feat: Adding cache eviction for users whose permissions change due to super user changes (#16362)
Adding cache eviction for users whose permissions change due to super user changes
This commit is contained in:
parent
b893cb5216
commit
8d9e071648
|
|
@ -2,10 +2,12 @@ package com.appsmith.server.helpers;
|
|||
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.HashMap;
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
public class CollectionUtils {
|
||||
|
||||
|
|
@ -65,4 +67,29 @@ public class CollectionUtils {
|
|||
list.addAll(set);
|
||||
}
|
||||
|
||||
/**
|
||||
* Finds all the elements which do not exist in the intersection between the two sets
|
||||
* @param set1
|
||||
* @param set2
|
||||
* @return
|
||||
* @param <T>
|
||||
*/
|
||||
public static <T> Set<T> findSymmetricDiff(Set<T> set1, Set<T> set2) {
|
||||
Map<T, Integer> map = new HashMap<>();
|
||||
set1.forEach(e -> putKeyForFindingSymmetricDiff(map, e));
|
||||
set2.forEach(e -> putKeyForFindingSymmetricDiff(map, e));
|
||||
return map.entrySet().stream()
|
||||
.filter(e -> e.getValue() == 1)
|
||||
.map(Map.Entry::getKey)
|
||||
.collect(Collectors.toSet());
|
||||
}
|
||||
|
||||
private static <T> void putKeyForFindingSymmetricDiff(Map<T, Integer> map, T key) {
|
||||
if (map.containsKey(key)) {
|
||||
map.replace(key, Integer.MAX_VALUE);
|
||||
} else {
|
||||
map.put(key, 1);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -52,6 +52,7 @@ import com.appsmith.server.exceptions.AppsmithError;
|
|||
import com.appsmith.server.exceptions.AppsmithException;
|
||||
import com.appsmith.server.helpers.PolicyUtils;
|
||||
import com.appsmith.server.helpers.TextUtils;
|
||||
import com.appsmith.server.repositories.CacheableRepositoryHelper;
|
||||
import com.appsmith.server.repositories.NewPageRepository;
|
||||
import com.appsmith.server.repositories.UserRepository;
|
||||
import com.appsmith.server.services.WorkspaceService;
|
||||
|
|
@ -109,10 +110,12 @@ import static com.appsmith.server.acl.AclPermission.RESET_PASSWORD_USERS;
|
|||
import static com.appsmith.server.constants.EnvVariables.APPSMITH_ADMIN_EMAILS;
|
||||
import static com.appsmith.server.constants.FieldName.DEFAULT_PERMISSION_GROUP;
|
||||
import static com.appsmith.server.constants.FieldName.PERMISSION_GROUP_ID;
|
||||
import static com.appsmith.server.helpers.CollectionUtils.findSymmetricDiff;
|
||||
import static com.appsmith.server.migrations.DatabaseChangelog.dropIndexIfExists;
|
||||
import static com.appsmith.server.migrations.DatabaseChangelog.ensureIndexes;
|
||||
import static com.appsmith.server.migrations.DatabaseChangelog.getUpdatedDynamicBindingPathList;
|
||||
import static com.appsmith.server.migrations.DatabaseChangelog.makeIndex;
|
||||
import static com.appsmith.server.migrations.MigrationHelperMethods.evictPermissionCacheForUsers;
|
||||
import static com.appsmith.server.repositories.BaseAppsmithRepositoryImpl.fieldName;
|
||||
import static java.lang.Boolean.TRUE;
|
||||
import static org.springframework.data.mongodb.core.query.Criteria.where;
|
||||
|
|
@ -2288,7 +2291,7 @@ public class DatabaseChangelog2 {
|
|||
}
|
||||
|
||||
@ChangeSet(order = "033", id = "update-super-users", author = "", runAlways = true)
|
||||
public void updateSuperUsers(MongockTemplate mongockTemplate) {
|
||||
public void updateSuperUsers(MongockTemplate mongockTemplate, CacheableRepositoryHelper cacheableRepositoryHelper) {
|
||||
// Read the admin emails from the environment and update the super users accordingly
|
||||
String adminEmailsStr = System.getenv(String.valueOf(APPSMITH_ADMIN_EMAILS));
|
||||
|
||||
|
|
@ -2325,6 +2328,9 @@ public class DatabaseChangelog2 {
|
|||
})
|
||||
.collect(Collectors.toSet());
|
||||
|
||||
Set<String> oldSuperUsers = instanceAdminPG.getAssignedToUserIds();
|
||||
Set<String> updatedUserIds = findSymmetricDiff(oldSuperUsers, userIds);
|
||||
evictPermissionCacheForUsers(updatedUserIds, mongockTemplate, cacheableRepositoryHelper);
|
||||
instanceAdminPG.setAssignedToUserIds(userIds);
|
||||
mongockTemplate.save(instanceAdminPG);
|
||||
}
|
||||
|
|
@ -2334,6 +2340,7 @@ public class DatabaseChangelog2 {
|
|||
user.setEmail(email);
|
||||
user.setIsEnabled(false);
|
||||
user.setTenantId(tenantId);
|
||||
user.setCreatedAt(Instant.now());
|
||||
user = mongockTemplate.save(user);
|
||||
|
||||
// Assign the user to the default permissions
|
||||
|
|
|
|||
|
|
@ -4,10 +4,16 @@ import com.appsmith.external.models.InvisibleActionFields;
|
|||
import com.appsmith.server.constants.ResourceModes;
|
||||
import com.appsmith.server.domains.ApplicationPage;
|
||||
import com.appsmith.server.domains.NewAction;
|
||||
import com.appsmith.server.domains.QUser;
|
||||
import com.appsmith.server.domains.User;
|
||||
import com.appsmith.server.dtos.ActionDTO;
|
||||
import com.appsmith.server.dtos.ApplicationJson;
|
||||
import com.appsmith.server.helpers.CollectionUtils;
|
||||
import com.appsmith.server.repositories.CacheableRepositoryHelper;
|
||||
import com.github.cloudyrock.mongock.driver.mongodb.springdata.v3.decorator.impl.MongockTemplate;
|
||||
import org.apache.commons.lang.StringUtils;
|
||||
import org.springframework.data.mongodb.core.query.Criteria;
|
||||
import org.springframework.data.mongodb.core.query.Query;
|
||||
|
||||
import java.time.Instant;
|
||||
import java.util.ArrayList;
|
||||
|
|
@ -19,6 +25,7 @@ import java.util.stream.Collectors;
|
|||
|
||||
import static com.appsmith.server.constants.ResourceModes.EDIT;
|
||||
import static com.appsmith.server.constants.ResourceModes.VIEW;
|
||||
import static com.appsmith.server.repositories.BaseAppsmithRepositoryImpl.fieldName;
|
||||
|
||||
public class MigrationHelperMethods {
|
||||
// Migration for deprecating archivedAt field in ActionDTO
|
||||
|
|
@ -165,4 +172,22 @@ public class MigrationHelperMethods {
|
|||
});
|
||||
}
|
||||
}
|
||||
|
||||
public static void evictPermissionCacheForUsers(Set<String> userIds,
|
||||
MongockTemplate mongockTemplate,
|
||||
CacheableRepositoryHelper cacheableRepositoryHelper) {
|
||||
|
||||
if (userIds == null || userIds.isEmpty()) {
|
||||
// Nothing to do here.
|
||||
return;
|
||||
}
|
||||
|
||||
userIds.forEach(userId -> {
|
||||
Query query = new Query(new Criteria(fieldName(QUser.user.id)).is(userId));
|
||||
User user = mongockTemplate.findOne(query, User.class);
|
||||
// blocking call for cache eviction to ensure its subscribed immediately before proceeding further.
|
||||
cacheableRepositoryHelper.evictPermissionGroupsUser(user.getEmail(), user.getTenantId())
|
||||
.block();
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user