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

morningman pushed a commit to branch branch-2.1
in repository https://gitbox.apache.org/repos/asf/doris.git


The following commit(s) were added to refs/heads/branch-2.1 by this push:
     new 3cb0deae9ce [opt](ranger) modify and enhance the feature of ranger 
access controller (#34392) (#34426)
3cb0deae9ce is described below

commit 3cb0deae9ceef92c71c35444c495bc5b94de6c7c
Author: Mingyu Chen <morning...@163.com>
AuthorDate: Mon May 6 17:08:47 2024 +0800

    [opt](ranger) modify and enhance the feature of ranger access controller 
(#34392) (#34426)
    
    bp #34392
---
 .../authorizer/ranger/RangerAccessController.java  |  29 ++-
 .../authorizer/ranger/doris/DorisAccessType.java   |   6 +-
 .../ranger/doris/RangerDorisAccessController.java  |  27 ++-
 .../ranger/hive/RangerHiveAccessController.java    |   4 +-
 .../org/apache/doris/common/util/PrintableMap.java |  11 +-
 .../org/apache/doris/mysql/privilege/Auth.java     |   3 +-
 .../expressions/functions/scalar/DateTrunc.java    |   2 +-
 .../apache/doris/mysql/privilege/RangerTest.java   | 230 +++++++++++++++++++++
 8 files changed, 297 insertions(+), 15 deletions(-)

diff --git 
a/fe/fe-core/src/main/java/org/apache/doris/catalog/authorizer/ranger/RangerAccessController.java
 
b/fe/fe-core/src/main/java/org/apache/doris/catalog/authorizer/ranger/RangerAccessController.java
index 5f49f4d5735..41aa5213839 100644
--- 
a/fe/fe-core/src/main/java/org/apache/doris/catalog/authorizer/ranger/RangerAccessController.java
+++ 
b/fe/fe-core/src/main/java/org/apache/doris/catalog/authorizer/ranger/RangerAccessController.java
@@ -68,7 +68,6 @@ public abstract class RangerAccessController implements 
CatalogAccessController
         }
     }
 
-
     public static void checkRequestResults(Collection<RangerAccessResult> 
results, String name)
             throws AuthorizationException {
         for (RangerAccessResult result : results) {
@@ -82,7 +81,8 @@ public abstract class RangerAccessController implements 
CatalogAccessController
                 throw new AuthorizationException(String.format(
                         "Permission denied: user [%s] does not have privilege 
for [%s] command on [%s]",
                         result.getAccessRequest().getUser(), name,
-                        
result.getAccessRequest().getResource().getAsString().replaceAll("/", ".")));
+                        
Optional.ofNullable(result.getAccessRequest().getResource().getAsString())
+                                .orElse("unknown resource").replaceAll("/", 
".")));
             }
         }
     }
@@ -135,12 +135,27 @@ public abstract class RangerAccessController implements 
CatalogAccessController
         if (StringUtils.isEmpty(maskType)) {
             return Optional.empty();
         }
-        String transformer = policy.getMaskTypeDef().getTransformer();
-        if (StringUtils.isEmpty(transformer)) {
-            return Optional.empty();
+        switch (maskType) {
+            case "MASK_NULL":
+                return Optional.of(new RangerDataMaskPolicy(currentUser, ctl, 
db, tbl, col, policy.getPolicyId(),
+                        policy.getPolicyVersion(), maskType, "NULL"));
+            case "MASK_NONE":
+                return Optional.empty();
+            case "CUSTOM":
+                String maskedValue = policy.getMaskedValue();
+                if (StringUtils.isEmpty(maskedValue)) {
+                    return Optional.empty();
+                }
+                return Optional.of(new RangerDataMaskPolicy(currentUser, ctl, 
db, tbl, col, policy.getPolicyId(),
+                        policy.getPolicyVersion(), maskType, 
maskedValue.replace("{col}", col)));
+            default:
+                String transformer = policy.getMaskTypeDef().getTransformer();
+                if (StringUtils.isEmpty(transformer)) {
+                    return Optional.empty();
+                }
+                return Optional.of(new RangerDataMaskPolicy(currentUser, ctl, 
db, tbl, col, policy.getPolicyId(),
+                        policy.getPolicyVersion(), maskType, 
transformer.replace("{col}", col)));
         }
-        return Optional.of(new RangerDataMaskPolicy(currentUser, ctl, db, tbl, 
col, policy.getPolicyId(),
-                policy.getPolicyVersion(), maskType, 
transformer.replace("{col}", col)));
     }
 
     protected abstract RangerAccessRequestImpl createRequest(UserIdentity 
currentUser);
diff --git 
a/fe/fe-core/src/main/java/org/apache/doris/catalog/authorizer/ranger/doris/DorisAccessType.java
 
