diff --git a/applicationset/webhook/testdata/gitlab-event.json b/applicationset/webhook/testdata/gitlab-event.json index 83ac0b4fcb059..9371005e181e6 100644 --- a/applicationset/webhook/testdata/gitlab-event.json +++ b/applicationset/webhook/testdata/gitlab-event.json @@ -1,65 +1,65 @@ { - "object_kind": "push", - "event_name": "push", - "before": "e5ba5f6c13b64670048daa88e4c053d60b0e115a", - "after": "bb0748feaa336d841c251017e4e374c22d0c8a98", - "ref": "refs/heads/master", - "checkout_sha": "bb0748feaa336d841c251017e4e374c22d0c8a98", - "message": null, - "user_id": 1, - "user_name": "name", - "user_username": "username", - "user_email": "", - "user_avatar": "", - "project_id": 1, - "project": { - "id": 1, - "name": "project", - "description": "", - "web_url": "https://gitlab/group/name", - "avatar_url": null, - "git_ssh_url": "ssh://git@gitlab:2222/group/name.git", - "git_http_url": "https://gitlab/group/name.git", - "namespace": "group", - "visibility_level": 1, - "path_with_namespace": "group/name", - "default_branch": "master", - "ci_config_path": null, - "homepage": "https://gitlab/group/name", - "url": "ssh://git@gitlab:2222/group/name.git", - "ssh_url": "ssh://git@gitlab:2222/group/name.git", - "http_url": "https://gitlab/group/name.git" - }, - "commits": [ - { - "id": "bb0748feaa336d841c251017e4e374c22d0c8a98", - "message": "Test commit message\n", - "timestamp": "2020-01-06T03:47:55Z", - "url": "https://gitlab/group/name/commit/bb0748feaa336d841c251017e4e374c22d0c8a98", - "author": { - "name": "User", - "email": "user@example.com" - }, - "added": [ - "file.yaml" - ], - "modified": [ - ], - "removed": [ - - ] - } - ], - "total_commits_count": 1, - "push_options": { - }, - "repository": { - "name": "name", - "url": "ssh://git@gitlab:2222/group/name.git", - "description": "", - "homepage": "https://gitlab/group/name", - "git_http_url": "https://gitlab/group/name.git", - "git_ssh_url": "ssh://git@gitlab:2222/group/name.git", - "visibility_level": 10 + "object_kind": "push", + "event_name": "push", + "before": "e5ba5f6c13b64670048daa88e4c053d60b0e115a", + "after": "bb0748feaa336d841c251017e4e374c22d0c8a98", + "ref": "refs/heads/master", + "checkout_sha": "bb0748feaa336d841c251017e4e374c22d0c8a98", + "message": null, + "user_id": 1, + "user_name": "name", + "user_username": "username", + "user_email": "", + "user_avatar": "", + "project_id": 1, + "project": { + "id": 1, + "name": "project", + "description": "", + "web_url": "https://gitlab.com/group/name", + "avatar_url": null, + "git_ssh_url": "ssh://git@gitlab.com:2222/group/name.git", + "git_http_url": "https://gitlab.com/group/name.git", + "namespace": "group", + "visibility_level": 1, + "path_with_namespace": "group/name", + "default_branch": "master", + "ci_config_path": null, + "homepage": "https://gitlab.com/group/name", + "url": "ssh://git@gitlab.com:2222/group/name.git", + "ssh_url": "ssh://git@gitlab.com:2222/group/name.git", + "http_url": "https://gitlab.com/group/name.git" + }, + "commits": [ + { + "id": "bb0748feaa336d841c251017e4e374c22d0c8a98", + "message": "Test commit message\n", + "timestamp": "2020-01-06T03:47:55Z", + "url": "https://gitlab.com/group/name/commit/bb0748feaa336d841c251017e4e374c22d0c8a98", + "author": { + "name": "User", + "email": "user@example.com" + }, + "added": [ + "file.yaml" + ], + "modified": [ + ], + "removed": [ + + ] } - } \ No newline at end of file + ], + "total_commits_count": 1, + "push_options": { + }, + "repository": { + "name": "name", + "url": "ssh://git@gitlab.com:2222/group/name.git", + "description": "", + "homepage": "https://gitlab.com/group/name", + "git_http_url": "https://gitlab.com/group/name.git", + "git_ssh_url": "ssh://git@gitlab.com:2222/group/name.git", + "visibility_level": 10 + } +} diff --git a/applicationset/webhook/testdata/gitlab-merge-request-approval-event.json b/applicationset/webhook/testdata/gitlab-merge-request-approval-event.json index bef2fee493f5e..f7137298a1971 100644 --- a/applicationset/webhook/testdata/gitlab-merge-request-approval-event.json +++ b/applicationset/webhook/testdata/gitlab-merge-request-approval-event.json @@ -14,7 +14,7 @@ "description": "", "web_url": "https://gitlab.com/group/name", "avatar_url": null, - "git_ssh_url": "ssh://git@gitlab:2222/group/name.git", + "git_ssh_url": "ssh://git@gitlab.com:2222/group/name.git", "git_http_url": "https://gitlab.com/group/name.git", "namespace": "group", "visibility_level": 1, @@ -22,17 +22,17 @@ "default_branch": "master", "ci_config_path": null, "homepage": "https://gitlab.com/group/name", - "url": "ssh://git@gitlab:2222/group/name.git", - "ssh_url": "ssh://git@gitlab:2222/group/name.git", + "url": "ssh://git@gitlab.com:2222/group/name.git", + "ssh_url": "ssh://git@gitlab.com:2222/group/name.git", "http_url": "https://gitlab.com/group/name.git" }, "repository": { "name": "name", - "url": "ssh://git@gitlab:2222/group/name.git", + "url": "ssh://git@gitlab.com:2222/group/name.git", "description": "", "homepage": "https://gitlab.com/group/name", "git_http_url": "https://gitlab.com/group/name.git", - "git_ssh_url": "ssh://git@gitlab:2222/group/name.git", + "git_ssh_url": "ssh://git@gitlab.com:2222/group/name.git", "visibility_level": 10 }, "object_attributes": { @@ -60,7 +60,7 @@ "description": "Aut reprehenderit ut est.", "web_url": "https://gitlab.com/group/name", "avatar_url": null, - "git_ssh_url": "ssh://git@gitlab:2222/group/name.git", + "git_ssh_url": "ssh://git@gitlab.com:2222/group/name.git", "git_http_url": "https://gitlab.com/group/name.git", "namespace": "Awesome Space", "visibility_level": 20, @@ -68,7 +68,7 @@ "default_branch": "master", "homepage": "https://gitlab.com/group/name", "url": "https://gitlab.com/group/name.git", - "ssh_url": "ssh://git@gitlab:2222/group/name.git", + "ssh_url": "ssh://git@gitlab.com:2222/group/name.git", "http_url": "https://gitlab.com/group/name.git" }, "target": { @@ -76,7 +76,7 @@ "description": "Aut reprehenderit ut est.", "web_url": "https://gitlab.com/group/name", "avatar_url": null, - "git_ssh_url": "ssh://git@gitlab:2222/group/name.git", + "git_ssh_url": "ssh://git@gitlab.com:2222/group/name.git", "git_http_url": "https://gitlab.com/group/name.git", "namespace": "Awesome Space", "visibility_level": 20, @@ -84,7 +84,7 @@ "default_branch": "master", "homepage": "https://gitlab.com/group/name", "url": "https://gitlab.com/group/name.git", - "ssh_url": "ssh://git@gitlab:2222/group/name.git", + "ssh_url": "ssh://git@gitlab.com:2222/group/name.git", "http_url": "https://gitlab.com/group/name.git" }, "last_commit": { diff --git a/applicationset/webhook/testdata/gitlab-merge-request-open-event.json b/applicationset/webhook/testdata/gitlab-merge-request-open-event.json index e4e226a46dad6..953ac8d366b07 100644 --- a/applicationset/webhook/testdata/gitlab-merge-request-open-event.json +++ b/applicationset/webhook/testdata/gitlab-merge-request-open-event.json @@ -14,7 +14,7 @@ "description": "", "web_url": "https://gitlab.com/group/name", "avatar_url": null, - "git_ssh_url": "ssh://git@gitlab:2222/group/name.git", + "git_ssh_url": "ssh://git@gitlab.com:2222/group/name.git", "git_http_url": "https://gitlab.com/group/name.git", "namespace": "group", "visibility_level": 1, @@ -22,17 +22,17 @@ "default_branch": "master", "ci_config_path": null, "homepage": "https://gitlab.com/group/name", - "url": "ssh://git@gitlab:2222/group/name.git", - "ssh_url": "ssh://git@gitlab:2222/group/name.git", + "url": "ssh://git@gitlab.com:2222/group/name.git", + "ssh_url": "ssh://git@gitlab.com:2222/group/name.git", "http_url": "https://gitlab.com/group/name.git" }, "repository": { "name": "name", - "url": "ssh://git@gitlab:2222/group/name.git", + "url": "ssh://git@gitlab.com:2222/group/name.git", "description": "", "homepage": "https://gitlab.com/group/name", "git_http_url": "https://gitlab.com/group/name.git", - "git_ssh_url": "ssh://git@gitlab:2222/group/name.git", + "git_ssh_url": "ssh://git@gitlab.com:2222/group/name.git", "visibility_level": 10 }, "object_attributes": { @@ -60,7 +60,7 @@ "description": "Aut reprehenderit ut est.", "web_url": "https://gitlab.com/group/name", "avatar_url": null, - "git_ssh_url": "ssh://git@gitlab:2222/group/name.git", + "git_ssh_url": "ssh://git@gitlab.com:2222/group/name.git", "git_http_url": "https://gitlab.com/group/name.git", "namespace": "Awesome Space", "visibility_level": 20, @@ -68,7 +68,7 @@ "default_branch": "master", "homepage": "https://gitlab.com/group/name", "url": "https://gitlab.com/group/name.git", - "ssh_url": "ssh://git@gitlab:2222/group/name.git", + "ssh_url": "ssh://git@gitlab.com:2222/group/name.git", "http_url": "https://gitlab.com/group/name.git" }, "target": { @@ -76,7 +76,7 @@ "description": "Aut reprehenderit ut est.", "web_url": "https://gitlab.com/group/name", "avatar_url": null, - "git_ssh_url": "ssh://git@gitlab:2222/group/name.git", + "git_ssh_url": "ssh://git@gitlab.com:2222/group/name.git", "git_http_url": "https://gitlab.com/group/name.git", "namespace": "Awesome Space", "visibility_level": 20, @@ -84,7 +84,7 @@ "default_branch": "master", "homepage": "https://gitlab.com/group/name", "url": "https://gitlab.com/group/name.git", - "ssh_url": "ssh://git@gitlab:2222/group/name.git", + "ssh_url": "ssh://git@gitlab.com:2222/group/name.git", "http_url": "https://gitlab.com/group/name.git" }, "last_commit": { diff --git a/applicationset/webhook/webhook.go b/applicationset/webhook/webhook.go index 474c32e591046..d032b4beedaf7 100644 --- a/applicationset/webhook/webhook.go +++ b/applicationset/webhook/webhook.go @@ -217,13 +217,7 @@ func getGitGeneratorInfo(payload any) *gitGeneratorInfo { } log.Infof("Received push event repo: %s, revision: %s, touchedHead: %v", webURL, revision, touchedHead) - urlObj, err := url.Parse(webURL) - if err != nil { - log.Errorf("Failed to parse repoURL '%s'", webURL) - return nil - } - regexpStr := `(?i)(http://|https://|\w+@|ssh://(\w+@)?)` + urlObj.Hostname() + "(:[0-9]+|)[:/]" + urlObj.Path[1:] + "(\\.git)?$" - repoRegexp, err := regexp.Compile(regexpStr) + repoRegexp, err := webhook.GetWebUrlRegex(webURL) if err != nil { log.Errorf("Failed to compile regexp for repoURL '%s'", webURL) return nil @@ -245,13 +239,7 @@ func getPRGeneratorInfo(payload any) *prGeneratorInfo { } apiURL := payload.Repository.URL - urlObj, err := url.Parse(apiURL) - if err != nil { - log.Errorf("Failed to parse repoURL '%s'", apiURL) - return nil - } - regexpStr := `(?i)(http://|https://|\w+@|ssh://(\w+@)?)` + urlObj.Hostname() + "(:[0-9]+|)[:/]" - apiRegexp, err := regexp.Compile(regexpStr) + apiRegexp, err := webhook.GetApiUrlRegex(apiURL) if err != nil { log.Errorf("Failed to compile regexp for repoURL '%s'", apiURL) return nil diff --git a/applicationset/webhook/webhook_test.go b/applicationset/webhook/webhook_test.go index 991af2dd22c51..5c5721798974a 100644 --- a/applicationset/webhook/webhook_test.go +++ b/applicationset/webhook/webhook_test.go @@ -63,7 +63,7 @@ func TestWebhookHandler(t *testing.T) { headerKey: "X-GitHub-Event", headerValue: "push", payloadFile: "github-commit-event.json", - effectedAppSets: []string{"git-github", "matrix-git-github", "merge-git-github", "matrix-scm-git-github", "matrix-nested-git-github", "merge-nested-git-github", "plugin", "matrix-pull-request-github-plugin"}, + effectedAppSets: []string{"git-github", "git-github-ssh", "git-github-alt-ssh", "matrix-git-github", "merge-git-github", "matrix-scm-git-github", "matrix-nested-git-github", "merge-nested-git-github", "plugin", "matrix-pull-request-github-plugin"}, expectedStatusCode: http.StatusOK, expectedRefresh: true, }, @@ -81,7 +81,7 @@ func TestWebhookHandler(t *testing.T) { headerKey: "X-GitHub-Event", headerValue: "push", payloadFile: "github-commit-branch-event.json", - effectedAppSets: []string{"git-github", "plugin", "matrix-pull-request-github-plugin"}, + effectedAppSets: []string{"git-github", "git-github-ssh", "git-github-alt-ssh", "plugin", "matrix-pull-request-github-plugin"}, expectedStatusCode: http.StatusOK, expectedRefresh: true, }, @@ -90,7 +90,7 @@ func TestWebhookHandler(t *testing.T) { headerKey: "X-GitHub-Event", headerValue: "ping", payloadFile: "github-ping-event.json", - effectedAppSets: []string{"git-github", "plugin"}, + effectedAppSets: []string{"git-github", "git-github-ssh", "git-github-alt-ssh", "plugin"}, expectedStatusCode: http.StatusOK, expectedRefresh: false, }, @@ -99,7 +99,7 @@ func TestWebhookHandler(t *testing.T) { headerKey: "X-Gitlab-Event", headerValue: "Push Hook", payloadFile: "gitlab-event.json", - effectedAppSets: []string{"git-gitlab", "plugin", "matrix-pull-request-github-plugin"}, + effectedAppSets: []string{"git-gitlab", "git-gitlab-ssh", "git-gitlab-alt-ssh", "plugin", "matrix-pull-request-github-plugin"}, expectedStatusCode: http.StatusOK, expectedRefresh: true, }, @@ -108,7 +108,7 @@ func TestWebhookHandler(t *testing.T) { headerKey: "X-Gitlab-Event", headerValue: "System Hook", payloadFile: "gitlab-event.json", - effectedAppSets: []string{"git-gitlab", "plugin", "matrix-pull-request-github-plugin"}, + effectedAppSets: []string{"git-gitlab", "git-gitlab-ssh", "git-gitlab-alt-ssh", "plugin", "matrix-pull-request-github-plugin"}, expectedStatusCode: http.StatusOK, expectedRefresh: true, }, @@ -117,7 +117,7 @@ func TestWebhookHandler(t *testing.T) { headerKey: "X-Random-Event", headerValue: "Push Hook", payloadFile: "gitlab-event.json", - effectedAppSets: []string{"git-gitlab", "plugin"}, + effectedAppSets: []string{"git-gitlab", "git-gitlab-ssh", "git-gitlab-alt-ssh", "plugin"}, expectedStatusCode: http.StatusBadRequest, expectedRefresh: false, }, @@ -126,7 +126,7 @@ func TestWebhookHandler(t *testing.T) { headerKey: "X-Random-Event", headerValue: "Push Hook", payloadFile: "invalid-event.json", - effectedAppSets: []string{"git-gitlab", "plugin"}, + effectedAppSets: []string{"git-gitlab", "git-gitlab-ssh", "git-gitlab-alt-ssh", "plugin"}, expectedStatusCode: http.StatusBadRequest, expectedRefresh: false, }, @@ -209,7 +209,11 @@ func TestWebhookHandler(t *testing.T) { fc := fake.NewClientBuilder().WithScheme(scheme).WithObjects( fakeAppWithGitGenerator("git-github", namespace, "https://github.com/org/repo"), fakeAppWithGitGenerator("git-github-copy", namespace, "https://github.com/org/repo-copy"), - fakeAppWithGitGenerator("git-gitlab", namespace, "https://gitlab/group/name"), + fakeAppWithGitGenerator("git-github-ssh", namespace, "ssh://git@github.com/org/repo"), + fakeAppWithGitGenerator("git-github-alt-ssh", namespace, "ssh://git@ssh.github.com:443/org/repo"), + fakeAppWithGitGenerator("git-gitlab", namespace, "https://gitlab.com/group/name"), + fakeAppWithGitGenerator("git-gitlab-ssh", namespace, "ssh://git@gitlab.com/group/name"), + fakeAppWithGitGenerator("git-gitlab-alt-ssh", namespace, "ssh://git@altssh.gitlab.com:443/group/name"), fakeAppWithGitGenerator("git-azure-devops", namespace, "https://dev.azure.com/fabrikam-fiber-inc/DefaultCollection/_git/Fabrikam-Fiber-Git"), fakeAppWithGitGeneratorWithRevision("github-shorthand", namespace, "https://github.com/org/repo", "env/dev"), fakeAppWithGithubPullRequestGenerator("pull-request-github", namespace, "CodErTOcat", "Hello-World"), diff --git a/util/webhook/testdata/gitlab-event.json b/util/webhook/testdata/gitlab-event.json index bede10363a1e1..9371005e181e6 100644 --- a/util/webhook/testdata/gitlab-event.json +++ b/util/webhook/testdata/gitlab-event.json @@ -16,26 +16,26 @@ "id": 1, "name": "project", "description": "", - "web_url": "https://gitlab/group/name", + "web_url": "https://gitlab.com/group/name", "avatar_url": null, - "git_ssh_url": "ssh://git@gitlab:2222/group/name.git", - "git_http_url": "https://gitlab/group/name.git", + "git_ssh_url": "ssh://git@gitlab.com:2222/group/name.git", + "git_http_url": "https://gitlab.com/group/name.git", "namespace": "group", "visibility_level": 1, "path_with_namespace": "group/name", "default_branch": "master", "ci_config_path": null, - "homepage": "https://gitlab/group/name", - "url": "ssh://git@gitlab:2222/group/name.git", - "ssh_url": "ssh://git@gitlab:2222/group/name.git", - "http_url": "https://gitlab/group/name.git" + "homepage": "https://gitlab.com/group/name", + "url": "ssh://git@gitlab.com:2222/group/name.git", + "ssh_url": "ssh://git@gitlab.com:2222/group/name.git", + "http_url": "https://gitlab.com/group/name.git" }, "commits": [ { "id": "bb0748feaa336d841c251017e4e374c22d0c8a98", "message": "Test commit message\n", "timestamp": "2020-01-06T03:47:55Z", - "url": "https://gitlab/group/name/commit/bb0748feaa336d841c251017e4e374c22d0c8a98", + "url": "https://gitlab.com/group/name/commit/bb0748feaa336d841c251017e4e374c22d0c8a98", "author": { "name": "User", "email": "user@example.com" @@ -55,11 +55,11 @@ }, "repository": { "name": "name", - "url": "ssh://git@gitlab:2222/group/name.git", + "url": "ssh://git@gitlab.com:2222/group/name.git", "description": "", - "homepage": "https://gitlab/group/name", - "git_http_url": "https://gitlab/group/name.git", - "git_ssh_url": "ssh://git@gitlab:2222/group/name.git", + "homepage": "https://gitlab.com/group/name", + "git_http_url": "https://gitlab.com/group/name.git", + "git_ssh_url": "ssh://git@gitlab.com:2222/group/name.git", "visibility_level": 10 } -} \ No newline at end of file +} diff --git a/util/webhook/webhook.go b/util/webhook/webhook.go index 0795ac6aec9d5..9c847fc445f20 100644 --- a/util/webhook/webhook.go +++ b/util/webhook/webhook.go @@ -41,7 +41,7 @@ type settingsSource interface { // https://www.rfc-editor.org/rfc/rfc3986#section-3.2.1 // https://github.com/shadow-maint/shadow/blob/master/libmisc/chkname.c#L36 -const usernameRegex = `[a-zA-Z0-9_\.][a-zA-Z0-9_\.-]{0,30}[a-zA-Z0-9_\.\$-]?` +const usernameRegex = `[\w\.][\w\.-]{0,30}[\w\.\$-]?` const payloadQueueSize = 50000 @@ -300,7 +300,7 @@ func (a *ArgoCDWebhookHandler) HandleEvent(payload any) { } for _, webURL := range webURLs { - repoRegexp, err := getWebUrlRegex(webURL) + repoRegexp, err := GetWebUrlRegex(webURL) if err != nil { log.Warnf("Failed to get repoRegexp: %s", err) continue @@ -329,21 +329,42 @@ func (a *ArgoCDWebhookHandler) HandleEvent(payload any) { } } -// getWebUrlRegex compiles a regex that will match any targetRevision referring to the same repo as the given webURL. +// GetWebUrlRegex compiles a regex that will match any targetRevision referring to the same repo as the given webURL. // webURL is expected to be a URL from an SCM webhook payload pointing to the web page for the repo. -func getWebUrlRegex(webURL string) (*regexp.Regexp, error) { - urlObj, err := url.Parse(webURL) +func GetWebUrlRegex(webURL string) (*regexp.Regexp, error) { + // 1. Optional: protocol (`http`, `https`, or `ssh`) followed by `://` + // 2. Optional: username followed by `@` + // 3. Optional: `ssh` or `altssh` subdomain + // 4. Required: hostname parsed from `webURL` + // 5. Optional: `:` followed by port number + // 6. Required: `:` or `/` + // 7. Required: path parsed from `webURL` + // 8. Optional: `.git` extension + return getUrlRegex(webURL, `(?i)^((https?|ssh)://)?(%[1]s@)?((alt)?ssh\.)?%[2]s(:\d+)?[:/]%[3]s(\.git)?$`) +} + +// GetApiUrlRegex compiles a regex that will match any targetRevision referring to the same repo as the given apiURL. +func GetApiUrlRegex(apiURL string) (*regexp.Regexp, error) { + // 1. Optional: protocol (`http` or `https`) followed by `://` + // 2. Optional: username followed by `@` + // 3. Required: hostname parsed from `webURL` + // 4. Optional: `:` followed by port number + // 5. Optional: `/` + return getUrlRegex(apiURL, `(?i)^(https?://)?(%[1]s@)?%[2]s(:\d+)?/?$`) +} + +func getUrlRegex(originalURL string, regexpFormat string) (*regexp.Regexp, error) { + urlObj, err := url.Parse(originalURL) if err != nil { - return nil, fmt.Errorf("failed to parse repoURL '%s'", webURL) + return nil, fmt.Errorf("failed to parse URL '%s'", originalURL) } regexEscapedHostname := regexp.QuoteMeta(urlObj.Hostname()) regexEscapedPath := regexp.QuoteMeta(urlObj.EscapedPath()[1:]) - regexpStr := fmt.Sprintf(`(?i)^(http://|https://|%s@|ssh://(%s@)?)%s(:[0-9]+|)[:/]%s(\.git)?$`, - usernameRegex, usernameRegex, regexEscapedHostname, regexEscapedPath) + regexpStr := fmt.Sprintf(regexpFormat, usernameRegex, regexEscapedHostname, regexEscapedPath) repoRegexp, err := regexp.Compile(regexpStr) if err != nil { - return nil, fmt.Errorf("failed to compile regexp for repoURL '%s'", webURL) + return nil, fmt.Errorf("failed to compile regexp for URL '%s'", originalURL) } return repoRegexp, nil diff --git a/util/webhook/webhook_test.go b/util/webhook/webhook_test.go index 41f8cc039dca9..633ca8fee5a0e 100644 --- a/util/webhook/webhook_test.go +++ b/util/webhook/webhook_test.go @@ -379,7 +379,7 @@ func TestGitLabPushEvent(t *testing.T) { close(h.queue) h.Wait() assert.Equal(t, http.StatusOK, w.Code) - expectedLogResult := "Received push event repo: https://gitlab/group/name, revision: master, touchedHead: true" + expectedLogResult := "Received push event repo: https://gitlab.com/group/name, revision: master, touchedHead: true" assert.Equal(t, expectedLogResult, hook.LastEntry().Message) hook.Reset() } @@ -397,7 +397,7 @@ func TestGitLabSystemEvent(t *testing.T) { close(h.queue) h.Wait() assert.Equal(t, http.StatusOK, w.Code) - expectedLogResult := "Received push event repo: https://gitlab/group/name, revision: master, touchedHead: true" + expectedLogResult := "Received push event repo: https://gitlab.com/group/name, revision: master, touchedHead: true" assert.Equal(t, expectedLogResult, hook.LastEntry().Message) hook.Reset() } @@ -603,7 +603,7 @@ func Test_affectedRevisionInfo_appRevisionHasChanged(t *testing.T) { } } -func Test_getWebUrlRegex(t *testing.T) { +func Test_GetWebUrlRegex(t *testing.T) { tests := []struct { shouldMatch bool webURL string @@ -619,24 +619,73 @@ func Test_getWebUrlRegex(t *testing.T) { {false, "https://example.com/org/repo", "https://example.com/org/repo-2", "partial match should not match"}, {true, "https://example.com/org/repo", "https://example.com/org/repo.git", "no .git should match with .git"}, {true, "https://example.com/org/repo", "git@example.com:org/repo", "git without protocol should match"}, - {true, "https://example.com/org/repo", "user@example.com:org/repo", "git with non-git username shout match"}, + {true, "https://example.com/org/repo", "user@example.com:org/repo", "git with non-git username should match"}, {true, "https://example.com/org/repo", "ssh://git@example.com/org/repo", "git with protocol should match"}, {true, "https://example.com/org/repo", "ssh://git@example.com:22/org/repo", "git with port number should match"}, {true, "https://example.com:443/org/repo", "ssh://git@example.com:22/org/repo", "https and ssh w/ different port numbers should match"}, + {true, "https://example.com:443/org/repo", "ssh://git@ssh.example.com:443/org/repo", "https and ssh w/ ssh subdomain should match"}, + {true, "https://example.com:443/org/repo", "ssh://git@altssh.example.com:443/org/repo", "https and ssh w/ altssh subdomain should match"}, + {false, "https://example.com:443/org/repo", "ssh://git@unknown.example.com:443/org/repo", "https and ssh w/ unknown subdomain should not match"}, {true, "https://example.com/org/repo", "ssh://user-name@example.com/org/repo", "valid usernames with hyphens in repo should match"}, {false, "https://example.com/org/repo", "ssh://-user-name@example.com/org/repo", "invalid usernames with hyphens in repo should not match"}, {true, "https://example.com:443/org/repo", "GIT@EXAMPLE.COM:22:ORG/REPO", "matches aren't case-sensitive"}, {true, "https://example.com/org/repo%20", "https://example.com/org/repo%20", "escape codes in path are preserved"}, + {true, "https://user@example.com/org/repo", "http://example.com/org/repo", "https+username should match http"}, + {true, "https://user@example.com/org/repo", "https://example.com/org/repo", "https+username should match https"}, + {true, "http://example.com/org/repo", "https://user@example.com/org/repo", "http should match https+username"}, + {true, "https://example.com/org/repo", "https://user@example.com/org/repo", "https should match https+username"}, + {true, "https://user@example.com/org/repo", "ssh://example.com/org/repo", "https+username should match ssh"}, } + for _, testCase := range tests { testCopy := testCase t.Run(testCopy.name, func(t *testing.T) { t.Parallel() - regexp, err := getWebUrlRegex(testCopy.webURL) + regexp, err := GetWebUrlRegex(testCopy.webURL) require.NoError(t, err) assert.Equal(t, regexp.MatchString(testCopy.repo), testCopy.shouldMatch, "sourceRevisionHasChanged()") }) } + + t.Run("bad URL should error", func(t *testing.T) { + _, err := GetWebUrlRegex("%%") + require.Error(t, err) + }) +} + +func Test_GetApiUrlRegex(t *testing.T) { + tests := []struct { + shouldMatch bool + apiURL string + repo string + name string + }{ + // Ensure input is regex-escaped. + {false, "https://an.example.com/", "https://an-example.com/", "dots in domain names should not be treated as wildcards"}, + + // Standard cases. + {true, "https://example.com/", "https://example.com/", "exact match should match"}, + {false, "https://example.com/", "ssh://example.com/", "should not match ssh"}, + {true, "https://user@example.com/", "http://example.com/", "https+username should match http"}, + {true, "https://user@example.com/", "https://example.com/", "https+username should match https"}, + {true, "http://example.com/", "https://user@example.com/", "http should match https+username"}, + {true, "https://example.com/", "https://user@example.com/", "https should match https+username"}, + } + + for _, testCase := range tests { + testCopy := testCase + t.Run(testCopy.name, func(t *testing.T) { + t.Parallel() + regexp, err := GetApiUrlRegex(testCopy.apiURL) + require.NoError(t, err) + assert.Equal(t, regexp.MatchString(testCopy.repo), testCopy.shouldMatch, "sourceRevisionHasChanged()") + }) + } + + t.Run("bad URL should error", func(t *testing.T) { + _, err := GetApiUrlRegex("%%") + require.Error(t, err) + }) } func TestGitHubCommitEventMaxPayloadSize(t *testing.T) {