diff --git a/libs/git/repository.go b/libs/git/repository.go index 86d56a7fcf..6940ddac83 100644 --- a/libs/git/repository.go +++ b/libs/git/repository.go @@ -4,6 +4,7 @@ import ( "errors" "fmt" "io/fs" + "net/url" "path" "path/filepath" "strings" @@ -100,7 +101,22 @@ func (r *Repository) LatestCommit() (string, error) { // return origin url if it's defined, otherwise an empty string func (r *Repository) OriginUrl() string { - return r.config.variables["remote.origin.url"] + rawUrl := r.config.variables["remote.origin.url"] + + // Remove username and password from the URL. + parsedUrl, err := url.Parse(rawUrl) + if err != nil { + // Git supports https URLs and non standard URLs like "ssh://" or "file://". + // Parsing these URLs is not supported by the Go standard library. In case + // of an error, we return the raw URL. This is okay because for ssh URLs + // because passwords cannot be included in the URL. + return rawUrl + } + // Setting User to nil removes the username and password from the URL when + // .String() is called. + // See: https://pkg.go.dev/net/url#URL.String + parsedUrl.User = nil + return parsedUrl.String() } // loadConfig loads and combines user specific and repository specific configuration files. diff --git a/libs/git/repository_test.go b/libs/git/repository_test.go index 7ddc7ea792..a28038eebd 100644 --- a/libs/git/repository_test.go +++ b/libs/git/repository_test.go @@ -207,3 +207,9 @@ func TestRepositoryGitConfigWhenNotARepo(t *testing.T) { originUrl := repo.OriginUrl() assert.Equal(t, "", originUrl) } + +func TestRepositoryOriginUrlRemovesUserCreds(t *testing.T) { + repo := newTestRepository(t) + repo.addOriginUrl("https://username:token@github.com/databricks/foobar.git") + repo.assertOriginUrl("https://github.com/databricks/foobar.git") +}