feat: Lockout policy (#2121)

* feat: lock users if lockout policy is set

* feat: setup

* feat: lock user on password failes

* feat: render error

* feat: lock user on command side

* feat: auth_req tests

* feat: lockout policy docs

* feat: remove show lockout failures from proto

* fix: console lockout

* feat: tests

* fix: tests

* unlock function

* add unlock button

* fix migration version

* lockout policy

* lint

* Update internal/auth/repository/eventsourcing/eventstore/auth_request.go

Co-authored-by: Silvan <silvan.reusser@gmail.com>

* fix: err message

* Update internal/command/setup_step4.go

Co-authored-by: Silvan <silvan.reusser@gmail.com>

Co-authored-by: Max Peintner <max@caos.ch>
Co-authored-by: Livio Amstutz <livio.a@gmail.com>
Co-authored-by: Silvan <silvan.reusser@gmail.com>
This commit is contained in:
Fabi
2021-08-11 08:36:32 +02:00
committed by GitHub
parent 272e411e27
commit bc951985ed
101 changed files with 2170 additions and 1574 deletions

View File

@@ -112,10 +112,10 @@ func writeModelToPasswordComplexityPolicy(wm *PasswordComplexityPolicyWriteModel
}
}
func writeModelToPasswordLockoutPolicy(wm *PasswordLockoutPolicyWriteModel) *domain.PasswordLockoutPolicy {
return &domain.PasswordLockoutPolicy{
func writeModelToLockoutPolicy(wm *LockoutPolicyWriteModel) *domain.LockoutPolicy {
return &domain.LockoutPolicy{
ObjectRoot: writeModelToObjectRoot(wm.WriteModel),
MaxAttempts: wm.MaxAttempts,
MaxPasswordAttempts: wm.MaxPasswordAttempts,
ShowLockOutFailures: wm.ShowLockOutFailures,
}
}

View File

@@ -9,10 +9,10 @@ import (
"github.com/caos/zitadel/internal/telemetry/tracing"
)
func (c *Commands) AddDefaultPasswordLockoutPolicy(ctx context.Context, policy *domain.PasswordLockoutPolicy) (*domain.PasswordLockoutPolicy, error) {
addedPolicy := NewIAMPasswordLockoutPolicyWriteModel()
func (c *Commands) AddDefaultLockoutPolicy(ctx context.Context, policy *domain.LockoutPolicy) (*domain.LockoutPolicy, error) {
addedPolicy := NewIAMLockoutPolicyWriteModel()
iamAgg := IAMAggregateFromWriteModel(&addedPolicy.WriteModel)
event, err := c.addDefaultPasswordLockoutPolicy(ctx, iamAgg, addedPolicy, policy)
event, err := c.addDefaultLockoutPolicy(ctx, iamAgg, addedPolicy, policy)
if err != nil {
return nil, err
}
@@ -25,34 +25,34 @@ func (c *Commands) AddDefaultPasswordLockoutPolicy(ctx context.Context, policy *
return nil, err
}
return writeModelToPasswordLockoutPolicy(&addedPolicy.PasswordLockoutPolicyWriteModel), nil
return writeModelToLockoutPolicy(&addedPolicy.LockoutPolicyWriteModel), nil
}
func (c *Commands) addDefaultPasswordLockoutPolicy(ctx context.Context, iamAgg *eventstore.Aggregate, addedPolicy *IAMPasswordLockoutPolicyWriteModel, policy *domain.PasswordLockoutPolicy) (eventstore.EventPusher, error) {
func (c *Commands) addDefaultLockoutPolicy(ctx context.Context, iamAgg *eventstore.Aggregate, addedPolicy *IAMLockoutPolicyWriteModel, policy *domain.LockoutPolicy) (eventstore.EventPusher, error) {
err := c.eventstore.FilterToQueryReducer(ctx, addedPolicy)
if err != nil {
return nil, err
}
if addedPolicy.State == domain.PolicyStateActive {
return nil, caos_errs.ThrowAlreadyExists(nil, "IAM-0olDf", "Errors.IAM.PasswordLockoutPolicy.AlreadyExists")
return nil, caos_errs.ThrowAlreadyExists(nil, "IAM-0olDf", "Errors.IAM.LockoutPolicy.AlreadyExists")
}
return iam_repo.NewPasswordLockoutPolicyAddedEvent(ctx, iamAgg, policy.MaxAttempts, policy.ShowLockOutFailures), nil
return iam_repo.NewLockoutPolicyAddedEvent(ctx, iamAgg, policy.MaxPasswordAttempts, policy.ShowLockOutFailures), nil
}
func (c *Commands) ChangeDefaultPasswordLockoutPolicy(ctx context.Context, policy *domain.PasswordLockoutPolicy) (*domain.PasswordLockoutPolicy, error) {
existingPolicy, err := c.defaultPasswordLockoutPolicyWriteModelByID(ctx)
func (c *Commands) ChangeDefaultLockoutPolicy(ctx context.Context, policy *domain.LockoutPolicy) (*domain.LockoutPolicy, error) {
existingPolicy, err := c.defaultLockoutPolicyWriteModelByID(ctx)
if err != nil {
return nil, err
}
if existingPolicy.State == domain.PolicyStateUnspecified || existingPolicy.State == domain.PolicyStateRemoved {
return nil, caos_errs.ThrowNotFound(nil, "IAM-0oPew", "Errors.IAM.PasswordLockoutPolicy.NotFound")
return nil, caos_errs.ThrowNotFound(nil, "IAM-0oPew", "Errors.IAM.LockoutPolicy.NotFound")
}
iamAgg := IAMAggregateFromWriteModel(&existingPolicy.PasswordLockoutPolicyWriteModel.WriteModel)
changedEvent, hasChanged := existingPolicy.NewChangedEvent(ctx, iamAgg, policy.MaxAttempts, policy.ShowLockOutFailures)
iamAgg := IAMAggregateFromWriteModel(&existingPolicy.LockoutPolicyWriteModel.WriteModel)
changedEvent, hasChanged := existingPolicy.NewChangedEvent(ctx, iamAgg, policy.MaxPasswordAttempts, policy.ShowLockOutFailures)
if !hasChanged {
return nil, caos_errs.ThrowPreconditionFailed(nil, "IAM-4M9vs", "Errors.IAM.PasswordLockoutPolicy.NotChanged")
return nil, caos_errs.ThrowPreconditionFailed(nil, "IAM-4M9vs", "Errors.IAM.LockoutPolicy.NotChanged")
}
pushedEvents, err := c.eventstore.PushEvents(ctx, changedEvent)
@@ -63,14 +63,14 @@ func (c *Commands) ChangeDefaultPasswordLockoutPolicy(ctx context.Context, polic
if err != nil {
return nil, err
}
return writeModelToPasswordLockoutPolicy(&existingPolicy.PasswordLockoutPolicyWriteModel), nil
return writeModelToLockoutPolicy(&existingPolicy.LockoutPolicyWriteModel), nil
}
func (c *Commands) defaultPasswordLockoutPolicyWriteModelByID(ctx context.Context) (policy *IAMPasswordLockoutPolicyWriteModel, err error) {
func (c *Commands) defaultLockoutPolicyWriteModelByID(ctx context.Context) (policy *IAMLockoutPolicyWriteModel, err error) {
ctx, span := tracing.NewSpan(ctx)
defer func() { span.EndWithError(err) }()
writeModel := NewIAMPasswordLockoutPolicyWriteModel()
writeModel := NewIAMLockoutPolicyWriteModel()
err = c.eventstore.FilterToQueryReducer(ctx, writeModel)
if err != nil {
return nil, err

View File

@@ -10,13 +10,13 @@ import (
"github.com/caos/zitadel/internal/repository/policy"
)
type IAMPasswordLockoutPolicyWriteModel struct {
PasswordLockoutPolicyWriteModel
type IAMLockoutPolicyWriteModel struct {
LockoutPolicyWriteModel
}
func NewIAMPasswordLockoutPolicyWriteModel() *IAMPasswordLockoutPolicyWriteModel {
return &IAMPasswordLockoutPolicyWriteModel{
PasswordLockoutPolicyWriteModel{
func NewIAMLockoutPolicyWriteModel() *IAMLockoutPolicyWriteModel {
return &IAMLockoutPolicyWriteModel{
LockoutPolicyWriteModel{
WriteModel: eventstore.WriteModel{
AggregateID: domain.IAMID,
ResourceOwner: domain.IAMID,
@@ -25,40 +25,40 @@ func NewIAMPasswordLockoutPolicyWriteModel() *IAMPasswordLockoutPolicyWriteModel
}
}
func (wm *IAMPasswordLockoutPolicyWriteModel) AppendEvents(events ...eventstore.EventReader) {
func (wm *IAMLockoutPolicyWriteModel) AppendEvents(events ...eventstore.EventReader) {
for _, event := range events {
switch e := event.(type) {
case *iam.PasswordLockoutPolicyAddedEvent:
wm.PasswordLockoutPolicyWriteModel.AppendEvents(&e.PasswordLockoutPolicyAddedEvent)
case *iam.PasswordLockoutPolicyChangedEvent:
wm.PasswordLockoutPolicyWriteModel.AppendEvents(&e.PasswordLockoutPolicyChangedEvent)
case *iam.LockoutPolicyAddedEvent:
wm.LockoutPolicyWriteModel.AppendEvents(&e.LockoutPolicyAddedEvent)
case *iam.LockoutPolicyChangedEvent:
wm.LockoutPolicyWriteModel.AppendEvents(&e.LockoutPolicyChangedEvent)
}
}
}
func (wm *IAMPasswordLockoutPolicyWriteModel) Reduce() error {
return wm.PasswordLockoutPolicyWriteModel.Reduce()
func (wm *IAMLockoutPolicyWriteModel) Reduce() error {
return wm.LockoutPolicyWriteModel.Reduce()
}
func (wm *IAMPasswordLockoutPolicyWriteModel) Query() *eventstore.SearchQueryBuilder {
func (wm *IAMLockoutPolicyWriteModel) Query() *eventstore.SearchQueryBuilder {
return eventstore.NewSearchQueryBuilder(eventstore.ColumnsEvent).
ResourceOwner(wm.ResourceOwner).
AddQuery().
AggregateTypes(iam.AggregateType).
AggregateIDs(wm.PasswordLockoutPolicyWriteModel.AggregateID).
AggregateIDs(wm.LockoutPolicyWriteModel.AggregateID).
EventTypes(
iam.PasswordLockoutPolicyAddedEventType,
iam.PasswordLockoutPolicyChangedEventType).
iam.LockoutPolicyAddedEventType,
iam.LockoutPolicyChangedEventType).
Builder()
}
func (wm *IAMPasswordLockoutPolicyWriteModel) NewChangedEvent(
func (wm *IAMLockoutPolicyWriteModel) NewChangedEvent(
ctx context.Context,
aggregate *eventstore.Aggregate,
maxAttempts uint64,
showLockoutFailure bool) (*iam.PasswordLockoutPolicyChangedEvent, bool) {
changes := make([]policy.PasswordLockoutPolicyChanges, 0)
if wm.MaxAttempts != maxAttempts {
showLockoutFailure bool) (*iam.LockoutPolicyChangedEvent, bool) {
changes := make([]policy.LockoutPolicyChanges, 0)
if wm.MaxPasswordAttempts != maxAttempts {
changes = append(changes, policy.ChangeMaxAttempts(maxAttempts))
}
if wm.ShowLockOutFailures != showLockoutFailure {
@@ -67,7 +67,7 @@ func (wm *IAMPasswordLockoutPolicyWriteModel) NewChangedEvent(
if len(changes) == 0 {
return nil, false
}
changedEvent, err := iam.NewPasswordLockoutPolicyChangedEvent(ctx, aggregate, changes)
changedEvent, err := iam.NewLockoutPolicyChangedEvent(ctx, aggregate, changes)
if err != nil {
return nil, false
}

View File

@@ -13,16 +13,16 @@ import (
"testing"
)
func TestCommandSide_AddDefaultPasswordLockoutPolicy(t *testing.T) {
func TestCommandSide_AddDefaultLockoutPolicy(t *testing.T) {
type fields struct {
eventstore *eventstore.Eventstore
}
type args struct {
ctx context.Context
policy *domain.PasswordLockoutPolicy
policy *domain.LockoutPolicy
}
type res struct {
want *domain.PasswordLockoutPolicy
want *domain.LockoutPolicy
err func(error) bool
}
tests := []struct {
@@ -32,13 +32,13 @@ func TestCommandSide_AddDefaultPasswordLockoutPolicy(t *testing.T) {
res res
}{
{
name: "password lockout policy already existing, already exists error",
name: "lockout policy already existing, already exists error",
fields: fields{
eventstore: eventstoreExpect(
t,
expectFilter(
eventFromEventPusher(
iam.NewPasswordLockoutPolicyAddedEvent(context.Background(),
iam.NewLockoutPolicyAddedEvent(context.Background(),
&iam.NewAggregate().Aggregate,
10,
true,
@@ -49,8 +49,8 @@ func TestCommandSide_AddDefaultPasswordLockoutPolicy(t *testing.T) {
},
args: args{
ctx: context.Background(),
policy: &domain.PasswordLockoutPolicy{
MaxAttempts: 10,
policy: &domain.LockoutPolicy{
MaxPasswordAttempts: 10,
ShowLockOutFailures: true,
},
},
@@ -67,7 +67,7 @@ func TestCommandSide_AddDefaultPasswordLockoutPolicy(t *testing.T) {
expectPush(
[]*repository.Event{
eventFromEventPusher(
iam.NewPasswordLockoutPolicyAddedEvent(context.Background(),
iam.NewLockoutPolicyAddedEvent(context.Background(),
&iam.NewAggregate().Aggregate,
10,
true,
@@ -79,18 +79,18 @@ func TestCommandSide_AddDefaultPasswordLockoutPolicy(t *testing.T) {
},
args: args{
ctx: context.Background(),
policy: &domain.PasswordLockoutPolicy{
MaxAttempts: 10,
policy: &domain.LockoutPolicy{
MaxPasswordAttempts: 10,
ShowLockOutFailures: true,
},
},
res: res{
want: &domain.PasswordLockoutPolicy{
want: &domain.LockoutPolicy{
ObjectRoot: models.ObjectRoot{
AggregateID: "IAM",
ResourceOwner: "IAM",
},
MaxAttempts: 10,
MaxPasswordAttempts: 10,
ShowLockOutFailures: true,
},
},
@@ -101,7 +101,7 @@ func TestCommandSide_AddDefaultPasswordLockoutPolicy(t *testing.T) {
r := &Commands{
eventstore: tt.fields.eventstore,
}
got, err := r.AddDefaultPasswordLockoutPolicy(tt.args.ctx, tt.args.policy)
got, err := r.AddDefaultLockoutPolicy(tt.args.ctx, tt.args.policy)
if tt.res.err == nil {
assert.NoError(t, err)
}
@@ -115,16 +115,16 @@ func TestCommandSide_AddDefaultPasswordLockoutPolicy(t *testing.T) {
}
}
func TestCommandSide_ChangeDefaultPasswordLockoutPolicy(t *testing.T) {
func TestCommandSide_ChangeDefaultLockoutPolicy(t *testing.T) {
type fields struct {
eventstore *eventstore.Eventstore
}
type args struct {
ctx context.Context
policy *domain.PasswordLockoutPolicy
policy *domain.LockoutPolicy
}
type res struct {
want *domain.PasswordLockoutPolicy
want *domain.LockoutPolicy
err func(error) bool
}
tests := []struct {
@@ -134,7 +134,7 @@ func TestCommandSide_ChangeDefaultPasswordLockoutPolicy(t *testing.T) {
res res
}{
{
name: "password lockout policy not existing, not found error",
name: "lockout policy not existing, not found error",
fields: fields{
eventstore: eventstoreExpect(
t,
@@ -143,8 +143,8 @@ func TestCommandSide_ChangeDefaultPasswordLockoutPolicy(t *testing.T) {
},
args: args{
ctx: context.Background(),
policy: &domain.PasswordLockoutPolicy{
MaxAttempts: 10,
policy: &domain.LockoutPolicy{
MaxPasswordAttempts: 10,
ShowLockOutFailures: true,
},
},
@@ -159,7 +159,7 @@ func TestCommandSide_ChangeDefaultPasswordLockoutPolicy(t *testing.T) {
t,
expectFilter(
eventFromEventPusher(
iam.NewPasswordLockoutPolicyAddedEvent(context.Background(),
iam.NewLockoutPolicyAddedEvent(context.Background(),
&iam.NewAggregate().Aggregate,
10,
true,
@@ -170,8 +170,8 @@ func TestCommandSide_ChangeDefaultPasswordLockoutPolicy(t *testing.T) {
},
args: args{
ctx: context.Background(),
policy: &domain.PasswordLockoutPolicy{
MaxAttempts: 10,
policy: &domain.LockoutPolicy{
MaxPasswordAttempts: 10,
ShowLockOutFailures: true,
},
},
@@ -186,7 +186,7 @@ func TestCommandSide_ChangeDefaultPasswordLockoutPolicy(t *testing.T) {
t,
expectFilter(
eventFromEventPusher(
iam.NewPasswordLockoutPolicyAddedEvent(context.Background(),
iam.NewLockoutPolicyAddedEvent(context.Background(),
&iam.NewAggregate().Aggregate,
10,
true,
@@ -196,7 +196,7 @@ func TestCommandSide_ChangeDefaultPasswordLockoutPolicy(t *testing.T) {
expectPush(
[]*repository.Event{
eventFromEventPusher(
newDefaultPasswordLockoutPolicyChangedEvent(context.Background(), 20, false),
newDefaultLockoutPolicyChangedEvent(context.Background(), 20, false),
),
},
),
@@ -204,18 +204,18 @@ func TestCommandSide_ChangeDefaultPasswordLockoutPolicy(t *testing.T) {
},
args: args{
ctx: context.Background(),
policy: &domain.PasswordLockoutPolicy{
MaxAttempts: 20,
policy: &domain.LockoutPolicy{
MaxPasswordAttempts: 20,
ShowLockOutFailures: false,
},
},
res: res{
want: &domain.PasswordLockoutPolicy{
want: &domain.LockoutPolicy{
ObjectRoot: models.ObjectRoot{
AggregateID: "IAM",
ResourceOwner: "IAM",
},
MaxAttempts: 20,
MaxPasswordAttempts: 20,
ShowLockOutFailures: false,
},
},
@@ -226,7 +226,7 @@ func TestCommandSide_ChangeDefaultPasswordLockoutPolicy(t *testing.T) {
r := &Commands{
eventstore: tt.fields.eventstore,
}
got, err := r.ChangeDefaultPasswordLockoutPolicy(tt.args.ctx, tt.args.policy)
got, err := r.ChangeDefaultLockoutPolicy(tt.args.ctx, tt.args.policy)
if tt.res.err == nil {
assert.NoError(t, err)
}
@@ -240,10 +240,10 @@ func TestCommandSide_ChangeDefaultPasswordLockoutPolicy(t *testing.T) {
}
}
func newDefaultPasswordLockoutPolicyChangedEvent(ctx context.Context, maxAttempts uint64, showLockoutFailure bool) *iam.PasswordLockoutPolicyChangedEvent {
event, _ := iam.NewPasswordLockoutPolicyChangedEvent(ctx,
func newDefaultLockoutPolicyChangedEvent(ctx context.Context, maxAttempts uint64, showLockoutFailure bool) *iam.LockoutPolicyChangedEvent {
event, _ := iam.NewLockoutPolicyChangedEvent(ctx,
&iam.NewAggregate().Aggregate,
[]policy.PasswordLockoutPolicyChanges{
[]policy.LockoutPolicyChanges{
policy.ChangeMaxAttempts(maxAttempts),
policy.ChangeShowLockOutFailures(showLockoutFailure),
},

View File

@@ -7,21 +7,21 @@ import (
"github.com/caos/zitadel/internal/repository/org"
)
func (c *Commands) AddPasswordLockoutPolicy(ctx context.Context, resourceOwner string, policy *domain.PasswordLockoutPolicy) (*domain.PasswordLockoutPolicy, error) {
func (c *Commands) AddLockoutPolicy(ctx context.Context, resourceOwner string, policy *domain.LockoutPolicy) (*domain.LockoutPolicy, error) {
if resourceOwner == "" {
return nil, caos_errs.ThrowInvalidArgument(nil, "Org-8fJif", "Errors.ResourceOwnerMissing")
}
addedPolicy := NewOrgPasswordLockoutPolicyWriteModel(resourceOwner)
addedPolicy := NewOrgLockoutPolicyWriteModel(resourceOwner)
err := c.eventstore.FilterToQueryReducer(ctx, addedPolicy)
if err != nil {
return nil, err
}
if addedPolicy.State == domain.PolicyStateActive {
return nil, caos_errs.ThrowAlreadyExists(nil, "ORG-0olDf", "Errors.ORG.PasswordLockoutPolicy.AlreadyExists")
return nil, caos_errs.ThrowAlreadyExists(nil, "ORG-0olDf", "Errors.ORG.LockoutPolicy.AlreadyExists")
}
orgAgg := OrgAggregateFromWriteModel(&addedPolicy.WriteModel)
pushedEvents, err := c.eventstore.PushEvents(ctx, org.NewPasswordLockoutPolicyAddedEvent(ctx, orgAgg, policy.MaxAttempts, policy.ShowLockOutFailures))
pushedEvents, err := c.eventstore.PushEvents(ctx, org.NewLockoutPolicyAddedEvent(ctx, orgAgg, policy.MaxPasswordAttempts, policy.ShowLockOutFailures))
if err != nil {
return nil, err
}
@@ -29,26 +29,26 @@ func (c *Commands) AddPasswordLockoutPolicy(ctx context.Context, resourceOwner s
if err != nil {
return nil, err
}
return writeModelToPasswordLockoutPolicy(&addedPolicy.PasswordLockoutPolicyWriteModel), nil
return writeModelToLockoutPolicy(&addedPolicy.LockoutPolicyWriteModel), nil
}
func (c *Commands) ChangePasswordLockoutPolicy(ctx context.Context, resourceOwner string, policy *domain.PasswordLockoutPolicy) (*domain.PasswordLockoutPolicy, error) {
func (c *Commands) ChangeLockoutPolicy(ctx context.Context, resourceOwner string, policy *domain.LockoutPolicy) (*domain.LockoutPolicy, error) {
if resourceOwner == "" {
return nil, caos_errs.ThrowInvalidArgument(nil, "Org-3J9fs", "Errors.ResourceOwnerMissing")
}
existingPolicy := NewOrgPasswordLockoutPolicyWriteModel(resourceOwner)
existingPolicy := NewOrgLockoutPolicyWriteModel(resourceOwner)
err := c.eventstore.FilterToQueryReducer(ctx, existingPolicy)
if err != nil {
return nil, err
}
if existingPolicy.State == domain.PolicyStateUnspecified || existingPolicy.State == domain.PolicyStateRemoved {
return nil, caos_errs.ThrowNotFound(nil, "ORG-ADfs1", "Errors.Org.PasswordLockoutPolicy.NotFound")
return nil, caos_errs.ThrowNotFound(nil, "ORG-ADfs1", "Errors.Org.LockoutPolicy.NotFound")
}
orgAgg := OrgAggregateFromWriteModel(&existingPolicy.PasswordLockoutPolicyWriteModel.WriteModel)
changedEvent, hasChanged := existingPolicy.NewChangedEvent(ctx, orgAgg, policy.MaxAttempts, policy.ShowLockOutFailures)
orgAgg := OrgAggregateFromWriteModel(&existingPolicy.LockoutPolicyWriteModel.WriteModel)
changedEvent, hasChanged := existingPolicy.NewChangedEvent(ctx, orgAgg, policy.MaxPasswordAttempts, policy.ShowLockOutFailures)
if !hasChanged {
return nil, caos_errs.ThrowPreconditionFailed(nil, "ORG-4M9vs", "Errors.Org.PasswordLockoutPolicy.NotChanged")
return nil, caos_errs.ThrowPreconditionFailed(nil, "ORG-4M9vs", "Errors.Org.LockoutPolicy.NotChanged")
}
pushedEvents, err := c.eventstore.PushEvents(ctx, changedEvent)
@@ -59,23 +59,23 @@ func (c *Commands) ChangePasswordLockoutPolicy(ctx context.Context, resourceOwne
if err != nil {
return nil, err
}
return writeModelToPasswordLockoutPolicy(&existingPolicy.PasswordLockoutPolicyWriteModel), nil
return writeModelToLockoutPolicy(&existingPolicy.LockoutPolicyWriteModel), nil
}
func (c *Commands) RemovePasswordLockoutPolicy(ctx context.Context, orgID string) error {
func (c *Commands) RemoveLockoutPolicy(ctx context.Context, orgID string) error {
if orgID == "" {
return caos_errs.ThrowInvalidArgument(nil, "Org-4J9fs", "Errors.ResourceOwnerMissing")
}
existingPolicy := NewOrgPasswordLockoutPolicyWriteModel(orgID)
existingPolicy := NewOrgLockoutPolicyWriteModel(orgID)
err := c.eventstore.FilterToQueryReducer(ctx, existingPolicy)
if err != nil {
return err
}
if existingPolicy.State == domain.PolicyStateUnspecified || existingPolicy.State == domain.PolicyStateRemoved {
return caos_errs.ThrowNotFound(nil, "ORG-D4zuz", "Errors.Org.PasswordLockoutPolicy.NotFound")
return caos_errs.ThrowNotFound(nil, "ORG-D4zuz", "Errors.Org.LockoutPolicy.NotFound")
}
orgAgg := OrgAggregateFromWriteModel(&existingPolicy.WriteModel)
_, err = c.eventstore.PushEvents(ctx, org.NewPasswordLockoutPolicyRemovedEvent(ctx, orgAgg))
_, err = c.eventstore.PushEvents(ctx, org.NewLockoutPolicyRemovedEvent(ctx, orgAgg))
return err
}

View File

@@ -9,13 +9,13 @@ import (
"github.com/caos/zitadel/internal/repository/policy"
)
type OrgPasswordLockoutPolicyWriteModel struct {
PasswordLockoutPolicyWriteModel
type OrgLockoutPolicyWriteModel struct {
LockoutPolicyWriteModel
}
func NewOrgPasswordLockoutPolicyWriteModel(orgID string) *OrgPasswordLockoutPolicyWriteModel {
return &OrgPasswordLockoutPolicyWriteModel{
PasswordLockoutPolicyWriteModel{
func NewOrgLockoutPolicyWriteModel(orgID string) *OrgLockoutPolicyWriteModel {
return &OrgLockoutPolicyWriteModel{
LockoutPolicyWriteModel{
WriteModel: eventstore.WriteModel{
AggregateID: orgID,
ResourceOwner: orgID,
@@ -24,42 +24,42 @@ func NewOrgPasswordLockoutPolicyWriteModel(orgID string) *OrgPasswordLockoutPoli
}
}
func (wm *OrgPasswordLockoutPolicyWriteModel) AppendEvents(events ...eventstore.EventReader) {
func (wm *OrgLockoutPolicyWriteModel) AppendEvents(events ...eventstore.EventReader) {
for _, event := range events {
switch e := event.(type) {
case *org.PasswordLockoutPolicyAddedEvent:
wm.PasswordLockoutPolicyWriteModel.AppendEvents(&e.PasswordLockoutPolicyAddedEvent)
case *org.PasswordLockoutPolicyChangedEvent:
wm.PasswordLockoutPolicyWriteModel.AppendEvents(&e.PasswordLockoutPolicyChangedEvent)
case *org.PasswordLockoutPolicyRemovedEvent:
wm.PasswordLockoutPolicyWriteModel.AppendEvents(&e.PasswordLockoutPolicyRemovedEvent)
case *org.LockoutPolicyAddedEvent:
wm.LockoutPolicyWriteModel.AppendEvents(&e.LockoutPolicyAddedEvent)
case *org.LockoutPolicyChangedEvent:
wm.LockoutPolicyWriteModel.AppendEvents(&e.LockoutPolicyChangedEvent)
case *org.LockoutPolicyRemovedEvent:
wm.LockoutPolicyWriteModel.AppendEvents(&e.LockoutPolicyRemovedEvent)
}
}
}
func (wm *OrgPasswordLockoutPolicyWriteModel) Reduce() error {
return wm.PasswordLockoutPolicyWriteModel.Reduce()
func (wm *OrgLockoutPolicyWriteModel) Reduce() error {
return wm.LockoutPolicyWriteModel.Reduce()
}
func (wm *OrgPasswordLockoutPolicyWriteModel) Query() *eventstore.SearchQueryBuilder {
func (wm *OrgLockoutPolicyWriteModel) Query() *eventstore.SearchQueryBuilder {
return eventstore.NewSearchQueryBuilder(eventstore.ColumnsEvent).
ResourceOwner(wm.ResourceOwner).
AddQuery().
AggregateTypes(org.AggregateType).
AggregateIDs(wm.PasswordLockoutPolicyWriteModel.AggregateID).
EventTypes(org.PasswordLockoutPolicyAddedEventType,
org.PasswordLockoutPolicyChangedEventType,
org.PasswordLockoutPolicyRemovedEventType).
AggregateIDs(wm.LockoutPolicyWriteModel.AggregateID).
EventTypes(org.LockoutPolicyAddedEventType,
org.LockoutPolicyChangedEventType,
org.LockoutPolicyRemovedEventType).
Builder()
}
func (wm *OrgPasswordLockoutPolicyWriteModel) NewChangedEvent(
func (wm *OrgLockoutPolicyWriteModel) NewChangedEvent(
ctx context.Context,
aggregate *eventstore.Aggregate,
maxAttempts uint64,
showLockoutFailure bool) (*org.PasswordLockoutPolicyChangedEvent, bool) {
changes := make([]policy.PasswordLockoutPolicyChanges, 0)
if wm.MaxAttempts != maxAttempts {
showLockoutFailure bool) (*org.LockoutPolicyChangedEvent, bool) {
changes := make([]policy.LockoutPolicyChanges, 0)
if wm.MaxPasswordAttempts != maxAttempts {
changes = append(changes, policy.ChangeMaxAttempts(maxAttempts))
}
if wm.ShowLockOutFailures != showLockoutFailure {
@@ -68,7 +68,7 @@ func (wm *OrgPasswordLockoutPolicyWriteModel) NewChangedEvent(
if len(changes) == 0 {
return nil, false
}
changedEvent, err := org.NewPasswordLockoutPolicyChangedEvent(ctx, aggregate, changes)
changedEvent, err := org.NewLockoutPolicyChangedEvent(ctx, aggregate, changes)
if err != nil {
return nil, false
}

View File

@@ -22,10 +22,10 @@ func TestCommandSide_AddPasswordLockoutPolicy(t *testing.T) {
type args struct {
ctx context.Context
orgID string
policy *domain.PasswordLockoutPolicy
policy *domain.LockoutPolicy
}
type res struct {
want *domain.PasswordLockoutPolicy
want *domain.LockoutPolicy
err func(error) bool
}
tests := []struct {
@@ -43,8 +43,8 @@ func TestCommandSide_AddPasswordLockoutPolicy(t *testing.T) {
},
args: args{
ctx: context.Background(),
policy: &domain.PasswordLockoutPolicy{
MaxAttempts: 10,
policy: &domain.LockoutPolicy{
MaxPasswordAttempts: 10,
ShowLockOutFailures: true,
},
},
@@ -59,7 +59,7 @@ func TestCommandSide_AddPasswordLockoutPolicy(t *testing.T) {
t,
expectFilter(
eventFromEventPusher(
org.NewPasswordLockoutPolicyAddedEvent(context.Background(),
org.NewLockoutPolicyAddedEvent(context.Background(),
&org.NewAggregate("org1", "org1").Aggregate,
10,
true,
@@ -71,8 +71,8 @@ func TestCommandSide_AddPasswordLockoutPolicy(t *testing.T) {
args: args{
ctx: context.Background(),
orgID: "org1",
policy: &domain.PasswordLockoutPolicy{
MaxAttempts: 10,
policy: &domain.LockoutPolicy{
MaxPasswordAttempts: 10,
ShowLockOutFailures: true,
},
},
@@ -89,7 +89,7 @@ func TestCommandSide_AddPasswordLockoutPolicy(t *testing.T) {
expectPush(
[]*repository.Event{
eventFromEventPusher(
org.NewPasswordLockoutPolicyAddedEvent(context.Background(),
org.NewLockoutPolicyAddedEvent(context.Background(),
&org.NewAggregate("org1", "org1").Aggregate,
10,
true,
@@ -102,18 +102,18 @@ func TestCommandSide_AddPasswordLockoutPolicy(t *testing.T) {
args: args{
ctx: context.Background(),
orgID: "org1",
policy: &domain.PasswordLockoutPolicy{
MaxAttempts: 10,
policy: &domain.LockoutPolicy{
MaxPasswordAttempts: 10,
ShowLockOutFailures: true,
},
},
res: res{
want: &domain.PasswordLockoutPolicy{
want: &domain.LockoutPolicy{
ObjectRoot: models.ObjectRoot{
AggregateID: "org1",
ResourceOwner: "org1",
},
MaxAttempts: 10,
MaxPasswordAttempts: 10,
ShowLockOutFailures: true,
},
},
@@ -124,7 +124,7 @@ func TestCommandSide_AddPasswordLockoutPolicy(t *testing.T) {
r := &Commands{
eventstore: tt.fields.eventstore,
}
got, err := r.AddPasswordLockoutPolicy(tt.args.ctx, tt.args.orgID, tt.args.policy)
got, err := r.AddLockoutPolicy(tt.args.ctx, tt.args.orgID, tt.args.policy)
if tt.res.err == nil {
assert.NoError(t, err)
}
@@ -145,10 +145,10 @@ func TestCommandSide_ChangePasswordLockoutPolicy(t *testing.T) {
type args struct {
ctx context.Context
orgID string
policy *domain.PasswordLockoutPolicy
policy *domain.LockoutPolicy
}
type res struct {
want *domain.PasswordLockoutPolicy
want *domain.LockoutPolicy
err func(error) bool
}
tests := []struct {
@@ -166,8 +166,8 @@ func TestCommandSide_ChangePasswordLockoutPolicy(t *testing.T) {
},
args: args{
ctx: context.Background(),
policy: &domain.PasswordLockoutPolicy{
MaxAttempts: 10,
policy: &domain.LockoutPolicy{
MaxPasswordAttempts: 10,
ShowLockOutFailures: true,
},
},
@@ -186,8 +186,8 @@ func TestCommandSide_ChangePasswordLockoutPolicy(t *testing.T) {
args: args{
ctx: context.Background(),
orgID: "org1",
policy: &domain.PasswordLockoutPolicy{
MaxAttempts: 10,
policy: &domain.LockoutPolicy{
MaxPasswordAttempts: 10,
ShowLockOutFailures: true,
},
},
@@ -202,7 +202,7 @@ func TestCommandSide_ChangePasswordLockoutPolicy(t *testing.T) {
t,
expectFilter(
eventFromEventPusher(
org.NewPasswordLockoutPolicyAddedEvent(context.Background(),
org.NewLockoutPolicyAddedEvent(context.Background(),
&org.NewAggregate("org1", "org1").Aggregate,
10,
true,
@@ -214,8 +214,8 @@ func TestCommandSide_ChangePasswordLockoutPolicy(t *testing.T) {
args: args{
ctx: context.Background(),
orgID: "org1",
policy: &domain.PasswordLockoutPolicy{
MaxAttempts: 10,
policy: &domain.LockoutPolicy{
MaxPasswordAttempts: 10,
ShowLockOutFailures: true,
},
},
@@ -230,7 +230,7 @@ func TestCommandSide_ChangePasswordLockoutPolicy(t *testing.T) {
t,
expectFilter(
eventFromEventPusher(
org.NewPasswordLockoutPolicyAddedEvent(context.Background(),
org.NewLockoutPolicyAddedEvent(context.Background(),
&org.NewAggregate("org1", "org1").Aggregate,
10,
true,
@@ -249,18 +249,18 @@ func TestCommandSide_ChangePasswordLockoutPolicy(t *testing.T) {
args: args{
ctx: context.Background(),
orgID: "org1",
policy: &domain.PasswordLockoutPolicy{
MaxAttempts: 5,
policy: &domain.LockoutPolicy{
MaxPasswordAttempts: 5,
ShowLockOutFailures: false,
},
},
res: res{
want: &domain.PasswordLockoutPolicy{
want: &domain.LockoutPolicy{
ObjectRoot: models.ObjectRoot{
AggregateID: "org1",
ResourceOwner: "org1",
},
MaxAttempts: 5,
MaxPasswordAttempts: 5,
ShowLockOutFailures: false,
},
},
@@ -271,7 +271,7 @@ func TestCommandSide_ChangePasswordLockoutPolicy(t *testing.T) {
r := &Commands{
eventstore: tt.fields.eventstore,
}
got, err := r.ChangePasswordLockoutPolicy(tt.args.ctx, tt.args.orgID, tt.args.policy)
got, err := r.ChangeLockoutPolicy(tt.args.ctx, tt.args.orgID, tt.args.policy)
if tt.res.err == nil {
assert.NoError(t, err)
}
@@ -340,7 +340,7 @@ func TestCommandSide_RemovePasswordLockoutPolicy(t *testing.T) {
t,
expectFilter(
eventFromEventPusher(
org.NewPasswordLockoutPolicyAddedEvent(context.Background(),
org.NewLockoutPolicyAddedEvent(context.Background(),
&org.NewAggregate("org1", "org1").Aggregate,
10,
true,
@@ -350,7 +350,7 @@ func TestCommandSide_RemovePasswordLockoutPolicy(t *testing.T) {
expectPush(
[]*repository.Event{
eventFromEventPusher(
org.NewPasswordLockoutPolicyRemovedEvent(context.Background(),
org.NewLockoutPolicyRemovedEvent(context.Background(),
&org.NewAggregate("org1", "org1").Aggregate),
),
},
@@ -373,7 +373,7 @@ func TestCommandSide_RemovePasswordLockoutPolicy(t *testing.T) {
r := &Commands{
eventstore: tt.fields.eventstore,
}
err := r.RemovePasswordLockoutPolicy(tt.args.ctx, tt.args.orgID)
err := r.RemoveLockoutPolicy(tt.args.ctx, tt.args.orgID)
if tt.res.err == nil {
assert.NoError(t, err)
}
@@ -384,10 +384,10 @@ func TestCommandSide_RemovePasswordLockoutPolicy(t *testing.T) {
}
}
func newPasswordLockoutPolicyChangedEvent(ctx context.Context, orgID string, maxAttempts uint64, showLockoutFailure bool) *org.PasswordLockoutPolicyChangedEvent {
event, _ := org.NewPasswordLockoutPolicyChangedEvent(ctx,
func newPasswordLockoutPolicyChangedEvent(ctx context.Context, orgID string, maxAttempts uint64, showLockoutFailure bool) *org.LockoutPolicyChangedEvent {
event, _ := org.NewLockoutPolicyChangedEvent(ctx,
&org.NewAggregate(orgID, orgID).Aggregate,
[]policy.PasswordLockoutPolicyChanges{
[]policy.LockoutPolicyChanges{
policy.ChangeMaxAttempts(maxAttempts),
policy.ChangeShowLockOutFailures(showLockoutFailure),
},

View File

@@ -6,29 +6,29 @@ import (
"github.com/caos/zitadel/internal/repository/policy"
)
type PasswordLockoutPolicyWriteModel struct {
type LockoutPolicyWriteModel struct {
eventstore.WriteModel
MaxAttempts uint64
MaxPasswordAttempts uint64
ShowLockOutFailures bool
State domain.PolicyState
}
func (wm *PasswordLockoutPolicyWriteModel) Reduce() error {
func (wm *LockoutPolicyWriteModel) Reduce() error {
for _, event := range wm.Events {
switch e := event.(type) {
case *policy.PasswordLockoutPolicyAddedEvent:
wm.MaxAttempts = e.MaxAttempts
case *policy.LockoutPolicyAddedEvent:
wm.MaxPasswordAttempts = e.MaxPasswordAttempts
wm.ShowLockOutFailures = e.ShowLockOutFailures
wm.State = domain.PolicyStateActive
case *policy.PasswordLockoutPolicyChangedEvent:
if e.MaxAttempts != nil {
wm.MaxAttempts = *e.MaxAttempts
case *policy.LockoutPolicyChangedEvent:
if e.MaxPasswordAttempts != nil {
wm.MaxPasswordAttempts = *e.MaxPasswordAttempts
}
if e.ShowLockOutFailures != nil {
wm.ShowLockOutFailures = *e.ShowLockOutFailures
}
case *policy.PasswordLockoutPolicyRemovedEvent:
case *policy.LockoutPolicyRemovedEvent:
wm.State = domain.PolicyStateRemoved
}
}

View File

@@ -0,0 +1,35 @@
package command
import (
"context"
"github.com/caos/logging"
"github.com/caos/zitadel/internal/domain"
"github.com/caos/zitadel/internal/eventstore"
)
type Step18 struct {
LockoutPolicy domain.LockoutPolicy
}
func (s *Step18) Step() domain.Step {
return domain.Step18
}
func (s *Step18) execute(ctx context.Context, commandSide *Commands) error {
return commandSide.SetupStep18(ctx, s)
}
func (c *Commands) SetupStep18(ctx context.Context, step *Step18) error {
fn := func(iam *IAMWriteModel) ([]eventstore.EventPusher, error) {
iamAgg := IAMAggregateFromWriteModel(&iam.WriteModel)
addedPolicy := NewIAMLockoutPolicyWriteModel()
events, err := c.addDefaultLockoutPolicy(ctx, iamAgg, addedPolicy, &step.LockoutPolicy)
if err != nil {
return nil, err
}
logging.Log("SETUP-3m99ds").Info("default lockout policy set up")
return []eventstore.EventPusher{events}, nil
}
return c.setup(ctx, step, fn)
}

View File

@@ -3,15 +3,13 @@ package command
import (
"context"
"github.com/caos/logging"
"github.com/caos/zitadel/internal/eventstore"
"github.com/caos/zitadel/internal/domain"
)
type Step4 struct {
DefaultPasswordLockoutPolicy domain.PasswordLockoutPolicy
DefaultPasswordLockoutPolicy domain.LockoutPolicy
}
func (s *Step4) Step() domain.Step {
@@ -21,19 +19,12 @@ func (s *Step4) Step() domain.Step {
func (s *Step4) execute(ctx context.Context, commandSide *Commands) error {
return commandSide.SetupStep4(ctx, s)
}
//This step should not be executed when a new instance is setup, because its not used anymore
//SetupStep4 is no op in favour of step 18.
//Password lockout policy is replaced by lockout policy
func (c *Commands) SetupStep4(ctx context.Context, step *Step4) error {
fn := func(iam *IAMWriteModel) ([]eventstore.EventPusher, error) {
iamAgg := IAMAggregateFromWriteModel(&iam.WriteModel)
event, err := c.addDefaultPasswordLockoutPolicy(ctx, iamAgg, NewIAMPasswordLockoutPolicyWriteModel(), &domain.PasswordLockoutPolicy{
MaxAttempts: step.DefaultPasswordLockoutPolicy.MaxAttempts,
ShowLockOutFailures: step.DefaultPasswordLockoutPolicy.ShowLockOutFailures,
})
if err != nil {
return nil, err
}
logging.Log("SETUP-Bfnge").Info("default password lockout policy set up")
return []eventstore.EventPusher{event}, nil
return nil, nil
}
return c.setup(ctx, step, fn)
}

View File

@@ -194,7 +194,7 @@ func (c *Commands) PasswordCodeSent(ctx context.Context, orgID, userID string) (
return err
}
func (c *Commands) HumanCheckPassword(ctx context.Context, orgID, userID, password string, authRequest *domain.AuthRequest) (err error) {
func (c *Commands) HumanCheckPassword(ctx context.Context, orgID, userID, password string, authRequest *domain.AuthRequest, lockoutPolicy *domain.LockoutPolicy) (err error) {
ctx, span := tracing.NewSpan(ctx)
defer func() { span.EndWithError(err) }()
@@ -225,7 +225,15 @@ func (c *Commands) HumanCheckPassword(ctx context.Context, orgID, userID, passwo
_, err = c.eventstore.PushEvents(ctx, user.NewHumanPasswordCheckSucceededEvent(ctx, userAgg, authRequestDomainToAuthRequestInfo(authRequest)))
return err
}
_, err = c.eventstore.PushEvents(ctx, user.NewHumanPasswordCheckFailedEvent(ctx, userAgg, authRequestDomainToAuthRequestInfo(authRequest)))
events := make([]eventstore.EventPusher, 0)
events = append(events, user.NewHumanPasswordCheckFailedEvent(ctx, userAgg, authRequestDomainToAuthRequestInfo(authRequest)))
if lockoutPolicy != nil && lockoutPolicy.MaxPasswordAttempts > 0 {
if existingPassword.PasswordCheckFailedCount+1 >= lockoutPolicy.MaxPasswordAttempts {
events = append(events, user.NewUserLockedEvent(ctx, userAgg))
}
}
_, err = c.eventstore.PushEvents(ctx, events...)
logging.Log("COMMAND-9fj7s").OnError(err).Error("error create password check failed event")
return caos_errs.ThrowInvalidArgument(nil, "COMMAND-452ad", "Errors.User.Password.Invalid")
}

View File

@@ -16,9 +16,10 @@ type HumanPasswordWriteModel struct {
Secret *crypto.CryptoValue
SecretChangeRequired bool
Code *crypto.CryptoValue
CodeCreationDate time.Time
CodeExpiry time.Duration
Code *crypto.CryptoValue
CodeCreationDate time.Time
CodeExpiry time.Duration
PasswordCheckFailedCount uint64
UserState domain.UserState
}
@@ -51,6 +52,7 @@ func (wm *HumanPasswordWriteModel) Reduce() error {
wm.Secret = e.Secret
wm.SecretChangeRequired = e.ChangeRequired
wm.Code = nil
wm.PasswordCheckFailedCount = 0
case *user.HumanPasswordCodeAddedEvent:
wm.Code = e.Code
wm.CodeCreationDate = e.CreationDate()
@@ -59,6 +61,12 @@ func (wm *HumanPasswordWriteModel) Reduce() error {
if wm.UserState == domain.UserStateInitial {
wm.UserState = domain.UserStateActive
}
case *user.HumanPasswordCheckFailedEvent:
wm.PasswordCheckFailedCount += 1
case *user.HumanPasswordCheckSucceededEvent:
wm.PasswordCheckFailedCount = 0
case *user.UserUnlockedEvent:
wm.PasswordCheckFailedCount = 0
case *user.UserRemovedEvent:
wm.UserState = domain.UserStateDeleted
}
@@ -78,14 +86,19 @@ func (wm *HumanPasswordWriteModel) Query() *eventstore.SearchQueryBuilder {
user.HumanPasswordChangedType,
user.HumanPasswordCodeAddedType,
user.HumanEmailVerifiedType,
user.HumanPasswordCheckFailedType,
user.HumanPasswordCheckSucceededType,
user.UserRemovedType,
user.UserUnlockedType,
user.UserV1AddedType,
user.UserV1RegisteredType,
user.UserV1InitialCodeAddedType,
user.UserV1InitializedCheckSucceededType,
user.UserV1PasswordChangedType,
user.UserV1PasswordCodeAddedType,
user.UserV1EmailVerifiedType).
user.UserV1EmailVerifiedType,
user.UserV1PasswordCheckFailedType,
user.UserV1PasswordCheckSucceededType).
Builder()
if wm.ResourceOwner != "" {

View File

@@ -1082,6 +1082,7 @@ func TestCommandSide_CheckPassword(t *testing.T) {
resourceOwner string
password string
authReq *domain.AuthRequest
lockoutPolicy *domain.LockoutPolicy
}
type res struct {
err func(error) bool
@@ -1177,7 +1178,7 @@ func TestCommandSide_CheckPassword(t *testing.T) {
},
},
{
name: "password not matching, precondition error",
name: "password not matching lockout policy not relevant, precondition error",
fields: fields{
eventstore: eventstoreExpect(
t,
@@ -1238,6 +1239,82 @@ func TestCommandSide_CheckPassword(t *testing.T) {
ID: "request1",
AgentID: "agent1",
},
lockoutPolicy: &domain.LockoutPolicy{},
},
res: res{
err: caos_errs.IsErrorInvalidArgument,
},
},
{
name: "password not matching, max password attempts reached - user locked, precondition error",
fields: fields{
eventstore: eventstoreExpect(
t,
expectFilter(
eventFromEventPusher(
user.NewHumanAddedEvent(context.Background(),
&user.NewAggregate("user1", "org1").Aggregate,
"username",
"firstname",
"lastname",
"nickname",
"displayname",
language.German,
domain.GenderUnspecified,
"email@test.ch",
true,
),
),
eventFromEventPusher(
user.NewHumanEmailVerifiedEvent(context.Background(),
&user.NewAggregate("user1", "org1").Aggregate,
),
),
eventFromEventPusher(
user.NewHumanPasswordChangedEvent(context.Background(),
&user.NewAggregate("user1", "org1").Aggregate,
&crypto.CryptoValue{
CryptoType: crypto.TypeHash,
Algorithm: "hash",
KeyID: "",
Crypted: []byte("password"),
},
false,
"")),
),
expectPush(
[]*repository.Event{
eventFromEventPusher(
user.NewHumanPasswordCheckFailedEvent(context.Background(),
&user.NewAggregate("user1", "org1").Aggregate,
&user.AuthRequestInfo{
ID: "request1",
UserAgentID: "agent1",
},
),
),
eventFromEventPusher(
user.NewUserLockedEvent(context.Background(),
&user.NewAggregate("user1", "org1").Aggregate,
),
),
},
),
),
userPasswordAlg: crypto.CreateMockHashAlg(gomock.NewController(t)),
},
args: args{
ctx: context.Background(),
userID: "user1",
password: "password1",
resourceOwner: "org1",
authReq: &domain.AuthRequest{
ID: "request1",
AgentID: "agent1",
},
lockoutPolicy: &domain.LockoutPolicy{
MaxPasswordAttempts: 1,
},
},
res: res{
err: caos_errs.IsErrorInvalidArgument,
@@ -1315,7 +1392,7 @@ func TestCommandSide_CheckPassword(t *testing.T) {
eventstore: tt.fields.eventstore,
userPasswordAlg: tt.fields.userPasswordAlg,
}
err := r.HumanCheckPassword(tt.args.ctx, tt.args.resourceOwner, tt.args.userID, tt.args.password, tt.args.authReq)
err := r.HumanCheckPassword(tt.args.ctx, tt.args.resourceOwner, tt.args.userID, tt.args.password, tt.args.authReq, tt.args.lockoutPolicy)
if tt.res.err == nil {
assert.NoError(t, err)
}