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.Collection;
|
||||||
|
import java.util.HashMap;
|
||||||
import java.util.LinkedHashSet;
|
import java.util.LinkedHashSet;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
public class CollectionUtils {
|
public class CollectionUtils {
|
||||||
|
|
||||||
|
|
@ -65,4 +67,29 @@ public class CollectionUtils {
|
||||||
list.addAll(set);
|
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.exceptions.AppsmithException;
|
||||||
import com.appsmith.server.helpers.PolicyUtils;
|
import com.appsmith.server.helpers.PolicyUtils;
|
||||||
import com.appsmith.server.helpers.TextUtils;
|
import com.appsmith.server.helpers.TextUtils;
|
||||||
|
import com.appsmith.server.repositories.CacheableRepositoryHelper;
|
||||||
import com.appsmith.server.repositories.NewPageRepository;
|
import com.appsmith.server.repositories.NewPageRepository;
|
||||||
import com.appsmith.server.repositories.UserRepository;
|
import com.appsmith.server.repositories.UserRepository;
|
||||||
import com.appsmith.server.services.WorkspaceService;
|
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.EnvVariables.APPSMITH_ADMIN_EMAILS;
|
||||||
import static com.appsmith.server.constants.FieldName.DEFAULT_PERMISSION_GROUP;
|
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.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.dropIndexIfExists;
|
||||||
import static com.appsmith.server.migrations.DatabaseChangelog.ensureIndexes;
|
import static com.appsmith.server.migrations.DatabaseChangelog.ensureIndexes;
|
||||||
import static com.appsmith.server.migrations.DatabaseChangelog.getUpdatedDynamicBindingPathList;
|
import static com.appsmith.server.migrations.DatabaseChangelog.getUpdatedDynamicBindingPathList;
|
||||||
import static com.appsmith.server.migrations.DatabaseChangelog.makeIndex;
|
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 com.appsmith.server.repositories.BaseAppsmithRepositoryImpl.fieldName;
|
||||||
import static java.lang.Boolean.TRUE;
|
import static java.lang.Boolean.TRUE;
|
||||||
import static org.springframework.data.mongodb.core.query.Criteria.where;
|
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)
|
@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
|
// Read the admin emails from the environment and update the super users accordingly
|
||||||
String adminEmailsStr = System.getenv(String.valueOf(APPSMITH_ADMIN_EMAILS));
|
String adminEmailsStr = System.getenv(String.valueOf(APPSMITH_ADMIN_EMAILS));
|
||||||
|
|
||||||
|
|
@ -2325,6 +2328,9 @@ public class DatabaseChangelog2 {
|
||||||
})
|
})
|
||||||
.collect(Collectors.toSet());
|
.collect(Collectors.toSet());
|
||||||
|
|
||||||
|
Set<String> oldSuperUsers = instanceAdminPG.getAssignedToUserIds();
|
||||||
|
Set<String> updatedUserIds = findSymmetricDiff(oldSuperUsers, userIds);
|
||||||
|
evictPermissionCacheForUsers(updatedUserIds, mongockTemplate, cacheableRepositoryHelper);
|
||||||
instanceAdminPG.setAssignedToUserIds(userIds);
|
instanceAdminPG.setAssignedToUserIds(userIds);
|
||||||
mongockTemplate.save(instanceAdminPG);
|
mongockTemplate.save(instanceAdminPG);
|
||||||
}
|
}
|
||||||
|
|
@ -2334,6 +2340,7 @@ public class DatabaseChangelog2 {
|
||||||
user.setEmail(email);
|
user.setEmail(email);
|
||||||
user.setIsEnabled(false);
|
user.setIsEnabled(false);
|
||||||
user.setTenantId(tenantId);
|
user.setTenantId(tenantId);
|
||||||
|
user.setCreatedAt(Instant.now());
|
||||||
user = mongockTemplate.save(user);
|
user = mongockTemplate.save(user);
|
||||||
|
|
||||||
// Assign the user to the default permissions
|
// 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.constants.ResourceModes;
|
||||||
import com.appsmith.server.domains.ApplicationPage;
|
import com.appsmith.server.domains.ApplicationPage;
|
||||||
import com.appsmith.server.domains.NewAction;
|
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.ActionDTO;
|
||||||
import com.appsmith.server.dtos.ApplicationJson;
|
import com.appsmith.server.dtos.ApplicationJson;
|
||||||
import com.appsmith.server.helpers.CollectionUtils;
|
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.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.time.Instant;
|
||||||
import java.util.ArrayList;
|
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.EDIT;
|
||||||
import static com.appsmith.server.constants.ResourceModes.VIEW;
|
import static com.appsmith.server.constants.ResourceModes.VIEW;
|
||||||
|
import static com.appsmith.server.repositories.BaseAppsmithRepositoryImpl.fieldName;
|
||||||
|
|
||||||
public class MigrationHelperMethods {
|
public class MigrationHelperMethods {
|
||||||
// Migration for deprecating archivedAt field in ActionDTO
|
// 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