From 9e359b3e9ea6c91e30a6f2f115bcbb2c1a1fefb4 Mon Sep 17 00:00:00 2001 From: qwerty287 <80460567+qwerty287@users.noreply.github.com> Date: Wed, 25 Mar 2026 14:30:29 +0100 Subject: [PATCH] Fix bitbucket api deprecations (#6324) --- server/forge/bitbucket/bitbucket.go | 27 +++++----- server/forge/bitbucket/bitbucket_test.go | 3 +- server/forge/bitbucket/fixtures/handler.go | 57 +++++++++++++++++++--- server/forge/bitbucket/internal/client.go | 14 +++--- server/forge/bitbucket/internal/types.go | 20 -------- 5 files changed, 72 insertions(+), 49 deletions(-) diff --git a/server/forge/bitbucket/bitbucket.go b/server/forge/bitbucket/bitbucket.go index 930bf38fd..8d01df40b 100644 --- a/server/forge/bitbucket/bitbucket.go +++ b/server/forge/bitbucket/bitbucket.go @@ -152,10 +152,9 @@ func (c *config) Refresh(ctx context.Context, user *model.User) (bool, error) { func (c *config) Teams(ctx context.Context, u *model.User, p *model.ListOptions) ([]*model.Team, error) { setListOptions(p) - opts := &internal.ListWorkspacesOpts{ + opts := &internal.ListOpts{ PageLen: p.PerPage, Page: p.Page, - Role: "member", } resp, err := c.newClient(ctx, u).ListWorkspaces(opts) if err != nil { @@ -206,31 +205,31 @@ func (c *config) Repos(ctx context.Context, u *model.User, p *model.ListOptions) client := c.newClient(ctx, u) - resp, err := client.ListWorkspaces(&internal.ListWorkspacesOpts{ + resp, err := client.ListWorkspaces(&internal.ListOpts{ Page: p.Page, PageLen: p.PerPage, - Role: "member", }) if err != nil { return nil, err } - userPermissions, err := client.ListPermissionsAll() - if err != nil { - return nil, err - } - - userPermissionsByRepo := make(map[string]*internal.RepoPerm) - for _, permission := range userPermissions { - userPermissionsByRepo[permission.Repo.FullName] = permission - } - var all []*model.Repo for _, workspace := range resp.Values { repos, err := client.ListReposAll(workspace.Slug) if err != nil { return nil, err } + + userPermissions, err := client.ListPermissionsAll(workspace.Slug) + if err != nil { + return nil, err + } + + userPermissionsByRepo := make(map[string]*internal.RepoPerm) + for _, permission := range userPermissions { + userPermissionsByRepo[permission.Repo.FullName] = permission + } + for _, repo := range repos { if perm, ok := userPermissionsByRepo[repo.FullName]; ok { all = append(all, convertRepo(repo, perm)) diff --git a/server/forge/bitbucket/bitbucket_test.go b/server/forge/bitbucket/bitbucket_test.go index 772d01a6d..1ce01e622 100644 --- a/server/forge/bitbucket/bitbucket_test.go +++ b/server/forge/bitbucket/bitbucket_test.go @@ -111,6 +111,7 @@ func TestBitbucket(t *testing.T) { repos, err := c.Repos(ctx, fakeUser, &model.ListOptions{Page: 1, PerPage: 10}) assert.NoError(t, err) + assert.Len(t, repos, 1) assert.Equal(t, fakeRepo.FullName, repos[0].FullName) _, err = c.Repos(ctx, fakeUserNoTeams, &model.ListOptions{Page: 1, PerPage: 10}) @@ -121,7 +122,7 @@ func TestBitbucket(t *testing.T) { teams, err := c.Teams(ctx, fakeUser, &model.ListOptions{Page: 1, PerPage: 10}) assert.NoError(t, err) - assert.Equal(t, "ueberdev42", teams[0].Login) + assert.Equal(t, "test_name", teams[0].Login) assert.Equal(t, "https://bitbucket.org/workspaces/ueberdev42/avatar/?ts=1658761964", teams[0].Avatar) _, err = c.Teams(ctx, fakeUserNoTeams, &model.ListOptions{Page: 1, PerPage: 10}) diff --git a/server/forge/bitbucket/fixtures/handler.go b/server/forge/bitbucket/fixtures/handler.go index ce95e7409..e8bcfdea4 100644 --- a/server/forge/bitbucket/fixtures/handler.go +++ b/server/forge/bitbucket/fixtures/handler.go @@ -28,7 +28,7 @@ func Handler() http.Handler { e := gin.New() e.POST("/site/oauth2/access_token", getOauth) - e.GET("/2.0/workspaces/", getWorkspaces) + e.GET("/2.0/user/workspaces/", getWorkspaces) e.GET("/2.0/repositories/:owner/:name", getRepo) e.GET("/2.0/repositories/:owner/:name/hooks", getRepoHooks) e.GET("/2.0/repositories/:owner/:name/src/:commit/:file", getRepoFile) @@ -38,7 +38,8 @@ func Handler() http.Handler { e.GET("/2.0/repositories/:owner", getUserRepos) e.GET("/2.0/user/", getUser) e.GET("/2.0/user/emails", getEmails) - e.GET("/2.0/user/permissions/repositories", getPermissions) + e.GET("/2.0/user/permissions/repositories", getPermission) + e.GET("/2.0/user/workspaces/:workspace/permissions/repositories", getPermissions) e.GET("/2.0/repositories/:owner/:name/commits/:commit", getBranchHead) e.GET("/2.0/repositories/:owner/:name/pullrequests", getPullRequests) e.GET("/2.0/repositories/:owner/:name/diffstat/:commit", getCommitDiffstat) @@ -75,9 +76,6 @@ func getOauth(c *gin.Context) { } func getWorkspaces(c *gin.Context) { - // TODO: should the role be used ? - // role, _ := c.Params.Get("role") - switch c.Request.Header.Get("Authorization") { case "Bearer teams_not_found", "Bearer c81e728d": c.String(http.StatusNotFound, "") @@ -202,8 +200,23 @@ func getUserRepos(c *gin.Context) { } } -func getPermissions(c *gin.Context) { +func getPermission(c *gin.Context) { if c.Query("page") == "" || c.Query("page") == "1" { + switch c.Query("q") { + case "repository.full_name=\"test_name/repo_name\"": + c.String(http.StatusOK, permissionPayLoad) + return + case "repository.full_name=\"martinherren1984/publictestrepo\"": + c.String(http.StatusOK, permissionHookPayLoad) + return + } + } + + c.String(http.StatusOK, "{\"values\":[]}") +} + +func getPermissions(c *gin.Context) { + if (c.Query("page") == "" || c.Query("page") == "1") && c.Param("workspace") == "test_name" { c.String(http.StatusOK, permissionsPayLoad) } else { c.String(http.StatusOK, "{\"values\":[]}") @@ -524,7 +537,7 @@ const workspacesPayload = ` "type": "workspace", "uuid": "{c7a04a76-fa20-43e4-dc42-a7506db4c95b}", "name": "Ueber Dev", - "slug": "ueberdev42", + "slug": "test_name", "links": { "avatar": { "href": "https://bitbucket.org/workspaces/ueberdev42/avatar/?ts=1658761964" @@ -573,3 +586,33 @@ const permissionsPayLoad = ` ] } ` + +const permissionPayLoad = ` +{ + "pagelen": 100, + "page": 1, + "values": [ + { + "repository": { + "full_name": "test_name/repo_name" + }, + "permission": "read" + } + ] +} +` + +const permissionHookPayLoad = ` +{ + "pagelen": 100, + "page": 1, + "values": [ + { + "repository": { + "full_name": "martinherren1984/publictestrepo" + }, + "permission": "admin" + } + ] +} +` diff --git a/server/forge/bitbucket/internal/client.go b/server/forge/bitbucket/internal/client.go index 9a9abafca..dd1ffba26 100644 --- a/server/forge/bitbucket/internal/client.go +++ b/server/forge/bitbucket/internal/client.go @@ -33,8 +33,8 @@ const ( pathUser = "%s/2.0/user/" pathEmails = "%s/2.0/user/emails" pathPermission = "%s/2.0/user/permissions/repositories?q=repository.full_name=%q" - pathPermissions = "%s/2.0/user/permissions/repositories?%s" - pathWorkspaces = "%s/2.0/workspaces/?%s" + pathPermissions = "%s/2.0/user/workspaces/%s/permissions/repositories?%s" + pathWorkspaces = "%s/2.0/user/workspaces/?%s" pathWorkspace = "%s/2.0/workspaces/%s" pathRepo = "%s/2.0/repositories/%s/%s" pathRepos = "%s/2.0/repositories/%s?%s" @@ -88,7 +88,7 @@ func (c *Client) ListEmail() (*EmailResp, error) { return out, err } -func (c *Client) ListWorkspaces(opts *ListWorkspacesOpts) (*WorkspacesResp, error) { +func (c *Client) ListWorkspaces(opts *ListOpts) (*WorkspacesResp, error) { out := new(WorkspacesResp) uri := fmt.Sprintf(pathWorkspaces, c.base, opts.Encode()) _, err := c.do(uri, http.MethodGet, nil, out) @@ -170,16 +170,16 @@ func (c *Client) GetPermission(fullName string) (*RepoPerm, error) { return out.Values[0], nil } -func (c *Client) ListPermissions(opts *ListOpts) (*RepoPermResp, error) { +func (c *Client) ListPermissions(workspace string, opts *ListOpts) (*RepoPermResp, error) { out := new(RepoPermResp) - uri := fmt.Sprintf(pathPermissions, c.base, opts.Encode()) + uri := fmt.Sprintf(pathPermissions, c.base, workspace, opts.Encode()) _, err := c.do(uri, http.MethodGet, nil, out) return out, err } -func (c *Client) ListPermissionsAll() ([]*RepoPerm, error) { +func (c *Client) ListPermissionsAll(workspace string) ([]*RepoPerm, error) { return shared_utils.Paginate(func(page int) ([]*RepoPerm, error) { - resp, err := c.ListPermissions(&ListOpts{Page: page, PageLen: pageSize}) + resp, err := c.ListPermissions(workspace, &ListOpts{Page: page, PageLen: pageSize}) if err != nil { return nil, err } diff --git a/server/forge/bitbucket/internal/types.go b/server/forge/bitbucket/internal/types.go index e4657878a..d816ce81f 100644 --- a/server/forge/bitbucket/internal/types.go +++ b/server/forge/bitbucket/internal/types.go @@ -221,26 +221,6 @@ func (o *ListOpts) Encode() string { return params.Encode() } -type ListWorkspacesOpts struct { - Page int - PageLen int - Role string -} - -func (o *ListWorkspacesOpts) Encode() string { - params := url.Values{} - if o.Page != 0 { - params.Set("page", strconv.Itoa(o.Page)) - } - if o.PageLen != 0 { - params.Set("pagelen", strconv.Itoa(o.PageLen)) - } - if len(o.Role) != 0 { - params.Set("role", o.Role) - } - return params.Encode() -} - type Error struct { Status int Body struct {