Have perforce permissions enforced using the new column#41983
Conversation
…-slash' into pjlast/41788-perforce-permissions-use-paths-column
|
Codenotify: Notifying subscribers in CODENOTIFY files for diff b74f2e0...170becc.
|
| Paths: []string{"/**", "-/dev/*"}, | ||
| PathIncludes: []string{"**"}, |
There was a problem hiding this comment.
These have to be double stars. With just "*" as an include rule, anything in the /dev/ path could never have been matched anyways
| paths := make([]string, 0, len(perm.PathIncludes)+len(perm.PathExcludes)) | ||
| for _, include := range perm.PathIncludes { | ||
| if !strings.HasPrefix(include, "/") { // ensure leading slash | ||
| include = "/" + include | ||
| } | ||
| paths = append(paths, include) | ||
| } | ||
| for _, exclude := range perm.PathExcludes { | ||
| if !strings.HasPrefix(exclude, "/") { // ensure leading slash | ||
| exclude = "/" + exclude | ||
| } | ||
| paths = append(paths, "-"+exclude) // excludes start with a minus (-) | ||
| } |
There was a problem hiding this comment.
Should we keep the current resolver, mark it as deprecated, and introduce a new endpoint that only takes Paths?
The other option is to change the current endpoint, but I fear this could break some existing functionality if someone was relying on it.
There was a problem hiding this comment.
I think we should just add the new fields and deprecate the old fields but not remove them.
We may also want to document that the rules are enforced in order now.
| "sample": { | ||
| PathIncludes: []string{"*"}, | ||
| Paths: []string{"/**", "-/dev/*"}, | ||
| PathIncludes: []string{"**"}, | ||
| PathExcludes: []string{"/dev/*"}, | ||
| }, |
There was a problem hiding this comment.
What is the order of the rules if we still separate PathIncludes from PathExcludes in this definition?
There was a problem hiding this comment.
With PathIncludes and PathExcludes, excludes take preference. So for all conversions to only Paths, excludes are appended at the end so that they still take preference (by being the last applicable rule)
…-slash' into pjlast/41788-perforce-permissions-use-paths-column
ryanslade
left a comment
There was a problem hiding this comment.
Nice, I've gone through it a couple of times and LGTM!
| // Iterate through all rules for the current path, and the final match takes | ||
| // preference. |
There was a problem hiding this comment.
drive-by: can't you just go through the rules backwards and then break early? Or even keep the old implementation, but just reverse the list when perforce hands it over?
I doubt this changes the benchmark, but there is one for this code path. May be worth running and comparing just to ensure there are no surprises in this new impl.
There was a problem hiding this comment.
I recall thinking about this, but can't remember why I didn't go through with it. Definitely worth it, even if only out of principle. But the numbers will be interesting.
I will report back.
Storing it in reverse is probably best, as it removes an additional step during runtime, as long as it doesn't confuse anyone 🤔
There was a problem hiding this comment.
I also discarded the idea of working backwards... but now that I think it through again it seems to make sense. It's an easy change to make and we have some decent test coverage now which should help us with confidence.
Just to confirm what we're thinking about:
Walk the list of rules in reverse and the first match gives us our state. So if the fist match in the reversed list is an include rule, the path is included. If exclude rule, the path is excluded. If no matches, we default to exclude as the current code does.
There was a problem hiding this comment.
I think we should store in the original order and the for loop that iterates over it can be in reverse.
|
as long as it doesn't confuse anyone 🤔
Maybe move the matching logic into the compiledRules struct and
give a lovely long doc string explaining what it means to match a
rule.
Even better, have a well defined and typed meaning for the rules stored
in the DB, that perforce ensures it matches. Right now its a little bit
unsettling that when we fetch rules from the provider, we are
normalizing them/interpreting them as exclusions/etc. I would hope that
happens at another layer TBH. But I don't wanna derail stuff, can be
follow up work/discussion.
|
…as well, but check that either both of them are set, or paths is set
| var pathExcludes []string | ||
| if perm.Paths == nil { | ||
| paths = make([]string, 0, len(*perm.PathIncludes)+len(*perm.PathExcludes)) | ||
| pathIncludes = make([]string, 0, len(*perm.PathIncludes)) |
There was a problem hiding this comment.
Not sure if this might panic if perm.PathIncludes in nil? Same for the next line
There was a problem hiding this comment.
PathIncludes cannot be nil at this point, there is a check above this that would have caught it
| BindID string | ||
| PathIncludes []string | ||
| PathExcludes []string | ||
| PathIncludes *[]string |
There was a problem hiding this comment.
Do these have to be pointers? A slice is already a pointer and can be nil
There was a problem hiding this comment.
I honestly did not know this. This should simplify things somewhat, thanks!
There was a problem hiding this comment.
Yeah, our GraphQL uses pointers for "optional" params or nullable return values.
ryanslade
left a comment
There was a problem hiding this comment.
LGTM, just a couple of questions about possible nil panics
3fc101d
into
pjlast/41927-perforce-paths-should-start-with-a-forward-slash

Solves #41788
This PR makes all Perforce permissions application logic use the new
pathscolumn in thesub_repo_permissionstable. We have to iterate through the entire permissions list, and preference is given to the last applicable rule (as opposed to exclusions taking preference in the past).Test plan
Added new test cases, updated test cases.