mirror of
https://github.com/zitadel/zitadel.git
synced 2025-08-12 04:07:31 +00:00
feat: mfa policy (#913)
* feat: add mfa to login policy * feat: add mfa to login policy * feat: add mfa to login policy * feat: add mfa to login policy * feat: add mfa to login policy on org * feat: add mfa to login policy on org * feat: append events on policy views * feat: iam login policy mfa definition * feat: login policies on orgs * feat: configured mfas in login process * feat: configured mfas in login process * Update internal/ui/login/static/i18n/en.yaml Co-authored-by: Livio Amstutz <livio.a@gmail.com> * fix: rename software and hardware mfas * fix: pr requests * fix user mfa * fix: test * fix: oidc version * fix: oidc version * fix: proto gen Co-authored-by: Livio Amstutz <livio.a@gmail.com> Co-authored-by: Max Peintner <max@caos.ch>
This commit is contained in:
@@ -44,6 +44,57 @@ func (o *Org) appendRemoveIdpProviderFromLoginPolicyEvent(event *es_models.Event
|
||||
o.LoginPolicy.IDPProviders[i] = o.LoginPolicy.IDPProviders[len(o.LoginPolicy.IDPProviders)-1]
|
||||
o.LoginPolicy.IDPProviders[len(o.LoginPolicy.IDPProviders)-1] = nil
|
||||
o.LoginPolicy.IDPProviders = o.LoginPolicy.IDPProviders[:len(o.LoginPolicy.IDPProviders)-1]
|
||||
return nil
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (o *Org) appendAddSecondFactorToLoginPolicyEvent(event *es_models.Event) error {
|
||||
mfa := &iam_es_model.MFA{}
|
||||
err := mfa.SetData(event)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
o.LoginPolicy.SecondFactors = append(o.LoginPolicy.SecondFactors, mfa.MfaType)
|
||||
return nil
|
||||
}
|
||||
|
||||
func (o *Org) appendRemoveSecondFactorFromLoginPolicyEvent(event *es_models.Event) error {
|
||||
mfa := &iam_es_model.MFA{}
|
||||
err := mfa.SetData(event)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if i, m := iam_es_model.GetMFA(o.LoginPolicy.SecondFactors, mfa.MfaType); m != 0 {
|
||||
o.LoginPolicy.SecondFactors[i] = o.LoginPolicy.SecondFactors[len(o.LoginPolicy.SecondFactors)-1]
|
||||
o.LoginPolicy.SecondFactors[len(o.LoginPolicy.SecondFactors)-1] = 0
|
||||
o.LoginPolicy.SecondFactors = o.LoginPolicy.SecondFactors[:len(o.LoginPolicy.SecondFactors)-1]
|
||||
return nil
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (o *Org) appendAddMultiFactorToLoginPolicyEvent(event *es_models.Event) error {
|
||||
mfa := &iam_es_model.MFA{}
|
||||
err := mfa.SetData(event)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
o.LoginPolicy.MultiFactors = append(o.LoginPolicy.MultiFactors, mfa.MfaType)
|
||||
return nil
|
||||
}
|
||||
|
||||
func (o *Org) appendRemoveMultiFactorFromLoginPolicyEvent(event *es_models.Event) error {
|
||||
mfa := &iam_es_model.MFA{}
|
||||
err := mfa.SetData(event)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if i, m := iam_es_model.GetMFA(o.LoginPolicy.MultiFactors, mfa.MfaType); m != 0 {
|
||||
o.LoginPolicy.MultiFactors[i] = o.LoginPolicy.MultiFactors[len(o.LoginPolicy.MultiFactors)-1]
|
||||
o.LoginPolicy.MultiFactors[len(o.LoginPolicy.MultiFactors)-1] = 0
|
||||
o.LoginPolicy.MultiFactors = o.LoginPolicy.MultiFactors[:len(o.LoginPolicy.MultiFactors)-1]
|
||||
return nil
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
@@ -208,3 +208,183 @@ func TestRemoveAddIdpToPolicyEvent(t *testing.T) {
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestAppendAddSecondFactorToPolicyEvent(t *testing.T) {
|
||||
type args struct {
|
||||
org *Org
|
||||
mfa *iam_es_model.MFA
|
||||
event *es_models.Event
|
||||
}
|
||||
tests := []struct {
|
||||
name string
|
||||
args args
|
||||
result *Org
|
||||
}{
|
||||
{
|
||||
name: "append add second factor to login policy event",
|
||||
args: args{
|
||||
org: &Org{LoginPolicy: &iam_es_model.LoginPolicy{AllowExternalIdp: true, AllowRegister: true, AllowUsernamePassword: true}},
|
||||
mfa: &iam_es_model.MFA{MfaType: int32(iam_model.SecondFactorTypeOTP)},
|
||||
event: &es_models.Event{},
|
||||
},
|
||||
result: &Org{LoginPolicy: &iam_es_model.LoginPolicy{
|
||||
AllowExternalIdp: true,
|
||||
AllowRegister: true,
|
||||
AllowUsernamePassword: true,
|
||||
SecondFactors: []int32{
|
||||
int32(iam_model.SecondFactorTypeOTP),
|
||||
}}},
|
||||
},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
if tt.args.mfa != nil {
|
||||
data, _ := json.Marshal(tt.args.mfa)
|
||||
tt.args.event.Data = data
|
||||
}
|
||||
tt.args.org.appendAddSecondFactorToLoginPolicyEvent(tt.args.event)
|
||||
if len(tt.result.LoginPolicy.SecondFactors) != len(tt.args.org.LoginPolicy.SecondFactors) {
|
||||
t.Errorf("got wrong second factor len: expected: %v, actual: %v ", len(tt.result.LoginPolicy.SecondFactors), len(tt.args.org.LoginPolicy.SecondFactors))
|
||||
}
|
||||
if tt.result.LoginPolicy.SecondFactors[0] != tt.args.mfa.MfaType {
|
||||
t.Errorf("got wrong second factor: expected: %v, actual: %v ", tt.result.LoginPolicy.SecondFactors[0], tt.args.mfa)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestRemoveSecondFactorFromPolicyEvent(t *testing.T) {
|
||||
type args struct {
|
||||
org *Org
|
||||
mfa *iam_es_model.MFA
|
||||
event *es_models.Event
|
||||
}
|
||||
tests := []struct {
|
||||
name string
|
||||
args args
|
||||
result *Org
|
||||
}{
|
||||
{
|
||||
name: "append remove second factor from login policy event",
|
||||
args: args{
|
||||
org: &Org{
|
||||
LoginPolicy: &iam_es_model.LoginPolicy{
|
||||
AllowExternalIdp: true,
|
||||
AllowRegister: true,
|
||||
AllowUsernamePassword: true,
|
||||
SecondFactors: []int32{
|
||||
int32(iam_model.SecondFactorTypeOTP),
|
||||
}}},
|
||||
mfa: &iam_es_model.MFA{MfaType: int32(iam_model.SecondFactorTypeOTP)},
|
||||
event: &es_models.Event{},
|
||||
},
|
||||
result: &Org{LoginPolicy: &iam_es_model.LoginPolicy{
|
||||
AllowExternalIdp: true,
|
||||
AllowRegister: true,
|
||||
AllowUsernamePassword: true,
|
||||
SecondFactors: []int32{}}},
|
||||
},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
if tt.args.mfa != nil {
|
||||
data, _ := json.Marshal(tt.args.mfa)
|
||||
tt.args.event.Data = data
|
||||
}
|
||||
tt.args.org.appendRemoveSecondFactorFromLoginPolicyEvent(tt.args.event)
|
||||
if len(tt.result.LoginPolicy.SecondFactors) != len(tt.args.org.LoginPolicy.SecondFactors) {
|
||||
t.Errorf("got wrong idp mfa len: expected: %v, actual: %v ", len(tt.result.LoginPolicy.SecondFactors), len(tt.args.org.LoginPolicy.SecondFactors))
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestAppendAddMultiFactorToPolicyEvent(t *testing.T) {
|
||||
type args struct {
|
||||
org *Org
|
||||
mfa *iam_es_model.MFA
|
||||
event *es_models.Event
|
||||
}
|
||||
tests := []struct {
|
||||
name string
|
||||
args args
|
||||
result *Org
|
||||
}{
|
||||
{
|
||||
name: "append add mfa to login policy event",
|
||||
args: args{
|
||||
org: &Org{LoginPolicy: &iam_es_model.LoginPolicy{AllowExternalIdp: true, AllowRegister: true, AllowUsernamePassword: true}},
|
||||
mfa: &iam_es_model.MFA{MfaType: int32(iam_model.MultiFactorTypeU2FWithPIN)},
|
||||
event: &es_models.Event{},
|
||||
},
|
||||
result: &Org{LoginPolicy: &iam_es_model.LoginPolicy{
|
||||
AllowExternalIdp: true,
|
||||
AllowRegister: true,
|
||||
AllowUsernamePassword: true,
|
||||
MultiFactors: []int32{
|
||||
int32(iam_model.MultiFactorTypeU2FWithPIN),
|
||||
}}},
|
||||
},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
if tt.args.mfa != nil {
|
||||
data, _ := json.Marshal(tt.args.mfa)
|
||||
tt.args.event.Data = data
|
||||
}
|
||||
tt.args.org.appendAddMultiFactorToLoginPolicyEvent(tt.args.event)
|
||||
if len(tt.result.LoginPolicy.MultiFactors) != len(tt.args.org.LoginPolicy.MultiFactors) {
|
||||
t.Errorf("got wrong second factor len: expected: %v, actual: %v ", len(tt.result.LoginPolicy.MultiFactors), len(tt.args.org.LoginPolicy.MultiFactors))
|
||||
}
|
||||
if tt.result.LoginPolicy.MultiFactors[0] != tt.args.mfa.MfaType {
|
||||
t.Errorf("got wrong second factor: expected: %v, actual: %v ", tt.result.LoginPolicy.MultiFactors[0], tt.args.mfa)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestRemoveMultiFactorFromPolicyEvent(t *testing.T) {
|
||||
type args struct {
|
||||
org *Org
|
||||
mfa *iam_es_model.MFA
|
||||
event *es_models.Event
|
||||
}
|
||||
tests := []struct {
|
||||
name string
|
||||
args args
|
||||
result *Org
|
||||
}{
|
||||
{
|
||||
name: "append remove mfa from login policy event",
|
||||
args: args{
|
||||
org: &Org{
|
||||
LoginPolicy: &iam_es_model.LoginPolicy{
|
||||
AllowExternalIdp: true,
|
||||
AllowRegister: true,
|
||||
AllowUsernamePassword: true,
|
||||
MultiFactors: []int32{
|
||||
int32(iam_model.MultiFactorTypeU2FWithPIN),
|
||||
}}},
|
||||
mfa: &iam_es_model.MFA{MfaType: int32(iam_model.MultiFactorTypeU2FWithPIN)},
|
||||
event: &es_models.Event{},
|
||||
},
|
||||
result: &Org{LoginPolicy: &iam_es_model.LoginPolicy{
|
||||
AllowExternalIdp: true,
|
||||
AllowRegister: true,
|
||||
AllowUsernamePassword: true,
|
||||
MultiFactors: []int32{}}},
|
||||
},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
if tt.args.mfa != nil {
|
||||
data, _ := json.Marshal(tt.args.mfa)
|
||||
tt.args.event.Data = data
|
||||
}
|
||||
tt.args.org.appendRemoveMultiFactorFromLoginPolicyEvent(tt.args.event)
|
||||
if len(tt.result.LoginPolicy.MultiFactors) != len(tt.args.org.LoginPolicy.MultiFactors) {
|
||||
t.Errorf("got wrong idp mfa len: expected: %v, actual: %v ", len(tt.result.LoginPolicy.MultiFactors), len(tt.args.org.LoginPolicy.MultiFactors))
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
@@ -199,6 +199,14 @@ func (o *Org) AppendEvent(event *es_models.Event) (err error) {
|
||||
err = o.appendAddIdpProviderToLoginPolicyEvent(event)
|
||||
case LoginPolicyIDPProviderRemoved:
|
||||
err = o.appendRemoveIdpProviderFromLoginPolicyEvent(event)
|
||||
case LoginPolicySecondFactorAdded:
|
||||
err = o.appendAddSecondFactorToLoginPolicyEvent(event)
|
||||
case LoginPolicySecondFactorRemoved:
|
||||
err = o.appendRemoveSecondFactorFromLoginPolicyEvent(event)
|
||||
case LoginPolicyMultiFactorAdded:
|
||||
err = o.appendAddMultiFactorToLoginPolicyEvent(event)
|
||||
case LoginPolicyMultiFactorRemoved:
|
||||
err = o.appendRemoveMultiFactorFromLoginPolicyEvent(event)
|
||||
case PasswordComplexityPolicyAdded:
|
||||
err = o.appendAddPasswordComplexityPolicyEvent(event)
|
||||
case PasswordComplexityPolicyChanged:
|
||||
|
@@ -51,9 +51,14 @@ const (
|
||||
LoginPolicyIDPProviderAdded models.EventType = "org.policy.login.idpprovider.added"
|
||||
LoginPolicyIDPProviderRemoved models.EventType = "org.policy.login.idpprovider.removed"
|
||||
LoginPolicyIDPProviderCascadeRemoved models.EventType = "org.policy.login.idpprovider.cascade.removed"
|
||||
LabelPolicyAdded models.EventType = "org.policy.label.added"
|
||||
LabelPolicyChanged models.EventType = "org.policy.label.changed"
|
||||
LabelPolicyRemoved models.EventType = "org.policy.label.removed"
|
||||
LoginPolicySecondFactorAdded models.EventType = "org.policy.login.secondfactor.added"
|
||||
LoginPolicySecondFactorRemoved models.EventType = "org.policy.login.secondfactor.removed"
|
||||
LoginPolicyMultiFactorAdded models.EventType = "org.policy.login.multifactor.added"
|
||||
LoginPolicyMultiFactorRemoved models.EventType = "org.policy.login.multifactor.removed"
|
||||
|
||||
LabelPolicyAdded models.EventType = "org.policy.label.added"
|
||||
LabelPolicyChanged models.EventType = "org.policy.label.changed"
|
||||
LabelPolicyRemoved models.EventType = "org.policy.label.removed"
|
||||
|
||||
PasswordComplexityPolicyAdded models.EventType = "org.policy.password.complexity.added"
|
||||
PasswordComplexityPolicyChanged models.EventType = "org.policy.password.complexity.changed"
|
||||
|
Reference in New Issue
Block a user