mirror of
https://github.com/zitadel/zitadel.git
synced 2025-02-28 12:17:24 +00:00
feat: Notification providers config (#3212)
* feat: add login check lifetimes to login policy * feat: org features test * feat: debug notificatiaon events * feat: debug notification file/log commands * feat: add requests to proto * feat: add api for debug notification providers file/log * feat: add projection for debug notifiication providers * feat: requests * feat: merge v2 * feat: add settings proto to generate * feat: notifiaction providers * fix: remove unused code * Update iam_converter.go Co-authored-by: Livio Amstutz <livio.a@gmail.com>
This commit is contained in:
parent
7d6c933485
commit
7899a0b851
@ -152,6 +152,10 @@ protoc \
|
||||
-I=/proto/include \
|
||||
--doc_out=${DOCS_PATH} --doc_opt=${PROTO_PATH}/docs/zitadel-md.tmpl,user.md \
|
||||
${PROTO_PATH}/user.proto
|
||||
protoc \
|
||||
-I=/proto/include \
|
||||
--doc_out=${DOCS_PATH} --doc_opt=${PROTO_PATH}/docs/zitadel-md.tmpl,settings.md \
|
||||
${PROTO_PATH}/settings.proto
|
||||
|
||||
|
||||
echo "done generating grpc"
|
@ -171,7 +171,7 @@ func startZitadel(config *startConfig) error {
|
||||
return fmt.Errorf("cannot start commands: %w", err)
|
||||
}
|
||||
|
||||
notification.Start(config.Notification, config.SystemDefaults, commands, queries, dbClient, assets.HandlerPrefix, smtpPasswordCrypto)
|
||||
notification.Start(config.Notification, config.SystemDefaults, commands, queries, dbClient, assets.HandlerPrefix, smtpPasswordCrypto, smsCrypto)
|
||||
|
||||
router := mux.NewRouter()
|
||||
err = startAPIs(ctx, router, commands, queries, eventstoreClient, dbClient, keyChan, config, storage, authZRepo)
|
||||
|
@ -188,6 +188,30 @@ Update twilio sms provider token
|
||||
PUT: /sms/twilio/{id}/token
|
||||
|
||||
|
||||
### GetFileSystemNotificationProvider
|
||||
|
||||
> **rpc** GetFileSystemNotificationProvider([GetFileSystemNotificationProviderRequest](#getfilesystemnotificationproviderrequest))
|
||||
[GetFileSystemNotificationProviderResponse](#getfilesystemnotificationproviderresponse)
|
||||
|
||||
Get file system notification provider
|
||||
|
||||
|
||||
|
||||
GET: /notification/provider/file
|
||||
|
||||
|
||||
### GetLogNotificationProvider
|
||||
|
||||
> **rpc** GetLogNotificationProvider([GetLogNotificationProviderRequest](#getlognotificationproviderrequest))
|
||||
[GetLogNotificationProviderResponse](#getlognotificationproviderresponse)
|
||||
|
||||
Get log notification provider
|
||||
|
||||
|
||||
|
||||
GET: /notification/provider/log
|
||||
|
||||
|
||||
### GetOIDCSettings
|
||||
|
||||
> **rpc** GetOIDCSettings([GetOIDCSettingsRequest](#getoidcsettingsrequest))
|
||||
@ -1997,6 +2021,23 @@ This is an empty request
|
||||
|
||||
|
||||
|
||||
### GetFileSystemNotificationProviderRequest
|
||||
This is an empty request
|
||||
|
||||
|
||||
|
||||
|
||||
### GetFileSystemNotificationProviderResponse
|
||||
|
||||
|
||||
|
||||
| Field | Type | Description | Validation |
|
||||
| ----- | ---- | ----------- | ----------- |
|
||||
| provider | zitadel.settings.v1.DebugNotificationProvider | - | |
|
||||
|
||||
|
||||
|
||||
|
||||
### GetIDPByIDRequest
|
||||
|
||||
|
||||
@ -2053,6 +2094,23 @@ This is an empty request
|
||||
|
||||
|
||||
|
||||
### GetLogNotificationProviderRequest
|
||||
This is an empty request
|
||||
|
||||
|
||||
|
||||
|
||||
### GetLogNotificationProviderResponse
|
||||
|
||||
|
||||
|
||||
| Field | Type | Description | Validation |
|
||||
| ----- | ---- | ----------- | ----------- |
|
||||
| provider | zitadel.settings.v1.DebugNotificationProvider | - | |
|
||||
|
||||
|
||||
|
||||
|
||||
### GetLoginPolicyRequest
|
||||
This is an empty request
|
||||
|
||||
|
31
internal/api/grpc/admin/notification_provider.go
Normal file
31
internal/api/grpc/admin/notification_provider.go
Normal file
@ -0,0 +1,31 @@
|
||||
package admin
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/caos/zitadel/internal/api/grpc/settings"
|
||||
"github.com/caos/zitadel/internal/domain"
|
||||
admin_pb "github.com/caos/zitadel/pkg/grpc/admin"
|
||||
)
|
||||
|
||||
func (s *Server) GetFileSystemNotificationProvider(ctx context.Context, req *admin_pb.GetFileSystemNotificationProviderRequest) (*admin_pb.GetFileSystemNotificationProviderResponse, error) {
|
||||
result, err := s.query.NotificationProviderByIDAndType(ctx, domain.IAMID, domain.NotificationProviderTypeFile)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
||||
}
|
||||
return &admin_pb.GetFileSystemNotificationProviderResponse{
|
||||
Provider: settings.NotificationProviderToPb(result),
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (s *Server) GetLogNotificationProvider(ctx context.Context, req *admin_pb.GetLogNotificationProviderRequest) (*admin_pb.GetLogNotificationProviderResponse, error) {
|
||||
result, err := s.query.NotificationProviderByIDAndType(ctx, domain.IAMID, domain.NotificationProviderTypeLog)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
||||
}
|
||||
return &admin_pb.GetLogNotificationProviderResponse{
|
||||
Provider: settings.NotificationProviderToPb(result),
|
||||
}, nil
|
||||
}
|
15
internal/api/grpc/settings/converter.go
Normal file
15
internal/api/grpc/settings/converter.go
Normal file
@ -0,0 +1,15 @@
|
||||
package settings
|
||||
|
||||
import (
|
||||
obj_pb "github.com/caos/zitadel/internal/api/grpc/object"
|
||||
"github.com/caos/zitadel/internal/query"
|
||||
settings_pb "github.com/caos/zitadel/pkg/grpc/settings"
|
||||
)
|
||||
|
||||
func NotificationProviderToPb(provider *query.DebugNotificationProvider) *settings_pb.DebugNotificationProvider {
|
||||
mapped := &settings_pb.DebugNotificationProvider{
|
||||
Compact: provider.Compact,
|
||||
Details: obj_pb.ToViewDetailsPb(provider.Sequence, provider.CreationDate, provider.ChangeDate, provider.AggregateID),
|
||||
}
|
||||
return mapped
|
||||
}
|
31
internal/command/debug_notification_model.go
Normal file
31
internal/command/debug_notification_model.go
Normal file
@ -0,0 +1,31 @@
|
||||
package command
|
||||
|
||||
import (
|
||||
"github.com/caos/zitadel/internal/domain"
|
||||
"github.com/caos/zitadel/internal/eventstore"
|
||||
"github.com/caos/zitadel/internal/repository/settings"
|
||||
)
|
||||
|
||||
type DebugNotificationWriteModel struct {
|
||||
eventstore.WriteModel
|
||||
|
||||
Compact bool
|
||||
State domain.NotificationProviderState
|
||||
}
|
||||
|
||||
func (wm *DebugNotificationWriteModel) Reduce() error {
|
||||
for _, event := range wm.Events {
|
||||
switch e := event.(type) {
|
||||
case *settings.DebugNotificationProviderAddedEvent:
|
||||
wm.Compact = e.Compact
|
||||
wm.State = domain.NotificationProviderStateActive
|
||||
case *settings.DebugNotificationProviderChangedEvent:
|
||||
if e.Compact != nil {
|
||||
wm.Compact = *e.Compact
|
||||
}
|
||||
case *settings.DebugNotificationProviderRemovedEvent:
|
||||
wm.State = domain.NotificationProviderStateRemoved
|
||||
}
|
||||
}
|
||||
return wm.WriteModel.Reduce()
|
||||
}
|
120
internal/command/iam_debug_notification_file.go
Normal file
120
internal/command/iam_debug_notification_file.go
Normal file
@ -0,0 +1,120 @@
|
||||
package command
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/caos/zitadel/internal/domain"
|
||||
caos_errs "github.com/caos/zitadel/internal/errors"
|
||||
"github.com/caos/zitadel/internal/eventstore"
|
||||
"github.com/caos/zitadel/internal/notification/channels/fs"
|
||||
iam_repo "github.com/caos/zitadel/internal/repository/iam"
|
||||
"github.com/caos/zitadel/internal/telemetry/tracing"
|
||||
)
|
||||
|
||||
func (c *Commands) AddDebugNotificationProviderFile(ctx context.Context, fileSystemProvider *fs.FSConfig) (*domain.ObjectDetails, error) {
|
||||
writeModel := NewIAMDebugNotificationFileWriteModel()
|
||||
iamAgg := IAMAggregateFromWriteModel(&writeModel.WriteModel)
|
||||
events, err := c.addDefaultDebugNotificationFile(ctx, iamAgg, writeModel, fileSystemProvider)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
pushedEvents, err := c.eventstore.Push(ctx, events...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
err = AppendAndReduce(writeModel, pushedEvents...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return writeModelToObjectDetails(&writeModel.DebugNotificationWriteModel.WriteModel), nil
|
||||
}
|
||||
|
||||
func (c *Commands) addDefaultDebugNotificationFile(ctx context.Context, iamAgg *eventstore.Aggregate, addedWriteModel *IAMDebugNotificationFileWriteModel, fileSystemProvider *fs.FSConfig) ([]eventstore.Command, error) {
|
||||
err := c.eventstore.FilterToQueryReducer(ctx, addedWriteModel)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if addedWriteModel.State.Exists() {
|
||||
return nil, caos_errs.ThrowAlreadyExists(nil, "IAM-d93nfs", "Errors.IAM.DebugNotificationProvider.AlreadyExists")
|
||||
}
|
||||
|
||||
events := []eventstore.Command{
|
||||
iam_repo.NewDebugNotificationProviderFileAddedEvent(ctx,
|
||||
iamAgg,
|
||||
fileSystemProvider.Compact),
|
||||
}
|
||||
return events, nil
|
||||
}
|
||||
|
||||
func (c *Commands) ChangeDefaultNotificationFile(ctx context.Context, fileSystemProvider *fs.FSConfig) (*domain.ObjectDetails, error) {
|
||||
writeModel := NewIAMDebugNotificationFileWriteModel()
|
||||
iamAgg := IAMAggregateFromWriteModel(&writeModel.WriteModel)
|
||||
events, err := c.changeDefaultDebugNotificationProviderFile(ctx, iamAgg, writeModel, fileSystemProvider)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
pushedEvents, err := c.eventstore.Push(ctx, events...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
err = AppendAndReduce(writeModel, pushedEvents...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return writeModelToObjectDetails(&writeModel.DebugNotificationWriteModel.WriteModel), nil
|
||||
}
|
||||
|
||||
func (c *Commands) changeDefaultDebugNotificationProviderFile(ctx context.Context, iamAgg *eventstore.Aggregate, existingProvider *IAMDebugNotificationFileWriteModel, fileSystemProvider *fs.FSConfig) ([]eventstore.Command, error) {
|
||||
err := c.defaultDebugNotificationProviderFileWriteModelByID(ctx, existingProvider)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if !existingProvider.State.Exists() {
|
||||
return nil, caos_errs.ThrowNotFound(nil, "IAM-fm9wl", "Errors.IAM.DebugNotificationProvider.NotFound")
|
||||
}
|
||||
events := make([]eventstore.Command, 0)
|
||||
changedEvent, hasChanged := existingProvider.NewChangedEvent(ctx,
|
||||
iamAgg,
|
||||
fileSystemProvider.Compact)
|
||||
if hasChanged {
|
||||
events = append(events, changedEvent)
|
||||
}
|
||||
if len(events) == 0 {
|
||||
return nil, caos_errs.ThrowPreconditionFailed(nil, "IAM-5M9vdd", "Errors.IAM.LoginPolicy.NotChanged")
|
||||
|
||||
}
|
||||
return events, nil
|
||||
}
|
||||
|
||||
func (c *Commands) RemoveDefaultNotificationFile(ctx context.Context) (*domain.ObjectDetails, error) {
|
||||
existingProvider := NewIAMDebugNotificationFileWriteModel()
|
||||
iamAgg := IAMAggregateFromWriteModel(&existingProvider.WriteModel)
|
||||
err := c.defaultDebugNotificationProviderFileWriteModelByID(ctx, existingProvider)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if !existingProvider.State.Exists() {
|
||||
return nil, caos_errs.ThrowNotFound(nil, "IAM-dj9ew", "Errors.IAM.DebugNotificationProvider.NotFound")
|
||||
}
|
||||
|
||||
events, err := c.eventstore.Push(ctx, iam_repo.NewDebugNotificationProviderFileRemovedEvent(ctx, iamAgg))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
err = AppendAndReduce(existingProvider, events...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return writeModelToObjectDetails(&existingProvider.DebugNotificationWriteModel.WriteModel), nil
|
||||
}
|
||||
|
||||
func (c *Commands) defaultDebugNotificationProviderFileWriteModelByID(ctx context.Context, writeModel *IAMDebugNotificationFileWriteModel) (err error) {
|
||||
ctx, span := tracing.NewSpan(ctx)
|
||||
defer func() { span.EndWithError(err) }()
|
||||
|
||||
err = c.eventstore.FilterToQueryReducer(ctx, writeModel)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
79
internal/command/iam_debug_notification_file_model.go
Normal file
79
internal/command/iam_debug_notification_file_model.go
Normal file
@ -0,0 +1,79 @@
|
||||
package command
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/caos/zitadel/internal/eventstore"
|
||||
"github.com/caos/zitadel/internal/repository/settings"
|
||||
|
||||
"github.com/caos/zitadel/internal/domain"
|
||||
"github.com/caos/zitadel/internal/repository/iam"
|
||||
)
|
||||
|
||||
type IAMDebugNotificationFileWriteModel struct {
|
||||
DebugNotificationWriteModel
|
||||
}
|
||||
|
||||
func NewIAMDebugNotificationFileWriteModel() *IAMDebugNotificationFileWriteModel {
|
||||
return &IAMDebugNotificationFileWriteModel{
|
||||
DebugNotificationWriteModel{
|
||||
WriteModel: eventstore.WriteModel{
|
||||
AggregateID: domain.IAMID,
|
||||
ResourceOwner: domain.IAMID,
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func (wm *IAMDebugNotificationFileWriteModel) AppendEvents(events ...eventstore.Event) {
|
||||
for _, event := range events {
|
||||
switch e := event.(type) {
|
||||
case *iam.DebugNotificationProviderFileAddedEvent:
|
||||
wm.DebugNotificationWriteModel.AppendEvents(&e.DebugNotificationProviderAddedEvent)
|
||||
case *iam.DebugNotificationProviderFileChangedEvent:
|
||||
wm.DebugNotificationWriteModel.AppendEvents(&e.DebugNotificationProviderChangedEvent)
|
||||
case *iam.DebugNotificationProviderFileRemovedEvent:
|
||||
wm.DebugNotificationWriteModel.AppendEvents(&e.DebugNotificationProviderRemovedEvent)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (wm *IAMDebugNotificationFileWriteModel) IsValid() bool {
|
||||
return wm.AggregateID != ""
|
||||
}
|
||||
|
||||
func (wm *IAMDebugNotificationFileWriteModel) Reduce() error {
|
||||
return wm.DebugNotificationWriteModel.Reduce()
|
||||
}
|
||||
|
||||
func (wm *IAMDebugNotificationFileWriteModel) Query() *eventstore.SearchQueryBuilder {
|
||||
return eventstore.NewSearchQueryBuilder(eventstore.ColumnsEvent).
|
||||
ResourceOwner(wm.ResourceOwner).
|
||||
AddQuery().
|
||||
AggregateTypes(iam.AggregateType).
|
||||
AggregateIDs(wm.DebugNotificationWriteModel.AggregateID).
|
||||
EventTypes(
|
||||
iam.DebugNotificationProviderFileAddedEventType,
|
||||
iam.DebugNotificationProviderFileChangedEventType,
|
||||
iam.DebugNotificationProviderFileRemovedEventType).
|
||||
Builder()
|
||||
}
|
||||
|
||||
func (wm *IAMDebugNotificationFileWriteModel) NewChangedEvent(
|
||||
ctx context.Context,
|
||||
aggregate *eventstore.Aggregate,
|
||||
compact bool) (*iam.DebugNotificationProviderFileChangedEvent, bool) {
|
||||
|
||||
changes := make([]settings.DebugNotificationProviderChanges, 0)
|
||||
if wm.Compact != compact {
|
||||
changes = append(changes, settings.ChangeCompact(compact))
|
||||
}
|
||||
if len(changes) == 0 {
|
||||
return nil, false
|
||||
}
|
||||
changedEvent, err := iam.NewDebugNotificationProviderFileChangedEvent(ctx, aggregate, changes)
|
||||
if err != nil {
|
||||
return nil, false
|
||||
}
|
||||
return changedEvent, true
|
||||
}
|
348
internal/command/iam_debug_notification_file_test.go
Normal file
348
internal/command/iam_debug_notification_file_test.go
Normal file
@ -0,0 +1,348 @@
|
||||
package command
|
||||
|
||||
import (
|
||||
"context"
|
||||
"testing"
|
||||
|
||||
"github.com/caos/zitadel/internal/domain"
|
||||
caos_errs "github.com/caos/zitadel/internal/errors"
|
||||
"github.com/caos/zitadel/internal/eventstore"
|
||||
"github.com/caos/zitadel/internal/eventstore/repository"
|
||||
"github.com/caos/zitadel/internal/notification/channels/fs"
|
||||
"github.com/caos/zitadel/internal/repository/iam"
|
||||
"github.com/caos/zitadel/internal/repository/settings"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
func TestCommandSide_AddDefaultDebugNotificationProviderFile(t *testing.T) {
|
||||
type fields struct {
|
||||
eventstore *eventstore.Eventstore
|
||||
}
|
||||
type args struct {
|
||||
ctx context.Context
|
||||
provider *fs.FSConfig
|
||||
}
|
||||
type res struct {
|
||||
want *domain.ObjectDetails
|
||||
err func(error) bool
|
||||
}
|
||||
tests := []struct {
|
||||
name string
|
||||
fields fields
|
||||
args args
|
||||
res res
|
||||
}{
|
||||
{
|
||||
name: "provider already existing, already exists error",
|
||||
fields: fields{
|
||||
eventstore: eventstoreExpect(
|
||||
t,
|
||||
expectFilter(
|
||||
eventFromEventPusher(
|
||||
iam.NewDebugNotificationProviderFileAddedEvent(context.Background(),
|
||||
&iam.NewAggregate().Aggregate,
|
||||
true,
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
},
|
||||
args: args{
|
||||
ctx: context.Background(),
|
||||
provider: &fs.FSConfig{
|
||||
Compact: true,
|
||||
Enabled: true,
|
||||
},
|
||||
},
|
||||
res: res{
|
||||
err: caos_errs.IsErrorAlreadyExists,
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "add provider,ok",
|
||||
fields: fields{
|
||||
eventstore: eventstoreExpect(
|
||||
t,
|
||||
expectFilter(),
|
||||
expectPush(
|
||||
[]*repository.Event{
|
||||
eventFromEventPusher(
|
||||
iam.NewDebugNotificationProviderFileAddedEvent(context.Background(),
|
||||
&iam.NewAggregate().Aggregate,
|
||||
true,
|
||||
),
|
||||
),
|
||||
},
|
||||
),
|
||||
),
|
||||
},
|
||||
args: args{
|
||||
ctx: context.Background(),
|
||||
provider: &fs.FSConfig{
|
||||
Compact: true,
|
||||
},
|
||||
},
|
||||
res: res{
|
||||
want: &domain.ObjectDetails{
|
||||
ResourceOwner: domain.IAMID,
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
r := &Commands{
|
||||
eventstore: tt.fields.eventstore,
|
||||
}
|
||||
got, err := r.AddDebugNotificationProviderFile(tt.args.ctx, tt.args.provider)
|
||||
if tt.res.err == nil {
|
||||
assert.NoError(t, err)
|
||||
}
|
||||
if tt.res.err != nil && !tt.res.err(err) {
|
||||
t.Errorf("got wrong err: %v ", err)
|
||||
}
|
||||
if tt.res.err == nil {
|
||||
assert.Equal(t, tt.res.want, got)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestCommandSide_ChangeDebugNotificationProviderFile(t *testing.T) {
|
||||
type fields struct {
|
||||
eventstore *eventstore.Eventstore
|
||||
}
|
||||
type args struct {
|
||||
ctx context.Context
|
||||
provider *fs.FSConfig
|
||||
}
|
||||
type res struct {
|
||||
want *domain.ObjectDetails
|
||||
err func(error) bool
|
||||
}
|
||||
tests := []struct {
|
||||
name string
|
||||
fields fields
|
||||
args args
|
||||
res res
|
||||
}{
|
||||
{
|
||||
name: "provider not existing, not found error",
|
||||
fields: fields{
|
||||
eventstore: eventstoreExpect(
|
||||
t,
|
||||
expectFilter(),
|
||||
),
|
||||
},
|
||||
args: args{
|
||||
ctx: context.Background(),
|
||||
provider: &fs.FSConfig{
|
||||
Compact: true,
|
||||
Enabled: true,
|
||||
},
|
||||
},
|
||||
res: res{
|
||||
err: caos_errs.IsNotFound,
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "no changes, precondition error",
|
||||
fields: fields{
|
||||
eventstore: eventstoreExpect(
|
||||
t,
|
||||
expectFilter(
|
||||
eventFromEventPusher(
|
||||
iam.NewDebugNotificationProviderFileAddedEvent(context.Background(),
|
||||
&iam.NewAggregate().Aggregate,
|
||||
true,
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
},
|
||||
args: args{
|
||||
ctx: context.Background(),
|
||||
provider: &fs.FSConfig{
|
||||
Compact: true,
|
||||
Enabled: false,
|
||||
},
|
||||
},
|
||||
res: res{
|
||||
err: caos_errs.IsPreconditionFailed,
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "no changes enabled, precondition error",
|
||||
fields: fields{
|
||||
eventstore: eventstoreExpect(
|
||||
t,
|
||||
expectFilter(
|
||||
eventFromEventPusher(
|
||||
iam.NewDebugNotificationProviderFileAddedEvent(context.Background(),
|
||||
&iam.NewAggregate().Aggregate,
|
||||
true,
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
},
|
||||
args: args{
|
||||
ctx: context.Background(),
|
||||
provider: &fs.FSConfig{
|
||||
Compact: true,
|
||||
Enabled: true,
|
||||
},
|
||||
},
|
||||
res: res{
|
||||
err: caos_errs.IsPreconditionFailed,
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "change, ok",
|
||||
fields: fields{
|
||||
eventstore: eventstoreExpect(
|
||||
t,
|
||||
expectFilter(
|
||||
eventFromEventPusher(
|
||||
iam.NewDebugNotificationProviderFileAddedEvent(context.Background(),
|
||||
&iam.NewAggregate().Aggregate,
|
||||
true,
|
||||
),
|
||||
),
|
||||
),
|
||||
expectPush(
|
||||
[]*repository.Event{
|
||||
eventFromEventPusher(
|
||||
newDefaultDebugNotificationFileChangedEvent(context.Background(),
|
||||
false),
|
||||
),
|
||||
},
|
||||
),
|
||||
),
|
||||
},
|
||||
args: args{
|
||||
ctx: context.Background(),
|
||||
provider: &fs.FSConfig{
|
||||
Compact: false,
|
||||
Enabled: false,
|
||||
},
|
||||
},
|
||||
res: res{
|
||||
want: &domain.ObjectDetails{
|
||||
ResourceOwner: "IAM",
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
r := &Commands{
|
||||
eventstore: tt.fields.eventstore,
|
||||
}
|
||||
got, err := r.ChangeDefaultNotificationFile(tt.args.ctx, tt.args.provider)
|
||||
if tt.res.err == nil {
|
||||
assert.NoError(t, err)
|
||||
}
|
||||
if tt.res.err != nil && !tt.res.err(err) {
|
||||
t.Errorf("got wrong err: %v ", err)
|
||||
}
|
||||
if tt.res.err == nil {
|
||||
assert.Equal(t, tt.res.want, got)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestCommandSide_RemoveDebugNotificationProviderFile(t *testing.T) {
|
||||
type fields struct {
|
||||
eventstore *eventstore.Eventstore
|
||||
}
|
||||
type args struct {
|
||||
ctx context.Context
|
||||
}
|
||||
type res struct {
|
||||
want *domain.ObjectDetails
|
||||
err func(error) bool
|
||||
}
|
||||
tests := []struct {
|
||||
name string
|
||||
fields fields
|
||||
args args
|
||||
res res
|
||||
}{
|
||||
{
|
||||
name: "provider not existing, not found error",
|
||||
fields: fields{
|
||||
eventstore: eventstoreExpect(
|
||||
t,
|
||||
expectFilter(),
|
||||
),
|
||||
},
|
||||
args: args{
|
||||
ctx: context.Background(),
|
||||
},
|
||||
res: res{
|
||||
err: caos_errs.IsNotFound,
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "remove, ok",
|
||||
fields: fields{
|
||||
eventstore: eventstoreExpect(
|
||||
t,
|
||||
expectFilter(
|
||||
eventFromEventPusher(
|
||||
iam.NewDebugNotificationProviderFileAddedEvent(context.Background(),
|
||||
&iam.NewAggregate().Aggregate,
|
||||
true,
|
||||
),
|
||||
),
|
||||
),
|
||||
expectPush(
|
||||
[]*repository.Event{
|
||||
eventFromEventPusher(
|
||||
iam.NewDebugNotificationProviderFileRemovedEvent(context.Background(),
|
||||
&iam.NewAggregate().Aggregate),
|
||||
),
|
||||
},
|
||||
),
|
||||
),
|
||||
},
|
||||
args: args{
|
||||
ctx: context.Background(),
|
||||
},
|
||||
res: res{
|
||||
want: &domain.ObjectDetails{
|
||||
ResourceOwner: "IAM",
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
r := &Commands{
|
||||
eventstore: tt.fields.eventstore,
|
||||
}
|
||||
got, err := r.RemoveDefaultNotificationFile(tt.args.ctx)
|
||||
if tt.res.err == nil {
|
||||
assert.NoError(t, err)
|
||||
}
|
||||
if tt.res.err != nil && !tt.res.err(err) {
|
||||
t.Errorf("got wrong err: %v ", err)
|
||||
}
|
||||
if tt.res.err == nil {
|
||||
assert.Equal(t, tt.res.want, got)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
func newDefaultDebugNotificationFileChangedEvent(ctx context.Context, compact bool) *iam.DebugNotificationProviderFileChangedEvent {
|
||||
event, _ := iam.NewDebugNotificationProviderFileChangedEvent(ctx,
|
||||
&iam.NewAggregate().Aggregate,
|
||||
[]settings.DebugNotificationProviderChanges{
|
||||
settings.ChangeCompact(compact),
|
||||
},
|
||||
)
|
||||
return event
|
||||
}
|
115
internal/command/iam_debug_notification_log.go
Normal file
115
internal/command/iam_debug_notification_log.go
Normal file
@ -0,0 +1,115 @@
|
||||
package command
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/caos/zitadel/internal/domain"
|
||||
caos_errs "github.com/caos/zitadel/internal/errors"
|
||||
"github.com/caos/zitadel/internal/eventstore"
|
||||
"github.com/caos/zitadel/internal/notification/channels/fs"
|
||||
iam_repo "github.com/caos/zitadel/internal/repository/iam"
|
||||
"github.com/caos/zitadel/internal/telemetry/tracing"
|
||||
)
|
||||
|
||||
func (c *Commands) AddDebugNotificationProviderLog(ctx context.Context, fileSystemProvider *fs.FSConfig) (*domain.ObjectDetails, error) {
|
||||
writeModel := NewIAMDebugNotificationLogWriteModel()
|
||||
iamAgg := IAMAggregateFromWriteModel(&writeModel.WriteModel)
|
||||
events, err := c.addDefaultDebugNotificationLog(ctx, iamAgg, writeModel, fileSystemProvider)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
pushedEvents, err := c.eventstore.Push(ctx, events...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
err = AppendAndReduce(writeModel, pushedEvents...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return writeModelToObjectDetails(&writeModel.DebugNotificationWriteModel.WriteModel), nil
|
||||
}
|
||||
|
||||
func (c *Commands) addDefaultDebugNotificationLog(ctx context.Context, iamAgg *eventstore.Aggregate, addedWriteModel *IAMDebugNotificationLogWriteModel, fileSystemProvider *fs.FSConfig) ([]eventstore.Command, error) {
|
||||
err := c.eventstore.FilterToQueryReducer(ctx, addedWriteModel)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if addedWriteModel.State.Exists() {
|
||||
return nil, caos_errs.ThrowAlreadyExists(nil, "IAM-3h0fs", "Errors.IAM.DebugNotificationProvider.AlreadyExists")
|
||||
}
|
||||
|
||||
events := []eventstore.Command{
|
||||
iam_repo.NewDebugNotificationProviderLogAddedEvent(ctx,
|
||||
iamAgg,
|
||||
fileSystemProvider.Compact),
|
||||
}
|
||||
return events, nil
|
||||
}
|
||||
|
||||
func (c *Commands) ChangeDefaultNotificationLog(ctx context.Context, fileSystemProvider *fs.FSConfig) (*domain.ObjectDetails, error) {
|
||||
writeModel := NewIAMDebugNotificationLogWriteModel()
|
||||
iamAgg := IAMAggregateFromWriteModel(&writeModel.WriteModel)
|
||||
event, err := c.changeDefaultDebugNotificationProviderLog(ctx, iamAgg, writeModel, fileSystemProvider)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
pushedEvents, err := c.eventstore.Push(ctx, event)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
err = AppendAndReduce(writeModel, pushedEvents...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return writeModelToObjectDetails(&writeModel.DebugNotificationWriteModel.WriteModel), nil
|
||||
}
|
||||
|
||||
func (c *Commands) changeDefaultDebugNotificationProviderLog(ctx context.Context, iamAgg *eventstore.Aggregate, existingProvider *IAMDebugNotificationLogWriteModel, fileSystemProvider *fs.FSConfig) (eventstore.Command, error) {
|
||||
err := c.defaultDebugNotificationProviderLogWriteModelByID(ctx, existingProvider)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if !existingProvider.State.Exists() {
|
||||
return nil, caos_errs.ThrowNotFound(nil, "IAM-2h0s3", "Errors.IAM.DebugNotificationProvider.NotFound")
|
||||
}
|
||||
changedEvent, hasChanged := existingProvider.NewChangedEvent(ctx,
|
||||
iamAgg,
|
||||
fileSystemProvider.Compact)
|
||||
if !hasChanged {
|
||||
return nil, caos_errs.ThrowPreconditionFailed(nil, "IAM-fn9p3", "Errors.IAM.LoginPolicy.NotChanged")
|
||||
}
|
||||
return changedEvent, nil
|
||||
}
|
||||
|
||||
func (c *Commands) RemoveDefaultNotificationLog(ctx context.Context) (*domain.ObjectDetails, error) {
|
||||
existingProvider := NewIAMDebugNotificationLogWriteModel()
|
||||
iamAgg := IAMAggregateFromWriteModel(&existingProvider.WriteModel)
|
||||
err := c.defaultDebugNotificationProviderLogWriteModelByID(ctx, existingProvider)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if !existingProvider.State.Exists() {
|
||||
return nil, caos_errs.ThrowNotFound(nil, "IAM-39lse", "Errors.IAM.DebugNotificationProvider.NotFound")
|
||||
}
|
||||
|
||||
events, err := c.eventstore.Push(ctx, iam_repo.NewDebugNotificationProviderLogRemovedEvent(ctx, iamAgg))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
err = AppendAndReduce(existingProvider, events...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return writeModelToObjectDetails(&existingProvider.DebugNotificationWriteModel.WriteModel), nil
|
||||
}
|
||||
|
||||
func (c *Commands) defaultDebugNotificationProviderLogWriteModelByID(ctx context.Context, writeModel *IAMDebugNotificationLogWriteModel) (err error) {
|
||||
ctx, span := tracing.NewSpan(ctx)
|
||||
defer func() { span.EndWithError(err) }()
|
||||
|
||||
err = c.eventstore.FilterToQueryReducer(ctx, writeModel)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
81
internal/command/iam_debug_notification_log_model.go
Normal file
81
internal/command/iam_debug_notification_log_model.go
Normal file
@ -0,0 +1,81 @@
|
||||
package command
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/caos/zitadel/internal/eventstore"
|
||||
"github.com/caos/zitadel/internal/repository/settings"
|
||||
|
||||
"github.com/caos/zitadel/internal/domain"
|
||||
"github.com/caos/zitadel/internal/repository/iam"
|
||||
)
|
||||
|
||||
type IAMDebugNotificationLogWriteModel struct {
|
||||
DebugNotificationWriteModel
|
||||
}
|
||||
|
||||
func NewIAMDebugNotificationLogWriteModel() *IAMDebugNotificationLogWriteModel {
|
||||
return &IAMDebugNotificationLogWriteModel{
|
||||
DebugNotificationWriteModel{
|
||||
WriteModel: eventstore.WriteModel{
|
||||
AggregateID: domain.IAMID,
|
||||
ResourceOwner: domain.IAMID,
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func (wm *IAMDebugNotificationLogWriteModel) AppendEvents(events ...eventstore.Event) {
|
||||
for _, event := range events {
|
||||
switch e := event.(type) {
|
||||
case *iam.DebugNotificationProviderLogAddedEvent:
|
||||
wm.DebugNotificationWriteModel.AppendEvents(&e.DebugNotificationProviderAddedEvent)
|
||||
case *iam.DebugNotificationProviderLogChangedEvent:
|
||||
wm.DebugNotificationWriteModel.AppendEvents(&e.DebugNotificationProviderChangedEvent)
|
||||
case *iam.DebugNotificationProviderLogRemovedEvent:
|
||||
wm.DebugNotificationWriteModel.AppendEvents(&e.DebugNotificationProviderRemovedEvent)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (wm *IAMDebugNotificationLogWriteModel) IsValid() bool {
|
||||
return wm.AggregateID != ""
|
||||
}
|
||||
|
||||
func (wm *IAMDebugNotificationLogWriteModel) Reduce() error {
|
||||
return wm.DebugNotificationWriteModel.Reduce()
|
||||
}
|
||||
|
||||
func (wm *IAMDebugNotificationLogWriteModel) Query() *eventstore.SearchQueryBuilder {
|
||||
return eventstore.NewSearchQueryBuilder(eventstore.ColumnsEvent).
|
||||
ResourceOwner(wm.ResourceOwner).
|
||||
AddQuery().
|
||||
AggregateTypes(iam.AggregateType).
|
||||
AggregateIDs(wm.DebugNotificationWriteModel.AggregateID).
|
||||
EventTypes(
|
||||
iam.DebugNotificationProviderLogAddedEventType,
|
||||
iam.DebugNotificationProviderLogChangedEventType,
|
||||
iam.DebugNotificationProviderLogEnabledEventType,
|
||||
iam.DebugNotificationProviderLogDisabledEventType,
|
||||
iam.DebugNotificationProviderLogRemovedEventType).
|
||||
Builder()
|
||||
}
|
||||
|
||||
func (wm *IAMDebugNotificationLogWriteModel) NewChangedEvent(
|
||||
ctx context.Context,
|
||||
aggregate *eventstore.Aggregate,
|
||||
compact bool) (*iam.DebugNotificationProviderLogChangedEvent, bool) {
|
||||
|
||||
changes := make([]settings.DebugNotificationProviderChanges, 0)
|
||||
if wm.Compact != compact {
|
||||
changes = append(changes, settings.ChangeCompact(compact))
|
||||
}
|
||||
if len(changes) == 0 {
|
||||
return nil, false
|
||||
}
|
||||
changedEvent, err := iam.NewDebugNotificationProviderLogChangedEvent(ctx, aggregate, changes)
|
||||
if err != nil {
|
||||
return nil, false
|
||||
}
|
||||
return changedEvent, true
|
||||
}
|
389
internal/command/iam_debug_notification_log_test.go
Normal file
389
internal/command/iam_debug_notification_log_test.go
Normal file
@ -0,0 +1,389 @@
|
||||
package command
|
||||
|
||||
import (
|
||||
"context"
|
||||
"testing"
|
||||
|
||||
"github.com/caos/zitadel/internal/domain"
|
||||
caos_errs "github.com/caos/zitadel/internal/errors"
|
||||
"github.com/caos/zitadel/internal/eventstore"
|
||||
"github.com/caos/zitadel/internal/eventstore/repository"
|
||||
"github.com/caos/zitadel/internal/notification/channels/fs"
|
||||
"github.com/caos/zitadel/internal/repository/iam"
|
||||
"github.com/caos/zitadel/internal/repository/settings"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
func TestCommandSide_AddDefaultDebugNotificationProviderLog(t *testing.T) {
|
||||
type fields struct {
|
||||
eventstore *eventstore.Eventstore
|
||||
}
|
||||
type args struct {
|
||||
ctx context.Context
|
||||
provider *fs.FSConfig
|
||||
}
|
||||
type res struct {
|
||||
want *domain.ObjectDetails
|
||||
err func(error) bool
|
||||
}
|
||||
tests := []struct {
|
||||
name string
|
||||
fields fields
|
||||
args args
|
||||
res res
|
||||
}{
|
||||
{
|
||||
name: "provider already existing, already exists error",
|
||||
fields: fields{
|
||||
eventstore: eventstoreExpect(
|
||||
t,
|
||||
expectFilter(
|
||||
eventFromEventPusher(
|
||||
iam.NewDebugNotificationProviderLogAddedEvent(context.Background(),
|
||||
&iam.NewAggregate().Aggregate,
|
||||
true,
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
},
|
||||
args: args{
|
||||
ctx: context.Background(),
|
||||
provider: &fs.FSConfig{
|
||||
Compact: true,
|
||||
Enabled: true,
|
||||
},
|
||||
},
|
||||
res: res{
|
||||
err: caos_errs.IsErrorAlreadyExists,
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "add disabled provider,ok",
|
||||
fields: fields{
|
||||
eventstore: eventstoreExpect(
|
||||
t,
|
||||
expectFilter(),
|
||||
expectPush(
|
||||
[]*repository.Event{
|
||||
eventFromEventPusher(
|
||||
iam.NewDebugNotificationProviderLogAddedEvent(context.Background(),
|
||||
&iam.NewAggregate().Aggregate,
|
||||
true,
|
||||
),
|
||||
),
|
||||
},
|
||||
),
|
||||
),
|
||||
},
|
||||
args: args{
|
||||
ctx: context.Background(),
|
||||
provider: &fs.FSConfig{
|
||||
Compact: true,
|
||||
},
|
||||
},
|
||||
res: res{
|
||||
want: &domain.ObjectDetails{
|
||||
ResourceOwner: domain.IAMID,
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "add provider,ok",
|
||||
fields: fields{
|
||||
eventstore: eventstoreExpect(
|
||||
t,
|
||||
expectFilter(),
|
||||
expectPush(
|
||||
[]*repository.Event{
|
||||
eventFromEventPusher(
|
||||
iam.NewDebugNotificationProviderLogAddedEvent(context.Background(),
|
||||
&iam.NewAggregate().Aggregate,
|
||||
true,
|
||||
),
|
||||
),
|
||||
},
|
||||
),
|
||||
),
|
||||
},
|
||||
args: args{
|
||||
ctx: context.Background(),
|
||||
provider: &fs.FSConfig{
|
||||
Compact: true,
|
||||
Enabled: true,
|
||||
},
|
||||
},
|
||||
res: res{
|
||||
want: &domain.ObjectDetails{
|
||||
ResourceOwner: domain.IAMID,
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
r := &Commands{
|
||||
eventstore: tt.fields.eventstore,
|
||||
}
|
||||
got, err := r.AddDebugNotificationProviderLog(tt.args.ctx, tt.args.provider)
|
||||
if tt.res.err == nil {
|
||||
assert.NoError(t, err)
|
||||
}
|
||||
if tt.res.err != nil && !tt.res.err(err) {
|
||||
t.Errorf("got wrong err: %v ", err)
|
||||
}
|
||||
if tt.res.err == nil {
|
||||
assert.Equal(t, tt.res.want, got)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestCommandSide_ChangeDebugNotificationProviderLog(t *testing.T) {
|
||||
type fields struct {
|
||||
eventstore *eventstore.Eventstore
|
||||
}
|
||||
type args struct {
|
||||
ctx context.Context
|
||||
provider *fs.FSConfig
|
||||
}
|
||||
type res struct {
|
||||
want *domain.ObjectDetails
|
||||
err func(error) bool
|
||||
}
|
||||
tests := []struct {
|
||||
name string
|
||||
fields fields
|
||||
args args
|
||||
res res
|
||||
}{
|
||||
{
|
||||
name: "provider not existing, not found error",
|
||||
fields: fields{
|
||||
eventstore: eventstoreExpect(
|
||||
t,
|
||||
expectFilter(),
|
||||
),
|
||||
},
|
||||
args: args{
|
||||
ctx: context.Background(),
|
||||
provider: &fs.FSConfig{
|
||||
Compact: true,
|
||||
Enabled: true,
|
||||
},
|
||||
},
|
||||
res: res{
|
||||
err: caos_errs.IsNotFound,
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "no changes, precondition error",
|
||||
fields: fields{
|
||||
eventstore: eventstoreExpect(
|
||||
t,
|
||||
expectFilter(
|
||||
eventFromEventPusher(
|
||||
iam.NewDebugNotificationProviderLogAddedEvent(context.Background(),
|
||||
&iam.NewAggregate().Aggregate,
|
||||
true,
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
},
|
||||
args: args{
|
||||
ctx: context.Background(),
|
||||
provider: &fs.FSConfig{
|
||||
Compact: true,
|
||||
Enabled: false,
|
||||
},
|
||||
},
|
||||
res: res{
|
||||
err: caos_errs.IsPreconditionFailed,
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "change, ok",
|
||||
fields: fields{
|
||||
eventstore: eventstoreExpect(
|
||||
t,
|
||||
expectFilter(
|
||||
eventFromEventPusher(
|
||||
iam.NewDebugNotificationProviderLogAddedEvent(context.Background(),
|
||||
&iam.NewAggregate().Aggregate,
|
||||
true,
|
||||
),
|
||||
),
|
||||
),
|
||||
expectPush(
|
||||
[]*repository.Event{
|
||||
eventFromEventPusher(
|
||||
newDefaultDebugNotificationLogChangedEvent(context.Background(),
|
||||
false),
|
||||
),
|
||||
},
|
||||
),
|
||||
),
|
||||
},
|
||||
args: args{
|
||||
ctx: context.Background(),
|
||||
provider: &fs.FSConfig{
|
||||
Compact: false,
|
||||
Enabled: false,
|
||||
},
|
||||
},
|
||||
res: res{
|
||||
want: &domain.ObjectDetails{
|
||||
ResourceOwner: "IAM",
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "change, ok",
|
||||
fields: fields{
|
||||
eventstore: eventstoreExpect(
|
||||
t,
|
||||
expectFilter(
|
||||
eventFromEventPusher(
|
||||
iam.NewDebugNotificationProviderLogAddedEvent(context.Background(),
|
||||
&iam.NewAggregate().Aggregate,
|
||||
true,
|
||||
),
|
||||
),
|
||||
),
|
||||
expectPush(
|
||||
[]*repository.Event{
|
||||
eventFromEventPusher(
|
||||
newDefaultDebugNotificationLogChangedEvent(context.Background(),
|
||||
false),
|
||||
),
|
||||
},
|
||||
),
|
||||
),
|
||||
},
|
||||
args: args{
|
||||
ctx: context.Background(),
|
||||
provider: &fs.FSConfig{
|
||||
Compact: false,
|
||||
Enabled: true,
|
||||
},
|
||||
},
|
||||
res: res{
|
||||
want: &domain.ObjectDetails{
|
||||
ResourceOwner: "IAM",
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
r := &Commands{
|
||||
eventstore: tt.fields.eventstore,
|
||||
}
|
||||
got, err := r.ChangeDefaultNotificationLog(tt.args.ctx, tt.args.provider)
|
||||
if tt.res.err == nil {
|
||||
assert.NoError(t, err)
|
||||
}
|
||||
if tt.res.err != nil && !tt.res.err(err) {
|
||||
t.Errorf("got wrong err: %v ", err)
|
||||
}
|
||||
if tt.res.err == nil {
|
||||
assert.Equal(t, tt.res.want, got)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestCommandSide_RemoveDebugNotificationProviderLog(t *testing.T) {
|
||||
type fields struct {
|
||||
eventstore *eventstore.Eventstore
|
||||
}
|
||||
type args struct {
|
||||
ctx context.Context
|
||||
}
|
||||
type res struct {
|
||||
want *domain.ObjectDetails
|
||||
err func(error) bool
|
||||
}
|
||||
tests := []struct {
|
||||
name string
|
||||
fields fields
|
||||
args args
|
||||
res res
|
||||
}{
|
||||
{
|
||||
name: "provider not existing, not found error",
|
||||
fields: fields{
|
||||
eventstore: eventstoreExpect(
|
||||
t,
|
||||
expectFilter(),
|
||||
),
|
||||
},
|
||||
args: args{
|
||||
ctx: context.Background(),
|
||||
},
|
||||
res: res{
|
||||
err: caos_errs.IsNotFound,
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "remove, ok",
|
||||
fields: fields{
|
||||
eventstore: eventstoreExpect(
|
||||
t,
|
||||
expectFilter(
|
||||
eventFromEventPusher(
|
||||
iam.NewDebugNotificationProviderLogAddedEvent(context.Background(),
|
||||
&iam.NewAggregate().Aggregate,
|
||||
true,
|
||||
),
|
||||
),
|
||||
),
|
||||
expectPush(
|
||||
[]*repository.Event{
|
||||
eventFromEventPusher(
|
||||
iam.NewDebugNotificationProviderLogRemovedEvent(context.Background(),
|
||||
&iam.NewAggregate().Aggregate),
|
||||
),
|
||||
},
|
||||
),
|
||||
),
|
||||
},
|
||||
args: args{
|
||||
ctx: context.Background(),
|
||||
},
|
||||
res: res{
|
||||
want: &domain.ObjectDetails{
|
||||
ResourceOwner: "IAM",
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
r := &Commands{
|
||||
eventstore: tt.fields.eventstore,
|
||||
}
|
||||
got, err := r.RemoveDefaultNotificationLog(tt.args.ctx)
|
||||
if tt.res.err == nil {
|
||||
assert.NoError(t, err)
|
||||
}
|
||||
if tt.res.err != nil && !tt.res.err(err) {
|
||||
t.Errorf("got wrong err: %v ", err)
|
||||
}
|
||||
if tt.res.err == nil {
|
||||
assert.Equal(t, tt.res.want, got)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
func newDefaultDebugNotificationLogChangedEvent(ctx context.Context, compact bool) *iam.DebugNotificationProviderLogChangedEvent {
|
||||
event, _ := iam.NewDebugNotificationProviderLogChangedEvent(ctx,
|
||||
&iam.NewAggregate().Aggregate,
|
||||
[]settings.DebugNotificationProviderChanges{
|
||||
settings.ChangeCompact(compact),
|
||||
},
|
||||
)
|
||||
return event
|
||||
}
|
@ -6,7 +6,6 @@ import (
|
||||
"golang.org/x/text/language"
|
||||
|
||||
"github.com/caos/zitadel/internal/crypto"
|
||||
"github.com/caos/zitadel/internal/notification/channels/chat"
|
||||
"github.com/caos/zitadel/internal/notification/channels/fs"
|
||||
"github.com/caos/zitadel/internal/notification/channels/log"
|
||||
"github.com/caos/zitadel/internal/notification/channels/twilio"
|
||||
@ -54,9 +53,10 @@ type DomainVerification struct {
|
||||
}
|
||||
|
||||
type Notifications struct {
|
||||
DebugMode bool
|
||||
Endpoints Endpoints
|
||||
Providers Channels
|
||||
DebugMode bool
|
||||
Endpoints Endpoints
|
||||
FileSystemPath string
|
||||
//Providers Channels
|
||||
}
|
||||
|
||||
type Endpoints struct {
|
||||
@ -68,7 +68,6 @@ type Endpoints struct {
|
||||
}
|
||||
|
||||
type Channels struct {
|
||||
Chat chat.ChatConfig
|
||||
Twilio twilio.TwilioConfig
|
||||
FileSystem fs.FSConfig
|
||||
Log log.LogConfig
|
||||
|
@ -12,3 +12,26 @@ const (
|
||||
func (f NotificationType) Valid() bool {
|
||||
return f >= 0 && f < notificationCount
|
||||
}
|
||||
|
||||
type NotificationProviderState int32
|
||||
|
||||
const (
|
||||
NotificationProviderStateUnspecified NotificationProviderState = iota
|
||||
NotificationProviderStateActive
|
||||
NotificationProviderStateRemoved
|
||||
|
||||
notificationProviderCount
|
||||
)
|
||||
|
||||
func (s NotificationProviderState) Exists() bool {
|
||||
return s == NotificationProviderStateActive
|
||||
}
|
||||
|
||||
type NotificationProviderType int32
|
||||
|
||||
const (
|
||||
NotificationProviderTypeFile NotificationProviderType = iota
|
||||
NotificationProviderTypeLog
|
||||
|
||||
notificationProviderTypeCount
|
||||
)
|
||||
|
@ -1,80 +0,0 @@
|
||||
package chat
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/json"
|
||||
"io/ioutil"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"unicode/utf8"
|
||||
|
||||
"github.com/k3a/html2text"
|
||||
|
||||
"github.com/caos/logging"
|
||||
caos_errs "github.com/caos/zitadel/internal/errors"
|
||||
"github.com/caos/zitadel/internal/notification/channels"
|
||||
)
|
||||
|
||||
func InitChatChannel(config ChatConfig) (channels.NotificationChannel, error) {
|
||||
|
||||
url, err := url.Parse(config.Url)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
logging.Log("NOTIF-kSvPp").Debug("successfully initialized chat email and sms channel")
|
||||
|
||||
return channels.HandleMessageFunc(func(message channels.Message) error {
|
||||
contentText := message.GetContent()
|
||||
if config.Compact {
|
||||
contentText = html2text.HTML2Text(contentText)
|
||||
}
|
||||
for _, splittedMsg := range splitMessage(contentText, config.SplitCount) {
|
||||
if err := sendMessage(splittedMsg, url); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}), nil
|
||||
}
|
||||
|
||||
func sendMessage(message string, chatUrl *url.URL) error {
|
||||
chatMsg := &struct {
|
||||
Text string `json:"text"`
|
||||
}{Text: message}
|
||||
req, err := json.Marshal(chatMsg)
|
||||
if err != nil {
|
||||
return caos_errs.ThrowInternal(err, "PROVI-s8uie", "Could not unmarshal content")
|
||||
}
|
||||
|
||||
response, err := http.Post(chatUrl.String(), "application/json; charset=UTF-8", bytes.NewReader(req))
|
||||
if err != nil {
|
||||
return caos_errs.ThrowInternal(err, "PROVI-si93s", "unable to send message")
|
||||
}
|
||||
if response.StatusCode != 200 {
|
||||
defer response.Body.Close()
|
||||
bodyBytes, err := ioutil.ReadAll(response.Body)
|
||||
if err != nil {
|
||||
return caos_errs.ThrowInternal(err, "PROVI-PSLd3", "unable to read response message")
|
||||
}
|
||||
logging.LogWithFields("PROVI-PS0kx", "Body", string(bodyBytes)).Warn("Chat Message post didnt get 200 OK")
|
||||
return caos_errs.ThrowInternal(nil, "PROVI-LSopw", string(bodyBytes))
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func splitMessage(message string, count int) []string {
|
||||
if count == 0 {
|
||||
return []string{message}
|
||||
}
|
||||
var splits []string
|
||||
var l, r int
|
||||
for l, r = 0, count; r < len(message); l, r = r, r+count {
|
||||
for !utf8.RuneStart(message[r]) {
|
||||
r--
|
||||
}
|
||||
splits = append(splits, message[l:r])
|
||||
}
|
||||
splits = append(splits, message[l:])
|
||||
return splits
|
||||
}
|
@ -1,9 +0,0 @@
|
||||
package chat
|
||||
|
||||
type ChatConfig struct {
|
||||
// Defaults to true if DebugMode is set to true
|
||||
Enabled *bool
|
||||
Url string
|
||||
SplitCount int
|
||||
Compact bool
|
||||
}
|
@ -19,9 +19,11 @@ import (
|
||||
"github.com/caos/zitadel/internal/notification/messages"
|
||||
)
|
||||
|
||||
func InitFSChannel(config FSConfig) (channels.NotificationChannel, error) {
|
||||
|
||||
if err := os.MkdirAll(config.Path, os.ModePerm); err != nil {
|
||||
func InitFSChannel(path string, config FSConfig) (channels.NotificationChannel, error) {
|
||||
if path == "" {
|
||||
return nil, nil
|
||||
}
|
||||
if err := os.MkdirAll(path, os.ModePerm); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
@ -46,6 +48,6 @@ func InitFSChannel(config FSConfig) (channels.NotificationChannel, error) {
|
||||
return caos_errors.ThrowUnimplementedf(nil, "NOTIF-6f9a1", "filesystem provider doesn't support message type %T", message)
|
||||
}
|
||||
|
||||
return ioutil.WriteFile(filepath.Join(config.Path, fileName), []byte(content), 0666)
|
||||
return ioutil.WriteFile(filepath.Join(path, fileName), []byte(content), 0666)
|
||||
}), nil
|
||||
}
|
||||
|
@ -2,6 +2,5 @@ package fs
|
||||
|
||||
type FSConfig struct {
|
||||
Enabled bool
|
||||
Path string
|
||||
Compact bool
|
||||
}
|
||||
|
@ -24,12 +24,15 @@ type Email struct {
|
||||
|
||||
func InitSMTPChannel(ctx context.Context, getSMTPConfig func(ctx context.Context) (*EmailConfig, error)) (*Email, error) {
|
||||
smtpConfig, err := getSMTPConfig(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
client, err := smtpConfig.SMTP.connectToSMTP(smtpConfig.Tls)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
logging.Log("NOTIF-4n4Ih").Debug("successfully initialized smtp email channel")
|
||||
logging.New().Debug("successfully initialized smtp email channel")
|
||||
|
||||
return &Email{
|
||||
smtpClient: client,
|
||||
|
@ -18,10 +18,10 @@ type Config struct {
|
||||
Repository eventsourcing.Config
|
||||
}
|
||||
|
||||
func Start(config Config, systemDefaults sd.SystemDefaults, command *command.Commands, queries *query.Queries, dbClient *sql.DB, assetsPrefix string, smtpPasswordEncAlg crypto.EncryptionAlgorithm) {
|
||||
func Start(config Config, systemDefaults sd.SystemDefaults, command *command.Commands, queries *query.Queries, dbClient *sql.DB, assetsPrefix string, smtpPasswordEncAlg crypto.EncryptionAlgorithm, smsCrypto *crypto.AESCrypto) {
|
||||
statikFS, err := fs.NewWithNamespace("notification")
|
||||
logging.OnError(err).Panic("unable to start listener")
|
||||
|
||||
_, err = eventsourcing.Start(config.Repository, statikFS, systemDefaults, command, queries, dbClient, assetsPrefix, smtpPasswordEncAlg)
|
||||
_, err = eventsourcing.Start(config.Repository, statikFS, systemDefaults, command, queries, dbClient, assetsPrefix, smtpPasswordEncAlg, smsCrypto)
|
||||
logging.OnError(err).Panic("unable to start app")
|
||||
}
|
||||
|
@ -34,7 +34,7 @@ func (h *handler) Eventstore() v1.Eventstore {
|
||||
return h.es
|
||||
}
|
||||
|
||||
func Register(configs Configs, bulkLimit, errorCount uint64, view *view.View, es v1.Eventstore, command *command.Commands, queries *query.Queries, systemDefaults sd.SystemDefaults, dir http.FileSystem, assetsPrefix string, smtpPasswordEncAlg crypto.EncryptionAlgorithm) []queryv1.Handler {
|
||||
func Register(configs Configs, bulkLimit, errorCount uint64, view *view.View, es v1.Eventstore, command *command.Commands, queries *query.Queries, systemDefaults sd.SystemDefaults, dir http.FileSystem, assetsPrefix string, smtpPasswordEncAlg crypto.EncryptionAlgorithm, smsCrypto *crypto.AESCrypto) []queryv1.Handler {
|
||||
aesCrypto, err := crypto.NewAESCrypto(systemDefaults.UserVerificationKey)
|
||||
logging.OnError(err).Fatal("error create new aes crypto")
|
||||
|
||||
@ -52,6 +52,7 @@ func Register(configs Configs, bulkLimit, errorCount uint64, view *view.View, es
|
||||
dir,
|
||||
assetsPrefix,
|
||||
smtpPasswordEncAlg,
|
||||
smsCrypto,
|
||||
),
|
||||
}
|
||||
}
|
||||
|
@ -7,6 +7,9 @@ import (
|
||||
"time"
|
||||
|
||||
"github.com/caos/logging"
|
||||
"github.com/caos/zitadel/internal/notification/channels/fs"
|
||||
"github.com/caos/zitadel/internal/notification/channels/log"
|
||||
"github.com/caos/zitadel/internal/notification/channels/twilio"
|
||||
|
||||
"github.com/caos/zitadel/internal/api/authz"
|
||||
"github.com/caos/zitadel/internal/command"
|
||||
@ -43,18 +46,10 @@ type Notification struct {
|
||||
assetsPrefix string
|
||||
queries *query.Queries
|
||||
smtpPasswordCrypto crypto.EncryptionAlgorithm
|
||||
smsTokenCrypto crypto.EncryptionAlgorithm
|
||||
}
|
||||
|
||||
func newNotification(
|
||||
handler handler,
|
||||
command *command.Commands,
|
||||
query *query.Queries,
|
||||
defaults sd.SystemDefaults,
|
||||
aesCrypto crypto.EncryptionAlgorithm,
|
||||
statikDir http.FileSystem,
|
||||
assetsPrefix string,
|
||||
smtpPasswordEncAlg crypto.EncryptionAlgorithm,
|
||||
) *Notification {
|
||||
func newNotification(handler handler, command *command.Commands, query *query.Queries, defaults sd.SystemDefaults, aesCrypto crypto.EncryptionAlgorithm, statikDir http.FileSystem, assetsPrefix string, smtpPasswordEncAlg crypto.EncryptionAlgorithm, smsCrypto *crypto.AESCrypto) *Notification {
|
||||
h := &Notification{
|
||||
handler: handler,
|
||||
command: command,
|
||||
@ -64,6 +59,7 @@ func newNotification(
|
||||
assetsPrefix: assetsPrefix,
|
||||
queries: query,
|
||||
smtpPasswordCrypto: smtpPasswordEncAlg,
|
||||
smsTokenCrypto: smsCrypto,
|
||||
}
|
||||
|
||||
h.subscribe()
|
||||
@ -165,7 +161,7 @@ func (n *Notification) handleInitUserCode(event *models.Event) (err error) {
|
||||
return err
|
||||
}
|
||||
|
||||
err = types.SendUserInitCode(ctx, string(template.Template), translator, user, initCode, n.systemDefaults, n.getSMTPConfig, n.AesCrypto, colors, n.assetsPrefix)
|
||||
err = types.SendUserInitCode(ctx, string(template.Template), translator, user, initCode, n.systemDefaults, n.getSMTPConfig, n.getFileSystemProvider, n.getLogProvider, n.AesCrypto, colors, n.assetsPrefix)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@ -203,7 +199,7 @@ func (n *Notification) handlePasswordCode(event *models.Event) (err error) {
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
err = types.SendPasswordCode(ctx, string(template.Template), translator, user, pwCode, n.systemDefaults, n.getSMTPConfig, n.AesCrypto, colors, n.assetsPrefix)
|
||||
err = types.SendPasswordCode(ctx, string(template.Template), translator, user, pwCode, n.systemDefaults, n.getSMTPConfig, n.getTwilioConfig, n.getFileSystemProvider, n.getLogProvider, n.AesCrypto, colors, n.assetsPrefix)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@ -242,7 +238,7 @@ func (n *Notification) handleEmailVerificationCode(event *models.Event) (err err
|
||||
return err
|
||||
}
|
||||
|
||||
err = types.SendEmailVerificationCode(ctx, string(template.Template), translator, user, emailCode, n.systemDefaults, n.getSMTPConfig, n.AesCrypto, colors, n.assetsPrefix)
|
||||
err = types.SendEmailVerificationCode(ctx, string(template.Template), translator, user, emailCode, n.systemDefaults, n.getSMTPConfig, n.getFileSystemProvider, n.getLogProvider, n.AesCrypto, colors, n.assetsPrefix)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@ -268,7 +264,7 @@ func (n *Notification) handlePhoneVerificationCode(event *models.Event) (err err
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
err = types.SendPhoneVerificationCode(translator, user, phoneCode, n.systemDefaults, n.AesCrypto)
|
||||
err = types.SendPhoneVerificationCode(context.Background(), translator, user, phoneCode, n.systemDefaults, n.getTwilioConfig, n.getFileSystemProvider, n.getLogProvider, n.AesCrypto)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@ -308,7 +304,7 @@ func (n *Notification) handleDomainClaimed(event *models.Event) (err error) {
|
||||
return err
|
||||
}
|
||||
|
||||
err = types.SendDomainClaimed(ctx, string(template.Template), translator, user, data["userName"], n.systemDefaults, n.getSMTPConfig, colors, n.assetsPrefix)
|
||||
err = types.SendDomainClaimed(ctx, string(template.Template), translator, user, data["userName"], n.systemDefaults, n.getSMTPConfig, n.getFileSystemProvider, n.getLogProvider, colors, n.assetsPrefix)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@ -355,7 +351,7 @@ func (n *Notification) handlePasswordlessRegistrationLink(event *models.Event) (
|
||||
return err
|
||||
}
|
||||
|
||||
err = types.SendPasswordlessRegistrationLink(ctx, string(template.Template), translator, user, addedEvent, n.systemDefaults, n.getSMTPConfig, n.AesCrypto, colors, n.assetsPrefix)
|
||||
err = types.SendPasswordlessRegistrationLink(ctx, string(template.Template), translator, user, addedEvent, n.systemDefaults, n.getSMTPConfig, n.getFileSystemProvider, n.getLogProvider, n.AesCrypto, colors, n.assetsPrefix)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@ -394,7 +390,7 @@ func (n *Notification) getUserEvents(userID string, sequence uint64) ([]*models.
|
||||
}
|
||||
|
||||
func (n *Notification) OnError(event *models.Event, err error) error {
|
||||
logging.LogWithFields("SPOOL-s9opc", "id", event.AggregateID, "sequence", event.Sequence).WithError(err).Warn("something went wrong in notification handler")
|
||||
logging.WithFields("id", event.AggregateID, "sequence", event.Sequence).WithError(err).Warn("something went wrong in notification handler")
|
||||
return spooler.HandleError(event, err, n.view.GetLatestNotificationFailedEvent, n.view.ProcessedNotificationFailedEvent, n.view.ProcessedNotificationSequence, n.errorCountUntilSkip)
|
||||
}
|
||||
|
||||
@ -437,6 +433,48 @@ func (n *Notification) getSMTPConfig(ctx context.Context) (*smtp.EmailConfig, er
|
||||
}, nil
|
||||
}
|
||||
|
||||
// Read iam twilio config
|
||||
func (n *Notification) getTwilioConfig(ctx context.Context) (*twilio.TwilioConfig, error) {
|
||||
config, err := n.queries.SMSProviderConfigByID(ctx, domain.IAMID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if config.TwilioConfig == nil {
|
||||
return nil, errors.ThrowNotFound(nil, "HANDLER-8nfow", "Errors.SMS.Twilio.NotFound")
|
||||
}
|
||||
token, err := crypto.Decrypt(config.TwilioConfig.Token, n.smtpPasswordCrypto)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &twilio.TwilioConfig{
|
||||
SID: config.TwilioConfig.SID,
|
||||
Token: string(token),
|
||||
SenderNumber: config.TwilioConfig.SenderNumber,
|
||||
}, nil
|
||||
}
|
||||
|
||||
// Read iam filesystem provider config
|
||||
func (n *Notification) getFileSystemProvider(ctx context.Context) (*fs.FSConfig, error) {
|
||||
config, err := n.queries.NotificationProviderByIDAndType(ctx, domain.IAMID, domain.NotificationProviderTypeFile)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &fs.FSConfig{
|
||||
Compact: config.Compact,
|
||||
}, nil
|
||||
}
|
||||
|
||||
// Read iam log provider config
|
||||
func (n *Notification) getLogProvider(ctx context.Context) (*log.LogConfig, error) {
|
||||
config, err := n.queries.NotificationProviderByIDAndType(ctx, domain.IAMID, domain.NotificationProviderTypeLog)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &log.LogConfig{
|
||||
Compact: config.Compact,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (n *Notification) getTranslatorWithOrgTexts(orgID, textType string) (*i18n.Translator, error) {
|
||||
ctx := context.Background()
|
||||
translator, err := i18n.NewTranslator(n.statikDir, i18n.TranslatorConfig{DefaultLanguage: n.queries.GetDefaultLanguage(ctx)})
|
||||
|
@ -22,7 +22,7 @@ type EsRepository struct {
|
||||
spooler *es_spol.Spooler
|
||||
}
|
||||
|
||||
func Start(conf Config, dir http.FileSystem, systemDefaults sd.SystemDefaults, command *command.Commands, queries *query.Queries, dbClient *sql.DB, assetsPrefix string, smtpPasswordEncAlg crypto.EncryptionAlgorithm) (*EsRepository, error) {
|
||||
func Start(conf Config, dir http.FileSystem, systemDefaults sd.SystemDefaults, command *command.Commands, queries *query.Queries, dbClient *sql.DB, assetsPrefix string, smtpPasswordEncAlg crypto.EncryptionAlgorithm, smsCrypto *crypto.AESCrypto) (*EsRepository, error) {
|
||||
es, err := v1.Start(dbClient)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@ -33,7 +33,7 @@ func Start(conf Config, dir http.FileSystem, systemDefaults sd.SystemDefaults, c
|
||||
return nil, err
|
||||
}
|
||||
|
||||
spool := spooler.StartSpooler(conf.Spooler, es, view, dbClient, command, queries, systemDefaults, dir, assetsPrefix, smtpPasswordEncAlg)
|
||||
spool := spooler.StartSpooler(conf.Spooler, es, view, dbClient, command, queries, systemDefaults, dir, assetsPrefix, smtpPasswordEncAlg, smsCrypto)
|
||||
|
||||
return &EsRepository{
|
||||
spool,
|
||||
|
@ -21,12 +21,12 @@ type SpoolerConfig struct {
|
||||
Handlers handler.Configs
|
||||
}
|
||||
|
||||
func StartSpooler(c SpoolerConfig, es v1.Eventstore, view *view.View, sql *sql.DB, command *command.Commands, queries *query.Queries, systemDefaults sd.SystemDefaults, dir http.FileSystem, assetsPrefix string, smtpPasswordEncAlg crypto.EncryptionAlgorithm) *spooler.Spooler {
|
||||
func StartSpooler(c SpoolerConfig, es v1.Eventstore, view *view.View, sql *sql.DB, command *command.Commands, queries *query.Queries, systemDefaults sd.SystemDefaults, dir http.FileSystem, assetsPrefix string, smtpPasswordEncAlg crypto.EncryptionAlgorithm, smsCrypto *crypto.AESCrypto) *spooler.Spooler {
|
||||
spoolerConfig := spooler.Config{
|
||||
Eventstore: es,
|
||||
Locker: &locker{dbClient: sql},
|
||||
ConcurrentWorkers: c.ConcurrentWorkers,
|
||||
ViewHandlers: handler.Register(c.Handlers, c.BulkLimit, c.FailureCountUntilSkip, view, es, command, queries, systemDefaults, dir, assetsPrefix, smtpPasswordEncAlg),
|
||||
ViewHandlers: handler.Register(c.Handlers, c.BulkLimit, c.FailureCountUntilSkip, view, es, command, queries, systemDefaults, dir, assetsPrefix, smtpPasswordEncAlg, smsCrypto),
|
||||
}
|
||||
spool := spoolerConfig.New()
|
||||
spool.Start()
|
||||
|
@ -22,3 +22,7 @@ func (c *Chain) HandleMessage(message channels.Message) error {
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *Chain) Len() int {
|
||||
return len(c.channels)
|
||||
}
|
||||
|
@ -1,45 +1,28 @@
|
||||
package senders
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/caos/zitadel/internal/config/systemdefaults"
|
||||
"github.com/caos/zitadel/internal/notification/channels"
|
||||
"github.com/caos/zitadel/internal/notification/channels/chat"
|
||||
"github.com/caos/zitadel/internal/notification/channels/fs"
|
||||
"github.com/caos/zitadel/internal/notification/channels/log"
|
||||
)
|
||||
|
||||
func debugChannels(config systemdefaults.Notifications) (channels.NotificationChannel, error) {
|
||||
|
||||
func debugChannels(ctx context.Context, config systemdefaults.Notifications, getFileSystemProvider func(ctx context.Context) (*fs.FSConfig, error), getLogProvider func(ctx context.Context) (*log.LogConfig, error)) (*Chain, error) {
|
||||
var (
|
||||
providers []channels.NotificationChannel
|
||||
enableChat bool
|
||||
providers []channels.NotificationChannel
|
||||
)
|
||||
|
||||
if config.Providers.Chat.Enabled != nil {
|
||||
enableChat = *config.Providers.Chat.Enabled
|
||||
} else {
|
||||
// ensures backward compatible configuration
|
||||
enableChat = config.DebugMode
|
||||
}
|
||||
|
||||
if enableChat {
|
||||
p, err := chat.InitChatChannel(config.Providers.Chat)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
if fsProvider, err := getFileSystemProvider(ctx); err == nil {
|
||||
p, err := fs.InitFSChannel(config.FileSystemPath, *fsProvider)
|
||||
if err == nil {
|
||||
providers = append(providers, p)
|
||||
}
|
||||
providers = append(providers, p)
|
||||
}
|
||||
|
||||
if config.Providers.FileSystem.Enabled {
|
||||
p, err := fs.InitFSChannel(config.Providers.FileSystem)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
providers = append(providers, p)
|
||||
}
|
||||
|
||||
if config.Providers.Log.Enabled {
|
||||
providers = append(providers, log.InitStdoutChannel(config.Providers.Log))
|
||||
if logProvider, err := getLogProvider(ctx); err == nil {
|
||||
providers = append(providers, log.InitStdoutChannel(*logProvider))
|
||||
}
|
||||
|
||||
return chainChannels(providers...), nil
|
||||
|
@ -3,25 +3,21 @@ package senders
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/caos/logging"
|
||||
"github.com/caos/zitadel/internal/config/systemdefaults"
|
||||
"github.com/caos/zitadel/internal/notification/channels"
|
||||
"github.com/caos/zitadel/internal/notification/channels/fs"
|
||||
"github.com/caos/zitadel/internal/notification/channels/log"
|
||||
"github.com/caos/zitadel/internal/notification/channels/smtp"
|
||||
)
|
||||
|
||||
func EmailChannels(ctx context.Context, config systemdefaults.Notifications, emailConfig func(ctx context.Context) (*smtp.EmailConfig, error)) (channels.NotificationChannel, error) {
|
||||
|
||||
debug, err := debugChannels(config)
|
||||
func EmailChannels(ctx context.Context, config systemdefaults.Notifications, emailConfig func(ctx context.Context) (*smtp.EmailConfig, error), getFileSystemProvider func(ctx context.Context) (*fs.FSConfig, error), getLogProvider func(ctx context.Context) (*log.LogConfig, error)) (chain *Chain, err error) {
|
||||
p, err := smtp.InitSMTPChannel(ctx, emailConfig)
|
||||
if err == nil {
|
||||
chain.channels = append(chain.channels, p)
|
||||
}
|
||||
chain, err = debugChannels(ctx, config, getFileSystemProvider, getLogProvider)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
logging.New().Info("Error in creating debug channels")
|
||||
}
|
||||
|
||||
if !config.DebugMode {
|
||||
p, err := smtp.InitSMTPChannel(ctx, emailConfig)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return chainChannels(debug, p), nil
|
||||
}
|
||||
|
||||
return debug, nil
|
||||
return chain, nil
|
||||
}
|
||||
|
@ -1,21 +1,21 @@
|
||||
package senders
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/caos/zitadel/internal/config/systemdefaults"
|
||||
"github.com/caos/zitadel/internal/notification/channels"
|
||||
"github.com/caos/zitadel/internal/notification/channels/fs"
|
||||
"github.com/caos/zitadel/internal/notification/channels/log"
|
||||
"github.com/caos/zitadel/internal/notification/channels/twilio"
|
||||
)
|
||||
|
||||
func SMSChannels(config systemdefaults.Notifications) (channels.NotificationChannel, error) {
|
||||
|
||||
debug, err := debugChannels(config)
|
||||
func SMSChannels(ctx context.Context, config systemdefaults.Notifications, twilioConfig *twilio.TwilioConfig, getFileSystemProvider func(ctx context.Context) (*fs.FSConfig, error), getLogProvider func(ctx context.Context) (*log.LogConfig, error)) (chain *Chain, err error) {
|
||||
if twilioConfig != nil {
|
||||
chain.channels = append(chain.channels, twilio.InitTwilioChannel(*twilioConfig))
|
||||
}
|
||||
chain, err = debugChannels(ctx, config, getFileSystemProvider, getLogProvider)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if !config.DebugMode {
|
||||
return chainChannels(debug, twilio.InitTwilioChannel(config.Providers.Twilio)), nil
|
||||
}
|
||||
|
||||
return debug, nil
|
||||
return chain, nil
|
||||
}
|
||||
|
@ -7,6 +7,8 @@ import (
|
||||
"github.com/caos/zitadel/internal/config/systemdefaults"
|
||||
"github.com/caos/zitadel/internal/domain"
|
||||
"github.com/caos/zitadel/internal/i18n"
|
||||
"github.com/caos/zitadel/internal/notification/channels/fs"
|
||||
"github.com/caos/zitadel/internal/notification/channels/log"
|
||||
"github.com/caos/zitadel/internal/notification/channels/smtp"
|
||||
"github.com/caos/zitadel/internal/notification/templates"
|
||||
"github.com/caos/zitadel/internal/query"
|
||||
@ -18,7 +20,7 @@ type DomainClaimedData struct {
|
||||
URL string
|
||||
}
|
||||
|
||||
func SendDomainClaimed(ctx context.Context, mailhtml string, translator *i18n.Translator, user *view_model.NotifyUser, username string, systemDefaults systemdefaults.SystemDefaults, emailConfig func(ctx context.Context) (*smtp.EmailConfig, error), colors *query.LabelPolicy, assetsPrefix string) error {
|
||||
func SendDomainClaimed(ctx context.Context, mailhtml string, translator *i18n.Translator, user *view_model.NotifyUser, username string, systemDefaults systemdefaults.SystemDefaults, emailConfig func(ctx context.Context) (*smtp.EmailConfig, error), getFileSystemProvider func(ctx context.Context) (*fs.FSConfig, error), getLogProvider func(ctx context.Context) (*log.LogConfig, error), colors *query.LabelPolicy, assetsPrefix string) error {
|
||||
url, err := templates.ParseTemplateText(systemDefaults.Notifications.Endpoints.DomainClaimed, &UrlData{UserID: user.ID})
|
||||
if err != nil {
|
||||
return err
|
||||
@ -35,5 +37,5 @@ func SendDomainClaimed(ctx context.Context, mailhtml string, translator *i18n.Tr
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return generateEmail(ctx, user, domainClaimedData.Subject, template, systemDefaults.Notifications, emailConfig, true)
|
||||
return generateEmail(ctx, user, domainClaimedData.Subject, template, systemDefaults.Notifications, emailConfig, getFileSystemProvider, getLogProvider, true)
|
||||
}
|
||||
|
@ -7,6 +7,8 @@ import (
|
||||
"github.com/caos/zitadel/internal/crypto"
|
||||
"github.com/caos/zitadel/internal/domain"
|
||||
"github.com/caos/zitadel/internal/i18n"
|
||||
"github.com/caos/zitadel/internal/notification/channels/fs"
|
||||
"github.com/caos/zitadel/internal/notification/channels/log"
|
||||
"github.com/caos/zitadel/internal/notification/channels/smtp"
|
||||
"github.com/caos/zitadel/internal/notification/templates"
|
||||
"github.com/caos/zitadel/internal/query"
|
||||
@ -19,7 +21,7 @@ type EmailVerificationCodeData struct {
|
||||
URL string
|
||||
}
|
||||
|
||||
func SendEmailVerificationCode(ctx context.Context, mailhtml string, translator *i18n.Translator, user *view_model.NotifyUser, code *es_model.EmailCode, systemDefaults systemdefaults.SystemDefaults, smtpConfig func(ctx context.Context) (*smtp.EmailConfig, error), alg crypto.EncryptionAlgorithm, colors *query.LabelPolicy, assetsPrefix string) error {
|
||||
func SendEmailVerificationCode(ctx context.Context, mailhtml string, translator *i18n.Translator, user *view_model.NotifyUser, code *es_model.EmailCode, systemDefaults systemdefaults.SystemDefaults, smtpConfig func(ctx context.Context) (*smtp.EmailConfig, error), getFileSystemProvider func(ctx context.Context) (*fs.FSConfig, error), getLogProvider func(ctx context.Context) (*log.LogConfig, error), alg crypto.EncryptionAlgorithm, colors *query.LabelPolicy, assetsPrefix string) error {
|
||||
codeString, err := crypto.DecryptString(code.Code, alg)
|
||||
if err != nil {
|
||||
return err
|
||||
@ -41,5 +43,5 @@ func SendEmailVerificationCode(ctx context.Context, mailhtml string, translator
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return generateEmail(ctx, user, emailCodeData.Subject, template, systemDefaults.Notifications, smtpConfig, true)
|
||||
return generateEmail(ctx, user, emailCodeData.Subject, template, systemDefaults.Notifications, smtpConfig, getFileSystemProvider, getLogProvider, true)
|
||||
}
|
||||
|
@ -7,6 +7,8 @@ import (
|
||||
"github.com/caos/zitadel/internal/crypto"
|
||||
"github.com/caos/zitadel/internal/domain"
|
||||
"github.com/caos/zitadel/internal/i18n"
|
||||
"github.com/caos/zitadel/internal/notification/channels/fs"
|
||||
"github.com/caos/zitadel/internal/notification/channels/log"
|
||||
"github.com/caos/zitadel/internal/notification/channels/smtp"
|
||||
"github.com/caos/zitadel/internal/notification/templates"
|
||||
"github.com/caos/zitadel/internal/query"
|
||||
@ -25,7 +27,7 @@ type UrlData struct {
|
||||
PasswordSet bool
|
||||
}
|
||||
|
||||
func SendUserInitCode(ctx context.Context, mailhtml string, translator *i18n.Translator, user *view_model.NotifyUser, code *es_model.InitUserCode, systemDefaults systemdefaults.SystemDefaults, smtpConfig func(ctx context.Context) (*smtp.EmailConfig, error), alg crypto.EncryptionAlgorithm, colors *query.LabelPolicy, assetsPrefix string) error {
|
||||
func SendUserInitCode(ctx context.Context, mailhtml string, translator *i18n.Translator, user *view_model.NotifyUser, code *es_model.InitUserCode, systemDefaults systemdefaults.SystemDefaults, smtpConfig func(ctx context.Context) (*smtp.EmailConfig, error), getFileSystemProvider func(ctx context.Context) (*fs.FSConfig, error), getLogProvider func(ctx context.Context) (*log.LogConfig, error), alg crypto.EncryptionAlgorithm, colors *query.LabelPolicy, assetsPrefix string) error {
|
||||
codeString, err := crypto.DecryptString(code.Code, alg)
|
||||
if err != nil {
|
||||
return err
|
||||
@ -45,5 +47,5 @@ func SendUserInitCode(ctx context.Context, mailhtml string, translator *i18n.Tra
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return generateEmail(ctx, user, initCodeData.Subject, template, systemDefaults.Notifications, smtpConfig, true)
|
||||
return generateEmail(ctx, user, initCodeData.Subject, template, systemDefaults.Notifications, smtpConfig, getFileSystemProvider, getLogProvider, true)
|
||||
}
|
||||
|
@ -7,7 +7,10 @@ import (
|
||||
"github.com/caos/zitadel/internal/crypto"
|
||||
"github.com/caos/zitadel/internal/domain"
|
||||
"github.com/caos/zitadel/internal/i18n"
|
||||
"github.com/caos/zitadel/internal/notification/channels/fs"
|
||||
"github.com/caos/zitadel/internal/notification/channels/log"
|
||||
"github.com/caos/zitadel/internal/notification/channels/smtp"
|
||||
"github.com/caos/zitadel/internal/notification/channels/twilio"
|
||||
"github.com/caos/zitadel/internal/notification/templates"
|
||||
"github.com/caos/zitadel/internal/query"
|
||||
es_model "github.com/caos/zitadel/internal/user/repository/eventsourcing/model"
|
||||
@ -21,7 +24,7 @@ type PasswordCodeData struct {
|
||||
URL string
|
||||
}
|
||||
|
||||
func SendPasswordCode(ctx context.Context, mailhtml string, translator *i18n.Translator, user *view_model.NotifyUser, code *es_model.PasswordCode, systemDefaults systemdefaults.SystemDefaults, smtpConfig func(ctx context.Context) (*smtp.EmailConfig, error), alg crypto.EncryptionAlgorithm, colors *query.LabelPolicy, assetsPrefix string) error {
|
||||
func SendPasswordCode(ctx context.Context, mailhtml string, translator *i18n.Translator, user *view_model.NotifyUser, code *es_model.PasswordCode, systemDefaults systemdefaults.SystemDefaults, smtpConfig func(ctx context.Context) (*smtp.EmailConfig, error), getTwilioConfig func(ctx context.Context) (*twilio.TwilioConfig, error), getFileSystemProvider func(ctx context.Context) (*fs.FSConfig, error), getLogProvider func(ctx context.Context) (*log.LogConfig, error), alg crypto.EncryptionAlgorithm, colors *query.LabelPolicy, assetsPrefix string) error {
|
||||
codeString, err := crypto.DecryptString(code.Code, alg)
|
||||
if err != nil {
|
||||
return err
|
||||
@ -44,8 +47,8 @@ func SendPasswordCode(ctx context.Context, mailhtml string, translator *i18n.Tra
|
||||
return err
|
||||
}
|
||||
if code.NotificationType == int32(domain.NotificationTypeSms) {
|
||||
return generateSms(user, passwordResetData.Text, systemDefaults.Notifications, false)
|
||||
return generateSms(ctx, user, passwordResetData.Text, systemDefaults.Notifications, getTwilioConfig, getFileSystemProvider, getLogProvider, false)
|
||||
}
|
||||
return generateEmail(ctx, user, passwordResetData.Subject, template, systemDefaults.Notifications, smtpConfig, true)
|
||||
return generateEmail(ctx, user, passwordResetData.Subject, template, systemDefaults.Notifications, smtpConfig, getFileSystemProvider, getLogProvider, true)
|
||||
|
||||
}
|
||||
|
@ -7,6 +7,8 @@ import (
|
||||
"github.com/caos/zitadel/internal/crypto"
|
||||
"github.com/caos/zitadel/internal/domain"
|
||||
"github.com/caos/zitadel/internal/i18n"
|
||||
"github.com/caos/zitadel/internal/notification/channels/fs"
|
||||
"github.com/caos/zitadel/internal/notification/channels/log"
|
||||
"github.com/caos/zitadel/internal/notification/channels/smtp"
|
||||
"github.com/caos/zitadel/internal/notification/templates"
|
||||
"github.com/caos/zitadel/internal/query"
|
||||
@ -19,7 +21,7 @@ type PasswordlessRegistrationLinkData struct {
|
||||
URL string
|
||||
}
|
||||
|
||||
func SendPasswordlessRegistrationLink(ctx context.Context, mailhtml string, translator *i18n.Translator, user *view_model.NotifyUser, code *user.HumanPasswordlessInitCodeRequestedEvent, systemDefaults systemdefaults.SystemDefaults, smtpConfig func(ctx context.Context) (*smtp.EmailConfig, error), alg crypto.EncryptionAlgorithm, colors *query.LabelPolicy, assetsPrefix string) error {
|
||||
func SendPasswordlessRegistrationLink(ctx context.Context, mailhtml string, translator *i18n.Translator, user *view_model.NotifyUser, code *user.HumanPasswordlessInitCodeRequestedEvent, systemDefaults systemdefaults.SystemDefaults, smtpConfig func(ctx context.Context) (*smtp.EmailConfig, error), getFileSystemProvider func(ctx context.Context) (*fs.FSConfig, error), getLogProvider func(ctx context.Context) (*log.LogConfig, error), alg crypto.EncryptionAlgorithm, colors *query.LabelPolicy, assetsPrefix string) error {
|
||||
codeString, err := crypto.DecryptString(code.Code, alg)
|
||||
if err != nil {
|
||||
return err
|
||||
@ -36,5 +38,5 @@ func SendPasswordlessRegistrationLink(ctx context.Context, mailhtml string, tran
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return generateEmail(ctx, user, emailCodeData.Subject, template, systemDefaults.Notifications, smtpConfig, true)
|
||||
return generateEmail(ctx, user, emailCodeData.Subject, template, systemDefaults.Notifications, smtpConfig, getFileSystemProvider, getLogProvider, true)
|
||||
}
|
||||
|
@ -1,12 +1,16 @@
|
||||
package types
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
|
||||
"github.com/caos/zitadel/internal/config/systemdefaults"
|
||||
"github.com/caos/zitadel/internal/crypto"
|
||||
"github.com/caos/zitadel/internal/domain"
|
||||
"github.com/caos/zitadel/internal/i18n"
|
||||
"github.com/caos/zitadel/internal/notification/channels/fs"
|
||||
"github.com/caos/zitadel/internal/notification/channels/log"
|
||||
"github.com/caos/zitadel/internal/notification/channels/twilio"
|
||||
"github.com/caos/zitadel/internal/notification/templates"
|
||||
es_model "github.com/caos/zitadel/internal/user/repository/eventsourcing/model"
|
||||
view_model "github.com/caos/zitadel/internal/user/repository/view/model"
|
||||
@ -16,7 +20,7 @@ type PhoneVerificationCodeData struct {
|
||||
UserID string
|
||||
}
|
||||
|
||||
func SendPhoneVerificationCode(translator *i18n.Translator, user *view_model.NotifyUser, code *es_model.PhoneCode, systemDefaults systemdefaults.SystemDefaults, alg crypto.EncryptionAlgorithm) error {
|
||||
func SendPhoneVerificationCode(ctx context.Context, translator *i18n.Translator, user *view_model.NotifyUser, code *es_model.PhoneCode, systemDefaults systemdefaults.SystemDefaults, getTwilioConfig func(ctx context.Context) (*twilio.TwilioConfig, error), getFileSystemProvider func(ctx context.Context) (*fs.FSConfig, error), getLogProvider func(ctx context.Context) (*log.LogConfig, error), alg crypto.EncryptionAlgorithm) error {
|
||||
codeString, err := crypto.DecryptString(code.Code, alg)
|
||||
if err != nil {
|
||||
return err
|
||||
@ -31,5 +35,5 @@ func SendPhoneVerificationCode(translator *i18n.Translator, user *view_model.Not
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return generateSms(user, template, systemDefaults.Notifications, true)
|
||||
return generateSms(ctx, user, template, systemDefaults.Notifications, getTwilioConfig, getFileSystemProvider, getLogProvider, true)
|
||||
}
|
||||
|
@ -4,6 +4,9 @@ import (
|
||||
"context"
|
||||
"html"
|
||||
|
||||
caos_errors "github.com/caos/zitadel/internal/errors"
|
||||
"github.com/caos/zitadel/internal/notification/channels/fs"
|
||||
"github.com/caos/zitadel/internal/notification/channels/log"
|
||||
"github.com/caos/zitadel/internal/notification/channels/smtp"
|
||||
"github.com/caos/zitadel/internal/notification/messages"
|
||||
"github.com/caos/zitadel/internal/notification/senders"
|
||||
@ -12,7 +15,7 @@ import (
|
||||
view_model "github.com/caos/zitadel/internal/user/repository/view/model"
|
||||
)
|
||||
|
||||
func generateEmail(ctx context.Context, user *view_model.NotifyUser, subject, content string, config systemdefaults.Notifications, smtpConfig func(ctx context.Context) (*smtp.EmailConfig, error), lastEmail bool) error {
|
||||
func generateEmail(ctx context.Context, user *view_model.NotifyUser, subject, content string, config systemdefaults.Notifications, smtpConfig func(ctx context.Context) (*smtp.EmailConfig, error), getFileSystemProvider func(ctx context.Context) (*fs.FSConfig, error), getLogProvider func(ctx context.Context) (*log.LogConfig, error), lastEmail bool) error {
|
||||
content = html.UnescapeString(content)
|
||||
message := &messages.Email{
|
||||
Recipients: []string{user.VerifiedEmail},
|
||||
@ -23,12 +26,15 @@ func generateEmail(ctx context.Context, user *view_model.NotifyUser, subject, co
|
||||
message.Recipients = []string{user.LastEmail}
|
||||
}
|
||||
|
||||
channels, err := senders.EmailChannels(ctx, config, smtpConfig)
|
||||
channelChain, err := senders.EmailChannels(ctx, config, smtpConfig, getFileSystemProvider, getLogProvider)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return channels.HandleMessage(message)
|
||||
if channelChain.Len() == 0 {
|
||||
return caos_errors.ThrowPreconditionFailed(nil, "MAIL-83nof", "Errors.Notification.Channels.NotPresent")
|
||||
}
|
||||
return channelChain.HandleMessage(message)
|
||||
}
|
||||
|
||||
func mapNotifyUserToArgs(user *view_model.NotifyUser) map[string]interface{} {
|
||||
|
@ -1,15 +1,26 @@
|
||||
package types
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/caos/zitadel/internal/config/systemdefaults"
|
||||
caos_errors "github.com/caos/zitadel/internal/errors"
|
||||
"github.com/caos/zitadel/internal/notification/channels/fs"
|
||||
"github.com/caos/zitadel/internal/notification/channels/log"
|
||||
"github.com/caos/zitadel/internal/notification/channels/twilio"
|
||||
"github.com/caos/zitadel/internal/notification/messages"
|
||||
"github.com/caos/zitadel/internal/notification/senders"
|
||||
view_model "github.com/caos/zitadel/internal/user/repository/view/model"
|
||||
)
|
||||
|
||||
func generateSms(user *view_model.NotifyUser, content string, config systemdefaults.Notifications, lastPhone bool) error {
|
||||
func generateSms(ctx context.Context, user *view_model.NotifyUser, content string, config systemdefaults.Notifications, getTwilioProvider func(ctx context.Context) (*twilio.TwilioConfig, error), getFileSystemProvider func(ctx context.Context) (*fs.FSConfig, error), getLogProvider func(ctx context.Context) (*log.LogConfig, error), lastPhone bool) error {
|
||||
number := ""
|
||||
twilio, err := getTwilioProvider(ctx)
|
||||
if err == nil {
|
||||
number = twilio.SenderNumber
|
||||
}
|
||||
message := &messages.SMS{
|
||||
SenderPhoneNumber: config.Providers.Twilio.SenderNumber,
|
||||
SenderPhoneNumber: number,
|
||||
RecipientPhoneNumber: user.VerifiedPhone,
|
||||
Content: content,
|
||||
}
|
||||
@ -17,9 +28,10 @@ func generateSms(user *view_model.NotifyUser, content string, config systemdefau
|
||||
message.RecipientPhoneNumber = user.LastPhone
|
||||
}
|
||||
|
||||
channels, err := senders.SMSChannels(config)
|
||||
if err != nil {
|
||||
return err
|
||||
channelChain, err := senders.SMSChannels(ctx, config, twilio, getFileSystemProvider, getLogProvider)
|
||||
|
||||
if channelChain.Len() == 0 {
|
||||
return caos_errors.ThrowPreconditionFailed(nil, "PHONE-w8nfow", "Errors.Notification.Channels.NotPresent")
|
||||
}
|
||||
return channels.HandleMessage(message)
|
||||
return channelChain.HandleMessage(message)
|
||||
}
|
||||
|
112
internal/query/notification_provider.go
Normal file
112
internal/query/notification_provider.go
Normal file
@ -0,0 +1,112 @@
|
||||
package query
|
||||
|
||||
import (
|
||||
"context"
|
||||
"database/sql"
|
||||
errs "errors"
|
||||
"time"
|
||||
|
||||
sq "github.com/Masterminds/squirrel"
|
||||
"github.com/caos/zitadel/internal/domain"
|
||||
"github.com/caos/zitadel/internal/errors"
|
||||
"github.com/caos/zitadel/internal/query/projection"
|
||||
)
|
||||
|
||||
type DebugNotificationProvider struct {
|
||||
AggregateID string
|
||||
CreationDate time.Time
|
||||
ChangeDate time.Time
|
||||
Sequence uint64
|
||||
ResourceOwner string
|
||||
State domain.NotificationProviderState
|
||||
Type domain.NotificationProviderType
|
||||
Compact bool
|
||||
}
|
||||
|
||||
var (
|
||||
notificationProviderTable = table{
|
||||
name: projection.DebugNotificationProviderTable,
|
||||
}
|
||||
NotificationProviderColumnAggID = Column{
|
||||
name: projection.DebugNotificationProviderAggIDCol,
|
||||
table: notificationProviderTable,
|
||||
}
|
||||
NotificationProviderColumnCreationDate = Column{
|
||||
name: projection.DebugNotificationProviderCreationDateCol,
|
||||
table: notificationProviderTable,
|
||||
}
|
||||
NotificationProviderColumnChangeDate = Column{
|
||||
name: projection.DebugNotificationProviderChangeDateCol,
|
||||
table: notificationProviderTable,
|
||||
}
|
||||
NotificationProviderColumnSequence = Column{
|
||||
name: projection.DebugNotificationProviderSequenceCol,
|
||||
table: notificationProviderTable,
|
||||
}
|
||||
NotificationProviderColumnResourceOwner = Column{
|
||||
name: projection.DebugNotificationProviderResourceOwnerCol,
|
||||
table: notificationProviderTable,
|
||||
}
|
||||
NotificationProviderColumnState = Column{
|
||||
name: projection.DebugNotificationProviderStateCol,
|
||||
table: notificationProviderTable,
|
||||
}
|
||||
NotificationProviderColumnType = Column{
|
||||
name: projection.DebugNotificationProviderTypeCol,
|
||||
table: notificationProviderTable,
|
||||
}
|
||||
NotificationProviderColumnCompact = Column{
|
||||
name: projection.DebugNotificationProviderCompactCol,
|
||||
table: notificationProviderTable,
|
||||
}
|
||||
)
|
||||
|
||||
func (q *Queries) NotificationProviderByIDAndType(ctx context.Context, aggID string, providerType domain.NotificationProviderType) (*DebugNotificationProvider, error) {
|
||||
query, scan := prepareDebugNotificationProviderQuery()
|
||||
stmt, args, err := query.Where(
|
||||
sq.Or{
|
||||
sq.Eq{
|
||||
LoginPolicyColumnOrgID.identifier(): aggID,
|
||||
},
|
||||
}).
|
||||
Limit(1).ToSql()
|
||||
if err != nil {
|
||||
return nil, errors.ThrowInternal(err, "QUERY-f9jSf", "Errors.Query.SQLStatement")
|
||||
}
|
||||
|
||||
row := q.client.QueryRowContext(ctx, stmt, args...)
|
||||
return scan(row)
|
||||
}
|
||||
|
||||
func prepareDebugNotificationProviderQuery() (sq.SelectBuilder, func(*sql.Row) (*DebugNotificationProvider, error)) {
|
||||
return sq.Select(
|
||||
NotificationProviderColumnAggID.identifier(),
|
||||
NotificationProviderColumnCreationDate.identifier(),
|
||||
NotificationProviderColumnChangeDate.identifier(),
|
||||
NotificationProviderColumnSequence.identifier(),
|
||||
NotificationProviderColumnResourceOwner.identifier(),
|
||||
NotificationProviderColumnState.identifier(),
|
||||
NotificationProviderColumnType.identifier(),
|
||||
NotificationProviderColumnCompact.identifier(),
|
||||
).From(notificationProviderTable.identifier()).PlaceholderFormat(sq.Dollar),
|
||||
func(row *sql.Row) (*DebugNotificationProvider, error) {
|
||||
p := new(DebugNotificationProvider)
|
||||
err := row.Scan(
|
||||
&p.AggregateID,
|
||||
&p.CreationDate,
|
||||
&p.ChangeDate,
|
||||
&p.Sequence,
|
||||
&p.ResourceOwner,
|
||||
&p.State,
|
||||
&p.Type,
|
||||
&p.Compact,
|
||||
)
|
||||
if err != nil {
|
||||
if errs.Is(err, sql.ErrNoRows) {
|
||||
return nil, errors.ThrowNotFound(err, "QUERY-s9ujf", "Errors.NotificationProvider.NotFound")
|
||||
}
|
||||
return nil, errors.ThrowInternal(err, "QUERY-2liu0", "Errors.Internal")
|
||||
}
|
||||
return p, nil
|
||||
}
|
||||
}
|
130
internal/query/notification_provider_test.go
Normal file
130
internal/query/notification_provider_test.go
Normal file
@ -0,0 +1,130 @@
|
||||
package query
|
||||
|
||||
import (
|
||||
"database/sql"
|
||||
"database/sql/driver"
|
||||
"errors"
|
||||
"fmt"
|
||||
"regexp"
|
||||
"testing"
|
||||
|
||||
"github.com/caos/zitadel/internal/domain"
|
||||
errs "github.com/caos/zitadel/internal/errors"
|
||||
)
|
||||
|
||||
func Test_NotificationProviderPrepares(t *testing.T) {
|
||||
type want struct {
|
||||
sqlExpectations sqlExpectation
|
||||
err checkErr
|
||||
}
|
||||
tests := []struct {
|
||||
name string
|
||||
prepare interface{}
|
||||
want want
|
||||
object interface{}
|
||||
}{
|
||||
{
|
||||
name: "prepareNotificationProviderQuery no result",
|
||||
prepare: prepareDebugNotificationProviderQuery,
|
||||
want: want{
|
||||
sqlExpectations: mockQueries(
|
||||
regexp.QuoteMeta(`SELECT zitadel.projections.notification_providers.aggregate_id,`+
|
||||
` zitadel.projections.notification_providers.creation_date,`+
|
||||
` zitadel.projections.notification_providers.change_date,`+
|
||||
` zitadel.projections.notification_providers.sequence,`+
|
||||
` zitadel.projections.notification_providers.resource_owner,`+
|
||||
` zitadel.projections.notification_providers.state,`+
|
||||
` zitadel.projections.notification_providers.provider_type,`+
|
||||
` zitadel.projections.notification_providers.compact`+
|
||||
` FROM zitadel.projections.notification_providers`),
|
||||
nil,
|
||||
nil,
|
||||
),
|
||||
err: func(err error) (error, bool) {
|
||||
if !errs.IsNotFound(err) {
|
||||
return fmt.Errorf("err should be zitadel.NotFoundError got: %w", err), false
|
||||
}
|
||||
return nil, true
|
||||
},
|
||||
},
|
||||
object: (*DebugNotificationProvider)(nil),
|
||||
},
|
||||
{
|
||||
name: "prepareNotificationProviderQuery found",
|
||||
prepare: prepareDebugNotificationProviderQuery,
|
||||
want: want{
|
||||
sqlExpectations: mockQuery(
|
||||
regexp.QuoteMeta(`SELECT zitadel.projections.notification_providers.aggregate_id,`+
|
||||
` zitadel.projections.notification_providers.creation_date,`+
|
||||
` zitadel.projections.notification_providers.change_date,`+
|
||||
` zitadel.projections.notification_providers.sequence,`+
|
||||
` zitadel.projections.notification_providers.resource_owner,`+
|
||||
` zitadel.projections.notification_providers.state,`+
|
||||
` zitadel.projections.notification_providers.provider_type,`+
|
||||
` zitadel.projections.notification_providers.compact`+
|
||||
` FROM zitadel.projections.notification_providers`),
|
||||
[]string{
|
||||
"aggregate_id",
|
||||
"creation_date",
|
||||
"change_date",
|
||||
"sequence",
|
||||
"resource_owner",
|
||||
"state",
|
||||
"provider_type",
|
||||
"compact",
|
||||
},
|
||||
[]driver.Value{
|
||||
"agg-id",
|
||||
testNow,
|
||||
testNow,
|
||||
uint64(20211109),
|
||||
"ro-id",
|
||||
domain.NotificationProviderStateActive,
|
||||
domain.NotificationProviderTypeFile,
|
||||
true,
|
||||
},
|
||||
),
|
||||
},
|
||||
object: &DebugNotificationProvider{
|
||||
AggregateID: "agg-id",
|
||||
CreationDate: testNow,
|
||||
ChangeDate: testNow,
|
||||
Sequence: 20211109,
|
||||
ResourceOwner: "ro-id",
|
||||
State: domain.NotificationProviderStateActive,
|
||||
Type: domain.NotificationProviderTypeFile,
|
||||
Compact: true,
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "prepareNotificationProviderQuery sql err",
|
||||
prepare: prepareDebugNotificationProviderQuery,
|
||||
want: want{
|
||||
sqlExpectations: mockQueryErr(
|
||||
regexp.QuoteMeta(`SELECT zitadel.projections.notification_providers.aggregate_id,`+
|
||||
` zitadel.projections.notification_providers.creation_date,`+
|
||||
` zitadel.projections.notification_providers.change_date,`+
|
||||
` zitadel.projections.notification_providers.sequence,`+
|
||||
` zitadel.projections.notification_providers.resource_owner,`+
|
||||
` zitadel.projections.notification_providers.state,`+
|
||||
` zitadel.projections.notification_providers.provider_type,`+
|
||||
` zitadel.projections.notification_providers.compact`+
|
||||
` FROM zitadel.projections.notification_providers`),
|
||||
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: 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)
|
||||
})
|
||||
}
|
||||
}
|
160
internal/query/projection/debug_notification.go
Normal file
160
internal/query/projection/debug_notification.go
Normal file
@ -0,0 +1,160 @@
|
||||
package projection
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/caos/logging"
|
||||
"github.com/caos/zitadel/internal/domain"
|
||||
"github.com/caos/zitadel/internal/repository/settings"
|
||||
|
||||
"github.com/caos/zitadel/internal/errors"
|
||||
"github.com/caos/zitadel/internal/eventstore"
|
||||
"github.com/caos/zitadel/internal/eventstore/handler"
|
||||
"github.com/caos/zitadel/internal/eventstore/handler/crdb"
|
||||
"github.com/caos/zitadel/internal/repository/iam"
|
||||
)
|
||||
|
||||
type DebugNotificationProviderProjection struct {
|
||||
crdb.StatementHandler
|
||||
}
|
||||
|
||||
const (
|
||||
DebugNotificationProviderTable = "zitadel.projections.notification_providers"
|
||||
)
|
||||
|
||||
func NewDebugNotificationProviderProjection(ctx context.Context, config crdb.StatementHandlerConfig) *DebugNotificationProviderProjection {
|
||||
p := &DebugNotificationProviderProjection{}
|
||||
config.ProjectionName = DebugNotificationProviderTable
|
||||
config.Reducers = p.reducers()
|
||||
p.StatementHandler = crdb.NewStatementHandler(ctx, config)
|
||||
return p
|
||||
}
|
||||
|
||||
func (p *DebugNotificationProviderProjection) reducers() []handler.AggregateReducer {
|
||||
return []handler.AggregateReducer{
|
||||
{
|
||||
Aggregate: iam.AggregateType,
|
||||
EventRedusers: []handler.EventReducer{
|
||||
{
|
||||
Event: iam.DebugNotificationProviderFileAddedEventType,
|
||||
Reduce: p.reduceDebugNotificationProviderAdded,
|
||||
},
|
||||
{
|
||||
Event: iam.DebugNotificationProviderFileChangedEventType,
|
||||
Reduce: p.reduceDebugNotificationProviderChanged,
|
||||
},
|
||||
{
|
||||
Event: iam.DebugNotificationProviderFileRemovedEventType,
|
||||
Reduce: p.reduceDebugNotificationProviderRemoved,
|
||||
},
|
||||
{
|
||||
Event: iam.DebugNotificationProviderLogAddedEventType,
|
||||
Reduce: p.reduceDebugNotificationProviderAdded,
|
||||
},
|
||||
{
|
||||
Event: iam.DebugNotificationProviderLogChangedEventType,
|
||||
Reduce: p.reduceDebugNotificationProviderChanged,
|
||||
},
|
||||
{
|
||||
Event: iam.DebugNotificationProviderLogRemovedEventType,
|
||||
Reduce: p.reduceDebugNotificationProviderRemoved,
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
const (
|
||||
DebugNotificationProviderAggIDCol = "aggregate_id"
|
||||
DebugNotificationProviderCreationDateCol = "creation_date"
|
||||
DebugNotificationProviderChangeDateCol = "change_date"
|
||||
DebugNotificationProviderSequenceCol = "sequence"
|
||||
DebugNotificationProviderResourceOwnerCol = "resource_owner"
|
||||
DebugNotificationProviderStateCol = "state"
|
||||
DebugNotificationProviderTypeCol = "provider_type"
|
||||
DebugNotificationProviderCompactCol = "compact"
|
||||
)
|
||||
|
||||
func (p *DebugNotificationProviderProjection) reduceDebugNotificationProviderAdded(event eventstore.Event) (*handler.Statement, error) {
|
||||
var providerEvent settings.DebugNotificationProviderAddedEvent
|
||||
var providerType domain.NotificationProviderType
|
||||
switch e := event.(type) {
|
||||
case *iam.DebugNotificationProviderFileAddedEvent:
|
||||
providerEvent = e.DebugNotificationProviderAddedEvent
|
||||
providerType = domain.NotificationProviderTypeFile
|
||||
case *iam.DebugNotificationProviderLogAddedEvent:
|
||||
providerEvent = e.DebugNotificationProviderAddedEvent
|
||||
providerType = domain.NotificationProviderTypeLog
|
||||
default:
|
||||
logging.WithFields("seq", event.Sequence(), "expectedTypes", []eventstore.EventType{iam.DebugNotificationProviderFileAddedEventType, iam.DebugNotificationProviderLogAddedEventType}).Error("wrong event type")
|
||||
return nil, errors.ThrowInvalidArgument(nil, "HANDL-pYPxS", "reduce.wrong.event.type")
|
||||
}
|
||||
|
||||
return crdb.NewCreateStatement(&providerEvent, []handler.Column{
|
||||
handler.NewCol(DebugNotificationProviderAggIDCol, providerEvent.Aggregate().ID),
|
||||
handler.NewCol(DebugNotificationProviderCreationDateCol, providerEvent.CreationDate()),
|
||||
handler.NewCol(DebugNotificationProviderChangeDateCol, providerEvent.CreationDate()),
|
||||
handler.NewCol(DebugNotificationProviderSequenceCol, providerEvent.Sequence()),
|
||||
handler.NewCol(DebugNotificationProviderResourceOwnerCol, providerEvent.Aggregate().ResourceOwner),
|
||||
handler.NewCol(DebugNotificationProviderStateCol, domain.NotificationProviderStateActive),
|
||||
handler.NewCol(DebugNotificationProviderTypeCol, providerType),
|
||||
handler.NewCol(DebugNotificationProviderCompactCol, providerEvent.Compact),
|
||||
}), nil
|
||||
}
|
||||
|
||||
func (p *DebugNotificationProviderProjection) reduceDebugNotificationProviderChanged(event eventstore.Event) (*handler.Statement, error) {
|
||||
var providerEvent settings.DebugNotificationProviderChangedEvent
|
||||
var providerType domain.NotificationProviderType
|
||||
switch e := event.(type) {
|
||||
case *iam.DebugNotificationProviderFileChangedEvent:
|
||||
providerEvent = e.DebugNotificationProviderChangedEvent
|
||||
providerType = domain.NotificationProviderTypeFile
|
||||
case *iam.DebugNotificationProviderLogChangedEvent:
|
||||
providerEvent = e.DebugNotificationProviderChangedEvent
|
||||
providerType = domain.NotificationProviderTypeLog
|
||||
default:
|
||||
logging.WithFields("seq", event.Sequence(), "expectedTypes", []eventstore.EventType{iam.DebugNotificationProviderFileChangedEventType, iam.DebugNotificationProviderLogChangedEventType}).Error("wrong event type")
|
||||
return nil, errors.ThrowInvalidArgument(nil, "HANDL-pYPxS", "reduce.wrong.event.type")
|
||||
}
|
||||
|
||||
cols := []handler.Column{
|
||||
handler.NewCol(DebugNotificationProviderChangeDateCol, providerEvent.CreationDate()),
|
||||
handler.NewCol(DebugNotificationProviderSequenceCol, providerEvent.Sequence()),
|
||||
}
|
||||
if providerEvent.Compact != nil {
|
||||
cols = append(cols, handler.NewCol(DebugNotificationProviderCompactCol, *providerEvent.Compact))
|
||||
}
|
||||
|
||||
return crdb.NewUpdateStatement(
|
||||
&providerEvent,
|
||||
cols,
|
||||
[]handler.Condition{
|
||||
handler.NewCond(DebugNotificationProviderAggIDCol, providerEvent.Aggregate().ID),
|
||||
handler.NewCond(DebugNotificationProviderTypeCol, providerType),
|
||||
},
|
||||
), nil
|
||||
}
|
||||
|
||||
func (p *DebugNotificationProviderProjection) reduceDebugNotificationProviderRemoved(event eventstore.Event) (*handler.Statement, error) {
|
||||
var providerEvent settings.DebugNotificationProviderRemovedEvent
|
||||
var providerType domain.NotificationProviderType
|
||||
switch e := event.(type) {
|
||||
case *iam.DebugNotificationProviderFileRemovedEvent:
|
||||
providerEvent = e.DebugNotificationProviderRemovedEvent
|
||||
providerType = domain.NotificationProviderTypeFile
|
||||
case *iam.DebugNotificationProviderLogRemovedEvent:
|
||||
providerEvent = e.DebugNotificationProviderRemovedEvent
|
||||
providerType = domain.NotificationProviderTypeLog
|
||||
default:
|
||||
logging.WithFields("seq", event.Sequence(), "expectedTypes", []eventstore.EventType{iam.DebugNotificationProviderFileRemovedEventType, iam.DebugNotificationProviderLogRemovedEventType}).Error("wrong event type")
|
||||
return nil, errors.ThrowInvalidArgument(nil, "HANDL-dow9f", "reduce.wrong.event.type")
|
||||
}
|
||||
|
||||
return crdb.NewDeleteStatement(
|
||||
&providerEvent,
|
||||
[]handler.Condition{
|
||||
handler.NewCond(DebugNotificationProviderAggIDCol, providerEvent.Aggregate().ID),
|
||||
handler.NewCond(DebugNotificationProviderTypeCol, providerType),
|
||||
},
|
||||
), nil
|
||||
}
|
232
internal/query/projection/debug_notification_provider_test.go
Normal file
232
internal/query/projection/debug_notification_provider_test.go
Normal file
@ -0,0 +1,232 @@
|
||||
package projection
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/caos/zitadel/internal/domain"
|
||||
"github.com/caos/zitadel/internal/errors"
|
||||
"github.com/caos/zitadel/internal/eventstore"
|
||||
"github.com/caos/zitadel/internal/eventstore/handler"
|
||||
"github.com/caos/zitadel/internal/eventstore/repository"
|
||||
"github.com/caos/zitadel/internal/repository/iam"
|
||||
)
|
||||
|
||||
func TestDebugNotificationProviderProjection_reduces(t *testing.T) {
|
||||
type args struct {
|
||||
event func(t *testing.T) eventstore.Event
|
||||
}
|
||||
tests := []struct {
|
||||
name string
|
||||
args args
|
||||
reduce func(event eventstore.Event) (*handler.Statement, error)
|
||||
want wantReduce
|
||||
}{
|
||||
{
|
||||
name: "iam.reduceNotificationProviderFileAdded",
|
||||
reduce: (&DebugNotificationProviderProjection{}).reduceDebugNotificationProviderAdded,
|
||||
args: args{
|
||||
event: getEvent(testEvent(
|
||||
repository.EventType(iam.DebugNotificationProviderFileAddedEventType),
|
||||
iam.AggregateType,
|
||||
[]byte(`{
|
||||
"compact": true
|
||||
}`),
|
||||
), iam.DebugNotificationProviderFileAddedEventMapper),
|
||||
},
|
||||
want: wantReduce{
|
||||
aggregateType: eventstore.AggregateType("iam"),
|
||||
sequence: 15,
|
||||
previousSequence: 10,
|
||||
projection: DebugNotificationProviderTable,
|
||||
executer: &testExecuter{
|
||||
executions: []execution{
|
||||
{
|
||||
expectedStmt: "INSERT INTO zitadel.projections.notification_providers (aggregate_id, creation_date, change_date, sequence, resource_owner, state, provider_type, compact) VALUES ($1, $2, $3, $4, $5, $6, $7, $8)",
|
||||
expectedArgs: []interface{}{
|
||||
"agg-id",
|
||||
anyArg{},
|
||||
anyArg{},
|
||||
uint64(15),
|
||||
"ro-id",
|
||||
domain.NotificationProviderStateActive,
|
||||
domain.NotificationProviderTypeFile,
|
||||
true,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "iam.reduceNotificationProviderFileChanged",
|
||||
reduce: (&DebugNotificationProviderProjection{}).reduceDebugNotificationProviderChanged,
|
||||
args: args{
|
||||
event: getEvent(testEvent(
|
||||
repository.EventType(iam.DebugNotificationProviderFileChangedEventType),
|
||||
iam.AggregateType,
|
||||
[]byte(`{
|
||||
"compact": true
|
||||
}`),
|
||||
), iam.DebugNotificationProviderFileChangedEventMapper),
|
||||
},
|
||||
want: wantReduce{
|
||||
aggregateType: eventstore.AggregateType("iam"),
|
||||
sequence: 15,
|
||||
previousSequence: 10,
|
||||
projection: DebugNotificationProviderTable,
|
||||
executer: &testExecuter{
|
||||
executions: []execution{
|
||||
{
|
||||
expectedStmt: "UPDATE zitadel.projections.notification_providers SET (change_date, sequence, compact) = ($1, $2, $3) WHERE (aggregate_id = $4) AND (provider_type = $5)",
|
||||
expectedArgs: []interface{}{
|
||||
anyArg{},
|
||||
uint64(15),
|
||||
true,
|
||||
"agg-id",
|
||||
domain.NotificationProviderTypeFile,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "iam.reduceNotificationProviderFileRemoved",
|
||||
reduce: (&DebugNotificationProviderProjection{}).reduceDebugNotificationProviderRemoved,
|
||||
args: args{
|
||||
event: getEvent(testEvent(
|
||||
repository.EventType(iam.DebugNotificationProviderFileRemovedEventType),
|
||||
iam.AggregateType,
|
||||
nil,
|
||||
), iam.DebugNotificationProviderFileRemovedEventMapper),
|
||||
},
|
||||
want: wantReduce{
|
||||
aggregateType: eventstore.AggregateType("iam"),
|
||||
sequence: 15,
|
||||
previousSequence: 10,
|
||||
projection: DebugNotificationProviderTable,
|
||||
executer: &testExecuter{
|
||||
executions: []execution{
|
||||
{
|
||||
expectedStmt: "DELETE FROM zitadel.projections.notification_providers WHERE (aggregate_id = $1) AND (provider_type = $2)",
|
||||
expectedArgs: []interface{}{
|
||||
"agg-id",
|
||||
domain.NotificationProviderTypeFile,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "iam.reduceNotificationProviderLogAdded",
|
||||
reduce: (&DebugNotificationProviderProjection{}).reduceDebugNotificationProviderAdded,
|
||||
args: args{
|
||||
event: getEvent(testEvent(
|
||||
repository.EventType(iam.DebugNotificationProviderLogAddedEventType),
|
||||
iam.AggregateType,
|
||||
[]byte(`{
|
||||
"compact": true
|
||||
}`),
|
||||
), iam.DebugNotificationProviderLogAddedEventMapper),
|
||||
},
|
||||
want: wantReduce{
|
||||
aggregateType: eventstore.AggregateType("iam"),
|
||||
sequence: 15,
|
||||
previousSequence: 10,
|
||||
projection: DebugNotificationProviderTable,
|
||||
executer: &testExecuter{
|
||||
executions: []execution{
|
||||
{
|
||||
expectedStmt: "INSERT INTO zitadel.projections.notification_providers (aggregate_id, creation_date, change_date, sequence, resource_owner, state, provider_type, compact) VALUES ($1, $2, $3, $4, $5, $6, $7, $8)",
|
||||
expectedArgs: []interface{}{
|
||||
"agg-id",
|
||||
anyArg{},
|
||||
anyArg{},
|
||||
uint64(15),
|
||||
"ro-id",
|
||||
domain.NotificationProviderStateActive,
|
||||
domain.NotificationProviderTypeLog,
|
||||
true,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "iam.reduceNotificationProviderLogChanged",
|
||||
reduce: (&DebugNotificationProviderProjection{}).reduceDebugNotificationProviderChanged,
|
||||
args: args{
|
||||
event: getEvent(testEvent(
|
||||
repository.EventType(iam.DebugNotificationProviderLogChangedEventType),
|
||||
iam.AggregateType,
|
||||
[]byte(`{
|
||||
"compact": true
|
||||
}`),
|
||||
), iam.DebugNotificationProviderLogChangedEventMapper),
|
||||
},
|
||||
want: wantReduce{
|
||||
aggregateType: eventstore.AggregateType("iam"),
|
||||
sequence: 15,
|
||||
previousSequence: 10,
|
||||
projection: DebugNotificationProviderTable,
|
||||
executer: &testExecuter{
|
||||
executions: []execution{
|
||||
{
|
||||
expectedStmt: "UPDATE zitadel.projections.notification_providers SET (change_date, sequence, compact) = ($1, $2, $3) WHERE (aggregate_id = $4) AND (provider_type = $5)",
|
||||
expectedArgs: []interface{}{
|
||||
anyArg{},
|
||||
uint64(15),
|
||||
true,
|
||||
"agg-id",
|
||||
domain.NotificationProviderTypeLog,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "iam.reduceNotificationProviderLogRemoved",
|
||||
reduce: (&DebugNotificationProviderProjection{}).reduceDebugNotificationProviderRemoved,
|
||||
args: args{
|
||||
event: getEvent(testEvent(
|
||||
repository.EventType(iam.DebugNotificationProviderLogRemovedEventType),
|
||||
iam.AggregateType,
|
||||
nil,
|
||||
), iam.DebugNotificationProviderLogRemovedEventMapper),
|
||||
},
|
||||
want: wantReduce{
|
||||
aggregateType: eventstore.AggregateType("iam"),
|
||||
sequence: 15,
|
||||
previousSequence: 10,
|
||||
projection: DebugNotificationProviderTable,
|
||||
executer: &testExecuter{
|
||||
executions: []execution{
|
||||
{
|
||||
expectedStmt: "DELETE FROM zitadel.projections.notification_providers WHERE (aggregate_id = $1) AND (provider_type = $2)",
|
||||
expectedArgs: []interface{}{
|
||||
"agg-id",
|
||||
domain.NotificationProviderTypeLog,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
event := baseEvent(t)
|
||||
got, err := tt.reduce(event)
|
||||
if _, ok := err.(errors.InvalidArgument); !ok {
|
||||
t.Errorf("no wrong event mapping: %v, got: %v", err, got)
|
||||
}
|
||||
|
||||
event = tt.args.event(t)
|
||||
got, err = tt.reduce(event)
|
||||
assertReduce(t, got, err, tt.want)
|
||||
})
|
||||
}
|
||||
}
|
@ -74,6 +74,7 @@ func Start(ctx context.Context, sqlClient *sql.DB, es *eventstore.Eventstore, co
|
||||
NewSMSConfigProjection(ctx, applyCustomConfig(projectionConfig, config.Customizations["sms_config"]))
|
||||
NewOIDCSettingsProjection(ctx, applyCustomConfig(projectionConfig, config.Customizations["oidc_settings"]))
|
||||
_, err := NewKeyProjection(ctx, applyCustomConfig(projectionConfig, config.Customizations["keys"]), keyConfig, keyChan)
|
||||
NewDebugNotificationProviderProjection(ctx, applyCustomConfig(projectionConfig, config.Customizations["debug_notification_provider"]))
|
||||
|
||||
return err
|
||||
}
|
||||
|
106
internal/repository/iam/debug_notification_file.go
Normal file
106
internal/repository/iam/debug_notification_file.go
Normal file
@ -0,0 +1,106 @@
|
||||
package iam
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/caos/zitadel/internal/eventstore"
|
||||
"github.com/caos/zitadel/internal/repository/settings"
|
||||
|
||||
"github.com/caos/zitadel/internal/eventstore/repository"
|
||||
)
|
||||
|
||||
const (
|
||||
fileType = ".file"
|
||||
)
|
||||
|
||||
var (
|
||||
DebugNotificationProviderFileAddedEventType = iamEventTypePrefix + settings.DebugNotificationPrefix + fileType + settings.DebugNotificationProviderAdded
|
||||
DebugNotificationProviderFileChangedEventType = iamEventTypePrefix + settings.DebugNotificationPrefix + fileType + settings.DebugNotificationProviderChanged
|
||||
DebugNotificationProviderFileRemovedEventType = iamEventTypePrefix + settings.DebugNotificationPrefix + fileType + settings.DebugNotificationProviderRemoved
|
||||
)
|
||||
|
||||
type DebugNotificationProviderFileAddedEvent struct {
|
||||
settings.DebugNotificationProviderAddedEvent
|
||||
}
|
||||
|
||||
func NewDebugNotificationProviderFileAddedEvent(
|
||||
ctx context.Context,
|
||||
aggregate *eventstore.Aggregate,
|
||||
compact bool,
|
||||
) *DebugNotificationProviderFileAddedEvent {
|
||||
return &DebugNotificationProviderFileAddedEvent{
|
||||
DebugNotificationProviderAddedEvent: *settings.NewDebugNotificationProviderAddedEvent(
|
||||
eventstore.NewBaseEventForPush(
|
||||
ctx,
|
||||
aggregate,
|
||||
DebugNotificationProviderFileAddedEventType),
|
||||
compact),
|
||||
}
|
||||
}
|
||||
|
||||
func DebugNotificationProviderFileAddedEventMapper(event *repository.Event) (eventstore.Event, error) {
|
||||
e, err := settings.DebugNotificationProviderAddedEventMapper(event)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &DebugNotificationProviderFileAddedEvent{DebugNotificationProviderAddedEvent: *e.(*settings.DebugNotificationProviderAddedEvent)}, nil
|
||||
}
|
||||
|
||||
type DebugNotificationProviderFileChangedEvent struct {
|
||||
settings.DebugNotificationProviderChangedEvent
|
||||
}
|
||||
|
||||
func NewDebugNotificationProviderFileChangedEvent(
|
||||
ctx context.Context,
|
||||
aggregate *eventstore.Aggregate,
|
||||
changes []settings.DebugNotificationProviderChanges,
|
||||
) (*DebugNotificationProviderFileChangedEvent, error) {
|
||||
changedEvent, err := settings.NewDebugNotificationProviderChangedEvent(
|
||||
eventstore.NewBaseEventForPush(
|
||||
ctx,
|
||||
aggregate,
|
||||
DebugNotificationProviderFileChangedEventType),
|
||||
changes,
|
||||
)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &DebugNotificationProviderFileChangedEvent{DebugNotificationProviderChangedEvent: *changedEvent}, nil
|
||||
}
|
||||
|
||||
func DebugNotificationProviderFileChangedEventMapper(event *repository.Event) (eventstore.Event, error) {
|
||||
e, err := settings.DebugNotificationProviderChangedEventMapper(event)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &DebugNotificationProviderFileChangedEvent{DebugNotificationProviderChangedEvent: *e.(*settings.DebugNotificationProviderChangedEvent)}, nil
|
||||
}
|
||||
|
||||
type DebugNotificationProviderFileRemovedEvent struct {
|
||||
settings.DebugNotificationProviderRemovedEvent
|
||||
}
|
||||
|
||||
func NewDebugNotificationProviderFileRemovedEvent(
|
||||
ctx context.Context,
|
||||
aggregate *eventstore.Aggregate,
|
||||
) *DebugNotificationProviderFileRemovedEvent {
|
||||
return &DebugNotificationProviderFileRemovedEvent{
|
||||
DebugNotificationProviderRemovedEvent: *settings.NewDebugNotificationProviderRemovedEvent(
|
||||
eventstore.NewBaseEventForPush(
|
||||
ctx,
|
||||
aggregate,
|
||||
DebugNotificationProviderFileRemovedEventType),
|
||||
),
|
||||
}
|
||||
}
|
||||
|
||||
func DebugNotificationProviderFileRemovedEventMapper(event *repository.Event) (eventstore.Event, error) {
|
||||
e, err := settings.DebugNotificationProviderRemovedEventMapper(event)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &DebugNotificationProviderFileRemovedEvent{DebugNotificationProviderRemovedEvent: *e.(*settings.DebugNotificationProviderRemovedEvent)}, nil
|
||||
}
|
108
internal/repository/iam/debug_notification_log.go
Normal file
108
internal/repository/iam/debug_notification_log.go
Normal file
@ -0,0 +1,108 @@
|
||||
package iam
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/caos/zitadel/internal/eventstore"
|
||||
"github.com/caos/zitadel/internal/repository/settings"
|
||||
|
||||
"github.com/caos/zitadel/internal/eventstore/repository"
|
||||
)
|
||||
|
||||
const (
|
||||
logType = ".log"
|
||||
)
|
||||
|
||||
var (
|
||||
DebugNotificationProviderLogAddedEventType = iamEventTypePrefix + settings.DebugNotificationPrefix + logType + settings.DebugNotificationProviderAdded
|
||||
DebugNotificationProviderLogChangedEventType = iamEventTypePrefix + settings.DebugNotificationPrefix + logType + settings.DebugNotificationProviderChanged
|
||||
DebugNotificationProviderLogEnabledEventType = iamEventTypePrefix + settings.DebugNotificationPrefix + logType + settings.DebugNotificationProviderEnabled
|
||||
DebugNotificationProviderLogDisabledEventType = iamEventTypePrefix + settings.DebugNotificationPrefix + logType + settings.DebugNotificationProviderDisabled
|
||||
DebugNotificationProviderLogRemovedEventType = iamEventTypePrefix + settings.DebugNotificationPrefix + logType + settings.DebugNotificationProviderRemoved
|
||||
)
|
||||
|
||||
type DebugNotificationProviderLogAddedEvent struct {
|
||||
settings.DebugNotificationProviderAddedEvent
|
||||
}
|
||||
|
||||
func NewDebugNotificationProviderLogAddedEvent(
|
||||
ctx context.Context,
|
||||
aggregate *eventstore.Aggregate,
|
||||
compact bool,
|
||||
) *DebugNotificationProviderLogAddedEvent {
|
||||
return &DebugNotificationProviderLogAddedEvent{
|
||||
DebugNotificationProviderAddedEvent: *settings.NewDebugNotificationProviderAddedEvent(
|
||||
eventstore.NewBaseEventForPush(
|
||||
ctx,
|
||||
aggregate,
|
||||
DebugNotificationProviderLogAddedEventType),
|
||||
compact),
|
||||
}
|
||||
}
|
||||
|
||||
func DebugNotificationProviderLogAddedEventMapper(event *repository.Event) (eventstore.Event, error) {
|
||||
e, err := settings.DebugNotificationProviderAddedEventMapper(event)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &DebugNotificationProviderLogAddedEvent{DebugNotificationProviderAddedEvent: *e.(*settings.DebugNotificationProviderAddedEvent)}, nil
|
||||
}
|
||||
|
||||
type DebugNotificationProviderLogChangedEvent struct {
|
||||
settings.DebugNotificationProviderChangedEvent
|
||||
}
|
||||
|
||||
func NewDebugNotificationProviderLogChangedEvent(
|
||||
ctx context.Context,
|
||||
aggregate *eventstore.Aggregate,
|
||||
changes []settings.DebugNotificationProviderChanges,
|
||||
) (*DebugNotificationProviderLogChangedEvent, error) {
|
||||
changedEvent, err := settings.NewDebugNotificationProviderChangedEvent(
|
||||
eventstore.NewBaseEventForPush(
|
||||
ctx,
|
||||
aggregate,
|
||||
DebugNotificationProviderLogChangedEventType),
|
||||
changes,
|
||||
)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &DebugNotificationProviderLogChangedEvent{DebugNotificationProviderChangedEvent: *changedEvent}, nil
|
||||
}
|
||||
|
||||
func DebugNotificationProviderLogChangedEventMapper(event *repository.Event) (eventstore.Event, error) {
|
||||
e, err := settings.DebugNotificationProviderChangedEventMapper(event)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &DebugNotificationProviderLogChangedEvent{DebugNotificationProviderChangedEvent: *e.(*settings.DebugNotificationProviderChangedEvent)}, nil
|
||||
}
|
||||
|
||||
type DebugNotificationProviderLogRemovedEvent struct {
|
||||
settings.DebugNotificationProviderRemovedEvent
|
||||
}
|
||||
|
||||
func NewDebugNotificationProviderLogRemovedEvent(
|
||||
ctx context.Context,
|
||||
aggregate *eventstore.Aggregate,
|
||||
) *DebugNotificationProviderLogRemovedEvent {
|
||||
return &DebugNotificationProviderLogRemovedEvent{
|
||||
DebugNotificationProviderRemovedEvent: *settings.NewDebugNotificationProviderRemovedEvent(
|
||||
eventstore.NewBaseEventForPush(
|
||||
ctx,
|
||||
aggregate,
|
||||
DebugNotificationProviderLogRemovedEventType),
|
||||
),
|
||||
}
|
||||
}
|
||||
|
||||
func DebugNotificationProviderLogRemovedEventMapper(event *repository.Event) (eventstore.Event, error) {
|
||||
e, err := settings.DebugNotificationProviderRemovedEventMapper(event)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &DebugNotificationProviderLogRemovedEvent{DebugNotificationProviderRemovedEvent: *e.(*settings.DebugNotificationProviderRemovedEvent)}, nil
|
||||
}
|
@ -23,6 +23,12 @@ func RegisterEventMappers(es *eventstore.Eventstore) {
|
||||
RegisterFilterEventMapper(SMSConfigActivatedEventType, SMSConfigActivatedEventMapper).
|
||||
RegisterFilterEventMapper(SMSConfigDeactivatedEventType, SMSConfigDeactivatedEventMapper).
|
||||
RegisterFilterEventMapper(SMSConfigRemovedEventType, SMSConfigRemovedEventMapper).
|
||||
RegisterFilterEventMapper(DebugNotificationProviderFileAddedEventType, DebugNotificationProviderFileAddedEventMapper).
|
||||
RegisterFilterEventMapper(DebugNotificationProviderFileChangedEventType, DebugNotificationProviderFileChangedEventMapper).
|
||||
RegisterFilterEventMapper(DebugNotificationProviderFileRemovedEventType, DebugNotificationProviderFileRemovedEventMapper).
|
||||
RegisterFilterEventMapper(DebugNotificationProviderLogAddedEventType, DebugNotificationProviderLogAddedEventMapper).
|
||||
RegisterFilterEventMapper(DebugNotificationProviderLogChangedEventType, DebugNotificationProviderLogChangedEventMapper).
|
||||
RegisterFilterEventMapper(DebugNotificationProviderLogRemovedEventType, DebugNotificationProviderLogRemovedEventMapper).
|
||||
RegisterFilterEventMapper(OIDCSettingsAddedEventType, OIDCSettingsAddedEventMapper).
|
||||
RegisterFilterEventMapper(OIDCSettingsChangedEventType, OIDCSettingsChangedEventMapper).
|
||||
RegisterFilterEventMapper(LabelPolicyAddedEventType, LabelPolicyAddedEventMapper).
|
||||
|
130
internal/repository/settings/debug_notification.go
Normal file
130
internal/repository/settings/debug_notification.go
Normal file
@ -0,0 +1,130 @@
|
||||
package settings
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
|
||||
"github.com/caos/zitadel/internal/errors"
|
||||
"github.com/caos/zitadel/internal/eventstore"
|
||||
"github.com/caos/zitadel/internal/eventstore/repository"
|
||||
)
|
||||
|
||||
const (
|
||||
DebugNotificationPrefix = "notification.provider.debug"
|
||||
DebugNotificationProviderAdded = "added"
|
||||
DebugNotificationProviderChanged = "changed"
|
||||
DebugNotificationProviderEnabled = "enabled"
|
||||
DebugNotificationProviderDisabled = "disabled"
|
||||
DebugNotificationProviderRemoved = "removed"
|
||||
)
|
||||
|
||||
type DebugNotificationProviderAddedEvent struct {
|
||||
eventstore.BaseEvent `json:"-"`
|
||||
|
||||
Compact bool `json:"compact,omitempty"`
|
||||
}
|
||||
|
||||
func (e *DebugNotificationProviderAddedEvent) Data() interface{} {
|
||||
return e
|
||||
}
|
||||
|
||||
func (e *DebugNotificationProviderAddedEvent) UniqueConstraints() []*eventstore.EventUniqueConstraint {
|
||||
return nil
|
||||
}
|
||||
|
||||
func NewDebugNotificationProviderAddedEvent(
|
||||
base *eventstore.BaseEvent,
|
||||
compact bool,
|
||||
) *DebugNotificationProviderAddedEvent {
|
||||
return &DebugNotificationProviderAddedEvent{
|
||||
BaseEvent: *base,
|
||||
Compact: compact,
|
||||
}
|
||||
}
|
||||
|
||||
func DebugNotificationProviderAddedEventMapper(event *repository.Event) (eventstore.Event, error) {
|
||||
e := &DebugNotificationProviderAddedEvent{
|
||||
BaseEvent: *eventstore.BaseEventFromRepo(event),
|
||||
}
|
||||
|
||||
err := json.Unmarshal(event.Data, e)
|
||||
if err != nil {
|
||||
return nil, errors.ThrowInternal(err, "SET-f93ns", "unable to unmarshal debug notification added")
|
||||
}
|
||||
|
||||
return e, nil
|
||||
}
|
||||
|
||||
type DebugNotificationProviderChangedEvent struct {
|
||||
eventstore.BaseEvent `json:"-"`
|
||||
|
||||
Compact *bool `json:"compact,omitempty"`
|
||||
}
|
||||
|
||||
func (e *DebugNotificationProviderChangedEvent) Data() interface{} {
|
||||
return e
|
||||
}
|
||||
|
||||
func (e *DebugNotificationProviderChangedEvent) UniqueConstraints() []*eventstore.EventUniqueConstraint {
|
||||
return nil
|
||||
}
|
||||
|
||||
func NewDebugNotificationProviderChangedEvent(
|
||||
base *eventstore.BaseEvent,
|
||||
changes []DebugNotificationProviderChanges,
|
||||
) (*DebugNotificationProviderChangedEvent, error) {
|
||||
if len(changes) == 0 {
|
||||
return nil, errors.ThrowPreconditionFailed(nil, "SET-hj90s", "Errors.NoChangesFound")
|
||||
}
|
||||
changeEvent := &DebugNotificationProviderChangedEvent{
|
||||
BaseEvent: *base,
|
||||
}
|
||||
for _, change := range changes {
|
||||
change(changeEvent)
|
||||
}
|
||||
return changeEvent, nil
|
||||
}
|
||||
|
||||
type DebugNotificationProviderChanges func(*DebugNotificationProviderChangedEvent)
|
||||
|
||||
func ChangeCompact(compact bool) func(*DebugNotificationProviderChangedEvent) {
|
||||
return func(e *DebugNotificationProviderChangedEvent) {
|
||||
e.Compact = &compact
|
||||
}
|
||||
}
|
||||
|
||||
func DebugNotificationProviderChangedEventMapper(event *repository.Event) (eventstore.Event, error) {
|
||||
e := &DebugNotificationProviderChangedEvent{
|
||||
BaseEvent: *eventstore.BaseEventFromRepo(event),
|
||||
}
|
||||
|
||||
err := json.Unmarshal(event.Data, e)
|
||||
if err != nil {
|
||||
return nil, errors.ThrowInternal(err, "POLIC-ehssl", "unable to unmarshal policy")
|
||||
}
|
||||
|
||||
return e, nil
|
||||
}
|
||||
|
||||
type DebugNotificationProviderRemovedEvent struct {
|
||||
eventstore.BaseEvent `json:"-"`
|
||||
}
|
||||
|
||||
func (e *DebugNotificationProviderRemovedEvent) Data() interface{} {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (e *DebugNotificationProviderRemovedEvent) UniqueConstraints() []*eventstore.EventUniqueConstraint {
|
||||
return nil
|
||||
}
|
||||
|
||||
func NewDebugNotificationProviderRemovedEvent(base *eventstore.BaseEvent) *DebugNotificationProviderRemovedEvent {
|
||||
return &DebugNotificationProviderRemovedEvent{
|
||||
BaseEvent: *base,
|
||||
}
|
||||
}
|
||||
|
||||
func DebugNotificationProviderRemovedEventMapper(event *repository.Event) (eventstore.Event, error) {
|
||||
return &DebugNotificationProviderRemovedEvent{
|
||||
BaseEvent: *eventstore.BaseEventFromRepo(event),
|
||||
}, nil
|
||||
}
|
@ -2,11 +2,11 @@ syntax = "proto3";
|
||||
|
||||
import "zitadel/idp.proto";
|
||||
import "zitadel/user.proto";
|
||||
import "zitadel/settings.proto";
|
||||
import "zitadel/object.proto";
|
||||
import "zitadel/options.proto";
|
||||
import "zitadel/org.proto";
|
||||
import "zitadel/policy.proto";
|
||||
import "zitadel/settings.proto";
|
||||
import "zitadel/text.proto";
|
||||
import "zitadel/member.proto";
|
||||
import "zitadel/features.proto";
|
||||
@ -336,6 +336,28 @@ service AdminService {
|
||||
};
|
||||
}
|
||||
|
||||
// Get file system notification provider
|
||||
rpc GetFileSystemNotificationProvider(GetFileSystemNotificationProviderRequest) returns (GetFileSystemNotificationProviderResponse) {
|
||||
option (google.api.http) = {
|
||||
get: "/notification/provider/file";
|
||||
};
|
||||
|
||||
option (zitadel.v1.auth_option) = {
|
||||
permission: "iam.read";
|
||||
};
|
||||
}
|
||||
|
||||
// Get log notification provider
|
||||
rpc GetLogNotificationProvider(GetLogNotificationProviderRequest) returns (GetLogNotificationProviderResponse) {
|
||||
option (google.api.http) = {
|
||||
get: "/notification/provider/log";
|
||||
};
|
||||
|
||||
option (zitadel.v1.auth_option) = {
|
||||
permission: "iam.read";
|
||||
};
|
||||
}
|
||||
|
||||
// Returns an organisation by id
|
||||
rpc GetOrgByID(GetOrgByIDRequest) returns (GetOrgByIDResponse) {
|
||||
option (google.api.http) = {
|
||||
@ -2561,6 +2583,20 @@ message UpdateSMSProviderTwilioTokenResponse {
|
||||
zitadel.v1.ObjectDetails details = 1;
|
||||
}
|
||||
|
||||
//This is an empty request
|
||||
message GetFileSystemNotificationProviderRequest {}
|
||||
|
||||
message GetFileSystemNotificationProviderResponse {
|
||||
zitadel.settings.v1.DebugNotificationProvider provider = 1;
|
||||
}
|
||||
|
||||
//This is an empty request
|
||||
message GetLogNotificationProviderRequest {}
|
||||
|
||||
message GetLogNotificationProviderResponse {
|
||||
zitadel.settings.v1.DebugNotificationProvider provider = 1;
|
||||
}
|
||||
|
||||
// This is an empty request
|
||||
message GetOIDCSettingsRequest {}
|
||||
|
||||
|
@ -72,6 +72,11 @@ enum SMSProviderConfigState {
|
||||
SMS_PROVIDER_CONFIG_INACTIVE = 2;
|
||||
}
|
||||
|
||||
message DebugNotificationProvider {
|
||||
zitadel.v1.ObjectDetails details = 1;
|
||||
bool compact = 2;
|
||||
}
|
||||
|
||||
message OIDCSettings {
|
||||
zitadel.v1.ObjectDetails details = 1;
|
||||
google.protobuf.Duration access_token_lifetime = 2;
|
||||
|
Loading…
x
Reference in New Issue
Block a user