Search in sources :

Example 6 with UserStoreClientException

use of org.wso2.carbon.user.core.UserStoreClientException in project identity-inbound-auth-oauth by wso2-extensions.

the class PasswordGrantHandler method validateUserCredentials.

private AuthenticatedUser validateUserCredentials(OAuth2AccessTokenReqDTO tokenReq, ServiceProvider serviceProvider) throws IdentityOAuth2Exception {
    boolean isPublishPasswordGrantLoginEnabled = Boolean.parseBoolean(IdentityUtil.getProperty(PUBLISH_PASSWORD_GRANT_LOGIN));
    try {
        // Get the user store preference order supplier.
        UserStorePreferenceOrderSupplier<List<String>> userStorePreferenceOrderSupplier = FrameworkUtils.getUserStorePreferenceOrderSupplier(null, serviceProvider);
        UserMgtContext userMgtContext = new UserMgtContext();
        userMgtContext.setUserStorePreferenceOrderSupplier(userStorePreferenceOrderSupplier);
        if (userStorePreferenceOrderSupplier != null) {
            UserCoreUtil.setUserMgtContextInThreadLocal(userMgtContext);
            if (log.isDebugEnabled()) {
                log.debug("UserMgtContext had been set as the thread local.");
            }
        }
        String username = tokenReq.getResourceOwnerUsername();
        if (!IdentityUtil.isEmailUsernameValidationDisabled()) {
            FrameworkUtils.validateUsername(username);
            username = FrameworkUtils.preprocessUsername(username, serviceProvider);
        }
        String tenantAwareUserName = MultitenantUtils.getTenantAwareUsername(username);
        String userTenantDomain = MultitenantUtils.getTenantDomain(username);
        ResolvedUserResult resolvedUserResult = FrameworkUtils.processMultiAttributeLoginIdentification(tenantAwareUserName, userTenantDomain);
        String userId = null;
        if (resolvedUserResult != null && ResolvedUserResult.UserResolvedStatus.SUCCESS.equals(resolvedUserResult.getResolvedStatus())) {
            tenantAwareUserName = resolvedUserResult.getUser().getUsername();
            userId = resolvedUserResult.getUser().getUserID();
            tokenReq.setResourceOwnerUsername(tenantAwareUserName + "@" + userTenantDomain);
        }
        AbstractUserStoreManager userStoreManager = getUserStoreManager(userTenantDomain);
        AuthenticationResult authenticationResult;
        if (userId != null) {
            authenticationResult = userStoreManager.authenticateWithID(userId, tokenReq.getResourceOwnerPassword());
        } else {
            authenticationResult = userStoreManager.authenticateWithID(UserCoreClaimConstants.USERNAME_CLAIM_URI, tenantAwareUserName, tokenReq.getResourceOwnerPassword(), UserCoreConstants.DEFAULT_PROFILE);
        }
        boolean authenticated = AuthenticationResult.AuthenticationStatus.SUCCESS == authenticationResult.getAuthenticationStatus() && authenticationResult.getAuthenticatedUser().isPresent();
        if (log.isDebugEnabled()) {
            log.debug("user " + tokenReq.getResourceOwnerUsername() + " authenticated: " + authenticated);
        }
        if (authenticated) {
            AuthenticatedUser authenticatedUser = new AuthenticatedUser(authenticationResult.getAuthenticatedUser().get());
            if (isPublishPasswordGrantLoginEnabled) {
                publishAuthenticationData(tokenReq, true, serviceProvider, authenticatedUser);
            }
            return authenticatedUser;
        } else {
            if (isPublishPasswordGrantLoginEnabled) {
                publishAuthenticationData(tokenReq, false, serviceProvider);
            }
            if (MultitenantConstants.SUPER_TENANT_DOMAIN_NAME.equalsIgnoreCase(MultitenantUtils.getTenantDomain(tokenReq.getResourceOwnerUsername()))) {
                throw new IdentityOAuth2Exception("Authentication failed for " + tenantAwareUserName);
            }
            username = tokenReq.getResourceOwnerUsername();
            if (IdentityTenantUtil.isTenantQualifiedUrlsEnabled()) {
                // For tenant qualified urls, no need to send fully qualified username in response.
                username = tenantAwareUserName;
            }
            throw new IdentityOAuth2Exception("Authentication failed for " + username);
        }
    } catch (UserStoreClientException e) {
        if (isPublishPasswordGrantLoginEnabled) {
            publishAuthenticationData(tokenReq, false, serviceProvider);
        }
        String message = e.getMessage();
        if (StringUtils.isNotBlank(e.getErrorCode())) {
            message = e.getErrorCode() + " " + e.getMessage();
        }
        throw new IdentityOAuth2Exception(message, e);
    } catch (UserStoreException e) {
        if (isPublishPasswordGrantLoginEnabled) {
            publishAuthenticationData(tokenReq, false, serviceProvider);
        }
        String message = e.getMessage();
        // Sometimes client exceptions are wrapped in the super class.
        // Therefore, checking for possible client exception.
        Throwable rootCause = ExceptionUtils.getRootCause(e);
        if (rootCause instanceof UserStoreClientException) {
            message = rootCause.getMessage();
            String errorCode = ((UserStoreClientException) rootCause).getErrorCode();
            if (StringUtils.isNotBlank(errorCode)) {
                message = errorCode + " " + message;
            }
        }
        if (e.getCause() instanceof IdentityException) {
            IdentityException identityException = (IdentityException) (e.getCause());
            // Set error code to message if available.
            if (StringUtils.isNotBlank(identityException.getErrorCode())) {
                message = identityException.getErrorCode() + " " + e.getMessage();
            }
        }
        throw new IdentityOAuth2Exception(message, e);
    } catch (AuthenticationFailedException e) {
        String message = "Authentication failed for the user: " + tokenReq.getResourceOwnerUsername();
        if (log.isDebugEnabled()) {
            log.debug(message, e);
        }
        throw new IdentityOAuth2Exception(message);
    } finally {
        UserCoreUtil.removeUserMgtContextInThreadLocal();
        if (log.isDebugEnabled()) {
            log.debug("UserMgtContext had been remove from the thread local.");
        }
    }
}
Also used : UserMgtContext(org.wso2.carbon.user.core.model.UserMgtContext) UserStoreClientException(org.wso2.carbon.user.core.UserStoreClientException) AuthenticationFailedException(org.wso2.carbon.identity.application.authentication.framework.exception.AuthenticationFailedException) IdentityException(org.wso2.carbon.identity.base.IdentityException) AuthenticatedUser(org.wso2.carbon.identity.application.authentication.framework.model.AuthenticatedUser) AuthenticationResult(org.wso2.carbon.user.core.common.AuthenticationResult) IdentityOAuth2Exception(org.wso2.carbon.identity.oauth2.IdentityOAuth2Exception) UserStoreException(org.wso2.carbon.user.api.UserStoreException) List(java.util.List) AbstractUserStoreManager(org.wso2.carbon.user.core.common.AbstractUserStoreManager) ResolvedUserResult(org.wso2.carbon.identity.multi.attribute.login.mgt.ResolvedUserResult)

