feat(refresh): &mut Client instead of Client

Breaking: This changes the existing API ... maybe Borrow can be used
to hide the type of client.
This commit is contained in:
Sebastian Thiel
2015-02-27 19:58:06 +01:00
parent 515e128cac
commit 4486bd595f
5 changed files with 46 additions and 10 deletions

View File

@@ -1,4 +1,10 @@
use chrono::{DateTime, UTC, TimeZone}; use chrono::{DateTime, UTC, TimeZone};
use std::marker::MarkerTrait;
/// A marker trait for all Flows
pub trait Flow : MarkerTrait {
fn type_id() -> AuthenticationType;
}
/// Represents a token as returned by OAuth2 servers. /// Represents a token as returned by OAuth2 servers.
/// ///
@@ -23,7 +29,6 @@ pub struct Token {
/// access_token will expire after this amount of time. /// access_token will expire after this amount of time.
/// Prefer using expiry_date() /// Prefer using expiry_date()
pub expires_in: Option<i64>, pub expires_in: Option<i64>,
/// timestamp is seconds since epoch indicating when the token will expire in absolute terms. /// timestamp is seconds since epoch indicating when the token will expire in absolute terms.
/// use expiry_date() to convert to DateTime. /// use expiry_date() to convert to DateTime.
pub expires_in_timestamp: Option<i64>, pub expires_in_timestamp: Option<i64>,

View File

@@ -11,7 +11,7 @@ use itertools::Itertools;
use rustc_serialize::json; use rustc_serialize::json;
use chrono::{DateTime,UTC}; use chrono::{DateTime,UTC};
use common::{Token, AuthenticationType}; use common::{Token, AuthenticationType, Flow};
pub const GOOGLE_TOKEN_URL: &'static str = "https://accounts.google.com/o/oauth2/token"; pub const GOOGLE_TOKEN_URL: &'static str = "https://accounts.google.com/o/oauth2/token";
@@ -27,6 +27,12 @@ pub struct DeviceFlow<NC> {
id: String, id: String,
} }
impl<NC> Flow for DeviceFlow<NC> {
fn type_id() -> AuthenticationType {
AuthenticationType::Device
}
}
/// Contains state of pending authentication requests /// Contains state of pending authentication requests
#[derive(Clone, Debug, PartialEq)] #[derive(Clone, Debug, PartialEq)]

View File

@@ -51,7 +51,8 @@
//! use oauth2::{RefreshFlow, AuthenticationType, RefreshResult}; //! use oauth2::{RefreshFlow, AuthenticationType, RefreshResult};
//! //!
//! # #[test] fn refresh() { //! # #[test] fn refresh() {
//! let mut f = RefreshFlow::new(hyper::Client::new()); //! let mut c = hyper::Client::new();
//! let mut f = RefreshFlow::new(&mut c);
//! let new_token = match *f.refresh_token(AuthenticationType::Device, //! let new_token = match *f.refresh_token(AuthenticationType::Device,
//! "my_client_id", "my_secret", //! "my_client_id", "my_secret",
//! "my_refresh_token") { //! "my_refresh_token") {
@@ -78,9 +79,10 @@ extern crate "rustc-serialize" as rustc_serialize;
mod device; mod device;
mod refresh; mod refresh;
mod common; mod common;
mod util;
pub use device::{DeviceFlow, PollInformation, PollResult, DeviceFlowHelper, pub use device::{DeviceFlow, PollInformation, PollResult, DeviceFlowHelper,
DeviceFlowHelperDelegate, Retry}; DeviceFlowHelperDelegate, Retry};
pub use refresh::{RefreshFlow, RefreshResult}; pub use refresh::{RefreshFlow, RefreshResult};
pub use common::{Token, AuthenticationType, ApplicationSecret, ConsoleApplicationSecret}; pub use common::{Token, AuthenticationType, ApplicationSecret, ConsoleApplicationSecret};
pub use util::TokenStorage;

View File

@@ -12,8 +12,8 @@ use super::Token;
/// Refresh an expired access token, as obtained by any other authentication flow. /// Refresh an expired access token, as obtained by any other authentication flow.
/// This flow is useful when your `Token` is expired and allows to obtain a new /// This flow is useful when your `Token` is expired and allows to obtain a new
/// and valid access token. /// and valid access token.
pub struct RefreshFlow<NC> { pub struct RefreshFlow<'a, NC> where NC: 'a {
client: hyper::Client<NC>, client: &'a mut hyper::Client<NC>,
result: RefreshResult, result: RefreshResult,
} }
@@ -28,10 +28,10 @@ pub enum RefreshResult {
Success(Token), Success(Token),
} }
impl<NC> RefreshFlow<NC> impl<'a, NC> RefreshFlow<'a, NC>
where NC: hyper::net::NetworkConnector { where NC: hyper::net::NetworkConnector {
pub fn new(client: hyper::Client<NC>) -> RefreshFlow<NC> { pub fn new(client: &'a mut hyper::Client<NC>) -> RefreshFlow<NC> {
RefreshFlow { RefreshFlow {
client: client, client: client,
result: RefreshResult::Error(hyper::HttpError::HttpStatusError), result: RefreshResult::Error(hyper::HttpError::HttpStatusError),
@@ -135,9 +135,9 @@ mod tests {
#[test] #[test]
fn refresh_flow() { fn refresh_flow() {
let mut c = hyper::Client::with_connector(<MockGoogleRefresh as Default>::default());
let mut flow = RefreshFlow::new( let mut flow = RefreshFlow::new(
hyper::Client::with_connector( &mut c);
<MockGoogleRefresh as Default>::default()));
match *flow.refresh_token(AuthenticationType::Device, match *flow.refresh_token(AuthenticationType::Device,

23
src/util.rs Normal file
View File

@@ -0,0 +1,23 @@
use common::{Token, AuthenticationType};
/// Implements a specialised storage to set and retrieve `Token` instances.
/// The `scope_hash` represents the signature of the scopes for which the given token
/// should be stored or retrieved.
pub trait TokenStorage {
/// If `token` is None, it is invalid or revoked and should be removed from storage.
fn set(&mut self, scope_hash: i64, token: Option<Token>);
/// A `None` result indicates that there is no token for the given scope_hash.
/// It is assumed that a token previously `set` will be retrievable using `get`
fn get(&self, scope_hash: i64) -> Option<Token>;
}
/// A generalized authenticator which will keep tokens valid and store them.
///
/// It is the go-to helper to deal with any kind of supported authentication flow,
/// which will be kept valid and usable.
pub struct Authenticator<S> {
auth_type: AuthenticationType,
storage: S,
// client ref ...
}