mirror of
https://github.com/zitadel/zitadel.git
synced 2025-12-06 05:32:04 +00:00
feat: http provider signing key addition (#10641)
# Which Problems Are Solved
HTTP Request to HTTP providers for Email or SMS are not signed.
# How the Problems Are Solved
Add a Signing Key to the HTTP Provider resources, which is then used to
generate a header to sign the payload.
# Additional Changes
Additional tests for query side of the SMTP provider.
# Additional Context
Closes #10067
---------
Co-authored-by: Marco A. <marco@zitadel.com>
(cherry picked from commit 8909b9a2a6)
This commit is contained in:
committed by
Livio Spring
parent
d2d94ea088
commit
1a7cd6e1af
@@ -149,6 +149,8 @@ func projections(
|
|||||||
keys.OIDC,
|
keys.OIDC,
|
||||||
keys.SAML,
|
keys.SAML,
|
||||||
keys.Target,
|
keys.Target,
|
||||||
|
keys.SMS,
|
||||||
|
keys.SMTP,
|
||||||
config.InternalAuthZ.RolePermissionMappings,
|
config.InternalAuthZ.RolePermissionMappings,
|
||||||
sessionTokenVerifier,
|
sessionTokenVerifier,
|
||||||
func(q *query.Queries) domain.PermissionCheck {
|
func(q *query.Queries) domain.PermissionCheck {
|
||||||
|
|||||||
27
cmd/setup/62.go
Normal file
27
cmd/setup/62.go
Normal file
@@ -0,0 +1,27 @@
|
|||||||
|
package setup
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
_ "embed"
|
||||||
|
|
||||||
|
"github.com/zitadel/zitadel/internal/database"
|
||||||
|
"github.com/zitadel/zitadel/internal/eventstore"
|
||||||
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
//go:embed 62.sql
|
||||||
|
addHTTPProviderSigningKey string
|
||||||
|
)
|
||||||
|
|
||||||
|
type HTTPProviderAddSigningKey struct {
|
||||||
|
dbClient *database.DB
|
||||||
|
}
|
||||||
|
|
||||||
|
func (mig *HTTPProviderAddSigningKey) Execute(ctx context.Context, _ eventstore.Event) error {
|
||||||
|
_, err := mig.dbClient.ExecContext(ctx, addHTTPProviderSigningKey)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
func (mig *HTTPProviderAddSigningKey) String() string {
|
||||||
|
return "62_http_provider_add_signing_key"
|
||||||
|
}
|
||||||
2
cmd/setup/62.sql
Normal file
2
cmd/setup/62.sql
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
ALTER TABLE IF EXISTS projections.sms_configs3_http ADD COLUMN IF NOT EXISTS signing_key TEXT NULL;
|
||||||
|
ALTER TABLE IF EXISTS projections.smtp_configs5_http ADD COLUMN IF NOT EXISTS signing_key TEXT NULL;
|
||||||
@@ -158,6 +158,7 @@ type Steps struct {
|
|||||||
s59SetupWebkeys *SetupWebkeys
|
s59SetupWebkeys *SetupWebkeys
|
||||||
s60GenerateSystemID *GenerateSystemID
|
s60GenerateSystemID *GenerateSystemID
|
||||||
s61IDPTemplate6SAMLSignatureAlgorithm *IDPTemplate6SAMLSignatureAlgorithm
|
s61IDPTemplate6SAMLSignatureAlgorithm *IDPTemplate6SAMLSignatureAlgorithm
|
||||||
|
s62HTTPProviderAddSigningKey *HTTPProviderAddSigningKey
|
||||||
}
|
}
|
||||||
|
|
||||||
func MustNewSteps(v *viper.Viper) *Steps {
|
func MustNewSteps(v *viper.Viper) *Steps {
|
||||||
|
|||||||
@@ -219,6 +219,7 @@ func Setup(ctx context.Context, config *Config, steps *Steps, masterKey string)
|
|||||||
steps.s58ReplaceLoginNames3View = &ReplaceLoginNames3View{dbClient: dbClient}
|
steps.s58ReplaceLoginNames3View = &ReplaceLoginNames3View{dbClient: dbClient}
|
||||||
steps.s60GenerateSystemID = &GenerateSystemID{eventstore: eventstoreClient}
|
steps.s60GenerateSystemID = &GenerateSystemID{eventstore: eventstoreClient}
|
||||||
steps.s61IDPTemplate6SAMLSignatureAlgorithm = &IDPTemplate6SAMLSignatureAlgorithm{dbClient: dbClient}
|
steps.s61IDPTemplate6SAMLSignatureAlgorithm = &IDPTemplate6SAMLSignatureAlgorithm{dbClient: dbClient}
|
||||||
|
steps.s62HTTPProviderAddSigningKey = &HTTPProviderAddSigningKey{dbClient: dbClient}
|
||||||
|
|
||||||
err = projection.Create(ctx, dbClient, eventstoreClient, config.Projections, nil, nil, nil)
|
err = projection.Create(ctx, dbClient, eventstoreClient, config.Projections, nil, nil, nil)
|
||||||
logging.OnError(err).Fatal("unable to start projections")
|
logging.OnError(err).Fatal("unable to start projections")
|
||||||
@@ -268,6 +269,7 @@ func Setup(ctx context.Context, config *Config, steps *Steps, masterKey string)
|
|||||||
steps.s58ReplaceLoginNames3View,
|
steps.s58ReplaceLoginNames3View,
|
||||||
steps.s60GenerateSystemID,
|
steps.s60GenerateSystemID,
|
||||||
steps.s61IDPTemplate6SAMLSignatureAlgorithm,
|
steps.s61IDPTemplate6SAMLSignatureAlgorithm,
|
||||||
|
steps.s62HTTPProviderAddSigningKey,
|
||||||
} {
|
} {
|
||||||
setupErr = executeMigration(ctx, eventstoreClient, step, "migration failed")
|
setupErr = executeMigration(ctx, eventstoreClient, step, "migration failed")
|
||||||
if setupErr != nil {
|
if setupErr != nil {
|
||||||
@@ -468,6 +470,8 @@ func startCommandsQueries(
|
|||||||
keys.OIDC,
|
keys.OIDC,
|
||||||
keys.SAML,
|
keys.SAML,
|
||||||
keys.Target,
|
keys.Target,
|
||||||
|
keys.SMS,
|
||||||
|
keys.SMTP,
|
||||||
config.InternalAuthZ.RolePermissionMappings,
|
config.InternalAuthZ.RolePermissionMappings,
|
||||||
sessionTokenVerifier,
|
sessionTokenVerifier,
|
||||||
func(q *query.Queries) domain.PermissionCheck {
|
func(q *query.Queries) domain.PermissionCheck {
|
||||||
|
|||||||
@@ -205,6 +205,8 @@ func startZitadel(ctx context.Context, config *Config, masterKey string, server
|
|||||||
keys.OIDC,
|
keys.OIDC,
|
||||||
keys.SAML,
|
keys.SAML,
|
||||||
keys.Target,
|
keys.Target,
|
||||||
|
keys.SMS,
|
||||||
|
keys.SMTP,
|
||||||
config.InternalAuthZ.RolePermissionMappings,
|
config.InternalAuthZ.RolePermissionMappings,
|
||||||
sessionTokenVerifier,
|
sessionTokenVerifier,
|
||||||
func(q *query.Queries) domain.PermissionCheck {
|
func(q *query.Queries) domain.PermissionCheck {
|
||||||
|
|||||||
@@ -55,8 +55,9 @@ func (s *Server) AddEmailProviderHTTP(ctx context.Context, req *admin_pb.AddEmai
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
return &admin_pb.AddEmailProviderHTTPResponse{
|
return &admin_pb.AddEmailProviderHTTPResponse{
|
||||||
Details: object.DomainToChangeDetailsPb(config.Details),
|
Details: object.DomainToChangeDetailsPb(config.Details),
|
||||||
Id: config.ID,
|
Id: config.ID,
|
||||||
|
SigningKey: config.SigningKey,
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -66,7 +67,8 @@ func (s *Server) UpdateEmailProviderHTTP(ctx context.Context, req *admin_pb.Upda
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
return &admin_pb.UpdateEmailProviderHTTPResponse{
|
return &admin_pb.UpdateEmailProviderHTTPResponse{
|
||||||
Details: object.DomainToChangeDetailsPb(config.Details),
|
Details: object.DomainToChangeDetailsPb(config.Details),
|
||||||
|
SigningKey: config.SigningKey,
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -68,7 +68,8 @@ func emailProviderToPb(config *query.SMTPConfig) settings_pb.EmailConfig {
|
|||||||
func httpToPb(http *query.HTTP) *settings_pb.EmailProvider_Http {
|
func httpToPb(http *query.HTTP) *settings_pb.EmailProvider_Http {
|
||||||
return &settings_pb.EmailProvider_Http{
|
return &settings_pb.EmailProvider_Http{
|
||||||
Http: &settings_pb.EmailProviderHTTP{
|
Http: &settings_pb.EmailProviderHTTP{
|
||||||
Endpoint: http.Endpoint,
|
Endpoint: http.Endpoint,
|
||||||
|
SigningKey: http.SigningKey,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -76,11 +77,12 @@ func httpToPb(http *query.HTTP) *settings_pb.EmailProvider_Http {
|
|||||||
func smtpToPb(config *query.SMTP) *settings_pb.EmailProvider_Smtp {
|
func smtpToPb(config *query.SMTP) *settings_pb.EmailProvider_Smtp {
|
||||||
return &settings_pb.EmailProvider_Smtp{
|
return &settings_pb.EmailProvider_Smtp{
|
||||||
Smtp: &settings_pb.EmailProviderSMTP{
|
Smtp: &settings_pb.EmailProviderSMTP{
|
||||||
Tls: config.TLS,
|
Tls: config.TLS,
|
||||||
Host: config.Host,
|
Host: config.Host,
|
||||||
User: config.User,
|
User: config.User,
|
||||||
SenderAddress: config.SenderAddress,
|
SenderAddress: config.SenderAddress,
|
||||||
SenderName: config.SenderName,
|
SenderName: config.SenderName,
|
||||||
|
ReplyToAddress: config.ReplyToAddress,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -123,11 +125,14 @@ func addEmailProviderHTTPToConfig(ctx context.Context, req *admin_pb.AddEmailPro
|
|||||||
}
|
}
|
||||||
|
|
||||||
func updateEmailProviderHTTPToConfig(ctx context.Context, req *admin_pb.UpdateEmailProviderHTTPRequest) *command.ChangeSMTPConfigHTTP {
|
func updateEmailProviderHTTPToConfig(ctx context.Context, req *admin_pb.UpdateEmailProviderHTTPRequest) *command.ChangeSMTPConfigHTTP {
|
||||||
|
// TODO handle expiration, currently only immediate expiration is supported
|
||||||
|
expirationSigningKey := req.GetExpirationSigningKey() != nil
|
||||||
return &command.ChangeSMTPConfigHTTP{
|
return &command.ChangeSMTPConfigHTTP{
|
||||||
ResourceOwner: authz.GetInstance(ctx).InstanceID(),
|
ResourceOwner: authz.GetInstance(ctx).InstanceID(),
|
||||||
ID: req.Id,
|
ID: req.Id,
|
||||||
Description: req.Description,
|
Description: req.Description,
|
||||||
Endpoint: req.Endpoint,
|
Endpoint: req.Endpoint,
|
||||||
|
ExpirationSigningKey: expirationSigningKey,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
554
internal/api/grpc/admin/email_converters_test.go
Normal file
554
internal/api/grpc/admin/email_converters_test.go
Normal file
@@ -0,0 +1,554 @@
|
|||||||
|
package admin
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"testing"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"github.com/stretchr/testify/assert"
|
||||||
|
"github.com/stretchr/testify/require"
|
||||||
|
"google.golang.org/protobuf/types/known/durationpb"
|
||||||
|
"google.golang.org/protobuf/types/known/timestamppb"
|
||||||
|
|
||||||
|
"github.com/zitadel/zitadel/internal/api/authz"
|
||||||
|
"github.com/zitadel/zitadel/internal/command"
|
||||||
|
"github.com/zitadel/zitadel/internal/domain"
|
||||||
|
"github.com/zitadel/zitadel/internal/query"
|
||||||
|
admin_pb "github.com/zitadel/zitadel/pkg/grpc/admin"
|
||||||
|
object_pb "github.com/zitadel/zitadel/pkg/grpc/object"
|
||||||
|
settings_pb "github.com/zitadel/zitadel/pkg/grpc/settings"
|
||||||
|
)
|
||||||
|
|
||||||
|
func Test_listEmailProvidersToModel(t *testing.T) {
|
||||||
|
type args struct {
|
||||||
|
req *admin_pb.ListEmailProvidersRequest
|
||||||
|
}
|
||||||
|
tests := []struct {
|
||||||
|
name string
|
||||||
|
args args
|
||||||
|
res *query.SMTPConfigsSearchQueries
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
name: "all fields filled",
|
||||||
|
args: args{
|
||||||
|
req: &admin_pb.ListEmailProvidersRequest{
|
||||||
|
Query: &object_pb.ListQuery{
|
||||||
|
Offset: 100,
|
||||||
|
Limit: 100,
|
||||||
|
Asc: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
res: &query.SMTPConfigsSearchQueries{
|
||||||
|
SearchRequest: query.SearchRequest{
|
||||||
|
Offset: 100,
|
||||||
|
Limit: 100,
|
||||||
|
Asc: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
for _, tt := range tests {
|
||||||
|
t.Run(tt.name, func(t *testing.T) {
|
||||||
|
got, err := listEmailProvidersToModel(tt.args.req)
|
||||||
|
require.NoError(t, err)
|
||||||
|
assert.Equal(t, tt.res, got)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func Test_emailProvidersToPb(t *testing.T) {
|
||||||
|
type args struct {
|
||||||
|
req []*query.SMTPConfig
|
||||||
|
}
|
||||||
|
tests := []struct {
|
||||||
|
name string
|
||||||
|
args args
|
||||||
|
res []*settings_pb.EmailProvider
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
name: "all fields filled",
|
||||||
|
args: args{
|
||||||
|
req: []*query.SMTPConfig{
|
||||||
|
{
|
||||||
|
CreationDate: time.Date(2000, 1, 1, 0, 0, 0, 0, time.UTC),
|
||||||
|
ChangeDate: time.Date(2000, 1, 1, 0, 0, 0, 0, time.UTC),
|
||||||
|
ResourceOwner: "resourceowner",
|
||||||
|
AggregateID: "agg",
|
||||||
|
ID: "id",
|
||||||
|
Sequence: 1,
|
||||||
|
Description: "description",
|
||||||
|
SMTPConfig: &query.SMTP{
|
||||||
|
TLS: true,
|
||||||
|
SenderAddress: "sender",
|
||||||
|
SenderName: "sendername",
|
||||||
|
ReplyToAddress: "address",
|
||||||
|
Host: "host",
|
||||||
|
User: "user",
|
||||||
|
},
|
||||||
|
HTTPConfig: nil,
|
||||||
|
State: 1,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
CreationDate: time.Date(2000, 1, 1, 0, 0, 0, 0, time.UTC),
|
||||||
|
ChangeDate: time.Date(2000, 1, 1, 0, 0, 0, 0, time.UTC),
|
||||||
|
ResourceOwner: "resourceowner",
|
||||||
|
AggregateID: "agg",
|
||||||
|
ID: "id",
|
||||||
|
Sequence: 1,
|
||||||
|
Description: "description",
|
||||||
|
SMTPConfig: nil,
|
||||||
|
HTTPConfig: &query.HTTP{
|
||||||
|
Endpoint: "endpoint",
|
||||||
|
SigningKey: "key",
|
||||||
|
},
|
||||||
|
State: 1,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
res: []*settings_pb.EmailProvider{
|
||||||
|
{
|
||||||
|
Details: &object_pb.ObjectDetails{
|
||||||
|
Sequence: 1,
|
||||||
|
CreationDate: timestamppb.New(time.Date(2000, 1, 1, 0, 0, 0, 0, time.UTC)),
|
||||||
|
ChangeDate: timestamppb.New(time.Date(2000, 1, 1, 0, 0, 0, 0, time.UTC)),
|
||||||
|
ResourceOwner: "resourceowner",
|
||||||
|
},
|
||||||
|
Id: "id",
|
||||||
|
State: 1,
|
||||||
|
Description: "description",
|
||||||
|
Config: &settings_pb.EmailProvider_Smtp{
|
||||||
|
Smtp: &settings_pb.EmailProviderSMTP{
|
||||||
|
SenderAddress: "sender",
|
||||||
|
SenderName: "sendername",
|
||||||
|
Tls: true,
|
||||||
|
Host: "host",
|
||||||
|
User: "user",
|
||||||
|
ReplyToAddress: "address",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Details: &object_pb.ObjectDetails{
|
||||||
|
Sequence: 1,
|
||||||
|
CreationDate: timestamppb.New(time.Date(2000, 1, 1, 0, 0, 0, 0, time.UTC)),
|
||||||
|
ChangeDate: timestamppb.New(time.Date(2000, 1, 1, 0, 0, 0, 0, time.UTC)),
|
||||||
|
ResourceOwner: "resourceowner",
|
||||||
|
},
|
||||||
|
Id: "id",
|
||||||
|
State: 1,
|
||||||
|
Description: "description",
|
||||||
|
Config: &settings_pb.EmailProvider_Http{
|
||||||
|
Http: &settings_pb.EmailProviderHTTP{
|
||||||
|
Endpoint: "endpoint",
|
||||||
|
SigningKey: "key",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
for _, tt := range tests {
|
||||||
|
t.Run(tt.name, func(t *testing.T) {
|
||||||
|
got := emailProvidersToPb(tt.args.req)
|
||||||
|
assert.Equal(t, tt.res, got)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func Test_emailProviderToProviderPb(t *testing.T) {
|
||||||
|
type args struct {
|
||||||
|
req *query.SMTPConfig
|
||||||
|
}
|
||||||
|
tests := []struct {
|
||||||
|
name string
|
||||||
|
args args
|
||||||
|
res *settings_pb.EmailProvider
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
name: "all fields filled, smtp",
|
||||||
|
args: args{
|
||||||
|
req: &query.SMTPConfig{
|
||||||
|
|
||||||
|
CreationDate: time.Date(2000, 1, 1, 0, 0, 0, 0, time.UTC),
|
||||||
|
ChangeDate: time.Date(2000, 1, 1, 0, 0, 0, 0, time.UTC),
|
||||||
|
ResourceOwner: "resourceowner",
|
||||||
|
AggregateID: "agg",
|
||||||
|
ID: "id",
|
||||||
|
Sequence: 1,
|
||||||
|
Description: "description",
|
||||||
|
SMTPConfig: &query.SMTP{
|
||||||
|
TLS: true,
|
||||||
|
SenderAddress: "sender",
|
||||||
|
SenderName: "sendername",
|
||||||
|
ReplyToAddress: "address",
|
||||||
|
Host: "host",
|
||||||
|
User: "user",
|
||||||
|
},
|
||||||
|
HTTPConfig: &query.HTTP{
|
||||||
|
Endpoint: "endpoint",
|
||||||
|
SigningKey: "key",
|
||||||
|
},
|
||||||
|
State: 1,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
res: &settings_pb.EmailProvider{
|
||||||
|
Details: &object_pb.ObjectDetails{
|
||||||
|
Sequence: 1,
|
||||||
|
CreationDate: timestamppb.New(time.Date(2000, 1, 1, 0, 0, 0, 0, time.UTC)),
|
||||||
|
ChangeDate: timestamppb.New(time.Date(2000, 1, 1, 0, 0, 0, 0, time.UTC)),
|
||||||
|
ResourceOwner: "resourceowner",
|
||||||
|
},
|
||||||
|
Id: "id",
|
||||||
|
State: 1,
|
||||||
|
Description: "description",
|
||||||
|
Config: &settings_pb.EmailProvider_Smtp{
|
||||||
|
Smtp: &settings_pb.EmailProviderSMTP{
|
||||||
|
SenderAddress: "sender",
|
||||||
|
SenderName: "sendername",
|
||||||
|
Tls: true,
|
||||||
|
Host: "host",
|
||||||
|
User: "user",
|
||||||
|
ReplyToAddress: "address",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "all fields filled, http",
|
||||||
|
args: args{
|
||||||
|
req: &query.SMTPConfig{
|
||||||
|
CreationDate: time.Date(2000, 1, 1, 0, 0, 0, 0, time.UTC),
|
||||||
|
ChangeDate: time.Date(2000, 1, 1, 0, 0, 0, 0, time.UTC),
|
||||||
|
ResourceOwner: "resourceowner",
|
||||||
|
AggregateID: "agg",
|
||||||
|
ID: "id",
|
||||||
|
Sequence: 1,
|
||||||
|
Description: "description",
|
||||||
|
HTTPConfig: &query.HTTP{
|
||||||
|
Endpoint: "endpoint",
|
||||||
|
SigningKey: "key",
|
||||||
|
},
|
||||||
|
State: 1,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
res: &settings_pb.EmailProvider{
|
||||||
|
Details: &object_pb.ObjectDetails{
|
||||||
|
Sequence: 1,
|
||||||
|
CreationDate: timestamppb.New(time.Date(2000, 1, 1, 0, 0, 0, 0, time.UTC)),
|
||||||
|
ChangeDate: timestamppb.New(time.Date(2000, 1, 1, 0, 0, 0, 0, time.UTC)),
|
||||||
|
ResourceOwner: "resourceowner",
|
||||||
|
},
|
||||||
|
Id: "id",
|
||||||
|
State: 1,
|
||||||
|
Description: "description",
|
||||||
|
Config: &settings_pb.EmailProvider_Http{
|
||||||
|
Http: &settings_pb.EmailProviderHTTP{
|
||||||
|
Endpoint: "endpoint",
|
||||||
|
SigningKey: "key",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
for _, tt := range tests {
|
||||||
|
t.Run(tt.name, func(t *testing.T) {
|
||||||
|
got := emailProviderToProviderPb(tt.args.req)
|
||||||
|
assert.Equal(t, tt.res, got)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func Test_emailProviderStateToPb(t *testing.T) {
|
||||||
|
type args struct {
|
||||||
|
req domain.SMTPConfigState
|
||||||
|
}
|
||||||
|
tests := []struct {
|
||||||
|
name string
|
||||||
|
args args
|
||||||
|
res settings_pb.EmailProviderState
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
name: "unspecified",
|
||||||
|
args: args{
|
||||||
|
req: domain.SMTPConfigStateUnspecified,
|
||||||
|
},
|
||||||
|
res: settings_pb.EmailProviderState_EMAIL_PROVIDER_STATE_UNSPECIFIED,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "removed",
|
||||||
|
args: args{
|
||||||
|
req: domain.SMTPConfigStateRemoved,
|
||||||
|
},
|
||||||
|
res: settings_pb.EmailProviderState_EMAIL_PROVIDER_STATE_UNSPECIFIED,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "active",
|
||||||
|
args: args{
|
||||||
|
req: domain.SMTPConfigStateActive,
|
||||||
|
},
|
||||||
|
res: settings_pb.EmailProviderState_EMAIL_PROVIDER_ACTIVE,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "inactive",
|
||||||
|
args: args{
|
||||||
|
req: domain.SMTPConfigStateInactive,
|
||||||
|
},
|
||||||
|
res: settings_pb.EmailProviderState_EMAIL_PROVIDER_INACTIVE,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "default",
|
||||||
|
args: args{
|
||||||
|
req: 100,
|
||||||
|
},
|
||||||
|
res: settings_pb.EmailProviderState_EMAIL_PROVIDER_STATE_UNSPECIFIED,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
for _, tt := range tests {
|
||||||
|
t.Run(tt.name, func(t *testing.T) {
|
||||||
|
got := emailProviderStateToPb(tt.args.req)
|
||||||
|
assert.Equal(t, tt.res, got)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func Test_httpToPb(t *testing.T) {
|
||||||
|
type args struct {
|
||||||
|
req *query.HTTP
|
||||||
|
}
|
||||||
|
tests := []struct {
|
||||||
|
name string
|
||||||
|
args args
|
||||||
|
res *settings_pb.EmailProvider_Http
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
name: "all fields filled",
|
||||||
|
args: args{
|
||||||
|
req: &query.HTTP{
|
||||||
|
Endpoint: "endpoint",
|
||||||
|
SigningKey: "key",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
res: &settings_pb.EmailProvider_Http{
|
||||||
|
Http: &settings_pb.EmailProviderHTTP{
|
||||||
|
Endpoint: "endpoint",
|
||||||
|
SigningKey: "key",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
for _, tt := range tests {
|
||||||
|
t.Run(tt.name, func(t *testing.T) {
|
||||||
|
got := httpToPb(tt.args.req)
|
||||||
|
assert.Equal(t, tt.res, got)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func Test_smtpToPb(t *testing.T) {
|
||||||
|
type args struct {
|
||||||
|
req *query.SMTP
|
||||||
|
}
|
||||||
|
tests := []struct {
|
||||||
|
name string
|
||||||
|
args args
|
||||||
|
res *settings_pb.EmailProvider_Smtp
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
name: "all fields filled",
|
||||||
|
args: args{
|
||||||
|
req: &query.SMTP{
|
||||||
|
SenderAddress: "sender",
|
||||||
|
SenderName: "sendername",
|
||||||
|
TLS: true,
|
||||||
|
Host: "host",
|
||||||
|
User: "user",
|
||||||
|
ReplyToAddress: "address",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
res: &settings_pb.EmailProvider_Smtp{
|
||||||
|
Smtp: &settings_pb.EmailProviderSMTP{
|
||||||
|
SenderAddress: "sender",
|
||||||
|
SenderName: "sendername",
|
||||||
|
Tls: true,
|
||||||
|
Host: "host",
|
||||||
|
User: "user",
|
||||||
|
ReplyToAddress: "address",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
for _, tt := range tests {
|
||||||
|
t.Run(tt.name, func(t *testing.T) {
|
||||||
|
got := smtpToPb(tt.args.req)
|
||||||
|
assert.Equal(t, tt.res, got)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func Test_addEmailProviderSMTPToConfig(t *testing.T) {
|
||||||
|
type args struct {
|
||||||
|
ctx context.Context
|
||||||
|
req *admin_pb.AddEmailProviderSMTPRequest
|
||||||
|
}
|
||||||
|
tests := []struct {
|
||||||
|
name string
|
||||||
|
args args
|
||||||
|
res *command.AddSMTPConfig
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
name: "all fields filled",
|
||||||
|
args: args{
|
||||||
|
ctx: authz.WithInstanceID(context.Background(), "instance"),
|
||||||
|
req: &admin_pb.AddEmailProviderSMTPRequest{
|
||||||
|
SenderAddress: "sender",
|
||||||
|
SenderName: "sendername",
|
||||||
|
Tls: true,
|
||||||
|
Host: "host",
|
||||||
|
User: "user",
|
||||||
|
Password: "password",
|
||||||
|
ReplyToAddress: "address",
|
||||||
|
Description: "description",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
res: &command.AddSMTPConfig{
|
||||||
|
ResourceOwner: "instance",
|
||||||
|
Description: "description",
|
||||||
|
Host: "host",
|
||||||
|
User: "user",
|
||||||
|
Password: "password",
|
||||||
|
Tls: true,
|
||||||
|
From: "sender",
|
||||||
|
FromName: "sendername",
|
||||||
|
ReplyToAddress: "address",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
for _, tt := range tests {
|
||||||
|
t.Run(tt.name, func(t *testing.T) {
|
||||||
|
got := addEmailProviderSMTPToConfig(tt.args.ctx, tt.args.req)
|
||||||
|
assert.Equal(t, tt.res, got)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func Test_updateEmailProviderSMTPToConfig(t *testing.T) {
|
||||||
|
type args struct {
|
||||||
|
ctx context.Context
|
||||||
|
req *admin_pb.UpdateEmailProviderSMTPRequest
|
||||||
|
}
|
||||||
|
tests := []struct {
|
||||||
|
name string
|
||||||
|
args args
|
||||||
|
res *command.ChangeSMTPConfig
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
name: "all fields filled",
|
||||||
|
args: args{
|
||||||
|
ctx: authz.WithInstanceID(context.Background(), "instance"),
|
||||||
|
req: &admin_pb.UpdateEmailProviderSMTPRequest{
|
||||||
|
SenderAddress: "sender",
|
||||||
|
SenderName: "sendername",
|
||||||
|
Tls: true,
|
||||||
|
Host: "host",
|
||||||
|
User: "user",
|
||||||
|
ReplyToAddress: "address",
|
||||||
|
Password: "password",
|
||||||
|
Description: "description",
|
||||||
|
Id: "id",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
res: &command.ChangeSMTPConfig{
|
||||||
|
ResourceOwner: "instance",
|
||||||
|
ID: "id",
|
||||||
|
Description: "description",
|
||||||
|
Host: "host",
|
||||||
|
User: "user",
|
||||||
|
Password: "password",
|
||||||
|
Tls: true,
|
||||||
|
From: "sender",
|
||||||
|
FromName: "sendername",
|
||||||
|
ReplyToAddress: "address",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
for _, tt := range tests {
|
||||||
|
t.Run(tt.name, func(t *testing.T) {
|
||||||
|
got := updateEmailProviderSMTPToConfig(tt.args.ctx, tt.args.req)
|
||||||
|
assert.Equal(t, tt.res, got)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func Test_addEmailProviderHTTPToConfig(t *testing.T) {
|
||||||
|
type args struct {
|
||||||
|
ctx context.Context
|
||||||
|
req *admin_pb.AddEmailProviderHTTPRequest
|
||||||
|
}
|
||||||
|
tests := []struct {
|
||||||
|
name string
|
||||||
|
args args
|
||||||
|
res *command.AddSMTPConfigHTTP
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
name: "all fields filled",
|
||||||
|
args: args{
|
||||||
|
ctx: authz.WithInstanceID(context.Background(), "instance"),
|
||||||
|
req: &admin_pb.AddEmailProviderHTTPRequest{
|
||||||
|
Endpoint: "endpoint",
|
||||||
|
Description: "description",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
res: &command.AddSMTPConfigHTTP{
|
||||||
|
ResourceOwner: "instance",
|
||||||
|
ID: "",
|
||||||
|
Description: "description",
|
||||||
|
Endpoint: "endpoint",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
for _, tt := range tests {
|
||||||
|
t.Run(tt.name, func(t *testing.T) {
|
||||||
|
got := addEmailProviderHTTPToConfig(tt.args.ctx, tt.args.req)
|
||||||
|
assert.Equal(t, tt.res, got)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func Test_updateEmailProviderHTTPToConfig(t *testing.T) {
|
||||||
|
type args struct {
|
||||||
|
ctx context.Context
|
||||||
|
req *admin_pb.UpdateEmailProviderHTTPRequest
|
||||||
|
}
|
||||||
|
tests := []struct {
|
||||||
|
name string
|
||||||
|
args args
|
||||||
|
res *command.ChangeSMTPConfigHTTP
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
name: "all fields filled",
|
||||||
|
args: args{
|
||||||
|
ctx: authz.WithInstanceID(context.Background(), "instance"),
|
||||||
|
req: &admin_pb.UpdateEmailProviderHTTPRequest{
|
||||||
|
Id: "id",
|
||||||
|
Endpoint: "endpoint",
|
||||||
|
Description: "description",
|
||||||
|
ExpirationSigningKey: durationpb.New(time.Second),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
res: &command.ChangeSMTPConfigHTTP{
|
||||||
|
ResourceOwner: "instance",
|
||||||
|
ID: "id",
|
||||||
|
Description: "description",
|
||||||
|
Endpoint: "endpoint",
|
||||||
|
ExpirationSigningKey: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
for _, tt := range tests {
|
||||||
|
t.Run(tt.name, func(t *testing.T) {
|
||||||
|
got := updateEmailProviderHTTPToConfig(tt.args.ctx, tt.args.req)
|
||||||
|
assert.Equal(t, tt.res, got)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -71,8 +71,9 @@ func (s *Server) AddSMSProviderHTTP(ctx context.Context, req *admin_pb.AddSMSPro
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
return &admin_pb.AddSMSProviderHTTPResponse{
|
return &admin_pb.AddSMSProviderHTTPResponse{
|
||||||
Details: object.DomainToAddDetailsPb(smsConfig.Details),
|
Details: object.DomainToAddDetailsPb(smsConfig.Details),
|
||||||
Id: smsConfig.ID,
|
Id: smsConfig.ID,
|
||||||
|
SigningKey: smsConfig.SigningKey,
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -82,7 +83,8 @@ func (s *Server) UpdateSMSProviderHTTP(ctx context.Context, req *admin_pb.Update
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
return &admin_pb.UpdateSMSProviderHTTPResponse{
|
return &admin_pb.UpdateSMSProviderHTTPResponse{
|
||||||
Details: object.DomainToChangeDetailsPb(smsConfig.Details),
|
Details: object.DomainToChangeDetailsPb(smsConfig.Details),
|
||||||
|
SigningKey: smsConfig.SigningKey,
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -56,7 +56,8 @@ func SMSConfigToPb(config *query.SMSConfig) settings_pb.SMSConfig {
|
|||||||
func HTTPConfigToPb(http *query.HTTP) *settings_pb.SMSProvider_Http {
|
func HTTPConfigToPb(http *query.HTTP) *settings_pb.SMSProvider_Http {
|
||||||
return &settings_pb.SMSProvider_Http{
|
return &settings_pb.SMSProvider_Http{
|
||||||
Http: &settings_pb.HTTPConfig{
|
Http: &settings_pb.HTTPConfig{
|
||||||
Endpoint: http.Endpoint,
|
Endpoint: http.Endpoint,
|
||||||
|
SigningKey: http.SigningKey,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -73,6 +74,8 @@ func TwilioConfigToPb(twilio *query.Twilio) *settings_pb.SMSProvider_Twilio {
|
|||||||
|
|
||||||
func smsStateToPb(state domain.SMSConfigState) settings_pb.SMSProviderConfigState {
|
func smsStateToPb(state domain.SMSConfigState) settings_pb.SMSProviderConfigState {
|
||||||
switch state {
|
switch state {
|
||||||
|
case domain.SMSConfigStateUnspecified, domain.SMSConfigStateRemoved:
|
||||||
|
return settings_pb.SMSProviderConfigState_SMS_PROVIDER_CONFIG_INACTIVE
|
||||||
case domain.SMSConfigStateInactive:
|
case domain.SMSConfigStateInactive:
|
||||||
return settings_pb.SMSProviderConfigState_SMS_PROVIDER_CONFIG_INACTIVE
|
return settings_pb.SMSProviderConfigState_SMS_PROVIDER_CONFIG_INACTIVE
|
||||||
case domain.SMSConfigStateActive:
|
case domain.SMSConfigStateActive:
|
||||||
@@ -113,10 +116,13 @@ func addSMSConfigHTTPToConfig(ctx context.Context, req *admin_pb.AddSMSProviderH
|
|||||||
}
|
}
|
||||||
|
|
||||||
func updateSMSConfigHTTPToConfig(ctx context.Context, req *admin_pb.UpdateSMSProviderHTTPRequest) *command.ChangeSMSHTTP {
|
func updateSMSConfigHTTPToConfig(ctx context.Context, req *admin_pb.UpdateSMSProviderHTTPRequest) *command.ChangeSMSHTTP {
|
||||||
|
// TODO handle expiration, currently only immediate expiration is supported
|
||||||
|
expirationSigningKey := req.GetExpirationSigningKey() != nil
|
||||||
return &command.ChangeSMSHTTP{
|
return &command.ChangeSMSHTTP{
|
||||||
ResourceOwner: authz.GetInstance(ctx).InstanceID(),
|
ResourceOwner: authz.GetInstance(ctx).InstanceID(),
|
||||||
ID: req.Id,
|
ID: req.Id,
|
||||||
Description: gu.Ptr(req.Description),
|
Description: gu.Ptr(req.Description),
|
||||||
Endpoint: gu.Ptr(req.Endpoint),
|
Endpoint: gu.Ptr(req.Endpoint),
|
||||||
|
ExpirationSigningKey: expirationSigningKey,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
520
internal/api/grpc/admin/sms_converters_test.go
Normal file
520
internal/api/grpc/admin/sms_converters_test.go
Normal file
@@ -0,0 +1,520 @@
|
|||||||
|
package admin
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"testing"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"github.com/muhlemmer/gu"
|
||||||
|
"github.com/stretchr/testify/assert"
|
||||||
|
"github.com/stretchr/testify/require"
|
||||||
|
"google.golang.org/protobuf/types/known/durationpb"
|
||||||
|
"google.golang.org/protobuf/types/known/timestamppb"
|
||||||
|
|
||||||
|
"github.com/zitadel/zitadel/internal/api/authz"
|
||||||
|
"github.com/zitadel/zitadel/internal/command"
|
||||||
|
"github.com/zitadel/zitadel/internal/domain"
|
||||||
|
"github.com/zitadel/zitadel/internal/query"
|
||||||
|
admin_pb "github.com/zitadel/zitadel/pkg/grpc/admin"
|
||||||
|
object_pb "github.com/zitadel/zitadel/pkg/grpc/object"
|
||||||
|
settings_pb "github.com/zitadel/zitadel/pkg/grpc/settings"
|
||||||
|
)
|
||||||
|
|
||||||
|
func Test_listSMSConfigsToModel(t *testing.T) {
|
||||||
|
type args struct {
|
||||||
|
req *admin_pb.ListSMSProvidersRequest
|
||||||
|
}
|
||||||
|
tests := []struct {
|
||||||
|
name string
|
||||||
|
args args
|
||||||
|
res *query.SMSConfigsSearchQueries
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
name: "all fields filled",
|
||||||
|
args: args{
|
||||||
|
req: &admin_pb.ListSMSProvidersRequest{
|
||||||
|
Query: &object_pb.ListQuery{
|
||||||
|
Offset: 100,
|
||||||
|
Limit: 100,
|
||||||
|
Asc: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
res: &query.SMSConfigsSearchQueries{
|
||||||
|
SearchRequest: query.SearchRequest{
|
||||||
|
Offset: 100,
|
||||||
|
Limit: 100,
|
||||||
|
Asc: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
for _, tt := range tests {
|
||||||
|
t.Run(tt.name, func(t *testing.T) {
|
||||||
|
got, err := listSMSConfigsToModel(tt.args.req)
|
||||||
|
require.NoError(t, err)
|
||||||
|
assert.Equal(t, tt.res, got)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func Test_SMSConfigsToPb(t *testing.T) {
|
||||||
|
type args struct {
|
||||||
|
req []*query.SMSConfig
|
||||||
|
}
|
||||||
|
tests := []struct {
|
||||||
|
name string
|
||||||
|
args args
|
||||||
|
res []*settings_pb.SMSProvider
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
name: "all fields filled",
|
||||||
|
args: args{
|
||||||
|
req: []*query.SMSConfig{
|
||||||
|
{
|
||||||
|
CreationDate: time.Date(2000, 1, 1, 0, 0, 0, 0, time.UTC),
|
||||||
|
ChangeDate: time.Date(2000, 1, 1, 0, 0, 0, 0, time.UTC),
|
||||||
|
ResourceOwner: "resourceowner",
|
||||||
|
AggregateID: "agg",
|
||||||
|
ID: "id",
|
||||||
|
Sequence: 1,
|
||||||
|
Description: "description",
|
||||||
|
TwilioConfig: &query.Twilio{
|
||||||
|
SID: "sid",
|
||||||
|
Token: nil,
|
||||||
|
SenderNumber: "sender",
|
||||||
|
VerifyServiceSID: "verify",
|
||||||
|
},
|
||||||
|
State: 1,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
CreationDate: time.Date(2000, 1, 1, 0, 0, 0, 0, time.UTC),
|
||||||
|
ChangeDate: time.Date(2000, 1, 1, 0, 0, 0, 0, time.UTC),
|
||||||
|
ResourceOwner: "resourceowner",
|
||||||
|
AggregateID: "agg",
|
||||||
|
ID: "id",
|
||||||
|
Sequence: 1,
|
||||||
|
Description: "description",
|
||||||
|
HTTPConfig: &query.HTTP{
|
||||||
|
Endpoint: "endpoint",
|
||||||
|
SigningKey: "key",
|
||||||
|
},
|
||||||
|
State: 1,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
res: []*settings_pb.SMSProvider{
|
||||||
|
{
|
||||||
|
Details: &object_pb.ObjectDetails{
|
||||||
|
Sequence: 1,
|
||||||
|
CreationDate: timestamppb.New(time.Date(2000, 1, 1, 0, 0, 0, 0, time.UTC)),
|
||||||
|
ChangeDate: timestamppb.New(time.Date(2000, 1, 1, 0, 0, 0, 0, time.UTC)),
|
||||||
|
ResourceOwner: "resourceowner",
|
||||||
|
},
|
||||||
|
Id: "id",
|
||||||
|
State: 1,
|
||||||
|
Description: "description",
|
||||||
|
Config: &settings_pb.SMSProvider_Twilio{
|
||||||
|
Twilio: &settings_pb.TwilioConfig{
|
||||||
|
Sid: "sid",
|
||||||
|
SenderNumber: "sender",
|
||||||
|
VerifyServiceSid: "verify",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Details: &object_pb.ObjectDetails{
|
||||||
|
Sequence: 1,
|
||||||
|
CreationDate: timestamppb.New(time.Date(2000, 1, 1, 0, 0, 0, 0, time.UTC)),
|
||||||
|
ChangeDate: timestamppb.New(time.Date(2000, 1, 1, 0, 0, 0, 0, time.UTC)),
|
||||||
|
ResourceOwner: "resourceowner",
|
||||||
|
},
|
||||||
|
Id: "id",
|
||||||
|
State: 1,
|
||||||
|
Description: "description",
|
||||||
|
Config: &settings_pb.SMSProvider_Http{
|
||||||
|
Http: &settings_pb.HTTPConfig{
|
||||||
|
Endpoint: "endpoint",
|
||||||
|
SigningKey: "key",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
for _, tt := range tests {
|
||||||
|
t.Run(tt.name, func(t *testing.T) {
|
||||||
|
got := SMSConfigsToPb(tt.args.req)
|
||||||
|
assert.Equal(t, tt.res, got)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func Test_SMSConfigToProviderPb(t *testing.T) {
|
||||||
|
type args struct {
|
||||||
|
req *query.SMSConfig
|
||||||
|
}
|
||||||
|
tests := []struct {
|
||||||
|
name string
|
||||||
|
args args
|
||||||
|
res *settings_pb.SMSProvider
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
name: "all fields filled, twilio",
|
||||||
|
args: args{
|
||||||
|
req: &query.SMSConfig{
|
||||||
|
|
||||||
|
CreationDate: time.Date(2000, 1, 1, 0, 0, 0, 0, time.UTC),
|
||||||
|
ChangeDate: time.Date(2000, 1, 1, 0, 0, 0, 0, time.UTC),
|
||||||
|
ResourceOwner: "resourceowner",
|
||||||
|
AggregateID: "agg",
|
||||||
|
ID: "id",
|
||||||
|
Sequence: 1,
|
||||||
|
Description: "description",
|
||||||
|
TwilioConfig: &query.Twilio{
|
||||||
|
SID: "sid",
|
||||||
|
Token: nil,
|
||||||
|
SenderNumber: "sender",
|
||||||
|
VerifyServiceSID: "verify",
|
||||||
|
},
|
||||||
|
State: 1,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
res: &settings_pb.SMSProvider{
|
||||||
|
Details: &object_pb.ObjectDetails{
|
||||||
|
Sequence: 1,
|
||||||
|
CreationDate: timestamppb.New(time.Date(2000, 1, 1, 0, 0, 0, 0, time.UTC)),
|
||||||
|
ChangeDate: timestamppb.New(time.Date(2000, 1, 1, 0, 0, 0, 0, time.UTC)),
|
||||||
|
ResourceOwner: "resourceowner",
|
||||||
|
},
|
||||||
|
Id: "id",
|
||||||
|
State: 1,
|
||||||
|
Description: "description",
|
||||||
|
Config: &settings_pb.SMSProvider_Twilio{
|
||||||
|
Twilio: &settings_pb.TwilioConfig{
|
||||||
|
Sid: "sid",
|
||||||
|
SenderNumber: "sender",
|
||||||
|
VerifyServiceSid: "verify",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "all fields filled, http",
|
||||||
|
args: args{
|
||||||
|
req: &query.SMSConfig{
|
||||||
|
CreationDate: time.Date(2000, 1, 1, 0, 0, 0, 0, time.UTC),
|
||||||
|
ChangeDate: time.Date(2000, 1, 1, 0, 0, 0, 0, time.UTC),
|
||||||
|
ResourceOwner: "resourceowner",
|
||||||
|
AggregateID: "agg",
|
||||||
|
ID: "id",
|
||||||
|
Sequence: 1,
|
||||||
|
Description: "description",
|
||||||
|
HTTPConfig: &query.HTTP{
|
||||||
|
Endpoint: "endpoint",
|
||||||
|
SigningKey: "key",
|
||||||
|
},
|
||||||
|
State: 1,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
res: &settings_pb.SMSProvider{
|
||||||
|
Details: &object_pb.ObjectDetails{
|
||||||
|
Sequence: 1,
|
||||||
|
CreationDate: timestamppb.New(time.Date(2000, 1, 1, 0, 0, 0, 0, time.UTC)),
|
||||||
|
ChangeDate: timestamppb.New(time.Date(2000, 1, 1, 0, 0, 0, 0, time.UTC)),
|
||||||
|
ResourceOwner: "resourceowner",
|
||||||
|
},
|
||||||
|
Id: "id",
|
||||||
|
State: 1,
|
||||||
|
Description: "description",
|
||||||
|
Config: &settings_pb.SMSProvider_Http{
|
||||||
|
Http: &settings_pb.HTTPConfig{
|
||||||
|
Endpoint: "endpoint",
|
||||||
|
SigningKey: "key",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
for _, tt := range tests {
|
||||||
|
t.Run(tt.name, func(t *testing.T) {
|
||||||
|
got := SMSConfigToProviderPb(tt.args.req)
|
||||||
|
assert.Equal(t, tt.res, got)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func Test_smsStateToPb(t *testing.T) {
|
||||||
|
type args struct {
|
||||||
|
req domain.SMSConfigState
|
||||||
|
}
|
||||||
|
tests := []struct {
|
||||||
|
name string
|
||||||
|
args args
|
||||||
|
res settings_pb.SMSProviderConfigState
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
name: "unspecified",
|
||||||
|
args: args{
|
||||||
|
req: domain.SMSConfigStateUnspecified,
|
||||||
|
},
|
||||||
|
res: settings_pb.SMSProviderConfigState_SMS_PROVIDER_CONFIG_INACTIVE,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "removed",
|
||||||
|
args: args{
|
||||||
|
req: domain.SMSConfigStateRemoved,
|
||||||
|
},
|
||||||
|
res: settings_pb.SMSProviderConfigState_SMS_PROVIDER_CONFIG_INACTIVE,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "active",
|
||||||
|
args: args{
|
||||||
|
req: domain.SMSConfigStateActive,
|
||||||
|
},
|
||||||
|
res: settings_pb.SMSProviderConfigState_SMS_PROVIDER_CONFIG_ACTIVE,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "inactive",
|
||||||
|
args: args{
|
||||||
|
req: domain.SMSConfigStateInactive,
|
||||||
|
},
|
||||||
|
res: settings_pb.SMSProviderConfigState_SMS_PROVIDER_CONFIG_INACTIVE,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "default",
|
||||||
|
args: args{
|
||||||
|
req: 100,
|
||||||
|
},
|
||||||
|
res: settings_pb.SMSProviderConfigState_SMS_PROVIDER_CONFIG_INACTIVE,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
for _, tt := range tests {
|
||||||
|
t.Run(tt.name, func(t *testing.T) {
|
||||||
|
got := smsStateToPb(tt.args.req)
|
||||||
|
assert.Equal(t, tt.res, got)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func Test_HTTPConfigToPb(t *testing.T) {
|
||||||
|
type args struct {
|
||||||
|
req *query.HTTP
|
||||||
|
}
|
||||||
|
tests := []struct {
|
||||||
|
name string
|
||||||
|
args args
|
||||||
|
res *settings_pb.SMSProvider_Http
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
name: "all fields filled",
|
||||||
|
args: args{
|
||||||
|
req: &query.HTTP{
|
||||||
|
Endpoint: "endpoint",
|
||||||
|
SigningKey: "key",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
res: &settings_pb.SMSProvider_Http{
|
||||||
|
Http: &settings_pb.HTTPConfig{
|
||||||
|
Endpoint: "endpoint",
|
||||||
|
SigningKey: "key",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
for _, tt := range tests {
|
||||||
|
t.Run(tt.name, func(t *testing.T) {
|
||||||
|
got := HTTPConfigToPb(tt.args.req)
|
||||||
|
assert.Equal(t, tt.res, got)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func Test_TwilioConfigToPb(t *testing.T) {
|
||||||
|
type args struct {
|
||||||
|
req *query.Twilio
|
||||||
|
}
|
||||||
|
tests := []struct {
|
||||||
|
name string
|
||||||
|
args args
|
||||||
|
res *settings_pb.SMSProvider_Twilio
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
name: "all fields filled",
|
||||||
|
args: args{
|
||||||
|
req: &query.Twilio{
|
||||||
|
SID: "sid",
|
||||||
|
SenderNumber: "sender",
|
||||||
|
VerifyServiceSID: "verify",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
res: &settings_pb.SMSProvider_Twilio{
|
||||||
|
Twilio: &settings_pb.TwilioConfig{
|
||||||
|
Sid: "sid",
|
||||||
|
SenderNumber: "sender",
|
||||||
|
VerifyServiceSid: "verify",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
for _, tt := range tests {
|
||||||
|
t.Run(tt.name, func(t *testing.T) {
|
||||||
|
got := TwilioConfigToPb(tt.args.req)
|
||||||
|
assert.Equal(t, tt.res, got)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func Test_addSMSConfigTwilioToConfig(t *testing.T) {
|
||||||
|
type args struct {
|
||||||
|
ctx context.Context
|
||||||
|
req *admin_pb.AddSMSProviderTwilioRequest
|
||||||
|
}
|
||||||
|
tests := []struct {
|
||||||
|
name string
|
||||||
|
args args
|
||||||
|
res *command.AddTwilioConfig
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
name: "all fields filled",
|
||||||
|
args: args{
|
||||||
|
ctx: authz.WithInstanceID(context.Background(), "instance"),
|
||||||
|
req: &admin_pb.AddSMSProviderTwilioRequest{
|
||||||
|
Sid: "sid",
|
||||||
|
Token: "token",
|
||||||
|
SenderNumber: "sender",
|
||||||
|
Description: "description",
|
||||||
|
VerifyServiceSid: "verify",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
res: &command.AddTwilioConfig{
|
||||||
|
ResourceOwner: "instance",
|
||||||
|
ID: "",
|
||||||
|
Description: "description",
|
||||||
|
SID: "sid",
|
||||||
|
Token: "token",
|
||||||
|
SenderNumber: "sender",
|
||||||
|
VerifyServiceSID: "verify",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
for _, tt := range tests {
|
||||||
|
t.Run(tt.name, func(t *testing.T) {
|
||||||
|
got := addSMSConfigTwilioToConfig(tt.args.ctx, tt.args.req)
|
||||||
|
assert.Equal(t, tt.res, got)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func Test_updateSMSConfigTwilioToConfig(t *testing.T) {
|
||||||
|
type args struct {
|
||||||
|
ctx context.Context
|
||||||
|
req *admin_pb.UpdateSMSProviderTwilioRequest
|
||||||
|
}
|
||||||
|
tests := []struct {
|
||||||
|
name string
|
||||||
|
args args
|
||||||
|
res *command.ChangeTwilioConfig
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
name: "all fields filled",
|
||||||
|
args: args{
|
||||||
|
ctx: authz.WithInstanceID(context.Background(), "instance"),
|
||||||
|
req: &admin_pb.UpdateSMSProviderTwilioRequest{
|
||||||
|
Id: "id",
|
||||||
|
Sid: "sid",
|
||||||
|
SenderNumber: "sender",
|
||||||
|
Description: "description",
|
||||||
|
VerifyServiceSid: "verify",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
res: &command.ChangeTwilioConfig{
|
||||||
|
ResourceOwner: "instance",
|
||||||
|
ID: "id",
|
||||||
|
Description: gu.Ptr("description"),
|
||||||
|
SID: gu.Ptr("sid"),
|
||||||
|
SenderNumber: gu.Ptr("sender"),
|
||||||
|
VerifyServiceSID: gu.Ptr("verify"),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
for _, tt := range tests {
|
||||||
|
t.Run(tt.name, func(t *testing.T) {
|
||||||
|
got := updateSMSConfigTwilioToConfig(tt.args.ctx, tt.args.req)
|
||||||
|
assert.Equal(t, tt.res, got)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func Test_addSMSConfigHTTPToConfig(t *testing.T) {
|
||||||
|
type args struct {
|
||||||
|
ctx context.Context
|
||||||
|
req *admin_pb.AddSMSProviderHTTPRequest
|
||||||
|
}
|
||||||
|
tests := []struct {
|
||||||
|
name string
|
||||||
|
args args
|
||||||
|
res *command.AddSMSHTTP
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
name: "all fields filled",
|
||||||
|
args: args{
|
||||||
|
ctx: authz.WithInstanceID(context.Background(), "instance"),
|
||||||
|
req: &admin_pb.AddSMSProviderHTTPRequest{
|
||||||
|
Endpoint: "endpoint",
|
||||||
|
Description: "description",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
res: &command.AddSMSHTTP{
|
||||||
|
ResourceOwner: "instance",
|
||||||
|
ID: "",
|
||||||
|
Description: "description",
|
||||||
|
Endpoint: "endpoint",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
for _, tt := range tests {
|
||||||
|
t.Run(tt.name, func(t *testing.T) {
|
||||||
|
got := addSMSConfigHTTPToConfig(tt.args.ctx, tt.args.req)
|
||||||
|
assert.Equal(t, tt.res, got)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func Test_updateSMSConfigHTTPToConfig(t *testing.T) {
|
||||||
|
type args struct {
|
||||||
|
ctx context.Context
|
||||||
|
req *admin_pb.UpdateSMSProviderHTTPRequest
|
||||||
|
}
|
||||||
|
tests := []struct {
|
||||||
|
name string
|
||||||
|
args args
|
||||||
|
res *command.ChangeSMSHTTP
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
name: "all fields filled",
|
||||||
|
args: args{
|
||||||
|
ctx: authz.WithInstanceID(context.Background(), "instance"),
|
||||||
|
req: &admin_pb.UpdateSMSProviderHTTPRequest{
|
||||||
|
Id: "id",
|
||||||
|
Endpoint: "endpoint",
|
||||||
|
Description: "description",
|
||||||
|
ExpirationSigningKey: durationpb.New(time.Second),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
res: &command.ChangeSMSHTTP{
|
||||||
|
ResourceOwner: "instance",
|
||||||
|
ID: "id",
|
||||||
|
Description: gu.Ptr("description"),
|
||||||
|
Endpoint: gu.Ptr("endpoint"),
|
||||||
|
ExpirationSigningKey: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
for _, tt := range tests {
|
||||||
|
t.Run(tt.name, func(t *testing.T) {
|
||||||
|
got := updateSMSConfigHTTPToConfig(tt.args.ctx, tt.args.req)
|
||||||
|
assert.Equal(t, tt.res, got)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
63
internal/api/grpc/object/converter_test.go
Normal file
63
internal/api/grpc/object/converter_test.go
Normal file
@@ -0,0 +1,63 @@
|
|||||||
|
package object
|
||||||
|
|
||||||
|
import (
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/stretchr/testify/assert"
|
||||||
|
|
||||||
|
object_pb "github.com/zitadel/zitadel/pkg/grpc/object"
|
||||||
|
)
|
||||||
|
|
||||||
|
func Test_ListQueryToModel(t *testing.T) {
|
||||||
|
type args struct {
|
||||||
|
req *object_pb.ListQuery
|
||||||
|
}
|
||||||
|
type res struct {
|
||||||
|
offset, limit uint64
|
||||||
|
asc bool
|
||||||
|
}
|
||||||
|
tests := []struct {
|
||||||
|
name string
|
||||||
|
args args
|
||||||
|
res res
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
name: "all fields filled",
|
||||||
|
args: args{
|
||||||
|
req: &object_pb.ListQuery{
|
||||||
|
Offset: 100,
|
||||||
|
Limit: 100,
|
||||||
|
Asc: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
res: res{
|
||||||
|
offset: 100,
|
||||||
|
limit: 100,
|
||||||
|
asc: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "all fields empty",
|
||||||
|
args: args{
|
||||||
|
req: &object_pb.ListQuery{
|
||||||
|
Offset: 0,
|
||||||
|
Limit: 0,
|
||||||
|
Asc: false,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
res: res{
|
||||||
|
offset: 0,
|
||||||
|
limit: 0,
|
||||||
|
asc: false,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
for _, tt := range tests {
|
||||||
|
t.Run(tt.name, func(t *testing.T) {
|
||||||
|
offset, limit, asc := ListQueryToModel(tt.args.req)
|
||||||
|
assert.Equal(t, tt.res.offset, offset)
|
||||||
|
assert.Equal(t, tt.res.limit, limit)
|
||||||
|
assert.Equal(t, tt.res.asc, asc)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -201,7 +201,12 @@ func (wm *IAMSMTPConfigWriteModel) NewChangedEvent(ctx context.Context, aggregat
|
|||||||
return changeEvent, true, nil
|
return changeEvent, true, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (wm *IAMSMTPConfigWriteModel) NewHTTPChangedEvent(ctx context.Context, aggregate *eventstore.Aggregate, id, description, endpoint string) (*instance.SMTPConfigHTTPChangedEvent, bool, error) {
|
func (wm *IAMSMTPConfigWriteModel) NewHTTPChangedEvent(
|
||||||
|
ctx context.Context,
|
||||||
|
aggregate *eventstore.Aggregate,
|
||||||
|
id, description, endpoint string,
|
||||||
|
signingKey *crypto.CryptoValue,
|
||||||
|
) (*instance.SMTPConfigHTTPChangedEvent, bool, error) {
|
||||||
changes := make([]instance.SMTPConfigHTTPChanges, 0)
|
changes := make([]instance.SMTPConfigHTTPChanges, 0)
|
||||||
var err error
|
var err error
|
||||||
if wm.HTTPConfig == nil {
|
if wm.HTTPConfig == nil {
|
||||||
@@ -217,6 +222,10 @@ func (wm *IAMSMTPConfigWriteModel) NewHTTPChangedEvent(ctx context.Context, aggr
|
|||||||
if wm.HTTPConfig.Endpoint != endpoint {
|
if wm.HTTPConfig.Endpoint != endpoint {
|
||||||
changes = append(changes, instance.ChangeSMTPConfigHTTPEndpoint(endpoint))
|
changes = append(changes, instance.ChangeSMTPConfigHTTPEndpoint(endpoint))
|
||||||
}
|
}
|
||||||
|
// if signingkey is set, update it as it is encrypted
|
||||||
|
if signingKey != nil {
|
||||||
|
changes = append(changes, instance.ChangeSMTPConfigHTTPSigningKey(signingKey))
|
||||||
|
}
|
||||||
if len(changes) == 0 {
|
if len(changes) == 0 {
|
||||||
return nil, false, nil
|
return nil, false, nil
|
||||||
}
|
}
|
||||||
@@ -251,7 +260,8 @@ func (wm *IAMSMTPConfigWriteModel) reduceSMTPConfigAddedEvent(e *instance.SMTPCo
|
|||||||
func (wm *IAMSMTPConfigWriteModel) reduceSMTPConfigHTTPAddedEvent(e *instance.SMTPConfigHTTPAddedEvent) {
|
func (wm *IAMSMTPConfigWriteModel) reduceSMTPConfigHTTPAddedEvent(e *instance.SMTPConfigHTTPAddedEvent) {
|
||||||
wm.Description = e.Description
|
wm.Description = e.Description
|
||||||
wm.HTTPConfig = &HTTPConfig{
|
wm.HTTPConfig = &HTTPConfig{
|
||||||
Endpoint: e.Endpoint,
|
Endpoint: e.Endpoint,
|
||||||
|
SigningKey: e.SigningKey,
|
||||||
}
|
}
|
||||||
wm.State = domain.SMTPConfigStateInactive
|
wm.State = domain.SMTPConfigStateInactive
|
||||||
// If ID has empty value we're dealing with the old and unique smtp settings
|
// If ID has empty value we're dealing with the old and unique smtp settings
|
||||||
@@ -313,6 +323,9 @@ func (wm *IAMSMTPConfigWriteModel) reduceSMTPConfigHTTPChangedEvent(e *instance.
|
|||||||
if e.Endpoint != nil {
|
if e.Endpoint != nil {
|
||||||
wm.HTTPConfig.Endpoint = *e.Endpoint
|
wm.HTTPConfig.Endpoint = *e.Endpoint
|
||||||
}
|
}
|
||||||
|
if e.SigningKey != nil {
|
||||||
|
wm.HTTPConfig.SigningKey = e.SigningKey
|
||||||
|
}
|
||||||
|
|
||||||
// If ID has empty value we're dealing with the old and unique smtp settings
|
// If ID has empty value we're dealing with the old and unique smtp settings
|
||||||
// These would be the default values for ID and State
|
// These would be the default values for ID and State
|
||||||
|
|||||||
@@ -157,6 +157,7 @@ type AddSMSHTTP struct {
|
|||||||
|
|
||||||
Description string
|
Description string
|
||||||
Endpoint string
|
Endpoint string
|
||||||
|
SigningKey string
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *Commands) AddSMSConfigHTTP(ctx context.Context, config *AddSMSHTTP) (err error) {
|
func (c *Commands) AddSMSConfigHTTP(ctx context.Context, config *AddSMSHTTP) (err error) {
|
||||||
@@ -174,6 +175,12 @@ func (c *Commands) AddSMSConfigHTTP(ctx context.Context, config *AddSMSHTTP) (er
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
code, err := c.newSigningKey(ctx, c.eventstore.Filter, c.smsEncryption) //nolint
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
config.SigningKey = code.PlainCode()
|
||||||
|
|
||||||
err = c.pushAppendAndReduce(ctx,
|
err = c.pushAppendAndReduce(ctx,
|
||||||
smsConfigWriteModel,
|
smsConfigWriteModel,
|
||||||
instance.NewSMSConfigHTTPAddedEvent(
|
instance.NewSMSConfigHTTPAddedEvent(
|
||||||
@@ -182,6 +189,7 @@ func (c *Commands) AddSMSConfigHTTP(ctx context.Context, config *AddSMSHTTP) (er
|
|||||||
config.ID,
|
config.ID,
|
||||||
config.Description,
|
config.Description,
|
||||||
config.Endpoint,
|
config.Endpoint,
|
||||||
|
code.Crypted,
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -196,8 +204,10 @@ type ChangeSMSHTTP struct {
|
|||||||
ResourceOwner string
|
ResourceOwner string
|
||||||
ID string
|
ID string
|
||||||
|
|
||||||
Description *string
|
Description *string
|
||||||
Endpoint *string
|
Endpoint *string
|
||||||
|
ExpirationSigningKey bool
|
||||||
|
SigningKey *string
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *Commands) ChangeSMSConfigHTTP(ctx context.Context, config *ChangeSMSHTTP) (err error) {
|
func (c *Commands) ChangeSMSConfigHTTP(ctx context.Context, config *ChangeSMSHTTP) (err error) {
|
||||||
@@ -214,12 +224,24 @@ func (c *Commands) ChangeSMSConfigHTTP(ctx context.Context, config *ChangeSMSHTT
|
|||||||
if !smsConfigWriteModel.State.Exists() || smsConfigWriteModel.HTTP == nil {
|
if !smsConfigWriteModel.State.Exists() || smsConfigWriteModel.HTTP == nil {
|
||||||
return zerrors.ThrowNotFound(nil, "COMMAND-6NW4I5Kqzj", "Errors.SMSConfig.NotFound")
|
return zerrors.ThrowNotFound(nil, "COMMAND-6NW4I5Kqzj", "Errors.SMSConfig.NotFound")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var changedSigningKey *crypto.CryptoValue
|
||||||
|
if config.ExpirationSigningKey {
|
||||||
|
code, err := c.newSigningKey(ctx, c.eventstore.Filter, c.smtpEncryption) //nolint
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
changedSigningKey = code.Crypted
|
||||||
|
config.SigningKey = &code.Plain
|
||||||
|
}
|
||||||
|
|
||||||
changedEvent, hasChanged, err := smsConfigWriteModel.NewHTTPChangedEvent(
|
changedEvent, hasChanged, err := smsConfigWriteModel.NewHTTPChangedEvent(
|
||||||
ctx,
|
ctx,
|
||||||
InstanceAggregateFromWriteModel(&smsConfigWriteModel.WriteModel),
|
InstanceAggregateFromWriteModel(&smsConfigWriteModel.WriteModel),
|
||||||
config.ID,
|
config.ID,
|
||||||
config.Description,
|
config.Description,
|
||||||
config.Endpoint)
|
config.Endpoint,
|
||||||
|
changedSigningKey)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -27,7 +27,8 @@ type TwilioConfig struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type HTTPConfig struct {
|
type HTTPConfig struct {
|
||||||
Endpoint string
|
Endpoint string
|
||||||
|
SigningKey *crypto.CryptoValue
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewIAMSMSConfigWriteModel(instanceID, id string) *IAMSMSConfigWriteModel {
|
func NewIAMSMSConfigWriteModel(instanceID, id string) *IAMSMSConfigWriteModel {
|
||||||
@@ -82,7 +83,8 @@ func (wm *IAMSMSConfigWriteModel) Reduce() error {
|
|||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
wm.HTTP = &HTTPConfig{
|
wm.HTTP = &HTTPConfig{
|
||||||
Endpoint: e.Endpoint,
|
Endpoint: e.Endpoint,
|
||||||
|
SigningKey: e.SigningKey,
|
||||||
}
|
}
|
||||||
wm.Description = e.Description
|
wm.Description = e.Description
|
||||||
wm.State = domain.SMSConfigStateInactive
|
wm.State = domain.SMSConfigStateInactive
|
||||||
@@ -96,6 +98,9 @@ func (wm *IAMSMSConfigWriteModel) Reduce() error {
|
|||||||
if e.Endpoint != nil {
|
if e.Endpoint != nil {
|
||||||
wm.HTTP.Endpoint = *e.Endpoint
|
wm.HTTP.Endpoint = *e.Endpoint
|
||||||
}
|
}
|
||||||
|
if e.SigningKey != nil {
|
||||||
|
wm.HTTP.SigningKey = e.SigningKey
|
||||||
|
}
|
||||||
case *instance.SMSConfigTwilioActivatedEvent:
|
case *instance.SMSConfigTwilioActivatedEvent:
|
||||||
if wm.ID != e.ID {
|
if wm.ID != e.ID {
|
||||||
wm.State = domain.SMSConfigStateInactive
|
wm.State = domain.SMSConfigStateInactive
|
||||||
@@ -189,7 +194,13 @@ func (wm *IAMSMSConfigWriteModel) NewTwilioChangedEvent(ctx context.Context, agg
|
|||||||
return changeEvent, true, nil
|
return changeEvent, true, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (wm *IAMSMSConfigWriteModel) NewHTTPChangedEvent(ctx context.Context, aggregate *eventstore.Aggregate, id string, description, endpoint *string) (*instance.SMSConfigHTTPChangedEvent, bool, error) {
|
func (wm *IAMSMSConfigWriteModel) NewHTTPChangedEvent(
|
||||||
|
ctx context.Context,
|
||||||
|
aggregate *eventstore.Aggregate,
|
||||||
|
id string,
|
||||||
|
description, endpoint *string,
|
||||||
|
signingKey *crypto.CryptoValue,
|
||||||
|
) (*instance.SMSConfigHTTPChangedEvent, bool, error) {
|
||||||
changes := make([]instance.SMSConfigHTTPChanges, 0)
|
changes := make([]instance.SMSConfigHTTPChanges, 0)
|
||||||
var err error
|
var err error
|
||||||
|
|
||||||
@@ -203,6 +214,10 @@ func (wm *IAMSMSConfigWriteModel) NewHTTPChangedEvent(ctx context.Context, aggre
|
|||||||
if endpoint != nil && wm.HTTP.Endpoint != *endpoint {
|
if endpoint != nil && wm.HTTP.Endpoint != *endpoint {
|
||||||
changes = append(changes, instance.ChangeSMSConfigHTTPEndpoint(*endpoint))
|
changes = append(changes, instance.ChangeSMSConfigHTTPEndpoint(*endpoint))
|
||||||
}
|
}
|
||||||
|
// if signingkey is set, update it as it is encrypted
|
||||||
|
if signingKey != nil {
|
||||||
|
changes = append(changes, instance.ChangeSMSConfigHTTPSigningKey(signingKey))
|
||||||
|
}
|
||||||
|
|
||||||
if len(changes) == 0 {
|
if len(changes) == 0 {
|
||||||
return nil, false, nil
|
return nil, false, nil
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ import (
|
|||||||
"context"
|
"context"
|
||||||
"errors"
|
"errors"
|
||||||
"testing"
|
"testing"
|
||||||
|
"time"
|
||||||
|
|
||||||
"github.com/muhlemmer/gu"
|
"github.com/muhlemmer/gu"
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
@@ -306,9 +307,11 @@ func TestCommandSide_ChangeSMSConfigTwilio(t *testing.T) {
|
|||||||
|
|
||||||
func TestCommandSide_AddSMSConfigHTTP(t *testing.T) {
|
func TestCommandSide_AddSMSConfigHTTP(t *testing.T) {
|
||||||
type fields struct {
|
type fields struct {
|
||||||
eventstore func(t *testing.T) *eventstore.Eventstore
|
eventstore func(t *testing.T) *eventstore.Eventstore
|
||||||
idGenerator id.Generator
|
idGenerator id.Generator
|
||||||
alg crypto.EncryptionAlgorithm
|
newEncryptedCodeWithDefault encryptedCodeWithDefaultFunc
|
||||||
|
defaultSecretGenerators *SecretGenerators
|
||||||
|
alg crypto.EncryptionAlgorithm
|
||||||
}
|
}
|
||||||
type args struct {
|
type args struct {
|
||||||
ctx context.Context
|
ctx context.Context
|
||||||
@@ -351,10 +354,18 @@ func TestCommandSide_AddSMSConfigHTTP(t *testing.T) {
|
|||||||
"providerid",
|
"providerid",
|
||||||
"description",
|
"description",
|
||||||
"endpoint",
|
"endpoint",
|
||||||
|
&crypto.CryptoValue{
|
||||||
|
CryptoType: crypto.TypeEncryption,
|
||||||
|
Algorithm: "enc",
|
||||||
|
KeyID: "id",
|
||||||
|
Crypted: []byte("12345678"),
|
||||||
|
},
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
idGenerator: id_mock.NewIDGeneratorExpectIDs(t, "providerid"),
|
idGenerator: id_mock.NewIDGeneratorExpectIDs(t, "providerid"),
|
||||||
|
newEncryptedCodeWithDefault: mockEncryptedCodeWithDefault("12345678", time.Hour),
|
||||||
|
defaultSecretGenerators: &SecretGenerators{},
|
||||||
},
|
},
|
||||||
args: args{
|
args: args{
|
||||||
ctx: context.Background(),
|
ctx: context.Background(),
|
||||||
@@ -374,9 +385,11 @@ func TestCommandSide_AddSMSConfigHTTP(t *testing.T) {
|
|||||||
for _, tt := range tests {
|
for _, tt := range tests {
|
||||||
t.Run(tt.name, func(t *testing.T) {
|
t.Run(tt.name, func(t *testing.T) {
|
||||||
r := &Commands{
|
r := &Commands{
|
||||||
eventstore: tt.fields.eventstore(t),
|
eventstore: tt.fields.eventstore(t),
|
||||||
idGenerator: tt.fields.idGenerator,
|
idGenerator: tt.fields.idGenerator,
|
||||||
smsEncryption: tt.fields.alg,
|
newEncryptedCodeWithDefault: tt.fields.newEncryptedCodeWithDefault,
|
||||||
|
defaultSecretGenerators: tt.fields.defaultSecretGenerators,
|
||||||
|
smsEncryption: tt.fields.alg,
|
||||||
}
|
}
|
||||||
err := r.AddSMSConfigHTTP(tt.args.ctx, tt.args.http)
|
err := r.AddSMSConfigHTTP(tt.args.ctx, tt.args.http)
|
||||||
if tt.res.err == nil {
|
if tt.res.err == nil {
|
||||||
@@ -394,7 +407,9 @@ func TestCommandSide_AddSMSConfigHTTP(t *testing.T) {
|
|||||||
|
|
||||||
func TestCommandSide_ChangeSMSConfigHTTP(t *testing.T) {
|
func TestCommandSide_ChangeSMSConfigHTTP(t *testing.T) {
|
||||||
type fields struct {
|
type fields struct {
|
||||||
eventstore func(*testing.T) *eventstore.Eventstore
|
eventstore func(*testing.T) *eventstore.Eventstore
|
||||||
|
newEncryptedCodeWithDefault encryptedCodeWithDefaultFunc
|
||||||
|
defaultSecretGenerators *SecretGenerators
|
||||||
}
|
}
|
||||||
type args struct {
|
type args struct {
|
||||||
ctx context.Context
|
ctx context.Context
|
||||||
@@ -474,6 +489,12 @@ func TestCommandSide_ChangeSMSConfigHTTP(t *testing.T) {
|
|||||||
"providerid",
|
"providerid",
|
||||||
"description",
|
"description",
|
||||||
"endpoint",
|
"endpoint",
|
||||||
|
&crypto.CryptoValue{
|
||||||
|
CryptoType: crypto.TypeEncryption,
|
||||||
|
Algorithm: "enc",
|
||||||
|
KeyID: "id",
|
||||||
|
Crypted: []byte("12345678"),
|
||||||
|
},
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
@@ -505,6 +526,12 @@ func TestCommandSide_ChangeSMSConfigHTTP(t *testing.T) {
|
|||||||
"providerid",
|
"providerid",
|
||||||
"description",
|
"description",
|
||||||
"endpoint",
|
"endpoint",
|
||||||
|
&crypto.CryptoValue{
|
||||||
|
CryptoType: crypto.TypeEncryption,
|
||||||
|
Algorithm: "enc",
|
||||||
|
KeyID: "id",
|
||||||
|
Crypted: []byte("12345678"),
|
||||||
|
},
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
@@ -514,17 +541,26 @@ func TestCommandSide_ChangeSMSConfigHTTP(t *testing.T) {
|
|||||||
"providerid",
|
"providerid",
|
||||||
"endpoint2",
|
"endpoint2",
|
||||||
"description2",
|
"description2",
|
||||||
|
&crypto.CryptoValue{
|
||||||
|
CryptoType: crypto.TypeEncryption,
|
||||||
|
Algorithm: "enc",
|
||||||
|
KeyID: "id",
|
||||||
|
Crypted: []byte("87654321"),
|
||||||
|
},
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
newEncryptedCodeWithDefault: mockEncryptedCodeWithDefault("87654321", time.Hour),
|
||||||
|
defaultSecretGenerators: &SecretGenerators{},
|
||||||
},
|
},
|
||||||
args: args{
|
args: args{
|
||||||
ctx: context.Background(),
|
ctx: context.Background(),
|
||||||
http: &ChangeSMSHTTP{
|
http: &ChangeSMSHTTP{
|
||||||
ResourceOwner: "INSTANCE",
|
ResourceOwner: "INSTANCE",
|
||||||
ID: "providerid",
|
ID: "providerid",
|
||||||
Description: gu.Ptr("description2"),
|
Description: gu.Ptr("description2"),
|
||||||
Endpoint: gu.Ptr("endpoint2"),
|
Endpoint: gu.Ptr("endpoint2"),
|
||||||
|
ExpirationSigningKey: true,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
res: res{
|
res: res{
|
||||||
@@ -537,7 +573,9 @@ func TestCommandSide_ChangeSMSConfigHTTP(t *testing.T) {
|
|||||||
for _, tt := range tests {
|
for _, tt := range tests {
|
||||||
t.Run(tt.name, func(t *testing.T) {
|
t.Run(tt.name, func(t *testing.T) {
|
||||||
r := &Commands{
|
r := &Commands{
|
||||||
eventstore: tt.fields.eventstore(t),
|
eventstore: tt.fields.eventstore(t),
|
||||||
|
newEncryptedCodeWithDefault: tt.fields.newEncryptedCodeWithDefault,
|
||||||
|
defaultSecretGenerators: tt.fields.defaultSecretGenerators,
|
||||||
}
|
}
|
||||||
err := r.ChangeSMSConfigHTTP(tt.args.ctx, tt.args.http)
|
err := r.ChangeSMSConfigHTTP(tt.args.ctx, tt.args.http)
|
||||||
if tt.res.err == nil {
|
if tt.res.err == nil {
|
||||||
@@ -707,6 +745,12 @@ func TestCommandSide_ActivateSMSConfig(t *testing.T) {
|
|||||||
"providerid",
|
"providerid",
|
||||||
"description",
|
"description",
|
||||||
"endpoint",
|
"endpoint",
|
||||||
|
&crypto.CryptoValue{
|
||||||
|
CryptoType: crypto.TypeEncryption,
|
||||||
|
Algorithm: "enc",
|
||||||
|
KeyID: "id",
|
||||||
|
Crypted: []byte("12345678"),
|
||||||
|
},
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
@@ -917,6 +961,12 @@ func TestCommandSide_DeactivateSMSConfig(t *testing.T) {
|
|||||||
"providerid",
|
"providerid",
|
||||||
"description",
|
"description",
|
||||||
"endpoint",
|
"endpoint",
|
||||||
|
&crypto.CryptoValue{
|
||||||
|
CryptoType: crypto.TypeEncryption,
|
||||||
|
Algorithm: "enc",
|
||||||
|
KeyID: "id",
|
||||||
|
Crypted: []byte("12345678"),
|
||||||
|
},
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
eventFromEventPusher(
|
eventFromEventPusher(
|
||||||
@@ -1083,6 +1133,12 @@ func TestCommandSide_RemoveSMSConfig(t *testing.T) {
|
|||||||
"providerid",
|
"providerid",
|
||||||
"description",
|
"description",
|
||||||
"endpoint",
|
"endpoint",
|
||||||
|
&crypto.CryptoValue{
|
||||||
|
CryptoType: crypto.TypeEncryption,
|
||||||
|
Algorithm: "enc",
|
||||||
|
KeyID: "id",
|
||||||
|
Crypted: []byte("12345678"),
|
||||||
|
},
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
@@ -1141,10 +1197,11 @@ func newSMSConfigTwilioChangedEvent(ctx context.Context, id, sid, senderName, de
|
|||||||
return event
|
return event
|
||||||
}
|
}
|
||||||
|
|
||||||
func newSMSConfigHTTPChangedEvent(ctx context.Context, id, endpoint, description string) *instance.SMSConfigHTTPChangedEvent {
|
func newSMSConfigHTTPChangedEvent(ctx context.Context, id, endpoint, description string, signingKey *crypto.CryptoValue) *instance.SMSConfigHTTPChangedEvent {
|
||||||
changes := []instance.SMSConfigHTTPChanges{
|
changes := []instance.SMSConfigHTTPChanges{
|
||||||
instance.ChangeSMSConfigHTTPEndpoint(endpoint),
|
instance.ChangeSMSConfigHTTPEndpoint(endpoint),
|
||||||
instance.ChangeSMSConfigHTTPDescription(description),
|
instance.ChangeSMSConfigHTTPDescription(description),
|
||||||
|
instance.ChangeSMSConfigHTTPSigningKey(signingKey),
|
||||||
}
|
}
|
||||||
event, _ := instance.NewSMSConfigHTTPChangedEvent(ctx,
|
event, _ := instance.NewSMSConfigHTTPChangedEvent(ctx,
|
||||||
&instance.NewAggregate("INSTANCE").Aggregate,
|
&instance.NewAggregate("INSTANCE").Aggregate,
|
||||||
|
|||||||
@@ -230,6 +230,7 @@ type AddSMTPConfigHTTP struct {
|
|||||||
|
|
||||||
Description string
|
Description string
|
||||||
Endpoint string
|
Endpoint string
|
||||||
|
SigningKey string
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *Commands) AddSMTPConfigHTTP(ctx context.Context, config *AddSMTPConfigHTTP) (err error) {
|
func (c *Commands) AddSMTPConfigHTTP(ctx context.Context, config *AddSMTPConfigHTTP) (err error) {
|
||||||
@@ -248,12 +249,19 @@ func (c *Commands) AddSMTPConfigHTTP(ctx context.Context, config *AddSMTPConfigH
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
code, err := c.newSigningKey(ctx, c.eventstore.Filter, c.smtpEncryption) //nolint
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
config.SigningKey = code.PlainCode()
|
||||||
|
|
||||||
err = c.pushAppendAndReduce(ctx, smtpConfigWriteModel, instance.NewSMTPConfigHTTPAddedEvent(
|
err = c.pushAppendAndReduce(ctx, smtpConfigWriteModel, instance.NewSMTPConfigHTTPAddedEvent(
|
||||||
ctx,
|
ctx,
|
||||||
InstanceAggregateFromWriteModel(&smtpConfigWriteModel.WriteModel),
|
InstanceAggregateFromWriteModel(&smtpConfigWriteModel.WriteModel),
|
||||||
config.ID,
|
config.ID,
|
||||||
config.Description,
|
config.Description,
|
||||||
config.Endpoint,
|
config.Endpoint,
|
||||||
|
code.Crypted,
|
||||||
))
|
))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
@@ -267,8 +275,10 @@ type ChangeSMTPConfigHTTP struct {
|
|||||||
ResourceOwner string
|
ResourceOwner string
|
||||||
ID string
|
ID string
|
||||||
|
|
||||||
Description string
|
Description string
|
||||||
Endpoint string
|
Endpoint string
|
||||||
|
ExpirationSigningKey bool
|
||||||
|
SigningKey *string
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *Commands) ChangeSMTPConfigHTTP(ctx context.Context, config *ChangeSMTPConfigHTTP) (err error) {
|
func (c *Commands) ChangeSMTPConfigHTTP(ctx context.Context, config *ChangeSMTPConfigHTTP) (err error) {
|
||||||
@@ -288,12 +298,23 @@ func (c *Commands) ChangeSMTPConfigHTTP(ctx context.Context, config *ChangeSMTPC
|
|||||||
return zerrors.ThrowNotFound(nil, "COMMAND-xIrdledqv4", "Errors.SMTPConfig.NotFound")
|
return zerrors.ThrowNotFound(nil, "COMMAND-xIrdledqv4", "Errors.SMTPConfig.NotFound")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var changedSigningKey *crypto.CryptoValue
|
||||||
|
if config.ExpirationSigningKey {
|
||||||
|
code, err := c.newSigningKey(ctx, c.eventstore.Filter, c.smtpEncryption) //nolint
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
changedSigningKey = code.Crypted
|
||||||
|
config.SigningKey = &code.Plain
|
||||||
|
}
|
||||||
|
|
||||||
changedEvent, hasChanged, err := smtpConfigWriteModel.NewHTTPChangedEvent(
|
changedEvent, hasChanged, err := smtpConfigWriteModel.NewHTTPChangedEvent(
|
||||||
ctx,
|
ctx,
|
||||||
InstanceAggregateFromWriteModel(&smtpConfigWriteModel.WriteModel),
|
InstanceAggregateFromWriteModel(&smtpConfigWriteModel.WriteModel),
|
||||||
config.ID,
|
config.ID,
|
||||||
config.Description,
|
config.Description,
|
||||||
config.Endpoint,
|
config.Endpoint,
|
||||||
|
changedSigningKey,
|
||||||
)
|
)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ import (
|
|||||||
"context"
|
"context"
|
||||||
"errors"
|
"errors"
|
||||||
"testing"
|
"testing"
|
||||||
|
"time"
|
||||||
|
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
"go.uber.org/mock/gomock"
|
"go.uber.org/mock/gomock"
|
||||||
@@ -902,8 +903,10 @@ func TestCommandSide_ChangeSMTPConfigPassword(t *testing.T) {
|
|||||||
|
|
||||||
func TestCommandSide_AddSMTPConfigHTTP(t *testing.T) {
|
func TestCommandSide_AddSMTPConfigHTTP(t *testing.T) {
|
||||||
type fields struct {
|
type fields struct {
|
||||||
eventstore func(t *testing.T) *eventstore.Eventstore
|
eventstore func(t *testing.T) *eventstore.Eventstore
|
||||||
idGenerator id.Generator
|
newEncryptedCodeWithDefault encryptedCodeWithDefaultFunc
|
||||||
|
defaultSecretGenerators *SecretGenerators
|
||||||
|
idGenerator id.Generator
|
||||||
}
|
}
|
||||||
type args struct {
|
type args struct {
|
||||||
http *AddSMTPConfigHTTP
|
http *AddSMTPConfigHTTP
|
||||||
@@ -944,10 +947,18 @@ func TestCommandSide_AddSMTPConfigHTTP(t *testing.T) {
|
|||||||
"configid",
|
"configid",
|
||||||
"test",
|
"test",
|
||||||
"endpoint",
|
"endpoint",
|
||||||
|
&crypto.CryptoValue{
|
||||||
|
CryptoType: crypto.TypeEncryption,
|
||||||
|
Algorithm: "enc",
|
||||||
|
KeyID: "id",
|
||||||
|
Crypted: []byte("12345678"),
|
||||||
|
},
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
idGenerator: id_mock.NewIDGeneratorExpectIDs(t, "configid"),
|
idGenerator: id_mock.NewIDGeneratorExpectIDs(t, "configid"),
|
||||||
|
newEncryptedCodeWithDefault: mockEncryptedCodeWithDefault("12345678", time.Hour),
|
||||||
|
defaultSecretGenerators: &SecretGenerators{},
|
||||||
},
|
},
|
||||||
args: args{
|
args: args{
|
||||||
http: &AddSMTPConfigHTTP{
|
http: &AddSMTPConfigHTTP{
|
||||||
@@ -966,8 +977,10 @@ func TestCommandSide_AddSMTPConfigHTTP(t *testing.T) {
|
|||||||
for _, tt := range tests {
|
for _, tt := range tests {
|
||||||
t.Run(tt.name, func(t *testing.T) {
|
t.Run(tt.name, func(t *testing.T) {
|
||||||
r := &Commands{
|
r := &Commands{
|
||||||
eventstore: tt.fields.eventstore(t),
|
eventstore: tt.fields.eventstore(t),
|
||||||
idGenerator: tt.fields.idGenerator,
|
idGenerator: tt.fields.idGenerator,
|
||||||
|
newEncryptedCodeWithDefault: tt.fields.newEncryptedCodeWithDefault,
|
||||||
|
defaultSecretGenerators: tt.fields.defaultSecretGenerators,
|
||||||
}
|
}
|
||||||
err := r.AddSMTPConfigHTTP(context.Background(), tt.args.http)
|
err := r.AddSMTPConfigHTTP(context.Background(), tt.args.http)
|
||||||
if tt.res.err == nil {
|
if tt.res.err == nil {
|
||||||
@@ -986,7 +999,9 @@ func TestCommandSide_AddSMTPConfigHTTP(t *testing.T) {
|
|||||||
|
|
||||||
func TestCommandSide_ChangeSMTPConfigHTTP(t *testing.T) {
|
func TestCommandSide_ChangeSMTPConfigHTTP(t *testing.T) {
|
||||||
type fields struct {
|
type fields struct {
|
||||||
eventstore func(t *testing.T) *eventstore.Eventstore
|
eventstore func(t *testing.T) *eventstore.Eventstore
|
||||||
|
newEncryptedCodeWithDefault encryptedCodeWithDefaultFunc
|
||||||
|
defaultSecretGenerators *SecretGenerators
|
||||||
}
|
}
|
||||||
type args struct {
|
type args struct {
|
||||||
http *ChangeSMTPConfigHTTP
|
http *ChangeSMTPConfigHTTP
|
||||||
@@ -1063,6 +1078,12 @@ func TestCommandSide_ChangeSMTPConfigHTTP(t *testing.T) {
|
|||||||
"ID",
|
"ID",
|
||||||
"test",
|
"test",
|
||||||
"endpoint",
|
"endpoint",
|
||||||
|
&crypto.CryptoValue{
|
||||||
|
CryptoType: crypto.TypeEncryption,
|
||||||
|
Algorithm: "enc",
|
||||||
|
KeyID: "id",
|
||||||
|
Crypted: []byte("12345678"),
|
||||||
|
},
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
@@ -1094,6 +1115,12 @@ func TestCommandSide_ChangeSMTPConfigHTTP(t *testing.T) {
|
|||||||
"ID",
|
"ID",
|
||||||
"",
|
"",
|
||||||
"endpoint",
|
"endpoint",
|
||||||
|
&crypto.CryptoValue{
|
||||||
|
CryptoType: crypto.TypeEncryption,
|
||||||
|
Algorithm: "enc",
|
||||||
|
KeyID: "id",
|
||||||
|
Crypted: []byte("12345678"),
|
||||||
|
},
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
@@ -1103,16 +1130,25 @@ func TestCommandSide_ChangeSMTPConfigHTTP(t *testing.T) {
|
|||||||
"ID",
|
"ID",
|
||||||
"test",
|
"test",
|
||||||
"endpoint2",
|
"endpoint2",
|
||||||
|
&crypto.CryptoValue{
|
||||||
|
CryptoType: crypto.TypeEncryption,
|
||||||
|
Algorithm: "enc",
|
||||||
|
KeyID: "id",
|
||||||
|
Crypted: []byte("87654321"),
|
||||||
|
},
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
newEncryptedCodeWithDefault: mockEncryptedCodeWithDefault("87654321", time.Hour),
|
||||||
|
defaultSecretGenerators: &SecretGenerators{},
|
||||||
},
|
},
|
||||||
args: args{
|
args: args{
|
||||||
http: &ChangeSMTPConfigHTTP{
|
http: &ChangeSMTPConfigHTTP{
|
||||||
ResourceOwner: "INSTANCE",
|
ResourceOwner: "INSTANCE",
|
||||||
ID: "ID",
|
ID: "ID",
|
||||||
Description: "test",
|
Description: "test",
|
||||||
Endpoint: "endpoint2",
|
Endpoint: "endpoint2",
|
||||||
|
ExpirationSigningKey: true,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
res: res{
|
res: res{
|
||||||
@@ -1125,7 +1161,9 @@ func TestCommandSide_ChangeSMTPConfigHTTP(t *testing.T) {
|
|||||||
for _, tt := range tests {
|
for _, tt := range tests {
|
||||||
t.Run(tt.name, func(t *testing.T) {
|
t.Run(tt.name, func(t *testing.T) {
|
||||||
r := &Commands{
|
r := &Commands{
|
||||||
eventstore: tt.fields.eventstore(t),
|
eventstore: tt.fields.eventstore(t),
|
||||||
|
newEncryptedCodeWithDefault: tt.fields.newEncryptedCodeWithDefault,
|
||||||
|
defaultSecretGenerators: tt.fields.defaultSecretGenerators,
|
||||||
}
|
}
|
||||||
err := r.ChangeSMTPConfigHTTP(context.Background(), tt.args.http)
|
err := r.ChangeSMTPConfigHTTP(context.Background(), tt.args.http)
|
||||||
if tt.res.err == nil {
|
if tt.res.err == nil {
|
||||||
@@ -1300,6 +1338,12 @@ func TestCommandSide_ActivateSMTPConfig(t *testing.T) {
|
|||||||
"ID",
|
"ID",
|
||||||
"test",
|
"test",
|
||||||
"endpoint",
|
"endpoint",
|
||||||
|
&crypto.CryptoValue{
|
||||||
|
CryptoType: crypto.TypeEncryption,
|
||||||
|
Algorithm: "enc",
|
||||||
|
KeyID: "id",
|
||||||
|
Crypted: []byte("12345678"),
|
||||||
|
},
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
@@ -1511,6 +1555,12 @@ func TestCommandSide_DeactivateSMTPConfig(t *testing.T) {
|
|||||||
"ID",
|
"ID",
|
||||||
"test",
|
"test",
|
||||||
"endpoint",
|
"endpoint",
|
||||||
|
&crypto.CryptoValue{
|
||||||
|
CryptoType: crypto.TypeEncryption,
|
||||||
|
Algorithm: "enc",
|
||||||
|
KeyID: "id",
|
||||||
|
Crypted: []byte("12345678"),
|
||||||
|
},
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
eventFromEventPusher(
|
eventFromEventPusher(
|
||||||
@@ -1677,6 +1727,12 @@ func TestCommandSide_RemoveSMTPConfig(t *testing.T) {
|
|||||||
"ID",
|
"ID",
|
||||||
"test",
|
"test",
|
||||||
"endpoint",
|
"endpoint",
|
||||||
|
&crypto.CryptoValue{
|
||||||
|
CryptoType: crypto.TypeEncryption,
|
||||||
|
Algorithm: "enc",
|
||||||
|
KeyID: "id",
|
||||||
|
Crypted: []byte("12345678"),
|
||||||
|
},
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
@@ -2051,10 +2107,11 @@ func newSMTPConfigChangedEvent(ctx context.Context, id, description string, tls
|
|||||||
return event
|
return event
|
||||||
}
|
}
|
||||||
|
|
||||||
func newSMTPConfigHTTPChangedEvent(ctx context.Context, id, description, endpoint string) *instance.SMTPConfigHTTPChangedEvent {
|
func newSMTPConfigHTTPChangedEvent(ctx context.Context, id, description, endpoint string, signingKey *crypto.CryptoValue) *instance.SMTPConfigHTTPChangedEvent {
|
||||||
changes := []instance.SMTPConfigHTTPChanges{
|
changes := []instance.SMTPConfigHTTPChanges{
|
||||||
instance.ChangeSMTPConfigHTTPDescription(description),
|
instance.ChangeSMTPConfigHTTPDescription(description),
|
||||||
instance.ChangeSMTPConfigHTTPEndpoint(endpoint),
|
instance.ChangeSMTPConfigHTTPEndpoint(endpoint),
|
||||||
|
instance.ChangeSMTPConfigHTTPSigningKey(signingKey),
|
||||||
}
|
}
|
||||||
event, _ := instance.NewSMTPConfigHTTPChangeEvent(ctx,
|
event, _ := instance.NewSMTPConfigHTTPChangeEvent(ctx,
|
||||||
&instance.NewAggregate("INSTANCE").Aggregate,
|
&instance.NewAggregate("INSTANCE").Aggregate,
|
||||||
|
|||||||
@@ -12,6 +12,11 @@ import (
|
|||||||
"github.com/zitadel/zitadel/internal/notification/channels"
|
"github.com/zitadel/zitadel/internal/notification/channels"
|
||||||
"github.com/zitadel/zitadel/internal/notification/messages"
|
"github.com/zitadel/zitadel/internal/notification/messages"
|
||||||
"github.com/zitadel/zitadel/internal/zerrors"
|
"github.com/zitadel/zitadel/internal/zerrors"
|
||||||
|
"github.com/zitadel/zitadel/pkg/actions"
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
SigningHeader = "ZITADEL-Signature"
|
||||||
)
|
)
|
||||||
|
|
||||||
func InitChannel(ctx context.Context, cfg Config) (channels.NotificationChannel, error) {
|
func InitChannel(ctx context.Context, cfg Config) (channels.NotificationChannel, error) {
|
||||||
@@ -39,6 +44,10 @@ func InitChannel(ctx context.Context, cfg Config) (channels.NotificationChannel,
|
|||||||
req.Header = cfg.Headers
|
req.Header = cfg.Headers
|
||||||
}
|
}
|
||||||
req.Header.Set("Content-Type", "application/json")
|
req.Header.Set("Content-Type", "application/json")
|
||||||
|
if cfg.SigningKey != "" {
|
||||||
|
req.Header.Set(SigningHeader, actions.ComputeSignatureHeader(time.Now(), []byte(payload), cfg.SigningKey))
|
||||||
|
}
|
||||||
|
|
||||||
resp, err := http.DefaultClient.Do(req)
|
resp, err := http.DefaultClient.Do(req)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
|
|||||||
@@ -6,9 +6,10 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
type Config struct {
|
type Config struct {
|
||||||
CallURL string
|
CallURL string
|
||||||
Method string
|
Method string
|
||||||
Headers http.Header
|
Headers http.Header
|
||||||
|
SigningKey string
|
||||||
}
|
}
|
||||||
|
|
||||||
func (w *Config) Validate() error {
|
func (w *Config) Validate() error {
|
||||||
|
|||||||
@@ -49,9 +49,10 @@ func (n *NotificationQueries) GetActiveEmailConfig(ctx context.Context) (*email.
|
|||||||
return &email.Config{
|
return &email.Config{
|
||||||
ProviderConfig: provider,
|
ProviderConfig: provider,
|
||||||
WebhookConfig: &webhook.Config{
|
WebhookConfig: &webhook.Config{
|
||||||
CallURL: config.HTTPConfig.Endpoint,
|
CallURL: config.HTTPConfig.Endpoint,
|
||||||
Method: http.MethodPost,
|
Method: http.MethodPost,
|
||||||
Headers: nil,
|
Headers: nil,
|
||||||
|
SigningKey: config.HTTPConfig.SigningKey,
|
||||||
},
|
},
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -45,9 +45,10 @@ func (n *NotificationQueries) GetActiveSMSConfig(ctx context.Context) (*sms.Conf
|
|||||||
return &sms.Config{
|
return &sms.Config{
|
||||||
ProviderConfig: provider,
|
ProviderConfig: provider,
|
||||||
WebhookConfig: &webhook.Config{
|
WebhookConfig: &webhook.Config{
|
||||||
CallURL: config.HTTPConfig.Endpoint,
|
CallURL: config.HTTPConfig.Endpoint,
|
||||||
Method: http.MethodPost,
|
Method: http.MethodPost,
|
||||||
Headers: nil,
|
Headers: nil,
|
||||||
|
SigningKey: config.HTTPConfig.SigningKey,
|
||||||
},
|
},
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -37,6 +37,7 @@ const (
|
|||||||
SMSHTTPColumnSMSID = "sms_id"
|
SMSHTTPColumnSMSID = "sms_id"
|
||||||
SMSHTTPColumnInstanceID = "instance_id"
|
SMSHTTPColumnInstanceID = "instance_id"
|
||||||
SMSHTTPColumnEndpoint = "endpoint"
|
SMSHTTPColumnEndpoint = "endpoint"
|
||||||
|
SMSHTTPColumnSigningKey = "signing_key"
|
||||||
)
|
)
|
||||||
|
|
||||||
type smsConfigProjection struct{}
|
type smsConfigProjection struct{}
|
||||||
@@ -80,6 +81,7 @@ func (*smsConfigProjection) Init() *old_handler.Check {
|
|||||||
handler.NewColumn(SMSHTTPColumnSMSID, handler.ColumnTypeText),
|
handler.NewColumn(SMSHTTPColumnSMSID, handler.ColumnTypeText),
|
||||||
handler.NewColumn(SMSHTTPColumnInstanceID, handler.ColumnTypeText),
|
handler.NewColumn(SMSHTTPColumnInstanceID, handler.ColumnTypeText),
|
||||||
handler.NewColumn(SMSHTTPColumnEndpoint, handler.ColumnTypeText),
|
handler.NewColumn(SMSHTTPColumnEndpoint, handler.ColumnTypeText),
|
||||||
|
handler.NewColumn(SMSHTTPColumnSigningKey, handler.ColumnTypeJSONB, handler.Nullable()),
|
||||||
},
|
},
|
||||||
handler.NewPrimaryKey(SMSHTTPColumnInstanceID, SMSHTTPColumnSMSID),
|
handler.NewPrimaryKey(SMSHTTPColumnInstanceID, SMSHTTPColumnSMSID),
|
||||||
smsHTTPTableSuffix,
|
smsHTTPTableSuffix,
|
||||||
@@ -286,6 +288,7 @@ func (p *smsConfigProjection) reduceSMSConfigHTTPAdded(event eventstore.Event) (
|
|||||||
handler.NewCol(SMSHTTPColumnSMSID, e.ID),
|
handler.NewCol(SMSHTTPColumnSMSID, e.ID),
|
||||||
handler.NewCol(SMSHTTPColumnInstanceID, e.Aggregate().InstanceID),
|
handler.NewCol(SMSHTTPColumnInstanceID, e.Aggregate().InstanceID),
|
||||||
handler.NewCol(SMSHTTPColumnEndpoint, e.Endpoint),
|
handler.NewCol(SMSHTTPColumnEndpoint, e.Endpoint),
|
||||||
|
handler.NewCol(SMSHTTPColumnSigningKey, e.SigningKey),
|
||||||
},
|
},
|
||||||
handler.WithTableSuffix(smsHTTPTableSuffix),
|
handler.WithTableSuffix(smsHTTPTableSuffix),
|
||||||
),
|
),
|
||||||
@@ -306,21 +309,24 @@ func (p *smsConfigProjection) reduceSMSConfigHTTPChanged(event eventstore.Event)
|
|||||||
if e.Description != nil {
|
if e.Description != nil {
|
||||||
columns = append(columns, handler.NewCol(SMSColumnDescription, *e.Description))
|
columns = append(columns, handler.NewCol(SMSColumnDescription, *e.Description))
|
||||||
}
|
}
|
||||||
if len(columns) > 0 {
|
stmts = append(stmts, handler.AddUpdateStatement(
|
||||||
stmts = append(stmts, handler.AddUpdateStatement(
|
columns,
|
||||||
columns,
|
[]handler.Condition{
|
||||||
[]handler.Condition{
|
handler.NewCond(SMSColumnID, e.ID),
|
||||||
handler.NewCond(SMSColumnID, e.ID),
|
handler.NewCond(SMSColumnInstanceID, e.Aggregate().InstanceID),
|
||||||
handler.NewCond(SMSColumnInstanceID, e.Aggregate().InstanceID),
|
},
|
||||||
},
|
))
|
||||||
))
|
|
||||||
}
|
|
||||||
|
|
||||||
|
httpColumns := make([]handler.Column, 0)
|
||||||
|
if e.SigningKey != nil {
|
||||||
|
httpColumns = append(httpColumns, handler.NewCol(SMSHTTPColumnSigningKey, e.SigningKey))
|
||||||
|
}
|
||||||
if e.Endpoint != nil {
|
if e.Endpoint != nil {
|
||||||
|
httpColumns = append(httpColumns, handler.NewCol(SMSHTTPColumnEndpoint, *e.Endpoint))
|
||||||
|
}
|
||||||
|
if len(httpColumns) > 0 {
|
||||||
stmts = append(stmts, handler.AddUpdateStatement(
|
stmts = append(stmts, handler.AddUpdateStatement(
|
||||||
[]handler.Column{
|
httpColumns,
|
||||||
handler.NewCol(SMSHTTPColumnEndpoint, *e.Endpoint),
|
|
||||||
},
|
|
||||||
[]handler.Condition{
|
[]handler.Condition{
|
||||||
handler.NewCond(SMSHTTPColumnSMSID, e.ID),
|
handler.NewCond(SMSHTTPColumnSMSID, e.ID),
|
||||||
handler.NewCond(SMSHTTPColumnInstanceID, e.Aggregate().InstanceID),
|
handler.NewCond(SMSHTTPColumnInstanceID, e.Aggregate().InstanceID),
|
||||||
|
|||||||
@@ -302,7 +302,8 @@ func TestSMSProjection_reduces(t *testing.T) {
|
|||||||
[]byte(`{
|
[]byte(`{
|
||||||
"id": "id",
|
"id": "id",
|
||||||
"description": "description",
|
"description": "description",
|
||||||
"endpoint": "endpoint"
|
"endpoint": "endpoint",
|
||||||
|
"signingKey": { "cryptoType": 0, "algorithm": "RSA-265", "keyId": "key-id" }
|
||||||
}`),
|
}`),
|
||||||
), eventstore.GenericEventMapper[instance.SMSConfigHTTPAddedEvent]),
|
), eventstore.GenericEventMapper[instance.SMSConfigHTTPAddedEvent]),
|
||||||
},
|
},
|
||||||
@@ -327,11 +328,12 @@ func TestSMSProjection_reduces(t *testing.T) {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
expectedStmt: "INSERT INTO projections.sms_configs3_http (sms_id, instance_id, endpoint) VALUES ($1, $2, $3)",
|
expectedStmt: "INSERT INTO projections.sms_configs3_http (sms_id, instance_id, endpoint, signing_key) VALUES ($1, $2, $3, $4)",
|
||||||
expectedArgs: []interface{}{
|
expectedArgs: []interface{}{
|
||||||
"id",
|
"id",
|
||||||
"instance-id",
|
"instance-id",
|
||||||
"endpoint",
|
"endpoint",
|
||||||
|
anyArg{},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@@ -348,7 +350,8 @@ func TestSMSProjection_reduces(t *testing.T) {
|
|||||||
[]byte(`{
|
[]byte(`{
|
||||||
"id": "id",
|
"id": "id",
|
||||||
"endpoint": "endpoint",
|
"endpoint": "endpoint",
|
||||||
"description": "description"
|
"description": "description",
|
||||||
|
"signingKey": { "cryptoType": 0, "algorithm": "RSA-265", "keyId": "key-id" }
|
||||||
}`),
|
}`),
|
||||||
), eventstore.GenericEventMapper[instance.SMSConfigHTTPChangedEvent]),
|
), eventstore.GenericEventMapper[instance.SMSConfigHTTPChangedEvent]),
|
||||||
},
|
},
|
||||||
@@ -369,8 +372,9 @@ func TestSMSProjection_reduces(t *testing.T) {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
expectedStmt: "UPDATE projections.sms_configs3_http SET endpoint = $1 WHERE (sms_id = $2) AND (instance_id = $3)",
|
expectedStmt: "UPDATE projections.sms_configs3_http SET (signing_key, endpoint) = ($1, $2) WHERE (sms_id = $3) AND (instance_id = $4)",
|
||||||
expectedArgs: []interface{}{
|
expectedArgs: []interface{}{
|
||||||
|
anyArg{},
|
||||||
"endpoint",
|
"endpoint",
|
||||||
"id",
|
"id",
|
||||||
"instance-id",
|
"instance-id",
|
||||||
@@ -452,6 +456,46 @@ func TestSMSProjection_reduces(t *testing.T) {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
name: "instance reduceSMSConfigHTTPChanged, only signing key",
|
||||||
|
args: args{
|
||||||
|
event: getEvent(
|
||||||
|
testEvent(
|
||||||
|
instance.SMSConfigHTTPChangedEventType,
|
||||||
|
instance.AggregateType,
|
||||||
|
[]byte(`{
|
||||||
|
"id": "id",
|
||||||
|
"signingKey": { "cryptoType": 0, "algorithm": "RSA-265", "keyId": "key-id" }
|
||||||
|
}`),
|
||||||
|
), 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 signing_key = $1 WHERE (sms_id = $2) AND (instance_id = $3)",
|
||||||
|
expectedArgs: []interface{}{
|
||||||
|
anyArg{},
|
||||||
|
"id",
|
||||||
|
"instance-id",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
{
|
{
|
||||||
name: "instance reduceSMSConfigTwilioActivated",
|
name: "instance reduceSMSConfigTwilioActivated",
|
||||||
args: args{
|
args: args{
|
||||||
|
|||||||
@@ -40,6 +40,7 @@ const (
|
|||||||
SMTPConfigHTTPColumnInstanceID = "instance_id"
|
SMTPConfigHTTPColumnInstanceID = "instance_id"
|
||||||
SMTPConfigHTTPColumnID = "id"
|
SMTPConfigHTTPColumnID = "id"
|
||||||
SMTPConfigHTTPColumnEndpoint = "endpoint"
|
SMTPConfigHTTPColumnEndpoint = "endpoint"
|
||||||
|
SMTPConfigHTTPColumnSigningKey = "signing_key"
|
||||||
)
|
)
|
||||||
|
|
||||||
type smtpConfigProjection struct{}
|
type smtpConfigProjection struct{}
|
||||||
@@ -86,6 +87,7 @@ func (*smtpConfigProjection) Init() *old_handler.Check {
|
|||||||
handler.NewColumn(SMTPConfigHTTPColumnID, handler.ColumnTypeText),
|
handler.NewColumn(SMTPConfigHTTPColumnID, handler.ColumnTypeText),
|
||||||
handler.NewColumn(SMTPConfigHTTPColumnInstanceID, handler.ColumnTypeText),
|
handler.NewColumn(SMTPConfigHTTPColumnInstanceID, handler.ColumnTypeText),
|
||||||
handler.NewColumn(SMTPConfigHTTPColumnEndpoint, handler.ColumnTypeText),
|
handler.NewColumn(SMTPConfigHTTPColumnEndpoint, handler.ColumnTypeText),
|
||||||
|
handler.NewColumn(SMTPConfigHTTPColumnSigningKey, handler.ColumnTypeJSONB, handler.Nullable()),
|
||||||
},
|
},
|
||||||
handler.NewPrimaryKey(SMTPConfigHTTPColumnInstanceID, SMTPConfigHTTPColumnID),
|
handler.NewPrimaryKey(SMTPConfigHTTPColumnInstanceID, SMTPConfigHTTPColumnID),
|
||||||
smtpConfigHTTPTableSuffix,
|
smtpConfigHTTPTableSuffix,
|
||||||
@@ -211,6 +213,7 @@ func (p *smtpConfigProjection) reduceSMTPConfigHTTPAdded(event eventstore.Event)
|
|||||||
handler.NewCol(SMTPConfigHTTPColumnInstanceID, e.Aggregate().InstanceID),
|
handler.NewCol(SMTPConfigHTTPColumnInstanceID, e.Aggregate().InstanceID),
|
||||||
handler.NewCol(SMTPConfigHTTPColumnID, getSMTPConfigID(e.ID, e.Aggregate())),
|
handler.NewCol(SMTPConfigHTTPColumnID, getSMTPConfigID(e.ID, e.Aggregate())),
|
||||||
handler.NewCol(SMTPConfigHTTPColumnEndpoint, e.Endpoint),
|
handler.NewCol(SMTPConfigHTTPColumnEndpoint, e.Endpoint),
|
||||||
|
handler.NewCol(SMTPConfigHTTPColumnSigningKey, e.SigningKey),
|
||||||
},
|
},
|
||||||
handler.WithTableSuffix(smtpConfigHTTPTableSuffix),
|
handler.WithTableSuffix(smtpConfigHTTPTableSuffix),
|
||||||
),
|
),
|
||||||
@@ -231,20 +234,21 @@ func (p *smtpConfigProjection) reduceSMTPConfigHTTPChanged(event eventstore.Even
|
|||||||
if e.Description != nil {
|
if e.Description != nil {
|
||||||
columns = append(columns, handler.NewCol(SMTPConfigColumnDescription, *e.Description))
|
columns = append(columns, handler.NewCol(SMTPConfigColumnDescription, *e.Description))
|
||||||
}
|
}
|
||||||
if len(columns) > 0 {
|
stmts = append(stmts, handler.AddUpdateStatement(
|
||||||
stmts = append(stmts, handler.AddUpdateStatement(
|
columns,
|
||||||
columns,
|
[]handler.Condition{
|
||||||
[]handler.Condition{
|
handler.NewCond(SMTPConfigColumnID, getSMTPConfigID(e.ID, e.Aggregate())),
|
||||||
handler.NewCond(SMTPConfigColumnID, getSMTPConfigID(e.ID, e.Aggregate())),
|
handler.NewCond(SMTPConfigColumnInstanceID, e.Aggregate().InstanceID),
|
||||||
handler.NewCond(SMTPConfigColumnInstanceID, e.Aggregate().InstanceID),
|
},
|
||||||
},
|
))
|
||||||
))
|
|
||||||
}
|
|
||||||
|
|
||||||
smtpColumns := make([]handler.Column, 0, 1)
|
smtpColumns := make([]handler.Column, 0, 1)
|
||||||
if e.Endpoint != nil {
|
if e.Endpoint != nil {
|
||||||
smtpColumns = append(smtpColumns, handler.NewCol(SMTPConfigHTTPColumnEndpoint, *e.Endpoint))
|
smtpColumns = append(smtpColumns, handler.NewCol(SMTPConfigHTTPColumnEndpoint, *e.Endpoint))
|
||||||
}
|
}
|
||||||
|
if e.SigningKey != nil {
|
||||||
|
smtpColumns = append(smtpColumns, handler.NewCol(SMTPConfigHTTPColumnSigningKey, e.SigningKey))
|
||||||
|
}
|
||||||
if len(smtpColumns) > 0 {
|
if len(smtpColumns) > 0 {
|
||||||
stmts = append(stmts, handler.AddUpdateStatement(
|
stmts = append(stmts, handler.AddUpdateStatement(
|
||||||
smtpColumns,
|
smtpColumns,
|
||||||
|
|||||||
@@ -225,7 +225,8 @@ func TestSMTPConfigProjection_reduces(t *testing.T) {
|
|||||||
"aggregate_id": "agg-id",
|
"aggregate_id": "agg-id",
|
||||||
"id": "config-id",
|
"id": "config-id",
|
||||||
"description": "test",
|
"description": "test",
|
||||||
"endpoint": "endpoint"
|
"endpoint": "endpoint",
|
||||||
|
"signingKey": { "cryptoType": 0, "algorithm": "RSA-265", "keyId": "key-id" }
|
||||||
}`,
|
}`,
|
||||||
),
|
),
|
||||||
), eventstore.GenericEventMapper[instance.SMTPConfigHTTPChangedEvent]),
|
), eventstore.GenericEventMapper[instance.SMTPConfigHTTPChangedEvent]),
|
||||||
@@ -247,9 +248,10 @@ func TestSMTPConfigProjection_reduces(t *testing.T) {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
expectedStmt: "UPDATE projections.smtp_configs5_http SET endpoint = $1 WHERE (id = $2) AND (instance_id = $3)",
|
expectedStmt: "UPDATE projections.smtp_configs5_http SET (endpoint, signing_key) = ($1, $2) WHERE (id = $3) AND (instance_id = $4)",
|
||||||
expectedArgs: []interface{}{
|
expectedArgs: []interface{}{
|
||||||
"endpoint",
|
"endpoint",
|
||||||
|
anyArg{},
|
||||||
"config-id",
|
"config-id",
|
||||||
"instance-id",
|
"instance-id",
|
||||||
},
|
},
|
||||||
@@ -338,6 +340,49 @@ func TestSMTPConfigProjection_reduces(t *testing.T) {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
}, {
|
||||||
|
name: "reduceSMTPConfigHTTPChanged, signing key",
|
||||||
|
args: args{
|
||||||
|
event: getEvent(
|
||||||
|
testEvent(
|
||||||
|
instance.SMTPConfigHTTPChangedEventType,
|
||||||
|
instance.AggregateType,
|
||||||
|
[]byte(`{
|
||||||
|
"instance_id": "instance-id",
|
||||||
|
"resource_owner": "ro-id",
|
||||||
|
"aggregate_id": "agg-id",
|
||||||
|
"id": "config-id",
|
||||||
|
"signingKey": { "cryptoType": 0, "algorithm": "RSA-265", "keyId": "key-id" }
|
||||||
|
}`,
|
||||||
|
),
|
||||||
|
), eventstore.GenericEventMapper[instance.SMTPConfigHTTPChangedEvent]),
|
||||||
|
},
|
||||||
|
reduce: (&smtpConfigProjection{}).reduceSMTPConfigHTTPChanged,
|
||||||
|
want: wantReduce{
|
||||||
|
aggregateType: eventstore.AggregateType("instance"),
|
||||||
|
sequence: 15,
|
||||||
|
executer: &testExecuter{
|
||||||
|
executions: []execution{
|
||||||
|
{
|
||||||
|
expectedStmt: "UPDATE projections.smtp_configs5 SET (change_date, sequence) = ($1, $2) WHERE (id = $3) AND (instance_id = $4)",
|
||||||
|
expectedArgs: []interface{}{
|
||||||
|
anyArg{},
|
||||||
|
uint64(15),
|
||||||
|
"config-id",
|
||||||
|
"instance-id",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
expectedStmt: "UPDATE projections.smtp_configs5_http SET signing_key = $1 WHERE (id = $2) AND (instance_id = $3)",
|
||||||
|
expectedArgs: []interface{}{
|
||||||
|
anyArg{},
|
||||||
|
"config-id",
|
||||||
|
"instance-id",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "reduceSMTPConfigAdded (no id)",
|
name: "reduceSMTPConfigAdded (no id)",
|
||||||
@@ -481,7 +526,8 @@ func TestSMTPConfigProjection_reduces(t *testing.T) {
|
|||||||
"id": "config-id",
|
"id": "config-id",
|
||||||
"description": "test",
|
"description": "test",
|
||||||
"senderAddress": "sender",
|
"senderAddress": "sender",
|
||||||
"endpoint": "endpoint"
|
"endpoint": "endpoint",
|
||||||
|
"signingKey": { "cryptoType": 0, "algorithm": "RSA-265", "keyId": "key-id" }
|
||||||
}`),
|
}`),
|
||||||
), eventstore.GenericEventMapper[instance.SMTPConfigHTTPAddedEvent]),
|
), eventstore.GenericEventMapper[instance.SMTPConfigHTTPAddedEvent]),
|
||||||
},
|
},
|
||||||
@@ -506,11 +552,12 @@ func TestSMTPConfigProjection_reduces(t *testing.T) {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
expectedStmt: "INSERT INTO projections.smtp_configs5_http (instance_id, id, endpoint) VALUES ($1, $2, $3)",
|
expectedStmt: "INSERT INTO projections.smtp_configs5_http (instance_id, id, endpoint, signing_key) VALUES ($1, $2, $3, $4)",
|
||||||
expectedArgs: []interface{}{
|
expectedArgs: []interface{}{
|
||||||
"instance-id",
|
"instance-id",
|
||||||
"config-id",
|
"config-id",
|
||||||
"endpoint",
|
"endpoint",
|
||||||
|
anyArg{},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -32,6 +32,8 @@ type Queries struct {
|
|||||||
keyEncryptionAlgorithm crypto.EncryptionAlgorithm
|
keyEncryptionAlgorithm crypto.EncryptionAlgorithm
|
||||||
idpConfigEncryption crypto.EncryptionAlgorithm
|
idpConfigEncryption crypto.EncryptionAlgorithm
|
||||||
targetEncryptionAlgorithm crypto.EncryptionAlgorithm
|
targetEncryptionAlgorithm crypto.EncryptionAlgorithm
|
||||||
|
smtpEncryptionAlgorithm crypto.EncryptionAlgorithm
|
||||||
|
smsEncryptionAlgorithm crypto.EncryptionAlgorithm
|
||||||
sessionTokenVerifier func(ctx context.Context, sessionToken string, sessionID string, tokenID string) (err error)
|
sessionTokenVerifier func(ctx context.Context, sessionToken string, sessionID string, tokenID string) (err error)
|
||||||
checkPermission domain.PermissionCheck
|
checkPermission domain.PermissionCheck
|
||||||
|
|
||||||
@@ -53,7 +55,7 @@ func StartQueries(
|
|||||||
cacheConnectors connector.Connectors,
|
cacheConnectors connector.Connectors,
|
||||||
projections projection.Config,
|
projections projection.Config,
|
||||||
defaults sd.SystemDefaults,
|
defaults sd.SystemDefaults,
|
||||||
idpConfigEncryption, otpEncryption, keyEncryptionAlgorithm, certEncryptionAlgorithm, targetEncryptionAlgorithm crypto.EncryptionAlgorithm,
|
idpConfigEncryption, otpEncryption, keyEncryptionAlgorithm, certEncryptionAlgorithm, targetEncryptionAlgorithm, smsEncryptionAlgorithm, smtpEncryptionAlgorithm crypto.EncryptionAlgorithm,
|
||||||
zitadelRoles []authz.RoleMapping,
|
zitadelRoles []authz.RoleMapping,
|
||||||
sessionTokenVerifier func(ctx context.Context, sessionToken string, sessionID string, tokenID string) (err error),
|
sessionTokenVerifier func(ctx context.Context, sessionToken string, sessionID string, tokenID string) (err error),
|
||||||
permissionCheck func(q *Queries) domain.PermissionCheck,
|
permissionCheck func(q *Queries) domain.PermissionCheck,
|
||||||
@@ -72,6 +74,8 @@ func StartQueries(
|
|||||||
keyEncryptionAlgorithm: keyEncryptionAlgorithm,
|
keyEncryptionAlgorithm: keyEncryptionAlgorithm,
|
||||||
idpConfigEncryption: idpConfigEncryption,
|
idpConfigEncryption: idpConfigEncryption,
|
||||||
targetEncryptionAlgorithm: targetEncryptionAlgorithm,
|
targetEncryptionAlgorithm: targetEncryptionAlgorithm,
|
||||||
|
smsEncryptionAlgorithm: smsEncryptionAlgorithm,
|
||||||
|
smtpEncryptionAlgorithm: smtpEncryptionAlgorithm,
|
||||||
sessionTokenVerifier: sessionTokenVerifier,
|
sessionTokenVerifier: sessionTokenVerifier,
|
||||||
multifactors: domain.MultifactorConfigs{
|
multifactors: domain.MultifactorConfigs{
|
||||||
OTP: domain.OTPConfig{
|
OTP: domain.OTPConfig{
|
||||||
|
|||||||
@@ -35,6 +35,13 @@ type SMSConfig struct {
|
|||||||
HTTPConfig *HTTP
|
HTTPConfig *HTTP
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (h *SMSConfig) decryptSigningKey(alg crypto.EncryptionAlgorithm) error {
|
||||||
|
if h.HTTPConfig == nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
return h.HTTPConfig.decryptSigningKey(alg)
|
||||||
|
}
|
||||||
|
|
||||||
type Twilio struct {
|
type Twilio struct {
|
||||||
SID string
|
SID string
|
||||||
Token *crypto.CryptoValue
|
Token *crypto.CryptoValue
|
||||||
@@ -43,7 +50,21 @@ type Twilio struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type HTTP struct {
|
type HTTP struct {
|
||||||
Endpoint string
|
Endpoint string
|
||||||
|
signingKey *crypto.CryptoValue
|
||||||
|
SigningKey string
|
||||||
|
}
|
||||||
|
|
||||||
|
func (h *HTTP) decryptSigningKey(alg crypto.EncryptionAlgorithm) error {
|
||||||
|
if h.signingKey == nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
keyValue, err := crypto.DecryptString(h.signingKey, alg)
|
||||||
|
if err != nil {
|
||||||
|
return zerrors.ThrowInternal(err, "QUERY-bxovy3YXwy", "Errors.Internal")
|
||||||
|
}
|
||||||
|
h.SigningKey = keyValue
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
type SMSConfigsSearchQueries struct {
|
type SMSConfigsSearchQueries struct {
|
||||||
@@ -142,6 +163,10 @@ var (
|
|||||||
name: projection.SMSHTTPColumnEndpoint,
|
name: projection.SMSHTTPColumnEndpoint,
|
||||||
table: smsHTTPTable,
|
table: smsHTTPTable,
|
||||||
}
|
}
|
||||||
|
SMSHTTPColumnSigningKey = Column{
|
||||||
|
name: projection.SMSHTTPColumnSigningKey,
|
||||||
|
table: smsHTTPTable,
|
||||||
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
func (q *Queries) SMSProviderConfigByID(ctx context.Context, id string) (config *SMSConfig, err error) {
|
func (q *Queries) SMSProviderConfigByID(ctx context.Context, id string) (config *SMSConfig, err error) {
|
||||||
@@ -163,7 +188,13 @@ func (q *Queries) SMSProviderConfigByID(ctx context.Context, id string) (config
|
|||||||
config, err = scan(row)
|
config, err = scan(row)
|
||||||
return err
|
return err
|
||||||
}, stmt, args...)
|
}, stmt, args...)
|
||||||
return config, err
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if err := config.decryptSigningKey(q.smsEncryptionAlgorithm); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return config, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (q *Queries) SMSProviderConfigActive(ctx context.Context, instanceID string) (config *SMSConfig, err error) {
|
func (q *Queries) SMSProviderConfigActive(ctx context.Context, instanceID string) (config *SMSConfig, err error) {
|
||||||
@@ -185,7 +216,13 @@ func (q *Queries) SMSProviderConfigActive(ctx context.Context, instanceID string
|
|||||||
config, err = scan(row)
|
config, err = scan(row)
|
||||||
return err
|
return err
|
||||||
}, stmt, args...)
|
}, stmt, args...)
|
||||||
return config, err
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if err := config.decryptSigningKey(q.smsEncryptionAlgorithm); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return config, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (q *Queries) SearchSMSConfigs(ctx context.Context, queries *SMSConfigsSearchQueries) (configs *SMSConfigs, err error) {
|
func (q *Queries) SearchSMSConfigs(ctx context.Context, queries *SMSConfigsSearchQueries) (configs *SMSConfigs, err error) {
|
||||||
@@ -208,8 +245,13 @@ func (q *Queries) SearchSMSConfigs(ctx context.Context, queries *SMSConfigsSearc
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, zerrors.ThrowInternal(err, "QUERY-l4bxm", "Errors.Internal")
|
return nil, zerrors.ThrowInternal(err, "QUERY-l4bxm", "Errors.Internal")
|
||||||
}
|
}
|
||||||
|
for i := range configs.Configs {
|
||||||
|
if err := configs.Configs[i].decryptSigningKey(q.smsEncryptionAlgorithm); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
}
|
||||||
configs.State, err = q.latestState(ctx, smsConfigsTable)
|
configs.State, err = q.latestState(ctx, smsConfigsTable)
|
||||||
return configs, err
|
return configs, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewSMSProviderStateQuery(state domain.SMSConfigState) (SearchQuery, error) {
|
func NewSMSProviderStateQuery(state domain.SMSConfigState) (SearchQuery, error) {
|
||||||
@@ -235,6 +277,7 @@ func prepareSMSConfigQuery() (sq.SelectBuilder, func(*sql.Row) (*SMSConfig, erro
|
|||||||
|
|
||||||
SMSHTTPColumnSMSID.identifier(),
|
SMSHTTPColumnSMSID.identifier(),
|
||||||
SMSHTTPColumnEndpoint.identifier(),
|
SMSHTTPColumnEndpoint.identifier(),
|
||||||
|
SMSHTTPColumnSigningKey.identifier(),
|
||||||
).From(smsConfigsTable.identifier()).
|
).From(smsConfigsTable.identifier()).
|
||||||
LeftJoin(join(SMSTwilioColumnSMSID, SMSColumnID)).
|
LeftJoin(join(SMSTwilioColumnSMSID, SMSColumnID)).
|
||||||
LeftJoin(join(SMSHTTPColumnSMSID, SMSColumnID)).
|
LeftJoin(join(SMSHTTPColumnSMSID, SMSColumnID)).
|
||||||
@@ -264,6 +307,7 @@ func prepareSMSConfigQuery() (sq.SelectBuilder, func(*sql.Row) (*SMSConfig, erro
|
|||||||
|
|
||||||
&httpConfig.id,
|
&httpConfig.id,
|
||||||
&httpConfig.endpoint,
|
&httpConfig.endpoint,
|
||||||
|
&httpConfig.signingKey,
|
||||||
)
|
)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -299,6 +343,7 @@ func prepareSMSConfigsQuery() (sq.SelectBuilder, func(*sql.Rows) (*SMSConfigs, e
|
|||||||
|
|
||||||
SMSHTTPColumnSMSID.identifier(),
|
SMSHTTPColumnSMSID.identifier(),
|
||||||
SMSHTTPColumnEndpoint.identifier(),
|
SMSHTTPColumnEndpoint.identifier(),
|
||||||
|
SMSHTTPColumnSigningKey.identifier(),
|
||||||
|
|
||||||
countColumn.identifier(),
|
countColumn.identifier(),
|
||||||
).From(smsConfigsTable.identifier()).
|
).From(smsConfigsTable.identifier()).
|
||||||
@@ -332,6 +377,7 @@ func prepareSMSConfigsQuery() (sq.SelectBuilder, func(*sql.Rows) (*SMSConfigs, e
|
|||||||
|
|
||||||
&httpConfig.id,
|
&httpConfig.id,
|
||||||
&httpConfig.endpoint,
|
&httpConfig.endpoint,
|
||||||
|
&httpConfig.signingKey,
|
||||||
|
|
||||||
&configs.Count,
|
&configs.Count,
|
||||||
)
|
)
|
||||||
@@ -371,8 +417,9 @@ func (c sqlTwilioConfig) set(smsConfig *SMSConfig) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type sqlHTTPConfig struct {
|
type sqlHTTPConfig struct {
|
||||||
id sql.NullString
|
id sql.NullString
|
||||||
endpoint sql.NullString
|
endpoint sql.NullString
|
||||||
|
signingKey *crypto.CryptoValue
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c sqlHTTPConfig) setSMS(smsConfig *SMSConfig) {
|
func (c sqlHTTPConfig) setSMS(smsConfig *SMSConfig) {
|
||||||
@@ -380,6 +427,7 @@ func (c sqlHTTPConfig) setSMS(smsConfig *SMSConfig) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
smsConfig.HTTPConfig = &HTTP{
|
smsConfig.HTTPConfig = &HTTP{
|
||||||
Endpoint: c.endpoint.String,
|
Endpoint: c.endpoint.String,
|
||||||
|
signingKey: c.signingKey,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -32,7 +32,8 @@ var (
|
|||||||
|
|
||||||
// http config
|
// http config
|
||||||
` projections.sms_configs3_http.sms_id,` +
|
` projections.sms_configs3_http.sms_id,` +
|
||||||
` projections.sms_configs3_http.endpoint` +
|
` projections.sms_configs3_http.endpoint,` +
|
||||||
|
` projections.sms_configs3_http.signing_key` +
|
||||||
` FROM projections.sms_configs3` +
|
` 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_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`)
|
` 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`)
|
||||||
@@ -55,6 +56,7 @@ var (
|
|||||||
// http config
|
// http config
|
||||||
` projections.sms_configs3_http.sms_id,` +
|
` projections.sms_configs3_http.sms_id,` +
|
||||||
` projections.sms_configs3_http.endpoint,` +
|
` projections.sms_configs3_http.endpoint,` +
|
||||||
|
` projections.sms_configs3_http.signing_key,` +
|
||||||
` COUNT(*) OVER ()` +
|
` COUNT(*) OVER ()` +
|
||||||
` FROM projections.sms_configs3` +
|
` 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_twilio ON projections.sms_configs3.id = projections.sms_configs3_twilio.sms_id AND projections.sms_configs3.instance_id = projections.sms_configs3_twilio.instance_id` +
|
||||||
@@ -78,6 +80,7 @@ var (
|
|||||||
// http config
|
// http config
|
||||||
"sms_id",
|
"sms_id",
|
||||||
"endpoint",
|
"endpoint",
|
||||||
|
"signing_key",
|
||||||
}
|
}
|
||||||
smsConfigsCols = append(smsConfigCols, "count")
|
smsConfigsCols = append(smsConfigCols, "count")
|
||||||
)
|
)
|
||||||
@@ -131,6 +134,7 @@ func Test_SMSConfigsPrepare(t *testing.T) {
|
|||||||
// http config
|
// http config
|
||||||
nil,
|
nil,
|
||||||
nil,
|
nil,
|
||||||
|
nil,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
@@ -185,6 +189,12 @@ func Test_SMSConfigsPrepare(t *testing.T) {
|
|||||||
// http config
|
// http config
|
||||||
"sms-id",
|
"sms-id",
|
||||||
"endpoint",
|
"endpoint",
|
||||||
|
&crypto.CryptoValue{
|
||||||
|
CryptoType: crypto.TypeEncryption,
|
||||||
|
Algorithm: "alg",
|
||||||
|
KeyID: "encKey",
|
||||||
|
Crypted: []byte("crypted"),
|
||||||
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
@@ -205,6 +215,12 @@ func Test_SMSConfigsPrepare(t *testing.T) {
|
|||||||
Description: "description",
|
Description: "description",
|
||||||
HTTPConfig: &HTTP{
|
HTTPConfig: &HTTP{
|
||||||
Endpoint: "endpoint",
|
Endpoint: "endpoint",
|
||||||
|
signingKey: &crypto.CryptoValue{
|
||||||
|
CryptoType: crypto.TypeEncryption,
|
||||||
|
Algorithm: "alg",
|
||||||
|
KeyID: "encKey",
|
||||||
|
Crypted: []byte("crypted"),
|
||||||
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@@ -236,6 +252,7 @@ func Test_SMSConfigsPrepare(t *testing.T) {
|
|||||||
// http config
|
// http config
|
||||||
nil,
|
nil,
|
||||||
nil,
|
nil,
|
||||||
|
nil,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"sms-id2",
|
"sms-id2",
|
||||||
@@ -255,6 +272,7 @@ func Test_SMSConfigsPrepare(t *testing.T) {
|
|||||||
// http config
|
// http config
|
||||||
nil,
|
nil,
|
||||||
nil,
|
nil,
|
||||||
|
nil,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"sms-id3",
|
"sms-id3",
|
||||||
@@ -274,6 +292,12 @@ func Test_SMSConfigsPrepare(t *testing.T) {
|
|||||||
// http config
|
// http config
|
||||||
"sms-id3",
|
"sms-id3",
|
||||||
"endpoint3",
|
"endpoint3",
|
||||||
|
&crypto.CryptoValue{
|
||||||
|
CryptoType: crypto.TypeEncryption,
|
||||||
|
Algorithm: "alg",
|
||||||
|
KeyID: "encKey",
|
||||||
|
Crypted: []byte("crypted"),
|
||||||
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
@@ -326,6 +350,12 @@ func Test_SMSConfigsPrepare(t *testing.T) {
|
|||||||
Description: "description",
|
Description: "description",
|
||||||
HTTPConfig: &HTTP{
|
HTTPConfig: &HTTP{
|
||||||
Endpoint: "endpoint3",
|
Endpoint: "endpoint3",
|
||||||
|
signingKey: &crypto.CryptoValue{
|
||||||
|
CryptoType: crypto.TypeEncryption,
|
||||||
|
Algorithm: "alg",
|
||||||
|
KeyID: "encKey",
|
||||||
|
Crypted: []byte("crypted"),
|
||||||
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@@ -410,6 +440,7 @@ func Test_SMSConfigPrepare(t *testing.T) {
|
|||||||
// http config
|
// http config
|
||||||
nil,
|
nil,
|
||||||
nil,
|
nil,
|
||||||
|
nil,
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
},
|
},
|
||||||
@@ -455,6 +486,12 @@ func Test_SMSConfigPrepare(t *testing.T) {
|
|||||||
// http config
|
// http config
|
||||||
"sms-id",
|
"sms-id",
|
||||||
"endpoint",
|
"endpoint",
|
||||||
|
&crypto.CryptoValue{
|
||||||
|
CryptoType: crypto.TypeEncryption,
|
||||||
|
Algorithm: "alg",
|
||||||
|
KeyID: "encKey",
|
||||||
|
Crypted: []byte("crypted"),
|
||||||
|
},
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
},
|
},
|
||||||
@@ -469,6 +506,12 @@ func Test_SMSConfigPrepare(t *testing.T) {
|
|||||||
Description: "description",
|
Description: "description",
|
||||||
HTTPConfig: &HTTP{
|
HTTPConfig: &HTTP{
|
||||||
Endpoint: "endpoint",
|
Endpoint: "endpoint",
|
||||||
|
signingKey: &crypto.CryptoValue{
|
||||||
|
CryptoType: crypto.TypeEncryption,
|
||||||
|
Algorithm: "alg",
|
||||||
|
KeyID: "encKey",
|
||||||
|
Crypted: []byte("crypted"),
|
||||||
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -121,6 +121,10 @@ var (
|
|||||||
name: projection.SMTPConfigHTTPColumnEndpoint,
|
name: projection.SMTPConfigHTTPColumnEndpoint,
|
||||||
table: smtpConfigsHTTPTable,
|
table: smtpConfigsHTTPTable,
|
||||||
}
|
}
|
||||||
|
SMTPConfigHTTPColumnSigningKey = Column{
|
||||||
|
name: projection.SMTPConfigHTTPColumnSigningKey,
|
||||||
|
table: smtpConfigsHTTPTable,
|
||||||
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
type SMTPConfig struct {
|
type SMTPConfig struct {
|
||||||
@@ -138,6 +142,13 @@ type SMTPConfig struct {
|
|||||||
State domain.SMTPConfigState
|
State domain.SMTPConfigState
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (h *SMTPConfig) decryptSigningKey(alg crypto.EncryptionAlgorithm) error {
|
||||||
|
if h.HTTPConfig == nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
return h.HTTPConfig.decryptSigningKey(alg)
|
||||||
|
}
|
||||||
|
|
||||||
type SMTP struct {
|
type SMTP struct {
|
||||||
TLS bool
|
TLS bool
|
||||||
SenderAddress string
|
SenderAddress string
|
||||||
@@ -166,7 +177,13 @@ func (q *Queries) SMTPConfigActive(ctx context.Context, resourceOwner string) (c
|
|||||||
config, err = scan(row)
|
config, err = scan(row)
|
||||||
return err
|
return err
|
||||||
}, query, args...)
|
}, query, args...)
|
||||||
return config, err
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if err := config.decryptSigningKey(q.smtpEncryptionAlgorithm); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return config, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (q *Queries) SMTPConfigByID(ctx context.Context, instanceID, id string) (config *SMTPConfig, err error) {
|
func (q *Queries) SMTPConfigByID(ctx context.Context, instanceID, id string) (config *SMTPConfig, err error) {
|
||||||
@@ -186,12 +203,16 @@ func (q *Queries) SMTPConfigByID(ctx context.Context, instanceID, id string) (co
|
|||||||
config, err = scan(row)
|
config, err = scan(row)
|
||||||
return err
|
return err
|
||||||
}, query, args...)
|
}, query, args...)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if err := config.decryptSigningKey(q.smtpEncryptionAlgorithm); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
return config, err
|
return config, err
|
||||||
}
|
}
|
||||||
|
|
||||||
func prepareSMTPConfigQuery() (sq.SelectBuilder, func(*sql.Row) (*SMTPConfig, error)) {
|
func prepareSMTPConfigQuery() (sq.SelectBuilder, func(*sql.Row) (*SMTPConfig, error)) {
|
||||||
password := new(crypto.CryptoValue)
|
|
||||||
|
|
||||||
return sq.Select(
|
return sq.Select(
|
||||||
SMTPConfigColumnCreationDate.identifier(),
|
SMTPConfigColumnCreationDate.identifier(),
|
||||||
SMTPConfigColumnChangeDate.identifier(),
|
SMTPConfigColumnChangeDate.identifier(),
|
||||||
@@ -211,7 +232,9 @@ func prepareSMTPConfigQuery() (sq.SelectBuilder, func(*sql.Row) (*SMTPConfig, er
|
|||||||
SMTPConfigSMTPColumnPassword.identifier(),
|
SMTPConfigSMTPColumnPassword.identifier(),
|
||||||
|
|
||||||
SMTPConfigHTTPColumnID.identifier(),
|
SMTPConfigHTTPColumnID.identifier(),
|
||||||
SMTPConfigHTTPColumnEndpoint.identifier()).
|
SMTPConfigHTTPColumnEndpoint.identifier(),
|
||||||
|
SMTPConfigHTTPColumnSigningKey.identifier(),
|
||||||
|
).
|
||||||
From(smtpConfigsTable.identifier()).
|
From(smtpConfigsTable.identifier()).
|
||||||
LeftJoin(join(SMTPConfigSMTPColumnID, SMTPConfigColumnID)).
|
LeftJoin(join(SMTPConfigSMTPColumnID, SMTPConfigColumnID)).
|
||||||
LeftJoin(join(SMTPConfigHTTPColumnID, SMTPConfigColumnID)).
|
LeftJoin(join(SMTPConfigHTTPColumnID, SMTPConfigColumnID)).
|
||||||
@@ -237,9 +260,10 @@ func prepareSMTPConfigQuery() (sq.SelectBuilder, func(*sql.Row) (*SMTPConfig, er
|
|||||||
&smtpConfig.replyToAddress,
|
&smtpConfig.replyToAddress,
|
||||||
&smtpConfig.host,
|
&smtpConfig.host,
|
||||||
&smtpConfig.user,
|
&smtpConfig.user,
|
||||||
&password,
|
&smtpConfig.password,
|
||||||
&httpConfig.id,
|
&httpConfig.id,
|
||||||
&httpConfig.endpoint,
|
&httpConfig.endpoint,
|
||||||
|
&httpConfig.signingKey,
|
||||||
)
|
)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if errors.Is(err, sql.ErrNoRows) {
|
if errors.Is(err, sql.ErrNoRows) {
|
||||||
@@ -247,9 +271,10 @@ func prepareSMTPConfigQuery() (sq.SelectBuilder, func(*sql.Row) (*SMTPConfig, er
|
|||||||
}
|
}
|
||||||
return nil, zerrors.ThrowInternal(err, "QUERY-9k87F", "Errors.Internal")
|
return nil, zerrors.ThrowInternal(err, "QUERY-9k87F", "Errors.Internal")
|
||||||
}
|
}
|
||||||
smtpConfig.password = password
|
|
||||||
smtpConfig.set(config)
|
smtpConfig.set(config)
|
||||||
httpConfig.setSMTP(config)
|
httpConfig.setSMTP(config)
|
||||||
|
|
||||||
return config, nil
|
return config, nil
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -275,6 +300,8 @@ func prepareSMTPConfigsQuery() (sq.SelectBuilder, func(*sql.Rows) (*SMTPConfigs,
|
|||||||
|
|
||||||
SMTPConfigHTTPColumnID.identifier(),
|
SMTPConfigHTTPColumnID.identifier(),
|
||||||
SMTPConfigHTTPColumnEndpoint.identifier(),
|
SMTPConfigHTTPColumnEndpoint.identifier(),
|
||||||
|
SMTPConfigHTTPColumnSigningKey.identifier(),
|
||||||
|
|
||||||
countColumn.identifier(),
|
countColumn.identifier(),
|
||||||
).From(smtpConfigsTable.identifier()).
|
).From(smtpConfigsTable.identifier()).
|
||||||
LeftJoin(join(SMTPConfigSMTPColumnID, SMTPConfigColumnID)).
|
LeftJoin(join(SMTPConfigSMTPColumnID, SMTPConfigColumnID)).
|
||||||
@@ -284,7 +311,6 @@ func prepareSMTPConfigsQuery() (sq.SelectBuilder, func(*sql.Rows) (*SMTPConfigs,
|
|||||||
configs := &SMTPConfigs{Configs: []*SMTPConfig{}}
|
configs := &SMTPConfigs{Configs: []*SMTPConfig{}}
|
||||||
for rows.Next() {
|
for rows.Next() {
|
||||||
config := new(SMTPConfig)
|
config := new(SMTPConfig)
|
||||||
password := new(crypto.CryptoValue)
|
|
||||||
var (
|
var (
|
||||||
smtpConfig = sqlSmtpConfig{}
|
smtpConfig = sqlSmtpConfig{}
|
||||||
httpConfig = sqlHTTPConfig{}
|
httpConfig = sqlHTTPConfig{}
|
||||||
@@ -304,20 +330,19 @@ func prepareSMTPConfigsQuery() (sq.SelectBuilder, func(*sql.Rows) (*SMTPConfigs,
|
|||||||
&smtpConfig.replyToAddress,
|
&smtpConfig.replyToAddress,
|
||||||
&smtpConfig.host,
|
&smtpConfig.host,
|
||||||
&smtpConfig.user,
|
&smtpConfig.user,
|
||||||
&password,
|
&smtpConfig.password,
|
||||||
&httpConfig.id,
|
&httpConfig.id,
|
||||||
&httpConfig.endpoint,
|
&httpConfig.endpoint,
|
||||||
|
&httpConfig.signingKey,
|
||||||
&configs.Count,
|
&configs.Count,
|
||||||
)
|
)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if errors.Is(err, sql.ErrNoRows) {
|
|
||||||
return nil, zerrors.ThrowNotFound(err, "QUERY-fwofw", "Errors.SMTPConfig.NotFound")
|
|
||||||
}
|
|
||||||
return nil, zerrors.ThrowInternal(err, "QUERY-9k87F", "Errors.Internal")
|
return nil, zerrors.ThrowInternal(err, "QUERY-9k87F", "Errors.Internal")
|
||||||
}
|
}
|
||||||
smtpConfig.password = password
|
|
||||||
smtpConfig.set(config)
|
smtpConfig.set(config)
|
||||||
httpConfig.setSMTP(config)
|
httpConfig.setSMTP(config)
|
||||||
|
|
||||||
configs.Configs = append(configs.Configs, config)
|
configs.Configs = append(configs.Configs, config)
|
||||||
}
|
}
|
||||||
return configs, nil
|
return configs, nil
|
||||||
@@ -344,6 +369,11 @@ func (q *Queries) SearchSMTPConfigs(ctx context.Context, queries *SMTPConfigsSea
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, zerrors.ThrowInternal(err, "QUERY-tOpKN", "Errors.Internal")
|
return nil, zerrors.ThrowInternal(err, "QUERY-tOpKN", "Errors.Internal")
|
||||||
}
|
}
|
||||||
|
for i := range configs.Configs {
|
||||||
|
if err := configs.Configs[i].decryptSigningKey(q.smtpEncryptionAlgorithm); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
}
|
||||||
configs.State, err = q.latestState(ctx, smsConfigsTable)
|
configs.State, err = q.latestState(ctx, smsConfigsTable)
|
||||||
return configs, err
|
return configs, err
|
||||||
}
|
}
|
||||||
@@ -379,6 +409,7 @@ func (c sqlHTTPConfig) setSMTP(smtpConfig *SMTPConfig) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
smtpConfig.HTTPConfig = &HTTP{
|
smtpConfig.HTTPConfig = &HTTP{
|
||||||
Endpoint: c.endpoint.String,
|
Endpoint: c.endpoint.String,
|
||||||
|
signingKey: c.signingKey,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -30,10 +30,34 @@ var (
|
|||||||
` projections.smtp_configs5_smtp.username,` +
|
` projections.smtp_configs5_smtp.username,` +
|
||||||
` projections.smtp_configs5_smtp.password,` +
|
` projections.smtp_configs5_smtp.password,` +
|
||||||
` projections.smtp_configs5_http.id,` +
|
` projections.smtp_configs5_http.id,` +
|
||||||
` projections.smtp_configs5_http.endpoint` +
|
` projections.smtp_configs5_http.endpoint,` +
|
||||||
|
` projections.smtp_configs5_http.signing_key` +
|
||||||
` FROM projections.smtp_configs5` +
|
` FROM projections.smtp_configs5` +
|
||||||
` LEFT JOIN projections.smtp_configs5_smtp ON projections.smtp_configs5.id = projections.smtp_configs5_smtp.id AND projections.smtp_configs5.instance_id = projections.smtp_configs5_smtp.instance_id` +
|
` LEFT JOIN projections.smtp_configs5_smtp ON projections.smtp_configs5.id = projections.smtp_configs5_smtp.id AND projections.smtp_configs5.instance_id = projections.smtp_configs5_smtp.instance_id` +
|
||||||
` LEFT JOIN projections.smtp_configs5_http ON projections.smtp_configs5.id = projections.smtp_configs5_http.id AND projections.smtp_configs5.instance_id = projections.smtp_configs5_http.instance_id`
|
` LEFT JOIN projections.smtp_configs5_http ON projections.smtp_configs5.id = projections.smtp_configs5_http.id AND projections.smtp_configs5.instance_id = projections.smtp_configs5_http.instance_id`
|
||||||
|
prepareSMTPConfigsStmt = `SELECT projections.smtp_configs5.creation_date,` +
|
||||||
|
` projections.smtp_configs5.change_date,` +
|
||||||
|
` projections.smtp_configs5.resource_owner,` +
|
||||||
|
` projections.smtp_configs5.sequence,` +
|
||||||
|
` projections.smtp_configs5.id,` +
|
||||||
|
` projections.smtp_configs5.state,` +
|
||||||
|
` projections.smtp_configs5.description,` +
|
||||||
|
` projections.smtp_configs5_smtp.id,` +
|
||||||
|
` projections.smtp_configs5_smtp.tls,` +
|
||||||
|
` projections.smtp_configs5_smtp.sender_address,` +
|
||||||
|
` projections.smtp_configs5_smtp.sender_name,` +
|
||||||
|
` projections.smtp_configs5_smtp.reply_to_address,` +
|
||||||
|
` projections.smtp_configs5_smtp.host,` +
|
||||||
|
` projections.smtp_configs5_smtp.username,` +
|
||||||
|
` projections.smtp_configs5_smtp.password,` +
|
||||||
|
` projections.smtp_configs5_http.id,` +
|
||||||
|
` projections.smtp_configs5_http.endpoint,` +
|
||||||
|
` projections.smtp_configs5_http.signing_key,` +
|
||||||
|
` COUNT(*) OVER ()` +
|
||||||
|
` FROM projections.smtp_configs5` +
|
||||||
|
` LEFT JOIN projections.smtp_configs5_smtp ON projections.smtp_configs5.id = projections.smtp_configs5_smtp.id AND projections.smtp_configs5.instance_id = projections.smtp_configs5_smtp.instance_id` +
|
||||||
|
` LEFT JOIN projections.smtp_configs5_http ON projections.smtp_configs5.id = projections.smtp_configs5_http.id AND projections.smtp_configs5.instance_id = projections.smtp_configs5_http.instance_id`
|
||||||
|
|
||||||
prepareSMTPConfigCols = []string{
|
prepareSMTPConfigCols = []string{
|
||||||
"creation_date",
|
"creation_date",
|
||||||
"change_date",
|
"change_date",
|
||||||
@@ -52,10 +76,12 @@ var (
|
|||||||
"smtp_password",
|
"smtp_password",
|
||||||
"id",
|
"id",
|
||||||
"endpoint",
|
"endpoint",
|
||||||
|
"signing_key",
|
||||||
}
|
}
|
||||||
|
prepareSMTPConfigsCols = append(prepareSMTPConfigCols, "count")
|
||||||
)
|
)
|
||||||
|
|
||||||
func Test_SMTPConfigsPrepares(t *testing.T) {
|
func Test_SMTPConfigPrepares(t *testing.T) {
|
||||||
type want struct {
|
type want struct {
|
||||||
sqlExpectations sqlExpectation
|
sqlExpectations sqlExpectation
|
||||||
err checkErr
|
err checkErr
|
||||||
@@ -109,6 +135,7 @@ func Test_SMTPConfigsPrepares(t *testing.T) {
|
|||||||
&crypto.CryptoValue{},
|
&crypto.CryptoValue{},
|
||||||
nil,
|
nil,
|
||||||
nil,
|
nil,
|
||||||
|
nil,
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
},
|
},
|
||||||
@@ -156,6 +183,12 @@ func Test_SMTPConfigsPrepares(t *testing.T) {
|
|||||||
nil,
|
nil,
|
||||||
"2232323",
|
"2232323",
|
||||||
"endpoint",
|
"endpoint",
|
||||||
|
&crypto.CryptoValue{
|
||||||
|
CryptoType: crypto.TypeEncryption,
|
||||||
|
Algorithm: "alg",
|
||||||
|
KeyID: "encKey",
|
||||||
|
Crypted: []byte("crypted"),
|
||||||
|
},
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
},
|
},
|
||||||
@@ -166,6 +199,12 @@ func Test_SMTPConfigsPrepares(t *testing.T) {
|
|||||||
Sequence: 20211108,
|
Sequence: 20211108,
|
||||||
HTTPConfig: &HTTP{
|
HTTPConfig: &HTTP{
|
||||||
Endpoint: "endpoint",
|
Endpoint: "endpoint",
|
||||||
|
signingKey: &crypto.CryptoValue{
|
||||||
|
CryptoType: crypto.TypeEncryption,
|
||||||
|
Algorithm: "alg",
|
||||||
|
KeyID: "encKey",
|
||||||
|
Crypted: []byte("crypted"),
|
||||||
|
},
|
||||||
},
|
},
|
||||||
ID: "2232323",
|
ID: "2232323",
|
||||||
State: domain.SMTPConfigStateActive,
|
State: domain.SMTPConfigStateActive,
|
||||||
@@ -197,6 +236,7 @@ func Test_SMTPConfigsPrepares(t *testing.T) {
|
|||||||
&crypto.CryptoValue{},
|
&crypto.CryptoValue{},
|
||||||
nil,
|
nil,
|
||||||
nil,
|
nil,
|
||||||
|
nil,
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
},
|
},
|
||||||
@@ -244,6 +284,7 @@ func Test_SMTPConfigsPrepares(t *testing.T) {
|
|||||||
&crypto.CryptoValue{},
|
&crypto.CryptoValue{},
|
||||||
nil,
|
nil,
|
||||||
nil,
|
nil,
|
||||||
|
nil,
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
},
|
},
|
||||||
@@ -290,3 +331,247 @@ func Test_SMTPConfigsPrepares(t *testing.T) {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func Test_SMTPConfigsPrepares(t *testing.T) {
|
||||||
|
type want struct {
|
||||||
|
sqlExpectations sqlExpectation
|
||||||
|
err checkErr
|
||||||
|
}
|
||||||
|
tests := []struct {
|
||||||
|
name string
|
||||||
|
prepare interface{}
|
||||||
|
want want
|
||||||
|
object interface{}
|
||||||
|
}{
|
||||||
|
|
||||||
|
{
|
||||||
|
name: "prepareSMTPConfigsQuery no result",
|
||||||
|
prepare: prepareSMTPConfigsQuery,
|
||||||
|
want: want{
|
||||||
|
sqlExpectations: mockQueries(
|
||||||
|
regexp.QuoteMeta(prepareSMTPConfigsStmt),
|
||||||
|
nil,
|
||||||
|
nil,
|
||||||
|
),
|
||||||
|
},
|
||||||
|
object: &SMTPConfigs{Configs: []*SMTPConfig{}},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "prepareSMTPConfigsQuery found",
|
||||||
|
prepare: prepareSMTPConfigsQuery,
|
||||||
|
want: want{
|
||||||
|
sqlExpectations: mockQueries(
|
||||||
|
regexp.QuoteMeta(prepareSMTPConfigsStmt),
|
||||||
|
prepareSMTPConfigsCols,
|
||||||
|
[][]driver.Value{
|
||||||
|
{
|
||||||
|
testNow,
|
||||||
|
testNow,
|
||||||
|
"ro",
|
||||||
|
uint64(20211108),
|
||||||
|
"2232323",
|
||||||
|
domain.SMTPConfigStateActive,
|
||||||
|
"test",
|
||||||
|
"2232323",
|
||||||
|
true,
|
||||||
|
"sender",
|
||||||
|
"name",
|
||||||
|
"reply-to",
|
||||||
|
"host",
|
||||||
|
"user",
|
||||||
|
&crypto.CryptoValue{},
|
||||||
|
nil,
|
||||||
|
nil,
|
||||||
|
nil,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
),
|
||||||
|
},
|
||||||
|
object: &SMTPConfigs{
|
||||||
|
SearchResponse: SearchResponse{
|
||||||
|
Count: 1,
|
||||||
|
},
|
||||||
|
Configs: []*SMTPConfig{
|
||||||
|
{
|
||||||
|
CreationDate: testNow,
|
||||||
|
ChangeDate: testNow,
|
||||||
|
ResourceOwner: "ro",
|
||||||
|
Sequence: 20211108,
|
||||||
|
SMTPConfig: &SMTP{
|
||||||
|
TLS: true,
|
||||||
|
SenderAddress: "sender",
|
||||||
|
SenderName: "name",
|
||||||
|
ReplyToAddress: "reply-to",
|
||||||
|
Host: "host",
|
||||||
|
User: "user",
|
||||||
|
Password: &crypto.CryptoValue{},
|
||||||
|
},
|
||||||
|
ID: "2232323",
|
||||||
|
State: domain.SMTPConfigStateActive,
|
||||||
|
Description: "test",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "prepareSMTPConfigsQuery found, multi",
|
||||||
|
prepare: prepareSMTPConfigsQuery,
|
||||||
|
want: want{
|
||||||
|
sqlExpectations: mockQueries(
|
||||||
|
regexp.QuoteMeta(prepareSMTPConfigsStmt),
|
||||||
|
prepareSMTPConfigsCols,
|
||||||
|
[][]driver.Value{
|
||||||
|
{
|
||||||
|
testNow,
|
||||||
|
testNow,
|
||||||
|
"ro",
|
||||||
|
uint64(20211108),
|
||||||
|
"2232323",
|
||||||
|
domain.SMTPConfigStateActive,
|
||||||
|
"test",
|
||||||
|
nil,
|
||||||
|
nil,
|
||||||
|
nil,
|
||||||
|
nil,
|
||||||
|
nil,
|
||||||
|
nil,
|
||||||
|
nil,
|
||||||
|
nil,
|
||||||
|
"2232323",
|
||||||
|
"endpoint",
|
||||||
|
&crypto.CryptoValue{
|
||||||
|
CryptoType: crypto.TypeEncryption,
|
||||||
|
Algorithm: "alg",
|
||||||
|
KeyID: "encKey",
|
||||||
|
Crypted: []byte("crypted"),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
testNow,
|
||||||
|
testNow,
|
||||||
|
"ro",
|
||||||
|
uint64(20211109),
|
||||||
|
"44442323",
|
||||||
|
domain.SMTPConfigStateInactive,
|
||||||
|
"test2",
|
||||||
|
"44442323",
|
||||||
|
true,
|
||||||
|
"sender2",
|
||||||
|
"name2",
|
||||||
|
"reply-to2",
|
||||||
|
"host2",
|
||||||
|
"user2",
|
||||||
|
&crypto.CryptoValue{},
|
||||||
|
nil,
|
||||||
|
nil,
|
||||||
|
nil,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
testNow,
|
||||||
|
testNow,
|
||||||
|
"ro",
|
||||||
|
uint64(20211109),
|
||||||
|
"23234444",
|
||||||
|
domain.SMTPConfigStateInactive,
|
||||||
|
"test3",
|
||||||
|
"23234444",
|
||||||
|
true,
|
||||||
|
"sender3",
|
||||||
|
"name3",
|
||||||
|
"reply-to3",
|
||||||
|
"host3",
|
||||||
|
"user3",
|
||||||
|
&crypto.CryptoValue{},
|
||||||
|
nil,
|
||||||
|
nil,
|
||||||
|
nil,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
),
|
||||||
|
},
|
||||||
|
object: &SMTPConfigs{
|
||||||
|
SearchResponse: SearchResponse{
|
||||||
|
Count: 3,
|
||||||
|
},
|
||||||
|
Configs: []*SMTPConfig{
|
||||||
|
{
|
||||||
|
CreationDate: testNow,
|
||||||
|
ChangeDate: testNow,
|
||||||
|
ResourceOwner: "ro",
|
||||||
|
Sequence: 20211108,
|
||||||
|
HTTPConfig: &HTTP{
|
||||||
|
Endpoint: "endpoint",
|
||||||
|
signingKey: &crypto.CryptoValue{
|
||||||
|
CryptoType: crypto.TypeEncryption,
|
||||||
|
Algorithm: "alg",
|
||||||
|
KeyID: "encKey",
|
||||||
|
Crypted: []byte("crypted"),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
ID: "2232323",
|
||||||
|
State: domain.SMTPConfigStateActive,
|
||||||
|
Description: "test",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
CreationDate: testNow,
|
||||||
|
ChangeDate: testNow,
|
||||||
|
ResourceOwner: "ro",
|
||||||
|
Sequence: 20211109,
|
||||||
|
SMTPConfig: &SMTP{
|
||||||
|
TLS: true,
|
||||||
|
SenderAddress: "sender2",
|
||||||
|
SenderName: "name2",
|
||||||
|
ReplyToAddress: "reply-to2",
|
||||||
|
Host: "host2",
|
||||||
|
User: "user2",
|
||||||
|
Password: &crypto.CryptoValue{},
|
||||||
|
},
|
||||||
|
ID: "44442323",
|
||||||
|
State: domain.SMTPConfigStateInactive,
|
||||||
|
Description: "test2",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
CreationDate: testNow,
|
||||||
|
ChangeDate: testNow,
|
||||||
|
ResourceOwner: "ro",
|
||||||
|
Sequence: 20211109,
|
||||||
|
SMTPConfig: &SMTP{
|
||||||
|
TLS: true,
|
||||||
|
SenderAddress: "sender3",
|
||||||
|
SenderName: "name3",
|
||||||
|
ReplyToAddress: "reply-to3",
|
||||||
|
Host: "host3",
|
||||||
|
User: "user3",
|
||||||
|
Password: &crypto.CryptoValue{},
|
||||||
|
},
|
||||||
|
ID: "23234444",
|
||||||
|
State: domain.SMTPConfigStateInactive,
|
||||||
|
Description: "test3",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "prepareSMTPConfigsQuery sql err",
|
||||||
|
prepare: prepareSMTPConfigsQuery,
|
||||||
|
want: want{
|
||||||
|
sqlExpectations: mockQueryErr(
|
||||||
|
regexp.QuoteMeta(prepareSMTPConfigsStmt),
|
||||||
|
sql.ErrConnDone,
|
||||||
|
),
|
||||||
|
err: func(err error) (error, bool) {
|
||||||
|
if !errors.Is(err, sql.ErrConnDone) {
|
||||||
|
return fmt.Errorf("err should be sql.ErrConnDone got: %w", err), false
|
||||||
|
}
|
||||||
|
return nil, true
|
||||||
|
},
|
||||||
|
},
|
||||||
|
object: (*SMTPConfigs)(nil),
|
||||||
|
},
|
||||||
|
}
|
||||||
|
for _, tt := range tests {
|
||||||
|
t.Run(tt.name, func(t *testing.T) {
|
||||||
|
assertPrepare(t, tt.prepare, tt.object, tt.want.sqlExpectations, tt.want.err)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -183,9 +183,10 @@ func (e *SMSConfigTwilioTokenChangedEvent) UniqueConstraints() []*eventstore.Uni
|
|||||||
type SMSConfigHTTPAddedEvent struct {
|
type SMSConfigHTTPAddedEvent struct {
|
||||||
*eventstore.BaseEvent `json:"-"`
|
*eventstore.BaseEvent `json:"-"`
|
||||||
|
|
||||||
ID string `json:"id,omitempty"`
|
ID string `json:"id,omitempty"`
|
||||||
Description string `json:"description,omitempty"`
|
Description string `json:"description,omitempty"`
|
||||||
Endpoint string `json:"endpoint,omitempty"`
|
Endpoint string `json:"endpoint,omitempty"`
|
||||||
|
SigningKey *crypto.CryptoValue `json:"signingKey"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewSMSConfigHTTPAddedEvent(
|
func NewSMSConfigHTTPAddedEvent(
|
||||||
@@ -194,6 +195,7 @@ func NewSMSConfigHTTPAddedEvent(
|
|||||||
id,
|
id,
|
||||||
description,
|
description,
|
||||||
endpoint string,
|
endpoint string,
|
||||||
|
signingKey *crypto.CryptoValue,
|
||||||
) *SMSConfigHTTPAddedEvent {
|
) *SMSConfigHTTPAddedEvent {
|
||||||
return &SMSConfigHTTPAddedEvent{
|
return &SMSConfigHTTPAddedEvent{
|
||||||
BaseEvent: eventstore.NewBaseEventForPush(
|
BaseEvent: eventstore.NewBaseEventForPush(
|
||||||
@@ -204,6 +206,7 @@ func NewSMSConfigHTTPAddedEvent(
|
|||||||
ID: id,
|
ID: id,
|
||||||
Description: description,
|
Description: description,
|
||||||
Endpoint: endpoint,
|
Endpoint: endpoint,
|
||||||
|
SigningKey: signingKey,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -222,9 +225,10 @@ func (e *SMSConfigHTTPAddedEvent) UniqueConstraints() []*eventstore.UniqueConstr
|
|||||||
type SMSConfigHTTPChangedEvent struct {
|
type SMSConfigHTTPChangedEvent struct {
|
||||||
*eventstore.BaseEvent `json:"-"`
|
*eventstore.BaseEvent `json:"-"`
|
||||||
|
|
||||||
ID string `json:"id,omitempty"`
|
ID string `json:"id,omitempty"`
|
||||||
Description *string `json:"description,omitempty"`
|
Description *string `json:"description,omitempty"`
|
||||||
Endpoint *string `json:"endpoint,omitempty"`
|
Endpoint *string `json:"endpoint,omitempty"`
|
||||||
|
SigningKey *crypto.CryptoValue `json:"signingKey,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewSMSConfigHTTPChangedEvent(
|
func NewSMSConfigHTTPChangedEvent(
|
||||||
@@ -262,6 +266,11 @@ func ChangeSMSConfigHTTPEndpoint(endpoint string) func(event *SMSConfigHTTPChang
|
|||||||
e.Endpoint = &endpoint
|
e.Endpoint = &endpoint
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
func ChangeSMSConfigHTTPSigningKey(signingKey *crypto.CryptoValue) func(event *SMSConfigHTTPChangedEvent) {
|
||||||
|
return func(e *SMSConfigHTTPChangedEvent) {
|
||||||
|
e.SigningKey = signingKey
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func (e *SMSConfigHTTPChangedEvent) SetBaseEvent(event *eventstore.BaseEvent) {
|
func (e *SMSConfigHTTPChangedEvent) SetBaseEvent(event *eventstore.BaseEvent) {
|
||||||
e.BaseEvent = event
|
e.BaseEvent = event
|
||||||
|
|||||||
@@ -217,9 +217,10 @@ func (e *SMTPConfigPasswordChangedEvent) UniqueConstraints() []*eventstore.Uniqu
|
|||||||
type SMTPConfigHTTPAddedEvent struct {
|
type SMTPConfigHTTPAddedEvent struct {
|
||||||
*eventstore.BaseEvent `json:"-"`
|
*eventstore.BaseEvent `json:"-"`
|
||||||
|
|
||||||
ID string `json:"id,omitempty"`
|
ID string `json:"id,omitempty"`
|
||||||
Description string `json:"description,omitempty"`
|
Description string `json:"description,omitempty"`
|
||||||
Endpoint string `json:"endpoint,omitempty"`
|
Endpoint string `json:"endpoint,omitempty"`
|
||||||
|
SigningKey *crypto.CryptoValue `json:"signingKey"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewSMTPConfigHTTPAddedEvent(
|
func NewSMTPConfigHTTPAddedEvent(
|
||||||
@@ -227,6 +228,7 @@ func NewSMTPConfigHTTPAddedEvent(
|
|||||||
aggregate *eventstore.Aggregate,
|
aggregate *eventstore.Aggregate,
|
||||||
id, description string,
|
id, description string,
|
||||||
endpoint string,
|
endpoint string,
|
||||||
|
signingKey *crypto.CryptoValue,
|
||||||
) *SMTPConfigHTTPAddedEvent {
|
) *SMTPConfigHTTPAddedEvent {
|
||||||
return &SMTPConfigHTTPAddedEvent{
|
return &SMTPConfigHTTPAddedEvent{
|
||||||
BaseEvent: eventstore.NewBaseEventForPush(
|
BaseEvent: eventstore.NewBaseEventForPush(
|
||||||
@@ -237,6 +239,7 @@ func NewSMTPConfigHTTPAddedEvent(
|
|||||||
ID: id,
|
ID: id,
|
||||||
Description: description,
|
Description: description,
|
||||||
Endpoint: endpoint,
|
Endpoint: endpoint,
|
||||||
|
SigningKey: signingKey,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -254,9 +257,10 @@ func (e *SMTPConfigHTTPAddedEvent) UniqueConstraints() []*eventstore.UniqueConst
|
|||||||
|
|
||||||
type SMTPConfigHTTPChangedEvent struct {
|
type SMTPConfigHTTPChangedEvent struct {
|
||||||
*eventstore.BaseEvent `json:"-"`
|
*eventstore.BaseEvent `json:"-"`
|
||||||
ID string `json:"id,omitempty"`
|
ID string `json:"id,omitempty"`
|
||||||
Description *string `json:"description,omitempty"`
|
Description *string `json:"description,omitempty"`
|
||||||
Endpoint *string `json:"endpoint,omitempty"`
|
Endpoint *string `json:"endpoint,omitempty"`
|
||||||
|
SigningKey *crypto.CryptoValue `json:"signingKey,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func (e *SMTPConfigHTTPChangedEvent) SetBaseEvent(event *eventstore.BaseEvent) {
|
func (e *SMTPConfigHTTPChangedEvent) SetBaseEvent(event *eventstore.BaseEvent) {
|
||||||
@@ -314,6 +318,12 @@ func ChangeSMTPConfigHTTPEndpoint(endpoint string) func(event *SMTPConfigHTTPCha
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func ChangeSMTPConfigHTTPSigningKey(signingKey *crypto.CryptoValue) func(event *SMTPConfigHTTPChangedEvent) {
|
||||||
|
return func(e *SMTPConfigHTTPChangedEvent) {
|
||||||
|
e.SigningKey = signingKey
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
type SMTPConfigActivatedEvent struct {
|
type SMTPConfigActivatedEvent struct {
|
||||||
*eventstore.BaseEvent `json:"-"`
|
*eventstore.BaseEvent `json:"-"`
|
||||||
ID string `json:"id,omitempty"`
|
ID string `json:"id,omitempty"`
|
||||||
|
|||||||
@@ -5069,6 +5069,12 @@ message AddEmailProviderHTTPRequest {
|
|||||||
message AddEmailProviderHTTPResponse {
|
message AddEmailProviderHTTPResponse {
|
||||||
zitadel.v1.ObjectDetails details = 1;
|
zitadel.v1.ObjectDetails details = 1;
|
||||||
string id = 2;
|
string id = 2;
|
||||||
|
// Key used to sign and check payload sent to the HTTP provider.
|
||||||
|
string signing_key = 3 [
|
||||||
|
(grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = {
|
||||||
|
example: "\"98KmsU67\""
|
||||||
|
}
|
||||||
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
message UpdateEmailProviderHTTPRequest {
|
message UpdateEmailProviderHTTPRequest {
|
||||||
@@ -5090,10 +5096,31 @@ message UpdateEmailProviderHTTPRequest {
|
|||||||
max_length: 200;
|
max_length: 200;
|
||||||
}
|
}
|
||||||
];
|
];
|
||||||
|
// Regenerate the key used for signing and checking the payload sent to the HTTP provider.
|
||||||
|
// Set the graceful period for the existing key. During that time, the previous
|
||||||
|
// signing key and the new one will be used to sign the request to allow you a smooth
|
||||||
|
// transition onf your API.
|
||||||
|
//
|
||||||
|
// Note that we currently only allow an immediate rotation ("0s") and will support
|
||||||
|
// longer expirations in the future.
|
||||||
|
optional google.protobuf.Duration expiration_signing_key = 4 [
|
||||||
|
(validate.rules).duration = {const: {seconds: 0, nanos: 0}},
|
||||||
|
(grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = {
|
||||||
|
example: "\"0s\""
|
||||||
|
minimum: 0
|
||||||
|
maximum: 0
|
||||||
|
}
|
||||||
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
message UpdateEmailProviderHTTPResponse {
|
message UpdateEmailProviderHTTPResponse {
|
||||||
zitadel.v1.ObjectDetails details = 1;
|
zitadel.v1.ObjectDetails details = 1;
|
||||||
|
// Key used to sign and check payload sent to the HTTP provider.
|
||||||
|
optional string signing_key = 2 [
|
||||||
|
(grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = {
|
||||||
|
example: "\"98KmsU67\""
|
||||||
|
}
|
||||||
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
message ActivateEmailProviderRequest {
|
message ActivateEmailProviderRequest {
|
||||||
@@ -5336,6 +5363,12 @@ message AddSMSProviderHTTPRequest {
|
|||||||
message AddSMSProviderHTTPResponse {
|
message AddSMSProviderHTTPResponse {
|
||||||
zitadel.v1.ObjectDetails details = 1;
|
zitadel.v1.ObjectDetails details = 1;
|
||||||
string id = 2;
|
string id = 2;
|
||||||
|
// Key used to sign and check payload sent to the HTTP provider.
|
||||||
|
string signing_key = 3 [
|
||||||
|
(grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = {
|
||||||
|
example: "\"98KmsU67\""
|
||||||
|
}
|
||||||
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
message UpdateSMSProviderHTTPRequest {
|
message UpdateSMSProviderHTTPRequest {
|
||||||
@@ -5357,10 +5390,30 @@ message UpdateSMSProviderHTTPRequest {
|
|||||||
max_length: 200;
|
max_length: 200;
|
||||||
}
|
}
|
||||||
];
|
];
|
||||||
|
// Regenerate the key used for signing and checking the payload sent to the HTTP provider.
|
||||||
|
// Set the graceful period for the existing key. During that time, the previous
|
||||||
|
// signing key and the new one will be used to sign the request to allow you a smooth
|
||||||
|
// transition onf your API.
|
||||||
|
//
|
||||||
|
// Note that we currently only allow an immediate rotation ("0s") and will support
|
||||||
|
// longer expirations in the future.
|
||||||
|
optional google.protobuf.Duration expiration_signing_key = 4 [
|
||||||
|
(validate.rules).duration = {const: {seconds: 0, nanos: 0}},
|
||||||
|
(grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = {
|
||||||
|
example: "\"0s\""
|
||||||
|
minimum: 0
|
||||||
|
maximum: 0
|
||||||
|
}
|
||||||
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
message UpdateSMSProviderHTTPResponse {
|
message UpdateSMSProviderHTTPResponse {
|
||||||
zitadel.v1.ObjectDetails details = 1;
|
zitadel.v1.ObjectDetails details = 1;// Key used to sign and check payload sent to the HTTP provider.
|
||||||
|
optional string signing_key = 2 [
|
||||||
|
(grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = {
|
||||||
|
example: "\"98KmsU67\""
|
||||||
|
}
|
||||||
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
message ActivateSMSProviderRequest {
|
message ActivateSMSProviderRequest {
|
||||||
|
|||||||
@@ -144,6 +144,11 @@ message EmailProviderSMTP {
|
|||||||
|
|
||||||
message EmailProviderHTTP {
|
message EmailProviderHTTP {
|
||||||
string endpoint = 1;
|
string endpoint = 1;
|
||||||
|
string signing_key = 2 [
|
||||||
|
(grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = {
|
||||||
|
example: "\"98KmsU67\""
|
||||||
|
}
|
||||||
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
message SMSProvider {
|
message SMSProvider {
|
||||||
@@ -166,6 +171,11 @@ message TwilioConfig {
|
|||||||
|
|
||||||
message HTTPConfig {
|
message HTTPConfig {
|
||||||
string endpoint = 1;
|
string endpoint = 1;
|
||||||
|
string signing_key = 2 [
|
||||||
|
(grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = {
|
||||||
|
example: "\"98KmsU67\""
|
||||||
|
}
|
||||||
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
enum SMSProviderConfigState {
|
enum SMSProviderConfigState {
|
||||||
|
|||||||
Reference in New Issue
Block a user