Skip to content

Commit

Permalink
[apache#5336]feat(auth-ranger): Remove MANAGED_BY_GRAVITINO limit and…
Browse files Browse the repository at this point in the history
… compatible for existing ranger policy
  • Loading branch information
theoryxu committed Nov 20, 2024
1 parent 306c0e8 commit ccca089
Show file tree
Hide file tree
Showing 2 changed files with 72 additions and 26 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -974,7 +974,23 @@ private void removePolicyByMetadataObject(List<String> metadataNames) {
.forEach(
policy -> {
try {
rangerClient.deletePolicy(policy.getId());
policy.setPolicyItems(
policy.getPolicyItems().stream()
.filter(rangerHelper::isNotGravitinoManagedPolicyItemAccess)
.collect(Collectors.toList()));
policy.setDenyPolicyItems(
policy.getDenyPolicyItems().stream()
.filter(rangerHelper::isNotGravitinoManagedPolicyItemAccess)
.collect(Collectors.toList()));
policy.setRowFilterPolicyItems(
policy.getRowFilterPolicyItems().stream()
.filter(rangerHelper::isNotGravitinoManagedPolicyItemAccess)
.collect(Collectors.toList()));
policy.setDataMaskPolicyItems(
policy.getDataMaskPolicyItems().stream()
.filter(rangerHelper::isNotGravitinoManagedPolicyItemAccess)
.collect(Collectors.toList()));
rangerClient.updatePolicy(policy.getId(), policy);
} catch (RangerServiceException e) {
LOG.error("Failed to rename the policy {}!", policy);
throw new RuntimeException(e);
Expand Down Expand Up @@ -1003,25 +1019,29 @@ private void updatePolicyByMetadataObject(
.forEach(
policy -> {
try {
// Update the policy name
String policyName = policy.getName();
List<String> policyNames = Lists.newArrayList(DOT_SPLITTER.splitToList(policyName));
Preconditions.checkArgument(
policyNames.size() >= oldMetadataNames.size(),
String.format("The policy name(%s) is invalid!", policyName));
int index = operationTypeIndex.get(operationType);
if (policyNames.get(index).equals(RangerHelper.RESOURCE_ALL)) {
// Doesn't need to rename the policy `*`
return;

// Update the policy name when the policy is managed by Gravitino
if (policy.getPolicyLabels().contains(RangerHelper.MANAGED_BY_GRAVITINO)) {
List<String> policyNames =
Lists.newArrayList(DOT_SPLITTER.splitToList(policyName));
Preconditions.checkArgument(
policyNames.size() >= oldMetadataNames.size(),
String.format("The policy name(%s) is invalid!", policyName));
if (policyNames.get(index).equals(RangerHelper.RESOURCE_ALL)) {
// Doesn't need to rename the policy `*`
return;
}
policyNames.set(index, newMetadataNames.get(index));
policy.setName(DOT_JOINER.join(policyNames));
}
policyNames.set(index, newMetadataNames.get(index));
// Update the policy resource name to new name
policy
.getResources()
.put(
rangerHelper.policyResourceDefines.get(index),
new RangerPolicy.RangerPolicyResource(newMetadataNames.get(index)));
policy.setName(DOT_JOINER.join(policyNames));

boolean alreadyExist =
existNewPolicies.stream()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,8 @@ public class RangerHelper {
public static final String GRAVITINO_METALAKE_OWNER_ROLE = "GRAVITINO_METALAKE_OWNER_ROLE";
public static final String GRAVITINO_CATALOG_OWNER_ROLE = "GRAVITINO_CATALOG_OWNER_ROLE";

public static final String GRAVITINO_ROLE_PREFIX = "GRAVITINO_";

public RangerHelper(
RangerClient rangerClient,
String rangerAdminName,
Expand Down Expand Up @@ -142,7 +144,7 @@ void addPolicyItem(RangerPolicy policy, String roleName, RangerSecurableObject s
new RangerPolicy.RangerPolicyItemAccess();
access.setType(rangerPrivilege.getName());
policyItem.getAccesses().add(access);
policyItem.getRoles().add(roleName);
policyItem.getRoles().add(GRAVITINO_ROLE_PREFIX + roleName);
if (Privilege.Condition.ALLOW == rangerPrivilege.condition()) {
policy.getPolicyItems().add(policyItem);
} else {
Expand All @@ -154,8 +156,8 @@ void addPolicyItem(RangerPolicy policy, String roleName, RangerSecurableObject s
.forEach(
policyItem -> {
// If the role is not in the policy item, then add it
if (!policyItem.getRoles().contains(roleName)) {
policyItem.getRoles().add(roleName);
if (!policyItem.getRoles().contains(GRAVITINO_ROLE_PREFIX + roleName)) {
policyItem.getRoles().add(GRAVITINO_ROLE_PREFIX + roleName);
}
});
}
Expand All @@ -172,7 +174,6 @@ public List<RangerPolicy> wildcardSearchPolies(List<String> metadataNames)
throws AuthorizationPluginException {
Map<String, String> searchFilters = new HashMap<>();
searchFilters.put(SearchFilter.SERVICE_NAME, rangerServiceName);
searchFilters.put(SearchFilter.POLICY_LABELS_PARTIAL, MANAGED_BY_GRAVITINO);
for (int i = 0; i < metadataNames.size(); i++) {
searchFilters.put(
SearchFilter.RESOURCE_PREFIX + policyResourceDefines.get(i), metadataNames.get(i));
Expand Down Expand Up @@ -224,8 +225,7 @@ public RangerPolicy findManagedPolicy(RangerMetadataObject rangerMetadataObject)
}
// Only return the policies that are managed by Gravitino.
if (policies.size() > 1) {
throw new AuthorizationPluginException(
"Every metadata object has only a Gravitino managed policy.");
throw new AuthorizationPluginException("Every metadata object has only a policy.");
}

if (policies.isEmpty()) {
Expand All @@ -234,15 +234,32 @@ public RangerPolicy findManagedPolicy(RangerMetadataObject rangerMetadataObject)

RangerPolicy policy = policies.get(0);
// Delegating Gravitino management policies cannot contain duplicate privilege
policy.getPolicyItems().forEach(this::checkPolicyItemAccess);
policy.getDenyPolicyItems().forEach(this::checkPolicyItemAccess);
policy.getRowFilterPolicyItems().forEach(this::checkPolicyItemAccess);
policy.getDataMaskPolicyItems().forEach(this::checkPolicyItemAccess);
policy.getPolicyItems().stream()
.filter(this::isGravitinoManagedPolicyItemAccess)
.forEach(this::checkPolicyItemAccess);
policy.getDenyPolicyItems().stream()
.filter(this::isGravitinoManagedPolicyItemAccess)
.forEach(this::checkPolicyItemAccess);
policy.getRowFilterPolicyItems().stream()
.filter(this::isGravitinoManagedPolicyItemAccess)
.forEach(this::checkPolicyItemAccess);
policy.getDataMaskPolicyItems().stream()
.filter(this::isGravitinoManagedPolicyItemAccess)
.forEach(this::checkPolicyItemAccess);

return policy;
}

boolean isGravitinoManagedPolicyItemAccess(RangerPolicy.RangerPolicyItem policyItem) {
return policyItem.getRoles().stream().anyMatch(role -> role.startsWith(GRAVITINO_ROLE_PREFIX));
}

boolean isNotGravitinoManagedPolicyItemAccess(RangerPolicy.RangerPolicyItem policyItem) {
return !isGravitinoManagedPolicyItemAccess(policyItem);
}

protected boolean checkRangerRole(String roleName) throws AuthorizationPluginException {
roleName = rangerRoleName(roleName);
try {
rangerClient.getRole(roleName, rangerAdminName, rangerServiceName);
} catch (RangerServiceException e) {
Expand All @@ -252,8 +269,16 @@ protected boolean checkRangerRole(String roleName) throws AuthorizationPluginExc
return true;
}

String rangerRoleName(String roleName) {
if (roleName.startsWith(GRAVITINO_ROLE_PREFIX)) {
return roleName;
}
return GRAVITINO_ROLE_PREFIX + roleName;
}

protected GrantRevokeRoleRequest createGrantRevokeRoleRequest(
String roleName, String userName, String groupName) {
roleName = rangerRoleName(roleName);
Set<String> users =
StringUtils.isEmpty(userName) ? Sets.newHashSet() : Sets.newHashSet(userName);
Set<String> groups =
Expand All @@ -278,6 +303,7 @@ protected GrantRevokeRoleRequest createGrantRevokeRoleRequest(
* @param isOwnerRole The role is owner role or not
*/
protected RangerRole createRangerRoleIfNotExists(String roleName, boolean isOwnerRole) {
roleName = rangerRoleName(roleName);
if (isOwnerRole) {
Preconditions.checkArgument(
roleName.equalsIgnoreCase(GRAVITINO_METALAKE_OWNER_ROLE)
Expand Down Expand Up @@ -428,7 +454,7 @@ protected RangerPolicy addOwnerRoleToNewPolicy(
policyItem
.getAccesses()
.add(new RangerPolicy.RangerPolicyItemAccess(ownerPrivilege.getName()));
policyItem.getRoles().add(ownerRoleName);
policyItem.getRoles().add(rangerRoleName(ownerRoleName));
policy.getPolicyItems().add(policyItem);
});
return policy;
Expand All @@ -454,8 +480,8 @@ protected void updatePolicyOwnerRole(RangerPolicy policy, String ownerRoleName)
// Add or remove the owner role in the policy item
matchPolicyItems.forEach(
policyItem -> {
if (!policyItem.getRoles().contains(ownerRoleName)) {
policyItem.getRoles().add(ownerRoleName);
if (!policyItem.getRoles().contains(rangerRoleName(ownerRoleName))) {
policyItem.getRoles().add(rangerRoleName(ownerRoleName));
}
});

Expand All @@ -480,8 +506,8 @@ protected void updatePolicyOwnerRole(RangerPolicy policy, String ownerRoleName)
policyItem
.getAccesses()
.add(new RangerPolicy.RangerPolicyItemAccess(ownerPrivilege.getName()));
if (!policyItem.getRoles().contains(ownerRoleName)) {
policyItem.getRoles().add(ownerRoleName);
if (!policyItem.getRoles().contains(rangerRoleName(ownerRoleName))) {
policyItem.getRoles().add(rangerRoleName(ownerRoleName));
}
policy.getPolicyItems().add(policyItem);
});
Expand Down

0 comments on commit ccca089

Please sign in to comment.