mirror of
https://github.com/zitadel/zitadel.git
synced 2025-10-17 09:04:09 +00:00
feat: provide option to limit (T)OTP checks (#7693)
* feat: provide option to limit (T)OTP checks * fix requests in console * update errors pkg * cleanup * cleanup * improve naming of existing config
This commit is contained in:
@@ -12,8 +12,10 @@ import (
|
||||
type HumanTOTPWriteModel struct {
|
||||
eventstore.WriteModel
|
||||
|
||||
State domain.MFAState
|
||||
Secret *crypto.CryptoValue
|
||||
State domain.MFAState
|
||||
Secret *crypto.CryptoValue
|
||||
CheckFailedCount uint64
|
||||
UserLocked bool
|
||||
}
|
||||
|
||||
func NewHumanTOTPWriteModel(userID, resourceOwner string) *HumanTOTPWriteModel {
|
||||
@@ -33,6 +35,16 @@ func (wm *HumanTOTPWriteModel) Reduce() error {
|
||||
wm.State = domain.MFAStateNotReady
|
||||
case *user.HumanOTPVerifiedEvent:
|
||||
wm.State = domain.MFAStateReady
|
||||
wm.CheckFailedCount = 0
|
||||
case *user.HumanOTPCheckSucceededEvent:
|
||||
wm.CheckFailedCount = 0
|
||||
case *user.HumanOTPCheckFailedEvent:
|
||||
wm.CheckFailedCount++
|
||||
case *user.UserLockedEvent:
|
||||
wm.UserLocked = true
|
||||
case *user.UserUnlockedEvent:
|
||||
wm.CheckFailedCount = 0
|
||||
wm.UserLocked = false
|
||||
case *user.HumanOTPRemovedEvent:
|
||||
wm.State = domain.MFAStateRemoved
|
||||
case *user.UserRemovedEvent:
|
||||
@@ -50,6 +62,10 @@ func (wm *HumanTOTPWriteModel) Query() *eventstore.SearchQueryBuilder {
|
||||
EventTypes(user.HumanMFAOTPAddedType,
|
||||
user.HumanMFAOTPVerifiedType,
|
||||
user.HumanMFAOTPRemovedType,
|
||||
user.HumanMFAOTPCheckSucceededType,
|
||||
user.HumanMFAOTPCheckFailedType,
|
||||
user.UserLockedType,
|
||||
user.UserUnlockedType,
|
||||
user.UserRemovedType,
|
||||
user.UserV1MFAOTPAddedType,
|
||||
user.UserV1MFAOTPVerifiedType,
|
||||
@@ -72,6 +88,9 @@ type OTPCodeWriteModel interface {
|
||||
CodeCreationDate() time.Time
|
||||
CodeExpiry() time.Duration
|
||||
Code() *crypto.CryptoValue
|
||||
CheckFailedCount() uint64
|
||||
UserLocked() bool
|
||||
eventstore.QueryReducer
|
||||
}
|
||||
|
||||
type HumanOTPSMSWriteModel struct {
|
||||
@@ -141,6 +160,9 @@ type HumanOTPSMSCodeWriteModel struct {
|
||||
code *crypto.CryptoValue
|
||||
codeCreationDate time.Time
|
||||
codeExpiry time.Duration
|
||||
|
||||
checkFailedCount uint64
|
||||
userLocked bool
|
||||
}
|
||||
|
||||
func (wm *HumanOTPSMSCodeWriteModel) CodeCreationDate() time.Time {
|
||||
@@ -155,6 +177,14 @@ func (wm *HumanOTPSMSCodeWriteModel) Code() *crypto.CryptoValue {
|
||||
return wm.code
|
||||
}
|
||||
|
||||
func (wm *HumanOTPSMSCodeWriteModel) CheckFailedCount() uint64 {
|
||||
return wm.checkFailedCount
|
||||
}
|
||||
|
||||
func (wm *HumanOTPSMSCodeWriteModel) UserLocked() bool {
|
||||
return wm.userLocked
|
||||
}
|
||||
|
||||
func NewHumanOTPSMSCodeWriteModel(userID, resourceOwner string) *HumanOTPSMSCodeWriteModel {
|
||||
return &HumanOTPSMSCodeWriteModel{
|
||||
HumanOTPSMSWriteModel: NewHumanOTPSMSWriteModel(userID, resourceOwner),
|
||||
@@ -163,10 +193,20 @@ func NewHumanOTPSMSCodeWriteModel(userID, resourceOwner string) *HumanOTPSMSCode
|
||||
|
||||
func (wm *HumanOTPSMSCodeWriteModel) Reduce() error {
|
||||
for _, event := range wm.Events {
|
||||
if e, ok := event.(*user.HumanOTPSMSCodeAddedEvent); ok {
|
||||
switch e := event.(type) {
|
||||
case *user.HumanOTPSMSCodeAddedEvent:
|
||||
wm.code = e.Code
|
||||
wm.codeCreationDate = e.CreationDate()
|
||||
wm.codeExpiry = e.Expiry
|
||||
case *user.HumanOTPSMSCheckSucceededEvent:
|
||||
wm.checkFailedCount = 0
|
||||
case *user.HumanOTPSMSCheckFailedEvent:
|
||||
wm.checkFailedCount++
|
||||
case *user.UserLockedEvent:
|
||||
wm.userLocked = true
|
||||
case *user.UserUnlockedEvent:
|
||||
wm.checkFailedCount = 0
|
||||
wm.userLocked = false
|
||||
}
|
||||
}
|
||||
return wm.HumanOTPSMSWriteModel.Reduce()
|
||||
@@ -179,6 +219,10 @@ func (wm *HumanOTPSMSCodeWriteModel) Query() *eventstore.SearchQueryBuilder {
|
||||
AggregateIDs(wm.AggregateID).
|
||||
EventTypes(
|
||||
user.HumanOTPSMSCodeAddedType,
|
||||
user.HumanOTPSMSCheckSucceededType,
|
||||
user.HumanOTPSMSCheckFailedType,
|
||||
user.UserLockedType,
|
||||
user.UserUnlockedType,
|
||||
user.HumanPhoneVerifiedType,
|
||||
user.HumanOTPSMSAddedType,
|
||||
user.HumanOTPSMSRemovedType,
|
||||
@@ -259,6 +303,9 @@ type HumanOTPEmailCodeWriteModel struct {
|
||||
code *crypto.CryptoValue
|
||||
codeCreationDate time.Time
|
||||
codeExpiry time.Duration
|
||||
|
||||
checkFailedCount uint64
|
||||
userLocked bool
|
||||
}
|
||||
|
||||
func (wm *HumanOTPEmailCodeWriteModel) CodeCreationDate() time.Time {
|
||||
@@ -273,6 +320,14 @@ func (wm *HumanOTPEmailCodeWriteModel) Code() *crypto.CryptoValue {
|
||||
return wm.code
|
||||
}
|
||||
|
||||
func (wm *HumanOTPEmailCodeWriteModel) CheckFailedCount() uint64 {
|
||||
return wm.checkFailedCount
|
||||
}
|
||||
|
||||
func (wm *HumanOTPEmailCodeWriteModel) UserLocked() bool {
|
||||
return wm.userLocked
|
||||
}
|
||||
|
||||
func NewHumanOTPEmailCodeWriteModel(userID, resourceOwner string) *HumanOTPEmailCodeWriteModel {
|
||||
return &HumanOTPEmailCodeWriteModel{
|
||||
HumanOTPEmailWriteModel: NewHumanOTPEmailWriteModel(userID, resourceOwner),
|
||||
@@ -281,10 +336,20 @@ func NewHumanOTPEmailCodeWriteModel(userID, resourceOwner string) *HumanOTPEmail
|
||||
|
||||
func (wm *HumanOTPEmailCodeWriteModel) Reduce() error {
|
||||
for _, event := range wm.Events {
|
||||
if e, ok := event.(*user.HumanOTPEmailCodeAddedEvent); ok {
|
||||
switch e := event.(type) {
|
||||
case *user.HumanOTPEmailCodeAddedEvent:
|
||||
wm.code = e.Code
|
||||
wm.codeCreationDate = e.CreationDate()
|
||||
wm.codeExpiry = e.Expiry
|
||||
case *user.HumanOTPEmailCheckSucceededEvent:
|
||||
wm.checkFailedCount = 0
|
||||
case *user.HumanOTPEmailCheckFailedEvent:
|
||||
wm.checkFailedCount++
|
||||
case *user.UserLockedEvent:
|
||||
wm.userLocked = true
|
||||
case *user.UserUnlockedEvent:
|
||||
wm.checkFailedCount = 0
|
||||
wm.userLocked = false
|
||||
}
|
||||
}
|
||||
return wm.HumanOTPEmailWriteModel.Reduce()
|
||||
@@ -297,6 +362,10 @@ func (wm *HumanOTPEmailCodeWriteModel) Query() *eventstore.SearchQueryBuilder {
|
||||
AggregateIDs(wm.AggregateID).
|
||||
EventTypes(
|
||||
user.HumanOTPEmailCodeAddedType,
|
||||
user.HumanOTPEmailCheckSucceededType,
|
||||
user.HumanOTPEmailCheckFailedType,
|
||||
user.UserLockedType,
|
||||
user.UserUnlockedType,
|
||||
user.HumanEmailVerifiedType,
|
||||
user.HumanOTPEmailAddedType,
|
||||
user.HumanOTPEmailRemovedType,
|
||||
|
Reference in New Issue
Block a user