From e271a0daaec8eddb3e74c9f0d175acd4eef2bbed Mon Sep 17 00:00:00 2001 From: Afra Hussaindeen Date: Tue, 3 Dec 2024 21:05:09 +0530 Subject: [PATCH] Relocate the logic for updating uniqueness validation properties to the service layer --- .../ClaimMetadataManagementServiceImpl.java | 91 +++++- .../claim/metadata/mgt/dao/ClaimDAO.java | 32 -- .../claim/metadata/mgt/dao/LocalClaimDAO.java | 100 +----- .../claim/metadata/mgt/util/SQLConstants.java | 1 - ...laimMetadataManagementServiceImplTest.java | 218 ++++++++++++- .../metadata/mgt/dao/LocalClaimDAOTest.java | 305 ------------------ 6 files changed, 301 insertions(+), 446 deletions(-) diff --git a/components/claim-mgt/org.wso2.carbon.identity.claim.metadata.mgt/src/main/java/org/wso2/carbon/identity/claim/metadata/mgt/ClaimMetadataManagementServiceImpl.java b/components/claim-mgt/org.wso2.carbon.identity.claim.metadata.mgt/src/main/java/org/wso2/carbon/identity/claim/metadata/mgt/ClaimMetadataManagementServiceImpl.java index 6ebb035f8b95..b878b68914ef 100644 --- a/components/claim-mgt/org.wso2.carbon.identity.claim.metadata.mgt/src/main/java/org/wso2/carbon/identity/claim/metadata/mgt/ClaimMetadataManagementServiceImpl.java +++ b/components/claim-mgt/org.wso2.carbon.identity.claim.metadata.mgt/src/main/java/org/wso2/carbon/identity/claim/metadata/mgt/ClaimMetadataManagementServiceImpl.java @@ -42,6 +42,7 @@ import java.util.Collection; import java.util.List; import java.util.Map; +import java.util.Optional; import java.util.Set; import java.util.stream.Collectors; @@ -67,6 +68,7 @@ import static org.wso2.carbon.identity.claim.metadata.mgt.util.ClaimConstants.ErrorMessage.ERROR_CODE_NON_EXISTING_EXTERNAL_CLAIM_URI; import static org.wso2.carbon.identity.claim.metadata.mgt.util.ClaimConstants.ErrorMessage.ERROR_CODE_NON_EXISTING_LOCAL_CLAIM; import static org.wso2.carbon.identity.claim.metadata.mgt.util.ClaimConstants.ErrorMessage.ERROR_CODE_NON_EXISTING_LOCAL_CLAIM_URI; +import static org.wso2.carbon.identity.claim.metadata.mgt.util.ClaimMetadataUtils.getServerLevelClaimUniquenessScope; /** * Default implementation of {@link org.wso2.carbon.identity.claim.metadata.mgt.ClaimMetadataManagementService} @@ -212,6 +214,8 @@ public void addLocalClaim(LocalClaim localClaim, String tenantDomain) throws Cla String.format(ERROR_CODE_EXISTING_LOCAL_CLAIM_URI.getMessage(), localClaim.getClaimURI())); } + validateAndSyncUniquenessClaimProperties(localClaim.getClaimProperties(), null); + ClaimMetadataEventPublisherProxy.getInstance().publishPreAddLocalClaim(tenantId, localClaim); this.unifiedClaimMetadataManager.addLocalClaim(localClaim, tenantId); @@ -236,11 +240,15 @@ public void updateLocalClaim(LocalClaim localClaim, String tenantDomain) throws // TODO : validate tenant domain? int tenantId = IdentityTenantUtil.getTenantId(tenantDomain); - if (!isExistingLocalClaim(localClaim.getClaimURI(), tenantId)) { + Optional existingLocalClaim = getLocalClaim(localClaim.getClaimURI(), tenantId); + if (!existingLocalClaim.isPresent()) { throw new ClaimMetadataClientException(ERROR_CODE_NON_EXISTING_LOCAL_CLAIM.getCode(), String.format(ERROR_CODE_NON_EXISTING_LOCAL_CLAIM.getMessage(), localClaim.getClaimURI())); } + validateAndSyncUniquenessClaimProperties(localClaim.getClaimProperties(), + existingLocalClaim.get().getClaimProperties()); + ClaimMetadataEventPublisherProxy.getInstance().publishPreUpdateLocalClaim(tenantId, localClaim); this.unifiedClaimMetadataManager.updateLocalClaim(localClaim, tenantId); @@ -595,6 +603,11 @@ private boolean isExistingLocalClaim(String localClaimURI, int tenantId) throws claim -> claim.getClaimURI().equalsIgnoreCase(localClaimURI)); } + private Optional getLocalClaim(String localClaimURI, int tenantId) throws ClaimMetadataException { + + return this.unifiedClaimMetadataManager.getLocalClaim(localClaimURI, tenantId); + } + @Override public List getMappedExternalClaimsForLocalClaim(String localClaimURI, String tenantDomain) throws ClaimMetadataException { @@ -603,4 +616,80 @@ public List getMappedExternalClaimsForLocalClaim(String localClaimURI, St return this.unifiedClaimMetadataManager.getMappedExternalClaims(localClaimURI, tenantId); } + /** + * Updates and synchronizes the claim uniqueness properties in the properties map. + * Manages the relationship between the legacy 'isUnique' property and the newer 'UniquenessScope' property, + * ensuring consistency between both properties based on their values. + * + * @param claimProperties Map of claim properties to be updated. + * @param existingClaimProperties Map of existing claim properties (null for new claims). + */ + private void validateAndSyncUniquenessClaimProperties(Map claimProperties, + Map existingClaimProperties) { + + // Case 1: If the 'isUnique' property is not provided, + // no property synchronization is needed. + if (!claimProperties.containsKey(ClaimConstants.IS_UNIQUE_CLAIM_PROPERTY)) { + return; + } + + String newUniquenessScopeValue = claimProperties.get(ClaimConstants.CLAIM_UNIQUENESS_SCOPE_PROPERTY); + String newIsUniqueValue = claimProperties.get(ClaimConstants.IS_UNIQUE_CLAIM_PROPERTY); + + // Case 2: If only the 'isUnique' property is provided, + // set the 'UniquenessScope' property based on the 'isUnique' value. + if (!claimProperties.containsKey(ClaimConstants.CLAIM_UNIQUENESS_SCOPE_PROPERTY)) { + updateScopeFromIsUnique(claimProperties, newIsUniqueValue); + return; + } + + // Case 3: If both 'isUnique' and 'UniquenessScope' properties are provided. + if (existingClaimProperties == null) { + // If there are no existing claim properties (i.e., this is a new claim), + // prioritize 'UniquenessScope' & update the 'isUnique' property accordingly. + updateIsUniqueFromScope(claimProperties, newUniquenessScopeValue); + return; + } + + String existingScopeValue = existingClaimProperties.get(ClaimConstants.CLAIM_UNIQUENESS_SCOPE_PROPERTY); + String existingIsUniqueValue = existingClaimProperties.get(ClaimConstants.IS_UNIQUE_CLAIM_PROPERTY); + + boolean isScopeChanged = !StringUtils.equals(newUniquenessScopeValue, existingScopeValue); + boolean isUniqueChanged = !StringUtils.equalsIgnoreCase(newIsUniqueValue, existingIsUniqueValue); + + if (isScopeChanged) { + // If 'UniquenessScope' has changed (regardless of 'isUnique' changes), prioritize 'UniquenessScope'. + updateIsUniqueFromScope(claimProperties, newUniquenessScopeValue); + } else if (isUniqueChanged) { + // If only 'isUnique' has changed, update 'UniquenessScope' based on the new 'isUnique' value. + updateScopeFromIsUnique(claimProperties, newIsUniqueValue); + } + } + + /** + * Updates the uniqueness scope property based on the isUnique value. + * + * @param properties Map of claim properties to update. + * @param isUniqueValue String value of isUnique property ("true" or "false"). + */ + private void updateScopeFromIsUnique(Map properties, String isUniqueValue) { + + boolean isUnique = Boolean.parseBoolean(isUniqueValue); + properties.put(ClaimConstants.CLAIM_UNIQUENESS_SCOPE_PROPERTY, + isUnique ? getServerLevelClaimUniquenessScope().toString() : + ClaimConstants.ClaimUniquenessScope.NONE.toString()); + } + + /** + * Updates the isUnique property based on the uniqueness scope value. + * + * @param properties Map of claim properties to update. + * @param scopeValue String value of the uniqueness scope. + */ + private void updateIsUniqueFromScope(Map properties, String scopeValue) { + + boolean isUnique = !ClaimConstants.ClaimUniquenessScope.NONE.toString().equals(scopeValue); + properties.put(ClaimConstants.IS_UNIQUE_CLAIM_PROPERTY, String.valueOf(isUnique)); + } + } diff --git a/components/claim-mgt/org.wso2.carbon.identity.claim.metadata.mgt/src/main/java/org/wso2/carbon/identity/claim/metadata/mgt/dao/ClaimDAO.java b/components/claim-mgt/org.wso2.carbon.identity.claim.metadata.mgt/src/main/java/org/wso2/carbon/identity/claim/metadata/mgt/dao/ClaimDAO.java index d9731f8a5674..34f799c1d829 100644 --- a/components/claim-mgt/org.wso2.carbon.identity.claim.metadata.mgt/src/main/java/org/wso2/carbon/identity/claim/metadata/mgt/dao/ClaimDAO.java +++ b/components/claim-mgt/org.wso2.carbon.identity.claim.metadata.mgt/src/main/java/org/wso2/carbon/identity/claim/metadata/mgt/dao/ClaimDAO.java @@ -261,36 +261,4 @@ public int getIdOfClaim(Connection connection, String claimDialectURI, String cl } return claimId; } - - /** - * Retrieves claim properties for a given claim ID from the database. - * - * @param connection Database connection to use for the query. - * @param claimId ID of the claim whose properties are to be retrieved. - * @param tenantId ID of the tenant. - * @return Map containing property name-value pairs for the claim. - * @throws ClaimMetadataException If an error occurs while retrieving the claim properties. - */ - public Map getClaimPropertiesById(Connection connection, int claimId, int tenantId) - throws ClaimMetadataException { - - Map claimProperties = new HashMap<>(); - - try (PreparedStatement prepStmt = connection.prepareStatement(SQLConstants.GET_CLAIM_PROPERTIES_BY_ID)) { - prepStmt.setInt(1, claimId); - prepStmt.setInt(2, tenantId); - - try (ResultSet rs = prepStmt.executeQuery()) { - while (rs.next()) { - String propertyName = rs.getString(SQLConstants.PROPERTY_NAME_COLUMN); - String propertyValue = rs.getString(SQLConstants.PROPERTY_VALUE_COLUMN); - claimProperties.put(propertyName, propertyValue); - } - } - } catch (SQLException e) { - throw new ClaimMetadataException("Error while retrieving claim properties for claim ID: " + claimId, e); - } - - return claimProperties; - } } diff --git a/components/claim-mgt/org.wso2.carbon.identity.claim.metadata.mgt/src/main/java/org/wso2/carbon/identity/claim/metadata/mgt/dao/LocalClaimDAO.java b/components/claim-mgt/org.wso2.carbon.identity.claim.metadata.mgt/src/main/java/org/wso2/carbon/identity/claim/metadata/mgt/dao/LocalClaimDAO.java index 3130e2b29564..aec151c9c70f 100644 --- a/components/claim-mgt/org.wso2.carbon.identity.claim.metadata.mgt/src/main/java/org/wso2/carbon/identity/claim/metadata/mgt/dao/LocalClaimDAO.java +++ b/components/claim-mgt/org.wso2.carbon.identity.claim.metadata.mgt/src/main/java/org/wso2/carbon/identity/claim/metadata/mgt/dao/LocalClaimDAO.java @@ -37,8 +37,6 @@ import java.util.List; import java.util.Map; -import static org.wso2.carbon.identity.claim.metadata.mgt.util.ClaimMetadataUtils.getServerLevelClaimUniquenessScope; - /** * Data access object for org.wso2.carbon.identity.claim.metadata.mgt.model.LocalClaim. */ @@ -67,6 +65,7 @@ public List getLocalClaims(int tenantId) throws ClaimMetadataExcepti List attributeMappingsOfClaim = claimAttributeMappingsOfDialect.get(claimId); Map propertiesOfClaim = claimPropertiesOfDialect.get(claimId); + localClaims.add(new LocalClaim(claim.getClaimURI(), attributeMappingsOfClaim, propertiesOfClaim)); } } finally { @@ -179,9 +178,6 @@ public void addLocalClaim(LocalClaim localClaim, int tenantId) throws ClaimMetad } addClaimAttributeMappings(connection, localClaimId, localClaim.getMappedAttributes(), tenantId); - if (shouldUpdateUniquenessValidationProperty(localClaim.getClaimProperties())) { - updateUniquenessValidationProperty(localClaim.getClaimProperties(), null, -1, -1); - } addClaimProperties(connection, localClaimId, localClaim.getClaimProperties(), tenantId); // End transaction @@ -210,9 +206,6 @@ public void updateLocalClaim(LocalClaim localClaim, int tenantId) throws ClaimMe deleteClaimAttributeMappings(connection, localClaimId, tenantId); addClaimAttributeMappings(connection, localClaimId, localClaim.getMappedAttributes(), tenantId); - if (shouldUpdateUniquenessValidationProperty(localClaim.getClaimProperties())) { - updateUniquenessValidationProperty(localClaim.getClaimProperties(), connection, localClaimId, tenantId); - } deleteClaimProperties(connection, localClaimId, tenantId); addClaimProperties(connection, localClaimId, localClaim.getClaimProperties(), tenantId); @@ -422,95 +415,4 @@ public List fetchMappedExternalClaims(String localClaimURI, int tenantId) throw new ClaimMetadataException("Error while obtaining mapped external claims for local claim.", e); } } - - /** - * Checks if the uniqueness validation property/properties needs to be updated. - * This occurs when the properties map contains the legacy isUnique property - * that needs to be mapped to the new UniquenessScope property. - * - * @param properties Map of claim properties to check. - * @return true if properties contain isUnique property. - */ - private boolean shouldUpdateUniquenessValidationProperty(Map properties) { - - return properties != null && - properties.containsKey(ClaimConstants.IS_UNIQUE_CLAIM_PROPERTY); - } - - /** - * Updates the uniqueness validation property/properties in the properties map. - * Handles the synchronization between legacy isUnique property - * and the new UniquenessScope property if isUnique property is defined. - * - * @param properties Map of claim properties to update. - * @param connection Database connection to use for retrieving existing properties. Can be null for new claims. - * @param localClaimId ID of the local claim. Only required when connection is provided. - * @param tenantId ID of the tenant. Only required when connection is provided. - * @throws ClaimMetadataException If an error occurs while updating the properties. - */ - private void updateUniquenessValidationProperty(Map properties, Connection connection, - int localClaimId, int tenantId) throws ClaimMetadataException { - - String newScopeValue = properties.get(ClaimConstants.CLAIM_UNIQUENESS_SCOPE_PROPERTY); - String newIsUniqueValue = properties.get(ClaimConstants.IS_UNIQUE_CLAIM_PROPERTY); - - boolean hasUniquenessScope = newScopeValue != null; - - // Case 1 : Only isUnique exists. - if (!hasUniquenessScope) { - updateScopeFromIsUnique(properties, newIsUniqueValue); - return; - } - - // Case 2 : Both isUnique & UniquenessScope exists. - if (connection == null) { - // If no database connection is available, use the UniquenessScope property value for uniqueness validation - // and update the isUnique property accordingly. - updateIsUniqueFromScope(properties, newScopeValue); - return; - } - - // Retrieve existing property values from the DB to determine what has changed. - Map existingProperties = getClaimPropertiesById(connection, localClaimId, tenantId); - String existingScopeValue = existingProperties.get(ClaimConstants.CLAIM_UNIQUENESS_SCOPE_PROPERTY); - String existingIsUniqueValue = existingProperties.get(ClaimConstants.IS_UNIQUE_CLAIM_PROPERTY); - - boolean isScopeChanged = !newScopeValue.equals(existingScopeValue); - boolean isUniqueChanged = !newIsUniqueValue.equals(existingIsUniqueValue); - - // If UniquenessScope changed (regardless of isUnique changes), prioritize scope. - if (isScopeChanged) { - updateIsUniqueFromScope(properties, newScopeValue); - } - // If only isUnique changed. - else if (isUniqueChanged) { - updateScopeFromIsUnique(properties, newIsUniqueValue); - } - } - - /** - * Updates the uniqueness scope property based on the isUnique value. - * - * @param properties Map of claim properties to update. - * @param isUniqueValue String value of isUnique property ("true" or "false"). - */ - private void updateScopeFromIsUnique(Map properties, String isUniqueValue) { - - boolean isUnique = Boolean.parseBoolean(isUniqueValue); - properties.put(ClaimConstants.CLAIM_UNIQUENESS_SCOPE_PROPERTY, - isUnique ? getServerLevelClaimUniquenessScope().toString() : - ClaimConstants.ClaimUniquenessScope.NONE.toString()); - } - - /** - * Updates the isUnique property based on the uniqueness scope value. - * - * @param properties Map of claim properties to update. - * @param scopeValue String value of the uniqueness scope. - */ - private void updateIsUniqueFromScope(Map properties, String scopeValue) { - - boolean isUnique = !ClaimConstants.ClaimUniquenessScope.NONE.toString().equals(scopeValue); - properties.put(ClaimConstants.IS_UNIQUE_CLAIM_PROPERTY, String.valueOf(isUnique)); - } } diff --git a/components/claim-mgt/org.wso2.carbon.identity.claim.metadata.mgt/src/main/java/org/wso2/carbon/identity/claim/metadata/mgt/util/SQLConstants.java b/components/claim-mgt/org.wso2.carbon.identity.claim.metadata.mgt/src/main/java/org/wso2/carbon/identity/claim/metadata/mgt/util/SQLConstants.java index 1346be74601a..cc157236520f 100644 --- a/components/claim-mgt/org.wso2.carbon.identity.claim.metadata.mgt/src/main/java/org/wso2/carbon/identity/claim/metadata/mgt/util/SQLConstants.java +++ b/components/claim-mgt/org.wso2.carbon.identity.claim.metadata.mgt/src/main/java/org/wso2/carbon/identity/claim/metadata/mgt/util/SQLConstants.java @@ -90,7 +90,6 @@ private SQLConstants() { "PROPERTY_VALUE, TENANT_ID) VALUES (?, ?, ?, ?)"; public static final String DELETE_CLAIM_PROPERTY = "DELETE FROM IDN_CLAIM_PROPERTY WHERE LOCAL_CLAIM_ID=? AND " + "TENANT_ID=?"; - public static final String GET_CLAIM_PROPERTIES_BY_ID = "SELECT PROPERTY_NAME, PROPERTY_VALUE FROM IDN_CLAIM_PROPERTY WHERE LOCAL_CLAIM_ID=? AND TENANT_ID=?"; public static final String GET_CLAIMS = "SELECT CLAIMS.ID, PROPERTY.PROPERTY_NAME, PROPERTY.PROPERTY_VALUE, " + "CLAIMS.CLAIM_URI, RESOLVED.CLAIM_URI MAPPED_URI FROM IDN_CLAIM CLAIMS " diff --git a/components/claim-mgt/org.wso2.carbon.identity.claim.metadata.mgt/src/test/java/org/wso2/carbon/identity/claim/metadata/mgt/ClaimMetadataManagementServiceImplTest.java b/components/claim-mgt/org.wso2.carbon.identity.claim.metadata.mgt/src/test/java/org/wso2/carbon/identity/claim/metadata/mgt/ClaimMetadataManagementServiceImplTest.java index 4d851de6b99a..f48fa6bf8ad4 100644 --- a/components/claim-mgt/org.wso2.carbon.identity.claim.metadata.mgt/src/test/java/org/wso2/carbon/identity/claim/metadata/mgt/ClaimMetadataManagementServiceImplTest.java +++ b/components/claim-mgt/org.wso2.carbon.identity.claim.metadata.mgt/src/test/java/org/wso2/carbon/identity/claim/metadata/mgt/ClaimMetadataManagementServiceImplTest.java @@ -18,10 +18,12 @@ package org.wso2.carbon.identity.claim.metadata.mgt; +import org.mockito.ArgumentCaptor; import org.mockito.MockedStatic; import org.mockito.Mockito; import org.testng.annotations.AfterMethod; import org.testng.annotations.BeforeMethod; +import org.testng.annotations.DataProvider; import org.testng.annotations.Test; import org.wso2.carbon.identity.claim.metadata.mgt.exception.ClaimMetadataClientException; import org.wso2.carbon.identity.claim.metadata.mgt.exception.ClaimMetadataException; @@ -30,13 +32,17 @@ import org.wso2.carbon.identity.claim.metadata.mgt.model.ClaimDialect; import org.wso2.carbon.identity.claim.metadata.mgt.model.ExternalClaim; 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.common.testng.WithCarbonHome; import org.wso2.carbon.identity.core.util.IdentityTenantUtil; import org.wso2.carbon.identity.core.util.IdentityUtil; import java.util.ArrayList; import java.util.Collections; +import java.util.HashMap; import java.util.List; +import java.util.Map; +import java.util.Optional; import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.anyInt; @@ -46,6 +52,7 @@ import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; +import static org.testng.Assert.assertEquals; import static org.testng.Assert.assertThrows; import static org.wso2.carbon.base.MultitenantConstants.SUPER_TENANT_DOMAIN_NAME; import static org.wso2.carbon.base.MultitenantConstants.SUPER_TENANT_ID; @@ -62,6 +69,8 @@ public class ClaimMetadataManagementServiceImplTest { private static final String EXTERNAL_CLAIM_DIALECT_URI = "https://abc.org"; private static final String EXTERNAL_CLAIM_URI = "test"; private static final String MAPPED_LOCAL_CLAIM_URI = "http://wso2.org/claims/test"; + private static final String PRIMARY_DOMAIN = "PRIMARY"; + private static final String USERNAME_ATTRIBUTE = "username"; private final ExternalClaim externalClaim = new ExternalClaim(EXTERNAL_CLAIM_DIALECT_URI, EXTERNAL_CLAIM_URI, MAPPED_LOCAL_CLAIM_URI); @@ -204,7 +213,7 @@ public void testAddLocalClaim() throws ClaimMetadataException { LocalClaim localClaimToBeAdded = new LocalClaim(LOCAL_CLAIM_1); localClaimToBeAdded.setMappedAttributes(new ArrayList<>()); localClaimToBeAdded.getMappedAttributes() - .add(new AttributeMapping("PRIMARY", "username")); + .add(new AttributeMapping(PRIMARY_DOMAIN, USERNAME_ATTRIBUTE)); when(unifiedClaimMetadataManager.getLocalClaims(anyInt())).thenReturn(new ArrayList<>()); service.addLocalClaim(localClaimToBeAdded, SUPER_TENANT_DOMAIN_NAME); verify(unifiedClaimMetadataManager, times(1)).addLocalClaim(any(), anyInt()); @@ -222,19 +231,20 @@ public void testUpdateLocalClaim() throws ClaimMetadataException { LocalClaim localClaimToBeUpdated = new LocalClaim(LOCAL_CLAIM_1); localClaimToBeUpdated.setMappedAttributes(new ArrayList<>()); localClaimToBeUpdated.getMappedAttributes() - .add(new AttributeMapping("PRIMARY", "user_name")); + .add(new AttributeMapping(PRIMARY_DOMAIN, USERNAME_ATTRIBUTE)); LocalClaim existingLocalClaim = new LocalClaim(LOCAL_CLAIM_1); existingLocalClaim.setMappedAttributes(new ArrayList<>()); existingLocalClaim.getMappedAttributes() - .add(new AttributeMapping("PRIMARY", "username")); + .add(new AttributeMapping(PRIMARY_DOMAIN, USERNAME_ATTRIBUTE)); - when(unifiedClaimMetadataManager.getLocalClaims(SUPER_TENANT_ID)) - .thenReturn(Collections.singletonList(existingLocalClaim)); + when(unifiedClaimMetadataManager.getLocalClaim(LOCAL_CLAIM_1, SUPER_TENANT_ID)) + .thenReturn(Optional.of(existingLocalClaim)); service.updateLocalClaim(localClaimToBeUpdated, SUPER_TENANT_DOMAIN_NAME); verify(unifiedClaimMetadataManager, times(1)).updateLocalClaim(any(), anyInt()); - when(unifiedClaimMetadataManager.getLocalClaims(SUPER_TENANT_ID)).thenReturn(new ArrayList<>()); + when(unifiedClaimMetadataManager.getLocalClaim(LOCAL_CLAIM_1, SUPER_TENANT_ID)) + .thenReturn(Optional.empty()); assertThrows(ClaimMetadataClientException.class, () -> { service.updateLocalClaim(localClaimToBeUpdated, SUPER_TENANT_DOMAIN_NAME); }); @@ -246,11 +256,11 @@ public void testUpdateLocalClaimMappings() throws ClaimMetadataException { LocalClaim localClaimToBeUpdated = new LocalClaim(LOCAL_CLAIM_1); localClaimToBeUpdated.setMappedAttributes(new ArrayList<>()); localClaimToBeUpdated.getMappedAttributes() - .add(new AttributeMapping("PRIMARY", "user_name")); + .add(new AttributeMapping(PRIMARY_DOMAIN, USERNAME_ATTRIBUTE)); List localClaimsList = new ArrayList<>(); localClaimsList.add(localClaimToBeUpdated); - service.updateLocalClaimMappings(localClaimsList, SUPER_TENANT_DOMAIN_NAME, "PRIMARY"); + service.updateLocalClaimMappings(localClaimsList, SUPER_TENANT_DOMAIN_NAME, PRIMARY_DOMAIN); verify(unifiedClaimMetadataManager, times(1)) .updateLocalClaimMappings(any(), anyInt(), anyString()); } @@ -355,6 +365,198 @@ public void testGetMappedExternalClaimsForLocalClaim() throws ClaimMetadataExcep verify(unifiedClaimMetadataManager, times(1)).getMappedExternalClaims(LOCAL_CLAIM_1, SUPER_TENANT_ID); } + @Test(dataProvider = "addLocalClaimUniquenessPropertiesData") + public void testAddLocalClaimShouldSetCorrectUniquenessProperties(String newIsUnique, String newUniquenessScope, + String expectedUniquenessScope, + String expectedIsUnique) + throws ClaimMetadataException { + + LocalClaim localClaim = new LocalClaim(LOCAL_CLAIM_1); + localClaim.setMappedAttributes(new ArrayList<>()); + localClaim.getMappedAttributes().add(new AttributeMapping(PRIMARY_DOMAIN, USERNAME_ATTRIBUTE)); + + Map claimProperties = new HashMap<>(); + if (newIsUnique != null) { + claimProperties.put(ClaimConstants.IS_UNIQUE_CLAIM_PROPERTY, newIsUnique); + } + if (newUniquenessScope != null) { + claimProperties.put(ClaimConstants.CLAIM_UNIQUENESS_SCOPE_PROPERTY, newUniquenessScope); + } + localClaim.setClaimProperties(claimProperties); + + when(unifiedClaimMetadataManager.getLocalClaims(anyInt())).thenReturn(new ArrayList<>()); + service.addLocalClaim(localClaim, SUPER_TENANT_DOMAIN_NAME); + + ArgumentCaptor localClaimCaptor = ArgumentCaptor.forClass(LocalClaim.class); + verify(unifiedClaimMetadataManager, + times(1)).addLocalClaim(localClaimCaptor.capture(), anyInt()); + + Map capturedProperties = localClaimCaptor.getValue().getClaimProperties(); + if (expectedIsUnique != null) { + assertEquals(capturedProperties.get(ClaimConstants.IS_UNIQUE_CLAIM_PROPERTY), expectedIsUnique); + } + if (expectedUniquenessScope != null) { + assertEquals(capturedProperties.get(ClaimConstants.CLAIM_UNIQUENESS_SCOPE_PROPERTY), + expectedUniquenessScope); + } + } + + @Test(dataProvider = "updateLocalClaimUniquenessPropertiesData") + public void testUpdateLocalClaimShouldSetCorrectUniquenessProperties(String existingIsUnique, + String existingUniquenessScope, + String newIsUnique, String newUniquenessScope, + String expectedUniquenessScope, + String expectedIsUnique) + throws ClaimMetadataException { + + // Create existing claim + LocalClaim existingLocalClaim = new LocalClaim(LOCAL_CLAIM_1); + existingLocalClaim.setMappedAttributes(new ArrayList<>()); + existingLocalClaim.getMappedAttributes().add(new AttributeMapping(PRIMARY_DOMAIN, USERNAME_ATTRIBUTE)); + + Map existingProperties = new HashMap<>(); + if (existingIsUnique != null) { + existingProperties.put(ClaimConstants.IS_UNIQUE_CLAIM_PROPERTY, existingIsUnique); + } + if (existingUniquenessScope != null) { + existingProperties.put(ClaimConstants.CLAIM_UNIQUENESS_SCOPE_PROPERTY, existingUniquenessScope); + } + existingLocalClaim.setClaimProperties(existingProperties); + + // Create updated claim + LocalClaim updatedLocalClaim = new LocalClaim(LOCAL_CLAIM_1); + updatedLocalClaim.setMappedAttributes(new ArrayList<>()); + updatedLocalClaim.getMappedAttributes().add(new AttributeMapping(PRIMARY_DOMAIN, USERNAME_ATTRIBUTE)); + + Map newProperties = new HashMap<>(); + if (newIsUnique != null) { + newProperties.put(ClaimConstants.IS_UNIQUE_CLAIM_PROPERTY, newIsUnique); + } + if (newUniquenessScope != null) { + newProperties.put(ClaimConstants.CLAIM_UNIQUENESS_SCOPE_PROPERTY, newUniquenessScope); + } + updatedLocalClaim.setClaimProperties(newProperties); + + when(unifiedClaimMetadataManager.getLocalClaim(LOCAL_CLAIM_1, SUPER_TENANT_ID)) + .thenReturn(Optional.of(existingLocalClaim)); + service.updateLocalClaim(updatedLocalClaim, SUPER_TENANT_DOMAIN_NAME); + + ArgumentCaptor localClaimCaptor = ArgumentCaptor.forClass(LocalClaim.class); + verify(unifiedClaimMetadataManager, + times(1)).updateLocalClaim(localClaimCaptor.capture(), anyInt()); + + Map capturedProperties = localClaimCaptor.getValue().getClaimProperties(); + if (expectedIsUnique != null) { + assertEquals(capturedProperties.get(ClaimConstants.IS_UNIQUE_CLAIM_PROPERTY), expectedIsUnique); + } + if (expectedUniquenessScope != null) { + assertEquals(capturedProperties.get(ClaimConstants.CLAIM_UNIQUENESS_SCOPE_PROPERTY), + expectedUniquenessScope); + } + } + + @DataProvider(name = "addLocalClaimUniquenessPropertiesData") + public Object[][] addLocalClaimUniquenessPropertiesData() { + + return new Object[][]{ + // Case 1: Only isUnique property is included + {"true", null, ClaimConstants.ClaimUniquenessScope.ACROSS_USERSTORES.toString(), "true"}, + {"false", null, ClaimConstants.ClaimUniquenessScope.NONE.toString(), "false"}, + + // Case 2: Only UniquenessScope property is included + {null, ClaimConstants.ClaimUniquenessScope.ACROSS_USERSTORES.toString(), + ClaimConstants.ClaimUniquenessScope.ACROSS_USERSTORES.toString(), null}, + {null, ClaimConstants.ClaimUniquenessScope.NONE.toString(), + ClaimConstants.ClaimUniquenessScope.NONE.toString(), null}, + {null, ClaimConstants.ClaimUniquenessScope.WITHIN_USERSTORE.toString(), + ClaimConstants.ClaimUniquenessScope.WITHIN_USERSTORE.toString(), null}, + + // Case 3: Both isUnique & UniquenessScope properties are included + {"true", ClaimConstants.ClaimUniquenessScope.ACROSS_USERSTORES.toString(), + ClaimConstants.ClaimUniquenessScope.ACROSS_USERSTORES.toString(), "true"}, + {"true", ClaimConstants.ClaimUniquenessScope.WITHIN_USERSTORE.toString(), + ClaimConstants.ClaimUniquenessScope.WITHIN_USERSTORE.toString(), "true"}, + {"true", ClaimConstants.ClaimUniquenessScope.NONE.toString(), + ClaimConstants.ClaimUniquenessScope.NONE.toString(), "false"}, + {"false", ClaimConstants.ClaimUniquenessScope.ACROSS_USERSTORES.toString(), + ClaimConstants.ClaimUniquenessScope.ACROSS_USERSTORES.toString(), "true"}, + {"false", ClaimConstants.ClaimUniquenessScope.WITHIN_USERSTORE.toString(), + ClaimConstants.ClaimUniquenessScope.WITHIN_USERSTORE.toString(), "true"}, + {"false", ClaimConstants.ClaimUniquenessScope.NONE.toString(), + ClaimConstants.ClaimUniquenessScope.NONE.toString(), "false"}}; + } + + @DataProvider(name = "updateLocalClaimUniquenessPropertiesData") + public Object[][] updateLocalClaimUniquenessPropertiesData() { + + return new Object[][]{ + // Case 1: None of the properties exist + {null, null, "true", null, ClaimConstants.ClaimUniquenessScope.ACROSS_USERSTORES.toString(), "true"}, + {null, null, "false", null, ClaimConstants.ClaimUniquenessScope.NONE.toString(), "false"}, + {null, null, null, ClaimConstants.ClaimUniquenessScope.NONE.toString(), + ClaimConstants.ClaimUniquenessScope.NONE.toString(), null}, + {null, null, null, ClaimConstants.ClaimUniquenessScope.ACROSS_USERSTORES.toString(), + ClaimConstants.ClaimUniquenessScope.ACROSS_USERSTORES.toString(), null}, + {null, null, null, ClaimConstants.ClaimUniquenessScope.WITHIN_USERSTORE.toString(), + ClaimConstants.ClaimUniquenessScope.WITHIN_USERSTORE.toString(), null}, + {null, null, "true", ClaimConstants.ClaimUniquenessScope.ACROSS_USERSTORES.toString(), + ClaimConstants.ClaimUniquenessScope.ACROSS_USERSTORES.toString(), "true"}, + {null, null, "true", ClaimConstants.ClaimUniquenessScope.WITHIN_USERSTORE.toString(), + ClaimConstants.ClaimUniquenessScope.WITHIN_USERSTORE.toString(), "true"}, + {null, null, "false", ClaimConstants.ClaimUniquenessScope.NONE.toString(), + ClaimConstants.ClaimUniquenessScope.NONE.toString(), "false"}, + {null, null, "false", ClaimConstants.ClaimUniquenessScope.ACROSS_USERSTORES.toString(), + ClaimConstants.ClaimUniquenessScope.ACROSS_USERSTORES.toString(), "true"}, + {null, null, "false", ClaimConstants.ClaimUniquenessScope.WITHIN_USERSTORE.toString(), + ClaimConstants.ClaimUniquenessScope.WITHIN_USERSTORE.toString(), "true"}, + {null, null, "true", ClaimConstants.ClaimUniquenessScope.NONE.toString(), + ClaimConstants.ClaimUniquenessScope.NONE.toString(), "false"}, + + // Case 2: Only isUnique property exists + {"true", null, "true", null, ClaimConstants.ClaimUniquenessScope.ACROSS_USERSTORES.toString(), "true"}, + {"true", null, "false", null, ClaimConstants.ClaimUniquenessScope.NONE.toString(), "false"}, + {"false", null, "true", null, ClaimConstants.ClaimUniquenessScope.ACROSS_USERSTORES.toString(), "true"}, + {"false", null, "false", null, ClaimConstants.ClaimUniquenessScope.NONE.toString(), "false"}, + + // Case 3: Only UniquenessScope property exists + {null, ClaimConstants.ClaimUniquenessScope.ACROSS_USERSTORES.toString(), "true", null, + ClaimConstants.ClaimUniquenessScope.ACROSS_USERSTORES.toString(), "true"}, + {null, ClaimConstants.ClaimUniquenessScope.ACROSS_USERSTORES.toString(), "false", null, + ClaimConstants.ClaimUniquenessScope.NONE.toString(), "false"}, + {null, ClaimConstants.ClaimUniquenessScope.WITHIN_USERSTORE.toString(), "true", null, + ClaimConstants.ClaimUniquenessScope.ACROSS_USERSTORES.toString(), "true"}, + {null, ClaimConstants.ClaimUniquenessScope.WITHIN_USERSTORE.toString(), "false", null, + ClaimConstants.ClaimUniquenessScope.NONE.toString(), "false"}, + {null, ClaimConstants.ClaimUniquenessScope.NONE.toString(), "true", null, + ClaimConstants.ClaimUniquenessScope.ACROSS_USERSTORES.toString(), "true"}, + {null, ClaimConstants.ClaimUniquenessScope.NONE.toString(), "false", null, + ClaimConstants.ClaimUniquenessScope.NONE.toString(), "false"}, + + // Case 4: Both properties exist - only isUnique property changes + {"true", ClaimConstants.ClaimUniquenessScope.ACROSS_USERSTORES.toString(), "false", + ClaimConstants.ClaimUniquenessScope.ACROSS_USERSTORES.toString(), + ClaimConstants.ClaimUniquenessScope.NONE.toString(), "false"}, + {"false", ClaimConstants.ClaimUniquenessScope.ACROSS_USERSTORES.toString(), "true", + ClaimConstants.ClaimUniquenessScope.ACROSS_USERSTORES.toString(), + ClaimConstants.ClaimUniquenessScope.ACROSS_USERSTORES.toString(), "true"}, + + // Case 5: Both properties exist - only UniquenessScope property changes + {"true", ClaimConstants.ClaimUniquenessScope.ACROSS_USERSTORES.toString(), "true", + ClaimConstants.ClaimUniquenessScope.WITHIN_USERSTORE.toString(), + ClaimConstants.ClaimUniquenessScope.WITHIN_USERSTORE.toString(), "true"}, + {"true", ClaimConstants.ClaimUniquenessScope.ACROSS_USERSTORES.toString(), "true", + ClaimConstants.ClaimUniquenessScope.NONE.toString(), + ClaimConstants.ClaimUniquenessScope.NONE.toString(), "false"}, + + // Case 6: Both properties exist - both properties change + {"true", ClaimConstants.ClaimUniquenessScope.ACROSS_USERSTORES.toString(), "false", + ClaimConstants.ClaimUniquenessScope.WITHIN_USERSTORE.toString(), + ClaimConstants.ClaimUniquenessScope.WITHIN_USERSTORE.toString(), "true"}, + {"true", ClaimConstants.ClaimUniquenessScope.ACROSS_USERSTORES.toString(), "false", + ClaimConstants.ClaimUniquenessScope.NONE.toString(), + ClaimConstants.ClaimUniquenessScope.NONE.toString(), "false"}}; + } + @AfterMethod public void tearDown() { diff --git a/components/claim-mgt/org.wso2.carbon.identity.claim.metadata.mgt/src/test/java/org/wso2/carbon/identity/claim/metadata/mgt/dao/LocalClaimDAOTest.java b/components/claim-mgt/org.wso2.carbon.identity.claim.metadata.mgt/src/test/java/org/wso2/carbon/identity/claim/metadata/mgt/dao/LocalClaimDAOTest.java index 3e56b78e0ab0..ff69ab6bfb08 100644 --- a/components/claim-mgt/org.wso2.carbon.identity.claim.metadata.mgt/src/test/java/org/wso2/carbon/identity/claim/metadata/mgt/dao/LocalClaimDAOTest.java +++ b/components/claim-mgt/org.wso2.carbon.identity.claim.metadata.mgt/src/test/java/org/wso2/carbon/identity/claim/metadata/mgt/dao/LocalClaimDAOTest.java @@ -16,7 +16,6 @@ package org.wso2.carbon.identity.claim.metadata.mgt.dao; import org.testng.annotations.BeforeClass; -import org.testng.annotations.BeforeMethod; import org.testng.annotations.DataProvider; import org.testng.annotations.Test; import org.wso2.carbon.identity.claim.metadata.mgt.exception.ClaimMetadataException; @@ -24,13 +23,9 @@ import org.wso2.carbon.identity.claim.metadata.mgt.model.ClaimDialect; 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.claim.metadata.mgt.util.ClaimConstants.ClaimUniquenessScope; import org.wso2.carbon.identity.common.testng.WithCarbonHome; import org.wso2.carbon.identity.common.testng.WithH2Database; -import org.wso2.carbon.identity.core.util.IdentityDatabaseUtil; -import java.sql.Connection; -import java.sql.SQLException; import java.util.ArrayList; import java.util.Arrays; import java.util.HashMap; @@ -39,7 +34,6 @@ import java.util.Objects; import static org.testng.Assert.assertEquals; -import static org.testng.Assert.assertFalse; import static org.testng.Assert.assertNotNull; import static org.testng.Assert.assertThrows; import static org.testng.Assert.assertTrue; @@ -55,7 +49,6 @@ public class LocalClaimDAOTest { LocalClaim localClaim1; LocalClaim localClaim2; LocalClaim localClaim3; - LocalClaim localClaim4; List mappedAttributes1; List mappedAttributes2; @@ -110,20 +103,6 @@ public void initTest() throws Exception { localClaim3.setClaimProperties(claimProperties3); } - @BeforeMethod - public void setUp() { - - localClaim4 = new LocalClaim("http://wso2.org/claims/nic"); - Map claimProperties = new HashMap<>(); - claimProperties.put("Description", "Nation Identity Card"); - claimProperties.put("FriendlyName", "NIC"); - localClaim4.setClaimProperties(claimProperties); - - List mappedAttributes = new ArrayList<>(); - mappedAttributes.add(new AttributeMapping("PRIMARY", "nic")); - localClaim4.setMappedAttributes(mappedAttributes); - } - @Test(dataProvider = "getLocalClaim") public void testGetLocalClaims(Object localClaim, int tenantId) throws ClaimMetadataException { @@ -359,288 +338,4 @@ private boolean areAttributeMappingsEqual(List attributeMappin } return true; } - - @DataProvider(name = "addLocalClaimUniquenessValidationData") - public Object[][] addLocalClaimUniquenessValidationData() { - - return new Object[][]{ - // {newIsUnique, newUniquenessScope, expectedUniquenessScope, expectedIsUnique}. - - // Case 1: Only isUnique property is included. - {"true", null, ClaimUniquenessScope.ACROSS_USERSTORES.toString(), "true"}, - {"false", null, ClaimUniquenessScope.NONE.toString(), "false"}, - - // Case 2: Only UniquenessScope property is included. - {null, ClaimUniquenessScope.ACROSS_USERSTORES.toString(), - ClaimUniquenessScope.ACROSS_USERSTORES.toString(), null}, - {null, ClaimUniquenessScope.NONE.toString(), ClaimUniquenessScope.NONE.toString(), null}, - {null, ClaimUniquenessScope.WITHIN_USERSTORE.toString(), - ClaimUniquenessScope.WITHIN_USERSTORE.toString(), null}, - - // Case 3: Both isUnique & UniquenessScope properties are included. - {"true", ClaimUniquenessScope.ACROSS_USERSTORES.toString(), - ClaimUniquenessScope.ACROSS_USERSTORES.toString(), "true"}, - {"true", ClaimUniquenessScope.WITHIN_USERSTORE.toString(), - ClaimUniquenessScope.WITHIN_USERSTORE.toString(), "true"}, - {"true", ClaimUniquenessScope.NONE.toString(), ClaimUniquenessScope.NONE.toString(), "false"}, - {"false", ClaimUniquenessScope.ACROSS_USERSTORES.toString(), - ClaimUniquenessScope.ACROSS_USERSTORES.toString(), "true"}, - {"false", ClaimUniquenessScope.WITHIN_USERSTORE.toString(), - ClaimUniquenessScope.WITHIN_USERSTORE.toString(), "true"}, - {"false", ClaimUniquenessScope.NONE.toString(), ClaimUniquenessScope.NONE.toString(), "false"} - }; - } - - @Test(dataProvider = "addLocalClaimUniquenessValidationData") - public void testAddLocalClaimWithUniquenessProperties(String newIsUnique, String newUniquenessScope, - String expectedUniquenessScope, String expectedIsUnique) - throws ClaimMetadataException { - - ClaimDialectDAO claimDialectDAO = new ClaimDialectDAO(); - ClaimDialect claimDialect = new ClaimDialect(ClaimConstants.LOCAL_CLAIM_DIALECT_URI); - claimDialectDAO.addClaimDialect(claimDialect, TEST_LOCAL_TENANT_ID); - - // Add uniqueness validation properties. - Map properties = new HashMap<>(localClaim4.getClaimProperties()); - if (newIsUnique != null) { - properties.put(ClaimConstants.IS_UNIQUE_CLAIM_PROPERTY, newIsUnique); - } - if (newUniquenessScope != null) { - properties.put(ClaimConstants.CLAIM_UNIQUENESS_SCOPE_PROPERTY, newUniquenessScope); - } - localClaim4.setClaimProperties(properties); - - // Add claim. - LocalClaimDAO localClaimDAO = new LocalClaimDAO(); - localClaimDAO.addLocalClaim(localClaim4, TEST_LOCAL_TENANT_ID); - - // Verify. - List retrievedClaims = localClaimDAO.getLocalClaims(TEST_LOCAL_TENANT_ID); - assertNotNull(retrievedClaims, "Retrieved claims should not be null"); - assertEquals(retrievedClaims.size(), 1, "Should have retrieved exactly one claim"); - - LocalClaim retrievedClaim = retrievedClaims.get(0); - verifyUniquenessProperties(retrievedClaim.getClaimProperties(), expectedUniquenessScope, expectedIsUnique); - - // Clean up. - localClaimDAO.removeLocalClaim(localClaim4.getClaimURI(), TEST_LOCAL_TENANT_ID); - claimDialectDAO.removeClaimDialect(claimDialect, TEST_LOCAL_TENANT_ID); - } - - @DataProvider(name = "updateLocalClaimUniquenessValidationData") - public Object[][] updateLocalClaimUniquenessValidationData() { - - return new Object[][]{ - // {existingIsUnique, existingUniquenessScope, newIsUnique, newUniquenessScope, - // expectedUniquenessScope, expectedIsUnique}. - - // Case 1: None of the properties exist. - {null, null, "true", null, ClaimUniquenessScope.ACROSS_USERSTORES.toString(), "true"}, - {null, null, "false", null, ClaimUniquenessScope.NONE.toString(), "false"}, - - {null, null, null, ClaimUniquenessScope.NONE.toString(), ClaimUniquenessScope.NONE.toString(), null}, - {null, null, null, ClaimUniquenessScope.ACROSS_USERSTORES.toString(), - ClaimUniquenessScope.ACROSS_USERSTORES.toString(), null}, - {null, null, null, ClaimUniquenessScope.WITHIN_USERSTORE.toString(), - ClaimUniquenessScope.WITHIN_USERSTORE.toString(), null}, - - {null, null, "true", ClaimUniquenessScope.ACROSS_USERSTORES.toString(), - ClaimUniquenessScope.ACROSS_USERSTORES.toString(), "true"}, - {null, null, "true", ClaimUniquenessScope.WITHIN_USERSTORE.toString(), - ClaimUniquenessScope.WITHIN_USERSTORE.toString(), "true"}, - {null, null, "false", ClaimUniquenessScope.NONE.toString(), - ClaimUniquenessScope.NONE.toString(), "false"}, - - {null, null, "false", ClaimUniquenessScope.ACROSS_USERSTORES.toString(), - ClaimUniquenessScope.ACROSS_USERSTORES.toString(), "true"}, - {null, null, "false", ClaimUniquenessScope.WITHIN_USERSTORE.toString(), - ClaimUniquenessScope.WITHIN_USERSTORE.toString(), "true"}, - {null, null, "true", ClaimUniquenessScope.NONE.toString(), - ClaimUniquenessScope.NONE.toString(), "false"}, - - // Case 2: Only isUnique property exists. - {"true", null, "true", null, ClaimUniquenessScope.ACROSS_USERSTORES.toString(), "true"}, - {"true", null, "false", null, ClaimUniquenessScope.NONE.toString(), "false"}, - {"false", null, "true", null, ClaimUniquenessScope.ACROSS_USERSTORES.toString(), "true"}, - {"false", null, "false", null, ClaimUniquenessScope.NONE.toString(), "false"}, - - {"true", null, null, ClaimUniquenessScope.NONE.toString(), ClaimUniquenessScope.NONE.toString(), null}, - {"true", null, null, ClaimUniquenessScope.ACROSS_USERSTORES.toString(), - ClaimUniquenessScope.ACROSS_USERSTORES.toString(), null}, - {"false", null, null, ClaimUniquenessScope.NONE.toString(), ClaimUniquenessScope.NONE.toString(), null}, - {"false", null, null, ClaimUniquenessScope.ACROSS_USERSTORES.toString(), - ClaimUniquenessScope.ACROSS_USERSTORES.toString(), null}, - - {"true", null, "true", ClaimUniquenessScope.ACROSS_USERSTORES.toString(), - ClaimUniquenessScope.ACROSS_USERSTORES.toString(), "true"}, - {"true", null, "true", ClaimUniquenessScope.NONE.toString(), - ClaimUniquenessScope.NONE.toString(), "false"}, - {"false", null, "false", ClaimUniquenessScope.ACROSS_USERSTORES.toString(), - ClaimUniquenessScope.ACROSS_USERSTORES.toString(), "true"}, - {"false", null, "false", ClaimUniquenessScope.NONE.toString(), - ClaimUniquenessScope.NONE.toString(), "false"}, - - {"true", null, "false", ClaimUniquenessScope.ACROSS_USERSTORES.toString(), - ClaimUniquenessScope.ACROSS_USERSTORES.toString(), "true"}, - {"true", null, "false", ClaimUniquenessScope.NONE.toString(), - ClaimUniquenessScope.NONE.toString(), "false"}, - {"false", null, "true", ClaimUniquenessScope.ACROSS_USERSTORES.toString(), - ClaimUniquenessScope.ACROSS_USERSTORES.toString(), "true"}, - {"false", null, "true", ClaimUniquenessScope.NONE.toString(), - ClaimUniquenessScope.NONE.toString(), "false"}, - - // Case 3: Only UniquenessScope property exists. - {null, ClaimUniquenessScope.ACROSS_USERSTORES.toString(), "true", null, - ClaimUniquenessScope.ACROSS_USERSTORES.toString(), "true"}, - {null, ClaimUniquenessScope.ACROSS_USERSTORES.toString(), "false", null, - ClaimUniquenessScope.NONE.toString(), "false"}, - {null, ClaimUniquenessScope.WITHIN_USERSTORE.toString(), "true", null, - ClaimUniquenessScope.ACROSS_USERSTORES.toString(), "true"}, - {null, ClaimUniquenessScope.WITHIN_USERSTORE.toString(), "false", null, - ClaimUniquenessScope.NONE.toString(), "false"}, - {null, ClaimUniquenessScope.NONE.toString(), "true", null, - ClaimUniquenessScope.ACROSS_USERSTORES.toString(), "true"}, - {null, ClaimUniquenessScope.NONE.toString(), "false", null, - ClaimUniquenessScope.NONE.toString(), "false"}, - - {null, ClaimUniquenessScope.ACROSS_USERSTORES.toString(), null, ClaimUniquenessScope.NONE.toString(), - ClaimUniquenessScope.NONE.toString(), null}, - {null, ClaimUniquenessScope.ACROSS_USERSTORES.toString(), null, - ClaimUniquenessScope.ACROSS_USERSTORES.toString(), - ClaimUniquenessScope.ACROSS_USERSTORES.toString(), null}, - {null, ClaimUniquenessScope.ACROSS_USERSTORES.toString(), null, - ClaimUniquenessScope.WITHIN_USERSTORE.toString(), - ClaimUniquenessScope.WITHIN_USERSTORE.toString(), null}, - {null, ClaimUniquenessScope.NONE.toString(), null, ClaimUniquenessScope.NONE.toString(), - ClaimUniquenessScope.NONE.toString(), null}, - {null, ClaimUniquenessScope.NONE.toString(), null, ClaimUniquenessScope.ACROSS_USERSTORES.toString(), - ClaimUniquenessScope.ACROSS_USERSTORES.toString(), null}, - {null, ClaimUniquenessScope.NONE.toString(), null, ClaimUniquenessScope.WITHIN_USERSTORE.toString(), - ClaimUniquenessScope.WITHIN_USERSTORE.toString(), null}, - - {null, ClaimUniquenessScope.ACROSS_USERSTORES.toString(), "true", - ClaimUniquenessScope.ACROSS_USERSTORES.toString(), - ClaimUniquenessScope.ACROSS_USERSTORES.toString(), "true"}, - {null, ClaimUniquenessScope.ACROSS_USERSTORES.toString(), "true", - ClaimUniquenessScope.WITHIN_USERSTORE.toString(), - ClaimUniquenessScope.WITHIN_USERSTORE.toString(), "true"}, - {null, ClaimUniquenessScope.ACROSS_USERSTORES.toString(), "false", ClaimUniquenessScope.NONE.toString(), - ClaimUniquenessScope.NONE.toString(), "false"}, - - // Case 4: Both properties exist - only isUnique property changes. - {"true", ClaimUniquenessScope.ACROSS_USERSTORES.toString(), "false", - ClaimUniquenessScope.ACROSS_USERSTORES.toString(), ClaimUniquenessScope.NONE.toString(), - "false"}, - {"false", ClaimUniquenessScope.ACROSS_USERSTORES.toString(), "true", - ClaimUniquenessScope.ACROSS_USERSTORES.toString(), - ClaimUniquenessScope.ACROSS_USERSTORES.toString(), "true"}, - - // Case 5: Both properties exist - only UniquenessScope property changes. - {"true", ClaimUniquenessScope.ACROSS_USERSTORES.toString(), "true", - ClaimUniquenessScope.WITHIN_USERSTORE.toString(), - ClaimUniquenessScope.WITHIN_USERSTORE.toString(), "true"}, - {"true", ClaimUniquenessScope.ACROSS_USERSTORES.toString(), "true", - ClaimUniquenessScope.NONE.toString(), - ClaimUniquenessScope.NONE.toString(), "false"}, - - // Case 6: Both properties exist - both properties change. - {"true", ClaimUniquenessScope.ACROSS_USERSTORES.toString(), "false", - ClaimUniquenessScope.WITHIN_USERSTORE.toString(), - ClaimUniquenessScope.WITHIN_USERSTORE.toString(), "true"}, - {"true", ClaimUniquenessScope.ACROSS_USERSTORES.toString(), "false", - ClaimUniquenessScope.NONE.toString(), - ClaimUniquenessScope.NONE.toString(), "false"} - }; - } - - @Test(dataProvider = "updateLocalClaimUniquenessValidationData") - public void testUpdateLocalClaimWithUniquenessProperties(String existingIsUnique, String existingUniquenessScope, - String newIsUnique, String newUniquenessScope, - String expectedUniquenessScope, String expectedIsUnique) - throws ClaimMetadataException { - - ClaimDialectDAO claimDialectDAO = new ClaimDialectDAO(); - ClaimDialect claimDialect = new ClaimDialect(ClaimConstants.LOCAL_CLAIM_DIALECT_URI); - claimDialectDAO.addClaimDialect(claimDialect, TEST_LOCAL_TENANT_ID); - - // Add initial claim. - LocalClaimDAO localClaimDAO = new LocalClaimDAO(); - localClaimDAO.addLocalClaim(localClaim4, TEST_LOCAL_TENANT_ID); - - // Update the DB directly to set the initial uniqueness validation related claim properties. - try (Connection connection = IdentityDatabaseUtil.getDBConnection(true)) { - ClaimDAO claimDAO = new ClaimDAO(); - int claimId = claimDAO.getClaimId(connection, ClaimConstants.LOCAL_CLAIM_DIALECT_URI, - localClaim4.getClaimURI(), TEST_LOCAL_TENANT_ID); - - Map claimProperties = new HashMap<>(); - if (existingIsUnique != null) { - claimProperties.put(ClaimConstants.IS_UNIQUE_CLAIM_PROPERTY, existingIsUnique); - } - if (existingUniquenessScope != null) { - claimProperties.put(ClaimConstants.CLAIM_UNIQUENESS_SCOPE_PROPERTY, existingUniquenessScope); - } - claimDAO.addClaimProperties(connection, claimId, claimProperties, TEST_LOCAL_TENANT_ID); - - IdentityDatabaseUtil.commitTransaction(connection); - } catch (SQLException e) { - throw new RuntimeException(e); - } - - // Update uniqueness validation properties. - Map newProperties = - updateUniquenessProperties(localClaim4.getClaimProperties(), newIsUnique, newUniquenessScope); - localClaim4.setClaimProperties(newProperties); - - // Update claim. - localClaimDAO.updateLocalClaim(localClaim4, TEST_LOCAL_TENANT_ID); - - // Verify. - List retrievedClaims = localClaimDAO.getLocalClaims(TEST_LOCAL_TENANT_ID); - assertNotNull(retrievedClaims, "Retrieved claims should not be null"); - assertEquals(retrievedClaims.size(), 1, "Should have retrieved exactly one claim"); - - LocalClaim retrievedClaim = retrievedClaims.get(0); - verifyUniquenessProperties(retrievedClaim.getClaimProperties(), expectedUniquenessScope, expectedIsUnique); - - // Clean up. - localClaimDAO.removeLocalClaim(localClaim4.getClaimURI(), TEST_LOCAL_TENANT_ID); - claimDialectDAO.removeClaimDialect(claimDialect, TEST_LOCAL_TENANT_ID); - } - - private Map updateUniquenessProperties(Map existingProperties, String newIsUnique, - String newUniquenessScope) { - - Map newProperties = new HashMap<>(existingProperties); - if (newIsUnique != null) { - newProperties.put(ClaimConstants.IS_UNIQUE_CLAIM_PROPERTY, newIsUnique); - } else { - newProperties.remove(ClaimConstants.IS_UNIQUE_CLAIM_PROPERTY); - } - if (newUniquenessScope != null) { - newProperties.put(ClaimConstants.CLAIM_UNIQUENESS_SCOPE_PROPERTY, newUniquenessScope); - } else { - newProperties.remove(ClaimConstants.CLAIM_UNIQUENESS_SCOPE_PROPERTY); - } - return newProperties; - } - - private void verifyUniquenessProperties(Map retrievedProperties, - String expectedUniquenessScope, String expectedIsUnique) { - - assertTrue(retrievedProperties.containsKey(ClaimConstants.CLAIM_UNIQUENESS_SCOPE_PROPERTY), - "UniquenessScope property should be present"); - assertEquals(expectedUniquenessScope, retrievedProperties.get(ClaimConstants.CLAIM_UNIQUENESS_SCOPE_PROPERTY), - "UniquenessScope should match expected value"); - - if (expectedIsUnique != null) { - assertTrue(retrievedProperties.containsKey(ClaimConstants.IS_UNIQUE_CLAIM_PROPERTY), - "isUnique property should be present"); - assertEquals(expectedIsUnique, retrievedProperties.get(ClaimConstants.IS_UNIQUE_CLAIM_PROPERTY), - "isUnique should match expected value"); - } else { - assertFalse(retrievedProperties.containsKey(ClaimConstants.IS_UNIQUE_CLAIM_PROPERTY), - "isUnique property should not be present"); - } - } }