feat: add default redirect uri and handling of unknown usernames (#3616)

* feat: add possibility to ignore username errors on first login screen

* console changes

* fix: handling of unknown usernames (#3445)

* fix: handling of unknown usernames

* fix: handle HideLoginNameSuffix on unknown users

* feat: add default redirect uri on login policy (#3607)

* feat: add default redirect uri on login policy

* fix tests

* feat: Console login policy default redirect (#3613)

* console default redirect

* placeholder

* validate default redirect uri

* allow empty default redirect uri

Co-authored-by: Max Peintner <max@caos.ch>

* remove wonrgly cherry picked migration

Co-authored-by: Max Peintner <max@caos.ch>
This commit is contained in:
Livio Amstutz
2022-05-16 15:39:09 +02:00
committed by GitHub
parent f1fa74a2c0
commit 411d7c6c5c
69 changed files with 655 additions and 107 deletions

View File

@@ -68,7 +68,9 @@ type InstanceSetup struct {
AllowExternalIDP bool
ForceMFA bool
HidePasswordReset bool
IgnoreUnknownUsername bool
PasswordlessType domain.PasswordlessType
DefaultRedirectURI string
PasswordCheckLifetime time.Duration
ExternalLoginCheckLifetime time.Duration
MfaInitSkipLifetime time.Duration
@@ -205,7 +207,9 @@ func (c *Commands) SetUpInstance(ctx context.Context, setup *InstanceSetup) (str
setup.LoginPolicy.AllowExternalIDP,
setup.LoginPolicy.ForceMFA,
setup.LoginPolicy.HidePasswordReset,
setup.LoginPolicy.IgnoreUnknownUsername,
setup.LoginPolicy.PasswordlessType,
setup.LoginPolicy.DefaultRedirectURI,
setup.LoginPolicy.PasswordCheckLifetime,
setup.LoginPolicy.ExternalLoginCheckLifetime,
setup.LoginPolicy.MfaInitSkipLifetime,

View File

@@ -31,8 +31,10 @@ func writeModelToLoginPolicy(wm *LoginPolicyWriteModel) *domain.LoginPolicy {
AllowRegister: wm.AllowRegister,
AllowExternalIDP: wm.AllowExternalIDP,
HidePasswordReset: wm.HidePasswordReset,
IgnoreUnknownUsernames: wm.IgnoreUnknownUsernames,
ForceMFA: wm.ForceMFA,
PasswordlessType: wm.PasswordlessType,
DefaultRedirectURI: wm.DefaultRedirectURI,
PasswordCheckLifetime: wm.PasswordCheckLifetime,
ExternalLoginCheckLifetime: wm.ExternalLoginCheckLifetime,
MFAInitSkipLifetime: wm.MFAInitSkipLifetime,

View File

@@ -17,7 +17,9 @@ func AddDefaultLoginPolicy(
allowExternalIDP bool,
forceMFA bool,
hidePasswordReset bool,
ignoreUnknownUsernames bool,
passwordlessType domain.PasswordlessType,
defaultRedirectURI string,
passwordCheckLifetime time.Duration,
externalLoginCheckLifetime time.Duration,
mfaInitSkipLifetime time.Duration,
@@ -34,7 +36,9 @@ func AddDefaultLoginPolicy(
allowExternalIDP,
forceMFA,
hidePasswordReset,
ignoreUnknownUsernames,
passwordlessType,
defaultRedirectURI,
passwordCheckLifetime,
externalLoginCheckLifetime,
mfaInitSkipLifetime,

View File

@@ -4,6 +4,7 @@ import (
"context"
"github.com/zitadel/logging"
"github.com/zitadel/zitadel/internal/domain"
caos_errs "github.com/zitadel/zitadel/internal/errors"
"github.com/zitadel/zitadel/internal/eventstore"
@@ -56,7 +57,9 @@ func (c *Commands) addDefaultLoginPolicy(ctx context.Context, instanceAgg *event
policy.AllowExternalIDP,
policy.ForceMFA,
policy.HidePasswordReset,
policy.IgnoreUnknownUsernames,
policy.PasswordlessType,
policy.DefaultRedirectURI,
policy.PasswordCheckLifetime,
policy.ExternalLoginCheckLifetime,
policy.MFAInitSkipLifetime,
@@ -83,6 +86,9 @@ func (c *Commands) ChangeDefaultLoginPolicy(ctx context.Context, policy *domain.
}
func (c *Commands) changeDefaultLoginPolicy(ctx context.Context, instanceAgg *eventstore.Aggregate, existingPolicy *InstanceLoginPolicyWriteModel, policy *domain.LoginPolicy) (eventstore.Command, error) {
if ok := domain.ValidateDefaultRedirectURI(policy.DefaultRedirectURI); !ok {
return nil, caos_errs.ThrowInvalidArgument(nil, "IAM-SFdqd", "Errors.IAM.LoginPolicy.RedirectURIInvalid")
}
err := c.defaultLoginPolicyWriteModelByID(ctx, existingPolicy)
if err != nil {
return nil, err
@@ -97,12 +103,15 @@ func (c *Commands) changeDefaultLoginPolicy(ctx context.Context, instanceAgg *ev
policy.AllowExternalIDP,
policy.ForceMFA,
policy.HidePasswordReset,
policy.IgnoreUnknownUsernames,
policy.PasswordlessType,
policy.DefaultRedirectURI,
policy.PasswordCheckLifetime,
policy.ExternalLoginCheckLifetime,
policy.MFAInitSkipLifetime,
policy.SecondFactorCheckLifetime,
policy.MultiFactorCheckLifetime)
policy.MultiFactorCheckLifetime,
)
if !hasChanged {
return nil, caos_errs.ThrowPreconditionFailed(nil, "INSTANCE-5M9vdd", "Errors.IAM.LoginPolicy.NotChanged")
}

View File

@@ -65,8 +65,10 @@ func (wm *InstanceLoginPolicyWriteModel) NewChangedEvent(
allowRegister,
allowExternalIDP,
forceMFA,
hidePasswordReset bool,
hidePasswordReset,
ignoreUnknownUsernames bool,
passwordlessType domain.PasswordlessType,
defaultRedirectURI string,
passwordCheckLifetime,
externalLoginCheckLifetime,
mfaInitSkipLifetime,
@@ -93,6 +95,12 @@ func (wm *InstanceLoginPolicyWriteModel) NewChangedEvent(
if wm.HidePasswordReset != hidePasswordReset {
changes = append(changes, policy.ChangeHidePasswordReset(hidePasswordReset))
}
if wm.IgnoreUnknownUsernames != ignoreUnknownUsernames {
changes = append(changes, policy.ChangeIgnoreUnknownUsernames(ignoreUnknownUsernames))
}
if wm.DefaultRedirectURI != defaultRedirectURI {
changes = append(changes, policy.ChangeDefaultRedirectURI(defaultRedirectURI))
}
if wm.PasswordCheckLifetime != passwordCheckLifetime {
changes = append(changes, policy.ChangePasswordCheckLifetime(passwordCheckLifetime))
}

View File

@@ -50,7 +50,9 @@ func TestCommandSide_AddDefaultLoginPolicy(t *testing.T) {
false,
false,
false,
false,
domain.PasswordlessTypeAllowed,
"",
time.Hour*1,
time.Hour*1,
time.Hour*1,
@@ -90,7 +92,9 @@ func TestCommandSide_AddDefaultLoginPolicy(t *testing.T) {
true,
true,
true,
true,
domain.PasswordlessTypeAllowed,
"https://example.com/redirect",
time.Hour*1,
time.Hour*2,
time.Hour*3,
@@ -110,7 +114,9 @@ func TestCommandSide_AddDefaultLoginPolicy(t *testing.T) {
AllowExternalIDP: true,
ForceMFA: true,
HidePasswordReset: true,
IgnoreUnknownUsernames: true,
PasswordlessType: domain.PasswordlessTypeAllowed,
DefaultRedirectURI: "https://example.com/redirect",
PasswordCheckLifetime: time.Hour * 1,
ExternalLoginCheckLifetime: time.Hour * 2,
MFAInitSkipLifetime: time.Hour * 3,
@@ -130,7 +136,9 @@ func TestCommandSide_AddDefaultLoginPolicy(t *testing.T) {
AllowExternalIDP: true,
ForceMFA: true,
HidePasswordReset: true,
IgnoreUnknownUsernames: true,
PasswordlessType: domain.PasswordlessTypeAllowed,
DefaultRedirectURI: "https://example.com/redirect",
PasswordCheckLifetime: time.Hour * 1,
ExternalLoginCheckLifetime: time.Hour * 2,
MFAInitSkipLifetime: time.Hour * 3,
@@ -210,7 +218,9 @@ func TestCommandSide_ChangeDefaultLoginPolicy(t *testing.T) {
true,
true,
true,
true,
domain.PasswordlessTypeAllowed,
"https://example.com/redirect",
time.Hour*1,
time.Hour*2,
time.Hour*3,
@@ -229,7 +239,9 @@ func TestCommandSide_ChangeDefaultLoginPolicy(t *testing.T) {
AllowExternalIDP: true,
ForceMFA: true,
HidePasswordReset: true,
IgnoreUnknownUsernames: true,
PasswordlessType: domain.PasswordlessTypeAllowed,
DefaultRedirectURI: "https://example.com/redirect",
PasswordCheckLifetime: time.Hour * 1,
ExternalLoginCheckLifetime: time.Hour * 2,
MFAInitSkipLifetime: time.Hour * 3,
@@ -256,7 +268,9 @@ func TestCommandSide_ChangeDefaultLoginPolicy(t *testing.T) {
true,
true,
true,
true,
domain.PasswordlessTypeAllowed,
"https://example.com/redirect",
time.Hour*1,
time.Hour*2,
time.Hour*3,
@@ -275,7 +289,9 @@ func TestCommandSide_ChangeDefaultLoginPolicy(t *testing.T) {
false,
false,
false,
false,
domain.PasswordlessTypeNotAllowed,
"",
time.Hour*10,
time.Hour*20,
time.Hour*30,
@@ -294,7 +310,9 @@ func TestCommandSide_ChangeDefaultLoginPolicy(t *testing.T) {
AllowExternalIDP: false,
ForceMFA: false,
HidePasswordReset: false,
IgnoreUnknownUsernames: false,
PasswordlessType: domain.PasswordlessTypeNotAllowed,
DefaultRedirectURI: "",
PasswordCheckLifetime: time.Hour * 10,
ExternalLoginCheckLifetime: time.Hour * 20,
MFAInitSkipLifetime: time.Hour * 30,
@@ -314,7 +332,9 @@ func TestCommandSide_ChangeDefaultLoginPolicy(t *testing.T) {
AllowExternalIDP: false,
ForceMFA: false,
HidePasswordReset: false,
IgnoreUnknownUsernames: false,
PasswordlessType: domain.PasswordlessTypeNotAllowed,
DefaultRedirectURI: "",
PasswordCheckLifetime: time.Hour * 10,
ExternalLoginCheckLifetime: time.Hour * 20,
MFAInitSkipLifetime: time.Hour * 30,
@@ -408,7 +428,9 @@ func TestCommandSide_AddIDPProviderDefaultLoginPolicy(t *testing.T) {
true,
true,
true,
true,
domain.PasswordlessTypeAllowed,
"",
time.Hour*1,
time.Hour*2,
time.Hour*3,
@@ -444,7 +466,9 @@ func TestCommandSide_AddIDPProviderDefaultLoginPolicy(t *testing.T) {
true,
true,
true,
true,
domain.PasswordlessTypeAllowed,
"",
time.Hour*1,
time.Hour*2,
time.Hour*3,
@@ -500,7 +524,9 @@ func TestCommandSide_AddIDPProviderDefaultLoginPolicy(t *testing.T) {
true,
true,
true,
true,
domain.PasswordlessTypeAllowed,
"",
time.Hour*1,
time.Hour*2,
time.Hour*3,
@@ -638,7 +664,9 @@ func TestCommandSide_RemoveIDPProviderDefaultLoginPolicy(t *testing.T) {
true,
true,
true,
true,
domain.PasswordlessTypeAllowed,
"",
time.Hour*1,
time.Hour*2,
time.Hour*3,
@@ -674,7 +702,9 @@ func TestCommandSide_RemoveIDPProviderDefaultLoginPolicy(t *testing.T) {
true,
true,
true,
true,
domain.PasswordlessTypeAllowed,
"",
time.Hour*1,
time.Hour*2,
time.Hour*3,
@@ -723,7 +753,9 @@ func TestCommandSide_RemoveIDPProviderDefaultLoginPolicy(t *testing.T) {
true,
true,
true,
true,
domain.PasswordlessTypeAllowed,
"",
time.Hour*1,
time.Hour*2,
time.Hour*3,
@@ -777,7 +809,9 @@ func TestCommandSide_RemoveIDPProviderDefaultLoginPolicy(t *testing.T) {
true,
true,
true,
true,
domain.PasswordlessTypeAllowed,
"",
time.Hour*1,
time.Hour*2,
time.Hour*3,
@@ -839,7 +873,9 @@ func TestCommandSide_RemoveIDPProviderDefaultLoginPolicy(t *testing.T) {
true,
true,
true,
true,
domain.PasswordlessTypeAllowed,
"",
time.Hour*1,
time.Hour*2,
time.Hour*3,
@@ -1392,8 +1428,9 @@ func TestCommandSide_RemoveMultiFactorDefaultLoginPolicy(t *testing.T) {
}
}
func newDefaultLoginPolicyChangedEvent(ctx context.Context, allowRegister, allowUsernamePassword, allowExternalIDP, forceMFA, hidePasswordReset bool,
func newDefaultLoginPolicyChangedEvent(ctx context.Context, allowRegister, allowUsernamePassword, allowExternalIDP, forceMFA, hidePasswordReset, ignoreUnknownUsernames bool,
passwordlessType domain.PasswordlessType,
redirectURI string,
passwordLifetime, externalLoginLifetime, mfaInitSkipLifetime, secondFactorLifetime, multiFactorLifetime time.Duration) *instance.LoginPolicyChangedEvent {
event, _ := instance.NewLoginPolicyChangedEvent(ctx,
&instance.NewAggregate("INSTANCE").Aggregate,
@@ -1403,7 +1440,9 @@ func newDefaultLoginPolicyChangedEvent(ctx context.Context, allowRegister, allow
policy.ChangeForceMFA(forceMFA),
policy.ChangeAllowUserNamePassword(allowUsernamePassword),
policy.ChangeHidePasswordReset(hidePasswordReset),
policy.ChangeIgnoreUnknownUsernames(ignoreUnknownUsernames),
policy.ChangePasswordlessType(passwordlessType),
policy.ChangeDefaultRedirectURI(redirectURI),
policy.ChangePasswordCheckLifetime(passwordLifetime),
policy.ChangeExternalLoginCheckLifetime(externalLoginLifetime),
policy.ChangeMFAInitSkipLifetime(mfaInitSkipLifetime),

View File

@@ -16,6 +16,9 @@ func (c *Commands) AddLoginPolicy(ctx context.Context, resourceOwner string, pol
if resourceOwner == "" {
return nil, caos_errs.ThrowInvalidArgument(nil, "Org-Fn8ds", "Errors.ResourceOwnerMissing")
}
if ok := domain.ValidateDefaultRedirectURI(policy.DefaultRedirectURI); !ok {
return nil, caos_errs.ThrowInvalidArgument(nil, "Org-WSfdq", "Errors.Org.LoginPolicy.RedirectURIInvalid")
}
addedPolicy := NewOrgLoginPolicyWriteModel(resourceOwner)
err := c.eventstore.FilterToQueryReducer(ctx, addedPolicy)
if err != nil {
@@ -36,7 +39,9 @@ func (c *Commands) AddLoginPolicy(ctx context.Context, resourceOwner string, pol
policy.AllowExternalIDP,
policy.ForceMFA,
policy.HidePasswordReset,
policy.IgnoreUnknownUsernames,
policy.PasswordlessType,
policy.DefaultRedirectURI,
policy.PasswordCheckLifetime,
policy.ExternalLoginCheckLifetime,
policy.MFAInitSkipLifetime,
@@ -76,6 +81,9 @@ func (c *Commands) ChangeLoginPolicy(ctx context.Context, resourceOwner string,
if resourceOwner == "" {
return nil, caos_errs.ThrowInvalidArgument(nil, "Org-Mf9sf", "Errors.ResourceOwnerMissing")
}
if ok := domain.ValidateDefaultRedirectURI(policy.DefaultRedirectURI); !ok {
return nil, caos_errs.ThrowInvalidArgument(nil, "Org-Sfd21", "Errors.Org.LoginPolicy.RedirectURIInvalid")
}
existingPolicy := NewOrgLoginPolicyWriteModel(resourceOwner)
err := c.eventstore.FilterToQueryReducer(ctx, existingPolicy)
if err != nil {
@@ -94,7 +102,9 @@ func (c *Commands) ChangeLoginPolicy(ctx context.Context, resourceOwner string,
policy.AllowExternalIDP,
policy.ForceMFA,
policy.HidePasswordReset,
policy.IgnoreUnknownUsernames,
policy.PasswordlessType,
policy.DefaultRedirectURI,
policy.PasswordCheckLifetime,
policy.ExternalLoginCheckLifetime,
policy.MFAInitSkipLifetime,

View File

@@ -67,8 +67,10 @@ func (wm *OrgLoginPolicyWriteModel) NewChangedEvent(
allowRegister,
allowExternalIDP,
forceMFA,
hidePasswordReset bool,
hidePasswordReset,
ignoreUnknownUsernames bool,
passwordlessType domain.PasswordlessType,
defaultRedirectURI string,
passwordCheckLifetime,
externalLoginCheckLifetime,
mfaInitSkipLifetime,
@@ -92,6 +94,9 @@ func (wm *OrgLoginPolicyWriteModel) NewChangedEvent(
if wm.HidePasswordReset != hidePasswordReset {
changes = append(changes, policy.ChangeHidePasswordReset(hidePasswordReset))
}
if wm.IgnoreUnknownUsernames != ignoreUnknownUsernames {
changes = append(changes, policy.ChangeIgnoreUnknownUsernames(ignoreUnknownUsernames))
}
if wm.PasswordCheckLifetime != passwordCheckLifetime {
changes = append(changes, policy.ChangePasswordCheckLifetime(passwordCheckLifetime))
}
@@ -110,6 +115,9 @@ func (wm *OrgLoginPolicyWriteModel) NewChangedEvent(
if passwordlessType.Valid() && wm.PasswordlessType != passwordlessType {
changes = append(changes, policy.ChangePasswordlessType(passwordlessType))
}
if wm.DefaultRedirectURI != defaultRedirectURI {
changes = append(changes, policy.ChangeDefaultRedirectURI(defaultRedirectURI))
}
if len(changes) == 0 {
return nil, false
}

View File

@@ -77,7 +77,9 @@ func TestCommandSide_AddLoginPolicy(t *testing.T) {
true,
true,
true,
true,
domain.PasswordlessTypeAllowed,
"https://example.com/redirect",
time.Hour*1,
time.Hour*2,
time.Hour*3,
@@ -96,7 +98,9 @@ func TestCommandSide_AddLoginPolicy(t *testing.T) {
AllowUsernamePassword: true,
AllowExternalIDP: true,
ForceMFA: true,
IgnoreUnknownUsernames: true,
PasswordlessType: domain.PasswordlessTypeAllowed,
DefaultRedirectURI: "https://example.com/redirect",
PasswordCheckLifetime: time.Hour * 1,
ExternalLoginCheckLifetime: time.Hour * 2,
MFAInitSkipLifetime: time.Hour * 3,
@@ -124,7 +128,9 @@ func TestCommandSide_AddLoginPolicy(t *testing.T) {
true,
true,
true,
true,
domain.PasswordlessTypeAllowed,
"https://example.com/redirect",
time.Hour*1,
time.Hour*2,
time.Hour*3,
@@ -145,7 +151,9 @@ func TestCommandSide_AddLoginPolicy(t *testing.T) {
AllowExternalIDP: true,
ForceMFA: true,
HidePasswordReset: true,
IgnoreUnknownUsernames: true,
PasswordlessType: domain.PasswordlessTypeAllowed,
DefaultRedirectURI: "https://example.com/redirect",
PasswordCheckLifetime: time.Hour * 1,
ExternalLoginCheckLifetime: time.Hour * 2,
MFAInitSkipLifetime: time.Hour * 3,
@@ -164,7 +172,9 @@ func TestCommandSide_AddLoginPolicy(t *testing.T) {
AllowExternalIDP: true,
ForceMFA: true,
HidePasswordReset: true,
IgnoreUnknownUsernames: true,
PasswordlessType: domain.PasswordlessTypeAllowed,
DefaultRedirectURI: "https://example.com/redirect",
PasswordCheckLifetime: time.Hour * 1,
ExternalLoginCheckLifetime: time.Hour * 2,
MFAInitSkipLifetime: time.Hour * 3,
@@ -222,11 +232,13 @@ func TestCommandSide_ChangeLoginPolicy(t *testing.T) {
args: args{
ctx: context.Background(),
policy: &domain.LoginPolicy{
AllowRegister: true,
AllowUsernamePassword: true,
AllowExternalIDP: true,
ForceMFA: true,
PasswordlessType: domain.PasswordlessTypeAllowed,
AllowRegister: true,
AllowUsernamePassword: true,
AllowExternalIDP: true,
ForceMFA: true,
IgnoreUnknownUsernames: true,
PasswordlessType: domain.PasswordlessTypeAllowed,
DefaultRedirectURI: "https://example.com/redirect",
},
},
res: res{
@@ -245,11 +257,13 @@ func TestCommandSide_ChangeLoginPolicy(t *testing.T) {
ctx: context.Background(),
orgID: "org1",
policy: &domain.LoginPolicy{
AllowRegister: true,
AllowUsernamePassword: true,
AllowExternalIDP: true,
ForceMFA: true,
PasswordlessType: domain.PasswordlessTypeAllowed,
AllowRegister: true,
AllowUsernamePassword: true,
AllowExternalIDP: true,
ForceMFA: true,
IgnoreUnknownUsernames: true,
PasswordlessType: domain.PasswordlessTypeAllowed,
DefaultRedirectURI: "https://example.com/redirect",
},
},
res: res{
@@ -270,7 +284,9 @@ func TestCommandSide_ChangeLoginPolicy(t *testing.T) {
true,
true,
true,
true,
domain.PasswordlessTypeAllowed,
"https://example.com/redirect",
time.Hour*1,
time.Hour*2,
time.Hour*3,
@@ -290,7 +306,9 @@ func TestCommandSide_ChangeLoginPolicy(t *testing.T) {
AllowExternalIDP: true,
ForceMFA: true,
HidePasswordReset: true,
IgnoreUnknownUsernames: true,
PasswordlessType: domain.PasswordlessTypeAllowed,
DefaultRedirectURI: "https://example.com/redirect",
PasswordCheckLifetime: time.Hour * 1,
ExternalLoginCheckLifetime: time.Hour * 2,
MFAInitSkipLifetime: time.Hour * 3,
@@ -316,7 +334,9 @@ func TestCommandSide_ChangeLoginPolicy(t *testing.T) {
true,
true,
true,
true,
domain.PasswordlessTypeAllowed,
"https://example.com/redirect",
time.Hour*1,
time.Hour*2,
time.Hour*3,
@@ -335,7 +355,9 @@ func TestCommandSide_ChangeLoginPolicy(t *testing.T) {
false,
false,
false,
false,
domain.PasswordlessTypeNotAllowed,
"",
&duration10,
&duration20,
&duration30,
@@ -355,7 +377,9 @@ func TestCommandSide_ChangeLoginPolicy(t *testing.T) {
AllowUsernamePassword: false,
AllowExternalIDP: false,
ForceMFA: false,
IgnoreUnknownUsernames: false,
PasswordlessType: domain.PasswordlessTypeNotAllowed,
DefaultRedirectURI: "",
PasswordCheckLifetime: time.Hour * 10,
ExternalLoginCheckLifetime: time.Hour * 20,
MFAInitSkipLifetime: time.Hour * 30,
@@ -374,7 +398,9 @@ func TestCommandSide_ChangeLoginPolicy(t *testing.T) {
AllowExternalIDP: false,
ForceMFA: false,
HidePasswordReset: false,
IgnoreUnknownUsernames: false,
PasswordlessType: domain.PasswordlessTypeNotAllowed,
DefaultRedirectURI: "",
PasswordCheckLifetime: time.Hour * 10,
ExternalLoginCheckLifetime: time.Hour * 20,
MFAInitSkipLifetime: time.Hour * 30,
@@ -465,7 +491,9 @@ func TestCommandSide_RemoveLoginPolicy(t *testing.T) {
true,
true,
true,
true,
domain.PasswordlessTypeAllowed,
"",
time.Hour*1,
time.Hour*2,
time.Hour*3,
@@ -603,7 +631,9 @@ func TestCommandSide_AddIDPProviderLoginPolicy(t *testing.T) {
true,
true,
true,
true,
domain.PasswordlessTypeAllowed,
"",
time.Hour*1,
time.Hour*2,
time.Hour*3,
@@ -642,7 +672,9 @@ func TestCommandSide_AddIDPProviderLoginPolicy(t *testing.T) {
true,
true,
true,
true,
domain.PasswordlessTypeAllowed,
"",
time.Hour*1,
time.Hour*2,
time.Hour*3,
@@ -701,7 +733,9 @@ func TestCommandSide_AddIDPProviderLoginPolicy(t *testing.T) {
true,
true,
true,
true,
domain.PasswordlessTypeAllowed,
"",
time.Hour*1,
time.Hour*2,
time.Hour*3,
@@ -863,7 +897,9 @@ func TestCommandSide_RemoveIDPProviderLoginPolicy(t *testing.T) {
true,
true,
true,
true,
domain.PasswordlessTypeAllowed,
"",
time.Hour*1,
time.Hour*2,
time.Hour*3,
@@ -902,7 +938,9 @@ func TestCommandSide_RemoveIDPProviderLoginPolicy(t *testing.T) {
true,
true,
true,
true,
domain.PasswordlessTypeAllowed,
"",
time.Hour*1,
time.Hour*2,
time.Hour*3,
@@ -953,7 +991,9 @@ func TestCommandSide_RemoveIDPProviderLoginPolicy(t *testing.T) {
true,
true,
true,
true,
domain.PasswordlessTypeAllowed,
"",
time.Hour*1,
time.Hour*2,
time.Hour*3,
@@ -1011,7 +1051,9 @@ func TestCommandSide_RemoveIDPProviderLoginPolicy(t *testing.T) {
true,
true,
true,
true,
domain.PasswordlessTypeAllowed,
"",
time.Hour*1,
time.Hour*2,
time.Hour*3,
@@ -1077,7 +1119,9 @@ func TestCommandSide_RemoveIDPProviderLoginPolicy(t *testing.T) {
true,
true,
true,
true,
domain.PasswordlessTypeAllowed,
"",
time.Hour*1,
time.Hour*2,
time.Hour*3,
@@ -1694,8 +1738,9 @@ func TestCommandSide_RemoveMultiFactorLoginPolicy(t *testing.T) {
}
}
func newLoginPolicyChangedEvent(ctx context.Context, orgID string, usernamePassword, register, externalIDP, mfa, passwordReset bool,
func newLoginPolicyChangedEvent(ctx context.Context, orgID string, usernamePassword, register, externalIDP, mfa, passwordReset, ignoreUnknownUsernames bool,
passwordlessType domain.PasswordlessType,
redirectURI string,
passwordLifetime, externalLoginLifetime, mfaInitSkipLifetime, secondFactorLifetime, multiFactorLifetime *time.Duration) *org.LoginPolicyChangedEvent {
changes := []policy.LoginPolicyChanges{
policy.ChangeAllowUserNamePassword(usernamePassword),
@@ -1703,7 +1748,9 @@ func newLoginPolicyChangedEvent(ctx context.Context, orgID string, usernamePassw
policy.ChangeAllowExternalIDP(externalIDP),
policy.ChangeForceMFA(mfa),
policy.ChangeHidePasswordReset(passwordReset),
policy.ChangeIgnoreUnknownUsernames(ignoreUnknownUsernames),
policy.ChangePasswordlessType(passwordlessType),
policy.ChangeDefaultRedirectURI(redirectURI),
}
if passwordLifetime != nil {
changes = append(changes, policy.ChangePasswordCheckLifetime(*passwordLifetime))

View File

@@ -16,7 +16,9 @@ type LoginPolicyWriteModel struct {
AllowExternalIDP bool
ForceMFA bool
HidePasswordReset bool
IgnoreUnknownUsernames bool
PasswordlessType domain.PasswordlessType
DefaultRedirectURI string
PasswordCheckLifetime time.Duration
ExternalLoginCheckLifetime time.Duration
MFAInitSkipLifetime time.Duration
@@ -35,6 +37,8 @@ func (wm *LoginPolicyWriteModel) Reduce() error {
wm.ForceMFA = e.ForceMFA
wm.PasswordlessType = e.PasswordlessType
wm.HidePasswordReset = e.HidePasswordReset
wm.IgnoreUnknownUsernames = e.IgnoreUnknownUsernames
wm.DefaultRedirectURI = e.DefaultRedirectURI
wm.PasswordCheckLifetime = e.PasswordCheckLifetime
wm.ExternalLoginCheckLifetime = e.ExternalLoginCheckLifetime
wm.MFAInitSkipLifetime = e.MFAInitSkipLifetime
@@ -57,9 +61,15 @@ func (wm *LoginPolicyWriteModel) Reduce() error {
if e.HidePasswordReset != nil {
wm.HidePasswordReset = *e.HidePasswordReset
}
if e.IgnoreUnknownUsernames != nil {
wm.IgnoreUnknownUsernames = *e.IgnoreUnknownUsernames
}
if e.PasswordlessType != nil {
wm.PasswordlessType = *e.PasswordlessType
}
if e.DefaultRedirectURI != nil {
wm.DefaultRedirectURI = *e.DefaultRedirectURI
}
if e.PasswordCheckLifetime != nil {
wm.PasswordCheckLifetime = *e.PasswordCheckLifetime
}

View File

@@ -1156,7 +1156,9 @@ func TestCommandSide_CheckPassword(t *testing.T) {
false,
false,
false,
false,
domain.PasswordlessTypeNotAllowed,
"",
time.Hour*1,
time.Hour*2,
time.Hour*3,
@@ -1191,7 +1193,9 @@ func TestCommandSide_CheckPassword(t *testing.T) {
false,
false,
false,
false,
domain.PasswordlessTypeNotAllowed,
"",
time.Hour*1,
time.Hour*2,
time.Hour*3,
@@ -1227,7 +1231,9 @@ func TestCommandSide_CheckPassword(t *testing.T) {
false,
false,
false,
false,
domain.PasswordlessTypeNotAllowed,
"",
time.Hour*1,
time.Hour*2,
time.Hour*3,
@@ -1279,7 +1285,9 @@ func TestCommandSide_CheckPassword(t *testing.T) {
false,
false,
false,
false,
domain.PasswordlessTypeNotAllowed,
"",
time.Hour*1,
time.Hour*2,
time.Hour*3,
@@ -1365,7 +1373,9 @@ func TestCommandSide_CheckPassword(t *testing.T) {
false,
false,
false,
false,
domain.PasswordlessTypeNotAllowed,
"",
time.Hour*1,
time.Hour*2,
time.Hour*3,
@@ -1458,7 +1468,9 @@ func TestCommandSide_CheckPassword(t *testing.T) {
false,
false,
false,
false,
domain.PasswordlessTypeNotAllowed,
"",
time.Hour*1,
time.Hour*2,
time.Hour*3,

View File

@@ -1687,7 +1687,9 @@ func TestCommandSide_RegisterHuman(t *testing.T) {
false,
false,
false,
false,
domain.PasswordlessTypeNotAllowed,
"",
time.Hour*1,
time.Hour*2,
time.Hour*3,
@@ -1750,7 +1752,9 @@ func TestCommandSide_RegisterHuman(t *testing.T) {
false,
false,
false,
false,
domain.PasswordlessTypeNotAllowed,
"",
time.Hour*1,
time.Hour*2,
time.Hour*3,
@@ -1813,7 +1817,9 @@ func TestCommandSide_RegisterHuman(t *testing.T) {
false,
false,
false,
false,
domain.PasswordlessTypeNotAllowed,
"",
time.Hour*1,
time.Hour*2,
time.Hour*3,
@@ -1893,7 +1899,9 @@ func TestCommandSide_RegisterHuman(t *testing.T) {
false,
false,
false,
false,
domain.PasswordlessTypeNotAllowed,
"",
time.Hour*1,
time.Hour*2,
time.Hour*3,
@@ -2031,7 +2039,9 @@ func TestCommandSide_RegisterHuman(t *testing.T) {
false,
false,
false,
false,
domain.PasswordlessTypeNotAllowed,
"",
time.Hour*1,
time.Hour*2,
time.Hour*3,
@@ -2137,7 +2147,9 @@ func TestCommandSide_RegisterHuman(t *testing.T) {
false,
false,
false,
false,
domain.PasswordlessTypeNotAllowed,
"",
time.Hour*1,
time.Hour*2,
time.Hour*3,
@@ -2237,7 +2249,9 @@ func TestCommandSide_RegisterHuman(t *testing.T) {
false,
false,
false,
false,
domain.PasswordlessTypeNotAllowed,
"",
time.Hour*1,
time.Hour*2,
time.Hour*3,
@@ -2359,7 +2373,9 @@ func TestCommandSide_RegisterHuman(t *testing.T) {
false,
false,
false,
false,
domain.PasswordlessTypeNotAllowed,
"",
time.Hour*1,
time.Hour*2,
time.Hour*3,