From 4486bd595fc4a3e6fecafbc5323fc0d6398a9ff9 Mon Sep 17 00:00:00 2001 From: Sebastian Thiel Date: Fri, 27 Feb 2015 19:58:06 +0100 Subject: [PATCH] feat(refresh): &mut Client instead of Client Breaking: This changes the existing API ... maybe Borrow can be used to hide the type of client. --- src/common.rs | 7 ++++++- src/device.rs | 8 +++++++- src/lib.rs | 6 ++++-- src/refresh.rs | 12 ++++++------ src/util.rs | 23 +++++++++++++++++++++++ 5 files changed, 46 insertions(+), 10 deletions(-) create mode 100644 src/util.rs diff --git a/src/common.rs b/src/common.rs index 4316e8e3e..628bd2c6d 100644 --- a/src/common.rs +++ b/src/common.rs @@ -1,4 +1,10 @@ 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. /// @@ -23,7 +29,6 @@ pub struct Token { /// access_token will expire after this amount of time. /// Prefer using expiry_date() pub expires_in: Option, - /// timestamp is seconds since epoch indicating when the token will expire in absolute terms. /// use expiry_date() to convert to DateTime. pub expires_in_timestamp: Option, diff --git a/src/device.rs b/src/device.rs index f5d47bf5a..34d3b212f 100644 --- a/src/device.rs +++ b/src/device.rs @@ -11,7 +11,7 @@ use itertools::Itertools; use rustc_serialize::json; 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"; @@ -27,6 +27,12 @@ pub struct DeviceFlow { id: String, } +impl Flow for DeviceFlow { + fn type_id() -> AuthenticationType { + AuthenticationType::Device + } +} + /// Contains state of pending authentication requests #[derive(Clone, Debug, PartialEq)] diff --git a/src/lib.rs b/src/lib.rs index 93cf8a7a3..4dfe23431 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -51,7 +51,8 @@ //! use oauth2::{RefreshFlow, AuthenticationType, RefreshResult}; //! //! # #[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, //! "my_client_id", "my_secret", //! "my_refresh_token") { @@ -78,9 +79,10 @@ extern crate "rustc-serialize" as rustc_serialize; mod device; mod refresh; mod common; +mod util; pub use device::{DeviceFlow, PollInformation, PollResult, DeviceFlowHelper, DeviceFlowHelperDelegate, Retry}; pub use refresh::{RefreshFlow, RefreshResult}; pub use common::{Token, AuthenticationType, ApplicationSecret, ConsoleApplicationSecret}; - +pub use util::TokenStorage; diff --git a/src/refresh.rs b/src/refresh.rs index 9d883ffcf..83fc37180 100644 --- a/src/refresh.rs +++ b/src/refresh.rs @@ -12,8 +12,8 @@ use super::Token; /// 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 /// and valid access token. -pub struct RefreshFlow { - client: hyper::Client, +pub struct RefreshFlow<'a, NC> where NC: 'a { + client: &'a mut hyper::Client, result: RefreshResult, } @@ -28,10 +28,10 @@ pub enum RefreshResult { Success(Token), } -impl RefreshFlow +impl<'a, NC> RefreshFlow<'a, NC> where NC: hyper::net::NetworkConnector { - pub fn new(client: hyper::Client) -> RefreshFlow { + pub fn new(client: &'a mut hyper::Client) -> RefreshFlow { RefreshFlow { client: client, result: RefreshResult::Error(hyper::HttpError::HttpStatusError), @@ -135,9 +135,9 @@ mod tests { #[test] fn refresh_flow() { + let mut c = hyper::Client::with_connector(::default()); let mut flow = RefreshFlow::new( - hyper::Client::with_connector( - ::default())); + &mut c); match *flow.refresh_token(AuthenticationType::Device, diff --git a/src/util.rs b/src/util.rs new file mode 100644 index 000000000..f671bf89d --- /dev/null +++ b/src/util.rs @@ -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); + /// 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; +} + + +/// 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 { + auth_type: AuthenticationType, + storage: S, + // client ref ... +} \ No newline at end of file