1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70
use std::collections::HashMap; use std::borrow::Cow; use chrono::{Duration, Utc}; use super::{Authorizer, Request, Grant, Scope, Time, TokenGenerator, Url}; struct SpecificGrant { owner_id: String, client_id: String, scope: Scope, redirect_url: Url, until: Time, } impl<'a> Into<Grant<'a>> for SpecificGrant { fn into(self) -> Grant<'a> { Grant { owner_id: Cow::Owned(self.owner_id), client_id: Cow::Owned(self.client_id), scope: Cow::Owned(self.scope), redirect_url: Cow::Owned(self.redirect_url), until: Cow::Owned(self.until), } } } impl<'a> Grant<'a> { fn from_refs(owner_id: &'a str, client_id: &'a str, scope: &'a Scope, redirect_url: &'a Url, until: &'a Time) -> Grant<'a> { Grant { owner_id: Cow::Borrowed(owner_id), client_id: Cow::Borrowed(client_id), scope: Cow::Borrowed(scope), redirect_url: Cow::Borrowed(redirect_url), until: Cow::Borrowed(until), } } } pub struct Storage<I: TokenGenerator> { issuer: I, tokens: HashMap<String, SpecificGrant> } impl<I: TokenGenerator> Storage<I> { pub fn new(issuer: I) -> Storage<I> { Storage {issuer: issuer, tokens: HashMap::new()} } } impl<I: TokenGenerator> Authorizer for Storage<I> { fn authorize(&mut self, req: Request) -> String { let owner_id = req.owner_id.to_string(); let client_id = req.client_id.to_string(); let scope = req.scope.clone(); let redirect_url = req.redirect_url.clone(); let until = Utc::now() + Duration::minutes(10); let token = self.issuer.generate( &Grant::from_refs(&owner_id, &client_id, &scope, &redirect_url, &until)); self.tokens.insert(token.clone(), SpecificGrant { owner_id, client_id, scope, redirect_url, until }); token } fn extract<'a>(&mut self, grant: &'a str) -> Option<Grant<'a>> { self.tokens.remove(grant).map(|v| v.into()) } }