Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update the group last modified date when updating a group [when unique group id is disabled] #590

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
Loading