diff --git a/components/org.wso2.carbon.identity.scim2.common/src/main/java/org/wso2/carbon/identity/scim2/common/impl/SCIMUserManager.java b/components/org.wso2.carbon.identity.scim2.common/src/main/java/org/wso2/carbon/identity/scim2/common/impl/SCIMUserManager.java index 8fe028595..1cf8de891 100644 --- a/components/org.wso2.carbon.identity.scim2.common/src/main/java/org/wso2/carbon/identity/scim2/common/impl/SCIMUserManager.java +++ b/components/org.wso2.carbon.identity.scim2.common/src/main/java/org/wso2/carbon/identity/scim2/common/impl/SCIMUserManager.java @@ -44,8 +44,10 @@ import org.wso2.carbon.identity.scim2.common.group.SCIMGroupHandler; import org.wso2.carbon.identity.scim2.common.internal.SCIMCommonComponentHolder; import org.wso2.carbon.identity.scim2.common.utils.AttributeMapper; +import org.wso2.carbon.identity.scim2.common.utils.IdentityEventExceptionSettings; import org.wso2.carbon.identity.scim2.common.utils.SCIMCommonConstants; import org.wso2.carbon.identity.scim2.common.utils.SCIMCommonUtils; +import org.wso2.carbon.identity.scim2.common.utils.SCIMConfigProcessor; import org.wso2.carbon.user.api.ClaimMapping; import org.wso2.carbon.user.api.UserStoreException; import org.wso2.carbon.user.core.PaginatedUserStoreManager; @@ -284,9 +286,16 @@ private void handleErrorsOnUserNameAndPasswordPolicy(Throwable e) throws BadRequ if (e instanceof PolicyViolationException) { throw new BadRequestException(e.getMessage(), ResponseCodeConstants.INVALID_VALUE); } - if ((e instanceof IdentityEventException) && StringUtils - .equals(ERROR_CODE_PASSWORD_HISTORY_VIOLATION, ((IdentityEventException) e).getErrorCode())) { - throw new BadRequestException(e.getMessage(), ResponseCodeConstants.INVALID_VALUE); + if (e instanceof IdentityEventException) { + IdentityEventException iee = ((IdentityEventException) e); + IdentityEventExceptionSettings ieeSettings = SCIMConfigProcessor.getInstance().getIdentityEventExceptionSettings(); + if (ieeSettings.getBadRequestErrorCodes().contains(iee.getErrorCode())) { + String errorMessage = e.getMessage(); + if (ieeSettings.isExposeErrorCodeInMessage()) { + errorMessage = "[" + iee.getErrorCode() + "] " + errorMessage; + } + throw new BadRequestException(errorMessage, ResponseCodeConstants.INVALID_VALUE); + } } e = e.getCause(); i++; diff --git a/components/org.wso2.carbon.identity.scim2.common/src/test/java/org/wso2/carbon/identity/scim2/common/impl/SCIMUserManagerTest.java b/components/org.wso2.carbon.identity.scim2.common/src/test/java/org/wso2/carbon/identity/scim2/common/impl/SCIMUserManagerTest.java index a5113e628..89a3e61cc 100644 --- a/components/org.wso2.carbon.identity.scim2.common/src/test/java/org/wso2/carbon/identity/scim2/common/impl/SCIMUserManagerTest.java +++ b/components/org.wso2.carbon.identity.scim2.common/src/test/java/org/wso2/carbon/identity/scim2/common/impl/SCIMUserManagerTest.java @@ -43,8 +43,10 @@ import org.wso2.carbon.identity.scim2.common.group.SCIMGroupHandler; import org.wso2.carbon.identity.scim2.common.test.utils.CommonTestUtils; import org.wso2.carbon.identity.scim2.common.utils.AttributeMapper; +import org.wso2.carbon.identity.scim2.common.utils.IdentityEventExceptionSettings; import org.wso2.carbon.identity.scim2.common.utils.SCIMCommonConstants; import org.wso2.carbon.identity.scim2.common.utils.SCIMCommonUtils; +import org.wso2.carbon.identity.scim2.common.utils.SCIMConfigProcessor; import org.wso2.carbon.identity.testutil.Whitebox; import org.wso2.carbon.user.api.Claim; import org.wso2.carbon.user.api.ClaimMapping; @@ -89,6 +91,7 @@ import static org.testng.AssertJUnit.assertEquals; import static org.testng.AssertJUnit.assertNotNull; import static org.testng.AssertJUnit.assertTrue; +import static org.testng.AssertJUnit.assertFalse; /* * Unit tests for SCIMUserManager @@ -96,7 +99,7 @@ @PrepareForTest({SCIMGroupHandler.class, IdentityUtil.class, SCIMUserSchemaExtensionBuilder.class, SCIMAttributeSchema.class, AttributeMapper.class, ClaimMetadataHandler.class, SCIMCommonUtils.class, IdentityTenantUtil.class, AbstractUserStoreManager.class, Group.class, UserCoreUtil.class, - ApplicationManagementService.class}) + ApplicationManagementService.class, SCIMConfigProcessor.class}) @PowerMockIgnore("java.sql.*") public class SCIMUserManagerTest extends PowerMockTestCase { @@ -141,7 +144,6 @@ public class SCIMUserManagerTest extends PowerMockTestCase { @BeforeMethod public void setUp() throws Exception { - initMocks(this); } @@ -663,6 +665,13 @@ public void testUpdateUserWithIdentityEventExceptionNotIntercepted() throws Exce when(ApplicationManagementService.getInstance()).thenReturn(applicationManagementService); when(applicationManagementService.getServiceProvider(anyString(), anyString())).thenReturn(null); + mockStatic(SCIMConfigProcessor.class); + SCIMConfigProcessor scimConfigProcessor = new SCIMConfigProcessor(); + IdentityEventExceptionSettings ieeSettings = scimConfigProcessor.getIdentityEventExceptionSettings(); + ieeSettings.setExposeErrorCodeInMessage(false); + ieeSettings.getBadRequestErrorCodes().add("NOT42"); + when(SCIMConfigProcessor.getInstance()).thenReturn(scimConfigProcessor); + String tenantDomain = "carbon.super"; SCIMUserManager scimUserManager = spy(new SCIMUserManager(mockedUserStoreManager, mockClaimMetadataManagementService, tenantDomain)); @@ -690,11 +699,53 @@ public void testUpdateUserWithIdentityEventExceptionIntercepted() throws Excepti when(ApplicationManagementService.getInstance()).thenReturn(applicationManagementService); when(applicationManagementService.getServiceProvider(anyString(), anyString())).thenReturn(null); + mockStatic(SCIMConfigProcessor.class); + SCIMConfigProcessor scimConfigProcessor = new SCIMConfigProcessor(); + IdentityEventExceptionSettings ieeSettings = scimConfigProcessor.getIdentityEventExceptionSettings(); + ieeSettings.setExposeErrorCodeInMessage(false); + ieeSettings.getBadRequestErrorCodes().add("42"); + when(SCIMConfigProcessor.getInstance()).thenReturn(scimConfigProcessor); + String tenantDomain = "carbon.super"; SCIMUserManager scimUserManager = spy(new SCIMUserManager(mockedUserStoreManager, mockClaimMetadataManagementService, tenantDomain)); doReturn(user).when(scimUserManager).getUser(anyString(), anyMap()); - Throwable expectedException = new UserStoreException(new IdentityEventException("22001", "This is a special code")); + Throwable expectedException = new UserStoreException(new IdentityEventException("42", "response to everything")); + doThrow(expectedException).when(mockedUserStoreManager).isExistingUser(anyString()); + + boolean hasExpectedBehaviour = false; + try { + scimUserManager.updateUser(user, null); + } catch (BadRequestException e) { + assertEquals(ResponseCodeConstants.INVALID_VALUE, e.getScimType()); + assertFalse("Error code shouldn't be exposed", e.getDetail().startsWith("[42] ")); + hasExpectedBehaviour = true; + } + + assertTrue("IdentityEventException is not properly handled.", hasExpectedBehaviour); + } + + @Test + public void testUpdateUserWithIdentityEventExceptionInterceptedAndExposeCode() throws Exception { + User user = new User(); + user.setUserName("newUser"); + + mockStatic(ApplicationManagementService.class); + when(ApplicationManagementService.getInstance()).thenReturn(applicationManagementService); + when(applicationManagementService.getServiceProvider(anyString(), anyString())).thenReturn(null); + + mockStatic(SCIMConfigProcessor.class); + SCIMConfigProcessor scimConfigProcessor = new SCIMConfigProcessor(); + IdentityEventExceptionSettings ieeSettings = scimConfigProcessor.getIdentityEventExceptionSettings(); + ieeSettings.setExposeErrorCodeInMessage(true); + ieeSettings.getBadRequestErrorCodes().add("42"); + when(SCIMConfigProcessor.getInstance()).thenReturn(scimConfigProcessor); + + String tenantDomain = "carbon.super"; + SCIMUserManager scimUserManager = spy(new SCIMUserManager(mockedUserStoreManager, + mockClaimMetadataManagementService, tenantDomain)); + doReturn(user).when(scimUserManager).getUser(anyString(), anyMap()); + Throwable expectedException = new UserStoreException(new IdentityEventException("42", "response to everything")); doThrow(expectedException).when(mockedUserStoreManager).isExistingUser(anyString()); boolean hasExpectedBehaviour = false; @@ -702,6 +753,7 @@ public void testUpdateUserWithIdentityEventExceptionIntercepted() throws Excepti scimUserManager.updateUser(user, null); } catch (BadRequestException e) { assertEquals(ResponseCodeConstants.INVALID_VALUE, e.getScimType()); + assertTrue("Error code should be exposed", e.getDetail().startsWith("[42] ")); hasExpectedBehaviour = true; }