Skip to content

Commit

Permalink
Enable disable feature by checking claim mapping existence.
Browse files Browse the repository at this point in the history
  • Loading branch information
PasinduYeshan committed Oct 29, 2024
1 parent a1eca1e commit cbbd23e
Show file tree
Hide file tree
Showing 8 changed files with 186 additions and 29 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,8 @@ public void handleEvent(Event event) throws IdentityEventException {
claims = new HashMap<>();
}

boolean supportMultipleMobileNumbers = Utils.isMultiEmailsAndMobileNumbersPerUserEnabled();
boolean supportMultipleMobileNumbers =
Utils.isMultiEmailsAndMobileNumbersPerUserEnabled(user.getTenantDomain(), user.getUserStoreDomain());

boolean enable = isMobileVerificationOnUpdateEnabled(user.getTenantDomain());

Expand Down Expand Up @@ -326,7 +327,8 @@ private void preSetUserClaimOnMobileNumberUpdate(Map<String, String> claims, Use
Utils.unsetThreadLocalToSkipSendingSmsOtpVerificationOnUpdate();
}

boolean supportMultipleMobileNumbers = Utils.isMultiEmailsAndMobileNumbersPerUserEnabled();
boolean supportMultipleMobileNumbers =
Utils.isMultiEmailsAndMobileNumbersPerUserEnabled(user.getTenantDomain(), user.getUserStoreDomain());
String multiAttributeSeparator = FrameworkUtils.getMultiAttributeSeparator();

String mobileNumber = claims.get(IdentityRecoveryConstants.MOBILE_NUMBER_CLAIM);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,8 @@ public void handleEvent(Event event) throws IdentityEventException {
claims = new HashMap<>();
}

boolean supportMultipleEmails = Utils.isMultiEmailsAndMobileNumbersPerUserEnabled();
boolean supportMultipleEmails =
Utils.isMultiEmailsAndMobileNumbersPerUserEnabled(user.getTenantDomain(), user.getUserStoreDomain());

boolean enable = false;

Expand Down Expand Up @@ -568,7 +569,8 @@ private void preSetUserClaimsOnEmailUpdate(Map<String, String> claims, UserStore
Utils.unsetThreadLocalToSkipSendingEmailVerificationOnUpdate();
}

boolean supportMultipleEmails = Utils.isMultiEmailsAndMobileNumbersPerUserEnabled();
boolean supportMultipleEmails =
Utils.isMultiEmailsAndMobileNumbersPerUserEnabled(user.getTenantDomain(), user.getUserStoreDomain());
String multiAttributeSeparator = FrameworkUtils.getMultiAttributeSeparator();

