mirror of
https://github.com/OMGeeky/yup-oauth2.git
synced 2026-01-07 03:31:31 +01:00
test(auth): removed DeviceFlowHelper
It's superseded by the more powerful `Authenticator`. Adjusted library documentation accordingly, as well as `auth` program.
This commit is contained in:
138
src/device.rs
138
src/device.rs
@@ -1,8 +1,6 @@
|
||||
use std::iter::IntoIterator;
|
||||
use std::time::Duration;
|
||||
use std::default::Default;
|
||||
use std::cmp::min;
|
||||
use std::old_io::timer;
|
||||
|
||||
use hyper;
|
||||
use hyper::header::ContentType;
|
||||
@@ -304,142 +302,6 @@ impl<C, NC> DeviceFlow<C, NC>
|
||||
}
|
||||
}
|
||||
|
||||
/// A utility type to help executing the `DeviceFlow` correctly.
|
||||
///
|
||||
/// This involves polling the authentication server in the given intervals
|
||||
/// until there is a definitive result.
|
||||
///
|
||||
/// These results will be passed the `DeviceFlowHelperDelegate` implementation to deal with
|
||||
/// * presenting the user code
|
||||
/// * inform the user about the progress or errors
|
||||
/// * abort the operation
|
||||
///
|
||||
pub struct DeviceFlowHelper<'a> {
|
||||
delegate: &'a mut (DeviceFlowHelperDelegate + 'a),
|
||||
}
|
||||
|
||||
impl<'a> DeviceFlowHelper<'a> {
|
||||
|
||||
/// Initialize a new instance with the given delegate
|
||||
pub fn new(delegate: &'a mut DeviceFlowHelperDelegate) -> DeviceFlowHelper<'a> {
|
||||
DeviceFlowHelper {
|
||||
delegate: delegate,
|
||||
}
|
||||
}
|
||||
|
||||
/// Blocks until a token was retrieved from the server, or the delegate
|
||||
/// decided to abort the attempt, or the user decided not to authorize
|
||||
/// the application.
|
||||
pub fn retrieve_token<'b, C, NC, T, I>(&mut self,
|
||||
client: C,
|
||||
client_id: &str, client_secret: &str, scopes: I)
|
||||
-> Option<Token>
|
||||
where T: Str,
|
||||
I: IntoIterator<Item=&'b T> + Clone,
|
||||
NC: hyper::net::NetworkConnector,
|
||||
C: BorrowMut<hyper::Client<NC>> {
|
||||
let mut flow = DeviceFlow::new(client);
|
||||
|
||||
// PHASE 1: REQUEST CODE
|
||||
loop {
|
||||
let res = flow.request_code(client_id, client_secret, scopes.clone());
|
||||
match res {
|
||||
RequestResult::Error(err) => {
|
||||
match self.delegate.connection_error(err) {
|
||||
Retry::Abort => return None,
|
||||
Retry::After(d) => timer::sleep(d),
|
||||
}
|
||||
},
|
||||
RequestResult::InvalidClient
|
||||
|RequestResult::InvalidScope(_) => {
|
||||
self.delegate.request_failure(res);
|
||||
return None
|
||||
}
|
||||
RequestResult::ProceedWithPolling(pi) => {
|
||||
self.delegate.present_user_code(pi);
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// PHASE 1: POLL TOKEN
|
||||
loop {
|
||||
match flow.poll_token() {
|
||||
PollResult::Error(err) => {
|
||||
match self.delegate.connection_error(err) {
|
||||
Retry::Abort => return None,
|
||||
Retry::After(d) => timer::sleep(d),
|
||||
}
|
||||
},
|
||||
PollResult::Expired(t) => {
|
||||
self.delegate.expired(t);
|
||||
return None
|
||||
},
|
||||
PollResult::AccessDenied => {
|
||||
self.delegate.denied();
|
||||
return None
|
||||
},
|
||||
PollResult::AuthorizationPending(pi) => {
|
||||
match self.delegate.pending(&pi) {
|
||||
Retry::Abort => return None,
|
||||
Retry::After(d) => timer::sleep(min(d, pi.interval)),
|
||||
}
|
||||
},
|
||||
PollResult::AccessGranted(token) => {
|
||||
return Some(token)
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// A utility type to indicate how operations DeviceFlowHelper operations should be retried
|
||||
pub enum Retry {
|
||||
/// Signal you don't want to retry
|
||||
Abort,
|
||||
/// Signals you want to retry after the given duration
|
||||
After(Duration)
|
||||
}
|
||||
|
||||
/// A partially implemented trait to interact with the `DeviceFlowHelper`
|
||||
///
|
||||
/// The only method that needs to be implemented manually is `present_user_code(...)`,
|
||||
/// as no assumptions are made on how this presentation should happen.
|
||||
pub trait DeviceFlowHelperDelegate {
|
||||
|
||||
/// Called whenever there is an HttpError, usually if there are network problems.
|
||||
///
|
||||
/// Return retry information.
|
||||
fn connection_error(&mut self, hyper::HttpError) -> Retry {
|
||||
Retry::Abort
|
||||
}
|
||||
|
||||
/// The server denied the attempt to obtain a request code
|
||||
fn request_failure(&mut self, RequestResult) {}
|
||||
|
||||
/// The server has returned a `user_code` which must be shown to the user,
|
||||
/// along with the `verification_url`.
|
||||
/// Will be called exactly once, provided we didn't abort during `request_code` phase.
|
||||
fn present_user_code(&mut self, PollInformation);
|
||||
|
||||
/// Called if the request code is expired. You will have to start over in this case.
|
||||
/// This will be the last call the delegate receives.
|
||||
fn expired(&mut self, DateTime<UTC>) {}
|
||||
|
||||
/// Called if the user denied access. You would have to start over.
|
||||
/// This will be the last call the delegate receives.
|
||||
fn denied(&mut self) {}
|
||||
|
||||
/// Called as long as we are waiting for the user to authorize us.
|
||||
/// Can be used to print progress information, or decide to time-out.
|
||||
///
|
||||
/// If the returned `Retry` variant is a duration, it will only be used if it
|
||||
/// is larger than the interval desired by the server.
|
||||
fn pending(&mut self, &PollInformation) -> Retry {
|
||||
Retry::After(Duration::seconds(5))
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#[cfg(test)]
|
||||
pub mod tests {
|
||||
|
||||
Reference in New Issue
Block a user