refactor(auth): move into central auth-engine setup
Some checks failed
continuous-integration/drone/push Build is failing
Some checks failed
continuous-integration/drone/push Build is failing
Signed-off-by: kjuulh <contact@kjuulh.io>
This commit is contained in:
parent
5837ee0288
commit
0bb7074334
@ -14,31 +14,31 @@ pub struct IntrospectionState {
|
|||||||
|
|
||||||
#[derive(clap::Args, Clone, Debug, PartialEq, Eq)]
|
#[derive(clap::Args, Clone, Debug, PartialEq, Eq)]
|
||||||
pub struct IntrospectionConfigClap {
|
pub struct IntrospectionConfigClap {
|
||||||
#[arg(
|
// #[arg(
|
||||||
env = "ZITADEL_AUTHORITY",
|
// env = "ZITADEL_AUTHORITY",
|
||||||
long = "zitadel-authority",
|
// long = "zitadel-authority",
|
||||||
group = "introspection"
|
// group = "zitadel"
|
||||||
)]
|
// )]
|
||||||
pub authority: String,
|
pub authority: Option<String>,
|
||||||
|
|
||||||
#[arg(
|
// #[arg(
|
||||||
env = "ZITADEL_CLIENT_ID",
|
// env = "ZITADEL_CLIENT_ID",
|
||||||
long = "zitadel-client-id",
|
// long = "zitadel-client-id",
|
||||||
group = "introspection"
|
// group = "zitadel"
|
||||||
)]
|
// )]
|
||||||
pub client_id: String,
|
pub client_id: Option<String>,
|
||||||
#[arg(
|
// #[arg(
|
||||||
env = "ZITADEL_CLIENT_SECRET",
|
// env = "ZITADEL_CLIENT_SECRET",
|
||||||
long = "zitadel-client-secret",
|
// long = "zitadel-client-secret",
|
||||||
group = "introspection"
|
// group = "zitadel"
|
||||||
)]
|
// )]
|
||||||
pub client_secret: String,
|
pub client_secret: Option<String>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl IntrospectionConfigClap {
|
impl IntrospectionConfigClap {
|
||||||
async fn try_into(self) -> anyhow::Result<IntrospectionState> {
|
async fn try_into(self) -> anyhow::Result<IntrospectionState> {
|
||||||
IntrospectionStateBuilder::new(&self.authority)
|
IntrospectionStateBuilder::new(&self.authority.unwrap())
|
||||||
.with_basic_auth(&self.client_id, &self.client_secret)
|
.with_basic_auth(&self.client_id.unwrap(), &self.client_secret.unwrap())
|
||||||
.build()
|
.build()
|
||||||
.await
|
.await
|
||||||
.context("failed to generate an introspection builder")
|
.context("failed to generate an introspection builder")
|
||||||
|
@ -1,2 +1,149 @@
|
|||||||
|
pub use introspection::IntrospectionConfigClap;
|
||||||
|
|
||||||
mod introspection;
|
mod introspection;
|
||||||
mod oauth;
|
mod oauth;
|
||||||
|
|
||||||
|
#[derive(clap::ValueEnum, Clone, PartialEq, Eq, Debug)]
|
||||||
|
pub enum AuthEngine {
|
||||||
|
Noop,
|
||||||
|
Zitadel,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(clap::Args, Clone, PartialEq, Eq, Debug)]
|
||||||
|
pub struct AuthClap {
|
||||||
|
#[arg(
|
||||||
|
env = "AUTH_ENGINE",
|
||||||
|
long = "auth-engine",
|
||||||
|
requires_ifs = [
|
||||||
|
( "zitadel", "ZitadelClap" )
|
||||||
|
],
|
||||||
|
default_value = "noop" )
|
||||||
|
]
|
||||||
|
pub engine: AuthEngine,
|
||||||
|
|
||||||
|
#[clap(flatten)]
|
||||||
|
pub zitadel: ZitadelClap,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(clap::Args, Clone, Debug, PartialEq, Eq)]
|
||||||
|
#[group(requires_all = ["auth_url", "client_id", "client_secret", "redirect_url", "token_url", "authority_url"])]
|
||||||
|
pub struct ZitadelClap {
|
||||||
|
#[arg(env = "ZITADEL_AUTH_URL", long = "zitadel-auth-url")]
|
||||||
|
pub auth_url: Option<String>,
|
||||||
|
|
||||||
|
#[arg(env = "ZITADEL_CLIENT_ID", long = "zitadel-client-id")]
|
||||||
|
pub client_id: Option<String>,
|
||||||
|
|
||||||
|
#[arg(env = "ZITADEL_CLIENT_SECRET", long = "zitadel-client-secret")]
|
||||||
|
pub client_secret: Option<String>,
|
||||||
|
|
||||||
|
#[arg(env = "ZITADEL_REDIRECT_URL", long = "zitadel-redirect-url")]
|
||||||
|
pub redirect_url: Option<String>,
|
||||||
|
|
||||||
|
#[arg(env = "ZITADEL_AUTHORITY_URL", long = "zitadel-authority-url")]
|
||||||
|
pub authority_url: Option<String>,
|
||||||
|
|
||||||
|
#[arg(env = "ZITADEL_TOKEN_URL", long = "zitadel-token-url")]
|
||||||
|
pub token_url: Option<String>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl AuthClap {}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod test {
|
||||||
|
use crate::{AuthClap, AuthEngine, ZitadelClap};
|
||||||
|
use clap::Parser;
|
||||||
|
use pretty_assertions::assert_eq;
|
||||||
|
|
||||||
|
#[derive(Parser)]
|
||||||
|
#[command(author, version, about, long_about = None)]
|
||||||
|
pub struct Cli {
|
||||||
|
#[command(subcommand)]
|
||||||
|
command: Commands,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(clap::Subcommand, Clone, Debug, Eq, PartialEq)]
|
||||||
|
pub enum Commands {
|
||||||
|
One {
|
||||||
|
#[clap(flatten)]
|
||||||
|
options: AuthClap,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_command_parse_as_default_noop() {
|
||||||
|
let cli: Cli = Cli::parse_from(&["base", "one"]);
|
||||||
|
|
||||||
|
assert_eq!(
|
||||||
|
cli.command,
|
||||||
|
Commands::One {
|
||||||
|
options: AuthClap {
|
||||||
|
engine: AuthEngine::Noop,
|
||||||
|
zitadel: ZitadelClap {
|
||||||
|
auth_url: None,
|
||||||
|
client_id: None,
|
||||||
|
client_secret: None,
|
||||||
|
redirect_url: None,
|
||||||
|
token_url: None,
|
||||||
|
authority_url: None,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_command_parse_as_noop() {
|
||||||
|
let cli: Cli = Cli::parse_from(&["base", "one", "--auth-engine", "noop"]);
|
||||||
|
|
||||||
|
assert_eq!(
|
||||||
|
cli.command,
|
||||||
|
Commands::One {
|
||||||
|
options: AuthClap {
|
||||||
|
engine: AuthEngine::Noop,
|
||||||
|
zitadel: ZitadelClap {
|
||||||
|
auth_url: None,
|
||||||
|
client_id: None,
|
||||||
|
client_secret: None,
|
||||||
|
redirect_url: None,
|
||||||
|
token_url: None,
|
||||||
|
authority_url: None,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_command_parse_as_zitadel() {
|
||||||
|
let cli: Cli = Cli::parse_from(&[
|
||||||
|
"base",
|
||||||
|
"one",
|
||||||
|
"--auth-engine",
|
||||||
|
"zitadel",
|
||||||
|
"--zitadel-client-id=something",
|
||||||
|
"--zitadel-client-secret=something",
|
||||||
|
"--zitadel-auth-url=https://something",
|
||||||
|
"--zitadel-redirect-url=https://something",
|
||||||
|
"--zitadel-token-url=https://something",
|
||||||
|
"--zitadel-authority-url=https://something",
|
||||||
|
]);
|
||||||
|
|
||||||
|
assert_eq!(
|
||||||
|
cli.command,
|
||||||
|
Commands::One {
|
||||||
|
options: AuthClap {
|
||||||
|
engine: AuthEngine::Zitadel,
|
||||||
|
zitadel: ZitadelClap {
|
||||||
|
auth_url: Some("https://something".into()),
|
||||||
|
client_id: Some("something".into()),
|
||||||
|
client_secret: Some("something".into()),
|
||||||
|
redirect_url: Some("https://something".into()),
|
||||||
|
token_url: Some("https://something".into()),
|
||||||
|
authority_url: Some("https://something".into()),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -3,40 +3,6 @@ use oauth2::{basic::BasicClient, AuthUrl, ClientId, ClientSecret, RedirectUrl, T
|
|||||||
use std::ops::Deref;
|
use std::ops::Deref;
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
|
|
||||||
#[derive(Clone, clap::Args, Debug, PartialEq, Eq)]
|
|
||||||
pub struct OAuthClientClap {
|
|
||||||
#[clap(flatten)]
|
|
||||||
zitadel: ZitadelClap,
|
|
||||||
|
|
||||||
#[clap(flatten)]
|
|
||||||
noop: NoopConfig,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Clone, clap::Args, Debug, PartialEq, Eq)]
|
|
||||||
pub struct NoopConfig {
|
|
||||||
#[arg(env = "OAUTH_NOOP", long = "oauth-noop", group = "auth")]
|
|
||||||
pub oauth_noop: Option<bool>,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(clap::Args, Clone, Debug, PartialEq, Eq)]
|
|
||||||
#[group(requires_all = ["auth_url", "client_id", "client_secret", "redirect_url", "token_url"])]
|
|
||||||
pub struct ZitadelClap {
|
|
||||||
#[arg(env = "ZITADEL_AUTH_URL", long = "zitadel-auth-url", group = "auth")]
|
|
||||||
pub auth_url: Option<String>,
|
|
||||||
|
|
||||||
#[arg(env = "ZITADEL_CLIENT_ID", long = "zitadel-client-id")]
|
|
||||||
pub client_id: Option<String>,
|
|
||||||
|
|
||||||
#[arg(env = "ZITADEL_CLIENT_SECRET", long = "zitadel-client-secret")]
|
|
||||||
pub client_secret: Option<String>,
|
|
||||||
|
|
||||||
#[arg(env = "ZITADEL_REDIRECT_URL", long = "zitadel-redirect-url")]
|
|
||||||
pub redirect_url: Option<String>,
|
|
||||||
|
|
||||||
#[arg(env = "ZITADEL_TOKEN_URL", long = "zitadel-token-url")]
|
|
||||||
pub token_url: Option<String>,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[async_trait]
|
#[async_trait]
|
||||||
pub trait OAuthClient {
|
pub trait OAuthClient {
|
||||||
async fn get_token(&self) -> anyhow::Result<()>;
|
async fn get_token(&self) -> anyhow::Result<()>;
|
||||||
@ -53,21 +19,6 @@ impl OAuth {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone)]
|
|
||||||
pub enum OAuthConfig {
|
|
||||||
Zitadel(ZitadelConfig),
|
|
||||||
Noop,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl From<OAuthConfig> for OAuth {
|
|
||||||
fn from(value: OAuthConfig) -> Self {
|
|
||||||
match value {
|
|
||||||
OAuthConfig::Zitadel(c) => c.into(),
|
|
||||||
OAuthConfig::Noop => Self::new_noop(),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Deref for OAuth {
|
impl Deref for OAuth {
|
||||||
type Target = Arc<dyn OAuthClient + Send + Sync + 'static>;
|
type Target = Arc<dyn OAuthClient + Send + Sync + 'static>;
|
||||||
|
|
||||||
@ -94,19 +45,14 @@ impl OAuthClient for NoopOAuthClient {
|
|||||||
|
|
||||||
// -- Zitadel
|
// -- Zitadel
|
||||||
|
|
||||||
#[derive(clap::Args, Clone)]
|
#[derive(Clone)]
|
||||||
#[group(conflicts_with = "NoopConfig", required = false)]
|
|
||||||
pub struct ZitadelConfig {
|
pub struct ZitadelConfig {
|
||||||
#[clap(env = "ZITADEL_AUTH_URL", long = "zitadel-auth-url")]
|
|
||||||
auth_url: String,
|
auth_url: String,
|
||||||
#[clap(env = "ZITADEL_CLIENT_ID", long = "zitadel-client-id")]
|
|
||||||
client_id: String,
|
client_id: String,
|
||||||
#[clap(env = "ZITADEL_CLIENT_SECRET", long = "zitadel-client-secret")]
|
|
||||||
client_secret: String,
|
client_secret: String,
|
||||||
#[clap(env = "ZITADEL_REDIRECT_URL", long = "zitadel-redirect-url")]
|
|
||||||
redirect_url: String,
|
redirect_url: String,
|
||||||
#[clap(env = "ZITADEL_TOKEN_URL", long = "zitadel-token-url")]
|
|
||||||
token_url: String,
|
token_url: String,
|
||||||
|
authority_url: String,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct ZitadelOAuthClient {
|
pub struct ZitadelOAuthClient {
|
||||||
@ -120,6 +66,7 @@ impl ZitadelOAuthClient {
|
|||||||
redirect_url: impl Into<String>,
|
redirect_url: impl Into<String>,
|
||||||
auth_url: impl Into<String>,
|
auth_url: impl Into<String>,
|
||||||
token_url: impl Into<String>,
|
token_url: impl Into<String>,
|
||||||
|
authority_url: impl Into<String>,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
Self {
|
Self {
|
||||||
client: Self::oauth_client(ZitadelConfig {
|
client: Self::oauth_client(ZitadelConfig {
|
||||||
@ -128,6 +75,7 @@ impl ZitadelOAuthClient {
|
|||||||
redirect_url: redirect_url.into(),
|
redirect_url: redirect_url.into(),
|
||||||
auth_url: auth_url.into(),
|
auth_url: auth_url.into(),
|
||||||
token_url: token_url.into(),
|
token_url: token_url.into(),
|
||||||
|
authority_url: authority_url.into(),
|
||||||
}),
|
}),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -151,6 +99,7 @@ impl From<ZitadelConfig> for ZitadelOAuthClient {
|
|||||||
value.redirect_url,
|
value.redirect_url,
|
||||||
value.auth_url,
|
value.auth_url,
|
||||||
value.token_url,
|
value.token_url,
|
||||||
|
value.authority_url,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -164,8 +113,9 @@ impl OAuthClient for ZitadelOAuthClient {
|
|||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use crate::oauth::{
|
use crate::{
|
||||||
NoopConfig, OAuth, OAuthClientClap, OAuthConfig, ZitadelClap, ZitadelConfig,
|
oauth::{OAuth, ZitadelConfig},
|
||||||
|
ZitadelClap,
|
||||||
};
|
};
|
||||||
use clap::Parser;
|
use clap::Parser;
|
||||||
use sealed_test::prelude::*;
|
use sealed_test::prelude::*;
|
||||||
@ -174,7 +124,7 @@ mod tests {
|
|||||||
#[command(author, version, about, long_about = None)]
|
#[command(author, version, about, long_about = None)]
|
||||||
pub struct Cli {
|
pub struct Cli {
|
||||||
#[clap(flatten)]
|
#[clap(flatten)]
|
||||||
options: OAuthClientClap,
|
options: ZitadelClap,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Parser, Debug)]
|
#[derive(Parser, Debug)]
|
||||||
@ -188,38 +138,10 @@ mod tests {
|
|||||||
pub enum Commands {
|
pub enum Commands {
|
||||||
One {
|
One {
|
||||||
#[clap(flatten)]
|
#[clap(flatten)]
|
||||||
options: OAuthClientClap,
|
options: ZitadelClap,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
#[tokio::test]
|
|
||||||
async fn test_noop() {
|
|
||||||
OAuth::from(OAuthConfig::Noop).get_token().await.unwrap();
|
|
||||||
}
|
|
||||||
|
|
||||||
#[tokio::test]
|
|
||||||
async fn test_zitadel() {
|
|
||||||
OAuth::from(OAuthConfig::Zitadel(ZitadelConfig {
|
|
||||||
client_id: "something".into(),
|
|
||||||
client_secret: "something".into(),
|
|
||||||
redirect_url: "https://something".into(),
|
|
||||||
auth_url: "https://something".into(),
|
|
||||||
token_url: "https://something".into(),
|
|
||||||
}))
|
|
||||||
.get_token()
|
|
||||||
.await
|
|
||||||
.unwrap();
|
|
||||||
}
|
|
||||||
|
|
||||||
#[tokio::test]
|
|
||||||
async fn test_parse_clap_noop() {
|
|
||||||
let cli: Cli = Cli::parse_from(&["base", "--oauth-noop=true"]);
|
|
||||||
|
|
||||||
assert_eq!(cli.options.noop.oauth_noop, Some(true));
|
|
||||||
|
|
||||||
println!("{:?}", cli.options);
|
|
||||||
}
|
|
||||||
|
|
||||||
#[tokio::test]
|
#[tokio::test]
|
||||||
async fn test_parse_clap_zitadel() {
|
async fn test_parse_clap_zitadel() {
|
||||||
let cli: Cli = Cli::parse_from(&[
|
let cli: Cli = Cli::parse_from(&[
|
||||||
@ -229,17 +151,19 @@ mod tests {
|
|||||||
"--zitadel-auth-url=https://something",
|
"--zitadel-auth-url=https://something",
|
||||||
"--zitadel-redirect-url=https://something",
|
"--zitadel-redirect-url=https://something",
|
||||||
"--zitadel-token-url=https://something",
|
"--zitadel-token-url=https://something",
|
||||||
|
"--zitadel-authority-url=https://something",
|
||||||
]);
|
]);
|
||||||
println!("{:?}", cli.options);
|
println!("{:?}", cli.options);
|
||||||
|
|
||||||
pretty_assertions::assert_eq!(
|
pretty_assertions::assert_eq!(
|
||||||
cli.options.zitadel,
|
cli.options,
|
||||||
ZitadelClap {
|
ZitadelClap {
|
||||||
auth_url: Some("https://something".into()),
|
auth_url: Some("https://something".into()),
|
||||||
client_id: Some("something".into()),
|
client_id: Some("something".into()),
|
||||||
client_secret: Some("something".into()),
|
client_secret: Some("something".into()),
|
||||||
redirect_url: Some("https://something".into()),
|
redirect_url: Some("https://something".into()),
|
||||||
token_url: Some("https://something".into())
|
token_url: Some("https://something".into()),
|
||||||
|
authority_url: Some("https://something".into()),
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@ -254,6 +178,7 @@ mod tests {
|
|||||||
"--zitadel-auth-url=https://something",
|
"--zitadel-auth-url=https://something",
|
||||||
"--zitadel-redirect-url=https://something",
|
"--zitadel-redirect-url=https://something",
|
||||||
"--zitadel-token-url=https://something",
|
"--zitadel-token-url=https://something",
|
||||||
|
"--zitadel-authority-url=https://something",
|
||||||
]);
|
]);
|
||||||
|
|
||||||
pretty_assertions::assert_eq!(cli.is_err(), true);
|
pretty_assertions::assert_eq!(cli.is_err(), true);
|
||||||
@ -266,21 +191,20 @@ mod tests {
|
|||||||
std::env::set_var("ZITADEL_AUTH_URL", "https://something");
|
std::env::set_var("ZITADEL_AUTH_URL", "https://something");
|
||||||
std::env::set_var("ZITADEL_REDIRECT_URL", "https://something");
|
std::env::set_var("ZITADEL_REDIRECT_URL", "https://something");
|
||||||
std::env::set_var("ZITADEL_TOKEN_URL", "https://something");
|
std::env::set_var("ZITADEL_TOKEN_URL", "https://something");
|
||||||
|
std::env::set_var("ZITADEL_AUTHORITY_URL", "https://something");
|
||||||
|
|
||||||
let cli = CliSubCommand::parse_from(&["base", "one"]);
|
let cli = CliSubCommand::parse_from(&["base", "one"]);
|
||||||
|
|
||||||
pretty_assertions::assert_eq!(
|
pretty_assertions::assert_eq!(
|
||||||
cli.command,
|
cli.command,
|
||||||
Commands::One {
|
Commands::One {
|
||||||
options: OAuthClientClap {
|
options: ZitadelClap {
|
||||||
zitadel: ZitadelClap {
|
auth_url: Some("https://something".into()),
|
||||||
auth_url: Some("https://something".into()),
|
client_id: Some("something".into()),
|
||||||
client_id: Some("something".into()),
|
client_secret: Some("something".into()),
|
||||||
client_secret: Some("something".into()),
|
redirect_url: Some("https://something".into()),
|
||||||
redirect_url: Some("https://something".into()),
|
token_url: Some("https://something".into()),
|
||||||
token_url: Some("https://something".into())
|
authority_url: Some("https://something".into()),
|
||||||
},
|
|
||||||
noop: NoopConfig { oauth_noop: None }
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
@ -292,16 +216,14 @@ mod tests {
|
|||||||
pretty_assertions::assert_eq!(
|
pretty_assertions::assert_eq!(
|
||||||
cli.command,
|
cli.command,
|
||||||
Commands::One {
|
Commands::One {
|
||||||
options: OAuthClientClap {
|
options: ZitadelClap {
|
||||||
zitadel: ZitadelClap {
|
auth_url: None,
|
||||||
auth_url: None,
|
client_id: None,
|
||||||
client_id: None,
|
client_secret: None,
|
||||||
client_secret: None,
|
redirect_url: None,
|
||||||
redirect_url: None,
|
token_url: None,
|
||||||
token_url: None
|
authority_url: None,
|
||||||
},
|
},
|
||||||
noop: NoopConfig { oauth_noop: None }
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user