Skip to content

Commit a08d988

Browse files
committed
Breaking change - Refactor SCIMService.ListSCIMProvisionedGroupsForEnterprise
1 parent 0838cc2 commit a08d988

6 files changed

Lines changed: 309 additions & 292 deletions

File tree

github/enterprise_scim.go

Lines changed: 66 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -5,39 +5,89 @@
55

66
package github
77

8-
// The URIs that are used to indicate the namespaces of the SCIM schemas (only core schemas are supported).
8+
import (
9+
"context"
10+
"fmt"
11+
)
12+
13+
// The URIs that are used to indicate the namespaces of the SCIM schemas
914
const SCIMSchemasURINamespacesGroups string = "urn:ietf:params:scim:schemas:core:2.0:Group"
15+
const SCIMSchemasURINamespacesListResponse string = "urn:ietf:params:scim:api:messages:2.0:ListResponse"
1016

1117
// SCIMEnterpriseGroupAttributes represents supported SCIM Enterprise group attributes.
1218
// GitHub API docs:https://docs.github.com/en/enterprise-cloud@latest/rest/enterprise-admin/scim#supported-scim-group-attributes
1319
type SCIMEnterpriseGroupAttributes struct {
1420
DisplayName *string `json:"displayName,omitempty"` // Human-readable name for a group.
15-
Members []*SCIMEnterpriseDisplayReference `json:"members,omitempty"` // (Optional.)
16-
ExternalID *string `json:"externalId,omitempty"` // (Optional.)
17-
// Only populated as a result of calling ListSCIMProvisionedIdentitiesOptions:
18-
Schemas []string `json:"schemas"` // (Optional.)
19-
ID *string `json:"id,omitempty"`
20-
Meta *SCIMMeta `json:"meta,omitempty"`
21+
Members []*SCIMEnterpriseDisplayReference `json:"members,omitempty"` // List of members who are assigned to the group in SCIM provider
22+
ExternalID *string `json:"externalId,omitempty"` // This identifier is generated by a SCIM provider. Must be unique per user.
23+
// Bellow: Only populated as a result of calling SetSCIMInformationForProvisionedEnterpriseGroup:
24+
Schemas []string `json:"schemas,omitempty"` // The URIs that are used to indicate the namespaces of the SCIM schemas.
25+
ID *string `json:"id,omitempty"` // The internally generated id for the group object.
26+
Meta *SCIMEnterpriseMeta `json:"meta,omitempty"` // The metadata associated with the creation/updates to the group.
2127
}
2228

2329
// SCIMEnterpriseDisplayReference represents a JSON SCIM (System for Cross-domain Identity Management) resource.
2430
type SCIMEnterpriseDisplayReference struct {
25-
Value string `json:"value"` // (Required.)
26-
Ref string `json:"$+ref"` // (Required.)
27-
Display *string `json:"displayName,omitempty"` // (Optional.)
31+
Value string `json:"value"` // The local unique identifier for the member
32+
Ref string `json:"$ref"`
33+
Display *string `json:"display,omitempty"` // The display name associated with the member
2834
}
2935

