mirror of
https://github.com/zitadel/zitadel.git
synced 2025-08-12 11:17:32 +00:00
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:
@@ -282,30 +282,30 @@ func (repo *IAMRepository) GetDefaultPasswordAgePolicy(ctx context.Context) (*ia
|
||||
return iam_es_model.PasswordAgeViewToModel(policy), nil
|
||||
}
|
||||
|
||||
func (repo *IAMRepository) GetDefaultPasswordLockoutPolicy(ctx context.Context) (*iam_model.PasswordLockoutPolicyView, error) {
|
||||
policy, viewErr := repo.View.PasswordLockoutPolicyByAggregateID(repo.SystemDefaults.IamID)
|
||||
func (repo *IAMRepository) GetDefaultLockoutPolicy(ctx context.Context) (*iam_model.LockoutPolicyView, error) {
|
||||
policy, viewErr := repo.View.LockoutPolicyByAggregateID(repo.SystemDefaults.IamID)
|
||||
if viewErr != nil && !caos_errs.IsNotFound(viewErr) {
|
||||
return nil, viewErr
|
||||
}
|
||||
if caos_errs.IsNotFound(viewErr) {
|
||||
policy = new(iam_es_model.PasswordLockoutPolicyView)
|
||||
policy = new(iam_es_model.LockoutPolicyView)
|
||||
}
|
||||
|
||||
events, esErr := repo.getIAMEvents(ctx, policy.Sequence)
|
||||
if caos_errs.IsNotFound(viewErr) && len(events) == 0 {
|
||||
return nil, caos_errs.ThrowNotFound(nil, "EVENT-2M9oP", "Errors.IAM.PasswordLockoutPolicy.NotFound")
|
||||
return nil, caos_errs.ThrowNotFound(nil, "EVENT-2M9oP", "Errors.IAM.LockoutPolicy.NotFound")
|
||||
}
|
||||
if esErr != nil {
|
||||
logging.Log("EVENT-3M0xs").WithError(esErr).Debug("error retrieving new events")
|
||||
return iam_es_model.PasswordLockoutViewToModel(policy), nil
|
||||
return iam_es_model.LockoutViewToModel(policy), nil
|
||||
}
|
||||
policyCopy := *policy
|
||||
for _, event := range events {
|
||||
if err := policyCopy.AppendEvent(event); err != nil {
|
||||
return iam_es_model.PasswordLockoutViewToModel(policy), nil
|
||||
return iam_es_model.LockoutViewToModel(policy), nil
|
||||
}
|
||||
}
|
||||
return iam_es_model.PasswordLockoutViewToModel(policy), nil
|
||||
return iam_es_model.LockoutViewToModel(policy), nil
|
||||
}
|
||||
|
||||
func (repo *IAMRepository) GetOrgIAMPolicy(ctx context.Context) (*iam_model.OrgIAMPolicyView, error) {
|
||||
|
@@ -3,6 +3,7 @@ package handler
|
||||
import (
|
||||
"time"
|
||||
|
||||
"github.com/caos/zitadel/internal/command"
|
||||
"github.com/caos/zitadel/internal/eventstore/v1"
|
||||
"github.com/caos/zitadel/internal/static"
|
||||
|
||||
@@ -31,7 +32,7 @@ func (h *handler) Eventstore() v1.Eventstore {
|
||||
return h.es
|
||||
}
|
||||
|
||||
func Register(configs Configs, bulkLimit, errorCount uint64, view *view.View, es v1.Eventstore, defaults systemdefaults.SystemDefaults, static static.Storage, localDevMode bool) []query.Handler {
|
||||
func Register(configs Configs, bulkLimit, errorCount uint64, view *view.View, es v1.Eventstore, defaults systemdefaults.SystemDefaults, command *command.Commands, static static.Storage, localDevMode bool) []query.Handler {
|
||||
handlers := []query.Handler{
|
||||
newOrg(
|
||||
handler{view, bulkLimit, configs.cycleDuration("Org"), errorCount, es}),
|
||||
@@ -53,8 +54,8 @@ func Register(configs Configs, bulkLimit, errorCount uint64, view *view.View, es
|
||||
handler{view, bulkLimit, configs.cycleDuration("PasswordComplexityPolicy"), errorCount, es}),
|
||||
newPasswordAgePolicy(
|
||||
handler{view, bulkLimit, configs.cycleDuration("PasswordAgePolicy"), errorCount, es}),
|
||||
newPasswordLockoutPolicy(
|
||||
handler{view, bulkLimit, configs.cycleDuration("PasswordLockoutPolicy"), errorCount, es}),
|
||||
newLockoutPolicy(
|
||||
handler{view, bulkLimit, configs.cycleDuration("LockoutPolicy"), errorCount, es}),
|
||||
newOrgIAMPolicy(
|
||||
handler{view, bulkLimit, configs.cycleDuration("OrgIAMPolicy"), errorCount, es}),
|
||||
newExternalIDP(
|
||||
|
@@ -13,16 +13,16 @@ import (
|
||||
)
|
||||
|
||||
const (
|
||||
passwordLockoutPolicyTable = "adminapi.password_lockout_policies"
|
||||
lockoutPolicyTable = "adminapi.lockout_policies"
|
||||
)
|
||||
|
||||
type PasswordLockoutPolicy struct {
|
||||
type LockoutPolicy struct {
|
||||
handler
|
||||
subscription *v1.Subscription
|
||||
}
|
||||
|
||||
func newPasswordLockoutPolicy(handler handler) *PasswordLockoutPolicy {
|
||||
h := &PasswordLockoutPolicy{
|
||||
func newLockoutPolicy(handler handler) *LockoutPolicy {
|
||||
h := &LockoutPolicy{
|
||||
handler: handler,
|
||||
}
|
||||
|
||||
@@ -31,7 +31,7 @@ func newPasswordLockoutPolicy(handler handler) *PasswordLockoutPolicy {
|
||||
return h
|
||||
}
|
||||
|
||||
func (p *PasswordLockoutPolicy) subscribe() {
|
||||
func (p *LockoutPolicy) subscribe() {
|
||||
p.subscription = p.es.Subscribe(p.AggregateTypes()...)
|
||||
go func() {
|
||||
for event := range p.subscription.Events {
|
||||
@@ -40,28 +40,28 @@ func (p *PasswordLockoutPolicy) subscribe() {
|
||||
}()
|
||||
}
|
||||
|
||||
func (p *PasswordLockoutPolicy) ViewModel() string {
|
||||
return passwordLockoutPolicyTable
|
||||
func (p *LockoutPolicy) ViewModel() string {
|
||||
return lockoutPolicyTable
|
||||
}
|
||||
|
||||
func (m *PasswordLockoutPolicy) Subscription() *v1.Subscription {
|
||||
func (m *LockoutPolicy) Subscription() *v1.Subscription {
|
||||
return m.subscription
|
||||
}
|
||||
|
||||
func (p *PasswordLockoutPolicy) AggregateTypes() []es_models.AggregateType {
|
||||
func (p *LockoutPolicy) AggregateTypes() []es_models.AggregateType {
|
||||
return []es_models.AggregateType{model.OrgAggregate, iam_es_model.IAMAggregate}
|
||||
}
|
||||
|
||||
func (p *PasswordLockoutPolicy) CurrentSequence() (uint64, error) {
|
||||
sequence, err := p.view.GetLatestPasswordLockoutPolicySequence()
|
||||
func (p *LockoutPolicy) CurrentSequence() (uint64, error) {
|
||||
sequence, err := p.view.GetLatestLockoutPolicySequence()
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
return sequence.CurrentSequence, nil
|
||||
}
|
||||
|
||||
func (p *PasswordLockoutPolicy) EventQuery() (*es_models.SearchQuery, error) {
|
||||
sequence, err := p.view.GetLatestPasswordLockoutPolicySequence()
|
||||
func (p *LockoutPolicy) EventQuery() (*es_models.SearchQuery, error) {
|
||||
sequence, err := p.view.GetLatestLockoutPolicySequence()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -70,41 +70,41 @@ func (p *PasswordLockoutPolicy) EventQuery() (*es_models.SearchQuery, error) {
|
||||
LatestSequenceFilter(sequence.CurrentSequence), nil
|
||||
}
|
||||
|
||||
func (p *PasswordLockoutPolicy) Reduce(event *es_models.Event) (err error) {
|
||||
func (p *LockoutPolicy) Reduce(event *es_models.Event) (err error) {
|
||||
switch event.AggregateType {
|
||||
case model.OrgAggregate, iam_es_model.IAMAggregate:
|
||||
err = p.processPasswordLockoutPolicy(event)
|
||||
err = p.processLockoutPolicy(event)
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
func (p *PasswordLockoutPolicy) processPasswordLockoutPolicy(event *es_models.Event) (err error) {
|
||||
policy := new(iam_model.PasswordLockoutPolicyView)
|
||||
func (p *LockoutPolicy) processLockoutPolicy(event *es_models.Event) (err error) {
|
||||
policy := new(iam_model.LockoutPolicyView)
|
||||
switch event.Type {
|
||||
case iam_es_model.PasswordLockoutPolicyAdded, model.PasswordLockoutPolicyAdded:
|
||||
case iam_es_model.LockoutPolicyAdded, model.LockoutPolicyAdded:
|
||||
err = policy.AppendEvent(event)
|
||||
case iam_es_model.PasswordLockoutPolicyChanged, model.PasswordLockoutPolicyChanged:
|
||||
policy, err = p.view.PasswordLockoutPolicyByAggregateID(event.AggregateID)
|
||||
case iam_es_model.LockoutPolicyChanged, model.LockoutPolicyChanged:
|
||||
policy, err = p.view.LockoutPolicyByAggregateID(event.AggregateID)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
err = policy.AppendEvent(event)
|
||||
case model.PasswordLockoutPolicyRemoved:
|
||||
return p.view.DeletePasswordLockoutPolicy(event.AggregateID, event)
|
||||
case model.LockoutPolicyRemoved:
|
||||
return p.view.DeleteLockoutPolicy(event.AggregateID, event)
|
||||
default:
|
||||
return p.view.ProcessedPasswordLockoutPolicySequence(event)
|
||||
return p.view.ProcessedLockoutPolicySequence(event)
|
||||
}
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return p.view.PutPasswordLockoutPolicy(policy, event)
|
||||
return p.view.PutLockoutPolicy(policy, event)
|
||||
}
|
||||
|
||||
func (p *PasswordLockoutPolicy) OnError(event *es_models.Event, err error) error {
|
||||
logging.LogWithFields("SPOOL-nD8sie", "id", event.AggregateID).WithError(err).Warn("something went wrong in passwordLockout policy handler")
|
||||
return spooler.HandleError(event, err, p.view.GetLatestPasswordLockoutPolicyFailedEvent, p.view.ProcessedPasswordLockoutPolicyFailedEvent, p.view.ProcessedPasswordLockoutPolicySequence, p.errorCountUntilSkip)
|
||||
func (p *LockoutPolicy) OnError(event *es_models.Event, err error) error {
|
||||
logging.LogWithFields("SPOOL-nD8sie", "id", event.AggregateID).WithError(err).Warn("something went wrong in Lockout policy handler")
|
||||
return spooler.HandleError(event, err, p.view.GetLatestLockoutPolicyFailedEvent, p.view.ProcessedLockoutPolicyFailedEvent, p.view.ProcessedLockoutPolicySequence, p.errorCountUntilSkip)
|
||||
}
|
||||
|
||||
func (p *PasswordLockoutPolicy) OnSuccess() error {
|
||||
return spooler.HandleSuccess(p.view.UpdatePasswordLockoutPolicySpoolerRunTimestamp)
|
||||
func (p *LockoutPolicy) OnSuccess() error {
|
||||
return spooler.HandleSuccess(p.view.UpdateLockoutPolicySpoolerRunTimestamp)
|
||||
}
|
||||
|
@@ -9,6 +9,7 @@ import (
|
||||
"github.com/caos/zitadel/internal/admin/repository/eventsourcing/eventstore"
|
||||
"github.com/caos/zitadel/internal/admin/repository/eventsourcing/spooler"
|
||||
admin_view "github.com/caos/zitadel/internal/admin/repository/eventsourcing/view"
|
||||
"github.com/caos/zitadel/internal/command"
|
||||
sd "github.com/caos/zitadel/internal/config/systemdefaults"
|
||||
"github.com/caos/zitadel/internal/config/types"
|
||||
"github.com/caos/zitadel/internal/eventstore/v1"
|
||||
@@ -34,7 +35,7 @@ type EsRepository struct {
|
||||
eventstore.UserRepo
|
||||
}
|
||||
|
||||
func Start(ctx context.Context, conf Config, systemDefaults sd.SystemDefaults, static static.Storage, roles []string, localDevMode bool) (*EsRepository, error) {
|
||||
func Start(ctx context.Context, conf Config, systemDefaults sd.SystemDefaults, command *command.Commands, static static.Storage, roles []string, localDevMode bool) (*EsRepository, error) {
|
||||
es, err := v1.Start(conf.Eventstore)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@@ -48,7 +49,7 @@ func Start(ctx context.Context, conf Config, systemDefaults sd.SystemDefaults, s
|
||||
return nil, err
|
||||
}
|
||||
|
||||
spool := spooler.StartSpooler(conf.Spooler, es, view, sqlClient, systemDefaults, static, localDevMode)
|
||||
spool := spooler.StartSpooler(conf.Spooler, es, view, sqlClient, systemDefaults, command, static, localDevMode)
|
||||
assetsAPI := conf.APIDomain + "/assets/v1/"
|
||||
|
||||
statikLoginFS, err := fs.NewWithNamespace("login")
|
||||
|
@@ -2,6 +2,7 @@ package spooler
|
||||
|
||||
import (
|
||||
"database/sql"
|
||||
"github.com/caos/zitadel/internal/command"
|
||||
"github.com/caos/zitadel/internal/config/systemdefaults"
|
||||
"github.com/caos/zitadel/internal/eventstore/v1"
|
||||
"github.com/caos/zitadel/internal/static"
|
||||
@@ -18,12 +19,12 @@ type SpoolerConfig struct {
|
||||
Handlers handler.Configs
|
||||
}
|
||||
|
||||
func StartSpooler(c SpoolerConfig, es v1.Eventstore, view *view.View, sql *sql.DB, defaults systemdefaults.SystemDefaults, static static.Storage, localDevMode bool) *spooler.Spooler {
|
||||
func StartSpooler(c SpoolerConfig, es v1.Eventstore, view *view.View, sql *sql.DB, defaults systemdefaults.SystemDefaults, command *command.Commands, static static.Storage, localDevMode bool) *spooler.Spooler {
|
||||
spoolerConfig := spooler.Config{
|
||||
Eventstore: es,
|
||||
Locker: &locker{dbClient: sql},
|
||||
ConcurrentWorkers: c.ConcurrentWorkers,
|
||||
ViewHandlers: handler.Register(c.Handlers, c.BulkLimit, c.FailureCountUntilSkip, view, es, defaults, static, localDevMode),
|
||||
ViewHandlers: handler.Register(c.Handlers, c.BulkLimit, c.FailureCountUntilSkip, view, es, defaults, command, static, localDevMode),
|
||||
}
|
||||
spool := spoolerConfig.New()
|
||||
spool.Start()
|
||||
|
@@ -0,0 +1,53 @@
|
||||
package view
|
||||
|
||||
import (
|
||||
"github.com/caos/zitadel/internal/errors"
|
||||
"github.com/caos/zitadel/internal/eventstore/v1/models"
|
||||
"github.com/caos/zitadel/internal/iam/repository/view"
|
||||
"github.com/caos/zitadel/internal/iam/repository/view/model"
|
||||
global_view "github.com/caos/zitadel/internal/view/repository"
|
||||
)
|
||||
|
||||
const (
|
||||
lockoutPolicyTable = "adminapi.lockout_policies"
|
||||
)
|
||||
|
||||
func (v *View) LockoutPolicyByAggregateID(aggregateID string) (*model.LockoutPolicyView, error) {
|
||||
return view.GetLockoutPolicyByAggregateID(v.Db, lockoutPolicyTable, aggregateID)
|
||||
}
|
||||
|
||||
func (v *View) PutLockoutPolicy(policy *model.LockoutPolicyView, event *models.Event) error {
|
||||
err := view.PutLockoutPolicy(v.Db, lockoutPolicyTable, policy)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return v.ProcessedLockoutPolicySequence(event)
|
||||
}
|
||||
|
||||
func (v *View) DeleteLockoutPolicy(aggregateID string, event *models.Event) error {
|
||||
err := view.DeleteLockoutPolicy(v.Db, lockoutPolicyTable, aggregateID)
|
||||
if err != nil && !errors.IsNotFound(err) {
|
||||
return err
|
||||
}
|
||||
return v.ProcessedLockoutPolicySequence(event)
|
||||
}
|
||||
|
||||
func (v *View) GetLatestLockoutPolicySequence() (*global_view.CurrentSequence, error) {
|
||||
return v.latestSequence(lockoutPolicyTable)
|
||||
}
|
||||
|
||||
func (v *View) ProcessedLockoutPolicySequence(event *models.Event) error {
|
||||
return v.saveCurrentSequence(lockoutPolicyTable, event)
|
||||
}
|
||||
|
||||
func (v *View) UpdateLockoutPolicySpoolerRunTimestamp() error {
|
||||
return v.updateSpoolerRunSequence(lockoutPolicyTable)
|
||||
}
|
||||
|
||||
func (v *View) GetLatestLockoutPolicyFailedEvent(sequence uint64) (*global_view.FailedEvent, error) {
|
||||
return v.latestFailedEvent(lockoutPolicyTable, sequence)
|
||||
}
|
||||
|
||||
func (v *View) ProcessedLockoutPolicyFailedEvent(failedEvent *global_view.FailedEvent) error {
|
||||
return v.saveFailedEvent(failedEvent)
|
||||
}
|
@@ -1,53 +0,0 @@
|
||||
package view
|
||||
|
||||
import (
|
||||
"github.com/caos/zitadel/internal/errors"
|
||||
"github.com/caos/zitadel/internal/eventstore/v1/models"
|
||||
"github.com/caos/zitadel/internal/iam/repository/view"
|
||||
"github.com/caos/zitadel/internal/iam/repository/view/model"
|
||||
global_view "github.com/caos/zitadel/internal/view/repository"
|
||||
)
|
||||
|
||||
const (
|
||||
passwordLockoutPolicyTable = "adminapi.password_lockout_policies"
|
||||
)
|
||||
|
||||
func (v *View) PasswordLockoutPolicyByAggregateID(aggregateID string) (*model.PasswordLockoutPolicyView, error) {
|
||||
return view.GetPasswordLockoutPolicyByAggregateID(v.Db, passwordLockoutPolicyTable, aggregateID)
|
||||
}
|
||||
|
||||
func (v *View) PutPasswordLockoutPolicy(policy *model.PasswordLockoutPolicyView, event *models.Event) error {
|
||||
err := view.PutPasswordLockoutPolicy(v.Db, passwordLockoutPolicyTable, policy)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return v.ProcessedPasswordLockoutPolicySequence(event)
|
||||
}
|
||||
|
||||
func (v *View) DeletePasswordLockoutPolicy(aggregateID string, event *models.Event) error {
|
||||
err := view.DeletePasswordLockoutPolicy(v.Db, passwordLockoutPolicyTable, aggregateID)
|
||||
if err != nil && !errors.IsNotFound(err) {
|
||||
return err
|
||||
}
|
||||
return v.ProcessedPasswordLockoutPolicySequence(event)
|
||||
}
|
||||
|
||||
func (v *View) GetLatestPasswordLockoutPolicySequence() (*global_view.CurrentSequence, error) {
|
||||
return v.latestSequence(passwordLockoutPolicyTable)
|
||||
}
|
||||
|
||||
func (v *View) ProcessedPasswordLockoutPolicySequence(event *models.Event) error {
|
||||
return v.saveCurrentSequence(passwordLockoutPolicyTable, event)
|
||||
}
|
||||
|
||||
func (v *View) UpdatePasswordLockoutPolicySpoolerRunTimestamp() error {
|
||||
return v.updateSpoolerRunSequence(passwordLockoutPolicyTable)
|
||||
}
|
||||
|
||||
func (v *View) GetLatestPasswordLockoutPolicyFailedEvent(sequence uint64) (*global_view.FailedEvent, error) {
|
||||
return v.latestFailedEvent(passwordLockoutPolicyTable, sequence)
|
||||
}
|
||||
|
||||
func (v *View) ProcessedPasswordLockoutPolicyFailedEvent(failedEvent *global_view.FailedEvent) error {
|
||||
return v.saveFailedEvent(failedEvent)
|
||||
}
|
@@ -43,7 +43,7 @@ type IAMRepository interface {
|
||||
|
||||
GetDefaultPasswordAgePolicy(ctx context.Context) (*iam_model.PasswordAgePolicyView, error)
|
||||
|
||||
GetDefaultPasswordLockoutPolicy(ctx context.Context) (*iam_model.PasswordLockoutPolicyView, error)
|
||||
GetDefaultLockoutPolicy(ctx context.Context) (*iam_model.LockoutPolicyView, error)
|
||||
|
||||
GetDefaultPrivacyPolicy(ctx context.Context) (*iam_model.PrivacyPolicyView, error)
|
||||
|
||||
|
31
internal/api/grpc/admin/lockout.go
Normal file
31
internal/api/grpc/admin/lockout.go
Normal file
@@ -0,0 +1,31 @@
|
||||
package admin
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/caos/zitadel/internal/api/grpc/object"
|
||||
policy_grpc "github.com/caos/zitadel/internal/api/grpc/policy"
|
||||
admin_pb "github.com/caos/zitadel/pkg/grpc/admin"
|
||||
)
|
||||
|
||||
func (s *Server) GetLockoutPolicy(ctx context.Context, req *admin_pb.GetLockoutPolicyRequest) (*admin_pb.GetLockoutPolicyResponse, error) {
|
||||
policy, err := s.iam.GetDefaultLockoutPolicy(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &admin_pb.GetLockoutPolicyResponse{Policy: policy_grpc.ModelLockoutPolicyToPb(policy)}, nil
|
||||
}
|
||||
|
||||
func (s *Server) UpdateLockoutPolicy(ctx context.Context, req *admin_pb.UpdateLockoutPolicyRequest) (*admin_pb.UpdateLockoutPolicyResponse, error) {
|
||||
policy, err := s.command.ChangeDefaultLockoutPolicy(ctx, UpdateLockoutPolicyToDomain(req))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &admin_pb.UpdateLockoutPolicyResponse{
|
||||
Details: object.ChangeToDetailsPb(
|
||||
policy.Sequence,
|
||||
policy.ChangeDate,
|
||||
policy.ResourceOwner,
|
||||
),
|
||||
}, nil
|
||||
}
|
12
internal/api/grpc/admin/lockout_converter.go
Normal file
12
internal/api/grpc/admin/lockout_converter.go
Normal file
@@ -0,0 +1,12 @@
|
||||
package admin
|
||||
|
||||
import (
|
||||
"github.com/caos/zitadel/internal/domain"
|
||||
"github.com/caos/zitadel/pkg/grpc/admin"
|
||||
)
|
||||
|
||||
func UpdateLockoutPolicyToDomain(p *admin.UpdateLockoutPolicyRequest) *domain.LockoutPolicy {
|
||||
return &domain.LockoutPolicy{
|
||||
MaxPasswordAttempts: uint64(p.MaxPasswordAttempts),
|
||||
}
|
||||
}
|
@@ -1,31 +0,0 @@
|
||||
package admin
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/caos/zitadel/internal/api/grpc/object"
|
||||
policy_grpc "github.com/caos/zitadel/internal/api/grpc/policy"
|
||||
admin_pb "github.com/caos/zitadel/pkg/grpc/admin"
|
||||
)
|
||||
|
||||
func (s *Server) GetPasswordLockoutPolicy(ctx context.Context, req *admin_pb.GetPasswordLockoutPolicyRequest) (*admin_pb.GetPasswordLockoutPolicyResponse, error) {
|
||||
policy, err := s.iam.GetDefaultPasswordLockoutPolicy(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &admin_pb.GetPasswordLockoutPolicyResponse{Policy: policy_grpc.ModelPasswordLockoutPolicyToPb(policy)}, nil
|
||||
}
|
||||
|
||||
func (s *Server) UpdatePasswordLockoutPolicy(ctx context.Context, req *admin_pb.UpdatePasswordLockoutPolicyRequest) (*admin_pb.UpdatePasswordLockoutPolicyResponse, error) {
|
||||
policy, err := s.command.ChangeDefaultPasswordLockoutPolicy(ctx, UpdatePasswordLockoutPolicyToDomain(req))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &admin_pb.UpdatePasswordLockoutPolicyResponse{
|
||||
Details: object.ChangeToDetailsPb(
|
||||
policy.Sequence,
|
||||
policy.ChangeDate,
|
||||
policy.ResourceOwner,
|
||||
),
|
||||
}, nil
|
||||
}
|
@@ -1,13 +0,0 @@
|
||||
package admin
|
||||
|
||||
import (
|
||||
"github.com/caos/zitadel/internal/domain"
|
||||
"github.com/caos/zitadel/pkg/grpc/admin"
|
||||
)
|
||||
|
||||
func UpdatePasswordLockoutPolicyToDomain(p *admin.UpdatePasswordLockoutPolicyRequest) *domain.PasswordLockoutPolicy {
|
||||
return &domain.PasswordLockoutPolicy{
|
||||
MaxAttempts: uint64(p.MaxAttempts),
|
||||
ShowLockOutFailures: p.ShowLockoutFailure,
|
||||
}
|
||||
}
|
63
internal/api/grpc/management/policy_lockout.go
Normal file
63
internal/api/grpc/management/policy_lockout.go
Normal file
@@ -0,0 +1,63 @@
|
||||
package management
|
||||
|
||||
import (
|
||||
"context"
|
||||
"github.com/caos/zitadel/internal/api/authz"
|
||||
"github.com/caos/zitadel/internal/api/grpc/object"
|
||||
policy_grpc "github.com/caos/zitadel/internal/api/grpc/policy"
|
||||
mgmt_pb "github.com/caos/zitadel/pkg/grpc/management"
|
||||
)
|
||||
|
||||
func (s *Server) GetLockoutPolicy(ctx context.Context, req *mgmt_pb.GetLockoutPolicyRequest) (*mgmt_pb.GetLockoutPolicyResponse, error) {
|
||||
policy, err := s.org.GetLockoutPolicy(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &mgmt_pb.GetLockoutPolicyResponse{Policy: policy_grpc.ModelLockoutPolicyToPb(policy), IsDefault: policy.Default}, nil
|
||||
}
|
||||
|
||||
func (s *Server) GetDefaultLockoutPolicy(ctx context.Context, req *mgmt_pb.GetDefaultLockoutPolicyRequest) (*mgmt_pb.GetDefaultLockoutPolicyResponse, error) {
|
||||
policy, err := s.org.GetDefaultLockoutPolicy(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &mgmt_pb.GetDefaultLockoutPolicyResponse{Policy: policy_grpc.ModelLockoutPolicyToPb(policy)}, nil
|
||||
}
|
||||
|
||||
func (s *Server) AddCustomLockoutPolicy(ctx context.Context, req *mgmt_pb.AddCustomLockoutPolicyRequest) (*mgmt_pb.AddCustomLockoutPolicyResponse, error) {
|
||||
policy, err := s.command.AddLockoutPolicy(ctx, authz.GetCtxData(ctx).OrgID, AddLockoutPolicyToDomain(req))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &mgmt_pb.AddCustomLockoutPolicyResponse{
|
||||
Details: object.AddToDetailsPb(
|
||||
policy.Sequence,
|
||||
policy.ChangeDate,
|
||||
policy.ResourceOwner,
|
||||
),
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (s *Server) UpdateCustomLockoutPolicy(ctx context.Context, req *mgmt_pb.UpdateCustomLockoutPolicyRequest) (*mgmt_pb.UpdateCustomLockoutPolicyResponse, error) {
|
||||
policy, err := s.command.ChangeLockoutPolicy(ctx, authz.GetCtxData(ctx).OrgID, UpdateLockoutPolicyToDomain(req))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &mgmt_pb.UpdateCustomLockoutPolicyResponse{
|
||||
Details: object.ChangeToDetailsPb(
|
||||
policy.Sequence,
|
||||
policy.ChangeDate,
|
||||
policy.ResourceOwner,
|
||||
),
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (s *Server) ResetLockoutPolicyToDefault(ctx context.Context, req *mgmt_pb.ResetLockoutPolicyToDefaultRequest) (*mgmt_pb.ResetLockoutPolicyToDefaultResponse, error) {
|
||||
objectDetails, err := s.command.RemovePasswordComplexityPolicy(ctx, authz.GetCtxData(ctx).OrgID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &mgmt_pb.ResetLockoutPolicyToDefaultResponse{
|
||||
Details: object.DomainToChangeDetailsPb(objectDetails),
|
||||
}, nil
|
||||
}
|
18
internal/api/grpc/management/policy_lockout_converter.go
Normal file
18
internal/api/grpc/management/policy_lockout_converter.go
Normal file
@@ -0,0 +1,18 @@
|
||||
package management
|
||||
|
||||
import (
|
||||
"github.com/caos/zitadel/internal/domain"
|
||||
mgmt "github.com/caos/zitadel/pkg/grpc/management"
|
||||
)
|
||||
|
||||
func AddLockoutPolicyToDomain(p *mgmt.AddCustomLockoutPolicyRequest) *domain.LockoutPolicy {
|
||||
return &domain.LockoutPolicy{
|
||||
MaxPasswordAttempts: uint64(p.MaxPasswordAttempts),
|
||||
}
|
||||
}
|
||||
|
||||
func UpdateLockoutPolicyToDomain(p *mgmt.UpdateCustomLockoutPolicyRequest) *domain.LockoutPolicy {
|
||||
return &domain.LockoutPolicy{
|
||||
MaxPasswordAttempts: uint64(p.MaxPasswordAttempts),
|
||||
}
|
||||
}
|
@@ -1,63 +0,0 @@
|
||||
package management
|
||||
|
||||
import (
|
||||
"context"
|
||||
"github.com/caos/zitadel/internal/api/authz"
|
||||
"github.com/caos/zitadel/internal/api/grpc/object"
|
||||
policy_grpc "github.com/caos/zitadel/internal/api/grpc/policy"
|
||||
mgmt_pb "github.com/caos/zitadel/pkg/grpc/management"
|
||||
)
|
||||
|
||||
func (s *Server) GetPasswordLockoutPolicy(ctx context.Context, req *mgmt_pb.GetPasswordLockoutPolicyRequest) (*mgmt_pb.GetPasswordLockoutPolicyResponse, error) {
|
||||
policy, err := s.org.GetPasswordLockoutPolicy(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &mgmt_pb.GetPasswordLockoutPolicyResponse{Policy: policy_grpc.ModelPasswordLockoutPolicyToPb(policy), IsDefault: policy.Default}, nil
|
||||
}
|
||||
|
||||
func (s *Server) GetDefaultPasswordLockoutPolicy(ctx context.Context, req *mgmt_pb.GetDefaultPasswordLockoutPolicyRequest) (*mgmt_pb.GetDefaultPasswordLockoutPolicyResponse, error) {
|
||||
policy, err := s.org.GetDefaultPasswordLockoutPolicy(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &mgmt_pb.GetDefaultPasswordLockoutPolicyResponse{Policy: policy_grpc.ModelPasswordLockoutPolicyToPb(policy)}, nil
|
||||
}
|
||||
|
||||
func (s *Server) AddCustomPasswordLockoutPolicy(ctx context.Context, req *mgmt_pb.AddCustomPasswordLockoutPolicyRequest) (*mgmt_pb.AddCustomPasswordLockoutPolicyResponse, error) {
|
||||
policy, err := s.command.AddPasswordLockoutPolicy(ctx, authz.GetCtxData(ctx).OrgID, AddPasswordLockoutPolicyToDomain(req))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &mgmt_pb.AddCustomPasswordLockoutPolicyResponse{
|
||||
Details: object.AddToDetailsPb(
|
||||
policy.Sequence,
|
||||
policy.ChangeDate,
|
||||
policy.ResourceOwner,
|
||||
),
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (s *Server) UpdateCustomPasswordLockoutPolicy(ctx context.Context, req *mgmt_pb.UpdateCustomPasswordLockoutPolicyRequest) (*mgmt_pb.UpdateCustomPasswordLockoutPolicyResponse, error) {
|
||||
policy, err := s.command.ChangePasswordLockoutPolicy(ctx, authz.GetCtxData(ctx).OrgID, UpdatePasswordLockoutPolicyToDomain(req))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &mgmt_pb.UpdateCustomPasswordLockoutPolicyResponse{
|
||||
Details: object.ChangeToDetailsPb(
|
||||
policy.Sequence,
|
||||
policy.ChangeDate,
|
||||
policy.ResourceOwner,
|
||||
),
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (s *Server) ResetPasswordLockoutPolicyToDefault(ctx context.Context, req *mgmt_pb.ResetPasswordLockoutPolicyToDefaultRequest) (*mgmt_pb.ResetPasswordLockoutPolicyToDefaultResponse, error) {
|
||||
objectDetails, err := s.command.RemovePasswordComplexityPolicy(ctx, authz.GetCtxData(ctx).OrgID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &mgmt_pb.ResetPasswordLockoutPolicyToDefaultResponse{
|
||||
Details: object.DomainToChangeDetailsPb(objectDetails),
|
||||
}, nil
|
||||
}
|
@@ -1,20 +0,0 @@
|
||||
package management
|
||||
|
||||
import (
|
||||
"github.com/caos/zitadel/internal/domain"
|
||||
mgmt "github.com/caos/zitadel/pkg/grpc/management"
|
||||
)
|
||||
|
||||
func AddPasswordLockoutPolicyToDomain(p *mgmt.AddCustomPasswordLockoutPolicyRequest) *domain.PasswordLockoutPolicy {
|
||||
return &domain.PasswordLockoutPolicy{
|
||||
MaxAttempts: uint64(p.MaxAttempts),
|
||||
ShowLockOutFailures: p.ShowLockoutFailure,
|
||||
}
|
||||
}
|
||||
|
||||
func UpdatePasswordLockoutPolicyToDomain(p *mgmt.UpdateCustomPasswordLockoutPolicyRequest) *domain.PasswordLockoutPolicy {
|
||||
return &domain.PasswordLockoutPolicy{
|
||||
MaxAttempts: uint64(p.MaxAttempts),
|
||||
ShowLockOutFailures: p.ShowLockoutFailure,
|
||||
}
|
||||
}
|
@@ -6,11 +6,10 @@ import (
|
||||
policy_pb "github.com/caos/zitadel/pkg/grpc/policy"
|
||||
)
|
||||
|
||||
func ModelPasswordLockoutPolicyToPb(policy *model.PasswordLockoutPolicyView) *policy_pb.PasswordLockoutPolicy {
|
||||
return &policy_pb.PasswordLockoutPolicy{
|
||||
IsDefault: policy.Default,
|
||||
MaxAttempts: policy.MaxAttempts,
|
||||
ShowLockoutFailure: policy.ShowLockOutFailures,
|
||||
func ModelLockoutPolicyToPb(policy *model.LockoutPolicyView) *policy_pb.LockoutPolicy {
|
||||
return &policy_pb.LockoutPolicy{
|
||||
IsDefault: policy.Default,
|
||||
MaxPasswordAttempts: policy.MaxPasswordAttempts,
|
||||
Details: object.ToViewDetailsPb(
|
||||
policy.Sequence,
|
||||
policy.CreationDate,
|
||||
|
@@ -35,14 +35,15 @@ type AuthRequestRepo struct {
|
||||
View *view.View
|
||||
Eventstore v1.Eventstore
|
||||
|
||||
UserSessionViewProvider userSessionViewProvider
|
||||
UserViewProvider userViewProvider
|
||||
UserCommandProvider userCommandProvider
|
||||
UserEventProvider userEventProvider
|
||||
OrgViewProvider orgViewProvider
|
||||
LoginPolicyViewProvider loginPolicyViewProvider
|
||||
IDPProviderViewProvider idpProviderViewProvider
|
||||
UserGrantProvider userGrantProvider
|
||||
UserSessionViewProvider userSessionViewProvider
|
||||
UserViewProvider userViewProvider
|
||||
UserCommandProvider userCommandProvider
|
||||
UserEventProvider userEventProvider
|
||||
OrgViewProvider orgViewProvider
|
||||
LoginPolicyViewProvider loginPolicyViewProvider
|
||||
LockoutPolicyViewProvider lockoutPolicyViewProvider
|
||||
IDPProviderViewProvider idpProviderViewProvider
|
||||
UserGrantProvider userGrantProvider
|
||||
|
||||
IdGenerator id.Generator
|
||||
|
||||
@@ -69,6 +70,10 @@ type loginPolicyViewProvider interface {
|
||||
LoginPolicyByAggregateID(string) (*iam_view_model.LoginPolicyView, error)
|
||||
}
|
||||
|
||||
type lockoutPolicyViewProvider interface {
|
||||
LockoutPolicyByAggregateID(string) (*iam_view_model.LockoutPolicyView, error)
|
||||
}
|
||||
|
||||
type idpProviderViewProvider interface {
|
||||
IDPProvidersByAggregateIDAndState(string, iam_model.IDPConfigState) ([]*iam_view_model.IDPProviderView, error)
|
||||
}
|
||||
@@ -240,7 +245,7 @@ func (repo *AuthRequestRepo) SelectUser(ctx context.Context, id, userID, userAge
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
user, err := activeUserByID(ctx, repo.UserViewProvider, repo.UserEventProvider, repo.OrgViewProvider, userID)
|
||||
user, err := activeUserByID(ctx, repo.UserViewProvider, repo.UserEventProvider, repo.OrgViewProvider, repo.LockoutPolicyViewProvider, userID)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -262,7 +267,11 @@ func (repo *AuthRequestRepo) VerifyPassword(ctx context.Context, id, userID, res
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return repo.Command.HumanCheckPassword(ctx, resourceOwner, userID, password, request.WithCurrentInfo(info))
|
||||
policy, err := repo.getLockoutPolicy(ctx, resourceOwner)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return repo.Command.HumanCheckPassword(ctx, resourceOwner, userID, password, request.WithCurrentInfo(info), policy)
|
||||
}
|
||||
|
||||
func (repo *AuthRequestRepo) VerifyMFAOTP(ctx context.Context, authRequestID, userID, resourceOwner, code, userAgentID string, info *domain.BrowserInfo) (err error) {
|
||||
@@ -414,6 +423,10 @@ func (repo *AuthRequestRepo) getAuthRequestEnsureUser(ctx context.Context, authR
|
||||
if request.UserID != userID {
|
||||
return nil, errors.ThrowPreconditionFailed(nil, "EVENT-GBH32", "Errors.User.NotMatchingUserID")
|
||||
}
|
||||
_, err = activeUserByID(ctx, repo.UserViewProvider, repo.UserEventProvider, repo.OrgViewProvider, repo.LockoutPolicyViewProvider, request.UserID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return request, nil
|
||||
}
|
||||
|
||||
@@ -466,6 +479,11 @@ func (repo *AuthRequestRepo) fillPolicies(ctx context.Context, request *domain.A
|
||||
if idpProviders != nil {
|
||||
request.AllowedExternalIDPs = idpProviders
|
||||
}
|
||||
lockoutPolicy, err := repo.getLockoutPolicy(ctx, orgID)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
request.LockoutPolicy = lockoutPolicy
|
||||
privacyPolicy, err := repo.getPrivacyPolicy(ctx, orgID)
|
||||
if err != nil {
|
||||
return err
|
||||
@@ -587,7 +605,7 @@ func (repo *AuthRequestRepo) nextSteps(ctx context.Context, request *domain.Auth
|
||||
}
|
||||
return steps, nil
|
||||
}
|
||||
user, err := activeUserByID(ctx, repo.UserViewProvider, repo.UserEventProvider, repo.OrgViewProvider, request.UserID)
|
||||
user, err := activeUserByID(ctx, repo.UserViewProvider, repo.UserEventProvider, repo.OrgViewProvider, repo.LockoutPolicyViewProvider, request.UserID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -795,6 +813,21 @@ func (repo *AuthRequestRepo) getPrivacyPolicy(ctx context.Context, orgID string)
|
||||
return policy.ToDomain(), err
|
||||
}
|
||||
|
||||
func (repo *AuthRequestRepo) getLockoutPolicy(ctx context.Context, orgID string) (*domain.LockoutPolicy, error) {
|
||||
policy, err := repo.View.LockoutPolicyByAggregateID(orgID)
|
||||
if errors.IsNotFound(err) {
|
||||
policy, err = repo.View.LockoutPolicyByAggregateID(repo.IAMID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
policy.Default = true
|
||||
}
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return policy.ToDomain(), err
|
||||
}
|
||||
|
||||
func (repo *AuthRequestRepo) getLabelPolicy(ctx context.Context, orgID string) (*domain.LabelPolicy, error) {
|
||||
policy, err := repo.View.LabelPolicyByAggregateIDAndState(orgID, int32(domain.LabelPolicyStateActive))
|
||||
if errors.IsNotFound(err) {
|
||||
@@ -921,7 +954,8 @@ func userSessionByIDs(ctx context.Context, provider userSessionViewProvider, eve
|
||||
return user_view_model.UserSessionToModel(&sessionCopy, provider.PrefixAvatarURL()), nil
|
||||
}
|
||||
|
||||
func activeUserByID(ctx context.Context, userViewProvider userViewProvider, userEventProvider userEventProvider, orgViewProvider orgViewProvider, userID string) (*user_model.UserView, error) {
|
||||
func activeUserByID(ctx context.Context, userViewProvider userViewProvider, userEventProvider userEventProvider, orgViewProvider orgViewProvider, lockoutPolicyProvider lockoutPolicyViewProvider, userID string) (*user_model.UserView, error) {
|
||||
// PLANNED: Check LockoutPolicy
|
||||
user, err := userByID(ctx, userViewProvider, userEventProvider, userID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@@ -930,7 +964,6 @@ func activeUserByID(ctx context.Context, userViewProvider userViewProvider, user
|
||||
if user.HumanView == nil {
|
||||
return nil, errors.ThrowPreconditionFailed(nil, "EVENT-Lm69x", "Errors.User.NotHuman")
|
||||
}
|
||||
|
||||
if user.State == user_model.UserStateLocked || user.State == user_model.UserStateSuspend {
|
||||
return nil, errors.ThrowPreconditionFailed(nil, "EVENT-FJ262", "Errors.User.Locked")
|
||||
}
|
||||
|
@@ -152,6 +152,14 @@ func (m *mockLoginPolicy) LoginPolicyByAggregateID(id string) (*iam_view_model.L
|
||||
return m.policy, nil
|
||||
}
|
||||
|
||||
type mockLockoutPolicy struct {
|
||||
policy *iam_view_model.LockoutPolicyView
|
||||
}
|
||||
|
||||
func (m *mockLockoutPolicy) LockoutPolicyByAggregateID(id string) (*iam_view_model.LockoutPolicyView, error) {
|
||||
return m.policy, nil
|
||||
}
|
||||
|
||||
func (m *mockViewUser) UserByID(string) (*user_view_model.UserView, error) {
|
||||
return &user_view_model.UserView{
|
||||
State: int32(user_model.UserStateActive),
|
||||
@@ -229,6 +237,7 @@ func TestAuthRequestRepo_nextSteps(t *testing.T) {
|
||||
orgViewProvider orgViewProvider
|
||||
userGrantProvider userGrantProvider
|
||||
loginPolicyProvider loginPolicyViewProvider
|
||||
lockoutPolicyProvider lockoutPolicyViewProvider
|
||||
PasswordCheckLifeTime time.Duration
|
||||
ExternalLoginCheckLifeTime time.Duration
|
||||
MFAInitSkippedLifeTime time.Duration
|
||||
@@ -404,6 +413,11 @@ func TestAuthRequestRepo_nextSteps(t *testing.T) {
|
||||
},
|
||||
},
|
||||
orgViewProvider: &mockViewOrg{State: org_model.OrgStateActive},
|
||||
lockoutPolicyProvider: &mockLockoutPolicy{
|
||||
policy: &iam_view_model.LockoutPolicyView{
|
||||
ShowLockOutFailures: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
args{&domain.AuthRequest{UserID: "UserID"}, false},
|
||||
nil,
|
||||
@@ -420,6 +434,11 @@ func TestAuthRequestRepo_nextSteps(t *testing.T) {
|
||||
},
|
||||
},
|
||||
orgViewProvider: &mockViewOrg{State: org_model.OrgStateActive},
|
||||
lockoutPolicyProvider: &mockLockoutPolicy{
|
||||
policy: &iam_view_model.LockoutPolicyView{
|
||||
ShowLockOutFailures: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
args{&domain.AuthRequest{UserID: "UserID"}, false},
|
||||
nil,
|
||||
@@ -431,6 +450,11 @@ func TestAuthRequestRepo_nextSteps(t *testing.T) {
|
||||
userViewProvider: &mockViewUser{},
|
||||
userEventProvider: &mockEventUser{},
|
||||
orgViewProvider: &mockViewErrOrg{},
|
||||
lockoutPolicyProvider: &mockLockoutPolicy{
|
||||
policy: &iam_view_model.LockoutPolicyView{
|
||||
ShowLockOutFailures: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
args{&domain.AuthRequest{UserID: "UserID"}, false},
|
||||
nil,
|
||||
@@ -442,6 +466,11 @@ func TestAuthRequestRepo_nextSteps(t *testing.T) {
|
||||
userViewProvider: &mockViewUser{},
|
||||
userEventProvider: &mockEventUser{},
|
||||
orgViewProvider: &mockViewOrg{State: org_model.OrgStateInactive},
|
||||
lockoutPolicyProvider: &mockLockoutPolicy{
|
||||
policy: &iam_view_model.LockoutPolicyView{
|
||||
ShowLockOutFailures: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
args{&domain.AuthRequest{UserID: "UserID"}, false},
|
||||
nil,
|
||||
@@ -456,6 +485,11 @@ func TestAuthRequestRepo_nextSteps(t *testing.T) {
|
||||
},
|
||||
userEventProvider: &mockEventUser{},
|
||||
orgViewProvider: &mockViewOrg{State: org_model.OrgStateActive},
|
||||
lockoutPolicyProvider: &mockLockoutPolicy{
|
||||
policy: &iam_view_model.LockoutPolicyView{
|
||||
ShowLockOutFailures: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
args{&domain.AuthRequest{UserID: "UserID", LoginPolicy: &domain.LoginPolicy{}}, false},
|
||||
[]domain.NextStep{&domain.PasswordStep{}},
|
||||
@@ -468,6 +502,11 @@ func TestAuthRequestRepo_nextSteps(t *testing.T) {
|
||||
userViewProvider: &mockViewUser{},
|
||||
userEventProvider: &mockEventUser{},
|
||||
orgViewProvider: &mockViewOrg{State: org_model.OrgStateActive},
|
||||
lockoutPolicyProvider: &mockLockoutPolicy{
|
||||
policy: &iam_view_model.LockoutPolicyView{
|
||||
ShowLockOutFailures: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
args{&domain.AuthRequest{UserID: "UserID"}, false},
|
||||
nil,
|
||||
@@ -483,6 +522,11 @@ func TestAuthRequestRepo_nextSteps(t *testing.T) {
|
||||
},
|
||||
userEventProvider: &mockEventUser{},
|
||||
orgViewProvider: &mockViewOrg{State: org_model.OrgStateActive},
|
||||
lockoutPolicyProvider: &mockLockoutPolicy{
|
||||
policy: &iam_view_model.LockoutPolicyView{
|
||||
ShowLockOutFailures: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
args{&domain.AuthRequest{UserID: "UserID"}, false},
|
||||
[]domain.NextStep{&domain.InitUserStep{
|
||||
@@ -500,6 +544,11 @@ func TestAuthRequestRepo_nextSteps(t *testing.T) {
|
||||
userEventProvider: &mockEventUser{},
|
||||
orgViewProvider: &mockViewOrg{State: org_model.OrgStateActive},
|
||||
MultiFactorCheckLifeTime: 10 * time.Hour,
|
||||
lockoutPolicyProvider: &mockLockoutPolicy{
|
||||
policy: &iam_view_model.LockoutPolicyView{
|
||||
ShowLockOutFailures: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
args{&domain.AuthRequest{UserID: "UserID", LoginPolicy: &domain.LoginPolicy{PasswordlessType: domain.PasswordlessTypeAllowed}}, false},
|
||||
[]domain.NextStep{&domain.PasswordlessRegistrationPromptStep{}},
|
||||
@@ -512,8 +561,13 @@ func TestAuthRequestRepo_nextSteps(t *testing.T) {
|
||||
userViewProvider: &mockViewUser{
|
||||
PasswordlessTokens: user_view_model.WebAuthNTokens{&user_view_model.WebAuthNView{ID: "id", State: int32(user_model.MFAStateReady)}},
|
||||
},
|
||||
userEventProvider: &mockEventUser{},
|
||||
orgViewProvider: &mockViewOrg{State: org_model.OrgStateActive},
|
||||
userEventProvider: &mockEventUser{},
|
||||
orgViewProvider: &mockViewOrg{State: org_model.OrgStateActive},
|
||||
lockoutPolicyProvider: &mockLockoutPolicy{
|
||||
policy: &iam_view_model.LockoutPolicyView{
|
||||
ShowLockOutFailures: true,
|
||||
},
|
||||
},
|
||||
MultiFactorCheckLifeTime: 10 * time.Hour,
|
||||
},
|
||||
args{&domain.AuthRequest{UserID: "UserID", LoginPolicy: &domain.LoginPolicy{PasswordlessType: domain.PasswordlessTypeAllowed}}, false},
|
||||
@@ -528,8 +582,13 @@ func TestAuthRequestRepo_nextSteps(t *testing.T) {
|
||||
PasswordSet: true,
|
||||
PasswordlessTokens: user_view_model.WebAuthNTokens{&user_view_model.WebAuthNView{ID: "id", State: int32(user_model.MFAStateReady)}},
|
||||
},
|
||||
userEventProvider: &mockEventUser{},
|
||||
orgViewProvider: &mockViewOrg{State: org_model.OrgStateActive},
|
||||
userEventProvider: &mockEventUser{},
|
||||
orgViewProvider: &mockViewOrg{State: org_model.OrgStateActive},
|
||||
lockoutPolicyProvider: &mockLockoutPolicy{
|
||||
policy: &iam_view_model.LockoutPolicyView{
|
||||
ShowLockOutFailures: true,
|
||||
},
|
||||
},
|
||||
MultiFactorCheckLifeTime: 10 * time.Hour,
|
||||
},
|
||||
args{&domain.AuthRequest{UserID: "UserID", LoginPolicy: &domain.LoginPolicy{PasswordlessType: domain.PasswordlessTypeAllowed}}, false},
|
||||
@@ -550,7 +609,12 @@ func TestAuthRequestRepo_nextSteps(t *testing.T) {
|
||||
IsEmailVerified: false,
|
||||
MFAMaxSetUp: int32(model.MFALevelMultiFactor),
|
||||
},
|
||||
userEventProvider: &mockEventUser{},
|
||||
userEventProvider: &mockEventUser{},
|
||||
lockoutPolicyProvider: &mockLockoutPolicy{
|
||||
policy: &iam_view_model.LockoutPolicyView{
|
||||
ShowLockOutFailures: true,
|
||||
},
|
||||
},
|
||||
orgViewProvider: &mockViewOrg{State: org_model.OrgStateActive},
|
||||
MultiFactorCheckLifeTime: 10 * time.Hour,
|
||||
},
|
||||
@@ -572,7 +636,12 @@ func TestAuthRequestRepo_nextSteps(t *testing.T) {
|
||||
PasswordInitRequired: true,
|
||||
},
|
||||
userEventProvider: &mockEventUser{},
|
||||
orgViewProvider: &mockViewOrg{State: org_model.OrgStateActive},
|
||||
lockoutPolicyProvider: &mockLockoutPolicy{
|
||||
policy: &iam_view_model.LockoutPolicyView{
|
||||
ShowLockOutFailures: true,
|
||||
},
|
||||
},
|
||||
orgViewProvider: &mockViewOrg{State: org_model.OrgStateActive},
|
||||
},
|
||||
args{&domain.AuthRequest{UserID: "UserID", LoginPolicy: &domain.LoginPolicy{}}, false},
|
||||
[]domain.NextStep{&domain.InitPasswordStep{}},
|
||||
@@ -588,7 +657,12 @@ func TestAuthRequestRepo_nextSteps(t *testing.T) {
|
||||
IsEmailVerified: true,
|
||||
MFAMaxSetUp: int32(model.MFALevelSecondFactor),
|
||||
},
|
||||
userEventProvider: &mockEventUser{},
|
||||
userEventProvider: &mockEventUser{},
|
||||
lockoutPolicyProvider: &mockLockoutPolicy{
|
||||
policy: &iam_view_model.LockoutPolicyView{
|
||||
ShowLockOutFailures: true,
|
||||
},
|
||||
},
|
||||
orgViewProvider: &mockViewOrg{State: org_model.OrgStateActive},
|
||||
SecondFactorCheckLifeTime: 18 * time.Hour,
|
||||
},
|
||||
@@ -613,6 +687,11 @@ func TestAuthRequestRepo_nextSteps(t *testing.T) {
|
||||
loginPolicyProvider: &mockLoginPolicy{
|
||||
policy: &iam_view_model.LoginPolicyView{},
|
||||
},
|
||||
lockoutPolicyProvider: &mockLockoutPolicy{
|
||||
policy: &iam_view_model.LockoutPolicyView{
|
||||
ShowLockOutFailures: true,
|
||||
},
|
||||
},
|
||||
ExternalLoginCheckLifeTime: 10 * 24 * time.Hour,
|
||||
SecondFactorCheckLifeTime: 18 * time.Hour,
|
||||
},
|
||||
@@ -634,8 +713,13 @@ func TestAuthRequestRepo_nextSteps(t *testing.T) {
|
||||
userViewProvider: &mockViewUser{
|
||||
PasswordSet: true,
|
||||
},
|
||||
userEventProvider: &mockEventUser{},
|
||||
orgViewProvider: &mockViewOrg{State: org_model.OrgStateActive},
|
||||
userEventProvider: &mockEventUser{},
|
||||
orgViewProvider: &mockViewOrg{State: org_model.OrgStateActive},
|
||||
lockoutPolicyProvider: &mockLockoutPolicy{
|
||||
policy: &iam_view_model.LockoutPolicyView{
|
||||
ShowLockOutFailures: true,
|
||||
},
|
||||
},
|
||||
PasswordCheckLifeTime: 10 * 24 * time.Hour,
|
||||
},
|
||||
args{&domain.AuthRequest{UserID: "UserID", LoginPolicy: &domain.LoginPolicy{}}, false},
|
||||
@@ -654,9 +738,14 @@ func TestAuthRequestRepo_nextSteps(t *testing.T) {
|
||||
IsEmailVerified: true,
|
||||
MFAMaxSetUp: int32(model.MFALevelSecondFactor),
|
||||
},
|
||||
userEventProvider: &mockEventUser{},
|
||||
orgViewProvider: &mockViewOrg{State: org_model.OrgStateActive},
|
||||
userGrantProvider: &mockUserGrants{},
|
||||
userEventProvider: &mockEventUser{},
|
||||
orgViewProvider: &mockViewOrg{State: org_model.OrgStateActive},
|
||||
userGrantProvider: &mockUserGrants{},
|
||||
lockoutPolicyProvider: &mockLockoutPolicy{
|
||||
policy: &iam_view_model.LockoutPolicyView{
|
||||
ShowLockOutFailures: true,
|
||||
},
|
||||
},
|
||||
SecondFactorCheckLifeTime: 18 * time.Hour,
|
||||
ExternalLoginCheckLifeTime: 10 * 24 * time.Hour,
|
||||
},
|
||||
@@ -682,8 +771,13 @@ func TestAuthRequestRepo_nextSteps(t *testing.T) {
|
||||
OTPState: int32(user_model.MFAStateReady),
|
||||
MFAMaxSetUp: int32(model.MFALevelMultiFactor),
|
||||
},
|
||||
userEventProvider: &mockEventUser{},
|
||||
orgViewProvider: &mockViewOrg{State: org_model.OrgStateActive},
|
||||
userEventProvider: &mockEventUser{},
|
||||
orgViewProvider: &mockViewOrg{State: org_model.OrgStateActive},
|
||||
lockoutPolicyProvider: &mockLockoutPolicy{
|
||||
policy: &iam_view_model.LockoutPolicyView{
|
||||
ShowLockOutFailures: true,
|
||||
},
|
||||
},
|
||||
PasswordCheckLifeTime: 10 * 24 * time.Hour,
|
||||
SecondFactorCheckLifeTime: 18 * time.Hour,
|
||||
},
|
||||
@@ -710,8 +804,13 @@ func TestAuthRequestRepo_nextSteps(t *testing.T) {
|
||||
OTPState: int32(user_model.MFAStateReady),
|
||||
MFAMaxSetUp: int32(model.MFALevelSecondFactor),
|
||||
},
|
||||
userEventProvider: &mockEventUser{},
|
||||
orgViewProvider: &mockViewOrg{State: org_model.OrgStateActive},
|
||||
userEventProvider: &mockEventUser{},
|
||||
orgViewProvider: &mockViewOrg{State: org_model.OrgStateActive},
|
||||
lockoutPolicyProvider: &mockLockoutPolicy{
|
||||
policy: &iam_view_model.LockoutPolicyView{
|
||||
ShowLockOutFailures: true,
|
||||
},
|
||||
},
|
||||
PasswordCheckLifeTime: 10 * 24 * time.Hour,
|
||||
SecondFactorCheckLifeTime: 18 * time.Hour,
|
||||
},
|
||||
@@ -739,8 +838,13 @@ func TestAuthRequestRepo_nextSteps(t *testing.T) {
|
||||
OTPState: int32(user_model.MFAStateReady),
|
||||
MFAMaxSetUp: int32(model.MFALevelSecondFactor),
|
||||
},
|
||||
userEventProvider: &mockEventUser{},
|
||||
orgViewProvider: &mockViewOrg{State: org_model.OrgStateActive},
|
||||
userEventProvider: &mockEventUser{},
|
||||
orgViewProvider: &mockViewOrg{State: org_model.OrgStateActive},
|
||||
lockoutPolicyProvider: &mockLockoutPolicy{
|
||||
policy: &iam_view_model.LockoutPolicyView{
|
||||
ShowLockOutFailures: true,
|
||||
},
|
||||
},
|
||||
PasswordCheckLifeTime: 10 * 24 * time.Hour,
|
||||
ExternalLoginCheckLifeTime: 10 * 24 * time.Hour,
|
||||
SecondFactorCheckLifeTime: 18 * time.Hour,
|
||||
@@ -771,8 +875,13 @@ func TestAuthRequestRepo_nextSteps(t *testing.T) {
|
||||
IsEmailVerified: true,
|
||||
MFAMaxSetUp: int32(model.MFALevelSecondFactor),
|
||||
},
|
||||
userEventProvider: &mockEventUser{},
|
||||
orgViewProvider: &mockViewOrg{State: org_model.OrgStateActive},
|
||||
userEventProvider: &mockEventUser{},
|
||||
orgViewProvider: &mockViewOrg{State: org_model.OrgStateActive},
|
||||
lockoutPolicyProvider: &mockLockoutPolicy{
|
||||
policy: &iam_view_model.LockoutPolicyView{
|
||||
ShowLockOutFailures: true,
|
||||
},
|
||||
},
|
||||
PasswordCheckLifeTime: 10 * 24 * time.Hour,
|
||||
SecondFactorCheckLifeTime: 18 * time.Hour,
|
||||
},
|
||||
@@ -797,8 +906,13 @@ func TestAuthRequestRepo_nextSteps(t *testing.T) {
|
||||
PasswordSet: true,
|
||||
MFAMaxSetUp: int32(model.MFALevelSecondFactor),
|
||||
},
|
||||
userEventProvider: &mockEventUser{},
|
||||
orgViewProvider: &mockViewOrg{State: org_model.OrgStateActive},
|
||||
userEventProvider: &mockEventUser{},
|
||||
orgViewProvider: &mockViewOrg{State: org_model.OrgStateActive},
|
||||
lockoutPolicyProvider: &mockLockoutPolicy{
|
||||
policy: &iam_view_model.LockoutPolicyView{
|
||||
ShowLockOutFailures: true,
|
||||
},
|
||||
},
|
||||
PasswordCheckLifeTime: 10 * 24 * time.Hour,
|
||||
SecondFactorCheckLifeTime: 18 * time.Hour,
|
||||
},
|
||||
@@ -823,8 +937,13 @@ func TestAuthRequestRepo_nextSteps(t *testing.T) {
|
||||
PasswordChangeRequired: true,
|
||||
MFAMaxSetUp: int32(model.MFALevelSecondFactor),
|
||||
},
|
||||
userEventProvider: &mockEventUser{},
|
||||
orgViewProvider: &mockViewOrg{State: org_model.OrgStateActive},
|
||||
userEventProvider: &mockEventUser{},
|
||||
orgViewProvider: &mockViewOrg{State: org_model.OrgStateActive},
|
||||
lockoutPolicyProvider: &mockLockoutPolicy{
|
||||
policy: &iam_view_model.LockoutPolicyView{
|
||||
ShowLockOutFailures: true,
|
||||
},
|
||||
},
|
||||
PasswordCheckLifeTime: 10 * 24 * time.Hour,
|
||||
SecondFactorCheckLifeTime: 18 * time.Hour,
|
||||
},
|
||||
@@ -849,9 +968,14 @@ func TestAuthRequestRepo_nextSteps(t *testing.T) {
|
||||
IsEmailVerified: true,
|
||||
MFAMaxSetUp: int32(model.MFALevelSecondFactor),
|
||||
},
|
||||
userEventProvider: &mockEventUser{},
|
||||
orgViewProvider: &mockViewOrg{State: org_model.OrgStateActive},
|
||||
userGrantProvider: &mockUserGrants{},
|
||||
userEventProvider: &mockEventUser{},
|
||||
orgViewProvider: &mockViewOrg{State: org_model.OrgStateActive},
|
||||
userGrantProvider: &mockUserGrants{},
|
||||
lockoutPolicyProvider: &mockLockoutPolicy{
|
||||
policy: &iam_view_model.LockoutPolicyView{
|
||||
ShowLockOutFailures: true,
|
||||
},
|
||||
},
|
||||
PasswordCheckLifeTime: 10 * 24 * time.Hour,
|
||||
SecondFactorCheckLifeTime: 18 * time.Hour,
|
||||
},
|
||||
@@ -877,9 +1001,14 @@ func TestAuthRequestRepo_nextSteps(t *testing.T) {
|
||||
IsEmailVerified: true,
|
||||
MFAMaxSetUp: int32(model.MFALevelSecondFactor),
|
||||
},
|
||||
userEventProvider: &mockEventUser{},
|
||||
orgViewProvider: &mockViewOrg{State: org_model.OrgStateActive},
|
||||
userGrantProvider: &mockUserGrants{},
|
||||
userEventProvider: &mockEventUser{},
|
||||
orgViewProvider: &mockViewOrg{State: org_model.OrgStateActive},
|
||||
userGrantProvider: &mockUserGrants{},
|
||||
lockoutPolicyProvider: &mockLockoutPolicy{
|
||||
policy: &iam_view_model.LockoutPolicyView{
|
||||
ShowLockOutFailures: true,
|
||||
},
|
||||
},
|
||||
PasswordCheckLifeTime: 10 * 24 * time.Hour,
|
||||
SecondFactorCheckLifeTime: 18 * time.Hour,
|
||||
},
|
||||
@@ -912,6 +1041,11 @@ func TestAuthRequestRepo_nextSteps(t *testing.T) {
|
||||
roleCheck: true,
|
||||
userGrants: 0,
|
||||
},
|
||||
lockoutPolicyProvider: &mockLockoutPolicy{
|
||||
policy: &iam_view_model.LockoutPolicyView{
|
||||
ShowLockOutFailures: true,
|
||||
},
|
||||
},
|
||||
PasswordCheckLifeTime: 10 * 24 * time.Hour,
|
||||
SecondFactorCheckLifeTime: 18 * time.Hour,
|
||||
},
|
||||
@@ -944,6 +1078,11 @@ func TestAuthRequestRepo_nextSteps(t *testing.T) {
|
||||
roleCheck: true,
|
||||
userGrants: 2,
|
||||
},
|
||||
lockoutPolicyProvider: &mockLockoutPolicy{
|
||||
policy: &iam_view_model.LockoutPolicyView{
|
||||
ShowLockOutFailures: true,
|
||||
},
|
||||
},
|
||||
PasswordCheckLifeTime: 10 * 24 * time.Hour,
|
||||
SecondFactorCheckLifeTime: 18 * time.Hour,
|
||||
},
|
||||
@@ -969,6 +1108,11 @@ func TestAuthRequestRepo_nextSteps(t *testing.T) {
|
||||
IsEmailVerified: true,
|
||||
MFAMaxSetUp: int32(model.MFALevelSecondFactor),
|
||||
},
|
||||
lockoutPolicyProvider: &mockLockoutPolicy{
|
||||
policy: &iam_view_model.LockoutPolicyView{
|
||||
ShowLockOutFailures: true,
|
||||
},
|
||||
},
|
||||
userEventProvider: &mockEventUser{},
|
||||
orgViewProvider: &mockViewOrg{State: org_model.OrgStateActive},
|
||||
SecondFactorCheckLifeTime: 18 * time.Hour,
|
||||
@@ -995,8 +1139,13 @@ func TestAuthRequestRepo_nextSteps(t *testing.T) {
|
||||
IsEmailVerified: true,
|
||||
MFAMaxSetUp: int32(model.MFALevelSecondFactor),
|
||||
},
|
||||
userEventProvider: &mockEventUser{},
|
||||
orgViewProvider: &mockViewOrg{State: org_model.OrgStateActive},
|
||||
userEventProvider: &mockEventUser{},
|
||||
orgViewProvider: &mockViewOrg{State: org_model.OrgStateActive},
|
||||
lockoutPolicyProvider: &mockLockoutPolicy{
|
||||
policy: &iam_view_model.LockoutPolicyView{
|
||||
ShowLockOutFailures: true,
|
||||
},
|
||||
},
|
||||
SecondFactorCheckLifeTime: 18 * time.Hour,
|
||||
PasswordCheckLifeTime: 10 * 24 * time.Hour,
|
||||
},
|
||||
@@ -1024,6 +1173,7 @@ func TestAuthRequestRepo_nextSteps(t *testing.T) {
|
||||
OrgViewProvider: tt.fields.orgViewProvider,
|
||||
UserGrantProvider: tt.fields.userGrantProvider,
|
||||
LoginPolicyViewProvider: tt.fields.loginPolicyProvider,
|
||||
LockoutPolicyViewProvider: tt.fields.lockoutPolicyProvider,
|
||||
PasswordCheckLifeTime: tt.fields.PasswordCheckLifeTime,
|
||||
ExternalLoginCheckLifeTime: tt.fields.ExternalLoginCheckLifeTime,
|
||||
MFAInitSkippedLifeTime: tt.fields.MFAInitSkippedLifeTime,
|
||||
|
@@ -73,6 +73,7 @@ func Register(configs Configs, bulkLimit, errorCount uint64, view *view.View, es
|
||||
newPrivacyPolicy(handler{view, bulkLimit, configs.cycleDuration("PrivacyPolicy"), errorCount, es}),
|
||||
newCustomText(handler{view, bulkLimit, configs.cycleDuration("CustomTexts"), errorCount, es}),
|
||||
newMetadata(handler{view, bulkLimit, configs.cycleDuration("Metadata"), errorCount, es}),
|
||||
newLockoutPolicy(handler{view, bulkLimit, configs.cycleDuration("LockoutPolicy"), errorCount, es}),
|
||||
}
|
||||
}
|
||||
|
||||
|
110
internal/auth/repository/eventsourcing/handler/lockout_policy.go
Normal file
110
internal/auth/repository/eventsourcing/handler/lockout_policy.go
Normal file
@@ -0,0 +1,110 @@
|
||||
package handler
|
||||
|
||||
import (
|
||||
"github.com/caos/logging"
|
||||
"github.com/caos/zitadel/internal/eventstore/v1"
|
||||
|
||||
es_models "github.com/caos/zitadel/internal/eventstore/v1/models"
|
||||
"github.com/caos/zitadel/internal/eventstore/v1/query"
|
||||
"github.com/caos/zitadel/internal/eventstore/v1/spooler"
|
||||
iam_es_model "github.com/caos/zitadel/internal/iam/repository/eventsourcing/model"
|
||||
iam_model "github.com/caos/zitadel/internal/iam/repository/view/model"
|
||||
org_es_model "github.com/caos/zitadel/internal/org/repository/eventsourcing/model"
|
||||
)
|
||||
|
||||
const (
|
||||
lockoutPolicyTable = "auth.lockout_policies"
|
||||
)
|
||||
|
||||
type LockoutPolicy struct {
|
||||
handler
|
||||
subscription *v1.Subscription
|
||||
}
|
||||
|
||||
func newLockoutPolicy(handler handler) *LockoutPolicy {
|
||||
h := &LockoutPolicy{
|
||||
handler: handler,
|
||||
}
|
||||
|
||||
h.subscribe()
|
||||
|
||||
return h
|
||||
}
|
||||
|
||||
func (p *LockoutPolicy) subscribe() {
|
||||
p.subscription = p.es.Subscribe(p.AggregateTypes()...)
|
||||
go func() {
|
||||
for event := range p.subscription.Events {
|
||||
query.ReduceEvent(p, event)
|
||||
}
|
||||
}()
|
||||
}
|
||||
|
||||
func (p *LockoutPolicy) ViewModel() string {
|
||||
return lockoutPolicyTable
|
||||
}
|
||||
|
||||
func (p *LockoutPolicy) Subscription() *v1.Subscription {
|
||||
return p.subscription
|
||||
}
|
||||
|
||||
func (_ *LockoutPolicy) AggregateTypes() []es_models.AggregateType {
|
||||
return []es_models.AggregateType{org_es_model.OrgAggregate, iam_es_model.IAMAggregate}
|
||||
}
|
||||
|
||||
func (p *LockoutPolicy) CurrentSequence() (uint64, error) {
|
||||
sequence, err := p.view.GetLatestLockoutPolicySequence()
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
return sequence.CurrentSequence, nil
|
||||
}
|
||||
|
||||
func (p *LockoutPolicy) EventQuery() (*es_models.SearchQuery, error) {
|
||||
sequence, err := p.view.GetLatestLockoutPolicySequence()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return es_models.NewSearchQuery().
|
||||
AggregateTypeFilter(p.AggregateTypes()...).
|
||||
LatestSequenceFilter(sequence.CurrentSequence), nil
|
||||
}
|
||||
|
||||
func (p *LockoutPolicy) Reduce(event *es_models.Event) (err error) {
|
||||
switch event.AggregateType {
|
||||
case org_es_model.OrgAggregate, iam_es_model.IAMAggregate:
|
||||
err = p.processLockoutPolicy(event)
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
func (p *LockoutPolicy) processLockoutPolicy(event *es_models.Event) (err error) {
|
||||
policy := new(iam_model.LockoutPolicyView)
|
||||
switch event.Type {
|
||||
case iam_es_model.LockoutPolicyAdded, org_es_model.LockoutPolicyAdded:
|
||||
err = policy.AppendEvent(event)
|
||||
case iam_es_model.LockoutPolicyChanged, org_es_model.LockoutPolicyChanged:
|
||||
policy, err = p.view.LockoutPolicyByAggregateID(event.AggregateID)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
err = policy.AppendEvent(event)
|
||||
case org_es_model.LockoutPolicyRemoved:
|
||||
return p.view.DeleteLockoutPolicy(event.AggregateID, event)
|
||||
default:
|
||||
return p.view.ProcessedLockoutPolicySequence(event)
|
||||
}
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return p.view.PutLockoutPolicy(policy, event)
|
||||
}
|
||||
|
||||
func (p *LockoutPolicy) OnError(event *es_models.Event, err error) error {
|
||||
logging.LogWithFields("SPOOL-0pos2", "id", event.AggregateID).WithError(err).Warn("something went wrong in passwordLockout policy handler")
|
||||
return spooler.HandleError(event, err, p.view.GetLatestLockoutPolicyFailedEvent, p.view.ProcessedLockoutPolicyFailedEvent, p.view.ProcessedLockoutPolicySequence, p.errorCountUntilSkip)
|
||||
}
|
||||
|
||||
func (p *LockoutPolicy) OnSuccess() error {
|
||||
return spooler.HandleSuccess(p.view.UpdateLockoutPolicySpoolerRunTimestamp)
|
||||
}
|
@@ -109,6 +109,7 @@ func Start(conf Config, authZ authz.Config, systemDefaults sd.SystemDefaults, co
|
||||
OrgViewProvider: view,
|
||||
IDPProviderViewProvider: view,
|
||||
LoginPolicyViewProvider: view,
|
||||
LockoutPolicyViewProvider: view,
|
||||
UserGrantProvider: view,
|
||||
IdGenerator: idGenerator,
|
||||
PasswordCheckLifeTime: systemDefaults.VerificationLifetimes.PasswordCheck.Duration,
|
||||
|
@@ -0,0 +1,53 @@
|
||||
package view
|
||||
|
||||
import (
|
||||
"github.com/caos/zitadel/internal/errors"
|
||||
"github.com/caos/zitadel/internal/eventstore/v1/models"
|
||||
"github.com/caos/zitadel/internal/iam/repository/view"
|
||||
"github.com/caos/zitadel/internal/iam/repository/view/model"
|
||||
global_view "github.com/caos/zitadel/internal/view/repository"
|
||||
)
|
||||
|
||||
const (
|
||||
passwordLockoutPolicyTable = "auth.lockout_policies"
|
||||
)
|
||||
|
||||
func (v *View) LockoutPolicyByAggregateID(aggregateID string) (*model.LockoutPolicyView, error) {
|
||||
return view.GetLockoutPolicyByAggregateID(v.Db, passwordLockoutPolicyTable, aggregateID)
|
||||
}
|
||||
|
||||
func (v *View) PutLockoutPolicy(policy *model.LockoutPolicyView, event *models.Event) error {
|
||||
err := view.PutLockoutPolicy(v.Db, passwordLockoutPolicyTable, policy)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return v.ProcessedLockoutPolicySequence(event)
|
||||
}
|
||||
|
||||
func (v *View) DeleteLockoutPolicy(aggregateID string, event *models.Event) error {
|
||||
err := view.DeleteLockoutPolicy(v.Db, passwordLockoutPolicyTable, aggregateID)
|
||||
if err != nil && !errors.IsNotFound(err) {
|
||||
return err
|
||||
}
|
||||
return v.ProcessedLockoutPolicySequence(event)
|
||||
}
|
||||
|
||||
func (v *View) GetLatestLockoutPolicySequence() (*global_view.CurrentSequence, error) {
|
||||
return v.latestSequence(passwordLockoutPolicyTable)
|
||||
}
|
||||
|
||||
func (v *View) ProcessedLockoutPolicySequence(event *models.Event) error {
|
||||
return v.saveCurrentSequence(passwordLockoutPolicyTable, event)
|
||||
}
|
||||
|
||||
func (v *View) UpdateLockoutPolicySpoolerRunTimestamp() error {
|
||||
return v.updateSpoolerRunSequence(passwordLockoutPolicyTable)
|
||||
}
|
||||
|
||||
func (v *View) GetLatestLockoutPolicyFailedEvent(sequence uint64) (*global_view.FailedEvent, error) {
|
||||
return v.latestFailedEvent(passwordLockoutPolicyTable, sequence)
|
||||
}
|
||||
|
||||
func (v *View) ProcessedLockoutPolicyFailedEvent(failedEvent *global_view.FailedEvent) error {
|
||||
return v.saveFailedEvent(failedEvent)
|
||||
}
|
@@ -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,
|
||||
}
|
||||
}
|
||||
|
@@ -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
|
||||
|
@@ -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
|
||||
}
|
||||
|
@@ -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),
|
||||
},
|
||||
|
@@ -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
|
||||
}
|
||||
|
@@ -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
|
||||
}
|
||||
|
@@ -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),
|
||||
},
|
||||
|
@@ -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
|
||||
}
|
||||
}
|
||||
|
35
internal/command/setup_step18.go
Normal file
35
internal/command/setup_step18.go
Normal 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)
|
||||
}
|
@@ -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)
|
||||
}
|
||||
|
@@ -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")
|
||||
}
|
||||
|
@@ -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 != "" {
|
||||
|
@@ -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)
|
||||
}
|
||||
|
@@ -48,6 +48,7 @@ type AuthRequest struct {
|
||||
AllowedExternalIDPs []*IDPProvider
|
||||
LabelPolicy *LabelPolicy
|
||||
PrivacyPolicy *PrivacyPolicy
|
||||
LockoutPolicy *LockoutPolicy
|
||||
DefaultTranslations []*CustomText
|
||||
OrgTranslations []*CustomText
|
||||
}
|
||||
|
@@ -22,5 +22,5 @@ type IAM struct {
|
||||
DefaultOrgIAMPolicy *OrgIAMPolicy
|
||||
DefaultPasswordComplexityPolicy *PasswordComplexityPolicy
|
||||
DefaultPasswordAgePolicy *PasswordAgePolicy
|
||||
DefaultPasswordLockoutPolicy *PasswordLockoutPolicy
|
||||
DefaultPasswordLockoutPolicy *LockoutPolicy
|
||||
}
|
||||
|
@@ -18,7 +18,7 @@ type Org struct {
|
||||
LabelPolicy *LabelPolicy
|
||||
PasswordComplexityPolicy *PasswordComplexityPolicy
|
||||
PasswordAgePolicy *PasswordAgePolicy
|
||||
PasswordLockoutPolicy *PasswordLockoutPolicy
|
||||
PasswordLockoutPolicy *LockoutPolicy
|
||||
IDPs []*IDPConfig
|
||||
}
|
||||
|
||||
|
@@ -4,9 +4,10 @@ import (
|
||||
"github.com/caos/zitadel/internal/eventstore/v1/models"
|
||||
)
|
||||
|
||||
type PasswordLockoutPolicy struct {
|
||||
type LockoutPolicy struct {
|
||||
models.ObjectRoot
|
||||
|
||||
MaxAttempts uint64
|
||||
Default bool
|
||||
MaxPasswordAttempts uint64
|
||||
ShowLockOutFailures bool
|
||||
}
|
||||
|
@@ -20,6 +20,7 @@ const (
|
||||
Step15
|
||||
Step16
|
||||
Step17
|
||||
Step18
|
||||
//StepCount marks the the length of possible steps (StepCount-1 == last possible step)
|
||||
StepCount
|
||||
)
|
||||
|
@@ -35,7 +35,7 @@ type IAM struct {
|
||||
DefaultOrgIAMPolicy *OrgIAMPolicy
|
||||
DefaultPasswordComplexityPolicy *PasswordComplexityPolicy
|
||||
DefaultPasswordAgePolicy *PasswordAgePolicy
|
||||
DefaultPasswordLockoutPolicy *PasswordLockoutPolicy
|
||||
DefaultLockoutPolicy *LockoutPolicy
|
||||
DefaultMailTemplate *MailTemplate
|
||||
DefaultMailTexts []*MailText
|
||||
}
|
||||
|
@@ -4,10 +4,10 @@ import (
|
||||
"github.com/caos/zitadel/internal/eventstore/v1/models"
|
||||
)
|
||||
|
||||
type PasswordLockoutPolicy struct {
|
||||
type LockoutPolicy struct {
|
||||
models.ObjectRoot
|
||||
|
||||
State PolicyState
|
||||
MaxAttempts uint64
|
||||
MaxPasswordAttempts uint64
|
||||
ShowLockOutFailures bool
|
||||
}
|
||||
|
@@ -5,9 +5,9 @@ import (
|
||||
"time"
|
||||
)
|
||||
|
||||
type PasswordLockoutPolicyView struct {
|
||||
type LockoutPolicyView struct {
|
||||
AggregateID string
|
||||
MaxAttempts uint64
|
||||
MaxPasswordAttempts uint64
|
||||
ShowLockOutFailures bool
|
||||
Default bool
|
||||
|
||||
@@ -16,32 +16,32 @@ type PasswordLockoutPolicyView struct {
|
||||
Sequence uint64
|
||||
}
|
||||
|
||||
type PasswordLockoutPolicySearchRequest struct {
|
||||
type LockoutPolicySearchRequest struct {
|
||||
Offset uint64
|
||||
Limit uint64
|
||||
SortingColumn PasswordLockoutPolicySearchKey
|
||||
SortingColumn LockoutPolicySearchKey
|
||||
Asc bool
|
||||
Queries []*PasswordLockoutPolicySearchQuery
|
||||
Queries []*LockoutPolicySearchQuery
|
||||
}
|
||||
|
||||
type PasswordLockoutPolicySearchKey int32
|
||||
type LockoutPolicySearchKey int32
|
||||
|
||||
const (
|
||||
PasswordLockoutPolicySearchKeyUnspecified PasswordLockoutPolicySearchKey = iota
|
||||
PasswordLockoutPolicySearchKeyAggregateID
|
||||
LockoutPolicySearchKeyUnspecified LockoutPolicySearchKey = iota
|
||||
LockoutPolicySearchKeyAggregateID
|
||||
)
|
||||
|
||||
type PasswordLockoutPolicySearchQuery struct {
|
||||
Key PasswordLockoutPolicySearchKey
|
||||
type LockoutPolicySearchQuery struct {
|
||||
Key LockoutPolicySearchKey
|
||||
Method domain.SearchMethod
|
||||
Value interface{}
|
||||
}
|
||||
|
||||
type PasswordLockoutPolicySearchResponse struct {
|
||||
type LockoutPolicySearchResponse struct {
|
||||
Offset uint64
|
||||
Limit uint64
|
||||
TotalResult uint64
|
||||
Result []*PasswordLockoutPolicyView
|
||||
Result []*LockoutPolicyView
|
||||
Sequence uint64
|
||||
Timestamp time.Time
|
||||
}
|
||||
|
@@ -36,7 +36,7 @@ type IAM struct {
|
||||
DefaultOrgIAMPolicy *OrgIAMPolicy `json:"-"`
|
||||
DefaultPasswordComplexityPolicy *PasswordComplexityPolicy `json:"-"`
|
||||
DefaultPasswordAgePolicy *PasswordAgePolicy `json:"-"`
|
||||
DefaultPasswordLockoutPolicy *PasswordLockoutPolicy `json:"-"`
|
||||
DefaultLockoutPolicy *LockoutPolicy `json:"-"`
|
||||
}
|
||||
|
||||
func IAMToModel(iam *IAM) *model.IAM {
|
||||
@@ -66,8 +66,8 @@ func IAMToModel(iam *IAM) *model.IAM {
|
||||
if iam.DefaultPasswordAgePolicy != nil {
|
||||
converted.DefaultPasswordAgePolicy = PasswordAgePolicyToModel(iam.DefaultPasswordAgePolicy)
|
||||
}
|
||||
if iam.DefaultPasswordLockoutPolicy != nil {
|
||||
converted.DefaultPasswordLockoutPolicy = PasswordLockoutPolicyToModel(iam.DefaultPasswordLockoutPolicy)
|
||||
if iam.DefaultLockoutPolicy != nil {
|
||||
converted.DefaultLockoutPolicy = LockoutPolicyToModel(iam.DefaultLockoutPolicy)
|
||||
}
|
||||
if iam.DefaultOrgIAMPolicy != nil {
|
||||
converted.DefaultOrgIAMPolicy = OrgIAMPolicyToModel(iam.DefaultOrgIAMPolicy)
|
||||
@@ -166,10 +166,10 @@ func (i *IAM) AppendEvent(event *es_models.Event) (err error) {
|
||||
return i.appendAddPasswordAgePolicyEvent(event)
|
||||
case PasswordAgePolicyChanged:
|
||||
return i.appendChangePasswordAgePolicyEvent(event)
|
||||
case PasswordLockoutPolicyAdded:
|
||||
return i.appendAddPasswordLockoutPolicyEvent(event)
|
||||
case PasswordLockoutPolicyChanged:
|
||||
return i.appendChangePasswordLockoutPolicyEvent(event)
|
||||
case LockoutPolicyAdded:
|
||||
return i.appendAddLockoutPolicyEvent(event)
|
||||
case LockoutPolicyChanged:
|
||||
return i.appendChangeLockoutPolicyEvent(event)
|
||||
case OrgIAMPolicyAdded:
|
||||
return i.appendAddOrgIAMPolicyEvent(event)
|
||||
case OrgIAMPolicyChanged:
|
||||
|
@@ -0,0 +1,60 @@
|
||||
package model
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
|
||||
"github.com/caos/zitadel/internal/errors"
|
||||
es_models "github.com/caos/zitadel/internal/eventstore/v1/models"
|
||||
iam_model "github.com/caos/zitadel/internal/iam/model"
|
||||
)
|
||||
|
||||
type LockoutPolicy struct {
|
||||
es_models.ObjectRoot
|
||||
|
||||
State int32 `json:"-"`
|
||||
MaxPasswordAttempts uint64 `json:"maxPasswordAttempts"`
|
||||
ShowLockOutFailures bool `json:"showLockOutFailures"`
|
||||
}
|
||||
|
||||
func LockoutPolicyToModel(policy *LockoutPolicy) *iam_model.LockoutPolicy {
|
||||
return &iam_model.LockoutPolicy{
|
||||
ObjectRoot: policy.ObjectRoot,
|
||||
State: iam_model.PolicyState(policy.State),
|
||||
MaxPasswordAttempts: policy.MaxPasswordAttempts,
|
||||
ShowLockOutFailures: policy.ShowLockOutFailures,
|
||||
}
|
||||
}
|
||||
|
||||
func (p *LockoutPolicy) Changes(changed *LockoutPolicy) map[string]interface{} {
|
||||
changes := make(map[string]interface{}, 2)
|
||||
|
||||
if p.MaxPasswordAttempts != changed.MaxPasswordAttempts {
|
||||
changes["maxAttempts"] = changed.MaxPasswordAttempts
|
||||
}
|
||||
if p.ShowLockOutFailures != changed.ShowLockOutFailures {
|
||||
changes["showLockOutFailures"] = changed.ShowLockOutFailures
|
||||
}
|
||||
return changes
|
||||
}
|
||||
|
||||
func (i *IAM) appendAddLockoutPolicyEvent(event *es_models.Event) error {
|
||||
i.DefaultLockoutPolicy = new(LockoutPolicy)
|
||||
err := i.DefaultLockoutPolicy.SetData(event)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
i.DefaultLockoutPolicy.ObjectRoot.CreationDate = event.CreationDate
|
||||
return nil
|
||||
}
|
||||
|
||||
func (i *IAM) appendChangeLockoutPolicyEvent(event *es_models.Event) error {
|
||||
return i.DefaultLockoutPolicy.SetData(event)
|
||||
}
|
||||
|
||||
func (p *LockoutPolicy) SetData(event *es_models.Event) error {
|
||||
err := json.Unmarshal(event.Data, p)
|
||||
if err != nil {
|
||||
return errors.ThrowInternal(err, "EVENT-7JS9d", "unable to unmarshal data")
|
||||
}
|
||||
return nil
|
||||
}
|
@@ -8,8 +8,8 @@ import (
|
||||
|
||||
func TestPasswordLockoutPolicyChanges(t *testing.T) {
|
||||
type args struct {
|
||||
existing *PasswordLockoutPolicy
|
||||
new *PasswordLockoutPolicy
|
||||
existing *LockoutPolicy
|
||||
new *LockoutPolicy
|
||||
}
|
||||
type res struct {
|
||||
changesLen int
|
||||
@@ -22,8 +22,8 @@ func TestPasswordLockoutPolicyChanges(t *testing.T) {
|
||||
{
|
||||
name: "lockout policy all attributes change",
|
||||
args: args{
|
||||
existing: &PasswordLockoutPolicy{MaxAttempts: 365, ShowLockOutFailures: true},
|
||||
new: &PasswordLockoutPolicy{MaxAttempts: 730, ShowLockOutFailures: false},
|
||||
existing: &LockoutPolicy{MaxPasswordAttempts: 365, ShowLockOutFailures: true},
|
||||
new: &LockoutPolicy{MaxPasswordAttempts: 730, ShowLockOutFailures: false},
|
||||
},
|
||||
res: res{
|
||||
changesLen: 2,
|
||||
@@ -32,8 +32,8 @@ func TestPasswordLockoutPolicyChanges(t *testing.T) {
|
||||
{
|
||||
name: "no changes",
|
||||
args: args{
|
||||
existing: &PasswordLockoutPolicy{MaxAttempts: 10, ShowLockOutFailures: true},
|
||||
new: &PasswordLockoutPolicy{MaxAttempts: 10, ShowLockOutFailures: true},
|
||||
existing: &LockoutPolicy{MaxPasswordAttempts: 10, ShowLockOutFailures: true},
|
||||
new: &LockoutPolicy{MaxPasswordAttempts: 10, ShowLockOutFailures: true},
|
||||
},
|
||||
res: res{
|
||||
changesLen: 0,
|
||||
@@ -53,7 +53,7 @@ func TestPasswordLockoutPolicyChanges(t *testing.T) {
|
||||
func TestAppendAddPasswordLockoutPolicyEvent(t *testing.T) {
|
||||
type args struct {
|
||||
iam *IAM
|
||||
policy *PasswordLockoutPolicy
|
||||
policy *LockoutPolicy
|
||||
event *es_models.Event
|
||||
}
|
||||
tests := []struct {
|
||||
@@ -65,10 +65,10 @@ func TestAppendAddPasswordLockoutPolicyEvent(t *testing.T) {
|
||||
name: "append add password lockout policy event",
|
||||
args: args{
|
||||
iam: new(IAM),
|
||||
policy: &PasswordLockoutPolicy{MaxAttempts: 10, ShowLockOutFailures: true},
|
||||
policy: &LockoutPolicy{MaxPasswordAttempts: 10, ShowLockOutFailures: true},
|
||||
event: new(es_models.Event),
|
||||
},
|
||||
result: &IAM{DefaultPasswordLockoutPolicy: &PasswordLockoutPolicy{MaxAttempts: 10, ShowLockOutFailures: true}},
|
||||
result: &IAM{DefaultLockoutPolicy: &LockoutPolicy{MaxPasswordAttempts: 10, ShowLockOutFailures: true}},
|
||||
},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
@@ -77,12 +77,12 @@ func TestAppendAddPasswordLockoutPolicyEvent(t *testing.T) {
|
||||
data, _ := json.Marshal(tt.args.policy)
|
||||
tt.args.event.Data = data
|
||||
}
|
||||
tt.args.iam.appendAddPasswordLockoutPolicyEvent(tt.args.event)
|
||||
if tt.result.DefaultPasswordLockoutPolicy.MaxAttempts != tt.args.iam.DefaultPasswordLockoutPolicy.MaxAttempts {
|
||||
t.Errorf("got wrong result: expected: %v, actual: %v ", tt.result.DefaultPasswordLockoutPolicy.MaxAttempts, tt.args.iam.DefaultPasswordLockoutPolicy.MaxAttempts)
|
||||
tt.args.iam.appendAddLockoutPolicyEvent(tt.args.event)
|
||||
if tt.result.DefaultLockoutPolicy.MaxPasswordAttempts != tt.args.iam.DefaultLockoutPolicy.MaxPasswordAttempts {
|
||||
t.Errorf("got wrong result: expected: %v, actual: %v ", tt.result.DefaultLockoutPolicy.MaxPasswordAttempts, tt.args.iam.DefaultLockoutPolicy.MaxPasswordAttempts)
|
||||
}
|
||||
if tt.result.DefaultPasswordLockoutPolicy.ShowLockOutFailures != tt.args.iam.DefaultPasswordLockoutPolicy.ShowLockOutFailures {
|
||||
t.Errorf("got wrong result: expected: %v, actual: %v ", tt.result.DefaultPasswordLockoutPolicy.ShowLockOutFailures, tt.args.iam.DefaultPasswordLockoutPolicy.ShowLockOutFailures)
|
||||
if tt.result.DefaultLockoutPolicy.ShowLockOutFailures != tt.args.iam.DefaultLockoutPolicy.ShowLockOutFailures {
|
||||
t.Errorf("got wrong result: expected: %v, actual: %v ", tt.result.DefaultLockoutPolicy.ShowLockOutFailures, tt.args.iam.DefaultLockoutPolicy.ShowLockOutFailures)
|
||||
}
|
||||
})
|
||||
}
|
||||
@@ -91,7 +91,7 @@ func TestAppendAddPasswordLockoutPolicyEvent(t *testing.T) {
|
||||
func TestAppendChangePasswordLockoutPolicyEvent(t *testing.T) {
|
||||
type args struct {
|
||||
iam *IAM
|
||||
policy *PasswordLockoutPolicy
|
||||
policy *LockoutPolicy
|
||||
event *es_models.Event
|
||||
}
|
||||
tests := []struct {
|
||||
@@ -102,14 +102,14 @@ func TestAppendChangePasswordLockoutPolicyEvent(t *testing.T) {
|
||||
{
|
||||
name: "append change password lockout policy event",
|
||||
args: args{
|
||||
iam: &IAM{DefaultPasswordLockoutPolicy: &PasswordLockoutPolicy{
|
||||
MaxAttempts: 10,
|
||||
iam: &IAM{DefaultLockoutPolicy: &LockoutPolicy{
|
||||
MaxPasswordAttempts: 10,
|
||||
}},
|
||||
policy: &PasswordLockoutPolicy{MaxAttempts: 5},
|
||||
policy: &LockoutPolicy{MaxPasswordAttempts: 5},
|
||||
event: &es_models.Event{},
|
||||
},
|
||||
result: &IAM{DefaultPasswordLockoutPolicy: &PasswordLockoutPolicy{
|
||||
MaxAttempts: 5,
|
||||
result: &IAM{DefaultLockoutPolicy: &LockoutPolicy{
|
||||
MaxPasswordAttempts: 5,
|
||||
}},
|
||||
},
|
||||
}
|
||||
@@ -119,9 +119,9 @@ func TestAppendChangePasswordLockoutPolicyEvent(t *testing.T) {
|
||||
data, _ := json.Marshal(tt.args.policy)
|
||||
tt.args.event.Data = data
|
||||
}
|
||||
tt.args.iam.appendChangePasswordLockoutPolicyEvent(tt.args.event)
|
||||
if tt.result.DefaultPasswordLockoutPolicy.MaxAttempts != tt.args.iam.DefaultPasswordLockoutPolicy.MaxAttempts {
|
||||
t.Errorf("got wrong result: expected: %v, actual: %v ", tt.result.DefaultPasswordLockoutPolicy.MaxAttempts, tt.args.iam.DefaultPasswordLockoutPolicy.MaxAttempts)
|
||||
tt.args.iam.appendChangeLockoutPolicyEvent(tt.args.event)
|
||||
if tt.result.DefaultLockoutPolicy.MaxPasswordAttempts != tt.args.iam.DefaultLockoutPolicy.MaxPasswordAttempts {
|
||||
t.Errorf("got wrong result: expected: %v, actual: %v ", tt.result.DefaultLockoutPolicy.MaxPasswordAttempts, tt.args.iam.DefaultLockoutPolicy.MaxPasswordAttempts)
|
||||
}
|
||||
})
|
||||
}
|
@@ -1,69 +0,0 @@
|
||||
package model
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
|
||||
"github.com/caos/zitadel/internal/errors"
|
||||
es_models "github.com/caos/zitadel/internal/eventstore/v1/models"
|
||||
iam_model "github.com/caos/zitadel/internal/iam/model"
|
||||
)
|
||||
|
||||
type PasswordLockoutPolicy struct {
|
||||
es_models.ObjectRoot
|
||||
|
||||
State int32 `json:"-"`
|
||||
MaxAttempts uint64 `json:"maxAttempts"`
|
||||
ShowLockOutFailures bool `json:"showLockOutFailures"`
|
||||
}
|
||||
|
||||
func PasswordLockoutPolicyFromModel(policy *iam_model.PasswordLockoutPolicy) *PasswordLockoutPolicy {
|
||||
return &PasswordLockoutPolicy{
|
||||
ObjectRoot: policy.ObjectRoot,
|
||||
State: int32(policy.State),
|
||||
MaxAttempts: policy.MaxAttempts,
|
||||
ShowLockOutFailures: policy.ShowLockOutFailures,
|
||||
}
|
||||
}
|
||||
|
||||
func PasswordLockoutPolicyToModel(policy *PasswordLockoutPolicy) *iam_model.PasswordLockoutPolicy {
|
||||
return &iam_model.PasswordLockoutPolicy{
|
||||
ObjectRoot: policy.ObjectRoot,
|
||||
State: iam_model.PolicyState(policy.State),
|
||||
MaxAttempts: policy.MaxAttempts,
|
||||
ShowLockOutFailures: policy.ShowLockOutFailures,
|
||||
}
|
||||
}
|
||||
|
||||
func (p *PasswordLockoutPolicy) Changes(changed *PasswordLockoutPolicy) map[string]interface{} {
|
||||
changes := make(map[string]interface{}, 2)
|
||||
|
||||
if p.MaxAttempts != changed.MaxAttempts {
|
||||
changes["maxAttempts"] = changed.MaxAttempts
|
||||
}
|
||||
if p.ShowLockOutFailures != changed.ShowLockOutFailures {
|
||||
changes["showLockOutFailures"] = changed.ShowLockOutFailures
|
||||
}
|
||||
return changes
|
||||
}
|
||||
|
||||
func (i *IAM) appendAddPasswordLockoutPolicyEvent(event *es_models.Event) error {
|
||||
i.DefaultPasswordLockoutPolicy = new(PasswordLockoutPolicy)
|
||||
err := i.DefaultPasswordLockoutPolicy.SetData(event)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
i.DefaultPasswordLockoutPolicy.ObjectRoot.CreationDate = event.CreationDate
|
||||
return nil
|
||||
}
|
||||
|
||||
func (i *IAM) appendChangePasswordLockoutPolicyEvent(event *es_models.Event) error {
|
||||
return i.DefaultPasswordLockoutPolicy.SetData(event)
|
||||
}
|
||||
|
||||
func (p *PasswordLockoutPolicy) SetData(event *es_models.Event) error {
|
||||
err := json.Unmarshal(event.Data, p)
|
||||
if err != nil {
|
||||
return errors.ThrowInternal(err, "EVENT-7JS9d", "unable to unmarshal data")
|
||||
}
|
||||
return nil
|
||||
}
|
@@ -65,8 +65,8 @@ const (
|
||||
PasswordAgePolicyAdded models.EventType = "iam.policy.password.age.added"
|
||||
PasswordAgePolicyChanged models.EventType = "iam.policy.password.age.changed"
|
||||
|
||||
PasswordLockoutPolicyAdded models.EventType = "iam.policy.password.lockout.added"
|
||||
PasswordLockoutPolicyChanged models.EventType = "iam.policy.password.lockout.changed"
|
||||
LockoutPolicyAdded models.EventType = "iam.policy.lockout.added"
|
||||
LockoutPolicyChanged models.EventType = "iam.policy.lockout.changed"
|
||||
|
||||
PrivacyPolicyAdded models.EventType = "iam.policy.privacy.added"
|
||||
PrivacyPolicyChanged models.EventType = "iam.policy.privacy.changed"
|
||||
|
@@ -2,6 +2,7 @@ package model
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"github.com/caos/zitadel/internal/domain"
|
||||
org_es_model "github.com/caos/zitadel/internal/org/repository/eventsourcing/model"
|
||||
"time"
|
||||
|
||||
@@ -14,65 +15,67 @@ import (
|
||||
)
|
||||
|
||||
const (
|
||||
PasswordLockoutKeyAggregateID = "aggregate_id"
|
||||
LockoutKeyAggregateID = "aggregate_id"
|
||||
)
|
||||
|
||||
type PasswordLockoutPolicyView struct {
|
||||
type LockoutPolicyView struct {
|
||||
AggregateID string `json:"-" gorm:"column:aggregate_id;primary_key"`
|
||||
CreationDate time.Time `json:"-" gorm:"column:creation_date"`
|
||||
ChangeDate time.Time `json:"-" gorm:"column:change_date"`
|
||||
State int32 `json:"-" gorm:"column:lockout_policy_state"`
|
||||
|
||||
MaxAttempts uint64 `json:"maxAttempts" gorm:"column:max_attempts"`
|
||||
MaxPasswordAttempts uint64 `json:"maxPasswordAttempts" gorm:"column:max_password_attempts"`
|
||||
ShowLockOutFailures bool `json:"showLockOutFailures" gorm:"column:show_lockout_failures"`
|
||||
Default bool `json:"-" gorm:"-"`
|
||||
|
||||
Sequence uint64 `json:"-" gorm:"column:sequence"`
|
||||
}
|
||||
|
||||
func PasswordLockoutViewFromModel(policy *model.PasswordLockoutPolicyView) *PasswordLockoutPolicyView {
|
||||
return &PasswordLockoutPolicyView{
|
||||
func LockoutViewToModel(policy *LockoutPolicyView) *model.LockoutPolicyView {
|
||||
return &model.LockoutPolicyView{
|
||||
AggregateID: policy.AggregateID,
|
||||
Sequence: policy.Sequence,
|
||||
CreationDate: policy.CreationDate,
|
||||
ChangeDate: policy.ChangeDate,
|
||||
MaxAttempts: policy.MaxAttempts,
|
||||
MaxPasswordAttempts: policy.MaxPasswordAttempts,
|
||||
ShowLockOutFailures: policy.ShowLockOutFailures,
|
||||
Default: policy.Default,
|
||||
}
|
||||
}
|
||||
|
||||
func PasswordLockoutViewToModel(policy *PasswordLockoutPolicyView) *model.PasswordLockoutPolicyView {
|
||||
return &model.PasswordLockoutPolicyView{
|
||||
AggregateID: policy.AggregateID,
|
||||
Sequence: policy.Sequence,
|
||||
CreationDate: policy.CreationDate,
|
||||
ChangeDate: policy.ChangeDate,
|
||||
MaxAttempts: policy.MaxAttempts,
|
||||
ShowLockOutFailures: policy.ShowLockOutFailures,
|
||||
Default: policy.Default,
|
||||
func (p *LockoutPolicyView) ToDomain() *domain.LockoutPolicy {
|
||||
return &domain.LockoutPolicy{
|
||||
ObjectRoot: models.ObjectRoot{
|
||||
AggregateID: p.AggregateID,
|
||||
CreationDate: p.CreationDate,
|
||||
ChangeDate: p.ChangeDate,
|
||||
Sequence: p.Sequence,
|
||||
},
|
||||
MaxPasswordAttempts: p.MaxPasswordAttempts,
|
||||
ShowLockOutFailures: p.ShowLockOutFailures,
|
||||
Default: p.Default,
|
||||
}
|
||||
}
|
||||
|
||||
func (i *PasswordLockoutPolicyView) AppendEvent(event *models.Event) (err error) {
|
||||
func (i *LockoutPolicyView) AppendEvent(event *models.Event) (err error) {
|
||||
i.Sequence = event.Sequence
|
||||
i.ChangeDate = event.CreationDate
|
||||
switch event.Type {
|
||||
case es_model.PasswordLockoutPolicyAdded, org_es_model.PasswordLockoutPolicyAdded:
|
||||
case es_model.LockoutPolicyAdded, org_es_model.LockoutPolicyAdded:
|
||||
i.setRootData(event)
|
||||
i.CreationDate = event.CreationDate
|
||||
err = i.SetData(event)
|
||||
case es_model.PasswordLockoutPolicyChanged, org_es_model.PasswordLockoutPolicyChanged:
|
||||
case es_model.LockoutPolicyChanged, org_es_model.LockoutPolicyChanged:
|
||||
err = i.SetData(event)
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
func (r *PasswordLockoutPolicyView) setRootData(event *models.Event) {
|
||||
func (r *LockoutPolicyView) setRootData(event *models.Event) {
|
||||
r.AggregateID = event.AggregateID
|
||||
}
|
||||
|
||||
func (r *PasswordLockoutPolicyView) SetData(event *models.Event) error {
|
||||
func (r *LockoutPolicyView) SetData(event *models.Event) error {
|
||||
if err := json.Unmarshal(event.Data, r); err != nil {
|
||||
logging.Log("EVEN-gHls0").WithError(err).Error("could not unmarshal event data")
|
||||
return caos_errs.ThrowInternal(err, "MODEL-Hs8uf", "Could not unmarshal data")
|
||||
|
@@ -6,53 +6,53 @@ import (
|
||||
"github.com/caos/zitadel/internal/view/repository"
|
||||
)
|
||||
|
||||
type PasswordLockoutPolicySearchRequest iam_model.PasswordLockoutPolicySearchRequest
|
||||
type PasswordLockoutPolicySearchQuery iam_model.PasswordLockoutPolicySearchQuery
|
||||
type PasswordLockoutPolicySearchKey iam_model.PasswordLockoutPolicySearchKey
|
||||
type LockoutPolicySearchRequest iam_model.LockoutPolicySearchRequest
|
||||
type LockoutPolicySearchQuery iam_model.LockoutPolicySearchQuery
|
||||
type LockoutPolicySearchKey iam_model.LockoutPolicySearchKey
|
||||
|
||||
func (req PasswordLockoutPolicySearchRequest) GetLimit() uint64 {
|
||||
func (req LockoutPolicySearchRequest) GetLimit() uint64 {
|
||||
return req.Limit
|
||||
}
|
||||
|
||||
func (req PasswordLockoutPolicySearchRequest) GetOffset() uint64 {
|
||||
func (req LockoutPolicySearchRequest) GetOffset() uint64 {
|
||||
return req.Offset
|
||||
}
|
||||
|
||||
func (req PasswordLockoutPolicySearchRequest) GetSortingColumn() repository.ColumnKey {
|
||||
if req.SortingColumn == iam_model.PasswordLockoutPolicySearchKeyUnspecified {
|
||||
func (req LockoutPolicySearchRequest) GetSortingColumn() repository.ColumnKey {
|
||||
if req.SortingColumn == iam_model.LockoutPolicySearchKeyUnspecified {
|
||||
return nil
|
||||
}
|
||||
return PasswordLockoutPolicySearchKey(req.SortingColumn)
|
||||
return LockoutPolicySearchKey(req.SortingColumn)
|
||||
}
|
||||
|
||||
func (req PasswordLockoutPolicySearchRequest) GetAsc() bool {
|
||||
func (req LockoutPolicySearchRequest) GetAsc() bool {
|
||||
return req.Asc
|
||||
}
|
||||
|
||||
func (req PasswordLockoutPolicySearchRequest) GetQueries() []repository.SearchQuery {
|
||||
func (req LockoutPolicySearchRequest) GetQueries() []repository.SearchQuery {
|
||||
result := make([]repository.SearchQuery, len(req.Queries))
|
||||
for i, q := range req.Queries {
|
||||
result[i] = PasswordLockoutPolicySearchQuery{Key: q.Key, Value: q.Value, Method: q.Method}
|
||||
result[i] = LockoutPolicySearchQuery{Key: q.Key, Value: q.Value, Method: q.Method}
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
func (req PasswordLockoutPolicySearchQuery) GetKey() repository.ColumnKey {
|
||||
return PasswordLockoutPolicySearchKey(req.Key)
|
||||
func (req LockoutPolicySearchQuery) GetKey() repository.ColumnKey {
|
||||
return LockoutPolicySearchKey(req.Key)
|
||||
}
|
||||
|
||||
func (req PasswordLockoutPolicySearchQuery) GetMethod() domain.SearchMethod {
|
||||
func (req LockoutPolicySearchQuery) GetMethod() domain.SearchMethod {
|
||||
return req.Method
|
||||
}
|
||||
|
||||
func (req PasswordLockoutPolicySearchQuery) GetValue() interface{} {
|
||||
func (req LockoutPolicySearchQuery) GetValue() interface{} {
|
||||
return req.Value
|
||||
}
|
||||
|
||||
func (key PasswordLockoutPolicySearchKey) ToColumnName() string {
|
||||
switch iam_model.PasswordLockoutPolicySearchKey(key) {
|
||||
case iam_model.PasswordLockoutPolicySearchKeyAggregateID:
|
||||
return PasswordLockoutKeyAggregateID
|
||||
func (key LockoutPolicySearchKey) ToColumnName() string {
|
||||
switch iam_model.LockoutPolicySearchKey(key) {
|
||||
case iam_model.LockoutPolicySearchKeyAggregateID:
|
||||
return LockoutKeyAggregateID
|
||||
default:
|
||||
return ""
|
||||
}
|
||||
|
@@ -9,24 +9,24 @@ import (
|
||||
"github.com/jinzhu/gorm"
|
||||
)
|
||||
|
||||
func GetPasswordLockoutPolicyByAggregateID(db *gorm.DB, table, aggregateID string) (*model.PasswordLockoutPolicyView, error) {
|
||||
policy := new(model.PasswordLockoutPolicyView)
|
||||
aggregateIDQuery := &model.PasswordLockoutPolicySearchQuery{Key: iam_model.PasswordLockoutPolicySearchKeyAggregateID, Value: aggregateID, Method: domain.SearchMethodEquals}
|
||||
func GetLockoutPolicyByAggregateID(db *gorm.DB, table, aggregateID string) (*model.LockoutPolicyView, error) {
|
||||
policy := new(model.LockoutPolicyView)
|
||||
aggregateIDQuery := &model.LockoutPolicySearchQuery{Key: iam_model.LockoutPolicySearchKeyAggregateID, Value: aggregateID, Method: domain.SearchMethodEquals}
|
||||
query := repository.PrepareGetByQuery(table, aggregateIDQuery)
|
||||
err := query(db, policy)
|
||||
if caos_errs.IsNotFound(err) {
|
||||
return nil, caos_errs.ThrowNotFound(nil, "VIEW-M9fsf", "Errors.IAM.PasswordLockoutPolicy.NotExisting")
|
||||
return nil, caos_errs.ThrowNotFound(nil, "VIEW-M9fsf", "Errors.IAM.LockoutPolicy.NotExisting")
|
||||
}
|
||||
return policy, err
|
||||
}
|
||||
|
||||
func PutPasswordLockoutPolicy(db *gorm.DB, table string, policy *model.PasswordLockoutPolicyView) error {
|
||||
func PutLockoutPolicy(db *gorm.DB, table string, policy *model.LockoutPolicyView) error {
|
||||
save := repository.PrepareSave(table)
|
||||
return save(db, policy)
|
||||
}
|
||||
|
||||
func DeletePasswordLockoutPolicy(db *gorm.DB, table, aggregateID string) error {
|
||||
delete := repository.PrepareDeleteByKey(table, model.PasswordLockoutPolicySearchKey(iam_model.PasswordLockoutPolicySearchKeyAggregateID), aggregateID)
|
||||
func DeleteLockoutPolicy(db *gorm.DB, table, aggregateID string) error {
|
||||
delete := repository.PrepareDeleteByKey(table, model.LockoutPolicySearchKey(iam_model.LockoutPolicySearchKeyAggregateID), aggregateID)
|
||||
|
||||
return delete(db)
|
||||
}
|
||||
|
@@ -501,55 +501,55 @@ func (repo *OrgRepository) GetDefaultPasswordAgePolicy(ctx context.Context) (*ia
|
||||
return iam_es_model.PasswordAgeViewToModel(policy), nil
|
||||
}
|
||||
|
||||
func (repo *OrgRepository) GetPasswordLockoutPolicy(ctx context.Context) (*iam_model.PasswordLockoutPolicyView, error) {
|
||||
policy, viewErr := repo.View.PasswordLockoutPolicyByAggregateID(authz.GetCtxData(ctx).OrgID)
|
||||
func (repo *OrgRepository) GetLockoutPolicy(ctx context.Context) (*iam_model.LockoutPolicyView, error) {
|
||||
policy, viewErr := repo.View.LockoutPolicyByAggregateID(authz.GetCtxData(ctx).OrgID)
|
||||
if viewErr != nil && !errors.IsNotFound(viewErr) {
|
||||
return nil, viewErr
|
||||
}
|
||||
if errors.IsNotFound(viewErr) {
|
||||
policy = new(iam_es_model.PasswordLockoutPolicyView)
|
||||
policy = new(iam_es_model.LockoutPolicyView)
|
||||
}
|
||||
events, esErr := repo.getOrgEvents(ctx, repo.SystemDefaults.IamID, policy.Sequence)
|
||||
if errors.IsNotFound(viewErr) && len(events) == 0 {
|
||||
return repo.GetDefaultPasswordLockoutPolicy(ctx)
|
||||
return repo.GetDefaultLockoutPolicy(ctx)
|
||||
}
|
||||
if esErr != nil {
|
||||
logging.Log("EVENT-mS9od").WithError(esErr).Debug("error retrieving new events")
|
||||
return iam_es_model.PasswordLockoutViewToModel(policy), nil
|
||||
return iam_es_model.LockoutViewToModel(policy), nil
|
||||
}
|
||||
policyCopy := *policy
|
||||
for _, event := range events {
|
||||
if err := policyCopy.AppendEvent(event); err != nil {
|
||||
return iam_es_model.PasswordLockoutViewToModel(policy), nil
|
||||
return iam_es_model.LockoutViewToModel(policy), nil
|
||||
}
|
||||
}
|
||||
return iam_es_model.PasswordLockoutViewToModel(policy), nil
|
||||
return iam_es_model.LockoutViewToModel(policy), nil
|
||||
}
|
||||
|
||||
func (repo *OrgRepository) GetDefaultPasswordLockoutPolicy(ctx context.Context) (*iam_model.PasswordLockoutPolicyView, error) {
|
||||
policy, viewErr := repo.View.PasswordLockoutPolicyByAggregateID(repo.SystemDefaults.IamID)
|
||||
func (repo *OrgRepository) GetDefaultLockoutPolicy(ctx context.Context) (*iam_model.LockoutPolicyView, error) {
|
||||
policy, viewErr := repo.View.LockoutPolicyByAggregateID(repo.SystemDefaults.IamID)
|
||||
if viewErr != nil && !errors.IsNotFound(viewErr) {
|
||||
return nil, viewErr
|
||||
}
|
||||
if errors.IsNotFound(viewErr) {
|
||||
policy = new(iam_es_model.PasswordLockoutPolicyView)
|
||||
policy = new(iam_es_model.LockoutPolicyView)
|
||||
}
|
||||
events, esErr := repo.getIAMEvents(ctx, policy.Sequence)
|
||||
if errors.IsNotFound(viewErr) && len(events) == 0 {
|
||||
return nil, errors.ThrowNotFound(nil, "EVENT-cmO9s", "Errors.IAM.PasswordLockoutPolicy.NotFound")
|
||||
return nil, errors.ThrowNotFound(nil, "EVENT-cmO9s", "Errors.IAM.LockoutPolicy.NotFound")
|
||||
}
|
||||
if esErr != nil {
|
||||
logging.Log("EVENT-2Ms9f").WithError(esErr).Debug("error retrieving new events")
|
||||
return iam_es_model.PasswordLockoutViewToModel(policy), nil
|
||||
return iam_es_model.LockoutViewToModel(policy), nil
|
||||
}
|
||||
policyCopy := *policy
|
||||
for _, event := range events {
|
||||
if err := policyCopy.AppendEvent(event); err != nil {
|
||||
return iam_es_model.PasswordLockoutViewToModel(policy), nil
|
||||
return iam_es_model.LockoutViewToModel(policy), nil
|
||||
}
|
||||
}
|
||||
policy.Default = true
|
||||
return iam_es_model.PasswordLockoutViewToModel(policy), nil
|
||||
return iam_es_model.LockoutViewToModel(policy), nil
|
||||
}
|
||||
|
||||
func (repo *OrgRepository) GetPrivacyPolicy(ctx context.Context) (*iam_model.PrivacyPolicyView, error) {
|
||||
|
@@ -71,8 +71,8 @@ func Register(configs Configs, bulkLimit, errorCount uint64, view *view.View, es
|
||||
handler{view, bulkLimit, configs.cycleDuration("PasswordComplexityPolicy"), errorCount, es}),
|
||||
newPasswordAgePolicy(
|
||||
handler{view, bulkLimit, configs.cycleDuration("PasswordAgePolicy"), errorCount, es}),
|
||||
newPasswordLockoutPolicy(
|
||||
handler{view, bulkLimit, configs.cycleDuration("PasswordLockoutPolicy"), errorCount, es}),
|
||||
newLockoutPolicy(
|
||||
handler{view, bulkLimit, configs.cycleDuration("LockoutPolicy"), errorCount, es}),
|
||||
newOrgIAMPolicy(
|
||||
handler{view, bulkLimit, configs.cycleDuration("OrgIAMPolicy"), errorCount, es}),
|
||||
newMailTemplate(
|
||||
|
@@ -13,16 +13,16 @@ import (
|
||||
)
|
||||
|
||||
const (
|
||||
passwordLockoutPolicyTable = "management.password_lockout_policies"
|
||||
lockoutPolicyTable = "management.lockout_policies"
|
||||
)
|
||||
|
||||
type PasswordLockoutPolicy struct {
|
||||
type LockoutPolicy struct {
|
||||
handler
|
||||
subscription *v1.Subscription
|
||||
}
|
||||
|
||||
func newPasswordLockoutPolicy(handler handler) *PasswordLockoutPolicy {
|
||||
h := &PasswordLockoutPolicy{
|
||||
func newLockoutPolicy(handler handler) *LockoutPolicy {
|
||||
h := &LockoutPolicy{
|
||||
handler: handler,
|
||||
}
|
||||
|
||||
@@ -31,7 +31,7 @@ func newPasswordLockoutPolicy(handler handler) *PasswordLockoutPolicy {
|
||||
return h
|
||||
}
|
||||
|
||||
func (m *PasswordLockoutPolicy) subscribe() {
|
||||
func (m *LockoutPolicy) subscribe() {
|
||||
m.subscription = m.es.Subscribe(m.AggregateTypes()...)
|
||||
go func() {
|
||||
for event := range m.subscription.Events {
|
||||
@@ -40,28 +40,28 @@ func (m *PasswordLockoutPolicy) subscribe() {
|
||||
}()
|
||||
}
|
||||
|
||||
func (p *PasswordLockoutPolicy) ViewModel() string {
|
||||
return passwordLockoutPolicyTable
|
||||
func (p *LockoutPolicy) ViewModel() string {
|
||||
return lockoutPolicyTable
|
||||
}
|
||||
|
||||
func (p *PasswordLockoutPolicy) Subscription() *v1.Subscription {
|
||||
func (p *LockoutPolicy) Subscription() *v1.Subscription {
|
||||
return p.subscription
|
||||
}
|
||||
|
||||
func (_ *PasswordLockoutPolicy) AggregateTypes() []es_models.AggregateType {
|
||||
func (_ *LockoutPolicy) AggregateTypes() []es_models.AggregateType {
|
||||
return []es_models.AggregateType{model.OrgAggregate, iam_es_model.IAMAggregate}
|
||||
}
|
||||
|
||||
func (p *PasswordLockoutPolicy) CurrentSequence() (uint64, error) {
|
||||
sequence, err := p.view.GetLatestPasswordLockoutPolicySequence()
|
||||
func (p *LockoutPolicy) CurrentSequence() (uint64, error) {
|
||||
sequence, err := p.view.GetLatestLockoutPolicySequence()
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
return sequence.CurrentSequence, nil
|
||||
}
|
||||
|
||||
func (p *PasswordLockoutPolicy) EventQuery() (*es_models.SearchQuery, error) {
|
||||
sequence, err := p.view.GetLatestPasswordLockoutPolicySequence()
|
||||
func (p *LockoutPolicy) EventQuery() (*es_models.SearchQuery, error) {
|
||||
sequence, err := p.view.GetLatestLockoutPolicySequence()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -70,7 +70,7 @@ func (p *PasswordLockoutPolicy) EventQuery() (*es_models.SearchQuery, error) {
|
||||
LatestSequenceFilter(sequence.CurrentSequence), nil
|
||||
}
|
||||
|
||||
func (p *PasswordLockoutPolicy) Reduce(event *es_models.Event) (err error) {
|
||||
func (p *LockoutPolicy) Reduce(event *es_models.Event) (err error) {
|
||||
switch event.AggregateType {
|
||||
case model.OrgAggregate, iam_es_model.IAMAggregate:
|
||||
err = p.processPasswordLockoutPolicy(event)
|
||||
@@ -78,33 +78,33 @@ func (p *PasswordLockoutPolicy) Reduce(event *es_models.Event) (err error) {
|
||||
return err
|
||||
}
|
||||
|
||||
func (p *PasswordLockoutPolicy) processPasswordLockoutPolicy(event *es_models.Event) (err error) {
|
||||
policy := new(iam_model.PasswordLockoutPolicyView)
|
||||
func (p *LockoutPolicy) processPasswordLockoutPolicy(event *es_models.Event) (err error) {
|
||||
policy := new(iam_model.LockoutPolicyView)
|
||||
switch event.Type {
|
||||
case iam_es_model.PasswordLockoutPolicyAdded, model.PasswordLockoutPolicyAdded:
|
||||
case iam_es_model.LockoutPolicyAdded, model.LockoutPolicyAdded:
|
||||
err = policy.AppendEvent(event)
|
||||
case iam_es_model.PasswordLockoutPolicyChanged, model.PasswordLockoutPolicyChanged:
|
||||
policy, err = p.view.PasswordLockoutPolicyByAggregateID(event.AggregateID)
|
||||
case iam_es_model.LockoutPolicyChanged, model.LockoutPolicyChanged:
|
||||
policy, err = p.view.LockoutPolicyByAggregateID(event.AggregateID)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
err = policy.AppendEvent(event)
|
||||
case model.PasswordLockoutPolicyRemoved:
|
||||
return p.view.DeletePasswordLockoutPolicy(event.AggregateID, event)
|
||||
case model.LockoutPolicyRemoved:
|
||||
return p.view.DeleteLockoutPolicy(event.AggregateID, event)
|
||||
default:
|
||||
return p.view.ProcessedPasswordLockoutPolicySequence(event)
|
||||
return p.view.ProcessedLockoutPolicySequence(event)
|
||||
}
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return p.view.PutPasswordLockoutPolicy(policy, event)
|
||||
return p.view.PutLockoutPolicy(policy, event)
|
||||
}
|
||||
|
||||
func (p *PasswordLockoutPolicy) OnError(event *es_models.Event, err error) error {
|
||||
func (p *LockoutPolicy) OnError(event *es_models.Event, err error) error {
|
||||
logging.LogWithFields("SPOOL-Bms8f", "id", event.AggregateID).WithError(err).Warn("something went wrong in passwordLockout policy handler")
|
||||
return spooler.HandleError(event, err, p.view.GetLatestPasswordLockoutPolicyFailedEvent, p.view.ProcessedPasswordLockoutPolicyFailedEvent, p.view.ProcessedPasswordLockoutPolicySequence, p.errorCountUntilSkip)
|
||||
return spooler.HandleError(event, err, p.view.GetLatestLockoutPolicyFailedEvent, p.view.ProcessedLockoutPolicyFailedEvent, p.view.ProcessedLockoutPolicySequence, p.errorCountUntilSkip)
|
||||
}
|
||||
|
||||
func (p *PasswordLockoutPolicy) OnSuccess() error {
|
||||
return spooler.HandleSuccess(p.view.UpdatePasswordLockoutPolicySpoolerRunTimestamp)
|
||||
func (p *LockoutPolicy) OnSuccess() error {
|
||||
return spooler.HandleSuccess(p.view.UpdateLockoutPolicySpoolerRunTimestamp)
|
||||
}
|
||||
|
@@ -0,0 +1,53 @@
|
||||
package view
|
||||
|
||||
import (
|
||||
"github.com/caos/zitadel/internal/errors"
|
||||
"github.com/caos/zitadel/internal/eventstore/v1/models"
|
||||
"github.com/caos/zitadel/internal/iam/repository/view"
|
||||
"github.com/caos/zitadel/internal/iam/repository/view/model"
|
||||
global_view "github.com/caos/zitadel/internal/view/repository"
|
||||
)
|
||||
|
||||
const (
|
||||
lockoutPolicyTable = "management.lockout_policies"
|
||||
)
|
||||
|
||||
func (v *View) LockoutPolicyByAggregateID(aggregateID string) (*model.LockoutPolicyView, error) {
|
||||
return view.GetLockoutPolicyByAggregateID(v.Db, lockoutPolicyTable, aggregateID)
|
||||
}
|
||||
|
||||
func (v *View) PutLockoutPolicy(policy *model.LockoutPolicyView, event *models.Event) error {
|
||||
err := view.PutLockoutPolicy(v.Db, lockoutPolicyTable, policy)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return v.ProcessedLockoutPolicySequence(event)
|
||||
}
|
||||
|
||||
func (v *View) DeleteLockoutPolicy(aggregateID string, event *models.Event) error {
|
||||
err := view.DeleteLockoutPolicy(v.Db, lockoutPolicyTable, aggregateID)
|
||||
if err != nil && !errors.IsNotFound(err) {
|
||||
return err
|
||||
}
|
||||
return v.ProcessedLockoutPolicySequence(event)
|
||||
}
|
||||
|
||||
func (v *View) GetLatestLockoutPolicySequence() (*global_view.CurrentSequence, error) {
|
||||
return v.latestSequence(lockoutPolicyTable)
|
||||
}
|
||||
|
||||
func (v *View) ProcessedLockoutPolicySequence(event *models.Event) error {
|
||||
return v.saveCurrentSequence(lockoutPolicyTable, event)
|
||||
}
|
||||
|
||||
func (v *View) UpdateLockoutPolicySpoolerRunTimestamp() error {
|
||||
return v.updateSpoolerRunSequence(lockoutPolicyTable)
|
||||
}
|
||||
|
||||
func (v *View) GetLatestLockoutPolicyFailedEvent(sequence uint64) (*global_view.FailedEvent, error) {
|
||||
return v.latestFailedEvent(lockoutPolicyTable, sequence)
|
||||
}
|
||||
|
||||
func (v *View) ProcessedLockoutPolicyFailedEvent(failedEvent *global_view.FailedEvent) error {
|
||||
return v.saveFailedEvent(failedEvent)
|
||||
}
|
@@ -1,53 +0,0 @@
|
||||
package view
|
||||
|
||||
import (
|
||||
"github.com/caos/zitadel/internal/errors"
|
||||
"github.com/caos/zitadel/internal/eventstore/v1/models"
|
||||
"github.com/caos/zitadel/internal/iam/repository/view"
|
||||
"github.com/caos/zitadel/internal/iam/repository/view/model"
|
||||
global_view "github.com/caos/zitadel/internal/view/repository"
|
||||
)
|
||||
|
||||
const (
|
||||
passwordLockoutPolicyTable = "management.password_lockout_policies"
|
||||
)
|
||||
|
||||
func (v *View) PasswordLockoutPolicyByAggregateID(aggregateID string) (*model.PasswordLockoutPolicyView, error) {
|
||||
return view.GetPasswordLockoutPolicyByAggregateID(v.Db, passwordLockoutPolicyTable, aggregateID)
|
||||
}
|
||||
|
||||
func (v *View) PutPasswordLockoutPolicy(policy *model.PasswordLockoutPolicyView, event *models.Event) error {
|
||||
err := view.PutPasswordLockoutPolicy(v.Db, passwordLockoutPolicyTable, policy)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return v.ProcessedPasswordLockoutPolicySequence(event)
|
||||
}
|
||||
|
||||
func (v *View) DeletePasswordLockoutPolicy(aggregateID string, event *models.Event) error {
|
||||
err := view.DeletePasswordLockoutPolicy(v.Db, passwordLockoutPolicyTable, aggregateID)
|
||||
if err != nil && !errors.IsNotFound(err) {
|
||||
return err
|
||||
}
|
||||
return v.ProcessedPasswordLockoutPolicySequence(event)
|
||||
}
|
||||
|
||||
func (v *View) GetLatestPasswordLockoutPolicySequence() (*global_view.CurrentSequence, error) {
|
||||
return v.latestSequence(passwordLockoutPolicyTable)
|
||||
}
|
||||
|
||||
func (v *View) ProcessedPasswordLockoutPolicySequence(event *models.Event) error {
|
||||
return v.saveCurrentSequence(passwordLockoutPolicyTable, event)
|
||||
}
|
||||
|
||||
func (v *View) UpdatePasswordLockoutPolicySpoolerRunTimestamp() error {
|
||||
return v.updateSpoolerRunSequence(passwordLockoutPolicyTable)
|
||||
}
|
||||
|
||||
func (v *View) GetLatestPasswordLockoutPolicyFailedEvent(sequence uint64) (*global_view.FailedEvent, error) {
|
||||
return v.latestFailedEvent(passwordLockoutPolicyTable, sequence)
|
||||
}
|
||||
|
||||
func (v *View) ProcessedPasswordLockoutPolicyFailedEvent(failedEvent *global_view.FailedEvent) error {
|
||||
return v.saveFailedEvent(failedEvent)
|
||||
}
|
@@ -42,8 +42,8 @@ type OrgRepository interface {
|
||||
GetPasswordAgePolicy(ctx context.Context) (*iam_model.PasswordAgePolicyView, error)
|
||||
GetDefaultPasswordAgePolicy(ctx context.Context) (*iam_model.PasswordAgePolicyView, error)
|
||||
|
||||
GetPasswordLockoutPolicy(ctx context.Context) (*iam_model.PasswordLockoutPolicyView, error)
|
||||
GetDefaultPasswordLockoutPolicy(ctx context.Context) (*iam_model.PasswordLockoutPolicyView, error)
|
||||
GetLockoutPolicy(ctx context.Context) (*iam_model.LockoutPolicyView, error)
|
||||
GetDefaultLockoutPolicy(ctx context.Context) (*iam_model.LockoutPolicyView, error)
|
||||
|
||||
GetPrivacyPolicy(ctx context.Context) (*iam_model.PrivacyPolicyView, error)
|
||||
GetDefaultPrivacyPolicy(ctx context.Context) (*iam_model.PrivacyPolicyView, error)
|
||||
|
@@ -24,7 +24,7 @@ type Org struct {
|
||||
MailTexts []*iam_model.MailText
|
||||
PasswordComplexityPolicy *iam_model.PasswordComplexityPolicy
|
||||
PasswordAgePolicy *iam_model.PasswordAgePolicy
|
||||
PasswordLockoutPolicy *iam_model.PasswordLockoutPolicy
|
||||
LockoutPolicy *iam_model.LockoutPolicy
|
||||
|
||||
IDPs []*iam_model.IDPConfig
|
||||
}
|
||||
|
@@ -30,7 +30,7 @@ type Org struct {
|
||||
LoginPolicy *iam_es_model.LoginPolicy `json:"-"`
|
||||
PasswordComplexityPolicy *iam_es_model.PasswordComplexityPolicy `json:"-"`
|
||||
PasswordAgePolicy *iam_es_model.PasswordAgePolicy `json:"-"`
|
||||
PasswordLockoutPolicy *iam_es_model.PasswordLockoutPolicy `json:"-"`
|
||||
LockoutPolicy *iam_es_model.LockoutPolicy `json:"-"`
|
||||
}
|
||||
|
||||
func OrgToModel(org *Org) *org_model.Org {
|
||||
@@ -60,8 +60,8 @@ func OrgToModel(org *Org) *org_model.Org {
|
||||
if org.PasswordAgePolicy != nil {
|
||||
converted.PasswordAgePolicy = iam_es_model.PasswordAgePolicyToModel(org.PasswordAgePolicy)
|
||||
}
|
||||
if org.PasswordLockoutPolicy != nil {
|
||||
converted.PasswordLockoutPolicy = iam_es_model.PasswordLockoutPolicyToModel(org.PasswordLockoutPolicy)
|
||||
if org.LockoutPolicy != nil {
|
||||
converted.LockoutPolicy = iam_es_model.LockoutPolicyToModel(org.LockoutPolicy)
|
||||
}
|
||||
return converted
|
||||
}
|
||||
@@ -196,12 +196,12 @@ func (o *Org) AppendEvent(event *es_models.Event) (err error) {
|
||||
err = o.appendChangePasswordAgePolicyEvent(event)
|
||||
case PasswordAgePolicyRemoved:
|
||||
o.appendRemovePasswordAgePolicyEvent(event)
|
||||
case PasswordLockoutPolicyAdded:
|
||||
err = o.appendAddPasswordLockoutPolicyEvent(event)
|
||||
case PasswordLockoutPolicyChanged:
|
||||
err = o.appendChangePasswordLockoutPolicyEvent(event)
|
||||
case PasswordLockoutPolicyRemoved:
|
||||
o.appendRemovePasswordLockoutPolicyEvent(event)
|
||||
case LockoutPolicyAdded:
|
||||
err = o.appendAddLockoutPolicyEvent(event)
|
||||
case LockoutPolicyChanged:
|
||||
err = o.appendChangeLockoutPolicyEvent(event)
|
||||
case LockoutPolicyRemoved:
|
||||
o.appendRemoveLockoutPolicyEvent(event)
|
||||
}
|
||||
if err != nil {
|
||||
return err
|
||||
|
@@ -5,20 +5,20 @@ import (
|
||||
iam_es_model "github.com/caos/zitadel/internal/iam/repository/eventsourcing/model"
|
||||
)
|
||||
|
||||
func (o *Org) appendAddPasswordLockoutPolicyEvent(event *es_models.Event) error {
|
||||
o.PasswordLockoutPolicy = new(iam_es_model.PasswordLockoutPolicy)
|
||||
err := o.PasswordLockoutPolicy.SetData(event)
|
||||
func (o *Org) appendAddLockoutPolicyEvent(event *es_models.Event) error {
|
||||
o.LockoutPolicy = new(iam_es_model.LockoutPolicy)
|
||||
err := o.LockoutPolicy.SetData(event)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
o.PasswordLockoutPolicy.ObjectRoot.CreationDate = event.CreationDate
|
||||
o.LockoutPolicy.ObjectRoot.CreationDate = event.CreationDate
|
||||
return nil
|
||||
}
|
||||
|
||||
func (o *Org) appendChangePasswordLockoutPolicyEvent(event *es_models.Event) error {
|
||||
return o.PasswordLockoutPolicy.SetData(event)
|
||||
func (o *Org) appendChangeLockoutPolicyEvent(event *es_models.Event) error {
|
||||
return o.LockoutPolicy.SetData(event)
|
||||
}
|
||||
|
||||
func (o *Org) appendRemovePasswordLockoutPolicyEvent(event *es_models.Event) {
|
||||
o.PasswordLockoutPolicy = nil
|
||||
func (o *Org) appendRemoveLockoutPolicyEvent(event *es_models.Event) {
|
||||
o.LockoutPolicy = nil
|
||||
}
|
||||
|
@@ -7,10 +7,10 @@ import (
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestAppendAddPasswordLockoutPolicyEvent(t *testing.T) {
|
||||
func TestAppendAddLockoutPolicyEvent(t *testing.T) {
|
||||
type args struct {
|
||||
org *Org
|
||||
policy *iam_es_model.PasswordLockoutPolicy
|
||||
policy *iam_es_model.LockoutPolicy
|
||||
event *es_models.Event
|
||||
}
|
||||
tests := []struct {
|
||||
@@ -19,13 +19,13 @@ func TestAppendAddPasswordLockoutPolicyEvent(t *testing.T) {
|
||||
result *Org
|
||||
}{
|
||||
{
|
||||
name: "append add password age policy event",
|
||||
name: "append add lockout policy event",
|
||||
args: args{
|
||||
org: &Org{},
|
||||
policy: &iam_es_model.PasswordLockoutPolicy{MaxAttempts: 10},
|
||||
policy: &iam_es_model.LockoutPolicy{MaxPasswordAttempts: 10},
|
||||
event: &es_models.Event{},
|
||||
},
|
||||
result: &Org{PasswordLockoutPolicy: &iam_es_model.PasswordLockoutPolicy{MaxAttempts: 10}},
|
||||
result: &Org{LockoutPolicy: &iam_es_model.LockoutPolicy{MaxPasswordAttempts: 10}},
|
||||
},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
@@ -34,18 +34,18 @@ func TestAppendAddPasswordLockoutPolicyEvent(t *testing.T) {
|
||||
data, _ := json.Marshal(tt.args.policy)
|
||||
tt.args.event.Data = data
|
||||
}
|
||||
tt.args.org.appendAddPasswordLockoutPolicyEvent(tt.args.event)
|
||||
if tt.result.PasswordLockoutPolicy.MaxAttempts != tt.args.org.PasswordLockoutPolicy.MaxAttempts {
|
||||
t.Errorf("got wrong result: expected: %v, actual: %v ", tt.result.PasswordLockoutPolicy.MaxAttempts, tt.args.org.PasswordLockoutPolicy.MaxAttempts)
|
||||
tt.args.org.appendAddLockoutPolicyEvent(tt.args.event)
|
||||
if tt.result.LockoutPolicy.MaxPasswordAttempts != tt.args.org.LockoutPolicy.MaxPasswordAttempts {
|
||||
t.Errorf("got wrong result: expected: %v, actual: %v ", tt.result.LockoutPolicy.MaxPasswordAttempts, tt.args.org.LockoutPolicy.MaxPasswordAttempts)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestAppendChangePasswordLockoutPolicyEvent(t *testing.T) {
|
||||
func TestAppendChangeLockoutPolicyEvent(t *testing.T) {
|
||||
type args struct {
|
||||
org *Org
|
||||
policy *iam_es_model.PasswordLockoutPolicy
|
||||
policy *iam_es_model.LockoutPolicy
|
||||
event *es_models.Event
|
||||
}
|
||||
tests := []struct {
|
||||
@@ -54,16 +54,16 @@ func TestAppendChangePasswordLockoutPolicyEvent(t *testing.T) {
|
||||
result *Org
|
||||
}{
|
||||
{
|
||||
name: "append change password age policy event",
|
||||
name: "append change lockout policy event",
|
||||
args: args{
|
||||
org: &Org{PasswordLockoutPolicy: &iam_es_model.PasswordLockoutPolicy{
|
||||
MaxAttempts: 10,
|
||||
org: &Org{LockoutPolicy: &iam_es_model.LockoutPolicy{
|
||||
MaxPasswordAttempts: 10,
|
||||
}},
|
||||
policy: &iam_es_model.PasswordLockoutPolicy{MaxAttempts: 5, ShowLockOutFailures: true},
|
||||
policy: &iam_es_model.LockoutPolicy{MaxPasswordAttempts: 5, ShowLockOutFailures: true},
|
||||
event: &es_models.Event{},
|
||||
},
|
||||
result: &Org{PasswordLockoutPolicy: &iam_es_model.PasswordLockoutPolicy{
|
||||
MaxAttempts: 5,
|
||||
result: &Org{LockoutPolicy: &iam_es_model.LockoutPolicy{
|
||||
MaxPasswordAttempts: 5,
|
||||
ShowLockOutFailures: true,
|
||||
}},
|
||||
},
|
||||
@@ -74,12 +74,12 @@ func TestAppendChangePasswordLockoutPolicyEvent(t *testing.T) {
|
||||
data, _ := json.Marshal(tt.args.policy)
|
||||
tt.args.event.Data = data
|
||||
}
|
||||
tt.args.org.appendChangePasswordLockoutPolicyEvent(tt.args.event)
|
||||
if tt.result.PasswordLockoutPolicy.MaxAttempts != tt.args.org.PasswordLockoutPolicy.MaxAttempts {
|
||||
t.Errorf("got wrong result: expected: %v, actual: %v ", tt.result.PasswordLockoutPolicy.MaxAttempts, tt.args.org.PasswordLockoutPolicy.MaxAttempts)
|
||||
tt.args.org.appendChangeLockoutPolicyEvent(tt.args.event)
|
||||
if tt.result.LockoutPolicy.MaxPasswordAttempts != tt.args.org.LockoutPolicy.MaxPasswordAttempts {
|
||||
t.Errorf("got wrong result: expected: %v, actual: %v ", tt.result.LockoutPolicy.MaxPasswordAttempts, tt.args.org.LockoutPolicy.MaxPasswordAttempts)
|
||||
}
|
||||
if tt.result.PasswordLockoutPolicy.ShowLockOutFailures != tt.args.org.PasswordLockoutPolicy.ShowLockOutFailures {
|
||||
t.Errorf("got wrong result: expected: %v, actual: %v ", tt.result.PasswordLockoutPolicy.ShowLockOutFailures, tt.args.org.PasswordLockoutPolicy.ShowLockOutFailures)
|
||||
if tt.result.LockoutPolicy.ShowLockOutFailures != tt.args.org.LockoutPolicy.ShowLockOutFailures {
|
||||
t.Errorf("got wrong result: expected: %v, actual: %v ", tt.result.LockoutPolicy.ShowLockOutFailures, tt.args.org.LockoutPolicy.ShowLockOutFailures)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
@@ -89,9 +89,9 @@ const (
|
||||
PasswordAgePolicyChanged models.EventType = "org.policy.password.age.changed"
|
||||
PasswordAgePolicyRemoved models.EventType = "org.policy.password.age.removed"
|
||||
|
||||
PasswordLockoutPolicyAdded models.EventType = "org.policy.password.lockout.added"
|
||||
PasswordLockoutPolicyChanged models.EventType = "org.policy.password.lockout.changed"
|
||||
PasswordLockoutPolicyRemoved models.EventType = "org.policy.password.lockout.removed"
|
||||
LockoutPolicyAdded models.EventType = "org.policy.lockout.added"
|
||||
LockoutPolicyChanged models.EventType = "org.policy.lockout.changed"
|
||||
LockoutPolicyRemoved models.EventType = "org.policy.lockout.removed"
|
||||
|
||||
PrivacyPolicyAdded models.EventType = "org.policy.privacy.added"
|
||||
PrivacyPolicyChanged models.EventType = "org.policy.privacy.changed"
|
||||
|
@@ -20,7 +20,7 @@ func readModelToIAM(readModel *ReadModel) *model.IAM {
|
||||
DefaultOrgIAMPolicy: readModelToOrgIAMPolicy(&readModel.DefaultOrgIAMPolicy),
|
||||
DefaultPasswordAgePolicy: readModelToPasswordAgePolicy(&readModel.DefaultPasswordAgePolicy),
|
||||
DefaultPasswordComplexityPolicy: readModelToPasswordComplexityPolicy(&readModel.DefaultPasswordComplexityPolicy),
|
||||
DefaultPasswordLockoutPolicy: readModelToPasswordLockoutPolicy(&readModel.DefaultPasswordLockoutPolicy),
|
||||
DefaultLockoutPolicy: readModelToPasswordLockoutPolicy(&readModel.DefaultPasswordLockoutPolicy),
|
||||
IDPs: readModelToIDPConfigs(&readModel.IDPs),
|
||||
}
|
||||
}
|
||||
@@ -121,10 +121,10 @@ func readModelToPasswordComplexityPolicy(readModel *IAMPasswordComplexityPolicyR
|
||||
MinLength: readModel.MinLength,
|
||||
}
|
||||
}
|
||||
func readModelToPasswordLockoutPolicy(readModel *IAMPasswordLockoutPolicyReadModel) *model.PasswordLockoutPolicy {
|
||||
return &model.PasswordLockoutPolicy{
|
||||
ObjectRoot: readModelToObjectRoot(readModel.PasswordLockoutPolicyReadModel.ReadModel),
|
||||
MaxAttempts: readModel.MaxAttempts,
|
||||
func readModelToPasswordLockoutPolicy(readModel *IAMLockoutPolicyReadModel) *model.LockoutPolicy {
|
||||
return &model.LockoutPolicy{
|
||||
ObjectRoot: readModelToObjectRoot(readModel.LockoutPolicyReadModel.ReadModel),
|
||||
MaxPasswordAttempts: readModel.MaxAttempts,
|
||||
ShowLockOutFailures: readModel.ShowLockOutFailures,
|
||||
}
|
||||
}
|
||||
|
@@ -25,7 +25,7 @@ type ReadModel struct {
|
||||
DefaultOrgIAMPolicy IAMOrgIAMPolicyReadModel
|
||||
DefaultPasswordComplexityPolicy IAMPasswordComplexityPolicyReadModel
|
||||
DefaultPasswordAgePolicy IAMPasswordAgePolicyReadModel
|
||||
DefaultPasswordLockoutPolicy IAMPasswordLockoutPolicyReadModel
|
||||
DefaultPasswordLockoutPolicy IAMLockoutPolicyReadModel
|
||||
}
|
||||
|
||||
func NewReadModel(id string) *ReadModel {
|
||||
@@ -80,8 +80,8 @@ func (rm *ReadModel) AppendEvents(events ...eventstore.EventReader) {
|
||||
*policy.PasswordAgePolicyChangedEvent:
|
||||
|
||||
rm.DefaultPasswordAgePolicy.AppendEvents(event)
|
||||
case *policy.PasswordLockoutPolicyAddedEvent,
|
||||
*policy.PasswordLockoutPolicyChangedEvent:
|
||||
case *policy.LockoutPolicyAddedEvent,
|
||||
*policy.LockoutPolicyChangedEvent:
|
||||
|
||||
rm.DefaultPasswordLockoutPolicy.AppendEvents(event)
|
||||
}
|
||||
|
@@ -6,19 +6,19 @@ import (
|
||||
"github.com/caos/zitadel/internal/repository/policy"
|
||||
)
|
||||
|
||||
type IAMPasswordLockoutPolicyReadModel struct {
|
||||
PasswordLockoutPolicyReadModel
|
||||
type IAMLockoutPolicyReadModel struct {
|
||||
LockoutPolicyReadModel
|
||||
}
|
||||
|
||||
func (rm *IAMPasswordLockoutPolicyReadModel) AppendEvents(events ...eventstore.EventReader) {
|
||||
func (rm *IAMLockoutPolicyReadModel) AppendEvents(events ...eventstore.EventReader) {
|
||||
for _, event := range events {
|
||||
switch e := event.(type) {
|
||||
case *iam.PasswordLockoutPolicyAddedEvent:
|
||||
rm.PasswordLockoutPolicyReadModel.AppendEvents(&e.PasswordLockoutPolicyAddedEvent)
|
||||
case *iam.PasswordLockoutPolicyChangedEvent:
|
||||
rm.PasswordLockoutPolicyReadModel.AppendEvents(&e.PasswordLockoutPolicyChangedEvent)
|
||||
case *policy.PasswordLockoutPolicyAddedEvent, *policy.PasswordLockoutPolicyChangedEvent:
|
||||
rm.PasswordLockoutPolicyReadModel.AppendEvents(e)
|
||||
case *iam.LockoutPolicyAddedEvent:
|
||||
rm.LockoutPolicyReadModel.AppendEvents(&e.LockoutPolicyAddedEvent)
|
||||
case *iam.LockoutPolicyChangedEvent:
|
||||
rm.LockoutPolicyReadModel.AppendEvents(&e.LockoutPolicyChangedEvent)
|
||||
case *policy.LockoutPolicyAddedEvent, *policy.LockoutPolicyChangedEvent:
|
||||
rm.LockoutPolicyReadModel.AppendEvents(e)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -7,18 +7,18 @@ import (
|
||||
)
|
||||
|
||||
type OrgPasswordLockoutPolicyReadModel struct {
|
||||
PasswordLockoutPolicyReadModel
|
||||
LockoutPolicyReadModel
|
||||
}
|
||||
|
||||
func (rm *OrgPasswordLockoutPolicyReadModel) AppendEvents(events ...eventstore.EventReader) {
|
||||
for _, event := range events {
|
||||
switch e := event.(type) {
|
||||
case *org.PasswordLockoutPolicyAddedEvent:
|
||||
rm.PasswordLockoutPolicyReadModel.AppendEvents(&e.PasswordLockoutPolicyAddedEvent)
|
||||
case *org.PasswordLockoutPolicyChangedEvent:
|
||||
rm.PasswordLockoutPolicyReadModel.AppendEvents(&e.PasswordLockoutPolicyChangedEvent)
|
||||
case *policy.PasswordLockoutPolicyAddedEvent, *policy.PasswordLockoutPolicyChangedEvent:
|
||||
rm.PasswordLockoutPolicyReadModel.AppendEvents(e)
|
||||
case *org.LockoutPolicyAddedEvent:
|
||||
rm.LockoutPolicyReadModel.AppendEvents(&e.LockoutPolicyAddedEvent)
|
||||
case *org.LockoutPolicyChangedEvent:
|
||||
rm.LockoutPolicyReadModel.AppendEvents(&e.LockoutPolicyChangedEvent)
|
||||
case *policy.LockoutPolicyAddedEvent, *policy.LockoutPolicyChangedEvent:
|
||||
rm.LockoutPolicyReadModel.AppendEvents(e)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -5,22 +5,22 @@ import (
|
||||
"github.com/caos/zitadel/internal/repository/policy"
|
||||
)
|
||||
|
||||
type PasswordLockoutPolicyReadModel struct {
|
||||
type LockoutPolicyReadModel struct {
|
||||
eventstore.ReadModel
|
||||
|
||||
MaxAttempts uint64
|
||||
ShowLockOutFailures bool
|
||||
}
|
||||
|
||||
func (rm *PasswordLockoutPolicyReadModel) Reduce() error {
|
||||
func (rm *LockoutPolicyReadModel) Reduce() error {
|
||||
for _, event := range rm.Events {
|
||||
switch e := event.(type) {
|
||||
case *policy.PasswordLockoutPolicyAddedEvent:
|
||||
rm.MaxAttempts = e.MaxAttempts
|
||||
case *policy.LockoutPolicyAddedEvent:
|
||||
rm.MaxAttempts = e.MaxPasswordAttempts
|
||||
rm.ShowLockOutFailures = e.ShowLockOutFailures
|
||||
case *policy.PasswordLockoutPolicyChangedEvent:
|
||||
if e.MaxAttempts != nil {
|
||||
rm.MaxAttempts = *e.MaxAttempts
|
||||
case *policy.LockoutPolicyChangedEvent:
|
||||
if e.MaxPasswordAttempts != nil {
|
||||
rm.MaxAttempts = *e.MaxPasswordAttempts
|
||||
}
|
||||
if e.ShowLockOutFailures != nil {
|
||||
rm.ShowLockOutFailures = *e.ShowLockOutFailures
|
||||
|
@@ -32,8 +32,8 @@ func RegisterEventMappers(es *eventstore.Eventstore) {
|
||||
RegisterFilterEventMapper(PasswordAgePolicyChangedEventType, PasswordAgePolicyChangedEventMapper).
|
||||
RegisterFilterEventMapper(PasswordComplexityPolicyAddedEventType, PasswordComplexityPolicyAddedEventMapper).
|
||||
RegisterFilterEventMapper(PasswordComplexityPolicyChangedEventType, PasswordComplexityPolicyChangedEventMapper).
|
||||
RegisterFilterEventMapper(PasswordLockoutPolicyAddedEventType, PasswordLockoutPolicyAddedEventMapper).
|
||||
RegisterFilterEventMapper(PasswordLockoutPolicyChangedEventType, PasswordLockoutPolicyChangedEventMapper).
|
||||
RegisterFilterEventMapper(LockoutPolicyAddedEventType, LockoutPolicyAddedEventMapper).
|
||||
RegisterFilterEventMapper(LockoutPolicyChangedEventType, LockoutPolicyChangedEventMapper).
|
||||
RegisterFilterEventMapper(PrivacyPolicyAddedEventType, PrivacyPolicyAddedEventMapper).
|
||||
RegisterFilterEventMapper(PrivacyPolicyChangedEventType, PrivacyPolicyChangedEventMapper).
|
||||
RegisterFilterEventMapper(MemberAddedEventType, MemberAddedEventMapper).
|
||||
|
@@ -9,67 +9,67 @@ import (
|
||||
)
|
||||
|
||||
var (
|
||||
PasswordLockoutPolicyAddedEventType = iamEventTypePrefix + policy.PasswordLockoutPolicyAddedEventType
|
||||
PasswordLockoutPolicyChangedEventType = iamEventTypePrefix + policy.PasswordLockoutPolicyChangedEventType
|
||||
LockoutPolicyAddedEventType = iamEventTypePrefix + policy.LockoutPolicyAddedEventType
|
||||
LockoutPolicyChangedEventType = iamEventTypePrefix + policy.LockoutPolicyChangedEventType
|
||||
)
|
||||
|
||||
type PasswordLockoutPolicyAddedEvent struct {
|
||||
policy.PasswordLockoutPolicyAddedEvent
|
||||
type LockoutPolicyAddedEvent struct {
|
||||
policy.LockoutPolicyAddedEvent
|
||||
}
|
||||
|
||||
func NewPasswordLockoutPolicyAddedEvent(
|
||||
func NewLockoutPolicyAddedEvent(
|
||||
ctx context.Context,
|
||||
aggregate *eventstore.Aggregate,
|
||||
maxAttempts uint64,
|
||||
showLockoutFailure bool,
|
||||
) *PasswordLockoutPolicyAddedEvent {
|
||||
return &PasswordLockoutPolicyAddedEvent{
|
||||
PasswordLockoutPolicyAddedEvent: *policy.NewPasswordLockoutPolicyAddedEvent(
|
||||
) *LockoutPolicyAddedEvent {
|
||||
return &LockoutPolicyAddedEvent{
|
||||
LockoutPolicyAddedEvent: *policy.NewLockoutPolicyAddedEvent(
|
||||
eventstore.NewBaseEventForPush(
|
||||
ctx,
|
||||
aggregate,
|
||||
PasswordLockoutPolicyAddedEventType),
|
||||
LockoutPolicyAddedEventType),
|
||||
maxAttempts,
|
||||
showLockoutFailure),
|
||||
}
|
||||
}
|
||||
|
||||
func PasswordLockoutPolicyAddedEventMapper(event *repository.Event) (eventstore.EventReader, error) {
|
||||
e, err := policy.PasswordLockoutPolicyAddedEventMapper(event)
|
||||
func LockoutPolicyAddedEventMapper(event *repository.Event) (eventstore.EventReader, error) {
|
||||
e, err := policy.LockoutPolicyAddedEventMapper(event)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &PasswordLockoutPolicyAddedEvent{PasswordLockoutPolicyAddedEvent: *e.(*policy.PasswordLockoutPolicyAddedEvent)}, nil
|
||||
return &LockoutPolicyAddedEvent{LockoutPolicyAddedEvent: *e.(*policy.LockoutPolicyAddedEvent)}, nil
|
||||
}
|
||||
|
||||
type PasswordLockoutPolicyChangedEvent struct {
|
||||
policy.PasswordLockoutPolicyChangedEvent
|
||||
type LockoutPolicyChangedEvent struct {
|
||||
policy.LockoutPolicyChangedEvent
|
||||
}
|
||||
|
||||
func NewPasswordLockoutPolicyChangedEvent(
|
||||
func NewLockoutPolicyChangedEvent(
|
||||
ctx context.Context,
|
||||
aggregate *eventstore.Aggregate,
|
||||
changes []policy.PasswordLockoutPolicyChanges,
|
||||
) (*PasswordLockoutPolicyChangedEvent, error) {
|
||||
changedEvent, err := policy.NewPasswordLockoutPolicyChangedEvent(
|
||||
changes []policy.LockoutPolicyChanges,
|
||||
) (*LockoutPolicyChangedEvent, error) {
|
||||
changedEvent, err := policy.NewLockoutPolicyChangedEvent(
|
||||
eventstore.NewBaseEventForPush(
|
||||
ctx,
|
||||
aggregate,
|
||||
PasswordLockoutPolicyChangedEventType),
|
||||
LockoutPolicyChangedEventType),
|
||||
changes,
|
||||
)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &PasswordLockoutPolicyChangedEvent{PasswordLockoutPolicyChangedEvent: *changedEvent}, nil
|
||||
return &LockoutPolicyChangedEvent{LockoutPolicyChangedEvent: *changedEvent}, nil
|
||||
}
|
||||
|
||||
func PasswordLockoutPolicyChangedEventMapper(event *repository.Event) (eventstore.EventReader, error) {
|
||||
e, err := policy.PasswordLockoutPolicyChangedEventMapper(event)
|
||||
func LockoutPolicyChangedEventMapper(event *repository.Event) (eventstore.EventReader, error) {
|
||||
e, err := policy.LockoutPolicyChangedEventMapper(event)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &PasswordLockoutPolicyChangedEvent{PasswordLockoutPolicyChangedEvent: *e.(*policy.PasswordLockoutPolicyChangedEvent)}, nil
|
||||
return &LockoutPolicyChangedEvent{LockoutPolicyChangedEvent: *e.(*policy.LockoutPolicyChangedEvent)}, nil
|
||||
}
|
||||
|
@@ -53,9 +53,9 @@ func RegisterEventMappers(es *eventstore.Eventstore) {
|
||||
RegisterFilterEventMapper(PasswordComplexityPolicyAddedEventType, PasswordComplexityPolicyAddedEventMapper).
|
||||
RegisterFilterEventMapper(PasswordComplexityPolicyChangedEventType, PasswordComplexityPolicyChangedEventMapper).
|
||||
RegisterFilterEventMapper(PasswordComplexityPolicyRemovedEventType, PasswordComplexityPolicyRemovedEventMapper).
|
||||
RegisterFilterEventMapper(PasswordLockoutPolicyAddedEventType, PasswordLockoutPolicyAddedEventMapper).
|
||||
RegisterFilterEventMapper(PasswordLockoutPolicyChangedEventType, PasswordLockoutPolicyChangedEventMapper).
|
||||
RegisterFilterEventMapper(PasswordLockoutPolicyRemovedEventType, PasswordLockoutPolicyRemovedEventMapper).
|
||||
RegisterFilterEventMapper(LockoutPolicyAddedEventType, LockoutPolicyAddedEventMapper).
|
||||
RegisterFilterEventMapper(LockoutPolicyChangedEventType, LockoutPolicyChangedEventMapper).
|
||||
RegisterFilterEventMapper(LockoutPolicyRemovedEventType, LockoutPolicyRemovedEventMapper).
|
||||
RegisterFilterEventMapper(PrivacyPolicyAddedEventType, PrivacyPolicyAddedEventMapper).
|
||||
RegisterFilterEventMapper(PrivacyPolicyChangedEventType, PrivacyPolicyChangedEventMapper).
|
||||
RegisterFilterEventMapper(PrivacyPolicyRemovedEventType, PrivacyPolicyRemovedEventMapper).
|
||||
|
@@ -9,95 +9,95 @@ import (
|
||||
)
|
||||
|
||||
var (
|
||||
PasswordLockoutPolicyAddedEventType = orgEventTypePrefix + policy.PasswordLockoutPolicyAddedEventType
|
||||
PasswordLockoutPolicyChangedEventType = orgEventTypePrefix + policy.PasswordLockoutPolicyChangedEventType
|
||||
PasswordLockoutPolicyRemovedEventType = orgEventTypePrefix + policy.PasswordLockoutPolicyRemovedEventType
|
||||
LockoutPolicyAddedEventType = orgEventTypePrefix + policy.LockoutPolicyAddedEventType
|
||||
LockoutPolicyChangedEventType = orgEventTypePrefix + policy.LockoutPolicyChangedEventType
|
||||
LockoutPolicyRemovedEventType = orgEventTypePrefix + policy.LockoutPolicyRemovedEventType
|
||||
)
|
||||
|
||||
type PasswordLockoutPolicyAddedEvent struct {
|
||||
policy.PasswordLockoutPolicyAddedEvent
|
||||
type LockoutPolicyAddedEvent struct {
|
||||
policy.LockoutPolicyAddedEvent
|
||||
}
|
||||
|
||||
func NewPasswordLockoutPolicyAddedEvent(
|
||||
func NewLockoutPolicyAddedEvent(
|
||||
ctx context.Context,
|
||||
aggregate *eventstore.Aggregate,
|
||||
maxAttempts uint64,
|
||||
showLockoutFailure bool,
|
||||
) *PasswordLockoutPolicyAddedEvent {
|
||||
return &PasswordLockoutPolicyAddedEvent{
|
||||
PasswordLockoutPolicyAddedEvent: *policy.NewPasswordLockoutPolicyAddedEvent(
|
||||
) *LockoutPolicyAddedEvent {
|
||||
return &LockoutPolicyAddedEvent{
|
||||
LockoutPolicyAddedEvent: *policy.NewLockoutPolicyAddedEvent(
|
||||
eventstore.NewBaseEventForPush(
|
||||
ctx,
|
||||
aggregate,
|
||||
PasswordLockoutPolicyAddedEventType),
|
||||
LockoutPolicyAddedEventType),
|
||||
maxAttempts,
|
||||
showLockoutFailure),
|
||||
}
|
||||
}
|
||||
|
||||
func PasswordLockoutPolicyAddedEventMapper(event *repository.Event) (eventstore.EventReader, error) {
|
||||
e, err := policy.PasswordLockoutPolicyAddedEventMapper(event)
|
||||
func LockoutPolicyAddedEventMapper(event *repository.Event) (eventstore.EventReader, error) {
|
||||
e, err := policy.LockoutPolicyAddedEventMapper(event)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &PasswordLockoutPolicyAddedEvent{PasswordLockoutPolicyAddedEvent: *e.(*policy.PasswordLockoutPolicyAddedEvent)}, nil
|
||||
return &LockoutPolicyAddedEvent{LockoutPolicyAddedEvent: *e.(*policy.LockoutPolicyAddedEvent)}, nil
|
||||
}
|
||||
|
||||
type PasswordLockoutPolicyChangedEvent struct {
|
||||
policy.PasswordLockoutPolicyChangedEvent
|
||||
type LockoutPolicyChangedEvent struct {
|
||||
policy.LockoutPolicyChangedEvent
|
||||
}
|
||||
|
||||
func NewPasswordLockoutPolicyChangedEvent(
|
||||
func NewLockoutPolicyChangedEvent(
|
||||
ctx context.Context,
|
||||
aggregate *eventstore.Aggregate,
|
||||
changes []policy.PasswordLockoutPolicyChanges,
|
||||
) (*PasswordLockoutPolicyChangedEvent, error) {
|
||||
changedEvent, err := policy.NewPasswordLockoutPolicyChangedEvent(
|
||||
changes []policy.LockoutPolicyChanges,
|
||||
) (*LockoutPolicyChangedEvent, error) {
|
||||
changedEvent, err := policy.NewLockoutPolicyChangedEvent(
|
||||
eventstore.NewBaseEventForPush(
|
||||
ctx,
|
||||
aggregate,
|
||||
PasswordLockoutPolicyChangedEventType),
|
||||
LockoutPolicyChangedEventType),
|
||||
changes,
|
||||
)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &PasswordLockoutPolicyChangedEvent{PasswordLockoutPolicyChangedEvent: *changedEvent}, nil
|
||||
return &LockoutPolicyChangedEvent{LockoutPolicyChangedEvent: *changedEvent}, nil
|
||||
}
|
||||
|
||||
func PasswordLockoutPolicyChangedEventMapper(event *repository.Event) (eventstore.EventReader, error) {
|
||||
e, err := policy.PasswordLockoutPolicyChangedEventMapper(event)
|
||||
func LockoutPolicyChangedEventMapper(event *repository.Event) (eventstore.EventReader, error) {
|
||||
e, err := policy.LockoutPolicyChangedEventMapper(event)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &PasswordLockoutPolicyChangedEvent{PasswordLockoutPolicyChangedEvent: *e.(*policy.PasswordLockoutPolicyChangedEvent)}, nil
|
||||
return &LockoutPolicyChangedEvent{LockoutPolicyChangedEvent: *e.(*policy.LockoutPolicyChangedEvent)}, nil
|
||||
}
|
||||
|
||||
type PasswordLockoutPolicyRemovedEvent struct {
|
||||
policy.PasswordLockoutPolicyRemovedEvent
|
||||
type LockoutPolicyRemovedEvent struct {
|
||||
policy.LockoutPolicyRemovedEvent
|
||||
}
|
||||
|
||||
func NewPasswordLockoutPolicyRemovedEvent(
|
||||
func NewLockoutPolicyRemovedEvent(
|
||||
ctx context.Context,
|
||||
aggregate *eventstore.Aggregate,
|
||||
) *PasswordLockoutPolicyRemovedEvent {
|
||||
return &PasswordLockoutPolicyRemovedEvent{
|
||||
PasswordLockoutPolicyRemovedEvent: *policy.NewPasswordLockoutPolicyRemovedEvent(
|
||||
) *LockoutPolicyRemovedEvent {
|
||||
return &LockoutPolicyRemovedEvent{
|
||||
LockoutPolicyRemovedEvent: *policy.NewLockoutPolicyRemovedEvent(
|
||||
eventstore.NewBaseEventForPush(
|
||||
ctx,
|
||||
aggregate,
|
||||
PasswordLockoutPolicyRemovedEventType),
|
||||
LockoutPolicyRemovedEventType),
|
||||
),
|
||||
}
|
||||
}
|
||||
|
||||
func PasswordLockoutPolicyRemovedEventMapper(event *repository.Event) (eventstore.EventReader, error) {
|
||||
e, err := policy.PasswordLockoutPolicyRemovedEventMapper(event)
|
||||
func LockoutPolicyRemovedEventMapper(event *repository.Event) (eventstore.EventReader, error) {
|
||||
e, err := policy.LockoutPolicyRemovedEventMapper(event)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &PasswordLockoutPolicyRemovedEvent{PasswordLockoutPolicyRemovedEvent: *e.(*policy.PasswordLockoutPolicyRemovedEvent)}, nil
|
||||
return &LockoutPolicyRemovedEvent{LockoutPolicyRemovedEvent: *e.(*policy.LockoutPolicyRemovedEvent)}, nil
|
||||
}
|
||||
|
@@ -9,41 +9,41 @@ import (
|
||||
)
|
||||
|
||||
const (
|
||||
PasswordLockoutPolicyAddedEventType = "policy.password.lockout.added"
|
||||
PasswordLockoutPolicyChangedEventType = "policy.password.lockout.changed"
|
||||
PasswordLockoutPolicyRemovedEventType = "policy.password.lockout.removed"
|
||||
LockoutPolicyAddedEventType = "policy.lockout.added"
|
||||
LockoutPolicyChangedEventType = "policy.lockout.changed"
|
||||
LockoutPolicyRemovedEventType = "policy.lockout.removed"
|
||||
)
|
||||
|
||||
type PasswordLockoutPolicyAddedEvent struct {
|
||||
type LockoutPolicyAddedEvent struct {
|
||||
eventstore.BaseEvent `json:"-"`
|
||||
|
||||
MaxAttempts uint64 `json:"maxAttempts,omitempty"`
|
||||
MaxPasswordAttempts uint64 `json:"maxPasswordAttempts,omitempty"`
|
||||
ShowLockOutFailures bool `json:"showLockOutFailures,omitempty"`
|
||||
}
|
||||
|
||||
func (e *PasswordLockoutPolicyAddedEvent) Data() interface{} {
|
||||
func (e *LockoutPolicyAddedEvent) Data() interface{} {
|
||||
return e
|
||||
}
|
||||
|
||||
func (e *PasswordLockoutPolicyAddedEvent) UniqueConstraints() []*eventstore.EventUniqueConstraint {
|
||||
func (e *LockoutPolicyAddedEvent) UniqueConstraints() []*eventstore.EventUniqueConstraint {
|
||||
return nil
|
||||
}
|
||||
|
||||
func NewPasswordLockoutPolicyAddedEvent(
|
||||
func NewLockoutPolicyAddedEvent(
|
||||
base *eventstore.BaseEvent,
|
||||
maxAttempts uint64,
|
||||
showLockOutFailures bool,
|
||||
) *PasswordLockoutPolicyAddedEvent {
|
||||
) *LockoutPolicyAddedEvent {
|
||||
|
||||
return &PasswordLockoutPolicyAddedEvent{
|
||||
return &LockoutPolicyAddedEvent{
|
||||
BaseEvent: *base,
|
||||
MaxAttempts: maxAttempts,
|
||||
MaxPasswordAttempts: maxAttempts,
|
||||
ShowLockOutFailures: showLockOutFailures,
|
||||
}
|
||||
}
|
||||
|
||||
func PasswordLockoutPolicyAddedEventMapper(event *repository.Event) (eventstore.EventReader, error) {
|
||||
e := &PasswordLockoutPolicyAddedEvent{
|
||||
func LockoutPolicyAddedEventMapper(event *repository.Event) (eventstore.EventReader, error) {
|
||||
e := &LockoutPolicyAddedEvent{
|
||||
BaseEvent: *eventstore.BaseEventFromRepo(event),
|
||||
}
|
||||
|
||||
@@ -55,29 +55,29 @@ func PasswordLockoutPolicyAddedEventMapper(event *repository.Event) (eventstore.
|
||||
return e, nil
|
||||
}
|
||||
|
||||
type PasswordLockoutPolicyChangedEvent struct {
|
||||
type LockoutPolicyChangedEvent struct {
|
||||
eventstore.BaseEvent `json:"-"`
|
||||
|
||||
MaxAttempts *uint64 `json:"maxAttempts,omitempty"`
|
||||
MaxPasswordAttempts *uint64 `json:"maxPasswordAttempts,omitempty"`
|
||||
ShowLockOutFailures *bool `json:"showLockOutFailures,omitempty"`
|
||||
}
|
||||
|
||||
func (e *PasswordLockoutPolicyChangedEvent) Data() interface{} {
|
||||
func (e *LockoutPolicyChangedEvent) Data() interface{} {
|
||||
return e
|
||||
}
|
||||
|
||||
func (e *PasswordLockoutPolicyChangedEvent) UniqueConstraints() []*eventstore.EventUniqueConstraint {
|
||||
func (e *LockoutPolicyChangedEvent) UniqueConstraints() []*eventstore.EventUniqueConstraint {
|
||||
return nil
|
||||
}
|
||||
|
||||
func NewPasswordLockoutPolicyChangedEvent(
|
||||
func NewLockoutPolicyChangedEvent(
|
||||
base *eventstore.BaseEvent,
|
||||
changes []PasswordLockoutPolicyChanges,
|
||||
) (*PasswordLockoutPolicyChangedEvent, error) {
|
||||
changes []LockoutPolicyChanges,
|
||||
) (*LockoutPolicyChangedEvent, error) {
|
||||
if len(changes) == 0 {
|
||||
return nil, errors.ThrowPreconditionFailed(nil, "POLICY-sdgh6", "Errors.NoChangesFound")
|
||||
}
|
||||
changeEvent := &PasswordLockoutPolicyChangedEvent{
|
||||
changeEvent := &LockoutPolicyChangedEvent{
|
||||
BaseEvent: *base,
|
||||
}
|
||||
for _, change := range changes {
|
||||
@@ -86,22 +86,22 @@ func NewPasswordLockoutPolicyChangedEvent(
|
||||
return changeEvent, nil
|
||||
}
|
||||
|
||||
type PasswordLockoutPolicyChanges func(*PasswordLockoutPolicyChangedEvent)
|
||||
type LockoutPolicyChanges func(*LockoutPolicyChangedEvent)
|
||||
|
||||
func ChangeMaxAttempts(maxAttempts uint64) func(*PasswordLockoutPolicyChangedEvent) {
|
||||
return func(e *PasswordLockoutPolicyChangedEvent) {
|
||||
e.MaxAttempts = &maxAttempts
|
||||
func ChangeMaxAttempts(maxAttempts uint64) func(*LockoutPolicyChangedEvent) {
|
||||
return func(e *LockoutPolicyChangedEvent) {
|
||||
e.MaxPasswordAttempts = &maxAttempts
|
||||
}
|
||||
}
|
||||
|
||||
func ChangeShowLockOutFailures(showLockOutFailures bool) func(*PasswordLockoutPolicyChangedEvent) {
|
||||
return func(e *PasswordLockoutPolicyChangedEvent) {
|
||||
func ChangeShowLockOutFailures(showLockOutFailures bool) func(*LockoutPolicyChangedEvent) {
|
||||
return func(e *LockoutPolicyChangedEvent) {
|
||||
e.ShowLockOutFailures = &showLockOutFailures
|
||||
}
|
||||
}
|
||||
|
||||
func PasswordLockoutPolicyChangedEventMapper(event *repository.Event) (eventstore.EventReader, error) {
|
||||
e := &PasswordLockoutPolicyChangedEvent{
|
||||
func LockoutPolicyChangedEventMapper(event *repository.Event) (eventstore.EventReader, error) {
|
||||
e := &LockoutPolicyChangedEvent{
|
||||
BaseEvent: *eventstore.BaseEventFromRepo(event),
|
||||
}
|
||||
|
||||
@@ -113,26 +113,26 @@ func PasswordLockoutPolicyChangedEventMapper(event *repository.Event) (eventstor
|
||||
return e, nil
|
||||
}
|
||||
|
||||
type PasswordLockoutPolicyRemovedEvent struct {
|
||||
type LockoutPolicyRemovedEvent struct {
|
||||
eventstore.BaseEvent `json:"-"`
|
||||
}
|
||||
|
||||
func (e *PasswordLockoutPolicyRemovedEvent) Data() interface{} {
|
||||
func (e *LockoutPolicyRemovedEvent) Data() interface{} {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (e *PasswordLockoutPolicyRemovedEvent) UniqueConstraints() []*eventstore.EventUniqueConstraint {
|
||||
func (e *LockoutPolicyRemovedEvent) UniqueConstraints() []*eventstore.EventUniqueConstraint {
|
||||
return nil
|
||||
}
|
||||
|
||||
func NewPasswordLockoutPolicyRemovedEvent(base *eventstore.BaseEvent) *PasswordLockoutPolicyRemovedEvent {
|
||||
return &PasswordLockoutPolicyRemovedEvent{
|
||||
func NewLockoutPolicyRemovedEvent(base *eventstore.BaseEvent) *LockoutPolicyRemovedEvent {
|
||||
return &LockoutPolicyRemovedEvent{
|
||||
BaseEvent: *base,
|
||||
}
|
||||
}
|
||||
|
||||
func PasswordLockoutPolicyRemovedEventMapper(event *repository.Event) (eventstore.EventReader, error) {
|
||||
return &PasswordLockoutPolicyRemovedEvent{
|
||||
func LockoutPolicyRemovedEventMapper(event *repository.Event) (eventstore.EventReader, error) {
|
||||
return &LockoutPolicyRemovedEvent{
|
||||
BaseEvent: *eventstore.BaseEventFromRepo(event),
|
||||
}, nil
|
||||
}
|
||||
|
@@ -23,6 +23,7 @@ type IAMSetUp struct {
|
||||
Step15 *command.Step15
|
||||
Step16 *command.Step16
|
||||
Step17 *command.Step17
|
||||
Step18 *command.Step18
|
||||
}
|
||||
|
||||
func (setup *IAMSetUp) Steps(currentDone domain.Step) ([]command.Step, error) {
|
||||
@@ -46,6 +47,7 @@ func (setup *IAMSetUp) Steps(currentDone domain.Step) ([]command.Step, error) {
|
||||
setup.Step15,
|
||||
setup.Step16,
|
||||
setup.Step17,
|
||||
setup.Step18,
|
||||
} {
|
||||
if step.Step() <= currentDone {
|
||||
continue
|
||||
|
@@ -231,6 +231,10 @@ func (l *Login) renderNextStep(w http.ResponseWriter, r *http.Request, authReq *
|
||||
}
|
||||
|
||||
func (l *Login) renderError(w http.ResponseWriter, r *http.Request, authReq *domain.AuthRequest, err error) {
|
||||
if err != nil {
|
||||
l.renderInternalError(w, r, authReq, err)
|
||||
return
|
||||
}
|
||||
if authReq == nil || len(authReq.PossibleSteps) == 0 {
|
||||
l.renderInternalError(w, r, authReq, caos_errs.ThrowInternal(err, "APP-OVOiT", "no possible steps"))
|
||||
return
|
||||
@@ -292,7 +296,7 @@ func (l *Login) chooseNextStep(w http.ResponseWriter, r *http.Request, authReq *
|
||||
func (l *Login) renderInternalError(w http.ResponseWriter, r *http.Request, authReq *domain.AuthRequest, err error) {
|
||||
var msg string
|
||||
if err != nil {
|
||||
msg = err.Error()
|
||||
_, msg = l.getErrorMessage(r, err)
|
||||
}
|
||||
data := l.getBaseData(r, authReq, "Error", "Internal", msg)
|
||||
l.renderer.RenderTemplate(w, r, l.getTranslator(authReq), l.renderer.Templates[tmplError], data, nil)
|
||||
|
@@ -288,6 +288,7 @@ Errors:
|
||||
ConfirmationWrong: Passwort Bestätigung stimmt nicht überein
|
||||
Empty: Passwort ist leer
|
||||
Invalid: Passwort ungültig
|
||||
InvalidAndLocked: Password ist undgültig und Benutzer wurde gesperrt, melden Sie sich bei ihrem Administrator.
|
||||
PasswordComplexityPolicy:
|
||||
NotFound: Passwort Policy konnte nicht gefunden werden
|
||||
MinLength: Passwort ist zu kurz
|
||||
@@ -312,6 +313,7 @@ Errors:
|
||||
InvalidCode: Code ist ungültig
|
||||
NotReady: Multifaktor OTP (OneTimePassword) ist nicht bereit
|
||||
Locked: Benutzer ist gesperrt
|
||||
SomethingWentWrong: Irgendetwas ist schief gelaufen
|
||||
NotActive: Benutzer ist nicht aktiv
|
||||
ExternalIDP:
|
||||
IDPTypeNotImplemented: IDP Typ ist nicht implementiert
|
||||
@@ -319,5 +321,8 @@ Errors:
|
||||
GrantRequired: Der Login an diese Applikation ist nicht möglich. Der Benutzer benötigt mindestens eine Berechtigung an der Applikation. Bitte melde dich bei deinem Administrator.
|
||||
IdentityProvider:
|
||||
InvalidConfig: Identitäts Provider Konfiguration ist ungültig
|
||||
IAM:
|
||||
LockoutPolicy:
|
||||
NotExisting: Lockout Policy existiert nicht
|
||||
|
||||
optional: (optional)
|
||||
|
@@ -288,6 +288,7 @@ Errors:
|
||||
ConfirmationWrong: Passwordconfirmation is wrong
|
||||
Empty: Password is empty
|
||||
Invalid: Password is invalid
|
||||
InvalidAndLocked: Password is invalid and user is locked, contact your administrator.
|
||||
PasswordComplexityPolicy:
|
||||
NotFound: Password policy not found
|
||||
MinLength: Password is to short
|
||||
@@ -312,6 +313,7 @@ Errors:
|
||||
InvalidCode: Invalid code
|
||||
NotReady: Multifactor OTP (OneTimePassword) isn't ready
|
||||
Locked: User is locked
|
||||
SomethingWentWrong: Something went wrong
|
||||
NotActive: User is not active
|
||||
ExternalIDP:
|
||||
IDPTypeNotImplemented: IDP Type is not implemented
|
||||
@@ -319,5 +321,8 @@ Errors:
|
||||
GrantRequired: Login not possible. The user is required to have at least one grant on the application. Please contact your administrator.
|
||||
IdentityProvider:
|
||||
InvalidConfig: Identity Provider configuration is invalid
|
||||
IAM:
|
||||
LockoutPolicy:
|
||||
NotExisting: Lockout Policy not existing
|
||||
|
||||
optional: (optional)
|
||||
|
Reference in New Issue
Block a user