feat: add http as smtp provider (#8545)

# Which Problems Are Solved

Send Email messages as a HTTP call to a relay, for own logic on handling
different Email providers

# How the Problems Are Solved

Create endpoints under Email provider to manage SMTP and HTTP in the
notification handlers.

# Additional Changes

Clean up old logic in command and query side to handle the general Email
providers with deactivate, activate and remove.

# Additional Context

Partially closes #8270

---------

Co-authored-by: Livio Spring <livio.a@gmail.com>
This commit is contained in:
Stefan Benz
2024-09-12 06:27:29 +02:00
committed by GitHub
parent d8a71d217c
commit 21c38b061d
28 changed files with 3575 additions and 1152 deletions

View File

@@ -0,0 +1,140 @@
package admin
import (
"context"
"github.com/zitadel/zitadel/internal/api/authz"
"github.com/zitadel/zitadel/internal/api/grpc/object"
admin_pb "github.com/zitadel/zitadel/pkg/grpc/admin"
)
func (s *Server) GetEmailProvider(ctx context.Context, req *admin_pb.GetEmailProviderRequest) (*admin_pb.GetEmailProviderResponse, error) {
smtp, err := s.query.SMTPConfigActive(ctx, authz.GetInstance(ctx).InstanceID())
if err != nil {
return nil, err
}
return &admin_pb.GetEmailProviderResponse{
Config: emailProviderToProviderPb(smtp),
}, nil
}
func (s *Server) GetEmailProviderById(ctx context.Context, req *admin_pb.GetEmailProviderByIdRequest) (*admin_pb.GetEmailProviderByIdResponse, error) {
smtp, err := s.query.SMTPConfigByID(ctx, authz.GetInstance(ctx).InstanceID(), req.Id)
if err != nil {
return nil, err
}
return &admin_pb.GetEmailProviderByIdResponse{
Config: emailProviderToProviderPb(smtp),
}, nil
}
func (s *Server) AddEmailProviderSMTP(ctx context.Context, req *admin_pb.AddEmailProviderSMTPRequest) (*admin_pb.AddEmailProviderSMTPResponse, error) {
config := addEmailProviderSMTPToConfig(ctx, req)
if err := s.command.AddSMTPConfig(ctx, config); err != nil {
return nil, err
}
return &admin_pb.AddEmailProviderSMTPResponse{
Details: object.DomainToChangeDetailsPb(config.Details),
Id: config.ID,
}, nil
}
func (s *Server) UpdateEmailProviderSMTP(ctx context.Context, req *admin_pb.UpdateEmailProviderSMTPRequest) (*admin_pb.UpdateEmailProviderSMTPResponse, error) {
config := updateEmailProviderSMTPToConfig(ctx, req)
if err := s.command.ChangeSMTPConfig(ctx, config); err != nil {
return nil, err
}
return &admin_pb.UpdateEmailProviderSMTPResponse{
Details: object.DomainToChangeDetailsPb(config.Details),
}, nil
}
func (s *Server) AddEmailProviderHTTP(ctx context.Context, req *admin_pb.AddEmailProviderHTTPRequest) (*admin_pb.AddEmailProviderHTTPResponse, error) {
config := addEmailProviderHTTPToConfig(ctx, req)
if err := s.command.AddSMTPConfigHTTP(ctx, config); err != nil {
return nil, err
}
return &admin_pb.AddEmailProviderHTTPResponse{
Details: object.DomainToChangeDetailsPb(config.Details),
Id: config.ID,
}, nil
}
func (s *Server) UpdateEmailProviderHTTP(ctx context.Context, req *admin_pb.UpdateEmailProviderHTTPRequest) (*admin_pb.UpdateEmailProviderHTTPResponse, error) {
config := updateEmailProviderHTTPToConfig(ctx, req)
if err := s.command.ChangeSMTPConfigHTTP(ctx, config); err != nil {
return nil, err
}
return &admin_pb.UpdateEmailProviderHTTPResponse{
Details: object.DomainToChangeDetailsPb(config.Details),
}, nil
}
func (s *Server) RemoveEmailProvider(ctx context.Context, req *admin_pb.RemoveEmailProviderRequest) (*admin_pb.RemoveEmailProviderResponse, error) {
details, err := s.command.RemoveSMTPConfig(ctx, authz.GetInstance(ctx).InstanceID(), req.Id)
if err != nil {
return nil, err
}
return &admin_pb.RemoveEmailProviderResponse{
Details: object.DomainToChangeDetailsPb(details),
}, nil
}
func (s *Server) UpdateEmailProviderSMTPPassword(ctx context.Context, req *admin_pb.UpdateEmailProviderSMTPPasswordRequest) (*admin_pb.UpdateEmailProviderSMTPPasswordResponse, error) {
details, err := s.command.ChangeSMTPConfigPassword(ctx, authz.GetInstance(ctx).InstanceID(), req.Id, req.Password)
if err != nil {
return nil, err
}
return &admin_pb.UpdateEmailProviderSMTPPasswordResponse{
Details: object.DomainToChangeDetailsPb(details),
}, nil
}
func (s *Server) ListEmailProviders(ctx context.Context, req *admin_pb.ListEmailProvidersRequest) (*admin_pb.ListEmailProvidersResponse, error) {
queries, err := listEmailProvidersToModel(req)
if err != nil {
return nil, err
}
result, err := s.query.SearchSMTPConfigs(ctx, queries)
if err != nil {
return nil, err
}
return &admin_pb.ListEmailProvidersResponse{
Details: object.ToListDetails(result.Count, result.Sequence, result.LastRun),
Result: emailProvidersToPb(result.Configs),
}, nil
}
func (s *Server) ActivateEmailProvider(ctx context.Context, req *admin_pb.ActivateEmailProviderRequest) (*admin_pb.ActivateEmailProviderResponse, error) {
result, err := s.command.ActivateSMTPConfig(ctx, authz.GetInstance(ctx).InstanceID(), req.Id)
if err != nil {
return nil, err
}
return &admin_pb.ActivateEmailProviderResponse{
Details: object.DomainToAddDetailsPb(result),
}, nil
}
func (s *Server) DeactivateEmailProvider(ctx context.Context, req *admin_pb.DeactivateEmailProviderRequest) (*admin_pb.DeactivateEmailProviderResponse, error) {
result, err := s.command.DeactivateSMTPConfig(ctx, authz.GetInstance(ctx).InstanceID(), req.Id)
if err != nil {
return nil, err
}
return &admin_pb.DeactivateEmailProviderResponse{
Details: object.DomainToAddDetailsPb(result),
}, nil
}
func (s *Server) TestEmailProviderById(ctx context.Context, req *admin_pb.TestEmailProviderSMTPByIdRequest) (*admin_pb.TestEmailProviderSMTPByIdResponse, error) {
if err := s.command.TestSMTPConfigById(ctx, authz.GetInstance(ctx).InstanceID(), req.Id, req.ReceiverAddress); err != nil {
return nil, err
}
return &admin_pb.TestEmailProviderSMTPByIdResponse{}, nil
}
func (s *Server) TestEmailProviderSMTP(ctx context.Context, req *admin_pb.TestEmailProviderSMTPRequest) (*admin_pb.TestEmailProviderSMTPResponse, error) {
if err := s.command.TestSMTPConfig(ctx, authz.GetInstance(ctx).InstanceID(), req.Id, req.ReceiverAddress, testEmailProviderSMTPToConfig(req)); err != nil {
return nil, err
}
return &admin_pb.TestEmailProviderSMTPResponse{}, nil
}

View File

@@ -0,0 +1,145 @@
package admin
import (
"context"
"github.com/zitadel/zitadel/internal/api/authz"
"github.com/zitadel/zitadel/internal/api/grpc/object"
"github.com/zitadel/zitadel/internal/command"
"github.com/zitadel/zitadel/internal/domain"
"github.com/zitadel/zitadel/internal/notification/channels/smtp"
"github.com/zitadel/zitadel/internal/query"
admin_pb "github.com/zitadel/zitadel/pkg/grpc/admin"
settings_pb "github.com/zitadel/zitadel/pkg/grpc/settings"
)
func listEmailProvidersToModel(req *admin_pb.ListEmailProvidersRequest) (*query.SMTPConfigsSearchQueries, error) {
offset, limit, asc := object.ListQueryToModel(req.Query)
return &query.SMTPConfigsSearchQueries{
SearchRequest: query.SearchRequest{
Offset: offset,
Limit: limit,
Asc: asc,
},
}, nil
}
func emailProvidersToPb(configs []*query.SMTPConfig) []*settings_pb.EmailProvider {
c := make([]*settings_pb.EmailProvider, len(configs))
for i, config := range configs {
c[i] = emailProviderToProviderPb(config)
}
return c
}
func emailProviderToProviderPb(config *query.SMTPConfig) *settings_pb.EmailProvider {
return &settings_pb.EmailProvider{
Details: object.ToViewDetailsPb(config.Sequence, config.CreationDate, config.ChangeDate, config.ResourceOwner),
Id: config.ID,
Description: config.Description,
State: emailProviderStateToPb(config.State),
Config: emailProviderToPb(config),
}
}
func emailProviderStateToPb(state domain.SMTPConfigState) settings_pb.EmailProviderState {
switch state {
case domain.SMTPConfigStateUnspecified, domain.SMTPConfigStateRemoved:
return settings_pb.EmailProviderState_EMAIL_PROVIDER_STATE_UNSPECIFIED
case domain.SMTPConfigStateActive:
return settings_pb.EmailProviderState_EMAIL_PROVIDER_ACTIVE
case domain.SMTPConfigStateInactive:
return settings_pb.EmailProviderState_EMAIL_PROVIDER_INACTIVE
default:
return settings_pb.EmailProviderState_EMAIL_PROVIDER_STATE_UNSPECIFIED
}
}
func emailProviderToPb(config *query.SMTPConfig) settings_pb.EmailConfig {
if config.SMTPConfig != nil {
return smtpToPb(config.SMTPConfig)
}
if config.HTTPConfig != nil {
return httpToPb(config.HTTPConfig)
}
return nil
}
func httpToPb(http *query.HTTP) *settings_pb.EmailProvider_Http {
return &settings_pb.EmailProvider_Http{
Http: &settings_pb.EmailProviderHTTP{
Endpoint: http.Endpoint,
},
}
}
func smtpToPb(config *query.SMTP) *settings_pb.EmailProvider_Smtp {
return &settings_pb.EmailProvider_Smtp{
Smtp: &settings_pb.EmailProviderSMTP{
Tls: config.TLS,
Host: config.Host,
User: config.User,
SenderAddress: config.SenderAddress,
SenderName: config.SenderName,
},
}
}
func addEmailProviderSMTPToConfig(ctx context.Context, req *admin_pb.AddEmailProviderSMTPRequest) *command.AddSMTPConfig {
return &command.AddSMTPConfig{
ResourceOwner: authz.GetInstance(ctx).InstanceID(),
Description: req.Description,
Tls: req.Tls,
From: req.SenderAddress,
FromName: req.SenderName,
ReplyToAddress: req.ReplyToAddress,
Host: req.Host,
User: req.User,
Password: req.Password,
}
}
func updateEmailProviderSMTPToConfig(ctx context.Context, req *admin_pb.UpdateEmailProviderSMTPRequest) *command.ChangeSMTPConfig {
return &command.ChangeSMTPConfig{
ResourceOwner: authz.GetInstance(ctx).InstanceID(),
ID: req.Id,
Description: req.Description,
Tls: req.Tls,
From: req.SenderAddress,
FromName: req.SenderName,
ReplyToAddress: req.ReplyToAddress,
Host: req.Host,
User: req.User,
Password: req.Password,
}
}
func addEmailProviderHTTPToConfig(ctx context.Context, req *admin_pb.AddEmailProviderHTTPRequest) *command.AddSMTPConfigHTTP {
return &command.AddSMTPConfigHTTP{
ResourceOwner: authz.GetInstance(ctx).InstanceID(),
Description: req.Description,
Endpoint: req.Endpoint,
}
}
func updateEmailProviderHTTPToConfig(ctx context.Context, req *admin_pb.UpdateEmailProviderHTTPRequest) *command.ChangeSMTPConfigHTTP {
return &command.ChangeSMTPConfigHTTP{
ResourceOwner: authz.GetInstance(ctx).InstanceID(),
ID: req.Id,
Description: req.Description,
Endpoint: req.Endpoint,
}
}
func testEmailProviderSMTPToConfig(req *admin_pb.TestEmailProviderSMTPRequest) *smtp.Config {
return &smtp.Config{
Tls: req.Tls,
From: req.SenderAddress,
FromName: req.SenderName,
SMTP: smtp.SMTP{
Host: req.Host,
User: req.User,
Password: req.Password,
},
}
}

View File

@@ -1,14 +1,16 @@
package admin
import (
"context"
"google.golang.org/protobuf/types/known/durationpb"
"github.com/zitadel/zitadel/internal/api/authz"
"github.com/zitadel/zitadel/internal/api/grpc/object"
obj_grpc "github.com/zitadel/zitadel/internal/api/grpc/object"
"github.com/zitadel/zitadel/internal/command"
"github.com/zitadel/zitadel/internal/crypto"
"github.com/zitadel/zitadel/internal/domain"
"github.com/zitadel/zitadel/internal/notification/channels/smtp"
"github.com/zitadel/zitadel/internal/query"
"github.com/zitadel/zitadel/internal/zerrors"
admin_pb "github.com/zitadel/zitadel/pkg/grpc/admin"
@@ -131,50 +133,51 @@ func SecretGeneratorTypeToDomain(generatorType settings_pb.SecretGeneratorType)
}
}
func AddSMTPToConfig(req *admin_pb.AddSMTPConfigRequest) *smtp.Config {
return &smtp.Config{
func addSMTPToConfig(ctx context.Context, req *admin_pb.AddSMTPConfigRequest) *command.AddSMTPConfig {
return &command.AddSMTPConfig{
ResourceOwner: authz.GetInstance(ctx).InstanceID(),
Description: req.Description,
Tls: req.Tls,
From: req.SenderAddress,
FromName: req.SenderName,
ReplyToAddress: req.ReplyToAddress,
SMTP: smtp.SMTP{
Host: req.Host,
User: req.User,
Password: req.Password,
},
Host: req.Host,
User: req.User,
Password: req.Password,
}
}
func UpdateSMTPToConfig(req *admin_pb.UpdateSMTPConfigRequest) *smtp.Config {
return &smtp.Config{
func updateSMTPToConfig(ctx context.Context, req *admin_pb.UpdateSMTPConfigRequest) *command.ChangeSMTPConfig {
return &command.ChangeSMTPConfig{
ResourceOwner: authz.GetInstance(ctx).InstanceID(),
ID: req.Id,
Description: req.Description,
Tls: req.Tls,
From: req.SenderAddress,
FromName: req.SenderName,
ReplyToAddress: req.ReplyToAddress,
SMTP: smtp.SMTP{
Host: req.Host,
User: req.User,
Password: req.Password,
},
Host: req.Host,
User: req.User,
Password: req.Password,
}
}
func SMTPConfigToPb(smtp *query.SMTPConfig) *settings_pb.SMTPConfig {
mapped := &settings_pb.SMTPConfig{
Description: smtp.Description,
Tls: smtp.TLS,
SenderAddress: smtp.SenderAddress,
SenderName: smtp.SenderName,
ReplyToAddress: smtp.ReplyToAddress,
Host: smtp.Host,
User: smtp.User,
Details: obj_grpc.ToViewDetailsPb(smtp.Sequence, smtp.CreationDate, smtp.ChangeDate, smtp.ResourceOwner),
Id: smtp.ID,
State: settings_pb.SMTPConfigState(smtp.State),
if smtp.SMTPConfig != nil {
return &settings_pb.SMTPConfig{
Description: smtp.Description,
Tls: smtp.SMTPConfig.TLS,
SenderAddress: smtp.SMTPConfig.SenderAddress,
SenderName: smtp.SMTPConfig.SenderName,
ReplyToAddress: smtp.SMTPConfig.ReplyToAddress,
Host: smtp.SMTPConfig.Host,
User: smtp.SMTPConfig.User,
Details: obj_grpc.ToViewDetailsPb(smtp.Sequence, smtp.CreationDate, smtp.ChangeDate, smtp.ResourceOwner),
Id: smtp.ID,
State: settings_pb.SMTPConfigState(smtp.State),
}
}
return mapped
return nil
}
func SecurityPolicyToPb(policy *query.SecurityPolicy) *settings_pb.SecurityPolicy {

View File

@@ -20,10 +20,7 @@ func (s *Server) GetSMTPConfig(ctx context.Context, req *admin_pb.GetSMTPConfigR
}
func (s *Server) GetSMTPConfigById(ctx context.Context, req *admin_pb.GetSMTPConfigByIdRequest) (*admin_pb.GetSMTPConfigByIdResponse, error) {
instanceID := authz.GetInstance(ctx).InstanceID()
resourceOwner := instanceID // Will be replaced when orgs have smtp configs
smtp, err := s.query.SMTPConfigByID(ctx, instanceID, resourceOwner, req.Id)
smtp, err := s.query.SMTPConfigByID(ctx, authz.GetInstance(ctx).InstanceID(), req.Id)
if err != nil {
return nil, err
}
@@ -33,29 +30,23 @@ func (s *Server) GetSMTPConfigById(ctx context.Context, req *admin_pb.GetSMTPCon
}
func (s *Server) AddSMTPConfig(ctx context.Context, req *admin_pb.AddSMTPConfigRequest) (*admin_pb.AddSMTPConfigResponse, error) {
id, details, err := s.command.AddSMTPConfig(ctx, authz.GetInstance(ctx).InstanceID(), AddSMTPToConfig(req))
if err != nil {
config := addSMTPToConfig(ctx, req)
if err := s.command.AddSMTPConfig(ctx, config); err != nil {
return nil, err
}
return &admin_pb.AddSMTPConfigResponse{
Details: object.ChangeToDetailsPb(
details.Sequence,
details.EventDate,
details.ResourceOwner),
Id: id,
Details: object.DomainToChangeDetailsPb(config.Details),
Id: config.ID,
}, nil
}
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(), req.Id, UpdateSMTPToConfig(req))
if err != nil {
config := updateSMTPToConfig(ctx, req)
if err := s.command.ChangeSMTPConfig(ctx, config); err != nil {
return nil, err
}
return &admin_pb.UpdateSMTPConfigResponse{
Details: object.ChangeToDetailsPb(
details.Sequence,
details.EventDate,
details.ResourceOwner),
Details: object.DomainToChangeDetailsPb(config.Details),
}, nil
}
@@ -65,10 +56,7 @@ func (s *Server) RemoveSMTPConfig(ctx context.Context, req *admin_pb.RemoveSMTPC
return nil, err
}
return &admin_pb.RemoveSMTPConfigResponse{
Details: object.ChangeToDetailsPb(
details.Sequence,
details.EventDate,
details.ResourceOwner),
Details: object.DomainToChangeDetailsPb(details),
}, nil
}
@@ -78,10 +66,7 @@ func (s *Server) UpdateSMTPConfigPassword(ctx context.Context, req *admin_pb.Upd
return nil, err
}
return &admin_pb.UpdateSMTPConfigPasswordResponse{
Details: object.ChangeToDetailsPb(
details.Sequence,
details.EventDate,
details.ResourceOwner),
Details: object.DomainToChangeDetailsPb(details),
}, nil
}
@@ -101,19 +86,11 @@ func (s *Server) ListSMTPConfigs(ctx context.Context, req *admin_pb.ListSMTPConf
}
func (s *Server) ActivateSMTPConfig(ctx context.Context, req *admin_pb.ActivateSMTPConfigRequest) (*admin_pb.ActivateSMTPConfigResponse, error) {
// Get the ID of current SMTP active provider if any
currentActiveProviderID := ""
smtp, err := s.query.SMTPConfigActive(ctx, authz.GetInstance(ctx).InstanceID())
if err == nil {
currentActiveProviderID = smtp.ID
}
result, err := s.command.ActivateSMTPConfig(ctx, authz.GetInstance(ctx).InstanceID(), req.Id, currentActiveProviderID)
result, err := s.command.ActivateSMTPConfig(ctx, authz.GetInstance(ctx).InstanceID(), req.Id)
if err != nil {
return nil, err
}
return &admin_pb.ActivateSMTPConfigResponse{
Details: object.DomainToAddDetailsPb(result),
}, nil

View File

@@ -2,6 +2,7 @@ package admin
import (
"github.com/zitadel/zitadel/internal/api/grpc/object"
"github.com/zitadel/zitadel/internal/domain"
"github.com/zitadel/zitadel/internal/query"
admin_pb "github.com/zitadel/zitadel/pkg/grpc/admin"
settings_pb "github.com/zitadel/zitadel/pkg/grpc/settings"
@@ -23,12 +24,12 @@ func SMTPConfigToProviderPb(config *query.SMTPConfig) *settings_pb.SMTPConfig {
Details: object.ToViewDetailsPb(config.Sequence, config.CreationDate, config.ChangeDate, config.ResourceOwner),
Id: config.ID,
Description: config.Description,
Tls: config.TLS,
Host: config.Host,
User: config.User,
State: settings_pb.SMTPConfigState(config.State),
SenderAddress: config.SenderAddress,
SenderName: config.SenderName,
Tls: config.SMTPConfig.TLS,
Host: config.SMTPConfig.Host,
User: config.SMTPConfig.User,
State: SMTPConfigStateToPb(config.State),
SenderAddress: config.SMTPConfig.SenderAddress,
SenderName: config.SMTPConfig.SenderName,
}
}
@@ -39,3 +40,16 @@ func SMTPConfigsToPb(configs []*query.SMTPConfig) []*settings_pb.SMTPConfig {
}
return c
}
func SMTPConfigStateToPb(state domain.SMTPConfigState) settings_pb.SMTPConfigState {
switch state {
case domain.SMTPConfigStateUnspecified, domain.SMTPConfigStateRemoved:
return settings_pb.SMTPConfigState_SMTP_CONFIG_STATE_UNSPECIFIED
case domain.SMTPConfigStateActive:
return settings_pb.SMTPConfigState_SMTP_CONFIG_ACTIVE
case domain.SMTPConfigStateInactive:
return settings_pb.SMTPConfigState_SMTP_CONFIG_INACTIVE
default:
return settings_pb.SMTPConfigState_SMTP_CONFIG_STATE_UNSPECIFIED
}
}

View File

@@ -116,7 +116,7 @@ type InstanceSetup struct {
}
EmailTemplate []byte
MessageTexts []*domain.CustomMessageText
SMTPConfiguration *smtp.Config
SMTPConfiguration *SMTPConfiguration
OIDCSettings *OIDCSettings
Quotas *SetQuotas
Features *InstanceFeatures
@@ -124,6 +124,15 @@ type InstanceSetup struct {
Restrictions *SetRestrictions
}
type SMTPConfiguration struct {
Description string
SMTP smtp.SMTP
Tls bool
From string
FromName string
ReplyToAddress string
}
type OIDCSettings struct {
AccessTokenLifetime time.Duration
IdTokenLifetime time.Duration
@@ -440,7 +449,7 @@ func setupOIDCSettings(commands *Commands, validations *[]preparation.Validation
)
}
func setupSMTPSettings(commands *Commands, validations *[]preparation.Validation, smtpConfig *smtp.Config, instanceAgg *instance.Aggregate) {
func setupSMTPSettings(commands *Commands, validations *[]preparation.Validation, smtpConfig *SMTPConfiguration, instanceAgg *instance.Aggregate) {
if smtpConfig == nil {
return
}

View File

@@ -12,8 +12,20 @@ import (
type IAMSMTPConfigWriteModel struct {
eventstore.WriteModel
ID string
Description string
ID string
Description string
SMTPConfig *SMTPConfig
HTTPConfig *HTTPConfig
State domain.SMTPConfigState
domain string
domainState domain.InstanceDomainState
smtpSenderAddressMatchesInstanceDomain bool
}
type SMTPConfig struct {
TLS bool
Host string
User string
@@ -21,11 +33,6 @@ type IAMSMTPConfigWriteModel struct {
SenderAddress string
SenderName string
ReplyToAddress string
State domain.SMTPConfigState
domain string
domainState domain.InstanceDomainState
smtpSenderAddressMatchesInstanceDomain bool
}
func NewIAMSMTPConfigWriteModel(instanceID, id, domain string) *IAMSMTPConfigWriteModel {
@@ -73,6 +80,23 @@ func (wm *IAMSMTPConfigWriteModel) Reduce() error {
continue
}
wm.reduceSMTPConfigChangedEvent(e)
case *instance.SMTPConfigPasswordChangedEvent:
if wm.ID != e.ID {
continue
}
if e.Password != nil {
wm.SMTPConfig.Password = e.Password
}
case *instance.SMTPConfigHTTPAddedEvent:
if wm.ID != e.ID {
continue
}
wm.reduceSMTPConfigHTTPAddedEvent(e)
case *instance.SMTPConfigHTTPChangedEvent:
if wm.ID != e.ID {
continue
}
wm.reduceSMTPConfigHTTPChangedEvent(e)
case *instance.SMTPConfigRemovedEvent:
if wm.ID != e.ID {
continue
@@ -120,6 +144,8 @@ func (wm *IAMSMTPConfigWriteModel) Query() *eventstore.SearchQueryBuilder {
instance.SMTPConfigRemovedEventType,
instance.SMTPConfigChangedEventType,
instance.SMTPConfigPasswordChangedEventType,
instance.SMTPConfigHTTPAddedEventType,
instance.SMTPConfigHTTPChangedEventType,
instance.SMTPConfigActivatedEventType,
instance.SMTPConfigDeactivatedEventType,
instance.SMTPConfigRemovedEventType,
@@ -133,6 +159,9 @@ func (wm *IAMSMTPConfigWriteModel) Query() *eventstore.SearchQueryBuilder {
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.SMTPConfig == nil {
return nil, false, nil
}
if wm.ID != id {
changes = append(changes, instance.ChangeSMTPConfigID(id))
@@ -140,22 +169,22 @@ func (wm *IAMSMTPConfigWriteModel) NewChangedEvent(ctx context.Context, aggregat
if wm.Description != description {
changes = append(changes, instance.ChangeSMTPConfigDescription(description))
}
if wm.TLS != tls {
if wm.SMTPConfig.TLS != tls {
changes = append(changes, instance.ChangeSMTPConfigTLS(tls))
}
if wm.SenderAddress != fromAddress {
if wm.SMTPConfig.SenderAddress != fromAddress {
changes = append(changes, instance.ChangeSMTPConfigFromAddress(fromAddress))
}
if wm.SenderName != fromName {
if wm.SMTPConfig.SenderName != fromName {
changes = append(changes, instance.ChangeSMTPConfigFromName(fromName))
}
if wm.ReplyToAddress != replyToAddress {
if wm.SMTPConfig.ReplyToAddress != replyToAddress {
changes = append(changes, instance.ChangeSMTPConfigReplyToAddress(replyToAddress))
}
if wm.Host != smtpHost {
if wm.SMTPConfig.Host != smtpHost {
changes = append(changes, instance.ChangeSMTPConfigSMTPHost(smtpHost))
}
if wm.User != smtpUser {
if wm.SMTPConfig.User != smtpUser {
changes = append(changes, instance.ChangeSMTPConfigSMTPUser(smtpUser))
}
if smtpPassword != nil {
@@ -171,15 +200,58 @@ func (wm *IAMSMTPConfigWriteModel) NewChangedEvent(ctx context.Context, aggregat
return changeEvent, true, nil
}
func (wm *IAMSMTPConfigWriteModel) NewHTTPChangedEvent(ctx context.Context, aggregate *eventstore.Aggregate, id, description, endpoint string) (*instance.SMTPConfigHTTPChangedEvent, bool, error) {
changes := make([]instance.SMTPConfigHTTPChanges, 0)
var err error
if wm.HTTPConfig == nil {
return nil, false, nil
}
if wm.ID != id {
changes = append(changes, instance.ChangeSMTPConfigHTTPID(id))
}
if wm.Description != description {
changes = append(changes, instance.ChangeSMTPConfigHTTPDescription(description))
}
if wm.HTTPConfig.Endpoint != endpoint {
changes = append(changes, instance.ChangeSMTPConfigHTTPEndpoint(endpoint))
}
if len(changes) == 0 {
return nil, false, nil
}
changeEvent, err := instance.NewSMTPConfigHTTPChangeEvent(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.SMTPConfig = &SMTPConfig{
TLS: e.TLS,
Host: e.Host,
User: e.User,
Password: e.Password,
SenderName: e.SenderName,
SenderAddress: e.SenderAddress,
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) reduceSMTPConfigHTTPAddedEvent(e *instance.SMTPConfigHTTPAddedEvent) {
wm.Description = e.Description
wm.HTTPConfig = &HTTPConfig{
Endpoint: e.Endpoint,
}
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
@@ -191,29 +263,54 @@ func (wm *IAMSMTPConfigWriteModel) reduceSMTPConfigAddedEvent(e *instance.SMTPCo
}
func (wm *IAMSMTPConfigWriteModel) reduceSMTPConfigChangedEvent(e *instance.SMTPConfigChangedEvent) {
if wm.SMTPConfig == nil {
return
}
if e.Description != nil {
wm.Description = *e.Description
}
if e.TLS != nil {
wm.TLS = *e.TLS
wm.SMTPConfig.TLS = *e.TLS
}
if e.Host != nil {
wm.Host = *e.Host
wm.SMTPConfig.Host = *e.Host
}
if e.User != nil {
wm.User = *e.User
wm.SMTPConfig.User = *e.User
}
if e.Password != nil {
wm.Password = e.Password
wm.SMTPConfig.Password = e.Password
}
if e.FromAddress != nil {
wm.SenderAddress = *e.FromAddress
wm.SMTPConfig.SenderAddress = *e.FromAddress
}
if e.FromName != nil {
wm.SenderName = *e.FromName
wm.SMTPConfig.SenderName = *e.FromName
}
if e.ReplyToAddress != nil {
wm.ReplyToAddress = *e.ReplyToAddress
wm.SMTPConfig.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) reduceSMTPConfigHTTPChangedEvent(e *instance.SMTPConfigHTTPChangedEvent) {
if wm.HTTPConfig == nil {
return
}
if e.Description != nil {
wm.Description = *e.Description
}
if e.Endpoint != nil {
wm.HTTPConfig.Endpoint = *e.Endpoint
}
// If ID has empty value we're dealing with the old and unique smtp settings
@@ -227,13 +324,8 @@ func (wm *IAMSMTPConfigWriteModel) reduceSMTPConfigChangedEvent(e *instance.SMTP
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.HTTPConfig = nil
wm.SMTPConfig = nil
wm.State = domain.SMTPConfigStateRemoved
// If ID has empty value we're dealing with the old and unique smtp settings

View File

@@ -15,151 +15,189 @@ import (
"github.com/zitadel/zitadel/internal/zerrors"
)
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
type AddSMTPConfig struct {
Details *domain.ObjectDetails
ResourceOwner string
ID string
Description string
Host string
User string
Password string
Tls bool
From string
FromName string
ReplyToAddress string
}
func (c *Commands) AddSMTPConfig(ctx context.Context, config *AddSMTPConfig) (err error) {
if config.ResourceOwner == "" {
return zerrors.ThrowInvalidArgument(nil, "COMMAND-PQN0wsqSyi", "Errors.ResourceOwnerMissing")
}
if config.ID == "" {
config.ID, err = c.idGenerator.Next()
if err != nil {
return err
}
}
from := strings.TrimSpace(config.From)
if from == "" {
return "", nil, zerrors.ThrowInvalidArgument(nil, "INST-ASv2d", "Errors.Invalid.Argument")
return zerrors.ThrowInvalidArgument(nil, "COMMAND-SAAFpV8VKV", "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)
hostAndPort := strings.TrimSpace(config.Host)
if _, _, err := net.SplitHostPort(hostAndPort); err != nil {
return "", nil, zerrors.ThrowInvalidArgument(nil, "INST-9JdRe", "Errors.Invalid.Argument")
return zerrors.ThrowInvalidArgument(nil, "COMMAND-EvAtufIinh", "Errors.Invalid.Argument")
}
var smtpPassword *crypto.CryptoValue
if config.SMTP.Password != "" {
smtpPassword, err = crypto.Encrypt([]byte(config.SMTP.Password), c.smtpEncryption)
if config.Password != "" {
smtpPassword, err = crypto.Encrypt([]byte(config.Password), c.smtpEncryption)
if err != nil {
return "", nil, err
return err
}
}
smtpConfigWriteModel, err := c.getSMTPConfig(ctx, instanceID, id, senderDomain)
smtpConfigWriteModel, err := c.getSMTPConfig(ctx, config.ResourceOwner, config.ID, senderDomain)
if err != nil {
return "", nil, err
return err
}
err = checkSenderAddress(smtpConfigWriteModel)
if err != nil {
return "", nil, err
return 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,
))
err = c.pushAppendAndReduce(ctx,
smtpConfigWriteModel,
instance.NewSMTPConfigAddedEvent(
ctx,
InstanceAggregateFromWriteModel(&smtpConfigWriteModel.WriteModel),
config.ID,
description,
config.Tls,
config.From,
config.FromName,
replyTo,
hostAndPort,
config.User,
smtpPassword,
),
)
if err != nil {
return "", nil, err
return err
}
err = AppendAndReduce(smtpConfigWriteModel, pushedEvents...)
if err != nil {
return "", nil, err
}
return id, writeModelToObjectDetails(&smtpConfigWriteModel.WriteModel), nil
config.Details = writeModelToObjectDetails(&smtpConfigWriteModel.WriteModel)
return nil
}
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")
type ChangeSMTPConfig struct {
Details *domain.ObjectDetails
ResourceOwner string
ID string
Description string
Host string
User string
Password string
Tls bool
From string
FromName string
ReplyToAddress string
}
func (c *Commands) ChangeSMTPConfig(ctx context.Context, config *ChangeSMTPConfig) error {
if config.ResourceOwner == "" {
return zerrors.ThrowInvalidArgument(nil, "COMMAND-jwA8gxldy3", "Errors.ResourceOwnerMissing")
}
if config.ID == "" {
return zerrors.ThrowInvalidArgument(nil, "COMMAND-2JPlSRzuHy", "Errors.IDMissing")
}
from := strings.TrimSpace(config.From)
if from == "" {
return nil, zerrors.ThrowInvalidArgument(nil, "INST-HSv2d", "Errors.Invalid.Argument")
return zerrors.ThrowInvalidArgument(nil, "COMMAND-gyPUXOTA4N", "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)
hostAndPort := strings.TrimSpace(config.Host)
if _, _, err := net.SplitHostPort(hostAndPort); err != nil {
return nil, zerrors.ThrowInvalidArgument(nil, "INST-Kv875", "Errors.Invalid.Argument")
return zerrors.ThrowInvalidArgument(nil, "COMMAND-kZNVkuL32L", "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 config.Password != "" {
smtpPassword, err = crypto.Encrypt([]byte(config.Password), c.smtpEncryption)
if err != nil {
return nil, err
return err
}
}
smtpConfigWriteModel, err := c.getSMTPConfig(ctx, instanceID, id, senderDomain)
smtpConfigWriteModel, err := c.getSMTPConfig(ctx, config.ResourceOwner, config.ID, senderDomain)
if err != nil {
return nil, err
return err
}
if !smtpConfigWriteModel.State.Exists() {
return nil, zerrors.ThrowNotFound(nil, "COMMAND-7j8gv", "Errors.SMTPConfig.NotFound")
return zerrors.ThrowNotFound(nil, "COMMAND-j5IDFtt3T1", "Errors.SMTPConfig.NotFound")
}
err = checkSenderAddress(smtpConfigWriteModel)
if err != nil {
return nil, err
return err
}
iamAgg := InstanceAggregateFromWriteModel(&smtpConfigWriteModel.WriteModel)
changedEvent, hasChanged, err := smtpConfigWriteModel.NewChangedEvent(
ctx,
iamAgg,
id,
InstanceAggregateFromWriteModel(&smtpConfigWriteModel.WriteModel),
config.ID,
description,
config.Tls,
from,
config.FromName,
replyTo,
hostAndPort,
config.SMTP.User,
config.User,
smtpPassword,
)
if err != nil {
return nil, err
return err
}
if !hasChanged {
return nil, zerrors.ThrowPreconditionFailed(nil, "COMMAND-lh3op", "Errors.NoChangesFound")
config.Details = writeModelToObjectDetails(&smtpConfigWriteModel.WriteModel)
return nil
}
pushedEvents, err := c.eventstore.Push(ctx, changedEvent)
err = c.pushAppendAndReduce(ctx, smtpConfigWriteModel, changedEvent)
if err != nil {
return nil, err
return err
}
err = AppendAndReduce(smtpConfigWriteModel, pushedEvents...)
if err != nil {
return nil, err
}
return writeModelToObjectDetails(&smtpConfigWriteModel.WriteModel), nil
config.Details = writeModelToObjectDetails(&smtpConfigWriteModel.WriteModel)
return nil
}
func (c *Commands) ChangeSMTPConfigPassword(ctx context.Context, instanceID, id string, password string) (*domain.ObjectDetails, error) {
instanceAgg := instance.NewAggregate(authz.GetInstance(ctx).InstanceID())
smtpConfigWriteModel, err := c.getSMTPConfig(ctx, instanceID, id, "")
func (c *Commands) ChangeSMTPConfigPassword(ctx context.Context, resourceOwner, id string, password string) (*domain.ObjectDetails, error) {
if resourceOwner == "" {
return nil, zerrors.ThrowInvalidArgument(nil, "COMMAND-gHAyvUXCAF", "Errors.ResourceOwnerMissing")
}
if id == "" {
return nil, zerrors.ThrowInvalidArgument(nil, "COMMAND-BCkAf7LcJA", "Errors.IDMissing")
}
smtpConfigWriteModel, err := c.getSMTPConfig(ctx, resourceOwner, id, "")
if err != nil {
return nil, err
}
if smtpConfigWriteModel.State != domain.SMTPConfigStateActive {
return nil, zerrors.ThrowNotFound(nil, "COMMAND-3n9ls", "Errors.SMTPConfig.NotFound")
return nil, zerrors.ThrowNotFound(nil, "COMMAND-rDHzqjGuKQ", "Errors.SMTPConfig.NotFound")
}
var smtpPassword *crypto.CryptoValue
@@ -170,68 +208,152 @@ func (c *Commands) ChangeSMTPConfigPassword(ctx context.Context, instanceID, id
}
}
pushedEvents, err := c.eventstore.Push(ctx, instance.NewSMTPConfigPasswordChangedEvent(
ctx,
&instanceAgg.Aggregate,
id,
smtpPassword))
err = c.pushAppendAndReduce(ctx,
smtpConfigWriteModel,
instance.NewSMTPConfigPasswordChangedEvent(
ctx,
InstanceAggregateFromWriteModel(&smtpConfigWriteModel.WriteModel),
id,
smtpPassword,
),
)
if err != nil {
return nil, err
}
err = AppendAndReduce(smtpConfigWriteModel, pushedEvents...)
if err != nil {
return nil, err
}
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")
}
type AddSMTPConfigHTTP struct {
Details *domain.ObjectDetails
ResourceOwner string
ID string
if len(activatedId) > 0 {
_, err := c.DeactivateSMTPConfig(ctx, instanceID, activatedId)
Description string
Endpoint string
}
func (c *Commands) AddSMTPConfigHTTP(ctx context.Context, config *AddSMTPConfigHTTP) (err error) {
if config.ResourceOwner == "" {
return zerrors.ThrowInvalidArgument(nil, "COMMAND-FTNDXc8ACS", "Errors.ResourceOwnerMissing")
}
if config.ID == "" {
config.ID, err = c.idGenerator.Next()
if err != nil {
return nil, err
return err
}
}
smtpConfigWriteModel, err := c.getSMTPConfig(ctx, instanceID, id, "")
smtpConfigWriteModel, err := c.getSMTPConfig(ctx, config.ResourceOwner, config.ID, "")
if err != nil {
return err
}
err = c.pushAppendAndReduce(ctx, smtpConfigWriteModel, instance.NewSMTPConfigHTTPAddedEvent(
ctx,
InstanceAggregateFromWriteModel(&smtpConfigWriteModel.WriteModel),
config.ID,
config.Description,
config.Endpoint,
))
if err != nil {
return err
}
config.Details = writeModelToObjectDetails(&smtpConfigWriteModel.WriteModel)
return nil
}
type ChangeSMTPConfigHTTP struct {
Details *domain.ObjectDetails
ResourceOwner string
ID string
Description string
Endpoint string
}
func (c *Commands) ChangeSMTPConfigHTTP(ctx context.Context, config *ChangeSMTPConfigHTTP) (err error) {
if config.ResourceOwner == "" {
return zerrors.ThrowInvalidArgument(nil, "COMMAND-k7QCGOWyJA", "Errors.ResourceOwnerMissing")
}
if config.ID == "" {
return zerrors.ThrowInvalidArgument(nil, "COMMAND-2MHkV8ObWo", "Errors.IDMissing")
}
smtpConfigWriteModel, err := c.getSMTPConfig(ctx, config.ResourceOwner, config.ID, "")
if err != nil {
return err
}
if !smtpConfigWriteModel.State.Exists() || smtpConfigWriteModel.HTTPConfig == nil {
return zerrors.ThrowNotFound(nil, "COMMAND-xIrdledqv4", "Errors.SMTPConfig.NotFound")
}
changedEvent, hasChanged, err := smtpConfigWriteModel.NewHTTPChangedEvent(
ctx,
InstanceAggregateFromWriteModel(&smtpConfigWriteModel.WriteModel),
config.ID,
config.Description,
config.Endpoint,
)
if err != nil {
return err
}
if !hasChanged {
config.Details = writeModelToObjectDetails(&smtpConfigWriteModel.WriteModel)
return nil
}
err = c.pushAppendAndReduce(ctx, smtpConfigWriteModel, changedEvent)
if err != nil {
return err
}
config.Details = writeModelToObjectDetails(&smtpConfigWriteModel.WriteModel)
return nil
}
func (c *Commands) ActivateSMTPConfig(ctx context.Context, resourceOwner, id string) (*domain.ObjectDetails, error) {
if resourceOwner == "" {
return nil, zerrors.ThrowInvalidArgument(nil, "COMMAND-h5htMCebv3", "Errors.ResourceOwnerMissing")
}
if id == "" {
return nil, zerrors.ThrowInvalidArgument(nil, "COMMAND-1hPl6oVMJa", "Errors.IDMissing")
}
smtpConfigWriteModel, err := c.getSMTPConfig(ctx, resourceOwner, id, "")
if err != nil {
return nil, err
}
if !smtpConfigWriteModel.State.Exists() {
return nil, zerrors.ThrowNotFound(nil, "COMMAND-kg8yr", "Errors.SMTPConfig.NotFound")
return nil, zerrors.ThrowNotFound(nil, "COMMAND-E9K20hxOS9", "Errors.SMTPConfig.NotFound")
}
if smtpConfigWriteModel.State == domain.SMTPConfigStateActive {
return nil, zerrors.ThrowNotFound(nil, "COMMAND-ed3lr", "Errors.SMTPConfig.AlreadyActive")
return nil, zerrors.ThrowPreconditionFailed(nil, "COMMAND-vUHBSmBzaw", "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...)
err = c.pushAppendAndReduce(ctx,
smtpConfigWriteModel,
instance.NewSMTPConfigActivatedEvent(
ctx,
InstanceAggregateFromWriteModel(&smtpConfigWriteModel.WriteModel),
id,
),
)
if err != nil {
return nil, err
}
return writeModelToObjectDetails(&smtpConfigWriteModel.WriteModel), nil
}
func (c *Commands) DeactivateSMTPConfig(ctx context.Context, instanceID, id string) (*domain.ObjectDetails, error) {
func (c *Commands) DeactivateSMTPConfig(ctx context.Context, resourceOwner, id string) (*domain.ObjectDetails, error) {
if resourceOwner == "" {
return nil, zerrors.ThrowInvalidArgument(nil, "COMMAND-pvNHou89Tw", "Errors.ResourceOwnerMissing")
}
if id == "" {
return nil, zerrors.ThrowInvalidArgument(nil, "SMTP-98ikl", "Errors.IDMissing")
return nil, zerrors.ThrowInvalidArgument(nil, "COMMAND-jLTIMrtApO", "Errors.IDMissing")
}
smtpConfigWriteModel, err := c.getSMTPConfig(ctx, instanceID, id, "")
smtpConfigWriteModel, err := c.getSMTPConfig(ctx, resourceOwner, id, "")
if err != nil {
return nil, err
}
@@ -239,46 +361,47 @@ func (c *Commands) DeactivateSMTPConfig(ctx context.Context, instanceID, id stri
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")
return nil, zerrors.ThrowPreconditionFailed(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...)
err = c.pushAppendAndReduce(ctx,
smtpConfigWriteModel,
instance.NewSMTPConfigDeactivatedEvent(
ctx,
InstanceAggregateFromWriteModel(&smtpConfigWriteModel.WriteModel),
id,
),
)
if err != nil {
return nil, err
}
return writeModelToObjectDetails(&smtpConfigWriteModel.WriteModel), nil
}
func (c *Commands) RemoveSMTPConfig(ctx context.Context, instanceID, id string) (*domain.ObjectDetails, error) {
func (c *Commands) RemoveSMTPConfig(ctx context.Context, resourceOwner, id string) (*domain.ObjectDetails, error) {
if resourceOwner == "" {
return nil, zerrors.ThrowInvalidArgument(nil, "COMMAND-t2WsPRgGaK", "Errors.ResourceOwnerMissing")
}
if id == "" {
return nil, zerrors.ThrowInvalidArgument(nil, "SMTP-7f5cv", "Errors.IDMissing")
return nil, zerrors.ThrowInvalidArgument(nil, "COMMAND-0ZV5whuUfu", "Errors.IDMissing")
}
smtpConfigWriteModel, err := c.getSMTPConfig(ctx, instanceID, id, "")
smtpConfigWriteModel, err := c.getSMTPConfig(ctx, resourceOwner, id, "")
if err != nil {
return nil, err
}
if !smtpConfigWriteModel.State.Exists() {
return nil, zerrors.ThrowNotFound(nil, "COMMAND-kg8rt", "Errors.SMTPConfig.NotFound")
return nil, zerrors.ThrowNotFound(nil, "COMMAND-09CXlTDL6w", "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...)
err = c.pushAppendAndReduce(ctx,
smtpConfigWriteModel,
instance.NewSMTPConfigRemovedEvent(
ctx,
InstanceAggregateFromWriteModel(&smtpConfigWriteModel.WriteModel),
id,
),
)
if err != nil {
return nil, err
}
@@ -303,11 +426,11 @@ func (c *Commands) TestSMTPConfig(ctx context.Context, instanceID, id, email str
if err != nil {
return err
}
if !smtpConfigWriteModel.State.Exists() {
if !smtpConfigWriteModel.State.Exists() || smtpConfigWriteModel.SMTPConfig == nil {
return zerrors.ThrowNotFound(nil, "SMTP-p9cc", "Errors.SMTPConfig.NotFound")
}
password, err = crypto.DecryptString(smtpConfigWriteModel.Password, c.smtpEncryption)
password, err = crypto.DecryptString(smtpConfigWriteModel.SMTPConfig.Password, c.smtpEncryption)
if err != nil {
return err
}
@@ -338,23 +461,22 @@ func (c *Commands) TestSMTPConfigById(ctx context.Context, instanceID, id, email
return err
}
if !smtpConfigWriteModel.State.Exists() {
if !smtpConfigWriteModel.State.Exists() || smtpConfigWriteModel.SMTPConfig == nil {
return zerrors.ThrowNotFound(nil, "SMTP-99klw", "Errors.SMTPConfig.NotFound")
}
password, err := crypto.DecryptString(smtpConfigWriteModel.Password, c.smtpEncryption)
password, err := crypto.DecryptString(smtpConfigWriteModel.SMTPConfig.Password, c.smtpEncryption)
if err != nil {
return err
}
smtpConfig := &smtp.Config{
Description: smtpConfigWriteModel.Description,
Tls: smtpConfigWriteModel.TLS,
From: smtpConfigWriteModel.SenderAddress,
FromName: smtpConfigWriteModel.SenderName,
Tls: smtpConfigWriteModel.SMTPConfig.TLS,
From: smtpConfigWriteModel.SMTPConfig.SenderAddress,
FromName: smtpConfigWriteModel.SMTPConfig.SenderName,
SMTP: smtp.SMTP{
Host: smtpConfigWriteModel.Host,
User: smtpConfigWriteModel.User,
Host: smtpConfigWriteModel.SMTPConfig.Host,
User: smtpConfigWriteModel.SMTPConfig.User,
Password: password,
},
}
@@ -373,7 +495,7 @@ func checkSenderAddress(writeModel *IAMSMTPConfigWriteModel) error {
return nil
}
if !writeModel.domainState.Exists() {
return zerrors.ThrowInvalidArgument(nil, "INST-83nl8", "Errors.SMTPConfig.SenderAdressNotCustomDomain")
return zerrors.ThrowInvalidArgument(nil, "INST-xtWIiR2ZbR", "Errors.SMTPConfig.SenderAdressNotCustomDomain")
}
return nil
}

File diff suppressed because it is too large Load Diff

View File

@@ -5,8 +5,8 @@ import (
"github.com/zitadel/logging"
"github.com/zitadel/zitadel/internal/notification/channels/email"
"github.com/zitadel/zitadel/internal/notification/channels/sms"
"github.com/zitadel/zitadel/internal/notification/channels/smtp"
"github.com/zitadel/zitadel/internal/notification/channels/webhook"
"github.com/zitadel/zitadel/internal/notification/handlers"
"github.com/zitadel/zitadel/internal/notification/senders"
@@ -62,20 +62,20 @@ func registerCounter(counter, desc string) {
logging.WithFields("metric", counter).OnError(err).Panic("unable to register counter")
}
func (c *channels) Email(ctx context.Context) (*senders.Chain, *smtp.Config, error) {
smtpCfg, err := c.q.GetSMTPConfig(ctx)
func (c *channels) Email(ctx context.Context) (*senders.Chain, *email.Config, error) {
emailCfg, err := c.q.GetActiveEmailConfig(ctx)
if err != nil {
return nil, nil, err
}
chain, err := senders.EmailChannels(
ctx,
smtpCfg,
emailCfg,
c.q.GetFileSystemProvider,
c.q.GetLogProvider,
c.counters.success.email,
c.counters.failed.email,
)
return chain, smtpCfg, err
return chain, emailCfg, err
}
func (c *channels) SMS(ctx context.Context) (*senders.Chain, *sms.Config, error) {

View File

@@ -0,0 +1,17 @@
package email
import (
"github.com/zitadel/zitadel/internal/notification/channels/smtp"
"github.com/zitadel/zitadel/internal/notification/channels/webhook"
)
type Config struct {
ProviderConfig *Provider
SMTPConfig *smtp.Config
WebhookConfig *webhook.Config
}
type Provider struct {
ID string `json:"id,omitempty"`
Description string `json:"description,omitempty"`
}

View File

@@ -1,7 +1,6 @@
package smtp
type Config struct {
Description string
SMTP SMTP
Tls bool
From string
@@ -18,3 +17,7 @@ type SMTP struct {
func (smtp *SMTP) HasAuth() bool {
return smtp.User != "" && smtp.Password != ""
}
type ConfigHTTP struct {
Endpoint string
}

View File

@@ -0,0 +1,56 @@
package handlers
import (
"context"
"net/http"
"github.com/zitadel/zitadel/internal/api/authz"
"github.com/zitadel/zitadel/internal/crypto"
"github.com/zitadel/zitadel/internal/notification/channels/email"
"github.com/zitadel/zitadel/internal/notification/channels/smtp"
"github.com/zitadel/zitadel/internal/notification/channels/webhook"
"github.com/zitadel/zitadel/internal/zerrors"
)
// GetSMTPConfig reads the iam SMTP provider config
func (n *NotificationQueries) GetActiveEmailConfig(ctx context.Context) (*email.Config, error) {
config, err := n.SMTPConfigActive(ctx, authz.GetInstance(ctx).InstanceID())
if err != nil {
return nil, err
}
provider := &email.Provider{
ID: config.ID,
Description: config.Description,
}
if config.SMTPConfig != nil {
password, err := crypto.DecryptString(config.SMTPConfig.Password, n.SMTPPasswordCrypto)
if err != nil {
return nil, err
}
return &email.Config{
ProviderConfig: provider,
SMTPConfig: &smtp.Config{
From: config.SMTPConfig.SenderAddress,
FromName: config.SMTPConfig.SenderName,
ReplyToAddress: config.SMTPConfig.ReplyToAddress,
Tls: config.SMTPConfig.TLS,
SMTP: smtp.SMTP{
Host: config.SMTPConfig.Host,
User: config.SMTPConfig.User,
Password: password,
},
},
}, nil
}
if config.HTTPConfig != nil {
return &email.Config{
ProviderConfig: provider,
WebhookConfig: &webhook.Config{
CallURL: config.HTTPConfig.Endpoint,
Method: http.MethodPost,
Headers: nil,
},
}, nil
}
return nil, zerrors.ThrowNotFound(err, "QUERY-KPQleOckOV", "Errors.SMTPConfig.NotFound")
}

View File

@@ -1,33 +0,0 @@
package handlers
import (
"context"
"github.com/zitadel/zitadel/internal/api/authz"
"github.com/zitadel/zitadel/internal/crypto"
"github.com/zitadel/zitadel/internal/notification/channels/smtp"
)
// GetSMTPConfig reads the iam SMTP provider config
func (n *NotificationQueries) GetSMTPConfig(ctx context.Context) (*smtp.Config, error) {
config, err := n.SMTPConfigActive(ctx, authz.GetInstance(ctx).InstanceID())
if err != nil {
return nil, err
}
password, err := crypto.DecryptString(config.Password, n.SMTPPasswordCrypto)
if err != nil {
return nil, err
}
return &smtp.Config{
Description: config.Description,
From: config.SenderAddress,
FromName: config.SenderName,
ReplyToAddress: config.ReplyToAddress,
Tls: config.TLS,
SMTP: smtp.SMTP{
Host: config.Host,
User: config.User,
Password: password,
},
}, nil
}

View File

@@ -15,6 +15,7 @@ import (
"github.com/zitadel/zitadel/internal/eventstore"
"github.com/zitadel/zitadel/internal/eventstore/repository"
es_repo_mock "github.com/zitadel/zitadel/internal/eventstore/repository/mock"
"github.com/zitadel/zitadel/internal/notification/channels/email"
channel_mock "github.com/zitadel/zitadel/internal/notification/channels/mock"
"github.com/zitadel/zitadel/internal/notification/channels/sms"
"github.com/zitadel/zitadel/internal/notification/channels/smtp"
@@ -1449,7 +1450,27 @@ func newUserNotifier(t *testing.T, ctrl *gomock.Controller, queries *mock.MockQu
f.SMSTokenCrypto,
),
otpEmailTmpl: defaultOTPEmailTemplate,
channels: &channels{Chain: *senders.ChainChannels(channel)},
channels: &channels{
Chain: *senders.ChainChannels(channel),
EmailConfig: &email.Config{
ProviderConfig: &email.Provider{
ID: "ID",
Description: "Description",
},
SMTPConfig: &smtp.Config{
SMTP: smtp.SMTP{
Host: "host",
User: "user",
Password: "password",
},
Tls: true,
From: "from",
FromName: "fromName",
ReplyToAddress: "replyToAddress",
},
WebhookConfig: nil,
},
},
}
}
@@ -1457,10 +1478,11 @@ var _ types.ChannelChains = (*channels)(nil)
type channels struct {
senders.Chain
EmailConfig *email.Config
}
func (c *channels) Email(context.Context) (*senders.Chain, *smtp.Config, error) {
return &c.Chain, nil, nil
func (c *channels) Email(context.Context) (*senders.Chain, *email.Config, error) {
return &c.Chain, c.EmailConfig, nil
}
func (c *channels) SMS(context.Context) (*senders.Chain, *sms.Config, error) {

View File

@@ -7,38 +7,61 @@ import (
"github.com/zitadel/zitadel/internal/api/authz"
"github.com/zitadel/zitadel/internal/notification/channels"
"github.com/zitadel/zitadel/internal/notification/channels/email"
"github.com/zitadel/zitadel/internal/notification/channels/fs"
"github.com/zitadel/zitadel/internal/notification/channels/instrumenting"
"github.com/zitadel/zitadel/internal/notification/channels/log"
"github.com/zitadel/zitadel/internal/notification/channels/smtp"
"github.com/zitadel/zitadel/internal/notification/channels/webhook"
)
const smtpSpanName = "smtp.NotificationChannel"
func EmailChannels(
ctx context.Context,
emailConfig *smtp.Config,
emailConfig *email.Config,
getFileSystemProvider func(ctx context.Context) (*fs.Config, error),
getLogProvider func(ctx context.Context) (*log.Config, error),
successMetricName,
failureMetricName string,
) (chain *Chain, err error) {
channels := make([]channels.NotificationChannel, 0, 3)
p, err := smtp.InitChannel(emailConfig)
logging.WithFields(
"instance", authz.GetInstance(ctx).InstanceID(),
).OnError(err).Debug("initializing SMTP channel failed")
if err == nil {
channels = append(
channels,
instrumenting.Wrap(
ctx,
p,
smtpSpanName,
successMetricName,
failureMetricName,
),
)
if emailConfig.SMTPConfig != nil {
p, err := smtp.InitChannel(emailConfig.SMTPConfig)
logging.WithFields(
"instance", authz.GetInstance(ctx).InstanceID(),
).OnError(err).Debug("initializing SMTP channel failed")
if err == nil {
channels = append(
channels,
instrumenting.Wrap(
ctx,
p,
smtpSpanName,
successMetricName,
failureMetricName,
),
)
}
}
if emailConfig.WebhookConfig != nil {
webhookChannel, err := webhook.InitChannel(ctx, *emailConfig.WebhookConfig)
logging.WithFields(
"instance", authz.GetInstance(ctx).InstanceID(),
"callurl", emailConfig.WebhookConfig.CallURL,
).OnError(err).Debug("initializing JSON channel failed")
if err == nil {
channels = append(
channels,
instrumenting.Wrap(
ctx,
webhookChannel,
webhookSpanName,
successMetricName,
failureMetricName,
),
)
}
}
channels = append(channels, debugChannels(ctx, getFileSystemProvider, getLogProvider)...)
return ChainChannels(channels...), nil

View File

@@ -7,8 +7,8 @@ import (
"github.com/zitadel/zitadel/internal/database"
"github.com/zitadel/zitadel/internal/eventstore"
"github.com/zitadel/zitadel/internal/i18n"
"github.com/zitadel/zitadel/internal/notification/channels/email"
"github.com/zitadel/zitadel/internal/notification/channels/sms"
"github.com/zitadel/zitadel/internal/notification/channels/smtp"
"github.com/zitadel/zitadel/internal/notification/channels/webhook"
"github.com/zitadel/zitadel/internal/notification/senders"
"github.com/zitadel/zitadel/internal/notification/templates"
@@ -23,7 +23,7 @@ type Notify func(
) error
type ChannelChains interface {
Email(context.Context) (*senders.Chain, *smtp.Config, error)
Email(context.Context) (*senders.Chain, *email.Config, error)
SMS(context.Context) (*senders.Chain, *sms.Config, error)
Webhook(context.Context, webhook.Config) (*senders.Chain, error)
}
@@ -54,8 +54,9 @@ func SendEmail(
ctx,
channels,
user,
data.Subject,
template,
data,
args,
allowUnverifiedNotificationChannel,
triggeringEvent,
)

View File

@@ -3,9 +3,13 @@ package types
import (
"context"
"html"
"strings"
"github.com/zitadel/logging"
"github.com/zitadel/zitadel/internal/eventstore"
"github.com/zitadel/zitadel/internal/notification/messages"
"github.com/zitadel/zitadel/internal/notification/templates"
"github.com/zitadel/zitadel/internal/query"
"github.com/zitadel/zitadel/internal/zerrors"
)
@@ -14,29 +18,56 @@ func generateEmail(
ctx context.Context,
channels ChannelChains,
user *query.NotifyUser,
subject,
content string,
template string,
data templates.TemplateData,
args map[string]interface{},
lastEmail bool,
triggeringEvent eventstore.Event,
) error {
content = html.UnescapeString(content)
message := &messages.Email{
Recipients: []string{user.VerifiedEmail},
Subject: subject,
Content: content,
TriggeringEvent: triggeringEvent,
}
if lastEmail {
message.Recipients = []string{user.LastEmail}
}
emailChannels, _, err := channels.Email(ctx)
if err != nil {
return err
}
emailChannels, config, err := channels.Email(ctx)
logging.OnError(err).Error("could not create email channel")
if emailChannels == nil || emailChannels.Len() == 0 {
return zerrors.ThrowPreconditionFailed(nil, "MAIL-83nof", "Errors.Notification.Channels.NotPresent")
return zerrors.ThrowPreconditionFailed(nil, "PHONE-w8nfow", "Errors.Notification.Channels.NotPresent")
}
return emailChannels.HandleMessage(message)
recipient := user.VerifiedEmail
if lastEmail {
recipient = user.LastEmail
}
if config.SMTPConfig != nil {
message := &messages.Email{
Recipients: []string{recipient},
Subject: data.Subject,
Content: html.UnescapeString(template),
TriggeringEvent: triggeringEvent,
}
return emailChannels.HandleMessage(message)
}
if config.WebhookConfig != nil {
caseArgs := make(map[string]interface{}, len(args))
for k, v := range args {
caseArgs[strings.ToLower(string(k[0]))+k[1:]] = v
}
contextInfo := map[string]interface{}{
"recipientEmailAddress": recipient,
"eventType": triggeringEvent.Type(),
"provider": config.ProviderConfig,
}
message := &messages.JSON{
Serializable: &serializableData{
ContextInfo: contextInfo,
TemplateData: data,
Args: caseArgs,
},
TriggeringEvent: triggeringEvent,
}
webhookChannels, err := channels.Webhook(ctx, *config.WebhookConfig)
if err != nil {
return err
}
return webhookChannels.HandleMessage(message)
}
return zerrors.ThrowPreconditionFailed(nil, "MAIL-83nof", "Errors.Notification.Channels.NotPresent")
}
func mapNotifyUserToArgs(user *query.NotifyUser, args map[string]interface{}) map[string]interface{} {

View File

@@ -8,26 +8,38 @@ import (
old_handler "github.com/zitadel/zitadel/internal/eventstore/handler"
"github.com/zitadel/zitadel/internal/eventstore/handler/v2"
"github.com/zitadel/zitadel/internal/repository/instance"
"github.com/zitadel/zitadel/internal/zerrors"
)
const (
SMTPConfigProjectionTable = "projections.smtp_configs2"
SMTPConfigColumnInstanceID = "instance_id"
SMTPConfigColumnResourceOwner = "resource_owner"
SMTPConfigColumnID = "id"
SMTPConfigColumnCreationDate = "creation_date"
SMTPConfigColumnChangeDate = "change_date"
SMTPConfigColumnSequence = "sequence"
SMTPConfigColumnTLS = "tls"
SMTPConfigColumnSenderAddress = "sender_address"
SMTPConfigColumnSenderName = "sender_name"
SMTPConfigColumnReplyToAddress = "reply_to_address"
SMTPConfigColumnSMTPHost = "host"
SMTPConfigColumnSMTPUser = "username"
SMTPConfigColumnSMTPPassword = "password"
SMTPConfigColumnState = "state"
SMTPConfigColumnDescription = "description"
SMTPConfigProjectionTable = "projections.smtp_configs3"
SMTPConfigTable = SMTPConfigProjectionTable + "_" + smtpConfigSMTPTableSuffix
SMTPConfigHTTPTable = SMTPConfigProjectionTable + "_" + smtpConfigHTTPTableSuffix
SMTPConfigColumnInstanceID = "instance_id"
SMTPConfigColumnResourceOwner = "resource_owner"
SMTPConfigColumnAggregateID = "aggregate_id"
SMTPConfigColumnID = "id"
SMTPConfigColumnCreationDate = "creation_date"
SMTPConfigColumnChangeDate = "change_date"
SMTPConfigColumnSequence = "sequence"
SMTPConfigColumnState = "state"
SMTPConfigColumnDescription = "description"
smtpConfigSMTPTableSuffix = "smtp"
SMTPConfigSMTPColumnInstanceID = "instance_id"
SMTPConfigSMTPColumnID = "id"
SMTPConfigSMTPColumnTLS = "tls"
SMTPConfigSMTPColumnSenderAddress = "sender_address"
SMTPConfigSMTPColumnSenderName = "sender_name"
SMTPConfigSMTPColumnReplyToAddress = "reply_to_address"
SMTPConfigSMTPColumnHost = "host"
SMTPConfigSMTPColumnUser = "username"
SMTPConfigSMTPColumnPassword = "password"
smtpConfigHTTPTableSuffix = "http"
SMTPConfigHTTPColumnInstanceID = "instance_id"
SMTPConfigHTTPColumnID = "id"
SMTPConfigHTTPColumnEndpoint = "endpoint"
)
type smtpConfigProjection struct{}
@@ -41,25 +53,43 @@ func (*smtpConfigProjection) Name() string {
}
func (*smtpConfigProjection) Init() *old_handler.Check {
return handler.NewTableCheck(
return handler.NewMultiTableCheck(
handler.NewTable([]*handler.InitColumn{
handler.NewColumn(SMTPConfigColumnID, handler.ColumnTypeText),
handler.NewColumn(SMTPConfigColumnAggregateID, handler.ColumnTypeText),
handler.NewColumn(SMTPConfigColumnCreationDate, handler.ColumnTypeTimestamp),
handler.NewColumn(SMTPConfigColumnChangeDate, handler.ColumnTypeTimestamp),
handler.NewColumn(SMTPConfigColumnSequence, handler.ColumnTypeInt64),
handler.NewColumn(SMTPConfigColumnResourceOwner, handler.ColumnTypeText),
handler.NewColumn(SMTPConfigColumnInstanceID, handler.ColumnTypeText),
handler.NewColumn(SMTPConfigColumnTLS, handler.ColumnTypeBool),
handler.NewColumn(SMTPConfigColumnSenderAddress, handler.ColumnTypeText),
handler.NewColumn(SMTPConfigColumnSenderName, handler.ColumnTypeText),
handler.NewColumn(SMTPConfigColumnReplyToAddress, handler.ColumnTypeText),
handler.NewColumn(SMTPConfigColumnSMTPHost, handler.ColumnTypeText),
handler.NewColumn(SMTPConfigColumnSMTPUser, handler.ColumnTypeText),
handler.NewColumn(SMTPConfigColumnSMTPPassword, handler.ColumnTypeJSONB, handler.Nullable()),
handler.NewColumn(SMTPConfigColumnState, handler.ColumnTypeEnum),
handler.NewColumn(SMTPConfigColumnDescription, handler.ColumnTypeText),
handler.NewColumn(SMTPConfigColumnState, handler.ColumnTypeEnum),
},
handler.NewPrimaryKey(SMTPConfigColumnInstanceID, SMTPConfigColumnResourceOwner, SMTPConfigColumnID),
handler.NewPrimaryKey(SMTPConfigColumnInstanceID, SMTPConfigColumnID),
),
handler.NewSuffixedTable([]*handler.InitColumn{
handler.NewColumn(SMTPConfigSMTPColumnID, handler.ColumnTypeText),
handler.NewColumn(SMTPConfigSMTPColumnInstanceID, handler.ColumnTypeText),
handler.NewColumn(SMTPConfigSMTPColumnTLS, handler.ColumnTypeBool),
handler.NewColumn(SMTPConfigSMTPColumnSenderAddress, handler.ColumnTypeText),
handler.NewColumn(SMTPConfigSMTPColumnSenderName, handler.ColumnTypeText),
handler.NewColumn(SMTPConfigSMTPColumnReplyToAddress, handler.ColumnTypeText),
handler.NewColumn(SMTPConfigSMTPColumnHost, handler.ColumnTypeText),
handler.NewColumn(SMTPConfigSMTPColumnUser, handler.ColumnTypeText),
handler.NewColumn(SMTPConfigSMTPColumnPassword, handler.ColumnTypeJSONB, handler.Nullable()),
},
handler.NewPrimaryKey(SMTPConfigSMTPColumnInstanceID, SMTPConfigSMTPColumnID),
smtpConfigSMTPTableSuffix,
handler.WithForeignKey(handler.NewForeignKeyOfPublicKeys()),
),
handler.NewSuffixedTable([]*handler.InitColumn{
handler.NewColumn(SMTPConfigHTTPColumnID, handler.ColumnTypeText),
handler.NewColumn(SMTPConfigHTTPColumnInstanceID, handler.ColumnTypeText),
handler.NewColumn(SMTPConfigHTTPColumnEndpoint, handler.ColumnTypeText),
},
handler.NewPrimaryKey(SMTPConfigHTTPColumnInstanceID, SMTPConfigHTTPColumnID),
smtpConfigHTTPTableSuffix,
handler.WithForeignKey(handler.NewForeignKeyOfPublicKeys()),
),
)
}
@@ -81,6 +111,14 @@ func (p *smtpConfigProjection) Reducers() []handler.AggregateReducer {
Event: instance.SMTPConfigPasswordChangedEventType,
Reduce: p.reduceSMTPConfigPasswordChanged,
},
{
Event: instance.SMTPConfigHTTPAddedEventType,
Reduce: p.reduceSMTPConfigHTTPAdded,
},
{
Event: instance.SMTPConfigHTTPChangedEventType,
Reduce: p.reduceSMTPConfigHTTPChanged,
},
{
Event: instance.SMTPConfigActivatedEventType,
Reduce: p.reduceSMTPConfigActivated,
@@ -103,9 +141,9 @@ func (p *smtpConfigProjection) Reducers() []handler.AggregateReducer {
}
func (p *smtpConfigProjection) reduceSMTPConfigAdded(event eventstore.Event) (*handler.Statement, error) {
e, ok := event.(*instance.SMTPConfigAddedEvent)
if !ok {
return nil, zerrors.ThrowInvalidArgumentf(nil, "HANDL-sk99F", "reduce.wrong.event.type %s", instance.SMTPConfigAddedEventType)
e, err := assertEvent[*instance.SMTPConfigAddedEvent](event)
if err != nil {
return nil, err
}
// Deal with old and unique SMTP settings (empty ID)
@@ -118,83 +156,116 @@ func (p *smtpConfigProjection) reduceSMTPConfigAdded(event eventstore.Event) (*h
state = domain.SMTPConfigStateActive
}
return handler.NewCreateStatement(
return handler.NewMultiStatement(
e,
[]handler.Column{
handler.NewCol(SMTPConfigColumnCreationDate, e.CreationDate()),
handler.NewCol(SMTPConfigColumnChangeDate, e.CreationDate()),
handler.NewCol(SMTPConfigColumnResourceOwner, e.Aggregate().ResourceOwner),
handler.NewCol(SMTPConfigColumnInstanceID, e.Aggregate().InstanceID),
handler.NewCol(SMTPConfigColumnSequence, e.Sequence()),
handler.NewCol(SMTPConfigColumnID, id),
handler.NewCol(SMTPConfigColumnTLS, e.TLS),
handler.NewCol(SMTPConfigColumnSenderAddress, e.SenderAddress),
handler.NewCol(SMTPConfigColumnSenderName, e.SenderName),
handler.NewCol(SMTPConfigColumnReplyToAddress, e.ReplyToAddress),
handler.NewCol(SMTPConfigColumnSMTPHost, e.Host),
handler.NewCol(SMTPConfigColumnSMTPUser, e.User),
handler.NewCol(SMTPConfigColumnSMTPPassword, e.Password),
handler.NewCol(SMTPConfigColumnState, state),
handler.NewCol(SMTPConfigColumnDescription, description),
},
handler.AddCreateStatement(
[]handler.Column{
handler.NewCol(SMTPConfigColumnCreationDate, e.CreationDate()),
handler.NewCol(SMTPConfigColumnChangeDate, e.CreationDate()),
handler.NewCol(SMTPConfigColumnInstanceID, e.Aggregate().InstanceID),
handler.NewCol(SMTPConfigColumnResourceOwner, e.Aggregate().ResourceOwner),
handler.NewCol(SMTPConfigColumnAggregateID, e.Aggregate().ID),
handler.NewCol(SMTPConfigColumnID, id),
handler.NewCol(SMTPConfigColumnSequence, e.Sequence()),
handler.NewCol(SMTPConfigColumnState, state),
handler.NewCol(SMTPConfigColumnDescription, description),
},
),
handler.AddCreateStatement(
[]handler.Column{
handler.NewCol(SMTPConfigSMTPColumnInstanceID, e.Aggregate().InstanceID),
handler.NewCol(SMTPConfigSMTPColumnID, e.ID),
handler.NewCol(SMTPConfigSMTPColumnTLS, e.TLS),
handler.NewCol(SMTPConfigSMTPColumnSenderAddress, e.SenderAddress),
handler.NewCol(SMTPConfigSMTPColumnSenderName, e.SenderName),
handler.NewCol(SMTPConfigSMTPColumnReplyToAddress, e.ReplyToAddress),
handler.NewCol(SMTPConfigSMTPColumnHost, e.Host),
handler.NewCol(SMTPConfigSMTPColumnUser, e.User),
handler.NewCol(SMTPConfigSMTPColumnPassword, e.Password),
},
handler.WithTableSuffix(smtpConfigSMTPTableSuffix),
),
), nil
}
func (p *smtpConfigProjection) reduceSMTPConfigChanged(event eventstore.Event) (*handler.Statement, error) {
e, ok := event.(*instance.SMTPConfigChangedEvent)
if !ok {
return nil, zerrors.ThrowInvalidArgumentf(nil, "HANDL-wl0wd", "reduce.wrong.event.type %s", instance.SMTPConfigChangedEventType)
func (p *smtpConfigProjection) reduceSMTPConfigHTTPAdded(event eventstore.Event) (*handler.Statement, error) {
e, err := assertEvent[*instance.SMTPConfigHTTPAddedEvent](event)
if err != nil {
return nil, err
}
columns := make([]handler.Column, 0, 8)
columns = append(columns, handler.NewCol(SMTPConfigColumnChangeDate, e.CreationDate()),
handler.NewCol(SMTPConfigColumnSequence, e.Sequence()))
return handler.NewMultiStatement(
e,
handler.AddCreateStatement(
[]handler.Column{
handler.NewCol(SMTPConfigColumnCreationDate, e.CreationDate()),
handler.NewCol(SMTPConfigColumnChangeDate, e.CreationDate()),
handler.NewCol(SMTPConfigColumnInstanceID, e.Aggregate().InstanceID),
handler.NewCol(SMTPConfigColumnResourceOwner, e.Aggregate().ResourceOwner),
handler.NewCol(SMTPConfigColumnAggregateID, e.Aggregate().ID),
handler.NewCol(SMTPConfigColumnID, e.ID),
handler.NewCol(SMTPConfigColumnSequence, e.Sequence()),
handler.NewCol(SMTPConfigColumnState, domain.SMTPConfigStateInactive),
handler.NewCol(SMTPConfigColumnDescription, e.Description),
},
),
handler.AddCreateStatement(
[]handler.Column{
handler.NewCol(SMTPConfigSMTPColumnInstanceID, e.Aggregate().InstanceID),
handler.NewCol(SMTPConfigSMTPColumnID, e.ID),
handler.NewCol(SMTPConfigHTTPColumnEndpoint, e.Endpoint),
},
handler.WithTableSuffix(smtpConfigHTTPTableSuffix),
),
), nil
}
// Deal with old and unique SMTP settings (empty ID)
id := e.ID
if e.ID == "" {
id = e.Aggregate().ResourceOwner
func (p *smtpConfigProjection) reduceSMTPConfigHTTPChanged(event eventstore.Event) (*handler.Statement, error) {
e, err := assertEvent[*instance.SMTPConfigHTTPChangedEvent](event)
if err != nil {
return nil, err
}
if e.TLS != nil {
columns = append(columns, handler.NewCol(SMTPConfigColumnTLS, *e.TLS))
}
if e.FromAddress != nil {
columns = append(columns, handler.NewCol(SMTPConfigColumnSenderAddress, *e.FromAddress))
}
if e.FromName != nil {
columns = append(columns, handler.NewCol(SMTPConfigColumnSenderName, *e.FromName))
}
if e.ReplyToAddress != nil {
columns = append(columns, handler.NewCol(SMTPConfigColumnReplyToAddress, *e.ReplyToAddress))
}
if e.Host != nil {
columns = append(columns, handler.NewCol(SMTPConfigColumnSMTPHost, *e.Host))
}
if e.User != nil {
columns = append(columns, handler.NewCol(SMTPConfigColumnSMTPUser, *e.User))
}
if e.Password != nil {
columns = append(columns, handler.NewCol(SMTPConfigColumnSMTPPassword, *e.Password))
stmts := make([]func(eventstore.Event) handler.Exec, 0, 3)
columns := []handler.Column{
handler.NewCol(SMTPConfigColumnChangeDate, e.CreationDate()),
handler.NewCol(SMTPConfigColumnSequence, e.Sequence()),
}
if e.Description != nil {
columns = append(columns, handler.NewCol(SMTPConfigColumnDescription, *e.Description))
}
return handler.NewUpdateStatement(
e,
columns,
[]handler.Condition{
handler.NewCond(SMTPConfigColumnID, id),
handler.NewCond(SMTPConfigColumnResourceOwner, e.Aggregate().ResourceOwner),
handler.NewCond(SMTPConfigColumnInstanceID, e.Aggregate().InstanceID),
},
), nil
if len(columns) > 0 {
stmts = append(stmts, handler.AddUpdateStatement(
columns,
[]handler.Condition{
handler.NewCond(SMTPConfigColumnID, e.ID),
handler.NewCond(SMTPConfigColumnInstanceID, e.Aggregate().InstanceID),
},
))
}
smtpColumns := make([]handler.Column, 0, 1)
if e.Endpoint != nil {
smtpColumns = append(smtpColumns, handler.NewCol(SMTPConfigHTTPColumnEndpoint, *e.Endpoint))
}
if len(smtpColumns) > 0 {
stmts = append(stmts, handler.AddUpdateStatement(
smtpColumns,
[]handler.Condition{
handler.NewCond(SMTPConfigHTTPColumnID, e.ID),
handler.NewCond(SMTPConfigHTTPColumnInstanceID, e.Aggregate().InstanceID),
},
handler.WithTableSuffix(smtpConfigHTTPTableSuffix),
))
}
return handler.NewMultiStatement(e, stmts...), nil
}
func (p *smtpConfigProjection) reduceSMTPConfigPasswordChanged(event eventstore.Event) (*handler.Statement, error) {
e, ok := event.(*instance.SMTPConfigPasswordChangedEvent)
if !ok {
return nil, zerrors.ThrowInvalidArgumentf(nil, "HANDL-fk02f", "reduce.wrong.event.type %s", instance.SMTPConfigChangedEventType)
func (p *smtpConfigProjection) reduceSMTPConfigChanged(event eventstore.Event) (*handler.Statement, error) {
e, err := assertEvent[*instance.SMTPConfigChangedEvent](event)
if err != nil {
return nil, err
}
// Deal with old and unique SMTP settings (empty ID)
@@ -203,25 +274,101 @@ func (p *smtpConfigProjection) reduceSMTPConfigPasswordChanged(event eventstore.
id = e.Aggregate().ResourceOwner
}
return handler.NewUpdateStatement(
stmts := make([]func(eventstore.Event) handler.Exec, 0, 3)
columns := []handler.Column{
handler.NewCol(SMTPConfigColumnChangeDate, e.CreationDate()),
handler.NewCol(SMTPConfigColumnSequence, e.Sequence()),
}
if e.Description != nil {
columns = append(columns, handler.NewCol(SMTPConfigColumnDescription, *e.Description))
}
if len(columns) > 0 {
stmts = append(stmts, handler.AddUpdateStatement(
columns,
[]handler.Condition{
handler.NewCond(SMTPConfigColumnID, id),
handler.NewCond(SMTPConfigColumnInstanceID, e.Aggregate().InstanceID),
},
))
}
httpColumns := make([]handler.Column, 0, 7)
if e.TLS != nil {
httpColumns = append(httpColumns, handler.NewCol(SMTPConfigSMTPColumnTLS, *e.TLS))
}
if e.FromAddress != nil {
httpColumns = append(httpColumns, handler.NewCol(SMTPConfigSMTPColumnSenderAddress, *e.FromAddress))
}
if e.FromName != nil {
httpColumns = append(httpColumns, handler.NewCol(SMTPConfigSMTPColumnSenderName, *e.FromName))
}
if e.ReplyToAddress != nil {
httpColumns = append(httpColumns, handler.NewCol(SMTPConfigSMTPColumnReplyToAddress, *e.ReplyToAddress))
}
if e.Host != nil {
httpColumns = append(httpColumns, handler.NewCol(SMTPConfigSMTPColumnHost, *e.Host))
}
if e.User != nil {
httpColumns = append(httpColumns, handler.NewCol(SMTPConfigSMTPColumnUser, *e.User))
}
if e.Password != nil {
httpColumns = append(httpColumns, handler.NewCol(SMTPConfigSMTPColumnPassword, *e.Password))
}
if len(httpColumns) > 0 {
stmts = append(stmts, handler.AddUpdateStatement(
httpColumns,
[]handler.Condition{
handler.NewCond(SMTPConfigSMTPColumnID, e.ID),
handler.NewCond(SMTPConfigSMTPColumnInstanceID, e.Aggregate().InstanceID),
},
handler.WithTableSuffix(smtpConfigSMTPTableSuffix),
))
}
return handler.NewMultiStatement(e, stmts...), nil
}
func (p *smtpConfigProjection) reduceSMTPConfigPasswordChanged(event eventstore.Event) (*handler.Statement, error) {
e, err := assertEvent[*instance.SMTPConfigPasswordChangedEvent](event)
if err != nil {
return nil, err
}
// Deal with old and unique SMTP settings (empty ID)
id := e.ID
if e.ID == "" {
id = e.Aggregate().ResourceOwner
}
return handler.NewMultiStatement(
e,
[]handler.Column{
handler.NewCol(SMTPConfigColumnChangeDate, e.CreationDate()),
handler.NewCol(SMTPConfigColumnSequence, e.Sequence()),
handler.NewCol(SMTPConfigColumnSMTPPassword, e.Password),
},
[]handler.Condition{
handler.NewCond(SMTPConfigColumnID, id),
handler.NewCond(SMTPConfigColumnResourceOwner, e.Aggregate().ResourceOwner),
handler.NewCond(SMTPConfigColumnInstanceID, e.Aggregate().InstanceID),
},
handler.AddUpdateStatement(
[]handler.Column{
handler.NewCol(SMTPConfigSMTPColumnPassword, e.Password),
},
[]handler.Condition{
handler.NewCond(SMTPConfigColumnID, id),
handler.NewCond(SMTPConfigColumnInstanceID, e.Aggregate().InstanceID),
},
handler.WithTableSuffix(smtpConfigSMTPTableSuffix),
),
handler.AddUpdateStatement(
[]handler.Column{
handler.NewCol(SMTPConfigColumnChangeDate, e.CreationDate()),
handler.NewCol(SMTPConfigColumnSequence, e.Sequence()),
},
[]handler.Condition{
handler.NewCond(SMTPConfigColumnID, id),
handler.NewCond(SMTPConfigColumnInstanceID, e.Aggregate().InstanceID),
},
),
), nil
}
func (p *smtpConfigProjection) reduceSMTPConfigActivated(event eventstore.Event) (*handler.Statement, error) {
e, ok := event.(*instance.SMTPConfigActivatedEvent)
if !ok {
return nil, zerrors.ThrowInvalidArgumentf(nil, "HANDL-fq92r", "reduce.wrong.event.type %s", instance.SMTPConfigActivatedEventType)
e, err := assertEvent[*instance.SMTPConfigActivatedEvent](event)
if err != nil {
return nil, err
}
// Deal with old and unique SMTP settings (empty ID)
@@ -230,25 +377,38 @@ func (p *smtpConfigProjection) reduceSMTPConfigActivated(event eventstore.Event)
id = e.Aggregate().ResourceOwner
}
return handler.NewUpdateStatement(
return handler.NewMultiStatement(
e,
[]handler.Column{
handler.NewCol(SMTPConfigColumnChangeDate, e.CreationDate()),
handler.NewCol(SMTPConfigColumnSequence, e.Sequence()),
handler.NewCol(SMTPConfigColumnState, domain.SMTPConfigStateActive),
},
[]handler.Condition{
handler.NewCond(SMTPConfigColumnID, id),
handler.NewCond(SMTPConfigColumnResourceOwner, e.Aggregate().ResourceOwner),
handler.NewCond(SMTPConfigColumnInstanceID, e.Aggregate().InstanceID),
},
handler.AddUpdateStatement(
[]handler.Column{
handler.NewCol(SMTPConfigColumnChangeDate, e.CreationDate()),
handler.NewCol(SMTPConfigColumnSequence, e.Sequence()),
handler.NewCol(SMTPConfigColumnState, domain.SMTPConfigStateInactive),
},
[]handler.Condition{
handler.Not(handler.NewCond(SMTPConfigColumnID, e.ID)),
handler.NewCond(SMTPConfigColumnState, domain.SMTPConfigStateActive),
handler.NewCond(SMTPConfigColumnInstanceID, e.Aggregate().InstanceID),
},
),
handler.AddUpdateStatement(
[]handler.Column{
handler.NewCol(SMTPConfigColumnChangeDate, e.CreationDate()),
handler.NewCol(SMTPConfigColumnSequence, e.Sequence()),
handler.NewCol(SMTPConfigColumnState, domain.SMTPConfigStateActive),
},
[]handler.Condition{
handler.NewCond(SMTPConfigColumnID, id),
handler.NewCond(SMTPConfigColumnInstanceID, e.Aggregate().InstanceID),
},
),
), nil
}
func (p *smtpConfigProjection) reduceSMTPConfigDeactivated(event eventstore.Event) (*handler.Statement, error) {
e, ok := event.(*instance.SMTPConfigDeactivatedEvent)
if !ok {
return nil, zerrors.ThrowInvalidArgumentf(nil, "HANDL-hv89j", "reduce.wrong.event.type %s", instance.SMTPConfigDeactivatedEventType)
e, err := assertEvent[*instance.SMTPConfigDeactivatedEvent](event)
if err != nil {
return nil, err
}
// Deal with old and unique SMTP settings (empty ID)
@@ -266,7 +426,6 @@ func (p *smtpConfigProjection) reduceSMTPConfigDeactivated(event eventstore.Even
},
[]handler.Condition{
handler.NewCond(SMTPConfigColumnID, id),
handler.NewCond(SMTPConfigColumnResourceOwner, e.Aggregate().ResourceOwner),
handler.NewCond(SMTPConfigColumnInstanceID, e.Aggregate().InstanceID),
},
), nil
@@ -288,7 +447,6 @@ func (p *smtpConfigProjection) reduceSMTPConfigRemoved(event eventstore.Event) (
e,
[]handler.Condition{
handler.NewCond(SMTPConfigColumnID, id),
handler.NewCond(SMTPConfigColumnResourceOwner, e.Aggregate().ResourceOwner),
handler.NewCond(SMTPConfigColumnInstanceID, e.Aggregate().InstanceID),
},
), nil

View File

@@ -28,19 +28,20 @@ func TestSMTPConfigProjection_reduces(t *testing.T) {
instance.SMTPConfigChangedEventType,
instance.AggregateType,
[]byte(`{
"instance_id": "instance-id",
"resource_owner": "ro-id",
"aggregate_id": "agg-id",
"id": "config-id",
"description": "test",
"tls": true,
"senderAddress": "sender",
"senderName": "name",
"replyToAddress": "reply-to",
"host": "host",
"user": "user",
"id": "44444",
"resource_owner": "ro-id",
"instance_id": "instance-id"
"user": "user"
}`,
),
), instance.SMTPConfigChangedEventMapper),
), eventstore.GenericEventMapper[instance.SMTPConfigChangedEvent]),
},
reduce: (&smtpConfigProjection{}).reduceSMTPConfigChanged,
want: wantReduce{
@@ -49,19 +50,233 @@ func TestSMTPConfigProjection_reduces(t *testing.T) {
executer: &testExecuter{
executions: []execution{
{
expectedStmt: "UPDATE projections.smtp_configs2 SET (change_date, sequence, tls, sender_address, sender_name, reply_to_address, host, username, description) = ($1, $2, $3, $4, $5, $6, $7, $8, $9) WHERE (id = $10) AND (resource_owner = $11) AND (instance_id = $12)",
expectedStmt: "UPDATE projections.smtp_configs3 SET (change_date, sequence, description) = ($1, $2, $3) WHERE (id = $4) AND (instance_id = $5)",
expectedArgs: []interface{}{
anyArg{},
uint64(15),
"test",
"config-id",
"instance-id",
},
},
{
expectedStmt: "UPDATE projections.smtp_configs3_smtp SET (tls, sender_address, sender_name, reply_to_address, host, username) = ($1, $2, $3, $4, $5, $6) WHERE (id = $7) AND (instance_id = $8)",
expectedArgs: []interface{}{
true,
"sender",
"name",
"reply-to",
"host",
"user",
"config-id",
"instance-id",
},
},
},
},
},
},
{
name: "reduceSMTPConfigChanged, description",
args: args{
event: getEvent(
testEvent(
instance.SMTPConfigChangedEventType,
instance.AggregateType,
[]byte(`{
"instance_id": "instance-id",
"resource_owner": "ro-id",
"aggregate_id": "agg-id",
"id": "config-id",
"description": "test"
}`,
),
), eventstore.GenericEventMapper[instance.SMTPConfigChangedEvent]),
},
reduce: (&smtpConfigProjection{}).reduceSMTPConfigChanged,
want: wantReduce{
aggregateType: eventstore.AggregateType("instance"),
sequence: 15,
executer: &testExecuter{
executions: []execution{
{
expectedStmt: "UPDATE projections.smtp_configs3 SET (change_date, sequence, description) = ($1, $2, $3) WHERE (id = $4) AND (instance_id = $5)",
expectedArgs: []interface{}{
anyArg{},
uint64(15),
"test",
"44444",
"ro-id",
"config-id",
"instance-id",
},
},
},
},
},
},
{
name: "reduceSMTPConfigChanged, senderAddress",
args: args{
event: getEvent(
testEvent(
instance.SMTPConfigChangedEventType,
instance.AggregateType,
[]byte(`{
"instance_id": "instance-id",
"resource_owner": "ro-id",
"aggregate_id": "agg-id",
"id": "config-id",
"senderAddress": "sender"
}`,
),
), eventstore.GenericEventMapper[instance.SMTPConfigChangedEvent]),
},
reduce: (&smtpConfigProjection{}).reduceSMTPConfigChanged,
want: wantReduce{
aggregateType: eventstore.AggregateType("instance"),
sequence: 15,
executer: &testExecuter{
executions: []execution{
{
expectedStmt: "UPDATE projections.smtp_configs3 SET (change_date, sequence) = ($1, $2) WHERE (id = $3) AND (instance_id = $4)",
expectedArgs: []interface{}{
anyArg{},
uint64(15),
"config-id",
"instance-id",
},
},
{
expectedStmt: "UPDATE projections.smtp_configs3_smtp SET sender_address = $1 WHERE (id = $2) AND (instance_id = $3)",
expectedArgs: []interface{}{
"sender",
"config-id",
"instance-id",
},
},
},
},
},
},
{
name: "reduceSMTPConfigHTTPChanged",
args: args{
event: getEvent(
testEvent(
instance.SMTPConfigHTTPChangedEventType,
instance.AggregateType,
[]byte(`{
"instance_id": "instance-id",
"resource_owner": "ro-id",
"aggregate_id": "agg-id",
"id": "config-id",
"description": "test",
"endpoint": "endpoint"
}`,
),
), eventstore.GenericEventMapper[instance.SMTPConfigHTTPChangedEvent]),
},
reduce: (&smtpConfigProjection{}).reduceSMTPConfigHTTPChanged,
want: wantReduce{
aggregateType: eventstore.AggregateType("instance"),
sequence: 15,
executer: &testExecuter{
executions: []execution{
{
expectedStmt: "UPDATE projections.smtp_configs3 SET (change_date, sequence, description) = ($1, $2, $3) WHERE (id = $4) AND (instance_id = $5)",
expectedArgs: []interface{}{
anyArg{},
uint64(15),
"test",
"config-id",
"instance-id",
},
},
{
expectedStmt: "UPDATE projections.smtp_configs3_http SET endpoint = $1 WHERE (id = $2) AND (instance_id = $3)",
expectedArgs: []interface{}{
"endpoint",
"config-id",
"instance-id",
},
},
},
},
},
},
{
name: "reduceSMTPConfigHTTPChanged, description",
args: args{
event: getEvent(
testEvent(
instance.SMTPConfigHTTPChangedEventType,
instance.AggregateType,
[]byte(`{
"instance_id": "instance-id",
"resource_owner": "ro-id",
"aggregate_id": "agg-id",
"id": "config-id",
"description": "test"
}`,
),
), eventstore.GenericEventMapper[instance.SMTPConfigHTTPChangedEvent]),
},
reduce: (&smtpConfigProjection{}).reduceSMTPConfigHTTPChanged,
want: wantReduce{
aggregateType: eventstore.AggregateType("instance"),
sequence: 15,
executer: &testExecuter{
executions: []execution{
{
expectedStmt: "UPDATE projections.smtp_configs3 SET (change_date, sequence, description) = ($1, $2, $3) WHERE (id = $4) AND (instance_id = $5)",
expectedArgs: []interface{}{
anyArg{},
uint64(15),
"test",
"config-id",
"instance-id",
},
},
},
},
},
},
{
name: "reduceSMTPConfigHTTPChanged, endpoint",
args: args{
event: getEvent(
testEvent(
instance.SMTPConfigHTTPChangedEventType,
instance.AggregateType,
[]byte(`{
"instance_id": "instance-id",
"resource_owner": "ro-id",
"aggregate_id": "agg-id",
"id": "config-id",
"endpoint": "endpoint"
}`,
),
), eventstore.GenericEventMapper[instance.SMTPConfigHTTPChangedEvent]),
},
reduce: (&smtpConfigProjection{}).reduceSMTPConfigHTTPChanged,
want: wantReduce{
aggregateType: eventstore.AggregateType("instance"),
sequence: 15,
executer: &testExecuter{
executions: []execution{
{
expectedStmt: "UPDATE projections.smtp_configs3 SET (change_date, sequence) = ($1, $2) WHERE (id = $3) AND (instance_id = $4)",
expectedArgs: []interface{}{
anyArg{},
uint64(15),
"config-id",
"instance-id",
},
},
{
expectedStmt: "UPDATE projections.smtp_configs3_http SET endpoint = $1 WHERE (id = $2) AND (instance_id = $3)",
expectedArgs: []interface{}{
"endpoint",
"config-id",
"instance-id",
},
},
@@ -77,9 +292,12 @@ func TestSMTPConfigProjection_reduces(t *testing.T) {
instance.SMTPConfigAddedEventType,
instance.AggregateType,
[]byte(`{
"tls": true,
"id": "id",
"instance_id": "instance-id",
"resource_owner": "ro-id",
"aggregate_id": "agg-id",
"id": "config-id",
"description": "test",
"tls": true,
"senderAddress": "sender",
"senderName": "name",
"replyToAddress": "reply-to",
@@ -91,7 +309,7 @@ func TestSMTPConfigProjection_reduces(t *testing.T) {
"keyId": "key-id"
}
}`),
), instance.SMTPConfigAddedEventMapper),
), eventstore.GenericEventMapper[instance.SMTPConfigAddedEvent]),
},
reduce: (&smtpConfigProjection{}).reduceSMTPConfigAdded,
want: wantReduce{
@@ -100,14 +318,24 @@ func TestSMTPConfigProjection_reduces(t *testing.T) {
executer: &testExecuter{
executions: []execution{
{
expectedStmt: "INSERT INTO projections.smtp_configs2 (creation_date, change_date, resource_owner, instance_id, sequence, id, tls, sender_address, sender_name, reply_to_address, host, username, password, state, description) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14, $15)",
expectedStmt: "INSERT INTO projections.smtp_configs3 (creation_date, change_date, instance_id, resource_owner, aggregate_id, id, sequence, state, description) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9)",
expectedArgs: []interface{}{
anyArg{},
anyArg{},
"ro-id",
"instance-id",
"ro-id",
"agg-id",
"config-id",
uint64(15),
"id",
domain.SMTPConfigStateInactive,
"test",
},
},
{
expectedStmt: "INSERT INTO projections.smtp_configs3_smtp (instance_id, id, tls, sender_address, sender_name, reply_to_address, host, username, password) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9)",
expectedArgs: []interface{}{
"instance-id",
"config-id",
true,
"sender",
"name",
@@ -115,10 +343,58 @@ func TestSMTPConfigProjection_reduces(t *testing.T) {
"host",
"user",
anyArg{},
domain.SMTPConfigState(3),
},
},
},
},
},
},
{
name: "reduceSMTPConfigHTTPAdded",
args: args{
event: getEvent(
testEvent(
instance.SMTPConfigHTTPAddedEventType,
instance.AggregateType,
[]byte(`{
"instance_id": "instance-id",
"resource_owner": "ro-id",
"aggregate_id": "agg-id",
"id": "config-id",
"description": "test",
"senderAddress": "sender",
"endpoint": "endpoint"
}`),
), eventstore.GenericEventMapper[instance.SMTPConfigHTTPAddedEvent]),
},
reduce: (&smtpConfigProjection{}).reduceSMTPConfigHTTPAdded,
want: wantReduce{
aggregateType: eventstore.AggregateType("instance"),
sequence: 15,
executer: &testExecuter{
executions: []execution{
{
expectedStmt: "INSERT INTO projections.smtp_configs3 (creation_date, change_date, instance_id, resource_owner, aggregate_id, id, sequence, state, description) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9)",
expectedArgs: []interface{}{
anyArg{},
anyArg{},
"instance-id",
"ro-id",
"agg-id",
"config-id",
uint64(15),
domain.SMTPConfigStateInactive,
"test",
},
},
{
expectedStmt: "INSERT INTO projections.smtp_configs3_http (instance_id, id, endpoint) VALUES ($1, $2, $3)",
expectedArgs: []interface{}{
"instance-id",
"config-id",
"endpoint",
},
},
},
},
},
@@ -130,9 +406,12 @@ func TestSMTPConfigProjection_reduces(t *testing.T) {
instance.SMTPConfigActivatedEventType,
instance.AggregateType,
[]byte(`{
"id": "config-id"
"instance_id": "instance-id",
"resource_owner": "ro-id",
"aggregate_id": "agg-id",
"id": "config-id"
}`),
), instance.SMTPConfigActivatedEventMapper),
), eventstore.GenericEventMapper[instance.SMTPConfigActivatedEvent]),
},
reduce: (&smtpConfigProjection{}).reduceSMTPConfigActivated,
want: wantReduce{
@@ -141,13 +420,23 @@ func TestSMTPConfigProjection_reduces(t *testing.T) {
executer: &testExecuter{
executions: []execution{
{
expectedStmt: "UPDATE projections.smtp_configs2 SET (change_date, sequence, state) = ($1, $2, $3) WHERE (id = $4) AND (resource_owner = $5) AND (instance_id = $6)",
expectedStmt: "UPDATE projections.smtp_configs3 SET (change_date, sequence, state) = ($1, $2, $3) WHERE (NOT (id = $4)) AND (state = $5) AND (instance_id = $6)",
expectedArgs: []interface{}{
anyArg{},
uint64(15),
domain.SMTPConfigStateInactive,
"config-id",
domain.SMTPConfigStateActive,
"instance-id",
},
},
{
expectedStmt: "UPDATE projections.smtp_configs3 SET (change_date, sequence, state) = ($1, $2, $3) WHERE (id = $4) AND (instance_id = $5)",
expectedArgs: []interface{}{
anyArg{},
uint64(15),
domain.SMTPConfigStateActive,
"config-id",
"ro-id",
"instance-id",
},
},
@@ -162,9 +451,12 @@ func TestSMTPConfigProjection_reduces(t *testing.T) {
instance.SMTPConfigDeactivatedEventType,
instance.AggregateType,
[]byte(`{
"id": "config-id"
"instance_id": "instance-id",
"resource_owner": "ro-id",
"aggregate_id": "agg-id",
"id": "config-id"
}`),
), instance.SMTPConfigDeactivatedEventMapper),
), eventstore.GenericEventMapper[instance.SMTPConfigDeactivatedEvent]),
},
reduce: (&smtpConfigProjection{}).reduceSMTPConfigDeactivated,
want: wantReduce{
@@ -173,13 +465,12 @@ func TestSMTPConfigProjection_reduces(t *testing.T) {
executer: &testExecuter{
executions: []execution{
{
expectedStmt: "UPDATE projections.smtp_configs2 SET (change_date, sequence, state) = ($1, $2, $3) WHERE (id = $4) AND (resource_owner = $5) AND (instance_id = $6)",
expectedStmt: "UPDATE projections.smtp_configs3 SET (change_date, sequence, state) = ($1, $2, $3) WHERE (id = $4) AND (instance_id = $5)",
expectedArgs: []interface{}{
anyArg{},
uint64(15),
domain.SMTPConfigStateInactive,
"config-id",
"ro-id",
"instance-id",
},
},
@@ -195,14 +486,17 @@ func TestSMTPConfigProjection_reduces(t *testing.T) {
instance.SMTPConfigPasswordChangedEventType,
instance.AggregateType,
[]byte(`{
"id": "config-id",
"instance_id": "instance-id",
"resource_owner": "ro-id",
"aggregate_id": "agg-id",
"id": "config-id",
"password": {
"cryptoType": 0,
"algorithm": "RSA-265",
"keyId": "key-id"
}
}`),
), instance.SMTPConfigPasswordChangedEventMapper),
), eventstore.GenericEventMapper[instance.SMTPConfigPasswordChangedEvent]),
},
reduce: (&smtpConfigProjection{}).reduceSMTPConfigPasswordChanged,
want: wantReduce{
@@ -211,13 +505,19 @@ func TestSMTPConfigProjection_reduces(t *testing.T) {
executer: &testExecuter{
executions: []execution{
{
expectedStmt: "UPDATE projections.smtp_configs2 SET (change_date, sequence, password) = ($1, $2, $3) WHERE (id = $4) AND (resource_owner = $5) AND (instance_id = $6)",
expectedStmt: "UPDATE projections.smtp_configs3_smtp SET password = $1 WHERE (id = $2) AND (instance_id = $3)",
expectedArgs: []interface{}{
anyArg{},
"config-id",
"instance-id",
},
},
{
expectedStmt: "UPDATE projections.smtp_configs3 SET (change_date, sequence) = ($1, $2) WHERE (id = $3) AND (instance_id = $4)",
expectedArgs: []interface{}{
anyArg{},
uint64(15),
anyArg{},
"config-id",
"ro-id",
"instance-id",
},
},
@@ -231,8 +531,13 @@ func TestSMTPConfigProjection_reduces(t *testing.T) {
event: getEvent(testEvent(
instance.SMTPConfigRemovedEventType,
instance.AggregateType,
[]byte(`{ "id": "config-id"}`),
), instance.SMTPConfigRemovedEventMapper),
[]byte(`{
"instance_id": "instance-id",
"resource_owner": "ro-id",
"aggregate_id": "agg-id",
"id": "config-id"
}`),
), eventstore.GenericEventMapper[instance.SMTPConfigRemovedEvent]),
},
reduce: (&smtpConfigProjection{}).reduceSMTPConfigRemoved,
want: wantReduce{
@@ -241,10 +546,9 @@ func TestSMTPConfigProjection_reduces(t *testing.T) {
executer: &testExecuter{
executions: []execution{
{
expectedStmt: "DELETE FROM projections.smtp_configs2 WHERE (id = $1) AND (resource_owner = $2) AND (instance_id = $3)",
expectedStmt: "DELETE FROM projections.smtp_configs3 WHERE (id = $1) AND (instance_id = $2)",
expectedArgs: []interface{}{
"config-id",
"ro-id",
"instance-id",
},
},
@@ -269,7 +573,7 @@ func TestSMTPConfigProjection_reduces(t *testing.T) {
executer: &testExecuter{
executions: []execution{
{
expectedStmt: "DELETE FROM projections.smtp_configs2 WHERE (instance_id = $1)",
expectedStmt: "DELETE FROM projections.smtp_configs3 WHERE (instance_id = $1)",
expectedArgs: []interface{}{
"agg-id",
},

View File

@@ -256,7 +256,7 @@ func prepareSMSConfigQuery(ctx context.Context, db prepareDatabase) (sq.SelectBu
&twilioConfig.token,
&twilioConfig.senderNumber,
&httpConfig.smsID,
&httpConfig.id,
&httpConfig.endpoint,
)
@@ -268,7 +268,7 @@ func prepareSMSConfigQuery(ctx context.Context, db prepareDatabase) (sq.SelectBu
}
twilioConfig.set(config)
httpConfig.set(config)
httpConfig.setSMS(config)
return config, nil
}
@@ -322,7 +322,7 @@ func prepareSMSConfigsQuery(ctx context.Context, db prepareDatabase) (sq.SelectB
&twilioConfig.token,
&twilioConfig.senderNumber,
&httpConfig.smsID,
&httpConfig.id,
&httpConfig.endpoint,
&configs.Count,
@@ -333,7 +333,7 @@ func prepareSMSConfigsQuery(ctx context.Context, db prepareDatabase) (sq.SelectB
}
twilioConfig.set(config)
httpConfig.set(config)
httpConfig.setSMS(config)
configs.Configs = append(configs.Configs, config)
}
@@ -361,12 +361,12 @@ func (c sqlTwilioConfig) set(smsConfig *SMSConfig) {
}
type sqlHTTPConfig struct {
smsID sql.NullString
id sql.NullString
endpoint sql.NullString
}
func (c sqlHTTPConfig) set(smsConfig *SMSConfig) {
if !c.smsID.Valid {
func (c sqlHTTPConfig) setSMS(smsConfig *SMSConfig) {
if !c.id.Valid {
return
}
smsConfig.HTTPConfig = &HTTP{

View File

@@ -52,34 +52,6 @@ var (
name: projection.SMTPConfigColumnSequence,
table: smtpConfigsTable,
}
SMTPConfigColumnTLS = Column{
name: projection.SMTPConfigColumnTLS,
table: smtpConfigsTable,
}
SMTPConfigColumnSenderAddress = Column{
name: projection.SMTPConfigColumnSenderAddress,
table: smtpConfigsTable,
}
SMTPConfigColumnSenderName = Column{
name: projection.SMTPConfigColumnSenderName,
table: smtpConfigsTable,
}
SMTPConfigColumnReplyToAddress = Column{
name: projection.SMTPConfigColumnReplyToAddress,
table: smtpConfigsTable,
}
SMTPConfigColumnSMTPHost = Column{
name: projection.SMTPConfigColumnSMTPHost,
table: smtpConfigsTable,
}
SMTPConfigColumnSMTPUser = Column{
name: projection.SMTPConfigColumnSMTPUser,
table: smtpConfigsTable,
}
SMTPConfigColumnSMTPPassword = Column{
name: projection.SMTPConfigColumnSMTPPassword,
table: smtpConfigsTable,
}
SMTPConfigColumnID = Column{
name: projection.SMTPConfigColumnID,
table: smtpConfigsTable,
@@ -92,13 +64,82 @@ var (
name: projection.SMTPConfigColumnDescription,
table: smtpConfigsTable,
}
smtpConfigsSMTPTable = table{
name: projection.SMTPConfigTable,
instanceIDCol: projection.SMTPConfigColumnInstanceID,
}
SMTPConfigSMTPColumnInstanceID = Column{
name: projection.SMTPConfigColumnInstanceID,
table: smtpConfigsSMTPTable,
}
SMTPConfigSMTPColumnID = Column{
name: projection.SMTPConfigColumnID,
table: smtpConfigsSMTPTable,
}
SMTPConfigSMTPColumnTLS = Column{
name: projection.SMTPConfigSMTPColumnTLS,
table: smtpConfigsSMTPTable,
}
SMTPConfigSMTPColumnSenderAddress = Column{
name: projection.SMTPConfigSMTPColumnSenderAddress,
table: smtpConfigsSMTPTable,
}
SMTPConfigSMTPColumnSenderName = Column{
name: projection.SMTPConfigSMTPColumnSenderName,
table: smtpConfigsSMTPTable,
}
SMTPConfigSMTPColumnReplyToAddress = Column{
name: projection.SMTPConfigSMTPColumnReplyToAddress,
table: smtpConfigsSMTPTable,
}
SMTPConfigSMTPColumnHost = Column{
name: projection.SMTPConfigSMTPColumnHost,
table: smtpConfigsSMTPTable,
}
SMTPConfigSMTPColumnUser = Column{
name: projection.SMTPConfigSMTPColumnUser,
table: smtpConfigsSMTPTable,
}
SMTPConfigSMTPColumnPassword = Column{
name: projection.SMTPConfigSMTPColumnPassword,
table: smtpConfigsSMTPTable,
}
smtpConfigsHTTPTable = table{
name: projection.SMTPConfigHTTPTable,
instanceIDCol: projection.SMTPConfigHTTPColumnInstanceID,
}
SMTPConfigHTTPColumnInstanceID = Column{
name: projection.SMTPConfigHTTPColumnInstanceID,
table: smtpConfigsHTTPTable,
}
SMTPConfigHTTPColumnID = Column{
name: projection.SMTPConfigHTTPColumnID,
table: smtpConfigsHTTPTable,
}
SMTPConfigHTTPColumnEndpoint = Column{
name: projection.SMTPConfigHTTPColumnEndpoint,
table: smtpConfigsHTTPTable,
}
)
type SMTPConfig struct {
CreationDate time.Time
ChangeDate time.Time
ResourceOwner string
Sequence uint64
CreationDate time.Time
ChangeDate time.Time
ResourceOwner string
AggregateID string
ID string
Sequence uint64
Description string
SMTPConfig *SMTP
HTTPConfig *HTTP
State domain.SMTPConfigState
}
type SMTP struct {
TLS bool
SenderAddress string
SenderName string
@@ -106,9 +147,6 @@ type SMTPConfig struct {
Host string
User string
Password *crypto.CryptoValue
ID string
State domain.SMTPConfigState
Description string
}
func (q *Queries) SMTPConfigActive(ctx context.Context, resourceOwner string) (config *SMTPConfig, err error) {
@@ -132,15 +170,14 @@ func (q *Queries) SMTPConfigActive(ctx context.Context, resourceOwner string) (c
return config, err
}
func (q *Queries) SMTPConfigByID(ctx context.Context, instanceID, resourceOwner, id string) (config *SMTPConfig, err error) {
func (q *Queries) SMTPConfigByID(ctx context.Context, instanceID, id string) (config *SMTPConfig, err error) {
ctx, span := tracing.NewSpan(ctx)
defer func() { span.EndWithError(err) }()
stmt, scan := prepareSMTPConfigQuery(ctx, q.client)
query, args, err := stmt.Where(sq.Eq{
SMTPConfigColumnResourceOwner.identifier(): resourceOwner,
SMTPConfigColumnInstanceID.identifier(): instanceID,
SMTPConfigColumnID.identifier(): id,
SMTPConfigColumnInstanceID.identifier(): instanceID,
SMTPConfigColumnID.identifier(): id,
}).ToSql()
if err != nil {
return nil, zerrors.ThrowInternal(err, "QUERY-8f8gw", "Errors.Query.SQLStatement")
@@ -161,35 +198,49 @@ func prepareSMTPConfigQuery(ctx context.Context, db prepareDatabase) (sq.SelectB
SMTPConfigColumnChangeDate.identifier(),
SMTPConfigColumnResourceOwner.identifier(),
SMTPConfigColumnSequence.identifier(),
SMTPConfigColumnTLS.identifier(),
SMTPConfigColumnSenderAddress.identifier(),
SMTPConfigColumnSenderName.identifier(),
SMTPConfigColumnReplyToAddress.identifier(),
SMTPConfigColumnSMTPHost.identifier(),
SMTPConfigColumnSMTPUser.identifier(),
SMTPConfigColumnSMTPPassword.identifier(),
SMTPConfigColumnID.identifier(),
SMTPConfigColumnState.identifier(),
SMTPConfigColumnDescription.identifier()).
From(smtpConfigsTable.identifier() + db.Timetravel(call.Took(ctx))).
SMTPConfigColumnDescription.identifier(),
SMTPConfigSMTPColumnID.identifier(),
SMTPConfigSMTPColumnTLS.identifier(),
SMTPConfigSMTPColumnSenderAddress.identifier(),
SMTPConfigSMTPColumnSenderName.identifier(),
SMTPConfigSMTPColumnReplyToAddress.identifier(),
SMTPConfigSMTPColumnHost.identifier(),
SMTPConfigSMTPColumnUser.identifier(),
SMTPConfigSMTPColumnPassword.identifier(),
SMTPConfigHTTPColumnID.identifier(),
SMTPConfigHTTPColumnEndpoint.identifier()).
From(smtpConfigsTable.identifier()).
LeftJoin(join(SMTPConfigSMTPColumnID, SMTPConfigColumnID)).
LeftJoin(join(SMTPConfigHTTPColumnID, SMTPConfigColumnID) + db.Timetravel(call.Took(ctx))).
PlaceholderFormat(sq.Dollar),
func(row *sql.Row) (*SMTPConfig, error) {
config := new(SMTPConfig)
var (
smtpConfig = sqlSmtpConfig{}
httpConfig = sqlHTTPConfig{}
)
err := row.Scan(
&config.CreationDate,
&config.ChangeDate,
&config.ResourceOwner,
&config.Sequence,
&config.TLS,
&config.SenderAddress,
&config.SenderName,
&config.ReplyToAddress,
&config.Host,
&config.User,
&password,
&config.ID,
&config.State,
&config.Description,
&smtpConfig.id,
&smtpConfig.tls,
&smtpConfig.senderAddress,
&smtpConfig.senderName,
&smtpConfig.replyToAddress,
&smtpConfig.host,
&smtpConfig.user,
&password,
&httpConfig.id,
&httpConfig.endpoint,
)
if err != nil {
if errors.Is(err, sql.ErrNoRows) {
@@ -197,7 +248,9 @@ func prepareSMTPConfigQuery(ctx context.Context, db prepareDatabase) (sq.SelectB
}
return nil, zerrors.ThrowInternal(err, "QUERY-9k87F", "Errors.Internal")
}
config.Password = password
smtpConfig.password = password
smtpConfig.set(config)
httpConfig.setSMTP(config)
return config, nil
}
}
@@ -208,38 +261,53 @@ func prepareSMTPConfigsQuery(ctx context.Context, db prepareDatabase) (sq.Select
SMTPConfigColumnChangeDate.identifier(),
SMTPConfigColumnResourceOwner.identifier(),
SMTPConfigColumnSequence.identifier(),
SMTPConfigColumnTLS.identifier(),
SMTPConfigColumnSenderAddress.identifier(),
SMTPConfigColumnSenderName.identifier(),
SMTPConfigColumnReplyToAddress.identifier(),
SMTPConfigColumnSMTPHost.identifier(),
SMTPConfigColumnSMTPUser.identifier(),
SMTPConfigColumnSMTPPassword.identifier(),
SMTPConfigColumnID.identifier(),
SMTPConfigColumnState.identifier(),
SMTPConfigColumnDescription.identifier(),
countColumn.identifier()).
From(smtpConfigsTable.identifier() + db.Timetravel(call.Took(ctx))).
SMTPConfigSMTPColumnID.identifier(),
SMTPConfigSMTPColumnTLS.identifier(),
SMTPConfigSMTPColumnSenderAddress.identifier(),
SMTPConfigSMTPColumnSenderName.identifier(),
SMTPConfigSMTPColumnReplyToAddress.identifier(),
SMTPConfigSMTPColumnHost.identifier(),
SMTPConfigSMTPColumnUser.identifier(),
SMTPConfigSMTPColumnPassword.identifier(),
SMTPConfigHTTPColumnID.identifier(),
SMTPConfigHTTPColumnEndpoint.identifier(),
countColumn.identifier(),
).From(smtpConfigsTable.identifier()).
LeftJoin(join(SMTPConfigSMTPColumnID, SMTPConfigColumnID)).
LeftJoin(join(SMTPConfigHTTPColumnID, SMTPConfigColumnID) + db.Timetravel(call.Took(ctx))).
PlaceholderFormat(sq.Dollar),
func(rows *sql.Rows) (*SMTPConfigs, error) {
configs := &SMTPConfigs{Configs: []*SMTPConfig{}}
for rows.Next() {
config := new(SMTPConfig)
password := new(crypto.CryptoValue)
var (
smtpConfig = sqlSmtpConfig{}
httpConfig = sqlHTTPConfig{}
)
err := rows.Scan(
&config.CreationDate,
&config.ChangeDate,
&config.ResourceOwner,
&config.Sequence,
&config.TLS,
&config.SenderAddress,
&config.SenderName,
&config.ReplyToAddress,
&config.Host,
&config.User,
&config.Password,
&config.ID,
&config.State,
&config.Description,
&smtpConfig.id,
&smtpConfig.tls,
&smtpConfig.senderAddress,
&smtpConfig.senderName,
&smtpConfig.replyToAddress,
&smtpConfig.host,
&smtpConfig.user,
&password,
&httpConfig.id,
&httpConfig.endpoint,
&configs.Count,
)
if err != nil {
@@ -248,6 +316,9 @@ func prepareSMTPConfigsQuery(ctx context.Context, db prepareDatabase) (sq.Select
}
return nil, zerrors.ThrowInternal(err, "QUERY-9k87F", "Errors.Internal")
}
smtpConfig.password = password
smtpConfig.set(config)
httpConfig.setSMTP(config)
configs.Configs = append(configs.Configs, config)
}
return configs, nil
@@ -277,3 +348,38 @@ func (q *Queries) SearchSMTPConfigs(ctx context.Context, queries *SMTPConfigsSea
configs.State, err = q.latestState(ctx, smsConfigsTable)
return configs, err
}
type sqlSmtpConfig struct {
id sql.NullString
tls sql.NullBool
senderAddress sql.NullString
senderName sql.NullString
replyToAddress sql.NullString
host sql.NullString
user sql.NullString
password *crypto.CryptoValue
}
func (c sqlSmtpConfig) set(smtpConfig *SMTPConfig) {
if !c.id.Valid {
return
}
smtpConfig.SMTPConfig = &SMTP{
TLS: c.tls.Bool,
SenderAddress: c.senderAddress.String,
SenderName: c.senderName.String,
ReplyToAddress: c.replyToAddress.String,
Host: c.host.String,
User: c.user.String,
Password: c.password,
}
}
func (c sqlHTTPConfig) setSMTP(smtpConfig *SMTPConfig) {
if !c.id.Valid {
return
}
smtpConfig.HTTPConfig = &HTTP{
Endpoint: c.endpoint.String,
}
}

View File

@@ -14,27 +14,36 @@ import (
)
var (
prepareSMTPConfigStmt = `SELECT projections.smtp_configs2.creation_date,` +
` projections.smtp_configs2.change_date,` +
` projections.smtp_configs2.resource_owner,` +
` projections.smtp_configs2.sequence,` +
` projections.smtp_configs2.tls,` +
` projections.smtp_configs2.sender_address,` +
` projections.smtp_configs2.sender_name,` +
` projections.smtp_configs2.reply_to_address,` +
` projections.smtp_configs2.host,` +
` projections.smtp_configs2.username,` +
` projections.smtp_configs2.password,` +
` projections.smtp_configs2.id,` +
` projections.smtp_configs2.state,` +
` projections.smtp_configs2.description` +
` FROM projections.smtp_configs2` +
prepareSMTPConfigStmt = `SELECT projections.smtp_configs3.creation_date,` +
` projections.smtp_configs3.change_date,` +
` projections.smtp_configs3.resource_owner,` +
` projections.smtp_configs3.sequence,` +
` projections.smtp_configs3.id,` +
` projections.smtp_configs3.state,` +
` projections.smtp_configs3.description,` +
` projections.smtp_configs3_smtp.id,` +
` projections.smtp_configs3_smtp.tls,` +
` projections.smtp_configs3_smtp.sender_address,` +
` projections.smtp_configs3_smtp.sender_name,` +
` projections.smtp_configs3_smtp.reply_to_address,` +
` projections.smtp_configs3_smtp.host,` +
` projections.smtp_configs3_smtp.username,` +
` projections.smtp_configs3_smtp.password,` +
` projections.smtp_configs3_http.id,` +
` projections.smtp_configs3_http.endpoint` +
` FROM projections.smtp_configs3` +
` LEFT JOIN projections.smtp_configs3_smtp ON projections.smtp_configs3.id = projections.smtp_configs3_smtp.id AND projections.smtp_configs3.instance_id = projections.smtp_configs3_smtp.instance_id` +
` LEFT JOIN projections.smtp_configs3_http ON projections.smtp_configs3.id = projections.smtp_configs3_http.id AND projections.smtp_configs3.instance_id = projections.smtp_configs3_http.instance_id` +
` AS OF SYSTEM TIME '-1 ms'`
prepareSMTPConfigCols = []string{
"creation_date",
"change_date",
"resource_owner",
"sequence",
"id",
"state",
"description",
"id",
"tls",
"sender_address",
"sender_name",
@@ -43,8 +52,7 @@ var (
"smtp_user",
"smtp_password",
"id",
"state",
"description",
"endpoint",
}
)
@@ -89,6 +97,10 @@ func Test_SMTPConfigsPrepares(t *testing.T) {
testNow,
"ro",
uint64(20211108),
"2232323",
domain.SMTPConfigStateActive,
"test",
"2232323",
true,
"sender",
"name",
@@ -96,27 +108,69 @@ func Test_SMTPConfigsPrepares(t *testing.T) {
"host",
"user",
&crypto.CryptoValue{},
"2232323",
domain.SMTPConfigStateActive,
"test",
nil,
nil,
},
),
},
object: &SMTPConfig{
CreationDate: testNow,
ChangeDate: testNow,
ResourceOwner: "ro",
Sequence: 20211108,
TLS: true,
SenderAddress: "sender",
SenderName: "name",
ReplyToAddress: "reply-to",
Host: "host",
User: "user",
Password: &crypto.CryptoValue{},
ID: "2232323",
State: domain.SMTPConfigStateActive,
Description: "test",
CreationDate: testNow,
ChangeDate: testNow,
ResourceOwner: "ro",
Sequence: 20211108,
SMTPConfig: &SMTP{
TLS: true,
SenderAddress: "sender",
SenderName: "name",
ReplyToAddress: "reply-to",
Host: "host",
User: "user",
Password: &crypto.CryptoValue{},
},
ID: "2232323",
State: domain.SMTPConfigStateActive,
Description: "test",
},
},
{
name: "prepareSMTPConfigQuery found, http",
prepare: prepareSMTPConfigQuery,
want: want{
sqlExpectations: mockQuery(
regexp.QuoteMeta(prepareSMTPConfigStmt),
prepareSMTPConfigCols,
[]driver.Value{
testNow,
testNow,
"ro",
uint64(20211108),
"2232323",
domain.SMTPConfigStateActive,
"test",
nil,
nil,
nil,
nil,
nil,
nil,
nil,
nil,
"2232323",
"endpoint",
},
),
},
object: &SMTPConfig{
CreationDate: testNow,
ChangeDate: testNow,
ResourceOwner: "ro",
Sequence: 20211108,
HTTPConfig: &HTTP{
Endpoint: "endpoint",
},
ID: "2232323",
State: domain.SMTPConfigStateActive,
Description: "test",
},
},
{
@@ -131,6 +185,10 @@ func Test_SMTPConfigsPrepares(t *testing.T) {
testNow,
"ro",
uint64(20211109),
"44442323",
domain.SMTPConfigStateInactive,
"test2",
"44442323",
true,
"sender2",
"name2",
@@ -138,27 +196,28 @@ func Test_SMTPConfigsPrepares(t *testing.T) {
"host2",
"user2",
&crypto.CryptoValue{},
"44442323",
domain.SMTPConfigStateInactive,
"test2",
nil,
nil,
},
),
},
object: &SMTPConfig{
CreationDate: testNow,
ChangeDate: testNow,
ResourceOwner: "ro",
Sequence: 20211109,
TLS: true,
SenderAddress: "sender2",
SenderName: "name2",
ReplyToAddress: "reply-to2",
Host: "host2",
User: "user2",
Password: &crypto.CryptoValue{},
ID: "44442323",
State: domain.SMTPConfigStateInactive,
Description: "test2",
CreationDate: testNow,
ChangeDate: testNow,
ResourceOwner: "ro",
Sequence: 20211109,
SMTPConfig: &SMTP{
TLS: true,
SenderAddress: "sender2",
SenderName: "name2",
ReplyToAddress: "reply-to2",
Host: "host2",
User: "user2",
Password: &crypto.CryptoValue{},
},
ID: "44442323",
State: domain.SMTPConfigStateInactive,
Description: "test2",
},
},
{
@@ -173,6 +232,10 @@ func Test_SMTPConfigsPrepares(t *testing.T) {
testNow,
"ro",
uint64(20211109),
"23234444",
domain.SMTPConfigStateInactive,
"test3",
"23234444",
true,
"sender3",
"name3",
@@ -180,27 +243,28 @@ func Test_SMTPConfigsPrepares(t *testing.T) {
"host3",
"user3",
&crypto.CryptoValue{},
"23234444",
domain.SMTPConfigStateInactive,
"test3",
nil,
nil,
},
),
},
object: &SMTPConfig{
CreationDate: testNow,
ChangeDate: testNow,
ResourceOwner: "ro",
Sequence: 20211109,
TLS: true,
SenderAddress: "sender3",
SenderName: "name3",
ReplyToAddress: "reply-to3",
Host: "host3",
User: "user3",
Password: &crypto.CryptoValue{},
ID: "23234444",
State: domain.SMTPConfigStateInactive,
Description: "test3",
CreationDate: testNow,
ChangeDate: testNow,
ResourceOwner: "ro",
Sequence: 20211109,
SMTPConfig: &SMTP{
TLS: true,
SenderAddress: "sender3",
SenderName: "name3",
ReplyToAddress: "reply-to3",
Host: "host3",
User: "user3",
Password: &crypto.CryptoValue{},
},
ID: "23234444",
State: domain.SMTPConfigStateInactive,
Description: "test3",
},
},
{

View File

@@ -12,12 +12,14 @@ func init() {
eventstore.RegisterFilterEventMapper(AggregateType, SecretGeneratorAddedEventType, SecretGeneratorAddedEventMapper)
eventstore.RegisterFilterEventMapper(AggregateType, SecretGeneratorChangedEventType, SecretGeneratorChangedEventMapper)
eventstore.RegisterFilterEventMapper(AggregateType, SecretGeneratorRemovedEventType, SecretGeneratorRemovedEventMapper)
eventstore.RegisterFilterEventMapper(AggregateType, SMTPConfigAddedEventType, SMTPConfigAddedEventMapper)
eventstore.RegisterFilterEventMapper(AggregateType, SMTPConfigChangedEventType, SMTPConfigChangedEventMapper)
eventstore.RegisterFilterEventMapper(AggregateType, SMTPConfigActivatedEventType, SMTPConfigActivatedEventMapper)
eventstore.RegisterFilterEventMapper(AggregateType, SMTPConfigDeactivatedEventType, SMTPConfigDeactivatedEventMapper)
eventstore.RegisterFilterEventMapper(AggregateType, SMTPConfigPasswordChangedEventType, SMTPConfigPasswordChangedEventMapper)
eventstore.RegisterFilterEventMapper(AggregateType, SMTPConfigRemovedEventType, SMTPConfigRemovedEventMapper)
eventstore.RegisterFilterEventMapper(AggregateType, SMTPConfigAddedEventType, eventstore.GenericEventMapper[SMTPConfigAddedEvent])
eventstore.RegisterFilterEventMapper(AggregateType, SMTPConfigChangedEventType, eventstore.GenericEventMapper[SMTPConfigChangedEvent])
eventstore.RegisterFilterEventMapper(AggregateType, SMTPConfigActivatedEventType, eventstore.GenericEventMapper[SMTPConfigActivatedEvent])
eventstore.RegisterFilterEventMapper(AggregateType, SMTPConfigDeactivatedEventType, eventstore.GenericEventMapper[SMTPConfigDeactivatedEvent])
eventstore.RegisterFilterEventMapper(AggregateType, SMTPConfigPasswordChangedEventType, eventstore.GenericEventMapper[SMTPConfigPasswordChangedEvent])
eventstore.RegisterFilterEventMapper(AggregateType, SMTPConfigHTTPAddedEventType, eventstore.GenericEventMapper[SMTPConfigHTTPAddedEvent])
eventstore.RegisterFilterEventMapper(AggregateType, SMTPConfigHTTPChangedEventType, eventstore.GenericEventMapper[SMTPConfigHTTPChangedEvent])
eventstore.RegisterFilterEventMapper(AggregateType, SMTPConfigRemovedEventType, eventstore.GenericEventMapper[SMTPConfigRemovedEvent])
eventstore.RegisterFilterEventMapper(AggregateType, SMSConfigTwilioAddedEventType, eventstore.GenericEventMapper[SMSConfigTwilioAddedEvent])
eventstore.RegisterFilterEventMapper(AggregateType, SMSConfigTwilioChangedEventType, eventstore.GenericEventMapper[SMSConfigTwilioChangedEvent])
eventstore.RegisterFilterEventMapper(AggregateType, SMSConfigTwilioTokenChangedEventType, eventstore.GenericEventMapper[SMSConfigTwilioTokenChangedEvent])

View File

@@ -10,16 +10,19 @@ import (
const (
smtpConfigPrefix = "smtp.config."
httpConfigPrefix = "http."
SMTPConfigAddedEventType = instanceEventTypePrefix + smtpConfigPrefix + "added"
SMTPConfigChangedEventType = instanceEventTypePrefix + smtpConfigPrefix + "changed"
SMTPConfigPasswordChangedEventType = instanceEventTypePrefix + smtpConfigPrefix + "password.changed"
SMTPConfigHTTPAddedEventType = instanceEventTypePrefix + smtpConfigPrefix + httpConfigPrefix + "added"
SMTPConfigHTTPChangedEventType = instanceEventTypePrefix + smtpConfigPrefix + httpConfigPrefix + "changed"
SMTPConfigRemovedEventType = instanceEventTypePrefix + smtpConfigPrefix + "removed"
SMTPConfigActivatedEventType = instanceEventTypePrefix + smtpConfigPrefix + "activated"
SMTPConfigDeactivatedEventType = instanceEventTypePrefix + smtpConfigPrefix + "deactivated"
)
type SMTPConfigAddedEvent struct {
eventstore.BaseEvent `json:"-"`
*eventstore.BaseEvent `json:"-"`
ID string `json:"id,omitempty"`
Description string `json:"description,omitempty"`
@@ -45,7 +48,7 @@ func NewSMTPConfigAddedEvent(
password *crypto.CryptoValue,
) *SMTPConfigAddedEvent {
return &SMTPConfigAddedEvent{
BaseEvent: *eventstore.NewBaseEventForPush(
BaseEvent: eventstore.NewBaseEventForPush(
ctx,
aggregate,
SMTPConfigAddedEventType,
@@ -61,6 +64,9 @@ func NewSMTPConfigAddedEvent(
Password: password,
}
}
func (e *SMTPConfigAddedEvent) SetBaseEvent(event *eventstore.BaseEvent) {
e.BaseEvent = event
}
func (e *SMTPConfigAddedEvent) Payload() interface{} {
return e
@@ -70,29 +76,21 @@ func (e *SMTPConfigAddedEvent) UniqueConstraints() []*eventstore.UniqueConstrain
return nil
}
func SMTPConfigAddedEventMapper(event eventstore.Event) (eventstore.Event, error) {
smtpConfigAdded := &SMTPConfigAddedEvent{
BaseEvent: *eventstore.BaseEventFromRepo(event),
}
err := event.Unmarshal(smtpConfigAdded)
if err != nil {
return nil, zerrors.ThrowInternal(err, "IAM-39fks", "unable to unmarshal smtp config added")
}
return smtpConfigAdded, nil
type SMTPConfigChangedEvent struct {
*eventstore.BaseEvent `json:"-"`
ID string `json:"id,omitempty"`
Description *string `json:"description,omitempty"`
FromAddress *string `json:"senderAddress,omitempty"`
FromName *string `json:"senderName,omitempty"`
ReplyToAddress *string `json:"replyToAddress,omitempty"`
TLS *bool `json:"tls,omitempty"`
Host *string `json:"host,omitempty"`
User *string `json:"user,omitempty"`
Password *crypto.CryptoValue `json:"password,omitempty"`
}
type SMTPConfigChangedEvent struct {
eventstore.BaseEvent `json:"-"`
ID string `json:"id,omitempty"`
Description *string `json:"description,omitempty"`
FromAddress *string `json:"senderAddress,omitempty"`
FromName *string `json:"senderName,omitempty"`
ReplyToAddress *string `json:"replyToAddress,omitempty"`
TLS *bool `json:"tls,omitempty"`
Host *string `json:"host,omitempty"`
User *string `json:"user,omitempty"`
Password *crypto.CryptoValue `json:"password,omitempty"`
func (e *SMTPConfigChangedEvent) SetBaseEvent(event *eventstore.BaseEvent) {
e.BaseEvent = event
}
func (e *SMTPConfigChangedEvent) Payload() interface{} {
@@ -113,7 +111,7 @@ func NewSMTPConfigChangeEvent(
return nil, zerrors.ThrowPreconditionFailed(nil, "IAM-o0pWf", "Errors.NoChangesFound")
}
changeEvent := &SMTPConfigChangedEvent{
BaseEvent: *eventstore.NewBaseEventForPush(
BaseEvent: eventstore.NewBaseEventForPush(
ctx,
aggregate,
SMTPConfigChangedEventType,
@@ -182,23 +180,10 @@ func ChangeSMTPConfigSMTPPassword(password *crypto.CryptoValue) func(event *SMTP
}
}
func SMTPConfigChangedEventMapper(event eventstore.Event) (eventstore.Event, error) {
e := &SMTPConfigChangedEvent{
BaseEvent: *eventstore.BaseEventFromRepo(event),
}
err := event.Unmarshal(e)
if err != nil {
return nil, zerrors.ThrowInternal(err, "IAM-m09oo", "unable to unmarshal smtp changed")
}
return e, nil
}
type SMTPConfigPasswordChangedEvent struct {
eventstore.BaseEvent `json:"-"`
ID string `json:"id,omitempty"`
Password *crypto.CryptoValue `json:"password,omitempty"`
*eventstore.BaseEvent `json:"-"`
ID string `json:"id,omitempty"`
Password *crypto.CryptoValue `json:"password,omitempty"`
}
func NewSMTPConfigPasswordChangedEvent(
@@ -208,7 +193,7 @@ func NewSMTPConfigPasswordChangedEvent(
password *crypto.CryptoValue,
) *SMTPConfigPasswordChangedEvent {
return &SMTPConfigPasswordChangedEvent{
BaseEvent: *eventstore.NewBaseEventForPush(
BaseEvent: eventstore.NewBaseEventForPush(
ctx,
aggregate,
SMTPConfigPasswordChangedEventType,
@@ -217,6 +202,10 @@ func NewSMTPConfigPasswordChangedEvent(
}
}
func (e *SMTPConfigPasswordChangedEvent) SetBaseEvent(event *eventstore.BaseEvent) {
e.BaseEvent = event
}
func (e *SMTPConfigPasswordChangedEvent) Payload() interface{} {
return e
}
@@ -225,21 +214,109 @@ func (e *SMTPConfigPasswordChangedEvent) UniqueConstraints() []*eventstore.Uniqu
return nil
}
func SMTPConfigPasswordChangedEventMapper(event eventstore.Event) (eventstore.Event, error) {
smtpConfigPasswordChanged := &SMTPConfigPasswordChangedEvent{
BaseEvent: *eventstore.BaseEventFromRepo(event),
}
err := event.Unmarshal(smtpConfigPasswordChanged)
if err != nil {
return nil, zerrors.ThrowInternal(err, "IAM-99iNF", "unable to unmarshal smtp config password changed")
}
type SMTPConfigHTTPAddedEvent struct {
*eventstore.BaseEvent `json:"-"`
return smtpConfigPasswordChanged, nil
ID string `json:"id,omitempty"`
Description string `json:"description,omitempty"`
Endpoint string `json:"endpoint,omitempty"`
}
func NewSMTPConfigHTTPAddedEvent(
ctx context.Context,
aggregate *eventstore.Aggregate,
id, description string,
endpoint string,
) *SMTPConfigHTTPAddedEvent {
return &SMTPConfigHTTPAddedEvent{
BaseEvent: eventstore.NewBaseEventForPush(
ctx,
aggregate,
SMTPConfigHTTPAddedEventType,
),
ID: id,
Description: description,
Endpoint: endpoint,
}
}
func (e *SMTPConfigHTTPAddedEvent) SetBaseEvent(event *eventstore.BaseEvent) {
e.BaseEvent = event
}
func (e *SMTPConfigHTTPAddedEvent) Payload() interface{} {
return e
}
func (e *SMTPConfigHTTPAddedEvent) UniqueConstraints() []*eventstore.UniqueConstraint {
return nil
}
type SMTPConfigHTTPChangedEvent struct {
*eventstore.BaseEvent `json:"-"`
ID string `json:"id,omitempty"`
Description *string `json:"description,omitempty"`
Endpoint *string `json:"endpoint,omitempty"`
}
func (e *SMTPConfigHTTPChangedEvent) SetBaseEvent(event *eventstore.BaseEvent) {
e.BaseEvent = event
}
func (e *SMTPConfigHTTPChangedEvent) Payload() interface{} {
return e
}
func (e *SMTPConfigHTTPChangedEvent) UniqueConstraints() []*eventstore.UniqueConstraint {
return nil
}
func NewSMTPConfigHTTPChangeEvent(
ctx context.Context,
aggregate *eventstore.Aggregate,
id string,
changes []SMTPConfigHTTPChanges,
) (*SMTPConfigHTTPChangedEvent, error) {
if len(changes) == 0 {
return nil, zerrors.ThrowPreconditionFailed(nil, "IAM-o0pWf", "Errors.NoChangesFound")
}
changeEvent := &SMTPConfigHTTPChangedEvent{
BaseEvent: eventstore.NewBaseEventForPush(
ctx,
aggregate,
SMTPConfigHTTPChangedEventType,
),
ID: id,
}
for _, change := range changes {
change(changeEvent)
}
return changeEvent, nil
}
type SMTPConfigHTTPChanges func(event *SMTPConfigHTTPChangedEvent)
func ChangeSMTPConfigHTTPID(id string) func(event *SMTPConfigHTTPChangedEvent) {
return func(e *SMTPConfigHTTPChangedEvent) {
e.ID = id
}
}
func ChangeSMTPConfigHTTPDescription(description string) func(event *SMTPConfigHTTPChangedEvent) {
return func(e *SMTPConfigHTTPChangedEvent) {
e.Description = &description
}
}
func ChangeSMTPConfigHTTPEndpoint(endpoint string) func(event *SMTPConfigHTTPChangedEvent) {
return func(e *SMTPConfigHTTPChangedEvent) {
e.Endpoint = &endpoint
}
}
type SMTPConfigActivatedEvent struct {
eventstore.BaseEvent `json:"-"`
ID string `json:"id,omitempty"`
*eventstore.BaseEvent `json:"-"`
ID string `json:"id,omitempty"`
}
func NewSMTPConfigActivatedEvent(
@@ -248,7 +325,7 @@ func NewSMTPConfigActivatedEvent(
id string,
) *SMTPConfigActivatedEvent {
return &SMTPConfigActivatedEvent{
BaseEvent: *eventstore.NewBaseEventForPush(
BaseEvent: eventstore.NewBaseEventForPush(
ctx,
aggregate,
SMTPConfigActivatedEventType,
@@ -257,6 +334,10 @@ func NewSMTPConfigActivatedEvent(
}
}
func (e *SMTPConfigActivatedEvent) SetBaseEvent(event *eventstore.BaseEvent) {
e.BaseEvent = event
}
func (e *SMTPConfigActivatedEvent) Payload() interface{} {
return e
}
@@ -265,21 +346,9 @@ func (e *SMTPConfigActivatedEvent) UniqueConstraints() []*eventstore.UniqueConst
return nil
}
func SMTPConfigActivatedEventMapper(event eventstore.Event) (eventstore.Event, error) {
smtpConfigActivated := &SMTPConfigActivatedEvent{
BaseEvent: *eventstore.BaseEventFromRepo(event),
}
err := event.Unmarshal(smtpConfigActivated)
if err != nil {
return nil, zerrors.ThrowInternal(err, "IAM-KPr5t", "unable to unmarshal smtp config removed")
}
return smtpConfigActivated, nil
}
type SMTPConfigDeactivatedEvent struct {
eventstore.BaseEvent `json:"-"`
ID string `json:"id,omitempty"`
*eventstore.BaseEvent `json:"-"`
ID string `json:"id,omitempty"`
}
func NewSMTPConfigDeactivatedEvent(
@@ -288,7 +357,7 @@ func NewSMTPConfigDeactivatedEvent(
id string,
) *SMTPConfigDeactivatedEvent {
return &SMTPConfigDeactivatedEvent{
BaseEvent: *eventstore.NewBaseEventForPush(
BaseEvent: eventstore.NewBaseEventForPush(
ctx,
aggregate,
SMTPConfigDeactivatedEventType,
@@ -297,6 +366,10 @@ func NewSMTPConfigDeactivatedEvent(
}
}
func (e *SMTPConfigDeactivatedEvent) SetBaseEvent(event *eventstore.BaseEvent) {
e.BaseEvent = event
}
func (e *SMTPConfigDeactivatedEvent) Payload() interface{} {
return e
}
@@ -305,21 +378,9 @@ func (e *SMTPConfigDeactivatedEvent) UniqueConstraints() []*eventstore.UniqueCon
return nil
}
func SMTPConfigDeactivatedEventMapper(event eventstore.Event) (eventstore.Event, error) {
smtpConfigDeactivated := &SMTPConfigDeactivatedEvent{
BaseEvent: *eventstore.BaseEventFromRepo(event),
}
err := event.Unmarshal(smtpConfigDeactivated)
if err != nil {
return nil, zerrors.ThrowInternal(err, "IAM-KPr5t", "unable to unmarshal smtp config removed")
}
return smtpConfigDeactivated, nil
}
type SMTPConfigRemovedEvent struct {
eventstore.BaseEvent `json:"-"`
ID string `json:"id,omitempty"`
*eventstore.BaseEvent `json:"-"`
ID string `json:"id,omitempty"`
}
func NewSMTPConfigRemovedEvent(
@@ -328,7 +389,7 @@ func NewSMTPConfigRemovedEvent(
id string,
) *SMTPConfigRemovedEvent {
return &SMTPConfigRemovedEvent{
BaseEvent: *eventstore.NewBaseEventForPush(
BaseEvent: eventstore.NewBaseEventForPush(
ctx,
aggregate,
SMTPConfigRemovedEventType,
@@ -337,6 +398,9 @@ func NewSMTPConfigRemovedEvent(
}
}
func (e *SMTPConfigRemovedEvent) SetBaseEvent(event *eventstore.BaseEvent) {
e.BaseEvent = event
}
func (e *SMTPConfigRemovedEvent) Payload() interface{} {
return e
}
@@ -344,15 +408,3 @@ func (e *SMTPConfigRemovedEvent) Payload() interface{} {
func (e *SMTPConfigRemovedEvent) UniqueConstraints() []*eventstore.UniqueConstraint {
return nil
}
func SMTPConfigRemovedEventMapper(event eventstore.Event) (eventstore.Event, error) {
smtpConfigRemoved := &SMTPConfigRemovedEvent{
BaseEvent: *eventstore.BaseEventFromRepo(event),
}
err := event.Unmarshal(smtpConfigRemoved)
if err != nil {
return nil, zerrors.ThrowInternal(err, "IAM-DVw1s", "unable to unmarshal smtp config removed")
}
return smtpConfigRemoved, nil
}