This is an automated email from the ASF dual-hosted git repository.

madhan 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 109dc779e RANGER-5216: added unit tests for Atlas authorizer (#581)
109dc779e is described below

commit 109dc779e46090f8f4869a24b213b3ebd8751fe2
Author: Madhan Neethiraj <[email protected]>
AuthorDate: Thu May 29 09:34:47 2025 -0700

    RANGER-5216: added unit tests for Atlas authorizer (#581)
---
 plugin-atlas/pom.xml                               |  12 +
 .../authorizer/TestRangerAtlasAuthorizer.java      | 522 +++++++++++++++++++++
 .../atlas/testutil/RangerAdminClientImpl.java      |  45 ++
 .../test/resources/atlas-application.properties    |  18 +
 .../src/test/resources/atlas-policies.json         | 181 +++++++
 .../src/test/{resource => resources}/logback.xml   |   0
 .../src/test/resources/ranger-atlas-security.xml   |  37 ++
 pom.xml                                            |   1 +
 8 files changed, 816 insertions(+)

diff --git a/plugin-atlas/pom.xml b/plugin-atlas/pom.xml
index 215fc8e81..e9166ce27 100644
--- a/plugin-atlas/pom.xml
+++ b/plugin-atlas/pom.xml
@@ -89,5 +89,17 @@
             <artifactId>ranger-plugins-common</artifactId>
             <version>${project.version}</version>
         </dependency>
+        <dependency>
+            <groupId>org.assertj</groupId>
+            <artifactId>assertj-core</artifactId>
+            <version>${assertj.version}</version>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.junit.jupiter</groupId>
+            <artifactId>junit-jupiter-api</artifactId>
+            <version>${junit.jupiter.version}</version>
+            <scope>test</scope>
+        </dependency>
     </dependencies>
 </project>
diff --git 
a/plugin-atlas/src/test/java/org/apache/ranger/authorization/atlas/authorizer/TestRangerAtlasAuthorizer.java
 
b/plugin-atlas/src/test/java/org/apache/ranger/authorization/atlas/authorizer/TestRangerAtlasAuthorizer.java
new file mode 100644
index 000000000..502dd93ab
--- /dev/null
+++ 
b/plugin-atlas/src/test/java/org/apache/ranger/authorization/atlas/authorizer/TestRangerAtlasAuthorizer.java
@@ -0,0 +1,522 @@
+/*
+ * 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.authorization.atlas.authorizer;
+
+import org.apache.atlas.authorize.AtlasAdminAccessRequest;
+import org.apache.atlas.authorize.AtlasEntityAccessRequest;
+import org.apache.atlas.authorize.AtlasPrivilege;
+import org.apache.atlas.authorize.AtlasRelationshipAccessRequest;
+import org.apache.atlas.authorize.AtlasTypeAccessRequest;
+import org.apache.atlas.model.instance.AtlasClassification;
+import org.apache.atlas.model.instance.AtlasEntityHeader;
+import org.apache.atlas.model.typedef.AtlasClassificationDef;
+import org.apache.atlas.model.typedef.AtlasEntityDef;
+import org.apache.atlas.type.AtlasTypeRegistry;
+import org.junit.jupiter.api.Test;
+
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.Set;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+public class TestRangerAtlasAuthorizer {
+    private static final String      USER_USER1                   = "user1";
+    private static final Set<String> USER_USER1_GROUPS            = 
Collections.singleton("users");
+    private static final String      USER_ADMIN1                  = "admin1";
+    private static final Set<String> USER_ADMIN1_GROUPS           = 
Collections.singleton("admins");
+    private static final String      USER_STEWARD1                = 
"data-steward1";
+    private static final Set<String> USER_STEWARD1_GROUPS         = 
Collections.singleton("stewards");
+    private static final String      USER_FINANCE_STEWARD1        = 
"finance-data-steward1";
+    private static final Set<String> USER_FINANCE_STEWARD1_GROUPS = new 
HashSet<>(Arrays.asList("finance-stewards", "stewards"));
+
+    private static final AtlasEntityDef         ENTITY_DEF_HIVE_TABLE          
 = new AtlasEntityDef("hive_table");
+    private static final AtlasClassificationDef CLASSIFICATION_DEF_FINANCE     
 = new AtlasClassificationDef("FINANCE");
+    private static final AtlasClassificationDef CLASSIFICATION_DEF_PII         
 = new AtlasClassificationDef("PII");
+    private static final AtlasClassificationDef 
CLASSIFICATION_DEF_DATA_QUALITY = new AtlasClassificationDef("DATA_QUALITY");
+    private static final AtlasEntityHeader      ENTITY_HIVE_TABLE_DB1_TBL1     
 = new AtlasEntityHeader(ENTITY_DEF_HIVE_TABLE.getName(), 
Collections.singletonMap("qualifiedName", "db1.tbl1@dev"));
+    private static final AtlasEntityHeader      ENTITY_HIVE_TABLE_DB1_TBL2     
 = new AtlasEntityHeader(ENTITY_DEF_HIVE_TABLE.getName(), 
Collections.singletonMap("qualifiedName", "db1.tbl2@dev"));
+    private static final AtlasClassification    CLASSIFICATION_FINANCE         
 = new AtlasClassification(CLASSIFICATION_DEF_FINANCE.getName());
+    private static final AtlasClassification    CLASSIFICATION_PII             
 = new AtlasClassification(CLASSIFICATION_DEF_PII.getName());
+    private static final AtlasClassification    CLASSIFICATION_DATA_QUALITY    
 = new AtlasClassification(CLASSIFICATION_DEF_DATA_QUALITY.getName());
+    private static final String                 LABEL_APPROVED                 
 = "approved";
+    private static final String                 
BUSINESS_METADATA_DATA_PROVIDER = "data-provider";
+    private static final String                 RELATIONSHIP_TYPE_CLONE_OF     
 = "cloneOf";
+
+    private final AtlasTypeRegistry     typeRegistry;
+    private final RangerAtlasAuthorizer authorizer;
+
+    public TestRangerAtlasAuthorizer() {
+        typeRegistry = new AtlasTypeRegistry();
+        authorizer   = new RangerAtlasAuthorizer();
+
+        authorizer.init();
+    }
+
+    @Test
+    public void testTypeDefRead() {
+        AtlasTypeAccessRequest request = new 
AtlasTypeAccessRequest(AtlasPrivilege.TYPE_READ, ENTITY_DEF_HIVE_TABLE);
+
+        request.setUser(USER_USER1, USER_USER1_GROUPS);
+
+        assertThat(authorizer.isAccessAllowed(request))
+                .as("%s should be allowed to read typedef %s", 
request.getUser(), ENTITY_DEF_HIVE_TABLE.getName())
+                .isTrue();
+    }
+
+    @Test
+    public void testTypeDefCreate() {
+        AtlasTypeAccessRequest request = new 
AtlasTypeAccessRequest(AtlasPrivilege.TYPE_CREATE, ENTITY_DEF_HIVE_TABLE);
+
+        request.setUser(USER_USER1, USER_USER1_GROUPS);
+
+        assertThat(authorizer.isAccessAllowed(request))
+                .as("%s should be denied to create typedef %s", 
request.getUser(), ENTITY_DEF_HIVE_TABLE.getName())
+                .isFalse();
+
+        request.setUser(USER_ADMIN1, USER_ADMIN1_GROUPS);
+
+        assertThat(authorizer.isAccessAllowed(request))
+                .as("%s should be allowed to create typedef %s", 
request.getUser(), ENTITY_DEF_HIVE_TABLE.getName())
+                .isTrue();
+    }
+
+    @Test
+    public void testTypeDefUpdate() {
+        AtlasTypeAccessRequest request = new 
AtlasTypeAccessRequest(AtlasPrivilege.TYPE_UPDATE, ENTITY_DEF_HIVE_TABLE);
+
+        request.setUser(USER_USER1, USER_USER1_GROUPS);
+
+        assertThat(authorizer.isAccessAllowed(request))
+                .as("%s should be denied to update typedef %s", 
request.getUser(), ENTITY_DEF_HIVE_TABLE.getName())
+                .isFalse();
+
+        request.setUser(USER_ADMIN1, USER_ADMIN1_GROUPS);
+
+        assertThat(authorizer.isAccessAllowed(request))
+                .as("%s should be allowed to update typedef %s", 
request.getUser(), ENTITY_DEF_HIVE_TABLE.getName())
+                .isTrue();
+    }
+
+    @Test
+    public void testTypeDefDelete() {
+        AtlasTypeAccessRequest request = new 
AtlasTypeAccessRequest(AtlasPrivilege.TYPE_DELETE, ENTITY_DEF_HIVE_TABLE);
+
+        request.setUser(USER_USER1, USER_USER1_GROUPS);
+
+        assertThat(authorizer.isAccessAllowed(request))
+                .as("%s should be denied to delete typedef %s", 
request.getUser(), ENTITY_DEF_HIVE_TABLE.getName())
+                .isFalse();
+
+        request.setUser(USER_ADMIN1, USER_ADMIN1_GROUPS);
+
+        assertThat(authorizer.isAccessAllowed(request))
+                .as("%s should be allowed to delete typedef %s", 
request.getUser(), ENTITY_DEF_HIVE_TABLE.getName())
+                .isTrue();
+    }
+
+    @Test
+    public void testEntityRead() {
+        AtlasEntityAccessRequest request = new 
AtlasEntityAccessRequest(typeRegistry, AtlasPrivilege.ENTITY_READ, 
ENTITY_HIVE_TABLE_DB1_TBL1);
+
+        request.setUser(USER_USER1, USER_USER1_GROUPS);
+
+        assertThat(authorizer.isAccessAllowed(request))
+                .as("%s should be denied to read entity %s", 
request.getUser(), request.getEntityId())
+                .isFalse();
+
+        request.setUser(USER_STEWARD1, USER_STEWARD1_GROUPS);
+
+        assertThat(authorizer.isAccessAllowed(request))
+                .as("%s should be allowed to read entity %s", 
request.getUser(), request.getEntityId())
+                .isTrue();
+
+        request.setUser(USER_ADMIN1, USER_ADMIN1_GROUPS);
+
+        assertThat(authorizer.isAccessAllowed(request))
+                .as("%s should be allowed to read entity %s", 
request.getUser(), request.getEntityId())
+                .isTrue();
+    }
+
+    @Test
+    public void testEntityCreate() {
+        AtlasEntityAccessRequest request = new 
AtlasEntityAccessRequest(typeRegistry, AtlasPrivilege.ENTITY_CREATE, 
ENTITY_HIVE_TABLE_DB1_TBL1);
+
+        request.setUser(USER_USER1, USER_USER1_GROUPS);
+
+        assertThat(authorizer.isAccessAllowed(request))
+                .as("%s should be denied to create entity %s", 
request.getUser(), request.getEntityId())
+                .isFalse();
+
+        request.setUser(USER_STEWARD1, USER_STEWARD1_GROUPS);
+
+        assertThat(authorizer.isAccessAllowed(request))
+                .as("%s should be denied to create entity %s", 
request.getUser(), request.getEntityId())
+                .isFalse();
+
+        request.setUser(USER_ADMIN1, USER_ADMIN1_GROUPS);
+
+        assertThat(authorizer.isAccessAllowed(request))
+                .as("%s should be allowed to create entity %s", 
request.getUser(), request.getEntityId())
+                .isTrue();
+    }
+
+    @Test
+    public void testEntityUpdate() {
+        AtlasEntityAccessRequest request = new 
AtlasEntityAccessRequest(typeRegistry, AtlasPrivilege.ENTITY_UPDATE, 
ENTITY_HIVE_TABLE_DB1_TBL1);
+
+        request.setUser(USER_USER1, USER_USER1_GROUPS);
+
+        assertThat(authorizer.isAccessAllowed(request))
+                .as("%s should be denied to update entity %s", 
request.getUser(), request.getEntityId())
+                .isFalse();
+
+        request.setUser(USER_STEWARD1, USER_STEWARD1_GROUPS);
+
+        assertThat(authorizer.isAccessAllowed(request))
+                .as("%s should be denied to update entity %s", 
request.getUser(), request.getEntityId())
+                .isFalse();
+
+        request.setUser(USER_ADMIN1, USER_ADMIN1_GROUPS);
+
+        assertThat(authorizer.isAccessAllowed(request))
+                .as("%s should be allowed to update entity %s", 
request.getUser(), request.getEntityId())
+                .isTrue();
+    }
+
+    @Test
+    public void testEntityDelete() {
+        AtlasEntityAccessRequest request = new 
AtlasEntityAccessRequest(typeRegistry, AtlasPrivilege.ENTITY_DELETE, 
ENTITY_HIVE_TABLE_DB1_TBL1);
+
+        request.setUser(USER_USER1, USER_USER1_GROUPS);
+
+        assertThat(authorizer.isAccessAllowed(request))
+                .as("%s should be denied to delete entity %s", 
request.getUser(), request.getEntityId())
+                .isFalse();
+
+        request.setUser(USER_STEWARD1, USER_STEWARD1_GROUPS);
+
+        assertThat(authorizer.isAccessAllowed(request))
+                .as("%s should be denied to delete entity %s", 
request.getUser(), request.getEntityId())
+                .isFalse();
+
+        request.setUser(USER_ADMIN1, USER_ADMIN1_GROUPS);
+
+        assertThat(authorizer.isAccessAllowed(request))
+                .as("%s should be allowed to delete entity %s", 
request.getUser(), request.getEntityId())
+                .isTrue();
+    }
+
+    @Test
+    public void testAddClassification() {
+        AtlasEntityAccessRequest request = new 
AtlasEntityAccessRequest(typeRegistry, 
AtlasPrivilege.ENTITY_ADD_CLASSIFICATION, ENTITY_HIVE_TABLE_DB1_TBL1, 
CLASSIFICATION_PII);
+
+        request.setUser(USER_USER1, USER_USER1_GROUPS);
+
+        assertThat(authorizer.isAccessAllowed(request))
+                .as("%s should be denied to add classification %s", 
request.getUser(), request.getClassification().getTypeName())
+                .isFalse();
+
+        request.setUser(USER_STEWARD1, USER_STEWARD1_GROUPS);
+
+        assertThat(authorizer.isAccessAllowed(request))
+                .as("%s should be allowed to add classification %s", 
request.getUser(), request.getClassification().getTypeName())
+                .isTrue();
+    }
+
+    @Test
+    public void testAddClassificationOnEntityHavingFinanceTag() {
+        AtlasEntityHeader entityHavingFinanceTag = new 
AtlasEntityHeader(ENTITY_HIVE_TABLE_DB1_TBL1);
+
+        
entityHavingFinanceTag.setClassifications(Collections.singletonList(CLASSIFICATION_FINANCE));
+
+        AtlasEntityAccessRequest request = new 
AtlasEntityAccessRequest(typeRegistry, 
AtlasPrivilege.ENTITY_ADD_CLASSIFICATION, entityHavingFinanceTag, 
CLASSIFICATION_DATA_QUALITY);
+
+        request.setUser(USER_USER1, USER_USER1_GROUPS);
+
+        assertThat(authorizer.isAccessAllowed(request))
+                .as("%s should be denied to add classification %s to entity 
having classifications %s", request.getUser(), 
request.getClassification().getTypeName(), 
entityHavingFinanceTag.getClassifications())
+                .isFalse();
+
+        request.setUser(USER_STEWARD1, USER_STEWARD1_GROUPS);
+
+        assertThat(authorizer.isAccessAllowed(request))
+                .as("%s should be denied to add classification %s to entity 
having classifications %s", request.getUser(), 
request.getClassification().getTypeName(), 
entityHavingFinanceTag.getClassifications())
+                .isFalse();
+
+        request.setUser(USER_FINANCE_STEWARD1, USER_FINANCE_STEWARD1_GROUPS);
+
+        assertThat(authorizer.isAccessAllowed(request))
+                .as("%s should be allowed to add classification %s to entity 
having classifications %s", request.getUser(), 
request.getClassification().getTypeName(), 
entityHavingFinanceTag.getClassifications())
+                .isTrue();
+    }
+
+    @Test
+    public void testAddClassificationOnEntityHavingFinanceDataQualityTags() {
+        AtlasEntityHeader entityHavingFinanceTag = new 
AtlasEntityHeader(ENTITY_HIVE_TABLE_DB1_TBL1);
+
+        
entityHavingFinanceTag.setClassifications(Arrays.asList(CLASSIFICATION_FINANCE, 
CLASSIFICATION_DATA_QUALITY));
+
+        AtlasEntityAccessRequest request = new 
AtlasEntityAccessRequest(typeRegistry, 
AtlasPrivilege.ENTITY_ADD_CLASSIFICATION, entityHavingFinanceTag, 
CLASSIFICATION_PII);
+
+        request.setUser(USER_USER1, USER_USER1_GROUPS);
+
+        assertThat(authorizer.isAccessAllowed(request))
+                .as("%s should be denied to add classification %s to entity 
having classifications %s", request.getUser(), 
request.getClassification().getTypeName(), 
entityHavingFinanceTag.getClassifications())
+                .isFalse();
+
+        request.setUser(USER_STEWARD1, USER_STEWARD1_GROUPS);
+
+        assertThat(authorizer.isAccessAllowed(request))
+                .as("%s should be denied to add classification %s to entity 
having classifications %s", request.getUser(), 
request.getClassification().getTypeName(), 
entityHavingFinanceTag.getClassifications())
+                .isFalse();
+
+        request.setUser(USER_FINANCE_STEWARD1, USER_FINANCE_STEWARD1_GROUPS);
+
+        assertThat(authorizer.isAccessAllowed(request))
+                .as("%s should be allowed to add classification %s to entity 
having classifications %s", request.getUser(), 
request.getClassification().getTypeName(), 
entityHavingFinanceTag.getClassifications())
+                .isTrue();
+    }
+
+    @Test
+    public void testUpdateClassification() {
+        AtlasEntityAccessRequest request = new 
AtlasEntityAccessRequest(typeRegistry, 
AtlasPrivilege.ENTITY_UPDATE_CLASSIFICATION, ENTITY_HIVE_TABLE_DB1_TBL1, 
CLASSIFICATION_PII);
+
+        request.setUser(USER_USER1, USER_USER1_GROUPS);
+
+        assertThat(authorizer.isAccessAllowed(request))
+                .as("%s should be denied to update classification %s", 
request.getUser(), request.getClassification().getTypeName())
+                .isFalse();
+
+        request.setUser(USER_STEWARD1, USER_STEWARD1_GROUPS);
+
+        assertThat(authorizer.isAccessAllowed(request))
+                .as("%s should be allowed to update classification %s", 
request.getUser(), request.getClassification().getTypeName())
+                .isTrue();
+    }
+
+    @Test
+    public void testRemoveClassification() {
+        AtlasEntityAccessRequest request = new 
AtlasEntityAccessRequest(typeRegistry, 
AtlasPrivilege.ENTITY_REMOVE_CLASSIFICATION, ENTITY_HIVE_TABLE_DB1_TBL1, 
CLASSIFICATION_PII);
+
+        request.setUser(USER_USER1, USER_USER1_GROUPS);
+
+        assertThat(authorizer.isAccessAllowed(request))
+                .as("%s should be denied to remove classification %s", 
request.getUser(), request.getClassification().getTypeName())
+                .isFalse();
+
+        request.setUser(USER_STEWARD1, USER_STEWARD1_GROUPS);
+
+        assertThat(authorizer.isAccessAllowed(request))
+                .as("%s should be allowed to remove classification %s", 
request.getUser(), request.getClassification().getTypeName())
+                .isTrue();
+    }
+
+    @Test
+    public void testAddLabel() {
+        AtlasEntityAccessRequest request = new 
AtlasEntityAccessRequest(typeRegistry, AtlasPrivilege.ENTITY_ADD_LABEL, 
ENTITY_HIVE_TABLE_DB1_TBL1, null, null, LABEL_APPROVED, null);
+
+        request.setUser(USER_USER1, USER_USER1_GROUPS);
+
+        assertThat(authorizer.isAccessAllowed(request))
+                .as("%s should be denied to add label ", request.getUser(), 
request.getLabel())
+                .isFalse();
+
+        request.setUser(USER_STEWARD1, USER_STEWARD1_GROUPS);
+
+        assertThat(authorizer.isAccessAllowed(request))
+                .as("%s should be allowed to add label %s", request.getUser(), 
request.getLabel())
+                .isTrue();
+    }
+
+    @Test
+    public void testRemoveLabel() {
+        AtlasEntityAccessRequest request = new 
AtlasEntityAccessRequest(typeRegistry, AtlasPrivilege.ENTITY_REMOVE_LABEL, 
ENTITY_HIVE_TABLE_DB1_TBL1, null, null, LABEL_APPROVED, null);
+
+        request.setUser(USER_USER1, USER_USER1_GROUPS);
+
+        assertThat(authorizer.isAccessAllowed(request))
+                .as("%s should be denied to remove label %s", 
request.getUser(), request.getLabel())
+                .isFalse();
+
+        request.setUser(USER_STEWARD1, USER_STEWARD1_GROUPS);
+
+        assertThat(authorizer.isAccessAllowed(request))
+                .as("%s should be allowed to remove label %s", 
request.getUser(), request.getLabel())
+                .isTrue();
+    }
+
+    @Test
+    public void testUpdateBusinessMetadata() {
+        AtlasEntityAccessRequest request = new 
AtlasEntityAccessRequest(typeRegistry, 
AtlasPrivilege.ENTITY_UPDATE_BUSINESS_METADATA, ENTITY_HIVE_TABLE_DB1_TBL1, 
null, null, null, BUSINESS_METADATA_DATA_PROVIDER, USER_USER1, 
USER_USER1_GROUPS);
+
+        request.setUser(USER_USER1, USER_USER1_GROUPS);
+
+        assertThat(authorizer.isAccessAllowed(request))
+                .as("%s should be denied to update business metadata %s", 
request.getUser(), request.getBusinessMetadata())
+                .isFalse();
+
+        request.setUser(USER_STEWARD1, USER_STEWARD1_GROUPS);
+
+        assertThat(authorizer.isAccessAllowed(request))
+                .as("%s should be allowed to update business metadata %s", 
request.getUser(), request.getBusinessMetadata())
+                .isTrue();
+    }
+
+    @Test
+    public void testImport() {
+        AtlasAdminAccessRequest request = new 
AtlasAdminAccessRequest(AtlasPrivilege.ADMIN_IMPORT);
+
+        request.setUser(USER_USER1, USER_USER1_GROUPS);
+
+        assertThat(authorizer.isAccessAllowed(request))
+                .as("%s should be denied to import", request.getUser())
+                .isFalse();
+
+        request.setUser(USER_STEWARD1, USER_STEWARD1_GROUPS);
+
+        assertThat(authorizer.isAccessAllowed(request))
+                .as("%s should be denied to import", request.getUser())
+                .isFalse();
+
+        request.setUser(USER_ADMIN1, USER_ADMIN1_GROUPS);
+
+        assertThat(authorizer.isAccessAllowed(request))
+                .as("%s should be allowed to import", request.getUser())
+                .isTrue();
+    }
+
+    @Test
+    public void testExport() {
+        AtlasAdminAccessRequest request = new 
AtlasAdminAccessRequest(AtlasPrivilege.ADMIN_EXPORT);
+
+        request.setUser(USER_USER1, USER_USER1_GROUPS);
+
+        assertThat(authorizer.isAccessAllowed(request))
+                .as("%s should be denied to export", request.getUser())
+                .isFalse();
+
+        request.setUser(USER_STEWARD1, USER_STEWARD1_GROUPS);
+
+        assertThat(authorizer.isAccessAllowed(request))
+                .as("%s should be denied to export", request.getUser())
+                .isFalse();
+
+        request.setUser(USER_ADMIN1, USER_ADMIN1_GROUPS);
+
+        assertThat(authorizer.isAccessAllowed(request))
+                .as("%s should be allowed to export", request.getUser())
+                .isTrue();
+    }
+
+    @Test
+    public void testPurge() {
+        AtlasAdminAccessRequest request = new 
AtlasAdminAccessRequest(AtlasPrivilege.ADMIN_PURGE);
+
+        request.setUser(USER_USER1, USER_USER1_GROUPS);
+
+        assertThat(authorizer.isAccessAllowed(request))
+                .as("%s should be denied to purge", request.getUser())
+                .isFalse();
+
+        request.setUser(USER_STEWARD1, USER_STEWARD1_GROUPS);
+
+        assertThat(authorizer.isAccessAllowed(request))
+                .as("%s should be denied to purge", request.getUser())
+                .isFalse();
+
+        request.setUser(USER_ADMIN1, USER_ADMIN1_GROUPS);
+
+        assertThat(authorizer.isAccessAllowed(request))
+                .as("%s should be allowed to purge", request.getUser())
+                .isTrue();
+    }
+
+    @Test
+    public void testAudits() {
+        AtlasAdminAccessRequest request = new 
AtlasAdminAccessRequest(AtlasPrivilege.ADMIN_AUDITS);
+
+        request.setUser(USER_USER1, USER_USER1_GROUPS);
+
+        assertThat(authorizer.isAccessAllowed(request))
+                .as("%s should be denied to admin audits", request.getUser())
+                .isFalse();
+
+        request.setUser(USER_STEWARD1, USER_STEWARD1_GROUPS);
+
+        assertThat(authorizer.isAccessAllowed(request))
+                .as("%s should be denied to admin audits", request.getUser())
+                .isFalse();
+
+        request.setUser(USER_ADMIN1, USER_ADMIN1_GROUPS);
+
+        assertThat(authorizer.isAccessAllowed(request))
+                .as("%s should be allowed to admin audits", request.getUser())
+                .isTrue();
+    }
+
+    @Test
+    public void testAddRelationship() {
+        AtlasRelationshipAccessRequest request = new 
AtlasRelationshipAccessRequest(typeRegistry, AtlasPrivilege.RELATIONSHIP_ADD, 
RELATIONSHIP_TYPE_CLONE_OF, ENTITY_HIVE_TABLE_DB1_TBL1, 
ENTITY_HIVE_TABLE_DB1_TBL2);
+
+        request.setUser(USER_USER1, USER_USER1_GROUPS);
+
+        assertThat(authorizer.isAccessAllowed(request))
+                .as("%s should be denied to add relationship %s", 
request.getUser(), request.getRelationshipType())
+                .isFalse();
+
+        request.setUser(USER_STEWARD1, USER_STEWARD1_GROUPS);
+
+        assertThat(authorizer.isAccessAllowed(request))
+                .as("%s should be allowed to add relationship %s", 
request.getUser(), request.getRelationshipType()).isTrue();
+    }
+
+    @Test
+    public void testUpdateRelationship() {
+        AtlasRelationshipAccessRequest request = new 
AtlasRelationshipAccessRequest(typeRegistry, 
AtlasPrivilege.RELATIONSHIP_UPDATE, RELATIONSHIP_TYPE_CLONE_OF, 
ENTITY_HIVE_TABLE_DB1_TBL1, ENTITY_HIVE_TABLE_DB1_TBL2);
+
+        request.setUser(USER_USER1, USER_USER1_GROUPS);
+
+        assertThat(authorizer.isAccessAllowed(request))
+                .as("%s should be denied to update relationship %s", 
request.getUser(), request.getRelationshipType())
+                .isFalse();
+
+        request.setUser(USER_STEWARD1, USER_STEWARD1_GROUPS);
+
+        assertThat(authorizer.isAccessAllowed(request))
+                .as("%s should be allowed to update relationship %s", 
request.getUser(), request.getRelationshipType())
+                .isTrue();
+    }
+
+    @Test
+    public void testRemoveRelationship() {
+        AtlasRelationshipAccessRequest request = new 
AtlasRelationshipAccessRequest(typeRegistry, 
AtlasPrivilege.RELATIONSHIP_REMOVE, RELATIONSHIP_TYPE_CLONE_OF, 
ENTITY_HIVE_TABLE_DB1_TBL1, ENTITY_HIVE_TABLE_DB1_TBL2);
+
+        request.setUser(USER_USER1, USER_USER1_GROUPS);
+
+        assertThat(authorizer.isAccessAllowed(request))
+                .as("%s should be denied to remove relationship %s", 
request.getUser(), request.getRelationshipType())
+                .isFalse();
+
+        request.setUser(USER_STEWARD1, USER_STEWARD1_GROUPS);
+
+        assertThat(authorizer.isAccessAllowed(request))
+                .as("%s should be allowed to remove relationship %s", 
request.getUser(), request.getRelationshipType()).isTrue();
+    }
+}
diff --git 
a/plugin-atlas/src/test/java/org/apache/ranger/authorization/atlas/testutil/RangerAdminClientImpl.java
 
b/plugin-atlas/src/test/java/org/apache/ranger/authorization/atlas/testutil/RangerAdminClientImpl.java
new file mode 100644
index 000000000..0c5833937
--- /dev/null
+++ 
b/plugin-atlas/src/test/java/org/apache/ranger/authorization/atlas/testutil/RangerAdminClientImpl.java
@@ -0,0 +1,45 @@
+/*
+ * 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.authorization.atlas.testutil;
+
+import org.apache.ranger.admin.client.AbstractRangerAdminClient;
+import org.apache.ranger.plugin.util.ServicePolicies;
+
+import java.io.File;
+import java.nio.file.FileSystems;
+import java.nio.file.Files;
+
+/**
+ * A test implementation of the RangerAdminClient interface that just reads 
policies in from a file and returns them
+ */
+public class RangerAdminClientImpl extends AbstractRangerAdminClient {
+    private static final String TEST_POLICIES_FILENAME = "atlas-policies.json";
+
+    public ServicePolicies getServicePoliciesIfUpdated(long lastKnownVersion, 
long lastActivationTimeInMillis) throws Exception {
+        String basedir = System.getProperty("basedir");
+
+        if (basedir == null) {
+            basedir = new File(".").getCanonicalPath();
+        }
+
+        java.nio.file.Path cachePath  = 
FileSystems.getDefault().getPath(basedir, "src/test/resources/" + 
TEST_POLICIES_FILENAME);
+        byte[]             cacheBytes = Files.readAllBytes(cachePath);
+
+        return gson.fromJson(new String(cacheBytes), ServicePolicies.class);
+    }
+}
diff --git a/plugin-atlas/src/test/resources/atlas-application.properties 
b/plugin-atlas/src/test/resources/atlas-application.properties
new file mode 100644
index 000000000..828a238e5
--- /dev/null
+++ b/plugin-atlas/src/test/resources/atlas-application.properties
@@ -0,0 +1,18 @@
+# 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.
+
+#
+# Empty properties file - needed to initialize RangerAtlasAuthorizer
+#
diff --git a/plugin-atlas/src/test/resources/atlas-policies.json 
b/plugin-atlas/src/test/resources/atlas-policies.json
new file mode 100644
index 000000000..1020dd8f6
--- /dev/null
+++ b/plugin-atlas/src/test/resources/atlas-policies.json
@@ -0,0 +1,181 @@
+{
+  "serviceName": "dev_atlas", "serviceId": 8, "policyVersion": 19,
+  "policies": [
+    {
+      "id": 1, "name": "Default: all type-category, type",
+      "resources": {
+        "type-category": { "values":  [ "*" ] },
+        "type":          { "values":  [ "*" ] }
+      },
+      "policyItems": [
+        {
+          "accesses":  [ { "type": "type-read" }],
+          "groups": [ "public" ]
+        },
+        {
+          "accesses":  [ { "type": "type-create" }, { "type": "type-update" }, 
{ "type":  "type-delete"} ],
+          "groups": [ "admins" ]
+        }
+      ]
+    },
+    {
+      "id": 2, "name": "Default: all entity-type, entity-classification, 
entity",
+      "resources": {
+        "entity-type":           { "values": [ "*" ] },
+        "entity-classification": { "values": [ "*" ] },
+        "entity":                { "values": [ "*" ] }
+      },
+      "policyItems": [
+        {
+          "accesses":  [ { "type": "entity-read" } ],
+          "groups": [ "stewards" ]
+        },
+        {
+          "accesses":  [ { "type": "entity-read" }, { "type": "entity-create" 
}, { "type": "entity-update" }, { "type": "entity-delete"} ],
+          "groups": [ "admins" ]
+        }
+      ]
+    },
+    {
+      "id": 3, "name": "Default: all entity-type, entity-classification, 
entity, classification",
+      "resources": {
+        "entity-type":           { "values": [ "*" ] },
+        "entity-classification": { "values": [ "*" ] },
+        "entity":                { "values": [ "*" ] },
+        "classification":        { "values": [ "*" ] }
+      },
+      "policyItems": [
+        {
+          "accesses":  [ { "type": "entity-add-classification" }, { "type": 
"entity-update-classification" }, { "type": "entity-remove-classification"} ],
+          "groups": [ "stewards" ]
+        }
+      ]
+    },
+    {
+      "id": 4, "name": "Default: all entity-type, entity-classification, 
entity, label",
+      "resources": {
+        "entity-type":           { "values": [ "*" ] },
+        "entity-classification": { "values": [ "*" ] },
+        "entity":                { "values": [ "*" ] },
+        "entity-label":          { "values": [ "*" ] }
+      },
+      "policyItems": [
+        {
+          "accesses":  [ { "type": "entity-add-label" }, { "type": 
"entity-update-label" }, { "type": "entity-remove-label"} ],
+          "groups": [ "stewards" ]
+        }
+      ]
+    },
+    {
+      "id": 5, "name": "Default: all entity-type, entity-classification, 
entity, business-metadata",
+      "resources": {
+        "entity-type":              { "values": [ "*" ] },
+        "entity-classification":    { "values": [ "*" ] },
+        "entity":                   { "values": [ "*" ] },
+        "entity-business-metadata": { "values": [ "*" ] }
+      },
+      "policyItems": [
+        {
+          "accesses":  [ { "type": "entity-update-business-metadata" } ],
+          "groups": [ "stewards" ]
+        }
+      ]
+    },
+    {
+      "id": 6, "name": "Default: all relationship-type, end-one-entity-type, 
end-one-entity-classification, end-one-entity, end-two-entity-type, 
end-two-entity-classification, end-two-entity",
+      "resources": {
+        "relationship-type":             { "values": [ "*" ] },
+        "end-one-entity-type":           { "values": [ "*" ] },
+        "end-one-entity-classification": { "values": [ "*" ] },
+        "end-one-entity":                { "values": [ "*" ] },
+        "end-two-entity-type":           { "values": [ "*" ] },
+        "end-two-entity-classification": { "values": [ "*" ] },
+        "end-two-entity":                { "values": [ "*" ] }
+      },
+      "policyItems": [
+        {
+          "accesses":  [ { "type": "add-relationship" }, { "type": 
"update-relationship" }, { "type": "remove-relationship" } ],
+          "groups": [ "stewards" ]
+        }
+      ]
+    },
+    {
+      "id": 7, "name": "Default: all atlas-service",
+      "resources": {
+        "atlas-service": { "values": [ "*" ] }
+      },
+      "policyItems": [
+        {
+          "accesses":  [ { "type": "admin-import" }, { "type": "admin-export" 
}, { "type": "admin-purge" }, { "type": "admin-audits" } ],
+          "groups": [ "admins" ]
+        }
+      ]
+    },
+    {
+      "id": 8, "name": "Entities having FINANCE classification", 
"isDenyAllElse": true,
+      "resources": {
+        "entity-type":           { "values": [ "*" ] },
+        "entity-classification": { "values": [ "FINANCE" ] },
+        "entity":                { "values": [ "*" ] },
+        "classification":        { "values": [ "*" ] }
+      },
+      "policyItems": [
+        {
+          "accesses":  [ { "type": "entity-add-classification" }, { "type": 
"entity-update-classification" }, { "type": "entity-remove-classification"} ],
+          "groups": [ "finance-stewards" ]
+        }
+      ]
+    }
+  ],
+  "serviceDef": {
+    "id": 3, "name": "atlas", "implClass": 
"org.apache.ranger.services.atlas.RangerServiceAtlas",
+    "resources": [
+      { "itemId": 1,  "name": "type-category",                 "level": 10 },
+      { "itemId": 2,  "name": "type",                          "level": 20, 
"parent": "type-category",         "accessTypeRestrictions": [ "type-read", 
"type-create", "type-update", "type-delete" ] },
+      { "itemId": 3,  "name": "entity-type",                   "level": 10 },
+      { "itemId": 4,  "name": "entity-classification",         "level": 20, 
"parent": "entity-type" },
+      { "itemId": 5,  "name": "entity",                        "level": 30, 
"parent": "entity-classification", "accessTypeRestrictions": [ "entity-read", 
"entity-create", "entity-update", "entity-delete" ] },
+      { "itemId": 6,  "name": "entity-label",                  "level": 40, 
"parent": "entity",                "accessTypeRestrictions": [ 
"entity-add-label", "entity-remove-label" ] },
+      { "itemId": 7,  "name": "entity-business-metadata",      "level": 40, 
"parent": "entity",                "accessTypeRestrictions": [ 
"entity-update-business-metadata" ] },
+      { "itemId": 8,  "name": "classification",                "level": 20, 
"parent": "entity",                "accessTypeRestrictions": [ 
"entity-add-classification", "entity-update-classification", 
"entity-remove-classification" ] },
+      { "itemId": 9,  "name": "atlas-service",                 "level": 10,    
                                "accessTypeRestrictions": [ "admin-import", 
"admin-export", "admin-purge", "admin-audits" ] },
+      { "itemId": 10, "name": "relationship-type",             "level": 10 },
+      { "itemId": 11, "name": "end-one-entity-type",           "level": 20, 
"parent": "relationship-type" },
+      { "itemId": 12, "name": "end-one-entity-classification", "level": 30, 
"parent": "end-one-entity-type" },
+      { "itemId": 13, "name": "end-one-entity",                "level": 40, 
"parent": "end-one-entity-classification", "accessTypeRestrictions": [ 
"add-relationship", "update-relationship", "remove-relationship" ] },
+      { "itemId": 14, "name": "end-two-entity-type",           "level": 50, 
"parent": "end-one-entity" },
+      { "itemId": 15, "name": "end-two-entity-classification", "level": 60, 
"parent": "end-two-entity-type" },
+      { "itemId": 16, "name": "end-two-entity",                "level": 70, 
"parent": "end-two-entity-classification", "accessTypeRestrictions": [ 
"add-relationship", "update-relationship", "remove-relationship" ] }
+    ],
+    "accessTypes": [
+      { "itemId": 1,  "name": "type-read",                       "category": 
"READ",   "label": "Read Type" },
+      { "itemId": 2,  "name": "type-create",                     "category": 
"MANAGE", "label": "Create Type" },
+      { "itemId": 3,  "name": "type-update",                     "category": 
"MANAGE", "label": "Update Type" },
+      { "itemId": 4,  "name": "type-delete",                     "category": 
"MANAGE", "label": "Delete Type" },
+      { "itemId": 5,  "name": "entity-read",                     "category": 
"READ",   "label": "Read Entity" },
+      { "itemId": 6,  "name": "entity-create",                   "category": 
"CREATE", "label": "Create Entity" },
+      { "itemId": 7,  "name": "entity-update",                   "category": 
"UPDATE", "label": "Update Entity" },
+      { "itemId": 8,  "name": "entity-delete",                   "category": 
"DELETE", "label": "Delete Entity" },
+      { "itemId": 9,  "name": "entity-add-classification",       "category": 
"UPDATE", "label": "Add Classification" },
+      { "itemId": 10, "name": "entity-update-classification",    "category": 
"UPDATE", "label": "Update Classification" },
+      { "itemId": 11, "name": "entity-remove-classification",    "category": 
"UPDATE", "label": "Remove Classification" },
+      { "itemId": 12, "name": "entity-add-label",                "category": 
"UPDATE", "label": "Add Label" },
+      { "itemId": 13, "name": "entity-remove-label",             "category": 
"UPDATE", "label": "Remove Label" },
+      { "itemId": 14, "name": "entity-update-business-metadata", "category": 
"UPDATE", "label": "Update Business Metadata" },
+      { "itemId": 15, "name": "add-relationship",                "category": 
"UPDATE", "label": "Add Relationship" },
+      { "itemId": 16, "name": "update-relationship",             "category": 
"UPDATE", "label": "Update Relationship" },
+      { "itemId": 17, "name": "remove-relationship",             "category": 
"UPDATE", "label": "Remove Relationship" },
+      { "itemId": 18, "name": "admin-export",                    "category": 
"MANAGE", "label": "Export" },
+      { "itemId": 19, "name": "admin-import",                    "category": 
"MANAGE", "label": "Import" },
+      { "itemId": 20, "name": "admin-purge",                     "category": 
"MANAGE", "label": "Purge" },
+      { "itemId": 21, "name": "admin-audits",                    "category": 
"MANAGE", "label": "Admin Audits" }
+    ],
+    "configs": [
+      { "itemId": 1, "name": "username",                    "type": "string",  
 "mandatory": true },
+      { "itemId": 2, "name": "password",                    "type": 
"password", "mandatory": true },
+      { "itemId": 3, "name": "atlas.rest.address",          "type": "string",  
 "mandatory": true, "defaultValue": "http://localhost:21000"; },
+      { "itemId": 4, "name": "commonNameForCertificate",    "type": "string",  
 "mandatory": false },
+      { "itemId": 5, "name": "ranger.plugin.audit.filters", "type": "string",  
 "mandatory": false }
+    ]
+  }
+}
diff --git a/plugin-atlas/src/test/resource/logback.xml 
b/plugin-atlas/src/test/resources/logback.xml
similarity index 100%
rename from plugin-atlas/src/test/resource/logback.xml
rename to plugin-atlas/src/test/resources/logback.xml
diff --git a/plugin-atlas/src/test/resources/ranger-atlas-security.xml 
b/plugin-atlas/src/test/resources/ranger-atlas-security.xml
new file mode 100644
index 000000000..8b5b1af01
--- /dev/null
+++ b/plugin-atlas/src/test/resources/ranger-atlas-security.xml
@@ -0,0 +1,37 @@
+<?xml version="1.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.
+-->
+<?xml-stylesheet type="text/xsl" href="configuration.xsl"?>
+<configuration xmlns:xi="http://www.w3.org/2001/XInclude";>
+    <property>
+        <name>ranger.plugin.atlas.service.name</name>
+        <value>dev_atlas</value>
+        <description>Name of the Ranger service containing policies for this 
SampleApp instance</description>
+    </property>
+
+    <property>
+        <name>ranger.plugin.atlas.policy.source.impl</name>
+        
<value>org.apache.ranger.authorization.atlas.testutil.RangerAdminClientImpl</value>
+        <description>Policy source</description>
+    </property>
+
+    <property>
+        <name>ranger.plugin.atlas.policy.cache.dir</name>
+        <value>target/policyCache</value>
+        <description>Directory where Ranger policies are cached after 
successful retrieval from the source</description>
+    </property>
+</configuration>
diff --git a/pom.xml b/pom.xml
index d9f470448..f2a0e40ee 100644
--- a/pom.xml
+++ b/pom.xml
@@ -38,6 +38,7 @@
         <asm.all.version>3.2</asm.all.version>
         <aspectj.version>1.8.2</aspectj.version>
         <assembly.plugin.version>2.6</assembly.plugin.version>
+        <assertj.version>3.27.3</assertj.version>
         <atlas.commons.logging.version>1.1.3</atlas.commons.logging.version>
         <atlas.jackson.databind.version>2.11.3</atlas.jackson.databind.version>
         <atlas.jackson.version>2.11.3</atlas.jackson.version>


Reply via email to