Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Adjust and add test user functionality #473

Merged
merged 7 commits into from
Nov 18, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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",
guyp-descope marked this conversation as resolved.
Show resolved Hide resolved
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": "[email protected]",
"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{"[email protected]"}, req["emails"])
}, response))
res, _, err := m.User().SearchAllTestUsers(context.Background(), &descope.UserSearchOptions{
Emails: []string{"[email protected]"},
})
require.NoError(t, err)
require.NotNil(t, res)
require.Len(t, res, 1)
require.Equal(t, "[email protected]", res[0].Email)
require.Equal(t, true, res[0].Test)
}

func TestSearchAllTestUsersSuccessEmptyOptions(t *testing.T) {
response := map[string]any{
"users": []map[string]any{{
"email": "[email protected]",
"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, "[email protected]", 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
guyp-descope marked this conversation as resolved.
Show resolved Hide resolved
//
// 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
Loading