diff --git a/components/org.wso2.carbon.identity.organization.discovery.service/pom.xml b/components/org.wso2.carbon.identity.organization.discovery.service/pom.xml index bee8bd6a2..026f46451 100644 --- a/components/org.wso2.carbon.identity.organization.discovery.service/pom.xml +++ b/components/org.wso2.carbon.identity.organization.discovery.service/pom.xml @@ -1,6 +1,6 @@ @@ -105,6 +109,7 @@ org.wso2.carbon.identity.organization.discovery.service.constant;version="${org.wso2.identity.organization.mgt.imp.pkg.version.range}", org.wso2.carbon.identity.organization.discovery.service.dao;version="${org.wso2.identity.organization.mgt.imp.pkg.version.range}", org.wso2.carbon.identity.organization.discovery.service.model;version="${org.wso2.identity.organization.mgt.imp.pkg.version.range}", + org.wso2.carbon.identity.organization.management.organization.user.sharing.constant;version="${org.wso2.identity.organization.mgt.imp.pkg.version.range}", org.wso2.carbon.identity.organization.management.service;version="${org.wso2.identity.organization.mgt.core.imp.pkg.version.range}", org.wso2.carbon.identity.organization.management.service.constant;version="${org.wso2.identity.organization.mgt.core.imp.pkg.version.range}", org.wso2.carbon.identity.organization.management.service.exception;version="${org.wso2.identity.organization.mgt.core.imp.pkg.version.range}", diff --git a/components/org.wso2.carbon.identity.organization.discovery.service/src/main/java/org/wso2/carbon/identity/organization/discovery/service/listener/OrganizationDiscoveryUserOperationListener.java b/components/org.wso2.carbon.identity.organization.discovery.service/src/main/java/org/wso2/carbon/identity/organization/discovery/service/listener/OrganizationDiscoveryUserOperationListener.java index 132e138bd..0c558889e 100644 --- a/components/org.wso2.carbon.identity.organization.discovery.service/src/main/java/org/wso2/carbon/identity/organization/discovery/service/listener/OrganizationDiscoveryUserOperationListener.java +++ b/components/org.wso2.carbon.identity.organization.discovery.service/src/main/java/org/wso2/carbon/identity/organization/discovery/service/listener/OrganizationDiscoveryUserOperationListener.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023, WSO2 LLC. (http://www.wso2.com). + * Copyright (c) 2023-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 @@ -46,6 +46,7 @@ import static org.wso2.carbon.identity.organization.config.service.constant.OrganizationConfigConstants.ErrorMessages.ERROR_CODE_DISCOVERY_CONFIG_NOT_EXIST; import static org.wso2.carbon.identity.organization.discovery.service.constant.DiscoveryConstants.ENABLE_CONFIG; import static org.wso2.carbon.identity.organization.discovery.service.constant.DiscoveryConstants.PRE_ADD_USER_EMAIL_DOMAIN_VALIDATE; +import static org.wso2.carbon.identity.organization.management.organization.user.sharing.constant.UserSharingConstants.CLAIM_MANAGED_ORGANIZATION; import static org.wso2.carbon.identity.organization.management.service.constant.OrganizationManagementConstants.ErrorMessages.ERROR_CODE_EMAIL_DOMAIN_ASSOCIATED_WITH_DIFFERENT_ORGANIZATION; import static org.wso2.carbon.identity.organization.management.service.constant.OrganizationManagementConstants.ErrorMessages.ERROR_CODE_EMAIL_DOMAIN_NOT_MAPPED_TO_ORGANIZATION; @@ -80,6 +81,10 @@ public boolean doPreAddUserWithID(String userName, Object credential, String[] r if (!OrganizationManagementUtil.isOrganization(tenantDomain)) { return true; } + if (claims != null && claims.containsKey(CLAIM_MANAGED_ORGANIZATION) + && StringUtils.isNotBlank(claims.get(CLAIM_MANAGED_ORGANIZATION))) { + return true; + } String organizationId = PrivilegedCarbonContext.getThreadLocalCarbonContext().getOrganizationId(); if (StringUtils.isBlank(organizationId)) { organizationId = getOrganizationManager().resolveOrganizationId(tenantDomain); diff --git a/components/org.wso2.carbon.identity.organization.discovery.service/src/test/java/org.wso2.carbon.identity.organization.discovery.service/listener/OrganizationDiscoveryUserOperationListenerTest.java b/components/org.wso2.carbon.identity.organization.discovery.service/src/test/java/org.wso2.carbon.identity.organization.discovery.service/listener/OrganizationDiscoveryUserOperationListenerTest.java new file mode 100644 index 000000000..d155fba50 --- /dev/null +++ b/components/org.wso2.carbon.identity.organization.discovery.service/src/test/java/org.wso2.carbon.identity.organization.discovery.service/listener/OrganizationDiscoveryUserOperationListenerTest.java @@ -0,0 +1,123 @@ +/* + * 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.organization.discovery.service.listener; + +import org.apache.commons.lang3.StringUtils; +import org.mockito.InjectMocks; +import org.mockito.Mock; +import org.mockito.MockitoAnnotations; +import org.testng.annotations.BeforeMethod; +import org.testng.annotations.DataProvider; +import org.testng.annotations.Test; +import org.wso2.carbon.context.PrivilegedCarbonContext; +import org.wso2.carbon.identity.organization.discovery.service.internal.OrganizationDiscoveryServiceHolder; +import org.wso2.carbon.identity.organization.discovery.service.util.TestUtils; +import org.wso2.carbon.identity.organization.management.service.OrganizationManager; +import org.wso2.carbon.identity.organization.management.service.exception.OrganizationManagementException; +import org.wso2.carbon.identity.organization.management.service.internal.OrganizationManagementDataHolder; +import org.wso2.carbon.user.core.UserStoreException; +import org.wso2.carbon.user.core.UserStoreManager; +import org.wso2.carbon.user.core.service.RealmService; +import org.wso2.carbon.user.core.tenant.Tenant; +import org.wso2.carbon.user.core.tenant.TenantManager; + +import java.util.HashMap; +import java.util.Map; + +import static org.mockito.Mockito.when; +import static org.testng.Assert.assertFalse; +import static org.testng.Assert.assertTrue; +import static org.wso2.carbon.identity.organization.management.organization.user.sharing.constant.UserSharingConstants.CLAIM_MANAGED_ORGANIZATION; +import static org.wso2.carbon.user.core.UserCoreConstants.DEFAULT_PROFILE; + +/** + * This class contains unit tests to verify the behavior of the OrganizationDiscoveryUserOperationListener class. + */ +public class OrganizationDiscoveryUserOperationListenerTest { + + private static final String TEST_ORG_ID = "10084a8d-113f-4211-a0d5-efe36b082211"; + private static final String TEST_TENANT_DOMAIN = "example.com"; + private static final String TEST_USER = "testUser"; + private static final Object TEST_CREDENTIALS = "dummyPassword"; + private static final int TEST_TENANT_ID = 1234; + + @InjectMocks + private OrganizationDiscoveryUserOperationListener organizationDiscoveryUserOperationListener; + + @Mock + private UserStoreManager userStoreManager; + + @Mock + private RealmService realmService; + + @Mock + private TenantManager tenantManager; + + @Mock + private Tenant tenant; + + @Mock + private OrganizationManager organizationManager; + + @BeforeMethod + public void setUp() throws Exception { + + MockitoAnnotations.openMocks(this); + + TestUtils.mockDataSource(); + PrivilegedCarbonContext.getThreadLocalCarbonContext().setTenantDomain(TEST_TENANT_DOMAIN); + OrganizationManagementDataHolder.getInstance().setRealmService(realmService); + OrganizationManagementDataHolder.getInstance().setOrganizationManager(organizationManager); + OrganizationDiscoveryServiceHolder.getInstance().setOrganizationManager(organizationManager); + + when(realmService.getTenantManager()).thenReturn(tenantManager); + when(tenantManager.getTenantId(TEST_TENANT_DOMAIN)).thenReturn(TEST_TENANT_ID); + when(tenantManager.getTenant(TEST_TENANT_ID)).thenReturn(tenant); + when(tenant.getAssociatedOrganizationUUID()).thenReturn(TEST_ORG_ID); + when(organizationManager.getOrganizationDepthInHierarchy(TEST_ORG_ID)).thenReturn(1); + } + + @DataProvider(name = "skipEmailDomainValidationTestDataProvider") + public Object[][] claimsProvider() { + + return new Object[][]{ + {null, false}, + {new HashMap(), false}, + {new HashMap() {{ put(CLAIM_MANAGED_ORGANIZATION, StringUtils.EMPTY); }}, false}, + {new HashMap() {{ put(CLAIM_MANAGED_ORGANIZATION, TEST_ORG_ID); }}, true} + }; + } + + @Test(dataProvider = "skipEmailDomainValidationTestDataProvider") + public void testSkipEmailDomainValidationForSharedUserCreation(Map claims, boolean expectedResult) + throws UserStoreException, OrganizationManagementException { + + when(organizationManager.resolveOrganizationId(TEST_TENANT_DOMAIN)) + .thenThrow(new OrganizationManagementException("Validation not skipped.")); + + boolean result = organizationDiscoveryUserOperationListener.doPreAddUserWithID(TEST_USER, TEST_CREDENTIALS, + new String[]{}, claims, DEFAULT_PROFILE, userStoreManager); + + if (expectedResult) { + assertTrue(result, "Email domain validation should be skipped for shared user creation."); + } else { + assertFalse(result, "Expected false when CLAIM_MANAGED_ORGANIZATION claim is missing."); + } + } +} diff --git a/components/org.wso2.carbon.identity.organization.discovery.service/src/test/resources/testng.xml b/components/org.wso2.carbon.identity.organization.discovery.service/src/test/resources/testng.xml index 7ded18103..4d9b33120 100644 --- a/components/org.wso2.carbon.identity.organization.discovery.service/src/test/resources/testng.xml +++ b/components/org.wso2.carbon.identity.organization.discovery.service/src/test/resources/testng.xml @@ -21,6 +21,7 @@ +