Use the builder pattern to create authenticators.

Beyond simply moving to the builder pattern for intialization this has a
few other effects.

The DeviceFlow and InstalledFlow can no longer be used without an
associated Authenticator. This is becaus they no longer have any
publicly accessible constructor. All initialization goes through the
Authenticator. This also means that the flows are always initialized
with a clone of the hyper client used by the Authenticator.

The authenticator uses the builder pattern which allows omitting
optional fields. This means that if users simply want a default hyper
client, they don't need to create one explicitly. One will be created
automatically. If users want to specify a hyper client (maybe to allow
sharing a single client between different libraries) they can still do so
by using the hyper_client method on the builder. Additionally for both
AuthenticatorDelegate's and FlowDelegate's if the user does not specify
an override the default ones will be used.

The builders are now exposed publicly with the names of Authenicator,
InstalledFlow, and DeviceFlow. The structs that actually implement those
behaviors are now hidden and only expose the GetToken trait. This means
some methods that were previously publicly accessible are no longer
available, but the methods appeared to be implementation details that
probably shouldn't have been exposed anyway.
This commit is contained in:
Glenn Griffin
2019-08-12 15:19:42 -07:00
parent 3dec512fa5
commit ccc6601ff3
9 changed files with 357 additions and 207 deletions

View File

@@ -1,36 +1,20 @@
use futures::prelude::*;
use yup_oauth2::{self, Authenticator, GetToken};
use yup_oauth2::{self, Authenticator, DeviceFlow, GetToken};
use hyper::client::Client;
use hyper_rustls::HttpsConnector;
use std::path;
use std::time::Duration;
use tokio;
fn main() {
let creds = yup_oauth2::read_application_secret(path::Path::new("clientsecret.json"))
.expect("clientsecret");
let https = HttpsConnector::new(1);
let client = Client::builder()
.keep_alive(false)
.build::<_, hyper::Body>(https);
let scopes = &["https://www.googleapis.com/auth/youtube.readonly".to_string()];
let ad = yup_oauth2::DefaultFlowDelegate;
let mut df = yup_oauth2::DeviceFlow::new::<String>(client.clone(), creds, ad, None);
df.set_wait_duration(Duration::from_secs(120));
let mut auth = Authenticator::new_disk(
client,
df,
yup_oauth2::DefaultAuthenticatorDelegate,
"tokenstorage.json",
)
.expect("authenticator");
let mut auth = Authenticator::new(DeviceFlow::new(creds))
.persist_tokens_to_disk("tokenstorage.json")
.build()
.expect("authenticator");
let scopes = vec!["https://www.googleapis.com/auth/youtube.readonly"];
let mut rt = tokio::runtime::Runtime::new().unwrap();
let fut = auth
.token(scopes.iter())
.and_then(|tok| Ok(println!("{:?}", tok)));
let fut = auth.token(scopes).and_then(|tok| Ok(println!("{:?}", tok)));
println!("{:?}", rt.block_on(fut));
}