From 0ba498587f4714f06684b97570ec3b10bca86f92 Mon Sep 17 00:00:00 2001 From: Pasindu Yeshan <61885844+PasinduYeshan@users.noreply.github.com> Date: Mon, 16 Dec 2024 11:20:42 +0530 Subject: [PATCH] Revert "Add support for passwordExpiryTime in user claims on request" --- .../pom.xml | 8 - .../constants/PasswordPolicyConstants.java | 2 - .../EnforcePasswordResetComponent.java | 6 - .../listener/PasswordExpiryEventListener.java | 115 ------- .../expiry/util/PasswordPolicyUtils.java | 145 +-------- .../expiry/PasswordPolicyUtilsTest.java | 307 ++---------------- .../PasswordResetEnforcerHandlerTest.java | 13 - .../PasswordExpiryEventListenerTest.java | 199 ------------ .../src/test/resources/testng.xml | 1 - 9 files changed, 38 insertions(+), 758 deletions(-) delete mode 100644 components/org.wso2.carbon.identity.password.expiry/src/main/java/org/wso2/carbon/identity/password/expiry/listener/PasswordExpiryEventListener.java delete mode 100644 components/org.wso2.carbon.identity.password.expiry/src/test/java/org/wso2/carbon/identity/password/expiry/listener/PasswordExpiryEventListenerTest.java diff --git a/components/org.wso2.carbon.identity.password.expiry/pom.xml b/components/org.wso2.carbon.identity.password.expiry/pom.xml index 1b257e0b8c..d58f801243 100644 --- a/components/org.wso2.carbon.identity.password.expiry/pom.xml +++ b/components/org.wso2.carbon.identity.password.expiry/pom.xml @@ -89,11 +89,6 @@ mockito-inline test - - org.wso2.carbon.identity.framework - org.wso2.carbon.identity.testutil - test - org.wso2.carbon.identity.organization.management.core org.wso2.carbon.identity.organization.management.service @@ -154,9 +149,6 @@ org.wso2.carbon.user.core; version="${carbon.kernel.package.import.version.range}", org.wso2.carbon.user.core.util; version="${carbon.kernel.package.import.version.range}", org.wso2.carbon.user.core.common; version="${carbon.kernel.package.import.version.range}", - org.wso2.carbon.user.core.listener; version="${carbon.kernel.package.import.version.range}", - org.wso2.carbon.user.core.model; version="${carbon.kernel.package.import.version.range}", - org.wso2.carbon.context; version="${carbon.kernel.package.import.version.range}", org.wso2.carbon.user.api.*; version="${carbon.user.api.imp.pkg.version.range}", org.wso2.carbon.identity.application.common.model.*; version="${carbon.identity.framework.imp.pkg.version.range}", diff --git a/components/org.wso2.carbon.identity.password.expiry/src/main/java/org/wso2/carbon/identity/password/expiry/constants/PasswordPolicyConstants.java b/components/org.wso2.carbon.identity.password.expiry/src/main/java/org/wso2/carbon/identity/password/expiry/constants/PasswordPolicyConstants.java index 14985c0eaa..f48eb32e1d 100644 --- a/components/org.wso2.carbon.identity.password.expiry/src/main/java/org/wso2/carbon/identity/password/expiry/constants/PasswordPolicyConstants.java +++ b/components/org.wso2.carbon.identity.password.expiry/src/main/java/org/wso2/carbon/identity/password/expiry/constants/PasswordPolicyConstants.java @@ -28,7 +28,6 @@ public class PasswordPolicyConstants { "http://wso2.org/claims/identity/lastPasswordUpdateTime"; public static final String LAST_CREDENTIAL_UPDATE_TIMESTAMP_CLAIM_NON_IDENTITY = "http://wso2.org/claims/lastPasswordChangedTimestamp"; - public static final String PASSWORD_EXPIRY_TIME_CLAIM = "http://wso2.org/claims/identity/passwordExpiryTime"; public static final String PASSWORD_RESET_PAGE = "/accountrecoveryendpoint/password-recovery-confirm.jsp"; public static final String PASSWORD_CHANGE_EVENT_HANDLER_NAME = "enforcePasswordResetEventHandler"; public static final String ENFORCE_PASSWORD_RESET_HANDLER = "EnforcePasswordResetHandler"; @@ -58,7 +57,6 @@ public class PasswordPolicyConstants { public static final String AUTHENTICATION_STATUS = "authenticationStatus"; public static final String BASIC_AUTHENTICATOR = "BasicAuthenticator"; public static final String FALSE = "false"; - public static final String TRUE = "true"; public static final String CONFIRMATION_QUERY_PARAM = "&confirmation="; public static final String PASSWORD_EXPIRED_QUERY_PARAMS = "&passwordExpired=true"; public static final String PASSWORD_EXPIRED_MSG_QUERY_PARAM = "&passwordExpiredMsg="; diff --git a/components/org.wso2.carbon.identity.password.expiry/src/main/java/org/wso2/carbon/identity/password/expiry/internal/EnforcePasswordResetComponent.java b/components/org.wso2.carbon.identity.password.expiry/src/main/java/org/wso2/carbon/identity/password/expiry/internal/EnforcePasswordResetComponent.java index a3bdce3194..536128988b 100644 --- a/components/org.wso2.carbon.identity.password.expiry/src/main/java/org/wso2/carbon/identity/password/expiry/internal/EnforcePasswordResetComponent.java +++ b/components/org.wso2.carbon.identity.password.expiry/src/main/java/org/wso2/carbon/identity/password/expiry/internal/EnforcePasswordResetComponent.java @@ -35,10 +35,8 @@ import org.wso2.carbon.identity.event.handler.AbstractEventHandler; import org.wso2.carbon.identity.governance.IdentityGovernanceService; import org.wso2.carbon.identity.governance.common.IdentityConnectorConfig; -import org.wso2.carbon.identity.password.expiry.listener.PasswordExpiryEventListener; import org.wso2.carbon.identity.password.expiry.services.ExpiredPasswordIdentificationService; import org.wso2.carbon.identity.password.expiry.services.impl.ExpiredPasswordIdentificationServiceImpl; -import org.wso2.carbon.user.core.listener.UserOperationEventListener; import org.wso2.carbon.user.core.service.RealmService; import org.wso2.carbon.identity.role.v2.mgt.core.RoleManagementService; @@ -58,10 +56,6 @@ public class EnforcePasswordResetComponent { protected void activate(ComponentContext context) { try { - // Register the listener to capture user operations. - PasswordExpiryEventListener listener = new PasswordExpiryEventListener(); - context.getBundleContext().registerService(UserOperationEventListener.class, listener, null); - EnforcePasswordResetAuthenticationHandler enforcePasswordResetAuthenticationHandler = new EnforcePasswordResetAuthenticationHandler(); BundleContext bundleContext = context.getBundleContext(); diff --git a/components/org.wso2.carbon.identity.password.expiry/src/main/java/org/wso2/carbon/identity/password/expiry/listener/PasswordExpiryEventListener.java b/components/org.wso2.carbon.identity.password.expiry/src/main/java/org/wso2/carbon/identity/password/expiry/listener/PasswordExpiryEventListener.java deleted file mode 100644 index 6f1babafdd..0000000000 --- a/components/org.wso2.carbon.identity.password.expiry/src/main/java/org/wso2/carbon/identity/password/expiry/listener/PasswordExpiryEventListener.java +++ /dev/null @@ -1,115 +0,0 @@ -/* - * Copyright (c) 2024, WSO2 LLC. (http://www.wso2.com). - * - * WSO2 LLC. licenses this file to you under the Apache License, - * Version 2.0 (the "License"); you may not use this file except - * in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ - -package org.wso2.carbon.identity.password.expiry.listener; - -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; -import org.wso2.carbon.context.PrivilegedCarbonContext; -import org.wso2.carbon.identity.application.authentication.framework.exception.PostAuthenticationFailedException; -import org.wso2.carbon.identity.core.AbstractIdentityUserOperationEventListener; -import org.wso2.carbon.identity.core.util.IdentityCoreConstants; -import org.wso2.carbon.identity.password.expiry.constants.PasswordPolicyConstants; -import org.wso2.carbon.identity.password.expiry.exceptions.ExpiredPasswordIdentificationException; -import org.wso2.carbon.identity.password.expiry.models.PasswordExpiryRule; -import org.wso2.carbon.identity.password.expiry.util.PasswordPolicyUtils; -import org.wso2.carbon.user.core.UserStoreException; -import org.wso2.carbon.user.core.UserStoreManager; -import org.wso2.carbon.user.core.model.UserClaimSearchEntry; - -import java.util.Arrays; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.Optional; - -/** - * This is an implementation of UserOperationEventListener. This defines additional operations for some of - * the core user management operations. - */ -public class PasswordExpiryEventListener extends AbstractIdentityUserOperationEventListener { - - private static final Log log = LogFactory.getLog(PasswordExpiryEventListener.class); - - public int getExecutionOrderId() { - - int orderId = getOrderId(); - if (orderId != IdentityCoreConstants.EVENT_LISTENER_ORDER_ID) { - return orderId; - } - return 102; - } - - @Override - public boolean doPostGetUserClaimValues(String username, String[] claims, String profileName, - Map claimMap, UserStoreManager userStoreManager) - throws UserStoreException { - - if (!isEnable() || !Arrays.asList(claims).contains(PasswordPolicyConstants.PASSWORD_EXPIRY_TIME_CLAIM)) { - return true; - } - log.debug("post get user claim values with id is called in PasswordExpiryEventListener"); - - try { - String userTenantDomain = PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantDomain(); - Optional passwordExpiryTime = - PasswordPolicyUtils.getUserPasswordExpiryTime(userTenantDomain, username); - passwordExpiryTime.ifPresent(expiryTime -> claimMap.put(PasswordPolicyConstants.PASSWORD_EXPIRY_TIME_CLAIM, - String.valueOf(expiryTime))); - } catch (ExpiredPasswordIdentificationException e) { - throw new UserStoreException("Error while retrieving password expiry time.", e); - } - return true; - } - - @Override - public boolean doPostGetUsersClaimValues(String[] userNames, String[] claims, String profileName, - UserClaimSearchEntry[] userClaimSearchEntries) throws UserStoreException { - - if (!isEnable() || !Arrays.asList(claims).contains(PasswordPolicyConstants.PASSWORD_EXPIRY_TIME_CLAIM)) { - return true; - } - log.debug("Method doPostGetUsersClaimValues getting executed in the PasswordExpiryEventListener."); - - try { - String tenantDomain = PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantDomain(); - if (!PasswordPolicyUtils.isPasswordExpiryEnabled(tenantDomain)) return true; - - boolean isSkipIfNoApplicableRulesEnabled = - PasswordPolicyUtils.isSkipIfNoApplicableRulesEnabled(tenantDomain); - int defaultPasswordExpiryInDays = PasswordPolicyUtils.getPasswordExpiryInDays(tenantDomain); - List passwordExpiryRules = PasswordPolicyUtils.getPasswordExpiryRules(tenantDomain); - - for (UserClaimSearchEntry userClaimSearchEntry : userClaimSearchEntries) { - String username = userClaimSearchEntry.getUserName(); - - if (userClaimSearchEntry.getClaims() == null) { - userClaimSearchEntry.setClaims(new HashMap()); - } - Optional passwordExpiryTime = PasswordPolicyUtils.getUserPasswordExpiryTime( - tenantDomain, username, true, isSkipIfNoApplicableRulesEnabled, - passwordExpiryRules, defaultPasswordExpiryInDays); - passwordExpiryTime.ifPresent(expiryTime -> userClaimSearchEntry.getClaims() - .put(PasswordPolicyConstants.PASSWORD_EXPIRY_TIME_CLAIM, String.valueOf(expiryTime))); - } - } catch (PostAuthenticationFailedException | ExpiredPasswordIdentificationException e) { - throw new UserStoreException("Error while retrieving password expiry time.", e); - } - return true; - } -} diff --git a/components/org.wso2.carbon.identity.password.expiry/src/main/java/org/wso2/carbon/identity/password/expiry/util/PasswordPolicyUtils.java b/components/org.wso2.carbon.identity.password.expiry/src/main/java/org/wso2/carbon/identity/password/expiry/util/PasswordPolicyUtils.java index 6d1a998667..8469fde2ec 100644 --- a/components/org.wso2.carbon.identity.password.expiry/src/main/java/org/wso2/carbon/identity/password/expiry/util/PasswordPolicyUtils.java +++ b/components/org.wso2.carbon.identity.password.expiry/src/main/java/org/wso2/carbon/identity/password/expiry/util/PasswordPolicyUtils.java @@ -48,13 +48,11 @@ import org.wso2.carbon.user.core.util.UserCoreUtil; import org.wso2.carbon.utils.multitenancy.MultitenantConstants; import org.wso2.carbon.user.core.common.Group; -import org.wso2.carbon.identity.password.expiry.exceptions.ExpiredPasswordIdentificationException; import java.util.ArrayList; import java.util.EnumMap; import java.util.List; import java.util.Map; -import java.util.Optional; import java.util.Set; import java.util.stream.Collectors; @@ -161,8 +159,6 @@ public static boolean isPasswordExpired(String tenantDomain, String tenantAwareU throws PostAuthenticationFailedException { try { - if (!isPasswordExpiryEnabled(tenantDomain)) return false; - UserRealm userRealm = getUserRealm(tenantDomain); UserStoreManager userStoreManager = getUserStoreManager(userRealm); String userId = ((AbstractUserStoreManager) userStoreManager).getUserIDFromUserName(tenantAwareUsername); @@ -180,8 +176,11 @@ public static boolean isPasswordExpired(String tenantDomain, String tenantAwareU skipIfNoApplicableRules); } - List filteredRules = - filterApplicableExpiryRules(passwordExpiryRules, skipIfNoApplicableRules); + // If the default behavior is to skip the password expiry, rules with skip logic are not necessary. + List filteredRules = passwordExpiryRules.stream() + .filter(rule -> !skipIfNoApplicableRules || + !PasswordExpiryRuleOperatorEnum.NE.equals(rule.getOperator())) + .collect(Collectors.toList()); Map> fetchedUserAttributes = new EnumMap<>(PasswordExpiryRuleAttributeEnum.class); @@ -194,7 +193,7 @@ public static boolean isPasswordExpired(String tenantDomain, String tenantAwareU } int expiryDays = rule.getExpiryDays() > 0 ? rule.getExpiryDays() : getPasswordExpiryInDays(tenantDomain); - return daysDifference >= expiryDays || StringUtils.isBlank(lastPasswordUpdatedTime); + return daysDifference >= expiryDays || lastPasswordUpdatedTime == null; } } // Apply default password expiry policy if no specific rule applies. @@ -293,137 +292,7 @@ private static boolean isPasswordExpiredUnderDefaultPolicy(String tenantDomain, throws PostAuthenticationFailedException { if (skipIfNoApplicableRules) return false; - return StringUtils.isBlank(lastPasswordUpdatedTime) || daysDifference >= getPasswordExpiryInDays(tenantDomain); - } - - /** - * This method returns password expiry time for the given user. - * - * @param tenantDomain The tenant domain. - * @param tenantAwareUsername The tenant aware username. - * @return Optional containing the password expiry time in milliseconds, or empty if not applicable. - * @throws ExpiredPasswordIdentificationException If an error occurred while getting the password expiry time. - */ - public static Optional getUserPasswordExpiryTime(String tenantDomain, String tenantAwareUsername) - throws ExpiredPasswordIdentificationException { - - return getUserPasswordExpiryTime(tenantDomain, tenantAwareUsername, null, - null, null, null); - } - - /** - * This method returns password expiry time for the given user. - * - * @param tenantDomain The tenant domain. - * @param tenantAwareUsername The tenant aware username. - * @param isPasswordExpiryEnabled Whether password expiry is enabled. - * @param isSkipIfNoApplicableRulesEnabled Whether skip if no applicable rules config is enabled. - * @param passwordExpiryRules Password expiry rules. - * @param defaultPasswordExpiryInDays Default password expiry in days. - * @return Optional containing the password expiry time in milliseconds, or empty if not applicable. - * @throws ExpiredPasswordIdentificationException If an error occurred while getting the password expiry time. - */ - public static Optional getUserPasswordExpiryTime(String tenantDomain, - String tenantAwareUsername, - Boolean isPasswordExpiryEnabled, - Boolean isSkipIfNoApplicableRulesEnabled, - List passwordExpiryRules, - Integer defaultPasswordExpiryInDays) - throws ExpiredPasswordIdentificationException { - - try { - if (isPasswordExpiryEnabled == null) { - isPasswordExpiryEnabled = isPasswordExpiryEnabled(tenantDomain); - } - // If the password expiry is not enabled, password expiry time is not applicable. - if (!isPasswordExpiryEnabled) return Optional.empty(); - - if (isSkipIfNoApplicableRulesEnabled == null) { - isSkipIfNoApplicableRulesEnabled = isSkipIfNoApplicableRulesEnabled(tenantDomain); - } - if (defaultPasswordExpiryInDays == null) { - defaultPasswordExpiryInDays = getPasswordExpiryInDays(tenantDomain); - } - if (passwordExpiryRules == null) { - passwordExpiryRules = getPasswordExpiryRules(tenantDomain); - } - - UserRealm userRealm = getUserRealm(tenantDomain); - UserStoreManager userStoreManager = getUserStoreManager(userRealm); - String userId = ((AbstractUserStoreManager) userStoreManager).getUserIDFromUserName(tenantAwareUsername); - String lastPasswordUpdatedTime = - getLastPasswordUpdatedTime(tenantAwareUsername, userStoreManager, userRealm); - - long lastPasswordUpdatedTimeInMillis = 0L; - boolean isLastPasswordUpdatedTimeBlank = StringUtils.isBlank(lastPasswordUpdatedTime); - if (!isLastPasswordUpdatedTimeBlank) { - lastPasswordUpdatedTimeInMillis = getLastPasswordUpdatedTimeInMillis(lastPasswordUpdatedTime); - } - - // If no rules are defined, use the default expiry time if "skipIfNoApplicableRules" is disabled. - if (CollectionUtils.isEmpty(passwordExpiryRules)) { - if (isSkipIfNoApplicableRulesEnabled) return Optional.empty(); - // If lastPasswordUpdatedTime is blank, set expiry time to now. - if (isLastPasswordUpdatedTimeBlank) { - return Optional.of(System.currentTimeMillis()); - } - return Optional.of( - lastPasswordUpdatedTimeInMillis + getDaysTimeInMillis(defaultPasswordExpiryInDays)); - } - - Map> userAttributes = - new EnumMap<>(PasswordExpiryRuleAttributeEnum.class); - - List filteredRules = - filterApplicableExpiryRules(passwordExpiryRules, isSkipIfNoApplicableRulesEnabled); - for (PasswordExpiryRule rule : filteredRules) { - if (isRuleApplicable(rule, userAttributes, tenantDomain, userId, userStoreManager)) { - // Skip the rule if the operator is not equals. - if (PasswordExpiryRuleOperatorEnum.NE.equals(rule.getOperator())) { - return Optional.empty(); - } - if (isLastPasswordUpdatedTimeBlank) { - return Optional.of(System.currentTimeMillis()); - } - int expiryDays = - rule.getExpiryDays() > 0 ? rule.getExpiryDays() : getPasswordExpiryInDays(tenantDomain); - return Optional.of(lastPasswordUpdatedTimeInMillis + getDaysTimeInMillis(expiryDays)); - } - } - - if (isSkipIfNoApplicableRulesEnabled) return Optional.empty(); - if (isLastPasswordUpdatedTimeBlank) { - return Optional.of(System.currentTimeMillis()); - } - return Optional.of( - lastPasswordUpdatedTimeInMillis + getDaysTimeInMillis(defaultPasswordExpiryInDays)); - } catch (UserStoreException | PostAuthenticationFailedException e) { - throw new ExpiredPasswordIdentificationException(PasswordPolicyConstants.ErrorMessages. - ERROR_WHILE_GETTING_USER_STORE_DOMAIN.getCode(), - PasswordPolicyConstants.ErrorMessages.ERROR_WHILE_GETTING_USER_STORE_DOMAIN.getMessage()); - } - } - - private static List filterApplicableExpiryRules(List passwordExpiryRules, - boolean skipIfNoApplicableRules) { - - if (!skipIfNoApplicableRules) { - return passwordExpiryRules; - } - // If the default behavior is to skip the password expiry, rules with skip logic are not required. - return passwordExpiryRules.stream().filter( - rule -> !PasswordExpiryRuleOperatorEnum.NE.equals(rule.getOperator())).collect(Collectors.toList()); - } - - /** - * This method returns the time in milliseconds for the given number of days. - * - * @param days The number of days. - * @return The time in milliseconds. - */ - private static long getDaysTimeInMillis(int days) { - - return (long) days * 24 * 60 * 60 * 1000; + return lastPasswordUpdatedTime == null || daysDifference >= getPasswordExpiryInDays(tenantDomain); } /** diff --git a/components/org.wso2.carbon.identity.password.expiry/src/test/java/org/wso2/carbon/identity/password/expiry/PasswordPolicyUtilsTest.java b/components/org.wso2.carbon.identity.password.expiry/src/test/java/org/wso2/carbon/identity/password/expiry/PasswordPolicyUtilsTest.java index 1600a8024d..09f15c6226 100644 --- a/components/org.wso2.carbon.identity.password.expiry/src/test/java/org/wso2/carbon/identity/password/expiry/PasswordPolicyUtilsTest.java +++ b/components/org.wso2.carbon.identity.password.expiry/src/test/java/org/wso2/carbon/identity/password/expiry/PasswordPolicyUtilsTest.java @@ -19,12 +19,7 @@ package org.wso2.carbon.identity.password.expiry; import org.testng.annotations.DataProvider; -import org.wso2.carbon.base.MultitenantConstants; -import org.wso2.carbon.identity.core.ServiceURL; -import org.wso2.carbon.identity.core.ServiceURLBuilder; -import org.wso2.carbon.identity.core.URLBuilderException; import org.wso2.carbon.identity.password.expiry.constants.PasswordPolicyConstants; -import org.wso2.carbon.identity.password.expiry.exceptions.ExpiredPasswordIdentificationException; import org.wso2.carbon.identity.password.expiry.internal.EnforcePasswordResetComponentDataHolder; import org.wso2.carbon.identity.password.expiry.models.PasswordExpiryRuleAttributeEnum; import org.wso2.carbon.identity.governance.bean.ConnectorConfig; @@ -61,8 +56,6 @@ import java.util.List; import java.util.Map; import java.util.HashMap; -import java.util.Optional; -import java.util.stream.Collectors; import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.anyInt; @@ -72,7 +65,6 @@ import static org.mockito.Mockito.mockStatic; import static org.mockito.Mockito.when; import static org.mockito.Mockito.verify; -import static org.wso2.carbon.identity.password.expiry.constants.PasswordPolicyConstants.PASSWORD_RESET_PAGE; /** * Tests for password change utils. @@ -101,20 +93,11 @@ public class PasswordPolicyUtilsTest { @Mock private RoleManagementService roleManagementService; - @Mock - private ServiceURLBuilder serviceURLBuilder; - - @Mock - private ServiceURL serviceURL; - private MockedStatic mockedStaticUserCoreUtil; - private MockedStatic mockedStaticServiceURLBuilder; private final String tenantDomain = "test.com"; private final String tenantAwareUsername = "tom@gmail.com"; private final String userId = "testUserId"; - private static final long TIME_TOLERANCE_MS = 2000; - private static final int DEFAULT_EXPIRY_DAYS = 30; private static final Map ROLE_MAP = new HashMap<>(); static { @@ -133,7 +116,6 @@ public void beforeTest() { mockedStaticIdentityTenantUtil = mockStatic(IdentityTenantUtil.class); mockedStaticUserCoreUtil = mockStatic(UserCoreUtil.class); - mockedStaticServiceURLBuilder = mockStatic(ServiceURLBuilder.class); } @AfterClass @@ -162,7 +144,13 @@ public void testGetPasswordExpiryPropertyNames() { @Test public void testPasswordExpiryEnabled() throws PostAuthenticationFailedException, IdentityGovernanceException { - mockPasswordExpiryEnabled(identityGovernanceService, PasswordPolicyConstants.FALSE); + Property property = new Property(); + property.setName(PasswordPolicyConstants.CONNECTOR_CONFIG_ENABLE_PASSWORD_EXPIRY); + property.setValue(PasswordPolicyConstants.FALSE); + Property[] properties = new Property[1]; + properties[0] = property; + when(identityGovernanceService.getConfiguration(new String[]{ + PasswordPolicyConstants.CONNECTOR_CONFIG_ENABLE_PASSWORD_EXPIRY}, tenantDomain)).thenReturn(properties); Assert.assertFalse(PasswordPolicyUtils.isPasswordExpiryEnabled(tenantDomain)); } @@ -201,40 +189,6 @@ public void testGetPasswordExpiryRules() throws PostAuthenticationFailedExceptio Assert.assertEquals(Arrays.asList(ROLE_MAP.get("employee"), ROLE_MAP.get("manager")), rule3.getValues()); } - @Test - public void testGetPasswordExpiryRulesWithInvalidRules() throws PostAuthenticationFailedException, IdentityGovernanceException { - - Property expiryRule1 = new Property(); - Property expiryRule2 = new Property(); - Property expiryRule3 = new Property(); - Property expiryRule4 = new Property(); - expiryRule1.setName(PasswordPolicyConstants.PASSWORD_EXPIRY_RULES_PREFIX+"1"); - expiryRule1.setValue(String.format("1,0,groups,ne,%s", GROUP_MAP.get("admin"))); - expiryRule2.setName(PasswordPolicyConstants.PASSWORD_EXPIRY_RULES_PREFIX+"2"); - expiryRule2.setValue( - String.format("2,40,invalid_rule,%s,%s", ROLE_MAP.get("employee"), ROLE_MAP.get("contractor"))); - expiryRule3.setName(PasswordPolicyConstants.PASSWORD_EXPIRY_RULES_PREFIX+"3"); - expiryRule3.setValue( - String.format("bbb,40,groups,ne,%s,%s", ROLE_MAP.get("employee"), ROLE_MAP.get("contractor"))); - expiryRule4.setName(PasswordPolicyConstants.PASSWORD_EXPIRY_RULES_PREFIX+"4"); - expiryRule4.setValue( - String.format("-1,40,groups,ne,%s,%s", ROLE_MAP.get("employee"), ROLE_MAP.get("contractor"))); - - Property[] properties = new Property[4]; - properties[0] = expiryRule1; - properties[1] = expiryRule2; - properties[2] = expiryRule3; - properties[3] = expiryRule4; - ConnectorConfig connectorConfig = new ConnectorConfig(); - connectorConfig.setProperties(properties); - - when(identityGovernanceService.getConnectorWithConfigs(tenantDomain, - PasswordPolicyConstants.CONNECTOR_CONFIG_NAME)).thenReturn(connectorConfig); - - List rules = PasswordPolicyUtils.getPasswordExpiryRules(tenantDomain); - Assert.assertEquals(rules.size(), 1); - } - @Test public void testGetUserRoles() throws PostAuthenticationFailedException, IdentityRoleManagementException { @@ -262,9 +216,8 @@ public void testIsPasswordExpiredWithoutRules(Integer daysAgo, boolean expectedE when(userRealm.getUserStoreManager()).thenReturn(abstractUserStoreManager); when(userRealm.getClaimManager()).thenReturn(claimManager); when(UserCoreUtil.addDomainToName(any(), any())).thenReturn(tenantAwareUsername); - when(abstractUserStoreManager.getUserIDFromUserName(tenantAwareUsername)).thenReturn(userId); - mockPasswordExpiryEnabled(identityGovernanceService, PasswordPolicyConstants.TRUE); + when(abstractUserStoreManager.getUserIDFromUserName(tenantAwareUsername)).thenReturn(userId); // Mock last password updated time. Long updateTime = getUpdateTime(daysAgo); @@ -289,17 +242,17 @@ public void testIsPasswordExpiredWithoutRules(Integer daysAgo, boolean expectedE public Object[][] passwordExpiryTestCases() { return new Object[][] { // {daysAgo, roles, groups, skipIfNoApplicableRules, expectedExpired, description}. - {55, new String[]{"employee", "manager"}, new String[]{}, false, false, + {55, new String[]{ROLE_MAP.get("employee"), ROLE_MAP.get("manager")}, new String[]{}, false, false, "Not expired: 3rd rule (60) applies"}, - {55, new String[]{"employee", "manager", "contractor"}, + {55, new String[]{ROLE_MAP.get("employee"), ROLE_MAP.get("manager"), ROLE_MAP.get("contractor")}, new String[]{}, false, true, "Expired: 2nd rule (40) applies"}, - {35, new String[]{"employee", "contractor"}, new String[]{}, false, false, + {35, new String[]{ROLE_MAP.get("employee"), ROLE_MAP.get("contractor")}, new String[]{}, false, false, "Not expired: 2nd rule (40) applies"}, - {35, new String[]{"employee", "contractor"}, new String[]{"admin"}, false, + {35, new String[]{ROLE_MAP.get("employee"), ROLE_MAP.get("contractor")}, new String[]{"admin"}, false, false, "Not expired: 1st rule (skip) applies."}, - {35, new String[]{"employee"}, new String[]{}, false, true, + {35, new String[]{ROLE_MAP.get("employee")}, new String[]{}, false, true, "Expired: Default expiry policy applies."}, - {35, new String[]{"employee"}, new String[]{}, true, false, + {35, new String[]{ROLE_MAP.get("employee")}, new String[]{}, true, false, "Not expired: Default expiry policy applies - skip if no rules applicable."}, }; } @@ -318,9 +271,13 @@ public void testIsPasswordExpiredWithRules(int daysAgo, String[] roles, String[] when(UserCoreUtil.addDomainToName(any(), any())).thenReturn(tenantAwareUsername); when(roleManagementService.getRoleListOfUser(userId, tenantDomain)).thenReturn(getRoles(roles)); - mockPasswordExpiryEnabled(identityGovernanceService, PasswordPolicyConstants.TRUE); - - when(abstractUserStoreManager.getGroupListOfUser(userId, null, null)).thenReturn(getGroups(groups)); + List userGroups = new ArrayList<>(); + Arrays.stream(groups).forEach(groupName -> { + Group groupObj = new Group(); + groupObj.setGroupID(GROUP_MAP.get(groupName)); + userGroups.add(groupObj); + }); + when(abstractUserStoreManager.getGroupListOfUser(userId, null, null)).thenReturn(userGroups); // Mock last password update time. Long updateTime = getUpdateTime(daysAgo); @@ -343,216 +300,22 @@ public void testIsPasswordExpiredWithRules(int daysAgo, String[] roles, String[] Assert.assertEquals(isExpired, expectedExpired, description); } - @DataProvider(name = "passwordExpiryTimeTestCases") - public Object[][] passwordExpiryTimeTestCases() { - return new Object[][] { - // {daysAgo, roles, groups, expiryDays, description} - {null, new String[]{"employee", "manager"}, new String[]{}, 0, "Expiry time: Now"}, - {30, new String[]{"employee", "manager"}, new String[]{}, 60, "60 days expiry: 3rd rule applies"}, - {100, new String[]{"employee"}, new String[]{"admin"}, null, "1st rule (skip) applies."}, - {10, new String[]{"employee"}, new String[]{}, 30, "30 days expiry: Default expiry policy applies"}, - {50, new String[]{"employee", "contractor"}, new String[]{}, 40, "40 days expiry: 2nd rule applies"} - }; - } - - @Test(dataProvider = "passwordExpiryTimeTestCases") - public void testGetUserPasswordExpiryTime(Integer daysAgo, String[] roles, String[] groups, Integer expiryDays, - String description) - throws IdentityGovernanceException, UserStoreException, ExpiredPasswordIdentificationException, - IdentityRoleManagementException { - - when(IdentityTenantUtil.getTenantId(anyString())).thenReturn(3); - when(realmService.getTenantUserRealm(anyInt())).thenReturn(userRealm); - when(userRealm.getUserStoreManager()).thenReturn(abstractUserStoreManager); - when(userRealm.getClaimManager()).thenReturn(claimManager); - when(abstractUserStoreManager.getUserIDFromUserName(tenantAwareUsername)).thenReturn(userId); - when(UserCoreUtil.addDomainToName(any(), any())).thenReturn(tenantAwareUsername); - - // Mock last password update time. - Long updateTime = daysAgo != null ? System.currentTimeMillis() - getDaysTimeInMillis(daysAgo) : null; - mockLastPasswordUpdateTime(updateTime, abstractUserStoreManager); - - mockPasswordExpiryEnabled(identityGovernanceService, PasswordPolicyConstants.TRUE); - - // Mock password expiry rules. - ConnectorConfig connectorConfig = new ConnectorConfig(); - connectorConfig.setProperties(getPasswordExpiryRulesProperties()); - when(identityGovernanceService.getConnectorWithConfigs(tenantDomain, - PasswordPolicyConstants.CONNECTOR_CONFIG_NAME)).thenReturn(connectorConfig); - - when(identityGovernanceService.getConfiguration( - new String[]{PasswordPolicyConstants.CONNECTOR_CONFIG_PASSWORD_EXPIRY_IN_DAYS}, - tenantDomain)).thenReturn(getPasswordExpiryInDaysProperty()); - when(identityGovernanceService.getConfiguration( - new String[]{PasswordPolicyConstants.CONNECTOR_CONFIG_SKIP_IF_NO_APPLICABLE_RULES}, - tenantDomain)).thenReturn(getSkipIfNoRulesApplicableProperty(PasswordPolicyConstants.FALSE)); - - // Mock user roles. - when(roleManagementService.getRoleListOfUser(userId, tenantDomain)).thenReturn(getRoles(roles)); - - // Mock user groups. - when(abstractUserStoreManager.getGroupListOfUser(userId, null, null)) - .thenReturn(getGroups(groups)); - - long testStartTime = System.currentTimeMillis(); - Optional expiryTime = - PasswordPolicyUtils.getUserPasswordExpiryTime(tenantDomain, tenantAwareUsername); - long testEndTime = System.currentTimeMillis(); - - if (expiryDays == null) { - Assert.assertFalse(expiryTime.isPresent(), description); - } else if (expiryDays == 0) { - Assert.assertTrue(expiryTime.isPresent()); - Assert.assertTrue(expiryTime.get() >= testStartTime && expiryTime.get() <= testEndTime); - } else { - Assert.assertTrue(expiryTime.isPresent()); - Assert.assertNotNull(updateTime); - long expectedExpiryTime = updateTime + getDaysTimeInMillis(expiryDays); - Assert.assertTrue(Math.abs(expiryTime.get() - expectedExpiryTime) <= TIME_TOLERANCE_MS); - } - } - - @Test - public void testGetUserPasswordExpiryTime() - throws IdentityGovernanceException, UserStoreException, ExpiredPasswordIdentificationException { - - // Case 1: Password expiry disabled. - Optional expiryTime = PasswordPolicyUtils.getUserPasswordExpiryTime( - tenantDomain, tenantAwareUsername, false, null, - null, null); - Assert.assertFalse(expiryTime.isPresent()); - - // Case 2: Password expiry enabled, but no rules. - mockPasswordExpiryEnabled(identityGovernanceService, PasswordPolicyConstants.TRUE); - when(IdentityTenantUtil.getTenantId(anyString())).thenReturn(3); - when(realmService.getTenantUserRealm(anyInt())).thenReturn(userRealm); - when(userRealm.getUserStoreManager()).thenReturn(abstractUserStoreManager); - when(userRealm.getClaimManager()).thenReturn(claimManager); - when(abstractUserStoreManager.getUserIDFromUserName(tenantAwareUsername)).thenReturn(userId); - when(UserCoreUtil.addDomainToName(any(), any())).thenReturn(tenantAwareUsername); - - // Mock last password update time to 20 days. - Long updateTime = System.currentTimeMillis() - getDaysTimeInMillis(20); - mockLastPasswordUpdateTime(updateTime, abstractUserStoreManager); - - expiryTime = PasswordPolicyUtils.getUserPasswordExpiryTime( - tenantDomain, tenantAwareUsername, true, false, - Collections.emptyList(), DEFAULT_EXPIRY_DAYS); - - long expectedExpiryTime = updateTime + getDaysTimeInMillis(DEFAULT_EXPIRY_DAYS); - Assert.assertTrue(Math.abs(expiryTime.get() - expectedExpiryTime) <= TIME_TOLERANCE_MS); - - // Case 3: Password expiry enabled, no applicable rules, skipIfNoApplicableRules enabled. - when(identityGovernanceService.getConfiguration( - new String[]{PasswordPolicyConstants.CONNECTOR_CONFIG_SKIP_IF_NO_APPLICABLE_RULES}, - tenantDomain)).thenReturn(getSkipIfNoRulesApplicableProperty(PasswordPolicyConstants.TRUE)); - - expiryTime = PasswordPolicyUtils.getUserPasswordExpiryTime(tenantDomain, tenantAwareUsername, - true, true, Collections.emptyList(), - DEFAULT_EXPIRY_DAYS); - Assert.assertFalse(expiryTime.isPresent()); - - // Case 4: UserStoreException. - when(abstractUserStoreManager.getUserIDFromUserName(tenantAwareUsername)).thenThrow( - new org.wso2.carbon.user.core.UserStoreException()); - try { - PasswordPolicyUtils.getUserPasswordExpiryTime(tenantDomain, tenantAwareUsername, - true, true, Collections.emptyList(), - DEFAULT_EXPIRY_DAYS); - Assert.fail("Expected PostAuthenticationFailedException was not thrown"); - } catch (Exception e) { - Assert.assertTrue(e instanceof ExpiredPasswordIdentificationException); - } - } - - @Test - public void testGetPasswordResetPageUrl() throws Exception { - - // Mocking ServiceURLBuilder - mockedStaticServiceURLBuilder.when( - (MockedStatic.Verification) ServiceURLBuilder.create()).thenReturn(serviceURLBuilder); - when(serviceURLBuilder.addPath(PASSWORD_RESET_PAGE)).thenReturn(serviceURLBuilder); - when(serviceURLBuilder.setTenant(anyString())).thenReturn(serviceURLBuilder); - when(serviceURLBuilder.build()).thenReturn(serviceURL); - - // Case 1: Tenant qualified URLs enabled. - mockedStaticIdentityTenantUtil.when(IdentityTenantUtil::isTenantQualifiedUrlsEnabled).thenReturn(true); - String tenantQualifiedURL = - String.format("https://example.com/t/%s/accountrecoveryendpoint/password-reset", tenantDomain); - when(serviceURL.getAbsolutePublicURL()).thenReturn(tenantQualifiedURL); - - String result = PasswordPolicyUtils.getPasswordResetPageUrl(tenantDomain); - Assert.assertEquals(tenantQualifiedURL, result); - - // Case 2: Tenant qualified URLs disabled, non-super tenant. - mockedStaticIdentityTenantUtil.when(IdentityTenantUtil::isTenantQualifiedUrlsEnabled).thenReturn(false); - String serverURL = "https://example.com"; - when(serviceURL.getAbsolutePublicURL()).thenReturn(serverURL); - - result = PasswordPolicyUtils.getPasswordResetPageUrl(tenantDomain); - Assert.assertEquals( - String.format("%s/t/%s%s?tenantDomain=%s", serverURL, tenantDomain, PASSWORD_RESET_PAGE, tenantDomain), - result); - - // Case 3: Tenant qualified URLs disabled, super tenant. - result = PasswordPolicyUtils.getPasswordResetPageUrl(MultitenantConstants.SUPER_TENANT_DOMAIN_NAME); - Assert.assertEquals(String.format("%s%s", serverURL, PASSWORD_RESET_PAGE), result); - - // Case 4: URLBuilderException. - when(serviceURLBuilder.build()).thenThrow(new URLBuilderException("Test exception")); - try { - PasswordPolicyUtils.getPasswordResetPageUrl(tenantDomain); - Assert.fail("Expected PostAuthenticationFailedException was not thrown"); - } catch (PostAuthenticationFailedException e) { - Assert.assertEquals( - PasswordPolicyConstants.ErrorMessages.ERROR_WHILE_BUILDING_PASSWORD_RESET_PAGE_URL.getCode(), - e.getErrorCode()); - } - } - - private void mockPasswordExpiryEnabled(IdentityGovernanceService identityGovernanceService, String enabled) throws IdentityGovernanceException { - - Property property = new Property(); - property.setName(PasswordPolicyConstants.CONNECTOR_CONFIG_ENABLE_PASSWORD_EXPIRY); - property.setValue(enabled); - Property[] properties = new Property[1]; - properties[0] = property; - when(identityGovernanceService.getConfiguration(new String[]{ - PasswordPolicyConstants.CONNECTOR_CONFIG_ENABLE_PASSWORD_EXPIRY}, tenantDomain)).thenReturn(properties); - } - - private static Long getDaysTimeInMillis(Integer days) { - - return days != null ? (long) days * 24 * 60 * 60 * 1000 : null; - } - private static Long getUpdateTime(Integer daysAgo) { - return daysAgo != null ? System.currentTimeMillis() - getDaysTimeInMillis(daysAgo) : null; + return daysAgo != null ? System.currentTimeMillis() - daysAgo * 24 * 60 * 60 * 1000L : null; } - private List getRoles(String[] roleNames) { + private List getRoles(String[] roleIds) { List userRoles = new ArrayList<>(); - for (String roleId : roleNames) { + for (String roleId : roleIds) { RoleBasicInfo roleInfo = new RoleBasicInfo(); - roleInfo.setId(ROLE_MAP.get(roleId)); + roleInfo.setId(roleId); userRoles.add(roleInfo); } return userRoles; } - private static List getGroups(String[] groupNames) { - - List userGroups = new ArrayList<>(); - Arrays.stream(groupNames).forEach(groupName -> { - Group groupObj = new Group(); - groupObj.setGroupID(GROUP_MAP.get(groupName)); - userGroups.add(groupObj); - }); - return userGroups; - } - private Property[] getPasswordExpiryRulesProperties() { Property expiryRule1 = new Property(); @@ -578,7 +341,7 @@ private Property[] getPasswordExpiryInDaysProperty() { Property property1 = new Property(); property1.setName(PasswordPolicyConstants.CONNECTOR_CONFIG_PASSWORD_EXPIRY_IN_DAYS); - property1.setValue(String.valueOf(DEFAULT_EXPIRY_DAYS)); + property1.setValue(String.valueOf(30)); Property[] properties = new Property[1]; properties[0] = property1; return properties; @@ -596,18 +359,10 @@ private Property[] getSkipIfNoRulesApplicableProperty(String value) { private void mockLastPasswordUpdateTime(Long updateTime, UserStoreManager userStoreManager) throws UserStoreException { - String updateTimeString = updateTime != null ? String.valueOf(updateTime) : null; - - // Mock for LAST_CREDENTIAL_UPDATE_TIMESTAMP_CLAIM. - Map claims1 = new HashMap<>(); - claims1.put(PasswordPolicyConstants.LAST_CREDENTIAL_UPDATE_TIMESTAMP_CLAIM, updateTimeString); - String[] claimURIs1 = new String[]{PasswordPolicyConstants.LAST_CREDENTIAL_UPDATE_TIMESTAMP_CLAIM}; - when(userStoreManager.getUserClaimValues(anyString(), eq(claimURIs1), isNull())).thenReturn(claims1); - - // Mock for LAST_CREDENTIAL_UPDATE_TIMESTAMP_CLAIM_NON_IDENTITY. - Map claims2 = new HashMap<>(); - claims2.put(PasswordPolicyConstants.LAST_CREDENTIAL_UPDATE_TIMESTAMP_CLAIM_NON_IDENTITY, updateTimeString); - String[] claimURIs2 = new String[]{PasswordPolicyConstants.LAST_CREDENTIAL_UPDATE_TIMESTAMP_CLAIM_NON_IDENTITY}; - when(userStoreManager.getUserClaimValues(anyString(), eq(claimURIs2), isNull())).thenReturn(claims2); + Map claims = new HashMap<>(); + claims.put(PasswordPolicyConstants.LAST_CREDENTIAL_UPDATE_TIMESTAMP_CLAIM, + updateTime != null ? String.valueOf(updateTime) : null); + String[] claimURIs = new String[]{PasswordPolicyConstants.LAST_CREDENTIAL_UPDATE_TIMESTAMP_CLAIM}; + when(userStoreManager.getUserClaimValues(anyString(), eq(claimURIs), isNull())).thenReturn(claims); } } diff --git a/components/org.wso2.carbon.identity.password.expiry/src/test/java/org/wso2/carbon/identity/password/expiry/PasswordResetEnforcerHandlerTest.java b/components/org.wso2.carbon.identity.password.expiry/src/test/java/org/wso2/carbon/identity/password/expiry/PasswordResetEnforcerHandlerTest.java index 2ee2a2e4d4..1e15901c78 100644 --- a/components/org.wso2.carbon.identity.password.expiry/src/test/java/org/wso2/carbon/identity/password/expiry/PasswordResetEnforcerHandlerTest.java +++ b/components/org.wso2.carbon.identity.password.expiry/src/test/java/org/wso2/carbon/identity/password/expiry/PasswordResetEnforcerHandlerTest.java @@ -155,13 +155,6 @@ public void testHandle() throws Exception { when(authenticationContext.getCurrentAuthenticatedIdPs()).thenReturn(idPs); idPs.put(AUTHENTICATOR_TYPE, authenticatedIdPData); - // Case 1 : Password expiry is not enabled. - when(PasswordPolicyUtils.isPasswordExpiryEnabled(anyString())).thenReturn(false); - PostAuthnHandlerFlowStatus flowStatus1 = enforcePasswordResetAuthenticationHandler.handle(httpServletRequest, - httpServletResponse, authenticationContext); - Assert.assertEquals(flowStatus1, PostAuthnHandlerFlowStatus.SUCCESS_COMPLETED); - - // Case 2 : Password expiry is enabled. List authenticators = getAuthenticatorConfigs(); when(PasswordPolicyUtils.isPasswordExpiryEnabled(anyString())).thenReturn(true); when(PasswordPolicyUtils.isPasswordExpired(anyString(), anyString())).thenReturn(true); @@ -186,12 +179,6 @@ public void testHandle() throws Exception { httpServletResponse, authenticationContext); Assert.assertEquals(flowStatus, PostAuthnHandlerFlowStatus.INCOMPLETE); verify(httpServletResponse).sendRedirect(captor.capture()); - - // Case 3 : Password expiry is enabled and password is not expired. - when(PasswordPolicyUtils.isPasswordExpired(anyString(), anyString())).thenReturn(false); - PostAuthnHandlerFlowStatus flowStatus2 = enforcePasswordResetAuthenticationHandler.handle(httpServletRequest, - httpServletResponse, authenticationContext); - Assert.assertEquals(flowStatus2, PostAuthnHandlerFlowStatus.SUCCESS_COMPLETED); } private static List getAuthenticatorConfigs() { diff --git a/components/org.wso2.carbon.identity.password.expiry/src/test/java/org/wso2/carbon/identity/password/expiry/listener/PasswordExpiryEventListenerTest.java b/components/org.wso2.carbon.identity.password.expiry/src/test/java/org/wso2/carbon/identity/password/expiry/listener/PasswordExpiryEventListenerTest.java deleted file mode 100644 index 93941822b0..0000000000 --- a/components/org.wso2.carbon.identity.password.expiry/src/test/java/org/wso2/carbon/identity/password/expiry/listener/PasswordExpiryEventListenerTest.java +++ /dev/null @@ -1,199 +0,0 @@ -/* - * Copyright (c) 2024, WSO2 LLC. (http://www.wso2.com). - * - * WSO2 LLC. licenses this file to you under the Apache License, - * Version 2.0 (the "License"); you may not use this file except - * in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ - -package org.wso2.carbon.identity.password.expiry.listener; - -import org.wso2.carbon.context.PrivilegedCarbonContext; -import org.wso2.carbon.identity.password.expiry.constants.PasswordPolicyConstants; -import org.wso2.carbon.identity.password.expiry.exceptions.ExpiredPasswordIdentificationException; -import org.wso2.carbon.identity.password.expiry.util.PasswordPolicyUtils; -import org.mockito.Mock; -import org.mockito.MockedStatic; -import org.mockito.MockitoAnnotations; -import org.testng.Assert; -import org.testng.annotations.AfterClass; -import org.testng.annotations.BeforeClass; -import org.testng.annotations.BeforeMethod; -import org.testng.annotations.Test; -import org.wso2.carbon.identity.common.testng.WithCarbonHome; -import org.wso2.carbon.user.core.UserStoreException; -import org.wso2.carbon.user.core.UserStoreManager; -import org.wso2.carbon.user.core.model.UserClaimSearchEntry; - -import java.util.Collections; -import java.util.HashMap; -import java.util.Map; -import java.util.Optional; - -import static org.mockito.ArgumentMatchers.any; -import static org.mockito.ArgumentMatchers.anyString; -import static org.mockito.ArgumentMatchers.eq; -import static org.mockito.Mockito.mockStatic; -import static org.mockito.Mockito.when; - -/** - * Unit test cases for PasswordExpiryEventListener. - */ -@WithCarbonHome -public class PasswordExpiryEventListenerTest { - - private static final String TENANT_DOMAIN = "test.com"; - private PasswordExpiryEventListener passwordExpiryEventListener; - - @Mock - PrivilegedCarbonContext privilegedCarbonContext; - @Mock - UserStoreManager userStoreManager; - - private MockedStatic mockedPrivilegedCarbonContext; - private MockedStatic mockedPasswordPolicyUtils; - - @BeforeMethod - public void setUp() { - - MockitoAnnotations.openMocks(this); - passwordExpiryEventListener = new PasswordExpiryEventListener(); - - mockedPrivilegedCarbonContext.when(PrivilegedCarbonContext::getThreadLocalCarbonContext) - .thenReturn(privilegedCarbonContext); - - when(privilegedCarbonContext.getTenantDomain()).thenReturn(TENANT_DOMAIN); - } - - @BeforeClass - public void init() { - - mockedPrivilegedCarbonContext = mockStatic(PrivilegedCarbonContext.class); - mockedPasswordPolicyUtils = mockStatic(PasswordPolicyUtils.class); - } - - @AfterClass - public void close() { - - mockedPrivilegedCarbonContext.close(); - mockedPasswordPolicyUtils.close(); - } - - @Test - public void testGetExecutionOrderId() { - - Assert.assertEquals(passwordExpiryEventListener.getExecutionOrderId(), 102); - } - - @Test - public void testDoPostGetUserClaimValuesWithPasswordExpiryClaim() throws UserStoreException { - - String username = "testUser"; - String[] claims; - Map claimMap = new HashMap<>(); - String profileName = "default"; - - // Case 1: When claims contains PASSWORD_EXPIRY_TIME_CLAIM. - claims = new String[]{PasswordPolicyConstants.PASSWORD_EXPIRY_TIME_CLAIM}; - - mockedPasswordPolicyUtils.when(() -> PasswordPolicyUtils.getUserPasswordExpiryTime( - eq(TENANT_DOMAIN), eq(username))).thenReturn(Optional.of(1000L)); - - passwordExpiryEventListener.doPostGetUserClaimValues(username, claims, profileName, claimMap, userStoreManager); - Assert.assertNotNull(claimMap.get(PasswordPolicyConstants.PASSWORD_EXPIRY_TIME_CLAIM)); - - // Case 2: PostAuthenticationFailedException is thrown. - mockedPasswordPolicyUtils.when(() -> - PasswordPolicyUtils.getUserPasswordExpiryTime(eq(TENANT_DOMAIN), eq(username))) - .thenThrow(new ExpiredPasswordIdentificationException("test-error", "test-error")); - try { - passwordExpiryEventListener.doPostGetUserClaimValues(username, claims, profileName, claimMap, userStoreManager); - } catch (Exception e) { - Assert.assertTrue(e instanceof UserStoreException); - } - } - - @Test - public void testDoPostGetUserClaimValuesWithoutPasswordExpiryClaim() throws UserStoreException { - - String username = "testUser"; - String[] claims; - Map claimMap = new HashMap<>(); - String profileName = "default"; - claims = new String[]{"claim1", "claim2"}; - - passwordExpiryEventListener.doPostGetUserClaimValues(username, claims, profileName, claimMap, userStoreManager); - Assert.assertFalse(claimMap.containsKey(PasswordPolicyConstants.PASSWORD_EXPIRY_TIME_CLAIM)); - } - - @Test - public void testDoPostGetUsersClaimValuesWithPasswordExpiryClaim() throws UserStoreException { - - String[] userNames = new String[]{"testUser1", "testUser2"}; - String[] claims = new String[]{PasswordPolicyConstants.PASSWORD_EXPIRY_TIME_CLAIM}; - String profileName = "default"; - - UserClaimSearchEntry[] userClaimSearchEntries = new UserClaimSearchEntry[2]; - userClaimSearchEntries[0] = new UserClaimSearchEntry(); - userClaimSearchEntries[0].setUserName("testUser1"); - userClaimSearchEntries[1] = new UserClaimSearchEntry(); - userClaimSearchEntries[1].setUserName("testUser1"); - - mockedPasswordPolicyUtils.when(() -> - PasswordPolicyUtils.isPasswordExpiryEnabled(TENANT_DOMAIN)).thenReturn(true); - mockedPasswordPolicyUtils.when(() -> - PasswordPolicyUtils.isSkipIfNoApplicableRulesEnabled(TENANT_DOMAIN)).thenReturn(false); - mockedPasswordPolicyUtils.when(() -> - PasswordPolicyUtils.getPasswordExpiryInDays(TENANT_DOMAIN)).thenReturn(30); - mockedPasswordPolicyUtils.when(() -> - PasswordPolicyUtils.getPasswordExpiryRules(TENANT_DOMAIN)).thenReturn(Collections.emptyList()); - mockedPasswordPolicyUtils.when(() -> PasswordPolicyUtils.getUserPasswordExpiryTime( - eq(TENANT_DOMAIN), anyString(), eq(true), eq(false), any(), eq(30))) - .thenReturn(Optional.of(1000L)); - - passwordExpiryEventListener.doPostGetUsersClaimValues(userNames, claims, profileName, userClaimSearchEntries); - Assert.assertNotNull( - userClaimSearchEntries[0].getClaims().get(PasswordPolicyConstants.PASSWORD_EXPIRY_TIME_CLAIM)); - Assert.assertNotNull( - userClaimSearchEntries[1].getClaims().get(PasswordPolicyConstants.PASSWORD_EXPIRY_TIME_CLAIM)); - - // Case 2: PostAuthenticationFailedException is thrown. - mockedPasswordPolicyUtils.when(() -> PasswordPolicyUtils.getUserPasswordExpiryTime( - eq(TENANT_DOMAIN), anyString(), eq(true), eq(false), any(), eq(30))) - .thenThrow(new ExpiredPasswordIdentificationException("test-error", "test-error")); - try { - passwordExpiryEventListener.doPostGetUsersClaimValues(userNames, claims, - profileName, userClaimSearchEntries); - } catch (Exception e) { - Assert.assertTrue(e instanceof UserStoreException); - } - } - - @Test - public void testDoPostGetUsersClaimValuesWithoutPasswordExpiryClaims() throws UserStoreException { - - String[] userNames = new String[]{"testUser1", "testUser2"}; - String[] claims = new String[]{"claim1", "claim2"}; - String profileName = "default"; - - UserClaimSearchEntry[] userClaimSearchEntries = new UserClaimSearchEntry[2]; - userClaimSearchEntries[0] = new UserClaimSearchEntry(); - userClaimSearchEntries[0].setUserName("testUser1"); - userClaimSearchEntries[1] = new UserClaimSearchEntry(); - userClaimSearchEntries[1].setUserName("testUser1"); - - passwordExpiryEventListener.doPostGetUsersClaimValues(userNames, claims, profileName, userClaimSearchEntries); - Assert.assertNull(userClaimSearchEntries[0].getClaims()); - Assert.assertNull(userClaimSearchEntries[1].getClaims()); - } -} diff --git a/components/org.wso2.carbon.identity.password.expiry/src/test/resources/testng.xml b/components/org.wso2.carbon.identity.password.expiry/src/test/resources/testng.xml index ed19db6cef..2aac16e379 100644 --- a/components/org.wso2.carbon.identity.password.expiry/src/test/resources/testng.xml +++ b/components/org.wso2.carbon.identity.password.expiry/src/test/resources/testng.xml @@ -14,7 +14,6 @@ -