diff --git a/github/enterprise_scim.go b/github/enterprise_scim.go index 3243841a88c..8407857c11d 100644 --- a/github/enterprise_scim.go +++ b/github/enterprise_scim.go @@ -214,6 +214,60 @@ func (s *EnterpriseService) ListProvisionedSCIMUsers(ctx context.Context, enterp return users, resp, nil } +// SetProvisionedSCIMGroup replaces an existing provisioned group’s information. +// +// You must provide all the information required for the group as if you were provisioning it for the first time. Any +// existing group information that you don't provide will be removed, including group membership. To update only +// specific attributes, refer to the `Enterprise.UpdateSCIMGroupAttribute()` method. +// +// GitHub API docs: https://docs.github.com/enterprise-cloud@latest/rest/enterprise-admin/scim#set-scim-information-for-a-provisioned-enterprise-group +// +//meta:operation PUT /scim/v2/enterprises/{enterprise}/Groups/{scim_group_id} +func (s *EnterpriseService) SetProvisionedSCIMGroup(ctx context.Context, enterprise, scimGroupID string, group SCIMEnterpriseGroupAttributes) (*SCIMEnterpriseGroupAttributes, *Response, error) { + u := fmt.Sprintf("scim/v2/enterprises/%v/Groups/%v", enterprise, scimGroupID) + req, err := s.client.NewRequest("PUT", u, group) + if err != nil { + return nil, nil, err + } + req.Header.Set("Accept", mediaTypeSCIM) + + groupNew := new(SCIMEnterpriseGroupAttributes) + resp, err := s.client.Do(ctx, req, groupNew) + if err != nil { + return nil, resp, err + } + + return groupNew, resp, nil +} + +// SetProvisionedSCIMUser replaces an existing provisioned user's information. +// +// You must supply complete user information, just as you would when provisioning them initially. Any previously +// existing data not provided will be deleted. To update specific attributes only, refer to the +// `Enterprise.UpdateSCIMUserAttribute()` method. +// +// **Warning**: Setting `active: false` will suspend a user, and their handle and email will be obfuscated. +// +// GitHub API docs: https://docs.github.com/enterprise-cloud@latest/rest/enterprise-admin/scim#set-scim-information-for-a-provisioned-enterprise-user +// +//meta:operation PUT /scim/v2/enterprises/{enterprise}/Users/{scim_user_id} +func (s *EnterpriseService) SetProvisionedSCIMUser(ctx context.Context, enterprise, scimUserID string, user SCIMEnterpriseUserAttributes) (*SCIMEnterpriseUserAttributes, *Response, error) { + u := fmt.Sprintf("scim/v2/enterprises/%v/Users/%v", enterprise, scimUserID) + req, err := s.client.NewRequest("PUT", u, user) + if err != nil { + return nil, nil, err + } + req.Header.Set("Accept", mediaTypeSCIM) + + userNew := new(SCIMEnterpriseUserAttributes) + resp, err := s.client.Do(ctx, req, userNew) + if err != nil { + return nil, resp, err + } + + return userNew, resp, nil +} + // UpdateSCIMGroupAttribute updates a provisioned group’s individual attributes. // // GitHub API docs: https://docs.github.com/enterprise-cloud@latest/rest/enterprise-admin/scim#update-an-attribute-for-a-scim-enterprise-group diff --git a/github/enterprise_scim_test.go b/github/enterprise_scim_test.go index 4f65c27ff71..51bb80eb64e 100644 --- a/github/enterprise_scim_test.go +++ b/github/enterprise_scim_test.go @@ -479,6 +479,155 @@ func TestEnterpriseService_ListProvisionedSCIMUsers(t *testing.T) { }) } +func TestEnterpriseService_SetProvisionedSCIMGroup(t *testing.T) { + t.Parallel() + client, mux, _ := setup(t) + + mux.HandleFunc("/scim/v2/enterprises/ee/Groups/abcd", func(w http.ResponseWriter, r *http.Request) { + testMethod(t, r, "PUT") + testHeader(t, r, "Accept", mediaTypeSCIM) + testBody(t, r, `{"displayName":"dn","externalId":"8aa1","schemas":["`+SCIMSchemasURINamespacesGroups+`"]}`+"\n") + w.WriteHeader(http.StatusOK) + fmt.Fprint(w, `{ + "schemas": ["`+SCIMSchemasURINamespacesGroups+`"], + "id": "abcd", + "externalId": "8aa1", + "displayName": "dn", + "meta": { + "resourceType": "Group", + "created": `+referenceTimeStr+`, + "lastModified": `+referenceTimeStr+`, + "location": "https://api.github.localhost/scim/v2/enterprises/ee/Groups/abcd" + } + }`) + }) + want := &SCIMEnterpriseGroupAttributes{ + Schemas: []string{SCIMSchemasURINamespacesGroups}, + ID: Ptr("abcd"), + ExternalID: Ptr("8aa1"), + DisplayName: Ptr("dn"), + Meta: &SCIMEnterpriseMeta{ + ResourceType: "Group", + Created: &Timestamp{referenceTime}, + LastModified: &Timestamp{referenceTime}, + Location: Ptr("https://api.github.localhost/scim/v2/enterprises/ee/Groups/abcd"), + }, + } + + ctx := t.Context() + input := SCIMEnterpriseGroupAttributes{ + Schemas: []string{SCIMSchemasURINamespacesGroups}, + ExternalID: Ptr("8aa1"), + DisplayName: Ptr("dn"), + } + got, _, err := client.Enterprise.SetProvisionedSCIMGroup(ctx, "ee", "abcd", input) + if err != nil { + t.Fatalf("Enterprise.SetProvisionedSCIMGroup returned unexpected error: %v", err) + } + if diff := cmp.Diff(want, got); diff != "" { + t.Fatalf("Enterprise.SetProvisionedSCIMGroup diff mismatch (-want +got):\n%v", diff) + } + + const methodName = "SetProvisionedSCIMGroup" + testBadOptions(t, methodName, func() (err error) { + _, _, err = client.Enterprise.SetProvisionedSCIMGroup(ctx, "\n", "\n", SCIMEnterpriseGroupAttributes{}) + return err + }) + + testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) { + got, resp, err := client.Enterprise.SetProvisionedSCIMGroup(ctx, "ee", "abcd", input) + if got != nil { + t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got) + } + return resp, err + }) +} + +func TestEnterpriseService_SetProvisionedSCIMUser(t *testing.T) { + t.Parallel() + client, mux, _ := setup(t) + + mux.HandleFunc("/scim/v2/enterprises/ee/Users/7fce", func(w http.ResponseWriter, r *http.Request) { + testMethod(t, r, "PUT") + testHeader(t, r, "Accept", mediaTypeSCIM) + testBody(t, r, `{"displayName":"John Doe","userName":"e123","emails":[{"value":"john@email.com","primary":true,"type":"work"}],"externalId":"e123","active":true,"schemas":["`+SCIMSchemasURINamespacesUser+`"]}`+"\n") + w.WriteHeader(http.StatusOK) + fmt.Fprint(w, `{ + "schemas": ["`+SCIMSchemasURINamespacesUser+`"], + "id": "7fce", + "externalId": "e123", + "active": true, + "userName": "e123", + "displayName": "John Doe", + "emails": [{ + "value": "john@email.com", + "type": "work", + "primary": true + }], + "meta": { + "resourceType": "User", + "created": `+referenceTimeStr+`, + "lastModified": `+referenceTimeStr+`, + "location": "https://api.github.localhost/scim/v2/enterprises/ee/Users/7fce" + } + }`) + }) + want := &SCIMEnterpriseUserAttributes{ + Schemas: []string{SCIMSchemasURINamespacesUser}, + ID: Ptr("7fce"), + ExternalID: "e123", + Active: true, + UserName: "e123", + DisplayName: "John Doe", + Emails: []*SCIMEnterpriseUserEmail{{ + Value: "john@email.com", + Type: "work", + Primary: true, + }}, + Meta: &SCIMEnterpriseMeta{ + ResourceType: "User", + Created: &Timestamp{referenceTime}, + LastModified: &Timestamp{referenceTime}, + Location: Ptr("https://api.github.localhost/scim/v2/enterprises/ee/Users/7fce"), + }, + } + + ctx := t.Context() + input := SCIMEnterpriseUserAttributes{ + Schemas: []string{SCIMSchemasURINamespacesUser}, + ExternalID: "e123", + Active: true, + UserName: "e123", + DisplayName: "John Doe", + Emails: []*SCIMEnterpriseUserEmail{{ + Value: "john@email.com", + Type: "work", + Primary: true, + }}, + } + got, _, err := client.Enterprise.SetProvisionedSCIMUser(ctx, "ee", "7fce", input) + if err != nil { + t.Fatalf("Enterprise.SetProvisionedSCIMUser returned unexpected error: %v", err) + } + if diff := cmp.Diff(want, got); diff != "" { + t.Fatalf("Enterprise.SetProvisionedSCIMUser diff mismatch (-want +got):\n%v", diff) + } + + const methodName = "SetProvisionedSCIMUser" + testBadOptions(t, methodName, func() (err error) { + _, _, err = client.Enterprise.SetProvisionedSCIMUser(ctx, "\n", "\n", SCIMEnterpriseUserAttributes{}) + return err + }) + + testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) { + got, resp, err := client.Enterprise.SetProvisionedSCIMUser(ctx, "ee", "7fce", input) + if got != nil { + t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got) + } + return resp, err + }) +} + func TestEnterpriseService_UpdateSCIMGroupAttribute(t *testing.T) { t.Parallel() client, mux, _ := setup(t)