From 6359958032d01eca935b6c9c667137f50407aac6 Mon Sep 17 00:00:00 2001 From: Nikhil P Bonte Date: Tue, 23 Jan 2024 11:22:51 +0530 Subject: [PATCH] New authorizer --- addons/models/0000-Area0/0010-base_model.json | 23 +- addons/policies/atlas_service.json | 14 + auth-agents-common/pom.xml | 7 + .../plugin/model/RangerBaseModelObject.java | 170 -- .../atlas/plugin/model/RangerPolicy.java | 1703 ---------------- .../plugin/service/RangerBasePlugin.java | 14 + .../atlas/plugin/util/ServicePolicies.java | 104 + .../AbstractCachePolicyTransformer.java | 1 + .../CachePolicyTransformerImpl.java | 59 +- .../PersonaCachePolicyTransformer.java | 89 +- .../PolicyTransformerTemplate.java | 14 + auth-common/pom.xml | 31 + .../apache/atlas/plugin/model/GroupInfo.java | 0 .../plugin/model/NewAccessResourceImpl.java | 253 +++ .../plugin/model/RangerBaseModelObject.java | 170 ++ .../atlas/plugin/model/RangerPolicy.java | 1734 +++++++++++++++++ .../apache/atlas/plugin/model/RangerRole.java | 0 .../atlas/plugin/model/RangerServiceDef.java | 9 +- .../model/RangerValidityRecurrence.java | 0 .../plugin/model/RangerValiditySchedule.java | 10 +- .../apache/atlas/plugin/model/UserInfo.java | 0 .../apache/atlas/plugin/util/RangerRoles.java | 0 .../atlas/plugin/util/RangerUserStore.java | 4 +- .../plugin/util/RangerUserStoreUtil.java | 0 .../janus/AtlasElasticsearchQuery.java | 2 +- .../model/discovery/IndexSearchParams.java | 5 + .../atlas/model/discovery/SearchParams.java | 9 + pom.xml | 1 + repository/pom.xml | 12 + .../apache/atlas/authorizer/AccessResult.java | 22 + .../atlas/authorizer/AccessorsExtractor.java | 271 +++ .../atlas/authorizer/AuthorizerUtils.java | 242 +++ .../authorizer/JsonToElasticsearchQuery.java | 86 + .../authorizer/NewAtlasAuditHandler.java | 250 +++ .../authorizers/AuthorizerCommon.java | 107 + .../authorizers/EntityAuthorizer.java | 469 +++++ .../authorizers/ListAuthorizer.java | 352 ++++ .../authorizers/RelationshipAuthorizer.java | 504 +++++ .../atlas/authorizer/store/PoliciesStore.java | 200 ++ .../atlas/authorizer/store/UsersStore.java | 86 + .../discovery/EntityDiscoveryService.java | 51 +- .../atlas/discovery/EntityLineageService.java | 6 +- .../store/graph/AtlasEntityStore.java | 3 +- .../store/graph/v1/DeleteHandlerV1.java | 4 +- .../store/graph/v2/AtlasEntityStoreV2.java | 193 +- .../graph/v2/AtlasRelationshipStoreV2.java | 9 +- .../store/graph/v2/EntityGraphMapper.java | 8 +- .../preprocessor/AuthPolicyPreProcessor.java | 45 +- .../AbstractGlossaryPreProcessor.java | 43 +- .../glossary/CategoryPreProcessor.java | 6 +- .../glossary/TermPreProcessor.java | 7 +- .../AbstractResourcePreProcessor.java | 6 +- .../repository/util/AccessControlUtils.java | 16 + .../resources/atlas-servicedef-atlas.json | 502 +++++ .../org/apache/atlas/web/rest/EntityREST.java | 89 +- 55 files changed, 5956 insertions(+), 2059 deletions(-) delete mode 100644 auth-agents-common/src/main/java/org/apache/atlas/plugin/model/RangerBaseModelObject.java delete mode 100644 auth-agents-common/src/main/java/org/apache/atlas/plugin/model/RangerPolicy.java create mode 100644 auth-common/pom.xml rename {auth-agents-common => auth-common}/src/main/java/org/apache/atlas/plugin/model/GroupInfo.java (100%) create mode 100644 auth-common/src/main/java/org/apache/atlas/plugin/model/NewAccessResourceImpl.java create mode 100644 auth-common/src/main/java/org/apache/atlas/plugin/model/RangerBaseModelObject.java create mode 100644 auth-common/src/main/java/org/apache/atlas/plugin/model/RangerPolicy.java rename {auth-agents-common => auth-common}/src/main/java/org/apache/atlas/plugin/model/RangerRole.java (100%) rename {auth-agents-common => auth-common}/src/main/java/org/apache/atlas/plugin/model/RangerServiceDef.java (99%) rename {auth-agents-common => auth-common}/src/main/java/org/apache/atlas/plugin/model/RangerValidityRecurrence.java (100%) rename {auth-agents-common => auth-common}/src/main/java/org/apache/atlas/plugin/model/RangerValiditySchedule.java (90%) rename {auth-agents-common => auth-common}/src/main/java/org/apache/atlas/plugin/model/UserInfo.java (100%) rename {auth-agents-common => auth-common}/src/main/java/org/apache/atlas/plugin/util/RangerRoles.java (100%) rename {auth-agents-common => auth-common}/src/main/java/org/apache/atlas/plugin/util/RangerUserStore.java (99%) rename {auth-agents-common => auth-common}/src/main/java/org/apache/atlas/plugin/util/RangerUserStoreUtil.java (100%) create mode 100644 repository/src/main/java/org/apache/atlas/authorizer/AccessResult.java create mode 100644 repository/src/main/java/org/apache/atlas/authorizer/AccessorsExtractor.java create mode 100644 repository/src/main/java/org/apache/atlas/authorizer/AuthorizerUtils.java create mode 100644 repository/src/main/java/org/apache/atlas/authorizer/JsonToElasticsearchQuery.java create mode 100644 repository/src/main/java/org/apache/atlas/authorizer/NewAtlasAuditHandler.java create mode 100644 repository/src/main/java/org/apache/atlas/authorizer/authorizers/AuthorizerCommon.java create mode 100644 repository/src/main/java/org/apache/atlas/authorizer/authorizers/EntityAuthorizer.java create mode 100644 repository/src/main/java/org/apache/atlas/authorizer/authorizers/ListAuthorizer.java create mode 100644 repository/src/main/java/org/apache/atlas/authorizer/authorizers/RelationshipAuthorizer.java create mode 100644 repository/src/main/java/org/apache/atlas/authorizer/store/PoliciesStore.java create mode 100644 repository/src/main/java/org/apache/atlas/authorizer/store/UsersStore.java create mode 100644 repository/src/main/resources/atlas-servicedef-atlas.json diff --git a/addons/models/0000-Area0/0010-base_model.json b/addons/models/0000-Area0/0010-base_model.json index fc8b63917b..5353fa1bc7 100644 --- a/addons/models/0000-Area0/0010-base_model.json +++ b/addons/models/0000-Area0/0010-base_model.json @@ -640,6 +640,17 @@ "skipScrubbing": true, "includeInNotification": true }, + { + "name": "abacService", + "typeName": "string", + "indexType": "STRING", + "cardinality": "SINGLE", + "isIndexable": false, + "isOptional": true, + "isUnique": false, + "skipScrubbing": true, + "includeInNotification": true + }, { "name": "authServiceIsEnabled", "typeName": "boolean", @@ -681,9 +692,19 @@ "Asset" ], "serviceType": "atlan", - "typeVersion": "1.1", + "typeVersion": "1.2", "attributeDefs": [ + { + "name": "policyFilterCriteria", + "typeName": "string", + "cardinality": "SINGLE", + "isIndexable": false, + "isOptional": true, + "isUnique": false, + "skipScrubbing": true, + "includeInNotification": true + }, { "name": "policyType", "typeName": "AuthPolicyType", diff --git a/addons/policies/atlas_service.json b/addons/policies/atlas_service.json index 49473d26ef..c164218b8c 100644 --- a/addons/policies/atlas_service.json +++ b/addons/policies/atlas_service.json @@ -12,6 +12,18 @@ } } }, + { + "typeName": "AuthService", + "attributes": + { + "qualifiedName": "auth_service_atlas_abac", + "name": "atlas_abac", + "authServiceType": "abac", + "authServiceConfig": { + "ranger.plugin.audit.filters": "[{'accessResult':'DENIED','isAudited':true}]" + } + } + }, { "typeName": "AuthService", "attributes": @@ -20,6 +32,7 @@ "name": "atlas", "authServiceType": "atlas", "tagService": "atlas_tag", + "abacService": "atlas_abac", "authServiceConfig": { "ranger.plugin.audit.filters": "[ {'accessResult': 'DENIED', 'isAudited': true}, {'users':['atlas'] ,'isAudited':false} ]" } @@ -33,6 +46,7 @@ "name": "heka", "authServiceType": "heka", "tagService": "atlas_tag", + "abacService": "atlas_abac", "authServiceConfig": {} } } diff --git a/auth-agents-common/pom.xml b/auth-agents-common/pom.xml index aa37156d5f..e307775796 100644 --- a/auth-agents-common/pom.xml +++ b/auth-agents-common/pom.xml @@ -55,6 +55,13 @@ ${project.version} + + + org.apache.atlas + auth-common + ${project.version} + + org.apache.atlas auth-audits diff --git a/auth-agents-common/src/main/java/org/apache/atlas/plugin/model/RangerBaseModelObject.java b/auth-agents-common/src/main/java/org/apache/atlas/plugin/model/RangerBaseModelObject.java deleted file mode 100644 index aba6661426..0000000000 --- a/auth-agents-common/src/main/java/org/apache/atlas/plugin/model/RangerBaseModelObject.java +++ /dev/null @@ -1,170 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ - -package org.apache.atlas.plugin.model; - -import org.apache.htrace.shaded.fasterxml.jackson.annotation.JsonInclude; - -import javax.xml.bind.annotation.XmlAccessType; -import javax.xml.bind.annotation.XmlAccessorType; -import javax.xml.bind.annotation.XmlRootElement; -import java.util.Date; - -@JsonInclude(JsonInclude.Include.NON_NULL) -@XmlRootElement -@XmlAccessorType(XmlAccessType.FIELD) -public class RangerBaseModelObject implements java.io.Serializable { - private static final long serialVersionUID = 1L; - - private Long id; - private String guid; - private Boolean isEnabled; - private String createdBy; - private String updatedBy; - private Date createTime; - private Date updateTime; - private Long version; - - public RangerBaseModelObject() { - setIsEnabled(null); - } - - public void updateFrom(RangerBaseModelObject other) { - setIsEnabled(other.getIsEnabled()); - } - - /** - * @return the id - */ - public Long getId() { - return id; - } - /** - * @param id the id to set - */ - public void setId(Long id) { - this.id = id; - } - /** - * @return the guid - */ - public String getGuid() { - return guid; - } - /** - * @param guid the guid to set - */ - public void setGuid(String guid) { - this.guid = guid; - } - /** - * @return the isEnabled - */ - public Boolean getIsEnabled() { - return isEnabled; - } - /** - * @param isEnabled the isEnabled to set - */ - public void setIsEnabled(Boolean isEnabled) { - this.isEnabled = isEnabled == null ? Boolean.TRUE : isEnabled; - } - /** - * @return the createdBy - */ - public String getCreatedBy() { - return createdBy; - } - /** - * @param createdBy the createdBy to set - */ - public void setCreatedBy(String createdBy) { - this.createdBy = createdBy; - } - /** - * @return the updatedBy - */ - public String getUpdatedBy() { - return updatedBy; - } - /** - * @param updatedBy the updatedBy to set - */ - public void setUpdatedBy(String updatedBy) { - this.updatedBy = updatedBy; - } - /** - * @return the createTime - */ - public Date getCreateTime() { - return createTime; - } - /** - * @param createTime the createTime to set - */ - public void setCreateTime(Date createTime) { - this.createTime = createTime; - } - /** - * @return the updateTime - */ - public Date getUpdateTime() { - return updateTime; - } - /** - * @param updateTime the updateTime to set - */ - public void setUpdateTime(Date updateTime) { - this.updateTime = updateTime; - } - /** - * @return the version - */ - public Long getVersion() { - return version; - } - /** - * @param version the version to set - */ - public void setVersion(Long version) { - this.version = version; - } - - @Override - public String toString( ) { - StringBuilder sb = new StringBuilder(); - - toString(sb); - - return sb.toString(); - } - - public StringBuilder toString(StringBuilder sb) { - sb.append("id={").append(id).append("} "); - sb.append("guid={").append(guid).append("} "); - sb.append("isEnabled={").append(isEnabled).append("} "); - sb.append("createdBy={").append(createdBy).append("} "); - sb.append("updatedBy={").append(updatedBy).append("} "); - sb.append("createTime={").append(createTime).append("} "); - sb.append("updateTime={").append(updateTime).append("} "); - sb.append("version={").append(version).append("} "); - - return sb; - } -} diff --git a/auth-agents-common/src/main/java/org/apache/atlas/plugin/model/RangerPolicy.java b/auth-agents-common/src/main/java/org/apache/atlas/plugin/model/RangerPolicy.java deleted file mode 100644 index f81f8e2854..0000000000 --- a/auth-agents-common/src/main/java/org/apache/atlas/plugin/model/RangerPolicy.java +++ /dev/null @@ -1,1703 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ - -package org.apache.atlas.plugin.model; - -import org.apache.commons.collections.CollectionUtils; -import org.apache.htrace.shaded.fasterxml.jackson.annotation.JsonInclude; - -import javax.xml.bind.annotation.XmlAccessType; -import javax.xml.bind.annotation.XmlAccessorType; -import javax.xml.bind.annotation.XmlRootElement; -import java.util.ArrayList; -import java.util.Comparator; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - - -@JsonInclude(JsonInclude.Include.NON_NULL) -@XmlRootElement -@XmlAccessorType(XmlAccessType.FIELD) -public class RangerPolicy extends RangerBaseModelObject implements java.io.Serializable { - public static final String POLICY_TYPE_ACCESS = "ACCESS"; - public static final String POLICY_TYPE_DATAMASK = "DATA_MASK"; - public static final String POLICY_TYPE_ROWFILTER = "ROW_FILTER"; - public static final String POLICY_TYPE_AUDIT = "AUDIT"; - - public static final String[] POLICY_TYPES = new String[] { - POLICY_TYPE_ACCESS, - POLICY_TYPE_DATAMASK, - POLICY_TYPE_ROWFILTER - }; - - public static final String MASK_TYPE_NULL = "MASK_NULL"; - public static final String MASK_TYPE_NONE = "MASK_NONE"; - public static final String MASK_TYPE_CUSTOM = "CUSTOM"; - - public static final int POLICY_PRIORITY_NORMAL = 0; - public static final int POLICY_PRIORITY_OVERRIDE = 1; - - public static final String POLICY_PRIORITY_NAME_NORMAL = "NORMAL"; - public static final String POLICY_PRIORITY_NAME_OVERRIDE = "OVERRIDE"; - - public static final Comparator POLICY_ID_COMPARATOR = new PolicyIdComparator(); - - // For future use - private static final long serialVersionUID = 1L; - - private String service; - private String name; - private String policyType; - private Integer policyPriority; - private String description; - private String resourceSignature; - private Boolean isAuditEnabled; - private Map resources; - private List conditions; - private List policyItems; - private List denyPolicyItems; - private List allowExceptions; - private List denyExceptions; - private List dataMaskPolicyItems; - private List rowFilterPolicyItems; - private String serviceType; - private Map options; - private List validitySchedules; - private List policyLabels; - private String zoneName; - private Boolean isDenyAllElse; - private Map attributes; - - public RangerPolicy() { - this(null, null, null, null, null, null, null, null, null, null, null); - } - - public RangerPolicy(String service, String name, String policyType, Integer policyPriority, String description, Map resources, List policyItems, String resourceSignature, Map options, List validitySchedules, List policyLables) { - this(service, name, policyType, policyPriority, description, resources, policyItems, resourceSignature, options, validitySchedules, policyLables, null); - } - - public RangerPolicy(String service, String name, String policyType, Integer policyPriority, String description, Map resources, List policyItems, String resourceSignature, Map options, List validitySchedules, List policyLables, String zoneName) { - this(service, name, policyType, policyPriority, description, resources, policyItems, resourceSignature, options, validitySchedules, policyLables, zoneName, null); - } - - public RangerPolicy(String service, String name, String policyType, Integer policyPriority, String description, Map resources, List policyItems, String resourceSignature, Map options, List validitySchedules, List policyLables, String zoneName, List conditions) { - this(service, name, policyType, policyPriority, description, resources, policyItems, resourceSignature, options, validitySchedules, policyLables, zoneName, conditions, null); - } - - /** - * @param service - * @param name - * @param policyType - * @param description - * @param resources - * @param policyItems - * @param resourceSignature TODO - */ - public RangerPolicy(String service, String name, String policyType, Integer policyPriority, String description, Map resources, List policyItems, String resourceSignature, Map options, List validitySchedules, List policyLables, String zoneName, List conditions, Boolean isDenyAllElse) { - super(); - - setService(service); - setName(name); - setPolicyType(policyType); - setPolicyPriority(policyPriority); - setDescription(description); - setResourceSignature(resourceSignature); - setIsAuditEnabled(null); - setResources(resources); - setPolicyItems(policyItems); - setDenyPolicyItems(null); - setAllowExceptions(null); - setDenyExceptions(null); - setDataMaskPolicyItems(null); - setRowFilterPolicyItems(null); - setOptions(options); - setValiditySchedules(validitySchedules); - setPolicyLabels(policyLables); - setZoneName(zoneName); - setConditions(conditions); - setIsDenyAllElse(isDenyAllElse); - - } - - /** - * @param other - */ - public void updateFrom(RangerPolicy other) { - super.updateFrom(other); - - setService(other.getService()); - setName(other.getName()); - setPolicyType(other.getPolicyType()); - setPolicyPriority(other.getPolicyPriority()); - setDescription(other.getDescription()); - setResourceSignature(other.getResourceSignature()); - setIsAuditEnabled(other.getIsAuditEnabled()); - setResources(other.getResources()); - setConditions(other.getConditions()); - setPolicyItems(other.getPolicyItems()); - setDenyPolicyItems(other.getDenyPolicyItems()); - setAllowExceptions(other.getAllowExceptions()); - setDenyExceptions(other.getDenyExceptions()); - setDataMaskPolicyItems(other.getDataMaskPolicyItems()); - setRowFilterPolicyItems(other.getRowFilterPolicyItems()); - setServiceType(other.getServiceType()); - setOptions(other.getOptions()); - setValiditySchedules(other.getValiditySchedules()); - setPolicyLabels(other.getPolicyLabels()); - setZoneName(other.getZoneName()); - setIsDenyAllElse(other.getIsDenyAllElse()); - } - - public Map getAttributes() { - return attributes; - } - - public void setAttributes(Map attributes) { - this.attributes = attributes; - } - - /** - * @return the type - */ - public String getService() { - return service; - } - - /** - * @param service the type to set - */ - public void setService(String service) { - this.service = service; - } - - /** - * @return the name - */ - public String getName() { - return name; - } - - /** - * @param name the name to set - */ - public void setName(String name) { - this.name = name; - } - - /** - * @return the policyType - */ - public String getPolicyType() { - return policyType; - } - - /** - * @param policyType the policyType to set - */ - public void setPolicyType(String policyType) { - this.policyType = policyType; - } - - /** - * @return the policyPriority - */ - public Integer getPolicyPriority() { - return policyPriority; - } - - /** - * @param policyPriority the policyPriority to set - */ - public void setPolicyPriority(Integer policyPriority) { - this.policyPriority = policyPriority == null ? RangerPolicy.POLICY_PRIORITY_NORMAL : policyPriority; - } - - /** - * @return the description - */ - public String getDescription() { - return description; - } - - /** - * @param description the description to set - */ - public void setDescription(String description) { - this.description = description; - } - - /** - * @return the resourceSignature - */ - public String getResourceSignature() { - return resourceSignature; - } - - /** - * @param resourceSignature the resourceSignature to set - */ - public void setResourceSignature(String resourceSignature) { - this.resourceSignature = resourceSignature; - } - - /** - * @return the isAuditEnabled - */ - public Boolean getIsAuditEnabled() { - return isAuditEnabled; - } - - /** - * @param isAuditEnabled the isEnabled to set - */ - public void setIsAuditEnabled(Boolean isAuditEnabled) { - this.isAuditEnabled = isAuditEnabled == null ? Boolean.TRUE : isAuditEnabled; - } - - public String getServiceType() { - return serviceType; - } - - public void setServiceType(String serviceType) { - this.serviceType = serviceType; - } - - public List getPolicyLabels() { - return policyLabels; - } - - public void setPolicyLabels(List policyLabels) { - if (this.policyLabels == null) { - this.policyLabels = new ArrayList<>(); - } - - if (this.policyLabels == policyLabels) { - return; - } - - this.policyLabels.clear(); - - if (policyLabels != null) { - this.policyLabels.addAll(policyLabels); - } - } - - /** - * @return the resources - */ - public Map getResources() { - return resources; - } - - /** - * @param resources the resources to set - */ - public void setResources(Map resources) { - if(this.resources == null) { - this.resources = new HashMap<>(); - } - - if(this.resources == resources) { - return; - } - - this.resources.clear(); - - if(resources != null) { - for(Map.Entry e : resources.entrySet()) { - this.resources.put(e.getKey(), e.getValue()); - } - } - } - - /** - * @return the policyItems - */ - public List getPolicyItems() { - return policyItems; - } - - /** - * @param policyItems the policyItems to set - */ - public void setPolicyItems(List policyItems) { - if(this.policyItems == null) { - this.policyItems = new ArrayList<>(); - } - - if(this.policyItems == policyItems) { - return; - } - - this.policyItems.clear(); - - if(policyItems != null) { - this.policyItems.addAll(policyItems); - } - } - - /** - * @return the denyPolicyItems - */ - public List getDenyPolicyItems() { - return denyPolicyItems; - } - - /** - * @param denyPolicyItems the denyPolicyItems to set - */ - public void setDenyPolicyItems(List denyPolicyItems) { - if(this.denyPolicyItems == null) { - this.denyPolicyItems = new ArrayList<>(); - } - - if(this.denyPolicyItems == denyPolicyItems) { - return; - } - - this.denyPolicyItems.clear(); - - if(denyPolicyItems != null) { - this.denyPolicyItems.addAll(denyPolicyItems); - } - } - - /** - * @return the allowExceptions - */ - public List getAllowExceptions() { - return allowExceptions; - } - - /** - * @param allowExceptions the allowExceptions to set - */ - public void setAllowExceptions(List allowExceptions) { - if(this.allowExceptions == null) { - this.allowExceptions = new ArrayList<>(); - } - - if(this.allowExceptions == allowExceptions) { - return; - } - - this.allowExceptions.clear(); - - if(allowExceptions != null) { - this.allowExceptions.addAll(allowExceptions); - } - } - - /** - * @return the denyExceptions - */ - public List getDenyExceptions() { - return denyExceptions; - } - - /** - * @param denyExceptions the denyExceptions to set - */ - public void setDenyExceptions(List denyExceptions) { - if(this.denyExceptions == null) { - this.denyExceptions = new ArrayList<>(); - } - - if(this.denyExceptions == denyExceptions) { - return; - } - - this.denyExceptions.clear(); - - if(denyExceptions != null) { - this.denyExceptions.addAll(denyExceptions); - } - } - - public List getDataMaskPolicyItems() { - return dataMaskPolicyItems; - } - - public void setDataMaskPolicyItems(List dataMaskPolicyItems) { - if(this.dataMaskPolicyItems == null) { - this.dataMaskPolicyItems = new ArrayList<>(); - } - - if(this.dataMaskPolicyItems == dataMaskPolicyItems) { - return; - } - - this.dataMaskPolicyItems.clear(); - - if(dataMaskPolicyItems != null) { - this.dataMaskPolicyItems.addAll(dataMaskPolicyItems); - } - } - - public List getRowFilterPolicyItems() { - return rowFilterPolicyItems; - } - - public void setRowFilterPolicyItems(List rowFilterPolicyItems) { - if(this.rowFilterPolicyItems == null) { - this.rowFilterPolicyItems = new ArrayList<>(); - } - - if(this.rowFilterPolicyItems == rowFilterPolicyItems) { - return; - } - - this.rowFilterPolicyItems.clear(); - - if(rowFilterPolicyItems != null) { - this.rowFilterPolicyItems.addAll(rowFilterPolicyItems); - } - } - - public Map getOptions() { return options; } - - public void setOptions(Map options) { - if (this.options == null) { - this.options = new HashMap<>(); - } - if (this.options == options) { - return; - } - this.options.clear(); - - if(options != null) { - for(Map.Entry e : options.entrySet()) { - this.options.put(e.getKey(), e.getValue()); - } - } - } - - public List getValiditySchedules() { return validitySchedules; } - - public void setValiditySchedules(List validitySchedules) { - if (this.validitySchedules == null) { - this.validitySchedules = new ArrayList<>(); - } - if (this.validitySchedules == validitySchedules) { - return; - } - this.validitySchedules.clear(); - - if(validitySchedules != null) { - this.validitySchedules.addAll(validitySchedules); - } - } - public String getZoneName() { return zoneName; } - - public void setZoneName(String zoneName) { - this.zoneName = zoneName; - } - - /** - * @return the conditions - */ - public List getConditions() { return conditions; } - /** - * @param conditions the conditions to set - */ - public void setConditions(List conditions) { - this.conditions = conditions; - } - - public Boolean getIsDenyAllElse() { - return isDenyAllElse; - } - - public void setIsDenyAllElse(Boolean isDenyAllElse) { - this.isDenyAllElse = isDenyAllElse == null ? Boolean.FALSE : isDenyAllElse; - } - - @Override - public String toString( ) { - StringBuilder sb = new StringBuilder(); - - toString(sb); - - return sb.toString(); - } - - public StringBuilder toString(StringBuilder sb) { - sb.append("RangerPolicy={"); - - super.toString(sb); - - sb.append("service={").append(service).append("} "); - sb.append("name={").append(name).append("} "); - sb.append("policyType={").append(policyType).append("} "); - sb.append("policyPriority={").append(policyPriority).append("} "); - sb.append("description={").append(description).append("} "); - sb.append("resourceSignature={").append(resourceSignature).append("} "); - sb.append("isAuditEnabled={").append(isAuditEnabled).append("} "); - sb.append("serviceType={").append(serviceType).append("} "); - - sb.append("resources={"); - if(resources != null) { - for(Map.Entry e : resources.entrySet()) { - sb.append(e.getKey()).append("={"); - e.getValue().toString(sb); - sb.append("} "); - } - } - sb.append("} "); - sb.append("policyLabels={"); - if(policyLabels != null) { - for(String policyLabel : policyLabels) { - if(policyLabel != null) { - sb.append(policyLabel).append(" "); - } - } - } - sb.append("} "); - - sb.append("policyConditions={"); - if(conditions != null) { - for(RangerPolicyItemCondition condition : conditions) { - if(condition != null) { - condition.toString(sb); - } - } - } - sb.append("} "); - - sb.append("policyItems={"); - if(policyItems != null) { - for(RangerPolicyItem policyItem : policyItems) { - if(policyItem != null) { - policyItem.toString(sb); - } - } - } - sb.append("} "); - - sb.append("denyPolicyItems={"); - if(denyPolicyItems != null) { - for(RangerPolicyItem policyItem : denyPolicyItems) { - if(policyItem != null) { - policyItem.toString(sb); - } - } - } - sb.append("} "); - - sb.append("allowExceptions={"); - if(allowExceptions != null) { - for(RangerPolicyItem policyItem : allowExceptions) { - if(policyItem != null) { - policyItem.toString(sb); - } - } - } - sb.append("} "); - - sb.append("denyExceptions={"); - if(denyExceptions != null) { - for(RangerPolicyItem policyItem : denyExceptions) { - if(policyItem != null) { - policyItem.toString(sb); - } - } - } - sb.append("} "); - - sb.append("dataMaskPolicyItems={"); - if(dataMaskPolicyItems != null) { - for(RangerDataMaskPolicyItem dataMaskPolicyItem : dataMaskPolicyItems) { - if(dataMaskPolicyItem != null) { - dataMaskPolicyItem.toString(sb); - } - } - } - sb.append("} "); - - sb.append("rowFilterPolicyItems={"); - if(rowFilterPolicyItems != null) { - for(RangerRowFilterPolicyItem rowFilterPolicyItem : rowFilterPolicyItems) { - if(rowFilterPolicyItem != null) { - rowFilterPolicyItem.toString(sb); - } - } - } - sb.append("} "); - - sb.append("options={"); - if(options != null) { - for(Map.Entry e : options.entrySet()) { - sb.append(e.getKey()).append("={"); - sb.append(e.getValue().toString()); - sb.append("} "); - } - } - sb.append("} "); - - //sb.append("validitySchedules={").append(validitySchedules).append("} "); - sb.append("validitySchedules={"); - if (CollectionUtils.isNotEmpty(validitySchedules)) { - for (RangerValiditySchedule schedule : validitySchedules) { - if (schedule != null) { - sb.append("schedule={").append(schedule).append("}"); - } - } - } - sb.append(", zoneName=").append(zoneName); - - sb.append(", isDenyAllElse={").append(isDenyAllElse).append("} "); - - sb.append("}"); - - sb.append("}"); - - return sb; - } - - static class PolicyIdComparator implements Comparator, java.io.Serializable { - @Override - public int compare(RangerPolicy me, RangerPolicy other) { - return Long.compare(me.getId(), other.getId()); - } - } - - @JsonInclude(JsonInclude.Include.NON_NULL) - @XmlRootElement - @XmlAccessorType(XmlAccessType.FIELD) - public static class RangerPolicyResource implements java.io.Serializable { - private static final long serialVersionUID = 1L; - - private List values; - private Boolean isExcludes; - private Boolean isRecursive; - - public RangerPolicyResource() { - this((List)null, null, null); - } - - public RangerPolicyResource(String value) { - setValue(value); - setIsExcludes(null); - setIsRecursive(null); - } - - public RangerPolicyResource(String value, Boolean isExcludes, Boolean isRecursive) { - setValue(value); - setIsExcludes(isExcludes); - setIsRecursive(isRecursive); - } - - public RangerPolicyResource(List values, Boolean isExcludes, Boolean isRecursive) { - setValues(values); - setIsExcludes(isExcludes); - setIsRecursive(isRecursive); - } - - /** - * @return the values - */ - public List getValues() { - return values; - } - - /** - * @param values the values to set - */ - public void setValues(List values) { - if(this.values == null) { - this.values = new ArrayList<>(); - } - - if(this.values == values) { - return; - } - - this.values.clear(); - - if(values != null) { - this.values.addAll(values); - } - } - - /** - * @param value the value to set - */ - public void setValue(String value) { - if(this.values == null) { - this.values = new ArrayList<>(); - } - - this.values.clear(); - - this.values.add(value); - } - - /** - * @return the isExcludes - */ - public Boolean getIsExcludes() { - return isExcludes; - } - - /** - * @param isExcludes the isExcludes to set - */ - public void setIsExcludes(Boolean isExcludes) { - this.isExcludes = isExcludes == null ? Boolean.FALSE : isExcludes; - } - - /** - * @return the isRecursive - */ - public Boolean getIsRecursive() { - return isRecursive; - } - - /** - * @param isRecursive the isRecursive to set - */ - public void setIsRecursive(Boolean isRecursive) { - this.isRecursive = isRecursive == null ? Boolean.FALSE : isRecursive; - } - - @Override - public String toString( ) { - StringBuilder sb = new StringBuilder(); - - toString(sb); - - return sb.toString(); - } - - public StringBuilder toString(StringBuilder sb) { - sb.append("RangerPolicyResource={"); - sb.append("values={"); - if(values != null) { - for(String value : values) { - sb.append(value).append(" "); - } - } - sb.append("} "); - sb.append("isExcludes={").append(isExcludes).append("} "); - sb.append("isRecursive={").append(isRecursive).append("} "); - sb.append("}"); - - return sb; - } - - @Override - public int hashCode() { - final int prime = 31; - int result = 1; - result = prime * result - + ((isExcludes == null) ? 0 : isExcludes.hashCode()); - result = prime * result - + ((isRecursive == null) ? 0 : isRecursive.hashCode()); - result = prime * result - + ((values == null) ? 0 : values.hashCode()); - return result; - } - - @Override - public boolean equals(Object obj) { - if (this == obj) - return true; - if (obj == null) - return false; - if (getClass() != obj.getClass()) - return false; - RangerPolicyResource other = (RangerPolicyResource) obj; - if (isExcludes == null) { - if (other.isExcludes != null) - return false; - } else if (!isExcludes.equals(other.isExcludes)) - return false; - if (isRecursive == null) { - if (other.isRecursive != null) - return false; - } else if (!isRecursive.equals(other.isRecursive)) - return false; - if (values == null) { - if (other.values != null) - return false; - } else if (!values.equals(other.values)) - return false; - return true; - } - - } - - @JsonInclude(JsonInclude.Include.NON_NULL) - @XmlRootElement - @XmlAccessorType(XmlAccessType.FIELD) - public static class RangerPolicyItem implements java.io.Serializable { - private static final long serialVersionUID = 1L; - - private List accesses; - private List users; - private List groups; - private List roles; - private List conditions; - private Boolean delegateAdmin; - - public RangerPolicyItem() { - this(null, null, null, null, null, null); - } - - public RangerPolicyItem(List accessTypes, List users, List groups, List roles, List conditions, Boolean delegateAdmin) { - setAccesses(accessTypes); - setUsers(users); - setGroups(groups); - setRoles(roles); - setConditions(conditions); - setDelegateAdmin(delegateAdmin); - } - - /** - * @return the accesses - */ - public List getAccesses() { - return accesses; - } - /** - * @param accesses the accesses to set - */ - public void setAccesses(List accesses) { - if(this.accesses == null) { - this.accesses = new ArrayList<>(); - } - - if(this.accesses == accesses) { - return; - } - - this.accesses.clear(); - - if(accesses != null) { - this.accesses.addAll(accesses); - } - } - /** - * @return the users - */ - public List getUsers() { - return users; - } - /** - * @param users the users to set - */ - public void setUsers(List users) { - if(this.users == null) { - this.users = new ArrayList<>(); - } - - if(this.users == users) { - return; - } - - this.users.clear(); - - if(users != null) { - this.users.addAll(users); - } - } - /** - * @return the groups - */ - public List getGroups() { - return groups; - } - /** - * @param groups the groups to set - */ - public void setGroups(List groups) { - if(this.groups == null) { - this.groups = new ArrayList<>(); - } - - if(this.groups == groups) { - return; - } - - this.groups.clear(); - - if(groups != null) { - this.groups.addAll(groups); - } - } - /** - * @return the roles - */ - public List getRoles() { - return roles; - } - /** - * @param roles the roles to set - */ - public void setRoles(List roles) { - if(this.roles == null) { - this.roles = new ArrayList<>(); - } - - if(this.roles == roles) { - return; - } - - this.roles.clear(); - - if(roles != null) { - this.roles.addAll(roles); - } - } - /** - * @return the conditions - */ - public List getConditions() { - return conditions; - } - /** - * @param conditions the conditions to set - */ - public void setConditions(List conditions) { - if(this.conditions == null) { - this.conditions = new ArrayList<>(); - } - - if(this.conditions == conditions) { - return; - } - - this.conditions.clear(); - - if(conditions != null) { - this.conditions.addAll(conditions); - } - } - - /** - * @return the delegateAdmin - */ - public Boolean getDelegateAdmin() { - return delegateAdmin; - } - - /** - * @param delegateAdmin the delegateAdmin to set - */ - public void setDelegateAdmin(Boolean delegateAdmin) { - this.delegateAdmin = delegateAdmin == null ? Boolean.FALSE : delegateAdmin; - } - - @Override - public String toString( ) { - StringBuilder sb = new StringBuilder(); - - toString(sb); - - return sb.toString(); - } - - public StringBuilder toString(StringBuilder sb) { - sb.append("RangerPolicyItem={"); - - sb.append("accessTypes={"); - if(accesses != null) { - for(RangerPolicyItemAccess access : accesses) { - if(access != null) { - access.toString(sb); - } - } - } - sb.append("} "); - - sb.append("users={"); - if(users != null) { - for(String user : users) { - if(user != null) { - sb.append(user).append(" "); - } - } - } - sb.append("} "); - - sb.append("groups={"); - if(groups != null) { - for(String group : groups) { - if(group != null) { - sb.append(group).append(" "); - } - } - } - sb.append("} "); - - sb.append("roles={"); - if(roles != null) { - for(String role : roles) { - if(role != null) { - sb.append(role).append(" "); - } - } - } - sb.append("} "); - - sb.append("conditions={"); - if(conditions != null) { - for(RangerPolicyItemCondition condition : conditions) { - if(condition != null) { - condition.toString(sb); - } - } - } - sb.append("} "); - - sb.append("delegateAdmin={").append(delegateAdmin).append("} "); - sb.append("}"); - - return sb; - } - - @Override - public int hashCode() { - final int prime = 31; - int result = 1; - result = prime * result - + ((accesses == null) ? 0 : accesses.hashCode()); - result = prime * result - + ((conditions == null) ? 0 : conditions.hashCode()); - result = prime * result - + ((delegateAdmin == null) ? 0 : delegateAdmin.hashCode()); - result = prime * result - + ((roles == null) ? 0 : roles.hashCode()); - result = prime * result - + ((groups == null) ? 0 : groups.hashCode()); - result = prime * result + ((users == null) ? 0 : users.hashCode()); - return result; - } - - @Override - public boolean equals(Object obj) { - if (this == obj) - return true; - if (obj == null) - return false; - if (getClass() != obj.getClass()) - return false; - RangerPolicyItem other = (RangerPolicyItem) obj; - if (accesses == null) { - if (other.accesses != null) - return false; - } else if (!accesses.equals(other.accesses)) - return false; - if (conditions == null) { - if (other.conditions != null) - return false; - } else if (!conditions.equals(other.conditions)) - return false; - if (delegateAdmin == null) { - if (other.delegateAdmin != null) - return false; - } else if (!delegateAdmin.equals(other.delegateAdmin)) - return false; - if (roles == null) { - if (other.roles != null) - return false; - } else if (!roles.equals(other.roles)) - return false; - if (groups == null) { - if (other.groups != null) - return false; - } else if (!groups.equals(other.groups)) - return false; - if (users == null) { - if (other.users != null) - return false; - } else if (!users.equals(other.users)) - return false; - return true; - - } - } - - @JsonInclude(JsonInclude.Include.NON_NULL) - @XmlRootElement - @XmlAccessorType(XmlAccessType.FIELD) - public static class RangerDataMaskPolicyItem extends RangerPolicyItem implements java.io.Serializable { - private static final long serialVersionUID = 1L; - - private RangerPolicyItemDataMaskInfo dataMaskInfo; - - public RangerDataMaskPolicyItem() { - this(null, null, null, null, null, null, null); - } - - public RangerDataMaskPolicyItem(List accesses, RangerPolicyItemDataMaskInfo dataMaskDetail, List users, List groups, List roles, List conditions, Boolean delegateAdmin) { - super(accesses, users, groups, roles, conditions, delegateAdmin); - - setDataMaskInfo(dataMaskDetail); - } - - /** - * @return the dataMaskInfo - */ - public RangerPolicyItemDataMaskInfo getDataMaskInfo() { - return dataMaskInfo; - } - - /** - * @param dataMaskInfo the dataMaskInfo to set - */ - public void setDataMaskInfo(RangerPolicyItemDataMaskInfo dataMaskInfo) { - this.dataMaskInfo = dataMaskInfo == null ? new RangerPolicyItemDataMaskInfo() : dataMaskInfo; - } - - @Override - public int hashCode() { - final int prime = 31; - int result = super.hashCode(); - result = prime * result + ((dataMaskInfo == null) ? 0 : dataMaskInfo.hashCode()); - return result; - } - - @Override - public boolean equals(Object obj) { - if(! super.equals(obj)) - return false; - if (this == obj) - return true; - if (obj == null) - return false; - if (getClass() != obj.getClass()) - return false; - RangerDataMaskPolicyItem other = (RangerDataMaskPolicyItem) obj; - if (dataMaskInfo == null) { - if (other.dataMaskInfo != null) - return false; - } else if (!dataMaskInfo.equals(other.dataMaskInfo)) - return false; - return true; - } - - @Override - public String toString( ) { - StringBuilder sb = new StringBuilder(); - - toString(sb); - - return sb.toString(); - } - - public StringBuilder toString(StringBuilder sb) { - sb.append("RangerDataMaskPolicyItem={"); - - super.toString(sb); - - sb.append("dataMaskInfo={"); - if(dataMaskInfo != null) { - dataMaskInfo.toString(sb); - } - sb.append("} "); - - sb.append("}"); - - return sb; - } - } - - @JsonInclude(JsonInclude.Include.NON_NULL) - @XmlRootElement - @XmlAccessorType(XmlAccessType.FIELD) - public static class RangerRowFilterPolicyItem extends RangerPolicyItem implements java.io.Serializable { - private static final long serialVersionUID = 1L; - - private RangerPolicyItemRowFilterInfo rowFilterInfo; - - public RangerRowFilterPolicyItem() { - this(null, null, null, null, null, null, null); - } - - public RangerRowFilterPolicyItem(RangerPolicyItemRowFilterInfo rowFilterInfo, List accesses, List users, List groups, List roles, List conditions, Boolean delegateAdmin) { - super(accesses, users, groups, roles, conditions, delegateAdmin); - - setRowFilterInfo(rowFilterInfo); - } - - /** - * @return the rowFilterInfo - */ - public RangerPolicyItemRowFilterInfo getRowFilterInfo() { - return rowFilterInfo; - } - - /** - * @param rowFilterInfo the rowFilterInfo to set - */ - public void setRowFilterInfo(RangerPolicyItemRowFilterInfo rowFilterInfo) { - this.rowFilterInfo = rowFilterInfo == null ? new RangerPolicyItemRowFilterInfo() : rowFilterInfo; - } - - @Override - public int hashCode() { - final int prime = 31; - int result = super.hashCode(); - result = prime * result + ((rowFilterInfo == null) ? 0 : rowFilterInfo.hashCode()); - return result; - } - - @Override - public boolean equals(Object obj) { - if(! super.equals(obj)) - return false; - if (this == obj) - return true; - if (obj == null) - return false; - if (getClass() != obj.getClass()) - return false; - RangerRowFilterPolicyItem other = (RangerRowFilterPolicyItem) obj; - if (rowFilterInfo == null) { - if (other.rowFilterInfo != null) - return false; - } else if (!rowFilterInfo.equals(other.rowFilterInfo)) - return false; - return true; - } - - @Override - public String toString( ) { - StringBuilder sb = new StringBuilder(); - - toString(sb); - - return sb.toString(); - } - - public StringBuilder toString(StringBuilder sb) { - sb.append("RangerRowFilterPolicyItem={"); - - super.toString(sb); - - sb.append("rowFilterInfo={"); - if(rowFilterInfo != null) { - rowFilterInfo.toString(sb); - } - sb.append("} "); - - sb.append("}"); - - return sb; - } - } - - @JsonInclude(JsonInclude.Include.NON_NULL) - @XmlRootElement - @XmlAccessorType(XmlAccessType.FIELD) - public static class RangerPolicyItemAccess implements java.io.Serializable { - private static final long serialVersionUID = 1L; - - private String type; - private Boolean isAllowed; - - public RangerPolicyItemAccess() { - this(null, null); - } - - public RangerPolicyItemAccess(String type) { - this(type, null); - } - - public RangerPolicyItemAccess(String type, Boolean isAllowed) { - setType(type); - setIsAllowed(isAllowed); - } - - /** - * @return the type - */ - public String getType() { - return type; - } - - /** - * @param type the type to set - */ - public void setType(String type) { - this.type = type; - } - - /** - * @return the isAllowed - */ - public Boolean getIsAllowed() { - return isAllowed; - } - - /** - * @param isAllowed the isAllowed to set - */ - public void setIsAllowed(Boolean isAllowed) { - this.isAllowed = isAllowed == null ? Boolean.TRUE : isAllowed; - } - - @Override - public String toString( ) { - StringBuilder sb = new StringBuilder(); - - toString(sb); - - return sb.toString(); - } - - public StringBuilder toString(StringBuilder sb) { - sb.append("RangerPolicyItemAccess={"); - sb.append("type={").append(type).append("} "); - sb.append("isAllowed={").append(isAllowed).append("} "); - sb.append("}"); - - return sb; - } - - @Override - public int hashCode() { - final int prime = 31; - int result = 1; - result = prime * result - + ((isAllowed == null) ? 0 : isAllowed.hashCode()); - result = prime * result + ((type == null) ? 0 : type.hashCode()); - return result; - } - - @Override - public boolean equals(Object obj) { - if (this == obj) - return true; - if (obj == null) - return false; - if (getClass() != obj.getClass()) - return false; - RangerPolicyItemAccess other = (RangerPolicyItemAccess) obj; - if (isAllowed == null) { - if (other.isAllowed != null) - return false; - } else if (!isAllowed.equals(other.isAllowed)) - return false; - if (type == null) { - if (other.type != null) - return false; - } else if (!type.equals(other.type)) - return false; - return true; - } - - } - - @JsonInclude(JsonInclude.Include.NON_NULL) - @XmlRootElement - @XmlAccessorType(XmlAccessType.FIELD) - public static class RangerPolicyItemCondition implements java.io.Serializable { - private static final long serialVersionUID = 1L; - - private String type; - private List values; - - public RangerPolicyItemCondition() { - this(null, null); - } - - public RangerPolicyItemCondition(String type, List values) { - setType(type); - setValues(values); - } - - /** - * @return the type - */ - public String getType() { - return type; - } - - /** - * @param type the type to set - */ - public void setType(String type) { - this.type = type; - } - - /** - * @return the value - */ - public List getValues() { - return values; - } - - /** - * @param values the value to set - */ - public void setValues(List values) { - if (this.values == null) { - this.values = new ArrayList<>(); - } - - if(this.values == values) { - return; - } - - this.values.clear(); - - if(values != null) { - this.values.addAll(values); - } - } - - @Override - public String toString( ) { - StringBuilder sb = new StringBuilder(); - - toString(sb); - - return sb.toString(); - } - - public StringBuilder toString(StringBuilder sb) { - sb.append("RangerPolicyCondition={"); - sb.append("type={").append(type).append("} "); - sb.append("values={"); - if(values != null) { - for(String value : values) { - sb.append(value).append(" "); - } - } - sb.append("} "); - sb.append("}"); - - return sb; - } - - @Override - public int hashCode() { - final int prime = 31; - int result = 1; - result = prime * result + ((type == null) ? 0 : type.hashCode()); - result = prime * result - + ((values == null) ? 0 : values.hashCode()); - return result; - } - - @Override - public boolean equals(Object obj) { - if (this == obj) - return true; - if (obj == null) - return false; - if (getClass() != obj.getClass()) - return false; - RangerPolicyItemCondition other = (RangerPolicyItemCondition) obj; - if (type == null) { - if (other.type != null) - return false; - } else if (!type.equals(other.type)) - return false; - if (values == null) { - if (other.values != null) - return false; - } else if (!values.equals(other.values)) - return false; - return true; - } - - } - - @JsonInclude(JsonInclude.Include.NON_NULL) - @XmlRootElement - @XmlAccessorType(XmlAccessType.FIELD) - public static class RangerPolicyItemDataMaskInfo implements java.io.Serializable { - private static final long serialVersionUID = 1L; - - private String dataMaskType; - private String conditionExpr; - private String valueExpr; - - public RangerPolicyItemDataMaskInfo() { } - - public RangerPolicyItemDataMaskInfo(String dataMaskType, String conditionExpr, String valueExpr) { - setDataMaskType(dataMaskType); - setConditionExpr(conditionExpr); - setValueExpr(valueExpr); - } - - public RangerPolicyItemDataMaskInfo(RangerPolicyItemDataMaskInfo that) { - this.dataMaskType = that.dataMaskType; - this.conditionExpr = that.conditionExpr; - this.valueExpr = that.valueExpr; - } - - public String getDataMaskType() { - return dataMaskType; - } - - public void setDataMaskType(String dataMaskType) { - this.dataMaskType = dataMaskType; - } - - public String getConditionExpr() { - return conditionExpr; - } - - public void setConditionExpr(String conditionExpr) { - this.conditionExpr = conditionExpr; - } - - public String getValueExpr() { - return valueExpr; - } - - public void setValueExpr(String valueExpr) { - this.valueExpr = valueExpr; - } - - @Override - public int hashCode() { - final int prime = 31; - int result = super.hashCode(); - result = prime * result + ((dataMaskType == null) ? 0 : dataMaskType.hashCode()); - result = prime * result + ((conditionExpr == null) ? 0 : conditionExpr.hashCode()); - result = prime * result + ((valueExpr == null) ? 0 : valueExpr.hashCode()); - return result; - } - - @Override - public boolean equals(Object obj) { - if (this == obj) - return true; - if (obj == null) - return false; - if (getClass() != obj.getClass()) - return false; - RangerPolicyItemDataMaskInfo other = (RangerPolicyItemDataMaskInfo) obj; - if (dataMaskType == null) { - if (other.dataMaskType != null) - return false; - } else if (!dataMaskType.equals(other.dataMaskType)) - return false; - if (conditionExpr == null) { - if (other.conditionExpr != null) - return false; - } else if (!conditionExpr.equals(other.conditionExpr)) - return false; - if (valueExpr == null) { - if (other.valueExpr != null) - return false; - } else if (!valueExpr.equals(other.valueExpr)) - return false; - return true; - } - - @Override - public String toString( ) { - StringBuilder sb = new StringBuilder(); - - toString(sb); - - return sb.toString(); - } - - public StringBuilder toString(StringBuilder sb) { - sb.append("RangerPolicyItemDataMaskInfo={"); - - sb.append("dataMaskType={").append(dataMaskType).append("} "); - sb.append("conditionExpr={").append(conditionExpr).append("} "); - sb.append("valueExpr={").append(valueExpr).append("} "); - - sb.append("}"); - - return sb; - } - } - - @JsonInclude(JsonInclude.Include.NON_NULL) - @XmlRootElement - @XmlAccessorType(XmlAccessType.FIELD) - public static class RangerPolicyItemRowFilterInfo implements java.io.Serializable { - private static final long serialVersionUID = 1L; - - private String filterExpr; - - public RangerPolicyItemRowFilterInfo() { } - - public RangerPolicyItemRowFilterInfo(String filterExpr) { - setFilterExpr(filterExpr); - } - - public RangerPolicyItemRowFilterInfo(RangerPolicyItemRowFilterInfo that) { - this.filterExpr = that.filterExpr; - } - - public String getFilterExpr() { - return filterExpr; - } - - public void setFilterExpr(String filterExpr) { - this.filterExpr = filterExpr; - } - - @Override - public int hashCode() { - final int prime = 31; - int result = super.hashCode(); - result = prime * result + ((filterExpr == null) ? 0 : filterExpr.hashCode()); - return result; - } - - @Override - public boolean equals(Object obj) { - if (this == obj) - return true; - if (obj == null) - return false; - if (getClass() != obj.getClass()) - return false; - RangerPolicyItemRowFilterInfo other = (RangerPolicyItemRowFilterInfo) obj; - if (filterExpr == null) { - if (other.filterExpr != null) - return false; - } else if (!filterExpr.equals(other.filterExpr)) - return false; - return true; - } - - @Override - public String toString( ) { - StringBuilder sb = new StringBuilder(); - - toString(sb); - - return sb.toString(); - } - - public StringBuilder toString(StringBuilder sb) { - sb.append("RangerPolicyItemRowFilterInfo={"); - - sb.append("filterExpr={").append(filterExpr).append("} "); - - sb.append("}"); - - return sb; - } - } -} diff --git a/auth-agents-common/src/main/java/org/apache/atlas/plugin/service/RangerBasePlugin.java b/auth-agents-common/src/main/java/org/apache/atlas/plugin/service/RangerBasePlugin.java index b224cccc7e..21bec4d03e 100644 --- a/auth-agents-common/src/main/java/org/apache/atlas/plugin/service/RangerBasePlugin.java +++ b/auth-agents-common/src/main/java/org/apache/atlas/plugin/service/RangerBasePlugin.java @@ -19,6 +19,8 @@ package org.apache.atlas.plugin.service; +import org.apache.atlas.authorizer.store.PoliciesStore; +import org.apache.atlas.authorizer.store.UsersStore; import org.apache.atlas.type.AtlasTypeRegistry; import org.apache.commons.collections.CollectionUtils; import org.apache.commons.collections.MapUtils; @@ -176,6 +178,7 @@ public RangerRoles getRoles() { public void setRoles(RangerRoles roles) { this.roles = roles; + UsersStore.getInstance().setAllRoles(roles); RangerPolicyEngine policyEngine = this.policyEngine; @@ -192,6 +195,7 @@ public RangerUserStore getUserStore() { public void setUserStore(RangerUserStore userStore) { this.userStore = userStore; + UsersStore.getInstance().setUserStore(userStore); // RangerPolicyEngine policyEngine = this.policyEngine; @@ -296,6 +300,16 @@ public void setPolicies(ServicePolicies policies) { LOG.debug("==> setPolicies(" + policies + ")"); } + if (policies != null) { + List resourcePolicies = policies.getPolicies(); + List tagPolicies = policies.getTagPolicies().getPolicies(); + List abacPolicies = policies.getAbacPolicies().getPolicies(); + + PoliciesStore.getInstance().setResourcePolicies(resourcePolicies); + PoliciesStore.getInstance().setTagPolicies(tagPolicies); + PoliciesStore.getInstance().setAbacPolicies(abacPolicies); + } + // guard against catastrophic failure during policy engine Initialization or try { RangerPolicyEngine oldPolicyEngine = this.policyEngine; diff --git a/auth-agents-common/src/main/java/org/apache/atlas/plugin/util/ServicePolicies.java b/auth-agents-common/src/main/java/org/apache/atlas/plugin/util/ServicePolicies.java index 547349c8f5..62c3b488bd 100644 --- a/auth-agents-common/src/main/java/org/apache/atlas/plugin/util/ServicePolicies.java +++ b/auth-agents-common/src/main/java/org/apache/atlas/plugin/util/ServicePolicies.java @@ -20,6 +20,7 @@ package org.apache.atlas.plugin.util; +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import org.apache.commons.collections.MapUtils; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; @@ -40,6 +41,7 @@ import java.util.List; import java.util.Map; +@JsonIgnoreProperties(ignoreUnknown = true) @JsonInclude(JsonInclude.Include.NON_NULL) @XmlRootElement @XmlAccessorType(XmlAccessType.FIELD) @@ -55,6 +57,7 @@ public class ServicePolicies implements java.io.Serializable { private RangerServiceDef serviceDef; private String auditMode = RangerPolicyEngine.AUDIT_DEFAULT; private TagPolicies tagPolicies; + private AbacPolicies abacPolicies; private Map securityZones; private List policyDeltas; private Map serviceConfig; @@ -160,6 +163,14 @@ public void setTagPolicies(TagPolicies tagPolicies) { this.tagPolicies = tagPolicies; } + public AbacPolicies getAbacPolicies() { + return abacPolicies; + } + + public void setAbacPolicies(AbacPolicies abacPolicies) { + this.abacPolicies = abacPolicies; + } + public Map getSecurityZones() { return securityZones; } public void setSecurityZones(Map securityZones) { @@ -302,6 +313,99 @@ public String toString() { } } + @JsonInclude(JsonInclude.Include.NON_NULL) + @XmlRootElement + @XmlAccessorType(XmlAccessType.FIELD) + public static class AbacPolicies implements java.io.Serializable { + private static final long serialVersionUID = 1L; + + private String serviceName; + private String serviceId; + private Long policyVersion; + private Date policyUpdateTime; + private List policies; + private RangerServiceDef serviceDef; + private String auditMode = RangerPolicyEngine.AUDIT_DEFAULT; + private Map serviceConfig; + + public String getServiceName() { + return serviceName; + } + + public void setServiceName(String serviceName) { + this.serviceName = serviceName; + } + + public String getServiceId() { + return serviceId; + } + + public void setServiceId(String serviceId) { + this.serviceId = serviceId; + } + + public Long getPolicyVersion() { + return policyVersion; + } + + public void setPolicyVersion(Long policyVersion) { + this.policyVersion = policyVersion; + } + + public Date getPolicyUpdateTime() { + return policyUpdateTime; + } + + public void setPolicyUpdateTime(Date policyUpdateTime) { + this.policyUpdateTime = policyUpdateTime; + } + + public List getPolicies() { + return policies; + } + + public void setPolicies(List policies) { + this.policies = policies; + } + + public RangerServiceDef getServiceDef() { + return serviceDef; + } + + public void setServiceDef(RangerServiceDef serviceDef) { + this.serviceDef = serviceDef; + } + + public String getAuditMode() { + return auditMode; + } + + public void setAuditMode(String auditMode) { + this.auditMode = auditMode; + } + + public Map getServiceConfig() { + return serviceConfig; + } + + public void setServiceConfig(Map serviceConfig) { + this.serviceConfig = serviceConfig; + } + + @Override + public String toString() { + return "serviceName=" + serviceName + ", " + + "serviceId=" + serviceId + ", " + + "policyVersion=" + policyVersion + ", " + + "policyUpdateTime=" + policyUpdateTime + ", " + + "policies=" + policies + ", " + + "serviceDef=" + serviceDef + ", " + + "auditMode=" + auditMode + + "serviceConfig=" + serviceConfig + ; + } + } + @JsonInclude(JsonInclude.Include.NON_NULL) @XmlRootElement @XmlAccessorType(XmlAccessType.FIELD) diff --git a/auth-agents-common/src/main/java/org/apache/atlas/policytransformer/AbstractCachePolicyTransformer.java b/auth-agents-common/src/main/java/org/apache/atlas/policytransformer/AbstractCachePolicyTransformer.java index 5c0a16b0b6..cd5dec9e36 100644 --- a/auth-agents-common/src/main/java/org/apache/atlas/policytransformer/AbstractCachePolicyTransformer.java +++ b/auth-agents-common/src/main/java/org/apache/atlas/policytransformer/AbstractCachePolicyTransformer.java @@ -30,6 +30,7 @@ public abstract class AbstractCachePolicyTransformer implements CachePolicyTrans public static final String PLACEHOLDER_ENTITY = "{entity}"; public static final String PLACEHOLDER_ENTITY_TYPE = "{entity-type}"; + public static final String PLACEHOLDER_FILTER_CRITERIA = "{criteria}"; public static final String PLACEHOLDER_TAG = "{tag}"; private static Map TEMPLATES = new HashMap<>(); diff --git a/auth-agents-common/src/main/java/org/apache/atlas/policytransformer/CachePolicyTransformerImpl.java b/auth-agents-common/src/main/java/org/apache/atlas/policytransformer/CachePolicyTransformerImpl.java index 4a81129a3c..75e7f39dc6 100644 --- a/auth-agents-common/src/main/java/org/apache/atlas/policytransformer/CachePolicyTransformerImpl.java +++ b/auth-agents-common/src/main/java/org/apache/atlas/policytransformer/CachePolicyTransformerImpl.java @@ -62,19 +62,8 @@ import java.util.Set; import java.util.stream.Collectors; -import static org.apache.atlas.repository.Constants.NAME; -import static org.apache.atlas.repository.Constants.QUALIFIED_NAME; -import static org.apache.atlas.repository.Constants.SERVICE_ENTITY_TYPE; -import static org.apache.atlas.repository.util.AccessControlUtils.ATTR_POLICY_CATEGORY; -import static org.apache.atlas.repository.util.AccessControlUtils.ATTR_POLICY_CONNECTION_QN; -import static org.apache.atlas.repository.util.AccessControlUtils.ATTR_POLICY_IS_ENABLED; -import static org.apache.atlas.repository.util.AccessControlUtils.ATTR_POLICY_PRIORITY; -import static org.apache.atlas.repository.util.AccessControlUtils.ATTR_POLICY_SERVICE_NAME; -import static org.apache.atlas.repository.util.AccessControlUtils.ATTR_POLICY_SUB_CATEGORY; -import static org.apache.atlas.repository.util.AccessControlUtils.POLICY_CATEGORY_PERSONA; -import static org.apache.atlas.repository.util.AccessControlUtils.POLICY_CATEGORY_PURPOSE; -import static org.apache.atlas.repository.util.AccessControlUtils.getIsPolicyEnabled; -import static org.apache.atlas.repository.util.AccessControlUtils.getPolicyCategory; +import static org.apache.atlas.repository.Constants.*; +import static org.apache.atlas.repository.util.AccessControlUtils.*; @Component public class CachePolicyTransformerImpl { @@ -91,6 +80,7 @@ public class CachePolicyTransformerImpl { public static final String ATTR_SERVICE_SERVICE_TYPE = "authServiceType"; public static final String ATTR_SERVICE_TAG_SERVICE = "tagService"; + public static final String ATTR_SERVICE_ABAC_SERVICE = "abacService"; public static final String ATTR_SERVICE_IS_ENABLED = "authServiceIsEnabled"; public static final String ATTR_SERVICE_LAST_SYNC = "authServicePolicyLastSync"; @@ -178,13 +168,43 @@ public ServicePolicies getPolicies(String serviceName, String pluginId, Long las } } + //Process abac based policies + String abacServiceName = (String) service.getAttribute(ATTR_SERVICE_ABAC_SERVICE); + + if (StringUtils.isNotEmpty(abacServiceName)) { + AtlasEntityHeader abacService = getServiceEntity(abacServiceName); + + if (abacService != null) { + allPolicies.addAll(getServicePolicies(abacService)); + ServicePolicies.AbacPolicies abacPolicies = new ServicePolicies.AbacPolicies(); + abacPolicies.setServiceName(abacServiceName); + abacPolicies.setPolicyUpdateTime(new Date()); + abacPolicies.setServiceId(abacService.getGuid()); + abacPolicies.setPolicyVersion(-1L); + String abacServiceDefName = String.format(RESOURCE_SERVICE_DEF_PATTERN, abacService.getAttribute(NAME)); + abacPolicies.setServiceDef(getResourceAsObject(abacServiceDefName, RangerServiceDef.class)); + + servicePolicies.setAbacPolicies(abacPolicies); + } + } + AtlasPerfMetrics.MetricRecorder recorderFilterPolicies = RequestContext.get().startMetricRecord("filterPolicies"); //filter out policies based on serviceName - List policiesA = allPolicies.stream().filter(x -> serviceName.equals(x.getService())).collect(Collectors.toList()); - List policiesB = allPolicies.stream().filter(x -> tagServiceName.equals(x.getService())).collect(Collectors.toList()); + List policiesA = new ArrayList<>(); + List policiesB = new ArrayList<>(); + List policiesC = new ArrayList<>(); + + try { + policiesA = allPolicies.stream().filter(x -> serviceName.equals(x.getService())).collect(Collectors.toList()); + policiesB = allPolicies.stream().filter(x -> tagServiceName.equals(x.getService())).collect(Collectors.toList()); + policiesC = allPolicies.stream().filter(x -> abacServiceName.equals(x.getService())).collect(Collectors.toList()); + } catch (NullPointerException exception) { + + } servicePolicies.setPolicies(policiesA); servicePolicies.getTagPolicies().setPolicies(policiesB); + servicePolicies.getAbacPolicies().setPolicies(policiesC); RequestContext.get().endMetricRecord(recorderFilterPolicies); @@ -427,6 +447,7 @@ private List getAtlasPolicies(String serviceName) throws Atla attributes.add(NAME); attributes.add(ATTR_POLICY_CATEGORY); attributes.add(ATTR_POLICY_SUB_CATEGORY); + attributes.add(ATTR_POLICY_FILTER_CRITERIA); attributes.add(ATTR_POLICY_TYPE); attributes.add(ATTR_POLICY_SERVICE_NAME); attributes.add(ATTR_POLICY_USERS); @@ -446,6 +467,7 @@ private List getAtlasPolicies(String serviceName) throws Atla List> mustClauseList = new ArrayList<>(); mustClauseList.add(getMap("term", getMap(ATTR_POLICY_SERVICE_NAME, serviceName))); + mustClauseList.add(getMap("term", getMap(ATTR_POLICY_IS_ENABLED, true))); mustClauseList.add(getMap("match", getMap("__state", Id.EntityState.ACTIVE))); dsl.put("query", getMap("bool", getMap("must", mustClauseList))); @@ -491,6 +513,7 @@ private AtlasEntityHeader getServiceEntity(String serviceName) throws AtlasBaseE attributes.add(NAME); attributes.add(ATTR_SERVICE_SERVICE_TYPE); attributes.add(ATTR_SERVICE_TAG_SERVICE); + attributes.add(ATTR_SERVICE_ABAC_SERVICE); attributes.add(ATTR_SERVICE_IS_ENABLED); Map dsl = getMap("size", 1); @@ -531,6 +554,7 @@ private RangerPolicy getRangerPolicy(AtlasEntityHeader atlasPolicy, String servi policy.setCreatedBy(atlasPolicy.getCreatedBy()); policy.setCreateTime(atlasPolicy.getCreateTime()); policy.setIsEnabled(getIsPolicyEnabled(atlasPolicy)); + policy.setPolicyResourceCategory(getPolicyResourceCategory(atlasPolicy)); policy.setConditions(getPolicyConditions(atlasPolicy)); policy.setValiditySchedules(getPolicyValiditySchedule(atlasPolicy)); @@ -539,6 +563,11 @@ private RangerPolicy getRangerPolicy(AtlasEntityHeader atlasPolicy, String servi policy.setPolicyPriority((Integer) atlasPolicy.getAttribute(ATTR_POLICY_PRIORITY)); } + if (POLICY_SERVICE_NAME_ABAC.equals(atlasPolicy.getAttribute(ATTR_POLICY_SERVICE_NAME))) { + String policyFilterCriteria = getPolicyFilterCriteria(atlasPolicy); + policy.setPolicyFilterCriteria(policyFilterCriteria); + } + return policy; } } diff --git a/auth-agents-common/src/main/java/org/apache/atlas/policytransformer/PersonaCachePolicyTransformer.java b/auth-agents-common/src/main/java/org/apache/atlas/policytransformer/PersonaCachePolicyTransformer.java index 6a6d2d3cd9..b4d296faf1 100644 --- a/auth-agents-common/src/main/java/org/apache/atlas/policytransformer/PersonaCachePolicyTransformer.java +++ b/auth-agents-common/src/main/java/org/apache/atlas/policytransformer/PersonaCachePolicyTransformer.java @@ -17,6 +17,10 @@ */ package org.apache.atlas.policytransformer; +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.ObjectMapper; + import org.apache.atlas.RequestContext; import org.apache.atlas.exception.AtlasBaseException; import org.apache.atlas.model.instance.AtlasEntity; @@ -33,20 +37,7 @@ import static org.apache.atlas.policytransformer.CachePolicyTransformerImpl.ATTR_NAME; import static org.apache.atlas.policytransformer.CachePolicyTransformerImpl.ATTR_POLICY_RESOURCES; -import static org.apache.atlas.repository.util.AccessControlUtils.ATTR_POLICY_ACTIONS; -import static org.apache.atlas.repository.util.AccessControlUtils.ATTR_POLICY_IS_ENABLED; -import static org.apache.atlas.repository.util.AccessControlUtils.ATTR_POLICY_RESOURCES_CATEGORY; -import static org.apache.atlas.repository.util.AccessControlUtils.POLICY_SUB_CATEGORY_DATA; -import static org.apache.atlas.repository.util.AccessControlUtils.POLICY_SUB_CATEGORY_METADATA; -import static org.apache.atlas.repository.util.AccessControlUtils.RESOURCES_ENTITY; -import static org.apache.atlas.repository.util.AccessControlUtils.RESOURCES_ENTITY_TYPE; -import static org.apache.atlas.repository.util.AccessControlUtils.getEntityByQualifiedName; -import static org.apache.atlas.repository.util.AccessControlUtils.getFilteredPolicyResources; -import static org.apache.atlas.repository.util.AccessControlUtils.getIsPolicyEnabled; -import static org.apache.atlas.repository.util.AccessControlUtils.getPolicyActions; -import static org.apache.atlas.repository.util.AccessControlUtils.getPolicyConnectionQN; -import static org.apache.atlas.repository.util.AccessControlUtils.getPolicyResources; -import static org.apache.atlas.repository.util.AccessControlUtils.getPolicySubCategory; +import static org.apache.atlas.repository.util.AccessControlUtils.*; public class PersonaCachePolicyTransformer extends AbstractCachePolicyTransformer { private static final Logger LOG = LoggerFactory.getLogger(PersonaCachePolicyTransformer.class); @@ -70,6 +61,9 @@ public List transform(AtlasEntityHeader atlasPolicy) { List entityResources = getFilteredPolicyResources(atlasResources, RESOURCES_ENTITY); List typeResources = getFilteredPolicyResources(atlasResources, RESOURCES_ENTITY_TYPE); + String policyServiceName = getPolicyServiceName(atlasPolicy); + String policyFilterCriteria = getPolicyFilterCriteria(atlasPolicy); + int index = 0; for (String atlasAction : atlasActions) { List currentTemplates = personaTemplate.getTemplate(atlasAction); @@ -87,43 +81,58 @@ public List transform(AtlasEntityHeader atlasPolicy) { header.setAttribute(ATTR_POLICY_ACTIONS, templatePolicy.getActions()); header.setAttribute(ATTR_POLICY_RESOURCES_CATEGORY, templatePolicy.getPolicyResourceCategory()); header.setAttribute(ATTR_POLICY_IS_ENABLED, getIsPolicyEnabled(atlasPolicy)); + header.setAttribute(ATTR_NAME, "transformed_policy_persona"); - String subCategory = getPolicySubCategory(atlasPolicy); - - List finalResources = new ArrayList<>(); - - for (String templateResource : templatePolicy.getResources()) { - if (templateResource.contains(PLACEHOLDER_ENTITY)) { - for (String entityResource : entityResources) { - finalResources.add(templateResource.replace(PLACEHOLDER_ENTITY, entityResource)); + if (policyServiceName.equals(POLICY_SERVICE_NAME_ABAC)) { + if (policyFilterCriteria != null && !policyFilterCriteria.isEmpty()) { + ObjectMapper mapper = new ObjectMapper(); + try { + JsonNode filterCriteriaNode = mapper.readTree(policyFilterCriteria); + if (filterCriteriaNode != null && filterCriteriaNode.get("entity") != null) { + JsonNode entityFilterCriteriaNode = filterCriteriaNode.get("entity"); + policyFilterCriteria = entityFilterCriteriaNode.toString(); + } + } catch (JsonProcessingException e) { + e.printStackTrace(); } + } + header.setAttribute(ATTR_POLICY_FILTER_CRITERIA, + templatePolicy.getPolicyFilterCriteria().replace(PLACEHOLDER_FILTER_CRITERIA, policyFilterCriteria)); + } else { + String subCategory = getPolicySubCategory(atlasPolicy); - } else if (templateResource.contains(PLACEHOLDER_ENTITY_TYPE)) { - - if (CollectionUtils.isNotEmpty(typeResources)) { - typeResources.forEach(x -> finalResources.add(templateResource.replace(PLACEHOLDER_ENTITY_TYPE, x))); - } else { - boolean isConnection = false; + List finalResources = new ArrayList<>(); - if (POLICY_SUB_CATEGORY_METADATA.equals(subCategory) || POLICY_SUB_CATEGORY_DATA.equals(subCategory)) { - isConnection = isConnectionPolicy(entityResources, atlasPolicy); + for (String templateResource : templatePolicy.getResources()) { + if (templateResource.contains(PLACEHOLDER_ENTITY)) { + for (String entityResource : entityResources) { + finalResources.add(templateResource.replace(PLACEHOLDER_ENTITY, entityResource)); } - if (isConnection) { - finalResources.add(templateResource.replace(PLACEHOLDER_ENTITY_TYPE, "*")); + } else if (templateResource.contains(PLACEHOLDER_ENTITY_TYPE)) { + + if (CollectionUtils.isNotEmpty(typeResources)) { + typeResources.forEach(x -> finalResources.add(templateResource.replace(PLACEHOLDER_ENTITY_TYPE, x))); } else { - finalResources.add(templateResource.replace(PLACEHOLDER_ENTITY_TYPE, "Process")); - finalResources.add(templateResource.replace(PLACEHOLDER_ENTITY_TYPE, "Catalog")); + boolean isConnection = false; + + if (POLICY_SUB_CATEGORY_METADATA.equals(subCategory) || POLICY_SUB_CATEGORY_DATA.equals(subCategory)) { + isConnection = isConnectionPolicy(entityResources, atlasPolicy); + } + + if (isConnection) { + finalResources.add(templateResource.replace(PLACEHOLDER_ENTITY_TYPE, "*")); + } else { + finalResources.add(templateResource.replace(PLACEHOLDER_ENTITY_TYPE, "Process")); + finalResources.add(templateResource.replace(PLACEHOLDER_ENTITY_TYPE, "Catalog")); + } } + } else { + finalResources.add(templateResource); } - } else { - finalResources.add(templateResource); } + header.setAttribute(ATTR_POLICY_RESOURCES, finalResources); } - header.setAttribute(ATTR_POLICY_RESOURCES, finalResources); - - header.setAttribute(ATTR_NAME, "transformed_policy_persona"); - ret.add(header); } } diff --git a/auth-agents-common/src/main/java/org/apache/atlas/policytransformer/PolicyTransformerTemplate.java b/auth-agents-common/src/main/java/org/apache/atlas/policytransformer/PolicyTransformerTemplate.java index 3bde95eef1..13ada447c5 100644 --- a/auth-agents-common/src/main/java/org/apache/atlas/policytransformer/PolicyTransformerTemplate.java +++ b/auth-agents-common/src/main/java/org/apache/atlas/policytransformer/PolicyTransformerTemplate.java @@ -63,6 +63,11 @@ public void fromJsonString(String json) { templatePolicy.setPolicyResourceCategory((String) policy.get("policyResourceCategory")); templatePolicy.setPolicyServiceName((String) policy.get("policyServiceName")); + Object filterCriteria = policy.get("policyFilterCriteria"); + if (filterCriteria != null) { + templatePolicy.setPolicyFilterCriteria((String) filterCriteria); + } + policies.add(templatePolicy); } @@ -76,6 +81,7 @@ class TemplatePolicy { private List resources; private List actions; private String policyResourceCategory; + private String policyFilterCriteria; public String getPolicyServiceName() { return policyServiceName; @@ -116,5 +122,13 @@ public List getActions() { public void setActions(List actions) { this.actions = actions; } + + public String getPolicyFilterCriteria() { + return policyFilterCriteria; + } + + public void setPolicyFilterCriteria(String policyFilterCriteria) { + this.policyFilterCriteria = policyFilterCriteria; + } } } diff --git a/auth-common/pom.xml b/auth-common/pom.xml new file mode 100644 index 0000000000..d816422e69 --- /dev/null +++ b/auth-common/pom.xml @@ -0,0 +1,31 @@ + + + + apache-atlas + org.apache.atlas + 3.0.0-SNAPSHOT + + 4.0.0 + + auth-common + + + + org.apache.htrace + htrace-core4 + 4.1.0-incubating + compile + + + commons-collections + commons-collections + + + commons-lang + commons-lang + + + + \ No newline at end of file diff --git a/auth-agents-common/src/main/java/org/apache/atlas/plugin/model/GroupInfo.java b/auth-common/src/main/java/org/apache/atlas/plugin/model/GroupInfo.java similarity index 100% rename from auth-agents-common/src/main/java/org/apache/atlas/plugin/model/GroupInfo.java rename to auth-common/src/main/java/org/apache/atlas/plugin/model/GroupInfo.java diff --git a/auth-common/src/main/java/org/apache/atlas/plugin/model/NewAccessResourceImpl.java b/auth-common/src/main/java/org/apache/atlas/plugin/model/NewAccessResourceImpl.java new file mode 100644 index 0000000000..0841060387 --- /dev/null +++ b/auth-common/src/main/java/org/apache/atlas/plugin/model/NewAccessResourceImpl.java @@ -0,0 +1,253 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.apache.atlas.plugin.model; + +import org.apache.atlas.plugin.model.RangerServiceDef.RangerResourceDef; +import org.apache.commons.lang.ObjectUtils; + +import java.util.Collections; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Set; + +public class NewAccessResourceImpl { + + private String RESOURCE_SEP = "/"; + private String RESOURCE_NAME_VAL_SEP = "="; + + private String ownerUser; + private Map elements; + private String stringifiedValue; + private String stringifiedCacheKeyValue; + private String leafName; + private RangerServiceDef serviceDef; + + public NewAccessResourceImpl() { + this(null, null); + } + + public NewAccessResourceImpl(Map elements) { + this(elements, null); + } + + public NewAccessResourceImpl(Map elements, String ownerUser) { + this.elements = elements; + this.ownerUser = ownerUser; + } + + public String getOwnerUser() { + return ownerUser; + } + + public boolean exists(String name) { + return elements != null && elements.containsKey(name); + } + + public Object getValue(String name) { + Object ret = null; + + if(elements != null && elements.containsKey(name)) { + ret = elements.get(name); + } + + return ret; + } + + public Set getKeys() { + Set ret = null; + + if(elements != null) { + ret = elements.keySet(); + } + + return ret; + } + + public void setOwnerUser(String ownerUser) { + this.ownerUser = ownerUser; + } + + public void setValue(String name, Object value) { + if(value == null) { + if(elements != null) { + elements.remove(name); + + if(elements.isEmpty()) { + elements = null; + } + } + } else { + if(elements == null) { + elements = new HashMap<>(); + } + elements.put(name, value); + } + + // reset, so that these will be computed again with updated elements + stringifiedValue = stringifiedCacheKeyValue = leafName = null; + } + + public void setServiceDef(final RangerServiceDef serviceDef) { + this.serviceDef = serviceDef; + this.stringifiedValue = this.stringifiedCacheKeyValue = this.leafName = null; + } + + public RangerServiceDef getServiceDef() { + return this.serviceDef; + } + + public String getLeafName() { + String ret = leafName; + + if(ret == null) { + if(serviceDef != null && serviceDef.getResources() != null) { + List resourceDefs = serviceDef.getResources(); + + for(int idx = resourceDefs.size() - 1; idx >= 0; idx--) { + RangerResourceDef resourceDef = resourceDefs.get(idx); + + if(resourceDef != null && exists(resourceDef.getName())) { + ret = leafName = resourceDef.getName(); + break; + } + } + } + } + + return ret; + } + + public String getAsString() { + String ret = stringifiedValue; + + if(ret == null) { + if(serviceDef != null && serviceDef.getResources() != null) { + StringBuilder sb = new StringBuilder(); + + for(RangerResourceDef resourceDef : serviceDef.getResources()) { + if(resourceDef == null || !exists(resourceDef.getName())) { + continue; + } + + if(sb.length() > 0) { + sb.append(RESOURCE_SEP); + } + + sb.append(getValue(resourceDef.getName())); + } + + if(sb.length() > 0) { + ret = stringifiedValue = sb.toString(); + } + } + } + + return ret; + } + + public String getCacheKey() { + String ret = stringifiedCacheKeyValue; + + if(ret == null) { + if(serviceDef != null && serviceDef.getResources() != null) { + StringBuilder sb = new StringBuilder(); + + for(RangerResourceDef resourceDef : serviceDef.getResources()) { + if(resourceDef == null || !exists(resourceDef.getName())) { + continue; + } + + if(sb.length() > 0) { + sb.append(RESOURCE_SEP); + } + + sb.append(resourceDef.getName()).append(RESOURCE_NAME_VAL_SEP).append(getValue(resourceDef.getName())); + } + + if(sb.length() > 0) { + ret = stringifiedCacheKeyValue = sb.toString(); + } + } + } + + return ret; + } + + public Map getAsMap() { + return elements == null ? Collections.EMPTY_MAP : Collections.unmodifiableMap(elements); + } + + public boolean equals(Object obj) { + if(obj == null || !(obj instanceof NewAccessResourceImpl)) { + return false; + } + + if(this == obj) { + return true; + } + + NewAccessResourceImpl other = (NewAccessResourceImpl) obj; + + return ObjectUtils.equals(ownerUser, other.ownerUser) && + ObjectUtils.equals(elements, other.elements); + } + + @Override + public int hashCode() { + int ret = 7; + + ret = 31 * ret + ObjectUtils.hashCode(ownerUser); + ret = 31 * ret + ObjectUtils.hashCode(elements); + + return ret; + } + + @Override + public String toString( ) { + StringBuilder sb = new StringBuilder(); + + toString(sb); + + return sb.toString(); + } + + public StringBuilder toString(StringBuilder sb) { + sb.append("RangerResourceImpl={"); + + sb.append("ownerUser={").append(ownerUser).append("} "); + + sb.append("elements={"); + if(elements != null) { + for(Map.Entry e : elements.entrySet()) { + sb.append(e.getKey()).append("=").append(e.getValue()).append("; "); + } + } + sb.append("} "); + + sb.append("}"); + + return sb; + } + + protected String getStringifiedValue() { return stringifiedValue; } + + protected void setStringifiedValue(String val) { this.stringifiedValue = val; } +} diff --git a/auth-common/src/main/java/org/apache/atlas/plugin/model/RangerBaseModelObject.java b/auth-common/src/main/java/org/apache/atlas/plugin/model/RangerBaseModelObject.java new file mode 100644 index 0000000000..aa8532da15 --- /dev/null +++ b/auth-common/src/main/java/org/apache/atlas/plugin/model/RangerBaseModelObject.java @@ -0,0 +1,170 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.apache.atlas.plugin.model; + +import org.apache.htrace.shaded.fasterxml.jackson.annotation.JsonInclude; + +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.XmlRootElement; +import java.util.Date; + +@JsonInclude(JsonInclude.Include.NON_NULL) +@XmlRootElement +@XmlAccessorType(XmlAccessType.FIELD) +public class RangerBaseModelObject implements java.io.Serializable { + private static final long serialVersionUID = 1L; + + private Long id; + private String guid; + private Boolean isEnabled; + private String createdBy; + private String updatedBy; + private Date createTime; + private Date updateTime; + private Long version; + + public RangerBaseModelObject() { + setIsEnabled(null); + } + + public void updateFrom(RangerBaseModelObject other) { + setIsEnabled(other.getIsEnabled()); + } + + /** + * @return the id + */ + public Long getId() { + return id; + } + /** + * @param id the id to set + */ + public void setId(Long id) { + this.id = id; + } + /** + * @return the guid + */ + public String getGuid() { + return guid; + } + /** + * @param guid the guid to set + */ + public void setGuid(String guid) { + this.guid = guid; + } + /** + * @return the isEnabled + */ + public Boolean getIsEnabled() { + return isEnabled; + } + /** + * @param isEnabled the isEnabled to set + */ + public void setIsEnabled(Boolean isEnabled) { + this.isEnabled = isEnabled == null ? Boolean.TRUE : isEnabled; + } + /** + * @return the createdBy + */ + public String getCreatedBy() { + return createdBy; + } + /** + * @param createdBy the createdBy to set + */ + public void setCreatedBy(String createdBy) { + this.createdBy = createdBy; + } + /** + * @return the updatedBy + */ + public String getUpdatedBy() { + return updatedBy; + } + /** + * @param updatedBy the updatedBy to set + */ + public void setUpdatedBy(String updatedBy) { + this.updatedBy = updatedBy; + } + /** + * @return the createTime + */ + public Date getCreateTime() { + return createTime; + } + /** + * @param createTime the createTime to set + */ + public void setCreateTime(Date createTime) { + this.createTime = createTime; + } + /** + * @return the updateTime + */ + public Date getUpdateTime() { + return updateTime; + } + /** + * @param updateTime the updateTime to set + */ + public void setUpdateTime(Date updateTime) { + this.updateTime = updateTime; + } + /** + * @return the version + */ + public Long getVersion() { + return version; + } + /** + * @param version the version to set + */ + public void setVersion(Long version) { + this.version = version; + } + + @Override + public String toString( ) { + StringBuilder sb = new StringBuilder(); + + toString(sb); + + return sb.toString(); + } + + public StringBuilder toString(StringBuilder sb) { + sb.append("id={").append(id).append("} "); + sb.append("guid={").append(guid).append("} "); + sb.append("isEnabled={").append(isEnabled).append("} "); + sb.append("createdBy={").append(createdBy).append("} "); + sb.append("updatedBy={").append(updatedBy).append("} "); + sb.append("createTime={").append(createTime).append("} "); + sb.append("updateTime={").append(updateTime).append("} "); + sb.append("version={").append(version).append("} "); + + return sb; + } +} diff --git a/auth-common/src/main/java/org/apache/atlas/plugin/model/RangerPolicy.java b/auth-common/src/main/java/org/apache/atlas/plugin/model/RangerPolicy.java new file mode 100644 index 0000000000..fe11b16776 --- /dev/null +++ b/auth-common/src/main/java/org/apache/atlas/plugin/model/RangerPolicy.java @@ -0,0 +1,1734 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.apache.atlas.plugin.model; + +import org.apache.commons.collections.CollectionUtils; +import org.apache.htrace.shaded.fasterxml.jackson.annotation.JsonIgnoreProperties; +import org.apache.htrace.shaded.fasterxml.jackson.annotation.JsonInclude; + +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.XmlRootElement; +import java.util.ArrayList; +import java.util.Comparator; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +@JsonIgnoreProperties(ignoreUnknown = true) +@JsonInclude(JsonInclude.Include.NON_NULL) +@XmlRootElement +@XmlAccessorType(XmlAccessType.FIELD) +public class RangerPolicy extends RangerBaseModelObject implements java.io.Serializable { + public static final String POLICY_TYPE_ACCESS = "ACCESS"; + public static final String POLICY_TYPE_DATAMASK = "DATA_MASK"; + public static final String POLICY_TYPE_ROWFILTER = "ROW_FILTER"; + public static final String POLICY_TYPE_AUDIT = "AUDIT"; + + public static final String[] POLICY_TYPES = new String[] { + POLICY_TYPE_ACCESS, + POLICY_TYPE_DATAMASK, + POLICY_TYPE_ROWFILTER + }; + + public static final String MASK_TYPE_NULL = "MASK_NULL"; + public static final String MASK_TYPE_NONE = "MASK_NONE"; + public static final String MASK_TYPE_CUSTOM = "CUSTOM"; + + public static final int POLICY_PRIORITY_NORMAL = 0; + public static final int POLICY_PRIORITY_OVERRIDE = 1; + + public static final String POLICY_PRIORITY_NAME_NORMAL = "NORMAL"; + public static final String POLICY_PRIORITY_NAME_OVERRIDE = "OVERRIDE"; + + public static final Comparator POLICY_ID_COMPARATOR = new PolicyIdComparator(); + + // For future use + private static final long serialVersionUID = 1L; + + private String service; + private String name; + private String policyType; + private Integer policyPriority; + private String description; + private String resourceSignature; + private Boolean isAuditEnabled; + private Map resources; + private List conditions; + private List policyItems; + private List denyPolicyItems; + private List allowExceptions; + private List denyExceptions; + private List dataMaskPolicyItems; + private List rowFilterPolicyItems; + private String serviceType; + private Map options; + private List validitySchedules; + private List policyLabels; + private String zoneName; + private Boolean isDenyAllElse; + private Map attributes; + private String policyFilterCriteria; + private String policyResourceCategory; + + public RangerPolicy() { + this(null, null, null, null, null, null, null, null, null, null, null); + } + + public RangerPolicy(String service, String name, String policyType, Integer policyPriority, String description, Map resources, List policyItems, String resourceSignature, Map options, List validitySchedules, List policyLables) { + this(service, name, policyType, policyPriority, description, resources, policyItems, resourceSignature, options, validitySchedules, policyLables, null); + } + + public RangerPolicy(String service, String name, String policyType, Integer policyPriority, String description, Map resources, List policyItems, String resourceSignature, Map options, List validitySchedules, List policyLables, String zoneName) { + this(service, name, policyType, policyPriority, description, resources, policyItems, resourceSignature, options, validitySchedules, policyLables, zoneName, null); + } + + public RangerPolicy(String service, String name, String policyType, Integer policyPriority, String description, Map resources, List policyItems, String resourceSignature, Map options, List validitySchedules, List policyLables, String zoneName, List conditions) { + this(service, name, policyType, policyPriority, description, resources, policyItems, resourceSignature, options, validitySchedules, policyLables, zoneName, conditions, null); + } + + public RangerPolicy(String service, String name, String policyType, Integer policyPriority, String description, Map resources, List policyItems, String resourceSignature, Map options, List validitySchedules, List policyLables, String zoneName, List conditions, Boolean isDenyAllElse) { + this(service, name, policyType, policyPriority, description, resources, policyItems, resourceSignature, options, validitySchedules, policyLables, zoneName, conditions, null, null, null); + } + + /** + * @param service + * @param name + * @param policyType + * @param description + * @param resources + * @param policyItems + * @param resourceSignature TODO + */ + public RangerPolicy(String service, String name, String policyType, Integer policyPriority, String description, Map resources, List policyItems, String resourceSignature, Map options, List validitySchedules, List policyLables, String zoneName, List conditions, Boolean isDenyAllElse, String policyFilterCriteria, String policyResourceCategory) { + super(); + + setService(service); + setName(name); + setPolicyType(policyType); + setPolicyPriority(policyPriority); + setDescription(description); + setResourceSignature(resourceSignature); + setIsAuditEnabled(null); + setResources(resources); + setPolicyItems(policyItems); + setDenyPolicyItems(null); + setAllowExceptions(null); + setDenyExceptions(null); + setDataMaskPolicyItems(null); + setRowFilterPolicyItems(null); + setOptions(options); + setValiditySchedules(validitySchedules); + setPolicyLabels(policyLables); + setZoneName(zoneName); + setConditions(conditions); + setIsDenyAllElse(isDenyAllElse); + setPolicyFilterCriteria(null); + setPolicyResourceCategory(null); + + } + + /** + * @param other + */ + public void updateFrom(RangerPolicy other) { + super.updateFrom(other); + + setService(other.getService()); + setName(other.getName()); + setPolicyType(other.getPolicyType()); + setPolicyPriority(other.getPolicyPriority()); + setDescription(other.getDescription()); + setResourceSignature(other.getResourceSignature()); + setIsAuditEnabled(other.getIsAuditEnabled()); + setResources(other.getResources()); + setConditions(other.getConditions()); + setPolicyItems(other.getPolicyItems()); + setDenyPolicyItems(other.getDenyPolicyItems()); + setAllowExceptions(other.getAllowExceptions()); + setDenyExceptions(other.getDenyExceptions()); + setDataMaskPolicyItems(other.getDataMaskPolicyItems()); + setRowFilterPolicyItems(other.getRowFilterPolicyItems()); + setServiceType(other.getServiceType()); + setOptions(other.getOptions()); + setValiditySchedules(other.getValiditySchedules()); + setPolicyLabels(other.getPolicyLabels()); + setZoneName(other.getZoneName()); + setIsDenyAllElse(other.getIsDenyAllElse()); + setPolicyFilterCriteria(other.getPolicyFilterCriteria()); + setPolicyResourceCategory(other.getPolicyResourceCategory()); + } + + public Map getAttributes() { + return attributes; + } + + public void setAttributes(Map attributes) { + this.attributes = attributes; + } + + /** + * @return the type + */ + public String getService() { + return service; + } + + /** + * @param service the type to set + */ + public void setService(String service) { + this.service = service; + } + + /** + * @return the name + */ + public String getName() { + return name; + } + + /** + * @param name the name to set + */ + public void setName(String name) { + this.name = name; + } + + /** + * @return the policyType + */ + public String getPolicyType() { + return policyType; + } + + /** + * @param policyType the policyType to set + */ + public void setPolicyType(String policyType) { + this.policyType = policyType; + } + + /** + * @return the policyPriority + */ + public Integer getPolicyPriority() { + return policyPriority; + } + + /** + * @param policyPriority the policyPriority to set + */ + public void setPolicyPriority(Integer policyPriority) { + this.policyPriority = policyPriority == null ? RangerPolicy.POLICY_PRIORITY_NORMAL : policyPriority; + } + + /** + * @return the description + */ + public String getDescription() { + return description; + } + + /** + * @param description the description to set + */ + public void setDescription(String description) { + this.description = description; + } + + /** + * @return the resourceSignature + */ + public String getResourceSignature() { + return resourceSignature; + } + + /** + * @param resourceSignature the resourceSignature to set + */ + public void setResourceSignature(String resourceSignature) { + this.resourceSignature = resourceSignature; + } + + /** + * @return the isAuditEnabled + */ + public Boolean getIsAuditEnabled() { + return isAuditEnabled; + } + + /** + * @param isAuditEnabled the isEnabled to set + */ + public void setIsAuditEnabled(Boolean isAuditEnabled) { + this.isAuditEnabled = isAuditEnabled == null ? Boolean.TRUE : isAuditEnabled; + } + + public String getServiceType() { + return serviceType; + } + + public void setServiceType(String serviceType) { + this.serviceType = serviceType; + } + + public List getPolicyLabels() { + return policyLabels; + } + + public void setPolicyLabels(List policyLabels) { + if (this.policyLabels == null) { + this.policyLabels = new ArrayList<>(); + } + + if (this.policyLabels == policyLabels) { + return; + } + + this.policyLabels.clear(); + + if (policyLabels != null) { + this.policyLabels.addAll(policyLabels); + } + } + + /** + * @return the resources + */ + public Map getResources() { + return resources; + } + + /** + * @param resources the resources to set + */ + public void setResources(Map resources) { + if(this.resources == null) { + this.resources = new HashMap<>(); + } + + if(this.resources == resources) { + return; + } + + this.resources.clear(); + + if(resources != null) { + for(Map.Entry e : resources.entrySet()) { + this.resources.put(e.getKey(), e.getValue()); + } + } + } + + /** + * @return the policyItems + */ + public List getPolicyItems() { + return policyItems; + } + + /** + * @param policyItems the policyItems to set + */ + public void setPolicyItems(List policyItems) { + if(this.policyItems == null) { + this.policyItems = new ArrayList<>(); + } + + if(this.policyItems == policyItems) { + return; + } + + this.policyItems.clear(); + + if(policyItems != null) { + this.policyItems.addAll(policyItems); + } + } + + /** + * @return the denyPolicyItems + */ + public List getDenyPolicyItems() { + return denyPolicyItems; + } + + /** + * @param denyPolicyItems the denyPolicyItems to set + */ + public void setDenyPolicyItems(List denyPolicyItems) { + if(this.denyPolicyItems == null) { + this.denyPolicyItems = new ArrayList<>(); + } + + if(this.denyPolicyItems == denyPolicyItems) { + return; + } + + this.denyPolicyItems.clear(); + + if(denyPolicyItems != null) { + this.denyPolicyItems.addAll(denyPolicyItems); + } + } + + /** + * @return the allowExceptions + */ + public List getAllowExceptions() { + return allowExceptions; + } + + /** + * @param allowExceptions the allowExceptions to set + */ + public void setAllowExceptions(List allowExceptions) { + if(this.allowExceptions == null) { + this.allowExceptions = new ArrayList<>(); + } + + if(this.allowExceptions == allowExceptions) { + return; + } + + this.allowExceptions.clear(); + + if(allowExceptions != null) { + this.allowExceptions.addAll(allowExceptions); + } + } + + /** + * @return the denyExceptions + */ + public List getDenyExceptions() { + return denyExceptions; + } + + /** + * @param denyExceptions the denyExceptions to set + */ + public void setDenyExceptions(List denyExceptions) { + if(this.denyExceptions == null) { + this.denyExceptions = new ArrayList<>(); + } + + if(this.denyExceptions == denyExceptions) { + return; + } + + this.denyExceptions.clear(); + + if(denyExceptions != null) { + this.denyExceptions.addAll(denyExceptions); + } + } + + public List getDataMaskPolicyItems() { + return dataMaskPolicyItems; + } + + public void setDataMaskPolicyItems(List dataMaskPolicyItems) { + if(this.dataMaskPolicyItems == null) { + this.dataMaskPolicyItems = new ArrayList<>(); + } + + if(this.dataMaskPolicyItems == dataMaskPolicyItems) { + return; + } + + this.dataMaskPolicyItems.clear(); + + if(dataMaskPolicyItems != null) { + this.dataMaskPolicyItems.addAll(dataMaskPolicyItems); + } + } + + public List getRowFilterPolicyItems() { + return rowFilterPolicyItems; + } + + public void setRowFilterPolicyItems(List rowFilterPolicyItems) { + if(this.rowFilterPolicyItems == null) { + this.rowFilterPolicyItems = new ArrayList<>(); + } + + if(this.rowFilterPolicyItems == rowFilterPolicyItems) { + return; + } + + this.rowFilterPolicyItems.clear(); + + if(rowFilterPolicyItems != null) { + this.rowFilterPolicyItems.addAll(rowFilterPolicyItems); + } + } + + public Map getOptions() { return options; } + + public void setOptions(Map options) { + if (this.options == null) { + this.options = new HashMap<>(); + } + if (this.options == options) { + return; + } + this.options.clear(); + + if(options != null) { + for(Map.Entry e : options.entrySet()) { + this.options.put(e.getKey(), e.getValue()); + } + } + } + + public List getValiditySchedules() { return validitySchedules; } + + public void setValiditySchedules(List validitySchedules) { + if (this.validitySchedules == null) { + this.validitySchedules = new ArrayList<>(); + } + if (this.validitySchedules == validitySchedules) { + return; + } + this.validitySchedules.clear(); + + if(validitySchedules != null) { + this.validitySchedules.addAll(validitySchedules); + } + } + public String getZoneName() { return zoneName; } + + public void setZoneName(String zoneName) { + this.zoneName = zoneName; + } + + /** + * @return the conditions + */ + public List getConditions() { return conditions; } + /** + * @param conditions the conditions to set + */ + public void setConditions(List conditions) { + this.conditions = conditions; + } + + public Boolean getIsDenyAllElse() { + return isDenyAllElse; + } + + public void setIsDenyAllElse(Boolean isDenyAllElse) { + this.isDenyAllElse = isDenyAllElse == null ? Boolean.FALSE : isDenyAllElse; + } + + public String getPolicyFilterCriteria() { + return policyFilterCriteria; + } + + public void setPolicyFilterCriteria(String policyFilterCriteria) { + this.policyFilterCriteria = policyFilterCriteria; + } + + public String getPolicyResourceCategory() { + return policyResourceCategory; + } + + public void setPolicyResourceCategory(String policyResourceCategory) { + this.policyResourceCategory = policyResourceCategory; + } + + @Override + public String toString( ) { + StringBuilder sb = new StringBuilder(); + + toString(sb); + + return sb.toString(); + } + + public StringBuilder toString(StringBuilder sb) { + sb.append("RangerPolicy={"); + + super.toString(sb); + + sb.append("service={").append(service).append("} "); + sb.append("name={").append(name).append("} "); + sb.append("policyType={").append(policyType).append("} "); + sb.append("policyPriority={").append(policyPriority).append("} "); + sb.append("description={").append(description).append("} "); + sb.append("resourceSignature={").append(resourceSignature).append("} "); + sb.append("isAuditEnabled={").append(isAuditEnabled).append("} "); + sb.append("serviceType={").append(serviceType).append("} "); + + sb.append("resources={"); + if(resources != null) { + for(Map.Entry e : resources.entrySet()) { + sb.append(e.getKey()).append("={"); + e.getValue().toString(sb); + sb.append("} "); + } + } + sb.append("} "); + sb.append("policyLabels={"); + if(policyLabels != null) { + for(String policyLabel : policyLabels) { + if(policyLabel != null) { + sb.append(policyLabel).append(" "); + } + } + } + sb.append("} "); + + sb.append("policyConditions={"); + if(conditions != null) { + for(RangerPolicyItemCondition condition : conditions) { + if(condition != null) { + condition.toString(sb); + } + } + } + sb.append("} "); + + sb.append("policyItems={"); + if(policyItems != null) { + for(RangerPolicyItem policyItem : policyItems) { + if(policyItem != null) { + policyItem.toString(sb); + } + } + } + sb.append("} "); + + sb.append("denyPolicyItems={"); + if(denyPolicyItems != null) { + for(RangerPolicyItem policyItem : denyPolicyItems) { + if(policyItem != null) { + policyItem.toString(sb); + } + } + } + sb.append("} "); + + sb.append("allowExceptions={"); + if(allowExceptions != null) { + for(RangerPolicyItem policyItem : allowExceptions) { + if(policyItem != null) { + policyItem.toString(sb); + } + } + } + sb.append("} "); + + sb.append("denyExceptions={"); + if(denyExceptions != null) { + for(RangerPolicyItem policyItem : denyExceptions) { + if(policyItem != null) { + policyItem.toString(sb); + } + } + } + sb.append("} "); + + sb.append("dataMaskPolicyItems={"); + if(dataMaskPolicyItems != null) { + for(RangerDataMaskPolicyItem dataMaskPolicyItem : dataMaskPolicyItems) { + if(dataMaskPolicyItem != null) { + dataMaskPolicyItem.toString(sb); + } + } + } + sb.append("} "); + + sb.append("rowFilterPolicyItems={"); + if(rowFilterPolicyItems != null) { + for(RangerRowFilterPolicyItem rowFilterPolicyItem : rowFilterPolicyItems) { + if(rowFilterPolicyItem != null) { + rowFilterPolicyItem.toString(sb); + } + } + } + sb.append("} "); + + sb.append("options={"); + if(options != null) { + for(Map.Entry e : options.entrySet()) { + sb.append(e.getKey()).append("={"); + sb.append(e.getValue().toString()); + sb.append("} "); + } + } + sb.append("} "); + + //sb.append("validitySchedules={").append(validitySchedules).append("} "); + sb.append("validitySchedules={"); + if (CollectionUtils.isNotEmpty(validitySchedules)) { + for (RangerValiditySchedule schedule : validitySchedules) { + if (schedule != null) { + sb.append("schedule={").append(schedule).append("}"); + } + } + } + sb.append(", zoneName=").append(zoneName); + + sb.append(", policyFilterCriteria=").append(policyFilterCriteria); + + sb.append(", policyResourceCategory=").append(policyResourceCategory); + + sb.append(", isDenyAllElse={").append(isDenyAllElse).append("} "); + + sb.append("}"); + + sb.append("}"); + + return sb; + } + + static class PolicyIdComparator implements Comparator, java.io.Serializable { + @Override + public int compare(RangerPolicy me, RangerPolicy other) { + return Long.compare(me.getId(), other.getId()); + } + } + + @JsonInclude(JsonInclude.Include.NON_NULL) + @XmlRootElement + @XmlAccessorType(XmlAccessType.FIELD) + public static class RangerPolicyResource implements java.io.Serializable { + private static final long serialVersionUID = 1L; + + private List values; + private Boolean isExcludes; + private Boolean isRecursive; + + public RangerPolicyResource() { + this((List)null, null, null); + } + + public RangerPolicyResource(String value) { + setValue(value); + setIsExcludes(null); + setIsRecursive(null); + } + + public RangerPolicyResource(String value, Boolean isExcludes, Boolean isRecursive) { + setValue(value); + setIsExcludes(isExcludes); + setIsRecursive(isRecursive); + } + + public RangerPolicyResource(List values, Boolean isExcludes, Boolean isRecursive) { + setValues(values); + setIsExcludes(isExcludes); + setIsRecursive(isRecursive); + } + + /** + * @return the values + */ + public List getValues() { + return values; + } + + /** + * @param values the values to set + */ + public void setValues(List values) { + if(this.values == null) { + this.values = new ArrayList<>(); + } + + if(this.values == values) { + return; + } + + this.values.clear(); + + if(values != null) { + this.values.addAll(values); + } + } + + /** + * @param value the value to set + */ + public void setValue(String value) { + if(this.values == null) { + this.values = new ArrayList<>(); + } + + this.values.clear(); + + this.values.add(value); + } + + /** + * @return the isExcludes + */ + public Boolean getIsExcludes() { + return isExcludes; + } + + /** + * @param isExcludes the isExcludes to set + */ + public void setIsExcludes(Boolean isExcludes) { + this.isExcludes = isExcludes == null ? Boolean.FALSE : isExcludes; + } + + /** + * @return the isRecursive + */ + public Boolean getIsRecursive() { + return isRecursive; + } + + /** + * @param isRecursive the isRecursive to set + */ + public void setIsRecursive(Boolean isRecursive) { + this.isRecursive = isRecursive == null ? Boolean.FALSE : isRecursive; + } + + @Override + public String toString( ) { + StringBuilder sb = new StringBuilder(); + + toString(sb); + + return sb.toString(); + } + + public StringBuilder toString(StringBuilder sb) { + sb.append("RangerPolicyResource={"); + sb.append("values={"); + if(values != null) { + for(String value : values) { + sb.append(value).append(" "); + } + } + sb.append("} "); + sb.append("isExcludes={").append(isExcludes).append("} "); + sb.append("isRecursive={").append(isRecursive).append("} "); + sb.append("}"); + + return sb; + } + + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + + ((isExcludes == null) ? 0 : isExcludes.hashCode()); + result = prime * result + + ((isRecursive == null) ? 0 : isRecursive.hashCode()); + result = prime * result + + ((values == null) ? 0 : values.hashCode()); + return result; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) + return true; + if (obj == null) + return false; + if (getClass() != obj.getClass()) + return false; + RangerPolicyResource other = (RangerPolicyResource) obj; + if (isExcludes == null) { + if (other.isExcludes != null) + return false; + } else if (!isExcludes.equals(other.isExcludes)) + return false; + if (isRecursive == null) { + if (other.isRecursive != null) + return false; + } else if (!isRecursive.equals(other.isRecursive)) + return false; + if (values == null) { + if (other.values != null) + return false; + } else if (!values.equals(other.values)) + return false; + return true; + } + + } + + @JsonInclude(JsonInclude.Include.NON_NULL) + @XmlRootElement + @XmlAccessorType(XmlAccessType.FIELD) + public static class RangerPolicyItem implements java.io.Serializable { + private static final long serialVersionUID = 1L; + + private List accesses; + private List users; + private List groups; + private List roles; + private List conditions; + private Boolean delegateAdmin; + + public RangerPolicyItem() { + this(null, null, null, null, null, null); + } + + public RangerPolicyItem(List accessTypes, List users, List groups, List roles, List conditions, Boolean delegateAdmin) { + setAccesses(accessTypes); + setUsers(users); + setGroups(groups); + setRoles(roles); + setConditions(conditions); + setDelegateAdmin(delegateAdmin); + } + + /** + * @return the accesses + */ + public List getAccesses() { + return accesses; + } + /** + * @param accesses the accesses to set + */ + public void setAccesses(List accesses) { + if(this.accesses == null) { + this.accesses = new ArrayList<>(); + } + + if(this.accesses == accesses) { + return; + } + + this.accesses.clear(); + + if(accesses != null) { + this.accesses.addAll(accesses); + } + } + /** + * @return the users + */ + public List getUsers() { + return users; + } + /** + * @param users the users to set + */ + public void setUsers(List users) { + if(this.users == null) { + this.users = new ArrayList<>(); + } + + if(this.users == users) { + return; + } + + this.users.clear(); + + if(users != null) { + this.users.addAll(users); + } + } + /** + * @return the groups + */ + public List getGroups() { + return groups; + } + /** + * @param groups the groups to set + */ + public void setGroups(List groups) { + if(this.groups == null) { + this.groups = new ArrayList<>(); + } + + if(this.groups == groups) { + return; + } + + this.groups.clear(); + + if(groups != null) { + this.groups.addAll(groups); + } + } + /** + * @return the roles + */ + public List getRoles() { + return roles; + } + /** + * @param roles the roles to set + */ + public void setRoles(List roles) { + if(this.roles == null) { + this.roles = new ArrayList<>(); + } + + if(this.roles == roles) { + return; + } + + this.roles.clear(); + + if(roles != null) { + this.roles.addAll(roles); + } + } + /** + * @return the conditions + */ + public List getConditions() { + return conditions; + } + /** + * @param conditions the conditions to set + */ + public void setConditions(List conditions) { + if(this.conditions == null) { + this.conditions = new ArrayList<>(); + } + + if(this.conditions == conditions) { + return; + } + + this.conditions.clear(); + + if(conditions != null) { + this.conditions.addAll(conditions); + } + } + + /** + * @return the delegateAdmin + */ + public Boolean getDelegateAdmin() { + return delegateAdmin; + } + + /** + * @param delegateAdmin the delegateAdmin to set + */ + public void setDelegateAdmin(Boolean delegateAdmin) { + this.delegateAdmin = delegateAdmin == null ? Boolean.FALSE : delegateAdmin; + } + + @Override + public String toString( ) { + StringBuilder sb = new StringBuilder(); + + toString(sb); + + return sb.toString(); + } + + public StringBuilder toString(StringBuilder sb) { + sb.append("RangerPolicyItem={"); + + sb.append("accessTypes={"); + if(accesses != null) { + for(RangerPolicyItemAccess access : accesses) { + if(access != null) { + access.toString(sb); + } + } + } + sb.append("} "); + + sb.append("users={"); + if(users != null) { + for(String user : users) { + if(user != null) { + sb.append(user).append(" "); + } + } + } + sb.append("} "); + + sb.append("groups={"); + if(groups != null) { + for(String group : groups) { + if(group != null) { + sb.append(group).append(" "); + } + } + } + sb.append("} "); + + sb.append("roles={"); + if(roles != null) { + for(String role : roles) { + if(role != null) { + sb.append(role).append(" "); + } + } + } + sb.append("} "); + + sb.append("conditions={"); + if(conditions != null) { + for(RangerPolicyItemCondition condition : conditions) { + if(condition != null) { + condition.toString(sb); + } + } + } + sb.append("} "); + + sb.append("delegateAdmin={").append(delegateAdmin).append("} "); + sb.append("}"); + + return sb; + } + + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + + ((accesses == null) ? 0 : accesses.hashCode()); + result = prime * result + + ((conditions == null) ? 0 : conditions.hashCode()); + result = prime * result + + ((delegateAdmin == null) ? 0 : delegateAdmin.hashCode()); + result = prime * result + + ((roles == null) ? 0 : roles.hashCode()); + result = prime * result + + ((groups == null) ? 0 : groups.hashCode()); + result = prime * result + ((users == null) ? 0 : users.hashCode()); + return result; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) + return true; + if (obj == null) + return false; + if (getClass() != obj.getClass()) + return false; + RangerPolicyItem other = (RangerPolicyItem) obj; + if (accesses == null) { + if (other.accesses != null) + return false; + } else if (!accesses.equals(other.accesses)) + return false; + if (conditions == null) { + if (other.conditions != null) + return false; + } else if (!conditions.equals(other.conditions)) + return false; + if (delegateAdmin == null) { + if (other.delegateAdmin != null) + return false; + } else if (!delegateAdmin.equals(other.delegateAdmin)) + return false; + if (roles == null) { + if (other.roles != null) + return false; + } else if (!roles.equals(other.roles)) + return false; + if (groups == null) { + if (other.groups != null) + return false; + } else if (!groups.equals(other.groups)) + return false; + if (users == null) { + if (other.users != null) + return false; + } else if (!users.equals(other.users)) + return false; + return true; + + } + } + + @JsonInclude(JsonInclude.Include.NON_NULL) + @XmlRootElement + @XmlAccessorType(XmlAccessType.FIELD) + public static class RangerDataMaskPolicyItem extends RangerPolicyItem implements java.io.Serializable { + private static final long serialVersionUID = 1L; + + private RangerPolicyItemDataMaskInfo dataMaskInfo; + + public RangerDataMaskPolicyItem() { + this(null, null, null, null, null, null, null); + } + + public RangerDataMaskPolicyItem(List accesses, RangerPolicyItemDataMaskInfo dataMaskDetail, List users, List groups, List roles, List conditions, Boolean delegateAdmin) { + super(accesses, users, groups, roles, conditions, delegateAdmin); + + setDataMaskInfo(dataMaskDetail); + } + + /** + * @return the dataMaskInfo + */ + public RangerPolicyItemDataMaskInfo getDataMaskInfo() { + return dataMaskInfo; + } + + /** + * @param dataMaskInfo the dataMaskInfo to set + */ + public void setDataMaskInfo(RangerPolicyItemDataMaskInfo dataMaskInfo) { + this.dataMaskInfo = dataMaskInfo == null ? new RangerPolicyItemDataMaskInfo() : dataMaskInfo; + } + + @Override + public int hashCode() { + final int prime = 31; + int result = super.hashCode(); + result = prime * result + ((dataMaskInfo == null) ? 0 : dataMaskInfo.hashCode()); + return result; + } + + @Override + public boolean equals(Object obj) { + if(! super.equals(obj)) + return false; + if (this == obj) + return true; + if (obj == null) + return false; + if (getClass() != obj.getClass()) + return false; + RangerDataMaskPolicyItem other = (RangerDataMaskPolicyItem) obj; + if (dataMaskInfo == null) { + if (other.dataMaskInfo != null) + return false; + } else if (!dataMaskInfo.equals(other.dataMaskInfo)) + return false; + return true; + } + + @Override + public String toString( ) { + StringBuilder sb = new StringBuilder(); + + toString(sb); + + return sb.toString(); + } + + public StringBuilder toString(StringBuilder sb) { + sb.append("RangerDataMaskPolicyItem={"); + + super.toString(sb); + + sb.append("dataMaskInfo={"); + if(dataMaskInfo != null) { + dataMaskInfo.toString(sb); + } + sb.append("} "); + + sb.append("}"); + + return sb; + } + } + + @JsonInclude(JsonInclude.Include.NON_NULL) + @XmlRootElement + @XmlAccessorType(XmlAccessType.FIELD) + public static class RangerRowFilterPolicyItem extends RangerPolicyItem implements java.io.Serializable { + private static final long serialVersionUID = 1L; + + private RangerPolicyItemRowFilterInfo rowFilterInfo; + + public RangerRowFilterPolicyItem() { + this(null, null, null, null, null, null, null); + } + + public RangerRowFilterPolicyItem(RangerPolicyItemRowFilterInfo rowFilterInfo, List accesses, List users, List groups, List roles, List conditions, Boolean delegateAdmin) { + super(accesses, users, groups, roles, conditions, delegateAdmin); + + setRowFilterInfo(rowFilterInfo); + } + + /** + * @return the rowFilterInfo + */ + public RangerPolicyItemRowFilterInfo getRowFilterInfo() { + return rowFilterInfo; + } + + /** + * @param rowFilterInfo the rowFilterInfo to set + */ + public void setRowFilterInfo(RangerPolicyItemRowFilterInfo rowFilterInfo) { + this.rowFilterInfo = rowFilterInfo == null ? new RangerPolicyItemRowFilterInfo() : rowFilterInfo; + } + + @Override + public int hashCode() { + final int prime = 31; + int result = super.hashCode(); + result = prime * result + ((rowFilterInfo == null) ? 0 : rowFilterInfo.hashCode()); + return result; + } + + @Override + public boolean equals(Object obj) { + if(! super.equals(obj)) + return false; + if (this == obj) + return true; + if (obj == null) + return false; + if (getClass() != obj.getClass()) + return false; + RangerRowFilterPolicyItem other = (RangerRowFilterPolicyItem) obj; + if (rowFilterInfo == null) { + if (other.rowFilterInfo != null) + return false; + } else if (!rowFilterInfo.equals(other.rowFilterInfo)) + return false; + return true; + } + + @Override + public String toString( ) { + StringBuilder sb = new StringBuilder(); + + toString(sb); + + return sb.toString(); + } + + public StringBuilder toString(StringBuilder sb) { + sb.append("RangerRowFilterPolicyItem={"); + + super.toString(sb); + + sb.append("rowFilterInfo={"); + if(rowFilterInfo != null) { + rowFilterInfo.toString(sb); + } + sb.append("} "); + + sb.append("}"); + + return sb; + } + } + + @JsonInclude(JsonInclude.Include.NON_NULL) + @XmlRootElement + @XmlAccessorType(XmlAccessType.FIELD) + public static class RangerPolicyItemAccess implements java.io.Serializable { + private static final long serialVersionUID = 1L; + + private String type; + private Boolean isAllowed; + + public RangerPolicyItemAccess() { + this(null, null); + } + + public RangerPolicyItemAccess(String type) { + this(type, null); + } + + public RangerPolicyItemAccess(String type, Boolean isAllowed) { + setType(type); + setIsAllowed(isAllowed); + } + + /** + * @return the type + */ + public String getType() { + return type; + } + + /** + * @param type the type to set + */ + public void setType(String type) { + this.type = type; + } + + /** + * @return the isAllowed + */ + public Boolean getIsAllowed() { + return isAllowed; + } + + /** + * @param isAllowed the isAllowed to set + */ + public void setIsAllowed(Boolean isAllowed) { + this.isAllowed = isAllowed == null ? Boolean.TRUE : isAllowed; + } + + @Override + public String toString( ) { + StringBuilder sb = new StringBuilder(); + + toString(sb); + + return sb.toString(); + } + + public StringBuilder toString(StringBuilder sb) { + sb.append("RangerPolicyItemAccess={"); + sb.append("type={").append(type).append("} "); + sb.append("isAllowed={").append(isAllowed).append("} "); + sb.append("}"); + + return sb; + } + + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + + ((isAllowed == null) ? 0 : isAllowed.hashCode()); + result = prime * result + ((type == null) ? 0 : type.hashCode()); + return result; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) + return true; + if (obj == null) + return false; + if (getClass() != obj.getClass()) + return false; + RangerPolicyItemAccess other = (RangerPolicyItemAccess) obj; + if (isAllowed == null) { + if (other.isAllowed != null) + return false; + } else if (!isAllowed.equals(other.isAllowed)) + return false; + if (type == null) { + if (other.type != null) + return false; + } else if (!type.equals(other.type)) + return false; + return true; + } + + } + + @JsonInclude(JsonInclude.Include.NON_NULL) + @XmlRootElement + @XmlAccessorType(XmlAccessType.FIELD) + public static class RangerPolicyItemCondition implements java.io.Serializable { + private static final long serialVersionUID = 1L; + + private String type; + private List values; + + public RangerPolicyItemCondition() { + this(null, null); + } + + public RangerPolicyItemCondition(String type, List values) { + setType(type); + setValues(values); + } + + /** + * @return the type + */ + public String getType() { + return type; + } + + /** + * @param type the type to set + */ + public void setType(String type) { + this.type = type; + } + + /** + * @return the value + */ + public List getValues() { + return values; + } + + /** + * @param values the value to set + */ + public void setValues(List values) { + if (this.values == null) { + this.values = new ArrayList<>(); + } + + if(this.values == values) { + return; + } + + this.values.clear(); + + if(values != null) { + this.values.addAll(values); + } + } + + @Override + public String toString( ) { + StringBuilder sb = new StringBuilder(); + + toString(sb); + + return sb.toString(); + } + + public StringBuilder toString(StringBuilder sb) { + sb.append("RangerPolicyCondition={"); + sb.append("type={").append(type).append("} "); + sb.append("values={"); + if(values != null) { + for(String value : values) { + sb.append(value).append(" "); + } + } + sb.append("} "); + sb.append("}"); + + return sb; + } + + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + ((type == null) ? 0 : type.hashCode()); + result = prime * result + + ((values == null) ? 0 : values.hashCode()); + return result; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) + return true; + if (obj == null) + return false; + if (getClass() != obj.getClass()) + return false; + RangerPolicyItemCondition other = (RangerPolicyItemCondition) obj; + if (type == null) { + if (other.type != null) + return false; + } else if (!type.equals(other.type)) + return false; + if (values == null) { + if (other.values != null) + return false; + } else if (!values.equals(other.values)) + return false; + return true; + } + + } + + @JsonInclude(JsonInclude.Include.NON_NULL) + @XmlRootElement + @XmlAccessorType(XmlAccessType.FIELD) + public static class RangerPolicyItemDataMaskInfo implements java.io.Serializable { + private static final long serialVersionUID = 1L; + + private String dataMaskType; + private String conditionExpr; + private String valueExpr; + + public RangerPolicyItemDataMaskInfo() { } + + public RangerPolicyItemDataMaskInfo(String dataMaskType, String conditionExpr, String valueExpr) { + setDataMaskType(dataMaskType); + setConditionExpr(conditionExpr); + setValueExpr(valueExpr); + } + + public RangerPolicyItemDataMaskInfo(RangerPolicyItemDataMaskInfo that) { + this.dataMaskType = that.dataMaskType; + this.conditionExpr = that.conditionExpr; + this.valueExpr = that.valueExpr; + } + + public String getDataMaskType() { + return dataMaskType; + } + + public void setDataMaskType(String dataMaskType) { + this.dataMaskType = dataMaskType; + } + + public String getConditionExpr() { + return conditionExpr; + } + + public void setConditionExpr(String conditionExpr) { + this.conditionExpr = conditionExpr; + } + + public String getValueExpr() { + return valueExpr; + } + + public void setValueExpr(String valueExpr) { + this.valueExpr = valueExpr; + } + + @Override + public int hashCode() { + final int prime = 31; + int result = super.hashCode(); + result = prime * result + ((dataMaskType == null) ? 0 : dataMaskType.hashCode()); + result = prime * result + ((conditionExpr == null) ? 0 : conditionExpr.hashCode()); + result = prime * result + ((valueExpr == null) ? 0 : valueExpr.hashCode()); + return result; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) + return true; + if (obj == null) + return false; + if (getClass() != obj.getClass()) + return false; + RangerPolicyItemDataMaskInfo other = (RangerPolicyItemDataMaskInfo) obj; + if (dataMaskType == null) { + if (other.dataMaskType != null) + return false; + } else if (!dataMaskType.equals(other.dataMaskType)) + return false; + if (conditionExpr == null) { + if (other.conditionExpr != null) + return false; + } else if (!conditionExpr.equals(other.conditionExpr)) + return false; + if (valueExpr == null) { + if (other.valueExpr != null) + return false; + } else if (!valueExpr.equals(other.valueExpr)) + return false; + return true; + } + + @Override + public String toString( ) { + StringBuilder sb = new StringBuilder(); + + toString(sb); + + return sb.toString(); + } + + public StringBuilder toString(StringBuilder sb) { + sb.append("RangerPolicyItemDataMaskInfo={"); + + sb.append("dataMaskType={").append(dataMaskType).append("} "); + sb.append("conditionExpr={").append(conditionExpr).append("} "); + sb.append("valueExpr={").append(valueExpr).append("} "); + + sb.append("}"); + + return sb; + } + } + + @JsonInclude(JsonInclude.Include.NON_NULL) + @XmlRootElement + @XmlAccessorType(XmlAccessType.FIELD) + public static class RangerPolicyItemRowFilterInfo implements java.io.Serializable { + private static final long serialVersionUID = 1L; + + private String filterExpr; + + public RangerPolicyItemRowFilterInfo() { } + + public RangerPolicyItemRowFilterInfo(String filterExpr) { + setFilterExpr(filterExpr); + } + + public RangerPolicyItemRowFilterInfo(RangerPolicyItemRowFilterInfo that) { + this.filterExpr = that.filterExpr; + } + + public String getFilterExpr() { + return filterExpr; + } + + public void setFilterExpr(String filterExpr) { + this.filterExpr = filterExpr; + } + + @Override + public int hashCode() { + final int prime = 31; + int result = super.hashCode(); + result = prime * result + ((filterExpr == null) ? 0 : filterExpr.hashCode()); + return result; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) + return true; + if (obj == null) + return false; + if (getClass() != obj.getClass()) + return false; + RangerPolicyItemRowFilterInfo other = (RangerPolicyItemRowFilterInfo) obj; + if (filterExpr == null) { + if (other.filterExpr != null) + return false; + } else if (!filterExpr.equals(other.filterExpr)) + return false; + return true; + } + + @Override + public String toString( ) { + StringBuilder sb = new StringBuilder(); + + toString(sb); + + return sb.toString(); + } + + public StringBuilder toString(StringBuilder sb) { + sb.append("RangerPolicyItemRowFilterInfo={"); + + sb.append("filterExpr={").append(filterExpr).append("} "); + + sb.append("}"); + + return sb; + } + } +} diff --git a/auth-agents-common/src/main/java/org/apache/atlas/plugin/model/RangerRole.java b/auth-common/src/main/java/org/apache/atlas/plugin/model/RangerRole.java similarity index 100% rename from auth-agents-common/src/main/java/org/apache/atlas/plugin/model/RangerRole.java rename to auth-common/src/main/java/org/apache/atlas/plugin/model/RangerRole.java diff --git a/auth-agents-common/src/main/java/org/apache/atlas/plugin/model/RangerServiceDef.java b/auth-common/src/main/java/org/apache/atlas/plugin/model/RangerServiceDef.java similarity index 99% rename from auth-agents-common/src/main/java/org/apache/atlas/plugin/model/RangerServiceDef.java rename to auth-common/src/main/java/org/apache/atlas/plugin/model/RangerServiceDef.java index 4c5d8988d0..73429c74bd 100644 --- a/auth-agents-common/src/main/java/org/apache/atlas/plugin/model/RangerServiceDef.java +++ b/auth-common/src/main/java/org/apache/atlas/plugin/model/RangerServiceDef.java @@ -19,6 +19,7 @@ package org.apache.atlas.plugin.model; +import org.apache.htrace.shaded.fasterxml.jackson.annotation.JsonIgnoreProperties; import org.apache.htrace.shaded.fasterxml.jackson.annotation.JsonInclude; import javax.xml.bind.annotation.XmlAccessType; @@ -99,10 +100,10 @@ public RangerServiceDef(String name, String implClass, String label, String desc } public RangerServiceDef(String name, String displayName, String implClass, String label, String description, - Map options, List configs, - List modifiedResourceDefs, List accessTypes, - List policyConditions, List contextEnrichers, - List enums) { + Map options, List configs, + List modifiedResourceDefs, List accessTypes, + List policyConditions, List contextEnrichers, + List enums) { this(name, implClass, label, description, options, configs, modifiedResourceDefs, accessTypes, policyConditions, contextEnrichers, enums); this.setDisplayName(displayName); } diff --git a/auth-agents-common/src/main/java/org/apache/atlas/plugin/model/RangerValidityRecurrence.java b/auth-common/src/main/java/org/apache/atlas/plugin/model/RangerValidityRecurrence.java similarity index 100% rename from auth-agents-common/src/main/java/org/apache/atlas/plugin/model/RangerValidityRecurrence.java rename to auth-common/src/main/java/org/apache/atlas/plugin/model/RangerValidityRecurrence.java diff --git a/auth-agents-common/src/main/java/org/apache/atlas/plugin/model/RangerValiditySchedule.java b/auth-common/src/main/java/org/apache/atlas/plugin/model/RangerValiditySchedule.java similarity index 90% rename from auth-agents-common/src/main/java/org/apache/atlas/plugin/model/RangerValiditySchedule.java rename to auth-common/src/main/java/org/apache/atlas/plugin/model/RangerValiditySchedule.java index 3bb3f078b5..f166598e28 100644 --- a/auth-agents-common/src/main/java/org/apache/atlas/plugin/model/RangerValiditySchedule.java +++ b/auth-common/src/main/java/org/apache/atlas/plugin/model/RangerValiditySchedule.java @@ -19,11 +19,9 @@ package org.apache.atlas.plugin.model; - -import org.codehaus.jackson.annotate.JsonAutoDetect; -import org.codehaus.jackson.annotate.JsonAutoDetect.Visibility; -import org.codehaus.jackson.annotate.JsonIgnoreProperties; -import org.codehaus.jackson.map.annotate.JsonSerialize; +import org.apache.htrace.shaded.fasterxml.jackson.annotation.JsonAutoDetect; +import org.apache.htrace.shaded.fasterxml.jackson.annotation.JsonIgnoreProperties; +import org.apache.htrace.shaded.fasterxml.jackson.databind.annotation.JsonSerialize; import javax.xml.bind.annotation.XmlAccessType; import javax.xml.bind.annotation.XmlAccessorType; @@ -33,7 +31,7 @@ import java.util.Arrays; import java.util.List; -@JsonAutoDetect(fieldVisibility=Visibility.ANY) +@JsonAutoDetect(fieldVisibility= JsonAutoDetect.Visibility.ANY) @JsonSerialize(include=JsonSerialize.Inclusion.NON_NULL) @JsonIgnoreProperties(ignoreUnknown=true) @XmlRootElement diff --git a/auth-agents-common/src/main/java/org/apache/atlas/plugin/model/UserInfo.java b/auth-common/src/main/java/org/apache/atlas/plugin/model/UserInfo.java similarity index 100% rename from auth-agents-common/src/main/java/org/apache/atlas/plugin/model/UserInfo.java rename to auth-common/src/main/java/org/apache/atlas/plugin/model/UserInfo.java diff --git a/auth-agents-common/src/main/java/org/apache/atlas/plugin/util/RangerRoles.java b/auth-common/src/main/java/org/apache/atlas/plugin/util/RangerRoles.java similarity index 100% rename from auth-agents-common/src/main/java/org/apache/atlas/plugin/util/RangerRoles.java rename to auth-common/src/main/java/org/apache/atlas/plugin/util/RangerRoles.java diff --git a/auth-agents-common/src/main/java/org/apache/atlas/plugin/util/RangerUserStore.java b/auth-common/src/main/java/org/apache/atlas/plugin/util/RangerUserStore.java similarity index 99% rename from auth-agents-common/src/main/java/org/apache/atlas/plugin/util/RangerUserStore.java rename to auth-common/src/main/java/org/apache/atlas/plugin/util/RangerUserStore.java index 7318648cf8..dc1115fa4c 100644 --- a/auth-agents-common/src/main/java/org/apache/atlas/plugin/util/RangerUserStore.java +++ b/auth-common/src/main/java/org/apache/atlas/plugin/util/RangerUserStore.java @@ -59,7 +59,7 @@ public RangerUserStore(Long userStoreVersion, Set users, Set runQueryWithLowLevelClient(String query) throws AtlasBaseException { + public Map runQueryWithLowLevelClient(String query) throws AtlasBaseException { Map ret = new HashMap<>(); try { String responseString = performDirectIndexQuery(query, true); diff --git a/intg/src/main/java/org/apache/atlas/model/discovery/IndexSearchParams.java b/intg/src/main/java/org/apache/atlas/model/discovery/IndexSearchParams.java index 84d9939242..a23b28aa33 100644 --- a/intg/src/main/java/org/apache/atlas/model/discovery/IndexSearchParams.java +++ b/intg/src/main/java/org/apache/atlas/model/discovery/IndexSearchParams.java @@ -33,6 +33,11 @@ public String getQuery() { return queryString; } + @Override + public void setQuery(String query) { + this.queryString = query; + } + public Map getDsl() { return dsl; } diff --git a/intg/src/main/java/org/apache/atlas/model/discovery/SearchParams.java b/intg/src/main/java/org/apache/atlas/model/discovery/SearchParams.java index acdcfca447..87b4b84ced 100644 --- a/intg/src/main/java/org/apache/atlas/model/discovery/SearchParams.java +++ b/intg/src/main/java/org/apache/atlas/model/discovery/SearchParams.java @@ -18,6 +18,7 @@ public class SearchParams { boolean suppressLogs; boolean excludeMeanings; boolean excludeClassifications; + boolean useAccessControlv2; RequestMetadata requestMetadata = new RequestMetadata(); boolean showHighlights; @@ -26,10 +27,18 @@ public String getQuery() { return getQuery(); } + public boolean getUseAccessControlv2() { + return useAccessControlv2; + } + public Set getAttributes() { return attributes; } + public void setQuery(String query) { + setQuery(query); + } + public void setAttributes(Set attributes) { this.attributes = attributes; } diff --git a/pom.xml b/pom.xml index 1cc9aa70dc..cbe4f00371 100644 --- a/pom.xml +++ b/pom.xml @@ -798,6 +798,7 @@ dashboardv2 dashboardv3 + auth-common auth-agents-cred auth-agents-common auth-audits diff --git a/repository/pom.xml b/repository/pom.xml index 10d8d876fb..f35e95b570 100755 --- a/repository/pom.xml +++ b/repository/pom.xml @@ -322,6 +322,18 @@ 3.0.0-SNAPSHOT + + org.apache.atlas + auth-common + 3.0.0-SNAPSHOT + + + org.apache.atlas + auth-audits + 3.0.0-SNAPSHOT + + + diff --git a/repository/src/main/java/org/apache/atlas/authorizer/AccessResult.java b/repository/src/main/java/org/apache/atlas/authorizer/AccessResult.java new file mode 100644 index 0000000000..a60331d1bc --- /dev/null +++ b/repository/src/main/java/org/apache/atlas/authorizer/AccessResult.java @@ -0,0 +1,22 @@ +package org.apache.atlas.authorizer; + +public class AccessResult { + private boolean isAllowed = false; + private String policyId = "-1"; + + public boolean isAllowed() { + return isAllowed; + } + + public void setAllowed(boolean allowed) { + this.isAllowed = allowed; + } + + public String getPolicyId() { + return policyId; + } + + public void setPolicyId(String policyId) { + this.policyId = policyId; + } +} diff --git a/repository/src/main/java/org/apache/atlas/authorizer/AccessorsExtractor.java b/repository/src/main/java/org/apache/atlas/authorizer/AccessorsExtractor.java new file mode 100644 index 0000000000..73814b492a --- /dev/null +++ b/repository/src/main/java/org/apache/atlas/authorizer/AccessorsExtractor.java @@ -0,0 +1,271 @@ +package org.apache.atlas.authorizer; + +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.ObjectMapper; +import org.apache.atlas.AtlasErrorCode; +import org.apache.atlas.authorize.AtlasAccessorRequest; +import org.apache.atlas.authorize.AtlasAccessorResponse; +import org.apache.atlas.authorize.AtlasPrivilege; +import org.apache.atlas.authorizer.authorizers.AuthorizerCommon; +import org.apache.atlas.authorizer.authorizers.EntityAuthorizer; +import org.apache.atlas.authorizer.authorizers.RelationshipAuthorizer; +import org.apache.atlas.authorizer.store.PoliciesStore; +import org.apache.atlas.exception.AtlasBaseException; +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.store.graph.v2.AtlasGraphUtilsV2; +import org.apache.atlas.type.AtlasEntityType; +import org.apache.commons.collections.CollectionUtils; +import org.apache.commons.lang3.StringUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashMap; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Set; + +import static org.apache.atlas.authorize.AtlasPrivilege.ENTITY_ADD_CLASSIFICATION; +import static org.apache.atlas.authorize.AtlasPrivilege.ENTITY_ADD_LABEL; +import static org.apache.atlas.authorize.AtlasPrivilege.ENTITY_CREATE; +import static org.apache.atlas.authorize.AtlasPrivilege.ENTITY_DELETE; +import static org.apache.atlas.authorize.AtlasPrivilege.ENTITY_READ; +import static org.apache.atlas.authorize.AtlasPrivilege.ENTITY_READ_CLASSIFICATION; +import static org.apache.atlas.authorize.AtlasPrivilege.ENTITY_REMOVE_CLASSIFICATION; +import static org.apache.atlas.authorize.AtlasPrivilege.ENTITY_REMOVE_LABEL; +import static org.apache.atlas.authorize.AtlasPrivilege.ENTITY_UPDATE; +import static org.apache.atlas.authorize.AtlasPrivilege.ENTITY_UPDATE_BUSINESS_METADATA; +import static org.apache.atlas.authorize.AtlasPrivilege.ENTITY_UPDATE_CLASSIFICATION; +import static org.apache.atlas.authorize.AtlasPrivilege.RELATIONSHIP_ADD; +import static org.apache.atlas.authorize.AtlasPrivilege.RELATIONSHIP_REMOVE; +import static org.apache.atlas.authorize.AtlasPrivilege.RELATIONSHIP_UPDATE; +import static org.apache.atlas.authorizer.authorizers.EntityAuthorizer.validateFilterCriteriaWithEntity; +import static org.apache.atlas.repository.Constants.QUALIFIED_NAME; + +public class AccessorsExtractor { + + private static final Logger LOG = LoggerFactory.getLogger(AccessorsExtractor.class); + + private static final Set ENTITY_ACTIONS = new HashSet(){{ + add(ENTITY_READ.getType()); + add(ENTITY_CREATE.getType()); + add(ENTITY_UPDATE.getType()); + add(ENTITY_DELETE.getType()); + add(ENTITY_READ_CLASSIFICATION.getType()); + add(ENTITY_ADD_CLASSIFICATION.getType()); + add(ENTITY_UPDATE_CLASSIFICATION.getType()); + add(ENTITY_REMOVE_CLASSIFICATION.getType()); + add(ENTITY_UPDATE_BUSINESS_METADATA.getType()); + add(ENTITY_ADD_LABEL.getType()); + add(ENTITY_REMOVE_LABEL.getType()); + }}; + + private static final Set RELATIONSHIP_ACTIONS = new HashSet(){{ + add(RELATIONSHIP_ADD.getType()); + add(RELATIONSHIP_UPDATE.getType()); + add(RELATIONSHIP_REMOVE.getType()); + }}; + + public static AtlasAccessorResponse getAccessors(AtlasAccessorRequest request) throws AtlasBaseException { + return getAccessorsInMemory(request); + } + + private static void collectSubjects(AtlasAccessorResponse response, List matchedPolicies) { + for (RangerPolicy policy: matchedPolicies) { + List policyItems = null; + if (CollectionUtils.isNotEmpty(policy.getPolicyItems())) { + for (RangerPolicy.RangerPolicyItem policyItem: policy.getPolicyItems()) { + response.getUsers().addAll(policyItem.getUsers()); + response.getRoles().addAll(policyItem.getRoles()); + response.getGroups().addAll(policyItem.getGroups()); + } + } else if (CollectionUtils.isNotEmpty(policy.getDenyPolicyItems())) { + for (RangerPolicy.RangerPolicyItem policyItem: policy.getDenyPolicyItems()) { + response.getDenyUsers().addAll(policyItem.getUsers()); + response.getDenyRoles().addAll(policyItem.getRoles()); + response.getDenyGroups().addAll(policyItem.getGroups()); + } + } + } + } + + private static AtlasEntity extractEntity(String guid, String qualifiedName, String typeName) throws AtlasBaseException { + AtlasEntity entity = null; + + if (StringUtils.isNotEmpty(guid)) { + entity = AuthorizerCommon.toAtlasEntityHeaderWithClassifications(guid); + + } else { + AtlasEntityType entityType = AuthorizerCommon.getEntityTypeByName(typeName); + if (entityType != null) { + try { + AtlasVertex vertex = AtlasGraphUtilsV2.findByTypeAndUniquePropertyName(typeName, QUALIFIED_NAME, qualifiedName); + if (vertex != null) { + entity = AuthorizerCommon.toAtlasEntityHeaderWithClassifications(vertex); + } else { + Map attributes = new HashMap<>(); + attributes.put(QUALIFIED_NAME, qualifiedName); + entity = new AtlasEntity(entityType.getTypeName(), attributes); + } + + } catch (AtlasBaseException abe) { + if (abe.getAtlasErrorCode() != AtlasErrorCode.INSTANCE_BY_UNIQUE_ATTRIBUTE_NOT_FOUND) { + throw abe; + } + + Map attributes = new HashMap<>(); + attributes.put(QUALIFIED_NAME, qualifiedName); + entity = new AtlasEntity(entityType.getTypeName(), attributes); + } + } else { + Map attributes = new HashMap<>(); + attributes.put(QUALIFIED_NAME, qualifiedName); + entity = new AtlasEntity(typeName, attributes); + } + } + return entity; + } + + public static AtlasAccessorResponse getAccessorsInMemory(AtlasAccessorRequest request) throws AtlasBaseException { + AtlasAccessorResponse response = new AtlasAccessorResponse(); + + String action = AtlasPrivilege.valueOf(request.getAction()).getType(); + + List abacPolicies = PoliciesStore.getRelevantPolicies(null, null, "atlas_abac", Arrays.asList(action), null, true); + + List matchedPolicies = getAccessorsInMemoryForAbacPolicies(request, abacPolicies); + + + List resourcePolicies = PoliciesStore.getRelevantPolicies(null, null, "atlas", Arrays.asList(action), null, true); + resourcePolicies.addAll(PoliciesStore.getRelevantPolicies(null, null, "atlas_tag", Arrays.asList(action), null, true)); + + matchedPolicies.addAll(getAccessorsInMemoryForRangerPolicies(request, resourcePolicies)); + + + collectSubjects(response, matchedPolicies); + + return response; + } + + public static List getAccessorsInMemoryForRangerPolicies(AtlasAccessorRequest request, List rangerPolicies) throws AtlasBaseException { + List matchedPolicies = new ArrayList<>(); + String action = AtlasPrivilege.valueOf(request.getAction()).getType(); + + if (ENTITY_ACTIONS.contains(action)) { + AtlasEntity entity = extractEntity(request.getGuid(), request.getQualifiedName(), request.getTypeName()); + Set entityTypes = AuthorizerCommon.getTypeAndSupertypesList(request.getTypeName()); + + boolean matched = false; + for (RangerPolicy policy: rangerPolicies) { + matched = EntityAuthorizer.evaluateRangerPolicyInMemory(policy, entity, entityTypes); + + if (matched) { + matchedPolicies.add(policy); + } + } + + } else if (RELATIONSHIP_ACTIONS.contains(action)) { + AtlasEntityHeader entityOne = new AtlasEntityHeader(extractEntity(request.getEntityGuidEnd1(), request.getEntityQualifiedNameEnd1(), request.getEntityTypeEnd1())); + AtlasEntityHeader entityTwo = new AtlasEntityHeader(extractEntity(request.getEntityGuidEnd2(), request.getEntityQualifiedNameEnd2(), request.getEntityTypeEnd2())); + + Set entityTypesOne = AuthorizerCommon.getTypeAndSupertypesList(request.getEntityTypeEnd1()); + Set entityTypesTwo = AuthorizerCommon.getTypeAndSupertypesList(request.getEntityTypeEnd2()); + + boolean matched = false; + for (RangerPolicy policy: rangerPolicies) { + matched = RelationshipAuthorizer.evaluateRangerPolicyInMemory(policy, request.getRelationshipTypeName(), entityOne, entityTwo, entityTypesOne, entityTypesTwo); + + if (matched) { + matchedPolicies.add(policy); + } + } + } + + return matchedPolicies; + } + + public static List getAccessorsInMemoryForAbacPolicies(AtlasAccessorRequest request, List abacPolicies) throws AtlasBaseException { + List matchedPolicies = new ArrayList<>(); + String action = AtlasPrivilege.valueOf(request.getAction()).getType(); + + ObjectMapper mapper = new ObjectMapper(); + + if (ENTITY_ACTIONS.contains(action)) { + AtlasEntity entity = extractEntity(request.getGuid(), request.getQualifiedName(), request.getTypeName()); + AtlasVertex vertex = AtlasGraphUtilsV2.findByGuid(entity.getGuid()); + if (vertex == null) { + vertex = AtlasGraphUtilsV2.findByTypeAndUniquePropertyName(request.getTypeName(), QUALIFIED_NAME, request.getQualifiedName()); + } + + for (RangerPolicy policy : abacPolicies) { + String filterCriteria = policy.getPolicyFilterCriteria(); + if (filterCriteria != null && !filterCriteria.isEmpty() ) { + + JsonNode filterCriteriaNode = null; + try { + filterCriteriaNode = mapper.readTree(policy.getPolicyFilterCriteria()); + } catch (JsonProcessingException e) { + e.printStackTrace(); + } + + if (filterCriteriaNode != null && filterCriteriaNode.get("entity") != null) { + JsonNode entityFilterCriteriaNode = filterCriteriaNode.get("entity"); + boolean matched = EntityAuthorizer.validateFilterCriteriaWithEntity(entityFilterCriteriaNode, entity, vertex); + + if (matched) { + matchedPolicies.add(policy); + } + } + } + } + + } else if (RELATIONSHIP_ACTIONS.contains(action)) { + AtlasEntityHeader entityOne = new AtlasEntityHeader(extractEntity(request.getEntityGuidEnd1(), request.getEntityQualifiedNameEnd1(), request.getEntityTypeEnd1())); + AtlasEntityHeader entityTwo = new AtlasEntityHeader(extractEntity(request.getEntityGuidEnd2(), request.getEntityQualifiedNameEnd2(), request.getEntityTypeEnd2())); + + AtlasVertex vertexOne = AtlasGraphUtilsV2.findByGuid(request.getEntityGuidEnd1()); + AtlasVertex vertexTwo = AtlasGraphUtilsV2.findByGuid(request.getEntityGuidEnd2()); + if (vertexOne == null) { + vertexOne = AtlasGraphUtilsV2.findByTypeAndUniquePropertyName(request.getEntityTypeEnd1(), QUALIFIED_NAME, request.getEntityQualifiedNameEnd1()); + } + if (vertexTwo == null) { + vertexTwo = AtlasGraphUtilsV2.findByTypeAndUniquePropertyName(request.getEntityTypeEnd2(), QUALIFIED_NAME, request.getEntityQualifiedNameEnd2()); + } + + for (RangerPolicy policy : abacPolicies) { + String filterCriteria = policy.getPolicyFilterCriteria(); + if (filterCriteria != null && !filterCriteria.isEmpty() ) { + + JsonNode filterCriteriaNode = null; + try { + filterCriteriaNode = mapper.readTree(policy.getPolicyFilterCriteria()); + } catch (JsonProcessingException e) { + e.printStackTrace(); + } + + if (filterCriteriaNode != null && filterCriteriaNode.get("endOneEntity") != null) { + JsonNode entityFilterCriteriaNode = filterCriteriaNode.get("endOneEntity"); + boolean matched = validateFilterCriteriaWithEntity(entityFilterCriteriaNode, new AtlasEntity(entityOne), vertexOne); + + if (matched) { + entityFilterCriteriaNode = filterCriteriaNode.get("endTwoEntity"); + matched = validateFilterCriteriaWithEntity(entityFilterCriteriaNode, new AtlasEntity(entityTwo), vertexTwo); + } + + if (matched) { + matchedPolicies.add(policy); + } + } + } + } + } + + return matchedPolicies; + } +} diff --git a/repository/src/main/java/org/apache/atlas/authorizer/AuthorizerUtils.java b/repository/src/main/java/org/apache/atlas/authorizer/AuthorizerUtils.java new file mode 100644 index 0000000000..3df03bc69d --- /dev/null +++ b/repository/src/main/java/org/apache/atlas/authorizer/AuthorizerUtils.java @@ -0,0 +1,242 @@ +package org.apache.atlas.authorizer; + +import org.apache.atlas.AtlasErrorCode; +import org.apache.atlas.RequestContext; +import org.apache.atlas.audit.provider.AuditHandler; +import org.apache.atlas.authorize.AtlasAccessorRequest; +import org.apache.atlas.authorize.AtlasAccessorResponse; +import org.apache.atlas.authorize.AtlasEntityAccessRequest; +import org.apache.atlas.authorize.AtlasPrivilege; +import org.apache.atlas.authorize.AtlasRelationshipAccessRequest; +import org.apache.atlas.authorizer.authorizers.AuthorizerCommon; +import org.apache.atlas.authorizer.authorizers.EntityAuthorizer; +import org.apache.atlas.authorizer.authorizers.ListAuthorizer; +import org.apache.atlas.authorizer.authorizers.RelationshipAuthorizer; +import org.apache.atlas.exception.AtlasBaseException; +import org.apache.atlas.model.instance.AtlasEntity; +import org.apache.atlas.model.instance.AtlasEntityHeader; +import org.apache.atlas.plugin.model.RangerServiceDef; +import org.apache.atlas.repository.graphdb.AtlasGraph; +import org.apache.atlas.repository.store.graph.v2.EntityGraphRetriever; +import org.apache.atlas.type.AtlasType; +import org.apache.atlas.type.AtlasTypeRegistry; +import org.apache.atlas.utils.AtlasPerfMetrics; +import org.apache.commons.lang.StringUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.stereotype.Component; + +import javax.inject.Inject; +import java.io.IOException; +import java.io.InputStream; +import java.util.List; +import java.util.Map; + +import static org.apache.atlas.repository.Constants.QUALIFIED_NAME; +import static org.apache.atlas.repository.Constants.SKIP_DELETE_AUTH_CHECK_TYPES; +import static org.apache.atlas.repository.Constants.SKIP_UPDATE_AUTH_CHECK_TYPES; + +@Component +public class AuthorizerUtils { + private static final Logger LOG = LoggerFactory.getLogger(AuthorizerUtils.class); + + public static final String POLICY_TYPE_ALLOW = "allow"; + 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; + + + private static RangerServiceDef SERVICE_DEF_ATLAS = null; + //private static RangerServiceDef SERVICE_DEF_ATLAS_TAG = null; + + + @Inject + public AuthorizerUtils(AtlasGraph graph, AtlasTypeRegistry typeRegistry) throws IOException { + this.typeRegistry = typeRegistry; + //this.entityRetriever = new EntityGraphRetriever(graph, typeRegistry, true); + + SERVICE_DEF_ATLAS = getResourceAsObject("/service-defs/atlas-servicedef-atlas.json", RangerServiceDef.class); + //SERVICE_DEF_ATLAS_TAG = getResourceAsObject("/service-defs/atlas-servicedef-atlas_tag.json", RangerServiceDef.class); + } + + public static void verifyUpdateEntityAccess(AtlasEntityHeader entityHeader) throws AtlasBaseException { + if (!SKIP_UPDATE_AUTH_CHECK_TYPES.contains(entityHeader.getTypeName())) { + verifyAccess(entityHeader, AtlasPrivilege.ENTITY_UPDATE); + } + } + + public static void verifyDeleteEntityAccess(AtlasEntityHeader entityHeader) throws AtlasBaseException { + if (!SKIP_DELETE_AUTH_CHECK_TYPES.contains(entityHeader.getTypeName())) { + verifyAccess(entityHeader, AtlasPrivilege.ENTITY_DELETE); + } + } + + public static void verifyEntityCreateAccess(AtlasEntity entity, AtlasPrivilege action) throws AtlasBaseException { + AtlasPerfMetrics.MetricRecorder recorder = RequestContext.get().startMetricRecord("verifyEntityCreateAccess"); + String userName = AuthorizerCommon.getCurrentUserName(); + + if (StringUtils.isEmpty(userName) || RequestContext.get().isImportInProgress()) { + return; + } + + AtlasEntityAccessRequest request = new AtlasEntityAccessRequest(typeRegistry, action, new AtlasEntityHeader(entity)); + NewAtlasAuditHandler auditHandler = new NewAtlasAuditHandler(request, SERVICE_DEF_ATLAS); + + try { + if (AtlasPrivilege.ENTITY_CREATE == action) { + AccessResult result = EntityAuthorizer.isAccessAllowedInMemory(entity, action.getType()); + auditHandler.processResult(result, request); + + if (!result.isAllowed()){ + String message = action.getType() + ":" + entity.getTypeName() + ":" + entity.getAttributes().get(QUALIFIED_NAME); + throw new AtlasBaseException(AtlasErrorCode.UNAUTHORIZED_ACCESS, userName, message); + } + } + } catch (AtlasBaseException e) { + throw e; + } finally { + auditHandler.flushAudit(); + RequestContext.get().endMetricRecord(recorder); + } + } + + public static void verifyAccess(AtlasEntityHeader entityHeader, AtlasPrivilege action) throws AtlasBaseException { + AtlasPerfMetrics.MetricRecorder recorder = RequestContext.get().startMetricRecord("verifyAccess"); + String userName = AuthorizerCommon.getCurrentUserName(); + + if (StringUtils.isEmpty(userName) || RequestContext.get().isImportInProgress()) { + return; + } + + AtlasEntityAccessRequest request = new AtlasEntityAccessRequest(typeRegistry, action, entityHeader); + NewAtlasAuditHandler auditHandler = new NewAtlasAuditHandler(request, SERVICE_DEF_ATLAS); + + try { + AccessResult result = EntityAuthorizer.isAccessAllowed(entityHeader.getGuid(), action.getType()); + auditHandler.processResult(result, request); + + if (!result.isAllowed()) { + throw new AtlasBaseException(AtlasErrorCode.UNAUTHORIZED_ACCESS, userName, action + ":" + entityHeader.getGuid()); + } + } catch (AtlasBaseException e) { + throw e; + } finally { + auditHandler.flushAudit(); + RequestContext.get().endMetricRecord(recorder); + } + } + + public static void verifyAccessForEvaluator(AtlasEntityHeader entityHeader, AtlasPrivilege action) throws AtlasBaseException { + AtlasPerfMetrics.MetricRecorder recorder = RequestContext.get().startMetricRecord("verifyAccess"); + String userName = AuthorizerCommon.getCurrentUserName(); + + if (StringUtils.isEmpty(userName) || RequestContext.get().isImportInProgress()) { + return; + } + + AtlasEntityAccessRequest request = new AtlasEntityAccessRequest(typeRegistry, action, entityHeader); + NewAtlasAuditHandler auditHandler = new NewAtlasAuditHandler(request, SERVICE_DEF_ATLAS); + + try { + String entityQNAme = (String) entityHeader.getAttribute(QUALIFIED_NAME); + + AccessResult result = EntityAuthorizer.isAccessAllowedEvaluator(entityHeader.getTypeName(), entityQNAme, action.getType()); + auditHandler.processResult(result, request); + + if (!result.isAllowed()) { + throw new AtlasBaseException(AtlasErrorCode.UNAUTHORIZED_ACCESS, userName, action + ":" + entityHeader.getTypeName() + ":" + entityQNAme); + } + } catch (AtlasBaseException e) { + throw e; + } finally { + auditHandler.flushAudit(); + RequestContext.get().endMetricRecord(recorder); + } + } + + public static void verifyRelationshipAccess(AtlasPrivilege action, String relationShipType, AtlasEntityHeader endOneEntity, AtlasEntityHeader endTwoEntity) throws AtlasBaseException { + AtlasPerfMetrics.MetricRecorder recorder = RequestContext.get().startMetricRecord("verifyAccess"); + String userName = AuthorizerCommon.getCurrentUserName(); + + if (StringUtils.isEmpty(userName) || RequestContext.get().isImportInProgress()) { + return; + } + + AtlasRelationshipAccessRequest request = new AtlasRelationshipAccessRequest(typeRegistry, + action, + relationShipType, + endOneEntity, + endTwoEntity); + + NewAtlasAuditHandler auditHandler = new NewAtlasAuditHandler(request, SERVICE_DEF_ATLAS); + + try { + AccessResult result = RelationshipAuthorizer.isRelationshipAccessAllowed(action.getType(), endOneEntity, endTwoEntity); + auditHandler.processResult(result, request); + + if (!result.isAllowed()) { + throw new AtlasBaseException(AtlasErrorCode.UNAUTHORIZED_ACCESS, RequestContext.getCurrentUser(), action + "|" + endOneEntity.getGuid() + "|" + endTwoEntity.getGuid()); + } + } catch (AtlasBaseException e) { + throw e; + } finally { + auditHandler.flushAudit(); + RequestContext.get().endMetricRecord(recorder); + } + } + + public static void verifyRelationshipCreateAccess(AtlasPrivilege action, String relationshipType, AtlasEntityHeader endOneEntity, AtlasEntityHeader endTwoEntity) throws AtlasBaseException { + AtlasPerfMetrics.MetricRecorder recorder = RequestContext.get().startMetricRecord("verifyAccess"); + String userName = AuthorizerCommon.getCurrentUserName(); + + if (StringUtils.isEmpty(userName) || RequestContext.get().isImportInProgress()) { + return; + } + + AtlasRelationshipAccessRequest request = new AtlasRelationshipAccessRequest(typeRegistry, + action, + relationshipType, + endOneEntity, + endTwoEntity); + NewAtlasAuditHandler auditHandler = new NewAtlasAuditHandler(request, SERVICE_DEF_ATLAS); + + try { + AccessResult result = RelationshipAuthorizer.isAccessAllowedInMemory(action.getType(), relationshipType, endOneEntity, endTwoEntity); + auditHandler.processResult(result, request); + + if (!result.isAllowed()) { + throw new AtlasBaseException(AtlasErrorCode.UNAUTHORIZED_ACCESS, RequestContext.getCurrentUser(), + action + ":" + endOneEntity.getTypeName() + "|" + endTwoEntity.getTypeName()); + } + } catch (AtlasBaseException e) { + throw e; + } finally { + auditHandler.flushAudit(); + RequestContext.get().endMetricRecord(recorder); + } + } + + public static AtlasAccessorResponse getAccessors(AtlasAccessorRequest request) throws AtlasBaseException { + AtlasPerfMetrics.MetricRecorder recorder = RequestContext.get().startMetricRecord("AuthorizerUtils.getAccessors"); + + try { + return AccessorsExtractor.getAccessors(request); + } finally { + RequestContext.get().endMetricRecord(recorder); + } + } + + public static Map getPreFilterDsl(String persona, String purpose, List actions) { + return ListAuthorizer.getElasticsearchDSL(persona, purpose, actions); + } + + private T getResourceAsObject(String resourceName, Class clazz) throws IOException { + InputStream stream = getClass().getResourceAsStream(resourceName); + return AtlasType.fromJson(stream, clazz); + } +} diff --git a/repository/src/main/java/org/apache/atlas/authorizer/JsonToElasticsearchQuery.java b/repository/src/main/java/org/apache/atlas/authorizer/JsonToElasticsearchQuery.java new file mode 100644 index 0000000000..f7715b1f58 --- /dev/null +++ b/repository/src/main/java/org/apache/atlas/authorizer/JsonToElasticsearchQuery.java @@ -0,0 +1,86 @@ +package org.apache.atlas.authorizer; + +import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.node.ArrayNode; +import com.fasterxml.jackson.databind.node.ObjectNode; +import org.apache.atlas.RequestContext; +import org.apache.atlas.utils.AtlasPerfMetrics; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class JsonToElasticsearchQuery { + private static final Logger LOG = LoggerFactory.getLogger(JsonToElasticsearchQuery.class); + + private static JsonNode convertConditionToQuery(String condition, JsonNode criterion, ObjectMapper mapper) { + if (condition.equals("AND")) { + return mapper.createObjectNode().set("bool", mapper.createObjectNode().set("filter", mapper.createArrayNode())); + } else if (condition.equals("OR")) { + //JsonNode node = mapper.createObjectNode().set("bool", mapper.createObjectNode()); + return mapper.createObjectNode() + .set("bool", mapper.createObjectNode() + .set("should", mapper.createArrayNode())); + } else { + throw new IllegalArgumentException("Unsupported condition: " + condition); + } + } + + public static JsonNode convertJsonToQuery(JsonNode data, ObjectMapper mapper) { + AtlasPerfMetrics.MetricRecorder convertJsonToQueryMetrics = RequestContext.get().startMetricRecord("convertJsonToQuery"); + String condition = data.get("condition").asText(); + JsonNode criterion = data.get("criterion"); + + JsonNode query = convertConditionToQuery(condition, criterion, mapper); + + for (JsonNode crit : criterion) { + if (crit.has("condition")) { + JsonNode nestedQuery = convertJsonToQuery(crit, mapper); + if (condition.equals("AND")) { + ((ArrayNode) query.get("bool").get("filter")).add(nestedQuery); + } else { + ((ArrayNode) query.get("bool").get("should")).add(nestedQuery); + } + } else { + String operator = crit.get("operator").asText(); + String attributeName = crit.get("attributeName").asText(); + String attributeValue = crit.get("attributeValue").asText(); + + switch (operator) { + case "EQUALS": + ObjectNode termNode = ((ArrayNode) query.get("bool").get(condition.equals("AND") ? "filter" : "should")).addObject(); + termNode.putObject("term").put(attributeName, attributeValue); + break; + + case "NOT_EQUALS": + termNode = ((ArrayNode) query.get("bool").get(condition.equals("AND") ? "filter" : "should")).addObject(); + termNode.putObject("bool").putObject("must_not").putObject("term").put(attributeName, attributeValue); + break; + + case "STARTS_WITH": + ObjectNode wildcardNode = ((ArrayNode) query.get("bool").get(condition.equals("AND") ? "filter" : "should")).addObject(); + wildcardNode.putObject("wildcard").put(attributeName, attributeValue + "*"); + break; + + case "ENDS_WITH": + wildcardNode = ((ArrayNode) query.get("bool").get(condition.equals("AND") ? "filter" : "should")).addObject(); + wildcardNode.putObject("wildcard").put(attributeName, "*" + attributeValue); + break; + + case "IN": + ObjectNode termsNode = ((ArrayNode) query.get("bool").get(condition.equals("AND") ? "filter" : "should")).addObject(); + termsNode.putObject("terms").set(attributeName, crit.get("attributeValue")); + break; + + case "NOT_IN": + termsNode = ((ArrayNode) query.get("bool").get(condition.equals("AND") ? "filter" : "should")).addObject(); + termsNode.putObject("bool").putObject("must_not").putObject("terms").put(attributeName, crit.get("attributeValue")); + break; + + default: LOG.warn("Found unknown operator {}", operator); + } + } + } + RequestContext.get().endMetricRecord(convertJsonToQueryMetrics); + return query; + } +} diff --git a/repository/src/main/java/org/apache/atlas/authorizer/NewAtlasAuditHandler.java b/repository/src/main/java/org/apache/atlas/authorizer/NewAtlasAuditHandler.java new file mode 100644 index 0000000000..4e6621f9c2 --- /dev/null +++ b/repository/src/main/java/org/apache/atlas/authorizer/NewAtlasAuditHandler.java @@ -0,0 +1,250 @@ +package org.apache.atlas.authorizer; + +import org.apache.atlas.RequestContext; +import org.apache.atlas.audit.model.AuthzAuditEvent; +import org.apache.atlas.audit.provider.AuditHandler; +import org.apache.atlas.audit.provider.AuditProviderFactory; +import org.apache.atlas.audit.provider.MiscUtil; +import org.apache.atlas.authorize.AtlasAccessRequest; +import org.apache.atlas.authorize.AtlasEntityAccessRequest; +import org.apache.atlas.authorize.AtlasPrivilege; +import org.apache.atlas.authorize.AtlasRelationshipAccessRequest; +import org.apache.atlas.authorizer.authorizers.AuthorizerCommon; +import org.apache.atlas.model.instance.AtlasClassification; +import org.apache.atlas.plugin.model.NewAccessResourceImpl; +import org.apache.atlas.plugin.model.RangerServiceDef; +import org.apache.commons.lang.StringUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.util.Collection; +import java.util.Date; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Map; +import java.util.Set; + +class NewAtlasAuditHandler { + private static final Logger LOG = LoggerFactory.getLogger(NewAtlasAuditHandler.class); + + public static final String RESOURCE_SERVICE = "atlas-service"; + public static final String RESOURCE_TYPE_CATEGORY = "type-category"; + public static final String RESOURCE_TYPE_NAME = "type"; + public static final String RESOURCE_ENTITY_TYPE = "entity-type"; + public static final String RESOURCE_ENTITY_CLASSIFICATION = "entity-classification"; + public static final String RESOURCE_CLASSIFICATION = "classification"; + public static final String RESOURCE_ENTITY_ID = "entity"; + public static final String RESOURCE_ENTITY_LABEL = "entity-label"; + public static final String RESOURCE_ENTITY_BUSINESS_METADATA = "entity-business-metadata"; + public static final String RESOURCE_ENTITY_OWNER = "owner"; + public static final String RESOURCE_RELATIONSHIP_TYPE = "relationship-type"; + public static final String RESOURCE_END_ONE_ENTITY_TYPE = "end-one-entity-type"; + public static final String RESOURCE_END_ONE_ENTITY_CLASSIFICATION = "end-one-entity-classification"; + public static final String RESOURCE_END_ONE_ENTITY_ID = "end-one-entity"; + public static final String RESOURCE_END_TWO_ENTITY_TYPE = "end-two-entity-type"; + public static final String RESOURCE_END_TWO_ENTITY_CLASSIFICATION = "end-two-entity-classification"; + public static final String RESOURCE_END_TWO_ENTITY_ID = "end-two-entity"; + public static final String SEARCH_FEATURE_POLICY_NAME = "Allow users to manage favorite searches"; + + public static final String ACCESS_TYPE_ENTITY_READ = "entity-read"; + public static final String ACCESS_TYPE_TYPE_READ = "type-read"; + public static final String ACCESS_TYPE_ENTITY_CREATE = "entity-create"; + public static final String ACCESS_TYPE_ENTITY_UPDATE = "entity-update"; + public static final String ACCESS_TYPE_ENTITY_DELETE = "entity-delete"; + public static final String ADMIN_USERNAME_DEFAULT = "admin"; + public static final String TAGSYNC_USERNAME_DEFAULT = "rangertagsync"; + public static final String ENTITY_TYPE_USER_PROFILE = "__AtlasUserProfile"; + public static final String ENTITY_TYPE_SAVED_SEARCH = "__AtlasUserSavedSearch"; + + + public static final String CONFIG_REST_ADDRESS = "atlas.rest.address"; + public static final String CONFIG_USERNAME = "username"; + public static final String CONFIG_PASSWORD = "password"; + public static final String ENTITY_NOT_CLASSIFIED = "_NOT_CLASSIFIED"; + + private static final String TYPE_ENTITY = "entity"; + private static final String TYPE_CLASSIFICATION = "classification"; + private static final String TYPE_STRUCT = "struct"; + private static final String TYPE_ENUM = "enum"; + private static final String TYPE_RELATIONSHIP = "relationship"; + private static final String TYPE_BUSINESS_METADATA = "business_metadata"; + + private static final String URL_LOGIN = "/j_spring_security_check"; + private static final String URL_GET_TYPESDEF_HEADERS = "/api/atlas/v2/types/typedefs/headers"; + private static final String URl_ENTITY_SEARCH = "v2/search/attribute?attrName=qualifiedName"; + + private static final String WEB_RESOURCE_CONTENT_TYPE = "application/x-www-form-urlencoded"; + private static final String CONNECTION_ERROR_MSG = " You can still save the repository and start creating" + + " policies, but you would not be able to use autocomplete for" + + " resource names. Check ranger_admin.log for more info."; + + + private final Map auditEvents; + private final String resourcePath; + private final String resourceType; + private long sequenceNumber = 0; + + public NewAtlasAuditHandler(AtlasEntityAccessRequest request, RangerServiceDef serviceDef) { + Collection classifications = request.getEntityClassifications(); + String strClassifications = classifications == null ? "[]" : classifications.toString(); + + if (request.getClassification() != null) { + strClassifications += ("," + request.getClassification().getTypeName()); + } + + NewAccessResourceImpl rangerResource = new NewAccessResourceImpl(); + + rangerResource.setServiceDef(serviceDef); + rangerResource.setValue(RESOURCE_ENTITY_TYPE, request.getEntityType()); + rangerResource.setValue(RESOURCE_ENTITY_CLASSIFICATION, strClassifications); + rangerResource.setValue(RESOURCE_ENTITY_ID, request.getEntityId()); + + if (AtlasPrivilege.ENTITY_ADD_LABEL.equals(request.getAction()) || AtlasPrivilege.ENTITY_REMOVE_LABEL.equals(request.getAction())) { + rangerResource.setValue(RESOURCE_ENTITY_LABEL, "label=" + request.getLabel()); + } else if (AtlasPrivilege.ENTITY_UPDATE_BUSINESS_METADATA.equals(request.getAction())) { + rangerResource.setValue(RESOURCE_ENTITY_BUSINESS_METADATA, "business-metadata=" + request.getBusinessMetadata()); + } + + auditEvents = new HashMap<>(); + resourceType = rangerResource.getLeafName(); + resourcePath = rangerResource.getAsString(); + } + + public NewAtlasAuditHandler(AtlasRelationshipAccessRequest request, RangerServiceDef serviceDef) { + NewAccessResourceImpl rangerResource = new NewAccessResourceImpl(); + rangerResource.setServiceDef(serviceDef); + + rangerResource.setValue(RESOURCE_RELATIONSHIP_TYPE, request.getRelationshipType()); + + //End 1 + final String end1EntityId = request.getEnd1EntityId(); + Set end1EntityTypeAndSuperTypes = request.getEnd1EntityTypeAndAllSuperTypes(); + + final Set end1Classifications = new HashSet(request.getEnd1EntityClassifications()); + Set classificationsWithSuperTypesEnd1 = new HashSet(); + for (AtlasClassification classificationToAuthorize : end1Classifications) { + classificationsWithSuperTypesEnd1.addAll(request.getClassificationTypeAndAllSuperTypes(classificationToAuthorize.getTypeName())); + } + + rangerResource.setValue(RESOURCE_END_ONE_ENTITY_TYPE, end1EntityTypeAndSuperTypes); + rangerResource.setValue(RESOURCE_END_ONE_ENTITY_CLASSIFICATION, classificationsWithSuperTypesEnd1); + rangerResource.setValue(RESOURCE_END_ONE_ENTITY_ID, end1EntityId); + + //End 2 + final String end2EntityId = request.getEnd2EntityId(); + Set end2EntityTypeAndSuperTypes = request.getEnd2EntityTypeAndAllSuperTypes(); + + final Set end2Classifications = new HashSet(request.getEnd2EntityClassifications()); + Set classificationsWithSuperTypesEnd2 = new HashSet(); + for (AtlasClassification classificationToAuthorize : end2Classifications) { + classificationsWithSuperTypesEnd2.addAll(request.getClassificationTypeAndAllSuperTypes(classificationToAuthorize.getTypeName())); + } + + rangerResource.setValue(RESOURCE_END_TWO_ENTITY_TYPE, end2EntityTypeAndSuperTypes); + rangerResource.setValue(RESOURCE_END_TWO_ENTITY_CLASSIFICATION, classificationsWithSuperTypesEnd2); + rangerResource.setValue(RESOURCE_END_TWO_ENTITY_ID, end2EntityId); + + + auditEvents = new HashMap<>(); + resourceType = rangerResource.getLeafName(); + resourcePath = rangerResource.getAsString(); + } + + public void processResult(AccessResult result, AtlasAccessRequest request) { + + AuthzAuditEvent auditEvent = getAuthzEvents(result, request); + + if (auditEvent != null) { + // audit event might have list of entity-types and classification-types; overwrite with the values in original request + if (resourcePath != null) { + auditEvent.setResourcePath(resourcePath); + } + + if (resourceType != null) { + auditEvent.setResourceType(resourceType); + } + + if (StringUtils.isNotEmpty(result.getPolicyId())) { + auditEvent.setPolicyId(result.getPolicyId()); + } + + auditEvents.put(auditEvent.getPolicyId() + auditEvent.getAccessType(), auditEvent); + } + } + + public void flushAudit() { + if (auditEvents != null) { + for (AuthzAuditEvent auditEvent : auditEvents.values()) { + logAuthzAudit(auditEvent); + } + } + } + + private void logAuthzAudit(AuthzAuditEvent auditEvent) { + if(auditEvent != null) { + populateDefaults(auditEvent); + + AuditHandler auditProvider = AuditProviderFactory.getInstance().getAuditProvider(); + if (auditProvider == null || !auditProvider.log(auditEvent)) { + LOG.warn("fail to log audit event " + auditEvent); + } + } + } + + private void populateDefaults(AuthzAuditEvent auditEvent) { + auditEvent.setUser(AuthorizerCommon.getCurrentUserName()); + + if (auditEvent.getAgentHostname() == null || auditEvent.getAgentHostname().isEmpty()) { + auditEvent.setAgentHostname(MiscUtil.getHostname()); + } + + if (auditEvent.getLogType() == null || auditEvent.getLogType().isEmpty()) { + auditEvent.setLogType("NewAuthZAudit"); + } + + if (auditEvent.getEventId() == null || auditEvent.getEventId().isEmpty()) { + auditEvent.setEventId(generateNextAuditEventId()); + } + + if (auditEvent.getAgentId() == null) { + auditEvent.setAgentId(MiscUtil.getApplicationType()); + } + + auditEvent.setSeqNum(sequenceNumber++); + } + + private String generateNextAuditEventId() { + final String ret; + + ret = RequestContext.get().getTraceId() + "-" + System.currentTimeMillis(); + + + return ret; + } + + public AuthzAuditEvent getAuthzEvents(AccessResult result, AtlasAccessRequest request) { + AuthzAuditEvent ret = null; + + if(request != null) { + ret = new AuthzAuditEvent(); + + ret.setRepositoryName("atlas"); + ret.setEventTime(request.getAccessTime() != null ? request.getAccessTime() : new Date()); + ret.setAction(request.getAction().getType()); + ret.setAccessResult((short) (result.isAllowed() ? 1 : 0)); + ret.setAccessType(request.getAction().getType()); + ret.setClientIP(RequestContext.get().getClientIPAddress()); + /*Set tags = getTags(request); + if (tags != null) { + ret.setTags(tags); + }*/ + ret.setAgentHostname(MiscUtil.getHostname()); + + populateDefaults(ret); + + //result.setAuditLogId(ret.getEventId()); + } + + return ret; + } +} \ No newline at end of file diff --git a/repository/src/main/java/org/apache/atlas/authorizer/authorizers/AuthorizerCommon.java b/repository/src/main/java/org/apache/atlas/authorizer/authorizers/AuthorizerCommon.java new file mode 100644 index 0000000000..648ba1d196 --- /dev/null +++ b/repository/src/main/java/org/apache/atlas/authorizer/authorizers/AuthorizerCommon.java @@ -0,0 +1,107 @@ +package org.apache.atlas.authorizer.authorizers; + +import org.apache.atlas.exception.AtlasBaseException; +import org.apache.atlas.model.instance.AtlasEntity; +import org.apache.atlas.repository.graphdb.AtlasGraph; +import org.apache.atlas.repository.graphdb.AtlasVertex; +import org.apache.atlas.repository.store.graph.v2.EntityGraphRetriever; +import org.apache.atlas.type.AtlasEntityType; +import org.apache.atlas.type.AtlasTypeRegistry; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.security.core.Authentication; +import org.springframework.security.core.context.SecurityContextHolder; +import org.springframework.stereotype.Component; + +import javax.inject.Inject; +import java.util.Collections; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Set; + +@Component +public class AuthorizerCommon { + private static final Logger LOG = LoggerFactory.getLogger(AuthorizerCommon.class); + + private static AtlasTypeRegistry typeRegistry; + private static EntityGraphRetriever entityRetriever; + + @Inject + public AuthorizerCommon(AtlasGraph graph, AtlasTypeRegistry typeRegistry) { + this.typeRegistry = typeRegistry; + this.entityRetriever = new EntityGraphRetriever(graph, typeRegistry, true); + } + + public static String getCurrentUserName() { + Authentication auth = SecurityContextHolder.getContext().getAuthentication(); + + return auth != null ? auth.getName() : ""; + } + + public static boolean arrayListContains(List listA, List listB) { + for (String listAItem : listA){ + if (listB.contains(listAItem)) { + return true; + } + } + return false; + } + + public static Map getMap(String key, Object value) { + Map map = new HashMap<>(); + map.put(key, value); + return map; + } + + public static boolean listStartsWith(String value, List list) { + for (String item : list){ + if (item.startsWith(value)) { + return true; + } + } + return false; + } + + public static boolean listMatchesWith(String value, List list) { + for (String item : list){ + if (item.matches(value.replace("*", ".*"))) { + return true; + } + } + return false; + } + + public static boolean listEndsWith(String value, List list) { + for (String item : list){ + if (item.endsWith(value)) { + return true; + } + } + return false; + } + + public static Set getTypeAndSupertypesList(String typeName) { + AtlasEntityType entityType = typeRegistry.getEntityTypeByName(typeName); + + if (entityType == null) { + return Collections.singleton(typeName); + } else { + return entityType.getTypeAndAllSuperTypes(); + } + } + + public static AtlasEntityType getEntityTypeByName(String typeName) { + return typeRegistry.getEntityTypeByName(typeName); + } + + public static AtlasEntity toAtlasEntityHeaderWithClassifications(String guid) throws AtlasBaseException { + //return new AtlasEntity(entityRetriever.toAtlasEntityHeaderWithClassifications(guid)); + return new AtlasEntity(entityRetriever.toAtlasEntity(guid)); + } + + public static AtlasEntity toAtlasEntityHeaderWithClassifications(AtlasVertex vertex) throws AtlasBaseException { + //return new AtlasEntity(entityRetriever.toAtlasEntityHeaderWithClassifications(vertex)); + return new AtlasEntity(entityRetriever.toAtlasEntity(vertex)); + } +} 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 new file mode 100644 index 0000000000..cbad556c3a --- /dev/null +++ b/repository/src/main/java/org/apache/atlas/authorizer/authorizers/EntityAuthorizer.java @@ -0,0 +1,469 @@ +package org.apache.atlas.authorizer.authorizers; + +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.ObjectMapper; +import org.apache.atlas.RequestContext; +import org.apache.atlas.authorize.AtlasAuthorizationUtils; +import org.apache.atlas.authorizer.AccessResult; +import org.apache.atlas.authorizer.store.PoliciesStore; +import org.apache.atlas.exception.AtlasBaseException; +import org.apache.atlas.model.instance.AtlasClassification; +import org.apache.atlas.model.instance.AtlasEntity; +import org.apache.atlas.plugin.model.RangerPolicy; +import org.apache.atlas.repository.graphdb.AtlasVertex; +import org.apache.atlas.repository.graphdb.janus.AtlasElasticsearchQuery; +import org.apache.atlas.repository.store.graph.v2.AtlasGraphUtilsV2; +import org.apache.atlas.utils.AtlasPerfMetrics; +import org.apache.commons.collections.CollectionUtils; +import org.apache.commons.lang.StringUtils; +import org.elasticsearch.client.RestClient; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collection; +import java.util.Collections; +import java.util.List; +import java.util.Map; +import java.util.Optional; +import java.util.Set; +import java.util.stream.Collectors; + +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; +import static org.apache.atlas.repository.Constants.QUALIFIED_NAME; +import static org.apache.atlas.repository.graphdb.janus.AtlasElasticsearchDatabase.getLowLevelClient; + +public class EntityAuthorizer { + + private static final Logger LOG = LoggerFactory.getLogger(AtlasAuthorizationUtils.class); + + public static AccessResult isAccessAllowedInMemory(AtlasEntity entity, String action) { + AccessResult result; + + result = isAccessAllowedInMemory(entity, action, POLICY_TYPE_DENY); + if (result.isAllowed()) { + result.setAllowed(false); + return result; + } + + return isAccessAllowedInMemory(entity, action, POLICY_TYPE_ALLOW); + } + + public static AccessResult isAccessAllowedInMemory(AtlasEntity entity, String action, String policyType) { + AtlasPerfMetrics.MetricRecorder recorder = RequestContext.get().startMetricRecord("isAccessAllowedInMemory."+policyType); + AccessResult result; + + List policies = PoliciesStore.getRelevantPolicies(null, null, "atlas_abac", Arrays.asList(action), policyType); + result = evaluateABACPoliciesInMemory(policies, entity); + + if (!result.isAllowed()) { + List tagPolicies = PoliciesStore.getRelevantPolicies(null, null, "atlas_tag", Collections.singletonList(action), policyType); + List resourcePolicies = PoliciesStore.getRelevantPolicies(null, null, "atlas", Collections.singletonList(action), policyType); + + tagPolicies.addAll(resourcePolicies); + + result = evaluateRangerPoliciesInMemory(tagPolicies, entity); + } + + RequestContext.get().endMetricRecord(recorder); + return result; + } + + public static AccessResult evaluateRangerPoliciesInMemory(List resourcePolicies, AtlasEntity entity) { + AtlasPerfMetrics.MetricRecorder recorder = RequestContext.get().startMetricRecord("validateResourcesForCreateEntityInMemory"); + AccessResult result = new AccessResult(); + + Set entityTypes = AuthorizerCommon.getTypeAndSupertypesList(entity.getTypeName()); + + for (RangerPolicy rangerPolicy : resourcePolicies) { + boolean evaluation = evaluateRangerPolicyInMemory(rangerPolicy, entity, entityTypes); + + if (evaluation) { + result.setAllowed(true); + result.setPolicyId(rangerPolicy.getGuid()); + return result; + } + } + + RequestContext.get().endMetricRecord(recorder); + return result; + } + + public static boolean evaluateRangerPolicyInMemory(RangerPolicy rangerPolicy, AtlasEntity entity, Set entityTypes) { + Map resources = rangerPolicy.getResources(); + + boolean allStar = true; + + for (String resource : resources.keySet()) { + if (!resources.get(resource).getValues().contains("*")){ + allStar = false; + break; + } + } + + if (allStar) { + return true; + + } else { + boolean resourcesMatched = true; + + for (String resource : resources.keySet()) { + List 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 (!match) { + resourcesMatched = false; + break; + } + } + + if ("entity".equals(resource)) { + if (!values.contains(("*"))) { + String assetQualifiedName = (String) entity.getAttribute(QUALIFIED_NAME); + Optional match = values.stream().filter(x -> assetQualifiedName.matches(x + .replace("{USER}", AuthorizerCommon.getCurrentUserName()) + .replace("*", ".*"))) + .findFirst(); + + if (!match.isPresent()) { + resourcesMatched = false; + break; + } + } + } + + if ("entity-business-metadata".equals(resource)) { + if (!values.contains(("*"))) { + String assetQualifiedName = (String) entity.getAttribute(QUALIFIED_NAME); + Optional match = values.stream().filter(x -> assetQualifiedName.matches(x + .replace("{USER}", AuthorizerCommon.getCurrentUserName()) + .replace("*", ".*"))) + .findFirst(); + + if (!match.isPresent()) { + resourcesMatched = false; + break; + } + } + } + + //for tag based policy + if ("tag".equals(resource)) { + 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; + break; + } + + List assetTags = entity.getClassifications().stream().map(x -> x.getTypeName()).collect(Collectors.toList()); + + for (String assetTag : assetTags) { + Optional match = values.stream().filter(x -> assetTag.matches(x.replace("*", ".*"))).findFirst(); + + if (!match.isPresent()) { + resourcesMatched = false; + break; + } + } + } + } + } + + if (resourcesMatched) { + LOG.info("Matched with policy: {}:{}", rangerPolicy.getName(), rangerPolicy.getGuid()); + return true; + } + } + + return false; + } + + public static AccessResult evaluateABACPoliciesInMemory(List abacPolicies, AtlasEntity entity) { + AccessResult result = new AccessResult(); + + AtlasVertex vertex = AtlasGraphUtilsV2.findByGuid(entity.getGuid()); + ObjectMapper mapper = new ObjectMapper(); + + for (RangerPolicy policy : abacPolicies) { + String filterCriteria = policy.getPolicyFilterCriteria(); + + boolean matched = false; + JsonNode filterCriteriaNode = null; + try { + filterCriteriaNode = mapper.readTree(filterCriteria); + } catch (JsonProcessingException e) { + e.printStackTrace(); + } + if (filterCriteriaNode != null && filterCriteriaNode.get("entity") != null) { + JsonNode entityFilterCriteriaNode = filterCriteriaNode.get("entity"); + matched = validateFilterCriteriaWithEntity(entityFilterCriteriaNode, entity, vertex); + } + if (matched) { + LOG.info("Matched with policy {}", policy.getGuid()); + result.setAllowed(true); + result.setPolicyId(policy.getGuid()); + return result; + } + } + return result; + } + + public static boolean validateFilterCriteriaWithEntity(JsonNode data, AtlasEntity entity, AtlasVertex vertex) { + AtlasPerfMetrics.MetricRecorder recorder = RequestContext.get().startMetricRecord("validateFilterCriteriaWithEntity"); + String condition = data.get("condition").asText(); + JsonNode criterion = data.get("criterion"); + + if (criterion.size() == 0) { + return false; + } + boolean result = true; + + for (JsonNode crit : criterion) { + + result = true; + if (condition.equals("OR")) { + result = false; + } + boolean evaluation = false; + + if (crit.has("condition")) { + evaluation = validateFilterCriteriaWithEntity(crit, entity, vertex); + } else { + evaluation = evaluateFilterCriteriaInMemory(crit, entity, vertex); + } + + if (condition.equals("AND")) { + if (!evaluation) { + return false; + } + result = true; + } else { + result = result || evaluation; + } + } + + RequestContext.get().endMetricRecord(recorder); + return result; + } + + private static boolean evaluateFilterCriteriaInMemory(JsonNode crit, AtlasEntity entity, AtlasVertex vertex) { + AtlasPerfMetrics.MetricRecorder recorder = RequestContext.get().startMetricRecord("evaluateFilterCriteria"); + + String attributeName = crit.get("attributeName").asText(); + + if (attributeName.endsWith(".text")) { + attributeName = attributeName.replace(".text", ""); + } else if (attributeName.endsWith(".keyword")) { + attributeName = attributeName.replace(".keyword", ""); + } + + List entityAttributeValues = new ArrayList<>(); + + switch (attributeName) { + case "__traitNames": + List tags = entity.getClassifications(); + if (tags != null) { + for (AtlasClassification tag: tags) { + if (StringUtils.isEmpty(tag.getEntityGuid()) || tag.getEntityGuid().equals(entity.getGuid())) { + entityAttributeValues.add(tag.getTypeName()); + } + } + } + break; + + case "__propagatedTraitNames": + tags = entity.getClassifications(); + if (tags != null) { + for (AtlasClassification tag: tags) { + if (StringUtils.isNotEmpty(tag.getEntityGuid()) && !tag.getEntityGuid().equals(entity.getGuid())) { + entityAttributeValues.add(tag.getTypeName()); + } + } + } + break; + + default: + Object attrValue = entity.getAttribute(attributeName); + if (attrValue != null) { + if (attrValue instanceof Collection) { + entityAttributeValues.addAll((Collection) entity.getAttribute(attributeName)); + } else { + entityAttributeValues.add((String) entity.getAttribute(attributeName)); + } + } else { + // try fetching from vertex + if (vertex != null) { + entityAttributeValues.addAll(vertex.getPropertyValues(attributeName, String.class)); + } + } + } + + String operator = crit.get("operator").asText(); + String attributeValue = crit.get("attributeValue").asText(); + + switch (operator) { + case "EQUALS": + if (entityAttributeValues.contains(attributeValue)) { + return true; + } + break; + case "STARTS_WITH": + if (AuthorizerCommon.listStartsWith(attributeValue, entityAttributeValues)) { + return true; + } + break; + case "LIKE": + if (AuthorizerCommon.listMatchesWith(attributeValue, entityAttributeValues)) { + return true; + } + break; + case "ENDS_WITH": + if (AuthorizerCommon.listEndsWith(attributeValue, entityAttributeValues)) { + return true; + } + break; + case "NOT_EQUALS": + if (!entityAttributeValues.contains(attributeValue)) { + return true; + } + break; +/* + case "IN": + break; + case "NOT_IN": + break; +*/ + + default: LOG.warn("Found unknown operator {}", operator); + } + + RequestContext.get().endMetricRecord(recorder); + return false; + } + + public static AccessResult isAccessAllowed(String guid, String action) throws AtlasBaseException { + AtlasPerfMetrics.MetricRecorder recorder = RequestContext.get().startMetricRecord("EntityAuthorizer.isAccessAllowed"); + AccessResult result = new AccessResult(); + + if (guid == null) { + return result; + } + List> filterClauseList = new ArrayList<>(); + Map policiesDSL = getElasticsearchDSL(null, null, true, Arrays.asList(action)); + filterClauseList.add(policiesDSL); + filterClauseList.add(getMap("term", getMap("__guid", guid))); + Map dsl = getMap("query", getMap("bool", getMap("filter", filterClauseList))); + + result = runESQueryAndEvaluateAccess(dsl); + + RequestContext.get().endMetricRecord(recorder); + return result; + } + + public static AccessResult isAccessAllowedEvaluator(String entityTypeName, String entityQualifiedName, String action) throws AtlasBaseException { + + List> filterClauseList = new ArrayList<>(); + Map policiesDSL = getElasticsearchDSL(null, null, true, Arrays.asList(action)); + filterClauseList.add(policiesDSL); + filterClauseList.add(getMap("wildcard", getMap("__typeName.keyword", entityTypeName))); + 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(); + Map response = null; + + try { + + try { + String dslString = mapper.writeValueAsString(dsl); + response = runElasticsearchQuery(dslString); + LOG.info(dslString); + } catch (JsonProcessingException | AtlasBaseException 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)) { + 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"); + } + } + + return result; + } + } + } finally { + RequestContext.get().endMetricRecord(recorder); + } + + return result; + } + + public static Map getElasticsearchDSL(String persona, String purpose, + boolean requestMatchedPolicyId, List actions) { + AtlasPerfMetrics.MetricRecorder recorder = RequestContext.get().startMetricRecord("EntityAuthorizer.getElasticsearchDSL"); + Map dsl = ListAuthorizer.getElasticsearchDSLForPolicyType(persona, purpose, actions, requestMatchedPolicyId, null); + + List> finaDsl = new ArrayList<>(); + if (dsl != null) { + finaDsl.add(dsl); + } + + RequestContext.get().endMetricRecord(recorder); + return getMap("bool", getMap("filter", getMap("bool", getMap("should", finaDsl)))); + } + + private static Integer getCountFromElasticsearch(String query) throws AtlasBaseException { + AtlasPerfMetrics.MetricRecorder recorder = RequestContext.get().startMetricRecord("EntityAuthorizer.getCountFromElasticsearch"); + + Map elasticsearchResult = runElasticsearchQuery(query); + Integer count = null; + if (elasticsearchResult!=null) { + count = (Integer) elasticsearchResult.get("total"); + } + RequestContext.get().endMetricRecord(recorder); + return count; + } + + private static Map runElasticsearchQuery(String query) throws AtlasBaseException { + AtlasPerfMetrics.MetricRecorder recorder = RequestContext.get().startMetricRecord("EntityAuthorizer.runElasticsearchQuery"); + RestClient restClient = getLowLevelClient(); + AtlasElasticsearchQuery elasticsearchQuery = new AtlasElasticsearchQuery("janusgraph_vertex_index", restClient); + + 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 new file mode 100644 index 0000000000..420aa0a426 --- /dev/null +++ b/repository/src/main/java/org/apache/atlas/authorizer/authorizers/ListAuthorizer.java @@ -0,0 +1,352 @@ +package org.apache.atlas.authorizer.authorizers; + +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.JsonToElasticsearchQuery; +import org.apache.atlas.authorizer.store.PoliciesStore; +import org.apache.atlas.plugin.model.RangerPolicy; +import org.apache.atlas.type.AtlasType; +import org.apache.atlas.utils.AtlasPerfMetrics; +import org.apache.commons.collections.CollectionUtils; +import org.apache.commons.collections.MapUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.util.ArrayList; +import java.util.Base64; +import java.util.HashMap; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Set; + +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; +import static org.apache.atlas.authorizer.authorizers.AuthorizerCommon.getMap; + +public class ListAuthorizer { + private static final Logger LOG = LoggerFactory.getLogger(AtlasAuthorizationUtils.class); + + public static Map getElasticsearchDSL(String persona, String purpose, List actions) { + AtlasPerfMetrics.MetricRecorder recorder = RequestContext.get().startMetricRecord("ListAuthorizer.getElasticsearchDSL"); + Map allowDsl = getElasticsearchDSLForPolicyType(persona, purpose, actions, false, POLICY_TYPE_ALLOW); + Map denyDsl = getElasticsearchDSLForPolicyType(persona, purpose, actions, false, POLICY_TYPE_DENY); + Map finaDsl = new HashMap<>(); + if (allowDsl != null) { + finaDsl.put("filter", allowDsl); + } + if (denyDsl != null) { + finaDsl.put("must_not", denyDsl); + } + + RequestContext.get().endMetricRecord(recorder); + return getMap("bool", finaDsl); + } + + public static Map getElasticsearchDSLForPolicyType(String persona, String purpose, + List actions, boolean requestMatchedPolicyId, + String policyType) { + AtlasPerfMetrics.MetricRecorder recorder = RequestContext.get().startMetricRecord("ListAuthorizer.getElasticsearchDSLForPolicyType."+ policyType); + + List resourcePolicies = PoliciesStore.getRelevantPolicies(persona, purpose, "atlas", actions, policyType); + List tagPolicies = PoliciesStore.getRelevantPolicies(persona, purpose, "atlas_tag", actions, policyType); + List abacPolicies = PoliciesStore.getRelevantPolicies(persona, purpose, "atlas_abac", actions, policyType); + + List> shouldClauses = new ArrayList<>(); + if (requestMatchedPolicyId) { + shouldClauses.addAll(getDSLForResourcePoliciesPerPolicy(resourcePolicies)); + shouldClauses.addAll(getDSLForTagPoliciesPerPolicy(tagPolicies)); + shouldClauses.addAll(getDSLForAbacPoliciesPerPolicy(abacPolicies)); + } else { + shouldClauses.addAll(getDSLForResourcePolicies(resourcePolicies)); + Map tagDsl = getDSLForTagPolicies(tagPolicies); + if (MapUtils.isNotEmpty(tagDsl)) { + shouldClauses.add(tagDsl); + } + shouldClauses.addAll(getDSLForAbacPolicies(abacPolicies)); + } + + LOG.info("Applicable policies to user {}", resourcePolicies.size() + tagPolicies.size() + abacPolicies.size()); + + Map boolClause = new HashMap<>(); + if (shouldClauses.isEmpty()) { + if (POLICY_TYPE_ALLOW.equals(policyType)) { + boolClause.put("must_not", getMap("match_all", new HashMap<>())); + } else { + return null; + } + + } else { + if (shouldClauses.size() > MAX_CLAUSE_LIMIT) { + List> splittedShould = new ArrayList<>(); + List>> partitionedShouldClause = Lists.partition(shouldClauses, MAX_CLAUSE_LIMIT); + + for (List> chunk : partitionedShouldClause) { + splittedShould.add(getMap("bool", getMap("should", chunk))); + } + boolClause.put("should", splittedShould); + + } else { + boolClause.put("should", shouldClauses); + } + + boolClause.put("minimum_should_match", 1); + } + + RequestContext.get().endMetricRecord(recorder); + return getMap("bool", boolClause); + } + + public static List> getDSLForResourcePolicies(List policies) { + + // To reduce the number of clauses + List combinedEntities = new ArrayList<>(); + Set combinedEntityTypes = new HashSet<>(); + List> shouldClauses = new ArrayList<>(); + + for (RangerPolicy policy : policies) { + if (!policy.getResources().isEmpty() && "ENTITY".equals(policy.getPolicyResourceCategory())) { + List entities = policy.getResources().get("entity").getValues(); + List entityTypesRaw = policy.getResources().get("entity-type").getValues(); + + if (entities.contains("*") && entityTypesRaw.contains("*")) { + Map emptyMap = new HashMap<>(); + shouldClauses.clear(); + shouldClauses.add(getMap("match_all",emptyMap)); + break; + } + + entities.remove("*"); + entityTypesRaw.remove("*"); + + //Set entityTypes = new HashSet<>(); + //entityTypesRaw.forEach(x -> entityTypes.addAll(AuthorizerCommon.getTypeAndSupertypesList(x))); + + if (!entities.isEmpty() && entityTypesRaw.isEmpty()) { + combinedEntities.addAll(entities); + } else if (entities.isEmpty() && !entityTypesRaw.isEmpty()) { + combinedEntityTypes.addAll(entityTypesRaw); + } else if (!entities.isEmpty() && !entityTypesRaw.isEmpty()) { + Map dslForPolicyResources = getDSLForResources(entities, new HashSet<>(entityTypesRaw), null, null); + shouldClauses.add(dslForPolicyResources); + } + } + } + if (!combinedEntities.isEmpty()) { + shouldClauses.add(getDSLForResources(combinedEntities, new HashSet<>(), null, null)); + } + if (!combinedEntityTypes.isEmpty()) { + shouldClauses.add(getDSLForResources(new ArrayList<>(), combinedEntityTypes, null, null)); + } + return shouldClauses; + } + + public static Map getDSLForResources(List entities, Set typeNames, List classifications, String clauseName){ + List> shouldClauses = new ArrayList<>(); + List termsQualifiedNames = new ArrayList<>(); + for (String entity: entities) { + if (!entity.equals("*")) { + if (entity.contains("*")) { + shouldClauses.add(getMap("wildcard", getMap("qualifiedName", entity))); + } else { + termsQualifiedNames.add(entity); + } + } + } + if (!termsQualifiedNames.isEmpty()) { + shouldClauses.add(getMap("terms", getMap("qualifiedName", termsQualifiedNames))); + } + + Map boolClause = new HashMap<>(); + + if (!shouldClauses.isEmpty()) { + boolClause.put("should", shouldClauses); + boolClause.put("minimum_should_match", 1); + } + + List> filterClauses = new ArrayList<>(); + + if (!typeNames.isEmpty() && !typeNames.contains("*")) { + List> typeClauses = new ArrayList<>(); + typeClauses.add(getMap("terms", getMap("__typeName.keyword", typeNames))); + typeClauses.add(getMap("terms", getMap("__superTypeNames.keyword", typeNames))); + + filterClauses.add(getMap("bool", getMap("should", typeClauses))); + } + + if (classifications != null && !classifications.isEmpty() && !classifications.contains("*")) { + List> classificationClauses = new ArrayList<>(); + + classificationClauses.add(getMap("terms", getMap("__traitNames", classifications))); + classificationClauses.add(getMap("terms", getMap("__propagatedTraitNames", classifications))); + + filterClauses.add(getMap("bool", getMap("should", classificationClauses))); + } + + if (!filterClauses.isEmpty()) { + boolClause.put("filter", filterClauses); + } + + if (clauseName != null) { + boolClause.put("_name", clauseName); + } + + return getMap("bool", boolClause); + } + + public static Map getDSLForTagPolicies(List policies) { + // To reduce the number of clauses + Set allTags = new HashSet<>(); + LOG.info("Found {} tag policies", policies.size()); + + for (RangerPolicy policy : policies) { + if (!policy.getResources().isEmpty()) { + LOG.info("policy {}", AtlasType.toJson(policy)); + List tags = policy.getResources().get("tag").getValues(); + if (!tags.isEmpty()) { + allTags.addAll(tags); + } + } + } + if (!allTags.isEmpty()) { + return getDSLForTags(allTags); + } + return null; + } + + public static List> getDSLForAbacPolicies(List policies) { + List dslList = new ArrayList<>(); + ObjectMapper mapper = new ObjectMapper(); + + for (RangerPolicy policy : policies) { + String filterCriteria = policy.getPolicyFilterCriteria(); + if (filterCriteria != null && !filterCriteria.isEmpty() ) { + JsonNode filterCriteriaNode = null; + try { + filterCriteriaNode = mapper.readTree(filterCriteria); + } catch (JsonProcessingException e) { + e.printStackTrace(); + } + if (filterCriteriaNode != null && filterCriteriaNode.get("entity") != null) { + JsonNode entityFilterCriteriaNode = filterCriteriaNode.get("entity"); + JsonNode dsl = JsonToElasticsearchQuery.convertJsonToQuery(entityFilterCriteriaNode, mapper); + dslList.add(dsl.toString()); + } + } + } + + List> clauses = new ArrayList<>(); + for (String dsl: dslList) { + String policyDSLBase64 = Base64.getEncoder().encodeToString(dsl.getBytes());; + clauses.add(getMap("wrapper", getMap("query", policyDSLBase64))); + } + return clauses; + } + + public static List> getDSLForResourcePoliciesPerPolicy(List policies) { + + List> shouldClauses = new ArrayList<>(); + + for (RangerPolicy policy : policies) { + if (!policy.getResources().isEmpty() && "ENTITY".equals(policy.getPolicyResourceCategory())) { + List entities = policy.getResources().get("entity").getValues(); + List entityTypesRaw = policy.getResources().get("entity-type").getValues(); + + if (entities.contains("*") && entityTypesRaw.contains("*")) { + shouldClauses.clear(); + shouldClauses.add(getMap("match_all", getMap("_name", policy.getGuid()))); + break; + } + + Map dslForPolicyResources = getDSLForResources(entities, new HashSet<>(entityTypesRaw), null, + policy.getGuid() + getPolicySuffix(policy)); + shouldClauses.add(dslForPolicyResources); + } + } + return shouldClauses; + } + + public static String getPolicySuffix(RangerPolicy policy) { + if (CollectionUtils.isNotEmpty(policy.getDenyPolicyItems())) { + return DENY_POLICY_NAME_SUFFIX; + } + return ""; + } + + public static List> getDSLForTagPoliciesPerPolicy(List policies) { + List> shouldClauses = new ArrayList<>(); + + LOG.info("Found {} tag policies", policies.size()); + + for (RangerPolicy policy : policies) { + if (!policy.getResources().isEmpty()) { + LOG.info("policy {}", AtlasType.toJson(policy)); + List tags = policy.getResources().get("tag").getValues(); + if (!tags.isEmpty()) { + + List> tagsClauses = new ArrayList<>(); + tagsClauses.add(getMap("terms", getMap("__traitNames", tags))); + tagsClauses.add(getMap("terms", getMap("__propagatedTraitNames", tags))); + + Map shouldMap = getMap("should", tagsClauses); + shouldMap.put("minimum_should_match", 1); + shouldMap.put("_name", policy.getGuid() + getPolicySuffix(policy)); + + Map boolClause = getMap("bool", shouldMap); + shouldClauses.add(boolClause); + } + } + } + + return shouldClauses; + } + + public static List> getDSLForAbacPoliciesPerPolicy(List policies) { + ObjectMapper mapper = new ObjectMapper(); + List> clauses = new ArrayList<>(); + + for (RangerPolicy policy : policies) { + String filterCriteria = policy.getPolicyFilterCriteria(); + if (filterCriteria != null && !filterCriteria.isEmpty() ) { + JsonNode filterCriteriaNode = null; + try { + filterCriteriaNode = mapper.readTree(filterCriteria); + } catch (JsonProcessingException e) { + e.printStackTrace(); + } + if (filterCriteriaNode != null && filterCriteriaNode.get("entity") != null) { + JsonNode entityFilterCriteriaNode = filterCriteriaNode.get("entity"); + JsonNode dsl = JsonToElasticsearchQuery.convertJsonToQuery(entityFilterCriteriaNode, mapper); + + String policyDSLBase64 = Base64.getEncoder().encodeToString(dsl.toString().getBytes()); + + Map shouldMap = getMap("should", getMap("wrapper", getMap("query", policyDSLBase64))); + shouldMap.put("_name", policy.getGuid() + getPolicySuffix(policy)); + + Map boolMap = getMap("bool", shouldMap); + clauses.add(boolMap); + } + } + } + + return clauses; + } + + private static Map getDSLForTags(Set tags){ + List> shouldClauses = new ArrayList<>(); + shouldClauses.add(getMap("terms", getMap("__traitNames", tags))); + shouldClauses.add(getMap("terms", getMap("__propagatedTraitNames", tags))); + + Map boolClause = new HashMap<>(); + boolClause.put("should", shouldClauses); + boolClause.put("minimum_should_match", 1); + + return getMap("bool", boolClause); + } +} diff --git a/repository/src/main/java/org/apache/atlas/authorizer/authorizers/RelationshipAuthorizer.java b/repository/src/main/java/org/apache/atlas/authorizer/authorizers/RelationshipAuthorizer.java new file mode 100644 index 0000000000..f2968ee6eb --- /dev/null +++ b/repository/src/main/java/org/apache/atlas/authorizer/authorizers/RelationshipAuthorizer.java @@ -0,0 +1,504 @@ +package org.apache.atlas.authorizer.authorizers; + +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.authorizer.AccessResult; +import org.apache.atlas.authorizer.JsonToElasticsearchQuery; +import org.apache.atlas.authorizer.store.PoliciesStore; +import org.apache.atlas.exception.AtlasBaseException; +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; +import org.apache.atlas.repository.store.graph.v2.AtlasGraphUtilsV2; +import org.apache.atlas.utils.AtlasPerfMetrics; +import org.apache.commons.collections.CollectionUtils; +import org.elasticsearch.client.RestClient; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Base64; +import java.util.Collections; +import java.util.HashMap; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Optional; +import java.util.Set; +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; +import static org.apache.atlas.authorizer.authorizers.AuthorizerCommon.getMap; +import static org.apache.atlas.authorizer.authorizers.EntityAuthorizer.validateFilterCriteriaWithEntity; +import static org.apache.atlas.authorizer.authorizers.ListAuthorizer.getDSLForResources; +import static org.apache.atlas.authorizer.authorizers.ListAuthorizer.getPolicySuffix; +import static org.apache.atlas.repository.Constants.QUALIFIED_NAME; +import static org.apache.atlas.repository.graphdb.janus.AtlasElasticsearchDatabase.getLowLevelClient; + +public class RelationshipAuthorizer { + + private static final Logger LOG = LoggerFactory.getLogger(RelationshipAuthorizer.class); + + public static AccessResult isAccessAllowedInMemory(String action, String relationshipType, AtlasEntityHeader endOneEntity, AtlasEntityHeader endTwoEntity) throws AtlasBaseException { + AccessResult result; + + result = checkRelationshipAccessAllowedInMemory(action, relationshipType, endOneEntity, endTwoEntity, POLICY_TYPE_DENY); + if (result.isAllowed()) { + result.setAllowed(false); + return result; + } + + return checkRelationshipAccessAllowedInMemory(action, relationshipType, endOneEntity, endTwoEntity, POLICY_TYPE_ALLOW); + } + + public static AccessResult checkRelationshipAccessAllowedInMemory(String action, String relationshipType, AtlasEntityHeader endOneEntity, + AtlasEntityHeader endTwoEntity, String policyType) throws AtlasBaseException { + //Relationship add, update, remove access check in memory + AtlasPerfMetrics.MetricRecorder recorder = RequestContext.get().startMetricRecord("checkRelationshipAccessAllowedInMemory."+policyType); + AccessResult result = new AccessResult(); + + try { + List policies = PoliciesStore.getRelevantPolicies(null, null, "atlas_abac", Arrays.asList(action), policyType); + ObjectMapper mapper = new ObjectMapper(); + AtlasVertex oneVertex = AtlasGraphUtilsV2.findByGuid(endOneEntity.getGuid()); + AtlasVertex twoVertex = AtlasGraphUtilsV2.findByGuid(endTwoEntity.getGuid()); + + //boolean ret = false; + //boolean eval; + + for (RangerPolicy policy : policies) { + String filterCriteria = policy.getPolicyFilterCriteria(); + + boolean eval = false; + JsonNode filterCriteriaNode = null; + try { + filterCriteriaNode = mapper.readTree(filterCriteria); + } catch (JsonProcessingException e) { + e.printStackTrace(); + } + if (filterCriteriaNode != null && filterCriteriaNode.get("endOneEntity") != null) { + JsonNode entityFilterCriteriaNode = filterCriteriaNode.get("endOneEntity"); + eval = validateFilterCriteriaWithEntity(entityFilterCriteriaNode, new AtlasEntity(endOneEntity), oneVertex); + + if (eval) { + entityFilterCriteriaNode = filterCriteriaNode.get("endTwoEntity"); + eval = validateFilterCriteriaWithEntity(entityFilterCriteriaNode, new AtlasEntity(endTwoEntity), twoVertex); + } + } + //ret = ret || eval; + if (eval) { + result.setAllowed(true); + result.setPolicyId(policy.getGuid()); + break; + } + } + + if (!result.isAllowed()) { + List rangerPolicies = PoliciesStore.getRelevantPolicies(null, null, "atlas_tag", Collections.singletonList(action), policyType); + rangerPolicies.addAll(PoliciesStore.getRelevantPolicies(null, null, "atlas", Collections.singletonList(action), policyType)); + + result = evaluateRangerPoliciesInMemory(rangerPolicies, relationshipType, endOneEntity, endTwoEntity); + } + + return result; + } finally { + RequestContext.get().endMetricRecord(recorder); + } + } + + public static AccessResult evaluateRangerPoliciesInMemory(List rangerPolicies, String relationshipType, + AtlasEntityHeader endOneEntity, AtlasEntityHeader endTwoEntity) { + AtlasPerfMetrics.MetricRecorder recorder = RequestContext.get().startMetricRecord("ListAuthorizer.evaluateRangerPoliciesInMemory"); + AccessResult result = new AccessResult(); + + Set endOneEntityTypes = AuthorizerCommon.getTypeAndSupertypesList(endOneEntity.getTypeName()); + Set endTwoEntityTypes = AuthorizerCommon.getTypeAndSupertypesList(endTwoEntity.getTypeName()); + + for (RangerPolicy rangerPolicy : rangerPolicies) { + boolean evaluation = evaluateRangerPolicyInMemory(rangerPolicy, relationshipType, endOneEntity, endTwoEntity, endOneEntityTypes, endTwoEntityTypes); + + if (evaluation) { + result.setAllowed(true); + result.setPolicyId(rangerPolicy.getGuid()); + return result; + } + } + + RequestContext.get().endMetricRecord(recorder); + return result; + } + + public static boolean evaluateRangerPolicyInMemory(RangerPolicy rangerPolicy, String relationshipType, + AtlasEntityHeader endOneEntity, AtlasEntityHeader endTwoEntity, + Set endOneEntityTypes, Set endTwoEntityTypes) { + + Map resources = rangerPolicy.getResources(); + + boolean allStar = true; + + for (String resource : resources.keySet()) { + if (!resources.get(resource).getValues().contains("*")){ + allStar = false; + break; + } + } + + if (allStar) { + LOG.info("Matched with policy: {}:{}", rangerPolicy.getName(), rangerPolicy.getGuid()); + return true; + + } else { + boolean resourcesMatched = true; + + for (String resource : resources.keySet()) { + List values = resources.get(resource).getValues(); + + if ("relationship-type".equals(resource)) { + if (!values.contains(("*"))) { + Optional match = values.stream().filter(x -> relationshipType.matches(x + .replace("*", ".*"))) + .findFirst(); + + if (!match.isPresent()) { + resourcesMatched = false; + break; + } + } + } + + if ("end-one-entity-type".equals(resource)) { + if (!values.contains(("*"))) { + boolean match = endOneEntityTypes.stream().anyMatch(assetType -> values.stream().anyMatch(policyAssetType -> assetType.matches(policyAssetType.replace("*", ".*")))); + + if (!match) { + resourcesMatched = false; + break; + } + } + } + + if ("end-two-entity-type".equals(resource)) { + if (!values.contains(("*"))) { + boolean match = endTwoEntityTypes.stream().anyMatch(assetType -> values.stream().anyMatch(policyAssetType -> assetType.matches(policyAssetType.replace("*", ".*")))); + + if (!match) { + resourcesMatched = false; + break; + } + } + } + + if ("end-one-entity".equals(resource)) { + if (!values.contains(("*"))) { + String assetQualifiedName = (String) endOneEntity.getAttribute(QUALIFIED_NAME); + Optional match = values.stream().filter(x -> assetQualifiedName.matches(x + .replace("{USER}", AuthorizerCommon.getCurrentUserName()) + .replace("*", ".*"))) + .findFirst(); + + if (!match.isPresent()) { + resourcesMatched = false; + break; + } + } + } + + if ("end-two-entity".equals(resource)) { + if (!values.contains(("*"))) { + String assetQualifiedName = (String) endTwoEntity.getAttribute(QUALIFIED_NAME); + Optional match = values.stream().filter(x -> assetQualifiedName.matches(x + .replace("{USER}", AuthorizerCommon.getCurrentUserName()) + .replace("*", ".*"))) + .findFirst(); + + if (!match.isPresent()) { + resourcesMatched = false; + break; + } + } + } + + //for tag based policy + if ("end-one-entity-classification".equals(resource)) { + if (!values.contains(("*"))) { + if (endOneEntity.getClassifications() == null || endOneEntity.getClassifications().isEmpty()) { + //since entity does not have tags at all, it should not pass this evaluation + resourcesMatched = false; + break; + } + + List assetTags = endOneEntity.getClassifications().stream().map(x -> x.getTypeName()).collect(Collectors.toList()); + + boolean match = assetTags.stream().anyMatch(assetTag -> values.stream().anyMatch(policyAssetType -> assetTag.matches(policyAssetType.replace("*", ".*")))); + + if (!match) { + resourcesMatched = false; + break; + } + } + } + + if ("end-two-entity-classification".equals(resource)) { + if (!values.contains(("*"))) { + if (endTwoEntity.getClassifications() == null || endTwoEntity.getClassifications().isEmpty()) { + //since entity does not have tags at all, it should not pass this evaluation + resourcesMatched = false; + break; + } + + List assetTags = endTwoEntity.getClassifications().stream().map(x -> x.getTypeName()).collect(Collectors.toList()); + + boolean match = assetTags.stream().anyMatch(assetTag -> values.stream().anyMatch(policyAssetType -> assetTag.matches(policyAssetType.replace("*", ".*")))); + + if (!match) { + resourcesMatched = false; + break; + } + } + } + } + + if (resourcesMatched) { + LOG.info("Matched with policy: {}:{}", rangerPolicy.getName(), rangerPolicy.getGuid()); + return true; + } + } + + return false; + } + + public static AccessResult isRelationshipAccessAllowed(String action, AtlasEntityHeader endOneEntity, AtlasEntityHeader endTwoEntity) throws AtlasBaseException { + AtlasPerfMetrics.MetricRecorder recorder = RequestContext.get().startMetricRecord("RelationshipAuthorizer.isRelationshipAccessAllowed"); + AccessResult result = new AccessResult(); + + //Relationship update, remove access check with ES query + if (endOneEntity == null || endTwoEntity == null || endOneEntity.getGuid() == null || endTwoEntity.getGuid() == null ) { + return result; + } + + try { + Map dsl = getElasticsearchDSLForRelationshipActions(Arrays.asList(action), endOneEntity.getGuid(), endTwoEntity.getGuid()); + ObjectMapper mapper = new ObjectMapper(); + String dslString = mapper.writeValueAsString(dsl); + RestClient restClient = getLowLevelClient(); + AtlasElasticsearchQuery elasticsearchQuery = new AtlasElasticsearchQuery("janusgraph_vertex_index", restClient); + Map elasticsearchResult = elasticsearchQuery.runQueryWithLowLevelClient(dslString); + LOG.info(dslString); + Integer count = null; + if (elasticsearchResult!=null) { + count = (Integer) elasticsearchResult.get("total"); + } + if (count != null && count == 2) { + List> docs = (List>) elasticsearchResult.get("data"); + List matchedClausesEndOne = new ArrayList<>(); + List matchedClausesEndTwo = new ArrayList<>(); + for (Map doc : docs) { + List matched_queries = (List) doc.get("matched_queries"); + if (matched_queries != null && !matched_queries.isEmpty()) { + Map source = (Map) doc.get("_source"); + String guid = (String) source.get("__guid"); + if (endOneEntity.getGuid().equals(guid)) { + for (String matched_query : matched_queries) { + if (matched_query.equals("tag-clause")) { + matchedClausesEndOne.add("tag-clause"); + } else if (matched_query.startsWith("end-one-")) { + matchedClausesEndOne.add(matched_query.substring(8)); + } + } + } else { + for (String matched_query : matched_queries) { + if (matched_query.equals("tag-clause")) { + matchedClausesEndTwo.add("tag-clause"); + } else if (matched_query.startsWith("end-two-")) { + matchedClausesEndTwo.add(matched_query.substring(8)); + } + } + } + } + } + List common = (List) CollectionUtils.intersection(matchedClausesEndOne, matchedClausesEndTwo); + if (!common.isEmpty()) { + Optional denied = common.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(common.get(0)); + } + } + + /*if (arrayListContains(matchedClausesEndOne, matchedClausesEndTwo)) { + result.setAllowed(true); + return result; + }*/ + } + LOG.info(dslString); + } catch (JsonProcessingException e) { + return result; + } finally { + RequestContext.get().endMetricRecord(recorder); + } + return result; + } + + public static Map getElasticsearchDSLForRelationshipActions(List actions, String endOneGuid, String endTwoGuid) throws JsonProcessingException { + AtlasPerfMetrics.MetricRecorder recorder = RequestContext.get().startMetricRecord("RelationshipAuthorizer.getElasticsearchDSLForRelationshipActions"); + + List> policiesClauses = new ArrayList<>(); + List resourcePolicies = PoliciesStore.getRelevantPolicies(null, null, "atlas", actions, POLICY_TYPE_ALLOW); + List> resourcePoliciesClauses = getDSLForRelationshipResourcePolicies(resourcePolicies); + + List tagPolicies = PoliciesStore.getRelevantPolicies(null, null, "atlas_tag", actions, POLICY_TYPE_ALLOW); + List> tagPoliciesClauses = getDSLForRelationshipTagPolicies(tagPolicies); + + List abacPolicies = PoliciesStore.getRelevantPolicies(null, null, "atlas_abac", actions, null); + List> abacPoliciesClauses = getDSLForRelationshipAbacPolicies(abacPolicies); + + policiesClauses.addAll(resourcePoliciesClauses); + policiesClauses.addAll(tagPoliciesClauses); + policiesClauses.addAll(abacPoliciesClauses); + + List> clauses = new ArrayList<>(); + + Map policiesBoolClause = new HashMap<>(); + if (policiesClauses.isEmpty()) { + policiesBoolClause.put("must_not", getMap("match_all", new HashMap<>())); + } else { + //policiesBoolClause.put("should", policiesClauses); + if (policiesClauses.size() > MAX_CLAUSE_LIMIT) { + List> splittedShould = new ArrayList<>(); + List>> partitionedShouldClause = Lists.partition(policiesClauses, MAX_CLAUSE_LIMIT); + + for (List> chunk : partitionedShouldClause) { + splittedShould.add(getMap("bool", getMap("should", chunk))); + } + policiesBoolClause.put("should", splittedShould); + + } else { + policiesBoolClause.put("should", policiesClauses); + } + + policiesBoolClause.put("minimum_should_match", 1); + } + clauses.add(getMap("bool", policiesBoolClause)); + + Map entitiesBoolClause = new HashMap<>(); + List> entityClauses = new ArrayList<>(); + entityClauses.add(getMap("term", getMap("__guid", endOneGuid))); + entityClauses.add(getMap("term", getMap("__guid", endTwoGuid))); + entitiesBoolClause.put("should", entityClauses); + entitiesBoolClause.put("minimum_should_match", 1); + clauses.add(getMap("bool", entitiesBoolClause)); + + Map boolClause = new HashMap<>(); + boolClause.put("filter", clauses); + + + RequestContext.get().endMetricRecord(recorder); + return getMap("query", getMap("bool", boolClause)); + } + + private static List> getDSLForRelationshipResourcePolicies(List policies) { + AtlasPerfMetrics.MetricRecorder recorder = RequestContext.get().startMetricRecord("RelationshipAuthorizer.getDSLForRelationshipResourcePolicies"); + + List> shouldClauses = new ArrayList<>(); + for (RangerPolicy policy : policies) { + if (!policy.getResources().isEmpty() && "RELATIONSHIP".equals(policy.getPolicyResourceCategory())) { + List relationshipEnds = new ArrayList<>(); + relationshipEnds.add("end-one"); + relationshipEnds.add("end-two"); + + for (String relationshipEnd : relationshipEnds) { + String clauseName = relationshipEnd + "-" + policy.getGuid(); + String entityParamName = relationshipEnd + "-entity"; + String entityTypeParamName = relationshipEnd + "-entity-type"; + String entityClassificationParamName = relationshipEnd + "-entity-classification"; + + List entities = policy.getResources().get(entityParamName).getValues(); + List entityTypesRaw = policy.getResources().get(entityTypeParamName).getValues(); + + //Set entityTypes = new HashSet<>(); + //entityTypesRaw.forEach(x -> entityTypes.addAll(getTypeAndSupertypesList(x))); + + List entityClassifications = policy.getResources().get(entityClassificationParamName).getValues(); + if (entities.contains("*") && entityTypesRaw.contains("*") && entityClassifications.contains("*")) { + shouldClauses.add(getMap("match_all", getMap("_name", clauseName))); + } else { + Map dslForPolicyResources = getDSLForResources(entities, new HashSet<>(entityTypesRaw), entityClassifications, clauseName); + shouldClauses.add(dslForPolicyResources); + } + } + } + } + + RequestContext.get().endMetricRecord(recorder); + return shouldClauses; + } + + private static List> getDSLForRelationshipTagPolicies(List policies) { + // To reduce the number of clauses + Set allTags = new HashSet<>(); + for (RangerPolicy policy : policies) { + if (!policy.getResources().isEmpty()) { + List tags = policy.getResources().get("tag").getValues(); + if (!tags.isEmpty()) { + allTags.addAll(tags); + } + } + } + + List> clauses = new ArrayList<>(); + + if (!allTags.isEmpty()) { + Map termsMapA = new HashMap<>(); + termsMapA.put("_name", "tag-clause"); + termsMapA.put("terms", getMap("__traitNames", allTags)); + clauses.add(termsMapA); + + Map termsMapB = new HashMap<>(); + termsMapB.put("_name", "tag-clause"); + termsMapB.put("terms", getMap("__propagatedTraitNames", allTags)); + clauses.add(termsMapB); + } + return clauses; + } + + private static List> getDSLForRelationshipAbacPolicies(List policies) throws JsonProcessingException { + List> shouldClauses = new ArrayList<>(); + for (RangerPolicy policy : policies) { + if ("RELATIONSHIP".equals(policy.getPolicyResourceCategory())) { + String filterCriteria = policy.getPolicyFilterCriteria(); + ObjectMapper mapper = new ObjectMapper(); + JsonNode filterCriteriaNode = mapper.readTree(filterCriteria); + + List relationshipEnds = new ArrayList<>(); + relationshipEnds.add("end-one"); + relationshipEnds.add("end-two"); + + String suffix = getPolicySuffix(policy); + for (String relationshipEnd : relationshipEnds) { + JsonNode endFilterCriteriaNode = filterCriteriaNode.get(relationshipEnd.equals("end-one") ? "endOneEntity" : "endTwoEntity"); + JsonNode Dsl = JsonToElasticsearchQuery.convertJsonToQuery(endFilterCriteriaNode, mapper); + String DslBase64 = Base64.getEncoder().encodeToString(Dsl.toString().getBytes()); + String clauseName = relationshipEnd + "-" + policy.getGuid(); + Map boolMap = new HashMap<>(); + boolMap.put("_name", clauseName + suffix); + boolMap.put("filter", getMap("wrapper", getMap("query", DslBase64))); + + shouldClauses.add(getMap("bool", boolMap)); + } + } + } + return shouldClauses; + } +} diff --git a/repository/src/main/java/org/apache/atlas/authorizer/store/PoliciesStore.java b/repository/src/main/java/org/apache/atlas/authorizer/store/PoliciesStore.java new file mode 100644 index 0000000000..89391e3980 --- /dev/null +++ b/repository/src/main/java/org/apache/atlas/authorizer/store/PoliciesStore.java @@ -0,0 +1,200 @@ +package org.apache.atlas.authorizer.store; + +import org.apache.atlas.RequestContext; +import org.apache.atlas.authorizer.authorizers.AuthorizerCommon; +import org.apache.atlas.plugin.model.RangerPolicy; +import org.apache.atlas.plugin.util.RangerRoles; +import org.apache.atlas.plugin.util.RangerUserStore; +import org.apache.atlas.utils.AtlasPerfMetrics; +import org.apache.commons.collections.CollectionUtils; +import org.apache.commons.lang.StringUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.util.ArrayList; +import java.util.List; +import java.util.stream.Collectors; + +import static org.apache.atlas.authorizer.AuthorizerUtils.POLICY_TYPE_ALLOW; +import static org.apache.atlas.authorizer.AuthorizerUtils.POLICY_TYPE_DENY; + +public class PoliciesStore { + + private static final Logger LOG = LoggerFactory.getLogger(PoliciesStore.class); + + private static List resourcePolicies; + private static List tagPolicies; + private static List abacPolicies; + + private static PoliciesStore policiesStore; + + public static PoliciesStore getInstance() { + synchronized (PoliciesStore.class) { + if (policiesStore == null) { + policiesStore = new PoliciesStore(); + } + return policiesStore; + } + } + + public void setResourcePolicies(List resourcePolicies) { + this.resourcePolicies = resourcePolicies; + } + + private static List getResourcePolicies() { + return resourcePolicies; + } + + public void setTagPolicies(List tagPolicies) { + this.tagPolicies = tagPolicies; + } + + private static List getTagPolicies() { + return tagPolicies; + } + + public void setAbacPolicies(List abacPolicies) { + this.abacPolicies = abacPolicies; + } + + private static List getAbacPolicies() { + return abacPolicies; + } + + public static List getRelevantPolicies(String persona, String purpose, String serviceName, List actions, String policyType) { + return getRelevantPolicies(null, null, serviceName, actions, policyType, false); + } + + public static List getRelevantPolicies(String persona, String purpose, String serviceName, List actions, String policyType, boolean ignoreUser) { + AtlasPerfMetrics.MetricRecorder recorder = RequestContext.get().startMetricRecord("getRelevantPolicies"); + String policyQualifiedNamePrefix = null; + if (persona != null && !persona.isEmpty()) { + policyQualifiedNamePrefix = persona; + } else if (purpose != null && !purpose.isEmpty()) { + policyQualifiedNamePrefix = purpose; + } + + List policies = new ArrayList<>(); + if ("atlas".equals(serviceName)) { + policies = getResourcePolicies(); + } else if ("atlas_tag".equals(serviceName)) { + policies = getTagPolicies(); + } else if ("atlas_abac".equals(serviceName)) { + policies = getAbacPolicies(); + } + + + if (CollectionUtils.isNotEmpty(policies)) { + policies = getFilteredPoliciesForQualifiedName(policies, policyQualifiedNamePrefix); + policies = getFilteredPoliciesForActions(policies, actions, policyType); + + if (!ignoreUser) { + String user = AuthorizerCommon.getCurrentUserName(); + LOG.info("Getting relevant policies for user: {}", user); + + RangerUserStore userStore = UsersStore.getUserStore(); + List groups = UsersStore.getGroupsForUser(user, userStore); + + RangerRoles allRoles = UsersStore.getAllRoles(); + List roles = UsersStore.getRolesForUser(user, allRoles); + roles.addAll(UsersStore.getNestedRolesForUser(roles, allRoles)); + + policies = getFilteredPoliciesForUser(policies, user, groups, roles, policyType); + } + } + + RequestContext.get().endMetricRecord(recorder); + return policies; + } + + static List getFilteredPoliciesForQualifiedName(List policies, String qualifiedNamePrefix) { + AtlasPerfMetrics.MetricRecorder recorder = RequestContext.get().startMetricRecord("getFilteredPoliciesForQualifiedName"); + if (qualifiedNamePrefix != null && !qualifiedNamePrefix.isEmpty()) { + List filteredPolicies = new ArrayList<>(); + for(RangerPolicy policy : policies) { + if (policy.getName().startsWith(qualifiedNamePrefix)) { + filteredPolicies.add(policy); + } + } + return filteredPolicies; + } + + RequestContext.get().endMetricRecord(recorder); + return policies; + } + + private static List getFilteredPoliciesForActions(List policies, List actions, String type) { + AtlasPerfMetrics.MetricRecorder recorder = RequestContext.get().startMetricRecord("getFilteredPoliciesForActions"); + List filteredPolicies = new ArrayList<>(); + + + for(RangerPolicy policy : policies) { + RangerPolicy.RangerPolicyItem policyItem = null; + + if (StringUtils.isNotEmpty(type)) { + if (POLICY_TYPE_ALLOW.equals(type) && !policy.getPolicyItems().isEmpty()) { + policyItem = policy.getPolicyItems().get(0); + } else if (POLICY_TYPE_DENY.equals(type) && !policy.getDenyPolicyItems().isEmpty()) { + policyItem = policy.getDenyPolicyItems().get(0); + } + } else { + if (!policy.getPolicyItems().isEmpty()) { + policyItem = policy.getPolicyItems().get(0); + } else if (!policy.getDenyPolicyItems().isEmpty()) { + policyItem = policy.getDenyPolicyItems().get(0); + } + } + + if (policyItem != null) { + List policyActions = new ArrayList<>(); + if (!policyItem.getAccesses().isEmpty()) { + policyActions = policyItem.getAccesses().stream().map(x -> x.getType()).collect(Collectors.toList()); + } + if (AuthorizerCommon.arrayListContains(policyActions, actions)) { + filteredPolicies.add(policy); + } + } + } + + RequestContext.get().endMetricRecord(recorder); + return filteredPolicies; + } + + private static List getFilteredPoliciesForUser(List policies, String user, List groups, List roles, String type) { + AtlasPerfMetrics.MetricRecorder recorder = RequestContext.get().startMetricRecord("getFilteredPoliciesForUser"); + + List filterPolicies = new ArrayList<>(); + for(RangerPolicy policy : policies) { + RangerPolicy.RangerPolicyItem policyItem = null; + + if (StringUtils.isNotEmpty(type)) { + if (POLICY_TYPE_ALLOW.equals(type) && !policy.getPolicyItems().isEmpty()) { + policyItem = policy.getPolicyItems().get(0); + } else if (POLICY_TYPE_DENY.equals(type) && !policy.getDenyPolicyItems().isEmpty()) { + policyItem = policy.getDenyPolicyItems().get(0); + } + } else { + if (!policy.getPolicyItems().isEmpty()) { + policyItem = policy.getPolicyItems().get(0); + } else if (!policy.getDenyPolicyItems().isEmpty()) { + policyItem = policy.getDenyPolicyItems().get(0); + } + } + + if (policyItem != null) { + List policyUsers = policyItem.getUsers(); + List policyGroups = policyItem.getGroups(); + List policyRoles = policyItem.getRoles(); + if (policyUsers.contains(user) + || policyGroups.contains("public") + || AuthorizerCommon.arrayListContains(policyGroups, groups) + || AuthorizerCommon.arrayListContains(policyRoles, roles)) { + filterPolicies.add(policy); + } + } + } + + RequestContext.get().endMetricRecord(recorder); + return filterPolicies; + } +} diff --git a/repository/src/main/java/org/apache/atlas/authorizer/store/UsersStore.java b/repository/src/main/java/org/apache/atlas/authorizer/store/UsersStore.java new file mode 100644 index 0000000000..4f15b0fa35 --- /dev/null +++ b/repository/src/main/java/org/apache/atlas/authorizer/store/UsersStore.java @@ -0,0 +1,86 @@ +package org.apache.atlas.authorizer.store; + +import org.apache.atlas.authorizer.authorizers.AuthorizerCommon; +import org.apache.atlas.plugin.model.RangerRole; +import org.apache.atlas.plugin.util.RangerRoles; +import org.apache.atlas.plugin.util.RangerUserStore; + +import java.util.ArrayList; +import java.util.List; +import java.util.Map; +import java.util.Set; + +public class UsersStore { + + private static RangerUserStore userStore; + private static RangerRoles allRoles; + private static UsersStore usersStore; + + public static UsersStore getInstance() { + synchronized (UsersStore.class) { + if (usersStore == null) { + usersStore = new UsersStore(); + } + return usersStore; + } + } + + public UsersStore() {} + + public void setUserStore(RangerUserStore userStore) { + this.userStore = userStore; + } + + public static RangerUserStore getUserStore() { + return userStore; + } + + public void setAllRoles(RangerRoles allRoles) { + this.allRoles = allRoles; + } + + public static RangerRoles getAllRoles() { + return allRoles; + } + + public static List getGroupsForUser(String user, RangerUserStore userStore) { + Map> userGroupMapping = userStore.getUserGroupMapping(); + List groups = new ArrayList<>(); + Set groupsSet = userGroupMapping.get(user); + if (groupsSet != null && !groupsSet.isEmpty()) { + groups.addAll(groupsSet); + } + return groups; + } + + public static List getRolesForUser(String user, RangerRoles allRoles) { + List roles = new ArrayList<>(); + Set rangerRoles = allRoles.getRangerRoles(); + for (RangerRole role : rangerRoles) { + List users = role.getUsers(); + for (RangerRole.RoleMember roleUser: users) { + if (roleUser.getName().equals(user)) { + roles.add(role.getName()); + } + } + } + return roles; + } + + public static List getNestedRolesForUser(List userRoles, RangerRoles allRoles) { + List ret = new ArrayList<>(); + Set rangerRoles = allRoles.getRangerRoles(); + for (RangerRole role : rangerRoles) { + List nestedRoles = role.getRoles(); + List nestedRolesName = new ArrayList<>(); + for (RangerRole.RoleMember nestedRole : nestedRoles) { + nestedRolesName.add(nestedRole.getName()); + } + if (AuthorizerCommon.arrayListContains(userRoles, nestedRolesName)) { + ret.add(role.getName()); + } + } + return ret; + } + +} diff --git a/repository/src/main/java/org/apache/atlas/discovery/EntityDiscoveryService.java b/repository/src/main/java/org/apache/atlas/discovery/EntityDiscoveryService.java index da4b3f2d63..f5ed00d2f0 100644 --- a/repository/src/main/java/org/apache/atlas/discovery/EntityDiscoveryService.java +++ b/repository/src/main/java/org/apache/atlas/discovery/EntityDiscoveryService.java @@ -17,11 +17,15 @@ */ package org.apache.atlas.discovery; +import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.node.ObjectNode; import com.google.common.annotations.VisibleForTesting; import org.apache.atlas.*; import org.apache.atlas.annotation.GraphTransaction; import org.apache.atlas.authorize.AtlasAuthorizationUtils; import org.apache.atlas.authorize.AtlasSearchResultScrubRequest; +import org.apache.atlas.authorizer.AuthorizerUtils; import org.apache.atlas.exception.AtlasBaseException; import org.apache.atlas.model.discovery.*; import org.apache.atlas.model.discovery.AtlasSearchResult.AtlasFullTextResult; @@ -39,6 +43,7 @@ import org.apache.atlas.repository.Constants; import org.apache.atlas.repository.graph.GraphBackedSearchIndexer; import org.apache.atlas.repository.graph.GraphHelper; +import org.apache.atlas.repository.audit.ESBasedAuditRepository; import org.apache.atlas.repository.graphdb.*; import org.apache.atlas.repository.graphdb.AtlasIndexQuery.Result; import org.apache.atlas.repository.store.graph.v2.AtlasGraphUtilsV2; @@ -996,6 +1001,10 @@ public AtlasSearchResult directIndexSearch(SearchParams searchParams) throws Atl String indexName = getIndexName(params); indexQuery = graph.elasticsearchQuery(indexName); + if (searchParams.getUseAccessControlv2()) { + addPreFiltersToSearchQuery(searchParams); + } + LOG.info(searchParams.getQuery()); AtlasPerfMetrics.MetricRecorder elasticSearchQueryMetric = RequestContext.get().startMetricRecord("elasticSearchQuery"); DirectIndexQueryResult indexQueryResult = indexQuery.vertices(searchParams); RequestContext.get().endMetricRecord(elasticSearchQueryMetric); @@ -1102,7 +1111,10 @@ private void prepareSearchResult(AtlasSearchResult ret, DirectIndexQueryResult i } catch (Exception e) { throw e; } - scrubSearchResults(ret, searchParams.getSuppressLogs()); + + if (!searchParams.getUseAccessControlv2()) { + scrubSearchResults(ret, searchParams.getSuppressLogs()); + } } private Map getMap(String key, Object value) { @@ -1148,4 +1160,41 @@ private String getIndexName(IndexSearchParams params) throws AtlasBaseException throw new AtlasBaseException("ES alias not found for purpose/persona " + params.getPurpose()); } } + + private void addPreFiltersToSearchQuery(SearchParams searchParams) { + try { + String persona = ((IndexSearchParams) searchParams).getPersona(); + String purpose = ((IndexSearchParams) searchParams).getPurpose(); + + AtlasPerfMetrics.MetricRecorder addPreFiltersToSearchQueryMetric = RequestContext.get().startMetricRecord("addPreFiltersToSearchQuery"); + ObjectMapper mapper = new ObjectMapper(); + List> mustClauseList = new ArrayList<>(); + + List actions = new ArrayList<>(); + actions.add("entity-read"); + + Map allPreFiltersBoolClause = AuthorizerUtils.getPreFilterDsl(persona, purpose, actions); + mustClauseList.add(allPreFiltersBoolClause); + + String dslString = searchParams.getQuery(); + JsonNode node = mapper.readTree(dslString); + JsonNode userQueryNode = node.get("query"); + if (userQueryNode != null) { + + String userQueryString = userQueryNode.toString(); + + String userQueryBase64 = Base64.getEncoder().encodeToString(userQueryString.getBytes()); + mustClauseList.add(getMap("wrapper", getMap("query", userQueryBase64))); + } + + JsonNode updateQueryNode = mapper.valueToTree(getMap("bool", getMap("must", mustClauseList))); + + ((ObjectNode) node).set("query", updateQueryNode); + searchParams.setQuery(node.toString()); + RequestContext.get().endMetricRecord(addPreFiltersToSearchQueryMetric); + + } catch (Exception e) { + LOG.error("Error -> addPreFiltersToSearchQuery!", e); + } + } } diff --git a/repository/src/main/java/org/apache/atlas/discovery/EntityLineageService.java b/repository/src/main/java/org/apache/atlas/discovery/EntityLineageService.java index 6927b1d1c4..818aadd3f8 100644 --- a/repository/src/main/java/org/apache/atlas/discovery/EntityLineageService.java +++ b/repository/src/main/java/org/apache/atlas/discovery/EntityLineageService.java @@ -29,6 +29,7 @@ import org.apache.atlas.authorize.AtlasEntityAccessRequest; import org.apache.atlas.authorize.AtlasPrivilege; import org.apache.atlas.authorize.AtlasSearchResultScrubRequest; +import org.apache.atlas.authorizer.AuthorizerUtils; import org.apache.atlas.exception.AtlasBaseException; import org.apache.atlas.model.discovery.AtlasSearchResult; import org.apache.atlas.model.instance.AtlasEntity; @@ -687,8 +688,9 @@ public SchemaDetails getSchemaForHiveTableByGuid(final String guid) throws Atlas AtlasEntityWithExtInfo entityWithExtInfo = entityRetriever.toAtlasEntityWithExtInfo(guid); AtlasEntity entity = entityWithExtInfo.getEntity(); - AtlasAuthorizationUtils.verifyAccess(new AtlasEntityAccessRequest(atlasTypeRegistry, AtlasPrivilege.ENTITY_READ, new AtlasEntityHeader(entity)), - "read entity schema: guid=", guid); + /*AtlasAuthorizationUtils.verifyAccess(new AtlasEntityAccessRequest(atlasTypeRegistry, AtlasPrivilege.ENTITY_READ, new AtlasEntityHeader(entity)), + "read entity schema: guid=", guid);*/ + AuthorizerUtils.verifyAccess(new AtlasEntityHeader(entity), AtlasPrivilege.ENTITY_READ); Map referredEntities = entityWithExtInfo.getReferredEntities(); List columnIds = getColumnIds(entity); diff --git a/repository/src/main/java/org/apache/atlas/repository/store/graph/AtlasEntityStore.java b/repository/src/main/java/org/apache/atlas/repository/store/graph/AtlasEntityStore.java index 02022fe040..df8d127138 100644 --- a/repository/src/main/java/org/apache/atlas/repository/store/graph/AtlasEntityStore.java +++ b/repository/src/main/java/org/apache/atlas/repository/store/graph/AtlasEntityStore.java @@ -67,6 +67,7 @@ public interface AtlasEntityStore { * @return AtlasEntity */ AtlasEntityWithExtInfo getById(String guid, boolean isMinExtInfo, boolean ignoreRelationships) throws AtlasBaseException; + AtlasEntityWithExtInfo getById(String guid, boolean v2Enabled) throws AtlasBaseException; /** @@ -351,7 +352,7 @@ EntityMutationResponse deleteByUniqueAttributes(List objectIds) BulkImportResponse bulkCreateOrUpdateBusinessAttributes(InputStream inputStream, String fileName) throws AtlasBaseException; - List getAccessors(List request) throws AtlasBaseException; + List getAccessors(List request, boolean v2Enabled) throws AtlasBaseException; void repairIndex() throws AtlasBaseException; diff --git a/repository/src/main/java/org/apache/atlas/repository/store/graph/v1/DeleteHandlerV1.java b/repository/src/main/java/org/apache/atlas/repository/store/graph/v1/DeleteHandlerV1.java index d4437922b6..68d678707d 100644 --- a/repository/src/main/java/org/apache/atlas/repository/store/graph/v1/DeleteHandlerV1.java +++ b/repository/src/main/java/org/apache/atlas/repository/store/graph/v1/DeleteHandlerV1.java @@ -24,6 +24,7 @@ import org.apache.atlas.authorize.AtlasAuthorizationUtils; import org.apache.atlas.authorize.AtlasPrivilege; import org.apache.atlas.authorize.AtlasRelationshipAccessRequest; +import org.apache.atlas.authorizer.AuthorizerUtils; import org.apache.atlas.exception.AtlasBaseException; import org.apache.atlas.model.TypeCategory; import org.apache.atlas.model.instance.AtlasClassification; @@ -519,7 +520,8 @@ public void authorizeRemoveRelation(AtlasEdge edge) throws AtlasBaseException { end1Entity = entityRetriever.toAtlasEntityHeaderWithClassifications(edge.getOutVertex()); end2Entity = entityRetriever.toAtlasEntityHeaderWithClassifications(edge.getInVertex()); - AtlasAuthorizationUtils.verifyAccess(new AtlasRelationshipAccessRequest(typeRegistry, AtlasPrivilege.RELATIONSHIP_REMOVE, relationShipType, end1Entity, end2Entity )); + //AtlasAuthorizationUtils.verifyAccess(new AtlasRelationshipAccessRequest(typeRegistry, AtlasPrivilege.RELATIONSHIP_REMOVE, relationShipType, end1Entity, end2Entity )); + AuthorizerUtils.verifyRelationshipAccess(AtlasPrivilege.RELATIONSHIP_REMOVE, relationShipType, end1Entity, end2Entity); RequestContext.get().endMetricRecord(metric); } diff --git a/repository/src/main/java/org/apache/atlas/repository/store/graph/v2/AtlasEntityStoreV2.java b/repository/src/main/java/org/apache/atlas/repository/store/graph/v2/AtlasEntityStoreV2.java index 6e3487f8d3..11cef4f7fc 100644 --- a/repository/src/main/java/org/apache/atlas/repository/store/graph/v2/AtlasEntityStoreV2.java +++ b/repository/src/main/java/org/apache/atlas/repository/store/graph/v2/AtlasEntityStoreV2.java @@ -30,6 +30,7 @@ import org.apache.atlas.authorize.*; import org.apache.atlas.authorize.AtlasEntityAccessRequest.AtlasEntityAccessRequestBuilder; import org.apache.atlas.authorize.AtlasPrivilege; +import org.apache.atlas.authorizer.AuthorizerUtils; import org.apache.atlas.discovery.EntityDiscoveryService; import org.apache.atlas.exception.AtlasBaseException; import org.apache.atlas.featureflag.FeatureFlagStore; @@ -213,7 +214,8 @@ public AtlasEntityWithExtInfo getById(final String guid, final boolean isMinExtI throw new AtlasBaseException(AtlasErrorCode.INSTANCE_GUID_NOT_FOUND, guid); } - AtlasAuthorizationUtils.verifyAccess(new AtlasEntityAccessRequest(typeRegistry, AtlasPrivilege.ENTITY_READ, new AtlasEntityHeader(ret.getEntity())), "read entity: guid=", guid); + // AtlasAuthorizationUtils.verifyAccess(new AtlasEntityAccessRequest(typeRegistry, AtlasPrivilege.ENTITY_READ, new AtlasEntityHeader(ret.getEntity())), "read entity: guid=", guid); + AuthorizerUtils.verifyAccess(new AtlasEntityHeader(ret.getEntity()), AtlasPrivilege.ENTITY_READ); if (LOG.isDebugEnabled()) { LOG.debug("<== getById({}, {}): {}", guid, isMinExtInfo, ret); @@ -222,6 +224,27 @@ public AtlasEntityWithExtInfo getById(final String guid, final boolean isMinExtI return ret; } + @Override + @GraphTransaction + public AtlasEntityWithExtInfo getById(final String guid, final boolean v2Enabled) throws AtlasBaseException { + + EntityGraphRetriever entityRetriever = new EntityGraphRetriever(graph, typeRegistry, false); + + AtlasEntityWithExtInfo ret = entityRetriever.toAtlasEntityWithExtInfo(guid, false); + + if (ret == null) { + throw new AtlasBaseException(AtlasErrorCode.INSTANCE_GUID_NOT_FOUND, guid); + } + + if (!v2Enabled) { + AtlasAuthorizationUtils.verifyAccess(new AtlasEntityAccessRequest(typeRegistry, AtlasPrivilege.ENTITY_READ, new AtlasEntityHeader(ret.getEntity())), "read entity: guid=", guid); + } else { + AuthorizerUtils.verifyAccess(new AtlasEntityHeader(ret.getEntity()), AtlasPrivilege.ENTITY_READ); + } + + return ret; + } + @Override @GraphTransaction public AtlasEntityWithExtInfo getByIdWithoutAuthorization(final String guid) throws AtlasBaseException { @@ -259,7 +282,8 @@ public AtlasEntityHeader getHeaderById(final String guid) throws AtlasBaseExcept throw new AtlasBaseException(AtlasErrorCode.INSTANCE_GUID_NOT_FOUND, guid); } - AtlasAuthorizationUtils.verifyAccess(new AtlasEntityAccessRequest(typeRegistry, AtlasPrivilege.ENTITY_READ, ret), "read entity: guid=", guid); + // AtlasAuthorizationUtils.verifyAccess(new AtlasEntityAccessRequest(typeRegistry, AtlasPrivilege.ENTITY_READ, ret), "read entity: guid=", guid); + AuthorizerUtils.verifyAccess(ret, AtlasPrivilege.ENTITY_READ); if (LOG.isDebugEnabled()) { LOG.debug("<== getHeaderById({}): {}", guid, ret); @@ -289,7 +313,8 @@ public AtlasEntitiesWithExtInfo getByIds(List guids, boolean isMinExtInf for(String guid : guids) { AtlasEntity entity = ret.getEntity(guid); try { - AtlasAuthorizationUtils.verifyAccess(new AtlasEntityAccessRequest(typeRegistry, AtlasPrivilege.ENTITY_READ, new AtlasEntityHeader(entity)), "read entity: guid=", guid); + // AtlasAuthorizationUtils.verifyAccess(new AtlasEntityAccessRequest(typeRegistry, AtlasPrivilege.ENTITY_READ, new AtlasEntityHeader(entity)), "read entity: guid=", guid); + AuthorizerUtils.verifyAccess(new AtlasEntityHeader(entity), AtlasPrivilege.ENTITY_READ); } catch (AtlasBaseException e) { if (RequestContext.get().isSkipFailedEntities()) { if (LOG.isDebugEnabled()) { @@ -329,7 +354,8 @@ public AtlasEntitiesWithExtInfo getEntitiesByUniqueAttributes(AtlasEntityType en if (ret != null && ret.getEntities() != null) { for (AtlasEntity entity : ret.getEntities()) { - AtlasAuthorizationUtils.verifyAccess(new AtlasEntityAccessRequest(typeRegistry, AtlasPrivilege.ENTITY_READ, new AtlasEntityHeader(entity)), "read entity: typeName=", entityType.getTypeName(), ", guid=", entity.getGuid()); + // AtlasAuthorizationUtils.verifyAccess(new AtlasEntityAccessRequest(typeRegistry, AtlasPrivilege.ENTITY_READ, new AtlasEntityHeader(entity)), "read entity: typeName=", entityType.getTypeName(), ", guid=", entity.getGuid()); + AuthorizerUtils.verifyAccess(new AtlasEntityHeader(entity), AtlasPrivilege.ENTITY_READ); } } @@ -365,7 +391,8 @@ public AtlasEntityWithExtInfo getByUniqueAttributes(AtlasEntityType entityType, uniqAttributes.toString()); } - AtlasAuthorizationUtils.verifyAccess(new AtlasEntityAccessRequest(typeRegistry, AtlasPrivilege.ENTITY_READ, new AtlasEntityHeader(ret.getEntity())), "read entity: typeName=", entityType.getTypeName(), ", uniqueAttributes=", uniqAttributes); + // AtlasAuthorizationUtils.verifyAccess(new AtlasEntityAccessRequest(typeRegistry, AtlasPrivilege.ENTITY_READ, new AtlasEntityHeader(ret.getEntity())), "read entity: typeName=", entityType.getTypeName(), ", uniqueAttributes=", uniqAttributes); + AuthorizerUtils.verifyAccess(new AtlasEntityHeader(ret.getEntity()), AtlasPrivilege.ENTITY_READ); if (LOG.isDebugEnabled()) { LOG.debug("<== getByUniqueAttribute({}, {}): {}", entityType.getTypeName(), uniqAttributes, ret); @@ -398,7 +425,8 @@ public AtlasEntityHeader getEntityHeaderByUniqueAttributes(AtlasEntityType entit uniqAttributes.toString()); } - AtlasAuthorizationUtils.verifyAccess(new AtlasEntityAccessRequest(typeRegistry, AtlasPrivilege.ENTITY_READ, ret), "read entity: typeName=", entityType.getTypeName(), ", uniqueAttributes=", uniqAttributes); + // AtlasAuthorizationUtils.verifyAccess(new AtlasEntityAccessRequest(typeRegistry, AtlasPrivilege.ENTITY_READ, ret), "read entity: typeName=", entityType.getTypeName(), ", uniqueAttributes=", uniqAttributes); + AuthorizerUtils.verifyAccess(ret, AtlasPrivilege.ENTITY_READ); if (LOG.isDebugEnabled()) { LOG.debug("<== getEntityHeaderByUniqueAttributes({}, {}): {}", entityType.getTypeName(), uniqAttributes, ret); @@ -510,7 +538,9 @@ public EntityMutationResponse updateByUniqueAttributes(AtlasEntityType entityTyp entity.setGuid(guid); - AtlasAuthorizationUtils.verifyUpdateEntityAccess(typeRegistry, new AtlasEntityHeader(entity), "update entity ByUniqueAttributes"); + //AtlasAuthorizationUtils.verifyUpdateEntityAccess(typeRegistry, new AtlasEntityHeader(entity), "update entity ByUniqueAttributes"); + AuthorizerUtils.verifyUpdateEntityAccess(new AtlasEntityHeader(entity)); + return createOrUpdate(new AtlasEntityStream(updatedEntityInfo), true, false, false, false); } @@ -527,7 +557,9 @@ public EntityMutationResponse updateEntityAttributeByGuid(String guid, String at AtlasEntityType entityType = (AtlasEntityType) typeRegistry.getType(entity.getTypeName()); AtlasAttribute attr = entityType.getAttribute(attrName); - AtlasAuthorizationUtils.verifyUpdateEntityAccess(typeRegistry, entity, "update entity ByUniqueAttributes : guid=" + guid); + //AtlasAuthorizationUtils.verifyUpdateEntityAccess(typeRegistry, entity, "update entity ByUniqueAttributes : guid=" + guid); + AuthorizerUtils.verifyUpdateEntityAccess(entity); + if (attr == null) { attr = entityType.getRelationshipAttribute(attrName, AtlasEntityUtil.getRelationshipType(attrValue)); @@ -582,7 +614,8 @@ public EntityMutationResponse deleteById(final String guid) throws AtlasBaseExce if (vertex != null) { AtlasEntityHeader entityHeader = entityRetriever.toAtlasEntityHeaderWithClassifications(vertex); - AtlasAuthorizationUtils.verifyDeleteEntityAccess(typeRegistry, entityHeader, "delete entity: guid=" + guid); + //AtlasAuthorizationUtils.verifyDeleteEntityAccess(typeRegistry, entityHeader, "delete entity: guid=" + guid); + AuthorizerUtils.verifyDeleteEntityAccess(entityHeader); deletionCandidates.add(vertex); } else { @@ -628,7 +661,8 @@ public EntityMutationResponse deleteByIds(final List guids) throws Atlas AtlasEntityHeader entityHeader = entityRetriever.toAtlasEntityHeaderWithClassifications(vertex); - AtlasAuthorizationUtils.verifyDeleteEntityAccess(typeRegistry, entityHeader, "delete entity: guid=" + guid); + //AtlasAuthorizationUtils.verifyDeleteEntityAccess(typeRegistry, entityHeader, "delete entity: guid=" + guid); + AuthorizerUtils.verifyDeleteEntityAccess(entityHeader); deletionCandidates.add(vertex); } @@ -671,7 +705,8 @@ public EntityMutationResponse restoreByIds(final List guids) throws Atla AtlasEntityHeader entityHeader = entityRetriever.toAtlasEntityHeaderWithClassifications(vertex); - AtlasAuthorizationUtils.verifyDeleteEntityAccess(typeRegistry, entityHeader, "delete entity: guid=" + guid); + //AtlasAuthorizationUtils.verifyDeleteEntityAccess(typeRegistry, entityHeader, "delete entity: guid=" + guid); + AuthorizerUtils.verifyDeleteEntityAccess(entityHeader); restoreCandidates.add(vertex); } @@ -737,8 +772,9 @@ public EntityMutationResponse deleteByUniqueAttributes(AtlasEntityType entityTyp if (vertex != null) { AtlasEntityHeader entityHeader = entityRetriever.toAtlasEntityHeaderWithClassifications(vertex); - AtlasAuthorizationUtils.verifyDeleteEntityAccess(typeRegistry, entityHeader, - "delete entity: typeName=" + entityType.getTypeName() + ", uniqueAttributes=" + uniqAttributes); + //AtlasAuthorizationUtils.verifyDeleteEntityAccess(typeRegistry, entityHeader, + // "delete entity: typeName=" + entityType.getTypeName() + ", uniqueAttributes=" + uniqAttributes); + AuthorizerUtils.verifyDeleteEntityAccess(entityHeader); deletionCandidates.add(vertex); } else { @@ -790,8 +826,9 @@ public EntityMutationResponse deleteByUniqueAttributes(List objec if (vertex != null) { AtlasEntityHeader entityHeader = entityRetriever.toAtlasEntityHeaderWithClassifications(vertex); - AtlasAuthorizationUtils.verifyDeleteEntityAccess(typeRegistry, entityHeader, - "delete entity: typeName=" + entityType.getTypeName() + ", uniqueAttributes=" + objectId.getUniqueAttributes()); + //AtlasAuthorizationUtils.verifyDeleteEntityAccess(typeRegistry, entityHeader, + // "delete entity: typeName=" + entityType.getTypeName() + ", uniqueAttributes=" + objectId.getUniqueAttributes()); + AuthorizerUtils.verifyDeleteEntityAccess(entityHeader); deletionCandidates.add(vertex); } else { @@ -939,9 +976,10 @@ public void addClassifications(final String guid, final List) entityForAuth.get("objects")).put("assetQualifiedNames", assetQualifiedNames); +// +// +// String[] userArray = new String[1]; +// userArray[0] = RequestContext.getCurrentUser(); +// entityForAuth.put("subjects", getMap("users", userArray)); +// +// String[] actionArray = new String[1]; +// actionArray[0] = action; +// entityForAuth.put("actions", actionArray); +// +// Boolean accessAllowed = this.atlasAuthorization.isAccessAllowed(entityForAuth, RequestContext.getCurrentUser()); +// return accessAllowed; +// } + private EntityMutationResponse createOrUpdate(EntityStream entityStream, boolean isPartialUpdate, boolean replaceClassifications, boolean replaceBusinessAttributes, boolean isOverwriteBusinessAttribute) throws AtlasBaseException { if (LOG.isDebugEnabled()) { LOG.debug("==> createOrUpdate()"); @@ -1433,8 +1507,10 @@ private EntityMutationResponse createOrUpdate(EntityStream entityStream, boolean if (!RequestContext.get().isImportInProgress() && !RequestContext.get().isSkipAuthorizationCheck()) { for (AtlasEntity entity : context.getCreatedEntities()) { if (!PreProcessor.skipInitialAuthCheckTypes.contains(entity.getTypeName())) { - AtlasAuthorizationUtils.verifyAccess(new AtlasEntityAccessRequest(typeRegistry, AtlasPrivilege.ENTITY_CREATE, new AtlasEntityHeader(entity)), - "create entity: type=", entity.getTypeName()); + /*AtlasAuthorizationUtils.verifyAccess(new AtlasEntityAccessRequest(typeRegistry, AtlasPrivilege.ENTITY_CREATE, new AtlasEntityHeader(entity)), + "create entity: type=", entity.getTypeName());*/ + //AuthorizerUtils.verifyEntityCreateAccess(entity, context.getVertex(entity.getGuid()), AtlasPrivilege.ENTITY_CREATE); + AuthorizerUtils.verifyEntityCreateAccess(entity, AtlasPrivilege.ENTITY_CREATE); } } } @@ -1499,7 +1575,8 @@ private EntityMutationResponse createOrUpdate(EntityStream entityStream, boolean if (skipAuthBaseConditions && (skipAuthMeaningsUpdate || skipAuthStarredDetailsUpdate)) { //do nothing, only diff is relationshipAttributes.meanings or starred, allow update } else { - AtlasAuthorizationUtils.verifyUpdateEntityAccess(typeRegistry, entityHeader,"update entity: type=" + entity.getTypeName()); + //AtlasAuthorizationUtils.verifyUpdateEntityAccess(typeRegistry, entityHeader,"update entity: type=" + entity.getTypeName()); + AuthorizerUtils.verifyUpdateEntityAccess(entityHeader); } } } @@ -2117,7 +2194,7 @@ public BulkImportResponse bulkCreateOrUpdateBusinessAttributes(InputStream input } @Override - public List getAccessors(List atlasAccessorRequestList) throws AtlasBaseException { + public List getAccessors(List atlasAccessorRequestList, boolean v2Enabled) throws AtlasBaseException { List ret = new ArrayList<>(); for (AtlasAccessorRequest accessorRequest : atlasAccessorRequestList) { @@ -2130,30 +2207,46 @@ public List getAccessors(List atlas case ENTITY_CREATE: case ENTITY_UPDATE: case ENTITY_DELETE: - AtlasEntityAccessRequestBuilder entityAccessRequestBuilder = getEntityAccessRequest(accessorRequest, action); - result = AtlasAuthorizationUtils.getAccessors(entityAccessRequestBuilder.build()); + if (!v2Enabled) { + AtlasEntityAccessRequestBuilder entityAccessRequestBuilder = getEntityAccessRequest(accessorRequest, action); + result = AtlasAuthorizationUtils.getAccessors(entityAccessRequestBuilder.build()); + } else { + result = AuthorizerUtils.getAccessors(accessorRequest); + } break; case ENTITY_READ_CLASSIFICATION: case ENTITY_ADD_CLASSIFICATION: case ENTITY_UPDATE_CLASSIFICATION: case ENTITY_REMOVE_CLASSIFICATION: - entityAccessRequestBuilder = getEntityAccessRequest(accessorRequest, action); - entityAccessRequestBuilder.setClassification(new AtlasClassification(accessorRequest.getClassification())); - result = AtlasAuthorizationUtils.getAccessors(entityAccessRequestBuilder.build()); + if (!v2Enabled) { + AtlasEntityAccessRequestBuilder entityAccessRequestBuilder = getEntityAccessRequest(accessorRequest, action); + entityAccessRequestBuilder.setClassification(new AtlasClassification(accessorRequest.getClassification())); + result = AtlasAuthorizationUtils.getAccessors(entityAccessRequestBuilder.build()); + } else { + result = AuthorizerUtils.getAccessors(accessorRequest); + } break; case ENTITY_ADD_LABEL: case ENTITY_REMOVE_LABEL: - entityAccessRequestBuilder = getEntityAccessRequest(accessorRequest, action); - entityAccessRequestBuilder.setLabel(accessorRequest.getLabel()); - result = AtlasAuthorizationUtils.getAccessors(entityAccessRequestBuilder.build()); + if (!v2Enabled) { + AtlasEntityAccessRequestBuilder entityAccessRequestBuilder = getEntityAccessRequest(accessorRequest, action); + entityAccessRequestBuilder.setLabel(accessorRequest.getLabel()); + result = AtlasAuthorizationUtils.getAccessors(entityAccessRequestBuilder.build()); + } else { + result = AuthorizerUtils.getAccessors(accessorRequest); + } break; case ENTITY_UPDATE_BUSINESS_METADATA: - entityAccessRequestBuilder = getEntityAccessRequest(accessorRequest, action); - entityAccessRequestBuilder.setBusinessMetadata(accessorRequest.getBusinessMetadata()); - result = AtlasAuthorizationUtils.getAccessors(entityAccessRequestBuilder.build()); + if (!v2Enabled) { + AtlasEntityAccessRequestBuilder entityAccessRequestBuilder = getEntityAccessRequest(accessorRequest, action); + entityAccessRequestBuilder.setBusinessMetadata(accessorRequest.getBusinessMetadata()); + result = AtlasAuthorizationUtils.getAccessors(entityAccessRequestBuilder.build()); + } else { + result = AuthorizerUtils.getAccessors(accessorRequest); + } break; @@ -2163,10 +2256,14 @@ public List getAccessors(List atlas AtlasEntityHeader end1EntityHeader = extractEntityHeader(accessorRequest.getEntityGuidEnd1(), accessorRequest.getEntityQualifiedNameEnd1(), accessorRequest.getEntityTypeEnd1()); AtlasEntityHeader end2EntityHeader = extractEntityHeader(accessorRequest.getEntityGuidEnd2(), accessorRequest.getEntityQualifiedNameEnd2(), accessorRequest.getEntityTypeEnd2()); - AtlasRelationshipAccessRequest relAccessRequest = new AtlasRelationshipAccessRequest(typeRegistry, - action, accessorRequest.getRelationshipTypeName(), end1EntityHeader, end2EntityHeader); + if (!v2Enabled) { + AtlasRelationshipAccessRequest relAccessRequest = new AtlasRelationshipAccessRequest(typeRegistry, + action, accessorRequest.getRelationshipTypeName(), end1EntityHeader, end2EntityHeader); - result = AtlasAuthorizationUtils.getAccessors(relAccessRequest); + result = AtlasAuthorizationUtils.getAccessors(relAccessRequest); + } else { + result = AuthorizerUtils.getAccessors(accessorRequest); + } break; diff --git a/repository/src/main/java/org/apache/atlas/repository/store/graph/v2/AtlasRelationshipStoreV2.java b/repository/src/main/java/org/apache/atlas/repository/store/graph/v2/AtlasRelationshipStoreV2.java index 3e8c8b9e42..305784daf1 100644 --- a/repository/src/main/java/org/apache/atlas/repository/store/graph/v2/AtlasRelationshipStoreV2.java +++ b/repository/src/main/java/org/apache/atlas/repository/store/graph/v2/AtlasRelationshipStoreV2.java @@ -25,6 +25,7 @@ import org.apache.atlas.authorize.AtlasAuthorizationUtils; import org.apache.atlas.authorize.AtlasPrivilege; import org.apache.atlas.authorize.AtlasRelationshipAccessRequest; +import org.apache.atlas.authorizer.AuthorizerUtils; import org.apache.atlas.exception.AtlasBaseException; import org.apache.atlas.model.TypeCategory; import org.apache.atlas.model.instance.AtlasEntityHeader; @@ -464,8 +465,9 @@ private AtlasEdge createRelationship(AtlasVertex end1Vertex, AtlasVertex end2Ver AtlasEntityHeader end1Entity = entityRetriever.toAtlasEntityHeaderWithClassifications(end1Vertex); AtlasEntityHeader end2Entity = entityRetriever.toAtlasEntityHeaderWithClassifications(end2Vertex); - AtlasAuthorizationUtils.verifyAccess(new AtlasRelationshipAccessRequest(typeRegistry, AtlasPrivilege.RELATIONSHIP_ADD, - relationship.getTypeName(), end1Entity, end2Entity)); +// AtlasAuthorizationUtils.verifyAccess(new AtlasRelationshipAccessRequest(typeRegistry, AtlasPrivilege.RELATIONSHIP_ADD, +// relationship.getTypeName(), end1Entity, end2Entity)); + AuthorizerUtils.verifyRelationshipCreateAccess(AtlasPrivilege.RELATIONSHIP_ADD, relationship.getTypeName(), end1Entity, end2Entity); if (existingRelationshipCheck) { @@ -520,7 +522,8 @@ private AtlasRelationship updateRelationship(AtlasEdge relationshipEdge, AtlasRe AtlasEntityHeader end1Entity = entityRetriever.toAtlasEntityHeaderWithClassifications(end1Vertex); AtlasEntityHeader end2Entity = entityRetriever.toAtlasEntityHeaderWithClassifications(end2Vertex); - AtlasAuthorizationUtils.verifyAccess(new AtlasRelationshipAccessRequest(typeRegistry, AtlasPrivilege.RELATIONSHIP_UPDATE, relationship.getTypeName(), end1Entity, end2Entity)); +// AtlasAuthorizationUtils.verifyAccess(new AtlasRelationshipAccessRequest(typeRegistry, AtlasPrivilege.RELATIONSHIP_UPDATE, relationship.getTypeName(), end1Entity, end2Entity)); + AuthorizerUtils.verifyRelationshipAccess(AtlasPrivilege.RELATIONSHIP_UPDATE, relationship.getTypeName(), end1Entity, end2Entity); updateTagPropagations(relationshipEdge, relationship); diff --git a/repository/src/main/java/org/apache/atlas/repository/store/graph/v2/EntityGraphMapper.java b/repository/src/main/java/org/apache/atlas/repository/store/graph/v2/EntityGraphMapper.java index 2858c31aab..dec91a83ba 100644 --- a/repository/src/main/java/org/apache/atlas/repository/store/graph/v2/EntityGraphMapper.java +++ b/repository/src/main/java/org/apache/atlas/repository/store/graph/v2/EntityGraphMapper.java @@ -21,9 +21,9 @@ import com.google.common.annotations.VisibleForTesting; import org.apache.atlas.*; import org.apache.atlas.annotation.GraphTransaction; -import org.apache.atlas.authorize.AtlasAuthorizationUtils; import org.apache.atlas.authorize.AtlasEntityAccessRequest; import org.apache.atlas.authorize.AtlasPrivilege; +import org.apache.atlas.authorizer.AuthorizerUtils; import org.apache.atlas.exception.AtlasBaseException; import org.apache.atlas.exception.EntityNotFoundException; import org.apache.atlas.model.TimeBoundary; @@ -666,7 +666,8 @@ public void addOrUpdateBusinessAttributes(String guid, Map roles = Arrays.asList(roleName); + policy.setAttribute(ATTR_POLICY_ROLES, roles); + + policy.setAttribute(ATTR_POLICY_USERS, new ArrayList<>()); + policy.setAttribute(ATTR_POLICY_GROUPS, new ArrayList<>()); + + //aliasStore.updateAlias(parentEntity, policy); + + return; + } + + if (StringUtils.isEmpty(policyCategory)) { throw new AtlasBaseException(BAD_REQUEST, "Please provide attribute " + ATTR_POLICY_CATEGORY); } @@ -169,6 +190,12 @@ private void processCreatePolicy(AtlasStruct entity) throws AtlasBaseException { private void processUpdatePolicy(AtlasStruct entity, AtlasVertex vertex) throws AtlasBaseException { AtlasPerfMetrics.MetricRecorder metricRecorder = RequestContext.get().startMetricRecord("processUpdatePolicy"); AtlasEntity policy = (AtlasEntity) entity; + + String policyServiceName = getPolicyServiceName(policy); + if (POLICY_SERVICE_NAME_ABAC.equals(policyServiceName)) { + return; + } + AtlasEntity existingPolicy = entityRetriever.toAtlasEntityWithExtInfo(vertex).getEntity(); String policyCategory = policy.hasAttribute(ATTR_POLICY_CATEGORY) ? getPolicyCategory(policy) : getPolicyCategory(existingPolicy); @@ -235,6 +262,11 @@ public void processDelete(AtlasVertex vertex) throws AtlasBaseException { try { AtlasEntity policy = entityRetriever.toAtlasEntity(vertex); + String policyServiceName = getPolicyServiceName(policy); + if (POLICY_SERVICE_NAME_ABAC.equals(policyServiceName)) { + return; + } + authorizeDeleteAuthPolicy(policy); if(!policy.getStatus().equals(AtlasEntity.Status.ACTIVE)) { @@ -254,8 +286,9 @@ public void processDelete(AtlasVertex vertex) throws AtlasBaseException { private void authorizeDeleteAuthPolicy(AtlasEntity policy) throws AtlasBaseException { if (!RequestContext.get().isSkipAuthorizationCheck()) { - AtlasEntityAccessRequest request = new AtlasEntityAccessRequest(typeRegistry, AtlasPrivilege.ENTITY_DELETE, new AtlasEntityHeader(policy)); - verifyAccess(request, "delete entity: guid=" + policy.getGuid()); +// AtlasEntityAccessRequest request = new AtlasEntityAccessRequest(typeRegistry, AtlasPrivilege.ENTITY_DELETE, new AtlasEntityHeader(policy)); +// verifyAccess(request, "delete entity: guid=" + policy.getGuid()); + AuthorizerUtils.verifyAccess(new AtlasEntityHeader(policy), AtlasPrivilege.ENTITY_DELETE); } /* else, * skip auth check diff --git a/repository/src/main/java/org/apache/atlas/repository/store/graph/v2/preprocessor/glossary/AbstractGlossaryPreProcessor.java b/repository/src/main/java/org/apache/atlas/repository/store/graph/v2/preprocessor/glossary/AbstractGlossaryPreProcessor.java index 91950f783c..5d0c7da481 100644 --- a/repository/src/main/java/org/apache/atlas/repository/store/graph/v2/preprocessor/glossary/AbstractGlossaryPreProcessor.java +++ b/repository/src/main/java/org/apache/atlas/repository/store/graph/v2/preprocessor/glossary/AbstractGlossaryPreProcessor.java @@ -21,9 +21,8 @@ import org.apache.atlas.AtlasErrorCode; import org.apache.atlas.AtlasException; import org.apache.atlas.RequestContext; -import org.apache.atlas.authorize.AtlasAuthorizationUtils; -import org.apache.atlas.authorize.AtlasEntityAccessRequest; import org.apache.atlas.authorize.AtlasPrivilege; +import org.apache.atlas.authorizer.AuthorizerUtils; import org.apache.atlas.discovery.EntityDiscoveryService; import org.apache.atlas.exception.AtlasBaseException; import org.apache.atlas.model.discovery.IndexSearchParams; @@ -227,25 +226,35 @@ public void updateMeaningsAttributesInEntitiesOnTermUpdate(String currentTermNam protected void isAuthorized(AtlasEntityHeader sourceGlossary, AtlasEntityHeader targetGlossary) throws AtlasBaseException { // source -> CREATE + UPDATE + DELETE - AtlasAuthorizationUtils.verifyAccess(new AtlasEntityAccessRequest(typeRegistry, AtlasPrivilege.ENTITY_CREATE, sourceGlossary), - "create on source Glossary: ", sourceGlossary.getAttribute(NAME)); +// AtlasAuthorizationUtils.verifyAccess(new AtlasEntityAccessRequest(typeRegistry, AtlasPrivilege.ENTITY_CREATE, sourceGlossary), +// ); +// +// AtlasAuthorizationUtils.verifyAccess(new AtlasEntityAccessRequest(typeRegistry, AtlasPrivilege.ENTITY_UPDATE, sourceGlossary), +// "update on source Glossary: ", sourceGlossary.getAttribute(NAME)); +// +// AtlasAuthorizationUtils.verifyAccess(new AtlasEntityAccessRequest(typeRegistry, AtlasPrivilege.ENTITY_DELETE, sourceGlossary), +// "delete on source Glossary: ", sourceGlossary.getAttribute(NAME)); - AtlasAuthorizationUtils.verifyAccess(new AtlasEntityAccessRequest(typeRegistry, AtlasPrivilege.ENTITY_UPDATE, sourceGlossary), - "update on source Glossary: ", sourceGlossary.getAttribute(NAME)); - - AtlasAuthorizationUtils.verifyAccess(new AtlasEntityAccessRequest(typeRegistry, AtlasPrivilege.ENTITY_DELETE, sourceGlossary), - "delete on source Glossary: ", sourceGlossary.getAttribute(NAME)); + //verifyAccess(new AtlasEntity(sourceGlossary), AtlasPrivilege.ENTITY_CREATE, "create on source Glossary: " + sourceGlossary.getAttribute(NAME)); + AuthorizerUtils.verifyEntityCreateAccess(new AtlasEntity(sourceGlossary), AtlasPrivilege.ENTITY_CREATE); + AuthorizerUtils.verifyAccess(sourceGlossary, AtlasPrivilege.ENTITY_UPDATE); + AuthorizerUtils.verifyAccess(sourceGlossary, AtlasPrivilege.ENTITY_DELETE); // target -> CREATE + UPDATE + DELETE - AtlasAuthorizationUtils.verifyAccess(new AtlasEntityAccessRequest(typeRegistry, AtlasPrivilege.ENTITY_CREATE, targetGlossary), - "create on source Glossary: ", targetGlossary.getAttribute(NAME)); - - AtlasAuthorizationUtils.verifyAccess(new AtlasEntityAccessRequest(typeRegistry, AtlasPrivilege.ENTITY_UPDATE, targetGlossary), - "update on source Glossary: ", targetGlossary.getAttribute(NAME)); - - AtlasAuthorizationUtils.verifyAccess(new AtlasEntityAccessRequest(typeRegistry, AtlasPrivilege.ENTITY_DELETE, targetGlossary), - "delete on source Glossary: ", targetGlossary.getAttribute(NAME)); +// AtlasAuthorizationUtils.verifyAccess(new AtlasEntityAccessRequest(typeRegistry, AtlasPrivilege.ENTITY_CREATE, targetGlossary), +// "create on source Glossary: ", targetGlossary.getAttribute(NAME)); +// +// AtlasAuthorizationUtils.verifyAccess(new AtlasEntityAccessRequest(typeRegistry, AtlasPrivilege.ENTITY_UPDATE, targetGlossary), +// "update on source Glossary: ", targetGlossary.getAttribute(NAME)); +// +// AtlasAuthorizationUtils.verifyAccess(new AtlasEntityAccessRequest(typeRegistry, AtlasPrivilege.ENTITY_DELETE, targetGlossary), +// "delete on source Glossary: ", targetGlossary.getAttribute(NAME)); + + //verifyAccess(new AtlasEntity(targetGlossary), AtlasPrivilege.ENTITY_CREATE, "create on source Glossary: " + targetGlossary.getAttribute(NAME)); + AuthorizerUtils.verifyEntityCreateAccess(new AtlasEntity(targetGlossary), AtlasPrivilege.ENTITY_CREATE); + AuthorizerUtils.verifyAccess(targetGlossary, AtlasPrivilege.ENTITY_UPDATE); + AuthorizerUtils.verifyAccess(targetGlossary, AtlasPrivilege.ENTITY_DELETE); } /** diff --git a/repository/src/main/java/org/apache/atlas/repository/store/graph/v2/preprocessor/glossary/CategoryPreProcessor.java b/repository/src/main/java/org/apache/atlas/repository/store/graph/v2/preprocessor/glossary/CategoryPreProcessor.java index eb39ff3b1d..10e71bf99e 100644 --- a/repository/src/main/java/org/apache/atlas/repository/store/graph/v2/preprocessor/glossary/CategoryPreProcessor.java +++ b/repository/src/main/java/org/apache/atlas/repository/store/graph/v2/preprocessor/glossary/CategoryPreProcessor.java @@ -23,6 +23,7 @@ import org.apache.atlas.authorize.AtlasAuthorizationUtils; import org.apache.atlas.authorize.AtlasEntityAccessRequest; import org.apache.atlas.authorize.AtlasPrivilege; +import org.apache.atlas.authorizer.AuthorizerUtils; import org.apache.atlas.exception.AtlasBaseException; import org.apache.atlas.model.instance.AtlasEntity; import org.apache.atlas.model.instance.AtlasEntityHeader; @@ -127,8 +128,9 @@ private void processCreateCategory(AtlasEntity entity, AtlasVertex vertex) throw validateParent(glossaryQualifiedName); entity.setAttribute(QUALIFIED_NAME, createQualifiedName(vertex)); - AtlasAuthorizationUtils.verifyAccess(new AtlasEntityAccessRequest(typeRegistry, AtlasPrivilege.ENTITY_CREATE, new AtlasEntityHeader(entity)), - "create entity: type=", entity.getTypeName()); +// AtlasAuthorizationUtils.verifyAccess(new AtlasEntityAccessRequest(typeRegistry, AtlasPrivilege.ENTITY_CREATE, new AtlasEntityHeader(entity)), +// "create entity: type=", entity.getTypeName()); + AuthorizerUtils.verifyEntityCreateAccess(entity, AtlasPrivilege.ENTITY_CREATE); validateChildren(entity, null); diff --git a/repository/src/main/java/org/apache/atlas/repository/store/graph/v2/preprocessor/glossary/TermPreProcessor.java b/repository/src/main/java/org/apache/atlas/repository/store/graph/v2/preprocessor/glossary/TermPreProcessor.java index 53e12ea93e..3e4afcaec6 100644 --- a/repository/src/main/java/org/apache/atlas/repository/store/graph/v2/preprocessor/glossary/TermPreProcessor.java +++ b/repository/src/main/java/org/apache/atlas/repository/store/graph/v2/preprocessor/glossary/TermPreProcessor.java @@ -23,6 +23,7 @@ import org.apache.atlas.authorize.AtlasAuthorizationUtils; import org.apache.atlas.authorize.AtlasEntityAccessRequest; import org.apache.atlas.authorize.AtlasPrivilege; +import org.apache.atlas.authorizer.AuthorizerUtils; import org.apache.atlas.exception.AtlasBaseException; import org.apache.atlas.model.instance.AtlasEntity; import org.apache.atlas.model.instance.AtlasEntityHeader; @@ -98,8 +99,10 @@ private void processCreateTerm(AtlasEntity entity, AtlasVertex vertex) throws At validateCategory(entity); entity.setAttribute(QUALIFIED_NAME, createQualifiedName()); - AtlasAuthorizationUtils.verifyAccess(new AtlasEntityAccessRequest(typeRegistry, AtlasPrivilege.ENTITY_CREATE, new AtlasEntityHeader(entity)), - "create entity: type=", entity.getTypeName()); +// AtlasAuthorizationUtils.verifyAccess(new AtlasEntityAccessRequest(typeRegistry, AtlasPrivilege.ENTITY_CREATE, new AtlasEntityHeader(entity)), +// "create entity: type=", entity.getTypeName()); + //verifyAccess(entity.getTypeName(), (String) entity.getAttribute(QUALIFIED_NAME), AtlasPrivilege.ENTITY_CREATE.getType()); + AuthorizerUtils.verifyEntityCreateAccess(entity, AtlasPrivilege.ENTITY_CREATE); RequestContext.get().endMetricRecord(metricRecorder); } diff --git a/repository/src/main/java/org/apache/atlas/repository/store/graph/v2/preprocessor/resource/AbstractResourcePreProcessor.java b/repository/src/main/java/org/apache/atlas/repository/store/graph/v2/preprocessor/resource/AbstractResourcePreProcessor.java index 5bd89e4597..819885a6b7 100644 --- a/repository/src/main/java/org/apache/atlas/repository/store/graph/v2/preprocessor/resource/AbstractResourcePreProcessor.java +++ b/repository/src/main/java/org/apache/atlas/repository/store/graph/v2/preprocessor/resource/AbstractResourcePreProcessor.java @@ -18,9 +18,8 @@ package org.apache.atlas.repository.store.graph.v2.preprocessor.resource; import org.apache.atlas.RequestContext; -import org.apache.atlas.authorize.AtlasAuthorizationUtils; -import org.apache.atlas.authorize.AtlasEntityAccessRequest; import org.apache.atlas.authorize.AtlasPrivilege; +import org.apache.atlas.authorizer.AuthorizerUtils; import org.apache.atlas.exception.AtlasBaseException; import org.apache.atlas.model.instance.AtlasEntity; import org.apache.atlas.model.instance.AtlasEntityHeader; @@ -135,6 +134,7 @@ private void verifyAccess(AtlasEntity entity, AtlasPrivilege privilege) throws A private void verifyAccess(AtlasEntityHeader entityHeader, AtlasPrivilege privilege) throws AtlasBaseException { String errorMessage = privilege.name() + " entity: " + entityHeader.getTypeName(); - AtlasAuthorizationUtils.verifyAccess(new AtlasEntityAccessRequest(typeRegistry, privilege, entityHeader), errorMessage); + //AtlasAuthorizationUtils.verifyAccess(new AtlasEntityAccessRequest(typeRegistry, privilege, entityHeader), errorMessage); + AuthorizerUtils.verifyAccess(entityHeader, privilege); } } diff --git a/repository/src/main/java/org/apache/atlas/repository/util/AccessControlUtils.java b/repository/src/main/java/org/apache/atlas/repository/util/AccessControlUtils.java index f222d909b6..b61c8d84ed 100644 --- a/repository/src/main/java/org/apache/atlas/repository/util/AccessControlUtils.java +++ b/repository/src/main/java/org/apache/atlas/repository/util/AccessControlUtils.java @@ -79,6 +79,7 @@ public final class AccessControlUtils { public static final String ATTR_POLICY_ACTIONS = "policyActions"; public static final String ATTR_POLICY_CATEGORY = "policyCategory"; public static final String ATTR_POLICY_SUB_CATEGORY = "policySubCategory"; + public static final String ATTR_POLICY_FILTER_CRITERIA = "policyFilterCriteria"; public static final String ATTR_POLICY_RESOURCES = "policyResources"; public static final String ATTR_POLICY_IS_ENABLED = "isPolicyEnabled"; public static final String ATTR_POLICY_CONNECTION_QN = "connectionQualifiedName"; @@ -98,6 +99,7 @@ public final class AccessControlUtils { public static final String ACCESS_READ_PERSONA_DOMAIN = "persona-domain-read"; public static final String ACCESS_READ_PERSONA_SUB_DOMAIN = "persona-domain-sub-domain-read"; public static final String ACCESS_READ_PERSONA_PRODUCT = "persona-domain-product-read"; + public static final String ACCESS_READ_DOMAIN = "domain-entity-read"; public static final String POLICY_CATEGORY_PERSONA = "persona"; public static final String POLICY_CATEGORY_PURPOSE = "purpose"; @@ -126,6 +128,8 @@ public final class AccessControlUtils { public static final String INSTANCE_DOMAIN_KEY = "instance"; + public static final String POLICY_SERVICE_NAME_ABAC = "atlas_abac"; + private AccessControlUtils() {} public static String getEntityName(AtlasEntity entity) { @@ -177,6 +181,14 @@ public static String getPolicyCategory(AtlasEntity policyEntity) { return getStringAttribute(policyEntity, ATTR_POLICY_CATEGORY); } + public static String getPolicyFilterCriteria(AtlasEntity policyEntity) { + return getStringAttribute(policyEntity, ATTR_POLICY_FILTER_CRITERIA); + } + + public static String getPolicyFilterCriteria(AtlasEntityHeader policyEntity) { + return getStringAttribute(policyEntity, ATTR_POLICY_FILTER_CRITERIA); + } + public static String getPolicyResourceCategory(AtlasEntity policyEntity) { return getStringAttribute(policyEntity, ATTR_POLICY_RESOURCES_CATEGORY); } @@ -201,6 +213,10 @@ public static String getPolicyServiceName(AtlasEntity policyEntity) { return getStringAttribute(policyEntity, ATTR_POLICY_SERVICE_NAME); } + public static String getPolicyServiceName(AtlasEntityHeader policyEntity) { + return getStringAttribute(policyEntity, ATTR_POLICY_SERVICE_NAME); + } + public static String getPolicyType(AtlasEntity policyEntity) { return getStringAttribute(policyEntity, ATTR_POLICY_TYPE); } diff --git a/repository/src/main/resources/atlas-servicedef-atlas.json b/repository/src/main/resources/atlas-servicedef-atlas.json new file mode 100644 index 0000000000..0539a562b9 --- /dev/null +++ b/repository/src/main/resources/atlas-servicedef-atlas.json @@ -0,0 +1,502 @@ +{ + "id": 15, + "name": "atlas", + "displayName": "atlas", + "implClass": "org.apache.atlas.services.atlas.RangerServiceAtlas", + "label": "Atlas Metadata Server", + "description": "Atlas Metadata Server", + "guid": "311a79b7-16f5-46f4-9829-a0224b9999c5", + "resources": [ + { + "itemId": 1, + "name": "type-category", + "type": "string", + "level": 10, + "mandatory": true, + "lookupSupported": true, + "recursiveSupported": false, + "excludesSupported": true, + "matcher": "org.apache.atlas.plugin.resourcematcher.RangerDefaultResourceMatcher", + "matcherOptions": { + "wildCard": "true", + "ignoreCase": "true" + }, + "label": "Type Catagory", + "description": "Type Catagory" + }, + { + "itemId": 2, + "name": "type", + "type": "string", + "level": 20, + "mandatory": true, + "parent": "type-category", + "isValidLeaf": true, + "lookupSupported": true, + "recursiveSupported": false, + "excludesSupported": true, + "matcher": "org.apache.atlas.plugin.resourcematcher.RangerDefaultResourceMatcher", + "matcherOptions": { + "wildCard": "true", + "ignoreCase": "false" + }, + "label": "Type Name", + "description": "Type Name", + "accessTypeRestrictions": ["type-read" ,"type-create", "type-update", "type-delete" ] + }, + { + "itemId": 3, + "name": "entity-type", + "type": "string", + "level": 10, + "mandatory": true, + "lookupSupported": true, + "recursiveSupported": false, + "excludesSupported": true, + "matcher": "org.apache.atlas.plugin.resourcematcher.RangerDefaultResourceMatcher", + "matcherOptions": { + "wildCard": "true", + "ignoreCase": "false" + }, + "label": "Entity Type", + "description": "Entity Type" + }, + { + "itemId": 4, + "name": "entity-classification", + "type": "string", + "level": 20, + "mandatory": true, + "parent": "entity-type", + "lookupSupported": true, + "recursiveSupported": false, + "excludesSupported": true, + "matcher": "org.apache.atlas.plugin.resourcematcher.RangerDefaultResourceMatcher", + "matcherOptions": { + "wildCard": "true", + "ignoreCase": "false" + }, + "label": "Entity Classification", + "description": "Entity Classification" + }, + { + "itemId": 5, + "name": "entity", + "type": "string", + "level": 30, + "mandatory": true, + "parent": "entity-classification", + "isValidLeaf": true, + "lookupSupported": true, + "recursiveSupported": false, + "excludesSupported": true, + "matcher": "org.apache.atlas.plugin.resourcematcher.RangerDefaultResourceMatcher", + "matcherOptions": { + "wildCard": "true", + "ignoreCase": "true" + }, + "label": "Entity ID", + "description": "Entity ID", + "accessTypeRestrictions": ["entity-read", "entity-create", "entity-update", "entity-delete"] + }, + { + "itemId": 6, + "name": "atlas-service", + "type": "string", + "level": 10, + "mandatory": true, + "lookupSupported": true, + "recursiveSupported": false, + "excludesSupported": true, + "matcher": "org.apache.atlas.plugin.resourcematcher.RangerDefaultResourceMatcher", + "matcherOptions": { + "wildCard": "true", + "ignoreCase": "true" + }, + "label": "Atlas Service", + "description": "Atlas Service", + "accessTypeRestrictions": ["admin-import", "admin-export", "admin-purge", "admin-audits", "admin-entity-audits", "admin-repair-index", "admin-task-cud"] + }, + { + "itemId": 7, + "name": "relationship-type", + "type": "string", + "level": 10, + "mandatory": true, + "lookupSupported": true, + "recursiveSupported": false, + "excludesSupported": true, + "matcher": "org.apache.atlas.plugin.resourcematcher.RangerDefaultResourceMatcher", + "matcherOptions": { + "wildCard": "true", + "ignoreCase": "false" + }, + "label": "Relationship Type", + "description": "Relationship Type" + }, + { + "itemId": 8, + "name": "end-one-entity-type", + "type": "string", + "level": 20, + "mandatory": true, + "parent": "relationship-type", + "lookupSupported": true, + "recursiveSupported": false, + "excludesSupported": true, + "matcher": "org.apache.atlas.plugin.resourcematcher.RangerDefaultResourceMatcher", + "matcherOptions": { + "wildCard": "true", + "ignoreCase": "false" + }, + "label": "End1 Entity Type", + "description": "End1 Entity Type" + }, + { + "itemId": 9, + "name": "end-one-entity-classification", + "type": "string", + "level": 30, + "mandatory": true, + "parent": "end-one-entity-type", + "lookupSupported": true, + "recursiveSupported": false, + "excludesSupported": true, + "matcher": "org.apache.atlas.plugin.resourcematcher.RangerDefaultResourceMatcher", + "matcherOptions": { + "wildCard": "true", + "ignoreCase": "false" + }, + "label": "End1 Entity Classification", + "description": "End1 Entity Classification" + }, + { + "itemId": 10, + "name": "end-one-entity", + "type": "string", + "level": 40, + "mandatory": true, + "parent": "end-one-entity-classification", + "lookupSupported": true, + "recursiveSupported": false, + "excludesSupported": true, + "matcher": "org.apache.atlas.plugin.resourcematcher.RangerDefaultResourceMatcher", + "matcherOptions": { + "wildCard": "true", + "ignoreCase": "true" + }, + "label": "End1 Entity ID", + "description": "End1 Entity ID" + }, + { + "itemId": 11, + "name": "end-two-entity-type", + "type": "string", + "level": 50, + "mandatory": true, + "parent": "end-one-entity", + "lookupSupported": true, + "recursiveSupported": false, + "excludesSupported": true, + "matcher": "org.apache.atlas.plugin.resourcematcher.RangerDefaultResourceMatcher", + "matcherOptions": { + "wildCard": "true", + "ignoreCase": "false" + }, + "label": "End2 Entity Type", + "description": "End2 Entity Type" + }, + { + "itemId": 12, + "name": "end-two-entity-classification", + "type": "string", + "level": 60, + "mandatory": true, + "parent": "end-two-entity-type", + "lookupSupported": true, + "recursiveSupported": false, + "excludesSupported": true, + "matcher": "org.apache.atlas.plugin.resourcematcher.RangerDefaultResourceMatcher", + "matcherOptions": { + "wildCard": "true", + "ignoreCase": "false" + }, + "label": "End2 Entity Classification", + "description": "End2 Entity Classification" + }, + { + "itemId": 13, + "name": "end-two-entity", + "type": "string", + "level": 70, + "mandatory": true, + "parent": "end-two-entity-classification", + "isValidLeaf": true, + "lookupSupported": true, + "recursiveSupported": false, + "excludesSupported": true, + "matcher": "org.apache.atlas.plugin.resourcematcher.RangerDefaultResourceMatcher", + "matcherOptions": { + "wildCard": "true", + "ignoreCase": "true" + }, + "label": "End2 Entity ID", + "description": "End2 Entity ID", + "accessTypeRestrictions": [ + "add-relationship", + "update-relationship", + "remove-relationship" + ] + }, + { + "itemId": 14, + "name": "entity-label", + "type": "string", + "level": 40, + "mandatory": true, + "parent": "entity", + "isValidLeaf": true, + "lookupSupported": true, + "recursiveSupported": false, + "excludesSupported": true, + "matcher": "org.apache.atlas.plugin.resourcematcher.RangerDefaultResourceMatcher", + "matcherOptions": { + "wildCard": "true", + "ignoreCase": "true" + }, + "label": "Label", + "description": "Label", + "accessTypeRestrictions": [ + "entity-add-label", + "entity-remove-label" + ] + }, + { + "itemId": 15, + "name": "entity-business-metadata", + "type": "string", + "level": 40, + "mandatory": true, + "parent": "entity", + "isValidLeaf": true, + "lookupSupported": true, + "recursiveSupported": false, + "excludesSupported": true, + "matcher": "org.apache.atlas.plugin.resourcematcher.RangerDefaultResourceMatcher", + "matcherOptions": { + "wildCard": "true", + "ignoreCase": "true" + }, + "label": "Business Metadata", + "description": "Business Metadata", + "accessTypeRestrictions": [ + "entity-update-business-metadata" + ] + }, + { + "itemId": 16, + "name": "classification", + "type": "string", + "level": 40, + "mandatory": true, + "parent": "entity", + "isValidLeaf": true, + "lookupSupported": true, + "recursiveSupported": false, + "excludesSupported": true, + "matcher": "org.apache.atlas.plugin.resourcematcher.RangerDefaultResourceMatcher", + "matcherOptions": { + "wildCard": "true", + "ignoreCase": "false" + }, + "label": "Targetted classifications", + "description": "Targetted classifications", + "accessTypeRestrictions": [ + "entity-add-classification", + "entity-update-classification", + "entity-remove-classification" + ] + } + ], + "accessTypes": [ + { + "itemId": 1, + "name": "type-create", + "label": "Create Type", + "impliedGrants": + [ + "type-read" + ] + }, + { + "itemId": 2, + "name": "type-update", + "label": "Update Type", + "impliedGrants": + [ + "type-read" + ] + }, + { + "itemId": 3, + "name": "type-delete", + "label": "Delete Type", + "impliedGrants": + [ + "type-read" + ] + }, + { + "itemId": 4, + "name": "entity-read", + "label": "Read Entity" + }, + { + "itemId": 5, + "name": "entity-create", + "label": "Create Entity" + }, + { + "itemId": 6, + "name": "entity-update", + "label": "Update Entity" + }, + { + "itemId": 7, + "name": "entity-delete", + "label": "Delete Entity" + }, + { + "itemId": 8, + "name": "entity-add-classification", + "label": "Add Classification" + }, + { + "itemId": 9, + "name": "entity-update-classification", + "label": "Update Classification" + }, + { + "itemId": 10, + "name": "entity-remove-classification", + "label": "Remove Classification" + }, + { + "itemId": 11, + "name": "admin-export", + "label": "Admin Export" + }, + { + "itemId": 12, + "name": "admin-import", + "label": "Admin Import" + }, + { + "itemId": 13, + "name": "add-relationship", + "label": "Add Relationship" + }, + { + "itemId": 14, + "name": "update-relationship", + "label": "Update Relationship" + }, + { + "itemId": 15, + "name": "remove-relationship", + "label": "Remove Relationship" + }, + { + "itemId": 16, + "name": "admin-purge", + "label": "Admin Purge" + }, + { + "itemId": 17, + "name": "entity-add-label", + "label": "Add Label" + }, + { + "itemId": 18, + "name": "entity-remove-label", + "label": "Remove Label" + }, + { + "itemId": 19, + "name": "entity-update-business-metadata", + "label": "Update Business Metadata" + }, + { + "itemId": 20, + "name": "type-read", + "label": "Read Type" + }, + { + "itemId": 21, + "name": "admin-audits", + "label": "Admin Audits" + }, + { + "itemId": 22, + "name": "admin-entity-audits", + "label": "Admin Entity Audits" + }, + { + "itemId": 23, + "name": "admin-repair-index", + "label": "Admin Repair Index" + }, + { + "itemId": 24, + "name": "admin-task-cud", + "label": "Admin task CUD API" + } + + ], + "configs": [ + { + "itemId": 1, + "name": "username", + "type": "string", + "mandatory": true, + "label": "Username" + }, + { + "itemId": 2, + "name": "password", + "type": "password", + "mandatory": true, + "label": "Password" + }, + { + "itemId": 3, + "name": "atlas.rest.address", + "type": "string", + "mandatory": true, + "defaultValue": "http://localhost:21000" + }, + { + "itemId": 4, + "name": "commonNameForCertificate", + "type": "string", + "mandatory": false, + "label": "Common Name for Certificate" + }, + + { + "itemId": 5, + "name": "ranger.plugin.audit.filters", + "type": "string", + "subType": "", + "mandatory": false, + "validationRegEx":"", + "validationMessage": "", + "uiHint":"", + "label": "Ranger Default Audit Filters", + "defaultValue": "[ {'accessResult': 'DENIED', 'isAudited': true}, {'users':['atlas'] ,'isAudited':false} ]" + } + ], + "options": { + "enableDenyAndExceptionsInPolicies": "true" + } +} diff --git a/webapp/src/main/java/org/apache/atlas/web/rest/EntityREST.java b/webapp/src/main/java/org/apache/atlas/web/rest/EntityREST.java index 846a023a1f..4bdab3bdfc 100644 --- a/webapp/src/main/java/org/apache/atlas/web/rest/EntityREST.java +++ b/webapp/src/main/java/org/apache/atlas/web/rest/EntityREST.java @@ -24,6 +24,7 @@ import org.apache.atlas.RequestContext; import org.apache.atlas.annotation.Timed; import org.apache.atlas.authorize.*; +import org.apache.atlas.authorizer.AuthorizerUtils; import org.apache.atlas.bulkimport.BulkImportResponse; import org.apache.atlas.exception.AtlasBaseException; import org.apache.atlas.model.TypeCategory; @@ -127,7 +128,9 @@ public EntityREST(AtlasTypeRegistry typeRegistry, AtlasEntityStore entitiesStore @GET @Path("/guid/{guid}") @Timed - public AtlasEntityWithExtInfo getById(@PathParam("guid") String guid, @QueryParam("minExtInfo") @DefaultValue("false") boolean minExtInfo, @QueryParam("ignoreRelationships") @DefaultValue("false") boolean ignoreRelationships) throws AtlasBaseException { + public AtlasEntityWithExtInfo getById(@PathParam("guid") String guid, + @QueryParam("minExtInfo") @DefaultValue("true") boolean minExtInfo, + @QueryParam("ignoreRelationships") @DefaultValue("false") boolean ignoreRelationships) throws AtlasBaseException { Servlets.validateQueryParamLength("guid", guid); AtlasPerfTracer perf = null; @@ -137,7 +140,7 @@ public AtlasEntityWithExtInfo getById(@PathParam("guid") String guid, @QueryPara perf = AtlasPerfTracer.getPerfTracer(PERF_LOG, "EntityREST.getById(" + guid + ", " + minExtInfo + " )"); } - return entitiesStore.getById(guid, minExtInfo, ignoreRelationships); + return entitiesStore.getById(guid, minExtInfo); } finally { AtlasPerfTracer.log(perf); } @@ -159,9 +162,8 @@ public List evaluatePolicies(List evaluatePolicies(List evaluatePolicies(List getAccessors(List atlasAccessorRequestList) throws AtlasBaseException { + public List getAccessors(List atlasAccessorRequestList, + @QueryParam("v2") @DefaultValue("true") boolean v2Enabled) throws AtlasBaseException { + //TODO remove temporary QueryParam v2Enabled AtlasPerfTracer perf = null; List ret; @@ -249,7 +281,7 @@ public List getAccessors(List atlas try { validateAccessorRequest(atlasAccessorRequestList); - ret = entitiesStore.getAccessors(atlasAccessorRequestList); + ret = entitiesStore.getAccessors(atlasAccessorRequestList, v2Enabled); } finally { AtlasPerfTracer.log(perf); @@ -1151,7 +1183,8 @@ public EntityAuditSearchResult searchAuditEventsByGuid(AuditSearchParams paramet if (e.getAtlasErrorCode() == AtlasErrorCode.INSTANCE_GUID_NOT_FOUND) { AtlasEntityHeader entityHeader = getEntityHeaderFromPurgedAudit(guid); - AtlasAuthorizationUtils.verifyAccess(new AtlasEntityAccessRequest(typeRegistry, ENTITY_READ, entityHeader), "read entity audit: guid=", guid); +// AtlasAuthorizationUtils.verifyAccess(new AtlasEntityAccessRequest(typeRegistry, ENTITY_READ, entityHeader), "read entity audit: guid=", guid); + AuthorizerUtils.verifyAccess(entityHeader, ENTITY_READ); } else { throw e; }