From 352bbedfbf385c69b22c13f0e53dcb14dabd1baa Mon Sep 17 00:00:00 2001 From: JSNortal <124635010+JSNortal@users.noreply.github.com> Date: Mon, 25 Sep 2023 20:53:06 +0100 Subject: [PATCH] fix: issue with GH App credential not writing if lines already exist (#3679) * Fix issue with GH App credential not writing if lines already exist * Fix lint issue of unused variable. --------- Co-authored-by: PePe Amengual Co-authored-by: Dylan Page --- server/events/vcs/git_cred_writer.go | 34 ++++++++++++++++++++--- server/events/vcs/git_cred_writer_test.go | 19 +++++++++++++ 2 files changed, 49 insertions(+), 4 deletions(-) diff --git a/server/events/vcs/git_cred_writer.go b/server/events/vcs/git_cred_writer.go index 6d6cf8531..eca5dc00d 100644 --- a/server/events/vcs/git_cred_writer.go +++ b/server/events/vcs/git_cred_writer.go @@ -38,11 +38,23 @@ func WriteGitCreds(gitUser string, gitToken string, gitHostname string, home str } if ghAccessToken { - // Need to replace the line. - if err := fileLineReplace(config, gitUser, gitHostname, credsFile); err != nil { - return errors.Wrap(err, "replacing git credentials line for github app") + hasGHToken, err := fileHasGHToken(gitUser, gitHostname, credsFile) + if err != nil { + return err } - logger.Info("updated git app credentials in %s", credsFile) + if hasGHToken { + // Need to replace the line. + if err := fileLineReplace(config, gitUser, gitHostname, credsFile); err != nil { + return errors.Wrap(err, "replacing git credentials line for github app") + } + logger.Info("updated git app credentials in %s", credsFile) + } else { + if err := fileAppend(config, credsFile); err != nil { + return err + } + logger.Info("wrote git credentials to %s", credsFile) + } + } else { // Otherwise we need to append the line. if err := fileAppend(config, credsFile); err != nil { @@ -113,3 +125,17 @@ func fileLineReplace(line, user, host, filename string) error { return os.WriteFile(filename, []byte(toWrite), 0600) } + +func fileHasGHToken(user, host, filename string) (bool, error) { + currContents, err := os.ReadFile(filename) // nolint: gosec + if err != nil { + return false, err + } + prevLines := strings.Split(string(currContents), "\n") + for _, l := range prevLines { + if strings.HasPrefix(l, "https://"+user) && strings.HasSuffix(l, host) { + return true, nil + } + } + return false, nil +} diff --git a/server/events/vcs/git_cred_writer_test.go b/server/events/vcs/git_cred_writer_test.go index 082f73247..64e758867 100644 --- a/server/events/vcs/git_cred_writer_test.go +++ b/server/events/vcs/git_cred_writer_test.go @@ -86,6 +86,25 @@ func TestWriteGitCreds_ReplaceApp(t *testing.T) { Equals(t, expContets, string(actContents)) } +// Test that the github app credential gets added even if there are other credentials. +func TestWriteGitCreds_AppendAppWhenFileNotEmpty(t *testing.T) { + logger := logging.NewNoopLogger(t) + tmp := t.TempDir() + t.Setenv("HOME", tmp) + + credsFile := filepath.Join(tmp, ".git-credentials") + contents := "line1\nhttps://user:token@host.com\nline2" + err := os.WriteFile(credsFile, []byte(contents), 0600) + Ok(t, err) + + err = vcs.WriteGitCreds("x-access-token", "token", "github.com", tmp, logger, true) + Ok(t, err) + expContets := "line1\nhttps://user:token@host.com\nline2\nhttps://x-access-token:token@github.com" + actContents, err := os.ReadFile(filepath.Join(tmp, ".git-credentials")) + Ok(t, err) + Equals(t, expContets, string(actContents)) +} + // Test that the github app credentials get updated when cred file is empty. func TestWriteGitCreds_AppendApp(t *testing.T) { logger := logging.NewNoopLogger(t)