mirror of
https://github.com/zitadel/zitadel.git
synced 2025-11-16 12:04:50 +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:
@@ -1657,6 +1657,340 @@ func TestRemoveIdpProviderFromLoginPolicy(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestAddSecondFactorToLoginPolicy(t *testing.T) {
|
||||
ctrl := gomock.NewController(t)
|
||||
type args struct {
|
||||
es *IAMEventstore
|
||||
ctx context.Context
|
||||
aggreageID string
|
||||
mfa iam_model.SecondFactorType
|
||||
}
|
||||
type res struct {
|
||||
result iam_model.SecondFactorType
|
||||
wantErr bool
|
||||
errFunc func(err error) bool
|
||||
}
|
||||
tests := []struct {
|
||||
name string
|
||||
args args
|
||||
res res
|
||||
}{
|
||||
{
|
||||
name: "add second factor to login policy, ok",
|
||||
args: args{
|
||||
es: GetMockManipulateIAMWithLoginPolicy(ctrl),
|
||||
ctx: authz.NewMockContext("orgID", "userID"),
|
||||
aggreageID: "AggregateID",
|
||||
mfa: iam_model.SecondFactorTypeOTP,
|
||||
},
|
||||
res: res{
|
||||
result: iam_model.SecondFactorTypeOTP,
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "add second factor to login policy, already existing",
|
||||
args: args{
|
||||
es: GetMockManipulateIAMWithLoginPolicyWithMFAs(ctrl),
|
||||
ctx: authz.NewMockContext("orgID", "userID"),
|
||||
aggreageID: "AggregateID",
|
||||
mfa: iam_model.SecondFactorTypeOTP,
|
||||
},
|
||||
res: res{
|
||||
wantErr: true,
|
||||
errFunc: caos_errs.IsErrorAlreadyExists,
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "invalid mfa",
|
||||
args: args{
|
||||
es: GetMockManipulateIAM(ctrl),
|
||||
ctx: authz.NewMockContext("orgID", "userID"),
|
||||
mfa: iam_model.SecondFactorTypeUnspecified,
|
||||
},
|
||||
res: res{
|
||||
wantErr: true,
|
||||
errFunc: caos_errs.IsPreconditionFailed,
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "existing iam not found",
|
||||
args: args{
|
||||
es: GetMockManipulateIAMNotExisting(ctrl),
|
||||
ctx: authz.NewMockContext("orgID", "userID"),
|
||||
aggreageID: "Test",
|
||||
mfa: iam_model.SecondFactorTypeOTP,
|
||||
},
|
||||
res: res{
|
||||
wantErr: true,
|
||||
errFunc: caos_errs.IsNotFound,
|
||||
},
|
||||
},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
result, err := tt.args.es.AddSecondFactorToLoginPolicy(tt.args.ctx, tt.args.aggreageID, tt.args.mfa)
|
||||
if (tt.res.wantErr && !tt.res.errFunc(err)) || (err != nil && !tt.res.wantErr) {
|
||||
t.Errorf("got wrong err: %v ", err)
|
||||
return
|
||||
}
|
||||
if tt.res.wantErr && tt.res.errFunc(err) {
|
||||
return
|
||||
}
|
||||
if result != tt.res.result {
|
||||
t.Errorf("got wrong result: expected: %v, actual: %v ", tt.res.result, result)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestRemoveSecondFactorFromLoginPolicy(t *testing.T) {
|
||||
ctrl := gomock.NewController(t)
|
||||
type args struct {
|
||||
es *IAMEventstore
|
||||
ctx context.Context
|
||||
aggregateID string
|
||||
mfa iam_model.SecondFactorType
|
||||
}
|
||||
type res struct {
|
||||
wantErr bool
|
||||
errFunc func(err error) bool
|
||||
}
|
||||
tests := []struct {
|
||||
name string
|
||||
args args
|
||||
res res
|
||||
}{
|
||||
{
|
||||
name: "remove second factor from login policy, ok",
|
||||
args: args{
|
||||
es: GetMockManipulateIAMWithLoginPolicyWithMFAs(ctrl),
|
||||
ctx: authz.NewMockContext("orgID", "userID"),
|
||||
aggregateID: "AggregateID",
|
||||
mfa: iam_model.SecondFactorTypeOTP,
|
||||
},
|
||||
res: res{},
|
||||
},
|
||||
{
|
||||
name: "remove second factor to login policy, not existing",
|
||||
args: args{
|
||||
es: GetMockManipulateIAMWithLoginPolicy(ctrl),
|
||||
ctx: authz.NewMockContext("orgID", "userID"),
|
||||
aggregateID: "AggregateID",
|
||||
mfa: iam_model.SecondFactorTypeOTP,
|
||||
},
|
||||
res: res{
|
||||
wantErr: true,
|
||||
errFunc: caos_errs.IsPreconditionFailed,
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "invalid provider",
|
||||
args: args{
|
||||
es: GetMockManipulateIAM(ctrl),
|
||||
ctx: authz.NewMockContext("orgID", "userID"),
|
||||
aggregateID: "AggregateID",
|
||||
mfa: iam_model.SecondFactorTypeUnspecified,
|
||||
},
|
||||
res: res{
|
||||
wantErr: true,
|
||||
errFunc: caos_errs.IsPreconditionFailed,
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "existing iam not found",
|
||||
args: args{
|
||||
es: GetMockManipulateIAMNotExisting(ctrl),
|
||||
ctx: authz.NewMockContext("orgID", "userID"),
|
||||
aggregateID: "Test",
|
||||
mfa: iam_model.SecondFactorTypeOTP,
|
||||
},
|
||||
res: res{
|
||||
wantErr: true,
|
||||
errFunc: caos_errs.IsNotFound,
|
||||
},
|
||||
},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
err := tt.args.es.RemoveSecondFactorFromLoginPolicy(tt.args.ctx, tt.args.aggregateID, tt.args.mfa)
|
||||
|
||||
if !tt.res.wantErr && err != nil {
|
||||
t.Errorf("should not get err: %v ", err)
|
||||
}
|
||||
if tt.res.wantErr && !tt.res.errFunc(err) {
|
||||
t.Errorf("got wrong err: %v ", err)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestAddMultiFactorToLoginPolicy(t *testing.T) {
|
||||
ctrl := gomock.NewController(t)
|
||||
type args struct {
|
||||
es *IAMEventstore
|
||||
ctx context.Context
|
||||
aggreageID string
|
||||
mfa iam_model.MultiFactorType
|
||||
}
|
||||
type res struct {
|
||||
result iam_model.MultiFactorType
|
||||
wantErr bool
|
||||
errFunc func(err error) bool
|
||||
}
|
||||
tests := []struct {
|
||||
name string
|
||||
args args
|
||||
res res
|
||||
}{
|
||||
{
|
||||
name: "add second factor to login policy, ok",
|
||||
args: args{
|
||||
es: GetMockManipulateIAMWithLoginPolicy(ctrl),
|
||||
ctx: authz.NewMockContext("orgID", "userID"),
|
||||
aggreageID: "AggregateID",
|
||||
mfa: iam_model.MultiFactorTypeU2FWithPIN,
|
||||
},
|
||||
res: res{
|
||||
result: iam_model.MultiFactorTypeU2FWithPIN,
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "add second factor to login policy, already existing",
|
||||
args: args{
|
||||
es: GetMockManipulateIAMWithLoginPolicyWithMFAs(ctrl),
|
||||
ctx: authz.NewMockContext("orgID", "userID"),
|
||||
aggreageID: "AggregateID",
|
||||
mfa: iam_model.MultiFactorTypeU2FWithPIN,
|
||||
},
|
||||
res: res{
|
||||
wantErr: true,
|
||||
errFunc: caos_errs.IsErrorAlreadyExists,
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "invalid mfa",
|
||||
args: args{
|
||||
es: GetMockManipulateIAM(ctrl),
|
||||
ctx: authz.NewMockContext("orgID", "userID"),
|
||||
mfa: iam_model.MultiFactorTypeUnspecified,
|
||||
},
|
||||
res: res{
|
||||
wantErr: true,
|
||||
errFunc: caos_errs.IsPreconditionFailed,
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "existing iam not found",
|
||||
args: args{
|
||||
es: GetMockManipulateIAMNotExisting(ctrl),
|
||||
ctx: authz.NewMockContext("orgID", "userID"),
|
||||
aggreageID: "Test",
|
||||
mfa: iam_model.MultiFactorTypeU2FWithPIN,
|
||||
},
|
||||
res: res{
|
||||
wantErr: true,
|
||||
errFunc: caos_errs.IsNotFound,
|
||||
},
|
||||
},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
result, err := tt.args.es.AddMultiFactorToLoginPolicy(tt.args.ctx, tt.args.aggreageID, tt.args.mfa)
|
||||
if (tt.res.wantErr && !tt.res.errFunc(err)) || (err != nil && !tt.res.wantErr) {
|
||||
t.Errorf("got wrong err: %v ", err)
|
||||
return
|
||||
}
|
||||
if tt.res.wantErr && tt.res.errFunc(err) {
|
||||
return
|
||||
}
|
||||
if result != tt.res.result {
|
||||
t.Errorf("got wrong result: expected: %v, actual: %v ", tt.res.result, result)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestRemoveMultiFactorFromLoginPolicy(t *testing.T) {
|
||||
ctrl := gomock.NewController(t)
|
||||
type args struct {
|
||||
es *IAMEventstore
|
||||
ctx context.Context
|
||||
aggregateID string
|
||||
mfa iam_model.MultiFactorType
|
||||
}
|
||||
type res struct {
|
||||
wantErr bool
|
||||
errFunc func(err error) bool
|
||||
}
|
||||
tests := []struct {
|
||||
name string
|
||||
args args
|
||||
res res
|
||||
}{
|
||||
{
|
||||
name: "remove second factor from login policy, ok",
|
||||
args: args{
|
||||
es: GetMockManipulateIAMWithLoginPolicyWithMFAs(ctrl),
|
||||
ctx: authz.NewMockContext("orgID", "userID"),
|
||||
aggregateID: "AggregateID",
|
||||
mfa: iam_model.MultiFactorTypeU2FWithPIN,
|
||||
},
|
||||
res: res{},
|
||||
},
|
||||
{
|
||||
name: "remove second factor to login policy, not existing",
|
||||
args: args{
|
||||
es: GetMockManipulateIAMWithLoginPolicy(ctrl),
|
||||
ctx: authz.NewMockContext("orgID", "userID"),
|
||||
aggregateID: "AggregateID",
|
||||
mfa: iam_model.MultiFactorTypeU2FWithPIN,
|
||||
},
|
||||
res: res{
|
||||
wantErr: true,
|
||||
errFunc: caos_errs.IsPreconditionFailed,
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "invalid provider",
|
||||
args: args{
|
||||
es: GetMockManipulateIAM(ctrl),
|
||||
ctx: authz.NewMockContext("orgID", "userID"),
|
||||
aggregateID: "AggregateID",
|
||||
mfa: iam_model.MultiFactorTypeUnspecified,
|
||||
},
|
||||
res: res{
|
||||
wantErr: true,
|
||||
errFunc: caos_errs.IsPreconditionFailed,
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "existing iam not found",
|
||||
args: args{
|
||||
es: GetMockManipulateIAMNotExisting(ctrl),
|
||||
ctx: authz.NewMockContext("orgID", "userID"),
|
||||
aggregateID: "Test",
|
||||
mfa: iam_model.MultiFactorTypeU2FWithPIN,
|
||||
},
|
||||
res: res{
|
||||
wantErr: true,
|
||||
errFunc: caos_errs.IsNotFound,
|
||||
},
|
||||
},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
err := tt.args.es.RemoveMultiFactorFromLoginPolicy(tt.args.ctx, tt.args.aggregateID, tt.args.mfa)
|
||||
|
||||
if !tt.res.wantErr && err != nil {
|
||||
t.Errorf("should not get err: %v ", err)
|
||||
}
|
||||
if tt.res.wantErr && !tt.res.errFunc(err) {
|
||||
t.Errorf("got wrong err: %v ", err)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestAddLabelPolicy(t *testing.T) {
|
||||
ctrl := gomock.NewController(t)
|
||||
type args struct {
|
||||
|
||||
Reference in New Issue
Block a user