mirror of
https://github.com/OMGeeky/yup-oauth2.git
synced 2026-01-19 08:44:44 +01:00
Improve documentation
This commit is contained in:
@@ -1,3 +1,4 @@
|
||||
//! Module contianing the core functionality for OAuth2 Authentication.
|
||||
use crate::authenticator_delegate::{
|
||||
AuthenticatorDelegate, DefaultAuthenticatorDelegate, FlowDelegate,
|
||||
};
|
||||
@@ -15,6 +16,8 @@ use std::path::PathBuf;
|
||||
use std::sync::Mutex;
|
||||
use std::time::Duration;
|
||||
|
||||
/// Authenticator is responsible for fetching tokens, handling refreshing tokens,
|
||||
/// and optionally persisting tokens to disk.
|
||||
pub struct Authenticator<C> {
|
||||
hyper_client: hyper::Client<C>,
|
||||
app_secret: ApplicationSecret,
|
||||
@@ -27,6 +30,7 @@ impl<C> Authenticator<C>
|
||||
where
|
||||
C: hyper::client::connect::Connect + 'static,
|
||||
{
|
||||
/// Return the current token for the provided scopes.
|
||||
pub async fn token<'a, T>(&'a self, scopes: &'a [T]) -> Result<Token, Error>
|
||||
where
|
||||
T: AsRef<str>,
|
||||
@@ -77,6 +81,7 @@ where
|
||||
}
|
||||
}
|
||||
|
||||
/// Configure an Authenticator using the builder pattern.
|
||||
pub struct AuthenticatorBuilder<C, F> {
|
||||
hyper_client_builder: C,
|
||||
app_secret: ApplicationSecret,
|
||||
@@ -85,8 +90,24 @@ pub struct AuthenticatorBuilder<C, F> {
|
||||
auth_flow: F,
|
||||
}
|
||||
|
||||
/// Create an authenticator that uses the installed flow.
|
||||
/// ```
|
||||
/// # async fn foo() {
|
||||
/// # use yup_oauth2::InstalledFlowReturnMethod;
|
||||
/// # let custom_flow_delegate = yup_oauth2::authenticator_delegate::DefaultFlowDelegate;
|
||||
/// # let app_secret = yup_oauth2::read_application_secret("/tmp/foo").unwrap();
|
||||
/// let authenticator = yup_oauth2::InstalledFlowAuthenticator::builder(
|
||||
/// app_secret,
|
||||
/// InstalledFlowReturnMethod::HTTPRedirect,
|
||||
/// )
|
||||
/// .build()
|
||||
/// .await
|
||||
/// .expect("failed to create authenticator");
|
||||
/// # }
|
||||
/// ```
|
||||
pub struct InstalledFlowAuthenticator;
|
||||
impl InstalledFlowAuthenticator {
|
||||
/// Use the builder pattern to create an Authenticator that uses the installed flow.
|
||||
pub fn builder(
|
||||
app_secret: ApplicationSecret,
|
||||
method: InstalledFlowReturnMethod,
|
||||
@@ -98,8 +119,19 @@ impl InstalledFlowAuthenticator {
|
||||
}
|
||||
}
|
||||
|
||||
/// Create an authenticator that uses the device flow.
|
||||
/// ```
|
||||
/// # async fn foo() {
|
||||
/// # let app_secret = yup_oauth2::read_application_secret("/tmp/foo").unwrap();
|
||||
/// let authenticator = yup_oauth2::DeviceFlowAuthenticator::builder(app_secret)
|
||||
/// .build()
|
||||
/// .await
|
||||
/// .expect("failed to create authenticator");
|
||||
/// # }
|
||||
/// ```
|
||||
pub struct DeviceFlowAuthenticator;
|
||||
impl DeviceFlowAuthenticator {
|
||||
/// Use the builder pattern to create an Authenticator that uses the device flow.
|
||||
pub fn builder(
|
||||
app_secret: ApplicationSecret,
|
||||
) -> AuthenticatorBuilder<DefaultHyperClient, DeviceFlow> {
|
||||
@@ -107,7 +139,45 @@ impl DeviceFlowAuthenticator {
|
||||
}
|
||||
}
|
||||
|
||||
/// Methods available when building any Authenticator.
|
||||
/// ```
|
||||
/// # async fn foo() {
|
||||
/// # let custom_hyper_client = hyper::Client::new();
|
||||
/// # let custom_auth_delegate = yup_oauth2::authenticator_delegate::DefaultAuthenticatorDelegate;
|
||||
/// # let app_secret = yup_oauth2::read_application_secret("/tmp/foo").unwrap();
|
||||
/// let authenticator = yup_oauth2::DeviceFlowAuthenticator::builder(app_secret)
|
||||
/// .hyper_client(custom_hyper_client)
|
||||
/// .persist_tokens_to_disk("/tmp/tokenfile.json")
|
||||
/// .auth_delegate(Box::new(custom_auth_delegate))
|
||||
/// .build()
|
||||
/// .await
|
||||
/// .expect("failed to create authenticator");
|
||||
/// # }
|
||||
/// ```
|
||||
impl<C, F> AuthenticatorBuilder<C, F> {
|
||||
/// Create the authenticator.
|
||||
pub async fn build(self) -> io::Result<Authenticator<C::Connector>>
|
||||
where
|
||||
C: HyperClientBuilder,
|
||||
F: Into<AuthFlow>,
|
||||
{
|
||||
let hyper_client = self.hyper_client_builder.build_hyper_client();
|
||||
let storage = match self.storage_type {
|
||||
StorageType::Memory => Storage::Memory {
|
||||
tokens: Mutex::new(storage::JSONTokens::new()),
|
||||
},
|
||||
StorageType::Disk(path) => Storage::Disk(storage::DiskStorage::new(path).await?),
|
||||
};
|
||||
|
||||
Ok(Authenticator {
|
||||
hyper_client,
|
||||
app_secret: self.app_secret,
|
||||
storage,
|
||||
auth_delegate: self.auth_delegate,
|
||||
auth_flow: self.auth_flow.into(),
|
||||
})
|
||||
}
|
||||
|
||||
fn with_auth_flow(
|
||||
app_secret: ApplicationSecret,
|
||||
auth_flow: F,
|
||||
@@ -153,31 +223,23 @@ impl<C, F> AuthenticatorBuilder<C, F> {
|
||||
..self
|
||||
}
|
||||
}
|
||||
|
||||
/// Create the authenticator.
|
||||
pub async fn build(self) -> io::Result<Authenticator<C::Connector>>
|
||||
where
|
||||
C: HyperClientBuilder,
|
||||
F: Into<AuthFlow>,
|
||||
{
|
||||
let hyper_client = self.hyper_client_builder.build_hyper_client();
|
||||
let storage = match self.storage_type {
|
||||
StorageType::Memory => Storage::Memory {
|
||||
tokens: Mutex::new(storage::JSONTokens::new()),
|
||||
},
|
||||
StorageType::Disk(path) => Storage::Disk(storage::DiskStorage::new(path).await?),
|
||||
};
|
||||
|
||||
Ok(Authenticator {
|
||||
hyper_client,
|
||||
app_secret: self.app_secret,
|
||||
storage,
|
||||
auth_delegate: self.auth_delegate,
|
||||
auth_flow: self.auth_flow.into(),
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
/// Methods available when building a device flow Authenticator.
|
||||
/// ```
|
||||
/// # async fn foo() {
|
||||
/// # let custom_flow_delegate = yup_oauth2::authenticator_delegate::DefaultFlowDelegate;
|
||||
/// # let app_secret = yup_oauth2::read_application_secret("/tmp/foo").unwrap();
|
||||
/// let authenticator = yup_oauth2::DeviceFlowAuthenticator::builder(app_secret)
|
||||
/// .device_code_url("foo")
|
||||
/// .flow_delegate(Box::new(custom_flow_delegate))
|
||||
/// .wait_duration(std::time::Duration::from_secs(120))
|
||||
/// .grant_type("foo")
|
||||
/// .build()
|
||||
/// .await
|
||||
/// .expect("failed to create authenticator");
|
||||
/// # }
|
||||
/// ```
|
||||
impl<C> AuthenticatorBuilder<C, DeviceFlow> {
|
||||
/// Use the provided device code url.
|
||||
pub fn device_code_url(self, url: impl Into<Cow<'static, str>>) -> Self {
|
||||
@@ -224,6 +286,22 @@ impl<C> AuthenticatorBuilder<C, DeviceFlow> {
|
||||
}
|
||||
}
|
||||
|
||||
/// Methods available when building an installed flow Authenticator.
|
||||
/// ```
|
||||
/// # async fn foo() {
|
||||
/// # use yup_oauth2::InstalledFlowReturnMethod;
|
||||
/// # let custom_flow_delegate = yup_oauth2::authenticator_delegate::DefaultFlowDelegate;
|
||||
/// # let app_secret = yup_oauth2::read_application_secret("/tmp/foo").unwrap();
|
||||
/// let authenticator = yup_oauth2::InstalledFlowAuthenticator::builder(
|
||||
/// app_secret,
|
||||
/// InstalledFlowReturnMethod::HTTPRedirect,
|
||||
/// )
|
||||
/// .flow_delegate(Box::new(custom_flow_delegate))
|
||||
/// .build()
|
||||
/// .await
|
||||
/// .expect("failed to create authenticator");
|
||||
/// # }
|
||||
/// ```
|
||||
impl<C> AuthenticatorBuilder<C, InstalledFlow> {
|
||||
/// Use the provided FlowDelegate.
|
||||
pub fn flow_delegate(self, flow_delegate: Box<dyn FlowDelegate>) -> Self {
|
||||
@@ -285,8 +363,10 @@ mod private {
|
||||
|
||||
/// A trait implemented for any hyper::Client as well as teh DefaultHyperClient.
|
||||
pub trait HyperClientBuilder {
|
||||
/// The hyper connector that the resulting hyper client will use.
|
||||
type Connector: hyper::client::connect::Connect + 'static;
|
||||
|
||||
/// Create a hyper::Client
|
||||
fn build_hyper_client(self) -> hyper::Client<Self::Connector>;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
//! Module containing types related to delegates.
|
||||
|
||||
use crate::error::{Error, PollError, RefreshError};
|
||||
|
||||
use std::error::Error as StdError;
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
//! Module containing various error types.
|
||||
|
||||
use std::error::Error as StdError;
|
||||
use std::fmt;
|
||||
use std::io;
|
||||
|
||||
15
src/lib.rs
15
src/lib.rs
@@ -20,19 +20,19 @@
|
||||
//! based on the Google APIs; it may or may not work with other providers.
|
||||
//!
|
||||
//! # Installed Flow Usage
|
||||
//! The `InstalledFlow` involves showing a URL to the user (or opening it in a browser)
|
||||
//! The installed flow involves showing a URL to the user (or opening it in a browser)
|
||||
//! and then either prompting the user to enter a displayed code, or make the authorizing
|
||||
//! website redirect to a web server spun up by this library and running on localhost.
|
||||
//!
|
||||
//! In order to use the interactive method, use the `InstalledInteractive` `FlowType`;
|
||||
//! for the redirect method, use `InstalledRedirect`, with the port number to let the
|
||||
//! server listen on.
|
||||
//! In order to use the interactive method, use the `Interactive` `InstalledFlowReturnMethod`;
|
||||
//! for the redirect method, use `HTTPRedirect`.
|
||||
//!
|
||||
//! You can implement your own `AuthenticatorDelegate` in order to customize the flow;
|
||||
//! the `InstalledFlow` uses the `present_user_url` method.
|
||||
//! the installed flow uses the `present_user_url` method.
|
||||
//!
|
||||
//! The returned `Token` is stored permanently in the given token storage in order to
|
||||
//! authorize future API requests to the same scopes.
|
||||
//! The returned `Token` will be stored in memory in order to authorize future
|
||||
//! API requests to the same scopes. The tokens can optionally be persisted to
|
||||
//! disk by using `persist_tokens_to_disk` when creating the authenticator.
|
||||
//!
|
||||
//! The following example, which is derived from the (actual and runnable) example in
|
||||
//! `examples/test-installed/`, shows the basics of using this crate:
|
||||
@@ -68,6 +68,7 @@
|
||||
//! }
|
||||
//! ```
|
||||
//!
|
||||
#![deny(missing_docs)]
|
||||
pub mod authenticator;
|
||||
pub mod authenticator_delegate;
|
||||
mod device;
|
||||
|
||||
@@ -69,15 +69,25 @@ fn decode_rsa_key(pem_pkcs8: &str) -> Result<PrivateKey, io::Error> {
|
||||
#[derive(Serialize, Deserialize, Debug, Clone)]
|
||||
pub struct ServiceAccountKey {
|
||||
#[serde(rename = "type")]
|
||||
/// key_type
|
||||
pub key_type: Option<String>,
|
||||
/// project_id
|
||||
pub project_id: Option<String>,
|
||||
/// private_key_id
|
||||
pub private_key_id: Option<String>,
|
||||
/// private_key
|
||||
pub private_key: String,
|
||||
/// client_email
|
||||
pub client_email: String,
|
||||
/// client_id
|
||||
pub client_id: Option<String>,
|
||||
/// auth_uri
|
||||
pub auth_uri: Option<String>,
|
||||
/// token_uri
|
||||
pub token_uri: String,
|
||||
/// auth_provider_x509_cert_url
|
||||
pub auth_provider_x509_cert_url: Option<String>,
|
||||
/// client_x509_cert_url
|
||||
pub client_x509_cert_url: Option<String>,
|
||||
}
|
||||
|
||||
@@ -150,8 +160,19 @@ impl JWTSigner {
|
||||
}
|
||||
}
|
||||
|
||||
/// Create an authenticator that uses a service account.
|
||||
/// ```
|
||||
/// # async fn foo() {
|
||||
/// # let service_key = yup_oauth2::service_account_key_from_file("/tmp/foo").unwrap();
|
||||
/// let authenticator = yup_oauth2::ServiceAccountAuthenticator::builder(service_key)
|
||||
/// .build()
|
||||
/// .expect("failed to create authenticator");
|
||||
/// # }
|
||||
/// ```
|
||||
pub struct ServiceAccountAuthenticator;
|
||||
impl ServiceAccountAuthenticator {
|
||||
/// Use the builder pattern to create an authenticator that uses a service
|
||||
/// account.
|
||||
pub fn builder(key: ServiceAccountKey) -> Builder<DefaultHyperClient> {
|
||||
Builder {
|
||||
client: DefaultHyperClient,
|
||||
@@ -161,12 +182,25 @@ impl ServiceAccountAuthenticator {
|
||||
}
|
||||
}
|
||||
|
||||
/// Configure a service account authenticator using the builder pattern.
|
||||
pub struct Builder<C> {
|
||||
client: C,
|
||||
key: ServiceAccountKey,
|
||||
subject: Option<String>,
|
||||
}
|
||||
|
||||
/// Methods available when building a service account authenticator.
|
||||
/// ```
|
||||
/// # async fn foo() {
|
||||
/// # let custom_hyper_client = hyper::Client::new();
|
||||
/// # let service_key = yup_oauth2::service_account_key_from_file("/tmp/foo").unwrap();
|
||||
/// let authenticator = yup_oauth2::ServiceAccountAuthenticator::builder(service_key)
|
||||
/// .hyper_client(custom_hyper_client)
|
||||
/// .subject("foo")
|
||||
/// .build()
|
||||
/// .expect("failed to create authenticator");
|
||||
/// # }
|
||||
/// ```
|
||||
impl<C> Builder<C> {
|
||||
/// Use the provided hyper client.
|
||||
pub fn hyper_client<NewC: HyperClientBuilder>(self, hyper_client: NewC) -> Builder<NewC> {
|
||||
@@ -178,9 +212,9 @@ impl<C> Builder<C> {
|
||||
}
|
||||
|
||||
/// Use the provided subject.
|
||||
pub fn subject(self, subject: String) -> Self {
|
||||
pub fn subject(self, subject: impl Into<String>) -> Self {
|
||||
Builder {
|
||||
subject: Some(subject),
|
||||
subject: Some(subject.into()),
|
||||
..self
|
||||
}
|
||||
}
|
||||
@@ -194,6 +228,7 @@ impl<C> Builder<C> {
|
||||
}
|
||||
}
|
||||
|
||||
/// ServiceAccountAccess can fetch oauth tokens using a service account.
|
||||
pub struct ServiceAccountAccess<C> {
|
||||
client: hyper::Client<C>,
|
||||
key: ServiceAccountKey,
|
||||
@@ -223,6 +258,7 @@ where
|
||||
})
|
||||
}
|
||||
|
||||
/// Return the current token for the provided scopes.
|
||||
pub async fn token<T>(&self, scopes: &[T]) -> Result<Token, Error>
|
||||
where
|
||||
T: AsRef<str>,
|
||||
|
||||
20
src/types.rs
20
src/types.rs
@@ -80,8 +80,8 @@ pub struct ApplicationSecret {
|
||||
pub token_uri: String,
|
||||
/// The authorization server endpoint URI.
|
||||
pub auth_uri: String,
|
||||
/// The redirect uris.
|
||||
pub redirect_uris: Vec<String>,
|
||||
|
||||
/// Name of the google project the credentials are associated with
|
||||
pub project_id: Option<String>,
|
||||
/// The service account email associated with the client.
|
||||
@@ -93,27 +93,13 @@ pub struct ApplicationSecret {
|
||||
pub client_x509_cert_url: Option<String>,
|
||||
}
|
||||
|
||||
impl ApplicationSecret {
|
||||
pub const fn empty() -> Self {
|
||||
ApplicationSecret {
|
||||
client_id: String::new(),
|
||||
client_secret: String::new(),
|
||||
token_uri: String::new(),
|
||||
auth_uri: String::new(),
|
||||
redirect_uris: Vec::new(),
|
||||
project_id: None,
|
||||
client_email: None,
|
||||
auth_provider_x509_cert_url: None,
|
||||
client_x509_cert_url: None,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// A type to facilitate reading and writing the json secret file
|
||||
/// as returned by the [google developer console](https://code.google.com/apis/console)
|
||||
#[derive(Deserialize, Serialize, Default)]
|
||||
pub struct ConsoleApplicationSecret {
|
||||
/// web app secret
|
||||
pub web: Option<ApplicationSecret>,
|
||||
/// installed app secret
|
||||
pub installed: Option<ApplicationSecret>,
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user