diff --git a/descope/internal/mgmt/user.go b/descope/internal/mgmt/user.go index 954bfacb..5e9207ef 100644 --- a/descope/internal/mgmt/user.go +++ b/descope/internal/mgmt/user.go @@ -12,18 +12,18 @@ type user struct { managementBase } -func (u *user) Create(loginID string, user *descope.UserRequest) (*descope.UserResponse, error) { +func (u *user) Create(loginID string, user *descope.CreateUserRequest) (*descope.UserResponse, error) { if user == nil { - user = &descope.UserRequest{} + user = &descope.CreateUserRequest{} } - return u.create(loginID, user.Email, user.Phone, user.Name, user.Picture, user.Roles, user.Tenants, false, false, user.CustomAttributes, user.VerifiedEmail, user.VerifiedPhone, nil) + return u.create(loginID, user.Email, user.Phone, user.Name, user.Picture, user.Roles, user.Tenants, false, false, user.CustomAttributes, user.VerifiedEmail, user.VerifiedPhone, user.AdditionalLoginIDs, nil) } -func (u *user) CreateTestUser(loginID string, user *descope.UserRequest) (*descope.UserResponse, error) { +func (u *user) CreateTestUser(loginID string, user *descope.CreateUserRequest) (*descope.UserResponse, error) { if user == nil { - user = &descope.UserRequest{} + user = &descope.CreateUserRequest{} } - return u.create(loginID, user.Email, user.Phone, user.Name, user.Picture, user.Roles, user.Tenants, false, true, user.CustomAttributes, user.VerifiedEmail, user.VerifiedPhone, nil) + return u.create(loginID, user.Email, user.Phone, user.Name, user.Picture, user.Roles, user.Tenants, false, true, user.CustomAttributes, user.VerifiedEmail, user.VerifiedPhone, user.AdditionalLoginIDs, nil) } func (u *user) CreateBatch(users []*descope.BatchUser) (*descope.UsersBatchResponse, error) { @@ -33,11 +33,11 @@ func (u *user) CreateBatch(users []*descope.BatchUser) (*descope.UsersBatchRespo return u.createBatch(users, nil) } -func (u *user) Invite(loginID string, user *descope.UserRequest, options *descope.InviteOptions) (*descope.UserResponse, error) { +func (u *user) Invite(loginID string, user *descope.CreateUserRequest, options *descope.InviteOptions) (*descope.UserResponse, error) { if user == nil { - user = &descope.UserRequest{} + user = &descope.CreateUserRequest{} } - return u.create(loginID, user.Email, user.Phone, user.Name, user.Picture, user.Roles, user.Tenants, true, false, user.CustomAttributes, user.VerifiedEmail, user.VerifiedPhone, options) + return u.create(loginID, user.Email, user.Phone, user.Name, user.Picture, user.Roles, user.Tenants, true, false, user.CustomAttributes, user.VerifiedEmail, user.VerifiedPhone, user.AdditionalLoginIDs, options) } func (u *user) InviteBatch(users []*descope.BatchUser, options *descope.InviteOptions) (*descope.UsersBatchResponse, error) { @@ -47,11 +47,11 @@ func (u *user) InviteBatch(users []*descope.BatchUser, options *descope.InviteOp return u.createBatch(users, options) } -func (u *user) create(loginID, email, phone, displayName, picture string, roles []string, tenants []*descope.AssociatedTenant, invite, test bool, customAttributes map[string]any, verifiedEmail *bool, verifiedPhone *bool, options *descope.InviteOptions) (*descope.UserResponse, error) { +func (u *user) create(loginID, email, phone, displayName, picture string, roles []string, tenants []*descope.AssociatedTenant, invite, test bool, customAttributes map[string]any, verifiedEmail *bool, verifiedPhone *bool, additionalLoginIDs []string, options *descope.InviteOptions) (*descope.UserResponse, error) { if loginID == "" { return nil, utils.NewInvalidArgumentError("loginID") } - req := makeCreateUserRequest(loginID, email, phone, displayName, picture, roles, tenants, invite, test, customAttributes, verifiedEmail, verifiedPhone, options) + req := makeCreateUserRequest(loginID, email, phone, displayName, picture, roles, tenants, invite, test, customAttributes, verifiedEmail, verifiedPhone, additionalLoginIDs, options) res, err := u.client.DoPostRequest(api.Routes.ManagementUserCreate(), req, nil, u.conf.ManagementKey) if err != nil { return nil, err @@ -455,9 +455,10 @@ func (u *user) GenerateEmbeddedLink(loginID string, customClaims map[string]any) return tRes.Token, nil } -func makeCreateUserRequest(loginID, email, phone, displayName, picture string, roles []string, tenants []*descope.AssociatedTenant, invite, test bool, customAttributes map[string]any, verifiedEmail *bool, verifiedPhone *bool, options *descope.InviteOptions) map[string]any { +func makeCreateUserRequest(loginID, email, phone, displayName, picture string, roles []string, tenants []*descope.AssociatedTenant, invite, test bool, customAttributes map[string]any, verifiedEmail *bool, verifiedPhone *bool, additionalLoginIDs []string, options *descope.InviteOptions) map[string]any { req := makeUpdateUserRequest(loginID, email, phone, displayName, picture, roles, tenants, customAttributes, verifiedEmail, verifiedPhone) req["invite"] = invite + req["additionalLoginIds"] = additionalLoginIDs if test { req["test"] = true } diff --git a/descope/internal/mgmt/user_test.go b/descope/internal/mgmt/user_test.go index 310b3cb5..84a40b2e 100644 --- a/descope/internal/mgmt/user_test.go +++ b/descope/internal/mgmt/user_test.go @@ -38,7 +38,7 @@ func TestUserCreateSuccess(t *testing.T) { } i++ }, response)) - user := &descope.UserRequest{} + user := &descope.CreateUserRequest{} user.Email = "foo@bar.com" user.Roles = []string{"foo"} user.CustomAttributes = ca @@ -81,7 +81,7 @@ func TestUserCreateSuccessWithOptions(t *testing.T) { assert.Nil(t, req["sendMail"]) assert.Nil(t, req["sendSMS"]) }, response)) - user := &descope.UserRequest{} + user := &descope.CreateUserRequest{} user.Email = "foo@bar.com" user.Roles = []string{"foo"} user.CustomAttributes = ca @@ -213,7 +213,7 @@ func TestUserCreateTestUserSuccess(t *testing.T) { require.Equal(t, "foo", roleNames[0]) require.EqualValues(t, true, req["test"]) }, response)) - user := &descope.UserRequest{} + user := &descope.CreateUserRequest{} user.Email = "foo@bar.com" user.Roles = []string{"foo"} res, err := m.User().CreateTestUser("abc", user) @@ -224,7 +224,7 @@ func TestUserCreateTestUserSuccess(t *testing.T) { func TestUserCreateError(t *testing.T) { m := newTestMgmt(nil, helpers.DoOk(nil)) - user := &descope.UserRequest{} + user := &descope.CreateUserRequest{} user.Email = "foo@bar.com" _, err := m.User().Create("", user) require.Error(t, err) @@ -1318,7 +1318,7 @@ func TestUserCreateWithVerifiedEmailUserSuccess(t *testing.T) { require.EqualValues(t, true, req["test"]) require.EqualValues(t, true, req["verifiedEmail"]) }, response)) - user := &descope.UserRequest{} + user := &descope.CreateUserRequest{} user.Email = "foo@bar.com" tr := true user.VerifiedEmail = &tr @@ -1346,7 +1346,7 @@ func TestUserCreateWithVerifiedPhoneUserSuccess(t *testing.T) { require.EqualValues(t, true, req["test"]) require.EqualValues(t, false, req["verifiedPhone"]) }, response)) - user := &descope.UserRequest{} + user := &descope.CreateUserRequest{} user.Email = "foo@bar.com" tr := false user.VerifiedPhone = &tr diff --git a/descope/sdk/mgmt.go b/descope/sdk/mgmt.go index 98fbdbaf..a538dc01 100644 --- a/descope/sdk/mgmt.go +++ b/descope/sdk/mgmt.go @@ -57,7 +57,7 @@ type User interface { // aren't associated with a tenant, while the tenants parameter can be used // to specify which tenants to associate the user with and what roles the // user has in each one. - Create(loginID string, user *descope.UserRequest) (*descope.UserResponse, error) + Create(loginID string, user *descope.CreateUserRequest) (*descope.UserResponse, error) // Create a new test user. // @@ -68,7 +68,7 @@ type User interface { // You can later generate OTP, Magic link and enchanted link to use in the test without the need // of 3rd party messaging services // Those users are not counted as part of the monthly active users - CreateTestUser(loginID string, user *descope.UserRequest) (*descope.UserResponse, error) + CreateTestUser(loginID string, user *descope.CreateUserRequest) (*descope.UserResponse, error) // Create users in batch. // @@ -85,7 +85,7 @@ type User interface { // the email / phone is explicitly set, or the loginID itself is an email address / phone number. // You must configure the invitation URL in the Descope console prior to // calling the method. - Invite(loginID string, user *descope.UserRequest, options *descope.InviteOptions) (*descope.UserResponse, error) + Invite(loginID string, user *descope.CreateUserRequest, options *descope.InviteOptions) (*descope.UserResponse, error) // Create users in batch and invite them via an email / text message. // diff --git a/descope/tests/mocks/mgmt/managementmock.go b/descope/tests/mocks/mgmt/managementmock.go index 8de8a6b7..ea95c914 100644 --- a/descope/tests/mocks/mgmt/managementmock.go +++ b/descope/tests/mocks/mgmt/managementmock.go @@ -141,11 +141,11 @@ func (m *MockSSO) ConfigureMapping(tenantID string, roleMappings []*descope.Role // Mock User type MockUser struct { - CreateAssert func(loginID string, user *descope.UserRequest) + CreateAssert func(loginID string, user *descope.CreateUserRequest) CreateResponse *descope.UserResponse CreateError error - CreateTestUserAssert func(loginID string, user *descope.UserRequest) + CreateTestUserAssert func(loginID string, user *descope.CreateUserRequest) CreateTestUserResponse *descope.UserResponse CreateTestUserError error @@ -153,7 +153,7 @@ type MockUser struct { CreateBatchResponse *descope.UsersBatchResponse CreateBatchError error - InviteAssert func(loginID string, user *descope.UserRequest, options *descope.InviteOptions) + InviteAssert func(loginID string, user *descope.CreateUserRequest, options *descope.InviteOptions) InviteResponse *descope.UserResponse InviteError error @@ -270,14 +270,14 @@ type MockUser struct { LogoutError error } -func (m *MockUser) Create(loginID string, user *descope.UserRequest) (*descope.UserResponse, error) { +func (m *MockUser) Create(loginID string, user *descope.CreateUserRequest) (*descope.UserResponse, error) { if m.CreateAssert != nil { m.CreateAssert(loginID, user) } return m.CreateResponse, m.CreateError } -func (m *MockUser) CreateTestUser(loginID string, user *descope.UserRequest) (*descope.UserResponse, error) { +func (m *MockUser) CreateTestUser(loginID string, user *descope.CreateUserRequest) (*descope.UserResponse, error) { if m.CreateTestUserAssert != nil { m.CreateTestUserAssert(loginID, user) } @@ -291,7 +291,7 @@ func (m *MockUser) CreateBatch(users []*descope.BatchUser) (*descope.UsersBatchR return m.CreateBatchResponse, m.CreateBatchError } -func (m *MockUser) Invite(loginID string, user *descope.UserRequest, options *descope.InviteOptions) (*descope.UserResponse, error) { +func (m *MockUser) Invite(loginID string, user *descope.CreateUserRequest, options *descope.InviteOptions) (*descope.UserResponse, error) { if m.InviteAssert != nil { m.InviteAssert(loginID, user, options) } diff --git a/descope/tests/mocks/mgmt/managementmock_test.go b/descope/tests/mocks/mgmt/managementmock_test.go index 59e23d06..38495264 100644 --- a/descope/tests/mocks/mgmt/managementmock_test.go +++ b/descope/tests/mocks/mgmt/managementmock_test.go @@ -16,7 +16,7 @@ func TestMockManagement(t *testing.T) { descopeClient := client.DescopeClient{ Management: &MockManagement{ MockUser: &MockUser{ - CreateAssert: func(loginID string, user *descope.UserRequest) { + CreateAssert: func(loginID string, user *descope.CreateUserRequest) { called = true assert.EqualValues(t, expectedLoginID, loginID) }, @@ -26,7 +26,7 @@ func TestMockManagement(t *testing.T) { }, } assert.NotNil(t, descopeClient.Management) - r, err := descopeClient.Management.User().Create(expectedLoginID, &descope.UserRequest{}) + r, err := descopeClient.Management.User().Create(expectedLoginID, &descope.CreateUserRequest{}) require.NoError(t, err) assert.EqualValues(t, expectedLoginID, r.UserID) assert.True(t, called) diff --git a/descope/types.go b/descope/types.go index 37b9d5f2..2c63b7ef 100644 --- a/descope/types.go +++ b/descope/types.go @@ -282,6 +282,11 @@ type UserRequest struct { VerifiedPhone *bool `json:"verifiedPhone,omitempty"` } +type CreateUserRequest struct { + UserRequest `json:",inline"` + AdditionalLoginIDs []string `json:"additionalLoginIds,omitempty"` +} + type BatchUser struct { LoginID string `json:"loginId,omitempty"` Password *BatchUserPassword `json:"password,omitempty"` diff --git a/examples/managementcli/main.go b/examples/managementcli/main.go index 073b416a..bcf3b7d3 100644 --- a/examples/managementcli/main.go +++ b/examples/managementcli/main.go @@ -55,7 +55,7 @@ func userCreate(args []string) error { for _, tenantID := range flags.Tenants { tenants = append(tenants, &descope.AssociatedTenant{TenantID: tenantID}) } - user := &descope.UserRequest{} + user := &descope.CreateUserRequest{} user.Email = "foo@bar.com" user.Phone = flags.Phone user.Name = flags.Name