parent
							
								
									686c5129f3
								
							
						
					
					
						commit
						a528624dc3
					
				| @ -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)) | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
					Loading…
					
					
				
		Reference in new issue