feat: permit all features to every instance and organisation (#3566)

This commit is contained in:
Livio Amstutz
2022-05-02 11:18:17 +02:00
committed by GitHub
parent a9f71ba08e
commit 861cf07700
71 changed files with 90 additions and 6589 deletions

View File

@@ -1,12 +1,10 @@
package command
import (
"context"
"time"
"github.com/zitadel/zitadel/internal/api/authz"
"github.com/zitadel/zitadel/internal/api/http"
authz_repo "github.com/zitadel/zitadel/internal/authz/repository"
sd "github.com/zitadel/zitadel/internal/config/systemdefaults"
"github.com/zitadel/zitadel/internal/crypto"
"github.com/zitadel/zitadel/internal/domain"
@@ -50,19 +48,12 @@ type Commands struct {
keyAlgorithm crypto.EncryptionAlgorithm
privateKeyLifetime time.Duration
publicKeyLifetime time.Duration
tokenVerifier orgFeatureChecker
}
type orgFeatureChecker interface {
CheckOrgFeatures(ctx context.Context, orgID string, requiredFeatures ...string) error
}
func StartCommands(es *eventstore.Eventstore,
defaults sd.SystemDefaults,
zitadelRoles []authz.RoleMapping,
staticStore static.Storage,
authZRepo authz_repo.Repository,
webAuthN *webauthn_helper.Config,
externalDomain string,
externalSecure bool,
@@ -119,8 +110,6 @@ func StartCommands(es *eventstore.Eventstore,
repo.domainVerificationGenerator = crypto.NewEncryptionGenerator(defaults.DomainVerification.VerificationGenerator, repo.domainVerificationAlg)
repo.domainVerificationValidator = http.ValidateDomain
repo.tokenVerifier = authZRepo
return repo, nil
}

View File

@@ -1,123 +0,0 @@
package command
import (
"time"
"github.com/zitadel/zitadel/internal/domain"
"github.com/zitadel/zitadel/internal/eventstore"
"github.com/zitadel/zitadel/internal/repository/features"
)
type FeaturesWriteModel struct {
eventstore.WriteModel
TierName string
TierDescription string
State domain.FeaturesState
StateDescription string
AuditLogRetention time.Duration
LoginPolicyFactors bool
LoginPolicyIDP bool
LoginPolicyPasswordless bool
LoginPolicyRegistration bool
LoginPolicyUsernameLogin bool
LoginPolicyPasswordReset bool
PasswordComplexityPolicy bool
LabelPolicyPrivateLabel bool
LabelPolicyWatermark bool
CustomDomain bool
PrivacyPolicy bool
MetadataUser bool
CustomTextMessage bool
CustomTextLogin bool
LockoutPolicy bool
ActionsAllowed domain.ActionsAllowed
MaxActions int
}
func (wm *FeaturesWriteModel) Reduce() error {
for _, event := range wm.Events {
switch e := event.(type) {
case *features.FeaturesSetEvent:
if e.TierName != nil {
wm.TierName = *e.TierName
}
if e.TierDescription != nil {
wm.TierDescription = *e.TierDescription
}
wm.State = domain.FeaturesStateActive
if e.State != nil {
wm.State = *e.State
}
if e.StateDescription != nil {
wm.StateDescription = *e.StateDescription
}
if e.AuditLogRetention != nil {
wm.AuditLogRetention = *e.AuditLogRetention
}
if e.LoginPolicyFactors != nil {
wm.LoginPolicyFactors = *e.LoginPolicyFactors
}
if e.LoginPolicyIDP != nil {
wm.LoginPolicyIDP = *e.LoginPolicyIDP
}
if e.LoginPolicyPasswordless != nil {
wm.LoginPolicyPasswordless = *e.LoginPolicyPasswordless
}
if e.LoginPolicyRegistration != nil {
wm.LoginPolicyRegistration = *e.LoginPolicyRegistration
}
if e.LoginPolicyUsernameLogin != nil {
wm.LoginPolicyUsernameLogin = *e.LoginPolicyUsernameLogin
}
if e.LoginPolicyPasswordReset != nil {
wm.LoginPolicyPasswordReset = *e.LoginPolicyPasswordReset
}
if e.PasswordComplexityPolicy != nil {
wm.PasswordComplexityPolicy = *e.PasswordComplexityPolicy
}
if e.LabelPolicy != nil {
wm.LabelPolicyPrivateLabel = *e.LabelPolicy
}
if e.LabelPolicyPrivateLabel != nil {
wm.LabelPolicyPrivateLabel = *e.LabelPolicyPrivateLabel
}
if e.LabelPolicyWatermark != nil {
wm.LabelPolicyWatermark = *e.LabelPolicyWatermark
}
if e.CustomDomain != nil {
wm.CustomDomain = *e.CustomDomain
}
if e.PrivacyPolicy != nil {
wm.PrivacyPolicy = *e.PrivacyPolicy
}
if e.MetadataUser != nil {
wm.MetadataUser = *e.MetadataUser
}
if e.CustomTextMessage != nil {
wm.CustomTextMessage = *e.CustomTextMessage
}
if e.CustomTextLogin != nil {
wm.CustomTextLogin = *e.CustomTextLogin
}
if e.LockoutPolicy != nil {
wm.LockoutPolicy = *e.LockoutPolicy
}
if e.Actions != nil {
wm.ActionsAllowed = domain.ActionsNotAllowed
if *e.Actions {
wm.ActionsAllowed = domain.ActionsAllowedUnlimited
}
}
if e.ActionsAllowed != nil {
wm.ActionsAllowed = *e.ActionsAllowed
}
if e.MaxActions != nil {
wm.MaxActions = *e.MaxActions
}
case *features.FeaturesRemovedEvent:
wm.State = domain.FeaturesStateRemoved
}
}
return wm.WriteModel.Reduce()
}

View File

@@ -29,34 +29,10 @@ const (
)
type InstanceSetup struct {
zitadel ZitadelConfig
InstanceName string
CustomDomain string
Org OrgSetup
Features struct {
TierName string
TierDescription string
Retention time.Duration
State domain.FeaturesState
StateDescription string
LoginPolicyFactors bool
LoginPolicyIDP bool
LoginPolicyPasswordless bool
LoginPolicyRegistration bool
LoginPolicyUsernameLogin bool
LoginPolicyPasswordReset bool
PasswordComplexityPolicy bool
LabelPolicyPrivateLabel bool
LabelPolicyWatermark bool
CustomDomain bool
PrivacyPolicy bool
MetadataUser bool
CustomTextMessage bool
CustomTextLogin bool
LockoutPolicy bool
ActionsAllowed domain.ActionsAllowed
MaxActions int
}
zitadel ZitadelConfig
InstanceName string
CustomDomain string
Org OrgSetup
SecretGenerators struct {
PasswordSaltCost uint
ClientSecret *crypto.GeneratorConfig
@@ -191,31 +167,6 @@ func (c *Commands) SetUpInstance(ctx context.Context, setup *InstanceSetup) (str
validations := []preparation.Validation{
addInstance(instanceAgg, setup.InstanceName),
SetDefaultFeatures(
instanceAgg,
setup.Features.TierName,
setup.Features.TierDescription,
setup.Features.State,
setup.Features.StateDescription,
setup.Features.Retention,
setup.Features.LoginPolicyFactors,
setup.Features.LoginPolicyIDP,
setup.Features.LoginPolicyPasswordless,
setup.Features.LoginPolicyRegistration,
setup.Features.LoginPolicyUsernameLogin,
setup.Features.LoginPolicyPasswordReset,
setup.Features.PasswordComplexityPolicy,
setup.Features.LabelPolicyPrivateLabel,
setup.Features.LabelPolicyWatermark,
setup.Features.CustomDomain,
setup.Features.PrivacyPolicy,
setup.Features.MetadataUser,
setup.Features.CustomTextMessage,
setup.Features.CustomTextLogin,
setup.Features.LockoutPolicy,
setup.Features.ActionsAllowed,
setup.Features.MaxActions,
),
addSecretGeneratorConfig(instanceAgg, domain.SecretGeneratorTypeAppSecret, setup.SecretGenerators.ClientSecret),
addSecretGeneratorConfig(instanceAgg, domain.SecretGeneratorTypeInitCode, setup.SecretGenerators.InitializeUserCode),
addSecretGeneratorConfig(instanceAgg, domain.SecretGeneratorTypeVerifyEmailCode, setup.SecretGenerators.EmailVerificationCode),

View File

@@ -169,31 +169,3 @@ func writeModelToIDPProvider(wm *IdentityProviderWriteModel) *domain.IDPProvider
Type: wm.IDPProviderType,
}
}
func writeModelToFeatures(wm *FeaturesWriteModel) *domain.Features {
return &domain.Features{
ObjectRoot: writeModelToObjectRoot(wm.WriteModel),
TierName: wm.TierName,
TierDescription: wm.TierDescription,
State: wm.State,
StateDescription: wm.StateDescription,
AuditLogRetention: wm.AuditLogRetention,
LoginPolicyFactors: wm.LoginPolicyFactors,
LoginPolicyIDP: wm.LoginPolicyIDP,
LoginPolicyPasswordless: wm.LoginPolicyPasswordless,
LoginPolicyRegistration: wm.LoginPolicyRegistration,
LoginPolicyUsernameLogin: wm.LoginPolicyUsernameLogin,
LoginPolicyPasswordReset: wm.LoginPolicyPasswordReset,
PasswordComplexityPolicy: wm.PasswordComplexityPolicy,
LabelPolicyPrivateLabel: wm.LabelPolicyPrivateLabel,
LabelPolicyWatermark: wm.LabelPolicyWatermark,
CustomDomain: wm.CustomDomain,
PrivacyPolicy: wm.PrivacyPolicy,
MetadataUser: wm.MetadataUser,
CustomTextMessage: wm.CustomTextMessage,
CustomTextLogin: wm.CustomTextLogin,
LockoutPolicy: wm.LockoutPolicy,
ActionsAllowed: wm.ActionsAllowed,
MaxActions: wm.MaxActions,
}
}

View File

@@ -1,160 +0,0 @@
package command
import (
"context"
"time"
"github.com/zitadel/zitadel/internal/command/preparation"
"github.com/zitadel/zitadel/internal/domain"
"github.com/zitadel/zitadel/internal/errors"
"github.com/zitadel/zitadel/internal/eventstore"
"github.com/zitadel/zitadel/internal/repository/instance"
)
func SetDefaultFeatures(
a *instance.Aggregate,
tierName,
tierDescription string,
state domain.FeaturesState,
stateDescription string,
retention time.Duration,
loginPolicyFactors,
loginPolicyIDP,
loginPolicyPasswordless,
loginPolicyRegistration,
loginPolicyUsernameLogin,
loginPolicyPasswordReset,
passwordComplexityPolicy,
labelPolicyPrivateLabel,
labelPolicyWatermark,
customDomain,
privacyPolicy,
metadataUser,
customTextMessage,
customTextLogin,
lockoutPolicy bool,
actionsAllowed domain.ActionsAllowed,
maxActions int,
) preparation.Validation {
return func() (preparation.CreateCommands, error) {
if !state.Valid() || state == domain.FeaturesStateUnspecified || state == domain.FeaturesStateRemoved {
return nil, errors.ThrowInvalidArgument(nil, "INSTA-d3r1s", "Errors.Invalid.Argument")
}
return func(ctx context.Context, filter preparation.FilterToQueryReducer) ([]eventstore.Command, error) {
writeModel, err := defaultFeatures(ctx, filter)
if err != nil {
return nil, err
}
event, hasChanged := writeModel.NewSetEvent(ctx, &a.Aggregate,
tierName,
tierDescription,
state,
stateDescription,
retention,
loginPolicyFactors,
loginPolicyIDP,
loginPolicyPasswordless,
loginPolicyRegistration,
loginPolicyUsernameLogin,
loginPolicyPasswordReset,
passwordComplexityPolicy,
labelPolicyPrivateLabel,
labelPolicyWatermark,
customDomain,
privacyPolicy,
metadataUser,
customTextMessage,
customTextLogin,
lockoutPolicy,
actionsAllowed,
maxActions,
)
if !hasChanged {
return nil, errors.ThrowPreconditionFailed(nil, "INSTA-GE4h2", "Errors.Features.NotChanged")
}
return []eventstore.Command{
event,
}, nil
}, nil
}
}
func defaultFeatures(ctx context.Context, filter preparation.FilterToQueryReducer) (*InstanceFeaturesWriteModel, error) {
features := NewInstanceFeaturesWriteModel(ctx)
events, err := filter(ctx, features.Query())
if err != nil {
return nil, err
}
if len(events) == 0 {
return features, nil
}
features.AppendEvents(events...)
err = features.Reduce()
return features, err
}
func (c *Commands) SetDefaultFeatures(ctx context.Context, features *domain.Features) (*domain.ObjectDetails, error) {
existingFeatures := NewInstanceFeaturesWriteModel(ctx)
setEvent, err := c.setDefaultFeatures(ctx, existingFeatures, features)
if err != nil {
return nil, err
}
pushedEvents, err := c.eventstore.Push(ctx, setEvent)
if err != nil {
return nil, err
}
err = AppendAndReduce(existingFeatures, pushedEvents...)
if err != nil {
return nil, err
}
return writeModelToObjectDetails(&existingFeatures.WriteModel), nil
}
func (c *Commands) setDefaultFeatures(ctx context.Context, existingFeatures *InstanceFeaturesWriteModel, features *domain.Features) (*instance.FeaturesSetEvent, error) {
err := c.eventstore.FilterToQueryReducer(ctx, existingFeatures)
if err != nil {
return nil, err
}
setEvent, hasChanged := existingFeatures.NewSetEvent(
ctx,
InstanceAggregateFromWriteModel(&existingFeatures.FeaturesWriteModel.WriteModel),
features.TierName,
features.TierDescription,
features.State,
features.StateDescription,
features.AuditLogRetention,
features.LoginPolicyFactors,
features.LoginPolicyIDP,
features.LoginPolicyPasswordless,
features.LoginPolicyRegistration,
features.LoginPolicyUsernameLogin,
features.LoginPolicyPasswordReset,
features.PasswordComplexityPolicy,
features.LabelPolicyPrivateLabel,
features.LabelPolicyWatermark,
features.CustomDomain,
features.PrivacyPolicy,
features.MetadataUser,
features.CustomTextMessage,
features.CustomTextLogin,
features.LockoutPolicy,
features.ActionsAllowed,
features.MaxActions,
)
if !hasChanged {
return nil, errors.ThrowPreconditionFailed(nil, "Features-GE4h2", "Errors.Features.NotChanged")
}
return setEvent, nil
}
func (c *Commands) getDefaultFeatures(ctx context.Context) (*domain.Features, error) {
existingFeatures := NewInstanceFeaturesWriteModel(ctx)
err := c.eventstore.FilterToQueryReducer(ctx, existingFeatures)
if err != nil {
return nil, err
}
features := writeModelToFeatures(&existingFeatures.FeaturesWriteModel)
features.IsDefault = true
return features, nil
}

View File

@@ -1,157 +0,0 @@
package command
import (
"context"
"time"
"github.com/zitadel/zitadel/internal/api/authz"
"github.com/zitadel/zitadel/internal/domain"
"github.com/zitadel/zitadel/internal/eventstore"
"github.com/zitadel/zitadel/internal/repository/features"
"github.com/zitadel/zitadel/internal/repository/instance"
)
type InstanceFeaturesWriteModel struct {
FeaturesWriteModel
}
func NewInstanceFeaturesWriteModel(ctx context.Context) *InstanceFeaturesWriteModel {
return &InstanceFeaturesWriteModel{
FeaturesWriteModel{
WriteModel: eventstore.WriteModel{
AggregateID: authz.GetInstance(ctx).InstanceID(),
ResourceOwner: authz.GetInstance(ctx).InstanceID(),
},
},
}
}
func (wm *InstanceFeaturesWriteModel) AppendEvents(events ...eventstore.Event) {
for _, event := range events {
switch e := event.(type) {
case *instance.FeaturesSetEvent:
wm.FeaturesWriteModel.AppendEvents(&e.FeaturesSetEvent)
}
}
}
func (wm *InstanceFeaturesWriteModel) IsValid() bool {
return wm.AggregateID != ""
}
func (wm *InstanceFeaturesWriteModel) Reduce() error {
return wm.FeaturesWriteModel.Reduce()
}
func (wm *InstanceFeaturesWriteModel) Query() *eventstore.SearchQueryBuilder {
return eventstore.NewSearchQueryBuilder(eventstore.ColumnsEvent).
ResourceOwner(wm.ResourceOwner).
AddQuery().
EventTypes(instance.FeaturesSetEventType).
AggregateTypes(instance.AggregateType).
Builder()
}
func (wm *InstanceFeaturesWriteModel) NewSetEvent(
ctx context.Context,
aggregate *eventstore.Aggregate,
tierName, tierDescription string,
state domain.FeaturesState,
stateDescription string,
auditLogRetention time.Duration,
loginPolicyFactors,
loginPolicyIDP,
loginPolicyPasswordless,
loginPolicyRegistration,
loginPolicyUsernameLogin,
loginPolicyPasswordReset,
passwordComplexityPolicy,
labelPolicyPrivateLabel,
labelPolicyWatermark,
customDomain,
privacyPolicy,
metadataUser,
customTextMessage,
customTextLogin,
lockoutPolicy bool,
actionsAllowed domain.ActionsAllowed,
maxActions int,
) (*instance.FeaturesSetEvent, bool) {
changes := make([]features.FeaturesChanges, 0)
if tierName != "" && wm.TierName != tierName {
changes = append(changes, features.ChangeTierName(tierName))
}
if wm.TierDescription != tierDescription {
changes = append(changes, features.ChangeTierDescription(tierDescription))
}
if wm.State != state {
changes = append(changes, features.ChangeState(state))
}
if wm.StateDescription != stateDescription {
changes = append(changes, features.ChangeStateDescription(stateDescription))
}
if auditLogRetention != 0 && wm.AuditLogRetention != auditLogRetention {
changes = append(changes, features.ChangeAuditLogRetention(auditLogRetention))
}
if wm.LoginPolicyFactors != loginPolicyFactors {
changes = append(changes, features.ChangeLoginPolicyFactors(loginPolicyFactors))
}
if wm.LoginPolicyIDP != loginPolicyIDP {
changes = append(changes, features.ChangeLoginPolicyIDP(loginPolicyIDP))
}
if wm.LoginPolicyPasswordless != loginPolicyPasswordless {
changes = append(changes, features.ChangeLoginPolicyPasswordless(loginPolicyPasswordless))
}
if wm.LoginPolicyRegistration != loginPolicyRegistration {
changes = append(changes, features.ChangeLoginPolicyRegistration(loginPolicyRegistration))
}
if wm.LoginPolicyUsernameLogin != loginPolicyUsernameLogin {
changes = append(changes, features.ChangeLoginPolicyUsernameLogin(loginPolicyUsernameLogin))
}
if wm.LoginPolicyPasswordReset != loginPolicyPasswordReset {
changes = append(changes, features.ChangeLoginPolicyPasswordReset(loginPolicyPasswordReset))
}
if wm.PasswordComplexityPolicy != passwordComplexityPolicy {
changes = append(changes, features.ChangePasswordComplexityPolicy(passwordComplexityPolicy))
}
if wm.LabelPolicyPrivateLabel != labelPolicyPrivateLabel {
changes = append(changes, features.ChangeLabelPolicyPrivateLabel(labelPolicyPrivateLabel))
}
if wm.LabelPolicyWatermark != labelPolicyWatermark {
changes = append(changes, features.ChangeLabelPolicyWatermark(labelPolicyWatermark))
}
if wm.CustomDomain != customDomain {
changes = append(changes, features.ChangeCustomDomain(customDomain))
}
if wm.PrivacyPolicy != privacyPolicy {
changes = append(changes, features.ChangePrivacyPolicy(privacyPolicy))
}
if wm.MetadataUser != metadataUser {
changes = append(changes, features.ChangeMetadataUser(metadataUser))
}
if wm.CustomTextMessage != customTextMessage {
changes = append(changes, features.ChangeCustomTextMessage(customTextMessage))
}
if wm.CustomTextLogin != customTextLogin {
changes = append(changes, features.ChangeCustomTextLogin(customTextLogin))
}
if wm.LockoutPolicy != lockoutPolicy {
changes = append(changes, features.ChangeLockoutPolicy(lockoutPolicy))
}
if wm.ActionsAllowed != actionsAllowed {
changes = append(changes, features.ChangeActionsAllowed(actionsAllowed))
}
if wm.MaxActions != maxActions {
changes = append(changes, features.ChangeMaxActions(maxActions))
}
if len(changes) == 0 {
return nil, false
}
changedEvent, err := instance.NewFeaturesSetEvent(ctx, aggregate, changes)
if err != nil {
return nil, false
}
return changedEvent, true
}

View File

@@ -1,152 +0,0 @@
package command
import (
"context"
"testing"
"time"
"github.com/zitadel/zitadel/internal/domain"
"github.com/zitadel/zitadel/internal/errors"
"github.com/zitadel/zitadel/internal/eventstore"
"github.com/zitadel/zitadel/internal/repository/features"
"github.com/zitadel/zitadel/internal/repository/instance"
)
func TestSetDefaultFeatures(t *testing.T) {
type args struct {
a *instance.Aggregate
tierName string
tierDescription string
state domain.FeaturesState
stateDescription string
retention time.Duration
loginPolicyFactors bool
loginPolicyIDP bool
loginPolicyPasswordless bool
loginPolicyRegistration bool
loginPolicyUsernameLogin bool
loginPolicyPasswordReset bool
passwordComplexityPolicy bool
labelPolicyPrivateLabel bool
labelPolicyWatermark bool
customDomain bool
privacyPolicy bool
metadataUser bool
customTextMessage bool
customTextLogin bool
lockoutPolicy bool
actionsAllowed domain.ActionsAllowed
maxActions int
}
tests := []struct {
name string
args args
want Want
}{
{
name: "invalid state",
args: args{
a: instance.NewAggregate("INSTANCE"),
tierName: "",
tierDescription: "",
state: 0,
stateDescription: "",
retention: 0,
loginPolicyFactors: false,
loginPolicyIDP: false,
loginPolicyPasswordless: false,
loginPolicyRegistration: false,
loginPolicyUsernameLogin: false,
loginPolicyPasswordReset: false,
passwordComplexityPolicy: false,
labelPolicyPrivateLabel: false,
labelPolicyWatermark: false,
customDomain: false,
privacyPolicy: false,
metadataUser: false,
customTextMessage: false,
customTextLogin: false,
lockoutPolicy: false,
actionsAllowed: 0,
maxActions: 0,
},
want: Want{
ValidationErr: errors.ThrowInvalidArgument(nil, "INSTA-d3r1s", "Errors.Invalid.Argument"),
},
},
{
name: "correct",
args: args{
a: instance.NewAggregate("INSTANCE"),
tierName: "",
tierDescription: "",
state: domain.FeaturesStateActive,
stateDescription: "",
retention: 0,
loginPolicyFactors: false,
loginPolicyIDP: false,
loginPolicyPasswordless: false,
loginPolicyRegistration: false,
loginPolicyUsernameLogin: false,
loginPolicyPasswordReset: false,
passwordComplexityPolicy: false,
labelPolicyPrivateLabel: false,
labelPolicyWatermark: false,
customDomain: false,
privacyPolicy: false,
metadataUser: false,
customTextMessage: false,
customTextLogin: false,
lockoutPolicy: false,
actionsAllowed: 0,
maxActions: 0,
},
want: Want{
Commands: []eventstore.Command{
func() *instance.FeaturesSetEvent {
event, _ := instance.NewFeaturesSetEvent(context.Background(), &instance.NewAggregate("INSTANCE").Aggregate,
[]features.FeaturesChanges{
features.ChangeState(domain.FeaturesStateActive),
},
)
return event
}(),
},
},
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
AssertValidation(t, SetDefaultFeatures(
tt.args.a,
tt.args.tierName,
tt.args.tierDescription,
tt.args.state,
tt.args.stateDescription,
tt.args.retention,
tt.args.loginPolicyFactors,
tt.args.loginPolicyIDP,
tt.args.loginPolicyPasswordless,
tt.args.loginPolicyRegistration,
tt.args.loginPolicyUsernameLogin,
tt.args.loginPolicyPasswordReset,
tt.args.passwordComplexityPolicy,
tt.args.labelPolicyPrivateLabel,
tt.args.labelPolicyWatermark,
tt.args.customDomain,
tt.args.privacyPolicy,
tt.args.metadataUser,
tt.args.customTextMessage,
tt.args.customTextLogin,
tt.args.lockoutPolicy,
tt.args.actionsAllowed,
tt.args.maxActions,
), NewMultiFilter().
Append(func(ctx context.Context, queryFactory *eventstore.SearchQueryBuilder) ([]eventstore.Event, error) {
return nil, nil
}).
Filter(),
tt.want)
})
}
}

View File

@@ -9,9 +9,7 @@ import (
"github.com/golang/mock/gomock"
"golang.org/x/text/language"
"github.com/zitadel/zitadel/internal/api/authz"
"github.com/zitadel/zitadel/internal/crypto"
"github.com/zitadel/zitadel/internal/errors"
"github.com/zitadel/zitadel/internal/eventstore"
"github.com/zitadel/zitadel/internal/eventstore/repository"
"github.com/zitadel/zitadel/internal/eventstore/repository/mock"
@@ -213,51 +211,6 @@ func GetMockSecretGenerator(t *testing.T) crypto.Generator {
return generator
}
func GetMockVerifier(t *testing.T, features ...string) *testVerifier {
return &testVerifier{
features: features,
}
}
type testVerifier struct {
features []string
}
func (v *testVerifier) VerifyAccessToken(ctx context.Context, token, clientID string) (string, string, string, string, string, error) {
return "userID", "agentID", "clientID", "de", "orgID", nil
}
func (v *testVerifier) SearchMyMemberships(ctx context.Context) ([]*authz.Membership, error) {
return nil, nil
}
func (v *testVerifier) ProjectIDAndOriginsByClientID(ctx context.Context, clientID string) (string, []string, error) {
return "", nil, nil
}
func (v *testVerifier) ExistsOrg(ctx context.Context, orgID string) error {
return nil
}
func (v *testVerifier) VerifierClientID(ctx context.Context, appName string) (string, error) {
return "clientID", nil
}
func (v *testVerifier) CheckOrgFeatures(ctx context.Context, orgID string, requiredFeatures ...string) error {
for _, feature := range requiredFeatures {
hasFeature := false
for _, f := range v.features {
if f == feature {
hasFeature = true
break
}
}
if !hasFeature {
return errors.ThrowPermissionDenied(nil, "id", "missing feature")
}
}
return nil
}
type mockInstance struct{}
func (m *mockInstance) InstanceID() string {

View File

@@ -15,10 +15,6 @@ func (c *Commands) AddAction(ctx context.Context, addAction *domain.Action, reso
if !addAction.IsValid() {
return "", nil, caos_errs.ThrowInvalidArgument(nil, "COMMAND-eg2gf", "Errors.Action.Invalid")
}
err = c.checkAdditionalActionAllowed(ctx, resourceOwner)
if err != nil {
return "", nil, err
}
addAction.AggregateID, err = c.idGenerator.Next()
if err != nil {
return "", nil, err
@@ -44,27 +40,6 @@ func (c *Commands) AddAction(ctx context.Context, addAction *domain.Action, reso
return actionModel.AggregateID, writeModelToObjectDetails(&actionModel.WriteModel), nil
}
func (c *Commands) checkAdditionalActionAllowed(ctx context.Context, resourceOwner string) error {
features, err := c.getOrgFeaturesOrDefault(ctx, resourceOwner)
if err != nil {
return err
}
existingActions, err := c.getActionsByOrgWriteModelByID(ctx, resourceOwner)
if err != nil {
return err
}
activeActions := make([]*ActionWriteModel, 0, len(existingActions.Actions))
for _, existingAction := range existingActions.Actions {
if existingAction.State == domain.ActionStateActive {
activeActions = append(activeActions, existingAction)
}
}
if features.ActionsAllowed == domain.ActionsAllowedUnlimited || len(activeActions) < features.MaxActions {
return nil
}
return caos_errs.ThrowPreconditionFailed(nil, "COMMAND-dfwg2", "Errors.Action.MaxAllowed")
}
func (c *Commands) ChangeAction(ctx context.Context, actionChange *domain.Action, resourceOwner string) (*domain.ObjectDetails, error) {
if !actionChange.IsValid() || actionChange.AggregateID == "" {
return nil, caos_errs.ThrowInvalidArgument(nil, "COMMAND-Df2f3", "Errors.Action.Invalid")
@@ -145,10 +120,6 @@ func (c *Commands) ReactivateAction(ctx context.Context, actionID string, resour
if existingAction.State != domain.ActionStateInactive {
return nil, caos_errs.ThrowPreconditionFailed(nil, "COMMAND-J53zh", "Errors.Action.NotInactive")
}
err = c.checkAdditionalActionAllowed(ctx, resourceOwner)
if err != nil {
return nil, err
}
actionAgg := ActionAggregateFromWriteModel(&existingAction.WriteModel)
events := []eventstore.Command{

View File

@@ -6,8 +6,6 @@ import (
"github.com/stretchr/testify/assert"
"github.com/zitadel/zitadel/internal/repository/features"
"github.com/zitadel/zitadel/internal/domain"
"github.com/zitadel/zitadel/internal/errors"
"github.com/zitadel/zitadel/internal/eventstore"
@@ -56,76 +54,10 @@ func TestCommands_AddAction(t *testing.T) {
err: errors.IsErrorInvalidArgument,
},
},
{
"no additional allowed, error",
fields{
eventstore: eventstoreExpect(t,
expectFilter(
eventFromEventPusher(
func() eventstore.Command {
e, _ := org.NewFeaturesSetEvent(context.Background(),
&org.NewAggregate("org1").Aggregate,
[]features.FeaturesChanges{
features.ChangeMaxActions(1),
},
)
return e
}(),
),
),
expectFilter(
eventFromEventPusher(
action.NewAddedEvent(context.Background(),
&action.NewAggregate("id1", "org1").Aggregate,
"name",
"name() {};",
0,
false,
),
),
),
),
},
args{
ctx: context.Background(),
addAction: &domain.Action{
Name: "name",
Script: "name() {};",
},
resourceOwner: "org1",
},
res{
err: errors.IsPreconditionFailed,
},
},
{
"unique constraint failed, error",
fields{
eventstore: eventstoreExpect(t,
expectFilter(
eventFromEventPusher(
func() eventstore.Command {
e, _ := org.NewFeaturesSetEvent(context.Background(),
&org.NewAggregate("org1").Aggregate,
[]features.FeaturesChanges{
features.ChangeMaxActions(2),
},
)
return e
}(),
),
),
expectFilter(
eventFromEventPusher(
action.NewAddedEvent(context.Background(),
&action.NewAggregate("id1", "org1").Aggregate,
"name",
"name() {};",
0,
false,
),
),
),
expectPushFailed(
errors.ThrowPreconditionFailed(nil, "id", "name already exists"),
[]*repository.Event{
@@ -160,30 +92,6 @@ func TestCommands_AddAction(t *testing.T) {
"push ok",
fields{
eventstore: eventstoreExpect(t,
expectFilter(
eventFromEventPusher(
func() eventstore.Command {
e, _ := org.NewFeaturesSetEvent(context.Background(),
&org.NewAggregate("org1").Aggregate,
[]features.FeaturesChanges{
features.ChangeMaxActions(2),
},
)
return e
}(),
),
),
expectFilter(
eventFromEventPusher(
action.NewAddedEvent(context.Background(),
&action.NewAggregate("id1", "org1").Aggregate,
"name",
"name() {};",
0,
false,
),
),
),
expectPush(
[]*repository.Event{
eventFromEventPusher(
@@ -663,94 +571,10 @@ func TestCommands_ReactivateAction(t *testing.T) {
err: errors.IsPreconditionFailed,
},
},
{
"no additional allowed, error",
fields{
eventstore: eventstoreExpect(t,
expectFilter(
eventFromEventPusher(
action.NewAddedEvent(context.Background(),
&action.NewAggregate("id1", "org1").Aggregate,
"name",
"name() {};",
0,
false,
),
),
eventFromEventPusher(
action.NewDeactivatedEvent(context.Background(),
&action.NewAggregate("id1", "org1").Aggregate,
),
),
),
expectFilter(
eventFromEventPusher(
func() eventstore.Command {
e, _ := org.NewFeaturesSetEvent(context.Background(),
&org.NewAggregate("org1").Aggregate,
[]features.FeaturesChanges{
features.ChangeMaxActions(1),
},
)
return e
}(),
),
),
expectFilter(
eventFromEventPusher(
action.NewAddedEvent(context.Background(),
&action.NewAggregate("id2", "org1").Aggregate,
"name2",
"name2() {};",
0,
false,
),
),
),
),
},
args{
ctx: context.Background(),
actionID: "id1",
resourceOwner: "org1",
},
res{
err: errors.IsPreconditionFailed,
},
},
{
"reactivate ok",
fields{
eventstore: eventstoreExpect(t,
expectFilter(
eventFromEventPusher(
action.NewAddedEvent(context.Background(),
&action.NewAggregate("id1", "org1").Aggregate,
"name",
"name() {};",
0,
false,
),
),
eventFromEventPusher(
action.NewDeactivatedEvent(context.Background(),
&action.NewAggregate("id1", "org1").Aggregate,
),
),
),
expectFilter(
eventFromEventPusher(
func() eventstore.Command {
e, _ := org.NewFeaturesSetEvent(context.Background(),
&org.NewAggregate("org1").Aggregate,
[]features.FeaturesChanges{
features.ChangeMaxActions(1),
},
)
return e
}(),
),
),
expectFilter(
eventFromEventPusher(
action.NewAddedEvent(context.Background(),

View File

@@ -1,393 +0,0 @@
package command
import (
"context"
"github.com/zitadel/zitadel/internal/domain"
caos_errs "github.com/zitadel/zitadel/internal/errors"
"github.com/zitadel/zitadel/internal/eventstore"
"github.com/zitadel/zitadel/internal/repository/org"
)
func (c *Commands) SetOrgFeatures(ctx context.Context, resourceOwner string, features *domain.Features) (*domain.ObjectDetails, error) {
if resourceOwner == "" {
return nil, caos_errs.ThrowInvalidArgument(nil, "Features-G5tg", "Errors.ResourceOwnerMissing")
}
err := c.checkOrgExists(ctx, resourceOwner)
if err != nil {
return nil, err
}
existingFeatures := NewOrgFeaturesWriteModel(resourceOwner)
err = c.eventstore.FilterToQueryReducer(ctx, existingFeatures)
if err != nil {
return nil, err
}
setEvent, hasChanged := existingFeatures.NewSetEvent(
ctx,
OrgAggregateFromWriteModel(&existingFeatures.FeaturesWriteModel.WriteModel),
features.TierName,
features.TierDescription,
features.State,
features.StateDescription,
features.AuditLogRetention,
features.LoginPolicyFactors,
features.LoginPolicyIDP,
features.LoginPolicyPasswordless,
features.LoginPolicyRegistration,
features.LoginPolicyUsernameLogin,
features.LoginPolicyPasswordReset,
features.PasswordComplexityPolicy,
features.LabelPolicyPrivateLabel,
features.LabelPolicyWatermark,
features.CustomDomain,
features.PrivacyPolicy,
features.MetadataUser,
features.CustomTextMessage,
features.CustomTextLogin,
features.LockoutPolicy,
features.ActionsAllowed,
features.MaxActions,
)
if !hasChanged {
return nil, caos_errs.ThrowPreconditionFailed(nil, "Features-GE4h2", "Errors.Features.NotChanged")
}
events, err := c.ensureOrgSettingsToFeatures(ctx, resourceOwner, features)
if err != nil {
return nil, err
}
events = append(events, setEvent)
pushedEvents, err := c.eventstore.Push(ctx, events...)
if err != nil {
return nil, err
}
err = AppendAndReduce(existingFeatures, pushedEvents...)
if err != nil {
return nil, err
}
return writeModelToObjectDetails(&existingFeatures.WriteModel), nil
}
func (c *Commands) RemoveOrgFeatures(ctx context.Context, orgID string) (*domain.ObjectDetails, error) {
if orgID == "" {
return nil, caos_errs.ThrowInvalidArgument(nil, "Features-G5tg", "Errors.ResourceOwnerMissing")
}
existingFeatures := NewOrgFeaturesWriteModel(orgID)
err := c.eventstore.FilterToQueryReducer(ctx, existingFeatures)
if err != nil {
return nil, err
}
if existingFeatures.State == domain.FeaturesStateUnspecified || existingFeatures.State == domain.FeaturesStateRemoved {
return nil, caos_errs.ThrowNotFound(nil, "Features-Bg32G", "Errors.Features.NotFound")
}
removedEvent := org.NewFeaturesRemovedEvent(ctx, OrgAggregateFromWriteModel(&existingFeatures.FeaturesWriteModel.WriteModel))
features, err := c.getDefaultFeatures(ctx)
if err != nil {
return nil, err
}
events, err := c.ensureOrgSettingsToFeatures(ctx, orgID, features)
if err != nil {
return nil, err
}
events = append(events, removedEvent)
pushedEvents, err := c.eventstore.Push(ctx, events...)
if err != nil {
return nil, err
}
err = AppendAndReduce(existingFeatures, pushedEvents...)
if err != nil {
return nil, err
}
return writeModelToObjectDetails(&existingFeatures.WriteModel), nil
}
func (c *Commands) ensureOrgSettingsToFeatures(ctx context.Context, orgID string, features *domain.Features) ([]eventstore.Command, error) {
events, err := c.setAllowedLoginPolicy(ctx, orgID, features)
if err != nil {
return nil, err
}
if !features.PasswordComplexityPolicy {
removePasswordComplexityEvent, err := c.removePasswordComplexityPolicyIfExists(ctx, orgID)
if err != nil {
return nil, err
}
if removePasswordComplexityEvent != nil {
events = append(events, removePasswordComplexityEvent)
}
}
labelPolicyEvents, err := c.setAllowedLabelPolicy(ctx, orgID, features)
if err != nil {
return nil, err
}
events = append(events, labelPolicyEvents...)
if !features.CustomDomain {
removeCustomDomainsEvents, err := c.removeCustomDomains(ctx, orgID)
if err != nil {
return nil, err
}
if removeCustomDomainsEvents != nil {
events = append(events, removeCustomDomainsEvents...)
}
}
if !features.CustomTextMessage {
removeCustomMessageTextEvents, err := c.removeOrgMessageTextsIfExists(ctx, orgID)
if err != nil {
return nil, err
}
if removeCustomMessageTextEvents != nil {
events = append(events, removeCustomMessageTextEvents...)
}
}
if !features.CustomTextLogin {
removeCustomLoginTextEvents, err := c.removeOrgLoginTextsIfExists(ctx, orgID)
if err != nil {
return nil, err
}
if removeCustomLoginTextEvents != nil {
events = append(events, removeCustomLoginTextEvents...)
}
}
if !features.PrivacyPolicy {
removePrivacyPolicyEvent, err := c.removePrivacyPolicyIfExists(ctx, orgID)
if err != nil {
return nil, err
}
if removePrivacyPolicyEvent != nil {
events = append(events, removePrivacyPolicyEvent)
}
}
if !features.LockoutPolicy {
removeLockoutPolicyEvent, err := c.removeLockoutPolicyIfExists(ctx, orgID)
if err != nil {
return nil, err
}
if removeLockoutPolicyEvent != nil {
events = append(events, removeLockoutPolicyEvent)
}
}
if !features.MetadataUser {
removeOrgUserMetadatas, err := c.removeUserMetadataFromOrg(ctx, orgID)
if err != nil {
return nil, err
}
if len(removeOrgUserMetadatas) > 0 {
events = append(events, removeOrgUserMetadatas...)
}
}
if features.ActionsAllowed == domain.ActionsNotAllowed {
removeOrgActions, err := c.removeActionsFromOrg(ctx, orgID)
if err != nil {
return nil, err
}
if len(removeOrgActions) > 0 {
events = append(events, removeOrgActions...)
}
}
if features.ActionsAllowed == domain.ActionsMaxAllowed {
deactivateActions, err := c.deactivateNotAllowedActionsFromOrg(ctx, orgID, features.MaxActions)
if err != nil {
return nil, err
}
if len(deactivateActions) > 0 {
events = append(events, deactivateActions...)
}
}
return events, nil
}
func (c *Commands) setAllowedLoginPolicy(ctx context.Context, orgID string, features *domain.Features) ([]eventstore.Command, error) {
events := make([]eventstore.Command, 0)
existingPolicy, err := c.orgLoginPolicyWriteModelByID(ctx, orgID)
if err != nil {
return nil, err
}
if existingPolicy.State == domain.PolicyStateUnspecified || existingPolicy.State == domain.PolicyStateRemoved {
return nil, nil
}
defaultPolicy, err := c.getDefaultLoginPolicy(ctx)
if err != nil {
return nil, err
}
policy := *existingPolicy
if !features.LoginPolicyFactors {
if defaultPolicy.ForceMFA != existingPolicy.ForceMFA {
policy.ForceMFA = defaultPolicy.ForceMFA
}
authFactorsEvents, err := c.setDefaultAuthFactorsInCustomLoginPolicy(ctx, orgID)
if err != nil {
return nil, err
}
events = append(events, authFactorsEvents...)
}
if !features.LoginPolicyIDP {
if defaultPolicy.AllowExternalIDP != existingPolicy.AllowExternalIDP {
policy.AllowExternalIDP = defaultPolicy.AllowExternalIDP
}
//TODO: handle idps
}
if !features.LoginPolicyRegistration && defaultPolicy.AllowRegister != existingPolicy.AllowRegister {
policy.AllowRegister = defaultPolicy.AllowRegister
}
if !features.LoginPolicyPasswordless && defaultPolicy.PasswordlessType != existingPolicy.PasswordlessType {
policy.PasswordlessType = defaultPolicy.PasswordlessType
}
if !features.LoginPolicyUsernameLogin && defaultPolicy.AllowUsernamePassword != existingPolicy.AllowUserNamePassword {
policy.AllowUserNamePassword = defaultPolicy.AllowUsernamePassword
}
if !features.LoginPolicyPasswordReset && defaultPolicy.HidePasswordReset != existingPolicy.HidePasswordReset {
policy.HidePasswordReset = defaultPolicy.HidePasswordReset
}
changedEvent, hasChanged := existingPolicy.NewChangedEvent(ctx,
OrgAggregateFromWriteModel(&existingPolicy.WriteModel),
policy.AllowUserNamePassword,
policy.AllowRegister,
policy.AllowExternalIDP,
policy.ForceMFA,
policy.HidePasswordReset,
policy.PasswordlessType,
policy.PasswordCheckLifetime,
policy.ExternalLoginCheckLifetime,
policy.MFAInitSkipLifetime,
policy.SecondFactorCheckLifetime,
policy.MultiFactorCheckLifetime)
if hasChanged {
events = append(events, changedEvent)
}
return events, nil
}
func (c *Commands) setDefaultAuthFactorsInCustomLoginPolicy(ctx context.Context, orgID string) ([]eventstore.Command, error) {
orgAuthFactors, err := c.orgLoginPolicyAuthFactorsWriteModel(ctx, orgID)
if err != nil {
return nil, err
}
events := make([]eventstore.Command, 0)
for _, factor := range domain.SecondFactorTypes() {
state := orgAuthFactors.SecondFactors[factor]
if state == nil || state.IAM == state.Org {
continue
}
secondFactorWriteModel := orgAuthFactors.ToSecondFactorWriteModel(factor)
if state.IAM == domain.FactorStateActive {
event, err := c.addSecondFactorToLoginPolicy(ctx, secondFactorWriteModel, factor)
if err != nil {
return nil, err
}
if event != nil {
events = append(events, event)
}
continue
}
event, err := c.removeSecondFactorFromLoginPolicy(ctx, secondFactorWriteModel, factor)
if err != nil {
return nil, err
}
if event != nil {
events = append(events, event)
}
}
for _, factor := range domain.MultiFactorTypes() {
state := orgAuthFactors.MultiFactors[factor]
if state == nil || state.IAM == state.Org {
continue
}
multiFactorWriteModel := orgAuthFactors.ToMultiFactorWriteModel(factor)
if state.IAM == domain.FactorStateActive {
event, err := c.addMultiFactorToLoginPolicy(ctx, multiFactorWriteModel, factor)
if err != nil {
return nil, err
}
if event != nil {
events = append(events, event)
}
continue
}
event, err := c.removeMultiFactorFromLoginPolicy(ctx, multiFactorWriteModel, factor)
if err != nil {
return nil, err
}
if event != nil {
events = append(events, event)
}
}
return events, nil
}
func (c *Commands) setAllowedLabelPolicy(ctx context.Context, orgID string, features *domain.Features) ([]eventstore.Command, error) {
events := make([]eventstore.Command, 0)
existingPolicy, err := c.orgLabelPolicyWriteModelByID(ctx, orgID)
if err != nil {
return nil, err
}
if existingPolicy.State == domain.PolicyStateUnspecified || existingPolicy.State == domain.PolicyStateRemoved {
return nil, nil
}
if !features.LabelPolicyPrivateLabel && !features.LabelPolicyWatermark {
removeEvent, err := c.removeLabelPolicy(ctx, existingPolicy)
if err != nil {
return nil, err
}
return append(events, removeEvent), nil
}
defaultPolicy, err := c.getDefaultLabelPolicy(ctx)
if err != nil {
return nil, err
}
policy := *existingPolicy
if !features.LabelPolicyWatermark && defaultPolicy.DisableWatermark != existingPolicy.DisableWatermark {
policy.DisableWatermark = defaultPolicy.DisableWatermark
}
if !features.LabelPolicyPrivateLabel {
if defaultPolicy.HideLoginNameSuffix != existingPolicy.HideLoginNameSuffix {
policy.HideLoginNameSuffix = defaultPolicy.HideLoginNameSuffix
}
policy.PrimaryColor = ""
policy.BackgroundColor = ""
policy.WarnColor = ""
policy.FontColor = ""
policy.PrimaryColorDark = ""
policy.BackgroundColorDark = ""
policy.WarnColorDark = ""
policy.FontColorDark = ""
assetsEvent, err := c.removeLabelPolicyAssets(ctx, existingPolicy)
if err != nil {
return nil, err
}
events = append(events, assetsEvent)
}
changedEvent, hasChangedEvent := existingPolicy.NewChangedEvent(ctx, OrgAggregateFromWriteModel(&existingPolicy.WriteModel),
policy.PrimaryColor, policy.BackgroundColor, policy.WarnColor, policy.FontColor,
policy.PrimaryColorDark, policy.BackgroundColorDark, policy.WarnColorDark, policy.FontColorDark,
policy.HideLoginNameSuffix, policy.ErrorMsgPopup, policy.HideLoginNameSuffix)
if hasChangedEvent {
events = append(events, changedEvent)
}
if len(events) > 0 {
events = append(events, org.NewLabelPolicyActivatedEvent(ctx, OrgAggregateFromWriteModel(&existingPolicy.WriteModel)))
}
return events, nil
}
func (c *Commands) getOrgFeaturesOrDefault(ctx context.Context, orgID string) (*domain.Features, error) {
existingFeatures := NewOrgFeaturesWriteModel(orgID)
err := c.eventstore.FilterToQueryReducer(ctx, existingFeatures)
if err != nil {
return nil, err
}
if existingFeatures.State != domain.FeaturesStateUnspecified && existingFeatures.State != domain.FeaturesStateRemoved {
return writeModelToFeatures(&existingFeatures.FeaturesWriteModel), nil
}
existingIAMFeatures := NewInstanceFeaturesWriteModel(ctx)
err = c.eventstore.FilterToQueryReducer(ctx, existingIAMFeatures)
if err != nil {
return nil, err
}
return writeModelToFeatures(&existingIAMFeatures.FeaturesWriteModel), nil
}

View File

@@ -1,163 +0,0 @@
package command
import (
"context"
"time"
"github.com/zitadel/zitadel/internal/domain"
"github.com/zitadel/zitadel/internal/eventstore"
"github.com/zitadel/zitadel/internal/repository/features"
"github.com/zitadel/zitadel/internal/repository/org"
)
type OrgFeaturesWriteModel struct {
FeaturesWriteModel
}
func NewOrgFeaturesWriteModel(orgID string) *OrgFeaturesWriteModel {
return &OrgFeaturesWriteModel{
FeaturesWriteModel{
WriteModel: eventstore.WriteModel{
AggregateID: orgID,
ResourceOwner: orgID,
},
},
}
}
func (wm *OrgFeaturesWriteModel) AppendEvents(events ...eventstore.Event) {
for _, event := range events {
switch e := event.(type) {
case *org.FeaturesSetEvent:
wm.FeaturesWriteModel.AppendEvents(&e.FeaturesSetEvent)
case *org.FeaturesRemovedEvent:
wm.FeaturesWriteModel.AppendEvents(&e.FeaturesRemovedEvent)
}
}
}
func (wm *OrgFeaturesWriteModel) IsValid() bool {
return wm.AggregateID != ""
}
func (wm *OrgFeaturesWriteModel) Reduce() error {
return wm.FeaturesWriteModel.Reduce()
}
func (wm *OrgFeaturesWriteModel) Query() *eventstore.SearchQueryBuilder {
return eventstore.NewSearchQueryBuilder(eventstore.ColumnsEvent).
ResourceOwner(wm.ResourceOwner).
AddQuery().
AggregateTypes(org.AggregateType).
AggregateIDs(wm.FeaturesWriteModel.AggregateID).
EventTypes(
org.FeaturesSetEventType,
org.FeaturesRemovedEventType).
Builder()
}
func (wm *OrgFeaturesWriteModel) NewSetEvent(
ctx context.Context,
aggregate *eventstore.Aggregate,
tierName,
tierDescription string,
state domain.FeaturesState,
stateDescription string,
auditLogRetention time.Duration,
loginPolicyFactors,
loginPolicyIDP,
loginPolicyPasswordless,
loginPolicyRegistration,
loginPolicyUsernameLogin,
loginPolicyPasswordReset,
passwordComplexityPolicy,
labelPolicyPrivateLabel,
labelPolicyWatermark,
customDomain,
privacyPolicy,
metadataUser,
customTextMessage,
customTextLogin,
lockoutPolicy bool,
actionsAllowed domain.ActionsAllowed,
maxActions int,
) (*org.FeaturesSetEvent, bool) {
changes := make([]features.FeaturesChanges, 0)
if tierName != "" && wm.TierName != tierName {
changes = append(changes, features.ChangeTierName(tierName))
}
if wm.TierDescription != tierDescription {
changes = append(changes, features.ChangeTierDescription(tierDescription))
}
if wm.State != state {
changes = append(changes, features.ChangeState(state))
}
if stateDescription != "" && wm.StateDescription != stateDescription {
changes = append(changes, features.ChangeStateDescription(stateDescription))
}
if auditLogRetention != 0 && wm.AuditLogRetention != auditLogRetention {
changes = append(changes, features.ChangeAuditLogRetention(auditLogRetention))
}
if wm.LoginPolicyFactors != loginPolicyFactors {
changes = append(changes, features.ChangeLoginPolicyFactors(loginPolicyFactors))
}
if wm.LoginPolicyIDP != loginPolicyIDP {
changes = append(changes, features.ChangeLoginPolicyIDP(loginPolicyIDP))
}
if wm.LoginPolicyPasswordless != loginPolicyPasswordless {
changes = append(changes, features.ChangeLoginPolicyPasswordless(loginPolicyPasswordless))
}
if wm.LoginPolicyRegistration != loginPolicyRegistration {
changes = append(changes, features.ChangeLoginPolicyRegistration(loginPolicyRegistration))
}
if wm.LoginPolicyUsernameLogin != loginPolicyUsernameLogin {
changes = append(changes, features.ChangeLoginPolicyUsernameLogin(loginPolicyUsernameLogin))
}
if wm.LoginPolicyPasswordReset != loginPolicyPasswordReset {
changes = append(changes, features.ChangeLoginPolicyPasswordReset(loginPolicyPasswordReset))
}
if wm.PasswordComplexityPolicy != passwordComplexityPolicy {
changes = append(changes, features.ChangePasswordComplexityPolicy(passwordComplexityPolicy))
}
if wm.LabelPolicyPrivateLabel != labelPolicyPrivateLabel {
changes = append(changes, features.ChangeLabelPolicyPrivateLabel(labelPolicyPrivateLabel))
}
if wm.LabelPolicyWatermark != labelPolicyWatermark {
changes = append(changes, features.ChangeLabelPolicyWatermark(labelPolicyWatermark))
}
if wm.CustomDomain != customDomain {
changes = append(changes, features.ChangeCustomDomain(customDomain))
}
if wm.PrivacyPolicy != privacyPolicy {
changes = append(changes, features.ChangePrivacyPolicy(privacyPolicy))
}
if wm.MetadataUser != metadataUser {
changes = append(changes, features.ChangeMetadataUser(metadataUser))
}
if wm.CustomTextMessage != customTextMessage {
changes = append(changes, features.ChangeCustomTextMessage(customTextMessage))
}
if wm.CustomTextLogin != customTextLogin {
changes = append(changes, features.ChangeCustomTextLogin(customTextLogin))
}
if wm.LockoutPolicy != lockoutPolicy {
changes = append(changes, features.ChangeLockoutPolicy(lockoutPolicy))
}
if wm.ActionsAllowed != actionsAllowed {
changes = append(changes, features.ChangeActionsAllowed(actionsAllowed))
}
if wm.MaxActions != maxActions {
changes = append(changes, features.ChangeMaxActions(maxActions))
}
if len(changes) == 0 {
return nil, false
}
changedEvent, err := org.NewFeaturesSetEvent(ctx, aggregate, changes)
if err != nil {
return nil, false
}
return changedEvent, true
}

File diff suppressed because it is too large Load Diff

View File

@@ -25,10 +25,6 @@ func (c *Commands) AddLabelPolicy(ctx context.Context, resourceOwner string, pol
return nil, caos_errs.ThrowAlreadyExists(nil, "Org-2B0ps", "Errors.Org.LabelPolicy.AlreadyExists")
}
err = c.checkLabelPolicyAllowed(ctx, resourceOwner, policy)
if err != nil {
return nil, err
}
orgAgg := OrgAggregateFromWriteModel(&addedPolicy.LabelPolicyWriteModel.WriteModel)
pushedEvents, err := c.eventstore.Push(ctx, org.NewLabelPolicyAddedEvent(
ctx,
@@ -70,11 +66,6 @@ func (c *Commands) ChangeLabelPolicy(ctx context.Context, resourceOwner string,
return nil, caos_errs.ThrowNotFound(nil, "Org-0K9dq", "Errors.Org.LabelPolicy.NotFound")
}
err = c.checkLabelPolicyAllowed(ctx, resourceOwner, policy)
if err != nil {
return nil, err
}
orgAgg := OrgAggregateFromWriteModel(&existingPolicy.LabelPolicyWriteModel.WriteModel)
changedEvent, hasChanged := existingPolicy.NewChangedEvent(
ctx,
@@ -105,28 +96,6 @@ func (c *Commands) ChangeLabelPolicy(ctx context.Context, resourceOwner string,
return writeModelToLabelPolicy(&existingPolicy.LabelPolicyWriteModel), nil
}
func (c *Commands) checkLabelPolicyAllowed(ctx context.Context, resourceOwner string, policy *domain.LabelPolicy) error {
defaultPolicy, err := c.getDefaultLabelPolicy(ctx)
if err != nil {
return err
}
requiredFeatures := make([]string, 0)
if defaultPolicy.PrimaryColor != policy.PrimaryColor || defaultPolicy.PrimaryColorDark != policy.PrimaryColorDark ||
defaultPolicy.FontColor != policy.FontColor || defaultPolicy.FontColorDark != policy.FontColorDark ||
defaultPolicy.BackgroundColor != policy.BackgroundColor || defaultPolicy.BackgroundColorDark != policy.BackgroundColorDark ||
defaultPolicy.WarnColor != defaultPolicy.WarnColor || defaultPolicy.WarnColorDark != defaultPolicy.WarnColorDark ||
defaultPolicy.LogoURL != policy.LogoURL || defaultPolicy.LogoDarkURL != policy.LogoDarkURL ||
defaultPolicy.IconURL != policy.IconURL || defaultPolicy.IconDarkURL != policy.IconDarkURL ||
defaultPolicy.Font != policy.Font ||
defaultPolicy.HideLoginNameSuffix != policy.HideLoginNameSuffix {
requiredFeatures = append(requiredFeatures, domain.FeatureLabelPolicyPrivateLabel)
}
if defaultPolicy.DisableWatermark != policy.DisableWatermark {
requiredFeatures = append(requiredFeatures, domain.FeatureLabelPolicyWatermark)
}
return c.tokenVerifier.CheckOrgFeatures(ctx, resourceOwner, requiredFeatures...)
}
func (c *Commands) ActivateLabelPolicy(ctx context.Context, orgID string) (*domain.ObjectDetails, error) {
if orgID == "" {
return nil, caos_errs.ThrowInvalidArgument(nil, "Org-KKd4X", "Errors.ResourceOwnerMissing")

View File

@@ -13,7 +13,6 @@ import (
"github.com/zitadel/zitadel/internal/eventstore"
"github.com/zitadel/zitadel/internal/eventstore/repository"
"github.com/zitadel/zitadel/internal/eventstore/v1/models"
"github.com/zitadel/zitadel/internal/repository/instance"
"github.com/zitadel/zitadel/internal/repository/org"
"github.com/zitadel/zitadel/internal/repository/policy"
"github.com/zitadel/zitadel/internal/static"
@@ -22,8 +21,7 @@ import (
func TestCommandSide_AddLabelPolicy(t *testing.T) {
type fields struct {
eventstore *eventstore.Eventstore
tokenVerifier orgFeatureChecker
eventstore *eventstore.Eventstore
}
type args struct {
ctx context.Context
@@ -104,78 +102,12 @@ func TestCommandSide_AddLabelPolicy(t *testing.T) {
err: caos_errs.IsErrorAlreadyExists,
},
},
{
name: "add policy, permission denied",
fields: fields{
eventstore: eventstoreExpect(
t,
expectFilter(),
expectFilter(
eventFromEventPusher(
instance.NewLabelPolicyAddedEvent(context.Background(),
&instance.NewAggregate("INSTANCE").Aggregate,
"#ffffff",
"#ffffff",
"#ffffff",
"#ffffff",
"#ffffff",
"#ffffff",
"#ffffff",
"#ffffff",
true,
true,
false,
),
),
),
),
tokenVerifier: GetMockVerifier(t),
},
args: args{
ctx: context.Background(),
orgID: "org1",
policy: &domain.LabelPolicy{
PrimaryColor: "#ffffff",
BackgroundColor: "#ffffff",
WarnColor: "#ffffff",
FontColor: "#ffffff",
PrimaryColorDark: "#ffffff",
BackgroundColorDark: "#ffffff",
WarnColorDark: "#ffffff",
FontColorDark: "#ffffff",
HideLoginNameSuffix: true,
ErrorMsgPopup: true,
DisableWatermark: true,
},
},
res: res{
err: caos_errs.IsPermissionDenied,
},
},
{
name: "add policy,ok",
fields: fields{
eventstore: eventstoreExpect(
t,
expectFilter(),
expectFilter(
eventFromEventPusher(
instance.NewLabelPolicyAddedEvent(context.Background(),
&instance.NewAggregate("INSTANCE").Aggregate,
"#ffffff",
"#ffffff",
"#ffffff",
"#ffffff",
"#ffffff",
"#ffffff",
"#ffffff",
"#ffffff",
true,
true,
false,
),
),
),
expectPush(
[]*repository.Event{
eventFromEventPusher(
@@ -197,7 +129,6 @@ func TestCommandSide_AddLabelPolicy(t *testing.T) {
},
),
),
tokenVerifier: GetMockVerifier(t, domain.FeatureLabelPolicyPrivateLabel, domain.FeatureLabelPolicyWatermark),
},
args: args{
ctx: context.Background(),
@@ -240,8 +171,7 @@ func TestCommandSide_AddLabelPolicy(t *testing.T) {
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
r := &Commands{
eventstore: tt.fields.eventstore,
tokenVerifier: tt.fields.tokenVerifier,
eventstore: tt.fields.eventstore,
}
got, err := r.AddLabelPolicy(tt.args.ctx, tt.args.orgID, tt.args.policy)
if tt.res.err == nil {
@@ -259,8 +189,7 @@ func TestCommandSide_AddLabelPolicy(t *testing.T) {
func TestCommandSide_ChangeLabelPolicy(t *testing.T) {
type fields struct {
eventstore *eventstore.Eventstore
tokenVerifier orgFeatureChecker
eventstore *eventstore.Eventstore
}
type args struct {
ctx context.Context
@@ -316,71 +245,6 @@ func TestCommandSide_ChangeLabelPolicy(t *testing.T) {
err: caos_errs.IsNotFound,
},
},
{
name: "permission denied error",
fields: fields{
eventstore: eventstoreExpect(
t,
expectFilter(
eventFromEventPusher(
org.NewLabelPolicyAddedEvent(context.Background(),
&org.NewAggregate("org1").Aggregate,
"#ffffff",
"#ffffff",
"#ffffff",
"#ffffff",
"#ffffff",
"#ffffff",
"#ffffff",
"#ffffff",
true,
true,
true,
),
),
),
expectFilter(
eventFromEventPusher(
instance.NewLabelPolicyAddedEvent(context.Background(),
&instance.NewAggregate("INSTANCE").Aggregate,
"#ffffff",
"#ffffff",
"#ffffff",
"#ffffff",
"#ffffff",
"#ffffff",
"#ffffff",
"#ffffff",
true,
true,
false,
),
),
),
),
tokenVerifier: GetMockVerifier(t),
},
args: args{
ctx: context.Background(),
orgID: "org1",
policy: &domain.LabelPolicy{
PrimaryColor: "#000000",
BackgroundColor: "#000000",
WarnColor: "#000000",
FontColor: "#000000",
PrimaryColorDark: "#000000",
BackgroundColorDark: "#000000",
WarnColorDark: "#000000",
FontColorDark: "#000000",
HideLoginNameSuffix: true,
ErrorMsgPopup: true,
DisableWatermark: true,
},
},
res: res{
err: caos_errs.IsPermissionDenied,
},
},
{
name: "no changes, precondition error",
fields: fields{
@@ -404,26 +268,7 @@ func TestCommandSide_ChangeLabelPolicy(t *testing.T) {
),
),
),
expectFilter(
eventFromEventPusher(
instance.NewLabelPolicyAddedEvent(context.Background(),
&instance.NewAggregate("INSTANCE").Aggregate,
"#ffffff",
"#ffffff",
"#ffffff",
"#ffffff",
"#ffffff",
"#ffffff",
"#ffffff",
"#ffffff",
true,
true,
false,
),
),
),
),
tokenVerifier: GetMockVerifier(t, domain.FeatureLabelPolicyPrivateLabel, domain.FeatureLabelPolicyWatermark),
},
args: args{
ctx: context.Background(),
@@ -469,24 +314,6 @@ func TestCommandSide_ChangeLabelPolicy(t *testing.T) {
),
),
),
expectFilter(
eventFromEventPusher(
instance.NewLabelPolicyAddedEvent(context.Background(),
&instance.NewAggregate("INSTANCE").Aggregate,
"#ffffff",
"#ffffff",
"#ffffff",
"#ffffff",
"#ffffff",
"#ffffff",
"#ffffff",
"#ffffff",
true,
true,
false,
),
),
),
expectPush(
[]*repository.Event{
eventFromEventPusher(
@@ -508,7 +335,6 @@ func TestCommandSide_ChangeLabelPolicy(t *testing.T) {
},
),
),
tokenVerifier: GetMockVerifier(t, domain.FeatureLabelPolicyPrivateLabel, domain.FeatureLabelPolicyWatermark),
},
args: args{
ctx: context.Background(),
@@ -551,8 +377,7 @@ func TestCommandSide_ChangeLabelPolicy(t *testing.T) {
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
r := &Commands{
eventstore: tt.fields.eventstore,
tokenVerifier: tt.fields.tokenVerifier,
eventstore: tt.fields.eventstore,
}
got, err := r.ChangeLabelPolicy(tt.args.ctx, tt.args.orgID, tt.args.policy)
if tt.res.err == nil {

View File

@@ -2,7 +2,6 @@ package command
import (
"context"
"reflect"
"github.com/zitadel/logging"
@@ -26,11 +25,6 @@ func (c *Commands) AddLoginPolicy(ctx context.Context, resourceOwner string, pol
return nil, caos_errs.ThrowAlreadyExists(nil, "Org-Dgfb2", "Errors.Org.LoginPolicy.AlreadyExists")
}
err = c.checkLoginPolicyAllowed(ctx, resourceOwner, policy)
if err != nil {
return nil, err
}
orgAgg := OrgAggregateFromWriteModel(&addedPolicy.WriteModel)
pushedEvents, err := c.eventstore.Push(
ctx,
@@ -91,11 +85,6 @@ func (c *Commands) ChangeLoginPolicy(ctx context.Context, resourceOwner string,
return nil, caos_errs.ThrowNotFound(nil, "Org-M0sif", "Errors.Org.LoginPolicy.NotFound")
}
err = c.checkLoginPolicyAllowed(ctx, resourceOwner, policy)
if err != nil {
return nil, err
}
orgAgg := OrgAggregateFromWriteModel(&existingPolicy.LoginPolicyWriteModel.WriteModel)
changedEvent, hasChanged := existingPolicy.NewChangedEvent(
ctx,
@@ -127,33 +116,6 @@ func (c *Commands) ChangeLoginPolicy(ctx context.Context, resourceOwner string,
return writeModelToLoginPolicy(&existingPolicy.LoginPolicyWriteModel), nil
}
func (c *Commands) checkLoginPolicyAllowed(ctx context.Context, resourceOwner string, policy *domain.LoginPolicy) error {
defaultPolicy, err := c.getDefaultLoginPolicy(ctx)
if err != nil {
return err
}
requiredFeatures := make([]string, 0)
if defaultPolicy.ForceMFA != policy.ForceMFA || !reflect.DeepEqual(defaultPolicy.MultiFactors, policy.MultiFactors) || !reflect.DeepEqual(defaultPolicy.SecondFactors, policy.SecondFactors) {
requiredFeatures = append(requiredFeatures, domain.FeatureLoginPolicyFactors)
}
if defaultPolicy.AllowExternalIDP != policy.AllowExternalIDP || !reflect.DeepEqual(defaultPolicy.IDPProviders, policy.IDPProviders) {
requiredFeatures = append(requiredFeatures, domain.FeatureLoginPolicyIDP)
}
if defaultPolicy.AllowRegister != policy.AllowRegister {
requiredFeatures = append(requiredFeatures, domain.FeatureLoginPolicyRegistration)
}
if defaultPolicy.PasswordlessType != policy.PasswordlessType {
requiredFeatures = append(requiredFeatures, domain.FeatureLoginPolicyPasswordless)
}
if defaultPolicy.AllowUsernamePassword != policy.AllowUsernamePassword {
requiredFeatures = append(requiredFeatures, domain.FeatureLoginPolicyUsernameLogin)
}
if defaultPolicy.HidePasswordReset != policy.HidePasswordReset {
requiredFeatures = append(requiredFeatures, domain.FeatureLoginPolicyPasswordReset)
}
return c.tokenVerifier.CheckOrgFeatures(ctx, resourceOwner, requiredFeatures...)
}
func (c *Commands) RemoveLoginPolicy(ctx context.Context, orgID string) (*domain.ObjectDetails, error) {
if orgID == "" {
return nil, caos_errs.ThrowInvalidArgument(nil, "Org-55Mg9", "Errors.ResourceOwnerMissing")

View File

@@ -12,7 +12,6 @@ import (
"github.com/zitadel/zitadel/internal/eventstore"
"github.com/zitadel/zitadel/internal/eventstore/repository"
"github.com/zitadel/zitadel/internal/eventstore/v1/models"
"github.com/zitadel/zitadel/internal/repository/instance"
"github.com/zitadel/zitadel/internal/repository/org"
"github.com/zitadel/zitadel/internal/repository/policy"
"github.com/zitadel/zitadel/internal/repository/user"
@@ -28,8 +27,7 @@ var (
func TestCommandSide_AddLoginPolicy(t *testing.T) {
type fields struct {
eventstore *eventstore.Eventstore
tokenVerifier orgFeatureChecker
eventstore *eventstore.Eventstore
}
type args struct {
ctx context.Context
@@ -110,77 +108,12 @@ func TestCommandSide_AddLoginPolicy(t *testing.T) {
err: caos_errs.IsErrorAlreadyExists,
},
},
{
name: "loginpolicy not allowed, permission denied error",
fields: fields{
eventstore: eventstoreExpect(
t,
expectFilter(),
expectFilter(
eventFromEventPusher(
instance.NewLoginPolicyAddedEvent(context.Background(),
&instance.NewAggregate("INSTANCE").Aggregate,
false,
true,
true,
true,
true,
domain.PasswordlessTypeAllowed,
time.Hour*1,
time.Hour*2,
time.Hour*3,
time.Hour*4,
time.Hour*5,
),
),
),
),
tokenVerifier: GetMockVerifier(t),
},
args: args{
ctx: context.Background(),
orgID: "org1",
policy: &domain.LoginPolicy{
AllowRegister: true,
AllowUsernamePassword: true,
AllowExternalIDP: true,
ForceMFA: true,
PasswordlessType: domain.PasswordlessTypeAllowed,
PasswordCheckLifetime: time.Hour * 1,
ExternalLoginCheckLifetime: time.Hour * 2,
MFAInitSkipLifetime: time.Hour * 3,
SecondFactorCheckLifetime: time.Hour * 4,
MultiFactorCheckLifetime: time.Hour * 5,
},
},
res: res{
err: caos_errs.IsPermissionDenied,
},
},
{
name: "add policy,ok",
fields: fields{
eventstore: eventstoreExpect(
t,
expectFilter(),
expectFilter(
eventFromEventPusher(
instance.NewLoginPolicyAddedEvent(context.Background(),
&instance.NewAggregate("INSTANCE").Aggregate,
false,
true,
true,
true,
true,
domain.PasswordlessTypeAllowed,
time.Hour*1,
time.Hour*2,
time.Hour*3,
time.Hour*4,
time.Hour*5,
),
),
),
expectPush(
[]*repository.Event{
eventFromEventPusher(
@@ -202,7 +135,6 @@ func TestCommandSide_AddLoginPolicy(t *testing.T) {
},
),
),
tokenVerifier: GetMockVerifier(t, domain.FeatureLoginPolicyUsernameLogin),
},
args: args{
ctx: context.Background(),
@@ -245,8 +177,7 @@ func TestCommandSide_AddLoginPolicy(t *testing.T) {
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
r := &Commands{
eventstore: tt.fields.eventstore,
tokenVerifier: tt.fields.tokenVerifier,
eventstore: tt.fields.eventstore,
}
got, err := r.AddLoginPolicy(tt.args.ctx, tt.args.orgID, tt.args.policy)
if tt.res.err == nil {
@@ -264,8 +195,7 @@ func TestCommandSide_AddLoginPolicy(t *testing.T) {
func TestCommandSide_ChangeLoginPolicy(t *testing.T) {
type fields struct {
eventstore *eventstore.Eventstore
tokenVerifier orgFeatureChecker
eventstore *eventstore.Eventstore
}
type args struct {
ctx context.Context
@@ -326,70 +256,6 @@ func TestCommandSide_ChangeLoginPolicy(t *testing.T) {
err: caos_errs.IsNotFound,
},
},
{
name: "not allowed, permission denied error",
fields: fields{
eventstore: eventstoreExpect(
t,
expectFilter(
eventFromEventPusher(
org.NewLoginPolicyAddedEvent(context.Background(),
&org.NewAggregate("org1").Aggregate,
true,
true,
true,
true,
true,
domain.PasswordlessTypeAllowed,
time.Hour*1,
time.Hour*2,
time.Hour*3,
time.Hour*4,
time.Hour*5,
),
),
),
expectFilter(
eventFromEventPusher(
instance.NewLoginPolicyAddedEvent(context.Background(),
&instance.NewAggregate("INSTANCE").Aggregate,
false,
true,
true,
true,
true,
domain.PasswordlessTypeAllowed,
time.Hour*1,
time.Hour*2,
time.Hour*3,
time.Hour*4,
time.Hour*5,
),
),
),
),
tokenVerifier: GetMockVerifier(t),
},
args: args{
ctx: context.Background(),
orgID: "org1",
policy: &domain.LoginPolicy{
AllowRegister: true,
AllowUsernamePassword: true,
AllowExternalIDP: true,
ForceMFA: true,
PasswordlessType: domain.PasswordlessTypeAllowed,
PasswordCheckLifetime: time.Hour * 1,
ExternalLoginCheckLifetime: time.Hour * 2,
MFAInitSkipLifetime: time.Hour * 3,
SecondFactorCheckLifetime: time.Hour * 4,
MultiFactorCheckLifetime: time.Hour * 5,
},
},
res: res{
err: caos_errs.IsPermissionDenied,
},
},
{
name: "no changes, precondition error",
fields: fields{
@@ -413,26 +279,7 @@ func TestCommandSide_ChangeLoginPolicy(t *testing.T) {
),
),
),
expectFilter(
eventFromEventPusher(
instance.NewLoginPolicyAddedEvent(context.Background(),
&instance.NewAggregate("INSTANCE").Aggregate,
false,
true,
true,
true,
true,
domain.PasswordlessTypeAllowed,
time.Hour*1,
time.Hour*2,
time.Hour*3,
time.Hour*4,
time.Hour*5,
),
),
),
),
tokenVerifier: GetMockVerifier(t, domain.FeatureLoginPolicyUsernameLogin),
},
args: args{
ctx: context.Background(),
@@ -478,24 +325,6 @@ func TestCommandSide_ChangeLoginPolicy(t *testing.T) {
),
),
),
expectFilter(
eventFromEventPusher(
instance.NewLoginPolicyAddedEvent(context.Background(),
&instance.NewAggregate("INSTANCE").Aggregate,
false,
false,
false,
false,
false,
domain.PasswordlessTypeNotAllowed,
time.Hour*1,
time.Hour*2,
time.Hour*3,
time.Hour*4,
time.Hour*5,
),
),
),
expectPush(
[]*repository.Event{
eventFromEventPusher(
@@ -517,7 +346,6 @@ func TestCommandSide_ChangeLoginPolicy(t *testing.T) {
},
),
),
tokenVerifier: GetMockVerifier(t, domain.FeatureLoginPolicyUsernameLogin),
},
args: args{
ctx: context.Background(),
@@ -559,8 +387,7 @@ func TestCommandSide_ChangeLoginPolicy(t *testing.T) {
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
r := &Commands{
eventstore: tt.fields.eventstore,
tokenVerifier: tt.fields.tokenVerifier,
eventstore: tt.fields.eventstore,
}
got, err := r.ChangeLoginPolicy(tt.args.ctx, tt.args.orgID, tt.args.policy)
if tt.res.err == nil {