mirror of
https://github.com/zitadel/zitadel.git
synced 2025-08-11 20:47:32 +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:
@@ -1671,6 +1671,15 @@ func TestCommandSide_HumanCheckOTPSMS(t *testing.T) {
|
||||
),
|
||||
),
|
||||
),
|
||||
expectFilter(), // recheck
|
||||
expectFilter(
|
||||
eventFromEventPusher(
|
||||
org.NewLockoutPolicyAddedEvent(ctx,
|
||||
&org.NewAggregate("orgID").Aggregate,
|
||||
3, 3, true,
|
||||
),
|
||||
),
|
||||
),
|
||||
expectPush(
|
||||
user.NewHumanOTPSMSCheckFailedEvent(ctx,
|
||||
&user.NewAggregate("user1", "org1").Aggregate,
|
||||
@@ -1707,6 +1716,86 @@ func TestCommandSide_HumanCheckOTPSMS(t *testing.T) {
|
||||
err: zerrors.ThrowInvalidArgument(nil, "CODE-woT0xc", "Errors.User.Code.Invalid"),
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "invalid code, max attempts reached, error",
|
||||
fields: fields{
|
||||
eventstore: expectEventstore(
|
||||
expectFilter(
|
||||
eventFromEventPusher(
|
||||
user.NewHumanOTPSMSAddedEvent(ctx,
|
||||
&user.NewAggregate("user1", "org1").Aggregate,
|
||||
),
|
||||
),
|
||||
eventFromEventPusherWithCreationDateNow(
|
||||
user.NewHumanOTPSMSCodeAddedEvent(ctx,
|
||||
&user.NewAggregate("user1", "org1").Aggregate,
|
||||
&crypto.CryptoValue{
|
||||
CryptoType: crypto.TypeEncryption,
|
||||
Algorithm: "enc",
|
||||
KeyID: "id",
|
||||
Crypted: []byte("other-code"),
|
||||
},
|
||||
time.Hour,
|
||||
&user.AuthRequestInfo{
|
||||
ID: "authRequestID",
|
||||
UserAgentID: "userAgentID",
|
||||
BrowserInfo: &user.BrowserInfo{
|
||||
UserAgent: "user-agent",
|
||||
AcceptLanguage: "en",
|
||||
RemoteIP: net.IP{192, 0, 2, 1},
|
||||
},
|
||||
},
|
||||
),
|
||||
),
|
||||
),
|
||||
expectFilter(), // recheck
|
||||
expectFilter(
|
||||
eventFromEventPusher(
|
||||
org.NewLockoutPolicyAddedEvent(ctx,
|
||||
&org.NewAggregate("orgID").Aggregate,
|
||||
1, 1, true,
|
||||
),
|
||||
),
|
||||
),
|
||||
expectPush(
|
||||
user.NewHumanOTPSMSCheckFailedEvent(ctx,
|
||||
&user.NewAggregate("user1", "org1").Aggregate,
|
||||
&user.AuthRequestInfo{
|
||||
ID: "authRequestID",
|
||||
UserAgentID: "userAgentID",
|
||||
BrowserInfo: &user.BrowserInfo{
|
||||
UserAgent: "user-agent",
|
||||
AcceptLanguage: "en",
|
||||
RemoteIP: net.IP{192, 0, 2, 1},
|
||||
},
|
||||
},
|
||||
),
|
||||
user.NewUserLockedEvent(ctx,
|
||||
&user.NewAggregate("user1", "org1").Aggregate,
|
||||
),
|
||||
),
|
||||
),
|
||||
userEncryption: crypto.CreateMockEncryptionAlg(gomock.NewController(t)),
|
||||
},
|
||||
args: args{
|
||||
ctx: ctx,
|
||||
userID: "user1",
|
||||
code: "code",
|
||||
resourceOwner: "org1",
|
||||
authRequest: &domain.AuthRequest{
|
||||
ID: "authRequestID",
|
||||
AgentID: "userAgentID",
|
||||
BrowserInfo: &domain.BrowserInfo{
|
||||
UserAgent: "user-agent",
|
||||
AcceptLanguage: "en",
|
||||
RemoteIP: net.IP{192, 0, 2, 1},
|
||||
},
|
||||
},
|
||||
},
|
||||
res: res{
|
||||
err: zerrors.ThrowInvalidArgument(nil, "CODE-woT0xc", "Errors.User.Code.Invalid"),
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "code ok",
|
||||
fields: fields{
|
||||
@@ -1739,6 +1828,7 @@ func TestCommandSide_HumanCheckOTPSMS(t *testing.T) {
|
||||
),
|
||||
),
|
||||
),
|
||||
expectFilter(), // recheck
|
||||
expectPush(
|
||||
user.NewHumanOTPSMSCheckSucceededEvent(ctx,
|
||||
&user.NewAggregate("user1", "org1").Aggregate,
|
||||
@@ -1777,6 +1867,65 @@ func TestCommandSide_HumanCheckOTPSMS(t *testing.T) {
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "code ok, locked in the meantime",
|
||||
fields: fields{
|
||||
eventstore: expectEventstore(
|
||||
expectFilter(
|
||||
eventFromEventPusher(
|
||||
user.NewHumanOTPSMSAddedEvent(ctx,
|
||||
&user.NewAggregate("user1", "org1").Aggregate,
|
||||
),
|
||||
),
|
||||
eventFromEventPusherWithCreationDateNow(
|
||||
user.NewHumanOTPSMSCodeAddedEvent(ctx,
|
||||
&user.NewAggregate("user1", "org1").Aggregate,
|
||||
&crypto.CryptoValue{
|
||||
CryptoType: crypto.TypeEncryption,
|
||||
Algorithm: "enc",
|
||||
KeyID: "id",
|
||||
Crypted: []byte("code"),
|
||||
},
|
||||
time.Hour,
|
||||
&user.AuthRequestInfo{
|
||||
ID: "authRequestID",
|
||||
UserAgentID: "userAgentID",
|
||||
BrowserInfo: &user.BrowserInfo{
|
||||
UserAgent: "user-agent",
|
||||
AcceptLanguage: "en",
|
||||
RemoteIP: net.IP{192, 0, 2, 1},
|
||||
},
|
||||
},
|
||||
),
|
||||
),
|
||||
),
|
||||
expectFilter( // recheck
|
||||
user.NewUserLockedEvent(ctx,
|
||||
&user.NewAggregate("user1", "org1").Aggregate,
|
||||
),
|
||||
),
|
||||
),
|
||||
userEncryption: crypto.CreateMockEncryptionAlg(gomock.NewController(t)),
|
||||
},
|
||||
args: args{
|
||||
ctx: ctx,
|
||||
userID: "user1",
|
||||
code: "code",
|
||||
resourceOwner: "org1",
|
||||
authRequest: &domain.AuthRequest{
|
||||
ID: "authRequestID",
|
||||
AgentID: "userAgentID",
|
||||
BrowserInfo: &domain.BrowserInfo{
|
||||
UserAgent: "user-agent",
|
||||
AcceptLanguage: "en",
|
||||
RemoteIP: net.IP{192, 0, 2, 1},
|
||||
},
|
||||
},
|
||||
},
|
||||
res: res{
|
||||
err: zerrors.ThrowPreconditionFailed(nil, "COMMAND-S6h4R", "Errors.User.Locked"),
|
||||
},
|
||||
},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
@@ -2616,6 +2765,15 @@ func TestCommandSide_HumanCheckOTPEmail(t *testing.T) {
|
||||
),
|
||||
),
|
||||
),
|
||||
expectFilter(), // recheck
|
||||
expectFilter(
|
||||
eventFromEventPusher(
|
||||
org.NewLockoutPolicyAddedEvent(ctx,
|
||||
&org.NewAggregate("orgID").Aggregate,
|
||||
3, 3, true,
|
||||
),
|
||||
),
|
||||
),
|
||||
expectPush(
|
||||
user.NewHumanOTPEmailCheckFailedEvent(ctx,
|
||||
&user.NewAggregate("user1", "org1").Aggregate,
|
||||
@@ -2652,6 +2810,86 @@ func TestCommandSide_HumanCheckOTPEmail(t *testing.T) {
|
||||
err: zerrors.ThrowInvalidArgument(nil, "CODE-woT0xc", "Errors.User.Code.Invalid"),
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "invalid code, max attempts reached, error",
|
||||
fields: fields{
|
||||
eventstore: expectEventstore(
|
||||
expectFilter(
|
||||
eventFromEventPusher(
|
||||
user.NewHumanOTPEmailAddedEvent(ctx,
|
||||
&user.NewAggregate("user1", "org1").Aggregate,
|
||||
),
|
||||
),
|
||||
eventFromEventPusherWithCreationDateNow(
|
||||
user.NewHumanOTPEmailCodeAddedEvent(ctx,
|
||||
&user.NewAggregate("user1", "org1").Aggregate,
|
||||
&crypto.CryptoValue{
|
||||
CryptoType: crypto.TypeEncryption,
|
||||
Algorithm: "enc",
|
||||
KeyID: "id",
|
||||
Crypted: []byte("other-code"),
|
||||
},
|
||||
time.Hour,
|
||||
&user.AuthRequestInfo{
|
||||
ID: "authRequestID",
|
||||
UserAgentID: "userAgentID",
|
||||
BrowserInfo: &user.BrowserInfo{
|
||||
UserAgent: "user-agent",
|
||||
AcceptLanguage: "en",
|
||||
RemoteIP: net.IP{192, 0, 2, 1},
|
||||
},
|
||||
},
|
||||
),
|
||||
),
|
||||
),
|
||||
expectFilter(), // recheck
|
||||
expectFilter(
|
||||
eventFromEventPusher(
|
||||
org.NewLockoutPolicyAddedEvent(ctx,
|
||||
&org.NewAggregate("orgID").Aggregate,
|
||||
1, 1, true,
|
||||
),
|
||||
),
|
||||
),
|
||||
expectPush(
|
||||
user.NewHumanOTPEmailCheckFailedEvent(ctx,
|
||||
&user.NewAggregate("user1", "org1").Aggregate,
|
||||
&user.AuthRequestInfo{
|
||||
ID: "authRequestID",
|
||||
UserAgentID: "userAgentID",
|
||||
BrowserInfo: &user.BrowserInfo{
|
||||
UserAgent: "user-agent",
|
||||
AcceptLanguage: "en",
|
||||
RemoteIP: net.IP{192, 0, 2, 1},
|
||||
},
|
||||
},
|
||||
),
|
||||
user.NewUserLockedEvent(ctx,
|
||||
&user.NewAggregate("user1", "org1").Aggregate,
|
||||
),
|
||||
),
|
||||
),
|
||||
userEncryption: crypto.CreateMockEncryptionAlg(gomock.NewController(t)),
|
||||
},
|
||||
args: args{
|
||||
ctx: ctx,
|
||||
userID: "user1",
|
||||
code: "code",
|
||||
resourceOwner: "org1",
|
||||
authRequest: &domain.AuthRequest{
|
||||
ID: "authRequestID",
|
||||
AgentID: "userAgentID",
|
||||
BrowserInfo: &domain.BrowserInfo{
|
||||
UserAgent: "user-agent",
|
||||
AcceptLanguage: "en",
|
||||
RemoteIP: net.IP{192, 0, 2, 1},
|
||||
},
|
||||
},
|
||||
},
|
||||
res: res{
|
||||
err: zerrors.ThrowInvalidArgument(nil, "CODE-woT0xc", "Errors.User.Code.Invalid"),
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "code ok",
|
||||
fields: fields{
|
||||
@@ -2684,6 +2922,7 @@ func TestCommandSide_HumanCheckOTPEmail(t *testing.T) {
|
||||
),
|
||||
),
|
||||
),
|
||||
expectFilter(), // recheck
|
||||
expectPush(
|
||||
user.NewHumanOTPEmailCheckSucceededEvent(ctx,
|
||||
&user.NewAggregate("user1", "org1").Aggregate,
|
||||
@@ -2722,6 +2961,65 @@ func TestCommandSide_HumanCheckOTPEmail(t *testing.T) {
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "code ok, locked in the meantime",
|
||||
fields: fields{
|
||||
eventstore: expectEventstore(
|
||||
expectFilter(
|
||||
eventFromEventPusher(
|
||||
user.NewHumanOTPEmailAddedEvent(ctx,
|
||||
&user.NewAggregate("user1", "org1").Aggregate,
|
||||
),
|
||||
),
|
||||
eventFromEventPusherWithCreationDateNow(
|
||||
user.NewHumanOTPEmailCodeAddedEvent(ctx,
|
||||
&user.NewAggregate("user1", "org1").Aggregate,
|
||||
&crypto.CryptoValue{
|
||||
CryptoType: crypto.TypeEncryption,
|
||||
Algorithm: "enc",
|
||||
KeyID: "id",
|
||||
Crypted: []byte("code"),
|
||||
},
|
||||
time.Hour,
|
||||
&user.AuthRequestInfo{
|
||||
ID: "authRequestID",
|
||||
UserAgentID: "userAgentID",
|
||||
BrowserInfo: &user.BrowserInfo{
|
||||
UserAgent: "user-agent",
|
||||
AcceptLanguage: "en",
|
||||
RemoteIP: net.IP{192, 0, 2, 1},
|
||||
},
|
||||
},
|
||||
),
|
||||
),
|
||||
),
|
||||
expectFilter( // recheck
|
||||
user.NewUserLockedEvent(ctx,
|
||||
&user.NewAggregate("user1", "org1").Aggregate,
|
||||
),
|
||||
),
|
||||
),
|
||||
userEncryption: crypto.CreateMockEncryptionAlg(gomock.NewController(t)),
|
||||
},
|
||||
args: args{
|
||||
ctx: ctx,
|
||||
userID: "user1",
|
||||
code: "code",
|
||||
resourceOwner: "org1",
|
||||
authRequest: &domain.AuthRequest{
|
||||
ID: "authRequestID",
|
||||
AgentID: "userAgentID",
|
||||
BrowserInfo: &domain.BrowserInfo{
|
||||
UserAgent: "user-agent",
|
||||
AcceptLanguage: "en",
|
||||
RemoteIP: net.IP{192, 0, 2, 1},
|
||||
},
|
||||
},
|
||||
},
|
||||
res: res{
|
||||
err: zerrors.ThrowPreconditionFailed(nil, "COMMAND-S6h4R", "Errors.User.Locked"),
|
||||
},
|
||||
},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
|
Reference in New Issue
Block a user