diff --git a/src/common.rs b/src/common.rs index 4316e8e..628bd2c 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 f5d47bf..34d3b21 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 93cf8a7..4dfe234 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 9d883ff..83fc371 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 0000000..f671bf8 --- /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