Skip to content

Commit

Permalink
Adjust and add test user functionality (#473)
Browse files Browse the repository at this point in the history
* Adjust and add test user functionality

* fix pr issues

* update README file

* fixed usage for test user search
  • Loading branch information
guyp-descope authored Nov 18, 2024
1 parent faeb1a2 commit 29a36b2
Show file tree
Hide file tree
Showing 6 changed files with 132 additions and 2 deletions.
9 changes: 9 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -1614,6 +1614,15 @@ user, err := descopeClient.Management.User().CreateTestUser(context.Background()
{TenantID: "tenant-ID2"},
})
// Search all test users, optionally according to tenant and/or role filter
// Results can be paginated using the limit and page parameters
usersResp, total, err := descopeClient.Management.User().SearchAllTestUsers(context.Background(), &descope.UserSearchOptions{TenantIDs: []string{"my-tenant-id"}})
if err == nil {
for _, user := range usersResp {
// Do something
}
}
// Now test user got created, and this user will be available until you delete it,
// you can use any management operation for test user CRUD.
// You can also delete all test users.
Expand Down
12 changes: 12 additions & 0 deletions descope/api/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,7 @@ var (
ssoApplicationLoad: "mgmt/sso/idp/app/load",
ssoApplicationLoadAll: "mgmt/sso/idp/apps/load",
userCreate: "mgmt/user/create",
testUserCreate: "mgmt/user/create/test",
userCreateBatch: "mgmt/user/create/batch",
userUpdate: "mgmt/user/update",
userPatch: "mgmt/user/patch",
Expand All @@ -109,6 +110,7 @@ var (
userImport: "mgmt/user/import",
userLoad: "mgmt/user",
userSearchAll: "mgmt/user/search",
testUserSearchAll: "mgmt/user/search/test",
userUpdateStatus: "mgmt/user/update/status",
userUpdateLoginID: "mgmt/user/update/loginid",
userUpdateEmail: "mgmt/user/update/email",
Expand Down Expand Up @@ -300,6 +302,7 @@ type mgmtEndpoints struct {
ssoApplicationLoadAll string

userCreate string
testUserCreate string
userCreateBatch string
userUpdate string
userPatch string
Expand All @@ -308,6 +311,7 @@ type mgmtEndpoints struct {
userImport string
userLoad string
userSearchAll string
testUserSearchAll string
userUpdateStatus string
userUpdateLoginID string
userUpdateEmail string
Expand Down Expand Up @@ -709,6 +713,10 @@ func (e *endpoints) ManagementUserCreate() string {
return path.Join(e.version, e.mgmt.userCreate)
}

func (e *endpoints) ManagementTestUserCreate() string {
return path.Join(e.version, e.mgmt.testUserCreate)
}

func (e *endpoints) ManagementUserCreateBatch() string {
return path.Join(e.version, e.mgmt.userCreateBatch)
}
Expand Down Expand Up @@ -741,6 +749,10 @@ func (e *endpoints) ManagementUserSearchAll() string {
return path.Join(e.versionV2, e.mgmt.userSearchAll)
}

func (e *endpoints) ManagementTestUserSearchAll() string {
return path.Join(e.versionV2, e.mgmt.testUserSearchAll)
}

func (e *endpoints) ManagementUserUpdateStatus() string {
return path.Join(e.version, e.mgmt.userUpdateStatus)
}
Expand Down
32 changes: 30 additions & 2 deletions descope/internal/mgmt/user.go
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,14 @@ func (u *user) create(ctx context.Context, loginID, email, phone, displayName, g
ssoAppIDs: ssoAppIDs,
})

res, err := u.client.DoPostRequest(ctx, api.Routes.ManagementUserCreate(), req, nil, u.conf.ManagementKey)
var res *api.HTTPResponse
var err error
if test {
res, err = u.client.DoPostRequest(ctx, api.Routes.ManagementTestUserCreate(), req, nil, u.conf.ManagementKey)
} else {
res, err = u.client.DoPostRequest(ctx, api.Routes.ManagementUserCreate(), req, nil, u.conf.ManagementKey)
}

if err != nil {
return nil, err
}
Expand Down Expand Up @@ -234,6 +241,20 @@ func (u *user) load(ctx context.Context, loginID, userID string) (*descope.UserR
}

func (u *user) SearchAll(ctx context.Context, options *descope.UserSearchOptions) ([]*descope.UserResponse, int, error) {
return u.searchAll(ctx, options, false)
}

func (u *user) SearchAllTestUsers(ctx context.Context, options *descope.UserSearchOptions) ([]*descope.UserResponse, int, error) {
// Init empty options if non given
if options == nil {
options = &descope.UserSearchOptions{}
}
options.WithTestUsers = true
options.TestUsersOnly = true
return u.searchAll(ctx, options, true)
}

func (u *user) searchAll(ctx context.Context, options *descope.UserSearchOptions, useTestEndpoint bool) ([]*descope.UserResponse, int, error) {
// Init empty options if non given
if options == nil {
options = &descope.UserSearchOptions{}
Expand All @@ -250,7 +271,14 @@ func (u *user) SearchAll(ctx context.Context, options *descope.UserSearchOptions
}

req := makeSearchAllRequest(options)
res, err := u.client.DoPostRequest(ctx, api.Routes.ManagementUserSearchAll(), req, nil, u.conf.ManagementKey)

var res *api.HTTPResponse
var err error
if useTestEndpoint {
res, err = u.client.DoPostRequest(ctx, api.Routes.ManagementTestUserSearchAll(), req, nil, u.conf.ManagementKey)
} else {
res, err = u.client.DoPostRequest(ctx, api.Routes.ManagementUserSearchAll(), req, nil, u.conf.ManagementKey)
}
if err != nil {
return nil, 0, err
}
Expand Down
61 changes: 61 additions & 0 deletions descope/internal/mgmt/user_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@ func TestUserCreateSuccess(t *testing.T) {
i := 0
m := newTestMgmt(nil, helpers.DoOkWithBody(func(r *http.Request) {
require.Equal(t, r.Header.Get("Authorization"), "Bearer a:key")
require.NotNil(t, r.URL)
require.Equal(t, "/v1/mgmt/user/create", r.URL.Path)
req := map[string]any{}
require.NoError(t, helpers.ReadBody(r, &req))
require.Equal(t, "abc", req["loginId"])
Expand Down Expand Up @@ -245,6 +247,8 @@ func TestUserCreateTestUserSuccess(t *testing.T) {
}}
m := newTestMgmt(nil, helpers.DoOkWithBody(func(r *http.Request) {
require.Equal(t, r.Header.Get("Authorization"), "Bearer a:key")
require.NotNil(t, r.URL)
require.Equal(t, "/v1/mgmt/user/create/test", r.URL.Path)
req := map[string]any{}
require.NoError(t, helpers.ReadBody(r, &req))
require.Equal(t, "abc", req["loginId"])
Expand Down Expand Up @@ -730,6 +734,8 @@ func TestSearchAllUsersSuccess(t *testing.T) {
roleNames := []string{"role1"}
m := newTestMgmt(nil, helpers.DoOkWithBody(func(r *http.Request) {
require.Equal(t, r.Header.Get("Authorization"), "Bearer a:key")
require.NotNil(t, r.URL)
require.Equal(t, "/v2/mgmt/user/search", r.URL.Path)
req := map[string]any{}
require.NoError(t, helpers.ReadBody(r, &req))
require.EqualValues(t, tenantIDs[0], req["tenantIds"].([]any)[0])
Expand Down Expand Up @@ -764,6 +770,61 @@ func TestSearchAllUsersSuccess(t *testing.T) {
require.Equal(t, 85, total)
}

func TestSearchAllTestUsersSuccess(t *testing.T) {
response := map[string]any{
"users": []map[string]any{{
"email": "a@b.c",
"test": true,
}},
"total": 85,
}

m := newTestMgmt(nil, helpers.DoOkWithBody(func(r *http.Request) {
require.Equal(t, r.Header.Get("Authorization"), "Bearer a:key")
require.NotNil(t, r.URL)
require.Equal(t, "/v2/mgmt/user/search/test", r.URL.Path)
req := map[string]any{}
require.NoError(t, helpers.ReadBody(r, &req))
require.EqualValues(t, true, req["testUsersOnly"].(bool))
require.EqualValues(t, true, req["withTestUser"].(bool))
require.EqualValues(t, []any{"a@b.com"}, req["emails"])
}, response))
res, _, err := m.User().SearchAllTestUsers(context.Background(), &descope.UserSearchOptions{
Emails: []string{"a@b.com"},
})
require.NoError(t, err)
require.NotNil(t, res)
require.Len(t, res, 1)
require.Equal(t, "a@b.c", res[0].Email)
require.Equal(t, true, res[0].Test)
}

func TestSearchAllTestUsersSuccessEmptyOptions(t *testing.T) {
response := map[string]any{
"users": []map[string]any{{
"email": "a@b.c",
"test": true,
}},
"total": 85,
}

m := newTestMgmt(nil, helpers.DoOkWithBody(func(r *http.Request) {
require.Equal(t, r.Header.Get("Authorization"), "Bearer a:key")
require.NotNil(t, r.URL)
require.Equal(t, "/v2/mgmt/user/search/test", r.URL.Path)
req := map[string]any{}
require.NoError(t, helpers.ReadBody(r, &req))
require.EqualValues(t, true, req["testUsersOnly"].(bool))
require.EqualValues(t, true, req["withTestUser"].(bool))
}, response))
res, _, err := m.User().SearchAllTestUsers(context.Background(), nil)
require.NoError(t, err)
require.NotNil(t, res)
require.Len(t, res, 1)
require.Equal(t, "a@b.c", res[0].Email)
require.Equal(t, true, res[0].Test)
}

func TestSearchAllUsersError(t *testing.T) {
m := newTestMgmt(nil, helpers.DoBadRequest(nil))
res, total, err := m.User().SearchAll(context.Background(), nil)
Expand Down
8 changes: 8 additions & 0 deletions descope/sdk/mgmt.go
Original file line number Diff line number Diff line change
Expand Up @@ -241,6 +241,14 @@ type User interface {
// Returns slice of users and total number of users for the query
SearchAll(ctx context.Context, options *descope.UserSearchOptions) ([]*descope.UserResponse, int, error)

// Search all test users according to given filters
//
// The options optional parameter allows to fine-tune the search filters
// and results. Using nil will result in a filter-less query with a set amount of
// results.
// Returns slice of users and total number of users for the query
SearchAllTestUsers(ctx context.Context, options *descope.UserSearchOptions) ([]*descope.UserResponse, int, error)

// Activate an existing user.
Activate(ctx context.Context, loginID string) (*descope.UserResponse, error)

Expand Down
12 changes: 12 additions & 0 deletions descope/tests/mocks/mgmt/managementmock.go
Original file line number Diff line number Diff line change
Expand Up @@ -283,6 +283,11 @@ type MockUser struct {
SearchAllTotalResponse int
SearchAllError error

SearchAllTestUsersAssert func(options *descope.UserSearchOptions)
SearchAllTestUsersResponse []*descope.UserResponse
SearchAllTestUsersTotalResponse int
SearchAllTestUsersError error

ActivateAssert func(loginID string)
ActivateResponse *descope.UserResponse
ActivateError error
Expand Down Expand Up @@ -517,6 +522,13 @@ func (m *MockUser) SearchAll(_ context.Context, options *descope.UserSearchOptio
return m.SearchAllResponse, m.SearchAllTotalResponse, m.SearchAllError
}

func (m *MockUser) SearchAllTestUsers(_ context.Context, options *descope.UserSearchOptions) ([]*descope.UserResponse, int, error) {
if m.SearchAllTestUsersAssert != nil {
m.SearchAllTestUsersAssert(options)
}
return m.SearchAllTestUsersResponse, m.SearchAllTestUsersTotalResponse, m.SearchAllTestUsersError
}

func (m *MockUser) Activate(_ context.Context, loginID string) (*descope.UserResponse, error) {
if m.ActivateAssert != nil {
m.ActivateAssert(loginID)
Expand Down

0 comments on commit 29a36b2

Please sign in to comment.