WIP commit of trying to create an inheritance structure with permissions.

Also, moving all permissions to READ & MANAGE. Not maintaining separate permissions to create, update & delete.
This commit is contained in:
Arpit Mohan 2020-03-06 09:29:45 +05:30
parent 1475d9124a
commit 40964c3dfe
6 changed files with 59 additions and 38 deletions

View File

@ -6,23 +6,29 @@ import lombok.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"),
READ("read"),
UPDATE("update"),
DELETE("delete"),
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);
CREATE_APPLICATIONS("create:applications"),
READ_APPLICATIONS("read:applications"),
UPDATE_APPLICATIONS("update:applications"),
DELETE_APPLICATIONS("delete:applications"),
CREATE_ORGANIZATIONS("create:organizations"),
READ_ORGANIZATIONS("read:organizations"),
UPDATE_ORGANIZATIONS("update:organizations"),
DELETE_ORGANIZATIONS("delete:organizations");
private String value;
private AclPermission parent;
AclPermission(String value) {
AclPermission(String value, AclPermission parent) {
this.value = value;
}
}

View File

@ -17,6 +17,7 @@ import org.springframework.stereotype.Service;
import reactor.core.publisher.Mono;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;
@ -61,7 +62,7 @@ public class ApplicationPageServiceImpl implements ApplicationPageService {
page.setLayouts(layoutList);
}
Mono<Application> applicationMono = applicationService.findById(page.getApplicationId())
Mono<Application> applicationMono = applicationService.findById(page.getApplicationId(), AclPermission.CREATE_PAGES)
.switchIfEmpty(Mono.error(new AppsmithException(AppsmithError.NO_RESOURCE_FOUND, FieldName.APPLICATION_ID, page.getApplicationId())));
return applicationMono
@ -178,6 +179,16 @@ public class ApplicationPageServiceImpl implements ApplicationPageService {
});
}
private Set<Policy> adminApplicationPolicy(Organization org, User user) {
Set<Policy> orgPolicies = org.getPolicies();
// If a user can create an application on org, they can read, update & delete all applications
return null;
}
private Set<Policy> adminPagePolicyForApplication(User user) {
return null;
}
public Mono<Application> createApplication(Application application) {
if (application.getName() == null || application.getName().trim().isEmpty()) {
return Mono.error(new AppsmithException(AppsmithError.INVALID_PARAMETER, FieldName.NAME));
@ -185,21 +196,29 @@ public class ApplicationPageServiceImpl implements ApplicationPageService {
Mono<User> userMono = sessionUserService.getCurrentUser();
Mono<Application> applicationMono = userMono
.map(user -> user.getCurrentOrganizationId())
.flatMap(orgId -> {
Mono<Organization> orgMono = organizationService.findById(orgId, AclPermission.CREATE_APPLICATIONS)
.flatMap(user -> {
String orgId = user.getCurrentOrganizationId();
Mono<Organization> orgMono = organizationService.findById(orgId, AclPermission.MANAGE_APPLICATIONS)
.switchIfEmpty(Mono.error(new AppsmithException(AppsmithError.NO_RESOURCE_FOUND, FieldName.ORGANIZATION, orgId)));
return orgMono.map(org -> {
application.setOrganizationId(org.getId());
// At the organization level, filter out all the application specific policies and apply them
// to the new application that we are creating.
Set<Policy> policySet = org.getPolicies().stream()
// At the organization level, filter out all the application specific policies and apply them
// to the new application that we are creating.
.filter(policy ->
policy.getPermission().equals(AclPermission.READ_APPLICATIONS.getValue()) ||
policy.getPermission().equals(AclPermission.UPDATE_APPLICATIONS.getValue()) ||
policy.getPermission().equals(AclPermission.DELETE_APPLICATIONS.getValue())
policy.getPermission().equals(AclPermission.MANAGE_APPLICATIONS.getValue())
).collect(Collectors.toSet());
Set<String> users = policySet.stream()
.map(policy -> policy.getUsers())
.flatMap(Collection::stream)
.collect(Collectors.toSet());
policySet.add(Policy.builder()
.permission(AclPermission.CREATE_PAGES.getValue())
.users(Set.of(user.getUsername())).build()
);
application.setPolicies(policySet);
return application;
});

View File

@ -1,5 +1,6 @@
package com.appsmith.server.services;
import com.appsmith.server.constants.AclPermission;
import com.appsmith.server.domains.Application;
import reactor.core.publisher.Mono;
@ -7,6 +8,8 @@ public interface ApplicationService extends CrudService<Application, String> {
Mono<Application> findById(String id);
Mono<Application> findById(String id, AclPermission aclPermission);
Mono<Application> findByIdAndOrganizationId(String id, String organizationId);
Mono<Application> findByName(String name);

View File

@ -94,6 +94,11 @@ public class ApplicationServiceImpl extends BaseService<ApplicationRepository, A
return repository.findById(id);
}
@Override
public Mono<Application> findById(String id, AclPermission aclPermission) {
return repository.findById(id, aclPermission);
}
@Override
public Mono<Application> findByIdAndOrganizationId(String id, String organizationId) {
return repository.findByIdAndOrganizationId(id, organizationId, AclPermission.READ_APPLICATIONS);
@ -111,7 +116,7 @@ public class ApplicationServiceImpl extends BaseService<ApplicationRepository, A
@Override
public Mono<Application> update(String id, Application resource) {
return repository.updateById(id, resource, AclPermission.UPDATE_APPLICATIONS)
return repository.updateById(id, resource, AclPermission.MANAGE_APPLICATIONS)
.flatMap(updatedObj -> analyticsService.sendEvent(AnalyticsEvents.UPDATE + "_" + updatedObj.getClass().getSimpleName().toUpperCase(), updatedObj));
}

View File

@ -4,7 +4,6 @@ import com.appsmith.external.models.Policy;
import com.appsmith.server.constants.AclPermission;
import com.appsmith.server.constants.AnalyticsEvents;
import com.appsmith.server.constants.FieldName;
import com.appsmith.server.domains.Application;
import com.appsmith.server.domains.Organization;
import com.appsmith.server.domains.OrganizationPlugin;
import com.appsmith.server.domains.OrganizationSetting;
@ -87,18 +86,11 @@ public class OrganizationServiceImpl extends BaseService<OrganizationRepository,
.users(Set.of(user.getUsername()))
.build();
Policy createAppPolicy = Policy.builder().permission(AclPermission.CREATE_APPLICATIONS.getValue())
Policy manageAppPolicy = Policy.builder().permission(AclPermission.MANAGE_APPLICATIONS.getValue())
.users(Set.of(user.getUsername()))
.build();
Policy updateAppPolicy = Policy.builder().permission(AclPermission.UPDATE_APPLICATIONS.getValue())
.users(Set.of(user.getUsername()))
.build();
Policy deleteAppPolicy = Policy.builder().permission(AclPermission.DELETE_APPLICATIONS.getValue())
.users(Set.of(user.getUsername()))
.build();
return Set.of(createAppPolicy, readAppPolicy, updateAppPolicy,deleteAppPolicy);
return Set.of(manageAppPolicy, readAppPolicy);
}
private Set<Policy> crudOrgPolicy(User user) {

View File

@ -42,11 +42,7 @@ public class SeedMongoData {
.users(Set.of("api_user"))
.build();
Policy createAppPolicy = Policy.builder().permission(AclPermission.CREATE_APPLICATIONS.getValue())
.users(Set.of("api_user"))
.build();
Policy updateAppPolicy = Policy.builder().permission(AclPermission.UPDATE_APPLICATIONS.getValue())
Policy manageAppPolicy = Policy.builder().permission(AclPermission.MANAGE_APPLICATIONS.getValue())
.users(Set.of("api_user"))
.build();
@ -55,7 +51,7 @@ public class SeedMongoData {
{"api_user", "api_user", UserState.ACTIVATED},
};
Object[][] orgData = {
{"Spring Test Organization", "appsmith-spring-test.com", "appsmith.com", Set.of(readAppPolicy, createAppPolicy, updateAppPolicy)}
{"Spring Test Organization", "appsmith-spring-test.com", "appsmith.com", Set.of(readAppPolicy, manageAppPolicy)}
};
Object[][] appData = {