Example 7 with UserStoreClientException

use of org.wso2.carbon.user.core.UserStoreClientException in project identity-inbound-provisioning-scim2 by wso2-extensions.

the class SCIMUserOperationListener method validateClaimUpdate.

/**
 * Validate whether the claim update request is from a provisioned user.
 *
 * @param username Username.
 * @throws UserStoreException if an error occurred while retrieving the user claim list.
 */
private void validateClaimUpdate(String username) throws UserStoreException {
    boolean isAttributeSyncingEnabled = true;
    /*
        If attribute syncing is disabled, blocking the attribute editing is not required.
        ToDo: There should be an option to disable attribute syncing.
        (https://github.com/wso2/product-is/issues/12414)
         */
    if (!isAttributeSyncingEnabled) {
        return;
    }
    /*
        Check whether this is an attribute syncing flow by checking the PROVISIONED_USER thread local property.
        If it is an attribute syncing flow, blocking the attribute editing is not required.
         */
    if (IdentityUtil.threadLocalProperties.get().get(FrameworkConstants.JIT_PROVISIONING_FLOW) != null && (Boolean) IdentityUtil.threadLocalProperties.get().get(FrameworkConstants.JIT_PROVISIONING_FLOW)) {
        return;
    }
    boolean isExistingJITProvisionedUser;
    try {
        isExistingJITProvisionedUser = UserSessionStore.getInstance().isExistingUser(username);
    } catch (UserSessionException e) {
        throw new UserStoreException("Error while checking the federated user existence for the user: " + username);
    }
    // If federated user is already provisioned, block that user's synced attribute editing.
    if (isExistingJITProvisionedUser) {
        throw new UserStoreClientException(SCIMCommonConstants.ErrorMessages.ERROR_CODE_INVALID_ATTRIBUTE_UPDATE.getMessage(), SCIMCommonConstants.ErrorMessages.ERROR_CODE_INVALID_ATTRIBUTE_UPDATE.getCode());
    }
}
Also used : UserStoreClientException(org.wso2.carbon.user.core.UserStoreClientException) UserStoreException(org.wso2.carbon.user.core.UserStoreException) UserSessionException(org.wso2.carbon.identity.application.authentication.framework.exception.UserSessionException)

