From 31773f0ac911951dcb1afcb45861e92a163abbbf Mon Sep 17 00:00:00 2001 From: Nikhil P Bonte Date: Fri, 19 Jan 2024 11:20:22 +0530 Subject: [PATCH] Extract deny policy id from response --- .../atlas/authorizer/AuthorizerUtils.java | 2 + .../authorizers/EntityAuthorizer.java | 111 +++++++++--------- .../authorizers/ListAuthorizer.java | 30 +++-- 3 files changed, 76 insertions(+), 67 deletions(-) diff --git a/repository/src/main/java/org/apache/atlas/authorizer/AuthorizerUtils.java b/repository/src/main/java/org/apache/atlas/authorizer/AuthorizerUtils.java index bb9875f84a..4035b0663d 100644 --- a/repository/src/main/java/org/apache/atlas/authorizer/AuthorizerUtils.java +++ b/repository/src/main/java/org/apache/atlas/authorizer/AuthorizerUtils.java @@ -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; diff --git a/repository/src/main/java/org/apache/atlas/authorizer/authorizers/EntityAuthorizer.java b/repository/src/main/java/org/apache/atlas/authorizer/authorizers/EntityAuthorizer.java index 6c7b284a0c..50730ddb5e 100644 --- a/repository/src/main/java/org/apache/atlas/authorizer/authorizers/EntityAuthorizer.java +++ b/repository/src/main/java/org/apache/atlas/authorizer/authorizers/EntityAuthorizer.java @@ -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 dsl = getMap("query", getMap("bool", getMap("filter", filterClauseList))); - ObjectMapper mapper = new ObjectMapper(); - Map 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> docs = (List>) response.get("data"); - for (Map doc : docs) { - List matched_queries = (List) 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> filterClauseList = new ArrayList<>(); Map 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 dsl = getMap("query", getMap("bool", getMap("filter", filterClauseList))); + + AccessResult result = runESQueryAndEvaluateAccess(dsl); + + return result; + } + + private static AccessResult runESQueryAndEvaluateAccess(Map dsl) throws AtlasBaseException { + AtlasPerfMetrics.MetricRecorder recorder = RequestContext.get().startMetricRecord("runESQueryAndEvaluateAccess"); + AccessResult result = new AccessResult(); ObjectMapper mapper = new ObjectMapper(); - String dslString = null; - Map response = null; + Map 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> docs = (List>) response.get("data"); + try { + String dslString = mapper.writeValueAsString(dsl); + response = runElasticsearchQuery(dslString); + LOG.info(dslString); + } catch (JsonProcessingException | AtlasBaseException e) { + e.printStackTrace(); + } - for (Map doc : docs) { - List matched_queries = (List) 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> docs = (List>) response.get("data"); + + for (Map doc : docs) { + List matched_queries = (List) doc.get("matched_queries"); + if (CollectionUtils.isNotEmpty(matched_queries)) { + Optional 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 getElasticsearchDSL(String persona, String pur AtlasPerfMetrics.MetricRecorder recorder = RequestContext.get().startMetricRecord("EntityAuthorizer.getElasticsearchDSL"); Map allowDsl = ListAuthorizer.getElasticsearchDSLForPolicyType(persona, purpose, actions, requestMatchedPolicyId, POLICY_TYPE_ALLOW); Map denyDsl = ListAuthorizer.getElasticsearchDSLForPolicyType(persona, purpose, actions, requestMatchedPolicyId, POLICY_TYPE_DENY); - Map finaDsl = new HashMap<>(); + //List> finaDsl = new ArrayList<>(); + + List> 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 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 elasticsearchResult = null; - elasticsearchResult = elasticsearchQuery.runQueryWithLowLevelClient(query); + + Map elasticsearchResult = elasticsearchQuery.runQueryWithLowLevelClient(query); RequestContext.get().endMetricRecord(recorder); return elasticsearchResult; } diff --git a/repository/src/main/java/org/apache/atlas/authorizer/authorizers/ListAuthorizer.java b/repository/src/main/java/org/apache/atlas/authorizer/authorizers/ListAuthorizer.java index 5309ca9d56..f3483dec17 100644 --- a/repository/src/main/java/org/apache/atlas/authorizer/authorizers/ListAuthorizer.java +++ b/repository/src/main/java/org/apache/atlas/authorizer/authorizers/ListAuthorizer.java @@ -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 getElasticsearchDSLForPolicyType(String person List> 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 tagDsl = getDSLForTagPolicies(tagPolicies); + if (MapUtils.isNotEmpty(tagDsl)) { + shouldClauses.add(tagDsl); + } shouldClauses.addAll(getDSLForAbacPolicies(abacPolicies)); } @@ -241,7 +251,7 @@ public static List> getDSLForAbacPolicies(List return clauses; } - public static List> getDSLForResourcePoliciesPerPolicy(List policies) { + public static List> getDSLForResourcePoliciesPerPolicy(List policies, String nameSuffix) { List> shouldClauses = new ArrayList<>(); @@ -256,14 +266,14 @@ public static List> getDSLForResourcePoliciesPerPolicy(List< break; } - Map dslForPolicyResources = getDSLForResources(entities, new HashSet<>(entityTypesRaw), null, policy.getGuid()); + Map dslForPolicyResources = getDSLForResources(entities, new HashSet<>(entityTypesRaw), null, policy.getGuid()+nameSuffix); shouldClauses.add(dslForPolicyResources); } } return shouldClauses; } - public static List> getDSLForTagPoliciesPerPolicy(List policies) { + public static List> getDSLForTagPoliciesPerPolicy(List policies, String nameSuffix) { List> shouldClauses = new ArrayList<>(); LOG.info("Found {} tag policies", policies.size()); @@ -280,7 +290,7 @@ public static List> getDSLForTagPoliciesPerPolicy(List shouldMap = getMap("should", tagsClauses); shouldMap.put("minimum_should_match", 1); - shouldMap.put("_name", policy.getGuid()); + shouldMap.put("_name", policy.getGuid() + nameSuffix); Map boolClause = getMap("bool", shouldMap); shouldClauses.add(boolClause); @@ -291,7 +301,7 @@ public static List> getDSLForTagPoliciesPerPolicy(List> getDSLForAbacPoliciesPerPolicy(List policies) { + public static List> getDSLForAbacPoliciesPerPolicy(List policies, String nameSuffix) { ObjectMapper mapper = new ObjectMapper(); List> clauses = new ArrayList<>(); @@ -311,7 +321,7 @@ public static List> getDSLForAbacPoliciesPerPolicy(List shouldMap = getMap("should", getMap("wrapper", getMap("query", policyDSLBase64))); - shouldMap.put("_name", policy.getGuid()); + shouldMap.put("_name", policy.getGuid() + nameSuffix); Map boolMap = getMap("bool", shouldMap); clauses.add(boolMap);