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:
Fabi
2022-03-07 14:22:37 +01:00
committed by GitHub
parent 7d6c933485
commit 7899a0b851
47 changed files with 2489 additions and 200 deletions

View File

@@ -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)
}

View File

@@ -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)
}

View File

@@ -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)
}

View File

@@ -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)
}

View File

@@ -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)
}

View File

@@ -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)
}

View File

@@ -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{} {

View File

@@ -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)
}