Skip to content

Commit e716505

Browse files
feat: Implement Enterprise SCIM - Delete Groups or Users (#3856)
1 parent 06ab3a2 commit e716505

2 files changed

Lines changed: 115 additions & 0 deletions

File tree

github/enterprise_scim.go

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -162,6 +162,9 @@ type SCIMEnterpriseAttributeOperation struct {
162162

163163
// ListProvisionedSCIMGroups lists provisioned SCIM groups in an enterprise.
164164
//
165+
// You can improve query search time by using the `excludedAttributes` query
166+
// parameter with a value of `members` to exclude members from the response.
167+
//
165168
// GitHub API docs: https://docs.github.com/enterprise-cloud@latest/rest/enterprise-admin/scim#list-provisioned-scim-groups-for-an-enterprise
166169
//
167170
//meta:operation GET /scim/v2/enterprises/{enterprise}/Groups
@@ -189,6 +192,10 @@ func (s *EnterpriseService) ListProvisionedSCIMGroups(ctx context.Context, enter
189192

190193
// ListProvisionedSCIMUsers lists provisioned SCIM enterprise users.
191194
//
195+
// When members are part of the group provisioning payload, they're designated
196+
// as external group members. Providers are responsible for maintaining a
197+
// mapping between the `externalId` and `id` for each user.
198+
//
192199
// GitHub API docs: https://docs.github.com/enterprise-cloud@latest/rest/enterprise-admin/scim#list-scim-provisioned-identities-for-an-enterprise
193200
//
194201
//meta:operation GET /scim/v2/enterprises/{enterprise}/Users
@@ -270,6 +277,14 @@ func (s *EnterpriseService) SetProvisionedSCIMUser(ctx context.Context, enterpri
270277

271278
// UpdateSCIMGroupAttribute updates a provisioned group’s individual attributes.
272279
//
280+
// The `attribute` parameter must include at least one of the following
281+
// Operations: `add`, `remove`, or `replace`.
282+
//
283+
// The update function can also be used to add group memberships.
284+
//
285+
// You can submit group memberships individually or in batches for improved
286+
// efficiency.
287+
//
273288
// GitHub API docs: https://docs.github.com/enterprise-cloud@latest/rest/enterprise-admin/scim#update-an-attribute-for-a-scim-enterprise-group
274289
//
275290
//meta:operation PATCH /scim/v2/enterprises/{enterprise}/Groups/{scim_group_id}
@@ -292,6 +307,16 @@ func (s *EnterpriseService) UpdateSCIMGroupAttribute(ctx context.Context, enterp
292307

293308
// UpdateSCIMUserAttribute updates a provisioned user's individual attributes.
294309
//
310+
// The `attribute` parameter must include at least one of the following
311+
// Operations: `add`, `remove`, or `replace`.
312+
//
313+
// Note: Complex SCIM path selectors that include filters are not supported.
314+
// For example, a path selector defined as `"path": "emails[type eq \"work\"]"`
315+
// will be ineffective.
316+
//
317+
// Warning: Setting `active: false` will suspend a user, and their handle and
318+
// email will be obfuscated.
319+
//
295320
// GitHub API docs: https://docs.github.com/enterprise-cloud@latest/rest/enterprise-admin/scim#update-an-attribute-for-a-scim-enterprise-user
296321
//
297322
//meta:operation PATCH /scim/v2/enterprises/{enterprise}/Users/{scim_user_id}
@@ -311,3 +336,39 @@ func (s *EnterpriseService) UpdateSCIMUserAttribute(ctx context.Context, enterpr
311336

312337
return user, resp, nil
313338
}
339+
340+
// DeleteSCIMGroup deletes a SCIM group from an enterprise.
341+
//
342+
// GitHub API docs: https://docs.github.com/enterprise-cloud@latest/rest/enterprise-admin/scim#delete-a-scim-group-from-an-enterprise
343+
//
344+
//meta:operation DELETE /scim/v2/enterprises/{enterprise}/Groups/{scim_group_id}
345+
func (s *EnterpriseService) DeleteSCIMGroup(ctx context.Context, enterprise, scimGroupID string) (*Response, error) {
346+
u := fmt.Sprintf("scim/v2/enterprises/%v/Groups/%v", enterprise, scimGroupID)
347+
req, err := s.client.NewRequest("DELETE", u, nil)
348+
if err != nil {
349+
return nil, err
350+
}
351+
352+
return s.client.Do(ctx, req, nil)
353+
}
354+
355+
// DeleteSCIMUser deletes a SCIM user from an enterprise.
356+
//
357+
// Suspends a SCIM user permanently from an enterprise. This action will:
358+
// remove all the user's data, anonymize their login, email, and display name,
359+
// erase all external identity SCIM attributes, delete the user's emails,
360+
// avatar, PATs, SSH keys, OAuth authorizations, GPG keys, and SAML mappings.
361+
// This action is irreversible.
362+
//
363+
// GitHub API docs: https://docs.github.com/enterprise-cloud@latest/rest/enterprise-admin/scim#delete-a-scim-user-from-an-enterprise
364+
//
365+
//meta:operation DELETE /scim/v2/enterprises/{enterprise}/Users/{scim_user_id}
366+
func (s *EnterpriseService) DeleteSCIMUser(ctx context.Context, enterprise, scimUserID string) (*Response, error) {
367+
u := fmt.Sprintf("scim/v2/enterprises/%v/Users/%v", enterprise, scimUserID)
368+
req, err := s.client.NewRequest("DELETE", u, nil)
369+
if err != nil {
370+
return nil, err
371+
}
372+
373+
return s.client.Do(ctx, req, nil)
374+
}

github/enterprise_scim_test.go

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -809,3 +809,57 @@ func TestEnterpriseService_UpdateSCIMUserAttribute(t *testing.T) {
809809
return resp, err
810810
})
811811
}
812+
813+
func TestEnterpriseService_DeleteSCIMGroup(t *testing.T) {
814+
t.Parallel()
815+
client, mux, _ := setup(t)
816+
817+
mux.HandleFunc("/scim/v2/enterprises/ee/Groups/abcd", func(w http.ResponseWriter, r *http.Request) {
818+
testMethod(t, r, "DELETE")
819+
testHeader(t, r, "Accept", mediaTypeV3)
820+
w.WriteHeader(http.StatusNoContent)
821+
})
822+
823+
ctx := t.Context()
824+
_, err := client.Enterprise.DeleteSCIMGroup(ctx, "ee", "abcd")
825+
if err != nil {
826+
t.Fatalf("Enterprise.DeleteSCIMGroup returned unexpected error: %v", err)
827+
}
828+
829+
const methodName = "DeleteSCIMGroup"
830+
testBadOptions(t, methodName, func() (err error) {
831+
_, err = client.Enterprise.DeleteSCIMGroup(ctx, "\n", "\n")
832+
return err
833+
})
834+
835+
testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) {
836+
return client.Enterprise.DeleteSCIMGroup(ctx, "ee", "abcd")
837+
})
838+
}
839+
840+
func TestEnterpriseService_DeleteSCIMUser(t *testing.T) {
841+
t.Parallel()
842+
client, mux, _ := setup(t)
843+
844+
mux.HandleFunc("/scim/v2/enterprises/ee/Users/7fce", func(w http.ResponseWriter, r *http.Request) {
845+
testMethod(t, r, "DELETE")
846+
testHeader(t, r, "Accept", mediaTypeV3)
847+
w.WriteHeader(http.StatusNoContent)
848+
})
849+
850+
ctx := t.Context()
851+
_, err := client.Enterprise.DeleteSCIMUser(ctx, "ee", "7fce")
852+
if err != nil {
853+
t.Fatalf("Enterprise.DeleteSCIMUser returned unexpected error: %v", err)
854+
}
855+
856+
const methodName = "DeleteSCIMUser"
857+
testBadOptions(t, methodName, func() (err error) {
858+
_, err = client.Enterprise.DeleteSCIMUser(ctx, "\n", "\n")
859+
return err
860+
})
861+
862+
testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) {
863+
return client.Enterprise.DeleteSCIMUser(ctx, "ee", "7fce")
864+
})
865+
}

0 commit comments

Comments
 (0)