inth_oauth2/token/
refresh.rs1use chrono::{DateTime, Utc, Duration};
2use serde_json::Value;
3
4use client::response::{FromResponse, ParseError};
5use token::Lifetime;
6
7#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
9pub struct Refresh {
10 refresh_token: String,
11 expires: DateTime<Utc>,
12}
13
14impl Refresh {
15 pub fn refresh_token(&self) -> &str { &self.refresh_token }
19
20 pub fn expires(&self) -> &DateTime<Utc> { &self.expires }
22}
23
24impl Lifetime for Refresh {
25 fn expired(&self) -> bool { self.expires < Utc::now() }
26}
27
28impl FromResponse for Refresh {
29 fn from_response(json: &Value) -> Result<Self, ParseError> {
30 let obj = json.as_object().ok_or(ParseError::ExpectedType("object"))?;
31
32 let refresh_token = obj.get("refresh_token")
33 .and_then(Value::as_str)
34 .ok_or(ParseError::ExpectedFieldType("refresh_token", "string"))?;
35 let expires_in = obj.get("expires_in")
36 .and_then(Value::as_i64)
37 .ok_or(ParseError::ExpectedFieldType("expires_in", "i64"))?;
38
39 Ok(Refresh {
40 refresh_token: refresh_token.into(),
41 expires: Utc::now() + Duration::seconds(expires_in),
42 })
43 }
44
45 fn from_response_inherit(json: &Value, prev: &Self) -> Result<Self, ParseError> {
46 let obj = json.as_object().ok_or(ParseError::ExpectedType("object"))?;
47
48 let refresh_token = obj.get("refresh_token")
49 .and_then(Value::as_str)
50 .or(Some(&prev.refresh_token))
51 .ok_or(ParseError::ExpectedFieldType("refresh_token", "string"))?;
52
53 let expires_in = obj.get("expires_in")
54 .and_then(Value::as_i64)
55 .ok_or(ParseError::ExpectedFieldType("expires_in", "i64"))?;
56
57 Ok(Refresh {
58 refresh_token: refresh_token.into(),
59 expires: Utc::now() + Duration::seconds(expires_in),
60 })
61 }
62}
63
64#[cfg(test)]
65mod tests {
66 use chrono::{Utc, Duration};
67
68 use client::response::FromResponse;
69 use super::Refresh;
70
71 #[test]
72 fn from_response() {
73 let json = r#"{"refresh_token":"aaaaaaaa","expires_in":3600}"#.parse().unwrap();
74 let refresh = Refresh::from_response(&json).unwrap();
75 assert_eq!("aaaaaaaa", refresh.refresh_token);
76 assert!(refresh.expires > Utc::now());
77 assert!(refresh.expires <= Utc::now() + Duration::seconds(3600));
78 }
79
80 #[test]
81 fn from_response_inherit() {
82 let json = r#"{"expires_in":3600}"#.parse().unwrap();
83 let prev = Refresh {
84 refresh_token: String::from("aaaaaaaa"),
85 expires: Utc::now(),
86 };
87 let refresh = Refresh::from_response_inherit(&json, &prev).unwrap();
88 assert_eq!("aaaaaaaa", refresh.refresh_token);
89 assert!(refresh.expires > Utc::now());
90 assert!(refresh.expires <= Utc::now() + Duration::seconds(3600));
91 }
92}