Skip to content

Commit

Permalink
Merge pull request #1527 from vmg-ventures/feature/add-saml-group-links
Browse files Browse the repository at this point in the history
Add Group SAML Links
  • Loading branch information
svanharmelen committed Aug 21, 2022
2 parents e3c59f9 + 54f06ed commit 301e201
Show file tree
Hide file tree
Showing 2 changed files with 216 additions and 0 deletions.
116 changes: 116 additions & 0 deletions groups.go
Expand Up @@ -75,6 +75,7 @@ type Group struct {
LDAPCN string `json:"ldap_cn"`
LDAPAccess AccessLevelValue `json:"ldap_access"`
LDAPGroupLinks []*LDAPGroupLink `json:"ldap_group_links"`
SAMLGroupLinks []*SAMLGroupLink `json:"saml_group_links"`
SharedRunnersMinutesLimit int `json:"shared_runners_minutes_limit"`
ExtraSharedRunnersMinutesLimit int `json:"extra_shared_runners_minutes_limit"`
PreventForkingOutsideGroup bool `json:"prevent_forking_outside_group"`
Expand All @@ -100,6 +101,14 @@ type LDAPGroupLink struct {
Provider string `json:"provider"`
}

// SAMLGroupLink represents a GitLab SAML group link.
//
// GitLab API docs: https://docs.gitlab.com/ce/api/groups.html#saml-group-links
type SAMLGroupLink struct {
AccessLevel string `json:"access_level"`
Name string `json:"name"`
}

// ListGroupsOptions represents the available ListGroups() options.
//
// GitLab API docs: https://docs.gitlab.com/ce/api/groups.html#list-project-groups
Expand Down Expand Up @@ -744,6 +753,113 @@ func (s *GroupsService) DeleteGroupLDAPLinkForProvider(gid interface{}, provider
return s.client.Do(req, nil)
}

// ListGroupSAMLLinks lists the group's SAML links. Available only for users who
// can edit groups.
//
// GitLab API docs:
// https://docs.gitlab.com/ee/api/groups.html#list-saml-group-links
func (s *GroupsService) ListGroupSAMLLinks(gid interface{}, options ...RequestOptionFunc) ([]*SAMLGroupLink, *Response, error) {
group, err := parseID(gid)
if err != nil {
return nil, nil, err
}
u := fmt.Sprintf("groups/%s/saml_group_links", PathEscape(group))

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

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

return gls, resp, nil
}

// GetGroupSAMLLink get a specific group SAML link. Available only for users who
// can edit groups.
//
// GitLab API docs:
// https://docs.gitlab.com/ee/api/groups.html#get-saml-group-link
func (s *GroupsService) GetGroupSAMLLink(gid interface{}, saml_group_name string, options ...RequestOptionFunc) (*SAMLGroupLink, *Response, error) {
group, err := parseID(gid)
if err != nil {
return nil, nil, err
}
u := fmt.Sprintf("groups/%s/saml_group_links/%s", PathEscape(group), PathEscape(saml_group_name))

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

gl := new(SAMLGroupLink)
resp, err := s.client.Do(req, &gl)
if err != nil {
return nil, resp, err
}

return gl, resp, nil
}

// AddGroupSAMLLinkOptions represents the available AddGroupSAMLLink() options.
//
// GitLab API docs:
// https://docs.gitlab.com/ee/api/groups.html#add-saml-group-link
type AddGroupSAMLLinkOptions struct {
AccessLevel *string `url:"access_level,omitempty" json:"access_level,omitempty"`
SamlGroupName *string `url:"saml_group_name,omitempty" json:"saml_group_name,omitempty"`
}

// AddGroupSAMLLink creates a new group SAML link. Available only for users who
// can edit groups.
//
// GitLab API docs:
// https://docs.gitlab.com/ee/api/groups.html#add-saml-group-link
func (s *GroupsService) AddGroupSAMLLink(gid interface{}, opt *AddGroupSAMLLinkOptions, options ...RequestOptionFunc) (*SAMLGroupLink, *Response, error) {
group, err := parseID(gid)
if err != nil {
return nil, nil, err
}
u := fmt.Sprintf("groups/%s/saml_group_links", PathEscape(group))

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

gl := new(SAMLGroupLink)
resp, err := s.client.Do(req, &gl)
if err != nil {
return nil, resp, err
}

return gl, resp, err
}

// DeleteGroupSAMLLink deletes a group SAML link. Available only for users who
// can edit groups.
//
// GitLab API docs:
// https://docs.gitlab.com/ee/api/groups.html#delete-saml-group-link
func (s *GroupsService) DeleteGroupSAMLLink(gid interface{}, saml_group_name string, options ...RequestOptionFunc) (*Response, error) {
group, err := parseID(gid)
if err != nil {
return nil, err
}
u := fmt.Sprintf("groups/%s/saml_group_links/%s", PathEscape(group), PathEscape(saml_group_name))

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

return s.client.Do(req, nil)
}

// ShareGroupWithGroupOptions represents the available ShareGroupWithGroup() options.
//
// GitLab API docs:
Expand Down
100 changes: 100 additions & 0 deletions groups_test.go
Expand Up @@ -364,6 +364,106 @@ func TestAddGroupLDAPLinkFilter(t *testing.T) {
}
}

