use crate::authentication::{IdentityProvider, IdentityProviderHandler};
use oauth2_client::re_exports::RedirectUri;
use std::env;
use std::error::Error;
use strum::IntoEnumIterator;
pub fn new(idp: IdentityProvider) -> Box<dyn IdentityProviderHandler> {
match idp {
#[cfg(feature = "authentication-amazon")]
IdentityProvider::Amazon => Box::new(super::amazon::AmazonIdentityProviderHandler::default()),
#[cfg(feature = "authentication-apple")]
IdentityProvider::Apple => Box::new(super::apple::AppleIdentityProviderHandler::default()),
#[cfg(feature = "authentication-digitalocean")]
IdentityProvider::DigitalOcean => {
Box::new(super::digital_ocean::DigitalOceanIdentityProviderHandler::default())
}
#[cfg(feature = "authentication-facebook")]
IdentityProvider::Facebook => Box::new(super::facebook::FacebookIdentityProviderHandler::default()),
#[cfg(feature = "authentication-github")]
IdentityProvider::GitHub => Box::new(super::github::GitHubIdentityProviderHandler::default()),
#[cfg(feature = "authentication-gitlab")]
IdentityProvider::GitLab => Box::new(super::gitlab::GitLabIdentityProviderHandler::default()),
#[cfg(feature = "authentication-google")]
IdentityProvider::Google => Box::new(super::google::GoogleIdentityProviderHandler::default()),
#[cfg(feature = "authentication-instagram")]
IdentityProvider::Instagram => Box::new(super::instagram::InstagramIdentityProviderHandler::default()),
#[cfg(feature = "authentication-linode")]
IdentityProvider::Linode => Box::new(super::linode::LinodeIdentityProviderHandler::default()),
#[cfg(feature = "authentication-microsoft")]
IdentityProvider::Microsoft => Box::new(super::microsoft::MicrosoftIdentityProviderHandler::default()),
#[cfg(feature = "authentication-okta")]
IdentityProvider::Okta => Box::new(super::okta::OktaIdentityProviderHandler::default()),
#[cfg(feature = "authentication-twitter")]
IdentityProvider::Twitter => Box::new(super::twitter::TwitterIdentityProviderHandler::default()),
}
}
pub struct IdentityProviderHandlerInfo {
pub idp: IdentityProvider,
pub handler: Box<dyn IdentityProviderHandler>,
pub client_secret: String,
pub redirect_uri: RedirectUri,
}
#[allow(unused)]
pub fn new_from_env_for_client_id(client_id: &str) -> Result<IdentityProviderHandlerInfo, Box<dyn Error>> {
for idp in IdentityProvider::iter() {
let client_id_env_var_name = format!("{}_CLIENT_ID", idp.as_ref().to_uppercase());
if let Ok(client_id_) = env::var(&client_id_env_var_name) {
if client_id != client_id_ {
continue;
}
let client_secret_env_var_name = format!("{}_CLIENT_SECRET", idp.as_ref().to_uppercase());
let client_secret = match env::var(&client_secret_env_var_name) {
Ok(secret) => secret,
Err(e) => {
let msg =
format!("Client is attempting {idp} login, but {client_secret_env_var_name} is not configured");
log::error!("{msg}");
return Err(e.into());
}
};
let redirect_url_env_var_name = format!("{}_REDIRECT_URL", idp.as_ref().to_uppercase());
let redirect_uri = match env::var(&redirect_url_env_var_name) {
Ok(redirect_url) => redirect_url.parse()?,
Err(e) => {
let msg =
format!("Client is attempting {idp} login, but {redirect_url_env_var_name} is not configured");
log::error!("{msg}");
return Err(e.into());
}
};
let handler = new(idp.clone());
return Ok(IdentityProviderHandlerInfo {
idp,
handler,
client_secret,
redirect_uri,
});
}
}
Err("Unsupported IdP".into())
}