Skip to content

Commit

Permalink
Merge pull request #2228 from atlanhq/gov-1233
Browse files Browse the repository at this point in the history
GOV-1233 Fix delete resources case
  • Loading branch information
nikhilbonte21 authored Aug 4, 2023
2 parents 17fed96 + 8bd2b4d commit 2b88441
Show file tree
Hide file tree
Showing 8 changed files with 108 additions and 42 deletions.
23 changes: 13 additions & 10 deletions addons/policies/bootstrap_entity_policies.json
Original file line number Diff line number Diff line change
Expand Up @@ -826,13 +826,15 @@
"policyType": "allow",
"policyPriority": 1,
"policyUsers":
[
"service-account-atlan-argo",
"service-account-atlan-backend"
],
[],
"policyGroups":
[],
"policyRoles": [],
"policyRoles":
[
"$admin",
"$member",
"$api-token-default-access"
],
"policyResourceCategory": "ENTITY",
"policyResources":
[
Expand Down Expand Up @@ -1348,14 +1350,15 @@
"policyType": "allow",
"policyPriority": 1,
"policyUsers":
[
"service-account-atlan-argo",
"service-account-atlan-backend"
],
[],
"policyGroups":
[],
"policyRoles":
[],
[
"$admin",
"$member",
"$api-token-default-access"
],
"policyResourceCategory": "ENTITY",
"policyResources":
[
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,9 @@
import java.net.UnknownHostException;
import java.util.*;

import static org.apache.atlas.repository.Constants.SKIP_DELETE_AUTH_CHECK_TYPES;
import static org.apache.atlas.repository.Constants.SKIP_UPDATE_AUTH_CHECK_TYPES;

public class AtlasAuthorizationUtils {
private static final Logger LOG = LoggerFactory.getLogger(AtlasAuthorizationUtils.class);

Expand All @@ -54,6 +57,18 @@ public static void verifyAccess(AtlasTypeAccessRequest request, Object... errorM
}
}

public static void verifyUpdateEntityAccess(AtlasEntityAccessRequest request, Object... errorMsgParams) throws AtlasBaseException {
if (!SKIP_UPDATE_AUTH_CHECK_TYPES.contains(request.getEntity().getTypeName())) {
verifyAccess(request, errorMsgParams);
}
}

public static void verifyDeleteEntityAccess(AtlasEntityAccessRequest request, Object... errorMsgParams) throws AtlasBaseException {
if (!SKIP_DELETE_AUTH_CHECK_TYPES.contains(request.getEntity().getTypeName())) {
verifyAccess(request, errorMsgParams);
}
}

public static void verifyAccess(AtlasEntityAccessRequest request, Object... errorMsgParams) throws AtlasBaseException {
if (! isAccessAllowed(request)) {
String message = (errorMsgParams != null && errorMsgParams.length > 0) ? StringUtils.join(errorMsgParams) : "";
Expand Down
12 changes: 12 additions & 0 deletions common/src/main/java/org/apache/atlas/repository/Constants.java
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,8 @@
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Set;

import static org.apache.atlas.type.AtlasStructType.AtlasAttribute.encodePropertyKey;

Expand Down Expand Up @@ -404,6 +406,16 @@ public enum SupportedFileExtensions { XLSX, XLS, CSV }
public static final String REQUEST_HEADER_USER_AGENT = "User-Agent";
public static final String REQUEST_HEADER_HOST = "Host";

public static final Set<String> SKIP_UPDATE_AUTH_CHECK_TYPES = new HashSet<String>() {{
add(README_ENTITY_TYPE);
add(LINK_ENTITY_TYPE);
}};

public static final Set<String> SKIP_DELETE_AUTH_CHECK_TYPES = new HashSet<String>() {{
add(README_ENTITY_TYPE);
add(LINK_ENTITY_TYPE);
}};

private Constants() {
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,6 @@
import static org.apache.atlas.repository.graph.GraphHelper.*;
import static org.apache.atlas.repository.graph.GraphHelper.getStatus;
import static org.apache.atlas.repository.store.graph.v2.EntityGraphMapper.validateLabels;
import static org.apache.atlas.repository.store.graph.v2.preprocessor.PreProcessor.RESOURCES_ENTITY_TYPES;
import static org.apache.atlas.repository.store.graph.v2.tasks.MeaningsTaskFactory.*;
import static org.apache.atlas.type.Constants.HAS_LINEAGE;
import static org.apache.atlas.type.Constants.HAS_LINEAGE_VALID;
Expand Down Expand Up @@ -511,7 +510,7 @@ public EntityMutationResponse updateByUniqueAttributes(AtlasEntityType entityTyp

entity.setGuid(guid);

AtlasAuthorizationUtils.verifyAccess(new AtlasEntityAccessRequest(typeRegistry, AtlasPrivilege.ENTITY_UPDATE, new AtlasEntityHeader(entity)), "update entity ByUniqueAttributes");
AtlasAuthorizationUtils.verifyUpdateEntityAccess(new AtlasEntityAccessRequest(typeRegistry, AtlasPrivilege.ENTITY_UPDATE, new AtlasEntityHeader(entity)), "update entity ByUniqueAttributes");

return createOrUpdate(new AtlasEntityStream(updatedEntityInfo), true, false, false, false);
}
Expand All @@ -528,7 +527,7 @@ public EntityMutationResponse updateEntityAttributeByGuid(String guid, String at
AtlasEntityType entityType = (AtlasEntityType) typeRegistry.getType(entity.getTypeName());
AtlasAttribute attr = entityType.getAttribute(attrName);

AtlasAuthorizationUtils.verifyAccess(new AtlasEntityAccessRequest(typeRegistry, AtlasPrivilege.ENTITY_UPDATE, entity), "update entity ByUniqueAttributes : guid=", guid );
AtlasAuthorizationUtils.verifyUpdateEntityAccess(new AtlasEntityAccessRequest(typeRegistry, AtlasPrivilege.ENTITY_UPDATE, entity), "update entity ByUniqueAttributes : guid=", guid);

if (attr == null) {
attr = entityType.getRelationshipAttribute(attrName, AtlasEntityUtil.getRelationshipType(attrValue));
Expand Down Expand Up @@ -583,7 +582,7 @@ public EntityMutationResponse deleteById(final String guid) throws AtlasBaseExce
if (vertex != null) {
AtlasEntityHeader entityHeader = entityRetriever.toAtlasEntityHeaderWithClassifications(vertex);

AtlasAuthorizationUtils.verifyAccess(new AtlasEntityAccessRequest(typeRegistry, AtlasPrivilege.ENTITY_DELETE, entityHeader), "delete entity: guid=", guid);
AtlasAuthorizationUtils.verifyDeleteEntityAccess(new AtlasEntityAccessRequest(typeRegistry, AtlasPrivilege.ENTITY_DELETE, entityHeader), "delete entity: guid=", guid);

deletionCandidates.add(vertex);
} else {
Expand Down Expand Up @@ -629,7 +628,7 @@ public EntityMutationResponse deleteByIds(final List<String> guids) throws Atlas

AtlasEntityHeader entityHeader = entityRetriever.toAtlasEntityHeaderWithClassifications(vertex);

AtlasAuthorizationUtils.verifyAccess(new AtlasEntityAccessRequest(typeRegistry, AtlasPrivilege.ENTITY_DELETE, entityHeader), "delete entity: guid=", guid);
AtlasAuthorizationUtils.verifyDeleteEntityAccess(new AtlasEntityAccessRequest(typeRegistry, AtlasPrivilege.ENTITY_DELETE, entityHeader), "delete entity: guid=", guid);

deletionCandidates.add(vertex);
}
Expand Down Expand Up @@ -672,7 +671,7 @@ public EntityMutationResponse restoreByIds(final List<String> guids) throws Atla

AtlasEntityHeader entityHeader = entityRetriever.toAtlasEntityHeaderWithClassifications(vertex);

AtlasAuthorizationUtils.verifyAccess(new AtlasEntityAccessRequest(typeRegistry, AtlasPrivilege.ENTITY_DELETE, entityHeader), "delete entity: guid=", guid);
AtlasAuthorizationUtils.verifyDeleteEntityAccess(new AtlasEntityAccessRequest(typeRegistry, AtlasPrivilege.ENTITY_DELETE, entityHeader), "delete entity: guid=", guid);

restoreCandidates.add(vertex);
}
Expand Down Expand Up @@ -738,7 +737,7 @@ public EntityMutationResponse deleteByUniqueAttributes(AtlasEntityType entityTyp
if (vertex != null) {
AtlasEntityHeader entityHeader = entityRetriever.toAtlasEntityHeaderWithClassifications(vertex);

AtlasAuthorizationUtils.verifyAccess(new AtlasEntityAccessRequest(typeRegistry, AtlasPrivilege.ENTITY_DELETE, entityHeader), "delete entity: typeName=", entityType.getTypeName(), ", uniqueAttributes=", uniqAttributes);
AtlasAuthorizationUtils.verifyDeleteEntityAccess(new AtlasEntityAccessRequest(typeRegistry, AtlasPrivilege.ENTITY_DELETE, entityHeader), "delete entity: typeName=", entityType.getTypeName(), ", uniqueAttributes=", uniqAttributes);

deletionCandidates.add(vertex);
} else {
Expand Down Expand Up @@ -790,7 +789,7 @@ public EntityMutationResponse deleteByUniqueAttributes(List<AtlasObjectId> objec
if (vertex != null) {
AtlasEntityHeader entityHeader = entityRetriever.toAtlasEntityHeaderWithClassifications(vertex);

AtlasAuthorizationUtils.verifyAccess(new AtlasEntityAccessRequest(typeRegistry, AtlasPrivilege.ENTITY_DELETE, entityHeader), "delete entity: typeName=", entityType.getTypeName(), ", uniqueAttributes=", objectId.getUniqueAttributes());
AtlasAuthorizationUtils.verifyDeleteEntityAccess(new AtlasEntityAccessRequest(typeRegistry, AtlasPrivilege.ENTITY_DELETE, entityHeader), "delete entity: typeName=", entityType.getTypeName(), ", uniqueAttributes=", objectId.getUniqueAttributes());

deletionCandidates.add(vertex);
} else {
Expand Down Expand Up @@ -1507,10 +1506,8 @@ private EntityMutationResponse createOrUpdate(EntityStream entityStream, boolean
//do nothing, only diff is relationshipAttributes.meanings, allow update

} else {
if (!RESOURCES_ENTITY_TYPES.contains(entityHeader.getTypeName())) {
AtlasEntityAccessRequest accessRequest = new AtlasEntityAccessRequest(typeRegistry, AtlasPrivilege.ENTITY_UPDATE, entityHeader);
AtlasAuthorizationUtils.verifyAccess(accessRequest, "update entity: type=", entity.getTypeName());
}
AtlasEntityAccessRequest accessRequest = new AtlasEntityAccessRequest(typeRegistry, AtlasPrivilege.ENTITY_UPDATE, entityHeader);
AtlasAuthorizationUtils.verifyUpdateEntityAccess(accessRequest, "update entity: type=", entity.getTypeName());
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,6 @@

import static org.apache.atlas.repository.Constants.ATLAS_GLOSSARY_CATEGORY_ENTITY_TYPE;
import static org.apache.atlas.repository.Constants.ATLAS_GLOSSARY_TERM_ENTITY_TYPE;
import static org.apache.atlas.repository.Constants.LINK_ENTITY_TYPE;
import static org.apache.atlas.repository.Constants.README_ENTITY_TYPE;


public interface PreProcessor {
Expand All @@ -22,11 +20,6 @@ public interface PreProcessor {
add(ATLAS_GLOSSARY_CATEGORY_ENTITY_TYPE);
}};

public static final Set<String> RESOURCES_ENTITY_TYPES = new HashSet<String>() {{
add(README_ENTITY_TYPE);
add(LINK_ENTITY_TYPE);
}};

void processAttributes(AtlasStruct entity, EntityMutationContext context, EntityMutations.EntityOperation operation) throws AtlasBaseException;

default void processDelete(AtlasVertex vertex) throws AtlasBaseException {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -53,22 +53,19 @@ public abstract class AbstractResourcePreProcessor implements PreProcessor {
this.entityRetriever = entityRetriever;
}

public void authorizeUpdate(AtlasEntity resourceEntity, AtlasVertex ResourceVertex, String edgeLabel) throws AtlasBaseException {
void authorizeResourceUpdate(AtlasEntity resourceEntity, AtlasVertex ResourceVertex, String edgeLabel) throws AtlasBaseException {
AtlasPerfMetrics.MetricRecorder metricRecorder = RequestContext.get().startMetricRecord("authorizeResourceUpdate");

try {
AtlasEntityHeader entityHeaderToAuthorize = null;

if (resourceEntity.hasRelationshipAttribute(ASSET_RELATION_ATTR) &&
resourceEntity.getRelationshipAttribute(ASSET_RELATION_ATTR) != null) {
AtlasObjectId asset = getAssetRelationAttr(resourceEntity);
if (asset != null) {
//Found linked asset in payload
AtlasObjectId asset = (AtlasObjectId) resourceEntity.getRelationshipAttribute(ASSET_RELATION_ATTR);

AtlasVertex assetVertex = entityRetriever.getEntityVertex(asset);
entityHeaderToAuthorize = entityRetriever.toAtlasEntityHeader(assetVertex);
}

if (entityHeaderToAuthorize == null) {
} else {
//Check for linked asset in store
Iterator atlasVertexIterator = ResourceVertex.query()
.direction(AtlasEdgeDirection.IN)
Expand All @@ -78,13 +75,14 @@ public void authorizeUpdate(AtlasEntity resourceEntity, AtlasVertex ResourceVert
.iterator();

if (atlasVertexIterator.hasNext()) {
//Found linked asset in store
AtlasVertex assetVertex = (AtlasVertex) atlasVertexIterator.next();
entityHeaderToAuthorize = entityRetriever.toAtlasEntityHeader(assetVertex);
}
}

if (entityHeaderToAuthorize == null) {
entityHeaderToAuthorize = new AtlasEntityHeader(resourceEntity);
} else {
//No linked asset to the Resource, check for resource update permission
entityHeaderToAuthorize = new AtlasEntityHeader(resourceEntity);
}
}

AtlasAuthorizationUtils.verifyAccess(new AtlasEntityAccessRequest(typeRegistry, AtlasPrivilege.ENTITY_UPDATE, entityHeaderToAuthorize),
Expand All @@ -93,4 +91,42 @@ public void authorizeUpdate(AtlasEntity resourceEntity, AtlasVertex ResourceVert
RequestContext.get().endMetricRecord(metricRecorder);
}
}

void authorizeResourceDelete(AtlasVertex resourceVertex) throws AtlasBaseException {
AtlasPerfMetrics.MetricRecorder recorder = RequestContext.get().startMetricRecord("authorizeResourceDelete");

try {
AtlasEntityHeader entityHeaderToAuthorize = null;

AtlasEntity resourceEntity = entityRetriever.toAtlasEntity(resourceVertex);

AtlasObjectId asset = getAssetRelationAttr(resourceEntity);
if (asset != null) {
entityHeaderToAuthorize = entityRetriever.toAtlasEntityHeader(asset.getGuid());

AtlasAuthorizationUtils.verifyAccess(new AtlasEntityAccessRequest(typeRegistry, AtlasPrivilege.ENTITY_UPDATE, entityHeaderToAuthorize),
"update entity: ", entityHeaderToAuthorize.getTypeName());

} else {
entityHeaderToAuthorize = new AtlasEntityHeader(resourceEntity);

AtlasAuthorizationUtils.verifyAccess(new AtlasEntityAccessRequest(typeRegistry, AtlasPrivilege.ENTITY_DELETE, entityHeaderToAuthorize),
"delete entity: ", entityHeaderToAuthorize.getTypeName());
}

} finally {
RequestContext.get().endMetricRecord(recorder);
}
}

private AtlasObjectId getAssetRelationAttr(AtlasEntity entity) {
AtlasObjectId ret = null;

if (entity.hasRelationshipAttribute(ASSET_RELATION_ATTR) &&
entity.getRelationshipAttribute(ASSET_RELATION_ATTR) != null) {
ret = (AtlasObjectId) entity.getRelationshipAttribute(ASSET_RELATION_ATTR);
}

return ret;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ private void processLinkUpdate(AtlasEntity linkEntity, AtlasVertex vertex) throw
try {
validateLinkAttribute(linkEntity, UPDATE.name());

authorizeUpdate(linkEntity, vertex, ASSET_LINK_EDGE_LABEL);
authorizeResourceUpdate(linkEntity, vertex, ASSET_LINK_EDGE_LABEL);
} finally {
RequestContext.get().endMetricRecord(metricRecorder);
}
Expand Down Expand Up @@ -95,4 +95,9 @@ private void validateLinkAttribute(AtlasEntity linkEntity, String operation) thr
private static Predicate<String> matchesEither(final Pattern a, final Pattern b) {
return input -> a.matcher(input).matches() || b.matcher(input).matches();
}

@Override
public void processDelete(AtlasVertex vertex) throws AtlasBaseException {
authorizeResourceDelete(vertex);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -69,9 +69,14 @@ private void processUpdateReadme(AtlasStruct struct, AtlasVertex vertex) throws
AtlasEntity readmeEntity = (AtlasEntity) struct;

try {
authorizeUpdate(readmeEntity, vertex, ASSET_README_EDGE_LABEL);
authorizeResourceUpdate(readmeEntity, vertex, ASSET_README_EDGE_LABEL);
} finally {
RequestContext.get().endMetricRecord(metricRecorder);
}
}

@Override
public void processDelete(AtlasVertex vertex) throws AtlasBaseException {
authorizeResourceDelete(vertex);
}
}

0 comments on commit 2b88441

Please sign in to comment.