Adding the policy hierarchy graph and the lateral policy graph
These graphs help us map policies that are inherited from the parent and also lateral policies that are assigned to the users given that the user has a particular permission. Currently, the hierarchy has been defined for org & application. Need to cascade it to more documents such as pages & actions.
This commit is contained in:
parent
a892ee90b5
commit
1f35bd6a07
1
app/server/.gitignore
vendored
1
app/server/.gitignore
vendored
|
|
@ -4,3 +4,4 @@ target/**
|
||||||
**/.idea
|
**/.idea
|
||||||
**/target
|
**/target
|
||||||
**/dist
|
**/dist
|
||||||
|
*.iml
|
||||||
|
|
|
||||||
|
|
@ -2,6 +2,7 @@ package com.appsmith.external.models;
|
||||||
|
|
||||||
|
|
||||||
import lombok.Builder;
|
import lombok.Builder;
|
||||||
|
import lombok.EqualsAndHashCode;
|
||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
import lombok.Setter;
|
import lombok.Setter;
|
||||||
import lombok.ToString;
|
import lombok.ToString;
|
||||||
|
|
@ -16,6 +17,7 @@ import java.util.Set;
|
||||||
@Setter
|
@Setter
|
||||||
@ToString
|
@ToString
|
||||||
@Builder
|
@Builder
|
||||||
|
@EqualsAndHashCode
|
||||||
public class Policy implements Serializable {
|
public class Policy implements Serializable {
|
||||||
|
|
||||||
String permission;
|
String permission;
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
package com.appsmith.server.constants;
|
package com.appsmith.server.acl;
|
||||||
|
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
|
|
@ -0,0 +1,51 @@
|
||||||
|
package com.appsmith.server.acl;
|
||||||
|
|
||||||
|
import com.appsmith.server.domains.Action;
|
||||||
|
import com.appsmith.server.domains.Application;
|
||||||
|
import com.appsmith.server.domains.Organization;
|
||||||
|
import com.appsmith.server.domains.Page;
|
||||||
|
import lombok.Getter;
|
||||||
|
|
||||||
|
@Getter
|
||||||
|
public enum AclPermission {
|
||||||
|
|
||||||
|
// These are generic permissions created to make the transition to the new ACL format easy. They must be removed
|
||||||
|
CREATE("create", null),
|
||||||
|
READ("read", null),
|
||||||
|
UPDATE("update", null),
|
||||||
|
DELETE("delete", null),
|
||||||
|
|
||||||
|
MANAGE_ORGANIZATIONS("manage:organizations", Organization.class),
|
||||||
|
READ_ORGANIZATIONS("read:organizations", Organization.class),
|
||||||
|
ORGANIZATION_MANAGE_APPLICATIONS("manage:orgApplications", Organization.class),
|
||||||
|
ORGANIZATION_READ_APPLICATIONS("read:orgApplications", Organization.class),
|
||||||
|
ORGANIZATION_PUBLISH_APPLICATIONS("publish:orgApplications", Organization.class),
|
||||||
|
|
||||||
|
MANAGE_APPLICATIONS("manage:applications", Application.class),
|
||||||
|
READ_APPLICATIONS("read:applications", Application.class),
|
||||||
|
PUBLISH_APPLICATIONS("publish:applications", Application.class),
|
||||||
|
|
||||||
|
MANAGE_PAGES("manage:pages", Page.class),
|
||||||
|
READ_PAGES("read:pages", Page.class),
|
||||||
|
|
||||||
|
MANAGE_ACTIONS("manage:actions", Action.class),
|
||||||
|
READ_ACTIONS("read:actions", Action.class),
|
||||||
|
EXECUTE_ACTIONS("execute:actions", Action.class);
|
||||||
|
|
||||||
|
private String value;
|
||||||
|
private Class entity;
|
||||||
|
|
||||||
|
AclPermission(String value, Class entity) {
|
||||||
|
this.value = value;
|
||||||
|
this.entity = entity;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static final AclPermission getPermissionByValue(String value, Class entity) {
|
||||||
|
for (AclPermission permission : values()) {
|
||||||
|
if (permission.getValue().equals(value) && permission.getEntity().equals(entity)) {
|
||||||
|
return permission;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,106 @@
|
||||||
|
package com.appsmith.server.acl;
|
||||||
|
|
||||||
|
import com.appsmith.external.models.Policy;
|
||||||
|
import com.appsmith.server.domains.User;
|
||||||
|
import lombok.Getter;
|
||||||
|
import lombok.Setter;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.jgrapht.Graph;
|
||||||
|
import org.jgrapht.graph.DefaultEdge;
|
||||||
|
import org.jgrapht.graph.DirectedMultigraph;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
import javax.annotation.PostConstruct;
|
||||||
|
import java.util.EnumSet;
|
||||||
|
import java.util.Set;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
|
import static com.appsmith.server.acl.AclPermission.MANAGE_ACTIONS;
|
||||||
|
import static com.appsmith.server.acl.AclPermission.MANAGE_APPLICATIONS;
|
||||||
|
import static com.appsmith.server.acl.AclPermission.MANAGE_ORGANIZATIONS;
|
||||||
|
import static com.appsmith.server.acl.AclPermission.MANAGE_PAGES;
|
||||||
|
import static com.appsmith.server.acl.AclPermission.ORGANIZATION_MANAGE_APPLICATIONS;
|
||||||
|
import static com.appsmith.server.acl.AclPermission.ORGANIZATION_PUBLISH_APPLICATIONS;
|
||||||
|
import static com.appsmith.server.acl.AclPermission.ORGANIZATION_READ_APPLICATIONS;
|
||||||
|
import static com.appsmith.server.acl.AclPermission.PUBLISH_APPLICATIONS;
|
||||||
|
import static com.appsmith.server.acl.AclPermission.READ_ACTIONS;
|
||||||
|
import static com.appsmith.server.acl.AclPermission.READ_APPLICATIONS;
|
||||||
|
import static com.appsmith.server.acl.AclPermission.READ_ORGANIZATIONS;
|
||||||
|
import static com.appsmith.server.acl.AclPermission.READ_PAGES;
|
||||||
|
|
||||||
|
@Getter
|
||||||
|
@Setter
|
||||||
|
@Slf4j
|
||||||
|
@Component
|
||||||
|
public class PolicyGenerator {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This graph defines the hierarchy of permissions from parent objects
|
||||||
|
*/
|
||||||
|
Graph<AclPermission, DefaultEdge> hierarchyGraph = new DirectedMultigraph<>(DefaultEdge.class);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This graph defines the permissions that must be given to a user given that they have another permission
|
||||||
|
* Eg: If the user is being given MANAGE_APPLICATION permission, they must also be given READ_APPLICATION permission
|
||||||
|
*/
|
||||||
|
Graph<AclPermission, DefaultEdge> lateralGraph = new DirectedMultigraph<>(DefaultEdge.class);
|
||||||
|
|
||||||
|
@PostConstruct
|
||||||
|
public void createPolicyGraph() {
|
||||||
|
|
||||||
|
EnumSet.allOf(AclPermission.class)
|
||||||
|
.forEach(permission -> {
|
||||||
|
hierarchyGraph.addVertex(permission);
|
||||||
|
lateralGraph.addVertex(permission);
|
||||||
|
});
|
||||||
|
|
||||||
|
createOrganizationPolicyGraph();
|
||||||
|
createApplicationPolicyGraph();
|
||||||
|
createPagePolicyGraph();
|
||||||
|
createActionPolicyGraph();
|
||||||
|
|
||||||
|
log.debug("Successfully created the createGraph & lateralGraph");
|
||||||
|
}
|
||||||
|
|
||||||
|
private void createOrganizationPolicyGraph() {
|
||||||
|
lateralGraph.addEdge(MANAGE_ORGANIZATIONS, READ_ORGANIZATIONS);
|
||||||
|
lateralGraph.addEdge(MANAGE_ORGANIZATIONS, ORGANIZATION_MANAGE_APPLICATIONS);
|
||||||
|
lateralGraph.addEdge(MANAGE_ORGANIZATIONS, ORGANIZATION_READ_APPLICATIONS);
|
||||||
|
lateralGraph.addEdge(MANAGE_ORGANIZATIONS, ORGANIZATION_PUBLISH_APPLICATIONS);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void createApplicationPolicyGraph() {
|
||||||
|
hierarchyGraph.addEdge(ORGANIZATION_MANAGE_APPLICATIONS, MANAGE_APPLICATIONS);
|
||||||
|
hierarchyGraph.addEdge(ORGANIZATION_READ_APPLICATIONS, READ_APPLICATIONS);
|
||||||
|
hierarchyGraph.addEdge(ORGANIZATION_PUBLISH_APPLICATIONS, PUBLISH_APPLICATIONS);
|
||||||
|
|
||||||
|
// If the user is being given MANAGE_APPLICATION permission, they must also be given READ_APPLICATION perm
|
||||||
|
lateralGraph.addEdge(MANAGE_APPLICATIONS, READ_APPLICATIONS);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void createActionPolicyGraph() {
|
||||||
|
hierarchyGraph.addEdge(MANAGE_PAGES, MANAGE_ACTIONS);
|
||||||
|
hierarchyGraph.addEdge(READ_PAGES, READ_ACTIONS);
|
||||||
|
|
||||||
|
lateralGraph.addEdge(MANAGE_PAGES, READ_PAGES);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void createPagePolicyGraph() {
|
||||||
|
hierarchyGraph.addEdge(MANAGE_APPLICATIONS, MANAGE_PAGES);
|
||||||
|
hierarchyGraph.addEdge(READ_APPLICATIONS, READ_PAGES);
|
||||||
|
|
||||||
|
lateralGraph.addEdge(MANAGE_PAGES, READ_PAGES);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Set<Policy> getLateralPoliciesForUser(AclPermission permission, User user) {
|
||||||
|
Set<DefaultEdge> lateralEdges = lateralGraph.outgoingEdgesOf(permission);
|
||||||
|
return lateralEdges.stream()
|
||||||
|
.map(lateralEdge -> {
|
||||||
|
AclPermission lateralPermission = lateralGraph.getEdgeTarget(lateralEdge);
|
||||||
|
return Policy.builder().permission(lateralPermission.getValue())
|
||||||
|
.users(Set.of(user.getUsername())).build();
|
||||||
|
})
|
||||||
|
.collect(Collectors.toSet());
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
package com.appsmith.server.authentication.handlers;
|
package com.appsmith.server.authentication.handlers;
|
||||||
|
|
||||||
import com.appsmith.server.constants.AclConstants;
|
import com.appsmith.server.acl.AclConstants;
|
||||||
import com.appsmith.server.constants.Security;
|
import com.appsmith.server.constants.Security;
|
||||||
import com.appsmith.server.domains.LoginSource;
|
import com.appsmith.server.domains.LoginSource;
|
||||||
import com.appsmith.server.domains.User;
|
import com.appsmith.server.domains.User;
|
||||||
|
|
|
||||||
|
|
@ -1,13 +0,0 @@
|
||||||
package com.appsmith.server.constants;
|
|
||||||
|
|
||||||
import com.appsmith.external.models.BaseDomain;
|
|
||||||
import org.springframework.stereotype.Component;
|
|
||||||
|
|
||||||
@Component
|
|
||||||
public class AclComponent<T extends BaseDomain> {
|
|
||||||
|
|
||||||
public String getPermission(Object entity) {
|
|
||||||
System.out.println("In the getPermission");
|
|
||||||
return "read:applications";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,34 +0,0 @@
|
||||||
package com.appsmith.server.constants;
|
|
||||||
|
|
||||||
import lombok.Getter;
|
|
||||||
|
|
||||||
@Getter
|
|
||||||
public enum AclPermission {
|
|
||||||
|
|
||||||
// These are generic permissions created to make the transition to the new ACL format easy. They must be removed
|
|
||||||
CREATE("create", null),
|
|
||||||
READ("read", null),
|
|
||||||
UPDATE("update", null),
|
|
||||||
DELETE("delete", null),
|
|
||||||
|
|
||||||
CREATE_ORGANIZATIONS("create:organizations", null),
|
|
||||||
READ_ORGANIZATIONS("read:organizations", null),
|
|
||||||
UPDATE_ORGANIZATIONS("update:organizations", null),
|
|
||||||
DELETE_ORGANIZATIONS("delete:organizations", null),
|
|
||||||
|
|
||||||
MANAGE_APPLICATIONS("manage:applications", null),
|
|
||||||
READ_APPLICATIONS("read:applications", MANAGE_APPLICATIONS),
|
|
||||||
|
|
||||||
CREATE_PAGES("create:pages", null),
|
|
||||||
READ_PAGES("read:pages", CREATE_PAGES),
|
|
||||||
UPDATE_PAGES("update:pages", null),
|
|
||||||
DELETE_PAGES("delete:pages", null);
|
|
||||||
|
|
||||||
|
|
||||||
private String value;
|
|
||||||
private AclPermission parent;
|
|
||||||
|
|
||||||
AclPermission(String value, AclPermission parent) {
|
|
||||||
this.value = value;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
package com.appsmith.server.repositories;
|
package com.appsmith.server.repositories;
|
||||||
|
|
||||||
import com.appsmith.server.constants.AclPermission;
|
import com.appsmith.server.acl.AclPermission;
|
||||||
import reactor.core.publisher.Mono;
|
import reactor.core.publisher.Mono;
|
||||||
|
|
||||||
public interface AppsmithRepository<T> {
|
public interface AppsmithRepository<T> {
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,7 @@ package com.appsmith.server.repositories;
|
||||||
|
|
||||||
import com.appsmith.external.models.BaseDomain;
|
import com.appsmith.external.models.BaseDomain;
|
||||||
import com.appsmith.external.models.QBaseDomain;
|
import com.appsmith.external.models.QBaseDomain;
|
||||||
import com.appsmith.server.constants.AclPermission;
|
import com.appsmith.server.acl.AclPermission;
|
||||||
import com.appsmith.server.constants.FieldName;
|
import com.appsmith.server.constants.FieldName;
|
||||||
import com.appsmith.server.domains.User;
|
import com.appsmith.server.domains.User;
|
||||||
import com.appsmith.server.exceptions.AppsmithError;
|
import com.appsmith.server.exceptions.AppsmithError;
|
||||||
|
|
@ -54,13 +54,13 @@ public abstract class BaseAppsmithRepositoryImpl<T extends BaseDomain> {
|
||||||
public static final Criteria userAcl(User user, AclPermission permission) {
|
public static final Criteria userAcl(User user, AclPermission permission) {
|
||||||
log.debug("Going to add userAcl for user: {} and permission: {}", user.getUsername(), permission.getValue());
|
log.debug("Going to add userAcl for user: {} and permission: {}", user.getUsername(), permission.getValue());
|
||||||
|
|
||||||
Criteria userCriteria = Criteria.where("policies")
|
Criteria userCriteria = Criteria.where(fieldName(QBaseDomain.baseDomain.policies))
|
||||||
.elemMatch(Criteria.where("users").all(user.getUsername())
|
.elemMatch(Criteria.where("users").all(user.getUsername())
|
||||||
.and("permission").is(permission.getValue())
|
.and("permission").is(permission.getValue())
|
||||||
);
|
);
|
||||||
log.debug("Got the userCriteria: {}", userCriteria.getCriteriaObject());
|
log.debug("Got the userCriteria: {}", userCriteria.getCriteriaObject());
|
||||||
|
|
||||||
Criteria groupCriteria = Criteria.where("policies")
|
Criteria groupCriteria = Criteria.where(fieldName(QBaseDomain.baseDomain.policies))
|
||||||
.elemMatch(Criteria.where("groups").all(user.getGroupIds())
|
.elemMatch(Criteria.where("groups").all(user.getGroupIds())
|
||||||
.and("permission").is(permission.getValue()));
|
.and("permission").is(permission.getValue()));
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
package com.appsmith.server.repositories;
|
package com.appsmith.server.repositories;
|
||||||
|
|
||||||
import com.appsmith.external.models.BaseDomain;
|
import com.appsmith.external.models.BaseDomain;
|
||||||
import com.appsmith.server.constants.AclPermission;
|
import com.appsmith.server.acl.AclPermission;
|
||||||
import com.appsmith.server.constants.FieldName;
|
import com.appsmith.server.constants.FieldName;
|
||||||
import com.appsmith.server.domains.User;
|
import com.appsmith.server.domains.User;
|
||||||
import lombok.NonNull;
|
import lombok.NonNull;
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
package com.appsmith.server.repositories;
|
package com.appsmith.server.repositories;
|
||||||
|
|
||||||
import com.appsmith.server.constants.AclPermission;
|
import com.appsmith.server.acl.AclPermission;
|
||||||
import com.appsmith.server.domains.Application;
|
import com.appsmith.server.domains.Application;
|
||||||
import reactor.core.publisher.Mono;
|
import reactor.core.publisher.Mono;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
package com.appsmith.server.repositories;
|
package com.appsmith.server.repositories;
|
||||||
|
|
||||||
import com.appsmith.server.constants.AclPermission;
|
import com.appsmith.server.acl.AclPermission;
|
||||||
import com.appsmith.server.domains.Application;
|
import com.appsmith.server.domains.Application;
|
||||||
import com.appsmith.server.domains.QApplication;
|
import com.appsmith.server.domains.QApplication;
|
||||||
import com.appsmith.server.domains.User;
|
import com.appsmith.server.domains.User;
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,8 @@
|
||||||
package com.appsmith.server.services;
|
package com.appsmith.server.services;
|
||||||
|
|
||||||
import com.appsmith.external.models.Policy;
|
import com.appsmith.external.models.Policy;
|
||||||
import com.appsmith.server.constants.AclPermission;
|
import com.appsmith.server.acl.AclPermission;
|
||||||
|
import com.appsmith.server.acl.PolicyGenerator;
|
||||||
import com.appsmith.server.constants.AnalyticsEvents;
|
import com.appsmith.server.constants.AnalyticsEvents;
|
||||||
import com.appsmith.server.constants.FieldName;
|
import com.appsmith.server.constants.FieldName;
|
||||||
import com.appsmith.server.domains.Application;
|
import com.appsmith.server.domains.Application;
|
||||||
|
|
@ -13,15 +14,20 @@ import com.appsmith.server.domains.User;
|
||||||
import com.appsmith.server.exceptions.AppsmithError;
|
import com.appsmith.server.exceptions.AppsmithError;
|
||||||
import com.appsmith.server.exceptions.AppsmithException;
|
import com.appsmith.server.exceptions.AppsmithException;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.jgrapht.graph.DefaultEdge;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
import reactor.core.publisher.Mono;
|
import reactor.core.publisher.Mono;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
|
import java.util.HashSet;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
|
import static com.appsmith.server.acl.AclPermission.ORGANIZATION_MANAGE_APPLICATIONS;
|
||||||
|
import static com.appsmith.server.acl.AclPermission.ORGANIZATION_READ_APPLICATIONS;
|
||||||
|
|
||||||
@Slf4j
|
@Slf4j
|
||||||
@Service
|
@Service
|
||||||
public class ApplicationPageServiceImpl implements ApplicationPageService {
|
public class ApplicationPageServiceImpl implements ApplicationPageService {
|
||||||
|
|
@ -31,17 +37,20 @@ public class ApplicationPageServiceImpl implements ApplicationPageService {
|
||||||
private final OrganizationService organizationService;
|
private final OrganizationService organizationService;
|
||||||
|
|
||||||
private final AnalyticsService analyticsService;
|
private final AnalyticsService analyticsService;
|
||||||
|
private final PolicyGenerator policyGenerator;
|
||||||
|
|
||||||
public ApplicationPageServiceImpl(ApplicationService applicationService,
|
public ApplicationPageServiceImpl(ApplicationService applicationService,
|
||||||
PageService pageService,
|
PageService pageService,
|
||||||
SessionUserService sessionUserService,
|
SessionUserService sessionUserService,
|
||||||
OrganizationService organizationService,
|
OrganizationService organizationService,
|
||||||
AnalyticsService analyticsService) {
|
AnalyticsService analyticsService,
|
||||||
|
PolicyGenerator policyGenerator) {
|
||||||
this.applicationService = applicationService;
|
this.applicationService = applicationService;
|
||||||
this.pageService = pageService;
|
this.pageService = pageService;
|
||||||
this.sessionUserService = sessionUserService;
|
this.sessionUserService = sessionUserService;
|
||||||
this.organizationService = organizationService;
|
this.organizationService = organizationService;
|
||||||
this.analyticsService = analyticsService;
|
this.analyticsService = analyticsService;
|
||||||
|
this.policyGenerator = policyGenerator;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Mono<Page> createPage(Page page) {
|
public Mono<Page> createPage(Page page) {
|
||||||
|
|
@ -62,7 +71,7 @@ public class ApplicationPageServiceImpl implements ApplicationPageService {
|
||||||
page.setLayouts(layoutList);
|
page.setLayouts(layoutList);
|
||||||
}
|
}
|
||||||
|
|
||||||
Mono<Application> applicationMono = applicationService.findById(page.getApplicationId(), AclPermission.CREATE_PAGES)
|
Mono<Application> applicationMono = applicationService.findById(page.getApplicationId(), AclPermission.MANAGE_PAGES)
|
||||||
.switchIfEmpty(Mono.error(new AppsmithException(AppsmithError.NO_RESOURCE_FOUND, FieldName.APPLICATION_ID, page.getApplicationId())));
|
.switchIfEmpty(Mono.error(new AppsmithException(AppsmithError.NO_RESOURCE_FOUND, FieldName.APPLICATION_ID, page.getApplicationId())));
|
||||||
|
|
||||||
return applicationMono
|
return applicationMono
|
||||||
|
|
@ -199,7 +208,7 @@ public class ApplicationPageServiceImpl implements ApplicationPageService {
|
||||||
.flatMap(user -> {
|
.flatMap(user -> {
|
||||||
String orgId = user.getCurrentOrganizationId();
|
String orgId = user.getCurrentOrganizationId();
|
||||||
|
|
||||||
Mono<Organization> orgMono = organizationService.findById(orgId, AclPermission.MANAGE_APPLICATIONS)
|
Mono<Organization> orgMono = organizationService.findById(orgId, ORGANIZATION_MANAGE_APPLICATIONS)
|
||||||
.switchIfEmpty(Mono.error(new AppsmithException(AppsmithError.NO_RESOURCE_FOUND, FieldName.ORGANIZATION, orgId)));
|
.switchIfEmpty(Mono.error(new AppsmithException(AppsmithError.NO_RESOURCE_FOUND, FieldName.ORGANIZATION, orgId)));
|
||||||
|
|
||||||
return orgMono.map(org -> {
|
return orgMono.map(org -> {
|
||||||
|
|
@ -208,18 +217,36 @@ public class ApplicationPageServiceImpl implements ApplicationPageService {
|
||||||
// to the new application that we are creating.
|
// to the new application that we are creating.
|
||||||
Set<Policy> policySet = org.getPolicies().stream()
|
Set<Policy> policySet = org.getPolicies().stream()
|
||||||
.filter(policy ->
|
.filter(policy ->
|
||||||
policy.getPermission().equals(AclPermission.READ_APPLICATIONS.getValue()) ||
|
policy.getPermission().equals(ORGANIZATION_MANAGE_APPLICATIONS.getValue()) ||
|
||||||
policy.getPermission().equals(AclPermission.MANAGE_APPLICATIONS.getValue())
|
policy.getPermission().equals(ORGANIZATION_READ_APPLICATIONS.getValue())
|
||||||
).collect(Collectors.toSet());
|
).collect(Collectors.toSet());
|
||||||
Set<String> users = policySet.stream()
|
|
||||||
.map(policy -> policy.getUsers())
|
Set<Policy> documentPolicies = policySet.stream()
|
||||||
|
.map(policy -> {
|
||||||
|
AclPermission aclPermission = AclPermission
|
||||||
|
.getPermissionByValue(policy.getPermission(), Organization.class);
|
||||||
|
|
||||||
|
// Check the hierarchy graph to derive child permissions that must be given to this
|
||||||
|
// document
|
||||||
|
Set<Policy> childPolicySet = new HashSet<>();
|
||||||
|
Set<DefaultEdge> edges = policyGenerator.getHierarchyGraph()
|
||||||
|
.outgoingEdgesOf(aclPermission);
|
||||||
|
for (DefaultEdge edge: edges) {
|
||||||
|
AclPermission childPermission = policyGenerator.getHierarchyGraph().getEdgeTarget(edge);
|
||||||
|
childPolicySet.add(Policy.builder().permission(childPermission.getValue())
|
||||||
|
.users(policy.getUsers()).build());
|
||||||
|
|
||||||
|
// Get the lateral permissions that must be applied given the child permission
|
||||||
|
// This is applied at a user level and not from the parent object. Hence only the
|
||||||
|
// current user gets these permissions
|
||||||
|
childPolicySet.addAll(policyGenerator.getLateralPoliciesForUser(childPermission, user));
|
||||||
|
}
|
||||||
|
childPolicySet.addAll(policyGenerator.getLateralPoliciesForUser(aclPermission, user));
|
||||||
|
return childPolicySet;
|
||||||
|
})
|
||||||
.flatMap(Collection::stream)
|
.flatMap(Collection::stream)
|
||||||
.collect(Collectors.toSet());
|
.collect(Collectors.toSet());
|
||||||
policySet.add(Policy.builder()
|
application.setPolicies(documentPolicies);
|
||||||
.permission(AclPermission.CREATE_PAGES.getValue())
|
|
||||||
.users(Set.of(user.getUsername())).build()
|
|
||||||
);
|
|
||||||
application.setPolicies(policySet);
|
|
||||||
return application;
|
return application;
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
package com.appsmith.server.services;
|
package com.appsmith.server.services;
|
||||||
|
|
||||||
import com.appsmith.server.constants.AclPermission;
|
import com.appsmith.server.acl.AclPermission;
|
||||||
import com.appsmith.server.domains.Application;
|
import com.appsmith.server.domains.Application;
|
||||||
import reactor.core.publisher.Mono;
|
import reactor.core.publisher.Mono;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
package com.appsmith.server.services;
|
package com.appsmith.server.services;
|
||||||
|
|
||||||
import com.appsmith.server.constants.AclPermission;
|
import com.appsmith.server.acl.AclPermission;
|
||||||
import com.appsmith.server.constants.AnalyticsEvents;
|
import com.appsmith.server.constants.AnalyticsEvents;
|
||||||
import com.appsmith.server.constants.Entity;
|
import com.appsmith.server.constants.Entity;
|
||||||
import com.appsmith.server.constants.FieldName;
|
import com.appsmith.server.constants.FieldName;
|
||||||
|
|
@ -13,15 +13,11 @@ import com.appsmith.server.exceptions.AppsmithException;
|
||||||
import com.appsmith.server.repositories.ActionRepository;
|
import com.appsmith.server.repositories.ActionRepository;
|
||||||
import com.appsmith.server.repositories.ApplicationRepository;
|
import com.appsmith.server.repositories.ApplicationRepository;
|
||||||
import com.appsmith.server.repositories.PageRepository;
|
import com.appsmith.server.repositories.PageRepository;
|
||||||
import com.mongodb.DBObject;
|
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.data.domain.Example;
|
import org.springframework.data.domain.Example;
|
||||||
import org.springframework.data.mongodb.core.ReactiveMongoTemplate;
|
import org.springframework.data.mongodb.core.ReactiveMongoTemplate;
|
||||||
import org.springframework.data.mongodb.core.convert.MongoConverter;
|
import org.springframework.data.mongodb.core.convert.MongoConverter;
|
||||||
import org.springframework.data.mongodb.core.query.Criteria;
|
|
||||||
import org.springframework.data.mongodb.core.query.Query;
|
|
||||||
import org.springframework.data.mongodb.core.query.Update;
|
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
import org.springframework.util.MultiValueMap;
|
import org.springframework.util.MultiValueMap;
|
||||||
import reactor.core.publisher.Flux;
|
import reactor.core.publisher.Flux;
|
||||||
|
|
@ -31,7 +27,6 @@ import reactor.core.scheduler.Scheduler;
|
||||||
import javax.validation.Validator;
|
import javax.validation.Validator;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
|
|
||||||
@Slf4j
|
@Slf4j
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,6 @@
|
||||||
package com.appsmith.server.services;
|
package com.appsmith.server.services;
|
||||||
|
|
||||||
import com.appsmith.external.models.BaseDomain;
|
import com.appsmith.external.models.BaseDomain;
|
||||||
import com.appsmith.server.constants.AclPermission;
|
|
||||||
import com.appsmith.server.constants.AnalyticsEvents;
|
import com.appsmith.server.constants.AnalyticsEvents;
|
||||||
import com.appsmith.server.constants.FieldName;
|
import com.appsmith.server.constants.FieldName;
|
||||||
import com.appsmith.server.exceptions.AppsmithError;
|
import com.appsmith.server.exceptions.AppsmithError;
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
package com.appsmith.server.services;
|
package com.appsmith.server.services;
|
||||||
|
|
||||||
import com.appsmith.server.constants.AclConstants;
|
import com.appsmith.server.acl.AclConstants;
|
||||||
import com.appsmith.server.constants.FieldName;
|
import com.appsmith.server.constants.FieldName;
|
||||||
import com.appsmith.server.domains.Group;
|
import com.appsmith.server.domains.Group;
|
||||||
import com.appsmith.server.repositories.GroupRepository;
|
import com.appsmith.server.repositories.GroupRepository;
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
package com.appsmith.server.services;
|
package com.appsmith.server.services;
|
||||||
|
|
||||||
import com.appsmith.server.constants.AclPermission;
|
import com.appsmith.server.acl.AclPermission;
|
||||||
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 reactor.core.publisher.Mono;
|
import reactor.core.publisher.Mono;
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,8 @@
|
||||||
package com.appsmith.server.services;
|
package com.appsmith.server.services;
|
||||||
|
|
||||||
import com.appsmith.external.models.Policy;
|
import com.appsmith.external.models.Policy;
|
||||||
import com.appsmith.server.constants.AclPermission;
|
import com.appsmith.server.acl.AclPermission;
|
||||||
|
import com.appsmith.server.acl.PolicyGenerator;
|
||||||
import com.appsmith.server.constants.AnalyticsEvents;
|
import com.appsmith.server.constants.AnalyticsEvents;
|
||||||
import com.appsmith.server.constants.FieldName;
|
import com.appsmith.server.constants.FieldName;
|
||||||
import com.appsmith.server.domains.Organization;
|
import com.appsmith.server.domains.Organization;
|
||||||
|
|
@ -15,6 +16,7 @@ import com.appsmith.server.exceptions.AppsmithException;
|
||||||
import com.appsmith.server.repositories.OrganizationRepository;
|
import com.appsmith.server.repositories.OrganizationRepository;
|
||||||
import com.appsmith.server.repositories.PluginRepository;
|
import com.appsmith.server.repositories.PluginRepository;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.jgrapht.graph.DefaultEdge;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.data.mongodb.core.ReactiveMongoTemplate;
|
import org.springframework.data.mongodb.core.ReactiveMongoTemplate;
|
||||||
import org.springframework.data.mongodb.core.convert.MongoConverter;
|
import org.springframework.data.mongodb.core.convert.MongoConverter;
|
||||||
|
|
@ -26,11 +28,14 @@ import reactor.core.scheduler.Scheduler;
|
||||||
|
|
||||||
import javax.validation.Validator;
|
import javax.validation.Validator;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
import java.util.Collection;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
|
import static com.appsmith.server.acl.AclPermission.MANAGE_ORGANIZATIONS;
|
||||||
|
|
||||||
@Slf4j
|
@Slf4j
|
||||||
@Service
|
@Service
|
||||||
public class OrganizationServiceImpl extends BaseService<OrganizationRepository, Organization, String> implements OrganizationService {
|
public class OrganizationServiceImpl extends BaseService<OrganizationRepository, Organization, String> implements OrganizationService {
|
||||||
|
|
@ -41,6 +46,7 @@ public class OrganizationServiceImpl extends BaseService<OrganizationRepository,
|
||||||
private final PluginRepository pluginRepository;
|
private final PluginRepository pluginRepository;
|
||||||
private final SessionUserService sessionUserService;
|
private final SessionUserService sessionUserService;
|
||||||
private final UserOrganizationService userOrganizationService;
|
private final UserOrganizationService userOrganizationService;
|
||||||
|
private final PolicyGenerator policyGenerator;
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
public OrganizationServiceImpl(Scheduler scheduler,
|
public OrganizationServiceImpl(Scheduler scheduler,
|
||||||
|
|
@ -53,7 +59,8 @@ public class OrganizationServiceImpl extends BaseService<OrganizationRepository,
|
||||||
GroupService groupService,
|
GroupService groupService,
|
||||||
PluginRepository pluginRepository,
|
PluginRepository pluginRepository,
|
||||||
SessionUserService sessionUserService,
|
SessionUserService sessionUserService,
|
||||||
UserOrganizationService userOrganizationService) {
|
UserOrganizationService userOrganizationService,
|
||||||
|
PolicyGenerator policyGenerator) {
|
||||||
super(scheduler, validator, mongoConverter, reactiveMongoTemplate, repository, analyticsService);
|
super(scheduler, validator, mongoConverter, reactiveMongoTemplate, repository, analyticsService);
|
||||||
this.repository = repository;
|
this.repository = repository;
|
||||||
this.settingService = settingService;
|
this.settingService = settingService;
|
||||||
|
|
@ -61,6 +68,7 @@ public class OrganizationServiceImpl extends BaseService<OrganizationRepository,
|
||||||
this.pluginRepository = pluginRepository;
|
this.pluginRepository = pluginRepository;
|
||||||
this.sessionUserService = sessionUserService;
|
this.sessionUserService = sessionUserService;
|
||||||
this.userOrganizationService = userOrganizationService;
|
this.userOrganizationService = userOrganizationService;
|
||||||
|
this.policyGenerator = policyGenerator;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
@ -81,41 +89,62 @@ public class OrganizationServiceImpl extends BaseService<OrganizationRepository,
|
||||||
return repository.findByName(name);
|
return repository.findByName(name);
|
||||||
}
|
}
|
||||||
|
|
||||||
private Set<Policy> crudAppPolicy(User user) {
|
// private Set<Policy> crudAppPolicy(User user) {
|
||||||
Policy readAppPolicy = Policy.builder().permission(AclPermission.READ_APPLICATIONS.getValue())
|
// Policy readAppPolicy = Policy.builder().permission(AclPermission.READ_APPLICATIONS.getValue())
|
||||||
.users(Set.of(user.getUsername()))
|
// .users(Set.of(user.getUsername()))
|
||||||
.build();
|
// .build();
|
||||||
|
//
|
||||||
Policy manageAppPolicy = Policy.builder().permission(AclPermission.MANAGE_APPLICATIONS.getValue())
|
// Policy manageAppPolicy = Policy.builder().permission(AclPermission.MANAGE_APPLICATIONS.getValue())
|
||||||
.users(Set.of(user.getUsername()))
|
// .users(Set.of(user.getUsername()))
|
||||||
.build();
|
// .build();
|
||||||
|
//
|
||||||
return Set.of(manageAppPolicy, readAppPolicy);
|
// return Set.of(manageAppPolicy, readAppPolicy);
|
||||||
}
|
// }
|
||||||
|
|
||||||
private Set<Policy> crudOrgPolicy(User user) {
|
private Set<Policy> crudOrgPolicy(User user) {
|
||||||
Policy readOrgPolicy = Policy.builder().permission(AclPermission.READ_ORGANIZATIONS.getValue())
|
Set<Policy> policySet = user.getPolicies().stream()
|
||||||
.users(Set.of(user.getUsername()))
|
.filter(policy ->
|
||||||
.build();
|
policy.getPermission().equals(MANAGE_ORGANIZATIONS.getValue())
|
||||||
|
).collect(Collectors.toSet());
|
||||||
|
|
||||||
Policy updateOrgPolicy = Policy.builder().permission(AclPermission.UPDATE_ORGANIZATIONS.getValue())
|
Set<Policy> documentPolicies = policySet.stream()
|
||||||
.users(Set.of(user.getUsername()))
|
.map(policy -> {
|
||||||
.build();
|
AclPermission aclPermission = AclPermission
|
||||||
|
.getPermissionByValue(policy.getPermission(), Organization.class);
|
||||||
|
// Check the hierarchy graph to derive child permissions that must be given to this
|
||||||
|
// document
|
||||||
|
Set<Policy> childPolicySet = new HashSet<>();
|
||||||
|
Set<DefaultEdge> edges = policyGenerator.getHierarchyGraph()
|
||||||
|
.outgoingEdgesOf(aclPermission);
|
||||||
|
for (DefaultEdge edge : edges) {
|
||||||
|
AclPermission childPermission = policyGenerator.getHierarchyGraph().getEdgeTarget(edge);
|
||||||
|
childPolicySet.add(Policy.builder().permission(childPermission.getValue())
|
||||||
|
.users(policy.getUsers()).build());
|
||||||
|
|
||||||
Policy deleteOrgPolicy = Policy.builder().permission(AclPermission.DELETE_ORGANIZATIONS.getValue())
|
// Get the lateral permissions that must be applied given the child permission
|
||||||
|
// This is applied at a user level and not from the parent object. Hence only the
|
||||||
|
// current user gets these permissions
|
||||||
|
childPolicySet.addAll(policyGenerator.getLateralPoliciesForUser(childPermission, user));
|
||||||
|
}
|
||||||
|
childPolicySet.addAll(policyGenerator.getLateralPoliciesForUser(aclPermission, user));
|
||||||
|
return childPolicySet;
|
||||||
|
}).flatMap(Collection::stream)
|
||||||
|
.collect(Collectors.toSet());
|
||||||
|
|
||||||
|
Policy manageOrgPolicy = Policy.builder().permission(MANAGE_ORGANIZATIONS.getValue())
|
||||||
.users(Set.of(user.getUsername()))
|
.users(Set.of(user.getUsername()))
|
||||||
.build();
|
.build();
|
||||||
return Set.of(readOrgPolicy, updateOrgPolicy,deleteOrgPolicy);
|
documentPolicies.add(manageOrgPolicy);
|
||||||
|
return documentPolicies;
|
||||||
}
|
}
|
||||||
|
|
||||||
private Set<Policy> adminPoliciesForOrganization(User user) {
|
private Set<Policy> adminPoliciesForOrganization(User user) {
|
||||||
|
|
||||||
Set<Policy> crudAppPolicies = crudAppPolicy(user);
|
|
||||||
Set<Policy> crudOrgPolicies = crudOrgPolicy(user);
|
Set<Policy> crudOrgPolicies = crudOrgPolicy(user);
|
||||||
|
|
||||||
Set<Policy> adminPolicies = new HashSet<>();
|
Set<Policy> adminPolicies = new HashSet<>();
|
||||||
adminPolicies.addAll(crudOrgPolicies);
|
adminPolicies.addAll(crudOrgPolicies);
|
||||||
adminPolicies.addAll(crudAppPolicies);
|
|
||||||
return adminPolicies;
|
return adminPolicies;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -138,7 +167,7 @@ public class OrganizationServiceImpl extends BaseService<OrganizationRepository,
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set the admin policies for this organization & user
|
// Set the admin policies for this organization & user
|
||||||
organization.setPolicies(adminPoliciesForOrganization(user));
|
organization.setPolicies(crudOrgPolicy(user));
|
||||||
|
|
||||||
Mono<Organization> organizationMono = Mono.just(organization)
|
Mono<Organization> organizationMono = Mono.just(organization)
|
||||||
.flatMap(this::validateObject)
|
.flatMap(this::validateObject)
|
||||||
|
|
@ -219,7 +248,7 @@ public class OrganizationServiceImpl extends BaseService<OrganizationRepository,
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Mono<Organization> update(String id, Organization resource) {
|
public Mono<Organization> update(String id, Organization resource) {
|
||||||
return repository.updateById(id, resource, AclPermission.UPDATE_ORGANIZATIONS)
|
return repository.updateById(id, resource, MANAGE_ORGANIZATIONS)
|
||||||
.flatMap(updatedObj -> analyticsService.sendEvent(AnalyticsEvents.UPDATE + "_" + updatedObj.getClass().getSimpleName().toUpperCase(), updatedObj));
|
.flatMap(updatedObj -> analyticsService.sendEvent(AnalyticsEvents.UPDATE + "_" + updatedObj.getClass().getSimpleName().toUpperCase(), updatedObj));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
package com.appsmith.server.services;
|
package com.appsmith.server.services;
|
||||||
|
|
||||||
import com.appsmith.server.constants.AclConstants;
|
import com.appsmith.server.acl.AclConstants;
|
||||||
import com.appsmith.server.domains.Group;
|
import com.appsmith.server.domains.Group;
|
||||||
import com.appsmith.server.domains.Organization;
|
import com.appsmith.server.domains.Organization;
|
||||||
import com.appsmith.server.domains.User;
|
import com.appsmith.server.domains.User;
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
package com.appsmith.server.services;
|
package com.appsmith.server.services;
|
||||||
|
|
||||||
import com.appsmith.server.constants.AclPermission;
|
import com.appsmith.server.acl.AclPermission;
|
||||||
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.exceptions.AppsmithError;
|
import com.appsmith.server.exceptions.AppsmithError;
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
package com.appsmith.server.configurations;
|
package com.appsmith.server.configurations;
|
||||||
|
|
||||||
import com.appsmith.external.models.Policy;
|
import com.appsmith.external.models.Policy;
|
||||||
import com.appsmith.server.constants.AclPermission;
|
import com.appsmith.server.acl.AclPermission;
|
||||||
import com.appsmith.server.domains.Application;
|
import com.appsmith.server.domains.Application;
|
||||||
import com.appsmith.server.domains.Organization;
|
import com.appsmith.server.domains.Organization;
|
||||||
import com.appsmith.server.domains.OrganizationPlugin;
|
import com.appsmith.server.domains.OrganizationPlugin;
|
||||||
|
|
@ -23,9 +23,14 @@ import reactor.core.publisher.Flux;
|
||||||
import reactor.core.publisher.Mono;
|
import reactor.core.publisher.Mono;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
import java.util.HashSet;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
|
import static com.appsmith.server.acl.AclPermission.MANAGE_ORGANIZATIONS;
|
||||||
|
import static com.appsmith.server.acl.AclPermission.ORGANIZATION_MANAGE_APPLICATIONS;
|
||||||
|
import static com.appsmith.server.acl.AclPermission.READ_APPLICATIONS;
|
||||||
|
|
||||||
@Slf4j
|
@Slf4j
|
||||||
@Configuration
|
@Configuration
|
||||||
public class SeedMongoData {
|
public class SeedMongoData {
|
||||||
|
|
@ -38,20 +43,24 @@ public class SeedMongoData {
|
||||||
PluginRepository pluginRepository) {
|
PluginRepository pluginRepository) {
|
||||||
|
|
||||||
log.info("Seeding the data");
|
log.info("Seeding the data");
|
||||||
Policy readAppPolicy = Policy.builder().permission(AclPermission.READ_APPLICATIONS.getValue())
|
Policy readAppPolicy = Policy.builder().permission(READ_APPLICATIONS.getValue())
|
||||||
.users(Set.of("api_user"))
|
.users(Set.of("api_user"))
|
||||||
.build();
|
.build();
|
||||||
|
|
||||||
Policy manageAppPolicy = Policy.builder().permission(AclPermission.MANAGE_APPLICATIONS.getValue())
|
Policy manageAppPolicy = Policy.builder().permission(ORGANIZATION_MANAGE_APPLICATIONS.getValue())
|
||||||
|
.users(Set.of("api_user"))
|
||||||
|
.build();
|
||||||
|
|
||||||
|
Policy manageOrgPolicy = Policy.builder().permission(MANAGE_ORGANIZATIONS.getValue())
|
||||||
.users(Set.of("api_user"))
|
.users(Set.of("api_user"))
|
||||||
.build();
|
.build();
|
||||||
|
|
||||||
Object[][] userData = {
|
Object[][] userData = {
|
||||||
{"user test", "usertest@usertest.com", UserState.ACTIVATED},
|
{"user test", "usertest@usertest.com", UserState.ACTIVATED, new HashSet<>()},
|
||||||
{"api_user", "api_user", UserState.ACTIVATED},
|
{"api_user", "api_user", UserState.ACTIVATED, Set.of(manageOrgPolicy)},
|
||||||
};
|
};
|
||||||
Object[][] orgData = {
|
Object[][] orgData = {
|
||||||
{"Spring Test Organization", "appsmith-spring-test.com", "appsmith.com", Set.of(readAppPolicy, manageAppPolicy)}
|
{"Spring Test Organization", "appsmith-spring-test.com", "appsmith.com", Set.of(manageAppPolicy)}
|
||||||
};
|
};
|
||||||
|
|
||||||
Object[][] appData = {
|
Object[][] appData = {
|
||||||
|
|
@ -107,6 +116,7 @@ public class SeedMongoData {
|
||||||
user.setName((String) array[0]);
|
user.setName((String) array[0]);
|
||||||
user.setEmail((String) array[1]);
|
user.setEmail((String) array[1]);
|
||||||
user.setState((UserState) array[2]);
|
user.setState((UserState) array[2]);
|
||||||
|
user.setPolicies((Set<Policy>) array[3]);
|
||||||
user.setCurrentOrganizationId(orgId);
|
user.setCurrentOrganizationId(orgId);
|
||||||
return user;
|
return user;
|
||||||
})
|
})
|
||||||
|
|
@ -122,7 +132,7 @@ public class SeedMongoData {
|
||||||
return app;
|
return app;
|
||||||
}).flatMap(applicationRepository::save)
|
}).flatMap(applicationRepository::save)
|
||||||
// Query the seed data to get the applicationId (required for page creation)
|
// Query the seed data to get the applicationId (required for page creation)
|
||||||
).then(applicationRepository.findByName((String) appData[0][0], AclPermission.READ_APPLICATIONS))
|
).then(applicationRepository.findByName((String) appData[0][0], READ_APPLICATIONS))
|
||||||
.map(application -> application.getId())
|
.map(application -> application.getId())
|
||||||
.flatMapMany(appId -> Flux.just(pageData)
|
.flatMapMany(appId -> Flux.just(pageData)
|
||||||
// Seed the page data into the DB
|
// Seed the page data into the DB
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,6 @@
|
||||||
package com.appsmith.server.services;
|
package com.appsmith.server.services;
|
||||||
|
|
||||||
|
import com.appsmith.external.models.Policy;
|
||||||
import com.appsmith.server.constants.FieldName;
|
import com.appsmith.server.constants.FieldName;
|
||||||
import com.appsmith.server.domains.Application;
|
import com.appsmith.server.domains.Application;
|
||||||
import com.appsmith.server.exceptions.AppsmithError;
|
import com.appsmith.server.exceptions.AppsmithError;
|
||||||
|
|
@ -15,6 +16,11 @@ import org.springframework.test.context.junit4.SpringRunner;
|
||||||
import reactor.core.publisher.Mono;
|
import reactor.core.publisher.Mono;
|
||||||
import reactor.test.StepVerifier;
|
import reactor.test.StepVerifier;
|
||||||
|
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
import static com.appsmith.server.acl.AclPermission.MANAGE_APPLICATIONS;
|
||||||
|
import static com.appsmith.server.acl.AclPermission.ORGANIZATION_MANAGE_APPLICATIONS;
|
||||||
|
import static com.appsmith.server.acl.AclPermission.READ_APPLICATIONS;
|
||||||
import static org.assertj.core.api.Assertions.assertThat;
|
import static org.assertj.core.api.Assertions.assertThat;
|
||||||
|
|
||||||
@RunWith(SpringRunner.class)
|
@RunWith(SpringRunner.class)
|
||||||
|
|
@ -49,6 +55,13 @@ public class ApplicationServiceTest {
|
||||||
testApplication.setName("ApplicationServiceTest TestApp");
|
testApplication.setName("ApplicationServiceTest TestApp");
|
||||||
Mono<Application> applicationMono = applicationPageService.createApplication(testApplication);
|
Mono<Application> applicationMono = applicationPageService.createApplication(testApplication);
|
||||||
|
|
||||||
|
Policy manageAppPolicy = Policy.builder().permission(MANAGE_APPLICATIONS.getValue())
|
||||||
|
.users(Set.of("api_user"))
|
||||||
|
.build();
|
||||||
|
Policy readAppPolicy = Policy.builder().permission(READ_APPLICATIONS.getValue())
|
||||||
|
.users(Set.of("api_user"))
|
||||||
|
.build();
|
||||||
|
|
||||||
StepVerifier
|
StepVerifier
|
||||||
.create(applicationMono)
|
.create(applicationMono)
|
||||||
.assertNext(application -> {
|
.assertNext(application -> {
|
||||||
|
|
@ -56,6 +69,7 @@ public class ApplicationServiceTest {
|
||||||
assertThat(application.getId()).isNotNull();
|
assertThat(application.getId()).isNotNull();
|
||||||
assertThat(application.getName().equals("ApplicationServiceTest TestApp"));
|
assertThat(application.getName().equals("ApplicationServiceTest TestApp"));
|
||||||
assertThat(application.getPolicies()).isNotEmpty();
|
assertThat(application.getPolicies()).isNotEmpty();
|
||||||
|
assertThat(application.getPolicies()).containsAll(Set.of(manageAppPolicy, readAppPolicy));
|
||||||
})
|
})
|
||||||
.verifyComplete();
|
.verifyComplete();
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,6 @@
|
||||||
package com.appsmith.server.services;
|
package com.appsmith.server.services;
|
||||||
|
|
||||||
import com.appsmith.external.models.Policy;
|
import com.appsmith.external.models.Policy;
|
||||||
import com.appsmith.server.constants.AclPermission;
|
|
||||||
import com.appsmith.server.constants.FieldName;
|
import com.appsmith.server.constants.FieldName;
|
||||||
import com.appsmith.server.domains.Organization;
|
import com.appsmith.server.domains.Organization;
|
||||||
import com.appsmith.server.exceptions.AppsmithError;
|
import com.appsmith.server.exceptions.AppsmithError;
|
||||||
|
|
@ -20,6 +19,8 @@ import reactor.test.StepVerifier;
|
||||||
|
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
|
import static com.appsmith.server.acl.AclPermission.MANAGE_APPLICATIONS;
|
||||||
|
import static com.appsmith.server.acl.AclPermission.ORGANIZATION_MANAGE_APPLICATIONS;
|
||||||
import static org.assertj.core.api.Assertions.assertThat;
|
import static org.assertj.core.api.Assertions.assertThat;
|
||||||
|
|
||||||
@RunWith(SpringJUnit4ClassRunner.class)
|
@RunWith(SpringJUnit4ClassRunner.class)
|
||||||
|
|
@ -66,12 +67,17 @@ public class OrganizationServiceTest {
|
||||||
@Test
|
@Test
|
||||||
@WithUserDetails(value = "api_user")
|
@WithUserDetails(value = "api_user")
|
||||||
public void validCreateOrganizationTest() {
|
public void validCreateOrganizationTest() {
|
||||||
|
Policy manageOrgAppPolicy = Policy.builder().permission(ORGANIZATION_MANAGE_APPLICATIONS.getValue())
|
||||||
|
.users(Set.of("api_user"))
|
||||||
|
.build();
|
||||||
|
|
||||||
Mono<Organization> organizationResponse = organizationService.create(organization)
|
Mono<Organization> organizationResponse = organizationService.create(organization)
|
||||||
.switchIfEmpty(Mono.error(new Exception("create is returning empty!!")));
|
.switchIfEmpty(Mono.error(new Exception("create is returning empty!!")));
|
||||||
StepVerifier.create(organizationResponse)
|
StepVerifier.create(organizationResponse)
|
||||||
.assertNext(organization1 -> {
|
.assertNext(organization1 -> {
|
||||||
assertThat(organization1.getName()).isEqualTo("Test Name");
|
assertThat(organization1.getName()).isEqualTo("Test Name");
|
||||||
assertThat(organization1.getPolicies()).isNotEmpty();
|
assertThat(organization1.getPolicies()).isNotEmpty();
|
||||||
|
assertThat(organization1.getPolicies()).containsAll(Set.of(manageOrgAppPolicy));
|
||||||
})
|
})
|
||||||
.verifyComplete();
|
.verifyComplete();
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue
Block a user