From f20a77ca5e2b16a23f4f58f468991106e74cc88e Mon Sep 17 00:00:00 2001 From: Krishna Indani Date: Sun, 22 Aug 2021 14:02:41 -0700 Subject: [PATCH 1/9] scim initial commit --- github/github.go | 2 + github/scim.go | 131 ++++++++++++++++++++++++++++++++++++++++++++ github/scim_test.go | 32 +++++++++++ 3 files changed, 165 insertions(+) create mode 100644 github/scim.go create mode 100644 github/scim_test.go diff --git a/github/github.go b/github/github.go index 56b63d17a24..c1c8ad4782a 100644 --- a/github/github.go +++ b/github/github.go @@ -182,6 +182,7 @@ type Client struct { Reactions *ReactionsService Repositories *RepositoriesService Search *SearchService + SCIM *SCIMService Teams *TeamsService Users *UsersService } @@ -309,6 +310,7 @@ func NewClient(httpClient *http.Client) *Client { c.Reactions = (*ReactionsService)(&c.common) c.Repositories = (*RepositoriesService)(&c.common) c.Search = (*SearchService)(&c.common) + c.SCIM = (*SCIMService)(&c.common) c.Teams = (*TeamsService)(&c.common) c.Users = (*UsersService)(&c.common) return c diff --git a/github/scim.go b/github/scim.go new file mode 100644 index 00000000000..d49c709f2b4 --- /dev/null +++ b/github/scim.go @@ -0,0 +1,131 @@ +package github + +import ( + "context" + "fmt" +) + +// SCIMService provides access to SCIM related functions in the +// GitHub API. +// +// GitHub API docs: https://docs.github.com/en/rest/reference/scim +type SCIMService service + +type SCIMUserAttributes struct { + UserName string `json:"user_name"` // Configured by the admin. Could be an email, login, or username. (Required.) + Name SCIMUserName `json:"name"` // (Required.) + DisplayName *string `json:"display_name,omitempty"` // The name of the user, suitable for display to end-users. (Optional.) + Emails []*SCIMUserEmails `json:"email"` // User emails. (Required.) + Schemas []*string `json:"schemas,omitempty"` // (Optional.) + ExternalID *string `json:"external_id,omitempty"` // (Optional.) + Groups []*string `json:"groups,omitempty"` // (Optional.) + Active bool `json:"active,omitempty"` // (Optional.) +} + +type SCIMUserName struct { + GivenName string `json:"given_name"` // The first name of the user. (Required.) + FamilyName string `json:"family_name"` // The last name of the user. (Required.) + Formatted *string `json:"formatted,omitempty"` +} + +type SCIMUserEmails struct { + Value string `json:"value"` // (Required.) + Primary bool `json:"primary,omitempty"` + Type *string `json:"type,omitempty"` +} + +type ListSCIMProvisionedIdentitiesOptions struct { + StartIndex *int `json:"start_index,omitempty"` // Used for pagination: the index of the first result to return. (Optional.) + Count *int `json:"count,omitempty"` // Used for pagination: the number of results to return. (Optional.) + Filter *string `json:"filter,omitempty"` // Filters results using the equals query parameter operator (eq). You can filter results that are equal to id, userName, emails, and external_id. For example, to search for an identity with the userName Octocat, you would use this query: ?filter=userName%20eq%20\"Octocat\". To filter results for the identity with the email octocat@github.com, you would use this query: ?filter=emails%20eq%20\"octocat@github.com\". (Optional.) +} + +// ListSCIMProvisionedIdentities lists SCIM provisioned identities. +// +// GitHub API docs: https://docs.github.com/en/rest/reference/scim#list-scim-provisioned-identities +func (s *SCIMService) ListSCIMProvisionedIdentities(ctx context.Context, org string, opts *ListSCIMProvisionedIdentitiesOptions) (*Response, error) { + u := fmt.Sprintf("/scim/v2/organizations/%v/Users", org) + u, err := addOptions(u, opts) + if err != nil { + return nil, err + } + req, err := s.client.NewRequest("GET", u, nil) + if err != nil { + return nil, err + } + return s.client.Do(ctx, req, nil) +} + +// ProvisionAndInviteSCIMUser provisions organization membership for a user, and send an activation email to the email address. +// +// GitHub API docs: https://docs.github.com/en/rest/reference/scim#provision-and-invite-a-scim-user +func (s *SCIMService) ProvisionAndInviteSCIMUser(ctx context.Context, org string, opts *SCIMUserAttributes) (*Response, error) { + u := fmt.Sprintf("/scim/v2/organizations/%v/Users", org) + u, err := addOptions(u, opts) + if err != nil { + return nil, err + } + req, err := s.client.NewRequest("POST", u, nil) + if err != nil { + return nil, err + } + return s.client.Do(ctx, req, nil) +} + +// GetSCIMProvisioningInfoForUser returns SCIM provisioning information for a user +// +// GitHub API docs: https://docs.github.com/en/rest/reference/scim#get-scim-provisioning-information-for-a-user +func (s *SCIMService) GetSCIMProvisioningInfoForUser(ctx context.Context, org, scimUserID string) (*Response, error) { + u := fmt.Sprintf("/scim/v2/organizations/%v/Users/%v", org, scimUserID) + req, err := s.client.NewRequest("GET", u, nil) + if err != nil { + return nil, err + } + return s.client.Do(ctx, req, nil) +} + +// UpdateProvisionedOrgMembership updates a provisioned organization membership. +// +// GitHub API docs: https://docs.github.com/en/rest/reference/scim#update-a-provisioned-organization-membership +func (s *SCIMService) UpdateProvisionedOrgMembership(ctx context.Context, org, scimUserID string, opts *SCIMUserAttributes) (*Response, error) { + u := fmt.Sprintf("/scim/v2/organizations/%v/Users/%v", org, scimUserID) + u, err := addOptions(u, opts) + if err != nil { + return nil, err + } + req, err := s.client.NewRequest("PUT", u, nil) + if err != nil { + return nil, err + } + return s.client.Do(ctx, req, nil) +} + +type UpdateAttributeForSCIMUserOptions struct { + Schemas []*string + Operations UpdateAttributeForSCIMUserOperations +} + +type UpdateAttributeForSCIMUserOperations struct { + Op string `json:"op"` // (Required.) + Path *string `json:"path,omitempty"` + Value *string `json:"value,omitempty"` +} + +// UpdateAttributeForSCIMUser updates an attribute for an SCIM user. +// +// GitHub API docs: https://docs.github.com/en/rest/reference/scim#update-an-attribute-for-a-scim-user +func UpdateAttributeForSCIMUser(ctx context.Context, org, scimUserID string) (*Response, error) { + return nil, nil +} + +// DeleteSCIMUserFromOrg deletes SCIM user from an organization +// +// GitHub API docs: https://docs.github.com/en/rest/reference/scim#delete-a-scim-user-from-an-organization +func (s *SCIMService) DeleteSCIMUserFromOrg(ctx context.Context, org, scimUserID string) (*Response, error) { + u := fmt.Sprintf("/scim/v2/organizations/%v/Users/%v", org, scimUserID) + req, err := s.client.NewRequest("DELETE", u, nil) + if err != nil { + return nil, err + } + return s.client.Do(ctx, req, nil) +} diff --git a/github/scim_test.go b/github/scim_test.go new file mode 100644 index 00000000000..58cbf91cc43 --- /dev/null +++ b/github/scim_test.go @@ -0,0 +1,32 @@ +package github + +import ( + "context" + "net/http" + "testing" +) + +func TestSCIMService_GetSCIMProvisioningInfoForUser(t *testing.T) { + client, mux, _, teardown := setup() + defer teardown() + + mux.HandleFunc("/scim/v2/organizations/o/Users/123", func(w http.ResponseWriter, r *http.Request) { + testMethod(t, r, "GET") + }) + + ctx := context.Background() + _, err := client.SCIM.GetSCIMProvisioningInfoForUser(ctx, "o", "123") + if err != nil { + t.Errorf("SCIM.GetSCIMProvisioningInfoForUser returned error: %v", err) + } + + const methodName = "GetSCIMProvisioningInfoForUser" + testBadOptions(t, methodName, func() error { + _, err := client.SCIM.GetSCIMProvisioningInfoForUser(ctx, "\n", "123") + return err + }) + + testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) { + return client.SCIM.GetSCIMProvisioningInfoForUser(ctx, "o", "123") + }) +} From 13d5e3f26dc05ae729be2856ef125cb6b96d430c Mon Sep 17 00:00:00 2001 From: Krishna Indani Date: Thu, 26 Aug 2021 17:27:41 -0700 Subject: [PATCH 2/9] scim service tests --- github/github-accessors.go | 64 +++++++++++++ github/github-accessors_test.go | 80 ++++++++++++++++ github/scim.go | 46 ++++++---- github/scim_test.go | 157 ++++++++++++++++++++++++++++++++ 4 files changed, 329 insertions(+), 18 deletions(-) diff --git a/github/github-accessors.go b/github/github-accessors.go index bd94ba944c2..19e44fc1c82 100644 --- a/github/github-accessors.go +++ b/github/github-accessors.go @@ -7180,6 +7180,30 @@ func (l *ListRepositories) GetTotalCount() int { return *l.TotalCount } +// GetCount returns the Count field if it's non-nil, zero value otherwise. +func (l *ListSCIMProvisionedIdentitiesOptions) GetCount() int { + if l == nil || l.Count == nil { + return 0 + } + return *l.Count +} + +// GetFilter returns the Filter field if it's non-nil, zero value otherwise. +func (l *ListSCIMProvisionedIdentitiesOptions) GetFilter() string { + if l == nil || l.Filter == nil { + return "" + } + return *l.Filter +} + +// GetStartIndex returns the StartIndex field if it's non-nil, zero value otherwise. +func (l *ListSCIMProvisionedIdentitiesOptions) GetStartIndex() int { + if l == nil || l.StartIndex == nil { + return 0 + } + return *l.StartIndex +} + // GetEndColumn returns the EndColumn field if it's non-nil, zero value otherwise. func (l *Location) GetEndColumn() int { if l == nil || l.EndColumn == nil { @@ -14572,6 +14596,38 @@ func (r *RunnerLabels) GetType() string { return *r.Type } +// GetDisplayName returns the DisplayName field if it's non-nil, zero value otherwise. +func (s *SCIMUserAttributes) GetDisplayName() string { + if s == nil || s.DisplayName == nil { + return "" + } + return *s.DisplayName +} + +// GetExternalID returns the ExternalID field if it's non-nil, zero value otherwise. +func (s *SCIMUserAttributes) GetExternalID() string { + if s == nil || s.ExternalID == nil { + return "" + } + return *s.ExternalID +} + +// GetType returns the Type field if it's non-nil, zero value otherwise. +func (s *SCIMUserEmails) GetType() string { + if s == nil || s.Type == nil { + return "" + } + return *s.Type +} + +// GetFormatted returns the Formatted field if it's non-nil, zero value otherwise. +func (s *SCIMUserName) GetFormatted() string { + if s == nil || s.Formatted == nil { + return "" + } + return *s.Formatted +} + // GetTotalCount returns the TotalCount field if it's non-nil, zero value otherwise. func (s *SelectedReposList) GetTotalCount() int { if s == nil || s.TotalCount == nil { @@ -16116,6 +16172,14 @@ func (t *TreeEntry) GetURL() string { return *t.URL } +// GetPath returns the Path field if it's non-nil, zero value otherwise. +func (u *UpdateAttributeForSCIMUserOperations) GetPath() string { + if u == nil || u.Path == nil { + return "" + } + return *u.Path +} + // GetCompletedAt returns the CompletedAt field if it's non-nil, zero value otherwise. func (u *UpdateCheckRunOptions) GetCompletedAt() Timestamp { if u == nil || u.CompletedAt == nil { diff --git a/github/github-accessors_test.go b/github/github-accessors_test.go index 4264ce8b9ad..e40737dca3a 100644 --- a/github/github-accessors_test.go +++ b/github/github-accessors_test.go @@ -8427,6 +8427,36 @@ func TestListRepositories_GetTotalCount(tt *testing.T) { l.GetTotalCount() } +func TestListSCIMProvisionedIdentitiesOptions_GetCount(tt *testing.T) { + var zeroValue int + l := &ListSCIMProvisionedIdentitiesOptions{Count: &zeroValue} + l.GetCount() + l = &ListSCIMProvisionedIdentitiesOptions{} + l.GetCount() + l = nil + l.GetCount() +} + +func TestListSCIMProvisionedIdentitiesOptions_GetFilter(tt *testing.T) { + var zeroValue string + l := &ListSCIMProvisionedIdentitiesOptions{Filter: &zeroValue} + l.GetFilter() + l = &ListSCIMProvisionedIdentitiesOptions{} + l.GetFilter() + l = nil + l.GetFilter() +} + +func TestListSCIMProvisionedIdentitiesOptions_GetStartIndex(tt *testing.T) { + var zeroValue int + l := &ListSCIMProvisionedIdentitiesOptions{StartIndex: &zeroValue} + l.GetStartIndex() + l = &ListSCIMProvisionedIdentitiesOptions{} + l.GetStartIndex() + l = nil + l.GetStartIndex() +} + func TestLocation_GetEndColumn(tt *testing.T) { var zeroValue int l := &Location{EndColumn: &zeroValue} @@ -17046,6 +17076,46 @@ func TestRunnerLabels_GetType(tt *testing.T) { r.GetType() } +func TestSCIMUserAttributes_GetDisplayName(tt *testing.T) { + var zeroValue string + s := &SCIMUserAttributes{DisplayName: &zeroValue} + s.GetDisplayName() + s = &SCIMUserAttributes{} + s.GetDisplayName() + s = nil + s.GetDisplayName() +} + +func TestSCIMUserAttributes_GetExternalID(tt *testing.T) { + var zeroValue string + s := &SCIMUserAttributes{ExternalID: &zeroValue} + s.GetExternalID() + s = &SCIMUserAttributes{} + s.GetExternalID() + s = nil + s.GetExternalID() +} + +func TestSCIMUserEmails_GetType(tt *testing.T) { + var zeroValue string + s := &SCIMUserEmails{Type: &zeroValue} + s.GetType() + s = &SCIMUserEmails{} + s.GetType() + s = nil + s.GetType() +} + +func TestSCIMUserName_GetFormatted(tt *testing.T) { + var zeroValue string + s := &SCIMUserName{Formatted: &zeroValue} + s.GetFormatted() + s = &SCIMUserName{} + s.GetFormatted() + s = nil + s.GetFormatted() +} + func TestSelectedReposList_GetTotalCount(tt *testing.T) { var zeroValue int s := &SelectedReposList{TotalCount: &zeroValue} @@ -18847,6 +18917,16 @@ func TestTreeEntry_GetURL(tt *testing.T) { t.GetURL() } +func TestUpdateAttributeForSCIMUserOperations_GetPath(tt *testing.T) { + var zeroValue string + u := &UpdateAttributeForSCIMUserOperations{Path: &zeroValue} + u.GetPath() + u = &UpdateAttributeForSCIMUserOperations{} + u.GetPath() + u = nil + u.GetPath() +} + func TestUpdateCheckRunOptions_GetCompletedAt(tt *testing.T) { var zeroValue Timestamp u := &UpdateCheckRunOptions{CompletedAt: &zeroValue} diff --git a/github/scim.go b/github/scim.go index d49c709f2b4..6052ae637f8 100644 --- a/github/scim.go +++ b/github/scim.go @@ -2,6 +2,7 @@ package github import ( "context" + "encoding/json" "fmt" ) @@ -23,15 +24,15 @@ type SCIMUserAttributes struct { } type SCIMUserName struct { - GivenName string `json:"given_name"` // The first name of the user. (Required.) - FamilyName string `json:"family_name"` // The last name of the user. (Required.) - Formatted *string `json:"formatted,omitempty"` + GivenName string `json:"given_name"` // The first name of the user. (Required.) + FamilyName string `json:"family_name"` // The last name of the user. (Required.) + Formatted *string `json:"formatted,omitempty"` // (Optional.) } type SCIMUserEmails struct { - Value string `json:"value"` // (Required.) - Primary bool `json:"primary,omitempty"` - Type *string `json:"type,omitempty"` + Value string `json:"value"` // (Required.) + Primary bool `json:"primary,omitempty"` // (Optional.) + Type *string `json:"type,omitempty"` // (Optional.) } type ListSCIMProvisionedIdentitiesOptions struct { @@ -44,7 +45,7 @@ type ListSCIMProvisionedIdentitiesOptions struct { // // GitHub API docs: https://docs.github.com/en/rest/reference/scim#list-scim-provisioned-identities func (s *SCIMService) ListSCIMProvisionedIdentities(ctx context.Context, org string, opts *ListSCIMProvisionedIdentitiesOptions) (*Response, error) { - u := fmt.Sprintf("/scim/v2/organizations/%v/Users", org) + u := fmt.Sprintf("scim/v2/organizations/%v/Users", org) u, err := addOptions(u, opts) if err != nil { return nil, err @@ -60,7 +61,7 @@ func (s *SCIMService) ListSCIMProvisionedIdentities(ctx context.Context, org str // // GitHub API docs: https://docs.github.com/en/rest/reference/scim#provision-and-invite-a-scim-user func (s *SCIMService) ProvisionAndInviteSCIMUser(ctx context.Context, org string, opts *SCIMUserAttributes) (*Response, error) { - u := fmt.Sprintf("/scim/v2/organizations/%v/Users", org) + u := fmt.Sprintf("scim/v2/organizations/%v/Users", org) u, err := addOptions(u, opts) if err != nil { return nil, err @@ -76,7 +77,7 @@ func (s *SCIMService) ProvisionAndInviteSCIMUser(ctx context.Context, org string // // GitHub API docs: https://docs.github.com/en/rest/reference/scim#get-scim-provisioning-information-for-a-user func (s *SCIMService) GetSCIMProvisioningInfoForUser(ctx context.Context, org, scimUserID string) (*Response, error) { - u := fmt.Sprintf("/scim/v2/organizations/%v/Users/%v", org, scimUserID) + u := fmt.Sprintf("scim/v2/organizations/%v/Users/%v", org, scimUserID) req, err := s.client.NewRequest("GET", u, nil) if err != nil { return nil, err @@ -88,7 +89,7 @@ func (s *SCIMService) GetSCIMProvisioningInfoForUser(ctx context.Context, org, s // // GitHub API docs: https://docs.github.com/en/rest/reference/scim#update-a-provisioned-organization-membership func (s *SCIMService) UpdateProvisionedOrgMembership(ctx context.Context, org, scimUserID string, opts *SCIMUserAttributes) (*Response, error) { - u := fmt.Sprintf("/scim/v2/organizations/%v/Users/%v", org, scimUserID) + u := fmt.Sprintf("scim/v2/organizations/%v/Users/%v", org, scimUserID) u, err := addOptions(u, opts) if err != nil { return nil, err @@ -101,28 +102,37 @@ func (s *SCIMService) UpdateProvisionedOrgMembership(ctx context.Context, org, s } type UpdateAttributeForSCIMUserOptions struct { - Schemas []*string - Operations UpdateAttributeForSCIMUserOperations + Schemas []*string `json:"schemas"` // (Optional.) + Operations UpdateAttributeForSCIMUserOperations `json:"operations"` // Set of operations to be performed. (Required.) } type UpdateAttributeForSCIMUserOperations struct { - Op string `json:"op"` // (Required.) - Path *string `json:"path,omitempty"` - Value *string `json:"value,omitempty"` + Op string `json:"op"` // (Required.) + Path *string `json:"path,omitempty"` // (Optional.) + Value json.RawMessage `json:"value,omitempty"` // (Optional.) } // UpdateAttributeForSCIMUser updates an attribute for an SCIM user. // // GitHub API docs: https://docs.github.com/en/rest/reference/scim#update-an-attribute-for-a-scim-user -func UpdateAttributeForSCIMUser(ctx context.Context, org, scimUserID string) (*Response, error) { - return nil, nil +func (s *SCIMService) UpdateAttributeForSCIMUser(ctx context.Context, org, scimUserID string, opts *UpdateAttributeForSCIMUserOptions) (*Response, error) { + u := fmt.Sprintf("scim/v2/organizations/%v/Users/%v", org, scimUserID) + u, err := addOptions(u, opts) + if err != nil { + return nil, err + } + req, err := s.client.NewRequest("PATCH", u, nil) + if err != nil { + return nil, err + } + return s.client.Do(ctx, req, nil) } // DeleteSCIMUserFromOrg deletes SCIM user from an organization // // GitHub API docs: https://docs.github.com/en/rest/reference/scim#delete-a-scim-user-from-an-organization func (s *SCIMService) DeleteSCIMUserFromOrg(ctx context.Context, org, scimUserID string) (*Response, error) { - u := fmt.Sprintf("/scim/v2/organizations/%v/Users/%v", org, scimUserID) + u := fmt.Sprintf("scim/v2/organizations/%v/Users/%v", org, scimUserID) req, err := s.client.NewRequest("DELETE", u, nil) if err != nil { return nil, err diff --git a/github/scim_test.go b/github/scim_test.go index 58cbf91cc43..f24577b98fb 100644 --- a/github/scim_test.go +++ b/github/scim_test.go @@ -6,12 +6,78 @@ import ( "testing" ) +func TestSCIMService_ListSCIMProvisionedIdentities(t *testing.T) { + client, mux, _, teardown := setup() + defer teardown() + + mux.HandleFunc("/scim/v2/organizations/o/Users", func(w http.ResponseWriter, r *http.Request) { + testMethod(t, r, "GET") + w.WriteHeader(http.StatusOK) + }) + + ctx := context.Background() + opts := &ListSCIMProvisionedIdentitiesOptions{} + _, err := client.SCIM.ListSCIMProvisionedIdentities(ctx, "o", opts) + if err != nil { + t.Errorf("SCIM.ListSCIMProvisionedIdentities returned error: %v", err) + } + + const methodName = "ListSCIMProvisionedIdentities" + testBadOptions(t, methodName, func() (err error) { + _, err = client.SCIM.ListSCIMProvisionedIdentities(ctx, "\n", opts) + return err + }) + + testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) { + return client.SCIM.ListSCIMProvisionedIdentities(ctx, "o", opts) + }) +} + +func TestSCIMService_ProvisionAndInviteSCIMUser(t *testing.T) { + client, mux, _, teardown := setup() + defer teardown() + + mux.HandleFunc("/scim/v2/organizations/o/Users", func(w http.ResponseWriter, r *http.Request) { + testMethod(t, r, "POST") + w.WriteHeader(http.StatusOK) + }) + + ctx := context.Background() + opts := &SCIMUserAttributes{ + UserName: "userName", + Name: SCIMUserName{ + GivenName: "givenName", + FamilyName: "familyName", + }, + Emails: []*SCIMUserEmails{ + { + Value: "octocat@github.com", + }, + }, + } + _, err := client.SCIM.ProvisionAndInviteSCIMUser(ctx, "o", opts) + if err != nil { + t.Errorf("SCIM.ListSCIMProvisionedIdentities returned error: %v", err) + } + + const methodName = "ProvisionAndInviteSCIMUser" + testBadOptions(t, methodName, func() (err error) { + _, err = client.SCIM.ProvisionAndInviteSCIMUser(ctx, "\n", opts) + return err + }) + + testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) { + return client.SCIM.ProvisionAndInviteSCIMUser(ctx, "o", opts) + }) +} + func TestSCIMService_GetSCIMProvisioningInfoForUser(t *testing.T) { client, mux, _, teardown := setup() defer teardown() mux.HandleFunc("/scim/v2/organizations/o/Users/123", func(w http.ResponseWriter, r *http.Request) { testMethod(t, r, "GET") + w.WriteHeader(http.StatusOK) }) ctx := context.Background() @@ -30,3 +96,94 @@ func TestSCIMService_GetSCIMProvisioningInfoForUser(t *testing.T) { return client.SCIM.GetSCIMProvisioningInfoForUser(ctx, "o", "123") }) } + +func TestSCIMService_UpdateProvisionedOrgMembership(t *testing.T) { + client, mux, _, teardown := setup() + defer teardown() + + mux.HandleFunc("/scim/v2/organizations/o/Users/123", func(w http.ResponseWriter, r *http.Request) { + testMethod(t, r, "PUT") + w.WriteHeader(http.StatusOK) + }) + + ctx := context.Background() + opts := &SCIMUserAttributes{ + UserName: "userName", + Name: SCIMUserName{ + GivenName: "givenName", + FamilyName: "familyName", + }, + Emails: []*SCIMUserEmails{ + { + Value: "octocat@github.com", + }, + }, + } + _, err := client.SCIM.UpdateProvisionedOrgMembership(ctx, "o", "123", opts) + if err != nil { + t.Errorf("SCIM.UpdateProvisionedOrgMembership returned error: %v", err) + } + + const methodName = "UpdateProvisionedOrgMembership" + testBadOptions(t, methodName, func() error { + _, err := client.SCIM.UpdateProvisionedOrgMembership(ctx, "\n", "123", opts) + return err + }) + + testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) { + return client.SCIM.UpdateProvisionedOrgMembership(ctx, "o", "123", opts) + }) +} + +func TestSCIMService_UpdateAttributeForSCIMUser(t *testing.T) { + client, mux, _, teardown := setup() + defer teardown() + + mux.HandleFunc("/scim/v2/organizations/o/Users/123", func(w http.ResponseWriter, r *http.Request) { + testMethod(t, r, "PATCH") + w.WriteHeader(http.StatusNoContent) + }) + + ctx := context.Background() + opts := &UpdateAttributeForSCIMUserOptions{} + _, err := client.SCIM.UpdateAttributeForSCIMUser(ctx, "o", "123", opts) + if err != nil { + t.Errorf("SCIM.UpdateAttributeForSCIMUser returned error: %v", err) + } + + const methodName = "UpdateAttributeForSCIMUser" + testBadOptions(t, methodName, func() error { + _, err := client.SCIM.UpdateAttributeForSCIMUser(ctx, "\n", "123", opts) + return err + }) + + testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) { + return client.SCIM.UpdateAttributeForSCIMUser(ctx, "o", "123", opts) + }) +} + +func TestSCIMService_DeleteSCIMUserFromOrg(t *testing.T) { + client, mux, _, teardown := setup() + defer teardown() + + mux.HandleFunc("/scim/v2/organizations/o/Users/123", func(w http.ResponseWriter, r *http.Request) { + testMethod(t, r, "DELETE") + w.WriteHeader(http.StatusNoContent) + }) + + ctx := context.Background() + _, err := client.SCIM.DeleteSCIMUserFromOrg(ctx, "o", "123") + if err != nil { + t.Errorf("SCIM.DeleteSCIMUserFromOrg returned error: %v", err) + } + + const methodName = "DeleteSCIMUserFromOrg" + testBadOptions(t, methodName, func() error { + _, err := client.SCIM.DeleteSCIMUserFromOrg(ctx, "\n", "") + return err + }) + + testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) { + return client.SCIM.DeleteSCIMUserFromOrg(ctx, "o", "123") + }) +} From ffb327a45c0d4b3bb8700d35ac498e30f9f884ed Mon Sep 17 00:00:00 2001 From: Krishna Indani Date: Thu, 26 Aug 2021 17:28:00 -0700 Subject: [PATCH 3/9] add vscode to gitignore --- .gitignore | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index 3d439783c94..aea73858e55 100644 --- a/.gitignore +++ b/.gitignore @@ -4,4 +4,5 @@ coverage.out # intellij files .idea/ vendor/ -.DS_Store \ No newline at end of file +.DS_Store +.vscode \ No newline at end of file From 21471e8b771fc903dfed8d84373b0b3e7c31a212 Mon Sep 17 00:00:00 2001 From: Krishna Indani Date: Thu, 26 Aug 2021 19:21:41 -0700 Subject: [PATCH 4/9] fix based on reviews --- github/github-accessors.go | 18 ++++++++++++- github/github-accessors_test.go | 26 ++++++++++++++++--- github/github.go | 2 +- github/scim.go | 45 +++++++++++++++++++++------------ github/scim_test.go | 4 +-- 5 files changed, 72 insertions(+), 23 deletions(-) diff --git a/github/github-accessors.go b/github/github-accessors.go index 19e44fc1c82..9bdcab00673 100644 --- a/github/github-accessors.go +++ b/github/github-accessors.go @@ -14596,6 +14596,14 @@ func (r *RunnerLabels) GetType() string { return *r.Type } +// GetActive returns the Active field if it's non-nil, zero value otherwise. +func (s *SCIMUserAttributes) GetActive() bool { + if s == nil || s.Active == nil { + return false + } + return *s.Active +} + // GetDisplayName returns the DisplayName field if it's non-nil, zero value otherwise. func (s *SCIMUserAttributes) GetDisplayName() string { if s == nil || s.DisplayName == nil { @@ -14612,8 +14620,16 @@ func (s *SCIMUserAttributes) GetExternalID() string { return *s.ExternalID } +// GetPrimary returns the Primary field if it's non-nil, zero value otherwise. +func (s *SCIMUserEmail) GetPrimary() bool { + if s == nil || s.Primary == nil { + return false + } + return *s.Primary +} + // GetType returns the Type field if it's non-nil, zero value otherwise. -func (s *SCIMUserEmails) GetType() string { +func (s *SCIMUserEmail) GetType() string { if s == nil || s.Type == nil { return "" } diff --git a/github/github-accessors_test.go b/github/github-accessors_test.go index e40737dca3a..10029493502 100644 --- a/github/github-accessors_test.go +++ b/github/github-accessors_test.go @@ -17076,6 +17076,16 @@ func TestRunnerLabels_GetType(tt *testing.T) { r.GetType() } +func TestSCIMUserAttributes_GetActive(tt *testing.T) { + var zeroValue bool + s := &SCIMUserAttributes{Active: &zeroValue} + s.GetActive() + s = &SCIMUserAttributes{} + s.GetActive() + s = nil + s.GetActive() +} + func TestSCIMUserAttributes_GetDisplayName(tt *testing.T) { var zeroValue string s := &SCIMUserAttributes{DisplayName: &zeroValue} @@ -17096,11 +17106,21 @@ func TestSCIMUserAttributes_GetExternalID(tt *testing.T) { s.GetExternalID() } -func TestSCIMUserEmails_GetType(tt *testing.T) { +func TestSCIMUserEmail_GetPrimary(tt *testing.T) { + var zeroValue bool + s := &SCIMUserEmail{Primary: &zeroValue} + s.GetPrimary() + s = &SCIMUserEmail{} + s.GetPrimary() + s = nil + s.GetPrimary() +} + +func TestSCIMUserEmail_GetType(tt *testing.T) { var zeroValue string - s := &SCIMUserEmails{Type: &zeroValue} + s := &SCIMUserEmail{Type: &zeroValue} s.GetType() - s = &SCIMUserEmails{} + s = &SCIMUserEmail{} s.GetType() s = nil s.GetType() diff --git a/github/github.go b/github/github.go index c1c8ad4782a..b87ded89185 100644 --- a/github/github.go +++ b/github/github.go @@ -181,8 +181,8 @@ type Client struct { PullRequests *PullRequestsService Reactions *ReactionsService Repositories *RepositoriesService - Search *SearchService SCIM *SCIMService + Search *SearchService Teams *TeamsService Users *UsersService } diff --git a/github/scim.go b/github/scim.go index 6052ae637f8..22a45c83365 100644 --- a/github/scim.go +++ b/github/scim.go @@ -1,3 +1,8 @@ +// Copyright 2021 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 ( @@ -12,33 +17,41 @@ import ( // GitHub API docs: https://docs.github.com/en/rest/reference/scim type SCIMService service +// SCIMUserAttributes represents supported SCIM User atrributes. +// +// GitHub API docs: https://docs.github.com/en/rest/reference/scim#supported-scim-user-attributes type SCIMUserAttributes struct { - UserName string `json:"user_name"` // Configured by the admin. Could be an email, login, or username. (Required.) - Name SCIMUserName `json:"name"` // (Required.) - DisplayName *string `json:"display_name,omitempty"` // The name of the user, suitable for display to end-users. (Optional.) - Emails []*SCIMUserEmails `json:"email"` // User emails. (Required.) - Schemas []*string `json:"schemas,omitempty"` // (Optional.) - ExternalID *string `json:"external_id,omitempty"` // (Optional.) - Groups []*string `json:"groups,omitempty"` // (Optional.) - Active bool `json:"active,omitempty"` // (Optional.) + UserName string `json:"user_name"` // Configured by the admin. Could be an email, login, or username. (Required.) + Name SCIMUserName `json:"name"` // (Required.) + DisplayName *string `json:"display_name,omitempty"` // The name of the user, suitable for display to end-users. (Optional.) + Emails []*SCIMUserEmail `json:"email"` // User emails. (Required.) + Schemas []string `json:"schemas,omitempty"` // (Optional.) + ExternalID *string `json:"external_id,omitempty"` // (Optional.) + Groups []string `json:"groups,omitempty"` // (Optional.) + Active *bool `json:"active,omitempty"` // (Optional.) } +// SCIMUserName represents SCIM user information. type SCIMUserName struct { GivenName string `json:"given_name"` // The first name of the user. (Required.) FamilyName string `json:"family_name"` // The last name of the user. (Required.) Formatted *string `json:"formatted,omitempty"` // (Optional.) } -type SCIMUserEmails struct { +//SCIMUserEmail represents SCIM user email. +type SCIMUserEmail struct { Value string `json:"value"` // (Required.) - Primary bool `json:"primary,omitempty"` // (Optional.) + Primary *bool `json:"primary,omitempty"` // (Optional.) Type *string `json:"type,omitempty"` // (Optional.) } +// ListSCIMProvisionedIdentitiesOptions represents options for ListSCIMProvisionedIdentities. +// +// Github API docs: https://docs.github.com/en/rest/reference/scim#list-scim-provisioned-identities--parameters type ListSCIMProvisionedIdentitiesOptions struct { StartIndex *int `json:"start_index,omitempty"` // Used for pagination: the index of the first result to return. (Optional.) Count *int `json:"count,omitempty"` // Used for pagination: the number of results to return. (Optional.) - Filter *string `json:"filter,omitempty"` // Filters results using the equals query parameter operator (eq). You can filter results that are equal to id, userName, emails, and external_id. For example, to search for an identity with the userName Octocat, you would use this query: ?filter=userName%20eq%20\"Octocat\". To filter results for the identity with the email octocat@github.com, you would use this query: ?filter=emails%20eq%20\"octocat@github.com\". (Optional.) + Filter *string `json:"filter,omitempty"` // Filter results using the equals query parameter operator (eq). You can filter results that are equal to id, userName, emails, and external_id. For example, to search for an identity with the userName Octocat, you would use this query: ?filter=userName%20eq%20\"Octocat\". To filter results for the identity with the email octocat@github.com, you would use this query: ?filter=emails%20eq%20\"octocat@github.com\". (Optional.) } // ListSCIMProvisionedIdentities lists SCIM provisioned identities. @@ -57,7 +70,7 @@ func (s *SCIMService) ListSCIMProvisionedIdentities(ctx context.Context, org str return s.client.Do(ctx, req, nil) } -// ProvisionAndInviteSCIMUser provisions organization membership for a user, and send an activation email to the email address. +// ProvisionAndInviteSCIMUser provisions organization membership for a user, and sends an activation email to the email address. // // GitHub API docs: https://docs.github.com/en/rest/reference/scim#provision-and-invite-a-scim-user func (s *SCIMService) ProvisionAndInviteSCIMUser(ctx context.Context, org string, opts *SCIMUserAttributes) (*Response, error) { @@ -73,7 +86,7 @@ func (s *SCIMService) ProvisionAndInviteSCIMUser(ctx context.Context, org string return s.client.Do(ctx, req, nil) } -// GetSCIMProvisioningInfoForUser returns SCIM provisioning information for a user +// GetSCIMProvisioningInfoForUser returns SCIM provisioning information for a user. // // GitHub API docs: https://docs.github.com/en/rest/reference/scim#get-scim-provisioning-information-for-a-user func (s *SCIMService) GetSCIMProvisioningInfoForUser(ctx context.Context, org, scimUserID string) (*Response, error) { @@ -102,8 +115,8 @@ func (s *SCIMService) UpdateProvisionedOrgMembership(ctx context.Context, org, s } type UpdateAttributeForSCIMUserOptions struct { - Schemas []*string `json:"schemas"` // (Optional.) - Operations UpdateAttributeForSCIMUserOperations `json:"operations"` // Set of operations to be performed. (Required.) + Schemas []string `json:"schemas,omitempty"` // (Optional.) + Operations UpdateAttributeForSCIMUserOperations `json:"operations"` // Set of operations to be performed. (Required.) } type UpdateAttributeForSCIMUserOperations struct { @@ -128,7 +141,7 @@ func (s *SCIMService) UpdateAttributeForSCIMUser(ctx context.Context, org, scimU return s.client.Do(ctx, req, nil) } -// DeleteSCIMUserFromOrg deletes SCIM user from an organization +// DeleteSCIMUserFromOrg deletes SCIM user from an organization. // // GitHub API docs: https://docs.github.com/en/rest/reference/scim#delete-a-scim-user-from-an-organization func (s *SCIMService) DeleteSCIMUserFromOrg(ctx context.Context, org, scimUserID string) (*Response, error) { diff --git a/github/scim_test.go b/github/scim_test.go index f24577b98fb..b28aa63ea4d 100644 --- a/github/scim_test.go +++ b/github/scim_test.go @@ -49,7 +49,7 @@ func TestSCIMService_ProvisionAndInviteSCIMUser(t *testing.T) { GivenName: "givenName", FamilyName: "familyName", }, - Emails: []*SCIMUserEmails{ + Emails: []*SCIMUserEmail{ { Value: "octocat@github.com", }, @@ -113,7 +113,7 @@ func TestSCIMService_UpdateProvisionedOrgMembership(t *testing.T) { GivenName: "givenName", FamilyName: "familyName", }, - Emails: []*SCIMUserEmails{ + Emails: []*SCIMUserEmail{ { Value: "octocat@github.com", }, From ccc1749443d418c9f563ab2c61e75f2fa9c234c0 Mon Sep 17 00:00:00 2001 From: Krishna Indani Date: Thu, 26 Aug 2021 19:24:42 -0700 Subject: [PATCH 5/9] add license in scim tests --- github/github.go | 2 +- github/scim_test.go | 5 +++++ 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/github/github.go b/github/github.go index b87ded89185..b83e4306c96 100644 --- a/github/github.go +++ b/github/github.go @@ -309,8 +309,8 @@ func NewClient(httpClient *http.Client) *Client { c.PullRequests = (*PullRequestsService)(&c.common) c.Reactions = (*ReactionsService)(&c.common) c.Repositories = (*RepositoriesService)(&c.common) - c.Search = (*SearchService)(&c.common) c.SCIM = (*SCIMService)(&c.common) + c.Search = (*SearchService)(&c.common) c.Teams = (*TeamsService)(&c.common) c.Users = (*UsersService)(&c.common) return c diff --git a/github/scim_test.go b/github/scim_test.go index b28aa63ea4d..3338a28a26c 100644 --- a/github/scim_test.go +++ b/github/scim_test.go @@ -1,3 +1,8 @@ +// Copyright 2021 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 ( From 8a71369705c9a6d3be94176f50408599f9ae56d6 Mon Sep 17 00:00:00 2001 From: Krishna Indani Date: Thu, 26 Aug 2021 19:41:04 -0700 Subject: [PATCH 6/9] add multiline comment for filter --- github/scim.go | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/github/scim.go b/github/scim.go index 22a45c83365..b97f637fe23 100644 --- a/github/scim.go +++ b/github/scim.go @@ -49,9 +49,14 @@ type SCIMUserEmail struct { // // Github API docs: https://docs.github.com/en/rest/reference/scim#list-scim-provisioned-identities--parameters type ListSCIMProvisionedIdentitiesOptions struct { - StartIndex *int `json:"start_index,omitempty"` // Used for pagination: the index of the first result to return. (Optional.) - Count *int `json:"count,omitempty"` // Used for pagination: the number of results to return. (Optional.) - Filter *string `json:"filter,omitempty"` // Filter results using the equals query parameter operator (eq). You can filter results that are equal to id, userName, emails, and external_id. For example, to search for an identity with the userName Octocat, you would use this query: ?filter=userName%20eq%20\"Octocat\". To filter results for the identity with the email octocat@github.com, you would use this query: ?filter=emails%20eq%20\"octocat@github.com\". (Optional.) + StartIndex *int `json:"start_index,omitempty"` // Used for pagination: the index of the first result to return. (Optional.) + Count *int `json:"count,omitempty"` // Used for pagination: the number of results to return. (Optional.) + // Filter results using the equals query parameter operator (eq). + //You can filter results that are equal to id, userName, emails, and external_id. + //For example, to search for an identity with the userName Octocat, you would use this query: ?filter=userName%20eq%20\"Octocat\". + //To filter results for the identity with the email octocat@github.com, you would use this query: ?filter=emails%20eq%20\"octocat@github.com\". + //(Optional.) + Filter *string `json:"filter,omitempty"` } // ListSCIMProvisionedIdentities lists SCIM provisioned identities. @@ -114,11 +119,15 @@ func (s *SCIMService) UpdateProvisionedOrgMembership(ctx context.Context, org, s return s.client.Do(ctx, req, nil) } +// UpdateAttributeForSCIMUserOptions represents options for UpdateAttributeForSCIMUser. +// +// GitHub API docs: https://docs.github.com/en/rest/reference/scim#update-an-attribute-for-a-scim-user--parameters type UpdateAttributeForSCIMUserOptions struct { Schemas []string `json:"schemas,omitempty"` // (Optional.) Operations UpdateAttributeForSCIMUserOperations `json:"operations"` // Set of operations to be performed. (Required.) } +// UpdateAttributeForSCIMUserOperations represents operations for UpdateAttributeForSCIMUser. type UpdateAttributeForSCIMUserOperations struct { Op string `json:"op"` // (Required.) Path *string `json:"path,omitempty"` // (Optional.) From f7aa77e7d9d6cc519aba334a62d3056f177571c6 Mon Sep 17 00:00:00 2001 From: Krishna Indani Date: Thu, 26 Aug 2021 19:46:19 -0700 Subject: [PATCH 7/9] add space in multi line comment --- github/scim.go | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/github/scim.go b/github/scim.go index b97f637fe23..45e2f2a6f87 100644 --- a/github/scim.go +++ b/github/scim.go @@ -52,10 +52,10 @@ type ListSCIMProvisionedIdentitiesOptions struct { StartIndex *int `json:"start_index,omitempty"` // Used for pagination: the index of the first result to return. (Optional.) Count *int `json:"count,omitempty"` // Used for pagination: the number of results to return. (Optional.) // Filter results using the equals query parameter operator (eq). - //You can filter results that are equal to id, userName, emails, and external_id. - //For example, to search for an identity with the userName Octocat, you would use this query: ?filter=userName%20eq%20\"Octocat\". - //To filter results for the identity with the email octocat@github.com, you would use this query: ?filter=emails%20eq%20\"octocat@github.com\". - //(Optional.) + // You can filter results that are equal to id, userName, emails, and external_id. + // For example, to search for an identity with the userName Octocat, you would use this query: ?filter=userName%20eq%20\"Octocat\". + // To filter results for the identity with the email octocat@github.com, you would use this query: ?filter=emails%20eq%20\"octocat@github.com\". + // (Optional.) Filter *string `json:"filter,omitempty"` } From bf0a905545708d54adc922b7746d79c95633d883 Mon Sep 17 00:00:00 2001 From: Krishna Indani Date: Thu, 26 Aug 2021 20:24:52 -0700 Subject: [PATCH 8/9] fix json tags --- github/scim.go | 26 +++++++++++++------------- github/scim_test.go | 8 ++++---- 2 files changed, 17 insertions(+), 17 deletions(-) diff --git a/github/scim.go b/github/scim.go index 45e2f2a6f87..021cfbb2357 100644 --- a/github/scim.go +++ b/github/scim.go @@ -21,21 +21,21 @@ type SCIMService service // // GitHub API docs: https://docs.github.com/en/rest/reference/scim#supported-scim-user-attributes type SCIMUserAttributes struct { - UserName string `json:"user_name"` // Configured by the admin. Could be an email, login, or username. (Required.) - Name SCIMUserName `json:"name"` // (Required.) - DisplayName *string `json:"display_name,omitempty"` // The name of the user, suitable for display to end-users. (Optional.) - Emails []*SCIMUserEmail `json:"email"` // User emails. (Required.) - Schemas []string `json:"schemas,omitempty"` // (Optional.) - ExternalID *string `json:"external_id,omitempty"` // (Optional.) - Groups []string `json:"groups,omitempty"` // (Optional.) - Active *bool `json:"active,omitempty"` // (Optional.) + UserName string `json:"userName"` // Configured by the admin. Could be an email, login, or username. (Required.) + Name SCIMUserName `json:"name"` // (Required.) + DisplayName *string `json:"displayName,omitempty"` // The name of the user, suitable for display to end-users. (Optional.) + Emails []*SCIMUserEmail `json:"emails"` // User emails. (Required.) + Schemas []string `json:"schemas,omitempty"` // (Optional.) + ExternalID *string `json:"externalId,omitempty"` // (Optional.) + Groups []string `json:"groups,omitempty"` // (Optional.) + Active *bool `json:"active,omitempty"` // (Optional.) } // SCIMUserName represents SCIM user information. type SCIMUserName struct { - GivenName string `json:"given_name"` // The first name of the user. (Required.) - FamilyName string `json:"family_name"` // The last name of the user. (Required.) - Formatted *string `json:"formatted,omitempty"` // (Optional.) + GivenName string `json:"givenName"` // The first name of the user. (Required.) + LastName string `json:"lastName"` // The last name of the user. (Required.) + Formatted *string `json:"formatted,omitempty"` // (Optional.) } //SCIMUserEmail represents SCIM user email. @@ -49,8 +49,8 @@ type SCIMUserEmail struct { // // Github API docs: https://docs.github.com/en/rest/reference/scim#list-scim-provisioned-identities--parameters type ListSCIMProvisionedIdentitiesOptions struct { - StartIndex *int `json:"start_index,omitempty"` // Used for pagination: the index of the first result to return. (Optional.) - Count *int `json:"count,omitempty"` // Used for pagination: the number of results to return. (Optional.) + StartIndex *int `json:"startIndex,omitempty"` // Used for pagination: the index of the first result to return. (Optional.) + Count *int `json:"count,omitempty"` // Used for pagination: the number of results to return. (Optional.) // Filter results using the equals query parameter operator (eq). // You can filter results that are equal to id, userName, emails, and external_id. // For example, to search for an identity with the userName Octocat, you would use this query: ?filter=userName%20eq%20\"Octocat\". diff --git a/github/scim_test.go b/github/scim_test.go index 3338a28a26c..776bd31d671 100644 --- a/github/scim_test.go +++ b/github/scim_test.go @@ -51,8 +51,8 @@ func TestSCIMService_ProvisionAndInviteSCIMUser(t *testing.T) { opts := &SCIMUserAttributes{ UserName: "userName", Name: SCIMUserName{ - GivenName: "givenName", - FamilyName: "familyName", + GivenName: "givenName", + LastName: "lastName", }, Emails: []*SCIMUserEmail{ { @@ -115,8 +115,8 @@ func TestSCIMService_UpdateProvisionedOrgMembership(t *testing.T) { opts := &SCIMUserAttributes{ UserName: "userName", Name: SCIMUserName{ - GivenName: "givenName", - FamilyName: "familyName", + GivenName: "givenName", + LastName: "lastName", }, Emails: []*SCIMUserEmail{ { From 895980e97433adc89e6253d617a257b102da9c33 Mon Sep 17 00:00:00 2001 From: Krishna Indani Date: Fri, 27 Aug 2021 10:52:11 -0700 Subject: [PATCH 9/9] use familyname instead of last name --- github/scim.go | 8 ++++---- github/scim_test.go | 8 ++++---- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/github/scim.go b/github/scim.go index 021cfbb2357..7a12d85b883 100644 --- a/github/scim.go +++ b/github/scim.go @@ -17,7 +17,7 @@ import ( // GitHub API docs: https://docs.github.com/en/rest/reference/scim type SCIMService service -// SCIMUserAttributes represents supported SCIM User atrributes. +// SCIMUserAttributes represents supported SCIM User attributes. // // GitHub API docs: https://docs.github.com/en/rest/reference/scim#supported-scim-user-attributes type SCIMUserAttributes struct { @@ -33,9 +33,9 @@ type SCIMUserAttributes struct { // SCIMUserName represents SCIM user information. type SCIMUserName struct { - GivenName string `json:"givenName"` // The first name of the user. (Required.) - LastName string `json:"lastName"` // The last name of the user. (Required.) - Formatted *string `json:"formatted,omitempty"` // (Optional.) + GivenName string `json:"givenName"` // The first name of the user. (Required.) + FamilyName string `json:"familyName"` // The family name of the user. (Required.) + Formatted *string `json:"formatted,omitempty"` // (Optional.) } //SCIMUserEmail represents SCIM user email. diff --git a/github/scim_test.go b/github/scim_test.go index 776bd31d671..3338a28a26c 100644 --- a/github/scim_test.go +++ b/github/scim_test.go @@ -51,8 +51,8 @@ func TestSCIMService_ProvisionAndInviteSCIMUser(t *testing.T) { opts := &SCIMUserAttributes{ UserName: "userName", Name: SCIMUserName{ - GivenName: "givenName", - LastName: "lastName", + GivenName: "givenName", + FamilyName: "familyName", }, Emails: []*SCIMUserEmail{ { @@ -115,8 +115,8 @@ func TestSCIMService_UpdateProvisionedOrgMembership(t *testing.T) { opts := &SCIMUserAttributes{ UserName: "userName", Name: SCIMUserName{ - GivenName: "givenName", - LastName: "lastName", + GivenName: "givenName", + FamilyName: "familyName", }, Emails: []*SCIMUserEmail{ {