This is an automated email from the ASF dual-hosted git repository. liuxun pushed a commit to branch main in repository https://gitbox.apache.org/repos/asf/gravitino.git
The following commit(s) were added to refs/heads/main by this push: new b953226ab [#5665] refactor(auth): Underlying datasource authorization privilege abstraction (#5674) b953226ab is described below commit b953226ab5fc5d15bcb2c075f1e292139f62e50c Author: Xun <x...@datastrato.com> AuthorDate: Wed Nov 27 20:49:02 2024 +0800 [#5665] refactor(auth): Underlying datasource authorization privilege abstraction (#5674) ### What changes were proposed in this pull request? 1. abstract AuthorizationMetadataObject interface 2. abstract AuthorizationPrivilege interface 3. abstract AuthorizationSecurableObject interface 4. abstract AuthorizationPrivilegesMappingProvider interface ### Why are the changes needed? Fix: #5665 ### Does this PR introduce _any_ user-facing change? N/A ### How was this patch tested? CI Passed. --- .../ranger/RangerAuthorizationHadoopSQLPlugin.java | 140 ++++++------- .../ranger/RangerAuthorizationPlugin.java | 229 ++++++++++++--------- .../authorization/ranger/RangerHelper.java | 25 ++- .../authorization/ranger/RangerMetadataObject.java | 138 ++++++++----- .../ranger/RangerMetadataObjects.java | 125 ----------- .../authorization/ranger/RangerPrivileges.java | 23 ++- .../ranger/RangerPrivilegesMappingProvider.java | 92 --------- .../ranger/RangerSecurableObject.java | 43 ++-- .../ranger/RangerSecurableObjects.java | 55 ----- .../test/RangerAuthorizationPluginIT.java | 29 +-- .../ranger/integration/test/RangerHiveIT.java | 21 +- .../ranger/integration/test/RangerITEnv.java | 4 +- .../authorization/AuthorizationMetadataObject.java | 79 +++---- .../authorization/AuthorizationPrivilege.java | 8 +- .../AuthorizationPrivilegesMappingProvider.java | 83 ++++++++ .../AuthorizationSecurableObject.java | 21 +- 16 files changed, 504 insertions(+), 611 deletions(-) diff --git a/authorizations/authorization-ranger/src/main/java/org/apache/gravitino/authorization/ranger/RangerAuthorizationHadoopSQLPlugin.java b/authorizations/authorization-ranger/src/main/java/org/apache/gravitino/authorization/ranger/RangerAuthorizationHadoopSQLPlugin.java index 9ad2a8c1e..d403d4469 100644 --- a/authorizations/authorization-ranger/src/main/java/org/apache/gravitino/authorization/ranger/RangerAuthorizationHadoopSQLPlugin.java +++ b/authorizations/authorization-ranger/src/main/java/org/apache/gravitino/authorization/ranger/RangerAuthorizationHadoopSQLPlugin.java @@ -32,6 +32,9 @@ import java.util.Set; import java.util.stream.Collectors; import java.util.stream.Stream; import org.apache.gravitino.MetadataObject; +import org.apache.gravitino.authorization.AuthorizationMetadataObject; +import org.apache.gravitino.authorization.AuthorizationPrivilege; +import org.apache.gravitino.authorization.AuthorizationSecurableObject; import org.apache.gravitino.authorization.Privilege; import org.apache.gravitino.authorization.SecurableObject; import org.apache.gravitino.authorization.SecurableObjects; @@ -62,38 +65,9 @@ public class RangerAuthorizationHadoopSQLPlugin extends RangerAuthorizationPlugi return instance; } - /** Validate different Ranger metadata object */ - @Override - public void validateRangerMetadataObject(List<String> names, RangerMetadataObject.Type type) - throws IllegalArgumentException { - Preconditions.checkArgument( - names != null && !names.isEmpty(), "Cannot create a Ranger metadata object with no names"); - Preconditions.checkArgument( - names.size() <= 3, - "Cannot create a Ranger metadata object with the name length which is greater than 3"); - Preconditions.checkArgument( - type != null, "Cannot create a Ranger metadata object with no type"); - - Preconditions.checkArgument( - names.size() != 1 || type == RangerMetadataObject.Type.SCHEMA, - "If the length of names is 1, it must be the SCHEMA type"); - - Preconditions.checkArgument( - names.size() != 2 || type == RangerMetadataObject.Type.TABLE, - "If the length of names is 2, it must be the TABLE type"); - - Preconditions.checkArgument( - names.size() != 3 || type == RangerMetadataObject.Type.COLUMN, - "If the length of names is 3, it must be COLUMN"); - - for (String name : names) { - RangerMetadataObjects.checkName(name); - } - } - @Override /** Set the default mapping Gravitino privilege name to the Ranger rule */ - public Map<Privilege.Name, Set<RangerPrivilege>> privilegesMappingRule() { + public Map<Privilege.Name, Set<AuthorizationPrivilege>> privilegesMappingRule() { return ImmutableMap.of( Privilege.Name.CREATE_CATALOG, ImmutableSet.of(RangerHadoopSQLPrivilege.CREATE), @@ -116,7 +90,7 @@ public class RangerAuthorizationHadoopSQLPlugin extends RangerAuthorizationPlugi @Override /** Set the default owner rule. */ - public Set<RangerPrivilege> ownerMappingRule() { + public Set<AuthorizationPrivilege> ownerMappingRule() { return ImmutableSet.of(RangerHadoopSQLPrivilege.ALL); } @@ -145,7 +119,7 @@ public class RangerAuthorizationHadoopSQLPlugin extends RangerAuthorizationPlugi /** * Allow Gravitino MetadataObject type defines rule. * - * @return The allow Gravitino MetadataObject type defines rule. + * @return To allow Gravitino MetadataObject type defines rule. */ @Override public Set<MetadataObject.Type> allowMetadataObjectTypesRule() { @@ -159,27 +133,27 @@ public class RangerAuthorizationHadoopSQLPlugin extends RangerAuthorizationPlugi /** Translate the Gravitino securable object to the Ranger owner securable object. */ @Override - public List<RangerSecurableObject> translateOwner(MetadataObject gravitinoMetadataObject) { - List<RangerSecurableObject> rangerSecurableObjects = new ArrayList<>(); + public List<AuthorizationSecurableObject> translateOwner(MetadataObject gravitinoMetadataObject) { + List<AuthorizationSecurableObject> AuthorizationSecurableObjects = new ArrayList<>(); switch (gravitinoMetadataObject.type()) { case METALAKE: case CATALOG: // Add `*` for the SCHEMA permission - rangerSecurableObjects.add( - generateRangerSecurableObject( + AuthorizationSecurableObjects.add( + generateAuthorizationSecurableObject( ImmutableList.of(RangerHelper.RESOURCE_ALL), RangerMetadataObject.Type.SCHEMA, ownerMappingRule())); // Add `*.*` for the TABLE permission - rangerSecurableObjects.add( - generateRangerSecurableObject( + AuthorizationSecurableObjects.add( + generateAuthorizationSecurableObject( ImmutableList.of(RangerHelper.RESOURCE_ALL, RangerHelper.RESOURCE_ALL), RangerMetadataObject.Type.TABLE, ownerMappingRule())); // Add `*.*.*` for the COLUMN permission - rangerSecurableObjects.add( - generateRangerSecurableObject( + AuthorizationSecurableObjects.add( + generateAuthorizationSecurableObject( ImmutableList.of( RangerHelper.RESOURCE_ALL, RangerHelper.RESOURCE_ALL, @@ -189,21 +163,21 @@ public class RangerAuthorizationHadoopSQLPlugin extends RangerAuthorizationPlugi break; case SCHEMA: // Add `{schema}` for the SCHEMA permission - rangerSecurableObjects.add( - generateRangerSecurableObject( + AuthorizationSecurableObjects.add( + generateAuthorizationSecurableObject( ImmutableList.of(gravitinoMetadataObject.name() /*Schema name*/), RangerMetadataObject.Type.SCHEMA, ownerMappingRule())); // Add `{schema}.*` for the TABLE permission - rangerSecurableObjects.add( - generateRangerSecurableObject( + AuthorizationSecurableObjects.add( + generateAuthorizationSecurableObject( ImmutableList.of( gravitinoMetadataObject.name() /*Schema name*/, RangerHelper.RESOURCE_ALL), RangerMetadataObject.Type.TABLE, ownerMappingRule())); // Add `{schema}.*.*` for the COLUMN permission - rangerSecurableObjects.add( - generateRangerSecurableObject( + AuthorizationSecurableObjects.add( + generateAuthorizationSecurableObject( ImmutableList.of( gravitinoMetadataObject.name() /*Schema name*/, RangerHelper.RESOURCE_ALL, @@ -213,14 +187,14 @@ public class RangerAuthorizationHadoopSQLPlugin extends RangerAuthorizationPlugi break; case TABLE: // Add `{schema}.{table}` for the TABLE permission - rangerSecurableObjects.add( - generateRangerSecurableObject( + AuthorizationSecurableObjects.add( + generateAuthorizationSecurableObject( translateMetadataObject(gravitinoMetadataObject).names(), RangerMetadataObject.Type.TABLE, ownerMappingRule())); // Add `{schema}.{table}.*` for the COLUMN permission - rangerSecurableObjects.add( - generateRangerSecurableObject( + AuthorizationSecurableObjects.add( + generateAuthorizationSecurableObject( Stream.concat( translateMetadataObject(gravitinoMetadataObject).names().stream(), Stream.of(RangerHelper.RESOURCE_ALL)) @@ -234,19 +208,19 @@ public class RangerAuthorizationHadoopSQLPlugin extends RangerAuthorizationPlugi gravitinoMetadataObject.type()); } - return rangerSecurableObjects; + return AuthorizationSecurableObjects; } /** Translate the Gravitino securable object to the Ranger securable object. */ @Override - public List<RangerSecurableObject> translatePrivilege(SecurableObject securableObject) { - List<RangerSecurableObject> rangerSecurableObjects = new ArrayList<>(); + public List<AuthorizationSecurableObject> translatePrivilege(SecurableObject securableObject) { + List<AuthorizationSecurableObject> AuthorizationSecurableObjects = new ArrayList<>(); securableObject.privileges().stream() .filter(Objects::nonNull) .forEach( gravitinoPrivilege -> { - Set<RangerPrivilege> rangerPrivileges = new HashSet<>(); + Set<AuthorizationPrivilege> rangerPrivileges = new HashSet<>(); // Ignore unsupported privileges if (!privilegesMappingRule().containsKey(gravitinoPrivilege.name())) { return; @@ -268,8 +242,8 @@ public class RangerAuthorizationHadoopSQLPlugin extends RangerAuthorizationPlugi case METALAKE: case CATALOG: // Add Ranger privilege(`SELECT`) to SCHEMA(`*`) - rangerSecurableObjects.add( - generateRangerSecurableObject( + AuthorizationSecurableObjects.add( + generateAuthorizationSecurableObject( ImmutableList.of(RangerHelper.RESOURCE_ALL), RangerMetadataObject.Type.SCHEMA, rangerPrivileges)); @@ -285,8 +259,8 @@ public class RangerAuthorizationHadoopSQLPlugin extends RangerAuthorizationPlugi case METALAKE: case CATALOG: // Add Ranger privilege(`CREATE`) to SCHEMA(`*`) - rangerSecurableObjects.add( - generateRangerSecurableObject( + AuthorizationSecurableObjects.add( + generateAuthorizationSecurableObject( ImmutableList.of(RangerHelper.RESOURCE_ALL), RangerMetadataObject.Type.SCHEMA, rangerPrivileges)); @@ -302,16 +276,16 @@ public class RangerAuthorizationHadoopSQLPlugin extends RangerAuthorizationPlugi case METALAKE: case CATALOG: // Add Ranger privilege(`SELECT`) to SCHEMA(`*`) - rangerSecurableObjects.add( - generateRangerSecurableObject( + AuthorizationSecurableObjects.add( + generateAuthorizationSecurableObject( ImmutableList.of(RangerHelper.RESOURCE_ALL), RangerMetadataObject.Type.SCHEMA, rangerPrivileges)); break; case SCHEMA: // Add Ranger privilege(`SELECT`) to SCHEMA(`{schema}`) - rangerSecurableObjects.add( - generateRangerSecurableObject( + AuthorizationSecurableObjects.add( + generateAuthorizationSecurableObject( ImmutableList.of(securableObject.name() /*Schema name*/), RangerMetadataObject.Type.SCHEMA, rangerPrivileges)); @@ -329,15 +303,15 @@ public class RangerAuthorizationHadoopSQLPlugin extends RangerAuthorizationPlugi case METALAKE: case CATALOG: // Add `*.*` for the TABLE permission - rangerSecurableObjects.add( - generateRangerSecurableObject( + AuthorizationSecurableObjects.add( + generateAuthorizationSecurableObject( ImmutableList.of( RangerHelper.RESOURCE_ALL, RangerHelper.RESOURCE_ALL), RangerMetadataObject.Type.TABLE, rangerPrivileges)); // Add `*.*.*` for the COLUMN permission - rangerSecurableObjects.add( - generateRangerSecurableObject( + AuthorizationSecurableObjects.add( + generateAuthorizationSecurableObject( ImmutableList.of( RangerHelper.RESOURCE_ALL, RangerHelper.RESOURCE_ALL, @@ -347,16 +321,16 @@ public class RangerAuthorizationHadoopSQLPlugin extends RangerAuthorizationPlugi break; case SCHEMA: // Add `{schema}.*` for the TABLE permission - rangerSecurableObjects.add( - generateRangerSecurableObject( + AuthorizationSecurableObjects.add( + generateAuthorizationSecurableObject( ImmutableList.of( securableObject.name() /*Schema name*/, RangerHelper.RESOURCE_ALL), RangerMetadataObject.Type.TABLE, rangerPrivileges)); // Add `{schema}.*.*` for the COLUMN permission - rangerSecurableObjects.add( - generateRangerSecurableObject( + AuthorizationSecurableObjects.add( + generateAuthorizationSecurableObject( ImmutableList.of( securableObject.name() /*Schema name*/, RangerHelper.RESOURCE_ALL, @@ -371,14 +345,14 @@ public class RangerAuthorizationHadoopSQLPlugin extends RangerAuthorizationPlugi gravitinoPrivilege.name(), securableObject.type()); } else { // Add `{schema}.{table}` for the TABLE permission - rangerSecurableObjects.add( - generateRangerSecurableObject( + AuthorizationSecurableObjects.add( + generateAuthorizationSecurableObject( translateMetadataObject(securableObject).names(), RangerMetadataObject.Type.TABLE, rangerPrivileges)); // Add `{schema}.{table}.*` for the COLUMN permission - rangerSecurableObjects.add( - generateRangerSecurableObject( + AuthorizationSecurableObjects.add( + generateAuthorizationSecurableObject( Stream.concat( translateMetadataObject(securableObject).names().stream(), Stream.of(RangerHelper.RESOURCE_ALL)) @@ -402,7 +376,7 @@ public class RangerAuthorizationHadoopSQLPlugin extends RangerAuthorizationPlugi } }); - return rangerSecurableObjects; + return AuthorizationSecurableObjects; } /** @@ -410,7 +384,7 @@ public class RangerAuthorizationHadoopSQLPlugin extends RangerAuthorizationPlugi * convert the Gravitino metadata object to the Ranger metadata object. */ @Override - public RangerMetadataObject translateMetadataObject(MetadataObject metadataObject) { + public AuthorizationMetadataObject translateMetadataObject(MetadataObject metadataObject) { Preconditions.checkArgument( allowMetadataObjectTypesRule().contains(metadataObject.type()), String.format( @@ -424,7 +398,7 @@ public class RangerAuthorizationHadoopSQLPlugin extends RangerAuthorizationPlugi Preconditions.checkArgument( nsMetadataObject.size() > 0, "The metadata object must have at least one name."); - RangerMetadataObject.Type type; + AuthorizationMetadataObject.Type type; if (metadataObject.type() == MetadataObject.Type.METALAKE || metadataObject.type() == MetadataObject.Type.CATALOG) { nsMetadataObject.clear(); @@ -435,10 +409,12 @@ public class RangerAuthorizationHadoopSQLPlugin extends RangerAuthorizationPlugi type = RangerMetadataObject.Type.fromMetadataType(metadataObject.type()); } - validateRangerMetadataObject(nsMetadataObject, type); - return new RangerMetadataObjects.RangerMetadataObjectImpl( - RangerMetadataObjects.getParentFullName(nsMetadataObject), - RangerMetadataObjects.getLastName(nsMetadataObject), - type); + RangerMetadataObject rangerMetadataObject = + new RangerMetadataObject( + AuthorizationMetadataObject.getParentFullName(nsMetadataObject), + AuthorizationMetadataObject.getLastName(nsMetadataObject), + type); + rangerMetadataObject.validateAuthorizationMetadataObject(); + return rangerMetadataObject; } } diff --git a/authorizations/authorization-ranger/src/main/java/org/apache/gravitino/authorization/ranger/RangerAuthorizationPlugin.java b/authorizations/authorization-ranger/src/main/java/org/apache/gravitino/authorization/ranger/RangerAuthorizationPlugin.java index 1b2c924d2..b522691cb 100644 --- a/authorizations/authorization-ranger/src/main/java/org/apache/gravitino/authorization/ranger/RangerAuthorizationPlugin.java +++ b/authorizations/authorization-ranger/src/main/java/org/apache/gravitino/authorization/ranger/RangerAuthorizationPlugin.java @@ -18,9 +18,6 @@ */ package org.apache.gravitino.authorization.ranger; -import static org.apache.gravitino.authorization.ranger.RangerMetadataObjects.DOT_JOINER; -import static org.apache.gravitino.authorization.ranger.RangerMetadataObjects.DOT_SPLITTER; - import com.google.common.annotations.VisibleForTesting; import com.google.common.base.Preconditions; import com.google.common.collect.ImmutableList; @@ -39,6 +36,10 @@ import java.util.concurrent.atomic.AtomicBoolean; import java.util.stream.Collectors; import java.util.stream.Stream; import org.apache.gravitino.MetadataObject; +import org.apache.gravitino.authorization.AuthorizationMetadataObject; +import org.apache.gravitino.authorization.AuthorizationPrivilege; +import org.apache.gravitino.authorization.AuthorizationPrivilegesMappingProvider; +import org.apache.gravitino.authorization.AuthorizationSecurableObject; import org.apache.gravitino.authorization.Group; import org.apache.gravitino.authorization.MetadataObjectChange; import org.apache.gravitino.authorization.Owner; @@ -76,7 +77,7 @@ import org.slf4j.LoggerFactory; * implement Gravitino Owner concept. <br> */ public abstract class RangerAuthorizationPlugin - implements AuthorizationPlugin, RangerPrivilegesMappingProvider, RangerMetadataObjectRule { + implements AuthorizationPlugin, AuthorizationPrivilegesMappingProvider { private static final Logger LOG = LoggerFactory.getLogger(RangerAuthorizationPlugin.class); protected final String rangerServiceName; @@ -107,6 +108,13 @@ public abstract class RangerAuthorizationPlugin policyResourceDefinesRule()); } + /** + * Set the Ranger policy resource defines rule. + * + * @return The policy resource defines rule. + */ + public abstract List<String> policyResourceDefinesRule(); + /** * Create a new role in the Ranger. <br> * 1. Create a policy for metadata object. <br> @@ -168,11 +176,12 @@ public abstract class RangerAuthorizationPlugin return false; } - List<RangerSecurableObject> rangerSecurableObjects = translatePrivilege(securableObject); - rangerSecurableObjects.stream() + List<AuthorizationSecurableObject> AuthorizationSecurableObjects = + translatePrivilege(securableObject); + AuthorizationSecurableObjects.stream() .forEach( - rangerSecurableObject -> { - if (!doAddSecurableObject(role.name(), rangerSecurableObject)) { + AuthorizationSecurableObject -> { + if (!doAddSecurableObject(role.name(), AuthorizationSecurableObject)) { throw new AuthorizationPluginException( "Failed to add the securable object to the Ranger policy!"); } @@ -184,11 +193,12 @@ public abstract class RangerAuthorizationPlugin return false; } - List<RangerSecurableObject> rangerSecurableObjects = translatePrivilege(securableObject); - rangerSecurableObjects.stream() + List<AuthorizationSecurableObject> AuthorizationSecurableObjects = + translatePrivilege(securableObject); + AuthorizationSecurableObjects.stream() .forEach( - rangerSecurableObject -> { - if (!doRemoveSecurableObject(role.name(), rangerSecurableObject)) { + AuthorizationSecurableObject -> { + if (!doRemoveSecurableObject(role.name(), AuthorizationSecurableObject)) { throw new AuthorizationPluginException( "Failed to add the securable object to the Ranger policy!"); } @@ -209,19 +219,19 @@ public abstract class RangerAuthorizationPlugin (oldSecurableObject.fullName().equals(newSecurableObject.fullName()) && oldSecurableObject.type().equals(newSecurableObject.type())), "The old and new securable objects metadata must be equal!"); - List<RangerSecurableObject> rangerOldSecurableObjects = + List<AuthorizationSecurableObject> rangerOldSecurableObjects = translatePrivilege(oldSecurableObject); - List<RangerSecurableObject> rangerNewSecurableObjects = + List<AuthorizationSecurableObject> rangerNewSecurableObjects = translatePrivilege(newSecurableObject); rangerOldSecurableObjects.stream() .forEach( - rangerSecurableObject -> { - doRemoveSecurableObject(role.name(), rangerSecurableObject); + AuthorizationSecurableObject -> { + doRemoveSecurableObject(role.name(), AuthorizationSecurableObject); }); rangerNewSecurableObjects.stream() .forEach( - rangerSecurableObject -> { - doAddSecurableObject(role.name(), rangerSecurableObject); + AuthorizationSecurableObject -> { + doAddSecurableObject(role.name(), AuthorizationSecurableObject); }); } else { throw new IllegalArgumentException( @@ -241,21 +251,24 @@ public abstract class RangerAuthorizationPlugin ((MetadataObjectChange.RenameMetadataObject) change).metadataObject(); MetadataObject newMetadataObject = ((MetadataObjectChange.RenameMetadataObject) change).newMetadataObject(); - RangerMetadataObject rangerMetadataObject = translateMetadataObject(metadataObject); - RangerMetadataObject newRangerMetadataObject = translateMetadataObject(newMetadataObject); - if (rangerMetadataObject.equals(newRangerMetadataObject)) { + AuthorizationMetadataObject AuthorizationMetadataObject = + translateMetadataObject(metadataObject); + AuthorizationMetadataObject newAuthorizationMetadataObject = + translateMetadataObject(newMetadataObject); + if (AuthorizationMetadataObject.equals(newAuthorizationMetadataObject)) { LOG.info( "The metadata object({}) and new metadata object({}) are equal, so ignore rename!", - rangerMetadataObject.fullName(), - newRangerMetadataObject.fullName()); + AuthorizationMetadataObject.fullName(), + newAuthorizationMetadataObject.fullName()); continue; } - doRenameMetadataObject(rangerMetadataObject, newRangerMetadataObject); + doRenameMetadataObject(AuthorizationMetadataObject, newAuthorizationMetadataObject); } else if (change instanceof MetadataObjectChange.RemoveMetadataObject) { MetadataObject metadataObject = ((MetadataObjectChange.RemoveMetadataObject) change).metadataObject(); - RangerMetadataObject rangerMetadataObject = translateMetadataObject(metadataObject); - doRemoveMetadataObject(rangerMetadataObject); + AuthorizationMetadataObject AuthorizationMetadataObject = + translateMetadataObject(metadataObject); + doRemoveMetadataObject(AuthorizationMetadataObject); } else { throw new IllegalArgumentException( "Unsupported metadata object change type: " @@ -322,7 +335,8 @@ public abstract class RangerAuthorizationPlugin onGroupAdded(groupEntity); } - List<RangerSecurableObject> rangerSecurableObjects = translateOwner(metadataObject); + List<AuthorizationSecurableObject> AuthorizationSecurableObjects = + translateOwner(metadataObject); String ownerRoleName; switch (metadataObject.type()) { case METALAKE: @@ -353,15 +367,16 @@ public abstract class RangerAuthorizationPlugin LOG.warn("Grant owner role: {} failed!", ownerRoleName, e); } - rangerSecurableObjects.stream() + AuthorizationSecurableObjects.stream() .forEach( - rangerSecurableObject -> { - RangerPolicy policy = rangerHelper.findManagedPolicy(rangerSecurableObject); + AuthorizationSecurableObject -> { + RangerPolicy policy = + rangerHelper.findManagedPolicy(AuthorizationSecurableObject); try { if (policy == null) { policy = rangerHelper.addOwnerRoleToNewPolicy( - rangerSecurableObject, ownerRoleName); + AuthorizationSecurableObject, ownerRoleName); rangerClient.createPolicy(policy); } else { rangerHelper.updatePolicyOwnerRole(policy, ownerRoleName); @@ -376,13 +391,15 @@ public abstract class RangerAuthorizationPlugin case SCHEMA: case TABLE: // The schema and table use user/group to manage the owner - rangerSecurableObjects.stream() + AuthorizationSecurableObjects.stream() .forEach( - rangerSecurableObject -> { - RangerPolicy policy = rangerHelper.findManagedPolicy(rangerSecurableObject); + AuthorizationSecurableObject -> { + RangerPolicy policy = + rangerHelper.findManagedPolicy(AuthorizationSecurableObject); try { if (policy == null) { - policy = rangerHelper.addOwnerToNewPolicy(rangerSecurableObject, newOwner); + policy = + rangerHelper.addOwnerToNewPolicy(AuthorizationSecurableObject, newOwner); rangerClient.createPolicy(policy); } else { rangerHelper.updatePolicyOwner(policy, preOwner, newOwner); @@ -607,20 +624,21 @@ public abstract class RangerAuthorizationPlugin * return true. <br> * 3. If the policy does not exist, then create a new policy. <br> */ - private boolean doAddSecurableObject(String roleName, RangerSecurableObject securableObject) { + private boolean doAddSecurableObject( + String roleName, AuthorizationSecurableObject securableObject) { RangerPolicy policy = rangerHelper.findManagedPolicy(securableObject); if (policy != null) { // Check the policy item's accesses and roles equal the Ranger securable object's privilege - List<RangerPrivilege> allowPrivilies = + List<AuthorizationPrivilege> allowPrivilies = securableObject.privileges().stream() .filter(privilege -> privilege.condition() == Privilege.Condition.ALLOW) .collect(Collectors.toList()); - List<RangerPrivilege> denyPrivilies = + List<AuthorizationPrivilege> denyPrivilies = securableObject.privileges().stream() .filter(privilege -> privilege.condition() == Privilege.Condition.DENY) .collect(Collectors.toList()); - Set<RangerPrivilege> policyPrivileges = + Set<AuthorizationPrivilege> policyPrivileges = policy.getPolicyItems().stream() .filter( policyItem -> @@ -632,7 +650,7 @@ public abstract class RangerAuthorizationPlugin .map(RangerPrivileges::valueOf) .collect(Collectors.toSet()); - Set<RangerPrivilege> policyDenyPrivileges = + Set<AuthorizationPrivilege> policyDenyPrivileges = policy.getDenyPolicyItems().stream() .filter( policyItem -> @@ -681,17 +699,17 @@ public abstract class RangerAuthorizationPlugin * 3. If policy does not contain any policy item, then delete this policy. <br> */ private boolean doRemoveSecurableObject( - String roleName, RangerSecurableObject rangerSecurableObject) { - RangerPolicy policy = rangerHelper.findManagedPolicy(rangerSecurableObject); + String roleName, AuthorizationSecurableObject AuthorizationSecurableObject) { + RangerPolicy policy = rangerHelper.findManagedPolicy(AuthorizationSecurableObject); if (policy == null) { LOG.warn( "Cannot find the Ranger policy for the Ranger securable object({})!", - rangerSecurableObject.fullName()); + AuthorizationSecurableObject.fullName()); // Don't throw exception or return false, because need support immutable operation. return true; } - rangerSecurableObject.privileges().stream() + AuthorizationSecurableObject.privileges().stream() .forEach( rangerPrivilege -> { if (rangerPrivilege.condition() == Privilege.Condition.ALLOW) { @@ -700,7 +718,7 @@ public abstract class RangerAuthorizationPlugin .forEach( policyItem -> { removePolicyItemIfEqualRoleName( - policyItem, rangerSecurableObject, roleName); + policyItem, AuthorizationSecurableObject, roleName); }); } else { policy @@ -708,7 +726,7 @@ public abstract class RangerAuthorizationPlugin .forEach( policyItem -> { removePolicyItemIfEqualRoleName( - policyItem, rangerSecurableObject, roleName); + policyItem, AuthorizationSecurableObject, roleName); }); } }); @@ -741,7 +759,7 @@ public abstract class RangerAuthorizationPlugin private void removePolicyItemIfEqualRoleName( RangerPolicy.RangerPolicyItem policyItem, - RangerSecurableObject rangerSecurableObject, + AuthorizationSecurableObject AuthorizationSecurableObject, String roleName) { roleName = rangerHelper.generateGravitinoRoleName(roleName); boolean match = @@ -751,7 +769,7 @@ public abstract class RangerAuthorizationPlugin access -> { // Use Gravitino privilege to search the Ranger policy item's access boolean matchPrivilege = - rangerSecurableObject.privileges().stream() + AuthorizationSecurableObject.privileges().stream() .anyMatch(privilege -> privilege.equalsTo(access.getType())); return matchPrivilege; }); @@ -767,20 +785,20 @@ public abstract class RangerAuthorizationPlugin * <br> * IF remove the COLUMN, Only need to remove `{schema}.*.*` <br> */ - private void doRemoveMetadataObject(RangerMetadataObject rangerMetadataObject) { - switch (rangerMetadataObject.type()) { + private void doRemoveMetadataObject(AuthorizationMetadataObject authMetadataObject) { + switch (authMetadataObject.metadataObjectType()) { case SCHEMA: - doRemoveSchemaMetadataObject(rangerMetadataObject); + doRemoveSchemaMetadataObject(authMetadataObject); break; case TABLE: - doRemoveTableMetadataObject(rangerMetadataObject); + doRemoveTableMetadataObject(authMetadataObject); break; case COLUMN: - removePolicyByMetadataObject(rangerMetadataObject.names()); + removePolicyByMetadataObject(authMetadataObject.names()); break; default: throw new IllegalArgumentException( - "Unsupported metadata object type: " + rangerMetadataObject.type()); + "Unsupported metadata object type: " + authMetadataObject.type()); } } @@ -788,13 +806,13 @@ public abstract class RangerAuthorizationPlugin * Remove the SCHEMA, Need to remove these the relevant policies, `{schema}`, `{schema}.*`, * `{schema}.*.*` permissions. */ - private void doRemoveSchemaMetadataObject(RangerMetadataObject rangerMetadataObject) { + private void doRemoveSchemaMetadataObject(AuthorizationMetadataObject authMetadataObject) { Preconditions.checkArgument( - rangerMetadataObject.type() == RangerMetadataObject.Type.SCHEMA, + authMetadataObject.type() == RangerMetadataObject.Type.SCHEMA, "The metadata object type must be SCHEMA"); Preconditions.checkArgument( - rangerMetadataObject.names().size() == 1, "The metadata object names must be 1"); - if (RangerHelper.RESOURCE_ALL.equals(rangerMetadataObject.name())) { + authMetadataObject.names().size() == 1, "The metadata object names must be 1"); + if (RangerHelper.RESOURCE_ALL.equals(authMetadataObject.name())) { // Delete metalake or catalog policies in this Ranger service try { List<RangerPolicy> policies = rangerClient.getPoliciesInService(rangerServiceName); @@ -807,14 +825,14 @@ public abstract class RangerAuthorizationPlugin } else { List<List<String>> loop = ImmutableList.of( - ImmutableList.of(rangerMetadataObject.name()) + ImmutableList.of(authMetadataObject.name()) /** SCHEMA permission */ , - ImmutableList.of(rangerMetadataObject.name(), RangerHelper.RESOURCE_ALL) + ImmutableList.of(authMetadataObject.name(), RangerHelper.RESOURCE_ALL) /** TABLE permission */ , ImmutableList.of( - rangerMetadataObject.name(), RangerHelper.RESOURCE_ALL, RangerHelper.RESOURCE_ALL) + authMetadataObject.name(), RangerHelper.RESOURCE_ALL, RangerHelper.RESOURCE_ALL) /** COLUMN permission */ ); for (List<String> resNames : loop) { @@ -827,14 +845,16 @@ public abstract class RangerAuthorizationPlugin * Remove the TABLE, Need to remove these the relevant policies, `*.{table}`, `*.{table}.{column}` * permissions. */ - private void doRemoveTableMetadataObject(RangerMetadataObject rangerMetadataObject) { + private void doRemoveTableMetadataObject( + AuthorizationMetadataObject AuthorizationMetadataObject) { List<List<String>> loop = ImmutableList.of( - rangerMetadataObject.names() + AuthorizationMetadataObject.names() /** TABLE permission */ , Stream.concat( - rangerMetadataObject.names().stream(), Stream.of(RangerHelper.RESOURCE_ALL)) + AuthorizationMetadataObject.names().stream(), + Stream.of(RangerHelper.RESOURCE_ALL)) .collect(Collectors.toList()) /** COLUMN permission */ ); @@ -851,20 +871,21 @@ public abstract class RangerAuthorizationPlugin * IF rename the COLUMN, Only need to rename `{schema}.*.*` <br> */ private void doRenameMetadataObject( - RangerMetadataObject rangerMetadataObject, RangerMetadataObject newRangerMetadataObject) { - switch (rangerMetadataObject.type()) { + AuthorizationMetadataObject AuthorizationMetadataObject, + AuthorizationMetadataObject newAuthMetadataObject) { + switch (newAuthMetadataObject.metadataObjectType()) { case SCHEMA: - doRenameSchemaMetadataObject(rangerMetadataObject, newRangerMetadataObject); + doRenameSchemaMetadataObject(AuthorizationMetadataObject, newAuthMetadataObject); break; case TABLE: - doRenameTableMetadataObject(rangerMetadataObject, newRangerMetadataObject); + doRenameTableMetadataObject(AuthorizationMetadataObject, newAuthMetadataObject); break; case COLUMN: - doRenameColumnMetadataObject(rangerMetadataObject, newRangerMetadataObject); + doRenameColumnMetadataObject(AuthorizationMetadataObject, newAuthMetadataObject); break; default: throw new IllegalArgumentException( - "Unsupported metadata object type: " + rangerMetadataObject.type()); + "Unsupported metadata object type: " + AuthorizationMetadataObject.type()); } } @@ -873,13 +894,15 @@ public abstract class RangerAuthorizationPlugin * `{schema}.*.*` <br> */ private void doRenameSchemaMetadataObject( - RangerMetadataObject rangerMetadataObject, RangerMetadataObject newRangerMetadataObject) { + AuthorizationMetadataObject AuthorizationMetadataObject, + AuthorizationMetadataObject newAuthorizationMetadataObject) { List<String> oldMetadataNames = new ArrayList<>(); List<String> newMetadataNames = new ArrayList<>(); List<Map<String, String>> loop = ImmutableList.of( ImmutableMap.of( - rangerMetadataObject.names().get(0), newRangerMetadataObject.names().get(0)), + AuthorizationMetadataObject.names().get(0), + newAuthorizationMetadataObject.names().get(0)), ImmutableMap.of(RangerHelper.RESOURCE_ALL, RangerHelper.RESOURCE_ALL), ImmutableMap.of(RangerHelper.RESOURCE_ALL, RangerHelper.RESOURCE_ALL)); for (Map<String, String> mapName : loop) { @@ -894,22 +917,23 @@ public abstract class RangerAuthorizationPlugin * <br> */ private void doRenameTableMetadataObject( - RangerMetadataObject rangerMetadataObject, RangerMetadataObject newRangerMetadataObject) { + AuthorizationMetadataObject AuthorizationMetadataObject, + AuthorizationMetadataObject newAuthorizationMetadataObject) { List<String> oldMetadataNames = new ArrayList<>(); List<String> newMetadataNames = new ArrayList<>(); List<Map<String, MetadataObject.Type>> loop = ImmutableList.of( - ImmutableMap.of(rangerMetadataObject.names().get(0), MetadataObject.Type.SCHEMA), - ImmutableMap.of(rangerMetadataObject.names().get(1), MetadataObject.Type.TABLE), + ImmutableMap.of(AuthorizationMetadataObject.names().get(0), MetadataObject.Type.SCHEMA), + ImmutableMap.of(AuthorizationMetadataObject.names().get(1), MetadataObject.Type.TABLE), ImmutableMap.of(RangerHelper.RESOURCE_ALL, MetadataObject.Type.COLUMN)); for (Map<String, MetadataObject.Type> nameAndType : loop) { oldMetadataNames.add(nameAndType.keySet().stream().findFirst().get()); if (nameAndType.containsValue(MetadataObject.Type.SCHEMA)) { - newMetadataNames.add(newRangerMetadataObject.names().get(0)); + newMetadataNames.add(newAuthorizationMetadataObject.names().get(0)); // Skip update the schema name operation continue; } else if (nameAndType.containsValue(MetadataObject.Type.TABLE)) { - newMetadataNames.add(newRangerMetadataObject.names().get(1)); + newMetadataNames.add(newAuthorizationMetadataObject.names().get(1)); } else if (nameAndType.containsValue(MetadataObject.Type.COLUMN)) { newMetadataNames.add(RangerHelper.RESOURCE_ALL); } @@ -919,26 +943,28 @@ public abstract class RangerAuthorizationPlugin /** rename the COLUMN, Only need to rename `*.*.{column}` <br> */ private void doRenameColumnMetadataObject( - RangerMetadataObject rangerMetadataObject, RangerMetadataObject newRangerMetadataObject) { + AuthorizationMetadataObject AuthorizationMetadataObject, + AuthorizationMetadataObject newAuthorizationMetadataObject) { List<String> oldMetadataNames = new ArrayList<>(); List<String> newMetadataNames = new ArrayList<>(); List<Map<String, MetadataObject.Type>> loop = ImmutableList.of( - ImmutableMap.of(rangerMetadataObject.names().get(0), MetadataObject.Type.SCHEMA), - ImmutableMap.of(rangerMetadataObject.names().get(1), MetadataObject.Type.TABLE), - ImmutableMap.of(rangerMetadataObject.names().get(2), MetadataObject.Type.COLUMN)); + ImmutableMap.of(AuthorizationMetadataObject.names().get(0), MetadataObject.Type.SCHEMA), + ImmutableMap.of(AuthorizationMetadataObject.names().get(1), MetadataObject.Type.TABLE), + ImmutableMap.of( + AuthorizationMetadataObject.names().get(2), MetadataObject.Type.COLUMN)); for (Map<String, MetadataObject.Type> nameAndType : loop) { oldMetadataNames.add(nameAndType.keySet().stream().findFirst().get()); if (nameAndType.containsValue(MetadataObject.Type.SCHEMA)) { - newMetadataNames.add(newRangerMetadataObject.names().get(0)); + newMetadataNames.add(newAuthorizationMetadataObject.names().get(0)); // Skip update the schema name operation continue; } else if (nameAndType.containsValue(MetadataObject.Type.TABLE)) { - newMetadataNames.add(newRangerMetadataObject.names().get(1)); + newMetadataNames.add(newAuthorizationMetadataObject.names().get(1)); // Skip update the table name operation continue; } else if (nameAndType.containsValue(MetadataObject.Type.COLUMN)) { - newMetadataNames.add(newRangerMetadataObject.names().get(2)); + newMetadataNames.add(newAuthorizationMetadataObject.names().get(2)); } updatePolicyByMetadataObject(MetadataObject.Type.COLUMN, oldMetadataNames, newMetadataNames); } @@ -997,9 +1023,12 @@ public abstract class RangerAuthorizationPlugin int index = operationTypeIndex.get(operationType); // Update the policy name is following Gravitino's spec - if (policy.getName().equals(DOT_JOINER.join(oldMetadataNames))) { + if (policy + .getName() + .equals(AuthorizationSecurableObject.DOT_JOINER.join(oldMetadataNames))) { List<String> policyNames = - Lists.newArrayList(DOT_SPLITTER.splitToList(policyName)); + Lists.newArrayList( + AuthorizationSecurableObject.DOT_SPLITTER.splitToList(policyName)); Preconditions.checkArgument( policyNames.size() >= oldMetadataNames.size(), String.format("The policy name(%s) is invalid!", policyName)); @@ -1008,7 +1037,7 @@ public abstract class RangerAuthorizationPlugin return; } policyNames.set(index, newMetadataNames.get(index)); - policy.setName(DOT_JOINER.join(policyNames)); + policy.setName(AuthorizationSecurableObject.DOT_JOINER.join(policyNames)); } // Update the policy resource name to new name policy @@ -1042,19 +1071,21 @@ public abstract class RangerAuthorizationPlugin @Override public void close() throws IOException {} - /** Generate Ranger securable object */ - public RangerSecurableObject generateRangerSecurableObject( - List<String> names, RangerMetadataObject.Type type, Set<RangerPrivilege> privileges) { - validateRangerMetadataObject(names, type); - RangerMetadataObject rangerMetadataObject = - new RangerMetadataObjects.RangerMetadataObjectImpl( - RangerMetadataObjects.getParentFullName(names), - RangerMetadataObjects.getLastName(names), + /** Generate authorization securable object */ + public AuthorizationSecurableObject generateAuthorizationSecurableObject( + List<String> names, + AuthorizationMetadataObject.Type type, + Set<AuthorizationPrivilege> privileges) { + AuthorizationMetadataObject authMetadataObject = + new RangerMetadataObject( + AuthorizationMetadataObject.getParentFullName(names), + AuthorizationMetadataObject.getLastName(names), type); - return new RangerSecurableObjects.RangerSecurableObjectImpl( - rangerMetadataObject.parent(), - rangerMetadataObject.name(), - rangerMetadataObject.type(), + authMetadataObject.validateAuthorizationMetadataObject(); + return new RangerSecurableObject( + authMetadataObject.parent(), + authMetadataObject.name(), + authMetadataObject.type(), privileges); } diff --git a/authorizations/authorization-ranger/src/main/java/org/apache/gravitino/authorization/ranger/RangerHelper.java b/authorizations/authorization-ranger/src/main/java/org/apache/gravitino/authorization/ranger/RangerHelper.java index cb74ad026..d955f7656 100644 --- a/authorizations/authorization-ranger/src/main/java/org/apache/gravitino/authorization/ranger/RangerHelper.java +++ b/authorizations/authorization-ranger/src/main/java/org/apache/gravitino/authorization/ranger/RangerHelper.java @@ -26,6 +26,9 @@ import java.util.Map; import java.util.Set; import java.util.stream.Collectors; import org.apache.commons.lang.StringUtils; +import org.apache.gravitino.authorization.AuthorizationMetadataObject; +import org.apache.gravitino.authorization.AuthorizationPrivilege; +import org.apache.gravitino.authorization.AuthorizationSecurableObject; import org.apache.gravitino.authorization.Owner; import org.apache.gravitino.authorization.Privilege; import org.apache.gravitino.exceptions.AuthorizationPluginException; @@ -49,7 +52,7 @@ public class RangerHelper { /** The `*` gives access to all resources */ public static final String RESOURCE_ALL = "*"; /** The owner privileges, the owner can do anything on the metadata object */ - private final Set<RangerPrivilege> ownerPrivileges; + private final Set<AuthorizationPrivilege> ownerPrivileges; /** The policy search keys */ protected final List<String> policyResourceDefines; @@ -69,7 +72,7 @@ public class RangerHelper { RangerClient rangerClient, String rangerAdminName, String rangerServiceName, - Set<RangerPrivilege> ownerPrivileges, + Set<AuthorizationPrivilege> ownerPrivileges, List<String> resourceDefines) { this.rangerClient = rangerClient; this.rangerAdminName = rangerAdminName; @@ -102,7 +105,8 @@ public class RangerHelper { * We cannot clean the policy items because one Ranger policy maybe contains multiple Gravitino * securable objects. <br> */ - void addPolicyItem(RangerPolicy policy, String roleName, RangerSecurableObject securableObject) { + void addPolicyItem( + RangerPolicy policy, String roleName, AuthorizationSecurableObject securableObject) { // Add the policy items by the securable object's privileges securableObject .privileges() @@ -191,12 +195,12 @@ public class RangerHelper { /** * Find the managed policy for the ranger securable object. * - * @param rangerMetadataObject The ranger securable object to find the managed policy. + * @param AuthorizationMetadataObject The ranger securable object to find the managed policy. * @return The managed policy for the metadata object. */ - public RangerPolicy findManagedPolicy(RangerMetadataObject rangerMetadataObject) + public RangerPolicy findManagedPolicy(AuthorizationMetadataObject AuthorizationMetadataObject) throws AuthorizationPluginException { - List<RangerPolicy> policies = wildcardSearchPolies(rangerMetadataObject.names()); + List<RangerPolicy> policies = wildcardSearchPolies(AuthorizationMetadataObject.names()); if (!policies.isEmpty()) { /** * Because Ranger doesn't support the precise search, Ranger will return the policy meets the @@ -204,7 +208,7 @@ public class RangerHelper { * match `db1.table1`, `db1.table2`, `db*.table*`, So we need to manually precisely filter * this research results. */ - List<String> nsMetadataObj = rangerMetadataObject.names(); + List<String> nsMetadataObj = AuthorizationMetadataObject.names(); Map<String, String> preciseFilters = new HashMap<>(); for (int i = 0; i < nsMetadataObj.size(); i++) { preciseFilters.put(policyResourceDefines.get(i), nsMetadataObj.get(i)); @@ -438,7 +442,7 @@ public class RangerHelper { }); } - protected RangerPolicy createPolicyAddResources(RangerMetadataObject metadataObject) { + protected RangerPolicy createPolicyAddResources(AuthorizationMetadataObject metadataObject) { RangerPolicy policy = new RangerPolicy(); policy.setService(rangerServiceName); policy.setName(metadataObject.fullName()); @@ -451,7 +455,8 @@ public class RangerHelper { return policy; } - protected RangerPolicy addOwnerToNewPolicy(RangerMetadataObject metadataObject, Owner newOwner) { + protected RangerPolicy addOwnerToNewPolicy( + AuthorizationMetadataObject metadataObject, Owner newOwner) { RangerPolicy policy = createPolicyAddResources(metadataObject); ownerPrivileges.forEach( @@ -476,7 +481,7 @@ public class RangerHelper { } protected RangerPolicy addOwnerRoleToNewPolicy( - RangerMetadataObject metadataObject, String ownerRoleName) { + AuthorizationMetadataObject metadataObject, String ownerRoleName) { RangerPolicy policy = createPolicyAddResources(metadataObject); ownerPrivileges.forEach( diff --git a/authorizations/authorization-ranger/src/main/java/org/apache/gravitino/authorization/ranger/RangerMetadataObject.java b/authorizations/authorization-ranger/src/main/java/org/apache/gravitino/authorization/ranger/RangerMetadataObject.java index e6611a179..b9354ee46 100644 --- a/authorizations/authorization-ranger/src/main/java/org/apache/gravitino/authorization/ranger/RangerMetadataObject.java +++ b/authorizations/authorization-ranger/src/main/java/org/apache/gravitino/authorization/ranger/RangerMetadataObject.java @@ -16,26 +16,20 @@ * specific language governing permissions and limitations * under the License. */ - package org.apache.gravitino.authorization.ranger; +import com.google.common.base.Preconditions; import java.util.List; -import javax.annotation.Nullable; import org.apache.gravitino.MetadataObject; -import org.apache.gravitino.annotation.Unstable; +import org.apache.gravitino.authorization.AuthorizationMetadataObject; -/** - * The Ranger MetadataObject is the basic unit of the Gravitino system. It represents the Apache - * Ranger metadata object in the Apache Gravitino system. The object can be a catalog, schema, - * table, column, etc. - */ -@Unstable -public interface RangerMetadataObject { +/** The helper class for {@link AuthorizationMetadataObject}. */ +public class RangerMetadataObject implements AuthorizationMetadataObject { /** * The type of object in the Ranger system. Every type will map one kind of the entity of the * Gravitino type system. */ - enum Type { + public enum Type implements AuthorizationMetadataObject.Type { /** A schema is a sub collection of the catalog. The schema can contain tables, columns, etc. */ SCHEMA(MetadataObject.Type.SCHEMA), /** A table is mapped the table of relational data sources like Apache Hive, MySQL, etc. */ @@ -49,13 +43,13 @@ public interface RangerMetadataObject { this.metadataType = type; } - public MetadataObject.Type getMetadataType() { + public MetadataObject.Type metadataObjectType() { return metadataType; } public static Type fromMetadataType(MetadataObject.Type metadataType) { for (Type type : Type.values()) { - if (type.getMetadataType() == metadataType) { + if (type.metadataObjectType() == metadataType) { return type; } } @@ -64,47 +58,97 @@ public interface RangerMetadataObject { } } - /** - * The parent full name of the object. If the object doesn't have parent, this method will return - * null. - * - * @return The parent full name of the object. - */ - @Nullable - String parent(); + /** The implementation of the {@link MetadataObject}. */ + private final String name; - /** - * The name of the object. - * - * @return The name of the object. - */ - String name(); + private final String parent; - /** - * The all name list of the object. - * - * @return The name list of the object. - */ - List<String> names(); + private final AuthorizationMetadataObject.Type type; /** - * The full name of the object. Full name will be separated by "." to represent a string - * identifier of the object, like catalog, catalog.table, etc. + * Create the metadata object with the given name, parent and type. * - * @return The name of the object. + * @param parent The parent of the metadata object + * @param name The name of the metadata object + * @param type The type of the metadata object */ - default String fullName() { - if (parent() == null) { - return name(); - } else { - return parent() + "." + name(); + public RangerMetadataObject(String parent, String name, AuthorizationMetadataObject.Type type) { + this.parent = parent; + this.name = name; + this.type = type; + } + + @Override + public String name() { + return name; + } + + @Override + public List<String> names() { + return DOT_SPLITTER.splitToList(fullName()); + } + + @Override + public String parent() { + return parent; + } + + @Override + public AuthorizationMetadataObject.Type type() { + return type; + } + + @Override + public void validateAuthorizationMetadataObject() throws IllegalArgumentException { + List<String> names = names(); + Preconditions.checkArgument( + names != null && !names.isEmpty(), "Cannot create a Ranger metadata object with no names"); + Preconditions.checkArgument( + names.size() <= 3, + "Cannot create a Ranger metadata object with the name length which is greater than 3"); + Preconditions.checkArgument( + type != null, "Cannot create a Ranger metadata object with no type"); + + Preconditions.checkArgument( + names.size() != 1 || type == RangerMetadataObject.Type.SCHEMA, + "If the length of names is 1, it must be the SCHEMA type"); + + Preconditions.checkArgument( + names.size() != 2 || type == RangerMetadataObject.Type.TABLE, + "If the length of names is 2, it must be the TABLE type"); + + Preconditions.checkArgument( + names.size() != 3 || type == RangerMetadataObject.Type.COLUMN, + "If the length of names is 3, it must be COLUMN"); + + for (String name : names) { + Preconditions.checkArgument(name != null, "Cannot create a metadata object with null name"); } } - /** - * The type of the object. - * - * @return The type of the object. - */ - Type type(); + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + + if (!(o instanceof RangerMetadataObject)) { + return false; + } + + RangerMetadataObject that = (RangerMetadataObject) o; + return java.util.Objects.equals(name, that.name) + && java.util.Objects.equals(parent, that.parent) + && type == that.type; + } + + @Override + public int hashCode() { + return java.util.Objects.hash(name, parent, type); + } + + @Override + public String toString() { + return "MetadataObject: [fullName=" + fullName() + "], [type=" + type + "]"; + } } diff --git a/authorizations/authorization-ranger/src/main/java/org/apache/gravitino/authorization/ranger/RangerMetadataObjects.java b/authorizations/authorization-ranger/src/main/java/org/apache/gravitino/authorization/ranger/RangerMetadataObjects.java deleted file mode 100644 index 7c7bed69d..000000000 --- a/authorizations/authorization-ranger/src/main/java/org/apache/gravitino/authorization/ranger/RangerMetadataObjects.java +++ /dev/null @@ -1,125 +0,0 @@ -/* - * 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.gravitino.authorization.ranger; - -import com.google.common.base.Joiner; -import com.google.common.base.Preconditions; -import com.google.common.base.Splitter; -import java.util.List; -import org.apache.gravitino.MetadataObject; - -/** The helper class for {@link RangerMetadataObject}. */ -public class RangerMetadataObjects { - protected static final Splitter DOT_SPLITTER = Splitter.on('.'); - - protected static final Joiner DOT_JOINER = Joiner.on('.'); - - private RangerMetadataObjects() {} - - /** - * Get the parent full name of the given full name. - * - * @param names The names of the metadata object - * @return The parent full name if it exists, otherwise null - */ - public static String getParentFullName(List<String> names) { - if (names.size() <= 1) { - return null; - } - - return DOT_JOINER.join(names.subList(0, names.size() - 1)); - } - - static String getLastName(List<String> names) { - Preconditions.checkArgument(names.size() > 0, "Cannot get the last name of an empty list"); - return names.get(names.size() - 1); - } - - static void checkName(String name) { - Preconditions.checkArgument(name != null, "Cannot create a metadata object with null name"); - } - - /** The implementation of the {@link MetadataObject}. */ - public static class RangerMetadataObjectImpl implements RangerMetadataObject { - private final String name; - - private final String parent; - - private final RangerMetadataObject.Type type; - - /** - * Create the metadata object with the given name, parent and type. - * - * @param parent The parent of the metadata object - * @param name The name of the metadata object - * @param type The type of the metadata object - */ - public RangerMetadataObjectImpl(String parent, String name, RangerMetadataObject.Type type) { - this.parent = parent; - this.name = name; - this.type = type; - } - - @Override - public String name() { - return name; - } - - @Override - public List<String> names() { - return DOT_SPLITTER.splitToList(fullName()); - } - - @Override - public String parent() { - return parent; - } - - @Override - public Type type() { - return type; - } - - @Override - public boolean equals(Object o) { - if (this == o) { - return true; - } - - if (!(o instanceof RangerMetadataObjectImpl)) { - return false; - } - - RangerMetadataObjectImpl that = (RangerMetadataObjectImpl) o; - return java.util.Objects.equals(name, that.name) - && java.util.Objects.equals(parent, that.parent) - && type == that.type; - } - - @Override - public int hashCode() { - return java.util.Objects.hash(name, parent, type); - } - - @Override - public String toString() { - return "MetadataObject: [fullName=" + fullName() + "], [type=" + type + "]"; - } - } -} diff --git a/authorizations/authorization-ranger/src/main/java/org/apache/gravitino/authorization/ranger/RangerPrivileges.java b/authorizations/authorization-ranger/src/main/java/org/apache/gravitino/authorization/ranger/RangerPrivileges.java index e47b46efc..bbae16a6b 100644 --- a/authorizations/authorization-ranger/src/main/java/org/apache/gravitino/authorization/ranger/RangerPrivileges.java +++ b/authorizations/authorization-ranger/src/main/java/org/apache/gravitino/authorization/ranger/RangerPrivileges.java @@ -21,11 +21,12 @@ package org.apache.gravitino.authorization.ranger; import com.google.common.base.Preconditions; import com.google.common.collect.Lists; import java.util.List; +import org.apache.gravitino.authorization.AuthorizationPrivilege; import org.apache.gravitino.authorization.Privilege; public class RangerPrivileges { /** Ranger Hive privileges enumeration. */ - public enum RangerHadoopSQLPrivilege implements RangerPrivilege { + public enum RangerHadoopSQLPrivilege implements AuthorizationPrivilege { ALL("all"), SELECT("select"), UPDATE("update"), @@ -61,12 +62,12 @@ public class RangerPrivileges { } } - public static class RangerHivePrivilegeImpl implements RangerPrivilege { - private RangerPrivilege rangerHivePrivilege; + public static class RangerHivePrivilegeImpl implements AuthorizationPrivilege { + private AuthorizationPrivilege rangerHivePrivilege; private Privilege.Condition condition; public RangerHivePrivilegeImpl( - RangerPrivilege rangerHivePrivilege, Privilege.Condition condition) { + AuthorizationPrivilege rangerHivePrivilege, Privilege.Condition condition) { this.rangerHivePrivilege = rangerHivePrivilege; this.condition = condition; } @@ -88,7 +89,7 @@ public class RangerPrivileges { } /** Ranger HDFS privileges enumeration. */ - public enum RangerHdfsPrivilege implements RangerPrivilege { + public enum RangerHdfsPrivilege implements AuthorizationPrivilege { READ("read"), WRITE("write"), EXECUTE("execute"); @@ -115,18 +116,18 @@ public class RangerPrivileges { } } - static List<Class<? extends Enum<? extends RangerPrivilege>>> allRangerPrivileges = + static List<Class<? extends Enum<? extends AuthorizationPrivilege>>> allRangerPrivileges = Lists.newArrayList( RangerHadoopSQLPrivilege.class, RangerPrivileges.RangerHdfsPrivilege.class); - public static RangerPrivilege valueOf(String name) { + public static AuthorizationPrivilege valueOf(String name) { Preconditions.checkArgument(name != null, "Privilege name string cannot be null!"); String strPrivilege = name.trim().toLowerCase(); - for (Class<? extends Enum<? extends RangerPrivilege>> enumClass : allRangerPrivileges) { - for (Enum<? extends RangerPrivilege> privilege : enumClass.getEnumConstants()) { - if (((RangerPrivilege) privilege).equalsTo(strPrivilege)) { - return (RangerPrivilege) privilege; + for (Class<? extends Enum<? extends AuthorizationPrivilege>> enumClass : allRangerPrivileges) { + for (Enum<? extends AuthorizationPrivilege> privilege : enumClass.getEnumConstants()) { + if (((AuthorizationPrivilege) privilege).equalsTo(strPrivilege)) { + return (AuthorizationPrivilege) privilege; } } } diff --git a/authorizations/authorization-ranger/src/main/java/org/apache/gravitino/authorization/ranger/RangerPrivilegesMappingProvider.java b/authorizations/authorization-ranger/src/main/java/org/apache/gravitino/authorization/ranger/RangerPrivilegesMappingProvider.java deleted file mode 100644 index ca11aaf70..000000000 --- a/authorizations/authorization-ranger/src/main/java/org/apache/gravitino/authorization/ranger/RangerPrivilegesMappingProvider.java +++ /dev/null @@ -1,92 +0,0 @@ -/* - * 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.gravitino.authorization.ranger; - -import java.util.List; -import java.util.Map; -import java.util.Set; -import org.apache.gravitino.MetadataObject; -import org.apache.gravitino.authorization.Privilege; -import org.apache.gravitino.authorization.SecurableObject; - -/** - * Ranger authorization use this provider to mapping Gravitino privilege to the Ranger privileges. - * We can use this it to support the different Ranger authorization components, such as Hive, HDFS, - * HBase, etc. - */ -public interface RangerPrivilegesMappingProvider { - /** - * Set the mapping Gravitino privilege name to the Ranger privileges rule. - * - * @return The mapping Gravitino privilege name to the Ranger privileges rule. - */ - Map<Privilege.Name, Set<RangerPrivilege>> privilegesMappingRule(); - - /** - * Set the owner Ranger privileges rule. - * - * @return The owner Ranger privileges rule. - */ - Set<RangerPrivilege> ownerMappingRule(); - - /** - * Set the Ranger policy resource defines rule. - * - * @return The policy resource defines rule. - */ - List<String> policyResourceDefinesRule(); - - /** - * Allow Gravitino privilege operation defines rule. - * - * @return The allow Gravitino privilege operation defines rule. - */ - Set<Privilege.Name> allowPrivilegesRule(); - - /** - * Allow Gravitino MetadataObject type defines rule. - * - * @return The allow Gravitino MetadataObject type defines rule. - */ - Set<MetadataObject.Type> allowMetadataObjectTypesRule(); - - /** - * Translate the Gravitino securable object to the Ranger securable object. - * - * @param securableObject The Gravitino securable object. - * @return The Ranger securable object list. - */ - List<RangerSecurableObject> translatePrivilege(SecurableObject securableObject); - - /** - * Translate the Gravitino securable object to the Ranger owner securable object. - * - * @param metadataObject The Gravitino metadata object. - * @return The Ranger owner securable object list. - */ - List<RangerSecurableObject> translateOwner(MetadataObject metadataObject); - - /** - * Translate the Gravitino metadata object to the Ranger metadata object. - * - * @param metadataObject The Gravitino metadata object. - * @return The Ranger metadata object. - */ - RangerMetadataObject translateMetadataObject(MetadataObject metadataObject); -} diff --git a/authorizations/authorization-ranger/src/main/java/org/apache/gravitino/authorization/ranger/RangerSecurableObject.java b/authorizations/authorization-ranger/src/main/java/org/apache/gravitino/authorization/ranger/RangerSecurableObject.java index da3311a17..3a6294f82 100644 --- a/authorizations/authorization-ranger/src/main/java/org/apache/gravitino/authorization/ranger/RangerSecurableObject.java +++ b/authorizations/authorization-ranger/src/main/java/org/apache/gravitino/authorization/ranger/RangerSecurableObject.java @@ -18,24 +18,37 @@ */ package org.apache.gravitino.authorization.ranger; +import com.google.common.collect.ImmutableList; +import com.google.common.collect.Sets; import java.util.List; -import org.apache.gravitino.annotation.Unstable; +import java.util.Set; +import org.apache.gravitino.authorization.AuthorizationMetadataObject; +import org.apache.gravitino.authorization.AuthorizationPrivilege; +import org.apache.gravitino.authorization.AuthorizationSecurableObject; + +/** The helper class for {@link RangerSecurableObject}. */ +public class RangerSecurableObject extends RangerMetadataObject + implements AuthorizationSecurableObject { + private final List<AuthorizationPrivilege> privileges; -/** - * The Ranger securable object is the entity which access can be granted. Unless allowed by a grant, - * access is denied. <br> - * You can use the helper class `RangerSecurableObjects` to create the Ranger securable object which - * you need. <br> - * There is a clear difference between Ranger's Securable Object and Gravitino's Securable Object, - * Ranger's Securable Object does not have the concept of `METALAKE`, so it needs to be defined - * specifically. - */ -@Unstable -public interface RangerSecurableObject extends RangerMetadataObject { /** - * The privileges of the Ranger securable object. + * Create the Ranger securable object with the given name, parent and type. * - * @return The privileges of the securable object. + * @param parent The parent of the metadata object + * @param name The name of the metadata object + * @param type The type of the metadata object */ - List<RangerPrivilege> privileges(); + public RangerSecurableObject( + String parent, + String name, + AuthorizationMetadataObject.Type type, + Set<AuthorizationPrivilege> privileges) { + super(parent, name, type); + this.privileges = ImmutableList.copyOf(Sets.newHashSet(privileges)); + } + + @Override + public List<AuthorizationPrivilege> privileges() { + return privileges; + } } diff --git a/authorizations/authorization-ranger/src/main/java/org/apache/gravitino/authorization/ranger/RangerSecurableObjects.java b/authorizations/authorization-ranger/src/main/java/org/apache/gravitino/authorization/ranger/RangerSecurableObjects.java deleted file mode 100644 index 999f78684..000000000 --- a/authorizations/authorization-ranger/src/main/java/org/apache/gravitino/authorization/ranger/RangerSecurableObjects.java +++ /dev/null @@ -1,55 +0,0 @@ -/* - * 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.gravitino.authorization.ranger; - -import com.google.common.collect.ImmutableList; -import com.google.common.collect.Sets; -import java.util.List; -import java.util.Set; -import org.apache.gravitino.authorization.ranger.RangerMetadataObjects.RangerMetadataObjectImpl; - -/** The helper class for {@link RangerSecurableObject}. */ -public class RangerSecurableObjects { - public static class RangerSecurableObjectImpl extends RangerMetadataObjectImpl - implements RangerSecurableObject { - - private final List<RangerPrivilege> privileges; - - /** - * Create the Ranger securable object with the given name, parent and type. - * - * @param parent The parent of the metadata object - * @param name The name of the metadata object - * @param type The type of the metadata object - */ - public RangerSecurableObjectImpl( - String parent, - String name, - RangerMetadataObject.Type type, - Set<RangerPrivilege> privileges) { - super(parent, name, type); - this.privileges = ImmutableList.copyOf(Sets.newHashSet(privileges)); - } - - @Override - public List<RangerPrivilege> privileges() { - return privileges; - } - } -} diff --git a/authorizations/authorization-ranger/src/test/java/org/apache/gravitino/authorization/ranger/integration/test/RangerAuthorizationPluginIT.java b/authorizations/authorization-ranger/src/test/java/org/apache/gravitino/authorization/ranger/integration/test/RangerAuthorizationPluginIT.java index 97f2b9035..50ca331d2 100644 --- a/authorizations/authorization-ranger/src/test/java/org/apache/gravitino/authorization/ranger/integration/test/RangerAuthorizationPluginIT.java +++ b/authorizations/authorization-ranger/src/test/java/org/apache/gravitino/authorization/ranger/integration/test/RangerAuthorizationPluginIT.java @@ -24,6 +24,8 @@ import java.util.Arrays; import java.util.List; import org.apache.gravitino.MetadataObject; import org.apache.gravitino.MetadataObjects; +import org.apache.gravitino.authorization.AuthorizationMetadataObject; +import org.apache.gravitino.authorization.AuthorizationSecurableObject; import org.apache.gravitino.authorization.Privilege; import org.apache.gravitino.authorization.Privileges; import org.apache.gravitino.authorization.SecurableObject; @@ -31,7 +33,6 @@ import org.apache.gravitino.authorization.SecurableObjects; import org.apache.gravitino.authorization.ranger.RangerAuthorizationPlugin; import org.apache.gravitino.authorization.ranger.RangerHelper; import org.apache.gravitino.authorization.ranger.RangerMetadataObject; -import org.apache.gravitino.authorization.ranger.RangerSecurableObject; import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.Tag; @@ -51,28 +52,28 @@ public class RangerAuthorizationPluginIT { public void testTranslateMetadataObject() { MetadataObject metalake = MetadataObjects.parse(String.format("metalake1"), MetadataObject.Type.METALAKE); - RangerMetadataObject rangerMetalake = rangerAuthPlugin.translateMetadataObject(metalake); + AuthorizationMetadataObject rangerMetalake = rangerAuthPlugin.translateMetadataObject(metalake); Assertions.assertEquals(1, rangerMetalake.names().size()); Assertions.assertEquals(RangerHelper.RESOURCE_ALL, rangerMetalake.names().get(0)); Assertions.assertEquals(RangerMetadataObject.Type.SCHEMA, rangerMetalake.type()); MetadataObject catalog = MetadataObjects.parse(String.format("catalog1"), MetadataObject.Type.CATALOG); - RangerMetadataObject rangerCatalog = rangerAuthPlugin.translateMetadataObject(catalog); + AuthorizationMetadataObject rangerCatalog = rangerAuthPlugin.translateMetadataObject(catalog); Assertions.assertEquals(1, rangerCatalog.names().size()); Assertions.assertEquals(RangerHelper.RESOURCE_ALL, rangerCatalog.names().get(0)); Assertions.assertEquals(RangerMetadataObject.Type.SCHEMA, rangerCatalog.type()); MetadataObject schema = MetadataObjects.parse(String.format("catalog1.schema1"), MetadataObject.Type.SCHEMA); - RangerMetadataObject rangerSchema = rangerAuthPlugin.translateMetadataObject(schema); + AuthorizationMetadataObject rangerSchema = rangerAuthPlugin.translateMetadataObject(schema); Assertions.assertEquals(1, rangerSchema.names().size()); Assertions.assertEquals("schema1", rangerSchema.names().get(0)); Assertions.assertEquals(RangerMetadataObject.Type.SCHEMA, rangerSchema.type()); MetadataObject table = MetadataObjects.parse(String.format("catalog1.schema1.tab1"), MetadataObject.Type.TABLE); - RangerMetadataObject rangerTable = rangerAuthPlugin.translateMetadataObject(table); + AuthorizationMetadataObject rangerTable = rangerAuthPlugin.translateMetadataObject(table); Assertions.assertEquals(2, rangerTable.names().size()); Assertions.assertEquals("schema1", rangerTable.names().get(0)); Assertions.assertEquals("tab1", rangerTable.names().get(1)); @@ -86,7 +87,7 @@ public class RangerAuthorizationPluginIT { String.format("metalake1"), MetadataObject.Type.METALAKE, Lists.newArrayList(Privileges.CreateSchema.allow())); - List<RangerSecurableObject> createSchemaInMetalake1 = + List<AuthorizationSecurableObject> createSchemaInMetalake1 = rangerAuthPlugin.translatePrivilege(createSchemaInMetalake); Assertions.assertEquals(1, createSchemaInMetalake1.size()); Assertions.assertEquals(RangerHelper.RESOURCE_ALL, createSchemaInMetalake1.get(0).fullName()); @@ -98,7 +99,7 @@ public class RangerAuthorizationPluginIT { String.format("catalog1"), MetadataObject.Type.CATALOG, Lists.newArrayList(Privileges.CreateSchema.allow())); - List<RangerSecurableObject> createSchemaInCatalog1 = + List<AuthorizationSecurableObject> createSchemaInCatalog1 = rangerAuthPlugin.translatePrivilege(createSchemaInCatalog); Assertions.assertEquals(1, createSchemaInCatalog1.size()); Assertions.assertEquals(RangerHelper.RESOURCE_ALL, createSchemaInCatalog1.get(0).fullName()); @@ -114,7 +115,7 @@ public class RangerAuthorizationPluginIT { String.format("metalake1"), MetadataObject.Type.METALAKE, Lists.newArrayList(Privileges.CreateTable.allow())); - List<RangerSecurableObject> metalake1 = rangerAuthPlugin.translatePrivilege(metalake); + List<AuthorizationSecurableObject> metalake1 = rangerAuthPlugin.translatePrivilege(metalake); Assertions.assertEquals(2, metalake1.size()); Assertions.assertEquals("*.*", metalake1.get(0).fullName()); Assertions.assertEquals(RangerMetadataObject.Type.TABLE, metalake1.get(0).type()); @@ -126,7 +127,7 @@ public class RangerAuthorizationPluginIT { String.format("catalog1"), MetadataObject.Type.CATALOG, Lists.newArrayList(Privileges.CreateTable.allow())); - List<RangerSecurableObject> catalog1 = rangerAuthPlugin.translatePrivilege(catalog); + List<AuthorizationSecurableObject> catalog1 = rangerAuthPlugin.translatePrivilege(catalog); Assertions.assertEquals(2, catalog1.size()); Assertions.assertEquals("*.*", catalog1.get(0).fullName()); Assertions.assertEquals(RangerMetadataObject.Type.TABLE, catalog1.get(0).type()); @@ -138,7 +139,7 @@ public class RangerAuthorizationPluginIT { String.format("catalog1.schema1"), MetadataObject.Type.SCHEMA, Lists.newArrayList(privilege)); - List<RangerSecurableObject> schema1 = rangerAuthPlugin.translatePrivilege(schema); + List<AuthorizationSecurableObject> schema1 = rangerAuthPlugin.translatePrivilege(schema); Assertions.assertEquals(2, schema1.size()); Assertions.assertEquals("schema1.*", schema1.get(0).fullName()); Assertions.assertEquals(RangerMetadataObject.Type.TABLE, schema1.get(0).type()); @@ -152,7 +153,7 @@ public class RangerAuthorizationPluginIT { String.format("catalog1.schema1.table1"), MetadataObject.Type.TABLE, Lists.newArrayList(privilege)); - List<RangerSecurableObject> table1 = rangerAuthPlugin.translatePrivilege(table); + List<AuthorizationSecurableObject> table1 = rangerAuthPlugin.translatePrivilege(table); Assertions.assertEquals(2, table1.size()); Assertions.assertEquals("schema1.table1", table1.get(0).fullName()); Assertions.assertEquals(RangerMetadataObject.Type.TABLE, table1.get(0).type()); @@ -167,7 +168,7 @@ public class RangerAuthorizationPluginIT { for (MetadataObject.Type type : ImmutableList.of(MetadataObject.Type.METALAKE, MetadataObject.Type.CATALOG)) { MetadataObject metalake = MetadataObjects.parse("metalake_or_catalog", type); - List<RangerSecurableObject> metalakeOwner = rangerAuthPlugin.translateOwner(metalake); + List<AuthorizationSecurableObject> metalakeOwner = rangerAuthPlugin.translateOwner(metalake); Assertions.assertEquals(3, metalakeOwner.size()); Assertions.assertEquals(RangerHelper.RESOURCE_ALL, metalakeOwner.get(0).fullName()); Assertions.assertEquals(RangerMetadataObject.Type.SCHEMA, metalakeOwner.get(0).type()); @@ -178,7 +179,7 @@ public class RangerAuthorizationPluginIT { } MetadataObject schema = MetadataObjects.parse("catalog1.schema1", MetadataObject.Type.SCHEMA); - List<RangerSecurableObject> schemaOwner = rangerAuthPlugin.translateOwner(schema); + List<AuthorizationSecurableObject> schemaOwner = rangerAuthPlugin.translateOwner(schema); Assertions.assertEquals(3, schemaOwner.size()); Assertions.assertEquals("schema1", schemaOwner.get(0).fullName()); Assertions.assertEquals(RangerMetadataObject.Type.SCHEMA, schemaOwner.get(0).type()); @@ -189,7 +190,7 @@ public class RangerAuthorizationPluginIT { MetadataObject table = MetadataObjects.parse("catalog1.schema1.table1", MetadataObject.Type.TABLE); - List<RangerSecurableObject> tableOwner = rangerAuthPlugin.translateOwner(table); + List<AuthorizationSecurableObject> tableOwner = rangerAuthPlugin.translateOwner(table); Assertions.assertEquals(2, tableOwner.size()); Assertions.assertEquals("schema1.table1", tableOwner.get(0).fullName()); Assertions.assertEquals(RangerMetadataObject.Type.TABLE, tableOwner.get(0).type()); diff --git a/authorizations/authorization-ranger/src/test/java/org/apache/gravitino/authorization/ranger/integration/test/RangerHiveIT.java b/authorizations/authorization-ranger/src/test/java/org/apache/gravitino/authorization/ranger/integration/test/RangerHiveIT.java index 7c45ff9b0..243491867 100644 --- a/authorizations/authorization-ranger/src/test/java/org/apache/gravitino/authorization/ranger/integration/test/RangerHiveIT.java +++ b/authorizations/authorization-ranger/src/test/java/org/apache/gravitino/authorization/ranger/integration/test/RangerHiveIT.java @@ -38,6 +38,7 @@ import java.util.concurrent.atomic.AtomicReference; import java.util.stream.Collectors; import org.apache.gravitino.MetadataObject; import org.apache.gravitino.MetadataObjects; +import org.apache.gravitino.authorization.AuthorizationSecurableObject; import org.apache.gravitino.authorization.MetadataObjectChange; import org.apache.gravitino.authorization.Owner; import org.apache.gravitino.authorization.Privilege; @@ -339,8 +340,8 @@ public class RangerHiveIT { Lists.newArrayList(String.format("%s3", dbName), "tab*"), GravitinoITUtils.genRandomName(currentFunName())); // findManagedPolicy function use precise search, so return null - RangerSecurableObject rangerSecurableObject = - rangerAuthHivePlugin.generateRangerSecurableObject( + AuthorizationSecurableObject rangerSecurableObject = + rangerAuthHivePlugin.generateAuthorizationSecurableObject( ImmutableList.of(String.format("%s3", dbName), "tab1"), RangerMetadataObject.Type.TABLE, ImmutableSet.of( @@ -1825,7 +1826,7 @@ public class RangerHiveIT { * @param rangerSecurableObject: the Ranger securable object to be verified */ private void verifyRangerSecurableObjectInRanger( - RangerSecurableObject rangerSecurableObject, + AuthorizationSecurableObject rangerSecurableObject, List<String> includeUsers, List<String> excludeUsers, List<String> includeGroups, @@ -1937,24 +1938,26 @@ public class RangerHiveIT { }); } - private void verifyRangerSecurableObjectInRanger(RangerSecurableObject securableObject) { + private void verifyRangerSecurableObjectInRanger(AuthorizationSecurableObject securableObject) { verifyRangerSecurableObjectInRanger(securableObject, null, null, null, null, null, null); } private void verifyRangerSecurableObjectInRanger( - RangerSecurableObject securableObject, List<String> includeUsers) { + AuthorizationSecurableObject securableObject, List<String> includeUsers) { verifyRangerSecurableObjectInRanger( securableObject, includeUsers, null, null, null, null, null); } private void verifyRangerSecurableObjectInRanger( - RangerSecurableObject securableObject, List<String> includeUsers, List<String> excludeUsers) { + AuthorizationSecurableObject securableObject, + List<String> includeUsers, + List<String> excludeUsers) { verifyRangerSecurableObjectInRanger( securableObject, includeUsers, excludeUsers, null, null, null, null); } private void verifyRangerSecurableObjectInRanger( - RangerSecurableObject securableObject, + AuthorizationSecurableObject securableObject, List<String> includeUsers, List<String> excludeUsers, List<String> includeGroups) { @@ -1963,7 +1966,7 @@ public class RangerHiveIT { } private void verifyRangerSecurableObjectInRanger( - RangerSecurableObject securableObject, + AuthorizationSecurableObject securableObject, List<String> includeUsers, List<String> excludeUsers, List<String> includeGroups, @@ -1973,7 +1976,7 @@ public class RangerHiveIT { } private void verifyRangerSecurableObjectInRanger( - RangerSecurableObject securableObject, + AuthorizationSecurableObject securableObject, List<String> includeUsers, List<String> excludeUsers, List<String> includeGroups, diff --git a/authorizations/authorization-ranger/src/test/java/org/apache/gravitino/authorization/ranger/integration/test/RangerITEnv.java b/authorizations/authorization-ranger/src/test/java/org/apache/gravitino/authorization/ranger/integration/test/RangerITEnv.java index 0c6dd5803..4f4a5ff91 100644 --- a/authorizations/authorization-ranger/src/test/java/org/apache/gravitino/authorization/ranger/integration/test/RangerITEnv.java +++ b/authorizations/authorization-ranger/src/test/java/org/apache/gravitino/authorization/ranger/integration/test/RangerITEnv.java @@ -27,13 +27,13 @@ import java.util.List; import java.util.Map; import java.util.concurrent.atomic.AtomicReference; import java.util.stream.Collectors; +import org.apache.gravitino.authorization.AuthorizationSecurableObject; import org.apache.gravitino.authorization.Privilege; import org.apache.gravitino.authorization.Role; import org.apache.gravitino.authorization.ranger.RangerAuthorizationHadoopSQLPlugin; import org.apache.gravitino.authorization.ranger.RangerAuthorizationPlugin; import org.apache.gravitino.authorization.ranger.RangerHelper; import org.apache.gravitino.authorization.ranger.RangerPrivileges; -import org.apache.gravitino.authorization.ranger.RangerSecurableObject; import org.apache.gravitino.authorization.ranger.reference.RangerDefines; import org.apache.gravitino.connector.AuthorizationPropertiesMeta; import org.apache.gravitino.integration.test.container.ContainerSuite; @@ -425,7 +425,7 @@ public class RangerITEnv { role.securableObjects() .forEach( securableObject -> { - List<RangerSecurableObject> rangerSecurableObjects = + List<AuthorizationSecurableObject> rangerSecurableObjects = rangerAuthPlugin.translatePrivilege(securableObject); rangerSecurableObjects.forEach( diff --git a/authorizations/authorization-ranger/src/main/java/org/apache/gravitino/authorization/ranger/RangerMetadataObject.java b/core/src/main/java/org/apache/gravitino/authorization/AuthorizationMetadataObject.java similarity index 53% copy from authorizations/authorization-ranger/src/main/java/org/apache/gravitino/authorization/ranger/RangerMetadataObject.java copy to core/src/main/java/org/apache/gravitino/authorization/AuthorizationMetadataObject.java index e6611a179..07b72da82 100644 --- a/authorizations/authorization-ranger/src/main/java/org/apache/gravitino/authorization/ranger/RangerMetadataObject.java +++ b/core/src/main/java/org/apache/gravitino/authorization/AuthorizationMetadataObject.java @@ -16,53 +16,28 @@ * specific language governing permissions and limitations * under the License. */ +package org.apache.gravitino.authorization; -package org.apache.gravitino.authorization.ranger; - +import com.google.common.base.Joiner; +import com.google.common.base.Preconditions; +import com.google.common.base.Splitter; import java.util.List; import javax.annotation.Nullable; import org.apache.gravitino.MetadataObject; -import org.apache.gravitino.annotation.Unstable; /** - * The Ranger MetadataObject is the basic unit of the Gravitino system. It represents the Apache - * Ranger metadata object in the Apache Gravitino system. The object can be a catalog, schema, - * table, column, etc. + * AuthorizationMetadataObject interface is used to define the underlying data source metadata + * object. */ -@Unstable -public interface RangerMetadataObject { - /** - * The type of object in the Ranger system. Every type will map one kind of the entity of the - * Gravitino type system. - */ - enum Type { - /** A schema is a sub collection of the catalog. The schema can contain tables, columns, etc. */ - SCHEMA(MetadataObject.Type.SCHEMA), - /** A table is mapped the table of relational data sources like Apache Hive, MySQL, etc. */ - TABLE(MetadataObject.Type.TABLE), - /** A column is a sub-collection of the table that represents a group of same type data. */ - COLUMN(MetadataObject.Type.COLUMN); - - private final MetadataObject.Type metadataType; - - Type(MetadataObject.Type type) { - this.metadataType = type; - } +public interface AuthorizationMetadataObject { + /** Underlying data source metadata object type. */ + interface Type { + MetadataObject.Type metadataObjectType(); + } - public MetadataObject.Type getMetadataType() { - return metadataType; - } + Splitter DOT_SPLITTER = Splitter.on('.'); - public static Type fromMetadataType(MetadataObject.Type metadataType) { - for (Type type : Type.values()) { - if (type.getMetadataType() == metadataType) { - return type; - } - } - throw new IllegalArgumentException( - "No matching RangerMetadataObject.Type for " + metadataType); - } - } + Joiner DOT_JOINER = Joiner.on('.'); /** * The parent full name of the object. If the object doesn't have parent, this method will return @@ -89,7 +64,7 @@ public interface RangerMetadataObject { /** * The full name of the object. Full name will be separated by "." to represent a string - * identifier of the object, like catalog, catalog.table, etc. + * identifier of the object, like `catalog`, `catalog.table`, etc. * * @return The name of the object. */ @@ -101,10 +76,36 @@ public interface RangerMetadataObject { } } + /** + * Get the parent full name of the given full name. + * + * @param names The names of the metadata object + * @return The parent full name if it exists, otherwise null + */ + static String getParentFullName(List<String> names) { + if (names.size() <= 1) { + return null; + } + + return DOT_JOINER.join(names.subList(0, names.size() - 1)); + } + + static String getLastName(List<String> names) { + Preconditions.checkArgument(names.size() > 0, "Cannot get the last name of an empty list"); + return names.get(names.size() - 1); + } + /** * The type of the object. * * @return The type of the object. */ Type type(); + + default MetadataObject.Type metadataObjectType() { + return type().metadataObjectType(); + } + + /** Validate different underlying datasource metadata object */ + void validateAuthorizationMetadataObject() throws IllegalArgumentException; } diff --git a/authorizations/authorization-ranger/src/main/java/org/apache/gravitino/authorization/ranger/RangerPrivilege.java b/core/src/main/java/org/apache/gravitino/authorization/AuthorizationPrivilege.java similarity index 80% rename from authorizations/authorization-ranger/src/main/java/org/apache/gravitino/authorization/ranger/RangerPrivilege.java rename to core/src/main/java/org/apache/gravitino/authorization/AuthorizationPrivilege.java index 04774b417..4c58b9ffc 100644 --- a/authorizations/authorization-ranger/src/main/java/org/apache/gravitino/authorization/ranger/RangerPrivilege.java +++ b/core/src/main/java/org/apache/gravitino/authorization/AuthorizationPrivilege.java @@ -16,12 +16,10 @@ * specific language governing permissions and limitations * under the License. */ -package org.apache.gravitino.authorization.ranger; +package org.apache.gravitino.authorization; -import org.apache.gravitino.authorization.Privilege; - -/** RangerPrivilege interface is used to define the Ranger privileges. */ -public interface RangerPrivilege { +/** AuthorizationPrivilege interface is used to define the underlying data source privileges. */ +public interface AuthorizationPrivilege { String getName(); Privilege.Condition condition(); diff --git a/core/src/main/java/org/apache/gravitino/authorization/AuthorizationPrivilegesMappingProvider.java b/core/src/main/java/org/apache/gravitino/authorization/AuthorizationPrivilegesMappingProvider.java new file mode 100644 index 000000000..218de2604 --- /dev/null +++ b/core/src/main/java/org/apache/gravitino/authorization/AuthorizationPrivilegesMappingProvider.java @@ -0,0 +1,83 @@ +/* + * 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.gravitino.authorization; + +import java.util.List; +import java.util.Map; +import java.util.Set; +import org.apache.gravitino.MetadataObject; + +/** + * Authorization use this provider to mapping Gravitino privilege to the underlying data source + * privileges. We can use this it to support the different data source, such as Hive, HDFS, HBase, + * etc. + */ +public interface AuthorizationPrivilegesMappingProvider { + /** + * Set the mapping Gravitino privilege name to the underlying data source privileges rule. + * + * @return The mapping Gravitino privilege name to the underlying data source privileges rule. + */ + Map<Privilege.Name, Set<AuthorizationPrivilege>> privilegesMappingRule(); + + /** + * Set the owner underlying data source privileges rule. + * + * @return The owner underlying data source privileges rule. + */ + Set<AuthorizationPrivilege> ownerMappingRule(); + + /** + * Allow Gravitino privilege operation defines rule. + * + * @return The allow Gravitino privilege operation defines rule. + */ + Set<Privilege.Name> allowPrivilegesRule(); + + /** + * Allow Gravitino MetadataObject type defines rule. + * + * @return To allow Gravitino MetadataObject type defines rule. + */ + Set<MetadataObject.Type> allowMetadataObjectTypesRule(); + + /** + * Translate the Gravitino securable object to the underlying data source securable object. + * + * @param securableObject The Gravitino securable object. + * @return The underlying data source securable object list. + */ + List<AuthorizationSecurableObject> translatePrivilege(SecurableObject securableObject); + + /** + * Translate the Gravitino securable object to the underlying data source owner securable object. + * + * @param metadataObject The Gravitino metadata object. + * @return The underlying data source owner securable object list. + */ + List<AuthorizationSecurableObject> translateOwner(MetadataObject metadataObject); + + /** + * Translate the Gravitino metadata object to the underlying data source metadata object. + * + * @param metadataObject The Gravitino metadata object. + * @return The underlying data source metadata object. + */ + AuthorizationMetadataObject translateMetadataObject(MetadataObject metadataObject); +} diff --git a/authorizations/authorization-ranger/src/main/java/org/apache/gravitino/authorization/ranger/RangerMetadataObjectRule.java b/core/src/main/java/org/apache/gravitino/authorization/AuthorizationSecurableObject.java similarity index 55% rename from authorizations/authorization-ranger/src/main/java/org/apache/gravitino/authorization/ranger/RangerMetadataObjectRule.java rename to core/src/main/java/org/apache/gravitino/authorization/AuthorizationSecurableObject.java index a8de00518..5c0e1b679 100644 --- a/authorizations/authorization-ranger/src/main/java/org/apache/gravitino/authorization/ranger/RangerMetadataObjectRule.java +++ b/core/src/main/java/org/apache/gravitino/authorization/AuthorizationSecurableObject.java @@ -16,13 +16,22 @@ * specific language governing permissions and limitations * under the License. */ -package org.apache.gravitino.authorization.ranger; +package org.apache.gravitino.authorization; import java.util.List; -/** Different underlying datasource have different Ranger metadata object rules */ -interface RangerMetadataObjectRule { - /** Validate different underlying datasource Ranger metadata object */ - void validateRangerMetadataObject(List<String> names, RangerMetadataObject.Type type) - throws IllegalArgumentException; +/** + * The authorization securable object is the entity which access can be granted. Unless allowed by a + * grant, access is denied. <br> + * There is a clear difference between underlying datasource's Securable Object and Gravitino's + * Securable Object, authorization's Securable Object does not have the concept of `METALAKE`, so it + * needs to be defined specifically. + */ +public interface AuthorizationSecurableObject extends AuthorizationMetadataObject { + /** + * The privileges of the authorization securable object. + * + * @return The privileges of the securable object. + */ + List<AuthorizationPrivilege> privileges(); }