Skip to content

Commit 5ff65d7

Browse files
committed
Add user support to git2go implementation
Signed-off-by: Philip Laine <[email protected]>
1 parent 934f5df commit 5ff65d7

File tree

6 files changed

+50
-26
lines changed

6 files changed

+50
-26
lines changed

controllers/gitrepository_controller.go

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -182,8 +182,12 @@ func (r *GitRepositoryReconciler) reconcile(ctx context.Context, repository sour
182182

183183
// determine auth method
184184
auth := &common.Auth{}
185-
authStrategy := git.AuthSecretStrategyForURL(repository.Spec.URL, repository.Spec.GitProtocolV2Compatibility)
186-
if repository.Spec.SecretRef != nil && authStrategy != nil {
185+
if repository.Spec.SecretRef != nil {
186+
authStrategy, err := git.AuthSecretStrategyForURL(repository.Spec.URL, repository.Spec.GitProtocolV2Compatibility)
187+
if err != nil {
188+
return sourcev1.GitRepositoryNotReady(repository, sourcev1.AuthenticationFailedReason, err.Error()), err
189+
}
190+
187191
name := types.NamespacedName{
188192
Namespace: repository.GetNamespace(),
189193
Name: repository.Spec.SecretRef.Name,

pkg/git/common/common.go

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,8 +25,9 @@ import (
2525
)
2626

2727
const (
28-
DefaultOrigin = "origin"
29-
DefaultBranch = "master"
28+
DefaultOrigin = "origin"
29+
DefaultBranch = "master"
30+
DefaultPublicKeyAuthUser = "git"
3031
)
3132

3233
type Commit interface {

pkg/git/git.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ func CheckoutStrategyForRef(ref *sourcev1.GitRepositoryRef, useGitV2 bool) commo
3535
return gitv1.CheckoutStrategyForRef(ref)
3636
}
3737

38-
func AuthSecretStrategyForURL(url string, useGitV2 bool) common.AuthSecretStrategy {
38+
func AuthSecretStrategyForURL(url string, useGitV2 bool) (common.AuthSecretStrategy, error) {
3939
if useGitV2 {
4040
return gitv2.AuthSecretStrategyForURL(url)
4141
}

pkg/git/v1/transport.go

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -28,8 +28,6 @@ import (
2828
"github.com/fluxcd/source-controller/pkg/git/common"
2929
)
3030

31-
const defaultPublicKeyAuthUser = "git"
32-
3331
func AuthSecretStrategyForURL(URL string) (common.AuthSecretStrategy, error) {
3432
u, err := url.Parse(URL)
3533
if err != nil {
@@ -75,7 +73,7 @@ func (s *PublicKeyAuth) Method(secret corev1.Secret) (*common.Auth, error) {
7573

7674
user := s.user
7775
if user == "" {
78-
user = defaultPublicKeyAuthUser
76+
user = common.DefaultPublicKeyAuthUser
7977
}
8078

8179
pk, err := ssh.NewPublicKeys(user, identity, "")

pkg/git/v2/transport.go

Lines changed: 24 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -22,21 +22,28 @@ import (
2222
"crypto/sha1"
2323
"fmt"
2424
"golang.org/x/crypto/ssh"
25+
"net/url"
2526
"strings"
2627

2728
"github.com/fluxcd/source-controller/pkg/git/common"
2829
git2go "github.com/libgit2/git2go/v31"
2930
corev1 "k8s.io/api/core/v1"
3031
)
3132

32-
func AuthSecretStrategyForURL(url string) common.AuthSecretStrategy {
33+
func AuthSecretStrategyForURL(URL string) (common.AuthSecretStrategy, error) {
34+
u, err := url.Parse(URL)
35+
if err != nil {
36+
return nil, fmt.Errorf("failed to parse URL to determine auth strategy: %w", err)
37+
}
38+
3339
switch {
34-
case strings.HasPrefix(url, "http"):
35-
return &BasicAuth{}
36-
case strings.HasPrefix(url, "ssh"):
37-
return &PublicKeyAuth{}
40+
case u.Scheme == "http", u.Scheme == "https":
41+
return &BasicAuth{}, nil
42+
case u.Scheme == "ssh":
43+
return &PublicKeyAuth{user: u.User.Username()}, nil
44+
default:
45+
return nil, fmt.Errorf("no auth secret strategy for scheme %s", u.Scheme)
3846
}
39-
return nil
4047
}
4148

4249
type BasicAuth struct{}
@@ -65,7 +72,9 @@ func (s *BasicAuth) Method(secret corev1.Secret) (*common.Auth, error) {
6572
return &common.Auth{CredCallback: credCallback, CertCallback: nil}, nil
6673
}
6774

68-
type PublicKeyAuth struct{}
75+
type PublicKeyAuth struct {
76+
user string
77+
}
6978

7079
func (s *PublicKeyAuth) Method(secret corev1.Secret) (*common.Auth, error) {
7180
identity := secret.Data["identity"]
@@ -79,14 +88,20 @@ func (s *PublicKeyAuth) Method(secret corev1.Secret) (*common.Auth, error) {
7988
return nil, err
8089
}
8190

82-
// Need to validate private key
91+
// Need to validate private key as it is not
92+
// done by git2go when loading the key
8393
_, err = ssh.ParsePrivateKey(identity)
8494
if err != nil {
8595
return nil, err
8696
}
8797

98+
user := s.user
99+
if user == "" {
100+
user = common.DefaultPublicKeyAuthUser
101+
}
102+
88103
credCallback := func(url string, username_from_url string, allowed_types git2go.CredType) (*git2go.Cred, error) {
89-
cred, err := git2go.NewCredSshKeyFromMemory("git", "", string(identity), "")
104+
cred, err := git2go.NewCredSshKeyFromMemory(user, "", string(identity), "")
90105
if err != nil {
91106
return nil, err
92107
}

pkg/git/v2/trasnport_test.go

Lines changed: 15 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -66,19 +66,25 @@ var (
6666

6767
func TestAuthSecretStrategyForURL(t *testing.T) {
6868
tests := []struct {
69-
name string
70-
url string
71-
want common.AuthSecretStrategy
69+
name string
70+
url string
71+
want common.AuthSecretStrategy
72+
wantErr bool
7273
}{
73-
{"HTTP", "http://git.example.com/org/repo.git", &BasicAuth{}},
74-
{"HTTPS", "https://git.example.com/org/repo.git", &BasicAuth{}},
75-
{"SSH", "ssh://git.example.com:2222/org/repo.git", &PublicKeyAuth{}},
76-
{"unsupported", "protocol://example.com", nil},
74+
{"HTTP", "http://git.example.com/org/repo.git", &BasicAuth{}, false},
75+
{"HTTPS", "https://git.example.com/org/repo.git", &BasicAuth{}, false},
76+
{"SSH", "ssh://git.example.com:2222/org/repo.git", &PublicKeyAuth{}, false},
77+
{"SSH with username", "ssh://[email protected]:2222/org/repo.git", &PublicKeyAuth{user: "example"}, false},
78+
{"unsupported", "protocol://example.com", nil, true},
7779
}
7880
for _, tt := range tests {
7981
t.Run(tt.name, func(t *testing.T) {
80-
got := AuthSecretStrategyForURL(tt.url)
81-
if reflect.TypeOf(got) != reflect.TypeOf(tt.want) {
82+
got, err := AuthSecretStrategyForURL(tt.url)
83+
if (err != nil) != tt.wantErr {
84+
t.Errorf("AuthSecretStrategyForURL() error = %v, wantErr %v", err, tt.wantErr)
85+
return
86+
}
87+
if !reflect.DeepEqual(got, tt.want) {
8288
t.Errorf("AuthSecretStrategyForURL() got = %v, want %v", got, tt.want)
8389
}
8490
})

0 commit comments

Comments
 (0)