This is an automated email from the ASF dual-hosted git repository. morrysnow pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/doris.git
The following commit(s) were added to refs/heads/master by this push: new 2aa1734dd20 [enhance](auth)ranger support storage vault and compute group (#47925) 2aa1734dd20 is described below commit 2aa1734dd20ebf738414bcb7ff9ed28be47b6ce8 Author: zhangdong <zhangd...@selectdb.com> AuthorDate: Tue Apr 8 15:24:58 2025 +0800 [enhance](auth)ranger support storage vault and compute group (#47925) --- .../authorizer/ranger/doris/DorisAccessType.java | 2 ++ .../authorizer/ranger/doris/DorisObjectType.java | 2 +- .../ranger/doris/RangerDorisAccessController.java | 30 ++++++++++++++++++-- .../ranger/doris/RangerDorisResource.java | 8 ++++++ .../apache/doris/mysql/privilege/RangerTest.java | 33 ++++++++++++++++++++-- 5 files changed, 70 insertions(+), 5 deletions(-) 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 77d7bfefc23..68a926f39cb 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 @@ -51,6 +51,8 @@ public enum DorisAccessType { case DROP_PRIV: return DROP; case USAGE_PRIV: + case STAGE_USAGE_PRIV: + case CLUSTER_USAGE_PRIV: return USAGE; case SHOW_VIEW_PRIV: return SHOW_VIEW; diff --git a/fe/fe-core/src/main/java/org/apache/doris/catalog/authorizer/ranger/doris/DorisObjectType.java b/fe/fe-core/src/main/java/org/apache/doris/catalog/authorizer/ranger/doris/DorisObjectType.java index cafff6bd6e1..334098aeb49 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/catalog/authorizer/ranger/doris/DorisObjectType.java +++ b/fe/fe-core/src/main/java/org/apache/doris/catalog/authorizer/ranger/doris/DorisObjectType.java @@ -18,5 +18,5 @@ package org.apache.doris.catalog.authorizer.ranger.doris; public enum DorisObjectType { - NONE, CATALOG, DATABASE, TABLE, COLUMN, RESOURCE, WORKLOAD_GROUP, GLOBAL + NONE, CATALOG, DATABASE, TABLE, COLUMN, RESOURCE, WORKLOAD_GROUP, GLOBAL, COMPUTE_GROUP, STORAGE_VAULT } 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 f9f571c0d0d..9ed9daa08f8 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 @@ -245,12 +245,38 @@ public class RangerDorisAccessController extends RangerAccessController { @Override public boolean checkCloudPriv(UserIdentity currentUser, String cloudName, PrivPredicate wanted, ResourceTypeEnum type) { - return false; + // only support CLUSTER, + // STORAGE_VAULT should call `checkStorageVaultPriv` + // GENERAL should call `checkResourcePriv` + // STAGE is used to support `copy into`, but this feature will soon expire, + // so it is no longer supported through Ranger + if (!ResourceTypeEnum.CLUSTER.equals(type)) { + return false; + } + PrivBitSet checkedPrivs = PrivBitSet.of(); + return checkGlobalPrivInternal(currentUser, wanted, checkedPrivs) + || checkComputeGroupPrivInternal(currentUser, cloudName, wanted, checkedPrivs); + } + + private boolean checkComputeGroupPrivInternal(UserIdentity currentUser, String computeGroupName, + PrivPredicate wanted, + PrivBitSet checkedPrivs) { + RangerDorisResource resource = new RangerDorisResource(DorisObjectType.COMPUTE_GROUP, computeGroupName); + return checkPrivilege(currentUser, wanted, resource, checkedPrivs); } @Override public boolean checkStorageVaultPriv(UserIdentity currentUser, String storageVaultName, PrivPredicate wanted) { - return false; + PrivBitSet checkedPrivs = PrivBitSet.of(); + return checkGlobalPrivInternal(currentUser, wanted, checkedPrivs) + || checkStorageVaultPrivInternal(currentUser, storageVaultName, wanted, checkedPrivs); + } + + private boolean checkStorageVaultPrivInternal(UserIdentity currentUser, String storageVaultName, + PrivPredicate wanted, + PrivBitSet checkedPrivs) { + RangerDorisResource resource = new RangerDorisResource(DorisObjectType.STORAGE_VAULT, storageVaultName); + return checkPrivilege(currentUser, wanted, resource, checkedPrivs); } @Override diff --git a/fe/fe-core/src/main/java/org/apache/doris/catalog/authorizer/ranger/doris/RangerDorisResource.java b/fe/fe-core/src/main/java/org/apache/doris/catalog/authorizer/ranger/doris/RangerDorisResource.java index db173a25354..672c06ec281 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/catalog/authorizer/ranger/doris/RangerDorisResource.java +++ b/fe/fe-core/src/main/java/org/apache/doris/catalog/authorizer/ranger/doris/RangerDorisResource.java @@ -27,6 +27,8 @@ public class RangerDorisResource extends RangerAccessResourceImpl { public static final String KEY_COLUMN = "column"; public static final String KEY_RESOURCE = "resource"; public static final String KEY_WORKLOAD_GROUP = "workload_group"; + public static final String KEY_COMPUTE_GROUP = "compute_group"; + public static final String KEY_STORAGE_VAULT = "storage_vault"; // FirstLevelResource => Catalog / Resource / WorkloadGroup / GLOBAL // SecondLevelResource => Database @@ -76,6 +78,12 @@ public class RangerDorisResource extends RangerAccessResourceImpl { case WORKLOAD_GROUP: setValue(KEY_WORKLOAD_GROUP, firstLevelResource); break; + case STORAGE_VAULT: + setValue(KEY_STORAGE_VAULT, firstLevelResource); + break; + case COMPUTE_GROUP: + setValue(KEY_COMPUTE_GROUP, firstLevelResource); + break; case NONE: default: break; 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 index a0f0ef0f2d1..e0e1dd36b2a 100644 --- 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 @@ -17,6 +17,7 @@ package org.apache.doris.mysql.privilege; +import org.apache.doris.analysis.ResourceTypeEnum; import org.apache.doris.analysis.UserIdentity; import org.apache.doris.catalog.authorizer.ranger.doris.RangerDorisAccessController; import org.apache.doris.catalog.authorizer.ranger.doris.RangerDorisResource; @@ -67,8 +68,10 @@ public class RangerTest { 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 cg = (String) resource.getValue(RangerDorisResource.KEY_COMPUTE_GROUP); + String sv = (String) resource.getValue(RangerDorisResource.KEY_STORAGE_VAULT); String user = request.getUser(); - return returnAccessResult(request, ctl, db, tbl, col, rs, wg, user); + return returnAccessResult(request, ctl, db, tbl, col, rs, wg, cg, sv, user); } @Override @@ -98,7 +101,7 @@ public class RangerTest { private RangerAccessResult returnAccessResult( RangerAccessRequest request, String ctl, String db, String tbl, - String col, String rs, String wg, String user) { + String col, String rs, String wg, String cg, String sv, String user) { RangerAccessResult result = new RangerAccessResult(1, "test", null, request); if (!Strings.isNullOrEmpty(wg)) { result.setIsAllowed(wg.equals("wg1")); @@ -114,6 +117,10 @@ public class RangerTest { result.setIsAllowed("ctl3".equals(ctl) && "db3".equals(db)); } else if (!Strings.isNullOrEmpty(ctl)) { result.setIsAllowed("ctl4".equals(ctl)); + } else if (!Strings.isNullOrEmpty(cg)) { + result.setIsAllowed("cg1".equals(cg)); + } else if (!Strings.isNullOrEmpty(sv)) { + result.setIsAllowed("sv1".equals(sv)); } else { result.setIsAllowed(false); } @@ -227,4 +234,26 @@ public class RangerTest { policy = ac.evalDataMaskPolicy(ui, "ctl1", "db1", "tbl1", "col4"); Assertions.assertTrue(!policy.isPresent()); } + + @Test + public void testComputeGroupAuth() { + DorisTestPlugin plugin = new DorisTestPlugin("test"); + RangerDorisAccessController ac = new RangerDorisAccessController(plugin); + UserIdentity ui = UserIdentity.createAnalyzedUserIdentWithIp("user1", "%"); + boolean cg1 = ac.checkCloudPriv(ui, "cg1", PrivPredicate.USAGE, ResourceTypeEnum.CLUSTER); + Assertions.assertTrue(cg1); + boolean cg2 = ac.checkCloudPriv(ui, "cg2", PrivPredicate.USAGE, ResourceTypeEnum.CLUSTER); + Assertions.assertFalse(cg2); + } + + @Test + public void testStorageVaultAuth() { + DorisTestPlugin plugin = new DorisTestPlugin("test"); + RangerDorisAccessController ac = new RangerDorisAccessController(plugin); + UserIdentity ui = UserIdentity.createAnalyzedUserIdentWithIp("user1", "%"); + boolean cg1 = ac.checkStorageVaultPriv(ui, "sv1", PrivPredicate.USAGE); + Assertions.assertTrue(cg1); + boolean cg2 = ac.checkStorageVaultPriv(ui, "sv2", PrivPredicate.USAGE); + Assertions.assertFalse(cg2); + } } --------------------------------------------------------------------- To unsubscribe, e-mail: commits-unsubscr...@doris.apache.org For additional commands, e-mail: commits-h...@doris.apache.org