From 852ff2b0b0a646b01c3988dbce5a3e058f62f3f6 Mon Sep 17 00:00:00 2001 From: Thisara-Welmilla Date: Tue, 12 Dec 2023 15:16:10 +0530 Subject: [PATCH] Improve JIT provisioning --- ...ProvisioningPostAuthenticationHandler.java | 58 ++++++++++++------- ...isioningPostAuthenticationHandlerTest.java | 2 + 2 files changed, 39 insertions(+), 21 deletions(-) diff --git a/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/handler/request/impl/JITProvisioningPostAuthenticationHandler.java b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/handler/request/impl/JITProvisioningPostAuthenticationHandler.java index c34c25a0c511..d67d7424587b 100644 --- a/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/handler/request/impl/JITProvisioningPostAuthenticationHandler.java +++ b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/handler/request/impl/JITProvisioningPostAuthenticationHandler.java @@ -207,28 +207,8 @@ private PostAuthnHandlerFlowStatus handleResponseFlow(HttpServletRequest request externalIdPConfigName, context, localClaimValues, externalIdPConfig); if (context.getProperty(FrameworkConstants.CHANGING_USERNAME_ALLOWED) != null) { username = request.getParameter(FrameworkConstants.USERNAME); - try { - /* - Checks whether the provided user is already existing in the system. If so an exception - will be thrown. - */ - UserRealm realm = getUserRealm(context.getTenantDomain()); - UserStoreManager userStoreManager = getUserStoreManager(context.getExternalIdP() - .getProvisioningUserStoreId(), realm, username); - String sanitizedUserName = UserCoreUtil.removeDomainFromName( - MultitenantUtils.getTenantAwareUsername(username)); - if (userStoreManager.isExistingUser(sanitizedUserName)) { - // Logging the error because the thrown exception is handled in the UI. - log.error(ErrorMessages.USER_ALREADY_EXISTS_ERROR.getCode() + " - " - + ErrorMessages.USER_ALREADY_EXISTS_ERROR.getMessage()); - handleExceptions(ErrorMessages.USER_ALREADY_EXISTS_ERROR.getMessage(), - "provided.username.already.exists", null); - } - } catch (UserStoreException e) { - handleExceptions(ErrorMessages.ERROR_WHILE_CHECKING_USERNAME_EXISTENCE.getMessage(), - "error.user.existence", e); - } } + isUsernameExists(context, username); callDefaultProvisioningHandler(username, context, externalIdPConfig, combinedLocalClaims, stepConfig); handleConsents(request, stepConfig, context.getTenantDomain()); @@ -353,6 +333,9 @@ private PostAuthnHandlerFlowStatus handleRequestFlow(HttpServletRequest request, username, request); // Set the property to make sure the request is a returning one. context.setProperty(FrameworkConstants.PASSWORD_PROVISION_REDIRECTION_TRIGGERED, true); + if (!externalIdPConfig.isModifyUserNameAllowed()) { + isUsernameExists(context, username); + } return PostAuthnHandlerFlowStatus.INCOMPLETE; } if (StringUtils.isEmpty(associatedLocalUser) && externalIdPConfig.isAssociateLocalUserEnabled()) { @@ -428,6 +411,9 @@ private PostAuthnHandlerFlowStatus handleRequestFlow(HttpServletRequest request, localClaimValues.get(EMAIL_ADDRESS_CLAIM))) { username = UserCoreUtil.addTenantDomainToEntry(username, context.getTenantDomain()); } + if (StringUtils.isEmpty(associatedLocalUser)) { + isUsernameExists(context, username); + } callDefaultProvisioningHandler(username, context, externalIdPConfig, localClaimValues, stepConfig); } @@ -1159,4 +1145,34 @@ private String getUserStoreDomain(String provisioningUserStoreId, UserRealm real } return userStoreDomain; } + + /** + * This method throws a PostAuthenticationFailedException if the provided username is already existing in the + * system. + * + * @param context AuthenticationContext. + * @param username Username of the federated user. + * @throws PostAuthenticationFailedException if the provided username already exists. + */ + private void isUsernameExists(AuthenticationContext context, String username) + throws PostAuthenticationFailedException { + + try { + UserRealm realm = getUserRealm(context.getTenantDomain()); + UserStoreManager userStoreManager = getUserStoreManager(context.getExternalIdP() + .getProvisioningUserStoreId(), realm, username); + String sanitizedUserName = UserCoreUtil.removeDomainFromName( + MultitenantUtils.getTenantAwareUsername(username)); + if (userStoreManager.isExistingUser(sanitizedUserName)) { + // Logging the error because the thrown exception is handled in the UI. + log.error(ErrorMessages.USER_ALREADY_EXISTS_ERROR.getCode() + " - " + + ErrorMessages.USER_ALREADY_EXISTS_ERROR.getMessage()); + handleExceptions(ErrorMessages.USER_ALREADY_EXISTS_ERROR.getMessage(), + ErrorMessages.USER_ALREADY_EXISTS_ERROR.getCode(), null); + } + } catch (UserStoreException e) { + handleExceptions(ErrorMessages.ERROR_WHILE_CHECKING_USERNAME_EXISTENCE.getMessage(), + "error.user.existence", e); + } + } } diff --git a/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/test/java/org/wso2/carbon/identity/application/authentication/framework/handler/request/impl/JITProvisioningPostAuthenticationHandlerTest.java b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/test/java/org/wso2/carbon/identity/application/authentication/framework/handler/request/impl/JITProvisioningPostAuthenticationHandlerTest.java index 86ec081b3eb4..5a801cd14d13 100644 --- a/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/test/java/org/wso2/carbon/identity/application/authentication/framework/handler/request/impl/JITProvisioningPostAuthenticationHandlerTest.java +++ b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/test/java/org/wso2/carbon/identity/application/authentication/framework/handler/request/impl/JITProvisioningPostAuthenticationHandlerTest.java @@ -172,6 +172,8 @@ public void testHandleWithAuthenticatedUserWithFederatedIdp() throws FrameworkEx when(mockUserStoreManager.getUserClaimValues(anyString(), eq(new String[]{FrameworkConstants.ACCOUNT_LOCKED_CLAIM_URI}), eq(UserCoreConstants.DEFAULT_PROFILE))).thenReturn(mockClaimValues); + when(mockUserStoreManager.getSecondaryUserStoreManager(anyString())).thenReturn(mockUserStoreManager); + when(mockUserStoreManager.isExistingUser(anyString())).thenReturn(false); when(mockClaimValues.get(FrameworkConstants.ACCOUNT_LOCKED_CLAIM_URI)).thenReturn("false"); // Need to mock getIdPConfigByName with a null parameter.