From 764c36f736ebafd236ece1a423e5b60a3db3cc48 Mon Sep 17 00:00:00 2001 From: folex <0xdxdy@gmail.com> Date: Fri, 27 Apr 2018 18:59:36 +0300 Subject: [PATCH] Use user/permissions bitbucket API instead of hooks --- .gitignore | 1 + remote/bitbucket/bitbucket.go | 14 +++++++---- remote/bitbucket/internal/client.go | 37 ++++++++++++++++++++++------- remote/bitbucket/internal/types.go | 10 ++++++++ 4 files changed, 49 insertions(+), 13 deletions(-) diff --git a/.gitignore b/.gitignore index c07e1ad4..ff661245 100644 --- a/.gitignore +++ b/.gitignore @@ -7,3 +7,4 @@ extras/ release/ server/swagger/files/*.json +.idea/ diff --git a/remote/bitbucket/bitbucket.go b/remote/bitbucket/bitbucket.go index c76d3821..1dcaa068 100644 --- a/remote/bitbucket/bitbucket.go +++ b/remote/bitbucket/bitbucket.go @@ -176,15 +176,21 @@ func (c *config) Perm(u *model.User, owner, name string) (*model.Perm, error) { client := c.newClient(u) perms := new(model.Perm) - _, err := client.FindRepo(owner, name) + repo, err := client.FindRepo(owner, name) if err != nil { return perms, err } - _, err = client.ListHooks(owner, name, &internal.ListOpts{}) + perm, err := client.GetPermission(repo.FullName) + if err == nil { - perms.Push = true - perms.Admin = true + switch perm.Permission { + case "admin": + perms.Push = true + perms.Admin = true + case "write": + perms.Push = true + } } perms.Pull = true return perms, nil diff --git a/remote/bitbucket/internal/client.go b/remote/bitbucket/internal/client.go index 9787255a..1b98dec9 100644 --- a/remote/bitbucket/internal/client.go +++ b/remote/bitbucket/internal/client.go @@ -22,6 +22,7 @@ import ( "net/http" "net/url" + "github.com/pkg/errors" "golang.org/x/oauth2" "golang.org/x/oauth2/bitbucket" ) @@ -34,15 +35,16 @@ const ( ) const ( - pathUser = "%s/2.0/user/" - pathEmails = "%s/2.0/user/emails" - pathTeams = "%s/2.0/teams/?%s" - pathRepo = "%s/2.0/repositories/%s/%s" - pathRepos = "%s/2.0/repositories/%s?%s" - pathHook = "%s/2.0/repositories/%s/%s/hooks/%s" - pathHooks = "%s/2.0/repositories/%s/%s/hooks?%s" - pathSource = "%s/1.0/repositories/%s/%s/src/%s/%s" - pathStatus = "%s/2.0/repositories/%s/%s/commit/%s/statuses/build" + pathUser = "%s/2.0/user/" + pathEmails = "%s/2.0/user/emails" + pathPermissions = "%s/2.0/user/permissions/repositories?q=repository.full_name=\"%s\"" + pathTeams = "%s/2.0/teams/?%s" + pathRepo = "%s/2.0/repositories/%s/%s" + pathRepos = "%s/2.0/repositories/%s?%s" + pathHook = "%s/2.0/repositories/%s/%s/hooks/%s" + pathHooks = "%s/2.0/repositories/%s/%s/hooks?%s" + pathSource = "%s/1.0/repositories/%s/%s/src/%s/%s" + pathStatus = "%s/2.0/repositories/%s/%s/commit/%s/statuses/build" ) type Client struct { @@ -152,6 +154,23 @@ func (c *Client) CreateStatus(owner, name, revision string, status *BuildStatus) return c.do(uri, post, status, nil) } +func (c *Client) GetPermission(full_name string) (*RepoPerm, error) { + out := new(RepoPermResp) + uri := fmt.Sprintf(pathPermissions, c.base, full_name) + err := c.do(uri, get, nil, out) + + if err != nil { + return nil, err + } + + if len(out.Values) == 0 { + err = errors.New(fmt.Sprint("no permissions in repository ", full_name)) + return nil, err + } else { + return out.Values[0], nil + } +} + func (c *Client) do(rawurl, method string, in, out interface{}) error { uri, err := url.Parse(rawurl) diff --git a/remote/bitbucket/internal/types.go b/remote/bitbucket/internal/types.go index 18c5e0ca..652b037c 100644 --- a/remote/bitbucket/internal/types.go +++ b/remote/bitbucket/internal/types.go @@ -224,3 +224,13 @@ type Error struct { func (e Error) Error() string { return e.Body.Message } + +type RepoPermResp struct { + Page int `json:"page"` + Pages int `json:"pagelen"` + Values []*RepoPerm `json:"values"` +} + +type RepoPerm struct { + Permission string `json:"permission"` +}