diff --git a/Cargo.lock b/Cargo.lock index 26ed0584..124d10f9 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1705,9 +1705,9 @@ dependencies = [ [[package]] name = "rustls" -version = "0.21.8" +version = "0.21.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "446e14c5cda4f3f30fe71863c34ec70f5ac79d6087097ad0bb433e1be5edf04c" +checksum = "629648aced5775d558af50b2b4c7b02983a04b312126d45eeead26e7caa498b9" dependencies = [ "log", "ring", @@ -2040,7 +2040,7 @@ checksum = "6980e8d7511241f8acf4aebddbb1ff938df5eebe98691418c4468d0b72a96a67" [[package]] name = "stackable-operator" version = "0.56.0" -source = "git+https://github.com/stackabletech//operator-rs.git?branch=feat/sso-auth-classes#3f7b5b5cae7358a905094d89d0a65d10e08997fe" +source = "git+https://github.com/stackabletech//operator-rs.git?branch=feat/sso-auth-classes#90bdd2da61ce4da0e3c72f89d93520ea3afb0af1" dependencies = [ "chrono", "clap", @@ -2076,7 +2076,7 @@ dependencies = [ [[package]] name = "stackable-operator-derive" version = "0.56.0" -source = "git+https://github.com/stackabletech//operator-rs.git?branch=feat/sso-auth-classes#3f7b5b5cae7358a905094d89d0a65d10e08997fe" +source = "git+https://github.com/stackabletech//operator-rs.git?branch=feat/sso-auth-classes#90bdd2da61ce4da0e3c72f89d93520ea3afb0af1" dependencies = [ "darling 0.20.3", "proc-macro2", @@ -2800,6 +2800,6 @@ dependencies = [ [[package]] name = "zeroize" -version = "1.6.1" +version = "1.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "12a3946ecfc929b583800f4629b6c25b88ac6e92a40ea5670f77112a85d40a8b" +checksum = "525b4ec142c6b68a2d10f01f7bbf6755599ca3f81ea53b8431b7dd348f5fdb2d" diff --git a/rust/crd/src/authentication.rs b/rust/crd/src/authentication.rs index 311d352c..d661ef76 100644 --- a/rust/crd/src/authentication.rs +++ b/rust/crd/src/authentication.rs @@ -1,69 +1,47 @@ -use serde::{Deserialize, Serialize}; use snafu::{ResultExt, Snafu}; use stackable_operator::{ client::Client, - commons::authentication::AuthenticationClass, - kube::runtime::reflector::ObjectRef, - schemars::{self, JsonSchema}, + commons::authentication::{ + oidc, AuthenticationClass, ClientAuthenticationConfig, ClientAuthenticationDetails, + }, }; #[derive(Snafu, Debug)] pub enum Error { - #[snafu(display("Failed to retrieve AuthenticationClass {authentication_class}"))] + #[snafu(display("Failed to retrieve AuthenticationClass"))] AuthenticationClassRetrieval { source: stackable_operator::error::Error, - authentication_class: ObjectRef, }, } type Result = std::result::Result; -#[derive(Clone, Debug, Deserialize, JsonSchema, PartialEq, Serialize)] -#[serde(rename_all = "camelCase")] -pub struct TrinoAuthenticationClassRef { - pub authentication_class: String, - pub secret: Option, -} - -#[derive(Clone, Debug, Deserialize, JsonSchema, PartialEq, Serialize)] -#[serde(rename_all = "camelCase")] -pub enum TrinoAuthenticationSecret { - Oidc(String), -} - pub struct ResolvedAuthenticationClassRef { pub authentication_class: AuthenticationClass, - pub secret_ref: Option, + pub oidc: Option, } /// Retrieve all provided `AuthenticationClass` references. pub async fn resolve_authentication_classes( client: &Client, - authentication_class_refs: &Vec, + client_authentication_details: &Vec, ) -> Result> { let mut resolved_auth_classes = vec![]; - for auth_class in authentication_class_refs { - let resolved_auth_class = - AuthenticationClass::resolve(client, &auth_class.authentication_class) - .await - .context(AuthenticationClassRetrievalSnafu { - authentication_class: ObjectRef::::new( - &auth_class.authentication_class, - ), - })?; - - let secret_ref = if let Some(auth_secret) = &auth_class.secret { - match auth_secret { - TrinoAuthenticationSecret::Oidc(secret) => Some(secret), - } - } else { - None - }; - + for client_authentication_detail in client_authentication_details { + let resolved_auth_class = client_authentication_detail + .resolve_class(client) + .await + .context(AuthenticationClassRetrievalSnafu)?; + let oidc = + if let ClientAuthenticationConfig::Oidc(oidc) = &client_authentication_detail.config { + Some(oidc.clone()) + } else { + None + }; resolved_auth_classes.push(ResolvedAuthenticationClassRef { authentication_class: resolved_auth_class, - secret_ref: secret_ref.cloned(), + oidc, }); } diff --git a/rust/crd/src/lib.rs b/rust/crd/src/lib.rs index bac4b4b3..ce3eb670 100644 --- a/rust/crd/src/lib.rs +++ b/rust/crd/src/lib.rs @@ -3,7 +3,6 @@ pub mod authentication; pub mod catalog; pub mod discovery; -use crate::authentication::TrinoAuthenticationClassRef; use crate::discovery::TrinoPodRef; use affinity::get_affinity; @@ -13,6 +12,7 @@ use snafu::{OptionExt, ResultExt, Snafu}; use stackable_operator::{ commons::{ affinity::StackableAffinity, + authentication::ClientAuthenticationDetails, cluster_operation::ClusterOperation, opa::OpaConfig, product_image_selection::ProductImage, @@ -196,7 +196,7 @@ pub struct TrinoClusterSpec { pub struct TrinoClusterConfig { /// Authentication options for Trino. #[serde(default)] - pub authentication: Vec, + pub authentication: Vec, /// Authorization options for Trino. #[serde(skip_serializing_if = "Option::is_none")] pub authorization: Option, @@ -739,7 +739,7 @@ impl TrinoCluster { } /// Returns user provided authentication settings - pub fn get_authentication(&self) -> &Vec { + pub fn get_authentication(&self) -> &Vec { &self.spec.cluster_config.authentication } diff --git a/rust/operator-binary/src/authentication/mod.rs b/rust/operator-binary/src/authentication/mod.rs index 7af67054..b3c0fc09 100644 --- a/rust/operator-binary/src/authentication/mod.rs +++ b/rust/operator-binary/src/authentication/mod.rs @@ -494,7 +494,14 @@ impl TryFrom> for TrinoAuthenticationTypes { oidc_authenticators.push(OidcAuthenticator::new( auth_class_name, provider, - resolved_auth_class.secret_ref, + resolved_auth_class + .oidc + .as_ref() + .map(|o| o.client_credentials_secret_ref.clone()), + resolved_auth_class + .oidc + .map(|o| o.extra_scopes) + .unwrap_or_default(), )); TrinoAuthenticationTypes::insert_auth_type_order( @@ -542,7 +549,7 @@ impl TryFrom> for TrinoAuthenticationTypes { #[cfg(test)] mod tests { use super::*; - use stackable_operator::commons::authentication::static_; + use stackable_operator::commons::authentication::{oidc, static_}; use stackable_operator::commons::secret_class::SecretClassVolume; use stackable_operator::{ commons::authentication::{static_::UserCredentialsSecretRef, AuthenticationClassSpec}, @@ -575,7 +582,7 @@ mod tests { ), }, }, - secret_ref: None, + oidc: None, } } @@ -622,7 +629,7 @@ mod tests { deserializer, ) .unwrap(), - secret_ref: None, + oidc: None, } } @@ -648,7 +655,10 @@ mod tests { deserializer, ) .unwrap(), - secret_ref: Some("my-oidc-secret".to_string()), + oidc: Some(oidc::ClientAuthenticationOptions { + client_credentials_secret_ref: "my-oidc-secret".to_string(), + extra_scopes: Vec::new(), + }), } } diff --git a/rust/operator-binary/src/authentication/oidc/mod.rs b/rust/operator-binary/src/authentication/oidc/mod.rs index 558123fa..e9552ca9 100644 --- a/rust/operator-binary/src/authentication/oidc/mod.rs +++ b/rust/operator-binary/src/authentication/oidc/mod.rs @@ -57,6 +57,7 @@ pub struct OidcAuthenticator { name: String, oidc: oidc::AuthenticationProvider, secret: Option, + extra_scopes: Vec, } impl OidcAuthenticator { @@ -64,11 +65,13 @@ impl OidcAuthenticator { name: String, provider: oidc::AuthenticationProvider, secret_ref: Option, + extra_scopes: Vec, ) -> Self { Self { name, oidc: provider, secret: secret_ref, + extra_scopes, } } } @@ -105,10 +108,12 @@ impl TrinoOidcAuthentication { issuer.to_string(), ); + let mut scopes = authenticator.oidc.scopes; + scopes.extend(authenticator.extra_scopes); oauth2_authentication_config.add_config_property( TrinoRole::Coordinator, HTTP_SERVER_AUTHENTICATION_OAUTH2_SCOPES.to_string(), - authenticator.oidc.scopes.join(","), + scopes.join(","), ); let (client_id_env, client_secret_env) = @@ -151,11 +156,16 @@ impl TrinoOidcAuthentication { oauth2_authentication_config.add_volume_mounts( TrinoRole::Coordinator, stackable_trino_crd::Container::Prepare, + tls_mounts.clone(), + ); + oauth2_authentication_config.add_volume_mounts( + TrinoRole::Worker, + stackable_trino_crd::Container::Prepare, tls_mounts, ); - if authenticator.oidc.tls.use_tls() { - if !authenticator.oidc.tls.use_tls_verification() { + if authenticator.oidc.tls.uses_tls() { + if !authenticator.oidc.tls.uses_tls_verification() { // TODO: this still true? // Use TLS but don't verify OIDC server ca => not supported return Err(Error::UnverifiedOidcTlsConnectionNotSupported); @@ -225,6 +235,7 @@ mod tests { auth_class_name.to_string(), oidc_auth_provider, credential_secret, + Vec::new(), ) } diff --git a/rust/operator-binary/src/authentication/password/ldap.rs b/rust/operator-binary/src/authentication/password/ldap.rs index 76bf3e23..79a3dc50 100644 --- a/rust/operator-binary/src/authentication/password/ldap.rs +++ b/rust/operator-binary/src/authentication/password/ldap.rs @@ -89,8 +89,8 @@ impl LdapAuthenticator { ); } - if self.ldap.tls.use_tls() { - if !self.ldap.tls.use_tls_verification() { + if self.ldap.tls.uses_tls() { + if !self.ldap.tls.uses_tls_verification() { // Use TLS but don't verify LDAP server ca => not supported return Err(Error::UnverifiedLdapTlsConnectionNotSupported); } diff --git a/rust/operator-binary/src/main.rs b/rust/operator-binary/src/main.rs index 688df159..7434ea47 100644 --- a/rust/operator-binary/src/main.rs +++ b/rust/operator-binary/src/main.rs @@ -154,5 +154,5 @@ fn references_authentication_class( .cluster_config .authentication .iter() - .any(|a| a.authentication_class == authentication_class_name) + .any(|c| c.authentication_class_name() == &authentication_class_name) }