feat: ResetPassword endpoint

This commit is contained in:
Stefan Benz
2024-09-24 20:42:20 +02:00
parent 04f5ed8d1c
commit 50e0c758de
17 changed files with 1275 additions and 89 deletions

View File

@@ -210,6 +210,7 @@ func TestCommands_CreateDebugEvents(t *testing.T) {
}},
want: &domain.ObjectDetails{
ResourceOwner: "instance1",
ID: "dgb1",
},
},
{
@@ -243,6 +244,7 @@ func TestCommands_CreateDebugEvents(t *testing.T) {
}},
want: &domain.ObjectDetails{
ResourceOwner: "instance1",
ID: "dgb1",
},
},
{
@@ -275,6 +277,7 @@ func TestCommands_CreateDebugEvents(t *testing.T) {
}},
want: &domain.ObjectDetails{
ResourceOwner: "instance1",
ID: "dgb1",
},
},
{
@@ -324,6 +327,7 @@ func TestCommands_CreateDebugEvents(t *testing.T) {
}},
want: &domain.ObjectDetails{
ResourceOwner: "instance1",
ID: "dgb1",
},
},
}

View File

@@ -64,6 +64,7 @@ func TestCommands_SetInstanceFeatures(t *testing.T) {
}},
want: &domain.ObjectDetails{
ResourceOwner: "instance1",
ID: "instance1",
},
},
{
@@ -93,6 +94,7 @@ func TestCommands_SetInstanceFeatures(t *testing.T) {
}},
want: &domain.ObjectDetails{
ResourceOwner: "instance1",
ID: "instance1",
},
},
{
@@ -111,6 +113,7 @@ func TestCommands_SetInstanceFeatures(t *testing.T) {
}},
want: &domain.ObjectDetails{
ResourceOwner: "instance1",
ID: "instance1",
},
},
{
@@ -129,6 +132,7 @@ func TestCommands_SetInstanceFeatures(t *testing.T) {
}},
want: &domain.ObjectDetails{
ResourceOwner: "instance1",
ID: "instance1",
},
},
{
@@ -147,6 +151,7 @@ func TestCommands_SetInstanceFeatures(t *testing.T) {
}},
want: &domain.ObjectDetails{
ResourceOwner: "instance1",
ID: "instance1",
},
},
{
@@ -165,6 +170,7 @@ func TestCommands_SetInstanceFeatures(t *testing.T) {
}},
want: &domain.ObjectDetails{
ResourceOwner: "instance1",
ID: "instance1",
},
},
{
@@ -224,6 +230,7 @@ func TestCommands_SetInstanceFeatures(t *testing.T) {
}},
want: &domain.ObjectDetails{
ResourceOwner: "instance1",
ID: "instance1",
},
},
{
@@ -275,6 +282,7 @@ func TestCommands_SetInstanceFeatures(t *testing.T) {
}},
want: &domain.ObjectDetails{
ResourceOwner: "instance1",
ID: "instance1",
},
},
}

View File

@@ -61,6 +61,7 @@ func TestCommands_SetSystemFeatures(t *testing.T) {
}},
want: &domain.ObjectDetails{
ResourceOwner: "SYSTEM",
ID: "SYSTEM",
},
},
{
@@ -79,6 +80,7 @@ func TestCommands_SetSystemFeatures(t *testing.T) {
}},
want: &domain.ObjectDetails{
ResourceOwner: "SYSTEM",
ID: "SYSTEM",
},
},
{
@@ -97,6 +99,7 @@ func TestCommands_SetSystemFeatures(t *testing.T) {
}},
want: &domain.ObjectDetails{
ResourceOwner: "SYSTEM",
ID: "SYSTEM",
},
},
{
@@ -115,6 +118,7 @@ func TestCommands_SetSystemFeatures(t *testing.T) {
}},
want: &domain.ObjectDetails{
ResourceOwner: "SYSTEM",
ID: "SYSTEM",
},
},
{
@@ -133,6 +137,7 @@ func TestCommands_SetSystemFeatures(t *testing.T) {
}},
want: &domain.ObjectDetails{
ResourceOwner: "SYSTEM",
ID: "SYSTEM",
},
},
{
@@ -192,6 +197,7 @@ func TestCommands_SetSystemFeatures(t *testing.T) {
}},
want: &domain.ObjectDetails{
ResourceOwner: "SYSTEM",
ID: "SYSTEM",
},
},
{
@@ -253,6 +259,7 @@ func TestCommands_SetSystemFeatures(t *testing.T) {
}},
want: &domain.ObjectDetails{
ResourceOwner: "SYSTEM",
ID: "SYSTEM",
},
},
}

