use clap::{Args, Parser, Subcommand};
use serde::{Deserialize, Serialize};
#[derive(Parser, PartialEq, Debug)]
#[command(author, version, about, long_about = None)]
pub struct Cli {
#[arg(long, global = true, default_value = "default")]
pub profile: String,
#[command(subcommand)]
pub command: Option<Commands>,
}
#[derive(Clone, Default, Serialize, PartialEq, Deserialize, Debug, clap::ValueEnum)]
pub enum ProviderKind {
#[default]
Microsoft,
Auth0,
}
#[derive(Args, Default, PartialEq, Debug)]
pub struct AuthArgs {
#[arg(long)]
pub provider: Option<ProviderKind>,
#[arg(long)]
pub tenant_id: Option<String>,
#[arg(long)]
pub domain: Option<String>,
#[arg(long)]
pub audience: Option<String>,
#[arg(long)]
pub client_id: Option<String>,
#[arg(long)]
pub scopes: Option<String>,
}
#[derive(Subcommand, PartialEq, Debug)]
pub enum Commands {
Login {
#[command(flatten)]
auth: AuthArgs,
#[arg(long, default_value = "3000")]
port: u16,
},
M2m {
#[command(flatten)]
auth: AuthArgs,
#[arg(long)]
client_secret: Option<String>,
},
Config {
#[command(subcommand)]
action: ConfigAction,
},
}
#[derive(Subcommand, PartialEq, Debug)]
pub enum ConfigAction {
Set {
#[command(flatten)]
auth: AuthArgs,
},
Show,
List,
}
#[cfg(test)]
mod tests {
use super::*;
use clap::CommandFactory;
#[test]
fn verify_cli() {
Cli::command().debug_assert();
}
#[test]
fn test_no_command_uses_default_profile() {
let cli = Cli::try_parse_from(["ez-token"]).unwrap();
assert_eq!(
cli,
Cli {
profile: "default".to_string(),
command: None,
}
);
}
#[test]
fn test_global_profile_flag() {
let cli = Cli::try_parse_from(["ez-token", "--profile", "prod", "config", "show"]).unwrap();
assert_eq!(
cli,
Cli {
profile: "prod".to_string(),
command: Some(Commands::Config {
action: ConfigAction::Show,
}),
}
);
}
#[test]
fn test_login_command_with_defaults() {
let cli = Cli::try_parse_from(["ez-token", "login"]).unwrap();
assert_eq!(
cli.command,
Some(Commands::Login {
auth: AuthArgs::default(),
port: 3000,
})
);
}
#[test]
fn test_login_command_with_auth_args_and_custom_port() {
let cli = Cli::try_parse_from([
"ez-token",
"login",
"--provider",
"auth0",
"--domain",
"my-org.eu.auth0.com",
"--client-id",
"12345",
"--port",
"8080",
])
.unwrap();
assert_eq!(
cli.command,
Some(Commands::Login {
auth: AuthArgs {
provider: Some(ProviderKind::Auth0),
domain: Some("my-org.eu.auth0.com".to_string()),
client_id: Some("12345".to_string()),
..Default::default()
},
port: 8080,
})
);
}
#[test]
fn test_m2m_command() {
let cli = Cli::try_parse_from([
"ez-token",
"m2m",
"--tenant-id",
"common",
"--client-secret",
"super-secret",
])
.unwrap();
assert_eq!(
cli.command,
Some(Commands::M2m {
auth: AuthArgs {
tenant_id: Some("common".to_string()),
..Default::default()
},
client_secret: Some("super-secret".to_string()),
})
);
}
#[test]
fn test_config_set_command() {
let cli = Cli::try_parse_from([
"ez-token",
"--profile",
"dev",
"config",
"set",
"--scopes",
"api://ez/.default",
])
.unwrap();
assert_eq!(cli.profile, "dev");
assert_eq!(
cli.command,
Some(Commands::Config {
action: ConfigAction::Set {
auth: AuthArgs {
scopes: Some("api://ez/.default".to_string()),
..Default::default()
}
}
})
);
}
#[test]
fn test_config_list_command() {
let cli = Cli::try_parse_from(["ez-token", "config", "list"]).unwrap();
assert_eq!(
cli.command,
Some(Commands::Config {
action: ConfigAction::List,
})
);
}
}