Ver Fonte

feat: enhance auth config (#922)

* feat: enhance auth config
gudnuf há 3 meses atrás
pai
commit
cceea654fe

+ 11 - 7
crates/cdk-integration-tests/src/bin/start_fake_auth_mint.rs

@@ -17,6 +17,7 @@ use anyhow::Result;
 use bip39::Mnemonic;
 use cdk_integration_tests::cli::CommonArgs;
 use cdk_integration_tests::shared;
+use cdk_mintd::config::AuthType;
 use clap::Parser;
 use tokio::sync::Notify;
 
@@ -68,16 +69,19 @@ async fn start_fake_auth_mint(
 
     // Enable authentication
     settings.auth = Some(cdk_mintd::config::Auth {
+        auth_enabled: true,
         openid_discovery,
         openid_client_id: "cashu-client".to_string(),
         mint_max_bat: 50,
-        enabled_mint: true,
-        enabled_melt: true,
-        enabled_swap: true,
-        enabled_check_mint_quote: true,
-        enabled_check_melt_quote: true,
-        enabled_restore: true,
-        enabled_check_proof_state: true,
+        mint: AuthType::Blind,
+        get_mint_quote: AuthType::Blind,
+        check_mint_quote: AuthType::Blind,
+        melt: AuthType::Blind,
+        get_melt_quote: AuthType::Blind,
+        check_melt_quote: AuthType::Blind,
+        swap: AuthType::Blind,
+        restore: AuthType::Blind,
+        check_proof_state: AuthType::Blind,
     });
 
     // Set description for the mint

+ 17 - 7
crates/cdk-mintd/example.config.toml

@@ -83,13 +83,23 @@ reserve_fee_min = 4
 # tls_dir = "/path/to/tls"
 
 # [auth]
+# Set to true to enable authentication features (defaults to false)
+# auth_enabled = false
 # openid_discovery = "http://127.0.0.1:8080/realms/cdk-test-realm/.well-known/openid-configuration"
 # openid_client_id = "cashu-client"
 # mint_max_bat=50
-# enabled_mint=true
-# enabled_melt=true
-# enabled_swap=true
-# enabled_check_mint_quote=true
-# enabled_check_melt_quote=true
-# enabled_restore=true
-# enabled_check_proof_state=true
+
+# Authentication settings for endpoints
+# Options: "clear", "blind", "none" (none = disabled)
+
+# mint = "blind"
+# get_mint_quote = "none"  
+# check_mint_quote = "none"
+
+# melt = "none"
+# get_melt_quote = "none"
+# check_melt_quote = "none"
+
+# swap = "blind"
+# restore = "blind"
+# check_proof_state = "none"

+ 45 - 16
crates/cdk-mintd/src/config.rs

@@ -208,30 +208,59 @@ pub struct Database {
     pub engine: DatabaseEngine,
 }
 
+#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq, Default)]
+#[serde(rename_all = "lowercase")]
+pub enum AuthType {
+    Clear,
+    Blind,
+    #[default]
+    None,
+}
+
+impl std::str::FromStr for AuthType {
+    type Err = String;
+
+    fn from_str(s: &str) -> Result<Self, Self::Err> {
+        match s.to_lowercase().as_str() {
+            "clear" => Ok(AuthType::Clear),
+            "blind" => Ok(AuthType::Blind),
+            "none" => Ok(AuthType::None),
+            _ => Err(format!("Unknown auth type: {s}")),
+        }
+    }
+}
+
 #[derive(Debug, Clone, Default, Serialize, Deserialize)]
 pub struct Auth {
+    #[serde(default)]
+    pub auth_enabled: bool,
     pub openid_discovery: String,
     pub openid_client_id: String,
     pub mint_max_bat: u64,
-    #[serde(default = "default_true")]
-    pub enabled_mint: bool,
-    #[serde(default = "default_true")]
-    pub enabled_melt: bool,
-    #[serde(default = "default_true")]
-    pub enabled_swap: bool,
-    #[serde(default = "default_true")]
-    pub enabled_check_mint_quote: bool,
-    #[serde(default = "default_true")]
-    pub enabled_check_melt_quote: bool,
-    #[serde(default = "default_true")]
-    pub enabled_restore: bool,
-    #[serde(default = "default_true")]
-    pub enabled_check_proof_state: bool,
+    #[serde(default = "default_blind")]
+    pub mint: AuthType,
+    #[serde(default)]
+    pub get_mint_quote: AuthType,
+    #[serde(default)]
+    pub check_mint_quote: AuthType,
+    #[serde(default)]
+    pub melt: AuthType,
+    #[serde(default)]
+    pub get_melt_quote: AuthType,
+    #[serde(default)]
+    pub check_melt_quote: AuthType,
+    #[serde(default = "default_blind")]
+    pub swap: AuthType,
+    #[serde(default = "default_blind")]
+    pub restore: AuthType,
+    #[serde(default)]
+    pub check_proof_state: AuthType,
 }
 
-fn default_true() -> bool {
-    true
+fn default_blind() -> AuthType {
+    AuthType::Blind
 }
+
 /// CDK settings, derived from `config.toml`
 #[derive(Debug, Clone, Serialize, Deserialize, Default)]
 pub struct Settings {

+ 49 - 28
crates/cdk-mintd/src/env_vars/auth.rs

@@ -4,19 +4,28 @@ use std::env;
 
 use crate::config::Auth;
 
+pub const ENV_AUTH_ENABLED: &str = "CDK_MINTD_AUTH_ENABLED";
 pub const ENV_AUTH_OPENID_DISCOVERY: &str = "CDK_MINTD_AUTH_OPENID_DISCOVERY";
 pub const ENV_AUTH_OPENID_CLIENT_ID: &str = "CDK_MINTD_AUTH_OPENID_CLIENT_ID";
 pub const ENV_AUTH_MINT_MAX_BAT: &str = "CDK_MINTD_AUTH_MINT_MAX_BAT";
-pub const ENV_AUTH_ENABLED_MINT: &str = "CDK_MINTD_AUTH_ENABLED_MINT";
-pub const ENV_AUTH_ENABLED_MELT: &str = "CDK_MINTD_AUTH_ENABLED_MELT";
-pub const ENV_AUTH_ENABLED_SWAP: &str = "CDK_MINTD_AUTH_ENABLED_SWAP";
-pub const ENV_AUTH_ENABLED_CHECK_MINT_QUOTE: &str = "CDK_MINTD_AUTH_ENABLED_CHECK_MINT_QUOTE";
-pub const ENV_AUTH_ENABLED_CHECK_MELT_QUOTE: &str = "CDK_MINTD_AUTH_ENABLED_CHECK_MELT_QUOTE";
-pub const ENV_AUTH_ENABLED_RESTORE: &str = "CDK_MINTD_AUTH_ENABLED_RESTORE";
-pub const ENV_AUTH_ENABLED_CHECK_PROOF_STATE: &str = "CDK_MINTD_AUTH_ENABLED_CHECK_PROOF_STATE";
+pub const ENV_AUTH_MINT: &str = "CDK_MINTD_AUTH_MINT";
+pub const ENV_AUTH_GET_MINT_QUOTE: &str = "CDK_MINTD_AUTH_GET_MINT_QUOTE";
+pub const ENV_AUTH_CHECK_MINT_QUOTE: &str = "CDK_MINTD_AUTH_CHECK_MINT_QUOTE";
+pub const ENV_AUTH_MELT: &str = "CDK_MINTD_AUTH_MELT";
+pub const ENV_AUTH_GET_MELT_QUOTE: &str = "CDK_MINTD_AUTH_GET_MELT_QUOTE";
+pub const ENV_AUTH_CHECK_MELT_QUOTE: &str = "CDK_MINTD_AUTH_CHECK_MELT_QUOTE";
+pub const ENV_AUTH_SWAP: &str = "CDK_MINTD_AUTH_SWAP";
+pub const ENV_AUTH_RESTORE: &str = "CDK_MINTD_AUTH_RESTORE";
+pub const ENV_AUTH_CHECK_PROOF_STATE: &str = "CDK_MINTD_AUTH_CHECK_PROOF_STATE";
 
 impl Auth {
     pub fn from_env(mut self) -> Self {
+        if let Ok(enabled_str) = env::var(ENV_AUTH_ENABLED) {
+            if let Ok(enabled) = enabled_str.parse() {
+                self.auth_enabled = enabled;
+            }
+        }
+
         if let Ok(discovery) = env::var(ENV_AUTH_OPENID_DISCOVERY) {
             self.openid_discovery = discovery;
         }
@@ -31,45 +40,57 @@ impl Auth {
             }
         }
 
-        if let Ok(enabled_mint_str) = env::var(ENV_AUTH_ENABLED_MINT) {
-            if let Ok(enabled) = enabled_mint_str.parse() {
-                self.enabled_mint = enabled;
+        if let Ok(mint_str) = env::var(ENV_AUTH_MINT) {
+            if let Ok(auth_type) = mint_str.parse() {
+                self.mint = auth_type;
+            }
+        }
+
+        if let Ok(get_mint_quote_str) = env::var(ENV_AUTH_GET_MINT_QUOTE) {
+            if let Ok(auth_type) = get_mint_quote_str.parse() {
+                self.get_mint_quote = auth_type;
+            }
+        }
+
+        if let Ok(check_mint_quote_str) = env::var(ENV_AUTH_CHECK_MINT_QUOTE) {
+            if let Ok(auth_type) = check_mint_quote_str.parse() {
+                self.check_mint_quote = auth_type;
             }
         }
 
-        if let Ok(enabled_melt_str) = env::var(ENV_AUTH_ENABLED_MELT) {
-            if let Ok(enabled) = enabled_melt_str.parse() {
-                self.enabled_melt = enabled;
+        if let Ok(melt_str) = env::var(ENV_AUTH_MELT) {
+            if let Ok(auth_type) = melt_str.parse() {
+                self.melt = auth_type;
             }
         }
 
-        if let Ok(enabled_swap_str) = env::var(ENV_AUTH_ENABLED_SWAP) {
-            if let Ok(enabled) = enabled_swap_str.parse() {
-                self.enabled_swap = enabled;
+        if let Ok(get_melt_quote_str) = env::var(ENV_AUTH_GET_MELT_QUOTE) {
+            if let Ok(auth_type) = get_melt_quote_str.parse() {
+                self.get_melt_quote = auth_type;
             }
         }
 
-        if let Ok(enabled_check_mint_str) = env::var(ENV_AUTH_ENABLED_CHECK_MINT_QUOTE) {
-            if let Ok(enabled) = enabled_check_mint_str.parse() {
-                self.enabled_check_mint_quote = enabled;
+        if let Ok(check_melt_quote_str) = env::var(ENV_AUTH_CHECK_MELT_QUOTE) {
+            if let Ok(auth_type) = check_melt_quote_str.parse() {
+                self.check_melt_quote = auth_type;
             }
         }
 
-        if let Ok(enabled_check_melt_str) = env::var(ENV_AUTH_ENABLED_CHECK_MELT_QUOTE) {
-            if let Ok(enabled) = enabled_check_melt_str.parse() {
-                self.enabled_check_melt_quote = enabled;
+        if let Ok(swap_str) = env::var(ENV_AUTH_SWAP) {
+            if let Ok(auth_type) = swap_str.parse() {
+                self.swap = auth_type;
             }
         }
 
-        if let Ok(enabled_restore_str) = env::var(ENV_AUTH_ENABLED_RESTORE) {
-            if let Ok(enabled) = enabled_restore_str.parse() {
-                self.enabled_restore = enabled;
+        if let Ok(restore_str) = env::var(ENV_AUTH_RESTORE) {
+            if let Ok(auth_type) = restore_str.parse() {
+                self.restore = auth_type;
             }
         }
 
-        if let Ok(enabled_check_proof_str) = env::var(ENV_AUTH_ENABLED_CHECK_PROOF_STATE) {
-            if let Ok(enabled) = enabled_check_proof_str.parse() {
-                self.enabled_check_proof_state = enabled;
+        if let Ok(check_proof_state_str) = env::var(ENV_AUTH_CHECK_PROOF_STATE) {
+            if let Ok(auth_type) = check_proof_state_str.parse() {
+                self.check_proof_state = auth_type;
             }
         }
 

+ 2 - 8
crates/cdk-mintd/src/env_vars/mod.rs

@@ -63,14 +63,8 @@ impl Settings {
             // Check env vars for auth config even if None
             let auth = self.auth.clone().unwrap_or_default().from_env();
 
-            // Only set auth if env vars are present and have non-default values
-            if auth.openid_discovery != String::default()
-                || auth.openid_client_id != String::default()
-                || auth.mint_max_bat != 0
-                || auth.enabled_mint
-                || auth.enabled_melt
-                || auth.enabled_swap
-            {
+            // Only set auth if auth_enabled flag is true
+            if auth.auth_enabled {
                 self.auth = Some(auth);
             } else {
                 self.auth = None;

+ 66 - 72
crates/cdk-mintd/src/lib.rs

@@ -43,7 +43,7 @@ use cdk_axum::cache::HttpCache;
 use cdk_sqlite::mint::MintSqliteAuthDatabase;
 use cdk_sqlite::MintSqliteDatabase;
 use cli::CLIArgs;
-use config::{DatabaseEngine, LnBackend};
+use config::{AuthType, DatabaseEngine, LnBackend};
 use env_vars::ENV_WORK_DIR;
 use setup::LnBackendSetup;
 use tower::ServiceBuilder;
@@ -456,116 +456,110 @@ async fn setup_authentication(
             }
         };
 
+        let mut protected_endpoints = HashMap::new();
+        let mut blind_auth_endpoints = vec![];
+        let mut clear_auth_endpoints = vec![];
+        let mut unprotected_endpoints = vec![];
+
         let mint_blind_auth_endpoint =
             ProtectedEndpoint::new(Method::Post, RoutePath::MintBlindAuth);
 
-        let mut protected_endpoints = HashMap::new();
-
         protected_endpoints.insert(mint_blind_auth_endpoint, AuthRequired::Clear);
 
-        let mut blind_auth_endpoints = vec![];
-        let mut unprotected_endpoints = vec![];
+        clear_auth_endpoints.push(mint_blind_auth_endpoint);
+
+        // Helper function to add endpoint based on auth type
+        let mut add_endpoint = |endpoint: ProtectedEndpoint, auth_type: &AuthType| {
+            match auth_type {
+                AuthType::Blind => {
+                    protected_endpoints.insert(endpoint, AuthRequired::Blind);
+                    blind_auth_endpoints.push(endpoint);
+                }
+                AuthType::Clear => {
+                    protected_endpoints.insert(endpoint, AuthRequired::Clear);
+                    clear_auth_endpoints.push(endpoint);
+                }
+                AuthType::None => {
+                    unprotected_endpoints.push(endpoint);
+                }
+            };
+        };
 
+        // Get mint quote endpoint
         {
             let mint_quote_protected_endpoint =
-                ProtectedEndpoint::new(Method::Post, RoutePath::MintQuoteBolt11);
-            let mint_protected_endpoint =
-                ProtectedEndpoint::new(Method::Post, RoutePath::MintBolt11);
-            if auth_settings.enabled_mint {
-                protected_endpoints.insert(mint_quote_protected_endpoint, AuthRequired::Blind);
-
-                protected_endpoints.insert(mint_protected_endpoint, AuthRequired::Blind);
-
-                blind_auth_endpoints.push(mint_quote_protected_endpoint);
-                blind_auth_endpoints.push(mint_protected_endpoint);
-            } else {
-                unprotected_endpoints.push(mint_protected_endpoint);
-                unprotected_endpoints.push(mint_quote_protected_endpoint);
-            }
+                ProtectedEndpoint::new(cdk::nuts::Method::Post, RoutePath::MintQuoteBolt11);
+            add_endpoint(mint_quote_protected_endpoint, &auth_settings.get_mint_quote);
         }
 
+        // Check mint quote endpoint
         {
-            let melt_quote_protected_endpoint =
-                ProtectedEndpoint::new(Method::Post, RoutePath::MeltQuoteBolt11);
-            let melt_protected_endpoint =
-                ProtectedEndpoint::new(Method::Post, RoutePath::MeltBolt11);
-
-            if auth_settings.enabled_melt {
-                protected_endpoints.insert(melt_quote_protected_endpoint, AuthRequired::Blind);
-                protected_endpoints.insert(melt_protected_endpoint, AuthRequired::Blind);
-
-                blind_auth_endpoints.push(melt_quote_protected_endpoint);
-                blind_auth_endpoints.push(melt_protected_endpoint);
-            } else {
-                unprotected_endpoints.push(melt_quote_protected_endpoint);
-                unprotected_endpoints.push(melt_protected_endpoint);
-            }
+            let check_mint_protected_endpoint =
+                ProtectedEndpoint::new(Method::Get, RoutePath::MintQuoteBolt11);
+            add_endpoint(
+                check_mint_protected_endpoint,
+                &auth_settings.check_mint_quote,
+            );
         }
 
+        // Mint endpoint
         {
-            let swap_protected_endpoint = ProtectedEndpoint::new(Method::Post, RoutePath::Swap);
-
-            if auth_settings.enabled_swap {
-                protected_endpoints.insert(swap_protected_endpoint, AuthRequired::Blind);
-                blind_auth_endpoints.push(swap_protected_endpoint);
-            } else {
-                unprotected_endpoints.push(swap_protected_endpoint);
-            }
+            let mint_protected_endpoint =
+                ProtectedEndpoint::new(cdk::nuts::Method::Post, RoutePath::MintBolt11);
+            add_endpoint(mint_protected_endpoint, &auth_settings.mint);
         }
 
+        // Get melt quote endpoint
         {
-            let check_mint_protected_endpoint =
-                ProtectedEndpoint::new(Method::Get, RoutePath::MintQuoteBolt11);
-
-            if auth_settings.enabled_check_mint_quote {
-                protected_endpoints.insert(check_mint_protected_endpoint, AuthRequired::Blind);
-                blind_auth_endpoints.push(check_mint_protected_endpoint);
-            } else {
-                unprotected_endpoints.push(check_mint_protected_endpoint);
-            }
+            let melt_quote_protected_endpoint = ProtectedEndpoint::new(
+                cdk::nuts::Method::Post,
+                cdk::nuts::RoutePath::MeltQuoteBolt11,
+            );
+            add_endpoint(melt_quote_protected_endpoint, &auth_settings.get_melt_quote);
         }
 
+        // Check melt quote endpoint
         {
             let check_melt_protected_endpoint =
                 ProtectedEndpoint::new(Method::Get, RoutePath::MeltQuoteBolt11);
+            add_endpoint(
+                check_melt_protected_endpoint,
+                &auth_settings.check_melt_quote,
+            );
+        }
 
-            if auth_settings.enabled_check_melt_quote {
-                protected_endpoints.insert(check_melt_protected_endpoint, AuthRequired::Blind);
-                blind_auth_endpoints.push(check_melt_protected_endpoint);
-            } else {
-                unprotected_endpoints.push(check_melt_protected_endpoint);
-            }
+        // Melt endpoint
+        {
+            let melt_protected_endpoint =
+                ProtectedEndpoint::new(Method::Post, RoutePath::MeltBolt11);
+            add_endpoint(melt_protected_endpoint, &auth_settings.melt);
+        }
+
+        // Swap endpoint
+        {
+            let swap_protected_endpoint = ProtectedEndpoint::new(Method::Post, RoutePath::Swap);
+            add_endpoint(swap_protected_endpoint, &auth_settings.swap);
         }
 
+        // Restore endpoint
         {
             let restore_protected_endpoint =
                 ProtectedEndpoint::new(Method::Post, RoutePath::Restore);
-
-            if auth_settings.enabled_restore {
-                protected_endpoints.insert(restore_protected_endpoint, AuthRequired::Blind);
-                blind_auth_endpoints.push(restore_protected_endpoint);
-            } else {
-                unprotected_endpoints.push(restore_protected_endpoint);
-            }
+            add_endpoint(restore_protected_endpoint, &auth_settings.restore);
         }
 
+        // Check proof state endpoint
         {
             let state_protected_endpoint =
                 ProtectedEndpoint::new(Method::Post, RoutePath::Checkstate);
-
-            if auth_settings.enabled_check_proof_state {
-                protected_endpoints.insert(state_protected_endpoint, AuthRequired::Blind);
-                blind_auth_endpoints.push(state_protected_endpoint);
-            } else {
-                unprotected_endpoints.push(state_protected_endpoint);
-            }
+            add_endpoint(state_protected_endpoint, &auth_settings.check_proof_state);
         }
 
         mint_builder = mint_builder.with_auth(
             auth_localstore.clone(),
             auth_settings.openid_discovery,
             auth_settings.openid_client_id,
-            vec![mint_blind_auth_endpoint],
+            clear_auth_endpoints,
         );
         mint_builder =
             mint_builder.with_blind_auth(auth_settings.mint_max_bat, blind_auth_endpoints);