-
Notifications
You must be signed in to change notification settings - Fork 246
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 ExperimentalComputablePermissions API #1894
Add ExperimentalComputablePermissions API #1894
Conversation
151a55e
to
c1f0fb2
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM overall, the only potential blocker I see is lack of tests and mitigation for schema recursion. I'd also like to see us supporting batched calls to both ComputablePermissions and DependentRelations, as I think that could be desirable for scenarios where you want to use these APIs for denormalization purposes.
expectedError: "relation/permission `invalid` not found", | ||
}, | ||
{ | ||
name: "basic", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
While I do understand this expected response from the perspective of the reachability graph (user:...
), it seems inconsistent for an API called ExperimentalComputablePermissions
. I wouldn't expect this to return relations, and so it also wouldn't make sense the API has a field IsPermission
.
It's not the same with ExperimentalDependentRelations
because the name of the RPC explicitly states "Relations" so it fits both relations and permissions.
The options that come to mind are:
- create a type
ExPermissionReference
that drops that field, and filter for permissions in the controller - rename the RPC to something like
ExperimentalComputableRelations
as it could return both.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I left it named permissions because that's how people will primarily use it; we could rename it, but I felt it was more discoverable that way. Both functions return both.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It could confuse folks, but it's not a big deal anyway, just my 2 cents
"...", | ||
|
||
[]string{"document#view", "document#viewer"}, | ||
}, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
add test that uses subject relation with a computed userset
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We have one though?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
oh I may missed it, just to be clear, something like relation members: team#members
where members is a permission
|
||
[]string{"document#view", "document#viewer"}, | ||
}, | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
also add test where there is recursion in the schema. Also add to the other API tests
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We have one; a group refers to its own members
|
||
subjectTypesToCheck := []*core.RelationReference{startingSubjectType} | ||
|
||
// TODO(jschorr): optimize this to not require walking over all types recursively. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We may want to add some sort of max depth to prevent infinite recursion that could happen via the schema? Perhaps adding a context deadline if this is taking too long as a precaution?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is a structural walk, not a a data-driven one; there should be no case where it causes infinite recursion as the check below reduces the working set over time
// RelationsEncounteredForSubject returns all relations that are encountered when walking outward from a subject+relation. | ||
func (rg *ReachabilityGraph) RelationsEncounteredForSubject( | ||
ctx context.Context, | ||
allDefinitions []*core.NamespaceDefinition, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: does this need to be "all definitions" or it could be any subset? The argument name would invite to think it has to be provided with all namespaces in the instance
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Its everything
return nil, err | ||
} | ||
|
||
nrg := ReachabilityGraphFor(&ValidatedNamespaceTypeSystem{nts}) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: shouldn't TypeSystemForNamespace
return a ValidatedNamespaceTypeSystem
then?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No; we know (internally here) that it is already validated but if the type system was loaded from memory, it may not have been validated yet
No description provided.