Skip to content

Commit

Permalink
Merge pull request #1829 from mauamy/feat/add-member-roles
Browse files Browse the repository at this point in the history
Add member roles API functionality
  • Loading branch information
svanharmelen authored Nov 13, 2023
2 parents ec84ef5 + 99ab72b commit 793bc3c
Show file tree
Hide file tree
Showing 5 changed files with 262 additions and 0 deletions.
2 changes: 2 additions & 0 deletions gitlab.go
Original file line number Diff line number Diff line change
Expand Up @@ -164,6 +164,7 @@ type Client struct {
LicenseTemplates *LicenseTemplatesService
ManagedLicenses *ManagedLicensesService
Markdown *MarkdownService
MemberRolesService *MemberRolesService
MergeRequestApprovals *MergeRequestApprovalsService
MergeRequests *MergeRequestsService
MergeTrains *MergeTrainsService
Expand Down Expand Up @@ -395,6 +396,7 @@ func newClient(options ...ClientOptionFunc) (*Client, error) {
c.LicenseTemplates = &LicenseTemplatesService{client: c}
c.ManagedLicenses = &ManagedLicensesService{client: c}
c.Markdown = &MarkdownService{client: c}
c.MemberRolesService = &MemberRolesService{client: c}
c.MergeRequestApprovals = &MergeRequestApprovalsService{client: c}
c.MergeRequests = &MergeRequestsService{client: c, timeStats: timeStats}
c.MergeTrains = &MergeTrainsService{client: c}
Expand Down
115 changes: 115 additions & 0 deletions member_roles.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,115 @@
package gitlab

import (
"fmt"
"net/http"
)

// MemberRolesService handles communication with the member roles related
// methods of the GitLab API.
//
// GitLab API docs: https://docs.gitlab.com/ee/api/member_roles.html
type MemberRolesService struct {
client *Client
}

// MemberRole represents a GitLab member role.
//
// GitLab API docs: https://docs.gitlab.com/ee/api/member_roles.html
type MemberRole struct {
ID int `json:"id"`
Name string `json:"name"`
Description string `json:"description,omitempty"`
GroupId int `json:"group_id"`
BaseAccessLevel AccessLevelValue `json:"base_access_level"`
AdminMergeRequests bool `json:"admin_merge_requests,omitempty"`
AdminVulnerability bool `json:"admin_vulnerability,omitempty"`
ReadCode bool `json:"read_code,omitempty"`
ReadDependency bool `json:"read_dependency,omitempty"`
ReadVulnerability bool `json:"read_vulnerability,omitempty"`
ManageProjectAccessToken bool `json:"manage_project_access_token,omitempty"`
}

// ListMemberRoles gets a list of member roles for a specified group.
//
// Gitlab API docs:
// https://docs.gitlab.com/ee/api/member_roles.html#list-all-member-roles-of-a-group
func (s *MemberRolesService) ListMemberRoles(gid interface{}, options ...RequestOptionFunc) ([]*MemberRole, *Response, error) {
group, err := parseID(gid)
if err != nil {
return nil, nil, err
}
u := fmt.Sprintf("groups/%s/member_roles", PathEscape(group))

req, err := s.client.NewRequest(http.MethodGet, u, nil, options)
if err != nil {
return nil, nil, err
}

var mrs []*MemberRole
resp, err := s.client.Do(req, &mrs)
if err != nil {
return nil, resp, err
}

return mrs, resp, nil
}

// CreateMemberRoleOptions represents the available CreateMemberRole() options.
//
// GitLab API docs:
// https://docs.gitlab.com/ee/api/member_roles.html#add-a-member-role-to-a-group
type CreateMemberRoleOptions struct {
Name *string `url:"name,omitempty" json:"name,omitempty"`
BaseAccessLevel *AccessLevelValue `url:"base_access_level,omitempty" json:"base_access_level,omitempty"`
Description *string `url:"description,omitempty" json:"description,omitempty"`
AdminMergeRequest *bool `url:"admin_merge_request,omitempty" json:"admin_merge_request,omitempty"`
AdminVulnerability *bool `url:"admin_vulnerability,omitempty" json:"admin_vulnerability,omitempty"`
ReadCode *bool `url:"read_code,omitempty" json:"read_code,omitempty"`
ReadDependency *bool `url:"read_dependency,omitempty" json:"read_dependency,omitempty"`
ReadVulnerability *bool `url:"read_vulnerability,omitempty" json:"read_vulnerability,omitempty"`
}

// CreateMemberRole creates a new member role for a specified group.
//
// Gitlab API docs:
// https://docs.gitlab.com/ee/api/member_roles.html#add-a-member-role-to-a-group
func (s *MemberRolesService) CreateMemberRole(gid interface{}, opt *CreateMemberRoleOptions, options ...RequestOptionFunc) (*MemberRole, *Response, error) {
group, err := parseID(gid)
if err != nil {
return nil, nil, err
}
u := fmt.Sprintf("groups/%s/member_roles", PathEscape(group))

req, err := s.client.NewRequest(http.MethodPost, u, opt, options)
if err != nil {
return nil, nil, err
}

mr := new(MemberRole)
resp, err := s.client.Do(req, mr)
if err != nil {
return nil, resp, err
}

return mr, resp, nil
}

// DeleteMemberRole deletes a member role from a specified group.
//
// Gitlab API docs:
// https://docs.gitlab.com/ee/api/member_roles.html#remove-member-role-of-a-group
func (s *MemberRolesService) DeleteMemberRole(gid interface{}, memberRole int, options ...RequestOptionFunc) (*Response, error) {
group, err := parseID(gid)
if err != nil {
return nil, err
}
u := fmt.Sprintf("groups/%s/member_roles/%d", PathEscape(group), memberRole)

req, err := s.client.NewRequest(http.MethodDelete, u, nil, options)
if err != nil {
return nil, err
}

return s.client.Do(req, nil)
}
105 changes: 105 additions & 0 deletions member_roles_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
package gitlab

import (
"net/http"
"testing"

"github.com/stretchr/testify/require"
)

func TestListMemberRoles(t *testing.T) {
mux, client := setup(t)

path := "/api/v4/groups/1/member_roles"

mux.HandleFunc(path, func(w http.ResponseWriter, r *http.Request) {
testMethod(t, r, http.MethodGet)
mustWriteHTTPResponse(t, w, "testdata/list_member_roles.json")
})

memberRoles, _, err := client.MemberRolesService.ListMemberRoles(1)
require.NoError(t, err)

want := []*MemberRole{
{
ID: 1,
Name: "GuestCodeReader",
Description: "A Guest user that can read code",
GroupId: 1,
BaseAccessLevel: 10, // Guest Base Level
AdminMergeRequests: false,
AdminVulnerability: false,
ReadCode: true,
ReadDependency: false,
ReadVulnerability: false,
ManageProjectAccessToken: false,
},
{
ID: 2,
Name: "GuestVulnerabilityReader",
Description: "A Guest user that can read vulnerabilities",
GroupId: 1,
BaseAccessLevel: 10, // Guest Base Level
AdminMergeRequests: false,
AdminVulnerability: false,
ReadCode: false,
ReadDependency: false,
ReadVulnerability: true,
ManageProjectAccessToken: false,
},
}

require.Equal(t, want, memberRoles)
}

func TestCreateMemberRole(t *testing.T) {
mux, client := setup(t)

path := "/api/v4/groups/84/member_roles"

mux.HandleFunc(path, func(w http.ResponseWriter, r *http.Request) {
testMethod(t, r, http.MethodPost)
mustWriteHTTPResponse(t, w, "testdata/create_member_role.json")
})

memberRole, _, err := client.MemberRolesService.CreateMemberRole(84, &CreateMemberRoleOptions{
Name: Ptr("Custom guest"),
BaseAccessLevel: Ptr(GuestPermissions),
Description: Ptr("a sample custom role"),
AdminMergeRequest: Ptr(false),
AdminVulnerability: Ptr(false),
ReadCode: Ptr(true),
ReadDependency: Ptr(false),
ReadVulnerability: Ptr(false),
})
require.NoError(t, err)

want := &MemberRole{
ID: 3,
Name: "Custom guest",
Description: "a sample custom role",
BaseAccessLevel: GuestPermissions,
GroupId: 84,
AdminMergeRequests: false,
AdminVulnerability: false,
ReadCode: true,
ReadDependency: false,
ReadVulnerability: false,
ManageProjectAccessToken: false,
}

require.Equal(t, want, memberRole)
}

func TestDeleteMemberRole(t *testing.T) {
mux, client := setup(t)

path := "/api/v4/groups/1/member_roles/2"

mux.HandleFunc(path, func(w http.ResponseWriter, r *http.Request) {
testMethod(t, r, http.MethodDelete)
})

_, err := client.MemberRolesService.DeleteMemberRole(1, 2)
require.NoError(t, err)
}
12 changes: 12 additions & 0 deletions testdata/create_member_role.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
{
"id": 3,
"name": "Custom guest",
"description": "a sample custom role",
"group_id": 84,
"base_access_level": 10,
"admin_merge_requests": false,
"admin_vulnerability": false,
"read_code": true,
"read_dependency": false,
"read_vulnerability": false
}
28 changes: 28 additions & 0 deletions testdata/list_member_roles.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
[
{
"id": 1,
"name": "GuestCodeReader",
"description": "A Guest user that can read code",
"group_id": 1,
"base_access_level": 10,
"admin_merge_request": false,
"admin_vulnerability": false,
"read_code": true,
"read_dependency": false,
"read_vulnerability": false,
"manage_project_access_token": false
},
{
"id": 2,
"name": "GuestVulnerabilityReader",
"description": "A Guest user that can read vulnerabilities",
"group_id": 1,
"base_access_level": 10,
"admin_merge_request": false,
"admin_vulnerability": false,
"read_code": false,
"read_dependency": false,
"read_vulnerability": true,
"manage_project_access_token": false
}
]

0 comments on commit 793bc3c

Please sign in to comment.