diff --git a/cloud/user.go b/cloud/user.go index 1a8fea84..de75de09 100644 --- a/cloud/user.go +++ b/cloud/user.go @@ -5,6 +5,8 @@ import ( "encoding/json" "fmt" "net/http" + "net/url" + "strconv" ) // UserService handles users for the Jira instance / API. @@ -209,6 +211,38 @@ func (s *UserService) GetCurrentUser(ctx context.Context) (*User, *Response, err return &user, resp, nil } +// GetAllUsers returns a list of all users, including active users, inactive users and previously deleted users that have an Atlassian account. +// +// JIRA API docs: https://developer.atlassian.com/cloud/jira/platform/rest/v2/api-group-users/#api-rest-api-2-users-get +func (s *UserService) GetAllUsers(ctx context.Context, options *SearchOptions) ([]User, *Response, error) { + u := url.URL{ + Path: "rest/api/2/users", + } + uv := url.Values{} + if options != nil { + if options.StartAt != 0 { + uv.Add("startAt", strconv.Itoa(options.StartAt)) + } + if options.MaxResults != 0 { + uv.Add("maxResults", strconv.Itoa(options.MaxResults)) + } + } + u.RawQuery = uv.Encode() + + req, err := s.client.NewRequest(ctx, http.MethodGet, u.String(), nil) + if err != nil { + return nil, nil, err + } + + var users []User + resp, err := s.client.Do(req, &users) + if err != nil { + return nil, resp, NewJiraError(resp, err) + } + + return users, resp, nil +} + // WithMaxResults sets the max results to return func WithMaxResults(maxResults int) UserSearchF { return func(s UserSearch) UserSearch { @@ -268,7 +302,7 @@ func WithProperty(property string) UserSearchF { // Find searches for user info from Jira: // It can find users by email or display name using the query parameter // -// Jira API docs: https://developer.atlassian.com/cloud/jira/platform/rest/v2/#api-rest-api-2-user-search-get +// Jira API docs: https://developer.atlassian.com/cloud/jira/platform/rest/v2/api-group-user-search/#api-rest-api-2-user-search-get // // TODO Double check this method if this works as expected, is using the latest API and the response is complete // This double check effort is done for v2 - Remove this two lines if this is completed. diff --git a/cloud/user_test.go b/cloud/user_test.go index 7e5fdb26..210d5fa2 100644 --- a/cloud/user_test.go +++ b/cloud/user_test.go @@ -282,3 +282,48 @@ func TestUserService_Find_SuccessParams(t *testing.T) { t.Error("Expected user. User is nil") } } + +func TestUserService_GetAllUsers_SuccessParams(t *testing.T) { + setup() + defer teardown() + t.Run("no-params", func(t *testing.T) { + testMux.HandleFunc("/rest/api/2/users", func(w http.ResponseWriter, r *http.Request) { + testMethod(t, r, http.MethodGet) + testRequestURL(t, r, "/rest/api/2/users") + + fmt.Fprint(w, `[{"self":"http://www.example.com/jira/rest/api/2/users","key":"fred", + "name":"fred","emailAddress":"fred@example.com","avatarUrls":{"48x48":"http://www.example.com/jira/secure/useravatar?size=large&ownerId=fred", + "24x24":"http://www.example.com/jira/secure/useravatar?size=small&ownerId=fred","16x16":"http://www.example.com/jira/secure/useravatar?size=xsmall&ownerId=fred", + "32x32":"http://www.example.com/jira/secure/useravatar?size=medium&ownerId=fred"},"displayName":"Fred F. User","active":true,"timeZone":"Australia/Sydney","groups":{"size":3,"items":[ + {"name":"jira-user","self":"http://www.example.com/jira/rest/api/2/group?groupname=jira-user"},{"name":"jira-admin", + "self":"http://www.example.com/jira/rest/api/2/group?groupname=jira-admin"},{"name":"important","self":"http://www.example.com/jira/rest/api/2/group?groupname=important" + }]},"applicationRoles":{"size":1,"items":[]},"expand":"groups,applicationRoles"}]`) + }) + + if user, _, err := testClient.User.GetAllUsers(context.Background(), nil); err != nil { + t.Errorf("Error given: %s", err) + } else if user == nil { + t.Error("Expected user. User is nil") + } + }) + t.Run("with-params", func(t *testing.T) { + testMux.HandleFunc("/rest/api/2/users?maxResults=50&startAt=1", func(w http.ResponseWriter, r *http.Request) { + testMethod(t, r, http.MethodGet) + testRequestURL(t, r, "/rest/api/2/users?maxResults=50&startAt=1") + + fmt.Fprint(w, `[{"self":"http://www.example.com/jira/rest/api/2/users?maxResults=50&startAt=1","key":"fred", + "name":"fred","emailAddress":"fred@example.com","avatarUrls":{"48x48":"http://www.example.com/jira/secure/useravatar?size=large&ownerId=fred", + "24x24":"http://www.example.com/jira/secure/useravatar?size=small&ownerId=fred","16x16":"http://www.example.com/jira/secure/useravatar?size=xsmall&ownerId=fred", + "32x32":"http://www.example.com/jira/secure/useravatar?size=medium&ownerId=fred"},"displayName":"Fred F. User","active":true,"timeZone":"Australia/Sydney","groups":{"size":3,"items":[ + {"name":"jira-user","self":"http://www.example.com/jira/rest/api/2/group?groupname=jira-user"},{"name":"jira-admin", + "self":"http://www.example.com/jira/rest/api/2/group?groupname=jira-admin"},{"name":"important","self":"http://www.example.com/jira/rest/api/2/group?groupname=important" + }]},"applicationRoles":{"size":1,"items":[]},"expand":"groups,applicationRoles"}]`) + }) + + if user, _, err := testClient.User.GetAllUsers(context.Background(), &SearchOptions{StartAt: 1, MaxResults: 50}); err != nil { + t.Errorf("Error given: %s", err) + } else if user == nil { + t.Error("Expected user. User is nil") + } + }) +}