diff --git a/examples/github.rs b/examples/github.rs index 3eaa5e5..982bf77 100644 --- a/examples/github.rs +++ b/examples/github.rs @@ -7,7 +7,6 @@ use inth_oauth2::provider::GitHub; fn main() { let client = Client::::new( - Default::default(), "01774654cd9a6051e478", "9f14d16d95d605e715ec1a9aecec220d2565fd5c", Some("https://cmcenroe.me/oauth2-paste/") @@ -19,6 +18,6 @@ fn main() { let mut code = String::new(); io::stdin().read_line(&mut code).unwrap(); - let token = client.request_token(code.trim()).unwrap(); + let token = client.request_token(&Default::default(), code.trim()).unwrap(); println!("{:?}", token); } diff --git a/examples/google.rs b/examples/google.rs index 0e431db..d4f70ad 100644 --- a/examples/google.rs +++ b/examples/google.rs @@ -7,7 +7,6 @@ use inth_oauth2::provider::Google; fn main() { let client = Client::::new( - Default::default(), "143225766783-ip2d9qv6sdr37276t77luk6f7bhd6bj5.apps.googleusercontent.com", "3kZ5WomzHFlN2f_XbhkyPd3o", Some("urn:ietf:wg:oauth:2.0:oob") @@ -20,9 +19,11 @@ fn main() { let mut code = String::new(); io::stdin().read_line(&mut code).unwrap(); - let token = client.request_token(code.trim()).unwrap(); + let http_client = Default::default(); + + let token = client.request_token(&http_client, code.trim()).unwrap(); println!("{:?}", token); - let token = client.refresh_token(token, None).unwrap(); + let token = client.refresh_token(&http_client, token, None).unwrap(); println!("{:?}", token); } diff --git a/examples/imgur.rs b/examples/imgur.rs index c48a39e..09128e3 100644 --- a/examples/imgur.rs +++ b/examples/imgur.rs @@ -7,7 +7,6 @@ use inth_oauth2::provider::Imgur; fn main() { let client = Client::::new( - Default::default(), "505c8ca804230e0", "c898d8cf28404102752b2119a3a1c6aab49899c8", Some("https://cmcenroe.me/oauth2-paste/") @@ -19,9 +18,11 @@ fn main() { let mut code = String::new(); io::stdin().read_line(&mut code).unwrap(); - let token = client.request_token(code.trim()).unwrap(); + let http_client = Default::default(); + + let token = client.request_token(&http_client, code.trim()).unwrap(); println!("{:?}", token); - let token = client.refresh_token(token, None).unwrap(); + let token = client.refresh_token(&http_client, token, None).unwrap(); println!("{:?}", token); } diff --git a/src/client/mod.rs b/src/client/mod.rs index 320efff..7fa74b6 100644 --- a/src/client/mod.rs +++ b/src/client/mod.rs @@ -19,7 +19,6 @@ mod error; /// OAuth 2.0 client. pub struct Client { - http_client: hyper::Client, client_id: String, client_secret: String, redirect_uri: Option, @@ -46,20 +45,17 @@ impl Client

{ /// use inth_oauth2::provider::Google; /// /// let client = Client::::new( - /// Default::default(), /// "CLIENT_ID", /// "CLIENT_SECRET", /// Some("urn:ietf:wg:oauth:2.0:oob") /// ); /// ``` pub fn new( - http_client: hyper::Client, client_id: S, client_secret: S, redirect_uri: Option ) -> Self where S: Into { Client { - http_client: http_client, client_id: client_id.into(), client_secret: client_secret.into(), redirect_uri: redirect_uri.map(Into::into), @@ -78,7 +74,6 @@ impl Client

{ /// use inth_oauth2::provider::Google; /// /// let client = Client::::new( - /// Default::default(), /// "CLIENT_ID", /// "CLIENT_SECRET", /// Some("urn:ietf:wg:oauth:2.0:oob") @@ -112,7 +107,11 @@ impl Client

{ Ok(uri.serialize()) } - fn post_token<'a>(&'a self, mut body_pairs: Vec<(&str, &'a str)>) -> Result { + fn post_token<'a>( + &'a self, + http_client: &hyper::Client, + mut body_pairs: Vec<(&str, &'a str)> + ) -> Result { if P::credentials_in_body() { body_pairs.push(("client_id", &self.client_id)); body_pairs.push(("client_secret", &self.client_secret)); @@ -129,7 +128,7 @@ impl Client

{ header::qitem(mime::Mime(mime::TopLevel::Application, mime::SubLevel::Json, vec![])), ]); - let request = self.http_client.post(P::token_uri()) + let request = http_client.post(P::token_uri()) .header(auth_header) .header(accept_header) .header(header::ContentType::form_url_encoded()) @@ -150,7 +149,7 @@ impl Client

{ /// Requests an access token using an authorization code. /// /// See [RFC 6749, section 4.1.3](http://tools.ietf.org/html/rfc6749#section-4.1.3). - pub fn request_token(&self, code: &str) -> Result { + pub fn request_token(&self, http_client: &hyper::Client, code: &str) -> Result { let mut body_pairs = vec![ ("grant_type", "authorization_code"), ("code", code), @@ -159,7 +158,8 @@ impl Client

{ body_pairs.push(("redirect_uri", redirect_uri)); } - let json = try!(self.post_token(body_pairs)); + + let json = try!(self.post_token(http_client, body_pairs)); let token = try!(P::Token::from_response(&json)); Ok(token) } @@ -171,6 +171,7 @@ impl Client

where P::Token: Token { /// See [RFC 6749, section 6](http://tools.ietf.org/html/rfc6749#section-6). pub fn refresh_token( &self, + http_client: &hyper::Client, token: P::Token, scope: Option<&str> ) -> Result { @@ -182,15 +183,15 @@ impl Client

where P::Token: Token { body_pairs.push(("scope", scope)); } - let json = try!(self.post_token(body_pairs)); + let json = try!(self.post_token(http_client, body_pairs)); let token = try!(P::Token::from_response_inherit(&json, &token)); Ok(token) } /// Ensures an access token is valid by refreshing it if necessary. - pub fn ensure_token(&self, token: P::Token) -> Result { + pub fn ensure_token(&self, http_client: &hyper::Client, token: P::Token) -> Result { if token.lifetime().expired() { - self.refresh_token(token, None) + self.refresh_token(http_client, token, None) } else { Ok(token) } @@ -213,7 +214,7 @@ mod tests { #[test] fn auth_uri() { - let client = Client::::new(Default::default(), "foo", "bar", None); + let client = Client::::new("foo", "bar", None); assert_eq!( "http://example.com/oauth2/auth?response_type=code&client_id=foo", client.auth_uri(None, None).unwrap() @@ -223,7 +224,6 @@ mod tests { #[test] fn auth_uri_with_redirect_uri() { let client = Client::::new( - Default::default(), "foo", "bar", Some("http://example.com/oauth2/callback") @@ -236,7 +236,7 @@ mod tests { #[test] fn auth_uri_with_scope() { - let client = Client::::new(Default::default(), "foo", "bar", None); + let client = Client::::new("foo", "bar", None); assert_eq!( "http://example.com/oauth2/auth?response_type=code&client_id=foo&scope=baz", client.auth_uri(Some("baz"), None).unwrap() @@ -245,7 +245,7 @@ mod tests { #[test] fn auth_uri_with_state() { - let client = Client::::new(Default::default(), "foo", "bar", None); + let client = Client::::new("foo", "bar", None); assert_eq!( "http://example.com/oauth2/auth?response_type=code&client_id=foo&state=baz", client.auth_uri(None, Some("baz")).unwrap() diff --git a/src/lib.rs b/src/lib.rs index d0c470e..ddc8478 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -33,7 +33,6 @@ //! use inth_oauth2::provider::Google; //! //! let client = Client::::new( -//! Default::default(), //! "client_id", //! "client_secret", //! Some("redirect_uri") @@ -45,7 +44,7 @@ //! ``` //! # use inth_oauth2::Client; //! # use inth_oauth2::provider::Google; -//! # let client = Client::::new(Default::default(), "", "", None); +//! # let client = Client::::new("", "", None); //! let auth_uri = client.auth_uri(Some("scope"), Some("state")).unwrap(); //! println!("Authorize the application by clicking on the link: {}", auth_uri); //! ``` @@ -56,12 +55,13 @@ //! use std::io; //! use inth_oauth2::{Client, Token}; //! # use inth_oauth2::provider::Google; -//! # let client = Client::::new(Default::default(), "", "", None); +//! # let client = Client::::new("", "", None); //! //! let mut code = String::new(); //! io::stdin().read_line(&mut code).unwrap(); //! -//! let token = client.request_token(code.trim()).unwrap(); +//! let http_client = Default::default(); +//! let token = client.request_token(&http_client, code.trim()).unwrap(); //! println!("{}", token.access_token()); //! ``` //! @@ -70,9 +70,10 @@ //! ```no_run //! # use inth_oauth2::Client; //! # use inth_oauth2::provider::Google; -//! # let client = Client::::new(Default::default(), "", "", None); -//! # let token = client.request_token("").unwrap(); -//! let token = client.refresh_token(token, None).unwrap(); +//! # let client = Client::::new("", "", None); +//! # let http_client = Default::default(); +//! # let token = client.request_token(&http_client, "").unwrap(); +//! let token = client.refresh_token(&http_client, token, None).unwrap(); //! ``` //! //! ### Ensuring an access token is still valid @@ -80,10 +81,11 @@ //! ```no_run //! # use inth_oauth2::Client; //! # use inth_oauth2::provider::Google; -//! # let client = Client::::new(Default::default(), "", "", None); -//! # let mut token = client.request_token("").unwrap(); +//! # let client = Client::::new("", "", None); +//! # let http_client = Default::default(); +//! # let mut token = client.request_token(&http_client, "").unwrap(); //! // Refresh token only if it has expired. -//! token = client.ensure_token(token).unwrap(); +//! token = client.ensure_token(&http_client, token).unwrap(); //! ``` //! //! ### Using bearer access tokens @@ -98,9 +100,9 @@ //! use hyper::header::Authorization; //! //! # fn main() { -//! # let client = Client::::new(Default::default(), "", "", None); -//! # let token = client.request_token("").unwrap(); //! let client = hyper::Client::new(); +//! # let oauth_client = Client::::new("", "", None); +//! # let token = oauth_client.request_token(&client, "").unwrap(); //! let request = client.get("https://example.com/resource") //! .header(Into::>::into(&token)); //! # } @@ -118,8 +120,9 @@ //! # use inth_oauth2::provider::Google; //! use rustc_serialize::json; //! # fn main() { -//! # let client = Client::::new(Default::default(), "", "", None); -//! # let token = client.request_token("").unwrap(); +//! # let http_client = Default::default(); +//! # let client = Client::::new("", "", None); +//! # let token = client.request_token(&http_client, "").unwrap(); //! let json = json::encode(&token).unwrap(); //! # } //! ``` @@ -130,8 +133,9 @@ //! # use inth_oauth2::Client; //! # use inth_oauth2::provider::Google; //! # fn main() { -//! # let client = Client::::new(Default::default(), "", "", None); -//! # let token = client.request_token("").unwrap(); +//! # let http_client = Default::default(); +//! # let client = Client::::new("", "", None); +//! # let token = client.request_token(&http_client, "").unwrap(); //! let json = serde_json::to_string(&token).unwrap(); //! # } //! ``` diff --git a/tests/auth_uri.rs b/tests/auth_uri.rs index c9719b5..34ee397 100644 --- a/tests/auth_uri.rs +++ b/tests/auth_uri.rs @@ -13,7 +13,6 @@ fn assert_get_uri_ok(uri: &str) { #[test] fn google_auth_uri_ok() { let client = Client::::new( - Default::default(), "143225766783-ip2d9qv6sdr37276t77luk6f7bhd6bj5.apps.googleusercontent.com", "", Some("urn:ietf:wg:oauth:2.0:oob") @@ -28,7 +27,6 @@ fn google_auth_uri_ok() { #[test] fn github_auth_uri_ok() { let client = Client::::new( - Default::default(), "01774654cd9a6051e478", "", Some("https://cmcenroe.me/oauth2-paste/") @@ -40,7 +38,6 @@ fn github_auth_uri_ok() { #[test] fn imgur_auth_uri_ok() { let client = Client::::new( - Default::default(), "505c8ca804230e0", "", Some("https://cmcenroe.me/oauth2-paste/") diff --git a/tests/mock.rs b/tests/mock.rs index 59c371c..7d4ce5d 100644 --- a/tests/mock.rs +++ b/tests/mock.rs @@ -58,28 +58,28 @@ mod connector { macro_rules! mock_client { ($p:ty, $c:ty) => { - Client::<$p>::new( - hyper::Client::with_connector(<$c>::default()), + (Client::<$p>::new( "client_id", "client_secret", None - ) + ), + hyper::Client::with_connector(<$c>::default())) } } #[test] fn request_token_bearer_static_success() { - let client = mock_client!(provider::BearerStatic, connector::BearerStatic); - let token = client.request_token("code").unwrap(); + let (client, http_client) = mock_client!(provider::BearerStatic, connector::BearerStatic); + let token = client.request_token(&http_client, "code").unwrap(); assert_eq!("aaaaaaaa", token.access_token()); assert_eq!(Some("example"), token.scope()); } #[test] fn request_token_bearer_expiring_success() { - let client = mock_client!(provider::BearerExpiring, connector::BearerExpiring); - let token = client.request_token("code").unwrap(); + let (client, http_client) = mock_client!(provider::BearerExpiring, connector::BearerExpiring); + let token = client.request_token(&http_client, "code").unwrap(); assert_eq!("aaaaaaaa", token.access_token()); assert_eq!(Some("example"), token.scope()); assert_eq!("bbbbbbbb", token.lifetime().refresh_token()); @@ -90,9 +90,9 @@ fn request_token_bearer_expiring_success() { #[test] fn refresh_token_bearer_full() { - let client = mock_client!(provider::BearerExpiring, connector::BearerExpiring); - let token = client.request_token("code").unwrap(); - let token = client.refresh_token(token, None).unwrap(); + let (client, http_client) = mock_client!(provider::BearerExpiring, connector::BearerExpiring); + let token = client.request_token(&http_client, "code").unwrap(); + let token = client.refresh_token(&http_client, token, None).unwrap(); assert_eq!("cccccccc", token.access_token()); assert_eq!(Some("example"), token.scope()); assert_eq!("dddddddd", token.lifetime().refresh_token()); @@ -103,9 +103,9 @@ fn refresh_token_bearer_full() { #[test] fn refresh_token_bearer_partial() { - let client = mock_client!(provider::BearerExpiring, connector::BearerExpiringPartial); - let token = client.request_token("code").unwrap(); - let token = client.refresh_token(token, None).unwrap(); + let (client, http_client) = mock_client!(provider::BearerExpiring, connector::BearerExpiringPartial); + let token = client.request_token(&http_client, "code").unwrap(); + let token = client.refresh_token(&http_client, token, None).unwrap(); assert_eq!("cccccccc", token.access_token()); assert_eq!(Some("example"), token.scope()); assert_eq!("bbbbbbbb", token.lifetime().refresh_token()); @@ -116,22 +116,22 @@ fn refresh_token_bearer_partial() { #[test] fn request_token_bearer_static_wrong_lifetime() { - let client = mock_client!(provider::BearerStatic, connector::BearerExpiring); - let err = client.request_token("code").unwrap_err(); + let (client, http_client) = mock_client!(provider::BearerStatic, connector::BearerExpiring); + let err = client.request_token(&http_client, "code").unwrap_err(); assert!(match err { ClientError::Parse(..) => true, _ => false }); } #[test] fn request_token_bearer_expiring_wrong_lifetime() { - let client = mock_client!(provider::BearerExpiring, connector::BearerStatic); - let err = client.request_token("code").unwrap_err(); + let (client, http_client) = mock_client!(provider::BearerExpiring, connector::BearerStatic); + let err = client.request_token(&http_client, "code").unwrap_err(); assert!(match err { ClientError::Parse(..) => true, _ => false }); } #[test] fn request_token_invalid_request() { - let client = mock_client!(provider::BearerStatic, connector::InvalidRequest); - let err = client.request_token("code").unwrap_err(); + let (client, http_client) = mock_client!(provider::BearerStatic, connector::InvalidRequest); + let err = client.request_token(&http_client, "code").unwrap_err(); assert!(match err { ClientError::OAuth2(err) => { assert_eq!(OAuth2ErrorCode::InvalidRequest, err.code); @@ -145,9 +145,9 @@ fn request_token_invalid_request() { #[test] fn refresh_token_invalid_request() { - let client = mock_client!(provider::BearerExpiring, connector::RefreshInvalidRequest); - let token = client.request_token("code").unwrap(); - let err = client.refresh_token(token, None).unwrap_err(); + let (client, http_client) = mock_client!(provider::BearerExpiring, connector::RefreshInvalidRequest); + let token = client.request_token(&http_client, "code").unwrap(); + let err = client.refresh_token(&http_client, token, None).unwrap_err(); assert!(match err { ClientError::OAuth2(err) => { assert_eq!(OAuth2ErrorCode::InvalidRequest, err.code);