summaryrefslogtreecommitdiffstats
path: root/src/registration.rs
diff options
context:
space:
mode:
authorAaron Power <theaaronepower@gmail.com>2017-04-21 12:06:30 +0100
committerAaron Power <theaaronepower@gmail.com>2017-04-21 12:06:30 +0100
commita528624dc3609bfd230bb4e1dd2f8fa6767eccca (patch)
tree54d6bf9058ea5ddbadaf6f5a80b99797e5e0b66d /src/registration.rs
parent686c5129f3290d0600bb06c91c52484325f2f174 (diff)
0.3.0 Redone registration api, added debug/clone
Diffstat (limited to 'src/registration.rs')
-rw-r--r--src/registration.rs128
1 files changed, 128 insertions, 0 deletions
diff --git a/src/registration.rs b/src/registration.rs
new file mode 100644
index 0000000..8b58f57
--- /dev/null
+++ b/src/registration.rs
@@ -0,0 +1,128 @@
+use reqwest::Client;
+
+use super::{Error, Mastodon, Result};
+use apps::AppBuilder;
+
+/// Handles registering your mastodon app to your instance. It is recommended
+/// you cache your data struct to avoid registering on every run.
+pub struct Registration {
+ base: String,
+ client: Client,
+ client_id: Option<String>,
+ client_secret: Option<String>,
+ redirect: Option<String>,
+}
+
+#[derive(Deserialize)]
+struct OAuth {
+ client_id: String,
+ client_secret: String,
+ redirect_uri: String,
+}
+
+#[derive(Deserialize)]
+struct AccessToken {
+ access_token: String,
+}
+
+impl Registration {
+ pub fn new<I: Into<String>>(base: I) -> Result<Self> {
+ Ok(Registration {
+ base: base.into(),
+ client: Client::new()?,
+ client_id: None,
+ client_secret: None,
+ redirect: None,
+ })
+ }
+
+ /// Register the application with the server from the `base` url.
+ ///
+ /// ```no_run
+ /// # extern crate mammut;
+ /// # fn main() {
+ /// # try().unwrap();
+ /// # }
+ /// # fn try() -> mammut::Result<()> {
+ /// use mammut::Registration;
+ /// use mammut::apps::{AppBuilder, Scope};
+ ///
+ /// let app = AppBuilder {
+ /// client_name: "mammut_test",
+ /// redirect_uris: "urn:ietf:wg:oauth:2.0:oob",
+ /// scopes: Scope::Read,
+ /// website: None,
+ /// };
+ ///
+ /// let mut registration = Registration::new("https://mastodon.social")?;
+ /// registration.register(app)?;
+ /// let url = registration.authorise()?;
+ /// // Here you now need to open the url in the browser
+ /// // And handle a the redirect url coming back with the code.
+ /// let code = String::from("RETURNED_FROM_BROWSER");
+ /// let mastodon = registration.create_access_token(code)?;
+ ///
+ /// println!("{:?}", mastodon.get_home_timeline()?);
+ /// # Ok(())
+ /// # }
+ /// ```
+ pub fn register(&mut self, app_builder: AppBuilder) -> Result<()> {
+ let url = format!("{}/api/v1/apps", self.base);
+
+ let app: OAuth = self.client.post(&url).form(&app_builder).send()?.json()?;
+
+ self.client_id = Some(app.client_id);
+ self.client_secret = Some(app.client_secret);
+ self.redirect = Some(app.redirect_uri);
+
+ Ok(())
+ }
+
+ /// Returns the full url needed for authorisation. This needs to be opened
+ /// in a browser.
+ pub fn authorise(&mut self) -> Result<String> {
+ self.is_registered()?;
+
+ let url = format!(
+ "{}/oauth/authorize?client_id={}&redirect_uri={}&response_type=code",
+ self.base,
+ self.client_id.clone().unwrap(),
+ self.redirect.clone().unwrap(),
+ );
+
+ Ok(url)
+ }
+
+ fn is_registered(&self) -> Result<()> {
+ if self.client_id.is_none() {
+ Err(Error::ClientIdRequired)
+ } else if self.client_secret.is_none() {
+ Err(Error::ClientSecretRequired)
+ } else {
+ Ok(())
+ }
+ }
+
+ pub fn create_access_token(self, code: String) -> Result<Mastodon> {
+ self.is_registered()?;
+ let url = format!(
+ "{}/oauth/token?client_id={}&client_secret={}&code={}&grant_type=authorization_code&redirect_uri={}",
+ self.base,
+ self.client_id.clone().unwrap(),
+ self.client_secret.clone().unwrap(),
+ code,
+ self.redirect.clone().unwrap()
+ );
+
+ let token: AccessToken = self.client.post(&url).send()?.json()?;
+
+ Ok(Mastodon::from_registration(self.base,
+ self.client_id.unwrap(),
+ self.client_secret.unwrap(),
+ self.redirect.unwrap(),
+ token.access_token,
+ self.client))
+ }
+}
+
+