diff options
-rw-r--r-- | clients/common.go | 10 | ||||
-rw-r--r-- | clients/common/common.go | 13 | ||||
-rw-r--r-- | clients/http/common.go | 33 | ||||
-rw-r--r-- | clients/http/git_upload_pack.go | 23 | ||||
-rw-r--r-- | clients/http/git_upload_pack_test.go | 17 | ||||
-rw-r--r-- | common_test.go | 9 | ||||
-rw-r--r-- | objects_test.go | 2 | ||||
-rw-r--r-- | remote.go | 23 | ||||
-rw-r--r-- | remote_test.go | 8 | ||||
-rw-r--r-- | repository.go | 12 | ||||
-rw-r--r-- | repository_test.go | 20 |
11 files changed, 152 insertions, 18 deletions
diff --git a/clients/common.go b/clients/common.go index 8003d07..fcbacf5 100644 --- a/clients/common.go +++ b/clients/common.go @@ -1,18 +1,10 @@ package clients import ( - "io" - "gopkg.in/src-d/go-git.v2/clients/common" "gopkg.in/src-d/go-git.v2/clients/http" ) -type GitUploadPackService interface { - Connect(url common.Endpoint) error - Info() (*common.GitUploadPackInfo, error) - Fetch(r *common.GitUploadPackRequest) (io.ReadCloser, error) -} - -func NewGitUploadPackService() GitUploadPackService { +func NewGitUploadPackService() common.GitUploadPackService { return http.NewGitUploadPackService() } diff --git a/clients/common/common.go b/clients/common/common.go index 44d8e6a..8756cfd 100644 --- a/clients/common/common.go +++ b/clients/common/common.go @@ -3,6 +3,7 @@ package common import ( "errors" "fmt" + "io" "io/ioutil" "strings" @@ -19,6 +20,18 @@ var ( const GitUploadPackServiceName = "git-upload-pack" +type GitUploadPackService interface { + Connect(url Endpoint) error + ConnectWithAuth(url Endpoint, auth AuthMethod) error + Info() (*GitUploadPackInfo, error) + Fetch(r *GitUploadPackRequest) (io.ReadCloser, error) +} + +type AuthMethod interface { + Name() string + String() string +} + type Endpoint string func NewEndpoint(url string) (Endpoint, error) { diff --git a/clients/http/common.go b/clients/http/common.go index 15338a8..fc3a236 100644 --- a/clients/http/common.go +++ b/clients/http/common.go @@ -1,6 +1,7 @@ package http import ( + "errors" "fmt" "net/http" @@ -8,6 +9,38 @@ import ( "gopkg.in/src-d/go-git.v2/core" ) +var InvalidAuthMethodErr = errors.New("invalid http auth method: a http.HTTPAuthMethod should be provided.") + +type HTTPAuthMethod interface { + common.AuthMethod + setAuth(r *http.Request) +} + +type BasicAuth struct { + username, password string +} + +func NewBasicAuth(username, password string) *BasicAuth { + return &BasicAuth{username, password} +} + +func (a *BasicAuth) setAuth(r *http.Request) { + r.SetBasicAuth(a.username, a.password) +} + +func (a *BasicAuth) Name() string { + return "http-basic-auth" +} + +func (a *BasicAuth) String() string { + masked := "*******" + if a.password == "" { + masked = "<empty>" + } + + return fmt.Sprintf("%s - %s:%s", a.Name(), a.username, masked) +} + type HTTPError struct { Response *http.Response } diff --git a/clients/http/git_upload_pack.go b/clients/http/git_upload_pack.go index 6960be1..217e4aa 100644 --- a/clients/http/git_upload_pack.go +++ b/clients/http/git_upload_pack.go @@ -15,6 +15,7 @@ type GitUploadPackService struct { Client *http.Client endpoint common.Endpoint + auth HTTPAuthMethod } func NewGitUploadPackService() *GitUploadPackService { @@ -29,6 +30,18 @@ func (s *GitUploadPackService) Connect(url common.Endpoint) error { return nil } +func (s *GitUploadPackService) ConnectWithAuth(url common.Endpoint, auth common.AuthMethod) error { + httpAuth, ok := auth.(HTTPAuthMethod) + if !ok { + return InvalidAuthMethodErr + } + + s.endpoint = url + s.auth = httpAuth + + return nil +} + func (s *GitUploadPackService) Info() (*common.GitUploadPackInfo, error) { url := fmt.Sprintf("%s/info/refs?service=%s", s.endpoint, common.GitUploadPackServiceName) res, err := s.doRequest("GET", url, nil) @@ -69,8 +82,10 @@ func (s *GitUploadPackService) doRequest(method, url string, content *strings.Re } s.applyHeadersToRequest(req, content) + s.applyAuthToRequest(req) res, err := s.Client.Do(req) + if err != nil { return nil, core.NewUnexpectedError(err) } @@ -94,3 +109,11 @@ func (s *GitUploadPackService) applyHeadersToRequest(req *http.Request, content req.Header.Add("Content-Length", string(content.Len())) } } + +func (s *GitUploadPackService) applyAuthToRequest(req *http.Request) { + if s.auth == nil { + return + } + + s.auth.setAuth(req) +} diff --git a/clients/http/git_upload_pack_test.go b/clients/http/git_upload_pack_test.go index b870259..02ed37c 100644 --- a/clients/http/git_upload_pack_test.go +++ b/clients/http/git_upload_pack_test.go @@ -19,6 +19,23 @@ func (s *SuiteRemote) TestConnect(c *C) { c.Assert(r.Connect(RepositoryFixture), IsNil) } +func (s *SuiteRemote) TestConnectWithAuth(c *C) { + auth := &BasicAuth{} + r := NewGitUploadPackService() + c.Assert(r.ConnectWithAuth(RepositoryFixture, auth), IsNil) + c.Assert(r.auth, Equals, auth) +} + +type mockAuth struct{} + +func (*mockAuth) Name() string { return "" } +func (*mockAuth) String() string { return "" } + +func (s *SuiteRemote) TestConnectWithAuthWrongType(c *C) { + r := NewGitUploadPackService() + c.Assert(r.ConnectWithAuth(RepositoryFixture, &mockAuth{}), Equals, InvalidAuthMethodErr) +} + func (s *SuiteRemote) TestDefaultBranch(c *C) { r := NewGitUploadPackService() c.Assert(r.Connect(RepositoryFixture), IsNil) diff --git a/common_test.go b/common_test.go index 1716813..03f027c 100644 --- a/common_test.go +++ b/common_test.go @@ -12,12 +12,19 @@ import ( func Test(t *testing.T) { TestingT(t) } -type MockGitUploadPackService struct{} +type MockGitUploadPackService struct { + Auth common.AuthMethod +} func (s *MockGitUploadPackService) Connect(url common.Endpoint) error { return nil } +func (s *MockGitUploadPackService) ConnectWithAuth(url common.Endpoint, auth common.AuthMethod) error { + s.Auth = auth + return nil +} + func (s *MockGitUploadPackService) Info() (*common.GitUploadPackInfo, error) { hash := core.NewHash("6ecf0ef2c2dffb796033e5a02219af86ec6584e5") diff --git a/objects_test.go b/objects_test.go index d2bd7db..9bebe26 100644 --- a/objects_test.go +++ b/objects_test.go @@ -16,7 +16,7 @@ var _ = Suite(&ObjectsSuite{}) func (s *ObjectsSuite) SetUpTest(c *C) { var err error - s.r, err = NewRepository(RepositoryFixture) + s.r, err = NewRepository(RepositoryFixture, nil) s.r.Remotes["origin"].upSrv = &MockGitUploadPackService{} s.r.Pull("origin", "refs/heads/master") @@ -11,13 +11,20 @@ import ( type Remote struct { Endpoint common.Endpoint + Auth common.AuthMethod - upSrv clients.GitUploadPackService + upSrv common.GitUploadPackService upInfo *common.GitUploadPackInfo } // NewRemote returns a new Remote, using as client http.DefaultClient func NewRemote(url string) (*Remote, error) { + return NewAuthenticatedRemote(url, nil) +} + +// NewAuthenticatedRemote returns a new Remote using the given AuthMethod, using as +// client http.DefaultClient +func NewAuthenticatedRemote(url string, auth common.AuthMethod) (*Remote, error) { end, err := common.NewEndpoint(url) if err != nil { return nil, err @@ -25,16 +32,28 @@ func NewRemote(url string) (*Remote, error) { return &Remote{ Endpoint: end, + Auth: auth, upSrv: clients.NewGitUploadPackService(), }, nil } // Connect with the endpoint func (r *Remote) Connect() error { - if err := r.upSrv.Connect(r.Endpoint); err != nil { + var err error + if r.Auth == nil { + err = r.upSrv.Connect(r.Endpoint) + } else { + err = r.upSrv.ConnectWithAuth(r.Endpoint, r.Auth) + } + + if err != nil { return err } + return r.retrieveUpInfo() +} + +func (r *Remote) retrieveUpInfo() error { var err error if r.upInfo, err = r.upSrv.Info(); err != nil { return err diff --git a/remote_test.go b/remote_test.go index c222e7d..7a40deb 100644 --- a/remote_test.go +++ b/remote_test.go @@ -1,6 +1,7 @@ package git import ( + "gopkg.in/src-d/go-git.v2/clients/http" "gopkg.in/src-d/go-git.v2/core" "gopkg.in/src-d/go-git.v2/formats/packfile" @@ -13,6 +14,13 @@ var _ = Suite(&SuiteRemote{}) const RepositoryFixture = "https://github.com/tyba/git-fixture" +func (s *SuiteRemote) TestNewAuthenticatedRemote(c *C) { + auth := &http.BasicAuth{} + r, err := NewAuthenticatedRemote(RepositoryFixture, auth) + c.Assert(err, IsNil) + c.Assert(r.Auth, Equals, auth) +} + func (s *SuiteRemote) TestConnect(c *C) { r, err := NewRemote(RepositoryFixture) c.Assert(err, IsNil) diff --git a/repository.go b/repository.go index 9bdccc0..bf45fdc 100644 --- a/repository.go +++ b/repository.go @@ -23,8 +23,16 @@ type Repository struct { } // NewRepository creates a new repository setting remote as default remote -func NewRepository(url string) (*Repository, error) { - remote, err := NewRemote(url) +func NewRepository(url string, auth common.AuthMethod) (*Repository, error) { + var remote *Remote + var err error + + if auth == nil { + remote, err = NewRemote(url) + } else { + remote, err = NewAuthenticatedRemote(url, auth) + } + if err != nil { return nil, err } diff --git a/repository_test.go b/repository_test.go index 7a480f1..421160d 100644 --- a/repository_test.go +++ b/repository_test.go @@ -2,6 +2,7 @@ package git import ( . "gopkg.in/check.v1" + "gopkg.in/src-d/go-git.v2/clients/http" "gopkg.in/src-d/go-git.v2/core" ) @@ -9,8 +10,21 @@ type SuiteRepository struct{} var _ = Suite(&SuiteRepository{}) +func (s *SuiteRepository) TestNewRepository(c *C) { + r, err := NewRepository(RepositoryFixture, nil) + c.Assert(err, IsNil) + c.Assert(r.Remotes["origin"].Auth, IsNil) +} + +func (s *SuiteRepository) TestNewRepositoryWithAuth(c *C) { + auth := &http.BasicAuth{} + r, err := NewRepository(RepositoryFixture, auth) + c.Assert(err, IsNil) + c.Assert(r.Remotes["origin"].Auth, Equals, auth) +} + func (s *SuiteRepository) TestPull(c *C) { - r, err := NewRepository(RepositoryFixture) + r, err := NewRepository(RepositoryFixture, nil) r.Remotes["origin"].upSrv = &MockGitUploadPackService{} c.Assert(err, IsNil) @@ -18,7 +32,7 @@ func (s *SuiteRepository) TestPull(c *C) { } func (s *SuiteRepository) TestCommit(c *C) { - r, err := NewRepository(RepositoryFixture) + r, err := NewRepository(RepositoryFixture, nil) r.Remotes["origin"].upSrv = &MockGitUploadPackService{} c.Assert(err, IsNil) @@ -34,7 +48,7 @@ func (s *SuiteRepository) TestCommit(c *C) { } func (s *SuiteRepository) TestCommits(c *C) { - r, err := NewRepository(RepositoryFixture) + r, err := NewRepository(RepositoryFixture, nil) r.Remotes["origin"].upSrv = &MockGitUploadPackService{} c.Assert(err, IsNil) |