Fix the comment missing issue when new users added to organization (#5314)

* -Add the newly added user to existing comment threads

* -update PR as per review comment

* -updated the PR as per review
This commit is contained in:
Nayan 2021-06-28 14:50:39 +06:00 committed by GitHub
parent 2370331628
commit 36c399ac4f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 51 additions and 22 deletions

View File

@ -5,14 +5,18 @@ import com.appsmith.external.models.Policy;
import com.appsmith.server.acl.AclPermission;
import com.appsmith.server.acl.PolicyGenerator;
import com.appsmith.server.domains.Application;
import com.appsmith.server.domains.CommentThread;
import com.appsmith.server.domains.Datasource;
import com.appsmith.server.domains.NewAction;
import com.appsmith.server.domains.NewPage;
import com.appsmith.server.domains.User;
import com.appsmith.server.repositories.ApplicationRepository;
import com.appsmith.server.repositories.CommentThreadRepository;
import com.appsmith.server.repositories.DatasourceRepository;
import com.appsmith.server.repositories.NewActionRepository;
import com.appsmith.server.repositories.NewPageRepository;
import com.appsmith.server.solutions.UserChangedHandler;
import lombok.AllArgsConstructor;
import org.apache.commons.collections.CollectionUtils;
import org.springframework.stereotype.Component;
import reactor.core.publisher.Flux;
@ -32,6 +36,7 @@ import java.util.stream.Collectors;
import static com.appsmith.server.acl.AclPermission.MANAGE_DATASOURCES;
@Component
@AllArgsConstructor
public class PolicyUtils {
private final PolicyGenerator policyGenerator;
@ -39,18 +44,8 @@ public class PolicyUtils {
private final DatasourceRepository datasourceRepository;
private final NewPageRepository newPageRepository;
private final NewActionRepository newActionRepository;
public PolicyUtils(PolicyGenerator policyGenerator,
ApplicationRepository applicationRepository,
DatasourceRepository datasourceRepository,
NewPageRepository newPageRepository,
NewActionRepository newActionRepository) {
this.policyGenerator = policyGenerator;
this.applicationRepository = applicationRepository;
this.datasourceRepository = datasourceRepository;
this.newPageRepository = newPageRepository;
this.newActionRepository = newActionRepository;
}
private final UserChangedHandler userChangedHandler;
private final CommentThreadRepository commentThreadRepository;
public <T extends BaseDomain> T addPoliciesToExistingObject(Map<String, Policy> policyMap, T obj) {
// Making a deep copy here so we don't modify the `policyMap` object.
@ -224,6 +219,23 @@ public class PolicyUtils {
.saveAll(updatedPages));
}
public Flux<CommentThread> updateWithApplicationPermissionsToAllItsCommentThreads(String applicationId, Map<String, Policy> commentThreadPolicyMap, boolean addPolicyToObject) {
return
// fetch comment threads with read permissions
commentThreadRepository.findByApplicationId(applicationId, AclPermission.READ_THREAD)
.switchIfEmpty(Mono.empty())
.map(thread -> {
if (addPolicyToObject) {
return addPoliciesToExistingObject(commentThreadPolicyMap, thread);
} else {
return removePoliciesFromExistingObject(commentThreadPolicyMap, thread);
}
})
.collectList()
.flatMapMany(commentThreads -> commentThreadRepository.saveAll(commentThreads));
}
/**
* Instead of fetching actions by pageId, fetch actions by applicationId and then update the action policies
* using the new ActionPoliciesMap. This ensures the following :

View File

@ -46,5 +46,4 @@ public class CustomCommentThreadRepositoryImpl extends BaseAppsmithRepositoryImp
CommentThread.class
);
}
}

View File

@ -6,6 +6,7 @@ import com.appsmith.server.acl.AppsmithRole;
import com.appsmith.server.constants.FieldName;
import com.appsmith.server.domains.Action;
import com.appsmith.server.domains.Application;
import com.appsmith.server.domains.CommentThread;
import com.appsmith.server.domains.Datasource;
import com.appsmith.server.domains.NewAction;
import com.appsmith.server.domains.NewPage;
@ -240,6 +241,9 @@ public class UserOrganizationServiceImpl implements UserOrganizationService {
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> actionPolicyMap = policyUtils.generateInheritedPoliciesFromSourcePolicies(pagePolicyMap, Page.class, Action.class);
Map<String, Policy> commentThreadPolicyMap = policyUtils.generateInheritedPoliciesFromSourcePolicies(
applicationPolicyMap, Application.class, CommentThread.class
);
//Now update the organization policies
Organization updatedOrganization = policyUtils.removePoliciesFromExistingObject(orgPolicyMap, organization);
@ -253,13 +257,20 @@ public class UserOrganizationServiceImpl implements UserOrganizationService {
.flatMap(application -> policyUtils.updateWithApplicationPermissionsToAllItsPages(application.getId(), pagePolicyMap, false));
Flux<NewAction> updatedActionsFlux = updatedApplicationsFlux
.flatMap(application -> policyUtils.updateWithPagePermissionsToAllItsActions(application.getId(), actionPolicyMap, false));
Flux<CommentThread> updatedThreadsFlux = updatedApplicationsFlux
.flatMap(application -> policyUtils.updateWithApplicationPermissionsToAllItsCommentThreads(application.getId(), commentThreadPolicyMap, false));
return Mono.zip(updatedDatasourcesFlux.collectList(), updatedPagesFlux.collectList(), updatedActionsFlux.collectList(), Mono.just(updatedOrganization))
.flatMap(tuple -> {
//By now all the datasources/applications/pages/actions have been updated. Just save the organization now
Organization updatedOrgBeforeSave = tuple.getT4();
return organizationRepository.save(updatedOrgBeforeSave);
});
return Mono.zip(
updatedDatasourcesFlux.collectList(),
updatedPagesFlux.collectList(),
updatedActionsFlux.collectList(),
updatedThreadsFlux.collectList(),
Mono.just(updatedOrganization)
).flatMap(tuple -> {
//By now all the datasources/applications/pages/actions have been updated. Just save the organization now
Organization updatedOrgBeforeSave = tuple.getT5();
return organizationRepository.save(updatedOrgBeforeSave);
});
}
private Mono<UserRole> updateMemberRole(Organization organization, User user, UserRole userRole, User currentUser, String originHeader) {
@ -403,6 +414,9 @@ public class UserOrganizationServiceImpl implements UserOrganizationService {
Map<String, Policy> applicationPolicyMap = policyUtils.generateInheritedPoliciesFromSourcePolicies(orgPolicyMap, Organization.class, Application.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> commentThreadPolicyMap = policyUtils.generateInheritedPoliciesFromSourcePolicies(
applicationPolicyMap, Application.class, CommentThread.class
);
Map<String, Policy> actionPolicyMap = policyUtils.generateInheritedPoliciesFromSourcePolicies(pagePolicyMap, Page.class, Action.class);
//Now update the organization policies
@ -417,8 +431,14 @@ public class UserOrganizationServiceImpl implements UserOrganizationService {
.flatMap(application -> policyUtils.updateWithApplicationPermissionsToAllItsPages(application.getId(), pagePolicyMap, true));
Flux<NewAction> updatedActionsFlux = updatedApplicationsFlux
.flatMap(application -> policyUtils.updateWithPagePermissionsToAllItsActions(application.getId(), actionPolicyMap, true));
Flux<CommentThread> updatedThreadsFlux = updatedApplicationsFlux
.flatMap(application -> policyUtils.updateWithApplicationPermissionsToAllItsCommentThreads(application.getId(), commentThreadPolicyMap, true));
return Mono.when(updatedDatasourcesFlux.collectList(), updatedPagesFlux.collectList(), updatedActionsFlux.collectList())
return Mono.when(
updatedDatasourcesFlux.collectList(),
updatedPagesFlux.collectList(),
updatedActionsFlux.collectList(),
updatedThreadsFlux.collectList())
//By now all the datasources/applications/pages/actions have been updated. Just save the organization now
.then(organizationRepository.save(updatedOrganization));
}

View File

@ -623,7 +623,6 @@ public class UserServiceImpl extends BaseService<UserRepository, User, String> i
.flatMap(tuple -> {
List<User> invitedUsers = tuple.getT1();
Organization organization = tuple.getT2();
return userOrganizationService.bulkAddUsersToOrganization(organization, invitedUsers, inviteUsersDTO.getRoleName());
});

View File

@ -19,7 +19,6 @@ import reactor.core.scheduler.Schedulers;
public class UserChangedHandler {
private final ApplicationEventPublisher applicationEventPublisher;
private final CommentRepository commentRepository;
private final OrganizationRepository organizationRepository;