diff --git a/.env.template b/.env.template index 45239f68..fb624703 100644 --- a/.env.template +++ b/.env.template @@ -425,6 +425,12 @@ ## KNOW WHAT YOU ARE DOING! # INCREASE_NOTE_SIZE_LIMIT=false +## Enforce Single Org with Reset Password Policy +## Enforce that the Single Org policy is enabled before setting the Reset Password policy +## Bitwarden enforces this by default. In Vaultwarden we encouraged to use multiple organizations because groups were not available. +## Setting this to true will enforce the Single Org Policy to be enabled before you can enable the Reset Password policy. +# ENFORCE_SINGLE_ORG_WITH_RESET_PW_POLICY=false + ######################## ### MFA/2FA settings ### ######################## diff --git a/src/api/core/organizations.rs b/src/api/core/organizations.rs index 8f4f7130..f1def030 100644 --- a/src/api/core/organizations.rs +++ b/src/api/core/organizations.rs @@ -1782,6 +1782,38 @@ async fn put_policy( None => err!("Invalid or unsupported policy type"), }; + // Bitwarden only allows the Reset Password policy when Single Org policy is enabled + // Vaultwarden encouraged to use multiple orgs instead of groups because groups were not available in the past + // Now that groups are available we can enforce this option when wanted. + // We put this behind a config option to prevent breaking current installation. + // Maybe we want to enable this by default in the future, but currently it is disabled by default. + if CONFIG.enforce_single_org_with_reset_pw_policy() { + if pol_type_enum == OrgPolicyType::ResetPassword && data.enabled { + let single_org_policy_enabled = + match OrgPolicy::find_by_org_and_type(org_id, OrgPolicyType::SingleOrg, &mut conn).await { + Some(p) => p.enabled, + None => false, + }; + + if !single_org_policy_enabled { + err!("Single Organization policy is not enabled. It is mandatory for this policy to be enabled.") + } + } + + // Also prevent the Single Org Policy to be disabled if the Reset Password policy is enabled + if pol_type_enum == OrgPolicyType::SingleOrg && !data.enabled { + let reset_pw_policy_enabled = + match OrgPolicy::find_by_org_and_type(org_id, OrgPolicyType::ResetPassword, &mut conn).await { + Some(p) => p.enabled, + None => false, + }; + + if reset_pw_policy_enabled { + err!("Account recovery policy is enabled. It is not allowed to disable this policy.") + } + } + } + // When enabling the TwoFactorAuthentication policy, revoke all members that do not have 2FA if pol_type_enum == OrgPolicyType::TwoFactorAuthentication && data.enabled { two_factor::enforce_2fa_policy_for_org( diff --git a/src/config.rs b/src/config.rs index 93944131..f5466e86 100644 --- a/src/config.rs +++ b/src/config.rs @@ -625,6 +625,11 @@ make_config! { increase_note_size_limit: bool, true, def, false; /// Generated max_note_size value to prevent if..else matching during every check _max_note_size: usize, false, gen, |c| if c.increase_note_size_limit {100_000} else {10_000}; + + /// Enforce Single Org with Reset Password Policy |> Enforce that the Single Org policy is enabled before setting the Reset Password policy + /// Bitwarden enforces this by default. In Vaultwarden we encouraged to use multiple organizations because groups were not available. + /// Setting this to true will enforce the Single Org Policy to be enabled before you can enable the Reset Password policy. + enforce_single_org_with_reset_pw_policy: bool, false, def, false; }, /// Yubikey settings