diff --git a/github/enterprise_scim.go b/github/enterprise_scim.go index bf8e6429365..ea45b2e5c86 100644 --- a/github/enterprise_scim.go +++ b/github/enterprise_scim.go @@ -70,7 +70,7 @@ type ListProvisionedSCIMGroupsEnterpriseOptions struct { // If specified, only results that match the specified filter will be returned. // Possible filters are `externalId`, `id`, and `displayName`. For example, `externalId eq "a123"`. Filter *string `url:"filter,omitempty"` - // Excludes the specified attribute from being returned in the results. + // Excludes the specified attributes from being returned in the results. ExcludedAttributes *string `url:"excludedAttributes,omitempty"` // Used for pagination: the starting index of the first result to return when paginating through values. // Default: 1. @@ -80,6 +80,14 @@ type ListProvisionedSCIMGroupsEnterpriseOptions struct { Count *int `url:"count,omitempty"` } +// GetProvisionedSCIMGroupEnterpriseOptions represents query parameters for GetProvisionedSCIMGroup. +// +// GitHub API docs: https://docs.github.com/enterprise-cloud@latest/rest/enterprise-admin/scim#get-scim-provisioning-information-for-an-enterprise-group +type GetProvisionedSCIMGroupEnterpriseOptions struct { + // Excludes the specified attributes from being returned in the results. + ExcludedAttributes *string `url:"excludedAttributes,omitempty"` +} + // SCIMEnterpriseUserAttributes represents supported SCIM enterprise user attributes, and represents the result of calling UpdateSCIMUserAttribute. // // GitHub API docs: https://docs.github.com/enterprise-cloud@latest/rest/enterprise-admin/scim#supported-scim-user-attributes @@ -162,8 +170,9 @@ type SCIMEnterpriseAttributeOperation struct { // ListProvisionedSCIMGroups lists provisioned SCIM groups in an enterprise. // -// You can improve query search time by using the `excludedAttributes` query -// parameter with a value of `members` to exclude members from the response. +// You can improve query search time by using the `excludedAttributes` and +// exclude the specified attributes, e.g. `members` to exclude members from the +// response. // // GitHub API docs: https://docs.github.com/enterprise-cloud@latest/rest/enterprise-admin/scim#list-provisioned-scim-groups-for-an-enterprise // @@ -381,6 +390,60 @@ func (s *EnterpriseService) ProvisionSCIMUser(ctx context.Context, enterprise st return userProvisioned, resp, nil } +// GetProvisionedSCIMGroup gets information about a SCIM group. +// +// You can use the `excludedAttributes` from `opts` and exclude the specified +// attributes from being returned in the results. Using this parameter can +// speed up response time. +// +// GitHub API docs: https://docs.github.com/enterprise-cloud@latest/rest/enterprise-admin/scim#get-scim-provisioning-information-for-an-enterprise-group +// +//meta:operation GET /scim/v2/enterprises/{enterprise}/Groups/{scim_group_id} +func (s *EnterpriseService) GetProvisionedSCIMGroup(ctx context.Context, enterprise, scimGroupID string, opts *GetProvisionedSCIMGroupEnterpriseOptions) (*SCIMEnterpriseGroupAttributes, *Response, error) { + u := fmt.Sprintf("scim/v2/enterprises/%v/Groups/%v", enterprise, scimGroupID) + 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 + } + req.Header.Set("Accept", mediaTypeSCIM) + + group := new(SCIMEnterpriseGroupAttributes) + resp, err := s.client.Do(ctx, req, group) + if err != nil { + return nil, resp, err + } + + return group, resp, nil +} + +// GetProvisionedSCIMUser gets information about a SCIM user. +// +// GitHub API docs: https://docs.github.com/enterprise-cloud@latest/rest/enterprise-admin/scim#get-scim-provisioning-information-for-an-enterprise-user +// +//meta:operation GET /scim/v2/enterprises/{enterprise}/Users/{scim_user_id} +func (s *EnterpriseService) GetProvisionedSCIMUser(ctx context.Context, enterprise, scimUserID string) (*SCIMEnterpriseUserAttributes, *Response, error) { + u := fmt.Sprintf("scim/v2/enterprises/%v/Users/%v", enterprise, scimUserID) + + req, err := s.client.NewRequest("GET", u, nil) + if err != nil { + return nil, nil, err + } + req.Header.Set("Accept", mediaTypeSCIM) + + user := new(SCIMEnterpriseUserAttributes) + resp, err := s.client.Do(ctx, req, user) + if err != nil { + return nil, resp, err + } + + return user, resp, nil +} + // DeleteSCIMGroup deletes a SCIM group from an enterprise. // // GitHub API docs: https://docs.github.com/enterprise-cloud@latest/rest/enterprise-admin/scim#delete-a-scim-group-from-an-enterprise diff --git a/github/enterprise_scim_test.go b/github/enterprise_scim_test.go index a0f984f818f..edfbd64724d 100644 --- a/github/enterprise_scim_test.go +++ b/github/enterprise_scim_test.go @@ -182,6 +182,15 @@ func TestListProvisionedSCIMGroupsEnterpriseOptions_Marshal(t *testing.T) { testJSONMarshal(t, u, want) } +func TestGetProvisionedSCIMGroupEnterpriseOptions_Marshal(t *testing.T) { + t.Parallel() + testJSONMarshal(t, &GetProvisionedSCIMGroupEnterpriseOptions{}, "{}") + + u := &GetProvisionedSCIMGroupEnterpriseOptions{ExcludedAttributes: Ptr("ea")} + want := `{"excludedAttributes": "ea"}` + testJSONMarshal(t, u, want) +} + func TestListProvisionedSCIMUsersEnterpriseOptions_Marshal(t *testing.T) { t.Parallel() testJSONMarshal(t, &ListProvisionedSCIMUsersEnterpriseOptions{}, "{}") @@ -1014,6 +1023,162 @@ func TestEnterpriseService_ProvisionSCIMUser(t *testing.T) { }) } +func TestEnterpriseService_GetProvisionedSCIMGroup(t *testing.T) { + t.Parallel() + client, mux, _ := setup(t) + + mux.HandleFunc("/scim/v2/enterprises/ee/Groups/914a", func(w http.ResponseWriter, r *http.Request) { + testMethod(t, r, "GET") + testHeader(t, r, "Accept", mediaTypeSCIM) + testFormValues(t, r, values{"excludedAttributes": "members,meta"}) + w.WriteHeader(http.StatusOK) + fmt.Fprint(w, `{ + "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 := &GetProvisionedSCIMGroupEnterpriseOptions{ExcludedAttributes: Ptr("members,meta")} + got, _, err := client.Enterprise.GetProvisionedSCIMGroup(ctx, "ee", "914a", opts) + if err != nil { + t.Fatalf("Enterprise.GetProvisionedSCIMGroup returned unexpected error: %v", err) + } + + want := &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: Ptr("https://api.github.com/scim/v2/enterprises/ee/Users/e7f9"), + Display: Ptr("d1"), + }}, + } + + if diff := cmp.Diff(want, got); diff != "" { + t.Fatalf("Enterprise.GetProvisionedSCIMGroup diff mismatch (-want +got):\n%v", diff) + } + + const methodName = "GetProvisionedSCIMGroup" + testBadOptions(t, methodName, func() (err error) { + _, _, err = client.Enterprise.GetProvisionedSCIMGroup(ctx, "ee", "\n", opts) + return err + }) + + testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) { + got, resp, err := client.Enterprise.GetProvisionedSCIMGroup(ctx, "ee", "914a", opts) + if got != nil { + t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got) + } + return resp, err + }) +} + +func TestEnterpriseService_GetProvisionedSCIMUser(t *testing.T) { + t.Parallel() + client, mux, _ := setup(t) + + mux.HandleFunc("/scim/v2/enterprises/ee/Users/5fc0", func(w http.ResponseWriter, r *http.Request) { + testMethod(t, r, "GET") + testHeader(t, r, "Accept", mediaTypeSCIM) + w.WriteHeader(http.StatusOK) + fmt.Fprint(w, `{ + "schemas": ["`+SCIMSchemasURINamespacesUser+`"], + "id": "5fc0", + "externalId": "00u1", + "userName": "octocat@github.com", + "displayName": "Mona Octocat", + "name": { + "givenName": "Mona", + "familyName": "Octocat", + "formatted": "Mona Octocat" + }, + "emails": [ + { + "value": "octocat@github.com", + "primary": true + } + ], + "active": true, + "meta": { + "resourceType": "User", + "created": `+referenceTimeStr+`, + "lastModified": `+referenceTimeStr+`, + "location": "https://api.github.com/scim/v2/enterprises/ee/Users/5fc0" + } + }`) + }) + + ctx := t.Context() + got, _, err := client.Enterprise.GetProvisionedSCIMUser(ctx, "ee", "5fc0") + if err != nil { + t.Fatalf("Enterprise.GetProvisionedSCIMUser returned unexpected error: %v", err) + } + + want := &SCIMEnterpriseUserAttributes{ + Schemas: []string{SCIMSchemasURINamespacesUser}, + ID: Ptr("5fc0"), + ExternalID: "00u1", + UserName: "octocat@github.com", + DisplayName: "Mona Octocat", + Name: &SCIMEnterpriseUserName{ + GivenName: "Mona", + FamilyName: "Octocat", + Formatted: Ptr("Mona Octocat"), + }, + Emails: []*SCIMEnterpriseUserEmail{{ + Value: "octocat@github.com", + Primary: true, + }}, + Active: true, + Meta: &SCIMEnterpriseMeta{ + ResourceType: "User", + Created: &Timestamp{referenceTime}, + LastModified: &Timestamp{referenceTime}, + Location: Ptr("https://api.github.com/scim/v2/enterprises/ee/Users/5fc0"), + }, + } + + if diff := cmp.Diff(want, got); diff != "" { + t.Fatalf("Enterprise.GetProvisionedSCIMUser diff mismatch (-want +got):\n%v", diff) + } + + const methodName = "GetProvisionedSCIMUser" + testBadOptions(t, methodName, func() (err error) { + _, _, err = client.Enterprise.GetProvisionedSCIMUser(ctx, "\n", "\n") + return err + }) + + testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) { + got, resp, err := client.Enterprise.GetProvisionedSCIMUser(ctx, "ee", "5fc0") + if got != nil { + t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got) + } + return resp, err + }) +} + func TestEnterpriseService_DeleteSCIMGroup(t *testing.T) { t.Parallel() client, mux, _ := setup(t) diff --git a/github/github-accessors.go b/github/github-accessors.go index 6b7ec07c7e9..417def5e7a6 100644 --- a/github/github-accessors.go +++ b/github/github-accessors.go @@ -10006,6 +10006,14 @@ func (g *GetAuditLogOptions) GetPhrase() string { return *g.Phrase } +// GetExcludedAttributes returns the ExcludedAttributes field if it's non-nil, zero value otherwise. +func (g *GetProvisionedSCIMGroupEnterpriseOptions) GetExcludedAttributes() string { + if g == nil || g.ExcludedAttributes == nil { + return "" + } + return *g.ExcludedAttributes +} + // GetComments returns the Comments field if it's non-nil, zero value otherwise. func (g *Gist) GetComments() int { if g == nil || g.Comments == nil { diff --git a/github/github-accessors_test.go b/github/github-accessors_test.go index 766bc5f2593..27ccf844711 100644 --- a/github/github-accessors_test.go +++ b/github/github-accessors_test.go @@ -12968,6 +12968,17 @@ func TestGetAuditLogOptions_GetPhrase(tt *testing.T) { g.GetPhrase() } +func TestGetProvisionedSCIMGroupEnterpriseOptions_GetExcludedAttributes(tt *testing.T) { + tt.Parallel() + var zeroValue string + g := &GetProvisionedSCIMGroupEnterpriseOptions{ExcludedAttributes: &zeroValue} + g.GetExcludedAttributes() + g = &GetProvisionedSCIMGroupEnterpriseOptions{} + g.GetExcludedAttributes() + g = nil + g.GetExcludedAttributes() +} + func TestGist_GetComments(tt *testing.T) { tt.Parallel() var zeroValue int