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

madhan pushed a commit to branch ranger-2.6
in repository https://gitbox.apache.org/repos/asf/ranger.git

commit 174b0cae93553a09555708ac3ff04263349cfee2
Author: Fateh Singh <[email protected]>
AuthorDate: Sun Nov 24 23:47:59 2024 -0800

    RANGER-5001: RANGER-4977: Support ignoreDescendantDeny & fix hbase scan 
authorization  (#411)
    
    * RANGER-5001: Support ignoreDescendantDeny
    
    * RANGER-4977: Fix hbase scan authorization by using 
ignoreDescendantDeny=false
    
    (cherry picked from commit 316049090a560f641d7774bbe7ef6490881eac22)
---
 .../plugin/policyengine/RangerAccessRequest.java   |  2 +
 .../policyengine/RangerAccessRequestImpl.java      | 57 ++++++++++++++--------
 .../policyengine/RangerAccessRequestReadOnly.java  |  3 ++
 .../policyengine/RangerAccessRequestWrapper.java   |  3 ++
 .../policyengine/RangerPolicyEngineImpl.java       |  5 ++
 .../policyengine/RangerTagAccessRequest.java       |  1 +
 .../RangerDefaultPolicyEvaluator.java              |  8 +--
 .../test_policyengine_tag_hive_filebased.json      | 26 +++++++++-
 .../authorization/hbase/AuthorizationSession.java  |  8 ++-
 .../hbase/RangerAuthorizationCoprocessor.java      |  2 +
 .../authorization/hbase/TestPolicyEngine.java      |  6 +++
 ...st_policyengine_hbase_ignoreDenyDescendant.json | 55 +++++++++++++++++++++
 12 files changed, 152 insertions(+), 24 deletions(-)

diff --git 
a/agents-common/src/main/java/org/apache/ranger/plugin/policyengine/RangerAccessRequest.java
 
b/agents-common/src/main/java/org/apache/ranger/plugin/policyengine/RangerAccessRequest.java
index 01848df76..2f3e51d33 100644
--- 
a/agents-common/src/main/java/org/apache/ranger/plugin/policyengine/RangerAccessRequest.java
+++ 
b/agents-common/src/main/java/org/apache/ranger/plugin/policyengine/RangerAccessRequest.java
@@ -32,6 +32,8 @@ public interface RangerAccessRequest {
 
        boolean isAccessTypeAny();
 
+       default boolean ignoreDescendantDeny() { return true; }
+
        boolean isAccessTypeDelegatedAdmin();
 
        String getUser();
diff --git 
a/agents-common/src/main/java/org/apache/ranger/plugin/policyengine/RangerAccessRequestImpl.java
 
b/agents-common/src/main/java/org/apache/ranger/plugin/policyengine/RangerAccessRequestImpl.java
index 019a0d893..769b40dd8 100644
--- 
a/agents-common/src/main/java/org/apache/ranger/plugin/policyengine/RangerAccessRequestImpl.java
+++ 
b/agents-common/src/main/java/org/apache/ranger/plugin/policyengine/RangerAccessRequestImpl.java
@@ -50,13 +50,14 @@ public class RangerAccessRequestImpl implements 
RangerAccessRequest {
        private String               action;
        private String               requestData;
        private String               sessionId;
-       private Map<String, Object>  context;
-       private String                           clusterName;
-       private String                           clusterType;
-
-       private boolean isAccessTypeAny;
-       private boolean isAccessTypeDelegatedAdmin;
-       private ResourceMatchingScope resourceMatchingScope = 
ResourceMatchingScope.SELF;
+       private Map<String, Object> context;
+       private String              clusterName;
+       private String              clusterType;
+       private Boolean             isDescendantDenyIgnored = true;
+
+       private boolean                                   isAccessTypeAny;
+       private boolean                                   
isAccessTypeDelegatedAdmin;
+       private ResourceMatchingScope                     resourceMatchingScope 
        = ResourceMatchingScope.SELF;
        private Map<String, ResourceElementMatchingScope> 
resourceElementMatchingScopes = Collections.emptyMap();
 
        public RangerAccessRequestImpl() {
@@ -80,6 +81,7 @@ public class RangerAccessRequestImpl implements 
RangerAccessRequest {
                setSessionId(null);
                setContext(null);
                setClusterName(null);
+               setIgnoreDescendantDeny(null);
        }
 
        public RangerAccessRequestImpl(RangerAccessRequest request) {
@@ -101,6 +103,7 @@ public class RangerAccessRequestImpl implements 
RangerAccessRequest {
                
setResourceElementMatchingScopes(request.getResourceElementMatchingScopes());
                setClientIPAddress(request.getClientIPAddress());
                setClusterType(request.getClusterType());
+               setIgnoreDescendantDeny(request.ignoreDescendantDeny());
        }
 
        @Override
@@ -113,6 +116,11 @@ public class RangerAccessRequestImpl implements 
RangerAccessRequest {
                return accessType;
        }
 
+       @Override
+       public boolean ignoreDescendantDeny() {
+               return isDescendantDenyIgnored == null || 
isDescendantDenyIgnored;
+       }
+
        @Override
        public String getUser() {
                return user;
@@ -134,7 +142,9 @@ public class RangerAccessRequestImpl implements 
RangerAccessRequest {
        }
 
        @Override
-       public String getClientIPAddress() { return clientIPAddress;}
+       public String getClientIPAddress() {
+               return clientIPAddress;
+       }
 
        @Override
        public String getRemoteIPAddress() {
@@ -142,7 +152,9 @@ public class RangerAccessRequestImpl implements 
RangerAccessRequest {
        }
 
        @Override
-       public List<String> getForwardedAddresses() { return 
forwardedAddresses; }
+       public List<String> getForwardedAddresses() {
+               return forwardedAddresses;
+       }
 
        @Override
        public String getClientType() {
@@ -175,7 +187,9 @@ public class RangerAccessRequestImpl implements 
RangerAccessRequest {
        }
 
        @Override
-       public Map<String, ResourceElementMatchingScope> 
getResourceElementMatchingScopes() { return this.resourceElementMatchingScopes; 
}
+       public Map<String, ResourceElementMatchingScope> 
getResourceElementMatchingScopes() {
+               return this.resourceElementMatchingScopes;
+       }
 
        @Override
        public boolean isAccessTypeAny() {
@@ -204,6 +218,10 @@ public class RangerAccessRequestImpl implements 
RangerAccessRequest {
                isAccessTypeDelegatedAdmin = StringUtils.equals(accessType, 
RangerPolicyEngine.ADMIN_ACCESS);
        }
 
+       public void setIgnoreDescendantDeny(Boolean isDescendantDenyIgnored) {
+               this.isDescendantDenyIgnored = isDescendantDenyIgnored == null 
|| isDescendantDenyIgnored;
+       }
+
        public void setUser(String user) {
                this.user = user;
        }
@@ -247,7 +265,7 @@ public class RangerAccessRequestImpl implements 
RangerAccessRequest {
        public void setSessionId(String sessionId) {
                this.sessionId = sessionId;
        }
-       
+
        public String getClusterName() {
                return clusterName;
        }
@@ -289,7 +307,7 @@ public class RangerAccessRequestImpl implements 
RangerAccessRequest {
                }
        }
 
-       public void extractAndSetClientIPAddress(boolean useForwardedIPAddress, 
String[]trustedProxyAddresses) {
+       public void extractAndSetClientIPAddress(boolean useForwardedIPAddress, 
String[] trustedProxyAddresses) {
                String ip = getRemoteIPAddress();
                if (ip == null) {
                        ip = getClientIPAddress();
@@ -328,7 +346,7 @@ public class RangerAccessRequestImpl implements 
RangerAccessRequest {
        }
 
        @Override
-       public String toString( ) {
+       public String toString() {
                StringBuilder sb = new StringBuilder();
 
                toString(sb);
@@ -344,16 +362,16 @@ public class RangerAccessRequestImpl implements 
RangerAccessRequest {
                sb.append("user={").append(user).append("} ");
 
                sb.append("userGroups={");
-               if(userGroups != null) {
-                       for(String userGroup : userGroups) {
+               if (userGroups != null) {
+                       for (String userGroup : userGroups) {
                                sb.append(userGroup).append(" ");
                        }
                }
                sb.append("} ");
 
                sb.append("userRoles={");
-               if(userRoles != null) {
-                       for(String role : userRoles) {
+               if (userRoles != null) {
+                       for (String role : userRoles) {
                                sb.append(role).append(" ");
                        }
                }
@@ -373,8 +391,8 @@ public class RangerAccessRequestImpl implements 
RangerAccessRequest {
                sb.append("clusterType={").append(clusterType).append("} ");
 
                sb.append("context={");
-               if(context != null) {
-                       for(Map.Entry<String, Object> e : context.entrySet()) {
+               if (context != null) {
+                       for (Map.Entry<String, Object> e : context.entrySet()) {
                                Object val = e.getValue();
 
                                if (!(val instanceof RangerAccessRequest)) { // 
to avoid recursive calls
@@ -388,6 +406,7 @@ public class RangerAccessRequestImpl implements 
RangerAccessRequest {
 
                return sb;
        }
+
        @Override
        public RangerAccessRequest getReadOnlyCopy() {
                return new RangerAccessRequestReadOnly(this);
diff --git 
a/agents-common/src/main/java/org/apache/ranger/plugin/policyengine/RangerAccessRequestReadOnly.java
 
b/agents-common/src/main/java/org/apache/ranger/plugin/policyengine/RangerAccessRequestReadOnly.java
index b732dfab6..1669efb1c 100644
--- 
a/agents-common/src/main/java/org/apache/ranger/plugin/policyengine/RangerAccessRequestReadOnly.java
+++ 
b/agents-common/src/main/java/org/apache/ranger/plugin/policyengine/RangerAccessRequestReadOnly.java
@@ -53,6 +53,9 @@ public class RangerAccessRequestReadOnly implements 
RangerAccessRequest {
        @Override
        public boolean isAccessTypeAny() { return source.isAccessTypeAny(); }
 
+       @Override
+       public boolean ignoreDescendantDeny() { return 
source.ignoreDescendantDeny(); }
+
        @Override
        public boolean isAccessTypeDelegatedAdmin() { return 
source.isAccessTypeDelegatedAdmin(); }
 
diff --git 
a/agents-common/src/main/java/org/apache/ranger/plugin/policyengine/RangerAccessRequestWrapper.java
 
b/agents-common/src/main/java/org/apache/ranger/plugin/policyengine/RangerAccessRequestWrapper.java
index 96f851e9a..d309c6204 100644
--- 
a/agents-common/src/main/java/org/apache/ranger/plugin/policyengine/RangerAccessRequestWrapper.java
+++ 
b/agents-common/src/main/java/org/apache/ranger/plugin/policyengine/RangerAccessRequestWrapper.java
@@ -47,6 +47,9 @@ public class RangerAccessRequestWrapper implements 
RangerAccessRequest {
     @Override
     public String getAccessType() { return accessType; }
 
+    @Override
+    public boolean ignoreDescendantDeny() { return 
request.ignoreDescendantDeny(); }
+
     @Override
     public boolean isAccessTypeAny() { return isAccessTypeAny; }
 
diff --git 
a/agents-common/src/main/java/org/apache/ranger/plugin/policyengine/RangerPolicyEngineImpl.java
 
b/agents-common/src/main/java/org/apache/ranger/plugin/policyengine/RangerPolicyEngineImpl.java
index bb4996cbe..bb2d57640 100644
--- 
a/agents-common/src/main/java/org/apache/ranger/plugin/policyengine/RangerPolicyEngineImpl.java
+++ 
b/agents-common/src/main/java/org/apache/ranger/plugin/policyengine/RangerPolicyEngineImpl.java
@@ -51,6 +51,7 @@ import java.util.HashSet;
 import java.util.List;
 import java.util.Map;
 import java.util.Set;
+import java.util.stream.Collectors;
 
 import static 
org.apache.ranger.plugin.policyengine.PolicyEvaluatorForTag.MATCH_TYPE_COMPARATOR;
 
@@ -677,6 +678,10 @@ public class RangerPolicyEngineImpl implements 
RangerPolicyEngine {
                        }
                        
RangerAccessRequestUtil.setAllRequestedAccessTypes(request.getContext(), 
allRequestedAccesses);
                        
RangerAccessRequestUtil.setIsAnyAccessInContext(request.getContext(), 
Boolean.TRUE);
+                       if (!request.ignoreDescendantDeny()) {
+                               Set<Set<String>> accessGroups = 
allRequestedAccesses.stream().map(Collections::singleton).collect(Collectors.toSet());
+                               
RangerAccessRequestUtil.setAllRequestedAccessTypeGroups(request, accessGroups);
+                       }
                }
 
                ret = evaluatePoliciesForOneAccessTypeNoAudit(request, 
policyType, zoneName, policyRepository, tagPolicyRepository);
diff --git 
a/agents-common/src/main/java/org/apache/ranger/plugin/policyengine/RangerTagAccessRequest.java
 
b/agents-common/src/main/java/org/apache/ranger/plugin/policyengine/RangerTagAccessRequest.java
index 4b2d70645..24ad6b337 100644
--- 
a/agents-common/src/main/java/org/apache/ranger/plugin/policyengine/RangerTagAccessRequest.java
+++ 
b/agents-common/src/main/java/org/apache/ranger/plugin/policyengine/RangerTagAccessRequest.java
@@ -61,6 +61,7 @@ public class RangerTagAccessRequest extends 
RangerAccessRequestImpl {
                super.setForwardedAddresses(request.getForwardedAddresses());
                super.setSessionId(request.getSessionId());
                
super.setResourceMatchingScope(request.getResourceMatchingScope());
+               super.setIgnoreDescendantDeny(request.ignoreDescendantDeny());
        }
        public RangerPolicyResourceMatcher.MatchType getMatchType() {
                return matchType;
diff --git 
a/agents-common/src/main/java/org/apache/ranger/plugin/policyevaluator/RangerDefaultPolicyEvaluator.java
 
b/agents-common/src/main/java/org/apache/ranger/plugin/policyevaluator/RangerDefaultPolicyEvaluator.java
index 183d93a4b..e2e3137eb 100644
--- 
a/agents-common/src/main/java/org/apache/ranger/plugin/policyevaluator/RangerDefaultPolicyEvaluator.java
+++ 
b/agents-common/src/main/java/org/apache/ranger/plugin/policyevaluator/RangerDefaultPolicyEvaluator.java
@@ -535,7 +535,7 @@ public class RangerDefaultPolicyEvaluator extends 
RangerAbstractPolicyEvaluator
                        LOG.debug("==> 
RangerDefaultPolicyEvaluator.updateAccessResult(" + result + ", " + matchType 
+", " + isAllowed + ", " + reason + ", " + getPolicyId() + ")");
                }
                if (!isAllowed) {
-                       if (matchType != 
RangerPolicyResourceMatcher.MatchType.DESCENDANT) {
+                       if (matchType != 
RangerPolicyResourceMatcher.MatchType.DESCENDANT || 
!result.getAccessRequest().ignoreDescendantDeny()) {
                                result.setIsAllowed(false);
                                result.setPolicyPriority(getPolicyPriority());
                                result.setPolicyId(getPolicyId());
@@ -870,11 +870,13 @@ public class RangerDefaultPolicyEvaluator extends 
RangerAbstractPolicyEvaluator
                                                        }
                                                }
                                        }
-                                       /* At least one access is allowed - 
this evaluator need not be checked for other accesses as the test below
+                                       /* At least one access is allowed or 
denied - this evaluator need not be checked for other accesses as the test below
                                         * implies that there is only one 
access group in the request
                                         */
                                        if (oneRequest.isAccessTypeAny() || 
RangerAccessRequestUtil.getIsAnyAccessInContext(oneRequest.getContext())) {
-                                               if (allowResult != null) {
+                                               if 
(oneRequest.ignoreDescendantDeny() && allowResult != null) {
+                                                       break;
+                                               } else if 
(!oneRequest.ignoreDescendantDeny() && denyResult != null) {
                                                        break;
                                                }
                                        }
diff --git 
a/agents-common/src/test/resources/policyengine/test_policyengine_tag_hive_filebased.json
 
b/agents-common/src/test/resources/policyengine/test_policyengine_tag_hive_filebased.json
index b3ca12ed6..4f92f82af 100644
--- 
a/agents-common/src/test/resources/policyengine/test_policyengine_tag_hive_filebased.json
+++ 
b/agents-common/src/test/resources/policyengine/test_policyengine_tag_hive_filebased.json
@@ -225,7 +225,7 @@
   },
 
   "tests":[
-    {"name":"DENY 'select from employee.personal;' for user1 using EXPIRES_ON 
tag",
+    {"name":"ALLOW 'select from employee.personal;' for user1 using EXPIRES_ON 
tag",
       "request":{
         "resource":{"elements":{"database":"employee", "table":"personal"}}, 
"resourceMatchingScope": "SELF_OR_DESCENDANTS",
         
"accessType":"select","user":"user1","userGroups":[],"requestData":"select from 
employee.personal;' for user1"
@@ -233,6 +233,30 @@
       },
       "result":{"isAudited":true,"isAllowed":true,"policyId":101}
     },
+    {"name":"DENY 'select from employee.personal;' for user1 using EXPIRES_ON 
tag with isDescendantDenyIgnored=false",
+      "request":{
+        "resource":{"elements":{"database":"employee", "table":"personal"}}, 
"resourceMatchingScope": "SELF_OR_DESCENDANTS", "isDescendantDenyIgnored": 
false,
+        
"accessType":"select","user":"user1","userGroups":[],"requestData":"select from 
employee.personal;' for user1 with isDescendantDenyIgnored=false"
+
+      },
+      "result":{"isAudited":true,"isAllowed":false,"policyId":5}
+    },
+    {"name":"ALLOW 'use employee;' for user1 using EXPIRES_ON tag",
+      "request":{
+        "resource":{"elements":{"database":"employee"}},
+        "accessType":"","user":"user1","userGroups":[],"requestData":"use 
employee;' for user1 using EXPIRES_ON tag"
+
+      },
+      "result":{"isAudited":true,"isAllowed":true,"policyId":101}
+    },
+    {"name":"DENY 'use employee;' for user1 using EXPIRES_ON tag with 
isDescendantDenyIgnored=false",
+      "request":{
+        "resource":{"elements":{"database":"employee"}}, 
"isDescendantDenyIgnored": false,
+        "accessType":"","user":"user1","userGroups":[],"requestData":"use 
employee;' for user1 using EXPIRES_ON tag with isDescendantDenyIgnored=false"
+
+      },
+      "result":{"isAudited":true,"isAllowed":false,"policyId":5}
+    },
     {"name":"ALLOW 'select ssn from employee.personal;' for user1 using 
EXPIRES_ON tag",
       "request":{
         "resource":{"elements":{"database":"employee", "table":"personal", 
"column":"ssn"}},
diff --git 
a/hbase-agent/src/main/java/org/apache/ranger/authorization/hbase/AuthorizationSession.java
 
b/hbase-agent/src/main/java/org/apache/ranger/authorization/hbase/AuthorizationSession.java
index 152c8a697..6e999ba51 100644
--- 
a/hbase-agent/src/main/java/org/apache/ranger/authorization/hbase/AuthorizationSession.java
+++ 
b/hbase-agent/src/main/java/org/apache/ranger/authorization/hbase/AuthorizationSession.java
@@ -64,6 +64,8 @@ public class AuthorizationSession {
        boolean _superUser = false; // is this session for a super user?
        private RangerAccessRequest.ResourceMatchingScope 
_resourceMatchingScope = RangerAccessRequest.ResourceMatchingScope.SELF;
 
+       private boolean _ignoreDescendantDeny = true;
+
        // internal state per-authorization
        RangerAccessRequest _request;
        RangerAccessResult _result;
@@ -195,7 +197,7 @@ public class AuthorizationSession {
                request.setClientIPAddress(_remoteAddress);
                request.setResourceMatchingScope(_resourceMatchingScope);
                request.setAccessTime(new Date());
-               
+               request.setIgnoreDescendantDeny(_ignoreDescendantDeny);
                _request = request;
                if (LOG.isDebugEnabled()) {
                        LOG.debug("Built request: " + request.toString());
@@ -377,4 +379,8 @@ public class AuthorizationSession {
                _resourceMatchingScope = scope;
                return this;
        }
+       AuthorizationSession ignoreDescendantDeny(boolean ignoreDescendantDeny) 
{
+               _ignoreDescendantDeny = ignoreDescendantDeny;
+               return this;
+       }
 }
diff --git 
a/hbase-agent/src/main/java/org/apache/ranger/authorization/hbase/RangerAuthorizationCoprocessor.java
 
b/hbase-agent/src/main/java/org/apache/ranger/authorization/hbase/RangerAuthorizationCoprocessor.java
index 15e57fa36..2c9b6b80b 100644
--- 
a/hbase-agent/src/main/java/org/apache/ranger/authorization/hbase/RangerAuthorizationCoprocessor.java
+++ 
b/hbase-agent/src/main/java/org/apache/ranger/authorization/hbase/RangerAuthorizationCoprocessor.java
@@ -441,6 +441,7 @@ public class RangerAuthorizationCoprocessor implements 
AccessControlService.Inte
                                        LOG.debug("evaluateAccess: family level 
access for [" + family + "] is evaluated to " + isColumnFamilyAuthorized + ". 
Checking if [" + family + "] descendants have access.");
                                }
                                
session.resourceMatchingScope(RangerAccessRequest.ResourceMatchingScope.SELF_OR_DESCENDANTS)
+                                               .ignoreDescendantDeny(false)
                                                .buildRequest()
                                                .authorize();
                                auditEvent = 
auditHandler.getAndDiscardMostRecentEvent(); // capture it only for failure
@@ -488,6 +489,7 @@ public class RangerAuthorizationCoprocessor implements 
AccessControlService.Inte
                                }
                                // Restore the headMatch setting
                                
session.resourceMatchingScope(RangerAccessRequest.ResourceMatchingScope.SELF);
+                               session.ignoreDescendantDeny(true);
                        } else {
                                LOG.debug("evaluateAccess: columns collection 
not empty.  Skipping Family level check, will do finer level access check.");
                                Set<String> accessibleColumns = new 
HashSet<String>(); // will be used in to populate our results cache for the 
filter
diff --git 
a/hbase-agent/src/test/java/org/apache/ranger/authorization/hbase/TestPolicyEngine.java
 
b/hbase-agent/src/test/java/org/apache/ranger/authorization/hbase/TestPolicyEngine.java
index 771038521..8c120419d 100644
--- 
a/hbase-agent/src/test/java/org/apache/ranger/authorization/hbase/TestPolicyEngine.java
+++ 
b/hbase-agent/src/test/java/org/apache/ranger/authorization/hbase/TestPolicyEngine.java
@@ -82,6 +82,12 @@ public class TestPolicyEngine {
 
                runTestsFromResourceFiles(hbaseTestResourceFiles);
        }
+       @Test
+       public void testPolicyEngine_hbase_ignoreDescendantDeny() {
+               String[] hbaseTestResourceFiles = { 
"/policyengine/test_policyengine_hbase_ignoreDenyDescendant.json" };
+
+               runTestsFromResourceFiles(hbaseTestResourceFiles);
+       }
 
        private void runTestsFromResourceFiles(String[] resourceNames) {
                for(String resourceName : resourceNames) {
diff --git 
a/hbase-agent/src/test/resources/policyengine/test_policyengine_hbase_ignoreDenyDescendant.json
 
b/hbase-agent/src/test/resources/policyengine/test_policyengine_hbase_ignoreDenyDescendant.json
new file mode 100644
index 000000000..1256f7e33
--- /dev/null
+++ 
b/hbase-agent/src/test/resources/policyengine/test_policyengine_hbase_ignoreDenyDescendant.json
@@ -0,0 +1,55 @@
+{
+  "serviceName":"hbasedev",
+
+  "serviceDef":{
+    "name":"hbase",
+    "id":2,
+    "resources":[
+      
{"name":"table","level":1,"parent":"","mandatory":true,"lookupSupported":true,"matcher":"org.apache.ranger.plugin.resourcematcher.RangerDefaultResourceMatcher","matcherOptions":{"wildCard":true,
 "ignoreCase":true},"label":"HBase Table","description":"HBase Table"},
+      
{"name":"column-family","level":2,"parent":"table","mandatory":true,"lookupSupported":true,"matcher":"org.apache.ranger.plugin.resourcematcher.RangerDefaultResourceMatcher","matcherOptions":{"wildCard":true,
 "ignoreCase":true},"label":"HBase Column-Family","description":"HBase 
Column-Family"},
+      
{"name":"column","level":3,"parent":"column-family","mandatory":true,"lookupSupported":true,"matcher":"org.apache.ranger.plugin.resourcematcher.RangerDefaultResourceMatcher","matcherOptions":{"wildCard":true,
 "ignoreCase":true},"label":"HBase Column","description":"HBase Column"}
+    ],
+    "accessTypes":[
+      {"name":"read","label":"Read"},
+      {"name":"write","label":"Write"},
+      {"name":"create","label":"Create"},
+      
{"name":"admin","label":"Admin","impliedGrants":["read","write","create"]}
+    ]
+  },
+
+  "policies":[
+    {"id":1,"name":"table=finance; column-family=restricted, 
column=restricted_column","isEnabled":true,"isAuditEnabled":true,
+      
"resources":{"table":{"values":["finance"]},"column-family":{"values":["restricted_cf"]},
 "column":{"values":["restricted_column"]}},
+      "denyPolicyItems":[
+        
{"accesses":[{"type":"read","isAllowed":true}],"users":["user1"],"groups":[],"delegateAdmin":false}
+      ]
+    }
+  ,
+    {"id":2,"name":"table=finance; 
column-family=restricted,column=*","isEnabled":true,"isAuditEnabled":true,
+      
"resources":{"table":{"values":["finance"]},"column-family":{"values":["restricted_cf"]},
 "column":{"values":["*"]}},
+      "policyItems":[
+        
{"accesses":[{"type":"read","isAllowed":true}],"users":["user1"],"groups":[],"delegateAdmin":false}
+      ]
+    }
+  ],
+
+  "tests":[
+    {"name":"TEST!!! DENY 'get' for restricted column family when 
isDescendantDenyIgnored=false",
+      "request":{
+        
"resource":{"elements":{"table":"finance","column-family":"restricted_cf"}},
+        "resourceMatchingScope": 
"SELF_OR_DESCENDANTS","isDescendantDenyIgnored": "false",
+        "accessType":"read","user":"user1","requestData":"deny get as there is 
a restricted column. Expected behavior for scan"
+      },
+      "result":{"isAudited":true,"isAllowed":false,"policyId":1}
+    },
+    {"name":"TEST!!! Allow 'get' for restricted column family when 
isDescendantDenyIgnored=true",
+      "request":{
+        
"resource":{"elements":{"table":"finance","column-family":"restricted_cf"}},
+        "resourceMatchingScope": "SELF_OR_DESCENDANTS",
+        "accessType":"read","user":"user1","requestData":"allow get as 
restricted column policy not considered. Not expected behavior"
+      },
+      "result":{"isAudited":true,"isAllowed":true,"policyId":2}
+    }
+
+  ]
+}

Reply via email to