3036
// SCIMEnterpriseMeta represents metadata about the SCIM resource.
3137
type SCIMEnterpriseMeta struct {
32-
ResourceType *string `json:"resourceType,omitempty"`
33-
Created *Timestamp `json:"created,omitempty"`
34-
LastModified *Timestamp `json:"lastModified,omitempty"`
35-
Location *string `json:"location,omitempty"`
38+
ResourceType *string `json:"resourceType"` // A type of a resource (`User` or `Group`).
39+
Created *Timestamp `json:"created,omitempty"` // A date and time when the user was created.
40+
LastModified *Timestamp `json:"lastModified,omitempty"` // A date and time when the user was last modified.
41+
Location *string `json:"location,omitempty"` // A URL location of an object
42+
}
43+
44+
// SCIMEnterpriseGroups represents the result of calling ListProvisionedSCIMGroupsForEnterprises.
45+
type SCIMEnterpriseGroups struct {
46+
Schemas []string `json:"schemas"`
47+
TotalResults *int `json:"totalResults"`
48+
Resources []*SCIMEnterpriseGroupAttributes `json:"Resources"`
49+
StartIndex *int `json:"startIndex"`
50+
ItemsPerPage *int `json:"itemsPerPage"`
51+
}
52+
53+
// ListProvisionedSCIMGroupsForEnterpriseOptions represents query parameters for ListProvisionedSCIMGroupsForEnterprise.
54+
//
55+
// GitHub API docs: https://docs.github.com/en/enterprise-cloud@latest/rest/enterprise-admin/scim#list-provisioned-scim-groups-for-an-enterprise--parameters
56+
type ListProvisionedSCIMGroupsForEnterpriseOptions struct {
57+
// If specified, only results that match the specified filter will be returned. Multiple filters are not supported.
58+
// Possible filters are `externalId`, id, and `displayName`. For example,`?filter=externalId eq "9138790-10932-109120392-12321"`.
59+
Filter *string `url:"filter,omitempty"`
60+
// Excludes the specified attribute from being returned in the results. Using this parameter can speed up response time.
61+
ExcludedAttributes *string `url:"excludedAttributes,omitempty"`
62+
// Excludes the specified attribute from being returned in the results. Using this parameter can speed up response time.
63+
// Default: 1.
64+
StartIndex *int `url:"startIndex,omitempty"`
65+
// Used for pagination: the number of results to return per page.
66+
// Default: 30.
67+
Count *int `url:"count,omitempty"`
3668
}
3769

3870
// ListProvisionedSCIMGroupsForEnterprise lists provisioned SCIM groups in an enterprise.
3971
// GitHub API docs: https://docs.github.com/en/enterprise-cloud@latest/rest/enterprise-admin/scim#list-provisioned-scim-groups-for-an-enterprise
4072
//
4173
//meta:operation GET /scim/v2/enterprises/{enterprise}/Groups
42-
// func (s *SCIMService) ListProvisionedSCIMGroupsForEnterprise(ctx context.Context, enterprise string, opts *ListOptions) ([]*SCIMEnterpriseGroupAttributes, *Response, error) {
43-
//}
74+
func (s *EnterpriseService) ListProvisionedSCIMGroupsForEnterprise(ctx context.Context, enterprise string, opts *ListProvisionedSCIMGroupsForEnterpriseOptions) (*SCIMEnterpriseGroupAttributes, *Response, error) {
75+
u := fmt.Sprintf("scim/v2/enterprises/%v/Groups", enterprise)
76+
u, err := addOptions(u, opts)
77+
if err != nil {
78+
return nil, nil, err
79+
}
80+
81+
req, err := s.client.NewRequest("GET", u, nil)
82+
if err != nil {
83+
return nil, nil, err
84+
}
85+
86+
groups := new(SCIMEnterpriseGroupAttributes)
87+
resp, err := s.client.Do(ctx, req, groups)
88+
if err != nil {
89+
return nil, resp, err
90+
}
91+
92+
return groups, resp, nil
93+
}

github/enterprise_scim_test.go

Lines changed: 208 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,216 @@
66
package github
77

