Explorar el Código

Fix panic around sso_master_password_policy (#6233)

Timshel hace 1 mes
padre
commit
f76362ff89
Se han modificado 3 ficheros con 22 adiciones y 11 borrados
  1. 4 4
      src/api/core/organizations.rs
  2. 2 2
      src/api/mod.rs
  3. 16 5
      src/config.rs

+ 4 - 4
src/api/core/organizations.rs

@@ -2063,12 +2063,12 @@ async fn list_policies_token(org_id: OrganizationId, token: &str, mut conn: DbCo
 async fn get_master_password_policy(org_id: OrganizationId, _headers: Headers, mut conn: DbConn) -> JsonResult {
     let policy =
         OrgPolicy::find_by_org_and_type(&org_id, OrgPolicyType::MasterPassword, &mut conn).await.unwrap_or_else(|| {
-            let data = match CONFIG.sso_master_password_policy() {
-                Some(policy) => policy,
-                None => "null".to_string(),
+            let (enabled, data) = match CONFIG.sso_master_password_policy_value() {
+                Some(policy) if CONFIG.sso_enabled() => (true, policy.to_string()),
+                _ => (false, "null".to_string()),
             };
 
-            OrgPolicy::new(org_id, OrgPolicyType::MasterPassword, CONFIG.sso_master_password_policy().is_some(), data)
+            OrgPolicy::new(org_id, OrgPolicyType::MasterPassword, enabled, data)
         });
 
     Ok(Json(policy.to_json()))

+ 2 - 2
src/api/mod.rs

@@ -110,8 +110,8 @@ async fn master_password_policy(user: &User, conn: &DbConn) -> Value {
                 enforce_on_login: acc.enforce_on_login || policy.enforce_on_login,
             }
         }))
-    } else if let Some(policy_str) = CONFIG.sso_master_password_policy().filter(|_| CONFIG.sso_enabled()) {
-        serde_json::from_str(&policy_str).unwrap_or(json!({}))
+    } else if CONFIG.sso_enabled() {
+        CONFIG.sso_master_password_policy_value().unwrap_or(json!({}))
     } else {
         json!({})
     };

+ 16 - 5
src/config.rs

@@ -974,7 +974,7 @@ fn validate_config(cfg: &ConfigItems) -> Result<(), Error> {
 
         validate_internal_sso_issuer_url(&cfg.sso_authority)?;
         validate_internal_sso_redirect_url(&cfg.sso_callback_path)?;
-        check_master_password_policy(&cfg.sso_master_password_policy)?;
+        validate_sso_master_password_policy(&cfg.sso_master_password_policy)?;
     }
 
     if cfg._enable_yubico {
@@ -1168,12 +1168,19 @@ fn validate_internal_sso_redirect_url(sso_callback_path: &String) -> Result<open
     }
 }
 
-fn check_master_password_policy(sso_master_password_policy: &Option<String>) -> Result<(), Error> {
+fn validate_sso_master_password_policy(
+    sso_master_password_policy: &Option<String>,
+) -> Result<Option<serde_json::Value>, Error> {
     let policy = sso_master_password_policy.as_ref().map(|mpp| serde_json::from_str::<serde_json::Value>(mpp));
-    if let Some(Err(error)) = policy {
-        err!(format!("Invalid sso_master_password_policy ({error}), Ensure that it's correctly escaped with ''"))
+
+    match policy {
+        None => Ok(None),
+        Some(Ok(jsobject @ serde_json::Value::Object(_))) => Ok(Some(jsobject)),
+        Some(Ok(_)) => err!("Invalid sso_master_password_policy: parsed value is not a JSON object"),
+        Some(Err(error)) => {
+            err!(format!("Invalid sso_master_password_policy ({error}), Ensure that it's correctly escaped with ''"))
+        }
     }
-    Ok(())
 }
 
 /// Extracts an RFC 6454 web origin from a URL.
@@ -1578,6 +1585,10 @@ impl Config {
         validate_internal_sso_redirect_url(&self.sso_callback_path())
     }
 
+    pub fn sso_master_password_policy_value(&self) -> Option<serde_json::Value> {
+        validate_sso_master_password_policy(&self.sso_master_password_policy()).ok().flatten()
+    }
+
     pub fn sso_scopes_vec(&self) -> Vec<String> {
         self.sso_scopes().split_whitespace().map(str::to_string).collect()
     }