mod github;
mod openid;
use crate::error::InvalidStateError;
use super::error::OAuthClientBuildError;
use super::ProfileProvider;
use super::{new_basic_client, store::InflightOAuthRequestStore, OAuthClient, SubjectProvider};
pub use github::GithubOAuthClientBuilder;
pub use openid::OpenIdOAuthClientBuilder;
#[derive(Default)]
pub struct OAuthClientBuilder {
client_id: Option<String>,
client_secret: Option<String>,
auth_url: Option<String>,
redirect_url: Option<String>,
token_url: Option<String>,
extra_auth_params: Vec<(String, String)>,
scopes: Vec<String>,
subject_provider: Option<Box<dyn SubjectProvider>>,
inflight_request_store: Option<Box<dyn InflightOAuthRequestStore>>,
profile_provider: Option<Box<dyn ProfileProvider>>,
}
impl OAuthClientBuilder {
pub fn new() -> Self {
Self::default()
}
pub fn build(self) -> Result<OAuthClient, OAuthClientBuildError> {
let client_id = self.client_id.ok_or_else(|| {
InvalidStateError::with_message(
"A client ID is required to successfully build an OAuthClient".into(),
)
})?;
let client_secret = self.client_secret.ok_or_else(|| {
InvalidStateError::with_message(
"A client secret is required to successfully build an OAuthClient".into(),
)
})?;
let auth_url = self.auth_url.ok_or_else(|| {
InvalidStateError::with_message(
"An auth URL is required to successfully build an OAuthClient".into(),
)
})?;
let redirect_url = self.redirect_url.ok_or_else(|| {
InvalidStateError::with_message(
"A redirect URL is required to successfully build an OAuthClient".into(),
)
})?;
let token_url = self.token_url.ok_or_else(|| {
InvalidStateError::with_message(
"A token URL is required to successfully build an OAuthClient".into(),
)
})?;
let subject_provider = self.subject_provider.ok_or_else(|| {
InvalidStateError::with_message(
"A subject provider is required to successfully build an OAuthClient".into(),
)
})?;
let inflight_request_store = self.inflight_request_store.ok_or_else(|| {
InvalidStateError::with_message(
"An in-flight request store is required to successfully build an OAuthClient"
.into(),
)
})?;
let profile_provider = self.profile_provider.ok_or_else(|| {
InvalidStateError::with_message(
"A profile provider is required to successfully build an OAuthClient".into(),
)
})?;
Ok(OAuthClient::new(
new_basic_client(client_id, client_secret, auth_url, redirect_url, token_url)?,
self.extra_auth_params,
self.scopes,
subject_provider.clone(),
inflight_request_store,
profile_provider,
))
}
pub fn with_client_id(mut self, client_id: String) -> Self {
self.client_id = Some(client_id);
self
}
pub fn with_client_secret(mut self, client_secret: String) -> Self {
self.client_secret = Some(client_secret);
self
}
pub fn with_auth_url(mut self, auth_url: String) -> Self {
self.auth_url = Some(auth_url);
self
}
pub fn with_redirect_url(mut self, redirect_url: String) -> Self {
self.redirect_url = Some(redirect_url);
self
}
pub fn with_token_url(mut self, token_url: String) -> Self {
self.token_url = Some(token_url);
self
}
pub fn with_extra_auth_params(mut self, extra_auth_params: Vec<(String, String)>) -> Self {
let mut extra_auth_params = extra_auth_params;
self.extra_auth_params.append(&mut extra_auth_params);
self
}
pub fn with_scopes(mut self, scopes: Vec<String>) -> Self {
let mut scopes = scopes;
self.scopes.append(&mut scopes);
self
}
pub fn with_subject_provider(mut self, subject_provider: Box<dyn SubjectProvider>) -> Self {
self.subject_provider = Some(subject_provider);
self
}
pub fn with_inflight_request_store(
mut self,
inflight_request_store: Box<dyn InflightOAuthRequestStore>,
) -> Self {
self.inflight_request_store = Some(inflight_request_store);
self
}
pub fn with_profile_provider(mut self, profile_provider: Box<dyn ProfileProvider>) -> Self {
self.profile_provider = Some(profile_provider);
self
}
}