mirror of
https://github.com/zitadel/zitadel.git
synced 2025-06-19 21:08:37 +00:00
feat: add http as sms provider (#8540)
# Which Problems Are Solved Send SMS messages as a HTTP call to a relay, for own logic on handling different SMS providers. # How the Problems Are Solved Add HTTP as SMS provider type and handling of webhook messages in the notification handlers. # Additional Changes Clean up old Twilio events, which were supposed to handle the general SMS 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:
parent
d2e0ac07f1
commit
5bdf1a4547
@ -34,23 +34,23 @@ func (s *Server) GetSMSProvider(ctx context.Context, req *admin_pb.GetSMSProvide
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (s *Server) AddSMSProviderTwilio(ctx context.Context, req *admin_pb.AddSMSProviderTwilioRequest) (*admin_pb.AddSMSProviderTwilioResponse, error) {
|
func (s *Server) AddSMSProviderTwilio(ctx context.Context, req *admin_pb.AddSMSProviderTwilioRequest) (*admin_pb.AddSMSProviderTwilioResponse, error) {
|
||||||
id, result, err := s.command.AddSMSConfigTwilio(ctx, authz.GetInstance(ctx).InstanceID(), AddSMSConfigTwilioToConfig(req))
|
smsConfig := addSMSConfigTwilioToConfig(ctx, req)
|
||||||
if err != nil {
|
if err := s.command.AddSMSConfigTwilio(ctx, smsConfig); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
return &admin_pb.AddSMSProviderTwilioResponse{
|
return &admin_pb.AddSMSProviderTwilioResponse{
|
||||||
Details: object.DomainToAddDetailsPb(result),
|
Details: object.DomainToAddDetailsPb(smsConfig.Details),
|
||||||
Id: id,
|
Id: smsConfig.ID,
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Server) UpdateSMSProviderTwilio(ctx context.Context, req *admin_pb.UpdateSMSProviderTwilioRequest) (*admin_pb.UpdateSMSProviderTwilioResponse, error) {
|
func (s *Server) UpdateSMSProviderTwilio(ctx context.Context, req *admin_pb.UpdateSMSProviderTwilioRequest) (*admin_pb.UpdateSMSProviderTwilioResponse, error) {
|
||||||
result, err := s.command.ChangeSMSConfigTwilio(ctx, authz.GetInstance(ctx).InstanceID(), req.Id, UpdateSMSConfigTwilioToConfig(req))
|
smsConfig := updateSMSConfigTwilioToConfig(ctx, req)
|
||||||
if err != nil {
|
if err := s.command.ChangeSMSConfigTwilio(ctx, smsConfig); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
return &admin_pb.UpdateSMSProviderTwilioResponse{
|
return &admin_pb.UpdateSMSProviderTwilioResponse{
|
||||||
Details: object.DomainToChangeDetailsPb(result),
|
Details: object.DomainToChangeDetailsPb(smsConfig.Details),
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -65,6 +65,27 @@ func (s *Server) UpdateSMSProviderTwilioToken(ctx context.Context, req *admin_pb
|
|||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (s *Server) AddSMSProviderHTTP(ctx context.Context, req *admin_pb.AddSMSProviderHTTPRequest) (*admin_pb.AddSMSProviderHTTPResponse, error) {
|
||||||
|
smsConfig := addSMSConfigHTTPToConfig(ctx, req)
|
||||||
|
if err := s.command.AddSMSConfigHTTP(ctx, smsConfig); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return &admin_pb.AddSMSProviderHTTPResponse{
|
||||||
|
Details: object.DomainToAddDetailsPb(smsConfig.Details),
|
||||||
|
Id: smsConfig.ID,
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *Server) UpdateSMSProviderHTTP(ctx context.Context, req *admin_pb.UpdateSMSProviderHTTPRequest) (*admin_pb.UpdateSMSProviderHTTPResponse, error) {
|
||||||
|
smsConfig := updateSMSConfigHTTPToConfig(ctx, req)
|
||||||
|
if err := s.command.ChangeSMSConfigHTTP(ctx, smsConfig); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return &admin_pb.UpdateSMSProviderHTTPResponse{
|
||||||
|
Details: object.DomainToChangeDetailsPb(smsConfig.Details),
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
|
||||||
func (s *Server) ActivateSMSProvider(ctx context.Context, req *admin_pb.ActivateSMSProviderRequest) (*admin_pb.ActivateSMSProviderResponse, error) {
|
func (s *Server) ActivateSMSProvider(ctx context.Context, req *admin_pb.ActivateSMSProviderRequest) (*admin_pb.ActivateSMSProviderResponse, error) {
|
||||||
result, err := s.command.ActivateSMSConfig(ctx, authz.GetInstance(ctx).InstanceID(), req.Id)
|
result, err := s.command.ActivateSMSConfig(ctx, authz.GetInstance(ctx).InstanceID(), req.Id)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -1,9 +1,14 @@
|
|||||||
package admin
|
package admin
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"context"
|
||||||
|
|
||||||
|
"github.com/muhlemmer/gu"
|
||||||
|
|
||||||
|
"github.com/zitadel/zitadel/internal/api/authz"
|
||||||
"github.com/zitadel/zitadel/internal/api/grpc/object"
|
"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/domain"
|
||||||
"github.com/zitadel/zitadel/internal/notification/channels/twilio"
|
|
||||||
"github.com/zitadel/zitadel/internal/query"
|
"github.com/zitadel/zitadel/internal/query"
|
||||||
admin_pb "github.com/zitadel/zitadel/pkg/grpc/admin"
|
admin_pb "github.com/zitadel/zitadel/pkg/grpc/admin"
|
||||||
settings_pb "github.com/zitadel/zitadel/pkg/grpc/settings"
|
settings_pb "github.com/zitadel/zitadel/pkg/grpc/settings"
|
||||||
@ -32,6 +37,7 @@ func SMSConfigToProviderPb(config *query.SMSConfig) *settings_pb.SMSProvider {
|
|||||||
return &settings_pb.SMSProvider{
|
return &settings_pb.SMSProvider{
|
||||||
Details: object.ToViewDetailsPb(config.Sequence, config.CreationDate, config.ChangeDate, config.ResourceOwner),
|
Details: object.ToViewDetailsPb(config.Sequence, config.CreationDate, config.ChangeDate, config.ResourceOwner),
|
||||||
Id: config.ID,
|
Id: config.ID,
|
||||||
|
Description: config.Description,
|
||||||
State: smsStateToPb(config.State),
|
State: smsStateToPb(config.State),
|
||||||
Config: SMSConfigToPb(config),
|
Config: SMSConfigToPb(config),
|
||||||
}
|
}
|
||||||
@ -41,9 +47,20 @@ func SMSConfigToPb(config *query.SMSConfig) settings_pb.SMSConfig {
|
|||||||
if config.TwilioConfig != nil {
|
if config.TwilioConfig != nil {
|
||||||
return TwilioConfigToPb(config.TwilioConfig)
|
return TwilioConfigToPb(config.TwilioConfig)
|
||||||
}
|
}
|
||||||
|
if config.HTTPConfig != nil {
|
||||||
|
return HTTPConfigToPb(config.HTTPConfig)
|
||||||
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func HTTPConfigToPb(http *query.HTTP) *settings_pb.SMSProvider_Http {
|
||||||
|
return &settings_pb.SMSProvider_Http{
|
||||||
|
Http: &settings_pb.HTTPConfig{
|
||||||
|
Endpoint: http.Endpoint,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func TwilioConfigToPb(twilio *query.Twilio) *settings_pb.SMSProvider_Twilio {
|
func TwilioConfigToPb(twilio *query.Twilio) *settings_pb.SMSProvider_Twilio {
|
||||||
return &settings_pb.SMSProvider_Twilio{
|
return &settings_pb.SMSProvider_Twilio{
|
||||||
Twilio: &settings_pb.TwilioConfig{
|
Twilio: &settings_pb.TwilioConfig{
|
||||||
@ -64,17 +81,39 @@ func smsStateToPb(state domain.SMSConfigState) settings_pb.SMSProviderConfigStat
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func AddSMSConfigTwilioToConfig(req *admin_pb.AddSMSProviderTwilioRequest) *twilio.Config {
|
func addSMSConfigTwilioToConfig(ctx context.Context, req *admin_pb.AddSMSProviderTwilioRequest) *command.AddTwilioConfig {
|
||||||
return &twilio.Config{
|
return &command.AddTwilioConfig{
|
||||||
|
ResourceOwner: authz.GetInstance(ctx).InstanceID(),
|
||||||
|
Description: req.Description,
|
||||||
SID: req.Sid,
|
SID: req.Sid,
|
||||||
SenderNumber: req.SenderNumber,
|
SenderNumber: req.SenderNumber,
|
||||||
Token: req.Token,
|
Token: req.Token,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func UpdateSMSConfigTwilioToConfig(req *admin_pb.UpdateSMSProviderTwilioRequest) *twilio.Config {
|
func updateSMSConfigTwilioToConfig(ctx context.Context, req *admin_pb.UpdateSMSProviderTwilioRequest) *command.ChangeTwilioConfig {
|
||||||
return &twilio.Config{
|
return &command.ChangeTwilioConfig{
|
||||||
SID: req.Sid,
|
ResourceOwner: authz.GetInstance(ctx).InstanceID(),
|
||||||
SenderNumber: req.SenderNumber,
|
ID: req.Id,
|
||||||
|
Description: gu.Ptr(req.Description),
|
||||||
|
SID: gu.Ptr(req.Sid),
|
||||||
|
SenderNumber: gu.Ptr(req.SenderNumber),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func addSMSConfigHTTPToConfig(ctx context.Context, req *admin_pb.AddSMSProviderHTTPRequest) *command.AddSMSHTTP {
|
||||||
|
return &command.AddSMSHTTP{
|
||||||
|
ResourceOwner: authz.GetInstance(ctx).InstanceID(),
|
||||||
|
Description: req.GetDescription(),
|
||||||
|
Endpoint: req.GetEndpoint(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func updateSMSConfigHTTPToConfig(ctx context.Context, req *admin_pb.UpdateSMSProviderHTTPRequest) *command.ChangeSMSHTTP {
|
||||||
|
return &command.ChangeSMSHTTP{
|
||||||
|
ResourceOwner: authz.GetInstance(ctx).InstanceID(),
|
||||||
|
ID: req.Id,
|
||||||
|
Description: gu.Ptr(req.Description),
|
||||||
|
Endpoint: gu.Ptr(req.Endpoint),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -5,203 +5,328 @@ import (
|
|||||||
|
|
||||||
"github.com/zitadel/zitadel/internal/crypto"
|
"github.com/zitadel/zitadel/internal/crypto"
|
||||||
"github.com/zitadel/zitadel/internal/domain"
|
"github.com/zitadel/zitadel/internal/domain"
|
||||||
"github.com/zitadel/zitadel/internal/notification/channels/twilio"
|
|
||||||
"github.com/zitadel/zitadel/internal/repository/instance"
|
"github.com/zitadel/zitadel/internal/repository/instance"
|
||||||
"github.com/zitadel/zitadel/internal/zerrors"
|
"github.com/zitadel/zitadel/internal/zerrors"
|
||||||
)
|
)
|
||||||
|
|
||||||
func (c *Commands) AddSMSConfigTwilio(ctx context.Context, instanceID string, config *twilio.Config) (string, *domain.ObjectDetails, error) {
|
type AddTwilioConfig struct {
|
||||||
id, err := c.idGenerator.Next()
|
Details *domain.ObjectDetails
|
||||||
if err != nil {
|
ResourceOwner string
|
||||||
return "", nil, err
|
ID string
|
||||||
|
|
||||||
|
Description string
|
||||||
|
SID string
|
||||||
|
Token string
|
||||||
|
SenderNumber string
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *Commands) AddSMSConfigTwilio(ctx context.Context, config *AddTwilioConfig) (err error) {
|
||||||
|
if config.ResourceOwner == "" {
|
||||||
|
return zerrors.ThrowInvalidArgument(nil, "COMMAND-ZLrZhKSKq0", "Errors.ResourceOwnerMissing")
|
||||||
}
|
}
|
||||||
smsConfigWriteModel, err := c.getSMSConfig(ctx, instanceID, id)
|
if config.ID == "" {
|
||||||
|
config.ID, err = c.idGenerator.Next()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", nil, err
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
smsConfigWriteModel, err := c.getSMSConfig(ctx, config.ResourceOwner, config.ID)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
var token *crypto.CryptoValue
|
var token *crypto.CryptoValue
|
||||||
if config.Token != "" {
|
if config.Token != "" {
|
||||||
token, err = crypto.Encrypt([]byte(config.Token), c.smsEncryption)
|
token, err = crypto.Encrypt([]byte(config.Token), c.smsEncryption)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", nil, err
|
return err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
err = c.pushAppendAndReduce(ctx,
|
||||||
iamAgg := InstanceAggregateFromWriteModel(&smsConfigWriteModel.WriteModel)
|
smsConfigWriteModel,
|
||||||
pushedEvents, err := c.eventstore.Push(ctx, instance.NewSMSConfigTwilioAddedEvent(
|
instance.NewSMSConfigTwilioAddedEvent(
|
||||||
ctx,
|
ctx,
|
||||||
iamAgg,
|
InstanceAggregateFromWriteModel(&smsConfigWriteModel.WriteModel),
|
||||||
id,
|
config.ID,
|
||||||
|
config.Description,
|
||||||
config.SID,
|
config.SID,
|
||||||
config.SenderNumber,
|
config.SenderNumber,
|
||||||
token))
|
token,
|
||||||
|
),
|
||||||
|
)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", nil, err
|
return err
|
||||||
}
|
}
|
||||||
err = AppendAndReduce(smsConfigWriteModel, pushedEvents...)
|
config.Details = writeModelToObjectDetails(&smsConfigWriteModel.WriteModel)
|
||||||
if err != nil {
|
return nil
|
||||||
return "", nil, err
|
|
||||||
}
|
|
||||||
return id, writeModelToObjectDetails(&smsConfigWriteModel.WriteModel), nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *Commands) ChangeSMSConfigTwilio(ctx context.Context, instanceID, id string, config *twilio.Config) (*domain.ObjectDetails, error) {
|
type ChangeTwilioConfig struct {
|
||||||
if id == "" {
|
Details *domain.ObjectDetails
|
||||||
return nil, zerrors.ThrowInvalidArgument(nil, "SMS-e9jwf", "Errors.IDMissing")
|
ResourceOwner string
|
||||||
|
ID string
|
||||||
|
|
||||||
|
Description *string
|
||||||
|
SID *string
|
||||||
|
Token *string
|
||||||
|
SenderNumber *string
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *Commands) ChangeSMSConfigTwilio(ctx context.Context, config *ChangeTwilioConfig) (err error) {
|
||||||
|
if config.ResourceOwner == "" {
|
||||||
|
return zerrors.ThrowInvalidArgument(nil, "COMMAND-RHXryJwmFG", "Errors.ResourceOwnerMissing")
|
||||||
}
|
}
|
||||||
smsConfigWriteModel, err := c.getSMSConfig(ctx, instanceID, id)
|
if config.ID == "" {
|
||||||
|
return zerrors.ThrowInvalidArgument(nil, "COMMAND-gMr93iNhTR", "Errors.IDMissing")
|
||||||
|
}
|
||||||
|
smsConfigWriteModel, err := c.getSMSConfig(ctx, config.ResourceOwner, config.ID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return err
|
||||||
}
|
}
|
||||||
if !smsConfigWriteModel.State.Exists() || smsConfigWriteModel.Twilio == nil {
|
if !smsConfigWriteModel.State.Exists() || smsConfigWriteModel.Twilio == nil {
|
||||||
return nil, zerrors.ThrowNotFound(nil, "COMMAND-2m9fw", "Errors.SMSConfig.NotFound")
|
return zerrors.ThrowNotFound(nil, "COMMAND-MUY0IFAf8O", "Errors.SMSConfig.NotFound")
|
||||||
}
|
}
|
||||||
iamAgg := InstanceAggregateFromWriteModel(&smsConfigWriteModel.WriteModel)
|
changedEvent, hasChanged, err := smsConfigWriteModel.NewTwilioChangedEvent(
|
||||||
|
|
||||||
changedEvent, hasChanged, err := smsConfigWriteModel.NewChangedEvent(
|
|
||||||
ctx,
|
ctx,
|
||||||
iamAgg,
|
InstanceAggregateFromWriteModel(&smsConfigWriteModel.WriteModel),
|
||||||
id,
|
config.ID,
|
||||||
|
config.Description,
|
||||||
config.SID,
|
config.SID,
|
||||||
config.SenderNumber)
|
config.SenderNumber)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return err
|
||||||
}
|
}
|
||||||
if !hasChanged {
|
if !hasChanged {
|
||||||
return nil, zerrors.ThrowPreconditionFailed(nil, "COMMAND-jf9wk", "Errors.NoChangesFound")
|
config.Details = writeModelToObjectDetails(&smsConfigWriteModel.WriteModel)
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
pushedEvents, err := c.eventstore.Push(ctx, changedEvent)
|
err = c.pushAppendAndReduce(ctx,
|
||||||
|
smsConfigWriteModel,
|
||||||
|
changedEvent,
|
||||||
|
)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return err
|
||||||
}
|
}
|
||||||
err = AppendAndReduce(smsConfigWriteModel, pushedEvents...)
|
config.Details = writeModelToObjectDetails(&smsConfigWriteModel.WriteModel)
|
||||||
if err != nil {
|
return nil
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
return writeModelToObjectDetails(&smsConfigWriteModel.WriteModel), nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *Commands) ChangeSMSConfigTwilioToken(ctx context.Context, instanceID, id, token string) (*domain.ObjectDetails, error) {
|
func (c *Commands) ChangeSMSConfigTwilioToken(ctx context.Context, resourceOwner, id, token string) (*domain.ObjectDetails, error) {
|
||||||
smsConfigWriteModel, err := c.getSMSConfig(ctx, instanceID, id)
|
if resourceOwner == "" {
|
||||||
|
return nil, zerrors.ThrowInvalidArgument(nil, "COMMAND-sLLA1HnMzj", "Errors.ResourceOwnerMissing")
|
||||||
|
}
|
||||||
|
if id == "" {
|
||||||
|
return nil, zerrors.ThrowInvalidArgument(nil, "SMS-PeNaqbC0r0", "Errors.IDMissing")
|
||||||
|
}
|
||||||
|
|
||||||
|
smsConfigWriteModel, err := c.getSMSConfig(ctx, resourceOwner, id)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
if !smsConfigWriteModel.State.Exists() || smsConfigWriteModel.Twilio == nil {
|
if !smsConfigWriteModel.State.Exists() || smsConfigWriteModel.Twilio == nil {
|
||||||
return nil, zerrors.ThrowNotFound(nil, "COMMAND-fj9wf", "Errors.SMSConfig.NotFound")
|
return nil, zerrors.ThrowNotFound(nil, "COMMAND-ij3NhEHATp", "Errors.SMSConfig.NotFound")
|
||||||
}
|
}
|
||||||
iamAgg := InstanceAggregateFromWriteModel(&smsConfigWriteModel.WriteModel)
|
|
||||||
newtoken, err := crypto.Encrypt([]byte(token), c.smsEncryption)
|
newtoken, err := crypto.Encrypt([]byte(token), c.smsEncryption)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
pushedEvents, err := c.eventstore.Push(ctx, instance.NewSMSConfigTokenChangedEvent(
|
err = c.pushAppendAndReduce(ctx,
|
||||||
|
smsConfigWriteModel,
|
||||||
|
instance.NewSMSConfigTokenChangedEvent(
|
||||||
ctx,
|
ctx,
|
||||||
iamAgg,
|
InstanceAggregateFromWriteModel(&smsConfigWriteModel.WriteModel),
|
||||||
id,
|
id,
|
||||||
newtoken))
|
newtoken,
|
||||||
if err != nil {
|
),
|
||||||
return nil, err
|
)
|
||||||
}
|
|
||||||
err = AppendAndReduce(smsConfigWriteModel, pushedEvents...)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
return writeModelToObjectDetails(&smsConfigWriteModel.WriteModel), nil
|
return writeModelToObjectDetails(&smsConfigWriteModel.WriteModel), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *Commands) ActivateSMSConfig(ctx context.Context, instanceID, id string) (*domain.ObjectDetails, error) {
|
type AddSMSHTTP struct {
|
||||||
if id == "" {
|
Details *domain.ObjectDetails
|
||||||
return nil, zerrors.ThrowInvalidArgument(nil, "SMS-dn93n", "Errors.IDMissing")
|
ResourceOwner string
|
||||||
|
ID string
|
||||||
|
|
||||||
|
Description string
|
||||||
|
Endpoint string
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *Commands) AddSMSConfigHTTP(ctx context.Context, config *AddSMSHTTP) (err error) {
|
||||||
|
if config.ResourceOwner == "" {
|
||||||
|
return zerrors.ThrowInvalidArgument(nil, "COMMAND-huy99qWjX4", "Errors.ResourceOwnerMissing")
|
||||||
}
|
}
|
||||||
smsConfigWriteModel, err := c.getSMSConfig(ctx, instanceID, id)
|
if config.ID == "" {
|
||||||
|
config.ID, err = c.idGenerator.Next()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
smsConfigWriteModel, err := c.getSMSConfig(ctx, config.ResourceOwner, config.ID)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
err = c.pushAppendAndReduce(ctx,
|
||||||
|
smsConfigWriteModel,
|
||||||
|
instance.NewSMSConfigHTTPAddedEvent(
|
||||||
|
ctx,
|
||||||
|
InstanceAggregateFromWriteModel(&smsConfigWriteModel.WriteModel),
|
||||||
|
config.ID,
|
||||||
|
config.Description,
|
||||||
|
config.Endpoint,
|
||||||
|
),
|
||||||
|
)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
config.Details = writeModelToObjectDetails(&smsConfigWriteModel.WriteModel)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
type ChangeSMSHTTP struct {
|
||||||
|
Details *domain.ObjectDetails
|
||||||
|
ResourceOwner string
|
||||||
|
ID string
|
||||||
|
|
||||||
|
Description *string
|
||||||
|
Endpoint *string
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *Commands) ChangeSMSConfigHTTP(ctx context.Context, config *ChangeSMSHTTP) (err error) {
|
||||||
|
if config.ResourceOwner == "" {
|
||||||
|
return zerrors.ThrowInvalidArgument(nil, "COMMAND-M622CFQnwK", "Errors.ResourceOwnerMissing")
|
||||||
|
}
|
||||||
|
if config.ID == "" {
|
||||||
|
return zerrors.ThrowInvalidArgument(nil, "COMMAND-phyb2e4Kll", "Errors.IDMissing")
|
||||||
|
}
|
||||||
|
smsConfigWriteModel, err := c.getSMSConfig(ctx, config.ResourceOwner, config.ID)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if !smsConfigWriteModel.State.Exists() || smsConfigWriteModel.HTTP == nil {
|
||||||
|
return zerrors.ThrowNotFound(nil, "COMMAND-6NW4I5Kqzj", "Errors.SMSConfig.NotFound")
|
||||||
|
}
|
||||||
|
changedEvent, hasChanged, err := smsConfigWriteModel.NewHTTPChangedEvent(
|
||||||
|
ctx,
|
||||||
|
InstanceAggregateFromWriteModel(&smsConfigWriteModel.WriteModel),
|
||||||
|
config.ID,
|
||||||
|
config.Description,
|
||||||
|
config.Endpoint)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if !hasChanged {
|
||||||
|
config.Details = writeModelToObjectDetails(&smsConfigWriteModel.WriteModel)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
err = c.pushAppendAndReduce(ctx, smsConfigWriteModel, changedEvent)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
config.Details = writeModelToObjectDetails(&smsConfigWriteModel.WriteModel)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *Commands) ActivateSMSConfig(ctx context.Context, resourceOwner, id string) (*domain.ObjectDetails, error) {
|
||||||
|
if resourceOwner == "" {
|
||||||
|
return nil, zerrors.ThrowInvalidArgument(nil, "COMMAND-EFgoOg997V", "Errors.ResourceOwnerMissing")
|
||||||
|
}
|
||||||
|
if id == "" {
|
||||||
|
return nil, zerrors.ThrowInvalidArgument(nil, "COMMAND-jJ6TVqzvjp", "Errors.IDMissing")
|
||||||
|
}
|
||||||
|
|
||||||
|
smsConfigWriteModel, err := c.getSMSConfig(ctx, resourceOwner, id)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
if !smsConfigWriteModel.State.Exists() {
|
if !smsConfigWriteModel.State.Exists() {
|
||||||
return nil, zerrors.ThrowNotFound(nil, "COMMAND-sn9we", "Errors.SMSConfig.NotFound")
|
return nil, zerrors.ThrowNotFound(nil, "COMMAND-9ULtp9PH5E", "Errors.SMSConfig.NotFound")
|
||||||
}
|
}
|
||||||
if smsConfigWriteModel.State == domain.SMSConfigStateActive {
|
if smsConfigWriteModel.State == domain.SMSConfigStateActive {
|
||||||
return nil, zerrors.ThrowNotFound(nil, "COMMAND-sn9we", "Errors.SMSConfig.AlreadyActive")
|
return nil, zerrors.ThrowPreconditionFailed(nil, "COMMAND-B25GFeIvRi", "Errors.SMSConfig.AlreadyActive")
|
||||||
}
|
}
|
||||||
iamAgg := InstanceAggregateFromWriteModel(&smsConfigWriteModel.WriteModel)
|
err = c.pushAppendAndReduce(ctx, smsConfigWriteModel,
|
||||||
pushedEvents, err := c.eventstore.Push(ctx, instance.NewSMSConfigTwilioActivatedEvent(
|
instance.NewSMSConfigActivatedEvent(
|
||||||
ctx,
|
ctx,
|
||||||
iamAgg,
|
InstanceAggregateFromWriteModel(&smsConfigWriteModel.WriteModel),
|
||||||
id))
|
id,
|
||||||
if err != nil {
|
),
|
||||||
return nil, err
|
)
|
||||||
}
|
|
||||||
err = AppendAndReduce(smsConfigWriteModel, pushedEvents...)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
return writeModelToObjectDetails(&smsConfigWriteModel.WriteModel), nil
|
return writeModelToObjectDetails(&smsConfigWriteModel.WriteModel), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *Commands) DeactivateSMSConfig(ctx context.Context, instanceID, id string) (*domain.ObjectDetails, error) {
|
func (c *Commands) DeactivateSMSConfig(ctx context.Context, resourceOwner, id string) (*domain.ObjectDetails, error) {
|
||||||
if id == "" {
|
if resourceOwner == "" {
|
||||||
return nil, zerrors.ThrowInvalidArgument(nil, "SMS-frkwf", "Errors.IDMissing")
|
return nil, zerrors.ThrowInvalidArgument(nil, "COMMAND-V9NWOZj8Gi", "Errors.ResourceOwnerMissing")
|
||||||
}
|
}
|
||||||
smsConfigWriteModel, err := c.getSMSConfig(ctx, instanceID, id)
|
if id == "" {
|
||||||
|
return nil, zerrors.ThrowInvalidArgument(nil, "COMMAND-xs1ah1v1CL", "Errors.IDMissing")
|
||||||
|
}
|
||||||
|
smsConfigWriteModel, err := c.getSMSConfig(ctx, resourceOwner, id)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
if !smsConfigWriteModel.State.Exists() {
|
if !smsConfigWriteModel.State.Exists() {
|
||||||
return nil, zerrors.ThrowNotFound(nil, "COMMAND-s39Kg", "Errors.SMSConfig.NotFound")
|
return nil, zerrors.ThrowNotFound(nil, "COMMAND-La91dGNhbM", "Errors.SMSConfig.NotFound")
|
||||||
}
|
}
|
||||||
if smsConfigWriteModel.State == domain.SMSConfigStateInactive {
|
if smsConfigWriteModel.State == domain.SMSConfigStateInactive {
|
||||||
return nil, zerrors.ThrowNotFound(nil, "COMMAND-dm9e3", "Errors.SMSConfig.AlreadyDeactivated")
|
return nil, zerrors.ThrowPreconditionFailed(nil, "COMMAND-OSZAEkYvk7", "Errors.SMSConfig.AlreadyDeactivated")
|
||||||
}
|
}
|
||||||
|
err = c.pushAppendAndReduce(ctx,
|
||||||
iamAgg := InstanceAggregateFromWriteModel(&smsConfigWriteModel.WriteModel)
|
smsConfigWriteModel,
|
||||||
pushedEvents, err := c.eventstore.Push(ctx, instance.NewSMSConfigDeactivatedEvent(
|
instance.NewSMSConfigDeactivatedEvent(
|
||||||
ctx,
|
ctx,
|
||||||
iamAgg,
|
InstanceAggregateFromWriteModel(&smsConfigWriteModel.WriteModel),
|
||||||
id))
|
id,
|
||||||
if err != nil {
|
),
|
||||||
return nil, err
|
)
|
||||||
}
|
|
||||||
err = AppendAndReduce(smsConfigWriteModel, pushedEvents...)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
return writeModelToObjectDetails(&smsConfigWriteModel.WriteModel), nil
|
return writeModelToObjectDetails(&smsConfigWriteModel.WriteModel), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *Commands) RemoveSMSConfig(ctx context.Context, instanceID, id string) (*domain.ObjectDetails, error) {
|
func (c *Commands) RemoveSMSConfig(ctx context.Context, resourceOwner, id string) (*domain.ObjectDetails, error) {
|
||||||
if id == "" {
|
if resourceOwner == "" {
|
||||||
return nil, zerrors.ThrowInvalidArgument(nil, "SMS-3j9fs", "Errors.IDMissing")
|
return nil, zerrors.ThrowInvalidArgument(nil, "COMMAND-cw0NSJsn1v", "Errors.ResourceOwnerMissing")
|
||||||
}
|
}
|
||||||
smsConfigWriteModel, err := c.getSMSConfig(ctx, instanceID, id)
|
if id == "" {
|
||||||
|
return nil, zerrors.ThrowInvalidArgument(nil, "COMMAND-Qrz7lvdC4c", "Errors.IDMissing")
|
||||||
|
}
|
||||||
|
smsConfigWriteModel, err := c.getSMSConfig(ctx, resourceOwner, id)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
if !smsConfigWriteModel.State.Exists() {
|
if !smsConfigWriteModel.State.Exists() {
|
||||||
return nil, zerrors.ThrowNotFound(nil, "COMMAND-sn9we", "Errors.SMSConfig.NotFound")
|
return nil, zerrors.ThrowNotFound(nil, "COMMAND-povEVHPCkV", "Errors.SMSConfig.NotFound")
|
||||||
}
|
}
|
||||||
|
|
||||||
iamAgg := InstanceAggregateFromWriteModel(&smsConfigWriteModel.WriteModel)
|
err = c.pushAppendAndReduce(ctx,
|
||||||
pushedEvents, err := c.eventstore.Push(ctx, instance.NewSMSConfigRemovedEvent(
|
smsConfigWriteModel,
|
||||||
|
instance.NewSMSConfigRemovedEvent(
|
||||||
ctx,
|
ctx,
|
||||||
iamAgg,
|
InstanceAggregateFromWriteModel(&smsConfigWriteModel.WriteModel),
|
||||||
id))
|
id,
|
||||||
if err != nil {
|
),
|
||||||
return nil, err
|
)
|
||||||
}
|
|
||||||
err = AppendAndReduce(smsConfigWriteModel, pushedEvents...)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
return writeModelToObjectDetails(&smsConfigWriteModel.WriteModel), nil
|
return writeModelToObjectDetails(&smsConfigWriteModel.WriteModel), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *Commands) getSMSConfig(ctx context.Context, instanceID, id string) (_ *IAMSMSConfigWriteModel, err error) {
|
func (c *Commands) getSMSConfig(ctx context.Context, instanceID, id string) (_ *IAMSMSConfigWriteModel, err error) {
|
||||||
writeModel := NewIAMSMSConfigWriteModel(instanceID, id)
|
writeModel := NewIAMSMSConfigWriteModel(instanceID, id)
|
||||||
err = c.eventstore.FilterToQueryReducer(ctx, writeModel)
|
err = c.eventstore.FilterToQueryReducer(ctx, writeModel)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
return writeModel, nil
|
return writeModel, nil
|
||||||
}
|
}
|
||||||
|
@ -13,7 +13,9 @@ type IAMSMSConfigWriteModel struct {
|
|||||||
eventstore.WriteModel
|
eventstore.WriteModel
|
||||||
|
|
||||||
ID string
|
ID string
|
||||||
|
Description string
|
||||||
Twilio *TwilioConfig
|
Twilio *TwilioConfig
|
||||||
|
HTTP *HTTPConfig
|
||||||
State domain.SMSConfigState
|
State domain.SMSConfigState
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -23,6 +25,10 @@ type TwilioConfig struct {
|
|||||||
SenderNumber string
|
SenderNumber string
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type HTTPConfig struct {
|
||||||
|
Endpoint string
|
||||||
|
}
|
||||||
|
|
||||||
func NewIAMSMSConfigWriteModel(instanceID, id string) *IAMSMSConfigWriteModel {
|
func NewIAMSMSConfigWriteModel(instanceID, id string) *IAMSMSConfigWriteModel {
|
||||||
return &IAMSMSConfigWriteModel{
|
return &IAMSMSConfigWriteModel{
|
||||||
WriteModel: eventstore.WriteModel{
|
WriteModel: eventstore.WriteModel{
|
||||||
@ -46,11 +52,15 @@ func (wm *IAMSMSConfigWriteModel) Reduce() error {
|
|||||||
Token: e.Token,
|
Token: e.Token,
|
||||||
SenderNumber: e.SenderNumber,
|
SenderNumber: e.SenderNumber,
|
||||||
}
|
}
|
||||||
|
wm.Description = e.Description
|
||||||
wm.State = domain.SMSConfigStateInactive
|
wm.State = domain.SMSConfigStateInactive
|
||||||
case *instance.SMSConfigTwilioChangedEvent:
|
case *instance.SMSConfigTwilioChangedEvent:
|
||||||
if wm.ID != e.ID {
|
if wm.ID != e.ID {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
if e.Description != nil {
|
||||||
|
wm.Description = *e.Description
|
||||||
|
}
|
||||||
if e.SID != nil {
|
if e.SID != nil {
|
||||||
wm.Twilio.SID = *e.SID
|
wm.Twilio.SID = *e.SID
|
||||||
}
|
}
|
||||||
@ -62,6 +72,42 @@ func (wm *IAMSMSConfigWriteModel) Reduce() error {
|
|||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
wm.Twilio.Token = e.Token
|
wm.Twilio.Token = e.Token
|
||||||
|
case *instance.SMSConfigHTTPAddedEvent:
|
||||||
|
if wm.ID != e.ID {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
wm.HTTP = &HTTPConfig{
|
||||||
|
Endpoint: e.Endpoint,
|
||||||
|
}
|
||||||
|
wm.Description = e.Description
|
||||||
|
wm.State = domain.SMSConfigStateInactive
|
||||||
|
case *instance.SMSConfigHTTPChangedEvent:
|
||||||
|
if wm.ID != e.ID {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if e.Description != nil {
|
||||||
|
wm.Description = *e.Description
|
||||||
|
}
|
||||||
|
if e.Endpoint != nil {
|
||||||
|
wm.HTTP.Endpoint = *e.Endpoint
|
||||||
|
}
|
||||||
|
case *instance.SMSConfigTwilioActivatedEvent:
|
||||||
|
if wm.ID != e.ID {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
wm.State = domain.SMSConfigStateActive
|
||||||
|
case *instance.SMSConfigTwilioDeactivatedEvent:
|
||||||
|
if wm.ID != e.ID {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
wm.State = domain.SMSConfigStateInactive
|
||||||
|
case *instance.SMSConfigTwilioRemovedEvent:
|
||||||
|
if wm.ID != e.ID {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
wm.Twilio = nil
|
||||||
|
wm.HTTP = nil
|
||||||
|
wm.State = domain.SMSConfigStateRemoved
|
||||||
case *instance.SMSConfigActivatedEvent:
|
case *instance.SMSConfigActivatedEvent:
|
||||||
if wm.ID != e.ID {
|
if wm.ID != e.ID {
|
||||||
continue
|
continue
|
||||||
@ -77,6 +123,7 @@ func (wm *IAMSMSConfigWriteModel) Reduce() error {
|
|||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
wm.Twilio = nil
|
wm.Twilio = nil
|
||||||
|
wm.HTTP = nil
|
||||||
wm.State = domain.SMSConfigStateRemoved
|
wm.State = domain.SMSConfigStateRemoved
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -92,21 +139,33 @@ func (wm *IAMSMSConfigWriteModel) Query() *eventstore.SearchQueryBuilder {
|
|||||||
instance.SMSConfigTwilioAddedEventType,
|
instance.SMSConfigTwilioAddedEventType,
|
||||||
instance.SMSConfigTwilioChangedEventType,
|
instance.SMSConfigTwilioChangedEventType,
|
||||||
instance.SMSConfigTwilioTokenChangedEventType,
|
instance.SMSConfigTwilioTokenChangedEventType,
|
||||||
|
instance.SMSConfigHTTPAddedEventType,
|
||||||
|
instance.SMSConfigHTTPChangedEventType,
|
||||||
|
instance.SMSConfigTwilioActivatedEventType,
|
||||||
|
instance.SMSConfigTwilioDeactivatedEventType,
|
||||||
|
instance.SMSConfigTwilioRemovedEventType,
|
||||||
instance.SMSConfigActivatedEventType,
|
instance.SMSConfigActivatedEventType,
|
||||||
instance.SMSConfigDeactivatedEventType,
|
instance.SMSConfigDeactivatedEventType,
|
||||||
instance.SMSConfigRemovedEventType).
|
instance.SMSConfigRemovedEventType).
|
||||||
Builder()
|
Builder()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (wm *IAMSMSConfigWriteModel) NewChangedEvent(ctx context.Context, aggregate *eventstore.Aggregate, id, sid, senderNumber string) (*instance.SMSConfigTwilioChangedEvent, bool, error) {
|
func (wm *IAMSMSConfigWriteModel) NewTwilioChangedEvent(ctx context.Context, aggregate *eventstore.Aggregate, id string, description, sid, senderNumber *string) (*instance.SMSConfigTwilioChangedEvent, bool, error) {
|
||||||
changes := make([]instance.SMSConfigTwilioChanges, 0)
|
changes := make([]instance.SMSConfigTwilioChanges, 0)
|
||||||
var err error
|
var err error
|
||||||
|
|
||||||
if wm.Twilio.SID != sid {
|
if wm.Twilio == nil {
|
||||||
changes = append(changes, instance.ChangeSMSConfigTwilioSID(sid))
|
return nil, false, nil
|
||||||
}
|
}
|
||||||
if wm.Twilio.SenderNumber != senderNumber {
|
|
||||||
changes = append(changes, instance.ChangeSMSConfigTwilioSenderNumber(senderNumber))
|
if description != nil && wm.Description != *description {
|
||||||
|
changes = append(changes, instance.ChangeSMSConfigTwilioDescription(*description))
|
||||||
|
}
|
||||||
|
if sid != nil && wm.Twilio.SID != *sid {
|
||||||
|
changes = append(changes, instance.ChangeSMSConfigTwilioSID(*sid))
|
||||||
|
}
|
||||||
|
if senderNumber != nil && wm.Twilio.SenderNumber != *senderNumber {
|
||||||
|
changes = append(changes, instance.ChangeSMSConfigTwilioSenderNumber(*senderNumber))
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(changes) == 0 {
|
if len(changes) == 0 {
|
||||||
@ -118,3 +177,28 @@ func (wm *IAMSMSConfigWriteModel) NewChangedEvent(ctx context.Context, aggregate
|
|||||||
}
|
}
|
||||||
return changeEvent, true, nil
|
return changeEvent, true, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (wm *IAMSMSConfigWriteModel) NewHTTPChangedEvent(ctx context.Context, aggregate *eventstore.Aggregate, id string, description, endpoint *string) (*instance.SMSConfigHTTPChangedEvent, bool, error) {
|
||||||
|
changes := make([]instance.SMSConfigHTTPChanges, 0)
|
||||||
|
var err error
|
||||||
|
|
||||||
|
if wm.HTTP == nil {
|
||||||
|
return nil, false, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
if description != nil && wm.Description != *description {
|
||||||
|
changes = append(changes, instance.ChangeSMSConfigHTTPDescription(*description))
|
||||||
|
}
|
||||||
|
if endpoint != nil && wm.HTTP.Endpoint != *endpoint {
|
||||||
|
changes = append(changes, instance.ChangeSMSConfigHTTPEndpoint(*endpoint))
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(changes) == 0 {
|
||||||
|
return nil, false, nil
|
||||||
|
}
|
||||||
|
changeEvent, err := instance.NewSMSConfigHTTPChangedEvent(ctx, aggregate, id, changes)
|
||||||
|
if err != nil {
|
||||||
|
return nil, false, err
|
||||||
|
}
|
||||||
|
return changeEvent, true, nil
|
||||||
|
}
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -953,6 +953,49 @@ func TestCommandSide_ActivateSMTPConfig(t *testing.T) {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
name: "activate smtp config, already active, ok",
|
||||||
|
fields: fields{
|
||||||
|
eventstore: eventstoreExpect(
|
||||||
|
t,
|
||||||
|
expectFilter(
|
||||||
|
eventFromEventPusher(
|
||||||
|
instance.NewSMTPConfigAddedEvent(
|
||||||
|
context.Background(),
|
||||||
|
&instance.NewAggregate("INSTANCE").Aggregate,
|
||||||
|
"ID",
|
||||||
|
"test",
|
||||||
|
true,
|
||||||
|
"from",
|
||||||
|
"name",
|
||||||
|
"",
|
||||||
|
"host:587",
|
||||||
|
"user",
|
||||||
|
&crypto.CryptoValue{},
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
expectPush(
|
||||||
|
instance.NewSMTPConfigActivatedEvent(
|
||||||
|
context.Background(),
|
||||||
|
&instance.NewAggregate("INSTANCE").Aggregate,
|
||||||
|
"ID",
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
},
|
||||||
|
args: args{
|
||||||
|
ctx: authz.WithInstanceID(context.Background(), "INSTANCE"),
|
||||||
|
id: "ID",
|
||||||
|
instanceID: "INSTANCE",
|
||||||
|
activatedId: "",
|
||||||
|
},
|
||||||
|
res: res{
|
||||||
|
want: &domain.ObjectDetails{
|
||||||
|
ResourceOwner: "INSTANCE",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
}
|
}
|
||||||
for _, tt := range tests {
|
for _, tt := range tests {
|
||||||
t.Run(tt.name, func(t *testing.T) {
|
t.Run(tt.name, func(t *testing.T) {
|
||||||
|
@ -5,8 +5,8 @@ import (
|
|||||||
|
|
||||||
"github.com/zitadel/logging"
|
"github.com/zitadel/logging"
|
||||||
|
|
||||||
|
"github.com/zitadel/zitadel/internal/notification/channels/sms"
|
||||||
"github.com/zitadel/zitadel/internal/notification/channels/smtp"
|
"github.com/zitadel/zitadel/internal/notification/channels/smtp"
|
||||||
"github.com/zitadel/zitadel/internal/notification/channels/twilio"
|
|
||||||
"github.com/zitadel/zitadel/internal/notification/channels/webhook"
|
"github.com/zitadel/zitadel/internal/notification/channels/webhook"
|
||||||
"github.com/zitadel/zitadel/internal/notification/handlers"
|
"github.com/zitadel/zitadel/internal/notification/handlers"
|
||||||
"github.com/zitadel/zitadel/internal/notification/senders"
|
"github.com/zitadel/zitadel/internal/notification/senders"
|
||||||
@ -78,20 +78,20 @@ func (c *channels) Email(ctx context.Context) (*senders.Chain, *smtp.Config, err
|
|||||||
return chain, smtpCfg, err
|
return chain, smtpCfg, err
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *channels) SMS(ctx context.Context) (*senders.Chain, *twilio.Config, error) {
|
func (c *channels) SMS(ctx context.Context) (*senders.Chain, *sms.Config, error) {
|
||||||
twilioCfg, err := c.q.GetTwilioConfig(ctx)
|
smsCfg, err := c.q.GetActiveSMSConfig(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, nil, err
|
return nil, nil, err
|
||||||
}
|
}
|
||||||
chain, err := senders.SMSChannels(
|
chain, err := senders.SMSChannels(
|
||||||
ctx,
|
ctx,
|
||||||
twilioCfg,
|
smsCfg,
|
||||||
c.q.GetFileSystemProvider,
|
c.q.GetFileSystemProvider,
|
||||||
c.q.GetLogProvider,
|
c.q.GetLogProvider,
|
||||||
c.counters.success.sms,
|
c.counters.success.sms,
|
||||||
c.counters.failed.sms,
|
c.counters.failed.sms,
|
||||||
)
|
)
|
||||||
return chain, twilioCfg, err
|
return chain, smsCfg, err
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *channels) Webhook(ctx context.Context, cfg webhook.Config) (*senders.Chain, error) {
|
func (c *channels) Webhook(ctx context.Context, cfg webhook.Config) (*senders.Chain, error) {
|
||||||
|
17
internal/notification/channels/sms/config.go
Normal file
17
internal/notification/channels/sms/config.go
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
package sms
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/zitadel/zitadel/internal/notification/channels/twilio"
|
||||||
|
"github.com/zitadel/zitadel/internal/notification/channels/webhook"
|
||||||
|
)
|
||||||
|
|
||||||
|
type Config struct {
|
||||||
|
ProviderConfig *Provider
|
||||||
|
TwilioConfig *twilio.Config
|
||||||
|
WebhookConfig *webhook.Config
|
||||||
|
}
|
||||||
|
|
||||||
|
type Provider struct {
|
||||||
|
ID string `json:"id,omitempty"`
|
||||||
|
Description string `json:"description,omitempty"`
|
||||||
|
}
|
52
internal/notification/handlers/config_sms.go
Normal file
52
internal/notification/handlers/config_sms.go
Normal file
@ -0,0 +1,52 @@
|
|||||||
|
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/sms"
|
||||||
|
"github.com/zitadel/zitadel/internal/notification/channels/twilio"
|
||||||
|
"github.com/zitadel/zitadel/internal/notification/channels/webhook"
|
||||||
|
"github.com/zitadel/zitadel/internal/zerrors"
|
||||||
|
)
|
||||||
|
|
||||||
|
// GetActiveSMSConfig reads the active iam sms provider config
|
||||||
|
func (n *NotificationQueries) GetActiveSMSConfig(ctx context.Context) (*sms.Config, error) {
|
||||||
|
config, err := n.SMSProviderConfigActive(ctx, authz.GetInstance(ctx).InstanceID())
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
provider := &sms.Provider{
|
||||||
|
ID: config.ID,
|
||||||
|
Description: config.Description,
|
||||||
|
}
|
||||||
|
if config.TwilioConfig != nil {
|
||||||
|
token, err := crypto.DecryptString(config.TwilioConfig.Token, n.SMSTokenCrypto)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return &sms.Config{
|
||||||
|
ProviderConfig: provider,
|
||||||
|
TwilioConfig: &twilio.Config{
|
||||||
|
SID: config.TwilioConfig.SID,
|
||||||
|
Token: token,
|
||||||
|
SenderNumber: config.TwilioConfig.SenderNumber,
|
||||||
|
},
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
if config.HTTPConfig != nil {
|
||||||
|
return &sms.Config{
|
||||||
|
ProviderConfig: provider,
|
||||||
|
WebhookConfig: &webhook.Config{
|
||||||
|
CallURL: config.HTTPConfig.Endpoint,
|
||||||
|
Method: http.MethodPost,
|
||||||
|
Headers: nil,
|
||||||
|
},
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil, zerrors.ThrowNotFound(nil, "HANDLER-8nfow", "Errors.SMS.Twilio.NotFound")
|
||||||
|
}
|
@ -1,35 +0,0 @@
|
|||||||
package handlers
|
|
||||||
|
|
||||||
import (
|
|
||||||
"context"
|
|
||||||
|
|
||||||
"github.com/zitadel/zitadel/internal/crypto"
|
|
||||||
"github.com/zitadel/zitadel/internal/domain"
|
|
||||||
"github.com/zitadel/zitadel/internal/notification/channels/twilio"
|
|
||||||
"github.com/zitadel/zitadel/internal/query"
|
|
||||||
"github.com/zitadel/zitadel/internal/zerrors"
|
|
||||||
)
|
|
||||||
|
|
||||||
// GetTwilioConfig reads the iam Twilio provider config
|
|
||||||
func (n *NotificationQueries) GetTwilioConfig(ctx context.Context) (*twilio.Config, error) {
|
|
||||||
active, err := query.NewSMSProviderStateQuery(domain.SMSConfigStateActive)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
config, err := n.SMSProviderConfig(ctx, active)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
if config.TwilioConfig == nil {
|
|
||||||
return nil, zerrors.ThrowNotFound(nil, "HANDLER-8nfow", "Errors.SMS.Twilio.NotFound")
|
|
||||||
}
|
|
||||||
token, err := crypto.DecryptString(config.TwilioConfig.Token, n.SMSTokenCrypto)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
return &twilio.Config{
|
|
||||||
SID: config.TwilioConfig.SID,
|
|
||||||
Token: token,
|
|
||||||
SenderNumber: config.TwilioConfig.SenderNumber,
|
|
||||||
}, nil
|
|
||||||
}
|
|
@ -161,24 +161,19 @@ func (mr *MockQueriesMockRecorder) NotificationProviderByIDAndType(arg0, arg1, a
|
|||||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "NotificationProviderByIDAndType", reflect.TypeOf((*MockQueries)(nil).NotificationProviderByIDAndType), arg0, arg1, arg2)
|
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "NotificationProviderByIDAndType", reflect.TypeOf((*MockQueries)(nil).NotificationProviderByIDAndType), arg0, arg1, arg2)
|
||||||
}
|
}
|
||||||
|
|
||||||
// SMSProviderConfig mocks base method.
|
// SMSProviderConfigActive mocks base method.
|
||||||
func (m *MockQueries) SMSProviderConfig(arg0 context.Context, arg1 ...query.SearchQuery) (*query.SMSConfig, error) {
|
func (m *MockQueries) SMSProviderConfigActive(arg0 context.Context, arg1 string) (*query.SMSConfig, error) {
|
||||||
m.ctrl.T.Helper()
|
m.ctrl.T.Helper()
|
||||||
varargs := []any{arg0}
|
ret := m.ctrl.Call(m, "SMSProviderConfigActive", arg0, arg1)
|
||||||
for _, a := range arg1 {
|
|
||||||
varargs = append(varargs, a)
|
|
||||||
}
|
|
||||||
ret := m.ctrl.Call(m, "SMSProviderConfig", varargs...)
|
|
||||||
ret0, _ := ret[0].(*query.SMSConfig)
|
ret0, _ := ret[0].(*query.SMSConfig)
|
||||||
ret1, _ := ret[1].(error)
|
ret1, _ := ret[1].(error)
|
||||||
return ret0, ret1
|
return ret0, ret1
|
||||||
}
|
}
|
||||||
|
|
||||||
// SMSProviderConfig indicates an expected call of SMSProviderConfig.
|
// SMSProviderConfigActive indicates an expected call of SMSProviderConfigActive.
|
||||||
func (mr *MockQueriesMockRecorder) SMSProviderConfig(arg0 any, arg1 ...any) *gomock.Call {
|
func (mr *MockQueriesMockRecorder) SMSProviderConfigActive(arg0, arg1 any) *gomock.Call {
|
||||||
mr.mock.ctrl.T.Helper()
|
mr.mock.ctrl.T.Helper()
|
||||||
varargs := append([]any{arg0}, arg1...)
|
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SMSProviderConfigActive", reflect.TypeOf((*MockQueries)(nil).SMSProviderConfigActive), arg0, arg1)
|
||||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SMSProviderConfig", reflect.TypeOf((*MockQueries)(nil).SMSProviderConfig), varargs...)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// SMTPConfigActive mocks base method.
|
// SMTPConfigActive mocks base method.
|
||||||
|
@ -21,7 +21,7 @@ type Queries interface {
|
|||||||
NotificationPolicyByOrg(ctx context.Context, shouldTriggerBulk bool, orgID string, withOwnerRemoved bool) (*query.NotificationPolicy, error)
|
NotificationPolicyByOrg(ctx context.Context, shouldTriggerBulk bool, orgID string, withOwnerRemoved bool) (*query.NotificationPolicy, error)
|
||||||
SearchMilestones(ctx context.Context, instanceIDs []string, queries *query.MilestonesSearchQueries) (*query.Milestones, error)
|
SearchMilestones(ctx context.Context, instanceIDs []string, queries *query.MilestonesSearchQueries) (*query.Milestones, error)
|
||||||
NotificationProviderByIDAndType(ctx context.Context, aggID string, providerType domain.NotificationProviderType) (*query.DebugNotificationProvider, error)
|
NotificationProviderByIDAndType(ctx context.Context, aggID string, providerType domain.NotificationProviderType) (*query.DebugNotificationProvider, error)
|
||||||
SMSProviderConfig(ctx context.Context, queries ...query.SearchQuery) (*query.SMSConfig, error)
|
SMSProviderConfigActive(ctx context.Context, resourceOwner string) (config *query.SMSConfig, err error)
|
||||||
SMTPConfigActive(ctx context.Context, resourceOwner string) (*query.SMTPConfig, error)
|
SMTPConfigActive(ctx context.Context, resourceOwner string) (*query.SMTPConfig, error)
|
||||||
GetDefaultLanguage(ctx context.Context) language.Tag
|
GetDefaultLanguage(ctx context.Context) language.Tag
|
||||||
GetInstanceRestrictions(ctx context.Context) (restrictions query.Restrictions, err error)
|
GetInstanceRestrictions(ctx context.Context) (restrictions query.Restrictions, err error)
|
||||||
|
@ -283,7 +283,7 @@ func (u *userNotifier) reducePasswordCodeAdded(event eventstore.Event) (*handler
|
|||||||
}
|
}
|
||||||
notify := types.SendEmail(ctx, u.channels, string(template.Template), translator, notifyUser, colors, e)
|
notify := types.SendEmail(ctx, u.channels, string(template.Template), translator, notifyUser, colors, e)
|
||||||
if e.NotificationType == domain.NotificationTypeSms {
|
if e.NotificationType == domain.NotificationTypeSms {
|
||||||
notify = types.SendSMSTwilio(ctx, u.channels, translator, notifyUser, colors, e)
|
notify = types.SendSMS(ctx, u.channels, translator, notifyUser, colors, e)
|
||||||
}
|
}
|
||||||
err = notify.SendPasswordCode(ctx, notifyUser, code, e.URLTemplate, e.AuthRequestID)
|
err = notify.SendPasswordCode(ctx, notifyUser, code, e.URLTemplate, e.AuthRequestID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -373,7 +373,7 @@ func (u *userNotifier) reduceOTPSMS(
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
notify := types.SendSMSTwilio(ctx, u.channels, translator, notifyUser, colors, event)
|
notify := types.SendSMS(ctx, u.channels, translator, notifyUser, colors, event)
|
||||||
err = notify.SendOTPSMSCode(ctx, plainCode, expiry)
|
err = notify.SendOTPSMSCode(ctx, plainCode, expiry)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
@ -709,7 +709,7 @@ func (u *userNotifier) reducePhoneCodeAdded(event eventstore.Event) (*handler.St
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
err = types.SendSMSTwilio(ctx, u.channels, translator, notifyUser, colors, e).
|
err = types.SendSMS(ctx, u.channels, translator, notifyUser, colors, e).
|
||||||
SendPhoneVerificationCode(ctx, code)
|
SendPhoneVerificationCode(ctx, code)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
|
@ -16,8 +16,8 @@ import (
|
|||||||
"github.com/zitadel/zitadel/internal/eventstore/repository"
|
"github.com/zitadel/zitadel/internal/eventstore/repository"
|
||||||
es_repo_mock "github.com/zitadel/zitadel/internal/eventstore/repository/mock"
|
es_repo_mock "github.com/zitadel/zitadel/internal/eventstore/repository/mock"
|
||||||
channel_mock "github.com/zitadel/zitadel/internal/notification/channels/mock"
|
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"
|
"github.com/zitadel/zitadel/internal/notification/channels/smtp"
|
||||||
"github.com/zitadel/zitadel/internal/notification/channels/twilio"
|
|
||||||
"github.com/zitadel/zitadel/internal/notification/channels/webhook"
|
"github.com/zitadel/zitadel/internal/notification/channels/webhook"
|
||||||
"github.com/zitadel/zitadel/internal/notification/handlers/mock"
|
"github.com/zitadel/zitadel/internal/notification/handlers/mock"
|
||||||
"github.com/zitadel/zitadel/internal/notification/messages"
|
"github.com/zitadel/zitadel/internal/notification/messages"
|
||||||
@ -1463,7 +1463,7 @@ func (c *channels) Email(context.Context) (*senders.Chain, *smtp.Config, error)
|
|||||||
return &c.Chain, nil, nil
|
return &c.Chain, nil, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *channels) SMS(context.Context) (*senders.Chain, *twilio.Config, error) {
|
func (c *channels) SMS(context.Context) (*senders.Chain, *sms.Config, error) {
|
||||||
return &c.Chain, nil, nil
|
return &c.Chain, nil, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3,36 +3,60 @@ package senders
|
|||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
|
||||||
|
"github.com/zitadel/logging"
|
||||||
|
|
||||||
|
"github.com/zitadel/zitadel/internal/api/authz"
|
||||||
"github.com/zitadel/zitadel/internal/notification/channels"
|
"github.com/zitadel/zitadel/internal/notification/channels"
|
||||||
"github.com/zitadel/zitadel/internal/notification/channels/fs"
|
"github.com/zitadel/zitadel/internal/notification/channels/fs"
|
||||||
"github.com/zitadel/zitadel/internal/notification/channels/instrumenting"
|
"github.com/zitadel/zitadel/internal/notification/channels/instrumenting"
|
||||||
"github.com/zitadel/zitadel/internal/notification/channels/log"
|
"github.com/zitadel/zitadel/internal/notification/channels/log"
|
||||||
|
"github.com/zitadel/zitadel/internal/notification/channels/sms"
|
||||||
"github.com/zitadel/zitadel/internal/notification/channels/twilio"
|
"github.com/zitadel/zitadel/internal/notification/channels/twilio"
|
||||||
|
"github.com/zitadel/zitadel/internal/notification/channels/webhook"
|
||||||
)
|
)
|
||||||
|
|
||||||
const twilioSpanName = "twilio.NotificationChannel"
|
const twilioSpanName = "twilio.NotificationChannel"
|
||||||
|
|
||||||
func SMSChannels(
|
func SMSChannels(
|
||||||
ctx context.Context,
|
ctx context.Context,
|
||||||
twilioConfig *twilio.Config,
|
smsConfig *sms.Config,
|
||||||
getFileSystemProvider func(ctx context.Context) (*fs.Config, error),
|
getFileSystemProvider func(ctx context.Context) (*fs.Config, error),
|
||||||
getLogProvider func(ctx context.Context) (*log.Config, error),
|
getLogProvider func(ctx context.Context) (*log.Config, error),
|
||||||
successMetricName,
|
successMetricName,
|
||||||
failureMetricName string,
|
failureMetricName string,
|
||||||
) (chain *Chain, err error) {
|
) (chain *Chain, err error) {
|
||||||
channels := make([]channels.NotificationChannel, 0, 3)
|
channels := make([]channels.NotificationChannel, 0, 3)
|
||||||
if twilioConfig != nil {
|
if smsConfig.TwilioConfig != nil {
|
||||||
channels = append(
|
channels = append(
|
||||||
channels,
|
channels,
|
||||||
instrumenting.Wrap(
|
instrumenting.Wrap(
|
||||||
ctx,
|
ctx,
|
||||||
twilio.InitChannel(*twilioConfig),
|
twilio.InitChannel(*smsConfig.TwilioConfig),
|
||||||
twilioSpanName,
|
twilioSpanName,
|
||||||
successMetricName,
|
successMetricName,
|
||||||
failureMetricName,
|
failureMetricName,
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
if smsConfig.WebhookConfig != nil {
|
||||||
|
webhookChannel, err := webhook.InitChannel(ctx, *smsConfig.WebhookConfig)
|
||||||
|
logging.WithFields(
|
||||||
|
"instance", authz.GetInstance(ctx).InstanceID(),
|
||||||
|
"callurl", smsConfig.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)...)
|
channels = append(channels, debugChannels(ctx, getFileSystemProvider, getLogProvider)...)
|
||||||
return ChainChannels(channels...), nil
|
return ChainChannels(channels...), nil
|
||||||
}
|
}
|
||||||
|
@ -15,23 +15,23 @@ const (
|
|||||||
)
|
)
|
||||||
|
|
||||||
type TemplateData struct {
|
type TemplateData struct {
|
||||||
Title string
|
Title string `json:"title,omitempty"`
|
||||||
PreHeader string
|
PreHeader string `json:"preHeader,omitempty"`
|
||||||
Subject string
|
Subject string `json:"subject,omitempty"`
|
||||||
Greeting string
|
Greeting string `json:"greeting,omitempty"`
|
||||||
Text string
|
Text string `json:"text,omitempty"`
|
||||||
URL string
|
URL string `json:"url,omitempty"`
|
||||||
ButtonText string
|
ButtonText string `json:"buttonText,omitempty"`
|
||||||
PrimaryColor string
|
PrimaryColor string `json:"primaryColor,omitempty"`
|
||||||
BackgroundColor string
|
BackgroundColor string `json:"backgroundColor,omitempty"`
|
||||||
FontColor string
|
FontColor string `json:"fontColor,omitempty"`
|
||||||
LogoURL string
|
LogoURL string `json:"logoUrl,omitempty"`
|
||||||
FontURL string
|
FontURL string `json:"fontUrl,omitempty"`
|
||||||
FontFaceFamily string
|
FontFaceFamily string `json:"fontFaceFamily,omitempty"`
|
||||||
FontFamily string
|
FontFamily string `json:"fontFamily,omitempty"`
|
||||||
|
|
||||||
IncludeFooter bool
|
IncludeFooter bool `json:"includeFooter,omitempty"`
|
||||||
FooterText string
|
FooterText string `json:"footerText,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func (data *TemplateData) Translate(translator *i18n.Translator, msgType string, args map[string]interface{}, langs ...string) {
|
func (data *TemplateData) Translate(translator *i18n.Translator, msgType string, args map[string]interface{}, langs ...string) {
|
||||||
|
@ -7,8 +7,8 @@ import (
|
|||||||
"github.com/zitadel/zitadel/internal/database"
|
"github.com/zitadel/zitadel/internal/database"
|
||||||
"github.com/zitadel/zitadel/internal/eventstore"
|
"github.com/zitadel/zitadel/internal/eventstore"
|
||||||
"github.com/zitadel/zitadel/internal/i18n"
|
"github.com/zitadel/zitadel/internal/i18n"
|
||||||
|
"github.com/zitadel/zitadel/internal/notification/channels/sms"
|
||||||
"github.com/zitadel/zitadel/internal/notification/channels/smtp"
|
"github.com/zitadel/zitadel/internal/notification/channels/smtp"
|
||||||
"github.com/zitadel/zitadel/internal/notification/channels/twilio"
|
|
||||||
"github.com/zitadel/zitadel/internal/notification/channels/webhook"
|
"github.com/zitadel/zitadel/internal/notification/channels/webhook"
|
||||||
"github.com/zitadel/zitadel/internal/notification/senders"
|
"github.com/zitadel/zitadel/internal/notification/senders"
|
||||||
"github.com/zitadel/zitadel/internal/notification/templates"
|
"github.com/zitadel/zitadel/internal/notification/templates"
|
||||||
@ -24,7 +24,7 @@ type Notify func(
|
|||||||
|
|
||||||
type ChannelChains interface {
|
type ChannelChains interface {
|
||||||
Email(context.Context) (*senders.Chain, *smtp.Config, error)
|
Email(context.Context) (*senders.Chain, *smtp.Config, error)
|
||||||
SMS(context.Context) (*senders.Chain, *twilio.Config, error)
|
SMS(context.Context) (*senders.Chain, *sms.Config, error)
|
||||||
Webhook(context.Context, webhook.Config) (*senders.Chain, error)
|
Webhook(context.Context, webhook.Config) (*senders.Chain, error)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -79,7 +79,7 @@ func sanitizeArgsForHTML(args map[string]any) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func SendSMSTwilio(
|
func SendSMS(
|
||||||
ctx context.Context,
|
ctx context.Context,
|
||||||
channels ChannelChains,
|
channels ChannelChains,
|
||||||
translator *i18n.Translator,
|
translator *i18n.Translator,
|
||||||
@ -99,7 +99,8 @@ func SendSMSTwilio(
|
|||||||
ctx,
|
ctx,
|
||||||
channels,
|
channels,
|
||||||
user,
|
user,
|
||||||
data.Text,
|
data,
|
||||||
|
args,
|
||||||
allowUnverifiedNotificationChannel,
|
allowUnverifiedNotificationChannel,
|
||||||
triggeringEvent,
|
triggeringEvent,
|
||||||
)
|
)
|
||||||
|
@ -2,40 +2,78 @@ package types
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
"strings"
|
||||||
|
|
||||||
"github.com/zitadel/logging"
|
"github.com/zitadel/logging"
|
||||||
|
|
||||||
"github.com/zitadel/zitadel/internal/eventstore"
|
"github.com/zitadel/zitadel/internal/eventstore"
|
||||||
"github.com/zitadel/zitadel/internal/notification/messages"
|
"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/query"
|
||||||
"github.com/zitadel/zitadel/internal/zerrors"
|
"github.com/zitadel/zitadel/internal/zerrors"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
type serializableData struct {
|
||||||
|
ContextInfo map[string]interface{} `json:"contextInfo,omitempty"`
|
||||||
|
TemplateData templates.TemplateData `json:"templateData,omitempty"`
|
||||||
|
Args map[string]interface{} `json:"args,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
func generateSms(
|
func generateSms(
|
||||||
ctx context.Context,
|
ctx context.Context,
|
||||||
channels ChannelChains,
|
channels ChannelChains,
|
||||||
user *query.NotifyUser,
|
user *query.NotifyUser,
|
||||||
content string,
|
data templates.TemplateData,
|
||||||
|
args map[string]interface{},
|
||||||
lastPhone bool,
|
lastPhone bool,
|
||||||
triggeringEvent eventstore.Event,
|
triggeringEvent eventstore.Event,
|
||||||
) error {
|
) error {
|
||||||
number := ""
|
smsChannels, config, err := channels.SMS(ctx)
|
||||||
smsChannels, twilioConfig, err := channels.SMS(ctx)
|
|
||||||
logging.OnError(err).Error("could not create sms channel")
|
logging.OnError(err).Error("could not create sms channel")
|
||||||
if smsChannels == nil || smsChannels.Len() == 0 {
|
if smsChannels == nil || smsChannels.Len() == 0 {
|
||||||
return zerrors.ThrowPreconditionFailed(nil, "PHONE-w8nfow", "Errors.Notification.Channels.NotPresent")
|
return zerrors.ThrowPreconditionFailed(nil, "PHONE-w8nfow", "Errors.Notification.Channels.NotPresent")
|
||||||
}
|
}
|
||||||
|
recipient := user.VerifiedPhone
|
||||||
|
if lastPhone {
|
||||||
|
recipient = user.LastPhone
|
||||||
|
}
|
||||||
|
if config.TwilioConfig != nil {
|
||||||
|
number := ""
|
||||||
if err == nil {
|
if err == nil {
|
||||||
number = twilioConfig.SenderNumber
|
number = config.TwilioConfig.SenderNumber
|
||||||
}
|
}
|
||||||
message := &messages.SMS{
|
message := &messages.SMS{
|
||||||
SenderPhoneNumber: number,
|
SenderPhoneNumber: number,
|
||||||
RecipientPhoneNumber: user.VerifiedPhone,
|
RecipientPhoneNumber: recipient,
|
||||||
Content: content,
|
Content: data.Text,
|
||||||
TriggeringEvent: triggeringEvent,
|
TriggeringEvent: triggeringEvent,
|
||||||
}
|
}
|
||||||
if lastPhone {
|
|
||||||
message.RecipientPhoneNumber = user.LastPhone
|
|
||||||
}
|
|
||||||
return smsChannels.HandleMessage(message)
|
return smsChannels.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{}{
|
||||||
|
"recipientPhoneNumber": recipient,
|
||||||
|
"eventType": triggeringEvent.Type(),
|
||||||
|
"provider": config.ProviderConfig,
|
||||||
|
}
|
||||||
|
|
||||||
|
message := &messages.JSON{
|
||||||
|
Serializable: &serializableData{
|
||||||
|
TemplateData: data,
|
||||||
|
Args: caseArgs,
|
||||||
|
ContextInfo: contextInfo,
|
||||||
|
},
|
||||||
|
TriggeringEvent: triggeringEvent,
|
||||||
|
}
|
||||||
|
webhookChannels, err := channels.Webhook(ctx, *config.WebhookConfig)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return webhookChannels.HandleMessage(message)
|
||||||
|
}
|
||||||
|
return zerrors.ThrowPreconditionFailed(nil, "PHONE-w8nfow", "Errors.Notification.Channels.NotPresent")
|
||||||
}
|
}
|
||||||
|
@ -8,12 +8,12 @@ import (
|
|||||||
old_handler "github.com/zitadel/zitadel/internal/eventstore/handler"
|
old_handler "github.com/zitadel/zitadel/internal/eventstore/handler"
|
||||||
"github.com/zitadel/zitadel/internal/eventstore/handler/v2"
|
"github.com/zitadel/zitadel/internal/eventstore/handler/v2"
|
||||||
"github.com/zitadel/zitadel/internal/repository/instance"
|
"github.com/zitadel/zitadel/internal/repository/instance"
|
||||||
"github.com/zitadel/zitadel/internal/zerrors"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
SMSConfigProjectionTable = "projections.sms_configs2"
|
SMSConfigProjectionTable = "projections.sms_configs3"
|
||||||
SMSTwilioTable = SMSConfigProjectionTable + "_" + smsTwilioTableSuffix
|
SMSTwilioTable = SMSConfigProjectionTable + "_" + smsTwilioTableSuffix
|
||||||
|
SMSHTTPTable = SMSConfigProjectionTable + "_" + smsHTTPTableSuffix
|
||||||
|
|
||||||
SMSColumnID = "id"
|
SMSColumnID = "id"
|
||||||
SMSColumnAggregateID = "aggregate_id"
|
SMSColumnAggregateID = "aggregate_id"
|
||||||
@ -23,13 +23,19 @@ const (
|
|||||||
SMSColumnState = "state"
|
SMSColumnState = "state"
|
||||||
SMSColumnResourceOwner = "resource_owner"
|
SMSColumnResourceOwner = "resource_owner"
|
||||||
SMSColumnInstanceID = "instance_id"
|
SMSColumnInstanceID = "instance_id"
|
||||||
|
SMSColumnDescription = "description"
|
||||||
|
|
||||||
smsTwilioTableSuffix = "twilio"
|
smsTwilioTableSuffix = "twilio"
|
||||||
SMSTwilioConfigColumnSMSID = "sms_id"
|
SMSTwilioColumnSMSID = "sms_id"
|
||||||
SMSTwilioColumnInstanceID = "instance_id"
|
SMSTwilioColumnInstanceID = "instance_id"
|
||||||
SMSTwilioConfigColumnSID = "sid"
|
SMSTwilioColumnSID = "sid"
|
||||||
SMSTwilioConfigColumnSenderNumber = "sender_number"
|
SMSTwilioColumnSenderNumber = "sender_number"
|
||||||
SMSTwilioConfigColumnToken = "token"
|
SMSTwilioColumnToken = "token"
|
||||||
|
|
||||||
|
smsHTTPTableSuffix = "http"
|
||||||
|
SMSHTTPColumnSMSID = "sms_id"
|
||||||
|
SMSHTTPColumnInstanceID = "instance_id"
|
||||||
|
SMSHTTPColumnEndpoint = "endpoint"
|
||||||
)
|
)
|
||||||
|
|
||||||
type smsConfigProjection struct{}
|
type smsConfigProjection struct{}
|
||||||
@ -53,20 +59,30 @@ func (*smsConfigProjection) Init() *old_handler.Check {
|
|||||||
handler.NewColumn(SMSColumnState, handler.ColumnTypeEnum),
|
handler.NewColumn(SMSColumnState, handler.ColumnTypeEnum),
|
||||||
handler.NewColumn(SMSColumnResourceOwner, handler.ColumnTypeText),
|
handler.NewColumn(SMSColumnResourceOwner, handler.ColumnTypeText),
|
||||||
handler.NewColumn(SMSColumnInstanceID, handler.ColumnTypeText),
|
handler.NewColumn(SMSColumnInstanceID, handler.ColumnTypeText),
|
||||||
|
handler.NewColumn(SMSColumnDescription, handler.ColumnTypeText),
|
||||||
},
|
},
|
||||||
handler.NewPrimaryKey(SMSColumnInstanceID, SMSColumnID),
|
handler.NewPrimaryKey(SMSColumnInstanceID, SMSColumnID),
|
||||||
),
|
),
|
||||||
handler.NewSuffixedTable([]*handler.InitColumn{
|
handler.NewSuffixedTable([]*handler.InitColumn{
|
||||||
handler.NewColumn(SMSTwilioConfigColumnSMSID, handler.ColumnTypeText),
|
handler.NewColumn(SMSTwilioColumnSMSID, handler.ColumnTypeText),
|
||||||
handler.NewColumn(SMSTwilioColumnInstanceID, handler.ColumnTypeText),
|
handler.NewColumn(SMSTwilioColumnInstanceID, handler.ColumnTypeText),
|
||||||
handler.NewColumn(SMSTwilioConfigColumnSID, handler.ColumnTypeText),
|
handler.NewColumn(SMSTwilioColumnSID, handler.ColumnTypeText),
|
||||||
handler.NewColumn(SMSTwilioConfigColumnSenderNumber, handler.ColumnTypeText),
|
handler.NewColumn(SMSTwilioColumnSenderNumber, handler.ColumnTypeText),
|
||||||
handler.NewColumn(SMSTwilioConfigColumnToken, handler.ColumnTypeJSONB),
|
handler.NewColumn(SMSTwilioColumnToken, handler.ColumnTypeJSONB),
|
||||||
},
|
},
|
||||||
handler.NewPrimaryKey(SMSTwilioColumnInstanceID, SMSTwilioConfigColumnSMSID),
|
handler.NewPrimaryKey(SMSTwilioColumnInstanceID, SMSTwilioColumnSMSID),
|
||||||
smsTwilioTableSuffix,
|
smsTwilioTableSuffix,
|
||||||
handler.WithForeignKey(handler.NewForeignKeyOfPublicKeys()),
|
handler.WithForeignKey(handler.NewForeignKeyOfPublicKeys()),
|
||||||
),
|
),
|
||||||
|
handler.NewSuffixedTable([]*handler.InitColumn{
|
||||||
|
handler.NewColumn(SMSHTTPColumnSMSID, handler.ColumnTypeText),
|
||||||
|
handler.NewColumn(SMSHTTPColumnInstanceID, handler.ColumnTypeText),
|
||||||
|
handler.NewColumn(SMSHTTPColumnEndpoint, handler.ColumnTypeText),
|
||||||
|
},
|
||||||
|
handler.NewPrimaryKey(SMSHTTPColumnInstanceID, SMSHTTPColumnSMSID),
|
||||||
|
smsHTTPTableSuffix,
|
||||||
|
handler.WithForeignKey(handler.NewForeignKeyOfPublicKeys()),
|
||||||
|
),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -87,6 +103,26 @@ func (p *smsConfigProjection) Reducers() []handler.AggregateReducer {
|
|||||||
Event: instance.SMSConfigTwilioTokenChangedEventType,
|
Event: instance.SMSConfigTwilioTokenChangedEventType,
|
||||||
Reduce: p.reduceSMSConfigTwilioTokenChanged,
|
Reduce: p.reduceSMSConfigTwilioTokenChanged,
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
Event: instance.SMSConfigHTTPAddedEventType,
|
||||||
|
Reduce: p.reduceSMSConfigHTTPAdded,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Event: instance.SMSConfigHTTPChangedEventType,
|
||||||
|
Reduce: p.reduceSMSConfigHTTPChanged,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Event: instance.SMSConfigTwilioActivatedEventType,
|
||||||
|
Reduce: p.reduceSMSConfigTwilioActivated,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Event: instance.SMSConfigTwilioDeactivatedEventType,
|
||||||
|
Reduce: p.reduceSMSConfigTwilioDeactivated,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Event: instance.SMSConfigTwilioRemovedEventType,
|
||||||
|
Reduce: p.reduceSMSConfigTwilioRemoved,
|
||||||
|
},
|
||||||
{
|
{
|
||||||
Event: instance.SMSConfigActivatedEventType,
|
Event: instance.SMSConfigActivatedEventType,
|
||||||
Reduce: p.reduceSMSConfigActivated,
|
Reduce: p.reduceSMSConfigActivated,
|
||||||
@ -109,9 +145,9 @@ func (p *smsConfigProjection) Reducers() []handler.AggregateReducer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (p *smsConfigProjection) reduceSMSConfigTwilioAdded(event eventstore.Event) (*handler.Statement, error) {
|
func (p *smsConfigProjection) reduceSMSConfigTwilioAdded(event eventstore.Event) (*handler.Statement, error) {
|
||||||
e, ok := event.(*instance.SMSConfigTwilioAddedEvent)
|
e, err := assertEvent[*instance.SMSConfigTwilioAddedEvent](event)
|
||||||
if !ok {
|
if err != nil {
|
||||||
return nil, zerrors.ThrowInvalidArgumentf(nil, "HANDL-s8efs", "reduce.wrong.event.type %s", instance.SMSConfigTwilioAddedEventType)
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
return handler.NewMultiStatement(
|
return handler.NewMultiStatement(
|
||||||
@ -126,15 +162,16 @@ func (p *smsConfigProjection) reduceSMSConfigTwilioAdded(event eventstore.Event)
|
|||||||
handler.NewCol(SMSColumnInstanceID, e.Aggregate().InstanceID),
|
handler.NewCol(SMSColumnInstanceID, e.Aggregate().InstanceID),
|
||||||
handler.NewCol(SMSColumnState, domain.SMSConfigStateInactive),
|
handler.NewCol(SMSColumnState, domain.SMSConfigStateInactive),
|
||||||
handler.NewCol(SMSColumnSequence, e.Sequence()),
|
handler.NewCol(SMSColumnSequence, e.Sequence()),
|
||||||
|
handler.NewCol(SMSColumnDescription, e.Description),
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
handler.AddCreateStatement(
|
handler.AddCreateStatement(
|
||||||
[]handler.Column{
|
[]handler.Column{
|
||||||
handler.NewCol(SMSTwilioConfigColumnSMSID, e.ID),
|
handler.NewCol(SMSTwilioColumnSMSID, e.ID),
|
||||||
handler.NewCol(SMSTwilioColumnInstanceID, e.Aggregate().InstanceID),
|
handler.NewCol(SMSTwilioColumnInstanceID, e.Aggregate().InstanceID),
|
||||||
handler.NewCol(SMSTwilioConfigColumnSID, e.SID),
|
handler.NewCol(SMSTwilioColumnSID, e.SID),
|
||||||
handler.NewCol(SMSTwilioConfigColumnToken, e.Token),
|
handler.NewCol(SMSTwilioColumnToken, e.Token),
|
||||||
handler.NewCol(SMSTwilioConfigColumnSenderNumber, e.SenderNumber),
|
handler.NewCol(SMSTwilioColumnSenderNumber, e.SenderNumber),
|
||||||
},
|
},
|
||||||
handler.WithTableSuffix(smsTwilioTableSuffix),
|
handler.WithTableSuffix(smsTwilioTableSuffix),
|
||||||
),
|
),
|
||||||
@ -142,57 +179,64 @@ func (p *smsConfigProjection) reduceSMSConfigTwilioAdded(event eventstore.Event)
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (p *smsConfigProjection) reduceSMSConfigTwilioChanged(event eventstore.Event) (*handler.Statement, error) {
|
func (p *smsConfigProjection) reduceSMSConfigTwilioChanged(event eventstore.Event) (*handler.Statement, error) {
|
||||||
e, ok := event.(*instance.SMSConfigTwilioChangedEvent)
|
e, err := assertEvent[*instance.SMSConfigTwilioChangedEvent](event)
|
||||||
if !ok {
|
if err != nil {
|
||||||
return nil, zerrors.ThrowInvalidArgumentf(nil, "HANDL-fi99F", "reduce.wrong.event.type %s", instance.SMSConfigTwilioChangedEventType)
|
return nil, err
|
||||||
}
|
|
||||||
columns := make([]handler.Column, 0)
|
|
||||||
if e.SID != nil {
|
|
||||||
columns = append(columns, handler.NewCol(SMSTwilioConfigColumnSID, *e.SID))
|
|
||||||
}
|
|
||||||
if e.SenderNumber != nil {
|
|
||||||
columns = append(columns, handler.NewCol(SMSTwilioConfigColumnSenderNumber, *e.SenderNumber))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return handler.NewMultiStatement(
|
stmts := make([]func(eventstore.Event) handler.Exec, 0, 3)
|
||||||
e,
|
columns := []handler.Column{
|
||||||
handler.AddUpdateStatement(
|
|
||||||
columns,
|
|
||||||
[]handler.Condition{
|
|
||||||
handler.NewCond(SMSTwilioConfigColumnSMSID, e.ID),
|
|
||||||
handler.NewCond(SMSTwilioColumnInstanceID, e.Aggregate().InstanceID),
|
|
||||||
},
|
|
||||||
handler.WithTableSuffix(smsTwilioTableSuffix),
|
|
||||||
),
|
|
||||||
handler.AddUpdateStatement(
|
|
||||||
[]handler.Column{
|
|
||||||
handler.NewCol(SMSColumnChangeDate, e.CreationDate()),
|
handler.NewCol(SMSColumnChangeDate, e.CreationDate()),
|
||||||
handler.NewCol(SMSColumnSequence, e.Sequence()),
|
handler.NewCol(SMSColumnSequence, e.Sequence()),
|
||||||
},
|
}
|
||||||
|
if e.Description != nil {
|
||||||
|
columns = append(columns, handler.NewCol(SMSColumnDescription, *e.Description))
|
||||||
|
}
|
||||||
|
if len(columns) > 0 {
|
||||||
|
stmts = append(stmts, handler.AddUpdateStatement(
|
||||||
|
columns,
|
||||||
[]handler.Condition{
|
[]handler.Condition{
|
||||||
handler.NewCond(SMSColumnID, e.ID),
|
handler.NewCond(SMSColumnID, e.ID),
|
||||||
handler.NewCond(SMSColumnInstanceID, e.Aggregate().InstanceID),
|
handler.NewCond(SMSColumnInstanceID, e.Aggregate().InstanceID),
|
||||||
},
|
},
|
||||||
),
|
))
|
||||||
), nil
|
}
|
||||||
|
|
||||||
|
twilioColumns := make([]handler.Column, 0)
|
||||||
|
if e.SID != nil {
|
||||||
|
twilioColumns = append(twilioColumns, handler.NewCol(SMSTwilioColumnSID, *e.SID))
|
||||||
|
}
|
||||||
|
if e.SenderNumber != nil {
|
||||||
|
twilioColumns = append(twilioColumns, handler.NewCol(SMSTwilioColumnSenderNumber, *e.SenderNumber))
|
||||||
|
}
|
||||||
|
if len(twilioColumns) > 0 {
|
||||||
|
stmts = append(stmts, handler.AddUpdateStatement(
|
||||||
|
twilioColumns,
|
||||||
|
[]handler.Condition{
|
||||||
|
handler.NewCond(SMSTwilioColumnSMSID, e.ID),
|
||||||
|
handler.NewCond(SMSTwilioColumnInstanceID, e.Aggregate().InstanceID),
|
||||||
|
},
|
||||||
|
handler.WithTableSuffix(smsTwilioTableSuffix),
|
||||||
|
))
|
||||||
|
}
|
||||||
|
|
||||||
|
return handler.NewMultiStatement(e, stmts...), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *smsConfigProjection) reduceSMSConfigTwilioTokenChanged(event eventstore.Event) (*handler.Statement, error) {
|
func (p *smsConfigProjection) reduceSMSConfigTwilioTokenChanged(event eventstore.Event) (*handler.Statement, error) {
|
||||||
e, ok := event.(*instance.SMSConfigTwilioTokenChangedEvent)
|
e, err := assertEvent[*instance.SMSConfigTwilioTokenChangedEvent](event)
|
||||||
if !ok {
|
if err != nil {
|
||||||
return nil, zerrors.ThrowInvalidArgumentf(nil, "HANDL-fi99F", "reduce.wrong.event.type %s", instance.SMSConfigTwilioTokenChangedEventType)
|
return nil, err
|
||||||
}
|
|
||||||
columns := make([]handler.Column, 0)
|
|
||||||
if e.Token != nil {
|
|
||||||
columns = append(columns, handler.NewCol(SMSTwilioConfigColumnToken, e.Token))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return handler.NewMultiStatement(
|
return handler.NewMultiStatement(
|
||||||
e,
|
e,
|
||||||
handler.AddUpdateStatement(
|
handler.AddUpdateStatement(
|
||||||
columns,
|
[]handler.Column{
|
||||||
|
handler.NewCol(SMSTwilioColumnToken, e.Token),
|
||||||
|
},
|
||||||
[]handler.Condition{
|
[]handler.Condition{
|
||||||
handler.NewCond(SMSTwilioConfigColumnSMSID, e.ID),
|
handler.NewCond(SMSTwilioColumnSMSID, e.ID),
|
||||||
handler.NewCond(SMSTwilioColumnInstanceID, e.Aggregate().InstanceID),
|
handler.NewCond(SMSTwilioColumnInstanceID, e.Aggregate().InstanceID),
|
||||||
},
|
},
|
||||||
handler.WithTableSuffix(smsTwilioTableSuffix),
|
handler.WithTableSuffix(smsTwilioTableSuffix),
|
||||||
@ -210,13 +254,99 @@ func (p *smsConfigProjection) reduceSMSConfigTwilioTokenChanged(event eventstore
|
|||||||
), nil
|
), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *smsConfigProjection) reduceSMSConfigActivated(event eventstore.Event) (*handler.Statement, error) {
|
func (p *smsConfigProjection) reduceSMSConfigHTTPAdded(event eventstore.Event) (*handler.Statement, error) {
|
||||||
e, ok := event.(*instance.SMSConfigActivatedEvent)
|
e, err := assertEvent[*instance.SMSConfigHTTPAddedEvent](event)
|
||||||
if !ok {
|
if err != nil {
|
||||||
return nil, zerrors.ThrowInvalidArgumentf(nil, "HANDL-fj9Ef", "reduce.wrong.event.type %s", instance.SMSConfigActivatedEventType)
|
return nil, err
|
||||||
}
|
}
|
||||||
return handler.NewUpdateStatement(
|
|
||||||
|
return handler.NewMultiStatement(
|
||||||
e,
|
e,
|
||||||
|
handler.AddCreateStatement(
|
||||||
|
[]handler.Column{
|
||||||
|
handler.NewCol(SMSColumnID, e.ID),
|
||||||
|
handler.NewCol(SMSColumnAggregateID, e.Aggregate().ID),
|
||||||
|
handler.NewCol(SMSColumnCreationDate, e.CreationDate()),
|
||||||
|
handler.NewCol(SMSColumnChangeDate, e.CreationDate()),
|
||||||
|
handler.NewCol(SMSColumnResourceOwner, e.Aggregate().ResourceOwner),
|
||||||
|
handler.NewCol(SMSColumnInstanceID, e.Aggregate().InstanceID),
|
||||||
|
handler.NewCol(SMSColumnState, domain.SMSConfigStateInactive),
|
||||||
|
handler.NewCol(SMSColumnSequence, e.Sequence()),
|
||||||
|
handler.NewCol(SMSColumnDescription, e.Description),
|
||||||
|
},
|
||||||
|
),
|
||||||
|
handler.AddCreateStatement(
|
||||||
|
[]handler.Column{
|
||||||
|
handler.NewCol(SMSHTTPColumnSMSID, e.ID),
|
||||||
|
handler.NewCol(SMSHTTPColumnInstanceID, e.Aggregate().InstanceID),
|
||||||
|
handler.NewCol(SMSHTTPColumnEndpoint, e.Endpoint),
|
||||||
|
},
|
||||||
|
handler.WithTableSuffix(smsHTTPTableSuffix),
|
||||||
|
),
|
||||||
|
), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *smsConfigProjection) reduceSMSConfigHTTPChanged(event eventstore.Event) (*handler.Statement, error) {
|
||||||
|
e, err := assertEvent[*instance.SMSConfigHTTPChangedEvent](event)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
stmts := make([]func(eventstore.Event) handler.Exec, 0, 3)
|
||||||
|
columns := []handler.Column{
|
||||||
|
handler.NewCol(SMSColumnChangeDate, e.CreationDate()),
|
||||||
|
handler.NewCol(SMSColumnSequence, e.Sequence()),
|
||||||
|
}
|
||||||
|
if e.Description != nil {
|
||||||
|
columns = append(columns, handler.NewCol(SMSColumnDescription, *e.Description))
|
||||||
|
}
|
||||||
|
if len(columns) > 0 {
|
||||||
|
stmts = append(stmts, handler.AddUpdateStatement(
|
||||||
|
columns,
|
||||||
|
[]handler.Condition{
|
||||||
|
handler.NewCond(SMSColumnID, e.ID),
|
||||||
|
handler.NewCond(SMSColumnInstanceID, e.Aggregate().InstanceID),
|
||||||
|
},
|
||||||
|
))
|
||||||
|
}
|
||||||
|
|
||||||
|
if e.Endpoint != nil {
|
||||||
|
stmts = append(stmts, handler.AddUpdateStatement(
|
||||||
|
[]handler.Column{
|
||||||
|
handler.NewCol(SMSHTTPColumnEndpoint, *e.Endpoint),
|
||||||
|
},
|
||||||
|
[]handler.Condition{
|
||||||
|
handler.NewCond(SMSHTTPColumnSMSID, e.ID),
|
||||||
|
handler.NewCond(SMSHTTPColumnInstanceID, e.Aggregate().InstanceID),
|
||||||
|
},
|
||||||
|
handler.WithTableSuffix(smsHTTPTableSuffix),
|
||||||
|
))
|
||||||
|
}
|
||||||
|
|
||||||
|
return handler.NewMultiStatement(e, stmts...), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *smsConfigProjection) reduceSMSConfigTwilioActivated(event eventstore.Event) (*handler.Statement, error) {
|
||||||
|
e, err := assertEvent[*instance.SMSConfigTwilioActivatedEvent](event)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return handler.NewMultiStatement(
|
||||||
|
e,
|
||||||
|
handler.AddUpdateStatement(
|
||||||
|
[]handler.Column{
|
||||||
|
handler.NewCol(SMSColumnState, domain.SMSConfigStateInactive),
|
||||||
|
handler.NewCol(SMSColumnChangeDate, e.CreationDate()),
|
||||||
|
handler.NewCol(SMSColumnSequence, e.Sequence()),
|
||||||
|
},
|
||||||
|
[]handler.Condition{
|
||||||
|
handler.Not(handler.NewCond(SMSColumnID, e.ID)),
|
||||||
|
handler.NewCond(SMSColumnState, domain.SMSConfigStateActive),
|
||||||
|
handler.NewCond(SMSColumnInstanceID, e.Aggregate().InstanceID),
|
||||||
|
},
|
||||||
|
),
|
||||||
|
handler.AddUpdateStatement(
|
||||||
[]handler.Column{
|
[]handler.Column{
|
||||||
handler.NewCol(SMSColumnState, domain.SMSConfigStateActive),
|
handler.NewCol(SMSColumnState, domain.SMSConfigStateActive),
|
||||||
handler.NewCol(SMSColumnChangeDate, e.CreationDate()),
|
handler.NewCol(SMSColumnChangeDate, e.CreationDate()),
|
||||||
@ -226,14 +356,85 @@ func (p *smsConfigProjection) reduceSMSConfigActivated(event eventstore.Event) (
|
|||||||
handler.NewCond(SMSColumnID, e.ID),
|
handler.NewCond(SMSColumnID, e.ID),
|
||||||
handler.NewCond(SMSColumnInstanceID, e.Aggregate().InstanceID),
|
handler.NewCond(SMSColumnInstanceID, e.Aggregate().InstanceID),
|
||||||
},
|
},
|
||||||
|
),
|
||||||
|
), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *smsConfigProjection) reduceSMSConfigTwilioDeactivated(event eventstore.Event) (*handler.Statement, error) {
|
||||||
|
e, err := assertEvent[*instance.SMSConfigTwilioDeactivatedEvent](event)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return handler.NewUpdateStatement(
|
||||||
|
e,
|
||||||
|
[]handler.Column{
|
||||||
|
handler.NewCol(SMSColumnState, domain.SMSConfigStateInactive),
|
||||||
|
handler.NewCol(SMSColumnChangeDate, e.CreationDate()),
|
||||||
|
handler.NewCol(SMSColumnSequence, e.Sequence()),
|
||||||
|
},
|
||||||
|
[]handler.Condition{
|
||||||
|
handler.NewCond(SMSColumnID, e.ID),
|
||||||
|
handler.NewCond(SMSColumnInstanceID, e.Aggregate().InstanceID),
|
||||||
|
},
|
||||||
|
), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *smsConfigProjection) reduceSMSConfigTwilioRemoved(event eventstore.Event) (*handler.Statement, error) {
|
||||||
|
e, err := assertEvent[*instance.SMSConfigTwilioRemovedEvent](event)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return handler.NewDeleteStatement(
|
||||||
|
e,
|
||||||
|
[]handler.Condition{
|
||||||
|
handler.NewCond(SMSColumnID, e.ID),
|
||||||
|
handler.NewCond(SMSColumnInstanceID, e.Aggregate().InstanceID),
|
||||||
|
},
|
||||||
|
), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *smsConfigProjection) reduceSMSConfigActivated(event eventstore.Event) (*handler.Statement, error) {
|
||||||
|
e, err := assertEvent[*instance.SMSConfigActivatedEvent](event)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return handler.NewMultiStatement(
|
||||||
|
e,
|
||||||
|
handler.AddUpdateStatement(
|
||||||
|
[]handler.Column{
|
||||||
|
handler.NewCol(SMSColumnState, domain.SMSConfigStateInactive),
|
||||||
|
handler.NewCol(SMSColumnChangeDate, e.CreationDate()),
|
||||||
|
handler.NewCol(SMSColumnSequence, e.Sequence()),
|
||||||
|
},
|
||||||
|
[]handler.Condition{
|
||||||
|
handler.Not(handler.NewCond(SMSColumnID, e.ID)),
|
||||||
|
handler.NewCond(SMSColumnState, domain.SMSConfigStateActive),
|
||||||
|
handler.NewCond(SMSColumnInstanceID, e.Aggregate().InstanceID),
|
||||||
|
},
|
||||||
|
),
|
||||||
|
handler.AddUpdateStatement(
|
||||||
|
[]handler.Column{
|
||||||
|
handler.NewCol(SMSColumnState, domain.SMSConfigStateActive),
|
||||||
|
handler.NewCol(SMSColumnChangeDate, e.CreationDate()),
|
||||||
|
handler.NewCol(SMSColumnSequence, e.Sequence()),
|
||||||
|
},
|
||||||
|
[]handler.Condition{
|
||||||
|
handler.NewCond(SMSColumnID, e.ID),
|
||||||
|
handler.NewCond(SMSColumnInstanceID, e.Aggregate().InstanceID),
|
||||||
|
},
|
||||||
|
),
|
||||||
), nil
|
), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *smsConfigProjection) reduceSMSConfigDeactivated(event eventstore.Event) (*handler.Statement, error) {
|
func (p *smsConfigProjection) reduceSMSConfigDeactivated(event eventstore.Event) (*handler.Statement, error) {
|
||||||
e, ok := event.(*instance.SMSConfigDeactivatedEvent)
|
e, err := assertEvent[*instance.SMSConfigDeactivatedEvent](event)
|
||||||
if !ok {
|
if err != nil {
|
||||||
return nil, zerrors.ThrowInvalidArgumentf(nil, "HANDL-dj9Js", "reduce.wrong.event.type %s", instance.SMSConfigDeactivatedEventType)
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
return handler.NewUpdateStatement(
|
return handler.NewUpdateStatement(
|
||||||
e,
|
e,
|
||||||
[]handler.Column{
|
[]handler.Column{
|
||||||
@ -249,10 +450,11 @@ func (p *smsConfigProjection) reduceSMSConfigDeactivated(event eventstore.Event)
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (p *smsConfigProjection) reduceSMSConfigRemoved(event eventstore.Event) (*handler.Statement, error) {
|
func (p *smsConfigProjection) reduceSMSConfigRemoved(event eventstore.Event) (*handler.Statement, error) {
|
||||||
e, ok := event.(*instance.SMSConfigRemovedEvent)
|
e, err := assertEvent[*instance.SMSConfigRemovedEvent](event)
|
||||||
if !ok {
|
if err != nil {
|
||||||
return nil, zerrors.ThrowInvalidArgumentf(nil, "HANDL-s9JJf", "reduce.wrong.event.type %s", instance.SMSConfigRemovedEventType)
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
return handler.NewDeleteStatement(
|
return handler.NewDeleteStatement(
|
||||||
e,
|
e,
|
||||||
[]handler.Condition{
|
[]handler.Condition{
|
||||||
|
@ -37,9 +37,10 @@ func TestSMSProjection_reduces(t *testing.T) {
|
|||||||
"keyId": "key-id",
|
"keyId": "key-id",
|
||||||
"crypted": "Y3J5cHRlZA=="
|
"crypted": "Y3J5cHRlZA=="
|
||||||
},
|
},
|
||||||
"senderNumber": "sender-number"
|
"senderNumber": "sender-number",
|
||||||
|
"description": "description"
|
||||||
}`),
|
}`),
|
||||||
), instance.SMSConfigTwilioAddedEventMapper),
|
), eventstore.GenericEventMapper[instance.SMSConfigTwilioAddedEvent]),
|
||||||
},
|
},
|
||||||
reduce: (&smsConfigProjection{}).reduceSMSConfigTwilioAdded,
|
reduce: (&smsConfigProjection{}).reduceSMSConfigTwilioAdded,
|
||||||
want: wantReduce{
|
want: wantReduce{
|
||||||
@ -48,7 +49,7 @@ func TestSMSProjection_reduces(t *testing.T) {
|
|||||||
executer: &testExecuter{
|
executer: &testExecuter{
|
||||||
executions: []execution{
|
executions: []execution{
|
||||||
{
|
{
|
||||||
expectedStmt: "INSERT INTO projections.sms_configs2 (id, aggregate_id, creation_date, change_date, resource_owner, instance_id, state, sequence) VALUES ($1, $2, $3, $4, $5, $6, $7, $8)",
|
expectedStmt: "INSERT INTO projections.sms_configs3 (id, aggregate_id, creation_date, change_date, resource_owner, instance_id, state, sequence, description) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9)",
|
||||||
expectedArgs: []interface{}{
|
expectedArgs: []interface{}{
|
||||||
"id",
|
"id",
|
||||||
"agg-id",
|
"agg-id",
|
||||||
@ -58,10 +59,11 @@ func TestSMSProjection_reduces(t *testing.T) {
|
|||||||
"instance-id",
|
"instance-id",
|
||||||
domain.SMSConfigStateInactive,
|
domain.SMSConfigStateInactive,
|
||||||
uint64(15),
|
uint64(15),
|
||||||
|
"description",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
expectedStmt: "INSERT INTO projections.sms_configs2_twilio (sms_id, instance_id, sid, token, sender_number) VALUES ($1, $2, $3, $4, $5)",
|
expectedStmt: "INSERT INTO projections.sms_configs3_twilio (sms_id, instance_id, sid, token, sender_number) VALUES ($1, $2, $3, $4, $5)",
|
||||||
expectedArgs: []interface{}{
|
expectedArgs: []interface{}{
|
||||||
"id",
|
"id",
|
||||||
"instance-id",
|
"instance-id",
|
||||||
@ -89,9 +91,10 @@ func TestSMSProjection_reduces(t *testing.T) {
|
|||||||
[]byte(`{
|
[]byte(`{
|
||||||
"id": "id",
|
"id": "id",
|
||||||
"sid": "sid",
|
"sid": "sid",
|
||||||
"senderNumber": "sender-number"
|
"senderNumber": "sender-number",
|
||||||
|
"description": "description"
|
||||||
}`),
|
}`),
|
||||||
), instance.SMSConfigTwilioChangedEventMapper),
|
), eventstore.GenericEventMapper[instance.SMSConfigTwilioChangedEvent]),
|
||||||
},
|
},
|
||||||
reduce: (&smsConfigProjection{}).reduceSMSConfigTwilioChanged,
|
reduce: (&smsConfigProjection{}).reduceSMSConfigTwilioChanged,
|
||||||
want: wantReduce{
|
want: wantReduce{
|
||||||
@ -100,7 +103,17 @@ func TestSMSProjection_reduces(t *testing.T) {
|
|||||||
executer: &testExecuter{
|
executer: &testExecuter{
|
||||||
executions: []execution{
|
executions: []execution{
|
||||||
{
|
{
|
||||||
expectedStmt: "UPDATE projections.sms_configs2_twilio SET (sid, sender_number) = ($1, $2) WHERE (sms_id = $3) AND (instance_id = $4)",
|
expectedStmt: "UPDATE projections.sms_configs3 SET (change_date, sequence, description) = ($1, $2, $3) WHERE (id = $4) AND (instance_id = $5)",
|
||||||
|
expectedArgs: []interface{}{
|
||||||
|
anyArg{},
|
||||||
|
uint64(15),
|
||||||
|
"description",
|
||||||
|
"id",
|
||||||
|
"instance-id",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
expectedStmt: "UPDATE projections.sms_configs3_twilio SET (sid, sender_number) = ($1, $2) WHERE (sms_id = $3) AND (instance_id = $4)",
|
||||||
expectedArgs: []interface{}{
|
expectedArgs: []interface{}{
|
||||||
"sid",
|
"sid",
|
||||||
"sender-number",
|
"sender-number",
|
||||||
@ -108,11 +121,75 @@ func TestSMSProjection_reduces(t *testing.T) {
|
|||||||
"instance-id",
|
"instance-id",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
{
|
{
|
||||||
expectedStmt: "UPDATE projections.sms_configs2 SET (change_date, sequence) = ($1, $2) WHERE (id = $3) AND (instance_id = $4)",
|
name: "instance reduceSMSConfigTwilioChanged, only description",
|
||||||
|
args: args{
|
||||||
|
event: getEvent(
|
||||||
|
testEvent(
|
||||||
|
instance.SMSConfigTwilioChangedEventType,
|
||||||
|
instance.AggregateType,
|
||||||
|
[]byte(`{
|
||||||
|
"id": "id",
|
||||||
|
"description": "description"
|
||||||
|
}`),
|
||||||
|
), eventstore.GenericEventMapper[instance.SMSConfigTwilioChangedEvent]),
|
||||||
|
},
|
||||||
|
reduce: (&smsConfigProjection{}).reduceSMSConfigTwilioChanged,
|
||||||
|
want: wantReduce{
|
||||||
|
aggregateType: eventstore.AggregateType("instance"),
|
||||||
|
sequence: 15,
|
||||||
|
executer: &testExecuter{
|
||||||
|
executions: []execution{
|
||||||
|
{
|
||||||
|
expectedStmt: "UPDATE projections.sms_configs3 SET (change_date, sequence, description) = ($1, $2, $3) WHERE (id = $4) AND (instance_id = $5)",
|
||||||
expectedArgs: []interface{}{
|
expectedArgs: []interface{}{
|
||||||
anyArg{},
|
anyArg{},
|
||||||
uint64(15),
|
uint64(15),
|
||||||
|
"description",
|
||||||
|
"id",
|
||||||
|
"instance-id",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "instance reduceSMSConfigTwilioChanged, only sid",
|
||||||
|
args: args{
|
||||||
|
event: getEvent(
|
||||||
|
testEvent(
|
||||||
|
instance.SMSConfigTwilioChangedEventType,
|
||||||
|
instance.AggregateType,
|
||||||
|
[]byte(`{
|
||||||
|
"id": "id",
|
||||||
|
"sid": "sid"
|
||||||
|
}`),
|
||||||
|
), eventstore.GenericEventMapper[instance.SMSConfigTwilioChangedEvent]),
|
||||||
|
},
|
||||||
|
reduce: (&smsConfigProjection{}).reduceSMSConfigTwilioChanged,
|
||||||
|
want: wantReduce{
|
||||||
|
aggregateType: eventstore.AggregateType("instance"),
|
||||||
|
sequence: 15,
|
||||||
|
executer: &testExecuter{
|
||||||
|
executions: []execution{
|
||||||
|
{
|
||||||
|
expectedStmt: "UPDATE projections.sms_configs3 SET (change_date, sequence) = ($1, $2) WHERE (id = $3) AND (instance_id = $4)",
|
||||||
|
expectedArgs: []interface{}{
|
||||||
|
anyArg{},
|
||||||
|
uint64(15),
|
||||||
|
"id",
|
||||||
|
"instance-id",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
expectedStmt: "UPDATE projections.sms_configs3_twilio SET sid = $1 WHERE (sms_id = $2) AND (instance_id = $3)",
|
||||||
|
expectedArgs: []interface{}{
|
||||||
|
"sid",
|
||||||
"id",
|
"id",
|
||||||
"instance-id",
|
"instance-id",
|
||||||
},
|
},
|
||||||
@ -137,7 +214,7 @@ func TestSMSProjection_reduces(t *testing.T) {
|
|||||||
"crypted": "Y3J5cHRlZA=="
|
"crypted": "Y3J5cHRlZA=="
|
||||||
}
|
}
|
||||||
}`),
|
}`),
|
||||||
), instance.SMSConfigTwilioTokenChangedEventMapper),
|
), eventstore.GenericEventMapper[instance.SMSConfigTwilioTokenChangedEvent]),
|
||||||
},
|
},
|
||||||
reduce: (&smsConfigProjection{}).reduceSMSConfigTwilioTokenChanged,
|
reduce: (&smsConfigProjection{}).reduceSMSConfigTwilioTokenChanged,
|
||||||
want: wantReduce{
|
want: wantReduce{
|
||||||
@ -146,7 +223,7 @@ func TestSMSProjection_reduces(t *testing.T) {
|
|||||||
executer: &testExecuter{
|
executer: &testExecuter{
|
||||||
executions: []execution{
|
executions: []execution{
|
||||||
{
|
{
|
||||||
expectedStmt: "UPDATE projections.sms_configs2_twilio SET token = $1 WHERE (sms_id = $2) AND (instance_id = $3)",
|
expectedStmt: "UPDATE projections.sms_configs3_twilio SET token = $1 WHERE (sms_id = $2) AND (instance_id = $3)",
|
||||||
expectedArgs: []interface{}{
|
expectedArgs: []interface{}{
|
||||||
&crypto.CryptoValue{
|
&crypto.CryptoValue{
|
||||||
CryptoType: crypto.TypeEncryption,
|
CryptoType: crypto.TypeEncryption,
|
||||||
@ -159,7 +236,7 @@ func TestSMSProjection_reduces(t *testing.T) {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
expectedStmt: "UPDATE projections.sms_configs2 SET (change_date, sequence) = ($1, $2) WHERE (id = $3) AND (instance_id = $4)",
|
expectedStmt: "UPDATE projections.sms_configs3 SET (change_date, sequence) = ($1, $2) WHERE (id = $3) AND (instance_id = $4)",
|
||||||
expectedArgs: []interface{}{
|
expectedArgs: []interface{}{
|
||||||
anyArg{},
|
anyArg{},
|
||||||
uint64(15),
|
uint64(15),
|
||||||
@ -171,6 +248,270 @@ func TestSMSProjection_reduces(t *testing.T) {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
name: "instance reduceSMSHTTPAdded",
|
||||||
|
args: args{
|
||||||
|
event: getEvent(
|
||||||
|
testEvent(
|
||||||
|
instance.SMSConfigHTTPAddedEventType,
|
||||||
|
instance.AggregateType,
|
||||||
|
[]byte(`{
|
||||||
|
"id": "id",
|
||||||
|
"description": "description",
|
||||||
|
"endpoint": "endpoint"
|
||||||
|
}`),
|
||||||
|
), eventstore.GenericEventMapper[instance.SMSConfigHTTPAddedEvent]),
|
||||||
|
},
|
||||||
|
reduce: (&smsConfigProjection{}).reduceSMSConfigHTTPAdded,
|
||||||
|
want: wantReduce{
|
||||||
|
aggregateType: eventstore.AggregateType("instance"),
|
||||||
|
sequence: 15,
|
||||||
|
executer: &testExecuter{
|
||||||
|
executions: []execution{
|
||||||
|
{
|
||||||
|
expectedStmt: "INSERT INTO projections.sms_configs3 (id, aggregate_id, creation_date, change_date, resource_owner, instance_id, state, sequence, description) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9)",
|
||||||
|
expectedArgs: []interface{}{
|
||||||
|
"id",
|
||||||
|
"agg-id",
|
||||||
|
anyArg{},
|
||||||
|
anyArg{},
|
||||||
|
"ro-id",
|
||||||
|
"instance-id",
|
||||||
|
domain.SMSConfigStateInactive,
|
||||||
|
uint64(15),
|
||||||
|
"description",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
expectedStmt: "INSERT INTO projections.sms_configs3_http (sms_id, instance_id, endpoint) VALUES ($1, $2, $3)",
|
||||||
|
expectedArgs: []interface{}{
|
||||||
|
"id",
|
||||||
|
"instance-id",
|
||||||
|
"endpoint",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "instance reduceSMSConfigHTTPChanged",
|
||||||
|
args: args{
|
||||||
|
event: getEvent(
|
||||||
|
testEvent(
|
||||||
|
instance.SMSConfigHTTPChangedEventType,
|
||||||
|
instance.AggregateType,
|
||||||
|
[]byte(`{
|
||||||
|
"id": "id",
|
||||||
|
"endpoint": "endpoint",
|
||||||
|
"description": "description"
|
||||||
|
}`),
|
||||||
|
), eventstore.GenericEventMapper[instance.SMSConfigHTTPChangedEvent]),
|
||||||
|
},
|
||||||
|
reduce: (&smsConfigProjection{}).reduceSMSConfigHTTPChanged,
|
||||||
|
want: wantReduce{
|
||||||
|
aggregateType: eventstore.AggregateType("instance"),
|
||||||
|
sequence: 15,
|
||||||
|
executer: &testExecuter{
|
||||||
|
executions: []execution{
|
||||||
|
{
|
||||||
|
expectedStmt: "UPDATE projections.sms_configs3 SET (change_date, sequence, description) = ($1, $2, $3) WHERE (id = $4) AND (instance_id = $5)",
|
||||||
|
expectedArgs: []interface{}{
|
||||||
|
anyArg{},
|
||||||
|
uint64(15),
|
||||||
|
"description",
|
||||||
|
"id",
|
||||||
|
"instance-id",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
expectedStmt: "UPDATE projections.sms_configs3_http SET endpoint = $1 WHERE (sms_id = $2) AND (instance_id = $3)",
|
||||||
|
expectedArgs: []interface{}{
|
||||||
|
"endpoint",
|
||||||
|
"id",
|
||||||
|
"instance-id",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "instance reduceSMSConfigHTTPChanged, only description",
|
||||||
|
args: args{
|
||||||
|
event: getEvent(
|
||||||
|
testEvent(
|
||||||
|
instance.SMSConfigHTTPChangedEventType,
|
||||||
|
instance.AggregateType,
|
||||||
|
[]byte(`{
|
||||||
|
"id": "id",
|
||||||
|
"description": "description"
|
||||||
|
}`),
|
||||||
|
), eventstore.GenericEventMapper[instance.SMSConfigHTTPChangedEvent]),
|
||||||
|
},
|
||||||
|
reduce: (&smsConfigProjection{}).reduceSMSConfigHTTPChanged,
|
||||||
|
want: wantReduce{
|
||||||
|
aggregateType: eventstore.AggregateType("instance"),
|
||||||
|
sequence: 15,
|
||||||
|
executer: &testExecuter{
|
||||||
|
executions: []execution{
|
||||||
|
{
|
||||||
|
expectedStmt: "UPDATE projections.sms_configs3 SET (change_date, sequence, description) = ($1, $2, $3) WHERE (id = $4) AND (instance_id = $5)",
|
||||||
|
expectedArgs: []interface{}{
|
||||||
|
anyArg{},
|
||||||
|
uint64(15),
|
||||||
|
"description",
|
||||||
|
"id",
|
||||||
|
"instance-id",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}, {
|
||||||
|
name: "instance reduceSMSConfigHTTPChanged, only endpoint",
|
||||||
|
args: args{
|
||||||
|
event: getEvent(
|
||||||
|
testEvent(
|
||||||
|
instance.SMSConfigHTTPChangedEventType,
|
||||||
|
instance.AggregateType,
|
||||||
|
[]byte(`{
|
||||||
|
"id": "id",
|
||||||
|
"endpoint": "endpoint"
|
||||||
|
}`),
|
||||||
|
), eventstore.GenericEventMapper[instance.SMSConfigHTTPChangedEvent]),
|
||||||
|
},
|
||||||
|
reduce: (&smsConfigProjection{}).reduceSMSConfigHTTPChanged,
|
||||||
|
want: wantReduce{
|
||||||
|
aggregateType: eventstore.AggregateType("instance"),
|
||||||
|
sequence: 15,
|
||||||
|
executer: &testExecuter{
|
||||||
|
executions: []execution{
|
||||||
|
{
|
||||||
|
expectedStmt: "UPDATE projections.sms_configs3 SET (change_date, sequence) = ($1, $2) WHERE (id = $3) AND (instance_id = $4)",
|
||||||
|
expectedArgs: []interface{}{
|
||||||
|
anyArg{},
|
||||||
|
uint64(15),
|
||||||
|
"id",
|
||||||
|
"instance-id",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
expectedStmt: "UPDATE projections.sms_configs3_http SET endpoint = $1 WHERE (sms_id = $2) AND (instance_id = $3)",
|
||||||
|
expectedArgs: []interface{}{
|
||||||
|
"endpoint",
|
||||||
|
"id",
|
||||||
|
"instance-id",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "instance reduceSMSConfigTwilioActivated",
|
||||||
|
args: args{
|
||||||
|
event: getEvent(
|
||||||
|
testEvent(
|
||||||
|
instance.SMSConfigTwilioActivatedEventType,
|
||||||
|
instance.AggregateType,
|
||||||
|
[]byte(`{
|
||||||
|
"id": "id"
|
||||||
|
}`),
|
||||||
|
), eventstore.GenericEventMapper[instance.SMSConfigTwilioActivatedEvent]),
|
||||||
|
},
|
||||||
|
reduce: (&smsConfigProjection{}).reduceSMSConfigTwilioActivated,
|
||||||
|
want: wantReduce{
|
||||||
|
aggregateType: eventstore.AggregateType("instance"),
|
||||||
|
sequence: 15,
|
||||||
|
executer: &testExecuter{
|
||||||
|
executions: []execution{
|
||||||
|
{
|
||||||
|
expectedStmt: "UPDATE projections.sms_configs3 SET (state, change_date, sequence) = ($1, $2, $3) WHERE (NOT (id = $4)) AND (state = $5) AND (instance_id = $6)",
|
||||||
|
expectedArgs: []interface{}{
|
||||||
|
domain.SMSConfigStateInactive,
|
||||||
|
anyArg{},
|
||||||
|
uint64(15),
|
||||||
|
"id",
|
||||||
|
domain.SMSConfigStateActive,
|
||||||
|
"instance-id",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
expectedStmt: "UPDATE projections.sms_configs3 SET (state, change_date, sequence) = ($1, $2, $3) WHERE (id = $4) AND (instance_id = $5)",
|
||||||
|
expectedArgs: []interface{}{
|
||||||
|
domain.SMSConfigStateActive,
|
||||||
|
anyArg{},
|
||||||
|
uint64(15),
|
||||||
|
"id",
|
||||||
|
"instance-id",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "instance reduceSMSConfigTwilioDeactivated",
|
||||||
|
args: args{
|
||||||
|
event: getEvent(
|
||||||
|
testEvent(
|
||||||
|
instance.SMSConfigTwilioDeactivatedEventType,
|
||||||
|
instance.AggregateType,
|
||||||
|
[]byte(`{
|
||||||
|
"id": "id"
|
||||||
|
}`),
|
||||||
|
), eventstore.GenericEventMapper[instance.SMSConfigTwilioDeactivatedEvent]),
|
||||||
|
},
|
||||||
|
reduce: (&smsConfigProjection{}).reduceSMSConfigTwilioDeactivated,
|
||||||
|
want: wantReduce{
|
||||||
|
aggregateType: eventstore.AggregateType("instance"),
|
||||||
|
sequence: 15,
|
||||||
|
executer: &testExecuter{
|
||||||
|
executions: []execution{
|
||||||
|
{
|
||||||
|
expectedStmt: "UPDATE projections.sms_configs3 SET (state, change_date, sequence) = ($1, $2, $3) WHERE (id = $4) AND (instance_id = $5)",
|
||||||
|
expectedArgs: []interface{}{
|
||||||
|
domain.SMSConfigStateInactive,
|
||||||
|
anyArg{},
|
||||||
|
uint64(15),
|
||||||
|
"id",
|
||||||
|
"instance-id",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "instance reduceSMSConfigTwilioRemoved",
|
||||||
|
args: args{
|
||||||
|
event: getEvent(
|
||||||
|
testEvent(
|
||||||
|
instance.SMSConfigTwilioRemovedEventType,
|
||||||
|
instance.AggregateType,
|
||||||
|
[]byte(`{
|
||||||
|
"id": "id"
|
||||||
|
}`),
|
||||||
|
), eventstore.GenericEventMapper[instance.SMSConfigTwilioRemovedEvent]),
|
||||||
|
},
|
||||||
|
reduce: (&smsConfigProjection{}).reduceSMSConfigTwilioRemoved,
|
||||||
|
want: wantReduce{
|
||||||
|
aggregateType: eventstore.AggregateType("instance"),
|
||||||
|
sequence: 15,
|
||||||
|
executer: &testExecuter{
|
||||||
|
executions: []execution{
|
||||||
|
{
|
||||||
|
expectedStmt: "DELETE FROM projections.sms_configs3 WHERE (id = $1) AND (instance_id = $2)",
|
||||||
|
expectedArgs: []interface{}{
|
||||||
|
"id",
|
||||||
|
"instance-id",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
{
|
{
|
||||||
name: "instance reduceSMSConfigActivated",
|
name: "instance reduceSMSConfigActivated",
|
||||||
args: args{
|
args: args{
|
||||||
@ -181,7 +522,7 @@ func TestSMSProjection_reduces(t *testing.T) {
|
|||||||
[]byte(`{
|
[]byte(`{
|
||||||
"id": "id"
|
"id": "id"
|
||||||
}`),
|
}`),
|
||||||
), instance.SMSConfigActivatedEventMapper),
|
), eventstore.GenericEventMapper[instance.SMSConfigActivatedEvent]),
|
||||||
},
|
},
|
||||||
reduce: (&smsConfigProjection{}).reduceSMSConfigActivated,
|
reduce: (&smsConfigProjection{}).reduceSMSConfigActivated,
|
||||||
want: wantReduce{
|
want: wantReduce{
|
||||||
@ -190,7 +531,18 @@ func TestSMSProjection_reduces(t *testing.T) {
|
|||||||
executer: &testExecuter{
|
executer: &testExecuter{
|
||||||
executions: []execution{
|
executions: []execution{
|
||||||
{
|
{
|
||||||
expectedStmt: "UPDATE projections.sms_configs2 SET (state, change_date, sequence) = ($1, $2, $3) WHERE (id = $4) AND (instance_id = $5)",
|
expectedStmt: "UPDATE projections.sms_configs3 SET (state, change_date, sequence) = ($1, $2, $3) WHERE (NOT (id = $4)) AND (state = $5) AND (instance_id = $6)",
|
||||||
|
expectedArgs: []interface{}{
|
||||||
|
domain.SMSConfigStateInactive,
|
||||||
|
anyArg{},
|
||||||
|
uint64(15),
|
||||||
|
"id",
|
||||||
|
domain.SMSConfigStateActive,
|
||||||
|
"instance-id",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
expectedStmt: "UPDATE projections.sms_configs3 SET (state, change_date, sequence) = ($1, $2, $3) WHERE (id = $4) AND (instance_id = $5)",
|
||||||
expectedArgs: []interface{}{
|
expectedArgs: []interface{}{
|
||||||
domain.SMSConfigStateActive,
|
domain.SMSConfigStateActive,
|
||||||
anyArg{},
|
anyArg{},
|
||||||
@ -213,7 +565,7 @@ func TestSMSProjection_reduces(t *testing.T) {
|
|||||||
[]byte(`{
|
[]byte(`{
|
||||||
"id": "id"
|
"id": "id"
|
||||||
}`),
|
}`),
|
||||||
), instance.SMSConfigDeactivatedEventMapper),
|
), eventstore.GenericEventMapper[instance.SMSConfigDeactivatedEvent]),
|
||||||
},
|
},
|
||||||
reduce: (&smsConfigProjection{}).reduceSMSConfigDeactivated,
|
reduce: (&smsConfigProjection{}).reduceSMSConfigDeactivated,
|
||||||
want: wantReduce{
|
want: wantReduce{
|
||||||
@ -222,7 +574,7 @@ func TestSMSProjection_reduces(t *testing.T) {
|
|||||||
executer: &testExecuter{
|
executer: &testExecuter{
|
||||||
executions: []execution{
|
executions: []execution{
|
||||||
{
|
{
|
||||||
expectedStmt: "UPDATE projections.sms_configs2 SET (state, change_date, sequence) = ($1, $2, $3) WHERE (id = $4) AND (instance_id = $5)",
|
expectedStmt: "UPDATE projections.sms_configs3 SET (state, change_date, sequence) = ($1, $2, $3) WHERE (id = $4) AND (instance_id = $5)",
|
||||||
expectedArgs: []interface{}{
|
expectedArgs: []interface{}{
|
||||||
domain.SMSConfigStateInactive,
|
domain.SMSConfigStateInactive,
|
||||||
anyArg{},
|
anyArg{},
|
||||||
@ -245,7 +597,7 @@ func TestSMSProjection_reduces(t *testing.T) {
|
|||||||
[]byte(`{
|
[]byte(`{
|
||||||
"id": "id"
|
"id": "id"
|
||||||
}`),
|
}`),
|
||||||
), instance.SMSConfigRemovedEventMapper),
|
), eventstore.GenericEventMapper[instance.SMSConfigRemovedEvent]),
|
||||||
},
|
},
|
||||||
reduce: (&smsConfigProjection{}).reduceSMSConfigRemoved,
|
reduce: (&smsConfigProjection{}).reduceSMSConfigRemoved,
|
||||||
want: wantReduce{
|
want: wantReduce{
|
||||||
@ -254,7 +606,7 @@ func TestSMSProjection_reduces(t *testing.T) {
|
|||||||
executer: &testExecuter{
|
executer: &testExecuter{
|
||||||
executions: []execution{
|
executions: []execution{
|
||||||
{
|
{
|
||||||
expectedStmt: "DELETE FROM projections.sms_configs2 WHERE (id = $1) AND (instance_id = $2)",
|
expectedStmt: "DELETE FROM projections.sms_configs3 WHERE (id = $1) AND (instance_id = $2)",
|
||||||
expectedArgs: []interface{}{
|
expectedArgs: []interface{}{
|
||||||
"id",
|
"id",
|
||||||
"instance-id",
|
"instance-id",
|
||||||
@ -281,7 +633,7 @@ func TestSMSProjection_reduces(t *testing.T) {
|
|||||||
executer: &testExecuter{
|
executer: &testExecuter{
|
||||||
executions: []execution{
|
executions: []execution{
|
||||||
{
|
{
|
||||||
expectedStmt: "DELETE FROM projections.sms_configs2 WHERE (instance_id = $1)",
|
expectedStmt: "DELETE FROM projections.sms_configs3 WHERE (instance_id = $1)",
|
||||||
expectedArgs: []interface{}{
|
expectedArgs: []interface{}{
|
||||||
"agg-id",
|
"agg-id",
|
||||||
},
|
},
|
||||||
|
@ -30,8 +30,10 @@ type SMSConfig struct {
|
|||||||
ResourceOwner string
|
ResourceOwner string
|
||||||
State domain.SMSConfigState
|
State domain.SMSConfigState
|
||||||
Sequence uint64
|
Sequence uint64
|
||||||
|
Description string
|
||||||
|
|
||||||
TwilioConfig *Twilio
|
TwilioConfig *Twilio
|
||||||
|
HTTPConfig *HTTP
|
||||||
}
|
}
|
||||||
|
|
||||||
type Twilio struct {
|
type Twilio struct {
|
||||||
@ -40,6 +42,10 @@ type Twilio struct {
|
|||||||
SenderNumber string
|
SenderNumber string
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type HTTP struct {
|
||||||
|
Endpoint string
|
||||||
|
}
|
||||||
|
|
||||||
type SMSConfigsSearchQueries struct {
|
type SMSConfigsSearchQueries struct {
|
||||||
SearchRequest
|
SearchRequest
|
||||||
Queries []SearchQuery
|
Queries []SearchQuery
|
||||||
@ -58,60 +64,79 @@ var (
|
|||||||
name: projection.SMSConfigProjectionTable,
|
name: projection.SMSConfigProjectionTable,
|
||||||
instanceIDCol: projection.SMSColumnInstanceID,
|
instanceIDCol: projection.SMSColumnInstanceID,
|
||||||
}
|
}
|
||||||
SMSConfigColumnID = Column{
|
SMSColumnID = Column{
|
||||||
name: projection.SMSColumnID,
|
name: projection.SMSColumnID,
|
||||||
table: smsConfigsTable,
|
table: smsConfigsTable,
|
||||||
}
|
}
|
||||||
SMSConfigColumnAggregateID = Column{
|
SMSColumnAggregateID = Column{
|
||||||
name: projection.SMSColumnAggregateID,
|
name: projection.SMSColumnAggregateID,
|
||||||
table: smsConfigsTable,
|
table: smsConfigsTable,
|
||||||
}
|
}
|
||||||
SMSConfigColumnCreationDate = Column{
|
SMSColumnCreationDate = Column{
|
||||||
name: projection.SMSColumnCreationDate,
|
name: projection.SMSColumnCreationDate,
|
||||||
table: smsConfigsTable,
|
table: smsConfigsTable,
|
||||||
}
|
}
|
||||||
SMSConfigColumnChangeDate = Column{
|
SMSColumnChangeDate = Column{
|
||||||
name: projection.SMSColumnChangeDate,
|
name: projection.SMSColumnChangeDate,
|
||||||
table: smsConfigsTable,
|
table: smsConfigsTable,
|
||||||
}
|
}
|
||||||
SMSConfigColumnResourceOwner = Column{
|
SMSColumnResourceOwner = Column{
|
||||||
name: projection.SMSColumnResourceOwner,
|
name: projection.SMSColumnResourceOwner,
|
||||||
table: smsConfigsTable,
|
table: smsConfigsTable,
|
||||||
}
|
}
|
||||||
SMSConfigColumnInstanceID = Column{
|
SMSColumnInstanceID = Column{
|
||||||
name: projection.SMSColumnInstanceID,
|
name: projection.SMSColumnInstanceID,
|
||||||
table: smsConfigsTable,
|
table: smsConfigsTable,
|
||||||
}
|
}
|
||||||
SMSConfigColumnState = Column{
|
SMSColumnState = Column{
|
||||||
name: projection.SMSColumnState,
|
name: projection.SMSColumnState,
|
||||||
table: smsConfigsTable,
|
table: smsConfigsTable,
|
||||||
}
|
}
|
||||||
SMSConfigColumnSequence = Column{
|
SMSColumnSequence = Column{
|
||||||
name: projection.SMSColumnSequence,
|
name: projection.SMSColumnSequence,
|
||||||
table: smsConfigsTable,
|
table: smsConfigsTable,
|
||||||
}
|
}
|
||||||
|
SMSColumnDescription = Column{
|
||||||
|
name: projection.SMSColumnDescription,
|
||||||
|
table: smsConfigsTable,
|
||||||
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
smsTwilioConfigsTable = table{
|
smsTwilioTable = table{
|
||||||
name: projection.SMSTwilioTable,
|
name: projection.SMSTwilioTable,
|
||||||
instanceIDCol: projection.SMSTwilioColumnInstanceID,
|
instanceIDCol: projection.SMSTwilioColumnInstanceID,
|
||||||
}
|
}
|
||||||
SMSTwilioConfigColumnSMSID = Column{
|
SMSTwilioColumnSMSID = Column{
|
||||||
name: projection.SMSTwilioConfigColumnSMSID,
|
name: projection.SMSTwilioColumnSMSID,
|
||||||
table: smsTwilioConfigsTable,
|
table: smsTwilioTable,
|
||||||
}
|
}
|
||||||
SMSTwilioConfigColumnSID = Column{
|
SMSTwilioColumnSID = Column{
|
||||||
name: projection.SMSTwilioConfigColumnSID,
|
name: projection.SMSTwilioColumnSID,
|
||||||
table: smsTwilioConfigsTable,
|
table: smsTwilioTable,
|
||||||
}
|
}
|
||||||
SMSTwilioConfigColumnToken = Column{
|
SMSTwilioColumnToken = Column{
|
||||||
name: projection.SMSTwilioConfigColumnToken,
|
name: projection.SMSTwilioColumnToken,
|
||||||
table: smsTwilioConfigsTable,
|
table: smsTwilioTable,
|
||||||
}
|
}
|
||||||
SMSTwilioConfigColumnSenderNumber = Column{
|
SMSTwilioColumnSenderNumber = Column{
|
||||||
name: projection.SMSTwilioConfigColumnSenderNumber,
|
name: projection.SMSTwilioColumnSenderNumber,
|
||||||
table: smsTwilioConfigsTable,
|
table: smsTwilioTable,
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
smsHTTPTable = table{
|
||||||
|
name: projection.SMSHTTPTable,
|
||||||
|
instanceIDCol: projection.SMSHTTPColumnInstanceID,
|
||||||
|
}
|
||||||
|
SMSHTTPColumnSMSID = Column{
|
||||||
|
name: projection.SMSHTTPColumnSMSID,
|
||||||
|
table: smsHTTPTable,
|
||||||
|
}
|
||||||
|
SMSHTTPColumnEndpoint = Column{
|
||||||
|
name: projection.SMSHTTPColumnEndpoint,
|
||||||
|
table: smsHTTPTable,
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -122,8 +147,8 @@ func (q *Queries) SMSProviderConfigByID(ctx context.Context, id string) (config
|
|||||||
query, scan := prepareSMSConfigQuery(ctx, q.client)
|
query, scan := prepareSMSConfigQuery(ctx, q.client)
|
||||||
stmt, args, err := query.Where(
|
stmt, args, err := query.Where(
|
||||||
sq.Eq{
|
sq.Eq{
|
||||||
SMSConfigColumnID.identifier(): id,
|
SMSColumnID.identifier(): id,
|
||||||
SMSConfigColumnInstanceID.identifier(): authz.GetInstance(ctx).InstanceID(),
|
SMSColumnInstanceID.identifier(): authz.GetInstance(ctx).InstanceID(),
|
||||||
},
|
},
|
||||||
).ToSql()
|
).ToSql()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -137,17 +162,15 @@ func (q *Queries) SMSProviderConfigByID(ctx context.Context, id string) (config
|
|||||||
return config, err
|
return config, err
|
||||||
}
|
}
|
||||||
|
|
||||||
func (q *Queries) SMSProviderConfig(ctx context.Context, queries ...SearchQuery) (config *SMSConfig, err error) {
|
func (q *Queries) SMSProviderConfigActive(ctx context.Context, instanceID string) (config *SMSConfig, err error) {
|
||||||
ctx, span := tracing.NewSpan(ctx)
|
ctx, span := tracing.NewSpan(ctx)
|
||||||
defer func() { span.EndWithError(err) }()
|
defer func() { span.EndWithError(err) }()
|
||||||
|
|
||||||
query, scan := prepareSMSConfigQuery(ctx, q.client)
|
query, scan := prepareSMSConfigQuery(ctx, q.client)
|
||||||
for _, searchQuery := range queries {
|
|
||||||
query = searchQuery.toQuery(query)
|
|
||||||
}
|
|
||||||
stmt, args, err := query.Where(
|
stmt, args, err := query.Where(
|
||||||
sq.Eq{
|
sq.Eq{
|
||||||
SMSConfigColumnInstanceID.identifier(): authz.GetInstance(ctx).InstanceID(),
|
SMSColumnInstanceID.identifier(): instanceID,
|
||||||
|
SMSColumnState.identifier(): domain.SMSConfigStateActive,
|
||||||
},
|
},
|
||||||
).ToSql()
|
).ToSql()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -168,7 +191,7 @@ func (q *Queries) SearchSMSConfigs(ctx context.Context, queries *SMSConfigsSearc
|
|||||||
query, scan := prepareSMSConfigsQuery(ctx, q.client)
|
query, scan := prepareSMSConfigsQuery(ctx, q.client)
|
||||||
stmt, args, err := queries.toQuery(query).
|
stmt, args, err := queries.toQuery(query).
|
||||||
Where(sq.Eq{
|
Where(sq.Eq{
|
||||||
SMSConfigColumnInstanceID.identifier(): authz.GetInstance(ctx).InstanceID(),
|
SMSColumnInstanceID.identifier(): authz.GetInstance(ctx).InstanceID(),
|
||||||
}).ToSql()
|
}).ToSql()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, zerrors.ThrowInvalidArgument(err, "QUERY-sn9Jf", "Errors.Query.InvalidRequest")
|
return nil, zerrors.ThrowInvalidArgument(err, "QUERY-sn9Jf", "Errors.Query.InvalidRequest")
|
||||||
@ -186,30 +209,36 @@ func (q *Queries) SearchSMSConfigs(ctx context.Context, queries *SMSConfigsSearc
|
|||||||
}
|
}
|
||||||
|
|
||||||
func NewSMSProviderStateQuery(state domain.SMSConfigState) (SearchQuery, error) {
|
func NewSMSProviderStateQuery(state domain.SMSConfigState) (SearchQuery, error) {
|
||||||
return NewNumberQuery(SMSConfigColumnState, state, NumberEquals)
|
return NewNumberQuery(SMSColumnState, state, NumberEquals)
|
||||||
}
|
}
|
||||||
|
|
||||||
func prepareSMSConfigQuery(ctx context.Context, db prepareDatabase) (sq.SelectBuilder, func(*sql.Row) (*SMSConfig, error)) {
|
func prepareSMSConfigQuery(ctx context.Context, db prepareDatabase) (sq.SelectBuilder, func(*sql.Row) (*SMSConfig, error)) {
|
||||||
return sq.Select(
|
return sq.Select(
|
||||||
SMSConfigColumnID.identifier(),
|
SMSColumnID.identifier(),
|
||||||
SMSConfigColumnAggregateID.identifier(),
|
SMSColumnAggregateID.identifier(),
|
||||||
SMSConfigColumnCreationDate.identifier(),
|
SMSColumnCreationDate.identifier(),
|
||||||
SMSConfigColumnChangeDate.identifier(),
|
SMSColumnChangeDate.identifier(),
|
||||||
SMSConfigColumnResourceOwner.identifier(),
|
SMSColumnResourceOwner.identifier(),
|
||||||
SMSConfigColumnState.identifier(),
|
SMSColumnState.identifier(),
|
||||||
SMSConfigColumnSequence.identifier(),
|
SMSColumnSequence.identifier(),
|
||||||
|
SMSColumnDescription.identifier(),
|
||||||
|
|
||||||
SMSTwilioConfigColumnSMSID.identifier(),
|
SMSTwilioColumnSMSID.identifier(),
|
||||||
SMSTwilioConfigColumnSID.identifier(),
|
SMSTwilioColumnSID.identifier(),
|
||||||
SMSTwilioConfigColumnToken.identifier(),
|
SMSTwilioColumnToken.identifier(),
|
||||||
SMSTwilioConfigColumnSenderNumber.identifier(),
|
SMSTwilioColumnSenderNumber.identifier(),
|
||||||
|
|
||||||
|
SMSHTTPColumnSMSID.identifier(),
|
||||||
|
SMSHTTPColumnEndpoint.identifier(),
|
||||||
).From(smsConfigsTable.identifier()).
|
).From(smsConfigsTable.identifier()).
|
||||||
LeftJoin(join(SMSTwilioConfigColumnSMSID, SMSConfigColumnID) + db.Timetravel(call.Took(ctx))).
|
LeftJoin(join(SMSTwilioColumnSMSID, SMSColumnID)).
|
||||||
|
LeftJoin(join(SMSHTTPColumnSMSID, SMSColumnID) + db.Timetravel(call.Took(ctx))).
|
||||||
PlaceholderFormat(sq.Dollar), func(row *sql.Row) (*SMSConfig, error) {
|
PlaceholderFormat(sq.Dollar), func(row *sql.Row) (*SMSConfig, error) {
|
||||||
config := new(SMSConfig)
|
config := new(SMSConfig)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
twilioConfig = sqlTwilioConfig{}
|
twilioConfig = sqlTwilioConfig{}
|
||||||
|
httpConfig = sqlHTTPConfig{}
|
||||||
)
|
)
|
||||||
|
|
||||||
err := row.Scan(
|
err := row.Scan(
|
||||||
@ -220,11 +249,15 @@ func prepareSMSConfigQuery(ctx context.Context, db prepareDatabase) (sq.SelectBu
|
|||||||
&config.ResourceOwner,
|
&config.ResourceOwner,
|
||||||
&config.State,
|
&config.State,
|
||||||
&config.Sequence,
|
&config.Sequence,
|
||||||
|
&config.Description,
|
||||||
|
|
||||||
&twilioConfig.smsID,
|
&twilioConfig.smsID,
|
||||||
&twilioConfig.sid,
|
&twilioConfig.sid,
|
||||||
&twilioConfig.token,
|
&twilioConfig.token,
|
||||||
&twilioConfig.senderNumber,
|
&twilioConfig.senderNumber,
|
||||||
|
|
||||||
|
&httpConfig.smsID,
|
||||||
|
&httpConfig.endpoint,
|
||||||
)
|
)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -235,6 +268,7 @@ func prepareSMSConfigQuery(ctx context.Context, db prepareDatabase) (sq.SelectBu
|
|||||||
}
|
}
|
||||||
|
|
||||||
twilioConfig.set(config)
|
twilioConfig.set(config)
|
||||||
|
httpConfig.set(config)
|
||||||
|
|
||||||
return config, nil
|
return config, nil
|
||||||
}
|
}
|
||||||
@ -242,21 +276,27 @@ func prepareSMSConfigQuery(ctx context.Context, db prepareDatabase) (sq.SelectBu
|
|||||||
|
|
||||||
func prepareSMSConfigsQuery(ctx context.Context, db prepareDatabase) (sq.SelectBuilder, func(*sql.Rows) (*SMSConfigs, error)) {
|
func prepareSMSConfigsQuery(ctx context.Context, db prepareDatabase) (sq.SelectBuilder, func(*sql.Rows) (*SMSConfigs, error)) {
|
||||||
return sq.Select(
|
return sq.Select(
|
||||||
SMSConfigColumnID.identifier(),
|
SMSColumnID.identifier(),
|
||||||
SMSConfigColumnAggregateID.identifier(),
|
SMSColumnAggregateID.identifier(),
|
||||||
SMSConfigColumnCreationDate.identifier(),
|
SMSColumnCreationDate.identifier(),
|
||||||
SMSConfigColumnChangeDate.identifier(),
|
SMSColumnChangeDate.identifier(),
|
||||||
SMSConfigColumnResourceOwner.identifier(),
|
SMSColumnResourceOwner.identifier(),
|
||||||
SMSConfigColumnState.identifier(),
|
SMSColumnState.identifier(),
|
||||||
SMSConfigColumnSequence.identifier(),
|
SMSColumnSequence.identifier(),
|
||||||
|
SMSColumnDescription.identifier(),
|
||||||
|
|
||||||
|
SMSTwilioColumnSMSID.identifier(),
|
||||||
|
SMSTwilioColumnSID.identifier(),
|
||||||
|
SMSTwilioColumnToken.identifier(),
|
||||||
|
SMSTwilioColumnSenderNumber.identifier(),
|
||||||
|
|
||||||
|
SMSHTTPColumnSMSID.identifier(),
|
||||||
|
SMSHTTPColumnEndpoint.identifier(),
|
||||||
|
|
||||||
SMSTwilioConfigColumnSMSID.identifier(),
|
|
||||||
SMSTwilioConfigColumnSID.identifier(),
|
|
||||||
SMSTwilioConfigColumnToken.identifier(),
|
|
||||||
SMSTwilioConfigColumnSenderNumber.identifier(),
|
|
||||||
countColumn.identifier(),
|
countColumn.identifier(),
|
||||||
).From(smsConfigsTable.identifier()).
|
).From(smsConfigsTable.identifier()).
|
||||||
LeftJoin(join(SMSTwilioConfigColumnSMSID, SMSConfigColumnID) + db.Timetravel(call.Took(ctx))).
|
LeftJoin(join(SMSTwilioColumnSMSID, SMSColumnID)).
|
||||||
|
LeftJoin(join(SMSHTTPColumnSMSID, SMSColumnID) + db.Timetravel(call.Took(ctx))).
|
||||||
PlaceholderFormat(sq.Dollar), func(row *sql.Rows) (*SMSConfigs, error) {
|
PlaceholderFormat(sq.Dollar), func(row *sql.Rows) (*SMSConfigs, error) {
|
||||||
configs := &SMSConfigs{Configs: []*SMSConfig{}}
|
configs := &SMSConfigs{Configs: []*SMSConfig{}}
|
||||||
|
|
||||||
@ -264,6 +304,7 @@ func prepareSMSConfigsQuery(ctx context.Context, db prepareDatabase) (sq.SelectB
|
|||||||
config := new(SMSConfig)
|
config := new(SMSConfig)
|
||||||
var (
|
var (
|
||||||
twilioConfig = sqlTwilioConfig{}
|
twilioConfig = sqlTwilioConfig{}
|
||||||
|
httpConfig = sqlHTTPConfig{}
|
||||||
)
|
)
|
||||||
|
|
||||||
err := row.Scan(
|
err := row.Scan(
|
||||||
@ -274,11 +315,16 @@ func prepareSMSConfigsQuery(ctx context.Context, db prepareDatabase) (sq.SelectB
|
|||||||
&config.ResourceOwner,
|
&config.ResourceOwner,
|
||||||
&config.State,
|
&config.State,
|
||||||
&config.Sequence,
|
&config.Sequence,
|
||||||
|
&config.Description,
|
||||||
|
|
||||||
&twilioConfig.smsID,
|
&twilioConfig.smsID,
|
||||||
&twilioConfig.sid,
|
&twilioConfig.sid,
|
||||||
&twilioConfig.token,
|
&twilioConfig.token,
|
||||||
&twilioConfig.senderNumber,
|
&twilioConfig.senderNumber,
|
||||||
|
|
||||||
|
&httpConfig.smsID,
|
||||||
|
&httpConfig.endpoint,
|
||||||
|
|
||||||
&configs.Count,
|
&configs.Count,
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -287,6 +333,7 @@ func prepareSMSConfigsQuery(ctx context.Context, db prepareDatabase) (sq.SelectB
|
|||||||
}
|
}
|
||||||
|
|
||||||
twilioConfig.set(config)
|
twilioConfig.set(config)
|
||||||
|
httpConfig.set(config)
|
||||||
|
|
||||||
configs.Configs = append(configs.Configs, config)
|
configs.Configs = append(configs.Configs, config)
|
||||||
}
|
}
|
||||||
@ -312,3 +359,17 @@ func (c sqlTwilioConfig) set(smsConfig *SMSConfig) {
|
|||||||
SenderNumber: c.senderNumber.String,
|
SenderNumber: c.senderNumber.String,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type sqlHTTPConfig struct {
|
||||||
|
smsID sql.NullString
|
||||||
|
endpoint sql.NullString
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c sqlHTTPConfig) set(smsConfig *SMSConfig) {
|
||||||
|
if !c.smsID.Valid {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
smsConfig.HTTPConfig = &HTTP{
|
||||||
|
Endpoint: c.endpoint.String,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -14,38 +14,50 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
expectedSMSConfigQuery = regexp.QuoteMeta(`SELECT projections.sms_configs2.id,` +
|
expectedSMSConfigQuery = regexp.QuoteMeta(`SELECT projections.sms_configs3.id,` +
|
||||||
` projections.sms_configs2.aggregate_id,` +
|
` projections.sms_configs3.aggregate_id,` +
|
||||||
` projections.sms_configs2.creation_date,` +
|
` projections.sms_configs3.creation_date,` +
|
||||||
` projections.sms_configs2.change_date,` +
|
` projections.sms_configs3.change_date,` +
|
||||||
` projections.sms_configs2.resource_owner,` +
|
` projections.sms_configs3.resource_owner,` +
|
||||||
` projections.sms_configs2.state,` +
|
` projections.sms_configs3.state,` +
|
||||||
` projections.sms_configs2.sequence,` +
|
` projections.sms_configs3.sequence,` +
|
||||||
|
` projections.sms_configs3.description,` +
|
||||||
|
|
||||||
// twilio config
|
// twilio config
|
||||||
` projections.sms_configs2_twilio.sms_id,` +
|
` projections.sms_configs3_twilio.sms_id,` +
|
||||||
` projections.sms_configs2_twilio.sid,` +
|
` projections.sms_configs3_twilio.sid,` +
|
||||||
` projections.sms_configs2_twilio.token,` +
|
` projections.sms_configs3_twilio.token,` +
|
||||||
` projections.sms_configs2_twilio.sender_number` +
|
` projections.sms_configs3_twilio.sender_number,` +
|
||||||
` FROM projections.sms_configs2` +
|
|
||||||
` LEFT JOIN projections.sms_configs2_twilio ON projections.sms_configs2.id = projections.sms_configs2_twilio.sms_id AND projections.sms_configs2.instance_id = projections.sms_configs2_twilio.instance_id` +
|
// http config
|
||||||
|
` projections.sms_configs3_http.sms_id,` +
|
||||||
|
` projections.sms_configs3_http.endpoint` +
|
||||||
|
` FROM projections.sms_configs3` +
|
||||||
|
` LEFT JOIN projections.sms_configs3_twilio ON projections.sms_configs3.id = projections.sms_configs3_twilio.sms_id AND projections.sms_configs3.instance_id = projections.sms_configs3_twilio.instance_id` +
|
||||||
|
` LEFT JOIN projections.sms_configs3_http ON projections.sms_configs3.id = projections.sms_configs3_http.sms_id AND projections.sms_configs3.instance_id = projections.sms_configs3_http.instance_id` +
|
||||||
` AS OF SYSTEM TIME '-1 ms'`)
|
` AS OF SYSTEM TIME '-1 ms'`)
|
||||||
expectedSMSConfigsQuery = regexp.QuoteMeta(`SELECT projections.sms_configs2.id,` +
|
expectedSMSConfigsQuery = regexp.QuoteMeta(`SELECT projections.sms_configs3.id,` +
|
||||||
` projections.sms_configs2.aggregate_id,` +
|
` projections.sms_configs3.aggregate_id,` +
|
||||||
` projections.sms_configs2.creation_date,` +
|
` projections.sms_configs3.creation_date,` +
|
||||||
` projections.sms_configs2.change_date,` +
|
` projections.sms_configs3.change_date,` +
|
||||||
` projections.sms_configs2.resource_owner,` +
|
` projections.sms_configs3.resource_owner,` +
|
||||||
` projections.sms_configs2.state,` +
|
` projections.sms_configs3.state,` +
|
||||||
` projections.sms_configs2.sequence,` +
|
` projections.sms_configs3.sequence,` +
|
||||||
|
` projections.sms_configs3.description,` +
|
||||||
|
|
||||||
// twilio config
|
// twilio config
|
||||||
` projections.sms_configs2_twilio.sms_id,` +
|
` projections.sms_configs3_twilio.sms_id,` +
|
||||||
` projections.sms_configs2_twilio.sid,` +
|
` projections.sms_configs3_twilio.sid,` +
|
||||||
` projections.sms_configs2_twilio.token,` +
|
` projections.sms_configs3_twilio.token,` +
|
||||||
` projections.sms_configs2_twilio.sender_number,` +
|
` projections.sms_configs3_twilio.sender_number,` +
|
||||||
|
|
||||||
|
// http config
|
||||||
|
` projections.sms_configs3_http.sms_id,` +
|
||||||
|
` projections.sms_configs3_http.endpoint,` +
|
||||||
` COUNT(*) OVER ()` +
|
` COUNT(*) OVER ()` +
|
||||||
` FROM projections.sms_configs2` +
|
` FROM projections.sms_configs3` +
|
||||||
` LEFT JOIN projections.sms_configs2_twilio ON projections.sms_configs2.id = projections.sms_configs2_twilio.sms_id AND projections.sms_configs2.instance_id = projections.sms_configs2_twilio.instance_id` +
|
` LEFT JOIN projections.sms_configs3_twilio ON projections.sms_configs3.id = projections.sms_configs3_twilio.sms_id AND projections.sms_configs3.instance_id = projections.sms_configs3_twilio.instance_id` +
|
||||||
|
` LEFT JOIN projections.sms_configs3_http ON projections.sms_configs3.id = projections.sms_configs3_http.sms_id AND projections.sms_configs3.instance_id = projections.sms_configs3_http.instance_id` +
|
||||||
` AS OF SYSTEM TIME '-1 ms'`)
|
` AS OF SYSTEM TIME '-1 ms'`)
|
||||||
|
|
||||||
smsConfigCols = []string{
|
smsConfigCols = []string{
|
||||||
@ -56,16 +68,20 @@ var (
|
|||||||
"resource_owner",
|
"resource_owner",
|
||||||
"state",
|
"state",
|
||||||
"sequence",
|
"sequence",
|
||||||
|
"description",
|
||||||
// twilio config
|
// twilio config
|
||||||
"sms_id",
|
"sms_id",
|
||||||
"sid",
|
"sid",
|
||||||
"token",
|
"token",
|
||||||
"sender-number",
|
"sender-number",
|
||||||
|
// http config
|
||||||
|
"sms_id",
|
||||||
|
"endpoint",
|
||||||
}
|
}
|
||||||
smsConfigsCols = append(smsConfigCols, "count")
|
smsConfigsCols = append(smsConfigCols, "count")
|
||||||
)
|
)
|
||||||
|
|
||||||
func Test_SMSConfigssPrepare(t *testing.T) {
|
func Test_SMSConfigsPrepare(t *testing.T) {
|
||||||
type want struct {
|
type want struct {
|
||||||
sqlExpectations sqlExpectation
|
sqlExpectations sqlExpectation
|
||||||
err checkErr
|
err checkErr
|
||||||
@ -104,11 +120,15 @@ func Test_SMSConfigssPrepare(t *testing.T) {
|
|||||||
"ro",
|
"ro",
|
||||||
domain.SMSConfigStateInactive,
|
domain.SMSConfigStateInactive,
|
||||||
uint64(20211109),
|
uint64(20211109),
|
||||||
|
"description",
|
||||||
// twilio config
|
// twilio config
|
||||||
"sms-id",
|
"sms-id",
|
||||||
"sid",
|
"sid",
|
||||||
&crypto.CryptoValue{},
|
&crypto.CryptoValue{},
|
||||||
"sender-number",
|
"sender-number",
|
||||||
|
// http config
|
||||||
|
nil,
|
||||||
|
nil,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
@ -126,6 +146,7 @@ func Test_SMSConfigssPrepare(t *testing.T) {
|
|||||||
ResourceOwner: "ro",
|
ResourceOwner: "ro",
|
||||||
State: domain.SMSConfigStateInactive,
|
State: domain.SMSConfigStateInactive,
|
||||||
Sequence: 20211109,
|
Sequence: 20211109,
|
||||||
|
Description: "description",
|
||||||
TwilioConfig: &Twilio{
|
TwilioConfig: &Twilio{
|
||||||
SID: "sid",
|
SID: "sid",
|
||||||
Token: &crypto.CryptoValue{},
|
Token: &crypto.CryptoValue{},
|
||||||
@ -135,6 +156,56 @@ func Test_SMSConfigssPrepare(t *testing.T) {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
name: "prepareSMSQuery http config",
|
||||||
|
prepare: prepareSMSConfigsQuery,
|
||||||
|
want: want{
|
||||||
|
sqlExpectations: mockQueries(
|
||||||
|
expectedSMSConfigsQuery,
|
||||||
|
smsConfigsCols,
|
||||||
|
[][]driver.Value{
|
||||||
|
{
|
||||||
|
"sms-id",
|
||||||
|
"agg-id",
|
||||||
|
testNow,
|
||||||
|
testNow,
|
||||||
|
"ro",
|
||||||
|
domain.SMSConfigStateInactive,
|
||||||
|
uint64(20211109),
|
||||||
|
"description",
|
||||||
|
// twilio config
|
||||||
|
nil,
|
||||||
|
nil,
|
||||||
|
nil,
|
||||||
|
nil,
|
||||||
|
// http config
|
||||||
|
"sms-id",
|
||||||
|
"endpoint",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
),
|
||||||
|
},
|
||||||
|
object: &SMSConfigs{
|
||||||
|
SearchResponse: SearchResponse{
|
||||||
|
Count: 1,
|
||||||
|
},
|
||||||
|
Configs: []*SMSConfig{
|
||||||
|
{
|
||||||
|
ID: "sms-id",
|
||||||
|
AggregateID: "agg-id",
|
||||||
|
CreationDate: testNow,
|
||||||
|
ChangeDate: testNow,
|
||||||
|
ResourceOwner: "ro",
|
||||||
|
State: domain.SMSConfigStateInactive,
|
||||||
|
Sequence: 20211109,
|
||||||
|
Description: "description",
|
||||||
|
HTTPConfig: &HTTP{
|
||||||
|
Endpoint: "endpoint",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
{
|
{
|
||||||
name: "prepareSMSConfigsQuery multiple result",
|
name: "prepareSMSConfigsQuery multiple result",
|
||||||
prepare: prepareSMSConfigsQuery,
|
prepare: prepareSMSConfigsQuery,
|
||||||
@ -149,13 +220,17 @@ func Test_SMSConfigssPrepare(t *testing.T) {
|
|||||||
testNow,
|
testNow,
|
||||||
testNow,
|
testNow,
|
||||||
"ro",
|
"ro",
|
||||||
domain.SMSConfigStateInactive,
|
domain.SMSConfigStateActive,
|
||||||
uint64(20211109),
|
uint64(20211109),
|
||||||
|
"description",
|
||||||
// twilio config
|
// twilio config
|
||||||
"sms-id",
|
"sms-id",
|
||||||
"sid",
|
"sid",
|
||||||
&crypto.CryptoValue{},
|
&crypto.CryptoValue{},
|
||||||
"sender-number",
|
"sender-number",
|
||||||
|
// http config
|
||||||
|
nil,
|
||||||
|
nil,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"sms-id2",
|
"sms-id2",
|
||||||
@ -165,18 +240,40 @@ func Test_SMSConfigssPrepare(t *testing.T) {
|
|||||||
"ro",
|
"ro",
|
||||||
domain.SMSConfigStateInactive,
|
domain.SMSConfigStateInactive,
|
||||||
uint64(20211109),
|
uint64(20211109),
|
||||||
|
"description",
|
||||||
// twilio config
|
// twilio config
|
||||||
"sms-id2",
|
"sms-id2",
|
||||||
"sid2",
|
"sid2",
|
||||||
&crypto.CryptoValue{},
|
&crypto.CryptoValue{},
|
||||||
"sender-number2",
|
"sender-number2",
|
||||||
|
// http config
|
||||||
|
nil,
|
||||||
|
nil,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"sms-id3",
|
||||||
|
"agg-id",
|
||||||
|
testNow,
|
||||||
|
testNow,
|
||||||
|
"ro",
|
||||||
|
domain.SMSConfigStateInactive,
|
||||||
|
uint64(20211109),
|
||||||
|
"description",
|
||||||
|
// twilio config
|
||||||
|
nil,
|
||||||
|
nil,
|
||||||
|
nil,
|
||||||
|
nil,
|
||||||
|
// http config
|
||||||
|
"sms-id3",
|
||||||
|
"endpoint3",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
},
|
},
|
||||||
object: &SMSConfigs{
|
object: &SMSConfigs{
|
||||||
SearchResponse: SearchResponse{
|
SearchResponse: SearchResponse{
|
||||||
Count: 2,
|
Count: 3,
|
||||||
},
|
},
|
||||||
Configs: []*SMSConfig{
|
Configs: []*SMSConfig{
|
||||||
{
|
{
|
||||||
@ -185,8 +282,9 @@ func Test_SMSConfigssPrepare(t *testing.T) {
|
|||||||
CreationDate: testNow,
|
CreationDate: testNow,
|
||||||
ChangeDate: testNow,
|
ChangeDate: testNow,
|
||||||
ResourceOwner: "ro",
|
ResourceOwner: "ro",
|
||||||
State: domain.SMSConfigStateInactive,
|
State: domain.SMSConfigStateActive,
|
||||||
Sequence: 20211109,
|
Sequence: 20211109,
|
||||||
|
Description: "description",
|
||||||
TwilioConfig: &Twilio{
|
TwilioConfig: &Twilio{
|
||||||
SID: "sid",
|
SID: "sid",
|
||||||
Token: &crypto.CryptoValue{},
|
Token: &crypto.CryptoValue{},
|
||||||
@ -201,12 +299,26 @@ func Test_SMSConfigssPrepare(t *testing.T) {
|
|||||||
ResourceOwner: "ro",
|
ResourceOwner: "ro",
|
||||||
State: domain.SMSConfigStateInactive,
|
State: domain.SMSConfigStateInactive,
|
||||||
Sequence: 20211109,
|
Sequence: 20211109,
|
||||||
|
Description: "description",
|
||||||
TwilioConfig: &Twilio{
|
TwilioConfig: &Twilio{
|
||||||
SID: "sid2",
|
SID: "sid2",
|
||||||
Token: &crypto.CryptoValue{},
|
Token: &crypto.CryptoValue{},
|
||||||
SenderNumber: "sender-number2",
|
SenderNumber: "sender-number2",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
ID: "sms-id3",
|
||||||
|
AggregateID: "agg-id",
|
||||||
|
CreationDate: testNow,
|
||||||
|
ChangeDate: testNow,
|
||||||
|
ResourceOwner: "ro",
|
||||||
|
State: domain.SMSConfigStateInactive,
|
||||||
|
Sequence: 20211109,
|
||||||
|
Description: "description",
|
||||||
|
HTTPConfig: &HTTP{
|
||||||
|
Endpoint: "endpoint3",
|
||||||
|
},
|
||||||
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@ -265,7 +377,50 @@ func Test_SMSConfigPrepare(t *testing.T) {
|
|||||||
object: (*SMSConfig)(nil),
|
object: (*SMSConfig)(nil),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "prepareSMSConfigQuery found",
|
name: "prepareSMSConfigQuery, twilio, found",
|
||||||
|
prepare: prepareSMSConfigQuery,
|
||||||
|
want: want{
|
||||||
|
sqlExpectations: mockQuery(
|
||||||
|
expectedSMSConfigQuery,
|
||||||
|
smsConfigCols,
|
||||||
|
[]driver.Value{
|
||||||
|
"sms-id",
|
||||||
|
"agg-id",
|
||||||
|
testNow,
|
||||||
|
testNow,
|
||||||
|
"ro",
|
||||||
|
domain.SMSConfigStateActive,
|
||||||
|
uint64(20211109),
|
||||||
|
"description",
|
||||||
|
// twilio config
|
||||||
|
"sms-id",
|
||||||
|
"sid",
|
||||||
|
&crypto.CryptoValue{},
|
||||||
|
"sender-number",
|
||||||
|
// http config
|
||||||
|
nil,
|
||||||
|
nil,
|
||||||
|
},
|
||||||
|
),
|
||||||
|
},
|
||||||
|
object: &SMSConfig{
|
||||||
|
ID: "sms-id",
|
||||||
|
AggregateID: "agg-id",
|
||||||
|
CreationDate: testNow,
|
||||||
|
ChangeDate: testNow,
|
||||||
|
ResourceOwner: "ro",
|
||||||
|
State: domain.SMSConfigStateActive,
|
||||||
|
Sequence: 20211109,
|
||||||
|
Description: "description",
|
||||||
|
TwilioConfig: &Twilio{
|
||||||
|
SID: "sid",
|
||||||
|
SenderNumber: "sender-number",
|
||||||
|
Token: &crypto.CryptoValue{},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "prepareSMSConfigQuery, http, found",
|
||||||
prepare: prepareSMSConfigQuery,
|
prepare: prepareSMSConfigQuery,
|
||||||
want: want{
|
want: want{
|
||||||
sqlExpectations: mockQuery(
|
sqlExpectations: mockQuery(
|
||||||
@ -279,11 +434,15 @@ func Test_SMSConfigPrepare(t *testing.T) {
|
|||||||
"ro",
|
"ro",
|
||||||
domain.SMSConfigStateInactive,
|
domain.SMSConfigStateInactive,
|
||||||
uint64(20211109),
|
uint64(20211109),
|
||||||
|
"description",
|
||||||
// twilio config
|
// twilio config
|
||||||
|
nil,
|
||||||
|
nil,
|
||||||
|
nil,
|
||||||
|
nil,
|
||||||
|
// http config
|
||||||
"sms-id",
|
"sms-id",
|
||||||
"sid",
|
"endpoint",
|
||||||
&crypto.CryptoValue{},
|
|
||||||
"sender-number",
|
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
},
|
},
|
||||||
@ -295,10 +454,9 @@ func Test_SMSConfigPrepare(t *testing.T) {
|
|||||||
ResourceOwner: "ro",
|
ResourceOwner: "ro",
|
||||||
State: domain.SMSConfigStateInactive,
|
State: domain.SMSConfigStateInactive,
|
||||||
Sequence: 20211109,
|
Sequence: 20211109,
|
||||||
TwilioConfig: &Twilio{
|
Description: "description",
|
||||||
SID: "sid",
|
HTTPConfig: &HTTP{
|
||||||
SenderNumber: "sender-number",
|
Endpoint: "endpoint",
|
||||||
Token: &crypto.CryptoValue{},
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
@ -18,12 +18,17 @@ func init() {
|
|||||||
eventstore.RegisterFilterEventMapper(AggregateType, SMTPConfigDeactivatedEventType, SMTPConfigDeactivatedEventMapper)
|
eventstore.RegisterFilterEventMapper(AggregateType, SMTPConfigDeactivatedEventType, SMTPConfigDeactivatedEventMapper)
|
||||||
eventstore.RegisterFilterEventMapper(AggregateType, SMTPConfigPasswordChangedEventType, SMTPConfigPasswordChangedEventMapper)
|
eventstore.RegisterFilterEventMapper(AggregateType, SMTPConfigPasswordChangedEventType, SMTPConfigPasswordChangedEventMapper)
|
||||||
eventstore.RegisterFilterEventMapper(AggregateType, SMTPConfigRemovedEventType, SMTPConfigRemovedEventMapper)
|
eventstore.RegisterFilterEventMapper(AggregateType, SMTPConfigRemovedEventType, SMTPConfigRemovedEventMapper)
|
||||||
eventstore.RegisterFilterEventMapper(AggregateType, SMSConfigTwilioAddedEventType, SMSConfigTwilioAddedEventMapper)
|
eventstore.RegisterFilterEventMapper(AggregateType, SMSConfigTwilioAddedEventType, eventstore.GenericEventMapper[SMSConfigTwilioAddedEvent])
|
||||||
eventstore.RegisterFilterEventMapper(AggregateType, SMSConfigTwilioChangedEventType, SMSConfigTwilioChangedEventMapper)
|
eventstore.RegisterFilterEventMapper(AggregateType, SMSConfigTwilioChangedEventType, eventstore.GenericEventMapper[SMSConfigTwilioChangedEvent])
|
||||||
eventstore.RegisterFilterEventMapper(AggregateType, SMSConfigTwilioTokenChangedEventType, SMSConfigTwilioTokenChangedEventMapper)
|
eventstore.RegisterFilterEventMapper(AggregateType, SMSConfigTwilioTokenChangedEventType, eventstore.GenericEventMapper[SMSConfigTwilioTokenChangedEvent])
|
||||||
eventstore.RegisterFilterEventMapper(AggregateType, SMSConfigActivatedEventType, SMSConfigActivatedEventMapper)
|
eventstore.RegisterFilterEventMapper(AggregateType, SMSConfigHTTPAddedEventType, eventstore.GenericEventMapper[SMSConfigHTTPAddedEvent])
|
||||||
eventstore.RegisterFilterEventMapper(AggregateType, SMSConfigDeactivatedEventType, SMSConfigDeactivatedEventMapper)
|
eventstore.RegisterFilterEventMapper(AggregateType, SMSConfigHTTPChangedEventType, eventstore.GenericEventMapper[SMSConfigHTTPChangedEvent])
|
||||||
eventstore.RegisterFilterEventMapper(AggregateType, SMSConfigRemovedEventType, SMSConfigRemovedEventMapper)
|
eventstore.RegisterFilterEventMapper(AggregateType, SMSConfigTwilioActivatedEventType, eventstore.GenericEventMapper[SMSConfigTwilioActivatedEvent])
|
||||||
|
eventstore.RegisterFilterEventMapper(AggregateType, SMSConfigTwilioDeactivatedEventType, eventstore.GenericEventMapper[SMSConfigTwilioDeactivatedEvent])
|
||||||
|
eventstore.RegisterFilterEventMapper(AggregateType, SMSConfigTwilioRemovedEventType, eventstore.GenericEventMapper[SMSConfigTwilioRemovedEvent])
|
||||||
|
eventstore.RegisterFilterEventMapper(AggregateType, SMSConfigActivatedEventType, eventstore.GenericEventMapper[SMSConfigActivatedEvent])
|
||||||
|
eventstore.RegisterFilterEventMapper(AggregateType, SMSConfigDeactivatedEventType, eventstore.GenericEventMapper[SMSConfigDeactivatedEvent])
|
||||||
|
eventstore.RegisterFilterEventMapper(AggregateType, SMSConfigRemovedEventType, eventstore.GenericEventMapper[SMSConfigRemovedEvent])
|
||||||
eventstore.RegisterFilterEventMapper(AggregateType, DebugNotificationProviderFileAddedEventType, DebugNotificationProviderFileAddedEventMapper)
|
eventstore.RegisterFilterEventMapper(AggregateType, DebugNotificationProviderFileAddedEventType, DebugNotificationProviderFileAddedEventMapper)
|
||||||
eventstore.RegisterFilterEventMapper(AggregateType, DebugNotificationProviderFileChangedEventType, DebugNotificationProviderFileChangedEventMapper)
|
eventstore.RegisterFilterEventMapper(AggregateType, DebugNotificationProviderFileChangedEventType, DebugNotificationProviderFileChangedEventMapper)
|
||||||
eventstore.RegisterFilterEventMapper(AggregateType, DebugNotificationProviderFileRemovedEventType, DebugNotificationProviderFileRemovedEventMapper)
|
eventstore.RegisterFilterEventMapper(AggregateType, DebugNotificationProviderFileRemovedEventType, DebugNotificationProviderFileRemovedEventMapper)
|
||||||
|
@ -11,18 +11,25 @@ import (
|
|||||||
const (
|
const (
|
||||||
smsConfigPrefix = "sms.config"
|
smsConfigPrefix = "sms.config"
|
||||||
smsConfigTwilioPrefix = "twilio."
|
smsConfigTwilioPrefix = "twilio."
|
||||||
|
smsConfigHTTPPrefix = "http."
|
||||||
SMSConfigTwilioAddedEventType = instanceEventTypePrefix + smsConfigPrefix + smsConfigTwilioPrefix + "added"
|
SMSConfigTwilioAddedEventType = instanceEventTypePrefix + smsConfigPrefix + smsConfigTwilioPrefix + "added"
|
||||||
SMSConfigTwilioChangedEventType = instanceEventTypePrefix + smsConfigPrefix + smsConfigTwilioPrefix + "changed"
|
SMSConfigTwilioChangedEventType = instanceEventTypePrefix + smsConfigPrefix + smsConfigTwilioPrefix + "changed"
|
||||||
|
SMSConfigHTTPAddedEventType = instanceEventTypePrefix + smsConfigPrefix + smsConfigHTTPPrefix + "added"
|
||||||
|
SMSConfigHTTPChangedEventType = instanceEventTypePrefix + smsConfigPrefix + smsConfigHTTPPrefix + "changed"
|
||||||
SMSConfigTwilioTokenChangedEventType = instanceEventTypePrefix + smsConfigPrefix + smsConfigTwilioPrefix + "token.changed"
|
SMSConfigTwilioTokenChangedEventType = instanceEventTypePrefix + smsConfigPrefix + smsConfigTwilioPrefix + "token.changed"
|
||||||
SMSConfigActivatedEventType = instanceEventTypePrefix + smsConfigPrefix + smsConfigTwilioPrefix + "activated"
|
SMSConfigTwilioActivatedEventType = instanceEventTypePrefix + smsConfigPrefix + smsConfigTwilioPrefix + "activated"
|
||||||
SMSConfigDeactivatedEventType = instanceEventTypePrefix + smsConfigPrefix + smsConfigTwilioPrefix + "deactivated"
|
SMSConfigTwilioDeactivatedEventType = instanceEventTypePrefix + smsConfigPrefix + smsConfigTwilioPrefix + "deactivated"
|
||||||
SMSConfigRemovedEventType = instanceEventTypePrefix + smsConfigPrefix + smsConfigTwilioPrefix + "removed"
|
SMSConfigTwilioRemovedEventType = instanceEventTypePrefix + smsConfigPrefix + smsConfigTwilioPrefix + "removed"
|
||||||
|
SMSConfigActivatedEventType = instanceEventTypePrefix + smsConfigPrefix + "activated"
|
||||||
|
SMSConfigDeactivatedEventType = instanceEventTypePrefix + smsConfigPrefix + "deactivated"
|
||||||
|
SMSConfigRemovedEventType = instanceEventTypePrefix + smsConfigPrefix + "removed"
|
||||||
)
|
)
|
||||||
|
|
||||||
type SMSConfigTwilioAddedEvent struct {
|
type SMSConfigTwilioAddedEvent struct {
|
||||||
eventstore.BaseEvent `json:"-"`
|
*eventstore.BaseEvent `json:"-"`
|
||||||
|
|
||||||
ID string `json:"id,omitempty"`
|
ID string `json:"id,omitempty"`
|
||||||
|
Description string `json:"description,omitempty"`
|
||||||
SID string `json:"sid,omitempty"`
|
SID string `json:"sid,omitempty"`
|
||||||
Token *crypto.CryptoValue `json:"token,omitempty"`
|
Token *crypto.CryptoValue `json:"token,omitempty"`
|
||||||
SenderNumber string `json:"senderNumber,omitempty"`
|
SenderNumber string `json:"senderNumber,omitempty"`
|
||||||
@ -32,23 +39,29 @@ func NewSMSConfigTwilioAddedEvent(
|
|||||||
ctx context.Context,
|
ctx context.Context,
|
||||||
aggregate *eventstore.Aggregate,
|
aggregate *eventstore.Aggregate,
|
||||||
id,
|
id,
|
||||||
|
description string,
|
||||||
sid,
|
sid,
|
||||||
senderNumber string,
|
senderNumber string,
|
||||||
token *crypto.CryptoValue,
|
token *crypto.CryptoValue,
|
||||||
) *SMSConfigTwilioAddedEvent {
|
) *SMSConfigTwilioAddedEvent {
|
||||||
return &SMSConfigTwilioAddedEvent{
|
return &SMSConfigTwilioAddedEvent{
|
||||||
BaseEvent: *eventstore.NewBaseEventForPush(
|
BaseEvent: eventstore.NewBaseEventForPush(
|
||||||
ctx,
|
ctx,
|
||||||
aggregate,
|
aggregate,
|
||||||
SMSConfigTwilioAddedEventType,
|
SMSConfigTwilioAddedEventType,
|
||||||
),
|
),
|
||||||
ID: id,
|
ID: id,
|
||||||
|
Description: description,
|
||||||
SID: sid,
|
SID: sid,
|
||||||
Token: token,
|
Token: token,
|
||||||
SenderNumber: senderNumber,
|
SenderNumber: senderNumber,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (e *SMSConfigTwilioAddedEvent) SetBaseEvent(event *eventstore.BaseEvent) {
|
||||||
|
e.BaseEvent = event
|
||||||
|
}
|
||||||
|
|
||||||
func (e *SMSConfigTwilioAddedEvent) Payload() interface{} {
|
func (e *SMSConfigTwilioAddedEvent) Payload() interface{} {
|
||||||
return e
|
return e
|
||||||
}
|
}
|
||||||
@ -57,22 +70,11 @@ func (e *SMSConfigTwilioAddedEvent) UniqueConstraints() []*eventstore.UniqueCons
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func SMSConfigTwilioAddedEventMapper(event eventstore.Event) (eventstore.Event, error) {
|
|
||||||
smsConfigAdded := &SMSConfigTwilioAddedEvent{
|
|
||||||
BaseEvent: *eventstore.BaseEventFromRepo(event),
|
|
||||||
}
|
|
||||||
err := event.Unmarshal(smsConfigAdded)
|
|
||||||
if err != nil {
|
|
||||||
return nil, zerrors.ThrowInternal(err, "IAM-smwiR", "unable to unmarshal sms config twilio added")
|
|
||||||
}
|
|
||||||
|
|
||||||
return smsConfigAdded, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
type SMSConfigTwilioChangedEvent struct {
|
type SMSConfigTwilioChangedEvent struct {
|
||||||
eventstore.BaseEvent `json:"-"`
|
*eventstore.BaseEvent `json:"-"`
|
||||||
|
|
||||||
ID string `json:"id,omitempty"`
|
ID string `json:"id,omitempty"`
|
||||||
|
Description *string `json:"description,omitempty"`
|
||||||
SID *string `json:"sid,omitempty"`
|
SID *string `json:"sid,omitempty"`
|
||||||
SenderNumber *string `json:"senderNumber,omitempty"`
|
SenderNumber *string `json:"senderNumber,omitempty"`
|
||||||
}
|
}
|
||||||
@ -87,7 +89,7 @@ func NewSMSConfigTwilioChangedEvent(
|
|||||||
return nil, zerrors.ThrowPreconditionFailed(nil, "IAM-smn8e", "Errors.NoChangesFound")
|
return nil, zerrors.ThrowPreconditionFailed(nil, "IAM-smn8e", "Errors.NoChangesFound")
|
||||||
}
|
}
|
||||||
changeEvent := &SMSConfigTwilioChangedEvent{
|
changeEvent := &SMSConfigTwilioChangedEvent{
|
||||||
BaseEvent: *eventstore.NewBaseEventForPush(
|
BaseEvent: eventstore.NewBaseEventForPush(
|
||||||
ctx,
|
ctx,
|
||||||
aggregate,
|
aggregate,
|
||||||
SMSConfigTwilioChangedEventType,
|
SMSConfigTwilioChangedEventType,
|
||||||
@ -108,12 +110,22 @@ func ChangeSMSConfigTwilioSID(sid string) func(event *SMSConfigTwilioChangedEven
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func ChangeSMSConfigTwilioDescription(description string) func(event *SMSConfigTwilioChangedEvent) {
|
||||||
|
return func(e *SMSConfigTwilioChangedEvent) {
|
||||||
|
e.Description = &description
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func ChangeSMSConfigTwilioSenderNumber(senderNumber string) func(event *SMSConfigTwilioChangedEvent) {
|
func ChangeSMSConfigTwilioSenderNumber(senderNumber string) func(event *SMSConfigTwilioChangedEvent) {
|
||||||
return func(e *SMSConfigTwilioChangedEvent) {
|
return func(e *SMSConfigTwilioChangedEvent) {
|
||||||
e.SenderNumber = &senderNumber
|
e.SenderNumber = &senderNumber
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (e *SMSConfigTwilioChangedEvent) SetBaseEvent(event *eventstore.BaseEvent) {
|
||||||
|
e.BaseEvent = event
|
||||||
|
}
|
||||||
|
|
||||||
func (e *SMSConfigTwilioChangedEvent) Payload() interface{} {
|
func (e *SMSConfigTwilioChangedEvent) Payload() interface{} {
|
||||||
return e
|
return e
|
||||||
}
|
}
|
||||||
@ -122,20 +134,8 @@ func (e *SMSConfigTwilioChangedEvent) UniqueConstraints() []*eventstore.UniqueCo
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func SMSConfigTwilioChangedEventMapper(event eventstore.Event) (eventstore.Event, error) {
|
|
||||||
smsConfigChanged := &SMSConfigTwilioChangedEvent{
|
|
||||||
BaseEvent: *eventstore.BaseEventFromRepo(event),
|
|
||||||
}
|
|
||||||
err := event.Unmarshal(smsConfigChanged)
|
|
||||||
if err != nil {
|
|
||||||
return nil, zerrors.ThrowInternal(err, "IAM-smwiR", "unable to unmarshal sms config twilio added")
|
|
||||||
}
|
|
||||||
|
|
||||||
return smsConfigChanged, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
type SMSConfigTwilioTokenChangedEvent struct {
|
type SMSConfigTwilioTokenChangedEvent struct {
|
||||||
eventstore.BaseEvent `json:"-"`
|
*eventstore.BaseEvent `json:"-"`
|
||||||
|
|
||||||
ID string `json:"id,omitempty"`
|
ID string `json:"id,omitempty"`
|
||||||
Token *crypto.CryptoValue `json:"token,omitempty"`
|
Token *crypto.CryptoValue `json:"token,omitempty"`
|
||||||
@ -148,7 +148,7 @@ func NewSMSConfigTokenChangedEvent(
|
|||||||
token *crypto.CryptoValue,
|
token *crypto.CryptoValue,
|
||||||
) *SMSConfigTwilioTokenChangedEvent {
|
) *SMSConfigTwilioTokenChangedEvent {
|
||||||
return &SMSConfigTwilioTokenChangedEvent{
|
return &SMSConfigTwilioTokenChangedEvent{
|
||||||
BaseEvent: *eventstore.NewBaseEventForPush(
|
BaseEvent: eventstore.NewBaseEventForPush(
|
||||||
ctx,
|
ctx,
|
||||||
aggregate,
|
aggregate,
|
||||||
SMSConfigTwilioTokenChangedEventType,
|
SMSConfigTwilioTokenChangedEventType,
|
||||||
@ -158,6 +158,10 @@ func NewSMSConfigTokenChangedEvent(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (e *SMSConfigTwilioTokenChangedEvent) SetBaseEvent(event *eventstore.BaseEvent) {
|
||||||
|
e.BaseEvent = event
|
||||||
|
}
|
||||||
|
|
||||||
func (e *SMSConfigTwilioTokenChangedEvent) Payload() interface{} {
|
func (e *SMSConfigTwilioTokenChangedEvent) Payload() interface{} {
|
||||||
return e
|
return e
|
||||||
}
|
}
|
||||||
@ -166,30 +170,130 @@ func (e *SMSConfigTwilioTokenChangedEvent) UniqueConstraints() []*eventstore.Uni
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func SMSConfigTwilioTokenChangedEventMapper(event eventstore.Event) (eventstore.Event, error) {
|
type SMSConfigHTTPAddedEvent struct {
|
||||||
smtpConfigTokenChagned := &SMSConfigTwilioTokenChangedEvent{
|
*eventstore.BaseEvent `json:"-"`
|
||||||
BaseEvent: *eventstore.BaseEventFromRepo(event),
|
|
||||||
}
|
|
||||||
err := event.Unmarshal(smtpConfigTokenChagned)
|
|
||||||
if err != nil {
|
|
||||||
return nil, zerrors.ThrowInternal(err, "IAM-fi9Wf", "unable to unmarshal sms config token changed")
|
|
||||||
}
|
|
||||||
|
|
||||||
return smtpConfigTokenChagned, nil
|
ID string `json:"id,omitempty"`
|
||||||
|
Description string `json:"description,omitempty"`
|
||||||
|
Endpoint string `json:"endpoint,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type SMSConfigActivatedEvent struct {
|
func NewSMSConfigHTTPAddedEvent(
|
||||||
eventstore.BaseEvent `json:"-"`
|
ctx context.Context,
|
||||||
|
aggregate *eventstore.Aggregate,
|
||||||
|
id,
|
||||||
|
description,
|
||||||
|
endpoint string,
|
||||||
|
) *SMSConfigHTTPAddedEvent {
|
||||||
|
return &SMSConfigHTTPAddedEvent{
|
||||||
|
BaseEvent: eventstore.NewBaseEventForPush(
|
||||||
|
ctx,
|
||||||
|
aggregate,
|
||||||
|
SMSConfigHTTPAddedEventType,
|
||||||
|
),
|
||||||
|
ID: id,
|
||||||
|
Description: description,
|
||||||
|
Endpoint: endpoint,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (e *SMSConfigHTTPAddedEvent) SetBaseEvent(event *eventstore.BaseEvent) {
|
||||||
|
e.BaseEvent = event
|
||||||
|
}
|
||||||
|
|
||||||
|
func (e *SMSConfigHTTPAddedEvent) Payload() interface{} {
|
||||||
|
return e
|
||||||
|
}
|
||||||
|
|
||||||
|
func (e *SMSConfigHTTPAddedEvent) UniqueConstraints() []*eventstore.UniqueConstraint {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
type SMSConfigHTTPChangedEvent struct {
|
||||||
|
*eventstore.BaseEvent `json:"-"`
|
||||||
|
|
||||||
|
ID string `json:"id,omitempty"`
|
||||||
|
Description *string `json:"description,omitempty"`
|
||||||
|
Endpoint *string `json:"endpoint,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewSMSConfigHTTPChangedEvent(
|
||||||
|
ctx context.Context,
|
||||||
|
aggregate *eventstore.Aggregate,
|
||||||
|
id string,
|
||||||
|
changes []SMSConfigHTTPChanges,
|
||||||
|
) (*SMSConfigHTTPChangedEvent, error) {
|
||||||
|
if len(changes) == 0 {
|
||||||
|
return nil, zerrors.ThrowPreconditionFailed(nil, "IAM-smn8e", "Errors.NoChangesFound")
|
||||||
|
}
|
||||||
|
changeEvent := &SMSConfigHTTPChangedEvent{
|
||||||
|
BaseEvent: eventstore.NewBaseEventForPush(
|
||||||
|
ctx,
|
||||||
|
aggregate,
|
||||||
|
SMSConfigHTTPChangedEventType,
|
||||||
|
),
|
||||||
|
ID: id,
|
||||||
|
}
|
||||||
|
for _, change := range changes {
|
||||||
|
change(changeEvent)
|
||||||
|
}
|
||||||
|
return changeEvent, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
type SMSConfigHTTPChanges func(event *SMSConfigHTTPChangedEvent)
|
||||||
|
|
||||||
|
func ChangeSMSConfigHTTPDescription(description string) func(event *SMSConfigHTTPChangedEvent) {
|
||||||
|
return func(e *SMSConfigHTTPChangedEvent) {
|
||||||
|
e.Description = &description
|
||||||
|
}
|
||||||
|
}
|
||||||
|
func ChangeSMSConfigHTTPEndpoint(endpoint string) func(event *SMSConfigHTTPChangedEvent) {
|
||||||
|
return func(e *SMSConfigHTTPChangedEvent) {
|
||||||
|
e.Endpoint = &endpoint
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (e *SMSConfigHTTPChangedEvent) SetBaseEvent(event *eventstore.BaseEvent) {
|
||||||
|
e.BaseEvent = event
|
||||||
|
}
|
||||||
|
|
||||||
|
func (e *SMSConfigHTTPChangedEvent) Payload() interface{} {
|
||||||
|
return e
|
||||||
|
}
|
||||||
|
|
||||||
|
func (e *SMSConfigHTTPChangedEvent) UniqueConstraints() []*eventstore.UniqueConstraint {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
type SMSConfigTwilioActivatedEvent struct {
|
||||||
|
*eventstore.BaseEvent `json:"-"`
|
||||||
ID string `json:"id,omitempty"`
|
ID string `json:"id,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewSMSConfigTwilioActivatedEvent(
|
func (e *SMSConfigTwilioActivatedEvent) SetBaseEvent(event *eventstore.BaseEvent) {
|
||||||
|
e.BaseEvent = event
|
||||||
|
}
|
||||||
|
|
||||||
|
func (e *SMSConfigTwilioActivatedEvent) Payload() interface{} {
|
||||||
|
return e
|
||||||
|
}
|
||||||
|
|
||||||
|
func (e *SMSConfigTwilioActivatedEvent) UniqueConstraints() []*eventstore.UniqueConstraint {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
type SMSConfigActivatedEvent struct {
|
||||||
|
*eventstore.BaseEvent `json:"-"`
|
||||||
|
ID string `json:"id,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewSMSConfigActivatedEvent(
|
||||||
ctx context.Context,
|
ctx context.Context,
|
||||||
aggregate *eventstore.Aggregate,
|
aggregate *eventstore.Aggregate,
|
||||||
id string,
|
id string,
|
||||||
) *SMSConfigActivatedEvent {
|
) *SMSConfigActivatedEvent {
|
||||||
return &SMSConfigActivatedEvent{
|
return &SMSConfigActivatedEvent{
|
||||||
BaseEvent: *eventstore.NewBaseEventForPush(
|
BaseEvent: eventstore.NewBaseEventForPush(
|
||||||
ctx,
|
ctx,
|
||||||
aggregate,
|
aggregate,
|
||||||
SMSConfigActivatedEventType,
|
SMSConfigActivatedEventType,
|
||||||
@ -198,6 +302,10 @@ func NewSMSConfigTwilioActivatedEvent(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (e *SMSConfigActivatedEvent) SetBaseEvent(event *eventstore.BaseEvent) {
|
||||||
|
e.BaseEvent = event
|
||||||
|
}
|
||||||
|
|
||||||
func (e *SMSConfigActivatedEvent) Payload() interface{} {
|
func (e *SMSConfigActivatedEvent) Payload() interface{} {
|
||||||
return e
|
return e
|
||||||
}
|
}
|
||||||
@ -206,20 +314,25 @@ func (e *SMSConfigActivatedEvent) UniqueConstraints() []*eventstore.UniqueConstr
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func SMSConfigActivatedEventMapper(event eventstore.Event) (eventstore.Event, error) {
|
type SMSConfigTwilioDeactivatedEvent struct {
|
||||||
smsConfigActivated := &SMSConfigActivatedEvent{
|
*eventstore.BaseEvent `json:"-"`
|
||||||
BaseEvent: *eventstore.BaseEventFromRepo(event),
|
ID string `json:"id,omitempty"`
|
||||||
}
|
}
|
||||||
err := event.Unmarshal(smsConfigActivated)
|
|
||||||
if err != nil {
|
|
||||||
return nil, zerrors.ThrowInternal(err, "IAM-dn92f", "unable to unmarshal sms config twilio activated changed")
|
|
||||||
}
|
|
||||||
|
|
||||||
return smsConfigActivated, nil
|
func (e *SMSConfigTwilioDeactivatedEvent) SetBaseEvent(event *eventstore.BaseEvent) {
|
||||||
|
e.BaseEvent = event
|
||||||
|
}
|
||||||
|
|
||||||
|
func (e *SMSConfigTwilioDeactivatedEvent) Payload() interface{} {
|
||||||
|
return e
|
||||||
|
}
|
||||||
|
|
||||||
|
func (e *SMSConfigTwilioDeactivatedEvent) UniqueConstraints() []*eventstore.UniqueConstraint {
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
type SMSConfigDeactivatedEvent struct {
|
type SMSConfigDeactivatedEvent struct {
|
||||||
eventstore.BaseEvent `json:"-"`
|
*eventstore.BaseEvent `json:"-"`
|
||||||
ID string `json:"id,omitempty"`
|
ID string `json:"id,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -229,7 +342,7 @@ func NewSMSConfigDeactivatedEvent(
|
|||||||
id string,
|
id string,
|
||||||
) *SMSConfigDeactivatedEvent {
|
) *SMSConfigDeactivatedEvent {
|
||||||
return &SMSConfigDeactivatedEvent{
|
return &SMSConfigDeactivatedEvent{
|
||||||
BaseEvent: *eventstore.NewBaseEventForPush(
|
BaseEvent: eventstore.NewBaseEventForPush(
|
||||||
ctx,
|
ctx,
|
||||||
aggregate,
|
aggregate,
|
||||||
SMSConfigDeactivatedEventType,
|
SMSConfigDeactivatedEventType,
|
||||||
@ -238,6 +351,10 @@ func NewSMSConfigDeactivatedEvent(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (e *SMSConfigDeactivatedEvent) SetBaseEvent(event *eventstore.BaseEvent) {
|
||||||
|
e.BaseEvent = event
|
||||||
|
}
|
||||||
|
|
||||||
func (e *SMSConfigDeactivatedEvent) Payload() interface{} {
|
func (e *SMSConfigDeactivatedEvent) Payload() interface{} {
|
||||||
return e
|
return e
|
||||||
}
|
}
|
||||||
@ -246,20 +363,25 @@ func (e *SMSConfigDeactivatedEvent) UniqueConstraints() []*eventstore.UniqueCons
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func SMSConfigDeactivatedEventMapper(event eventstore.Event) (eventstore.Event, error) {
|
type SMSConfigTwilioRemovedEvent struct {
|
||||||
smsConfigDeactivated := &SMSConfigDeactivatedEvent{
|
*eventstore.BaseEvent `json:"-"`
|
||||||
BaseEvent: *eventstore.BaseEventFromRepo(event),
|
ID string `json:"id,omitempty"`
|
||||||
}
|
}
|
||||||
err := event.Unmarshal(smsConfigDeactivated)
|
|
||||||
if err != nil {
|
|
||||||
return nil, zerrors.ThrowInternal(err, "IAM-dn92f", "unable to unmarshal sms config twilio deactivated changed")
|
|
||||||
}
|
|
||||||
|
|
||||||
return smsConfigDeactivated, nil
|
func (e *SMSConfigTwilioRemovedEvent) SetBaseEvent(event *eventstore.BaseEvent) {
|
||||||
|
e.BaseEvent = event
|
||||||
|
}
|
||||||
|
|
||||||
|
func (e *SMSConfigTwilioRemovedEvent) Payload() interface{} {
|
||||||
|
return e
|
||||||
|
}
|
||||||
|
|
||||||
|
func (e *SMSConfigTwilioRemovedEvent) UniqueConstraints() []*eventstore.UniqueConstraint {
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
type SMSConfigRemovedEvent struct {
|
type SMSConfigRemovedEvent struct {
|
||||||
eventstore.BaseEvent `json:"-"`
|
*eventstore.BaseEvent `json:"-"`
|
||||||
ID string `json:"id,omitempty"`
|
ID string `json:"id,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -269,7 +391,7 @@ func NewSMSConfigRemovedEvent(
|
|||||||
id string,
|
id string,
|
||||||
) *SMSConfigRemovedEvent {
|
) *SMSConfigRemovedEvent {
|
||||||
return &SMSConfigRemovedEvent{
|
return &SMSConfigRemovedEvent{
|
||||||
BaseEvent: *eventstore.NewBaseEventForPush(
|
BaseEvent: eventstore.NewBaseEventForPush(
|
||||||
ctx,
|
ctx,
|
||||||
aggregate,
|
aggregate,
|
||||||
SMSConfigRemovedEventType,
|
SMSConfigRemovedEventType,
|
||||||
@ -278,6 +400,10 @@ func NewSMSConfigRemovedEvent(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (e *SMSConfigRemovedEvent) SetBaseEvent(event *eventstore.BaseEvent) {
|
||||||
|
e.BaseEvent = event
|
||||||
|
}
|
||||||
|
|
||||||
func (e *SMSConfigRemovedEvent) Payload() interface{} {
|
func (e *SMSConfigRemovedEvent) Payload() interface{} {
|
||||||
return e
|
return e
|
||||||
}
|
}
|
||||||
@ -285,15 +411,3 @@ func (e *SMSConfigRemovedEvent) Payload() interface{} {
|
|||||||
func (e *SMSConfigRemovedEvent) UniqueConstraints() []*eventstore.UniqueConstraint {
|
func (e *SMSConfigRemovedEvent) UniqueConstraints() []*eventstore.UniqueConstraint {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func SMSConfigRemovedEventMapper(event eventstore.Event) (eventstore.Event, error) {
|
|
||||||
smsConfigRemoved := &SMSConfigRemovedEvent{
|
|
||||||
BaseEvent: *eventstore.BaseEventFromRepo(event),
|
|
||||||
}
|
|
||||||
err := event.Unmarshal(smsConfigRemoved)
|
|
||||||
if err != nil {
|
|
||||||
return nil, zerrors.ThrowInternal(err, "IAM-99iNF", "unable to unmarshal sms config removed")
|
|
||||||
}
|
|
||||||
|
|
||||||
return smsConfigRemoved, nil
|
|
||||||
}
|
|
||||||
|
@ -690,6 +690,40 @@ service AdminService {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
rpc AddSMSProviderHTTP(AddSMSProviderHTTPRequest) returns (AddSMSProviderHTTPResponse) {
|
||||||
|
option (google.api.http) = {
|
||||||
|
post: "/sms/http";
|
||||||
|
body: "*"
|
||||||
|
};
|
||||||
|
|
||||||
|
option (zitadel.v1.auth_option) = {
|
||||||
|
permission: "iam.write";
|
||||||
|
};
|
||||||
|
|
||||||
|
option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_operation) = {
|
||||||
|
tags: "SMS Provider";
|
||||||
|
summary: "Add HTTP SMS Provider";
|
||||||
|
description: "Configure a new SMS provider of the type HTTP. A provider has to be activated to be able to send notifications."
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
rpc UpdateSMSProviderHTTP(UpdateSMSProviderHTTPRequest) returns (UpdateSMSProviderHTTPResponse) {
|
||||||
|
option (google.api.http) = {
|
||||||
|
put: "/sms/http/{id}";
|
||||||
|
body: "*"
|
||||||
|
};
|
||||||
|
|
||||||
|
option (zitadel.v1.auth_option) = {
|
||||||
|
permission: "iam.write";
|
||||||
|
};
|
||||||
|
|
||||||
|
option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_operation) = {
|
||||||
|
tags: "SMS Provider";
|
||||||
|
summary: "Update HTTP SMS Provider";
|
||||||
|
description: "Change the configuration of an SMS provider of the type HTTP. A provider has to be activated to be able to send notifications."
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
rpc ActivateSMSProvider(ActivateSMSProviderRequest) returns (ActivateSMSProviderResponse) {
|
rpc ActivateSMSProvider(ActivateSMSProviderRequest) returns (ActivateSMSProviderResponse) {
|
||||||
option (google.api.http) = {
|
option (google.api.http) = {
|
||||||
post: "/sms/{id}/_activate";
|
post: "/sms/{id}/_activate";
|
||||||
@ -4507,6 +4541,14 @@ message AddSMSProviderTwilioRequest {
|
|||||||
max_length: 200;
|
max_length: 200;
|
||||||
}
|
}
|
||||||
];
|
];
|
||||||
|
string description = 4 [
|
||||||
|
(validate.rules).string = {min_len: 0, max_len: 200},
|
||||||
|
(grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = {
|
||||||
|
example: "\"provider description\"";
|
||||||
|
min_length: 0;
|
||||||
|
max_length: 200;
|
||||||
|
}
|
||||||
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
message AddSMSProviderTwilioResponse {
|
message AddSMSProviderTwilioResponse {
|
||||||
@ -4534,6 +4576,14 @@ message UpdateSMSProviderTwilioRequest {
|
|||||||
max_length: 200;
|
max_length: 200;
|
||||||
}
|
}
|
||||||
];
|
];
|
||||||
|
string description = 4 [
|
||||||
|
(validate.rules).string = {min_len: 0, max_len: 200},
|
||||||
|
(grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = {
|
||||||
|
example: "\"provider description\"";
|
||||||
|
min_length: 0;
|
||||||
|
max_length: 200;
|
||||||
|
}
|
||||||
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
message UpdateSMSProviderTwilioResponse {
|
message UpdateSMSProviderTwilioResponse {
|
||||||
@ -4549,6 +4599,56 @@ message UpdateSMSProviderTwilioTokenResponse {
|
|||||||
zitadel.v1.ObjectDetails details = 1;
|
zitadel.v1.ObjectDetails details = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
message AddSMSProviderHTTPRequest {
|
||||||
|
string endpoint = 1 [
|
||||||
|
(validate.rules).string = {min_len: 1, max_len: 2048},
|
||||||
|
(google.api.field_behavior) = REQUIRED,
|
||||||
|
(grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = {
|
||||||
|
example: "\"http://relay.example.com/provider\"";
|
||||||
|
min_length: 1;
|
||||||
|
max_length: 2048;
|
||||||
|
}
|
||||||
|
];
|
||||||
|
string description = 2 [
|
||||||
|
(validate.rules).string = {min_len: 0, max_len: 200},
|
||||||
|
(grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = {
|
||||||
|
example: "\"provider description\"";
|
||||||
|
min_length: 0;
|
||||||
|
max_length: 200;
|
||||||
|
}
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
message AddSMSProviderHTTPResponse {
|
||||||
|
zitadel.v1.ObjectDetails details = 1;
|
||||||
|
string id = 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
message UpdateSMSProviderHTTPRequest {
|
||||||
|
string id = 1 [(validate.rules).string = {min_len: 1, max_len: 200}];
|
||||||
|
string endpoint = 2 [
|
||||||
|
(validate.rules).string = {min_len: 1, max_len: 2048},
|
||||||
|
(google.api.field_behavior) = REQUIRED,
|
||||||
|
(grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = {
|
||||||
|
example: "\"http://relay.example.com/provider\"";
|
||||||
|
min_length: 1;
|
||||||
|
max_length: 2048;
|
||||||
|
}
|
||||||
|
];
|
||||||
|
string description = 3 [
|
||||||
|
(validate.rules).string = {min_len: 0, max_len: 200},
|
||||||
|
(grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = {
|
||||||
|
example: "\"provider description\"";
|
||||||
|
min_length: 0;
|
||||||
|
max_length: 200;
|
||||||
|
}
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
message UpdateSMSProviderHTTPResponse {
|
||||||
|
zitadel.v1.ObjectDetails details = 1;
|
||||||
|
}
|
||||||
|
|
||||||
message ActivateSMSProviderRequest {
|
message ActivateSMSProviderRequest {
|
||||||
string id = 1 [(validate.rules).string = {min_len: 1, max_len: 200}];
|
string id = 1 [(validate.rules).string = {min_len: 1, max_len: 200}];
|
||||||
}
|
}
|
||||||
|
@ -7,7 +7,7 @@ import "protoc-gen-openapiv2/options/annotations.proto";
|
|||||||
|
|
||||||
package zitadel.settings.v1;
|
package zitadel.settings.v1;
|
||||||
|
|
||||||
option go_package ="github.com/zitadel/zitadel/pkg/grpc/settings";
|
option go_package = "github.com/zitadel/zitadel/pkg/grpc/settings";
|
||||||
|
|
||||||
message SecretGenerator {
|
message SecretGenerator {
|
||||||
SecretGeneratorType generator_type = 1;
|
SecretGeneratorType generator_type = 1;
|
||||||
@ -99,9 +99,11 @@ message SMSProvider {
|
|||||||
zitadel.v1.ObjectDetails details = 1;
|
zitadel.v1.ObjectDetails details = 1;
|
||||||
string id = 2;
|
string id = 2;
|
||||||
SMSProviderConfigState state = 3;
|
SMSProviderConfigState state = 3;
|
||||||
|
string description = 6;
|
||||||
|
|
||||||
oneof config {
|
oneof config {
|
||||||
TwilioConfig twilio = 4;
|
TwilioConfig twilio = 4;
|
||||||
|
HTTPConfig http = 5;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -110,6 +112,10 @@ message TwilioConfig {
|
|||||||
string sender_number = 2;
|
string sender_number = 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
message HTTPConfig {
|
||||||
|
string endpoint = 1;
|
||||||
|
}
|
||||||
|
|
||||||
enum SMSProviderConfigState {
|
enum SMSProviderConfigState {
|
||||||
SMS_PROVIDER_CONFIG_STATE_UNSPECIFIED = 0;
|
SMS_PROVIDER_CONFIG_STATE_UNSPECIFIED = 0;
|
||||||
SMS_PROVIDER_CONFIG_ACTIVE = 1;
|
SMS_PROVIDER_CONFIG_ACTIVE = 1;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user