mirror of
https://github.com/zitadel/zitadel.git
synced 2025-08-12 00:47:33 +00:00
feat: custom domain feature (#1618)
* fix: custom domain * fix: custom domain * fix: custom domain * fix: custom domain feature in proto * fix: remove custom domains on feature downgrade * fix test * fix: custom domain feature in proto * ensure tests work Co-authored-by: fabi <fabienne.gerschwiler@gmail.com>
This commit is contained in:
@@ -23,6 +23,7 @@ type FeaturesWriteModel struct {
|
||||
LoginPolicyUsernameLogin bool
|
||||
PasswordComplexityPolicy bool
|
||||
LabelPolicy bool
|
||||
CustomDomain bool
|
||||
}
|
||||
|
||||
func (wm *FeaturesWriteModel) Reduce() error {
|
||||
@@ -66,6 +67,9 @@ func (wm *FeaturesWriteModel) Reduce() error {
|
||||
if e.LabelPolicy != nil {
|
||||
wm.LabelPolicy = *e.LabelPolicy
|
||||
}
|
||||
if e.CustomDomain != nil {
|
||||
wm.CustomDomain = *e.CustomDomain
|
||||
}
|
||||
case *features.FeaturesRemovedEvent:
|
||||
wm.State = domain.FeaturesStateRemoved
|
||||
}
|
||||
|
@@ -47,6 +47,7 @@ func (c *Commands) setDefaultFeatures(ctx context.Context, existingFeatures *IAM
|
||||
features.LoginPolicyUsernameLogin,
|
||||
features.PasswordComplexityPolicy,
|
||||
features.LabelPolicy,
|
||||
features.CustomDomain,
|
||||
)
|
||||
if !hasChanged {
|
||||
return nil, caos_errs.ThrowPreconditionFailed(nil, "Features-GE4h2", "Errors.Features.NotChanged")
|
||||
|
@@ -62,7 +62,8 @@ func (wm *IAMFeaturesWriteModel) NewSetEvent(
|
||||
loginPolicyRegistration,
|
||||
loginPolicyUsernameLogin,
|
||||
passwordComplexityPolicy,
|
||||
labelPolicy bool,
|
||||
labelPolicy,
|
||||
customDomain bool,
|
||||
) (*iam.FeaturesSetEvent, bool) {
|
||||
|
||||
changes := make([]features.FeaturesChanges, 0)
|
||||
@@ -103,6 +104,9 @@ func (wm *IAMFeaturesWriteModel) NewSetEvent(
|
||||
if wm.LabelPolicy != labelPolicy {
|
||||
changes = append(changes, features.ChangeLabelPolicy(labelPolicy))
|
||||
}
|
||||
if wm.CustomDomain != customDomain {
|
||||
changes = append(changes, features.ChangeCustomDomain(customDomain))
|
||||
}
|
||||
|
||||
if len(changes) == 0 {
|
||||
return nil, false
|
||||
|
@@ -2,13 +2,14 @@ package command
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/caos/logging"
|
||||
"github.com/caos/zitadel/internal/eventstore"
|
||||
|
||||
http_utils "github.com/caos/zitadel/internal/api/http"
|
||||
"github.com/caos/zitadel/internal/crypto"
|
||||
"github.com/caos/zitadel/internal/domain"
|
||||
caos_errs "github.com/caos/zitadel/internal/errors"
|
||||
"github.com/caos/zitadel/internal/eventstore"
|
||||
"github.com/caos/zitadel/internal/repository/org"
|
||||
)
|
||||
|
||||
@@ -206,6 +207,38 @@ func (c *Commands) addOrgDomain(ctx context.Context, orgAgg *eventstore.Aggregat
|
||||
return events, nil
|
||||
}
|
||||
|
||||
func (c *Commands) removeCustomDomains(ctx context.Context, orgID string) ([]eventstore.EventPusher, error) {
|
||||
orgDomains := NewOrgDomainsWriteModel(orgID)
|
||||
err := c.eventstore.FilterToQueryReducer(ctx, orgDomains)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
hasDefault := false
|
||||
defaultDomain := domain.NewIAMDomainName(orgDomains.OrgName, c.iamDomain)
|
||||
isPrimary := defaultDomain == orgDomains.PrimaryDomain
|
||||
orgAgg := OrgAggregateFromWriteModel(&orgDomains.WriteModel)
|
||||
events := make([]eventstore.EventPusher, 0, len(orgDomains.Domains))
|
||||
for _, orgDomain := range orgDomains.Domains {
|
||||
if orgDomain.State == domain.OrgDomainStateActive {
|
||||
if orgDomain.Domain == defaultDomain {
|
||||
hasDefault = true
|
||||
continue
|
||||
}
|
||||
events = append(events, org.NewDomainRemovedEvent(ctx, orgAgg, orgDomain.Domain, orgDomain.Verified))
|
||||
}
|
||||
}
|
||||
if !hasDefault {
|
||||
return append([]eventstore.EventPusher{
|
||||
org.NewDomainAddedEvent(ctx, orgAgg, defaultDomain),
|
||||
org.NewDomainPrimarySetEvent(ctx, orgAgg, defaultDomain),
|
||||
}, events...), nil
|
||||
}
|
||||
if !isPrimary {
|
||||
return append([]eventstore.EventPusher{org.NewDomainPrimarySetEvent(ctx, orgAgg, defaultDomain)}, events...), nil
|
||||
}
|
||||
return events, nil
|
||||
}
|
||||
|
||||
func (c *Commands) getOrgDomainWriteModel(ctx context.Context, orgID, domain string) (*OrgDomainWriteModel, error) {
|
||||
domainWriteModel := NewOrgDomainWriteModel(orgID, domain)
|
||||
err := c.eventstore.FilterToQueryReducer(ctx, domainWriteModel)
|
||||
|
@@ -95,3 +95,72 @@ func (wm *OrgDomainWriteModel) Query() *eventstore.SearchQueryBuilder {
|
||||
org.OrgDomainPrimarySetEventType,
|
||||
org.OrgDomainRemovedEventType)
|
||||
}
|
||||
|
||||
type OrgDomainsWriteModel struct {
|
||||
eventstore.WriteModel
|
||||
|
||||
Domains []*Domain
|
||||
PrimaryDomain string
|
||||
OrgName string
|
||||
}
|
||||
|
||||
type Domain struct {
|
||||
Domain string
|
||||
Verified bool
|
||||
State domain.OrgDomainState
|
||||
}
|
||||
|
||||
func NewOrgDomainsWriteModel(orgID string) *OrgDomainsWriteModel {
|
||||
return &OrgDomainsWriteModel{
|
||||
WriteModel: eventstore.WriteModel{
|
||||
AggregateID: orgID,
|
||||
ResourceOwner: orgID,
|
||||
},
|
||||
Domains: make([]*Domain, 0),
|
||||
}
|
||||
}
|
||||
|
||||
func (wm *OrgDomainsWriteModel) Reduce() error {
|
||||
for _, event := range wm.Events {
|
||||
switch e := event.(type) {
|
||||
case *org.OrgAddedEvent:
|
||||
wm.OrgName = e.Name
|
||||
case *org.OrgChangedEvent:
|
||||
wm.OrgName = e.Name
|
||||
case *org.DomainAddedEvent:
|
||||
wm.Domains = append(wm.Domains, &Domain{Domain: e.Domain, State: domain.OrgDomainStateActive})
|
||||
case *org.DomainVerifiedEvent:
|
||||
for _, d := range wm.Domains {
|
||||
if d.Domain == e.Domain {
|
||||
d.Verified = true
|
||||
continue
|
||||
}
|
||||
}
|
||||
case *org.DomainPrimarySetEvent:
|
||||
wm.PrimaryDomain = e.Domain
|
||||
case *org.DomainRemovedEvent:
|
||||
for _, d := range wm.Domains {
|
||||
if d.Domain == e.Domain {
|
||||
d.State = domain.OrgDomainStateRemoved
|
||||
continue
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (wm *OrgDomainsWriteModel) Query() *eventstore.SearchQueryBuilder {
|
||||
return eventstore.NewSearchQueryBuilder(eventstore.ColumnsEvent, org.AggregateType).
|
||||
AggregateIDs(wm.AggregateID).
|
||||
ResourceOwner(wm.ResourceOwner).
|
||||
EventTypes(
|
||||
org.OrgAddedEventType,
|
||||
org.OrgChangedEventType,
|
||||
org.OrgDomainAddedEventType,
|
||||
org.OrgDomainVerifiedEventType,
|
||||
org.OrgDomainVerificationAddedEventType,
|
||||
org.OrgDomainVerifiedEventType,
|
||||
org.OrgDomainPrimarySetEventType,
|
||||
org.OrgDomainRemovedEventType)
|
||||
}
|
||||
|
@@ -113,6 +113,15 @@ func (c *Commands) ensureOrgSettingsToFeatures(ctx context.Context, orgID string
|
||||
events = append(events, removeLabelPolicyEvent)
|
||||
}
|
||||
}
|
||||
if !features.CustomDomain {
|
||||
removeCustomDomainsEvents, err := c.removeCustomDomains(ctx, orgID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if removeCustomDomainsEvents != nil {
|
||||
events = append(events, removeCustomDomainsEvents...)
|
||||
}
|
||||
}
|
||||
return events, nil
|
||||
}
|
||||
|
||||
|
@@ -19,6 +19,7 @@ import (
|
||||
func TestCommandSide_SetOrgFeatures(t *testing.T) {
|
||||
type fields struct {
|
||||
eventstore *eventstore.Eventstore
|
||||
iamDomain string
|
||||
}
|
||||
type args struct {
|
||||
ctx context.Context
|
||||
@@ -55,6 +56,7 @@ func TestCommandSide_SetOrgFeatures(t *testing.T) {
|
||||
LoginPolicyUsernameLogin: false,
|
||||
PasswordComplexityPolicy: false,
|
||||
LabelPolicy: false,
|
||||
CustomDomain: false,
|
||||
},
|
||||
},
|
||||
res: res{
|
||||
@@ -87,6 +89,7 @@ func TestCommandSide_SetOrgFeatures(t *testing.T) {
|
||||
LoginPolicyUsernameLogin: false,
|
||||
PasswordComplexityPolicy: false,
|
||||
LabelPolicy: false,
|
||||
CustomDomain: false,
|
||||
},
|
||||
},
|
||||
res: res{
|
||||
@@ -136,6 +139,36 @@ func TestCommandSide_SetOrgFeatures(t *testing.T) {
|
||||
),
|
||||
),
|
||||
),
|
||||
expectFilter(
|
||||
eventFromEventPusher(
|
||||
org.NewOrgAddedEvent(
|
||||
context.Background(),
|
||||
&org.NewAggregate("org1", "org1").Aggregate,
|
||||
"org1",
|
||||
),
|
||||
),
|
||||
eventFromEventPusher(
|
||||
org.NewDomainAddedEvent(
|
||||
context.Background(),
|
||||
&org.NewAggregate("org1", "org1").Aggregate,
|
||||
"org1.iam-domain",
|
||||
),
|
||||
),
|
||||
eventFromEventPusher(
|
||||
org.NewDomainVerifiedEvent(
|
||||
context.Background(),
|
||||
&org.NewAggregate("org1", "org1").Aggregate,
|
||||
"org1.iam-domain",
|
||||
),
|
||||
),
|
||||
eventFromEventPusher(
|
||||
org.NewDomainPrimarySetEvent(
|
||||
context.Background(),
|
||||
&org.NewAggregate("org1", "org1").Aggregate,
|
||||
"org1.iam-domain",
|
||||
),
|
||||
),
|
||||
),
|
||||
expectPush(
|
||||
[]*repository.Event{
|
||||
eventFromEventPusher(
|
||||
@@ -144,6 +177,7 @@ func TestCommandSide_SetOrgFeatures(t *testing.T) {
|
||||
},
|
||||
),
|
||||
),
|
||||
iamDomain: "iam-domain",
|
||||
},
|
||||
args: args{
|
||||
ctx: context.Background(),
|
||||
@@ -159,6 +193,439 @@ func TestCommandSide_SetOrgFeatures(t *testing.T) {
|
||||
LoginPolicyUsernameLogin: false,
|
||||
PasswordComplexityPolicy: false,
|
||||
LabelPolicy: false,
|
||||
CustomDomain: false,
|
||||
},
|
||||
},
|
||||
res: res{
|
||||
want: &domain.ObjectDetails{
|
||||
ResourceOwner: "org1",
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "set with default policies, custom domains, ok",
|
||||
fields: fields{
|
||||
eventstore: eventstoreExpect(
|
||||
t,
|
||||
expectFilter(),
|
||||
expectFilter(
|
||||
eventFromEventPusher(
|
||||
iam.NewLoginPolicyAddedEvent(
|
||||
context.Background(),
|
||||
&iam.NewAggregate().Aggregate,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
domain.PasswordlessTypeAllowed,
|
||||
),
|
||||
),
|
||||
),
|
||||
expectFilter(
|
||||
eventFromEventPusher(
|
||||
iam.NewPasswordComplexityPolicyAddedEvent(
|
||||
context.Background(),
|
||||
&iam.NewAggregate().Aggregate,
|
||||
8,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
),
|
||||
),
|
||||
),
|
||||
expectFilter(
|
||||
eventFromEventPusher(
|
||||
iam.NewLabelPolicyAddedEvent(
|
||||
context.Background(),
|
||||
&iam.NewAggregate().Aggregate,
|
||||
"primary",
|
||||
"secondary",
|
||||
false,
|
||||
),
|
||||
),
|
||||
),
|
||||
expectFilter(
|
||||
eventFromEventPusher(
|
||||
org.NewOrgAddedEvent(
|
||||
context.Background(),
|
||||
&org.NewAggregate("org1", "org1").Aggregate,
|
||||
"org1",
|
||||
),
|
||||
),
|
||||
eventFromEventPusher(
|
||||
org.NewDomainAddedEvent(
|
||||
context.Background(),
|
||||
&org.NewAggregate("org1", "org1").Aggregate,
|
||||
"org1.iam-domain",
|
||||
),
|
||||
),
|
||||
eventFromEventPusher(
|
||||
org.NewDomainVerifiedEvent(
|
||||
context.Background(),
|
||||
&org.NewAggregate("org1", "org1").Aggregate,
|
||||
"org1.iam-domain",
|
||||
),
|
||||
),
|
||||
eventFromEventPusher(
|
||||
org.NewDomainPrimarySetEvent(
|
||||
context.Background(),
|
||||
&org.NewAggregate("org1", "org1").Aggregate,
|
||||
"org1.iam-domain",
|
||||
),
|
||||
),
|
||||
eventFromEventPusher(
|
||||
org.NewDomainAddedEvent(
|
||||
context.Background(),
|
||||
&org.NewAggregate("org1", "org1").Aggregate,
|
||||
"test1",
|
||||
),
|
||||
),
|
||||
eventFromEventPusher(
|
||||
org.NewDomainVerifiedEvent(
|
||||
context.Background(),
|
||||
&org.NewAggregate("org1", "org1").Aggregate,
|
||||
"test1",
|
||||
),
|
||||
),
|
||||
eventFromEventPusher(
|
||||
org.NewDomainAddedEvent(
|
||||
context.Background(),
|
||||
&org.NewAggregate("org1", "org1").Aggregate,
|
||||
"test2",
|
||||
),
|
||||
),
|
||||
),
|
||||
expectPush(
|
||||
[]*repository.Event{
|
||||
eventFromEventPusher(
|
||||
org.NewDomainRemovedEvent(context.Background(), &org.NewAggregate("org1", "org1").Aggregate, "test1", true),
|
||||
),
|
||||
eventFromEventPusher(
|
||||
org.NewDomainRemovedEvent(context.Background(), &org.NewAggregate("org1", "org1").Aggregate, "test2", false),
|
||||
),
|
||||
eventFromEventPusher(
|
||||
newFeaturesSetEvent(context.Background(), "org1", "Test", domain.FeaturesStateActive, time.Hour),
|
||||
),
|
||||
},
|
||||
uniqueConstraintsFromEventConstraint(org.NewRemoveOrgDomainUniqueConstraint("test1")),
|
||||
),
|
||||
),
|
||||
iamDomain: "iam-domain",
|
||||
},
|
||||
args: args{
|
||||
ctx: context.Background(),
|
||||
resourceOwner: "org1",
|
||||
features: &domain.Features{
|
||||
TierName: "Test",
|
||||
State: domain.FeaturesStateActive,
|
||||
AuditLogRetention: time.Hour,
|
||||
LoginPolicyFactors: false,
|
||||
LoginPolicyIDP: false,
|
||||
LoginPolicyPasswordless: false,
|
||||
LoginPolicyRegistration: false,
|
||||
LoginPolicyUsernameLogin: false,
|
||||
PasswordComplexityPolicy: false,
|
||||
LabelPolicy: false,
|
||||
CustomDomain: false,
|
||||
},
|
||||
},
|
||||
res: res{
|
||||
want: &domain.ObjectDetails{
|
||||
ResourceOwner: "org1",
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "set with default policies, custom domains, default not primary, ok",
|
||||
fields: fields{
|
||||
eventstore: eventstoreExpect(
|
||||
t,
|
||||
expectFilter(),
|
||||
expectFilter(
|
||||
eventFromEventPusher(
|
||||
iam.NewLoginPolicyAddedEvent(
|
||||
context.Background(),
|
||||
&iam.NewAggregate().Aggregate,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
domain.PasswordlessTypeAllowed,
|
||||
),
|
||||
),
|
||||
),
|
||||
expectFilter(
|
||||
eventFromEventPusher(
|
||||
iam.NewPasswordComplexityPolicyAddedEvent(
|
||||
context.Background(),
|
||||
&iam.NewAggregate().Aggregate,
|
||||
8,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
),
|
||||
),
|
||||
),
|
||||
expectFilter(
|
||||
eventFromEventPusher(
|
||||
iam.NewLabelPolicyAddedEvent(
|
||||
context.Background(),
|
||||
&iam.NewAggregate().Aggregate,
|
||||
"primary",
|
||||
"secondary",
|
||||
false,
|
||||
),
|
||||
),
|
||||
),
|
||||
expectFilter(
|
||||
eventFromEventPusher(
|
||||
org.NewOrgAddedEvent(
|
||||
context.Background(),
|
||||
&org.NewAggregate("org1", "org1").Aggregate,
|
||||
"org1",
|
||||
),
|
||||
),
|
||||
eventFromEventPusher(
|
||||
org.NewDomainAddedEvent(
|
||||
context.Background(),
|
||||
&org.NewAggregate("org1", "org1").Aggregate,
|
||||
"org1.iam-domain",
|
||||
),
|
||||
),
|
||||
eventFromEventPusher(
|
||||
org.NewDomainVerifiedEvent(
|
||||
context.Background(),
|
||||
&org.NewAggregate("org1", "org1").Aggregate,
|
||||
"org1.iam-domain",
|
||||
),
|
||||
),
|
||||
eventFromEventPusher(
|
||||
org.NewDomainPrimarySetEvent(
|
||||
context.Background(),
|
||||
&org.NewAggregate("org1", "org1").Aggregate,
|
||||
"org1.iam-domain",
|
||||
),
|
||||
),
|
||||
eventFromEventPusher(
|
||||
org.NewDomainAddedEvent(
|
||||
context.Background(),
|
||||
&org.NewAggregate("org1", "org1").Aggregate,
|
||||
"test1",
|
||||
),
|
||||
),
|
||||
eventFromEventPusher(
|
||||
org.NewDomainVerifiedEvent(
|
||||
context.Background(),
|
||||
&org.NewAggregate("org1", "org1").Aggregate,
|
||||
"test1",
|
||||
),
|
||||
),
|
||||
eventFromEventPusher(
|
||||
org.NewDomainPrimarySetEvent(
|
||||
context.Background(),
|
||||
&org.NewAggregate("org1", "org1").Aggregate,
|
||||
"test1.iam-domain",
|
||||
),
|
||||
),
|
||||
eventFromEventPusher(
|
||||
org.NewDomainAddedEvent(
|
||||
context.Background(),
|
||||
&org.NewAggregate("org1", "org1").Aggregate,
|
||||
"test2",
|
||||
),
|
||||
),
|
||||
),
|
||||
expectPush(
|
||||
[]*repository.Event{
|
||||
eventFromEventPusher(
|
||||
org.NewDomainPrimarySetEvent(context.Background(), &org.NewAggregate("org1", "org1").Aggregate, "org1.iam-domain"),
|
||||
),
|
||||
eventFromEventPusher(
|
||||
org.NewDomainRemovedEvent(context.Background(), &org.NewAggregate("org1", "org1").Aggregate, "test1", true),
|
||||
),
|
||||
eventFromEventPusher(
|
||||
org.NewDomainRemovedEvent(context.Background(), &org.NewAggregate("org1", "org1").Aggregate, "test2", false),
|
||||
),
|
||||
eventFromEventPusher(
|
||||
newFeaturesSetEvent(context.Background(), "org1", "Test", domain.FeaturesStateActive, time.Hour),
|
||||
),
|
||||
},
|
||||
uniqueConstraintsFromEventConstraint(org.NewRemoveOrgDomainUniqueConstraint("test1")),
|
||||
),
|
||||
),
|
||||
iamDomain: "iam-domain",
|
||||
},
|
||||
args: args{
|
||||
ctx: context.Background(),
|
||||
resourceOwner: "org1",
|
||||
features: &domain.Features{
|
||||
TierName: "Test",
|
||||
State: domain.FeaturesStateActive,
|
||||
AuditLogRetention: time.Hour,
|
||||
LoginPolicyFactors: false,
|
||||
LoginPolicyIDP: false,
|
||||
LoginPolicyPasswordless: false,
|
||||
LoginPolicyRegistration: false,
|
||||
LoginPolicyUsernameLogin: false,
|
||||
PasswordComplexityPolicy: false,
|
||||
LabelPolicy: false,
|
||||
CustomDomain: false,
|
||||
},
|
||||
},
|
||||
res: res{
|
||||
want: &domain.ObjectDetails{
|
||||
ResourceOwner: "org1",
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "set with default policies, custom domains, default not existing, ok",
|
||||
fields: fields{
|
||||
eventstore: eventstoreExpect(
|
||||
t,
|
||||
expectFilter(),
|
||||
expectFilter(
|
||||
eventFromEventPusher(
|
||||
iam.NewLoginPolicyAddedEvent(
|
||||
context.Background(),
|
||||
&iam.NewAggregate().Aggregate,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
domain.PasswordlessTypeAllowed,
|
||||
),
|
||||
),
|
||||
),
|
||||
expectFilter(
|
||||
eventFromEventPusher(
|
||||
iam.NewPasswordComplexityPolicyAddedEvent(
|
||||
context.Background(),
|
||||
&iam.NewAggregate().Aggregate,
|
||||
8,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
),
|
||||
),
|
||||
),
|
||||
expectFilter(
|
||||
eventFromEventPusher(
|
||||
iam.NewLabelPolicyAddedEvent(
|
||||
context.Background(),
|
||||
&iam.NewAggregate().Aggregate,
|
||||
"primary",
|
||||
"secondary",
|
||||
false,
|
||||
),
|
||||
),
|
||||
),
|
||||
expectFilter(
|
||||
eventFromEventPusher(
|
||||
org.NewOrgAddedEvent(
|
||||
context.Background(),
|
||||
&org.NewAggregate("org1", "org1").Aggregate,
|
||||
"org1",
|
||||
),
|
||||
),
|
||||
eventFromEventPusher(
|
||||
org.NewDomainAddedEvent(
|
||||
context.Background(),
|
||||
&org.NewAggregate("org1", "org1").Aggregate,
|
||||
"org1.iam-domain",
|
||||
),
|
||||
),
|
||||
eventFromEventPusher(
|
||||
org.NewDomainVerifiedEvent(
|
||||
context.Background(),
|
||||
&org.NewAggregate("org1", "org1").Aggregate,
|
||||
"org1.iam-domain",
|
||||
),
|
||||
),
|
||||
eventFromEventPusher(
|
||||
org.NewDomainPrimarySetEvent(
|
||||
context.Background(),
|
||||
&org.NewAggregate("org1", "org1").Aggregate,
|
||||
"org1.iam-domain",
|
||||
),
|
||||
),
|
||||
eventFromEventPusher(
|
||||
org.NewDomainAddedEvent(
|
||||
context.Background(),
|
||||
&org.NewAggregate("org1", "org1").Aggregate,
|
||||
"test1",
|
||||
),
|
||||
),
|
||||
eventFromEventPusher(
|
||||
org.NewDomainVerifiedEvent(
|
||||
context.Background(),
|
||||
&org.NewAggregate("org1", "org1").Aggregate,
|
||||
"test1",
|
||||
),
|
||||
),
|
||||
eventFromEventPusher(
|
||||
org.NewDomainPrimarySetEvent(
|
||||
context.Background(),
|
||||
&org.NewAggregate("org1", "org1").Aggregate,
|
||||
"test1.iam-domain",
|
||||
),
|
||||
),
|
||||
eventFromEventPusher(
|
||||
org.NewDomainAddedEvent(
|
||||
context.Background(),
|
||||
&org.NewAggregate("org1", "org1").Aggregate,
|
||||
"test2",
|
||||
),
|
||||
),
|
||||
eventFromEventPusher(
|
||||
org.NewDomainRemovedEvent(
|
||||
context.Background(),
|
||||
&org.NewAggregate("org1", "org1").Aggregate,
|
||||
"org1.iam-domain", true,
|
||||
),
|
||||
),
|
||||
),
|
||||
expectPush(
|
||||
[]*repository.Event{
|
||||
eventFromEventPusher(
|
||||
org.NewDomainAddedEvent(context.Background(), &org.NewAggregate("org1", "org1").Aggregate, "org1.iam-domain"),
|
||||
),
|
||||
eventFromEventPusher(
|
||||
org.NewDomainPrimarySetEvent(context.Background(), &org.NewAggregate("org1", "org1").Aggregate, "org1.iam-domain"),
|
||||
),
|
||||
eventFromEventPusher(
|
||||
org.NewDomainRemovedEvent(context.Background(), &org.NewAggregate("org1", "org1").Aggregate, "test1", true),
|
||||
),
|
||||
eventFromEventPusher(
|
||||
org.NewDomainRemovedEvent(context.Background(), &org.NewAggregate("org1", "org1").Aggregate, "test2", false),
|
||||
),
|
||||
eventFromEventPusher(
|
||||
newFeaturesSetEvent(context.Background(), "org1", "Test", domain.FeaturesStateActive, time.Hour),
|
||||
),
|
||||
},
|
||||
uniqueConstraintsFromEventConstraint(org.NewRemoveOrgDomainUniqueConstraint("test1")),
|
||||
),
|
||||
),
|
||||
iamDomain: "iam-domain",
|
||||
},
|
||||
args: args{
|
||||
ctx: context.Background(),
|
||||
resourceOwner: "org1",
|
||||
features: &domain.Features{
|
||||
TierName: "Test",
|
||||
State: domain.FeaturesStateActive,
|
||||
AuditLogRetention: time.Hour,
|
||||
LoginPolicyFactors: false,
|
||||
LoginPolicyIDP: false,
|
||||
LoginPolicyPasswordless: false,
|
||||
LoginPolicyRegistration: false,
|
||||
LoginPolicyUsernameLogin: false,
|
||||
PasswordComplexityPolicy: false,
|
||||
LabelPolicy: false,
|
||||
CustomDomain: false,
|
||||
},
|
||||
},
|
||||
res: res{
|
||||
@@ -281,6 +748,36 @@ func TestCommandSide_SetOrgFeatures(t *testing.T) {
|
||||
),
|
||||
),
|
||||
),
|
||||
expectFilter(
|
||||
eventFromEventPusher(
|
||||
org.NewOrgAddedEvent(
|
||||
context.Background(),
|
||||
&org.NewAggregate("org1", "org1").Aggregate,
|
||||
"org1",
|
||||
),
|
||||
),
|
||||
eventFromEventPusher(
|
||||
org.NewDomainAddedEvent(
|
||||
context.Background(),
|
||||
&org.NewAggregate("org1", "org1").Aggregate,
|
||||
"org1.iam-domain",
|
||||
),
|
||||
),
|
||||
eventFromEventPusher(
|
||||
org.NewDomainVerifiedEvent(
|
||||
context.Background(),
|
||||
&org.NewAggregate("org1", "org1").Aggregate,
|
||||
"org1.iam-domain",
|
||||
),
|
||||
),
|
||||
eventFromEventPusher(
|
||||
org.NewDomainPrimarySetEvent(
|
||||
context.Background(),
|
||||
&org.NewAggregate("org1", "org1").Aggregate,
|
||||
"org1.iam-domain",
|
||||
),
|
||||
),
|
||||
),
|
||||
expectPush(
|
||||
[]*repository.Event{
|
||||
eventFromEventPusher(
|
||||
@@ -307,6 +804,7 @@ func TestCommandSide_SetOrgFeatures(t *testing.T) {
|
||||
},
|
||||
),
|
||||
),
|
||||
iamDomain: "iam-domain",
|
||||
},
|
||||
args: args{
|
||||
ctx: context.Background(),
|
||||
@@ -335,6 +833,7 @@ func TestCommandSide_SetOrgFeatures(t *testing.T) {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
r := &Commands{
|
||||
eventstore: tt.fields.eventstore,
|
||||
iamDomain: tt.fields.iamDomain,
|
||||
}
|
||||
got, err := r.SetOrgFeatures(tt.args.ctx, tt.args.resourceOwner, tt.args.features)
|
||||
if tt.res.err == nil {
|
||||
@@ -353,6 +852,7 @@ func TestCommandSide_SetOrgFeatures(t *testing.T) {
|
||||
func TestCommandSide_RemoveOrgFeatures(t *testing.T) {
|
||||
type fields struct {
|
||||
eventstore *eventstore.Eventstore
|
||||
iamDomain string
|
||||
}
|
||||
type args struct {
|
||||
ctx context.Context
|
||||
@@ -448,6 +948,36 @@ func TestCommandSide_RemoveOrgFeatures(t *testing.T) {
|
||||
),
|
||||
),
|
||||
),
|
||||
expectFilter(
|
||||
eventFromEventPusher(
|
||||
org.NewOrgAddedEvent(
|
||||
context.Background(),
|
||||
&org.NewAggregate("org1", "org1").Aggregate,
|
||||
"org1",
|
||||
),
|
||||
),
|
||||
eventFromEventPusher(
|
||||
org.NewDomainAddedEvent(
|
||||
context.Background(),
|
||||
&org.NewAggregate("org1", "org1").Aggregate,
|
||||
"org1.iam-domain",
|
||||
),
|
||||
),
|
||||
eventFromEventPusher(
|
||||
org.NewDomainVerifiedEvent(
|
||||
context.Background(),
|
||||
&org.NewAggregate("org1", "org1").Aggregate,
|
||||
"org1.iam-domain",
|
||||
),
|
||||
),
|
||||
eventFromEventPusher(
|
||||
org.NewDomainPrimarySetEvent(
|
||||
context.Background(),
|
||||
&org.NewAggregate("org1", "org1").Aggregate,
|
||||
"org1.iam-domain",
|
||||
),
|
||||
),
|
||||
),
|
||||
expectPush(
|
||||
[]*repository.Event{
|
||||
eventFromEventPusher(
|
||||
@@ -456,6 +986,7 @@ func TestCommandSide_RemoveOrgFeatures(t *testing.T) {
|
||||
},
|
||||
),
|
||||
),
|
||||
iamDomain: "iam-domain",
|
||||
},
|
||||
args: args{
|
||||
ctx: context.Background(),
|
||||
@@ -472,6 +1003,7 @@ func TestCommandSide_RemoveOrgFeatures(t *testing.T) {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
r := &Commands{
|
||||
eventstore: tt.fields.eventstore,
|
||||
iamDomain: tt.fields.iamDomain,
|
||||
}
|
||||
got, err := r.RemoveOrgFeatures(tt.args.ctx, tt.args.resourceOwner)
|
||||
if tt.res.err == nil {
|
||||
|
Reference in New Issue
Block a user