Repository: xanzy/go-gitlab
Pull request #1924 (2024-04-30 15:20:45)

Add SAML group link support for custom roles
As a GitLab Ultimate customer, we would like to be able to use the custom role feature through SAML and terraform. This change intends to add the ID for the custom role (member_role_id) as an option to the List, Get and Add Group SAML Links commands. Our intention is to then add support to the terraform provider.


Patch:
diff --git a/groups.go b/groups.go
index 2ec7c50..23241f4 100644
--- a/groups.go
+++ b/groups.go
@@ -123,8 +123,9 @@ type LDAPGroupLink struct {
 //
 // GitLab API docs: https://docs.gitlab.com/ee/api/groups.html#saml-group-links
 type SAMLGroupLink struct {
-	Name        string           `json:"name"`
-	AccessLevel AccessLevelValue `json:"access_level"`
+	Name         string           `json:"name"`
+	AccessLevel  AccessLevelValue `json:"access_level"`
+	MemberRoleID int              `json:"member_role_id,omitempty"`
 }
 
 // ListGroupsOptions represents the available ListGroups() options.


Test patch:
diff --git a/groups_test.go b/groups_test.go
index 9087bc4..c272e07 100644
--- a/groups_test.go
+++ b/groups_test.go
@@ -432,6 +432,38 @@ func TestListGroupSAMLLinks(t *testing.T) {
 	}
 }
 
+func TestListGroupSAMLLinksCustomRole(t *testing.T) {
+	mux, client := setup(t)
+
+	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":30,
+		"name":"gitlab_group_example_developer",
+		"member_role_id":123
+	}
+]`)
+		})
+
+	links, _, err := client.Groups.ListGroupSAMLLinks(1)
+	if err != nil {
+		t.Errorf("Groups.ListGroupSAMLLinks returned error: %v", err)
+	}
+
+	want := []*SAMLGroupLink{
+		{
+			AccessLevel:  DeveloperPermissions,
+			Name:         "gitlab_group_example_developer",
+			MemberRoleID: 123,
+		},
+	}
+	if !reflect.DeepEqual(want, links) {
+		t.Errorf("Groups.ListGroupSAMLLinks returned %+v, want %+v", links, want)
+	}
+}
+
 func TestGetGroupSAMLLink(t *testing.T) {
 	mux, client := setup(t)
 
@@ -459,6 +491,35 @@ func TestGetGroupSAMLLink(t *testing.T) {
 	}
 }
 
+func TestGetGroupSAMLLinkCustomRole(t *testing.T) {
+	mux, client := setup(t)
+
+	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":30,
+	"name":"gitlab_group_example_developer",
+	"member_role_id":123
+}`)
+		})
+
+	links, _, err := client.Groups.GetGroupSAMLLink(1, "gitlab_group_example_developer")
+	if err != nil {
+		t.Errorf("Groups.GetGroupSAMLLinks returned error: %v", err)
+	}
+
+	want := &SAMLGroupLink{
+		AccessLevel:  DeveloperPermissions,
+		Name:         "gitlab_group_example_developer",
+		MemberRoleID: 123,
+	}
+	if !reflect.DeepEqual(want, links) {
+		t.Errorf("Groups.GetGroupSAMLLink returned %+v, want %+v", links, want)
+	}
+}
+
 func TestAddGroupSAMLLink(t *testing.T) {
 	mux, client := setup(t)
 
@@ -491,6 +552,40 @@ func TestAddGroupSAMLLink(t *testing.T) {
 	}
 }
 
+func TestAddGroupSAMLLinkCustomRole(t *testing.T) {
+	mux, client := setup(t)
+
+	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":30,
+	"name":"gitlab_group_example_developer",
+	"member_role_id":123
+}`)
+		})
+
+	opt := &AddGroupSAMLLinkOptions{
+		SAMLGroupName: Ptr("gitlab_group_example_developer"),
+		AccessLevel:   Ptr(DeveloperPermissions),
+	}
+
+	link, _, err := client.Groups.AddGroupSAMLLink(1, opt)
+	if err != nil {
+		t.Errorf("Groups.AddGroupSAMLLink returned error: %v", err)
+	}
+
+	want := &SAMLGroupLink{
+		AccessLevel:  DeveloperPermissions,
+		Name:         "gitlab_group_example_developer",
+		MemberRoleID: 123,
+	}
+	if !reflect.DeepEqual(want, link) {
+		t.Errorf("Groups.AddGroupSAMLLink returned %+v, want %+v", link, want)
+	}
+}
+
 func TestRestoreGroup(t *testing.T) {
 	mux, client := setup(t)
 	mux.HandleFunc("/api/v4/groups/1/restore",