Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add AggregationStorePermissionExecutor #2086

Merged
merged 7 commits into from
May 14, 2021

Conversation

Chandrasekar-Rajasekar
Copy link
Collaborator

Resolves #2048

Description

Add AggregationStorePermissionExecutor for all models managed by Aggregation Datastore

License

I confirm that this contribution is made under an Apache 2.0 license and that I have the authority necessary to make this contribution on behalf of its copyright owner.

public <A extends Annotation> ExpressionResult checkPermission(Class<A> annotationClass,
PersistentResource resource,
Set<String> requestedFields) {
return ExpressionResult.PASS;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This would be cleaner if you check user checks on the requested fields for the requested resource.

ChangeSpec changeSpec,
Class<A> annotationClass,
String field) {
return null;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How about throwing UnsupportedOperationException here?

*/
public FilterExpression buildEntityFilterExpression(Type<?> forType, RequestScope requestScope) {
Class<? extends Annotation> annotationClass = ReadPermission.class;
ParseTree classPermissions = entityDictionary.getPermissionsForClass(forType, annotationClass);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

YOu can combine this line and the one above.

Class<A> annotationClass,
Set<String> requestedFields) {
Supplier<Expression> expressionSupplier = () ->
expressionBuilder.buildUserCheckAnyExpression(
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This needs to change to match the RFC

(entityRule AND (field1Rule OR field2Rule ... OR fieldNRule)

@Override
public <A extends Annotation> ExpressionResult checkPermission(Class<A> annotationClass,
PersistentResource resource,
Set<String> requestedFields) {
return ExpressionResult.PASS;
Expression expression = expressionBuilder.buildUserCheckAnyExpression(
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we add a Preconditions check or maybe return FAIL if annotationClass is anything other than a ReadPermission for all of these checks?

ParseTree classPermissions = entityDictionary.getPermissionsForClass(resourceClass, annotationClass);
Expression entityExpression = normalizedExpressionFromParseTree(classPermissions, leafBuilderFn);

Expression anyFiledExpression = buildAnyFieldExpression(
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

anyField instead of anyFiled.

requestedFields,
requestScope);

return executeExpressions(expression, annotationClass, Expression.EvaluationMode.ALL_CHECKS);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should actually call checkPermissions with expressionExecutor set to Optional.empty(). That's how user only checks are evaluated.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Alternatively, call checkOnlyUserPermissions like elsewhere in this file.

return checkOnlyUserPermissions(
resourceClass,
annotationClass,
Optional.empty(),
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I found a bug in the user check cache in Elide 5. The user check cache will look at either one field or no fields (this case). However, this check could be called multiple times with different fields. We really ought to make the cache always map to a set of requested fields. Optional.empty() isn't right here, but we can't do the right thing until this bug is fixed.


// evaluated expression = (user none or filter check)
Assertions.assertEquals(
ExpressionResult.DEFERRED,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This doesn't seem right to me. The filter check should never apply at the field level.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The field level check should not inherit the entity level check here.


// evaluated expression = (user none or filter check) AND (user all OR user none)
Assertions.assertEquals(
ExpressionResult.DEFERRED,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure this tests makes sense either. Let's discuss. I don't think DEFERRED is a valid return scenario.

com.yahoo.elide.core.RequestScope scope = bindAndgetRequestScope(Model1.class);
PermissionExecutor executor = scope.getPermissionExecutor();

FilterExpression expression = executor.getReadPermissionFilter(ClassType.of(Model1.class), Collections.emptySet()).orElse(null);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

To make these tests realistic, the set of requested fields should not be empty - but rather set to the all the fields.

return ExpressionResult.FAIL;
}

Expression expression = expressionBuilder.buildUserCheckAnyExpression(
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure this is what you want here from the Permission Builder. UserCheckAnyExpression will look at a combination of field and entity for each field.

Assertions.assertEquals(
ExpressionResult.DEFERRED,
ExpressionResult.PASS,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Shouldn't this be FAIL?

@@ -130,6 +129,13 @@ public long getMetric() {
new PersistentResource(new Model("dim1", 0, 1), "1", scope),
new HashSet<>(Arrays.asList("filterDim", "metric"))));

// evaluated expression = (user none OR null)
Assertions.assertEquals(
ExpressionResult.PASS,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Shouldn't this be FAIL?

@aklish aklish merged commit b75011e into master May 14, 2021
@aklish aklish deleted the AggregationStorePermissionExecutor branch May 14, 2021 22:52
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

RFC: Aggregation Store Security Rules
2 participants