feat: custom message text (#1801)

* feat: default custom message text

* feat: org custom message text

* feat: org custom message text

* feat: custom messages query side

* feat: default messages

* feat: message text user fields

* feat: check for inactive user

* feat: fix send password reset

* feat: fix custom org text

* feat: add variables to docs

* feat: custom text tests

* feat: fix notifications

* feat: add custom text feature

* feat: add custom text feature

* feat: feature in custom message texts

* feat: add custom text feature in frontend

* feat: merge main

* feat: feature tests

* feat: change phone message in setup

* fix: remove unused code, add event translation

* fix: merge main and fix problems

* fix: english translation file

* fix: migration versions

* fix: setup

* feat: fix pr requests

* feat: fix phone code message

* feat: migration

* feat: setup

* fix: remove unused tests

Co-authored-by: Livio Amstutz <livio.a@gmail.com>
This commit is contained in:
Fabi
2021-06-10 13:49:10 +02:00
committed by GitHub
parent 67462eefe0
commit bdf3887f9e
107 changed files with 4930 additions and 2715 deletions

View File

@@ -33,64 +33,23 @@ type IAM struct {
DefaultLoginPolicy *LoginPolicy `json:"-"`
DefaultLabelPolicy *LabelPolicy `json:"-"`
DefaultMailTemplate *MailTemplate `json:"-"`
DefaultMailTexts []*MailText `json:"-"`
DefaultOrgIAMPolicy *OrgIAMPolicy `json:"-"`
DefaultPasswordComplexityPolicy *PasswordComplexityPolicy `json:"-"`
DefaultPasswordAgePolicy *PasswordAgePolicy `json:"-"`
DefaultPasswordLockoutPolicy *PasswordLockoutPolicy `json:"-"`
}
func IAMFromModel(iam *model.IAM) *IAM {
members := IAMMembersFromModel(iam.Members)
idps := IDPConfigsFromModel(iam.IDPs)
mailTexts := MailTextsFromModel(iam.DefaultMailTexts)
converted := &IAM{
ObjectRoot: iam.ObjectRoot,
SetUpStarted: Step(iam.SetUpStarted),
SetUpDone: Step(iam.SetUpDone),
GlobalOrgID: iam.GlobalOrgID,
IAMProjectID: iam.IAMProjectID,
Members: members,
IDPs: idps,
DefaultMailTexts: mailTexts,
}
if iam.DefaultLoginPolicy != nil {
converted.DefaultLoginPolicy = LoginPolicyFromModel(iam.DefaultLoginPolicy)
}
if iam.DefaultLabelPolicy != nil {
converted.DefaultLabelPolicy = LabelPolicyFromModel(iam.DefaultLabelPolicy)
}
if iam.DefaultMailTemplate != nil {
converted.DefaultMailTemplate = MailTemplateFromModel(iam.DefaultMailTemplate)
}
if iam.DefaultPasswordComplexityPolicy != nil {
converted.DefaultPasswordComplexityPolicy = PasswordComplexityPolicyFromModel(iam.DefaultPasswordComplexityPolicy)
}
if iam.DefaultPasswordAgePolicy != nil {
converted.DefaultPasswordAgePolicy = PasswordAgePolicyFromModel(iam.DefaultPasswordAgePolicy)
}
if iam.DefaultPasswordLockoutPolicy != nil {
converted.DefaultPasswordLockoutPolicy = PasswordLockoutPolicyFromModel(iam.DefaultPasswordLockoutPolicy)
}
if iam.DefaultOrgIAMPolicy != nil {
converted.DefaultOrgIAMPolicy = OrgIAMPolicyFromModel(iam.DefaultOrgIAMPolicy)
}
return converted
}
func IAMToModel(iam *IAM) *model.IAM {
members := IAMMembersToModel(iam.Members)
idps := IDPConfigsToModel(iam.IDPs)
mailTexts := MailTextsToModel(iam.DefaultMailTexts)
converted := &model.IAM{
ObjectRoot: iam.ObjectRoot,
SetUpStarted: domain.Step(iam.SetUpStarted),
SetUpDone: domain.Step(iam.SetUpDone),
GlobalOrgID: iam.GlobalOrgID,
IAMProjectID: iam.IAMProjectID,
Members: members,
IDPs: idps,
DefaultMailTexts: mailTexts,
ObjectRoot: iam.ObjectRoot,
SetUpStarted: domain.Step(iam.SetUpStarted),
SetUpDone: domain.Step(iam.SetUpDone),
GlobalOrgID: iam.GlobalOrgID,
IAMProjectID: iam.IAMProjectID,
Members: members,
IDPs: idps,
}
if iam.DefaultLoginPolicy != nil {
converted.DefaultLoginPolicy = LoginPolicyToModel(iam.DefaultLoginPolicy)
@@ -199,10 +158,6 @@ func (i *IAM) AppendEvent(event *es_models.Event) (err error) {
return i.appendAddMailTemplateEvent(event)
case MailTemplateChanged:
return i.appendChangeMailTemplateEvent(event)
case MailTextAdded:
return i.appendAddMailTextEvent(event)
case MailTextChanged:
return i.appendChangeMailTextEvent(event)
case PasswordComplexityPolicyAdded:
return i.appendAddPasswordComplexityPolicyEvent(event)
case PasswordComplexityPolicyChanged:

View File

@@ -110,43 +110,6 @@ func (p *MailText) Changes(changed *MailText) map[string]interface{} {
return changes
}
func (i *IAM) appendAddMailTextEvent(event *es_models.Event) error {
mailText := &MailText{}
err := mailText.SetDataLabel(event)
if err != nil {
return err
}
mailText.ObjectRoot.CreationDate = event.CreationDate
i.DefaultMailTexts = append(i.DefaultMailTexts, mailText)
return nil
}
func (i *IAM) appendChangeMailTextEvent(event *es_models.Event) error {
mailText := &MailText{}
err := mailText.SetDataLabel(event)
if err != nil {
return err
}
if n, m := GetMailText(i.DefaultMailTexts, mailText.MailTextType, mailText.Language); m != nil {
i.DefaultMailTexts[n] = mailText
}
return nil
}
func (i *IAM) appendRemoveMailTextEvent(event *es_models.Event) error {
mailText := &MailText{}
err := mailText.SetDataLabel(event)
if err != nil {
return err
}
if n, m := GetMailText(i.DefaultMailTexts, mailText.MailTextType, mailText.Language); m != nil {
i.DefaultMailTexts[n] = i.DefaultMailTexts[len(i.DefaultMailTexts)-1]
i.DefaultMailTexts[len(i.DefaultMailTexts)-1] = nil
i.DefaultMailTexts = i.DefaultMailTexts[:len(i.DefaultMailTexts)-1]
}
return nil
}
func (p *MailText) SetDataLabel(event *es_models.Event) error {
err := json.Unmarshal(event.Data, p)
if err != nil {

View File

@@ -1,134 +0,0 @@
package model
import (
"encoding/json"
"testing"
es_models "github.com/caos/zitadel/internal/eventstore/v1/models"
)
func TestAppendAddMailTextEvent(t *testing.T) {
type args struct {
iam *IAM
mailText *MailText
event *es_models.Event
}
tests := []struct {
name string
args args
result *IAM
}{
{
name: "append add mailText event",
args: args{
iam: &IAM{},
mailText: &MailText{
MailTextType: "PasswordReset",
Language: "DE"},
event: &es_models.Event{},
},
result: &IAM{DefaultMailTexts: []*MailText{&MailText{
MailTextType: "PasswordReset",
Language: "DE"}}},
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
if tt.args.mailText != nil {
data, _ := json.Marshal(tt.args.mailText)
tt.args.event.Data = data
}
tt.args.iam.appendAddMailTextEvent(tt.args.event)
if len(tt.args.iam.DefaultMailTexts) != 1 {
t.Errorf("got wrong result should have one mailText actual: %v ", len(tt.args.iam.DefaultMailTexts))
}
if tt.args.iam.DefaultMailTexts[0] == tt.result.DefaultMailTexts[0] {
t.Errorf("got wrong result: expected: %v, actual: %v ", tt.result.DefaultMailTexts[0], tt.args.iam.DefaultMailTexts[0])
}
})
}
}
func TestAppendChangeMailTextEvent(t *testing.T) {
type args struct {
iam *IAM
mailText *MailText
event *es_models.Event
}
tests := []struct {
name string
args args
result *IAM
}{
{
name: "append change mailText event",
args: args{
iam: &IAM{DefaultMailTexts: []*MailText{&MailText{
MailTextType: "PasswordReset",
Language: "DE"}}},
mailText: &MailText{
MailTextType: "ChangedPasswordReset",
Language: "DE"},
event: &es_models.Event{},
},
result: &IAM{DefaultMailTexts: []*MailText{&MailText{
MailTextType: "PasswordReset",
Language: "ChangedDE"}}},
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
if tt.args.mailText != nil {
data, _ := json.Marshal(tt.args.mailText)
tt.args.event.Data = data
}
tt.args.iam.appendChangeMailTextEvent(tt.args.event)
if len(tt.args.iam.DefaultMailTexts) != 1 {
t.Errorf("got wrong result should have one mailText actual: %v ", len(tt.args.iam.DefaultMailTexts))
}
if tt.args.iam.DefaultMailTexts[0] == tt.result.DefaultMailTexts[0] {
t.Errorf("got wrong result: expected: %v, actual: %v ", tt.result.DefaultMailTexts[0], tt.args.iam.DefaultMailTexts[0])
}
})
}
}
func TestAppendRemoveMailTextEvent(t *testing.T) {
type args struct {
iam *IAM
mailText *MailText
event *es_models.Event
}
tests := []struct {
name string
args args
result *IAM
}{
{
name: "append remove mailText event",
args: args{
iam: &IAM{DefaultMailTexts: []*MailText{&MailText{
MailTextType: "PasswordReset",
Language: "DE",
Subject: "Subject"}}},
mailText: &MailText{
MailTextType: "PasswordReset",
Language: "DE"},
event: &es_models.Event{},
},
result: &IAM{DefaultMailTexts: []*MailText{}},
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
if tt.args.mailText != nil {
data, _ := json.Marshal(tt.args.mailText)
tt.args.event.Data = data
}
tt.args.iam.appendRemoveMailTextEvent(tt.args.event)
if len(tt.args.iam.DefaultMailTexts) != 0 {
t.Errorf("got wrong result should have no mailText actual: %v ", len(tt.args.iam.DefaultMailTexts))
}
})
}
}

View File

@@ -54,8 +54,9 @@ const (
MailTemplateAdded models.EventType = "iam.mail.template.added"
MailTemplateChanged models.EventType = "iam.mail.template.changed"
MailTextAdded models.EventType = "iam.mail.text.added"
MailTextChanged models.EventType = "iam.mail.text.changed"
CustomTextSet models.EventType = "iam.customtext.set"
CustomTextRemoved models.EventType = "iam.customtext.removed"
PasswordComplexityPolicyAdded models.EventType = "iam.policy.password.complexity.added"
PasswordComplexityPolicyChanged models.EventType = "iam.policy.password.complexity.changed"

View File

@@ -1,54 +0,0 @@
package view
import (
"github.com/caos/zitadel/internal/domain"
caos_errs "github.com/caos/zitadel/internal/errors"
iam_model "github.com/caos/zitadel/internal/iam/model"
"github.com/caos/zitadel/internal/iam/repository/view/model"
"github.com/caos/zitadel/internal/view/repository"
"github.com/jinzhu/gorm"
"strings"
)
func GetMailTexts(db *gorm.DB, table string, aggregateID string) ([]*model.MailTextView, error) {
texts := make([]*model.MailTextView, 0)
queries := []*iam_model.MailTextSearchQuery{
{
Key: iam_model.MailTextSearchKeyAggregateID,
Value: aggregateID,
Method: domain.SearchMethodEquals,
},
}
query := repository.PrepareSearchQuery(table, model.MailTextSearchRequest{Queries: queries})
_, err := query(db, &texts)
if err != nil {
return nil, err
}
return texts, nil
}
func GetMailTextByIDs(db *gorm.DB, table, aggregateID string, textType string, language string) (*model.MailTextView, error) {
mailText := new(model.MailTextView)
aggregateIDQuery := &model.MailTextSearchQuery{Key: iam_model.MailTextSearchKeyAggregateID, Value: aggregateID, Method: domain.SearchMethodEquals}
textTypeQuery := &model.MailTextSearchQuery{Key: iam_model.MailTextSearchKeyMailTextType, Value: textType, Method: domain.SearchMethodEquals}
languageQuery := &model.MailTextSearchQuery{Key: iam_model.MailTextSearchKeyLanguage, Value: strings.ToUpper(language), Method: domain.SearchMethodEquals}
query := repository.PrepareGetByQuery(table, aggregateIDQuery, textTypeQuery, languageQuery)
err := query(db, mailText)
if caos_errs.IsNotFound(err) {
return nil, caos_errs.ThrowNotFound(nil, "VIEW-IiJjm", "Errors.IAM.MailText.NotExisting")
}
return mailText, err
}
func PutMailText(db *gorm.DB, table string, mailText *model.MailTextView) error {
save := repository.PrepareSave(table)
return save(db, mailText)
}
func DeleteMailText(db *gorm.DB, table, aggregateID string, textType string, language string) error {
aggregateIDSearch := repository.Key{Key: model.MailTextSearchKey(iam_model.MailTextSearchKeyAggregateID), Value: aggregateID}
textTypeSearch := repository.Key{Key: model.MailTextSearchKey(iam_model.MailTextSearchKeyMailTextType), Value: textType}
languageSearch := repository.Key{Key: model.MailTextSearchKey(iam_model.MailTextSearchKeyLanguage), Value: language}
delete := repository.PrepareDeleteByKeys(table, aggregateIDSearch, textTypeSearch, languageSearch)
return delete(db)
}

View File

@@ -0,0 +1,54 @@
package view
import (
"github.com/jinzhu/gorm"
"github.com/caos/zitadel/internal/domain"
caos_errs "github.com/caos/zitadel/internal/errors"
iam_model "github.com/caos/zitadel/internal/iam/model"
"github.com/caos/zitadel/internal/iam/repository/view/model"
"github.com/caos/zitadel/internal/view/repository"
)
func GetMessageTexts(db *gorm.DB, table string, aggregateID string) ([]*model.MessageTextView, error) {
texts := make([]*model.MessageTextView, 0)
queries := []*iam_model.MessageTextSearchQuery{
{
Key: iam_model.MessageTextSearchKeyAggregateID,
Value: aggregateID,
Method: domain.SearchMethodEquals,
},
}
query := repository.PrepareSearchQuery(table, model.MessageTextSearchRequest{Queries: queries})
_, err := query(db, &texts)
if err != nil {
return nil, err
}
return texts, nil
}
func GetMessageTextByIDs(db *gorm.DB, table, aggregateID, textType, lang string) (*model.MessageTextView, error) {
mailText := new(model.MessageTextView)
aggregateIDQuery := &model.MessageTextSearchQuery{Key: iam_model.MessageTextSearchKeyAggregateID, Value: aggregateID, Method: domain.SearchMethodEquals}
textTypeQuery := &model.MessageTextSearchQuery{Key: iam_model.MessageTextSearchKeyMessageTextType, Value: textType, Method: domain.SearchMethodEquals}
languageQuery := &model.MessageTextSearchQuery{Key: iam_model.MessageTextSearchKeyLanguage, Value: lang, Method: domain.SearchMethodEquals}
query := repository.PrepareGetByQuery(table, aggregateIDQuery, textTypeQuery, languageQuery)
err := query(db, mailText)
if caos_errs.IsNotFound(err) {
return nil, caos_errs.ThrowNotFound(nil, "VIEW-IiJjm", "Errors.IAM.CustomMessageText.NotExisting")
}
return mailText, err
}
func PutMessageText(db *gorm.DB, table string, mailText *model.MessageTextView) error {
save := repository.PrepareSave(table)
return save(db, mailText)
}
func DeleteMessageText(db *gorm.DB, table, aggregateID, textType, lang string) error {
aggregateIDSearch := repository.Key{Key: model.MessageTextSearchKey(iam_model.MessageTextSearchKeyAggregateID), Value: aggregateID}
textTypeSearch := repository.Key{Key: model.MessageTextSearchKey(iam_model.MessageTextSearchKeyMessageTextType), Value: textType}
languageSearch := repository.Key{Key: model.MessageTextSearchKey(iam_model.MessageTextSearchKeyLanguage), Value: lang}
delete := repository.PrepareDeleteByKeys(table, aggregateIDSearch, textTypeSearch, languageSearch)
return delete(db)
}

View File

@@ -1,117 +0,0 @@
package model
import (
"encoding/json"
"time"
org_es_model "github.com/caos/zitadel/internal/org/repository/eventsourcing/model"
es_model "github.com/caos/zitadel/internal/iam/repository/eventsourcing/model"
"github.com/caos/logging"
caos_errs "github.com/caos/zitadel/internal/errors"
"github.com/caos/zitadel/internal/eventstore/v1/models"
"github.com/caos/zitadel/internal/iam/model"
)
const (
MailTextKeyAggregateID = "aggregate_id"
MailTextKeyMailTextType = "mail_text_type"
MailTextKeyLanguage = "language"
)
type MailTextView struct {
AggregateID string `json:"-" gorm:"column:aggregate_id;primary_key"`
CreationDate time.Time `json:"-" gorm:"column:creation_date"`
ChangeDate time.Time `json:"-" gorm:"column:change_date"`
State int32 `json:"-" gorm:"column:mail_text_state"`
MailTextType string `json:"mailTextType" gorm:"column:mail_text_type;primary_key"`
Language string `json:"language" gorm:"column:language;primary_key"`
Title string `json:"title" gorm:"column:title"`
PreHeader string `json:"preHeader" gorm:"column:pre_header"`
Subject string `json:"subject" gorm:"column:subject"`
Greeting string `json:"greeting" gorm:"column:greeting"`
Text string `json:"text" gorm:"column:text"`
ButtonText string `json:"buttonText" gorm:"column:button_text"`
Default bool `json:"-" gorm:"-"`
Sequence uint64 `json:"-" gorm:"column:sequence"`
}
func MailTextViewFromModel(template *model.MailTextView) *MailTextView {
return &MailTextView{
AggregateID: template.AggregateID,
Sequence: template.Sequence,
CreationDate: template.CreationDate,
ChangeDate: template.ChangeDate,
MailTextType: template.MailTextType,
Language: template.Language,
Title: template.Title,
PreHeader: template.PreHeader,
Subject: template.Subject,
Greeting: template.Greeting,
Text: template.Text,
ButtonText: template.ButtonText,
Default: template.Default,
}
}
func MailTextsViewToModel(textsIn []*MailTextView, defaultIn bool) *model.MailTextsView {
return &model.MailTextsView{
Texts: mailTextsViewToModelArr(textsIn, defaultIn),
}
}
func mailTextsViewToModelArr(texts []*MailTextView, defaultIn bool) []*model.MailTextView {
result := make([]*model.MailTextView, len(texts))
for i, r := range texts {
r.Default = defaultIn
result[i] = MailTextViewToModel(r)
}
return result
}
func MailTextViewToModel(template *MailTextView) *model.MailTextView {
return &model.MailTextView{
AggregateID: template.AggregateID,
Sequence: template.Sequence,
CreationDate: template.CreationDate,
ChangeDate: template.ChangeDate,
MailTextType: template.MailTextType,
Language: template.Language,
Title: template.Title,
PreHeader: template.PreHeader,
Subject: template.Subject,
Greeting: template.Greeting,
Text: template.Text,
ButtonText: template.ButtonText,
Default: template.Default,
}
}
func (i *MailTextView) AppendEvent(event *models.Event) (err error) {
i.Sequence = event.Sequence
switch event.Type {
case es_model.MailTextAdded, org_es_model.MailTextAdded:
i.setRootData(event)
i.CreationDate = event.CreationDate
err = i.SetData(event)
case es_model.MailTextChanged, org_es_model.MailTextChanged:
i.ChangeDate = event.CreationDate
err = i.SetData(event)
}
return err
}
func (r *MailTextView) setRootData(event *models.Event) {
r.AggregateID = event.AggregateID
}
func (r *MailTextView) SetData(event *models.Event) error {
if err := json.Unmarshal(event.Data, r); err != nil {
logging.Log("MODEL-UFqAG").WithError(err).Error("could not unmarshal event data")
return caos_errs.ThrowInternal(err, "MODEL-5CVaR", "Could not unmarshal data")
}
return nil
}

View File

@@ -1,63 +0,0 @@
package model
import (
"github.com/caos/zitadel/internal/domain"
iam_model "github.com/caos/zitadel/internal/iam/model"
"github.com/caos/zitadel/internal/view/repository"
)
type MailTextSearchRequest iam_model.MailTextSearchRequest
type MailTextSearchQuery iam_model.MailTextSearchQuery
type MailTextSearchKey iam_model.MailTextSearchKey
func (req MailTextSearchRequest) GetLimit() uint64 {
return req.Limit
}
func (req MailTextSearchRequest) GetOffset() uint64 {
return req.Offset
}
func (req MailTextSearchRequest) GetSortingColumn() repository.ColumnKey {
if req.SortingColumn == iam_model.MailTextSearchKeyUnspecified {
return nil
}
return MailTextSearchKey(req.SortingColumn)
}
func (req MailTextSearchRequest) GetAsc() bool {
return req.Asc
}
func (req MailTextSearchRequest) GetQueries() []repository.SearchQuery {
result := make([]repository.SearchQuery, len(req.Queries))
for i, q := range req.Queries {
result[i] = MailTextSearchQuery{Key: q.Key, Value: q.Value, Method: q.Method}
}
return result
}
func (req MailTextSearchQuery) GetKey() repository.ColumnKey {
return MailTextSearchKey(req.Key)
}
func (req MailTextSearchQuery) GetMethod() domain.SearchMethod {
return req.Method
}
func (req MailTextSearchQuery) GetValue() interface{} {
return req.Value
}
func (key MailTextSearchKey) ToColumnName() string {
switch iam_model.MailTextSearchKey(key) {
case iam_model.MailTextSearchKeyAggregateID:
return MailTextKeyAggregateID
case iam_model.MailTextSearchKeyMailTextType:
return MailTextKeyMailTextType
case iam_model.MailTextSearchKeyLanguage:
return MailTextKeyLanguage
default:
return ""
}
}

View File

@@ -0,0 +1,184 @@
package model
import (
"encoding/json"
"time"
"golang.org/x/text/language"
"github.com/caos/zitadel/internal/domain"
org_es_model "github.com/caos/zitadel/internal/org/repository/eventsourcing/model"
es_model "github.com/caos/zitadel/internal/iam/repository/eventsourcing/model"
"github.com/caos/logging"
caos_errs "github.com/caos/zitadel/internal/errors"
"github.com/caos/zitadel/internal/eventstore/v1/models"
"github.com/caos/zitadel/internal/iam/model"
)
const (
MessageTextKeyAggregateID = "aggregate_id"
MessageTextKeyMessageTextType = "message_text_type"
MessageTextKeyLanguage = "language"
)
type MessageTextView struct {
AggregateID string `json:"-" gorm:"column:aggregate_id;primary_key"`
CreationDate time.Time `json:"-" gorm:"column:creation_date"`
ChangeDate time.Time `json:"-" gorm:"column:change_date"`
State int32 `json:"-" gorm:"column:message_text_state"`
MessageTextType string `json:"-" gorm:"column:message_text_type;primary_key"`
Language string `json:"-" gorm:"column:language;primary_key"`
Title string `json:"-" gorm:"column:title"`
PreHeader string `json:"-" gorm:"column:pre_header"`
Subject string `json:"-" gorm:"column:subject"`
Greeting string `json:"-" gorm:"column:greeting"`
Text string `json:"-" gorm:"column:text"`
ButtonText string `json:"-" gorm:"column:button_text"`
FooterText string `json:"-" gorm:"column:footer_text"`
Default bool `json:"-" gorm:"-"`
Sequence uint64 `json:"-" gorm:"column:sequence"`
}
func MessageTextViewFromModel(template *model.MessageTextView) *MessageTextView {
return &MessageTextView{
AggregateID: template.AggregateID,
Sequence: template.Sequence,
CreationDate: template.CreationDate,
ChangeDate: template.ChangeDate,
MessageTextType: template.MessageTextType,
Language: template.Language.String(),
Title: template.Title,
PreHeader: template.PreHeader,
Subject: template.Subject,
Greeting: template.Greeting,
Text: template.Text,
ButtonText: template.ButtonText,
FooterText: template.FooterText,
Default: template.Default,
}
}
func MessageTextsViewToModel(textsIn []*MessageTextView, defaultIn bool) *model.MessageTextsView {
return &model.MessageTextsView{
Texts: messageTextsViewToModelArr(textsIn, defaultIn),
}
}
func messageTextsViewToModelArr(texts []*MessageTextView, defaultIn bool) []*model.MessageTextView {
result := make([]*model.MessageTextView, len(texts))
for i, r := range texts {
r.Default = defaultIn
result[i] = MessageTextViewToModel(r)
}
return result
}
func MessageTextViewToModel(template *MessageTextView) *model.MessageTextView {
lang := language.Make(template.Language)
return &model.MessageTextView{
AggregateID: template.AggregateID,
Sequence: template.Sequence,
CreationDate: template.CreationDate,
ChangeDate: template.ChangeDate,
MessageTextType: template.MessageTextType,
Language: lang,
Title: template.Title,
PreHeader: template.PreHeader,
Subject: template.Subject,
Greeting: template.Greeting,
Text: template.Text,
ButtonText: template.ButtonText,
FooterText: template.FooterText,
Default: template.Default,
}
}
func (i *MessageTextView) AppendEvent(event *models.Event) (err error) {
i.Sequence = event.Sequence
switch event.Type {
case es_model.CustomTextSet, org_es_model.CustomTextSet:
i.setRootData(event)
customText := new(CustomText)
err = customText.SetData(event)
if err != nil {
return err
}
if customText.Key == domain.MessageTitle {
i.Title = customText.Text
}
if customText.Key == domain.MessagePreHeader {
i.PreHeader = customText.Text
}
if customText.Key == domain.MessageSubject {
i.Subject = customText.Text
}
if customText.Key == domain.MessageGreeting {
i.Greeting = customText.Text
}
if customText.Key == domain.MessageText {
i.Text = customText.Text
}
if customText.Key == domain.MessageButtonText {
i.ButtonText = customText.Text
}
if customText.Key == domain.MessageFooterText {
i.FooterText = customText.Text
}
i.ChangeDate = event.CreationDate
case es_model.CustomTextRemoved, org_es_model.CustomTextRemoved:
customText := new(CustomText)
err = customText.SetData(event)
if err != nil {
return err
}
if customText.Key == domain.MessageTitle {
i.Title = ""
}
if customText.Key == domain.MessagePreHeader {
i.PreHeader = ""
}
if customText.Key == domain.MessageSubject {
i.Subject = ""
}
if customText.Key == domain.MessageGreeting {
i.Greeting = ""
}
if customText.Key == domain.MessageText {
i.Text = ""
}
if customText.Key == domain.MessageButtonText {
i.ButtonText = ""
}
if customText.Key == domain.MessageFooterText {
i.FooterText = ""
}
i.ChangeDate = event.CreationDate
case org_es_model.CustomTextMessageRemoved:
i.State = int32(model.PolicyStateRemoved)
}
return err
}
func (r *MessageTextView) setRootData(event *models.Event) {
r.AggregateID = event.AggregateID
}
type CustomText struct {
Template string `json:"template"`
Key string `json:"key"`
Language language.Tag `json:"language"`
Text string `json:"text"`
}
func (r *CustomText) SetData(event *models.Event) error {
if err := json.Unmarshal(event.Data, r); err != nil {
logging.Log("MODEL-3n9fs").WithError(err).Error("could not unmarshal event data")
return caos_errs.ThrowInternal(err, "MODEL-5CVaR", "Could not unmarshal data")
}
return nil
}

View File

@@ -0,0 +1,63 @@
package model
import (
"github.com/caos/zitadel/internal/domain"
iam_model "github.com/caos/zitadel/internal/iam/model"
"github.com/caos/zitadel/internal/view/repository"
)
type MessageTextSearchRequest iam_model.MessageTextSearchRequest
type MessageTextSearchQuery iam_model.MessageTextSearchQuery
type MessageTextSearchKey iam_model.MessageTextSearchKey
func (req MessageTextSearchRequest) GetLimit() uint64 {
return req.Limit
}
func (req MessageTextSearchRequest) GetOffset() uint64 {
return req.Offset
}
func (req MessageTextSearchRequest) GetSortingColumn() repository.ColumnKey {
if req.SortingColumn == iam_model.MessageTextSearchKeyUnspecified {
return nil
}
return MessageTextSearchKey(req.SortingColumn)
}
func (req MessageTextSearchRequest) GetAsc() bool {
return req.Asc
}
func (req MessageTextSearchRequest) GetQueries() []repository.SearchQuery {
result := make([]repository.SearchQuery, len(req.Queries))
for i, q := range req.Queries {
result[i] = MessageTextSearchQuery{Key: q.Key, Value: q.Value, Method: q.Method}
}
return result
}
func (req MessageTextSearchQuery) GetKey() repository.ColumnKey {
return MessageTextSearchKey(req.Key)
}
func (req MessageTextSearchQuery) GetMethod() domain.SearchMethod {
return req.Method
}
func (req MessageTextSearchQuery) GetValue() interface{} {
return req.Value
}
func (key MessageTextSearchKey) ToColumnName() string {
switch iam_model.MessageTextSearchKey(key) {
case iam_model.MessageTextSearchKeyAggregateID:
return MessageTextKeyAggregateID
case iam_model.MessageTextSearchKeyMessageTextType:
return MessageTextKeyMessageTextType
case iam_model.MessageTextSearchKeyLanguage:
return MessageTextKeyLanguage
default:
return ""
}
}