mirror of
https://github.com/woodpecker-ci/woodpecker.git
synced 2024-11-22 18:01:02 +00:00
Merge pull request #2409 from folex/master
Use proper Bitbucket API for permission detection
This commit is contained in:
commit
c01a05def6
6 changed files with 128 additions and 19 deletions
1
.gitignore
vendored
1
.gitignore
vendored
|
@ -7,3 +7,4 @@ extras/
|
|||
release/
|
||||
|
||||
server/swagger/files/*.json
|
||||
.idea/
|
||||
|
|
|
@ -176,17 +176,27 @@ 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{})
|
||||
if err == nil {
|
||||
perms.Push = true
|
||||
perms.Admin = true
|
||||
perm, err := client.GetPermission(repo.FullName)
|
||||
if err != nil {
|
||||
return perms, err
|
||||
}
|
||||
perms.Pull = true
|
||||
|
||||
switch perm.Permission {
|
||||
case "admin":
|
||||
perms.Admin = true
|
||||
fallthrough
|
||||
case "write":
|
||||
perms.Push = true
|
||||
fallthrough
|
||||
default:
|
||||
perms.Pull = true
|
||||
}
|
||||
|
||||
return perms, nil
|
||||
}
|
||||
|
||||
|
|
|
@ -161,19 +161,30 @@ func Test_bitbucket(t *testing.T) {
|
|||
g.It("Should authorize read access", func() {
|
||||
perm, err := c.Perm(
|
||||
fakeUser,
|
||||
fakeRepoNoHooks.Owner,
|
||||
fakeRepoNoHooks.Name,
|
||||
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,
|
||||
)
|
||||
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,
|
||||
fakeRepo.Owner,
|
||||
fakeRepo.Name,
|
||||
fakeRepoAdmin.Owner,
|
||||
fakeRepoAdmin.Name,
|
||||
)
|
||||
g.Assert(err == nil).IsTrue()
|
||||
g.Assert(perm.Pull).IsTrue()
|
||||
|
@ -350,6 +361,24 @@ var (
|
|||
FullName: "test_name/hook_empty",
|
||||
}
|
||||
|
||||
fakeRepoReadOnly = &model.Repo{
|
||||
Owner: "test_name",
|
||||
Name: "permission_read",
|
||||
FullName: "test_name/permission_read",
|
||||
}
|
||||
|
||||
fakeRepoWriteOnly = &model.Repo{
|
||||
Owner: "test_name",
|
||||
Name: "permission_write",
|
||||
FullName: "test_name/permission_write",
|
||||
}
|
||||
|
||||
fakeRepoAdmin = &model.Repo{
|
||||
Owner: "test_name",
|
||||
Name: "permission_admin",
|
||||
FullName: "test_name/permission_admin",
|
||||
}
|
||||
|
||||
fakeBuild = &model.Build{
|
||||
Commit: "9ecad50",
|
||||
}
|
||||
|
|
|
@ -15,6 +15,7 @@
|
|||
package fixtures
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net/http"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
|
@ -36,6 +37,7 @@ func Handler() http.Handler {
|
|||
e.GET("/2.0/repositories/:owner", getUserRepos)
|
||||
e.GET("/2.0/teams/", getUserTeams)
|
||||
e.GET("/2.0/user/", getUser)
|
||||
e.GET("/2.0/user/permissions/repositories", getPermissions)
|
||||
|
||||
return e
|
||||
}
|
||||
|
@ -70,6 +72,8 @@ func getRepo(c *gin.Context) {
|
|||
switch c.Param("name") {
|
||||
case "not_found", "repo_unknown", "repo_not_found":
|
||||
c.String(404, "")
|
||||
case "permission_read", "permission_write", "permission_admin":
|
||||
c.String(200, fmt.Sprintf(permissionRepoPayload, c.Param("name")))
|
||||
default:
|
||||
c.String(200, repoPayload)
|
||||
}
|
||||
|
@ -144,6 +148,24 @@ func getUserRepos(c *gin.Context) {
|
|||
}
|
||||
}
|
||||
|
||||
func permission(p string) string {
|
||||
return fmt.Sprintf(permissionPayload, p)
|
||||
}
|
||||
|
||||
func getPermissions(c *gin.Context) {
|
||||
query := c.Request.URL.Query()["q"][0]
|
||||
switch query {
|
||||
case `repository.full_name="test_name/permission_read"`:
|
||||
c.String(200, permission("read"))
|
||||
case `repository.full_name="test_name/permission_write"`:
|
||||
c.String(200, permission("write"))
|
||||
case `repository.full_name="test_name/permission_admin"`:
|
||||
c.String(200, permission("admin"))
|
||||
default:
|
||||
c.String(200, permission("read"))
|
||||
}
|
||||
}
|
||||
|
||||
const tokenPayload = `
|
||||
{
|
||||
"access_token":"2YotnFZFEjr1zCsicMWpAA",
|
||||
|
@ -170,6 +192,14 @@ const repoPayload = `
|
|||
}
|
||||
`
|
||||
|
||||
const permissionRepoPayload = `
|
||||
{
|
||||
"full_name": "test_name/%s",
|
||||
"scm": "git",
|
||||
"is_private": true
|
||||
}
|
||||
`
|
||||
|
||||
const repoHookPayload = `
|
||||
{
|
||||
"pagelen": 10,
|
||||
|
@ -238,3 +268,15 @@ const userTeamPayload = `
|
|||
]
|
||||
}
|
||||
`
|
||||
|
||||
const permissionPayload = `
|
||||
{
|
||||
"pagelen": 1,
|
||||
"values": [
|
||||
{
|
||||
"permission": "%s"
|
||||
}
|
||||
],
|
||||
"page": 1
|
||||
}
|
||||
`
|
||||
|
|
|
@ -34,15 +34,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=%q"
|
||||
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 +153,22 @@ func (c *Client) CreateStatus(owner, name, revision string, status *BuildStatus)
|
|||
return c.do(uri, post, status, nil)
|
||||
}
|
||||
|
||||
func (c *Client) GetPermission(fullName string) (*RepoPerm, error) {
|
||||
out := new(RepoPermResp)
|
||||
uri := fmt.Sprintf(pathPermissions, c.base, fullName)
|
||||
err := c.do(uri, get, nil, out)
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if len(out.Values) == 0 {
|
||||
return nil, fmt.Errorf("no permissions in repository %s", fullName)
|
||||
} else {
|
||||
return out.Values[0], nil
|
||||
}
|
||||
}
|
||||
|
||||
func (c *Client) do(rawurl, method string, in, out interface{}) error {
|
||||
|
||||
uri, err := url.Parse(rawurl)
|
||||
|
|
|
@ -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"`
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue