Skip to content

Commit

Permalink
Evaluator API: In-memory evaluation for all relationship access
Browse files Browse the repository at this point in the history
  • Loading branch information
nikhilbonte21 committed Jan 31, 2024
1 parent 9c565c2 commit d877ae6
Show file tree
Hide file tree
Showing 6 changed files with 144 additions and 46 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,11 @@ public static void verifyRelationshipAccess(AtlasPrivilege action, String relati
if (!useAbacAuthorizer) {
AtlasAuthorizationUtils.verifyAccess(new AtlasRelationshipAccessRequest(typeRegistry, action, relationShipType, endOneEntity, endTwoEntity));
} else {
if (action == AtlasPrivilege.RELATIONSHIP_ADD) {
NewAuthorizerUtils.verifyRelationshipAccessInMem(action,
relationShipType,
endOneEntity,
endTwoEntity);
/*if (action == AtlasPrivilege.RELATIONSHIP_ADD) {
NewAuthorizerUtils.verifyRelationshipCreateAccess(AtlasPrivilege.RELATIONSHIP_ADD,
relationShipType,
endOneEntity,
Expand All @@ -116,7 +120,7 @@ public static void verifyRelationshipAccess(AtlasPrivilege action, String relati
relationShipType,
endOneEntity,
endTwoEntity);
}
}*/
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -186,7 +186,7 @@ public static void verifyRelationshipAccess(AtlasPrivilege action, String relati
}
}

public static void verifyRelationshipCreateAccess(AtlasPrivilege action, String relationshipType, AtlasEntityHeader endOneEntity, AtlasEntityHeader endTwoEntity) throws AtlasBaseException {
public static void verifyRelationshipAccessInMem(AtlasPrivilege action, String relationshipType, AtlasEntityHeader endOneEntity, AtlasEntityHeader endTwoEntity) throws AtlasBaseException {
AtlasPerfMetrics.MetricRecorder recorder = RequestContext.get().startMetricRecord("verifyAccess");
String userName = AuthorizerCommon.getCurrentUserName();

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import org.apache.atlas.exception.AtlasBaseException;
import org.apache.atlas.model.instance.AtlasEntity;
import org.apache.atlas.model.instance.AtlasEntityHeader;
import org.apache.atlas.repository.graphdb.AtlasGraph;
import org.apache.atlas.repository.graphdb.AtlasVertex;
import org.apache.atlas.repository.store.graph.v2.EntityGraphRetriever;
Expand All @@ -19,6 +20,7 @@
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;

@Component
public class AuthorizerCommon {
Expand Down Expand Up @@ -104,4 +106,42 @@ public static AtlasEntity toAtlasEntityHeaderWithClassifications(AtlasVertex ver
//return new AtlasEntity(entityRetriever.toAtlasEntityHeaderWithClassifications(vertex));
return new AtlasEntity(entityRetriever.toAtlasEntity(vertex));
}

public static boolean isResourceMatch(List<String> policyValues, String actualValue) {
return isResourceMatch(policyValues, actualValue, false);
}

public static boolean isResourceMatch(List<String> policyValues, String actualValue, boolean replaceUser) {
if (!policyValues.contains("*")) {
if (replaceUser) {
return policyValues.stream().anyMatch(x -> actualValue.matches(x
.replace("{USER}", AuthorizerCommon.getCurrentUserName())
.replace("*", ".*")));
} else {
return policyValues.stream().anyMatch(x -> actualValue.matches(x.replace("*", ".*")));
}
}
return true;
}

public static boolean isResourceMatch(List<String> policyValues, Set<String> entityValues) {
if (!policyValues.contains("*")) {
return entityValues.stream().anyMatch(assetType -> policyValues.stream().anyMatch(policyAssetType -> assetType.matches(policyAssetType.replace("*", ".*"))));
}
return true;
}

public static boolean isTagResourceMatch(List<String> policyValues, AtlasEntityHeader entityHeader) {
if (!policyValues.contains(("*"))) {
if (entityHeader.getClassifications() == null || entityHeader.getClassifications().isEmpty()) {
//since entity does not have tags at all, it should not pass this evaluation
return false;
}

List<String> assetTags = entityHeader.getClassifications().stream().map(x -> x.getTypeName()).collect(Collectors.toList());

return assetTags.stream().anyMatch(assetTag -> policyValues.stream().anyMatch(policyAssetType -> assetTag.matches(policyAssetType.replace("*", ".*"))));
}
return true;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
import org.apache.atlas.exception.AtlasBaseException;
import org.apache.atlas.model.instance.AtlasClassification;
import org.apache.atlas.model.instance.AtlasEntity;
import org.apache.atlas.model.instance.AtlasEntityHeader;
import org.apache.atlas.plugin.model.RangerPolicy;
import org.apache.atlas.repository.graphdb.AtlasVertex;
import org.apache.atlas.repository.graphdb.janus.AtlasElasticsearchQuery;
Expand All @@ -35,6 +36,8 @@
import static org.apache.atlas.authorizer.NewAuthorizerUtils.POLICY_TYPE_ALLOW;
import static org.apache.atlas.authorizer.NewAuthorizerUtils.POLICY_TYPE_DENY;
import static org.apache.atlas.authorizer.authorizers.AuthorizerCommon.getMap;
import static org.apache.atlas.authorizer.authorizers.AuthorizerCommon.isResourceMatch;
import static org.apache.atlas.authorizer.authorizers.AuthorizerCommon.isTagResourceMatch;
import static org.apache.atlas.repository.Constants.QUALIFIED_NAME;
import static org.apache.atlas.repository.graphdb.janus.AtlasElasticsearchDatabase.getLowLevelClient;

Expand All @@ -54,7 +57,7 @@ public static AccessResult isAccessAllowedInMemory(AtlasEntity entity, String ac
return isAccessAllowedInMemory(entity, action, POLICY_TYPE_ALLOW);
}

public static AccessResult isAccessAllowedInMemory(AtlasEntity entity, String action, String policyType) {
private static AccessResult isAccessAllowedInMemory(AtlasEntity entity, String action, String policyType) {
AtlasPerfMetrics.MetricRecorder recorder = RequestContext.get().startMetricRecord("isAccessAllowedInMemory."+policyType);
AccessResult result;

Expand All @@ -74,7 +77,7 @@ public static AccessResult isAccessAllowedInMemory(AtlasEntity entity, String ac
return result;
}

public static AccessResult evaluateRangerPoliciesInMemory(List<RangerPolicy> resourcePolicies, AtlasEntity entity) {
private static AccessResult evaluateRangerPoliciesInMemory(List<RangerPolicy> resourcePolicies, AtlasEntity entity) {
AtlasPerfMetrics.MetricRecorder recorder = RequestContext.get().startMetricRecord("validateResourcesForCreateEntityInMemory");
AccessResult result = new AccessResult();

Expand Down Expand Up @@ -116,31 +119,28 @@ public static boolean evaluateRangerPolicyInMemory(RangerPolicy rangerPolicy, At
List<String> values = resources.get(resource).getValues();

if ("entity-type".equals(resource)) {
boolean match = entityTypes.stream().anyMatch(assetType -> values.stream().anyMatch(policyAssetType -> assetType.matches(policyAssetType.replace("*", ".*"))));
if (!isResourceMatch(values, entityTypes)) {
resourcesMatched = false;
break;
}

/*boolean match = entityTypes.stream().anyMatch(assetType -> values.stream().anyMatch(policyAssetType -> assetType.matches(policyAssetType.replace("*", ".*"))));
if (!match) {
resourcesMatched = false;
break;
}
}*/
}

if ("entity".equals(resource)) {
if (!values.contains(("*"))) {
String assetQualifiedName = (String) entity.getAttribute(QUALIFIED_NAME);
Optional<String> match = values.stream().filter(x -> assetQualifiedName.matches(x
.replace("{USER}", AuthorizerCommon.getCurrentUserName())
.replace("*", ".*")))
.findFirst();
String assetQualifiedName = (String) entity.getAttribute(QUALIFIED_NAME);

if (!match.isPresent()) {
resourcesMatched = false;
break;
}
if (!isResourceMatch(values, assetQualifiedName, true)) {
resourcesMatched = false;
break;
}
}

if ("entity-business-metadata".equals(resource)) {
if (!values.contains(("*"))) {
/*if (!values.contains(("*"))) {
String assetQualifiedName = (String) entity.getAttribute(QUALIFIED_NAME);
Optional<String> match = values.stream().filter(x -> assetQualifiedName.matches(x
.replace("{USER}", AuthorizerCommon.getCurrentUserName())
Expand All @@ -151,12 +151,17 @@ public static boolean evaluateRangerPolicyInMemory(RangerPolicy rangerPolicy, At
resourcesMatched = false;
break;
}
}
}*/
}

//for tag based policy
if ("tag".equals(resource)) {
if (!values.contains(("*"))) {
if (!isTagResourceMatch(values, new AtlasEntityHeader(entity))) {
resourcesMatched = false;
break;
}

/*if (!values.contains(("*"))) {
if (entity.getClassifications() == null || entity.getClassifications().isEmpty()) {
//since entity does not have tags at all, it should not pass this evaluation
resourcesMatched = false;
Expand All @@ -173,7 +178,7 @@ public static boolean evaluateRangerPolicyInMemory(RangerPolicy rangerPolicy, At
break;
}
}
}
}*/
}
}

Expand All @@ -186,7 +191,7 @@ public static boolean evaluateRangerPolicyInMemory(RangerPolicy rangerPolicy, At
return false;
}

public static AccessResult evaluateABACPoliciesInMemory(List<RangerPolicy> abacPolicies, AtlasEntity entity) {
private static AccessResult evaluateABACPoliciesInMemory(List<RangerPolicy> abacPolicies, AtlasEntity entity) {
AccessResult result = new AccessResult();

AtlasVertex vertex = AtlasGraphUtilsV2.findByGuid(entity.getGuid());
Expand Down Expand Up @@ -432,7 +437,7 @@ private static AccessResult runESQueryAndEvaluateAccess(Map<String, Object> dsl)
return result;
}

public static Map<String, Object> getElasticsearchDSL(String persona, String purpose,
private static Map<String, Object> getElasticsearchDSL(String persona, String purpose,
boolean requestMatchedPolicyId, List<String> actions) {
AtlasPerfMetrics.MetricRecorder recorder = RequestContext.get().startMetricRecord("EntityAuthorizer.getElasticsearchDSL");
Map<String, Object> dsl = ListAuthorizer.getElasticsearchDSLForPolicyType(persona, purpose, actions, requestMatchedPolicyId, null);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,7 @@ public static Map<String, Object> getElasticsearchDSLForPolicyType(String person
return getMap("bool", boolClause);
}

public static List<Map<String, Object>> getDSLForResourcePolicies(List<RangerPolicy> policies) {
private static List<Map<String, Object>> getDSLForResourcePolicies(List<RangerPolicy> policies) {

// To reduce the number of clauses
List<String> combinedEntities = new ArrayList<>();
Expand Down
Loading

0 comments on commit d877ae6

Please sign in to comment.