Skip to content
This repository was archived by the owner on Dec 10, 2024. It is now read-only.

Commit 793bc3c

Browse files
authored
Merge pull request #1829 from mauamy/feat/add-member-roles
Add member roles API functionality
2 parents ec84ef5 + 99ab72b commit 793bc3c

File tree

5 files changed

+262
-0
lines changed

5 files changed

+262
-0
lines changed

gitlab.go

+2
Original file line numberDiff line numberDiff line change
@@ -164,6 +164,7 @@ type Client struct {
164164
LicenseTemplates *LicenseTemplatesService
165165
ManagedLicenses *ManagedLicensesService
166166
Markdown *MarkdownService
167+
MemberRolesService *MemberRolesService
167168
MergeRequestApprovals *MergeRequestApprovalsService
168169
MergeRequests *MergeRequestsService
169170
MergeTrains *MergeTrainsService
@@ -395,6 +396,7 @@ func newClient(options ...ClientOptionFunc) (*Client, error) {
395396
c.LicenseTemplates = &LicenseTemplatesService{client: c}
396397
c.ManagedLicenses = &ManagedLicensesService{client: c}
397398
c.Markdown = &MarkdownService{client: c}
399+
c.MemberRolesService = &MemberRolesService{client: c}
398400
c.MergeRequestApprovals = &MergeRequestApprovalsService{client: c}
399401
c.MergeRequests = &MergeRequestsService{client: c, timeStats: timeStats}
400402
c.MergeTrains = &MergeTrainsService{client: c}

member_roles.go

+115
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,115 @@
1+
package gitlab
2+
3+
import (
4+
"fmt"
5+
"net/http"
6+
)
7+
8+
// MemberRolesService handles communication with the member roles related
9+
// methods of the GitLab API.
10+
//
11+
// GitLab API docs: https://docs.gitlab.com/ee/api/member_roles.html
12+
type MemberRolesService struct {
13+
client *Client
14+
}
15+
16+
// MemberRole represents a GitLab member role.
17+
//
18+
// GitLab API docs: https://docs.gitlab.com/ee/api/member_roles.html
19+
type MemberRole struct {
20+
ID int `json:"id"`
21+
Name string `json:"name"`
22+
Description string `json:"description,omitempty"`
23+
GroupId int `json:"group_id"`
24+
BaseAccessLevel AccessLevelValue `json:"base_access_level"`
25+
AdminMergeRequests bool `json:"admin_merge_requests,omitempty"`
26+
AdminVulnerability bool `json:"admin_vulnerability,omitempty"`
27+
ReadCode bool `json:"read_code,omitempty"`
28+
ReadDependency bool `json:"read_dependency,omitempty"`
29+
ReadVulnerability bool `json:"read_vulnerability,omitempty"`
30+
ManageProjectAccessToken bool `json:"manage_project_access_token,omitempty"`
31+
}
32+
33+
// ListMemberRoles gets a list of member roles for a specified group.
34+
//
35+
// Gitlab API docs:
36+
// https://docs.gitlab.com/ee/api/member_roles.html#list-all-member-roles-of-a-group
37+
func (s *MemberRolesService) ListMemberRoles(gid interface{}, options ...RequestOptionFunc) ([]*MemberRole, *Response, error) {
38+
group, err := parseID(gid)
39+
if err != nil {
40+
return nil, nil, err
41+
}
42+
u := fmt.Sprintf("groups/%s/member_roles", PathEscape(group))
43+
44+
req, err := s.client.NewRequest(http.MethodGet, u, nil, options)
45+
if err != nil {
46+
return nil, nil, err
47+
}
48+
49+
var mrs []*MemberRole
50+
resp, err := s.client.Do(req, &mrs)
51+
if err != nil {
52+
return nil, resp, err
53+
}
54+
55+
return mrs, resp, nil
56+
}
57+
58+
// CreateMemberRoleOptions represents the available CreateMemberRole() options.
59+
//
60+
// GitLab API docs:
61+
// https://docs.gitlab.com/ee/api/member_roles.html#add-a-member-role-to-a-group
62+
type CreateMemberRoleOptions struct {
63+
Name *string `url:"name,omitempty" json:"name,omitempty"`
64+
BaseAccessLevel *AccessLevelValue `url:"base_access_level,omitempty" json:"base_access_level,omitempty"`
65+
Description *string `url:"description,omitempty" json:"description,omitempty"`
66+
AdminMergeRequest *bool `url:"admin_merge_request,omitempty" json:"admin_merge_request,omitempty"`
67+
AdminVulnerability *bool `url:"admin_vulnerability,omitempty" json:"admin_vulnerability,omitempty"`
68+
ReadCode *bool `url:"read_code,omitempty" json:"read_code,omitempty"`
69+
ReadDependency *bool `url:"read_dependency,omitempty" json:"read_dependency,omitempty"`
70+
ReadVulnerability *bool `url:"read_vulnerability,omitempty" json:"read_vulnerability,omitempty"`
71+
}
72+
73+
// CreateMemberRole creates a new member role for a specified group.
74+
//
75+
// Gitlab API docs:
76+
// https://docs.gitlab.com/ee/api/member_roles.html#add-a-member-role-to-a-group
77+
func (s *MemberRolesService) CreateMemberRole(gid interface{}, opt *CreateMemberRoleOptions, options ...RequestOptionFunc) (*MemberRole, *Response, error) {
78+
group, err := parseID(gid)
79+
if err != nil {
80+
return nil, nil, err
81+
}
82+
u := fmt.Sprintf("groups/%s/member_roles", PathEscape(group))
83+
84+
req, err := s.client.NewRequest(http.MethodPost, u, opt, options)
85+
if err != nil {
86+
return nil, nil, err
87+
}
88+
89+
mr := new(MemberRole)
90+
resp, err := s.client.Do(req, mr)
91+
if err != nil {
92+
return nil, resp, err
93+
}
94+
95+
return mr, resp, nil
96+
}
97+
98+
// DeleteMemberRole deletes a member role from a specified group.
99+
//
100+
// Gitlab API docs:
101+
// https://docs.gitlab.com/ee/api/member_roles.html#remove-member-role-of-a-group
102+
func (s *MemberRolesService) DeleteMemberRole(gid interface{}, memberRole int, options ...RequestOptionFunc) (*Response, error) {
103+
group, err := parseID(gid)
104+
if err != nil {
105+
return nil, err
106+
}
107+
u := fmt.Sprintf("groups/%s/member_roles/%d", PathEscape(group), memberRole)
108+
109+
req, err := s.client.NewRequest(http.MethodDelete, u, nil, options)
110+
if err != nil {
111+
return nil, err
112+
}
113+
114+
return s.client.Do(req, nil)
115+
}

member_roles_test.go

+105
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,105 @@
1+
package gitlab
2+
3+
import (
4+
"net/http"
5+
"testing"
6+
7+
"github.com/stretchr/testify/require"
8+
)
9+
10+
func TestListMemberRoles(t *testing.T) {
11+
mux, client := setup(t)
12+
13+
path := "/api/v4/groups/1/member_roles"
14+
15+
mux.HandleFunc(path, func(w http.ResponseWriter, r *http.Request) {
16+
testMethod(t, r, http.MethodGet)
17+
mustWriteHTTPResponse(t, w, "testdata/list_member_roles.json")
18+
})
19+
20+
memberRoles, _, err := client.MemberRolesService.ListMemberRoles(1)
21+
require.NoError(t, err)
22+
23+
want := []*MemberRole{
24+
{
25+
ID: 1,
26+
Name: "GuestCodeReader",
27+
Description: "A Guest user that can read code",
28+
GroupId: 1,
29+
BaseAccessLevel: 10, // Guest Base Level
30+
AdminMergeRequests: false,
31+
AdminVulnerability: false,
32+
ReadCode: true,
33+
ReadDependency: false,
34+
ReadVulnerability: false,
35+
ManageProjectAccessToken: false,
36+
},
37+
{
38+
ID: 2,
39+
Name: "GuestVulnerabilityReader",
40+
Description: "A Guest user that can read vulnerabilities",
41+
GroupId: 1,
42+
BaseAccessLevel: 10, // Guest Base Level
43+
AdminMergeRequests: false,
44+
AdminVulnerability: false,
45+
ReadCode: false,
46+
ReadDependency: false,
47+
ReadVulnerability: true,
48+
ManageProjectAccessToken: false,
49+
},
50+
}
51+
52+
require.Equal(t, want, memberRoles)
53+
}
54+
55+
func TestCreateMemberRole(t *testing.T) {
56+
mux, client := setup(t)
57+
58+
path := "/api/v4/groups/84/member_roles"
59+
60+
mux.HandleFunc(path, func(w http.ResponseWriter, r *http.Request) {
61+
testMethod(t, r, http.MethodPost)
62+
mustWriteHTTPResponse(t, w, "testdata/create_member_role.json")
63+
})
64+
65+
memberRole, _, err := client.MemberRolesService.CreateMemberRole(84, &CreateMemberRoleOptions{
66+
Name: Ptr("Custom guest"),
67+
BaseAccessLevel: Ptr(GuestPermissions),
68+
Description: Ptr("a sample custom role"),
69+
AdminMergeRequest: Ptr(false),
70+
AdminVulnerability: Ptr(false),
71+
ReadCode: Ptr(true),
72+
ReadDependency: Ptr(false),
73+
ReadVulnerability: Ptr(false),
74+
})
75+
require.NoError(t, err)
76+
77+
want := &MemberRole{
78+
ID: 3,
79+
Name: "Custom guest",
80+
Description: "a sample custom role",
81+
BaseAccessLevel: GuestPermissions,
82+
GroupId: 84,
83+
AdminMergeRequests: false,
84+
AdminVulnerability: false,
85+
ReadCode: true,
86+
ReadDependency: false,
87+
ReadVulnerability: false,
88+
ManageProjectAccessToken: false,
89+
}
90+
91+
require.Equal(t, want, memberRole)
92+
}
93+
94+
func TestDeleteMemberRole(t *testing.T) {
95+
mux, client := setup(t)
96+
97+
path := "/api/v4/groups/1/member_roles/2"
98+
99+
mux.HandleFunc(path, func(w http.ResponseWriter, r *http.Request) {
100+
testMethod(t, r, http.MethodDelete)
101+
})
102+
103+
_, err := client.MemberRolesService.DeleteMemberRole(1, 2)
104+
require.NoError(t, err)
105+
}

testdata/create_member_role.json

+12
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
{
2+
"id": 3,
3+
"name": "Custom guest",
4+
"description": "a sample custom role",
5+
"group_id": 84,
6+
"base_access_level": 10,
7+
"admin_merge_requests": false,
8+
"admin_vulnerability": false,
9+
"read_code": true,
10+
"read_dependency": false,
11+
"read_vulnerability": false
12+
}

testdata/list_member_roles.json

+28
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
[
2+
{
3+
"id": 1,
4+
"name": "GuestCodeReader",
5+
"description": "A Guest user that can read code",
6+
"group_id": 1,
7+
"base_access_level": 10,
8+
"admin_merge_request": false,
9+
"admin_vulnerability": false,
10+
"read_code": true,
11+
"read_dependency": false,
12+
"read_vulnerability": false,
13+
"manage_project_access_token": false
14+
},
15+
{
16+
"id": 2,
17+
"name": "GuestVulnerabilityReader",
18+
"description": "A Guest user that can read vulnerabilities",
19+
"group_id": 1,
20+
"base_access_level": 10,
21+
"admin_merge_request": false,
22+
"admin_vulnerability": false,
23+
"read_code": false,
24+
"read_dependency": false,
25+
"read_vulnerability": true,
26+
"manage_project_access_token": false
27+
}
28+
]

0 commit comments

Comments
 (0)