Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,8 @@ public static DorisAccessType toAccessType(Privilege privilege) {
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;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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
}
Original file line number Diff line number Diff line change
Expand Up @@ -260,12 +260,38 @@ private boolean checkColPrivInternal(UserIdentity currentUser, String ctl, Strin
@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
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -76,6 +78,12 @@ public RangerDorisResource(DorisObjectType objectType, String firstLevelResource
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;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -67,8 +68,10 @@ public RangerAccessResult isAccessAllowed(RangerAccessRequest request) {
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
Expand Down Expand Up @@ -98,7 +101,7 @@ public RangerAccessResult evalDataMaskPolicies(RangerAccessRequest request,

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"));
Expand All @@ -114,6 +117,10 @@ private RangerAccessResult returnAccessResult(
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);
}
Expand Down Expand Up @@ -227,4 +234,26 @@ public void testDataMask() {
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);
}
}