Livio Amstutz 300ade66a7
feat: add WebAuthN support for passwordless login and 2fa (#966)
* at least registration prompt works

* in memory test for login

* buttons to start webauthn process

* begin eventstore impl

* begin eventstore impl

* serialize into bytes

* fix: u2f, passwordless types

* fix for localhost

* fix script

* fix: u2f, passwordless types

* fix: add u2f

* fix: verify u2f

* fix: session data in event store

* fix: u2f credentials in eventstore

* fix: webauthn pkg handles business models

* feat: tests

* feat: append events

* fix: test

* fix: check only ready webauthn creds

* fix: move u2f methods to authrepo

* frontend improvements

* fix return

* feat: add passwordless

* feat: add passwordless

* improve ui / error handling

* separate call for login

* fix login

* js

* feat: u2f login methods

* feat: remove unused session id

* feat: error handling

* feat: error handling

* feat: refactor user eventstore

* feat: finish webauthn

* feat: u2f and passwordlss in auth.proto

* u2f step

* passwordless step

* cleanup js

* EndpointPasswordLessLogin

* migration

* update mfaChecked test

* next step test

* token name

* cleanup

* attribute

* passwordless as tokens

* remove sms as otp type

* add "user" to amr for webauthn

* error handling

* fixes

* fix tests

* naming

* naming

* fixes

* session handler

* i18n

* error handling in login

* Update internal/ui/login/static/i18n/de.yaml

Co-authored-by: Fabi <38692350+fgerschwiler@users.noreply.github.com>

* Update internal/ui/login/static/i18n/en.yaml

Co-authored-by: Fabi <38692350+fgerschwiler@users.noreply.github.com>

* improvements

* merge fixes

* fixes

* fixes

Co-authored-by: Fabiennne <fabienne.gerschwiler@gmail.com>
Co-authored-by: Fabi <38692350+fgerschwiler@users.noreply.github.com>
2020-12-02 17:00:04 +01:00

794 lines
22 KiB
Go

package eventsourcing
import (
"context"
"github.com/caos/zitadel/internal/api/authz"
caos_errs "github.com/caos/zitadel/internal/errors"
"github.com/caos/zitadel/internal/eventstore/models"
iam_model "github.com/caos/zitadel/internal/iam/model"
iam_es_model "github.com/caos/zitadel/internal/iam/repository/eventsourcing/model"
"github.com/caos/zitadel/internal/org/repository/eventsourcing/model"
"testing"
)
func TestLoginPolicyAddedAggregate(t *testing.T) {
type args struct {
ctx context.Context
existing *model.Org
new *iam_es_model.LoginPolicy
aggCreator *models.AggregateCreator
}
type res struct {
eventLen int
eventTypes []models.EventType
wantErr bool
errFunc func(err error) bool
}
tests := []struct {
name string
args args
res res
}{
{
name: "add login polciy",
args: args{
ctx: authz.NewMockContext("orgID", "userID"),
existing: &model.Org{
ObjectRoot: models.ObjectRoot{AggregateID: "AggregateID"},
},
new: &iam_es_model.LoginPolicy{
ObjectRoot: models.ObjectRoot{AggregateID: "AggregateID"},
AllowUsernamePassword: true,
},
aggCreator: models.NewAggregateCreator("Test"),
},
res: res{
eventLen: 1,
eventTypes: []models.EventType{model.LoginPolicyAdded},
},
},
{
name: "existing org nil",
args: args{
ctx: authz.NewMockContext("orgID", "userID"),
existing: nil,
aggCreator: models.NewAggregateCreator("Test"),
},
res: res{
wantErr: true,
errFunc: caos_errs.IsPreconditionFailed,
},
},
{
name: "login policy config nil",
args: args{
ctx: authz.NewMockContext("orgID", "userID"),
existing: &model.Org{ObjectRoot: models.ObjectRoot{AggregateID: "AggregateID"}},
new: nil,
aggCreator: models.NewAggregateCreator("Test"),
},
res: res{
wantErr: true,
errFunc: caos_errs.IsPreconditionFailed,
},
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
agg, err := LoginPolicyAddedAggregate(tt.args.aggCreator, tt.args.existing, tt.args.new)(tt.args.ctx)
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 && len(agg.Events) != tt.res.eventLen {
t.Errorf("got wrong event len: expected: %v, actual: %v ", tt.res.eventLen, len(agg.Events))
}
for i := 0; i < tt.res.eventLen; i++ {
if !tt.res.wantErr && agg.Events[i].Type != tt.res.eventTypes[i] {
t.Errorf("got wrong event type: expected: %v, actual: %v ", tt.res.eventTypes[i], agg.Events[i].Type.String())
}
if !tt.res.wantErr && agg.Events[i].Data == nil {
t.Errorf("should have data in event")
}
}
})
}
}
func TestLoginPolicyChangedAggregate(t *testing.T) {
type args struct {
ctx context.Context
existing *model.Org
new *iam_es_model.LoginPolicy
aggCreator *models.AggregateCreator
}
type res struct {
eventLen int
eventTypes []models.EventType
wantErr bool
errFunc func(err error) bool
}
tests := []struct {
name string
args args
res res
}{
{
name: "change login policy",
args: args{
ctx: authz.NewMockContext("orgID", "userID"),
existing: &model.Org{
ObjectRoot: models.ObjectRoot{AggregateID: "AggregateID"},
LoginPolicy: &iam_es_model.LoginPolicy{
ObjectRoot: models.ObjectRoot{AggregateID: "AggregateID"},
},
},
new: &iam_es_model.LoginPolicy{
ObjectRoot: models.ObjectRoot{AggregateID: "AggregateID"},
AllowUsernamePassword: true,
AllowRegister: true,
},
aggCreator: models.NewAggregateCreator("Test"),
},
res: res{
eventLen: 1,
eventTypes: []models.EventType{model.LoginPolicyChanged},
},
},
{
name: "existing org nil",
args: args{
ctx: authz.NewMockContext("orgID", "userID"),
existing: nil,
aggCreator: models.NewAggregateCreator("Test"),
},
res: res{
wantErr: true,
errFunc: caos_errs.IsPreconditionFailed,
},
},
{
name: "login policy config nil",
args: args{
ctx: authz.NewMockContext("orgID", "userID"),
existing: &model.Org{ObjectRoot: models.ObjectRoot{AggregateID: "AggregateID"}},
new: nil,
aggCreator: models.NewAggregateCreator("Test"),
},
res: res{
wantErr: true,
errFunc: caos_errs.IsPreconditionFailed,
},
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
agg, err := LoginPolicyChangedAggregate(tt.args.aggCreator, tt.args.existing, tt.args.new)(tt.args.ctx)
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 && len(agg.Events) != tt.res.eventLen {
t.Errorf("got wrong event len: expected: %v, actual: %v ", tt.res.eventLen, len(agg.Events))
}
for i := 0; i < tt.res.eventLen; i++ {
if !tt.res.wantErr && agg.Events[i].Type != tt.res.eventTypes[i] {
t.Errorf("got wrong event type: expected: %v, actual: %v ", tt.res.eventTypes[i], agg.Events[i].Type.String())
}
if !tt.res.wantErr && agg.Events[i].Data == nil {
t.Errorf("should have data in event")
}
}
})
}
}
func TestLoginPolicyRemovedAggregate(t *testing.T) {
type args struct {
ctx context.Context
existing *model.Org
aggCreator *models.AggregateCreator
}
type res struct {
eventLen int
eventTypes []models.EventType
wantErr bool
errFunc func(err error) bool
}
tests := []struct {
name string
args args
res res
}{
{
name: "remove login policy",
args: args{
ctx: authz.NewMockContext("orgID", "userID"),
existing: &model.Org{
ObjectRoot: models.ObjectRoot{AggregateID: "AggregateID"},
LoginPolicy: &iam_es_model.LoginPolicy{
ObjectRoot: models.ObjectRoot{AggregateID: "AggregateID"},
},
},
aggCreator: models.NewAggregateCreator("Test"),
},
res: res{
eventLen: 1,
eventTypes: []models.EventType{model.LoginPolicyRemoved},
},
},
{
name: "existing org nil",
args: args{
ctx: authz.NewMockContext("orgID", "userID"),
existing: nil,
aggCreator: models.NewAggregateCreator("Test"),
},
res: res{
wantErr: true,
errFunc: caos_errs.IsPreconditionFailed,
},
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
agg, err := LoginPolicyRemovedAggregate(tt.args.aggCreator, tt.args.existing)(tt.args.ctx)
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 && len(agg.Events) != tt.res.eventLen {
t.Errorf("got wrong event len: expected: %v, actual: %v ", tt.res.eventLen, len(agg.Events))
}
for i := 0; i < tt.res.eventLen; i++ {
if !tt.res.wantErr && agg.Events[i].Type != tt.res.eventTypes[i] {
t.Errorf("got wrong event type: expected: %v, actual: %v ", tt.res.eventTypes[i], agg.Events[i].Type.String())
}
}
})
}
}
func TestLoginPolicyIdpProviderAddedAggregate(t *testing.T) {
type args struct {
ctx context.Context
existing *model.Org
new *iam_es_model.IDPProvider
aggCreator *models.AggregateCreator
}
type res struct {
eventLen int
eventTypes []models.EventType
wantErr bool
errFunc func(err error) bool
}
tests := []struct {
name string
args args
res res
}{
{
name: "add idp provider to login policy",
args: args{
ctx: authz.NewMockContext("orgID", "userID"),
existing: &model.Org{
ObjectRoot: models.ObjectRoot{AggregateID: "AggregateID"},
},
new: &iam_es_model.IDPProvider{
ObjectRoot: models.ObjectRoot{AggregateID: "AggregateID"},
Type: int32(iam_model.IDPProviderTypeSystem),
IDPConfigID: "IDPConfigID",
},
aggCreator: models.NewAggregateCreator("Test"),
},
res: res{
eventLen: 1,
eventTypes: []models.EventType{model.LoginPolicyIDPProviderAdded},
},
},
{
name: "existing org nil",
args: args{
ctx: authz.NewMockContext("orgID", "userID"),
existing: nil,
aggCreator: models.NewAggregateCreator("Test"),
},
res: res{
wantErr: true,
errFunc: caos_errs.IsPreconditionFailed,
},
},
{
name: "idp config config nil",
args: args{
ctx: authz.NewMockContext("orgID", "userID"),
existing: &model.Org{ObjectRoot: models.ObjectRoot{AggregateID: "AggregateID"}},
new: nil,
aggCreator: models.NewAggregateCreator("Test"),
},
res: res{
wantErr: true,
errFunc: caos_errs.IsPreconditionFailed,
},
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
agg, err := LoginPolicyIDPProviderAddedAggregate(tt.args.aggCreator, tt.args.existing, tt.args.new, "IAMID")(tt.args.ctx)
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 && len(agg.Events) != tt.res.eventLen {
t.Errorf("got wrong event len: expected: %v, actual: %v ", tt.res.eventLen, len(agg.Events))
}
for i := 0; i < tt.res.eventLen; i++ {
if !tt.res.wantErr && agg.Events[i].Type != tt.res.eventTypes[i] {
t.Errorf("got wrong event type: expected: %v, actual: %v ", tt.res.eventTypes[i], agg.Events[i].Type.String())
}
if !tt.res.wantErr && agg.Events[i].Data == nil {
t.Errorf("should have data in event")
}
}
})
}
}
func TestLoginPolicyIdpProviderRemovedAggregate(t *testing.T) {
type args struct {
ctx context.Context
existing *model.Org
new *iam_es_model.IDPProviderID
cascade bool
aggCreator *models.AggregateCreator
}
type res struct {
eventLen int
eventTypes []models.EventType
wantErr bool
errFunc func(err error) bool
}
tests := []struct {
name string
args args
res res
}{
{
name: "remove idp provider to login policy",
args: args{
ctx: authz.NewMockContext("orgID", "userID"),
existing: &model.Org{
ObjectRoot: models.ObjectRoot{AggregateID: "AggregateID"},
LoginPolicy: &iam_es_model.LoginPolicy{
AllowUsernamePassword: true,
IDPProviders: []*iam_es_model.IDPProvider{
{IDPConfigID: "IDPConfigID", Type: int32(iam_model.IDPProviderTypeSystem)},
},
}},
new: &iam_es_model.IDPProviderID{
IDPConfigID: "IDPConfigID",
},
aggCreator: models.NewAggregateCreator("Test"),
},
res: res{
eventLen: 1,
eventTypes: []models.EventType{model.LoginPolicyIDPProviderRemoved},
},
},
{
name: "remove idp provider to login policy cascade",
args: args{
ctx: authz.NewMockContext("orgID", "userID"),
existing: &model.Org{
ObjectRoot: models.ObjectRoot{AggregateID: "AggregateID"},
LoginPolicy: &iam_es_model.LoginPolicy{
AllowUsernamePassword: true,
IDPProviders: []*iam_es_model.IDPProvider{
{IDPConfigID: "IDPConfigID", Type: int32(iam_model.IDPProviderTypeSystem)},
},
}},
new: &iam_es_model.IDPProviderID{
IDPConfigID: "IDPConfigID",
},
cascade: true,
aggCreator: models.NewAggregateCreator("Test"),
},
res: res{
eventLen: 1,
eventTypes: []models.EventType{model.LoginPolicyIDPProviderCascadeRemoved},
},
},
{
name: "existing org nil",
args: args{
ctx: authz.NewMockContext("orgID", "userID"),
existing: nil,
aggCreator: models.NewAggregateCreator("Test"),
},
res: res{
wantErr: true,
errFunc: caos_errs.IsPreconditionFailed,
},
},
{
name: "idp config config nil",
args: args{
ctx: authz.NewMockContext("orgID", "userID"),
existing: &model.Org{ObjectRoot: models.ObjectRoot{AggregateID: "AggregateID"}},
new: nil,
aggCreator: models.NewAggregateCreator("Test"),
},
res: res{
wantErr: true,
errFunc: caos_errs.IsPreconditionFailed,
},
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
agg, err := LoginPolicyIDPProviderRemovedAggregate(tt.args.ctx, tt.args.aggCreator, tt.args.existing, tt.args.new, tt.args.cascade)
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 && len(agg.Events) != tt.res.eventLen {
t.Errorf("got wrong event len: expected: %v, actual: %v ", tt.res.eventLen, len(agg.Events))
}
for i := 0; i < tt.res.eventLen; i++ {
if !tt.res.wantErr && agg.Events[i].Type != tt.res.eventTypes[i] {
t.Errorf("got wrong event type: expected: %v, actual: %v ", tt.res.eventTypes[i], agg.Events[i].Type.String())
}
if !tt.res.wantErr && agg.Events[i].Data == nil {
t.Errorf("should have data in event")
}
}
})
}
}
func TestLoginPolicySecondFactorAddedAggregate(t *testing.T) {
type args struct {
ctx context.Context
existing *model.Org
new *iam_es_model.MFA
aggCreator *models.AggregateCreator
}
type res struct {
eventLen int
eventTypes []models.EventType
wantErr bool
errFunc func(err error) bool
}
tests := []struct {
name string
args args
res res
}{
{
name: "add second factor to login policy",
args: args{
ctx: authz.NewMockContext("orgID", "userID"),
existing: &model.Org{
ObjectRoot: models.ObjectRoot{AggregateID: "AggregateID"},
},
new: &iam_es_model.MFA{
MFAType: int32(iam_model.SecondFactorTypeOTP),
},
aggCreator: models.NewAggregateCreator("Test"),
},
res: res{
eventLen: 1,
eventTypes: []models.EventType{model.LoginPolicySecondFactorAdded},
},
},
{
name: "existing org nil",
args: args{
ctx: authz.NewMockContext("orgID", "userID"),
existing: nil,
aggCreator: models.NewAggregateCreator("Test"),
},
res: res{
wantErr: true,
errFunc: caos_errs.IsPreconditionFailed,
},
},
{
name: "mfa nil",
args: args{
ctx: authz.NewMockContext("orgID", "userID"),
existing: &model.Org{ObjectRoot: models.ObjectRoot{AggregateID: "AggregateID"}},
new: nil,
aggCreator: models.NewAggregateCreator("Test"),
},
res: res{
wantErr: true,
errFunc: caos_errs.IsPreconditionFailed,
},
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
agg, err := LoginPolicySecondFactorAddedAggregate(tt.args.aggCreator, tt.args.existing, tt.args.new, "IAMID")(tt.args.ctx)
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 && (agg == nil || len(agg.Events) != tt.res.eventLen) {
t.Errorf("got wrong event len: expected: %v, actual: %v ", tt.res.eventLen, len(agg.Events))
return
}
for i := 0; i < tt.res.eventLen; i++ {
if !tt.res.wantErr && agg.Events[i].Type != tt.res.eventTypes[i] {
t.Errorf("got wrong event type: expected: %v, actual: %v ", tt.res.eventTypes[i], agg.Events[i].Type.String())
}
if !tt.res.wantErr && agg.Events[i].Data == nil {
t.Errorf("should have data in event")
}
}
})
}
}
func TestLoginPolicySecondFactorRemovedAggregate(t *testing.T) {
type args struct {
ctx context.Context
existing *model.Org
new *iam_es_model.MFA
aggCreator *models.AggregateCreator
}
type res struct {
eventLen int
eventTypes []models.EventType
wantErr bool
errFunc func(err error) bool
}
tests := []struct {
name string
args args
res res
}{
{
name: "remove second factor from login policy",
args: args{
ctx: authz.NewMockContext("orgID", "userID"),
existing: &model.Org{
ObjectRoot: models.ObjectRoot{AggregateID: "AggregateID"},
LoginPolicy: &iam_es_model.LoginPolicy{
AllowUsernamePassword: true,
SecondFactors: []int32{
int32(iam_model.SecondFactorTypeOTP),
},
}},
new: &iam_es_model.MFA{
MFAType: int32(iam_model.SecondFactorTypeOTP),
},
aggCreator: models.NewAggregateCreator("Test"),
},
res: res{
eventLen: 1,
eventTypes: []models.EventType{model.LoginPolicySecondFactorRemoved},
},
},
{
name: "existing org nil",
args: args{
ctx: authz.NewMockContext("orgID", "userID"),
existing: nil,
aggCreator: models.NewAggregateCreator("Test"),
},
res: res{
wantErr: true,
errFunc: caos_errs.IsPreconditionFailed,
},
},
{
name: "mfa nil",
args: args{
ctx: authz.NewMockContext("orgID", "userID"),
existing: &model.Org{ObjectRoot: models.ObjectRoot{AggregateID: "AggregateID"}},
new: nil,
aggCreator: models.NewAggregateCreator("Test"),
},
res: res{
wantErr: true,
errFunc: caos_errs.IsPreconditionFailed,
},
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
agg, err := LoginPolicySecondFactorRemovedAggregate(tt.args.aggCreator, tt.args.existing, tt.args.new)(tt.args.ctx)
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 && len(agg.Events) != tt.res.eventLen {
t.Errorf("got wrong event len: expected: %v, actual: %v ", tt.res.eventLen, len(agg.Events))
}
for i := 0; i < tt.res.eventLen; i++ {
if !tt.res.wantErr && agg.Events[i].Type != tt.res.eventTypes[i] {
t.Errorf("got wrong event type: expected: %v, actual: %v ", tt.res.eventTypes[i], agg.Events[i].Type.String())
}
if !tt.res.wantErr && agg.Events[i].Data == nil {
t.Errorf("should have data in event")
}
}
})
}
}
func TestLoginPolicyMultiFactorAddedAggregate(t *testing.T) {
type args struct {
ctx context.Context
existing *model.Org
new *iam_es_model.MFA
aggCreator *models.AggregateCreator
}
type res struct {
eventLen int
eventTypes []models.EventType
wantErr bool
errFunc func(err error) bool
}
tests := []struct {
name string
args args
res res
}{
{
name: "add mfa to login policy",
args: args{
ctx: authz.NewMockContext("orgID", "userID"),
existing: &model.Org{
ObjectRoot: models.ObjectRoot{AggregateID: "AggregateID"},
},
new: &iam_es_model.MFA{
MFAType: int32(iam_model.MultiFactorTypeU2FWithPIN),
},
aggCreator: models.NewAggregateCreator("Test"),
},
res: res{
eventLen: 1,
eventTypes: []models.EventType{model.LoginPolicyMultiFactorAdded},
},
},
{
name: "existing org nil",
args: args{
ctx: authz.NewMockContext("orgID", "userID"),
existing: nil,
aggCreator: models.NewAggregateCreator("Test"),
},
res: res{
wantErr: true,
errFunc: caos_errs.IsPreconditionFailed,
},
},
{
name: "mfa nil",
args: args{
ctx: authz.NewMockContext("orgID", "userID"),
existing: &model.Org{ObjectRoot: models.ObjectRoot{AggregateID: "AggregateID"}},
new: nil,
aggCreator: models.NewAggregateCreator("Test"),
},
res: res{
wantErr: true,
errFunc: caos_errs.IsPreconditionFailed,
},
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
agg, err := LoginPolicyMultiFactorAddedAggregate(tt.args.aggCreator, tt.args.existing, tt.args.new, "IAMID")(tt.args.ctx)
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 && (agg == nil || len(agg.Events) != tt.res.eventLen) {
t.Errorf("got wrong event len: expected: %v, actual: %v ", tt.res.eventLen, len(agg.Events))
return
}
for i := 0; i < tt.res.eventLen; i++ {
if !tt.res.wantErr && agg.Events[i].Type != tt.res.eventTypes[i] {
t.Errorf("got wrong event type: expected: %v, actual: %v ", tt.res.eventTypes[i], agg.Events[i].Type.String())
}
if !tt.res.wantErr && agg.Events[i].Data == nil {
t.Errorf("should have data in event")
}
}
})
}
}
func TestLoginPolicyMultiFactorRemovedAggregate(t *testing.T) {
type args struct {
ctx context.Context
existing *model.Org
new *iam_es_model.MFA
aggCreator *models.AggregateCreator
}
type res struct {
eventLen int
eventTypes []models.EventType
wantErr bool
errFunc func(err error) bool
}
tests := []struct {
name string
args args
res res
}{
{
name: "remove mfa from login policy",
args: args{
ctx: authz.NewMockContext("orgID", "userID"),
existing: &model.Org{
ObjectRoot: models.ObjectRoot{AggregateID: "AggregateID"},
LoginPolicy: &iam_es_model.LoginPolicy{
AllowUsernamePassword: true,
MultiFactors: []int32{
int32(iam_model.MultiFactorTypeU2FWithPIN),
},
}},
new: &iam_es_model.MFA{
MFAType: int32(iam_model.MultiFactorTypeU2FWithPIN),
},
aggCreator: models.NewAggregateCreator("Test"),
},
res: res{
eventLen: 1,
eventTypes: []models.EventType{model.LoginPolicyMultiFactorRemoved},
},
},
{
name: "existing org nil",
args: args{
ctx: authz.NewMockContext("orgID", "userID"),
existing: nil,
aggCreator: models.NewAggregateCreator("Test"),
},
res: res{
wantErr: true,
errFunc: caos_errs.IsPreconditionFailed,
},
},
{
name: "mfa nil",
args: args{
ctx: authz.NewMockContext("orgID", "userID"),
existing: &model.Org{ObjectRoot: models.ObjectRoot{AggregateID: "AggregateID"}},
new: nil,
aggCreator: models.NewAggregateCreator("Test"),
},
res: res{
wantErr: true,
errFunc: caos_errs.IsPreconditionFailed,
},
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
agg, err := LoginPolicyMultiFactorRemovedAggregate(tt.args.aggCreator, tt.args.existing, tt.args.new)(tt.args.ctx)
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 && len(agg.Events) != tt.res.eventLen {
t.Errorf("got wrong event len: expected: %v, actual: %v ", tt.res.eventLen, len(agg.Events))
}
for i := 0; i < tt.res.eventLen; i++ {
if !tt.res.wantErr && agg.Events[i].Type != tt.res.eventTypes[i] {
t.Errorf("got wrong event type: expected: %v, actual: %v ", tt.res.eventTypes[i], agg.Events[i].Type.String())
}
if !tt.res.wantErr && agg.Events[i].Data == nil {
t.Errorf("should have data in event")
}
}
})
}
}