-
Notifications
You must be signed in to change notification settings - Fork 311
Implement a typechecking function in schema #2374
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
base: main
Are you sure you want to change the base?
Conversation
620c6e6
to
8a35625
Compare
definition resource { | ||
relation viewer: organization#member | ||
relation banned: user | ||
permission view = viewer - banned |
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.
So this raises an interesting question: the target subject types of view
here are technically user
and organization#member
, since you can issue a check for organization#member here. Question is: do we include that in this set?
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 think we do include it and make it required to be specified
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.
organization#member
is also a user
though (or, really, the set of things that are on the other end of that relation -- and here we have computed subtypes again). I'm okay with it being specified, 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.
Yeah, but its valid, so I think we should add it
…equire graph and there's an unrelated bug discovered
8a35625
to
3c06f92
Compare
} | ||
if rel.TypeInformation != nil { | ||
return ts.getTypesForInfo(ctx, defName, rel.TypeInformation, seen) | ||
} else if rel.UsersetRewrite != nil { |
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.
drop the else here, since all branches return
if err != nil { | ||
return nil, err | ||
} | ||
rel, ok := def.GetRelation(relationName) |
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.
newlines after if statements
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.
The wsl
linter does this for you 😄 https://github.com/bombsimon/wsl.
We should send a separate PR adding it
if dr.GetRelation() == ellipsesRelation { | ||
out.Add(dr.GetNamespace()) | ||
} else if dr.GetRelation() != "" { | ||
rest, err := ts.getTypesForRelationInternal(ctx, dr.GetNamespace(), dr.GetRelation(), seen) |
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.
you could pass out
to this call and then not need to create a new set every time
`, | ||
expected: map[string][]string{ | ||
"organization#member": {"user"}, | ||
"resource#viewer": {"user"}, |
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 should include organization#member
; please make sure the test captures if it is missing (not sure why it is succeeding right now)
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'm not sure I completely understand why it should.
The type of an organization#member
is a user, it's just the set of them; so if I combine direct users and then organization members, it's all users in the end, and the expected type of the viewer
permission is always user
.
That's what I'd expect, anyway; if there were types annotated after the permission name like:
permission view: user = org->member + viewer
as opposed to
permission view: organization#member + user = org->member + 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.
Sorry, I deleted my previous comment because it was wrong 😄
One use case for this work could be to warn people that their permission doesn't make sense because it will never ever return true
. For this use case I believe that you should not include organization#member
because it's not a terminal type.
E.g. if your permission is
relation aaa: user
relation bbb: organization#member
permission view = aaa & bbb
view
can return true for some users (if the user
is member of some organization)
However, if it was
relation aaa: user
relation bbb: apiKey
permission view = aaa & bbb
view
will never return true no matter what relationships you write.
The code of CheckPermission
API could have something like
if relation is intersection AND len(terminalTypes) != 1 {
return error("intersection will never lead to true, please rewrite it")
}
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 necessary because it is a valid subject type for the check, and for LS. The type annotation is indicating the types of allowed subjects, so it should be present.
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.
But we're not gonna use this code to validate the subject types for Check and LS, right?
require.Len(t, types, len(expected), rel) | ||
|
||
for _, typ := range types { | ||
require.Contains(t, expected, typ, fmt.Sprintf("expected %v to be in %v", typ, expected)) |
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.
Better to build a set of expected vs a set of actual and compare, to ensure none are missing either
Addressing the implementation part of #2371
Also opened a new issue stemming from the new
schema.Graph
object not covering all cases.