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