Example 8 with UserStoreClientException

use of org.wso2.carbon.user.core.UserStoreClientException in project identity-inbound-provisioning-scim2 by wso2-extensions.

the class SCIMUserManager method listGroups.

/**
 * List all the groups.
 *
 * @param startIndex         Start index in the request.
 * @param count              Limit in the request.
 * @param sortBy             SortBy
 * @param sortOrder          Sorting order
 * @param domainName         Domain Name
 * @param requiredAttributes Required attributes
 * @return List of groups.
 * @throws CharonException If an error occurred.
 * @throws BadRequestException If an error occurred.
 */
private List<Object> listGroups(int startIndex, Integer count, String sortBy, String sortOrder, String domainName, Map<String, Boolean> requiredAttributes) throws CharonException, BadRequestException {
    List<Object> groupList = new ArrayList<>();
    // 0th index is to store total number of results.
    groupList.add(0);
    try {
        Set<String> groupNames;
        if (carbonUM.isRoleAndGroupSeparationEnabled()) {
            groupNames = getGroupNamesForGroupsEndpoint(domainName);
        } else {
            groupNames = getRoleNamesForGroupsEndpoint(domainName);
        }
        for (String groupName : groupNames) {
            String userStoreDomainName = IdentityUtil.extractDomainFromName(groupName);
            if (isInternalOrApplicationGroup(userStoreDomainName) || isSCIMEnabled(userStoreDomainName)) {
                if (log.isDebugEnabled()) {
                    log.debug(String.format("SCIM is enabled for the user-store domain: %s. Including group with " + "name: %s in the response.", userStoreDomainName, groupName));
                }
                Group group;
                if (!isMemberAttributeRequired(requiredAttributes)) {
                    group = getGroupWithoutMembers(groupName);
                } else {
                    group = getGroupWithName(groupName);
                }
                if (group.getId() != null) {
                    groupList.add(group);
                }
            } else {
                if (log.isDebugEnabled()) {
                    log.debug(String.format("SCIM is disabled for the user-store domain: %s. Hence " + "group with name: %s is excluded in the response.", userStoreDomainName, groupName));
                }
            }
        }
    } catch (UserStoreClientException e) {
        String errorMessage = String.format("Error in obtaining role names from user store. %s", e.getMessage());
        if (log.isDebugEnabled()) {
            log.debug(errorMessage, e);
        }
        throw new BadRequestException(errorMessage, ResponseCodeConstants.INVALID_VALUE);
    } catch (org.wso2.carbon.user.core.UserStoreException e) {
        // Sometimes client exceptions are wrapped in the super class.
        // Therefore checking for possible client exception.
        Throwable ex = ExceptionUtils.getRootCause(e);
        if (ex instanceof UserStoreClientException) {
            String errorMessage = String.format("Error in obtaining role names from user store. %s", ex.getMessage());
            if (log.isDebugEnabled()) {
                log.debug(errorMessage, ex);
            }
            throw new BadRequestException(errorMessage, ResponseCodeConstants.INVALID_VALUE);
        }
        String errMsg = "Error in obtaining role names from user store.";
        errMsg += e.getMessage();
        throw resolveError(e, errMsg);
    } catch (org.wso2.carbon.user.api.UserStoreException e) {
        String errMsg = "Error in retrieving role names from user store.";
        throw resolveError(e, errMsg);
    } catch (IdentitySCIMException | BadRequestException e) {
        throw new CharonException("Error in retrieving SCIM Group information from database.", e);
    }
    // Set the totalResults value in index 0.
    groupList.set(0, groupList.size() - 1);
    return groupList;
}
Also used : Group(org.wso2.charon3.core.objects.Group) UserStoreClientException(org.wso2.carbon.user.core.UserStoreClientException) UserStoreException(org.wso2.carbon.user.api.UserStoreException) ArrayList(java.util.ArrayList) IdentitySCIMException(org.wso2.carbon.identity.scim2.common.exceptions.IdentitySCIMException) BadRequestException(org.wso2.charon3.core.exceptions.BadRequestException) CharonException(org.wso2.charon3.core.exceptions.CharonException)

Example 9 with UserStoreClientException

use of org.wso2.carbon.user.core.UserStoreClientException in project identity-inbound-provisioning-scim2 by wso2-extensions.

the class SCIMUserManager method createUser.

@Override
public User createUser(User user, Map<String, Boolean> requiredAttributes) throws CharonException, ConflictException, BadRequestException, ForbiddenException {
    String userStoreName = null;
    try {
        String userStoreDomainFromSP = getUserStoreDomainFromSP();
        if (userStoreDomainFromSP != null) {
            userStoreName = userStoreDomainFromSP;
        }
    } catch (IdentityApplicationManagementException e) {
        throw new CharonException("Error retrieving User Store name. ", e);
    }
    StringBuilder userName = new StringBuilder();
    if (StringUtils.isNotBlank(userStoreName)) {
        // If we have set a user store under provisioning configuration - we should only use that.
        String currentUserName = user.getUserName();
        currentUserName = UserCoreUtil.removeDomainFromName(currentUserName);
        user.setUserName(userName.append(userStoreName).append(CarbonConstants.DOMAIN_SEPARATOR).append(currentUserName).toString());
    }
    String userStoreDomainName = IdentityUtil.extractDomainFromName(user.getUserName());
    if (!user.getUserName().contains(CarbonConstants.DOMAIN_SEPARATOR) && !UserCoreConstants.PRIMARY_DEFAULT_DOMAIN_NAME.equalsIgnoreCase(userStoreDomainName)) {
        user.setUserName(IdentityUtil.addDomainToName(user.getUserName(), userStoreDomainName));
    }
    if (StringUtils.isNotBlank(userStoreDomainName) && !isSCIMEnabled(userStoreDomainName)) {
        throw new CharonException("Cannot add user through scim to user store " + ". SCIM is not " + "enabled for user store " + userStoreDomainName);
    }
    try {
        // Persist in carbon user store.
        if (log.isDebugEnabled()) {
            log.debug("Creating user: " + user.getUserName());
        }
        // Remove the existing SCIM id attribute as we are going to use the one generated from the user core.
        user.getAttributeList().remove(SCIMConstants.CommonSchemaConstants.ID);
        // Set thread local property to signal the downstream SCIMUserOperationListener
        // about the provisioning route.
        SCIMCommonUtils.setThreadLocalIsManagedThroughSCIMEP(true);
        Map<String, String> claimsMap = AttributeMapper.getClaimsMap(user);
        // Skip groups attribute since we map groups attribute to actual groups in ldap.
        // and do not update it as an attribute in user schema.
        claimsMap.remove(SCIMConstants.UserSchemaConstants.GROUP_URI);
        // changes must be applied via Group Resource.
        if (claimsMap.containsKey(SCIMConstants.UserSchemaConstants.ROLES_URI + "." + SCIMConstants.DEFAULT)) {
            claimsMap.remove(SCIMConstants.UserSchemaConstants.ROLES_URI);
        }
        // If we have the user id, we can check the user from it instead of username.
        boolean isExistingUser = false;
        if (StringUtils.isNotEmpty(user.getId())) {
            isExistingUser = carbonUM.isExistingUserWithID(user.getId());
        } else {
            if (isLoginIdentifiersEnabled() && StringUtils.isNotBlank(getPrimaryLoginIdentifierClaim())) {
                String[] existingUserList = carbonUM.getUserList(getPrimaryLoginIdentifierClaim(), UserCoreUtil.removeDomainFromName(user.getUserName()), null);
                if (ArrayUtils.isNotEmpty(existingUserList)) {
                    isExistingUser = true;
                }
            } else {
                isExistingUser = carbonUM.isExistingUser(user.getUserName());
            }
        }
        if (isExistingUser) {
            String error = "User with the name: " + user.getUserName() + " already exists in the system.";
            throw new ConflictException(error);
        }
        claimsMap.remove(SCIMConstants.UserSchemaConstants.USER_NAME_URI);
        Map<String, String> claimsInLocalDialect = SCIMCommonUtils.convertSCIMtoLocalDialect(claimsMap);
        org.wso2.carbon.user.core.common.User coreUser = null;
        /*Provide a preferred primary login identifier.Generate a unique user id as the immutable identifier of
             the user instead of human readable username. The primary login identifier claim value will be the
             human readable username.*/
        if (isLoginIdentifiersEnabled()) {
            String immutableUserIdentifier = getUniqueUserID();
            String primaryLoginIdentifier = getPrimaryLoginIdentifierClaim();
            if (StringUtils.isNotBlank(primaryLoginIdentifier)) {
                if (claimsInLocalDialect.containsKey(primaryLoginIdentifier)) {
                    if (claimsInLocalDialect.get(primaryLoginIdentifier).equals(UserCoreUtil.removeDomainFromName(user.getUserName()))) {
                        coreUser = carbonUM.addUserWithID(immutableUserIdentifier, user.getPassword(), null, claimsInLocalDialect, null);
                    } else {
                        throw new BadRequestException("The claim value for " + primaryLoginIdentifier + " " + "and username should be same.");
                    }
                } else {
                    claimsInLocalDialect.put(getPrimaryLoginIdentifierClaim(), UserCoreUtil.removeDomainFromName(user.getUserName()));
                    coreUser = carbonUM.addUserWithID(immutableUserIdentifier, user.getPassword(), null, claimsInLocalDialect, null);
                }
            }
        } else {
            // Create the user in the user core.
            coreUser = carbonUM.addUserWithID(user.getUserName(), user.getPassword(), null, claimsInLocalDialect, null);
        }
        if (coreUser == null) {
            coreUser = carbonUM.getUser(null, user.getUserName());
            // engagement exists. Please check issue : https://github.com/wso2/product-is/issues/10442
            if (coreUser != null && StringUtils.isBlank(coreUser.getUserID())) {
                return user;
            }
        }
        // We use the generated unique ID of the user core user as the SCIM ID.
        user.setId(coreUser.getUserID());
        if (log.isDebugEnabled()) {
            log.debug("User: " + user.getUserName() + " and with ID " + user.getId() + "  is created through SCIM.");
        }
        // Get Claims related to SCIM claim dialect
        Map<String, String> scimToLocalClaimsMap = SCIMCommonUtils.getSCIMtoLocalMappings();
        // Get required SCIM Claims in local claim dialect.
        List<String> requiredClaimsInLocalDialect = getRequiredClaimsInLocalDialect(scimToLocalClaimsMap, requiredAttributes);
        // Get the user from the user store in order to get the default attributes during the user creation
        // response.
        user = this.getSCIMUser(coreUser, requiredClaimsInLocalDialect, scimToLocalClaimsMap, claimsInLocalDialect);
        // Set the schemas of the SCIM user.
        user.setSchemas(this);
    } catch (UserStoreClientException e) {
        String errorMessage = String.format("Error in adding the user: " + user.getUserName() + ". %s", e.getMessage());
        if (log.isDebugEnabled()) {
            log.debug(errorMessage, e);
        }
        if (isResourceLimitReachedError(e)) {
            handleResourceLimitReached();
        }
        throw new BadRequestException(errorMessage, ResponseCodeConstants.INVALID_VALUE);
    } catch (UserStoreException e) {
        // Sometimes client exceptions are wrapped in the super class.
        // Therefore checking for possible client exception.
        Throwable ex = ExceptionUtils.getRootCause(e);
        if (ex instanceof UserStoreClientException) {
            String errorMessage = String.format("Error in adding the user: " + user.getUserName() + ". %s", ex.getMessage());
            if (log.isDebugEnabled()) {
                log.debug(errorMessage, ex);
            }
            if (isResourceLimitReachedError((UserStoreClientException) ex)) {
                handleResourceLimitReached();
            }
            throw new BadRequestException(errorMessage, ResponseCodeConstants.INVALID_VALUE);
        }
        handleErrorsOnUserNameAndPasswordPolicy(e);
    } catch (NotImplementedException e) {
        throw new CharonException("Error in getting user information from Carbon User Store", e);
    }
    return user;
}
Also used : ConflictException(org.wso2.charon3.core.exceptions.ConflictException) UserStoreClientException(org.wso2.carbon.user.core.UserStoreClientException) IdentityApplicationManagementException(org.wso2.carbon.identity.application.common.IdentityApplicationManagementException) NotImplementedException(org.wso2.charon3.core.exceptions.NotImplementedException) UserStoreException(org.wso2.carbon.user.api.UserStoreException) SCIMUserStoreException(org.wso2.carbon.identity.scim2.common.extenstion.SCIMUserStoreException) BadRequestException(org.wso2.charon3.core.exceptions.BadRequestException) CharonException(org.wso2.charon3.core.exceptions.CharonException)

Example 10 with UserStoreClientException

use of org.wso2.carbon.user.core.UserStoreClientException in project identity-inbound-provisioning-scim2 by wso2-extensions.

the class SCIMUserManager method updateUser.

@Override
public User updateUser(User user, Map<String, Boolean> requiredAttributes) throws CharonException, BadRequestException {
    try {
        if (log.isDebugEnabled()) {
            log.debug("Updating user: " + user.getUserName());
        }
        // Set thread local property to signal the downstream SCIMUserOperationListener
        // about the provisioning route.
        SCIMCommonUtils.setThreadLocalIsManagedThroughSCIMEP(true);
        // get user claim values
        Map<String, String> claims = AttributeMapper.getClaimsMap(user);
        // Check if username of the updating user existing in the userstore.
        try {
            String userStoreDomainFromSP = getUserStoreDomainFromSP();
            SCIMResourceTypeSchema schema = SCIMResourceSchemaManager.getInstance().getUserResourceSchema();
            User oldUser = this.getUser(user.getId(), ResourceManagerUtil.getAllAttributeURIs(schema));
            if (userStoreDomainFromSP != null && !userStoreDomainFromSP.equalsIgnoreCase(IdentityUtil.extractDomainFromName(oldUser.getUserName()))) {
                throw new CharonException("User :" + oldUser.getUserName() + "is not belong to user store " + userStoreDomainFromSP + "Hence user updating fail");
            }
            if (getUserStoreDomainFromSP() != null && !UserCoreConstants.PRIMARY_DEFAULT_DOMAIN_NAME.equalsIgnoreCase(getUserStoreDomainFromSP())) {
                user.setUserName(IdentityUtil.addDomainToName(UserCoreUtil.removeDomainFromName(user.getUserName()), getUserStoreDomainFromSP()));
            }
            String username = user.getUsername();
            String oldUsername = oldUser.getUsername();
            if (!IdentityUtil.isUserStoreInUsernameCaseSensitive(oldUser.getUsername())) {
                username = username.toLowerCase();
                oldUsername = oldUsername.toLowerCase();
            }
            /*If primary login identifier configuration is enabled,username value can be another claim and it
                could be modifiable.*/
            if (!(isLoginIdentifiersEnabled() && StringUtils.isNotBlank(getPrimaryLoginIdentifierClaim()))) {
                // This is handled here as the IS is still not capable of updating the username via SCIM.
                if (!StringUtils.equals(username, oldUsername)) {
                    if (log.isDebugEnabled()) {
                        log.debug("Failing the request as attempting to modify username. Old username: " + oldUser.getUserName() + ", new username: " + user.getUserName());
                    }
                    throw new BadRequestException("Attribute userName cannot be modified.", ResponseCodeConstants.MUTABILITY);
                }
            }
        } catch (IdentityApplicationManagementException e) {
            throw new CharonException("Error retrieving User Store name. ", e);
        }
        boolean isExistingUser;
        if (StringUtils.isNotEmpty(user.getId())) {
            isExistingUser = carbonUM.isExistingUserWithID(user.getId());
        } else {
            isExistingUser = carbonUM.isExistingUser(user.getUserName());
        }
        if (!isExistingUser) {
            throw new CharonException("User name is immutable in carbon user store.");
        }
        // Skip groups attribute since we map groups attribute to actual groups in ldap.
        // and do not update it as an attribute in user schema.
        claims.remove(SCIMConstants.UserSchemaConstants.GROUP_URI);
        // changes must be applied via Group Resource.
        if (claims.containsKey(SCIMConstants.UserSchemaConstants.ROLES_URI + "." + SCIMConstants.DEFAULT)) {
            claims.remove(SCIMConstants.UserSchemaConstants.ROLES_URI);
        }
        claims.remove(SCIMConstants.UserSchemaConstants.USER_NAME_URI);
        // Since we are already populating last_modified claim value from SCIMUserOperationListener, we need to
        // remove this claim value which is coming from charon-level.
        claims.remove(SCIMConstants.CommonSchemaConstants.LAST_MODIFIED_URI);
        // Location is a meta attribute of user object.
        claims.remove(SCIMConstants.CommonSchemaConstants.LOCATION_URI);
        // Resource-Type is a meta attribute of user object.
        claims.remove(SCIMConstants.CommonSchemaConstants.RESOURCE_TYPE_URI);
        Map<String, String> scimToLocalClaimsMap = SCIMCommonUtils.getSCIMtoLocalMappings();
        List<String> requiredClaims = getOnlyRequiredClaims(scimToLocalClaimsMap.keySet(), requiredAttributes);
        List<String> requiredClaimsInLocalDialect;
        if (MapUtils.isNotEmpty(scimToLocalClaimsMap)) {
            scimToLocalClaimsMap.keySet().retainAll(requiredClaims);
            requiredClaimsInLocalDialect = new ArrayList<>(scimToLocalClaimsMap.values());
        } else {
            if (log.isDebugEnabled()) {
                log.debug("SCIM to Local Claim mappings list is empty.");
            }
            requiredClaimsInLocalDialect = new ArrayList<>();
        }
        // Get existing user claims.
        Map<String, String> oldClaimList = carbonUM.getUserClaimValuesWithID(user.getId(), requiredClaimsInLocalDialect.toArray(new String[0]), null);
        oldClaimList.remove(LOCATION_CLAIM);
        oldClaimList.remove(LAST_MODIFIED_CLAIM);
        oldClaimList.remove(RESOURCE_TYPE_CLAIM);
        // Get user claims mapped from SCIM dialect to WSO2 dialect.
        Map<String, String> claimValuesInLocalDialect = SCIMCommonUtils.convertSCIMtoLocalDialect(claims);
        // If the primary login identifier claim is enabled, pass that as a claim for userstoremanger.
        if (isLoginIdentifiersEnabled() && StringUtils.isNotBlank(getPrimaryLoginIdentifierClaim())) {
            claimValuesInLocalDialect.put(getPrimaryLoginIdentifierClaim(), UserCoreUtil.removeDomainFromName(user.getUsername()));
        }
        // If password is updated, set it separately.
        if (user.getPassword() != null) {
            carbonUM.updateCredentialByAdminWithID(user.getId(), user.getPassword());
        }
        updateUserClaims(user, oldClaimList, claimValuesInLocalDialect);
        if (log.isDebugEnabled()) {
            log.debug("User: " + user.getUserName() + " updated through SCIM.");
        }
        return getUser(user.getId(), requiredAttributes);
    } catch (UserStoreClientException e) {
        String errorMessage = String.format("Error while updating attributes of user. %s", e.getMessage());
        if (log.isDebugEnabled()) {
            log.debug(errorMessage, e);
        }
        throw new BadRequestException(errorMessage, ResponseCodeConstants.INVALID_VALUE);
    } catch (UserStoreException e) {
        String errMsg = "Error while updating attributes of user: " + user.getUserName();
        log.error(errMsg, e);
        // Sometimes client exceptions are wrapped in the super class.
        // Therefore checking for possible client exception.
        Throwable ex = ExceptionUtils.getRootCause(e);
        if (ex instanceof UserStoreClientException) {
            String errorMessage = String.format("Error while updating attributes of user. %s", ex.getMessage());
            if (log.isDebugEnabled()) {
                log.debug(errorMessage, ex);
            }
            throw new BadRequestException(errorMessage, ResponseCodeConstants.INVALID_VALUE);
        }
        handleErrorsOnUserNameAndPasswordPolicy(e);
        if (isNotifyUserstoreStatusEnabled()) {
            throw resolveError(e, errMsg + ". " + e.getMessage());
        } else {
            throw resolveError(e, errMsg);
        }
    } catch (BadRequestException e) {
        // This is needed as most BadRequests are thrown to charon as
        // CharonExceptions but if there are any bad requests handled
        // due to MUTABILITY at this level we need to properly notify
        // the end party.
        reThrowMutabilityBadRequests(e);
        log.error("Error occurred while trying to update the user", e);
        throw new CharonException("Error occurred while trying to update the user", e);
    } catch (CharonException e) {
        log.error("Error occurred while trying to update the user", e);
        throw new CharonException("Error occurred while trying to update the user", e);
    }
}
Also used : User(org.wso2.charon3.core.objects.User) UserStoreClientException(org.wso2.carbon.user.core.UserStoreClientException) IdentityApplicationManagementException(org.wso2.carbon.identity.application.common.IdentityApplicationManagementException) UserStoreException(org.wso2.carbon.user.api.UserStoreException) SCIMUserStoreException(org.wso2.carbon.identity.scim2.common.extenstion.SCIMUserStoreException) BadRequestException(org.wso2.charon3.core.exceptions.BadRequestException) SCIMResourceTypeSchema(org.wso2.charon3.core.schema.SCIMResourceTypeSchema) CharonException(org.wso2.charon3.core.exceptions.CharonException)

