Skip to content

Commit 1d6de4c

Browse files
authored
[#9254,#9168] improvement(authz): Optimize metadata authorization in the list metalake and list role. (#9255)
### What changes were proposed in this pull request? Optimize metadata authorization in the list metalake and list role. ### Why are the changes needed? Fix: #9254 #9168 ### Does this PR introduce _any_ user-facing change? None ### How was this patch tested? Existing test case in org.apache.gravitino.client.integration.test.authorization.MetalakeAuthorizationIT Existing test case in org.apache.gravitino.client.integration.test.authorization.RoleAuthorizationIT
1 parent 98867e2 commit 1d6de4c

File tree

4 files changed

+51
-79
lines changed

4 files changed

+51
-79
lines changed

server-common/src/main/java/org/apache/gravitino/server/authorization/MetadataAuthzHelper.java

Lines changed: 43 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@
3333
import org.apache.gravitino.Configs;
3434
import org.apache.gravitino.Entity;
3535
import org.apache.gravitino.GravitinoEnv;
36+
import org.apache.gravitino.Metalake;
3637
import org.apache.gravitino.NameIdentifier;
3738
import org.apache.gravitino.authorization.AuthorizationRequestContext;
3839
import org.apache.gravitino.authorization.GravitinoAuthorizer;
@@ -88,6 +89,25 @@ public static NameIdentifier[] filterByPrivilege(
8889
.toArray(NameIdentifier[]::new);
8990
}
9091

92+
public static Metalake[] filterMetalakes(Metalake[] metalakes, String expression) {
93+
if (!enableAuthorization()) {
94+
return metalakes;
95+
}
96+
checkExecutor();
97+
AuthorizationRequestContext authorizationRequestContext = new AuthorizationRequestContext();
98+
return doFilter(
99+
expression,
100+
metalakes,
101+
GravitinoAuthorizerProvider.getInstance().getGravitinoAuthorizer(),
102+
authorizationRequestContext,
103+
metalake -> {
104+
String metalakeName = metalake.name();
105+
return splitMetadataNames(
106+
metalakeName,
107+
Entity.EntityType.METALAKE,
108+
NameIdentifierUtil.ofMetalake(metalakeName));
109+
});
110+
}
91111
/**
92112
* Call {@link AuthorizationExpressionEvaluator} to filter the metadata list
93113
*
@@ -102,41 +122,7 @@ public static NameIdentifier[] filterByExpression(
102122
String expression,
103123
Entity.EntityType entityType,
104124
NameIdentifier[] nameIdentifiers) {
105-
if (!enableAuthorization()) {
106-
return nameIdentifiers;
107-
}
108-
checkExecutor();
109-
AuthorizationRequestContext authorizationRequestContext = new AuthorizationRequestContext();
110-
List<CompletableFuture<NameIdentifier>> futures = new ArrayList<>();
111-
for (NameIdentifier nameIdentifier : nameIdentifiers) {
112-
Principal currentPrincipal = PrincipalUtils.getCurrentPrincipal();
113-
futures.add(
114-
CompletableFuture.supplyAsync(
115-
() -> {
116-
try {
117-
return PrincipalUtils.doAs(
118-
currentPrincipal,
119-
() -> {
120-
Map<Entity.EntityType, NameIdentifier> nameIdentifierMap =
121-
spiltMetadataNames(metalake, entityType, nameIdentifier);
122-
AuthorizationExpressionEvaluator authorizationExpressionEvaluator =
123-
new AuthorizationExpressionEvaluator(expression);
124-
return authorizationExpressionEvaluator.evaluate(
125-
nameIdentifierMap, authorizationRequestContext)
126-
? nameIdentifier
127-
: null;
128-
});
129-
} catch (Exception e) {
130-
LOG.error("GravitinoAuthorize error:{}", e.getMessage(), e);
131-
return null;
132-
}
133-
},
134-
executor));
135-
}
136-
return futures.stream()
137-
.map(CompletableFuture::join)
138-
.filter(Objects::nonNull)
139-
.toArray(NameIdentifier[]::new);
125+
return filterByExpression(metalake, expression, entityType, nameIdentifiers, e -> e);
140126
}
141127

142128
/**
@@ -155,7 +141,7 @@ public static boolean checkAccess(
155141

156142
String metalake = NameIdentifierUtil.getMetalake(identifier);
157143
Map<Entity.EntityType, NameIdentifier> nameIdentifierMap =
158-
spiltMetadataNames(metalake, entityType, identifier);
144+
splitMetadataNames(metalake, entityType, identifier);
159145
AuthorizationExpressionEvaluator authorizationExpressionEvaluator =
160146
new AuthorizationExpressionEvaluator(expression);
161147
return authorizationExpressionEvaluator.evaluate(
@@ -181,9 +167,8 @@ public static <E> E[] filterByExpression(
181167
Function<E, NameIdentifier> toNameIdentifier) {
182168
GravitinoAuthorizer authorizer =
183169
GravitinoAuthorizerProvider.getInstance().getGravitinoAuthorizer();
184-
Principal currentPrincipal = PrincipalUtils.getCurrentPrincipal();
185170
return filterByExpression(
186-
metalake, expression, entityType, entities, toNameIdentifier, currentPrincipal, authorizer);
171+
metalake, expression, entityType, entities, toNameIdentifier, authorizer);
187172
}
188173

189174
/**
@@ -195,7 +180,6 @@ public static <E> E[] filterByExpression(
195180
* @param entityType entity type
196181
* @param entities metadata entities
197182
* @param toNameIdentifier function to convert entity to NameIdentifier
198-
* @param currentPrincipal current principal
199183
* @param authorizer authorizer to filter metadata
200184
* @return Filtered Metadata Entity
201185
* @param <E> Entity class
@@ -206,13 +190,30 @@ public static <E> E[] filterByExpression(
206190
Entity.EntityType entityType,
207191
E[] entities,
208192
Function<E, NameIdentifier> toNameIdentifier,
209-
Principal currentPrincipal,
210193
GravitinoAuthorizer authorizer) {
211194
if (!enableAuthorization()) {
212195
return entities;
213196
}
214197
checkExecutor();
215198
AuthorizationRequestContext authorizationRequestContext = new AuthorizationRequestContext();
199+
return doFilter(
200+
expression,
201+
entities,
202+
authorizer,
203+
authorizationRequestContext,
204+
(entity) -> {
205+
NameIdentifier nameIdentifier = toNameIdentifier.apply(entity);
206+
return splitMetadataNames(metalake, entityType, nameIdentifier);
207+
});
208+
}
209+
210+
private static <E> E[] doFilter(
211+
String expression,
212+
E[] entities,
213+
GravitinoAuthorizer authorizer,
214+
AuthorizationRequestContext authorizationRequestContext,
215+
Function<E, Map<Entity.EntityType, NameIdentifier>> extractMetadataNamesMap) {
216+
Principal currentPrincipal = PrincipalUtils.getCurrentPrincipal();
216217
List<CompletableFuture<E>> futures = new ArrayList<>();
217218
for (E entity : entities) {
218219
futures.add(
@@ -224,11 +225,8 @@ public static <E> E[] filterByExpression(
224225
() -> {
225226
AuthorizationExpressionEvaluator authorizationExpressionEvaluator =
226227
new AuthorizationExpressionEvaluator(expression, authorizer);
227-
NameIdentifier nameIdentifier = toNameIdentifier.apply(entity);
228-
Map<Entity.EntityType, NameIdentifier> nameIdentifierMap =
229-
spiltMetadataNames(metalake, entityType, nameIdentifier);
230228
return authorizationExpressionEvaluator.evaluate(
231-
nameIdentifierMap, authorizationRequestContext)
229+
extractMetadataNamesMap.apply(entity), authorizationRequestContext)
232230
? entity
233231
: null;
234232
});
@@ -255,7 +253,7 @@ public static <E> E[] filterByExpression(
255253
* @param nameIdentifier metadata name
256254
* @return A map containing the metadata object and all its parent objects, keyed by their types
257255
*/
258-
public static Map<Entity.EntityType, NameIdentifier> spiltMetadataNames(
256+
public static Map<Entity.EntityType, NameIdentifier> splitMetadataNames(
259257
String metalake, Entity.EntityType entityType, NameIdentifier nameIdentifier) {
260258
Map<Entity.EntityType, NameIdentifier> nameIdentifierMap = new HashMap<>();
261259
nameIdentifierMap.put(Entity.EntityType.METALAKE, NameIdentifierUtil.ofMetalake(metalake));

server/src/main/java/org/apache/gravitino/server/web/filter/ParameterUtil.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -171,7 +171,7 @@ public static Map<Entity.EntityType, NameIdentifier> extractNameIdentifierFromPa
171171
NameIdentifier nameIdentifier =
172172
MetadataObjectUtil.toEntityIdent(metalake, MetadataObjects.parse(fullName, type));
173173
nameIdentifierMap.putAll(
174-
MetadataAuthzHelper.spiltMetadataNames(
174+
MetadataAuthzHelper.splitMetadataNames(
175175
metalake, MetadataObjectUtil.toEntityType(type), nameIdentifier));
176176
}
177177

server/src/main/java/org/apache/gravitino/server/web/rest/MetalakeOperations.java

Lines changed: 1 addition & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -89,22 +89,7 @@ public Response listMetalakes() {
8989
httpRequest,
9090
() -> {
9191
Metalake[] metalakes = metalakeDispatcher.listMetalakes();
92-
metalakes =
93-
Arrays.stream(metalakes)
94-
.filter(
95-
metalake -> {
96-
NameIdentifier[] nameIdentifiers =
97-
new NameIdentifier[] {NameIdentifierUtil.ofMetalake(metalake.name())};
98-
return MetadataAuthzHelper.filterByExpression(
99-
metalake.name(),
100-
"METALAKE_USER",
101-
Entity.EntityType.METALAKE,
102-
nameIdentifiers)
103-
.length
104-
> 0;
105-
})
106-
.toList()
107-
.toArray(new Metalake[0]);
92+
metalakes = MetadataAuthzHelper.filterMetalakes(metalakes, "METALAKE_USER");
10893
MetalakeDTO[] metalakeDTOs =
10994
Arrays.stream(metalakes).map(DTOConverters::toDTO).toArray(MetalakeDTO[]::new);
11095
Response response = Utils.ok(new MetalakeListResponse(metalakeDTOs));

server/src/main/java/org/apache/gravitino/server/web/rest/RoleOperations.java

Lines changed: 6 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,6 @@
3838
import org.apache.gravitino.GravitinoEnv;
3939
import org.apache.gravitino.MetadataObject;
4040
import org.apache.gravitino.MetadataObjects;
41-
import org.apache.gravitino.NameIdentifier;
4241
import org.apache.gravitino.authorization.AccessControlDispatcher;
4342
import org.apache.gravitino.authorization.AuthorizationUtils;
4443
import org.apache.gravitino.authorization.Privilege;
@@ -92,22 +91,12 @@ public Response listRoles(
9291
() -> {
9392
String[] names = accessControlManager.listRoleNames(metalake);
9493
names =
95-
Arrays.stream(names)
96-
.filter(
97-
role -> {
98-
NameIdentifier[] nameIdentifiers =
99-
new NameIdentifier[] {NameIdentifierUtil.ofRole(metalake, role)};
100-
return MetadataAuthzHelper.filterByExpression(
101-
metalake,
102-
AuthorizationExpressionConstants
103-
.loadRoleAuthorizationExpression,
104-
Entity.EntityType.ROLE,
105-
nameIdentifiers)
106-
.length
107-
> 0;
108-
})
109-
.collect(Collectors.toList())
110-
.toArray(new String[0]);
94+
MetadataAuthzHelper.filterByExpression(
95+
metalake,
96+
AuthorizationExpressionConstants.loadRoleAuthorizationExpression,
97+
Entity.EntityType.ROLE,
98+
names,
99+
roleName -> NameIdentifierUtil.ofRole(metalake, roleName));
111100
return Utils.ok(new NameListResponse(names));
112101
});
113102
} catch (Exception e) {

0 commit comments

Comments
 (0)