mirror of
https://github.com/open-metadata/OpenMetadata.git
synced 2025-10-27 08:44:49 +00:00
parent
68c3e0b8fe
commit
e7a4a7a3e5
@ -1270,8 +1270,8 @@ public abstract class EntityRepository<T extends EntityInterface> {
|
||||
return;
|
||||
}
|
||||
|
||||
if (updatedByBot()) {
|
||||
// Revert changes to extension field, if being updated by a bot
|
||||
if (updatedByBot() && operation == Operation.PUT) {
|
||||
// Revert extension field, if being updated by a bot with a PUT request to avoid overwriting custom extension
|
||||
updated.setExtension(original.getExtension());
|
||||
return;
|
||||
}
|
||||
|
||||
@ -339,7 +339,7 @@ public class TeamRepository extends EntityRepository<Team> {
|
||||
private List<EntityReference> getChildren(UUID teamId) throws IOException {
|
||||
if (teamId.equals(organization.getId())) { // For organization all the parentless teams are children
|
||||
List<String> children = daoCollection.teamDAO().listTeamsUnderOrganization(teamId.toString());
|
||||
return EntityUtil.populateEntityReferencesById(children, Entity.TEAM);
|
||||
return EntityUtil.populateEntityReferencesById(EntityUtil.toIDs(children), Entity.TEAM);
|
||||
}
|
||||
List<EntityRelationshipRecord> children = findTo(teamId, TEAM, Relationship.PARENT_OF, TEAM);
|
||||
return EntityUtil.populateEntityReferences(children, TEAM);
|
||||
|
||||
@ -205,7 +205,7 @@ public class UserRepository extends EntityRepository<User> {
|
||||
private List<EntityReference> getTeamChildren(UUID teamId) throws IOException {
|
||||
if (teamId.equals(organization.getId())) { // For organization all the parentless teams are children
|
||||
List<String> children = daoCollection.teamDAO().listTeamsUnderOrganization(teamId.toString());
|
||||
return EntityUtil.populateEntityReferencesById(children, Entity.TEAM);
|
||||
return EntityUtil.populateEntityReferencesById(EntityUtil.toIDs(children), Entity.TEAM);
|
||||
}
|
||||
List<EntityRelationshipRecord> children = findTo(teamId, TEAM, Relationship.PARENT_OF, TEAM);
|
||||
return EntityUtil.populateEntityReferences(children, TEAM);
|
||||
|
||||
@ -19,6 +19,7 @@ import io.swagger.v3.oas.annotations.Parameter;
|
||||
import io.swagger.v3.oas.annotations.media.Content;
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import io.swagger.v3.oas.annotations.responses.ApiResponse;
|
||||
import java.io.IOException;
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
import javax.ws.rs.GET;
|
||||
@ -31,13 +32,19 @@ import javax.ws.rs.core.MediaType;
|
||||
import javax.ws.rs.core.SecurityContext;
|
||||
import lombok.NonNull;
|
||||
import org.openmetadata.schema.EntityInterface;
|
||||
import org.openmetadata.schema.type.EntityReference;
|
||||
import org.openmetadata.schema.type.MetadataOperation;
|
||||
import org.openmetadata.schema.type.ResourcePermission;
|
||||
import org.openmetadata.service.Entity;
|
||||
import org.openmetadata.service.jdbi3.CollectionDAO;
|
||||
import org.openmetadata.service.jdbi3.EntityRepository;
|
||||
import org.openmetadata.service.resources.Collection;
|
||||
import org.openmetadata.service.resources.EntityResource;
|
||||
import org.openmetadata.service.security.Authorizer;
|
||||
import org.openmetadata.service.security.policyevaluator.OperationContext;
|
||||
import org.openmetadata.service.security.policyevaluator.PolicyEvaluator;
|
||||
import org.openmetadata.service.security.policyevaluator.ResourceContext;
|
||||
import org.openmetadata.service.util.EntityUtil;
|
||||
import org.openmetadata.service.util.ResultList;
|
||||
|
||||
@Path("/v1/permissions")
|
||||
@ -173,6 +180,37 @@ public class PermissionsResource {
|
||||
return authorizer.getPermission(securityContext, user, resourceContext);
|
||||
}
|
||||
|
||||
@GET
|
||||
@Path("/policies")
|
||||
@Operation(
|
||||
operationId = "getPermissionsForPolicies",
|
||||
summary = "Get permissions for a set of policies",
|
||||
tags = "permission",
|
||||
responses = {
|
||||
@ApiResponse(
|
||||
responseCode = "200",
|
||||
description = "Permissions for a set of policies",
|
||||
content =
|
||||
@Content(
|
||||
mediaType = "application/json",
|
||||
schema = @Schema(implementation = ResourcePermissionList.class)))
|
||||
})
|
||||
public ResultList<ResourcePermission> getPermissionForPolicies(
|
||||
@Context SecurityContext securityContext,
|
||||
@Parameter(description = "List of policy of ids", schema = @Schema(type = "UUID")) @QueryParam("ids")
|
||||
List<UUID> ids)
|
||||
throws IOException {
|
||||
// User must have read access to policies
|
||||
OperationContext operationContext = new OperationContext(Entity.POLICY, MetadataOperation.VIEW_ALL);
|
||||
EntityRepository<EntityInterface> dao = Entity.getEntityRepository(Entity.POLICY);
|
||||
for (UUID id : ids) {
|
||||
ResourceContext resourceContext = EntityResource.getResourceContext(Entity.POLICY, dao).id(id).build();
|
||||
authorizer.authorize(securityContext, operationContext, resourceContext);
|
||||
}
|
||||
List<EntityReference> policies = EntityUtil.populateEntityReferencesById(ids, Entity.POLICY);
|
||||
return new ResourcePermissionList(PolicyEvaluator.listPermission(policies));
|
||||
}
|
||||
|
||||
static class ResourcePermissionList extends ResultList<ResourcePermission> {
|
||||
@SuppressWarnings("unused")
|
||||
public ResourcePermissionList() {}
|
||||
|
||||
@ -20,6 +20,7 @@ import static org.openmetadata.schema.teams.authn.SSOAuthMechanism.SsoServiceTyp
|
||||
import static org.openmetadata.schema.teams.authn.SSOAuthMechanism.SsoServiceType.CUSTOM_OIDC;
|
||||
import static org.openmetadata.schema.teams.authn.SSOAuthMechanism.SsoServiceType.GOOGLE;
|
||||
import static org.openmetadata.schema.teams.authn.SSOAuthMechanism.SsoServiceType.OKTA;
|
||||
import static org.openmetadata.schema.type.Permission.Access.ALLOW;
|
||||
import static org.openmetadata.service.Entity.ADMIN_USER_NAME;
|
||||
import static org.openmetadata.service.exception.CatalogExceptionMessage.notAdmin;
|
||||
import static org.openmetadata.service.resources.teams.UserResource.USER_PROTECTED_FIELDS;
|
||||
@ -45,7 +46,6 @@ import org.openmetadata.schema.teams.authn.BasicAuthMechanism;
|
||||
import org.openmetadata.schema.teams.authn.JWTAuthMechanism;
|
||||
import org.openmetadata.schema.teams.authn.JWTTokenExpiry;
|
||||
import org.openmetadata.schema.teams.authn.SSOAuthMechanism;
|
||||
import org.openmetadata.schema.type.Permission.Access;
|
||||
import org.openmetadata.schema.type.ResourcePermission;
|
||||
import org.openmetadata.service.Entity;
|
||||
import org.openmetadata.service.OpenMetadataApplicationConfig;
|
||||
@ -184,24 +184,18 @@ public class DefaultAuthorizer implements Authorizer {
|
||||
public List<ResourcePermission> listPermissions(SecurityContext securityContext, String user) {
|
||||
SubjectContext subjectContext = getSubjectContext(securityContext);
|
||||
subjectContext = changeSubjectContext(user, subjectContext);
|
||||
|
||||
if (subjectContext.isAdmin() || subjectContext.isBot()) {
|
||||
// Admins and bots have permissions to do all operations.
|
||||
return PolicyEvaluator.getResourcePermissions(Access.ALLOW);
|
||||
}
|
||||
return PolicyEvaluator.listPermission(subjectContext);
|
||||
return subjectContext.isAdmin()
|
||||
? PolicyEvaluator.getResourcePermissions(ALLOW) // Admin has permissions to do all operations.
|
||||
: PolicyEvaluator.listPermission(subjectContext);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ResourcePermission getPermission(SecurityContext securityContext, String user, String resourceType) {
|
||||
SubjectContext subjectContext = getSubjectContext(securityContext);
|
||||
subjectContext = changeSubjectContext(user, subjectContext);
|
||||
|
||||
if (subjectContext.isAdmin() || subjectContext.isBot()) {
|
||||
// Admins and bots have permissions to do all operations.
|
||||
return PolicyEvaluator.getResourcePermission(resourceType, Access.ALLOW);
|
||||
}
|
||||
return PolicyEvaluator.getPermission(subjectContext, resourceType);
|
||||
return subjectContext.isAdmin()
|
||||
? PolicyEvaluator.getResourcePermission(resourceType, ALLOW) // Admin has permissions to do all operations.
|
||||
: PolicyEvaluator.getPermission(subjectContext, resourceType);
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -209,12 +203,9 @@ public class DefaultAuthorizer implements Authorizer {
|
||||
SecurityContext securityContext, String user, ResourceContextInterface resourceContext) {
|
||||
SubjectContext subjectContext = getSubjectContext(securityContext);
|
||||
subjectContext = changeSubjectContext(user, subjectContext);
|
||||
|
||||
if (subjectContext.isAdmin() || subjectContext.isBot()) {
|
||||
// Admins and bots have permissions to do all operations.
|
||||
return PolicyEvaluator.getResourcePermission(resourceContext.getResource(), Access.ALLOW);
|
||||
}
|
||||
return PolicyEvaluator.getPermission(subjectContext, resourceContext);
|
||||
return subjectContext.isAdmin()
|
||||
? PolicyEvaluator.getResourcePermission(resourceContext.getResource(), ALLOW) // Admin all permissions
|
||||
: PolicyEvaluator.getPermission(subjectContext, resourceContext);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@ -24,6 +24,7 @@ import lombok.NonNull;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.openmetadata.schema.entity.policies.Policy;
|
||||
import org.openmetadata.schema.entity.policies.accessControl.Rule;
|
||||
import org.openmetadata.schema.type.EntityReference;
|
||||
import org.openmetadata.schema.type.MetadataOperation;
|
||||
import org.openmetadata.schema.type.Permission;
|
||||
import org.openmetadata.schema.type.Permission.Access;
|
||||
@ -33,6 +34,7 @@ import org.openmetadata.service.ResourceRegistry;
|
||||
import org.openmetadata.service.exception.CatalogExceptionMessage;
|
||||
import org.openmetadata.service.security.AuthorizationException;
|
||||
import org.openmetadata.service.security.policyevaluator.SubjectContext.PolicyContext;
|
||||
import org.openmetadata.service.security.policyevaluator.SubjectContext.PolicyIterator;
|
||||
|
||||
/**
|
||||
* PolicyEvaluator for {@link MetadataOperation metadata operations} based on OpenMetadata's internal {@link Policy}
|
||||
@ -155,6 +157,20 @@ public class PolicyEvaluator {
|
||||
return new ArrayList<>(resourcePermissionMap.values());
|
||||
}
|
||||
|
||||
/** Returns a list of operations that a user can perform on all the resources. */
|
||||
public static List<ResourcePermission> listPermission(@NonNull List<EntityReference> policies) {
|
||||
Map<String, ResourcePermission> resourcePermissionMap = initResourcePermissions();
|
||||
PolicyIterator policyIterator = new PolicyIterator("", "", null, policies);
|
||||
while (policyIterator.hasNext()) {
|
||||
PolicyContext policyContext = policyIterator.next();
|
||||
for (CompiledRule rule : policyContext.getRules()) {
|
||||
LOG.debug("Evaluating {}:{}:{}\n", policyContext.getRoleName(), policyContext.getPolicyName(), rule.getName());
|
||||
rule.setPermission(resourcePermissionMap, policyContext);
|
||||
}
|
||||
}
|
||||
return new ArrayList<>(resourcePermissionMap.values());
|
||||
}
|
||||
|
||||
/** Returns a list of operations that a user can perform on the given resource/entity type */
|
||||
public static ResourcePermission getPermission(@NonNull SubjectContext subjectContext, String resourceType) {
|
||||
// Initialize all permissions to NOT_ALLOW
|
||||
|
||||
@ -141,11 +141,11 @@ public class SubjectContext {
|
||||
private int policyIndex = 0;
|
||||
private final List<EntityReference> policies;
|
||||
|
||||
PolicyIterator(String entityType, String entityName, String roleName, List<EntityReference> policy) {
|
||||
PolicyIterator(String entityType, String entityName, String roleName, List<EntityReference> policies) {
|
||||
this.entityType = entityType;
|
||||
this.entityName = entityName;
|
||||
this.roleName = roleName;
|
||||
this.policies = listOrEmpty(policy);
|
||||
this.policies = listOrEmpty(policies);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@ -28,7 +28,6 @@ import java.util.Optional;
|
||||
import java.util.UUID;
|
||||
import java.util.function.BiPredicate;
|
||||
import java.util.regex.Pattern;
|
||||
import java.util.stream.Collectors;
|
||||
import javax.ws.rs.WebApplicationException;
|
||||
import lombok.Getter;
|
||||
import lombok.NonNull;
|
||||
@ -222,14 +221,10 @@ public final class EntityUtil {
|
||||
return refs;
|
||||
}
|
||||
|
||||
public static List<EntityReference> populateEntityReferencesById(List<String> ids, @NonNull String entityType)
|
||||
public static List<EntityReference> populateEntityReferencesById(List<UUID> list, String entityType)
|
||||
throws IOException {
|
||||
List<EntityReference> refs = new ArrayList<>(ids.size());
|
||||
for (String id : ids) {
|
||||
refs.add(Entity.getEntityReferenceById(entityType, UUID.fromString(id), ALL));
|
||||
}
|
||||
refs.sort(compareEntityReference);
|
||||
return refs;
|
||||
List<EntityReference> refs = toEntityReferences(list, entityType);
|
||||
return populateEntityReferences(refs);
|
||||
}
|
||||
|
||||
public static EntityReference validateEntityLink(EntityLink entityLink) {
|
||||
@ -285,6 +280,12 @@ public final class EntityUtil {
|
||||
return entityReferences;
|
||||
}
|
||||
|
||||
public static List<UUID> toIDs(List<String> list) {
|
||||
List<UUID> ids = new ArrayList<>(list.size());
|
||||
list.forEach(entry -> ids.add(UUID.fromString(entry)));
|
||||
return ids;
|
||||
}
|
||||
|
||||
public static List<EntityReference> toEntityReferences(List<UUID> ids, String entityType) {
|
||||
if (ids == null) {
|
||||
return null;
|
||||
@ -339,13 +340,6 @@ public final class EntityUtil {
|
||||
}
|
||||
}
|
||||
|
||||
public static List<UUID> getIDList(List<EntityReference> refList) {
|
||||
if (refList == null) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
return refList.stream().sorted(compareEntityReference).map(EntityReference::getId).collect(Collectors.toList());
|
||||
}
|
||||
|
||||
/** Entity version extension name formed by entityType.version.versionNumber. Example - `table.version.0.1` */
|
||||
public static String getVersionExtension(String entityType, Double version) {
|
||||
return String.format("%s.%s", getVersionExtensionPrefix(entityType), version.toString());
|
||||
|
||||
@ -37,6 +37,7 @@ import static org.openmetadata.service.util.TestUtils.assertResponse;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.URISyntaxException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
@ -78,12 +79,33 @@ class PermissionsResourceTest extends OpenMetadataApplicationTest {
|
||||
private static List<Rule> ORG_RULES;
|
||||
|
||||
private static final String DATA_STEWARD_ROLE_NAME = "DataSteward";
|
||||
private static Policy DATA_STEWARD_POLICY;
|
||||
private static final String DATA_STEWARD_POLICY_NAME = "DataStewardPolicy";
|
||||
private static List<Rule> DATA_STEWARD_RULES;
|
||||
|
||||
private static final String DATA_CONSUMER_ROLE_NAME = "DataConsumer";
|
||||
private static Policy DATA_CONSUMER_POLICY;
|
||||
private static final String DATA_CONSUMER_POLICY_NAME = "DataConsumerPolicy";
|
||||
private static List<Rule> DATA_CONSUMER_RULES;
|
||||
private static List<MetadataOperation> DATA_CONSUMER_ALLOWED =
|
||||
List.of(
|
||||
VIEW_ALL,
|
||||
VIEW_BASIC,
|
||||
VIEW_USAGE,
|
||||
VIEW_DATA_PROFILE,
|
||||
VIEW_SAMPLE_DATA,
|
||||
VIEW_BASIC,
|
||||
VIEW_TESTS,
|
||||
VIEW_QUERIES,
|
||||
EDIT_DESCRIPTION,
|
||||
EDIT_TAGS);
|
||||
|
||||
private static List<MetadataOperation> DATA_STEWARD_ALLOWED = new ArrayList<>(DATA_CONSUMER_ALLOWED);
|
||||
|
||||
static {
|
||||
// Additional permissions over DATA_CONSUMER
|
||||
DATA_STEWARD_ALLOWED.addAll(List.of(EDIT_OWNER, EDIT_DISPLAY_NAME, EDIT_LINEAGE));
|
||||
}
|
||||
|
||||
private static final String DATA_STEWARD_USER_NAME = "user-data-steward";
|
||||
private static User DATA_STEWARD_USER;
|
||||
@ -95,13 +117,9 @@ class PermissionsResourceTest extends OpenMetadataApplicationTest {
|
||||
new TableResourceTest().setup(test);
|
||||
PolicyResourceTest policyResourceTest = new PolicyResourceTest();
|
||||
|
||||
Policy ORG_POLICY =
|
||||
Policy orgPolicy =
|
||||
policyResourceTest.getEntityByName(ORG_POLICY_NAME, null, PolicyResource.FIELDS, ADMIN_AUTH_HEADERS);
|
||||
ORG_RULES = ORG_POLICY.getRules();
|
||||
|
||||
Policy DATA_STEWARD_POLICY =
|
||||
policyResourceTest.getEntityByName(DATA_STEWARD_POLICY_NAME, null, PolicyResource.FIELDS, ADMIN_AUTH_HEADERS);
|
||||
DATA_STEWARD_RULES = DATA_STEWARD_POLICY.getRules();
|
||||
ORG_RULES = orgPolicy.getRules();
|
||||
|
||||
DATA_STEWARD_POLICY =
|
||||
policyResourceTest.getEntityByName(DATA_STEWARD_POLICY_NAME, null, PolicyResource.FIELDS, ADMIN_AUTH_HEADERS);
|
||||
@ -109,7 +127,7 @@ class PermissionsResourceTest extends OpenMetadataApplicationTest {
|
||||
|
||||
DATA_STEWARD_USER = EntityResourceTest.USER_WITH_DATA_STEWARD_ROLE;
|
||||
|
||||
Policy DATA_CONSUMER_POLICY =
|
||||
DATA_CONSUMER_POLICY =
|
||||
policyResourceTest.getEntityByName(DATA_CONSUMER_POLICY_NAME, null, PolicyResource.FIELDS, ADMIN_AUTH_HEADERS);
|
||||
DATA_CONSUMER_RULES = DATA_CONSUMER_POLICY.getRules();
|
||||
|
||||
@ -129,12 +147,14 @@ class PermissionsResourceTest extends OpenMetadataApplicationTest {
|
||||
|
||||
@Test
|
||||
void get_admin_permissions() throws HttpResponseException {
|
||||
// Ensure an admin has all the permissions
|
||||
List<ResourcePermission> actualPermissions = getPermissions(ADMIN_AUTH_HEADERS);
|
||||
assertEquals(PolicyEvaluator.getResourcePermissions(ALLOW), actualPermissions);
|
||||
}
|
||||
|
||||
@Test
|
||||
void get_dataConsumer_permissions() throws HttpResponseException {
|
||||
// Ensure data consumer has permissions based on his role and the inherited roles
|
||||
List<MetadataOperation> conditional = List.of(ALL); // All operations are conditionally allowed
|
||||
|
||||
// Validate permissions for all resources as logged-in user
|
||||
@ -142,7 +162,7 @@ class PermissionsResourceTest extends OpenMetadataApplicationTest {
|
||||
List<ResourcePermission> actualPermissions = getPermissions(authHeaders);
|
||||
assertDataConsumerPermissions(actualPermissions, conditional);
|
||||
|
||||
// Validate permissions for DATA_CONSUMER_USER as admin and validate it
|
||||
// Validate permissions for all resources for data consumer as admin
|
||||
actualPermissions = getPermissions(DATA_CONSUMER_USER_NAME, ADMIN_AUTH_HEADERS);
|
||||
assertDataConsumerPermissions(actualPermissions, conditional);
|
||||
|
||||
@ -152,7 +172,7 @@ class PermissionsResourceTest extends OpenMetadataApplicationTest {
|
||||
assertDataConsumerPermission(actualPermission, conditional);
|
||||
}
|
||||
|
||||
// Validate permission as admin user for each resource one at a time
|
||||
// Validate permission of data consumer as admin user for each resource one at a time
|
||||
for (ResourceDescriptor rd : ResourceRegistry.listResourceDescriptors()) {
|
||||
ResourcePermission actualPermission = getPermission(rd.getName(), DATA_CONSUMER_USER_NAME, authHeaders);
|
||||
assertDataConsumerPermission(actualPermission, conditional);
|
||||
@ -194,6 +214,58 @@ class PermissionsResourceTest extends OpenMetadataApplicationTest {
|
||||
assertDataConsumerPermission(actualPermission, Collections.emptyList());
|
||||
}
|
||||
|
||||
@Test
|
||||
void get_dataSteward_permissions() throws HttpResponseException {
|
||||
Map<String, String> authHeaders = SecurityUtil.authHeaders(DATA_STEWARD_USER_NAME + "@open-metadata.org");
|
||||
List<ResourcePermission> actualPermissions = getPermissions(authHeaders);
|
||||
|
||||
for (ResourcePermission actualPermission : actualPermissions) { // For all resources
|
||||
assertDataStewardPermission(actualPermission);
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
void get_policyPermissions() throws HttpResponseException {
|
||||
// Get permissions for DATA_CONSUMER policy and assert it is correct
|
||||
List<UUID> policies = new ArrayList<>(List.of(DATA_CONSUMER_POLICY.getId()));
|
||||
List<ResourcePermission> actual = getPermissionsForPolicies(policies, ADMIN_AUTH_HEADERS);
|
||||
for (ResourcePermission actualPermission : actual) { // For every resource
|
||||
for (Permission permission : actualPermission.getPermissions()) {
|
||||
if (DATA_CONSUMER_ALLOWED.contains(permission.getOperation())) {
|
||||
assertPermissionAllowed(permission, null, DATA_CONSUMER_POLICY_NAME, DATA_CONSUMER_RULES);
|
||||
} else {
|
||||
assertPermissionNotAllowed(permission);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Get permissions for DATA_CONSUMER and DATA_STEWARD policies and assert it is correct
|
||||
policies.add(DATA_STEWARD_POLICY.getId());
|
||||
actual = getPermissionsForPolicies(policies, ADMIN_AUTH_HEADERS);
|
||||
for (ResourcePermission actualPermission : actual) { // For every resource
|
||||
for (Permission permission : actualPermission.getPermissions()) {
|
||||
if (DATA_CONSUMER_ALLOWED.contains(permission.getOperation())) {
|
||||
assertPermissionAllowed(permission, null, DATA_CONSUMER_POLICY_NAME, DATA_CONSUMER_RULES);
|
||||
} else if (DATA_STEWARD_ALLOWED.contains(permission.getOperation())) {
|
||||
assertPermissionAllowed(permission, null, DATA_STEWARD_POLICY_NAME, DATA_STEWARD_RULES);
|
||||
} else {
|
||||
assertPermissionNotAllowed(permission);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void assertDataStewardPermission(ResourcePermission actualPermission) {
|
||||
// Only allowed operations in DataConsumerRole. All other operations are conditionalAllow by default
|
||||
for (Permission permission : actualPermission.getPermissions()) {
|
||||
if (DATA_STEWARD_ALLOWED.contains(permission.getOperation())) {
|
||||
assertPermissionAllowed(permission, DATA_STEWARD_ROLE_NAME, DATA_STEWARD_POLICY_NAME, DATA_STEWARD_RULES);
|
||||
} else {
|
||||
assertPermissionConditional(permission, null, ORG_POLICY_NAME, ORG_RULES);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void assertAllOperationsAllowed(ResourcePermission actualPermission) {
|
||||
assertEquals(Entity.TABLE, actualPermission.getResource());
|
||||
for (Permission permission : actualPermission.getPermissions()) {
|
||||
@ -205,70 +277,36 @@ class PermissionsResourceTest extends OpenMetadataApplicationTest {
|
||||
private void assertDataConsumerPermissions(
|
||||
List<ResourcePermission> actualPermissions, List<MetadataOperation> conditional) {
|
||||
// Only allowed operations in DataConsumerRole. All other operations are notAllow by default
|
||||
for (ResourcePermission actualPermission : actualPermissions) { // For all resources
|
||||
assertDataConsumerPermission(actualPermission, conditional);
|
||||
for (ResourcePermission actualPermission : actualPermissions) { // For every resource
|
||||
assertDataConsumerPermission(actualPermission, conditional); // assert permission
|
||||
}
|
||||
}
|
||||
|
||||
private void assertDataConsumerPermission(ResourcePermission actualPermission, List<MetadataOperation> conditional) {
|
||||
List<MetadataOperation> allowed =
|
||||
List.of(
|
||||
VIEW_ALL,
|
||||
VIEW_BASIC,
|
||||
VIEW_USAGE,
|
||||
VIEW_DATA_PROFILE,
|
||||
VIEW_SAMPLE_DATA,
|
||||
VIEW_BASIC,
|
||||
VIEW_TESTS,
|
||||
VIEW_QUERIES,
|
||||
EDIT_DESCRIPTION,
|
||||
EDIT_TAGS);
|
||||
|
||||
// Only allowed operations in DataConsumerRole. All other operations are conditional allow or not allow
|
||||
for (Permission permission : actualPermission.getPermissions()) {
|
||||
if (allowed.contains(permission.getOperation())) {
|
||||
assertPermission(permission, ALLOW, DATA_CONSUMER_ROLE_NAME, DATA_CONSUMER_POLICY_NAME, DATA_CONSUMER_RULES);
|
||||
if (DATA_CONSUMER_ALLOWED.contains(permission.getOperation())) {
|
||||
assertPermissionAllowed(permission, DATA_CONSUMER_ROLE_NAME, DATA_CONSUMER_POLICY_NAME, DATA_CONSUMER_RULES);
|
||||
} else if (conditional.contains(permission.getOperation()) || conditional.contains(ALL)) {
|
||||
assertPermission(permission, CONDITIONAL_ALLOW, null, ORG_POLICY_NAME, ORG_RULES);
|
||||
assertPermissionConditional(permission, null, ORG_POLICY_NAME, ORG_RULES);
|
||||
} else {
|
||||
assertPermission(permission, NOT_ALLOW, null, null, null);
|
||||
assertPermissionNotAllowed(permission);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
void get_dataSteward_permissions() throws HttpResponseException {
|
||||
Map<String, String> authHeaders = SecurityUtil.authHeaders(DATA_STEWARD_USER_NAME + "@open-metadata.org");
|
||||
List<ResourcePermission> actualPermissions = getPermissions(authHeaders);
|
||||
|
||||
for (ResourcePermission actualPermission : actualPermissions) { // For all resources
|
||||
assertDataStewardPermission(actualPermission);
|
||||
}
|
||||
private void assertPermissionAllowed(
|
||||
Permission permission, String expectedRole, String expectedPolicy, List<Rule> expectedRules) {
|
||||
assertPermission(permission, ALLOW, expectedRole, expectedPolicy, expectedRules);
|
||||
}
|
||||
|
||||
private void assertDataStewardPermission(ResourcePermission actualPermission) {
|
||||
// Only allowed operations in DataConsumerRole. All other operations are conditionalAllow by default
|
||||
List<MetadataOperation> allowed =
|
||||
List.of(
|
||||
VIEW_ALL,
|
||||
VIEW_BASIC,
|
||||
VIEW_USAGE,
|
||||
VIEW_DATA_PROFILE,
|
||||
VIEW_SAMPLE_DATA,
|
||||
VIEW_TESTS,
|
||||
VIEW_QUERIES,
|
||||
EDIT_OWNER,
|
||||
EDIT_DISPLAY_NAME,
|
||||
EDIT_LINEAGE,
|
||||
EDIT_DESCRIPTION,
|
||||
EDIT_TAGS);
|
||||
for (Permission permission : actualPermission.getPermissions()) {
|
||||
if (allowed.contains(permission.getOperation())) {
|
||||
assertPermission(permission, ALLOW, DATA_STEWARD_ROLE_NAME, DATA_STEWARD_POLICY_NAME, DATA_STEWARD_RULES);
|
||||
} else {
|
||||
assertPermission(permission, CONDITIONAL_ALLOW, null, ORG_POLICY_NAME, ORG_RULES);
|
||||
}
|
||||
}
|
||||
private void assertPermissionConditional(
|
||||
Permission permission, String expectedRole, String expectedPolicy, List<Rule> expectedRules) {
|
||||
assertPermission(permission, CONDITIONAL_ALLOW, expectedRole, expectedPolicy, expectedRules);
|
||||
}
|
||||
|
||||
private void assertPermissionNotAllowed(Permission permission) {
|
||||
assertPermission(permission, NOT_ALLOW, null, null, null);
|
||||
}
|
||||
|
||||
private void assertPermission(
|
||||
@ -315,4 +353,13 @@ class PermissionsResourceTest extends OpenMetadataApplicationTest {
|
||||
target = user != null ? target.queryParam("user", user) : target;
|
||||
return TestUtils.get(target, ResourcePermission.class, authHeaders);
|
||||
}
|
||||
|
||||
public List<ResourcePermission> getPermissionsForPolicies(List<UUID> policyIds, Map<String, String> authHeaders)
|
||||
throws HttpResponseException {
|
||||
WebTarget target = getResource("permissions/policies");
|
||||
for (UUID policyId : policyIds) {
|
||||
target = target.queryParam("ids", policyId);
|
||||
}
|
||||
return TestUtils.get(target, ResourcePermissionList.class, authHeaders).getData();
|
||||
}
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user