fix: import user, hide login name suffix (#1474)

* fix: import user, and label policy command side

* feat: Import user and hide loginname suffix (#1464)

* fix: import user

* fix: label policy

* fix: label policy

* fix: label policy

* fix: migrations

* fix: migrations

* fix: migrations

* fix: label policy

* loginSuffix in login ui

* suffix

* fix cursor on disabled user selection

Co-authored-by: Livio Amstutz <livio.a@gmail.com>

(cherry picked from commit 03ddb8fc38)

* feat: Import user and hide loginname suffix (#1464)

* fix: import user

* fix: label policy

* fix: label policy

* fix: label policy

* fix: migrations

* fix: migrations

* fix: migrations

* fix: label policy

* loginSuffix in login ui

* suffix

* fix cursor on disabled user selection

Co-authored-by: Livio Amstutz <livio.a@gmail.com>

(cherry picked from commit 03ddb8fc38)

* feat: Import user and hide loginname suffix (#1464)

* fix: import user

* fix: label policy

* fix: label policy

* fix: label policy

* fix: migrations

* fix: migrations

* fix: migrations

* fix: label policy

* loginSuffix in login ui

* suffix

* fix cursor on disabled user selection

Co-authored-by: Livio Amstutz <livio.a@gmail.com>

(cherry picked from commit 03ddb8fc38)

* fix: label policy events

* loginname placeholder

* fix: tests

* fix: tests

* Update internal/command/iam_policy_label_model.go

Co-authored-by: Livio Amstutz <livio.a@gmail.com>

Co-authored-by: Livio Amstutz <livio.a@gmail.com>
This commit is contained in:
Fabi
2021-03-25 14:41:07 +01:00
committed by GitHub
parent d7255130a4
commit 4d10f3e715
58 changed files with 1444 additions and 309 deletions

View File

@@ -46,9 +46,10 @@ func writeModelToLoginPolicy(wm *LoginPolicyWriteModel) *domain.LoginPolicy {
func writeModelToLabelPolicy(wm *LabelPolicyWriteModel) *domain.LabelPolicy {
return &domain.LabelPolicy{
ObjectRoot: writeModelToObjectRoot(wm.WriteModel),
PrimaryColor: wm.PrimaryColor,
SecondaryColor: wm.SecondaryColor,
ObjectRoot: writeModelToObjectRoot(wm.WriteModel),
PrimaryColor: wm.PrimaryColor,
SecondaryColor: wm.SecondaryColor,
HideLoginNameSuffix: wm.HideLoginNameSuffix,
}
}

View File

@@ -40,7 +40,7 @@ func (c *Commands) addDefaultLabelPolicy(ctx context.Context, iamAgg *eventstore
return nil, caos_errs.ThrowAlreadyExists(nil, "IAM-2B0ps", "Errors.IAM.LabelPolicy.AlreadyExists")
}
return iam_repo.NewLabelPolicyAddedEvent(ctx, iamAgg, policy.PrimaryColor, policy.SecondaryColor), nil
return iam_repo.NewLabelPolicyAddedEvent(ctx, iamAgg, policy.PrimaryColor, policy.SecondaryColor, policy.HideLoginNameSuffix), nil
}
@@ -57,7 +57,7 @@ func (c *Commands) ChangeDefaultLabelPolicy(ctx context.Context, policy *domain.
return nil, caos_errs.ThrowNotFound(nil, "IAM-0K9dq", "Errors.IAM.LabelPolicy.NotFound")
}
iamAgg := IAMAggregateFromWriteModel(&existingPolicy.LabelPolicyWriteModel.WriteModel)
changedEvent, hasChanged := existingPolicy.NewChangedEvent(ctx, iamAgg, policy.PrimaryColor, policy.SecondaryColor)
changedEvent, hasChanged := existingPolicy.NewChangedEvent(ctx, iamAgg, policy.PrimaryColor, policy.SecondaryColor, policy.HideLoginNameSuffix)
if !hasChanged {
return nil, caos_errs.ThrowPreconditionFailed(nil, "IAM-4M9vs", "Errors.IAM.LabelPolicy.NotChanged")
}

View File

@@ -53,6 +53,7 @@ func (wm *IAMLabelPolicyWriteModel) NewChangedEvent(
aggregate *eventstore.Aggregate,
primaryColor,
secondaryColor string,
hideLoginNameSuffix bool,
) (*iam.LabelPolicyChangedEvent, bool) {
changes := make([]policy.LabelPolicyChanges, 0)
if wm.PrimaryColor != primaryColor {
@@ -61,6 +62,9 @@ func (wm *IAMLabelPolicyWriteModel) NewChangedEvent(
if wm.SecondaryColor != secondaryColor {
changes = append(changes, policy.ChangeSecondaryColor(secondaryColor))
}
if wm.HideLoginNameSuffix != hideLoginNameSuffix {
changes = append(changes, policy.ChangeHideLoginNameSuffix(hideLoginNameSuffix))
}
if len(changes) == 0 {
return nil, false
}

View File

@@ -60,6 +60,7 @@ func TestCommandSide_AddDefaultLabelPolicy(t *testing.T) {
&iam.NewAggregate().Aggregate,
"primary-color",
"secondary-color",
true,
),
),
),
@@ -68,8 +69,9 @@ func TestCommandSide_AddDefaultLabelPolicy(t *testing.T) {
args: args{
ctx: context.Background(),
policy: &domain.LabelPolicy{
PrimaryColor: "primary-color",
SecondaryColor: "secondary-color",
PrimaryColor: "primary-color",
SecondaryColor: "secondary-color",
HideLoginNameSuffix: true,
},
},
res: res{
@@ -89,6 +91,7 @@ func TestCommandSide_AddDefaultLabelPolicy(t *testing.T) {
&iam.NewAggregate().Aggregate,
"primary-color",
"secondary-color",
true,
),
),
},
@@ -98,8 +101,9 @@ func TestCommandSide_AddDefaultLabelPolicy(t *testing.T) {
args: args{
ctx: context.Background(),
policy: &domain.LabelPolicy{
PrimaryColor: "primary-color",
SecondaryColor: "secondary-color",
PrimaryColor: "primary-color",
SecondaryColor: "secondary-color",
HideLoginNameSuffix: true,
},
},
res: res{
@@ -108,8 +112,9 @@ func TestCommandSide_AddDefaultLabelPolicy(t *testing.T) {
AggregateID: "IAM",
ResourceOwner: "IAM",
},
PrimaryColor: "primary-color",
SecondaryColor: "secondary-color",
PrimaryColor: "primary-color",
SecondaryColor: "secondary-color",
HideLoginNameSuffix: true,
},
},
},
@@ -199,6 +204,7 @@ func TestCommandSide_ChangeDefaultLabelPolicy(t *testing.T) {
&iam.NewAggregate().Aggregate,
"primary-color",
"secondary-color",
true,
),
),
),
@@ -207,8 +213,9 @@ func TestCommandSide_ChangeDefaultLabelPolicy(t *testing.T) {
args: args{
ctx: context.Background(),
policy: &domain.LabelPolicy{
PrimaryColor: "primary-color",
SecondaryColor: "secondary-color",
PrimaryColor: "primary-color",
SecondaryColor: "secondary-color",
HideLoginNameSuffix: true,
},
},
res: res{
@@ -226,13 +233,14 @@ func TestCommandSide_ChangeDefaultLabelPolicy(t *testing.T) {
&iam.NewAggregate().Aggregate,
"primary-color",
"secondary-color",
true,
),
),
),
expectPush(
[]*repository.Event{
eventFromEventPusher(
newDefaultLabelPolicyChangedEvent(context.Background(), "primary-color-change", "secondary-color-change"),
newDefaultLabelPolicyChangedEvent(context.Background(), "primary-color-change", "secondary-color-change", false),
),
},
),
@@ -241,8 +249,9 @@ func TestCommandSide_ChangeDefaultLabelPolicy(t *testing.T) {
args: args{
ctx: context.Background(),
policy: &domain.LabelPolicy{
PrimaryColor: "primary-color-change",
SecondaryColor: "secondary-color-change",
PrimaryColor: "primary-color-change",
SecondaryColor: "secondary-color-change",
HideLoginNameSuffix: false,
},
},
res: res{
@@ -251,8 +260,9 @@ func TestCommandSide_ChangeDefaultLabelPolicy(t *testing.T) {
AggregateID: "IAM",
ResourceOwner: "IAM",
},
PrimaryColor: "primary-color-change",
SecondaryColor: "secondary-color-change",
PrimaryColor: "primary-color-change",
SecondaryColor: "secondary-color-change",
HideLoginNameSuffix: false,
},
},
},
@@ -276,12 +286,13 @@ func TestCommandSide_ChangeDefaultLabelPolicy(t *testing.T) {
}
}
func newDefaultLabelPolicyChangedEvent(ctx context.Context, primaryColor, secondaryColor string) *iam.LabelPolicyChangedEvent {
func newDefaultLabelPolicyChangedEvent(ctx context.Context, primaryColor, secondaryColor string, hideLoginNameSuffix bool) *iam.LabelPolicyChangedEvent {
event, _ := iam.NewLabelPolicyChangedEvent(ctx,
&iam.NewAggregate().Aggregate,
[]policy.LabelPolicyChanges{
policy.ChangePrimaryColor(primaryColor),
policy.ChangeSecondaryColor(secondaryColor),
policy.ChangeHideLoginNameSuffix(hideLoginNameSuffix),
},
)
return event

View File

@@ -25,7 +25,7 @@ func (c *Commands) AddLabelPolicy(ctx context.Context, resourceOwner string, pol
}
orgAgg := OrgAggregateFromWriteModel(&addedPolicy.LabelPolicyWriteModel.WriteModel)
pushedEvents, err := c.eventstore.PushEvents(ctx, org.NewLabelPolicyAddedEvent(ctx, orgAgg, policy.PrimaryColor, policy.SecondaryColor))
pushedEvents, err := c.eventstore.PushEvents(ctx, org.NewLabelPolicyAddedEvent(ctx, orgAgg, policy.PrimaryColor, policy.SecondaryColor, policy.HideLoginNameSuffix))
if err != nil {
return nil, err
}
@@ -53,7 +53,7 @@ func (c *Commands) ChangeLabelPolicy(ctx context.Context, resourceOwner string,
}
orgAgg := OrgAggregateFromWriteModel(&existingPolicy.LabelPolicyWriteModel.WriteModel)
changedEvent, hasChanged := existingPolicy.NewChangedEvent(ctx, orgAgg, policy.PrimaryColor, policy.SecondaryColor)
changedEvent, hasChanged := existingPolicy.NewChangedEvent(ctx, orgAgg, policy.PrimaryColor, policy.SecondaryColor, policy.HideLoginNameSuffix)
if !hasChanged {
return nil, caos_errs.ThrowPreconditionFailed(nil, "Org-4M9vs", "Errors.Org.LabelPolicy.NotChanged")
}
@@ -69,19 +69,26 @@ func (c *Commands) ChangeLabelPolicy(ctx context.Context, resourceOwner string,
return writeModelToLabelPolicy(&existingPolicy.LabelPolicyWriteModel), nil
}
func (c *Commands) RemoveLabelPolicy(ctx context.Context, orgID string) error {
func (c *Commands) RemoveLabelPolicy(ctx context.Context, orgID string) (*domain.ObjectDetails, error) {
if orgID == "" {
return caos_errs.ThrowInvalidArgument(nil, "Org-Mf9sf", "Errors.ResourceOwnerMissing")
return nil, caos_errs.ThrowInvalidArgument(nil, "Org-Mf9sf", "Errors.ResourceOwnerMissing")
}
existingPolicy := NewOrgLabelPolicyWriteModel(orgID)
err := c.eventstore.FilterToQueryReducer(ctx, existingPolicy)
if err != nil {
return err
return nil, err
}
if existingPolicy.State == domain.PolicyStateUnspecified || existingPolicy.State == domain.PolicyStateRemoved {
return caos_errs.ThrowNotFound(nil, "Org-3M9df", "Errors.Org.LabelPolicy.NotFound")
return nil, caos_errs.ThrowNotFound(nil, "Org-3M9df", "Errors.Org.LabelPolicy.NotFound")
}
orgAgg := OrgAggregateFromWriteModel(&existingPolicy.WriteModel)
_, err = c.eventstore.PushEvents(ctx, org.NewLabelPolicyRemovedEvent(ctx, orgAgg))
return err
pushedEvents, err := c.eventstore.PushEvents(ctx, org.NewLabelPolicyRemovedEvent(ctx, orgAgg))
if err != nil {
return nil, err
}
err = AppendAndReduce(existingPolicy, pushedEvents...)
if err != nil {
return nil, err
}
return writeModelToObjectDetails(&existingPolicy.LabelPolicyWriteModel.WriteModel), nil
}

View File

@@ -52,6 +52,7 @@ func (wm *OrgLabelPolicyWriteModel) NewChangedEvent(
aggregate *eventstore.Aggregate,
primaryColor,
secondaryColor string,
hideLoginNameSuffix bool,
) (*org.LabelPolicyChangedEvent, bool) {
changes := make([]policy.LabelPolicyChanges, 0)
if wm.PrimaryColor != primaryColor {
@@ -60,6 +61,9 @@ func (wm *OrgLabelPolicyWriteModel) NewChangedEvent(
if wm.SecondaryColor != secondaryColor {
changes = append(changes, policy.ChangeSecondaryColor(secondaryColor))
}
if wm.HideLoginNameSuffix != hideLoginNameSuffix {
changes = append(changes, policy.ChangeHideLoginNameSuffix(hideLoginNameSuffix))
}
if len(changes) == 0 {
return nil, false
}

View File

@@ -82,6 +82,7 @@ func TestCommandSide_AddLabelPolicy(t *testing.T) {
&org.NewAggregate("org1", "org1").Aggregate,
"primary-color",
"secondary-color",
true,
),
),
),
@@ -91,8 +92,9 @@ func TestCommandSide_AddLabelPolicy(t *testing.T) {
ctx: context.Background(),
orgID: "org1",
policy: &domain.LabelPolicy{
PrimaryColor: "primary-color",
SecondaryColor: "secondary-color",
PrimaryColor: "primary-color",
SecondaryColor: "secondary-color",
HideLoginNameSuffix: true,
},
},
res: res{
@@ -112,6 +114,7 @@ func TestCommandSide_AddLabelPolicy(t *testing.T) {
&org.NewAggregate("org1", "org1").Aggregate,
"primary-color",
"secondary-color",
true,
),
),
},
@@ -122,8 +125,9 @@ func TestCommandSide_AddLabelPolicy(t *testing.T) {
ctx: context.Background(),
orgID: "org1",
policy: &domain.LabelPolicy{
PrimaryColor: "primary-color",
SecondaryColor: "secondary-color",
PrimaryColor: "primary-color",
SecondaryColor: "secondary-color",
HideLoginNameSuffix: true,
},
},
res: res{
@@ -132,8 +136,9 @@ func TestCommandSide_AddLabelPolicy(t *testing.T) {
AggregateID: "org1",
ResourceOwner: "org1",
},
PrimaryColor: "primary-color",
SecondaryColor: "secondary-color",
PrimaryColor: "primary-color",
SecondaryColor: "secondary-color",
HideLoginNameSuffix: true,
},
},
},
@@ -244,6 +249,7 @@ func TestCommandSide_ChangeLabelPolicy(t *testing.T) {
&org.NewAggregate("org1", "org1").Aggregate,
"primary-color",
"secondary-color",
true,
),
),
),
@@ -253,8 +259,9 @@ func TestCommandSide_ChangeLabelPolicy(t *testing.T) {
ctx: context.Background(),
orgID: "org1",
policy: &domain.LabelPolicy{
PrimaryColor: "primary-color",
SecondaryColor: "secondary-color",
PrimaryColor: "primary-color",
SecondaryColor: "secondary-color",
HideLoginNameSuffix: true,
},
},
res: res{
@@ -272,13 +279,14 @@ func TestCommandSide_ChangeLabelPolicy(t *testing.T) {
&org.NewAggregate("org1", "org1").Aggregate,
"primary-color",
"secondary-color",
true,
),
),
),
expectPush(
[]*repository.Event{
eventFromEventPusher(
newLabelPolicyChangedEvent(context.Background(), "org1", "primary-color-change", "secondary-color-change"),
newLabelPolicyChangedEvent(context.Background(), "org1", "primary-color-change", "secondary-color-change", false),
),
},
),
@@ -288,8 +296,9 @@ func TestCommandSide_ChangeLabelPolicy(t *testing.T) {
ctx: context.Background(),
orgID: "org1",
policy: &domain.LabelPolicy{
PrimaryColor: "primary-color-change",
SecondaryColor: "secondary-color-change",
PrimaryColor: "primary-color-change",
SecondaryColor: "secondary-color-change",
HideLoginNameSuffix: false,
},
},
res: res{
@@ -298,8 +307,9 @@ func TestCommandSide_ChangeLabelPolicy(t *testing.T) {
AggregateID: "org1",
ResourceOwner: "org1",
},
PrimaryColor: "primary-color-change",
SecondaryColor: "secondary-color-change",
PrimaryColor: "primary-color-change",
SecondaryColor: "secondary-color-change",
HideLoginNameSuffix: false,
},
},
},
@@ -381,6 +391,7 @@ func TestCommandSide_RemoveLabelPolicy(t *testing.T) {
&org.NewAggregate("org1", "org1").Aggregate,
"primary-color",
"secondary-color",
true,
),
),
),
@@ -406,7 +417,7 @@ func TestCommandSide_RemoveLabelPolicy(t *testing.T) {
r := &Commands{
eventstore: tt.fields.eventstore,
}
err := r.RemoveLabelPolicy(tt.args.ctx, tt.args.orgID)
_, err := r.RemoveLabelPolicy(tt.args.ctx, tt.args.orgID)
if tt.res.err == nil {
assert.NoError(t, err)
}
@@ -417,12 +428,13 @@ func TestCommandSide_RemoveLabelPolicy(t *testing.T) {
}
}
func newLabelPolicyChangedEvent(ctx context.Context, orgID, primaryColor, secondaryColor string) *org.LabelPolicyChangedEvent {
func newLabelPolicyChangedEvent(ctx context.Context, orgID, primaryColor, secondaryColor string, hideLoginNameSuffix bool) *org.LabelPolicyChangedEvent {
event, _ := org.NewLabelPolicyChangedEvent(ctx,
&org.NewAggregate(orgID, orgID).Aggregate,
[]policy.LabelPolicyChanges{
policy.ChangePrimaryColor(primaryColor),
policy.ChangeSecondaryColor(secondaryColor),
policy.ChangeHideLoginNameSuffix(hideLoginNameSuffix),
},
)
return event

View File

@@ -9,8 +9,9 @@ import (
type LabelPolicyWriteModel struct {
eventstore.WriteModel
PrimaryColor string
SecondaryColor string
PrimaryColor string
SecondaryColor string
HideLoginNameSuffix bool
State domain.PolicyState
}
@@ -21,6 +22,7 @@ func (wm *LabelPolicyWriteModel) Reduce() error {
case *policy.LabelPolicyAddedEvent:
wm.PrimaryColor = e.PrimaryColor
wm.SecondaryColor = e.SecondaryColor
wm.HideLoginNameSuffix = e.HideLoginNameSuffix
wm.State = domain.PolicyStateActive
case *policy.LabelPolicyChangedEvent:
if e.PrimaryColor != nil {
@@ -29,6 +31,9 @@ func (wm *LabelPolicyWriteModel) Reduce() error {
if e.SecondaryColor != nil {
wm.SecondaryColor = *e.SecondaryColor
}
if e.HideLoginNameSuffix != nil {
wm.HideLoginNameSuffix = *e.HideLoginNameSuffix
}
case *policy.LabelPolicyRemovedEvent:
wm.State = domain.PolicyStateRemoved
}

View File

@@ -50,7 +50,46 @@ func (c *Commands) AddHuman(ctx context.Context, orgID string, human *domain.Hum
return writeModelToHuman(addedHuman), nil
}
func (c *Commands) ImportHuman(ctx context.Context, orgID string, human *domain.Human) (*domain.Human, error) {
if orgID == "" {
return nil, caos_errs.ThrowInvalidArgument(nil, "COMMAND-5N8fs", "Errors.ResourceOwnerMissing")
}
orgIAMPolicy, err := c.getOrgIAMPolicy(ctx, orgID)
if err != nil {
return nil, caos_errs.ThrowPreconditionFailed(err, "COMMAND-2N9fs", "Errors.Org.OrgIAMPolicy.NotFound")
}
pwPolicy, err := c.getOrgPasswordComplexityPolicy(ctx, orgID)
if err != nil {
return nil, caos_errs.ThrowPreconditionFailed(err, "COMMAND-4N8gs", "Errors.Org.PasswordComplexity.NotFound")
}
events, addedHuman, err := c.importHuman(ctx, orgID, human, orgIAMPolicy, pwPolicy)
if err != nil {
return nil, err
}
pushedEvents, err := c.eventstore.PushEvents(ctx, events...)
if err != nil {
return nil, err
}
err = AppendAndReduce(addedHuman, pushedEvents...)
if err != nil {
return nil, err
}
return writeModelToHuman(addedHuman), nil
}
func (c *Commands) addHuman(ctx context.Context, orgID string, human *domain.Human, orgIAMPolicy *domain.OrgIAMPolicy, pwPolicy *domain.PasswordComplexityPolicy) ([]eventstore.EventPusher, *HumanWriteModel, error) {
if orgID == "" || !human.IsValid() {
return nil, nil, caos_errs.ThrowInvalidArgument(nil, "COMMAND-4M90d", "Errors.User.Invalid")
}
if human.Password != nil && human.SecretString != "" {
human.ChangeRequired = true
}
return c.createHuman(ctx, orgID, human, nil, false, orgIAMPolicy, pwPolicy)
}
func (c *Commands) importHuman(ctx context.Context, orgID string, human *domain.Human, orgIAMPolicy *domain.OrgIAMPolicy, pwPolicy *domain.PasswordComplexityPolicy) ([]eventstore.EventPusher, *HumanWriteModel, error) {
if orgID == "" || !human.IsValid() {
return nil, nil, caos_errs.ThrowInvalidArgument(nil, "COMMAND-4M90d", "Errors.User.Invalid")
}
@@ -104,6 +143,9 @@ func (c *Commands) registerHuman(ctx context.Context, orgID string, human *domai
if err != nil {
return nil, nil, caos_errs.ThrowPreconditionFailed(err, "COMMAND-M5Fsd", "Errors.Org.PasswordComplexity.NotFound")
}
if human.Password != nil && human.SecretString != "" {
human.ChangeRequired = false
}
return c.createHuman(ctx, orgID, human, externalIDP, true, orgIAMPolicy, pwPolicy)
}
@@ -117,9 +159,12 @@ func (c *Commands) createHuman(ctx context.Context, orgID string, human *domain.
}
human.AggregateID = userID
human.SetNamesAsDisplayname()
if err := human.HashPasswordIfExisting(pwPolicy, c.userPasswordAlg, !selfregister); err != nil {
return nil, nil, err
if human.Password != nil {
if err := human.HashPasswordIfExisting(pwPolicy, c.userPasswordAlg, human.ChangeRequired); err != nil {
return nil, nil, err
}
}
addedHuman := NewHumanWriteModel(human.AggregateID, orgID)
//TODO: adlerhurst maybe we could simplify the code below
userAgg := UserAggregateFromWriteModel(&addedHuman.WriteModel)

View File

@@ -171,51 +171,6 @@ func TestCommandSide_AddHuman(t *testing.T) {
err: caos_errs.IsErrorInvalidArgument,
},
},
{
name: "org policy check failed, precondition error",
fields: fields{
eventstore: eventstoreExpect(
t,
expectFilter(
eventFromEventPusher(
org.NewOrgIAMPolicyAddedEvent(context.Background(),
&user.NewAggregate("user1", "org1").Aggregate,
true,
),
),
),
expectFilter(
eventFromEventPusher(
org.NewPasswordComplexityPolicyAddedEvent(context.Background(),
&user.NewAggregate("user1", "org1").Aggregate,
1,
false,
false,
false,
false,
),
),
),
),
},
args: args{
ctx: context.Background(),
orgID: "org1",
human: &domain.Human{
Username: "email@test.ch",
Profile: &domain.Profile{
FirstName: "firstname",
LastName: "lastname",
},
Email: &domain.Email{
EmailAddress: "email@test.ch",
},
},
},
res: res{
err: caos_errs.IsPreconditionFailed,
},
},
{
name: "add human (with initial code), ok",
fields: fields{
@@ -695,6 +650,553 @@ func TestCommandSide_AddHuman(t *testing.T) {
}
}
func TestCommandSide_ImportHuman(t *testing.T) {
type fields struct {
eventstore *eventstore.Eventstore
idGenerator id.Generator
secretGenerator crypto.Generator
userPasswordAlg crypto.HashAlgorithm
}
type args struct {
ctx context.Context
orgID string
human *domain.Human
}
type res struct {
want *domain.Human
err func(error) bool
}
tests := []struct {
name string
fields fields
args args
res res
}{
{
name: "orgid missing, invalid argument error",
fields: fields{
eventstore: eventstoreExpect(
t,
),
},
args: args{
ctx: context.Background(),
orgID: "",
human: &domain.Human{
Username: "username",
Profile: &domain.Profile{
FirstName: "firstname",
LastName: "lastname",
},
Email: &domain.Email{
EmailAddress: "email@test.ch",
},
},
},
res: res{
err: caos_errs.IsErrorInvalidArgument,
},
},
{
name: "org policy not found, precondition error",
fields: fields{
eventstore: eventstoreExpect(
t,
expectFilter(),
expectFilter(),
),
},
args: args{
ctx: context.Background(),
orgID: "org1",
human: &domain.Human{
Username: "username",
Profile: &domain.Profile{
FirstName: "firstname",
LastName: "lastname",
},
Email: &domain.Email{
EmailAddress: "email@test.ch",
},
},
},
res: res{
err: caos_errs.IsPreconditionFailed,
},
},
{
name: "password policy not found, precondition error",
fields: fields{
eventstore: eventstoreExpect(
t,
expectFilter(
eventFromEventPusher(
org.NewOrgIAMPolicyAddedEvent(context.Background(),
&user.NewAggregate("user1", "org1").Aggregate,
true,
),
),
),
expectFilter(),
expectFilter(),
),
},
args: args{
ctx: context.Background(),
orgID: "org1",
human: &domain.Human{
Username: "username",
Profile: &domain.Profile{
FirstName: "firstname",
LastName: "lastname",
},
Email: &domain.Email{
EmailAddress: "email@test.ch",
},
},
},
res: res{
err: caos_errs.IsPreconditionFailed,
},
},
{
name: "user invalid, invalid argument error",
fields: fields{
eventstore: eventstoreExpect(
t,
expectFilter(
eventFromEventPusher(
org.NewOrgIAMPolicyAddedEvent(context.Background(),
&user.NewAggregate("user1", "org1").Aggregate,
true,
),
),
),
expectFilter(
eventFromEventPusher(
org.NewPasswordComplexityPolicyAddedEvent(context.Background(),
&user.NewAggregate("user1", "org1").Aggregate,
1,
false,
false,
false,
false,
),
),
),
),
},
args: args{
ctx: context.Background(),
orgID: "org1",
human: &domain.Human{
Username: "username",
Profile: &domain.Profile{
FirstName: "firstname",
},
},
},
res: res{
err: caos_errs.IsErrorInvalidArgument,
},
},
{
name: "add human (with password and initial code), ok",
fields: fields{
eventstore: eventstoreExpect(
t,
expectFilter(
eventFromEventPusher(
org.NewOrgIAMPolicyAddedEvent(context.Background(),
&user.NewAggregate("user1", "org1").Aggregate,
true,
),
),
),
expectFilter(
eventFromEventPusher(
org.NewPasswordComplexityPolicyAddedEvent(context.Background(),
&user.NewAggregate("user1", "org1").Aggregate,
1,
false,
false,
false,
false,
),
),
),
expectPush(
[]*repository.Event{
eventFromEventPusher(
newAddHumanEvent("password", true, ""),
),
eventFromEventPusher(
user.NewHumanInitialCodeAddedEvent(context.Background(),
&user.NewAggregate("user1", "org1").Aggregate,
&crypto.CryptoValue{
CryptoType: crypto.TypeEncryption,
Algorithm: "enc",
KeyID: "id",
Crypted: []byte("a"),
},
time.Hour*1,
),
),
},
uniqueConstraintsFromEventConstraint(user.NewAddUsernameUniqueConstraint("username", "org1", true)),
),
),
idGenerator: id_mock.NewIDGeneratorExpectIDs(t, "user1"),
secretGenerator: GetMockSecretGenerator(t),
userPasswordAlg: crypto.CreateMockHashAlg(gomock.NewController(t)),
},
args: args{
ctx: context.Background(),
orgID: "org1",
human: &domain.Human{
Username: "username",
Password: &domain.Password{
SecretString: "password",
ChangeRequired: true,
},
Profile: &domain.Profile{
FirstName: "firstname",
LastName: "lastname",
},
Email: &domain.Email{
EmailAddress: "email@test.ch",
},
},
},
res: res{
want: &domain.Human{
ObjectRoot: models.ObjectRoot{
AggregateID: "user1",
ResourceOwner: "org1",
},
Username: "username",
Profile: &domain.Profile{
FirstName: "firstname",
LastName: "lastname",
DisplayName: "firstname lastname",
PreferredLanguage: language.Und,
},
Email: &domain.Email{
EmailAddress: "email@test.ch",
},
State: domain.UserStateInitial,
},
},
},
{
name: "add human email verified password change not required, ok",
fields: fields{
eventstore: eventstoreExpect(
t,
expectFilter(
eventFromEventPusher(
org.NewOrgIAMPolicyAddedEvent(context.Background(),
&user.NewAggregate("user1", "org1").Aggregate,
true,
),
),
),
expectFilter(
eventFromEventPusher(
org.NewPasswordComplexityPolicyAddedEvent(context.Background(),
&user.NewAggregate("user1", "org1").Aggregate,
1,
false,
false,
false,
false,
),
),
),
expectPush(
[]*repository.Event{
eventFromEventPusher(
newAddHumanEvent("password", false, ""),
),
eventFromEventPusher(
user.NewHumanEmailVerifiedEvent(context.Background(),
&user.NewAggregate("user1", "org1").Aggregate),
),
},
uniqueConstraintsFromEventConstraint(user.NewAddUsernameUniqueConstraint("username", "org1", true)),
),
),
idGenerator: id_mock.NewIDGeneratorExpectIDs(t, "user1"),
secretGenerator: GetMockSecretGenerator(t),
userPasswordAlg: crypto.CreateMockHashAlg(gomock.NewController(t)),
},
args: args{
ctx: context.Background(),
orgID: "org1",
human: &domain.Human{
Username: "username",
Password: &domain.Password{
SecretString: "password",
ChangeRequired: false,
},
Profile: &domain.Profile{
FirstName: "firstname",
LastName: "lastname",
},
Email: &domain.Email{
EmailAddress: "email@test.ch",
IsEmailVerified: true,
},
},
},
res: res{
want: &domain.Human{
ObjectRoot: models.ObjectRoot{
AggregateID: "user1",
ResourceOwner: "org1",
},
Username: "username",
Profile: &domain.Profile{
FirstName: "firstname",
LastName: "lastname",
DisplayName: "firstname lastname",
PreferredLanguage: language.Und,
},
Email: &domain.Email{
EmailAddress: "email@test.ch",
IsEmailVerified: true,
},
State: domain.UserStateActive,
},
},
},
{
name: "add human (with phone), ok",
fields: fields{
eventstore: eventstoreExpect(
t,
expectFilter(
eventFromEventPusher(
org.NewOrgIAMPolicyAddedEvent(context.Background(),
&user.NewAggregate("user1", "org1").Aggregate,
true,
),
),
),
expectFilter(
eventFromEventPusher(
org.NewPasswordComplexityPolicyAddedEvent(context.Background(),
&user.NewAggregate("user1", "org1").Aggregate,
1,
false,
false,
false,
false,
),
),
),
expectPush(
[]*repository.Event{
eventFromEventPusher(
newAddHumanEvent("password", false, "+41711234567"),
),
eventFromEventPusher(
user.NewHumanInitialCodeAddedEvent(context.Background(),
&user.NewAggregate("user1", "org1").Aggregate,
&crypto.CryptoValue{
CryptoType: crypto.TypeEncryption,
Algorithm: "enc",
KeyID: "id",
Crypted: []byte("a"),
},
time.Hour*1,
),
),
eventFromEventPusher(
user.NewHumanPhoneCodeAddedEvent(context.Background(),
&user.NewAggregate("user1", "org1").Aggregate,
&crypto.CryptoValue{
CryptoType: crypto.TypeEncryption,
Algorithm: "enc",
KeyID: "id",
Crypted: []byte("a"),
},
time.Hour*1)),
},
uniqueConstraintsFromEventConstraint(user.NewAddUsernameUniqueConstraint("username", "org1", true)),
),
),
idGenerator: id_mock.NewIDGeneratorExpectIDs(t, "user1"),
secretGenerator: GetMockSecretGenerator(t),
userPasswordAlg: crypto.CreateMockHashAlg(gomock.NewController(t)),
},
args: args{
ctx: context.Background(),
orgID: "org1",
human: &domain.Human{
Username: "username",
Profile: &domain.Profile{
FirstName: "firstname",
LastName: "lastname",
},
Password: &domain.Password{
SecretString: "password",
ChangeRequired: false,
},
Email: &domain.Email{
EmailAddress: "email@test.ch",
},
Phone: &domain.Phone{
PhoneNumber: "+41711234567",
},
},
},
res: res{
want: &domain.Human{
ObjectRoot: models.ObjectRoot{
AggregateID: "user1",
ResourceOwner: "org1",
},
Username: "username",
Profile: &domain.Profile{
FirstName: "firstname",
LastName: "lastname",
DisplayName: "firstname lastname",
PreferredLanguage: language.Und,
},
Email: &domain.Email{
EmailAddress: "email@test.ch",
},
Phone: &domain.Phone{
PhoneNumber: "+41711234567",
},
State: domain.UserStateInitial,
},
},
},
{
name: "add human (with verified phone), ok",
fields: fields{
eventstore: eventstoreExpect(
t,
expectFilter(
eventFromEventPusher(
org.NewOrgIAMPolicyAddedEvent(context.Background(),
&user.NewAggregate("user1", "org1").Aggregate,
true,
),
),
),
expectFilter(
eventFromEventPusher(
org.NewPasswordComplexityPolicyAddedEvent(context.Background(),
&user.NewAggregate("user1", "org1").Aggregate,
1,
false,
false,
false,
false,
),
),
),
expectPush(
[]*repository.Event{
eventFromEventPusher(
newAddHumanEvent("password", false, "+41711234567"),
),
eventFromEventPusher(
user.NewHumanInitialCodeAddedEvent(context.Background(),
&user.NewAggregate("user1", "org1").Aggregate,
&crypto.CryptoValue{
CryptoType: crypto.TypeEncryption,
Algorithm: "enc",
KeyID: "id",
Crypted: []byte("a"),
},
time.Hour*1,
),
),
eventFromEventPusher(
user.NewHumanPhoneVerifiedEvent(context.Background(),
&user.NewAggregate("user1", "org1").Aggregate),
),
},
uniqueConstraintsFromEventConstraint(user.NewAddUsernameUniqueConstraint("username", "org1", true)),
),
),
idGenerator: id_mock.NewIDGeneratorExpectIDs(t, "user1"),
secretGenerator: GetMockSecretGenerator(t),
userPasswordAlg: crypto.CreateMockHashAlg(gomock.NewController(t)),
},
args: args{
ctx: context.Background(),
orgID: "org1",
human: &domain.Human{
Username: "username",
Profile: &domain.Profile{
FirstName: "firstname",
LastName: "lastname",
},
Password: &domain.Password{
SecretString: "password",
ChangeRequired: false,
},
Email: &domain.Email{
EmailAddress: "email@test.ch",
},
Phone: &domain.Phone{
PhoneNumber: "+41711234567",
IsPhoneVerified: true,
},
},
},
res: res{
want: &domain.Human{
ObjectRoot: models.ObjectRoot{
AggregateID: "user1",
ResourceOwner: "org1",
},
Username: "username",
Profile: &domain.Profile{
FirstName: "firstname",
LastName: "lastname",
DisplayName: "firstname lastname",
PreferredLanguage: language.Und,
},
Email: &domain.Email{
EmailAddress: "email@test.ch",
},
Phone: &domain.Phone{
PhoneNumber: "+41711234567",
},
State: domain.UserStateInitial,
},
},
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
r := &Commands{
eventstore: tt.fields.eventstore,
idGenerator: tt.fields.idGenerator,
initializeUserCode: tt.fields.secretGenerator,
phoneVerificationCode: tt.fields.secretGenerator,
userPasswordAlg: tt.fields.userPasswordAlg,
}
got, err := r.ImportHuman(tt.args.ctx, tt.args.orgID, tt.args.human)
if tt.res.err == nil {
assert.NoError(t, err)
}
if tt.res.err != nil && !tt.res.err(err) {
t.Errorf("got wrong err: %v ", err)
}
if tt.res.err == nil {
assert.Equal(t, tt.res.want, got)
}
})
}
}
func TestCommandSide_RegisterHuman(t *testing.T) {
type fields struct {
eventstore *eventstore.Eventstore
@@ -836,54 +1338,6 @@ func TestCommandSide_RegisterHuman(t *testing.T) {
err: caos_errs.IsPreconditionFailed,
},
},
{
name: "org policy check failed, precondition error",
fields: fields{
eventstore: eventstoreExpect(
t,
expectFilter(
eventFromEventPusher(
org.NewOrgIAMPolicyAddedEvent(context.Background(),
&org.NewAggregate("org1", "org1").Aggregate,
true,
),
),
),
expectFilter(
eventFromEventPusher(
org.NewPasswordComplexityPolicyAddedEvent(context.Background(),
&org.NewAggregate("org1", "org1").Aggregate,
1,
false,
false,
false,
false,
),
),
),
),
},
args: args{
ctx: context.Background(),
orgID: "org1",
human: &domain.Human{
Username: "email@test.ch",
Profile: &domain.Profile{
FirstName: "firstname",
LastName: "lastname",
},
Email: &domain.Email{
EmailAddress: "email@test.ch",
},
Password: &domain.Password{
SecretString: "password",
},
},
},
res: res{
err: caos_errs.IsPreconditionFailed,
},
},
{
name: "add human (with password and initial code), ok",
fields: fields{