Skip to content

Commit

Permalink
add support for google source repository authentication
Browse files Browse the repository at this point in the history
  • Loading branch information
mvanholsteijn committed Nov 8, 2021
1 parent 2fc6bc9 commit 1ef1802
Show file tree
Hide file tree
Showing 3 changed files with 81 additions and 29 deletions.
99 changes: 72 additions & 27 deletions clone.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,12 @@ package main

import (
"bytes"
"context"
"fmt"
"github.com/binxio/gcloudconfig"
sshconfig "github.com/kevinburke/ssh_config"
"golang.org/x/crypto/ssh"
"golang.org/x/oauth2/google"
"gopkg.in/src-d/go-billy.v4/memfs"
"gopkg.in/src-d/go-git.v4"
"gopkg.in/src-d/go-git.v4/config"
Expand All @@ -15,64 +18,61 @@ import (
"io"
"io/ioutil"
"log"
"net/url"
neturl "net/url"
"os"
"os/exec"
"strings"
)

func getCredentialHelper(url string) string {
cmd := exec.Command("git", "config", "--get-urlmatch", "credential.helper", url)
func getCredentialHelper(url *neturl.URL) string {
cmd := exec.Command("git", "config", "--get-urlmatch", "credential.helper", url.String())
helper, err := cmd.Output()
if err == nil {
return strings.TrimSpace(string(helper))
}

if exiterr, ok := err.(*exec.ExitError); ok {
if exiterr.ExitCode() != 1 {
log.Fatalf("ERROR: %s returned exitcode %d", cmd.String(), exiterr.ExitCode())
if exitError, ok := err.(*exec.ExitError); ok {
if exitError.ExitCode() != 1 {
log.Printf("ERROR: %s returned exitcode %d", cmd.String(), exitError.ExitCode())
}
} else {
log.Fatalf("ERROR: %s failed %s", cmd.String(), err)
log.Printf("ERROR: %s failed %s", cmd.String(), err)
}
return ""
}

func getPassword(repositoryUrl string) transport.AuthMethod {

u, err := url.Parse(repositoryUrl)
if err != nil {
log.Fatalf("ERROR: url '%s' could not be parsed, %s", repositoryUrl, err)
}
func getPassword(repositoryUrl *neturl.URL) (transport.AuthMethod, error) {

if os.Getenv("GIT_ASKPASS") == "" && getCredentialHelper(repositoryUrl) == "" {
// No credential helper specified, not passing in credentials
return nil
return nil, nil
}

user := u.User.Username()
password, _ := u.User.Password()

user := repositoryUrl.User.Username()
password, _ := repositoryUrl.User.Password()
log.Printf("protocol=%s\nhost=%s\nusername=%s\npath=%s\n",
repositoryUrl.Scheme, repositoryUrl.Host, user, repositoryUrl.Path)
cmd := exec.Command("git", "credential", "fill")
stdin, err := cmd.StdinPipe()
if err != nil {
log.Fatalf("ERROR: internal error on getPassword %s", err)
return nil, fmt.Errorf("ERROR: internal error on getPassword %s", err)
}
stderr, err := cmd.StderrPipe()
if err != nil {
log.Fatalf("ERROR: internal error on getPassword %s", err)
return nil, fmt.Errorf("ERROR: internal error on getPassword %s", err)
}

go func() {
defer stdin.Close()
input := fmt.Sprintf("protocol=%s\nhost=%s\nusername=%s\npath=%s\n", u.Scheme, u.Host, user, u.Path)
input := fmt.Sprintf("protocol=%s\nhost=%s\nusername=%s\npath=%s\n",
repositoryUrl.Scheme, repositoryUrl.Host, user, repositoryUrl.Path)
io.WriteString(stdin, input)
}()

out, err := cmd.Output()
if err != nil {
io.Copy(os.Stderr, stderr)
log.Fatalf("ERROR: git credential fill failed, %s", err)
return nil, fmt.Errorf("ERROR: git credential fill failed, %s", err)
}

for _, line := range strings.Split(string(out), "\n") {
Expand All @@ -84,8 +84,36 @@ func getPassword(repositoryUrl string) transport.AuthMethod {
password = value[1]
}
}
log.Printf("curl -H 'Authorization: Bearer %s' https://www.googleapis.com/oauth2/v3/userinfo", password)
return &githttp.BasicAuth{Username: user, Password: password}, nil
}

func IsGoogleSourceRepository(url *neturl.URL) bool {
return url.Scheme == "https" && url.Host == "source.developers.google.com"
}

func getGoogleCredentials(url *neturl.URL) (transport.AuthMethod, error) {
var err error
var credentials *google.Credentials

return &githttp.BasicAuth{Username: user, Password: password}
if gcloudconfig.IsGCloudOnPath() {
credentials, err = gcloudconfig.GetCredentials("")
} else {
credentials, err = google.FindDefaultCredentials(
context.Background(),
"https://www.googleapis.com/auth/cloud-platform")
}
if err != nil {
return nil, err
}
token, err := credentials.TokenSource.Token()
if err != nil {
return nil, err
}
return &githttp.BasicAuth{
Username: url.User.Username(),
Password: token.AccessToken,
}, nil
}

func identityFileAuthentication(user string, host string) (auth transport.AuthMethod, err error) {
Expand Down Expand Up @@ -155,19 +183,36 @@ func sshAgentAuthentication(user, host, keyFile string, key ssh.PublicKey) (auth
func GetAuth(url string) (auth transport.AuthMethod, plainOpen bool, err error) {

if MatchesScheme(url) {
if os.Getenv("GIT_ASKPASS") != "" || getCredentialHelper(url) != "" {
auth = getPassword(url)
repositoryUrl, err := neturl.Parse(url)
if err != nil {
return nil, true, err
}

if os.Getenv("GIT_ASKPASS") != "" || getCredentialHelper(repositoryUrl) != "" {
auth, err = getPassword(repositoryUrl)
if err != nil {
return nil, true, err
}
return auth, false, nil
}
return auth, false, nil

if IsGoogleSourceRepository(repositoryUrl) {
auth, err = getGoogleCredentials(repositoryUrl)
if err != nil {
return nil, true, err
}
return auth, false, nil
}

return nil, true, nil
}

if MatchesScpLike(url) {
user, host, _, _ := FindScpLikeComponents(url)

if auth, err = identityFileAuthentication(user, host); err != nil {
return
return nil, true, err
}

} else {
auth = nil
plainOpen = true
Expand Down
3 changes: 2 additions & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,12 @@ module github.com/binxio/cru
go 1.14

require (
github.com/binxio/gcloudconfig v0.1.5
github.com/docopt/docopt-go v0.0.0-20180111231733-ee0de3bc6815
github.com/google/go-containerregistry v0.1.1
github.com/kevinburke/ssh_config v0.0.0-20190725054713-01f96b0aa0cd
github.com/mitchellh/go-homedir v1.1.0
golang.org/x/crypto v0.0.0-20200510223506-06a226fb4e37
golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d
golang.org/x/tools v0.0.0-20200619210111-0f592d2728bb
gopkg.in/src-d/go-billy.v4 v4.3.2
gopkg.in/src-d/go-git.v4 v4.13.1
Expand Down
8 changes: 7 additions & 1 deletion go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ cloud.google.com/go v0.52.0/go.mod h1:pXajvRH/6o3+F9jDHZWQ5PbGhn+o8w9qiu/CffaVdO
cloud.google.com/go v0.53.0/go.mod h1:fp/UouUEsRkN6ryDKNW/Upv/JBKnv6WDthjR6+vze6M=
cloud.google.com/go v0.54.0/go.mod h1:1rq2OEkV3YMf6n/9ZvGWI3GWw0VoqH/1x2nd8Is/bPc=
cloud.google.com/go v0.56.0/go.mod h1:jr7tqZxxKOVYizybht9+26Z/gUq7tiRzu+ACVAMbKVk=
cloud.google.com/go v0.57.0 h1:EpMNVUorLiZIELdMZbCYX/ByTFCdoYopYAGxaGVz9ms=
cloud.google.com/go v0.57.0/go.mod h1:oXiQ6Rzq3RAkkY7N6t3TcE6jE+CIBBbA36lwQ1JyzZs=
cloud.google.com/go/bigquery v1.0.1/go.mod h1:i/xbL2UlR5RvWAURpBYZTtm/cXjCha9lbfbpx4poX+o=
cloud.google.com/go/bigquery v1.3.0/go.mod h1:PjpwJnslEMmckchkHFfq+HTD2DmtT67aNFKH1/VBDHE=
Expand Down Expand Up @@ -121,6 +122,8 @@ github.com/aybabtme/rgbterm v0.0.0-20170906152045-cc83f3b3ce59/go.mod h1:q/89r3U
github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q=
github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8=
github.com/bgentry/speakeasy v0.1.0/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kBD4zp0CCIs=
github.com/binxio/gcloudconfig v0.1.5 h1:nbvWtpqn7yJs4qPuXxTu9D3DYrSyc0FHkXraseMMCV4=
github.com/binxio/gcloudconfig v0.1.5/go.mod h1:IpQXzgqmv2JS1i+hbhqhHqzeYWg5zWkdN4sZJznJDUM=
github.com/bketelsen/crypt v0.0.3-0.20200106085610-5cbc8cc4026c/go.mod h1:MKsuJmJgSg28kpZDP6UIiPt0e0Oz0kqKNGyRaWEPv84=
github.com/blakesmith/ar v0.0.0-20190502131153-809d4375e1fb/go.mod h1:PkYb9DJNAwrSvRx5DYA+gUcOIgTGVMNkfSCbZM8cWpI=
github.com/blang/semver v3.5.0+incompatible/go.mod h1:kRBLl5iJ+tD4TcOOxsy/0fnwebNt5EWlYSAyrTnjyyk=
Expand Down Expand Up @@ -168,7 +171,6 @@ github.com/dimchansky/utfbom v1.1.0/go.mod h1:rO41eb7gLfo8SF1jd9F8HplJm1Fewwi4mQ
github.com/dnaeon/go-vcr v1.0.1/go.mod h1:aBB1+wY4s93YsC3HHjMBMrwTj2R9FHDzUr9KyGc8n1E=
github.com/docker/cli v0.0.0-20191017083524-a8ff7f821017 h1:2HQmlpI3yI9deH18Q6xiSOIjXD4sLI55Y/gfpa8/558=
github.com/docker/cli v0.0.0-20191017083524-a8ff7f821017/go.mod h1:JLrzqnKDaYBop7H2jaqPtU4hHvMKP+vjCwu2uszcLI8=
github.com/docker/distribution v2.7.1+incompatible h1:a5mlkVzth6W5A4fOsS3D2EO5BUmsJpcB+cRlLU7cSug=
github.com/docker/distribution v2.7.1+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w=
github.com/docker/docker v0.7.3-0.20190327010347-be7ac8be2ae0/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk=
github.com/docker/docker v1.4.2-0.20190924003213-a8608b5b67c7 h1:Cvj7S8I4Xpx78KAl6TwTmMHuHlZ/0SM60NUneGJQ7IE=
Expand Down Expand Up @@ -277,6 +279,7 @@ github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrU
github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w=
github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0=
github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QDs8UjoX8=
github.com/golang/protobuf v1.4.2 h1:+Z5KGCizgyZCbGh1KZqA0fcLLkwbsjIzS4aV2v7wJX0=
github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI=
github.com/golangci/check v0.0.0-20180506172741-cfe4005ccda2/go.mod h1:k9Qvh+8juN+UKMCS/3jFtGICgW8O96FVaZsaxdzDkR4=
github.com/golangci/dupl v0.0.0-20180902072040-3e9179ac440a/go.mod h1:ryS0uhF+x9jgbj/N71xsEqODy9BN81/GonCZiOzirOk=
Expand Down Expand Up @@ -748,6 +751,7 @@ golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4Iltr
golang.org/x/oauth2 v0.0.0-20190402181905-9f3314589c9a/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
golang.org/x/oauth2 v0.0.0-20191202225959-858c2ad4c8b6/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d h1:TzXSXBo42m9gQenoE3b9BGiEpg5IG2JkU5FkPIawgtw=
golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
Expand Down Expand Up @@ -912,6 +916,7 @@ google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7
google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
google.golang.org/appengine v1.6.1/go.mod h1:i06prIuMbXzDqacNJfV5OdTW448YApPu5ww/cMBSeb0=
google.golang.org/appengine v1.6.5/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc=
google.golang.org/appengine v1.6.6 h1:lMO5rYAqUxkmaj76jAkRUvt5JZgFymx/+Q5Mzfivuhc=
google.golang.org/appengine v1.6.6/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc=
google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
Expand Down Expand Up @@ -961,6 +966,7 @@ google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzi
google.golang.org/protobuf v1.22.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
google.golang.org/protobuf v1.24.0 h1:UhZDfRO8JRQru4/+LlLE0BRKGF8L+PICnvYZmx/fEGA=
google.golang.org/protobuf v1.24.0/go.mod h1:r/3tXBNzIEhYS9I1OUVjXDlt8tc493IdKGjtUeSXeh4=
gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
Expand Down

0 comments on commit 1ef1802

Please sign in to comment.