String emailAddress = claims.get(IdentityRecoveryConstants.EMAIL_ADDRESS_CLAIM);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -768,7 +768,8 @@ private UserRecoveryData validateSelfRegistrationCode(String code, String verifi
HashMap<String, String> userClaims = getClaimsListToUpdate(user, verifiedChannelType,
externallyVerifiedClaim, recoveryData.getRecoveryScenario().toString());

boolean supportMultipleEmailsAndMobileNumbers = Utils.isMultiEmailsAndMobileNumbersPerUserEnabled();
boolean supportMultipleEmailsAndMobileNumbers =
Utils.isMultiEmailsAndMobileNumbersPerUserEnabled(user.getTenantDomain(), user.getUserStoreDomain());
String multiAttributeSeparator = FrameworkUtils.getMultiAttributeSeparator();

if (RecoverySteps.VERIFY_EMAIL.equals(recoveryData.getRecoveryStep())) {
Expand Down Expand Up @@ -990,7 +991,8 @@ public void confirmVerificationCodeMe(String code, Map<String, String> propertie
UserStoreManager userStoreManager = getUserStoreManager(user);
HashMap<String, String> userClaims = new HashMap<>();

boolean supportMultipleEmailsAndMobileNumbers = Utils.isMultiEmailsAndMobileNumbersPerUserEnabled();
boolean supportMultipleEmailsAndMobileNumbers =
Utils.isMultiEmailsAndMobileNumbersPerUserEnabled(user.getTenantDomain(), user.getUserStoreDomain());

String pendingMobileNumberClaimValue = recoveryData.getRemainingSetIds();
if (StringUtils.isNotBlank(pendingMobileNumberClaimValue)) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,9 @@
import org.wso2.carbon.identity.auth.attribute.handler.model.ValidationResult;
import org.wso2.carbon.identity.base.IdentityException;
import org.wso2.carbon.identity.central.log.mgt.utils.LoggerUtils;
import org.wso2.carbon.identity.claim.metadata.mgt.exception.ClaimMetadataException;
import org.wso2.carbon.identity.claim.metadata.mgt.model.LocalClaim;
import org.wso2.carbon.identity.claim.metadata.mgt.util.ClaimConstants;
import org.wso2.carbon.identity.core.util.IdentityTenantUtil;
import org.wso2.carbon.identity.core.util.IdentityUtil;
import org.wso2.carbon.identity.event.IdentityEventConstants;
Expand Down Expand Up @@ -1393,14 +1396,56 @@ public static boolean isUseVerifyClaimEnabled() {
}

/**
* Check whether the supporting multiple email addresses and mobile numbers per user is enabled.
* Check whether the supporting multiple email addresses and mobile numbers per user feature is enabled.
*
* @param tenantDomain Tenant domain.
* @param userStoreDomain User store domain.
* @return True if the config is set to true, false otherwise.
*/
public static boolean isMultiEmailsAndMobileNumbersPerUserEnabled() {
public static boolean isMultiEmailsAndMobileNumbersPerUserEnabled(String tenantDomain, String userStoreDomain) {

return Boolean.parseBoolean(IdentityUtil.getProperty(
IdentityRecoveryConstants.ConnectorConfig.SUPPORT_MULTI_EMAILS_AND_MOBILE_NUMBERS_PER_USER));
if (!Boolean.parseBoolean(IdentityUtil.getProperty(
IdentityRecoveryConstants.ConnectorConfig.SUPPORT_MULTI_EMAILS_AND_MOBILE_NUMBERS_PER_USER))) {
return false;
}

try {
List<LocalClaim> localClaims =
IdentityRecoveryServiceDataHolder.getInstance().getClaimMetadataManagementService()
.getLocalClaims(tenantDomain);

List<String> claimURIsToCheck = Arrays.asList(
IdentityRecoveryConstants.VERIFIED_MOBILE_NUMBERS_CLAIM,
IdentityRecoveryConstants.MOBILE_NUMBERS_CLAIM,
IdentityRecoveryConstants.EMAIL_ADDRESSES_CLAIM,
IdentityRecoveryConstants.VERIFIED_EMAIL_ADDRESSES_CLAIM);

for (String claimUri : claimURIsToCheck) {
boolean isValidClaim = localClaims.stream()
.filter(claim -> claimUri.equals(claim.getClaimURI()))
.anyMatch(claim -> {
// Check if claim is supported by default.
Map<String, String> claimProperties = claim.getClaimProperties();
boolean isSupportedByDefault = Boolean.parseBoolean(
claimProperties.getOrDefault(
ClaimConstants.SUPPORTED_BY_DEFAULT_PROPERTY, Boolean.FALSE.toString()));

boolean hasValidMapping = StringUtils.isNotBlank(claim.getMappedAttribute(userStoreDomain));

// Return true only if both conditions are met
return isSupportedByDefault && hasValidMapping;

});

if (!isValidClaim) {
return false;
}
}
return true;
} catch (ClaimMetadataException e) {
log.error("Error while retrieving multiple emails and mobiles config.", e);
return false;
}
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -575,8 +575,8 @@ private static Map<String, String> getUserClaimsFromEvent(Event event2) {
private void mockUtilMethods(boolean mobileVerificationEnabled, boolean multiAttributeEnabled,
boolean useVerifyClaimEnabled) {

mockedUtils.when(
Utils::isMultiEmailsAndMobileNumbersPerUserEnabled).thenReturn(multiAttributeEnabled);
mockedUtils.when(() -> Utils.isMultiEmailsAndMobileNumbersPerUserEnabled(anyString(), anyString()))
.thenReturn(multiAttributeEnabled);
mockedUtils.when(Utils::isUseVerifyClaimEnabled).thenReturn(useVerifyClaimEnabled);
mockedUtils.when(() -> Utils.getConnectorConfig(
eq(IdentityRecoveryConstants.ConnectorConfig.ENABLE_MOBILE_NUM_VERIFICATION_ON_UPDATE),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -762,8 +762,8 @@ private void mockPendingVerificationEmail(String pendingEmail) throws UserStoreE
private void mockUtilMethods(boolean emailVerificationEnabled, boolean multiAttributeEnabled,
boolean userVerifyClaimEnabled, boolean notificationOnEmailUpdate) {

mockedUtils.when(
Utils::isMultiEmailsAndMobileNumbersPerUserEnabled).thenReturn(multiAttributeEnabled);
mockedUtils.when(() -> Utils.isMultiEmailsAndMobileNumbersPerUserEnabled(anyString(), anyString()))
.thenReturn(multiAttributeEnabled);
mockedUtils.when(Utils::isUseVerifyClaimEnabled).thenReturn(userVerifyClaimEnabled);
mockGetConnectorConfig(IdentityRecoveryConstants.ConnectorConfig.ENABLE_EMAIL_VERIFICATION_ON_UPDATE,
emailVerificationEnabled);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,10 @@
import org.wso2.carbon.identity.auth.attribute.handler.exception.AuthAttributeHandlerException;
import org.wso2.carbon.identity.auth.attribute.handler.model.ValidationResult;
import org.wso2.carbon.identity.base.IdentityException;
import org.wso2.carbon.identity.claim.metadata.mgt.ClaimMetadataManagementService;
import org.wso2.carbon.identity.claim.metadata.mgt.exception.ClaimMetadataException;
import org.wso2.carbon.identity.claim.metadata.mgt.model.AttributeMapping;
import org.wso2.carbon.identity.claim.metadata.mgt.model.LocalClaim;
import org.wso2.carbon.identity.common.testng.WithCarbonHome;
import org.wso2.carbon.identity.consent.mgt.services.ConsentUtilityService;
import org.wso2.carbon.identity.core.util.IdentityTenantUtil;
Expand Down Expand Up @@ -97,9 +101,11 @@
import org.wso2.carbon.utils.multitenancy.MultitenantUtils;

import java.sql.Timestamp;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;

import static org.mockito.ArgumentMatchers.any;
Expand All @@ -111,6 +117,7 @@
import static org.mockito.ArgumentMatchers.isNull;
import static org.mockito.Mockito.atLeastOnce;
import static org.mockito.Mockito.doNothing;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.doThrow;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.mockStatic;
Expand Down Expand Up @@ -627,7 +634,7 @@ public void testAttributeVerificationFailures(String scenario, Property[] proper

@Test
public void testConfirmVerificationCodeMe()
throws IdentityRecoveryException, UserStoreException {
throws IdentityRecoveryException, UserStoreException, ClaimMetadataException {

// Case 1: Multiple email and mobile per user is enabled.
String verificationPendingMobileNumber = "0700000000";
Expand Down Expand Up @@ -691,7 +698,7 @@ public void testConfirmVerificationCodeMe()

@Test
public void testConfirmVerificationCodeMeVerificationOnVerifiedListUpdate()
throws IdentityRecoveryException, UserStoreException {
throws IdentityRecoveryException, UserStoreException, ClaimMetadataException {

// Case 1: Recovery Scenario - MOBILE_VERIFICATION_ON_VERIFIED_LIST_UPDATE.
String verificationPendingMobileNumber = "0700000000";
Expand Down Expand Up @@ -736,7 +743,7 @@ public void testConfirmVerificationCodeMeVerificationOnVerifiedListUpdate()

@Test(expectedExceptions = IdentityRecoveryServerException.class)
public void testConfirmVerificationCodeMeUserStoreException()
throws IdentityRecoveryException, UserStoreException {
throws IdentityRecoveryException, UserStoreException, ClaimMetadataException {

// Case 3: Throws user store exception while getting user claim values.
String verificationPendingMobileNumber = "0700000000";
Expand All @@ -758,7 +765,7 @@ public void testConfirmVerificationCodeMeUserStoreException()

@Test
public void testGetConfirmedSelfRegisteredUserVerifyEmail()
throws IdentityRecoveryException, UserStoreException, IdentityGovernanceException {
throws IdentityRecoveryException, UserStoreException, IdentityGovernanceException, ClaimMetadataException {

String verifiedChannelType = NotificationChannels.EMAIL_CHANNEL.getChannelType();
String verifiedChannelClaim = "http://wso2.org/claims/emailaddress";
Expand Down Expand Up @@ -859,7 +866,8 @@ public void testGetConfirmedSelfRegisteredUserVerifyMobile()
when(identityGovernanceService.getConfiguration(any(), anyString())).thenReturn(testProperties);

try (MockedStatic<Utils> mockedUtils = mockStatic(Utils.class)) {
mockedUtils.when(Utils::isMultiEmailsAndMobileNumbersPerUserEnabled).thenReturn(true);
mockedUtils.when(() -> Utils.isMultiEmailsAndMobileNumbersPerUserEnabled(anyString(), anyString()))
.thenReturn(true);
mockedUtils.when(() -> Utils.getConnectorConfig(
eq(IdentityRecoveryConstants.ConnectorConfig.ENABLE_MOBILE_VERIFICATION_BY_PRIVILEGED_USER),
anyString()))
Expand Down Expand Up @@ -889,7 +897,8 @@ public void testGetConfirmedSelfRegisteredUserVerifyMobile()
// Case 2: External Verified Channel type.
verifiedChannelType = NotificationChannels.EXTERNAL_CHANNEL.getChannelType();
try (MockedStatic<Utils> mockedUtils = mockStatic(Utils.class)) {
mockedUtils.when(Utils::isMultiEmailsAndMobileNumbersPerUserEnabled).thenReturn(true);
mockedUtils.when(() -> Utils.isMultiEmailsAndMobileNumbersPerUserEnabled(anyString(), anyString()))
.thenReturn(true);
mockedUtils.when(() -> Utils.getConnectorConfig(
eq(IdentityRecoveryConstants.ConnectorConfig.ENABLE_MOBILE_VERIFICATION_BY_PRIVILEGED_USER),
anyString()))
Expand All @@ -911,7 +920,8 @@ public void testGetConfirmedSelfRegisteredUserVerifyMobile()

// Case 3: Throws user store exception while getting user claim values.
try (MockedStatic<Utils> mockedUtils = mockStatic(Utils.class)) {
mockedUtils.when(Utils::isMultiEmailsAndMobileNumbersPerUserEnabled).thenReturn(true);
mockedUtils.when(() -> Utils.isMultiEmailsAndMobileNumbersPerUserEnabled(anyString(), anyString()))
.thenReturn(true);
mockedUtils.when(() -> Utils.getConnectorConfig(
eq(IdentityRecoveryConstants.ConnectorConfig.ENABLE_MOBILE_VERIFICATION_BY_PRIVILEGED_USER),
anyString()))
Expand All @@ -935,7 +945,8 @@ public void testGetConfirmedSelfRegisteredUserVerifyMobile()
verifiedChannelType = NotificationChannels.SMS_CHANNEL.getChannelType();
verifiedChannelClaim = "http://wso2.org/claims/invalid";
try (MockedStatic<Utils> mockedUtils = mockStatic(Utils.class)) {
mockedUtils.when(Utils::isMultiEmailsAndMobileNumbersPerUserEnabled).thenReturn(true);
mockedUtils.when(() -> Utils.isMultiEmailsAndMobileNumbersPerUserEnabled(anyString(), anyString()))
.thenReturn(true);
mockedUtils.when(() -> Utils.getConnectorConfig(
eq(IdentityRecoveryConstants.ConnectorConfig.ENABLE_MOBILE_VERIFICATION_BY_PRIVILEGED_USER),
anyString()))
Expand All @@ -952,7 +963,7 @@ public void testGetConfirmedSelfRegisteredUserVerifyMobile()

@Test
public void testGetConfirmedSelfRegisteredUserConfirmSignUp()
throws IdentityRecoveryException, UserStoreException, IdentityGovernanceException {
throws IdentityRecoveryException, UserStoreException, IdentityGovernanceException, ClaimMetadataException {

String verifiedChannelType = NotificationChannels.EMAIL_CHANNEL.getChannelType();
String verifiedChannelClaim = "http://wso2.org/claims/emailaddress";
Expand Down Expand Up @@ -1562,11 +1573,43 @@ private User getUser() {
return user;
}

private void mockMultiAttributeEnabled(Boolean isEnabled) {
private void mockMultiAttributeEnabled(Boolean isEnabled) throws ClaimMetadataException {

mockedIdentityUtil.when(() -> IdentityUtil.getProperty(
eq(IdentityRecoveryConstants.ConnectorConfig.SUPPORT_MULTI_EMAILS_AND_MOBILE_NUMBERS_PER_USER)))
.thenReturn(isEnabled.toString());
if (!isEnabled) return;
// Mock ClaimMetadataManagementService.
ClaimMetadataManagementService claimMetadataManagementService = mock(ClaimMetadataManagementService.class);
when(identityRecoveryServiceDataHolder.getClaimMetadataManagementService())
.thenReturn(claimMetadataManagementService);

List<LocalClaim> localClaims = new ArrayList<>();

// Add claims with valid mappings.
LocalClaim mobileNumbersClaim = new LocalClaim(IdentityRecoveryConstants.MOBILE_NUMBERS_CLAIM);
mobileNumbersClaim.setMappedAttributes(
Arrays.asList(new AttributeMapping(TEST_USERSTORE_DOMAIN, "mobileNumbers")));

LocalClaim verifiedMobileNumbersClaim = new LocalClaim(IdentityRecoveryConstants.VERIFIED_MOBILE_NUMBERS_CLAIM);
verifiedMobileNumbersClaim.setMappedAttributes(
Arrays.asList(new AttributeMapping(TEST_USERSTORE_DOMAIN, "verifiedMobileNumbers")));

LocalClaim emailAddressesClaim = new LocalClaim(IdentityRecoveryConstants.EMAIL_ADDRESSES_CLAIM);
emailAddressesClaim.setMappedAttributes(
Arrays.asList(new AttributeMapping(TEST_USERSTORE_DOMAIN, "emailAddresses")));

LocalClaim verifiedEmailAddressesClaim =
new LocalClaim(IdentityRecoveryConstants.VERIFIED_EMAIL_ADDRESSES_CLAIM);
verifiedEmailAddressesClaim.setMappedAttributes(
Arrays.asList(new AttributeMapping(TEST_USERSTORE_DOMAIN, "verifiedEmailAddresses")));

localClaims.add(verifiedMobileNumbersClaim);
localClaims.add(mobileNumbersClaim);
localClaims.add(emailAddressesClaim);
localClaims.add(verifiedEmailAddressesClaim);

doReturn(localClaims).when(claimMetadataManagementService).getLocalClaims(TEST_TENANT_DOMAIN_NAME);
}

private void mockGetUserClaimValue(String claimUri, String claimValue) throws UserStoreException {
Expand Down
Loading

0 comments on commit cbbd23e

Please sign in to comment.