Skip to content
This repository was archived by the owner on Sep 30, 2024. It is now read-only.

Have perforce permissions enforced using the new column#41983

Merged
pjlast merged 13 commits into
pjlast/41927-perforce-paths-should-start-with-a-forward-slashfrom
pjlast/41788-perforce-permissions-use-paths-column
Sep 23, 2022
Merged

Have perforce permissions enforced using the new column#41983
pjlast merged 13 commits into
pjlast/41927-perforce-paths-should-start-with-a-forward-slashfrom
pjlast/41788-perforce-permissions-use-paths-column

Conversation

@pjlast

@pjlast pjlast commented Sep 23, 2022

Copy link
Copy Markdown
Contributor

Solves #41788

This PR makes all Perforce permissions application logic use the new paths column in the sub_repo_permissions table. 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.

@cla-bot cla-bot Bot added the cla-signed label Sep 23, 2022
…-slash' into pjlast/41788-perforce-permissions-use-paths-column
@pjlast pjlast linked an issue Sep 23, 2022 that may be closed by this pull request
@sourcegraph-bot

sourcegraph-bot commented Sep 23, 2022

Copy link
Copy Markdown
Contributor

Codenotify: Notifying subscribers in CODENOTIFY files for diff b74f2e0...170becc.

Notify File(s)
@beyang internal/search/symbol/symbol_test.go
@camdencheek internal/search/symbol/symbol_test.go
@indradhanush enterprise/cmd/repo-updater/internal/authz/perms_syncer_test.go
@keegancsmith internal/search/symbol/symbol_test.go
@unknwon enterprise/cmd/frontend/internal/authz/resolvers/resolver.go
enterprise/cmd/frontend/internal/authz/resolvers/resolver_test.go
enterprise/cmd/repo-updater/internal/authz/perms_syncer_test.go
enterprise/internal/authz/perforce/cmd/scanprotects/main.go
enterprise/internal/authz/perforce/cmd/scanprotects/main_test.go
enterprise/internal/authz/perforce/perforce_test.go
enterprise/internal/authz/perforce/protects.go
enterprise/internal/authz/perforce/protects_test.go
internal/authz/iface.go
internal/authz/sub_repo_perms.go
internal/authz/sub_repo_perms_test.go

@pjlast pjlast self-assigned this Sep 23, 2022
@pjlast pjlast requested review from a team, mrnugget, ryanslade and sashaostrikov September 23, 2022 09:17
Comment thread internal/authz/sub_repo_perms_test.go Outdated
Comment on lines +129 to +130
Paths: []string{"/**", "-/dev/*"},
PathIncludes: []string{"**"},

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

These have to be double stars. With just "*" as an include rule, anything in the /dev/ path could never have been matched anyways

Comment on lines +257 to +269
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 (-)
}

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

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.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

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.

Comment on lines 128 to 132
"sample": {
PathIncludes: []string{"*"},
Paths: []string{"/**", "-/dev/*"},
PathIncludes: []string{"**"},
PathExcludes: []string{"/dev/*"},
},

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

What is the order of the rules if we still separate PathIncludes from PathExcludes in this definition?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

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)

Comment thread enterprise/internal/authz/perforce/protects.go Outdated

@ryanslade ryanslade left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Nice, I've gone through it a couple of times and LGTM!

Comment on lines +287 to +288
// Iterate through all rules for the current path, and the final match takes
// preference.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

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.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

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 🤔

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

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.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

I think we should store in the original order and the for loop that iterates over it can be in reverse.

@keegancsmith

keegancsmith commented Sep 23, 2022 via email

Copy link
Copy Markdown
Member

var pathExcludes []string
if perm.Paths == nil {
paths = make([]string, 0, len(*perm.PathIncludes)+len(*perm.PathExcludes))
pathIncludes = make([]string, 0, len(*perm.PathIncludes))

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Not sure if this might panic if perm.PathIncludes in nil? Same for the next line

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

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

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Do these have to be pointers? A slice is already a pointer and can be nil

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

I honestly did not know this. This should simplify things somewhat, thanks!

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

image

GraphQL does not seem to agree

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Yeah, our GraphQL uses pointers for "optional" params or nullable return values.

@ryanslade ryanslade left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

LGTM, just a couple of questions about possible nil panics

@pjlast pjlast merged commit 3fc101d into pjlast/41927-perforce-paths-should-start-with-a-forward-slash Sep 23, 2022
@pjlast pjlast deleted the pjlast/41788-perforce-permissions-use-paths-column branch September 23, 2022 13:57
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Perforce: change permission applications to use paths column

6 participants