diff --git a/Cargo.lock b/Cargo.lock index 83e7861b0d2..e3ddfb845ba 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1787,6 +1787,7 @@ dependencies = [ "bon", "chrono", "claims", + "clap", "insta", "jsonwebtoken", "mockall", diff --git a/crates/crates_io_trustpub/Cargo.toml b/crates/crates_io_trustpub/Cargo.toml index cea86803f5a..19151e31364 100644 --- a/crates/crates_io_trustpub/Cargo.toml +++ b/crates/crates_io_trustpub/Cargo.toml @@ -31,6 +31,7 @@ tracing = "=0.1.41" [dev-dependencies] bon = "=3.7.2" claims = "=0.8.0" +clap = { version = "=4.5.48", features = ["derive", "env", "unicode", "wrap_help"] } insta = { version = "=1.43.2", features = ["json", "redactions"] } mockito = "=1.7.0" serde_json = "=1.0.145" diff --git a/crates/crates_io_trustpub/examples/load_jwks.rs b/crates/crates_io_trustpub/examples/load_jwks.rs new file mode 100644 index 00000000000..6fc9d5cf793 --- /dev/null +++ b/crates/crates_io_trustpub/examples/load_jwks.rs @@ -0,0 +1,62 @@ +use clap::{Parser, ValueEnum}; +use crates_io_trustpub::github::GITHUB_ISSUER_URL; +use crates_io_trustpub::keystore::load_jwks::load_jwks; +use reqwest::Client; + +#[derive(Clone, Debug, ValueEnum)] +enum Provider { + #[value(name = "github")] + GitHub, +} + +impl Provider { + fn issuer_url(&self) -> &'static str { + match self { + Provider::GitHub => GITHUB_ISSUER_URL, + } + } +} + +#[derive(Parser)] +#[command(name = "load_jwks")] +#[command(about = "Load and display JWKS keys from OpenID Connect providers")] +struct Args { + /// The provider to load JWKS from + provider: Provider, +} + +#[tokio::main] +async fn main() -> anyhow::Result<()> { + let args = Args::parse(); + + let issuer_url = args.provider.issuer_url(); + + println!("Loading JWKS for provider: {:?}", args.provider); + println!("Issuer URL: {}", issuer_url); + println!(); + + let client = Client::new(); + + let jwks = load_jwks(&client, issuer_url).await?; + println!("Successfully loaded JWKS with {} keys:", jwks.keys.len()); + println!(); + + for key in &jwks.keys { + let key_id = key.common.key_id.as_deref().unwrap_or(""); + println!("Key ID: {}", key_id); + + if let Some(alg) = &key.common.key_algorithm { + println!("Algorithm: {:?}", alg); + } + + if let Some(usage) = &key.common.public_key_use { + println!("Usage: {:?}", usage); + } + + println!("Algorithm Parameters: {:?}", key.algorithm); + + println!(); + } + + Ok(()) +} diff --git a/crates/crates_io_trustpub/src/keystore/mod.rs b/crates/crates_io_trustpub/src/keystore/mod.rs index 73cb3a8b3ae..d6ebbbd876f 100644 --- a/crates/crates_io_trustpub/src/keystore/mod.rs +++ b/crates/crates_io_trustpub/src/keystore/mod.rs @@ -1,5 +1,5 @@ mod r#impl; -mod load_jwks; +pub mod load_jwks; use async_trait::async_trait; pub use r#impl::RealOidcKeyStore;