View File

@@ -59,6 +59,7 @@ func (c *Commands) SetSchemaUserPassword(ctx context.Context, user *SetSchemaUse
return nil, err
}
resourceOwner := existing.ResourceOwner
// when no password was set yet
if existing.EncodedHash == "" {
existingUser, err := c.getSchemaUserExists(ctx, user.ResourceOwner, user.UserID)
if err != nil {
@@ -79,7 +80,7 @@ func (c *Commands) SetSchemaUserPassword(ctx context.Context, user *SetSchemaUse
}
encodedPassword := schemaUser.EncodedPasswordHash
if user.Password != "" {
if encodedPassword == "" && user.Password != "" {
encodedPassword, err = c.userPasswordHasher.Hash(user.Password)
if err = convertPasswapErr(err); err != nil {
return nil, err

View File

@@ -5,9 +5,7 @@ import (
"github.com/zitadel/zitadel/internal/crypto"
"github.com/zitadel/zitadel/internal/eventstore"
"github.com/zitadel/zitadel/internal/repository/user"
"github.com/zitadel/zitadel/internal/repository/user/authenticator"
"github.com/zitadel/zitadel/internal/repository/user/schemauser"
)
type PasswordV3WriteModel struct {
@@ -45,7 +43,7 @@ func (wm *PasswordV3WriteModel) Reduce() error {
wm.EncodedHash = ""
wm.ChangeRequired = false
wm.Code = nil
case *user.HumanPasswordCodeAddedEvent:
case *authenticator.PasswordCodeAddedEvent:
wm.Code = e.Code
wm.CodeCreationDate = e.CreationDate()
wm.CodeExpiry = e.Expiry
@@ -58,7 +56,7 @@ func (wm *PasswordV3WriteModel) Query() *eventstore.SearchQueryBuilder {
return eventstore.NewSearchQueryBuilder(eventstore.ColumnsEvent).
ResourceOwner(wm.ResourceOwner).
AddQuery().
AggregateTypes(schemauser.AggregateType).
AggregateTypes(authenticator.AggregateType).
AggregateIDs(wm.AggregateID).
EventTypes(
authenticator.PasswordCreatedType,

View File

@@ -4,8 +4,11 @@ import (
"context"
"errors"
"testing"
"time"
"github.com/stretchr/testify/assert"
"github.com/zitadel/passwap"
"go.uber.org/mock/gomock"
"github.com/zitadel/zitadel/internal/api/authz"
"github.com/zitadel/zitadel/internal/crypto"
@@ -50,6 +53,7 @@ func TestCommands_SetSchemaUserPassword(t *testing.T) {
eventstore func(t *testing.T) *eventstore.Eventstore
userPasswordHasher *crypto.Hasher
checkPermission domain.PermissionCheck
codeAlg crypto.EncryptionAlgorithm
}
type args struct {
ctx context.Context
@@ -117,7 +121,7 @@ func TestCommands_SetSchemaUserPassword(t *testing.T) {
},
res{
err: func(err error) bool {
return errors.Is(err, zerrors.ThrowNotFound(nil, "TODO", "TODO"))
return errors.Is(err, zerrors.ThrowNotFound(nil, "COMMAND-TODO", "Errors.User.Password.NotFound"))
},
},
},
@@ -176,6 +180,39 @@ func TestCommands_SetSchemaUserPassword(t *testing.T) {
},
},
},
{
"password set, complexity failed",
fields{
eventstore: expectEventstore(
filterSchemaUserPasswordExisting(),
filterPasswordComplexityPolicyExisting(),
expectPush(
authenticator.NewPasswordCreatedEvent(
context.Background(),
&authenticator.NewAggregate("user1", "org1").Aggregate,
"user1",
"$plain$x$password",
false,
),
),
),
checkPermission: newMockPermissionCheckAllowed(),
userPasswordHasher: mockPasswordHasher("x"),
},
args{
ctx: authz.NewMockContext("instanceID", "", ""),
user: &SetSchemaUserPassword{
UserID: "user1",
Password: "password",
ChangeRequired: false,
},
},
res{
details: &domain.ObjectDetails{
ResourceOwner: "org1",
},
},
},
{
"password set, ok",
fields{
@@ -242,6 +279,40 @@ func TestCommands_SetSchemaUserPassword(t *testing.T) {
},
},
},
{
"password set, encoded, ok",
fields{
eventstore: expectEventstore(
filterSchemaUserPasswordExisting(),
filterPasswordComplexityPolicyExisting(),
expectPush(
authenticator.NewPasswordCreatedEvent(
context.Background(),
&authenticator.NewAggregate("user1", "org1").Aggregate,
"user1",
"$plain$x$password2",
false,
),
),
),
checkPermission: newMockPermissionCheckAllowed(),
userPasswordHasher: mockPasswordHasher("x"),
},
args{
ctx: authz.NewMockContext("instanceID", "", ""),
user: &SetSchemaUserPassword{
UserID: "user1",
Password: "passwordnotused",
EncodedPasswordHash: "$plain$x$password2",
ChangeRequired: false,
},
},
res{
details: &domain.ObjectDetails{
ResourceOwner: "org1",
},
},
},
{
"password set, current password, ok",
fields{
@@ -258,7 +329,6 @@ func TestCommands_SetSchemaUserPassword(t *testing.T) {
),
),
),
checkPermission: newMockPermissionCheckNotAllowed(),
userPasswordHasher: mockPasswordHasher("x"),
},
args{
@@ -277,7 +347,7 @@ func TestCommands_SetSchemaUserPassword(t *testing.T) {
},
},
{
"password set, code, ok",
"password set, current password, ok",
fields{
eventstore: expectEventstore(
filterSchemaUserPasswordExisting(),
@@ -292,15 +362,15 @@ func TestCommands_SetSchemaUserPassword(t *testing.T) {
),
),
),
checkPermission: newMockPermissionCheckNotAllowed(),
userPasswordHasher: mockPasswordHasher("x"),
},
args{
ctx: authz.NewMockContext("instanceID", "", ""),
user: &SetSchemaUserPassword{
UserID: "user1",
Password: "password2",
ChangeRequired: false,
UserID: "user1",
Password: "password2",
CurrentPassword: "password",
ChangeRequired: false,
},
},
res{
@@ -308,6 +378,160 @@ func TestCommands_SetSchemaUserPassword(t *testing.T) {
ResourceOwner: "org1",
},
},
}, {
"password set, current password, failed",
fields{
eventstore: expectEventstore(
filterSchemaUserPasswordExisting(),
),
userPasswordHasher: mockPasswordHasher("x"),
},
args{
ctx: authz.NewMockContext("instanceID", "", ""),
user: &SetSchemaUserPassword{
UserID: "user1",
Password: "password2",
CurrentPassword: "notreally",
ChangeRequired: false,
},
},
res{
err: func(err error) bool {
return errors.Is(err, zerrors.ThrowInvalidArgument(passwap.ErrPasswordMismatch, "COMMAND-3M0fs", "Errors.User.Password.Invalid"))
},
},
},
{
"password set, code, ok",
fields{
eventstore: expectEventstore(
expectFilter(
eventFromEventPusher(
authenticator.NewPasswordCreatedEvent(
context.Background(),
&authenticator.NewAggregate("user1", "org1").Aggregate,
"user1",
"$plain$x$password",
false,
),
),
eventFromEventPusherWithCreationDateNow(
authenticator.NewPasswordCodeAddedEvent(context.Background(),
&authenticator.NewAggregate("user1", "org1").Aggregate,
&crypto.CryptoValue{
CryptoType: crypto.TypeEncryption,
Algorithm: "enc",
KeyID: "id",
Crypted: []byte("code"),
},
time.Hour*1,
domain.NotificationTypeEmail,
"",
false,
),
),
),
filterPasswordComplexityPolicyExisting(),
expectPush(
authenticator.NewPasswordCreatedEvent(
context.Background(),
&authenticator.NewAggregate("user1", "org1").Aggregate,
"user1",
"$plain$x$password2",
false,
),
),
),
userPasswordHasher: mockPasswordHasher("x"),
codeAlg: crypto.CreateMockEncryptionAlg(gomock.NewController(t)),
},
args{
ctx: authz.NewMockContext("instanceID", "", ""),
user: &SetSchemaUserPassword{
UserID: "user1",
Password: "password2",
VerificationCode: "code",
ChangeRequired: false,
},
},
res{
details: &domain.ObjectDetails{
ResourceOwner: "org1",
},
},
},
{
"password set, code, failed",
fields{
eventstore: expectEventstore(
expectFilter(
eventFromEventPusher(
authenticator.NewPasswordCreatedEvent(
context.Background(),
&authenticator.NewAggregate("user1", "org1").Aggregate,
"user1",
"$plain$x$password",
false,
),
),
eventFromEventPusherWithCreationDateNow(
authenticator.NewPasswordCodeAddedEvent(context.Background(),
&authenticator.NewAggregate("user1", "org1").Aggregate,
&crypto.CryptoValue{
CryptoType: crypto.TypeEncryption,
Algorithm: "enc",
KeyID: "id",
Crypted: []byte("code"),
},
time.Hour*1,
domain.NotificationTypeEmail,
"",
false,
),
),
),
),
userPasswordHasher: mockPasswordHasher("x"),
codeAlg: crypto.CreateMockEncryptionAlg(gomock.NewController(t)),
},
args{
ctx: authz.NewMockContext("instanceID", "", ""),
user: &SetSchemaUserPassword{
UserID: "user1",
Password: "password2",
VerificationCode: "notreally",
ChangeRequired: false,
},
},
res{
err: func(err error) bool {
return errors.Is(err, zerrors.ThrowInvalidArgument(nil, "CODE-woT0xc", "Errors.User.Code.Invalid"))
},
},
},
{
"password set, code, no code",
fields{
eventstore: expectEventstore(
filterSchemaUserPasswordExisting(),
),
userPasswordHasher: mockPasswordHasher("x"),
codeAlg: crypto.CreateMockEncryptionAlg(gomock.NewController(t)),
},
args{
ctx: authz.NewMockContext("instanceID", "", ""),
user: &SetSchemaUserPassword{
UserID: "user1",
Password: "password2",
VerificationCode: "notreally",
ChangeRequired: false,
},
},
res{
err: func(err error) bool {
return errors.Is(err, zerrors.ThrowPreconditionFailed(nil, "COMMAND-TODO", "Errors.User.Code.NotFound"))
},
},
},
}
for _, tt := range tests {
@@ -316,6 +540,7 @@ func TestCommands_SetSchemaUserPassword(t *testing.T) {
eventstore: tt.fields.eventstore(t),
checkPermission: tt.fields.checkPermission,
userPasswordHasher: tt.fields.userPasswordHasher,
userEncryption: tt.fields.codeAlg,
}
details, err := c.SetSchemaUserPassword(tt.args.ctx, tt.args.user)
if tt.res.err == nil {
@@ -331,6 +556,224 @@ func TestCommands_SetSchemaUserPassword(t *testing.T) {
}
}
func TestCommands_RequestSchemaUserPasswordReset(t *testing.T) {
type fields struct {
eventstore func(t *testing.T) *eventstore.Eventstore
checkPermission domain.PermissionCheck
newCode encrypedCodeFunc
}
type args struct {
ctx context.Context
user *RequestSchemaUserPasswordReset
}
type res struct {
details *domain.ObjectDetails
plainCode string
err func(error) bool
}
tests := []struct {
name string
fields fields
args args
res res
}{
{
"no userID, error",
fields{
eventstore: expectEventstore(),
checkPermission: newMockPermissionCheckAllowed(),
},
args{
ctx: authz.NewMockContext("instanceID", "", ""),
user: &RequestSchemaUserPasswordReset{},
},
res{
err: func(err error) bool {
return errors.Is(err, zerrors.ThrowInvalidArgument(nil, "COMMAND-PoSU5BOZCi", "Errors.IDMissing"))
},
},
},
{
"password not existing, error",
fields{
eventstore: expectEventstore(
expectFilter(),
),
checkPermission: newMockPermissionCheckAllowed(),
},
args{
ctx: authz.NewMockContext("instanceID", "", ""),
user: &RequestSchemaUserPasswordReset{
UserID: "notexisting",
},
},
res{
err: func(err error) bool {
return errors.Is(err, zerrors.ThrowNotFound(nil, "COMMAND-TODO", "Errors.User.Password.NotFound"))
},
},
},
{
"no permission, error",
fields{
eventstore: expectEventstore(
expectFilter(),
),
checkPermission: newMockPermissionCheckNotAllowed(),
},
args{
ctx: authz.NewMockContext("instanceID", "", ""),
user: &RequestSchemaUserPasswordReset{
UserID: "user1",
},
},
res{
err: func(err error) bool {
return errors.Is(err, zerrors.ThrowPermissionDenied(nil, "AUTHZ-HKJD33", "Errors.PermissionDenied"))
},
},
},
{
"password reset, email, ok",
fields{
eventstore: expectEventstore(
filterSchemaUserPasswordExisting(),
expectPush(
authenticator.NewPasswordCodeAddedEvent(
context.Background(),
&authenticator.NewAggregate("user1", "org1").Aggregate,
&crypto.CryptoValue{
CryptoType: crypto.TypeEncryption,
Algorithm: "enc",
KeyID: "id",
Crypted: []byte("code"),
},
10*time.Minute,
domain.NotificationTypeEmail,
"https://example.com/password/changey?userID={{.UserID}}&code={{.Code}}&orgID={{.OrgID}}",
false,
),
),
),
checkPermission: newMockPermissionCheckAllowed(),
newCode: mockEncryptedCode("code", 10*time.Minute),
},
args{
ctx: authz.NewMockContext("instanceID", "", ""),
user: &RequestSchemaUserPasswordReset{
UserID: "user1",
NotificationType: domain.NotificationTypeEmail,
URLTemplate: "https://example.com/password/changey?userID={{.UserID}}&code={{.Code}}&orgID={{.OrgID}}",
},
},
res{
details: &domain.ObjectDetails{
ResourceOwner: "org1",
},
},
},
{
"password reset, sms, ok",
fields{
eventstore: expectEventstore(
filterSchemaUserPasswordExisting(),
expectPush(
authenticator.NewPasswordCodeAddedEvent(
context.Background(),
&authenticator.NewAggregate("user1", "org1").Aggregate,
&crypto.CryptoValue{
CryptoType: crypto.TypeEncryption,
Algorithm: "enc",
KeyID: "id",
Crypted: []byte("code"),
},
10*time.Minute,
domain.NotificationTypeSms,
"",
false,
),
),
),
checkPermission: newMockPermissionCheckAllowed(),
newCode: mockEncryptedCode("code", 10*time.Minute),
},
args{
ctx: authz.NewMockContext("instanceID", "", ""),
user: &RequestSchemaUserPasswordReset{
UserID: "user1",
NotificationType: domain.NotificationTypeSms,
},
},
res{
details: &domain.ObjectDetails{
ResourceOwner: "org1",
},
},
},
{
"password reset, returned, ok",
fields{
eventstore: expectEventstore(
filterSchemaUserPasswordExisting(),
expectPush(
authenticator.NewPasswordCodeAddedEvent(
context.Background(),
&authenticator.NewAggregate("user1", "org1").Aggregate,
&crypto.CryptoValue{
CryptoType: crypto.TypeEncryption,
Algorithm: "enc",
KeyID: "id",
Crypted: []byte("code"),
},
10*time.Minute,
domain.NotificationTypeEmail,
"",
true,
),
),
),
checkPermission: newMockPermissionCheckAllowed(),
newCode: mockEncryptedCode("code", 10*time.Minute),
},
args{
ctx: authz.NewMockContext("instanceID", "", ""),
user: &RequestSchemaUserPasswordReset{
UserID: "user1",
ReturnCode: true,
},
},
res{
details: &domain.ObjectDetails{
ResourceOwner: "org1",
},
plainCode: "code",
},
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
c := &Commands{
eventstore: tt.fields.eventstore(t),
checkPermission: tt.fields.checkPermission,
newEncryptedCode: tt.fields.newCode,
}
details, err := c.RequestSchemaUserPasswordReset(tt.args.ctx, tt.args.user)
if tt.res.err == nil {
assert.NoError(t, err)
}
if tt.res.err != nil && !tt.res.err(err) {
t.Errorf("got wrong err: %v ", err)
}
if tt.res.err == nil {
assertObjectDetails(t, tt.res.details, details)
}
if tt.res.plainCode != "" {
assert.Equal(t, tt.res.plainCode, tt.args.user.PlainCode)
}
})
}
}
func TestCommands_DeleteSchemaUserPassword(t *testing.T) {
type fields struct {
eventstore func(t *testing.T) *eventstore.Eventstore

View File

@@ -39,8 +39,8 @@ func (c *Commands) AddUsername(ctx context.Context, username *AddUsername) (*dom
return pushedEventsToObjectDetails(events), nil
}
func (c *Commands) DeleteUsername(ctx context.Context, resourceOwner, id string) (_ *domain.ObjectDetails, err error) {
existing, err := c.getSchemaUsernameExistsWithPermission(ctx, resourceOwner, id)
func (c *Commands) DeleteUsername(ctx context.Context, resourceOwner, userID, id string) (_ *domain.ObjectDetails, err error) {
existing, err := c.getSchemaUsernameExistsWithPermission(ctx, resourceOwner, userID, id)
if err != nil {
return nil, err
}
@@ -57,11 +57,14 @@ func (c *Commands) DeleteUsername(ctx context.Context, resourceOwner, id string)
return pushedEventsToObjectDetails(events), nil
}
func (c *Commands) getSchemaUsernameExistsWithPermission(ctx context.Context, resourceOwner, id string) (*UsernameV3WriteModel, error) {
func (c *Commands) getSchemaUsernameExistsWithPermission(ctx context.Context, resourceOwner, userID, id string) (*UsernameV3WriteModel, error) {
if userID == "" {
return nil, zerrors.ThrowInvalidArgument(nil, "COMMAND-J6ybG5WZiy", "Errors.IDMissing")
}
if id == "" {
return nil, zerrors.ThrowInvalidArgument(nil, "COMMAND-PoSU5BOZCi", "Errors.IDMissing")
}
writeModel := NewUsernameV3WriteModel(resourceOwner, id)
writeModel := NewUsernameV3WriteModel(resourceOwner, userID, id)
if err := c.eventstore.FilterToQueryReducer(ctx, writeModel); err != nil {
return nil, err
}

View File

@@ -3,7 +3,6 @@ package command
import (
"github.com/zitadel/zitadel/internal/eventstore"
"github.com/zitadel/zitadel/internal/repository/user/authenticator"
"github.com/zitadel/zitadel/internal/repository/user/schemauser"
)
type UsernameV3WriteModel struct {
@@ -13,12 +12,13 @@ type UsernameV3WriteModel struct {
IsOrgSpecific bool
}
func NewUsernameV3WriteModel(resourceOwner, userID string) *UsernameV3WriteModel {
func NewUsernameV3WriteModel(resourceOwner, userID, id string) *UsernameV3WriteModel {
return &UsernameV3WriteModel{
WriteModel: eventstore.WriteModel{
AggregateID: userID,
AggregateID: id,
ResourceOwner: resourceOwner,
},
UserID: userID,
}
}
@@ -26,6 +26,9 @@ func (wm *UsernameV3WriteModel) Reduce() error {
for _, event := range wm.Events {
switch e := event.(type) {
case *authenticator.UsernameCreatedEvent:
if e.UserID != wm.UserID {
continue
}
wm.UserID = e.UserID
wm.Username = e.Username
wm.IsOrgSpecific = e.IsOrgSpecific
@@ -42,7 +45,7 @@ func (wm *UsernameV3WriteModel) Query() *eventstore.SearchQueryBuilder {
return eventstore.NewSearchQueryBuilder(eventstore.ColumnsEvent).
ResourceOwner(wm.ResourceOwner).
AddQuery().
AggregateTypes(schemauser.AggregateType).
AggregateTypes(authenticator.AggregateType).
AggregateIDs(wm.AggregateID).
EventTypes(
authenticator.UsernameCreatedType,

View File

@@ -63,7 +63,7 @@ func filterUsernameExisting(isOrgSpecifc bool) expect {
authenticator.NewUsernameCreatedEvent(
context.Background(),
&authenticator.NewAggregate("username1", "org1").Aggregate,
"id1",
"user1",
isOrgSpecifc,
"username",
),
@@ -264,6 +264,7 @@ func TestCommands_DeleteUsername(t *testing.T) {
type args struct {
ctx context.Context
resourceOwner string
userID string
id string
}
type res struct {
@@ -277,7 +278,7 @@ func TestCommands_DeleteUsername(t *testing.T) {
res res
}{
{
"no ID, error",
"no userID, error",
fields{
eventstore: expectEventstore(),
checkPermission: newMockPermissionCheckAllowed(),
@@ -286,6 +287,23 @@ func TestCommands_DeleteUsername(t *testing.T) {
ctx: authz.NewMockContext("instanceID", "", ""),
id: "",
},
res{
err: func(err error) bool {
return errors.Is(err, zerrors.ThrowInvalidArgument(nil, "COMMAND-J6ybG5WZiy", "Errors.IDMissing"))
},
},
},
{
"no ID, error",
fields{
eventstore: expectEventstore(),
checkPermission: newMockPermissionCheckAllowed(),
},
args{
ctx: authz.NewMockContext("instanceID", "", ""),
userID: "user1",
id: "",
},
res{
err: func(err error) bool {
return errors.Is(err, zerrors.ThrowInvalidArgument(nil, "COMMAND-PoSU5BOZCi", "Errors.IDMissing"))
@@ -301,8 +319,9 @@ func TestCommands_DeleteUsername(t *testing.T) {
checkPermission: newMockPermissionCheckAllowed(),
},
args{
ctx: authz.NewMockContext("instanceID", "", ""),
id: "notexisting",
ctx: authz.NewMockContext("instanceID", "", ""),
userID: "user1",
id: "notexisting",
},
res{
err: func(err error) bool {
@@ -319,7 +338,7 @@ func TestCommands_DeleteUsername(t *testing.T) {
authenticator.NewUsernameCreatedEvent(
context.Background(),
&authenticator.NewAggregate("username1", "org1").Aggregate,
"id1",
"user1",
true,
"username",
),
@@ -337,8 +356,9 @@ func TestCommands_DeleteUsername(t *testing.T) {
checkPermission: newMockPermissionCheckAllowed(),
},
args{
ctx: authz.NewMockContext("instanceID", "", ""),
id: "notexisting",
ctx: authz.NewMockContext("instanceID", "", ""),
userID: "user1",
id: "notexisting",
},
res{
err: func(err error) bool {
@@ -355,8 +375,9 @@ func TestCommands_DeleteUsername(t *testing.T) {
checkPermission: newMockPermissionCheckNotAllowed(),
},
args{
ctx: authz.NewMockContext("instanceID", "", ""),
id: "username1",
ctx: authz.NewMockContext("instanceID", "", ""),
userID: "user1",
id: "username1",
},
res{
err: func(err error) bool {
@@ -381,8 +402,9 @@ func TestCommands_DeleteUsername(t *testing.T) {
checkPermission: newMockPermissionCheckAllowed(),
},
args{
ctx: authz.NewMockContext("instanceID", "", ""),
id: "username1",
ctx: authz.NewMockContext("instanceID", "", ""),
userID: "user1",
id: "username1",
},
res{
details: &domain.ObjectDetails{
@@ -407,8 +429,9 @@ func TestCommands_DeleteUsername(t *testing.T) {
checkPermission: newMockPermissionCheckAllowed(),
},
args{
ctx: authz.NewMockContext("instanceID", "", ""),
id: "username1",
ctx: authz.NewMockContext("instanceID", "", ""),
userID: "user1",
id: "username1",
},
res{
details: &domain.ObjectDetails{
@@ -423,7 +446,7 @@ func TestCommands_DeleteUsername(t *testing.T) {
eventstore: tt.fields.eventstore(t),
checkPermission: tt.fields.checkPermission,
}
details, err := c.DeleteUsername(tt.args.ctx, tt.args.resourceOwner, tt.args.id)
details, err := c.DeleteUsername(tt.args.ctx, tt.args.resourceOwner, tt.args.userID, tt.args.id)
if tt.res.err == nil {
assert.NoError(t, err)
}