diff --git a/crates/cli/src/sync.rs b/crates/cli/src/sync.rs index 647ef2635..eaf2482d1 100644 --- a/crates/cli/src/sync.rs +++ b/crates/cli/src/sync.rs @@ -189,10 +189,14 @@ pub async fn config_sync( let encrypted_client_secret = if let Some(client_secret) = provider.client_secret.as_deref() { Some(encrypter.encrypt_to_string(client_secret.as_bytes())?) - } else if let Some(siwa) = provider.sign_in_with_apple.as_ref() { - // For SIWA, we JSON-encode the config and encrypt it, reusing the client_secret - // field in the database - let encoded = serde_json::to_vec(siwa)?; + } else if let Some(mut siwa) = provider.sign_in_with_apple.clone() { + if siwa.private_key.is_none() { + if let Some(private_key_file) = siwa.private_key_file.take() { + let key = tokio::fs::read_to_string(private_key_file).await?; + siwa.private_key = Some(key); + } + } + let encoded = serde_json::to_vec(&siwa)?; Some(encrypter.encrypt_to_string(&encoded)?) } else { None diff --git a/crates/handlers/src/upstream_oauth2/mod.rs b/crates/handlers/src/upstream_oauth2/mod.rs index 695c50efb..c8e37a86c 100644 --- a/crates/handlers/src/upstream_oauth2/mod.rs +++ b/crates/handlers/src/upstream_oauth2/mod.rs @@ -6,13 +6,11 @@ use std::string::FromUtf8Error; -use camino::Utf8PathBuf; use mas_data_model::{UpstreamOAuthProvider, UpstreamOAuthProviderTokenAuthMethod}; use mas_iana::jose::JsonWebSignatureAlg; use mas_keystore::{DecryptError, Encrypter, Keystore}; use mas_oidc_client::types::client_credentials::ClientCredentials; use pkcs8::DecodePrivateKey; -use schemars::JsonSchema; use serde::Deserialize; use thiserror::Error; use url::Url; @@ -32,12 +30,6 @@ enum ProviderCredentialsError { #[error("Provider doesn't have a client secret")] MissingClientSecret, - #[error("Duplicate private key and private key file for Sign in with Apple")] - DuplicatePrivateKey, - - #[error("Missing private key for signing the id_token")] - MissingPrivateKey, - #[error("Could not decrypt client secret")] DecryptClientSecret { #[from] @@ -63,25 +55,14 @@ enum ProviderCredentialsError { }, } -#[derive(Debug, Deserialize, JsonSchema)] +#[derive(Debug, Deserialize)] pub struct SignInWithApple { - /// The private key file used to sign the `id_token` - #[serde(skip_serializing_if = "Option::is_none")] - #[schemars(with = "Option")] - pub private_key_file: Option, - - /// The private key used to sign the `id_token` - #[serde(skip_serializing_if = "Option::is_none")] - pub private_key: Option, - - /// The Team ID of the Apple Developer Portal + pub private_key: String, pub team_id: String, - - /// The key ID of the Apple Developer Portal pub key_id: String, } -async fn client_credentials_for_provider( +fn client_credentials_for_provider( provider: &UpstreamOAuthProvider, token_endpoint: &Url, keystore: &Keystore, @@ -89,6 +70,7 @@ async fn client_credentials_for_provider( ) -> Result { let client_id = provider.client_id.clone(); + // Decrypt the client secret let client_secret = provider .encrypted_client_secret .as_deref() @@ -142,32 +124,10 @@ async fn client_credentials_for_provider( }, UpstreamOAuthProviderTokenAuthMethod::SignInWithApple => { - let client_secret = - client_secret.ok_or(ProviderCredentialsError::MissingClientSecret)?; + let params = client_secret.ok_or(ProviderCredentialsError::MissingClientSecret)?; + let params: SignInWithApple = serde_json::from_str(¶ms)?; - let params: SignInWithApple = serde_json::from_str(&client_secret) - .map_err(|inner| ProviderCredentialsError::InvalidClientSecretJson { inner })?; - - if params.private_key.is_none() && params.private_key_file.is_none() { - return Err(ProviderCredentialsError::MissingPrivateKey); - } - - if params.private_key.is_some() && params.private_key_file.is_some() { - return Err(ProviderCredentialsError::DuplicatePrivateKey); - } - - let private_key_pem = if let Some(private_key) = params.private_key { - private_key - } else if let Some(private_key_file) = params.private_key_file { - tokio::fs::read_to_string(private_key_file) - .await - .map_err(|_| ProviderCredentialsError::MissingPrivateKey)? - } else { - unreachable!("already validated above") - }; - - let key = elliptic_curve::SecretKey::from_pkcs8_pem(&private_key_pem) - .map_err(|inner| ProviderCredentialsError::InvalidPrivateKey { inner })?; + let key = elliptic_curve::SecretKey::from_pkcs8_pem(¶ms.private_key)?; ClientCredentials::SignInWithApple { client_id, @@ -179,4 +139,4 @@ async fn client_credentials_for_provider( }; Ok(client_credentials) -} +} \ No newline at end of file