mirror of
https://github.com/OMGeeky/yup-oauth2.git
synced 2025-12-31 08:30:05 +01:00
Merge pull request #97 from markcatley/salesforce-device-flow-updates
Updates to allow retrieving a token using the device flow on Salesforce.
This commit is contained in:
@@ -1,9 +1,10 @@
|
||||
use std::iter::{FromIterator, IntoIterator};
|
||||
use std::time::Duration;
|
||||
|
||||
use ::log::{log, error};
|
||||
use chrono::{self, Utc};
|
||||
use futures::stream::Stream;
|
||||
use futures::{future, prelude::*};
|
||||
use futures::stream::Stream;
|
||||
use http;
|
||||
use hyper;
|
||||
use hyper::header;
|
||||
@@ -150,11 +151,13 @@ where
|
||||
| Err(e @ PollError::Expired(_)) => {
|
||||
Box::new(Err(RequestError::Poll(e)).into_future())
|
||||
}
|
||||
Err(_) if i < maxn => {
|
||||
Err(ref e) if i < maxn => {
|
||||
error!("Unknown error from poll token api: {}", e);
|
||||
Box::new(Ok(future::Loop::Continue(i + 1)).into_future())
|
||||
}
|
||||
// Too many attempts.
|
||||
Ok(None) | Err(_) => {
|
||||
error!("Too many poll attempts");
|
||||
Box::new(Err(RequestError::Poll(PollError::TimedOut)).into_future())
|
||||
}
|
||||
})
|
||||
@@ -218,12 +221,17 @@ where
|
||||
return Err(RequestError::ClientError(err));
|
||||
}
|
||||
Ok(res) => {
|
||||
// This return type is defined in https://tools.ietf.org/html/draft-ietf-oauth-device-flow-15#section-3.2
|
||||
// The alias is present as Google use a non-standard name for verification_uri.
|
||||
// According to the standard interval is optional, however, all tested implementations provide it.
|
||||
// verification_uri_complete is optional in the standard but not provided in tested implementations.
|
||||
#[derive(Deserialize)]
|
||||
struct JsonData {
|
||||
device_code: String,
|
||||
user_code: String,
|
||||
verification_url: String,
|
||||
expires_in: i64,
|
||||
#[serde(alias = "verification_url")]
|
||||
verification_uri: String,
|
||||
expires_in: Option<i64>,
|
||||
interval: i64,
|
||||
}
|
||||
|
||||
@@ -242,11 +250,12 @@ where
|
||||
|
||||
let decoded: JsonData = json::from_str(&json_str).unwrap();
|
||||
|
||||
let expires_in = decoded.expires_in.unwrap_or(60 * 60);
|
||||
|
||||
let pi = PollInformation {
|
||||
user_code: decoded.user_code,
|
||||
verification_url: decoded.verification_url,
|
||||
expires_at: Utc::now()
|
||||
+ chrono::Duration::seconds(decoded.expires_in),
|
||||
verification_url: decoded.verification_uri,
|
||||
expires_at: Utc::now() + chrono::Duration::seconds(expires_in),
|
||||
interval: Duration::from_secs(i64::abs(decoded.interval) as u64),
|
||||
};
|
||||
Ok((pi, decoded.device_code))
|
||||
|
||||
23
src/types.rs
23
src/types.rs
@@ -292,16 +292,18 @@ impl Token {
|
||||
if self.access_token.len() == 0 {
|
||||
panic!("called expired() on unset token");
|
||||
}
|
||||
self.expiry_date() - chrono::Duration::minutes(1) <= Utc::now()
|
||||
if let Some(expiry_date) = self.expiry_date() {
|
||||
expiry_date - chrono::Duration::minutes(1) <= Utc::now()
|
||||
} else {
|
||||
false
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns a DateTime object representing our expiry date.
|
||||
pub fn expiry_date(&self) -> DateTime<Utc> {
|
||||
Utc.timestamp(
|
||||
self.expires_in_timestamp
|
||||
.expect("Tokens without an absolute expiry are invalid"),
|
||||
0,
|
||||
)
|
||||
pub fn expiry_date(&self) -> Option<DateTime<Utc>> {
|
||||
let expires_in_timestamp = self.expires_in_timestamp?;
|
||||
|
||||
Utc.timestamp(expires_in_timestamp, 0).into()
|
||||
}
|
||||
|
||||
/// Adjust our stored expiry format to be absolute, using the current time.
|
||||
@@ -311,8 +313,11 @@ impl Token {
|
||||
return self;
|
||||
}
|
||||
|
||||
self.expires_in_timestamp = Some(Utc::now().timestamp() + self.expires_in.unwrap());
|
||||
self.expires_in = None;
|
||||
if let Some(expires_in) = self.expires_in {
|
||||
self.expires_in_timestamp = Some(Utc::now().timestamp() + expires_in);
|
||||
self.expires_in = None;
|
||||
}
|
||||
|
||||
self
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user