feat: SMTP Templates (#6932)

* feat: smtp templates poc

* feat: add isActive & ProviderType to SMTP backend

* feat: change providertype to uint32 and fix tests

* feat: minimal smtp provider component

* feat: woking on diiferent providers

* feat: keep working on providers

* feat: initial stepper for new provider

* fix: settings list and working on stepper

* feat: step 1 and 2 form inputs

* feat: starter for smtp test step

* fix: misspelled SMPT

* fix: remove tests for now

* feat: add tls toggle remove old google provider

* feat: working on add smtp and table

* fix: duplicated identifiers

* fix: settings list

* fix: add missing smtp config properties

* fix: add configID to smtp config table

* fix: working on listproviders

* feat: working in listSMTPConfigs

* fix: add count to listsmtpconfigs

* fix: getting empty results from listSMTPConfigs

* feat: table now shows real data

* fix: remaining styles for smtp-table

* fix: remove old notification-smtp-provider-component

* feat: delete smtp configuration

* feat: deactivate smtp config

* feat: replace isActive with state for smtp config

* feat: activate smtp config

* fix: remaining errors after main merge

* fix: list smtp providers panic and material mdc

* feat: refactor to only one provider component

* feat: current provider details view

* fix: refactor AddSMTPConfig and ChangeSMTPConfig

* fix: smtp config reduce issue

* fix: recover domain in NewIAMSMTPConfigWriteModel

* fix: add code needed by SetUpInstance

* fix: go tests and warn about passing context to InstanceAggregateFromWriteModel

* fix: i18n and add missing trans for fr, it, zh

* fix: add e2e tests

* docs: add smtp templates

* fix: remove provider_type, add description

* fix: remaining error from merge main

* fix: add @stebenz change for primary key

* fix: inactive placed after removed to prevent deleted configs to show as inactive

* fix: smtp provider id can be empty (migrated)

* feat: add mailchimp transactional template

* feat: add Brevo (Sendinblue) template

* feat: change brevo logo, add color to tls icon

* fix: queries use resourceowner, id must not be empty

* fix: deal with old smtp settings and tests

* fix: resourceOwner is the instanceID

* fix: remove aggregate_id, rename SMTPConfigByAggregateID with SMTPConfigActive

* fix: add tests for multiple configs with different IDs

* fix: conflict

* fix: remove notification-smtp-provider

* fix: add @peintnermax suggestions, rename module and fix e2e tests

* fix: remove material legacy modules

* fix: remove ctx as parameter for  InstanceAggregateFromWriteModel

* fix: add Id to SMTPConfigToPb

* fix:  change InstanceAggregateFromWriteModel to avoid linter errors

* fix import

* rm unused package-lock

* update yarn lock

---------

Co-authored-by: Elio Bischof <elio@zitadel.com>
Co-authored-by: Max Peintner <max@caos.ch>
Co-authored-by: Stefan Benz <46600784+stebenz@users.noreply.github.com>
This commit is contained in:
Miguel Cabrerizo
2024-04-11 09:16:10 +02:00
committed by GitHub
parent e2f0cd034a
commit d229da6af7
93 changed files with 6359 additions and 6132 deletions

View File

@@ -391,6 +391,7 @@ func setupSMTPSettings(commands *Commands, validations *[]preparation.Validation
*validations = append(*validations,
commands.prepareAddSMTPConfig(
instanceAgg,
smtpConfig.Description,
smtpConfig.From,
smtpConfig.FromName,
smtpConfig.ReplyToAddress,

View File

@@ -82,5 +82,11 @@ func (wm *InstanceWriteModel) Query() *eventstore.SearchQueryBuilder {
}
func InstanceAggregateFromWriteModel(wm *eventstore.WriteModel) *eventstore.Aggregate {
return eventstore.AggregateFromWriteModel(wm, instance.AggregateType, instance.AggregateVersion)
return &eventstore.Aggregate{
ID: wm.AggregateID,
Type: instance.AggregateType,
ResourceOwner: wm.ResourceOwner,
InstanceID: wm.InstanceID,
Version: instance.AggregateVersion,
}
}

View File

@@ -9,16 +9,18 @@ import (
"github.com/zitadel/zitadel/internal/repository/instance"
)
type InstanceSMTPConfigWriteModel struct {
type IAMSMTPConfigWriteModel struct {
eventstore.WriteModel
SenderAddress string
SenderName string
ReplyToAddress string
ID string
Description string
TLS bool
Host string
User string
Password *crypto.CryptoValue
SenderAddress string
SenderName string
ReplyToAddress string
State domain.SMTPConfigState
domain string
@@ -26,17 +28,19 @@ type InstanceSMTPConfigWriteModel struct {
smtpSenderAddressMatchesInstanceDomain bool
}
func NewInstanceSMTPConfigWriteModel(instanceID, domain string) *InstanceSMTPConfigWriteModel {
return &InstanceSMTPConfigWriteModel{
func NewIAMSMTPConfigWriteModel(instanceID, id, domain string) *IAMSMTPConfigWriteModel {
return &IAMSMTPConfigWriteModel{
WriteModel: eventstore.WriteModel{
AggregateID: instanceID,
ResourceOwner: instanceID,
InstanceID: instanceID,
},
ID: id,
domain: domain,
}
}
func (wm *InstanceSMTPConfigWriteModel) AppendEvents(events ...eventstore.Event) {
func (wm *IAMSMTPConfigWriteModel) AppendEvents(events ...eventstore.Event) {
for _, event := range events {
switch e := event.(type) {
case *instance.DomainAddedEvent:
@@ -56,46 +60,34 @@ func (wm *InstanceSMTPConfigWriteModel) AppendEvents(events ...eventstore.Event)
}
}
func (wm *InstanceSMTPConfigWriteModel) Reduce() error {
func (wm *IAMSMTPConfigWriteModel) Reduce() error {
for _, event := range wm.Events {
switch e := event.(type) {
case *instance.SMTPConfigAddedEvent:
wm.TLS = e.TLS
wm.SenderAddress = e.SenderAddress
wm.SenderName = e.SenderName
wm.ReplyToAddress = e.ReplyToAddress
wm.Host = e.Host
wm.User = e.User
wm.Password = e.Password
wm.State = domain.SMTPConfigStateActive
if wm.ID != e.ID {
continue
}
wm.reduceSMTPConfigAddedEvent(e)
case *instance.SMTPConfigChangedEvent:
if e.TLS != nil {
wm.TLS = *e.TLS
}
if e.FromAddress != nil {
wm.SenderAddress = *e.FromAddress
}
if e.FromName != nil {
wm.SenderName = *e.FromName
}
if e.ReplyToAddress != nil {
wm.ReplyToAddress = *e.ReplyToAddress
}
if e.Host != nil {
wm.Host = *e.Host
}
if e.User != nil {
wm.User = *e.User
if wm.ID != e.ID {
continue
}
wm.reduceSMTPConfigChangedEvent(e)
case *instance.SMTPConfigRemovedEvent:
wm.State = domain.SMTPConfigStateRemoved
wm.TLS = false
wm.SenderName = ""
wm.SenderAddress = ""
wm.ReplyToAddress = ""
wm.Host = ""
wm.User = ""
wm.Password = nil
if wm.ID != e.ID {
continue
}
wm.reduceSMTPConfigRemovedEvent(e)
case *instance.SMTPConfigActivatedEvent:
if wm.ID != e.ID {
continue
}
wm.State = domain.SMTPConfigStateActive
case *instance.SMTPConfigDeactivatedEvent:
if wm.ID != e.ID {
continue
}
wm.State = domain.SMTPConfigStateInactive
case *instance.DomainAddedEvent:
wm.domainState = domain.InstanceDomainStateActive
case *instance.DomainRemovedEvent:
@@ -111,7 +103,13 @@ func (wm *InstanceSMTPConfigWriteModel) Reduce() error {
return wm.WriteModel.Reduce()
}
func (wm *InstanceSMTPConfigWriteModel) Query() *eventstore.SearchQueryBuilder {
func (wm *IAMSMTPConfigWriteModel) Query() *eventstore.SearchQueryBuilder {
// If ID equals ResourceOwner we're dealing with the old and unique smtp settings
// Let's set the empty ID for the query
if wm.ID == wm.ResourceOwner {
wm.ID = ""
}
return eventstore.NewSearchQueryBuilder(eventstore.ColumnsEvent).
ResourceOwner(wm.ResourceOwner).
AddQuery().
@@ -122,6 +120,9 @@ func (wm *InstanceSMTPConfigWriteModel) Query() *eventstore.SearchQueryBuilder {
instance.SMTPConfigRemovedEventType,
instance.SMTPConfigChangedEventType,
instance.SMTPConfigPasswordChangedEventType,
instance.SMTPConfigActivatedEventType,
instance.SMTPConfigDeactivatedEventType,
instance.SMTPConfigRemovedEventType,
instance.InstanceDomainAddedEventType,
instance.InstanceDomainRemovedEventType,
instance.DomainPolicyAddedEventType,
@@ -129,10 +130,16 @@ func (wm *InstanceSMTPConfigWriteModel) Query() *eventstore.SearchQueryBuilder {
Builder()
}
func (wm *InstanceSMTPConfigWriteModel) NewChangedEvent(ctx context.Context, aggregate *eventstore.Aggregate, tls bool, fromAddress, fromName, replyToAddress, smtpHost, smtpUser string) (*instance.SMTPConfigChangedEvent, bool, error) {
func (wm *IAMSMTPConfigWriteModel) NewChangedEvent(ctx context.Context, aggregate *eventstore.Aggregate, id, description string, tls bool, fromAddress, fromName, replyToAddress, smtpHost, smtpUser string, smtpPassword *crypto.CryptoValue) (*instance.SMTPConfigChangedEvent, bool, error) {
changes := make([]instance.SMTPConfigChanges, 0)
var err error
if wm.ID != id {
changes = append(changes, instance.ChangeSMTPConfigID(id))
}
if wm.Description != description {
changes = append(changes, instance.ChangeSMTPConfigDescription(description))
}
if wm.TLS != tls {
changes = append(changes, instance.ChangeSMTPConfigTLS(tls))
}
@@ -151,13 +158,87 @@ func (wm *InstanceSMTPConfigWriteModel) NewChangedEvent(ctx context.Context, agg
if wm.User != smtpUser {
changes = append(changes, instance.ChangeSMTPConfigSMTPUser(smtpUser))
}
if smtpPassword != nil {
changes = append(changes, instance.ChangeSMTPConfigSMTPPassword(smtpPassword))
}
if len(changes) == 0 {
return nil, false, nil
}
changeEvent, err := instance.NewSMTPConfigChangeEvent(ctx, aggregate, changes)
changeEvent, err := instance.NewSMTPConfigChangeEvent(ctx, aggregate, id, changes)
if err != nil {
return nil, false, err
}
return changeEvent, true, nil
}
func (wm *IAMSMTPConfigWriteModel) reduceSMTPConfigAddedEvent(e *instance.SMTPConfigAddedEvent) {
wm.Description = e.Description
wm.TLS = e.TLS
wm.Host = e.Host
wm.User = e.User
wm.Password = e.Password
wm.SenderAddress = e.SenderAddress
wm.SenderName = e.SenderName
wm.ReplyToAddress = e.ReplyToAddress
wm.State = domain.SMTPConfigStateInactive
// If ID has empty value we're dealing with the old and unique smtp settings
// These would be the default values for ID and State
if e.ID == "" {
wm.Description = "generic"
wm.ID = e.Aggregate().ResourceOwner
wm.State = domain.SMTPConfigStateActive
}
}
func (wm *IAMSMTPConfigWriteModel) reduceSMTPConfigChangedEvent(e *instance.SMTPConfigChangedEvent) {
if e.Description != nil {
wm.Description = *e.Description
}
if e.TLS != nil {
wm.TLS = *e.TLS
}
if e.Host != nil {
wm.Host = *e.Host
}
if e.User != nil {
wm.User = *e.User
}
if e.Password != nil {
wm.Password = e.Password
}
if e.FromAddress != nil {
wm.SenderAddress = *e.FromAddress
}
if e.FromName != nil {
wm.SenderName = *e.FromName
}
if e.ReplyToAddress != nil {
wm.ReplyToAddress = *e.ReplyToAddress
}
// If ID has empty value we're dealing with the old and unique smtp settings
// These would be the default values for ID and State
if e.ID == "" {
wm.Description = "generic"
wm.ID = e.Aggregate().ResourceOwner
wm.State = domain.SMTPConfigStateActive
}
}
func (wm *IAMSMTPConfigWriteModel) reduceSMTPConfigRemovedEvent(e *instance.SMTPConfigRemovedEvent) {
wm.Description = ""
wm.TLS = false
wm.SenderName = ""
wm.SenderAddress = ""
wm.ReplyToAddress = ""
wm.Host = ""
wm.User = ""
wm.Password = nil
wm.State = domain.SMTPConfigStateRemoved
// If ID has empty value we're dealing with the old and unique smtp settings
// These would be the default values for ID and State
if e.ID == "" {
wm.ID = e.Aggregate().ResourceOwner
}
}

View File

@@ -15,51 +15,153 @@ import (
"github.com/zitadel/zitadel/internal/zerrors"
)
func (c *Commands) AddSMTPConfig(ctx context.Context, config *smtp.Config) (*domain.ObjectDetails, error) {
instanceAgg := instance.NewAggregate(authz.GetInstance(ctx).InstanceID())
validation := c.prepareAddSMTPConfig(instanceAgg, config.From, config.FromName, config.ReplyToAddress, config.SMTP.Host, config.SMTP.User, []byte(config.SMTP.Password), config.Tls)
cmds, err := preparation.PrepareCommands(ctx, c.eventstore.Filter, validation)
func (c *Commands) AddSMTPConfig(ctx context.Context, instanceID string, config *smtp.Config) (string, *domain.ObjectDetails, error) {
id, err := c.idGenerator.Next()
if err != nil {
return nil, err
return "", nil, err
}
events, err := c.eventstore.Push(ctx, cmds...)
from := strings.TrimSpace(config.From)
if from == "" {
return "", nil, zerrors.ThrowInvalidArgument(nil, "INST-ASv2d", "Errors.Invalid.Argument")
}
fromSplitted := strings.Split(from, "@")
senderDomain := fromSplitted[len(fromSplitted)-1]
description := strings.TrimSpace(config.Description)
replyTo := strings.TrimSpace(config.ReplyToAddress)
hostAndPort := strings.TrimSpace(config.SMTP.Host)
if _, _, err := net.SplitHostPort(hostAndPort); err != nil {
return "", nil, zerrors.ThrowInvalidArgument(nil, "INST-9JdRe", "Errors.Invalid.Argument")
}
var smtpPassword *crypto.CryptoValue
if config.SMTP.Password != "" {
smtpPassword, err = crypto.Encrypt([]byte(config.SMTP.Password), c.smtpEncryption)
if err != nil {
return "", nil, err
}
}
smtpConfigWriteModel, err := c.getSMTPConfig(ctx, instanceID, id, senderDomain)
if err != nil {
return nil, err
return "", nil, err
}
return &domain.ObjectDetails{
Sequence: events[len(events)-1].Sequence(),
EventDate: events[len(events)-1].CreatedAt(),
ResourceOwner: events[len(events)-1].Aggregate().InstanceID,
}, nil
err = checkSenderAddress(smtpConfigWriteModel)
if err != nil {
return "", nil, err
}
iamAgg := InstanceAggregateFromWriteModel(&smtpConfigWriteModel.WriteModel)
pushedEvents, err := c.eventstore.Push(ctx, instance.NewSMTPConfigAddedEvent(
ctx,
iamAgg,
id,
description,
config.Tls,
config.From,
config.FromName,
replyTo,
hostAndPort,
config.SMTP.User,
smtpPassword,
))
if err != nil {
return "", nil, err
}
err = AppendAndReduce(smtpConfigWriteModel, pushedEvents...)
if err != nil {
return "", nil, err
}
return id, writeModelToObjectDetails(&smtpConfigWriteModel.WriteModel), nil
}
func (c *Commands) ChangeSMTPConfig(ctx context.Context, config *smtp.Config) (*domain.ObjectDetails, error) {
instanceAgg := instance.NewAggregate(authz.GetInstance(ctx).InstanceID())
validation := c.prepareChangeSMTPConfig(instanceAgg, config.From, config.FromName, config.ReplyToAddress, config.SMTP.Host, config.SMTP.User, config.Tls)
cmds, err := preparation.PrepareCommands(ctx, c.eventstore.Filter, validation)
func (c *Commands) ChangeSMTPConfig(ctx context.Context, instanceID string, id string, config *smtp.Config) (*domain.ObjectDetails, error) {
if id == "" {
return nil, zerrors.ThrowInvalidArgument(nil, "SMTP-x8vo9", "Errors.IDMissing")
}
from := strings.TrimSpace(config.From)
if from == "" {
return nil, zerrors.ThrowInvalidArgument(nil, "INST-HSv2d", "Errors.Invalid.Argument")
}
fromSplitted := strings.Split(from, "@")
senderDomain := fromSplitted[len(fromSplitted)-1]
description := strings.TrimSpace(config.Description)
replyTo := strings.TrimSpace(config.ReplyToAddress)
hostAndPort := strings.TrimSpace(config.SMTP.Host)
if _, _, err := net.SplitHostPort(hostAndPort); err != nil {
return nil, zerrors.ThrowInvalidArgument(nil, "INST-Kv875", "Errors.Invalid.Argument")
}
var smtpPassword *crypto.CryptoValue
var err error
if config.SMTP.Password != "" {
smtpPassword, err = crypto.Encrypt([]byte(config.SMTP.Password), c.smtpEncryption)
if err != nil {
return nil, err
}
}
smtpConfigWriteModel, err := c.getSMTPConfig(ctx, instanceID, id, senderDomain)
if err != nil {
return nil, err
}
events, err := c.eventstore.Push(ctx, cmds...)
if !smtpConfigWriteModel.State.Exists() {
return nil, zerrors.ThrowNotFound(nil, "COMMAND-7j8gv", "Errors.SMTPConfig.NotFound")
}
err = checkSenderAddress(smtpConfigWriteModel)
if err != nil {
return nil, err
}
return &domain.ObjectDetails{
Sequence: events[len(events)-1].Sequence(),
EventDate: events[len(events)-1].CreatedAt(),
ResourceOwner: events[len(events)-1].Aggregate().InstanceID,
}, nil
iamAgg := InstanceAggregateFromWriteModel(&smtpConfigWriteModel.WriteModel)
changedEvent, hasChanged, err := smtpConfigWriteModel.NewChangedEvent(
ctx,
iamAgg,
id,
description,
config.Tls,
from,
config.FromName,
replyTo,
hostAndPort,
config.SMTP.User,
smtpPassword,
)
if err != nil {
return nil, err
}
if !hasChanged {
return nil, zerrors.ThrowPreconditionFailed(nil, "COMMAND-lh3op", "Errors.NoChangesFound")
}
pushedEvents, err := c.eventstore.Push(ctx, changedEvent)
if err != nil {
return nil, err
}
err = AppendAndReduce(smtpConfigWriteModel, pushedEvents...)
if err != nil {
return nil, err
}
return writeModelToObjectDetails(&smtpConfigWriteModel.WriteModel), nil
}
func (c *Commands) ChangeSMTPConfigPassword(ctx context.Context, password string) (*domain.ObjectDetails, error) {
func (c *Commands) ChangeSMTPConfigPassword(ctx context.Context, instanceID, id string, password string) (*domain.ObjectDetails, error) {
instanceAgg := instance.NewAggregate(authz.GetInstance(ctx).InstanceID())
smtpConfigWriteModel, err := getSMTPConfigWriteModel(ctx, c.eventstore.Filter, "")
smtpConfigWriteModel, err := c.getSMTPConfig(ctx, instanceID, id, "")
if err != nil {
return nil, err
}
if smtpConfigWriteModel.State != domain.SMTPConfigStateActive {
return nil, zerrors.ThrowNotFound(nil, "COMMAND-3n9ls", "Errors.SMTPConfig.NotFound")
}
var smtpPassword *crypto.CryptoValue
if password != "" {
smtpPassword, err = crypto.Encrypt([]byte(password), c.smtpEncryption)
@@ -67,39 +169,144 @@ func (c *Commands) ChangeSMTPConfigPassword(ctx context.Context, password string
return nil, err
}
}
events, err := c.eventstore.Push(ctx, instance.NewSMTPConfigPasswordChangedEvent(
pushedEvents, err := c.eventstore.Push(ctx, instance.NewSMTPConfigPasswordChangedEvent(
ctx,
&instanceAgg.Aggregate,
id,
smtpPassword))
if err != nil {
return nil, err
}
return &domain.ObjectDetails{
Sequence: events[len(events)-1].Sequence(),
EventDate: events[len(events)-1].CreatedAt(),
ResourceOwner: events[len(events)-1].Aggregate().InstanceID,
}, nil
}
func (c *Commands) RemoveSMTPConfig(ctx context.Context) (*domain.ObjectDetails, error) {
instanceAgg := instance.NewAggregate(authz.GetInstance(ctx).InstanceID())
validation := c.prepareRemoveSMTPConfig(instanceAgg)
cmds, err := preparation.PrepareCommands(ctx, c.eventstore.Filter, validation)
err = AppendAndReduce(smtpConfigWriteModel, pushedEvents...)
if err != nil {
return nil, err
}
events, err := c.eventstore.Push(ctx, cmds...)
return writeModelToObjectDetails(&smtpConfigWriteModel.WriteModel), nil
}
func (c *Commands) ActivateSMTPConfig(ctx context.Context, instanceID, id, activatedId string) (*domain.ObjectDetails, error) {
if id == "" {
return nil, zerrors.ThrowInvalidArgument(nil, "SMTP-nm56k", "Errors.IDMissing")
}
if len(activatedId) > 0 {
_, err := c.DeactivateSMTPConfig(ctx, instanceID, activatedId)
if err != nil {
return nil, err
}
}
smtpConfigWriteModel, err := c.getSMTPConfig(ctx, instanceID, id, "")
if err != nil {
return nil, err
}
return &domain.ObjectDetails{
Sequence: events[len(events)-1].Sequence(),
EventDate: events[len(events)-1].CreatedAt(),
ResourceOwner: events[len(events)-1].Aggregate().InstanceID,
}, nil
if !smtpConfigWriteModel.State.Exists() {
return nil, zerrors.ThrowNotFound(nil, "COMMAND-kg8yr", "Errors.SMTPConfig.NotFound")
}
if smtpConfigWriteModel.State == domain.SMTPConfigStateActive {
return nil, zerrors.ThrowNotFound(nil, "COMMAND-ed3lr", "Errors.SMTPConfig.AlreadyActive")
}
iamAgg := InstanceAggregateFromWriteModel(&smtpConfigWriteModel.WriteModel)
pushedEvents, err := c.eventstore.Push(ctx, instance.NewSMTPConfigActivatedEvent(
ctx,
iamAgg,
id))
if err != nil {
return nil, err
}
err = AppendAndReduce(smtpConfigWriteModel, pushedEvents...)
if err != nil {
return nil, err
}
return writeModelToObjectDetails(&smtpConfigWriteModel.WriteModel), nil
}
func (c *Commands) prepareAddSMTPConfig(a *instance.Aggregate, from, name, replyTo, hostAndPort, user string, password []byte, tls bool) preparation.Validation {
func (c *Commands) DeactivateSMTPConfig(ctx context.Context, instanceID, id string) (*domain.ObjectDetails, error) {
if id == "" {
return nil, zerrors.ThrowInvalidArgument(nil, "SMTP-98ikl", "Errors.IDMissing")
}
smtpConfigWriteModel, err := c.getSMTPConfig(ctx, instanceID, id, "")
if err != nil {
return nil, err
}
if !smtpConfigWriteModel.State.Exists() {
return nil, zerrors.ThrowNotFound(nil, "COMMAND-k39PJ", "Errors.SMTPConfig.NotFound")
}
if smtpConfigWriteModel.State == domain.SMTPConfigStateInactive {
return nil, zerrors.ThrowNotFound(nil, "COMMAND-km8g3", "Errors.SMTPConfig.AlreadyDeactivated")
}
iamAgg := InstanceAggregateFromWriteModel(&smtpConfigWriteModel.WriteModel)
pushedEvents, err := c.eventstore.Push(ctx, instance.NewSMTPConfigDeactivatedEvent(
ctx,
iamAgg,
id))
if err != nil {
return nil, err
}
err = AppendAndReduce(smtpConfigWriteModel, pushedEvents...)
if err != nil {
return nil, err
}
return writeModelToObjectDetails(&smtpConfigWriteModel.WriteModel), nil
}
func (c *Commands) RemoveSMTPConfig(ctx context.Context, instanceID, id string) (*domain.ObjectDetails, error) {
if id == "" {
return nil, zerrors.ThrowInvalidArgument(nil, "SMTP-7f5cv", "Errors.IDMissing")
}
smtpConfigWriteModel, err := c.getSMTPConfig(ctx, instanceID, id, "")
if err != nil {
return nil, err
}
if !smtpConfigWriteModel.State.Exists() {
return nil, zerrors.ThrowNotFound(nil, "COMMAND-kg8rt", "Errors.SMTPConfig.NotFound")
}
iamAgg := InstanceAggregateFromWriteModel(&smtpConfigWriteModel.WriteModel)
pushedEvents, err := c.eventstore.Push(ctx, instance.NewSMTPConfigRemovedEvent(
ctx,
iamAgg,
id))
if err != nil {
return nil, err
}
err = AppendAndReduce(smtpConfigWriteModel, pushedEvents...)
if err != nil {
return nil, err
}
return writeModelToObjectDetails(&smtpConfigWriteModel.WriteModel), nil
}
func checkSenderAddress(writeModel *IAMSMTPConfigWriteModel) error {
if !writeModel.smtpSenderAddressMatchesInstanceDomain {
return nil
}
if !writeModel.domainState.Exists() {
return zerrors.ThrowInvalidArgument(nil, "INST-83nl8", "Errors.SMTPConfig.SenderAdressNotCustomDomain")
}
return nil
}
func (c *Commands) getSMTPConfig(ctx context.Context, instanceID, id, domain string) (writeModel *IAMSMTPConfigWriteModel, err error) {
writeModel = NewIAMSMTPConfigWriteModel(instanceID, id, domain)
err = c.eventstore.FilterToQueryReducer(ctx, writeModel)
if err != nil {
return nil, err
}
return writeModel, nil
}
// TODO: SetUpInstance still uses this and would be removed as soon as deprecated PrepareCommands is removed
func (c *Commands) prepareAddSMTPConfig(a *instance.Aggregate, description, from, name, replyTo, hostAndPort, user string, password []byte, tls bool) preparation.Validation {
return func() (preparation.CreateCommands, error) {
if from = strings.TrimSpace(from); from == "" {
return nil, zerrors.ThrowInvalidArgument(nil, "INST-mruNY", "Errors.Invalid.Argument")
@@ -112,9 +319,14 @@ func (c *Commands) prepareAddSMTPConfig(a *instance.Aggregate, from, name, reply
return nil, zerrors.ThrowInvalidArgument(nil, "INST-9JdRe", "Errors.Invalid.Argument")
}
return func(ctx context.Context, filter preparation.FilterToQueryReducer) ([]eventstore.Command, error) {
id, err := c.idGenerator.Next()
if err != nil {
return nil, zerrors.ThrowInternal(nil, "INST-9JdRe", "Errors.Invalid.Argument")
}
fromSplitted := strings.Split(from, "@")
senderDomain := fromSplitted[len(fromSplitted)-1]
writeModel, err := getSMTPConfigWriteModel(ctx, filter, senderDomain)
writeModel, err := getSMTPConfigWriteModel(ctx, filter, id, senderDomain)
if err != nil {
return nil, err
}
@@ -136,6 +348,8 @@ func (c *Commands) prepareAddSMTPConfig(a *instance.Aggregate, from, name, reply
instance.NewSMTPConfigAddedEvent(
ctx,
&a.Aggregate,
id,
description,
tls,
from,
name,
@@ -149,83 +363,8 @@ func (c *Commands) prepareAddSMTPConfig(a *instance.Aggregate, from, name, reply
}
}
func (c *Commands) prepareChangeSMTPConfig(a *instance.Aggregate, from, name, replyTo, hostAndPort, user string, tls bool) preparation.Validation {
return func() (preparation.CreateCommands, error) {
if from = strings.TrimSpace(from); from == "" {
return nil, zerrors.ThrowInvalidArgument(nil, "INST-ASv2d", "Errors.Invalid.Argument")
}
replyTo = strings.TrimSpace(replyTo)
hostAndPort = strings.TrimSpace(hostAndPort)
if _, _, err := net.SplitHostPort(hostAndPort); err != nil {
return nil, zerrors.ThrowInvalidArgument(nil, "INST-Kv875", "Errors.Invalid.Argument")
}
return func(ctx context.Context, filter preparation.FilterToQueryReducer) ([]eventstore.Command, error) {
fromSplitted := strings.Split(from, "@")
senderDomain := fromSplitted[len(fromSplitted)-1]
writeModel, err := getSMTPConfigWriteModel(ctx, filter, senderDomain)
if err != nil {
return nil, err
}
if writeModel.State != domain.SMTPConfigStateActive {
return nil, zerrors.ThrowNotFound(nil, "INST-Svq1a", "Errors.SMTPConfig.NotFound")
}
err = checkSenderAddress(writeModel)
if err != nil {
return nil, err
}
changedEvent, hasChanged, err := writeModel.NewChangedEvent(
ctx,
&a.Aggregate,
tls,
from,
name,
replyTo,
hostAndPort,
user,
)
if err != nil {
return nil, err
}
if !hasChanged {
return nil, zerrors.ThrowPreconditionFailed(nil, "COMMAND-m0o3f", "Errors.NoChangesFound")
}
return []eventstore.Command{
changedEvent,
}, nil
}, nil
}
}
func (c *Commands) prepareRemoveSMTPConfig(a *instance.Aggregate) preparation.Validation {
return func() (preparation.CreateCommands, error) {
return func(ctx context.Context, filter preparation.FilterToQueryReducer) ([]eventstore.Command, error) {
writeModel, err := getSMTPConfigWriteModel(ctx, filter, "")
if err != nil {
return nil, err
}
if writeModel.State != domain.SMTPConfigStateActive {
return nil, zerrors.ThrowNotFound(nil, "INST-Sfefg", "Errors.SMTPConfig.NotFound")
}
return []eventstore.Command{
instance.NewSMTPConfigRemovedEvent(ctx, &a.Aggregate),
}, nil
}, nil
}
}
func checkSenderAddress(writeModel *InstanceSMTPConfigWriteModel) error {
if !writeModel.smtpSenderAddressMatchesInstanceDomain {
return nil
}
if !writeModel.domainState.Exists() {
return zerrors.ThrowInvalidArgument(nil, "INST-83nl8", "Errors.SMTPConfig.SenderAdressNotCustomDomain")
}
return nil
}
func getSMTPConfigWriteModel(ctx context.Context, filter preparation.FilterToQueryReducer, domain string) (_ *InstanceSMTPConfigWriteModel, err error) {
writeModel := NewInstanceSMTPConfigWriteModel(authz.GetInstance(ctx).InstanceID(), domain)
func getSMTPConfigWriteModel(ctx context.Context, filter preparation.FilterToQueryReducer, id, domain string) (_ *IAMSMTPConfigWriteModel, err error) {
writeModel := NewIAMSMTPConfigWriteModel(authz.GetInstance(ctx).InstanceID(), id, domain)
events, err := filter(ctx, writeModel.Query())
if err != nil {
return nil, err

View File

@@ -11,6 +11,8 @@ import (
"github.com/zitadel/zitadel/internal/crypto"
"github.com/zitadel/zitadel/internal/domain"
"github.com/zitadel/zitadel/internal/eventstore"
"github.com/zitadel/zitadel/internal/id"
id_mock "github.com/zitadel/zitadel/internal/id/mock"
"github.com/zitadel/zitadel/internal/notification/channels/smtp"
"github.com/zitadel/zitadel/internal/repository/instance"
"github.com/zitadel/zitadel/internal/zerrors"
@@ -18,12 +20,14 @@ import (
func TestCommandSide_AddSMTPConfig(t *testing.T) {
type fields struct {
eventstore *eventstore.Eventstore
alg crypto.EncryptionAlgorithm
eventstore *eventstore.Eventstore
idGenerator id.Generator
alg crypto.EncryptionAlgorithm
}
type args struct {
ctx context.Context
smtp *smtp.Config
ctx context.Context
instanceID string
smtp *smtp.Config
}
type res struct {
want *domain.ObjectDetails
@@ -51,13 +55,13 @@ func TestCommandSide_AddSMTPConfig(t *testing.T) {
),
),
),
idGenerator: id_mock.NewIDGeneratorExpectIDs(t, "configid"),
alg: crypto.CreateMockEncryptionAlg(gomock.NewController(t)),
},
args: args{
ctx: authz.WithInstanceID(context.Background(), "INSTANCE"),
smtp: &smtp.Config{
Tls: true,
From: "from@domain.ch",
FromName: "name",
From: "from@domain.ch",
SMTP: smtp.SMTP{
Host: "host:587",
User: "user",
@@ -69,58 +73,6 @@ func TestCommandSide_AddSMTPConfig(t *testing.T) {
err: zerrors.IsErrorInvalidArgument,
},
},
{
name: "smtp config, error already exists",
fields: fields{
eventstore: eventstoreExpect(
t,
expectFilter(
eventFromEventPusher(
instance.NewDomainAddedEvent(context.Background(),
&instance.NewAggregate("INSTANCE").Aggregate,
"domain.ch",
false,
),
),
eventFromEventPusher(
instance.NewDomainPolicyAddedEvent(context.Background(),
&instance.NewAggregate("INSTANCE").Aggregate,
true, true, false,
),
),
eventFromEventPusher(
instance.NewSMTPConfigAddedEvent(context.Background(),
&instance.NewAggregate("INSTANCE").Aggregate,
true,
"from@domain.ch",
"name",
"",
"host:587",
"user",
&crypto.CryptoValue{},
),
),
),
),
},
args: args{
ctx: authz.WithInstanceID(context.Background(), "INSTANCE"),
smtp: &smtp.Config{
Tls: true,
From: "from@domain.ch",
FromName: "name",
ReplyToAddress: "",
SMTP: smtp.SMTP{
Host: "host:587",
User: "user",
Password: "password",
},
},
},
res: res{
err: zerrors.IsErrorAlreadyExists,
},
},
{
name: "add smtp config, ok",
fields: fields{
@@ -145,6 +97,8 @@ func TestCommandSide_AddSMTPConfig(t *testing.T) {
instance.NewSMTPConfigAddedEvent(
context.Background(),
&instance.NewAggregate("INSTANCE").Aggregate,
"configid",
"test",
true,
"from@domain.ch",
"name",
@@ -160,14 +114,16 @@ func TestCommandSide_AddSMTPConfig(t *testing.T) {
),
),
),
alg: crypto.CreateMockEncryptionAlg(gomock.NewController(t)),
idGenerator: id_mock.NewIDGeneratorExpectIDs(t, "configid"),
alg: crypto.CreateMockEncryptionAlg(gomock.NewController(t)),
},
args: args{
ctx: authz.WithInstanceID(context.Background(), "INSTANCE"),
smtp: &smtp.Config{
Tls: true,
From: "from@domain.ch",
FromName: "name",
Description: "test",
Tls: true,
From: "from@domain.ch",
FromName: "name",
SMTP: smtp.SMTP{
Host: "host:587",
User: "user",
@@ -205,6 +161,8 @@ func TestCommandSide_AddSMTPConfig(t *testing.T) {
instance.NewSMTPConfigAddedEvent(
context.Background(),
&instance.NewAggregate("INSTANCE").Aggregate,
"configid",
"test",
true,
"from@domain.ch",
"name",
@@ -220,11 +178,13 @@ func TestCommandSide_AddSMTPConfig(t *testing.T) {
),
),
),
alg: crypto.CreateMockEncryptionAlg(gomock.NewController(t)),
idGenerator: id_mock.NewIDGeneratorExpectIDs(t, "configid"),
alg: crypto.CreateMockEncryptionAlg(gomock.NewController(t)),
},
args: args{
ctx: authz.WithInstanceID(context.Background(), "INSTANCE"),
smtp: &smtp.Config{
Description: "test",
Tls: true,
From: "from@domain.ch",
FromName: "name",
@@ -245,14 +205,17 @@ func TestCommandSide_AddSMTPConfig(t *testing.T) {
{
name: "smtp config, port is missing",
fields: fields{
eventstore: eventstoreExpect(t),
eventstore: eventstoreExpect(t),
idGenerator: id_mock.NewIDGeneratorExpectIDs(t, "configid"),
alg: crypto.CreateMockEncryptionAlg(gomock.NewController(t)),
},
args: args{
ctx: authz.WithInstanceID(context.Background(), "INSTANCE"),
smtp: &smtp.Config{
Tls: true,
From: "from@domain.ch",
FromName: "name",
Description: "test",
Tls: true,
From: "from@domain.ch",
FromName: "name",
SMTP: smtp.SMTP{
Host: "host",
User: "user",
@@ -267,14 +230,17 @@ func TestCommandSide_AddSMTPConfig(t *testing.T) {
{
name: "smtp config, host is empty",
fields: fields{
eventstore: eventstoreExpect(t),
eventstore: eventstoreExpect(t),
idGenerator: id_mock.NewIDGeneratorExpectIDs(t, "configid"),
alg: crypto.CreateMockEncryptionAlg(gomock.NewController(t)),
},
args: args{
ctx: authz.WithInstanceID(context.Background(), "INSTANCE"),
smtp: &smtp.Config{
Tls: true,
From: "from@domain.ch",
FromName: "name",
Description: "test",
Tls: true,
From: "from@domain.ch",
FromName: "name",
SMTP: smtp.SMTP{
Host: " ",
User: "user",
@@ -310,6 +276,8 @@ func TestCommandSide_AddSMTPConfig(t *testing.T) {
instance.NewSMTPConfigAddedEvent(
context.Background(),
&instance.NewAggregate("INSTANCE").Aggregate,
"configid",
"test",
true,
"from@domain.ch",
"name",
@@ -325,14 +293,16 @@ func TestCommandSide_AddSMTPConfig(t *testing.T) {
),
),
),
alg: crypto.CreateMockEncryptionAlg(gomock.NewController(t)),
alg: crypto.CreateMockEncryptionAlg(gomock.NewController(t)),
idGenerator: id_mock.NewIDGeneratorExpectIDs(t, "configid"),
},
args: args{
ctx: authz.WithInstanceID(context.Background(), "INSTANCE"),
smtp: &smtp.Config{
Tls: true,
From: "from@domain.ch",
FromName: "name",
Description: "test",
Tls: true,
From: "from@domain.ch",
FromName: "name",
SMTP: smtp.SMTP{
Host: "[2001:db8::1]:2525",
User: "user",
@@ -351,9 +321,10 @@ func TestCommandSide_AddSMTPConfig(t *testing.T) {
t.Run(tt.name, func(t *testing.T) {
r := &Commands{
eventstore: tt.fields.eventstore,
idGenerator: tt.fields.idGenerator,
smtpEncryption: tt.fields.alg,
}
got, err := r.AddSMTPConfig(tt.args.ctx, tt.args.smtp)
_, got, err := r.AddSMTPConfig(tt.args.ctx, tt.args.instanceID, tt.args.smtp)
if tt.res.err == nil {
assert.NoError(t, err)
}
@@ -372,8 +343,10 @@ func TestCommandSide_ChangeSMTPConfig(t *testing.T) {
eventstore *eventstore.Eventstore
}
type args struct {
ctx context.Context
smtp *smtp.Config
ctx context.Context
instanceID string
id string
smtp *smtp.Config
}
type res struct {
want *domain.ObjectDetails
@@ -385,6 +358,21 @@ func TestCommandSide_ChangeSMTPConfig(t *testing.T) {
args args
res res
}{
{
name: "id empty, precondition error",
fields: fields{
eventstore: eventstoreExpect(
t,
),
},
args: args{
ctx: authz.WithInstanceID(context.Background(), "INSTANCE"),
smtp: &smtp.Config{},
},
res: res{
err: zerrors.IsErrorInvalidArgument,
},
},
{
name: "empty config, invalid argument error",
fields: fields{
@@ -395,6 +383,7 @@ func TestCommandSide_ChangeSMTPConfig(t *testing.T) {
args: args{
ctx: authz.WithInstanceID(context.Background(), "INSTANCE"),
smtp: &smtp.Config{},
id: "configID",
},
res: res{
err: zerrors.IsErrorInvalidArgument,
@@ -411,14 +400,17 @@ func TestCommandSide_ChangeSMTPConfig(t *testing.T) {
args: args{
ctx: authz.WithInstanceID(context.Background(), "INSTANCE"),
smtp: &smtp.Config{
Tls: true,
From: "from@domain.ch",
FromName: "name",
Description: "test",
Tls: true,
From: "from@domain.ch",
FromName: "name",
SMTP: smtp.SMTP{
Host: "host:587",
User: "user",
},
},
instanceID: "INSTANCE",
id: "ID",
},
res: res{
err: zerrors.IsNotFound,
@@ -447,6 +439,8 @@ func TestCommandSide_ChangeSMTPConfig(t *testing.T) {
instance.NewSMTPConfigAddedEvent(
context.Background(),
&instance.NewAggregate("INSTANCE").Aggregate,
"ID",
"test",
true,
"from@domain.ch",
"name",
@@ -460,11 +454,14 @@ func TestCommandSide_ChangeSMTPConfig(t *testing.T) {
),
},
args: args{
ctx: authz.WithInstanceID(context.Background(), "INSTANCE"),
ctx: authz.WithInstanceID(context.Background(), "INSTANCE"),
instanceID: "INSTANCE",
id: "ID",
smtp: &smtp.Config{
Tls: true,
From: "from@wrongdomain.ch",
FromName: "name",
Description: "test",
Tls: true,
From: "from@wrongdomain.ch",
FromName: "name",
SMTP: smtp.SMTP{
Host: "host:587",
User: "user",
@@ -498,6 +495,8 @@ func TestCommandSide_ChangeSMTPConfig(t *testing.T) {
instance.NewSMTPConfigAddedEvent(
context.Background(),
&instance.NewAggregate("INSTANCE").Aggregate,
"ID",
"test",
true,
"from@domain.ch",
"name",
@@ -513,14 +512,17 @@ func TestCommandSide_ChangeSMTPConfig(t *testing.T) {
args: args{
ctx: authz.WithInstanceID(context.Background(), "INSTANCE"),
smtp: &smtp.Config{
Tls: true,
From: "from@domain.ch",
FromName: "name",
Description: "test",
Tls: true,
From: "from@domain.ch",
FromName: "name",
SMTP: smtp.SMTP{
Host: "host:587",
User: "user",
},
},
instanceID: "INSTANCE",
id: "ID",
},
res: res{
err: zerrors.IsPreconditionFailed,
@@ -549,6 +551,8 @@ func TestCommandSide_ChangeSMTPConfig(t *testing.T) {
instance.NewSMTPConfigAddedEvent(
context.Background(),
&instance.NewAggregate("INSTANCE").Aggregate,
"ID",
"",
true,
"from@domain.ch",
"name",
@@ -562,6 +566,8 @@ func TestCommandSide_ChangeSMTPConfig(t *testing.T) {
expectPush(
newSMTPConfigChangedEvent(
context.Background(),
"ID",
"test",
false,
"from2@domain.ch",
"name2",
@@ -575,6 +581,7 @@ func TestCommandSide_ChangeSMTPConfig(t *testing.T) {
args: args{
ctx: authz.WithInstanceID(context.Background(), "INSTANCE"),
smtp: &smtp.Config{
Description: "test",
Tls: false,
From: "from2@domain.ch",
FromName: "name2",
@@ -584,6 +591,8 @@ func TestCommandSide_ChangeSMTPConfig(t *testing.T) {
User: "user2",
},
},
id: "ID",
instanceID: "INSTANCE",
},
res: res{
want: &domain.ObjectDetails{
@@ -599,15 +608,18 @@ func TestCommandSide_ChangeSMTPConfig(t *testing.T) {
args: args{
ctx: authz.WithInstanceID(context.Background(), "INSTANCE"),
smtp: &smtp.Config{
Tls: true,
From: "from@domain.ch",
FromName: "name",
Description: "test",
Tls: true,
From: "from@domain.ch",
FromName: "name",
SMTP: smtp.SMTP{
Host: "host",
User: "user",
Password: "password",
},
},
instanceID: "INSTANCE",
id: "ID",
},
res: res{
err: zerrors.IsErrorInvalidArgument,
@@ -621,15 +633,18 @@ func TestCommandSide_ChangeSMTPConfig(t *testing.T) {
args: args{
ctx: authz.WithInstanceID(context.Background(), "INSTANCE"),
smtp: &smtp.Config{
Tls: true,
From: "from@domain.ch",
FromName: "name",
Description: "test",
Tls: true,
From: "from@domain.ch",
FromName: "name",
SMTP: smtp.SMTP{
Host: " ",
User: "user",
Password: "password",
},
},
instanceID: "INSTANCE",
id: "ID",
},
res: res{
err: zerrors.IsErrorInvalidArgument,
@@ -658,6 +673,8 @@ func TestCommandSide_ChangeSMTPConfig(t *testing.T) {
instance.NewSMTPConfigAddedEvent(
context.Background(),
&instance.NewAggregate("INSTANCE").Aggregate,
"ID",
"",
true,
"from@domain.ch",
"name",
@@ -671,6 +688,8 @@ func TestCommandSide_ChangeSMTPConfig(t *testing.T) {
expectPush(
newSMTPConfigChangedEvent(
context.Background(),
"ID",
"test",
false,
"from2@domain.ch",
"name2",
@@ -684,6 +703,7 @@ func TestCommandSide_ChangeSMTPConfig(t *testing.T) {
args: args{
ctx: authz.WithInstanceID(context.Background(), "INSTANCE"),
smtp: &smtp.Config{
Description: "test",
Tls: false,
From: "from2@domain.ch",
FromName: "name2",
@@ -693,6 +713,8 @@ func TestCommandSide_ChangeSMTPConfig(t *testing.T) {
User: "user2",
},
},
instanceID: "INSTANCE",
id: "ID",
},
res: res{
want: &domain.ObjectDetails{
@@ -706,7 +728,7 @@ func TestCommandSide_ChangeSMTPConfig(t *testing.T) {
r := &Commands{
eventstore: tt.fields.eventstore,
}
got, err := r.ChangeSMTPConfig(tt.args.ctx, tt.args.smtp)
got, err := r.ChangeSMTPConfig(tt.args.ctx, tt.args.instanceID, tt.args.id, tt.args.smtp)
if tt.res.err == nil {
assert.NoError(t, err)
}
@@ -726,8 +748,10 @@ func TestCommandSide_ChangeSMTPConfigPassword(t *testing.T) {
alg crypto.EncryptionAlgorithm
}
type args struct {
ctx context.Context
password string
ctx context.Context
instanceID string
id string
password string
}
type res struct {
want *domain.ObjectDetails
@@ -750,6 +774,7 @@ func TestCommandSide_ChangeSMTPConfigPassword(t *testing.T) {
args: args{
ctx: context.Background(),
password: "",
id: "ID",
},
res: res{
err: zerrors.IsNotFound,
@@ -765,6 +790,8 @@ func TestCommandSide_ChangeSMTPConfigPassword(t *testing.T) {
instance.NewSMTPConfigAddedEvent(
context.Background(),
&instance.NewAggregate("INSTANCE").Aggregate,
"ID",
"test",
true,
"from",
"name",
@@ -774,11 +801,19 @@ func TestCommandSide_ChangeSMTPConfigPassword(t *testing.T) {
&crypto.CryptoValue{},
),
),
eventFromEventPusher(
instance.NewSMTPConfigActivatedEvent(
context.Background(),
&instance.NewAggregate("INSTANCE").Aggregate,
"ID",
),
),
),
expectPush(
instance.NewSMTPConfigPasswordChangedEvent(
context.Background(),
&instance.NewAggregate("INSTANCE").Aggregate,
"ID",
&crypto.CryptoValue{
CryptoType: crypto.TypeEncryption,
Algorithm: "enc",
@@ -791,8 +826,10 @@ func TestCommandSide_ChangeSMTPConfigPassword(t *testing.T) {
alg: crypto.CreateMockEncryptionAlg(gomock.NewController(t)),
},
args: args{
ctx: authz.WithInstanceID(context.Background(), "INSTANCE"),
password: "password",
ctx: authz.WithInstanceID(context.Background(), "INSTANCE"),
password: "password",
id: "ID",
instanceID: "INSTANCE",
},
res: res{
want: &domain.ObjectDetails{
@@ -807,7 +844,246 @@ func TestCommandSide_ChangeSMTPConfigPassword(t *testing.T) {
eventstore: tt.fields.eventstore,
smtpEncryption: tt.fields.alg,
}
got, err := r.ChangeSMTPConfigPassword(tt.args.ctx, tt.args.password)
got, err := r.ChangeSMTPConfigPassword(tt.args.ctx, tt.args.instanceID, tt.args.id, tt.args.password)
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_ActivateSMTPConfig(t *testing.T) {
type fields struct {
eventstore *eventstore.Eventstore
alg crypto.EncryptionAlgorithm
}
type args struct {
ctx context.Context
instanceID string
id string
activatedId string
}
type res struct {
want *domain.ObjectDetails
err func(error) bool
}
tests := []struct {
name string
fields fields
args args
res res
}{
{
name: "id empty, precondition error",
fields: fields{
eventstore: eventstoreExpect(
t,
),
},
args: args{
ctx: authz.WithInstanceID(context.Background(), "INSTANCE"),
},
res: res{
err: zerrors.IsErrorInvalidArgument,
},
},
{
name: "smtp not existing, not found error",
fields: fields{
eventstore: eventstoreExpect(
t,
expectFilter(),
),
},
args: args{
ctx: context.Background(),
instanceID: "INSTANCE",
id: "id",
},
res: res{
err: zerrors.IsNotFound,
},
},
{
name: "activate smtp config, ok",
fields: fields{
eventstore: eventstoreExpect(
t,
expectFilter(
eventFromEventPusher(
instance.NewSMTPConfigAddedEvent(
context.Background(),
&instance.NewAggregate("INSTANCE").Aggregate,
"ID",
"test",
true,
"from",
"name",
"",
"host:587",
"user",
&crypto.CryptoValue{},
),
),
),
expectPush(
instance.NewSMTPConfigActivatedEvent(
context.Background(),
&instance.NewAggregate("INSTANCE").Aggregate,
"ID",
),
),
),
},
args: args{
ctx: authz.WithInstanceID(context.Background(), "INSTANCE"),
id: "ID",
instanceID: "INSTANCE",
activatedId: "",
},
res: res{
want: &domain.ObjectDetails{
ResourceOwner: "INSTANCE",
},
},
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
r := &Commands{
eventstore: tt.fields.eventstore,
smtpEncryption: tt.fields.alg,
}
got, err := r.ActivateSMTPConfig(tt.args.ctx, tt.args.instanceID, tt.args.id, tt.args.activatedId)
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_DeactivateSMTPConfig(t *testing.T) {
type fields struct {
eventstore *eventstore.Eventstore
alg crypto.EncryptionAlgorithm
}
type args struct {
ctx context.Context
instanceID string
id string
activatedId string
}
type res struct {
want *domain.ObjectDetails
err func(error) bool
}
tests := []struct {
name string
fields fields
args args
res res
}{
{
name: "id empty, precondition error",
fields: fields{
eventstore: eventstoreExpect(
t,
),
},
args: args{
ctx: authz.WithInstanceID(context.Background(), "INSTANCE"),
},
res: res{
err: zerrors.IsErrorInvalidArgument,
},
},
{
name: "smtp not existing, not found error",
fields: fields{
eventstore: eventstoreExpect(
t,
expectFilter(),
),
},
args: args{
ctx: context.Background(),
instanceID: "INSTANCE",
id: "id",
},
res: res{
err: zerrors.IsNotFound,
},
},
{
name: "deactivate smtp config, ok",
fields: fields{
eventstore: eventstoreExpect(
t,
expectFilter(
eventFromEventPusher(
instance.NewSMTPConfigAddedEvent(
context.Background(),
&instance.NewAggregate("INSTANCE").Aggregate,
"ID",
"test",
true,
"from",
"name",
"",
"host:587",
"user",
&crypto.CryptoValue{},
),
),
eventFromEventPusher(
instance.NewSMTPConfigActivatedEvent(
context.Background(),
&instance.NewAggregate("INSTANCE").Aggregate,
"ID",
),
),
),
expectPush(
instance.NewSMTPConfigDeactivatedEvent(
context.Background(),
&instance.NewAggregate("INSTANCE").Aggregate,
"ID",
),
),
),
},
args: args{
ctx: authz.WithInstanceID(context.Background(), "INSTANCE"),
id: "ID",
instanceID: "INSTANCE",
activatedId: "",
},
res: res{
want: &domain.ObjectDetails{
ResourceOwner: "INSTANCE",
},
},
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
r := &Commands{
eventstore: tt.fields.eventstore,
smtpEncryption: tt.fields.alg,
}
got, err := r.DeactivateSMTPConfig(tt.args.ctx, tt.args.instanceID, tt.args.id)
if tt.res.err == nil {
assert.NoError(t, err)
}
@@ -827,7 +1103,9 @@ func TestCommandSide_RemoveSMTPConfig(t *testing.T) {
alg crypto.EncryptionAlgorithm
}
type args struct {
ctx context.Context
ctx context.Context
instanceID string
id string
}
type res struct {
want *domain.ObjectDetails
@@ -849,6 +1127,7 @@ func TestCommandSide_RemoveSMTPConfig(t *testing.T) {
},
args: args{
ctx: context.Background(),
id: "ID",
},
res: res{
err: zerrors.IsNotFound,
@@ -864,6 +1143,8 @@ func TestCommandSide_RemoveSMTPConfig(t *testing.T) {
instance.NewSMTPConfigAddedEvent(
context.Background(),
&instance.NewAggregate("INSTANCE").Aggregate,
"ID",
"test",
true,
"from",
"name",
@@ -878,12 +1159,15 @@ func TestCommandSide_RemoveSMTPConfig(t *testing.T) {
instance.NewSMTPConfigRemovedEvent(
context.Background(),
&instance.NewAggregate("INSTANCE").Aggregate,
"ID",
),
),
),
},
args: args{
ctx: authz.WithInstanceID(context.Background(), "INSTANCE"),
ctx: authz.WithInstanceID(context.Background(), "INSTANCE"),
id: "ID",
instanceID: "INSTANCE",
},
res: res{
want: &domain.ObjectDetails{
@@ -898,7 +1182,7 @@ func TestCommandSide_RemoveSMTPConfig(t *testing.T) {
eventstore: tt.fields.eventstore,
smtpEncryption: tt.fields.alg,
}
got, err := r.RemoveSMTPConfig(tt.args.ctx)
got, err := r.RemoveSMTPConfig(tt.args.ctx, tt.args.instanceID, tt.args.id)
if tt.res.err == nil {
assert.NoError(t, err)
}
@@ -912,8 +1196,9 @@ func TestCommandSide_RemoveSMTPConfig(t *testing.T) {
}
}
func newSMTPConfigChangedEvent(ctx context.Context, tls bool, fromAddress, fromName, replyTo, host, user string) *instance.SMTPConfigChangedEvent {
func newSMTPConfigChangedEvent(ctx context.Context, id, description string, tls bool, fromAddress, fromName, replyTo, host, user string) *instance.SMTPConfigChangedEvent {
changes := []instance.SMTPConfigChanges{
instance.ChangeSMTPConfigDescription(description),
instance.ChangeSMTPConfigTLS(tls),
instance.ChangeSMTPConfigFromAddress(fromAddress),
instance.ChangeSMTPConfigFromName(fromName),
@@ -923,6 +1208,7 @@ func newSMTPConfigChangedEvent(ctx context.Context, tls bool, fromAddress, fromN
}
event, _ := instance.NewSMTPConfigChangeEvent(ctx,
&instance.NewAggregate("INSTANCE").Aggregate,
id,
changes,
)
return event