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:
Fabi
2020-11-04 11:26:10 +01:00
committed by GitHub
parent 51417be35d
commit 202aae4954
76 changed files with 12913 additions and 5614 deletions

View File

@@ -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
}

View File

@@ -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))
}
})
}
}

View File

@@ -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:

View File

@@ -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"