Implement FromResponse for tokens
This commit is contained in:
parent
3aa66c2d30
commit
2628759a2e
|
@ -82,4 +82,14 @@ impl<'a> JsonObjectHelper<'a> {
|
|||
pub fn get_string(&self, key: &'static str) -> Result<&'a str, ParseError> {
|
||||
self.get_string_option(key).ok_or(ParseError::ExpectedFieldType(key, "string"))
|
||||
}
|
||||
|
||||
/// Gets a field as an i64 or returns `None`.
|
||||
pub fn get_i64_option(&self, key: &'static str) -> Option<i64> {
|
||||
self.0.get(key).and_then(Json::as_i64)
|
||||
}
|
||||
|
||||
/// Gets a field as an i64 or fails with `ParseError::ExpectedFieldType`.
|
||||
pub fn get_i64(&self, key: &'static str) -> Result<i64, ParseError> {
|
||||
self.get_i64_option(key).ok_or(ParseError::ExpectedFieldType(key, "i64"))
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
use hyper::header;
|
||||
use rustc_serialize::json::Json;
|
||||
|
||||
use super::{Token, Lifetime};
|
||||
use client::response::{FromResponse, ParseError, JsonHelper};
|
||||
|
||||
/// The bearer token type.
|
||||
///
|
||||
|
@ -23,3 +25,35 @@ impl<'a, L: Lifetime> Into<header::Authorization<header::Bearer>> for &'a Bearer
|
|||
header::Authorization(header::Bearer { token: self.access_token.clone() })
|
||||
}
|
||||
}
|
||||
|
||||
impl<L: Lifetime> Bearer<L> {
|
||||
fn from_response_and_lifetime(json: &Json, lifetime: L) -> Result<Self, ParseError> {
|
||||
let obj = try!(JsonHelper(json).as_object());
|
||||
|
||||
let token_type = try!(obj.get_string("token_type"));
|
||||
if token_type != "Bearer" && token_type != "bearer" {
|
||||
return Err(ParseError::ExpectedFieldValue("token_type", "Bearer"));
|
||||
}
|
||||
|
||||
let access_token = try!(obj.get_string("access_token"));
|
||||
let scope = obj.get_string_option("scope");
|
||||
|
||||
Ok(Bearer {
|
||||
access_token: access_token.into(),
|
||||
scope: scope.map(Into::into),
|
||||
lifetime: lifetime,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
impl<L: Lifetime> FromResponse for Bearer<L> {
|
||||
fn from_response(json: &Json) -> Result<Self, ParseError> {
|
||||
let lifetime = try!(FromResponse::from_response(json));
|
||||
Bearer::from_response_and_lifetime(json, lifetime)
|
||||
}
|
||||
|
||||
fn from_response_inherit(json: &Json, prev: &Self) -> Result<Self, ParseError> {
|
||||
let lifetime = try!(FromResponse::from_response_inherit(json, &prev.lifetime));
|
||||
Bearer::from_response_and_lifetime(json, lifetime)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
use chrono::{DateTime, UTC};
|
||||
use chrono::{DateTime, UTC, Duration};
|
||||
use rustc_serialize::json::Json;
|
||||
|
||||
use super::Lifetime;
|
||||
use client::response::{FromResponse, ParseError, JsonHelper};
|
||||
|
||||
/// An expiring token.
|
||||
#[derive(Debug)]
|
||||
|
@ -22,3 +24,32 @@ impl Expiring {
|
|||
impl Lifetime for Expiring {
|
||||
fn expired(&self) -> bool { self.expires < UTC::now() }
|
||||
}
|
||||
|
||||
impl FromResponse for Expiring {
|
||||
fn from_response(json: &Json) -> Result<Self, ParseError> {
|
||||
let obj = try!(JsonHelper(json).as_object());
|
||||
|
||||
let refresh_token = try!(obj.get_string("refresh_token"));
|
||||
let expires_in = try!(obj.get_i64("expires_in"));
|
||||
|
||||
Ok(Expiring {
|
||||
refresh_token: refresh_token.into(),
|
||||
expires: UTC::now() + Duration::seconds(expires_in),
|
||||
})
|
||||
}
|
||||
|
||||
fn from_response_inherit(json: &Json, prev: &Self) -> Result<Self, ParseError> {
|
||||
let obj = try!(JsonHelper(json).as_object());
|
||||
|
||||
let refresh_token = try! {
|
||||
obj.get_string("refresh_token")
|
||||
.or(Ok(&prev.refresh_token))
|
||||
};
|
||||
let expires_in = try!(obj.get_i64("expires_in"));
|
||||
|
||||
Ok(Expiring {
|
||||
refresh_token: refresh_token.into(),
|
||||
expires: UTC::now() + Duration::seconds(expires_in),
|
||||
})
|
||||
}
|
||||
}
|
||||
|
|
|
@ -5,10 +5,12 @@
|
|||
//!
|
||||
//! Expiring and non-expiring tokens are abstracted through the `Lifetime` trait.
|
||||
|
||||
use client::response::FromResponse;
|
||||
|
||||
/// OAuth 2.0 tokens.
|
||||
///
|
||||
/// See [RFC 6749, section 5](http://tools.ietf.org/html/rfc6749#section-5).
|
||||
pub trait Token<L: Lifetime> {
|
||||
pub trait Token<L: Lifetime>: FromResponse {
|
||||
/// Returns the access token.
|
||||
///
|
||||
/// See [RF C6749, section 1.4](http://tools.ietf.org/html/rfc6749#section-1.4).
|
||||
|
@ -22,7 +24,7 @@ pub trait Token<L: Lifetime> {
|
|||
}
|
||||
|
||||
/// OAuth 2.0 token lifetimes.
|
||||
pub trait Lifetime {
|
||||
pub trait Lifetime: FromResponse {
|
||||
/// Returns true if the access token is no longer valid.
|
||||
fn expired(&self) -> bool;
|
||||
}
|
||||
|
|
|
@ -1,4 +1,7 @@
|
|||
use rustc_serialize::json::Json;
|
||||
|
||||
use super::Lifetime;
|
||||
use client::response::{FromResponse, ParseError, JsonHelper};
|
||||
|
||||
/// A static, non-expiring token.
|
||||
#[derive(Debug)]
|
||||
|
@ -7,3 +10,13 @@ pub struct Static;
|
|||
impl Lifetime for Static {
|
||||
fn expired(&self) -> bool { false }
|
||||
}
|
||||
|
||||
impl FromResponse for Static {
|
||||
fn from_response(json: &Json) -> Result<Self, ParseError> {
|
||||
let obj = try!(JsonHelper(json).as_object());
|
||||
if obj.0.contains_key("expires_in") {
|
||||
return Err(ParseError::UnexpectedField("expires_in"));
|
||||
}
|
||||
Ok(Static)
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue