use of org.wso2.carbon.identity.scim2.common.utils.SCIMCommonUtils in project identity-inbound-provisioning-scim2 by wso2-extensions.
the class SCIMUserManager method getSCIMUsers.
/**
* get the specified user from the store
*
* @param users Set of users.
* @param claimURIList Requested claim list.
* @param scimToLocalClaimsMap SCIM to local claims mappings.
* @param requiredAttributes Attributes required.
* @return Array of SCIM User
* @throws CharonException CharonException
*/
private Set<User> getSCIMUsers(Set<org.wso2.carbon.user.core.common.User> users, List<String> claimURIList, Map<String, String> scimToLocalClaimsMap, Map<String, Boolean> requiredAttributes) throws CharonException {
List<User> scimUsers = new ArrayList<>();
// obtain user claim values
List<UniqueIDUserClaimSearchEntry> searchEntries;
Map<String, List<String>> usersRoles = new HashMap<>();
try {
searchEntries = carbonUM.getUsersClaimValuesWithID(users.stream().map(org.wso2.carbon.user.core.common.User::getUserID).collect(Collectors.toList()), claimURIList, null);
if (isGroupsAttributeRequired(requiredAttributes)) {
if (IdentityUtil.isGroupsVsRolesSeparationImprovementsEnabled()) {
usersRoles = searchEntries.stream().map(userClaimSearchEntry -> {
String userID = userClaimSearchEntry.getUser().getUserID();
List<String> groupsList = getGroups(userClaimSearchEntry);
return new AbstractMap.SimpleEntry<>(userID, groupsList);
}).collect(Collectors.toMap(AbstractMap.SimpleEntry::getKey, AbstractMap.SimpleEntry::getValue));
} else {
usersRoles = carbonUM.getRoleListOfUsersWithID(users.stream().map(org.wso2.carbon.user.core.common.User::getUserID).collect(Collectors.toList()));
}
}
} catch (org.wso2.carbon.user.core.UserStoreException e) {
String errorMsg = "Error occurred while retrieving SCIM user information";
throw resolveError(e, errorMsg);
}
Map<String, Group> groupMetaAttributesCache = new HashMap<>();
for (org.wso2.carbon.user.core.common.User user : users) {
String userStoreDomainName = user.getUserStoreDomain();
if (isSCIMEnabled(userStoreDomainName)) {
if (log.isDebugEnabled()) {
log.debug("SCIM is enabled for the user-store domain : " + userStoreDomainName + ". " + "Including user : " + user.getUsername() + " in the response.");
}
User scimUser;
Map<String, String> userClaimValues = new HashMap<>();
for (UniqueIDUserClaimSearchEntry entry : searchEntries) {
if (entry.getUser() != null && StringUtils.isNotBlank(entry.getUser().getUserID()) && entry.getUser().getUserID().equals(user.getUserID())) {
userClaimValues = entry.getClaims();
}
}
Map<String, String> attributes;
try {
attributes = SCIMCommonUtils.convertLocalToSCIMDialect(userClaimValues, scimToLocalClaimsMap);
} catch (UserStoreException e) {
throw resolveError(e, "Error in converting local claims to SCIM dialect for user: " + user.getUsername());
}
try {
if (!attributes.containsKey(SCIMConstants.CommonSchemaConstants.ID_URI)) {
if (log.isDebugEnabled()) {
log.debug(String.format("Skipping adding user %s with id %s as attribute %s is not " + "available.", user.getFullQualifiedUsername(), user.getUserID(), SCIMConstants.CommonSchemaConstants.ID_URI));
}
continue;
}
// skip simple type addresses claim because it is complex with sub types in the schema
if (attributes.containsKey(SCIMConstants.UserSchemaConstants.ADDRESSES_URI)) {
attributes.remove(SCIMConstants.UserSchemaConstants.ADDRESSES_URI);
}
if (IdentityUtil.isGroupsVsRolesSeparationImprovementsEnabled()) {
filterAttributes(attributes, Arrays.asList(SCIMConstants.UserSchemaConstants.ROLES_URI, SCIMConstants.UserSchemaConstants.GROUP_URI));
}
// Location URI is not available for users who created from the mgt console also location URI is not
// tenant aware, so need to update the location URI according to the tenant.
String locationURI = SCIMCommonUtils.getSCIMUserURL(attributes.get(SCIMConstants.CommonSchemaConstants.ID_URI));
attributes.put(SCIMConstants.CommonSchemaConstants.LOCATION_URI, locationURI);
if (!attributes.containsKey(SCIMConstants.CommonSchemaConstants.RESOURCE_TYPE_URI)) {
attributes.put(SCIMConstants.CommonSchemaConstants.RESOURCE_TYPE_URI, SCIMConstants.USER);
}
// Add username with domain name
if (mandateDomainForUsernamesAndGroupNamesInResponse()) {
setUserNameWithDomain(userClaimValues, attributes, user);
} else {
if (isLoginIdentifiersEnabled() && StringUtils.isNotBlank(getPrimaryLoginIdentifierClaim())) {
String primaryLoginIdentifier = userClaimValues.get(getPrimaryLoginIdentifierClaim());
if (StringUtils.isNotBlank(primaryLoginIdentifier)) {
attributes.put(SCIMConstants.UserSchemaConstants.USER_NAME_URI, primaryLoginIdentifier);
} else {
attributes.put(SCIMConstants.UserSchemaConstants.USER_NAME_URI, user.getDomainQualifiedUsername());
}
} else {
attributes.put(SCIMConstants.UserSchemaConstants.USER_NAME_URI, user.getDomainQualifiedUsername());
}
}
// construct the SCIM Object from the attributes
scimUser = (User) AttributeMapper.constructSCIMObjectFromAttributes(this, attributes, 1);
if (isGroupsAttributeRequired(requiredAttributes)) {
// Get groups of user and add it as groups attribute.
List<String> roleList = usersRoles.get(user.getUserID());
List<String> groupsList = new ArrayList<>();
if (isNotEmpty(roleList)) {
groupsList = new ArrayList<>(roleList);
} else {
if (log.isDebugEnabled()) {
log.debug(String.format("Roles not found for user %s with id %s .", user.getFullQualifiedUsername(), user.getUserID()));
}
}
if (!IdentityUtil.isGroupsVsRolesSeparationImprovementsEnabled()) {
if (carbonUM.isRoleAndGroupSeparationEnabled()) {
// Remove roles, if the role and group separation feature is enabled.
groupsList.removeIf(SCIMCommonUtils::isHybridRole);
} else {
checkForSCIMDisabledHybridRoles(groupsList);
}
}
for (String group : groupsList) {
if (UserCoreUtil.isEveryoneRole(group, carbonUM.getRealmConfiguration()) || CarbonConstants.REGISTRY_ANONNYMOUS_ROLE_NAME.equalsIgnoreCase(group)) {
// Carbon specific roles do not possess SCIM info, hence skipping them.
continue;
}
Group groupObject = groupMetaAttributesCache.get(group);
if (groupObject == null && !groupMetaAttributesCache.containsKey(group)) {
org.wso2.carbon.user.core.common.Group userGroup = carbonUM.getGroupByGroupName(UserCoreUtil.addDomainToName(group, userStoreDomainName), null);
groupObject = buildGroup(userGroup);
groupMetaAttributesCache.put(group, groupObject);
}
if (groupObject != null && isFilteringEnhancementsEnabled()) {
groupObject.setDisplayName(prependDomain(group));
}
if (groupObject != null) {
// Can be null for non SCIM groups.
scimUser.setGroup(null, groupObject);
}
}
}
// Set the roles attribute if the the role and group separation feature is enabled.
if (IdentityUtil.isGroupsVsRolesSeparationImprovementsEnabled()) {
List<String> rolesList = getRoles(searchEntries, user);
setRolesOfUser(rolesList, groupMetaAttributesCache, user, scimUser);
} else if (carbonUM.isRoleAndGroupSeparationEnabled()) {
List<String> rolesList = carbonUM.getHybridRoleListOfUser(user.getUsername(), user.getUserStoreDomain());
checkForSCIMDisabledHybridRoles(rolesList);
setRolesOfUser(rolesList, groupMetaAttributesCache, user, scimUser);
}
} catch (UserStoreException e) {
throw resolveError(e, "Error in getting user information for user: " + user.getUsername());
} catch (CharonException | NotFoundException | IdentitySCIMException | BadRequestException e) {
throw new CharonException("Error in getting user information for user: " + user.getUsername(), e);
}
if (scimUser != null) {
scimUsers.add(scimUser);
}
} else {
if (log.isDebugEnabled()) {
log.debug("SCIM is disabled for the user-store domain : " + userStoreDomainName + ". " + "Hence user : " + user.getUsername() + " in this domain is excluded in the response.");
}
}
}
if (removeDuplicateUsersInUsersResponseEnabled) {
TreeSet<User> scimUserSet = new TreeSet<>(Comparator.comparing(User::getUsername));
scimUserSet.addAll(scimUsers);
return scimUserSet;
}
Set<User> scimUserSet = new LinkedHashSet<>();
scimUserSet.addAll(scimUsers);
return scimUserSet;
}
use of org.wso2.carbon.identity.scim2.common.utils.SCIMCommonUtils in project identity-inbound-provisioning-scim2 by wso2-extensions.
the class SCIMUserManager method getSCIMUser.
/**
* get the specfied user from the store
*
* @param coreUser User of the underlying user store.
* @param claimURIList
* @return
* @throws CharonException
*/
private User getSCIMUser(org.wso2.carbon.user.core.common.User coreUser, List<String> claimURIList, Map<String, String> scimToLocalClaimsMap, Map<String, String> userClaimValues) throws CharonException {
User scimUser = null;
String userStoreDomainName = coreUser.getUserStoreDomain();
if (StringUtils.isNotBlank(userStoreDomainName) && !isSCIMEnabled(userStoreDomainName)) {
throw new CharonException("Cannot get user through SCIM to user store. SCIM is not enabled for user store: " + userStoreDomainName);
}
try {
// TODO: If we can get the updated user claim values from the add user method, we don't need to do
// this call. Please check the status of the issue: https://github.com/wso2/product-is/issues/7160
userClaimValues = carbonUM.getUserClaimValuesWithID(coreUser.getUserID(), claimURIList.toArray(new String[0]), null);
Map<String, String> attributes = SCIMCommonUtils.convertLocalToSCIMDialect(userClaimValues, scimToLocalClaimsMap);
if (!attributes.containsKey(SCIMConstants.CommonSchemaConstants.ID_URI)) {
return scimUser;
}
// Skip simple type addresses claim because it is complex with sub types in the schema.
attributes.remove(SCIMConstants.UserSchemaConstants.ADDRESSES_URI);
List<String> groupsList = null;
List<String> rolesList = null;
if (IdentityUtil.isGroupsVsRolesSeparationImprovementsEnabled()) {
// Get user groups from attributes.
groupsList = getMultiValuedAttributeList(userStoreDomainName, attributes, SCIMConstants.UserSchemaConstants.GROUP_URI);
// Add userstore domain to the group names.
groupsList = addDomainToNames(userStoreDomainName, groupsList);
// Get user roles from attributes.
rolesList = getMultiValuedAttributeList(userStoreDomainName, attributes, SCIMConstants.UserSchemaConstants.ROLES_URI + "." + SCIMConstants.DEFAULT);
checkForSCIMDisabledHybridRoles(rolesList);
// Skip groups and roles claims because they are handled separately.
filterAttributes(attributes, Arrays.asList(SCIMConstants.UserSchemaConstants.ROLES_URI, SCIMConstants.UserSchemaConstants.GROUP_URI));
} else {
// Set groups.
groupsList = new ArrayList<>(carbonUM.getRoleListOfUserWithID(coreUser.getUserID()));
if (carbonUM.isRoleAndGroupSeparationEnabled()) {
// Remove roles, if the role and group separation feature is enabled.
groupsList.removeIf(SCIMCommonUtils::isHybridRole);
// Set roles.
rolesList = carbonUM.getHybridRoleListOfUser(coreUser.getUsername(), coreUser.getUserStoreDomain());
checkForSCIMDisabledHybridRoles(rolesList);
} else {
checkForSCIMDisabledHybridRoles(groupsList);
}
}
// If primary login identifire is enabled, set the username value of scim response to that value.
if (isLoginIdentifiersEnabled() && StringUtils.isNotBlank(getPrimaryLoginIdentifierClaim())) {
String primaryLoginIdentifier = userClaimValues.get(getPrimaryLoginIdentifierClaim());
attributes.put(SCIMConstants.UserSchemaConstants.USER_NAME_URI, primaryLoginIdentifier);
} else {
// Add username with domain name.
attributes.put(SCIMConstants.UserSchemaConstants.USER_NAME_URI, coreUser.getUsername());
}
// Location URI is not available for users who created from the mgt console also location URI is not
// tenant aware, so need to update the location URI according to the tenant.
String locationURI = SCIMCommonUtils.getSCIMUserURL(attributes.get(SCIMConstants.CommonSchemaConstants.ID_URI));
attributes.put(SCIMConstants.CommonSchemaConstants.LOCATION_URI, locationURI);
if (!attributes.containsKey(SCIMConstants.CommonSchemaConstants.RESOURCE_TYPE_URI)) {
attributes.put(SCIMConstants.CommonSchemaConstants.RESOURCE_TYPE_URI, SCIMConstants.USER);
}
Map<String, Group> groupMetaAttributesCache = new HashMap<>();
// Construct the SCIM Object from the attributes.
scimUser = (User) AttributeMapper.constructSCIMObjectFromAttributes(this, attributes, 1);
// Add username with domain name.
if (mandateDomainForUsernamesAndGroupNamesInResponse()) {
// If primary login identifire is enabled, set the username value of scim response to that value.
if (isLoginIdentifiersEnabled() && StringUtils.isNotBlank(getPrimaryLoginIdentifierClaim())) {
String primaryLoginIdentifier = userClaimValues.get(getPrimaryLoginIdentifierClaim());
scimUser.setUserName(prependDomain(primaryLoginIdentifier));
} else {
scimUser.setUserName(prependDomain(coreUser.getDomainQualifiedUsername()));
}
} else {
if (isLoginIdentifiersEnabled() && StringUtils.isNotBlank(getPrimaryLoginIdentifierClaim())) {
String primaryLoginIdentifier = userClaimValues.get(getPrimaryLoginIdentifierClaim());
scimUser.setUserName(primaryLoginIdentifier);
} else {
scimUser.setUserName(coreUser.getDomainQualifiedUsername());
}
}
// Add groups of user.
for (String groupName : groupsList) {
if (UserCoreUtil.isEveryoneRole(groupName, carbonUM.getRealmConfiguration()) || CarbonConstants.REGISTRY_ANONNYMOUS_ROLE_NAME.equalsIgnoreCase(groupName)) {
// Carbon specific roles do not possess SCIM info, hence skipping them.
continue;
}
Group groupObject = groupMetaAttributesCache.get(groupName);
if (groupObject == null && !groupMetaAttributesCache.containsKey(groupName)) {
org.wso2.carbon.user.core.common.Group userGroup = carbonUM.getGroupByGroupName(UserCoreUtil.addDomainToName(groupName, userStoreDomainName), null);
groupObject = buildGroup(userGroup);
groupMetaAttributesCache.put(groupName, groupObject);
}
if (groupObject != null && isFilteringEnhancementsEnabled()) {
groupObject.setDisplayName(prependDomain(groupName));
}
if (groupObject != null) {
// can be null for non SCIM groups
scimUser.setGroup(null, groupObject);
}
}
// Set the roles attribute if the the role and group separation feature is enabled.
if (carbonUM.isRoleAndGroupSeparationEnabled()) {
setRolesOfUser(rolesList, groupMetaAttributesCache, coreUser, scimUser);
}
} catch (UserStoreException e) {
throw resolveError(e, "Error in getting user information for user: " + coreUser.getDomainQualifiedUsername());
} catch (CharonException | NotFoundException | IdentitySCIMException | BadRequestException e) {
throw new CharonException("Error in getting user information for user: " + coreUser.getDomainQualifiedUsername(), e);
}
return scimUser;
}
use of org.wso2.carbon.identity.scim2.common.utils.SCIMCommonUtils in project identity-inbound-provisioning-scim2 by wso2-extensions.
the class SCIMUserManager method filterGroupsBySingleAttribute.
/**
* Filter groups with a single attribute.
*
* @param node Expression node
* @param startIndex Starting index
* @param count Number of results required
* @param sortBy SortBy
* @param sortOrder Sorting order
* @param domainName Domain to be filtered
* @param requiredAttributes Required attributes
* @return Filtered groups
* @throws CharonException Error in Filtering
*/
private List<Object> filterGroupsBySingleAttribute(ExpressionNode node, int startIndex, int count, String sortBy, String sortOrder, String domainName, Map<String, Boolean> requiredAttributes) throws CharonException, BadRequestException {
String attributeName = node.getAttributeValue();
String filterOperation = node.getOperation();
String attributeValue = node.getValue();
if (log.isDebugEnabled()) {
log.debug("Filtering groups with filter: " + attributeName + " + " + filterOperation + " + " + attributeValue);
}
// Check whether the filter operation is supported for filtering in groups.
if (isFilteringNotSupported(filterOperation)) {
String errorMessage = "Filter operation: " + filterOperation + " is not supported for groups filtering.";
throw new CharonException(errorMessage);
}
// Resolve the domain name in request according to 'FilterUsersAndGroupsOnlyFromPrimaryDomain' or
// EnableFilteringEnhancements' properties in identity.xml or domain name embedded in the filter attribute
// value.
domainName = resolveDomain(domainName, node);
List<Object> filteredGroups = new ArrayList<>();
// 0th index is to store total number of results.
filteredGroups.add(0);
try {
List<String> groupsList = new ArrayList<>(getGroupList(node, domainName));
// Remove roles, if the role and group separation feature is enabled.
if (carbonUM.isRoleAndGroupSeparationEnabled()) {
groupsList.removeIf(SCIMCommonUtils::isHybridRole);
}
if (groupsList != null) {
for (String groupName : groupsList) {
if (groupName != null && carbonUM.isExistingRole(groupName, false)) {
// Skip internal roles.
if (CarbonConstants.REGISTRY_ANONNYMOUS_ROLE_NAME.equals(groupName) || UserCoreUtil.isEveryoneRole(groupName, carbonUM.getRealmConfiguration())) {
continue;
}
Group group = getRoleWithDefaultAttributes(groupName, requiredAttributes);
if (group != null && group.getId() != null) {
filteredGroups.add(group);
}
} else {
// Returning null will send a resource not found error to client by Charon.
filteredGroups.clear();
filteredGroups.add(0);
return filteredGroups;
}
}
}
} catch (org.wso2.carbon.user.core.UserStoreException e) {
String errorMsg = "Error in filtering groups by attribute name : " + attributeName + ", " + "attribute value : " + attributeValue + " and filter operation : " + filterOperation;
throw resolveError(e, errorMsg);
} catch (org.wso2.carbon.user.api.UserStoreException e) {
throw resolveError(e, "Error in filtering group with filter: " + attributeName + " + " + filterOperation + " + " + attributeValue);
}
// Set the totalResults value in index 0.
filteredGroups.set(0, filteredGroups.size() - 1);
return filteredGroups;
}
Aggregations