mirror of
https://github.com/zitadel/zitadel.git
synced 2024-12-04 23:45:07 +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) {
|
||||
id, result, err := s.command.AddSMSConfigTwilio(ctx, authz.GetInstance(ctx).InstanceID(), AddSMSConfigTwilioToConfig(req))
|
||||
if err != nil {
|
||||
smsConfig := addSMSConfigTwilioToConfig(ctx, req)
|
||||
if err := s.command.AddSMSConfigTwilio(ctx, smsConfig); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &admin_pb.AddSMSProviderTwilioResponse{
|
||||
Details: object.DomainToAddDetailsPb(result),
|
||||
Id: id,
|
||||
Details: object.DomainToAddDetailsPb(smsConfig.Details),
|
||||
Id: smsConfig.ID,
|
||||
}, nil
|
||||
}
|
||||
|
||||
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))
|
||||
if err != nil {
|
||||
smsConfig := updateSMSConfigTwilioToConfig(ctx, req)
|
||||
if err := s.command.ChangeSMSConfigTwilio(ctx, smsConfig); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &admin_pb.UpdateSMSProviderTwilioResponse{
|
||||
Details: object.DomainToChangeDetailsPb(result),
|
||||
Details: object.DomainToChangeDetailsPb(smsConfig.Details),
|
||||
}, nil
|
||||
}
|
||||
|
||||
@ -65,6 +65,27 @@ func (s *Server) UpdateSMSProviderTwilioToken(ctx context.Context, req *admin_pb
|
||||
}, 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) {
|
||||
result, err := s.command.ActivateSMSConfig(ctx, authz.GetInstance(ctx).InstanceID(), req.Id)
|
||||
if err != nil {
|
||||
|
@ -1,9 +1,14 @@
|
||||
package admin
|
||||
|
||||
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/command"
|
||||
"github.com/zitadel/zitadel/internal/domain"
|
||||
"github.com/zitadel/zitadel/internal/notification/channels/twilio"
|
||||
"github.com/zitadel/zitadel/internal/query"
|
||||
admin_pb "github.com/zitadel/zitadel/pkg/grpc/admin"
|
||||
settings_pb "github.com/zitadel/zitadel/pkg/grpc/settings"
|
||||
@ -30,10 +35,11 @@ func SMSConfigsToPb(configs []*query.SMSConfig) []*settings_pb.SMSProvider {
|
||||
|
||||
func SMSConfigToProviderPb(config *query.SMSConfig) *settings_pb.SMSProvider {
|
||||
return &settings_pb.SMSProvider{
|
||||
Details: object.ToViewDetailsPb(config.Sequence, config.CreationDate, config.ChangeDate, config.ResourceOwner),
|
||||
Id: config.ID,
|
||||
State: smsStateToPb(config.State),
|
||||
Config: SMSConfigToPb(config),
|
||||
Details: object.ToViewDetailsPb(config.Sequence, config.CreationDate, config.ChangeDate, config.ResourceOwner),
|
||||
Id: config.ID,
|
||||
Description: config.Description,
|
||||
State: smsStateToPb(config.State),
|
||||
Config: SMSConfigToPb(config),
|
||||
}
|
||||
}
|
||||
|
||||
@ -41,9 +47,20 @@ func SMSConfigToPb(config *query.SMSConfig) settings_pb.SMSConfig {
|
||||
if config.TwilioConfig != nil {
|
||||
return TwilioConfigToPb(config.TwilioConfig)
|
||||
}
|
||||
if config.HTTPConfig != nil {
|
||||
return HTTPConfigToPb(config.HTTPConfig)
|
||||
}
|
||||
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 {
|
||||
return &settings_pb.SMSProvider_Twilio{
|
||||
Twilio: &settings_pb.TwilioConfig{
|
||||
@ -64,17 +81,39 @@ func smsStateToPb(state domain.SMSConfigState) settings_pb.SMSProviderConfigStat
|
||||
}
|
||||
}
|
||||
|
||||
func AddSMSConfigTwilioToConfig(req *admin_pb.AddSMSProviderTwilioRequest) *twilio.Config {
|
||||
return &twilio.Config{
|
||||
SID: req.Sid,
|
||||
SenderNumber: req.SenderNumber,
|
||||
Token: req.Token,
|
||||
func addSMSConfigTwilioToConfig(ctx context.Context, req *admin_pb.AddSMSProviderTwilioRequest) *command.AddTwilioConfig {
|
||||
return &command.AddTwilioConfig{
|
||||
ResourceOwner: authz.GetInstance(ctx).InstanceID(),
|
||||
Description: req.Description,
|
||||
SID: req.Sid,
|
||||
SenderNumber: req.SenderNumber,
|
||||
Token: req.Token,
|
||||
}
|
||||
}
|
||||
|
||||
func UpdateSMSConfigTwilioToConfig(req *admin_pb.UpdateSMSProviderTwilioRequest) *twilio.Config {
|
||||
return &twilio.Config{
|
||||
SID: req.Sid,
|
||||
SenderNumber: req.SenderNumber,
|
||||
func updateSMSConfigTwilioToConfig(ctx context.Context, req *admin_pb.UpdateSMSProviderTwilioRequest) *command.ChangeTwilioConfig {
|
||||
return &command.ChangeTwilioConfig{
|
||||
ResourceOwner: authz.GetInstance(ctx).InstanceID(),
|
||||
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/domain"
|
||||
"github.com/zitadel/zitadel/internal/notification/channels/twilio"
|
||||
"github.com/zitadel/zitadel/internal/repository/instance"
|
||||
"github.com/zitadel/zitadel/internal/zerrors"
|
||||
)
|
||||
|
||||
func (c *Commands) AddSMSConfigTwilio(ctx context.Context, instanceID string, config *twilio.Config) (string, *domain.ObjectDetails, error) {
|
||||
id, err := c.idGenerator.Next()
|
||||
if err != nil {
|
||||
return "", nil, err
|
||||
type AddTwilioConfig struct {
|
||||
Details *domain.ObjectDetails
|
||||
ResourceOwner string
|
||||
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 {
|
||||
return err
|
||||
}
|
||||
}
|
||||
smsConfigWriteModel, err := c.getSMSConfig(ctx, config.ResourceOwner, config.ID)
|
||||
if err != nil {
|
||||
return "", nil, err
|
||||
return err
|
||||
}
|
||||
|
||||
var token *crypto.CryptoValue
|
||||
if config.Token != "" {
|
||||
token, err = crypto.Encrypt([]byte(config.Token), c.smsEncryption)
|
||||
if err != nil {
|
||||
return "", nil, err
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
iamAgg := InstanceAggregateFromWriteModel(&smsConfigWriteModel.WriteModel)
|
||||
pushedEvents, err := c.eventstore.Push(ctx, instance.NewSMSConfigTwilioAddedEvent(
|
||||
ctx,
|
||||
iamAgg,
|
||||
id,
|
||||
config.SID,
|
||||
config.SenderNumber,
|
||||
token))
|
||||
err = c.pushAppendAndReduce(ctx,
|
||||
smsConfigWriteModel,
|
||||
instance.NewSMSConfigTwilioAddedEvent(
|
||||
ctx,
|
||||
InstanceAggregateFromWriteModel(&smsConfigWriteModel.WriteModel),
|
||||
config.ID,
|
||||
config.Description,
|
||||
config.SID,
|
||||
config.SenderNumber,
|
||||
token,
|
||||
),
|
||||
)
|
||||
if err != nil {
|
||||
return "", nil, err
|
||||
return err
|
||||
}
|
||||
err = AppendAndReduce(smsConfigWriteModel, pushedEvents...)
|
||||
if err != nil {
|
||||
return "", nil, err
|
||||
}
|
||||
return id, writeModelToObjectDetails(&smsConfigWriteModel.WriteModel), nil
|
||||
config.Details = writeModelToObjectDetails(&smsConfigWriteModel.WriteModel)
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *Commands) ChangeSMSConfigTwilio(ctx context.Context, instanceID, id string, config *twilio.Config) (*domain.ObjectDetails, error) {
|
||||
if id == "" {
|
||||
return nil, zerrors.ThrowInvalidArgument(nil, "SMS-e9jwf", "Errors.IDMissing")
|
||||
type ChangeTwilioConfig struct {
|
||||
Details *domain.ObjectDetails
|
||||
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 {
|
||||
return nil, err
|
||||
return err
|
||||
}
|
||||
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.NewChangedEvent(
|
||||
changedEvent, hasChanged, err := smsConfigWriteModel.NewTwilioChangedEvent(
|
||||
ctx,
|
||||
iamAgg,
|
||||
id,
|
||||
InstanceAggregateFromWriteModel(&smsConfigWriteModel.WriteModel),
|
||||
config.ID,
|
||||
config.Description,
|
||||
config.SID,
|
||||
config.SenderNumber)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
return err
|
||||
}
|
||||
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 {
|
||||
return nil, err
|
||||
return err
|
||||
}
|
||||
err = AppendAndReduce(smsConfigWriteModel, pushedEvents...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return writeModelToObjectDetails(&smsConfigWriteModel.WriteModel), nil
|
||||
config.Details = writeModelToObjectDetails(&smsConfigWriteModel.WriteModel)
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *Commands) ChangeSMSConfigTwilioToken(ctx context.Context, instanceID, id, token string) (*domain.ObjectDetails, error) {
|
||||
smsConfigWriteModel, err := c.getSMSConfig(ctx, instanceID, id)
|
||||
func (c *Commands) ChangeSMSConfigTwilioToken(ctx context.Context, resourceOwner, id, token string) (*domain.ObjectDetails, error) {
|
||||
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 {
|
||||
return nil, err
|
||||
}
|
||||
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)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
pushedEvents, err := c.eventstore.Push(ctx, instance.NewSMSConfigTokenChangedEvent(
|
||||
ctx,
|
||||
iamAgg,
|
||||
id,
|
||||
newtoken))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
err = AppendAndReduce(smsConfigWriteModel, pushedEvents...)
|
||||
err = c.pushAppendAndReduce(ctx,
|
||||
smsConfigWriteModel,
|
||||
instance.NewSMSConfigTokenChangedEvent(
|
||||
ctx,
|
||||
InstanceAggregateFromWriteModel(&smsConfigWriteModel.WriteModel),
|
||||
id,
|
||||
newtoken,
|
||||
),
|
||||
)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return writeModelToObjectDetails(&smsConfigWriteModel.WriteModel), nil
|
||||
}
|
||||
|
||||
func (c *Commands) ActivateSMSConfig(ctx context.Context, instanceID, id string) (*domain.ObjectDetails, error) {
|
||||
if id == "" {
|
||||
return nil, zerrors.ThrowInvalidArgument(nil, "SMS-dn93n", "Errors.IDMissing")
|
||||
type AddSMSHTTP struct {
|
||||
Details *domain.ObjectDetails
|
||||
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 {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
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 {
|
||||
return nil, zerrors.ThrowNotFound(nil, "COMMAND-sn9we", "Errors.SMSConfig.AlreadyActive")
|
||||
return nil, zerrors.ThrowPreconditionFailed(nil, "COMMAND-B25GFeIvRi", "Errors.SMSConfig.AlreadyActive")
|
||||
}
|
||||
iamAgg := InstanceAggregateFromWriteModel(&smsConfigWriteModel.WriteModel)
|
||||
pushedEvents, err := c.eventstore.Push(ctx, instance.NewSMSConfigTwilioActivatedEvent(
|
||||
ctx,
|
||||
iamAgg,
|
||||
id))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
err = AppendAndReduce(smsConfigWriteModel, pushedEvents...)
|
||||
err = c.pushAppendAndReduce(ctx, smsConfigWriteModel,
|
||||
instance.NewSMSConfigActivatedEvent(
|
||||
ctx,
|
||||
InstanceAggregateFromWriteModel(&smsConfigWriteModel.WriteModel),
|
||||
id,
|
||||
),
|
||||
)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return writeModelToObjectDetails(&smsConfigWriteModel.WriteModel), nil
|
||||
}
|
||||
|
||||
func (c *Commands) DeactivateSMSConfig(ctx context.Context, instanceID, id string) (*domain.ObjectDetails, error) {
|
||||
if id == "" {
|
||||
return nil, zerrors.ThrowInvalidArgument(nil, "SMS-frkwf", "Errors.IDMissing")
|
||||
func (c *Commands) DeactivateSMSConfig(ctx context.Context, resourceOwner, id string) (*domain.ObjectDetails, error) {
|
||||
if resourceOwner == "" {
|
||||
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 {
|
||||
return nil, err
|
||||
}
|
||||
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 {
|
||||
return nil, zerrors.ThrowNotFound(nil, "COMMAND-dm9e3", "Errors.SMSConfig.AlreadyDeactivated")
|
||||
return nil, zerrors.ThrowPreconditionFailed(nil, "COMMAND-OSZAEkYvk7", "Errors.SMSConfig.AlreadyDeactivated")
|
||||
}
|
||||
|
||||
iamAgg := InstanceAggregateFromWriteModel(&smsConfigWriteModel.WriteModel)
|
||||
pushedEvents, err := c.eventstore.Push(ctx, instance.NewSMSConfigDeactivatedEvent(
|
||||
ctx,
|
||||
iamAgg,
|
||||
id))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
err = AppendAndReduce(smsConfigWriteModel, pushedEvents...)
|
||||
err = c.pushAppendAndReduce(ctx,
|
||||
smsConfigWriteModel,
|
||||
instance.NewSMSConfigDeactivatedEvent(
|
||||
ctx,
|
||||
InstanceAggregateFromWriteModel(&smsConfigWriteModel.WriteModel),
|
||||
id,
|
||||
),
|
||||
)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return writeModelToObjectDetails(&smsConfigWriteModel.WriteModel), nil
|
||||
}
|
||||
|
||||
func (c *Commands) RemoveSMSConfig(ctx context.Context, instanceID, id string) (*domain.ObjectDetails, error) {
|
||||
if id == "" {
|
||||
return nil, zerrors.ThrowInvalidArgument(nil, "SMS-3j9fs", "Errors.IDMissing")
|
||||
func (c *Commands) RemoveSMSConfig(ctx context.Context, resourceOwner, id string) (*domain.ObjectDetails, error) {
|
||||
if resourceOwner == "" {
|
||||
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 {
|
||||
return nil, err
|
||||
}
|
||||
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)
|
||||
pushedEvents, err := c.eventstore.Push(ctx, instance.NewSMSConfigRemovedEvent(
|
||||
ctx,
|
||||
iamAgg,
|
||||
id))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
err = AppendAndReduce(smsConfigWriteModel, pushedEvents...)
|
||||
err = c.pushAppendAndReduce(ctx,
|
||||
smsConfigWriteModel,
|
||||
instance.NewSMSConfigRemovedEvent(
|
||||
ctx,
|
||||
InstanceAggregateFromWriteModel(&smsConfigWriteModel.WriteModel),
|
||||
id,
|
||||
),
|
||||
)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return writeModelToObjectDetails(&smsConfigWriteModel.WriteModel), nil
|
||||
}
|
||||
|
||||
func (c *Commands) getSMSConfig(ctx context.Context, instanceID, id string) (_ *IAMSMSConfigWriteModel, err error) {
|
||||
writeModel := NewIAMSMSConfigWriteModel(instanceID, id)
|
||||
err = c.eventstore.FilterToQueryReducer(ctx, writeModel)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return writeModel, nil
|
||||
}
|
||||
|
@ -12,9 +12,11 @@ import (
|
||||
type IAMSMSConfigWriteModel struct {
|
||||
eventstore.WriteModel
|
||||
|
||||
ID string
|
||||
Twilio *TwilioConfig
|
||||
State domain.SMSConfigState
|
||||
ID string
|
||||
Description string
|
||||
Twilio *TwilioConfig
|
||||
HTTP *HTTPConfig
|
||||
State domain.SMSConfigState
|
||||
}
|
||||
|
||||
type TwilioConfig struct {
|
||||
@ -23,6 +25,10 @@ type TwilioConfig struct {
|
||||
SenderNumber string
|
||||
}
|
||||
|
||||
type HTTPConfig struct {
|
||||
Endpoint string
|
||||
}
|
||||
|
||||
func NewIAMSMSConfigWriteModel(instanceID, id string) *IAMSMSConfigWriteModel {
|
||||
return &IAMSMSConfigWriteModel{
|
||||
WriteModel: eventstore.WriteModel{
|
||||
@ -46,11 +52,15 @@ func (wm *IAMSMSConfigWriteModel) Reduce() error {
|
||||
Token: e.Token,
|
||||
SenderNumber: e.SenderNumber,
|
||||
}
|
||||
wm.Description = e.Description
|
||||
wm.State = domain.SMSConfigStateInactive
|
||||
case *instance.SMSConfigTwilioChangedEvent:
|
||||
if wm.ID != e.ID {
|
||||
continue
|
||||
}
|
||||
if e.Description != nil {
|
||||
wm.Description = *e.Description
|
||||
}
|
||||
if e.SID != nil {
|
||||
wm.Twilio.SID = *e.SID
|
||||
}
|
||||
@ -62,6 +72,42 @@ func (wm *IAMSMSConfigWriteModel) Reduce() error {
|
||||
continue
|
||||
}
|
||||
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:
|
||||
if wm.ID != e.ID {
|
||||
continue
|
||||
@ -77,6 +123,7 @@ func (wm *IAMSMSConfigWriteModel) Reduce() error {
|
||||
continue
|
||||
}
|
||||
wm.Twilio = nil
|
||||
wm.HTTP = nil
|
||||
wm.State = domain.SMSConfigStateRemoved
|
||||
}
|
||||
}
|
||||
@ -92,21 +139,33 @@ func (wm *IAMSMSConfigWriteModel) Query() *eventstore.SearchQueryBuilder {
|
||||
instance.SMSConfigTwilioAddedEventType,
|
||||
instance.SMSConfigTwilioChangedEventType,
|
||||
instance.SMSConfigTwilioTokenChangedEventType,
|
||||
instance.SMSConfigHTTPAddedEventType,
|
||||
instance.SMSConfigHTTPChangedEventType,
|
||||
instance.SMSConfigTwilioActivatedEventType,
|
||||
instance.SMSConfigTwilioDeactivatedEventType,
|
||||
instance.SMSConfigTwilioRemovedEventType,
|
||||
instance.SMSConfigActivatedEventType,
|
||||
instance.SMSConfigDeactivatedEventType,
|
||||
instance.SMSConfigRemovedEventType).
|
||||
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)
|
||||
var err error
|
||||
|
||||
if wm.Twilio.SID != sid {
|
||||
changes = append(changes, instance.ChangeSMSConfigTwilioSID(sid))
|
||||
if wm.Twilio == nil {
|
||||
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 {
|
||||
@ -118,3 +177,28 @@ func (wm *IAMSMSConfigWriteModel) NewChangedEvent(ctx context.Context, aggregate
|
||||
}
|
||||
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 {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
|
@ -5,8 +5,8 @@ import (
|
||||
|
||||
"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/twilio"
|
||||
"github.com/zitadel/zitadel/internal/notification/channels/webhook"
|
||||
"github.com/zitadel/zitadel/internal/notification/handlers"
|
||||
"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
|
||||
}
|
||||
|
||||
func (c *channels) SMS(ctx context.Context) (*senders.Chain, *twilio.Config, error) {
|
||||
twilioCfg, err := c.q.GetTwilioConfig(ctx)
|
||||
func (c *channels) SMS(ctx context.Context) (*senders.Chain, *sms.Config, error) {
|
||||
smsCfg, err := c.q.GetActiveSMSConfig(ctx)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
chain, err := senders.SMSChannels(
|
||||
ctx,
|
||||
twilioCfg,
|
||||
smsCfg,
|
||||
c.q.GetFileSystemProvider,
|
||||
c.q.GetLogProvider,
|
||||
c.counters.success.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) {
|
||||
|
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)
|
||||
}
|
||||
|
||||
// SMSProviderConfig mocks base method.
|
||||
func (m *MockQueries) SMSProviderConfig(arg0 context.Context, arg1 ...query.SearchQuery) (*query.SMSConfig, error) {
|
||||
// SMSProviderConfigActive mocks base method.
|
||||
func (m *MockQueries) SMSProviderConfigActive(arg0 context.Context, arg1 string) (*query.SMSConfig, error) {
|
||||
m.ctrl.T.Helper()
|
||||
varargs := []any{arg0}
|
||||
for _, a := range arg1 {
|
||||
varargs = append(varargs, a)
|
||||
}
|
||||
ret := m.ctrl.Call(m, "SMSProviderConfig", varargs...)
|
||||
ret := m.ctrl.Call(m, "SMSProviderConfigActive", arg0, arg1)
|
||||
ret0, _ := ret[0].(*query.SMSConfig)
|
||||
ret1, _ := ret[1].(error)
|
||||
return ret0, ret1
|
||||
}
|
||||
|
||||
// SMSProviderConfig indicates an expected call of SMSProviderConfig.
|
||||
func (mr *MockQueriesMockRecorder) SMSProviderConfig(arg0 any, arg1 ...any) *gomock.Call {
|
||||
// SMSProviderConfigActive indicates an expected call of SMSProviderConfigActive.
|
||||
func (mr *MockQueriesMockRecorder) SMSProviderConfigActive(arg0, arg1 any) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
varargs := append([]any{arg0}, arg1...)
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SMSProviderConfig", reflect.TypeOf((*MockQueries)(nil).SMSProviderConfig), varargs...)
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SMSProviderConfigActive", reflect.TypeOf((*MockQueries)(nil).SMSProviderConfigActive), arg0, arg1)
|
||||
}
|
||||
|
||||
// SMTPConfigActive mocks base method.
|
||||
|
@ -21,7 +21,7 @@ type Queries interface {
|
||||
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)
|
||||
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)
|
||||
GetDefaultLanguage(ctx context.Context) language.Tag
|
||||
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)
|
||||
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)
|
||||
if err != nil {
|
||||
@ -373,7 +373,7 @@ func (u *userNotifier) reduceOTPSMS(
|
||||
if err != nil {
|
||||
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)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@ -709,7 +709,7 @@ func (u *userNotifier) reducePhoneCodeAdded(event eventstore.Event) (*handler.St
|
||||
if err != nil {
|
||||
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)
|
||||
if err != nil {
|
||||
return err
|
||||
|
@ -16,8 +16,8 @@ import (
|
||||
"github.com/zitadel/zitadel/internal/eventstore/repository"
|
||||
es_repo_mock "github.com/zitadel/zitadel/internal/eventstore/repository/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/twilio"
|
||||
"github.com/zitadel/zitadel/internal/notification/channels/webhook"
|
||||
"github.com/zitadel/zitadel/internal/notification/handlers/mock"
|
||||
"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
|
||||
}
|
||||
|
||||
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
|
||||
}
|
||||
|
||||
|
@ -3,36 +3,60 @@ package senders
|
||||
import (
|
||||
"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/fs"
|
||||
"github.com/zitadel/zitadel/internal/notification/channels/instrumenting"
|
||||
"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/webhook"
|
||||
)
|
||||
|
||||
const twilioSpanName = "twilio.NotificationChannel"
|
||||
|
||||
func SMSChannels(
|
||||
ctx context.Context,
|
||||
twilioConfig *twilio.Config,
|
||||
smsConfig *sms.Config,
|
||||
getFileSystemProvider func(ctx context.Context) (*fs.Config, error),
|
||||
getLogProvider func(ctx context.Context) (*log.Config, error),
|
||||
successMetricName,
|
||||
failureMetricName string,
|
||||
) (chain *Chain, err error) {
|
||||
channels := make([]channels.NotificationChannel, 0, 3)
|
||||
if twilioConfig != nil {
|
||||
if smsConfig.TwilioConfig != nil {
|
||||
channels = append(
|
||||
channels,
|
||||
instrumenting.Wrap(
|
||||
ctx,
|
||||
twilio.InitChannel(*twilioConfig),
|
||||
twilio.InitChannel(*smsConfig.TwilioConfig),
|
||||
twilioSpanName,
|
||||
successMetricName,
|
||||
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)...)
|
||||
return ChainChannels(channels...), nil
|
||||
}
|
||||
|
@ -15,23 +15,23 @@ const (
|
||||
)
|
||||
|
||||
type TemplateData struct {
|
||||
Title string
|
||||
PreHeader string
|
||||
Subject string
|
||||
Greeting string
|
||||
Text string
|
||||
URL string
|
||||
ButtonText string
|
||||
PrimaryColor string
|
||||
BackgroundColor string
|
||||
FontColor string
|
||||
LogoURL string
|
||||
FontURL string
|
||||
FontFaceFamily string
|
||||
FontFamily string
|
||||
Title string `json:"title,omitempty"`
|
||||
PreHeader string `json:"preHeader,omitempty"`
|
||||
Subject string `json:"subject,omitempty"`
|
||||
Greeting string `json:"greeting,omitempty"`
|
||||
Text string `json:"text,omitempty"`
|
||||
URL string `json:"url,omitempty"`
|
||||
ButtonText string `json:"buttonText,omitempty"`
|
||||
PrimaryColor string `json:"primaryColor,omitempty"`
|
||||
BackgroundColor string `json:"backgroundColor,omitempty"`
|
||||
FontColor string `json:"fontColor,omitempty"`
|
||||
LogoURL string `json:"logoUrl,omitempty"`
|
||||
FontURL string `json:"fontUrl,omitempty"`
|
||||
FontFaceFamily string `json:"fontFaceFamily,omitempty"`
|
||||
FontFamily string `json:"fontFamily,omitempty"`
|
||||
|
||||
IncludeFooter bool
|
||||
FooterText string
|
||||
IncludeFooter bool `json:"includeFooter,omitempty"`
|
||||
FooterText string `json:"footerText,omitempty"`
|
||||
}
|
||||
|
||||
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/eventstore"
|
||||
"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/twilio"
|
||||
"github.com/zitadel/zitadel/internal/notification/channels/webhook"
|
||||
"github.com/zitadel/zitadel/internal/notification/senders"
|
||||
"github.com/zitadel/zitadel/internal/notification/templates"
|
||||
@ -24,7 +24,7 @@ type Notify func(
|
||||
|
||||
type ChannelChains interface {
|
||||
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)
|
||||
}
|
||||
|
||||
@ -79,7 +79,7 @@ func sanitizeArgsForHTML(args map[string]any) {
|
||||
}
|
||||
}
|
||||
|
||||
func SendSMSTwilio(
|
||||
func SendSMS(
|
||||
ctx context.Context,
|
||||
channels ChannelChains,
|
||||
translator *i18n.Translator,
|
||||
@ -99,7 +99,8 @@ func SendSMSTwilio(
|
||||
ctx,
|
||||
channels,
|
||||
user,
|
||||
data.Text,
|
||||
data,
|
||||
args,
|
||||
allowUnverifiedNotificationChannel,
|
||||
triggeringEvent,
|
||||
)
|
||||
|
@ -2,40 +2,78 @@ package types
|
||||
|
||||
import (
|
||||
"context"
|
||||
"strings"
|
||||
|
||||
"github.com/zitadel/logging"
|
||||
|
||||
"github.com/zitadel/zitadel/internal/eventstore"
|
||||
"github.com/zitadel/zitadel/internal/notification/messages"
|
||||
"github.com/zitadel/zitadel/internal/notification/templates"
|
||||
"github.com/zitadel/zitadel/internal/query"
|
||||
"github.com/zitadel/zitadel/internal/zerrors"
|
||||
)
|
||||
|
||||
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(
|
||||
ctx context.Context,
|
||||
channels ChannelChains,
|
||||
user *query.NotifyUser,
|
||||
content string,
|
||||
data templates.TemplateData,
|
||||
args map[string]interface{},
|
||||
lastPhone bool,
|
||||
triggeringEvent eventstore.Event,
|
||||
) error {
|
||||
number := ""
|
||||
smsChannels, twilioConfig, err := channels.SMS(ctx)
|
||||
smsChannels, config, err := channels.SMS(ctx)
|
||||
logging.OnError(err).Error("could not create sms channel")
|
||||
if smsChannels == nil || smsChannels.Len() == 0 {
|
||||
return zerrors.ThrowPreconditionFailed(nil, "PHONE-w8nfow", "Errors.Notification.Channels.NotPresent")
|
||||
}
|
||||
if err == nil {
|
||||
number = twilioConfig.SenderNumber
|
||||
}
|
||||
message := &messages.SMS{
|
||||
SenderPhoneNumber: number,
|
||||
RecipientPhoneNumber: user.VerifiedPhone,
|
||||
Content: content,
|
||||
TriggeringEvent: triggeringEvent,
|
||||
}
|
||||
recipient := user.VerifiedPhone
|
||||
if lastPhone {
|
||||
message.RecipientPhoneNumber = user.LastPhone
|
||||
recipient = user.LastPhone
|
||||
}
|
||||
return smsChannels.HandleMessage(message)
|
||||
if config.TwilioConfig != nil {
|
||||
number := ""
|
||||
if err == nil {
|
||||
number = config.TwilioConfig.SenderNumber
|
||||
}
|
||||
message := &messages.SMS{
|
||||
SenderPhoneNumber: number,
|
||||
RecipientPhoneNumber: recipient,
|
||||
Content: data.Text,
|
||||
TriggeringEvent: triggeringEvent,
|
||||
}
|
||||
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"
|
||||
"github.com/zitadel/zitadel/internal/eventstore/handler/v2"
|
||||
"github.com/zitadel/zitadel/internal/repository/instance"
|
||||
"github.com/zitadel/zitadel/internal/zerrors"
|
||||
)
|
||||
|
||||
const (
|
||||
SMSConfigProjectionTable = "projections.sms_configs2"
|
||||
SMSConfigProjectionTable = "projections.sms_configs3"
|
||||
SMSTwilioTable = SMSConfigProjectionTable + "_" + smsTwilioTableSuffix
|
||||
SMSHTTPTable = SMSConfigProjectionTable + "_" + smsHTTPTableSuffix
|
||||
|
||||
SMSColumnID = "id"
|
||||
SMSColumnAggregateID = "aggregate_id"
|
||||
@ -23,13 +23,19 @@ const (
|
||||
SMSColumnState = "state"
|
||||
SMSColumnResourceOwner = "resource_owner"
|
||||
SMSColumnInstanceID = "instance_id"
|
||||
SMSColumnDescription = "description"
|
||||
|
||||
smsTwilioTableSuffix = "twilio"
|
||||
SMSTwilioConfigColumnSMSID = "sms_id"
|
||||
SMSTwilioColumnInstanceID = "instance_id"
|
||||
SMSTwilioConfigColumnSID = "sid"
|
||||
SMSTwilioConfigColumnSenderNumber = "sender_number"
|
||||
SMSTwilioConfigColumnToken = "token"
|
||||
smsTwilioTableSuffix = "twilio"
|
||||
SMSTwilioColumnSMSID = "sms_id"
|
||||
SMSTwilioColumnInstanceID = "instance_id"
|
||||
SMSTwilioColumnSID = "sid"
|
||||
SMSTwilioColumnSenderNumber = "sender_number"
|
||||
SMSTwilioColumnToken = "token"
|
||||
|
||||
smsHTTPTableSuffix = "http"
|
||||
SMSHTTPColumnSMSID = "sms_id"
|
||||
SMSHTTPColumnInstanceID = "instance_id"
|
||||
SMSHTTPColumnEndpoint = "endpoint"
|
||||
)
|
||||
|
||||
type smsConfigProjection struct{}
|
||||
@ -53,20 +59,30 @@ func (*smsConfigProjection) Init() *old_handler.Check {
|
||||
handler.NewColumn(SMSColumnState, handler.ColumnTypeEnum),
|
||||
handler.NewColumn(SMSColumnResourceOwner, handler.ColumnTypeText),
|
||||
handler.NewColumn(SMSColumnInstanceID, handler.ColumnTypeText),
|
||||
handler.NewColumn(SMSColumnDescription, handler.ColumnTypeText),
|
||||
},
|
||||
handler.NewPrimaryKey(SMSColumnInstanceID, SMSColumnID),
|
||||
),
|
||||
handler.NewSuffixedTable([]*handler.InitColumn{
|
||||
handler.NewColumn(SMSTwilioConfigColumnSMSID, handler.ColumnTypeText),
|
||||
handler.NewColumn(SMSTwilioColumnSMSID, handler.ColumnTypeText),
|
||||
handler.NewColumn(SMSTwilioColumnInstanceID, handler.ColumnTypeText),
|
||||
handler.NewColumn(SMSTwilioConfigColumnSID, handler.ColumnTypeText),
|
||||
handler.NewColumn(SMSTwilioConfigColumnSenderNumber, handler.ColumnTypeText),
|
||||
handler.NewColumn(SMSTwilioConfigColumnToken, handler.ColumnTypeJSONB),
|
||||
handler.NewColumn(SMSTwilioColumnSID, handler.ColumnTypeText),
|
||||
handler.NewColumn(SMSTwilioColumnSenderNumber, handler.ColumnTypeText),
|
||||
handler.NewColumn(SMSTwilioColumnToken, handler.ColumnTypeJSONB),
|
||||
},
|
||||
handler.NewPrimaryKey(SMSTwilioColumnInstanceID, SMSTwilioConfigColumnSMSID),
|
||||
handler.NewPrimaryKey(SMSTwilioColumnInstanceID, SMSTwilioColumnSMSID),
|
||||
smsTwilioTableSuffix,
|
||||
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,
|
||||
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,
|
||||
Reduce: p.reduceSMSConfigActivated,
|
||||
@ -109,9 +145,9 @@ func (p *smsConfigProjection) Reducers() []handler.AggregateReducer {
|
||||
}
|
||||
|
||||
func (p *smsConfigProjection) reduceSMSConfigTwilioAdded(event eventstore.Event) (*handler.Statement, error) {
|
||||
e, ok := event.(*instance.SMSConfigTwilioAddedEvent)
|
||||
if !ok {
|
||||
return nil, zerrors.ThrowInvalidArgumentf(nil, "HANDL-s8efs", "reduce.wrong.event.type %s", instance.SMSConfigTwilioAddedEventType)
|
||||
e, err := assertEvent[*instance.SMSConfigTwilioAddedEvent](event)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return handler.NewMultiStatement(
|
||||
@ -126,15 +162,16 @@ func (p *smsConfigProjection) reduceSMSConfigTwilioAdded(event eventstore.Event)
|
||||
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(SMSTwilioConfigColumnSMSID, e.ID),
|
||||
handler.NewCol(SMSTwilioColumnSMSID, e.ID),
|
||||
handler.NewCol(SMSTwilioColumnInstanceID, e.Aggregate().InstanceID),
|
||||
handler.NewCol(SMSTwilioConfigColumnSID, e.SID),
|
||||
handler.NewCol(SMSTwilioConfigColumnToken, e.Token),
|
||||
handler.NewCol(SMSTwilioConfigColumnSenderNumber, e.SenderNumber),
|
||||
handler.NewCol(SMSTwilioColumnSID, e.SID),
|
||||
handler.NewCol(SMSTwilioColumnToken, e.Token),
|
||||
handler.NewCol(SMSTwilioColumnSenderNumber, e.SenderNumber),
|
||||
},
|
||||
handler.WithTableSuffix(smsTwilioTableSuffix),
|
||||
),
|
||||
@ -142,57 +179,64 @@ func (p *smsConfigProjection) reduceSMSConfigTwilioAdded(event eventstore.Event)
|
||||
}
|
||||
|
||||
func (p *smsConfigProjection) reduceSMSConfigTwilioChanged(event eventstore.Event) (*handler.Statement, error) {
|
||||
e, ok := event.(*instance.SMSConfigTwilioChangedEvent)
|
||||
if !ok {
|
||||
return nil, zerrors.ThrowInvalidArgumentf(nil, "HANDL-fi99F", "reduce.wrong.event.type %s", instance.SMSConfigTwilioChangedEventType)
|
||||
}
|
||||
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))
|
||||
e, err := assertEvent[*instance.SMSConfigTwilioChangedEvent](event)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return handler.NewMultiStatement(
|
||||
e,
|
||||
handler.AddUpdateStatement(
|
||||
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(SMSTwilioConfigColumnSMSID, e.ID),
|
||||
handler.NewCond(SMSTwilioColumnInstanceID, e.Aggregate().InstanceID),
|
||||
},
|
||||
handler.WithTableSuffix(smsTwilioTableSuffix),
|
||||
),
|
||||
handler.AddUpdateStatement(
|
||||
[]handler.Column{
|
||||
handler.NewCol(SMSColumnChangeDate, e.CreationDate()),
|
||||
handler.NewCol(SMSColumnSequence, e.Sequence()),
|
||||
},
|
||||
[]handler.Condition{
|
||||
handler.NewCond(SMSColumnID, e.ID),
|
||||
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) {
|
||||
e, ok := event.(*instance.SMSConfigTwilioTokenChangedEvent)
|
||||
if !ok {
|
||||
return nil, zerrors.ThrowInvalidArgumentf(nil, "HANDL-fi99F", "reduce.wrong.event.type %s", instance.SMSConfigTwilioTokenChangedEventType)
|
||||
}
|
||||
columns := make([]handler.Column, 0)
|
||||
if e.Token != nil {
|
||||
columns = append(columns, handler.NewCol(SMSTwilioConfigColumnToken, e.Token))
|
||||
e, err := assertEvent[*instance.SMSConfigTwilioTokenChangedEvent](event)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return handler.NewMultiStatement(
|
||||
e,
|
||||
handler.AddUpdateStatement(
|
||||
columns,
|
||||
[]handler.Column{
|
||||
handler.NewCol(SMSTwilioColumnToken, e.Token),
|
||||
},
|
||||
[]handler.Condition{
|
||||
handler.NewCond(SMSTwilioConfigColumnSMSID, e.ID),
|
||||
handler.NewCond(SMSTwilioColumnSMSID, e.ID),
|
||||
handler.NewCond(SMSTwilioColumnInstanceID, e.Aggregate().InstanceID),
|
||||
},
|
||||
handler.WithTableSuffix(smsTwilioTableSuffix),
|
||||
@ -210,15 +254,122 @@ func (p *smsConfigProjection) reduceSMSConfigTwilioTokenChanged(event eventstore
|
||||
), nil
|
||||
}
|
||||
|
||||
func (p *smsConfigProjection) reduceSMSConfigActivated(event eventstore.Event) (*handler.Statement, error) {
|
||||
e, ok := event.(*instance.SMSConfigActivatedEvent)
|
||||
if !ok {
|
||||
return nil, zerrors.ThrowInvalidArgumentf(nil, "HANDL-fj9Ef", "reduce.wrong.event.type %s", instance.SMSConfigActivatedEventType)
|
||||
func (p *smsConfigProjection) reduceSMSConfigHTTPAdded(event eventstore.Event) (*handler.Statement, error) {
|
||||
e, err := assertEvent[*instance.SMSConfigHTTPAddedEvent](event)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return handler.NewMultiStatement(
|
||||
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.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
|
||||
}
|
||||
|
||||
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.SMSConfigStateActive),
|
||||
handler.NewCol(SMSColumnState, domain.SMSConfigStateInactive),
|
||||
handler.NewCol(SMSColumnChangeDate, e.CreationDate()),
|
||||
handler.NewCol(SMSColumnSequence, e.Sequence()),
|
||||
},
|
||||
@ -229,11 +380,61 @@ func (p *smsConfigProjection) reduceSMSConfigActivated(event eventstore.Event) (
|
||||
), nil
|
||||
}
|
||||
|
||||
func (p *smsConfigProjection) reduceSMSConfigDeactivated(event eventstore.Event) (*handler.Statement, error) {
|
||||
e, ok := event.(*instance.SMSConfigDeactivatedEvent)
|
||||
if !ok {
|
||||
return nil, zerrors.ThrowInvalidArgumentf(nil, "HANDL-dj9Js", "reduce.wrong.event.type %s", instance.SMSConfigDeactivatedEventType)
|
||||
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
|
||||
}
|
||||
|
||||
func (p *smsConfigProjection) reduceSMSConfigDeactivated(event eventstore.Event) (*handler.Statement, error) {
|
||||
e, err := assertEvent[*instance.SMSConfigDeactivatedEvent](event)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return handler.NewUpdateStatement(
|
||||
e,
|
||||
[]handler.Column{
|
||||
@ -249,10 +450,11 @@ func (p *smsConfigProjection) reduceSMSConfigDeactivated(event eventstore.Event)
|
||||
}
|
||||
|
||||
func (p *smsConfigProjection) reduceSMSConfigRemoved(event eventstore.Event) (*handler.Statement, error) {
|
||||
e, ok := event.(*instance.SMSConfigRemovedEvent)
|
||||
if !ok {
|
||||
return nil, zerrors.ThrowInvalidArgumentf(nil, "HANDL-s9JJf", "reduce.wrong.event.type %s", instance.SMSConfigRemovedEventType)
|
||||
e, err := assertEvent[*instance.SMSConfigRemovedEvent](event)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return handler.NewDeleteStatement(
|
||||
e,
|
||||
[]handler.Condition{
|
||||
|
@ -37,9 +37,10 @@ func TestSMSProjection_reduces(t *testing.T) {
|
||||
"keyId": "key-id",
|
||||
"crypted": "Y3J5cHRlZA=="
|
||||
},
|
||||
"senderNumber": "sender-number"
|
||||
"senderNumber": "sender-number",
|
||||
"description": "description"
|
||||
}`),
|
||||
), instance.SMSConfigTwilioAddedEventMapper),
|
||||
), eventstore.GenericEventMapper[instance.SMSConfigTwilioAddedEvent]),
|
||||
},
|
||||
reduce: (&smsConfigProjection{}).reduceSMSConfigTwilioAdded,
|
||||
want: wantReduce{
|
||||
@ -48,7 +49,7 @@ func TestSMSProjection_reduces(t *testing.T) {
|
||||
executer: &testExecuter{
|
||||
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{}{
|
||||
"id",
|
||||
"agg-id",
|
||||
@ -58,10 +59,11 @@ func TestSMSProjection_reduces(t *testing.T) {
|
||||
"instance-id",
|
||||
domain.SMSConfigStateInactive,
|
||||
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{}{
|
||||
"id",
|
||||
"instance-id",
|
||||
@ -89,9 +91,10 @@ func TestSMSProjection_reduces(t *testing.T) {
|
||||
[]byte(`{
|
||||
"id": "id",
|
||||
"sid": "sid",
|
||||
"senderNumber": "sender-number"
|
||||
"senderNumber": "sender-number",
|
||||
"description": "description"
|
||||
}`),
|
||||
), instance.SMSConfigTwilioChangedEventMapper),
|
||||
), eventstore.GenericEventMapper[instance.SMSConfigTwilioChangedEvent]),
|
||||
},
|
||||
reduce: (&smsConfigProjection{}).reduceSMSConfigTwilioChanged,
|
||||
want: wantReduce{
|
||||
@ -100,7 +103,17 @@ func TestSMSProjection_reduces(t *testing.T) {
|
||||
executer: &testExecuter{
|
||||
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{}{
|
||||
"sid",
|
||||
"sender-number",
|
||||
@ -108,11 +121,75 @@ func TestSMSProjection_reduces(t *testing.T) {
|
||||
"instance-id",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
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_configs2 SET (change_date, sequence) = ($1, $2) WHERE (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",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
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",
|
||||
"instance-id",
|
||||
},
|
||||
@ -137,7 +214,7 @@ func TestSMSProjection_reduces(t *testing.T) {
|
||||
"crypted": "Y3J5cHRlZA=="
|
||||
}
|
||||
}`),
|
||||
), instance.SMSConfigTwilioTokenChangedEventMapper),
|
||||
), eventstore.GenericEventMapper[instance.SMSConfigTwilioTokenChangedEvent]),
|
||||
},
|
||||
reduce: (&smsConfigProjection{}).reduceSMSConfigTwilioTokenChanged,
|
||||
want: wantReduce{
|
||||
@ -146,7 +223,7 @@ func TestSMSProjection_reduces(t *testing.T) {
|
||||
executer: &testExecuter{
|
||||
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{}{
|
||||
&crypto.CryptoValue{
|
||||
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{}{
|
||||
anyArg{},
|
||||
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",
|
||||
args: args{
|
||||
@ -181,7 +522,7 @@ func TestSMSProjection_reduces(t *testing.T) {
|
||||
[]byte(`{
|
||||
"id": "id"
|
||||
}`),
|
||||
), instance.SMSConfigActivatedEventMapper),
|
||||
), eventstore.GenericEventMapper[instance.SMSConfigActivatedEvent]),
|
||||
},
|
||||
reduce: (&smsConfigProjection{}).reduceSMSConfigActivated,
|
||||
want: wantReduce{
|
||||
@ -190,7 +531,18 @@ func TestSMSProjection_reduces(t *testing.T) {
|
||||
executer: &testExecuter{
|
||||
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{}{
|
||||
domain.SMSConfigStateActive,
|
||||
anyArg{},
|
||||
@ -213,7 +565,7 @@ func TestSMSProjection_reduces(t *testing.T) {
|
||||
[]byte(`{
|
||||
"id": "id"
|
||||
}`),
|
||||
), instance.SMSConfigDeactivatedEventMapper),
|
||||
), eventstore.GenericEventMapper[instance.SMSConfigDeactivatedEvent]),
|
||||
},
|
||||
reduce: (&smsConfigProjection{}).reduceSMSConfigDeactivated,
|
||||
want: wantReduce{
|
||||
@ -222,7 +574,7 @@ func TestSMSProjection_reduces(t *testing.T) {
|
||||
executer: &testExecuter{
|
||||
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{}{
|
||||
domain.SMSConfigStateInactive,
|
||||
anyArg{},
|
||||
@ -245,7 +597,7 @@ func TestSMSProjection_reduces(t *testing.T) {
|
||||
[]byte(`{
|
||||
"id": "id"
|
||||
}`),
|
||||
), instance.SMSConfigRemovedEventMapper),
|
||||
), eventstore.GenericEventMapper[instance.SMSConfigRemovedEvent]),
|
||||
},
|
||||
reduce: (&smsConfigProjection{}).reduceSMSConfigRemoved,
|
||||
want: wantReduce{
|
||||
@ -254,7 +606,7 @@ func TestSMSProjection_reduces(t *testing.T) {
|
||||
executer: &testExecuter{
|
||||
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{}{
|
||||
"id",
|
||||
"instance-id",
|
||||
@ -281,7 +633,7 @@ func TestSMSProjection_reduces(t *testing.T) {
|
||||
executer: &testExecuter{
|
||||
executions: []execution{
|
||||
{
|
||||
expectedStmt: "DELETE FROM projections.sms_configs2 WHERE (instance_id = $1)",
|
||||
expectedStmt: "DELETE FROM projections.sms_configs3 WHERE (instance_id = $1)",
|
||||
expectedArgs: []interface{}{
|
||||
"agg-id",
|
||||
},
|
||||
|
@ -30,8 +30,10 @@ type SMSConfig struct {
|
||||
ResourceOwner string
|
||||
State domain.SMSConfigState
|
||||
Sequence uint64
|
||||
Description string
|
||||
|
||||
TwilioConfig *Twilio
|
||||
HTTPConfig *HTTP
|
||||
}
|
||||
|
||||
type Twilio struct {
|
||||
@ -40,6 +42,10 @@ type Twilio struct {
|
||||
SenderNumber string
|
||||
}
|
||||
|
||||
type HTTP struct {
|
||||
Endpoint string
|
||||
}
|
||||
|
||||
type SMSConfigsSearchQueries struct {
|
||||
SearchRequest
|
||||
Queries []SearchQuery
|
||||
@ -58,60 +64,79 @@ var (
|
||||
name: projection.SMSConfigProjectionTable,
|
||||
instanceIDCol: projection.SMSColumnInstanceID,
|
||||
}
|
||||
SMSConfigColumnID = Column{
|
||||
SMSColumnID = Column{
|
||||
name: projection.SMSColumnID,
|
||||
table: smsConfigsTable,
|
||||
}
|
||||
SMSConfigColumnAggregateID = Column{
|
||||
SMSColumnAggregateID = Column{
|
||||
name: projection.SMSColumnAggregateID,
|
||||
table: smsConfigsTable,
|
||||
}
|
||||
SMSConfigColumnCreationDate = Column{
|
||||
SMSColumnCreationDate = Column{
|
||||
name: projection.SMSColumnCreationDate,
|
||||
table: smsConfigsTable,
|
||||
}
|
||||
SMSConfigColumnChangeDate = Column{
|
||||
SMSColumnChangeDate = Column{
|
||||
name: projection.SMSColumnChangeDate,
|
||||
table: smsConfigsTable,
|
||||
}
|
||||
SMSConfigColumnResourceOwner = Column{
|
||||
SMSColumnResourceOwner = Column{
|
||||
name: projection.SMSColumnResourceOwner,
|
||||
table: smsConfigsTable,
|
||||
}
|
||||
SMSConfigColumnInstanceID = Column{
|
||||
SMSColumnInstanceID = Column{
|
||||
name: projection.SMSColumnInstanceID,
|
||||
table: smsConfigsTable,
|
||||
}
|
||||
SMSConfigColumnState = Column{
|
||||
SMSColumnState = Column{
|
||||
name: projection.SMSColumnState,
|
||||
table: smsConfigsTable,
|
||||
}
|
||||
SMSConfigColumnSequence = Column{
|
||||
SMSColumnSequence = Column{
|
||||
name: projection.SMSColumnSequence,
|
||||
table: smsConfigsTable,
|
||||
}
|
||||
SMSColumnDescription = Column{
|
||||
name: projection.SMSColumnDescription,
|
||||
table: smsConfigsTable,
|
||||
}
|
||||
)
|
||||
|
||||
var (
|
||||
smsTwilioConfigsTable = table{
|
||||
smsTwilioTable = table{
|
||||
name: projection.SMSTwilioTable,
|
||||
instanceIDCol: projection.SMSTwilioColumnInstanceID,
|
||||
}
|
||||
SMSTwilioConfigColumnSMSID = Column{
|
||||
name: projection.SMSTwilioConfigColumnSMSID,
|
||||
table: smsTwilioConfigsTable,
|
||||
SMSTwilioColumnSMSID = Column{
|
||||
name: projection.SMSTwilioColumnSMSID,
|
||||
table: smsTwilioTable,
|
||||
}
|
||||
SMSTwilioConfigColumnSID = Column{
|
||||
name: projection.SMSTwilioConfigColumnSID,
|
||||
table: smsTwilioConfigsTable,
|
||||
SMSTwilioColumnSID = Column{
|
||||
name: projection.SMSTwilioColumnSID,
|
||||
table: smsTwilioTable,
|
||||
}
|
||||
SMSTwilioConfigColumnToken = Column{
|
||||
name: projection.SMSTwilioConfigColumnToken,
|
||||
table: smsTwilioConfigsTable,
|
||||
SMSTwilioColumnToken = Column{
|
||||
name: projection.SMSTwilioColumnToken,
|
||||
table: smsTwilioTable,
|
||||
}
|
||||
SMSTwilioConfigColumnSenderNumber = Column{
|
||||
name: projection.SMSTwilioConfigColumnSenderNumber,
|
||||
table: smsTwilioConfigsTable,
|
||||
SMSTwilioColumnSenderNumber = Column{
|
||||
name: projection.SMSTwilioColumnSenderNumber,
|
||||
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)
|
||||
stmt, args, err := query.Where(
|
||||
sq.Eq{
|
||||
SMSConfigColumnID.identifier(): id,
|
||||
SMSConfigColumnInstanceID.identifier(): authz.GetInstance(ctx).InstanceID(),
|
||||
SMSColumnID.identifier(): id,
|
||||
SMSColumnInstanceID.identifier(): authz.GetInstance(ctx).InstanceID(),
|
||||
},
|
||||
).ToSql()
|
||||
if err != nil {
|
||||
@ -137,17 +162,15 @@ func (q *Queries) SMSProviderConfigByID(ctx context.Context, id string) (config
|
||||
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)
|
||||
defer func() { span.EndWithError(err) }()
|
||||
|
||||
query, scan := prepareSMSConfigQuery(ctx, q.client)
|
||||
for _, searchQuery := range queries {
|
||||
query = searchQuery.toQuery(query)
|
||||
}
|
||||
stmt, args, err := query.Where(
|
||||
sq.Eq{
|
||||
SMSConfigColumnInstanceID.identifier(): authz.GetInstance(ctx).InstanceID(),
|
||||
SMSColumnInstanceID.identifier(): instanceID,
|
||||
SMSColumnState.identifier(): domain.SMSConfigStateActive,
|
||||
},
|
||||
).ToSql()
|
||||
if err != nil {
|
||||
@ -168,7 +191,7 @@ func (q *Queries) SearchSMSConfigs(ctx context.Context, queries *SMSConfigsSearc
|
||||
query, scan := prepareSMSConfigsQuery(ctx, q.client)
|
||||
stmt, args, err := queries.toQuery(query).
|
||||
Where(sq.Eq{
|
||||
SMSConfigColumnInstanceID.identifier(): authz.GetInstance(ctx).InstanceID(),
|
||||
SMSColumnInstanceID.identifier(): authz.GetInstance(ctx).InstanceID(),
|
||||
}).ToSql()
|
||||
if err != nil {
|
||||
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) {
|
||||
return NewNumberQuery(SMSConfigColumnState, state, NumberEquals)
|
||||
return NewNumberQuery(SMSColumnState, state, NumberEquals)
|
||||
}
|
||||
|
||||
func prepareSMSConfigQuery(ctx context.Context, db prepareDatabase) (sq.SelectBuilder, func(*sql.Row) (*SMSConfig, error)) {
|
||||
return sq.Select(
|
||||
SMSConfigColumnID.identifier(),
|
||||
SMSConfigColumnAggregateID.identifier(),
|
||||
SMSConfigColumnCreationDate.identifier(),
|
||||
SMSConfigColumnChangeDate.identifier(),
|
||||
SMSConfigColumnResourceOwner.identifier(),
|
||||
SMSConfigColumnState.identifier(),
|
||||
SMSConfigColumnSequence.identifier(),
|
||||
SMSColumnID.identifier(),
|
||||
SMSColumnAggregateID.identifier(),
|
||||
SMSColumnCreationDate.identifier(),
|
||||
SMSColumnChangeDate.identifier(),
|
||||
SMSColumnResourceOwner.identifier(),
|
||||
SMSColumnState.identifier(),
|
||||
SMSColumnSequence.identifier(),
|
||||
SMSColumnDescription.identifier(),
|
||||
|
||||
SMSTwilioConfigColumnSMSID.identifier(),
|
||||
SMSTwilioConfigColumnSID.identifier(),
|
||||
SMSTwilioConfigColumnToken.identifier(),
|
||||
SMSTwilioConfigColumnSenderNumber.identifier(),
|
||||
SMSTwilioColumnSMSID.identifier(),
|
||||
SMSTwilioColumnSID.identifier(),
|
||||
SMSTwilioColumnToken.identifier(),
|
||||
SMSTwilioColumnSenderNumber.identifier(),
|
||||
|
||||
SMSHTTPColumnSMSID.identifier(),
|
||||
SMSHTTPColumnEndpoint.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) {
|
||||
config := new(SMSConfig)
|
||||
|
||||
var (
|
||||
twilioConfig = sqlTwilioConfig{}
|
||||
httpConfig = sqlHTTPConfig{}
|
||||
)
|
||||
|
||||
err := row.Scan(
|
||||
@ -220,11 +249,15 @@ func prepareSMSConfigQuery(ctx context.Context, db prepareDatabase) (sq.SelectBu
|
||||
&config.ResourceOwner,
|
||||
&config.State,
|
||||
&config.Sequence,
|
||||
&config.Description,
|
||||
|
||||
&twilioConfig.smsID,
|
||||
&twilioConfig.sid,
|
||||
&twilioConfig.token,
|
||||
&twilioConfig.senderNumber,
|
||||
|
||||
&httpConfig.smsID,
|
||||
&httpConfig.endpoint,
|
||||
)
|
||||
|
||||
if err != nil {
|
||||
@ -235,6 +268,7 @@ func prepareSMSConfigQuery(ctx context.Context, db prepareDatabase) (sq.SelectBu
|
||||
}
|
||||
|
||||
twilioConfig.set(config)
|
||||
httpConfig.set(config)
|
||||
|
||||
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)) {
|
||||
return sq.Select(
|
||||
SMSConfigColumnID.identifier(),
|
||||
SMSConfigColumnAggregateID.identifier(),
|
||||
SMSConfigColumnCreationDate.identifier(),
|
||||
SMSConfigColumnChangeDate.identifier(),
|
||||
SMSConfigColumnResourceOwner.identifier(),
|
||||
SMSConfigColumnState.identifier(),
|
||||
SMSConfigColumnSequence.identifier(),
|
||||
SMSColumnID.identifier(),
|
||||
SMSColumnAggregateID.identifier(),
|
||||
SMSColumnCreationDate.identifier(),
|
||||
SMSColumnChangeDate.identifier(),
|
||||
SMSColumnResourceOwner.identifier(),
|
||||
SMSColumnState.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(),
|
||||
).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) {
|
||||
configs := &SMSConfigs{Configs: []*SMSConfig{}}
|
||||
|
||||
@ -264,6 +304,7 @@ func prepareSMSConfigsQuery(ctx context.Context, db prepareDatabase) (sq.SelectB
|
||||
config := new(SMSConfig)
|
||||
var (
|
||||
twilioConfig = sqlTwilioConfig{}
|
||||
httpConfig = sqlHTTPConfig{}
|
||||
)
|
||||
|
||||
err := row.Scan(
|
||||
@ -274,11 +315,16 @@ func prepareSMSConfigsQuery(ctx context.Context, db prepareDatabase) (sq.SelectB
|
||||
&config.ResourceOwner,
|
||||
&config.State,
|
||||
&config.Sequence,
|
||||
&config.Description,
|
||||
|
||||
&twilioConfig.smsID,
|
||||
&twilioConfig.sid,
|
||||
&twilioConfig.token,
|
||||
&twilioConfig.senderNumber,
|
||||
|
||||
&httpConfig.smsID,
|
||||
&httpConfig.endpoint,
|
||||
|
||||
&configs.Count,
|
||||
)
|
||||
|
||||
@ -287,6 +333,7 @@ func prepareSMSConfigsQuery(ctx context.Context, db prepareDatabase) (sq.SelectB
|
||||
}
|
||||
|
||||
twilioConfig.set(config)
|
||||
httpConfig.set(config)
|
||||
|
||||
configs.Configs = append(configs.Configs, config)
|
||||
}
|
||||
@ -312,3 +359,17 @@ func (c sqlTwilioConfig) set(smsConfig *SMSConfig) {
|
||||
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 (
|
||||
expectedSMSConfigQuery = regexp.QuoteMeta(`SELECT projections.sms_configs2.id,` +
|
||||
` projections.sms_configs2.aggregate_id,` +
|
||||
` projections.sms_configs2.creation_date,` +
|
||||
` projections.sms_configs2.change_date,` +
|
||||
` projections.sms_configs2.resource_owner,` +
|
||||
` projections.sms_configs2.state,` +
|
||||
` projections.sms_configs2.sequence,` +
|
||||
expectedSMSConfigQuery = regexp.QuoteMeta(`SELECT projections.sms_configs3.id,` +
|
||||
` projections.sms_configs3.aggregate_id,` +
|
||||
` projections.sms_configs3.creation_date,` +
|
||||
` projections.sms_configs3.change_date,` +
|
||||
` projections.sms_configs3.resource_owner,` +
|
||||
` projections.sms_configs3.state,` +
|
||||
` projections.sms_configs3.sequence,` +
|
||||
` projections.sms_configs3.description,` +
|
||||
|
||||
// twilio config
|
||||
` projections.sms_configs2_twilio.sms_id,` +
|
||||
` projections.sms_configs2_twilio.sid,` +
|
||||
` projections.sms_configs2_twilio.token,` +
|
||||
` projections.sms_configs2_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` +
|
||||
` projections.sms_configs3_twilio.sms_id,` +
|
||||
` projections.sms_configs3_twilio.sid,` +
|
||||
` projections.sms_configs3_twilio.token,` +
|
||||
` projections.sms_configs3_twilio.sender_number,` +
|
||||
|
||||
// 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'`)
|
||||
expectedSMSConfigsQuery = regexp.QuoteMeta(`SELECT projections.sms_configs2.id,` +
|
||||
` projections.sms_configs2.aggregate_id,` +
|
||||
` projections.sms_configs2.creation_date,` +
|
||||
` projections.sms_configs2.change_date,` +
|
||||
` projections.sms_configs2.resource_owner,` +
|
||||
` projections.sms_configs2.state,` +
|
||||
` projections.sms_configs2.sequence,` +
|
||||
expectedSMSConfigsQuery = regexp.QuoteMeta(`SELECT projections.sms_configs3.id,` +
|
||||
` projections.sms_configs3.aggregate_id,` +
|
||||
` projections.sms_configs3.creation_date,` +
|
||||
` projections.sms_configs3.change_date,` +
|
||||
` projections.sms_configs3.resource_owner,` +
|
||||
` projections.sms_configs3.state,` +
|
||||
` projections.sms_configs3.sequence,` +
|
||||
` projections.sms_configs3.description,` +
|
||||
|
||||
// twilio config
|
||||
` projections.sms_configs2_twilio.sms_id,` +
|
||||
` projections.sms_configs2_twilio.sid,` +
|
||||
` projections.sms_configs2_twilio.token,` +
|
||||
` projections.sms_configs2_twilio.sender_number,` +
|
||||
` projections.sms_configs3_twilio.sms_id,` +
|
||||
` projections.sms_configs3_twilio.sid,` +
|
||||
` projections.sms_configs3_twilio.token,` +
|
||||
` projections.sms_configs3_twilio.sender_number,` +
|
||||
|
||||
// http config
|
||||
` projections.sms_configs3_http.sms_id,` +
|
||||
` projections.sms_configs3_http.endpoint,` +
|
||||
` COUNT(*) OVER ()` +
|
||||
` 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` +
|
||||
` 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'`)
|
||||
|
||||
smsConfigCols = []string{
|
||||
@ -56,16 +68,20 @@ var (
|
||||
"resource_owner",
|
||||
"state",
|
||||
"sequence",
|
||||
"description",
|
||||
// twilio config
|
||||
"sms_id",
|
||||
"sid",
|
||||
"token",
|
||||
"sender-number",
|
||||
// http config
|
||||
"sms_id",
|
||||
"endpoint",
|
||||
}
|
||||
smsConfigsCols = append(smsConfigCols, "count")
|
||||
)
|
||||
|
||||
func Test_SMSConfigssPrepare(t *testing.T) {
|
||||
func Test_SMSConfigsPrepare(t *testing.T) {
|
||||
type want struct {
|
||||
sqlExpectations sqlExpectation
|
||||
err checkErr
|
||||
@ -104,11 +120,15 @@ func Test_SMSConfigssPrepare(t *testing.T) {
|
||||
"ro",
|
||||
domain.SMSConfigStateInactive,
|
||||
uint64(20211109),
|
||||
"description",
|
||||
// twilio config
|
||||
"sms-id",
|
||||
"sid",
|
||||
&crypto.CryptoValue{},
|
||||
"sender-number",
|
||||
// http config
|
||||
nil,
|
||||
nil,
|
||||
},
|
||||
},
|
||||
),
|
||||
@ -126,6 +146,7 @@ func Test_SMSConfigssPrepare(t *testing.T) {
|
||||
ResourceOwner: "ro",
|
||||
State: domain.SMSConfigStateInactive,
|
||||
Sequence: 20211109,
|
||||
Description: "description",
|
||||
TwilioConfig: &Twilio{
|
||||
SID: "sid",
|
||||
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",
|
||||
prepare: prepareSMSConfigsQuery,
|
||||
@ -149,13 +220,17 @@ func Test_SMSConfigssPrepare(t *testing.T) {
|
||||
testNow,
|
||||
testNow,
|
||||
"ro",
|
||||
domain.SMSConfigStateInactive,
|
||||
domain.SMSConfigStateActive,
|
||||
uint64(20211109),
|
||||
"description",
|
||||
// twilio config
|
||||
"sms-id",
|
||||
"sid",
|
||||
&crypto.CryptoValue{},
|
||||
"sender-number",
|
||||
// http config
|
||||
nil,
|
||||
nil,
|
||||
},
|
||||
{
|
||||
"sms-id2",
|
||||
@ -165,18 +240,40 @@ func Test_SMSConfigssPrepare(t *testing.T) {
|
||||
"ro",
|
||||
domain.SMSConfigStateInactive,
|
||||
uint64(20211109),
|
||||
"description",
|
||||
// twilio config
|
||||
"sms-id2",
|
||||
"sid2",
|
||||
&crypto.CryptoValue{},
|
||||
"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{
|
||||
SearchResponse: SearchResponse{
|
||||
Count: 2,
|
||||
Count: 3,
|
||||
},
|
||||
Configs: []*SMSConfig{
|
||||
{
|
||||
@ -185,8 +282,9 @@ func Test_SMSConfigssPrepare(t *testing.T) {
|
||||
CreationDate: testNow,
|
||||
ChangeDate: testNow,
|
||||
ResourceOwner: "ro",
|
||||
State: domain.SMSConfigStateInactive,
|
||||
State: domain.SMSConfigStateActive,
|
||||
Sequence: 20211109,
|
||||
Description: "description",
|
||||
TwilioConfig: &Twilio{
|
||||
SID: "sid",
|
||||
Token: &crypto.CryptoValue{},
|
||||
@ -201,12 +299,26 @@ func Test_SMSConfigssPrepare(t *testing.T) {
|
||||
ResourceOwner: "ro",
|
||||
State: domain.SMSConfigStateInactive,
|
||||
Sequence: 20211109,
|
||||
Description: "description",
|
||||
TwilioConfig: &Twilio{
|
||||
SID: "sid2",
|
||||
Token: &crypto.CryptoValue{},
|
||||
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),
|
||||
},
|
||||
{
|
||||
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,
|
||||
want: want{
|
||||
sqlExpectations: mockQuery(
|
||||
@ -279,11 +434,15 @@ func Test_SMSConfigPrepare(t *testing.T) {
|
||||
"ro",
|
||||
domain.SMSConfigStateInactive,
|
||||
uint64(20211109),
|
||||
"description",
|
||||
// twilio config
|
||||
nil,
|
||||
nil,
|
||||
nil,
|
||||
nil,
|
||||
// http config
|
||||
"sms-id",
|
||||
"sid",
|
||||
&crypto.CryptoValue{},
|
||||
"sender-number",
|
||||
"endpoint",
|
||||
},
|
||||
),
|
||||
},
|
||||
@ -295,10 +454,9 @@ func Test_SMSConfigPrepare(t *testing.T) {
|
||||
ResourceOwner: "ro",
|
||||
State: domain.SMSConfigStateInactive,
|
||||
Sequence: 20211109,
|
||||
TwilioConfig: &Twilio{
|
||||
SID: "sid",
|
||||
SenderNumber: "sender-number",
|
||||
Token: &crypto.CryptoValue{},
|
||||
Description: "description",
|
||||
HTTPConfig: &HTTP{
|
||||
Endpoint: "endpoint",
|
||||
},
|
||||
},
|
||||
},
|
||||
|
@ -18,12 +18,17 @@ func init() {
|
||||
eventstore.RegisterFilterEventMapper(AggregateType, SMTPConfigDeactivatedEventType, SMTPConfigDeactivatedEventMapper)
|
||||
eventstore.RegisterFilterEventMapper(AggregateType, SMTPConfigPasswordChangedEventType, SMTPConfigPasswordChangedEventMapper)
|
||||
eventstore.RegisterFilterEventMapper(AggregateType, SMTPConfigRemovedEventType, SMTPConfigRemovedEventMapper)
|
||||
eventstore.RegisterFilterEventMapper(AggregateType, SMSConfigTwilioAddedEventType, SMSConfigTwilioAddedEventMapper)
|
||||
eventstore.RegisterFilterEventMapper(AggregateType, SMSConfigTwilioChangedEventType, SMSConfigTwilioChangedEventMapper)
|
||||
eventstore.RegisterFilterEventMapper(AggregateType, SMSConfigTwilioTokenChangedEventType, SMSConfigTwilioTokenChangedEventMapper)
|
||||
eventstore.RegisterFilterEventMapper(AggregateType, SMSConfigActivatedEventType, SMSConfigActivatedEventMapper)
|
||||
eventstore.RegisterFilterEventMapper(AggregateType, SMSConfigDeactivatedEventType, SMSConfigDeactivatedEventMapper)
|
||||
eventstore.RegisterFilterEventMapper(AggregateType, SMSConfigRemovedEventType, SMSConfigRemovedEventMapper)
|
||||
eventstore.RegisterFilterEventMapper(AggregateType, SMSConfigTwilioAddedEventType, eventstore.GenericEventMapper[SMSConfigTwilioAddedEvent])
|
||||
eventstore.RegisterFilterEventMapper(AggregateType, SMSConfigTwilioChangedEventType, eventstore.GenericEventMapper[SMSConfigTwilioChangedEvent])
|
||||
eventstore.RegisterFilterEventMapper(AggregateType, SMSConfigTwilioTokenChangedEventType, eventstore.GenericEventMapper[SMSConfigTwilioTokenChangedEvent])
|
||||
eventstore.RegisterFilterEventMapper(AggregateType, SMSConfigHTTPAddedEventType, eventstore.GenericEventMapper[SMSConfigHTTPAddedEvent])
|
||||
eventstore.RegisterFilterEventMapper(AggregateType, SMSConfigHTTPChangedEventType, eventstore.GenericEventMapper[SMSConfigHTTPChangedEvent])
|
||||
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, DebugNotificationProviderFileChangedEventType, DebugNotificationProviderFileChangedEventMapper)
|
||||
eventstore.RegisterFilterEventMapper(AggregateType, DebugNotificationProviderFileRemovedEventType, DebugNotificationProviderFileRemovedEventMapper)
|
||||
|
@ -11,18 +11,25 @@ import (
|
||||
const (
|
||||
smsConfigPrefix = "sms.config"
|
||||
smsConfigTwilioPrefix = "twilio."
|
||||
smsConfigHTTPPrefix = "http."
|
||||
SMSConfigTwilioAddedEventType = instanceEventTypePrefix + smsConfigPrefix + smsConfigTwilioPrefix + "added"
|
||||
SMSConfigTwilioChangedEventType = instanceEventTypePrefix + smsConfigPrefix + smsConfigTwilioPrefix + "changed"
|
||||
SMSConfigHTTPAddedEventType = instanceEventTypePrefix + smsConfigPrefix + smsConfigHTTPPrefix + "added"
|
||||
SMSConfigHTTPChangedEventType = instanceEventTypePrefix + smsConfigPrefix + smsConfigHTTPPrefix + "changed"
|
||||
SMSConfigTwilioTokenChangedEventType = instanceEventTypePrefix + smsConfigPrefix + smsConfigTwilioPrefix + "token.changed"
|
||||
SMSConfigActivatedEventType = instanceEventTypePrefix + smsConfigPrefix + smsConfigTwilioPrefix + "activated"
|
||||
SMSConfigDeactivatedEventType = instanceEventTypePrefix + smsConfigPrefix + smsConfigTwilioPrefix + "deactivated"
|
||||
SMSConfigRemovedEventType = instanceEventTypePrefix + smsConfigPrefix + smsConfigTwilioPrefix + "removed"
|
||||
SMSConfigTwilioActivatedEventType = instanceEventTypePrefix + smsConfigPrefix + smsConfigTwilioPrefix + "activated"
|
||||
SMSConfigTwilioDeactivatedEventType = instanceEventTypePrefix + smsConfigPrefix + smsConfigTwilioPrefix + "deactivated"
|
||||
SMSConfigTwilioRemovedEventType = instanceEventTypePrefix + smsConfigPrefix + smsConfigTwilioPrefix + "removed"
|
||||
SMSConfigActivatedEventType = instanceEventTypePrefix + smsConfigPrefix + "activated"
|
||||
SMSConfigDeactivatedEventType = instanceEventTypePrefix + smsConfigPrefix + "deactivated"
|
||||
SMSConfigRemovedEventType = instanceEventTypePrefix + smsConfigPrefix + "removed"
|
||||
)
|
||||
|
||||
type SMSConfigTwilioAddedEvent struct {
|
||||
eventstore.BaseEvent `json:"-"`
|
||||
*eventstore.BaseEvent `json:"-"`
|
||||
|
||||
ID string `json:"id,omitempty"`
|
||||
Description string `json:"description,omitempty"`
|
||||
SID string `json:"sid,omitempty"`
|
||||
Token *crypto.CryptoValue `json:"token,omitempty"`
|
||||
SenderNumber string `json:"senderNumber,omitempty"`
|
||||
@ -32,23 +39,29 @@ func NewSMSConfigTwilioAddedEvent(
|
||||
ctx context.Context,
|
||||
aggregate *eventstore.Aggregate,
|
||||
id,
|
||||
description string,
|
||||
sid,
|
||||
senderNumber string,
|
||||
token *crypto.CryptoValue,
|
||||
) *SMSConfigTwilioAddedEvent {
|
||||
return &SMSConfigTwilioAddedEvent{
|
||||
BaseEvent: *eventstore.NewBaseEventForPush(
|
||||
BaseEvent: eventstore.NewBaseEventForPush(
|
||||
ctx,
|
||||
aggregate,
|
||||
SMSConfigTwilioAddedEventType,
|
||||
),
|
||||
ID: id,
|
||||
Description: description,
|
||||
SID: sid,
|
||||
Token: token,
|
||||
SenderNumber: senderNumber,
|
||||
}
|
||||
}
|
||||
|
||||
func (e *SMSConfigTwilioAddedEvent) SetBaseEvent(event *eventstore.BaseEvent) {
|
||||
e.BaseEvent = event
|
||||
}
|
||||
|
||||
func (e *SMSConfigTwilioAddedEvent) Payload() interface{} {
|
||||
return e
|
||||
}
|
||||
@ -57,22 +70,11 @@ func (e *SMSConfigTwilioAddedEvent) UniqueConstraints() []*eventstore.UniqueCons
|
||||
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 {
|
||||
eventstore.BaseEvent `json:"-"`
|
||||
*eventstore.BaseEvent `json:"-"`
|
||||
|
||||
ID string `json:"id,omitempty"`
|
||||
Description *string `json:"description,omitempty"`
|
||||
SID *string `json:"sid,omitempty"`
|
||||
SenderNumber *string `json:"senderNumber,omitempty"`
|
||||
}
|
||||
@ -87,7 +89,7 @@ func NewSMSConfigTwilioChangedEvent(
|
||||
return nil, zerrors.ThrowPreconditionFailed(nil, "IAM-smn8e", "Errors.NoChangesFound")
|
||||
}
|
||||
changeEvent := &SMSConfigTwilioChangedEvent{
|
||||
BaseEvent: *eventstore.NewBaseEventForPush(
|
||||
BaseEvent: eventstore.NewBaseEventForPush(
|
||||
ctx,
|
||||
aggregate,
|
||||
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) {
|
||||
return func(e *SMSConfigTwilioChangedEvent) {
|
||||
e.SenderNumber = &senderNumber
|
||||
}
|
||||
}
|
||||
|
||||
func (e *SMSConfigTwilioChangedEvent) SetBaseEvent(event *eventstore.BaseEvent) {
|
||||
e.BaseEvent = event
|
||||
}
|
||||
|
||||
func (e *SMSConfigTwilioChangedEvent) Payload() interface{} {
|
||||
return e
|
||||
}
|
||||
@ -122,20 +134,8 @@ func (e *SMSConfigTwilioChangedEvent) UniqueConstraints() []*eventstore.UniqueCo
|
||||
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 {
|
||||
eventstore.BaseEvent `json:"-"`
|
||||
*eventstore.BaseEvent `json:"-"`
|
||||
|
||||
ID string `json:"id,omitempty"`
|
||||
Token *crypto.CryptoValue `json:"token,omitempty"`
|
||||
@ -148,7 +148,7 @@ func NewSMSConfigTokenChangedEvent(
|
||||
token *crypto.CryptoValue,
|
||||
) *SMSConfigTwilioTokenChangedEvent {
|
||||
return &SMSConfigTwilioTokenChangedEvent{
|
||||
BaseEvent: *eventstore.NewBaseEventForPush(
|
||||
BaseEvent: eventstore.NewBaseEventForPush(
|
||||
ctx,
|
||||
aggregate,
|
||||
SMSConfigTwilioTokenChangedEventType,
|
||||
@ -158,6 +158,10 @@ func NewSMSConfigTokenChangedEvent(
|
||||
}
|
||||
}
|
||||
|
||||
func (e *SMSConfigTwilioTokenChangedEvent) SetBaseEvent(event *eventstore.BaseEvent) {
|
||||
e.BaseEvent = event
|
||||
}
|
||||
|
||||
func (e *SMSConfigTwilioTokenChangedEvent) Payload() interface{} {
|
||||
return e
|
||||
}
|
||||
@ -166,30 +170,130 @@ func (e *SMSConfigTwilioTokenChangedEvent) UniqueConstraints() []*eventstore.Uni
|
||||
return nil
|
||||
}
|
||||
|
||||
func SMSConfigTwilioTokenChangedEventMapper(event eventstore.Event) (eventstore.Event, error) {
|
||||
smtpConfigTokenChagned := &SMSConfigTwilioTokenChangedEvent{
|
||||
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")
|
||||
}
|
||||
type SMSConfigHTTPAddedEvent struct {
|
||||
*eventstore.BaseEvent `json:"-"`
|
||||
|
||||
return smtpConfigTokenChagned, nil
|
||||
ID string `json:"id,omitempty"`
|
||||
Description string `json:"description,omitempty"`
|
||||
Endpoint string `json:"endpoint,omitempty"`
|
||||
}
|
||||
|
||||
func NewSMSConfigHTTPAddedEvent(
|
||||
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"`
|
||||
}
|
||||
|
||||
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"`
|
||||
*eventstore.BaseEvent `json:"-"`
|
||||
ID string `json:"id,omitempty"`
|
||||
}
|
||||
|
||||
func NewSMSConfigTwilioActivatedEvent(
|
||||
func NewSMSConfigActivatedEvent(
|
||||
ctx context.Context,
|
||||
aggregate *eventstore.Aggregate,
|
||||
id string,
|
||||
) *SMSConfigActivatedEvent {
|
||||
return &SMSConfigActivatedEvent{
|
||||
BaseEvent: *eventstore.NewBaseEventForPush(
|
||||
BaseEvent: eventstore.NewBaseEventForPush(
|
||||
ctx,
|
||||
aggregate,
|
||||
SMSConfigActivatedEventType,
|
||||
@ -198,6 +302,10 @@ func NewSMSConfigTwilioActivatedEvent(
|
||||
}
|
||||
}
|
||||
|
||||
func (e *SMSConfigActivatedEvent) SetBaseEvent(event *eventstore.BaseEvent) {
|
||||
e.BaseEvent = event
|
||||
}
|
||||
|
||||
func (e *SMSConfigActivatedEvent) Payload() interface{} {
|
||||
return e
|
||||
}
|
||||
@ -206,21 +314,26 @@ func (e *SMSConfigActivatedEvent) UniqueConstraints() []*eventstore.UniqueConstr
|
||||
return nil
|
||||
}
|
||||
|
||||
func SMSConfigActivatedEventMapper(event eventstore.Event) (eventstore.Event, error) {
|
||||
smsConfigActivated := &SMSConfigActivatedEvent{
|
||||
BaseEvent: *eventstore.BaseEventFromRepo(event),
|
||||
}
|
||||
err := event.Unmarshal(smsConfigActivated)
|
||||
if err != nil {
|
||||
return nil, zerrors.ThrowInternal(err, "IAM-dn92f", "unable to unmarshal sms config twilio activated changed")
|
||||
}
|
||||
type SMSConfigTwilioDeactivatedEvent struct {
|
||||
*eventstore.BaseEvent `json:"-"`
|
||||
ID string `json:"id,omitempty"`
|
||||
}
|
||||
|
||||
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 {
|
||||
eventstore.BaseEvent `json:"-"`
|
||||
ID string `json:"id,omitempty"`
|
||||
*eventstore.BaseEvent `json:"-"`
|
||||
ID string `json:"id,omitempty"`
|
||||
}
|
||||
|
||||
func NewSMSConfigDeactivatedEvent(
|
||||
@ -229,7 +342,7 @@ func NewSMSConfigDeactivatedEvent(
|
||||
id string,
|
||||
) *SMSConfigDeactivatedEvent {
|
||||
return &SMSConfigDeactivatedEvent{
|
||||
BaseEvent: *eventstore.NewBaseEventForPush(
|
||||
BaseEvent: eventstore.NewBaseEventForPush(
|
||||
ctx,
|
||||
aggregate,
|
||||
SMSConfigDeactivatedEventType,
|
||||
@ -238,6 +351,10 @@ func NewSMSConfigDeactivatedEvent(
|
||||
}
|
||||
}
|
||||
|
||||
func (e *SMSConfigDeactivatedEvent) SetBaseEvent(event *eventstore.BaseEvent) {
|
||||
e.BaseEvent = event
|
||||
}
|
||||
|
||||
func (e *SMSConfigDeactivatedEvent) Payload() interface{} {
|
||||
return e
|
||||
}
|
||||
@ -246,21 +363,26 @@ func (e *SMSConfigDeactivatedEvent) UniqueConstraints() []*eventstore.UniqueCons
|
||||
return nil
|
||||
}
|
||||
|
||||
func SMSConfigDeactivatedEventMapper(event eventstore.Event) (eventstore.Event, error) {
|
||||
smsConfigDeactivated := &SMSConfigDeactivatedEvent{
|
||||
BaseEvent: *eventstore.BaseEventFromRepo(event),
|
||||
}
|
||||
err := event.Unmarshal(smsConfigDeactivated)
|
||||
if err != nil {
|
||||
return nil, zerrors.ThrowInternal(err, "IAM-dn92f", "unable to unmarshal sms config twilio deactivated changed")
|
||||
}
|
||||
type SMSConfigTwilioRemovedEvent struct {
|
||||
*eventstore.BaseEvent `json:"-"`
|
||||
ID string `json:"id,omitempty"`
|
||||
}
|
||||
|
||||
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 {
|
||||
eventstore.BaseEvent `json:"-"`
|
||||
ID string `json:"id,omitempty"`
|
||||
*eventstore.BaseEvent `json:"-"`
|
||||
ID string `json:"id,omitempty"`
|
||||
}
|
||||
|
||||
func NewSMSConfigRemovedEvent(
|
||||
@ -269,7 +391,7 @@ func NewSMSConfigRemovedEvent(
|
||||
id string,
|
||||
) *SMSConfigRemovedEvent {
|
||||
return &SMSConfigRemovedEvent{
|
||||
BaseEvent: *eventstore.NewBaseEventForPush(
|
||||
BaseEvent: eventstore.NewBaseEventForPush(
|
||||
ctx,
|
||||
aggregate,
|
||||
SMSConfigRemovedEventType,
|
||||
@ -278,6 +400,10 @@ func NewSMSConfigRemovedEvent(
|
||||
}
|
||||
}
|
||||
|
||||
func (e *SMSConfigRemovedEvent) SetBaseEvent(event *eventstore.BaseEvent) {
|
||||
e.BaseEvent = event
|
||||
}
|
||||
|
||||
func (e *SMSConfigRemovedEvent) Payload() interface{} {
|
||||
return e
|
||||
}
|
||||
@ -285,15 +411,3 @@ func (e *SMSConfigRemovedEvent) Payload() interface{} {
|
||||
func (e *SMSConfigRemovedEvent) UniqueConstraints() []*eventstore.UniqueConstraint {
|
||||
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) {
|
||||
option (google.api.http) = {
|
||||
post: "/sms/{id}/_activate";
|
||||
@ -4507,6 +4541,14 @@ message AddSMSProviderTwilioRequest {
|
||||
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 {
|
||||
@ -4534,6 +4576,14 @@ message UpdateSMSProviderTwilioRequest {
|
||||
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 {
|
||||
@ -4549,6 +4599,56 @@ message UpdateSMSProviderTwilioTokenResponse {
|
||||
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 {
|
||||
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;
|
||||
|
||||
option go_package ="github.com/zitadel/zitadel/pkg/grpc/settings";
|
||||
option go_package = "github.com/zitadel/zitadel/pkg/grpc/settings";
|
||||
|
||||
message SecretGenerator {
|
||||
SecretGeneratorType generator_type = 1;
|
||||
@ -99,9 +99,11 @@ message SMSProvider {
|
||||
zitadel.v1.ObjectDetails details = 1;
|
||||
string id = 2;
|
||||
SMSProviderConfigState state = 3;
|
||||
string description = 6;
|
||||
|
||||
oneof config {
|
||||
TwilioConfig twilio = 4;
|
||||
HTTPConfig http = 5;
|
||||
}
|
||||
}
|
||||
|
||||
@ -110,6 +112,10 @@ message TwilioConfig {
|
||||
string sender_number = 2;
|
||||
}
|
||||
|
||||
message HTTPConfig {
|
||||
string endpoint = 1;
|
||||
}
|
||||
|
||||
enum SMSProviderConfigState {
|
||||
SMS_PROVIDER_CONFIG_STATE_UNSPECIFIED = 0;
|
||||
SMS_PROVIDER_CONFIG_ACTIVE = 1;
|
||||
@ -117,8 +123,8 @@ enum SMSProviderConfigState {
|
||||
}
|
||||
|
||||
message DebugNotificationProvider {
|
||||
zitadel.v1.ObjectDetails details = 1;
|
||||
bool compact = 2;
|
||||
zitadel.v1.ObjectDetails details = 1;
|
||||
bool compact = 2;
|
||||
}
|
||||
|
||||
message OIDCSettings {
|
||||
|
Loading…
Reference in New Issue
Block a user