Fixed comment missing issue when user role is changed (#5898)
* -fixed comment missing issue when user role is changed * WIP: add test for policy utils * -added test for policy utils comment permission when users are added or removed * -removed unused code * -removed public access modifier for an internal function * -add test to verify comment thread policy updated when user role changed in organization * -add tests for add user and remove user from organization to test comment thread policies
This commit is contained in:
parent
dea9f26116
commit
5261f782df
|
|
@ -50,7 +50,13 @@ public class PolicyUtils {
|
||||||
// TODO: Investigate a solution without using deep-copy.
|
// TODO: Investigate a solution without using deep-copy.
|
||||||
final Map<String, Policy> policyMap1 = new HashMap<>();
|
final Map<String, Policy> policyMap1 = new HashMap<>();
|
||||||
for (Map.Entry<String, Policy> entry : policyMap.entrySet()) {
|
for (Map.Entry<String, Policy> entry : policyMap.entrySet()) {
|
||||||
policyMap1.put(entry.getKey(), entry.getValue());
|
Policy entryValue = entry.getValue();
|
||||||
|
Policy policy = Policy.builder()
|
||||||
|
.users(new HashSet<>(entryValue.getUsers()))
|
||||||
|
.permission(entryValue.getPermission())
|
||||||
|
.groups(new HashSet<>(entryValue.getGroups()))
|
||||||
|
.build();
|
||||||
|
policyMap1.put(entry.getKey(), policy);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Append the user to the existing permission policy if it already exists.
|
// Append the user to the existing permission policy if it already exists.
|
||||||
|
|
@ -221,7 +227,7 @@ public class PolicyUtils {
|
||||||
.saveAll(updatedPages));
|
.saveAll(updatedPages));
|
||||||
}
|
}
|
||||||
|
|
||||||
public Flux<CommentThread> updateWithApplicationPermissionsToAllItsCommentThreads(
|
public Flux<CommentThread> updateCommentThreadPermissions(
|
||||||
String applicationId, Map<String, Policy> commentThreadPolicyMap, String username, boolean addPolicyToObject) {
|
String applicationId, Map<String, Policy> commentThreadPolicyMap, String username, boolean addPolicyToObject) {
|
||||||
|
|
||||||
return
|
return
|
||||||
|
|
|
||||||
|
|
@ -10,16 +10,12 @@ import java.util.List;
|
||||||
public interface UserOrganizationService {
|
public interface UserOrganizationService {
|
||||||
Mono<User> addUserToOrganization(String orgId, User user);
|
Mono<User> addUserToOrganization(String orgId, User user);
|
||||||
|
|
||||||
Mono<User> saveUser(User user);
|
|
||||||
|
|
||||||
Mono<Organization> addUserRoleToOrganization(String orgId, UserRole userRole);
|
Mono<Organization> addUserRoleToOrganization(String orgId, UserRole userRole);
|
||||||
|
|
||||||
Mono<Organization> addUserToOrganizationGivenUserObject(Organization organization, User user, UserRole userRole);
|
Mono<Organization> addUserToOrganizationGivenUserObject(Organization organization, User user, UserRole userRole);
|
||||||
|
|
||||||
Mono<User> leaveOrganization(String orgId);
|
Mono<User> leaveOrganization(String orgId);
|
||||||
|
|
||||||
Mono<Organization> removeUserRoleFromOrganizationGivenUserObject(Organization organization, User user);
|
|
||||||
|
|
||||||
Mono<UserRole> updateRoleForMember(String orgId, UserRole userRole, String originHeader);
|
Mono<UserRole> updateRoleForMember(String orgId, UserRole userRole, String originHeader);
|
||||||
|
|
||||||
Mono<Organization> bulkAddUsersToOrganization(Organization organization, List<User> users, String roleName);
|
Mono<Organization> bulkAddUsersToOrganization(Organization organization, List<User> users, String roleName);
|
||||||
|
|
|
||||||
|
|
@ -120,11 +120,6 @@ public class UserOrganizationServiceImpl implements UserOrganizationService {
|
||||||
.flatMap(userRepository::save);
|
.flatMap(userRepository::save);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public Mono<User> saveUser(User user) {
|
|
||||||
return userRepository.save(user);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Mono<Organization> addUserRoleToOrganization(String orgId, UserRole userRole) {
|
public Mono<Organization> addUserRoleToOrganization(String orgId, UserRole userRole) {
|
||||||
Mono<Organization> organizationMono = organizationRepository.findById(orgId, MANAGE_ORGANIZATIONS)
|
Mono<Organization> organizationMono = organizationRepository.findById(orgId, MANAGE_ORGANIZATIONS)
|
||||||
|
|
@ -169,7 +164,9 @@ public class UserOrganizationServiceImpl implements UserOrganizationService {
|
||||||
Map<String, Policy> datasourcePolicyMap = policyUtils.generateInheritedPoliciesFromSourcePolicies(orgPolicyMap, Organization.class, Datasource.class);
|
Map<String, Policy> datasourcePolicyMap = policyUtils.generateInheritedPoliciesFromSourcePolicies(orgPolicyMap, Organization.class, Datasource.class);
|
||||||
Map<String, Policy> pagePolicyMap = policyUtils.generateInheritedPoliciesFromSourcePolicies(applicationPolicyMap, Application.class, Page.class);
|
Map<String, Policy> pagePolicyMap = policyUtils.generateInheritedPoliciesFromSourcePolicies(applicationPolicyMap, Application.class, Page.class);
|
||||||
Map<String, Policy> actionPolicyMap = policyUtils.generateInheritedPoliciesFromSourcePolicies(pagePolicyMap, Page.class, Action.class);
|
Map<String, Policy> actionPolicyMap = policyUtils.generateInheritedPoliciesFromSourcePolicies(pagePolicyMap, Page.class, Action.class);
|
||||||
|
Map<String, Policy> commentThreadPolicyMap = policyUtils.generateInheritedPoliciesFromSourcePolicies(
|
||||||
|
applicationPolicyMap, Application.class, CommentThread.class
|
||||||
|
);
|
||||||
//Now update the organization policies
|
//Now update the organization policies
|
||||||
Organization updatedOrganization = policyUtils.addPoliciesToExistingObject(orgPolicyMap, organization);
|
Organization updatedOrganization = policyUtils.addPoliciesToExistingObject(orgPolicyMap, organization);
|
||||||
updatedOrganization.setUserRoles(userRoles);
|
updatedOrganization.setUserRoles(userRoles);
|
||||||
|
|
@ -182,8 +179,16 @@ public class UserOrganizationServiceImpl implements UserOrganizationService {
|
||||||
.flatMap(application -> policyUtils.updateWithApplicationPermissionsToAllItsPages(application.getId(), pagePolicyMap, true));
|
.flatMap(application -> policyUtils.updateWithApplicationPermissionsToAllItsPages(application.getId(), pagePolicyMap, true));
|
||||||
Flux<NewAction> updatedActionsFlux = updatedApplicationsFlux
|
Flux<NewAction> updatedActionsFlux = updatedApplicationsFlux
|
||||||
.flatMap(application -> policyUtils.updateWithPagePermissionsToAllItsActions(application.getId(), actionPolicyMap, true));
|
.flatMap(application -> policyUtils.updateWithPagePermissionsToAllItsActions(application.getId(), actionPolicyMap, true));
|
||||||
|
Flux<CommentThread> updatedThreadsFlux = updatedApplicationsFlux
|
||||||
|
.flatMap(application -> policyUtils.updateCommentThreadPermissions(application.getId(), commentThreadPolicyMap, user.getUsername(), true));
|
||||||
|
|
||||||
return Mono.zip(updatedDatasourcesFlux.collectList(), updatedPagesFlux.collectList(), updatedActionsFlux.collectList(), Mono.just(updatedOrganization))
|
return Mono.zip(
|
||||||
|
updatedDatasourcesFlux.collectList(),
|
||||||
|
updatedPagesFlux.collectList(),
|
||||||
|
updatedActionsFlux.collectList(),
|
||||||
|
Mono.just(updatedOrganization),
|
||||||
|
updatedThreadsFlux.collectList()
|
||||||
|
)
|
||||||
.flatMap(tuple -> {
|
.flatMap(tuple -> {
|
||||||
//By now all the datasources/applications/pages/actions have been updated. Just save the organization now
|
//By now all the datasources/applications/pages/actions have been updated. Just save the organization now
|
||||||
Organization updatedOrgBeforeSave = tuple.getT4();
|
Organization updatedOrgBeforeSave = tuple.getT4();
|
||||||
|
|
@ -212,8 +217,7 @@ public class UserOrganizationServiceImpl implements UserOrganizationService {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
private Mono<Organization> removeUserRoleFromOrganizationGivenUserObject(Organization organization, User user) {
|
||||||
public Mono<Organization> removeUserRoleFromOrganizationGivenUserObject(Organization organization, User user) {
|
|
||||||
List<UserRole> userRoles = organization.getUserRoles();
|
List<UserRole> userRoles = organization.getUserRoles();
|
||||||
if (userRoles == null) {
|
if (userRoles == null) {
|
||||||
return Mono.error(new AppsmithException(AppsmithError.NO_RESOURCE_FOUND, FieldName.USER + " in organization", organization.getName()));
|
return Mono.error(new AppsmithException(AppsmithError.NO_RESOURCE_FOUND, FieldName.USER + " in organization", organization.getName()));
|
||||||
|
|
@ -258,7 +262,7 @@ public class UserOrganizationServiceImpl implements UserOrganizationService {
|
||||||
Flux<NewAction> updatedActionsFlux = updatedApplicationsFlux
|
Flux<NewAction> updatedActionsFlux = updatedApplicationsFlux
|
||||||
.flatMap(application -> policyUtils.updateWithPagePermissionsToAllItsActions(application.getId(), actionPolicyMap, false));
|
.flatMap(application -> policyUtils.updateWithPagePermissionsToAllItsActions(application.getId(), actionPolicyMap, false));
|
||||||
Flux<CommentThread> updatedThreadsFlux = updatedApplicationsFlux
|
Flux<CommentThread> updatedThreadsFlux = updatedApplicationsFlux
|
||||||
.flatMap(application -> policyUtils.updateWithApplicationPermissionsToAllItsCommentThreads(
|
.flatMap(application -> policyUtils.updateCommentThreadPermissions(
|
||||||
application.getId(), commentThreadPolicyMap, user.getUsername(), false
|
application.getId(), commentThreadPolicyMap, user.getUsername(), false
|
||||||
));
|
));
|
||||||
|
|
||||||
|
|
@ -434,7 +438,7 @@ public class UserOrganizationServiceImpl implements UserOrganizationService {
|
||||||
Flux<NewAction> updatedActionsFlux = updatedApplicationsFlux
|
Flux<NewAction> updatedActionsFlux = updatedApplicationsFlux
|
||||||
.flatMap(application -> policyUtils.updateWithPagePermissionsToAllItsActions(application.getId(), actionPolicyMap, true));
|
.flatMap(application -> policyUtils.updateWithPagePermissionsToAllItsActions(application.getId(), actionPolicyMap, true));
|
||||||
Flux<CommentThread> updatedThreadsFlux = updatedApplicationsFlux
|
Flux<CommentThread> updatedThreadsFlux = updatedApplicationsFlux
|
||||||
.flatMap(application -> policyUtils.updateWithApplicationPermissionsToAllItsCommentThreads(
|
.flatMap(application -> policyUtils.updateCommentThreadPermissions(
|
||||||
application.getId(), commentThreadPolicyMap, null, true
|
application.getId(), commentThreadPolicyMap, null, true
|
||||||
));
|
));
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,138 @@
|
||||||
|
package com.appsmith.server.helpers;
|
||||||
|
|
||||||
|
import com.appsmith.external.models.Policy;
|
||||||
|
import com.appsmith.server.acl.AclPermission;
|
||||||
|
import com.appsmith.server.domains.CommentThread;
|
||||||
|
import com.appsmith.server.domains.User;
|
||||||
|
import com.appsmith.server.repositories.CommentThreadRepository;
|
||||||
|
import org.junit.Before;
|
||||||
|
import org.junit.Test;
|
||||||
|
import org.junit.runner.RunWith;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.boot.test.context.SpringBootTest;
|
||||||
|
import org.springframework.security.test.context.support.WithUserDetails;
|
||||||
|
import org.springframework.test.context.junit4.SpringRunner;
|
||||||
|
import reactor.core.publisher.Flux;
|
||||||
|
import reactor.core.publisher.Mono;
|
||||||
|
import reactor.test.StepVerifier;
|
||||||
|
|
||||||
|
import java.util.HashSet;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
import static org.assertj.core.api.Assertions.assertThat;
|
||||||
|
|
||||||
|
@SpringBootTest
|
||||||
|
@RunWith(SpringRunner.class)
|
||||||
|
public class PolicyUtilsTest {
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private PolicyUtils policyUtils;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private CommentThreadRepository commentThreadRepository;
|
||||||
|
|
||||||
|
@Before
|
||||||
|
public void cleanUp() {
|
||||||
|
commentThreadRepository.deleteAll().block();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@WithUserDetails("api_user")
|
||||||
|
public void updateWithApplicationPermissionsToAllItsCommentThreads_AddPermissions_PermissionsAdded() {
|
||||||
|
// create a thread
|
||||||
|
String testApplicationId = "test-application-id";
|
||||||
|
CommentThread commentThread = new CommentThread();
|
||||||
|
commentThread.setApplicationId(testApplicationId);
|
||||||
|
Map<String, Policy> commentThreadPolicies = policyUtils.generatePolicyFromPermission(
|
||||||
|
Set.of(AclPermission.MANAGE_THREAD, AclPermission.COMMENT_ON_THREAD), "api_user"
|
||||||
|
);
|
||||||
|
commentThread.setPolicies(Set.copyOf(commentThreadPolicies.values()));
|
||||||
|
Mono<CommentThread> saveThreadMono = commentThreadRepository.save(commentThread);
|
||||||
|
|
||||||
|
// add a new user and update the policies of the new user
|
||||||
|
String newUserName = "new_test_user";
|
||||||
|
Map<String, Policy> commentThreadPoliciesForNewUser = policyUtils.generatePolicyFromPermission(
|
||||||
|
Set.of(AclPermission.COMMENT_ON_THREAD), newUserName
|
||||||
|
);
|
||||||
|
Flux<CommentThread> updateCommentThreads = policyUtils.updateCommentThreadPermissions(
|
||||||
|
testApplicationId, commentThreadPoliciesForNewUser, newUserName, true
|
||||||
|
);
|
||||||
|
|
||||||
|
// check if new policies updated
|
||||||
|
Mono<List<CommentThread>> applicationCommentList = saveThreadMono
|
||||||
|
.thenMany(updateCommentThreads)
|
||||||
|
.collectList()
|
||||||
|
.thenMany(commentThreadRepository.findByApplicationId(testApplicationId, AclPermission.READ_THREAD))
|
||||||
|
.collectList();
|
||||||
|
|
||||||
|
StepVerifier.create(applicationCommentList)
|
||||||
|
.assertNext(commentThreads -> {
|
||||||
|
assertThat(commentThreads.size()).isEqualTo(1);
|
||||||
|
CommentThread commentThread1 = commentThreads.get(0);
|
||||||
|
Set<Policy> policies = commentThread1.getPolicies();
|
||||||
|
assertThat(policyUtils.isPermissionPresentForUser(policies, AclPermission.MANAGE_THREAD.getValue(), "api_user")).isTrue();
|
||||||
|
assertThat(policyUtils.isPermissionPresentForUser(policies, AclPermission.MANAGE_THREAD.getValue(), newUserName)).isFalse();
|
||||||
|
assertThat(policyUtils.isPermissionPresentForUser(policies, AclPermission.READ_THREAD.getValue(), "api_user")).isTrue();
|
||||||
|
assertThat(policyUtils.isPermissionPresentForUser(policies, AclPermission.READ_THREAD.getValue(), newUserName)).isTrue();
|
||||||
|
assertThat(policyUtils.isPermissionPresentForUser(policies, AclPermission.COMMENT_ON_THREAD.getValue(), "api_user")).isTrue();
|
||||||
|
assertThat(policyUtils.isPermissionPresentForUser(policies, AclPermission.COMMENT_ON_THREAD.getValue(), newUserName)).isTrue();
|
||||||
|
})
|
||||||
|
.verifyComplete();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@WithUserDetails("api_user")
|
||||||
|
public void updateWithApplicationPermissionsToAllItsCommentThreads_RemovePermissions_PermissionsRemoved() {
|
||||||
|
String newUserName = "new_test_user";
|
||||||
|
|
||||||
|
// create a thread with two users having permission on it
|
||||||
|
String testApplicationId = "test-application-id";
|
||||||
|
CommentThread commentThread = new CommentThread();
|
||||||
|
commentThread.setApplicationId(testApplicationId);
|
||||||
|
commentThread.setPolicies(new HashSet<>());
|
||||||
|
|
||||||
|
User user1 = new User();
|
||||||
|
user1.setEmail("api_user");
|
||||||
|
|
||||||
|
User user2 = new User();
|
||||||
|
user2.setEmail(newUserName);
|
||||||
|
|
||||||
|
Map<String, Policy> commentThreadPolicies = policyUtils.generatePolicyFromPermissionForMultipleUsers(
|
||||||
|
Set.of(AclPermission.MANAGE_THREAD, AclPermission.COMMENT_ON_THREAD), List.of(user1, user2)
|
||||||
|
);
|
||||||
|
|
||||||
|
commentThread.setPolicies(Set.copyOf(commentThreadPolicies.values()));
|
||||||
|
Mono<CommentThread> saveThreadMono = commentThreadRepository.save(commentThread);
|
||||||
|
|
||||||
|
// remove an user and update the policies of the user
|
||||||
|
Map<String, Policy> commentThreadPoliciesForNewUser = policyUtils.generatePolicyFromPermission(
|
||||||
|
Set.of(AclPermission.MANAGE_THREAD, AclPermission.COMMENT_ON_THREAD), newUserName
|
||||||
|
);
|
||||||
|
Flux<CommentThread> updateCommentThreads = policyUtils.updateCommentThreadPermissions(
|
||||||
|
testApplicationId, commentThreadPoliciesForNewUser, newUserName, false
|
||||||
|
);
|
||||||
|
|
||||||
|
// check if new policies updated
|
||||||
|
Mono<List<CommentThread>> applicationCommentList = saveThreadMono
|
||||||
|
.thenMany(updateCommentThreads)
|
||||||
|
.collectList()
|
||||||
|
.thenMany(commentThreadRepository.findByApplicationId(testApplicationId, AclPermission.READ_THREAD))
|
||||||
|
.collectList();
|
||||||
|
|
||||||
|
StepVerifier.create(applicationCommentList)
|
||||||
|
.assertNext(commentThreads -> {
|
||||||
|
assertThat(commentThreads.size()).isEqualTo(1);
|
||||||
|
CommentThread commentThread1 = commentThreads.get(0);
|
||||||
|
Set<Policy> policies = commentThread1.getPolicies();
|
||||||
|
assertThat(policyUtils.isPermissionPresentForUser(policies, AclPermission.MANAGE_THREAD.getValue(), "api_user")).isTrue();
|
||||||
|
assertThat(policyUtils.isPermissionPresentForUser(policies, AclPermission.MANAGE_THREAD.getValue(), newUserName)).isFalse();
|
||||||
|
assertThat(policyUtils.isPermissionPresentForUser(policies, AclPermission.READ_THREAD.getValue(), "api_user")).isTrue();
|
||||||
|
assertThat(policyUtils.isPermissionPresentForUser(policies, AclPermission.READ_THREAD.getValue(), newUserName)).isFalse();
|
||||||
|
assertThat(policyUtils.isPermissionPresentForUser(policies, AclPermission.COMMENT_ON_THREAD.getValue(), "api_user")).isTrue();
|
||||||
|
assertThat(policyUtils.isPermissionPresentForUser(policies, AclPermission.COMMENT_ON_THREAD.getValue(), newUserName)).isFalse();
|
||||||
|
})
|
||||||
|
.verifyComplete();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -1,11 +1,19 @@
|
||||||
package com.appsmith.server.services;
|
package com.appsmith.server.services;
|
||||||
|
|
||||||
|
import com.appsmith.external.models.Policy;
|
||||||
|
import com.appsmith.server.acl.AclPermission;
|
||||||
import com.appsmith.server.acl.AppsmithRole;
|
import com.appsmith.server.acl.AppsmithRole;
|
||||||
|
import com.appsmith.server.acl.PolicyGenerator;
|
||||||
import com.appsmith.server.constants.FieldName;
|
import com.appsmith.server.constants.FieldName;
|
||||||
|
import com.appsmith.server.domains.Application;
|
||||||
|
import com.appsmith.server.domains.CommentThread;
|
||||||
import com.appsmith.server.domains.Organization;
|
import com.appsmith.server.domains.Organization;
|
||||||
import com.appsmith.server.domains.User;
|
import com.appsmith.server.domains.User;
|
||||||
import com.appsmith.server.domains.UserRole;
|
import com.appsmith.server.domains.UserRole;
|
||||||
import com.appsmith.server.exceptions.AppsmithError;
|
import com.appsmith.server.exceptions.AppsmithError;
|
||||||
|
import com.appsmith.server.helpers.PolicyUtils;
|
||||||
|
import com.appsmith.server.repositories.ApplicationRepository;
|
||||||
|
import com.appsmith.server.repositories.CommentThreadRepository;
|
||||||
import com.appsmith.server.repositories.OrganizationRepository;
|
import com.appsmith.server.repositories.OrganizationRepository;
|
||||||
import com.appsmith.server.repositories.UserRepository;
|
import com.appsmith.server.repositories.UserRepository;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
|
@ -22,13 +30,15 @@ import reactor.core.publisher.Mono;
|
||||||
import reactor.test.StepVerifier;
|
import reactor.test.StepVerifier;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Arrays;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
|
import static com.appsmith.server.acl.AppsmithRole.ORGANIZATION_ADMIN;
|
||||||
|
import static com.appsmith.server.acl.AppsmithRole.ORGANIZATION_DEVELOPER;
|
||||||
|
import static com.appsmith.server.acl.AppsmithRole.ORGANIZATION_VIEWER;
|
||||||
import static org.junit.Assert.assertFalse;
|
import static org.junit.Assert.assertFalse;
|
||||||
import static org.junit.Assert.assertTrue;
|
import static org.assertj.core.api.Assertions.assertThat;
|
||||||
import static org.junit.jupiter.api.Assertions.assertArrayEquals;
|
|
||||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||||
|
|
||||||
@Slf4j
|
@Slf4j
|
||||||
|
|
@ -46,6 +56,21 @@ class UserOrganizationServiceTest {
|
||||||
@Autowired
|
@Autowired
|
||||||
private UserRepository userRepository;
|
private UserRepository userRepository;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private PolicyUtils policyUtils;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private ApplicationRepository applicationRepository;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private CommentService commentService;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private CommentThreadRepository commentThreadRepository;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private PolicyGenerator policyGenerator;
|
||||||
|
|
||||||
private Organization organization;
|
private Organization organization;
|
||||||
private User user;
|
private User user;
|
||||||
|
|
||||||
|
|
@ -53,27 +78,39 @@ class UserOrganizationServiceTest {
|
||||||
public void setup() {
|
public void setup() {
|
||||||
Organization org = new Organization();
|
Organization org = new Organization();
|
||||||
org.setName("Test org");
|
org.setName("Test org");
|
||||||
|
org.setUserRoles(new ArrayList<>());
|
||||||
UserRole userRole = new UserRole();
|
|
||||||
userRole.setUsername("dummy_username");
|
|
||||||
userRole.setUserId("dummy_user_id");
|
|
||||||
userRole.setName("dummy_username");
|
|
||||||
userRole.setRoleName(AppsmithRole.ORGANIZATION_DEVELOPER.getName());
|
|
||||||
userRole.setRole(AppsmithRole.ORGANIZATION_DEVELOPER);
|
|
||||||
|
|
||||||
List<UserRole> userRoles = new ArrayList<>();
|
|
||||||
userRoles.add(userRole);
|
|
||||||
org.setUserRoles(userRoles);
|
|
||||||
|
|
||||||
this.organization = organizationRepository.save(org).block();
|
this.organization = organizationRepository.save(org).block();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private UserRole createUserRole(String username, String userId, AppsmithRole role) {
|
||||||
|
UserRole userRole = new UserRole();
|
||||||
|
userRole.setUsername(username);
|
||||||
|
userRole.setUserId(userId);
|
||||||
|
userRole.setName(username);
|
||||||
|
if(role != null) {
|
||||||
|
userRole.setRoleName(role.getName());
|
||||||
|
userRole.setRole(role);
|
||||||
|
}
|
||||||
|
return userRole;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void addRolesToOrg(List<UserRole> roles) {
|
||||||
|
this.organization.setUserRoles(roles);
|
||||||
|
for (UserRole userRole : roles) {
|
||||||
|
Set<AclPermission> rolePermissions = userRole.getRole().getPermissions();
|
||||||
|
Map<String, Policy> orgPolicyMap = policyUtils.generatePolicyFromPermission(
|
||||||
|
rolePermissions, userRole.getUsername()
|
||||||
|
);
|
||||||
|
this.organization = policyUtils.addPoliciesToExistingObject(orgPolicyMap, organization);
|
||||||
|
}
|
||||||
|
this.organization = organizationRepository.save(organization).block();
|
||||||
|
}
|
||||||
|
|
||||||
@AfterEach
|
@AfterEach
|
||||||
public void clear() {
|
public void clear() {
|
||||||
User currentUser = userRepository.findByEmail("api_user").block();
|
User currentUser = userRepository.findByEmail("api_user").block();
|
||||||
currentUser.getOrganizationIds().remove(organization.getId());
|
currentUser.getOrganizationIds().remove(organization.getId());
|
||||||
userRepository.save(currentUser);
|
userRepository.save(currentUser);
|
||||||
|
|
||||||
organizationRepository.deleteById(organization.getId()).block();
|
organizationRepository.deleteById(organization.getId()).block();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -88,11 +125,7 @@ class UserOrganizationServiceTest {
|
||||||
currentUser.getOrganizationIds().add(organization.getId());
|
currentUser.getOrganizationIds().add(organization.getId());
|
||||||
userRepository.save(currentUser).block();
|
userRepository.save(currentUser).block();
|
||||||
|
|
||||||
UserRole userRole = new UserRole();
|
UserRole userRole = createUserRole(currentUser.getUsername(), currentUser.getId(), ORGANIZATION_DEVELOPER);
|
||||||
userRole.setUsername(currentUser.getUsername());
|
|
||||||
userRole.setUserId(currentUser.getId());
|
|
||||||
userRole.setName(currentUser.getName());
|
|
||||||
userRole.setRoleName(AppsmithRole.ORGANIZATION_DEVELOPER.getName());
|
|
||||||
|
|
||||||
Organization updatedOrganization = userOrganizationService.addUserToOrganizationGivenUserObject(
|
Organization updatedOrganization = userOrganizationService.addUserToOrganizationGivenUserObject(
|
||||||
this.organization, currentUser, userRole
|
this.organization, currentUser, userRole
|
||||||
|
|
@ -130,10 +163,7 @@ class UserOrganizationServiceTest {
|
||||||
public void updateRoleForMember_WhenAdminRoleRemovedWithNoOtherAdmin_ThrowsExceptions() {
|
public void updateRoleForMember_WhenAdminRoleRemovedWithNoOtherAdmin_ThrowsExceptions() {
|
||||||
// add the current user as an admin to the organization first
|
// add the current user as an admin to the organization first
|
||||||
User currentUser = userRepository.findByEmail("api_user").block();
|
User currentUser = userRepository.findByEmail("api_user").block();
|
||||||
UserRole userRole = new UserRole();
|
UserRole userRole = createUserRole(currentUser.getUsername(), currentUser.getId(), ORGANIZATION_ADMIN);
|
||||||
userRole.setUsername(currentUser.getUsername());
|
|
||||||
userRole.setRole(AppsmithRole.ORGANIZATION_DEVELOPER);
|
|
||||||
userRole.setRoleName(AppsmithRole.ORGANIZATION_ADMIN.getName());
|
|
||||||
|
|
||||||
userOrganizationService.addUserToOrganizationGivenUserObject(organization, currentUser, userRole).block();
|
userOrganizationService.addUserToOrganizationGivenUserObject(organization, currentUser, userRole).block();
|
||||||
|
|
||||||
|
|
@ -151,23 +181,13 @@ class UserOrganizationServiceTest {
|
||||||
@WithUserDetails(value = "api_user")
|
@WithUserDetails(value = "api_user")
|
||||||
public void updateRoleForMember_WhenAdminRoleRemovedButOtherAdminExists_MemberRemoved() {
|
public void updateRoleForMember_WhenAdminRoleRemovedButOtherAdminExists_MemberRemoved() {
|
||||||
// add another admin role to the organization
|
// add another admin role to the organization
|
||||||
UserRole adminRole = new UserRole();
|
UserRole adminRole = createUserRole("dummy_username2", "dummy_user_id2", ORGANIZATION_ADMIN);
|
||||||
adminRole.setUsername("dummy_username2");
|
|
||||||
adminRole.setUserId("dummy_user_id2");
|
|
||||||
adminRole.setName("dummy_username2");
|
|
||||||
adminRole.setRoleName(AppsmithRole.ORGANIZATION_ADMIN.getName());
|
|
||||||
adminRole.setRole(AppsmithRole.ORGANIZATION_ADMIN);
|
|
||||||
this.organization.getUserRoles().add(adminRole);
|
this.organization.getUserRoles().add(adminRole);
|
||||||
|
|
||||||
this.organization = organizationRepository.save(this.organization).block();
|
this.organization = organizationRepository.save(this.organization).block();
|
||||||
|
|
||||||
// add the current user as an admin to the organization
|
// add the current user as an admin to the organization
|
||||||
User currentUser = userRepository.findByEmail("api_user").block();
|
User currentUser = userRepository.findByEmail("api_user").block();
|
||||||
UserRole userRole = new UserRole();
|
UserRole userRole = createUserRole(currentUser.getUsername(), currentUser.getId(), ORGANIZATION_ADMIN);
|
||||||
userRole.setUsername(currentUser.getUsername());
|
|
||||||
userRole.setRole(AppsmithRole.ORGANIZATION_ADMIN);
|
|
||||||
userRole.setRoleName(AppsmithRole.ORGANIZATION_ADMIN.getName());
|
|
||||||
|
|
||||||
userOrganizationService.addUserToOrganizationGivenUserObject(organization, currentUser, userRole).block();
|
userOrganizationService.addUserToOrganizationGivenUserObject(organization, currentUser, userRole).block();
|
||||||
|
|
||||||
// try to remove the user from org
|
// try to remove the user from org
|
||||||
|
|
@ -181,4 +201,137 @@ class UserOrganizationServiceTest {
|
||||||
}
|
}
|
||||||
).verifyComplete();
|
).verifyComplete();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private Application createTestApplicationForCommentThreadTests() {
|
||||||
|
// add a two roles to the organization
|
||||||
|
User devUser = new User();
|
||||||
|
devUser.setEmail("test_developer");
|
||||||
|
userRepository.findByEmail("test_developer")
|
||||||
|
.switchIfEmpty(userRepository.save(devUser))
|
||||||
|
.block();
|
||||||
|
|
||||||
|
UserRole adminRole = createUserRole("api_user", "api_user", ORGANIZATION_ADMIN);
|
||||||
|
UserRole devRole = createUserRole("test_developer", "test_developer", ORGANIZATION_DEVELOPER);
|
||||||
|
|
||||||
|
List<UserRole> userRoles = new ArrayList<>(2);
|
||||||
|
userRoles.add(adminRole);
|
||||||
|
userRoles.add(devRole);
|
||||||
|
|
||||||
|
addRolesToOrg(userRoles);
|
||||||
|
|
||||||
|
// create a test application
|
||||||
|
Application application = new Application();
|
||||||
|
application.setOrganizationId(this.organization.getId());
|
||||||
|
application.setName("Test application");
|
||||||
|
Set<Policy> documentPolicies = policyGenerator.getAllChildPolicies(
|
||||||
|
organization.getPolicies(), Organization.class, Application.class
|
||||||
|
);
|
||||||
|
application.setPolicies(documentPolicies);
|
||||||
|
return application;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@WithUserDetails("api_user")
|
||||||
|
public void updateRoleForMember_WhenCommentThreadExists_ThreadPoliciesUnchanged() {
|
||||||
|
// create a test application
|
||||||
|
Mono<CommentThread> commentThreadMono = applicationRepository.save(createTestApplicationForCommentThreadTests())
|
||||||
|
.flatMap(savedApplication -> {
|
||||||
|
CommentThread commentThread = new CommentThread();
|
||||||
|
commentThread.setApplicationId(savedApplication.getId());
|
||||||
|
commentThread.setPolicies(policyGenerator.getAllChildPolicies(
|
||||||
|
savedApplication.getPolicies(), Application.class, CommentThread.class
|
||||||
|
));
|
||||||
|
return commentThreadRepository.save(commentThread);
|
||||||
|
}).flatMap(commentThread -> {
|
||||||
|
// update an user's role
|
||||||
|
UserRole updatedRole = createUserRole("test_developer", "test_developer", ORGANIZATION_VIEWER);
|
||||||
|
return userOrganizationService.updateRoleForMember(
|
||||||
|
organization.getId(), updatedRole, null
|
||||||
|
).thenReturn(commentThread);
|
||||||
|
}).flatMap(commentThread ->
|
||||||
|
commentThreadRepository.findById(commentThread.getId())
|
||||||
|
);
|
||||||
|
|
||||||
|
StepVerifier.create(commentThreadMono).assertNext(commentThread -> {
|
||||||
|
Set<Policy> policies = commentThread.getPolicies();
|
||||||
|
assertThat(policyUtils.isPermissionPresentForUser(
|
||||||
|
policies, AclPermission.READ_THREAD.getValue(), "test_developer"
|
||||||
|
)).isTrue();
|
||||||
|
assertThat(policyUtils.isPermissionPresentForUser(
|
||||||
|
policies, AclPermission.READ_THREAD.getValue(), "api_user"
|
||||||
|
)).isTrue();
|
||||||
|
}).verifyComplete();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@WithUserDetails("api_user")
|
||||||
|
public void updateRoleForMember_WhenCommentThreadExistsAndUserRemoved_UserRemovedFromThreadPolicies() {
|
||||||
|
Mono<CommentThread> commentThreadMono = applicationRepository.save(createTestApplicationForCommentThreadTests())
|
||||||
|
.flatMap(savedApplication -> {
|
||||||
|
CommentThread commentThread = new CommentThread();
|
||||||
|
commentThread.setApplicationId(savedApplication.getId());
|
||||||
|
commentThread.setPolicies(policyGenerator.getAllChildPolicies(
|
||||||
|
savedApplication.getPolicies(), Application.class, CommentThread.class
|
||||||
|
));
|
||||||
|
return commentThreadRepository.save(commentThread);
|
||||||
|
}).flatMap(commentThread -> {
|
||||||
|
// remove the test_developer user from the organization
|
||||||
|
UserRole updatedRole = createUserRole("test_developer", "test_developer", null);
|
||||||
|
return userOrganizationService.updateRoleForMember(organization.getId(), updatedRole, null)
|
||||||
|
.thenReturn(commentThread);
|
||||||
|
}).flatMap(commentThread ->
|
||||||
|
commentThreadRepository.findById(commentThread.getId())
|
||||||
|
);
|
||||||
|
|
||||||
|
StepVerifier.create(commentThreadMono).assertNext(commentThread -> {
|
||||||
|
Set<Policy> policies = commentThread.getPolicies();
|
||||||
|
assertThat(policyUtils.isPermissionPresentForUser(
|
||||||
|
policies, AclPermission.READ_THREAD.getValue(), "test_developer"
|
||||||
|
)).isFalse();
|
||||||
|
assertThat(policyUtils.isPermissionPresentForUser(
|
||||||
|
policies, AclPermission.READ_THREAD.getValue(), "api_user"
|
||||||
|
)).isTrue();
|
||||||
|
}).verifyComplete();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@WithUserDetails("api_user")
|
||||||
|
public void bulkAddUsersToOrganization_WhenNewUserAdded_ThreadPolicyUpdated() {
|
||||||
|
// create a new user
|
||||||
|
User user = new User();
|
||||||
|
user.setEmail("new_test_user");
|
||||||
|
Mono<User> saveUserMono = userRepository.save(user);
|
||||||
|
|
||||||
|
Mono<CommentThread> commentThreadMono = applicationRepository.save(createTestApplicationForCommentThreadTests())
|
||||||
|
.flatMap(savedApplication -> {
|
||||||
|
CommentThread commentThread = new CommentThread();
|
||||||
|
commentThread.setApplicationId(savedApplication.getId());
|
||||||
|
commentThread.setPolicies(policyGenerator.getAllChildPolicies(
|
||||||
|
savedApplication.getPolicies(), Application.class, CommentThread.class
|
||||||
|
));
|
||||||
|
return commentThreadRepository.save(commentThread);
|
||||||
|
}).flatMap(commentThread -> {
|
||||||
|
// add the new user to the organization
|
||||||
|
List<User> users = new ArrayList<>(1);
|
||||||
|
users.add(user);
|
||||||
|
return userOrganizationService
|
||||||
|
.bulkAddUsersToOrganization(organization, users, ORGANIZATION_DEVELOPER.getName())
|
||||||
|
.thenReturn(commentThread);
|
||||||
|
}).flatMap(commentThread ->
|
||||||
|
commentThreadRepository.findById(commentThread.getId())
|
||||||
|
);
|
||||||
|
|
||||||
|
StepVerifier.create(saveUserMono.then(commentThreadMono)).assertNext(commentThread -> {
|
||||||
|
Set<Policy> policies = commentThread.getPolicies();
|
||||||
|
assertThat(policyUtils.isPermissionPresentForUser(
|
||||||
|
policies, AclPermission.READ_THREAD.getValue(), "test_developer"
|
||||||
|
)).isTrue();
|
||||||
|
assertThat(policyUtils.isPermissionPresentForUser(
|
||||||
|
policies, AclPermission.READ_THREAD.getValue(), "new_test_user"
|
||||||
|
)).isTrue();
|
||||||
|
assertThat(policyUtils.isPermissionPresentForUser(
|
||||||
|
policies, AclPermission.READ_THREAD.getValue(), "api_user"
|
||||||
|
)).isTrue();
|
||||||
|
}).verifyComplete();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
Loading…
Reference in New Issue
Block a user