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

Perforce paths should start with a forward slash#41972

Merged
pjlast merged 8 commits into
pjlast/41781-create-database-migrationsfrom
pjlast/41927-perforce-paths-should-start-with-a-forward-slash
Sep 23, 2022
Merged

Perforce paths should start with a forward slash#41972
pjlast merged 8 commits into
pjlast/41781-create-database-migrationsfrom
pjlast/41927-perforce-paths-should-start-with-a-forward-slash

Conversation

@pjlast

@pjlast pjlast commented Sep 23, 2022

Copy link
Copy Markdown
Contributor

Solves #41927

There is a bug in the gobwas/glob package we use where the file something.java cannot be matched to the path **/something.java. This is because **/something.java get's converted to a suffix of /something.java, which != something.java.

One solution is to prepend all file checks with a /, however this breaks another case:
We store all paths without forward slashes. So a path like dev/test/** then becomes unmatchable to /dev/test/some_test.java, due to the difference in forward slash at the front.

By ensuring that all paths and file matches start with a forward slash (i.e. being explicit about the root directory), this solves both cases.

Test plan

Updated unit tests. Added new unit tests

@sourcegraph-bot

sourcegraph-bot commented Sep 23, 2022

Copy link
Copy Markdown
Contributor

Codenotify: Notifying subscribers in CODENOTIFY files for diff f32c06d...3fc101d.

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 requested review from a team, mrnugget, ryanslade and sashaostrikov September 23, 2022 06:09
Comment on lines +345 to +347
if !strings.HasPrefix(rule, "/") {
rule = "/" + rule
}

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.

This is so that existing path rules get a leading slash when compiled (if they don't have one), so that we don't have to worry about migrations.

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 you can add a code comment here that explains this (because sooner or later someone will come along and think "don't we add these slashes when writing PathIncludes?")

Comment thread internal/authz/sub_repo_perms.go Outdated
// see one level of the tree at a time so we have no way of knowing which path leads
// to a file the user is allowed to see.
if strings.HasPrefix(rule, "*") {
if strings.HasPrefix(rule, "*") || strings.HasPrefix(rule, "/*") {

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.

We just have to check for both cases here, as we cannot be sure where this function is called (It's also possible to do the prefix adding above here)

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.

Can we instead make sure that the rule string starts with / as we do in other places? Would make the code follow the same convention everywhere.

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.

Yeah, I think that's better (hence my comment above). Only thought of it after working through my own PR. But now that I have a second opinion feeling the same, I'll add it

@pjlast pjlast linked an issue Sep 23, 2022 that may be closed by this pull request
@pjlast pjlast self-assigned this Sep 23, 2022
Comment thread internal/authz/sub_repo_perms.go Outdated
for {
lastSlash := strings.LastIndex(rule, "/")
if lastSlash == -1 {
if lastSlash <= 0 {

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.

Since all rules start with a slash now, the lastSlash index will never be -1, so we check for <= 0 instead. (i.e. it used to break on something.java, now it needs to break on /something.java

@mrnugget mrnugget 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.

Leaving final approval to everyone else, since I still miss too much context, but on the surface this looks good!

Comment on lines +345 to +347
if !strings.HasPrefix(rule, "/") {
rule = "/" + rule
}

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 you can add a code comment here that explains this (because sooner or later someone will come along and think "don't we add these slashes when writing PathIncludes?")

parsedLine.isExclusion = true // is an exclusion
parsedLine.match = parsedLine.match[1:] // trim leading -
parsedLine.isExclusion = true // is an exclusion
parsedLine.match = strings.TrimPrefix(parsedLine.match, "-") // trim leading -

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.

+1 for this change, love that it makes the code more explicit in intentions.

Comment on lines 504 to +507
s = strings.TrimPrefix(s, "//")
if !strings.HasPrefix(s, "/") {
s = "/" + s // make sure path starts with a '/'
}

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.

Instead of trimming the slashes from prefix and then adding them later, could we do some regex magic here? Or is this performance critical?

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.

It's pretty performance critical, especially now that we have to exhaust the entire list of rules to make sure we enforce them correctly.

But I'd say the fact that it's generally referred to as "regex magic" is the bigger deterrent for not using it, especially here where we want to be sure (and understand) what we're doing

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.

Haha, I read "regex magic" in my email inbox, put on my Batcape to come swooping in here and point at the "no magic!" sign on the wall and you beat me to it, Petri.

In all seriousness: I like how simple this is, so my vote goes for this, even if it can look a bit redundant.

Comment thread internal/authz/sub_repo_perms.go Outdated
// see one level of the tree at a time so we have no way of knowing which path leads
// to a file the user is allowed to see.
if strings.HasPrefix(rule, "*") {
if strings.HasPrefix(rule, "*") || strings.HasPrefix(rule, "/*") {

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.

Can we instead make sure that the rule string starts with / as we do in other places? Would make the code follow the same convention everywhere.

setSubRepositoryPermissionsForUsers(
repository: "UmVwb3NpdG9yeTox"
userPermissions: [{bindID: "alice", pathIncludes: ["*"], pathExcludes: ["*_test.go"]}]
userPermissions: [{bindID: "alice", pathIncludes: ["/*"], pathExcludes: ["/*_test.go"]}]

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.

Now that we always expect a / prefix, do we want to update this resolver to enforce that?

read group Rome * //depot/.../something.java ## Can read all files named 'something.java'
read group Rome * -//depot/dev/prodA/... ## Except files in this directory
`,
cannotReadAny: []string{"dev/prodA/something.java", "dev/prodA/another_dir/something.java"},

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.

Can we also confirm that it doesn't match these paths with leading slahes? For example /dev/prodA/something.java

@camdencheek

Copy link
Copy Markdown
Member

There is a bug in the gobwas/glob package we use

Should we open a patch for this upstream?

@pjlast

pjlast commented Sep 23, 2022

Copy link
Copy Markdown
Contributor Author

@camdencheek we could try. At this point I'm not 100% sure if it's a bug, or a misunderstanding (either from us, or from the package maintainer), because the package seems very solid with a vast array of test cases.

I can open an issue and see if they reply

@pjlast pjlast merged commit 7d3ab17 into pjlast/41781-create-database-migrations Sep 23, 2022
@pjlast pjlast deleted the pjlast/41927-perforce-paths-should-start-with-a-forward-slash branch September 23, 2022 14:29
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: paths should start with a forward slash

6 participants