func TestListGroupSAMLLinks(t *testing.T) {
mux, server, client := setup(t)
defer teardown(server)

mux.HandleFunc("/api/v4/groups/1/saml_group_links",
func(w http.ResponseWriter, r *http.Request) {
testMethod(t, r, http.MethodGet)
fmt.Fprint(w, `[
{
"access_level":"Developer",
"name":"gitlab_group_example_developer"
},
{
"access_level":"Maintainer",
"name":"gitlab_group_example_maintainer"
}
]`)
})

links, _, err := client.Groups.ListGroupSAMLLinks(1)
if err != nil {
t.Errorf("Groups.ListGroupSAMLLinks returned error: %v", err)
}

want := []*SAMLGroupLink{
{
AccessLevel: "Developer",
Name: "gitlab_group_example_developer",
},
{
AccessLevel: "Maintainer",
Name: "gitlab_group_example_maintainer",
},
}
if !reflect.DeepEqual(want, links) {
t.Errorf("Groups.ListGroupSAMLLinks returned %+v, want %+v", links, want)
}
}

func TestGetGroupSAMLLink(t *testing.T) {
mux, server, client := setup(t)
defer teardown(server)

mux.HandleFunc("/api/v4/groups/1/saml_group_links/gitlab_group_example_developer",
func(w http.ResponseWriter, r *http.Request) {
testMethod(t, r, http.MethodGet)
fmt.Fprint(w, `
{
"access_level":"Developer",
"name":"gitlab_group_example_developer"
}`)
})

links, _, err := client.Groups.GetGroupSAMLLink(1, "gitlab_group_example_developer")
if err != nil {
t.Errorf("Groups.GetGroupSAMLLinks returned error: %v", err)
}

want := &SAMLGroupLink{
AccessLevel: "Developer",
Name: "gitlab_group_example_developer",
}
if !reflect.DeepEqual(want, links) {
t.Errorf("Groups.GetGroupSAMLLink returned %+v, want %+v", links, want)
}
}

func TestAddGroupSAMLLink(t *testing.T) {
mux, server, client := setup(t)
defer teardown(server)

mux.HandleFunc("/api/v4/groups/1/saml_group_links",
func(w http.ResponseWriter, r *http.Request) {
testMethod(t, r, http.MethodPost)
fmt.Fprint(w, `
{
"access_level":"Developer",
"name":"gitlab_group_example_developer"
}`)
})

opt := &AddGroupSAMLLinkOptions{
AccessLevel: String("Developer"),
SamlGroupName: String("gitlab_group_example_developer"),
}

link, _, err := client.Groups.AddGroupSAMLLink(1, opt)
if err != nil {
t.Errorf("Groups.AddGroupSAMLLink returned error: %v", err)
}

want := &SAMLGroupLink{
AccessLevel: "Developer",
Name: "gitlab_group_example_developer",
}
if !reflect.DeepEqual(want, link) {
t.Errorf("Groups.AddGroupSAMLLink returned %+v, want %+v", link, want)
}
}

func TestRestoreGroup(t *testing.T) {
mux, server, client := setup(t)
defer teardown(server)
Expand Down

0 comments on commit 301e201

Please sign in to comment.