mirror of
https://github.com/woodpecker-ci/woodpecker.git
synced 2024-12-24 10:07:21 +02:00
Pass down context.Context (#371)
* pass context down to remote clients * make tests work * add ctx to Refresh() and use it * bitbucketserver * code format * plugin interface: add todo context * solve todo * RM TODO by using context.WithTimeout * refactor & fix * Apply suggestions from code review Co-authored-by: Anbraten <anton@ju60.de> * go fmt * Update server/remote/coding/coding.go Co-authored-by: Anbraten <anton@ju60.de> Co-authored-by: Anbraten <anton@ju60.de>
This commit is contained in:
parent
c0888de86b
commit
e3499f610d
@ -333,9 +333,9 @@ func PostApproval(c *gin.Context) {
|
||||
for _, item := range buildItems {
|
||||
uri := fmt.Sprintf("%s/%s/%d", server.Config.Server.Host, repo.FullName, build.Number)
|
||||
if len(buildItems) > 1 {
|
||||
err = remote_.Status(user, repo, build, uri, item.Proc)
|
||||
err = remote_.Status(c, user, repo, build, uri, item.Proc)
|
||||
} else {
|
||||
err = remote_.Status(user, repo, build, uri, nil)
|
||||
err = remote_.Status(c, user, repo, build, uri, nil)
|
||||
}
|
||||
if err != nil {
|
||||
logrus.Errorf("error setting commit status for %s/%d: %v", repo.FullName, build.Number, err)
|
||||
@ -373,7 +373,7 @@ func PostDecline(c *gin.Context) {
|
||||
}
|
||||
|
||||
uri := fmt.Sprintf("%s/%s/%d", server.Config.Server.Host, repo.FullName, build.Number)
|
||||
err = remote_.Status(user, repo, build, uri, nil)
|
||||
err = remote_.Status(c, user, repo, build, uri, nil)
|
||||
if err != nil {
|
||||
logrus.Errorf("error setting commit status for %s/%d: %v", repo.FullName, build.Number, err)
|
||||
}
|
||||
@ -426,7 +426,7 @@ func PostBuild(c *gin.Context) {
|
||||
// may be stale. Therefore, we should refresh prior to dispatching
|
||||
// the job.
|
||||
if refresher, ok := remote_.(remote.Refresher); ok {
|
||||
ok, _ := refresher.Refresh(user)
|
||||
ok, _ := refresher.Refresh(c, user)
|
||||
if ok {
|
||||
store.UpdateUser(c, user)
|
||||
}
|
||||
|
@ -155,7 +155,7 @@ func PostHook(c *gin.Context) {
|
||||
// may be stale. Therefore, we should refresh prior to dispatching
|
||||
// the build.
|
||||
if refresher, ok := remote_.(remote.Refresher); ok {
|
||||
ok, err := refresher.Refresh(user)
|
||||
ok, err := refresher.Refresh(c, user)
|
||||
if err != nil {
|
||||
logrus.Errorf("failed to refresh oauth2 token: %s", err)
|
||||
} else if ok {
|
||||
@ -168,7 +168,7 @@ func PostHook(c *gin.Context) {
|
||||
|
||||
// fetch the build file from the remote
|
||||
configFetcher := shared.NewConfigFetcher(remote_, user, repo, build)
|
||||
remoteYamlConfigs, err := configFetcher.Fetch()
|
||||
remoteYamlConfigs, err := configFetcher.Fetch(c)
|
||||
if err != nil {
|
||||
logrus.Errorf("error: %s: cannot find %s in %s: %s", repo.FullName, repo.Config, build.Ref, err)
|
||||
c.AbortWithError(404, err)
|
||||
@ -278,9 +278,9 @@ func PostHook(c *gin.Context) {
|
||||
for _, item := range buildItems {
|
||||
uri := fmt.Sprintf("%s/%s/%d", server.Config.Server.Host, repo.FullName, build.Number)
|
||||
if len(buildItems) > 1 {
|
||||
err = remote_.Status(user, repo, build, uri, item.Proc)
|
||||
err = remote_.Status(c, user, repo, build, uri, item.Proc)
|
||||
} else {
|
||||
err = remote_.Status(user, repo, build, uri, nil)
|
||||
err = remote_.Status(c, user, repo, build, uri, nil)
|
||||
}
|
||||
if err != nil {
|
||||
logrus.Errorf("error setting commit status for %s/%d: %v", repo.FullName, build.Number, err)
|
||||
|
@ -75,13 +75,13 @@ func PostRepo(c *gin.Context) {
|
||||
sig,
|
||||
)
|
||||
|
||||
err = r.Activate(user, repo, link)
|
||||
err = r.Activate(c, user, repo, link)
|
||||
if err != nil {
|
||||
c.String(500, err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
from, err := r.Repo(user, repo.Owner, repo.Name)
|
||||
from, err := r.Repo(c, user, repo.Owner, repo.Name)
|
||||
if err == nil {
|
||||
repo.Update(from)
|
||||
}
|
||||
@ -187,7 +187,10 @@ func DeleteRepo(c *gin.Context) {
|
||||
}
|
||||
}
|
||||
|
||||
r.Deactivate(user, repo, server.Config.Server.Host)
|
||||
if err := r.Deactivate(c, user, repo, server.Config.Server.Host); err != nil {
|
||||
c.AbortWithError(http.StatusInternalServerError, err)
|
||||
return
|
||||
}
|
||||
c.JSON(200, repo)
|
||||
}
|
||||
|
||||
@ -212,14 +215,14 @@ func RepairRepo(c *gin.Context) {
|
||||
sig,
|
||||
)
|
||||
|
||||
r.Deactivate(user, repo, host)
|
||||
err = r.Activate(user, repo, link)
|
||||
_ = r.Deactivate(c, user, repo, host)
|
||||
err = r.Activate(c, user, repo, link)
|
||||
if err != nil {
|
||||
c.String(500, err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
from, err := r.Repo(user, repo.Owner, repo.Name)
|
||||
from, err := r.Repo(c, user, repo.Owner, repo.Name)
|
||||
if err == nil {
|
||||
repo.Name = from.Name
|
||||
repo.Owner = from.Owner
|
||||
@ -255,7 +258,7 @@ func MoveRepo(c *gin.Context) {
|
||||
return
|
||||
}
|
||||
|
||||
from, err := r.Repo(user, owner, name)
|
||||
from, err := r.Repo(c, user, owner, name)
|
||||
if err != nil {
|
||||
c.AbortWithError(http.StatusInternalServerError, err)
|
||||
return
|
||||
@ -298,8 +301,9 @@ func MoveRepo(c *gin.Context) {
|
||||
sig,
|
||||
)
|
||||
|
||||
r.Deactivate(user, repo, host)
|
||||
err = r.Activate(user, repo, link)
|
||||
// TODO: check if we should handle that error
|
||||
r.Deactivate(c, user, repo, host)
|
||||
err = r.Activate(c, user, repo, link)
|
||||
if err != nil {
|
||||
c.String(500, err.Error())
|
||||
return
|
||||
|
@ -54,7 +54,7 @@ func GetFeed(c *gin.Context) {
|
||||
Perms: store.FromContext(c),
|
||||
Match: shared.NamespaceFilter(config.OwnersWhitelist),
|
||||
}
|
||||
if err := sync.Sync(user); err != nil {
|
||||
if err := sync.Sync(c, user); err != nil {
|
||||
logrus.Debugf("sync error: %s: %s", user.Login, err)
|
||||
} else {
|
||||
logrus.Debugf("sync complete: %s", user.Login)
|
||||
@ -100,7 +100,7 @@ func GetRepos(c *gin.Context) {
|
||||
Match: shared.NamespaceFilter(config.OwnersWhitelist),
|
||||
}
|
||||
|
||||
if err := sync.Sync(user); err != nil {
|
||||
if err := sync.Sync(c, user); err != nil {
|
||||
logrus.Debugf("sync error: %s: %s", user.Login, err)
|
||||
} else {
|
||||
logrus.Debugf("sync complete: %s", user.Login)
|
||||
|
@ -338,12 +338,12 @@ func (s *RPC) Done(c context.Context, id string, state rpc.State) error {
|
||||
}
|
||||
|
||||
if !isMultiPipeline(procs) {
|
||||
s.updateRemoteStatus(repo, build, nil)
|
||||
s.updateRemoteStatus(c, repo, build, nil)
|
||||
}
|
||||
}
|
||||
|
||||
if isMultiPipeline(procs) {
|
||||
s.updateRemoteStatus(repo, build, proc)
|
||||
s.updateRemoteStatus(c, repo, build, proc)
|
||||
}
|
||||
|
||||
if err := s.logger.Close(c, id); err != nil {
|
||||
@ -416,17 +416,17 @@ func buildStatus(procs []*model.Proc) string {
|
||||
return status
|
||||
}
|
||||
|
||||
func (s *RPC) updateRemoteStatus(repo *model.Repo, build *model.Build, proc *model.Proc) {
|
||||
func (s *RPC) updateRemoteStatus(ctx context.Context, repo *model.Repo, build *model.Build, proc *model.Proc) {
|
||||
user, err := s.store.GetUser(repo.UserID)
|
||||
if err == nil {
|
||||
if refresher, ok := s.remote.(remote.Refresher); ok {
|
||||
ok, _ := refresher.Refresh(user)
|
||||
ok, _ := refresher.Refresh(ctx, user)
|
||||
if ok {
|
||||
s.store.UpdateUser(user)
|
||||
}
|
||||
}
|
||||
uri := fmt.Sprintf("%s/%s/%d", server.Config.Server.Host, repo.FullName, build.Number)
|
||||
err = s.remote.Status(user, repo, build, uri, proc)
|
||||
err = s.remote.Status(ctx, user, repo, build, uri, proc)
|
||||
if err != nil {
|
||||
logrus.Errorf("error setting commit status for %s/%d: %v", repo.FullName, build.Number, err)
|
||||
}
|
||||
|
@ -9,13 +9,13 @@ type builtin struct {
|
||||
globals []*model.Environ
|
||||
}
|
||||
|
||||
// New returns a new local registry service.
|
||||
// Filesystem returns a new local registry service.
|
||||
func Filesystem(params []string) model.EnvironService {
|
||||
var globals []*model.Environ
|
||||
|
||||
for _, item := range params {
|
||||
kvpair := strings.SplitN(item, ":", 2)
|
||||
globals = append(globals, &model.Environ{Name: kvpair[0], Value: kvpair[1]})
|
||||
kvPair := strings.SplitN(item, ":", 2)
|
||||
globals = append(globals, &model.Environ{Name: kvPair[0], Value: kvPair[1]})
|
||||
}
|
||||
return &builtin{globals}
|
||||
}
|
||||
|
@ -2,6 +2,7 @@ package internal
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"encoding/json"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
@ -11,7 +12,7 @@ import (
|
||||
|
||||
// Send makes an http request to the given endpoint, writing the input
|
||||
// to the request body and unmarshaling the output from the response body.
|
||||
func Send(method, path string, in, out interface{}) error {
|
||||
func Send(ctx context.Context, method, path string, in, out interface{}) error {
|
||||
uri, err := url.Parse(path)
|
||||
if err != nil {
|
||||
return err
|
||||
@ -29,7 +30,7 @@ func Send(method, path string, in, out interface{}) error {
|
||||
}
|
||||
|
||||
// creates a new http request to bitbucket.
|
||||
req, err := http.NewRequest(method, uri.String(), buf)
|
||||
req, err := http.NewRequestWithContext(ctx, method, uri.String(), buf)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -1,6 +1,7 @@
|
||||
package sender
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
|
||||
"github.com/woodpecker-ci/woodpecker/server/model"
|
||||
@ -22,7 +23,7 @@ func (p *plugin) SenderAllowed(user *model.User, repo *model.Repo, build *model.
|
||||
"build": build,
|
||||
"config": conf,
|
||||
}
|
||||
err := internal.Send("POST", path, &data, nil)
|
||||
err := internal.Send(context.TODO(), "POST", path, &data, nil)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
@ -31,21 +32,21 @@ func (p *plugin) SenderAllowed(user *model.User, repo *model.Repo, build *model.
|
||||
|
||||
func (p *plugin) SenderCreate(repo *model.Repo, sender *model.Sender) error {
|
||||
path := fmt.Sprintf("%s/senders/%s/%s", p.endpoint, repo.Owner, repo.Name)
|
||||
return internal.Send("POST", path, sender, nil)
|
||||
return internal.Send(context.TODO(), "POST", path, sender, nil)
|
||||
}
|
||||
|
||||
func (p *plugin) SenderUpdate(repo *model.Repo, sender *model.Sender) error {
|
||||
path := fmt.Sprintf("%s/senders/%s/%s", p.endpoint, repo.Owner, repo.Name)
|
||||
return internal.Send("PUT", path, sender, nil)
|
||||
return internal.Send(context.TODO(), "PUT", path, sender, nil)
|
||||
}
|
||||
|
||||
func (p *plugin) SenderDelete(repo *model.Repo, login string) error {
|
||||
path := fmt.Sprintf("%s/senders/%s/%s/%s", p.endpoint, repo.Owner, repo.Name, login)
|
||||
return internal.Send("DELETE", path, nil, nil)
|
||||
return internal.Send(context.TODO(), "DELETE", path, nil, nil)
|
||||
}
|
||||
|
||||
func (p *plugin) SenderList(repo *model.Repo) (out []*model.Sender, err error) {
|
||||
path := fmt.Sprintf("%s/senders/%s/%s", p.endpoint, repo.Owner, repo.Name)
|
||||
err = internal.Send("GET", path, nil, out)
|
||||
err = internal.Send(context.TODO(), "GET", path, nil, out)
|
||||
return out, err
|
||||
}
|
||||
|
@ -134,7 +134,7 @@ type Queue interface {
|
||||
// Push pushes a task to the tail of this queue.
|
||||
Push(c context.Context, task *Task) error
|
||||
|
||||
// Push pushes a task to the tail of this queue.
|
||||
// PushAtOnce pushes a task to the tail of this queue.
|
||||
PushAtOnce(c context.Context, tasks []*Task) error
|
||||
|
||||
// Poll retrieves and removes a task head of this queue.
|
||||
@ -149,13 +149,13 @@ type Queue interface {
|
||||
// Error signals the task is complete with errors.
|
||||
Error(c context.Context, id string, err error) error
|
||||
|
||||
// Error signals the task is complete with errors.
|
||||
// ErrorAtOnce signals the task is complete with errors.
|
||||
ErrorAtOnce(c context.Context, id []string, err error) error
|
||||
|
||||
// Evict removes a pending task from the queue.
|
||||
Evict(c context.Context, id string) error
|
||||
|
||||
// Evict removes a pending task from the queue.
|
||||
// EvictAtOnce removes a pending task from the queue.
|
||||
EvictAtOnce(c context.Context, id []string) error
|
||||
|
||||
// Wait waits until the task is complete.
|
||||
@ -164,9 +164,9 @@ type Queue interface {
|
||||
// Info returns internal queue information.
|
||||
Info(c context.Context) InfoT
|
||||
|
||||
// Stops the queue from handing out new work items in Poll
|
||||
// Pause stops the queue from handing out new work items in Poll
|
||||
Pause()
|
||||
|
||||
// Starts the queue again, Poll returns new items
|
||||
// Resume starts the queue again, Poll returns new items
|
||||
Resume()
|
||||
}
|
||||
|
@ -15,6 +15,7 @@
|
||||
package bitbucket
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"net/http"
|
||||
"net/url"
|
||||
@ -53,7 +54,7 @@ func New(client, secret string) remote.Remote {
|
||||
|
||||
// Login authenticates an account with Bitbucket using the oauth2 protocol. The
|
||||
// Bitbucket account details are returned when the user is successfully authenticated.
|
||||
func (c *config) Login(w http.ResponseWriter, req *http.Request) (*model.User, error) {
|
||||
func (c *config) Login(ctx context.Context, w http.ResponseWriter, req *http.Request) (*model.User, error) {
|
||||
config := c.newConfig(server.Config.Server.Host)
|
||||
|
||||
// get the OAuth errors
|
||||
@ -72,12 +73,12 @@ func (c *config) Login(w http.ResponseWriter, req *http.Request) (*model.User, e
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
token, err := config.Exchange(oauth2.NoContext, code)
|
||||
token, err := config.Exchange(ctx, code)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
client := internal.NewClient(c.API, config.Client(oauth2.NoContext, token))
|
||||
client := internal.NewClient(ctx, c.API, config.Client(ctx, token))
|
||||
curr, err := client.FindCurrent()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@ -87,8 +88,8 @@ func (c *config) Login(w http.ResponseWriter, req *http.Request) (*model.User, e
|
||||
|
||||
// Auth uses the Bitbucket oauth2 access token and refresh token to authenticate
|
||||
// a session and return the Bitbucket account login.
|
||||
func (c *config) Auth(token, secret string) (string, error) {
|
||||
client := c.newClientToken(token, secret)
|
||||
func (c *config) Auth(ctx context.Context, token, secret string) (string, error) {
|
||||
client := c.newClientToken(ctx, token, secret)
|
||||
user, err := client.FindCurrent()
|
||||
if err != nil {
|
||||
return "", err
|
||||
@ -98,10 +99,10 @@ func (c *config) Auth(token, secret string) (string, error) {
|
||||
|
||||
// Refresh refreshes the Bitbucket oauth2 access token. If the token is
|
||||
// refreshed the user is updated and a true value is returned.
|
||||
func (c *config) Refresh(user *model.User) (bool, error) {
|
||||
func (c *config) Refresh(ctx context.Context, user *model.User) (bool, error) {
|
||||
config := c.newConfig("")
|
||||
source := config.TokenSource(
|
||||
oauth2.NoContext, &oauth2.Token{RefreshToken: user.Secret})
|
||||
ctx, &oauth2.Token{RefreshToken: user.Secret})
|
||||
|
||||
token, err := source.Token()
|
||||
if err != nil || len(token.AccessToken) == 0 {
|
||||
@ -115,12 +116,12 @@ func (c *config) Refresh(user *model.User) (bool, error) {
|
||||
}
|
||||
|
||||
// Teams returns a list of all team membership for the Bitbucket account.
|
||||
func (c *config) Teams(u *model.User) ([]*model.Team, error) {
|
||||
func (c *config) Teams(ctx context.Context, u *model.User) ([]*model.Team, error) {
|
||||
opts := &internal.ListTeamOpts{
|
||||
PageLen: 100,
|
||||
Role: "member",
|
||||
}
|
||||
resp, err := c.newClient(u).ListTeams(opts)
|
||||
resp, err := c.newClient(ctx, u).ListTeams(opts)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@ -128,8 +129,8 @@ func (c *config) Teams(u *model.User) ([]*model.Team, error) {
|
||||
}
|
||||
|
||||
// Repo returns the named Bitbucket repository.
|
||||
func (c *config) Repo(u *model.User, owner, name string) (*model.Repo, error) {
|
||||
repo, err := c.newClient(u).FindRepo(owner, name)
|
||||
func (c *config) Repo(ctx context.Context, u *model.User, owner, name string) (*model.Repo, error) {
|
||||
repo, err := c.newClient(ctx, u).FindRepo(owner, name)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@ -138,8 +139,8 @@ func (c *config) Repo(u *model.User, owner, name string) (*model.Repo, error) {
|
||||
|
||||
// Repos returns a list of all repositories for Bitbucket account, including
|
||||
// organization repositories.
|
||||
func (c *config) Repos(u *model.User) ([]*model.Repo, error) {
|
||||
client := c.newClient(u)
|
||||
func (c *config) Repos(ctx context.Context, u *model.User) ([]*model.Repo, error) {
|
||||
client := c.newClient(ctx, u)
|
||||
|
||||
var all []*model.Repo
|
||||
|
||||
@ -171,8 +172,8 @@ func (c *config) Repos(u *model.User) ([]*model.Repo, error) {
|
||||
// does not have an endpoint to access user permissions, we attempt to fetch
|
||||
// the repository hook list, which is restricted to administrators to calculate
|
||||
// administrative access to a repository.
|
||||
func (c *config) Perm(u *model.User, owner, name string) (*model.Perm, error) {
|
||||
client := c.newClient(u)
|
||||
func (c *config) Perm(ctx context.Context, u *model.User, owner, name string) (*model.Perm, error) {
|
||||
client := c.newClient(ctx, u)
|
||||
|
||||
perms := new(model.Perm)
|
||||
repo, err := client.FindRepo(owner, name)
|
||||
@ -200,40 +201,40 @@ func (c *config) Perm(u *model.User, owner, name string) (*model.Perm, error) {
|
||||
}
|
||||
|
||||
// File fetches the file from the Bitbucket repository and returns its contents.
|
||||
func (c *config) File(u *model.User, r *model.Repo, b *model.Build, f string) ([]byte, error) {
|
||||
config, err := c.newClient(u).FindSource(r.Owner, r.Name, b.Commit, f)
|
||||
func (c *config) File(ctx context.Context, u *model.User, r *model.Repo, b *model.Build, f string) ([]byte, error) {
|
||||
config, err := c.newClient(ctx, u).FindSource(r.Owner, r.Name, b.Commit, f)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return []byte(*config), err
|
||||
}
|
||||
|
||||
func (c *config) Dir(u *model.User, r *model.Repo, b *model.Build, f string) ([]*remote.FileMeta, error) {
|
||||
func (c *config) Dir(ctx context.Context, u *model.User, r *model.Repo, b *model.Build, f string) ([]*remote.FileMeta, error) {
|
||||
return nil, fmt.Errorf("Not implemented")
|
||||
}
|
||||
|
||||
// Status creates a build status for the Bitbucket commit.
|
||||
func (c *config) Status(u *model.User, r *model.Repo, b *model.Build, link string, proc *model.Proc) error {
|
||||
func (c *config) Status(ctx context.Context, u *model.User, r *model.Repo, b *model.Build, link string, proc *model.Proc) error {
|
||||
status := internal.BuildStatus{
|
||||
State: convertStatus(b.Status),
|
||||
Desc: convertDesc(b.Status),
|
||||
Key: "Drone",
|
||||
Url: link,
|
||||
}
|
||||
return c.newClient(u).CreateStatus(r.Owner, r.Name, b.Commit, &status)
|
||||
return c.newClient(ctx, u).CreateStatus(r.Owner, r.Name, b.Commit, &status)
|
||||
}
|
||||
|
||||
// Activate activates the repository by registering repository push hooks with
|
||||
// the Bitbucket repository. Prior to registering hook, previously created hooks
|
||||
// are deleted.
|
||||
func (c *config) Activate(u *model.User, r *model.Repo, link string) error {
|
||||
func (c *config) Activate(ctx context.Context, u *model.User, r *model.Repo, link string) error {
|
||||
rawurl, err := url.Parse(link)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
c.Deactivate(u, r, link)
|
||||
c.Deactivate(ctx, u, r, link)
|
||||
|
||||
return c.newClient(u).CreateHook(r.Owner, r.Name, &internal.Hook{
|
||||
return c.newClient(ctx, u).CreateHook(r.Owner, r.Name, &internal.Hook{
|
||||
Active: true,
|
||||
Desc: rawurl.Host,
|
||||
Events: []string{"repo:push"},
|
||||
@ -243,8 +244,8 @@ func (c *config) Activate(u *model.User, r *model.Repo, link string) error {
|
||||
|
||||
// Deactivate deactives the repository be removing repository push hooks from
|
||||
// the Bitbucket repository.
|
||||
func (c *config) Deactivate(u *model.User, r *model.Repo, link string) error {
|
||||
client := c.newClient(u)
|
||||
func (c *config) Deactivate(ctx context.Context, u *model.User, r *model.Repo, link string) error {
|
||||
client := c.newClient(ctx, u)
|
||||
|
||||
hooks, err := client.ListHooks(r.Owner, r.Name, &internal.ListOpts{})
|
||||
if err != nil {
|
||||
@ -274,13 +275,14 @@ func (c *config) Hook(req *http.Request) (*model.Repo, *model.Build, error) {
|
||||
}
|
||||
|
||||
// helper function to return the bitbucket oauth2 client
|
||||
func (c *config) newClient(u *model.User) *internal.Client {
|
||||
return c.newClientToken(u.Token, u.Secret)
|
||||
func (c *config) newClient(ctx context.Context, u *model.User) *internal.Client {
|
||||
return c.newClientToken(ctx, u.Token, u.Secret)
|
||||
}
|
||||
|
||||
// helper function to return the bitbucket oauth2 client
|
||||
func (c *config) newClientToken(token, secret string) *internal.Client {
|
||||
func (c *config) newClientToken(ctx context.Context, token, secret string) *internal.Client {
|
||||
return internal.NewClientToken(
|
||||
ctx,
|
||||
c.API,
|
||||
c.Client,
|
||||
c.Secret,
|
||||
|
@ -16,6 +16,7 @@ package bitbucket
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"net/http"
|
||||
"net/http/httptest"
|
||||
"testing"
|
||||
@ -35,6 +36,7 @@ func Test_bitbucket(t *testing.T) {
|
||||
c := &config{URL: s.URL, API: s.URL}
|
||||
|
||||
g := goblin.Goblin(t)
|
||||
ctx := context.Background()
|
||||
g.Describe("Bitbucket client", func() {
|
||||
|
||||
g.After(func() {
|
||||
@ -61,13 +63,13 @@ func Test_bitbucket(t *testing.T) {
|
||||
g.It("Should redirect to authorize", func() {
|
||||
w := httptest.NewRecorder()
|
||||
r, _ := http.NewRequest("GET", "", nil)
|
||||
_, err := c.Login(w, r)
|
||||
_, err := c.Login(ctx, w, r)
|
||||
g.Assert(err == nil).IsTrue()
|
||||
g.Assert(w.Code).Equal(http.StatusSeeOther)
|
||||
})
|
||||
g.It("Should return authenticated user", func() {
|
||||
r, _ := http.NewRequest("GET", "?code=code", nil)
|
||||
u, err := c.Login(nil, r)
|
||||
u, err := c.Login(ctx, nil, r)
|
||||
g.Assert(err == nil).IsTrue()
|
||||
g.Assert(u.Login).Equal(fakeUser.Login)
|
||||
g.Assert(u.Token).Equal("2YotnFZFEjr1zCsicMWpAA")
|
||||
@ -76,54 +78,48 @@ func Test_bitbucket(t *testing.T) {
|
||||
g.It("Should handle failure to exchange code", func() {
|
||||
w := httptest.NewRecorder()
|
||||
r, _ := http.NewRequest("GET", "?code=code_bad_request", nil)
|
||||
_, err := c.Login(w, r)
|
||||
_, err := c.Login(ctx, w, r)
|
||||
g.Assert(err != nil).IsTrue()
|
||||
})
|
||||
g.It("Should handle failure to resolve user", func() {
|
||||
r, _ := http.NewRequest("GET", "?code=code_user_not_found", nil)
|
||||
_, err := c.Login(nil, r)
|
||||
_, err := c.Login(ctx, nil, r)
|
||||
g.Assert(err != nil).IsTrue()
|
||||
})
|
||||
g.It("Should handle authentication errors", func() {
|
||||
r, _ := http.NewRequest("GET", "?error=invalid_scope", nil)
|
||||
_, err := c.Login(nil, r)
|
||||
_, err := c.Login(ctx, nil, r)
|
||||
g.Assert(err != nil).IsTrue()
|
||||
})
|
||||
})
|
||||
|
||||
g.Describe("Given an access token", func() {
|
||||
g.It("Should return the authenticated user", func() {
|
||||
login, err := c.Auth(
|
||||
fakeUser.Token,
|
||||
fakeUser.Secret,
|
||||
)
|
||||
login, err := c.Auth(ctx, fakeUser.Token, fakeUser.Secret)
|
||||
g.Assert(err == nil).IsTrue()
|
||||
g.Assert(login).Equal(fakeUser.Login)
|
||||
})
|
||||
g.It("Should handle a failure to resolve user", func() {
|
||||
_, err := c.Auth(
|
||||
fakeUserNotFound.Token,
|
||||
fakeUserNotFound.Secret,
|
||||
)
|
||||
_, err := c.Auth(ctx, fakeUserNotFound.Token, fakeUserNotFound.Secret)
|
||||
g.Assert(err != nil).IsTrue()
|
||||
})
|
||||
})
|
||||
|
||||
g.Describe("Given a refresh token", func() {
|
||||
g.It("Should return a refresh access token", func() {
|
||||
ok, err := c.Refresh(fakeUserRefresh)
|
||||
ok, err := c.Refresh(ctx, fakeUserRefresh)
|
||||
g.Assert(err == nil).IsTrue()
|
||||
g.Assert(ok).IsTrue()
|
||||
g.Assert(fakeUserRefresh.Token).Equal("2YotnFZFEjr1zCsicMWpAA")
|
||||
g.Assert(fakeUserRefresh.Secret).Equal("tGzv3JOkF0XG5Qx2TlKWIA")
|
||||
})
|
||||
g.It("Should handle an empty access token", func() {
|
||||
ok, err := c.Refresh(fakeUserRefreshEmpty)
|
||||
ok, err := c.Refresh(ctx, fakeUserRefreshEmpty)
|
||||
g.Assert(err == nil).IsFalse()
|
||||
g.Assert(ok).IsFalse()
|
||||
})
|
||||
g.It("Should handle a failure to refresh", func() {
|
||||
ok, err := c.Refresh(fakeUserRefreshFail)
|
||||
ok, err := c.Refresh(ctx, fakeUserRefreshFail)
|
||||
g.Assert(err != nil).IsTrue()
|
||||
g.Assert(ok).IsFalse()
|
||||
})
|
||||
@ -131,61 +127,37 @@ func Test_bitbucket(t *testing.T) {
|
||||
|
||||
g.Describe("When requesting a repository", func() {
|
||||
g.It("Should return the details", func() {
|
||||
repo, err := c.Repo(
|
||||
fakeUser,
|
||||
fakeRepo.Owner,
|
||||
fakeRepo.Name,
|
||||
)
|
||||
repo, err := c.Repo(ctx, fakeUser, fakeRepo.Owner, fakeRepo.Name)
|
||||
g.Assert(err == nil).IsTrue()
|
||||
g.Assert(repo.FullName).Equal(fakeRepo.FullName)
|
||||
})
|
||||
g.It("Should handle not found errors", func() {
|
||||
_, err := c.Repo(
|
||||
fakeUser,
|
||||
fakeRepoNotFound.Owner,
|
||||
fakeRepoNotFound.Name,
|
||||
)
|
||||
_, err := c.Repo(ctx, fakeUser, fakeRepoNotFound.Owner, fakeRepoNotFound.Name)
|
||||
g.Assert(err != nil).IsTrue()
|
||||
})
|
||||
})
|
||||
|
||||
g.Describe("When requesting repository permissions", func() {
|
||||
g.It("Should handle not found errors", func() {
|
||||
_, err := c.Perm(
|
||||
fakeUser,
|
||||
fakeRepoNotFound.Owner,
|
||||
fakeRepoNotFound.Name,
|
||||
)
|
||||
_, err := c.Perm(ctx, fakeUser, fakeRepoNotFound.Owner, fakeRepoNotFound.Name)
|
||||
g.Assert(err != nil).IsTrue()
|
||||
})
|
||||
g.It("Should authorize read access", func() {
|
||||
perm, err := c.Perm(
|
||||
fakeUser,
|
||||
fakeRepoReadOnly.Owner,
|
||||
fakeRepoReadOnly.Name,
|
||||
)
|
||||
perm, err := c.Perm(ctx, fakeUser, fakeRepoReadOnly.Owner, fakeRepoReadOnly.Name)
|
||||
g.Assert(err == nil).IsTrue()
|
||||
g.Assert(perm.Pull).IsTrue()
|
||||
g.Assert(perm.Push).IsFalse()
|
||||
g.Assert(perm.Admin).IsFalse()
|
||||
})
|
||||
g.It("Should authorize write access", func() {
|
||||
perm, err := c.Perm(
|
||||
fakeUser,
|
||||
fakeRepoWriteOnly.Owner,
|
||||
fakeRepoWriteOnly.Name,
|
||||
)
|
||||
perm, err := c.Perm(ctx, fakeUser, fakeRepoWriteOnly.Owner, fakeRepoWriteOnly.Name)
|
||||
g.Assert(err == nil).IsTrue()
|
||||
g.Assert(perm.Pull).IsTrue()
|
||||
g.Assert(perm.Push).IsTrue()
|
||||
g.Assert(perm.Admin).IsFalse()
|
||||
})
|
||||
g.It("Should authorize admin access", func() {
|
||||
perm, err := c.Perm(
|
||||
fakeUser,
|
||||
fakeRepoAdmin.Owner,
|
||||
fakeRepoAdmin.Name,
|
||||
)
|
||||
perm, err := c.Perm(ctx, fakeUser, fakeRepoAdmin.Owner, fakeRepoAdmin.Name)
|
||||
g.Assert(err == nil).IsTrue()
|
||||
g.Assert(perm.Pull).IsTrue()
|
||||
g.Assert(perm.Push).IsTrue()
|
||||
@ -195,67 +167,67 @@ func Test_bitbucket(t *testing.T) {
|
||||
|
||||
g.Describe("When requesting user repositories", func() {
|
||||
g.It("Should return the details", func() {
|
||||
repos, err := c.Repos(fakeUser)
|
||||
repos, err := c.Repos(ctx, fakeUser)
|
||||
g.Assert(err == nil).IsTrue()
|
||||
g.Assert(repos[0].FullName).Equal(fakeRepo.FullName)
|
||||
})
|
||||
g.It("Should handle organization not found errors", func() {
|
||||
_, err := c.Repos(fakeUserNoTeams)
|
||||
_, err := c.Repos(ctx, fakeUserNoTeams)
|
||||
g.Assert(err != nil).IsTrue()
|
||||
})
|
||||
g.It("Should handle not found errors", func() {
|
||||
_, err := c.Repos(fakeUserNoRepos)
|
||||
_, err := c.Repos(ctx, fakeUserNoRepos)
|
||||
g.Assert(err != nil).IsTrue()
|
||||
})
|
||||
})
|
||||
|
||||
g.Describe("When requesting user teams", func() {
|
||||
g.It("Should return the details", func() {
|
||||
teams, err := c.Teams(fakeUser)
|
||||
teams, err := c.Teams(ctx, fakeUser)
|
||||
g.Assert(err == nil).IsTrue()
|
||||
g.Assert(teams[0].Login).Equal("superfriends")
|
||||
g.Assert(teams[0].Avatar).Equal("http://i.imgur.com/ZygP55A.jpg")
|
||||
})
|
||||
g.It("Should handle not found error", func() {
|
||||
_, err := c.Teams(fakeUserNoTeams)
|
||||
_, err := c.Teams(ctx, fakeUserNoTeams)
|
||||
g.Assert(err != nil).IsTrue()
|
||||
})
|
||||
})
|
||||
|
||||
g.Describe("When downloading a file", func() {
|
||||
g.It("Should return the bytes", func() {
|
||||
raw, err := c.File(fakeUser, fakeRepo, fakeBuild, "file")
|
||||
raw, err := c.File(ctx, fakeUser, fakeRepo, fakeBuild, "file")
|
||||
g.Assert(err == nil).IsTrue()
|
||||
g.Assert(len(raw) != 0).IsTrue()
|
||||
})
|
||||
g.It("Should handle not found error", func() {
|
||||
_, err := c.File(fakeUser, fakeRepo, fakeBuild, "file_not_found")
|
||||
_, err := c.File(ctx, fakeUser, fakeRepo, fakeBuild, "file_not_found")
|
||||
g.Assert(err != nil).IsTrue()
|
||||
})
|
||||
})
|
||||
|
||||
g.Describe("When activating a repository", func() {
|
||||
g.It("Should error when malformed hook", func() {
|
||||
err := c.Activate(fakeUser, fakeRepo, "%gh&%ij")
|
||||
err := c.Activate(ctx, fakeUser, fakeRepo, "%gh&%ij")
|
||||
g.Assert(err != nil).IsTrue()
|
||||
})
|
||||
g.It("Should create the hook", func() {
|
||||
err := c.Activate(fakeUser, fakeRepo, "http://127.0.0.1")
|
||||
err := c.Activate(ctx, fakeUser, fakeRepo, "http://127.0.0.1")
|
||||
g.Assert(err == nil).IsTrue()
|
||||
})
|
||||
})
|
||||
|
||||
g.Describe("When deactivating a repository", func() {
|
||||
g.It("Should error when listing hooks fails", func() {
|
||||
err := c.Deactivate(fakeUser, fakeRepoNoHooks, "http://127.0.0.1")
|
||||
err := c.Deactivate(ctx, fakeUser, fakeRepoNoHooks, "http://127.0.0.1")
|
||||
g.Assert(err != nil).IsTrue()
|
||||
})
|
||||
g.It("Should successfully remove hooks", func() {
|
||||
err := c.Deactivate(fakeUser, fakeRepo, "http://127.0.0.1")
|
||||
err := c.Deactivate(ctx, fakeUser, fakeRepo, "http://127.0.0.1")
|
||||
g.Assert(err == nil).IsTrue()
|
||||
})
|
||||
g.It("Should successfully deactivate when hook already removed", func() {
|
||||
err := c.Deactivate(fakeUser, fakeRepoEmptyHook, "http://127.0.0.1")
|
||||
err := c.Deactivate(ctx, fakeUser, fakeRepoEmptyHook, "http://127.0.0.1")
|
||||
g.Assert(err == nil).IsTrue()
|
||||
})
|
||||
})
|
||||
@ -283,7 +255,7 @@ func Test_bitbucket(t *testing.T) {
|
||||
})
|
||||
|
||||
g.It("Should update the status", func() {
|
||||
err := c.Status(fakeUser, fakeRepo, fakeBuild, "http://127.0.0.1", nil)
|
||||
err := c.Status(ctx, fakeUser, fakeRepo, fakeBuild, "http://127.0.0.1", nil)
|
||||
g.Assert(err == nil).IsTrue()
|
||||
})
|
||||
|
||||
|
@ -16,6 +16,7 @@ package internal
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io"
|
||||
@ -50,19 +51,24 @@ const (
|
||||
type Client struct {
|
||||
*http.Client
|
||||
base string
|
||||
ctx context.Context
|
||||
}
|
||||
|
||||
func NewClient(url string, client *http.Client) *Client {
|
||||
return &Client{client, url}
|
||||
func NewClient(ctx context.Context, url string, client *http.Client) *Client {
|
||||
return &Client{
|
||||
Client: client,
|
||||
base: url,
|
||||
ctx: ctx,
|
||||
}
|
||||
}
|
||||
|
||||
func NewClientToken(url, client, secret string, token *oauth2.Token) *Client {
|
||||
func NewClientToken(ctx context.Context, url, client, secret string, token *oauth2.Token) *Client {
|
||||
config := &oauth2.Config{
|
||||
ClientID: client,
|
||||
ClientSecret: secret,
|
||||
Endpoint: bitbucket.Endpoint,
|
||||
}
|
||||
return NewClient(url, config.Client(oauth2.NoContext, token))
|
||||
return NewClient(ctx, url, config.Client(ctx, token))
|
||||
}
|
||||
|
||||
func (c *Client) FindCurrent() (*Account, error) {
|
||||
@ -172,7 +178,6 @@ func (c *Client) GetPermission(fullName string) (*RepoPerm, error) {
|
||||
}
|
||||
|
||||
func (c *Client) do(rawurl, method string, in, out interface{}) (*string, error) {
|
||||
|
||||
uri, err := url.Parse(rawurl)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@ -190,7 +195,7 @@ func (c *Client) do(rawurl, method string, in, out interface{}) (*string, error)
|
||||
}
|
||||
|
||||
// creates a new http request to bitbucket.
|
||||
req, err := http.NewRequest(method, uri.String(), buf)
|
||||
req, err := http.NewRequestWithContext(c.ctx, method, uri.String(), buf)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
@ -18,6 +18,7 @@ package bitbucketserver
|
||||
// quality or security standards expected of this project. Please use with caution.
|
||||
|
||||
import (
|
||||
"context"
|
||||
"crypto/rsa"
|
||||
"crypto/tls"
|
||||
"crypto/x509"
|
||||
@ -103,7 +104,7 @@ func New(opts Opts) (remote.Remote, error) {
|
||||
return config, nil
|
||||
}
|
||||
|
||||
func (c *Config) Login(res http.ResponseWriter, req *http.Request) (*model.User, error) {
|
||||
func (c *Config) Login(ctx context.Context, res http.ResponseWriter, req *http.Request) (*model.User, error) {
|
||||
requestToken, u, err := c.Consumer.GetRequestTokenAndUrl("oob")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@ -119,7 +120,7 @@ func (c *Config) Login(res http.ResponseWriter, req *http.Request) (*model.User,
|
||||
return nil, err
|
||||
}
|
||||
|
||||
client := internal.NewClientWithToken(c.URL, c.Consumer, accessToken.Token)
|
||||
client := internal.NewClientWithToken(ctx, c.URL, c.Consumer, accessToken.Token)
|
||||
|
||||
user, err := client.FindCurrentUser()
|
||||
if err != nil {
|
||||
@ -131,12 +132,12 @@ func (c *Config) Login(res http.ResponseWriter, req *http.Request) (*model.User,
|
||||
}
|
||||
|
||||
// Auth is not supported by the Stash driver.
|
||||
func (*Config) Auth(token, secret string) (string, error) {
|
||||
func (*Config) Auth(ctx context.Context, token, secret string) (string, error) {
|
||||
return "", fmt.Errorf("Not Implemented")
|
||||
}
|
||||
|
||||
// Teams is not supported by the Stash driver.
|
||||
func (*Config) Teams(u *model.User) ([]*model.Team, error) {
|
||||
func (*Config) Teams(ctx context.Context, u *model.User) ([]*model.Team, error) {
|
||||
var teams []*model.Team
|
||||
return teams, nil
|
||||
}
|
||||
@ -146,16 +147,16 @@ func (*Config) TeamPerm(u *model.User, org string) (*model.Perm, error) {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
func (c *Config) Repo(u *model.User, owner, name string) (*model.Repo, error) {
|
||||
repo, err := internal.NewClientWithToken(c.URL, c.Consumer, u.Token).FindRepo(owner, name)
|
||||
func (c *Config) Repo(ctx context.Context, u *model.User, owner, name string) (*model.Repo, error) {
|
||||
repo, err := internal.NewClientWithToken(ctx, c.URL, c.Consumer, u.Token).FindRepo(owner, name)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return convertRepo(repo), nil
|
||||
}
|
||||
|
||||
func (c *Config) Repos(u *model.User) ([]*model.Repo, error) {
|
||||
repos, err := internal.NewClientWithToken(c.URL, c.Consumer, u.Token).FindRepos()
|
||||
func (c *Config) Repos(ctx context.Context, u *model.User) ([]*model.Repo, error) {
|
||||
repos, err := internal.NewClientWithToken(ctx, c.URL, c.Consumer, u.Token).FindRepos()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@ -167,24 +168,24 @@ func (c *Config) Repos(u *model.User) ([]*model.Repo, error) {
|
||||
return all, nil
|
||||
}
|
||||
|
||||
func (c *Config) Perm(u *model.User, owner, repo string) (*model.Perm, error) {
|
||||
client := internal.NewClientWithToken(c.URL, c.Consumer, u.Token)
|
||||
func (c *Config) Perm(ctx context.Context, u *model.User, owner, repo string) (*model.Perm, error) {
|
||||
client := internal.NewClientWithToken(ctx, c.URL, c.Consumer, u.Token)
|
||||
|
||||
return client.FindRepoPerms(owner, repo)
|
||||
}
|
||||
|
||||
func (c *Config) File(u *model.User, r *model.Repo, b *model.Build, f string) ([]byte, error) {
|
||||
client := internal.NewClientWithToken(c.URL, c.Consumer, u.Token)
|
||||
func (c *Config) File(ctx context.Context, u *model.User, r *model.Repo, b *model.Build, f string) ([]byte, error) {
|
||||
client := internal.NewClientWithToken(ctx, c.URL, c.Consumer, u.Token)
|
||||
|
||||
return client.FindFileForRepo(r.Owner, r.Name, f, b.Ref)
|
||||
}
|
||||
|
||||
func (c *Config) Dir(u *model.User, r *model.Repo, b *model.Build, f string) ([]*remote.FileMeta, error) {
|
||||
func (c *Config) Dir(ctx context.Context, u *model.User, r *model.Repo, b *model.Build, f string) ([]*remote.FileMeta, error) {
|
||||
return nil, fmt.Errorf("Not implemented")
|
||||
}
|
||||
|
||||
// Status is not supported by the bitbucketserver driver.
|
||||
func (c *Config) Status(u *model.User, r *model.Repo, b *model.Build, link string, proc *model.Proc) error {
|
||||
func (c *Config) Status(ctx context.Context, u *model.User, r *model.Repo, b *model.Build, link string, proc *model.Proc) error {
|
||||
status := internal.BuildStatus{
|
||||
State: convertStatus(b.Status),
|
||||
Desc: convertDesc(b.Status),
|
||||
@ -193,7 +194,7 @@ func (c *Config) Status(u *model.User, r *model.Repo, b *model.Build, link strin
|
||||
Url: link,
|
||||
}
|
||||
|
||||
client := internal.NewClientWithToken(c.URL, c.Consumer, u.Token)
|
||||
client := internal.NewClientWithToken(ctx, c.URL, c.Consumer, u.Token)
|
||||
|
||||
return client.CreateStatus(b.Commit, &status)
|
||||
}
|
||||
@ -217,14 +218,14 @@ func (c *Config) Netrc(user *model.User, r *model.Repo) (*model.Netrc, error) {
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (c *Config) Activate(u *model.User, r *model.Repo, link string) error {
|
||||
client := internal.NewClientWithToken(c.URL, c.Consumer, u.Token)
|
||||
func (c *Config) Activate(ctx context.Context, u *model.User, r *model.Repo, link string) error {
|
||||
client := internal.NewClientWithToken(ctx, c.URL, c.Consumer, u.Token)
|
||||
|
||||
return client.CreateHook(r.Owner, r.Name, link)
|
||||
}
|
||||
|
||||
func (c *Config) Deactivate(u *model.User, r *model.Repo, link string) error {
|
||||
client := internal.NewClientWithToken(c.URL, c.Consumer, u.Token)
|
||||
func (c *Config) Deactivate(ctx context.Context, u *model.User, r *model.Repo, link string) error {
|
||||
client := internal.NewClientWithToken(ctx, c.URL, c.Consumer, u.Token)
|
||||
return client.DeleteHook(r.Owner, r.Name, link)
|
||||
}
|
||||
|
||||
|
@ -16,6 +16,7 @@ package internal
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io"
|
||||
@ -48,20 +49,27 @@ type Client struct {
|
||||
client *http.Client
|
||||
base string
|
||||
accessToken string
|
||||
ctx context.Context
|
||||
}
|
||||
|
||||
func NewClientWithToken(url string, consumer *oauth.Consumer, AccessToken string) *Client {
|
||||
func NewClientWithToken(ctx context.Context, url string, consumer *oauth.Consumer, AccessToken string) *Client {
|
||||
var token oauth.AccessToken
|
||||
token.Token = AccessToken
|
||||
client, err := consumer.MakeHttpClient(&token)
|
||||
if err != nil {
|
||||
log.Error(err)
|
||||
}
|
||||
return &Client{client, url, AccessToken}
|
||||
|
||||
return &Client{
|
||||
client: client,
|
||||
base: url,
|
||||
accessToken: AccessToken,
|
||||
ctx: ctx,
|
||||
}
|
||||
}
|
||||
|
||||
func (c *Client) FindCurrentUser() (*User, error) {
|
||||
CurrentUserIdResponse, err := c.client.Get(fmt.Sprintf(currentUserId, c.base))
|
||||
CurrentUserIdResponse, err := c.doGet(fmt.Sprintf(currentUserId, c.base))
|
||||
if CurrentUserIdResponse != nil {
|
||||
defer CurrentUserIdResponse.Body.Close()
|
||||
}
|
||||
@ -75,7 +83,7 @@ func (c *Client) FindCurrentUser() (*User, error) {
|
||||
}
|
||||
login := string(bits)
|
||||
|
||||
CurrentUserResponse, err := c.client.Get(fmt.Sprintf(pathUser, c.base, login))
|
||||
CurrentUserResponse, err := c.doGet(fmt.Sprintf(pathUser, c.base, login))
|
||||
if CurrentUserResponse != nil {
|
||||
defer CurrentUserResponse.Body.Close()
|
||||
}
|
||||
@ -100,7 +108,7 @@ func (c *Client) FindCurrentUser() (*User, error) {
|
||||
|
||||
func (c *Client) FindRepo(owner string, name string) (*Repo, error) {
|
||||
urlString := fmt.Sprintf(pathRepo, c.base, owner, name)
|
||||
response, err := c.client.Get(urlString)
|
||||
response, err := c.doGet(urlString)
|
||||
if response != nil {
|
||||
defer response.Body.Close()
|
||||
}
|
||||
@ -128,7 +136,7 @@ func (c *Client) FindRepoPerms(owner string, repo string) (*model.Perm, error) {
|
||||
return perms, err
|
||||
}
|
||||
// Must have admin to be able to list hooks. If have access the enable perms
|
||||
resp, err := c.client.Get(fmt.Sprintf(pathHook, c.base, owner, repo, hookName))
|
||||
resp, err := c.doGet(fmt.Sprintf(pathHook, c.base, owner, repo, hookName))
|
||||
if resp != nil {
|
||||
defer resp.Body.Close()
|
||||
}
|
||||
@ -141,7 +149,7 @@ func (c *Client) FindRepoPerms(owner string, repo string) (*model.Perm, error) {
|
||||
}
|
||||
|
||||
func (c *Client) FindFileForRepo(owner string, repo string, fileName string, ref string) ([]byte, error) {
|
||||
response, err := c.client.Get(fmt.Sprintf(pathSource, c.base, owner, repo, fileName, ref))
|
||||
response, err := c.doGet(fmt.Sprintf(pathSource, c.base, owner, repo, fileName, ref))
|
||||
if response != nil {
|
||||
defer response.Body.Close()
|
||||
}
|
||||
@ -203,7 +211,7 @@ func (c *Client) DeleteHook(owner string, name string, link string) error {
|
||||
|
||||
func (c *Client) GetHookDetails(owner string, name string) (*HookPluginDetails, error) {
|
||||
urlString := fmt.Sprintf(pathHookDetails, c.base, owner, name, hookName)
|
||||
response, err := c.client.Get(urlString)
|
||||
response, err := c.doGet(urlString)
|
||||
if response != nil {
|
||||
defer response.Body.Close()
|
||||
}
|
||||
@ -218,7 +226,7 @@ func (c *Client) GetHookDetails(owner string, name string) (*HookPluginDetails,
|
||||
|
||||
func (c *Client) GetHooks(owner string, name string) (*HookSettings, error) {
|
||||
urlString := fmt.Sprintf(pathHookSettings, c.base, owner, name, hookName)
|
||||
response, err := c.client.Get(urlString)
|
||||
response, err := c.doGet(urlString)
|
||||
if response != nil {
|
||||
defer response.Body.Close()
|
||||
}
|
||||
@ -233,9 +241,22 @@ func (c *Client) GetHooks(owner string, name string) (*HookSettings, error) {
|
||||
|
||||
//TODO: make these as as general do with the action
|
||||
|
||||
//Helper function to help create get
|
||||
func (c *Client) doGet(url string) (*http.Response, error) {
|
||||
request, err := http.NewRequestWithContext(c.ctx, "GET", url, nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
request.Header.Add("Content-Type", "application/json")
|
||||
return c.client.Do(request)
|
||||
}
|
||||
|
||||
//Helper function to help create the hook
|
||||
func (c *Client) doPut(url string, body []byte) error {
|
||||
request, err := http.NewRequest("PUT", url, bytes.NewBuffer(body))
|
||||
request, err := http.NewRequestWithContext(c.ctx, "PUT", url, bytes.NewBuffer(body))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
request.Header.Add("Content-Type", "application/json")
|
||||
response, err := c.client.Do(request)
|
||||
if response != nil {
|
||||
@ -258,7 +279,10 @@ func (c *Client) doPost(url string, status *BuildStatus) error {
|
||||
return err
|
||||
}
|
||||
}
|
||||
request, err := http.NewRequest("POST", url, buf)
|
||||
request, err := http.NewRequestWithContext(c.ctx, "POST", url, buf)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
request.Header.Add("Content-Type", "application/json")
|
||||
response, err := c.client.Do(request)
|
||||
if response != nil {
|
||||
@ -269,7 +293,10 @@ func (c *Client) doPost(url string, status *BuildStatus) error {
|
||||
|
||||
//Helper function to do delete on the hook
|
||||
func (c *Client) doDelete(url string) error {
|
||||
request, err := http.NewRequest("DELETE", url, nil)
|
||||
request, err := http.NewRequestWithContext(c.ctx, "DELETE", url, nil)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
response, err := c.client.Do(request)
|
||||
if response != nil {
|
||||
defer response.Body.Close()
|
||||
@ -281,7 +308,7 @@ func (c *Client) doDelete(url string) error {
|
||||
func (c *Client) paginatedRepos(start int) ([]*Repo, error) {
|
||||
limit := 1000
|
||||
requestUrl := fmt.Sprintf(pathRepos, c.base, strconv.Itoa(start), strconv.Itoa(limit))
|
||||
response, err := c.client.Get(requestUrl)
|
||||
response, err := c.doGet(requestUrl)
|
||||
if response != nil {
|
||||
defer response.Body.Close()
|
||||
}
|
||||
|
@ -15,6 +15,7 @@
|
||||
package coding
|
||||
|
||||
import (
|
||||
"context"
|
||||
"crypto/tls"
|
||||
"fmt"
|
||||
"net/http"
|
||||
@ -25,7 +26,6 @@ import (
|
||||
"github.com/woodpecker-ci/woodpecker/server/remote"
|
||||
"github.com/woodpecker-ci/woodpecker/server/remote/coding/internal"
|
||||
|
||||
"golang.org/x/net/context"
|
||||
"golang.org/x/oauth2"
|
||||
)
|
||||
|
||||
@ -78,7 +78,7 @@ type Coding struct {
|
||||
|
||||
// Login authenticates the session and returns the
|
||||
// remote user details.
|
||||
func (c *Coding) Login(res http.ResponseWriter, req *http.Request) (*model.User, error) {
|
||||
func (c *Coding) Login(ctx context.Context, res http.ResponseWriter, req *http.Request) (*model.User, error) {
|
||||
config := c.newConfig(server.Config.Server.Host)
|
||||
|
||||
// get the OAuth errors
|
||||
@ -97,12 +97,12 @@ func (c *Coding) Login(res http.ResponseWriter, req *http.Request) (*model.User,
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
token, err := config.Exchange(c.newContext(), code)
|
||||
token, err := config.Exchange(c.newContext(ctx), code)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
user, err := c.newClientToken(token.AccessToken, token.RefreshToken).GetCurrentUser()
|
||||
user, err := c.newClientToken(ctx, token.AccessToken).GetCurrentUser()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@ -119,8 +119,8 @@ func (c *Coding) Login(res http.ResponseWriter, req *http.Request) (*model.User,
|
||||
|
||||
// Auth authenticates the session and returns the remote user
|
||||
// login for the given token and secret
|
||||
func (c *Coding) Auth(token, secret string) (string, error) {
|
||||
user, err := c.newClientToken(token, secret).GetCurrentUser()
|
||||
func (c *Coding) Auth(ctx context.Context, token, secret string) (string, error) {
|
||||
user, err := c.newClientToken(ctx, token).GetCurrentUser()
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
@ -130,9 +130,9 @@ func (c *Coding) Auth(token, secret string) (string, error) {
|
||||
// Refresh refreshes an oauth token and expiration for the given
|
||||
// user. It returns true if the token was refreshed, false if the
|
||||
// token was not refreshed, and error if it failed to refersh.
|
||||
func (c *Coding) Refresh(u *model.User) (bool, error) {
|
||||
func (c *Coding) Refresh(ctx context.Context, u *model.User) (bool, error) {
|
||||
config := c.newConfig("")
|
||||
source := config.TokenSource(c.newContext(), &oauth2.Token{RefreshToken: u.Secret})
|
||||
source := config.TokenSource(c.newContext(ctx), &oauth2.Token{RefreshToken: u.Secret})
|
||||
token, err := source.Token()
|
||||
if err != nil || len(token.AccessToken) == 0 {
|
||||
return false, err
|
||||
@ -145,9 +145,9 @@ func (c *Coding) Refresh(u *model.User) (bool, error) {
|
||||
}
|
||||
|
||||
// Teams fetches a list of team memberships from the remote system.
|
||||
func (c *Coding) Teams(u *model.User) ([]*model.Team, error) {
|
||||
func (c *Coding) Teams(ctx context.Context, u *model.User) ([]*model.Team, error) {
|
||||
// EMPTY: not implemented in Coding OAuth API
|
||||
return nil, nil
|
||||
return nil, fmt.Errorf("Not implemented")
|
||||
}
|
||||
|
||||
// TeamPerm fetches the named organization permissions from
|
||||
@ -158,12 +158,13 @@ func (c *Coding) TeamPerm(u *model.User, org string) (*model.Perm, error) {
|
||||
}
|
||||
|
||||
// Repo fetches the named repository from the remote system.
|
||||
func (c *Coding) Repo(u *model.User, owner, repo string) (*model.Repo, error) {
|
||||
project, err := c.newClient(u).GetProject(owner, repo)
|
||||
func (c *Coding) Repo(ctx context.Context, u *model.User, owner, name string) (*model.Repo, error) {
|
||||
client := c.newClient(ctx, u)
|
||||
project, err := client.GetProject(owner, name)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
depot, err := c.newClient(u).GetDepot(owner, repo)
|
||||
depot, err := client.GetDepot(owner, name)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@ -181,15 +182,16 @@ func (c *Coding) Repo(u *model.User, owner, repo string) (*model.Repo, error) {
|
||||
}
|
||||
|
||||
// Repos fetches a list of repos from the remote system.
|
||||
func (c *Coding) Repos(u *model.User) ([]*model.Repo, error) {
|
||||
projectList, err := c.newClient(u).GetProjectList()
|
||||
func (c *Coding) Repos(ctx context.Context, u *model.User) ([]*model.Repo, error) {
|
||||
client := c.newClient(ctx, u)
|
||||
projectList, err := client.GetProjectList()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
repos := make([]*model.Repo, 0)
|
||||
for _, project := range projectList {
|
||||
depot, err := c.newClient(u).GetDepot(project.Owner, project.Name)
|
||||
depot, err := client.GetDepot(project.Owner, project.Name)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@ -211,8 +213,8 @@ func (c *Coding) Repos(u *model.User) ([]*model.Repo, error) {
|
||||
|
||||
// Perm fetches the named repository permissions from
|
||||
// the remote system for the specified user.
|
||||
func (c *Coding) Perm(u *model.User, owner, repo string) (*model.Perm, error) {
|
||||
project, err := c.newClient(u).GetProject(owner, repo)
|
||||
func (c *Coding) Perm(ctx context.Context, u *model.User, owner, repo string) (*model.Perm, error) {
|
||||
project, err := c.newClient(ctx, u).GetProject(owner, repo)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@ -228,20 +230,20 @@ func (c *Coding) Perm(u *model.User, owner, repo string) (*model.Perm, error) {
|
||||
|
||||
// File fetches a file from the remote repository and returns in string
|
||||
// format.
|
||||
func (c *Coding) File(u *model.User, r *model.Repo, b *model.Build, f string) ([]byte, error) {
|
||||
data, err := c.newClient(u).GetFile(r.Owner, r.Name, b.Commit, f)
|
||||
func (c *Coding) File(ctx context.Context, u *model.User, r *model.Repo, b *model.Build, f string) ([]byte, error) {
|
||||
data, err := c.newClient(ctx, u).GetFile(r.Owner, r.Name, b.Commit, f)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return data, nil
|
||||
}
|
||||
|
||||
func (c *Coding) Dir(u *model.User, r *model.Repo, b *model.Build, f string) ([]*remote.FileMeta, error) {
|
||||
func (c *Coding) Dir(ctx context.Context, u *model.User, r *model.Repo, b *model.Build, f string) ([]*remote.FileMeta, error) {
|
||||
return nil, fmt.Errorf("Not implemented")
|
||||
}
|
||||
|
||||
// Status sends the commit status to the remote system.
|
||||
func (c *Coding) Status(u *model.User, r *model.Repo, b *model.Build, link string, proc *model.Proc) error {
|
||||
func (c *Coding) Status(ctx context.Context, u *model.User, r *model.Repo, b *model.Build, link string, proc *model.Proc) error {
|
||||
// EMPTY: not implemented in Coding OAuth API
|
||||
return nil
|
||||
}
|
||||
@ -264,14 +266,14 @@ func (c *Coding) Netrc(u *model.User, r *model.Repo) (*model.Netrc, error) {
|
||||
}
|
||||
|
||||
// Activate activates a repository by creating the post-commit hook.
|
||||
func (c *Coding) Activate(u *model.User, r *model.Repo, link string) error {
|
||||
return c.newClient(u).AddWebhook(r.Owner, r.Name, link)
|
||||
func (c *Coding) Activate(ctx context.Context, u *model.User, r *model.Repo, link string) error {
|
||||
return c.newClient(ctx, u).AddWebhook(r.Owner, r.Name, link)
|
||||
}
|
||||
|
||||
// Deactivate deactivates a repository by removing all previously created
|
||||
// post-commit hooks matching the given link.
|
||||
func (c *Coding) Deactivate(u *model.User, r *model.Repo, link string) error {
|
||||
return c.newClient(u).RemoveWebhook(r.Owner, r.Name, link)
|
||||
func (c *Coding) Deactivate(ctx context.Context, u *model.User, r *model.Repo, link string) error {
|
||||
return c.newClient(ctx, u).RemoveWebhook(r.Owner, r.Name, link)
|
||||
}
|
||||
|
||||
// Hook parses the post-commit hook from the Request body and returns the
|
||||
@ -286,11 +288,11 @@ func (c *Coding) Hook(r *http.Request) (*model.Repo, *model.Build, error) {
|
||||
|
||||
// helper function to return the Coding oauth2 context using an HTTPClient that
|
||||
// disables TLS verification if disabled in the remote settings.
|
||||
func (c *Coding) newContext() context.Context {
|
||||
func (c *Coding) newContext(ctx context.Context) context.Context {
|
||||
if !c.SkipVerify {
|
||||
return oauth2.NoContext
|
||||
return ctx
|
||||
}
|
||||
return context.WithValue(nil, oauth2.HTTPClient, &http.Client{
|
||||
return context.WithValue(ctx, oauth2.HTTPClient, &http.Client{
|
||||
Transport: &http.Transport{
|
||||
Proxy: http.ProxyFromEnvironment,
|
||||
TLSClientConfig: &tls.Config{
|
||||
@ -315,12 +317,12 @@ func (c *Coding) newConfig(redirect string) *oauth2.Config {
|
||||
}
|
||||
|
||||
// helper function to return the Coding oauth2 client
|
||||
func (c *Coding) newClient(u *model.User) *internal.Client {
|
||||
return c.newClientToken(u.Token, u.Secret)
|
||||
func (c *Coding) newClient(ctx context.Context, u *model.User) *internal.Client {
|
||||
return c.newClientToken(ctx, u.Token)
|
||||
}
|
||||
|
||||
// helper function to return the Coding oauth2 client
|
||||
func (c *Coding) newClientToken(token, secret string) *internal.Client {
|
||||
func (c *Coding) newClientToken(ctx context.Context, token string) *internal.Client {
|
||||
client := &http.Client{
|
||||
Transport: &http.Transport{
|
||||
Proxy: http.ProxyFromEnvironment,
|
||||
@ -329,7 +331,7 @@ func (c *Coding) newClientToken(token, secret string) *internal.Client {
|
||||
},
|
||||
},
|
||||
}
|
||||
return internal.NewClient(c.URL, "/api", token, "drone", client)
|
||||
return internal.NewClient(ctx, c.URL, "/api", token, "drone", client)
|
||||
}
|
||||
|
||||
func (c *Coding) resourceLink(resourcePath string) string {
|
||||
|
@ -16,6 +16,7 @@ package coding
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"net/http"
|
||||
"net/http/httptest"
|
||||
"testing"
|
||||
@ -33,6 +34,7 @@ func Test_coding(t *testing.T) {
|
||||
s := httptest.NewServer(fixtures.Handler())
|
||||
c := &Coding{URL: s.URL}
|
||||
|
||||
ctx := context.Background()
|
||||
g := goblin.Goblin(t)
|
||||
g.Describe("Coding", func() {
|
||||
|
||||
@ -67,13 +69,13 @@ func Test_coding(t *testing.T) {
|
||||
g.It("Should redirect to authorize", func() {
|
||||
w := httptest.NewRecorder()
|
||||
r, _ := http.NewRequest("GET", "", nil)
|
||||
_, err := c.Login(w, r)
|
||||
_, err := c.Login(ctx, w, r)
|
||||
g.Assert(err == nil).IsTrue()
|
||||
g.Assert(w.Code).Equal(http.StatusSeeOther)
|
||||
})
|
||||
g.It("Should return authenticated user", func() {
|
||||
r, _ := http.NewRequest("GET", "?code=code", nil)
|
||||
u, err := c.Login(nil, r)
|
||||
u, err := c.Login(ctx, nil, r)
|
||||
g.Assert(err == nil).IsTrue()
|
||||
g.Assert(u.Login).Equal(fakeUser.Login)
|
||||
g.Assert(u.Token).Equal(fakeUser.Token)
|
||||
@ -83,43 +85,33 @@ func Test_coding(t *testing.T) {
|
||||
|
||||
g.Describe("Given an access token", func() {
|
||||
g.It("Should return the anthenticated user", func() {
|
||||
login, err := c.Auth(
|
||||
fakeUser.Token,
|
||||
fakeUser.Secret,
|
||||
)
|
||||
login, err := c.Auth(ctx, fakeUser.Token, fakeUser.Secret)
|
||||
g.Assert(err == nil).IsTrue()
|
||||
g.Assert(login).Equal(fakeUser.Login)
|
||||
})
|
||||
g.It("Should handle a failure to resolve user", func() {
|
||||
_, err := c.Auth(
|
||||
fakeUserNotFound.Token,
|
||||
fakeUserNotFound.Secret,
|
||||
)
|
||||
_, err := c.Auth(ctx, fakeUserNotFound.Token, fakeUserNotFound.Secret)
|
||||
g.Assert(err != nil).IsTrue()
|
||||
})
|
||||
})
|
||||
|
||||
g.Describe("Given a refresh token", func() {
|
||||
g.It("Should return a refresh access token", func() {
|
||||
ok, err := c.Refresh(fakeUserRefresh)
|
||||
ok, err := c.Refresh(ctx, fakeUserRefresh)
|
||||
g.Assert(err == nil).IsTrue()
|
||||
g.Assert(ok).IsTrue()
|
||||
g.Assert(fakeUserRefresh.Token).Equal("VDZupx0usVRV4oOd1FCu4xUxgk8SY0TK")
|
||||
g.Assert(fakeUserRefresh.Secret).Equal("BenBQq7TWZ7Cp0aUM47nQjTz2QHNmTWcPctB609n")
|
||||
})
|
||||
g.It("Should handle an invalid refresh token", func() {
|
||||
ok, _ := c.Refresh(fakeUserRefreshInvalid)
|
||||
ok, _ := c.Refresh(ctx, fakeUserRefreshInvalid)
|
||||
g.Assert(ok).IsFalse()
|
||||
})
|
||||
})
|
||||
|
||||
g.Describe("When requesting a repository", func() {
|
||||
g.It("Should return the details", func() {
|
||||
repo, err := c.Repo(
|
||||
fakeUser,
|
||||
fakeRepo.Owner,
|
||||
fakeRepo.Name,
|
||||
)
|
||||
repo, err := c.Repo(ctx, fakeUser, fakeRepo.Owner, fakeRepo.Name)
|
||||
g.Assert(err == nil).IsTrue()
|
||||
g.Assert(repo.FullName).Equal(fakeRepo.FullName)
|
||||
g.Assert(repo.Avatar).Equal(s.URL + fakeRepo.Avatar)
|
||||
@ -130,57 +122,49 @@ func Test_coding(t *testing.T) {
|
||||
g.Assert(repo.IsPrivate).Equal(fakeRepo.IsPrivate)
|
||||
})
|
||||
g.It("Should handle not found errors", func() {
|
||||
_, err := c.Repo(
|
||||
fakeUser,
|
||||
fakeRepoNotFound.Owner,
|
||||
fakeRepoNotFound.Name,
|
||||
)
|
||||
_, err := c.Repo(ctx, fakeUser, fakeRepoNotFound.Owner, fakeRepoNotFound.Name)
|
||||
g.Assert(err != nil).IsTrue()
|
||||
})
|
||||
})
|
||||
|
||||
g.Describe("When requesting repository permissions", func() {
|
||||
g.It("Should authorize admin access for project owner", func() {
|
||||
perm, err := c.Perm(fakeUser, "demo1", "perm_owner")
|
||||
perm, err := c.Perm(ctx, fakeUser, "demo1", "perm_owner")
|
||||
g.Assert(err == nil).IsTrue()
|
||||
g.Assert(perm.Pull).IsTrue()
|
||||
g.Assert(perm.Push).IsTrue()
|
||||
g.Assert(perm.Admin).IsTrue()
|
||||
})
|
||||
g.It("Should authorize admin access for project admin", func() {
|
||||
perm, err := c.Perm(fakeUser, "demo1", "perm_admin")
|
||||
perm, err := c.Perm(ctx, fakeUser, "demo1", "perm_admin")
|
||||
g.Assert(err == nil).IsTrue()
|
||||
g.Assert(perm.Pull).IsTrue()
|
||||
g.Assert(perm.Push).IsTrue()
|
||||
g.Assert(perm.Admin).IsTrue()
|
||||
})
|
||||
g.It("Should authorize read access for project member", func() {
|
||||
perm, err := c.Perm(fakeUser, "demo1", "perm_member")
|
||||
perm, err := c.Perm(ctx, fakeUser, "demo1", "perm_member")
|
||||
g.Assert(err == nil).IsTrue()
|
||||
g.Assert(perm.Pull).IsTrue()
|
||||
g.Assert(perm.Push).IsTrue()
|
||||
g.Assert(perm.Admin).IsFalse()
|
||||
})
|
||||
g.It("Should authorize no access for project guest", func() {
|
||||
perm, err := c.Perm(fakeUser, "demo1", "perm_guest")
|
||||
perm, err := c.Perm(ctx, fakeUser, "demo1", "perm_guest")
|
||||
g.Assert(err == nil).IsTrue()
|
||||
g.Assert(perm.Pull).IsFalse()
|
||||
g.Assert(perm.Push).IsFalse()
|
||||
g.Assert(perm.Admin).IsFalse()
|
||||
})
|
||||
g.It("Should handle not found errors", func() {
|
||||
_, err := c.Perm(
|
||||
fakeUser,
|
||||
fakeRepoNotFound.Owner,
|
||||
fakeRepoNotFound.Name,
|
||||
)
|
||||
_, err := c.Perm(ctx, fakeUser, fakeRepoNotFound.Owner, fakeRepoNotFound.Name)
|
||||
g.Assert(err != nil).IsTrue()
|
||||
})
|
||||
})
|
||||
|
||||
g.Describe("When downloading a file", func() {
|
||||
g.It("Should return file for specified build", func() {
|
||||
data, err := c.File(fakeUser, fakeRepo, fakeBuild, ".drone.yml")
|
||||
data, err := c.File(ctx, fakeUser, fakeRepo, fakeBuild, ".drone.yml")
|
||||
g.Assert(err == nil).IsTrue()
|
||||
g.Assert(string(data)).Equal("pipeline:\n test:\n image: golang:1.6\n commands:\n - go test\n")
|
||||
})
|
||||
@ -213,22 +197,22 @@ func Test_coding(t *testing.T) {
|
||||
|
||||
g.Describe("When activating a repository", func() {
|
||||
g.It("Should create the hook", func() {
|
||||
err := c.Activate(fakeUser, fakeRepo, "http://127.0.0.1")
|
||||
err := c.Activate(ctx, fakeUser, fakeRepo, "http://127.0.0.1")
|
||||
g.Assert(err == nil).IsTrue()
|
||||
})
|
||||
g.It("Should update the hook when exists", func() {
|
||||
err := c.Activate(fakeUser, fakeRepo, "http://127.0.0.2")
|
||||
err := c.Activate(ctx, fakeUser, fakeRepo, "http://127.0.0.2")
|
||||
g.Assert(err == nil).IsTrue()
|
||||
})
|
||||
})
|
||||
|
||||
g.Describe("When deactivating a repository", func() {
|
||||
g.It("Should successfully remove hook", func() {
|
||||
err := c.Deactivate(fakeUser, fakeRepo, "http://127.0.0.3")
|
||||
err := c.Deactivate(ctx, fakeUser, fakeRepo, "http://127.0.0.3")
|
||||
g.Assert(err == nil).IsTrue()
|
||||
})
|
||||
g.It("Should successfully deactivate when hook already removed", func() {
|
||||
err := c.Deactivate(fakeUser, fakeRepo, "http://127.0.0.4")
|
||||
err := c.Deactivate(ctx, fakeUser, fakeRepo, "http://127.0.0.4")
|
||||
g.Assert(err == nil).IsTrue()
|
||||
})
|
||||
})
|
||||
|
@ -15,6 +15,7 @@
|
||||
package internal
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
@ -29,6 +30,7 @@ type Client struct {
|
||||
token string
|
||||
agent string
|
||||
client *http.Client
|
||||
ctx context.Context
|
||||
}
|
||||
|
||||
type GenericAPIResponse struct {
|
||||
@ -36,13 +38,14 @@ type GenericAPIResponse struct {
|
||||
Data json.RawMessage `json:"data,omitempty"`
|
||||
}
|
||||
|
||||
func NewClient(baseURL, apiPath, token, agent string, client *http.Client) *Client {
|
||||
func NewClient(ctx context.Context, baseURL, apiPath, token, agent string, client *http.Client) *Client {
|
||||
return &Client{
|
||||
baseURL: baseURL,
|
||||
apiPath: apiPath,
|
||||
token: token,
|
||||
agent: agent,
|
||||
client: client,
|
||||
ctx: ctx,
|
||||
}
|
||||
}
|
||||
|
||||
@ -63,10 +66,10 @@ func (c *Client) Do(method, u string, params url.Values) ([]byte, error) {
|
||||
var req *http.Request
|
||||
var err error
|
||||
if method != "GET" {
|
||||
req, err = http.NewRequest(method, rawURL+"?access_token="+c.token, strings.NewReader(params.Encode()))
|
||||
req, err = http.NewRequestWithContext(c.ctx, method, rawURL+"?access_token="+c.token, strings.NewReader(params.Encode()))
|
||||
req.Header.Set("Content-Type", "application/x-www-form-urlencoded;charset=UTF-8")
|
||||
} else {
|
||||
req, err = http.NewRequest("GET", rawURL+"?"+params.Encode(), nil)
|
||||
req, err = http.NewRequestWithContext(c.ctx, "GET", rawURL+"?"+params.Encode(), nil)
|
||||
}
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("fail to create request for url %q: %v", rawURL, err)
|
||||
|
@ -91,7 +91,7 @@ func New(opts Opts) (remote.Remote, error) {
|
||||
|
||||
// Login authenticates an account with Gitea using basic authentication. The
|
||||
// Gitea account details are returned when the user is successfully authenticated.
|
||||
func (c *Gitea) Login(w http.ResponseWriter, req *http.Request) (*model.User, error) {
|
||||
func (c *Gitea) Login(ctx context.Context, w http.ResponseWriter, req *http.Request) (*model.User, error) {
|
||||
config := &oauth2.Config{
|
||||
ClientID: c.ClientID,
|
||||
ClientSecret: c.ClientSecret,
|
||||
@ -123,7 +123,7 @@ func (c *Gitea) Login(w http.ResponseWriter, req *http.Request) (*model.User, er
|
||||
return nil, err
|
||||
}
|
||||
|
||||
client, err := c.newClientToken(token.AccessToken)
|
||||
client, err := c.newClientToken(ctx, token.AccessToken)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@ -144,8 +144,8 @@ func (c *Gitea) Login(w http.ResponseWriter, req *http.Request) (*model.User, er
|
||||
|
||||
// Auth uses the Gitea oauth2 access token and refresh token to authenticate
|
||||
// a session and return the Gitea account login.
|
||||
func (c *Gitea) Auth(token, _ string) (string, error) {
|
||||
client, err := c.newClientToken(token)
|
||||
func (c *Gitea) Auth(ctx context.Context, token, secret string) (string, error) {
|
||||
client, err := c.newClientToken(ctx, token)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
@ -158,7 +158,7 @@ func (c *Gitea) Auth(token, _ string) (string, error) {
|
||||
|
||||
// Refresh refreshes the Gitea oauth2 access token. If the token is
|
||||
// refreshed the user is updated and a true value is returned.
|
||||
func (c *Gitea) Refresh(user *model.User) (bool, error) {
|
||||
func (c *Gitea) Refresh(ctx context.Context, user *model.User) (bool, error) {
|
||||
config := &oauth2.Config{
|
||||
ClientID: c.ClientID,
|
||||
ClientSecret: c.ClientSecret,
|
||||
@ -167,7 +167,7 @@ func (c *Gitea) Refresh(user *model.User) (bool, error) {
|
||||
TokenURL: fmt.Sprintf(accessTokenURL, c.URL),
|
||||
},
|
||||
}
|
||||
source := config.TokenSource(context.TODO(), &oauth2.Token{RefreshToken: user.Secret})
|
||||
source := config.TokenSource(ctx, &oauth2.Token{RefreshToken: user.Secret})
|
||||
|
||||
token, err := source.Token()
|
||||
if err != nil || len(token.AccessToken) == 0 {
|
||||
@ -181,8 +181,8 @@ func (c *Gitea) Refresh(user *model.User) (bool, error) {
|
||||
}
|
||||
|
||||
// Teams is supported by the Gitea driver.
|
||||
func (c *Gitea) Teams(u *model.User) ([]*model.Team, error) {
|
||||
client, err := c.newClientToken(u.Token)
|
||||
func (c *Gitea) Teams(ctx context.Context, u *model.User) ([]*model.Team, error) {
|
||||
client, err := c.newClientToken(ctx, u.Token)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@ -222,8 +222,8 @@ func (c *Gitea) TeamPerm(u *model.User, org string) (*model.Perm, error) {
|
||||
}
|
||||
|
||||
// Repo returns the named Gitea repository.
|
||||
func (c *Gitea) Repo(u *model.User, owner, name string) (*model.Repo, error) {
|
||||
client, err := c.newClientToken(u.Token)
|
||||
func (c *Gitea) Repo(ctx context.Context, u *model.User, owner, name string) (*model.Repo, error) {
|
||||
client, err := c.newClientToken(ctx, u.Token)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@ -240,10 +240,10 @@ func (c *Gitea) Repo(u *model.User, owner, name string) (*model.Repo, error) {
|
||||
|
||||
// Repos returns a list of all repositories for the Gitea account, including
|
||||
// organization repositories.
|
||||
func (c *Gitea) Repos(u *model.User) ([]*model.Repo, error) {
|
||||
func (c *Gitea) Repos(ctx context.Context, u *model.User) ([]*model.Repo, error) {
|
||||
repos := make([]*model.Repo, 0, perPage)
|
||||
|
||||
client, err := c.newClientToken(u.Token)
|
||||
client, err := c.newClientToken(ctx, u.Token)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@ -278,8 +278,8 @@ func (c *Gitea) Repos(u *model.User) ([]*model.Repo, error) {
|
||||
}
|
||||
|
||||
// Perm returns the user permissions for the named Gitea repository.
|
||||
func (c *Gitea) Perm(u *model.User, owner, name string) (*model.Perm, error) {
|
||||
client, err := c.newClientToken(u.Token)
|
||||
func (c *Gitea) Perm(ctx context.Context, u *model.User, owner, name string) (*model.Perm, error) {
|
||||
client, err := c.newClientToken(ctx, u.Token)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@ -292,8 +292,8 @@ func (c *Gitea) Perm(u *model.User, owner, name string) (*model.Perm, error) {
|
||||
}
|
||||
|
||||
// File fetches the file from the Gitea repository and returns its contents.
|
||||
func (c *Gitea) File(u *model.User, r *model.Repo, b *model.Build, f string) ([]byte, error) {
|
||||
client, err := c.newClientToken(u.Token)
|
||||
func (c *Gitea) File(ctx context.Context, u *model.User, r *model.Repo, b *model.Build, f string) ([]byte, error) {
|
||||
client, err := c.newClientToken(ctx, u.Token)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@ -302,10 +302,10 @@ func (c *Gitea) File(u *model.User, r *model.Repo, b *model.Build, f string) ([]
|
||||
return cfg, err
|
||||
}
|
||||
|
||||
func (c *Gitea) Dir(u *model.User, r *model.Repo, b *model.Build, f string) ([]*remote.FileMeta, error) {
|
||||
func (c *Gitea) Dir(ctx context.Context, u *model.User, r *model.Repo, b *model.Build, f string) ([]*remote.FileMeta, error) {
|
||||
var configs []*remote.FileMeta
|
||||
|
||||
client, err := c.newClientToken(u.Token)
|
||||
client, err := c.newClientToken(ctx, u.Token)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@ -321,7 +321,7 @@ func (c *Gitea) Dir(u *model.User, r *model.Repo, b *model.Build, f string) ([]*
|
||||
for _, e := range tree.Entries {
|
||||
// Filter path matching pattern and type file (blob)
|
||||
if m, _ := filepath.Match(f, e.Path); m && e.Type == "blob" {
|
||||
data, err := c.File(u, r, b, e.Path)
|
||||
data, err := c.File(ctx, u, r, b, e.Path)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("multi-pipeline cannot get %s: %s", e.Path, err)
|
||||
}
|
||||
@ -337,8 +337,8 @@ func (c *Gitea) Dir(u *model.User, r *model.Repo, b *model.Build, f string) ([]*
|
||||
}
|
||||
|
||||
// Status is supported by the Gitea driver.
|
||||
func (c *Gitea) Status(u *model.User, r *model.Repo, b *model.Build, link string, proc *model.Proc) error {
|
||||
client, err := c.newClientToken(u.Token)
|
||||
func (c *Gitea) Status(ctx context.Context, u *model.User, r *model.Repo, b *model.Build, link string, proc *model.Proc) error {
|
||||
client, err := c.newClientToken(ctx, u.Token)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@ -381,7 +381,7 @@ func (c *Gitea) Netrc(u *model.User, r *model.Repo) (*model.Netrc, error) {
|
||||
|
||||
// Activate activates the repository by registering post-commit hooks with
|
||||
// the Gitea repository.
|
||||
func (c *Gitea) Activate(u *model.User, r *model.Repo, link string) error {
|
||||
func (c *Gitea) Activate(ctx context.Context, u *model.User, r *model.Repo, link string) error {
|
||||
config := map[string]string{
|
||||
"url": link,
|
||||
"secret": r.Hash,
|
||||
@ -394,7 +394,7 @@ func (c *Gitea) Activate(u *model.User, r *model.Repo, link string) error {
|
||||
Active: true,
|
||||
}
|
||||
|
||||
client, err := c.newClientToken(u.Token)
|
||||
client, err := c.newClientToken(ctx, u.Token)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@ -404,8 +404,8 @@ func (c *Gitea) Activate(u *model.User, r *model.Repo, link string) error {
|
||||
|
||||
// Deactivate deactives the repository be removing repository push hooks from
|
||||
// the Gitea repository.
|
||||
func (c *Gitea) Deactivate(u *model.User, r *model.Repo, link string) error {
|
||||
client, err := c.newClientToken(u.Token)
|
||||
func (c *Gitea) Deactivate(ctx context.Context, u *model.User, r *model.Repo, link string) error {
|
||||
client, err := c.newClientToken(ctx, u.Token)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@ -431,14 +431,14 @@ func (c *Gitea) Hook(r *http.Request) (*model.Repo, *model.Build, error) {
|
||||
}
|
||||
|
||||
// helper function to return the Gitea client with Token
|
||||
func (c *Gitea) newClientToken(token string) (*gitea.Client, error) {
|
||||
func (c *Gitea) newClientToken(ctx context.Context, token string) (*gitea.Client, error) {
|
||||
httpClient := &http.Client{}
|
||||
if c.SkipVerify {
|
||||
httpClient.Transport = &http.Transport{
|
||||
TLSClientConfig: &tls.Config{InsecureSkipVerify: true},
|
||||
}
|
||||
}
|
||||
return gitea.NewClient(c.URL, gitea.SetToken(token), gitea.SetHTTPClient(httpClient))
|
||||
return gitea.NewClient(c.URL, gitea.SetToken(token), gitea.SetHTTPClient(httpClient), gitea.SetContext(ctx))
|
||||
}
|
||||
|
||||
const (
|
||||
|
@ -15,6 +15,7 @@
|
||||
package gitea
|
||||
|
||||
import (
|
||||
"context"
|
||||
"net/http/httptest"
|
||||
"testing"
|
||||
|
||||
@ -33,6 +34,7 @@ func Test_gitea(t *testing.T) {
|
||||
SkipVerify: true,
|
||||
})
|
||||
|
||||
ctx := context.Background()
|
||||
g := goblin.Goblin(t)
|
||||
g.Describe("Gitea", func() {
|
||||
|
||||
@ -89,7 +91,7 @@ func Test_gitea(t *testing.T) {
|
||||
|
||||
g.Describe("Requesting a repository", func() {
|
||||
g.It("Should return the repository details", func() {
|
||||
repo, err := c.Repo(fakeUser, fakeRepo.Owner, fakeRepo.Name)
|
||||
repo, err := c.Repo(ctx, fakeUser, fakeRepo.Owner, fakeRepo.Name)
|
||||
g.Assert(err == nil).IsTrue()
|
||||
g.Assert(repo.Owner).Equal(fakeRepo.Owner)
|
||||
g.Assert(repo.Name).Equal(fakeRepo.Name)
|
||||
@ -99,57 +101,57 @@ func Test_gitea(t *testing.T) {
|
||||
g.Assert(repo.Link).Equal("http://localhost/test_name/repo_name")
|
||||
})
|
||||
g.It("Should handle a not found error", func() {
|
||||
_, err := c.Repo(fakeUser, fakeRepoNotFound.Owner, fakeRepoNotFound.Name)
|
||||
_, err := c.Repo(ctx, fakeUser, fakeRepoNotFound.Owner, fakeRepoNotFound.Name)
|
||||
g.Assert(err != nil).IsTrue()
|
||||
})
|
||||
})
|
||||
|
||||
g.Describe("Requesting repository permissions", func() {
|
||||
g.It("Should return the permission details", func() {
|
||||
perm, err := c.Perm(fakeUser, fakeRepo.Owner, fakeRepo.Name)
|
||||
perm, err := c.Perm(ctx, fakeUser, fakeRepo.Owner, fakeRepo.Name)
|
||||
g.Assert(err == nil).IsTrue()
|
||||
g.Assert(perm.Admin).IsTrue()
|
||||
g.Assert(perm.Push).IsTrue()
|
||||
g.Assert(perm.Pull).IsTrue()
|
||||
})
|
||||
g.It("Should handle a not found error", func() {
|
||||
_, err := c.Perm(fakeUser, fakeRepoNotFound.Owner, fakeRepoNotFound.Name)
|
||||
_, err := c.Perm(ctx, fakeUser, fakeRepoNotFound.Owner, fakeRepoNotFound.Name)
|
||||
g.Assert(err != nil).IsTrue()
|
||||
})
|
||||
})
|
||||
|
||||
g.Describe("Requesting a repository list", func() {
|
||||
g.It("Should return the repository list", func() {
|
||||
repos, err := c.Repos(fakeUser)
|
||||
repos, err := c.Repos(ctx, fakeUser)
|
||||
g.Assert(err == nil).IsTrue()
|
||||
g.Assert(repos[0].Owner).Equal(fakeRepo.Owner)
|
||||
g.Assert(repos[0].Name).Equal(fakeRepo.Name)
|
||||
g.Assert(repos[0].FullName).Equal(fakeRepo.Owner + "/" + fakeRepo.Name)
|
||||
})
|
||||
g.It("Should handle a not found error", func() {
|
||||
_, err := c.Repos(fakeUserNoRepos)
|
||||
_, err := c.Repos(ctx, fakeUserNoRepos)
|
||||
g.Assert(err != nil).IsTrue()
|
||||
})
|
||||
})
|
||||
|
||||
g.It("Should register repository hooks", func() {
|
||||
err := c.Activate(fakeUser, fakeRepo, "http://localhost")
|
||||
err := c.Activate(ctx, fakeUser, fakeRepo, "http://localhost")
|
||||
g.Assert(err == nil).IsTrue()
|
||||
})
|
||||
|
||||
g.It("Should remove repository hooks", func() {
|
||||
err := c.Deactivate(fakeUser, fakeRepo, "http://localhost")
|
||||
err := c.Deactivate(ctx, fakeUser, fakeRepo, "http://localhost")
|
||||
g.Assert(err == nil).IsTrue()
|
||||
})
|
||||
|
||||
g.It("Should return a repository file", func() {
|
||||
raw, err := c.File(fakeUser, fakeRepo, fakeBuild, ".drone.yml")
|
||||
raw, err := c.File(ctx, fakeUser, fakeRepo, fakeBuild, ".drone.yml")
|
||||
g.Assert(err == nil).IsTrue()
|
||||
g.Assert(string(raw)).Equal("{ platform: linux/amd64 }")
|
||||
})
|
||||
|
||||
g.It("Should return nil from send build status", func() {
|
||||
err := c.Status(fakeUser, fakeRepo, fakeBuild, "http://gitea.io", nil)
|
||||
err := c.Status(ctx, fakeUser, fakeRepo, fakeBuild, "http://gitea.io", nil)
|
||||
g.Assert(err == nil).IsTrue()
|
||||
})
|
||||
|
||||
|
@ -15,6 +15,7 @@
|
||||
package github
|
||||
|
||||
import (
|
||||
"context"
|
||||
"crypto/tls"
|
||||
"fmt"
|
||||
"net"
|
||||
@ -28,8 +29,8 @@ import (
|
||||
"github.com/woodpecker-ci/woodpecker/server/model"
|
||||
"github.com/woodpecker-ci/woodpecker/server/remote"
|
||||
|
||||
// TODO upgrade to v39 to pass context down
|
||||
"github.com/google/go-github/github"
|
||||
"golang.org/x/net/context"
|
||||
"golang.org/x/oauth2"
|
||||
)
|
||||
|
||||
@ -82,9 +83,6 @@ func New(opts Opts) (remote.Remote, error) {
|
||||
r.API = r.URL + "/api/v3/"
|
||||
}
|
||||
|
||||
// Hack to enable oauth2 access in older GHE
|
||||
// TODO: dont use deprecated func
|
||||
oauth2.RegisterBrokenAuthHeaderProvider(r.URL)
|
||||
return r, nil
|
||||
}
|
||||
|
||||
@ -104,7 +102,7 @@ type client struct {
|
||||
}
|
||||
|
||||
// Login authenticates the session and returns the remote user details.
|
||||
func (c *client) Login(res http.ResponseWriter, req *http.Request) (*model.User, error) {
|
||||
func (c *client) Login(ctx context.Context, res http.ResponseWriter, req *http.Request) (*model.User, error) {
|
||||
config := c.newConfig(req)
|
||||
|
||||
// get the OAuth errors
|
||||
@ -126,12 +124,12 @@ func (c *client) Login(res http.ResponseWriter, req *http.Request) (*model.User,
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
token, err := config.Exchange(c.newContext(), code)
|
||||
token, err := config.Exchange(c.newContext(ctx), code)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
client := c.newClientToken(token.AccessToken)
|
||||
client := c.newClientToken(ctx, token.AccessToken)
|
||||
user, _, err := client.Users.Get("")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@ -155,8 +153,8 @@ func (c *client) Login(res http.ResponseWriter, req *http.Request) (*model.User,
|
||||
}
|
||||
|
||||
// Auth returns the GitHub user login for the given access token.
|
||||
func (c *client) Auth(token, secret string) (string, error) {
|
||||
client := c.newClientToken(token)
|
||||
func (c *client) Auth(ctx context.Context, token, secret string) (string, error) {
|
||||
client := c.newClientToken(ctx, token)
|
||||
user, _, err := client.Users.Get("")
|
||||
if err != nil {
|
||||
return "", err
|
||||
@ -165,8 +163,8 @@ func (c *client) Auth(token, secret string) (string, error) {
|
||||
}
|
||||
|
||||
// Teams returns a list of all team membership for the GitHub account.
|
||||
func (c *client) Teams(u *model.User) ([]*model.Team, error) {
|
||||
client := c.newClientToken(u.Token)
|
||||
func (c *client) Teams(ctx context.Context, u *model.User) ([]*model.Team, error) {
|
||||
client := c.newClientToken(ctx, u.Token)
|
||||
|
||||
opts := new(github.ListOptions)
|
||||
opts.Page = 1
|
||||
@ -184,8 +182,8 @@ func (c *client) Teams(u *model.User) ([]*model.Team, error) {
|
||||
}
|
||||
|
||||
// Repo returns the named GitHub repository.
|
||||
func (c *client) Repo(u *model.User, owner, name string) (*model.Repo, error) {
|
||||
client := c.newClientToken(u.Token)
|
||||
func (c *client) Repo(ctx context.Context, u *model.User, owner, name string) (*model.Repo, error) {
|
||||
client := c.newClientToken(ctx, u.Token)
|
||||
repo, _, err := client.Repositories.Get(owner, name)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@ -195,8 +193,8 @@ func (c *client) Repo(u *model.User, owner, name string) (*model.Repo, error) {
|
||||
|
||||
// Repos returns a list of all repositories for GitHub account, including
|
||||
// organization repositories.
|
||||
func (c *client) Repos(u *model.User) ([]*model.Repo, error) {
|
||||
client := c.newClientToken(u.Token)
|
||||
func (c *client) Repos(ctx context.Context, u *model.User) ([]*model.Repo, error) {
|
||||
client := c.newClientToken(ctx, u.Token)
|
||||
|
||||
opts := new(github.RepositoryListOptions)
|
||||
opts.PerPage = 100
|
||||
@ -215,8 +213,8 @@ func (c *client) Repos(u *model.User) ([]*model.Repo, error) {
|
||||
}
|
||||
|
||||
// Perm returns the user permissions for the named GitHub repository.
|
||||
func (c *client) Perm(u *model.User, owner, name string) (*model.Perm, error) {
|
||||
client := c.newClientToken(u.Token)
|
||||
func (c *client) Perm(ctx context.Context, u *model.User, owner, name string) (*model.Perm, error) {
|
||||
client := c.newClientToken(ctx, u.Token)
|
||||
repo, _, err := client.Repositories.Get(owner, name)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@ -225,8 +223,8 @@ func (c *client) Perm(u *model.User, owner, name string) (*model.Perm, error) {
|
||||
}
|
||||
|
||||
// File fetches the file from the GitHub repository and returns its contents.
|
||||
func (c *client) File(u *model.User, r *model.Repo, b *model.Build, f string) ([]byte, error) {
|
||||
client := c.newClientToken(u.Token)
|
||||
func (c *client) File(ctx context.Context, u *model.User, r *model.Repo, b *model.Build, f string) ([]byte, error) {
|
||||
client := c.newClientToken(ctx, u.Token)
|
||||
|
||||
opts := new(github.RepositoryContentGetOptions)
|
||||
opts.Ref = b.Commit
|
||||
@ -240,8 +238,8 @@ func (c *client) File(u *model.User, r *model.Repo, b *model.Build, f string) ([
|
||||
return data.Decode()
|
||||
}
|
||||
|
||||
func (c *client) Dir(u *model.User, r *model.Repo, b *model.Build, f string) ([]*remote.FileMeta, error) {
|
||||
client := c.newClientToken(u.Token)
|
||||
func (c *client) Dir(ctx context.Context, u *model.User, r *model.Repo, b *model.Build, f string) ([]*remote.FileMeta, error) {
|
||||
client := c.newClientToken(ctx, u.Token)
|
||||
|
||||
opts := new(github.RepositoryContentGetOptions)
|
||||
opts.Ref = b.Commit
|
||||
@ -255,7 +253,7 @@ func (c *client) Dir(u *model.User, r *model.Repo, b *model.Build, f string) ([]
|
||||
|
||||
for _, file := range data {
|
||||
go func(path string) {
|
||||
content, err := c.File(u, r, b, path)
|
||||
content, err := c.File(ctx, u, r, b, path)
|
||||
if err != nil {
|
||||
errc <- err
|
||||
} else {
|
||||
@ -305,8 +303,8 @@ func (c *client) Netrc(u *model.User, r *model.Repo) (*model.Netrc, error) {
|
||||
|
||||
// Deactivate deactives the repository be removing registered push hooks from
|
||||
// the GitHub repository.
|
||||
func (c *client) Deactivate(u *model.User, r *model.Repo, link string) error {
|
||||
client := c.newClientToken(u.Token)
|
||||
func (c *client) Deactivate(ctx context.Context, u *model.User, r *model.Repo, link string) error {
|
||||
client := c.newClientToken(ctx, u.Token)
|
||||
hooks, _, err := client.Repositories.ListHooks(r.Owner, r.Name, nil)
|
||||
if err != nil {
|
||||
return err
|
||||
@ -321,11 +319,11 @@ func (c *client) Deactivate(u *model.User, r *model.Repo, link string) error {
|
||||
|
||||
// helper function to return the GitHub oauth2 context using an HTTPClient that
|
||||
// disables TLS verification if disabled in the remote settings.
|
||||
func (c *client) newContext() context.Context {
|
||||
func (c *client) newContext(ctx context.Context) context.Context {
|
||||
if !c.SkipVerify {
|
||||
return oauth2.NoContext
|
||||
return ctx
|
||||
}
|
||||
return context.WithValue(nil, oauth2.HTTPClient, &http.Client{
|
||||
return context.WithValue(ctx, oauth2.HTTPClient, &http.Client{
|
||||
Transport: &http.Transport{
|
||||
Proxy: http.ProxyFromEnvironment,
|
||||
TLSClientConfig: &tls.Config{
|
||||
@ -359,11 +357,11 @@ func (c *client) newConfig(req *http.Request) *oauth2.Config {
|
||||
}
|
||||
|
||||
// helper function to return the GitHub oauth2 client
|
||||
func (c *client) newClientToken(token string) *github.Client {
|
||||
func (c *client) newClientToken(ctx context.Context, token string) *github.Client {
|
||||
ts := oauth2.StaticTokenSource(
|
||||
&oauth2.Token{AccessToken: token},
|
||||
)
|
||||
tc := oauth2.NewClient(oauth2.NoContext, ts)
|
||||
tc := oauth2.NewClient(ctx, ts)
|
||||
if c.SkipVerify {
|
||||
tc.Transport.(*oauth2.Transport).Base = &http.Transport{
|
||||
Proxy: http.ProxyFromEnvironment,
|
||||
@ -427,8 +425,8 @@ func matchingHooks(hooks []github.Hook, rawurl string) *github.Hook {
|
||||
|
||||
// Status sends the commit status to the remote system.
|
||||
// An example would be the GitHub pull request status.
|
||||
func (c *client) Status(u *model.User, r *model.Repo, b *model.Build, link string, proc *model.Proc) error {
|
||||
client := c.newClientToken(u.Token)
|
||||
func (c *client) Status(ctx context.Context, u *model.User, r *model.Repo, b *model.Build, link string, proc *model.Proc) error {
|
||||
client := c.newClientToken(ctx, u.Token)
|
||||
switch b.Event {
|
||||
case "deployment":
|
||||
return deploymentStatus(client, r, b, link)
|
||||
@ -486,11 +484,11 @@ func deploymentStatus(client *github.Client, r *model.Repo, b *model.Build, link
|
||||
|
||||
// Activate activates a repository by creating the post-commit hook and
|
||||
// adding the SSH deploy key, if applicable.
|
||||
func (c *client) Activate(u *model.User, r *model.Repo, link string) error {
|
||||
if err := c.Deactivate(u, r, link); err != nil {
|
||||
func (c *client) Activate(ctx context.Context, u *model.User, r *model.Repo, link string) error {
|
||||
if err := c.Deactivate(ctx, u, r, link); err != nil {
|
||||
return err
|
||||
}
|
||||
client := c.newClientToken(u.Token)
|
||||
client := c.newClientToken(ctx, u.Token)
|
||||
hook := &github.Hook{
|
||||
Name: github.String("web"),
|
||||
Events: []string{
|
||||
|
@ -15,6 +15,7 @@
|
||||
package github
|
||||
|
||||
import (
|
||||
"context"
|
||||
"net/http/httptest"
|
||||
"testing"
|
||||
|
||||
@ -34,6 +35,7 @@ func Test_github(t *testing.T) {
|
||||
SkipVerify: true,
|
||||
})
|
||||
|
||||
ctx := context.Background()
|
||||
g := goblin.Goblin(t)
|
||||
g.Describe("GitHub", func() {
|
||||
|
||||
@ -95,7 +97,7 @@ func Test_github(t *testing.T) {
|
||||
|
||||
g.Describe("Requesting a repository", func() {
|
||||
g.It("Should return the repository details", func() {
|
||||
repo, err := c.Repo(fakeUser, fakeRepo.Owner, fakeRepo.Name)
|
||||
repo, err := c.Repo(ctx, fakeUser, fakeRepo.Owner, fakeRepo.Name)
|
||||
g.Assert(err == nil).IsTrue()
|
||||
g.Assert(repo.Owner).Equal(fakeRepo.Owner)
|
||||
g.Assert(repo.Name).Equal(fakeRepo.Name)
|
||||
@ -105,21 +107,21 @@ func Test_github(t *testing.T) {
|
||||
g.Assert(repo.Link).Equal(fakeRepo.Link)
|
||||
})
|
||||
g.It("Should handle a not found error", func() {
|
||||
_, err := c.Repo(fakeUser, fakeRepoNotFound.Owner, fakeRepoNotFound.Name)
|
||||
_, err := c.Repo(ctx, fakeUser, fakeRepoNotFound.Owner, fakeRepoNotFound.Name)
|
||||
g.Assert(err != nil).IsTrue()
|
||||
})
|
||||
})
|
||||
|
||||
g.Describe("Requesting repository permissions", func() {
|
||||
g.It("Should return the permission details", func() {
|
||||
perm, err := c.Perm(fakeUser, fakeRepo.Owner, fakeRepo.Name)
|
||||
perm, err := c.Perm(ctx, fakeUser, fakeRepo.Owner, fakeRepo.Name)
|
||||
g.Assert(err == nil).IsTrue()
|
||||
g.Assert(perm.Admin).IsTrue()
|
||||
g.Assert(perm.Push).IsTrue()
|
||||
g.Assert(perm.Pull).IsTrue()
|
||||
})
|
||||
g.It("Should handle a not found error", func() {
|
||||
_, err := c.Perm(fakeUser, fakeRepoNotFound.Owner, fakeRepoNotFound.Name)
|
||||
_, err := c.Perm(ctx, fakeUser, fakeRepoNotFound.Owner, fakeRepoNotFound.Name)
|
||||
g.Assert(err != nil).IsTrue()
|
||||
})
|
||||
})
|
||||
|
@ -15,6 +15,7 @@
|
||||
package gitlab
|
||||
|
||||
import (
|
||||
"context"
|
||||
"crypto/tls"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
@ -113,7 +114,7 @@ func Load(config string) *Gitlab {
|
||||
|
||||
// Login authenticates the session and returns the
|
||||
// remote user details.
|
||||
func (g *Gitlab) Login(res http.ResponseWriter, req *http.Request) (*model.User, error) {
|
||||
func (g *Gitlab) Login(ctx context.Context, res http.ResponseWriter, req *http.Request) (*model.User, error) {
|
||||
|
||||
var config = &oauth2.Config{
|
||||
ClientId: g.Client,
|
||||
@ -193,7 +194,7 @@ func (g *Gitlab) Login(res http.ResponseWriter, req *http.Request) (*model.User,
|
||||
return user, nil
|
||||
}
|
||||
|
||||
func (g *Gitlab) Auth(token, secret string) (string, error) {
|
||||
func (g *Gitlab) Auth(ctx context.Context, token, secret string) (string, error) {
|
||||
client := NewClient(g.URL, token, g.SkipVerify)
|
||||
login, err := client.CurrentUser()
|
||||
if err != nil {
|
||||
@ -202,7 +203,7 @@ func (g *Gitlab) Auth(token, secret string) (string, error) {
|
||||
return login.Username, nil
|
||||
}
|
||||
|
||||
func (g *Gitlab) Teams(u *model.User) ([]*model.Team, error) {
|
||||
func (g *Gitlab) Teams(ctx context.Context, u *model.User) ([]*model.Team, error) {
|
||||
client := NewClient(g.URL, u.Token, g.SkipVerify)
|
||||
groups, err := client.AllGroups()
|
||||
if err != nil {
|
||||
@ -218,7 +219,7 @@ func (g *Gitlab) Teams(u *model.User) ([]*model.Team, error) {
|
||||
}
|
||||
|
||||
// Repo fetches the named repository from the remote system.
|
||||
func (g *Gitlab) Repo(u *model.User, owner, name string) (*model.Repo, error) {
|
||||
func (g *Gitlab) Repo(ctx context.Context, u *model.User, owner, name string) (*model.Repo, error) {
|
||||
client := NewClient(g.URL, u.Token, g.SkipVerify)
|
||||
id, err := GetProjectId(g, client, owner, name)
|
||||
if err != nil {
|
||||
@ -257,7 +258,7 @@ func (g *Gitlab) Repo(u *model.User, owner, name string) (*model.Repo, error) {
|
||||
}
|
||||
|
||||
// Repos fetches a list of repos from the remote system.
|
||||
func (g *Gitlab) Repos(u *model.User) ([]*model.Repo, error) {
|
||||
func (g *Gitlab) Repos(ctx context.Context, u *model.User) ([]*model.Repo, error) {
|
||||
client := NewClient(g.URL, u.Token, g.SkipVerify)
|
||||
|
||||
var repos = []*model.Repo{}
|
||||
@ -297,7 +298,7 @@ func (g *Gitlab) Repos(u *model.User) ([]*model.Repo, error) {
|
||||
}
|
||||
|
||||
// Perm fetches the named repository from the remote system.
|
||||
func (g *Gitlab) Perm(u *model.User, owner, name string) (*model.Perm, error) {
|
||||
func (g *Gitlab) Perm(ctx context.Context, u *model.User, owner, name string) (*model.Perm, error) {
|
||||
|
||||
client := NewClient(g.URL, u.Token, g.SkipVerify)
|
||||
id, err := GetProjectId(g, client, owner, name)
|
||||
@ -324,35 +325,35 @@ func (g *Gitlab) Perm(u *model.User, owner, name string) (*model.Perm, error) {
|
||||
}
|
||||
|
||||
// File fetches a file from the remote repository and returns in string format.
|
||||
func (g *Gitlab) File(user *model.User, repo *model.Repo, build *model.Build, f string) ([]byte, error) {
|
||||
var client = NewClient(g.URL, user.Token, g.SkipVerify)
|
||||
id, err := GetProjectId(g, client, repo.Owner, repo.Name)
|
||||
func (g *Gitlab) File(ctx context.Context, u *model.User, r *model.Repo, b *model.Build, f string) ([]byte, error) {
|
||||
var client = NewClient(g.URL, u.Token, g.SkipVerify)
|
||||
id, err := GetProjectId(g, client, r.Owner, r.Name)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
out, err := client.RepoRawFileRef(id, build.Commit, f)
|
||||
out, err := client.RepoRawFileRef(id, b.Commit, f)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return out, err
|
||||
}
|
||||
|
||||
func (c *Gitlab) Dir(u *model.User, r *model.Repo, b *model.Build, f string) ([]*remote.FileMeta, error) {
|
||||
func (c *Gitlab) Dir(ctx context.Context, u *model.User, r *model.Repo, b *model.Build, f string) ([]*remote.FileMeta, error) {
|
||||
return nil, fmt.Errorf("Not implemented")
|
||||
}
|
||||
|
||||
// NOTE Currently gitlab doesn't support status for commits and events,
|
||||
// also if we want get MR status in gitlab we need implement a special plugin for gitlab,
|
||||
// gitlab uses API to fetch build status on client side. But for now we skip this.
|
||||
func (g *Gitlab) Status(u *model.User, repo *model.Repo, b *model.Build, link string, proc *model.Proc) error {
|
||||
func (g *Gitlab) Status(ctx context.Context, u *model.User, r *model.Repo, b *model.Build, link string, proc *model.Proc) error {
|
||||
client := NewClient(g.URL, u.Token, g.SkipVerify)
|
||||
|
||||
status := getStatus(b.Status)
|
||||
desc := getDesc(b.Status)
|
||||
|
||||
client.SetStatus(
|
||||
ns(repo.Owner, repo.Name),
|
||||
ns(r.Owner, r.Name),
|
||||
b.Commit,
|
||||
status,
|
||||
desc,
|
||||
@ -407,9 +408,9 @@ func (g *Gitlab) Netrc(u *model.User, r *model.Repo) (*model.Netrc, error) {
|
||||
|
||||
// Activate activates a repository by adding a Post-commit hook and
|
||||
// a Public Deploy key, if applicable.
|
||||
func (g *Gitlab) Activate(user *model.User, repo *model.Repo, link string) error {
|
||||
var client = NewClient(g.URL, user.Token, g.SkipVerify)
|
||||
id, err := GetProjectId(g, client, repo.Owner, repo.Name)
|
||||
func (g *Gitlab) Activate(ctx context.Context, u *model.User, r *model.Repo, link string) error {
|
||||
var client = NewClient(g.URL, u.Token, g.SkipVerify)
|
||||
id, err := GetProjectId(g, client, r.Owner, r.Name)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@ -432,9 +433,9 @@ func (g *Gitlab) Activate(user *model.User, repo *model.Repo, link string) error
|
||||
|
||||
// Deactivate removes a repository by removing all the post-commit hooks
|
||||
// which are equal to link and removing the SSH deploy key.
|
||||
func (g *Gitlab) Deactivate(user *model.User, repo *model.Repo, link string) error {
|
||||
var client = NewClient(g.URL, user.Token, g.SkipVerify)
|
||||
id, err := GetProjectId(g, client, repo.Owner, repo.Name)
|
||||
func (g *Gitlab) Deactivate(ctx context.Context, u *model.User, r *model.Repo, link string) error {
|
||||
var client = NewClient(g.URL, u.Token, g.SkipVerify)
|
||||
id, err := GetProjectId(g, client, r.Owner, r.Name)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -16,6 +16,7 @@ package gitlab
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"net/http"
|
||||
"testing"
|
||||
|
||||
@ -43,13 +44,14 @@ func Test_Gitlab(t *testing.T) {
|
||||
Owner: "diaspora",
|
||||
}
|
||||
|
||||
ctx := context.Background()
|
||||
g := goblin.Goblin(t)
|
||||
g.Describe("Gitlab Plugin", func() {
|
||||
// Test projects method
|
||||
g.Describe("AllProjects", func() {
|
||||
g.It("Should return only non-archived projects is hidden", func() {
|
||||
gitlab.HideArchives = true
|
||||
_projects, err := gitlab.Repos(&user)
|
||||
_projects, err := gitlab.Repos(ctx, &user)
|
||||
|
||||
g.Assert(err == nil).IsTrue()
|
||||
g.Assert(len(_projects)).Equal(1)
|
||||
@ -57,7 +59,7 @@ func Test_Gitlab(t *testing.T) {
|
||||
|
||||
g.It("Should return all the projects", func() {
|
||||
gitlab.HideArchives = false
|
||||
_projects, err := gitlab.Repos(&user)
|
||||
_projects, err := gitlab.Repos(ctx, &user)
|
||||
|
||||
g.Assert(err == nil).IsTrue()
|
||||
g.Assert(len(_projects)).Equal(2)
|
||||
@ -67,7 +69,7 @@ func Test_Gitlab(t *testing.T) {
|
||||
// Test repository method
|
||||
g.Describe("Repo", func() {
|
||||
g.It("Should return valid repo", func() {
|
||||
_repo, err := gitlab.Repo(&user, "diaspora", "diaspora-client")
|
||||
_repo, err := gitlab.Repo(ctx, &user, "diaspora", "diaspora-client")
|
||||
|
||||
g.Assert(err == nil).IsTrue()
|
||||
g.Assert(_repo.Name).Equal("diaspora-client")
|
||||
@ -76,7 +78,7 @@ func Test_Gitlab(t *testing.T) {
|
||||
})
|
||||
|
||||
g.It("Should return error, when repo not exist", func() {
|
||||
_, err := gitlab.Repo(&user, "not-existed", "not-existed")
|
||||
_, err := gitlab.Repo(ctx, &user, "not-existed", "not-existed")
|
||||
|
||||
g.Assert(err != nil).IsTrue()
|
||||
})
|
||||
@ -85,21 +87,21 @@ func Test_Gitlab(t *testing.T) {
|
||||
// Test permissions method
|
||||
g.Describe("Perm", func() {
|
||||
g.It("Should return repo permissions", func() {
|
||||
perm, err := gitlab.Perm(&user, "diaspora", "diaspora-client")
|
||||
perm, err := gitlab.Perm(ctx, &user, "diaspora", "diaspora-client")
|
||||
g.Assert(err == nil).IsTrue()
|
||||
g.Assert(perm.Admin).Equal(true)
|
||||
g.Assert(perm.Pull).Equal(true)
|
||||
g.Assert(perm.Push).Equal(true)
|
||||
})
|
||||
g.It("Should return repo permissions when user is admin", func() {
|
||||
perm, err := gitlab.Perm(&user, "brightbox", "puppet")
|
||||
perm, err := gitlab.Perm(ctx, &user, "brightbox", "puppet")
|
||||
g.Assert(err == nil).IsTrue()
|
||||
g.Assert(perm.Admin).Equal(true)
|
||||
g.Assert(perm.Pull).Equal(true)
|
||||
g.Assert(perm.Push).Equal(true)
|
||||
})
|
||||
g.It("Should return error, when repo is not exist", func() {
|
||||
_, err := gitlab.Perm(&user, "not-existed", "not-existed")
|
||||
_, err := gitlab.Perm(ctx, &user, "not-existed", "not-existed")
|
||||
|
||||
g.Assert(err != nil).IsTrue()
|
||||
})
|
||||
@ -108,13 +110,13 @@ func Test_Gitlab(t *testing.T) {
|
||||
// Test activate method
|
||||
g.Describe("Activate", func() {
|
||||
g.It("Should be success", func() {
|
||||
err := gitlab.Activate(&user, &repo, "http://example.com/api/hook/test/test?access_token=token")
|
||||
err := gitlab.Activate(ctx, &user, &repo, "http://example.com/api/hook/test/test?access_token=token")
|
||||
|
||||
g.Assert(err == nil).IsTrue()
|
||||
})
|
||||
|
||||
g.It("Should be failed, when token not given", func() {
|
||||
err := gitlab.Activate(&user, &repo, "http://example.com/api/hook/test/test")
|
||||
err := gitlab.Activate(ctx, &user, &repo, "http://example.com/api/hook/test/test")
|
||||
|
||||
g.Assert(err != nil).IsTrue()
|
||||
})
|
||||
@ -123,7 +125,7 @@ func Test_Gitlab(t *testing.T) {
|
||||
// Test deactivate method
|
||||
g.Describe("Deactivate", func() {
|
||||
g.It("Should be success", func() {
|
||||
err := gitlab.Deactivate(&user, &repo, "http://example.com/api/hook/test/test?access_token=token")
|
||||
err := gitlab.Deactivate(ctx, &user, &repo, "http://example.com/api/hook/test/test?access_token=token")
|
||||
|
||||
g.Assert(err == nil).IsTrue()
|
||||
})
|
||||
|
@ -15,6 +15,7 @@
|
||||
package gitlab3
|
||||
|
||||
import (
|
||||
"context"
|
||||
"crypto/tls"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
@ -113,7 +114,7 @@ func Load(config string) *Gitlab {
|
||||
|
||||
// Login authenticates the session and returns the
|
||||
// remote user details.
|
||||
func (g *Gitlab) Login(res http.ResponseWriter, req *http.Request) (*model.User, error) {
|
||||
func (g *Gitlab) Login(ctx context.Context, res http.ResponseWriter, req *http.Request) (*model.User, error) {
|
||||
|
||||
var config = &oauth2.Config{
|
||||
ClientId: g.Client,
|
||||
@ -193,7 +194,7 @@ func (g *Gitlab) Login(res http.ResponseWriter, req *http.Request) (*model.User,
|
||||
return user, nil
|
||||
}
|
||||
|
||||
func (g *Gitlab) Auth(token, secret string) (string, error) {
|
||||
func (g *Gitlab) Auth(ctx context.Context, token, secret string) (string, error) {
|
||||
client := NewClient(g.URL, token, g.SkipVerify)
|
||||
login, err := client.CurrentUser()
|
||||
if err != nil {
|
||||
@ -202,7 +203,7 @@ func (g *Gitlab) Auth(token, secret string) (string, error) {
|
||||
return login.Username, nil
|
||||
}
|
||||
|
||||
func (g *Gitlab) Teams(u *model.User) ([]*model.Team, error) {
|
||||
func (g *Gitlab) Teams(ctx context.Context, u *model.User) ([]*model.Team, error) {
|
||||
client := NewClient(g.URL, u.Token, g.SkipVerify)
|
||||
groups, err := client.AllGroups()
|
||||
if err != nil {
|
||||
@ -218,7 +219,7 @@ func (g *Gitlab) Teams(u *model.User) ([]*model.Team, error) {
|
||||
}
|
||||
|
||||
// Repo fetches the named repository from the remote system.
|
||||
func (g *Gitlab) Repo(u *model.User, owner, name string) (*model.Repo, error) {
|
||||
func (g *Gitlab) Repo(ctx context.Context, u *model.User, owner, name string) (*model.Repo, error) {
|
||||
client := NewClient(g.URL, u.Token, g.SkipVerify)
|
||||
id, err := GetProjectId(g, client, owner, name)
|
||||
if err != nil {
|
||||
@ -257,7 +258,7 @@ func (g *Gitlab) Repo(u *model.User, owner, name string) (*model.Repo, error) {
|
||||
}
|
||||
|
||||
// Repos fetches a list of repos from the remote system.
|
||||
func (g *Gitlab) Repos(u *model.User) ([]*model.Repo, error) {
|
||||
func (g *Gitlab) Repos(ctx context.Context, u *model.User) ([]*model.Repo, error) {
|
||||
client := NewClient(g.URL, u.Token, g.SkipVerify)
|
||||
|
||||
var repos = []*model.Repo{}
|
||||
@ -297,7 +298,7 @@ func (g *Gitlab) Repos(u *model.User) ([]*model.Repo, error) {
|
||||
}
|
||||
|
||||
// Perm fetches the named repository from the remote system.
|
||||
func (g *Gitlab) Perm(u *model.User, owner, name string) (*model.Perm, error) {
|
||||
func (g *Gitlab) Perm(ctx context.Context, u *model.User, owner, name string) (*model.Perm, error) {
|
||||
|
||||
client := NewClient(g.URL, u.Token, g.SkipVerify)
|
||||
id, err := GetProjectId(g, client, owner, name)
|
||||
@ -324,7 +325,7 @@ func (g *Gitlab) Perm(u *model.User, owner, name string) (*model.Perm, error) {
|
||||
}
|
||||
|
||||
// File fetches a file from the remote repository and returns in string format.
|
||||
func (g *Gitlab) File(user *model.User, repo *model.Repo, build *model.Build, f string) ([]byte, error) {
|
||||
func (g *Gitlab) File(ctx context.Context, user *model.User, repo *model.Repo, build *model.Build, f string) ([]byte, error) {
|
||||
var client = NewClient(g.URL, user.Token, g.SkipVerify)
|
||||
id, err := GetProjectId(g, client, repo.Owner, repo.Name)
|
||||
if err != nil {
|
||||
@ -338,21 +339,21 @@ func (g *Gitlab) File(user *model.User, repo *model.Repo, build *model.Build, f
|
||||
return out, err
|
||||
}
|
||||
|
||||
func (c *Gitlab) Dir(u *model.User, r *model.Repo, b *model.Build, f string) ([]*remote.FileMeta, error) {
|
||||
func (c *Gitlab) Dir(ctx context.Context, u *model.User, r *model.Repo, b *model.Build, f string) ([]*remote.FileMeta, error) {
|
||||
return nil, fmt.Errorf("Not implemented")
|
||||
}
|
||||
|
||||
// NOTE Currently gitlab doesn't support status for commits and events,
|
||||
// also if we want get MR status in gitlab we need implement a special plugin for gitlab,
|
||||
// gitlab uses API to fetch build status on client side. But for now we skip this.
|
||||
func (g *Gitlab) Status(u *model.User, repo *model.Repo, b *model.Build, link string, proc *model.Proc) error {
|
||||
func (g *Gitlab) Status(ctx context.Context, u *model.User, r *model.Repo, b *model.Build, link string, proc *model.Proc) error {
|
||||
client := NewClient(g.URL, u.Token, g.SkipVerify)
|
||||
|
||||
status := getStatus(b.Status)
|
||||
desc := getDesc(b.Status)
|
||||
|
||||
client.SetStatus(
|
||||
ns(repo.Owner, repo.Name),
|
||||
ns(r.Owner, r.Name),
|
||||
b.Commit,
|
||||
status,
|
||||
desc,
|
||||
@ -407,9 +408,9 @@ func (g *Gitlab) Netrc(u *model.User, r *model.Repo) (*model.Netrc, error) {
|
||||
|
||||
// Activate activates a repository by adding a Post-commit hook and
|
||||
// a Public Deploy key, if applicable.
|
||||
func (g *Gitlab) Activate(user *model.User, repo *model.Repo, link string) error {
|
||||
var client = NewClient(g.URL, user.Token, g.SkipVerify)
|
||||
id, err := GetProjectId(g, client, repo.Owner, repo.Name)
|
||||
func (g *Gitlab) Activate(ctx context.Context, u *model.User, r *model.Repo, link string) error {
|
||||
var client = NewClient(g.URL, u.Token, g.SkipVerify)
|
||||
id, err := GetProjectId(g, client, r.Owner, r.Name)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@ -432,9 +433,9 @@ func (g *Gitlab) Activate(user *model.User, repo *model.Repo, link string) error
|
||||
|
||||
// Deactivate removes a repository by removing all the post-commit hooks
|
||||
// which are equal to link and removing the SSH deploy key.
|
||||
func (g *Gitlab) Deactivate(user *model.User, repo *model.Repo, link string) error {
|
||||
var client = NewClient(g.URL, user.Token, g.SkipVerify)
|
||||
id, err := GetProjectId(g, client, repo.Owner, repo.Name)
|
||||
func (g *Gitlab) Deactivate(ctx context.Context, u *model.User, r *model.Repo, link string) error {
|
||||
var client = NewClient(g.URL, u.Token, g.SkipVerify)
|
||||
id, err := GetProjectId(g, client, r.Owner, r.Name)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -49,7 +49,7 @@ func Test_Gitlab(t *testing.T) {
|
||||
g.Describe("AllProjects", func() {
|
||||
g.It("Should return only non-archived projects is hidden", func() {
|
||||
gitlab.HideArchives = true
|
||||
_projects, err := gitlab.Repos(&user)
|
||||
_projects, err := gitlab.Repos(nil, &user)
|
||||
|
||||
g.Assert(err == nil).IsTrue()
|
||||
g.Assert(len(_projects)).Equal(1)
|
||||
@ -57,7 +57,7 @@ func Test_Gitlab(t *testing.T) {
|
||||
|
||||
g.It("Should return all the projects", func() {
|
||||
gitlab.HideArchives = false
|
||||
_projects, err := gitlab.Repos(&user)
|
||||
_projects, err := gitlab.Repos(nil, &user)
|
||||
|
||||
g.Assert(err == nil).IsTrue()
|
||||
g.Assert(len(_projects)).Equal(2)
|
||||
@ -67,7 +67,7 @@ func Test_Gitlab(t *testing.T) {
|
||||
// Test repository method
|
||||
g.Describe("Repo", func() {
|
||||
g.It("Should return valid repo", func() {
|
||||
_repo, err := gitlab.Repo(&user, "diaspora", "diaspora-client")
|
||||
_repo, err := gitlab.Repo(nil, &user, "diaspora", "diaspora-client")
|
||||
|
||||
g.Assert(err == nil).IsTrue()
|
||||
g.Assert(_repo.Name).Equal("diaspora-client")
|
||||
@ -76,7 +76,7 @@ func Test_Gitlab(t *testing.T) {
|
||||
})
|
||||
|
||||
g.It("Should return error, when repo not exist", func() {
|
||||
_, err := gitlab.Repo(&user, "not-existed", "not-existed")
|
||||
_, err := gitlab.Repo(nil, &user, "not-existed", "not-existed")
|
||||
|
||||
g.Assert(err != nil).IsTrue()
|
||||
})
|
||||
@ -85,21 +85,21 @@ func Test_Gitlab(t *testing.T) {
|
||||
// Test permissions method
|
||||
g.Describe("Perm", func() {
|
||||
g.It("Should return repo permissions", func() {
|
||||
perm, err := gitlab.Perm(&user, "diaspora", "diaspora-client")
|
||||
perm, err := gitlab.Perm(nil, &user, "diaspora", "diaspora-client")
|
||||
g.Assert(err == nil).IsTrue()
|
||||
g.Assert(perm.Admin).Equal(true)
|
||||
g.Assert(perm.Pull).Equal(true)
|
||||
g.Assert(perm.Push).Equal(true)
|
||||
})
|
||||
g.It("Should return repo permissions when user is admin", func() {
|
||||
perm, err := gitlab.Perm(&user, "brightbox", "puppet")
|
||||
perm, err := gitlab.Perm(nil, &user, "brightbox", "puppet")
|
||||
g.Assert(err == nil).IsTrue()
|
||||
g.Assert(perm.Admin).Equal(true)
|
||||
g.Assert(perm.Pull).Equal(true)
|
||||
g.Assert(perm.Push).Equal(true)
|
||||
})
|
||||
g.It("Should return error, when repo is not exist", func() {
|
||||
_, err := gitlab.Perm(&user, "not-existed", "not-existed")
|
||||
_, err := gitlab.Perm(nil, &user, "not-existed", "not-existed")
|
||||
|
||||
g.Assert(err != nil).IsTrue()
|
||||
})
|
||||
@ -108,13 +108,13 @@ func Test_Gitlab(t *testing.T) {
|
||||
// Test activate method
|
||||
g.Describe("Activate", func() {
|
||||
g.It("Should be success", func() {
|
||||
err := gitlab.Activate(&user, &repo, "http://example.com/api/hook/test/test?access_token=token")
|
||||
err := gitlab.Activate(nil, &user, &repo, "http://example.com/api/hook/test/test?access_token=token")
|
||||
|
||||
g.Assert(err == nil).IsTrue()
|
||||
})
|
||||
|
||||
g.It("Should be failed, when token not given", func() {
|
||||
err := gitlab.Activate(&user, &repo, "http://example.com/api/hook/test/test")
|
||||
err := gitlab.Activate(nil, &user, &repo, "http://example.com/api/hook/test/test")
|
||||
|
||||
g.Assert(err != nil).IsTrue()
|
||||
})
|
||||
@ -123,7 +123,7 @@ func Test_Gitlab(t *testing.T) {
|
||||
// Test deactivate method
|
||||
g.Describe("Deactivate", func() {
|
||||
g.It("Should be success", func() {
|
||||
err := gitlab.Deactivate(&user, &repo, "http://example.com/api/hook/test/test?access_token=token")
|
||||
err := gitlab.Deactivate(nil, &user, &repo, "http://example.com/api/hook/test/test?access_token=token")
|
||||
|
||||
g.Assert(err == nil).IsTrue()
|
||||
})
|
||||
|
@ -15,6 +15,7 @@
|
||||
package gogs
|
||||
|
||||
import (
|
||||
"context"
|
||||
"crypto/tls"
|
||||
"fmt"
|
||||
"net"
|
||||
@ -68,7 +69,7 @@ func New(opts Opts) (remote.Remote, error) {
|
||||
|
||||
// Login authenticates an account with Gogs using basic authentication. The
|
||||
// Gogs account details are returned when the user is successfully authenticated.
|
||||
func (c *client) Login(res http.ResponseWriter, req *http.Request) (*model.User, error) {
|
||||
func (c *client) Login(ctx context.Context, res http.ResponseWriter, req *http.Request) (*model.User, error) {
|
||||
var (
|
||||
username = req.FormValue("username")
|
||||
password = req.FormValue("password")
|
||||
@ -122,12 +123,12 @@ func (c *client) Login(res http.ResponseWriter, req *http.Request) (*model.User,
|
||||
}
|
||||
|
||||
// Auth is not supported by the Gogs driver.
|
||||
func (c *client) Auth(token, secret string) (string, error) {
|
||||
func (c *client) Auth(ctx context.Context, token, secret string) (string, error) {
|
||||
return "", fmt.Errorf("Not Implemented")
|
||||
}
|
||||
|
||||
// Teams is not supported by the Gogs driver.
|
||||
func (c *client) Teams(u *model.User) ([]*model.Team, error) {
|
||||
func (c *client) Teams(ctx context.Context, u *model.User) ([]*model.Team, error) {
|
||||
client := c.newClientToken(u.Token)
|
||||
orgs, err := client.ListMyOrgs()
|
||||
if err != nil {
|
||||
@ -142,7 +143,7 @@ func (c *client) Teams(u *model.User) ([]*model.Team, error) {
|
||||
}
|
||||
|
||||
// Repo returns the named Gogs repository.
|
||||
func (c *client) Repo(u *model.User, owner, name string) (*model.Repo, error) {
|
||||
func (c *client) Repo(ctx context.Context, u *model.User, owner, name string) (*model.Repo, error) {
|
||||
client := c.newClientToken(u.Token)
|
||||
repo, err := client.GetRepo(owner, name)
|
||||
if err != nil {
|
||||
@ -153,7 +154,7 @@ func (c *client) Repo(u *model.User, owner, name string) (*model.Repo, error) {
|
||||
|
||||
// Repos returns a list of all repositories for the Gogs account, including
|
||||
// organization repositories.
|
||||
func (c *client) Repos(u *model.User) ([]*model.Repo, error) {
|
||||
func (c *client) Repos(ctx context.Context, u *model.User) ([]*model.Repo, error) {
|
||||
repos := []*model.Repo{}
|
||||
|
||||
client := c.newClientToken(u.Token)
|
||||
@ -169,7 +170,7 @@ func (c *client) Repos(u *model.User) ([]*model.Repo, error) {
|
||||
}
|
||||
|
||||
// Perm returns the user permissions for the named Gogs repository.
|
||||
func (c *client) Perm(u *model.User, owner, name string) (*model.Perm, error) {
|
||||
func (c *client) Perm(ctx context.Context, u *model.User, owner, name string) (*model.Perm, error) {
|
||||
client := c.newClientToken(u.Token)
|
||||
repo, err := client.GetRepo(owner, name)
|
||||
if err != nil {
|
||||
@ -179,7 +180,7 @@ func (c *client) Perm(u *model.User, owner, name string) (*model.Perm, error) {
|
||||
}
|
||||
|
||||
// File fetches the file from the Gogs repository and returns its contents.
|
||||
func (c *client) File(u *model.User, r *model.Repo, b *model.Build, f string) ([]byte, error) {
|
||||
func (c *client) File(ctx context.Context, u *model.User, r *model.Repo, b *model.Build, f string) ([]byte, error) {
|
||||
client := c.newClientToken(u.Token)
|
||||
ref := b.Commit
|
||||
|
||||
@ -202,12 +203,12 @@ func (c *client) File(u *model.User, r *model.Repo, b *model.Build, f string) ([
|
||||
return cfg, err
|
||||
}
|
||||
|
||||
func (c *client) Dir(u *model.User, r *model.Repo, b *model.Build, f string) ([]*remote.FileMeta, error) {
|
||||
func (c *client) Dir(ctx context.Context, u *model.User, r *model.Repo, b *model.Build, f string) ([]*remote.FileMeta, error) {
|
||||
return nil, fmt.Errorf("Not implemented")
|
||||
}
|
||||
|
||||
// Status is not supported by the Gogs driver.
|
||||
func (c *client) Status(u *model.User, r *model.Repo, b *model.Build, link string, proc *model.Proc) error {
|
||||
func (c *client) Status(ctx context.Context, u *model.User, r *model.Repo, b *model.Build, link string, proc *model.Proc) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
@ -231,7 +232,7 @@ func (c *client) Netrc(u *model.User, r *model.Repo) (*model.Netrc, error) {
|
||||
|
||||
// Activate activates the repository by registering post-commit hooks with
|
||||
// the Gogs repository.
|
||||
func (c *client) Activate(u *model.User, r *model.Repo, link string) error {
|
||||
func (c *client) Activate(ctx context.Context, u *model.User, r *model.Repo, link string) error {
|
||||
config := map[string]string{
|
||||
"url": link,
|
||||
"secret": r.Hash,
|
||||
@ -250,7 +251,7 @@ func (c *client) Activate(u *model.User, r *model.Repo, link string) error {
|
||||
}
|
||||
|
||||
// Deactivate is not supported by the Gogs driver.
|
||||
func (c *client) Deactivate(u *model.User, r *model.Repo, link string) error {
|
||||
func (c *client) Deactivate(ctx context.Context, u *model.User, r *model.Repo, link string) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
|
@ -15,6 +15,7 @@
|
||||
package gogs
|
||||
|
||||
import (
|
||||
"context"
|
||||
"net/http/httptest"
|
||||
"testing"
|
||||
|
||||
@ -34,6 +35,7 @@ func Test_gogs(t *testing.T) {
|
||||
SkipVerify: true,
|
||||
})
|
||||
|
||||
ctx := context.Background()
|
||||
g := goblin.Goblin(t)
|
||||
g.Describe("Gogs", func() {
|
||||
|
||||
@ -88,7 +90,7 @@ func Test_gogs(t *testing.T) {
|
||||
|
||||
g.Describe("Requesting a repository", func() {
|
||||
g.It("Should return the repository details", func() {
|
||||
repo, err := c.Repo(fakeUser, fakeRepo.Owner, fakeRepo.Name)
|
||||
repo, err := c.Repo(ctx, fakeUser, fakeRepo.Owner, fakeRepo.Name)
|
||||
g.Assert(err == nil).IsTrue()
|
||||
g.Assert(repo.Owner).Equal(fakeRepo.Owner)
|
||||
g.Assert(repo.Name).Equal(fakeRepo.Name)
|
||||
@ -98,52 +100,52 @@ func Test_gogs(t *testing.T) {
|
||||
g.Assert(repo.Link).Equal("http://localhost/test_name/repo_name")
|
||||
})
|
||||
g.It("Should handle a not found error", func() {
|
||||
_, err := c.Repo(fakeUser, fakeRepoNotFound.Owner, fakeRepoNotFound.Name)
|
||||
_, err := c.Repo(ctx, fakeUser, fakeRepoNotFound.Owner, fakeRepoNotFound.Name)
|
||||
g.Assert(err != nil).IsTrue()
|
||||
})
|
||||
})
|
||||
|
||||
g.Describe("Requesting repository permissions", func() {
|
||||
g.It("Should return the permission details", func() {
|
||||
perm, err := c.Perm(fakeUser, fakeRepo.Owner, fakeRepo.Name)
|
||||
perm, err := c.Perm(ctx, fakeUser, fakeRepo.Owner, fakeRepo.Name)
|
||||
g.Assert(err == nil).IsTrue()
|
||||
g.Assert(perm.Admin).IsTrue()
|
||||
g.Assert(perm.Push).IsTrue()
|
||||
g.Assert(perm.Pull).IsTrue()
|
||||
})
|
||||
g.It("Should handle a not found error", func() {
|
||||
_, err := c.Perm(fakeUser, fakeRepoNotFound.Owner, fakeRepoNotFound.Name)
|
||||
_, err := c.Perm(ctx, fakeUser, fakeRepoNotFound.Owner, fakeRepoNotFound.Name)
|
||||
g.Assert(err != nil).IsTrue()
|
||||
})
|
||||
})
|
||||
|
||||
g.Describe("Requesting a repository list", func() {
|
||||
g.It("Should return the repository list", func() {
|
||||
repos, err := c.Repos(fakeUser)
|
||||
repos, err := c.Repos(ctx, fakeUser)
|
||||
g.Assert(err == nil).IsTrue()
|
||||
g.Assert(repos[0].Owner).Equal(fakeRepo.Owner)
|
||||
g.Assert(repos[0].Name).Equal(fakeRepo.Name)
|
||||
g.Assert(repos[0].FullName).Equal(fakeRepo.Owner + "/" + fakeRepo.Name)
|
||||
})
|
||||
g.It("Should handle a not found error", func() {
|
||||
_, err := c.Repos(fakeUserNoRepos)
|
||||
_, err := c.Repos(ctx, fakeUserNoRepos)
|
||||
g.Assert(err != nil).IsTrue()
|
||||
})
|
||||
})
|
||||
|
||||
g.It("Should register repositroy hooks", func() {
|
||||
err := c.Activate(fakeUser, fakeRepo, "http://localhost")
|
||||
err := c.Activate(ctx, fakeUser, fakeRepo, "http://localhost")
|
||||
g.Assert(err == nil).IsTrue()
|
||||
})
|
||||
|
||||
g.It("Should return a repository file", func() {
|
||||
raw, err := c.File(fakeUser, fakeRepo, fakeBuild, ".drone.yml")
|
||||
raw, err := c.File(ctx, fakeUser, fakeRepo, fakeBuild, ".drone.yml")
|
||||
g.Assert(err == nil).IsTrue()
|
||||
g.Assert(string(raw)).Equal("{ platform: linux/amd64 }")
|
||||
})
|
||||
|
||||
g.It("Should return a repository file from a ref", func() {
|
||||
raw, err := c.File(fakeUser, fakeRepo, fakeBuildWithRef, ".drone.yml")
|
||||
raw, err := c.File(ctx, fakeUser, fakeRepo, fakeBuildWithRef, ".drone.yml")
|
||||
g.Assert(err == nil).IsTrue()
|
||||
g.Assert(string(raw)).Equal("{ platform: linux/amd64 }")
|
||||
})
|
||||
@ -162,9 +164,9 @@ func Test_gogs(t *testing.T) {
|
||||
})
|
||||
|
||||
g.It("Should return no-op for usupporeted features", func() {
|
||||
_, err1 := c.Auth("octocat", "4vyW6b49Z")
|
||||
err2 := c.Status(nil, nil, nil, "", nil)
|
||||
err3 := c.Deactivate(nil, nil, "")
|
||||
_, err1 := c.Auth(ctx, "octocat", "4vyW6b49Z")
|
||||
err2 := c.Status(ctx, nil, nil, nil, "", nil)
|
||||
err3 := c.Deactivate(ctx, nil, nil, "")
|
||||
g.Assert(err1 != nil).IsTrue()
|
||||
g.Assert(err2 == nil).IsTrue()
|
||||
g.Assert(err3 == nil).IsTrue()
|
||||
|
@ -1,296 +0,0 @@
|
||||
// Code generated by mockery v0.0.0-dev. DO NOT EDIT.
|
||||
|
||||
package mocks
|
||||
|
||||
import (
|
||||
http "net/http"
|
||||
|
||||
mock "github.com/stretchr/testify/mock"
|
||||
model "github.com/woodpecker-ci/woodpecker/server/model"
|
||||
|
||||
remote "github.com/woodpecker-ci/woodpecker/server/remote"
|
||||
)
|
||||
|
||||
// Remote is an autogenerated mock type for the Remote type
|
||||
type Remote struct {
|
||||
mock.Mock
|
||||
}
|
||||
|
||||
// Activate provides a mock function with given fields: u, r, link
|
||||
func (_m *Remote) Activate(u *model.User, r *model.Repo, link string) error {
|
||||
ret := _m.Called(u, r, link)
|
||||
|
||||
var r0 error
|
||||
if rf, ok := ret.Get(0).(func(*model.User, *model.Repo, string) error); ok {
|
||||
r0 = rf(u, r, link)
|
||||
} else {
|
||||
r0 = ret.Error(0)
|
||||
}
|
||||
|
||||
return r0
|
||||
}
|
||||
|
||||
// Auth provides a mock function with given fields: token, secret
|
||||
func (_m *Remote) Auth(token string, secret string) (string, error) {
|
||||
ret := _m.Called(token, secret)
|
||||
|
||||
var r0 string
|
||||
if rf, ok := ret.Get(0).(func(string, string) string); ok {
|
||||
r0 = rf(token, secret)
|
||||
} else {
|
||||
r0 = ret.Get(0).(string)
|
||||
}
|
||||
|
||||
var r1 error
|
||||
if rf, ok := ret.Get(1).(func(string, string) error); ok {
|
||||
r1 = rf(token, secret)
|
||||
} else {
|
||||
r1 = ret.Error(1)
|
||||
}
|
||||
|
||||
return r0, r1
|
||||
}
|
||||
|
||||
// Deactivate provides a mock function with given fields: u, r, link
|
||||
func (_m *Remote) Deactivate(u *model.User, r *model.Repo, link string) error {
|
||||
ret := _m.Called(u, r, link)
|
||||
|
||||
var r0 error
|
||||
if rf, ok := ret.Get(0).(func(*model.User, *model.Repo, string) error); ok {
|
||||
r0 = rf(u, r, link)
|
||||
} else {
|
||||
r0 = ret.Error(0)
|
||||
}
|
||||
|
||||
return r0
|
||||
}
|
||||
|
||||
// Dir provides a mock function with given fields: u, r, b, f
|
||||
func (_m *Remote) Dir(u *model.User, r *model.Repo, b *model.Build, f string) ([]*remote.FileMeta, error) {
|
||||
ret := _m.Called(u, r, b, f)
|
||||
|
||||
var r0 []*remote.FileMeta
|
||||
if rf, ok := ret.Get(0).(func(*model.User, *model.Repo, *model.Build, string) []*remote.FileMeta); ok {
|
||||
r0 = rf(u, r, b, f)
|
||||
} else {
|
||||
if ret.Get(0) != nil {
|
||||
r0 = ret.Get(0).([]*remote.FileMeta)
|
||||
}
|
||||
}
|
||||
|
||||
var r1 error
|
||||
if rf, ok := ret.Get(1).(func(*model.User, *model.Repo, *model.Build, string) error); ok {
|
||||
r1 = rf(u, r, b, f)
|
||||
} else {
|
||||
r1 = ret.Error(1)
|
||||
}
|
||||
|
||||
return r0, r1
|
||||
}
|
||||
|
||||
// File provides a mock function with given fields: u, r, b, f
|
||||
func (_m *Remote) File(u *model.User, r *model.Repo, b *model.Build, f string) ([]byte, error) {
|
||||
ret := _m.Called(u, r, b, f)
|
||||
|
||||
var r0 []byte
|
||||
if rf, ok := ret.Get(0).(func(*model.User, *model.Repo, *model.Build, string) []byte); ok {
|
||||
r0 = rf(u, r, b, f)
|
||||
} else {
|
||||
if ret.Get(0) != nil {
|
||||
r0 = ret.Get(0).([]byte)
|
||||
}
|
||||
}
|
||||
|
||||
var r1 error
|
||||
if rf, ok := ret.Get(1).(func(*model.User, *model.Repo, *model.Build, string) error); ok {
|
||||
r1 = rf(u, r, b, f)
|
||||
} else {
|
||||
r1 = ret.Error(1)
|
||||
}
|
||||
|
||||
return r0, r1
|
||||
}
|
||||
|
||||
// Hook provides a mock function with given fields: r
|
||||
func (_m *Remote) Hook(r *http.Request) (*model.Repo, *model.Build, error) {
|
||||
ret := _m.Called(r)
|
||||
|
||||
var r0 *model.Repo
|
||||
if rf, ok := ret.Get(0).(func(*http.Request) *model.Repo); ok {
|
||||
r0 = rf(r)
|
||||
} else {
|
||||
if ret.Get(0) != nil {
|
||||
r0 = ret.Get(0).(*model.Repo)
|
||||
}
|
||||
}
|
||||
|
||||
var r1 *model.Build
|
||||
if rf, ok := ret.Get(1).(func(*http.Request) *model.Build); ok {
|
||||
r1 = rf(r)
|
||||
} else {
|
||||
if ret.Get(1) != nil {
|
||||
r1 = ret.Get(1).(*model.Build)
|
||||
}
|
||||
}
|
||||
|
||||
var r2 error
|
||||
if rf, ok := ret.Get(2).(func(*http.Request) error); ok {
|
||||
r2 = rf(r)
|
||||
} else {
|
||||
r2 = ret.Error(2)
|
||||
}
|
||||
|
||||
return r0, r1, r2
|
||||
}
|
||||
|
||||
// Login provides a mock function with given fields: w, r
|
||||
func (_m *Remote) Login(w http.ResponseWriter, r *http.Request) (*model.User, error) {
|
||||
ret := _m.Called(w, r)
|
||||
|
||||
var r0 *model.User
|
||||
if rf, ok := ret.Get(0).(func(http.ResponseWriter, *http.Request) *model.User); ok {
|
||||
r0 = rf(w, r)
|
||||
} else {
|
||||
if ret.Get(0) != nil {
|
||||
r0 = ret.Get(0).(*model.User)
|
||||
}
|
||||
}
|
||||
|
||||
var r1 error
|
||||
if rf, ok := ret.Get(1).(func(http.ResponseWriter, *http.Request) error); ok {
|
||||
r1 = rf(w, r)
|
||||
} else {
|
||||
r1 = ret.Error(1)
|
||||
}
|
||||
|
||||
return r0, r1
|
||||
}
|
||||
|
||||
// Netrc provides a mock function with given fields: u, r
|
||||
func (_m *Remote) Netrc(u *model.User, r *model.Repo) (*model.Netrc, error) {
|
||||
ret := _m.Called(u, r)
|
||||
|
||||
var r0 *model.Netrc
|
||||
if rf, ok := ret.Get(0).(func(*model.User, *model.Repo) *model.Netrc); ok {
|
||||
r0 = rf(u, r)
|
||||
} else {
|
||||
if ret.Get(0) != nil {
|
||||
r0 = ret.Get(0).(*model.Netrc)
|
||||
}
|
||||
}
|
||||
|
||||
var r1 error
|
||||
if rf, ok := ret.Get(1).(func(*model.User, *model.Repo) error); ok {
|
||||
r1 = rf(u, r)
|
||||
} else {
|
||||
r1 = ret.Error(1)
|
||||
}
|
||||
|
||||
return r0, r1
|
||||
}
|
||||
|
||||
// Perm provides a mock function with given fields: u, owner, repo
|
||||
func (_m *Remote) Perm(u *model.User, owner string, repo string) (*model.Perm, error) {
|
||||
ret := _m.Called(u, owner, repo)
|
||||
|
||||
var r0 *model.Perm
|
||||
if rf, ok := ret.Get(0).(func(*model.User, string, string) *model.Perm); ok {
|
||||
r0 = rf(u, owner, repo)
|
||||
} else {
|
||||
if ret.Get(0) != nil {
|
||||
r0 = ret.Get(0).(*model.Perm)
|
||||
}
|
||||
}
|
||||
|
||||
var r1 error
|
||||
if rf, ok := ret.Get(1).(func(*model.User, string, string) error); ok {
|
||||
r1 = rf(u, owner, repo)
|
||||
} else {
|
||||
r1 = ret.Error(1)
|
||||
}
|
||||
|
||||
return r0, r1
|
||||
}
|
||||
|
||||
// Repo provides a mock function with given fields: u, owner, repo
|
||||
func (_m *Remote) Repo(u *model.User, owner string, repo string) (*model.Repo, error) {
|
||||
ret := _m.Called(u, owner, repo)
|
||||
|
||||
var r0 *model.Repo
|
||||
if rf, ok := ret.Get(0).(func(*model.User, string, string) *model.Repo); ok {
|
||||
r0 = rf(u, owner, repo)
|
||||
} else {
|
||||
if ret.Get(0) != nil {
|
||||
r0 = ret.Get(0).(*model.Repo)
|
||||
}
|
||||
}
|
||||
|
||||
var r1 error
|
||||
if rf, ok := ret.Get(1).(func(*model.User, string, string) error); ok {
|
||||
r1 = rf(u, owner, repo)
|
||||
} else {
|
||||
r1 = ret.Error(1)
|
||||
}
|
||||
|
||||
return r0, r1
|
||||
}
|
||||
|
||||
// Repos provides a mock function with given fields: u
|
||||
func (_m *Remote) Repos(u *model.User) ([]*model.Repo, error) {
|
||||
ret := _m.Called(u)
|
||||
|
||||
var r0 []*model.Repo
|
||||
if rf, ok := ret.Get(0).(func(*model.User) []*model.Repo); ok {
|
||||
r0 = rf(u)
|
||||
} else {
|
||||
if ret.Get(0) != nil {
|
||||
r0 = ret.Get(0).([]*model.Repo)
|
||||
}
|
||||
}
|
||||
|
||||
var r1 error
|
||||
if rf, ok := ret.Get(1).(func(*model.User) error); ok {
|
||||
r1 = rf(u)
|
||||
} else {
|
||||
r1 = ret.Error(1)
|
||||
}
|
||||
|
||||
return r0, r1
|
||||
}
|
||||
|
||||
// Status provides a mock function with given fields: u, r, b, link, proc
|
||||
func (_m *Remote) Status(u *model.User, r *model.Repo, b *model.Build, link string, proc *model.Proc) error {
|
||||
ret := _m.Called(u, r, b, link, proc)
|
||||
|
||||
var r0 error
|
||||
if rf, ok := ret.Get(0).(func(*model.User, *model.Repo, *model.Build, string, *model.Proc) error); ok {
|
||||
r0 = rf(u, r, b, link, proc)
|
||||
} else {
|
||||
r0 = ret.Error(0)
|
||||
}
|
||||
|
||||
return r0
|
||||
}
|
||||
|
||||
// Teams provides a mock function with given fields: u
|
||||
func (_m *Remote) Teams(u *model.User) ([]*model.Team, error) {
|
||||
ret := _m.Called(u)
|
||||
|
||||
var r0 []*model.Team
|
||||
if rf, ok := ret.Get(0).(func(*model.User) []*model.Team); ok {
|
||||
r0 = rf(u)
|
||||
} else {
|
||||
if ret.Get(0) != nil {
|
||||
r0 = ret.Get(0).([]*model.Team)
|
||||
}
|
||||
}
|
||||
|
||||
var r1 error
|
||||
if rf, ok := ret.Get(1).(func(*model.User) error); ok {
|
||||
r1 = rf(u)
|
||||
} else {
|
||||
r1 = ret.Error(1)
|
||||
}
|
||||
|
||||
return r0, r1
|
||||
}
|
298
server/remote/mocks/remote.go
Normal file
298
server/remote/mocks/remote.go
Normal file
@ -0,0 +1,298 @@
|
||||
// Code generated by mockery v1.0.0. DO NOT EDIT.
|
||||
|
||||
package mocks
|
||||
|
||||
import (
|
||||
context "context"
|
||||
http "net/http"
|
||||
|
||||
mock "github.com/stretchr/testify/mock"
|
||||
|
||||
model "github.com/woodpecker-ci/woodpecker/server/model"
|
||||
|
||||
remote "github.com/woodpecker-ci/woodpecker/server/remote"
|
||||
)
|
||||
|
||||
// Remote is an autogenerated mock type for the Remote type
|
||||
type Remote struct {
|
||||
mock.Mock
|
||||
}
|
||||
|
||||
// Activate provides a mock function with given fields: ctx, u, r, link
|
||||
func (_m *Remote) Activate(ctx context.Context, u *model.User, r *model.Repo, link string) error {
|
||||
ret := _m.Called(ctx, u, r, link)
|
||||
|
||||
var r0 error
|
||||
if rf, ok := ret.Get(0).(func(context.Context, *model.User, *model.Repo, string) error); ok {
|
||||
r0 = rf(ctx, u, r, link)
|
||||
} else {
|
||||
r0 = ret.Error(0)
|
||||
}
|
||||
|
||||
return r0
|
||||
}
|
||||
|
||||
// Auth provides a mock function with given fields: ctx, token, secret
|
||||
func (_m *Remote) Auth(ctx context.Context, token string, secret string) (string, error) {
|
||||
ret := _m.Called(ctx, token, secret)
|
||||
|
||||
var r0 string
|
||||
if rf, ok := ret.Get(0).(func(context.Context, string, string) string); ok {
|
||||
r0 = rf(ctx, token, secret)
|
||||
} else {
|
||||
r0 = ret.Get(0).(string)
|
||||
}
|
||||
|
||||
var r1 error
|
||||
if rf, ok := ret.Get(1).(func(context.Context, string, string) error); ok {
|
||||
r1 = rf(ctx, token, secret)
|
||||
} else {
|
||||
r1 = ret.Error(1)
|
||||
}
|
||||
|
||||
return r0, r1
|
||||
}
|
||||
|
||||
// Deactivate provides a mock function with given fields: ctx, u, r, link
|
||||
func (_m *Remote) Deactivate(ctx context.Context, u *model.User, r *model.Repo, link string) error {
|
||||
ret := _m.Called(ctx, u, r, link)
|
||||
|
||||
var r0 error
|
||||
if rf, ok := ret.Get(0).(func(context.Context, *model.User, *model.Repo, string) error); ok {
|
||||
r0 = rf(ctx, u, r, link)
|
||||
} else {
|
||||
r0 = ret.Error(0)
|
||||
}
|
||||
|
||||
return r0
|
||||
}
|
||||
|
||||
// Dir provides a mock function with given fields: ctx, u, r, b, f
|
||||
func (_m *Remote) Dir(ctx context.Context, u *model.User, r *model.Repo, b *model.Build, f string) ([]*remote.FileMeta, error) {
|
||||
ret := _m.Called(ctx, u, r, b, f)
|
||||
|
||||
var r0 []*remote.FileMeta
|
||||
if rf, ok := ret.Get(0).(func(context.Context, *model.User, *model.Repo, *model.Build, string) []*remote.FileMeta); ok {
|
||||
r0 = rf(ctx, u, r, b, f)
|
||||
} else {
|
||||
if ret.Get(0) != nil {
|
||||
r0 = ret.Get(0).([]*remote.FileMeta)
|
||||
}
|
||||
}
|
||||
|
||||
var r1 error
|
||||
if rf, ok := ret.Get(1).(func(context.Context, *model.User, *model.Repo, *model.Build, string) error); ok {
|
||||
r1 = rf(ctx, u, r, b, f)
|
||||
} else {
|
||||
r1 = ret.Error(1)
|
||||
}
|
||||
|
||||
return r0, r1
|
||||
}
|
||||
|
||||
// File provides a mock function with given fields: ctx, u, r, b, f
|
||||
func (_m *Remote) File(ctx context.Context, u *model.User, r *model.Repo, b *model.Build, f string) ([]byte, error) {
|
||||
ret := _m.Called(ctx, u, r, b, f)
|
||||
|
||||
var r0 []byte
|
||||
if rf, ok := ret.Get(0).(func(context.Context, *model.User, *model.Repo, *model.Build, string) []byte); ok {
|
||||
r0 = rf(ctx, u, r, b, f)
|
||||
} else {
|
||||
if ret.Get(0) != nil {
|
||||
r0 = ret.Get(0).([]byte)
|
||||
}
|
||||
}
|
||||
|
||||
var r1 error
|
||||
if rf, ok := ret.Get(1).(func(context.Context, *model.User, *model.Repo, *model.Build, string) error); ok {
|
||||
r1 = rf(ctx, u, r, b, f)
|
||||
} else {
|
||||
r1 = ret.Error(1)
|
||||
}
|
||||
|
||||
return r0, r1
|
||||
}
|
||||
|
||||
// Hook provides a mock function with given fields: r
|
||||
func (_m *Remote) Hook(r *http.Request) (*model.Repo, *model.Build, error) {
|
||||
ret := _m.Called(r)
|
||||
|
||||
var r0 *model.Repo
|
||||
if rf, ok := ret.Get(0).(func(*http.Request) *model.Repo); ok {
|
||||
r0 = rf(r)
|
||||
} else {
|
||||
if ret.Get(0) != nil {
|
||||
r0 = ret.Get(0).(*model.Repo)
|
||||
}
|
||||
}
|
||||
|
||||
var r1 *model.Build
|
||||
if rf, ok := ret.Get(1).(func(*http.Request) *model.Build); ok {
|
||||
r1 = rf(r)
|
||||
} else {
|
||||
if ret.Get(1) != nil {
|
||||
r1 = ret.Get(1).(*model.Build)
|
||||
}
|
||||
}
|
||||
|
||||
var r2 error
|
||||
if rf, ok := ret.Get(2).(func(*http.Request) error); ok {
|
||||
r2 = rf(r)
|
||||
} else {
|
||||
r2 = ret.Error(2)
|
||||
}
|
||||
|
||||
return r0, r1, r2
|
||||
}
|
||||
|
||||
// Login provides a mock function with given fields: ctx, w, r
|
||||
func (_m *Remote) Login(ctx context.Context, w http.ResponseWriter, r *http.Request) (*model.User, error) {
|
||||
ret := _m.Called(ctx, w, r)
|
||||
|
||||
var r0 *model.User
|
||||
if rf, ok := ret.Get(0).(func(context.Context, http.ResponseWriter, *http.Request) *model.User); ok {
|
||||
r0 = rf(ctx, w, r)
|
||||
} else {
|
||||
if ret.Get(0) != nil {
|
||||
r0 = ret.Get(0).(*model.User)
|
||||
}
|
||||
}
|
||||
|
||||
var r1 error
|
||||
if rf, ok := ret.Get(1).(func(context.Context, http.ResponseWriter, *http.Request) error); ok {
|
||||
r1 = rf(ctx, w, r)
|
||||
} else {
|
||||
r1 = ret.Error(1)
|
||||
}
|
||||
|
||||
return r0, r1
|
||||
}
|
||||
|
||||
// Netrc provides a mock function with given fields: u, r
|
||||
func (_m *Remote) Netrc(u *model.User, r *model.Repo) (*model.Netrc, error) {
|
||||
ret := _m.Called(u, r)
|
||||
|
||||
var r0 *model.Netrc
|
||||
if rf, ok := ret.Get(0).(func(*model.User, *model.Repo) *model.Netrc); ok {
|
||||
r0 = rf(u, r)
|
||||
} else {
|
||||
if ret.Get(0) != nil {
|
||||
r0 = ret.Get(0).(*model.Netrc)
|
||||
}
|
||||
}
|
||||
|
||||
var r1 error
|
||||
if rf, ok := ret.Get(1).(func(*model.User, *model.Repo) error); ok {
|
||||
r1 = rf(u, r)
|
||||
} else {
|
||||
r1 = ret.Error(1)
|
||||
}
|
||||
|
||||
return r0, r1
|
||||
}
|
||||
|
||||
// Perm provides a mock function with given fields: ctx, u, owner, repo
|
||||
func (_m *Remote) Perm(ctx context.Context, u *model.User, owner string, repo string) (*model.Perm, error) {
|
||||
ret := _m.Called(ctx, u, owner, repo)
|
||||
|
||||
var r0 *model.Perm
|
||||
if rf, ok := ret.Get(0).(func(context.Context, *model.User, string, string) *model.Perm); ok {
|
||||
r0 = rf(ctx, u, owner, repo)
|
||||
} else {
|
||||
if ret.Get(0) != nil {
|
||||
r0 = ret.Get(0).(*model.Perm)
|
||||
}
|
||||
}
|
||||
|
||||
var r1 error
|
||||
if rf, ok := ret.Get(1).(func(context.Context, *model.User, string, string) error); ok {
|
||||
r1 = rf(ctx, u, owner, repo)
|
||||
} else {
|
||||
r1 = ret.Error(1)
|
||||
}
|
||||
|
||||
return r0, r1
|
||||
}
|
||||
|
||||
// Repo provides a mock function with given fields: ctx, u, owner, name
|
||||
func (_m *Remote) Repo(ctx context.Context, u *model.User, owner string, name string) (*model.Repo, error) {
|
||||
ret := _m.Called(ctx, u, owner, name)
|
||||
|
||||
var r0 *model.Repo
|
||||
if rf, ok := ret.Get(0).(func(context.Context, *model.User, string, string) *model.Repo); ok {
|
||||
r0 = rf(ctx, u, owner, name)
|
||||
} else {
|
||||
if ret.Get(0) != nil {
|
||||
r0 = ret.Get(0).(*model.Repo)
|
||||
}
|
||||
}
|
||||
|
||||
var r1 error
|
||||
if rf, ok := ret.Get(1).(func(context.Context, *model.User, string, string) error); ok {
|
||||
r1 = rf(ctx, u, owner, name)
|
||||
} else {
|
||||
r1 = ret.Error(1)
|
||||
}
|
||||
|
||||
return r0, r1
|
||||
}
|
||||
|
||||
// Repos provides a mock function with given fields: ctx, u
|
||||
func (_m *Remote) Repos(ctx context.Context, u *model.User) ([]*model.Repo, error) {
|
||||
ret := _m.Called(ctx, u)
|
||||
|
||||
var r0 []*model.Repo
|
||||
if rf, ok := ret.Get(0).(func(context.Context, *model.User) []*model.Repo); ok {
|
||||
r0 = rf(ctx, u)
|
||||
} else {
|
||||
if ret.Get(0) != nil {
|
||||
r0 = ret.Get(0).([]*model.Repo)
|
||||
}
|
||||
}
|
||||
|
||||
var r1 error
|
||||
if rf, ok := ret.Get(1).(func(context.Context, *model.User) error); ok {
|
||||
r1 = rf(ctx, u)
|
||||
} else {
|
||||
r1 = ret.Error(1)
|
||||
}
|
||||
|
||||
return r0, r1
|
||||
}
|
||||
|
||||
// Status provides a mock function with given fields: ctx, u, r, b, link, proc
|
||||
func (_m *Remote) Status(ctx context.Context, u *model.User, r *model.Repo, b *model.Build, link string, proc *model.Proc) error {
|
||||
ret := _m.Called(ctx, u, r, b, link, proc)
|
||||
|
||||
var r0 error
|
||||
if rf, ok := ret.Get(0).(func(context.Context, *model.User, *model.Repo, *model.Build, string, *model.Proc) error); ok {
|
||||
r0 = rf(ctx, u, r, b, link, proc)
|
||||
} else {
|
||||
r0 = ret.Error(0)
|
||||
}
|
||||
|
||||
return r0
|
||||
}
|
||||
|
||||
// Teams provides a mock function with given fields: ctx, u
|
||||
func (_m *Remote) Teams(ctx context.Context, u *model.User) ([]*model.Team, error) {
|
||||
ret := _m.Called(ctx, u)
|
||||
|
||||
var r0 []*model.Team
|
||||
if rf, ok := ret.Get(0).(func(context.Context, *model.User) []*model.Team); ok {
|
||||
r0 = rf(ctx, u)
|
||||
} else {
|
||||
if ret.Get(0) != nil {
|
||||
r0 = ret.Get(0).([]*model.Team)
|
||||
}
|
||||
}
|
||||
|
||||
var r1 error
|
||||
if rf, ok := ret.Get(1).(func(context.Context, *model.User) error); ok {
|
||||
r1 = rf(ctx, u)
|
||||
} else {
|
||||
r1 = ret.Error(1)
|
||||
}
|
||||
|
||||
return r0, r1
|
||||
}
|
@ -14,63 +14,61 @@
|
||||
|
||||
package remote
|
||||
|
||||
//go:generate mockery -name Remote -output mock -case=underscore
|
||||
//go:generate mockery -name Remote -output mocks -case=underscore
|
||||
|
||||
import (
|
||||
"context"
|
||||
"net/http"
|
||||
|
||||
"github.com/woodpecker-ci/woodpecker/server/model"
|
||||
|
||||
"golang.org/x/net/context"
|
||||
)
|
||||
|
||||
// TODO: use pagination
|
||||
// TODO: use context
|
||||
// TODO: add Driver() who return source forge back
|
||||
|
||||
type Remote interface {
|
||||
// Login authenticates the session and returns the
|
||||
// remote user details.
|
||||
Login(w http.ResponseWriter, r *http.Request) (*model.User, error)
|
||||
Login(ctx context.Context, w http.ResponseWriter, r *http.Request) (*model.User, error)
|
||||
|
||||
// Auth authenticates the session and returns the remote user
|
||||
// login for the given token and secret
|
||||
Auth(token, secret string) (string, error)
|
||||
Auth(ctx context.Context, token, secret string) (string, error)
|
||||
|
||||
// Teams fetches a list of team memberships from the remote system.
|
||||
Teams(u *model.User) ([]*model.Team, error)
|
||||
Teams(ctx context.Context, u *model.User) ([]*model.Team, error)
|
||||
|
||||
// Repo fetches the named repository from the remote system.
|
||||
Repo(u *model.User, owner, repo string) (*model.Repo, error)
|
||||
Repo(ctx context.Context, u *model.User, owner, name string) (*model.Repo, error)
|
||||
|
||||
// Repos fetches a list of repos from the remote system.
|
||||
Repos(u *model.User) ([]*model.Repo, error)
|
||||
Repos(ctx context.Context, u *model.User) ([]*model.Repo, error)
|
||||
|
||||
// Perm fetches the named repository permissions from
|
||||
// the remote system for the specified user.
|
||||
Perm(u *model.User, owner, repo string) (*model.Perm, error)
|
||||
Perm(ctx context.Context, u *model.User, owner, repo string) (*model.Perm, error)
|
||||
|
||||
// File fetches a file from the remote repository and returns in string
|
||||
// format.
|
||||
File(u *model.User, r *model.Repo, b *model.Build, f string) ([]byte, error)
|
||||
File(ctx context.Context, u *model.User, r *model.Repo, b *model.Build, f string) ([]byte, error)
|
||||
|
||||
// Dir fetches a folder from the remote repository
|
||||
Dir(u *model.User, r *model.Repo, b *model.Build, f string) ([]*FileMeta, error)
|
||||
Dir(ctx context.Context, u *model.User, r *model.Repo, b *model.Build, f string) ([]*FileMeta, error)
|
||||
|
||||
// Status sends the commit status to the remote system.
|
||||
// An example would be the GitHub pull request status.
|
||||
Status(u *model.User, r *model.Repo, b *model.Build, link string, proc *model.Proc) error
|
||||
Status(ctx context.Context, u *model.User, r *model.Repo, b *model.Build, link string, proc *model.Proc) error
|
||||
|
||||
// Netrc returns a .netrc file that can be used to clone
|
||||
// private repositories from a remote system.
|
||||
Netrc(u *model.User, r *model.Repo) (*model.Netrc, error)
|
||||
|
||||
// Activate activates a repository by creating the post-commit hook.
|
||||
Activate(u *model.User, r *model.Repo, link string) error
|
||||
Activate(ctx context.Context, u *model.User, r *model.Repo, link string) error
|
||||
|
||||
// Deactivate deactivates a repository by removing all previously created
|
||||
// post-commit hooks matching the given link.
|
||||
Deactivate(u *model.User, r *model.Repo, link string) error
|
||||
Deactivate(ctx context.Context, u *model.User, r *model.Repo, link string) error
|
||||
|
||||
// Hook parses the post-commit hook from the Request body and returns the
|
||||
// required data in a standard format.
|
||||
@ -93,46 +91,46 @@ func (a ByName) Swap(i, j int) { a[i], a[j] = a[j], a[i] }
|
||||
// returns true if the token was refreshed, false if the token was not refreshed,
|
||||
// and error if it failed to refersh.
|
||||
type Refresher interface {
|
||||
Refresh(*model.User) (bool, error)
|
||||
Refresh(context.Context, *model.User) (bool, error)
|
||||
}
|
||||
|
||||
// Login authenticates the session and returns the
|
||||
// remote user details.
|
||||
func Login(c context.Context, w http.ResponseWriter, r *http.Request) (*model.User, error) {
|
||||
return FromContext(c).Login(w, r)
|
||||
return FromContext(c).Login(c, w, r)
|
||||
}
|
||||
|
||||
// Auth authenticates the session and returns the remote user
|
||||
// login for the given token and secret
|
||||
func Auth(c context.Context, token, secret string) (string, error) {
|
||||
return FromContext(c).Auth(token, secret)
|
||||
return FromContext(c).Auth(c, token, secret)
|
||||
}
|
||||
|
||||
// Teams fetches a list of team memberships from the remote system.
|
||||
func Teams(c context.Context, u *model.User) ([]*model.Team, error) {
|
||||
return FromContext(c).Teams(u)
|
||||
return FromContext(c).Teams(c, u)
|
||||
}
|
||||
|
||||
// Repo fetches the named repository from the remote system.
|
||||
func Repo(c context.Context, u *model.User, owner, repo string) (*model.Repo, error) {
|
||||
return FromContext(c).Repo(u, owner, repo)
|
||||
return FromContext(c).Repo(c, u, owner, repo)
|
||||
}
|
||||
|
||||
// Repos fetches a list of repos from the remote system.
|
||||
func Repos(c context.Context, u *model.User) ([]*model.Repo, error) {
|
||||
return FromContext(c).Repos(u)
|
||||
return FromContext(c).Repos(c, u)
|
||||
}
|
||||
|
||||
// Perm fetches the named repository permissions from
|
||||
// the remote system for the specified user.
|
||||
func Perm(c context.Context, u *model.User, owner, repo string) (*model.Perm, error) {
|
||||
return FromContext(c).Perm(u, owner, repo)
|
||||
return FromContext(c).Perm(c, u, owner, repo)
|
||||
}
|
||||
|
||||
// Status sends the commit status to the remote system.
|
||||
// An example would be the GitHub pull request status.
|
||||
func Status(c context.Context, u *model.User, r *model.Repo, b *model.Build, link string, proc *model.Proc) error {
|
||||
return FromContext(c).Status(u, r, b, link, proc)
|
||||
return FromContext(c).Status(c, u, r, b, link, proc)
|
||||
}
|
||||
|
||||
// Netrc returns a .netrc file that can be used to clone
|
||||
@ -144,13 +142,13 @@ func Netrc(c context.Context, u *model.User, r *model.Repo) (*model.Netrc, error
|
||||
// Activate activates a repository by creating the post-commit hook and
|
||||
// adding the SSH deploy key, if applicable.
|
||||
func Activate(c context.Context, u *model.User, r *model.Repo, link string) error {
|
||||
return FromContext(c).Activate(u, r, link)
|
||||
return FromContext(c).Activate(c, u, r, link)
|
||||
}
|
||||
|
||||
// Deactivate removes a repository by removing all the post-commit hooks
|
||||
// which are equal to link and removing the SSH deploy key.
|
||||
func Deactivate(c context.Context, u *model.User, r *model.Repo, link string) error {
|
||||
return FromContext(c).Deactivate(u, r, link)
|
||||
return FromContext(c).Deactivate(c, u, r, link)
|
||||
}
|
||||
|
||||
// Hook parses the post-commit hook from the Request body
|
||||
@ -168,5 +166,5 @@ func Refresh(c context.Context, u *model.User) (bool, error) {
|
||||
if !ok {
|
||||
return false, nil
|
||||
}
|
||||
return refresher.Refresh(u)
|
||||
return refresher.Refresh(c, u)
|
||||
}
|
||||
|
@ -95,7 +95,7 @@ func SetPerm() gin.HandlerFunc {
|
||||
user.Login, repo.FullName, err)
|
||||
}
|
||||
if time.Unix(perm.Synced, 0).Add(time.Hour).Before(time.Now()) {
|
||||
perm, err = remote.FromContext(c).Perm(user, repo.Owner, repo.Name)
|
||||
perm, err = remote.FromContext(c).Perm(c, user, repo.Owner, repo.Name)
|
||||
if err == nil {
|
||||
log.Debugf("Synced user permission for %s %s", user.Login, repo.FullName)
|
||||
perm.Repo = repo.FullName
|
||||
|
@ -52,7 +52,7 @@ func Refresh(c *gin.Context) {
|
||||
// attempts to refresh the access token. If the
|
||||
// token is refreshed, we must also persist to the
|
||||
// database.
|
||||
ok, _ = refresher.Refresh(user)
|
||||
ok, _ = refresher.Refresh(c, user)
|
||||
if ok {
|
||||
err := store.UpdateUser(c, user)
|
||||
if err != nil {
|
||||
|
@ -1,6 +1,8 @@
|
||||
package shared
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
"strings"
|
||||
"time"
|
||||
@ -27,81 +29,90 @@ func NewConfigFetcher(remote remote.Remote, user *model.User, repo *model.Repo,
|
||||
}
|
||||
}
|
||||
|
||||
// Fetch
|
||||
// TODO: dedupe code
|
||||
func (cf *configFetcher) Fetch() (files []*remote.FileMeta, err error) {
|
||||
var file []byte
|
||||
config := strings.TrimSpace(cf.repo.Config)
|
||||
|
||||
// Fetch pipeline config from source forge
|
||||
func (cf *configFetcher) Fetch(ctx context.Context) (files []*remote.FileMeta, err error) {
|
||||
logrus.Tracef("Start Fetching config for '%s'", cf.repo.FullName)
|
||||
|
||||
for i := 0; i < 5; i++ {
|
||||
select {
|
||||
case <-time.After(time.Second * time.Duration(i)):
|
||||
if len(config) > 0 {
|
||||
// either a file
|
||||
if !strings.HasSuffix(config, "/") {
|
||||
file, err = cf.remote_.File(cf.user, cf.repo, cf.build, config)
|
||||
if err == nil && len(file) != 0 {
|
||||
logrus.Tracef("ConfigFetch[%s]: found file '%s'", cf.repo.FullName, config)
|
||||
return []*remote.FileMeta{{
|
||||
Name: config,
|
||||
Data: file,
|
||||
}}, nil
|
||||
}
|
||||
}
|
||||
|
||||
// or a folder
|
||||
files, err = cf.remote_.Dir(cf.user, cf.repo, cf.build, strings.TrimSuffix(config, "/"))
|
||||
if err == nil {
|
||||
logrus.Tracef("ConfigFetch[%s]: found %d files in '%s'", cf.repo.FullName, len(files), config)
|
||||
return filterPipelineFiles(files), nil
|
||||
}
|
||||
} else {
|
||||
logrus.Tracef("ConfigFetch[%s]: user did not defined own config follow default procedure", cf.repo.FullName)
|
||||
// no user defined config so try .woodpecker/*.yml -> .woodpecker.yml -> .drone.yml
|
||||
|
||||
// test .woodpecker/ folder
|
||||
// if folder is not supported we will get a "Not implemented" error and continue
|
||||
config = ".woodpecker"
|
||||
files, err = cf.remote_.Dir(cf.user, cf.repo, cf.build, config)
|
||||
logrus.Tracef("ConfigFetch[%s]: found %d files in '%s'", cf.repo.FullName, len(files), config)
|
||||
files = filterPipelineFiles(files)
|
||||
if err == nil && len(files) != 0 {
|
||||
return files, nil
|
||||
}
|
||||
|
||||
config = ".woodpecker.yml"
|
||||
file, err = cf.remote_.File(cf.user, cf.repo, cf.build, config)
|
||||
if err == nil && len(file) != 0 {
|
||||
logrus.Tracef("ConfigFetch[%s]: found file '%s'", cf.repo.FullName, config)
|
||||
return []*remote.FileMeta{{
|
||||
Name: ".woodpecker.yml",
|
||||
Data: file,
|
||||
}}, nil
|
||||
}
|
||||
|
||||
config = ".drone.yml"
|
||||
file, err = cf.remote_.File(cf.user, cf.repo, cf.build, config)
|
||||
if err == nil && len(file) != 0 {
|
||||
logrus.Tracef("ConfigFetch[%s]: found file '%s'", cf.repo.FullName, config)
|
||||
return []*remote.FileMeta{{
|
||||
Name: ".drone.yml",
|
||||
Data: file,
|
||||
}}, nil
|
||||
}
|
||||
|
||||
if err == nil && len(files) == 0 {
|
||||
return nil, fmt.Errorf("ConfigFetcher: Fallback did not found config")
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: retry loop is inactive and could maybe be fixed/deleted
|
||||
return nil, err
|
||||
// try to fetch 3 times, timeout is one second longer each time
|
||||
for i := 0; i < 3; i++ {
|
||||
files, err = cf.fetch(ctx, time.Second*time.Duration(i), strings.TrimSpace(cf.repo.Config))
|
||||
if errors.Is(err, context.DeadlineExceeded) {
|
||||
continue
|
||||
}
|
||||
return
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// fetch config by timeout
|
||||
// TODO: dedupe code
|
||||
func (cf *configFetcher) fetch(c context.Context, timeout time.Duration, config string) ([]*remote.FileMeta, error) {
|
||||
ctx, cancel := context.WithTimeout(c, timeout)
|
||||
defer cancel()
|
||||
|
||||
if len(config) > 0 {
|
||||
logrus.Tracef("ConfigFetch[%s]: use user config '%s'", cf.repo.FullName, config)
|
||||
// either a file
|
||||
if !strings.HasSuffix(config, "/") {
|
||||
file, err := cf.remote_.File(ctx, cf.user, cf.repo, cf.build, config)
|
||||
if err == nil && len(file) != 0 {
|
||||
logrus.Tracef("ConfigFetch[%s]: found file '%s'", cf.repo.FullName, config)
|
||||
return []*remote.FileMeta{{
|
||||
Name: config,
|
||||
Data: file,
|
||||
}}, nil
|
||||
}
|
||||
}
|
||||
|
||||
// or a folder
|
||||
files, err := cf.remote_.Dir(ctx, cf.user, cf.repo, cf.build, strings.TrimSuffix(config, "/"))
|
||||
if err == nil && len(files) != 0 {
|
||||
logrus.Tracef("ConfigFetch[%s]: found %d files in '%s'", cf.repo.FullName, len(files), config)
|
||||
return filterPipelineFiles(files), nil
|
||||
}
|
||||
|
||||
return nil, fmt.Errorf("config '%s' not found: %s", config, err)
|
||||
}
|
||||
|
||||
return []*remote.FileMeta{}, nil
|
||||
logrus.Tracef("ConfigFetch[%s]: user did not defined own config follow default procedure", cf.repo.FullName)
|
||||
// no user defined config so try .woodpecker/*.yml -> .woodpecker.yml -> .drone.yml
|
||||
|
||||
// test .woodpecker/ folder
|
||||
// if folder is not supported we will get a "Not implemented" error and continue
|
||||
config = ".woodpecker"
|
||||
files, err := cf.remote_.Dir(ctx, cf.user, cf.repo, cf.build, config)
|
||||
files = filterPipelineFiles(files)
|
||||
if err == nil && len(files) != 0 {
|
||||
logrus.Tracef("ConfigFetch[%s]: found %d files in '%s'", cf.repo.FullName, len(files), config)
|
||||
return files, nil
|
||||
}
|
||||
|
||||
config = ".woodpecker.yml"
|
||||
file, err := cf.remote_.File(ctx, cf.user, cf.repo, cf.build, config)
|
||||
if err == nil && len(file) != 0 {
|
||||
logrus.Tracef("ConfigFetch[%s]: found file '%s'", cf.repo.FullName, config)
|
||||
return []*remote.FileMeta{{
|
||||
Name: config,
|
||||
Data: file,
|
||||
}}, nil
|
||||
}
|
||||
|
||||
config = ".drone.yml"
|
||||
file, err = cf.remote_.File(ctx, cf.user, cf.repo, cf.build, config)
|
||||
if err == nil && len(file) != 0 {
|
||||
logrus.Tracef("ConfigFetch[%s]: found file '%s'", cf.repo.FullName, config)
|
||||
return []*remote.FileMeta{{
|
||||
Name: config,
|
||||
Data: file,
|
||||
}}, nil
|
||||
}
|
||||
|
||||
select {
|
||||
case <-ctx.Done():
|
||||
return nil, ctx.Err()
|
||||
default:
|
||||
return []*remote.FileMeta{}, fmt.Errorf("ConfigFetcher: Fallback did not found config: %s", err)
|
||||
}
|
||||
}
|
||||
|
||||
func filterPipelineFiles(files []*remote.FileMeta) []*remote.FileMeta {
|
||||
|
@ -1,6 +1,7 @@
|
||||
package shared_test
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"path/filepath"
|
||||
"testing"
|
||||
@ -216,7 +217,7 @@ func TestFetch(t *testing.T) {
|
||||
r := new(mocks.Remote)
|
||||
dirs := map[string][]*remote.FileMeta{}
|
||||
for _, file := range tt.files {
|
||||
r.On("File", mock.Anything, mock.Anything, mock.Anything, file.name).Return(file.data, nil)
|
||||
r.On("File", mock.Anything, mock.Anything, mock.Anything, mock.Anything, file.name).Return(file.data, nil)
|
||||
path := filepath.Dir(file.name)
|
||||
if path != "." {
|
||||
dirs[path] = append(dirs[path], &remote.FileMeta{
|
||||
@ -227,12 +228,12 @@ func TestFetch(t *testing.T) {
|
||||
}
|
||||
|
||||
for path, files := range dirs {
|
||||
r.On("Dir", mock.Anything, mock.Anything, mock.Anything, path).Return(files, nil)
|
||||
r.On("Dir", mock.Anything, mock.Anything, mock.Anything, mock.Anything, path).Return(files, nil)
|
||||
}
|
||||
|
||||
// if the previous mocks do not match return not found errors
|
||||
r.On("File", mock.Anything, mock.Anything, mock.Anything, mock.Anything).Return(nil, fmt.Errorf("File not found"))
|
||||
r.On("Dir", mock.Anything, mock.Anything, mock.Anything, mock.Anything).Return(nil, fmt.Errorf("Directory not found"))
|
||||
r.On("File", mock.Anything, mock.Anything, mock.Anything, mock.Anything, mock.Anything).Return(nil, fmt.Errorf("File not found"))
|
||||
r.On("Dir", mock.Anything, mock.Anything, mock.Anything, mock.Anything, mock.Anything).Return(nil, fmt.Errorf("Directory not found"))
|
||||
|
||||
configFetcher := shared.NewConfigFetcher(
|
||||
r,
|
||||
@ -240,7 +241,7 @@ func TestFetch(t *testing.T) {
|
||||
repo,
|
||||
&model.Build{Commit: "89ab7b2d6bfb347144ac7c557e638ab402848fee"},
|
||||
)
|
||||
files, err := configFetcher.Fetch()
|
||||
files, err := configFetcher.Fetch(context.Background())
|
||||
if tt.expectedError && err == nil {
|
||||
t.Fatal("expected an error")
|
||||
} else if !tt.expectedError && err != nil {
|
||||
|
@ -15,6 +15,7 @@
|
||||
package shared
|
||||
|
||||
import (
|
||||
"context"
|
||||
"time"
|
||||
|
||||
"github.com/woodpecker-ci/woodpecker/server/model"
|
||||
@ -24,7 +25,7 @@ import (
|
||||
|
||||
// UserSyncer syncs the user repository and permissions.
|
||||
type UserSyncer interface {
|
||||
Sync(user *model.User) error
|
||||
Sync(ctx context.Context, user *model.User) error
|
||||
}
|
||||
|
||||
type Syncer struct {
|
||||
@ -62,9 +63,9 @@ func (s *Syncer) SetFilter(fn FilterFunc) {
|
||||
s.Match = fn
|
||||
}
|
||||
|
||||
func (s *Syncer) Sync(user *model.User) error {
|
||||
func (s *Syncer) Sync(ctx context.Context, user *model.User) error {
|
||||
unix := time.Now().Unix() - (3601) // force immediate expiration. note 1 hour expiration is hard coded at the moment
|
||||
repos, err := s.Remote.Repos(user)
|
||||
repos, err := s.Remote.Repos(ctx, user)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user