Support dynamic providers

This commit is contained in:
Matthew Scheirer 2017-08-18 18:55:13 -04:00
parent 2d524faf92
commit 179532e061
3 changed files with 31 additions and 29 deletions

View File

@ -5,8 +5,6 @@ mod error;
pub mod response;
pub use self::error::ClientError;
use std::marker::PhantomData;
use hyper::{self, header, mime};
use serde_json::{self, Value};
use url::Url;
@ -29,7 +27,7 @@ pub struct Client<P: Provider> {
/// Redirect URI.
pub redirect_uri: Option<String>,
provider: PhantomData<P>,
provider: P,
}
impl<P: Provider> Client<P> {
@ -52,7 +50,7 @@ impl<P: Provider> Client<P> {
client_id: client_id,
client_secret: client_secret,
redirect_uri: redirect_uri,
provider: PhantomData,
provider: P::default(),
}
}
@ -79,7 +77,7 @@ impl<P: Provider> Client<P> {
/// ```
pub fn auth_uri(&self, scope: Option<&str>, state: Option<&str>) -> Result<Url, ClientError>
{
let mut uri = Url::parse(P::auth_uri())?;
let mut uri = Url::parse(self.provider.auth_uri())?;
{
let mut query = uri.query_pairs_mut();
@ -122,7 +120,7 @@ impl<P: Provider> Client<P> {
]);
let body = body.finish();
let request = http_client.post(P::token_uri())
let request = http_client.post(self.provider.token_uri())
.header(auth_header)
.header(accept_header)
.header(header::ContentType::form_url_encoded())
@ -201,12 +199,13 @@ mod tests {
use provider::Provider;
use super::Client;
#[derive(Default)]
struct Test;
impl Provider for Test {
type Lifetime = Static;
type Token = Bearer<Static>;
fn auth_uri() -> &'static str { "http://example.com/oauth2/auth" }
fn token_uri() -> &'static str { "http://example.com/oauth2/token" }
fn auth_uri(&self) -> &'static str { "http://example.com/oauth2/auth" }
fn token_uri(&self) -> &'static str { "http://example.com/oauth2/token" }
}
#[test]

View File

@ -3,7 +3,7 @@
use token::{Token, Lifetime, Bearer, Static, Refresh};
/// OAuth 2.0 providers.
pub trait Provider {
pub trait Provider: Default {
/// The lifetime of tokens issued by the provider.
type Lifetime: Lifetime;
@ -15,14 +15,14 @@ pub trait Provider {
/// See [RFC 6749, section 3.1](http://tools.ietf.org/html/rfc6749#section-3.1).
///
/// Note: likely to become an associated constant.
fn auth_uri() -> &'static str;
fn auth_uri(&self) -> &str;
/// The token endpoint URI.
///
/// See [RFC 6749, section 3.2](http://tools.ietf.org/html/rfc6749#section-3.2).
///
/// Note: likely to become an associated constant.
fn token_uri() -> &'static str;
fn token_uri(&self) -> &str;
/// Provider requires credentials via request body.
///
@ -62,49 +62,49 @@ pub mod google {
///
/// See [Using OAuth 2.0 for Web Server
/// Applications](https://developers.google.com/identity/protocols/OAuth2WebServer).
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
#[derive(Default, Debug, Clone, Copy, PartialEq, Eq)]
pub struct Web;
impl Provider for Web {
type Lifetime = Expiring;
type Token = Bearer<Expiring>;
fn auth_uri() -> &'static str { "https://accounts.google.com/o/oauth2/v2/auth" }
fn token_uri() -> &'static str { "https://www.googleapis.com/oauth2/v4/token" }
fn auth_uri(&self) -> &'static str { "https://accounts.google.com/o/oauth2/v2/auth" }
fn token_uri(&self) -> &'static str { "https://www.googleapis.com/oauth2/v4/token" }
}
/// Google OAuth 2.0 provider for installed applications.
///
/// See [Using OAuth 2.0 for Installed
/// Applications](https://developers.google.com/identity/protocols/OAuth2InstalledApp).
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
#[derive(Default, Debug, Clone, Copy, PartialEq, Eq)]
pub struct Installed;
impl Provider for Installed {
type Lifetime = Refresh;
type Token = Bearer<Refresh>;
fn auth_uri() -> &'static str { "https://accounts.google.com/o/oauth2/v2/auth" }
fn token_uri() -> &'static str { "https://www.googleapis.com/oauth2/v4/token" }
fn auth_uri(&self) -> &'static str { "https://accounts.google.com/o/oauth2/v2/auth" }
fn token_uri(&self) -> &'static str { "https://www.googleapis.com/oauth2/v4/token" }
}
}
/// GitHub OAuth 2.0 provider.
///
/// See [OAuth, GitHub Developer Guide](https://developer.github.com/v3/oauth/).
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
#[derive(Default, Debug, Clone, Copy, PartialEq, Eq)]
pub struct GitHub;
impl Provider for GitHub {
type Lifetime = Static;
type Token = Bearer<Static>;
fn auth_uri() -> &'static str { "https://github.com/login/oauth/authorize" }
fn token_uri() -> &'static str { "https://github.com/login/oauth/access_token" }
fn auth_uri(&self) -> &'static str { "https://github.com/login/oauth/authorize" }
fn token_uri(&self) -> &'static str { "https://github.com/login/oauth/access_token" }
}
/// Imgur OAuth 2.0 provider.
///
/// See [OAuth 2.0, Imgur](https://api.imgur.com/oauth2).
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
#[derive(Default, Debug, Clone, Copy, PartialEq, Eq)]
pub struct Imgur;
impl Provider for Imgur {
type Lifetime = Refresh;
type Token = Bearer<Refresh>;
fn auth_uri() -> &'static str { "https://api.imgur.com/oauth2/authorize" }
fn token_uri() -> &'static str { "https://api.imgur.com/oauth2/token" }
fn auth_uri(&self) -> &'static str { "https://api.imgur.com/oauth2/authorize" }
fn token_uri(&self) -> &'static str { "https://api.imgur.com/oauth2/token" }
}

View File

@ -12,28 +12,31 @@ mod provider {
use inth_oauth2::token::{Bearer, Static, Expiring, Refresh};
use inth_oauth2::provider::Provider;
#[derive(Default)]
pub struct BearerStatic;
impl Provider for BearerStatic {
type Lifetime = Static;
type Token = Bearer<Static>;
fn auth_uri() -> &'static str { "https://example.com/oauth/auth" }
fn token_uri() -> &'static str { "https://example.com/oauth/token" }
fn auth_uri(&self) -> &'static str { "https://example.com/oauth/auth" }
fn token_uri(&self) -> &'static str { "https://example.com/oauth/token" }
}
#[derive(Default)]
pub struct BearerExpiring;
impl Provider for BearerExpiring {
type Lifetime = Expiring;
type Token = Bearer<Expiring>;
fn auth_uri() -> &'static str { "https://example.com/oauth/auth" }
fn token_uri() -> &'static str { "https://example.com/oauth/token" }
fn auth_uri(&self) -> &'static str { "https://example.com/oauth/auth" }
fn token_uri(&self) -> &'static str { "https://example.com/oauth/token" }
}
#[derive(Default)]
pub struct BearerRefresh;
impl Provider for BearerRefresh {
type Lifetime = Refresh;
type Token = Bearer<Refresh>;
fn auth_uri() -> &'static str { "https://example.com/oauth/auth" }
fn token_uri() -> &'static str { "https://example.com/oauth/token" }
fn auth_uri(&self) -> &'static str { "https://example.com/oauth/auth" }
fn token_uri(&self) -> &'static str { "https://example.com/oauth/token" }
}
}