Aggregations

UserStoreException (org.wso2.carbon.user.api.UserStoreException)15 UserStoreClientException (org.wso2.carbon.user.core.UserStoreClientException)11 IdentityUserStoreMgtException (org.wso2.carbon.identity.user.store.configuration.utils.IdentityUserStoreMgtException)8 SecondaryUserStoreConfigurationUtil.buildIdentityUserStoreClientException (org.wso2.carbon.identity.user.store.configuration.utils.SecondaryUserStoreConfigurationUtil.buildIdentityUserStoreClientException)8 UserStoreClientException (org.wso2.carbon.user.api.UserStoreClientException)8 IdentityUserStoreClientException (org.wso2.carbon.identity.user.store.configuration.utils.IdentityUserStoreClientException)6 BadRequestException (org.wso2.charon3.core.exceptions.BadRequestException)6 CharonException (org.wso2.charon3.core.exceptions.CharonException)5 AuthenticatedUser (org.wso2.carbon.identity.application.authentication.framework.model.AuthenticatedUser)4 SCIMUserStoreException (org.wso2.carbon.identity.scim2.common.extenstion.SCIMUserStoreException)4 User (org.wso2.charon3.core.objects.User)4 ArrayList (java.util.ArrayList)3 Map (java.util.Map)3 AuthenticationFailedException (org.wso2.carbon.identity.application.authentication.framework.exception.AuthenticationFailedException)3 IdentityApplicationManagementException (org.wso2.carbon.identity.application.common.IdentityApplicationManagementException)3 AbstractUserStoreDAOFactory (org.wso2.carbon.identity.user.store.configuration.dao.AbstractUserStoreDAOFactory)3 AbstractUserStoreManager (org.wso2.carbon.user.core.common.AbstractUserStoreManager)3 Path (java.nio.file.Path)2 StepConfig (org.wso2.carbon.identity.application.authentication.framework.config.model.StepConfig)2 FrameworkException (org.wso2.carbon.identity.application.authentication.framework.exception.FrameworkException)2