diff --git a/src/cache.rs b/src/cache.rs index cda759b5429409a324a07cad11c0bb7f8218bae1..4f85dbd94b1beaa19c7b81c96ecce8d6e0cf05b8 100644 --- a/src/cache.rs +++ b/src/cache.rs @@ -13,20 +13,75 @@ * limitations under the License. */ +use lazy_static::lazy_static; use std::collections::HashMap; +use std::convert::From; +use std::time::SystemTime; + +use oauth2::basic::BasicTokenResponse; + +const TOKEN_DEFAULT_EXPIRES: u64 = 24 * 60 * 60; struct UserToken { access_token: String, - expires_in: u32, - refresh_token: String, - scope: String, - token_type: String, + expires_at: u64, + refresh_token: Option<String>, +} + + +impl UserToken { + fn is_expired(&self) -> bool { + match SystemTime::now().duration_since(SystemTime::UNIX_EPOCH) { + Ok(d) => d.as_secs() >= self.expires_at, + Err(_) => true + } + } +} + +impl From<BasicTokenResponse> for UserToken { + fn from(response: BasicTokenResponse) -> Self { + UserToken { + access_token: response.access_token.secret().to_string(), + expires_at: match response.expires_in { + Some(duration) => duration, + None => TOKEN_DEFAULT_EXPIRES + } + SystemTime::now().duration_since(SystemTime::UNIX_EPOCH).ok().unwrap().as_secs(), + refresh_token: match response.refresh_token { + Some(t) => Some(t.secret().to_string()), + None => None + } + } + } } -static mut USER_TOKENS: Option<HashMap<String, UserToken>> = None; +struct Cache { + user_tokens: HashMap<String, UserToken> +} + +impl Cache { + fn new() -> Cache { + Cache { + user_tokens: HashMap::new() + } + } + + fn load_user_token(&self, owner: String) -> Option<&UserToken> { + return self.user_tokens.get(&owner); + } -fn setup_cache() { - unsafe { - USER_TOKENS = Some(HashMap::new()); + fn save_user_token(&self, owner: String, token: UserToken) { + self.user_tokens.insert(owner, token); } + + fn cleanup_tokens(&self) { + for (owner, token) in self.user_tokens { + if token.is_expired() { + self.user_tokens.remove(&owner); + } + } + } +} + +lazy_static! { + static ref CACHE: Cache = Cache::new(); }