88
import (
9-
"fmt"
109
"net/http"
1110
"testing"
1211

1312
"github.com/google/go-cmp/cmp"
1413
)
14+
15+
func TestSCIMProvisionedGroups_Marshal(t *testing.T) {
16+
t.Parallel()
17+
testJSONMarshal(t, &SCIMEnterpriseGroups{}, "{}")
18+
19+
u := &SCIMEnterpriseGroups{
20+
Schemas: []string{"s1"},
21+
TotalResults: Ptr(1),
22+
ItemsPerPage: Ptr(2),
23+
StartIndex: Ptr(3),
24+
Resources: []*SCIMEnterpriseGroupAttributes{
25+
{
26+
DisplayName: Ptr("dn"),
27+
Members: []*SCIMEnterpriseDisplayReference{
28+
{
29+
Value: "v",
30+
Ref: "r",
31+
Display: Ptr("d"),
32+
},
33+
},
34+
Schemas: []string{"s2"},
35+
ExternalID: Ptr("eid"),
36+
ID: Ptr("id"),
37+
Meta: &SCIMEnterpriseMeta{
38+
ResourceType: Ptr("rt"),
39+
Created: &Timestamp{referenceTime},
40+
LastModified: &Timestamp{referenceTime},
41+
Location: Ptr("l"),
42+
},
43+
},
44+
},
45+
}
46+
47+
want := `{
48+
"schemas": ["s1"],
49+
"totalResults": 1,
50+
"itemsPerPage": 2,
51+
"startIndex": 3,
52+
"Resources": [{
53+
"displayName": "dn",
54+
"members": [{
55+
"value": "v",
56+
"$ref": "r",
57+
"display": "d"
58+
}]
59+
,"schemas": ["s2"],
60+
"externalId": "eid",
61+
"id": "id",
62+
"meta": {
63+
"resourceType": "rt",
64+
"created": ` + referenceTimeStr + `,
65+
"lastModified": ` + referenceTimeStr + `,
66+
"location": "l"
67+
}
68+
}]
69+
}`
70+
71+
testJSONMarshal(t, u, want)
72+
}
73+
74+
func TestSCIMEnterpriseGroupAttributes_Marshal(t *testing.T) {
75+
t.Parallel()
76+
testJSONMarshal(t, &SCIMEnterpriseGroupAttributes{}, "{}")
77+
78+
u := &SCIMEnterpriseGroupAttributes{
79+
DisplayName: Ptr("dn"),
80+
Members: []*SCIMEnterpriseDisplayReference{{
81+
Value: "v",
82+
Ref: "r",
83+
Display: Ptr("d"),
84+
}},
85+
ExternalID: Ptr("eid"),
86+
ID: Ptr("id"),
87+
Schemas: []string{"s1"},
88+
Meta: &SCIMEnterpriseMeta{
89+
ResourceType: Ptr("rt"),
90+
Created: &Timestamp{referenceTime},
91+
LastModified: &Timestamp{referenceTime},
92+
Location: Ptr("l"),
93+
},
94+
}
95+
96+
want := `{
97+
"schemas": ["s1"],
98+
"externalId": "eid",
99+
"displayName": "dn",
100+
"members" : [{
101+
"value": "v",
102+
"$ref": "r",
103+
"display": "d"
104+
}],
105+
"id": "id",
106+
"meta": {
107+
"resourceType": "rt",
108+
"created": ` + referenceTimeStr + `,
109+
"lastModified": ` + referenceTimeStr + `,
110+
"location": "l"
111+
}
112+
}]
113+
}`
114+
115+
testJSONMarshal(t, u, want)
116+
}
117+
118+
func TestEnterpriseService_ListProvisionedSCIMGroupsForEnterprise(t *testing.T) {
119+
t.Parallel()
120+
client, mux, _ := setup(t)
121+
122+
mux.HandleFunc("scim/v2/enterprises/ee/Groups", func(w http.ResponseWriter, r *http.Request) {
123+
testMethod(t, r, "GET")
124+
testFormValues(t, r, values{
125+
"startIndex": "1",
126+
"excludedAttributes": "members,meta",
127+
"count": "3",
128+
"filter": `externalId eq "8aa1"`,
129+
})
130+
w.WriteHeader(http.StatusOK)
131+
_, _ = w.Write([]byte(`{
132+
"schemas": [` + SCIMSchemasURINamespacesListResponse + `],
133+
"totalResults": 1,
134+
"Resources": [
135+
{
136+
"schemas": [` + SCIMSchemasURINamespacesGroups + `],
137+
"externalId": "8aa1",
138+
"id": "24b2",
139+
"displayName": "dn",
140+
"members": [
141+
{
142+
"value": "879d",
143+
"$+ref": "https://api.github.localhost/scim/v2/Users/879d",
144+
"display": "u1"
145+
},
146+
{
147+
"value": "0db5",
148+
"$+ref": "https://api.github.localhost/scim/v2/Users/0db5",
149+
"display": "u2"
150+
}
151+
],
152+
"meta": {
153+
"resourceType": "Group",
154+
"created": ` + referenceTimeStr + `,
155+
"lastModified": ` + referenceTimeStr + `,
156+
"location": "https://api.github.localhost/scim/v2/Groups/24b2"
157+
}
158+
}
159+
],
160+
"startIndex": 1,
161+
"itemsPerPage": 1
162+
}`))
163+
})
164+
165+
ctx := t.Context()
166+
opts := &ListProvisionedSCIMGroupsForEnterpriseOptions{
167+
StartIndex: Ptr(1),
168+
ExcludedAttributes: Ptr("members,meta"),
169+
Count: Ptr(3),
170+
Filter: Ptr(`externalId eq "8aa1"`),
171+
}
172+
groups, _, err := client.Enterprise.ListProvisionedSCIMGroupsForEnterprise(ctx, "ee", opts)
173+
if err != nil {
174+
t.Errorf("Enterprise.ListSCIMProvisionedIdentities returned error: %v", err)
175+
}
176+
177+
want := SCIMEnterpriseGroups{
178+
Schemas: []string{SCIMSchemasURINamespacesListResponse},
179+
TotalResults: Ptr(1),
180+
ItemsPerPage: Ptr(1),
181+
StartIndex: Ptr(1),
182+
Resources: []*SCIMEnterpriseGroupAttributes{
183+
{
184+
ID: Ptr("123e4567-e89b-12d3-a456-426614174000"),
185+
Meta: &SCIMEnterpriseMeta{
186+
ResourceType: Ptr("Group"),
187+
Created: &Timestamp{referenceTime},
188+
LastModified: &Timestamp{referenceTime},
189+
Location: Ptr("https://api.github.com/scim/v2/enterprises/octo/Groups/123e4567-e89b-12d3-a456-426614174000"),
190+
},
191+
192+
DisplayName: Ptr("Mona Octocat"),
193+
Schemas: []string{"urn:ietf:params:scim:schemas:core:2.0:Group"},
194+
ExternalID: Ptr("00u1dhhb1fkIGP7RL1d8"),
195+
Members: []*SCIMEnterpriseDisplayReference{
196+
{
197+
Value: "5fc0c238-1112-11e8-8e45-920c87bdbd75",
198+
Ref: "https://api.github.com/scim/v2/enterprises/octo/Users/5fc0c238-1112-11e8-8e45-920c87bdbd75",
199+
Display: Ptr("Mona Octocat"),
200+
},
201+
},
202+
},
203+
},
204+
}
205+
206+
if !cmp.Equal(groups, &want) {
207+
diff := cmp.Diff(groups, want)
208+
t.Errorf("SCIM.ListSCIMProvisionedGroupsForEnterprise returned %+v, want %+v: diff %+v", groups, want, diff)
209+
}
210+
211+
const methodName = "ListSCIMProvisionedGroupsForEnterprise"
212+
testBadOptions(t, methodName, func() (err error) {
213+
_, _, err = client.Enterprise.ListProvisionedSCIMGroupsForEnterprise(ctx, "\n", opts)
214+
return err
215+
})
216+
217+
testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) {
218+
_, r, err := client.Enterprise.ListProvisionedSCIMGroupsForEnterprise(ctx, "o", opts)
219+
return r, err
220+
})
221+
}

0 commit comments

Comments
 (0)