diff options
author | Aaron Power <theaaronepower@gmail.com> | 2017-04-21 12:06:30 +0100 |
---|---|---|
committer | Aaron Power <theaaronepower@gmail.com> | 2017-04-21 12:06:30 +0100 |
commit | a528624dc3609bfd230bb4e1dd2f8fa6767eccca (patch) | |
tree | 54d6bf9058ea5ddbadaf6f5a80b99797e5e0b66d /src/registration.rs | |
parent | 686c5129f3290d0600bb06c91c52484325f2f174 (diff) |
0.3.0 Redone registration api, added debug/clone
Diffstat (limited to 'src/registration.rs')
-rw-r--r-- | src/registration.rs | 128 |
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)) + } +} + + |