inth_oauth2/
provider.rs

1//! Providers.
2
3use url::Url;
4
5use token::{Token, Lifetime, Bearer, Static, Refresh};
6
7/// OAuth 2.0 providers.
8pub trait Provider {
9    /// The lifetime of tokens issued by the provider.
10    type Lifetime: Lifetime;
11
12    /// The type of token issued by the provider.
13    type Token: Token<Self::Lifetime>;
14
15    /// The authorization endpoint URI.
16    ///
17    /// See [RFC 6749, section 3.1](http://tools.ietf.org/html/rfc6749#section-3.1).
18    fn auth_uri(&self) -> &Url;
19
20    /// The token endpoint URI.
21    ///
22    /// See [RFC 6749, section 3.2](http://tools.ietf.org/html/rfc6749#section-3.2).
23    fn token_uri(&self) -> &Url;
24
25    /// Provider requires credentials via request body.
26    ///
27    /// Although not recommended by the RFC, some providers require `client_id` and `client_secret`
28    /// as part of the request body.
29    ///
30    /// See [RFC 6749, section 2.3.1](http://tools.ietf.org/html/rfc6749#section-2.3.1).
31    fn credentials_in_body(&self) -> bool { false }
32}
33
34/// Google OAuth 2.0 providers.
35///
36/// See [Using OAuth 2.0 to Access Google
37/// APIs](https://developers.google.com/identity/protocols/OAuth2).
38pub mod google {
39    use url::Url;
40    use token::{Bearer, Expiring, Refresh};
41    use super::Provider;
42
43    /// Signals the server to return the authorization code by prompting the user to copy and
44    /// paste.
45    ///
46    /// See [Choosing a redirect URI][uri].
47    ///
48    /// [uri]: https://developers.google.com/identity/protocols/OAuth2InstalledApp#choosingredirecturi
49    pub const REDIRECT_URI_OOB: &'static str = "urn:ietf:wg:oauth:2.0:oob";
50
51    /// Signals the server to return the authorization code in the page title.
52    ///
53    /// See [Choosing a redirect URI][uri].
54    ///
55    /// [uri]: https://developers.google.com/identity/protocols/OAuth2InstalledApp#choosingredirecturi
56    pub const REDIRECT_URI_OOB_AUTO: &'static str = "urn:ietf:wg:oauth:2.0:oob:auto";
57
58    lazy_static! {
59        static ref AUTH_URI: Url = Url::parse("https://accounts.google.com/o/oauth2/v2/auth").unwrap();
60        static ref TOKEN_URI: Url = Url::parse("https://www.googleapis.com/oauth2/v4/token").unwrap();
61    }
62
63    /// Google OAuth 2.0 provider for web applications.
64    ///
65    /// See [Using OAuth 2.0 for Web Server
66    /// Applications](https://developers.google.com/identity/protocols/OAuth2WebServer).
67    #[derive(Debug, Clone, Copy, PartialEq, Eq)]
68    pub struct Web;
69    impl Provider for Web {
70        type Lifetime = Expiring;
71        type Token = Bearer<Expiring>;
72        fn auth_uri(&self) -> &Url { &AUTH_URI }
73        fn token_uri(&self) -> &Url { &TOKEN_URI }
74    }
75
76    /// Google OAuth 2.0 provider for installed applications.
77    ///
78    /// See [Using OAuth 2.0 for Installed
79    /// Applications](https://developers.google.com/identity/protocols/OAuth2InstalledApp).
80    #[derive(Debug, Clone, Copy, PartialEq, Eq)]
81    pub struct Installed;
82    impl Provider for Installed {
83        type Lifetime = Refresh;
84        type Token = Bearer<Refresh>;
85        fn auth_uri(&self) -> &Url { &AUTH_URI }
86        fn token_uri(&self) -> &Url { &TOKEN_URI }
87    }
88}
89
90lazy_static! {
91    static ref GITHUB_AUTH_URI: Url = Url::parse("https://github.com/login/oauth/authorize").unwrap();
92    static ref GITHUB_TOKEN_URI: Url = Url::parse("https://github.com/login/oauth/access_token").unwrap();
93    static ref IMGUR_AUTH_URI: Url = Url::parse("https://api.imgur.com/oauth2/authorize").unwrap();
94    static ref IMGUR_TOKEN_URI: Url = Url::parse("https://api.imgur.com/oauth2/token").unwrap();
95}
96
97/// GitHub OAuth 2.0 provider.
98///
99/// See [OAuth, GitHub Developer Guide](https://developer.github.com/v3/oauth/).
100#[derive(Debug, Clone, Copy, PartialEq, Eq)]
101pub struct GitHub;
102impl Provider for GitHub {
103    type Lifetime = Static;
104    type Token = Bearer<Static>;
105    fn auth_uri(&self) -> &Url { &GITHUB_AUTH_URI }
106    fn token_uri(&self) -> &Url { &GITHUB_TOKEN_URI }
107}
108
109/// Imgur OAuth 2.0 provider.
110///
111/// See [OAuth 2.0, Imgur](https://api.imgur.com/oauth2).
112#[derive(Debug, Clone, Copy, PartialEq, Eq)]
113pub struct Imgur;
114impl Provider for Imgur {
115    type Lifetime = Refresh;
116    type Token = Bearer<Refresh>;
117    fn auth_uri(&self) -> &Url { &IMGUR_AUTH_URI }
118    fn token_uri(&self) -> &Url { &IMGUR_TOKEN_URI }
119}
120
121#[test]
122fn google_urls() {
123    let prov = google::Web;
124    prov.auth_uri();
125    prov.token_uri();
126    let prov = google::Installed;
127    prov.auth_uri();
128    prov.token_uri();
129}
130
131#[test]
132fn github_urls() {
133    let prov = GitHub;
134    prov.auth_uri();
135    prov.token_uri();
136}
137
138#[test]
139fn imgur_urls() {
140    let prov = Imgur;
141    prov.auth_uri();
142    prov.token_uri();
143}