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:
Livio Spring
2024-04-10 11:14:55 +02:00
committed by GitHub
parent e3f10f7e23
commit 153df2e12f
58 changed files with 752 additions and 755 deletions

View File

@@ -27,6 +27,7 @@ type LockoutPolicy struct {
State domain.PolicyState
MaxPasswordAttempts uint64
MaxOTPAttempts uint64
ShowFailures bool
IsDefault bool
@@ -69,6 +70,10 @@ var (
name: projection.LockoutPolicyMaxPasswordAttemptsCol,
table: lockoutTable,
}
LockoutColMaxOTPAttempts = Column{
name: projection.LockoutPolicyMaxOTPAttemptsCol,
table: lockoutTable,
}
LockoutColIsDefault = Column{
name: projection.LockoutPolicyIsDefaultCol,
table: lockoutTable,
@@ -77,13 +82,9 @@ var (
name: projection.LockoutPolicyStateCol,
table: lockoutTable,
}
LockoutPolicyOwnerRemoved = Column{
name: projection.LockoutPolicyOwnerRemovedCol,
table: lockoutTable,
}
)
func (q *Queries) LockoutPolicyByOrg(ctx context.Context, shouldTriggerBulk bool, orgID string, withOwnerRemoved bool) (policy *LockoutPolicy, err error) {
func (q *Queries) LockoutPolicyByOrg(ctx context.Context, shouldTriggerBulk bool, orgID string) (policy *LockoutPolicy, err error) {
ctx, span := tracing.NewSpan(ctx)
defer func() { span.EndWithError(err) }()
@@ -96,9 +97,6 @@ func (q *Queries) LockoutPolicyByOrg(ctx context.Context, shouldTriggerBulk bool
eq := sq.Eq{
LockoutColInstanceID.identifier(): authz.GetInstance(ctx).InstanceID(),
}
if !withOwnerRemoved {
eq[LockoutPolicyOwnerRemoved.identifier()] = false
}
stmt, scan := prepareLockoutPolicyQuery(ctx, q.client)
query, args, err := stmt.Where(
@@ -153,6 +151,7 @@ func prepareLockoutPolicyQuery(ctx context.Context, db prepareDatabase) (sq.Sele
LockoutColResourceOwner.identifier(),
LockoutColShowFailures.identifier(),
LockoutColMaxPasswordAttempts.identifier(),
LockoutColMaxOTPAttempts.identifier(),
LockoutColIsDefault.identifier(),
LockoutColState.identifier(),
).
@@ -168,6 +167,7 @@ func prepareLockoutPolicyQuery(ctx context.Context, db prepareDatabase) (sq.Sele
&policy.ResourceOwner,
&policy.ShowFailures,
&policy.MaxPasswordAttempts,
&policy.MaxOTPAttempts,
&policy.IsDefault,
&policy.State,
)

View File

@@ -13,16 +13,17 @@ import (
)
var (
prepareLockoutPolicyStmt = `SELECT projections.lockout_policies2.id,` +
` projections.lockout_policies2.sequence,` +
` projections.lockout_policies2.creation_date,` +
` projections.lockout_policies2.change_date,` +
` projections.lockout_policies2.resource_owner,` +
` projections.lockout_policies2.show_failure,` +
` projections.lockout_policies2.max_password_attempts,` +
` projections.lockout_policies2.is_default,` +
` projections.lockout_policies2.state` +
` FROM projections.lockout_policies2` +
prepareLockoutPolicyStmt = `SELECT projections.lockout_policies3.id,` +
` projections.lockout_policies3.sequence,` +
` projections.lockout_policies3.creation_date,` +
` projections.lockout_policies3.change_date,` +
` projections.lockout_policies3.resource_owner,` +
` projections.lockout_policies3.show_failure,` +
` projections.lockout_policies3.max_password_attempts,` +
` projections.lockout_policies3.max_otp_attempts,` +
` projections.lockout_policies3.is_default,` +
` projections.lockout_policies3.state` +
` FROM projections.lockout_policies3` +
` AS OF SYSTEM TIME '-1 ms'`
prepareLockoutPolicyCols = []string{
@@ -33,6 +34,7 @@ var (
"resource_owner",
"show_failure",
"max_password_attempts",
"max_otp_attempts",
"is_default",
"state",
}
@@ -82,6 +84,7 @@ func Test_LockoutPolicyPrepares(t *testing.T) {
"ro",
true,
20,
20,
true,
domain.PolicyStateActive,
},
@@ -96,6 +99,7 @@ func Test_LockoutPolicyPrepares(t *testing.T) {
State: domain.PolicyStateActive,
ShowFailures: true,
MaxPasswordAttempts: 20,
MaxOTPAttempts: 20,
IsDefault: true,
},
},

View File

@@ -14,7 +14,7 @@ import (
)
const (
LockoutPolicyTable = "projections.lockout_policies2"
LockoutPolicyTable = "projections.lockout_policies3"
LockoutPolicyIDCol = "id"
LockoutPolicyCreationDateCol = "creation_date"
@@ -25,8 +25,8 @@ const (
LockoutPolicyResourceOwnerCol = "resource_owner"
LockoutPolicyInstanceIDCol = "instance_id"
LockoutPolicyMaxPasswordAttemptsCol = "max_password_attempts"
LockoutPolicyMaxOTPAttemptsCol = "max_otp_attempts"
LockoutPolicyShowLockOutFailuresCol = "show_failure"
LockoutPolicyOwnerRemovedCol = "owner_removed"
)
type lockoutPolicyProjection struct{}
@@ -51,11 +51,10 @@ func (*lockoutPolicyProjection) Init() *old_handler.Check {
handler.NewColumn(LockoutPolicyResourceOwnerCol, handler.ColumnTypeText),
handler.NewColumn(LockoutPolicyInstanceIDCol, handler.ColumnTypeText),
handler.NewColumn(LockoutPolicyMaxPasswordAttemptsCol, handler.ColumnTypeInt64),
handler.NewColumn(LockoutPolicyMaxOTPAttemptsCol, handler.ColumnTypeInt64, handler.Default(0)),
handler.NewColumn(LockoutPolicyShowLockOutFailuresCol, handler.ColumnTypeBool),
handler.NewColumn(LockoutPolicyOwnerRemovedCol, handler.ColumnTypeBool, handler.Default(false)),
},
handler.NewPrimaryKey(LockoutPolicyInstanceIDCol, LockoutPolicyIDCol),
handler.WithIndex(handler.NewIndex("owner_removed", []string{LockoutPolicyOwnerRemovedCol})),
),
)
}
@@ -125,6 +124,7 @@ func (p *lockoutPolicyProjection) reduceAdded(event eventstore.Event) (*handler.
handler.NewCol(LockoutPolicyIDCol, policyEvent.Aggregate().ID),
handler.NewCol(LockoutPolicyStateCol, domain.PolicyStateActive),
handler.NewCol(LockoutPolicyMaxPasswordAttemptsCol, policyEvent.MaxPasswordAttempts),
handler.NewCol(LockoutPolicyMaxOTPAttemptsCol, policyEvent.MaxOTPAttempts),
handler.NewCol(LockoutPolicyShowLockOutFailuresCol, policyEvent.ShowLockOutFailures),
handler.NewCol(LockoutPolicyIsDefaultCol, isDefault),
handler.NewCol(LockoutPolicyResourceOwnerCol, policyEvent.Aggregate().ResourceOwner),
@@ -149,6 +149,9 @@ func (p *lockoutPolicyProjection) reduceChanged(event eventstore.Event) (*handle
if policyEvent.MaxPasswordAttempts != nil {
cols = append(cols, handler.NewCol(LockoutPolicyMaxPasswordAttemptsCol, *policyEvent.MaxPasswordAttempts))
}
if policyEvent.MaxOTPAttempts != nil {
cols = append(cols, handler.NewCol(LockoutPolicyMaxOTPAttemptsCol, *policyEvent.MaxOTPAttempts))
}
if policyEvent.ShowLockOutFailures != nil {
cols = append(cols, handler.NewCol(LockoutPolicyShowLockOutFailuresCol, *policyEvent.ShowLockOutFailures))
}

View File

@@ -30,6 +30,7 @@ func TestLockoutPolicyProjection_reduces(t *testing.T) {
org.AggregateType,
[]byte(`{
"maxPasswordAttempts": 10,
"maxOTPAttempts": 10,
"showLockOutFailures": true
}`),
), org.LockoutPolicyAddedEventMapper),
@@ -41,7 +42,7 @@ func TestLockoutPolicyProjection_reduces(t *testing.T) {
executer: &testExecuter{
executions: []execution{
{
expectedStmt: "INSERT INTO projections.lockout_policies2 (creation_date, change_date, sequence, id, state, max_password_attempts, show_failure, is_default, resource_owner, instance_id) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10)",
expectedStmt: "INSERT INTO projections.lockout_policies3 (creation_date, change_date, sequence, id, state, max_password_attempts, max_otp_attempts, show_failure, is_default, resource_owner, instance_id) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11)",
expectedArgs: []interface{}{
anyArg{},
anyArg{},
@@ -49,6 +50,7 @@ func TestLockoutPolicyProjection_reduces(t *testing.T) {
"agg-id",
domain.PolicyStateActive,
uint64(10),
uint64(10),
true,
false,
"ro-id",
@@ -69,6 +71,7 @@ func TestLockoutPolicyProjection_reduces(t *testing.T) {
org.AggregateType,
[]byte(`{
"maxPasswordAttempts": 10,
"maxOTPAttempts": 10,
"showLockOutFailures": true
}`),
), org.LockoutPolicyChangedEventMapper),
@@ -79,11 +82,12 @@ func TestLockoutPolicyProjection_reduces(t *testing.T) {
executer: &testExecuter{
executions: []execution{
{
expectedStmt: "UPDATE projections.lockout_policies2 SET (change_date, sequence, max_password_attempts, show_failure) = ($1, $2, $3, $4) WHERE (id = $5) AND (instance_id = $6)",
expectedStmt: "UPDATE projections.lockout_policies3 SET (change_date, sequence, max_password_attempts, max_otp_attempts, show_failure) = ($1, $2, $3, $4, $5) WHERE (id = $6) AND (instance_id = $7)",
expectedArgs: []interface{}{
anyArg{},
uint64(15),
uint64(10),
uint64(10),
true,
"agg-id",
"instance-id",
@@ -110,7 +114,7 @@ func TestLockoutPolicyProjection_reduces(t *testing.T) {
executer: &testExecuter{
executions: []execution{
{
expectedStmt: "DELETE FROM projections.lockout_policies2 WHERE (id = $1) AND (instance_id = $2)",
expectedStmt: "DELETE FROM projections.lockout_policies3 WHERE (id = $1) AND (instance_id = $2)",
expectedArgs: []interface{}{
"agg-id",
"instance-id",
@@ -137,7 +141,7 @@ func TestLockoutPolicyProjection_reduces(t *testing.T) {
executer: &testExecuter{
executions: []execution{
{
expectedStmt: "DELETE FROM projections.lockout_policies2 WHERE (instance_id = $1)",
expectedStmt: "DELETE FROM projections.lockout_policies3 WHERE (instance_id = $1)",
expectedArgs: []interface{}{
"agg-id",
},
@@ -156,6 +160,7 @@ func TestLockoutPolicyProjection_reduces(t *testing.T) {
instance.AggregateType,
[]byte(`{
"maxPasswordAttempts": 10,
"maxOTPAttempts": 10,
"showLockOutFailures": true
}`),
), instance.LockoutPolicyAddedEventMapper),
@@ -166,7 +171,7 @@ func TestLockoutPolicyProjection_reduces(t *testing.T) {
executer: &testExecuter{
executions: []execution{
{
expectedStmt: "INSERT INTO projections.lockout_policies2 (creation_date, change_date, sequence, id, state, max_password_attempts, show_failure, is_default, resource_owner, instance_id) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10)",
expectedStmt: "INSERT INTO projections.lockout_policies3 (creation_date, change_date, sequence, id, state, max_password_attempts, max_otp_attempts, show_failure, is_default, resource_owner, instance_id) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11)",
expectedArgs: []interface{}{
anyArg{},
anyArg{},
@@ -174,6 +179,7 @@ func TestLockoutPolicyProjection_reduces(t *testing.T) {
"agg-id",
domain.PolicyStateActive,
uint64(10),
uint64(10),
true,
true,
"ro-id",
@@ -194,6 +200,7 @@ func TestLockoutPolicyProjection_reduces(t *testing.T) {
instance.AggregateType,
[]byte(`{
"maxPasswordAttempts": 10,
"maxOTPAttempts": 10,
"showLockOutFailures": true
}`),
), instance.LockoutPolicyChangedEventMapper),
@@ -204,11 +211,12 @@ func TestLockoutPolicyProjection_reduces(t *testing.T) {
executer: &testExecuter{
executions: []execution{
{
expectedStmt: "UPDATE projections.lockout_policies2 SET (change_date, sequence, max_password_attempts, show_failure) = ($1, $2, $3, $4) WHERE (id = $5) AND (instance_id = $6)",
expectedStmt: "UPDATE projections.lockout_policies3 SET (change_date, sequence, max_password_attempts, max_otp_attempts, show_failure) = ($1, $2, $3, $4, $5) WHERE (id = $6) AND (instance_id = $7)",
expectedArgs: []interface{}{
anyArg{},
uint64(15),
uint64(10),
uint64(10),
true,
"agg-id",
"instance-id",
@@ -235,7 +243,7 @@ func TestLockoutPolicyProjection_reduces(t *testing.T) {
executer: &testExecuter{
executions: []execution{
{
expectedStmt: "DELETE FROM projections.lockout_policies2 WHERE (instance_id = $1) AND (resource_owner = $2)",
expectedStmt: "DELETE FROM projections.lockout_policies3 WHERE (instance_id = $1) AND (resource_owner = $2)",
expectedArgs: []interface{}{
"instance-id",
"agg-id",