From 224842029dc99ae8b90344a146a5bbd1d4fb5c35 Mon Sep 17 00:00:00 2001 From: Pasindu Yeshan Date: Wed, 18 Dec 2024 15:41:34 +0530 Subject: [PATCH 1/5] Disable rule based password expiry for users missing required scopes --- .changeset/lemon-pets-wait.md | 6 ++++++ apps/console/src/public/deployment.config.json | 4 +--- .../constants/validation-config-constants.ts | 8 ++++++++ .../admin.validation.v1/pages/validation-config-edit.tsx | 5 ++++- 4 files changed, 19 insertions(+), 4 deletions(-) create mode 100644 .changeset/lemon-pets-wait.md diff --git a/.changeset/lemon-pets-wait.md b/.changeset/lemon-pets-wait.md new file mode 100644 index 00000000000..264de80731a --- /dev/null +++ b/.changeset/lemon-pets-wait.md @@ -0,0 +1,6 @@ +--- +"@wso2is/admin.validation.v1": patch +"@wso2is/console": patch +--- + +Disable rule based password expiry for users without required scopes diff --git a/apps/console/src/public/deployment.config.json b/apps/console/src/public/deployment.config.json index 831f821ca3f..72fabfe981c 100644 --- a/apps/console/src/public/deployment.config.json +++ b/apps/console/src/public/deployment.config.json @@ -732,9 +732,7 @@ "console:loginAndRegistration" ], "read": [ - "internal_governance_view", - "internal_group_mgt_view", - "internal_role_mgt_view" + "internal_governance_view" ], "update": [ "internal_config_update", diff --git a/features/admin.validation.v1/constants/validation-config-constants.ts b/features/admin.validation.v1/constants/validation-config-constants.ts index 9ecd2d3b615..b51be91a1a0 100644 --- a/features/admin.validation.v1/constants/validation-config-constants.ts +++ b/features/admin.validation.v1/constants/validation-config-constants.ts @@ -41,6 +41,14 @@ export class ValidationConfigConstants { PASSWORD_MIN_VALUE: 5 }; + /** + * These scopes are checked to determine whether to display the new rule-based password expiry configuration UI. + * If these scopes are not available, legacy password expiry configuration will be shown for backward compatibility. + */ + public static readonly RULE_BASED_PASSWORD_EXPIRY_REQUIRED_SCOPES: string[] = [ + "internal_role_mgt_view", + "internal_group_mgt_view" + ]; } /** diff --git a/features/admin.validation.v1/pages/validation-config-edit.tsx b/features/admin.validation.v1/pages/validation-config-edit.tsx index 297e5ea5fed..c126b4a1667 100644 --- a/features/admin.validation.v1/pages/validation-config-edit.tsx +++ b/features/admin.validation.v1/pages/validation-config-edit.tsx @@ -97,7 +97,6 @@ export const ValidationConfigEditPage: FunctionComponent state?.config?.ui?.features?.loginAndRegistration?.disabledFeatures); - const isRuleBasedPasswordExpiryDisabled: boolean = disabledFeatures?.includes("ruleBasedPasswordExpiry"); const featureConfig: FeatureConfigInterface = useSelector((state: AppState) => state?.config?.ui?.features); const [ isSubmitting, setSubmitting ] = useState(false); @@ -137,6 +136,10 @@ export const ValidationConfigEditPage: FunctionComponent([]); const isReadOnly: boolean = !useRequiredScopes(featureConfig?.governanceConnectors?.scopes?.update); + const hasScopesForRuleBasedPasswordExpiry: boolean = + useRequiredScopes(ValidationConfigConstants.RULE_BASED_PASSWORD_EXPIRY_REQUIRED_SCOPES); + const isRuleBasedPasswordExpiryDisabled: boolean = disabledFeatures?.includes("ruleBasedPasswordExpiry") + || !hasScopesForRuleBasedPasswordExpiry; const { data: passwordHistoryCountData, From 1d32c9fde660b675ac8d0ead2c9dbb9db00434c3 Mon Sep 17 00:00:00 2001 From: Pasindu Yeshan Date: Thu, 19 Dec 2024 10:31:53 +0530 Subject: [PATCH 2/5] Fix handle update method --- .../pages/validation-config-edit.tsx | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/features/admin.validation.v1/pages/validation-config-edit.tsx b/features/admin.validation.v1/pages/validation-config-edit.tsx index c126b4a1667..8218b1703b5 100644 --- a/features/admin.validation.v1/pages/validation-config-edit.tsx +++ b/features/admin.validation.v1/pages/validation-config-edit.tsx @@ -603,14 +603,21 @@ export const ValidationConfigEditPage: FunctionComponent { if (hasPasswordExpiryRuleErrors) return; - const processedFormValues: ValidationFormInterface = { + let processedFormValues: ValidationFormInterface = { ...values, - passwordExpiryEnabled: passwordExpiryEnabled, - passwordExpiryRules: processPasswordExpiryRules(), - passwordExpirySkipFallback: passwordExpirySkipFallback, - passwordExpiryTime: defaultPasswordExpiryTime + passwordExpiryEnabled: passwordExpiryEnabled }; + if (!isRuleBasedPasswordExpiryDisabled) { + processedFormValues = { + ...values, + passwordExpiryEnabled: passwordExpiryEnabled, + passwordExpiryRules: processPasswordExpiryRules(), + passwordExpirySkipFallback: passwordExpirySkipFallback, + passwordExpiryTime: defaultPasswordExpiryTime + }; + } + const updatePasswordPolicies: Promise = serverConfigurationConfig.processPasswordPoliciesSubmitData( processedFormValues, !isPasswordInputValidationEnabled From 6b3787362d3c09f79dd3ba28f11fd3511df7651e Mon Sep 17 00:00:00 2001 From: Pasindu Yeshan Date: Thu, 2 Jan 2025 10:59:56 +0530 Subject: [PATCH 3/5] Introduce ruleBasedPasswordExpiry feature config --- .../resources/deployment.config.json.j2 | 30 +++++++++++++++++++ .../console/src/public/deployment.config.json | 19 ++++++++++++ features/admin.core.v1/models/config.ts | 4 +++ .../constants/validation-config-constants.ts | 9 ++---- .../pages/validation-config-edit.tsx | 21 ++++++------- 5 files changed, 65 insertions(+), 18 deletions(-) diff --git a/apps/console/java/org.wso2.identity.apps.console.server.feature/resources/deployment.config.json.j2 b/apps/console/java/org.wso2.identity.apps.console.server.feature/resources/deployment.config.json.j2 index eb3b282153e..a4b48f75c9d 100644 --- a/apps/console/java/org.wso2.identity.apps.console.server.feature/resources/deployment.config.json.j2 +++ b/apps/console/java/org.wso2.identity.apps.console.server.feature/resources/deployment.config.json.j2 @@ -1304,6 +1304,36 @@ ] }, {% endif %} + {% if console.rule_based_password_expiry is defined %} + "ruleBasedPasswordExpiry": { + "enabled": {% if console.rule_based_password_expiry.enabled is defined %} {{ console.rule_based_password_expiry.enabled }}, + {% else %} true, + {% endif %} + "scopes": { + {% if console.rule_based_password_expiry.scopes is defined %} + {% for operation, scopes in console.rule_based_password_expiry.scopes.items() %} + "{{ operation }}": [ + {% for scope in scopes %} + "{{ scope }}"{{ "," if not loop.last }} + {% endfor %} + ]{{ "," if not loop.last }} + {% endfor %} + {% else %} + "create": [], + "read": [], + "update": [], + "delete": [] + {% endif %} + }, + "disabledFeatures": [ + {% if console.rule_based_password_expiry.disabled_features is defined %} + {% for feature in console.rule_based_password_expiry.disabled_features %} + "{{ feature }}"{{ "," if not loop.last }} + {% endfor %} + {% endif %} + ] + }, + {% endif %} {% if console.server is defined %} "server": { "disabledFeatures": [ diff --git a/apps/console/src/public/deployment.config.json b/apps/console/src/public/deployment.config.json index 72fabfe981c..9d0af78301f 100644 --- a/apps/console/src/public/deployment.config.json +++ b/apps/console/src/public/deployment.config.json @@ -921,6 +921,25 @@ ] } }, + "ruleBasedPasswordExpiry": { + "disabledFeatures": [], + "enabled": true, + "scopes": { + "create": [], + "delete": [], + "feature": [], + "read": [ + "internal_governance_view", + "internal_group_mgt_view", + "internal_role_mgt_view" + ], + "update": [ + "internal_config_update", + "internal_governance_update", + "internal_validation_rule_mgt_update" + ] + } + }, "saml2Configuration": { "disabledFeatures": [], "enabled": true, diff --git a/features/admin.core.v1/models/config.ts b/features/admin.core.v1/models/config.ts index 2a0f12d51c4..bb934362154 100644 --- a/features/admin.core.v1/models/config.ts +++ b/features/admin.core.v1/models/config.ts @@ -250,6 +250,10 @@ export interface FeatureConfigInterface { * Resident Outbound Provisioning feature */ residentOutboundProvisioning?: FeatureAccessConfigInterface; + /** + * Rule based password expiry feature + */ + ruleBasedPasswordExpiry?: FeatureAccessConfigInterface; /** * Connection management feature. */ diff --git a/features/admin.validation.v1/constants/validation-config-constants.ts b/features/admin.validation.v1/constants/validation-config-constants.ts index b51be91a1a0..068892b4858 100644 --- a/features/admin.validation.v1/constants/validation-config-constants.ts +++ b/features/admin.validation.v1/constants/validation-config-constants.ts @@ -42,13 +42,10 @@ export class ValidationConfigConstants { }; /** - * These scopes are checked to determine whether to display the new rule-based password expiry configuration UI. - * If these scopes are not available, legacy password expiry configuration will be shown for backward compatibility. + * Set of keys used to enable/disable features. */ - public static readonly RULE_BASED_PASSWORD_EXPIRY_REQUIRED_SCOPES: string[] = [ - "internal_role_mgt_view", - "internal_group_mgt_view" - ]; + public static readonly FEATURE_DICTIONARY: Map = new Map() + .set("RULE_BASED_PASSWORD_EXPIRY", "validation.ruleBasedPasswordExpiry");; } /** diff --git a/features/admin.validation.v1/pages/validation-config-edit.tsx b/features/admin.validation.v1/pages/validation-config-edit.tsx index 8218b1703b5..51803ef6aae 100644 --- a/features/admin.validation.v1/pages/validation-config-edit.tsx +++ b/features/admin.validation.v1/pages/validation-config-edit.tsx @@ -136,10 +136,11 @@ export const ValidationConfigEditPage: FunctionComponent([]); const isReadOnly: boolean = !useRequiredScopes(featureConfig?.governanceConnectors?.scopes?.update); - const hasScopesForRuleBasedPasswordExpiry: boolean = - useRequiredScopes(ValidationConfigConstants.RULE_BASED_PASSWORD_EXPIRY_REQUIRED_SCOPES); - const isRuleBasedPasswordExpiryDisabled: boolean = disabledFeatures?.includes("ruleBasedPasswordExpiry") - || !hasScopesForRuleBasedPasswordExpiry; + const hasRuleBasedPasswordExpiryReadPermissions: boolean = + useRequiredScopes(featureConfig?.ruleBasedPasswordExpiry?.scopes?.read); + const isRuleBasedPasswordExpiryDisabled: boolean = + disabledFeatures?.includes(ValidationConfigConstants.FEATURE_DICTIONARY.get("RULE_BASED_PASSWORD_EXPIRY")) + || !hasRuleBasedPasswordExpiryReadPermissions; const { data: passwordHistoryCountData, @@ -603,19 +604,15 @@ export const ValidationConfigEditPage: FunctionComponent { if (hasPasswordExpiryRuleErrors) return; - let processedFormValues: ValidationFormInterface = { + const processedFormValues: ValidationFormInterface = { ...values, passwordExpiryEnabled: passwordExpiryEnabled }; if (!isRuleBasedPasswordExpiryDisabled) { - processedFormValues = { - ...values, - passwordExpiryEnabled: passwordExpiryEnabled, - passwordExpiryRules: processPasswordExpiryRules(), - passwordExpirySkipFallback: passwordExpirySkipFallback, - passwordExpiryTime: defaultPasswordExpiryTime - }; + processedFormValues.passwordExpiryRules = processPasswordExpiryRules(); + processedFormValues.passwordExpirySkipFallback = passwordExpirySkipFallback; + processedFormValues.passwordExpiryTime = defaultPasswordExpiryTime; } const updatePasswordPolicies: Promise = serverConfigurationConfig.processPasswordPoliciesSubmitData( From 4f2a1109a3b40308397ccb7230c2807416a3f6b4 Mon Sep 17 00:00:00 2001 From: Pasindu Yeshan Date: Thu, 2 Jan 2025 14:19:02 +0530 Subject: [PATCH 4/5] Refactor --- .../resources/deployment.config.json.j2 | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/apps/console/java/org.wso2.identity.apps.console.server.feature/resources/deployment.config.json.j2 b/apps/console/java/org.wso2.identity.apps.console.server.feature/resources/deployment.config.json.j2 index 67f882de65b..b098e9c7bf5 100644 --- a/apps/console/java/org.wso2.identity.apps.console.server.feature/resources/deployment.config.json.j2 +++ b/apps/console/java/org.wso2.identity.apps.console.server.feature/resources/deployment.config.json.j2 @@ -1337,6 +1337,13 @@ {% endif %} {% if console.rule_based_password_expiry is defined %} "ruleBasedPasswordExpiry": { + "disabledFeatures": [ + {% if console.rule_based_password_expiry.disabled_features is defined %} + {% for feature in console.rule_based_password_expiry.disabled_features %} + "{{ feature }}"{{ "," if not loop.last }} + {% endfor %} + {% endif %} + ], "enabled": {% if console.rule_based_password_expiry.enabled is defined %} {{ console.rule_based_password_expiry.enabled }}, {% else %} true, {% endif %} @@ -1352,17 +1359,11 @@ {% else %} "create": [], "read": [], + "feature": [], "update": [], "delete": [] {% endif %} - }, - "disabledFeatures": [ - {% if console.rule_based_password_expiry.disabled_features is defined %} - {% for feature in console.rule_based_password_expiry.disabled_features %} - "{{ feature }}"{{ "," if not loop.last }} - {% endfor %} - {% endif %} - ] + } }, {% endif %} {% if console.server is defined %} From 058e4a4c64facb79c717a3fe19ec287bf1467083 Mon Sep 17 00:00:00 2001 From: Pasindu Yeshan Date: Thu, 2 Jan 2025 16:59:29 +0530 Subject: [PATCH 5/5] add admin.core to changeset --- .changeset/lemon-pets-wait.md | 1 + 1 file changed, 1 insertion(+) diff --git a/.changeset/lemon-pets-wait.md b/.changeset/lemon-pets-wait.md index 264de80731a..63166366d1b 100644 --- a/.changeset/lemon-pets-wait.md +++ b/.changeset/lemon-pets-wait.md @@ -1,4 +1,5 @@ --- +"@wso2is/admin.core.v1": patch "@wso2is/admin.validation.v1": patch "@wso2is/console": patch ---