mirror of
https://github.com/zitadel/zitadel.git
synced 2025-02-28 21:17:23 +00:00
feat: text query (#2735)
* feat: change mail template to new query side * feat: adminapi message text * feat: adminapi message text * feat: adminapi message text * feat: message texts * feat: admin texts * feat: tests * feat: tests * feat: custom login text on adminapi * feat: custom login text * feat: custom login text * feat: message text prepare test * feat: login text texts * feat: custom login text * merge main * fix go.sum Co-authored-by: Livio Amstutz <livio.a@gmail.com>
This commit is contained in:
parent
a43e1fc34a
commit
c5d6325897
@ -193,7 +193,7 @@ func startZitadel(configPaths []string) {
|
|||||||
startUI(ctx, conf, authRepo, commands, queries, store)
|
startUI(ctx, conf, authRepo, commands, queries, store)
|
||||||
|
|
||||||
if *notificationEnabled {
|
if *notificationEnabled {
|
||||||
notification.Start(ctx, conf.Notification, conf.SystemDefaults, commands, store != nil)
|
notification.Start(ctx, conf.Notification, conf.SystemDefaults, commands, queries, store != nil)
|
||||||
}
|
}
|
||||||
|
|
||||||
<-ctx.Done()
|
<-ctx.Done()
|
||||||
|
144
go.mod
144
go.mod
@ -1,15 +1,12 @@
|
|||||||
module github.com/caos/zitadel
|
module github.com/caos/zitadel
|
||||||
|
|
||||||
go 1.16
|
go 1.17
|
||||||
|
|
||||||
require (
|
require (
|
||||||
cloud.google.com/go/storage v1.18.2
|
cloud.google.com/go/storage v1.18.2
|
||||||
cloud.google.com/go/trace v1.0.0 // indirect
|
|
||||||
github.com/BurntSushi/toml v0.4.1
|
github.com/BurntSushi/toml v0.4.1
|
||||||
github.com/DATA-DOG/go-sqlmock v1.5.0
|
github.com/DATA-DOG/go-sqlmock v1.5.0
|
||||||
github.com/GoogleCloudPlatform/opentelemetry-operations-go/exporter/trace v1.0.0
|
github.com/GoogleCloudPlatform/opentelemetry-operations-go/exporter/trace v1.0.0
|
||||||
github.com/Masterminds/goutils v1.1.1 // indirect
|
|
||||||
github.com/Masterminds/semver v1.5.0 // indirect
|
|
||||||
github.com/Masterminds/sprig v2.22.0+incompatible
|
github.com/Masterminds/sprig v2.22.0+incompatible
|
||||||
github.com/Masterminds/squirrel v1.5.2
|
github.com/Masterminds/squirrel v1.5.2
|
||||||
github.com/VictoriaMetrics/fastcache v1.8.0
|
github.com/VictoriaMetrics/fastcache v1.8.0
|
||||||
@ -39,18 +36,12 @@ require (
|
|||||||
github.com/grpc-ecosystem/go-grpc-middleware v1.3.0
|
github.com/grpc-ecosystem/go-grpc-middleware v1.3.0
|
||||||
github.com/grpc-ecosystem/grpc-gateway v1.16.0
|
github.com/grpc-ecosystem/grpc-gateway v1.16.0
|
||||||
github.com/grpc-ecosystem/grpc-gateway/v2 v2.7.1
|
github.com/grpc-ecosystem/grpc-gateway/v2 v2.7.1
|
||||||
github.com/huandu/xstrings v1.3.2 // indirect
|
|
||||||
github.com/jinzhu/gorm v1.9.16
|
github.com/jinzhu/gorm v1.9.16
|
||||||
github.com/kevinburke/go-types v0.0.0-20210723172823-2deba1f80ba7 // indirect
|
|
||||||
github.com/kevinburke/rest v0.0.0-20210506044642-5611499aa33c // indirect
|
|
||||||
github.com/kevinburke/twilio-go v0.0.0-20210327194925-1623146bcf73
|
github.com/kevinburke/twilio-go v0.0.0-20210327194925-1623146bcf73
|
||||||
github.com/lib/pq v1.10.4
|
github.com/lib/pq v1.10.4
|
||||||
github.com/lucasb-eyer/go-colorful v1.2.0
|
github.com/lucasb-eyer/go-colorful v1.2.0
|
||||||
github.com/manifoldco/promptui v0.9.0
|
github.com/manifoldco/promptui v0.9.0
|
||||||
github.com/mattn/go-colorable v0.1.12 // indirect; indirect github.com/mitchellh/copystructure v1.0.0 // indirect
|
|
||||||
github.com/mattn/go-sqlite3 v2.0.3+incompatible // indirect
|
|
||||||
github.com/minio/minio-go/v7 v7.0.16
|
github.com/minio/minio-go/v7 v7.0.16
|
||||||
github.com/mitchellh/copystructure v1.2.0 // indirect
|
|
||||||
github.com/muesli/gamut v0.2.0
|
github.com/muesli/gamut v0.2.0
|
||||||
github.com/nicksnyder/go-i18n/v2 v2.1.2
|
github.com/nicksnyder/go-i18n/v2 v2.1.2
|
||||||
github.com/nsf/jsondiff v0.0.0-20210926074059-1e845ec5d249
|
github.com/nsf/jsondiff v0.0.0-20210926074059-1e845ec5d249
|
||||||
@ -61,7 +52,6 @@ require (
|
|||||||
github.com/sony/sonyflake v1.0.0
|
github.com/sony/sonyflake v1.0.0
|
||||||
github.com/spf13/cobra v1.2.1
|
github.com/spf13/cobra v1.2.1
|
||||||
github.com/stretchr/testify v1.7.0
|
github.com/stretchr/testify v1.7.0
|
||||||
github.com/ttacon/builder v0.0.0-20170518171403-c099f663e1c2 // indirect
|
|
||||||
github.com/ttacon/libphonenumber v1.2.1
|
github.com/ttacon/libphonenumber v1.2.1
|
||||||
go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.27.0
|
go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.27.0
|
||||||
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.27.0
|
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.27.0
|
||||||
@ -77,7 +67,6 @@ require (
|
|||||||
golang.org/x/crypto v0.0.0-20211117183948-ae814b36b871
|
golang.org/x/crypto v0.0.0-20211117183948-ae814b36b871
|
||||||
golang.org/x/oauth2 v0.0.0-20211104180415-d3ed0bb246c8
|
golang.org/x/oauth2 v0.0.0-20211104180415-d3ed0bb246c8
|
||||||
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c
|
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c
|
||||||
golang.org/x/sys v0.0.0-20211205182925-97ca703d548d // indirect
|
|
||||||
golang.org/x/text v0.3.7
|
golang.org/x/text v0.3.7
|
||||||
golang.org/x/tools v0.1.8
|
golang.org/x/tools v0.1.8
|
||||||
google.golang.org/api v0.61.0
|
google.golang.org/api v0.61.0
|
||||||
@ -95,4 +84,135 @@ require (
|
|||||||
sigs.k8s.io/yaml v1.3.0
|
sigs.k8s.io/yaml v1.3.0
|
||||||
)
|
)
|
||||||
|
|
||||||
|
require (
|
||||||
|
cloud.google.com/go v0.97.0 // indirect
|
||||||
|
cloud.google.com/go/trace v1.0.0 // indirect
|
||||||
|
github.com/AlecAivazis/survey/v2 v2.3.2 // indirect
|
||||||
|
github.com/AppsFlyer/go-sundheit v0.2.0 // indirect
|
||||||
|
github.com/Masterminds/goutils v1.1.1 // indirect
|
||||||
|
github.com/Masterminds/semver v1.5.0 // indirect
|
||||||
|
github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.0.0 // indirect
|
||||||
|
github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.8.2 // indirect
|
||||||
|
github.com/aws/aws-sdk-go-v2/internal/configsources v1.1.2 // indirect
|
||||||
|
github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.0.2 // indirect
|
||||||
|
github.com/aws/aws-sdk-go-v2/internal/ini v1.3.2 // indirect
|
||||||
|
github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.5.0 // indirect
|
||||||
|
github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.5.2 // indirect
|
||||||
|
github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.9.2 // indirect
|
||||||
|
github.com/aws/aws-sdk-go-v2/service/sso v1.6.2 // indirect
|
||||||
|
github.com/aws/aws-sdk-go-v2/service/sts v1.11.1 // indirect
|
||||||
|
github.com/aws/smithy-go v1.9.0 // indirect
|
||||||
|
github.com/beorn7/perks v1.0.1 // indirect
|
||||||
|
github.com/cenkalti/backoff/v4 v4.1.1 // indirect
|
||||||
|
github.com/census-instrumentation/opencensus-proto v0.2.1 // indirect
|
||||||
|
github.com/cespare/xxhash/v2 v2.1.2 // indirect
|
||||||
|
github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e // indirect
|
||||||
|
github.com/cloudflare/cfssl v0.0.0-20190726000631-633726f6bcb7 // indirect
|
||||||
|
github.com/cloudflare/cloudflare-go v0.23.0 // indirect
|
||||||
|
github.com/cloudscale-ch/cloudscale-go-sdk v1.7.1 // indirect
|
||||||
|
github.com/cncf/udpa/go v0.0.0-20210930031921-04548b0d99d4 // indirect
|
||||||
|
github.com/cncf/xds/go v0.0.0-20211011173535-cb28da3451f1 // indirect
|
||||||
|
github.com/davecgh/go-spew v1.1.1 // indirect
|
||||||
|
github.com/dgrijalva/jwt-go v3.2.0+incompatible // indirect
|
||||||
|
github.com/dlclark/regexp2 v1.4.1-0.20201116162257-a2a8dda75c91 // indirect
|
||||||
|
github.com/dustin/go-humanize v1.0.0 // indirect
|
||||||
|
github.com/emirpasic/gods v1.12.0 // indirect
|
||||||
|
github.com/envoyproxy/go-control-plane v0.9.10-0.20210907150352-cf90f659a021 // indirect
|
||||||
|
github.com/evanphx/json-patch v4.11.0+incompatible // indirect
|
||||||
|
github.com/felixge/httpsnoop v1.0.2 // indirect
|
||||||
|
github.com/fsnotify/fsnotify v1.4.9 // indirect
|
||||||
|
github.com/fxamacker/cbor/v2 v2.2.0 // indirect
|
||||||
|
github.com/ghodss/yaml v1.0.0 // indirect
|
||||||
|
github.com/go-git/gcfg v1.5.0 // indirect
|
||||||
|
github.com/go-git/go-billy/v5 v5.0.0 // indirect
|
||||||
|
github.com/go-git/go-git/v5 v5.2.0 // indirect
|
||||||
|
github.com/go-logr/logr v0.4.0 // indirect
|
||||||
|
github.com/go-sourcemap/sourcemap v2.1.3+incompatible // indirect
|
||||||
|
github.com/gobuffalo/flect v0.2.3 // indirect
|
||||||
|
github.com/gofrs/flock v0.8.1 // indirect
|
||||||
|
github.com/gofrs/uuid v3.2.0+incompatible // indirect
|
||||||
|
github.com/gogo/protobuf v1.3.2 // indirect
|
||||||
|
github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0 // indirect
|
||||||
|
github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect
|
||||||
|
github.com/golang/snappy v0.0.4 // indirect
|
||||||
|
github.com/google/certificate-transparency-go v1.0.21 // indirect
|
||||||
|
github.com/google/go-cmp v0.5.6 // indirect
|
||||||
|
github.com/google/go-github/v31 v31.0.0 // indirect
|
||||||
|
github.com/google/go-querystring v1.0.0 // indirect
|
||||||
|
github.com/google/gofuzz v1.1.0 // indirect
|
||||||
|
github.com/google/uuid v1.3.0 // indirect
|
||||||
|
github.com/googleapis/gax-go/v2 v2.1.1 // indirect
|
||||||
|
github.com/googleapis/gnostic v0.5.5 // indirect
|
||||||
|
github.com/gorilla/handlers v1.5.1 // indirect
|
||||||
|
github.com/huandu/xstrings v1.3.2 // indirect
|
||||||
|
github.com/imdario/mergo v0.3.12 // indirect
|
||||||
|
github.com/inconshreveable/mousetrap v1.0.0 // indirect
|
||||||
|
github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99 // indirect
|
||||||
|
github.com/jinzhu/inflection v1.0.0 // indirect
|
||||||
|
github.com/json-iterator/go v1.1.11 // indirect
|
||||||
|
github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51 // indirect
|
||||||
|
github.com/kevinburke/go-types v0.0.0-20210723172823-2deba1f80ba7 // indirect
|
||||||
|
github.com/kevinburke/rest v0.0.0-20210506044642-5611499aa33c // indirect
|
||||||
|
github.com/kevinburke/ssh_config v0.0.0-20190725054713-01f96b0aa0cd // indirect
|
||||||
|
github.com/klauspost/compress v1.13.5 // indirect
|
||||||
|
github.com/klauspost/cpuid v1.3.1 // indirect
|
||||||
|
github.com/lann/builder v0.0.0-20180802200727-47ae307949d0 // indirect
|
||||||
|
github.com/lann/ps v0.0.0-20150810152359-62de8c46ede0 // indirect
|
||||||
|
github.com/mattn/go-colorable v0.1.12 // indirect
|
||||||
|
github.com/mattn/go-isatty v0.0.14 // indirect
|
||||||
|
github.com/mattn/go-sqlite3 v2.0.3+incompatible // indirect
|
||||||
|
github.com/matttproud/golang_protobuf_extensions v1.0.2-0.20181231171920-c182affec369 // indirect
|
||||||
|
github.com/mgutz/ansi v0.0.0-20170206155736-9520e82c474b // indirect
|
||||||
|
github.com/minio/md5-simd v1.1.0 // indirect
|
||||||
|
github.com/minio/sha256-simd v0.1.1 // indirect
|
||||||
|
github.com/mitchellh/copystructure v1.2.0 // indirect
|
||||||
|
github.com/mitchellh/go-homedir v1.1.0 // indirect
|
||||||
|
github.com/mitchellh/mapstructure v1.4.1 // indirect
|
||||||
|
github.com/mitchellh/reflectwalk v1.0.2 // indirect
|
||||||
|
github.com/moby/spdystream v0.2.0 // indirect
|
||||||
|
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
|
||||||
|
github.com/modern-go/reflect2 v1.0.1 // indirect
|
||||||
|
github.com/muesli/clusters v0.0.0-20200529215643-2700303c1762 // indirect
|
||||||
|
github.com/muesli/kmeans v0.2.1 // indirect
|
||||||
|
github.com/pires/go-proxyproto v0.6.1 // indirect
|
||||||
|
github.com/pmezard/go-difflib v1.0.0 // indirect
|
||||||
|
github.com/prometheus/client_golang v1.11.0 // indirect
|
||||||
|
github.com/prometheus/client_model v0.2.0 // indirect
|
||||||
|
github.com/prometheus/common v0.26.0 // indirect
|
||||||
|
github.com/prometheus/procfs v0.6.0 // indirect
|
||||||
|
github.com/rs/xid v1.2.1 // indirect
|
||||||
|
github.com/satori/go.uuid v1.2.0 // indirect
|
||||||
|
github.com/sergi/go-diff v1.1.0 // indirect
|
||||||
|
github.com/sirupsen/logrus v1.8.1 // indirect
|
||||||
|
github.com/spf13/pflag v1.0.5 // indirect
|
||||||
|
github.com/ttacon/builder v0.0.0-20170518171403-c099f663e1c2 // indirect
|
||||||
|
github.com/wcharczuk/go-chart/v2 v2.1.0 // indirect
|
||||||
|
github.com/x448/float16 v0.8.4 // indirect
|
||||||
|
github.com/xanzy/ssh-agent v0.2.1 // indirect
|
||||||
|
github.com/xrash/smetrics v0.0.0-20200730060457-89a2a8a1fb0b // indirect
|
||||||
|
go.opencensus.io v0.23.0 // indirect
|
||||||
|
go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.2.0 // indirect
|
||||||
|
go.opentelemetry.io/otel/internal/metric v0.25.0 // indirect
|
||||||
|
go.opentelemetry.io/proto/otlp v0.10.0 // indirect
|
||||||
|
golang.org/x/image v0.0.0-20200927104501-e162460cd6b5 // indirect
|
||||||
|
golang.org/x/mod v0.5.1 // indirect
|
||||||
|
golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2 // indirect
|
||||||
|
golang.org/x/sys v0.0.0-20211205182925-97ca703d548d // indirect
|
||||||
|
golang.org/x/term v0.0.0-20210503060354-a79de5458b56 // indirect
|
||||||
|
golang.org/x/time v0.0.0-20210723032227-1f47c861a9ac // indirect
|
||||||
|
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 // indirect
|
||||||
|
gomodules.xyz/jsonpatch/v2 v2.2.0 // indirect
|
||||||
|
google.golang.org/appengine v1.6.7 // indirect
|
||||||
|
gopkg.in/inf.v0 v0.9.1 // indirect
|
||||||
|
gopkg.in/ini.v1 v1.62.0 // indirect
|
||||||
|
gopkg.in/warnings.v0 v0.1.2 // indirect
|
||||||
|
gopkg.in/yaml.v2 v2.4.0 // indirect
|
||||||
|
k8s.io/component-base v0.22.2 // indirect
|
||||||
|
k8s.io/klog/v2 v2.9.0 // indirect
|
||||||
|
k8s.io/kube-openapi v0.0.0-20211109043538-20434351676c // indirect
|
||||||
|
k8s.io/utils v0.0.0-20210819203725-bdf08cb9a70a // indirect
|
||||||
|
sigs.k8s.io/controller-tools v0.7.0 // indirect
|
||||||
|
sigs.k8s.io/structured-merge-diff/v4 v4.1.2 // indirect
|
||||||
|
)
|
||||||
|
|
||||||
replace github.com/gin-gonic/gin => github.com/gin-gonic/gin v1.7.4
|
replace github.com/gin-gonic/gin => github.com/gin-gonic/gin v1.7.4
|
||||||
|
@ -2,34 +2,26 @@ package eventstore
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"fmt"
|
|
||||||
"io/ioutil"
|
|
||||||
"net/http"
|
"net/http"
|
||||||
"os"
|
|
||||||
"strings"
|
"strings"
|
||||||
"sync"
|
"sync"
|
||||||
|
|
||||||
|
"github.com/caos/logging"
|
||||||
"golang.org/x/text/language"
|
"golang.org/x/text/language"
|
||||||
"sigs.k8s.io/yaml"
|
|
||||||
|
|
||||||
|
admin_view "github.com/caos/zitadel/internal/admin/repository/eventsourcing/view"
|
||||||
|
"github.com/caos/zitadel/internal/config/systemdefaults"
|
||||||
"github.com/caos/zitadel/internal/domain"
|
"github.com/caos/zitadel/internal/domain"
|
||||||
v1 "github.com/caos/zitadel/internal/eventstore/v1"
|
v1 "github.com/caos/zitadel/internal/eventstore/v1"
|
||||||
"github.com/caos/zitadel/internal/eventstore/v1/models"
|
"github.com/caos/zitadel/internal/eventstore/v1/models"
|
||||||
"github.com/caos/zitadel/internal/i18n"
|
"github.com/caos/zitadel/internal/i18n"
|
||||||
iam_view "github.com/caos/zitadel/internal/iam/repository/view"
|
|
||||||
"github.com/caos/zitadel/internal/query"
|
|
||||||
"github.com/caos/zitadel/internal/user/repository/view/model"
|
|
||||||
|
|
||||||
caos_errs "github.com/caos/zitadel/internal/errors"
|
|
||||||
|
|
||||||
"github.com/caos/logging"
|
|
||||||
|
|
||||||
admin_view "github.com/caos/zitadel/internal/admin/repository/eventsourcing/view"
|
|
||||||
"github.com/caos/zitadel/internal/config/systemdefaults"
|
|
||||||
iam_model "github.com/caos/zitadel/internal/iam/model"
|
iam_model "github.com/caos/zitadel/internal/iam/model"
|
||||||
|
iam_view "github.com/caos/zitadel/internal/iam/repository/view"
|
||||||
iam_es_model "github.com/caos/zitadel/internal/iam/repository/view/model"
|
iam_es_model "github.com/caos/zitadel/internal/iam/repository/view/model"
|
||||||
|
"github.com/caos/zitadel/internal/query"
|
||||||
"github.com/caos/zitadel/internal/telemetry/tracing"
|
"github.com/caos/zitadel/internal/telemetry/tracing"
|
||||||
usr_model "github.com/caos/zitadel/internal/user/model"
|
usr_model "github.com/caos/zitadel/internal/user/model"
|
||||||
|
"github.com/caos/zitadel/internal/user/repository/view/model"
|
||||||
)
|
)
|
||||||
|
|
||||||
type IAMRepository struct {
|
type IAMRepository struct {
|
||||||
@ -167,14 +159,6 @@ func (repo *IAMRepository) SearchDefaultIDPProviders(ctx context.Context, reques
|
|||||||
return result, nil
|
return result, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (repo *IAMRepository) GetDefaultMailTemplate(ctx context.Context) (*iam_model.MailTemplateView, error) {
|
|
||||||
template, err := repo.View.MailTemplateByAggregateID(repo.SystemDefaults.IamID)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
return iam_es_model.MailTemplateViewToModel(template), err
|
|
||||||
}
|
|
||||||
|
|
||||||
func (repo *IAMRepository) SearchIAMMembersx(ctx context.Context, request *iam_model.IAMMemberSearchRequest) (*iam_model.IAMMemberSearchResponse, error) {
|
func (repo *IAMRepository) SearchIAMMembersx(ctx context.Context, request *iam_model.IAMMemberSearchRequest) (*iam_model.IAMMemberSearchResponse, error) {
|
||||||
err := request.EnsureLimit(repo.SearchLimit)
|
err := request.EnsureLimit(repo.SearchLimit)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -198,68 +182,6 @@ func (repo *IAMRepository) SearchIAMMembersx(ctx context.Context, request *iam_m
|
|||||||
return result, nil
|
return result, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (repo *IAMRepository) GetDefaultMessageText(ctx context.Context, textType, lang string) (*domain.CustomMessageText, error) {
|
|
||||||
repo.mutex.Lock()
|
|
||||||
defer repo.mutex.Unlock()
|
|
||||||
var err error
|
|
||||||
contents, ok := repo.NotificationTranslationFileContents[lang]
|
|
||||||
if !ok {
|
|
||||||
contents, err = repo.readTranslationFile(repo.NotificationDir, fmt.Sprintf("/i18n/%s.yaml", lang))
|
|
||||||
if caos_errs.IsNotFound(err) {
|
|
||||||
contents, err = repo.readTranslationFile(repo.NotificationDir, fmt.Sprintf("/i18n/%s.yaml", repo.SystemDefaults.DefaultLanguage.String()))
|
|
||||||
}
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
repo.NotificationTranslationFileContents[lang] = contents
|
|
||||||
}
|
|
||||||
messageTexts := new(domain.MessageTexts)
|
|
||||||
if err := yaml.Unmarshal(contents, messageTexts); err != nil {
|
|
||||||
return nil, caos_errs.ThrowInternal(err, "TEXT-3N9fs", "Errors.TranslationFile.ReadError")
|
|
||||||
}
|
|
||||||
return messageTexts.GetMessageTextByType(textType), nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (repo *IAMRepository) GetCustomMessageText(ctx context.Context, textType, lang string) (*domain.CustomMessageText, error) {
|
|
||||||
texts, err := repo.View.CustomTextsByAggregateIDAndTemplateAndLand(repo.SystemDefaults.IamID, textType, lang)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
result := iam_es_model.CustomTextViewsToMessageDomain(repo.SystemDefaults.IamID, lang, texts)
|
|
||||||
result.Default = true
|
|
||||||
return result, err
|
|
||||||
}
|
|
||||||
|
|
||||||
func (repo *IAMRepository) GetDefaultLoginTexts(ctx context.Context, lang string) (*domain.CustomLoginText, error) {
|
|
||||||
repo.mutex.Lock()
|
|
||||||
defer repo.mutex.Unlock()
|
|
||||||
contents, ok := repo.LoginTranslationFileContents[lang]
|
|
||||||
var err error
|
|
||||||
if !ok {
|
|
||||||
contents, err = repo.readTranslationFile(repo.LoginDir, fmt.Sprintf("/i18n/%s.yaml", lang))
|
|
||||||
if caos_errs.IsNotFound(err) {
|
|
||||||
contents, err = repo.readTranslationFile(repo.LoginDir, fmt.Sprintf("/i18n/%s.yaml", repo.SystemDefaults.DefaultLanguage.String()))
|
|
||||||
}
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
repo.LoginTranslationFileContents[lang] = contents
|
|
||||||
}
|
|
||||||
loginText := new(domain.CustomLoginText)
|
|
||||||
if err := yaml.Unmarshal(contents, loginText); err != nil {
|
|
||||||
return nil, caos_errs.ThrowInternal(err, "TEXT-GHR3Q", "Errors.TranslationFile.ReadError")
|
|
||||||
}
|
|
||||||
return loginText, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (repo *IAMRepository) GetCustomLoginTexts(ctx context.Context, lang string) (*domain.CustomLoginText, error) {
|
|
||||||
texts, err := repo.View.CustomTextsByAggregateIDAndTemplateAndLand(repo.SystemDefaults.IamID, domain.LoginCustomText, lang)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
return iam_es_model.CustomTextViewsToLoginDomain(repo.SystemDefaults.IamID, lang, texts), err
|
|
||||||
}
|
|
||||||
|
|
||||||
func (repo *IAMRepository) getIAMEvents(ctx context.Context, sequence uint64) ([]*models.Event, error) {
|
func (repo *IAMRepository) getIAMEvents(ctx context.Context, sequence uint64) ([]*models.Event, error) {
|
||||||
query, err := iam_view.IAMByIDQuery(domain.IAMID, sequence)
|
query, err := iam_view.IAMByIDQuery(domain.IAMID, sequence)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -267,18 +189,3 @@ func (repo *IAMRepository) getIAMEvents(ctx context.Context, sequence uint64) ([
|
|||||||
}
|
}
|
||||||
return repo.Eventstore.FilterEvents(ctx, query)
|
return repo.Eventstore.FilterEvents(ctx, query)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (repo *IAMRepository) readTranslationFile(dir http.FileSystem, filename string) ([]byte, error) {
|
|
||||||
r, err := dir.Open(filename)
|
|
||||||
if os.IsNotExist(err) {
|
|
||||||
return nil, caos_errs.ThrowNotFound(err, "TEXT-3n9fs", "Errors.TranslationFile.NotFound")
|
|
||||||
}
|
|
||||||
if err != nil {
|
|
||||||
return nil, caos_errs.ThrowInternal(err, "TEXT-93njw", "Errors.TranslationFile.ReadError")
|
|
||||||
}
|
|
||||||
contents, err := ioutil.ReadAll(r)
|
|
||||||
if err != nil {
|
|
||||||
return nil, caos_errs.ThrowInternal(err, "TEXT-l0fse", "Errors.TranslationFile.ReadError")
|
|
||||||
}
|
|
||||||
return contents, nil
|
|
||||||
}
|
|
||||||
|
@ -1,133 +0,0 @@
|
|||||||
package handler
|
|
||||||
|
|
||||||
import (
|
|
||||||
"github.com/caos/logging"
|
|
||||||
|
|
||||||
caos_errs "github.com/caos/zitadel/internal/errors"
|
|
||||||
"github.com/caos/zitadel/internal/eventstore/v1"
|
|
||||||
es_models "github.com/caos/zitadel/internal/eventstore/v1/models"
|
|
||||||
"github.com/caos/zitadel/internal/eventstore/v1/query"
|
|
||||||
"github.com/caos/zitadel/internal/eventstore/v1/spooler"
|
|
||||||
iam_es_model "github.com/caos/zitadel/internal/iam/repository/eventsourcing/model"
|
|
||||||
iam_model "github.com/caos/zitadel/internal/iam/repository/view/model"
|
|
||||||
"github.com/caos/zitadel/internal/org/repository/eventsourcing/model"
|
|
||||||
)
|
|
||||||
|
|
||||||
type CustomText struct {
|
|
||||||
handler
|
|
||||||
subscription *v1.Subscription
|
|
||||||
}
|
|
||||||
|
|
||||||
func newCustomText(handler handler) *CustomText {
|
|
||||||
h := &CustomText{
|
|
||||||
handler: handler,
|
|
||||||
}
|
|
||||||
|
|
||||||
h.subscribe()
|
|
||||||
|
|
||||||
return h
|
|
||||||
}
|
|
||||||
|
|
||||||
func (m *CustomText) subscribe() {
|
|
||||||
m.subscription = m.es.Subscribe(m.AggregateTypes()...)
|
|
||||||
go func() {
|
|
||||||
for event := range m.subscription.Events {
|
|
||||||
query.ReduceEvent(m, event)
|
|
||||||
}
|
|
||||||
}()
|
|
||||||
}
|
|
||||||
|
|
||||||
const (
|
|
||||||
customTextTable = "adminapi.custom_texts"
|
|
||||||
)
|
|
||||||
|
|
||||||
func (m *CustomText) Subscription() *v1.Subscription {
|
|
||||||
return m.subscription
|
|
||||||
}
|
|
||||||
|
|
||||||
func (m *CustomText) ViewModel() string {
|
|
||||||
return customTextTable
|
|
||||||
}
|
|
||||||
|
|
||||||
func (_ *CustomText) AggregateTypes() []es_models.AggregateType {
|
|
||||||
return []es_models.AggregateType{model.OrgAggregate, iam_es_model.IAMAggregate}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (p *CustomText) CurrentSequence() (uint64, error) {
|
|
||||||
sequence, err := p.view.GetLatestCustomTextSequence()
|
|
||||||
if err != nil {
|
|
||||||
return 0, err
|
|
||||||
}
|
|
||||||
return sequence.CurrentSequence, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (m *CustomText) EventQuery() (*es_models.SearchQuery, error) {
|
|
||||||
sequence, err := m.view.GetLatestCustomTextSequence()
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
return es_models.NewSearchQuery().
|
|
||||||
AggregateTypeFilter(m.AggregateTypes()...).
|
|
||||||
LatestSequenceFilter(sequence.CurrentSequence), nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (m *CustomText) Reduce(event *es_models.Event) (err error) {
|
|
||||||
switch event.AggregateType {
|
|
||||||
case model.OrgAggregate, iam_es_model.IAMAggregate:
|
|
||||||
err = m.processCustomText(event)
|
|
||||||
}
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
func (m *CustomText) processCustomText(event *es_models.Event) (err error) {
|
|
||||||
customText := new(iam_model.CustomTextView)
|
|
||||||
switch event.Type {
|
|
||||||
case iam_es_model.CustomTextSet, model.CustomTextSet:
|
|
||||||
text := new(iam_model.CustomTextView)
|
|
||||||
err = text.SetData(event)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
customText, err = m.view.CustomTextByIDs(event.AggregateID, text.Template, text.Key, text.Language)
|
|
||||||
if err != nil && !caos_errs.IsNotFound(err) {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
if caos_errs.IsNotFound(err) {
|
|
||||||
err = nil
|
|
||||||
customText = new(iam_model.CustomTextView)
|
|
||||||
customText.Language = text.Language
|
|
||||||
customText.Template = text.Template
|
|
||||||
customText.CreationDate = event.CreationDate
|
|
||||||
}
|
|
||||||
err = customText.AppendEvent(event)
|
|
||||||
case iam_es_model.CustomTextRemoved, model.CustomTextRemoved:
|
|
||||||
text := new(iam_model.CustomTextView)
|
|
||||||
err = text.SetData(event)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
return m.view.DeleteCustomText(event.AggregateID, text.Template, text.Language, text.Key, event)
|
|
||||||
case iam_es_model.CustomTextMessageRemoved, model.CustomTextMessageRemoved:
|
|
||||||
text := new(iam_model.CustomTextView)
|
|
||||||
err = text.SetData(event)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
return m.view.DeleteCustomTextTemplate(event.AggregateID, text.Template, text.Language, event)
|
|
||||||
default:
|
|
||||||
return m.view.ProcessedCustomTextSequence(event)
|
|
||||||
}
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
return m.view.PutCustomText(customText, event)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (m *CustomText) OnError(event *es_models.Event, err error) error {
|
|
||||||
logging.LogWithFields("SPOOL-3m912", "id", event.AggregateID).WithError(err).Warn("something went wrong in custom text handler")
|
|
||||||
return spooler.HandleError(event, err, m.view.GetLatestCustomTextFailedEvent, m.view.ProcessedCustomTextFailedEvent, m.view.ProcessedCustomTextSequence, m.errorCountUntilSkip)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (o *CustomText) OnSuccess() error {
|
|
||||||
return spooler.HandleSuccess(o.view.UpdateCustomTextSpoolerRunTimestamp)
|
|
||||||
}
|
|
@ -46,12 +46,6 @@ func Register(configs Configs, bulkLimit, errorCount uint64, view *view.View, es
|
|||||||
newExternalIDP(
|
newExternalIDP(
|
||||||
handler{view, bulkLimit, configs.cycleDuration("ExternalIDP"), errorCount, es},
|
handler{view, bulkLimit, configs.cycleDuration("ExternalIDP"), errorCount, es},
|
||||||
defaults),
|
defaults),
|
||||||
newMailTemplate(
|
|
||||||
handler{view, bulkLimit, configs.cycleDuration("MailTemplate"), errorCount, es}),
|
|
||||||
newMessageText(
|
|
||||||
handler{view, bulkLimit, configs.cycleDuration("MessageText"), errorCount, es}),
|
|
||||||
newCustomText(
|
|
||||||
handler{view, bulkLimit, configs.cycleDuration("CustomTexts"), errorCount, es}),
|
|
||||||
}
|
}
|
||||||
if static != nil {
|
if static != nil {
|
||||||
handlers = append(handlers, newStyling(
|
handlers = append(handlers, newStyling(
|
||||||
|
@ -1,108 +0,0 @@
|
|||||||
package handler
|
|
||||||
|
|
||||||
import (
|
|
||||||
"github.com/caos/logging"
|
|
||||||
"github.com/caos/zitadel/internal/eventstore/v1"
|
|
||||||
|
|
||||||
es_models "github.com/caos/zitadel/internal/eventstore/v1/models"
|
|
||||||
"github.com/caos/zitadel/internal/eventstore/v1/query"
|
|
||||||
"github.com/caos/zitadel/internal/eventstore/v1/spooler"
|
|
||||||
"github.com/caos/zitadel/internal/iam/repository/eventsourcing/model"
|
|
||||||
iam_es_model "github.com/caos/zitadel/internal/iam/repository/eventsourcing/model"
|
|
||||||
iam_model "github.com/caos/zitadel/internal/iam/repository/view/model"
|
|
||||||
)
|
|
||||||
|
|
||||||
type MailTemplate struct {
|
|
||||||
handler
|
|
||||||
subscription *v1.Subscription
|
|
||||||
}
|
|
||||||
|
|
||||||
func newMailTemplate(handler handler) *MailTemplate {
|
|
||||||
h := &MailTemplate{
|
|
||||||
handler: handler,
|
|
||||||
}
|
|
||||||
|
|
||||||
h.subscribe()
|
|
||||||
|
|
||||||
return h
|
|
||||||
}
|
|
||||||
|
|
||||||
func (m *MailTemplate) subscribe() {
|
|
||||||
m.subscription = m.es.Subscribe(m.AggregateTypes()...)
|
|
||||||
go func() {
|
|
||||||
for event := range m.subscription.Events {
|
|
||||||
query.ReduceEvent(m, event)
|
|
||||||
}
|
|
||||||
}()
|
|
||||||
}
|
|
||||||
|
|
||||||
const (
|
|
||||||
mailTemplateTable = "adminapi.mail_templates"
|
|
||||||
)
|
|
||||||
|
|
||||||
func (m *MailTemplate) ViewModel() string {
|
|
||||||
return mailTemplateTable
|
|
||||||
}
|
|
||||||
|
|
||||||
func (m *MailTemplate) Subscription() *v1.Subscription {
|
|
||||||
return m.subscription
|
|
||||||
}
|
|
||||||
|
|
||||||
func (m *MailTemplate) AggregateTypes() []es_models.AggregateType {
|
|
||||||
return []es_models.AggregateType{iam_es_model.IAMAggregate}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (m *MailTemplate) CurrentSequence() (uint64, error) {
|
|
||||||
sequence, err := m.view.GetLatestMailTemplateSequence()
|
|
||||||
if err != nil {
|
|
||||||
return 0, err
|
|
||||||
}
|
|
||||||
return sequence.CurrentSequence, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (m *MailTemplate) EventQuery() (*es_models.SearchQuery, error) {
|
|
||||||
sequence, err := m.view.GetLatestMailTemplateSequence()
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
return es_models.NewSearchQuery().
|
|
||||||
AggregateTypeFilter(m.AggregateTypes()...).
|
|
||||||
LatestSequenceFilter(sequence.CurrentSequence), nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (m *MailTemplate) Reduce(event *es_models.Event) (err error) {
|
|
||||||
switch event.AggregateType {
|
|
||||||
case model.IAMAggregate:
|
|
||||||
err = m.processMailTemplate(event)
|
|
||||||
}
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
func (m *MailTemplate) processMailTemplate(event *es_models.Event) (err error) {
|
|
||||||
template := new(iam_model.MailTemplateView)
|
|
||||||
switch event.Type {
|
|
||||||
case model.MailTemplateAdded:
|
|
||||||
err = template.AppendEvent(event)
|
|
||||||
case model.MailTemplateChanged:
|
|
||||||
template, err = m.view.MailTemplateByAggregateID(event.AggregateID)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
err = template.AppendEvent(event)
|
|
||||||
default:
|
|
||||||
return m.view.ProcessedMailTemplateSequence(event)
|
|
||||||
}
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
return m.view.PutMailTemplate(template, event)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (m *MailTemplate) OnError(event *es_models.Event, err error) error {
|
|
||||||
logging.LogWithFields("SPOOL-Wj8sf", "id", event.AggregateID).WithError(err).Warn("something went wrong in label template handler")
|
|
||||||
return spooler.HandleError(event, err, m.view.GetLatestMailTemplateFailedEvent, m.view.ProcessedMailTemplateFailedEvent, m.view.ProcessedMailTemplateSequence, m.errorCountUntilSkip)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (m *MailTemplate) OnSuccess() error {
|
|
||||||
return spooler.HandleSuccess(m.view.UpdateMailTemplateSpoolerRunTimestamp)
|
|
||||||
}
|
|
@ -1,121 +0,0 @@
|
|||||||
package handler
|
|
||||||
|
|
||||||
import (
|
|
||||||
"github.com/caos/logging"
|
|
||||||
|
|
||||||
caos_errs "github.com/caos/zitadel/internal/errors"
|
|
||||||
"github.com/caos/zitadel/internal/eventstore/v1"
|
|
||||||
|
|
||||||
es_models "github.com/caos/zitadel/internal/eventstore/v1/models"
|
|
||||||
"github.com/caos/zitadel/internal/eventstore/v1/query"
|
|
||||||
"github.com/caos/zitadel/internal/eventstore/v1/spooler"
|
|
||||||
"github.com/caos/zitadel/internal/iam/repository/eventsourcing/model"
|
|
||||||
iam_es_model "github.com/caos/zitadel/internal/iam/repository/eventsourcing/model"
|
|
||||||
iam_model "github.com/caos/zitadel/internal/iam/repository/view/model"
|
|
||||||
)
|
|
||||||
|
|
||||||
type MessageText struct {
|
|
||||||
handler
|
|
||||||
subscription *v1.Subscription
|
|
||||||
}
|
|
||||||
|
|
||||||
func newMessageText(handler handler) *MessageText {
|
|
||||||
h := &MessageText{
|
|
||||||
handler: handler,
|
|
||||||
}
|
|
||||||
|
|
||||||
h.subscribe()
|
|
||||||
|
|
||||||
return h
|
|
||||||
}
|
|
||||||
|
|
||||||
func (m *MessageText) subscribe() {
|
|
||||||
m.subscription = m.es.Subscribe(m.AggregateTypes()...)
|
|
||||||
go func() {
|
|
||||||
for event := range m.subscription.Events {
|
|
||||||
query.ReduceEvent(m, event)
|
|
||||||
}
|
|
||||||
}()
|
|
||||||
}
|
|
||||||
|
|
||||||
const (
|
|
||||||
mailTextTable = "adminapi.message_texts"
|
|
||||||
)
|
|
||||||
|
|
||||||
func (m *MessageText) ViewModel() string {
|
|
||||||
return mailTextTable
|
|
||||||
}
|
|
||||||
|
|
||||||
func (m *MessageText) Subscription() *v1.Subscription {
|
|
||||||
return m.subscription
|
|
||||||
}
|
|
||||||
|
|
||||||
func (_ *MessageText) AggregateTypes() []es_models.AggregateType {
|
|
||||||
return []es_models.AggregateType{iam_es_model.IAMAggregate}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (p *MessageText) CurrentSequence() (uint64, error) {
|
|
||||||
sequence, err := p.view.GetLatestMessageTextSequence()
|
|
||||||
if err != nil {
|
|
||||||
return 0, err
|
|
||||||
}
|
|
||||||
return sequence.CurrentSequence, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (m *MessageText) EventQuery() (*es_models.SearchQuery, error) {
|
|
||||||
sequence, err := m.view.GetLatestMessageTextSequence()
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
return es_models.NewSearchQuery().
|
|
||||||
AggregateTypeFilter(m.AggregateTypes()...).
|
|
||||||
LatestSequenceFilter(sequence.CurrentSequence), nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (m *MessageText) Reduce(event *es_models.Event) (err error) {
|
|
||||||
switch event.AggregateType {
|
|
||||||
case model.IAMAggregate:
|
|
||||||
err = m.processMessageText(event)
|
|
||||||
}
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
func (m *MessageText) processMessageText(event *es_models.Event) (err error) {
|
|
||||||
message := new(iam_model.MessageTextView)
|
|
||||||
switch event.Type {
|
|
||||||
case model.CustomTextSet,
|
|
||||||
model.CustomTextRemoved:
|
|
||||||
text := new(iam_model.CustomTextView)
|
|
||||||
err = text.SetData(event)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
message, err = m.view.MessageTextByIDs(event.AggregateID, text.Template, text.Language)
|
|
||||||
if err != nil && !caos_errs.IsNotFound(err) {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
if caos_errs.IsNotFound(err) {
|
|
||||||
err = nil
|
|
||||||
message = new(iam_model.MessageTextView)
|
|
||||||
message.Language = text.Language
|
|
||||||
message.MessageTextType = text.Template
|
|
||||||
message.CreationDate = event.CreationDate
|
|
||||||
}
|
|
||||||
err = message.AppendEvent(event)
|
|
||||||
default:
|
|
||||||
return m.view.ProcessedMessageTextSequence(event)
|
|
||||||
}
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
return m.view.PutMessageText(message, event)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (m *MessageText) OnError(event *es_models.Event, err error) error {
|
|
||||||
logging.LogWithFields("HANDL-5jk84", "id", event.AggregateID).WithError(err).Warn("something went wrong in label mailText handler")
|
|
||||||
return spooler.HandleError(event, err, m.view.GetLatestMessageTextFailedEvent, m.view.ProcessedMessageTextFailedEvent, m.view.ProcessedMessageTextSequence, m.errorCountUntilSkip)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (o *MessageText) OnSuccess() error {
|
|
||||||
return spooler.HandleSuccess(o.view.UpdateMessageTextSpoolerRunTimestamp)
|
|
||||||
}
|
|
@ -1,65 +0,0 @@
|
|||||||
package view
|
|
||||||
|
|
||||||
import (
|
|
||||||
"github.com/caos/zitadel/internal/errors"
|
|
||||||
"github.com/caos/zitadel/internal/eventstore/v1/models"
|
|
||||||
"github.com/caos/zitadel/internal/iam/repository/view"
|
|
||||||
"github.com/caos/zitadel/internal/iam/repository/view/model"
|
|
||||||
global_view "github.com/caos/zitadel/internal/view/repository"
|
|
||||||
)
|
|
||||||
|
|
||||||
const (
|
|
||||||
customTextTable = "adminapi.custom_texts"
|
|
||||||
)
|
|
||||||
|
|
||||||
func (v *View) CustomTextByIDs(aggregateID, template, lang, key string) (*model.CustomTextView, error) {
|
|
||||||
return view.CustomTextByIDs(v.Db, customTextTable, aggregateID, template, lang, key)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (v *View) CustomTextsByAggregateIDAndTemplateAndLand(aggregateID, template, lang string) ([]*model.CustomTextView, error) {
|
|
||||||
return view.GetCustomTexts(v.Db, customTextTable, aggregateID, template, lang)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (v *View) PutCustomText(template *model.CustomTextView, event *models.Event) error {
|
|
||||||
err := view.PutCustomText(v.Db, customTextTable, template)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
return v.ProcessedCustomTextSequence(event)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (v *View) DeleteCustomText(aggregateID, textType, lang, key string, event *models.Event) error {
|
|
||||||
err := view.DeleteCustomText(v.Db, customTextTable, aggregateID, textType, lang, key)
|
|
||||||
if err != nil && !errors.IsNotFound(err) {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
return v.ProcessedCustomTextSequence(event)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (v *View) DeleteCustomTextTemplate(aggregateID, textType, lang string, event *models.Event) error {
|
|
||||||
err := view.DeleteCustomTextTemplate(v.Db, customTextTable, aggregateID, textType, lang)
|
|
||||||
if err != nil && !errors.IsNotFound(err) {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
return v.ProcessedCustomTextSequence(event)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (v *View) GetLatestCustomTextSequence() (*global_view.CurrentSequence, error) {
|
|
||||||
return v.latestSequence(customTextTable)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (v *View) ProcessedCustomTextSequence(event *models.Event) error {
|
|
||||||
return v.saveCurrentSequence(customTextTable, event)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (v *View) UpdateCustomTextSpoolerRunTimestamp() error {
|
|
||||||
return v.updateSpoolerRunSequence(customTextTable)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (v *View) GetLatestCustomTextFailedEvent(sequence uint64) (*global_view.FailedEvent, error) {
|
|
||||||
return v.latestFailedEvent(customTextTable, sequence)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (v *View) ProcessedCustomTextFailedEvent(failedEvent *global_view.FailedEvent) error {
|
|
||||||
return v.saveFailedEvent(failedEvent)
|
|
||||||
}
|
|
@ -1,44 +0,0 @@
|
|||||||
package view
|
|
||||||
|
|
||||||
import (
|
|
||||||
"github.com/caos/zitadel/internal/eventstore/v1/models"
|
|
||||||
"github.com/caos/zitadel/internal/iam/repository/view"
|
|
||||||
"github.com/caos/zitadel/internal/iam/repository/view/model"
|
|
||||||
global_view "github.com/caos/zitadel/internal/view/repository"
|
|
||||||
)
|
|
||||||
|
|
||||||
const (
|
|
||||||
mailTemplateTable = "adminapi.mail_templates"
|
|
||||||
)
|
|
||||||
|
|
||||||
func (v *View) MailTemplateByAggregateID(aggregateID string) (*model.MailTemplateView, error) {
|
|
||||||
return view.GetMailTemplateByAggregateID(v.Db, mailTemplateTable, aggregateID)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (v *View) PutMailTemplate(template *model.MailTemplateView, event *models.Event) error {
|
|
||||||
err := view.PutMailTemplate(v.Db, mailTemplateTable, template)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
return v.ProcessedMailTemplateSequence(event)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (v *View) GetLatestMailTemplateSequence() (*global_view.CurrentSequence, error) {
|
|
||||||
return v.latestSequence(mailTemplateTable)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (v *View) ProcessedMailTemplateSequence(event *models.Event) error {
|
|
||||||
return v.saveCurrentSequence(mailTemplateTable, event)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (v *View) UpdateMailTemplateSpoolerRunTimestamp() error {
|
|
||||||
return v.updateSpoolerRunSequence(mailTemplateTable)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (v *View) GetLatestMailTemplateFailedEvent(sequence uint64) (*global_view.FailedEvent, error) {
|
|
||||||
return v.latestFailedEvent(mailTemplateTable, sequence)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (v *View) ProcessedMailTemplateFailedEvent(failedEvent *global_view.FailedEvent) error {
|
|
||||||
return v.saveFailedEvent(failedEvent)
|
|
||||||
}
|
|
@ -1,48 +0,0 @@
|
|||||||
package view
|
|
||||||
|
|
||||||
import (
|
|
||||||
"github.com/caos/zitadel/internal/eventstore/v1/models"
|
|
||||||
"github.com/caos/zitadel/internal/iam/repository/view"
|
|
||||||
"github.com/caos/zitadel/internal/iam/repository/view/model"
|
|
||||||
global_view "github.com/caos/zitadel/internal/view/repository"
|
|
||||||
)
|
|
||||||
|
|
||||||
const (
|
|
||||||
messageTextTable = "adminapi.message_texts"
|
|
||||||
)
|
|
||||||
|
|
||||||
func (v *View) MessageTexts(aggregateID string) ([]*model.MessageTextView, error) {
|
|
||||||
return view.GetMessageTexts(v.Db, messageTextTable, aggregateID)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (v *View) MessageTextByIDs(aggregateID, textType, lang string) (*model.MessageTextView, error) {
|
|
||||||
return view.GetMessageTextByIDs(v.Db, messageTextTable, aggregateID, textType, lang)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (v *View) PutMessageText(template *model.MessageTextView, event *models.Event) error {
|
|
||||||
err := view.PutMessageText(v.Db, messageTextTable, template)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
return v.ProcessedMessageTextSequence(event)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (v *View) GetLatestMessageTextSequence() (*global_view.CurrentSequence, error) {
|
|
||||||
return v.latestSequence(messageTextTable)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (v *View) ProcessedMessageTextSequence(event *models.Event) error {
|
|
||||||
return v.saveCurrentSequence(messageTextTable, event)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (v *View) UpdateMessageTextSpoolerRunTimestamp() error {
|
|
||||||
return v.updateSpoolerRunSequence(messageTextTable)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (v *View) GetLatestMessageTextFailedEvent(sequence uint64) (*global_view.FailedEvent, error) {
|
|
||||||
return v.latestFailedEvent(messageTextTable, sequence)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (v *View) ProcessedMessageTextFailedEvent(failedEvent *global_view.FailedEvent) error {
|
|
||||||
return v.saveFailedEvent(failedEvent)
|
|
||||||
}
|
|
@ -5,7 +5,6 @@ import (
|
|||||||
|
|
||||||
"golang.org/x/text/language"
|
"golang.org/x/text/language"
|
||||||
|
|
||||||
"github.com/caos/zitadel/internal/domain"
|
|
||||||
usr_model "github.com/caos/zitadel/internal/user/model"
|
usr_model "github.com/caos/zitadel/internal/user/model"
|
||||||
|
|
||||||
iam_model "github.com/caos/zitadel/internal/iam/model"
|
iam_model "github.com/caos/zitadel/internal/iam/model"
|
||||||
@ -24,11 +23,4 @@ type IAMRepository interface {
|
|||||||
|
|
||||||
IDPProvidersByIDPConfigID(ctx context.Context, idpConfigID string) ([]*iam_model.IDPProviderView, error)
|
IDPProvidersByIDPConfigID(ctx context.Context, idpConfigID string) ([]*iam_model.IDPProviderView, error)
|
||||||
ExternalIDPsByIDPConfigID(ctx context.Context, idpConfigID string) ([]*usr_model.ExternalIDPView, error)
|
ExternalIDPsByIDPConfigID(ctx context.Context, idpConfigID string) ([]*usr_model.ExternalIDPView, error)
|
||||||
|
|
||||||
GetDefaultMailTemplate(ctx context.Context) (*iam_model.MailTemplateView, error)
|
|
||||||
|
|
||||||
GetDefaultMessageText(ctx context.Context, textType, language string) (*domain.CustomMessageText, error)
|
|
||||||
GetCustomMessageText(ctx context.Context, textType string, language string) (*domain.CustomMessageText, error)
|
|
||||||
GetDefaultLoginTexts(ctx context.Context, lang string) (*domain.CustomLoginText, error)
|
|
||||||
GetCustomLoginTexts(ctx context.Context, lang string) (*domain.CustomLoginText, error)
|
|
||||||
}
|
}
|
||||||
|
@ -12,22 +12,22 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
func (s *Server) GetDefaultInitMessageText(ctx context.Context, req *admin_pb.GetDefaultInitMessageTextRequest) (*admin_pb.GetDefaultInitMessageTextResponse, error) {
|
func (s *Server) GetDefaultInitMessageText(ctx context.Context, req *admin_pb.GetDefaultInitMessageTextRequest) (*admin_pb.GetDefaultInitMessageTextResponse, error) {
|
||||||
msg, err := s.iam.GetDefaultMessageText(ctx, domain.InitCodeMessageType, req.Language)
|
msg, err := s.query.DefaultMessageTextByTypeAndLanguageFromFileSystem(domain.InitCodeMessageType, req.Language)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
return &admin_pb.GetDefaultInitMessageTextResponse{
|
return &admin_pb.GetDefaultInitMessageTextResponse{
|
||||||
CustomText: text_grpc.DomainCustomMsgTextToPb(msg),
|
CustomText: text_grpc.ModelCustomMessageTextToPb(msg),
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Server) GetCustomInitMessageText(ctx context.Context, req *admin_pb.GetCustomInitMessageTextRequest) (*admin_pb.GetCustomInitMessageTextResponse, error) {
|
func (s *Server) GetCustomInitMessageText(ctx context.Context, req *admin_pb.GetCustomInitMessageTextRequest) (*admin_pb.GetCustomInitMessageTextResponse, error) {
|
||||||
msg, err := s.iam.GetCustomMessageText(ctx, domain.InitCodeMessageType, req.Language)
|
msg, err := s.query.CustomMessageTextByTypeAndLanguage(ctx, domain.IAMID, domain.InitCodeMessageType, req.Language)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
return &admin_pb.GetCustomInitMessageTextResponse{
|
return &admin_pb.GetCustomInitMessageTextResponse{
|
||||||
CustomText: text_grpc.DomainCustomMsgTextToPb(msg),
|
CustomText: text_grpc.ModelCustomMessageTextToPb(msg),
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -46,22 +46,22 @@ func (s *Server) SetDefaultInitMessageText(ctx context.Context, req *admin_pb.Se
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (s *Server) GetDefaultPasswordResetMessageText(ctx context.Context, req *admin_pb.GetDefaultPasswordResetMessageTextRequest) (*admin_pb.GetDefaultPasswordResetMessageTextResponse, error) {
|
func (s *Server) GetDefaultPasswordResetMessageText(ctx context.Context, req *admin_pb.GetDefaultPasswordResetMessageTextRequest) (*admin_pb.GetDefaultPasswordResetMessageTextResponse, error) {
|
||||||
msg, err := s.iam.GetDefaultMessageText(ctx, domain.PasswordResetMessageType, req.Language)
|
msg, err := s.query.DefaultMessageTextByTypeAndLanguageFromFileSystem(domain.PasswordResetMessageType, req.Language)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
return &admin_pb.GetDefaultPasswordResetMessageTextResponse{
|
return &admin_pb.GetDefaultPasswordResetMessageTextResponse{
|
||||||
CustomText: text_grpc.DomainCustomMsgTextToPb(msg),
|
CustomText: text_grpc.ModelCustomMessageTextToPb(msg),
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Server) GetCustomPasswordResetMessageText(ctx context.Context, req *admin_pb.GetCustomPasswordResetMessageTextRequest) (*admin_pb.GetCustomPasswordResetMessageTextResponse, error) {
|
func (s *Server) GetCustomPasswordResetMessageText(ctx context.Context, req *admin_pb.GetCustomPasswordResetMessageTextRequest) (*admin_pb.GetCustomPasswordResetMessageTextResponse, error) {
|
||||||
msg, err := s.iam.GetCustomMessageText(ctx, domain.PasswordResetMessageType, req.Language)
|
msg, err := s.query.CustomMessageTextByTypeAndLanguage(ctx, domain.IAMID, domain.PasswordResetMessageType, req.Language)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
return &admin_pb.GetCustomPasswordResetMessageTextResponse{
|
return &admin_pb.GetCustomPasswordResetMessageTextResponse{
|
||||||
CustomText: text_grpc.DomainCustomMsgTextToPb(msg),
|
CustomText: text_grpc.ModelCustomMessageTextToPb(msg),
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -80,22 +80,22 @@ func (s *Server) SetDefaultPasswordResetMessageText(ctx context.Context, req *ad
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (s *Server) GetDefaultVerifyEmailMessageText(ctx context.Context, req *admin_pb.GetDefaultVerifyEmailMessageTextRequest) (*admin_pb.GetDefaultVerifyEmailMessageTextResponse, error) {
|
func (s *Server) GetDefaultVerifyEmailMessageText(ctx context.Context, req *admin_pb.GetDefaultVerifyEmailMessageTextRequest) (*admin_pb.GetDefaultVerifyEmailMessageTextResponse, error) {
|
||||||
msg, err := s.iam.GetDefaultMessageText(ctx, domain.VerifyEmailMessageType, req.Language)
|
msg, err := s.query.DefaultMessageTextByTypeAndLanguageFromFileSystem(domain.VerifyEmailMessageType, req.Language)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
return &admin_pb.GetDefaultVerifyEmailMessageTextResponse{
|
return &admin_pb.GetDefaultVerifyEmailMessageTextResponse{
|
||||||
CustomText: text_grpc.DomainCustomMsgTextToPb(msg),
|
CustomText: text_grpc.ModelCustomMessageTextToPb(msg),
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Server) GetCustomVerifyEmailMessageText(ctx context.Context, req *admin_pb.GetCustomVerifyEmailMessageTextRequest) (*admin_pb.GetCustomVerifyEmailMessageTextResponse, error) {
|
func (s *Server) GetCustomVerifyEmailMessageText(ctx context.Context, req *admin_pb.GetCustomVerifyEmailMessageTextRequest) (*admin_pb.GetCustomVerifyEmailMessageTextResponse, error) {
|
||||||
msg, err := s.iam.GetCustomMessageText(ctx, domain.VerifyEmailMessageType, req.Language)
|
msg, err := s.query.CustomMessageTextByTypeAndLanguage(ctx, domain.IAMID, domain.VerifyEmailMessageType, req.Language)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
return &admin_pb.GetCustomVerifyEmailMessageTextResponse{
|
return &admin_pb.GetCustomVerifyEmailMessageTextResponse{
|
||||||
CustomText: text_grpc.DomainCustomMsgTextToPb(msg),
|
CustomText: text_grpc.ModelCustomMessageTextToPb(msg),
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -114,22 +114,22 @@ func (s *Server) SetDefaultVerifyEmailMessageText(ctx context.Context, req *admi
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (s *Server) GetDefaultVerifyPhoneMessageText(ctx context.Context, req *admin_pb.GetDefaultVerifyPhoneMessageTextRequest) (*admin_pb.GetDefaultVerifyPhoneMessageTextResponse, error) {
|
func (s *Server) GetDefaultVerifyPhoneMessageText(ctx context.Context, req *admin_pb.GetDefaultVerifyPhoneMessageTextRequest) (*admin_pb.GetDefaultVerifyPhoneMessageTextResponse, error) {
|
||||||
msg, err := s.iam.GetDefaultMessageText(ctx, domain.VerifyPhoneMessageType, req.Language)
|
msg, err := s.query.DefaultMessageTextByTypeAndLanguageFromFileSystem(domain.VerifyPhoneMessageType, req.Language)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
return &admin_pb.GetDefaultVerifyPhoneMessageTextResponse{
|
return &admin_pb.GetDefaultVerifyPhoneMessageTextResponse{
|
||||||
CustomText: text_grpc.DomainCustomMsgTextToPb(msg),
|
CustomText: text_grpc.ModelCustomMessageTextToPb(msg),
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Server) GetCustomVerifyPhoneMessageText(ctx context.Context, req *admin_pb.GetCustomVerifyPhoneMessageTextRequest) (*admin_pb.GetCustomVerifyPhoneMessageTextResponse, error) {
|
func (s *Server) GetCustomVerifyPhoneMessageText(ctx context.Context, req *admin_pb.GetCustomVerifyPhoneMessageTextRequest) (*admin_pb.GetCustomVerifyPhoneMessageTextResponse, error) {
|
||||||
msg, err := s.iam.GetCustomMessageText(ctx, domain.VerifyPhoneMessageType, req.Language)
|
msg, err := s.query.CustomMessageTextByTypeAndLanguage(ctx, domain.IAMID, domain.VerifyPhoneMessageType, req.Language)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
return &admin_pb.GetCustomVerifyPhoneMessageTextResponse{
|
return &admin_pb.GetCustomVerifyPhoneMessageTextResponse{
|
||||||
CustomText: text_grpc.DomainCustomMsgTextToPb(msg),
|
CustomText: text_grpc.ModelCustomMessageTextToPb(msg),
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -148,22 +148,22 @@ func (s *Server) SetDefaultVerifyPhoneMessageText(ctx context.Context, req *admi
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (s *Server) GetDefaultDomainClaimedMessageText(ctx context.Context, req *admin_pb.GetDefaultDomainClaimedMessageTextRequest) (*admin_pb.GetDefaultDomainClaimedMessageTextResponse, error) {
|
func (s *Server) GetDefaultDomainClaimedMessageText(ctx context.Context, req *admin_pb.GetDefaultDomainClaimedMessageTextRequest) (*admin_pb.GetDefaultDomainClaimedMessageTextResponse, error) {
|
||||||
msg, err := s.iam.GetDefaultMessageText(ctx, domain.DomainClaimedMessageType, req.Language)
|
msg, err := s.query.DefaultMessageTextByTypeAndLanguageFromFileSystem(domain.DomainClaimedMessageType, req.Language)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
return &admin_pb.GetDefaultDomainClaimedMessageTextResponse{
|
return &admin_pb.GetDefaultDomainClaimedMessageTextResponse{
|
||||||
CustomText: text_grpc.DomainCustomMsgTextToPb(msg),
|
CustomText: text_grpc.ModelCustomMessageTextToPb(msg),
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Server) GetCustomDomainClaimedMessageText(ctx context.Context, req *admin_pb.GetCustomDomainClaimedMessageTextRequest) (*admin_pb.GetCustomDomainClaimedMessageTextResponse, error) {
|
func (s *Server) GetCustomDomainClaimedMessageText(ctx context.Context, req *admin_pb.GetCustomDomainClaimedMessageTextRequest) (*admin_pb.GetCustomDomainClaimedMessageTextResponse, error) {
|
||||||
msg, err := s.iam.GetCustomMessageText(ctx, domain.DomainClaimedMessageType, req.Language)
|
msg, err := s.query.CustomMessageTextByTypeAndLanguage(ctx, domain.IAMID, domain.DomainClaimedMessageType, req.Language)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
return &admin_pb.GetCustomDomainClaimedMessageTextResponse{
|
return &admin_pb.GetCustomDomainClaimedMessageTextResponse{
|
||||||
CustomText: text_grpc.DomainCustomMsgTextToPb(msg),
|
CustomText: text_grpc.ModelCustomMessageTextToPb(msg),
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -182,22 +182,22 @@ func (s *Server) SetDefaultDomainClaimedMessageText(ctx context.Context, req *ad
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (s *Server) GetDefaultPasswordlessRegistrationMessageText(ctx context.Context, req *admin_pb.GetDefaultPasswordlessRegistrationMessageTextRequest) (*admin_pb.GetDefaultPasswordlessRegistrationMessageTextResponse, error) {
|
func (s *Server) GetDefaultPasswordlessRegistrationMessageText(ctx context.Context, req *admin_pb.GetDefaultPasswordlessRegistrationMessageTextRequest) (*admin_pb.GetDefaultPasswordlessRegistrationMessageTextResponse, error) {
|
||||||
msg, err := s.iam.GetDefaultMessageText(ctx, domain.PasswordlessRegistrationMessageType, req.Language)
|
msg, err := s.query.DefaultMessageTextByTypeAndLanguageFromFileSystem(domain.PasswordlessRegistrationMessageType, req.Language)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
return &admin_pb.GetDefaultPasswordlessRegistrationMessageTextResponse{
|
return &admin_pb.GetDefaultPasswordlessRegistrationMessageTextResponse{
|
||||||
CustomText: text_grpc.DomainCustomMsgTextToPb(msg),
|
CustomText: text_grpc.ModelCustomMessageTextToPb(msg),
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Server) GetCustomPasswordlessRegistrationMessageText(ctx context.Context, req *admin_pb.GetCustomPasswordlessRegistrationMessageTextRequest) (*admin_pb.GetCustomPasswordlessRegistrationMessageTextResponse, error) {
|
func (s *Server) GetCustomPasswordlessRegistrationMessageText(ctx context.Context, req *admin_pb.GetCustomPasswordlessRegistrationMessageTextRequest) (*admin_pb.GetCustomPasswordlessRegistrationMessageTextResponse, error) {
|
||||||
msg, err := s.iam.GetCustomMessageText(ctx, domain.PasswordlessRegistrationMessageType, req.Language)
|
msg, err := s.query.CustomMessageTextByTypeAndLanguage(ctx, domain.IAMID, domain.PasswordlessRegistrationMessageType, req.Language)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
return &admin_pb.GetCustomPasswordlessRegistrationMessageTextResponse{
|
return &admin_pb.GetCustomPasswordlessRegistrationMessageTextResponse{
|
||||||
CustomText: text_grpc.DomainCustomMsgTextToPb(msg),
|
CustomText: text_grpc.ModelCustomMessageTextToPb(msg),
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -216,7 +216,7 @@ func (s *Server) SetDefaultPasswordlessRegistrationMessageText(ctx context.Conte
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (s *Server) GetDefaultLoginTexts(ctx context.Context, req *admin_pb.GetDefaultLoginTextsRequest) (*admin_pb.GetDefaultLoginTextsResponse, error) {
|
func (s *Server) GetDefaultLoginTexts(ctx context.Context, req *admin_pb.GetDefaultLoginTextsRequest) (*admin_pb.GetDefaultLoginTextsResponse, error) {
|
||||||
msg, err := s.iam.GetDefaultLoginTexts(ctx, req.Language)
|
msg, err := s.query.GetDefaultLoginTexts(ctx, req.Language)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@ -225,7 +225,7 @@ func (s *Server) GetDefaultLoginTexts(ctx context.Context, req *admin_pb.GetDefa
|
|||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
func (s *Server) GetCustomLoginTexts(ctx context.Context, req *admin_pb.GetCustomLoginTextsRequest) (*admin_pb.GetCustomLoginTextsResponse, error) {
|
func (s *Server) GetCustomLoginTexts(ctx context.Context, req *admin_pb.GetCustomLoginTextsRequest) (*admin_pb.GetCustomLoginTextsResponse, error) {
|
||||||
msg, err := s.iam.GetCustomLoginTexts(ctx, req.Language)
|
msg, err := s.query.GetCustomLoginTexts(ctx, domain.IAMID, req.Language)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
@ -13,22 +13,22 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
func (s *Server) GetCustomInitMessageText(ctx context.Context, req *mgmt_pb.GetCustomInitMessageTextRequest) (*mgmt_pb.GetCustomInitMessageTextResponse, error) {
|
func (s *Server) GetCustomInitMessageText(ctx context.Context, req *mgmt_pb.GetCustomInitMessageTextRequest) (*mgmt_pb.GetCustomInitMessageTextResponse, error) {
|
||||||
msg, err := s.org.GetMessageText(ctx, authz.GetCtxData(ctx).OrgID, domain.InitCodeMessageType, req.Language)
|
msg, err := s.query.CustomMessageTextByTypeAndLanguage(ctx, authz.GetCtxData(ctx).OrgID, domain.InitCodeMessageType, req.Language)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
return &mgmt_pb.GetCustomInitMessageTextResponse{
|
return &mgmt_pb.GetCustomInitMessageTextResponse{
|
||||||
CustomText: text_grpc.DomainCustomMsgTextToPb(msg),
|
CustomText: text_grpc.ModelCustomMessageTextToPb(msg),
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Server) GetDefaultInitMessageText(ctx context.Context, req *mgmt_pb.GetDefaultInitMessageTextRequest) (*mgmt_pb.GetDefaultInitMessageTextResponse, error) {
|
func (s *Server) GetDefaultInitMessageText(ctx context.Context, req *mgmt_pb.GetDefaultInitMessageTextRequest) (*mgmt_pb.GetDefaultInitMessageTextResponse, error) {
|
||||||
msg, err := s.org.GetDefaultMessageText(ctx, domain.InitCodeMessageType, req.Language)
|
msg, err := s.query.IAMMessageTextByTypeAndLanguage(ctx, domain.InitCodeMessageType, req.Language)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
return &mgmt_pb.GetDefaultInitMessageTextResponse{
|
return &mgmt_pb.GetDefaultInitMessageTextResponse{
|
||||||
CustomText: text_grpc.DomainCustomMsgTextToPb(msg),
|
CustomText: text_grpc.ModelCustomMessageTextToPb(msg),
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -61,22 +61,22 @@ func (s *Server) ResetCustomInitMessageTextToDefault(ctx context.Context, req *m
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (s *Server) GetCustomPasswordResetMessageText(ctx context.Context, req *mgmt_pb.GetCustomPasswordResetMessageTextRequest) (*mgmt_pb.GetCustomPasswordResetMessageTextResponse, error) {
|
func (s *Server) GetCustomPasswordResetMessageText(ctx context.Context, req *mgmt_pb.GetCustomPasswordResetMessageTextRequest) (*mgmt_pb.GetCustomPasswordResetMessageTextResponse, error) {
|
||||||
msg, err := s.org.GetMessageText(ctx, authz.GetCtxData(ctx).OrgID, domain.PasswordResetMessageType, req.Language)
|
msg, err := s.query.CustomMessageTextByTypeAndLanguage(ctx, authz.GetCtxData(ctx).OrgID, domain.PasswordResetMessageType, req.Language)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
return &mgmt_pb.GetCustomPasswordResetMessageTextResponse{
|
return &mgmt_pb.GetCustomPasswordResetMessageTextResponse{
|
||||||
CustomText: text_grpc.DomainCustomMsgTextToPb(msg),
|
CustomText: text_grpc.ModelCustomMessageTextToPb(msg),
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Server) GetDefaultPasswordResetMessageText(ctx context.Context, req *mgmt_pb.GetDefaultPasswordResetMessageTextRequest) (*mgmt_pb.GetDefaultPasswordResetMessageTextResponse, error) {
|
func (s *Server) GetDefaultPasswordResetMessageText(ctx context.Context, req *mgmt_pb.GetDefaultPasswordResetMessageTextRequest) (*mgmt_pb.GetDefaultPasswordResetMessageTextResponse, error) {
|
||||||
msg, err := s.org.GetDefaultMessageText(ctx, domain.PasswordResetMessageType, req.Language)
|
msg, err := s.query.IAMMessageTextByTypeAndLanguage(ctx, domain.PasswordResetMessageType, req.Language)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
return &mgmt_pb.GetDefaultPasswordResetMessageTextResponse{
|
return &mgmt_pb.GetDefaultPasswordResetMessageTextResponse{
|
||||||
CustomText: text_grpc.DomainCustomMsgTextToPb(msg),
|
CustomText: text_grpc.ModelCustomMessageTextToPb(msg),
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -109,22 +109,22 @@ func (s *Server) ResetCustomPasswordResetMessageTextToDefault(ctx context.Contex
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (s *Server) GetCustomVerifyEmailMessageText(ctx context.Context, req *mgmt_pb.GetCustomVerifyEmailMessageTextRequest) (*mgmt_pb.GetCustomVerifyEmailMessageTextResponse, error) {
|
func (s *Server) GetCustomVerifyEmailMessageText(ctx context.Context, req *mgmt_pb.GetCustomVerifyEmailMessageTextRequest) (*mgmt_pb.GetCustomVerifyEmailMessageTextResponse, error) {
|
||||||
msg, err := s.org.GetMessageText(ctx, authz.GetCtxData(ctx).OrgID, domain.VerifyEmailMessageType, req.Language)
|
msg, err := s.query.CustomMessageTextByTypeAndLanguage(ctx, authz.GetCtxData(ctx).OrgID, domain.VerifyEmailMessageType, req.Language)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
return &mgmt_pb.GetCustomVerifyEmailMessageTextResponse{
|
return &mgmt_pb.GetCustomVerifyEmailMessageTextResponse{
|
||||||
CustomText: text_grpc.DomainCustomMsgTextToPb(msg),
|
CustomText: text_grpc.ModelCustomMessageTextToPb(msg),
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Server) GetDefaultVerifyEmailMessageText(ctx context.Context, req *mgmt_pb.GetDefaultVerifyEmailMessageTextRequest) (*mgmt_pb.GetDefaultVerifyEmailMessageTextResponse, error) {
|
func (s *Server) GetDefaultVerifyEmailMessageText(ctx context.Context, req *mgmt_pb.GetDefaultVerifyEmailMessageTextRequest) (*mgmt_pb.GetDefaultVerifyEmailMessageTextResponse, error) {
|
||||||
msg, err := s.org.GetDefaultMessageText(ctx, domain.VerifyEmailMessageType, req.Language)
|
msg, err := s.query.IAMMessageTextByTypeAndLanguage(ctx, domain.VerifyEmailMessageType, req.Language)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
return &mgmt_pb.GetDefaultVerifyEmailMessageTextResponse{
|
return &mgmt_pb.GetDefaultVerifyEmailMessageTextResponse{
|
||||||
CustomText: text_grpc.DomainCustomMsgTextToPb(msg),
|
CustomText: text_grpc.ModelCustomMessageTextToPb(msg),
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -157,22 +157,22 @@ func (s *Server) ResetCustomVerifyEmailMessageTextToDefault(ctx context.Context,
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (s *Server) GetCustomVerifyPhoneMessageText(ctx context.Context, req *mgmt_pb.GetCustomVerifyPhoneMessageTextRequest) (*mgmt_pb.GetCustomVerifyPhoneMessageTextResponse, error) {
|
func (s *Server) GetCustomVerifyPhoneMessageText(ctx context.Context, req *mgmt_pb.GetCustomVerifyPhoneMessageTextRequest) (*mgmt_pb.GetCustomVerifyPhoneMessageTextResponse, error) {
|
||||||
msg, err := s.org.GetMessageText(ctx, authz.GetCtxData(ctx).OrgID, domain.VerifyPhoneMessageType, req.Language)
|
msg, err := s.query.CustomMessageTextByTypeAndLanguage(ctx, authz.GetCtxData(ctx).OrgID, domain.VerifyPhoneMessageType, req.Language)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
return &mgmt_pb.GetCustomVerifyPhoneMessageTextResponse{
|
return &mgmt_pb.GetCustomVerifyPhoneMessageTextResponse{
|
||||||
CustomText: text_grpc.DomainCustomMsgTextToPb(msg),
|
CustomText: text_grpc.ModelCustomMessageTextToPb(msg),
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Server) GetDefaultVerifyPhoneMessageText(ctx context.Context, req *mgmt_pb.GetDefaultVerifyPhoneMessageTextRequest) (*mgmt_pb.GetDefaultVerifyPhoneMessageTextResponse, error) {
|
func (s *Server) GetDefaultVerifyPhoneMessageText(ctx context.Context, req *mgmt_pb.GetDefaultVerifyPhoneMessageTextRequest) (*mgmt_pb.GetDefaultVerifyPhoneMessageTextResponse, error) {
|
||||||
msg, err := s.org.GetDefaultMessageText(ctx, domain.VerifyPhoneMessageType, req.Language)
|
msg, err := s.query.IAMMessageTextByTypeAndLanguage(ctx, domain.VerifyPhoneMessageType, req.Language)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
return &mgmt_pb.GetDefaultVerifyPhoneMessageTextResponse{
|
return &mgmt_pb.GetDefaultVerifyPhoneMessageTextResponse{
|
||||||
CustomText: text_grpc.DomainCustomMsgTextToPb(msg),
|
CustomText: text_grpc.ModelCustomMessageTextToPb(msg),
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -205,22 +205,22 @@ func (s *Server) ResetCustomVerifyPhoneMessageTextToDefault(ctx context.Context,
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (s *Server) GetCustomDomainClaimedMessageText(ctx context.Context, req *mgmt_pb.GetCustomDomainClaimedMessageTextRequest) (*mgmt_pb.GetCustomDomainClaimedMessageTextResponse, error) {
|
func (s *Server) GetCustomDomainClaimedMessageText(ctx context.Context, req *mgmt_pb.GetCustomDomainClaimedMessageTextRequest) (*mgmt_pb.GetCustomDomainClaimedMessageTextResponse, error) {
|
||||||
msg, err := s.org.GetMessageText(ctx, authz.GetCtxData(ctx).OrgID, domain.DomainClaimedMessageType, req.Language)
|
msg, err := s.query.CustomMessageTextByTypeAndLanguage(ctx, authz.GetCtxData(ctx).OrgID, domain.DomainClaimedMessageType, req.Language)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
return &mgmt_pb.GetCustomDomainClaimedMessageTextResponse{
|
return &mgmt_pb.GetCustomDomainClaimedMessageTextResponse{
|
||||||
CustomText: text_grpc.DomainCustomMsgTextToPb(msg),
|
CustomText: text_grpc.ModelCustomMessageTextToPb(msg),
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Server) GetDefaultDomainClaimedMessageText(ctx context.Context, req *mgmt_pb.GetDefaultDomainClaimedMessageTextRequest) (*mgmt_pb.GetDefaultDomainClaimedMessageTextResponse, error) {
|
func (s *Server) GetDefaultDomainClaimedMessageText(ctx context.Context, req *mgmt_pb.GetDefaultDomainClaimedMessageTextRequest) (*mgmt_pb.GetDefaultDomainClaimedMessageTextResponse, error) {
|
||||||
msg, err := s.org.GetDefaultMessageText(ctx, domain.DomainClaimedMessageType, req.Language)
|
msg, err := s.query.IAMMessageTextByTypeAndLanguage(ctx, domain.DomainClaimedMessageType, req.Language)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
return &mgmt_pb.GetDefaultDomainClaimedMessageTextResponse{
|
return &mgmt_pb.GetDefaultDomainClaimedMessageTextResponse{
|
||||||
CustomText: text_grpc.DomainCustomMsgTextToPb(msg),
|
CustomText: text_grpc.ModelCustomMessageTextToPb(msg),
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -253,22 +253,22 @@ func (s *Server) ResetCustomDomainClaimedMessageTextToDefault(ctx context.Contex
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (s *Server) GetCustomPasswordlessRegistrationMessageText(ctx context.Context, req *mgmt_pb.GetCustomPasswordlessRegistrationMessageTextRequest) (*mgmt_pb.GetCustomPasswordlessRegistrationMessageTextResponse, error) {
|
func (s *Server) GetCustomPasswordlessRegistrationMessageText(ctx context.Context, req *mgmt_pb.GetCustomPasswordlessRegistrationMessageTextRequest) (*mgmt_pb.GetCustomPasswordlessRegistrationMessageTextResponse, error) {
|
||||||
msg, err := s.org.GetMessageText(ctx, authz.GetCtxData(ctx).OrgID, domain.PasswordlessRegistrationMessageType, req.Language)
|
msg, err := s.query.CustomMessageTextByTypeAndLanguage(ctx, authz.GetCtxData(ctx).OrgID, domain.PasswordlessRegistrationMessageType, req.Language)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
return &mgmt_pb.GetCustomPasswordlessRegistrationMessageTextResponse{
|
return &mgmt_pb.GetCustomPasswordlessRegistrationMessageTextResponse{
|
||||||
CustomText: text_grpc.DomainCustomMsgTextToPb(msg),
|
CustomText: text_grpc.ModelCustomMessageTextToPb(msg),
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Server) GetDefaultPasswordlessRegistrationMessageText(ctx context.Context, req *mgmt_pb.GetDefaultPasswordlessRegistrationMessageTextRequest) (*mgmt_pb.GetDefaultPasswordlessRegistrationMessageTextResponse, error) {
|
func (s *Server) GetDefaultPasswordlessRegistrationMessageText(ctx context.Context, req *mgmt_pb.GetDefaultPasswordlessRegistrationMessageTextRequest) (*mgmt_pb.GetDefaultPasswordlessRegistrationMessageTextResponse, error) {
|
||||||
msg, err := s.org.GetDefaultMessageText(ctx, domain.PasswordlessRegistrationMessageType, req.Language)
|
msg, err := s.query.IAMMessageTextByTypeAndLanguage(ctx, domain.PasswordlessRegistrationMessageType, req.Language)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
return &mgmt_pb.GetDefaultPasswordlessRegistrationMessageTextResponse{
|
return &mgmt_pb.GetDefaultPasswordlessRegistrationMessageTextResponse{
|
||||||
CustomText: text_grpc.DomainCustomMsgTextToPb(msg),
|
CustomText: text_grpc.ModelCustomMessageTextToPb(msg),
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -301,7 +301,7 @@ func (s *Server) ResetCustomPasswordlessRegistrationMessageTextToDefault(ctx con
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (s *Server) GetCustomLoginTexts(ctx context.Context, req *mgmt_pb.GetCustomLoginTextsRequest) (*mgmt_pb.GetCustomLoginTextsResponse, error) {
|
func (s *Server) GetCustomLoginTexts(ctx context.Context, req *mgmt_pb.GetCustomLoginTextsRequest) (*mgmt_pb.GetCustomLoginTextsResponse, error) {
|
||||||
msg, err := s.org.GetLoginTexts(ctx, authz.GetCtxData(ctx).OrgID, req.Language)
|
msg, err := s.query.GetCustomLoginTexts(ctx, authz.GetCtxData(ctx).OrgID, req.Language)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@ -311,7 +311,7 @@ func (s *Server) GetCustomLoginTexts(ctx context.Context, req *mgmt_pb.GetCustom
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (s *Server) GetDefaultLoginTexts(ctx context.Context, req *mgmt_pb.GetDefaultLoginTextsRequest) (*mgmt_pb.GetDefaultLoginTextsResponse, error) {
|
func (s *Server) GetDefaultLoginTexts(ctx context.Context, req *mgmt_pb.GetDefaultLoginTextsRequest) (*mgmt_pb.GetDefaultLoginTextsResponse, error) {
|
||||||
msg, err := s.org.GetDefaultLoginTexts(ctx, req.Language)
|
msg, err := s.query.IAMLoginTexts(ctx, req.Language)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
@ -3,9 +3,28 @@ package text
|
|||||||
import (
|
import (
|
||||||
"github.com/caos/zitadel/internal/api/grpc/object"
|
"github.com/caos/zitadel/internal/api/grpc/object"
|
||||||
"github.com/caos/zitadel/internal/domain"
|
"github.com/caos/zitadel/internal/domain"
|
||||||
|
"github.com/caos/zitadel/internal/query"
|
||||||
text_pb "github.com/caos/zitadel/pkg/grpc/text"
|
text_pb "github.com/caos/zitadel/pkg/grpc/text"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
func ModelCustomMessageTextToPb(msg *query.MessageText) *text_pb.MessageCustomText {
|
||||||
|
return &text_pb.MessageCustomText{
|
||||||
|
Title: msg.Title,
|
||||||
|
PreHeader: msg.PreHeader,
|
||||||
|
Subject: msg.Subject,
|
||||||
|
Greeting: msg.Greeting,
|
||||||
|
Text: msg.Text,
|
||||||
|
ButtonText: msg.ButtonText,
|
||||||
|
FooterText: msg.Footer,
|
||||||
|
Details: object.ToViewDetailsPb(
|
||||||
|
msg.Sequence,
|
||||||
|
msg.CreationDate,
|
||||||
|
msg.ChangeDate,
|
||||||
|
msg.AggregateID,
|
||||||
|
),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func DomainCustomMsgTextToPb(msg *domain.CustomMessageText) *text_pb.MessageCustomText {
|
func DomainCustomMsgTextToPb(msg *domain.CustomMessageText) *text_pb.MessageCustomText {
|
||||||
return &text_pb.MessageCustomText{
|
return &text_pb.MessageCustomText{
|
||||||
Title: msg.Title,
|
Title: msg.Title,
|
||||||
|
@ -991,11 +991,11 @@ func labelPolicyToDomain(p *query.LabelPolicy) *domain.LabelPolicy {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (repo *AuthRequestRepo) getLoginTexts(ctx context.Context, aggregateID string) ([]*domain.CustomText, error) {
|
func (repo *AuthRequestRepo) getLoginTexts(ctx context.Context, aggregateID string) ([]*domain.CustomText, error) {
|
||||||
loginTexts, err := repo.View.CustomTextsByAggregateIDAndTemplate(aggregateID, domain.LoginCustomText)
|
loginTexts, err := repo.Query.CustomTextListByTemplate(ctx, aggregateID, domain.LoginCustomText)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
return iam_view_model.CustomTextViewsToDomain(loginTexts), err
|
return query.CustomTextsToDomain(loginTexts), err
|
||||||
}
|
}
|
||||||
|
|
||||||
func (repo *AuthRequestRepo) hasSucceededPage(ctx context.Context, request *domain.AuthRequest, provider applicationProvider) (bool, error) {
|
func (repo *AuthRequestRepo) hasSucceededPage(ctx context.Context, request *domain.AuthRequest, provider applicationProvider) (bool, error) {
|
||||||
|
@ -41,15 +41,15 @@ func (repo *OrgRepository) GetMyPasswordComplexityPolicy(ctx context.Context) (*
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (repo *OrgRepository) GetLoginText(ctx context.Context, orgID string) ([]*domain.CustomText, error) {
|
func (repo *OrgRepository) GetLoginText(ctx context.Context, orgID string) ([]*domain.CustomText, error) {
|
||||||
loginTexts, err := repo.View.CustomTextsByAggregateIDAndTemplate(domain.IAMID, domain.LoginCustomText)
|
loginTexts, err := repo.Query.CustomTextListByTemplate(ctx, domain.IAMID, domain.LoginCustomText)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
orgLoginTexts, err := repo.View.CustomTextsByAggregateIDAndTemplate(orgID, domain.LoginCustomText)
|
orgLoginTexts, err := repo.Query.CustomTextListByTemplate(ctx, orgID, domain.LoginCustomText)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
return append(iam_view_model.CustomTextViewsToDomain(loginTexts), iam_view_model.CustomTextViewsToDomain(orgLoginTexts)...), nil
|
return append(query.CustomTextsToDomain(loginTexts), query.CustomTextsToDomain(orgLoginTexts)...), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *OrgRepository) getIAMEvents(ctx context.Context, sequence uint64) ([]*models.Event, error) {
|
func (p *OrgRepository) getIAMEvents(ctx context.Context, sequence uint64) ([]*models.Event, error) {
|
||||||
|
@ -1,132 +0,0 @@
|
|||||||
package handler
|
|
||||||
|
|
||||||
import (
|
|
||||||
"github.com/caos/logging"
|
|
||||||
caos_errs "github.com/caos/zitadel/internal/errors"
|
|
||||||
"github.com/caos/zitadel/internal/eventstore/v1"
|
|
||||||
es_models "github.com/caos/zitadel/internal/eventstore/v1/models"
|
|
||||||
"github.com/caos/zitadel/internal/eventstore/v1/query"
|
|
||||||
"github.com/caos/zitadel/internal/eventstore/v1/spooler"
|
|
||||||
iam_es_model "github.com/caos/zitadel/internal/iam/repository/eventsourcing/model"
|
|
||||||
iam_model "github.com/caos/zitadel/internal/iam/repository/view/model"
|
|
||||||
"github.com/caos/zitadel/internal/org/repository/eventsourcing/model"
|
|
||||||
)
|
|
||||||
|
|
||||||
type CustomText struct {
|
|
||||||
handler
|
|
||||||
subscription *v1.Subscription
|
|
||||||
}
|
|
||||||
|
|
||||||
func newCustomText(handler handler) *CustomText {
|
|
||||||
h := &CustomText{
|
|
||||||
handler: handler,
|
|
||||||
}
|
|
||||||
|
|
||||||
h.subscribe()
|
|
||||||
|
|
||||||
return h
|
|
||||||
}
|
|
||||||
|
|
||||||
func (m *CustomText) subscribe() {
|
|
||||||
m.subscription = m.es.Subscribe(m.AggregateTypes()...)
|
|
||||||
go func() {
|
|
||||||
for event := range m.subscription.Events {
|
|
||||||
query.ReduceEvent(m, event)
|
|
||||||
}
|
|
||||||
}()
|
|
||||||
}
|
|
||||||
|
|
||||||
const (
|
|
||||||
customTextTable = "auth.custom_texts"
|
|
||||||
)
|
|
||||||
|
|
||||||
func (m *CustomText) ViewModel() string {
|
|
||||||
return customTextTable
|
|
||||||
}
|
|
||||||
|
|
||||||
func (m *CustomText) Subscription() *v1.Subscription {
|
|
||||||
return m.subscription
|
|
||||||
}
|
|
||||||
|
|
||||||
func (_ *CustomText) AggregateTypes() []es_models.AggregateType {
|
|
||||||
return []es_models.AggregateType{model.OrgAggregate, iam_es_model.IAMAggregate}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (p *CustomText) CurrentSequence() (uint64, error) {
|
|
||||||
sequence, err := p.view.GetLatestCustomTextSequence()
|
|
||||||
if err != nil {
|
|
||||||
return 0, err
|
|
||||||
}
|
|
||||||
return sequence.CurrentSequence, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (m *CustomText) EventQuery() (*es_models.SearchQuery, error) {
|
|
||||||
sequence, err := m.view.GetLatestCustomTextSequence()
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
return es_models.NewSearchQuery().
|
|
||||||
AggregateTypeFilter(m.AggregateTypes()...).
|
|
||||||
LatestSequenceFilter(sequence.CurrentSequence), nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (m *CustomText) Reduce(event *es_models.Event) (err error) {
|
|
||||||
switch event.AggregateType {
|
|
||||||
case model.OrgAggregate, iam_es_model.IAMAggregate:
|
|
||||||
err = m.processCustomText(event)
|
|
||||||
}
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
func (m *CustomText) processCustomText(event *es_models.Event) (err error) {
|
|
||||||
customText := new(iam_model.CustomTextView)
|
|
||||||
switch event.Type {
|
|
||||||
case iam_es_model.CustomTextSet, model.CustomTextSet:
|
|
||||||
text := new(iam_model.CustomTextView)
|
|
||||||
err = text.SetData(event)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
customText, err = m.view.CustomTextByIDs(event.AggregateID, text.Template, text.Key, text.Language)
|
|
||||||
if err != nil && !caos_errs.IsNotFound(err) {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
if caos_errs.IsNotFound(err) {
|
|
||||||
err = nil
|
|
||||||
customText = new(iam_model.CustomTextView)
|
|
||||||
customText.Language = text.Language
|
|
||||||
customText.Template = text.Template
|
|
||||||
customText.CreationDate = event.CreationDate
|
|
||||||
}
|
|
||||||
err = customText.AppendEvent(event)
|
|
||||||
case iam_es_model.CustomTextRemoved, model.CustomTextRemoved:
|
|
||||||
text := new(iam_model.CustomTextView)
|
|
||||||
err = text.SetData(event)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
return m.view.DeleteCustomText(event.AggregateID, text.Template, text.Language, text.Key, event)
|
|
||||||
case iam_es_model.CustomTextMessageRemoved, model.CustomTextMessageRemoved:
|
|
||||||
text := new(iam_model.CustomTextView)
|
|
||||||
err = text.SetData(event)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
return m.view.DeleteCustomTextTemplate(event.AggregateID, text.Template, text.Language, event)
|
|
||||||
default:
|
|
||||||
return m.view.ProcessedCustomTextSequence(event)
|
|
||||||
}
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
return m.view.PutCustomText(customText, event)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (m *CustomText) OnError(event *es_models.Event, err error) error {
|
|
||||||
logging.LogWithFields("SPOOL-3m0fs", "id", event.AggregateID).WithError(err).Warn("something went wrong in custom text handler")
|
|
||||||
return spooler.HandleError(event, err, m.view.GetLatestCustomTextFailedEvent, m.view.ProcessedCustomTextFailedEvent, m.view.ProcessedCustomTextSequence, m.errorCountUntilSkip)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (o *CustomText) OnSuccess() error {
|
|
||||||
return spooler.HandleSuccess(o.view.UpdateCustomTextSpoolerRunTimestamp)
|
|
||||||
}
|
|
@ -56,7 +56,6 @@ func Register(configs Configs, bulkLimit, errorCount uint64, view *view.View, es
|
|||||||
handler{view, bulkLimit, configs.cycleDuration("ExternalIDP"), errorCount, es},
|
handler{view, bulkLimit, configs.cycleDuration("ExternalIDP"), errorCount, es},
|
||||||
systemDefaults),
|
systemDefaults),
|
||||||
newRefreshToken(handler{view, bulkLimit, configs.cycleDuration("RefreshToken"), errorCount, es}),
|
newRefreshToken(handler{view, bulkLimit, configs.cycleDuration("RefreshToken"), errorCount, es}),
|
||||||
newCustomText(handler{view, bulkLimit, configs.cycleDuration("CustomTexts"), errorCount, es}),
|
|
||||||
newMetadata(handler{view, bulkLimit, configs.cycleDuration("Metadata"), errorCount, es}),
|
newMetadata(handler{view, bulkLimit, configs.cycleDuration("Metadata"), errorCount, es}),
|
||||||
newOrgProjectMapping(handler{view, bulkLimit, configs.cycleDuration("OrgProjectMapping"), errorCount, es}),
|
newOrgProjectMapping(handler{view, bulkLimit, configs.cycleDuration("OrgProjectMapping"), errorCount, es}),
|
||||||
}
|
}
|
||||||
|
@ -108,6 +108,7 @@ func Start(conf Config, authZ authz.Config, systemDefaults sd.SystemDefaults, co
|
|||||||
PrivacyPolicyProvider: queries,
|
PrivacyPolicyProvider: queries,
|
||||||
LabelPolicyProvider: queries,
|
LabelPolicyProvider: queries,
|
||||||
Command: command,
|
Command: command,
|
||||||
|
Query: queries,
|
||||||
OrgViewProvider: queries,
|
OrgViewProvider: queries,
|
||||||
AuthRequests: authReq,
|
AuthRequests: authReq,
|
||||||
View: view,
|
View: view,
|
||||||
@ -119,7 +120,6 @@ func Start(conf Config, authZ authz.Config, systemDefaults sd.SystemDefaults, co
|
|||||||
IDPProviderViewProvider: view,
|
IDPProviderViewProvider: view,
|
||||||
LockoutPolicyViewProvider: queries,
|
LockoutPolicyViewProvider: queries,
|
||||||
LoginPolicyViewProvider: queries,
|
LoginPolicyViewProvider: queries,
|
||||||
Query: queries,
|
|
||||||
UserGrantProvider: queryView,
|
UserGrantProvider: queryView,
|
||||||
ProjectProvider: queryView,
|
ProjectProvider: queryView,
|
||||||
ApplicationProvider: queries,
|
ApplicationProvider: queries,
|
||||||
|
@ -1,69 +0,0 @@
|
|||||||
package view
|
|
||||||
|
|
||||||
import (
|
|
||||||
"github.com/caos/zitadel/internal/errors"
|
|
||||||
"github.com/caos/zitadel/internal/eventstore/v1/models"
|
|
||||||
"github.com/caos/zitadel/internal/iam/repository/view"
|
|
||||||
"github.com/caos/zitadel/internal/iam/repository/view/model"
|
|
||||||
global_view "github.com/caos/zitadel/internal/view/repository"
|
|
||||||
)
|
|
||||||
|
|
||||||
const (
|
|
||||||
customTextTable = "auth.custom_texts"
|
|
||||||
)
|
|
||||||
|
|
||||||
func (v *View) CustomTextByIDs(aggregateID, template, lang, key string) (*model.CustomTextView, error) {
|
|
||||||
return view.CustomTextByIDs(v.Db, customTextTable, aggregateID, template, lang, key)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (v *View) CustomTextsByAggregateIDAndTemplateAndLand(aggregateID, template, lang string) ([]*model.CustomTextView, error) {
|
|
||||||
return view.GetCustomTexts(v.Db, customTextTable, aggregateID, template, lang)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (v *View) CustomTextsByAggregateIDAndTemplate(aggregateID, template string) ([]*model.CustomTextView, error) {
|
|
||||||
return view.GetCustomTextsByAggregateIDAndTemplate(v.Db, customTextTable, aggregateID, template)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (v *View) PutCustomText(template *model.CustomTextView, event *models.Event) error {
|
|
||||||
err := view.PutCustomText(v.Db, customTextTable, template)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
return v.ProcessedCustomTextSequence(event)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (v *View) DeleteCustomText(aggregateID, textType, lang, key string, event *models.Event) error {
|
|
||||||
err := view.DeleteCustomText(v.Db, customTextTable, aggregateID, textType, lang, key)
|
|
||||||
if err != nil && !errors.IsNotFound(err) {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
return v.ProcessedCustomTextSequence(event)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (v *View) DeleteCustomTextTemplate(aggregateID, textType, lang string, event *models.Event) error {
|
|
||||||
err := view.DeleteCustomTextTemplate(v.Db, customTextTable, aggregateID, textType, lang)
|
|
||||||
if err != nil && !errors.IsNotFound(err) {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
return v.ProcessedCustomTextSequence(event)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (v *View) GetLatestCustomTextSequence() (*global_view.CurrentSequence, error) {
|
|
||||||
return v.latestSequence(customTextTable)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (v *View) ProcessedCustomTextSequence(event *models.Event) error {
|
|
||||||
return v.saveCurrentSequence(customTextTable, event)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (v *View) UpdateCustomTextSpoolerRunTimestamp() error {
|
|
||||||
return v.updateSpoolerRunSequence(customTextTable)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (v *View) GetLatestCustomTextFailedEvent(sequence uint64) (*global_view.FailedEvent, error) {
|
|
||||||
return v.latestFailedEvent(customTextTable, sequence)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (v *View) ProcessedCustomTextFailedEvent(failedEvent *global_view.FailedEvent) error {
|
|
||||||
return v.saveFailedEvent(failedEvent)
|
|
||||||
}
|
|
@ -3,12 +3,11 @@ package command
|
|||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
|
||||||
"golang.org/x/text/language"
|
|
||||||
|
|
||||||
"github.com/caos/zitadel/internal/domain"
|
"github.com/caos/zitadel/internal/domain"
|
||||||
caos_errs "github.com/caos/zitadel/internal/errors"
|
caos_errs "github.com/caos/zitadel/internal/errors"
|
||||||
"github.com/caos/zitadel/internal/eventstore"
|
"github.com/caos/zitadel/internal/eventstore"
|
||||||
"github.com/caos/zitadel/internal/repository/iam"
|
"github.com/caos/zitadel/internal/repository/iam"
|
||||||
|
"golang.org/x/text/language"
|
||||||
)
|
)
|
||||||
|
|
||||||
func (c *Commands) SetDefaultMessageText(ctx context.Context, messageText *domain.CustomMessageText) (*domain.ObjectDetails, error) {
|
func (c *Commands) SetDefaultMessageText(ctx context.Context, messageText *domain.CustomMessageText) (*domain.ObjectDetails, error) {
|
||||||
@ -39,25 +38,53 @@ func (c *Commands) setDefaultMessageText(ctx context.Context, iamAgg *eventstore
|
|||||||
}
|
}
|
||||||
events := make([]eventstore.EventPusher, 0)
|
events := make([]eventstore.EventPusher, 0)
|
||||||
if existingMessageText.Greeting != msg.Greeting {
|
if existingMessageText.Greeting != msg.Greeting {
|
||||||
events = append(events, iam.NewCustomTextSetEvent(ctx, iamAgg, msg.MessageTextType, domain.MessageGreeting, msg.Greeting, msg.Language))
|
if msg.Greeting != "" {
|
||||||
|
events = append(events, iam.NewCustomTextSetEvent(ctx, iamAgg, msg.MessageTextType, domain.MessageGreeting, msg.Greeting, msg.Language))
|
||||||
|
} else {
|
||||||
|
events = append(events, iam.NewCustomTextRemovedEvent(ctx, iamAgg, msg.MessageTextType, domain.MessageGreeting, msg.Language))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if existingMessageText.Subject != msg.Subject {
|
if existingMessageText.Subject != msg.Subject {
|
||||||
events = append(events, iam.NewCustomTextSetEvent(ctx, iamAgg, msg.MessageTextType, domain.MessageSubject, msg.Subject, msg.Language))
|
if msg.Subject != "" {
|
||||||
|
events = append(events, iam.NewCustomTextSetEvent(ctx, iamAgg, msg.MessageTextType, domain.MessageSubject, msg.Subject, msg.Language))
|
||||||
|
} else {
|
||||||
|
events = append(events, iam.NewCustomTextRemovedEvent(ctx, iamAgg, msg.MessageTextType, domain.MessageSubject, msg.Language))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if existingMessageText.Title != msg.Title {
|
if existingMessageText.Title != msg.Title {
|
||||||
events = append(events, iam.NewCustomTextSetEvent(ctx, iamAgg, msg.MessageTextType, domain.MessageTitle, msg.Title, msg.Language))
|
if msg.Title != "" {
|
||||||
|
events = append(events, iam.NewCustomTextSetEvent(ctx, iamAgg, msg.MessageTextType, domain.MessageTitle, msg.Title, msg.Language))
|
||||||
|
} else {
|
||||||
|
events = append(events, iam.NewCustomTextRemovedEvent(ctx, iamAgg, msg.MessageTextType, domain.MessageTitle, msg.Language))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if existingMessageText.PreHeader != msg.PreHeader {
|
if existingMessageText.PreHeader != msg.PreHeader {
|
||||||
events = append(events, iam.NewCustomTextSetEvent(ctx, iamAgg, msg.MessageTextType, domain.MessagePreHeader, msg.PreHeader, msg.Language))
|
if msg.PreHeader != "" {
|
||||||
|
events = append(events, iam.NewCustomTextSetEvent(ctx, iamAgg, msg.MessageTextType, domain.MessagePreHeader, msg.PreHeader, msg.Language))
|
||||||
|
} else {
|
||||||
|
events = append(events, iam.NewCustomTextRemovedEvent(ctx, iamAgg, msg.MessageTextType, domain.MessagePreHeader, msg.Language))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if existingMessageText.Text != msg.Text {
|
if existingMessageText.Text != msg.Text {
|
||||||
events = append(events, iam.NewCustomTextSetEvent(ctx, iamAgg, msg.MessageTextType, domain.MessageText, msg.Text, msg.Language))
|
if msg.Text != "" {
|
||||||
|
events = append(events, iam.NewCustomTextSetEvent(ctx, iamAgg, msg.MessageTextType, domain.MessageText, msg.Text, msg.Language))
|
||||||
|
} else {
|
||||||
|
events = append(events, iam.NewCustomTextRemovedEvent(ctx, iamAgg, msg.MessageTextType, domain.MessageText, msg.Language))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if existingMessageText.ButtonText != msg.ButtonText {
|
if existingMessageText.ButtonText != msg.ButtonText {
|
||||||
events = append(events, iam.NewCustomTextSetEvent(ctx, iamAgg, msg.MessageTextType, domain.MessageButtonText, msg.ButtonText, msg.Language))
|
if msg.ButtonText != "" {
|
||||||
|
events = append(events, iam.NewCustomTextSetEvent(ctx, iamAgg, msg.MessageTextType, domain.MessageButtonText, msg.ButtonText, msg.Language))
|
||||||
|
} else {
|
||||||
|
events = append(events, iam.NewCustomTextRemovedEvent(ctx, iamAgg, msg.MessageTextType, domain.MessageButtonText, msg.Language))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if existingMessageText.FooterText != msg.FooterText {
|
if existingMessageText.FooterText != msg.FooterText {
|
||||||
events = append(events, iam.NewCustomTextSetEvent(ctx, iamAgg, msg.MessageTextType, domain.MessageFooterText, msg.FooterText, msg.Language))
|
if msg.FooterText != "" {
|
||||||
|
events = append(events, iam.NewCustomTextSetEvent(ctx, iamAgg, msg.MessageTextType, domain.MessageFooterText, msg.FooterText, msg.Language))
|
||||||
|
} else {
|
||||||
|
events = append(events, iam.NewCustomTextRemovedEvent(ctx, iamAgg, msg.MessageTextType, domain.MessageFooterText, msg.Language))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return events, existingMessageText, nil
|
return events, existingMessageText, nil
|
||||||
}
|
}
|
||||||
|
@ -1,46 +0,0 @@
|
|||||||
package model
|
|
||||||
|
|
||||||
import (
|
|
||||||
"github.com/caos/zitadel/internal/domain"
|
|
||||||
"time"
|
|
||||||
)
|
|
||||||
|
|
||||||
type MailTemplateView struct {
|
|
||||||
AggregateID string
|
|
||||||
Template []byte
|
|
||||||
Default bool
|
|
||||||
|
|
||||||
CreationDate time.Time
|
|
||||||
ChangeDate time.Time
|
|
||||||
Sequence uint64
|
|
||||||
}
|
|
||||||
|
|
||||||
type MailTemplateSearchRequest struct {
|
|
||||||
Offset uint64
|
|
||||||
Limit uint64
|
|
||||||
SortingColumn MailTemplateSearchKey
|
|
||||||
Asc bool
|
|
||||||
Queries []*MailTemplateSearchQuery
|
|
||||||
}
|
|
||||||
|
|
||||||
type MailTemplateSearchKey int32
|
|
||||||
|
|
||||||
const (
|
|
||||||
MailTemplateSearchKeyUnspecified MailTemplateSearchKey = iota
|
|
||||||
MailTemplateSearchKeyAggregateID
|
|
||||||
)
|
|
||||||
|
|
||||||
type MailTemplateSearchQuery struct {
|
|
||||||
Key MailTemplateSearchKey
|
|
||||||
Method domain.SearchMethod
|
|
||||||
Value interface{}
|
|
||||||
}
|
|
||||||
|
|
||||||
type MailTemplateSearchResponse struct {
|
|
||||||
Offset uint64
|
|
||||||
Limit uint64
|
|
||||||
TotalResult uint64
|
|
||||||
Result []*MailTemplateView
|
|
||||||
Sequence uint64
|
|
||||||
Timestamp time.Time
|
|
||||||
}
|
|
@ -1,32 +0,0 @@
|
|||||||
package view
|
|
||||||
|
|
||||||
import (
|
|
||||||
"github.com/caos/zitadel/internal/domain"
|
|
||||||
caos_errs "github.com/caos/zitadel/internal/errors"
|
|
||||||
iam_model "github.com/caos/zitadel/internal/iam/model"
|
|
||||||
"github.com/caos/zitadel/internal/iam/repository/view/model"
|
|
||||||
"github.com/caos/zitadel/internal/view/repository"
|
|
||||||
"github.com/jinzhu/gorm"
|
|
||||||
)
|
|
||||||
|
|
||||||
func GetMailTemplateByAggregateID(db *gorm.DB, table, aggregateID string) (*model.MailTemplateView, error) {
|
|
||||||
template := new(model.MailTemplateView)
|
|
||||||
aggregateIDQuery := &model.MailTemplateSearchQuery{Key: iam_model.MailTemplateSearchKeyAggregateID, Value: aggregateID, Method: domain.SearchMethodEquals}
|
|
||||||
query := repository.PrepareGetByQuery(table, aggregateIDQuery)
|
|
||||||
err := query(db, template)
|
|
||||||
if caos_errs.IsNotFound(err) {
|
|
||||||
return nil, caos_errs.ThrowNotFound(nil, "VIEW-iPnmU", "Errors.IAM.MailTemplate.NotExisting")
|
|
||||||
}
|
|
||||||
return template, err
|
|
||||||
}
|
|
||||||
|
|
||||||
func PutMailTemplate(db *gorm.DB, table string, template *model.MailTemplateView) error {
|
|
||||||
save := repository.PrepareSave(table)
|
|
||||||
return save(db, template)
|
|
||||||
}
|
|
||||||
|
|
||||||
func DeleteMailTemplate(db *gorm.DB, table, aggregateID string) error {
|
|
||||||
delete := repository.PrepareDeleteByKey(table, model.MailTemplateSearchKey(iam_model.MailTemplateSearchKeyAggregateID), aggregateID)
|
|
||||||
|
|
||||||
return delete(db)
|
|
||||||
}
|
|
@ -38,30 +38,6 @@ type CustomTextView struct {
|
|||||||
Sequence uint64 `json:"-" gorm:"column:sequence"`
|
Sequence uint64 `json:"-" gorm:"column:sequence"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func CustomTextViewsToDomain(texts []*CustomTextView) []*domain.CustomText {
|
|
||||||
result := make([]*domain.CustomText, len(texts))
|
|
||||||
for i, text := range texts {
|
|
||||||
result[i] = CustomTextViewToDomain(text)
|
|
||||||
}
|
|
||||||
return result
|
|
||||||
}
|
|
||||||
|
|
||||||
func CustomTextViewToDomain(text *CustomTextView) *domain.CustomText {
|
|
||||||
lang := language.Make(text.Language)
|
|
||||||
return &domain.CustomText{
|
|
||||||
ObjectRoot: models.ObjectRoot{
|
|
||||||
AggregateID: text.AggregateID,
|
|
||||||
Sequence: text.Sequence,
|
|
||||||
CreationDate: text.CreationDate,
|
|
||||||
ChangeDate: text.ChangeDate,
|
|
||||||
},
|
|
||||||
Template: text.Template,
|
|
||||||
Language: lang,
|
|
||||||
Key: text.Key,
|
|
||||||
Text: text.Text,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (i *CustomTextView) AppendEvent(event *models.Event) (err error) {
|
func (i *CustomTextView) AppendEvent(event *models.Event) (err error) {
|
||||||
i.Sequence = event.Sequence
|
i.Sequence = event.Sequence
|
||||||
switch event.Type {
|
switch event.Type {
|
||||||
@ -97,46 +73,6 @@ func (r *CustomTextView) IsMessageTemplate() bool {
|
|||||||
r.Template == domain.PasswordlessRegistrationMessageType
|
r.Template == domain.PasswordlessRegistrationMessageType
|
||||||
}
|
}
|
||||||
|
|
||||||
func CustomTextViewsToMessageDomain(aggregateID, lang string, texts []*CustomTextView) *domain.CustomMessageText {
|
|
||||||
langTag := language.Make(lang)
|
|
||||||
result := &domain.CustomMessageText{
|
|
||||||
ObjectRoot: models.ObjectRoot{
|
|
||||||
AggregateID: aggregateID,
|
|
||||||
},
|
|
||||||
Language: langTag,
|
|
||||||
}
|
|
||||||
for _, text := range texts {
|
|
||||||
if text.CreationDate.Before(result.CreationDate) {
|
|
||||||
result.CreationDate = text.CreationDate
|
|
||||||
}
|
|
||||||
if text.ChangeDate.After(result.ChangeDate) {
|
|
||||||
result.ChangeDate = text.ChangeDate
|
|
||||||
}
|
|
||||||
if text.Key == domain.MessageTitle {
|
|
||||||
result.Title = text.Text
|
|
||||||
}
|
|
||||||
if text.Key == domain.MessagePreHeader {
|
|
||||||
result.PreHeader = text.Text
|
|
||||||
}
|
|
||||||
if text.Key == domain.MessageSubject {
|
|
||||||
result.Subject = text.Text
|
|
||||||
}
|
|
||||||
if text.Key == domain.MessageGreeting {
|
|
||||||
result.Greeting = text.Text
|
|
||||||
}
|
|
||||||
if text.Key == domain.MessageText {
|
|
||||||
result.Text = text.Text
|
|
||||||
}
|
|
||||||
if text.Key == domain.MessageButtonText {
|
|
||||||
result.ButtonText = text.Text
|
|
||||||
}
|
|
||||||
if text.Key == domain.MessageFooterText {
|
|
||||||
result.FooterText = text.Text
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return result
|
|
||||||
}
|
|
||||||
|
|
||||||
func CustomTextViewsToLoginDomain(aggregateID, lang string, texts []*CustomTextView) *domain.CustomLoginText {
|
func CustomTextViewsToLoginDomain(aggregateID, lang string, texts []*CustomTextView) *domain.CustomLoginText {
|
||||||
langTag := language.Make(lang)
|
langTag := language.Make(lang)
|
||||||
result := &domain.CustomLoginText{
|
result := &domain.CustomLoginText{
|
||||||
|
@ -1,80 +0,0 @@
|
|||||||
package model
|
|
||||||
|
|
||||||
import (
|
|
||||||
"encoding/json"
|
|
||||||
"time"
|
|
||||||
|
|
||||||
org_es_model "github.com/caos/zitadel/internal/org/repository/eventsourcing/model"
|
|
||||||
|
|
||||||
es_model "github.com/caos/zitadel/internal/iam/repository/eventsourcing/model"
|
|
||||||
|
|
||||||
"github.com/caos/logging"
|
|
||||||
caos_errs "github.com/caos/zitadel/internal/errors"
|
|
||||||
"github.com/caos/zitadel/internal/eventstore/v1/models"
|
|
||||||
"github.com/caos/zitadel/internal/iam/model"
|
|
||||||
)
|
|
||||||
|
|
||||||
const (
|
|
||||||
MailTemplateKeyAggregateID = "aggregate_id"
|
|
||||||
)
|
|
||||||
|
|
||||||
type MailTemplateView struct {
|
|
||||||
AggregateID string `json:"-" gorm:"column:aggregate_id;primary_key"`
|
|
||||||
CreationDate time.Time `json:"-" gorm:"column:creation_date"`
|
|
||||||
ChangeDate time.Time `json:"-" gorm:"column:change_date"`
|
|
||||||
State int32 `json:"-" gorm:"column:mail_template_state"`
|
|
||||||
|
|
||||||
Template []byte `json:"template" gorm:"column:template"`
|
|
||||||
Default bool `json:"-" gorm:"-"`
|
|
||||||
|
|
||||||
Sequence uint64 `json:"-" gorm:"column:sequence"`
|
|
||||||
}
|
|
||||||
|
|
||||||
func MailTemplateViewFromModel(template *model.MailTemplateView) *MailTemplateView {
|
|
||||||
return &MailTemplateView{
|
|
||||||
AggregateID: template.AggregateID,
|
|
||||||
Sequence: template.Sequence,
|
|
||||||
CreationDate: template.CreationDate,
|
|
||||||
ChangeDate: template.ChangeDate,
|
|
||||||
Template: template.Template,
|
|
||||||
Default: template.Default,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func MailTemplateViewToModel(template *MailTemplateView) *model.MailTemplateView {
|
|
||||||
return &model.MailTemplateView{
|
|
||||||
AggregateID: template.AggregateID,
|
|
||||||
Sequence: template.Sequence,
|
|
||||||
CreationDate: template.CreationDate,
|
|
||||||
ChangeDate: template.ChangeDate,
|
|
||||||
Template: template.Template,
|
|
||||||
Default: template.Default,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (i *MailTemplateView) AppendEvent(event *models.Event) (err error) {
|
|
||||||
i.Sequence = event.Sequence
|
|
||||||
i.ChangeDate = event.CreationDate
|
|
||||||
switch event.Type {
|
|
||||||
case es_model.MailTemplateAdded, org_es_model.MailTemplateAdded:
|
|
||||||
i.setRootData(event)
|
|
||||||
i.CreationDate = event.CreationDate
|
|
||||||
err = i.SetData(event)
|
|
||||||
case es_model.MailTemplateChanged, org_es_model.MailTemplateChanged:
|
|
||||||
i.ChangeDate = event.CreationDate
|
|
||||||
err = i.SetData(event)
|
|
||||||
}
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
func (r *MailTemplateView) setRootData(event *models.Event) {
|
|
||||||
r.AggregateID = event.AggregateID
|
|
||||||
}
|
|
||||||
|
|
||||||
func (r *MailTemplateView) SetData(event *models.Event) error {
|
|
||||||
if err := json.Unmarshal(event.Data, r); err != nil {
|
|
||||||
logging.Log("MODEL-YDZmZ").WithError(err).Error("could not unmarshal event data")
|
|
||||||
return caos_errs.ThrowInternal(err, "MODEL-sKWwO", "Could not unmarshal data")
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
@ -1,59 +0,0 @@
|
|||||||
package model
|
|
||||||
|
|
||||||
import (
|
|
||||||
"github.com/caos/zitadel/internal/domain"
|
|
||||||
iam_model "github.com/caos/zitadel/internal/iam/model"
|
|
||||||
"github.com/caos/zitadel/internal/view/repository"
|
|
||||||
)
|
|
||||||
|
|
||||||
type MailTemplateSearchRequest iam_model.MailTemplateSearchRequest
|
|
||||||
type MailTemplateSearchQuery iam_model.MailTemplateSearchQuery
|
|
||||||
type MailTemplateSearchKey iam_model.MailTemplateSearchKey
|
|
||||||
|
|
||||||
func (req MailTemplateSearchRequest) GetLimit() uint64 {
|
|
||||||
return req.Limit
|
|
||||||
}
|
|
||||||
|
|
||||||
func (req MailTemplateSearchRequest) GetOffset() uint64 {
|
|
||||||
return req.Offset
|
|
||||||
}
|
|
||||||
|
|
||||||
func (req MailTemplateSearchRequest) GetSortingColumn() repository.ColumnKey {
|
|
||||||
if req.SortingColumn == iam_model.MailTemplateSearchKeyUnspecified {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
return MailTemplateSearchKey(req.SortingColumn)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (req MailTemplateSearchRequest) GetAsc() bool {
|
|
||||||
return req.Asc
|
|
||||||
}
|
|
||||||
|
|
||||||
func (req MailTemplateSearchRequest) GetQueries() []repository.SearchQuery {
|
|
||||||
result := make([]repository.SearchQuery, len(req.Queries))
|
|
||||||
for i, q := range req.Queries {
|
|
||||||
result[i] = MailTemplateSearchQuery{Key: q.Key, Value: q.Value, Method: q.Method}
|
|
||||||
}
|
|
||||||
return result
|
|
||||||
}
|
|
||||||
|
|
||||||
func (req MailTemplateSearchQuery) GetKey() repository.ColumnKey {
|
|
||||||
return MailTemplateSearchKey(req.Key)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (req MailTemplateSearchQuery) GetMethod() domain.SearchMethod {
|
|
||||||
return req.Method
|
|
||||||
}
|
|
||||||
|
|
||||||
func (req MailTemplateSearchQuery) GetValue() interface{} {
|
|
||||||
return req.Value
|
|
||||||
}
|
|
||||||
|
|
||||||
func (key MailTemplateSearchKey) ToColumnName() string {
|
|
||||||
switch iam_model.MailTemplateSearchKey(key) {
|
|
||||||
case iam_model.MailTemplateSearchKeyAggregateID:
|
|
||||||
return MailTemplateKeyAggregateID
|
|
||||||
default:
|
|
||||||
return ""
|
|
||||||
}
|
|
||||||
}
|
|
@ -3,7 +3,6 @@ package eventstore
|
|||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"fmt"
|
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
"net/http"
|
"net/http"
|
||||||
"os"
|
"os"
|
||||||
@ -14,7 +13,6 @@ import (
|
|||||||
"github.com/caos/logging"
|
"github.com/caos/logging"
|
||||||
"github.com/golang/protobuf/ptypes"
|
"github.com/golang/protobuf/ptypes"
|
||||||
"golang.org/x/text/language"
|
"golang.org/x/text/language"
|
||||||
"sigs.k8s.io/yaml"
|
|
||||||
|
|
||||||
"github.com/caos/zitadel/internal/api/authz"
|
"github.com/caos/zitadel/internal/api/authz"
|
||||||
"github.com/caos/zitadel/internal/config/systemdefaults"
|
"github.com/caos/zitadel/internal/config/systemdefaults"
|
||||||
@ -206,134 +204,6 @@ func (repo *OrgRepository) SearchIDPProviders(ctx context.Context, request *iam_
|
|||||||
return result, nil
|
return result, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (repo *OrgRepository) GetDefaultMailTemplate(ctx context.Context) (*iam_model.MailTemplateView, error) {
|
|
||||||
template, err := repo.View.MailTemplateByAggregateID(repo.SystemDefaults.IamID)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
template.Default = true
|
|
||||||
return iam_view_model.MailTemplateViewToModel(template), err
|
|
||||||
}
|
|
||||||
|
|
||||||
func (repo *OrgRepository) GetMailTemplate(ctx context.Context) (*iam_model.MailTemplateView, error) {
|
|
||||||
template, err := repo.View.MailTemplateByAggregateID(authz.GetCtxData(ctx).OrgID)
|
|
||||||
if errors.IsNotFound(err) {
|
|
||||||
template, err = repo.View.MailTemplateByAggregateID(repo.SystemDefaults.IamID)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
template.Default = true
|
|
||||||
}
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
return iam_view_model.MailTemplateViewToModel(template), err
|
|
||||||
}
|
|
||||||
|
|
||||||
func (repo *OrgRepository) GetDefaultMessageText(ctx context.Context, textType, lang string) (*domain.CustomMessageText, error) {
|
|
||||||
repo.mutex.Lock()
|
|
||||||
defer repo.mutex.Unlock()
|
|
||||||
var err error
|
|
||||||
contents, ok := repo.NotificationTranslationFileContents[lang]
|
|
||||||
if !ok {
|
|
||||||
contents, err = repo.readTranslationFile(repo.NotificationDir, fmt.Sprintf("/i18n/%s.yaml", lang))
|
|
||||||
if errors.IsNotFound(err) {
|
|
||||||
contents, err = repo.readTranslationFile(repo.NotificationDir, fmt.Sprintf("/i18n/%s.yaml", repo.SystemDefaults.DefaultLanguage.String()))
|
|
||||||
}
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
repo.NotificationTranslationFileContents[lang] = contents
|
|
||||||
}
|
|
||||||
notificationTextMap := make(map[string]interface{})
|
|
||||||
if err := yaml.Unmarshal(contents, ¬ificationTextMap); err != nil {
|
|
||||||
return nil, errors.ThrowInternal(err, "TEXT-093sd", "Errors.TranslationFile.ReadError")
|
|
||||||
}
|
|
||||||
texts, err := repo.View.CustomTextsByAggregateIDAndTemplateAndLand(repo.SystemDefaults.IamID, textType, lang)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
for _, text := range texts {
|
|
||||||
messageTextMap, ok := notificationTextMap[textType].(map[string]interface{})
|
|
||||||
if !ok {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
messageTextMap[text.Key] = text.Text
|
|
||||||
}
|
|
||||||
jsonbody, err := json.Marshal(notificationTextMap)
|
|
||||||
if err != nil {
|
|
||||||
return nil, errors.ThrowInternal(err, "TEXT-02m8f", "Errors.TranslationFile.MergeError")
|
|
||||||
}
|
|
||||||
notificationText := new(domain.MessageTexts)
|
|
||||||
if err := json.Unmarshal(jsonbody, ¬ificationText); err != nil {
|
|
||||||
return nil, errors.ThrowInternal(err, "TEXT-20ops", "Errors.TranslationFile.MergeError")
|
|
||||||
}
|
|
||||||
result := notificationText.GetMessageTextByType(textType)
|
|
||||||
result.Default = true
|
|
||||||
return result, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (repo *OrgRepository) GetMessageText(ctx context.Context, orgID, textType, lang string) (*domain.CustomMessageText, error) {
|
|
||||||
texts, err := repo.View.CustomTextsByAggregateIDAndTemplateAndLand(orgID, textType, lang)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
if len(texts) == 0 {
|
|
||||||
return repo.GetDefaultMessageText(ctx, textType, lang)
|
|
||||||
}
|
|
||||||
return iam_view_model.CustomTextViewsToMessageDomain(repo.SystemDefaults.IamID, lang, texts), err
|
|
||||||
}
|
|
||||||
|
|
||||||
func (repo *OrgRepository) GetDefaultLoginTexts(ctx context.Context, lang string) (*domain.CustomLoginText, error) {
|
|
||||||
repo.mutex.Lock()
|
|
||||||
defer repo.mutex.Unlock()
|
|
||||||
contents, ok := repo.LoginTranslationFileContents[lang]
|
|
||||||
var err error
|
|
||||||
if !ok {
|
|
||||||
contents, err = repo.readTranslationFile(repo.LoginDir, fmt.Sprintf("/i18n/%s.yaml", lang))
|
|
||||||
if errors.IsNotFound(err) {
|
|
||||||
contents, err = repo.readTranslationFile(repo.LoginDir, fmt.Sprintf("/i18n/%s.yaml", repo.SystemDefaults.DefaultLanguage.String()))
|
|
||||||
}
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
repo.LoginTranslationFileContents[lang] = contents
|
|
||||||
}
|
|
||||||
loginTextMap := make(map[string]interface{})
|
|
||||||
if err := yaml.Unmarshal(contents, &loginTextMap); err != nil {
|
|
||||||
return nil, errors.ThrowInternal(err, "TEXT-l0fse", "Errors.TranslationFile.ReadError")
|
|
||||||
}
|
|
||||||
texts, err := repo.View.CustomTextsByAggregateIDAndTemplateAndLand(repo.SystemDefaults.IamID, domain.LoginCustomText, lang)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
for _, text := range texts {
|
|
||||||
keys := strings.Split(text.Key, ".")
|
|
||||||
screenTextMap, ok := loginTextMap[keys[0]].(map[string]interface{})
|
|
||||||
if !ok {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
screenTextMap[keys[1]] = text.Text
|
|
||||||
}
|
|
||||||
jsonbody, err := json.Marshal(loginTextMap)
|
|
||||||
if err != nil {
|
|
||||||
return nil, errors.ThrowInternal(err, "TEXT-2n8fs", "Errors.TranslationFile.MergeError")
|
|
||||||
}
|
|
||||||
loginText := new(domain.CustomLoginText)
|
|
||||||
if err := json.Unmarshal(jsonbody, &loginText); err != nil {
|
|
||||||
return nil, errors.ThrowInternal(err, "TEXT-2n8fs", "Errors.TranslationFile.MergeError")
|
|
||||||
}
|
|
||||||
return loginText, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (repo *OrgRepository) GetLoginTexts(ctx context.Context, orgID, lang string) (*domain.CustomLoginText, error) {
|
|
||||||
texts, err := repo.View.CustomTextsByAggregateIDAndTemplateAndLand(orgID, domain.LoginCustomText, lang)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
return iam_view_model.CustomTextViewsToLoginDomain(repo.SystemDefaults.IamID, lang, texts), err
|
|
||||||
}
|
|
||||||
|
|
||||||
func (repo *OrgRepository) getOrgChanges(ctx context.Context, orgID string, lastSequence uint64, limit uint64, sortAscending bool, auditLogRetention time.Duration) (*org_model.OrgChanges, error) {
|
func (repo *OrgRepository) getOrgChanges(ctx context.Context, orgID string, lastSequence uint64, limit uint64, sortAscending bool, auditLogRetention time.Duration) (*org_model.OrgChanges, error) {
|
||||||
query := org_view.ChangesQuery(orgID, lastSequence, limit, sortAscending, auditLogRetention)
|
query := org_view.ChangesQuery(orgID, lastSequence, limit, sortAscending, auditLogRetention)
|
||||||
|
|
||||||
|
@ -1,132 +0,0 @@
|
|||||||
package handler
|
|
||||||
|
|
||||||
import (
|
|
||||||
"github.com/caos/logging"
|
|
||||||
caos_errs "github.com/caos/zitadel/internal/errors"
|
|
||||||
"github.com/caos/zitadel/internal/eventstore/v1"
|
|
||||||
es_models "github.com/caos/zitadel/internal/eventstore/v1/models"
|
|
||||||
"github.com/caos/zitadel/internal/eventstore/v1/query"
|
|
||||||
"github.com/caos/zitadel/internal/eventstore/v1/spooler"
|
|
||||||
iam_es_model "github.com/caos/zitadel/internal/iam/repository/eventsourcing/model"
|
|
||||||
iam_model "github.com/caos/zitadel/internal/iam/repository/view/model"
|
|
||||||
"github.com/caos/zitadel/internal/org/repository/eventsourcing/model"
|
|
||||||
)
|
|
||||||
|
|
||||||
type CustomText struct {
|
|
||||||
handler
|
|
||||||
subscription *v1.Subscription
|
|
||||||
}
|
|
||||||
|
|
||||||
func newCustomText(handler handler) *CustomText {
|
|
||||||
h := &CustomText{
|
|
||||||
handler: handler,
|
|
||||||
}
|
|
||||||
|
|
||||||
h.subscribe()
|
|
||||||
|
|
||||||
return h
|
|
||||||
}
|
|
||||||
|
|
||||||
func (m *CustomText) subscribe() {
|
|
||||||
m.subscription = m.es.Subscribe(m.AggregateTypes()...)
|
|
||||||
go func() {
|
|
||||||
for event := range m.subscription.Events {
|
|
||||||
query.ReduceEvent(m, event)
|
|
||||||
}
|
|
||||||
}()
|
|
||||||
}
|
|
||||||
|
|
||||||
const (
|
|
||||||
customTextTable = "management.custom_texts"
|
|
||||||
)
|
|
||||||
|
|
||||||
func (m *CustomText) ViewModel() string {
|
|
||||||
return customTextTable
|
|
||||||
}
|
|
||||||
|
|
||||||
func (m *CustomText) Subscription() *v1.Subscription {
|
|
||||||
return m.subscription
|
|
||||||
}
|
|
||||||
|
|
||||||
func (_ *CustomText) AggregateTypes() []es_models.AggregateType {
|
|
||||||
return []es_models.AggregateType{model.OrgAggregate, iam_es_model.IAMAggregate}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (p *CustomText) CurrentSequence() (uint64, error) {
|
|
||||||
sequence, err := p.view.GetLatestCustomTextSequence()
|
|
||||||
if err != nil {
|
|
||||||
return 0, err
|
|
||||||
}
|
|
||||||
return sequence.CurrentSequence, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (m *CustomText) EventQuery() (*es_models.SearchQuery, error) {
|
|
||||||
sequence, err := m.view.GetLatestCustomTextSequence()
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
return es_models.NewSearchQuery().
|
|
||||||
AggregateTypeFilter(m.AggregateTypes()...).
|
|
||||||
LatestSequenceFilter(sequence.CurrentSequence), nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (m *CustomText) Reduce(event *es_models.Event) (err error) {
|
|
||||||
switch event.AggregateType {
|
|
||||||
case model.OrgAggregate, iam_es_model.IAMAggregate:
|
|
||||||
err = m.processCustomText(event)
|
|
||||||
}
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
func (m *CustomText) processCustomText(event *es_models.Event) (err error) {
|
|
||||||
customText := new(iam_model.CustomTextView)
|
|
||||||
switch event.Type {
|
|
||||||
case iam_es_model.CustomTextSet, model.CustomTextSet:
|
|
||||||
text := new(iam_model.CustomTextView)
|
|
||||||
err = text.SetData(event)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
customText, err = m.view.CustomTextByIDs(event.AggregateID, text.Template, text.Key, text.Language)
|
|
||||||
if err != nil && !caos_errs.IsNotFound(err) {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
if caos_errs.IsNotFound(err) {
|
|
||||||
err = nil
|
|
||||||
customText = new(iam_model.CustomTextView)
|
|
||||||
customText.Language = text.Language
|
|
||||||
customText.Template = text.Template
|
|
||||||
customText.CreationDate = event.CreationDate
|
|
||||||
}
|
|
||||||
err = customText.AppendEvent(event)
|
|
||||||
case iam_es_model.CustomTextRemoved, model.CustomTextRemoved:
|
|
||||||
text := new(iam_model.CustomTextView)
|
|
||||||
err = text.SetData(event)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
return m.view.DeleteCustomText(event.AggregateID, text.Template, text.Language, text.Key, event)
|
|
||||||
case iam_es_model.CustomTextMessageRemoved, model.CustomTextMessageRemoved:
|
|
||||||
text := new(iam_model.CustomTextView)
|
|
||||||
err = text.SetData(event)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
return m.view.DeleteCustomTextTemplate(event.AggregateID, text.Template, text.Language, event)
|
|
||||||
default:
|
|
||||||
return m.view.ProcessedCustomTextSequence(event)
|
|
||||||
}
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
return m.view.PutCustomText(customText, event)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (m *CustomText) OnError(event *es_models.Event, err error) error {
|
|
||||||
logging.LogWithFields("SPOOL-3m912", "id", event.AggregateID).WithError(err).Warn("something went wrong in custom text handler")
|
|
||||||
return spooler.HandleError(event, err, m.view.GetLatestCustomTextFailedEvent, m.view.ProcessedCustomTextFailedEvent, m.view.ProcessedCustomTextSequence, m.errorCountUntilSkip)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (o *CustomText) OnSuccess() error {
|
|
||||||
return spooler.HandleSuccess(o.view.UpdateCustomTextSpoolerRunTimestamp)
|
|
||||||
}
|
|
@ -50,12 +50,6 @@ func Register(configs Configs, bulkLimit, errorCount uint64, view *view.View, es
|
|||||||
newExternalIDP(
|
newExternalIDP(
|
||||||
handler{view, bulkLimit, configs.cycleDuration("ExternalIDP"), errorCount, es},
|
handler{view, bulkLimit, configs.cycleDuration("ExternalIDP"), errorCount, es},
|
||||||
defaults),
|
defaults),
|
||||||
newMailTemplate(
|
|
||||||
handler{view, bulkLimit, configs.cycleDuration("MailTemplate"), errorCount, es}),
|
|
||||||
newMessageText(
|
|
||||||
handler{view, bulkLimit, configs.cycleDuration("MessageText"), errorCount, es}),
|
|
||||||
newCustomText(
|
|
||||||
handler{view, bulkLimit, configs.cycleDuration("CustomText"), errorCount, es}),
|
|
||||||
newMetadata(
|
newMetadata(
|
||||||
handler{view, bulkLimit, configs.cycleDuration("Metadata"), errorCount, es}),
|
handler{view, bulkLimit, configs.cycleDuration("Metadata"), errorCount, es}),
|
||||||
}
|
}
|
||||||
|
@ -1,110 +0,0 @@
|
|||||||
package handler
|
|
||||||
|
|
||||||
import (
|
|
||||||
"github.com/caos/logging"
|
|
||||||
"github.com/caos/zitadel/internal/eventstore/v1"
|
|
||||||
iam_es_model "github.com/caos/zitadel/internal/iam/repository/eventsourcing/model"
|
|
||||||
|
|
||||||
es_models "github.com/caos/zitadel/internal/eventstore/v1/models"
|
|
||||||
"github.com/caos/zitadel/internal/eventstore/v1/query"
|
|
||||||
"github.com/caos/zitadel/internal/eventstore/v1/spooler"
|
|
||||||
iam_model "github.com/caos/zitadel/internal/iam/repository/view/model"
|
|
||||||
"github.com/caos/zitadel/internal/org/repository/eventsourcing/model"
|
|
||||||
)
|
|
||||||
|
|
||||||
type MailTemplate struct {
|
|
||||||
handler
|
|
||||||
subscription *v1.Subscription
|
|
||||||
}
|
|
||||||
|
|
||||||
func newMailTemplate(handler handler) *MailTemplate {
|
|
||||||
h := &MailTemplate{
|
|
||||||
handler: handler,
|
|
||||||
}
|
|
||||||
|
|
||||||
h.subscribe()
|
|
||||||
|
|
||||||
return h
|
|
||||||
}
|
|
||||||
|
|
||||||
func (m *MailTemplate) subscribe() {
|
|
||||||
m.subscription = m.es.Subscribe(m.AggregateTypes()...)
|
|
||||||
go func() {
|
|
||||||
for event := range m.subscription.Events {
|
|
||||||
query.ReduceEvent(m, event)
|
|
||||||
}
|
|
||||||
}()
|
|
||||||
}
|
|
||||||
|
|
||||||
const (
|
|
||||||
mailTemplateTable = "management.mail_templates"
|
|
||||||
)
|
|
||||||
|
|
||||||
func (m *MailTemplate) ViewModel() string {
|
|
||||||
return mailTemplateTable
|
|
||||||
}
|
|
||||||
|
|
||||||
func (m *MailTemplate) Subscription() *v1.Subscription {
|
|
||||||
return m.subscription
|
|
||||||
}
|
|
||||||
|
|
||||||
func (_ *MailTemplate) AggregateTypes() []es_models.AggregateType {
|
|
||||||
return []es_models.AggregateType{model.OrgAggregate, iam_es_model.IAMAggregate}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (p *MailTemplate) CurrentSequence() (uint64, error) {
|
|
||||||
sequence, err := p.view.GetLatestMailTemplateSequence()
|
|
||||||
if err != nil {
|
|
||||||
return 0, err
|
|
||||||
}
|
|
||||||
return sequence.CurrentSequence, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (m *MailTemplate) EventQuery() (*es_models.SearchQuery, error) {
|
|
||||||
sequence, err := m.view.GetLatestMailTemplateSequence()
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
return es_models.NewSearchQuery().
|
|
||||||
AggregateTypeFilter(m.AggregateTypes()...).
|
|
||||||
LatestSequenceFilter(sequence.CurrentSequence), nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (m *MailTemplate) Reduce(event *es_models.Event) (err error) {
|
|
||||||
switch event.AggregateType {
|
|
||||||
case model.OrgAggregate, iam_es_model.IAMAggregate:
|
|
||||||
err = m.processMailTemplate(event)
|
|
||||||
}
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
func (m *MailTemplate) processMailTemplate(event *es_models.Event) (err error) {
|
|
||||||
template := new(iam_model.MailTemplateView)
|
|
||||||
switch event.Type {
|
|
||||||
case iam_es_model.MailTemplateAdded, model.MailTemplateAdded:
|
|
||||||
err = template.AppendEvent(event)
|
|
||||||
case iam_es_model.MailTemplateChanged, model.MailTemplateChanged:
|
|
||||||
template, err = m.view.MailTemplateByAggregateID(event.AggregateID)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
err = template.AppendEvent(event)
|
|
||||||
case model.MailTemplateRemoved:
|
|
||||||
return m.view.DeleteMailTemplate(event.AggregateID, event)
|
|
||||||
default:
|
|
||||||
return m.view.ProcessedMailTemplateSequence(event)
|
|
||||||
}
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
return m.view.PutMailTemplate(template, event)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (m *MailTemplate) OnError(event *es_models.Event, err error) error {
|
|
||||||
logging.LogWithFields("SPOOL-1n87f", "id", event.AggregateID).WithError(err).Warn("something went wrong in label template handler")
|
|
||||||
return spooler.HandleError(event, err, m.view.GetLatestMailTemplateFailedEvent, m.view.ProcessedMailTemplateFailedEvent, m.view.ProcessedMailTemplateSequence, m.errorCountUntilSkip)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (o *MailTemplate) OnSuccess() error {
|
|
||||||
return spooler.HandleSuccess(o.view.UpdateMailTemplateSpoolerRunTimestamp)
|
|
||||||
}
|
|
@ -1,132 +0,0 @@
|
|||||||
package handler
|
|
||||||
|
|
||||||
import (
|
|
||||||
"github.com/caos/logging"
|
|
||||||
caos_errs "github.com/caos/zitadel/internal/errors"
|
|
||||||
"github.com/caos/zitadel/internal/eventstore/v1"
|
|
||||||
es_models "github.com/caos/zitadel/internal/eventstore/v1/models"
|
|
||||||
"github.com/caos/zitadel/internal/eventstore/v1/query"
|
|
||||||
"github.com/caos/zitadel/internal/eventstore/v1/spooler"
|
|
||||||
iam_es_model "github.com/caos/zitadel/internal/iam/repository/eventsourcing/model"
|
|
||||||
iam_model "github.com/caos/zitadel/internal/iam/repository/view/model"
|
|
||||||
"github.com/caos/zitadel/internal/org/repository/eventsourcing/model"
|
|
||||||
)
|
|
||||||
|
|
||||||
type MessageText struct {
|
|
||||||
handler
|
|
||||||
subscription *v1.Subscription
|
|
||||||
}
|
|
||||||
|
|
||||||
func newMessageText(handler handler) *MessageText {
|
|
||||||
h := &MessageText{
|
|
||||||
handler: handler,
|
|
||||||
}
|
|
||||||
|
|
||||||
h.subscribe()
|
|
||||||
|
|
||||||
return h
|
|
||||||
}
|
|
||||||
|
|
||||||
func (m *MessageText) subscribe() {
|
|
||||||
m.subscription = m.es.Subscribe(m.AggregateTypes()...)
|
|
||||||
go func() {
|
|
||||||
for event := range m.subscription.Events {
|
|
||||||
query.ReduceEvent(m, event)
|
|
||||||
}
|
|
||||||
}()
|
|
||||||
}
|
|
||||||
|
|
||||||
const (
|
|
||||||
messageTextTable = "management.message_texts"
|
|
||||||
)
|
|
||||||
|
|
||||||
func (m *MessageText) ViewModel() string {
|
|
||||||
return messageTextTable
|
|
||||||
}
|
|
||||||
|
|
||||||
func (m *MessageText) Subscription() *v1.Subscription {
|
|
||||||
return m.subscription
|
|
||||||
}
|
|
||||||
|
|
||||||
func (_ *MessageText) AggregateTypes() []es_models.AggregateType {
|
|
||||||
return []es_models.AggregateType{model.OrgAggregate, iam_es_model.IAMAggregate}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (p *MessageText) CurrentSequence() (uint64, error) {
|
|
||||||
sequence, err := p.view.GetLatestMessageTextSequence()
|
|
||||||
if err != nil {
|
|
||||||
return 0, err
|
|
||||||
}
|
|
||||||
return sequence.CurrentSequence, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (m *MessageText) EventQuery() (*es_models.SearchQuery, error) {
|
|
||||||
sequence, err := m.view.GetLatestMessageTextSequence()
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
return es_models.NewSearchQuery().
|
|
||||||
AggregateTypeFilter(m.AggregateTypes()...).
|
|
||||||
LatestSequenceFilter(sequence.CurrentSequence), nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (m *MessageText) Reduce(event *es_models.Event) (err error) {
|
|
||||||
switch event.AggregateType {
|
|
||||||
case model.OrgAggregate, iam_es_model.IAMAggregate:
|
|
||||||
err = m.processMessageText(event)
|
|
||||||
}
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
func (m *MessageText) processMessageText(event *es_models.Event) (err error) {
|
|
||||||
message := new(iam_model.MessageTextView)
|
|
||||||
switch event.Type {
|
|
||||||
case iam_es_model.CustomTextSet, model.CustomTextSet,
|
|
||||||
iam_es_model.CustomTextRemoved, model.CustomTextRemoved:
|
|
||||||
text := new(iam_model.CustomTextView)
|
|
||||||
err = text.SetData(event)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
if !text.IsMessageTemplate() {
|
|
||||||
return m.view.ProcessedMessageTextSequence(event)
|
|
||||||
}
|
|
||||||
message, err = m.view.MessageTextByIDs(event.AggregateID, text.Template, text.Language)
|
|
||||||
if err != nil && !caos_errs.IsNotFound(err) {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
if caos_errs.IsNotFound(err) {
|
|
||||||
err = nil
|
|
||||||
message = new(iam_model.MessageTextView)
|
|
||||||
message.Language = text.Language
|
|
||||||
message.MessageTextType = text.Template
|
|
||||||
message.CreationDate = event.CreationDate
|
|
||||||
}
|
|
||||||
err = message.AppendEvent(event)
|
|
||||||
case model.CustomTextMessageRemoved:
|
|
||||||
text := new(iam_model.CustomTextView)
|
|
||||||
err = text.SetData(event)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
if !text.IsMessageTemplate() {
|
|
||||||
return m.view.ProcessedMessageTextSequence(event)
|
|
||||||
}
|
|
||||||
return m.view.DeleteMessageText(event.AggregateID, text.Template, text.Language, event)
|
|
||||||
default:
|
|
||||||
return m.view.ProcessedMessageTextSequence(event)
|
|
||||||
}
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
return m.view.PutMessageText(message, event)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (m *MessageText) OnError(event *es_models.Event, err error) error {
|
|
||||||
logging.LogWithFields("SPOOL-om8Hu", "id", event.AggregateID).WithError(err).Warn("something went wrong in label text handler")
|
|
||||||
return spooler.HandleError(event, err, m.view.GetLatestMessageTextFailedEvent, m.view.ProcessedMessageTextFailedEvent, m.view.ProcessedMessageTextSequence, m.errorCountUntilSkip)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (o *MessageText) OnSuccess() error {
|
|
||||||
return spooler.HandleSuccess(o.view.UpdateMessageTextSpoolerRunTimestamp)
|
|
||||||
}
|
|
@ -1,65 +0,0 @@
|
|||||||
package view
|
|
||||||
|
|
||||||
import (
|
|
||||||
"github.com/caos/zitadel/internal/errors"
|
|
||||||
"github.com/caos/zitadel/internal/eventstore/v1/models"
|
|
||||||
"github.com/caos/zitadel/internal/iam/repository/view"
|
|
||||||
"github.com/caos/zitadel/internal/iam/repository/view/model"
|
|
||||||
global_view "github.com/caos/zitadel/internal/view/repository"
|
|
||||||
)
|
|
||||||
|
|
||||||
const (
|
|
||||||
customTextTable = "management.custom_texts"
|
|
||||||
)
|
|
||||||
|
|
||||||
func (v *View) CustomTextByIDs(aggregateID, template, lang, key string) (*model.CustomTextView, error) {
|
|
||||||
return view.CustomTextByIDs(v.Db, customTextTable, aggregateID, template, lang, key)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (v *View) CustomTextsByAggregateIDAndTemplateAndLand(aggregateID, template, lang string) ([]*model.CustomTextView, error) {
|
|
||||||
return view.GetCustomTexts(v.Db, customTextTable, aggregateID, template, lang)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (v *View) PutCustomText(template *model.CustomTextView, event *models.Event) error {
|
|
||||||
err := view.PutCustomText(v.Db, customTextTable, template)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
return v.ProcessedCustomTextSequence(event)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (v *View) DeleteCustomText(aggregateID, textType, lang, key string, event *models.Event) error {
|
|
||||||
err := view.DeleteCustomText(v.Db, customTextTable, aggregateID, textType, lang, key)
|
|
||||||
if err != nil && !errors.IsNotFound(err) {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
return v.ProcessedCustomTextSequence(event)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (v *View) DeleteCustomTextTemplate(aggregateID, textType, lang string, event *models.Event) error {
|
|
||||||
err := view.DeleteCustomTextTemplate(v.Db, customTextTable, aggregateID, textType, lang)
|
|
||||||
if err != nil && !errors.IsNotFound(err) {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
return v.ProcessedCustomTextSequence(event)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (v *View) GetLatestCustomTextSequence() (*global_view.CurrentSequence, error) {
|
|
||||||
return v.latestSequence(customTextTable)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (v *View) ProcessedCustomTextSequence(event *models.Event) error {
|
|
||||||
return v.saveCurrentSequence(customTextTable, event)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (v *View) UpdateCustomTextSpoolerRunTimestamp() error {
|
|
||||||
return v.updateSpoolerRunSequence(customTextTable)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (v *View) GetLatestCustomTextFailedEvent(sequence uint64) (*global_view.FailedEvent, error) {
|
|
||||||
return v.latestFailedEvent(customTextTable, sequence)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (v *View) ProcessedCustomTextFailedEvent(failedEvent *global_view.FailedEvent) error {
|
|
||||||
return v.saveFailedEvent(failedEvent)
|
|
||||||
}
|
|
@ -1,53 +0,0 @@
|
|||||||
package view
|
|
||||||
|
|
||||||
import (
|
|
||||||
"github.com/caos/zitadel/internal/errors"
|
|
||||||
"github.com/caos/zitadel/internal/eventstore/v1/models"
|
|
||||||
"github.com/caos/zitadel/internal/iam/repository/view"
|
|
||||||
"github.com/caos/zitadel/internal/iam/repository/view/model"
|
|
||||||
global_view "github.com/caos/zitadel/internal/view/repository"
|
|
||||||
)
|
|
||||||
|
|
||||||
const (
|
|
||||||
mailTemplateTable = "management.mail_templates"
|
|
||||||
)
|
|
||||||
|
|
||||||
func (v *View) MailTemplateByAggregateID(aggregateID string) (*model.MailTemplateView, error) {
|
|
||||||
return view.GetMailTemplateByAggregateID(v.Db, mailTemplateTable, aggregateID)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (v *View) PutMailTemplate(template *model.MailTemplateView, event *models.Event) error {
|
|
||||||
err := view.PutMailTemplate(v.Db, mailTemplateTable, template)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
return v.ProcessedMailTemplateSequence(event)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (v *View) DeleteMailTemplate(aggregateID string, event *models.Event) error {
|
|
||||||
err := view.DeleteMailTemplate(v.Db, mailTemplateTable, aggregateID)
|
|
||||||
if err != nil && !errors.IsNotFound(err) {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
return v.ProcessedMailTemplateSequence(event)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (v *View) GetLatestMailTemplateSequence() (*global_view.CurrentSequence, error) {
|
|
||||||
return v.latestSequence(mailTemplateTable)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (v *View) ProcessedMailTemplateSequence(event *models.Event) error {
|
|
||||||
return v.saveCurrentSequence(mailTemplateTable, event)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (v *View) UpdateMailTemplateSpoolerRunTimestamp() error {
|
|
||||||
return v.updateSpoolerRunSequence(mailTemplateTable)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (v *View) GetLatestMailTemplateFailedEvent(sequence uint64) (*global_view.FailedEvent, error) {
|
|
||||||
return v.latestFailedEvent(mailTemplateTable, sequence)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (v *View) ProcessedMailTemplateFailedEvent(failedEvent *global_view.FailedEvent) error {
|
|
||||||
return v.saveFailedEvent(failedEvent)
|
|
||||||
}
|
|
@ -1,57 +0,0 @@
|
|||||||
package view
|
|
||||||
|
|
||||||
import (
|
|
||||||
"github.com/caos/zitadel/internal/errors"
|
|
||||||
"github.com/caos/zitadel/internal/eventstore/v1/models"
|
|
||||||
"github.com/caos/zitadel/internal/iam/repository/view"
|
|
||||||
"github.com/caos/zitadel/internal/iam/repository/view/model"
|
|
||||||
global_view "github.com/caos/zitadel/internal/view/repository"
|
|
||||||
)
|
|
||||||
|
|
||||||
const (
|
|
||||||
messageTextTable = "management.message_texts"
|
|
||||||
)
|
|
||||||
|
|
||||||
func (v *View) MessageTextsByAggregateID(aggregateID string) ([]*model.MessageTextView, error) {
|
|
||||||
return view.GetMessageTexts(v.Db, messageTextTable, aggregateID)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (v *View) MessageTextByIDs(aggregateID, textType, lang string) (*model.MessageTextView, error) {
|
|
||||||
return view.GetMessageTextByIDs(v.Db, messageTextTable, aggregateID, textType, lang)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (v *View) PutMessageText(template *model.MessageTextView, event *models.Event) error {
|
|
||||||
err := view.PutMessageText(v.Db, messageTextTable, template)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
return v.ProcessedMessageTextSequence(event)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (v *View) DeleteMessageText(aggregateID, textType, lang string, event *models.Event) error {
|
|
||||||
err := view.DeleteMessageText(v.Db, messageTextTable, aggregateID, textType, lang)
|
|
||||||
if err != nil && !errors.IsNotFound(err) {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
return v.ProcessedMessageTextSequence(event)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (v *View) GetLatestMessageTextSequence() (*global_view.CurrentSequence, error) {
|
|
||||||
return v.latestSequence(messageTextTable)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (v *View) ProcessedMessageTextSequence(event *models.Event) error {
|
|
||||||
return v.saveCurrentSequence(messageTextTable, event)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (v *View) UpdateMessageTextSpoolerRunTimestamp() error {
|
|
||||||
return v.updateSpoolerRunSequence(messageTextTable)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (v *View) GetLatestMessageTextFailedEvent(sequence uint64) (*global_view.FailedEvent, error) {
|
|
||||||
return v.latestFailedEvent(messageTextTable, sequence)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (v *View) ProcessedMessageTextFailedEvent(failedEvent *global_view.FailedEvent) error {
|
|
||||||
return v.saveFailedEvent(failedEvent)
|
|
||||||
}
|
|
@ -6,7 +6,6 @@ import (
|
|||||||
|
|
||||||
"golang.org/x/text/language"
|
"golang.org/x/text/language"
|
||||||
|
|
||||||
"github.com/caos/zitadel/internal/domain"
|
|
||||||
iam_model "github.com/caos/zitadel/internal/iam/model"
|
iam_model "github.com/caos/zitadel/internal/iam/model"
|
||||||
|
|
||||||
org_model "github.com/caos/zitadel/internal/org/model"
|
org_model "github.com/caos/zitadel/internal/org/model"
|
||||||
@ -25,13 +24,4 @@ type OrgRepository interface {
|
|||||||
|
|
||||||
SearchIDPProviders(ctx context.Context, request *iam_model.IDPProviderSearchRequest) (*iam_model.IDPProviderSearchResponse, error)
|
SearchIDPProviders(ctx context.Context, request *iam_model.IDPProviderSearchRequest) (*iam_model.IDPProviderSearchResponse, error)
|
||||||
GetIDPProvidersByIDPConfigID(ctx context.Context, aggregateID, idpConfigID string) ([]*iam_model.IDPProviderView, error)
|
GetIDPProvidersByIDPConfigID(ctx context.Context, aggregateID, idpConfigID string) ([]*iam_model.IDPProviderView, error)
|
||||||
|
|
||||||
GetDefaultMailTemplate(ctx context.Context) (*iam_model.MailTemplateView, error)
|
|
||||||
GetMailTemplate(ctx context.Context) (*iam_model.MailTemplateView, error)
|
|
||||||
|
|
||||||
GetDefaultMessageText(ctx context.Context, textType string, language string) (*domain.CustomMessageText, error)
|
|
||||||
GetMessageText(ctx context.Context, orgID, textType, lang string) (*domain.CustomMessageText, error)
|
|
||||||
|
|
||||||
GetDefaultLoginTexts(ctx context.Context, lang string) (*domain.CustomLoginText, error)
|
|
||||||
GetLoginTexts(ctx context.Context, orgID, lang string) (*domain.CustomLoginText, error)
|
|
||||||
}
|
}
|
||||||
|
@ -2,10 +2,12 @@ package notification
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
|
||||||
"github.com/caos/logging"
|
"github.com/caos/logging"
|
||||||
"github.com/caos/zitadel/internal/command"
|
"github.com/caos/zitadel/internal/command"
|
||||||
sd "github.com/caos/zitadel/internal/config/systemdefaults"
|
sd "github.com/caos/zitadel/internal/config/systemdefaults"
|
||||||
"github.com/caos/zitadel/internal/notification/repository/eventsourcing"
|
"github.com/caos/zitadel/internal/notification/repository/eventsourcing"
|
||||||
|
"github.com/caos/zitadel/internal/query"
|
||||||
"github.com/rakyll/statik/fs"
|
"github.com/rakyll/statik/fs"
|
||||||
|
|
||||||
_ "github.com/caos/zitadel/internal/notification/statik"
|
_ "github.com/caos/zitadel/internal/notification/statik"
|
||||||
@ -16,7 +18,7 @@ type Config struct {
|
|||||||
Repository eventsourcing.Config
|
Repository eventsourcing.Config
|
||||||
}
|
}
|
||||||
|
|
||||||
func Start(ctx context.Context, config Config, systemDefaults sd.SystemDefaults, command *command.Commands, hasStatics bool) {
|
func Start(ctx context.Context, config Config, systemDefaults sd.SystemDefaults, command *command.Commands, queries *query.Queries, hasStatics bool) {
|
||||||
statikFS, err := fs.NewWithNamespace("notification")
|
statikFS, err := fs.NewWithNamespace("notification")
|
||||||
logging.Log("CONFI-7usEW").OnError(err).Panic("unable to start listener")
|
logging.Log("CONFI-7usEW").OnError(err).Panic("unable to start listener")
|
||||||
|
|
||||||
@ -24,6 +26,6 @@ func Start(ctx context.Context, config Config, systemDefaults sd.SystemDefaults,
|
|||||||
if !hasStatics {
|
if !hasStatics {
|
||||||
apiDomain = ""
|
apiDomain = ""
|
||||||
}
|
}
|
||||||
_, err = eventsourcing.Start(config.Repository, statikFS, systemDefaults, command, apiDomain)
|
_, err = eventsourcing.Start(config.Repository, statikFS, systemDefaults, command, queries, apiDomain)
|
||||||
logging.Log("MAIN-9uBxp").OnError(err).Panic("unable to start app")
|
logging.Log("MAIN-9uBxp").OnError(err).Panic("unable to start app")
|
||||||
}
|
}
|
||||||
|
@ -1,133 +0,0 @@
|
|||||||
package handler
|
|
||||||
|
|
||||||
import (
|
|
||||||
"github.com/caos/logging"
|
|
||||||
|
|
||||||
caos_errs "github.com/caos/zitadel/internal/errors"
|
|
||||||
"github.com/caos/zitadel/internal/eventstore/v1"
|
|
||||||
es_models "github.com/caos/zitadel/internal/eventstore/v1/models"
|
|
||||||
"github.com/caos/zitadel/internal/eventstore/v1/query"
|
|
||||||
"github.com/caos/zitadel/internal/eventstore/v1/spooler"
|
|
||||||
iam_es_model "github.com/caos/zitadel/internal/iam/repository/eventsourcing/model"
|
|
||||||
iam_model "github.com/caos/zitadel/internal/iam/repository/view/model"
|
|
||||||
"github.com/caos/zitadel/internal/org/repository/eventsourcing/model"
|
|
||||||
)
|
|
||||||
|
|
||||||
type CustomText struct {
|
|
||||||
handler
|
|
||||||
subscription *v1.Subscription
|
|
||||||
}
|
|
||||||
|
|
||||||
func newCustomText(handler handler) *CustomText {
|
|
||||||
h := &CustomText{
|
|
||||||
handler: handler,
|
|
||||||
}
|
|
||||||
|
|
||||||
h.subscribe()
|
|
||||||
|
|
||||||
return h
|
|
||||||
}
|
|
||||||
|
|
||||||
func (m *CustomText) subscribe() {
|
|
||||||
m.subscription = m.es.Subscribe(m.AggregateTypes()...)
|
|
||||||
go func() {
|
|
||||||
for event := range m.subscription.Events {
|
|
||||||
query.ReduceEvent(m, event)
|
|
||||||
}
|
|
||||||
}()
|
|
||||||
}
|
|
||||||
|
|
||||||
const (
|
|
||||||
customTextTable = "notification.custom_texts"
|
|
||||||
)
|
|
||||||
|
|
||||||
func (m *CustomText) ViewModel() string {
|
|
||||||
return customTextTable
|
|
||||||
}
|
|
||||||
|
|
||||||
func (m *CustomText) Subscription() *v1.Subscription {
|
|
||||||
return m.subscription
|
|
||||||
}
|
|
||||||
|
|
||||||
func (_ *CustomText) AggregateTypes() []es_models.AggregateType {
|
|
||||||
return []es_models.AggregateType{model.OrgAggregate, iam_es_model.IAMAggregate}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (p *CustomText) CurrentSequence() (uint64, error) {
|
|
||||||
sequence, err := p.view.GetLatestCustomTextSequence()
|
|
||||||
if err != nil {
|
|
||||||
return 0, err
|
|
||||||
}
|
|
||||||
return sequence.CurrentSequence, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (m *CustomText) EventQuery() (*es_models.SearchQuery, error) {
|
|
||||||
sequence, err := m.view.GetLatestCustomTextSequence()
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
return es_models.NewSearchQuery().
|
|
||||||
AggregateTypeFilter(m.AggregateTypes()...).
|
|
||||||
LatestSequenceFilter(sequence.CurrentSequence), nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (m *CustomText) Reduce(event *es_models.Event) (err error) {
|
|
||||||
switch event.AggregateType {
|
|
||||||
case model.OrgAggregate, iam_es_model.IAMAggregate:
|
|
||||||
err = m.processCustomText(event)
|
|
||||||
}
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
func (m *CustomText) processCustomText(event *es_models.Event) (err error) {
|
|
||||||
customText := new(iam_model.CustomTextView)
|
|
||||||
switch event.Type {
|
|
||||||
case iam_es_model.CustomTextSet, model.CustomTextSet:
|
|
||||||
text := new(iam_model.CustomTextView)
|
|
||||||
err = text.SetData(event)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
customText, err = m.view.CustomTextByIDs(event.AggregateID, text.Template, text.Key, text.Language)
|
|
||||||
if err != nil && !caos_errs.IsNotFound(err) {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
if caos_errs.IsNotFound(err) {
|
|
||||||
err = nil
|
|
||||||
customText = new(iam_model.CustomTextView)
|
|
||||||
customText.Language = text.Language
|
|
||||||
customText.Template = text.Template
|
|
||||||
customText.CreationDate = event.CreationDate
|
|
||||||
}
|
|
||||||
err = customText.AppendEvent(event)
|
|
||||||
case iam_es_model.CustomTextRemoved, model.CustomTextRemoved:
|
|
||||||
text := new(iam_model.CustomTextView)
|
|
||||||
err = text.SetData(event)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
return m.view.DeleteCustomText(event.AggregateID, text.Template, text.Language, text.Key, event)
|
|
||||||
case iam_es_model.CustomTextMessageRemoved, model.CustomTextMessageRemoved:
|
|
||||||
text := new(iam_model.CustomTextView)
|
|
||||||
err = text.SetData(event)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
return m.view.DeleteCustomTextTemplate(event.AggregateID, text.Template, text.Language, event)
|
|
||||||
default:
|
|
||||||
return m.view.ProcessedCustomTextSequence(event)
|
|
||||||
}
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
return m.view.PutCustomText(customText, event)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (m *CustomText) OnError(event *es_models.Event, err error) error {
|
|
||||||
logging.LogWithFields("SPOOL-3m912", "id", event.AggregateID).WithError(err).Warn("something went wrong in custom text handler")
|
|
||||||
return spooler.HandleError(event, err, m.view.GetLatestCustomTextFailedEvent, m.view.ProcessedCustomTextFailedEvent, m.view.ProcessedCustomTextSequence, m.errorCountUntilSkip)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (o *CustomText) OnSuccess() error {
|
|
||||||
return spooler.HandleSuccess(o.view.UpdateCustomTextSpoolerRunTimestamp)
|
|
||||||
}
|
|
@ -5,13 +5,14 @@ import (
|
|||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/caos/logging"
|
"github.com/caos/logging"
|
||||||
|
"github.com/caos/zitadel/internal/query"
|
||||||
|
|
||||||
"github.com/caos/zitadel/internal/command"
|
"github.com/caos/zitadel/internal/command"
|
||||||
sd "github.com/caos/zitadel/internal/config/systemdefaults"
|
sd "github.com/caos/zitadel/internal/config/systemdefaults"
|
||||||
"github.com/caos/zitadel/internal/config/types"
|
"github.com/caos/zitadel/internal/config/types"
|
||||||
"github.com/caos/zitadel/internal/crypto"
|
"github.com/caos/zitadel/internal/crypto"
|
||||||
v1 "github.com/caos/zitadel/internal/eventstore/v1"
|
v1 "github.com/caos/zitadel/internal/eventstore/v1"
|
||||||
"github.com/caos/zitadel/internal/eventstore/v1/query"
|
queryv1 "github.com/caos/zitadel/internal/eventstore/v1/query"
|
||||||
"github.com/caos/zitadel/internal/notification/repository/eventsourcing/view"
|
"github.com/caos/zitadel/internal/notification/repository/eventsourcing/view"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -34,20 +35,20 @@ func (h *handler) Eventstore() v1.Eventstore {
|
|||||||
return h.es
|
return h.es
|
||||||
}
|
}
|
||||||
|
|
||||||
func Register(configs Configs, bulkLimit, errorCount uint64, view *view.View, es v1.Eventstore, command *command.Commands, systemDefaults sd.SystemDefaults, dir http.FileSystem, apiDomain string) []query.Handler {
|
func Register(configs Configs, bulkLimit, errorCount uint64, view *view.View, es v1.Eventstore, command *command.Commands, queries *query.Queries, systemDefaults sd.SystemDefaults, dir http.FileSystem, apiDomain string) []queryv1.Handler {
|
||||||
aesCrypto, err := crypto.NewAESCrypto(systemDefaults.UserVerificationKey)
|
aesCrypto, err := crypto.NewAESCrypto(systemDefaults.UserVerificationKey)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
logging.Log("HANDL-s90ew").WithError(err).Debug("error create new aes crypto")
|
logging.Log("HANDL-s90ew").WithError(err).Debug("error create new aes crypto")
|
||||||
}
|
}
|
||||||
return []query.Handler{
|
return []queryv1.Handler{
|
||||||
newNotifyUser(
|
newNotifyUser(
|
||||||
handler{view, bulkLimit, configs.cycleDuration("User"), errorCount, es},
|
handler{view, bulkLimit, configs.cycleDuration("User"), errorCount, es},
|
||||||
systemDefaults.IamID,
|
systemDefaults.IamID,
|
||||||
),
|
),
|
||||||
newCustomText(handler{view, bulkLimit, configs.cycleDuration("CustomText"), errorCount, es}),
|
|
||||||
newNotification(
|
newNotification(
|
||||||
handler{view, bulkLimit, configs.cycleDuration("Notification"), errorCount, es},
|
handler{view, bulkLimit, configs.cycleDuration("Notification"), errorCount, es},
|
||||||
command,
|
command,
|
||||||
|
queries,
|
||||||
systemDefaults,
|
systemDefaults,
|
||||||
aesCrypto,
|
aesCrypto,
|
||||||
dir,
|
dir,
|
||||||
|
@ -7,8 +7,6 @@ import (
|
|||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/caos/logging"
|
"github.com/caos/logging"
|
||||||
"golang.org/x/text/language"
|
|
||||||
|
|
||||||
"github.com/caos/zitadel/internal/api/authz"
|
"github.com/caos/zitadel/internal/api/authz"
|
||||||
"github.com/caos/zitadel/internal/command"
|
"github.com/caos/zitadel/internal/command"
|
||||||
sd "github.com/caos/zitadel/internal/config/systemdefaults"
|
sd "github.com/caos/zitadel/internal/config/systemdefaults"
|
||||||
@ -17,12 +15,13 @@ import (
|
|||||||
"github.com/caos/zitadel/internal/errors"
|
"github.com/caos/zitadel/internal/errors"
|
||||||
v1 "github.com/caos/zitadel/internal/eventstore/v1"
|
v1 "github.com/caos/zitadel/internal/eventstore/v1"
|
||||||
"github.com/caos/zitadel/internal/eventstore/v1/models"
|
"github.com/caos/zitadel/internal/eventstore/v1/models"
|
||||||
"github.com/caos/zitadel/internal/eventstore/v1/query"
|
queryv1 "github.com/caos/zitadel/internal/eventstore/v1/query"
|
||||||
"github.com/caos/zitadel/internal/eventstore/v1/spooler"
|
"github.com/caos/zitadel/internal/eventstore/v1/spooler"
|
||||||
"github.com/caos/zitadel/internal/i18n"
|
"github.com/caos/zitadel/internal/i18n"
|
||||||
iam_model "github.com/caos/zitadel/internal/iam/model"
|
iam_model "github.com/caos/zitadel/internal/iam/model"
|
||||||
iam_es_model "github.com/caos/zitadel/internal/iam/repository/view/model"
|
iam_es_model "github.com/caos/zitadel/internal/iam/repository/view/model"
|
||||||
"github.com/caos/zitadel/internal/notification/types"
|
"github.com/caos/zitadel/internal/notification/types"
|
||||||
|
"github.com/caos/zitadel/internal/query"
|
||||||
user_repo "github.com/caos/zitadel/internal/repository/user"
|
user_repo "github.com/caos/zitadel/internal/repository/user"
|
||||||
es_model "github.com/caos/zitadel/internal/user/repository/eventsourcing/model"
|
es_model "github.com/caos/zitadel/internal/user/repository/eventsourcing/model"
|
||||||
"github.com/caos/zitadel/internal/user/repository/view"
|
"github.com/caos/zitadel/internal/user/repository/view"
|
||||||
@ -30,14 +29,10 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
notificationTable = "notification.notifications"
|
notificationTable = "notification.notifications"
|
||||||
NotifyUserID = "NOTIFICATION"
|
NotifyUserID = "NOTIFICATION"
|
||||||
labelPolicyTableOrg = "management.label_policies"
|
labelPolicyTableOrg = "management.label_policies"
|
||||||
labelPolicyTableDef = "adminapi.label_policies"
|
labelPolicyTableDef = "adminapi.label_policies"
|
||||||
mailTemplateTableOrg = "management.mail_templates"
|
|
||||||
mailTemplateTableDef = "adminapi.mail_templates"
|
|
||||||
messageTextTableOrg = "management.message_texts"
|
|
||||||
messageTextTableDef = "adminapi.message_texts"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
type Notification struct {
|
type Notification struct {
|
||||||
@ -48,11 +43,13 @@ type Notification struct {
|
|||||||
statikDir http.FileSystem
|
statikDir http.FileSystem
|
||||||
subscription *v1.Subscription
|
subscription *v1.Subscription
|
||||||
apiDomain string
|
apiDomain string
|
||||||
|
queries *query.Queries
|
||||||
}
|
}
|
||||||
|
|
||||||
func newNotification(
|
func newNotification(
|
||||||
handler handler,
|
handler handler,
|
||||||
command *command.Commands,
|
command *command.Commands,
|
||||||
|
query *query.Queries,
|
||||||
defaults sd.SystemDefaults,
|
defaults sd.SystemDefaults,
|
||||||
aesCrypto crypto.EncryptionAlgorithm,
|
aesCrypto crypto.EncryptionAlgorithm,
|
||||||
statikDir http.FileSystem,
|
statikDir http.FileSystem,
|
||||||
@ -65,6 +62,7 @@ func newNotification(
|
|||||||
statikDir: statikDir,
|
statikDir: statikDir,
|
||||||
AesCrypto: aesCrypto,
|
AesCrypto: aesCrypto,
|
||||||
apiDomain: apiDomain,
|
apiDomain: apiDomain,
|
||||||
|
queries: query,
|
||||||
}
|
}
|
||||||
|
|
||||||
h.subscribe()
|
h.subscribe()
|
||||||
@ -76,7 +74,7 @@ func (k *Notification) subscribe() {
|
|||||||
k.subscription = k.es.Subscribe(k.AggregateTypes()...)
|
k.subscription = k.es.Subscribe(k.AggregateTypes()...)
|
||||||
go func() {
|
go func() {
|
||||||
for event := range k.subscription.Events {
|
for event := range k.subscription.Events {
|
||||||
query.ReduceEvent(k, event)
|
queryv1.ReduceEvent(k, event)
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
}
|
}
|
||||||
@ -424,21 +422,20 @@ func (n *Notification) getLabelPolicy(ctx context.Context) (*iam_model.LabelPoli
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Read organization specific template
|
// Read organization specific template
|
||||||
func (n *Notification) getMailTemplate(ctx context.Context) (*iam_model.MailTemplateView, error) {
|
func (n *Notification) getMailTemplate(ctx context.Context) (*query.MailTemplate, error) {
|
||||||
// read from Org
|
// read from Org
|
||||||
template, err := n.view.MailTemplateByAggregateID(authz.GetCtxData(ctx).OrgID, mailTemplateTableOrg)
|
template, err := n.queries.MailTemplateByOrg(ctx, authz.GetCtxData(ctx).OrgID)
|
||||||
if errors.IsNotFound(err) {
|
if errors.IsNotFound(err) {
|
||||||
// read from default
|
// read from default
|
||||||
template, err = n.view.MailTemplateByAggregateID(n.systemDefaults.IamID, mailTemplateTableDef)
|
template, err = n.queries.DefaultMailTemplate(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
template.Default = true
|
|
||||||
}
|
}
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
return iam_es_model.MailTemplateViewToModel(template), err
|
return template, err
|
||||||
}
|
}
|
||||||
|
|
||||||
func (n *Notification) getTranslatorWithOrgTexts(orgID, textType string) (*i18n.Translator, error) {
|
func (n *Notification) getTranslatorWithOrgTexts(orgID, textType string) (*i18n.Translator, error) {
|
||||||
@ -446,52 +443,27 @@ func (n *Notification) getTranslatorWithOrgTexts(orgID, textType string) (*i18n.
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
allCustomTexts, err := n.view.CustomTextsByAggregateIDAndTemplate(domain.IAMID, textType)
|
ctx := context.TODO()
|
||||||
|
allCustomTexts, err := n.queries.CustomTextListByTemplate(ctx, domain.IAMID, textType)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return translator, nil
|
return translator, nil
|
||||||
}
|
}
|
||||||
customTexts, err := n.view.CustomTextsByAggregateIDAndTemplate(orgID, textType)
|
customTexts, err := n.queries.CustomTextListByTemplate(ctx, orgID, textType)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return translator, nil
|
return translator, nil
|
||||||
}
|
}
|
||||||
allCustomTexts = append(allCustomTexts, customTexts...)
|
allCustomTexts.CustomTexts = append(allCustomTexts.CustomTexts, customTexts.CustomTexts...)
|
||||||
|
|
||||||
for _, text := range allCustomTexts {
|
for _, text := range allCustomTexts.CustomTexts {
|
||||||
msg := i18n.Message{
|
msg := i18n.Message{
|
||||||
ID: text.Template + "." + text.Key,
|
ID: text.Template + "." + text.Key,
|
||||||
Text: text.Text,
|
Text: text.Text,
|
||||||
}
|
}
|
||||||
translator.AddMessages(language.Make(text.Language), msg)
|
translator.AddMessages(text.Language, msg)
|
||||||
}
|
}
|
||||||
return translator, nil
|
return translator, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Read organization specific texts
|
|
||||||
func (n *Notification) getMessageText(user *model.NotifyUser, textType, lang string) (*iam_model.MessageTextView, error) {
|
|
||||||
langTag := language.Make(lang)
|
|
||||||
if langTag == language.Und {
|
|
||||||
langTag = language.English
|
|
||||||
}
|
|
||||||
langBase, _ := langTag.Base()
|
|
||||||
|
|
||||||
defaultMessageText, err := n.view.MessageTextByIDs(n.systemDefaults.IamID, textType, langBase.String(), messageTextTableDef)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
defaultMessageText.Default = true
|
|
||||||
|
|
||||||
// read from Org
|
|
||||||
orgMessageText, err := n.view.MessageTextByIDs(user.ResourceOwner, textType, langBase.String(), messageTextTableOrg)
|
|
||||||
if errors.IsNotFound(err) {
|
|
||||||
return iam_es_model.MessageTextViewToModel(defaultMessageText), nil
|
|
||||||
}
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
mergedText := mergeMessageTexts(defaultMessageText, orgMessageText)
|
|
||||||
return iam_es_model.MessageTextViewToModel(mergedText), err
|
|
||||||
}
|
|
||||||
|
|
||||||
func (n *Notification) getUserByID(userID string) (*model.NotifyUser, error) {
|
func (n *Notification) getUserByID(userID string) (*model.NotifyUser, error) {
|
||||||
user, usrErr := n.view.NotifyUserByID(userID)
|
user, usrErr := n.view.NotifyUserByID(userID)
|
||||||
if usrErr != nil && !errors.IsNotFound(usrErr) {
|
if usrErr != nil && !errors.IsNotFound(usrErr) {
|
||||||
@ -515,28 +487,3 @@ func (n *Notification) getUserByID(userID string) (*model.NotifyUser, error) {
|
|||||||
}
|
}
|
||||||
return &userCopy, nil
|
return &userCopy, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func mergeMessageTexts(defaultText *iam_es_model.MessageTextView, orgText *iam_es_model.MessageTextView) *iam_es_model.MessageTextView {
|
|
||||||
if orgText.Subject == "" {
|
|
||||||
orgText.Subject = defaultText.Subject
|
|
||||||
}
|
|
||||||
if orgText.Title == "" {
|
|
||||||
orgText.Title = defaultText.Title
|
|
||||||
}
|
|
||||||
if orgText.PreHeader == "" {
|
|
||||||
orgText.PreHeader = defaultText.PreHeader
|
|
||||||
}
|
|
||||||
if orgText.Text == "" {
|
|
||||||
orgText.Text = defaultText.Text
|
|
||||||
}
|
|
||||||
if orgText.Greeting == "" {
|
|
||||||
orgText.Greeting = defaultText.Greeting
|
|
||||||
}
|
|
||||||
if orgText.ButtonText == "" {
|
|
||||||
orgText.ButtonText = defaultText.ButtonText
|
|
||||||
}
|
|
||||||
if orgText.FooterText == "" {
|
|
||||||
orgText.FooterText = defaultText.FooterText
|
|
||||||
}
|
|
||||||
return orgText
|
|
||||||
}
|
|
||||||
|
@ -5,6 +5,7 @@ import (
|
|||||||
|
|
||||||
"github.com/caos/zitadel/internal/command"
|
"github.com/caos/zitadel/internal/command"
|
||||||
"github.com/caos/zitadel/internal/eventstore/v1"
|
"github.com/caos/zitadel/internal/eventstore/v1"
|
||||||
|
"github.com/caos/zitadel/internal/query"
|
||||||
|
|
||||||
"golang.org/x/text/language"
|
"golang.org/x/text/language"
|
||||||
|
|
||||||
@ -27,7 +28,7 @@ type EsRepository struct {
|
|||||||
spooler *es_spol.Spooler
|
spooler *es_spol.Spooler
|
||||||
}
|
}
|
||||||
|
|
||||||
func Start(conf Config, dir http.FileSystem, systemDefaults sd.SystemDefaults, command *command.Commands, apiDomain string) (*EsRepository, error) {
|
func Start(conf Config, dir http.FileSystem, systemDefaults sd.SystemDefaults, command *command.Commands, queries *query.Queries, apiDomain string) (*EsRepository, error) {
|
||||||
es, err := v1.Start(conf.Eventstore)
|
es, err := v1.Start(conf.Eventstore)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
@ -42,7 +43,7 @@ func Start(conf Config, dir http.FileSystem, systemDefaults sd.SystemDefaults, c
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
spool := spooler.StartSpooler(conf.Spooler, es, view, sqlClient, command, systemDefaults, dir, apiDomain)
|
spool := spooler.StartSpooler(conf.Spooler, es, view, sqlClient, command, queries, systemDefaults, dir, apiDomain)
|
||||||
|
|
||||||
return &EsRepository{
|
return &EsRepository{
|
||||||
spool,
|
spool,
|
||||||
|
@ -6,6 +6,7 @@ import (
|
|||||||
|
|
||||||
"github.com/caos/zitadel/internal/command"
|
"github.com/caos/zitadel/internal/command"
|
||||||
"github.com/caos/zitadel/internal/eventstore/v1"
|
"github.com/caos/zitadel/internal/eventstore/v1"
|
||||||
|
"github.com/caos/zitadel/internal/query"
|
||||||
|
|
||||||
sd "github.com/caos/zitadel/internal/config/systemdefaults"
|
sd "github.com/caos/zitadel/internal/config/systemdefaults"
|
||||||
"github.com/caos/zitadel/internal/eventstore/v1/spooler"
|
"github.com/caos/zitadel/internal/eventstore/v1/spooler"
|
||||||
@ -20,12 +21,12 @@ type SpoolerConfig struct {
|
|||||||
Handlers handler.Configs
|
Handlers handler.Configs
|
||||||
}
|
}
|
||||||
|
|
||||||
func StartSpooler(c SpoolerConfig, es v1.Eventstore, view *view.View, sql *sql.DB, command *command.Commands, systemDefaults sd.SystemDefaults, dir http.FileSystem, apiDomain string) *spooler.Spooler {
|
func StartSpooler(c SpoolerConfig, es v1.Eventstore, view *view.View, sql *sql.DB, command *command.Commands, queries *query.Queries, systemDefaults sd.SystemDefaults, dir http.FileSystem, apiDomain string) *spooler.Spooler {
|
||||||
spoolerConfig := spooler.Config{
|
spoolerConfig := spooler.Config{
|
||||||
Eventstore: es,
|
Eventstore: es,
|
||||||
Locker: &locker{dbClient: sql},
|
Locker: &locker{dbClient: sql},
|
||||||
ConcurrentWorkers: c.ConcurrentWorkers,
|
ConcurrentWorkers: c.ConcurrentWorkers,
|
||||||
ViewHandlers: handler.Register(c.Handlers, c.BulkLimit, c.FailureCountUntilSkip, view, es, command, systemDefaults, dir, apiDomain),
|
ViewHandlers: handler.Register(c.Handlers, c.BulkLimit, c.FailureCountUntilSkip, view, es, command, queries, systemDefaults, dir, apiDomain),
|
||||||
}
|
}
|
||||||
spool := spoolerConfig.New()
|
spool := spoolerConfig.New()
|
||||||
spool.Start()
|
spool.Start()
|
||||||
|
@ -1,69 +0,0 @@
|
|||||||
package view
|
|
||||||
|
|
||||||
import (
|
|
||||||
"github.com/caos/zitadel/internal/errors"
|
|
||||||
"github.com/caos/zitadel/internal/eventstore/v1/models"
|
|
||||||
"github.com/caos/zitadel/internal/iam/repository/view"
|
|
||||||
"github.com/caos/zitadel/internal/iam/repository/view/model"
|
|
||||||
global_view "github.com/caos/zitadel/internal/view/repository"
|
|
||||||
)
|
|
||||||
|
|
||||||
const (
|
|
||||||
customTextTable = "notification.custom_texts"
|
|
||||||
)
|
|
||||||
|
|
||||||
func (v *View) CustomTextByIDs(aggregateID, template, lang, key string) (*model.CustomTextView, error) {
|
|
||||||
return view.CustomTextByIDs(v.Db, customTextTable, aggregateID, template, lang, key)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (v *View) CustomTextsByAggregateIDAndTemplate(aggregateID, template string) ([]*model.CustomTextView, error) {
|
|
||||||
return view.GetCustomTextsByAggregateIDAndTemplate(v.Db, customTextTable, aggregateID, template)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (v *View) CustomTextsByAggregateIDAndTemplateAndLang(aggregateID, template, lang string) ([]*model.CustomTextView, error) {
|
|
||||||
return view.GetCustomTexts(v.Db, customTextTable, aggregateID, template, lang)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (v *View) PutCustomText(template *model.CustomTextView, event *models.Event) error {
|
|
||||||
err := view.PutCustomText(v.Db, customTextTable, template)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
return v.ProcessedCustomTextSequence(event)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (v *View) DeleteCustomText(aggregateID, textType, lang, key string, event *models.Event) error {
|
|
||||||
err := view.DeleteCustomText(v.Db, customTextTable, aggregateID, textType, lang, key)
|
|
||||||
if err != nil && !errors.IsNotFound(err) {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
return v.ProcessedCustomTextSequence(event)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (v *View) DeleteCustomTextTemplate(aggregateID, textType, lang string, event *models.Event) error {
|
|
||||||
err := view.DeleteCustomTextTemplate(v.Db, customTextTable, aggregateID, textType, lang)
|
|
||||||
if err != nil && !errors.IsNotFound(err) {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
return v.ProcessedCustomTextSequence(event)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (v *View) GetLatestCustomTextSequence() (*global_view.CurrentSequence, error) {
|
|
||||||
return v.latestSequence(customTextTable)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (v *View) ProcessedCustomTextSequence(event *models.Event) error {
|
|
||||||
return v.saveCurrentSequence(customTextTable, event)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (v *View) UpdateCustomTextSpoolerRunTimestamp() error {
|
|
||||||
return v.updateSpoolerRunSequence(customTextTable)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (v *View) GetLatestCustomTextFailedEvent(sequence uint64) (*global_view.FailedEvent, error) {
|
|
||||||
return v.latestFailedEvent(customTextTable, sequence)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (v *View) ProcessedCustomTextFailedEvent(failedEvent *global_view.FailedEvent) error {
|
|
||||||
return v.saveFailedEvent(failedEvent)
|
|
||||||
}
|
|
@ -1,10 +0,0 @@
|
|||||||
package view
|
|
||||||
|
|
||||||
import (
|
|
||||||
"github.com/caos/zitadel/internal/iam/repository/view"
|
|
||||||
"github.com/caos/zitadel/internal/iam/repository/view/model"
|
|
||||||
)
|
|
||||||
|
|
||||||
func (v *View) MailTemplateByAggregateID(aggregateID string, mailTemplateTableVar string) (*model.MailTemplateView, error) {
|
|
||||||
return view.GetMailTemplateByAggregateID(v.Db, mailTemplateTableVar, aggregateID)
|
|
||||||
}
|
|
1091
internal/query/custom_text.go
Normal file
1091
internal/query/custom_text.go
Normal file
File diff suppressed because it is too large
Load Diff
221
internal/query/custom_text_test.go
Normal file
221
internal/query/custom_text_test.go
Normal file
@ -0,0 +1,221 @@
|
|||||||
|
package query
|
||||||
|
|
||||||
|
import (
|
||||||
|
"database/sql"
|
||||||
|
"database/sql/driver"
|
||||||
|
"errors"
|
||||||
|
"fmt"
|
||||||
|
"regexp"
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
errs "github.com/caos/zitadel/internal/errors"
|
||||||
|
"golang.org/x/text/language"
|
||||||
|
)
|
||||||
|
|
||||||
|
func Test_CustomTextPrepares(t *testing.T) {
|
||||||
|
type want struct {
|
||||||
|
sqlExpectations sqlExpectation
|
||||||
|
err checkErr
|
||||||
|
}
|
||||||
|
tests := []struct {
|
||||||
|
name string
|
||||||
|
prepare interface{}
|
||||||
|
want want
|
||||||
|
object interface{}
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
name: "prepareCustomTextQuery no result",
|
||||||
|
prepare: prepareCustomTextsQuery,
|
||||||
|
want: want{
|
||||||
|
sqlExpectations: mockQueries(
|
||||||
|
regexp.QuoteMeta(`SELECT zitadel.projections.custom_texts.aggregate_id,`+
|
||||||
|
` zitadel.projections.custom_texts.sequence,`+
|
||||||
|
` zitadel.projections.custom_texts.creation_date,`+
|
||||||
|
` zitadel.projections.custom_texts.change_date,`+
|
||||||
|
` zitadel.projections.custom_texts.language,`+
|
||||||
|
` zitadel.projections.custom_texts.template,`+
|
||||||
|
` zitadel.projections.custom_texts.key,`+
|
||||||
|
` zitadel.projections.custom_texts.text,`+
|
||||||
|
` COUNT(*) OVER ()`+
|
||||||
|
` FROM zitadel.projections.custom_texts`),
|
||||||
|
nil,
|
||||||
|
nil,
|
||||||
|
),
|
||||||
|
err: func(err error) (error, bool) {
|
||||||
|
if !errs.IsNotFound(err) {
|
||||||
|
return fmt.Errorf("err should be zitadel.NotFoundError got: %w", err), false
|
||||||
|
}
|
||||||
|
return nil, true
|
||||||
|
},
|
||||||
|
},
|
||||||
|
object: &CustomTexts{CustomTexts: []*CustomText{}},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "prepareCustomTextQuery one result",
|
||||||
|
prepare: prepareCustomTextsQuery,
|
||||||
|
want: want{
|
||||||
|
sqlExpectations: mockQueries(
|
||||||
|
regexp.QuoteMeta(`SELECT zitadel.projections.custom_texts.aggregate_id,`+
|
||||||
|
` zitadel.projections.custom_texts.sequence,`+
|
||||||
|
` zitadel.projections.custom_texts.creation_date,`+
|
||||||
|
` zitadel.projections.custom_texts.change_date,`+
|
||||||
|
` zitadel.projections.custom_texts.language,`+
|
||||||
|
` zitadel.projections.custom_texts.template,`+
|
||||||
|
` zitadel.projections.custom_texts.key,`+
|
||||||
|
` zitadel.projections.custom_texts.text,`+
|
||||||
|
` COUNT(*) OVER ()`+
|
||||||
|
` FROM zitadel.projections.custom_texts`),
|
||||||
|
[]string{
|
||||||
|
"aggregate_id",
|
||||||
|
"sequence",
|
||||||
|
"creation_date",
|
||||||
|
"change_date",
|
||||||
|
"language",
|
||||||
|
"template",
|
||||||
|
"key",
|
||||||
|
"text",
|
||||||
|
"count",
|
||||||
|
},
|
||||||
|
[][]driver.Value{
|
||||||
|
{
|
||||||
|
"agg-id",
|
||||||
|
uint64(20211109),
|
||||||
|
testNow,
|
||||||
|
testNow,
|
||||||
|
"en",
|
||||||
|
"template",
|
||||||
|
"key",
|
||||||
|
"text",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
),
|
||||||
|
},
|
||||||
|
object: &CustomTexts{
|
||||||
|
SearchResponse: SearchResponse{
|
||||||
|
Count: 1,
|
||||||
|
},
|
||||||
|
CustomTexts: []*CustomText{
|
||||||
|
{
|
||||||
|
AggregateID: "agg-id",
|
||||||
|
CreationDate: testNow,
|
||||||
|
ChangeDate: testNow,
|
||||||
|
Sequence: 20211109,
|
||||||
|
Language: language.English,
|
||||||
|
Template: "template",
|
||||||
|
Key: "key",
|
||||||
|
Text: "text",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "prepareCustomTextQuery multiple result",
|
||||||
|
prepare: prepareCustomTextsQuery,
|
||||||
|
want: want{
|
||||||
|
sqlExpectations: mockQueries(
|
||||||
|
regexp.QuoteMeta(`SELECT zitadel.projections.custom_texts.aggregate_id,`+
|
||||||
|
` zitadel.projections.custom_texts.sequence,`+
|
||||||
|
` zitadel.projections.custom_texts.creation_date,`+
|
||||||
|
` zitadel.projections.custom_texts.change_date,`+
|
||||||
|
` zitadel.projections.custom_texts.language,`+
|
||||||
|
` zitadel.projections.custom_texts.template,`+
|
||||||
|
` zitadel.projections.custom_texts.key,`+
|
||||||
|
` zitadel.projections.custom_texts.text,`+
|
||||||
|
` COUNT(*) OVER ()`+
|
||||||
|
` FROM zitadel.projections.custom_texts`),
|
||||||
|
[]string{
|
||||||
|
"aggregate_id",
|
||||||
|
"sequence",
|
||||||
|
"creation_date",
|
||||||
|
"change_date",
|
||||||
|
"language",
|
||||||
|
"template",
|
||||||
|
"key",
|
||||||
|
"text",
|
||||||
|
"count",
|
||||||
|
},
|
||||||
|
[][]driver.Value{
|
||||||
|
{
|
||||||
|
"agg-id",
|
||||||
|
uint64(20211109),
|
||||||
|
testNow,
|
||||||
|
testNow,
|
||||||
|
"en",
|
||||||
|
"template",
|
||||||
|
"key",
|
||||||
|
"text",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"agg-id",
|
||||||
|
uint64(20211109),
|
||||||
|
testNow,
|
||||||
|
testNow,
|
||||||
|
"en",
|
||||||
|
"template",
|
||||||
|
"key2",
|
||||||
|
"text",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
),
|
||||||
|
},
|
||||||
|
object: &CustomTexts{
|
||||||
|
SearchResponse: SearchResponse{
|
||||||
|
Count: 2,
|
||||||
|
},
|
||||||
|
CustomTexts: []*CustomText{
|
||||||
|
{
|
||||||
|
AggregateID: "agg-id",
|
||||||
|
CreationDate: testNow,
|
||||||
|
ChangeDate: testNow,
|
||||||
|
Sequence: 20211109,
|
||||||
|
Language: language.English,
|
||||||
|
Template: "template",
|
||||||
|
Key: "key",
|
||||||
|
Text: "text",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
AggregateID: "agg-id",
|
||||||
|
CreationDate: testNow,
|
||||||
|
ChangeDate: testNow,
|
||||||
|
Sequence: 20211109,
|
||||||
|
Language: language.English,
|
||||||
|
Template: "template",
|
||||||
|
Key: "key2",
|
||||||
|
Text: "text",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "prepareCustomTextQuery sql err",
|
||||||
|
prepare: prepareCustomTextsQuery,
|
||||||
|
want: want{
|
||||||
|
sqlExpectations: mockQueryErr(
|
||||||
|
regexp.QuoteMeta(`SELECT zitadel.projections.custom_texts.aggregate_id,`+
|
||||||
|
` zitadel.projections.custom_texts.sequence,`+
|
||||||
|
` zitadel.projections.custom_texts.creation_date,`+
|
||||||
|
` zitadel.projections.custom_texts.change_date,`+
|
||||||
|
` zitadel.projections.custom_texts.language,`+
|
||||||
|
` zitadel.projections.custom_texts.template,`+
|
||||||
|
` zitadel.projections.custom_texts.key,`+
|
||||||
|
` zitadel.projections.custom_texts.text,`+
|
||||||
|
` COUNT(*) OVER ()`+
|
||||||
|
` FROM zitadel.projections.custom_texts`),
|
||||||
|
sql.ErrConnDone,
|
||||||
|
),
|
||||||
|
err: func(err error) (error, bool) {
|
||||||
|
if !errors.Is(err, sql.ErrConnDone) {
|
||||||
|
return fmt.Errorf("err should be sql.ErrConnDone got: %w", err), false
|
||||||
|
}
|
||||||
|
return nil, true
|
||||||
|
},
|
||||||
|
},
|
||||||
|
object: nil,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
for _, tt := range tests {
|
||||||
|
t.Run(tt.name, func(t *testing.T) {
|
||||||
|
assertPrepare(t, tt.prepare, tt.object, tt.want.sqlExpectations, tt.want.err)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
126
internal/query/mail_template.go
Normal file
126
internal/query/mail_template.go
Normal file
@ -0,0 +1,126 @@
|
|||||||
|
package query
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"database/sql"
|
||||||
|
errs "errors"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
sq "github.com/Masterminds/squirrel"
|
||||||
|
"github.com/caos/zitadel/internal/domain"
|
||||||
|
"github.com/caos/zitadel/internal/errors"
|
||||||
|
"github.com/caos/zitadel/internal/query/projection"
|
||||||
|
)
|
||||||
|
|
||||||
|
type MailTemplate struct {
|
||||||
|
AggregateID string
|
||||||
|
Sequence uint64
|
||||||
|
CreationDate time.Time
|
||||||
|
ChangeDate time.Time
|
||||||
|
State domain.PolicyState
|
||||||
|
|
||||||
|
Template []byte
|
||||||
|
IsDefault bool
|
||||||
|
}
|
||||||
|
|
||||||
|
var (
|
||||||
|
mailTemplateTable = table{
|
||||||
|
name: projection.MailTemplateTable,
|
||||||
|
}
|
||||||
|
MailTemplateColAggregateID = Column{
|
||||||
|
name: projection.MailTemplateAggregateIDCol,
|
||||||
|
table: mailTemplateTable,
|
||||||
|
}
|
||||||
|
MailTemplateColSequence = Column{
|
||||||
|
name: projection.MailTemplateSequenceCol,
|
||||||
|
table: mailTemplateTable,
|
||||||
|
}
|
||||||
|
MailTemplateColCreationDate = Column{
|
||||||
|
name: projection.MailTemplateCreationDateCol,
|
||||||
|
table: mailTemplateTable,
|
||||||
|
}
|
||||||
|
MailTemplateColChangeDate = Column{
|
||||||
|
name: projection.MailTemplateChangeDateCol,
|
||||||
|
table: mailTemplateTable,
|
||||||
|
}
|
||||||
|
MailTemplateColTemplate = Column{
|
||||||
|
name: projection.MailTemplateTemplateCol,
|
||||||
|
table: mailTemplateTable,
|
||||||
|
}
|
||||||
|
MailTemplateColIsDefault = Column{
|
||||||
|
name: projection.MailTemplateIsDefaultCol,
|
||||||
|
table: mailTemplateTable,
|
||||||
|
}
|
||||||
|
MailTemplateColState = Column{
|
||||||
|
name: projection.MailTemplateStateCol,
|
||||||
|
table: mailTemplateTable,
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
func (q *Queries) MailTemplateByOrg(ctx context.Context, orgID string) (*MailTemplate, error) {
|
||||||
|
stmt, scan := prepareMailTemplateQuery()
|
||||||
|
query, args, err := stmt.Where(
|
||||||
|
sq.Or{
|
||||||
|
sq.Eq{
|
||||||
|
MailTemplateColAggregateID.identifier(): orgID,
|
||||||
|
},
|
||||||
|
sq.Eq{
|
||||||
|
MailTemplateColAggregateID.identifier(): q.iamID,
|
||||||
|
},
|
||||||
|
}).
|
||||||
|
OrderBy(MailTemplateColIsDefault.identifier()).
|
||||||
|
Limit(1).ToSql()
|
||||||
|
if err != nil {
|
||||||
|
return nil, errors.ThrowInternal(err, "QUERY-m0sJg", "Errors.Query.SQLStatement")
|
||||||
|
}
|
||||||
|
|
||||||
|
row := q.client.QueryRowContext(ctx, query, args...)
|
||||||
|
return scan(row)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (q *Queries) DefaultMailTemplate(ctx context.Context) (*MailTemplate, error) {
|
||||||
|
stmt, scan := prepareMailTemplateQuery()
|
||||||
|
query, args, err := stmt.Where(sq.Eq{
|
||||||
|
MailTemplateColAggregateID.identifier(): q.iamID,
|
||||||
|
}).
|
||||||
|
OrderBy(MailTemplateColIsDefault.identifier()).
|
||||||
|
Limit(1).ToSql()
|
||||||
|
if err != nil {
|
||||||
|
return nil, errors.ThrowInternal(err, "QUERY-2m0fH", "Errors.Query.SQLStatement")
|
||||||
|
}
|
||||||
|
|
||||||
|
row := q.client.QueryRowContext(ctx, query, args...)
|
||||||
|
return scan(row)
|
||||||
|
}
|
||||||
|
|
||||||
|
func prepareMailTemplateQuery() (sq.SelectBuilder, func(*sql.Row) (*MailTemplate, error)) {
|
||||||
|
return sq.Select(
|
||||||
|
MailTemplateColAggregateID.identifier(),
|
||||||
|
MailTemplateColSequence.identifier(),
|
||||||
|
MailTemplateColCreationDate.identifier(),
|
||||||
|
MailTemplateColChangeDate.identifier(),
|
||||||
|
MailTemplateColTemplate.identifier(),
|
||||||
|
MailTemplateColIsDefault.identifier(),
|
||||||
|
MailTemplateColState.identifier(),
|
||||||
|
).
|
||||||
|
From(mailTemplateTable.identifier()).PlaceholderFormat(sq.Dollar),
|
||||||
|
func(row *sql.Row) (*MailTemplate, error) {
|
||||||
|
policy := new(MailTemplate)
|
||||||
|
err := row.Scan(
|
||||||
|
&policy.AggregateID,
|
||||||
|
&policy.Sequence,
|
||||||
|
&policy.CreationDate,
|
||||||
|
&policy.ChangeDate,
|
||||||
|
&policy.Template,
|
||||||
|
&policy.IsDefault,
|
||||||
|
&policy.State,
|
||||||
|
)
|
||||||
|
if err != nil {
|
||||||
|
if errs.Is(err, sql.ErrNoRows) {
|
||||||
|
return nil, errors.ThrowNotFound(err, "QUERY-2NO0g", "Errors.MailTemplate.NotFound")
|
||||||
|
}
|
||||||
|
return nil, errors.ThrowInternal(err, "QUERY-4Nisf", "Errors.Internal")
|
||||||
|
}
|
||||||
|
return policy, nil
|
||||||
|
}
|
||||||
|
}
|
324
internal/query/message_text.go
Normal file
324
internal/query/message_text.go
Normal file
@ -0,0 +1,324 @@
|
|||||||
|
package query
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"database/sql"
|
||||||
|
"encoding/json"
|
||||||
|
errs "errors"
|
||||||
|
"fmt"
|
||||||
|
"io/ioutil"
|
||||||
|
"net/http"
|
||||||
|
"os"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
sq "github.com/Masterminds/squirrel"
|
||||||
|
"golang.org/x/text/language"
|
||||||
|
"sigs.k8s.io/yaml"
|
||||||
|
|
||||||
|
"github.com/caos/zitadel/internal/domain"
|
||||||
|
"github.com/caos/zitadel/internal/errors"
|
||||||
|
"github.com/caos/zitadel/internal/query/projection"
|
||||||
|
)
|
||||||
|
|
||||||
|
type MessageTexts struct {
|
||||||
|
InitCode MessageText
|
||||||
|
PasswordReset MessageText
|
||||||
|
VerifyEmail MessageText
|
||||||
|
VerifyPhone MessageText
|
||||||
|
DomainClaimed MessageText
|
||||||
|
PasswordlessRegistration MessageText
|
||||||
|
}
|
||||||
|
|
||||||
|
type MessageText struct {
|
||||||
|
AggregateID string
|
||||||
|
Sequence uint64
|
||||||
|
CreationDate time.Time
|
||||||
|
ChangeDate time.Time
|
||||||
|
State domain.PolicyState
|
||||||
|
|
||||||
|
IsDefault bool
|
||||||
|
|
||||||
|
Type string
|
||||||
|
Language language.Tag
|
||||||
|
Title string
|
||||||
|
PreHeader string
|
||||||
|
Subject string
|
||||||
|
Greeting string
|
||||||
|
Text string
|
||||||
|
ButtonText string
|
||||||
|
Footer string
|
||||||
|
}
|
||||||
|
|
||||||
|
var (
|
||||||
|
messageTextTable = table{
|
||||||
|
name: projection.MessageTextTable,
|
||||||
|
}
|
||||||
|
MessageTextColAggregateID = Column{
|
||||||
|
name: projection.MessageTextAggregateIDCol,
|
||||||
|
table: messageTextTable,
|
||||||
|
}
|
||||||
|
MessageTextColSequence = Column{
|
||||||
|
name: projection.MessageTextSequenceCol,
|
||||||
|
table: messageTextTable,
|
||||||
|
}
|
||||||
|
MessageTextColCreationDate = Column{
|
||||||
|
name: projection.MessageTextCreationDateCol,
|
||||||
|
table: messageTextTable,
|
||||||
|
}
|
||||||
|
MessageTextColChangeDate = Column{
|
||||||
|
name: projection.MessageTextChangeDateCol,
|
||||||
|
table: messageTextTable,
|
||||||
|
}
|
||||||
|
MessageTextColState = Column{
|
||||||
|
name: projection.MessageTextStateCol,
|
||||||
|
table: messageTextTable,
|
||||||
|
}
|
||||||
|
MessageTextColType = Column{
|
||||||
|
name: projection.MessageTextTypeCol,
|
||||||
|
table: messageTextTable,
|
||||||
|
}
|
||||||
|
MessageTextColLanguage = Column{
|
||||||
|
name: projection.MessageTextLanguageCol,
|
||||||
|
table: messageTextTable,
|
||||||
|
}
|
||||||
|
MessageTextColTitle = Column{
|
||||||
|
name: projection.MessageTextTitleCol,
|
||||||
|
table: messageTextTable,
|
||||||
|
}
|
||||||
|
MessageTextColPreHeader = Column{
|
||||||
|
name: projection.MessageTextPreHeaderCol,
|
||||||
|
table: messageTextTable,
|
||||||
|
}
|
||||||
|
MessageTextColSubject = Column{
|
||||||
|
name: projection.MessageTextSubjectCol,
|
||||||
|
table: messageTextTable,
|
||||||
|
}
|
||||||
|
MessageTextColGreeting = Column{
|
||||||
|
name: projection.MessageTextGreetingCol,
|
||||||
|
table: messageTextTable,
|
||||||
|
}
|
||||||
|
MessageTextColText = Column{
|
||||||
|
name: projection.MessageTextTextCol,
|
||||||
|
table: messageTextTable,
|
||||||
|
}
|
||||||
|
MessageTextColButtonText = Column{
|
||||||
|
name: projection.MessageTextButtonTextCol,
|
||||||
|
table: messageTextTable,
|
||||||
|
}
|
||||||
|
MessageTextColFooter = Column{
|
||||||
|
name: projection.MessageTextFooterCol,
|
||||||
|
table: messageTextTable,
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
func (q *Queries) MessageTextByOrg(ctx context.Context, orgID string) (*MessageText, error) {
|
||||||
|
stmt, scan := prepareMessageTextQuery()
|
||||||
|
query, args, err := stmt.Where(
|
||||||
|
sq.Or{
|
||||||
|
sq.Eq{
|
||||||
|
MessageTextColAggregateID.identifier(): orgID,
|
||||||
|
},
|
||||||
|
sq.Eq{
|
||||||
|
MessageTextColAggregateID.identifier(): q.iamID,
|
||||||
|
},
|
||||||
|
}).
|
||||||
|
OrderBy(MessageTextColAggregateID.identifier()).
|
||||||
|
Limit(1).ToSql()
|
||||||
|
if err != nil {
|
||||||
|
return nil, errors.ThrowInternal(err, "QUERY-90n3N", "Errors.Query.SQLStatement")
|
||||||
|
}
|
||||||
|
|
||||||
|
row := q.client.QueryRowContext(ctx, query, args...)
|
||||||
|
return scan(row)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (q *Queries) DefaultMessageText(ctx context.Context) (*MessageText, error) {
|
||||||
|
stmt, scan := prepareMessageTextQuery()
|
||||||
|
query, args, err := stmt.Where(sq.Eq{
|
||||||
|
MessageTextColAggregateID.identifier(): q.iamID,
|
||||||
|
}).
|
||||||
|
Limit(1).ToSql()
|
||||||
|
if err != nil {
|
||||||
|
return nil, errors.ThrowInternal(err, "QUERY-1b9mf", "Errors.Query.SQLStatement")
|
||||||
|
}
|
||||||
|
|
||||||
|
row := q.client.QueryRowContext(ctx, query, args...)
|
||||||
|
return scan(row)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (q *Queries) DefaultMessageTextByTypeAndLanguageFromFileSystem(messageType, language string) (*MessageText, error) {
|
||||||
|
contents, err := q.readNotificationTextMessages(language)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
messageTexts := new(MessageTexts)
|
||||||
|
if err := yaml.Unmarshal(contents, messageTexts); err != nil {
|
||||||
|
return nil, errors.ThrowInternal(err, "TEXT-3N9fs", "Errors.TranslationFile.ReadError")
|
||||||
|
}
|
||||||
|
return messageTexts.GetMessageTextByType(messageType), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (q *Queries) CustomMessageTextByTypeAndLanguage(ctx context.Context, aggregateID, messageType, language string) (*MessageText, error) {
|
||||||
|
stmt, scan := prepareMessageTextQuery()
|
||||||
|
query, args, err := stmt.Where(
|
||||||
|
sq.Eq{
|
||||||
|
MessageTextColAggregateID.identifier(): aggregateID,
|
||||||
|
MessageTextColType.identifier(): messageType,
|
||||||
|
MessageTextColLanguage.identifier(): language,
|
||||||
|
},
|
||||||
|
).
|
||||||
|
Limit(1).ToSql()
|
||||||
|
if err != nil {
|
||||||
|
return nil, errors.ThrowInternal(err, "QUERY-1b9mf", "Errors.Query.SQLStatement")
|
||||||
|
}
|
||||||
|
|
||||||
|
row := q.client.QueryRowContext(ctx, query, args...)
|
||||||
|
return scan(row)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (q *Queries) IAMMessageTextByTypeAndLanguage(ctx context.Context, messageType, language string) (*MessageText, error) {
|
||||||
|
contents, err := q.readNotificationTextMessages(language)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
notificationTextMap := make(map[string]interface{})
|
||||||
|
if err := yaml.Unmarshal(contents, ¬ificationTextMap); err != nil {
|
||||||
|
return nil, errors.ThrowInternal(err, "QUERY-ekjFF", "Errors.TranslationFile.ReadError")
|
||||||
|
}
|
||||||
|
texts, err := q.CustomTextList(ctx, domain.IAMID, messageType, language)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
for _, text := range texts.CustomTexts {
|
||||||
|
messageTextMap, ok := notificationTextMap[messageType].(map[string]interface{})
|
||||||
|
if !ok {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
messageTextMap[text.Key] = text.Text
|
||||||
|
}
|
||||||
|
jsonbody, err := json.Marshal(notificationTextMap)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
return nil, errors.ThrowInternal(err, "QUERY-3m8fJ", "Errors.TranslationFile.MergeError")
|
||||||
|
}
|
||||||
|
notificationText := new(MessageTexts)
|
||||||
|
if err := json.Unmarshal(jsonbody, ¬ificationText); err != nil {
|
||||||
|
return nil, errors.ThrowInternal(err, "QUERY-9MkfD", "Errors.TranslationFile.MergeError")
|
||||||
|
}
|
||||||
|
result := notificationText.GetMessageTextByType(messageType)
|
||||||
|
result.IsDefault = true
|
||||||
|
return result, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (q *Queries) readNotificationTextMessages(language string) ([]byte, error) {
|
||||||
|
q.mutex.Lock()
|
||||||
|
defer q.mutex.Unlock()
|
||||||
|
var err error
|
||||||
|
contents, ok := q.NotificationTranslationFileContents[language]
|
||||||
|
if !ok {
|
||||||
|
contents, err = q.readTranslationFile(q.NotificationDir, fmt.Sprintf("/i18n/%s.yaml", language))
|
||||||
|
if errors.IsNotFound(err) {
|
||||||
|
contents, err = q.readTranslationFile(q.NotificationDir, fmt.Sprintf("/i18n/%s.yaml", q.DefaultLanguage.String()))
|
||||||
|
}
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
q.NotificationTranslationFileContents[language] = contents
|
||||||
|
}
|
||||||
|
return contents, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func prepareMessageTextQuery() (sq.SelectBuilder, func(*sql.Row) (*MessageText, error)) {
|
||||||
|
return sq.Select(
|
||||||
|
MessageTextColAggregateID.identifier(),
|
||||||
|
MessageTextColSequence.identifier(),
|
||||||
|
MessageTextColCreationDate.identifier(),
|
||||||
|
MessageTextColChangeDate.identifier(),
|
||||||
|
MessageTextColState.identifier(),
|
||||||
|
MessageTextColType.identifier(),
|
||||||
|
MessageTextColLanguage.identifier(),
|
||||||
|
MessageTextColTitle.identifier(),
|
||||||
|
MessageTextColPreHeader.identifier(),
|
||||||
|
MessageTextColSubject.identifier(),
|
||||||
|
MessageTextColGreeting.identifier(),
|
||||||
|
MessageTextColText.identifier(),
|
||||||
|
MessageTextColButtonText.identifier(),
|
||||||
|
MessageTextColFooter.identifier(),
|
||||||
|
).
|
||||||
|
From(messageTextTable.identifier()).PlaceholderFormat(sq.Dollar),
|
||||||
|
func(row *sql.Row) (*MessageText, error) {
|
||||||
|
msg := new(MessageText)
|
||||||
|
lang := ""
|
||||||
|
title := sql.NullString{}
|
||||||
|
preHeader := sql.NullString{}
|
||||||
|
subject := sql.NullString{}
|
||||||
|
greeting := sql.NullString{}
|
||||||
|
text := sql.NullString{}
|
||||||
|
buttonText := sql.NullString{}
|
||||||
|
footer := sql.NullString{}
|
||||||
|
err := row.Scan(
|
||||||
|
&msg.AggregateID,
|
||||||
|
&msg.Sequence,
|
||||||
|
&msg.CreationDate,
|
||||||
|
&msg.ChangeDate,
|
||||||
|
&msg.State,
|
||||||
|
&msg.Type,
|
||||||
|
&lang,
|
||||||
|
&title,
|
||||||
|
&preHeader,
|
||||||
|
&subject,
|
||||||
|
&greeting,
|
||||||
|
&text,
|
||||||
|
&buttonText,
|
||||||
|
&footer,
|
||||||
|
)
|
||||||
|
if err != nil {
|
||||||
|
if errs.Is(err, sql.ErrNoRows) {
|
||||||
|
return nil, errors.ThrowNotFound(err, "QUERY-3nlrS", "Errors.MessageText.NotFound")
|
||||||
|
}
|
||||||
|
return nil, errors.ThrowInternal(err, "QUERY-499gJ", "Errors.Internal")
|
||||||
|
}
|
||||||
|
msg.Language = language.Make(lang)
|
||||||
|
msg.Title = title.String
|
||||||
|
msg.PreHeader = preHeader.String
|
||||||
|
msg.Subject = subject.String
|
||||||
|
msg.Greeting = greeting.String
|
||||||
|
msg.Text = text.String
|
||||||
|
msg.ButtonText = buttonText.String
|
||||||
|
msg.Footer = footer.String
|
||||||
|
return msg, nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (q *Queries) readTranslationFile(dir http.FileSystem, filename string) ([]byte, error) {
|
||||||
|
r, err := dir.Open(filename)
|
||||||
|
if os.IsNotExist(err) {
|
||||||
|
return nil, errors.ThrowNotFound(err, "QUERY-sN9wg", "Errors.TranslationFile.NotFound")
|
||||||
|
}
|
||||||
|
if err != nil {
|
||||||
|
return nil, errors.ThrowInternal(err, "QUERY-93njw", "Errors.TranslationFile.ReadError")
|
||||||
|
}
|
||||||
|
contents, err := ioutil.ReadAll(r)
|
||||||
|
if err != nil {
|
||||||
|
return nil, errors.ThrowInternal(err, "QUERY-l0fse", "Errors.TranslationFile.ReadError")
|
||||||
|
}
|
||||||
|
return contents, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *MessageTexts) GetMessageTextByType(msgType string) *MessageText {
|
||||||
|
switch msgType {
|
||||||
|
case domain.InitCodeMessageType:
|
||||||
|
return &m.InitCode
|
||||||
|
case domain.PasswordResetMessageType:
|
||||||
|
return &m.PasswordReset
|
||||||
|
case domain.VerifyEmailMessageType:
|
||||||
|
return &m.VerifyEmail
|
||||||
|
case domain.VerifyPhoneMessageType:
|
||||||
|
return &m.VerifyPhone
|
||||||
|
case domain.DomainClaimedMessageType:
|
||||||
|
return &m.DomainClaimed
|
||||||
|
case domain.PasswordlessRegistrationMessageType:
|
||||||
|
return &m.PasswordlessRegistration
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
167
internal/query/message_text_test.go
Normal file
167
internal/query/message_text_test.go
Normal file
@ -0,0 +1,167 @@
|
|||||||
|
package query
|
||||||
|
|
||||||
|
import (
|
||||||
|
"database/sql"
|
||||||
|
"database/sql/driver"
|
||||||
|
"errors"
|
||||||
|
"fmt"
|
||||||
|
"regexp"
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/caos/zitadel/internal/domain"
|
||||||
|
errs "github.com/caos/zitadel/internal/errors"
|
||||||
|
"golang.org/x/text/language"
|
||||||
|
)
|
||||||
|
|
||||||
|
func Test_MessageTextPrepares(t *testing.T) {
|
||||||
|
type want struct {
|
||||||
|
sqlExpectations sqlExpectation
|
||||||
|
err checkErr
|
||||||
|
}
|
||||||
|
tests := []struct {
|
||||||
|
name string
|
||||||
|
prepare interface{}
|
||||||
|
want want
|
||||||
|
object interface{}
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
name: "prepareMessageTextQuery no result",
|
||||||
|
prepare: prepareMessageTextQuery,
|
||||||
|
want: want{
|
||||||
|
sqlExpectations: mockQueries(
|
||||||
|
regexp.QuoteMeta(`SELECT zitadel.projections.message_texts.aggregate_id,`+
|
||||||
|
` zitadel.projections.message_texts.sequence,`+
|
||||||
|
` zitadel.projections.message_texts.creation_date,`+
|
||||||
|
` zitadel.projections.message_texts.change_date,`+
|
||||||
|
` zitadel.projections.message_texts.state,`+
|
||||||
|
` zitadel.projections.message_texts.type,`+
|
||||||
|
` zitadel.projections.message_texts.language,`+
|
||||||
|
` zitadel.projections.message_texts.title,`+
|
||||||
|
` zitadel.projections.message_texts.pre_header,`+
|
||||||
|
` zitadel.projections.message_texts.subject,`+
|
||||||
|
` zitadel.projections.message_texts.greeting,`+
|
||||||
|
` zitadel.projections.message_texts.text,`+
|
||||||
|
` zitadel.projections.message_texts.button_text,`+
|
||||||
|
` zitadel.projections.message_texts.footer_text`+
|
||||||
|
` FROM zitadel.projections.message_texts`),
|
||||||
|
nil,
|
||||||
|
nil,
|
||||||
|
),
|
||||||
|
err: func(err error) (error, bool) {
|
||||||
|
if !errs.IsNotFound(err) {
|
||||||
|
return fmt.Errorf("err should be zitadel.NotFoundError got: %w", err), false
|
||||||
|
}
|
||||||
|
return nil, true
|
||||||
|
},
|
||||||
|
},
|
||||||
|
object: (*MessageText)(nil),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "prepareMesssageTextQuery found",
|
||||||
|
prepare: prepareMessageTextQuery,
|
||||||
|
want: want{
|
||||||
|
sqlExpectations: mockQuery(
|
||||||
|
regexp.QuoteMeta(`SELECT zitadel.projections.message_texts.aggregate_id,`+
|
||||||
|
` zitadel.projections.message_texts.sequence,`+
|
||||||
|
` zitadel.projections.message_texts.creation_date,`+
|
||||||
|
` zitadel.projections.message_texts.change_date,`+
|
||||||
|
` zitadel.projections.message_texts.state,`+
|
||||||
|
` zitadel.projections.message_texts.type,`+
|
||||||
|
` zitadel.projections.message_texts.language,`+
|
||||||
|
` zitadel.projections.message_texts.title,`+
|
||||||
|
` zitadel.projections.message_texts.pre_header,`+
|
||||||
|
` zitadel.projections.message_texts.subject,`+
|
||||||
|
` zitadel.projections.message_texts.greeting,`+
|
||||||
|
` zitadel.projections.message_texts.text,`+
|
||||||
|
` zitadel.projections.message_texts.button_text,`+
|
||||||
|
` zitadel.projections.message_texts.footer_text`+
|
||||||
|
` FROM zitadel.projections.message_texts`),
|
||||||
|
[]string{
|
||||||
|
"aggregate_id",
|
||||||
|
"sequence",
|
||||||
|
"creation_date",
|
||||||
|
"change_date",
|
||||||
|
"state",
|
||||||
|
"type",
|
||||||
|
"language",
|
||||||
|
"title",
|
||||||
|
"pre_header",
|
||||||
|
"subject",
|
||||||
|
"greeting",
|
||||||
|
"text",
|
||||||
|
"button_text",
|
||||||
|
"footer_text",
|
||||||
|
},
|
||||||
|
[]driver.Value{
|
||||||
|
"agg-id",
|
||||||
|
uint64(20211109),
|
||||||
|
testNow,
|
||||||
|
testNow,
|
||||||
|
domain.PolicyStateActive,
|
||||||
|
"type",
|
||||||
|
"en",
|
||||||
|
"title",
|
||||||
|
"pre_header",
|
||||||
|
"subject",
|
||||||
|
"greeting",
|
||||||
|
"text",
|
||||||
|
"button_text",
|
||||||
|
"footer_text",
|
||||||
|
},
|
||||||
|
),
|
||||||
|
},
|
||||||
|
object: &MessageText{
|
||||||
|
AggregateID: "agg-id",
|
||||||
|
CreationDate: testNow,
|
||||||
|
ChangeDate: testNow,
|
||||||
|
Sequence: 20211109,
|
||||||
|
State: domain.PolicyStateActive,
|
||||||
|
Type: "type",
|
||||||
|
Language: language.English,
|
||||||
|
Title: "title",
|
||||||
|
PreHeader: "pre_header",
|
||||||
|
Subject: "subject",
|
||||||
|
Greeting: "greeting",
|
||||||
|
Text: "text",
|
||||||
|
ButtonText: "button_text",
|
||||||
|
Footer: "footer_text",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "prepareMessageTextQuery sql err",
|
||||||
|
prepare: prepareMessageTextQuery,
|
||||||
|
want: want{
|
||||||
|
sqlExpectations: mockQueryErr(
|
||||||
|
regexp.QuoteMeta(`SELECT zitadel.projections.message_texts.aggregate_id,`+
|
||||||
|
` zitadel.projections.message_texts.sequence,`+
|
||||||
|
` zitadel.projections.message_texts.creation_date,`+
|
||||||
|
` zitadel.projections.message_texts.change_date,`+
|
||||||
|
` zitadel.projections.message_texts.state,`+
|
||||||
|
` zitadel.projections.message_texts.type,`+
|
||||||
|
` zitadel.projections.message_texts.language,`+
|
||||||
|
` zitadel.projections.message_texts.title,`+
|
||||||
|
` zitadel.projections.message_texts.pre_header,`+
|
||||||
|
` zitadel.projections.message_texts.subject,`+
|
||||||
|
` zitadel.projections.message_texts.greeting,`+
|
||||||
|
` zitadel.projections.message_texts.text,`+
|
||||||
|
` zitadel.projections.message_texts.button_text,`+
|
||||||
|
` zitadel.projections.message_texts.footer_text`+
|
||||||
|
` FROM zitadel.projections.message_texts`),
|
||||||
|
sql.ErrConnDone,
|
||||||
|
),
|
||||||
|
err: func(err error) (error, bool) {
|
||||||
|
if !errors.Is(err, sql.ErrConnDone) {
|
||||||
|
return fmt.Errorf("err should be sql.ErrConnDone got: %w", err), false
|
||||||
|
}
|
||||||
|
return nil, true
|
||||||
|
},
|
||||||
|
},
|
||||||
|
object: nil,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
for _, tt := range tests {
|
||||||
|
t.Run(tt.name, func(t *testing.T) {
|
||||||
|
assertPrepare(t, tt.prepare, tt.object, tt.want.sqlExpectations, tt.want.err)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
@ -92,7 +92,7 @@ func (p *CustomTextProjection) reduceSet(event eventstore.EventReader) (*handler
|
|||||||
logging.LogWithFields("PROJE-g0Jfs", "seq", event.Sequence(), "expectedTypes", []eventstore.EventType{org.CustomTextSetEventType, iam.CustomTextSetEventType}).Error("wrong event type")
|
logging.LogWithFields("PROJE-g0Jfs", "seq", event.Sequence(), "expectedTypes", []eventstore.EventType{org.CustomTextSetEventType, iam.CustomTextSetEventType}).Error("wrong event type")
|
||||||
return nil, errors.ThrowInvalidArgument(nil, "PROJE-KKfw4", "reduce.wrong.event.type")
|
return nil, errors.ThrowInvalidArgument(nil, "PROJE-KKfw4", "reduce.wrong.event.type")
|
||||||
}
|
}
|
||||||
return crdb.NewCreateStatement(
|
return crdb.NewUpsertStatement(
|
||||||
&customTextEvent,
|
&customTextEvent,
|
||||||
[]handler.Column{
|
[]handler.Column{
|
||||||
handler.NewCol(CustomTextAggregateIDCol, customTextEvent.Aggregate().ID),
|
handler.NewCol(CustomTextAggregateIDCol, customTextEvent.Aggregate().ID),
|
||||||
@ -124,7 +124,7 @@ func (p *CustomTextProjection) reduceRemoved(event eventstore.EventReader) (*han
|
|||||||
handler.NewCond(CustomTextAggregateIDCol, customTextEvent.Aggregate().ID),
|
handler.NewCond(CustomTextAggregateIDCol, customTextEvent.Aggregate().ID),
|
||||||
handler.NewCond(CustomTextTemplateCol, customTextEvent.Template),
|
handler.NewCond(CustomTextTemplateCol, customTextEvent.Template),
|
||||||
handler.NewCond(CustomTextKeyCol, customTextEvent.Key),
|
handler.NewCond(CustomTextKeyCol, customTextEvent.Key),
|
||||||
handler.NewCond(CustomTextLanguageCol, customTextEvent.Language),
|
handler.NewCond(CustomTextLanguageCol, customTextEvent.Language.String()),
|
||||||
}), nil
|
}), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -45,7 +45,7 @@ func TestCustomTextProjection_reduces(t *testing.T) {
|
|||||||
executer: &testExecuter{
|
executer: &testExecuter{
|
||||||
executions: []execution{
|
executions: []execution{
|
||||||
{
|
{
|
||||||
expectedStmt: "INSERT INTO zitadel.projections.custom_texts (aggregate_id, creation_date, change_date, sequence, is_default, template, language, key, text) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9)",
|
expectedStmt: "UPSERT INTO zitadel.projections.custom_texts (aggregate_id, creation_date, change_date, sequence, is_default, template, language, key, text) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9)",
|
||||||
expectedArgs: []interface{}{
|
expectedArgs: []interface{}{
|
||||||
"agg-id",
|
"agg-id",
|
||||||
anyArg{},
|
anyArg{},
|
||||||
@ -89,7 +89,7 @@ func TestCustomTextProjection_reduces(t *testing.T) {
|
|||||||
"agg-id",
|
"agg-id",
|
||||||
"InitCode",
|
"InitCode",
|
||||||
"Text",
|
"Text",
|
||||||
language.English,
|
"en",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@ -152,7 +152,7 @@ func TestCustomTextProjection_reduces(t *testing.T) {
|
|||||||
executer: &testExecuter{
|
executer: &testExecuter{
|
||||||
executions: []execution{
|
executions: []execution{
|
||||||
{
|
{
|
||||||
expectedStmt: "INSERT INTO zitadel.projections.custom_texts (aggregate_id, creation_date, change_date, sequence, is_default, template, language, key, text) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9)",
|
expectedStmt: "UPSERT INTO zitadel.projections.custom_texts (aggregate_id, creation_date, change_date, sequence, is_default, template, language, key, text) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9)",
|
||||||
expectedArgs: []interface{}{
|
expectedArgs: []interface{}{
|
||||||
"agg-id",
|
"agg-id",
|
||||||
anyArg{},
|
anyArg{},
|
||||||
@ -196,7 +196,7 @@ func TestCustomTextProjection_reduces(t *testing.T) {
|
|||||||
"agg-id",
|
"agg-id",
|
||||||
"InitCode",
|
"InitCode",
|
||||||
"Text",
|
"Text",
|
||||||
language.English,
|
"en",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
@ -96,7 +96,7 @@ func (p *MessageTextProjection) reduceAdded(event eventstore.EventReader) (*hand
|
|||||||
return nil, errors.ThrowInvalidArgument(nil, "PROJE-2n90r", "reduce.wrong.event.type")
|
return nil, errors.ThrowInvalidArgument(nil, "PROJE-2n90r", "reduce.wrong.event.type")
|
||||||
}
|
}
|
||||||
if !isMessageTemplate(templateEvent.Template) {
|
if !isMessageTemplate(templateEvent.Template) {
|
||||||
return nil, nil
|
return crdb.NewNoOpStatement(event), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
cols := []handler.Column{
|
cols := []handler.Column{
|
||||||
|
@ -3,7 +3,10 @@ package query
|
|||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"database/sql"
|
"database/sql"
|
||||||
|
"net/http"
|
||||||
|
"sync"
|
||||||
|
|
||||||
|
"github.com/caos/logging"
|
||||||
sd "github.com/caos/zitadel/internal/config/systemdefaults"
|
sd "github.com/caos/zitadel/internal/config/systemdefaults"
|
||||||
"github.com/caos/zitadel/internal/config/types"
|
"github.com/caos/zitadel/internal/config/types"
|
||||||
"github.com/caos/zitadel/internal/eventstore"
|
"github.com/caos/zitadel/internal/eventstore"
|
||||||
@ -16,12 +19,21 @@ import (
|
|||||||
"github.com/caos/zitadel/internal/repository/project"
|
"github.com/caos/zitadel/internal/repository/project"
|
||||||
usr_repo "github.com/caos/zitadel/internal/repository/user"
|
usr_repo "github.com/caos/zitadel/internal/repository/user"
|
||||||
"github.com/caos/zitadel/internal/telemetry/tracing"
|
"github.com/caos/zitadel/internal/telemetry/tracing"
|
||||||
|
"github.com/rakyll/statik/fs"
|
||||||
|
"golang.org/x/text/language"
|
||||||
)
|
)
|
||||||
|
|
||||||
type Queries struct {
|
type Queries struct {
|
||||||
iamID string
|
iamID string
|
||||||
eventstore *eventstore.Eventstore
|
eventstore *eventstore.Eventstore
|
||||||
client *sql.DB
|
client *sql.DB
|
||||||
|
|
||||||
|
DefaultLanguage language.Tag
|
||||||
|
LoginDir http.FileSystem
|
||||||
|
NotificationDir http.FileSystem
|
||||||
|
mutex sync.Mutex
|
||||||
|
LoginTranslationFileContents map[string][]byte
|
||||||
|
NotificationTranslationFileContents map[string][]byte
|
||||||
}
|
}
|
||||||
|
|
||||||
type Config struct {
|
type Config struct {
|
||||||
@ -34,10 +46,21 @@ func StartQueries(ctx context.Context, es *eventstore.Eventstore, projections pr
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
statikLoginFS, err := fs.NewWithNamespace("login")
|
||||||
|
logging.Log("CONFI-7usEW").OnError(err).Panic("unable to start login statik dir")
|
||||||
|
|
||||||
|
statikNotificationFS, err := fs.NewWithNamespace("notification")
|
||||||
|
logging.Log("CONFI-7usEW").OnError(err).Panic("unable to start notification statik dir")
|
||||||
|
|
||||||
repo = &Queries{
|
repo = &Queries{
|
||||||
iamID: defaults.IamID,
|
iamID: defaults.IamID,
|
||||||
eventstore: es,
|
eventstore: es,
|
||||||
client: sqlClient,
|
client: sqlClient,
|
||||||
|
DefaultLanguage: defaults.DefaultLanguage,
|
||||||
|
LoginDir: statikLoginFS,
|
||||||
|
NotificationDir: statikNotificationFS,
|
||||||
|
LoginTranslationFileContents: make(map[string][]byte),
|
||||||
|
NotificationTranslationFileContents: make(map[string][]byte),
|
||||||
}
|
}
|
||||||
iam_repo.RegisterEventMappers(repo.eventstore)
|
iam_repo.RegisterEventMappers(repo.eventstore)
|
||||||
usr_repo.RegisterEventMappers(repo.eventstore)
|
usr_repo.RegisterEventMappers(repo.eventstore)
|
||||||
|
@ -289,7 +289,7 @@ service ManagementService {
|
|||||||
// Changes the username
|
// Changes the username
|
||||||
rpc UpdateUserName(UpdateUserNameRequest) returns (UpdateUserNameResponse) {
|
rpc UpdateUserName(UpdateUserNameRequest) returns (UpdateUserNameResponse) {
|
||||||
option (google.api.http) = {
|
option (google.api.http) = {
|
||||||
get: "/users/{user_id}/username"
|
put: "/users/{user_id}/username"
|
||||||
};
|
};
|
||||||
|
|
||||||
option (zitadel.v1.auth_option) = {
|
option (zitadel.v1.auth_option) = {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user