b/fe/fe-core/src/main/java/org/apache/doris/catalog/authorizer/ranger/doris/DorisAccessType.java
index e71d6847e8a..259646557da 100644
--- 
a/fe/fe-core/src/main/java/org/apache/doris/catalog/authorizer/ranger/doris/DorisAccessType.java
+++ 
b/fe/fe-core/src/main/java/org/apache/doris/catalog/authorizer/ranger/doris/DorisAccessType.java
@@ -46,9 +46,11 @@ public enum DorisAccessType {
         } else if (priv == PrivPredicate.SHOW_VIEW) {
             return SHOW_VIEW;
         } else if (priv == PrivPredicate.SHOW_RESOURCES) {
-            return SHOW_RESOURCES;
+            // For Ranger, there is only USAGE priv for RESOURCE and 
WORKLOAD_GROUP.
+            // So when checking SHOW_XXX priv, convert it to USAGE priv and 
pass to Ranger.
+            return USAGE;
         } else if (priv == PrivPredicate.SHOW_WORKLOAD_GROUP) {
-            return SHOW_WORKLOAD_GROUP;
+            return USAGE;
         } else if (priv == PrivPredicate.GRANT) {
             return GRANT;
         } else if (priv == PrivPredicate.ADMIN) {
diff --git 
a/fe/fe-core/src/main/java/org/apache/doris/catalog/authorizer/ranger/doris/RangerDorisAccessController.java
 
b/fe/fe-core/src/main/java/org/apache/doris/catalog/authorizer/ranger/doris/RangerDorisAccessController.java
index 280321cf26f..fdf9064a5f7 100644
--- 
a/fe/fe-core/src/main/java/org/apache/doris/catalog/authorizer/ranger/doris/RangerDorisAccessController.java
+++ 
b/fe/fe-core/src/main/java/org/apache/doris/catalog/authorizer/ranger/doris/RangerDorisAccessController.java
@@ -23,7 +23,9 @@ import 
org.apache.doris.catalog.authorizer.ranger.RangerAccessController;
 import org.apache.doris.cluster.ClusterNamespace;
 import org.apache.doris.common.AuthorizationException;
 import org.apache.doris.mysql.privilege.PrivPredicate;
+import org.apache.doris.resource.workloadgroup.WorkloadGroupMgr;
 
+import com.google.common.annotations.VisibleForTesting;
 import org.apache.logging.log4j.LogManager;
 import org.apache.logging.log4j.Logger;
 import org.apache.ranger.plugin.policyengine.RangerAccessRequest;
@@ -41,7 +43,7 @@ import java.util.stream.Collectors;
 
 public class RangerDorisAccessController extends RangerAccessController {
     private static final Logger LOG = 
LogManager.getLogger(RangerDorisAccessController.class);
-    private RangerDorisPlugin dorisPlugin;
+    private RangerBasePlugin dorisPlugin;
     // private static ScheduledThreadPoolExecutor logFlushTimer = 
ThreadPoolManager.newDaemonScheduledThreadPool(1,
     //        "ranger-doris-audit-log-flusher-timer", true);
     // private RangerHiveAuditHandler auditHandler;
@@ -53,6 +55,11 @@ public class RangerDorisAccessController extends 
RangerAccessController {
         // logFlushTimer.scheduleAtFixedRate(new 
RangerHiveAuditLogFlusher(auditHandler), 10, 20L, TimeUnit.SECONDS);
     }
 
+    @VisibleForTesting
+    public RangerDorisAccessController(RangerBasePlugin plugin) {
+        dorisPlugin = plugin;
+    }
+
     private RangerAccessRequestImpl createRequest(UserIdentity currentUser, 
DorisAccessType accessType) {
         RangerAccessRequestImpl request = createRequest(currentUser);
         request.setAction(accessType.name());
@@ -117,6 +124,10 @@ public class RangerDorisAccessController extends 
RangerAccessController {
 
     @Override
     public boolean checkDbPriv(UserIdentity currentUser, String ctl, String 
db, PrivPredicate wanted) {
+        boolean res = checkCtlPriv(currentUser, ctl, wanted);
+        if (res) {
+            return true;
+        }
         RangerDorisResource resource = new 
RangerDorisResource(DorisObjectType.DATABASE, ctl,
                 ClusterNamespace.getNameFromFullName(db));
         return checkPrivilege(currentUser, 
DorisAccessType.toAccessType(wanted), resource);
@@ -124,6 +135,11 @@ public class RangerDorisAccessController extends 
RangerAccessController {
 
     @Override
     public boolean checkTblPriv(UserIdentity currentUser, String ctl, String 
db, String tbl, PrivPredicate wanted) {
+        boolean res = checkDbPriv(currentUser, ctl, db, wanted);
+        if (res) {
+            return true;
+        }
+
         RangerDorisResource resource = new 
RangerDorisResource(DorisObjectType.TABLE,
                 ctl, ClusterNamespace.getNameFromFullName(db), tbl);
         return checkPrivilege(currentUser, 
DorisAccessType.toAccessType(wanted), resource);
@@ -132,6 +148,11 @@ public class RangerDorisAccessController extends 
RangerAccessController {
     @Override
     public void checkColsPriv(UserIdentity currentUser, String ctl, String db, 
String tbl, Set<String> cols,
             PrivPredicate wanted) throws AuthorizationException {
+        boolean res = checkTblPriv(currentUser, ctl, db, tbl, wanted);
+        if (res) {
+            return;
+        }
+
         List<RangerDorisResource> resources = new ArrayList<>();
         for (String col : cols) {
             RangerDorisResource resource = new 
RangerDorisResource(DorisObjectType.COLUMN,
@@ -150,6 +171,10 @@ public class RangerDorisAccessController extends 
RangerAccessController {
 
     @Override
     public boolean checkWorkloadGroupPriv(UserIdentity currentUser, String 
workloadGroupName, PrivPredicate wanted) {
+        // For compatibility with older versions, it is not needed to check 
the privileges of the default group.
+        if (WorkloadGroupMgr.DEFAULT_GROUP_NAME.equals(workloadGroupName)) {
+            return true;
+        }
         RangerDorisResource resource = new 
RangerDorisResource(DorisObjectType.WORKLOAD_GROUP, workloadGroupName);
         return checkPrivilege(currentUser, 
DorisAccessType.toAccessType(wanted), resource);
     }
diff --git 
a/fe/fe-core/src/main/java/org/apache/doris/catalog/authorizer/ranger/hive/RangerHiveAccessController.java
 
b/fe/fe-core/src/main/java/org/apache/doris/catalog/authorizer/ranger/hive/RangerHiveAccessController.java
index 789ba9ddf4a..f746607303d 100644
--- 
a/fe/fe-core/src/main/java/org/apache/doris/catalog/authorizer/ranger/hive/RangerHiveAccessController.java
+++ 
b/fe/fe-core/src/main/java/org/apache/doris/catalog/authorizer/ranger/hive/RangerHiveAccessController.java
@@ -184,7 +184,9 @@ public class RangerHiveAccessController extends 
RangerAccessController {
 
     @Override
     public boolean checkWorkloadGroupPriv(UserIdentity currentUser, String 
workloadGroupName, PrivPredicate wanted) {
-        return false;
+        // Not support workload group privilege in ranger hive plugin.
+        // So always return true to pass the check
+        return true;
     }
 
     @Override
diff --git 
a/fe/fe-core/src/main/java/org/apache/doris/common/util/PrintableMap.java 
b/fe/fe-core/src/main/java/org/apache/doris/common/util/PrintableMap.java
index 27d6468827b..734f0ae2268 100644
--- a/fe/fe-core/src/main/java/org/apache/doris/common/util/PrintableMap.java
+++ b/fe/fe-core/src/main/java/org/apache/doris/common/util/PrintableMap.java
@@ -55,8 +55,15 @@ public class PrintableMap<K, V> {
         SENSITIVE_KEY.add("bos_secret_accesskey");
         SENSITIVE_KEY.add("jdbc.password");
         SENSITIVE_KEY.add("elasticsearch.password");
-        SENSITIVE_KEY.addAll(Arrays.asList(S3Properties.SECRET_KEY, 
ObsProperties.SECRET_KEY, OssProperties.SECRET_KEY,
-                GCSProperties.SECRET_KEY, CosProperties.SECRET_KEY, 
GlueProperties.SECRET_KEY, MCProperties.SECRET_KEY,
+        SENSITIVE_KEY.addAll(Arrays.asList(
+                S3Properties.SECRET_KEY,
+                S3Properties.Env.SECRET_KEY,
+                ObsProperties.SECRET_KEY,
+                OssProperties.SECRET_KEY,
+                GCSProperties.SECRET_KEY,
+                CosProperties.SECRET_KEY,
+                GlueProperties.SECRET_KEY,
+                MCProperties.SECRET_KEY,
                 DLFProperties.SECRET_KEY));
         HIDDEN_KEY = Sets.newHashSet();
         HIDDEN_KEY.addAll(S3Properties.Env.FS_KEYS);
diff --git 
a/fe/fe-core/src/main/java/org/apache/doris/mysql/privilege/Auth.java 
b/fe/fe-core/src/main/java/org/apache/doris/mysql/privilege/Auth.java
index cd47128beed..2c7d99d4195 100644
--- a/fe/fe-core/src/main/java/org/apache/doris/mysql/privilege/Auth.java
+++ b/fe/fe-core/src/main/java/org/apache/doris/mysql/privilege/Auth.java
@@ -386,12 +386,13 @@ public class Auth implements Writable {
     public boolean checkWorkloadGroupPriv(UserIdentity currentUser, String 
workloadGroupName, PrivPredicate wanted) {
         readLock();
         try {
-            Set<Role> roles = getRolesByUserWithLdap(currentUser);
             // currently stream load not support ip based auth, so normal 
should not auth temporary
             // need remove later
             if (WorkloadGroupMgr.DEFAULT_GROUP_NAME.equals(workloadGroupName)) 
{
                 return true;
             }
+
+            Set<Role> roles = getRolesByUserWithLdap(currentUser);
             for (Role role : roles) {
                 if (role.checkWorkloadGroupPriv(workloadGroupName, wanted)) {
                     return true;
diff --git 
a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/scalar/DateTrunc.java
 
b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/scalar/DateTrunc.java
index 03408b48dd5..743976c6c1a 100644
--- 
a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/scalar/DateTrunc.java
+++ 
b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/scalar/DateTrunc.java
@@ -68,7 +68,7 @@ public class DateTrunc extends ScalarFunction
         final String constParam = ((VarcharLiteral) 
getArgument(1)).getStringValue().toLowerCase();
         if (!Lists.newArrayList("year", "quarter", "month", "week", "day", 
"hour", "minute", "second")
                 .contains(constParam)) {
-            throw new AnalysisException("date_trunc function second param only 
support argument is"
+            throw new AnalysisException("date_trunc function second param only 
support argument is "
                     + "year|quarter|month|week|day|hour|minute|second");
         }
     }
diff --git 
a/fe/fe-core/src/test/java/org/apache/doris/mysql/privilege/RangerTest.java 
b/fe/fe-core/src/test/java/org/apache/doris/mysql/privilege/RangerTest.java
new file mode 100644
index 00000000000..a0f0ef0f2d1
--- /dev/null
+++ b/fe/fe-core/src/test/java/org/apache/doris/mysql/privilege/RangerTest.java
@@ -0,0 +1,230 @@
+// 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.doris.mysql.privilege;
+
+import org.apache.doris.analysis.UserIdentity;
+import 
org.apache.doris.catalog.authorizer.ranger.doris.RangerDorisAccessController;
+import org.apache.doris.catalog.authorizer.ranger.doris.RangerDorisResource;
+import org.apache.doris.common.AuthorizationException;
+
+import com.google.common.base.Strings;
+import com.google.common.collect.Lists;
+import com.google.common.collect.Sets;
+import org.apache.ranger.plugin.policyengine.RangerAccessRequest;
+import org.apache.ranger.plugin.policyengine.RangerAccessResource;
+import org.apache.ranger.plugin.policyengine.RangerAccessResult;
+import org.apache.ranger.plugin.policyengine.RangerAccessResultProcessor;
+import org.apache.ranger.plugin.service.RangerBasePlugin;
+import org.junit.Test;
+import org.junit.jupiter.api.Assertions;
+
+import java.util.Collection;
+import java.util.List;
+import java.util.Optional;
+import java.util.Set;
+
+public class RangerTest {
+
+    public static class DorisTestPlugin extends RangerBasePlugin {
+        public DorisTestPlugin(String serviceName) {
+            super(serviceName, null, null);
+            // super.init();
+        }
+
+        @Override
+        public Collection<RangerAccessResult> 
isAccessAllowed(Collection<RangerAccessRequest> requests) {
+            List<RangerAccessResult> results = Lists.newArrayList();
+            for (RangerAccessRequest request : requests) {
+                RangerAccessResult result = isAccessAllowed(request);
+                if (result != null) {
+                    results.add(result);
+                }
+            }
+            return results;
+        }
+
+        @Override
+        public RangerAccessResult isAccessAllowed(RangerAccessRequest request) 
{
+            RangerAccessResource resource = request.getResource();
+            String ctl = (String) 
resource.getValue(RangerDorisResource.KEY_CATALOG);
+            String db = (String) 
resource.getValue(RangerDorisResource.KEY_DATABASE);
+            String tbl = (String) 
resource.getValue(RangerDorisResource.KEY_TABLE);
+            String col = (String) 
resource.getValue(RangerDorisResource.KEY_COLUMN);
+            String rs = (String) 
resource.getValue(RangerDorisResource.KEY_RESOURCE);
+            String wg = (String) 
resource.getValue(RangerDorisResource.KEY_WORKLOAD_GROUP);
+            String user = request.getUser();
+            return returnAccessResult(request, ctl, db, tbl, col, rs, wg, 
user);
+        }
+
+        @Override
+        public RangerAccessResult evalDataMaskPolicies(RangerAccessRequest 
request,
+                RangerAccessResultProcessor resultProcessor) {
+            RangerAccessResource resource = request.getResource();
+            String ctl = (String) 
resource.getValue(RangerDorisResource.KEY_CATALOG);
+            String db = (String) 
resource.getValue(RangerDorisResource.KEY_DATABASE);
+            String tbl = (String) 
resource.getValue(RangerDorisResource.KEY_TABLE);
+            String col = (String) 
resource.getValue(RangerDorisResource.KEY_COLUMN);
+
+            RangerAccessResult result = new RangerAccessResult(2, "test", 
null, request);
+            result.setPolicyVersion(1L);
+            if ("ctl1".equals(ctl) && "db1".equals(db) && "tbl1".equals(tbl) 
&& "col1".equals(col)) {
+                result.addAdditionalInfo("maskType", "MASK_NULL");
+            } else if ("ctl1".equals(ctl) && "db1".equals(db) && 
"tbl1".equals(tbl) && "col2".equals(col)) {
+                result.addAdditionalInfo("maskType", "MASK_NONE");
+            } else if ("ctl1".equals(ctl) && "db1".equals(db) && 
"tbl1".equals(tbl) && "col3".equals(col)) {
+                result.addAdditionalInfo("maskType", "CUSTOM");
+                result.addAdditionalInfo("maskedValue", "hex({col})");
+            } else {
+                // Unable to mock other mask type
+                result.addAdditionalInfo("maskType", "");
+            }
+            return result;
+        }
+
+        private RangerAccessResult returnAccessResult(
+                RangerAccessRequest request, String ctl, String db, String tbl,
+                String col, String rs, String wg, String user) {
+            RangerAccessResult result = new RangerAccessResult(1, "test", 
null, request);
+            if (!Strings.isNullOrEmpty(wg)) {
+                result.setIsAllowed(wg.equals("wg1"));
+            } else if (!Strings.isNullOrEmpty(rs)) {
+                result.setIsAllowed(wg.equals("rs1"));
+            } else if (!Strings.isNullOrEmpty(col)) {
+                boolean res = ("ctl1".equals(ctl) && "db1".equals(db) && 
"tbl1".equals(tbl) && "col1".equals(col))
+                        || ("ctl1".equals(ctl) && "db1".equals(db) && 
"tbl1".equals(tbl) && "col2".equals(col));
+                result.setIsAllowed(res);
+            } else if (!Strings.isNullOrEmpty(tbl)) {
+                result.setIsAllowed("ctl2".equals(ctl) && "db2".equals(db) && 
"tbl2".equals(tbl));
+            } else if (!Strings.isNullOrEmpty(db)) {
+                result.setIsAllowed("ctl3".equals(ctl) && "db3".equals(db));
+            } else if (!Strings.isNullOrEmpty(ctl)) {
+                result.setIsAllowed("ctl4".equals(ctl));
+            } else {
+                result.setIsAllowed(false);
+            }
+            return result;
+        }
+    }
+
+    // Does not have priv on ctl1.db1.tbl1.col3
+    @Test(expected = AuthorizationException.class)
+    public void testNoAuthCol() throws AuthorizationException {
+        DorisTestPlugin plugin = new DorisTestPlugin("test");
+        RangerDorisAccessController ac = new 
RangerDorisAccessController(plugin);
+        UserIdentity ui = UserIdentity.createAnalyzedUserIdentWithIp("user1", 
"%");
+        Set<String> cols = Sets.newHashSet();
+        cols.add("col1");
+        cols.add("col3");
+        ac.checkColsPriv(ui, "ctl1", "db1", "tbl1", cols, 
PrivPredicate.SELECT);
+    }
+
+    // Have priv on ctl1.db1.tbl1.col1 & col2
+    @Test
+    public void testAuthCol() throws AuthorizationException {
+        DorisTestPlugin plugin = new DorisTestPlugin("test");
+        RangerDorisAccessController ac = new 
RangerDorisAccessController(plugin);
+        UserIdentity ui = UserIdentity.createAnalyzedUserIdentWithIp("user1", 
"%");
+        Set<String> cols = Sets.newHashSet();
+        cols.add("col1");
+        cols.add("col2");
+        ac.checkColsPriv(ui, "ctl1", "db1", "tbl1", cols, 
PrivPredicate.SELECT);
+    }
+
+    // Have priv on ctl2.db2.tbl2, so when checking auth on col1 & col2, can 
pass
+    @Test
+    public void testUsingTableAuthAsColAuth() throws AuthorizationException {
+        DorisTestPlugin plugin = new DorisTestPlugin("test");
+        RangerDorisAccessController ac = new 
RangerDorisAccessController(plugin);
+        UserIdentity ui = UserIdentity.createAnalyzedUserIdentWithIp("user1", 
"%");
+        Set<String> cols = Sets.newHashSet();
+        cols.add("col1");
+        cols.add("col2");
+        ac.checkColsPriv(ui, "ctl2", "db2", "tbl2", cols, 
PrivPredicate.SELECT);
+    }
+
+    // Does not have priv on ctl2.db2.tbl3, so when checking auth on col1 & 
col2, can not pass
+    @Test(expected = AuthorizationException.class)
+    public void testUsingNoTableAuthAsColAuth() throws AuthorizationException {
+        DorisTestPlugin plugin = new DorisTestPlugin("test");
+        RangerDorisAccessController ac = new 
RangerDorisAccessController(plugin);
+        UserIdentity ui = UserIdentity.createAnalyzedUserIdentWithIp("user1", 
"%");
+        Set<String> cols = Sets.newHashSet();
+        cols.add("col1");
+        cols.add("col2");
+        ac.checkColsPriv(ui, "ctl2", "db2", "tbl3", cols, 
PrivPredicate.SELECT);
+    }
+
+    // Have priv on ctl3.db3, so when checking auth on tbl1 and (tbl1.col1 & 
tbl1.col2), can pass
+    @Test
+    public void testUsingDbAuthAsColAndTableAuth() throws 
AuthorizationException {
+        DorisTestPlugin plugin = new DorisTestPlugin("test");
+        RangerDorisAccessController ac = new 
RangerDorisAccessController(plugin);
+        UserIdentity ui = UserIdentity.createAnalyzedUserIdentWithIp("user1", 
"%");
+        Set<String> cols = Sets.newHashSet();
+        cols.add("col1");
+        cols.add("col2");
+        ac.checkColsPriv(ui, "ctl3", "db3", "tbl1", cols, 
PrivPredicate.SELECT);
+        ac.checkTblPriv(ui, "ctl3", "db3", "tbl1", PrivPredicate.SELECT);
+    }
+
+
+    // Does not have priv on ctl2.db3, so when checking auth on col1 & col2, 
can not pass
+    @Test(expected = AuthorizationException.class)
+    public void testNoDbAuthAsColAndTableAuth() throws AuthorizationException {
+        DorisTestPlugin plugin = new DorisTestPlugin("test");
+        RangerDorisAccessController ac = new 
RangerDorisAccessController(plugin);
+        UserIdentity ui = UserIdentity.createAnalyzedUserIdentWithIp("user1", 
"%");
+        Set<String> cols = Sets.newHashSet();
+        cols.add("col1");
+        cols.add("col2");
+        ac.checkColsPriv(ui, "ctl2", "db3", "tbl3", cols, 
PrivPredicate.SELECT);
+    }
+
+    // Have priv on ctl4, so when checking auth on objs under ctl4, can pass
+    @Test
+    public void testUsingCtlAuthAsColAndTableAndDbAuth() throws 
AuthorizationException {
+        DorisTestPlugin plugin = new DorisTestPlugin("test");
+        RangerDorisAccessController ac = new 
RangerDorisAccessController(plugin);
+        UserIdentity ui = UserIdentity.createAnalyzedUserIdentWithIp("user1", 
"%");
+        Set<String> cols = Sets.newHashSet();
+        cols.add("col1");
+        cols.add("col2");
+        ac.checkColsPriv(ui, "ctl4", "db1", "tbl1", cols, 
PrivPredicate.SELECT);
+        ac.checkTblPriv(ui, "ctl4", "db2", "tbl2", PrivPredicate.SELECT);
+        ac.checkDbPriv(ui, "ctl4", "db3", PrivPredicate.SELECT);
+    }
+
+    @Test
+    public void testDataMask() {
+        DorisTestPlugin plugin = new DorisTestPlugin("test");
+        RangerDorisAccessController ac = new 
RangerDorisAccessController(plugin);
+        UserIdentity ui = UserIdentity.createAnalyzedUserIdentWithIp("user1", 
"%");
+        // MASK_NULL
+        Optional<DataMaskPolicy> policy = ac.evalDataMaskPolicy(ui, "ctl1", 
"db1", "tbl1", "col1");
+        Assertions.assertEquals("NULL", policy.get().getMaskTypeDef());
+        // MASK_NONE
+        policy = ac.evalDataMaskPolicy(ui, "ctl1", "db1", "tbl1", "col2");
+        Assertions.assertTrue(!policy.isPresent());
+        // CUSTOM
+        policy = ac.evalDataMaskPolicy(ui, "ctl1", "db1", "tbl1", "col3");
+        Assertions.assertEquals("hex(col3)", policy.get().getMaskTypeDef());
+        // Others
+        policy = ac.evalDataMaskPolicy(ui, "ctl1", "db1", "tbl1", "col4");
+        Assertions.assertTrue(!policy.isPresent());
+    }
+}


---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscr...@doris.apache.org
For additional commands, e-mail: commits-h...@doris.apache.org

Reply via email to