Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Evaluator API: In-memory evaluation for all relationship access #2810

Merged
merged 1 commit into from
Jan 31, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
Loading