diff --git a/internal/admin/repository/eventsourcing/eventstore/iam.go b/internal/admin/repository/eventsourcing/eventstore/iam.go index 9524c808aa..39551ad364 100644 --- a/internal/admin/repository/eventsourcing/eventstore/iam.go +++ b/internal/admin/repository/eventsourcing/eventstore/iam.go @@ -396,16 +396,6 @@ func (repo *IAMRepository) GetDefaultMailTemplate(ctx context.Context) (*iam_mod return iam_es_model.MailTemplateViewToModel(template), err } -func (repo *IAMRepository) AddDefaultMailTemplate(ctx context.Context, template *iam_model.MailTemplate) (*iam_model.MailTemplate, error) { - template.AggregateID = repo.SystemDefaults.IamID - return repo.IAMEventstore.AddMailTemplate(ctx, template) -} - -func (repo *IAMRepository) ChangeDefaultMailTemplate(ctx context.Context, template *iam_model.MailTemplate) (*iam_model.MailTemplate, error) { - template.AggregateID = repo.SystemDefaults.IamID - return repo.IAMEventstore.ChangeMailTemplate(ctx, template) -} - func (repo *IAMRepository) SearchIAMMembersx(ctx context.Context, request *iam_model.IAMMemberSearchRequest) (*iam_model.IAMMemberSearchResponse, error) { request.EnsureLimit(repo.SearchLimit) sequence, err := repo.View.GetLatestIAMMemberSequence() diff --git a/internal/admin/repository/iam.go b/internal/admin/repository/iam.go index 51e96b1b69..dc1205e435 100644 --- a/internal/admin/repository/iam.go +++ b/internal/admin/repository/iam.go @@ -26,8 +26,6 @@ type IAMRepository interface { GetDefaultLabelPolicy(ctx context.Context) (*iam_model.LabelPolicyView, error) GetDefaultMailTemplate(ctx context.Context) (*iam_model.MailTemplateView, error) - AddDefaultMailTemplate(ctx context.Context, template *iam_model.MailTemplate) (*iam_model.MailTemplate, error) - ChangeDefaultMailTemplate(ctx context.Context, template *iam_model.MailTemplate) (*iam_model.MailTemplate, error) GetDefaultMailTexts(ctx context.Context) (*iam_model.MailTextsView, error) GetDefaultMailText(ctx context.Context, textType string, language string) (*iam_model.MailTextView, error) diff --git a/internal/api/grpc/admin/org.go b/internal/api/grpc/admin/org.go index d301a0b8a5..266a3d416d 100644 --- a/internal/api/grpc/admin/org.go +++ b/internal/api/grpc/admin/org.go @@ -65,7 +65,7 @@ func (s *Server) GetOrgIamPolicy(ctx context.Context, in *admin.OrgIamPolicyID) } func (s *Server) CreateOrgIamPolicy(ctx context.Context, in *admin.OrgIamPolicyRequest) (_ *admin.OrgIamPolicy, err error) { - policy, err := s.command.AddOrgIAMPolicy(ctx, orgIAMPolicyRequestToDomain(in)) + policy, err := s.command.AddOrgIAMPolicy(ctx, in.OrgId, orgIAMPolicyRequestToDomain(in)) if err != nil { return nil, err } @@ -73,7 +73,7 @@ func (s *Server) CreateOrgIamPolicy(ctx context.Context, in *admin.OrgIamPolicyR } func (s *Server) UpdateOrgIamPolicy(ctx context.Context, in *admin.OrgIamPolicyRequest) (_ *admin.OrgIamPolicy, err error) { - policy, err := s.command.ChangeOrgIAMPolicy(ctx, orgIAMPolicyRequestToDomain(in)) + policy, err := s.command.ChangeOrgIAMPolicy(ctx, in.OrgId, orgIAMPolicyRequestToDomain(in)) if err != nil { return nil, err } diff --git a/internal/api/grpc/admin/template.go b/internal/api/grpc/admin/template.go index 8e4d4b25d4..b4227691d4 100644 --- a/internal/api/grpc/admin/template.go +++ b/internal/api/grpc/admin/template.go @@ -16,9 +16,9 @@ func (s *Server) GetDefaultMailTemplate(ctx context.Context, _ *empty.Empty) (*a } func (s *Server) UpdateDefaultMailTemplate(ctx context.Context, policy *admin.DefaultMailTemplateUpdate) (*admin.DefaultMailTemplate, error) { - result, err := s.iam.ChangeDefaultMailTemplate(ctx, templateToModel(policy)) + result, err := s.command.ChangeDefaultMailTemplate(ctx, templateToDomain(policy)) if err != nil { return nil, err } - return templateFromModel(result), nil + return templateFromDomain(result), nil } diff --git a/internal/api/grpc/admin/template_converter.go b/internal/api/grpc/admin/template_converter.go index c4c8b65967..c42414593f 100644 --- a/internal/api/grpc/admin/template_converter.go +++ b/internal/api/grpc/admin/template_converter.go @@ -1,42 +1,30 @@ package admin import ( - "github.com/caos/logging" iam_model "github.com/caos/zitadel/internal/iam/model" + "github.com/caos/zitadel/internal/v2/domain" "github.com/caos/zitadel/pkg/grpc/admin" - "github.com/golang/protobuf/ptypes" + "google.golang.org/protobuf/types/known/timestamppb" ) -func templateToModel(policy *admin.DefaultMailTemplateUpdate) *iam_model.MailTemplate { - return &iam_model.MailTemplate{ +func templateToDomain(policy *admin.DefaultMailTemplateUpdate) *domain.MailTemplate { + return &domain.MailTemplate{ Template: policy.Template, } } -func templateFromModel(policy *iam_model.MailTemplate) *admin.DefaultMailTemplate { - creationDate, err := ptypes.TimestampProto(policy.CreationDate) - logging.Log("ADMIN-CAA7T").OnError(err).Debug("date parse failed") - - changeDate, err := ptypes.TimestampProto(policy.ChangeDate) - logging.Log("ADMIN-H52Zx").OnError(err).Debug("date parse failed") - +func templateFromDomain(policy *domain.MailTemplate) *admin.DefaultMailTemplate { return &admin.DefaultMailTemplate{ Template: policy.Template, - CreationDate: creationDate, - ChangeDate: changeDate, + CreationDate: timestamppb.New(policy.CreationDate), + ChangeDate: timestamppb.New(policy.ChangeDate), } } func templateViewFromModel(policy *iam_model.MailTemplateView) *admin.DefaultMailTemplateView { - creationDate, err := ptypes.TimestampProto(policy.CreationDate) - logging.Log("ADMIN-yWFs5").OnError(err).Debug("date parse failed") - - changeDate, err := ptypes.TimestampProto(policy.ChangeDate) - logging.Log("ADMIN-JRpIO").OnError(err).Debug("date parse failed") - return &admin.DefaultMailTemplateView{ Template: policy.Template, - CreationDate: creationDate, - ChangeDate: changeDate, + CreationDate: timestamppb.New(policy.CreationDate), + ChangeDate: timestamppb.New(policy.ChangeDate), } } diff --git a/internal/api/grpc/admin/text.go b/internal/api/grpc/admin/text.go index 5f053de0e9..fc26b10f16 100644 --- a/internal/api/grpc/admin/text.go +++ b/internal/api/grpc/admin/text.go @@ -24,9 +24,9 @@ func (s *Server) GetDefaultMailText(ctx context.Context, textType string, langua } func (s *Server) UpdateDefaultMailText(ctx context.Context, text *admin.DefaultMailTextUpdate) (*admin.DefaultMailText, error) { - result, err := s.iam.ChangeDefaultMailText(ctx, textToModel(text)) + result, err := s.command.ChangeDefaultMailText(ctx, textToDomain(text)) if err != nil { return nil, err } - return textFromModel(result), nil + return textFromDomain(result), nil } diff --git a/internal/api/grpc/admin/text_converter.go b/internal/api/grpc/admin/text_converter.go index 20b4052b29..cca6bc616d 100644 --- a/internal/api/grpc/admin/text_converter.go +++ b/internal/api/grpc/admin/text_converter.go @@ -1,14 +1,14 @@ package admin import ( - "github.com/caos/logging" iam_model "github.com/caos/zitadel/internal/iam/model" + "github.com/caos/zitadel/internal/v2/domain" "github.com/caos/zitadel/pkg/grpc/admin" - "github.com/golang/protobuf/ptypes" + "google.golang.org/protobuf/types/known/timestamppb" ) -func textToModel(text *admin.DefaultMailTextUpdate) *iam_model.MailText { - return &iam_model.MailText{ +func textToDomain(text *admin.DefaultMailTextUpdate) *domain.MailText { + return &domain.MailText{ MailTextType: text.MailTextType, Language: text.Language, Title: text.Title, @@ -20,13 +20,7 @@ func textToModel(text *admin.DefaultMailTextUpdate) *iam_model.MailText { } } -func textFromModel(text *iam_model.MailText) *admin.DefaultMailText { - creationDate, err := ptypes.TimestampProto(text.CreationDate) - logging.Log("ADMIN-Jlzsj").OnError(err).Debug("date parse failed") - - changeDate, err := ptypes.TimestampProto(text.ChangeDate) - logging.Log("ADMIN-mw5b8").OnError(err).Debug("date parse failed") - +func textFromDomain(text *domain.MailText) *admin.DefaultMailText { return &admin.DefaultMailText{ MailTextType: text.MailTextType, Language: text.Language, @@ -36,8 +30,8 @@ func textFromModel(text *iam_model.MailText) *admin.DefaultMailText { Greeting: text.Greeting, Text: text.Text, ButtonText: text.ButtonText, - CreationDate: creationDate, - ChangeDate: changeDate, + CreationDate: timestamppb.New(text.CreationDate), + ChangeDate: timestamppb.New(text.ChangeDate), } } @@ -57,12 +51,6 @@ func textsViewToModel(queries []*iam_model.MailTextView) []*admin.DefaultMailTex } func textViewFromModel(text *iam_model.MailTextView) *admin.DefaultMailTextView { - creationDate, err := ptypes.TimestampProto(text.CreationDate) - logging.Log("ADMIN-7RyJc").OnError(err).Debug("date parse failed") - - changeDate, err := ptypes.TimestampProto(text.ChangeDate) - logging.Log("ADMIN-fTFgY").OnError(err).Debug("date parse failed") - return &admin.DefaultMailTextView{ MailTextType: text.MailTextType, Language: text.Language, @@ -72,7 +60,7 @@ func textViewFromModel(text *iam_model.MailTextView) *admin.DefaultMailTextView Greeting: text.Greeting, Text: text.Text, ButtonText: text.ButtonText, - CreationDate: creationDate, - ChangeDate: changeDate, + CreationDate: timestamppb.New(text.CreationDate), + ChangeDate: timestamppb.New(text.ChangeDate), } } diff --git a/internal/api/grpc/management/login_policy.go b/internal/api/grpc/management/login_policy.go index df9c7ffc12..716b736f45 100644 --- a/internal/api/grpc/management/login_policy.go +++ b/internal/api/grpc/management/login_policy.go @@ -26,7 +26,7 @@ func (s *Server) GetDefaultLoginPolicy(ctx context.Context, _ *empty.Empty) (*ma } func (s *Server) CreateLoginPolicy(ctx context.Context, policy *management.LoginPolicyRequest) (*management.LoginPolicy, error) { - result, err := s.command.AddLoginPolicy(ctx, loginPolicyRequestToDomain(ctx, policy)) + result, err := s.command.AddLoginPolicy(ctx, authz.GetCtxData(ctx).OrgID, loginPolicyRequestToDomain(ctx, policy)) if err != nil { return nil, err } @@ -34,7 +34,7 @@ func (s *Server) CreateLoginPolicy(ctx context.Context, policy *management.Login } func (s *Server) UpdateLoginPolicy(ctx context.Context, policy *management.LoginPolicyRequest) (*management.LoginPolicy, error) { - result, err := s.command.ChangeLoginPolicy(ctx, loginPolicyRequestToDomain(ctx, policy)) + result, err := s.command.ChangeLoginPolicy(ctx, authz.GetCtxData(ctx).OrgID, loginPolicyRequestToDomain(ctx, policy)) if err != nil { return nil, err } @@ -55,7 +55,7 @@ func (s *Server) GetLoginPolicyIdpProviders(ctx context.Context, request *manage } func (s *Server) AddIdpProviderToLoginPolicy(ctx context.Context, provider *management.IdpProviderAdd) (*management.IdpProvider, error) { - result, err := s.command.AddIDPProviderToLoginPolicy(ctx, idpProviderAddToDomain(ctx, provider)) + result, err := s.command.AddIDPProviderToLoginPolicy(ctx, authz.GetCtxData(ctx).OrgID, idpProviderAddToDomain(ctx, provider)) if err != nil { return nil, err } @@ -67,7 +67,7 @@ func (s *Server) RemoveIdpProviderFromLoginPolicy(ctx context.Context, provider if err != nil { return &empty.Empty{}, err } - err = s.command.RemoveIDPProviderFromLoginPolicy(ctx, idpProviderIDToDomain(ctx, provider), externalIDPViewsToDomain(externalIDPs)...) + err = s.command.RemoveIDPProviderFromLoginPolicy(ctx, authz.GetCtxData(ctx).OrgID, idpProviderIDToDomain(ctx, provider), externalIDPViewsToDomain(externalIDPs)...) return &empty.Empty{}, err } diff --git a/internal/api/grpc/management/mail_template.go b/internal/api/grpc/management/mail_template.go index 290b1534ab..6bed0bbfc4 100644 --- a/internal/api/grpc/management/mail_template.go +++ b/internal/api/grpc/management/mail_template.go @@ -2,6 +2,7 @@ package management import ( "context" + "github.com/caos/zitadel/internal/api/authz" "github.com/caos/zitadel/pkg/grpc/management" "github.com/golang/protobuf/ptypes/empty" @@ -24,22 +25,22 @@ func (s *Server) GetDefaultMailTemplate(ctx context.Context, _ *empty.Empty) (*m } func (s *Server) CreateMailTemplate(ctx context.Context, template *management.MailTemplateUpdate) (*management.MailTemplate, error) { - result, err := s.org.AddMailTemplate(ctx, mailTemplateRequestToModel(template)) + result, err := s.command.AddMailTemplate(ctx, authz.GetCtxData(ctx).OrgID, mailTemplateRequestToDomain(template)) if err != nil { return nil, err } - return mailTemplateFromModel(result), nil + return mailTemplateFromDomain(result), nil } func (s *Server) UpdateMailTemplate(ctx context.Context, template *management.MailTemplateUpdate) (*management.MailTemplate, error) { - result, err := s.org.ChangeMailTemplate(ctx, mailTemplateRequestToModel(template)) + result, err := s.command.ChangeMailTemplate(ctx, authz.GetCtxData(ctx).OrgID, mailTemplateRequestToDomain(template)) if err != nil { return nil, err } - return mailTemplateFromModel(result), nil + return mailTemplateFromDomain(result), nil } func (s *Server) RemoveMailTemplate(ctx context.Context, _ *empty.Empty) (*empty.Empty, error) { - err := s.org.RemoveMailTemplate(ctx) + err := s.command.RemoveMailTemplate(ctx, authz.GetCtxData(ctx).OrgID) return &empty.Empty{}, err } diff --git a/internal/api/grpc/management/mail_template_converter.go b/internal/api/grpc/management/mail_template_converter.go index a4e9dffa70..8f2958f5fc 100644 --- a/internal/api/grpc/management/mail_template_converter.go +++ b/internal/api/grpc/management/mail_template_converter.go @@ -1,42 +1,31 @@ package management import ( - "github.com/caos/logging" iam_model "github.com/caos/zitadel/internal/iam/model" + "github.com/caos/zitadel/internal/v2/domain" "github.com/caos/zitadel/pkg/grpc/management" - "github.com/golang/protobuf/ptypes" + "google.golang.org/protobuf/types/known/timestamppb" ) -func mailTemplateRequestToModel(mailTemplate *management.MailTemplateUpdate) *iam_model.MailTemplate { - return &iam_model.MailTemplate{ +func mailTemplateRequestToDomain(mailTemplate *management.MailTemplateUpdate) *domain.MailTemplate { + return &domain.MailTemplate{ Template: mailTemplate.Template, } } -func mailTemplateFromModel(mailTemplate *iam_model.MailTemplate) *management.MailTemplate { - creationDate, err := ptypes.TimestampProto(mailTemplate.CreationDate) - logging.Log("MANAG-ULKZ6").OnError(err).Debug("date parse failed") - - changeDate, err := ptypes.TimestampProto(mailTemplate.ChangeDate) - logging.Log("MANAG-451rI").OnError(err).Debug("date parse failed") +func mailTemplateFromDomain(mailTemplate *domain.MailTemplate) *management.MailTemplate { return &management.MailTemplate{ Template: mailTemplate.Template, - CreationDate: creationDate, - ChangeDate: changeDate, + CreationDate: timestamppb.New(mailTemplate.CreationDate), + ChangeDate: timestamppb.New(mailTemplate.ChangeDate), } } func mailTemplateViewFromModel(mailTemplate *iam_model.MailTemplateView) *management.MailTemplateView { - creationDate, err := ptypes.TimestampProto(mailTemplate.CreationDate) - logging.Log("MANAG-koQnB").OnError(err).Debug("date parse failed") - - changeDate, err := ptypes.TimestampProto(mailTemplate.ChangeDate) - logging.Log("MANAG-ToDhD").OnError(err).Debug("date parse failed") - return &management.MailTemplateView{ Default: mailTemplate.Default, Template: mailTemplate.Template, - CreationDate: creationDate, - ChangeDate: changeDate, + CreationDate: timestamppb.New(mailTemplate.CreationDate), + ChangeDate: timestamppb.New(mailTemplate.ChangeDate), } } diff --git a/internal/api/grpc/management/mail_text.go b/internal/api/grpc/management/mail_text.go index 1d9928a1cd..81d0dba49a 100644 --- a/internal/api/grpc/management/mail_text.go +++ b/internal/api/grpc/management/mail_text.go @@ -2,6 +2,7 @@ package management import ( "context" + "github.com/caos/zitadel/internal/api/authz" "github.com/caos/zitadel/pkg/grpc/management" "github.com/golang/protobuf/ptypes/empty" @@ -24,22 +25,22 @@ func (s *Server) GetDefaultMailTexts(ctx context.Context, _ *empty.Empty) (*mana } func (s *Server) CreateMailText(ctx context.Context, mailText *management.MailTextUpdate) (*management.MailText, error) { - result, err := s.org.AddMailText(ctx, mailTextRequestToModel(mailText)) + result, err := s.command.AddMailText(ctx, authz.GetCtxData(ctx).OrgID, mailTextRequestToDomain(mailText)) if err != nil { return nil, err } - return mailTextFromModel(result), nil + return mailTextFromDoamin(result), nil } func (s *Server) UpdateMailText(ctx context.Context, mailText *management.MailTextUpdate) (*management.MailText, error) { - result, err := s.org.ChangeMailText(ctx, mailTextRequestToModel(mailText)) + result, err := s.command.ChangeMailText(ctx, authz.GetCtxData(ctx).OrgID, mailTextRequestToDomain(mailText)) if err != nil { return nil, err } - return mailTextFromModel(result), nil + return mailTextFromDoamin(result), nil } func (s *Server) RemoveMailText(ctx context.Context, mailText *management.MailTextRemove) (*empty.Empty, error) { - err := s.org.RemoveMailText(ctx, mailTextRemoveToModel(mailText)) + err := s.command.RemoveMailText(ctx, authz.GetCtxData(ctx).OrgID, mailText.MailTextType, mailText.Language) return &empty.Empty{}, err } diff --git a/internal/api/grpc/management/mail_text_converter.go b/internal/api/grpc/management/mail_text_converter.go index 8b4e580e01..7a5b2f5ebb 100644 --- a/internal/api/grpc/management/mail_text_converter.go +++ b/internal/api/grpc/management/mail_text_converter.go @@ -3,12 +3,14 @@ package management import ( "github.com/caos/logging" iam_model "github.com/caos/zitadel/internal/iam/model" + "github.com/caos/zitadel/internal/v2/domain" "github.com/caos/zitadel/pkg/grpc/management" "github.com/golang/protobuf/ptypes" + "google.golang.org/protobuf/types/known/timestamppb" ) -func mailTextRequestToModel(mailText *management.MailTextUpdate) *iam_model.MailText { - return &iam_model.MailText{ +func mailTextRequestToDomain(mailText *management.MailTextUpdate) *domain.MailText { + return &domain.MailText{ MailTextType: mailText.MailTextType, Language: mailText.Language, Title: mailText.Title, @@ -20,20 +22,7 @@ func mailTextRequestToModel(mailText *management.MailTextUpdate) *iam_model.Mail } } -func mailTextRemoveToModel(mailText *management.MailTextRemove) *iam_model.MailText { - return &iam_model.MailText{ - MailTextType: mailText.MailTextType, - Language: mailText.Language, - } -} - -func mailTextFromModel(mailText *iam_model.MailText) *management.MailText { - creationDate, err := ptypes.TimestampProto(mailText.CreationDate) - logging.Log("MANAG-ULKZ6").OnError(err).Debug("date parse failed") - - changeDate, err := ptypes.TimestampProto(mailText.ChangeDate) - logging.Log("MANAG-451rI").OnError(err).Debug("date parse failed") - +func mailTextFromDoamin(mailText *domain.MailText) *management.MailText { return &management.MailText{ MailTextType: mailText.MailTextType, Language: mailText.Language, @@ -43,8 +32,8 @@ func mailTextFromModel(mailText *iam_model.MailText) *management.MailText { Greeting: mailText.Greeting, Text: mailText.Text, ButtonText: mailText.ButtonText, - CreationDate: creationDate, - ChangeDate: changeDate, + CreationDate: timestamppb.New(mailText.CreationDate), + ChangeDate: timestamppb.New(mailText.ChangeDate), } } diff --git a/internal/api/grpc/management/password_age_policy.go b/internal/api/grpc/management/password_age_policy.go index 9432faf21f..1248123237 100644 --- a/internal/api/grpc/management/password_age_policy.go +++ b/internal/api/grpc/management/password_age_policy.go @@ -24,7 +24,7 @@ func (s *Server) GetDefaultPasswordAgePolicy(ctx context.Context, _ *empty.Empty } func (s *Server) CreatePasswordAgePolicy(ctx context.Context, policy *management.PasswordAgePolicyRequest) (*management.PasswordAgePolicy, error) { - result, err := s.command.AddPasswordAgePolicy(ctx, passwordAgePolicyRequestToDomain(ctx, policy)) + result, err := s.command.AddPasswordAgePolicy(ctx, authz.GetCtxData(ctx).OrgID, passwordAgePolicyRequestToDomain(ctx, policy)) if err != nil { return nil, err } @@ -32,7 +32,7 @@ func (s *Server) CreatePasswordAgePolicy(ctx context.Context, policy *management } func (s *Server) UpdatePasswordAgePolicy(ctx context.Context, policy *management.PasswordAgePolicyRequest) (*management.PasswordAgePolicy, error) { - result, err := s.command.ChangePasswordAgePolicy(ctx, passwordAgePolicyRequestToDomain(ctx, policy)) + result, err := s.command.ChangePasswordAgePolicy(ctx, authz.GetCtxData(ctx).OrgID, passwordAgePolicyRequestToDomain(ctx, policy)) if err != nil { return nil, err } diff --git a/internal/api/grpc/management/password_complexity_policy.go b/internal/api/grpc/management/password_complexity_policy.go index 2fb8b09563..b8888fc779 100644 --- a/internal/api/grpc/management/password_complexity_policy.go +++ b/internal/api/grpc/management/password_complexity_policy.go @@ -24,7 +24,7 @@ func (s *Server) GetDefaultPasswordComplexityPolicy(ctx context.Context, _ *empt } func (s *Server) CreatePasswordComplexityPolicy(ctx context.Context, policy *management.PasswordComplexityPolicyRequest) (*management.PasswordComplexityPolicy, error) { - result, err := s.command.AddPasswordComplexityPolicy(ctx, passwordComplexityPolicyRequestToDomain(ctx, policy)) + result, err := s.command.AddPasswordComplexityPolicy(ctx, authz.GetCtxData(ctx).OrgID, passwordComplexityPolicyRequestToDomain(ctx, policy)) if err != nil { return nil, err } @@ -32,7 +32,7 @@ func (s *Server) CreatePasswordComplexityPolicy(ctx context.Context, policy *man } func (s *Server) UpdatePasswordComplexityPolicy(ctx context.Context, policy *management.PasswordComplexityPolicyRequest) (*management.PasswordComplexityPolicy, error) { - result, err := s.command.ChangePasswordComplexityPolicy(ctx, passwordComplexityPolicyRequestToDomain(ctx, policy)) + result, err := s.command.ChangePasswordComplexityPolicy(ctx, authz.GetCtxData(ctx).OrgID, passwordComplexityPolicyRequestToDomain(ctx, policy)) if err != nil { return nil, err } diff --git a/internal/api/grpc/management/password_lockout_policy.go b/internal/api/grpc/management/password_lockout_policy.go index 83d490bec4..0e4bb428a0 100644 --- a/internal/api/grpc/management/password_lockout_policy.go +++ b/internal/api/grpc/management/password_lockout_policy.go @@ -24,7 +24,7 @@ func (s *Server) GetDefaultPasswordLockoutPolicy(ctx context.Context, _ *empty.E } func (s *Server) CreatePasswordLockoutPolicy(ctx context.Context, policy *management.PasswordLockoutPolicyRequest) (*management.PasswordLockoutPolicy, error) { - result, err := s.command.AddPasswordLockoutPolicy(ctx, passwordLockoutPolicyRequestToDomain(ctx, policy)) + result, err := s.command.AddPasswordLockoutPolicy(ctx, authz.GetCtxData(ctx).OrgID, passwordLockoutPolicyRequestToDomain(ctx, policy)) if err != nil { return nil, err } @@ -32,7 +32,7 @@ func (s *Server) CreatePasswordLockoutPolicy(ctx context.Context, policy *manage } func (s *Server) UpdatePasswordLockoutPolicy(ctx context.Context, policy *management.PasswordLockoutPolicyRequest) (*management.PasswordLockoutPolicy, error) { - result, err := s.command.ChangePasswordLockoutPolicy(ctx, passwordLockoutPolicyRequestToDomain(ctx, policy)) + result, err := s.command.ChangePasswordLockoutPolicy(ctx, authz.GetCtxData(ctx).OrgID, passwordLockoutPolicyRequestToDomain(ctx, policy)) if err != nil { return nil, err } diff --git a/internal/management/repository/eventsourcing/eventstore/org.go b/internal/management/repository/eventsourcing/eventstore/org.go index de173878fd..0bb7fca8c7 100644 --- a/internal/management/repository/eventsourcing/eventstore/org.go +++ b/internal/management/repository/eventsourcing/eventstore/org.go @@ -738,23 +738,6 @@ func (repo *OrgRepository) GetMailTemplate(ctx context.Context) (*iam_model.Mail return iam_es_model.MailTemplateViewToModel(template), err } -func (repo *OrgRepository) AddMailTemplate(ctx context.Context, template *iam_model.MailTemplate) (*iam_model.MailTemplate, error) { - template.AggregateID = authz.GetCtxData(ctx).OrgID - return repo.OrgEventstore.AddMailTemplate(ctx, template) -} - -func (repo *OrgRepository) ChangeMailTemplate(ctx context.Context, template *iam_model.MailTemplate) (*iam_model.MailTemplate, error) { - template.AggregateID = authz.GetCtxData(ctx).OrgID - return repo.OrgEventstore.ChangeMailTemplate(ctx, template) -} - -func (repo *OrgRepository) RemoveMailTemplate(ctx context.Context) error { - template := &iam_model.MailTemplate{ObjectRoot: models.ObjectRoot{ - AggregateID: authz.GetCtxData(ctx).OrgID, - }} - return repo.OrgEventstore.RemoveMailTemplate(ctx, template) -} - func (repo *OrgRepository) GetDefaultMailTexts(ctx context.Context) (*iam_model.MailTextsView, error) { texts, err := repo.View.MailTextsByAggregateID(repo.SystemDefaults.IamID) if err != nil { diff --git a/internal/management/repository/org.go b/internal/management/repository/org.go index 955b96d213..f53b69443b 100644 --- a/internal/management/repository/org.go +++ b/internal/management/repository/org.go @@ -42,9 +42,6 @@ type OrgRepository interface { GetDefaultMailTemplate(ctx context.Context) (*iam_model.MailTemplateView, error) GetMailTemplate(ctx context.Context) (*iam_model.MailTemplateView, error) - AddMailTemplate(ctx context.Context, template *iam_model.MailTemplate) (*iam_model.MailTemplate, error) - ChangeMailTemplate(ctx context.Context, template *iam_model.MailTemplate) (*iam_model.MailTemplate, error) - RemoveMailTemplate(ctx context.Context) error GetDefaultMailTexts(ctx context.Context) (*iam_model.MailTextsView, error) GetMailTexts(ctx context.Context) (*iam_model.MailTextsView, error) diff --git a/internal/setup/step10.go b/internal/setup/step10.go deleted file mode 100644 index 4316f87776..0000000000 --- a/internal/setup/step10.go +++ /dev/null @@ -1,98 +0,0 @@ -package setup - -// -//type Step10 struct { -// DefaultMailTemplate iam_model.MailTemplate -// DefaultMailTexts []iam_model.MailText -// -// setup *Setup -//} -// -//func (s *Step10) isNil() bool { -// return s == nil -//} -// -//func (step *Step10) step() iam_model.Step { -// return iam_model.Step10 -//} -// -//func (step *Step10) init(setup *Setup) { -// step.setup = setup -//} -// -//func (step *Step10) execute(ctx context.Context) (*iam_model.IAM, error) { -// iam, agg, err := step.mailTemplate(ctx, &step.DefaultMailTemplate) -// if err != nil { -// logging.Log("SETUP-1UYCt").WithField("step", step.step()).WithError(err).Error("unable to finish setup (Mail template)") -// return nil, err -// } -// iam, agg, push, err := step.setup.IamEvents.PrepareSetupDone(ctx, iam, agg, step.step()) -// if err != nil { -// logging.Log("SETUP-fMLsb").WithField("step", step.step()).WithError(err).Error("unable to finish setup (prepare setup done)") -// return nil, err -// } -// err = es_sdk.PushAggregates(ctx, push, iam.AppendEvents, agg) -// if err != nil { -// logging.Log("SETUP-GuS3f").WithField("step", step.step()).WithError(err).Error("unable to finish setup") -// return nil, err -// } -// -// iam, agg, err = step.defaultMailTexts(ctx, &step.DefaultMailTexts) -// if err != nil { -// logging.Log("SETUP-p4oWq").WithError(err).Error("unable to set up defaultMailTexts") -// return nil, err -// } -// iam, agg, push, err = step.setup.IamEvents.PrepareSetupDone(ctx, iam, agg, step.step()) -// if err != nil { -// logging.Log("SETUP-fMLsb").WithField("step", step.step()).WithError(err).Error("unable to finish setup (prepare setup done)") -// return nil, err -// } -// err = es_sdk.PushAggregates(ctx, push, iam.AppendEvents, agg) -// if err != nil { -// logging.Log("SETUP-GuS3f").WithField("step", step.step()).WithError(err).Error("unable to finish setup") -// return nil, err -// } -// -// return iam_es_model.IAMToModel(iam), nil -//} -// -//func (step *Step10) mailTemplate(ctx context.Context, mailTemplate *iam_model.MailTemplate) (*iam_es_model.IAM, *models.Aggregate, error) { -// logging.Log("SETUP-cNrF3").Info("setting up mail template") -// mailTemplate.AggregateID = step.setup.iamID -// iam, aggregate, err := step.setup.IamEvents.PrepareAddMailTemplate(ctx, mailTemplate) -// if err != nil { -// return nil, nil, err -// } -// return iam, aggregate, nil -//} -// -//func (step *Step10) defaultMailTexts(ctx context.Context, defaultMailTexts *[]iam_model.MailText) (*iam_es_model.IAM, *models.Aggregate, error) { -// logging.Log("SETUP-dsTh3").Info("setting up defaultMailTexts") -// iam := &iam_es_model.IAM{} -// var aggregate *models.Aggregate -// for index, iamDefaultMailText := range *defaultMailTexts { -// iaml, aggregatel, err := step.defaultMailText(ctx, &iamDefaultMailText) -// if err != nil { -// logging.LogWithFields("SETUP-IlLif", "DefaultMailText", iamDefaultMailText.MailTextType).WithError(err).Error("unable to create defaultMailText") -// return nil, nil, err -// } -// if index == 0 { -// aggregate = aggregatel -// } else { -// aggregate.Events = append(aggregate.Events, aggregatel.Events...) -// } -// iam = iaml -// } -// logging.Log("SETUP-dgjT4").Info("defaultMailTexts set up") -// return iam, aggregate, nil -//} -// -//func (step *Step10) defaultMailText(ctx context.Context, mailText *iam_model.MailText) (*iam_es_model.IAM, *models.Aggregate, error) { -// logging.Log("SETUP-cNrF3").Info("setting up mail text") -// mailText.AggregateID = step.setup.iamID -// iam, aggregate, err := step.setup.IamEvents.PrepareAddMailText(ctx, mailText) -// if err != nil { -// return nil, nil, err -// } -// return iam, aggregate, nil -//} diff --git a/internal/static/i18n/de.yaml b/internal/static/i18n/de.yaml index 69ebb2f088..26238d216d 100644 --- a/internal/static/i18n/de.yaml +++ b/internal/static/i18n/de.yaml @@ -132,6 +132,16 @@ Errors: AlreadyExists: Multifaktor existiert bereits NotExisting: Multifaktor existiert nicht Unspecified: Multifaktor ungültig + MailTemplate: + NotFound: Default Mail Template nicht gefunden + NotChanged: Default Mail Template wurde nicht verändert + AlreadyExists: Default Mail Template existiert bereits + Invalid: Default Mail Template ist ungültig + MailText: + NotFound: Default Mail Text konnte nicht gefunden werden + NotChanged: Default Mail Text wurde nicht verändert + AlreadyExists: Default Mail Text existiert bereits + Invalid: Default Mail Text ist ungültig PasswordComplexity: NotFound: Password Komplexitäts Policy konnte nicht gefunden werden Empty: Passwort Komplexitäts Policy ist leer @@ -234,6 +244,16 @@ Errors: LabelPolicy: NotFound: Default Private Label Policy konnte nicht gefunden NotChanged: Default Private Label Policy wurde nicht verändert + MailTemplate: + NotFound: Default Mail Template konnte nicht gefunden werden + NotChanged: Default Mail Template wurde nicht verändert + AlreadyExists: Default Mail Template existiert bereits + Invalid: Default Mail Template ist ungültig + MailText: + NotFound: Default Mail Text konnte nicht gefunden werden + NotChanged: Default Mail Text wurde nicht verändert + AlreadyExists: Default Mail Text existiert bereits + Invalid: Default Mail Text ist ungültig PasswordComplexityPolicy: NotFound: Default Password Complexity Policy konnte nicht gefunden werden NotExisting: Default Password Complexity Policy existiert nicht diff --git a/internal/static/i18n/en.yaml b/internal/static/i18n/en.yaml index 266c21bb6c..5afca93faf 100644 --- a/internal/static/i18n/en.yaml +++ b/internal/static/i18n/en.yaml @@ -132,6 +132,16 @@ Errors: AlreadyExists: Multifactor already exists NotExisting: Multifactor not existing Unspecified: Multifactor invalid + MailTemplate: + NotFound: Default Mail Template not found + NotChanged: Default Mail Template has not been changed + AlreadyExists: Default Mail Template already exists + Invalid: Default Mail Template is invalid + MailText: + NotFound: Default Mail Text not found + NotChanged: Default Mail Text has not been changed + AlreadyExists: Default Mail Text already exists + Invalid: Default Mail Text is invalid PasswordComplexity: NotFound: Password Complexity Policy not found Empty: Password Complexity Policy is empty @@ -230,6 +240,16 @@ Errors: LabelPolicy: NotFound: Default Private Label Policy not found NotChanged: Default Private Label Policy has not been changed + MailTemplate: + NotFound: Default Mail Template not found + NotChanged: Default Mail Template has not been changed + AlreadyExists: Default Mail Template already exists + Invalid: Default Mail Template is invalid + MailText: + NotFound: Default Mail Text not found + NotChanged: Default Mail Text has not been changed + AlreadyExists: Default Mail Text already exists + Invalid: Default Mail Text is invalid PasswordComplexityPolicy: NotFound: Default Private Label Policy not found NotExisting: Default Password Complexity Policy not existing diff --git a/internal/v2/command/iam_converter.go b/internal/v2/command/iam_converter.go index 239e6b4c36..d2812db67a 100644 --- a/internal/v2/command/iam_converter.go +++ b/internal/v2/command/iam_converter.go @@ -52,6 +52,27 @@ func writeModelToLabelPolicy(wm *LabelPolicyWriteModel) *domain.LabelPolicy { } } +func writeModelToMailTemplate(wm *MailTemplateWriteModel) *domain.MailTemplate { + return &domain.MailTemplate{ + ObjectRoot: writeModelToObjectRoot(wm.WriteModel), + Template: wm.Template, + } +} + +func writeModelToMailText(wm *MailTextWriteModel) *domain.MailText { + return &domain.MailText{ + ObjectRoot: writeModelToObjectRoot(wm.WriteModel), + MailTextType: wm.MailTextType, + Language: wm.Language, + Title: wm.Title, + PreHeader: wm.PreHeader, + Subject: wm.Subject, + Greeting: wm.Greeting, + Text: wm.Text, + ButtonText: wm.ButtonText, + } +} + func writeModelToOrgIAMPolicy(wm *IAMOrgIAMPolicyWriteModel) *domain.OrgIAMPolicy { return &domain.OrgIAMPolicy{ ObjectRoot: writeModelToObjectRoot(wm.PolicyOrgIAMWriteModel.WriteModel), @@ -59,6 +80,28 @@ func writeModelToOrgIAMPolicy(wm *IAMOrgIAMPolicyWriteModel) *domain.OrgIAMPolic } } +func writeModelToMailTemplatePolicy(wm *MailTemplateWriteModel) *domain.MailTemplate { + return &domain.MailTemplate{ + ObjectRoot: writeModelToObjectRoot(wm.WriteModel), + Template: wm.Template, + } +} + +func writeModelToMailTextPolicy(wm *MailTextWriteModel) *domain.MailText { + return &domain.MailText{ + ObjectRoot: writeModelToObjectRoot(wm.WriteModel), + State: wm.State, + MailTextType: wm.MailTextType, + Language: wm.Language, + Title: wm.Title, + PreHeader: wm.PreHeader, + Subject: wm.Subject, + Greeting: wm.Greeting, + Text: wm.Text, + ButtonText: wm.ButtonText, + } +} + func writeModelToPasswordAgePolicy(wm *PasswordAgePolicyWriteModel) *domain.PasswordAgePolicy { return &domain.PasswordAgePolicy{ ObjectRoot: writeModelToObjectRoot(wm.WriteModel), diff --git a/internal/v2/command/iam_policy_mail_template.go b/internal/v2/command/iam_policy_mail_template.go new file mode 100644 index 0000000000..f08ddefa81 --- /dev/null +++ b/internal/v2/command/iam_policy_mail_template.go @@ -0,0 +1,83 @@ +package command + +import ( + "context" + caos_errs "github.com/caos/zitadel/internal/errors" + "github.com/caos/zitadel/internal/telemetry/tracing" + "github.com/caos/zitadel/internal/v2/domain" + iam_repo "github.com/caos/zitadel/internal/v2/repository/iam" +) + +func (r *CommandSide) AddDefaultMailTemplate(ctx context.Context, policy *domain.MailTemplate) (*domain.MailTemplate, error) { + addedPolicy := NewIAMMailTemplateWriteModel() + iamAgg := IAMAggregateFromWriteModel(&addedPolicy.MailTemplateWriteModel.WriteModel) + err := r.addDefaultMailTemplate(ctx, nil, addedPolicy, policy) + if err != nil { + return nil, err + } + + err = r.eventstore.PushAggregate(ctx, addedPolicy, iamAgg) + if err != nil { + return nil, err + } + + return writeModelToMailTemplatePolicy(&addedPolicy.MailTemplateWriteModel), nil +} + +func (r *CommandSide) addDefaultMailTemplate(ctx context.Context, iamAgg *iam_repo.Aggregate, addedPolicy *IAMMailTemplateWriteModel, policy *domain.MailTemplate) error { + if !policy.IsValid() { + return caos_errs.ThrowPreconditionFailed(nil, "IAM-fm9sd", "Errors.IAM.MailTemplate.Invalid") + } + err := r.eventstore.FilterToQueryReducer(ctx, addedPolicy) + if err != nil { + return err + } + if addedPolicy.State == domain.PolicyStateActive { + return caos_errs.ThrowAlreadyExists(nil, "IAM-5n8fs", "Errors.IAM.MailTemplate.AlreadyExists") + } + + iamAgg.PushEvents(iam_repo.NewMailTemplateAddedEvent(ctx, policy.Template)) + + return nil +} + +func (r *CommandSide) ChangeDefaultMailTemplate(ctx context.Context, policy *domain.MailTemplate) (*domain.MailTemplate, error) { + if !policy.IsValid() { + return nil, caos_errs.ThrowPreconditionFailed(nil, "IAM-4m9ds", "Errors.IAM.MailTemplate.Invalid") + } + existingPolicy, err := r.defaultMailTemplateWriteModelByID(ctx) + if err != nil { + return nil, err + } + + if existingPolicy.State == domain.PolicyStateUnspecified || existingPolicy.State == domain.PolicyStateRemoved { + return nil, caos_errs.ThrowNotFound(nil, "IAM-2N8fs", "Errors.IAM.MailTemplate.NotFound") + } + + changedEvent, hasChanged := existingPolicy.NewChangedEvent(ctx, policy.Template) + if !hasChanged { + return nil, caos_errs.ThrowPreconditionFailed(nil, "IAM-3nfsG", "Errors.IAM.MailTemplate.NotChanged") + } + + iamAgg := IAMAggregateFromWriteModel(&existingPolicy.MailTemplateWriteModel.WriteModel) + iamAgg.PushEvents(changedEvent) + + err = r.eventstore.PushAggregate(ctx, existingPolicy, iamAgg) + if err != nil { + return nil, err + } + + return writeModelToMailTemplatePolicy(&existingPolicy.MailTemplateWriteModel), nil +} + +func (r *CommandSide) defaultMailTemplateWriteModelByID(ctx context.Context) (policy *IAMMailTemplateWriteModel, err error) { + ctx, span := tracing.NewSpan(ctx) + defer func() { span.EndWithError(err) }() + + writeModel := NewIAMMailTemplateWriteModel() + err = r.eventstore.FilterToQueryReducer(ctx, writeModel) + if err != nil { + return nil, err + } + return writeModel, nil +} diff --git a/internal/v2/command/iam_policy_mail_template_model.go b/internal/v2/command/iam_policy_mail_template_model.go new file mode 100644 index 0000000000..07d8f4ad0f --- /dev/null +++ b/internal/v2/command/iam_policy_mail_template_model.go @@ -0,0 +1,65 @@ +package command + +import ( + "context" + "reflect" + + "github.com/caos/zitadel/internal/eventstore/v2" + "github.com/caos/zitadel/internal/v2/domain" + "github.com/caos/zitadel/internal/v2/repository/iam" + "github.com/caos/zitadel/internal/v2/repository/policy" +) + +type IAMMailTemplateWriteModel struct { + MailTemplateWriteModel +} + +func NewIAMMailTemplateWriteModel() *IAMMailTemplateWriteModel { + return &IAMMailTemplateWriteModel{ + MailTemplateWriteModel{ + WriteModel: eventstore.WriteModel{ + AggregateID: domain.IAMID, + ResourceOwner: domain.IAMID, + }, + }, + } +} + +func (wm *IAMMailTemplateWriteModel) AppendEvents(events ...eventstore.EventReader) { + for _, event := range events { + switch e := event.(type) { + case *iam.MailTemplateAddedEvent: + wm.MailTemplateWriteModel.AppendEvents(&e.MailTemplateAddedEvent) + case *iam.MailTemplateChangedEvent: + wm.MailTemplateWriteModel.AppendEvents(&e.MailTemplateChangedEvent) + } + } +} + +func (wm *IAMMailTemplateWriteModel) Reduce() error { + return wm.MailTemplateWriteModel.Reduce() +} + +func (wm *IAMMailTemplateWriteModel) Query() *eventstore.SearchQueryBuilder { + return eventstore.NewSearchQueryBuilder(eventstore.ColumnsEvent, iam.AggregateType). + AggregateIDs(wm.MailTemplateWriteModel.AggregateID). + ResourceOwner(wm.ResourceOwner) +} + +func (wm *IAMMailTemplateWriteModel) NewChangedEvent( + ctx context.Context, + template []byte, +) (*iam.MailTemplateChangedEvent, bool) { + changes := make([]policy.MailTemplateChanges, 0) + if !reflect.DeepEqual(wm.Template, template) { + changes = append(changes, policy.ChangeTemplate(template)) + } + if len(changes) == 0 { + return nil, false + } + changedEvent, err := iam.NewMailTemplateChangedEvent(ctx, changes) + if err != nil { + return nil, false + } + return changedEvent, true +} diff --git a/internal/v2/command/iam_policy_mail_text.go b/internal/v2/command/iam_policy_mail_text.go new file mode 100644 index 0000000000..25ec6b67b1 --- /dev/null +++ b/internal/v2/command/iam_policy_mail_text.go @@ -0,0 +1,103 @@ +package command + +import ( + "context" + caos_errs "github.com/caos/zitadel/internal/errors" + "github.com/caos/zitadel/internal/telemetry/tracing" + "github.com/caos/zitadel/internal/v2/domain" + iam_repo "github.com/caos/zitadel/internal/v2/repository/iam" +) + +func (r *CommandSide) AddDefaultMailText(ctx context.Context, policy *domain.MailText) (*domain.MailText, error) { + addedPolicy := NewIAMMailTextWriteModel(policy.MailTextType, policy.Language) + iamAgg := IAMAggregateFromWriteModel(&addedPolicy.MailTextWriteModel.WriteModel) + err := r.addDefaultMailText(ctx, nil, addedPolicy, policy) + if err != nil { + return nil, err + } + + err = r.eventstore.PushAggregate(ctx, addedPolicy, iamAgg) + if err != nil { + return nil, err + } + + return writeModelToMailTextPolicy(&addedPolicy.MailTextWriteModel), nil +} + +func (r *CommandSide) addDefaultMailText(ctx context.Context, iamAgg *iam_repo.Aggregate, addedPolicy *IAMMailTextWriteModel, mailText *domain.MailText) error { + if !mailText.IsValid() { + return caos_errs.ThrowPreconditionFailed(nil, "IAM-3n8fs", "Errors.IAM.MailText.Invalid") + } + err := r.eventstore.FilterToQueryReducer(ctx, addedPolicy) + if err != nil { + return err + } + if addedPolicy.State == domain.PolicyStateActive { + return caos_errs.ThrowAlreadyExists(nil, "IAM-9o0pM", "Errors.IAM.MailText.AlreadyExists") + } + + iamAgg.PushEvents( + iam_repo.NewMailTextAddedEvent( + ctx, + mailText.MailTextType, + mailText.Language, + mailText.Title, + mailText.PreHeader, + mailText.Subject, + mailText.Greeting, + mailText.Text, + mailText.ButtonText), + ) + + return nil +} + +func (r *CommandSide) ChangeDefaultMailText(ctx context.Context, mailText *domain.MailText) (*domain.MailText, error) { + if !mailText.IsValid() { + return nil, caos_errs.ThrowPreconditionFailed(nil, "IAM-kd9fs", "Errors.IAM.MailText.Invalid") + } + existingPolicy, err := r.defaultMailTextWriteModelByID(ctx, mailText.MailTextType, mailText.Language) + if err != nil { + return nil, err + } + + if existingPolicy.State == domain.PolicyStateUnspecified || existingPolicy.State == domain.PolicyStateRemoved { + return nil, caos_errs.ThrowNotFound(nil, "IAM-2N8fs", "Errors.IAM.MailText.NotFound") + } + + changedEvent, hasChanged := existingPolicy.NewChangedEvent( + ctx, + mailText.MailTextType, + mailText.Language, + mailText.Title, + mailText.PreHeader, + mailText.Subject, + mailText.Greeting, + mailText.Text, + mailText.ButtonText) + if !hasChanged { + return nil, caos_errs.ThrowPreconditionFailed(nil, "IAM-m9L0s", "Errors.IAM.MailText.NotChanged") + } + + iamAgg := IAMAggregateFromWriteModel(&existingPolicy.MailTextWriteModel.WriteModel) + iamAgg.PushEvents(changedEvent) + + err = r.eventstore.PushAggregate(ctx, existingPolicy, iamAgg) + if err != nil { + return nil, err + } + + return writeModelToMailTextPolicy(&existingPolicy.MailTextWriteModel), nil +} + +func (r *CommandSide) defaultMailTextWriteModelByID(ctx context.Context, mailTextType, language string) (policy *IAMMailTextWriteModel, err error) { + ctx, span := tracing.NewSpan(ctx) + defer func() { span.EndWithError(err) }() + + writeModel := NewIAMMailTextWriteModel(mailTextType, language) + err = r.eventstore.FilterToQueryReducer(ctx, writeModel) + if err != nil { + return nil, err + } + return writeModel, nil +} diff --git a/internal/v2/command/iam_policy_mail_text_model.go b/internal/v2/command/iam_policy_mail_text_model.go new file mode 100644 index 0000000000..a87d89f5f9 --- /dev/null +++ b/internal/v2/command/iam_policy_mail_text_model.go @@ -0,0 +1,87 @@ +package command + +import ( + "context" + "github.com/caos/zitadel/internal/eventstore/v2" + "github.com/caos/zitadel/internal/v2/domain" + "github.com/caos/zitadel/internal/v2/repository/iam" + "github.com/caos/zitadel/internal/v2/repository/policy" +) + +type IAMMailTextWriteModel struct { + MailTextWriteModel +} + +func NewIAMMailTextWriteModel(mailTextType, language string) *IAMMailTextWriteModel { + return &IAMMailTextWriteModel{ + MailTextWriteModel{ + WriteModel: eventstore.WriteModel{ + AggregateID: domain.IAMID, + ResourceOwner: domain.IAMID, + }, + MailTextType: mailTextType, + Language: language, + }, + } +} + +func (wm *IAMMailTextWriteModel) AppendEvents(events ...eventstore.EventReader) { + for _, event := range events { + switch e := event.(type) { + case *iam.MailTextAddedEvent: + wm.MailTextWriteModel.AppendEvents(&e.MailTextAddedEvent) + case *iam.MailTextChangedEvent: + wm.MailTextWriteModel.AppendEvents(&e.MailTextChangedEvent) + } + } +} + +func (wm *IAMMailTextWriteModel) Reduce() error { + return wm.MailTextWriteModel.Reduce() +} + +func (wm *IAMMailTextWriteModel) Query() *eventstore.SearchQueryBuilder { + return eventstore.NewSearchQueryBuilder(eventstore.ColumnsEvent, iam.AggregateType). + AggregateIDs(wm.MailTextWriteModel.AggregateID). + ResourceOwner(wm.ResourceOwner) +} + +func (wm *IAMMailTextWriteModel) NewChangedEvent( + ctx context.Context, + mailTextType, + language, + title, + preHeader, + subject, + greeting, + text, + buttonText string, +) (*iam.MailTextChangedEvent, bool) { + changes := make([]policy.MailTextChanges, 0) + if wm.Title != title { + changes = append(changes, policy.ChangeTitle(title)) + } + if wm.PreHeader != preHeader { + changes = append(changes, policy.ChangePreHeader(preHeader)) + } + if wm.Subject != subject { + changes = append(changes, policy.ChangeSubject(subject)) + } + if wm.Greeting != greeting { + changes = append(changes, policy.ChangeGreeting(greeting)) + } + if wm.Text != text { + changes = append(changes, policy.ChangeText(text)) + } + if wm.ButtonText != buttonText { + changes = append(changes, policy.ChangeButtonText(buttonText)) + } + if len(changes) == 0 { + return nil, false + } + changedEvent, err := iam.NewMailTextChangedEvent(ctx, mailTextType, language, changes) + if err != nil { + return nil, false + } + return changedEvent, true +} diff --git a/internal/v2/command/org_policy_label.go b/internal/v2/command/org_policy_label.go index 77ee5f1775..1c7628c0be 100644 --- a/internal/v2/command/org_policy_label.go +++ b/internal/v2/command/org_policy_label.go @@ -8,8 +8,8 @@ import ( "github.com/caos/zitadel/internal/v2/repository/org" ) -func (r *CommandSide) AddLabelPolicy(ctx context.Context, policy *domain.LabelPolicy) (*domain.LabelPolicy, error) { - addedPolicy := NewOrgLabelPolicyWriteModel(policy.AggregateID) +func (r *CommandSide) AddLabelPolicy(ctx context.Context, resourceOwner string, policy *domain.LabelPolicy) (*domain.LabelPolicy, error) { + addedPolicy := NewOrgLabelPolicyWriteModel(resourceOwner) err := r.eventstore.FilterToQueryReducer(ctx, addedPolicy) if err != nil { return nil, err @@ -29,8 +29,8 @@ func (r *CommandSide) AddLabelPolicy(ctx context.Context, policy *domain.LabelPo return writeModelToLabelPolicy(&addedPolicy.LabelPolicyWriteModel), nil } -func (r *CommandSide) ChangeLabelPolicy(ctx context.Context, policy *domain.LabelPolicy) (*domain.LabelPolicy, error) { - existingPolicy := NewOrgLabelPolicyWriteModel(policy.AggregateID) +func (r *CommandSide) ChangeLabelPolicy(ctx context.Context, resourceOwner string, policy *domain.LabelPolicy) (*domain.LabelPolicy, error) { + existingPolicy := NewOrgLabelPolicyWriteModel(resourceOwner) err := r.eventstore.FilterToQueryReducer(ctx, existingPolicy) if err != nil { return nil, err diff --git a/internal/v2/command/org_policy_login.go b/internal/v2/command/org_policy_login.go index 7188b6129d..9393ab8cf3 100644 --- a/internal/v2/command/org_policy_login.go +++ b/internal/v2/command/org_policy_login.go @@ -10,8 +10,8 @@ import ( "github.com/caos/zitadel/internal/v2/repository/org" ) -func (r *CommandSide) AddLoginPolicy(ctx context.Context, policy *domain.LoginPolicy) (*domain.LoginPolicy, error) { - addedPolicy := NewOrgLoginPolicyWriteModel(policy.AggregateID) +func (r *CommandSide) AddLoginPolicy(ctx context.Context, resourceOwner string, policy *domain.LoginPolicy) (*domain.LoginPolicy, error) { + addedPolicy := NewOrgLoginPolicyWriteModel(resourceOwner) err := r.eventstore.FilterToQueryReducer(ctx, addedPolicy) if err != nil { return nil, err @@ -31,8 +31,8 @@ func (r *CommandSide) AddLoginPolicy(ctx context.Context, policy *domain.LoginPo return writeModelToLoginPolicy(&addedPolicy.LoginPolicyWriteModel), nil } -func (r *CommandSide) ChangeLoginPolicy(ctx context.Context, policy *domain.LoginPolicy) (*domain.LoginPolicy, error) { - existingPolicy := NewOrgLoginPolicyWriteModel(policy.AggregateID) +func (r *CommandSide) ChangeLoginPolicy(ctx context.Context, resourceOwner string, policy *domain.LoginPolicy) (*domain.LoginPolicy, error) { + existingPolicy := NewOrgLoginPolicyWriteModel(resourceOwner) err := r.eventstore.FilterToQueryReducer(ctx, existingPolicy) if err != nil { return nil, err @@ -71,8 +71,8 @@ func (r *CommandSide) RemoveLoginPolicy(ctx context.Context, orgID string) error return r.eventstore.PushAggregate(ctx, existingPolicy, orgAgg) } -func (r *CommandSide) AddIDPProviderToLoginPolicy(ctx context.Context, idpProvider *domain.IDPProvider) (*domain.IDPProvider, error) { - idpModel := NewOrgIdentityProviderWriteModel(idpProvider.AggregateID, idpProvider.IDPConfigID) +func (r *CommandSide) AddIDPProviderToLoginPolicy(ctx context.Context, resourceOwner string, idpProvider *domain.IDPProvider) (*domain.IDPProvider, error) { + idpModel := NewOrgIdentityProviderWriteModel(resourceOwner, idpProvider.IDPConfigID) err := r.eventstore.FilterToQueryReducer(ctx, idpModel) if err != nil { return nil, err @@ -91,8 +91,8 @@ func (r *CommandSide) AddIDPProviderToLoginPolicy(ctx context.Context, idpProvid return writeModelToIDPProvider(&idpModel.IdentityProviderWriteModel), nil } -func (r *CommandSide) RemoveIDPProviderFromLoginPolicy(ctx context.Context, idpProvider *domain.IDPProvider, cascadeExternalIDPs ...*domain.ExternalIDP) error { - idpModel := NewOrgIdentityProviderWriteModel(idpProvider.AggregateID, idpProvider.IDPConfigID) +func (r *CommandSide) RemoveIDPProviderFromLoginPolicy(ctx context.Context, resourceOwner string, idpProvider *domain.IDPProvider, cascadeExternalIDPs ...*domain.ExternalIDP) error { + idpModel := NewOrgIdentityProviderWriteModel(resourceOwner, idpProvider.IDPConfigID) err := r.eventstore.FilterToQueryReducer(ctx, idpModel) if err != nil { return err diff --git a/internal/v2/command/org_policy_mail_template.go b/internal/v2/command/org_policy_mail_template.go new file mode 100644 index 0000000000..558c7513d6 --- /dev/null +++ b/internal/v2/command/org_policy_mail_template.go @@ -0,0 +1,77 @@ +package command + +import ( + "context" + + caos_errs "github.com/caos/zitadel/internal/errors" + "github.com/caos/zitadel/internal/v2/domain" + "github.com/caos/zitadel/internal/v2/repository/org" +) + +func (r *CommandSide) AddMailTemplate(ctx context.Context, resourceOwner string, policy *domain.MailTemplate) (*domain.MailTemplate, error) { + if !policy.IsValid() { + return nil, caos_errs.ThrowPreconditionFailed(nil, "ORG-3m9fs", "Errors.Org.MailTemplate.Invalid") + } + addedPolicy := NewOrgMailTemplateWriteModel(resourceOwner) + err := r.eventstore.FilterToQueryReducer(ctx, addedPolicy) + if err != nil { + return nil, err + } + if addedPolicy.State == domain.PolicyStateActive { + return nil, caos_errs.ThrowAlreadyExists(nil, "Org-9kufs", "Errors.Org.MailTemplate.AlreadyExists") + } + + orgAgg := OrgAggregateFromWriteModel(&addedPolicy.MailTemplateWriteModel.WriteModel) + orgAgg.PushEvents(org.NewMailTemplateAddedEvent(ctx, policy.Template)) + + err = r.eventstore.PushAggregate(ctx, addedPolicy, orgAgg) + if err != nil { + return nil, err + } + + return writeModelToMailTemplate(&addedPolicy.MailTemplateWriteModel), nil +} + +func (r *CommandSide) ChangeMailTemplate(ctx context.Context, resourceOwner string, policy *domain.MailTemplate) (*domain.MailTemplate, error) { + if !policy.IsValid() { + return nil, caos_errs.ThrowPreconditionFailed(nil, "ORG-9f9ds", "Errors.Org.MailTemplate.Invalid") + } + existingPolicy := NewOrgMailTemplateWriteModel(resourceOwner) + err := r.eventstore.FilterToQueryReducer(ctx, existingPolicy) + if err != nil { + return nil, err + } + if existingPolicy.State == domain.PolicyStateUnspecified || existingPolicy.State == domain.PolicyStateRemoved { + return nil, caos_errs.ThrowNotFound(nil, "Org-5m9ie", "Errors.Org.MailTemplate.NotFound") + } + + changedEvent, hasChanged := existingPolicy.NewChangedEvent(ctx, policy.Template) + if !hasChanged { + return nil, caos_errs.ThrowPreconditionFailed(nil, "Org-4M9vs", "Errors.Org.MailTemplate.NotChanged") + } + + orgAgg := OrgAggregateFromWriteModel(&existingPolicy.MailTemplateWriteModel.WriteModel) + orgAgg.PushEvents(changedEvent) + + err = r.eventstore.PushAggregate(ctx, existingPolicy, orgAgg) + if err != nil { + return nil, err + } + + return writeModelToMailTemplate(&existingPolicy.MailTemplateWriteModel), nil +} + +func (r *CommandSide) RemoveMailTemplate(ctx context.Context, orgID string) error { + existingPolicy := NewOrgMailTemplateWriteModel(orgID) + err := r.eventstore.FilterToQueryReducer(ctx, existingPolicy) + if err != nil { + return err + } + if existingPolicy.State == domain.PolicyStateUnspecified || existingPolicy.State == domain.PolicyStateRemoved { + return caos_errs.ThrowNotFound(nil, "Org-3b8Jf", "Errors.Org.MailTemplate.NotFound") + } + orgAgg := OrgAggregateFromWriteModel(&existingPolicy.WriteModel) + orgAgg.PushEvents(org.NewMailTemplateRemovedEvent(ctx)) + + return r.eventstore.PushAggregate(ctx, existingPolicy, orgAgg) +} diff --git a/internal/v2/command/org_policy_mail_template_model.go b/internal/v2/command/org_policy_mail_template_model.go new file mode 100644 index 0000000000..1ac78bedf5 --- /dev/null +++ b/internal/v2/command/org_policy_mail_template_model.go @@ -0,0 +1,67 @@ +package command + +import ( + "context" + "reflect" + + "github.com/caos/zitadel/internal/eventstore/v2" + "github.com/caos/zitadel/internal/v2/repository/org" + "github.com/caos/zitadel/internal/v2/repository/policy" +) + +type OrgMailTemplateWriteModel struct { + MailTemplateWriteModel +} + +func NewOrgMailTemplateWriteModel(orgID string) *OrgMailTemplateWriteModel { + return &OrgMailTemplateWriteModel{ + MailTemplateWriteModel{ + WriteModel: eventstore.WriteModel{ + AggregateID: orgID, + ResourceOwner: orgID, + }, + }, + } +} + +func (wm *OrgMailTemplateWriteModel) AppendEvents(events ...eventstore.EventReader) { + for _, event := range events { + switch e := event.(type) { + case *org.MailTemplateAddedEvent: + wm.MailTemplateWriteModel.AppendEvents(&e.MailTemplateAddedEvent) + case *org.MailTemplateChangedEvent: + wm.MailTemplateWriteModel.AppendEvents(&e.MailTemplateChangedEvent) + } + } +} + +func (wm *OrgMailTemplateWriteModel) Reduce() error { + return wm.MailTemplateWriteModel.Reduce() +} + +func (wm *OrgMailTemplateWriteModel) Query() *eventstore.SearchQueryBuilder { + query := eventstore.NewSearchQueryBuilder(eventstore.ColumnsEvent, org.AggregateType). + AggregateIDs(wm.MailTemplateWriteModel.AggregateID) + if wm.ResourceOwner != "" { + query.ResourceOwner(wm.ResourceOwner) + } + return query +} + +func (wm *OrgMailTemplateWriteModel) NewChangedEvent( + ctx context.Context, + template []byte, +) (*org.MailTemplateChangedEvent, bool) { + changes := make([]policy.MailTemplateChanges, 0) + if !reflect.DeepEqual(wm.Template, template) { + changes = append(changes, policy.ChangeTemplate(template)) + } + if len(changes) == 0 { + return nil, false + } + changedEvent, err := org.NewMailTemplateChangedEvent(ctx, changes) + if err != nil { + return nil, false + } + return changedEvent, true +} diff --git a/internal/v2/command/org_policy_mail_text.go b/internal/v2/command/org_policy_mail_text.go new file mode 100644 index 0000000000..ae4e7db6db --- /dev/null +++ b/internal/v2/command/org_policy_mail_text.go @@ -0,0 +1,97 @@ +package command + +import ( + "context" + + caos_errs "github.com/caos/zitadel/internal/errors" + "github.com/caos/zitadel/internal/v2/domain" + "github.com/caos/zitadel/internal/v2/repository/org" +) + +func (r *CommandSide) AddMailText(ctx context.Context, resourceOwner string, mailText *domain.MailText) (*domain.MailText, error) { + if !mailText.IsValid() { + return nil, caos_errs.ThrowPreconditionFailed(nil, "Org-4778u", "Errors.Org.MailText.Invalid") + } + addedPolicy := NewOrgMailTextWriteModel(resourceOwner, mailText.MailTextType, mailText.Language) + err := r.eventstore.FilterToQueryReducer(ctx, addedPolicy) + if err != nil { + return nil, err + } + if addedPolicy.State == domain.PolicyStateActive { + return nil, caos_errs.ThrowAlreadyExists(nil, "Org-9kufs", "Errors.Org.MailText.AlreadyExists") + } + + orgAgg := OrgAggregateFromWriteModel(&addedPolicy.MailTextWriteModel.WriteModel) + orgAgg.PushEvents( + org.NewMailTextAddedEvent( + ctx, + resourceOwner, + mailText.MailTextType, + mailText.Language, + mailText.Title, + mailText.PreHeader, + mailText.Subject, + mailText.Greeting, + mailText.Text, + mailText.ButtonText)) + + err = r.eventstore.PushAggregate(ctx, addedPolicy, orgAgg) + if err != nil { + return nil, err + } + + return writeModelToMailText(&addedPolicy.MailTextWriteModel), nil +} + +func (r *CommandSide) ChangeMailText(ctx context.Context, resourceOwner string, mailText *domain.MailText) (*domain.MailText, error) { + if !mailText.IsValid() { + return nil, caos_errs.ThrowPreconditionFailed(nil, "Org-3m9fs", "Errors.Org.MailText.Invalid") + } + existingPolicy := NewOrgMailTextWriteModel(resourceOwner, mailText.MailTextType, mailText.Language) + err := r.eventstore.FilterToQueryReducer(ctx, existingPolicy) + if err != nil { + return nil, err + } + if existingPolicy.State == domain.PolicyStateUnspecified || existingPolicy.State == domain.PolicyStateRemoved { + return nil, caos_errs.ThrowNotFound(nil, "Org-3n8fM", "Errors.Org.MailText.NotFound") + } + + changedEvent, hasChanged := existingPolicy.NewChangedEvent( + ctx, + mailText.MailTextType, + mailText.Language, + mailText.Title, + mailText.PreHeader, + mailText.Subject, + mailText.Greeting, + mailText.Text, + mailText.ButtonText) + if !hasChanged { + return nil, caos_errs.ThrowPreconditionFailed(nil, "Org-2n9fs", "Errors.Org.MailText.NotChanged") + } + + orgAgg := OrgAggregateFromWriteModel(&existingPolicy.MailTextWriteModel.WriteModel) + orgAgg.PushEvents(changedEvent) + + err = r.eventstore.PushAggregate(ctx, existingPolicy, orgAgg) + if err != nil { + return nil, err + } + + return writeModelToMailText(&existingPolicy.MailTextWriteModel), nil +} + +func (r *CommandSide) RemoveMailText(ctx context.Context, resourceOwner, mailTextType, language string) error { + existingPolicy := NewOrgMailTextWriteModel(resourceOwner, mailTextType, language) + err := r.eventstore.FilterToQueryReducer(ctx, existingPolicy) + if err != nil { + return err + } + if existingPolicy.State == domain.PolicyStateUnspecified || existingPolicy.State == domain.PolicyStateRemoved { + return caos_errs.ThrowNotFound(nil, "Org-3b8Jf", "Errors.Org.MailText.NotFound") + } + orgAgg := OrgAggregateFromWriteModel(&existingPolicy.WriteModel) + orgAgg.PushEvents(org.NewMailTextRemovedEvent(ctx, mailTextType, language, resourceOwner)) + + return r.eventstore.PushAggregate(ctx, existingPolicy, orgAgg) +} diff --git a/internal/v2/command/org_policy_mail_text_model.go b/internal/v2/command/org_policy_mail_text_model.go new file mode 100644 index 0000000000..e493e5cf5b --- /dev/null +++ b/internal/v2/command/org_policy_mail_text_model.go @@ -0,0 +1,89 @@ +package command + +import ( + "context" + "github.com/caos/zitadel/internal/eventstore/v2" + "github.com/caos/zitadel/internal/v2/repository/org" + "github.com/caos/zitadel/internal/v2/repository/policy" +) + +type OrgMailTextWriteModel struct { + MailTextWriteModel +} + +func NewOrgMailTextWriteModel(orgID, mailTextType, language string) *OrgMailTextWriteModel { + return &OrgMailTextWriteModel{ + MailTextWriteModel{ + WriteModel: eventstore.WriteModel{ + AggregateID: orgID, + ResourceOwner: orgID, + }, + MailTextType: mailTextType, + Language: language, + }, + } +} + +func (wm *OrgMailTextWriteModel) AppendEvents(events ...eventstore.EventReader) { + for _, event := range events { + switch e := event.(type) { + case *org.MailTextAddedEvent: + wm.MailTextWriteModel.AppendEvents(&e.MailTextAddedEvent) + case *org.MailTextChangedEvent: + wm.MailTextWriteModel.AppendEvents(&e.MailTextChangedEvent) + } + } +} + +func (wm *OrgMailTextWriteModel) Reduce() error { + return wm.MailTextWriteModel.Reduce() +} + +func (wm *OrgMailTextWriteModel) Query() *eventstore.SearchQueryBuilder { + query := eventstore.NewSearchQueryBuilder(eventstore.ColumnsEvent, org.AggregateType). + AggregateIDs(wm.MailTextWriteModel.AggregateID) + if wm.ResourceOwner != "" { + query.ResourceOwner(wm.ResourceOwner) + } + return query +} + +func (wm *OrgMailTextWriteModel) NewChangedEvent( + ctx context.Context, + mailTextType, + language, + title, + preHeader, + subject, + greeting, + text, + buttonText string, +) (*org.MailTextChangedEvent, bool) { + changes := make([]policy.MailTextChanges, 0) + if wm.Title != title { + changes = append(changes, policy.ChangeTitle(title)) + } + if wm.PreHeader != preHeader { + changes = append(changes, policy.ChangePreHeader(preHeader)) + } + if wm.Subject != subject { + changes = append(changes, policy.ChangeSubject(subject)) + } + if wm.Greeting != greeting { + changes = append(changes, policy.ChangeGreeting(greeting)) + } + if wm.Text != text { + changes = append(changes, policy.ChangeText(text)) + } + if wm.ButtonText != buttonText { + changes = append(changes, policy.ChangeButtonText(buttonText)) + } + if len(changes) == 0 { + return nil, false + } + changedEvent, err := org.NewMailTextChangedEvent(ctx, mailTextType, language, changes) + if err != nil { + return nil, false + } + return changedEvent, true +} diff --git a/internal/v2/command/org_policy_org_iam.go b/internal/v2/command/org_policy_org_iam.go index a79bb78e80..ff50710b06 100644 --- a/internal/v2/command/org_policy_org_iam.go +++ b/internal/v2/command/org_policy_org_iam.go @@ -8,8 +8,8 @@ import ( "github.com/caos/zitadel/internal/v2/repository/org" ) -func (r *CommandSide) AddOrgIAMPolicy(ctx context.Context, policy *domain.OrgIAMPolicy) (*domain.OrgIAMPolicy, error) { - addedPolicy := NewORGOrgIAMPolicyWriteModel(policy.AggregateID) +func (r *CommandSide) AddOrgIAMPolicy(ctx context.Context, resourceOwner string, policy *domain.OrgIAMPolicy) (*domain.OrgIAMPolicy, error) { + addedPolicy := NewORGOrgIAMPolicyWriteModel(resourceOwner) orgAgg := OrgAggregateFromWriteModel(&addedPolicy.PolicyOrgIAMWriteModel.WriteModel) err := r.addOrgIAMPolicy(ctx, orgAgg, addedPolicy, policy) if err != nil { @@ -40,8 +40,8 @@ func (r *CommandSide) addOrgIAMPolicy(ctx context.Context, orgAgg *org.Aggregate return nil } -func (r *CommandSide) ChangeOrgIAMPolicy(ctx context.Context, policy *domain.OrgIAMPolicy) (*domain.OrgIAMPolicy, error) { - existingPolicy, err := r.orgIAMPolicyWriteModelByID(ctx, policy.AggregateID) +func (r *CommandSide) ChangeOrgIAMPolicy(ctx context.Context, resourceOwner string, policy *domain.OrgIAMPolicy) (*domain.OrgIAMPolicy, error) { + existingPolicy, err := r.orgIAMPolicyWriteModelByID(ctx, resourceOwner) if err != nil { return nil, err } diff --git a/internal/v2/command/org_policy_password_age.go b/internal/v2/command/org_policy_password_age.go index 9e21d0b688..b6c6f5dfdf 100644 --- a/internal/v2/command/org_policy_password_age.go +++ b/internal/v2/command/org_policy_password_age.go @@ -8,8 +8,8 @@ import ( "github.com/caos/zitadel/internal/v2/repository/org" ) -func (r *CommandSide) AddPasswordAgePolicy(ctx context.Context, policy *domain.PasswordAgePolicy) (*domain.PasswordAgePolicy, error) { - addedPolicy := NewOrgPasswordAgePolicyWriteModel(policy.AggregateID) +func (r *CommandSide) AddPasswordAgePolicy(ctx context.Context, resourceOwner string, policy *domain.PasswordAgePolicy) (*domain.PasswordAgePolicy, error) { + addedPolicy := NewOrgPasswordAgePolicyWriteModel(resourceOwner) err := r.eventstore.FilterToQueryReducer(ctx, addedPolicy) if err != nil { return nil, err @@ -29,8 +29,8 @@ func (r *CommandSide) AddPasswordAgePolicy(ctx context.Context, policy *domain.P return writeModelToPasswordAgePolicy(&addedPolicy.PasswordAgePolicyWriteModel), nil } -func (r *CommandSide) ChangePasswordAgePolicy(ctx context.Context, policy *domain.PasswordAgePolicy) (*domain.PasswordAgePolicy, error) { - existingPolicy := NewOrgPasswordAgePolicyWriteModel(policy.AggregateID) +func (r *CommandSide) ChangePasswordAgePolicy(ctx context.Context, resourceOwner string, policy *domain.PasswordAgePolicy) (*domain.PasswordAgePolicy, error) { + existingPolicy := NewOrgPasswordAgePolicyWriteModel(resourceOwner) err := r.eventstore.FilterToQueryReducer(ctx, existingPolicy) if err != nil { return nil, err diff --git a/internal/v2/command/org_policy_password_complexity.go b/internal/v2/command/org_policy_password_complexity.go index 272a6eb74f..52e11c90fd 100644 --- a/internal/v2/command/org_policy_password_complexity.go +++ b/internal/v2/command/org_policy_password_complexity.go @@ -20,11 +20,11 @@ func (r *CommandSide) getOrgPasswordComplexityPolicy(ctx context.Context, orgID return r.getDefaultPasswordComplexityPolicy(ctx) } -func (r *CommandSide) AddPasswordComplexityPolicy(ctx context.Context, policy *domain.PasswordComplexityPolicy) (*domain.PasswordComplexityPolicy, error) { +func (r *CommandSide) AddPasswordComplexityPolicy(ctx context.Context, resourceOwner string, policy *domain.PasswordComplexityPolicy) (*domain.PasswordComplexityPolicy, error) { if err := policy.IsValid(); err != nil { return nil, err } - addedPolicy := NewOrgPasswordComplexityPolicyWriteModel(policy.AggregateID) + addedPolicy := NewOrgPasswordComplexityPolicyWriteModel(resourceOwner) err := r.eventstore.FilterToQueryReducer(ctx, addedPolicy) if err != nil { return nil, err @@ -44,12 +44,12 @@ func (r *CommandSide) AddPasswordComplexityPolicy(ctx context.Context, policy *d return writeModelToPasswordComplexityPolicy(&addedPolicy.PasswordComplexityPolicyWriteModel), nil } -func (r *CommandSide) ChangePasswordComplexityPolicy(ctx context.Context, policy *domain.PasswordComplexityPolicy) (*domain.PasswordComplexityPolicy, error) { +func (r *CommandSide) ChangePasswordComplexityPolicy(ctx context.Context, resourceOwner string, policy *domain.PasswordComplexityPolicy) (*domain.PasswordComplexityPolicy, error) { if err := policy.IsValid(); err != nil { return nil, err } - existingPolicy := NewOrgPasswordComplexityPolicyWriteModel(policy.AggregateID) + existingPolicy := NewOrgPasswordComplexityPolicyWriteModel(resourceOwner) err := r.eventstore.FilterToQueryReducer(ctx, existingPolicy) if err != nil { return nil, err diff --git a/internal/v2/command/org_policy_password_lockout.go b/internal/v2/command/org_policy_password_lockout.go index 260ca987cc..c07635e35f 100644 --- a/internal/v2/command/org_policy_password_lockout.go +++ b/internal/v2/command/org_policy_password_lockout.go @@ -8,8 +8,8 @@ import ( "github.com/caos/zitadel/internal/v2/repository/org" ) -func (r *CommandSide) AddPasswordLockoutPolicy(ctx context.Context, policy *domain.PasswordLockoutPolicy) (*domain.PasswordLockoutPolicy, error) { - addedPolicy := NewOrgPasswordLockoutPolicyWriteModel(policy.AggregateID) +func (r *CommandSide) AddPasswordLockoutPolicy(ctx context.Context, resourceOwner string, policy *domain.PasswordLockoutPolicy) (*domain.PasswordLockoutPolicy, error) { + addedPolicy := NewOrgPasswordLockoutPolicyWriteModel(resourceOwner) err := r.eventstore.FilterToQueryReducer(ctx, addedPolicy) if err != nil { return nil, err @@ -29,8 +29,8 @@ func (r *CommandSide) AddPasswordLockoutPolicy(ctx context.Context, policy *doma return writeModelToPasswordLockoutPolicy(&addedPolicy.PasswordLockoutPolicyWriteModel), nil } -func (r *CommandSide) ChangePasswordLockoutPolicy(ctx context.Context, policy *domain.PasswordLockoutPolicy) (*domain.PasswordLockoutPolicy, error) { - existingPolicy := NewOrgPasswordLockoutPolicyWriteModel(policy.AggregateID) +func (r *CommandSide) ChangePasswordLockoutPolicy(ctx context.Context, resourceOwner string, policy *domain.PasswordLockoutPolicy) (*domain.PasswordLockoutPolicy, error) { + existingPolicy := NewOrgPasswordLockoutPolicyWriteModel(resourceOwner) err := r.eventstore.FilterToQueryReducer(ctx, existingPolicy) if err != nil { return nil, err diff --git a/internal/v2/command/policy_mail_template_model.go b/internal/v2/command/policy_mail_template_model.go new file mode 100644 index 0000000000..bbf6950329 --- /dev/null +++ b/internal/v2/command/policy_mail_template_model.go @@ -0,0 +1,32 @@ +package command + +import ( + "github.com/caos/zitadel/internal/eventstore/v2" + "github.com/caos/zitadel/internal/v2/domain" + "github.com/caos/zitadel/internal/v2/repository/policy" +) + +type MailTemplateWriteModel struct { + eventstore.WriteModel + + Template []byte + + State domain.PolicyState +} + +func (wm *MailTemplateWriteModel) Reduce() error { + for _, event := range wm.Events { + switch e := event.(type) { + case *policy.MailTemplateAddedEvent: + wm.Template = e.Template + wm.State = domain.PolicyStateActive + case *policy.MailTemplateChangedEvent: + if e.Template != nil { + wm.Template = *e.Template + } + case *policy.MailTemplateRemovedEvent: + wm.State = domain.PolicyStateRemoved + } + } + return wm.WriteModel.Reduce() +} diff --git a/internal/v2/command/policy_mail_text_model.go b/internal/v2/command/policy_mail_text_model.go new file mode 100644 index 0000000000..ad1fe4c226 --- /dev/null +++ b/internal/v2/command/policy_mail_text_model.go @@ -0,0 +1,65 @@ +package command + +import ( + "github.com/caos/zitadel/internal/eventstore/v2" + "github.com/caos/zitadel/internal/v2/domain" + "github.com/caos/zitadel/internal/v2/repository/policy" +) + +type MailTextWriteModel struct { + eventstore.WriteModel + + MailTextType string + Language string + Title string + PreHeader string + Subject string + Greeting string + Text string + ButtonText string + + State domain.PolicyState +} + +func (wm *MailTextWriteModel) Reduce() error { + for _, event := range wm.Events { + switch e := event.(type) { + case *policy.MailTextAddedEvent: + if wm.MailTextType != e.MailTextType || wm.Language != e.Language { + continue + } + wm.Title = e.Title + wm.PreHeader = e.PreHeader + wm.Subject = e.Subject + wm.Greeting = e.Greeting + wm.Text = e.Text + wm.ButtonText = e.ButtonText + wm.State = domain.PolicyStateActive + case *policy.MailTextChangedEvent: + if wm.MailTextType != e.MailTextType || wm.Language != e.Language { + continue + } + if e.Title != nil { + wm.Title = *e.Title + } + if e.PreHeader != nil { + wm.PreHeader = *e.PreHeader + } + if e.Subject != nil { + wm.Subject = *e.Subject + } + if e.Greeting != nil { + wm.Greeting = *e.Greeting + } + if e.Text != nil { + wm.Text = *e.Text + } + if e.ButtonText != nil { + wm.ButtonText = *e.ButtonText + } + case *policy.MailTextRemovedEvent: + wm.State = domain.PolicyStateRemoved + } + } + return wm.WriteModel.Reduce() +} diff --git a/internal/v2/command/setup_step10.go b/internal/v2/command/setup_step10.go index c000c19d48..47e93af9e1 100644 --- a/internal/v2/command/setup_step10.go +++ b/internal/v2/command/setup_step10.go @@ -2,15 +2,14 @@ package command import ( "context" - iam_model "github.com/caos/zitadel/internal/iam/model" - + "github.com/caos/logging" "github.com/caos/zitadel/internal/v2/domain" iam_repo "github.com/caos/zitadel/internal/v2/repository/iam" ) type Step10 struct { - DefaultMailTemplate iam_model.MailTemplate - DefaultMailTexts []iam_model.MailText + DefaultMailTemplate domain.MailTemplate + DefaultMailTexts []domain.MailText } func (s *Step10) Step() domain.Step { @@ -23,23 +22,19 @@ func (s *Step10) execute(ctx context.Context, commandSide *CommandSide) error { func (r *CommandSide) SetupStep10(ctx context.Context, step *Step10) error { fn := func(iam *IAMWriteModel) (*iam_repo.Aggregate, error) { - //multiFactorModel := NewIAMMultiFactorWriteModel() - //iamAgg := IAMAggregateFromWriteModel(&multiFactorModel.MultiFactoryWriteModel.WriteModel) - //if !step.Passwordless { - // return iamAgg, nil - //} - //err := setPasswordlessAllowedInPolicy(ctx, r, iamAgg) - //if err != nil { - // return nil, err - //} - //logging.Log("SETUP-AEG2t").Info("allowed passwordless in login policy") - //err = r.addMultiFactorToDefaultLoginPolicy(ctx, iamAgg, multiFactorModel, domain.MultiFactorTypeU2FWithPIN) - //if err != nil { - // return nil, err - //} - //logging.Log("SETUP-ADfng").Info("added passwordless to MFA login policy") - //return iamAgg, err - return nil, nil + iamAgg := IAMAggregateFromWriteModel(&iam.WriteModel) + err := r.addDefaultMailTemplate(ctx, iamAgg, NewIAMMailTemplateWriteModel(), &step.DefaultMailTemplate) + if err != nil { + return nil, err + } + for _, text := range step.DefaultMailTexts { + r.addDefaultMailText(ctx, iamAgg, NewIAMMailTextWriteModel(text.MailTextType, text.Language), &text) + if err != nil { + return nil, err + } + } + logging.Log("SETUP-3N9fs").Info("default mail template/text set up") + return iamAgg, nil } return r.setup(ctx, step, fn) } diff --git a/internal/v2/domain/policy_mail_template.go b/internal/v2/domain/policy_mail_template.go new file mode 100644 index 0000000000..be205cede3 --- /dev/null +++ b/internal/v2/domain/policy_mail_template.go @@ -0,0 +1,15 @@ +package domain + +import "github.com/caos/zitadel/internal/eventstore/models" + +type MailTemplate struct { + models.ObjectRoot + + State PolicyState + Default bool + Template []byte +} + +func (m *MailTemplate) IsValid() bool { + return m.Template != nil +} diff --git a/internal/v2/domain/policy_mail_text.go b/internal/v2/domain/policy_mail_text.go new file mode 100644 index 0000000000..35a1950549 --- /dev/null +++ b/internal/v2/domain/policy_mail_text.go @@ -0,0 +1,22 @@ +package domain + +import "github.com/caos/zitadel/internal/eventstore/models" + +type MailText struct { + models.ObjectRoot + + State PolicyState + Default bool + MailTextType string + Language string + Title string + PreHeader string + Subject string + Greeting string + Text string + ButtonText string +} + +func (m *MailText) IsValid() bool { + return m.MailTextType != "" && m.Language != "" && m.Title != "" && m.PreHeader != "" && m.Subject != "" && m.Greeting != "" && m.Text != "" && m.ButtonText != "" +} diff --git a/internal/v2/repository/iam/eventstore.go b/internal/v2/repository/iam/eventstore.go index 8a73336c54..f57efa2568 100644 --- a/internal/v2/repository/iam/eventstore.go +++ b/internal/v2/repository/iam/eventstore.go @@ -32,5 +32,9 @@ func RegisterEventMappers(es *eventstore.Eventstore) { RegisterFilterEventMapper(IDPOIDCConfigChangedEventType, IDPOIDCConfigChangedEventMapper). RegisterFilterEventMapper(LoginPolicyIDPProviderAddedEventType, IdentityProviderAddedEventMapper). RegisterFilterEventMapper(LoginPolicyIDPProviderRemovedEventType, IdentityProviderRemovedEventMapper). - RegisterFilterEventMapper(LoginPolicyIDPProviderCascadeRemovedEventType, IdentityProviderCascadeRemovedEventMapper) + RegisterFilterEventMapper(LoginPolicyIDPProviderCascadeRemovedEventType, IdentityProviderCascadeRemovedEventMapper). + RegisterFilterEventMapper(MailTemplateAddedEventType, MailTemplateAddedEventMapper). + RegisterFilterEventMapper(MailTemplateChangedEventType, MailTemplateChangedEventMapper). + RegisterFilterEventMapper(MailTextAddedEventType, MailTextAddedEventMapper). + RegisterFilterEventMapper(MailTextChangedEventType, MailTextChangedEventMapper) } diff --git a/internal/v2/repository/iam/policy_mail_template.go b/internal/v2/repository/iam/policy_mail_template.go new file mode 100644 index 0000000000..65448b8795 --- /dev/null +++ b/internal/v2/repository/iam/policy_mail_template.go @@ -0,0 +1,64 @@ +package iam + +import ( + "context" + "github.com/caos/zitadel/internal/eventstore/v2" + "github.com/caos/zitadel/internal/eventstore/v2/repository" + "github.com/caos/zitadel/internal/v2/repository/policy" +) + +var ( + MailTemplateAddedEventType = iamEventTypePrefix + policy.MailTemplatePolicyAddedEventType + MailTemplateChangedEventType = iamEventTypePrefix + policy.MailTemplatePolicyChangedEventType +) + +type MailTemplateAddedEvent struct { + policy.MailTemplateAddedEvent +} + +func NewMailTemplateAddedEvent( + ctx context.Context, + template []byte, +) *MailTemplateAddedEvent { + return &MailTemplateAddedEvent{ + MailTemplateAddedEvent: *policy.NewMailTemplateAddedEvent( + eventstore.NewBaseEventForPush(ctx, MailTemplateAddedEventType), + template), + } +} + +func MailTemplateAddedEventMapper(event *repository.Event) (eventstore.EventReader, error) { + e, err := policy.MailTemplateAddedEventMapper(event) + if err != nil { + return nil, err + } + + return &MailTemplateAddedEvent{MailTemplateAddedEvent: *e.(*policy.MailTemplateAddedEvent)}, nil +} + +type MailTemplateChangedEvent struct { + policy.MailTemplateChangedEvent +} + +func NewMailTemplateChangedEvent( + ctx context.Context, + changes []policy.MailTemplateChanges, +) (*MailTemplateChangedEvent, error) { + changedEvent, err := policy.NewMailTemplateChangedEvent( + eventstore.NewBaseEventForPush(ctx, MailTemplateChangedEventType), + changes, + ) + if err != nil { + return nil, err + } + return &MailTemplateChangedEvent{MailTemplateChangedEvent: *changedEvent}, nil +} + +func MailTemplateChangedEventMapper(event *repository.Event) (eventstore.EventReader, error) { + e, err := policy.MailTemplateChangedEventMapper(event) + if err != nil { + return nil, err + } + + return &MailTemplateChangedEvent{MailTemplateChangedEvent: *e.(*policy.MailTemplateChangedEvent)}, nil +} diff --git a/internal/v2/repository/iam/policy_mail_text.go b/internal/v2/repository/iam/policy_mail_text.go new file mode 100644 index 0000000000..c0ec0f7f6e --- /dev/null +++ b/internal/v2/repository/iam/policy_mail_text.go @@ -0,0 +1,83 @@ +package iam + +import ( + "context" + "github.com/caos/zitadel/internal/eventstore/v2" + "github.com/caos/zitadel/internal/eventstore/v2/repository" + "github.com/caos/zitadel/internal/v2/domain" + "github.com/caos/zitadel/internal/v2/repository/policy" +) + +var ( + MailTextAddedEventType = iamEventTypePrefix + policy.MailTextPolicyAddedEventType + MailTextChangedEventType = iamEventTypePrefix + policy.MailTextPolicyChangedEventType +) + +type MailTextAddedEvent struct { + policy.MailTextAddedEvent +} + +func NewMailTextAddedEvent( + ctx context.Context, + mailTextType, + language, + title, + preHeader, + subject, + greeting, + text, + buttonText string, +) *MailTextAddedEvent { + return &MailTextAddedEvent{ + MailTextAddedEvent: *policy.NewMailTextAddedEvent( + eventstore.NewBaseEventForPushWithResourceOwner(ctx, MailTextAddedEventType, domain.IAMID), + mailTextType, + language, + title, + preHeader, + subject, + greeting, + text, + buttonText), + } +} + +func MailTextAddedEventMapper(event *repository.Event) (eventstore.EventReader, error) { + e, err := policy.MailTextAddedEventMapper(event) + if err != nil { + return nil, err + } + + return &MailTextAddedEvent{MailTextAddedEvent: *e.(*policy.MailTextAddedEvent)}, nil +} + +type MailTextChangedEvent struct { + policy.MailTextChangedEvent +} + +func NewMailTextChangedEvent( + ctx context.Context, + mailTextType, + language string, + changes []policy.MailTextChanges, +) (*MailTextChangedEvent, error) { + changedEvent, err := policy.NewMailTextChangedEvent( + eventstore.NewBaseEventForPush(ctx, MailTextChangedEventType), + mailTextType, + language, + changes, + ) + if err != nil { + return nil, err + } + return &MailTextChangedEvent{MailTextChangedEvent: *changedEvent}, nil +} + +func MailTextChangedEventMapper(event *repository.Event) (eventstore.EventReader, error) { + e, err := policy.MailTextChangedEventMapper(event) + if err != nil { + return nil, err + } + + return &MailTextChangedEvent{MailTextChangedEvent: *e.(*policy.MailTextChangedEvent)}, nil +} diff --git a/internal/v2/repository/org/eventstore.go b/internal/v2/repository/org/eventstore.go index 9659bfb19f..3e0f83cadf 100644 --- a/internal/v2/repository/org/eventstore.go +++ b/internal/v2/repository/org/eventstore.go @@ -43,5 +43,11 @@ func RegisterEventMappers(es *eventstore.Eventstore) { RegisterFilterEventMapper(PasswordComplexityPolicyRemovedEventType, PasswordComplexityPolicyRemovedEventMapper). RegisterFilterEventMapper(PasswordLockoutPolicyAddedEventType, PasswordLockoutPolicyAddedEventMapper). RegisterFilterEventMapper(PasswordLockoutPolicyChangedEventType, PasswordLockoutPolicyChangedEventMapper). - RegisterFilterEventMapper(PasswordLockoutPolicyRemovedEventType, PasswordLockoutPolicyRemovedEventMapper) + RegisterFilterEventMapper(PasswordLockoutPolicyRemovedEventType, PasswordLockoutPolicyRemovedEventMapper). + RegisterFilterEventMapper(MailTemplateAddedEventType, MailTemplateAddedEventMapper). + RegisterFilterEventMapper(MailTemplateChangedEventType, MailTemplateChangedEventMapper). + RegisterFilterEventMapper(MailTemplateRemovedEventType, MailTemplateRemovedEventMapper). + RegisterFilterEventMapper(MailTextAddedEventType, MailTextAddedEventMapper). + RegisterFilterEventMapper(MailTextChangedEventType, MailTextChangedEventMapper). + RegisterFilterEventMapper(MailTextRemovedEventType, MailTextRemovedEventMapper) } diff --git a/internal/v2/repository/org/policy_mail_template.go b/internal/v2/repository/org/policy_mail_template.go new file mode 100644 index 0000000000..06cb5f8d41 --- /dev/null +++ b/internal/v2/repository/org/policy_mail_template.go @@ -0,0 +1,89 @@ +package org + +import ( + "context" + + "github.com/caos/zitadel/internal/eventstore/v2" + "github.com/caos/zitadel/internal/eventstore/v2/repository" + "github.com/caos/zitadel/internal/v2/repository/policy" +) + +var ( + MailTemplateAddedEventType = orgEventTypePrefix + policy.MailTemplatePolicyAddedEventType + MailTemplateChangedEventType = orgEventTypePrefix + policy.MailTemplatePolicyChangedEventType + MailTemplateRemovedEventType = orgEventTypePrefix + policy.MailTemplatePolicyRemovedEventType +) + +type MailTemplateAddedEvent struct { + policy.MailTemplateAddedEvent +} + +func NewMailTemplateAddedEvent( + ctx context.Context, + template []byte, +) *MailTemplateAddedEvent { + return &MailTemplateAddedEvent{ + MailTemplateAddedEvent: *policy.NewMailTemplateAddedEvent( + eventstore.NewBaseEventForPush(ctx, MailTemplateAddedEventType), + template), + } +} + +func MailTemplateAddedEventMapper(event *repository.Event) (eventstore.EventReader, error) { + e, err := policy.MailTemplateAddedEventMapper(event) + if err != nil { + return nil, err + } + + return &MailTemplateAddedEvent{MailTemplateAddedEvent: *e.(*policy.MailTemplateAddedEvent)}, nil +} + +type MailTemplateChangedEvent struct { + policy.MailTemplateChangedEvent +} + +func NewMailTemplateChangedEvent( + ctx context.Context, + changes []policy.MailTemplateChanges, +) (*MailTemplateChangedEvent, error) { + changedEvent, err := policy.NewMailTemplateChangedEvent( + eventstore.NewBaseEventForPush(ctx, MailTemplateChangedEventType), + changes, + ) + if err != nil { + return nil, err + } + return &MailTemplateChangedEvent{MailTemplateChangedEvent: *changedEvent}, nil +} + +func MailTemplateChangedEventMapper(event *repository.Event) (eventstore.EventReader, error) { + e, err := policy.MailTemplateChangedEventMapper(event) + if err != nil { + return nil, err + } + + return &MailTemplateChangedEvent{MailTemplateChangedEvent: *e.(*policy.MailTemplateChangedEvent)}, nil +} + +type MailTemplateRemovedEvent struct { + policy.MailTemplateRemovedEvent +} + +func NewMailTemplateRemovedEvent( + ctx context.Context, +) *MailTemplateRemovedEvent { + return &MailTemplateRemovedEvent{ + MailTemplateRemovedEvent: *policy.NewMailTemplateRemovedEvent( + eventstore.NewBaseEventForPush(ctx, MailTemplateRemovedEventType), + ), + } +} + +func MailTemplateRemovedEventMapper(event *repository.Event) (eventstore.EventReader, error) { + e, err := policy.MailTemplateRemovedEventMapper(event) + if err != nil { + return nil, err + } + + return &MailTemplateRemovedEvent{MailTemplateRemovedEvent: *e.(*policy.MailTemplateRemovedEvent)}, nil +} diff --git a/internal/v2/repository/org/policy_mail_text.go b/internal/v2/repository/org/policy_mail_text.go new file mode 100644 index 0000000000..f917ef9cbb --- /dev/null +++ b/internal/v2/repository/org/policy_mail_text.go @@ -0,0 +1,113 @@ +package org + +import ( + "context" + + "github.com/caos/zitadel/internal/eventstore/v2" + "github.com/caos/zitadel/internal/eventstore/v2/repository" + "github.com/caos/zitadel/internal/v2/repository/policy" +) + +var ( + MailTextAddedEventType = orgEventTypePrefix + policy.MailTextPolicyAddedEventType + MailTextChangedEventType = orgEventTypePrefix + policy.MailTextPolicyChangedEventType + MailTextRemovedEventType = orgEventTypePrefix + policy.MailTextPolicyRemovedEventType +) + +type MailTextAddedEvent struct { + policy.MailTextAddedEvent +} + +func NewMailTextAddedEvent( + ctx context.Context, + resourceOwner, + mailTextType, + language, + title, + preHeader, + subject, + greeting, + text, + buttonText string, +) *MailTextAddedEvent { + return &MailTextAddedEvent{ + MailTextAddedEvent: *policy.NewMailTextAddedEvent( + eventstore.NewBaseEventForPushWithResourceOwner(ctx, MailTextAddedEventType, resourceOwner), + mailTextType, + language, + title, + preHeader, + subject, + greeting, + text, + buttonText), + } +} + +func MailTextAddedEventMapper(event *repository.Event) (eventstore.EventReader, error) { + e, err := policy.MailTextAddedEventMapper(event) + if err != nil { + return nil, err + } + + return &MailTextAddedEvent{MailTextAddedEvent: *e.(*policy.MailTextAddedEvent)}, nil +} + +type MailTextChangedEvent struct { + policy.MailTextChangedEvent +} + +func NewMailTextChangedEvent( + ctx context.Context, + mailTextType, + language string, + changes []policy.MailTextChanges, +) (*MailTextChangedEvent, error) { + changedEvent, err := policy.NewMailTextChangedEvent( + eventstore.NewBaseEventForPush(ctx, MailTextChangedEventType), + mailTextType, + language, + changes, + ) + if err != nil { + return nil, err + } + return &MailTextChangedEvent{MailTextChangedEvent: *changedEvent}, nil +} + +func MailTextChangedEventMapper(event *repository.Event) (eventstore.EventReader, error) { + e, err := policy.MailTextChangedEventMapper(event) + if err != nil { + return nil, err + } + + return &MailTextChangedEvent{MailTextChangedEvent: *e.(*policy.MailTextChangedEvent)}, nil +} + +type MailTextRemovedEvent struct { + policy.MailTextRemovedEvent +} + +func NewMailTextRemovedEvent( + ctx context.Context, + resourceOwner, + mailTextType, + language string, +) *MailTextRemovedEvent { + return &MailTextRemovedEvent{ + MailTextRemovedEvent: *policy.NewMailTextRemovedEvent( + eventstore.NewBaseEventForPushWithResourceOwner(ctx, MailTextRemovedEventType, resourceOwner), + mailTextType, + language, + ), + } +} + +func MailTextRemovedEventMapper(event *repository.Event) (eventstore.EventReader, error) { + e, err := policy.MailTextRemovedEventMapper(event) + if err != nil { + return nil, err + } + + return &MailTextRemovedEvent{MailTextRemovedEvent: *e.(*policy.MailTextRemovedEvent)}, nil +} diff --git a/internal/v2/repository/policy/mail_template.go b/internal/v2/repository/policy/mail_template.go new file mode 100644 index 0000000000..f1a89a6e48 --- /dev/null +++ b/internal/v2/repository/policy/mail_template.go @@ -0,0 +1,128 @@ +package policy + +import ( + "encoding/json" + "github.com/caos/zitadel/internal/errors" + "github.com/caos/zitadel/internal/eventstore/v2" + "github.com/caos/zitadel/internal/eventstore/v2/repository" +) + +const ( + mailPolicyPrefix = "mail." + mailTemplatePolicyPrefix = mailPolicyPrefix + "template." + MailTemplatePolicyAddedEventType = mailTemplatePolicyPrefix + "added" + MailTemplatePolicyChangedEventType = mailTemplatePolicyPrefix + "changed" + MailTemplatePolicyRemovedEventType = mailTemplatePolicyPrefix + "removed" +) + +type MailTemplateAddedEvent struct { + eventstore.BaseEvent `json:"-"` + + Template []byte `json:"template,omitempty"` +} + +func (e *MailTemplateAddedEvent) Data() interface{} { + return e +} + +func (e *MailTemplateAddedEvent) UniqueConstraints() []*eventstore.EventUniqueConstraint { + return nil +} + +func NewMailTemplateAddedEvent( + base *eventstore.BaseEvent, + template []byte, +) *MailTemplateAddedEvent { + return &MailTemplateAddedEvent{ + BaseEvent: *base, + Template: template, + } +} + +func MailTemplateAddedEventMapper(event *repository.Event) (eventstore.EventReader, error) { + e := &MailTemplateAddedEvent{ + BaseEvent: *eventstore.BaseEventFromRepo(event), + } + + err := json.Unmarshal(event.Data, e) + if err != nil { + return nil, errors.ThrowInternal(err, "POLIC-5m9if", "unable to unmarshal mail template") + } + + return e, nil +} + +type MailTemplateChangedEvent struct { + eventstore.BaseEvent `json:"-"` + + Template *[]byte `json:"template,omitempty"` +} + +func (e *MailTemplateChangedEvent) Data() interface{} { + return e +} + +func (e *MailTemplateChangedEvent) UniqueConstraints() []*eventstore.EventUniqueConstraint { + return nil +} + +func NewMailTemplateChangedEvent( + base *eventstore.BaseEvent, + changes []MailTemplateChanges, +) (*MailTemplateChangedEvent, error) { + if len(changes) == 0 { + return nil, errors.ThrowPreconditionFailed(nil, "POLICY-m9osd", "Errors.NoChangesFound") + } + changeEvent := &MailTemplateChangedEvent{ + BaseEvent: *base, + } + for _, change := range changes { + change(changeEvent) + } + return changeEvent, nil +} + +type MailTemplateChanges func(*MailTemplateChangedEvent) + +func ChangeTemplate(template []byte) func(*MailTemplateChangedEvent) { + return func(e *MailTemplateChangedEvent) { + e.Template = &template + } +} + +func MailTemplateChangedEventMapper(event *repository.Event) (eventstore.EventReader, error) { + e := &MailTemplateChangedEvent{ + BaseEvent: *eventstore.BaseEventFromRepo(event), + } + + err := json.Unmarshal(event.Data, e) + if err != nil { + return nil, errors.ThrowInternal(err, "POLIC-3uu8K", "unable to unmarshal mail template policy") + } + + return e, nil +} + +type MailTemplateRemovedEvent struct { + eventstore.BaseEvent `json:"-"` +} + +func (e *MailTemplateRemovedEvent) Data() interface{} { + return nil +} + +func (e *MailTemplateRemovedEvent) UniqueConstraints() []*eventstore.EventUniqueConstraint { + return nil +} + +func NewMailTemplateRemovedEvent(base *eventstore.BaseEvent) *MailTemplateRemovedEvent { + return &MailTemplateRemovedEvent{ + BaseEvent: *base, + } +} + +func MailTemplateRemovedEventMapper(event *repository.Event) (eventstore.EventReader, error) { + return &MailTemplateRemovedEvent{ + BaseEvent: *eventstore.BaseEventFromRepo(event), + }, nil +} diff --git a/internal/v2/repository/policy/mail_text.go b/internal/v2/repository/policy/mail_text.go new file mode 100644 index 0000000000..3f0a17fbb2 --- /dev/null +++ b/internal/v2/repository/policy/mail_text.go @@ -0,0 +1,209 @@ +package policy + +import ( + "encoding/json" + "fmt" + "github.com/caos/zitadel/internal/errors" + "github.com/caos/zitadel/internal/eventstore/v2" + "github.com/caos/zitadel/internal/eventstore/v2/repository" +) + +const ( + uniqueMailText = "mail_text" + mailTextPolicyPrefix = mailPolicyPrefix + "text." + MailTextPolicyAddedEventType = mailTextPolicyPrefix + "added" + MailTextPolicyChangedEventType = mailTextPolicyPrefix + "changed" + MailTextPolicyRemovedEventType = mailTextPolicyPrefix + "removed" +) + +func NewAddMailTextUniqueConstraint(aggregateID, mailTextType, langugage string) *eventstore.EventUniqueConstraint { + return eventstore.NewAddEventUniqueConstraint( + uniqueMailText, + fmt.Sprintf("%v:%v:%v", aggregateID, mailTextType, langugage), + "Errors.Org.AlreadyExists") +} + +func NewRemoveMailTextUniqueConstraint(aggregateID, mailTextType, langugage string) *eventstore.EventUniqueConstraint { + return eventstore.NewRemoveEventUniqueConstraint( + uniqueMailText, + fmt.Sprintf("%v:%v:%v", aggregateID, mailTextType, langugage)) +} + +type MailTextAddedEvent struct { + eventstore.BaseEvent `json:"-"` + + MailTextType string `json:"mailTextType,omitempty"` + Language string `json:"language,omitempty"` + Title string `json:"title,omitempty"` + PreHeader string `json:"preHeader,omitempty"` + Subject string `json:"subject,omitempty"` + Greeting string `json:"greeting,omitempty"` + Text string `json:"text,omitempty"` + ButtonText string `json:"buttonText,omitempty"` +} + +func (e *MailTextAddedEvent) Data() interface{} { + return e +} + +func (e *MailTextAddedEvent) UniqueConstraints() []*eventstore.EventUniqueConstraint { + return []*eventstore.EventUniqueConstraint{NewAddMailTextUniqueConstraint(e.ResourceOwner(), e.MailTextType, e.Language)} +} + +func NewMailTextAddedEvent( + base *eventstore.BaseEvent, + mailTextType, + language, + title, + preHeader, + subject, + greeting, + text, + buttonText string, +) *MailTextAddedEvent { + return &MailTextAddedEvent{ + BaseEvent: *base, + MailTextType: mailTextType, + Language: language, + Title: title, + PreHeader: preHeader, + Subject: subject, + Greeting: greeting, + Text: text, + ButtonText: buttonText, + } +} + +func MailTextAddedEventMapper(event *repository.Event) (eventstore.EventReader, error) { + e := &MailTextAddedEvent{ + BaseEvent: *eventstore.BaseEventFromRepo(event), + } + + err := json.Unmarshal(event.Data, e) + if err != nil { + return nil, errors.ThrowInternal(err, "POLIC-5m9if", "unable to unmarshal mail text policy") + } + + return e, nil +} + +type MailTextChangedEvent struct { + eventstore.BaseEvent `json:"-"` + + MailTextType string `json:"mailTextType,omitempty"` + Language string `json:"language,omitempty"` + Title *string `json:"title,omitempty"` + PreHeader *string `json:"preHeader,omitempty"` + Subject *string `json:"subject,omitempty"` + Greeting *string `json:"greeting,omitempty"` + Text *string `json:"text,omitempty"` + ButtonText *string `json:"buttonText,omitempty"` +} + +func (e *MailTextChangedEvent) Data() interface{} { + return e +} + +func (e *MailTextChangedEvent) UniqueConstraints() []*eventstore.EventUniqueConstraint { + return nil +} + +func NewMailTextChangedEvent( + base *eventstore.BaseEvent, + mailTextType, + language string, + changes []MailTextChanges, +) (*MailTextChangedEvent, error) { + if len(changes) == 0 { + return nil, errors.ThrowPreconditionFailed(nil, "POLICY-m9osd", "Errors.NoChangesFound") + } + changeEvent := &MailTextChangedEvent{ + BaseEvent: *base, + MailTextType: mailTextType, + Language: language, + } + for _, change := range changes { + change(changeEvent) + } + return changeEvent, nil +} + +type MailTextChanges func(*MailTextChangedEvent) + +func ChangeTitle(title string) func(*MailTextChangedEvent) { + return func(e *MailTextChangedEvent) { + e.Title = &title + } +} + +func ChangePreHeader(preHeader string) func(*MailTextChangedEvent) { + return func(e *MailTextChangedEvent) { + e.PreHeader = &preHeader + } +} + +func ChangeSubject(greeting string) func(*MailTextChangedEvent) { + return func(e *MailTextChangedEvent) { + e.Subject = &greeting + } +} + +func ChangeGreeting(greeting string) func(*MailTextChangedEvent) { + return func(e *MailTextChangedEvent) { + e.Greeting = &greeting + } +} + +func ChangeText(text string) func(*MailTextChangedEvent) { + return func(e *MailTextChangedEvent) { + e.Text = &text + } +} + +func ChangeButtonText(buttonText string) func(*MailTextChangedEvent) { + return func(e *MailTextChangedEvent) { + e.ButtonText = &buttonText + } +} + +func MailTextChangedEventMapper(event *repository.Event) (eventstore.EventReader, error) { + e := &MailTextChangedEvent{ + BaseEvent: *eventstore.BaseEventFromRepo(event), + } + + err := json.Unmarshal(event.Data, e) + if err != nil { + return nil, errors.ThrowInternal(err, "POLIC-bn88u", "unable to unmarshal mail text policy") + } + + return e, nil +} + +type MailTextRemovedEvent struct { + eventstore.BaseEvent `json:"-"` + + MailTextType string `json:"mailTextType,omitempty"` + Language string `json:"language,omitempty"` +} + +func (e *MailTextRemovedEvent) Data() interface{} { + return nil +} + +func (e *MailTextRemovedEvent) UniqueConstraints() []*eventstore.EventUniqueConstraint { + return []*eventstore.EventUniqueConstraint{NewRemoveMailTextUniqueConstraint(e.ResourceOwner(), e.MailTextType, e.Language)} +} + +func NewMailTextRemovedEvent(base *eventstore.BaseEvent, mailTextType, language string) *MailTextRemovedEvent { + return &MailTextRemovedEvent{ + BaseEvent: *base, + MailTextType: mailTextType, + Language: language, + } +} + +func MailTextRemovedEventMapper(event *repository.Event) (eventstore.EventReader, error) { + return &MailTextRemovedEvent{ + BaseEvent: *eventstore.BaseEventFromRepo(event), + }, nil +}