Skip to content

Commit

Permalink
added passing the bearer header
Browse files Browse the repository at this point in the history
Signed-off-by: reggie-k <[email protected]>
  • Loading branch information
reggie-k committed Jan 29, 2025
1 parent 0c70dee commit 2895760
Show file tree
Hide file tree
Showing 4 changed files with 129 additions and 0 deletions.
4 changes: 4 additions & 0 deletions util/git/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -971,6 +971,10 @@ func (m *nativeGitClient) runCredentialedCmd(args ...string) error {
for _, e := range environ {
if strings.HasPrefix(e, forceBasicAuthHeaderEnv+"=") {
args = append([]string{"--config-env", "http.extraHeader=" + forceBasicAuthHeaderEnv}, args...)
} else {
if strings.HasPrefix(e, bearerAuthHeaderEnv+"=") {
args = append([]string{"--config-env", "http.extraHeader=" + bearerAuthHeaderEnv}, args...)
}
}
}

Expand Down
91 changes: 91 additions & 0 deletions util/git/client_test.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
package git

import (
"context"
"errors"
"io"
"os"
"os/exec"
"path"
Expand Down Expand Up @@ -904,3 +907,91 @@ func TestNewAuth(t *testing.T) {
})
}
}
func Test_nativeGitClient_runCredentialedCmd(t *testing.T) {
tests := []struct {
name string
creds Creds
environ []string
expectedArgs []string
expectedEnv []string
expectedErr bool
}{
{
name: "basic auth header set",
creds: &mockCreds{
environ: []string{forceBasicAuthHeaderEnv + "=Basic dGVzdDp0ZXN0"},
},
expectedArgs: []string{"--config-env", "http.extraHeader=" + forceBasicAuthHeaderEnv, "status"},
expectedEnv: []string{forceBasicAuthHeaderEnv + "=Basic dGVzdDp0ZXN0"},
expectedErr: false,
},
{
name: "bearer auth header set",
creds: &mockCreds{
environ: []string{bearerAuthHeaderEnv + "=Bearer test-token"},
},
expectedArgs: []string{"--config-env", "http.extraHeader=" + bearerAuthHeaderEnv, "status"},
expectedEnv: []string{bearerAuthHeaderEnv + "=Bearer test-token"},
expectedErr: false,
},
{
name: "no auth header set",
creds: &mockCreds{
environ: []string{},
},
expectedArgs: []string{"status"},
expectedEnv: []string{},
expectedErr: false,
},
{
name: "error getting environment",
creds: &mockCreds{
environErr: true,
},
expectedArgs: []string{},
expectedEnv: []string{},
expectedErr: true,
},
}

for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
client := &nativeGitClient{
creds: tt.creds,
}

err := client.runCredentialedCmd("status")
if (err != nil) != tt.expectedErr {
t.Errorf("runCredentialedCmd() error = %v, expectedErr %v", err, tt.expectedErr)
return
}

if tt.expectedErr {
return
}

cmd := exec.Command("git", tt.expectedArgs...)
cmd.Env = append(os.Environ(), tt.expectedEnv...)
output, err := cmd.CombinedOutput()
if err != nil {
t.Errorf("runCredentialedCmd() command error = %v, output = %s", err, output)
}
})
}
}

type mockCreds struct {
environ []string
environErr bool
}

func (m *mockCreds) Environ() (io.Closer, []string, error) {
if m.environErr {
return nil, nil, errors.New("error getting environment")
}
return io.NopCloser(nil), m.environ, nil
}

func (m *mockCreds) GetUserInfo(ctx context.Context) (string, string, error) {
return "", "", nil
}
13 changes: 13 additions & 0 deletions util/git/creds.go
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ const (
// githubAccessTokenUsername is a username that is used to with the github access token
githubAccessTokenUsername = "x-access-token"
forceBasicAuthHeaderEnv = "ARGOCD_GIT_AUTH_HEADER"
bearerAuthHeaderEnv = "ARGOCD_GIT_BEARER_AUTH_HEADER"
// This is the resource id of the OAuth application of Azure Devops.
azureDevopsEntraResourceId = "499b84ac-1321-427f-aa17-267ca6975798/.default"
)
Expand Down Expand Up @@ -179,6 +180,13 @@ func (creds HTTPSCreds) BasicAuthHeader() string {
return h
}

func (creds HTTPSCreds) BearerAuthHeader() string {
h := "Authorization: Bearer "
t := creds.bearerToken
h += base64.StdEncoding.EncodeToString([]byte(t))
return h
}

// Get additional required environment variables for executing git client to
// access specific repository via HTTPS.
func (creds HTTPSCreds) Environ() (io.Closer, []string, error) {
Expand Down Expand Up @@ -240,6 +248,11 @@ func (creds HTTPSCreds) Environ() (io.Closer, []string, error) {
// skipped. This is insecure, but some environments may need it.
if creds.password != "" && creds.forceBasicAuth {
env = append(env, fmt.Sprintf("%s=%s", forceBasicAuthHeaderEnv, creds.BasicAuthHeader()))
} else {
// If bearer token is set, we will set ARGOCD_BEARER_AUTH_HEADER to hold the HTTP authorization header
if creds.bearerToken != "" {
env = append(env, fmt.Sprintf("%s=%s", bearerAuthHeaderEnv, creds.BearerAuthHeader()))
}
}
nonce := creds.store.Add(text.FirstNonEmpty(creds.username, githubAccessTokenUsername), creds.password)
env = append(env, creds.store.Environ(nonce)...)
Expand Down
21 changes: 21 additions & 0 deletions util/git/creds_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -167,6 +167,27 @@ func TestHTTPSCreds_Environ_forceBasicAuth(t *testing.T) {
})
}

func TestHTTPSCreds_Environ_bearerTokenAuth(t *testing.T) {
t.Run("Enabled and credentials set", func(t *testing.T) {
store := &memoryCredsStore{creds: make(map[string]cred)}
creds := NewHTTPSCreds("", "", "token", "", "", false, "", "", store, false)
closer, env, err := creds.Environ()
require.NoError(t, err)
defer closer.Close()
var header string
for _, envVar := range env {
if strings.HasPrefix(envVar, bearerAuthHeaderEnv+"=") {
header = envVar[len(bearerAuthHeaderEnv)+1:]
}
if header != "" {
break
}
}
b64enc := base64.StdEncoding.EncodeToString([]byte("token"))
assert.Equal(t, "Authorization: Bearer "+b64enc, header)
})
}

func TestHTTPSCreds_Environ_clientCert(t *testing.T) {
store := &memoryCredsStore{creds: make(map[string]cred)}
creds := NewHTTPSCreds("", "", "", "clientCertData", "clientCertKey", false, "", "", store, false)
Expand Down

0 comments on commit 2895760

Please sign in to comment.