@@ -56,11 +56,9 @@ fn main() -> Result<(), Box<Error>> {
|
||||
}
|
||||
|
||||
fn register() -> Result<Mastodon, Box<Error>> {
|
||||
let mut app = App::builder();
|
||||
app.client_name("elefren-examples");
|
||||
|
||||
let registration = Registration::new("https://mastodon.social")
|
||||
.register(app)?;
|
||||
.client_name("elefren-examples")
|
||||
.register()?;
|
||||
let url = registration.authorize_url()?;
|
||||
|
||||
println!("Click this link to authorize on Mastodon: {}", url);
|
||||
|
||||
+9
-16
@@ -2,16 +2,11 @@
|
||||
#![cfg_attr(not(feature = "toml"), allow(unused_imports))]
|
||||
extern crate elefren;
|
||||
|
||||
pub use self::elefren::{Data, MastodonClient};
|
||||
pub use self::elefren::prelude::*;
|
||||
pub use self::elefren::apps::prelude::*;
|
||||
|
||||
use std::{error::Error, io};
|
||||
|
||||
use self::elefren::{
|
||||
apps::{App, Scopes},
|
||||
Mastodon,
|
||||
Registration,
|
||||
};
|
||||
|
||||
#[cfg(feature = "toml")]
|
||||
use self::elefren::data::toml;
|
||||
|
||||
@@ -34,20 +29,18 @@ pub fn get_mastodon_data() -> Result<Mastodon, Box<Error>> {
|
||||
|
||||
#[cfg(feature = "toml")]
|
||||
pub fn register() -> Result<Mastodon, Box<Error>> {
|
||||
let mut app = App::builder();
|
||||
app.client_name("elefren-examples")
|
||||
.scopes(Scopes::All)
|
||||
.website("https://github.com/pwoolcoc/elefren");
|
||||
|
||||
let website = read_line("Please enter your mastodon instance url:")?;
|
||||
let registration = Registration::new(website.trim());
|
||||
let registered = registration.register(app)?;
|
||||
let url = registered.authorize_url()?;
|
||||
let registration = Registration::new(website.trim())
|
||||
.client_name("elefren-examples")
|
||||
.scopes(Scopes::All)
|
||||
.website("https://github.com/pwoolcoc/elefren")
|
||||
.register()?;
|
||||
let url = registration.authorize_url()?;
|
||||
|
||||
println!("Click this link to authorize on Mastodon: {}", url);
|
||||
let code = read_line("Paste the returned authorization code: ")?;
|
||||
|
||||
let mastodon = registered.complete(code)?;
|
||||
let mastodon = registration.complete(code)?;
|
||||
|
||||
// Save app data for using on the next run.
|
||||
toml::to_file(&*mastodon, "mastodon-data.toml")?;
|
||||
|
||||
+2
-20
@@ -1,7 +1,5 @@
|
||||
use std::{borrow::Cow, fmt};
|
||||
|
||||
use try_from::TryInto;
|
||||
|
||||
use errors::{Error, Result};
|
||||
|
||||
/// Provides the necessary types for registering an App and getting the
|
||||
@@ -43,7 +41,7 @@ impl App {
|
||||
/// # Ok(())
|
||||
/// # }
|
||||
/// ```
|
||||
#[derive(Debug, Default, Serialize)]
|
||||
#[derive(Clone, Debug, Default, PartialEq, Serialize)]
|
||||
pub struct AppBuilder<'a> {
|
||||
client_name: Option<Cow<'a, str>>,
|
||||
redirect_uris: Option<Cow<'a, str>>,
|
||||
@@ -106,26 +104,10 @@ impl<'a> AppBuilder<'a> {
|
||||
}
|
||||
}
|
||||
|
||||
impl TryInto<App> for App {
|
||||
type Err = Error;
|
||||
|
||||
fn try_into(self) -> Result<App> {
|
||||
Ok(self)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> TryInto<App> for AppBuilder<'a> {
|
||||
type Err = Error;
|
||||
|
||||
fn try_into(self) -> Result<App> {
|
||||
Ok(self.build()?)
|
||||
}
|
||||
}
|
||||
|
||||
/// Permission scope of the application.
|
||||
/// [Details on what each permission provides][1]
|
||||
/// [1]: https://github.com/tootsuite/documentation/blob/master/Using-the-API/OAuth-details.md)
|
||||
#[derive(Debug, Clone, Copy, Serialize)]
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Serialize)]
|
||||
pub enum Scopes {
|
||||
/// All Permissions, equivalent to `read write follow`
|
||||
#[serde(rename = "read write follow")]
|
||||
|
||||
+2
-1
@@ -1,7 +1,7 @@
|
||||
use reqwest::{Client, Request, RequestBuilder, Response};
|
||||
use Result;
|
||||
|
||||
pub trait HttpSend {
|
||||
pub trait HttpSend: Clone {
|
||||
fn execute(&self, client: &Client, request: Request) -> Result<Response>;
|
||||
fn send(&self, client: &Client, builder: &mut RequestBuilder) -> Result<Response> {
|
||||
let request = builder.build()?;
|
||||
@@ -9,6 +9,7 @@ pub trait HttpSend {
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct HttpSender;
|
||||
|
||||
impl HttpSend for HttpSender {
|
||||
|
||||
+3
-4
@@ -11,10 +11,9 @@
|
||||
//! # fn try() -> elefren::Result<()> {
|
||||
//! use elefren::{apps::prelude::*, prelude::*};
|
||||
//!
|
||||
//! let mut app = App::builder();
|
||||
//! app.client_name("elefren_test");
|
||||
//!
|
||||
//! let registration = Registration::new("https://mastodon.social").register(app)?;
|
||||
//! let registration = Registration::new("https://mastodon.social")
|
||||
//! .client_name("elefren_test")
|
||||
//! .register()?;
|
||||
//! let url = registration.authorize_url()?;
|
||||
//! // Here you now need to open the url in the browser
|
||||
//! // And handle a the redirect url coming back with the code.
|
||||
|
||||
+89
-27
@@ -1,19 +1,17 @@
|
||||
use reqwest::{Client, RequestBuilder, Response};
|
||||
use try_from::TryInto;
|
||||
use std::borrow::Cow;
|
||||
|
||||
use apps::{App, Scopes};
|
||||
use reqwest::{Client, RequestBuilder, Response};
|
||||
|
||||
use apps::{App, AppBuilder, Scopes};
|
||||
use http_send::{HttpSend, HttpSender};
|
||||
use Data;
|
||||
use Error;
|
||||
use Mastodon;
|
||||
use MastodonBuilder;
|
||||
use Result;
|
||||
use {Data, Mastodon, MastodonBuilder, Result};
|
||||
|
||||
/// 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<H: HttpSend> {
|
||||
pub struct Registration<'a, H: HttpSend> {
|
||||
base: String,
|
||||
client: Client,
|
||||
app_builder: AppBuilder<'a>,
|
||||
http_sender: H,
|
||||
}
|
||||
|
||||
@@ -34,7 +32,7 @@ struct AccessToken {
|
||||
access_token: String,
|
||||
}
|
||||
|
||||
impl Registration<HttpSender> {
|
||||
impl<'a> Registration<'a, HttpSender> {
|
||||
/// Construct a new registration process to the instance of the `base` url.
|
||||
/// ```
|
||||
/// use elefren::apps::prelude::*;
|
||||
@@ -45,21 +43,43 @@ impl Registration<HttpSender> {
|
||||
Registration {
|
||||
base: base.into(),
|
||||
client: Client::new(),
|
||||
app_builder: AppBuilder::new(),
|
||||
http_sender: HttpSender,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<H: HttpSend> Registration<H> {
|
||||
impl<'a, H: HttpSend> Registration<'a, H> {
|
||||
#[allow(dead_code)]
|
||||
pub(crate) fn with_sender<I: Into<String>>(base: I, http_sender: H) -> Self {
|
||||
Registration {
|
||||
base: base.into(),
|
||||
client: Client::new(),
|
||||
app_builder: AppBuilder::new(),
|
||||
http_sender,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn client_name<I: Into<Cow<'a, str>>>(&mut self, name: I) -> &mut Self {
|
||||
self.app_builder.client_name(name.into());
|
||||
self
|
||||
}
|
||||
|
||||
pub fn redirect_uris<I: Into<Cow<'a, str>>>(&mut self, uris: I) -> &mut Self {
|
||||
self.app_builder.redirect_uris(uris);
|
||||
self
|
||||
}
|
||||
|
||||
pub fn scopes(&mut self, scopes: Scopes) -> &mut Self {
|
||||
self.app_builder.scopes(scopes);
|
||||
self
|
||||
}
|
||||
|
||||
pub fn website<I: Into<Cow<'a, str>>>(&mut self, website: I) -> &mut Self {
|
||||
self.app_builder.website(website);
|
||||
self
|
||||
}
|
||||
|
||||
fn send(&self, req: &mut RequestBuilder) -> Result<Response> {
|
||||
Ok(self.http_sender.send(&self.client, req)?)
|
||||
}
|
||||
@@ -71,38 +91,32 @@ impl<H: HttpSend> Registration<H> {
|
||||
/// # fn main () -> elefren::Result<()> {
|
||||
/// use elefren::{apps::prelude::*, prelude::*};
|
||||
///
|
||||
/// let mut builder = App::builder();
|
||||
/// builder.client_name("elefren_test");
|
||||
/// let app = builder.build()?;
|
||||
///
|
||||
/// let registration = Registration::new("https://mastodon.social");
|
||||
/// let registered = registration.register(app)?;
|
||||
/// let url = registered.authorize_url()?;
|
||||
/// let registration = Registration::new("https://mastodon.social")
|
||||
/// .client_name("elefren_test")
|
||||
/// .register()?;
|
||||
/// let url = registration.authorize_url()?;
|
||||
/// // 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 = registered.complete(code)?;
|
||||
/// let mastodon = registration.complete(code)?;
|
||||
///
|
||||
/// println!("{:?}", mastodon.get_home_timeline()?.initial_items);
|
||||
/// # Ok(())
|
||||
/// # }
|
||||
/// ```
|
||||
pub fn register<I: TryInto<App>>(self, app: I) -> Result<Registered<H>>
|
||||
where
|
||||
Error: From<<I as TryInto<App>>::Err>,
|
||||
{
|
||||
let app = app.try_into()?;
|
||||
pub fn register(&mut self) -> Result<Registered<H>> {
|
||||
let app: App = self.app_builder.clone().build()?;
|
||||
let url = format!("{}/api/v1/apps", self.base);
|
||||
let oauth: OAuth = self.send(self.client.post(&url).form(&app))?.json()?;
|
||||
|
||||
Ok(Registered {
|
||||
base: self.base,
|
||||
client: self.client,
|
||||
base: self.base.clone(),
|
||||
client: self.client.clone(),
|
||||
client_id: oauth.client_id,
|
||||
client_secret: oauth.client_secret,
|
||||
redirect: oauth.redirect_uri,
|
||||
scopes: app.scopes(),
|
||||
http_sender: self.http_sender,
|
||||
http_sender: self.http_sender.clone(),
|
||||
})
|
||||
}
|
||||
}
|
||||
@@ -160,3 +174,51 @@ pub struct Registered<H: HttpSend> {
|
||||
scopes: Scopes,
|
||||
http_sender: H,
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn test_registration_new() {
|
||||
let r = Registration::new("https://example.com");
|
||||
assert_eq!(r.base, "https://example.com".to_string());
|
||||
assert_eq!(r.app_builder, AppBuilder::new());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_set_client_name() {
|
||||
let mut r = Registration::new("https://example.com");
|
||||
r.client_name("foo-test");
|
||||
|
||||
assert_eq!(r.base, "https://example.com".to_string());
|
||||
assert_eq!(&mut r.app_builder, AppBuilder::new().client_name("foo-test"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_set_redirect_uris() {
|
||||
let mut r = Registration::new("https://example.com");
|
||||
r.redirect_uris("https://foo.com");
|
||||
|
||||
assert_eq!(r.base, "https://example.com".to_string());
|
||||
assert_eq!(&mut r.app_builder, AppBuilder::new().redirect_uris("https://foo.com"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_set_scopes() {
|
||||
let mut r = Registration::new("https://example.com");
|
||||
r.scopes(Scopes::All);
|
||||
|
||||
assert_eq!(r.base, "https://example.com".to_string());
|
||||
assert_eq!(&mut r.app_builder, AppBuilder::new().scopes(Scopes::All));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_set_website() {
|
||||
let mut r = Registration::new("https://example.com");
|
||||
r.website("https://website.example.com");
|
||||
|
||||
assert_eq!(r.base, "https://example.com".to_string());
|
||||
assert_eq!(&mut r.app_builder, AppBuilder::new().website("https://website.example.com"));
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user