mirror of
https://github.com/zitadel/zitadel.git
synced 2025-11-15 03:06:02 +00:00
feat: e-mail templates (#1158)
* View definition added * Get templates and texts from the database. * Fill in texts in templates * Fill in texts in templates * Client API added * Weekly backup * Weekly backup * Daily backup * Weekly backup * Tests added * Corrections from merge branch * Fixes from pull request review
This commit is contained in:
@@ -964,3 +964,118 @@ func (es *IAMEventstore) ChangeOrgIAMPolicy(ctx context.Context, policy *iam_mod
|
||||
es.iamCache.cacheIAM(repoIam)
|
||||
return model.OrgIAMPolicyToModel(repoIam.DefaultOrgIAMPolicy), nil
|
||||
}
|
||||
|
||||
func (es *IAMEventstore) PrepareAddMailTemplate(ctx context.Context, template *iam_model.MailTemplate) (*model.IAM, *models.Aggregate, error) {
|
||||
if template == nil || !template.IsValid() {
|
||||
return nil, nil, caos_errs.ThrowPreconditionFailed(nil, "EVENT-j9l18", "Errors.IAM.MailTemplate.Empty")
|
||||
}
|
||||
iam, err := es.IAMByID(ctx, template.AggregateID)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
repoIam := model.IAMFromModel(iam)
|
||||
mailTemplate := model.MailTemplateFromModel(template)
|
||||
|
||||
addAggregate := MailTemplateAddedAggregate(es.Eventstore.AggregateCreator(), repoIam, mailTemplate)
|
||||
aggregate, err := addAggregate(ctx)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
return repoIam, aggregate, nil
|
||||
}
|
||||
|
||||
func (es *IAMEventstore) AddMailTemplate(ctx context.Context, template *iam_model.MailTemplate) (*iam_model.MailTemplate, error) {
|
||||
repoIam, addAggregate, err := es.PrepareAddMailTemplate(ctx, template)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
err = es_sdk.PushAggregates(ctx, es.PushAggregates, repoIam.AppendEvents, addAggregate)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
es.iamCache.cacheIAM(repoIam)
|
||||
return model.MailTemplateToModel(repoIam.DefaultMailTemplate), nil
|
||||
}
|
||||
|
||||
func (es *IAMEventstore) ChangeMailTemplate(ctx context.Context, template *iam_model.MailTemplate) (*iam_model.MailTemplate, error) {
|
||||
if template == nil || !template.IsValid() {
|
||||
return nil, caos_errs.ThrowPreconditionFailed(nil, "EVENT-gCnCs", "Errors.IAM.MailTemplateInvalid")
|
||||
}
|
||||
iam, err := es.IAMByID(ctx, template.AggregateID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
repoIam := model.IAMFromModel(iam)
|
||||
repoMailTemplate := model.MailTemplateFromModel(template)
|
||||
|
||||
addAggregate := MailTemplateChangedAggregate(es.Eventstore.AggregateCreator(), repoIam, repoMailTemplate)
|
||||
err = es_sdk.Push(ctx, es.PushAggregates, repoIam.AppendEvents, addAggregate)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
es.iamCache.cacheIAM(repoIam)
|
||||
return model.MailTemplateToModel(repoIam.DefaultMailTemplate), nil
|
||||
}
|
||||
|
||||
func (es *IAMEventstore) PrepareAddMailText(ctx context.Context, text *iam_model.MailText) (*model.IAM, *models.Aggregate, error) {
|
||||
if text == nil || !text.IsValid() {
|
||||
return nil, nil, caos_errs.ThrowPreconditionFailed(nil, "EVENT-j9l18", "Errors.IAM.MailText.Empty")
|
||||
}
|
||||
iam, err := es.IAMByID(ctx, text.AggregateID)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
repoIam := model.IAMFromModel(iam)
|
||||
mailText := model.MailTextFromModel(text)
|
||||
|
||||
addAggregate := MailTextAddedAggregate(es.Eventstore.AggregateCreator(), repoIam, mailText)
|
||||
aggregate, err := addAggregate(ctx)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
return repoIam, aggregate, nil
|
||||
}
|
||||
|
||||
func (es *IAMEventstore) AddMailText(ctx context.Context, text *iam_model.MailText) (*iam_model.MailText, error) {
|
||||
repoIam, addAggregate, err := es.PrepareAddMailText(ctx, text)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
err = es_sdk.PushAggregates(ctx, es.PushAggregates, repoIam.AppendEvents, addAggregate)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
es.iamCache.cacheIAM(repoIam)
|
||||
|
||||
if _, m := model.GetMailText(repoIam.DefaultMailTexts, text.MailTextType, text.Language); m != nil {
|
||||
return model.MailTextToModel(m), nil
|
||||
}
|
||||
return nil, caos_errs.ThrowInternal(nil, "EVENT-9AwUm", "Errors.Internal")
|
||||
}
|
||||
|
||||
func (es *IAMEventstore) ChangeMailText(ctx context.Context, text *iam_model.MailText) (*iam_model.MailText, error) {
|
||||
if !text.IsValid() {
|
||||
return nil, caos_errs.ThrowPreconditionFailed(nil, "EVENT-J5xbB", "Errors.IAM.MailTextInvalid")
|
||||
}
|
||||
existing, err := es.IAMByID(ctx, text.AggregateID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if _, m := existing.GetDefaultMailText(text.MailTextType, text.Language); m == nil {
|
||||
return nil, caos_errs.ThrowPreconditionFailed(nil, "EVENT-0CTV3", "Errors.IAM.MailTextNotExisting")
|
||||
}
|
||||
repoIam := model.IAMFromModel(existing)
|
||||
repoMember := model.MailTextFromModel(text)
|
||||
|
||||
projectAggregate := MailTextChangedAggregate(es.Eventstore.AggregateCreator(), repoIam, repoMember)
|
||||
err = es_sdk.Push(ctx, es.PushAggregates, repoIam.AppendEvents, projectAggregate)
|
||||
es.iamCache.cacheIAM(repoIam)
|
||||
|
||||
if _, m := model.GetMailText(repoIam.DefaultMailTexts, text.MailTextType, text.Language); m != nil {
|
||||
return model.MailTextToModel(m), nil
|
||||
}
|
||||
return nil, caos_errs.ThrowInternal(nil, "EVENT-HawVx", "Errors.Internal")
|
||||
}
|
||||
|
||||
@@ -216,3 +216,29 @@ func GetMockManipulateIAMWithLabelPolicy(ctrl *gomock.Controller) *IAMEventstore
|
||||
mockEs.EXPECT().PushAggregates(gomock.Any(), gomock.Any()).Return(nil)
|
||||
return GetMockedEventstore(ctrl, mockEs)
|
||||
}
|
||||
|
||||
func GetMockManipulateIAMWithMailTemplate(ctrl *gomock.Controller) *IAMEventstore {
|
||||
mailTemplate, _ := json.Marshal(model.MailTemplate{Template: []byte("<!doctype htm>")})
|
||||
events := []*es_models.Event{
|
||||
&es_models.Event{AggregateID: "AggregateID", Sequence: 1, Type: model.IAMSetupStarted},
|
||||
&es_models.Event{AggregateID: "AggregateID", Sequence: 1, Type: model.MailTemplateAdded, Data: mailTemplate},
|
||||
}
|
||||
mockEs := mock.NewMockEventstore(ctrl)
|
||||
mockEs.EXPECT().FilterEvents(gomock.Any(), gomock.Any()).Return(events, nil)
|
||||
mockEs.EXPECT().AggregateCreator().Return(es_models.NewAggregateCreator("TEST"))
|
||||
mockEs.EXPECT().PushAggregates(gomock.Any(), gomock.Any()).Return(nil)
|
||||
return GetMockedEventstore(ctrl, mockEs)
|
||||
}
|
||||
|
||||
func GetMockManipulateIAMWithMailText(ctrl *gomock.Controller) *IAMEventstore {
|
||||
mailText, _ := json.Marshal(model.MailText{MailTextType: "Type", Language: "DE"})
|
||||
events := []*es_models.Event{
|
||||
&es_models.Event{AggregateID: "AggregateID", Sequence: 1, Type: model.IAMSetupStarted},
|
||||
&es_models.Event{AggregateID: "AggregateID", Sequence: 1, Type: model.MailTextAdded, Data: mailText},
|
||||
}
|
||||
mockEs := mock.NewMockEventstore(ctrl)
|
||||
mockEs.EXPECT().FilterEvents(gomock.Any(), gomock.Any()).Return(events, nil)
|
||||
mockEs.EXPECT().AggregateCreator().Return(es_models.NewAggregateCreator("TEST"))
|
||||
mockEs.EXPECT().PushAggregates(gomock.Any(), gomock.Any()).Return(nil)
|
||||
return GetMockedEventstore(ctrl, mockEs)
|
||||
}
|
||||
|
||||
@@ -2815,3 +2815,321 @@ func TestChangeOrgIAMPolicy(t *testing.T) {
|
||||
})
|
||||
}
|
||||
}
|
||||
func TestAddMailTemplate(t *testing.T) {
|
||||
ctrl := gomock.NewController(t)
|
||||
type args struct {
|
||||
es *IAMEventstore
|
||||
ctx context.Context
|
||||
policy *iam_model.MailTemplate
|
||||
}
|
||||
type res struct {
|
||||
result *iam_model.MailTemplate
|
||||
wantErr bool
|
||||
errFunc func(err error) bool
|
||||
}
|
||||
tests := []struct {
|
||||
name string
|
||||
args args
|
||||
res res
|
||||
}{
|
||||
{
|
||||
name: "add mailtemplate, ok",
|
||||
args: args{
|
||||
es: GetMockManipulateIAM(ctrl),
|
||||
ctx: authz.NewMockContext("orgID", "userID"),
|
||||
policy: &iam_model.MailTemplate{
|
||||
ObjectRoot: es_models.ObjectRoot{AggregateID: "AggregateID", Sequence: 0},
|
||||
Template: []byte("<!doctype html>"),
|
||||
},
|
||||
},
|
||||
res: res{
|
||||
result: &iam_model.MailTemplate{
|
||||
ObjectRoot: es_models.ObjectRoot{AggregateID: "AggregateID", Sequence: 0},
|
||||
Template: []byte("<!doctype html>"),
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "invalid policy",
|
||||
args: args{
|
||||
es: GetMockManipulateIAM(ctrl),
|
||||
ctx: authz.NewMockContext("orgID", "userID"),
|
||||
policy: &iam_model.MailTemplate{
|
||||
ObjectRoot: es_models.ObjectRoot{Sequence: 0},
|
||||
},
|
||||
},
|
||||
res: res{
|
||||
wantErr: true,
|
||||
errFunc: caos_errs.IsPreconditionFailed,
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "existing iam not found",
|
||||
args: args{
|
||||
es: GetMockManipulateIAMNotExisting(ctrl),
|
||||
ctx: authz.NewMockContext("orgID", "userID"),
|
||||
policy: &iam_model.MailTemplate{
|
||||
ObjectRoot: es_models.ObjectRoot{AggregateID: "AggregateID", Sequence: 0},
|
||||
},
|
||||
},
|
||||
res: res{
|
||||
wantErr: true,
|
||||
errFunc: caos_errs.IsNotFound,
|
||||
},
|
||||
},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
result, err := tt.args.es.AddMailTemplate(tt.args.ctx, tt.args.policy)
|
||||
if (tt.res.wantErr && !tt.res.errFunc(err)) || (err != nil && !tt.res.wantErr) {
|
||||
t.Errorf("got wrong err: %v ", err)
|
||||
return
|
||||
}
|
||||
if tt.res.wantErr && tt.res.errFunc(err) {
|
||||
return
|
||||
}
|
||||
if string(result.Template) != string(tt.res.result.Template) {
|
||||
t.Errorf("got wrong result Template: expected: %v, actual: %v ", tt.res.result.Template, result.Template)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestChangeMailTemplate(t *testing.T) {
|
||||
ctrl := gomock.NewController(t)
|
||||
type args struct {
|
||||
es *IAMEventstore
|
||||
ctx context.Context
|
||||
template *iam_model.MailTemplate
|
||||
}
|
||||
type res struct {
|
||||
result *iam_model.MailTemplate
|
||||
wantErr bool
|
||||
errFunc func(err error) bool
|
||||
}
|
||||
tests := []struct {
|
||||
name string
|
||||
args args
|
||||
res res
|
||||
}{
|
||||
{
|
||||
name: "add mail template, ok",
|
||||
args: args{
|
||||
es: GetMockManipulateIAMWithMailTemplate(ctrl),
|
||||
ctx: authz.NewMockContext("orgID", "userID"),
|
||||
template: &iam_model.MailTemplate{
|
||||
ObjectRoot: es_models.ObjectRoot{AggregateID: "AggregateID", Sequence: 0},
|
||||
Template: []byte("<!doctype html>"),
|
||||
},
|
||||
},
|
||||
res: res{
|
||||
result: &iam_model.MailTemplate{
|
||||
ObjectRoot: es_models.ObjectRoot{AggregateID: "AggregateID", Sequence: 0},
|
||||
Template: []byte("<!doctype html>"),
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "invalid mail template",
|
||||
args: args{
|
||||
es: GetMockManipulateIAM(ctrl),
|
||||
ctx: authz.NewMockContext("orgID", "userID"),
|
||||
template: &iam_model.MailTemplate{
|
||||
ObjectRoot: es_models.ObjectRoot{Sequence: 0},
|
||||
},
|
||||
},
|
||||
res: res{
|
||||
wantErr: true,
|
||||
errFunc: caos_errs.IsPreconditionFailed,
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "existing iam not found",
|
||||
args: args{
|
||||
es: GetMockManipulateIAMNotExisting(ctrl),
|
||||
ctx: authz.NewMockContext("orgID", "userID"),
|
||||
template: &iam_model.MailTemplate{
|
||||
ObjectRoot: es_models.ObjectRoot{AggregateID: "AggregateID", Sequence: 0},
|
||||
},
|
||||
},
|
||||
res: res{
|
||||
wantErr: true,
|
||||
errFunc: caos_errs.IsNotFound,
|
||||
},
|
||||
},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
result, err := tt.args.es.ChangeMailTemplate(tt.args.ctx, tt.args.template)
|
||||
if (tt.res.wantErr && !tt.res.errFunc(err)) || (err != nil && !tt.res.wantErr) {
|
||||
t.Errorf("got wrong err: %v ", err)
|
||||
return
|
||||
}
|
||||
if tt.res.wantErr && tt.res.errFunc(err) {
|
||||
return
|
||||
}
|
||||
if string(result.Template) != string(tt.res.result.Template) {
|
||||
t.Errorf("got wrong result Template: expected: %v, actual: %v ", tt.res.result.Template, result.Template)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
func TestAddMailText(t *testing.T) {
|
||||
ctrl := gomock.NewController(t)
|
||||
type args struct {
|
||||
es *IAMEventstore
|
||||
ctx context.Context
|
||||
policy *iam_model.MailText
|
||||
}
|
||||
type res struct {
|
||||
result *iam_model.MailText
|
||||
wantErr bool
|
||||
errFunc func(err error) bool
|
||||
}
|
||||
tests := []struct {
|
||||
name string
|
||||
args args
|
||||
res res
|
||||
}{
|
||||
{
|
||||
name: "add mailtemplate, ok",
|
||||
args: args{
|
||||
es: GetMockManipulateIAM(ctrl),
|
||||
ctx: authz.NewMockContext("orgID", "userID"),
|
||||
policy: &iam_model.MailText{
|
||||
ObjectRoot: es_models.ObjectRoot{AggregateID: "AggregateID", Sequence: 0},
|
||||
MailTextType: "Type", Language: "DE",
|
||||
},
|
||||
},
|
||||
res: res{
|
||||
result: &iam_model.MailText{
|
||||
ObjectRoot: es_models.ObjectRoot{AggregateID: "AggregateID", Sequence: 0},
|
||||
MailTextType: "Type", Language: "DE",
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "invalid policy",
|
||||
args: args{
|
||||
es: GetMockManipulateIAM(ctrl),
|
||||
ctx: authz.NewMockContext("orgID", "userID"),
|
||||
policy: &iam_model.MailText{
|
||||
ObjectRoot: es_models.ObjectRoot{Sequence: 0},
|
||||
},
|
||||
},
|
||||
res: res{
|
||||
wantErr: true,
|
||||
errFunc: caos_errs.IsPreconditionFailed,
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "existing iam not found",
|
||||
args: args{
|
||||
es: GetMockManipulateIAMNotExisting(ctrl),
|
||||
ctx: authz.NewMockContext("orgID", "userID"),
|
||||
policy: &iam_model.MailText{
|
||||
ObjectRoot: es_models.ObjectRoot{AggregateID: "AggregateID", Sequence: 0},
|
||||
},
|
||||
},
|
||||
res: res{
|
||||
wantErr: true,
|
||||
errFunc: caos_errs.IsNotFound,
|
||||
},
|
||||
},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
result, err := tt.args.es.AddMailText(tt.args.ctx, tt.args.policy)
|
||||
if (tt.res.wantErr && !tt.res.errFunc(err)) || (err != nil && !tt.res.wantErr) {
|
||||
t.Errorf("got wrong err: %v ", err)
|
||||
return
|
||||
}
|
||||
if tt.res.wantErr && tt.res.errFunc(err) {
|
||||
return
|
||||
}
|
||||
if string(result.MailTextType) != string(tt.res.result.MailTextType) {
|
||||
t.Errorf("got wrong result MailTextType: expected: %v, actual: %v ", tt.res.result.MailTextType, result.MailTextType)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestChangeMailText(t *testing.T) {
|
||||
ctrl := gomock.NewController(t)
|
||||
type args struct {
|
||||
es *IAMEventstore
|
||||
ctx context.Context
|
||||
policy *iam_model.MailText
|
||||
}
|
||||
type res struct {
|
||||
result *iam_model.MailText
|
||||
wantErr bool
|
||||
errFunc func(err error) bool
|
||||
}
|
||||
tests := []struct {
|
||||
name string
|
||||
args args
|
||||
res res
|
||||
}{
|
||||
{
|
||||
name: "change mailtemplate, ok",
|
||||
args: args{
|
||||
es: GetMockManipulateIAMWithMailText(ctrl),
|
||||
ctx: authz.NewMockContext("orgID", "userID"),
|
||||
policy: &iam_model.MailText{
|
||||
ObjectRoot: es_models.ObjectRoot{AggregateID: "AggregateID", Sequence: 0},
|
||||
MailTextType: "Type", Language: "DE",
|
||||
},
|
||||
},
|
||||
res: res{
|
||||
result: &iam_model.MailText{
|
||||
ObjectRoot: es_models.ObjectRoot{AggregateID: "AggregateID", Sequence: 0},
|
||||
MailTextType: "Type", Language: "DE",
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "invalid policy",
|
||||
args: args{
|
||||
es: GetMockManipulateIAM(ctrl),
|
||||
ctx: authz.NewMockContext("orgID", "userID"),
|
||||
policy: &iam_model.MailText{
|
||||
ObjectRoot: es_models.ObjectRoot{Sequence: 0},
|
||||
},
|
||||
},
|
||||
res: res{
|
||||
wantErr: true,
|
||||
errFunc: caos_errs.IsPreconditionFailed,
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "existing iam not found",
|
||||
args: args{
|
||||
es: GetMockManipulateIAMNotExisting(ctrl),
|
||||
ctx: authz.NewMockContext("orgID", "userID"),
|
||||
policy: &iam_model.MailText{
|
||||
ObjectRoot: es_models.ObjectRoot{AggregateID: "AggregateID", Sequence: 0},
|
||||
},
|
||||
},
|
||||
res: res{
|
||||
wantErr: true,
|
||||
errFunc: caos_errs.IsNotFound,
|
||||
},
|
||||
},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
result, err := tt.args.es.ChangeMailText(tt.args.ctx, tt.args.policy)
|
||||
if (tt.res.wantErr && !tt.res.errFunc(err)) || (err != nil && !tt.res.wantErr) {
|
||||
t.Errorf("got wrong err: %v ", err)
|
||||
return
|
||||
}
|
||||
if tt.res.wantErr && tt.res.errFunc(err) {
|
||||
return
|
||||
}
|
||||
if string(result.MailTextType) != string(tt.res.result.MailTextType) {
|
||||
t.Errorf("got wrong result MailTextType: expected: %v, actual: %v ", tt.res.result.MailTextType, result.MailTextType)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
@@ -232,6 +232,7 @@ func OIDCIDPConfigChangedAggregate(aggCreator *es_models.AggregateCreator, exist
|
||||
return agg.AppendEvent(model.OIDCIDPConfigChanged, changes)
|
||||
}
|
||||
}
|
||||
|
||||
func LabelPolicyAddedAggregate(aggCreator *es_models.AggregateCreator, existing *model.IAM, policy *model.LabelPolicy) func(ctx context.Context) (*es_models.Aggregate, error) {
|
||||
return func(ctx context.Context) (*es_models.Aggregate, error) {
|
||||
if policy == nil {
|
||||
@@ -678,6 +679,101 @@ func checkExistingLoginPolicyIDPProviderValidation(idpConfigID string) func(...*
|
||||
}
|
||||
}
|
||||
|
||||
func MailTemplateAddedAggregate(aggCreator *es_models.AggregateCreator, existing *model.IAM, template *model.MailTemplate) func(ctx context.Context) (*es_models.Aggregate, error) {
|
||||
return func(ctx context.Context) (*es_models.Aggregate, error) {
|
||||
if template == nil {
|
||||
return nil, errors.ThrowPreconditionFailed(nil, "EVENT-ZCfDS", "Errors.Internal")
|
||||
}
|
||||
agg, err := IAMAggregate(ctx, aggCreator, existing)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
validationQuery := es_models.NewSearchQuery().
|
||||
AggregateTypeFilter(model.IAMAggregate).
|
||||
EventTypesFilter(model.MailTemplateAdded).
|
||||
AggregateIDFilter(existing.AggregateID)
|
||||
|
||||
validation := checkExistingMailTemplateValidation()
|
||||
agg.SetPrecondition(validationQuery, validation)
|
||||
return agg.AppendEvent(model.MailTemplateAdded, template)
|
||||
}
|
||||
}
|
||||
|
||||
func checkExistingMailTemplateValidation() func(...*es_models.Event) error {
|
||||
return func(events ...*es_models.Event) error {
|
||||
for _, event := range events {
|
||||
switch event.Type {
|
||||
case model.MailTemplateAdded:
|
||||
return errors.ThrowPreconditionFailed(nil, "EVENT-uKPiJ", "Errors.IAM.MailTemplate.AlreadyExists")
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
func MailTemplateChangedAggregate(aggCreator *es_models.AggregateCreator, existing *model.IAM, template *model.MailTemplate) func(ctx context.Context) (*es_models.Aggregate, error) {
|
||||
return func(ctx context.Context) (*es_models.Aggregate, error) {
|
||||
if template == nil {
|
||||
return nil, errors.ThrowPreconditionFailed(nil, "EVENT-s4PVD", "Errors.Internal")
|
||||
}
|
||||
agg, err := IAMAggregate(ctx, aggCreator, existing)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
changes := existing.DefaultMailTemplate.Changes(template)
|
||||
if len(changes) == 0 {
|
||||
return nil, errors.ThrowPreconditionFailed(nil, "EVENT-hxxSm", "Errors.NoChangesFound")
|
||||
}
|
||||
return agg.AppendEvent(model.MailTemplateChanged, changes)
|
||||
}
|
||||
}
|
||||
|
||||
func MailTextAddedAggregate(aggCreator *es_models.AggregateCreator, existing *model.IAM, text *model.MailText) func(ctx context.Context) (*es_models.Aggregate, error) {
|
||||
return func(ctx context.Context) (*es_models.Aggregate, error) {
|
||||
if text == nil {
|
||||
return nil, errors.ThrowPreconditionFailed(nil, "EVENT-ZCfDS", "Errors.Internal")
|
||||
}
|
||||
agg, err := IAMAggregate(ctx, aggCreator, existing)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
validationQuery := es_models.NewSearchQuery().
|
||||
AggregateTypeFilter(model.IAMAggregate).
|
||||
EventTypesFilter(model.MailTextAdded).
|
||||
AggregateIDFilter(existing.AggregateID)
|
||||
|
||||
validation := checkExistingMailTextValidation()
|
||||
agg.SetPrecondition(validationQuery, validation)
|
||||
return agg.AppendEvent(model.MailTextAdded, text)
|
||||
}
|
||||
}
|
||||
|
||||
func checkExistingMailTextValidation() func(...*es_models.Event) error {
|
||||
return func(events ...*es_models.Event) error {
|
||||
for _, event := range events {
|
||||
switch event.Type {
|
||||
case model.MailTextAdded:
|
||||
return errors.ThrowPreconditionFailed(nil, "EVENT-ijzeq", "Errors.IAM.MailText.AlreadyExists")
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
func MailTextChangedAggregate(aggCreator *es_models.AggregateCreator, existingIAM *model.IAM, text *model.MailText) func(ctx context.Context) (*es_models.Aggregate, error) {
|
||||
return func(ctx context.Context) (*es_models.Aggregate, error) {
|
||||
if text == nil {
|
||||
return nil, errors.ThrowPreconditionFailed(nil, "EVENT-mgYpV", "Errors.Internal")
|
||||
}
|
||||
|
||||
agg, err := IAMAggregate(ctx, aggCreator, existingIAM)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return agg.AppendEvent(model.MailTextChanged, text)
|
||||
}
|
||||
}
|
||||
|
||||
func checkExistingLoginPolicySecondFactorValidation(mfaType int32) func(...*es_models.Event) error {
|
||||
return func(events ...*es_models.Event) error {
|
||||
mfas := make([]int32, 0)
|
||||
|
||||
@@ -31,6 +31,8 @@ type IAM struct {
|
||||
IDPs []*IDPConfig `json:"-"`
|
||||
DefaultLoginPolicy *LoginPolicy `json:"-"`
|
||||
DefaultLabelPolicy *LabelPolicy `json:"-"`
|
||||
DefaultMailTemplate *MailTemplate `json:"-"`
|
||||
DefaultMailTexts []*MailText `json:"-"`
|
||||
DefaultOrgIAMPolicy *OrgIAMPolicy `json:"-"`
|
||||
DefaultPasswordComplexityPolicy *PasswordComplexityPolicy `json:"-"`
|
||||
DefaultPasswordAgePolicy *PasswordAgePolicy `json:"-"`
|
||||
@@ -40,14 +42,16 @@ type IAM struct {
|
||||
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,
|
||||
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)
|
||||
@@ -55,6 +59,9 @@ func IAMFromModel(iam *model.IAM) *IAM {
|
||||
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)
|
||||
}
|
||||
@@ -73,14 +80,16 @@ func IAMFromModel(iam *model.IAM) *IAM {
|
||||
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: model.Step(iam.SetUpStarted),
|
||||
SetUpDone: model.Step(iam.SetUpDone),
|
||||
GlobalOrgID: iam.GlobalOrgID,
|
||||
IAMProjectID: iam.IAMProjectID,
|
||||
Members: members,
|
||||
IDPs: idps,
|
||||
ObjectRoot: iam.ObjectRoot,
|
||||
SetUpStarted: model.Step(iam.SetUpStarted),
|
||||
SetUpDone: model.Step(iam.SetUpDone),
|
||||
GlobalOrgID: iam.GlobalOrgID,
|
||||
IAMProjectID: iam.IAMProjectID,
|
||||
Members: members,
|
||||
IDPs: idps,
|
||||
DefaultMailTexts: mailTexts,
|
||||
}
|
||||
if iam.DefaultLoginPolicy != nil {
|
||||
converted.DefaultLoginPolicy = LoginPolicyToModel(iam.DefaultLoginPolicy)
|
||||
@@ -88,6 +97,9 @@ func IAMToModel(iam *IAM) *model.IAM {
|
||||
if iam.DefaultLabelPolicy != nil {
|
||||
converted.DefaultLabelPolicy = LabelPolicyToModel(iam.DefaultLabelPolicy)
|
||||
}
|
||||
if iam.DefaultMailTemplate != nil {
|
||||
converted.DefaultMailTemplate = MailTemplateToModel(iam.DefaultMailTemplate)
|
||||
}
|
||||
if iam.DefaultPasswordComplexityPolicy != nil {
|
||||
converted.DefaultPasswordComplexityPolicy = PasswordComplexityPolicyToModel(iam.DefaultPasswordComplexityPolicy)
|
||||
}
|
||||
@@ -180,6 +192,14 @@ func (i *IAM) AppendEvent(event *es_models.Event) (err error) {
|
||||
return i.appendAddLabelPolicyEvent(event)
|
||||
case LabelPolicyChanged:
|
||||
return i.appendChangeLabelPolicyEvent(event)
|
||||
case MailTemplateAdded:
|
||||
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:
|
||||
|
||||
64
internal/iam/repository/eventsourcing/model/mail_template.go
Normal file
64
internal/iam/repository/eventsourcing/model/mail_template.go
Normal file
@@ -0,0 +1,64 @@
|
||||
package model
|
||||
|
||||
import (
|
||||
b64 "encoding/base64"
|
||||
"encoding/json"
|
||||
|
||||
"github.com/caos/zitadel/internal/errors"
|
||||
"github.com/caos/zitadel/internal/eventstore/models"
|
||||
es_models "github.com/caos/zitadel/internal/eventstore/models"
|
||||
iam_model "github.com/caos/zitadel/internal/iam/model"
|
||||
)
|
||||
|
||||
type MailTemplate struct {
|
||||
models.ObjectRoot
|
||||
State int32 `json:"-"`
|
||||
Template []byte
|
||||
}
|
||||
|
||||
func MailTemplateToModel(template *MailTemplate) *iam_model.MailTemplate {
|
||||
return &iam_model.MailTemplate{
|
||||
ObjectRoot: template.ObjectRoot,
|
||||
State: iam_model.PolicyState(template.State),
|
||||
Template: template.Template,
|
||||
}
|
||||
}
|
||||
|
||||
func MailTemplateFromModel(template *iam_model.MailTemplate) *MailTemplate {
|
||||
return &MailTemplate{
|
||||
ObjectRoot: template.ObjectRoot,
|
||||
State: int32(template.State),
|
||||
Template: template.Template,
|
||||
}
|
||||
}
|
||||
|
||||
func (p *MailTemplate) Changes(changed *MailTemplate) map[string]interface{} {
|
||||
changes := make(map[string]interface{}, 1)
|
||||
if b64.StdEncoding.EncodeToString(changed.Template) != b64.StdEncoding.EncodeToString(p.Template) {
|
||||
changes["template"] = b64.StdEncoding.EncodeToString(changed.Template)
|
||||
}
|
||||
|
||||
return changes
|
||||
}
|
||||
|
||||
func (i *IAM) appendAddMailTemplateEvent(event *es_models.Event) error {
|
||||
i.DefaultMailTemplate = new(MailTemplate)
|
||||
err := i.DefaultMailTemplate.SetDataLabel(event)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
i.DefaultMailTemplate.ObjectRoot.CreationDate = event.CreationDate
|
||||
return nil
|
||||
}
|
||||
|
||||
func (i *IAM) appendChangeMailTemplateEvent(event *es_models.Event) error {
|
||||
return i.DefaultMailTemplate.SetDataLabel(event)
|
||||
}
|
||||
|
||||
func (p *MailTemplate) SetDataLabel(event *es_models.Event) error {
|
||||
err := json.Unmarshal(event.Data, p)
|
||||
if err != nil {
|
||||
return errors.ThrowInternal(err, "MODEL-ikjhf", "unable to unmarshal data")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
@@ -0,0 +1,126 @@
|
||||
package model
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"testing"
|
||||
|
||||
es_models "github.com/caos/zitadel/internal/eventstore/models"
|
||||
)
|
||||
|
||||
func TestMailTemplateChanges(t *testing.T) {
|
||||
type args struct {
|
||||
existing *MailTemplate
|
||||
new *MailTemplate
|
||||
}
|
||||
type res struct {
|
||||
changesLen int
|
||||
}
|
||||
tests := []struct {
|
||||
name string
|
||||
args args
|
||||
res res
|
||||
}{
|
||||
{
|
||||
name: "mailtemplate all attributes change",
|
||||
args: args{
|
||||
existing: &MailTemplate{Template: []byte("<doctype html>")},
|
||||
new: &MailTemplate{Template: []byte("<!doctype html>")},
|
||||
},
|
||||
res: res{
|
||||
changesLen: 1,
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "no changes",
|
||||
args: args{
|
||||
existing: &MailTemplate{Template: []byte("<!doctype html>")},
|
||||
new: &MailTemplate{Template: []byte("<!doctype html>")},
|
||||
},
|
||||
res: res{
|
||||
changesLen: 0,
|
||||
},
|
||||
},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
changes := tt.args.existing.Changes(tt.args.new)
|
||||
if len(changes) != tt.res.changesLen {
|
||||
t.Errorf("got wrong changes len: expected: %v, actual: %v ", tt.res.changesLen, len(changes))
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestAppendAddMailTemplateEvent(t *testing.T) {
|
||||
type args struct {
|
||||
iam *IAM
|
||||
policy *MailTemplate
|
||||
event *es_models.Event
|
||||
}
|
||||
tests := []struct {
|
||||
name string
|
||||
args args
|
||||
result *IAM
|
||||
}{
|
||||
{
|
||||
name: "append add label policy event",
|
||||
args: args{
|
||||
iam: new(IAM),
|
||||
policy: &MailTemplate{Template: []byte("<!doctype html>")},
|
||||
event: new(es_models.Event),
|
||||
},
|
||||
result: &IAM{DefaultMailTemplate: &MailTemplate{Template: []byte("<!doctype html>")}},
|
||||
},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
if tt.args.policy != nil {
|
||||
data, _ := json.Marshal(tt.args.policy)
|
||||
tt.args.event.Data = data
|
||||
}
|
||||
tt.args.iam.appendAddMailTemplateEvent(tt.args.event)
|
||||
if string(tt.result.DefaultMailTemplate.Template) != string(tt.args.iam.DefaultMailTemplate.Template) {
|
||||
t.Errorf("got wrong result: expected: %v, actual: %v ", tt.result.DefaultMailTemplate.Template, tt.args.iam.DefaultMailTemplate.Template)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestAppendChangeMailTemplateEvent(t *testing.T) {
|
||||
type args struct {
|
||||
iam *IAM
|
||||
policy *MailTemplate
|
||||
event *es_models.Event
|
||||
}
|
||||
tests := []struct {
|
||||
name string
|
||||
args args
|
||||
result *IAM
|
||||
}{
|
||||
{
|
||||
name: "append change label policy event",
|
||||
args: args{
|
||||
iam: &IAM{DefaultMailTemplate: &MailTemplate{
|
||||
Template: []byte("<doctype html>"),
|
||||
}},
|
||||
policy: &MailTemplate{Template: []byte("<!doctype html>")},
|
||||
event: &es_models.Event{},
|
||||
},
|
||||
result: &IAM{DefaultMailTemplate: &MailTemplate{
|
||||
Template: []byte("<!doctype html>"),
|
||||
}},
|
||||
},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
if tt.args.policy != nil {
|
||||
data, _ := json.Marshal(tt.args.policy)
|
||||
tt.args.event.Data = data
|
||||
}
|
||||
tt.args.iam.appendChangeMailTemplateEvent(tt.args.event)
|
||||
if string(tt.result.DefaultMailTemplate.Template) != string(tt.args.iam.DefaultMailTemplate.Template) {
|
||||
t.Errorf("got wrong result: expected: %v, actual: %v ", tt.result.DefaultMailTemplate.Template, tt.args.iam.DefaultMailTemplate.Template)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
157
internal/iam/repository/eventsourcing/model/mail_text.go
Normal file
157
internal/iam/repository/eventsourcing/model/mail_text.go
Normal file
@@ -0,0 +1,157 @@
|
||||
package model
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
|
||||
"github.com/caos/zitadel/internal/errors"
|
||||
"github.com/caos/zitadel/internal/eventstore/models"
|
||||
es_models "github.com/caos/zitadel/internal/eventstore/models"
|
||||
iam_model "github.com/caos/zitadel/internal/iam/model"
|
||||
)
|
||||
|
||||
type MailText struct {
|
||||
models.ObjectRoot
|
||||
State int32 `json:"-"`
|
||||
MailTextType string
|
||||
Language string
|
||||
Title string
|
||||
PreHeader string
|
||||
Subject string
|
||||
Greeting string
|
||||
Text string
|
||||
ButtonText string
|
||||
}
|
||||
|
||||
func GetMailText(mailTexts []*MailText, mailTextType string, language string) (int, *MailText) {
|
||||
for i, m := range mailTexts {
|
||||
if m.MailTextType == mailTextType && m.Language == language {
|
||||
return i, m
|
||||
}
|
||||
}
|
||||
return -1, nil
|
||||
}
|
||||
|
||||
func MailTextsToModel(mailTexts []*MailText) []*iam_model.MailText {
|
||||
convertedMailTexts := make([]*iam_model.MailText, len(mailTexts))
|
||||
for i, m := range mailTexts {
|
||||
convertedMailTexts[i] = MailTextToModel(m)
|
||||
}
|
||||
return convertedMailTexts
|
||||
}
|
||||
|
||||
func MailTextToModel(mailText *MailText) *iam_model.MailText {
|
||||
return &iam_model.MailText{
|
||||
ObjectRoot: mailText.ObjectRoot,
|
||||
State: iam_model.PolicyState(mailText.State),
|
||||
MailTextType: mailText.MailTextType,
|
||||
Language: mailText.Language,
|
||||
Title: mailText.Title,
|
||||
PreHeader: mailText.PreHeader,
|
||||
Subject: mailText.Subject,
|
||||
Greeting: mailText.Greeting,
|
||||
Text: mailText.Text,
|
||||
ButtonText: mailText.ButtonText,
|
||||
}
|
||||
}
|
||||
|
||||
func MailTextsFromModel(mailTexts []*iam_model.MailText) []*MailText {
|
||||
convertedMailTexts := make([]*MailText, len(mailTexts))
|
||||
for i, m := range mailTexts {
|
||||
convertedMailTexts[i] = MailTextFromModel(m)
|
||||
}
|
||||
return convertedMailTexts
|
||||
}
|
||||
|
||||
func MailTextFromModel(mailText *iam_model.MailText) *MailText {
|
||||
return &MailText{
|
||||
ObjectRoot: mailText.ObjectRoot,
|
||||
State: int32(mailText.State),
|
||||
MailTextType: mailText.MailTextType,
|
||||
Language: mailText.Language,
|
||||
Title: mailText.Title,
|
||||
PreHeader: mailText.PreHeader,
|
||||
Subject: mailText.Subject,
|
||||
Greeting: mailText.Greeting,
|
||||
Text: mailText.Text,
|
||||
ButtonText: mailText.ButtonText,
|
||||
}
|
||||
}
|
||||
|
||||
func (p *MailText) Changes(changed *MailText) map[string]interface{} {
|
||||
changes := make(map[string]interface{}, 8)
|
||||
|
||||
changes["mailTextType"] = changed.MailTextType
|
||||
|
||||
changes["language"] = changed.Language
|
||||
|
||||
if changed.Title != p.Title {
|
||||
changes["title"] = changed.Title
|
||||
}
|
||||
|
||||
if changed.PreHeader != p.PreHeader {
|
||||
changes["preHeader"] = changed.PreHeader
|
||||
}
|
||||
|
||||
if changed.Subject != p.Subject {
|
||||
changes["subject"] = changed.Subject
|
||||
}
|
||||
|
||||
if changed.Greeting != p.Greeting {
|
||||
changes["greeting"] = changed.Greeting
|
||||
}
|
||||
|
||||
if changed.Text != p.Text {
|
||||
changes["text"] = changed.Text
|
||||
}
|
||||
|
||||
if changed.ButtonText != p.ButtonText {
|
||||
changes["buttonText"] = changed.ButtonText
|
||||
}
|
||||
|
||||
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 {
|
||||
return errors.ThrowInternal(err, "MODEL-3FUV5", "unable to unmarshal data")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
134
internal/iam/repository/eventsourcing/model/mail_text_test.go
Normal file
134
internal/iam/repository/eventsourcing/model/mail_text_test.go
Normal file
@@ -0,0 +1,134 @@
|
||||
package model
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"testing"
|
||||
|
||||
es_models "github.com/caos/zitadel/internal/eventstore/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))
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
@@ -38,6 +38,11 @@ const (
|
||||
LabelPolicyAdded models.EventType = "iam.policy.label.added"
|
||||
LabelPolicyChanged models.EventType = "iam.policy.label.changed"
|
||||
|
||||
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"
|
||||
|
||||
PasswordComplexityPolicyAdded models.EventType = "iam.policy.password.complexity.added"
|
||||
PasswordComplexityPolicyChanged models.EventType = "iam.policy.password.complexity.changed"
|
||||
|
||||
|
||||
@@ -11,8 +11,8 @@ import (
|
||||
|
||||
func IDPByID(db *gorm.DB, table, idpID string) (*model.IDPConfigView, error) {
|
||||
idp := new(model.IDPConfigView)
|
||||
userIDQuery := &model.IDPConfigSearchQuery{Key: iam_model.IDPConfigSearchKeyIdpConfigID, Value: idpID, Method: global_model.SearchMethodEquals}
|
||||
query := repository.PrepareGetByQuery(table, userIDQuery)
|
||||
idpIDQuery := &model.IDPConfigSearchQuery{Key: iam_model.IDPConfigSearchKeyIdpConfigID, Value: idpID, Method: global_model.SearchMethodEquals}
|
||||
query := repository.PrepareGetByQuery(table, idpIDQuery)
|
||||
err := query(db, idp)
|
||||
if caos_errs.IsNotFound(err) {
|
||||
return nil, caos_errs.ThrowNotFound(nil, "VIEW-Ahq2s", "Errors.IAM.IdpNotExisting")
|
||||
|
||||
@@ -11,8 +11,8 @@ import (
|
||||
|
||||
func GetLabelPolicyByAggregateID(db *gorm.DB, table, aggregateID string) (*model.LabelPolicyView, error) {
|
||||
policy := new(model.LabelPolicyView)
|
||||
userIDQuery := &model.LabelPolicySearchQuery{Key: iam_model.LabelPolicySearchKeyAggregateID, Value: aggregateID, Method: global_model.SearchMethodEquals}
|
||||
query := repository.PrepareGetByQuery(table, userIDQuery)
|
||||
aggregateIDQuery := &model.LabelPolicySearchQuery{Key: iam_model.LabelPolicySearchKeyAggregateID, Value: aggregateID, Method: global_model.SearchMethodEquals}
|
||||
query := repository.PrepareGetByQuery(table, aggregateIDQuery)
|
||||
err := query(db, policy)
|
||||
if caos_errs.IsNotFound(err) {
|
||||
return nil, caos_errs.ThrowNotFound(nil, "VIEW-68G11", "Errors.IAM.LabelPolicy.NotExisting")
|
||||
|
||||
@@ -11,8 +11,8 @@ import (
|
||||
|
||||
func GetLoginPolicyByAggregateID(db *gorm.DB, table, aggregateID string) (*model.LoginPolicyView, error) {
|
||||
policy := new(model.LoginPolicyView)
|
||||
userIDQuery := &model.LoginPolicySearchQuery{Key: iam_model.LoginPolicySearchKeyAggregateID, Value: aggregateID, Method: global_model.SearchMethodEquals}
|
||||
query := repository.PrepareGetByQuery(table, userIDQuery)
|
||||
aggregateIDQuery := &model.LoginPolicySearchQuery{Key: iam_model.LoginPolicySearchKeyAggregateID, Value: aggregateID, Method: global_model.SearchMethodEquals}
|
||||
query := repository.PrepareGetByQuery(table, aggregateIDQuery)
|
||||
err := query(db, policy)
|
||||
if caos_errs.IsNotFound(err) {
|
||||
return nil, caos_errs.ThrowNotFound(nil, "VIEW-Lso0cs", "Errors.IAM.LoginPolicy.NotExisting")
|
||||
|
||||
32
internal/iam/repository/view/mail_template_view.go
Normal file
32
internal/iam/repository/view/mail_template_view.go
Normal file
@@ -0,0 +1,32 @@
|
||||
package view
|
||||
|
||||
import (
|
||||
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"
|
||||
global_model "github.com/caos/zitadel/internal/model"
|
||||
"github.com/caos/zitadel/internal/view/repository"
|
||||
"github.com/jinzhu/gorm"
|
||||
)
|
||||
|
||||
func GetMailTemplateByAggregateID(db *gorm.DB, table, aggregateID string) (*model.MailTemplateView, error) {
|
||||
template := new(model.MailTemplateView)
|
||||
aggregateIDQuery := &model.MailTemplateSearchQuery{Key: iam_model.MailTemplateSearchKeyAggregateID, Value: aggregateID, Method: global_model.SearchMethodEquals}
|
||||
query := repository.PrepareGetByQuery(table, aggregateIDQuery)
|
||||
err := query(db, template)
|
||||
if caos_errs.IsNotFound(err) {
|
||||
return nil, caos_errs.ThrowNotFound(nil, "VIEW-iPnmU", "Errors.IAM.MailTemplate.NotExisting")
|
||||
}
|
||||
return template, err
|
||||
}
|
||||
|
||||
func PutMailTemplate(db *gorm.DB, table string, template *model.MailTemplateView) error {
|
||||
save := repository.PrepareSave(table)
|
||||
return save(db, template)
|
||||
}
|
||||
|
||||
func DeleteMailTemplate(db *gorm.DB, table, aggregateID string) error {
|
||||
delete := repository.PrepareDeleteByKey(table, model.MailTemplateSearchKey(iam_model.MailTemplateSearchKeyAggregateID), aggregateID)
|
||||
|
||||
return delete(db)
|
||||
}
|
||||
53
internal/iam/repository/view/mail_text_view.go
Normal file
53
internal/iam/repository/view/mail_text_view.go
Normal file
@@ -0,0 +1,53 @@
|
||||
package view
|
||||
|
||||
import (
|
||||
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"
|
||||
global_model "github.com/caos/zitadel/internal/model"
|
||||
"github.com/caos/zitadel/internal/view/repository"
|
||||
"github.com/jinzhu/gorm"
|
||||
)
|
||||
|
||||
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: global_model.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: global_model.SearchMethodEquals}
|
||||
textTypeQuery := &model.MailTextSearchQuery{Key: iam_model.MailTextSearchKeyMailTextType, Value: textType, Method: global_model.SearchMethodEquals}
|
||||
languageQuery := &model.MailTextSearchQuery{Key: iam_model.MailTextSearchKeyLanguage, Value: language, Method: global_model.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)
|
||||
}
|
||||
80
internal/iam/repository/view/model/mail_template.go
Normal file
80
internal/iam/repository/view/model/mail_template.go
Normal file
@@ -0,0 +1,80 @@
|
||||
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/models"
|
||||
"github.com/caos/zitadel/internal/iam/model"
|
||||
)
|
||||
|
||||
const (
|
||||
MailTemplateKeyAggregateID = "aggregate_id"
|
||||
)
|
||||
|
||||
type MailTemplateView 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_template_state"`
|
||||
|
||||
Template []byte `json:"template" gorm:"column:template"`
|
||||
Default bool `json:"-" gorm:"-"`
|
||||
|
||||
Sequence uint64 `json:"-" gorm:"column:sequence"`
|
||||
}
|
||||
|
||||
func MailTemplateViewFromModel(template *model.MailTemplateView) *MailTemplateView {
|
||||
return &MailTemplateView{
|
||||
AggregateID: template.AggregateID,
|
||||
Sequence: template.Sequence,
|
||||
CreationDate: template.CreationDate,
|
||||
ChangeDate: template.ChangeDate,
|
||||
Template: template.Template,
|
||||
Default: template.Default,
|
||||
}
|
||||
}
|
||||
|
||||
func MailTemplateViewToModel(template *MailTemplateView) *model.MailTemplateView {
|
||||
return &model.MailTemplateView{
|
||||
AggregateID: template.AggregateID,
|
||||
Sequence: template.Sequence,
|
||||
CreationDate: template.CreationDate,
|
||||
ChangeDate: template.ChangeDate,
|
||||
Template: template.Template,
|
||||
Default: template.Default,
|
||||
}
|
||||
}
|
||||
|
||||
func (i *MailTemplateView) AppendEvent(event *models.Event) (err error) {
|
||||
i.Sequence = event.Sequence
|
||||
i.ChangeDate = event.CreationDate
|
||||
switch event.Type {
|
||||
case es_model.MailTemplateAdded, org_es_model.MailTemplateAdded:
|
||||
i.setRootData(event)
|
||||
i.CreationDate = event.CreationDate
|
||||
err = i.SetData(event)
|
||||
case es_model.MailTemplateChanged, org_es_model.MailTemplateChanged:
|
||||
i.ChangeDate = event.CreationDate
|
||||
err = i.SetData(event)
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
func (r *MailTemplateView) setRootData(event *models.Event) {
|
||||
r.AggregateID = event.AggregateID
|
||||
}
|
||||
|
||||
func (r *MailTemplateView) SetData(event *models.Event) error {
|
||||
if err := json.Unmarshal(event.Data, r); err != nil {
|
||||
logging.Log("MODEL-YDZmZ").WithError(err).Error("could not unmarshal event data")
|
||||
return caos_errs.ThrowInternal(err, "MODEL-sKWwO", "Could not unmarshal data")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
59
internal/iam/repository/view/model/mail_template_query.go
Normal file
59
internal/iam/repository/view/model/mail_template_query.go
Normal file
@@ -0,0 +1,59 @@
|
||||
package model
|
||||
|
||||
import (
|
||||
iam_model "github.com/caos/zitadel/internal/iam/model"
|
||||
global_model "github.com/caos/zitadel/internal/model"
|
||||
"github.com/caos/zitadel/internal/view/repository"
|
||||
)
|
||||
|
||||
type MailTemplateSearchRequest iam_model.MailTemplateSearchRequest
|
||||
type MailTemplateSearchQuery iam_model.MailTemplateSearchQuery
|
||||
type MailTemplateSearchKey iam_model.MailTemplateSearchKey
|
||||
|
||||
func (req MailTemplateSearchRequest) GetLimit() uint64 {
|
||||
return req.Limit
|
||||
}
|
||||
|
||||
func (req MailTemplateSearchRequest) GetOffset() uint64 {
|
||||
return req.Offset
|
||||
}
|
||||
|
||||
func (req MailTemplateSearchRequest) GetSortingColumn() repository.ColumnKey {
|
||||
if req.SortingColumn == iam_model.MailTemplateSearchKeyUnspecified {
|
||||
return nil
|
||||
}
|
||||
return MailTemplateSearchKey(req.SortingColumn)
|
||||
}
|
||||
|
||||
func (req MailTemplateSearchRequest) GetAsc() bool {
|
||||
return req.Asc
|
||||
}
|
||||
|
||||
func (req MailTemplateSearchRequest) GetQueries() []repository.SearchQuery {
|
||||
result := make([]repository.SearchQuery, len(req.Queries))
|
||||
for i, q := range req.Queries {
|
||||
result[i] = MailTemplateSearchQuery{Key: q.Key, Value: q.Value, Method: q.Method}
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
func (req MailTemplateSearchQuery) GetKey() repository.ColumnKey {
|
||||
return MailTemplateSearchKey(req.Key)
|
||||
}
|
||||
|
||||
func (req MailTemplateSearchQuery) GetMethod() global_model.SearchMethod {
|
||||
return req.Method
|
||||
}
|
||||
|
||||
func (req MailTemplateSearchQuery) GetValue() interface{} {
|
||||
return req.Value
|
||||
}
|
||||
|
||||
func (key MailTemplateSearchKey) ToColumnName() string {
|
||||
switch iam_model.MailTemplateSearchKey(key) {
|
||||
case iam_model.MailTemplateSearchKeyAggregateID:
|
||||
return MailTemplateKeyAggregateID
|
||||
default:
|
||||
return ""
|
||||
}
|
||||
}
|
||||
117
internal/iam/repository/view/model/mail_text.go
Normal file
117
internal/iam/repository/view/model/mail_text.go
Normal file
@@ -0,0 +1,117 @@
|
||||
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/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
|
||||
}
|
||||
63
internal/iam/repository/view/model/mail_text_query.go
Normal file
63
internal/iam/repository/view/model/mail_text_query.go
Normal file
@@ -0,0 +1,63 @@
|
||||
package model
|
||||
|
||||
import (
|
||||
iam_model "github.com/caos/zitadel/internal/iam/model"
|
||||
global_model "github.com/caos/zitadel/internal/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() global_model.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 ""
|
||||
}
|
||||
}
|
||||
@@ -11,8 +11,8 @@ import (
|
||||
|
||||
func GetOrgIAMPolicyByAggregateID(db *gorm.DB, table, aggregateID string) (*model.OrgIAMPolicyView, error) {
|
||||
policy := new(model.OrgIAMPolicyView)
|
||||
userIDQuery := &model.OrgIAMPolicySearchQuery{Key: iam_model.OrgIAMPolicySearchKeyAggregateID, Value: aggregateID, Method: global_model.SearchMethodEquals}
|
||||
query := repository.PrepareGetByQuery(table, userIDQuery)
|
||||
aggregateIDQuery := &model.OrgIAMPolicySearchQuery{Key: iam_model.OrgIAMPolicySearchKeyAggregateID, Value: aggregateID, Method: global_model.SearchMethodEquals}
|
||||
query := repository.PrepareGetByQuery(table, aggregateIDQuery)
|
||||
err := query(db, policy)
|
||||
if caos_errs.IsNotFound(err) {
|
||||
return nil, caos_errs.ThrowNotFound(nil, "VIEW-5fi9s", "Errors.IAM.OrgIAMPolicy.NotExisting")
|
||||
|
||||
@@ -11,8 +11,8 @@ import (
|
||||
|
||||
func GetPasswordAgePolicyByAggregateID(db *gorm.DB, table, aggregateID string) (*model.PasswordAgePolicyView, error) {
|
||||
policy := new(model.PasswordAgePolicyView)
|
||||
userIDQuery := &model.PasswordAgePolicySearchQuery{Key: iam_model.PasswordAgePolicySearchKeyAggregateID, Value: aggregateID, Method: global_model.SearchMethodEquals}
|
||||
query := repository.PrepareGetByQuery(table, userIDQuery)
|
||||
aggregateIDQuery := &model.PasswordAgePolicySearchQuery{Key: iam_model.PasswordAgePolicySearchKeyAggregateID, Value: aggregateID, Method: global_model.SearchMethodEquals}
|
||||
query := repository.PrepareGetByQuery(table, aggregateIDQuery)
|
||||
err := query(db, policy)
|
||||
if caos_errs.IsNotFound(err) {
|
||||
return nil, caos_errs.ThrowNotFound(nil, "VIEW-Lso0cs", "Errors.IAM.PasswordAgePolicy.NotExisting")
|
||||
|
||||
@@ -11,8 +11,8 @@ import (
|
||||
|
||||
func GetPasswordComplexityPolicyByAggregateID(db *gorm.DB, table, aggregateID string) (*model.PasswordComplexityPolicyView, error) {
|
||||
policy := new(model.PasswordComplexityPolicyView)
|
||||
userIDQuery := &model.PasswordComplexityPolicySearchQuery{Key: iam_model.PasswordComplexityPolicySearchKeyAggregateID, Value: aggregateID, Method: global_model.SearchMethodEquals}
|
||||
query := repository.PrepareGetByQuery(table, userIDQuery)
|
||||
aggregateIDQuery := &model.PasswordComplexityPolicySearchQuery{Key: iam_model.PasswordComplexityPolicySearchKeyAggregateID, Value: aggregateID, Method: global_model.SearchMethodEquals}
|
||||
query := repository.PrepareGetByQuery(table, aggregateIDQuery)
|
||||
err := query(db, policy)
|
||||
if caos_errs.IsNotFound(err) {
|
||||
return nil, caos_errs.ThrowNotFound(nil, "VIEW-Lso0cs", "Errors.IAM.PasswordComplexityPolicy.NotExisting")
|
||||
|
||||
@@ -11,8 +11,8 @@ import (
|
||||
|
||||
func GetPasswordLockoutPolicyByAggregateID(db *gorm.DB, table, aggregateID string) (*model.PasswordLockoutPolicyView, error) {
|
||||
policy := new(model.PasswordLockoutPolicyView)
|
||||
userIDQuery := &model.PasswordLockoutPolicySearchQuery{Key: iam_model.PasswordLockoutPolicySearchKeyAggregateID, Value: aggregateID, Method: global_model.SearchMethodEquals}
|
||||
query := repository.PrepareGetByQuery(table, userIDQuery)
|
||||
aggregateIDQuery := &model.PasswordLockoutPolicySearchQuery{Key: iam_model.PasswordLockoutPolicySearchKeyAggregateID, Value: aggregateID, Method: global_model.SearchMethodEquals}
|
||||
query := repository.PrepareGetByQuery(table, aggregateIDQuery)
|
||||
err := query(db, policy)
|
||||
if caos_errs.IsNotFound(err) {
|
||||
return nil, caos_errs.ThrowNotFound(nil, "VIEW-Lso0cs", "Errors.IAM.PasswordLockoutPolicy.NotExisting")
|
||||
|
||||
Reference in New Issue
Block a user