-
Notifications
You must be signed in to change notification settings - Fork 2.2k
feat!: Implement Enterprise SCIM - EnterpriseService.ListProvisionedSCIMGroups #3814
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
+432
−390
Merged
Changes from 20 commits
Commits
Show all changes
26 commits
Select commit
Hold shift + click to select a range
65b5cfe
Initial Enterprise SCIM schema
elminster-aom c1c2f12
Add missing type structs
elminster-aom f7d36fc
Deprecate ListSCIMProvisionedGroupsForEnterprise for ListProvisionedS…
elminster-aom 0838cc2
Refactor - Focus on ListProvisionedSCIMGroupsForEnterprise only
elminster-aom a08d988
Breaking change - Refactor SCIMService.ListSCIMProvisionedGroupsForEn…
elminster-aom 0700f94
Bump version of go-github to v78.0.0 (#3815)
gmlewis b7731e5
Bump go-github from v77 to v78 in /scrape (#3816)
gmlewis ab42c15
chore: Enable 'modernize'; bump golangci-lint to v2.6.1 (#3817)
alexandear 2b21b37
feat: Add `required_reviewers` support to `PullRequestRuleParameters`…
smazmi 2568481
Add support for new custom properties for orgs APIs (#3804)
Not-Dhananjay-Mishra a44d6ae
build(deps): Bump golang.org/x/sync from 0.17.0 to 0.18.0 in /tools (…
dependabot[bot] c2d8c9e
chore: Enable nolintlint linter (#3821)
alexandear ee7887d
Fix struct type issues and adjust standards
elminster-aom 6bdaa40
Merge branch 'master' into enterpriseSCIM
elminster-aom 5e283e1
Merge branch 'master' into enterpriseSCIM
elminster-aom b33cd46
Rename ListProvisionedSCIMGroupsForEnterprise to ListProvisionedSCIME…
elminster-aom 7bc8c30
Improve comments
elminster-aom af91ab8
Improve nomenclature
elminster-aom 862685b
Fix lint issue with jsonfieldname
elminster-aom e506052
Merge branch 'master' into enterpriseSCIM
elminster-aom 4ed75ac
Simplify to ListProvisionedSCIMGroups()
elminster-aom e8fffba
Fix ListProvisionedSCIMGroupsEnterpriseOptions type
elminster-aom 919fbd9
Update github/enterprise_scim.go
elminster-aom 9de4f3d
Merge branch 'master' into enterpriseSCIM
elminster-aom 04ec0d3
Fix lint error in SCIMEnterpriseGroupAttributes comments
elminster-aom 7368118
Merge branch 'master' into enterpriseSCIM
elminster-aom File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Some comments aren't visible on the classic Files Changed page.
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,98 @@ | ||
| // Copyright 2025 The go-github AUTHORS. All rights reserved. | ||
| // | ||
| // Use of this source code is governed by a BSD-style | ||
| // license that can be found in the LICENSE file. | ||
|
|
||
| package github | ||
|
|
||
| import ( | ||
| "context" | ||
| "fmt" | ||
| ) | ||
|
|
||
| // SCIMSchemasURINamespacesGroups is the SCIM schema URI namespace for group resources. | ||
| // This constant represents the standard SCIM core schema for group objects as defined by RFC 7643. | ||
| const SCIMSchemasURINamespacesGroups = "urn:ietf:params:scim:schemas:core:2.0:Group" | ||
|
|
||
| // SCIMSchemasURINamespacesListResponse is the SCIM schema URI namespace for list response resources. | ||
| // This constant represents the standard SCIM namespace for list responses used in paginated queries, as defined by RFC 7644. | ||
| const SCIMSchemasURINamespacesListResponse = "urn:ietf:params:scim:api:messages:2.0:ListResponse" | ||
|
|
||
| // SCIMEnterpriseGroupAttributes represents supported SCIM Enterprise group attributes. | ||
| // GitHub API docs:https://docs.github.com/enterprise-cloud@latest/rest/enterprise-admin/scim#supported-scim-group-attributes | ||
elminster-aom marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| type SCIMEnterpriseGroupAttributes struct { | ||
| DisplayName *string `json:"displayName,omitempty"` // Human-readable name for a group. | ||
| Members []*SCIMEnterpriseDisplayReference `json:"members,omitempty"` // List of members who are assigned to the group in SCIM provider | ||
| ExternalID *string `json:"externalId,omitempty"` // This identifier is generated by a SCIM provider. Must be unique per user. | ||
| // Bellow: Only populated as a result of calling SetSCIMInformationForProvisionedEnterpriseGroup: | ||
| Schemas []string `json:"schemas,omitempty"` // The URIs that are used to indicate the namespaces of the SCIM schemas. | ||
| ID *string `json:"id,omitempty"` // The internally generated id for the group object. | ||
| Meta *SCIMEnterpriseMeta `json:"meta,omitempty"` // The metadata associated with the creation/updates to the group. | ||
| } | ||
|
|
||
| // SCIMEnterpriseDisplayReference represents a JSON SCIM (System for Cross-domain Identity Management) resource reference. | ||
| type SCIMEnterpriseDisplayReference struct { | ||
| Value string `json:"value"` // The local unique identifier for the member (e.g., user ID or group ID). | ||
| Ref string `json:"$ref"` // The URI reference to the member resource (e.g., https://api.github.com/scim/v2/Users/{id}). | ||
| Display *string `json:"display,omitempty"` // The display name associated with the member (e.g., user name or group name). | ||
| } | ||
|
|
||
| // SCIMEnterpriseMeta represents metadata about the SCIM resource. | ||
| type SCIMEnterpriseMeta struct { | ||
| ResourceType string `json:"resourceType"` // A type of a resource (`User` or `Group`). | ||
| Created *Timestamp `json:"created,omitempty"` // A date and time when the user was created. | ||
| LastModified *Timestamp `json:"lastModified,omitempty"` // A date and time when the user was last modified. | ||
| Location *string `json:"location,omitempty"` // A URL location of an object | ||
| } | ||
|
|
||
| // SCIMEnterpriseGroups represents the result of calling ListProvisionedSCIMEnterpriseGroups. | ||
| type SCIMEnterpriseGroups struct { | ||
| Schemas []string `json:"schemas,omitempty"` | ||
| TotalResults *int `json:"totalResults,omitempty"` | ||
| Resources []*SCIMEnterpriseGroupAttributes `json:"Resources,omitempty"` | ||
| StartIndex *int `json:"startIndex,omitempty"` | ||
| ItemsPerPage *int `json:"itemsPerPage,omitempty"` | ||
| } | ||
|
|
||
| // ListProvisionedSCIMEnterpriseGroupsOptions represents query parameters for ListProvisionedSCIMEnterpriseGroups. | ||
| // | ||
| // GitHub API docs: https://docs.github.com/enterprise-cloud@latest/rest/enterprise-admin/scim#list-provisioned-scim-groups-for-an-enterprise--parameters | ||
| type ListProvisionedSCIMEnterpriseGroupsOptions struct { | ||
| // If specified, only results that match the specified filter will be returned. Multiple filters are not supported. | ||
| // Possible filters are `externalId`, id, and `displayName`. For example,`?filter=externalId eq "9138790-10932-109120392-12321"`. | ||
| Filter *string `url:"filter,omitempty"` | ||
| // Excludes the specified attribute from being returned in the results. Using this parameter can speed up response time. | ||
| ExcludedAttributes *string `url:"excludedAttributes,omitempty"` | ||
| // Excludes the specified attribute from being returned in the results. Using this parameter can speed up response time. | ||
| // Default: 1. | ||
| StartIndex *int `url:"startIndex,omitempty"` | ||
| // Used for pagination: the number of results to return per page. | ||
| // Default: 30. | ||
| Count *int `url:"count,omitempty"` | ||
| } | ||
|
|
||
| // ListProvisionedSCIMEnterpriseGroups lists provisioned SCIM groups in an enterprise. | ||
| // | ||
| // GitHub API docs: https://docs.github.com/enterprise-cloud@latest/rest/enterprise-admin/scim#list-provisioned-scim-groups-for-an-enterprise | ||
| // | ||
| //meta:operation GET /scim/v2/enterprises/{enterprise}/Groups | ||
| func (s *EnterpriseService) ListProvisionedSCIMEnterpriseGroups(ctx context.Context, enterprise string, opts *ListProvisionedSCIMEnterpriseGroupsOptions) (*SCIMEnterpriseGroups, *Response, error) { | ||
| u := fmt.Sprintf("scim/v2/enterprises/%v/Groups", enterprise) | ||
| u, err := addOptions(u, opts) | ||
| if err != nil { | ||
| return nil, nil, err | ||
| } | ||
|
|
||
| req, err := s.client.NewRequest("GET", u, nil) | ||
| if err != nil { | ||
| return nil, nil, err | ||
| } | ||
|
|
||
| groups := new(SCIMEnterpriseGroups) | ||
| resp, err := s.client.Do(ctx, req, groups) | ||
| if err != nil { | ||
| return nil, resp, err | ||
| } | ||
|
|
||
| return groups, resp, nil | ||
| } | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,201 @@ | ||
| // Copyright 2025 The go-github AUTHORS. All rights reserved. | ||
| // | ||
| // Use of this source code is governed by a BSD-style | ||
| // license that can be found in the LICENSE file. | ||
|
|
||
| package github | ||
|
|
||
| import ( | ||
| "net/http" | ||
| "testing" | ||
|
|
||
| "github.com/google/go-cmp/cmp" | ||
| ) | ||
|
|
||
| func TestSCIMProvisionedGroups_Marshal(t *testing.T) { | ||
| t.Parallel() | ||
| testJSONMarshal(t, &SCIMEnterpriseGroups{}, "{}") | ||
|
|
||
| u := &SCIMEnterpriseGroups{ | ||
| Schemas: []string{SCIMSchemasURINamespacesListResponse}, | ||
| TotalResults: Ptr(1), | ||
| ItemsPerPage: Ptr(1), | ||
| StartIndex: Ptr(1), | ||
| Resources: []*SCIMEnterpriseGroupAttributes{{ | ||
| DisplayName: Ptr("gn1"), | ||
| Members: []*SCIMEnterpriseDisplayReference{{ | ||
| Value: "idm1", | ||
| Ref: "https://api.github.com/scim/v2/enterprises/ee/Users/idm1", | ||
| Display: Ptr("m1"), | ||
| }}, | ||
| Schemas: []string{SCIMSchemasURINamespacesGroups}, | ||
| ExternalID: Ptr("eidgn1"), | ||
| ID: Ptr("idgn1"), | ||
| Meta: &SCIMEnterpriseMeta{ | ||
| ResourceType: "Group", | ||
| Created: &Timestamp{referenceTime}, | ||
| LastModified: &Timestamp{referenceTime}, | ||
| Location: Ptr("https://api.github.com/scim/v2/enterprises/ee/Groups/idgn1"), | ||
| }, | ||
| }}, | ||
| } | ||
|
|
||
| want := `{ | ||
| "schemas": ["` + SCIMSchemasURINamespacesListResponse + `"], | ||
| "totalResults": 1, | ||
| "itemsPerPage": 1, | ||
| "startIndex": 1, | ||
| "Resources": [{ | ||
| "schemas": ["` + SCIMSchemasURINamespacesGroups + `"], | ||
| "id": "idgn1", | ||
| "externalId": "eidgn1", | ||
| "displayName": "gn1", | ||
| "meta": { | ||
| "resourceType": "Group", | ||
| "created": ` + referenceTimeStr + `, | ||
| "lastModified": ` + referenceTimeStr + `, | ||
| "location": "https://api.github.com/scim/v2/enterprises/ee/Groups/idgn1" | ||
| }, | ||
| "members": [{ | ||
| "value": "idm1", | ||
| "$ref": "https://api.github.com/scim/v2/enterprises/ee/Users/idm1", | ||
| "display": "m1" | ||
| }] | ||
| }] | ||
| }` | ||
|
|
||
| testJSONMarshal(t, u, want) | ||
| } | ||
|
|
||
| func TestSCIMEnterpriseGroupAttributes_Marshal(t *testing.T) { | ||
| t.Parallel() | ||
| testJSONMarshal(t, &SCIMEnterpriseGroupAttributes{}, "{}") | ||
|
|
||
| u := &SCIMEnterpriseGroupAttributes{ | ||
| DisplayName: Ptr("dn"), | ||
| Members: []*SCIMEnterpriseDisplayReference{{ | ||
| Value: "v", | ||
| Ref: "r", | ||
| Display: Ptr("d"), | ||
| }}, | ||
| ExternalID: Ptr("eid"), | ||
| ID: Ptr("id"), | ||
| Schemas: []string{"s1"}, | ||
| Meta: &SCIMEnterpriseMeta{ | ||
| ResourceType: "rt", | ||
| Created: &Timestamp{referenceTime}, | ||
| LastModified: &Timestamp{referenceTime}, | ||
| Location: Ptr("l"), | ||
| }, | ||
| } | ||
|
|
||
| want := `{ | ||
| "schemas": ["s1"], | ||
| "externalId": "eid", | ||
| "displayName": "dn", | ||
| "members" : [{ | ||
| "value": "v", | ||
| "$ref": "r", | ||
| "display": "d" | ||
| }], | ||
| "id": "id", | ||
| "meta": { | ||
| "resourceType": "rt", | ||
| "created": ` + referenceTimeStr + `, | ||
| "lastModified": ` + referenceTimeStr + `, | ||
| "location": "l" | ||
| } | ||
| }` | ||
|
|
||
| testJSONMarshal(t, u, want) | ||
| } | ||
|
|
||
| func TestEnterpriseService_ListProvisionedSCIMEnterpriseGroups(t *testing.T) { | ||
| t.Parallel() | ||
| client, mux, _ := setup(t) | ||
|
|
||
| mux.HandleFunc("/scim/v2/enterprises/ee/Groups", func(w http.ResponseWriter, r *http.Request) { | ||
| testMethod(t, r, "GET") | ||
| testFormValues(t, r, values{ | ||
| "startIndex": "1", | ||
| "excludedAttributes": "members,meta", | ||
| "count": "3", | ||
| "filter": `externalId eq "914a"`, | ||
| }) | ||
| w.WriteHeader(http.StatusOK) | ||
| _, _ = w.Write([]byte(`{ | ||
| "schemas": ["` + SCIMSchemasURINamespacesListResponse + `"], | ||
| "totalResults": 1, | ||
| "itemsPerPage": 1, | ||
| "startIndex": 1, | ||
| "Resources": [{ | ||
| "schemas": ["` + SCIMSchemasURINamespacesGroups + `"], | ||
| "id": "914a", | ||
| "externalId": "de88", | ||
| "displayName": "gn1", | ||
| "meta": { | ||
| "resourceType": "Group", | ||
| "created": ` + referenceTimeStr + `, | ||
| "lastModified": ` + referenceTimeStr + `, | ||
| "location": "https://api.github.com/scim/v2/enterprises/ee/Groups/914a" | ||
| }, | ||
| "members": [{ | ||
| "value": "e7f9", | ||
| "$ref": "https://api.github.com/scim/v2/enterprises/ee/Users/e7f9", | ||
| "display": "d1" | ||
| }] | ||
| }] | ||
| }`)) | ||
| }) | ||
|
|
||
| ctx := t.Context() | ||
| opts := &ListProvisionedSCIMEnterpriseGroupsOptions{ | ||
| StartIndex: Ptr(1), | ||
| ExcludedAttributes: Ptr("members,meta"), | ||
| Count: Ptr(3), | ||
| Filter: Ptr(`externalId eq "914a"`), | ||
| } | ||
| groups, _, err := client.Enterprise.ListProvisionedSCIMEnterpriseGroups(ctx, "ee", opts) | ||
| if err != nil { | ||
| t.Errorf("Enterprise.ListProvisionedSCIMEnterpriseGroups returned error: %v", err) | ||
| } | ||
|
|
||
| want := SCIMEnterpriseGroups{ | ||
| Schemas: []string{SCIMSchemasURINamespacesListResponse}, | ||
| TotalResults: Ptr(1), | ||
| ItemsPerPage: Ptr(1), | ||
| StartIndex: Ptr(1), | ||
| Resources: []*SCIMEnterpriseGroupAttributes{{ | ||
| ID: Ptr("914a"), | ||
| Meta: &SCIMEnterpriseMeta{ | ||
| ResourceType: "Group", | ||
| Created: &Timestamp{referenceTime}, | ||
| LastModified: &Timestamp{referenceTime}, | ||
| Location: Ptr("https://api.github.com/scim/v2/enterprises/ee/Groups/914a"), | ||
| }, | ||
| DisplayName: Ptr("gn1"), | ||
| Schemas: []string{SCIMSchemasURINamespacesGroups}, | ||
| ExternalID: Ptr("de88"), | ||
| Members: []*SCIMEnterpriseDisplayReference{{ | ||
| Value: "e7f9", | ||
| Ref: "https://api.github.com/scim/v2/enterprises/ee/Users/e7f9", | ||
| Display: Ptr("d1"), | ||
| }}, | ||
| }}, | ||
| } | ||
|
|
||
| if diff := cmp.Diff(want, *groups); diff != "" { | ||
| t.Errorf("Enterprise.ListProvisionedSCIMEnterpriseGroups diff mismatch (-want +got):\n%v", diff) | ||
| } | ||
|
|
||
| const methodName = "ListProvisionedSCIMEnterpriseGroups" | ||
| testBadOptions(t, methodName, func() (err error) { | ||
| _, _, err = client.Enterprise.ListProvisionedSCIMEnterpriseGroups(ctx, "\n", opts) | ||
| return err | ||
| }) | ||
|
|
||
| testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) { | ||
| _, r, err := client.Enterprise.ListProvisionedSCIMEnterpriseGroups(ctx, "o", opts) | ||
| return r, err | ||
| }) | ||
| } |
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.