You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ranger.apache.org by me...@apache.org on 2021/06/14 05:31:16 UTC
[ranger] branch master updated: RANGER-3195 - Atlas Ranger
Authorizer changes to add/update/remove classification on entities.
This is an automated email from the ASF dual-hosted git repository.
mehul pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/ranger.git
The following commit(s) were added to refs/heads/master by this push:
new 4bd4290 RANGER-3195 - Atlas Ranger Authorizer changes to add/update/remove classification on entities.
4bd4290 is described below
commit 4bd42903161404552bd5867b376c4fb081df290d
Author: nixonrodrigues <ni...@apache.org>
AuthorDate: Tue Mar 2 18:22:15 2021 +0530
RANGER-3195 - Atlas Ranger Authorizer changes to add/update/remove classification on entities.
Change-Id: If1eb2882a52c669e9ed101fa58b65f94452e706b
Signed-off-by: Mehul Parikh <me...@apache.org>
---
.../service-defs/ranger-servicedef-atlas.json | 42 ++-
.../atlas/authorizer/RangerAtlasAuthorizer.java | 40 +--
.../ranger/services/atlas/RangerServiceAtlas.java | 5 +-
.../optimized/current/ranger_core_db_mysql.sql | 1 +
.../optimized/current/ranger_core_db_oracle.sql | 1 +
.../optimized/current/ranger_core_db_postgres.sql | 1 +
.../current/ranger_core_db_sqlanywhere.sql | 2 +
.../optimized/current/ranger_core_db_sqlserver.sql | 1 +
...PatchAtlasForClassificationResource_J10047.java | 308 +++++++++++++++++++++
9 files changed, 370 insertions(+), 31 deletions(-)
diff --git a/agents-common/src/main/resources/service-defs/ranger-servicedef-atlas.json b/agents-common/src/main/resources/service-defs/ranger-servicedef-atlas.json
index d8331db..7495b79 100644
--- a/agents-common/src/main/resources/service-defs/ranger-servicedef-atlas.json
+++ b/agents-common/src/main/resources/service-defs/ranger-servicedef-atlas.json
@@ -38,7 +38,7 @@
"matcher": "org.apache.ranger.plugin.resourcematcher.RangerDefaultResourceMatcher",
"matcherOptions": {
"wildCard": "true",
- "ignoreCase": "true"
+ "ignoreCase": "false"
},
"label": "Type Name",
"description": "Type Name",
@@ -56,7 +56,7 @@
"matcher": "org.apache.ranger.plugin.resourcematcher.RangerDefaultResourceMatcher",
"matcherOptions": {
"wildCard": "true",
- "ignoreCase": "true"
+ "ignoreCase": "false"
},
"label": "Entity Type",
"description": "Entity Type"
@@ -74,7 +74,7 @@
"matcher": "org.apache.ranger.plugin.resourcematcher.RangerDefaultResourceMatcher",
"matcherOptions": {
"wildCard": "true",
- "ignoreCase": "true"
+ "ignoreCase": "false"
},
"label": "Entity Classification",
"description": "Entity Classification"
@@ -97,7 +97,7 @@
},
"label": "Entity ID",
"description": "Entity ID",
- "accessTypeRestrictions": ["entity-read", "entity-create", "entity-update", "entity-delete", "entity-add-classification", "entity-update-classification", "entity-remove-classification"]
+ "accessTypeRestrictions": ["entity-read", "entity-create", "entity-update", "entity-delete"]
},
{
"itemId": 6,
@@ -129,7 +129,7 @@
"matcher": "org.apache.ranger.plugin.resourcematcher.RangerDefaultResourceMatcher",
"matcherOptions": {
"wildCard": "true",
- "ignoreCase": "true"
+ "ignoreCase": "false"
},
"label": "Relationship Type",
"description": "Relationship Type"
@@ -147,7 +147,7 @@
"matcher": "org.apache.ranger.plugin.resourcematcher.RangerDefaultResourceMatcher",
"matcherOptions": {
"wildCard": "true",
- "ignoreCase": "true"
+ "ignoreCase": "false"
},
"label": "End1 Entity Type",
"description": "End1 Entity Type"
@@ -165,7 +165,7 @@
"matcher": "org.apache.ranger.plugin.resourcematcher.RangerDefaultResourceMatcher",
"matcherOptions": {
"wildCard": "true",
- "ignoreCase": "true"
+ "ignoreCase": "false"
},
"label": "End1 Entity Classification",
"description": "End1 Entity Classification"
@@ -201,7 +201,7 @@
"matcher": "org.apache.ranger.plugin.resourcematcher.RangerDefaultResourceMatcher",
"matcherOptions": {
"wildCard": "true",
- "ignoreCase": "true"
+ "ignoreCase": "false"
},
"label": "End2 Entity Type",
"description": "End2 Entity Type"
@@ -219,7 +219,7 @@
"matcher": "org.apache.ranger.plugin.resourcematcher.RangerDefaultResourceMatcher",
"matcherOptions": {
"wildCard": "true",
- "ignoreCase": "true"
+ "ignoreCase": "false"
},
"label": "End2 Entity Classification",
"description": "End2 Entity Classification"
@@ -292,6 +292,30 @@
"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.ranger.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": [
diff --git a/plugin-atlas/src/main/java/org/apache/ranger/authorization/atlas/authorizer/RangerAtlasAuthorizer.java b/plugin-atlas/src/main/java/org/apache/ranger/authorization/atlas/authorizer/RangerAtlasAuthorizer.java
index 79ef604..2fe7338 100644
--- a/plugin-atlas/src/main/java/org/apache/ranger/authorization/atlas/authorizer/RangerAtlasAuthorizer.java
+++ b/plugin-atlas/src/main/java/org/apache/ranger/authorization/atlas/authorizer/RangerAtlasAuthorizer.java
@@ -57,6 +57,12 @@ public class RangerAtlasAuthorizer implements AtlasAuthorizer {
private static final Log LOG = LogFactory.getLog(RangerAtlasAuthorizer.class);
private static final Log PERF_LOG = RangerPerfTracer.getPerfLogger("atlasauth.request");
+ private static final Set<AtlasPrivilege> CLASSIFICATION_PRIVILEGES = new HashSet<AtlasPrivilege>() {{
+ add(AtlasPrivilege.ENTITY_ADD_CLASSIFICATION);
+ add(AtlasPrivilege.ENTITY_REMOVE_CLASSIFICATION);
+ add(AtlasPrivilege.ENTITY_UPDATE_CLASSIFICATION);
+ }};
+
private static volatile RangerBasePlugin atlasPlugin = null;
@Override
@@ -372,7 +378,7 @@ public class RangerAtlasAuthorizer implements AtlasAuthorizer {
LOG.debug("==> isAccessAllowed(" + request + ")");
}
- boolean ret = true;
+ boolean ret = false;
try {
final String action = request.getAction() != null ? request.getAction().getType() : null;
@@ -400,31 +406,25 @@ public class RangerAtlasAuthorizer implements AtlasAuthorizer {
rangerResource.setValue(RESOURCE_ENTITY_LABEL, request.getLabel());
} else if (AtlasPrivilege.ENTITY_UPDATE_BUSINESS_METADATA.equals(request.getAction())) {
rangerResource.setValue(RESOURCE_ENTITY_BUSINESS_METADATA, request.getBusinessMetadata());
+ } else if (StringUtils.isNotEmpty(classification) && CLASSIFICATION_PRIVILEGES.contains(request.getAction())) {
+ rangerResource.setValue(RESOURCE_CLASSIFICATION, request.getClassificationTypeAndAllSuperTypes(classification));
}
- if (StringUtils.isNotEmpty(classification)) {
- rangerResource.setValue(RESOURCE_ENTITY_CLASSIFICATION, request.getClassificationTypeAndAllSuperTypes(classification));
-
- ret = checkAccess(rangerRequest, auditHandler);
- }
-
- if (ret) {
- if (CollectionUtils.isNotEmpty(request.getEntityClassifications())) {
- // check authorization for each classification
- for (String classificationToAuthorize : request.getEntityClassifications()) {
- rangerResource.setValue(RESOURCE_ENTITY_CLASSIFICATION, request.getClassificationTypeAndAllSuperTypes(classificationToAuthorize));
+ if (CollectionUtils.isNotEmpty(request.getEntityClassifications())) {
+ // check authorization for each classification
+ for (String classificationToAuthorize : request.getEntityClassifications()) {
+ rangerResource.setValue(RESOURCE_ENTITY_CLASSIFICATION, request.getClassificationTypeAndAllSuperTypes(classificationToAuthorize));
- ret = checkAccess(rangerRequest, auditHandler);
+ ret = checkAccess(rangerRequest, auditHandler);
- if (!ret) {
- break;
- }
+ if (!ret) {
+ break;
}
- } else {
- rangerResource.setValue(RESOURCE_ENTITY_CLASSIFICATION, ENTITY_NOT_CLASSIFIED);
-
- ret = checkAccess(rangerRequest, auditHandler);
}
+ } else {
+ rangerResource.setValue(RESOURCE_ENTITY_CLASSIFICATION, ENTITY_NOT_CLASSIFIED );
+
+ ret = checkAccess(rangerRequest, auditHandler);
}
} finally {
diff --git a/plugin-atlas/src/main/java/org/apache/ranger/services/atlas/RangerServiceAtlas.java b/plugin-atlas/src/main/java/org/apache/ranger/services/atlas/RangerServiceAtlas.java
index c13633a..4851d87 100644
--- a/plugin-atlas/src/main/java/org/apache/ranger/services/atlas/RangerServiceAtlas.java
+++ b/plugin-atlas/src/main/java/org/apache/ranger/services/atlas/RangerServiceAtlas.java
@@ -62,6 +62,7 @@ public class RangerServiceAtlas extends RangerBaseService {
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";
@@ -172,7 +173,7 @@ public class RangerServiceAtlas extends RangerBaseService {
}
// 2. add a policy-item for rangertagsync user with 'entity-read' permission in the policy for 'entity-type'
- if (policyResources.containsKey(RangerServiceAtlas.RESOURCE_ENTITY_TYPE)) {
+ if (policyResources.containsKey(RESOURCE_ENTITY_TYPE) && !policyResources.containsKey(RESOURCE_CLASSIFICATION)) {
RangerPolicyItem policyItemForTagSyncUser = new RangerPolicyItem();
policyItemForTagSyncUser.setUsers(Collections.singletonList(tagSyncUser));
@@ -193,7 +194,7 @@ public class RangerServiceAtlas extends RangerBaseService {
if (defaultPolicy.getName().contains("all")
&& policyResources.containsKey(RangerServiceAtlas.RESOURCE_ENTITY_TYPE)
- && StringUtils.isNotBlank(lookUpUser)) {
+ && StringUtils.isNotBlank(lookUpUser) && !policyResources.containsKey(RESOURCE_CLASSIFICATION)) {
RangerPolicyItem policyItemForLookupUser = new RangerPolicyItem();
policyItemForLookupUser.setUsers(Collections.singletonList(lookUpUser));
policyItemForLookupUser.setAccesses(Collections.singletonList(new RangerPolicyItemAccess(ACCESS_TYPE_ENTITY_READ)));
diff --git a/security-admin/db/mysql/optimized/current/ranger_core_db_mysql.sql b/security-admin/db/mysql/optimized/current/ranger_core_db_mysql.sql
index 8934549..2024e62 100644
--- a/security-admin/db/mysql/optimized/current/ranger_core_db_mysql.sql
+++ b/security-admin/db/mysql/optimized/current/ranger_core_db_mysql.sql
@@ -1841,6 +1841,7 @@ INSERT INTO x_db_version_h (version,inst_at,inst_by,updated_at,updated_by,active
INSERT INTO x_db_version_h (version,inst_at,inst_by,updated_at,updated_by,active) VALUES ('J10044',UTC_TIMESTAMP(),'Ranger 1.0.0',UTC_TIMESTAMP(),'localhost','Y');
INSERT INTO x_db_version_h (version,inst_at,inst_by,updated_at,updated_by,active) VALUES ('J10045',UTC_TIMESTAMP(),'Ranger 1.0.0',UTC_TIMESTAMP(),'localhost','Y');
INSERT INTO x_db_version_h (version,inst_at,inst_by,updated_at,updated_by,active) VALUES ('J10046',UTC_TIMESTAMP(),'Ranger 1.0.0',UTC_TIMESTAMP(),'localhost','Y');
+INSERT INTO x_db_version_h (version,inst_at,inst_by,updated_at,updated_by,active) VALUES ('J10047',UTC_TIMESTAMP(),'Ranger 2.2.0',UTC_TIMESTAMP(),'localhost','Y');
INSERT INTO x_db_version_h (version,inst_at,inst_by,updated_at,updated_by,active) VALUES ('J10049',UTC_TIMESTAMP(),'Ranger 1.0.0',UTC_TIMESTAMP(),'localhost','Y');
INSERT INTO x_db_version_h (version,inst_at,inst_by,updated_at,updated_by,active) VALUES ('J10050',UTC_TIMESTAMP(),'Ranger 1.0.0',UTC_TIMESTAMP(),'localhost','Y');
INSERT INTO x_db_version_h (version,inst_at,inst_by,updated_at,updated_by,active) VALUES ('JAVA_PATCHES',UTC_TIMESTAMP(),'Ranger 1.0.0',UTC_TIMESTAMP(),'localhost','Y');
diff --git a/security-admin/db/oracle/optimized/current/ranger_core_db_oracle.sql b/security-admin/db/oracle/optimized/current/ranger_core_db_oracle.sql
index 4cd84ee..d2c4f27 100644
--- a/security-admin/db/oracle/optimized/current/ranger_core_db_oracle.sql
+++ b/security-admin/db/oracle/optimized/current/ranger_core_db_oracle.sql
@@ -2056,6 +2056,7 @@ INSERT INTO x_db_version_h (id,version,inst_at,inst_by,updated_at,updated_by,act
INSERT INTO x_db_version_h (id,version,inst_at,inst_by,updated_at,updated_by,active) VALUES (X_DB_VERSION_H_SEQ.nextval,'J10044',sys_extract_utc(systimestamp),'Ranger 1.0.0',sys_extract_utc(systimestamp),'localhost','Y');
INSERT INTO x_db_version_h (id,version,inst_at,inst_by,updated_at,updated_by,active) VALUES (X_DB_VERSION_H_SEQ.nextval,'J10045',sys_extract_utc(systimestamp),'Ranger 1.0.0',sys_extract_utc(systimestamp),'localhost','Y');
INSERT INTO x_db_version_h (id,version,inst_at,inst_by,updated_at,updated_by,active) VALUES (X_DB_VERSION_H_SEQ.nextval,'J10046',sys_extract_utc(systimestamp),'Ranger 1.0.0',sys_extract_utc(systimestamp),'localhost','Y');
+INSERT INTO x_db_version_h (id,version,inst_at,inst_by,updated_at,updated_by,active) VALUES (X_DB_VERSION_H_SEQ.nextval,'J10047',sys_extract_utc(systimestamp),'Ranger 2.2.0',sys_extract_utc(systimestamp),'localhost','Y');
INSERT INTO x_db_version_h (id,version,inst_at,inst_by,updated_at,updated_by,active) VALUES (X_DB_VERSION_H_SEQ.nextval,'J10049',sys_extract_utc(systimestamp),'Ranger 1.0.0',sys_extract_utc(systimestamp),'localhost','Y');
INSERT INTO x_db_version_h (id,version,inst_at,inst_by,updated_at,updated_by,active) VALUES (X_DB_VERSION_H_SEQ.nextval,'J10050',sys_extract_utc(systimestamp),'Ranger 1.0.0',sys_extract_utc(systimestamp),'localhost','Y');
INSERT INTO x_db_version_h (id,version,inst_at,inst_by,updated_at,updated_by,active) VALUES (X_DB_VERSION_H_SEQ.nextval,'JAVA_PATCHES',sys_extract_utc(systimestamp),'Ranger 1.0.0',sys_extract_utc(systimestamp),'localhost','Y');
diff --git a/security-admin/db/postgres/optimized/current/ranger_core_db_postgres.sql b/security-admin/db/postgres/optimized/current/ranger_core_db_postgres.sql
index 0e3afbc..0feeb23 100644
--- a/security-admin/db/postgres/optimized/current/ranger_core_db_postgres.sql
+++ b/security-admin/db/postgres/optimized/current/ranger_core_db_postgres.sql
@@ -1980,6 +1980,7 @@ INSERT INTO x_db_version_h (version,inst_at,inst_by,updated_at,updated_by,active
INSERT INTO x_db_version_h (version,inst_at,inst_by,updated_at,updated_by,active) VALUES ('J10044',current_timestamp,'Ranger 1.0.0',current_timestamp,'localhost','Y');
INSERT INTO x_db_version_h (version,inst_at,inst_by,updated_at,updated_by,active) VALUES ('J10045',current_timestamp,'Ranger 1.0.0',current_timestamp,'localhost','Y');
INSERT INTO x_db_version_h (version,inst_at,inst_by,updated_at,updated_by,active) VALUES ('J10046',current_timestamp,'Ranger 1.0.0',current_timestamp,'localhost','Y');
+INSERT INTO x_db_version_h (version,inst_at,inst_by,updated_at,updated_by,active) VALUES ('J10047',current_timestamp,'Ranger 2.2.0',current_timestamp,'localhost','Y');
INSERT INTO x_db_version_h (version,inst_at,inst_by,updated_at,updated_by,active) VALUES ('J10049',current_timestamp,'Ranger 1.0.0',current_timestamp,'localhost','Y');
INSERT INTO x_db_version_h (version,inst_at,inst_by,updated_at,updated_by,active) VALUES ('J10050',current_timestamp,'Ranger 1.0.0',current_timestamp,'localhost','Y');
INSERT INTO x_db_version_h (version,inst_at,inst_by,updated_at,updated_by,active) VALUES ('JAVA_PATCHES',current_timestamp,'Ranger 1.0.0',current_timestamp,'localhost','Y');
diff --git a/security-admin/db/sqlanywhere/optimized/current/ranger_core_db_sqlanywhere.sql b/security-admin/db/sqlanywhere/optimized/current/ranger_core_db_sqlanywhere.sql
index aca913d..0ea76b9 100644
--- a/security-admin/db/sqlanywhere/optimized/current/ranger_core_db_sqlanywhere.sql
+++ b/security-admin/db/sqlanywhere/optimized/current/ranger_core_db_sqlanywhere.sql
@@ -2405,6 +2405,8 @@ INSERT INTO x_db_version_h (version,inst_at,inst_by,updated_at,updated_by,active
GO
INSERT INTO x_db_version_h (version,inst_at,inst_by,updated_at,updated_by,active) VALUES ('J10046',CURRENT_TIMESTAMP,'Ranger 1.0.0',CURRENT_TIMESTAMP,'localhost','Y');
GO
+INSERT INTO x_db_version_h (version,inst_at,inst_by,updated_at,updated_by,active) VALUES ('J10047',CURRENT_TIMESTAMP,'Ranger 2.2.0',CURRENT_TIMESTAMP,'localhost','Y');
+GO
INSERT INTO x_db_version_h (version,inst_at,inst_by,updated_at,updated_by,active) VALUES ('J10049',CURRENT_TIMESTAMP,'Ranger 1.0.0',CURRENT_TIMESTAMP,'localhost','Y');
GO
INSERT INTO x_db_version_h (version,inst_at,inst_by,updated_at,updated_by,active) VALUES ('J10050',CURRENT_TIMESTAMP,'Ranger 1.0.0',CURRENT_TIMESTAMP,'localhost','Y');
diff --git a/security-admin/db/sqlserver/optimized/current/ranger_core_db_sqlserver.sql b/security-admin/db/sqlserver/optimized/current/ranger_core_db_sqlserver.sql
index 300308a..4eaa77c 100644
--- a/security-admin/db/sqlserver/optimized/current/ranger_core_db_sqlserver.sql
+++ b/security-admin/db/sqlserver/optimized/current/ranger_core_db_sqlserver.sql
@@ -4191,6 +4191,7 @@ INSERT INTO x_db_version_h (version,inst_at,inst_by,updated_at,updated_by,active
INSERT INTO x_db_version_h (version,inst_at,inst_by,updated_at,updated_by,active) VALUES ('J10044',CURRENT_TIMESTAMP,'Ranger 1.0.0',CURRENT_TIMESTAMP,'localhost','Y');
INSERT INTO x_db_version_h (version,inst_at,inst_by,updated_at,updated_by,active) VALUES ('J10045',CURRENT_TIMESTAMP,'Ranger 1.0.0',CURRENT_TIMESTAMP,'localhost','Y');
INSERT INTO x_db_version_h (version,inst_at,inst_by,updated_at,updated_by,active) VALUES ('J10046',CURRENT_TIMESTAMP,'Ranger 1.0.0',CURRENT_TIMESTAMP,'localhost','Y');
+INSERT INTO x_db_version_h (version,inst_at,inst_by,updated_at,updated_by,active) VALUES ('J10047',CURRENT_TIMESTAMP,'Ranger 2.2.0',CURRENT_TIMESTAMP,'localhost','Y');
INSERT INTO x_db_version_h (version,inst_at,inst_by,updated_at,updated_by,active) VALUES ('J10049',CURRENT_TIMESTAMP,'Ranger 1.0.0',CURRENT_TIMESTAMP,'localhost','Y');
INSERT INTO x_db_version_h (version,inst_at,inst_by,updated_at,updated_by,active) VALUES ('J10050',CURRENT_TIMESTAMP,'Ranger 1.0.0',CURRENT_TIMESTAMP,'localhost','Y');
INSERT INTO x_db_version_h (version,inst_at,inst_by,updated_at,updated_by,active) VALUES ('JAVA_PATCHES',CURRENT_TIMESTAMP,'Ranger 1.0.0',CURRENT_TIMESTAMP,'localhost','Y');
diff --git a/security-admin/src/main/java/org/apache/ranger/patch/PatchAtlasForClassificationResource_J10047.java b/security-admin/src/main/java/org/apache/ranger/patch/PatchAtlasForClassificationResource_J10047.java
new file mode 100644
index 0000000..e60ff73
--- /dev/null
+++ b/security-admin/src/main/java/org/apache/ranger/patch/PatchAtlasForClassificationResource_J10047.java
@@ -0,0 +1,308 @@
+/*
+ * 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.ranger.patch;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.ListIterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Date;
+import org.apache.log4j.Logger;
+import org.apache.ranger.biz.ServiceDBStore;
+import org.apache.ranger.common.RangerValidatorFactory;
+import org.apache.ranger.db.RangerDaoManager;
+import org.apache.ranger.entity.XXService;
+import org.apache.ranger.entity.XXServiceDef;
+import org.apache.ranger.plugin.model.RangerPolicy;
+import org.apache.ranger.plugin.model.RangerPolicy.RangerPolicyItem;
+import org.apache.ranger.plugin.model.RangerPolicy.RangerPolicyItemAccess;
+import org.apache.ranger.plugin.model.RangerPolicy.RangerPolicyResource;
+import org.apache.ranger.plugin.model.RangerServiceDef;
+import org.apache.ranger.plugin.model.RangerServiceDef.RangerAccessTypeDef;
+import org.apache.ranger.plugin.model.validation.RangerServiceDefValidator;
+import org.apache.ranger.plugin.model.validation.RangerValidator;
+import org.apache.ranger.plugin.store.EmbeddedServiceDefsUtil;
+import org.apache.ranger.plugin.util.SearchFilter;
+import org.springframework.stereotype.Component;
+import org.springframework.beans.factory.annotation.Autowired;
+import static org.apache.ranger.plugin.store.EmbeddedServiceDefsUtil.EMBEDDED_SERVICEDEF_ATLAS_NAME;
+
+@Component
+public class PatchAtlasForClassificationResource_J10047 extends BaseLoader {
+
+
+ private static final Logger logger = Logger.getLogger(PatchAtlasForClassificationResource_J10047.class);
+
+
+ private static final List<String> ATLAS_RESOURCES = new ArrayList<>(
+ Arrays.asList( "classification"));
+
+ private static final List<String> ATLAS_ACCESS_TYPES = new ArrayList<>(
+ Arrays.asList("entity-remove-classification", "entity-add-classification", "entity-update-classification"));
+
+ private static final List<String> ATLAS_RESOURCE_ENTITY = new ArrayList<>(
+ Arrays.asList("entity-type", "entity-classification", "entity"));
+
+ private static final String ENTITY_CLASSIFICATION = "entity-classification";
+
+ private static final String CLASSIFICATION = "classification";
+
+ private static final String ENTITY = "entity";
+
+ private static final List<String> TYPES = new ArrayList<>(
+ Arrays.asList("type", "entity-type", "entity-classification", "relationship-type", "end-one-entity-type",
+ "end-one-entity-classification","end-two-entity-type","end-two-entity-classification","entity-business-metadata"));
+
+ @Autowired
+ RangerDaoManager daoMgr;
+
+ @Autowired
+ ServiceDBStore svcDBStore;
+
+ @Autowired
+ RangerValidatorFactory validatorFactory;
+
+ @Autowired
+ ServiceDBStore svcStore;
+
+
+ public static void main(String[] args) {
+ logger.info("main()");
+ try {
+ PatchAtlasForClassificationResource_J10047 loader = (PatchAtlasForClassificationResource_J10047) org.apache.ranger.util.CLIUtil
+ .getBean(PatchAtlasForClassificationResource_J10047.class);
+ loader.init();
+ while (loader.isMoreToProcess()) {
+ loader.load();
+ }
+ logger.info("Load complete. Exiting!!!");
+ System.exit(0);
+ } catch (Exception e) {
+ logger.error("Error loading", e);
+ System.exit(1);
+ }
+ }
+
+ @Override
+ public void init() throws Exception {
+ // Do Nothing
+ }
+
+ @Override
+ public void execLoad() {
+ logger.info("==> PatchAtlasForClassificationResource_J10047.execLoad()");
+ try {
+ addResourceClassificationsInServiceDef();
+ createAdditionalPolicyWithClassificationForExistingEntityClassificationPolicy();
+ } catch (Exception e) {
+ e.printStackTrace();
+ throw new RuntimeException("Error while updating " + EMBEDDED_SERVICEDEF_ATLAS_NAME + " service-def");
+ }
+ logger.info("<== PatchAtlasForClassificationResource_J10047.execLoad()");
+ }
+
+ @Override
+ public void printStats() {
+ logger.info("PatchAtlasForClassificationResource_J10047 Logs");
+ }
+
+ private void addResourceClassificationsInServiceDef() throws Exception {
+ RangerServiceDef ret = null;
+ RangerServiceDef embeddedAtlasServiceDef = null;
+ XXServiceDef xXServiceDefObj = null;
+ RangerServiceDef dbAtlasServiceDef = null;
+
+
+ embeddedAtlasServiceDef = EmbeddedServiceDefsUtil.instance().getEmbeddedServiceDef(EMBEDDED_SERVICEDEF_ATLAS_NAME);
+ if (embeddedAtlasServiceDef != null) {
+ xXServiceDefObj = daoMgr.getXXServiceDef().findByName(EMBEDDED_SERVICEDEF_ATLAS_NAME);
+ if (xXServiceDefObj == null) {
+ logger.info(" service-def for "+ EMBEDDED_SERVICEDEF_ATLAS_NAME+" not found. No patching is needed");
+ return;
+ }
+
+ dbAtlasServiceDef = svcDBStore.getServiceDefByName(EMBEDDED_SERVICEDEF_ATLAS_NAME);
+
+ updateResourceInServiceDef(embeddedAtlasServiceDef, dbAtlasServiceDef);
+ updateTypeResourceWithIgnoreCase(dbAtlasServiceDef.getResources());
+ removeEntityResourceAccessTypeRestrictions(dbAtlasServiceDef.getResources());
+
+ RangerServiceDefValidator validator = validatorFactory.getServiceDefValidator(svcStore);
+ validator.validate(dbAtlasServiceDef, RangerValidator.Action.UPDATE);
+ ret = svcStore.updateServiceDef(dbAtlasServiceDef);
+ if (ret == null) {
+ logger.error("Error while updating "+EMBEDDED_SERVICEDEF_ATLAS_NAME+" service-def");
+ throw new RuntimeException("Error while updating " + EMBEDDED_SERVICEDEF_ATLAS_NAME + " service-def");
+ }
+ }
+ }
+
+ private void updateResourceInServiceDef(RangerServiceDef embeddedAtlasServiceDef, RangerServiceDef dbAtlasServiceDef) {
+ List<RangerServiceDef.RangerResourceDef> embeddedAtlasResourceDefs;
+ List<RangerAccessTypeDef> embeddedAtlasAccessTypes;
+ embeddedAtlasResourceDefs = embeddedAtlasServiceDef.getResources();
+ embeddedAtlasAccessTypes = embeddedAtlasServiceDef.getAccessTypes();
+
+ if (!checkResourcePresent(dbAtlasServiceDef.getResources()) && checkResourcePresent(embeddedAtlasResourceDefs)) {
+ dbAtlasServiceDef.setResources(embeddedAtlasResourceDefs);
+ if (checkAccessPresent(embeddedAtlasAccessTypes)) {
+ dbAtlasServiceDef.setAccessTypes(embeddedAtlasAccessTypes);
+ }
+ } else {
+ logger.info("resource already present");
+ }
+ }
+
+ private boolean checkResourcePresent(List<RangerServiceDef.RangerResourceDef> resourceDefs) {
+ boolean ret = false;
+ for (RangerServiceDef.RangerResourceDef resourceDef : resourceDefs) {
+ if (ATLAS_RESOURCES.contains(resourceDef.getName())) {
+ ret = true;
+ break;
+ }
+ }
+ return ret;
+ }
+
+ private boolean checkAccessPresent(List<RangerServiceDef.RangerAccessTypeDef> embeddedAtlasAccessTypes) {
+ boolean ret = false;
+ for (RangerServiceDef.RangerAccessTypeDef accessDef : embeddedAtlasAccessTypes) {
+ if (ATLAS_ACCESS_TYPES.contains(accessDef.getName())) {
+ ret = true;
+ break;
+ }
+ }
+ return ret;
+ }
+
+ private void updateTypeResourceWithIgnoreCase(List<RangerServiceDef.RangerResourceDef> dbSerresourceDefs) {
+ for (RangerServiceDef.RangerResourceDef dbResourceDef : dbSerresourceDefs) {
+ if (TYPES.contains(dbResourceDef.getName())) {
+ dbResourceDef.getMatcherOptions().put("ignoreCase", "false");
+ }
+ }
+ }
+
+ private void removeEntityResourceAccessTypeRestrictions(List<RangerServiceDef.RangerResourceDef> dbSerresourceDefs) {
+ for (RangerServiceDef.RangerResourceDef dbResourceDef : dbSerresourceDefs) {
+ if (ENTITY.equals(dbResourceDef.getName())) {
+ dbResourceDef.getAccessTypeRestrictions().removeAll(ATLAS_ACCESS_TYPES);
+ }
+ }
+ }
+
+ private void createAdditionalPolicyWithClassificationForExistingEntityClassificationPolicy() throws Exception {
+
+ XXServiceDef xXServiceDefObj = daoMgr.getXXServiceDef().findByName(EMBEDDED_SERVICEDEF_ATLAS_NAME);
+
+ if (xXServiceDefObj == null) {
+ logger.debug("ServiceDef not found with name :" + EMBEDDED_SERVICEDEF_ATLAS_NAME);
+ return;
+ }
+
+ Long xServiceDefId = xXServiceDefObj.getId();
+ List<XXService> xxServices = daoMgr.getXXService().findByServiceDefId(xServiceDefId);
+
+ for (XXService xxService : xxServices) {
+
+ List<RangerPolicy> servicePolicies = svcStore.getServicePolicies(xxService.getId(), new SearchFilter());
+
+ for (RangerPolicy policy : servicePolicies) {
+
+ if(!isEntityResource(policy.getResources())){
+ continue;
+ }
+
+ List<RangerPolicyItem> policyItems = policy.getPolicyItems();
+ List<RangerPolicyItem> denypolicyItems = policy.getDenyPolicyItems();
+
+ boolean policyItemCheck = checkAndFilterNonClassificationAccessTypeFromPolicy(policyItems);
+ boolean denyPolicyItemCheck = checkAndFilterNonClassificationAccessTypeFromPolicy(denypolicyItems);
+
+ if (policyItemCheck || denyPolicyItemCheck) {
+ policy.setName(policy.getName() + " - " + CLASSIFICATION);
+
+ Map<String, RangerPolicyResource> xPolResMap = policy.getResources();
+
+ RangerPolicyResource resource = xPolResMap.get(ENTITY_CLASSIFICATION);
+
+ xPolResMap.put(CLASSIFICATION, resource);
+ policy.setResources(xPolResMap);
+
+ policy.setVersion(1L);
+ policy.setGuid(null);
+ policy.setId(null);
+ policy.setCreateTime(new Date());
+ policy.setUpdateTime(new Date());
+
+ svcStore.createPolicy(policy);
+ logger.info("New Additional policy created");
+ }
+ }
+ }
+ logger.info("<== createAdditionalPolicyWithClassificationForExistingPolicy");
+ }
+
+ private boolean isEntityResource(Map<String, RangerPolicyResource> xPolResMap) {
+ boolean ret = true;
+
+ if (xPolResMap != null && xPolResMap.size() == ATLAS_RESOURCE_ENTITY.size()){
+ for (String resourceName : ATLAS_RESOURCE_ENTITY) {
+ if (xPolResMap.get(resourceName) == null) {
+ ret = false;
+ break;
+ }
+ }
+ }else{
+ ret = false;
+ }
+
+ return ret;
+ }
+
+ private boolean checkAndFilterNonClassificationAccessTypeFromPolicy(List<RangerPolicyItem> policyItems) {
+
+ ListIterator<RangerPolicyItem> policyItemListIterator = policyItems.listIterator();
+ boolean isClassificationAccessTypeExist = false;
+
+ while (policyItemListIterator.hasNext()) {
+ RangerPolicyItem policyItem = policyItemListIterator.next();
+ ListIterator<RangerPolicyItemAccess> itemAccessListIterator = policyItem.getAccesses().listIterator();
+
+ boolean accessPresent = false;
+ while (itemAccessListIterator.hasNext()) {
+ RangerPolicyItemAccess access = itemAccessListIterator.next();
+ if (!ATLAS_ACCESS_TYPES.contains(access.getType())) {
+ itemAccessListIterator.remove();
+ } else {
+ accessPresent = true;
+ isClassificationAccessTypeExist = true;
+ }
+ }
+ if (!accessPresent) {
+ policyItemListIterator.remove();
+ }
+ }
+
+ return isClassificationAccessTypeExist;
+ }
+
+}