Skip to content

Commit

Permalink
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #2770 from atlanhq/accesscontrolv2-nb
Browse files Browse the repository at this point in the history
Extract deny policy id from response
nikhilbonte21 authored Jan 19, 2024
2 parents f275e21 + 31773f0 commit aa9ad98
Showing 3 changed files with 76 additions and 67 deletions.
Original file line number Diff line number Diff line change
@@ -44,6 +44,8 @@ public class AuthorizerUtils {
public static final String POLICY_TYPE_DENY = "deny";
public static final int MAX_CLAUSE_LIMIT = 1024;

public static final String DENY_POLICY_NAME_SUFFIX = "_deny";

private static AtlasTypeRegistry typeRegistry;
private static EntityGraphRetriever entityRetriever;
private static AuditHandler auditProvider;
Original file line number Diff line number Diff line change
@@ -3,7 +3,6 @@
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.google.common.collect.Lists;
import org.apache.atlas.RequestContext;
import org.apache.atlas.authorize.AtlasAuthorizationUtils;
import org.apache.atlas.authorizer.AccessResult;
@@ -25,7 +24,7 @@
import java.util.*;
import java.util.stream.Collectors;

import static org.apache.atlas.authorizer.AuthorizerUtils.MAX_CLAUSE_LIMIT;
import static org.apache.atlas.authorizer.AuthorizerUtils.DENY_POLICY_NAME_SUFFIX;
import static org.apache.atlas.authorizer.AuthorizerUtils.POLICY_TYPE_ALLOW;
import static org.apache.atlas.authorizer.AuthorizerUtils.POLICY_TYPE_DENY;
import static org.apache.atlas.authorizer.authorizers.AuthorizerCommon.getMap;
@@ -355,41 +354,14 @@ public static AccessResult isAccessAllowed(String guid, String action) throws At
filterClauseList.add(policiesDSL);
filterClauseList.add(getMap("term", getMap("__guid", guid)));
Map<String, Object> dsl = getMap("query", getMap("bool", getMap("filter", filterClauseList)));
ObjectMapper mapper = new ObjectMapper();
Map<String, Object> response = null;
try {
String dslString = mapper.writeValueAsString(dsl);
response = runElasticsearchQuery(dslString);
LOG.info(dslString);
} catch (JsonProcessingException e) {
e.printStackTrace();
}

if (response != null) {
Integer count = (Integer) response.get("total");
if (count != null && count > 0) {
String policyId = null;
List<Map<String, Object>> docs = (List<Map<String, Object>>) response.get("data");

for (Map<String, Object> doc : docs) {
List<String> matched_queries = (List<String>) doc.get("matched_queries");
if (CollectionUtils.isNotEmpty(matched_queries)) {
policyId = matched_queries.get(0);
}
}

result.setAllowed(true);
result.setPolicyId(policyId);
return result;
}
}
result = runESQueryAndEvaluateAccess(dsl);

RequestContext.get().endMetricRecord(recorder);
return result;
}

