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 on user addition/ deletion to the group #4168

Open
wants to merge 1 commit into
base: 4.10.x
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
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 @@ -282,6 +282,7 @@ CREATE TABLE IF NOT EXISTS UM_ROLE (
UM_ROLE_NAME VARCHAR(255) NOT NULL,
UM_TENANT_ID INTEGER DEFAULT 0,
UM_SHARED_ROLE BOOLEAN DEFAULT FALSE,
UM_LAST_MODIFIED TIMESTAMP,
PRIMARY KEY (UM_ID, UM_TENANT_ID),
UNIQUE(UM_ROLE_NAME, UM_TENANT_ID));

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -154,6 +154,8 @@ public final class JDBCRealmConstants {
public static final String GET_GROUP_FILTER_WITH_LAST_MODIFIED = "GetGroupFilterWithLastModifiedSQL";
public static final String ADD_GROUP = "AddGroupSQL";
public static final String UPDATE_GROUP_NAME = "UpdateGroupNameSQL";
public static final String UPDATE_GROUP_LAST_MODIFIED = "UpdateGroupLastModifiedTimeSQL";
public static final String UPDATE_GROUP_LAST_MODIFIED_WITH_GROUP_ID = "UpdateGroupLastModifiedTimeWithGroupIDSQL";
public static final String COUNT_ROLES_SQL = "SELECT COUNT(UM_ROLE_NAME) AS RESULT FROM UM_ROLE WHERE UM_ROLE_NAME LIKE ? AND " +
"UM_TENANT_ID = ?";
public static final String COUNT_USERS_WITH_CLAIM_SQL = "SELECT COUNT(UM_USER_ID) AS RESULT FROM UM_USER_ATTRIBUTE WHERE UM_ATTR_NAME = ? " +
Expand Down Expand Up @@ -530,6 +532,10 @@ public final class JDBCRealmConstants {
"UM_CREATED_TIME, UM_LAST_MODIFIED) VALUES (?, ?, ?, ?, ?)";
public static final String UPDATE_GROUP_NAME_SQL = "UPDATE UM_ROLE set UM_ROLE_NAME = ?, UM_LAST_MODIFIED = ? " +
"WHERE UM_ROLE_UUID = ? AND UM_TENANT_ID = ?";
public static final String UPDATE_GROUP_LAST_MODIFIED_SQL = "UPDATE UM_ROLE set UM_LAST_MODIFIED = ? " +
"WHERE UM_ROLE_NAME = ? AND UM_TENANT_ID = ?";
public static final String UPDATE_GROUP_LAST_MODIFIED_WITH_GROUP_ID_SQL = "UPDATE UM_ROLE set " +
"UM_LAST_MODIFIED = ? WHERE UM_ROLE_UUID = ? AND UM_TENANT_ID = ?";

// properties
public static final String DATASOURCE = "dataSource";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -689,6 +689,13 @@ public class JDBCUserStoreConstants {
setAdvancedProperty(JDBCRealmConstants.UPDATE_GROUP_NAME, "Update Group Name SQL",
JDBCRealmConstants.UPDATE_GROUP_NAME_SQL, "",
new Property[]{GROUP.getProperty(), SQL.getProperty(), FALSE.getProperty()});
setAdvancedProperty(JDBCRealmConstants.UPDATE_GROUP_LAST_MODIFIED, "Update Group Last Modified Time SQL",
JDBCRealmConstants.UPDATE_GROUP_LAST_MODIFIED_SQL, "",
new Property[]{GROUP.getProperty(), SQL.getProperty(), FALSE.getProperty()});
setAdvancedProperty(JDBCRealmConstants.UPDATE_GROUP_LAST_MODIFIED_WITH_GROUP_ID,
"Update Group Last Modified Time With Group ID SQL",
JDBCRealmConstants.UPDATE_GROUP_LAST_MODIFIED_WITH_GROUP_ID_SQL, "",
new Property[]{GROUP.getProperty(), SQL.getProperty(), FALSE.getProperty()});

setAdvancedProperty(JDBCRealmConstants.ADD_USER_PROPERTY, "Add User Property SQL",
JDBCRealmConstants.ADD_USER_PROPERTY_SQL, "",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@

import org.apache.axiom.om.util.Base64;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang.ArrayUtils;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
Expand Down Expand Up @@ -84,11 +85,14 @@
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.TimeZone;
import java.util.stream.Collectors;

import javax.sql.DataSource;

import static java.time.ZoneOffset.UTC;
Expand Down Expand Up @@ -1662,6 +1666,12 @@ public void doUpdateUserListOfRoleWithID(String roleName, String[] deletedUserID
if (sqlStmt2 == null) {
throw new UserStoreException("The sql statement for add user to role is null.");
}

String sqlStmt3 = realmConfig.getUserStoreProperty(JDBCRealmConstants.UPDATE_GROUP_LAST_MODIFIED);
if (StringUtils.isBlank(sqlStmt3) && !isShared) {
throw new UserStoreException("The sql statement for update group last modified time is null.");
}

if (deletedUserIDs != null) {
if (isShared) {
DatabaseUtil.udpateUserRoleMappingInBatchMode(dbConnection, sqlStmt1, roleName, tenantId,
Expand Down Expand Up @@ -1694,6 +1704,9 @@ public void doUpdateUserListOfRoleWithID(String roleName, String[] deletedUserID
}
}
}
if (!isShared && (deletedUserIDs != null || newUserIDs != null)) {
this.updateValuesToDatabaseWithUTCTime(dbConnection, sqlStmt3, new Date(), roleName, tenantId);
}
dbConnection.commit();
} catch (SQLException e) {
DatabaseUtil.rollBack(dbConnection);
Expand All @@ -1713,7 +1726,6 @@ public void doUpdateUserListOfRoleWithID(String roleName, String[] deletedUserID
} finally {
DatabaseUtil.closeAllConnections(dbConnection);
}

}

@Override
Expand Down Expand Up @@ -1789,6 +1801,8 @@ public void doUpdateRoleListOfUserWithID(String userID, String[] deletedRoles, S
if (userNames.length > 1) {
userID = userNames[1];
}
String sqlStmt3 = realmConfig.getUserStoreProperty(JDBCRealmConstants.UPDATE_GROUP_LAST_MODIFIED);

if (deletedRoles != null && deletedRoles.length > 0) {
// Break the provided role list based on whether roles are shared or not
RoleBreakdown breakdown = getSharedRoleBreakdown(deletedRoles);
Expand All @@ -1802,12 +1816,27 @@ public void doUpdateRoleListOfUserWithID(String userID, String[] deletedRoles, S
if (sqlStmt1 == null) {
throw new UserStoreException("The sql statement for remove user from role is null.");
}
if (StringUtils.isBlank(sqlStmt3)) {
throw new UserStoreException("The sql statement for update group last modified time is null.");
}
if (sqlStmt1.contains(UserCoreConstants.UM_TENANT_COLUMN)) {
DatabaseUtil.udpateUserRoleMappingInBatchMode(dbConnection, sqlStmt1, roles, tenantId, userID,
tenantId, tenantId);
} else {
DatabaseUtil.udpateUserRoleMappingInBatchMode(dbConnection, sqlStmt1, roles, userID);
}

// If there are common groups in new and deleted, their modified time should only be updated
// during the add operation.
if (ArrayUtils.isNotEmpty(newRoles)) {
List<String> rolesToDeleteOnly =
(List<String>) CollectionUtils.subtract(Arrays.asList(roles), Arrays.asList(newRoles));
this.updateValuesToDatabaseWithUTCTimeInBatchMode(dbConnection, sqlStmt3, new Date(),
rolesToDeleteOnly, tenantId);
} else {
this.updateValuesToDatabaseWithUTCTimeInBatchMode(dbConnection, sqlStmt3, new Date(),
roles, tenantId);
}
}
if (sharedRoles.length > 0) {
sqlStmt1 = realmConfig
Expand Down Expand Up @@ -1849,6 +1878,9 @@ public void doUpdateRoleListOfUserWithID(String userID, String[] deletedRoles, S
if (sqlStmt2 == null) {
throw new UserStoreException("The sql statement for add user to role is null.");
}
if (StringUtils.isBlank(sqlStmt3)) {
throw new UserStoreException("The sql statement for update group last modified time is null.");
}
if (sqlStmt2.contains(UserCoreConstants.UM_TENANT_COLUMN)) {
if (UserCoreConstants.OPENEDGE_TYPE.equals(type)) {
DatabaseUtil
Expand All @@ -1862,6 +1894,8 @@ public void doUpdateRoleListOfUserWithID(String userID, String[] deletedRoles, S
} else {
DatabaseUtil.udpateUserRoleMappingInBatchMode(dbConnection, sqlStmt2, newRoles, userID);
}
this.updateValuesToDatabaseWithUTCTimeInBatchMode(dbConnection, sqlStmt3, new Date(), roles,
tenantId);
}
if (sharedRoles.length > 0) {
sqlStmt2 = realmConfig.getUserStoreProperty(JDBCRealmConstants.ADD_SHARED_ROLE_TO_USER_WITH_ID);
Expand Down Expand Up @@ -1896,7 +1930,6 @@ public void doUpdateRoleListOfUserWithID(String userID, String[] deletedRoles, S
} finally {
DatabaseUtil.closeAllConnections(dbConnection);
}

}

@Override
Expand Down Expand Up @@ -2397,6 +2430,84 @@ private void updateValuesToDatabaseWithUTCTime(Connection dbConnection, String s
}
}

private void updateValuesToDatabaseWithUTCTimeInBatchMode(Connection dbConnection, String sqlStmt,
Object... params) throws UserStoreException {

PreparedStatement prepStmt = null;
boolean localConnection = false;
try {
Instant currentInstant = Instant.now();
if (dbConnection == null) {
localConnection = true;
dbConnection = getDBConnection();
}
prepStmt = dbConnection.prepareStatement(sqlStmt);
int batchParamIndex = -1;
if (params != null && params.length > 0) {
for (int i = 0; i < params.length; i++) {
Object param = params[i];
if (param == null) {
throw new UserStoreException("Invalid data provided");
} else if (param instanceof String[]) {
batchParamIndex = i;
} else if (param instanceof String) {
if (isStoreUserAttributeAsUnicode()) {
prepStmt.setNString(i + 1, (String) param);
} else {
prepStmt.setString(i + 1, (String) param);
}
} else if (param instanceof Integer) {
prepStmt.setInt(i + 1, (Integer) param);
} else if (param instanceof Date) {
// Convert the current date-time to UTC time with ISO Date time format.
OffsetDateTime offsetDateTime = currentInstant.atOffset(ZoneOffset.UTC);
LocalDateTime localDateTime = offsetDateTime.toLocalDateTime();
int nanoSeconds = localDateTime.getNano();
int roundedNanoSeconds = (nanoSeconds / 1000000) * 1000000;
LocalDateTime formattedDateTime = localDateTime.withNano(roundedNanoSeconds);
prepStmt.setTimestamp(i + 1, Timestamp.valueOf(formattedDateTime));
} else if (param instanceof Boolean) {
prepStmt.setBoolean(i + 1, (Boolean) param);
}
}
}
if (batchParamIndex != -1) {
String[] values = (String[]) params[batchParamIndex];
for (String value : values) {
prepStmt.setString(batchParamIndex + 1, value);
prepStmt.addBatch();
}
}

int[] count = prepStmt.executeBatch();
if (log.isDebugEnabled()) {
log.debug("Executed a batch update. Query is : " + sqlStmt + ": and result is"
+ Arrays.toString(count));
}

if (localConnection) {
dbConnection.commit();
}
} catch (SQLException e) {
DatabaseUtil.rollBack(dbConnection);
String msg = "Error occurred while updating string values to database.";
if (log.isDebugEnabled()) {
log.debug(msg, e);
}
if (e instanceof SQLIntegrityConstraintViolationException) {
// Duplicate entry
throw new UserStoreException(msg, ERROR_CODE_DUPLICATE_WHILE_WRITING_TO_DATABASE.getCode(), e);
}
// Other SQL Exception
throw new UserStoreException(msg, e);
} finally {
if (localConnection) {
DatabaseUtil.closeAllConnections(dbConnection);
}
DatabaseUtil.closeAllConnections(null, prepStmt);
}
}

public void addPropertyWithID(Connection dbConnection, String userID, String propertyName, String value,
String profileName) throws UserStoreException {

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -602,6 +602,14 @@ public static Map<String, String> getSQL(Map<String, String> properties) {
if (!properties.containsKey(JDBCRealmConstants.UPDATE_GROUP_NAME)) {
properties.put(JDBCRealmConstants.UPDATE_GROUP_NAME, JDBCRealmConstants.UPDATE_GROUP_NAME_SQL);
}
if (!properties.containsKey(JDBCRealmConstants.UPDATE_GROUP_LAST_MODIFIED)) {
properties.put(JDBCRealmConstants.UPDATE_GROUP_LAST_MODIFIED,
JDBCRealmConstants.UPDATE_GROUP_LAST_MODIFIED_SQL);
}
if (!properties.containsKey(JDBCRealmConstants.UPDATE_GROUP_LAST_MODIFIED_WITH_GROUP_ID)) {
properties.put(JDBCRealmConstants.UPDATE_GROUP_LAST_MODIFIED_WITH_GROUP_ID,
JDBCRealmConstants.UPDATE_GROUP_LAST_MODIFIED_WITH_GROUP_ID_SQL);
}

//openedge
if (!properties.containsKey(JDBCRealmConstants.ADD_USER_TO_ROLE_OPENEDGE)) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -282,6 +282,7 @@ CREATE TABLE IF NOT EXISTS UM_ROLE (
UM_ROLE_NAME VARCHAR(255) NOT NULL,
UM_TENANT_ID INTEGER DEFAULT 0,
UM_SHARED_ROLE BOOLEAN DEFAULT FALSE,
UM_LAST_MODIFIED TIMESTAMP,
PRIMARY KEY (UM_ID, UM_TENANT_ID),
UNIQUE(UM_ROLE_NAME, UM_TENANT_ID));

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -267,6 +267,7 @@ CREATE TABLE IF NOT EXISTS UM_ROLE (
UM_ROLE_NAME VARCHAR(255) NOT NULL,
UM_TENANT_ID INTEGER DEFAULT 0,
UM_SHARED_ROLE BOOLEAN DEFAULT FALSE,
UM_LAST_MODIFIED TIMESTAMP,
PRIMARY KEY (UM_ID, UM_TENANT_ID),
UNIQUE(UM_ROLE_NAME, UM_TENANT_ID));

Expand Down