Skip to content

Commit

Permalink
Update the group last modified date on group update
Browse files Browse the repository at this point in the history
  • Loading branch information
ThaminduDilshan committed Jan 3, 2025
1 parent c457f30 commit c78c3b2
Show file tree
Hide file tree
Showing 4 changed files with 117 additions and 20 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -289,16 +289,55 @@ public void addSCIMGroupAttributesToSCIMDisabledHybridRoles(int tenantId,
}
}

/**
* @deprecated Use {@link GroupDAO#updateSCIMGroupAttributesWithUpdatedColumn(int, String, Map)} instead.
* Update SCIM group attributes.
*
* @param tenantId Tenant id.
* @param roleName Group name.
* @param attributes Attributes to be updated.
* @throws IdentitySCIMException If an error occurred while updating the attributes.
*/
@Deprecated
public void updateSCIMGroupAttributes(int tenantId, String roleName,
Map<String, String> attributes) throws IdentitySCIMException {

Connection connection = IdentityDatabaseUtil.getDBConnection();
doUpdateSCIMGroupAttributes(tenantId, roleName, attributes, SQLQueries.UPDATE_ATTRIBUTES_SQL);
}

/**
* Update SCIM group attributes.
*
* @param tenantId Tenant id.
* @param roleName Group name.
* @param attributes Attributes to be updated.
* @throws IdentitySCIMException If an error occurred while updating the attributes.
*/
public void updateSCIMGroupAttributesWithUpdatedColumn(int tenantId, String roleName,
Map<String, String> attributes)
throws IdentitySCIMException {

doUpdateSCIMGroupAttributes(tenantId, roleName, attributes, SQLQueries.UPDATE_ATTRIBUTES_SQL_NEW);
}

