mirror of
https://github.com/zitadel/zitadel.git
synced 2025-01-07 18:17:42 +00:00
feat: enable default smtp config on setup (#3622)
* feat: enable default smtp config on setup * fix tests * fix channel order Co-authored-by: Fabi <38692350+fgerschwiler@users.noreply.github.com>
This commit is contained in:
parent
5571db3e1b
commit
024eedc1b5
@ -24,6 +24,7 @@ type DefaultInstance struct {
|
|||||||
|
|
||||||
instanceSetup command.InstanceSetup
|
instanceSetup command.InstanceSetup
|
||||||
userEncryptionKey *crypto.KeyConfig
|
userEncryptionKey *crypto.KeyConfig
|
||||||
|
smtpEncryptionKey *crypto.KeyConfig
|
||||||
masterKey string
|
masterKey string
|
||||||
db *sql.DB
|
db *sql.DB
|
||||||
es *eventstore.Eventstore
|
es *eventstore.Eventstore
|
||||||
@ -42,12 +43,19 @@ func (mig *DefaultInstance) Execute(ctx context.Context) error {
|
|||||||
if err = verifyKey(mig.userEncryptionKey, keyStorage); err != nil {
|
if err = verifyKey(mig.userEncryptionKey, keyStorage); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
userAlg, err := crypto.NewAESCrypto(mig.userEncryptionKey, keyStorage)
|
userAlg, err := crypto.NewAESCrypto(mig.userEncryptionKey, keyStorage)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if err = verifyKey(mig.smtpEncryptionKey, keyStorage); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
smtpEncryption, err := crypto.NewAESCrypto(mig.smtpEncryptionKey, keyStorage)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
cmd, err := command.StartCommands(mig.es,
|
cmd, err := command.StartCommands(mig.es,
|
||||||
mig.defaults,
|
mig.defaults,
|
||||||
mig.zitadelRoles,
|
mig.zitadelRoles,
|
||||||
@ -58,7 +66,7 @@ func (mig *DefaultInstance) Execute(ctx context.Context) error {
|
|||||||
mig.externalPort,
|
mig.externalPort,
|
||||||
nil,
|
nil,
|
||||||
nil,
|
nil,
|
||||||
nil,
|
smtpEncryption,
|
||||||
nil,
|
nil,
|
||||||
userAlg,
|
userAlg,
|
||||||
nil,
|
nil,
|
||||||
|
@ -53,6 +53,7 @@ type Steps struct {
|
|||||||
|
|
||||||
type encryptionKeyConfig struct {
|
type encryptionKeyConfig struct {
|
||||||
User *crypto.KeyConfig
|
User *crypto.KeyConfig
|
||||||
|
SMTP *crypto.KeyConfig
|
||||||
}
|
}
|
||||||
|
|
||||||
func MustNewSteps(v *viper.Viper) *Steps {
|
func MustNewSteps(v *viper.Viper) *Steps {
|
||||||
|
@ -61,6 +61,7 @@ func Setup(config *Config, steps *Steps, masterKey string) {
|
|||||||
|
|
||||||
steps.S3DefaultInstance.instanceSetup = config.DefaultInstance
|
steps.S3DefaultInstance.instanceSetup = config.DefaultInstance
|
||||||
steps.S3DefaultInstance.userEncryptionKey = config.EncryptionKeys.User
|
steps.S3DefaultInstance.userEncryptionKey = config.EncryptionKeys.User
|
||||||
|
steps.S3DefaultInstance.smtpEncryptionKey = config.EncryptionKeys.SMTP
|
||||||
steps.S3DefaultInstance.masterKey = masterKey
|
steps.S3DefaultInstance.masterKey = masterKey
|
||||||
steps.S3DefaultInstance.db = dbClient
|
steps.S3DefaultInstance.db = dbClient
|
||||||
steps.S3DefaultInstance.es = eventstoreClient
|
steps.S3DefaultInstance.es = eventstoreClient
|
||||||
|
@ -56,7 +56,7 @@ func (s *Server) GetSMTPConfig(ctx context.Context, req *admin_pb.GetSMTPConfigR
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (s *Server) UpdateSMTPConfig(ctx context.Context, req *admin_pb.UpdateSMTPConfigRequest) (*admin_pb.UpdateSMTPConfigResponse, error) {
|
func (s *Server) UpdateSMTPConfig(ctx context.Context, req *admin_pb.UpdateSMTPConfigRequest) (*admin_pb.UpdateSMTPConfigResponse, error) {
|
||||||
details, err := s.command.ChangeSMTPConfig(ctx, authz.GetInstance(ctx).InstanceID(), UpdateSMTPToConfig(req))
|
details, err := s.command.ChangeSMTPConfig(ctx, UpdateSMTPToConfig(req))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@ -69,7 +69,7 @@ func (s *Server) UpdateSMTPConfig(ctx context.Context, req *admin_pb.UpdateSMTPC
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (s *Server) UpdateSMTPConfigPassword(ctx context.Context, req *admin_pb.UpdateSMTPConfigPasswordRequest) (*admin_pb.UpdateSMTPConfigPasswordResponse, error) {
|
func (s *Server) UpdateSMTPConfigPassword(ctx context.Context, req *admin_pb.UpdateSMTPConfigPasswordRequest) (*admin_pb.UpdateSMTPConfigPasswordResponse, error) {
|
||||||
details, err := s.command.ChangeSMTPConfigPassword(ctx, authz.GetInstance(ctx).InstanceID(), req.Password)
|
details, err := s.command.ChangeSMTPConfigPassword(ctx, req.Password)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
@ -14,6 +14,7 @@ import (
|
|||||||
"github.com/zitadel/zitadel/internal/errors"
|
"github.com/zitadel/zitadel/internal/errors"
|
||||||
"github.com/zitadel/zitadel/internal/eventstore"
|
"github.com/zitadel/zitadel/internal/eventstore"
|
||||||
"github.com/zitadel/zitadel/internal/id"
|
"github.com/zitadel/zitadel/internal/id"
|
||||||
|
"github.com/zitadel/zitadel/internal/notification/channels/smtp"
|
||||||
"github.com/zitadel/zitadel/internal/repository/instance"
|
"github.com/zitadel/zitadel/internal/repository/instance"
|
||||||
"github.com/zitadel/zitadel/internal/repository/org"
|
"github.com/zitadel/zitadel/internal/repository/org"
|
||||||
"github.com/zitadel/zitadel/internal/repository/project"
|
"github.com/zitadel/zitadel/internal/repository/project"
|
||||||
@ -96,8 +97,9 @@ type InstanceSetup struct {
|
|||||||
MaxAttempts uint64
|
MaxAttempts uint64
|
||||||
ShouldShowLockoutFailure bool
|
ShouldShowLockoutFailure bool
|
||||||
}
|
}
|
||||||
EmailTemplate []byte
|
EmailTemplate []byte
|
||||||
MessageTexts []*domain.CustomMessageText
|
MessageTexts []*domain.CustomMessageText
|
||||||
|
SMTPConfiguration *smtp.EmailConfig
|
||||||
}
|
}
|
||||||
|
|
||||||
type ZitadelConfig struct {
|
type ZitadelConfig struct {
|
||||||
@ -261,6 +263,20 @@ func (c *Commands) SetUpInstance(ctx context.Context, setup *InstanceSetup) (str
|
|||||||
ClockSkew: 0,
|
ClockSkew: 0,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if setup.SMTPConfiguration != nil {
|
||||||
|
validations = append(validations,
|
||||||
|
c.prepareAddSMTPConfig(
|
||||||
|
instanceAgg,
|
||||||
|
setup.SMTPConfiguration.From,
|
||||||
|
setup.SMTPConfiguration.FromName,
|
||||||
|
setup.SMTPConfiguration.SMTP.Host,
|
||||||
|
setup.SMTPConfiguration.SMTP.User,
|
||||||
|
[]byte(setup.SMTPConfiguration.SMTP.Password),
|
||||||
|
setup.SMTPConfiguration.Tls,
|
||||||
|
),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
validations = append(validations,
|
validations = append(validations,
|
||||||
AddOrgCommand(ctx, orgAgg, setup.Org.Name),
|
AddOrgCommand(ctx, orgAgg, setup.Org.Name),
|
||||||
AddHumanCommand(userAgg, &setup.Org.Human, c.userPasswordAlg, c.userEncryption),
|
AddHumanCommand(userAgg, &setup.Org.Human, c.userPasswordAlg, c.userEncryption),
|
||||||
|
@ -45,7 +45,7 @@ func (wm *InstanceSecretGeneratorConfigWriteModel) Reduce() error {
|
|||||||
wm.IncludeLowerLetters = e.IncludeLowerLetters
|
wm.IncludeLowerLetters = e.IncludeLowerLetters
|
||||||
wm.IncludeUpperLetters = e.IncludeUpperLetters
|
wm.IncludeUpperLetters = e.IncludeUpperLetters
|
||||||
wm.IncludeDigits = e.IncludeDigits
|
wm.IncludeDigits = e.IncludeDigits
|
||||||
wm.IncludeSymbols = e.IncludeDigits
|
wm.IncludeSymbols = e.IncludeSymbols
|
||||||
wm.State = domain.SecretGeneratorStateActive
|
wm.State = domain.SecretGeneratorStateActive
|
||||||
case *instance.SecretGeneratorChangedEvent:
|
case *instance.SecretGeneratorChangedEvent:
|
||||||
if wm.GeneratorType != e.GeneratorType {
|
if wm.GeneratorType != e.GeneratorType {
|
||||||
|
@ -2,118 +2,169 @@ package command
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
"strings"
|
||||||
|
|
||||||
|
"github.com/zitadel/zitadel/internal/api/authz"
|
||||||
|
"github.com/zitadel/zitadel/internal/command/preparation"
|
||||||
"github.com/zitadel/zitadel/internal/crypto"
|
"github.com/zitadel/zitadel/internal/crypto"
|
||||||
"github.com/zitadel/zitadel/internal/domain"
|
"github.com/zitadel/zitadel/internal/domain"
|
||||||
|
"github.com/zitadel/zitadel/internal/errors"
|
||||||
caos_errs "github.com/zitadel/zitadel/internal/errors"
|
caos_errs "github.com/zitadel/zitadel/internal/errors"
|
||||||
|
"github.com/zitadel/zitadel/internal/eventstore"
|
||||||
"github.com/zitadel/zitadel/internal/notification/channels/smtp"
|
"github.com/zitadel/zitadel/internal/notification/channels/smtp"
|
||||||
"github.com/zitadel/zitadel/internal/repository/instance"
|
"github.com/zitadel/zitadel/internal/repository/instance"
|
||||||
)
|
)
|
||||||
|
|
||||||
func (c *Commands) AddSMTPConfig(ctx context.Context, instanceID string, config *smtp.EmailConfig) (*domain.ObjectDetails, error) {
|
func (c *Commands) AddSMTPConfig(ctx context.Context, config *smtp.EmailConfig) (*domain.ObjectDetails, error) {
|
||||||
smtpConfigWriteModel, err := c.getSMTPConfig(ctx, instanceID)
|
instanceAgg := instance.NewAggregate(authz.GetInstance(ctx).InstanceID())
|
||||||
|
validation := c.prepareAddSMTPConfig(instanceAgg, config.From, config.FromName, config.SMTP.Host, config.SMTP.User, []byte(config.SMTP.Password), config.Tls)
|
||||||
|
cmds, err := preparation.PrepareCommands(ctx, c.eventstore.Filter, validation)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
if smtpConfigWriteModel.State == domain.SMTPConfigStateActive {
|
events, err := c.eventstore.Push(ctx, cmds...)
|
||||||
return nil, caos_errs.ThrowAlreadyExists(nil, "COMMAND-en9lw", "Errors.SMTPConfig.AlreadyExists")
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return &domain.ObjectDetails{
|
||||||
|
Sequence: events[len(events)-1].Sequence(),
|
||||||
|
EventDate: events[len(events)-1].CreationDate(),
|
||||||
|
ResourceOwner: events[len(events)-1].Aggregate().InstanceID,
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *Commands) ChangeSMTPConfig(ctx context.Context, config *smtp.EmailConfig) (*domain.ObjectDetails, error) {
|
||||||
|
instanceAgg := instance.NewAggregate(authz.GetInstance(ctx).InstanceID())
|
||||||
|
validation := c.prepareChangeSMTPConfig(instanceAgg, config.From, config.FromName, config.SMTP.Host, config.SMTP.User, config.Tls)
|
||||||
|
cmds, err := preparation.PrepareCommands(ctx, c.eventstore.Filter, validation)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
events, err := c.eventstore.Push(ctx, cmds...)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return &domain.ObjectDetails{
|
||||||
|
Sequence: events[len(events)-1].Sequence(),
|
||||||
|
EventDate: events[len(events)-1].CreationDate(),
|
||||||
|
ResourceOwner: events[len(events)-1].Aggregate().InstanceID,
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *Commands) ChangeSMTPConfigPassword(ctx context.Context, password string) (*domain.ObjectDetails, error) {
|
||||||
|
instanceAgg := instance.NewAggregate(authz.GetInstance(ctx).InstanceID())
|
||||||
|
smtpConfigWriteModel, err := getSMTPConfigWriteModel(ctx, c.eventstore.Filter)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if smtpConfigWriteModel.State != domain.SMTPConfigStateActive {
|
||||||
|
return nil, caos_errs.ThrowNotFound(nil, "COMMAND-3n9ls", "Errors.SMTPConfig.NotFound")
|
||||||
}
|
}
|
||||||
var smtpPassword *crypto.CryptoValue
|
var smtpPassword *crypto.CryptoValue
|
||||||
if config.SMTP.Password != "" {
|
if password != "" {
|
||||||
smtpPassword, err = crypto.Encrypt([]byte(config.SMTP.Password), c.smtpEncryption)
|
smtpPassword, err = crypto.Encrypt([]byte(password), c.smtpEncryption)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
events, err := c.eventstore.Push(ctx, instance.NewSMTPConfigPasswordChangedEvent(
|
||||||
iamAgg := InstanceAggregateFromWriteModel(&smtpConfigWriteModel.WriteModel)
|
|
||||||
pushedEvents, err := c.eventstore.Push(ctx, instance.NewSMTPConfigAddedEvent(
|
|
||||||
ctx,
|
ctx,
|
||||||
iamAgg,
|
&instanceAgg.Aggregate,
|
||||||
config.Tls,
|
|
||||||
config.From,
|
|
||||||
config.FromName,
|
|
||||||
config.SMTP.Host,
|
|
||||||
config.SMTP.User,
|
|
||||||
smtpPassword))
|
smtpPassword))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
err = AppendAndReduce(smtpConfigWriteModel, pushedEvents...)
|
return &domain.ObjectDetails{
|
||||||
if err != nil {
|
Sequence: events[len(events)-1].Sequence(),
|
||||||
return nil, err
|
EventDate: events[len(events)-1].CreationDate(),
|
||||||
}
|
ResourceOwner: events[len(events)-1].Aggregate().InstanceID,
|
||||||
return writeModelToObjectDetails(&smtpConfigWriteModel.WriteModel), nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *Commands) ChangeSMTPConfig(ctx context.Context, instanceID string, config *smtp.EmailConfig) (*domain.ObjectDetails, error) {
|
func (c *Commands) prepareAddSMTPConfig(a *instance.Aggregate, from, name, host, user string, password []byte, tls bool) preparation.Validation {
|
||||||
smtpConfigWriteModel, err := c.getSMTPConfig(ctx, instanceID)
|
return func() (preparation.CreateCommands, error) {
|
||||||
if err != nil {
|
if from = strings.TrimSpace(from); from == "" {
|
||||||
return nil, err
|
return nil, errors.ThrowInvalidArgument(nil, "INST-mruNY", "Errors.Invalid.Argument")
|
||||||
|
}
|
||||||
|
if host = strings.TrimSpace(host); host == "" {
|
||||||
|
return nil, errors.ThrowInvalidArgument(nil, "INST-SF3g1", "Errors.Invalid.Argument")
|
||||||
|
}
|
||||||
|
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, errors.ThrowAlreadyExists(nil, "INST-W3VS2", "Errors.SMTPConfig.AlreadyExists")
|
||||||
|
}
|
||||||
|
var smtpPassword *crypto.CryptoValue
|
||||||
|
if password != nil {
|
||||||
|
smtpPassword, err = crypto.Encrypt(password, c.smtpEncryption)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return []eventstore.Command{
|
||||||
|
instance.NewSMTPConfigAddedEvent(
|
||||||
|
ctx,
|
||||||
|
&a.Aggregate,
|
||||||
|
tls,
|
||||||
|
from,
|
||||||
|
name,
|
||||||
|
host,
|
||||||
|
user,
|
||||||
|
smtpPassword,
|
||||||
|
),
|
||||||
|
}, nil
|
||||||
|
}, nil
|
||||||
}
|
}
|
||||||
if smtpConfigWriteModel.State == domain.SMTPConfigStateUnspecified {
|
|
||||||
return nil, caos_errs.ThrowNotFound(nil, "COMMAND-3n9ls", "Errors.SMTPConfig.NotFound")
|
|
||||||
}
|
|
||||||
iamAgg := InstanceAggregateFromWriteModel(&smtpConfigWriteModel.WriteModel)
|
|
||||||
|
|
||||||
changedEvent, hasChanged, err := smtpConfigWriteModel.NewChangedEvent(
|
|
||||||
ctx,
|
|
||||||
iamAgg,
|
|
||||||
config.Tls,
|
|
||||||
config.From,
|
|
||||||
config.FromName,
|
|
||||||
config.SMTP.Host,
|
|
||||||
config.SMTP.User)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
if !hasChanged {
|
|
||||||
return nil, caos_errs.ThrowPreconditionFailed(nil, "COMMAND-m0o3f", "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, instanceID, password string) (*domain.ObjectDetails, error) {
|
func (c *Commands) prepareChangeSMTPConfig(a *instance.Aggregate, from, name, host, user string, tls bool) preparation.Validation {
|
||||||
smtpConfigWriteModel, err := c.getSMTPConfig(ctx, instanceID)
|
return func() (preparation.CreateCommands, error) {
|
||||||
if err != nil {
|
if from = strings.TrimSpace(from); from == "" {
|
||||||
return nil, err
|
return nil, errors.ThrowInvalidArgument(nil, "INST-ASv2d", "Errors.Invalid.Argument")
|
||||||
|
}
|
||||||
|
if host = strings.TrimSpace(host); host == "" {
|
||||||
|
return nil, errors.ThrowInvalidArgument(nil, "INST-VDwvq", "Errors.Invalid.Argument")
|
||||||
|
}
|
||||||
|
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, errors.ThrowNotFound(nil, "INST-Svq1a", "Errors.SMTPConfig.NotFound")
|
||||||
|
}
|
||||||
|
changedEvent, hasChanged, err := writeModel.NewChangedEvent(
|
||||||
|
ctx,
|
||||||
|
&a.Aggregate,
|
||||||
|
tls,
|
||||||
|
from,
|
||||||
|
name,
|
||||||
|
host,
|
||||||
|
user,
|
||||||
|
)
|
||||||
|
if !hasChanged {
|
||||||
|
return nil, caos_errs.ThrowPreconditionFailed(nil, "COMMAND-m0o3f", "Errors.NoChangesFound")
|
||||||
|
}
|
||||||
|
return []eventstore.Command{
|
||||||
|
changedEvent,
|
||||||
|
}, nil
|
||||||
|
}, nil
|
||||||
}
|
}
|
||||||
if smtpConfigWriteModel.State == domain.SMTPConfigStateUnspecified {
|
|
||||||
return nil, caos_errs.ThrowNotFound(nil, "COMMAND-3n9ls", "Errors.SMTPConfig.NotFound")
|
|
||||||
}
|
|
||||||
iamAgg := InstanceAggregateFromWriteModel(&smtpConfigWriteModel.WriteModel)
|
|
||||||
newPW, err := crypto.Encrypt([]byte(password), c.smtpEncryption)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
pushedEvents, err := c.eventstore.Push(ctx, instance.NewSMTPConfigPasswordChangedEvent(
|
|
||||||
ctx,
|
|
||||||
iamAgg,
|
|
||||||
newPW))
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
err = AppendAndReduce(smtpConfigWriteModel, pushedEvents...)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
return writeModelToObjectDetails(&smtpConfigWriteModel.WriteModel), nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *Commands) getSMTPConfig(ctx context.Context, instanceID string) (_ *InstanceSMTPConfigWriteModel, err error) {
|
func getSMTPConfigWriteModel(ctx context.Context, filter preparation.FilterToQueryReducer) (_ *InstanceSMTPConfigWriteModel, err error) {
|
||||||
writeModel := NewInstanceSMTPConfigWriteModel(instanceID)
|
writeModel := NewInstanceSMTPConfigWriteModel(authz.GetInstance(ctx).InstanceID())
|
||||||
err = c.eventstore.FilterToQueryReducer(ctx, writeModel)
|
events, err := filter(ctx, writeModel.Query())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
if len(events) == 0 {
|
||||||
return writeModel, nil
|
return writeModel, nil
|
||||||
|
}
|
||||||
|
writeModel.AppendEvents(events...)
|
||||||
|
err = writeModel.Reduce()
|
||||||
|
return writeModel, err
|
||||||
}
|
}
|
||||||
|
@ -7,6 +7,7 @@ import (
|
|||||||
"github.com/golang/mock/gomock"
|
"github.com/golang/mock/gomock"
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
|
|
||||||
|
"github.com/zitadel/zitadel/internal/api/authz"
|
||||||
"github.com/zitadel/zitadel/internal/crypto"
|
"github.com/zitadel/zitadel/internal/crypto"
|
||||||
"github.com/zitadel/zitadel/internal/domain"
|
"github.com/zitadel/zitadel/internal/domain"
|
||||||
caos_errs "github.com/zitadel/zitadel/internal/errors"
|
caos_errs "github.com/zitadel/zitadel/internal/errors"
|
||||||
@ -22,9 +23,8 @@ func TestCommandSide_AddSMTPConfig(t *testing.T) {
|
|||||||
alg crypto.EncryptionAlgorithm
|
alg crypto.EncryptionAlgorithm
|
||||||
}
|
}
|
||||||
type args struct {
|
type args struct {
|
||||||
ctx context.Context
|
ctx context.Context
|
||||||
instanceID string
|
smtp *smtp.EmailConfig
|
||||||
smtp *smtp.EmailConfig
|
|
||||||
}
|
}
|
||||||
type res struct {
|
type res struct {
|
||||||
want *domain.ObjectDetails
|
want *domain.ObjectDetails
|
||||||
@ -57,10 +57,16 @@ func TestCommandSide_AddSMTPConfig(t *testing.T) {
|
|||||||
),
|
),
|
||||||
},
|
},
|
||||||
args: args{
|
args: args{
|
||||||
ctx: context.Background(),
|
ctx: authz.WithInstanceID(context.Background(), "INSTANCE"),
|
||||||
instanceID: "INSTANCE",
|
|
||||||
smtp: &smtp.EmailConfig{
|
smtp: &smtp.EmailConfig{
|
||||||
Tls: true,
|
Tls: true,
|
||||||
|
From: "from",
|
||||||
|
FromName: "name",
|
||||||
|
SMTP: smtp.SMTP{
|
||||||
|
Host: "host",
|
||||||
|
User: "user",
|
||||||
|
Password: "password",
|
||||||
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
res: res{
|
res: res{
|
||||||
@ -75,21 +81,23 @@ func TestCommandSide_AddSMTPConfig(t *testing.T) {
|
|||||||
expectFilter(),
|
expectFilter(),
|
||||||
expectPush(
|
expectPush(
|
||||||
[]*repository.Event{
|
[]*repository.Event{
|
||||||
eventFromEventPusher(instance.NewSMTPConfigAddedEvent(
|
eventFromEventPusherWithInstanceID(
|
||||||
context.Background(),
|
"INSTANCE",
|
||||||
&instance.NewAggregate("INSTANCE").Aggregate,
|
instance.NewSMTPConfigAddedEvent(
|
||||||
true,
|
context.Background(),
|
||||||
"from",
|
&instance.NewAggregate("INSTANCE").Aggregate,
|
||||||
"name",
|
true,
|
||||||
"host",
|
"from",
|
||||||
"user",
|
"name",
|
||||||
&crypto.CryptoValue{
|
"host",
|
||||||
CryptoType: crypto.TypeEncryption,
|
"user",
|
||||||
Algorithm: "enc",
|
&crypto.CryptoValue{
|
||||||
KeyID: "id",
|
CryptoType: crypto.TypeEncryption,
|
||||||
Crypted: []byte("password"),
|
Algorithm: "enc",
|
||||||
},
|
KeyID: "id",
|
||||||
),
|
Crypted: []byte("password"),
|
||||||
|
},
|
||||||
|
),
|
||||||
),
|
),
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
@ -97,8 +105,7 @@ func TestCommandSide_AddSMTPConfig(t *testing.T) {
|
|||||||
alg: crypto.CreateMockEncryptionAlg(gomock.NewController(t)),
|
alg: crypto.CreateMockEncryptionAlg(gomock.NewController(t)),
|
||||||
},
|
},
|
||||||
args: args{
|
args: args{
|
||||||
ctx: context.Background(),
|
ctx: authz.WithInstanceID(context.Background(), "INSTANCE"),
|
||||||
instanceID: "INSTANCE",
|
|
||||||
smtp: &smtp.EmailConfig{
|
smtp: &smtp.EmailConfig{
|
||||||
Tls: true,
|
Tls: true,
|
||||||
From: "from",
|
From: "from",
|
||||||
@ -123,7 +130,7 @@ func TestCommandSide_AddSMTPConfig(t *testing.T) {
|
|||||||
eventstore: tt.fields.eventstore,
|
eventstore: tt.fields.eventstore,
|
||||||
smtpEncryption: tt.fields.alg,
|
smtpEncryption: tt.fields.alg,
|
||||||
}
|
}
|
||||||
got, err := r.AddSMTPConfig(tt.args.ctx, tt.args.instanceID, tt.args.smtp)
|
got, err := r.AddSMTPConfig(tt.args.ctx, tt.args.smtp)
|
||||||
if tt.res.err == nil {
|
if tt.res.err == nil {
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
}
|
}
|
||||||
@ -142,9 +149,8 @@ func TestCommandSide_ChangeSMTPConfig(t *testing.T) {
|
|||||||
eventstore *eventstore.Eventstore
|
eventstore *eventstore.Eventstore
|
||||||
}
|
}
|
||||||
type args struct {
|
type args struct {
|
||||||
ctx context.Context
|
ctx context.Context
|
||||||
instanceID string
|
smtp *smtp.EmailConfig
|
||||||
smtp *smtp.EmailConfig
|
|
||||||
}
|
}
|
||||||
type res struct {
|
type res struct {
|
||||||
want *domain.ObjectDetails
|
want *domain.ObjectDetails
|
||||||
@ -156,6 +162,21 @@ func TestCommandSide_ChangeSMTPConfig(t *testing.T) {
|
|||||||
args args
|
args args
|
||||||
res res
|
res res
|
||||||
}{
|
}{
|
||||||
|
{
|
||||||
|
name: "empty config, invalid argument error",
|
||||||
|
fields: fields{
|
||||||
|
eventstore: eventstoreExpect(
|
||||||
|
t,
|
||||||
|
),
|
||||||
|
},
|
||||||
|
args: args{
|
||||||
|
ctx: authz.WithInstanceID(context.Background(), "INSTANCE"),
|
||||||
|
smtp: &smtp.EmailConfig{},
|
||||||
|
},
|
||||||
|
res: res{
|
||||||
|
err: caos_errs.IsErrorInvalidArgument,
|
||||||
|
},
|
||||||
|
},
|
||||||
{
|
{
|
||||||
name: "smtp not existing, not found error",
|
name: "smtp not existing, not found error",
|
||||||
fields: fields{
|
fields: fields{
|
||||||
@ -165,14 +186,21 @@ func TestCommandSide_ChangeSMTPConfig(t *testing.T) {
|
|||||||
),
|
),
|
||||||
},
|
},
|
||||||
args: args{
|
args: args{
|
||||||
ctx: context.Background(),
|
ctx: authz.WithInstanceID(context.Background(), "INSTANCE"),
|
||||||
smtp: &smtp.EmailConfig{},
|
smtp: &smtp.EmailConfig{
|
||||||
|
Tls: true,
|
||||||
|
From: "from",
|
||||||
|
FromName: "name",
|
||||||
|
SMTP: smtp.SMTP{
|
||||||
|
Host: "host",
|
||||||
|
User: "user",
|
||||||
|
},
|
||||||
|
},
|
||||||
},
|
},
|
||||||
res: res{
|
res: res{
|
||||||
err: caos_errs.IsNotFound,
|
err: caos_errs.IsNotFound,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
||||||
{
|
{
|
||||||
name: "no changes, precondition error",
|
name: "no changes, precondition error",
|
||||||
fields: fields{
|
fields: fields{
|
||||||
@ -195,8 +223,7 @@ func TestCommandSide_ChangeSMTPConfig(t *testing.T) {
|
|||||||
),
|
),
|
||||||
},
|
},
|
||||||
args: args{
|
args: args{
|
||||||
ctx: context.Background(),
|
ctx: authz.WithInstanceID(context.Background(), "INSTANCE"),
|
||||||
instanceID: "INSTANCE",
|
|
||||||
smtp: &smtp.EmailConfig{
|
smtp: &smtp.EmailConfig{
|
||||||
Tls: true,
|
Tls: true,
|
||||||
From: "from",
|
From: "from",
|
||||||
@ -232,7 +259,8 @@ func TestCommandSide_ChangeSMTPConfig(t *testing.T) {
|
|||||||
),
|
),
|
||||||
expectPush(
|
expectPush(
|
||||||
[]*repository.Event{
|
[]*repository.Event{
|
||||||
eventFromEventPusher(
|
eventFromEventPusherWithInstanceID(
|
||||||
|
"INSTANCE",
|
||||||
newSMTPConfigChangedEvent(
|
newSMTPConfigChangedEvent(
|
||||||
context.Background(),
|
context.Background(),
|
||||||
false,
|
false,
|
||||||
@ -247,7 +275,7 @@ func TestCommandSide_ChangeSMTPConfig(t *testing.T) {
|
|||||||
),
|
),
|
||||||
},
|
},
|
||||||
args: args{
|
args: args{
|
||||||
ctx: context.Background(),
|
ctx: authz.WithInstanceID(context.Background(), "INSTANCE"),
|
||||||
smtp: &smtp.EmailConfig{
|
smtp: &smtp.EmailConfig{
|
||||||
Tls: false,
|
Tls: false,
|
||||||
From: "from2",
|
From: "from2",
|
||||||
@ -270,7 +298,7 @@ func TestCommandSide_ChangeSMTPConfig(t *testing.T) {
|
|||||||
r := &Commands{
|
r := &Commands{
|
||||||
eventstore: tt.fields.eventstore,
|
eventstore: tt.fields.eventstore,
|
||||||
}
|
}
|
||||||
got, err := r.ChangeSMTPConfig(tt.args.ctx, tt.args.instanceID, tt.args.smtp)
|
got, err := r.ChangeSMTPConfig(tt.args.ctx, tt.args.smtp)
|
||||||
if tt.res.err == nil {
|
if tt.res.err == nil {
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
}
|
}
|
||||||
@ -290,9 +318,8 @@ func TestCommandSide_ChangeSMTPConfigPassword(t *testing.T) {
|
|||||||
alg crypto.EncryptionAlgorithm
|
alg crypto.EncryptionAlgorithm
|
||||||
}
|
}
|
||||||
type args struct {
|
type args struct {
|
||||||
ctx context.Context
|
ctx context.Context
|
||||||
instanceID string
|
password string
|
||||||
password string
|
|
||||||
}
|
}
|
||||||
type res struct {
|
type res struct {
|
||||||
want *domain.ObjectDetails
|
want *domain.ObjectDetails
|
||||||
@ -341,16 +368,18 @@ func TestCommandSide_ChangeSMTPConfigPassword(t *testing.T) {
|
|||||||
),
|
),
|
||||||
expectPush(
|
expectPush(
|
||||||
[]*repository.Event{
|
[]*repository.Event{
|
||||||
eventFromEventPusher(instance.NewSMTPConfigPasswordChangedEvent(
|
eventFromEventPusherWithInstanceID(
|
||||||
context.Background(),
|
"INSTANCE",
|
||||||
&instance.NewAggregate("INSTANCE").Aggregate,
|
instance.NewSMTPConfigPasswordChangedEvent(
|
||||||
&crypto.CryptoValue{
|
context.Background(),
|
||||||
CryptoType: crypto.TypeEncryption,
|
&instance.NewAggregate("INSTANCE").Aggregate,
|
||||||
Algorithm: "enc",
|
&crypto.CryptoValue{
|
||||||
KeyID: "id",
|
CryptoType: crypto.TypeEncryption,
|
||||||
Crypted: []byte("password"),
|
Algorithm: "enc",
|
||||||
},
|
KeyID: "id",
|
||||||
),
|
Crypted: []byte("password"),
|
||||||
|
},
|
||||||
|
),
|
||||||
),
|
),
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
@ -358,9 +387,8 @@ func TestCommandSide_ChangeSMTPConfigPassword(t *testing.T) {
|
|||||||
alg: crypto.CreateMockEncryptionAlg(gomock.NewController(t)),
|
alg: crypto.CreateMockEncryptionAlg(gomock.NewController(t)),
|
||||||
},
|
},
|
||||||
args: args{
|
args: args{
|
||||||
ctx: context.Background(),
|
ctx: authz.WithInstanceID(context.Background(), "INSTANCE"),
|
||||||
instanceID: "INSTANCE",
|
password: "password",
|
||||||
password: "password",
|
|
||||||
},
|
},
|
||||||
res: res{
|
res: res{
|
||||||
want: &domain.ObjectDetails{
|
want: &domain.ObjectDetails{
|
||||||
@ -375,7 +403,7 @@ func TestCommandSide_ChangeSMTPConfigPassword(t *testing.T) {
|
|||||||
eventstore: tt.fields.eventstore,
|
eventstore: tt.fields.eventstore,
|
||||||
smtpEncryption: tt.fields.alg,
|
smtpEncryption: tt.fields.alg,
|
||||||
}
|
}
|
||||||
got, err := r.ChangeSMTPConfigPassword(tt.args.ctx, tt.args.instanceID, tt.args.password)
|
got, err := r.ChangeSMTPConfigPassword(tt.args.ctx, tt.args.password)
|
||||||
if tt.res.err == nil {
|
if tt.res.err == nil {
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
}
|
}
|
||||||
|
@ -29,6 +29,7 @@ func InitSMTPChannel(ctx context.Context, getSMTPConfig func(ctx context.Context
|
|||||||
}
|
}
|
||||||
client, err := smtpConfig.SMTP.connectToSMTP(smtpConfig.Tls)
|
client, err := smtpConfig.SMTP.connectToSMTP(smtpConfig.Tls)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
logging.New().WithError(err).Error("could not connect to smtp")
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -483,6 +483,7 @@ func (n *Notification) getSMTPConfig(ctx context.Context) (*smtp.EmailConfig, er
|
|||||||
return &smtp.EmailConfig{
|
return &smtp.EmailConfig{
|
||||||
From: config.SenderAddress,
|
From: config.SenderAddress,
|
||||||
FromName: config.SenderName,
|
FromName: config.SenderName,
|
||||||
|
Tls: config.TLS,
|
||||||
SMTP: smtp.SMTP{
|
SMTP: smtp.SMTP{
|
||||||
Host: config.Host,
|
Host: config.Host,
|
||||||
User: config.User,
|
User: config.User,
|
||||||
|
@ -8,7 +8,7 @@ import (
|
|||||||
"github.com/zitadel/zitadel/internal/notification/channels/log"
|
"github.com/zitadel/zitadel/internal/notification/channels/log"
|
||||||
)
|
)
|
||||||
|
|
||||||
func debugChannels(ctx context.Context, getFileSystemProvider func(ctx context.Context) (*fs.FSConfig, error), getLogProvider func(ctx context.Context) (*log.LogConfig, error)) (*Chain, error) {
|
func debugChannels(ctx context.Context, getFileSystemProvider func(ctx context.Context) (*fs.FSConfig, error), getLogProvider func(ctx context.Context) (*log.LogConfig, error)) []channels.NotificationChannel {
|
||||||
var (
|
var (
|
||||||
providers []channels.NotificationChannel
|
providers []channels.NotificationChannel
|
||||||
)
|
)
|
||||||
@ -24,5 +24,5 @@ func debugChannels(ctx context.Context, getFileSystemProvider func(ctx context.C
|
|||||||
providers = append(providers, log.InitStdoutChannel(*logProvider))
|
providers = append(providers, log.InitStdoutChannel(*logProvider))
|
||||||
}
|
}
|
||||||
|
|
||||||
return chainChannels(providers...), nil
|
return providers
|
||||||
}
|
}
|
||||||
|
@ -3,21 +3,18 @@ package senders
|
|||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
|
||||||
"github.com/zitadel/logging"
|
"github.com/zitadel/zitadel/internal/notification/channels"
|
||||||
|
|
||||||
"github.com/zitadel/zitadel/internal/notification/channels/fs"
|
"github.com/zitadel/zitadel/internal/notification/channels/fs"
|
||||||
"github.com/zitadel/zitadel/internal/notification/channels/log"
|
"github.com/zitadel/zitadel/internal/notification/channels/log"
|
||||||
"github.com/zitadel/zitadel/internal/notification/channels/smtp"
|
"github.com/zitadel/zitadel/internal/notification/channels/smtp"
|
||||||
)
|
)
|
||||||
|
|
||||||
func EmailChannels(ctx context.Context, emailConfig func(ctx context.Context) (*smtp.EmailConfig, error), getFileSystemProvider func(ctx context.Context) (*fs.FSConfig, error), getLogProvider func(ctx context.Context) (*log.LogConfig, error)) (chain *Chain, err error) {
|
func EmailChannels(ctx context.Context, emailConfig func(ctx context.Context) (*smtp.EmailConfig, error), getFileSystemProvider func(ctx context.Context) (*fs.FSConfig, error), getLogProvider func(ctx context.Context) (*log.LogConfig, error)) (chain *Chain, err error) {
|
||||||
|
channels := make([]channels.NotificationChannel, 0, 3)
|
||||||
p, err := smtp.InitSMTPChannel(ctx, emailConfig)
|
p, err := smtp.InitSMTPChannel(ctx, emailConfig)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
chain.channels = append(chain.channels, p)
|
channels = append(channels, p)
|
||||||
}
|
}
|
||||||
chain, err = debugChannels(ctx, getFileSystemProvider, getLogProvider)
|
channels = append(channels, debugChannels(ctx, getFileSystemProvider, getLogProvider)...)
|
||||||
if err != nil {
|
return chainChannels(channels...), nil
|
||||||
logging.New().Info("Error in creating debug channels")
|
|
||||||
}
|
|
||||||
return chain, nil
|
|
||||||
}
|
}
|
||||||
|
@ -3,18 +3,17 @@ package senders
|
|||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
|
||||||
|
"github.com/zitadel/zitadel/internal/notification/channels"
|
||||||
"github.com/zitadel/zitadel/internal/notification/channels/fs"
|
"github.com/zitadel/zitadel/internal/notification/channels/fs"
|
||||||
"github.com/zitadel/zitadel/internal/notification/channels/log"
|
"github.com/zitadel/zitadel/internal/notification/channels/log"
|
||||||
"github.com/zitadel/zitadel/internal/notification/channels/twilio"
|
"github.com/zitadel/zitadel/internal/notification/channels/twilio"
|
||||||
)
|
)
|
||||||
|
|
||||||
func SMSChannels(ctx context.Context, twilioConfig *twilio.TwilioConfig, getFileSystemProvider func(ctx context.Context) (*fs.FSConfig, error), getLogProvider func(ctx context.Context) (*log.LogConfig, error)) (chain *Chain, err error) {
|
func SMSChannels(ctx context.Context, twilioConfig *twilio.TwilioConfig, getFileSystemProvider func(ctx context.Context) (*fs.FSConfig, error), getLogProvider func(ctx context.Context) (*log.LogConfig, error)) (chain *Chain, err error) {
|
||||||
|
channels := make([]channels.NotificationChannel, 0, 3)
|
||||||
if twilioConfig != nil {
|
if twilioConfig != nil {
|
||||||
chain.channels = append(chain.channels, twilio.InitTwilioChannel(*twilioConfig))
|
channels = append(channels, twilio.InitTwilioChannel(*twilioConfig))
|
||||||
}
|
}
|
||||||
chain, err = debugChannels(ctx, getFileSystemProvider, getLogProvider)
|
channels = append(channels, debugChannels(ctx, getFileSystemProvider, getLogProvider)...)
|
||||||
if err != nil {
|
return chainChannels(channels...), nil
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
return chain, nil
|
|
||||||
}
|
}
|
||||||
|
@ -8,7 +8,6 @@ import (
|
|||||||
"github.com/zitadel/zitadel/internal/eventstore/handler"
|
"github.com/zitadel/zitadel/internal/eventstore/handler"
|
||||||
"github.com/zitadel/zitadel/internal/eventstore/handler/crdb"
|
"github.com/zitadel/zitadel/internal/eventstore/handler/crdb"
|
||||||
"github.com/zitadel/zitadel/internal/repository/instance"
|
"github.com/zitadel/zitadel/internal/repository/instance"
|
||||||
"github.com/zitadel/zitadel/internal/repository/project"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
@ -61,7 +60,7 @@ func NewSMTPConfigProjection(ctx context.Context, config crdb.StatementHandlerCo
|
|||||||
func (p *SMTPConfigProjection) reducers() []handler.AggregateReducer {
|
func (p *SMTPConfigProjection) reducers() []handler.AggregateReducer {
|
||||||
return []handler.AggregateReducer{
|
return []handler.AggregateReducer{
|
||||||
{
|
{
|
||||||
Aggregate: project.AggregateType,
|
Aggregate: instance.AggregateType,
|
||||||
EventRedusers: []handler.EventReducer{
|
EventRedusers: []handler.EventReducer{
|
||||||
{
|
{
|
||||||
Event: instance.SMTPConfigAddedEventType,
|
Event: instance.SMTPConfigAddedEventType,
|
||||||
|
@ -11,7 +11,7 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
smtpConfigPrefix = "smtp.config"
|
smtpConfigPrefix = "smtp.config."
|
||||||
SMTPConfigAddedEventType = instanceEventTypePrefix + smtpConfigPrefix + "added"
|
SMTPConfigAddedEventType = instanceEventTypePrefix + smtpConfigPrefix + "added"
|
||||||
SMTPConfigChangedEventType = instanceEventTypePrefix + smtpConfigPrefix + "changed"
|
SMTPConfigChangedEventType = instanceEventTypePrefix + smtpConfigPrefix + "changed"
|
||||||
SMTPConfigPasswordChangedEventType = instanceEventTypePrefix + smtpConfigPrefix + "password.changed"
|
SMTPConfigPasswordChangedEventType = instanceEventTypePrefix + smtpConfigPrefix + "password.changed"
|
||||||
|
Loading…
x
Reference in New Issue
Block a user