public static AccessResult isAccessAllowedEvaluator(String entityTypeName, String entityQualifiedName, String action) throws AtlasBaseException {
AccessResult result = new AccessResult();

List<Map<String, Object>> filterClauseList = new ArrayList<>();
Map<String, Object> policiesDSL = getElasticsearchDSL(null, null, true, Arrays.asList(action));
@@ -398,34 +370,55 @@ public static AccessResult isAccessAllowedEvaluator(String entityTypeName, Strin
if (entityQualifiedName != null)
filterClauseList.add(getMap("wildcard", getMap("qualifiedName", entityQualifiedName)));
Map<String, Object> dsl = getMap("query", getMap("bool", getMap("filter", filterClauseList)));

AccessResult result = runESQueryAndEvaluateAccess(dsl);

return result;
}

private static AccessResult runESQueryAndEvaluateAccess(Map<String, Object> dsl) throws AtlasBaseException {
AtlasPerfMetrics.MetricRecorder recorder = RequestContext.get().startMetricRecord("runESQueryAndEvaluateAccess");
AccessResult result = new AccessResult();
ObjectMapper mapper = new ObjectMapper();
String dslString = null;
Map<String, Object> response = null;
Map<String, Object> response = null;

try {
dslString = mapper.writeValueAsString(dsl);
response = runElasticsearchQuery(dslString);
LOG.info(dslString);
} catch (JsonProcessingException e) {
e.printStackTrace();
}

if (response != null) {
Integer count = (Integer) response.get("total");
if (count != null && count > 0) {
String policyId = null;
List<Map<String, Object>> docs = (List<Map<String, Object>>) response.get("data");
try {
String dslString = mapper.writeValueAsString(dsl);
response = runElasticsearchQuery(dslString);
LOG.info(dslString);
} catch (JsonProcessingException | AtlasBaseException e) {
e.printStackTrace();
}

for (Map<String, Object> doc : docs) {
List<String> matched_queries = (List<String>) doc.get("matched_queries");
if (CollectionUtils.isNotEmpty(matched_queries)) {
policyId = matched_queries.get(0);
if (response != null) {
Integer count = (Integer) response.get("total");
if (count != null && count > 0) {
String policyId = null;
List<Map<String, Object>> docs = (List<Map<String, Object>>) response.get("data");

for (Map<String, Object> doc : docs) {
List<String> matched_queries = (List<String>) doc.get("matched_queries");
if (CollectionUtils.isNotEmpty(matched_queries)) {
Optional<String> denied = matched_queries.stream().filter(x -> x.endsWith(DENY_POLICY_NAME_SUFFIX)).findFirst();

if (denied.isPresent()) {
result.setPolicyId(denied.get().split("_")[0]);
} else {
result.setAllowed(true);
result.setPolicyId(matched_queries.get(0));
}
} else {
throw new AtlasBaseException("Failed to extract matched policy guid");
}
}
}

result.setAllowed(true);
result.setPolicyId(policyId);
return result;
return result;
}
}
} finally {
RequestContext.get().endMetricRecord(recorder);
}

return result;
@@ -436,15 +429,19 @@ public static Map<String, Object> getElasticsearchDSL(String persona, String pur
AtlasPerfMetrics.MetricRecorder recorder = RequestContext.get().startMetricRecord("EntityAuthorizer.getElasticsearchDSL");
Map<String, Object> allowDsl = ListAuthorizer.getElasticsearchDSLForPolicyType(persona, purpose, actions, requestMatchedPolicyId, POLICY_TYPE_ALLOW);
Map<String, Object> denyDsl = ListAuthorizer.getElasticsearchDSLForPolicyType(persona, purpose, actions, requestMatchedPolicyId, POLICY_TYPE_DENY);
Map<String, Object> finaDsl = new HashMap<>();
//List<Map<String, Object>> finaDsl = new ArrayList<>();

List<Map<String, Object>> combinedShouldClauses = new ArrayList<>();
if (allowDsl != null) {
finaDsl.put("filter", allowDsl);
combinedShouldClauses.addAll((List) ((Map) allowDsl.get("bool")).get("should") );
//finaDsl.add(allowDsl);
}
if (denyDsl != null) {
finaDsl.put("must_not", denyDsl);
combinedShouldClauses.addAll((List) ((Map) denyDsl.get("bool")).get("should") );
//finaDsl.put("must_not", denyDsl);
}
RequestContext.get().endMetricRecord(recorder);
return getMap("bool", finaDsl);
return getMap("bool", getMap("filter", getMap("bool", getMap("should", combinedShouldClauses))));
}

private static Integer getCountFromElasticsearch(String query) throws AtlasBaseException {
@@ -463,8 +460,8 @@ private static Map<String, Object> runElasticsearchQuery(String query) throws At
AtlasPerfMetrics.MetricRecorder recorder = RequestContext.get().startMetricRecord("EntityAuthorizer.runElasticsearchQuery");
RestClient restClient = getLowLevelClient();
AtlasElasticsearchQuery elasticsearchQuery = new AtlasElasticsearchQuery("janusgraph_vertex_index", restClient);
Map<String, Object> elasticsearchResult = null;
elasticsearchResult = elasticsearchQuery.runQueryWithLowLevelClient(query);

Map<String, Object> elasticsearchResult = elasticsearchQuery.runQueryWithLowLevelClient(query);
RequestContext.get().endMetricRecord(recorder);
return elasticsearchResult;
}
Original file line number Diff line number Diff line change
@@ -12,12 +12,14 @@
import org.apache.atlas.plugin.model.RangerPolicy;
import org.apache.atlas.type.AtlasType;
import org.apache.atlas.utils.AtlasPerfMetrics;
import org.apache.commons.collections.MapUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.*;
import java.util.stream.Collectors;

import static org.apache.atlas.authorizer.AuthorizerUtils.DENY_POLICY_NAME_SUFFIX;
import static org.apache.atlas.authorizer.AuthorizerUtils.MAX_CLAUSE_LIMIT;
import static org.apache.atlas.authorizer.AuthorizerUtils.POLICY_TYPE_ALLOW;
import static org.apache.atlas.authorizer.AuthorizerUtils.POLICY_TYPE_DENY;
@@ -55,12 +57,20 @@ public static Map<String, Object> getElasticsearchDSLForPolicyType(String person

List<Map<String, Object>> shouldClauses = new ArrayList<>();
if (requestMatchedPolicyId) {
shouldClauses.addAll(getDSLForResourcePoliciesPerPolicy(resourcePolicies));
shouldClauses.addAll(getDSLForTagPoliciesPerPolicy(tagPolicies));
shouldClauses.addAll(getDSLForAbacPoliciesPerPolicy(abacPolicies));
String suffix = "";
if (POLICY_TYPE_DENY.equals(policyType)) {
suffix = DENY_POLICY_NAME_SUFFIX;
}

shouldClauses.addAll(getDSLForResourcePoliciesPerPolicy(resourcePolicies, suffix));
shouldClauses.addAll(getDSLForTagPoliciesPerPolicy(tagPolicies, suffix));
shouldClauses.addAll(getDSLForAbacPoliciesPerPolicy(abacPolicies, suffix));
} else {
shouldClauses.addAll(getDSLForResourcePolicies(resourcePolicies));
shouldClauses.add(getDSLForTagPolicies(tagPolicies));
Map<String, Object> tagDsl = getDSLForTagPolicies(tagPolicies);
if (MapUtils.isNotEmpty(tagDsl)) {
shouldClauses.add(tagDsl);
}
shouldClauses.addAll(getDSLForAbacPolicies(abacPolicies));
}

@@ -241,7 +251,7 @@ public static List<Map<String, Object>> getDSLForAbacPolicies(List<RangerPolicy>
return clauses;
}

public static List<Map<String, Object>> getDSLForResourcePoliciesPerPolicy(List<RangerPolicy> policies) {
public static List<Map<String, Object>> getDSLForResourcePoliciesPerPolicy(List<RangerPolicy> policies, String nameSuffix) {

List<Map<String, Object>> shouldClauses = new ArrayList<>();

@@ -256,14 +266,14 @@ public static List<Map<String, Object>> getDSLForResourcePoliciesPerPolicy(List<
break;
}

Map<String, Object> dslForPolicyResources = getDSLForResources(entities, new HashSet<>(entityTypesRaw), null, policy.getGuid());
Map<String, Object> dslForPolicyResources = getDSLForResources(entities, new HashSet<>(entityTypesRaw), null, policy.getGuid()+nameSuffix);
shouldClauses.add(dslForPolicyResources);
}
}
return shouldClauses;
}

public static List<Map<String, Object>> getDSLForTagPoliciesPerPolicy(List<RangerPolicy> policies) {
public static List<Map<String, Object>> getDSLForTagPoliciesPerPolicy(List<RangerPolicy> policies, String nameSuffix) {
List<Map<String, Object>> shouldClauses = new ArrayList<>();

LOG.info("Found {} tag policies", policies.size());
@@ -280,7 +290,7 @@ public static List<Map<String, Object>> getDSLForTagPoliciesPerPolicy(List<Range

Map<String, Object> shouldMap = getMap("should", tagsClauses);
shouldMap.put("minimum_should_match", 1);
shouldMap.put("_name", policy.getGuid());
shouldMap.put("_name", policy.getGuid() + nameSuffix);

Map<String, Object> boolClause = getMap("bool", shouldMap);
shouldClauses.add(boolClause);
@@ -291,7 +301,7 @@ public static List<Map<String, Object>> getDSLForTagPoliciesPerPolicy(List<Range
return shouldClauses;
}

public static List<Map<String, Object>> getDSLForAbacPoliciesPerPolicy(List<RangerPolicy> policies) {
public static List<Map<String, Object>> getDSLForAbacPoliciesPerPolicy(List<RangerPolicy> policies, String nameSuffix) {
ObjectMapper mapper = new ObjectMapper();
List<Map<String, Object>> clauses = new ArrayList<>();

@@ -311,7 +321,7 @@ public static List<Map<String, Object>> getDSLForAbacPoliciesPerPolicy(List<Rang
String policyDSLBase64 = Base64.getEncoder().encodeToString(dsl.toString().getBytes());

Map<String, Object> shouldMap = getMap("should", getMap("wrapper", getMap("query", policyDSLBase64)));
shouldMap.put("_name", policy.getGuid());
shouldMap.put("_name", policy.getGuid() + nameSuffix);

Map<String, Object> boolMap = getMap("bool", shouldMap);
clauses.add(boolMap);

0 comments on commit aa9ad98

Please sign in to comment.