/**
* Do update SCIM group attributes.
*
* @param tenantId Tenant id.
* @param roleName Group name.
* @param attributes Attributes to be updated.
* @param sqlQuery SQL query to update the attributes.
* @throws IdentitySCIMException If an error occurred while updating the attributes.
*/
private void doUpdateSCIMGroupAttributes(int tenantId, String roleName, Map<String, String> attributes,
String sqlQuery) throws IdentitySCIMException {

Connection connection = IdentityDatabaseUtil.getDBConnection(true);
PreparedStatement prepStmt = null;

if (isExistingGroup(SCIMCommonUtils.getGroupNameWithDomain(roleName), tenantId)) {
try {
prepStmt = connection.prepareStatement(SQLQueries.UPDATE_ATTRIBUTES_SQL);

prepStmt = connection.prepareStatement(sqlQuery);
prepStmt.setInt(2, tenantId);
prepStmt.setString(3, roleName);

Expand All @@ -308,19 +347,16 @@ public void updateSCIMGroupAttributes(int tenantId, String roleName,
prepStmt.setString(4, entry.getKey());
prepStmt.setString(1, entry.getValue());
prepStmt.addBatch();

} else {
throw new IdentitySCIMException("Error when adding SCIM Attribute: "
+ entry.getKey()
+ " An attribute with the same name doesn't exists.");
+ entry.getKey() + " An attribute with the same name doesn't exists.");
}
}
int[] return_count = prepStmt.executeBatch();
int[] returnCount = prepStmt.executeBatch();
if (log.isDebugEnabled()) {
log.debug("No. of records updated for updating SCIM Group : " + return_count.length);
log.debug("No. of records updated for updating SCIM Group : " + returnCount.length);
}
connection.commit();

} catch (SQLException e) {
throw new IdentitySCIMException("Error updating the SCIM Group Attributes.", e);
} finally {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,10 +41,15 @@ public class SQLQueries {
public static final String CHECK_EXISTING_ATTRIBUTE_WITH_AUDIENCE_SQL =
"SELECT TENANT_ID, ROLE_NAME, ATTR_NAME FROM IDN_SCIM_GROUP WHERE IDN_SCIM_GROUP.TENANT_ID=? AND " +
"IDN_SCIM_GROUP.ROLE_NAME=? AND IDN_SCIM_GROUP.ATTR_NAME=? AND IDN_SCIM_GROUP.AUDIENCE_REF_ID=?";

@Deprecated
public static final String UPDATE_ATTRIBUTES_SQL =
"UPDATE IDN_SCIM_GROUP SET UM_ATTR_VALUE=? WHERE TENANT_ID=? AND ROLE_NAME=? AND ATTR_NAME=?";
public static final String UPDATE_ATTRIBUTES_SQL_NEW =
"UPDATE IDN_SCIM_GROUP SET ATTR_VALUE=? WHERE TENANT_ID=? AND ROLE_NAME=? AND ATTR_NAME=?";
public static final String UPDATE_GROUP_NAME_SQL =
"UPDATE IDN_SCIM_GROUP SET ROLE_NAME=? WHERE TENANT_ID=? AND ROLE_NAME=?";

public static final String DELETE_GROUP_SQL =
"DELETE FROM IDN_SCIM_GROUP WHERE TENANT_ID=? AND ROLE_NAME=?";
public static final String CHECK_EXISTING_ATTRIBUTE_SQL =
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -335,4 +335,17 @@ public String[] getGroupListFromAttributeName(String attributeName, String searc
GroupDAO groupDAO = new GroupDAO();
return groupDAO.getGroupNameList(attributeName, searchAttribute, this.tenantId, domainName);
}

/**
* Update SCIM attributes of the group.
*
* @param groupName The display name of the group.
* @param attributes The attributes to be updated.
* @throws IdentitySCIMException IdentitySCIMException when updating the SCIM Group information.
*/
public void updateSCIMAttributes(String groupName, Map<String, String> attributes) throws IdentitySCIMException {

GroupDAO groupDAO = new GroupDAO();
groupDAO.updateSCIMGroupAttributesWithUpdatedColumn(tenantId, groupName, attributes);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -508,7 +508,7 @@ public User getUser(String userId, Map<String, Boolean> requiredAttributes) thro
throw resolveError(e, errMsg);
}
} catch (BadRequestException | NotImplementedException e) {
throw new CharonException("Error in getting user information from Carbon User Store", e);
throw new CharonException("Error in getting user information from Carbon User Store", e);
}
return scimUser;
}
Expand Down Expand Up @@ -601,7 +601,7 @@ public void deleteUser(String userId) throws NotFoundException, CharonException,
@Override
@Deprecated
public UsersGetResponse listUsersWithGET(Node rootNode, int startIndex, int count, String sortBy, String sortOrder,
String domainName, Map<String, Boolean> requiredAttributes)
String domainName, Map<String, Boolean> requiredAttributes)
throws CharonException, NotImplementedException, BadRequestException {

if (sortBy != null || sortOrder != null) {
Expand All @@ -615,7 +615,7 @@ public UsersGetResponse listUsersWithGET(Node rootNode, int startIndex, int coun

@Override
public UsersGetResponse listUsersWithGET(Node rootNode, Integer startIndex, Integer count, String sortBy,
String sortOrder, String domainName, Map<String, Boolean> requiredAttributes)
String sortOrder, String domainName, Map<String, Boolean> requiredAttributes)
throws CharonException, NotImplementedException, BadRequestException {

// Validate NULL value for startIndex.
Expand Down Expand Up @@ -689,7 +689,7 @@ private Resource getResourceByTenantId(int tenantId) throws org.wso2.carbon.user
* @throws BadRequestException
*/
private UsersGetResponse listUsers(Map<String, Boolean> requiredAttributes, int offset, Integer limit,
String sortBy, String sortOrder, String domainName) throws CharonException,
String sortBy, String sortOrder, String domainName) throws CharonException,
BadRequestException {

List<User> scimUsers = new ArrayList<>();
Expand Down Expand Up @@ -980,7 +980,7 @@ private Set<org.wso2.carbon.user.core.common.User> listUsernamesAcrossAllDomains
* @throws CharonException Error while retrieving users
*/
private List<User> getUserDetails(Set<org.wso2.carbon.user.core.common.User> coreUsers,
Map<String, Boolean> requiredAttributes)
Map<String, Boolean> requiredAttributes)
throws CharonException, BadRequestException {

List<User> users = new ArrayList<>();
Expand Down Expand Up @@ -1410,7 +1410,7 @@ private int handleLimitEqualsNULL(Integer limit) {
* @throws BadRequestException
*/
private UsersGetResponse filterUsers(Node node, Map<String, Boolean> requiredAttributes, int offset, Integer limit,
String sortBy, String sortOrder, String domainName) throws CharonException,
String sortBy, String sortOrder, String domainName) throws CharonException,
BadRequestException {

// Handle limit equals NULL scenario.
Expand Down Expand Up @@ -3503,6 +3503,9 @@ private void doPatchGroup(String groupId, String currentGroupName, Map<String, L
List<PatchOperation> displayNameOperations = new ArrayList<>();
List<PatchOperation> memberOperations = new ArrayList<>();
String newGroupName = currentGroupName;
Date groupLastUpdatedTime = null;
String groupNameForIDNScim = SCIMCommonUtils.getGroupNameWithDomain(currentGroupName);

for (List<PatchOperation> patchOperationList : patchOperations.values()) {
for (PatchOperation patchOperation : patchOperationList) {
if (StringUtils.equals(SCIMConstants.GroupSchemaConstants.DISPLAY_NAME,
Expand All @@ -3519,7 +3522,14 @@ private void doPatchGroup(String groupId, String currentGroupName, Map<String, L

if (CollectionUtils.isNotEmpty(displayNameOperations)) {
newGroupName = (String) displayNameOperations.get(0).getValues();
setGroupDisplayName(groupId, currentGroupName, newGroupName);
String[] resolvedGroupNames = resolveGroupDomains(currentGroupName, newGroupName);
boolean groupUpdated = setGroupDisplayName(groupId, resolvedGroupNames[0], resolvedGroupNames[1]);
if (groupUpdated) {
groupLastUpdatedTime = new Date();
groupNameForIDNScim = resolvedGroupNames[1];
} else {
groupNameForIDNScim = resolvedGroupNames[0];
}
}

Collections.sort(memberOperations);
Expand Down Expand Up @@ -3605,10 +3615,20 @@ private void doPatchGroup(String groupId, String currentGroupName, Map<String, L
carbonUM.updateUserListOfRoleWithID(newGroupName,
deletedMemberIdsFromUserstore.toArray(new String[0]),
addedMemberIdsFromUserstore.toArray(new String[0]));
groupLastUpdatedTime = new Date();
}

// Update the group name in UM_HYBRID_GROUP_ROLE table.
carbonUM.updateGroupName(currentGroupName, newGroupName);

// Update the last modified time of the group.
if (!carbonUM.isUniqueGroupIdEnabled() && groupLastUpdatedTime != null) {
Map<String, String> attributes = new HashMap<>();
attributes.put(SCIMConstants.CommonSchemaConstants.LAST_MODIFIED_URI,
AttributeUtil.formatDateTime(groupLastUpdatedTime.toInstant()));
SCIMGroupHandler groupHandler = new SCIMGroupHandler(carbonUM.getTenantId());
groupHandler.updateSCIMAttributes(groupNameForIDNScim, attributes);
}
} catch (UserStoreException e) {
if (e instanceof org.wso2.carbon.user.core.UserStoreException && (StringUtils
.equals(UserCoreErrorConstants.ErrorMessages.ERROR_CODE_DUPLICATE_WHILE_WRITING_TO_DATABASE
Expand Down Expand Up @@ -3676,12 +3696,10 @@ private void prepareAddedRemovedMemberLists(Set<String> addedMembers, Set<String
}
}

private void setGroupDisplayName(String groupId, String oldGroupName, String newGroupName)
throws IdentityApplicationManagementException, CharonException, BadRequestException, IdentitySCIMException,
UserStoreException {
private String[] resolveGroupDomains(String oldGroupName, String newGroupName)
throws IdentityApplicationManagementException, CharonException, IdentitySCIMException {

String userStoreDomainFromSP = getUserStoreDomainFromSP();

String oldGroupDomain = IdentityUtil.extractDomainFromName(oldGroupName);
if (userStoreDomainFromSP != null && !userStoreDomainFromSP.equalsIgnoreCase(oldGroupDomain)) {
throw new CharonException("Group :" + oldGroupName + "is not belong to user store " +
Expand All @@ -3707,10 +3725,19 @@ private void setGroupDisplayName(String groupId, String oldGroupName, String new
oldGroupName = SCIMCommonUtils.getGroupNameWithDomain(oldGroupName);
newGroupName = SCIMCommonUtils.getGroupNameWithDomain(newGroupName);

return new String[] { oldGroupName, newGroupName };
}

private boolean setGroupDisplayName(String groupId, String oldGroupName, String newGroupName)
throws IdentityApplicationManagementException, IdentitySCIMException, UserStoreException {

if (!StringUtils.equals(oldGroupName, newGroupName)) {
// Update group name in carbon UM.
carbonUM.renameGroup(groupId, newGroupName);
return true;
}

return false;
}

@Override
Expand Down Expand Up @@ -3758,6 +3785,9 @@ public Group updateGroup(Group oldGroup, Group newGroup, Map<String, Boolean> re
public boolean doUpdateGroup(Group oldGroup, Group newGroup) throws CharonException, IdentitySCIMException,
BadRequestException, IdentityApplicationManagementException, org.wso2.carbon.user.core.UserStoreException {

Date groupLastUpdatedTime = null;
String groupNameForIDNScim = SCIMCommonUtils.getGroupNameWithDomain(oldGroup.getDisplayName());

setGroupDisplayName(oldGroup, newGroup);
if (log.isDebugEnabled()) {
log.debug("Updating group: " + oldGroup.getDisplayName());
Expand Down Expand Up @@ -3806,14 +3836,27 @@ public boolean doUpdateGroup(Group oldGroup, Group newGroup) throws CharonExcept
// Update group name in carbon UM
carbonUM.renameGroup(oldGroup.getId(), newGroupDisplayName);
updated = true;
groupLastUpdatedTime = new Date();
groupNameForIDNScim = SCIMCommonUtils.getGroupNameWithDomain(newGroupDisplayName);
}
// Update the group with added members and deleted members.
if (isNotEmpty(addedMembers) || isNotEmpty(deletedMembers)) {
carbonUM.updateUserListOfRoleWithID(newGroupDisplayName,
deletedMemberIdsFromUserstore.toArray(new String[0]),
addedMemberIdsFromUserstore.toArray(new String[0]));
updated = true;
groupLastUpdatedTime = new Date();
}

// Update the last modified time of the group.
if (!carbonUM.isUniqueGroupIdEnabled() && groupLastUpdatedTime != null) {
Map<String, String> attributes = new HashMap<>();
attributes.put(SCIMConstants.CommonSchemaConstants.LAST_MODIFIED_URI,
AttributeUtil.formatDateTime(groupLastUpdatedTime.toInstant()));
SCIMGroupHandler groupHandler = new SCIMGroupHandler(carbonUM.getTenantId());
groupHandler.updateSCIMAttributes(groupNameForIDNScim, attributes);
}

return updated;
}

Expand Down

0 comments on commit c78c3b2

Please sign in to comment.