feat(database): support for postgres (#3998)

* beginning with postgres statements

* try pgx

* use pgx

* database

* init works for postgres

* arrays working

* init for cockroach

* init

* start tests

* tests

* TESTS

* ch

* ch

* chore: use go 1.18

* read stmts

* fix typo

* tests

* connection string

* add missing error handler

* cleanup

* start all apis

* go mod tidy

* old update

* switch back to minute

* on conflict

* replace string slice with `database.StringArray` in db models

* fix tests and start

* update go version in dockerfile

* setup go

* clean up

* remove notification migration

* update

* docs: add deploy guide for postgres

* fix: revert sonyflake

* use `database.StringArray` for daos

* use `database.StringArray` every where

* new tables

* index naming,
metadata primary key,
project grant role key type

* docs(postgres): change to beta

* chore: correct compose

* fix(defaults): add empty postgres config

* refactor: remove unused code

* docs: add postgres to self hosted

* fix broken link

* so?

* change title

* add mdx to link

* fix stmt

* update goreleaser in test-code

* docs: improve postgres example

* update more projections

* fix: add beta log for postgres

* revert index name change

* prerelease

* fix: add sequence to v1 "reduce paniced"

* log if nil

* add logging

* fix: log output

* fix(import): check if org exists and user

* refactor: imports

* fix(user): ignore malformed events

* refactor: method naming

* fix: test

* refactor: correct errors.Is call

* ci: don't build dev binaries on main

* fix(go releaser): update version to 1.11.0

* fix(user): projection should not break

* fix(user): handle error properly

* docs: correct config example

* Update .releaserc.js

* Update .releaserc.js

Co-authored-by: Livio Amstutz <[email protected]>
Co-authored-by: Elio Bischof <[email protected]>
This commit is contained in:
Silvan
2022-08-31 07:52:43 +00:00
committed by GitHub
co-authored by Livio Amstutz Elio Bischof
parent d6c9815945
commit 77b4fc5487
189 changed files with 3401 additions and 2956 deletions
+1 -1
View File
@@ -130,7 +130,7 @@ func OIDCGrantTypesFromModel(grantTypes []domain.OIDCGrantType) []app_pb.OIDCGra
}
func OIDCGrantTypesToDomain(grantTypes []app_pb.OIDCGrantType) []domain.OIDCGrantType {
if grantTypes == nil || len(grantTypes) == 0 {
if len(grantTypes) == 0 {
return []domain.OIDCGrantType{domain.OIDCGrantTypeAuthorizationCode}
}
oidcGrantTypes := make([]domain.OIDCGrantType, len(grantTypes))
+3 -4
View File
@@ -6,9 +6,6 @@ import (
"strings"
"time"
//sql import
_ "github.com/lib/pq"
"github.com/mitchellh/mapstructure"
"github.com/zitadel/logging"
@@ -61,13 +58,15 @@ func (c *Config) Decode(configs []interface{}) (dialect.Connector, error) {
}
func (c *Config) Connect(useAdmin bool) (*sql.DB, error) {
client, err := sql.Open("postgres", c.String(useAdmin))
client, err := sql.Open("pgx", c.String(useAdmin))
if err != nil {
return nil, err
}
client.SetMaxOpenConns(int(c.MaxOpenConns))
client.SetConnMaxLifetime(c.MaxConnLifetime)
client.SetConnMaxIdleTime(c.MaxConnIdleTime)
return client, nil
}
+3 -18
View File
@@ -6,6 +6,8 @@ import (
_ "github.com/zitadel/zitadel/internal/database/cockroach"
"github.com/zitadel/zitadel/internal/database/dialect"
_ "github.com/zitadel/zitadel/internal/database/postgres"
"github.com/zitadel/zitadel/internal/errors"
)
type Config struct {
@@ -17,23 +19,6 @@ func (c *Config) SetConnector(connector dialect.Connector) {
c.connector = connector
}
type User struct {
Username string
Password string
SSL SSL
}
type SSL struct {
// type of connection security
Mode string
// RootCert Path to the CA certificate
RootCert string
// Cert Path to the client certificate
Cert string
// Key Path to the client private key
Key string
}
func Connect(config Config, useAdmin bool) (*sql.DB, error) {
client, err := config.connector.Connect(useAdmin)
if err != nil {
@@ -41,7 +26,7 @@ func Connect(config Config, useAdmin bool) (*sql.DB, error) {
}
if err := client.Ping(); err != nil {
return nil, err
return nil, errors.ThrowPreconditionFailed(err, "DATAB-0pIWD", "Errors.Database.Connection.Failed")
}
return client, nil
+153
View File
@@ -0,0 +1,153 @@
package postgres
import (
"database/sql"
"strconv"
"strings"
"time"
"github.com/mitchellh/mapstructure"
"github.com/zitadel/logging"
"github.com/zitadel/zitadel/internal/database/dialect"
)
const (
sslDisabledMode = "disable"
)
type Config struct {
Host string
Port int32
Database string
MaxOpenConns uint32
MaxConnLifetime time.Duration
MaxConnIdleTime time.Duration
User User
Admin User
//Additional options to be appended as options=<Options>
//The value will be taken as is. Multiple options are space separated.
Options string
}
func (c *Config) MatchName(name string) bool {
for _, key := range []string{"pg", "postgres"} {
if strings.TrimSpace(strings.ToLower(name)) == key {
return true
}
}
return false
}
func (c *Config) Decode(configs []interface{}) (dialect.Connector, error) {
decoder, err := mapstructure.NewDecoder(&mapstructure.DecoderConfig{
DecodeHook: mapstructure.StringToTimeDurationHookFunc(),
Result: c,
})
if err != nil {
return nil, err
}
for _, config := range configs {
if err = decoder.Decode(config); err != nil {
return nil, err
}
}
return c, nil
}
func (c *Config) Connect(useAdmin bool) (*sql.DB, error) {
logging.Warn("postgres is currently in beta")
db, err := sql.Open("pgx", c.String(useAdmin))
if err != nil {
return nil, err
}
db.SetMaxOpenConns(int(c.MaxOpenConns))
db.SetConnMaxLifetime(c.MaxConnLifetime)
db.SetConnMaxIdleTime(c.MaxConnIdleTime)
return db, nil
}
func (c *Config) DatabaseName() string {
return c.Database
}
func (c *Config) Username() string {
return c.User.Username
}
func (c *Config) Password() string {
return c.User.Password
}
func (c *Config) Type() string {
return "postgres"
}
type User struct {
Username string
Password string
SSL SSL
}
type SSL struct {
// type of connection security
Mode string
// RootCert Path to the CA certificate
RootCert string
// Cert Path to the client certificate
Cert string
// Key Path to the client private key
Key string
}
func (s *Config) checkSSL(user User) {
if user.SSL.Mode == sslDisabledMode || user.SSL.Mode == "" {
user.SSL = SSL{Mode: sslDisabledMode}
return
}
if user.SSL.RootCert == "" {
logging.WithFields(
"cert set", user.SSL.Cert != "",
"key set", user.SSL.Key != "",
"rootCert set", user.SSL.RootCert != "",
).Fatal("at least ssl root cert has to be set")
}
}
func (c Config) String(useAdmin bool) string {
user := c.User
if useAdmin {
user = c.Admin
}
c.checkSSL(user)
fields := []string{
"host=" + c.Host,
"port=" + strconv.Itoa(int(c.Port)),
"user=" + user.Username,
"application_name=zitadel",
"sslmode=" + user.SSL.Mode,
}
if c.Options != "" {
fields = append(fields, "options="+c.Options)
}
if user.Password != "" {
fields = append(fields, "password="+user.Password)
}
if !useAdmin {
fields = append(fields, "dbname="+c.Database)
}
if user.SSL.Mode != sslDisabledMode {
fields = append(fields, "sslrootcert="+user.SSL.RootCert)
if user.SSL.Cert != "" {
fields = append(fields, "sslcert="+user.SSL.Cert)
}
if user.SSL.Key != "" {
fields = append(fields, "sslkey="+user.SSL.Key)
}
}
return strings.Join(fields, " ")
}
+14
View File
@@ -0,0 +1,14 @@
package postgres
import (
//sql import
_ "github.com/jackc/pgx/v4/stdlib"
"github.com/zitadel/zitadel/internal/database/dialect"
)
func init() {
config := &Config{}
dialect.Register(config, config, false)
}
+72
View File
@@ -0,0 +1,72 @@
package database
import (
"database/sql/driver"
"github.com/jackc/pgtype"
)
type StringArray []string
// Scan implements the `database/sql.Scanner` interface.
func (s *StringArray) Scan(src any) error {
array := new(pgtype.TextArray)
if err := array.Scan(src); err != nil {
return err
}
if err := array.AssignTo(s); err != nil {
return err
}
return nil
}
// Value implements the `database/sql/driver.Valuer`` interface.
func (s StringArray) Value() (driver.Value, error) {
if len(s) == 0 {
return nil, nil
}
array := pgtype.TextArray{}
if err := array.Set(s); err != nil {
return nil, err
}
return array.Value()
}
type enumField interface {
~int8 | ~uint8 | ~int16 | ~uint16 | ~int32 | ~uint32
}
type EnumArray[F enumField] []F
// Scan implements the `database/sql.Scanner` interface.
func (s *EnumArray[F]) Scan(src any) error {
array := new(pgtype.Int2Array)
if err := array.Scan(src); err != nil {
return err
}
ints := make([]int32, 0, len(array.Elements))
if err := array.AssignTo(&ints); err != nil {
return err
}
*s = make([]F, len(ints))
for i, a := range ints {
(*s)[i] = F(a)
}
return nil
}
// Value implements the `database/sql/driver.Valuer`` interface.
func (s EnumArray[F]) Value() (driver.Value, error) {
if len(s) == 0 {
return nil, nil
}
array := pgtype.Int2Array{}
if err := array.Set(s); err != nil {
return nil, err
}
return array.Value()
}
@@ -6,15 +6,15 @@ import (
"strconv"
"strings"
"github.com/lib/pq"
"github.com/zitadel/zitadel/internal/database"
"github.com/zitadel/zitadel/internal/errors"
"github.com/zitadel/zitadel/internal/eventstore"
)
const (
currentSequenceStmtFormat = `SELECT current_sequence, aggregate_type, instance_id FROM %s WHERE projection_name = $1 AND instance_id = ANY ($2) FOR UPDATE`
updateCurrentSequencesStmtFormat = `UPSERT INTO %s (projection_name, aggregate_type, current_sequence, instance_id, timestamp) VALUES `
currentSequenceStmtFormat = `SELECT current_sequence, aggregate_type, instance_id FROM %s WHERE projection_name = $1 AND instance_id = ANY ($2) FOR UPDATE`
updateCurrentSequencesStmtFormat = `INSERT INTO %s (projection_name, aggregate_type, current_sequence, instance_id, timestamp) VALUES `
updateCurrentSequencesConflictStmt = ` ON CONFLICT (projection_name, aggregate_type, instance_id) DO UPDATE SET current_sequence = EXCLUDED.current_sequence, timestamp = EXCLUDED.timestamp`
)
type currentSequences map[eventstore.AggregateType][]*instanceSequence
@@ -24,8 +24,8 @@ type instanceSequence struct {
sequence uint64
}
func (h *StatementHandler) currentSequences(ctx context.Context, query func(context.Context, string, ...interface{}) (*sql.Rows, error), instanceIDs []string) (currentSequences, error) {
rows, err := query(ctx, h.currentSequenceStmt, h.ProjectionName, pq.StringArray(instanceIDs))
func (h *StatementHandler) currentSequences(ctx context.Context, query func(context.Context, string, ...interface{}) (*sql.Rows, error), instanceIDs database.StringArray) (currentSequences, error) {
rows, err := query(ctx, h.currentSequenceStmt, h.ProjectionName, instanceIDs)
if err != nil {
return nil, err
}
@@ -74,7 +74,7 @@ func (h *StatementHandler) updateCurrentSequences(tx *sql.Tx, sequences currentS
}
}
res, err := tx.Exec(h.updateSequencesBaseStmt+strings.Join(valueQueries, ", "), values...)
res, err := tx.Exec(h.updateSequencesBaseStmt+strings.Join(valueQueries, ", ")+updateCurrentSequencesConflictStmt, values...)
if err != nil {
return errors.ThrowInternal(err, "CRDB-TrH2Z", "unable to exec update sequence")
}
@@ -8,8 +8,8 @@ import (
"time"
"github.com/DATA-DOG/go-sqlmock"
"github.com/lib/pq"
"github.com/zitadel/zitadel/internal/database"
"github.com/zitadel/zitadel/internal/eventstore"
)
@@ -17,7 +17,7 @@ type mockExpectation func(sqlmock.Sqlmock)
func expectFailureCount(tableName string, projectionName, instanceID string, failedSeq, failureCount uint64) func(sqlmock.Sqlmock) {
return func(m sqlmock.Sqlmock) {
m.ExpectQuery(`WITH failures AS \(SELECT failure_count FROM `+tableName+` WHERE projection_name = \$1 AND failed_sequence = \$2\ AND instance_id = \$3\) SELECT IF\(EXISTS\(SELECT failure_count FROM failures\), \(SELECT failure_count FROM failures\), 0\) AS failure_count`).
m.ExpectQuery(`WITH failures AS \(SELECT failure_count FROM `+tableName+` WHERE projection_name = \$1 AND failed_sequence = \$2 AND instance_id = \$3\) SELECT COALESCE\(\(SELECT failure_count FROM failures\), 0\) AS failure_count`).
WithArgs(projectionName, failedSeq, instanceID).
WillReturnRows(
sqlmock.NewRows([]string{"failure_count"}).
@@ -28,7 +28,7 @@ func expectFailureCount(tableName string, projectionName, instanceID string, fai
func expectUpdateFailureCount(tableName string, projectionName, instanceID string, seq, failureCount uint64) func(sqlmock.Sqlmock) {
return func(m sqlmock.Sqlmock) {
m.ExpectExec(`UPSERT INTO `+tableName+` \(projection_name, failed_sequence, failure_count, error, instance_id\) VALUES \(\$1, \$2, \$3, \$4\, \$5\)`).
m.ExpectExec(`INSERT INTO `+tableName+` \(projection_name, failed_sequence, failure_count, error, instance_id\) VALUES \(\$1, \$2, \$3, \$4\, \$5\) ON CONFLICT \(projection_name, failed_sequence, instance_id\) DO UPDATE SET failure_count = EXCLUDED\.failure_count, error = EXCLUDED\.error`).
WithArgs(projectionName, seq, failureCount, sqlmock.AnyArg(), instanceID).WillReturnResult(sqlmock.NewResult(1, 1))
}
}
@@ -133,7 +133,7 @@ func expectCurrentSequence(tableName, projection string, seq uint64, aggregateTy
m.ExpectQuery(`SELECT current_sequence, aggregate_type, instance_id FROM `+tableName+` WHERE projection_name = \$1 AND instance_id = ANY \(\$2\) FOR UPDATE`).
WithArgs(
projection,
pq.StringArray(instanceIDs),
database.StringArray(instanceIDs),
).
WillReturnRows(
rows,
@@ -146,7 +146,7 @@ func expectCurrentSequenceErr(tableName, projection string, instanceIDs []string
m.ExpectQuery(`SELECT current_sequence, aggregate_type, instance_id FROM `+tableName+` WHERE projection_name = \$1 AND instance_id = ANY \(\$2\) FOR UPDATE`).
WithArgs(
projection,
pq.StringArray(instanceIDs),
database.StringArray(instanceIDs),
).
WillReturnError(err)
}
@@ -157,7 +157,7 @@ func expectCurrentSequenceNoRows(tableName, projection string, instanceIDs []str
m.ExpectQuery(`SELECT current_sequence, aggregate_type, instance_id FROM `+tableName+` WHERE projection_name = \$1 AND instance_id = ANY \(\$2\) FOR UPDATE`).
WithArgs(
projection,
pq.StringArray(instanceIDs),
database.StringArray(instanceIDs),
).
WillReturnRows(
sqlmock.NewRows([]string{"current_sequence", "aggregate_type", "instance_id"}),
@@ -170,7 +170,7 @@ func expectCurrentSequenceScanErr(tableName, projection string, instanceIDs []st
m.ExpectQuery(`SELECT current_sequence, aggregate_type, instance_id FROM `+tableName+` WHERE projection_name = \$1 AND instance_id = ANY \(\$2\) FOR UPDATE`).
WithArgs(
projection,
pq.StringArray(instanceIDs),
database.StringArray(instanceIDs),
).
WillReturnRows(
sqlmock.NewRows([]string{"current_sequence", "aggregate_type", "instance_id"}).
@@ -182,7 +182,7 @@ func expectCurrentSequenceScanErr(tableName, projection string, instanceIDs []st
func expectUpdateCurrentSequence(tableName, projection string, seq uint64, aggregateType, instanceID string) func(sqlmock.Sqlmock) {
return func(m sqlmock.Sqlmock) {
m.ExpectExec("UPSERT INTO "+tableName+` \(projection_name, aggregate_type, current_sequence, instance_id, timestamp\) VALUES \(\$1, \$2, \$3, \$4, NOW\(\)\)`).
m.ExpectExec("INSERT INTO "+tableName+` \(projection_name, aggregate_type, current_sequence, instance_id, timestamp\) VALUES \(\$1, \$2, \$3, \$4, NOW\(\)\) ON CONFLICT \(projection_name, aggregate_type, instance_id\) DO UPDATE SET current_sequence = EXCLUDED.current_sequence, timestamp = EXCLUDED.timestamp`).
WithArgs(
projection,
aggregateType,
@@ -213,7 +213,7 @@ func expectUpdateThreeCurrentSequence(t *testing.T, tableName, projection string
matchers[i] = matcher
}
return func(m sqlmock.Sqlmock) {
m.ExpectExec("UPSERT INTO " + tableName + ` \(projection_name, aggregate_type, current_sequence, instance_id, timestamp\) VALUES \(\$1, \$2, \$3, \$4, NOW\(\)\), \(\$5, \$6, \$7, \$8, NOW\(\)\), \(\$9, \$10, \$11, \$12, NOW\(\)\)`).
m.ExpectExec("INSERT INTO " + tableName + ` \(projection_name, aggregate_type, current_sequence, instance_id, timestamp\) VALUES \(\$1, \$2, \$3, \$4, NOW\(\)\), \(\$5, \$6, \$7, \$8, NOW\(\)\), \(\$9, \$10, \$11, \$12, NOW\(\)\) ON CONFLICT \(projection_name, aggregate_type, instance_id\) DO UPDATE SET current_sequence = EXCLUDED.current_sequence, timestamp = EXCLUDED.timestamp`).
WithArgs(
matchers...,
).
@@ -262,7 +262,7 @@ func (m *currentSequenceMatcher) Match(value driver.Value) bool {
func expectUpdateCurrentSequenceErr(tableName, projection string, seq uint64, err error, aggregateType, instanceID string) func(sqlmock.Sqlmock) {
return func(m sqlmock.Sqlmock) {
m.ExpectExec("UPSERT INTO "+tableName+` \(projection_name, aggregate_type, current_sequence, instance_id, timestamp\) VALUES \(\$1, \$2, \$3, \$4, NOW\(\)\)`).
m.ExpectExec("INSERT INTO "+tableName+` \(projection_name, aggregate_type, current_sequence, instance_id, timestamp\) VALUES \(\$1, \$2, \$3, \$4, NOW\(\)\) ON CONFLICT \(projection_name, aggregate_type, instance_id\) DO UPDATE SET current_sequence = EXCLUDED.current_sequence, timestamp = EXCLUDED.timestamp`).
WithArgs(
projection,
aggregateType,
@@ -275,7 +275,7 @@ func expectUpdateCurrentSequenceErr(tableName, projection string, seq uint64, er
func expectUpdateCurrentSequenceNoRows(tableName, projection string, seq uint64, aggregateType, instanceID string) func(sqlmock.Sqlmock) {
return func(m sqlmock.Sqlmock) {
m.ExpectExec("UPSERT INTO "+tableName+` \(projection_name, aggregate_type, current_sequence, instance_id, timestamp\) VALUES \(\$1, \$2, \$3, \$4, NOW\(\)\)`).
m.ExpectExec("INSERT INTO "+tableName+` \(projection_name, aggregate_type, current_sequence, instance_id, timestamp\) VALUES \(\$1, \$2, \$3, \$4, NOW\(\)\) ON CONFLICT \(projection_name, aggregate_type, instance_id\) DO UPDATE SET current_sequence = EXCLUDED.current_sequence, timestamp = EXCLUDED.timestamp`).
WithArgs(
projection,
aggregateType,
@@ -297,10 +297,10 @@ func expectLock(lockTable, workerName string, d time.Duration, instanceID string
` WHERE `+lockTable+`\.projection_name = \$3 AND `+lockTable+`\.instance_id = ANY \(\$5\) AND \(`+lockTable+`\.locker_id = \$1 OR `+lockTable+`\.locked_until < now\(\)\)`).
WithArgs(
workerName,
float64(d),
d,
projectionName,
instanceID,
pq.StringArray{instanceID},
database.StringArray{instanceID},
).
WillReturnResult(
sqlmock.NewResult(1, 1),
@@ -317,11 +317,11 @@ func expectLockMultipleInstances(lockTable, workerName string, d time.Duration,
` WHERE `+lockTable+`\.projection_name = \$3 AND `+lockTable+`\.instance_id = ANY \(\$6\) AND \(`+lockTable+`\.locker_id = \$1 OR `+lockTable+`\.locked_until < now\(\)\)`).
WithArgs(
workerName,
float64(d),
d,
projectionName,
instanceID1,
instanceID2,
pq.StringArray{instanceID1, instanceID2},
database.StringArray{instanceID1, instanceID2},
).
WillReturnResult(
sqlmock.NewResult(1, 1),
@@ -338,10 +338,10 @@ func expectLockNoRows(lockTable, workerName string, d time.Duration, instanceID
` WHERE `+lockTable+`\.projection_name = \$3 AND `+lockTable+`\.instance_id = ANY \(\$5\) AND \(`+lockTable+`\.locker_id = \$1 OR `+lockTable+`\.locked_until < now\(\)\)`).
WithArgs(
workerName,
float64(d),
d,
projectionName,
instanceID,
pq.StringArray{instanceID},
database.StringArray{instanceID},
).
WillReturnResult(driver.ResultNoRows)
}
@@ -356,10 +356,10 @@ func expectLockErr(lockTable, workerName string, d time.Duration, instanceID str
` WHERE `+lockTable+`\.projection_name = \$3 AND `+lockTable+`\.instance_id = ANY \(\$5\) AND \(`+lockTable+`\.locker_id = \$1 OR `+lockTable+`\.locked_until < now\(\)\)`).
WithArgs(
workerName,
float64(d),
d,
projectionName,
instanceID,
pq.StringArray{instanceID},
database.StringArray{instanceID},
).
WillReturnError(err)
}
@@ -10,15 +10,12 @@ import (
)
const (
setFailureCountStmtFormat = "UPSERT INTO %s" +
setFailureCountStmtFormat = "INSERT INTO %s" +
" (projection_name, failed_sequence, failure_count, error, instance_id)" +
" VALUES ($1, $2, $3, $4, $5)"
" VALUES ($1, $2, $3, $4, $5) ON CONFLICT (projection_name, failed_sequence, instance_id)" +
" DO UPDATE SET failure_count = EXCLUDED.failure_count, error = EXCLUDED.error"
failureCountStmtFormat = "WITH failures AS (SELECT failure_count FROM %s WHERE projection_name = $1 AND failed_sequence = $2 AND instance_id = $3)" +
" SELECT IF(" +
"EXISTS(SELECT failure_count FROM failures)," +
" (SELECT failure_count FROM failures)," +
" 0" +
") AS failure_count"
" SELECT COALESCE((SELECT failure_count FROM failures), 0) AS failure_count"
)
func (h *StatementHandler) handleFailedStmt(tx *sql.Tx, stmt *handler.Statement, execErr error) (shouldContinue bool) {
@@ -72,12 +72,12 @@ func NewStatementHandler(
aggregates: aggregateTypes,
reduces: reduces,
bulkLimit: config.BulkLimit,
Locker: NewLocker(config.Client, config.LockTable, config.ProjectionHandlerConfig.ProjectionName),
Locker: NewLocker(config.Client, config.LockTable, config.ProjectionName),
}
h.ProjectionHandler = handler.NewProjectionHandler(ctx, config.ProjectionHandlerConfig, h.reduce, h.Update, h.SearchQuery, h.Lock, h.Unlock)
err := h.Init(ctx, config.InitCheck)
logging.OnError(err).Fatal("unable to initialize projections")
logging.OnError(err).WithField("projection", config.ProjectionName).Fatal("unable to initialize projections")
h.Subscribe(h.aggregates...)
+13 -12
View File
@@ -6,11 +6,10 @@ import (
"fmt"
"strings"
"github.com/lib/pq"
"github.com/jackc/pgconn"
"github.com/zitadel/logging"
caos_errs "github.com/zitadel/zitadel/internal/errors"
"github.com/zitadel/zitadel/internal/eventstore/handler"
)
@@ -186,7 +185,7 @@ type ForeignKey struct {
RefColumns []string
}
//Init implements handler.Init
// Init implements handler.Init
func (h *StatementHandler) Init(ctx context.Context, checks ...*handler.Check) error {
for _, check := range checks {
if check == nil || check.IsNoop() {
@@ -280,7 +279,7 @@ func isErrAlreadyExists(err error) bool {
if !errors.As(err, &caosErr) {
return false
}
sqlErr, ok := caosErr.GetParent().(*pq.Error)
sqlErr, ok := caosErr.GetParent().(*pgconn.PgError)
if !ok {
return false
}
@@ -288,14 +287,11 @@ func isErrAlreadyExists(err error) bool {
}
func createTableStatement(table *Table, tableName string, suffix string) string {
stmt := fmt.Sprintf("CREATE TABLE %s (%s, PRIMARY KEY (%s)",
stmt := fmt.Sprintf("CREATE TABLE IF NOT EXISTS %s (%s, PRIMARY KEY (%s)",
tableName+suffix,
createColumnsStatement(table.columns, tableName),
strings.Join(table.primaryKey, ", "),
)
for _, index := range table.indices {
stmt += fmt.Sprintf(", INDEX %s (%s)", index.Name, strings.Join(index.Columns, ","))
}
for _, key := range table.foreignKeys {
ref := tableName
if len(key.RefColumns) > 0 {
@@ -309,7 +305,13 @@ func createTableStatement(table *Table, tableName string, suffix string) string
for _, constraint := range table.constraints {
stmt += fmt.Sprintf(", CONSTRAINT %s UNIQUE (%s)", constraint.Name, strings.Join(constraint.Columns, ","))
}
return stmt + ");"
stmt += ");"
for _, index := range table.indices {
stmt += fmt.Sprintf("CREATE INDEX IF NOT EXISTS %s ON %s (%s);", index.Name, tableName+suffix, strings.Join(index.Columns, ","))
}
return stmt
}
func createViewStatement(viewName string, selectStmt string) string {
@@ -321,7 +323,7 @@ func createViewStatement(viewName string, selectStmt string) string {
func createIndexStatement(index *Index) func(config execConfig) string {
return func(config execConfig) string {
stmt := fmt.Sprintf("CREATE INDEX %s ON %s (%s)",
stmt := fmt.Sprintf("CREATE INDEX IF NOT EXISTS %s ON %s (%s)",
index.Name,
config.tableName,
strings.Join(index.Columns, ","),
@@ -380,9 +382,8 @@ func columnType(columnType ColumnType) string {
case ColumnTypeJSONB:
return "JSONB"
case ColumnTypeBytes:
return "BYTES"
return "BYTEA"
default:
panic("unknown column type")
return ""
}
}
+4 -4
View File
@@ -8,9 +8,9 @@ import (
"strings"
"time"
"github.com/lib/pq"
"github.com/zitadel/logging"
"github.com/zitadel/zitadel/internal/database"
"github.com/zitadel/zitadel/internal/errors"
"github.com/zitadel/zitadel/internal/id"
)
@@ -91,17 +91,17 @@ func (h *locker) Unlock(instanceIDs ...string) error {
return nil
}
func (h *locker) lockStatement(lockDuration time.Duration, instanceIDs []string) (string, []interface{}) {
func (h *locker) lockStatement(lockDuration time.Duration, instanceIDs database.StringArray) (string, []interface{}) {
valueQueries := make([]string, len(instanceIDs))
values := make([]interface{}, len(instanceIDs)+4)
values[0] = h.workerName
//the unit of crdb interval is seconds (https://www.cockroachlabs.com/docs/stable/interval.html).
values[1] = lockDuration.Seconds()
values[1] = lockDuration
values[2] = h.projectionName
for i, instanceID := range instanceIDs {
valueQueries[i] = "($1, now()+$2::INTERVAL, $3, $" + strconv.Itoa(i+4) + ")"
values[i+3] = instanceID
}
values[len(values)-1] = pq.StringArray(instanceIDs)
values[len(values)-1] = instanceIDs
return h.lockStmt(strings.Join(valueQueries, ", "), len(values)), values
}
+15 -14
View File
@@ -10,6 +10,7 @@ import (
"github.com/DATA-DOG/go-sqlmock"
"github.com/zitadel/zitadel/internal/database"
z_errs "github.com/zitadel/zitadel/internal/errors"
)
@@ -43,9 +44,9 @@ func TestStatementHandler_handleLock(t *testing.T) {
name: "lock fails",
want: want{
expectations: []mockExpectation{
expectLock(lockTable, workerName, 2, "instanceID"),
expectLock(lockTable, workerName, 2, "instanceID"),
expectLockErr(lockTable, workerName, 2, "instanceID", errLock),
expectLock(lockTable, workerName, 2*time.Second, "instanceID"),
expectLock(lockTable, workerName, 2*time.Second, "instanceID"),
expectLockErr(lockTable, workerName, 2*time.Second, "instanceID", errLock),
},
},
args: args{
@@ -63,8 +64,8 @@ func TestStatementHandler_handleLock(t *testing.T) {
name: "success",
want: want{
expectations: []mockExpectation{
expectLock(lockTable, workerName, 2, "instanceID"),
expectLock(lockTable, workerName, 2, "instanceID"),
expectLock(lockTable, workerName, 2*time.Second, "instanceID"),
expectLock(lockTable, workerName, 2*time.Second, "instanceID"),
},
},
args: args{
@@ -81,8 +82,8 @@ func TestStatementHandler_handleLock(t *testing.T) {
name: "success with multiple",
want: want{
expectations: []mockExpectation{
expectLockMultipleInstances(lockTable, workerName, 2, "instanceID1", "instanceID2"),
expectLockMultipleInstances(lockTable, workerName, 2, "instanceID1", "instanceID2"),
expectLockMultipleInstances(lockTable, workerName, 2*time.Second, "instanceID1", "instanceID2"),
expectLockMultipleInstances(lockTable, workerName, 2*time.Second, "instanceID1", "instanceID2"),
},
},
args: args{
@@ -149,7 +150,7 @@ func TestStatementHandler_renewLock(t *testing.T) {
name: "lock fails",
want: want{
expectations: []mockExpectation{
expectLockErr(lockTable, workerName, 1, "instanceID", sql.ErrTxDone),
expectLockErr(lockTable, workerName, 1*time.Second, "instanceID", sql.ErrTxDone),
},
isErr: func(err error) bool {
return errors.Is(err, sql.ErrTxDone)
@@ -157,14 +158,14 @@ func TestStatementHandler_renewLock(t *testing.T) {
},
args: args{
lockDuration: 1 * time.Second,
instanceIDs: []string{"instanceID"},
instanceIDs: database.StringArray{"instanceID"},
},
},
{
name: "lock no rows",
want: want{
expectations: []mockExpectation{
expectLockNoRows(lockTable, workerName, 2, "instanceID"),
expectLockNoRows(lockTable, workerName, 2*time.Second, "instanceID"),
},
isErr: func(err error) bool {
return errors.Is(err, renewNoRowsAffectedErr)
@@ -172,14 +173,14 @@ func TestStatementHandler_renewLock(t *testing.T) {
},
args: args{
lockDuration: 2 * time.Second,
instanceIDs: []string{"instanceID"},
instanceIDs: database.StringArray{"instanceID"},
},
},
{
name: "success",
want: want{
expectations: []mockExpectation{
expectLock(lockTable, workerName, 3, "instanceID"),
expectLock(lockTable, workerName, 3*time.Second, "instanceID"),
},
isErr: func(err error) bool {
return errors.Is(err, nil)
@@ -187,14 +188,14 @@ func TestStatementHandler_renewLock(t *testing.T) {
},
args: args{
lockDuration: 3 * time.Second,
instanceIDs: []string{"instanceID"},
instanceIDs: database.StringArray{"instanceID"},
},
},
{
name: "success with multiple",
want: want{
expectations: []mockExpectation{
expectLockMultipleInstances(lockTable, workerName, 3, "instanceID1", "instanceID2"),
expectLockMultipleInstances(lockTable, workerName, 3*time.Second, "instanceID1", "instanceID2"),
},
isErr: func(err error) bool {
return errors.Is(err, nil)
+72 -27
View File
@@ -4,8 +4,7 @@ import (
"strconv"
"strings"
"github.com/lib/pq"
"github.com/zitadel/zitadel/internal/database"
caos_errs "github.com/zitadel/zitadel/internal/errors"
"github.com/zitadel/zitadel/internal/eventstore"
"github.com/zitadel/zitadel/internal/eventstore/handler"
@@ -51,10 +50,13 @@ func NewCreateStatement(event eventstore.Event, values []handler.Column, opts ..
}
}
func NewUpsertStatement(event eventstore.Event, values []handler.Column, opts ...execOption) *handler.Statement {
func NewUpsertStatement(event eventstore.Event, conflictCols []handler.Column, values []handler.Column, opts ...execOption) *handler.Statement {
cols, params, args := columnsToQuery(values)
columnNames := strings.Join(cols, ", ")
valuesPlaceholder := strings.Join(params, ", ")
conflictTarget := make([]string, len(conflictCols))
for i, col := range conflictCols {
conflictTarget[i] = col.Name
}
config := execConfig{
args: args,
@@ -64,8 +66,14 @@ func NewUpsertStatement(event eventstore.Event, values []handler.Column, opts ..
config.err = handler.ErrNoValues
}
updateCols, updateVals := getUpdateCols(cols, conflictTarget)
if len(updateCols) == 0 || len(updateVals) == 0 {
config.err = handler.ErrNoValues
}
q := func(config execConfig) string {
return "UPSERT INTO " + config.tableName + " (" + columnNames + ") VALUES (" + valuesPlaceholder + ")"
return "INSERT INTO " + config.tableName + " (" + strings.Join(cols, ", ") + ") VALUES (" + strings.Join(params, ", ") + ")" +
" ON CONFLICT (" + strings.Join(conflictTarget, ", ") + ") DO UPDATE SET (" + strings.Join(updateCols, ", ") + ") = (" + strings.Join(updateVals, ", ") + ")"
}
return &handler.Statement{
@@ -77,15 +85,38 @@ func NewUpsertStatement(event eventstore.Event, values []handler.Column, opts ..
}
}
func getUpdateCols(cols, conflictTarget []string) (updateCols, updateVals []string) {
updateCols = make([]string, len(cols))
updateVals = make([]string, len(cols))
copy(updateCols, cols)
for i := len(updateCols) - 1; i >= 0; i-- {
updateVals[i] = "EXCLUDED." + updateCols[i]
for _, conflict := range conflictTarget {
if conflict == updateCols[i] {
copy(updateCols[i:], updateCols[i+1:])
updateCols[len(updateCols)-1] = ""
updateCols = updateCols[:len(updateCols)-1]
copy(updateVals[i:], updateVals[i+1:])
updateVals[len(updateVals)-1] = ""
updateVals = updateVals[:len(updateVals)-1]
break
}
}
}
return updateCols, updateVals
}
func NewUpdateStatement(event eventstore.Event, values []handler.Column, conditions []handler.Condition, opts ...execOption) *handler.Statement {
cols, params, args := columnsToQuery(values)
wheres, whereArgs := conditionsToWhere(conditions, len(params))
args = append(args, whereArgs...)
columnNames := strings.Join(cols, ", ")
valuesPlaceholder := strings.Join(params, ", ")
wheresPlaceholders := strings.Join(wheres, " AND ")
config := execConfig{
args: args,
}
@@ -99,7 +130,7 @@ func NewUpdateStatement(event eventstore.Event, values []handler.Column, conditi
}
q := func(config execConfig) string {
return "UPDATE " + config.tableName + " SET (" + columnNames + ") = (" + valuesPlaceholder + ") WHERE " + wheresPlaceholders
return "UPDATE " + config.tableName + " SET (" + strings.Join(cols, ", ") + ") = (" + strings.Join(params, ", ") + ") WHERE " + strings.Join(wheres, " AND ")
}
return &handler.Statement{
@@ -171,9 +202,9 @@ func AddCreateStatement(columns []handler.Column, opts ...execOption) func(event
}
}
func AddUpsertStatement(values []handler.Column, opts ...execOption) func(eventstore.Event) Exec {
func AddUpsertStatement(indexCols []handler.Column, values []handler.Column, opts ...execOption) func(eventstore.Event) Exec {
return func(event eventstore.Event) Exec {
return NewUpsertStatement(event, values, opts...).Execute
return NewUpsertStatement(event, indexCols, values, opts...).Execute
}
}
@@ -189,9 +220,9 @@ func AddDeleteStatement(conditions []handler.Condition, opts ...execOption) func
}
}
func AddCopyStatement(from, to []handler.Column, conditions []handler.Condition, opts ...execOption) func(eventstore.Event) Exec {
func AddCopyStatement(conflict, from, to []handler.Column, conditions []handler.Condition, opts ...execOption) func(eventstore.Event) Exec {
return func(event eventstore.Event) Exec {
return NewCopyStatement(event, from, to, conditions, opts...).Execute
return NewCopyStatement(event, conflict, from, to, conditions, opts...).Execute
}
}
@@ -218,11 +249,9 @@ func NewArrayRemoveCol(column string, value interface{}) handler.Column {
func NewArrayIntersectCol(column string, value interface{}) handler.Column {
var arrayType string
switch value.(type) {
case pq.StringArray:
arrayType = "STRING"
case pq.Int32Array,
pq.Int64Array:
arrayType = "INT"
case []string, database.StringArray:
arrayType = "TEXT"
//TODO: handle more types if necessary
}
return handler.Column{
@@ -234,25 +263,29 @@ func NewArrayIntersectCol(column string, value interface{}) handler.Column {
}
}
//NewCopyStatement creates a new upsert statement which updates a column from an existing row
// NewCopyStatement creates a new upsert statement which updates a column from an existing row
// cols represent the columns which are objective to change.
// if the value of a col is empty the data will be copied from the selected row
// if the value of a col is not empty the data will be set by the static value
// conds represent the conditions for the selection subquery
func NewCopyStatement(event eventstore.Event, from, to []handler.Column, conds []handler.Condition, opts ...execOption) *handler.Statement {
func NewCopyStatement(event eventstore.Event, conflictCols, from, to []handler.Column, conds []handler.Condition, opts ...execOption) *handler.Statement {
columnNames := make([]string, len(to))
selectColumns := make([]string, len(from))
updateColumns := make([]string, len(columnNames))
argCounter := 0
args := []interface{}{}
for i := range from {
for i, col := range from {
columnNames[i] = to[i].Name
selectColumns[i] = from[i].Name
if from[i].Value != nil {
updateColumns[i] = "EXCLUDED." + col.Name
if col.Value != nil {
argCounter++
selectColumns[i] = "$" + strconv.Itoa(argCounter)
args = append(args, from[i].Value)
updateColumns[i] = selectColumns[i]
args = append(args, col.Value)
}
}
wheres := make([]string, len(conds))
@@ -262,6 +295,11 @@ func NewCopyStatement(event eventstore.Event, from, to []handler.Column, conds [
args = append(args, cond.Value)
}
conflictTargets := make([]string, len(conflictCols))
for i, conflictCol := range conflictCols {
conflictTargets[i] = conflictCol.Name
}
config := execConfig{
args: args,
}
@@ -275,7 +313,7 @@ func NewCopyStatement(event eventstore.Event, from, to []handler.Column, conds [
}
q := func(config execConfig) string {
return "UPSERT INTO " +
return "INSERT INTO " +
config.tableName +
" (" +
strings.Join(columnNames, ", ") +
@@ -283,7 +321,14 @@ func NewCopyStatement(event eventstore.Event, from, to []handler.Column, conds [
strings.Join(selectColumns, ", ") +
" FROM " +
config.tableName + " AS copy_table WHERE " +
strings.Join(wheres, " AND ")
strings.Join(wheres, " AND ") +
" ON CONFLICT (" +
strings.Join(conflictTargets, ", ") +
") DO UPDATE SET (" +
strings.Join(columnNames, ", ") +
") = (" +
strings.Join(updateColumns, ", ") +
")"
}
return &handler.Statement{
@@ -178,9 +178,10 @@ func TestNewCreateStatement(t *testing.T) {
func TestNewUpsertStatement(t *testing.T) {
type args struct {
table string
event *testEvent
values []handler.Column
table string
event *testEvent
conflictCols []handler.Column
values []handler.Column
}
type want struct {
aggregateType eventstore.AggregateType
@@ -249,7 +250,7 @@ func TestNewUpsertStatement(t *testing.T) {
},
},
{
name: "correct",
name: "no update cols",
args: args{
table: "my_table",
event: &testEvent{
@@ -257,6 +258,9 @@ func TestNewUpsertStatement(t *testing.T) {
sequence: 1,
previousSequence: 0,
},
conflictCols: []handler.Column{
handler.NewCol("col1", nil),
},
values: []handler.Column{
{
Name: "col1",
@@ -264,6 +268,42 @@ func TestNewUpsertStatement(t *testing.T) {
},
},
},
want: want{
table: "my_table",
aggregateType: "agg",
sequence: 1,
previousSequence: 1,
executer: &wantExecuter{
shouldExecute: false,
},
isErr: func(err error) bool {
return errors.Is(err, handler.ErrNoValues)
},
},
},
{
name: "correct",
args: args{
table: "my_table",
event: &testEvent{
aggregateType: "agg",
sequence: 1,
previousSequence: 0,
},
conflictCols: []handler.Column{
handler.NewCol("col1", nil),
},
values: []handler.Column{
{
Name: "col1",
Value: "val",
},
{
Name: "col2",
Value: "val",
},
},
},
want: want{
table: "my_table",
aggregateType: "agg",
@@ -272,8 +312,8 @@ func TestNewUpsertStatement(t *testing.T) {
executer: &wantExecuter{
params: []params{
{
query: "UPSERT INTO my_table (col1) VALUES ($1)",
args: []interface{}{"val"},
query: "INSERT INTO my_table (col1, col2) VALUES ($1, $2) ON CONFLICT (col1) DO UPDATE SET (col2) = (EXCLUDED.col2)",
args: []interface{}{"val", "val"},
},
},
shouldExecute: true,
@@ -287,7 +327,7 @@ func TestNewUpsertStatement(t *testing.T) {
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
tt.want.executer.t = t
stmt := NewUpsertStatement(tt.args.event, tt.args.values)
stmt := NewUpsertStatement(tt.args.event, tt.args.conflictCols, tt.args.values)
err := stmt.Execute(tt.want.executer, tt.args.table)
if !tt.want.isErr(err) {
@@ -724,11 +764,18 @@ func TestNewMultiStatement(t *testing.T) {
},
}),
AddUpsertStatement(
[]handler.Column{
handler.NewCol("col1", nil),
},
[]handler.Column{
{
Name: "col1",
Value: 1,
},
{
Name: "col2",
Value: 2,
},
}),
AddUpdateStatement(
[]handler.Column{
@@ -761,8 +808,8 @@ func TestNewMultiStatement(t *testing.T) {
args: []interface{}{1},
},
{
query: "UPSERT INTO my_table (col1) VALUES ($1)",
args: []interface{}{1},
query: "INSERT INTO my_table (col1, col2) VALUES ($1, $2) ON CONFLICT (col1) DO UPDATE SET (col2) = (EXCLUDED.col2)",
args: []interface{}{1, 2},
},
{
query: "UPDATE my_table SET (col1) = ($1) WHERE (col1 = $2)",
@@ -799,11 +846,12 @@ func TestNewMultiStatement(t *testing.T) {
func TestNewCopyStatement(t *testing.T) {
type args struct {
table string
event *testEvent
from []handler.Column
to []handler.Column
conds []handler.Condition
table string
event *testEvent
conflictingCols []handler.Column
from []handler.Column
to []handler.Column
conds []handler.Condition
}
type want struct {
aggregateType eventstore.AggregateType
@@ -1004,7 +1052,7 @@ func TestNewCopyStatement(t *testing.T) {
executer: &wantExecuter{
params: []params{
{
query: "UPSERT INTO my_table (state, id, col_a, col_b) SELECT $1, id, col_a, col_b FROM my_table AS copy_table WHERE copy_table.id = $2 AND copy_table.state = $3",
query: "INSERT INTO my_table (state, id, col_a, col_b) SELECT $1, id, col_a, col_b FROM my_table AS copy_table WHERE copy_table.id = $2 AND copy_table.state = $3 ON CONFLICT () DO UPDATE SET (state, id, col_a, col_b) = ($1, EXCLUDED.id, EXCLUDED.col_a, EXCLUDED.col_b)",
args: []interface{}{1, 2, 3},
},
},
@@ -1071,7 +1119,7 @@ func TestNewCopyStatement(t *testing.T) {
executer: &wantExecuter{
params: []params{
{
query: "UPSERT INTO my_table (state, id, col_c, col_d) SELECT $1, id, col_a, col_b FROM my_table AS copy_table WHERE copy_table.id = $2 AND copy_table.state = $3",
query: "INSERT INTO my_table (state, id, col_c, col_d) SELECT $1, id, col_a, col_b FROM my_table AS copy_table WHERE copy_table.id = $2 AND copy_table.state = $3 ON CONFLICT () DO UPDATE SET (state, id, col_c, col_d) = ($1, EXCLUDED.id, EXCLUDED.col_a, EXCLUDED.col_b)",
args: []interface{}{1, 2, 3},
},
},
@@ -1086,7 +1134,7 @@ func TestNewCopyStatement(t *testing.T) {
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
tt.want.executer.t = t
stmt := NewCopyStatement(tt.args.event, tt.args.from, tt.args.to, tt.args.conds)
stmt := NewCopyStatement(tt.args.event, tt.args.conflictingCols, tt.args.from, tt.args.to, tt.args.conds)
err := stmt.Execute(tt.want.executer, tt.args.table)
if !tt.want.isErr(err) {
+15 -6
View File
@@ -9,6 +9,8 @@ import (
"github.com/zitadel/logging"
"github.com/zitadel/zitadel/cmd/initialise"
"github.com/zitadel/zitadel/internal/database"
"github.com/zitadel/zitadel/internal/database/cockroach"
)
var (
@@ -45,13 +47,20 @@ func TestMain(m *testing.M) {
}
func initDB(db *sql.DB) error {
username := "zitadel"
database := "zitadel"
err := initialise.Initialise(db, initialise.VerifyUser(username, ""),
initialise.VerifyDatabase(database),
initialise.VerifyGrant(database, username))
initialise.ReadStmts("cockroach")
config := new(database.Config)
config.SetConnector(&cockroach.Config{
User: cockroach.User{
Username: "zitadel",
},
Database: "zitadel",
})
err := initialise.Init(db,
initialise.VerifyUser(config.Username(), ""),
initialise.VerifyDatabase(config.Database()),
initialise.VerifyGrant(config.Database(), config.Username()))
if err != nil {
return err
}
return initialise.VerifyZitadel(db)
return initialise.VerifyZitadel(db, *config)
}
+14 -8
View File
@@ -9,6 +9,7 @@ import (
"strings"
"github.com/cockroachdb/cockroach-go/v2/crdb"
"github.com/jackc/pgconn"
"github.com/lib/pq"
"github.com/zitadel/logging"
@@ -30,7 +31,7 @@ const (
" SELECT MAX(event_sequence) seq, 1 join_me" +
" FROM eventstore.events" +
" WHERE aggregate_type = $2" +
" AND (CASE WHEN $9::STRING IS NULL THEN instance_id is null else instance_id = $9::STRING END)" +
" AND (CASE WHEN $9::TEXT IS NULL THEN instance_id is null else instance_id = $9::TEXT END)" +
") AS agg_type " +
// combined with
"LEFT JOIN " +
@@ -39,7 +40,7 @@ const (
" SELECT event_sequence seq, resource_owner ro, 1 join_me" +
" FROM eventstore.events" +
" WHERE aggregate_type = $2 AND aggregate_id = $3" +
" AND (CASE WHEN $9::STRING IS NULL THEN instance_id is null else instance_id = $9::STRING END)" +
" AND (CASE WHEN $9::TEXT IS NULL THEN instance_id is null else instance_id = $9::TEXT END)" +
" ORDER BY event_sequence DESC" +
" LIMIT 1" +
") AS agg USING(join_me)" +
@@ -69,9 +70,9 @@ const (
" $5::JSONB AS event_data," +
" $6::VARCHAR AS editor_user," +
" $7::VARCHAR AS editor_service," +
" IFNULL((resource_owner), $8::VARCHAR) AS resource_owner," +
" COALESCE((resource_owner), $8::VARCHAR) AS resource_owner," +
" $9::VARCHAR AS instance_id," +
" NEXTVAL(CONCAT('eventstore.', IF($9 <> '', CONCAT('i_', $9), 'system'), '_seq'))," +
" NEXTVAL(CONCAT('eventstore.', (CASE WHEN $9 <> '' THEN CONCAT('i_', $9) ELSE 'system' END), '_seq'))," +
" aggregate_sequence AS previous_aggregate_sequence," +
" aggregate_type_sequence AS previous_aggregate_type_sequence " +
"FROM previous_data " +
@@ -156,7 +157,7 @@ func (db *CRDB) Push(ctx context.Context, events []*repository.Event, uniqueCons
var instanceRegexp = regexp.MustCompile(`eventstore\.i_[0-9a-zA-Z]{1,}_seq`)
func (db *CRDB) CreateInstance(ctx context.Context, instanceID string) error {
row := db.client.QueryRowContext(ctx, "SELECT CONCAT('eventstore.i_', $1, '_seq')", instanceID)
row := db.client.QueryRowContext(ctx, "SELECT CONCAT('eventstore.i_', $1::TEXT, '_seq')", instanceID)
if row.Err() != nil {
return caos_errs.ThrowInvalidArgument(row.Err(), "SQL-7gtFA", "Errors.InvalidArgument")
}
@@ -218,7 +219,7 @@ func (db *CRDB) Filter(ctx context.Context, searchQuery *repository.SearchQuery)
return events, nil
}
//LatestSequence returns the latest sequence found by the search query
// LatestSequence returns the latest sequence found by the search query
func (db *CRDB) LatestSequence(ctx context.Context, searchQuery *repository.SearchQuery) (uint64, error) {
var seq Sequence
err := query(ctx, db, searchQuery, &seq)
@@ -228,7 +229,7 @@ func (db *CRDB) LatestSequence(ctx context.Context, searchQuery *repository.Sear
return uint64(seq), nil
}
//InstanceIDs returns the instance ids found by the search query
// InstanceIDs returns the instance ids found by the search query
func (db *CRDB) InstanceIDs(ctx context.Context, searchQuery *repository.SearchQuery) ([]string, error) {
var ids []string
err := query(ctx, db, searchQuery, &ids)
@@ -331,7 +332,7 @@ var (
placeholder = regexp.MustCompile(`\?`)
)
//placeholder replaces all "?" with postgres placeholders ($<NUMBER>)
// placeholder replaces all "?" with postgres placeholders ($<NUMBER>)
func (db *CRDB) placeholder(query string) string {
occurances := placeholder.FindAllStringIndex(query, -1)
if len(occurances) == 0 {
@@ -355,5 +356,10 @@ func (db *CRDB) isUniqueViolationError(err error) bool {
return true
}
}
if pgxErr, ok := err.(*pgconn.PgError); ok {
if pgxErr.Code == "23505" {
return true
}
}
return false
}
+18 -19
View File
@@ -6,8 +6,7 @@ import (
"sync"
"testing"
"github.com/lib/pq"
"github.com/zitadel/zitadel/internal/database"
"github.com/zitadel/zitadel/internal/eventstore/repository"
)
@@ -279,7 +278,7 @@ func TestCRDB_Push_OneAggregate(t *testing.T) {
uniqueCount int
assetCount int
aggType repository.AggregateType
aggID []string
aggID database.StringArray
}
type res struct {
wantErr bool
@@ -430,7 +429,7 @@ func TestCRDB_Push_OneAggregate(t *testing.T) {
t.Errorf("CRDB.Push() error = %v, wantErr %v", err, tt.res.wantErr)
}
countEventRow := testCRDBClient.QueryRow("SELECT COUNT(*) FROM eventstore.events where aggregate_type = $1 AND aggregate_id = ANY($2)", tt.res.eventsRes.aggType, pq.Array(tt.res.eventsRes.aggID))
countEventRow := testCRDBClient.QueryRow("SELECT COUNT(*) FROM eventstore.events where aggregate_type = $1 AND aggregate_id = ANY($2)", tt.res.eventsRes.aggType, tt.res.eventsRes.aggID)
var eventCount int
err := countEventRow.Scan(&eventCount)
if err != nil {
@@ -462,8 +461,8 @@ func TestCRDB_Push_MultipleAggregate(t *testing.T) {
}
type eventsRes struct {
pushedEventsCount int
aggType []repository.AggregateType
aggID []string
aggType database.StringArray
aggID database.StringArray
}
type res struct {
wantErr bool
@@ -487,7 +486,7 @@ func TestCRDB_Push_MultipleAggregate(t *testing.T) {
eventsRes: eventsRes{
pushedEventsCount: 2,
aggID: []string{"100", "101"},
aggType: []repository.AggregateType{repository.AggregateType(t.Name())},
aggType: database.StringArray{t.Name()},
},
},
},
@@ -506,7 +505,7 @@ func TestCRDB_Push_MultipleAggregate(t *testing.T) {
eventsRes: eventsRes{
pushedEventsCount: 4,
aggID: []string{"102", "103"},
aggType: []repository.AggregateType{repository.AggregateType(t.Name())},
aggType: database.StringArray{t.Name()},
},
},
},
@@ -533,7 +532,7 @@ func TestCRDB_Push_MultipleAggregate(t *testing.T) {
eventsRes: eventsRes{
pushedEventsCount: 12,
aggID: []string{"106", "107", "108"},
aggType: []repository.AggregateType{repository.AggregateType(t.Name())},
aggType: database.StringArray{t.Name()},
},
},
},
@@ -547,7 +546,7 @@ func TestCRDB_Push_MultipleAggregate(t *testing.T) {
t.Errorf("CRDB.Push() error = %v, wantErr %v", err, tt.res.wantErr)
}
countRow := testCRDBClient.QueryRow("SELECT COUNT(*) FROM eventstore.events where aggregate_type = ANY($1) AND aggregate_id = ANY($2)", pq.Array(tt.res.eventsRes.aggType), pq.Array(tt.res.eventsRes.aggID))
countRow := testCRDBClient.QueryRow("SELECT COUNT(*) FROM eventstore.events where aggregate_type = ANY($1) AND aggregate_id = ANY($2)", tt.res.eventsRes.aggType, tt.res.eventsRes.aggID)
var count int
err := countRow.Scan(&count)
if err != nil {
@@ -645,8 +644,8 @@ func TestCRDB_Push_Parallel(t *testing.T) {
}
type eventsRes struct {
pushedEventsCount int
aggTypes []repository.AggregateType
aggIDs []string
aggTypes database.StringArray
aggIDs database.StringArray
}
type res struct {
errCount int
@@ -681,7 +680,7 @@ func TestCRDB_Push_Parallel(t *testing.T) {
eventsRes: eventsRes{
aggIDs: []string{"200", "201", "202", "203"},
pushedEventsCount: 9,
aggTypes: []repository.AggregateType{repository.AggregateType(t.Name())},
aggTypes: database.StringArray{t.Name()},
},
},
},
@@ -718,7 +717,7 @@ func TestCRDB_Push_Parallel(t *testing.T) {
eventsRes: eventsRes{
aggIDs: []string{"204", "205", "206"},
pushedEventsCount: 14,
aggTypes: []repository.AggregateType{repository.AggregateType(t.Name())},
aggTypes: database.StringArray{t.Name()},
},
},
},
@@ -748,7 +747,7 @@ func TestCRDB_Push_Parallel(t *testing.T) {
eventsRes: eventsRes{
aggIDs: []string{"207", "208"},
pushedEventsCount: 11,
aggTypes: []repository.AggregateType{repository.AggregateType(t.Name())},
aggTypes: database.StringArray{t.Name()},
},
},
},
@@ -781,7 +780,7 @@ func TestCRDB_Push_Parallel(t *testing.T) {
t.Errorf("CRDB.Push() error count = %d, wanted err count %d, errs: %v", len(errs), tt.res.errCount, errs)
}
rows, err := testCRDBClient.Query("SELECT event_data FROM eventstore.events where aggregate_type = ANY($1) AND aggregate_id = ANY($2) order by event_sequence", pq.Array(tt.res.eventsRes.aggTypes), pq.Array(tt.res.eventsRes.aggIDs))
rows, err := testCRDBClient.Query("SELECT event_data FROM eventstore.events where aggregate_type = ANY($1) AND aggregate_id = ANY($2) order by event_sequence", tt.res.eventsRes.aggTypes, tt.res.eventsRes.aggIDs)
if err != nil {
t.Error("unable to query inserted rows: ", err)
return
@@ -993,10 +992,10 @@ func TestCRDB_Push_ResourceOwner(t *testing.T) {
events []*repository.Event
}
type res struct {
resourceOwners []string
resourceOwners database.StringArray
}
type fields struct {
aggregateIDs []string
aggregateIDs database.StringArray
aggregateType string
}
tests := []struct {
@@ -1128,7 +1127,7 @@ func TestCRDB_Push_ResourceOwner(t *testing.T) {
}
}
rows, err := testCRDBClient.Query("SELECT resource_owner FROM eventstore.events WHERE aggregate_type = $1 AND aggregate_id = ANY($2) ORDER BY event_sequence", tt.fields.aggregateType, pq.Array(tt.fields.aggregateIDs))
rows, err := testCRDBClient.Query("SELECT resource_owner FROM eventstore.events WHERE aggregate_type = $1 AND aggregate_id = ANY($2) ORDER BY event_sequence", tt.fields.aggregateType, tt.fields.aggregateIDs)
if err != nil {
t.Error("unable to query inserted rows: ", err)
return
@@ -9,6 +9,8 @@ import (
"github.com/zitadel/logging"
"github.com/zitadel/zitadel/cmd/initialise"
"github.com/zitadel/zitadel/internal/database"
"github.com/zitadel/zitadel/internal/database/cockroach"
)
var (
@@ -42,15 +44,22 @@ func TestMain(m *testing.M) {
}
func initDB(db *sql.DB) error {
username := "zitadel"
database := "zitadel"
err := initialise.Initialise(db, initialise.VerifyUser(username, ""),
initialise.VerifyDatabase(database),
initialise.VerifyGrant(database, username))
config := new(database.Config)
config.SetConnector(&cockroach.Config{User: cockroach.User{Username: "zitadel"}, Database: "zitadel"})
if err := initialise.ReadStmts("cockroach"); err != nil {
return err
}
err := initialise.Init(db,
initialise.VerifyUser(config.Username(), ""),
initialise.VerifyDatabase(config.Database()),
initialise.VerifyGrant(config.Database(), config.Username()))
if err != nil {
return err
}
return initialise.VerifyZitadel(db)
return initialise.VerifyZitadel(db, *config)
}
func fillUniqueData(unique_type, field, instanceID string) error {
@@ -8,7 +8,6 @@ import (
"fmt"
"strings"
"github.com/lib/pq"
"github.com/zitadel/logging"
z_errors "github.com/zitadel/zitadel/internal/errors"
@@ -170,8 +169,6 @@ func prepareCondition(criteria querier, filters [][]*repository.Filter) (clause
for _, f := range filter {
value := f.Value
switch value.(type) {
case []bool, []float64, []int64, []string, []repository.AggregateType, []repository.EventType, *[]bool, *[]float64, *[]int64, *[]string, *[]repository.AggregateType, *[]repository.EventType:
value = pq.Array(value)
case map[string]interface{}:
var err error
value, err = json.Marshal(value)
@@ -9,7 +9,6 @@ import (
"time"
"github.com/DATA-DOG/go-sqlmock"
"github.com/lib/pq"
"github.com/zitadel/zitadel/internal/errors"
"github.com/zitadel/zitadel/internal/eventstore/repository"
@@ -265,7 +264,7 @@ func Test_prepareCondition(t *testing.T) {
},
res: res{
clause: " WHERE ( aggregate_type = ANY(?) )",
values: []interface{}{pq.Array([]repository.AggregateType{"user", "org"})},
values: []interface{}{[]repository.AggregateType{"user", "org"}},
},
},
{
@@ -281,7 +280,7 @@ func Test_prepareCondition(t *testing.T) {
},
res: res{
clause: " WHERE ( aggregate_type = ANY(?) AND aggregate_id = ? AND event_type = ANY(?) )",
values: []interface{}{pq.Array([]repository.AggregateType{"user", "org"}), "1234", pq.Array([]repository.EventType{"user.created", "org.created"})},
values: []interface{}{[]repository.AggregateType{"user", "org"}, "1234", []repository.EventType{"user.created", "org.created"}},
},
},
}
+29 -28
View File
@@ -3,11 +3,12 @@ package eventstore
import (
"database/sql"
"github.com/zitadel/zitadel/internal/database"
"github.com/zitadel/zitadel/internal/errors"
"github.com/zitadel/zitadel/internal/eventstore/repository"
)
//SearchQueryBuilder represents the builder for your filter
// SearchQueryBuilder represents the builder for your filter
// if invalid data are set the filter will fail
type SearchQueryBuilder struct {
columns repository.Columns
@@ -79,51 +80,51 @@ func (builder *SearchQueryBuilder) Matches(event Event, existingLen int) (matche
return false
}
//Columns defines which fields are set
// Columns defines which fields are set
func (builder *SearchQueryBuilder) Columns(columns Columns) *SearchQueryBuilder {
builder.columns = repository.Columns(columns)
return builder
}
//Limit defines how many events are returned maximally.
// Limit defines how many events are returned maximally.
func (builder *SearchQueryBuilder) Limit(limit uint64) *SearchQueryBuilder {
builder.limit = limit
return builder
}
//ResourceOwner defines the resource owner (org) of the events
// ResourceOwner defines the resource owner (org) of the events
func (builder *SearchQueryBuilder) ResourceOwner(resourceOwner string) *SearchQueryBuilder {
builder.resourceOwner = resourceOwner
return builder
}
//InstanceID defines the instanceID (system) of the events
// InstanceID defines the instanceID (system) of the events
func (builder *SearchQueryBuilder) InstanceID(instanceID string) *SearchQueryBuilder {
builder.instanceID = instanceID
return builder
}
//OrderDesc changes the sorting order of the returned events to descending
// OrderDesc changes the sorting order of the returned events to descending
func (builder *SearchQueryBuilder) OrderDesc() *SearchQueryBuilder {
builder.desc = true
return builder
}
//OrderAsc changes the sorting order of the returned events to ascending
// OrderAsc changes the sorting order of the returned events to ascending
func (builder *SearchQueryBuilder) OrderAsc() *SearchQueryBuilder {
builder.desc = false
return builder
}
//SetTx ensures that the eventstore library uses the existing transaction
// SetTx ensures that the eventstore library uses the existing transaction
func (builder *SearchQueryBuilder) SetTx(tx *sql.Tx) *SearchQueryBuilder {
builder.tx = tx
return builder
}
//AddQuery creates a new sub query.
//All fields in the sub query are AND-connected in the storage request.
//Multiple sub queries are OR-connected in the storage request.
// AddQuery creates a new sub query.
// All fields in the sub query are AND-connected in the storage request.
// Multiple sub queries are OR-connected in the storage request.
func (builder *SearchQueryBuilder) AddQuery() *SearchQuery {
query := &SearchQuery{
builder: builder,
@@ -133,61 +134,61 @@ func (builder *SearchQueryBuilder) AddQuery() *SearchQuery {
return query
}
//Or creates a new sub query on the search query builder
// Or creates a new sub query on the search query builder
func (query SearchQuery) Or() *SearchQuery {
return query.builder.AddQuery()
}
//AggregateTypes filters for events with the given aggregate types
// AggregateTypes filters for events with the given aggregate types
func (query *SearchQuery) AggregateTypes(types ...AggregateType) *SearchQuery {
query.aggregateTypes = types
return query
}
//SequenceGreater filters for events with sequence greater the requested sequence
// SequenceGreater filters for events with sequence greater the requested sequence
func (query *SearchQuery) SequenceGreater(sequence uint64) *SearchQuery {
query.eventSequenceGreater = sequence
return query
}
//SequenceLess filters for events with sequence less the requested sequence
// SequenceLess filters for events with sequence less the requested sequence
func (query *SearchQuery) SequenceLess(sequence uint64) *SearchQuery {
query.eventSequenceLess = sequence
return query
}
//AggregateIDs filters for events with the given aggregate id's
// AggregateIDs filters for events with the given aggregate id's
func (query *SearchQuery) AggregateIDs(ids ...string) *SearchQuery {
query.aggregateIDs = ids
return query
}
//InstanceID filters for events with the given instanceID
// InstanceID filters for events with the given instanceID
func (query *SearchQuery) InstanceID(instanceID string) *SearchQuery {
query.instanceID = instanceID
return query
}
//ExcludedInstanceID filters for events not having the given instanceIDs
// ExcludedInstanceID filters for events not having the given instanceIDs
func (query *SearchQuery) ExcludedInstanceID(instanceIDs ...string) *SearchQuery {
query.excludedInstanceIDs = instanceIDs
return query
}
//EventTypes filters for events with the given event types
// EventTypes filters for events with the given event types
func (query *SearchQuery) EventTypes(types ...EventType) *SearchQuery {
query.eventTypes = types
return query
}
//EventData filters for events with the given event data.
//Use this call with care as it will be slower than the other filters.
// EventData filters for events with the given event data.
// Use this call with care as it will be slower than the other filters.
func (query *SearchQuery) EventData(data map[string]interface{}) *SearchQuery {
query.eventData = data
return query
}
//Builder returns the SearchQueryBuilder of the sub query
// Builder returns the SearchQueryBuilder of the sub query
func (query *SearchQuery) Builder() *SearchQueryBuilder {
return query.builder
}
@@ -262,7 +263,7 @@ func (query *SearchQuery) aggregateIDFilter() *repository.Filter {
if len(query.aggregateIDs) == 1 {
return repository.NewFilter(repository.FieldAggregateID, query.aggregateIDs[0], repository.OperationEquals)
}
return repository.NewFilter(repository.FieldAggregateID, query.aggregateIDs, repository.OperationIn)
return repository.NewFilter(repository.FieldAggregateID, database.StringArray(query.aggregateIDs), repository.OperationIn)
}
func (query *SearchQuery) eventTypeFilter() *repository.Filter {
@@ -272,9 +273,9 @@ func (query *SearchQuery) eventTypeFilter() *repository.Filter {
if len(query.eventTypes) == 1 {
return repository.NewFilter(repository.FieldEventType, repository.EventType(query.eventTypes[0]), repository.OperationEquals)
}
eventTypes := make([]repository.EventType, len(query.eventTypes))
eventTypes := make(database.StringArray, len(query.eventTypes))
for i, eventType := range query.eventTypes {
eventTypes[i] = repository.EventType(eventType)
eventTypes[i] = string(eventType)
}
return repository.NewFilter(repository.FieldEventType, eventTypes, repository.OperationIn)
}
@@ -286,9 +287,9 @@ func (query *SearchQuery) aggregateTypeFilter() *repository.Filter {
if len(query.aggregateTypes) == 1 {
return repository.NewFilter(repository.FieldAggregateType, repository.AggregateType(query.aggregateTypes[0]), repository.OperationEquals)
}
aggregateTypes := make([]repository.AggregateType, len(query.aggregateTypes))
aggregateTypes := make(database.StringArray, len(query.aggregateTypes))
for i, aggregateType := range query.aggregateTypes {
aggregateTypes[i] = repository.AggregateType(aggregateType)
aggregateTypes[i] = string(aggregateType)
}
return repository.NewFilter(repository.FieldAggregateType, aggregateTypes, repository.OperationIn)
}
@@ -326,7 +327,7 @@ func (query *SearchQuery) excludedInstanceIDFilter() *repository.Filter {
if len(query.excludedInstanceIDs) == 0 {
return nil
}
return repository.NewFilter(repository.FieldInstanceID, query.excludedInstanceIDs, repository.OperationNotIn)
return repository.NewFilter(repository.FieldInstanceID, database.StringArray(query.excludedInstanceIDs), repository.OperationNotIn)
}
func (builder *SearchQueryBuilder) resourceOwnerFilter() *repository.Filter {
+6 -5
View File
@@ -5,6 +5,7 @@ import (
"reflect"
"testing"
"github.com/zitadel/zitadel/internal/database"
"github.com/zitadel/zitadel/internal/errors"
"github.com/zitadel/zitadel/internal/eventstore/repository"
)
@@ -312,7 +313,7 @@ func TestSearchQuerybuilderBuild(t *testing.T) {
Limit: 0,
Filters: [][]*repository.Filter{
{
repository.NewFilter(repository.FieldAggregateType, []repository.AggregateType{"user", "org"}, repository.OperationIn),
repository.NewFilter(repository.FieldAggregateType, database.StringArray{"user", "org"}, repository.OperationIn),
},
},
},
@@ -483,7 +484,7 @@ func TestSearchQuerybuilderBuild(t *testing.T) {
Filters: [][]*repository.Filter{
{
repository.NewFilter(repository.FieldAggregateType, repository.AggregateType("user"), repository.OperationEquals),
repository.NewFilter(repository.FieldAggregateID, []string{"1234", "0815"}, repository.OperationIn),
repository.NewFilter(repository.FieldAggregateID, database.StringArray{"1234", "0815"}, repository.OperationIn),
},
},
},
@@ -561,7 +562,7 @@ func TestSearchQuerybuilderBuild(t *testing.T) {
Filters: [][]*repository.Filter{
{
repository.NewFilter(repository.FieldAggregateType, repository.AggregateType("user"), repository.OperationEquals),
repository.NewFilter(repository.FieldEventType, []repository.EventType{"user.created", "user.changed"}, repository.OperationIn),
repository.NewFilter(repository.FieldEventType, database.StringArray{"user.created", "user.changed"}, repository.OperationIn),
},
},
},
@@ -740,10 +741,10 @@ func assertRepoQuery(t *testing.T, want, got *repository.SearchQuery) {
if !reflect.DeepEqual(got.Columns, want.Columns) {
t.Errorf("wrong columns in query: got: %v want: %v", got.Columns, want.Columns)
}
if !reflect.DeepEqual(got.Desc, want.Desc) {
if got.Desc != want.Desc {
t.Errorf("wrong desc in query: got: %v want: %v", got.Desc, want.Desc)
}
if !reflect.DeepEqual(got.Limit, want.Limit) {
if got.Limit != want.Limit {
t.Errorf("wrong limit in query: got: %v want: %v", got.Limit, want.Limit)
}
@@ -2,8 +2,6 @@ package sql
import (
"database/sql"
_ "github.com/lib/pq"
)
func Start(client *sql.DB) *SQL {
@@ -7,7 +7,6 @@ import (
"strconv"
"strings"
"github.com/lib/pq"
"github.com/zitadel/logging"
z_errors "github.com/zitadel/zitadel/internal/errors"
@@ -72,10 +71,6 @@ func prepareCondition(filters [][]*es_models.Filter) (clause string, values []in
subClauses := make([]string, 0, len(filter))
for _, f := range filter {
value := f.GetValue()
switch value.(type) {
case []bool, []float64, []int64, []string, []es_models.AggregateType, []es_models.EventType, *[]bool, *[]float64, *[]int64, *[]string, *[]es_models.AggregateType, *[]es_models.EventType:
value = pq.Array(value)
}
subClauses = append(subClauses, getCondition(f))
if subClauses[len(subClauses)-1] == "" {
@@ -6,8 +6,6 @@ import (
"testing"
"time"
"github.com/lib/pq"
"github.com/zitadel/zitadel/internal/errors"
es_models "github.com/zitadel/zitadel/internal/eventstore/v1/models"
)
@@ -365,7 +363,7 @@ func Test_prepareCondition(t *testing.T) {
},
res: res{
clause: " WHERE ( aggregate_type = ANY(?) )",
values: []interface{}{pq.Array([]es_models.AggregateType{"user", "org"})},
values: []interface{}{[]es_models.AggregateType{"user", "org"}},
},
},
{
@@ -381,7 +379,7 @@ func Test_prepareCondition(t *testing.T) {
},
res: res{
clause: " WHERE ( aggregate_type = ANY(?) AND aggregate_id = ? AND event_type = ANY(?) )",
values: []interface{}{pq.Array([]es_models.AggregateType{"user", "org"}), "1234", pq.Array([]es_models.EventType{"user.created", "org.created"})},
values: []interface{}{[]es_models.AggregateType{"user", "org"}, "1234", []es_models.EventType{"user.created", "org.created"}},
},
},
}
@@ -3,9 +3,6 @@ package sql
import (
"context"
"database/sql"
//sql import
_ "github.com/lib/pq"
)
type SQL struct {
+1 -1
View File
@@ -31,7 +31,7 @@ func Renew(dbClient *sql.DB, lockTable, lockerID, viewModel, instanceID string,
return crdb.ExecuteTx(context.Background(), dbClient, nil, func(tx *sql.Tx) error {
insert := fmt.Sprintf(insertStmtFormat, lockTable)
result, err := tx.Exec(insert,
lockerID, waitTime.Milliseconds()/millisecondsAsSeconds, viewModel, instanceID)
lockerID, waitTime, viewModel, instanceID)
if err != nil {
tx.Rollback()
+6 -1
View File
@@ -38,7 +38,12 @@ func ReduceEvent(handler Handler, event *models.Event) {
if err != nil {
handler.Subscription().Unsubscribe()
logging.WithFields("cause", err, "stack", string(debug.Stack())).Error("reduce panicked")
logging.WithFields(
"cause", err,
"stack", string(debug.Stack()),
"sequence", event.Sequence,
"instnace", event.InstanceID,
).Error("reduce panicked")
}
}()
currentSequence, err := handler.CurrentSequence(event.InstanceID)
+5 -2
View File
@@ -75,7 +75,10 @@ func (s *spooledHandler) load(workerID string) {
err := recover()
if err != nil {
logging.WithFields("cause", err, "stack", string(debug.Stack())).Error("reduce panicked")
logging.WithFields(
"cause", err,
"stack", string(debug.Stack()),
).Error("reduce panicked")
}
}()
ctx, cancel := context.WithCancel(context.Background())
@@ -167,7 +170,7 @@ func (s *spooledHandler) query(ctx context.Context, instanceIDs ...string) ([]*m
return s.eventstore.FilterEvents(ctx, query)
}
//lock ensures the lock on the database.
// lock ensures the lock on the database.
// the returned channel will be closed if ctx is done or an error occured durring lock
func (s *spooledHandler) lock(ctx context.Context, errs chan<- error, workerID string) chan bool {
renewTimer := time.After(0)
@@ -5,11 +5,11 @@ import (
"time"
"github.com/zitadel/zitadel/internal/crypto"
"github.com/zitadel/zitadel/internal/database"
"github.com/zitadel/zitadel/internal/eventstore"
"github.com/zitadel/zitadel/internal/repository/instance"
"github.com/zitadel/zitadel/internal/repository/org"
"github.com/lib/pq"
"github.com/zitadel/logging"
caos_errs "github.com/zitadel/zitadel/internal/errors"
@@ -36,18 +36,18 @@ type IDPConfigView struct {
IDPProviderType int32 `json:"-" gorm:"column:idp_provider_type"`
AutoRegister bool `json:"autoRegister" gorm:"column:auto_register"`
IsOIDC bool `json:"-" gorm:"column:is_oidc"`
OIDCClientID string `json:"clientId" gorm:"column:oidc_client_id"`
OIDCClientSecret *crypto.CryptoValue `json:"clientSecret" gorm:"column:oidc_client_secret"`
OIDCIssuer string `json:"issuer" gorm:"column:oidc_issuer"`
OIDCScopes pq.StringArray `json:"scopes" gorm:"column:oidc_scopes"`
OIDCIDPDisplayNameMapping int32 `json:"idpDisplayNameMapping" gorm:"column:oidc_idp_display_name_mapping"`
OIDCUsernameMapping int32 `json:"usernameMapping" gorm:"column:oidc_idp_username_mapping"`
OAuthAuthorizationEndpoint string `json:"authorizationEndpoint" gorm:"column:oauth_authorization_endpoint"`
OAuthTokenEndpoint string `json:"tokenEndpoint" gorm:"column:oauth_token_endpoint"`
JWTEndpoint string `json:"jwtEndpoint" gorm:"jwt_endpoint"`
JWTKeysEndpoint string `json:"keysEndpoint" gorm:"jwt_keys_endpoint"`
JWTHeaderName string `json:"headerName" gorm:"jwt_header_name"`
IsOIDC bool `json:"-" gorm:"column:is_oidc"`
OIDCClientID string `json:"clientId" gorm:"column:oidc_client_id"`
OIDCClientSecret *crypto.CryptoValue `json:"clientSecret" gorm:"column:oidc_client_secret"`
OIDCIssuer string `json:"issuer" gorm:"column:oidc_issuer"`
OIDCScopes database.StringArray `json:"scopes" gorm:"column:oidc_scopes"`
OIDCIDPDisplayNameMapping int32 `json:"idpDisplayNameMapping" gorm:"column:oidc_idp_display_name_mapping"`
OIDCUsernameMapping int32 `json:"usernameMapping" gorm:"column:oidc_idp_username_mapping"`
OAuthAuthorizationEndpoint string `json:"authorizationEndpoint" gorm:"column:oauth_authorization_endpoint"`
OAuthTokenEndpoint string `json:"tokenEndpoint" gorm:"column:oauth_token_endpoint"`
JWTEndpoint string `json:"jwtEndpoint" gorm:"jwt_endpoint"`
JWTKeysEndpoint string `json:"keysEndpoint" gorm:"jwt_keys_endpoint"`
JWTHeaderName string `json:"headerName" gorm:"jwt_header_name"`
Sequence uint64 `json:"-" gorm:"column:sequence"`
InstanceID string `json:"instanceID" gorm:"column:instance_id;primary_key"`
+2 -2
View File
@@ -51,7 +51,7 @@ func SonyFlakeGenerator() Generator {
}
// the following is a copy of sonyflake (https://github.com/sony/sonyflake/blob/master/sonyflake.go)
//with the change of using the "POD-IP" if no private ip is found
// with the change of using the "POD-IP" if no private ip is found
func privateIPv4() (net.IP, error) {
as, err := net.InterfaceAddrs()
if err != nil {
@@ -88,7 +88,7 @@ func isPrivateIPv4(ip net.IP) bool {
func machineID() (uint16, error) {
if GeneratorConfig == nil {
return 0, errors.New("Cannot create a unique ID for the machine, generator has not been configured.")
return 0, errors.New("cannot create a unique id for the machine, generator has not been configured")
}
errors := []string{}
@@ -4,10 +4,10 @@ import (
"encoding/json"
"time"
"github.com/lib/pq"
"github.com/zitadel/logging"
http_util "github.com/zitadel/zitadel/internal/api/http"
"github.com/zitadel/zitadel/internal/database"
"github.com/zitadel/zitadel/internal/domain"
caos_errs "github.com/zitadel/zitadel/internal/errors"
"github.com/zitadel/zitadel/internal/eventstore"
@@ -37,30 +37,30 @@ type ApplicationView struct {
HasProjectCheck bool `json:"hasProjectCheck" gorm:"column:has_project_check"`
PrivateLabelingSetting domain.PrivateLabelingSetting `json:"privateLabelingSetting" gorm:"column:private_labeling_setting"`
IsOIDC bool `json:"-" gorm:"column:is_oidc"`
OIDCVersion int32 `json:"oidcVersion" gorm:"column:oidc_version"`
OIDCClientID string `json:"clientId" gorm:"column:oidc_client_id"`
OIDCRedirectUris pq.StringArray `json:"redirectUris" gorm:"column:oidc_redirect_uris"`
OIDCResponseTypes pq.Int64Array `json:"responseTypes" gorm:"column:oidc_response_types"`
OIDCGrantTypes pq.Int64Array `json:"grantTypes" gorm:"column:oidc_grant_types"`
OIDCApplicationType int32 `json:"applicationType" gorm:"column:oidc_application_type"`
OIDCAuthMethodType int32 `json:"authMethodType" gorm:"column:oidc_auth_method_type"`
OIDCPostLogoutRedirectUris pq.StringArray `json:"postLogoutRedirectUris" gorm:"column:oidc_post_logout_redirect_uris"`
NoneCompliant bool `json:"-" gorm:"column:none_compliant"`
ComplianceProblems pq.StringArray `json:"-" gorm:"column:compliance_problems"`
DevMode bool `json:"devMode" gorm:"column:dev_mode"`
OriginAllowList pq.StringArray `json:"-" gorm:"column:origin_allow_list"`
AdditionalOrigins pq.StringArray `json:"additionalOrigins" gorm:"column:additional_origins"`
AccessTokenType int32 `json:"accessTokenType" gorm:"column:access_token_type"`
AccessTokenRoleAssertion bool `json:"accessTokenRoleAssertion" gorm:"column:access_token_role_assertion"`
IDTokenRoleAssertion bool `json:"idTokenRoleAssertion" gorm:"column:id_token_role_assertion"`
IDTokenUserinfoAssertion bool `json:"idTokenUserinfoAssertion" gorm:"column:id_token_userinfo_assertion"`
ClockSkew time.Duration `json:"clockSkew" gorm:"column:clock_skew"`
IsOIDC bool `json:"-" gorm:"column:is_oidc"`
OIDCVersion int32 `json:"oidcVersion" gorm:"column:oidc_version"`
OIDCClientID string `json:"clientId" gorm:"column:oidc_client_id"`
OIDCRedirectUris database.StringArray `json:"redirectUris" gorm:"column:oidc_redirect_uris"`
OIDCResponseTypes database.EnumArray[domain.OIDCResponseType] `json:"responseTypes" gorm:"column:oidc_response_types"`
OIDCGrantTypes database.EnumArray[domain.OIDCGrantType] `json:"grantTypes" gorm:"column:oidc_grant_types"`
OIDCApplicationType int32 `json:"applicationType" gorm:"column:oidc_application_type"`
OIDCAuthMethodType int32 `json:"authMethodType" gorm:"column:oidc_auth_method_type"`
OIDCPostLogoutRedirectUris database.StringArray `json:"postLogoutRedirectUris" gorm:"column:oidc_post_logout_redirect_uris"`
NoneCompliant bool `json:"-" gorm:"column:none_compliant"`
ComplianceProblems database.StringArray `json:"-" gorm:"column:compliance_problems"`
DevMode bool `json:"devMode" gorm:"column:dev_mode"`
OriginAllowList database.StringArray `json:"-" gorm:"column:origin_allow_list"`
AdditionalOrigins database.StringArray `json:"additionalOrigins" gorm:"column:additional_origins"`
AccessTokenType int32 `json:"accessTokenType" gorm:"column:access_token_type"`
AccessTokenRoleAssertion bool `json:"accessTokenRoleAssertion" gorm:"column:access_token_role_assertion"`
IDTokenRoleAssertion bool `json:"idTokenRoleAssertion" gorm:"column:id_token_role_assertion"`
IDTokenUserinfoAssertion bool `json:"idTokenUserinfoAssertion" gorm:"column:id_token_userinfo_assertion"`
ClockSkew time.Duration `json:"clockSkew" gorm:"column:clock_skew"`
Sequence uint64 `json:"-" gorm:"sequence"`
}
func OIDCResponseTypesToModel(oidctypes []int64) []model.OIDCResponseType {
func OIDCResponseTypesToModel(oidctypes []domain.OIDCResponseType) []model.OIDCResponseType {
result := make([]model.OIDCResponseType, len(oidctypes))
for i, t := range oidctypes {
result[i] = model.OIDCResponseType(t)
@@ -68,7 +68,7 @@ func OIDCResponseTypesToModel(oidctypes []int64) []model.OIDCResponseType {
return result
}
func OIDCGrantTypesToModel(granttypes []int64) []model.OIDCGrantType {
func OIDCGrantTypesToModel(granttypes []domain.OIDCGrantType) []model.OIDCGrantType {
result := make([]model.OIDCGrantType, len(granttypes))
for i, t := range granttypes {
result[i] = model.OIDCGrantType(t)
@@ -169,7 +169,7 @@ func (a *ApplicationView) SetData(event *models.Event) error {
}
func (a *ApplicationView) setOriginAllowList() error {
allowList := make([]string, 0)
allowList := make(database.StringArray, 0)
for _, redirect := range a.OIDCRedirectUris {
origin, err := http_util.GetOriginFromURLString(redirect)
if err != nil {
@@ -4,9 +4,9 @@ import (
"encoding/json"
"time"
"github.com/lib/pq"
"github.com/zitadel/logging"
"github.com/zitadel/zitadel/internal/database"
caos_errs "github.com/zitadel/zitadel/internal/errors"
"github.com/zitadel/zitadel/internal/eventstore"
"github.com/zitadel/zitadel/internal/eventstore/v1/models"
@@ -24,18 +24,18 @@ const (
)
type ProjectGrantView struct {
GrantID string `json:"-" gorm:"column:grant_id;primary_key"`
ProjectID string `json:"-" gorm:"column:project_id"`
OrgID string `json:"-" gorm:"column:org_id"`
Name string `json:"name" gorm:"column:project_name"`
CreationDate time.Time `json:"-" gorm:"column:creation_date"`
ChangeDate time.Time `json:"-" gorm:"column:change_date"`
State int32 `json:"-" gorm:"column:project_state"`
ResourceOwner string `json:"-" gorm:"column:resource_owner"`
ResourceOwnerName string `json:"-" gorm:"column:resource_owner_name"`
OrgName string `json:"-" gorm:"column:org_name"`
Sequence uint64 `json:"-" gorm:"column:sequence"`
GrantedRoleKeys pq.StringArray `json:"-" gorm:"column:granted_role_keys"`
GrantID string `json:"-" gorm:"column:grant_id;primary_key"`
ProjectID string `json:"-" gorm:"column:project_id"`
OrgID string `json:"-" gorm:"column:org_id"`
Name string `json:"name" gorm:"column:project_name"`
CreationDate time.Time `json:"-" gorm:"column:creation_date"`
ChangeDate time.Time `json:"-" gorm:"column:change_date"`
State int32 `json:"-" gorm:"column:project_state"`
ResourceOwner string `json:"-" gorm:"column:resource_owner"`
ResourceOwnerName string `json:"-" gorm:"column:resource_owner_name"`
OrgName string `json:"-" gorm:"column:org_name"`
Sequence uint64 `json:"-" gorm:"column:sequence"`
GrantedRoleKeys database.StringArray `json:"-" gorm:"column:granted_role_keys"`
}
type ProjectGrant struct {
@@ -4,9 +4,9 @@ import (
"encoding/json"
"time"
"github.com/lib/pq"
"github.com/zitadel/logging"
"github.com/zitadel/zitadel/internal/database"
caos_errs "github.com/zitadel/zitadel/internal/errors"
"github.com/zitadel/zitadel/internal/eventstore"
"github.com/zitadel/zitadel/internal/eventstore/v1/models"
@@ -24,19 +24,19 @@ const (
)
type ProjectGrantMemberView struct {
UserID string `json:"userId" gorm:"column:user_id;primary_key"`
GrantID string `json:"grantId" gorm:"column:grant_id;primary_key"`
ProjectID string `json:"-" gorm:"column:project_id"`
UserName string `json:"-" gorm:"column:user_name"`
Email string `json:"-" gorm:"column:email_address"`
FirstName string `json:"-" gorm:"column:first_name"`
LastName string `json:"-" gorm:"column:last_name"`
DisplayName string `json:"-" gorm:"column:display_name"`
Roles pq.StringArray `json:"roles" gorm:"column:roles"`
Sequence uint64 `json:"-" gorm:"column:sequence"`
PreferredLoginName string `json:"-" gorm:"column:preferred_login_name"`
AvatarKey string `json:"-" gorm:"column:avatar_key"`
UserResourceOwner string `json:"-" gorm:"column:user_resource_owner"`
UserID string `json:"userId" gorm:"column:user_id;primary_key"`
GrantID string `json:"grantId" gorm:"column:grant_id;primary_key"`
ProjectID string `json:"-" gorm:"column:project_id"`
UserName string `json:"-" gorm:"column:user_name"`
Email string `json:"-" gorm:"column:email_address"`
FirstName string `json:"-" gorm:"column:first_name"`
LastName string `json:"-" gorm:"column:last_name"`
DisplayName string `json:"-" gorm:"column:display_name"`
Roles database.StringArray `json:"roles" gorm:"column:roles"`
Sequence uint64 `json:"-" gorm:"column:sequence"`
PreferredLoginName string `json:"-" gorm:"column:preferred_login_name"`
AvatarKey string `json:"-" gorm:"column:avatar_key"`
UserResourceOwner string `json:"-" gorm:"column:user_resource_owner"`
CreationDate time.Time `json:"-" gorm:"column:creation_date"`
ChangeDate time.Time `json:"-" gorm:"column:change_date"`
@@ -5,8 +5,6 @@ import (
"reflect"
"testing"
"github.com/lib/pq"
es_models "github.com/zitadel/zitadel/internal/eventstore/v1/models"
es_model "github.com/zitadel/zitadel/internal/project/repository/eventsourcing/model"
"github.com/zitadel/zitadel/internal/repository/project"
@@ -30,18 +28,18 @@ func TestGrantedProjectMemberAppendEvent(t *testing.T) {
{
name: "append added member event",
args: args{
event: &es_models.Event{AggregateID: "AggregateID", Sequence: 1, Type: es_models.EventType(project.GrantMemberAddedType), ResourceOwner: "OrgID", Data: mockProjectGrantMemberData(&es_model.ProjectGrantMember{GrantID: "ProjectGrantID", UserID: "UserID", Roles: pq.StringArray{"Role"}})},
event: &es_models.Event{AggregateID: "AggregateID", Sequence: 1, Type: es_models.EventType(project.GrantMemberAddedType), ResourceOwner: "OrgID", Data: mockProjectGrantMemberData(&es_model.ProjectGrantMember{GrantID: "ProjectGrantID", UserID: "UserID", Roles: []string{"Role"}})},
member: &ProjectGrantMemberView{},
},
result: &ProjectGrantMemberView{ProjectID: "AggregateID", UserID: "UserID", GrantID: "ProjectGrantID", Roles: pq.StringArray{"Role"}},
result: &ProjectGrantMemberView{ProjectID: "AggregateID", UserID: "UserID", GrantID: "ProjectGrantID", Roles: []string{"Role"}},
},
{
name: "append changed member event",
args: args{
event: &es_models.Event{AggregateID: "AggregateID", Sequence: 1, Type: es_models.EventType(project.GrantMemberAddedType), ResourceOwner: "OrgID", Data: mockProjectGrantMemberData(&es_model.ProjectGrantMember{GrantID: "ProjectGrantID", Roles: pq.StringArray{"RoleChanged"}})},
member: &ProjectGrantMemberView{ProjectID: "AggregateID", UserID: "UserID", GrantID: "ProjectGrantID", Roles: pq.StringArray{"Role"}},
event: &es_models.Event{AggregateID: "AggregateID", Sequence: 1, Type: es_models.EventType(project.GrantMemberAddedType), ResourceOwner: "OrgID", Data: mockProjectGrantMemberData(&es_model.ProjectGrantMember{GrantID: "ProjectGrantID", Roles: []string{"RoleChanged"}})},
member: &ProjectGrantMemberView{ProjectID: "AggregateID", UserID: "UserID", GrantID: "ProjectGrantID", Roles: []string{"Role"}},
},
result: &ProjectGrantMemberView{ProjectID: "AggregateID", UserID: "UserID", GrantID: "ProjectGrantID", Roles: pq.StringArray{"RoleChanged"}},
result: &ProjectGrantMemberView{ProjectID: "AggregateID", UserID: "UserID", GrantID: "ProjectGrantID", Roles: []string{"RoleChanged"}},
},
}
for _, tt := range tests {
@@ -5,8 +5,6 @@ import (
"reflect"
"testing"
"github.com/lib/pq"
es_models "github.com/zitadel/zitadel/internal/eventstore/v1/models"
"github.com/zitadel/zitadel/internal/project/model"
es_model "github.com/zitadel/zitadel/internal/project/repository/eventsourcing/model"
@@ -36,34 +34,34 @@ func TestProjectGrantAppendEvent(t *testing.T) {
{
name: "append added project grant event",
args: args{
event: &es_models.Event{AggregateID: "AggregateID", Sequence: 1, Type: es_models.EventType(project.GrantAddedType), ResourceOwner: "GrantedOrgID", Data: mockProjectGrantData(&es_model.ProjectGrant{GrantID: "ProjectGrantID", GrantedOrgID: "GrantedOrgID", RoleKeys: pq.StringArray{"Role"}})},
event: &es_models.Event{AggregateID: "AggregateID", Sequence: 1, Type: es_models.EventType(project.GrantAddedType), ResourceOwner: "GrantedOrgID", Data: mockProjectGrantData(&es_model.ProjectGrant{GrantID: "ProjectGrantID", GrantedOrgID: "GrantedOrgID", RoleKeys: []string{"Role"}})},
project: &ProjectGrantView{},
},
result: &ProjectGrantView{ProjectID: "AggregateID", ResourceOwner: "GrantedOrgID", OrgID: "GrantedOrgID", State: int32(model.ProjectStateActive), GrantedRoleKeys: pq.StringArray{"Role"}},
result: &ProjectGrantView{ProjectID: "AggregateID", ResourceOwner: "GrantedOrgID", OrgID: "GrantedOrgID", State: int32(model.ProjectStateActive), GrantedRoleKeys: []string{"Role"}},
},
{
name: "append change project grant event",
args: args{
event: &es_models.Event{AggregateID: "AggregateID", Sequence: 1, Type: es_models.EventType(project.GrantChangedType), ResourceOwner: "GrantedOrgID", Data: mockProjectGrantData(&es_model.ProjectGrant{GrantID: "ProjectGrantID", RoleKeys: pq.StringArray{"RoleChanged"}})},
project: &ProjectGrantView{ProjectID: "AggregateID", ResourceOwner: "GrantedOrgID", OrgID: "GrantedOrgID", State: int32(model.ProjectStateActive), GrantedRoleKeys: pq.StringArray{"Role"}},
event: &es_models.Event{AggregateID: "AggregateID", Sequence: 1, Type: es_models.EventType(project.GrantChangedType), ResourceOwner: "GrantedOrgID", Data: mockProjectGrantData(&es_model.ProjectGrant{GrantID: "ProjectGrantID", RoleKeys: []string{"RoleChanged"}})},
project: &ProjectGrantView{ProjectID: "AggregateID", ResourceOwner: "GrantedOrgID", OrgID: "GrantedOrgID", State: int32(model.ProjectStateActive), GrantedRoleKeys: []string{"Role"}},
},
result: &ProjectGrantView{ProjectID: "AggregateID", ResourceOwner: "GrantedOrgID", OrgID: "GrantedOrgID", State: int32(model.ProjectStateActive), GrantedRoleKeys: pq.StringArray{"RoleChanged"}},
result: &ProjectGrantView{ProjectID: "AggregateID", ResourceOwner: "GrantedOrgID", OrgID: "GrantedOrgID", State: int32(model.ProjectStateActive), GrantedRoleKeys: []string{"RoleChanged"}},
},
{
name: "append deactivate project grant event",
args: args{
event: &es_models.Event{AggregateID: "AggregateID", Sequence: 1, Type: es_models.EventType(project.GrantDeactivatedType), ResourceOwner: "GrantedOrgID", Data: mockProjectGrantData(&es_model.ProjectGrant{GrantID: "ProjectGrantID"})},
project: &ProjectGrantView{ProjectID: "AggregateID", ResourceOwner: "GrantedOrgID", OrgID: "GrantedOrgID", State: int32(model.ProjectStateActive), GrantedRoleKeys: pq.StringArray{"Role"}},
project: &ProjectGrantView{ProjectID: "AggregateID", ResourceOwner: "GrantedOrgID", OrgID: "GrantedOrgID", State: int32(model.ProjectStateActive), GrantedRoleKeys: []string{"Role"}},
},
result: &ProjectGrantView{ProjectID: "AggregateID", ResourceOwner: "GrantedOrgID", OrgID: "GrantedOrgID", State: int32(model.ProjectStateInactive), GrantedRoleKeys: pq.StringArray{"Role"}},
result: &ProjectGrantView{ProjectID: "AggregateID", ResourceOwner: "GrantedOrgID", OrgID: "GrantedOrgID", State: int32(model.ProjectStateInactive), GrantedRoleKeys: []string{"Role"}},
},
{
name: "append reactivate project grant event",
args: args{
event: &es_models.Event{AggregateID: "AggregateID", Sequence: 1, Type: es_models.EventType(project.GrantReactivatedType), ResourceOwner: "GrantedOrgID", Data: mockProjectGrantData(&es_model.ProjectGrant{GrantID: "ProjectGrantID"})},
project: &ProjectGrantView{ProjectID: "AggregateID", ResourceOwner: "GrantedOrgID", OrgID: "GrantedOrgID", State: int32(model.ProjectStateInactive), GrantedRoleKeys: pq.StringArray{"Role"}},
project: &ProjectGrantView{ProjectID: "AggregateID", ResourceOwner: "GrantedOrgID", OrgID: "GrantedOrgID", State: int32(model.ProjectStateInactive), GrantedRoleKeys: []string{"Role"}},
},
result: &ProjectGrantView{ProjectID: "AggregateID", ResourceOwner: "GrantedOrgID", OrgID: "GrantedOrgID", State: int32(model.ProjectStateActive), GrantedRoleKeys: pq.StringArray{"Role"}},
result: &ProjectGrantView{ProjectID: "AggregateID", ResourceOwner: "GrantedOrgID", OrgID: "GrantedOrgID", State: int32(model.ProjectStateActive), GrantedRoleKeys: []string{"Role"}},
},
}
for _, tt := range tests {
@@ -4,9 +4,9 @@ import (
"encoding/json"
"time"
"github.com/lib/pq"
"github.com/zitadel/logging"
"github.com/zitadel/zitadel/internal/database"
caos_errs "github.com/zitadel/zitadel/internal/errors"
"github.com/zitadel/zitadel/internal/eventstore"
"github.com/zitadel/zitadel/internal/eventstore/v1/models"
@@ -23,18 +23,18 @@ const (
)
type ProjectMemberView struct {
UserID string `json:"userId" gorm:"column:user_id;primary_key"`
ProjectID string `json:"-" gorm:"column:project_id;primary_key"`
UserName string `json:"-" gorm:"column:user_name"`
Email string `json:"-" gorm:"column:email_address"`
FirstName string `json:"-" gorm:"column:first_name"`
LastName string `json:"-" gorm:"column:last_name"`
DisplayName string `json:"-" gorm:"column:display_name"`
Roles pq.StringArray `json:"roles" gorm:"column:roles"`
Sequence uint64 `json:"-" gorm:"column:sequence"`
PreferredLoginName string `json:"-" gorm:"column:preferred_login_name"`
AvatarKey string `json:"-" gorm:"column:avatar_key"`
UserResourceOwner string `json:"-" gorm:"column:user_resource_owner"`
UserID string `json:"userId" gorm:"column:user_id;primary_key"`
ProjectID string `json:"-" gorm:"column:project_id;primary_key"`
UserName string `json:"-" gorm:"column:user_name"`
Email string `json:"-" gorm:"column:email_address"`
FirstName string `json:"-" gorm:"column:first_name"`
LastName string `json:"-" gorm:"column:last_name"`
DisplayName string `json:"-" gorm:"column:display_name"`
Roles database.StringArray `json:"roles" gorm:"column:roles"`
Sequence uint64 `json:"-" gorm:"column:sequence"`
PreferredLoginName string `json:"-" gorm:"column:preferred_login_name"`
AvatarKey string `json:"-" gorm:"column:avatar_key"`
UserResourceOwner string `json:"-" gorm:"column:user_resource_owner"`
CreationDate time.Time `json:"-" gorm:"column:creation_date"`
ChangeDate time.Time `json:"-" gorm:"column:change_date"`
@@ -5,8 +5,6 @@ import (
"reflect"
"testing"
"github.com/lib/pq"
es_models "github.com/zitadel/zitadel/internal/eventstore/v1/models"
es_model "github.com/zitadel/zitadel/internal/project/repository/eventsourcing/model"
"github.com/zitadel/zitadel/internal/repository/project"
@@ -30,18 +28,18 @@ func TestProjectMemberAppendEvent(t *testing.T) {
{
name: "append added member event",
args: args{
event: &es_models.Event{AggregateID: "AggregateID", Sequence: 1, Type: es_models.EventType(project.MemberAddedType), ResourceOwner: "OrgID", Data: mockProjectMemberData(&es_model.ProjectMember{UserID: "UserID", Roles: pq.StringArray{"Role"}})},
event: &es_models.Event{AggregateID: "AggregateID", Sequence: 1, Type: es_models.EventType(project.MemberAddedType), ResourceOwner: "OrgID", Data: mockProjectMemberData(&es_model.ProjectMember{UserID: "UserID", Roles: []string{"Role"}})},
member: &ProjectMemberView{},
},
result: &ProjectMemberView{ProjectID: "AggregateID", UserID: "UserID", Roles: pq.StringArray{"Role"}},
result: &ProjectMemberView{ProjectID: "AggregateID", UserID: "UserID", Roles: []string{"Role"}},
},
{
name: "append changed member event",
args: args{
event: &es_models.Event{AggregateID: "AggregateID", Sequence: 1, Type: es_models.EventType(project.MemberAddedType), ResourceOwner: "OrgID", Data: mockProjectMemberData(&es_model.ProjectMember{UserID: "UserID", Roles: pq.StringArray{"RoleChanged"}})},
member: &ProjectMemberView{ProjectID: "AggregateID", UserID: "UserID", Roles: pq.StringArray{"Role"}},
event: &es_models.Event{AggregateID: "AggregateID", Sequence: 1, Type: es_models.EventType(project.MemberAddedType), ResourceOwner: "OrgID", Data: mockProjectMemberData(&es_model.ProjectMember{UserID: "UserID", Roles: []string{"RoleChanged"}})},
member: &ProjectMemberView{ProjectID: "AggregateID", UserID: "UserID", Roles: []string{"Role"}},
},
result: &ProjectMemberView{ProjectID: "AggregateID", UserID: "UserID", Roles: pq.StringArray{"RoleChanged"}},
result: &ProjectMemberView{ProjectID: "AggregateID", UserID: "UserID", Roles: []string{"RoleChanged"}},
},
}
for _, tt := range tests {
+2 -3
View File
@@ -6,7 +6,6 @@ import (
"time"
sq "github.com/Masterminds/squirrel"
"github.com/lib/pq"
"github.com/zitadel/zitadel/internal/api/authz"
@@ -216,8 +215,8 @@ func prepareFlowQuery(flowType domain.FlowType) (sq.SelectBuilder, func(*sql.Row
for rows.Next() {
var (
actionID sql.NullString
actionCreationDate pq.NullTime
actionChangeDate pq.NullTime
actionCreationDate sql.NullTime
actionChangeDate sql.NullTime
actionResourceOwner sql.NullString
actionState sql.NullInt32
actionSequence sql.NullInt64
+81 -81
View File
@@ -31,14 +31,14 @@ func Test_FlowPrepares(t *testing.T) {
},
want: want{
sqlExpectations: mockQueries(
regexp.QuoteMeta(`SELECT projections.actions.id,`+
` projections.actions.creation_date,`+
` projections.actions.change_date,`+
` projections.actions.resource_owner,`+
` projections.actions.action_state,`+
` projections.actions.sequence,`+
` projections.actions.name,`+
` projections.actions.script,`+
regexp.QuoteMeta(`SELECT projections.actions2.id,`+
` projections.actions2.creation_date,`+
` projections.actions2.change_date,`+
` projections.actions2.resource_owner,`+
` projections.actions2.action_state,`+
` projections.actions2.sequence,`+
` projections.actions2.name,`+
` projections.actions2.script,`+
` projections.flows_triggers.trigger_type,`+
` projections.flows_triggers.trigger_sequence,`+
` projections.flows_triggers.flow_type,`+
@@ -46,7 +46,7 @@ func Test_FlowPrepares(t *testing.T) {
` projections.flows_triggers.sequence,`+
` projections.flows_triggers.resource_owner`+
` FROM projections.flows_triggers`+
` LEFT JOIN projections.actions ON projections.flows_triggers.action_id = projections.actions.id`),
` LEFT JOIN projections.actions2 ON projections.flows_triggers.action_id = projections.actions2.id`),
nil,
nil,
),
@@ -63,14 +63,14 @@ func Test_FlowPrepares(t *testing.T) {
},
want: want{
sqlExpectations: mockQueries(
regexp.QuoteMeta(`SELECT projections.actions.id,`+
` projections.actions.creation_date,`+
` projections.actions.change_date,`+
` projections.actions.resource_owner,`+
` projections.actions.action_state,`+
` projections.actions.sequence,`+
` projections.actions.name,`+
` projections.actions.script,`+
regexp.QuoteMeta(`SELECT projections.actions2.id,`+
` projections.actions2.creation_date,`+
` projections.actions2.change_date,`+
` projections.actions2.resource_owner,`+
` projections.actions2.action_state,`+
` projections.actions2.sequence,`+
` projections.actions2.name,`+
` projections.actions2.script,`+
` projections.flows_triggers.trigger_type,`+
` projections.flows_triggers.trigger_sequence,`+
` projections.flows_triggers.flow_type,`+
@@ -78,7 +78,7 @@ func Test_FlowPrepares(t *testing.T) {
` projections.flows_triggers.sequence,`+
` projections.flows_triggers.resource_owner`+
` FROM projections.flows_triggers`+
` LEFT JOIN projections.actions ON projections.flows_triggers.action_id = projections.actions.id`),
` LEFT JOIN projections.actions2 ON projections.flows_triggers.action_id = projections.actions2.id`),
[]string{
"id",
"creation_date",
@@ -144,14 +144,14 @@ func Test_FlowPrepares(t *testing.T) {
},
want: want{
sqlExpectations: mockQueries(
regexp.QuoteMeta(`SELECT projections.actions.id,`+
` projections.actions.creation_date,`+
` projections.actions.change_date,`+
` projections.actions.resource_owner,`+
` projections.actions.action_state,`+
` projections.actions.sequence,`+
` projections.actions.name,`+
` projections.actions.script,`+
regexp.QuoteMeta(`SELECT projections.actions2.id,`+
` projections.actions2.creation_date,`+
` projections.actions2.change_date,`+
` projections.actions2.resource_owner,`+
` projections.actions2.action_state,`+
` projections.actions2.sequence,`+
` projections.actions2.name,`+
` projections.actions2.script,`+
` projections.flows_triggers.trigger_type,`+
` projections.flows_triggers.trigger_sequence,`+
` projections.flows_triggers.flow_type,`+
@@ -159,7 +159,7 @@ func Test_FlowPrepares(t *testing.T) {
` projections.flows_triggers.sequence,`+
` projections.flows_triggers.resource_owner`+
` FROM projections.flows_triggers`+
` LEFT JOIN projections.actions ON projections.flows_triggers.action_id = projections.actions.id`),
` LEFT JOIN projections.actions2 ON projections.flows_triggers.action_id = projections.actions2.id`),
[]string{
"id",
"creation_date",
@@ -253,14 +253,14 @@ func Test_FlowPrepares(t *testing.T) {
},
want: want{
sqlExpectations: mockQueries(
regexp.QuoteMeta(`SELECT projections.actions.id,`+
` projections.actions.creation_date,`+
` projections.actions.change_date,`+
` projections.actions.resource_owner,`+
` projections.actions.action_state,`+
` projections.actions.sequence,`+
` projections.actions.name,`+
` projections.actions.script,`+
regexp.QuoteMeta(`SELECT projections.actions2.id,`+
` projections.actions2.creation_date,`+
` projections.actions2.change_date,`+
` projections.actions2.resource_owner,`+
` projections.actions2.action_state,`+
` projections.actions2.sequence,`+
` projections.actions2.name,`+
` projections.actions2.script,`+
` projections.flows_triggers.trigger_type,`+
` projections.flows_triggers.trigger_sequence,`+
` projections.flows_triggers.flow_type,`+
@@ -268,7 +268,7 @@ func Test_FlowPrepares(t *testing.T) {
` projections.flows_triggers.sequence,`+
` projections.flows_triggers.resource_owner`+
` FROM projections.flows_triggers`+
` LEFT JOIN projections.actions ON projections.flows_triggers.action_id = projections.actions.id`),
` LEFT JOIN projections.actions2 ON projections.flows_triggers.action_id = projections.actions2.id`),
[]string{
"id",
"creation_date",
@@ -321,14 +321,14 @@ func Test_FlowPrepares(t *testing.T) {
},
want: want{
sqlExpectations: mockQueryErr(
regexp.QuoteMeta(`SELECT projections.actions.id,`+
` projections.actions.creation_date,`+
` projections.actions.change_date,`+
` projections.actions.resource_owner,`+
` projections.actions.action_state,`+
` projections.actions.sequence,`+
` projections.actions.name,`+
` projections.actions.script,`+
regexp.QuoteMeta(`SELECT projections.actions2.id,`+
` projections.actions2.creation_date,`+
` projections.actions2.change_date,`+
` projections.actions2.resource_owner,`+
` projections.actions2.action_state,`+
` projections.actions2.sequence,`+
` projections.actions2.name,`+
` projections.actions2.script,`+
` projections.flows_triggers.trigger_type,`+
` projections.flows_triggers.trigger_sequence,`+
` projections.flows_triggers.flow_type,`+
@@ -336,7 +336,7 @@ func Test_FlowPrepares(t *testing.T) {
` projections.flows_triggers.sequence,`+
` projections.flows_triggers.resource_owner`+
` FROM projections.flows_triggers`+
` LEFT JOIN projections.actions ON projections.flows_triggers.action_id = projections.actions.id`),
` LEFT JOIN projections.actions2 ON projections.flows_triggers.action_id = projections.actions2.id`),
sql.ErrConnDone,
),
err: func(err error) (error, bool) {
@@ -353,16 +353,16 @@ func Test_FlowPrepares(t *testing.T) {
prepare: prepareTriggerActionsQuery,
want: want{
sqlExpectations: mockQueries(
regexp.QuoteMeta(`SELECT projections.actions.id,`+
` projections.actions.creation_date,`+
` projections.actions.change_date,`+
` projections.actions.resource_owner,`+
` projections.actions.action_state,`+
` projections.actions.sequence,`+
` projections.actions.name,`+
` projections.actions.script`+
regexp.QuoteMeta(`SELECT projections.actions2.id,`+
` projections.actions2.creation_date,`+
` projections.actions2.change_date,`+
` projections.actions2.resource_owner,`+
` projections.actions2.action_state,`+
` projections.actions2.sequence,`+
` projections.actions2.name,`+
` projections.actions2.script`+
` FROM projections.flows_triggers`+
` LEFT JOIN projections.actions ON projections.flows_triggers.action_id = projections.actions.id`),
` LEFT JOIN projections.actions2 ON projections.flows_triggers.action_id = projections.actions2.id`),
nil,
nil,
),
@@ -374,16 +374,16 @@ func Test_FlowPrepares(t *testing.T) {
prepare: prepareTriggerActionsQuery,
want: want{
sqlExpectations: mockQueries(
regexp.QuoteMeta(`SELECT projections.actions.id,`+
` projections.actions.creation_date,`+
` projections.actions.change_date,`+
` projections.actions.resource_owner,`+
` projections.actions.action_state,`+
` projections.actions.sequence,`+
` projections.actions.name,`+
` projections.actions.script`+
regexp.QuoteMeta(`SELECT projections.actions2.id,`+
` projections.actions2.creation_date,`+
` projections.actions2.change_date,`+
` projections.actions2.resource_owner,`+
` projections.actions2.action_state,`+
` projections.actions2.sequence,`+
` projections.actions2.name,`+
` projections.actions2.script`+
` FROM projections.flows_triggers`+
` LEFT JOIN projections.actions ON projections.flows_triggers.action_id = projections.actions.id`),
` LEFT JOIN projections.actions2 ON projections.flows_triggers.action_id = projections.actions2.id`),
[]string{
"id",
"creation_date",
@@ -426,16 +426,16 @@ func Test_FlowPrepares(t *testing.T) {
prepare: prepareTriggerActionsQuery,
want: want{
sqlExpectations: mockQueries(
regexp.QuoteMeta(`SELECT projections.actions.id,`+
` projections.actions.creation_date,`+
` projections.actions.change_date,`+
` projections.actions.resource_owner,`+
` projections.actions.action_state,`+
` projections.actions.sequence,`+
` projections.actions.name,`+
` projections.actions.script`+
regexp.QuoteMeta(`SELECT projections.actions2.id,`+
` projections.actions2.creation_date,`+
` projections.actions2.change_date,`+
` projections.actions2.resource_owner,`+
` projections.actions2.action_state,`+
` projections.actions2.sequence,`+
` projections.actions2.name,`+
` projections.actions2.script`+
` FROM projections.flows_triggers`+
` LEFT JOIN projections.actions ON projections.flows_triggers.action_id = projections.actions.id`),
` LEFT JOIN projections.actions2 ON projections.flows_triggers.action_id = projections.actions2.id`),
[]string{
"id",
"creation_date",
@@ -498,16 +498,16 @@ func Test_FlowPrepares(t *testing.T) {
prepare: prepareTriggerActionsQuery,
want: want{
sqlExpectations: mockQueryErr(
regexp.QuoteMeta(`SELECT projections.actions.id,`+
` projections.actions.creation_date,`+
` projections.actions.change_date,`+
` projections.actions.resource_owner,`+
` projections.actions.action_state,`+
` projections.actions.sequence,`+
` projections.actions.name,`+
` projections.actions.script`+
regexp.QuoteMeta(`SELECT projections.actions2.id,`+
` projections.actions2.creation_date,`+
` projections.actions2.change_date,`+
` projections.actions2.resource_owner,`+
` projections.actions2.action_state,`+
` projections.actions2.sequence,`+
` projections.actions2.name,`+
` projections.actions2.script`+
` FROM projections.flows_triggers`+
` LEFT JOIN projections.actions ON projections.flows_triggers.action_id = projections.actions.id`),
` LEFT JOIN projections.actions2 ON projections.flows_triggers.action_id = projections.actions2.id`),
sql.ErrConnDone,
),
err: func(err error) (error, bool) {
+77 -77
View File
@@ -29,18 +29,18 @@ func Test_ActionPrepares(t *testing.T) {
prepare: prepareActionsQuery,
want: want{
sqlExpectations: mockQueries(
regexp.QuoteMeta(`SELECT projections.actions.id,`+
` projections.actions.creation_date,`+
` projections.actions.change_date,`+
` projections.actions.resource_owner,`+
` projections.actions.sequence,`+
` projections.actions.action_state,`+
` projections.actions.name,`+
` projections.actions.script,`+
` projections.actions.timeout,`+
` projections.actions.allowed_to_fail,`+
regexp.QuoteMeta(`SELECT projections.actions2.id,`+
` projections.actions2.creation_date,`+
` projections.actions2.change_date,`+
` projections.actions2.resource_owner,`+
` projections.actions2.sequence,`+
` projections.actions2.action_state,`+
` projections.actions2.name,`+
` projections.actions2.script,`+
` projections.actions2.timeout,`+
` projections.actions2.allowed_to_fail,`+
` COUNT(*) OVER ()`+
` FROM projections.actions`),
` FROM projections.actions2`),
nil,
nil,
),
@@ -52,18 +52,18 @@ func Test_ActionPrepares(t *testing.T) {
prepare: prepareActionsQuery,
want: want{
sqlExpectations: mockQueries(
regexp.QuoteMeta(`SELECT projections.actions.id,`+
` projections.actions.creation_date,`+
` projections.actions.change_date,`+
` projections.actions.resource_owner,`+
` projections.actions.sequence,`+
` projections.actions.action_state,`+
` projections.actions.name,`+
` projections.actions.script,`+
` projections.actions.timeout,`+
` projections.actions.allowed_to_fail,`+
regexp.QuoteMeta(`SELECT projections.actions2.id,`+
` projections.actions2.creation_date,`+
` projections.actions2.change_date,`+
` projections.actions2.resource_owner,`+
` projections.actions2.sequence,`+
` projections.actions2.action_state,`+
` projections.actions2.name,`+
` projections.actions2.script,`+
` projections.actions2.timeout,`+
` projections.actions2.allowed_to_fail,`+
` COUNT(*) OVER ()`+
` FROM projections.actions`),
` FROM projections.actions2`),
[]string{
"id",
"creation_date",
@@ -118,18 +118,18 @@ func Test_ActionPrepares(t *testing.T) {
prepare: prepareActionsQuery,
want: want{
sqlExpectations: mockQueries(
regexp.QuoteMeta(`SELECT projections.actions.id,`+
` projections.actions.creation_date,`+
` projections.actions.change_date,`+
` projections.actions.resource_owner,`+
` projections.actions.sequence,`+
` projections.actions.action_state,`+
` projections.actions.name,`+
` projections.actions.script,`+
` projections.actions.timeout,`+
` projections.actions.allowed_to_fail,`+
regexp.QuoteMeta(`SELECT projections.actions2.id,`+
` projections.actions2.creation_date,`+
` projections.actions2.change_date,`+
` projections.actions2.resource_owner,`+
` projections.actions2.sequence,`+
` projections.actions2.action_state,`+
` projections.actions2.name,`+
` projections.actions2.script,`+
` projections.actions2.timeout,`+
` projections.actions2.allowed_to_fail,`+
` COUNT(*) OVER ()`+
` FROM projections.actions`),
` FROM projections.actions2`),
[]string{
"id",
"creation_date",
@@ -208,18 +208,18 @@ func Test_ActionPrepares(t *testing.T) {
prepare: prepareActionsQuery,
want: want{
sqlExpectations: mockQueryErr(
regexp.QuoteMeta(`SELECT projections.actions.id,`+
` projections.actions.creation_date,`+
` projections.actions.change_date,`+
` projections.actions.resource_owner,`+
` projections.actions.sequence,`+
` projections.actions.action_state,`+
` projections.actions.name,`+
` projections.actions.script,`+
` projections.actions.timeout,`+
` projections.actions.allowed_to_fail,`+
regexp.QuoteMeta(`SELECT projections.actions2.id,`+
` projections.actions2.creation_date,`+
` projections.actions2.change_date,`+
` projections.actions2.resource_owner,`+
` projections.actions2.sequence,`+
` projections.actions2.action_state,`+
` projections.actions2.name,`+
` projections.actions2.script,`+
` projections.actions2.timeout,`+
` projections.actions2.allowed_to_fail,`+
` COUNT(*) OVER ()`+
` FROM projections.actions`),
` FROM projections.actions2`),
sql.ErrConnDone,
),
err: func(err error) (error, bool) {
@@ -236,17 +236,17 @@ func Test_ActionPrepares(t *testing.T) {
prepare: prepareActionQuery,
want: want{
sqlExpectations: mockQueries(
regexp.QuoteMeta(`SELECT projections.actions.id,`+
` projections.actions.creation_date,`+
` projections.actions.change_date,`+
` projections.actions.resource_owner,`+
` projections.actions.sequence,`+
` projections.actions.action_state,`+
` projections.actions.name,`+
` projections.actions.script,`+
` projections.actions.timeout,`+
` projections.actions.allowed_to_fail`+
` FROM projections.actions`),
regexp.QuoteMeta(`SELECT projections.actions2.id,`+
` projections.actions2.creation_date,`+
` projections.actions2.change_date,`+
` projections.actions2.resource_owner,`+
` projections.actions2.sequence,`+
` projections.actions2.action_state,`+
` projections.actions2.name,`+
` projections.actions2.script,`+
` projections.actions2.timeout,`+
` projections.actions2.allowed_to_fail`+
` FROM projections.actions2`),
nil,
nil,
),
@@ -264,17 +264,17 @@ func Test_ActionPrepares(t *testing.T) {
prepare: prepareActionQuery,
want: want{
sqlExpectations: mockQuery(
regexp.QuoteMeta(`SELECT projections.actions.id,`+
` projections.actions.creation_date,`+
` projections.actions.change_date,`+
` projections.actions.resource_owner,`+
` projections.actions.sequence,`+
` projections.actions.action_state,`+
` projections.actions.name,`+
` projections.actions.script,`+
` projections.actions.timeout,`+
` projections.actions.allowed_to_fail`+
` FROM projections.actions`),
regexp.QuoteMeta(`SELECT projections.actions2.id,`+
` projections.actions2.creation_date,`+
` projections.actions2.change_date,`+
` projections.actions2.resource_owner,`+
` projections.actions2.sequence,`+
` projections.actions2.action_state,`+
` projections.actions2.name,`+
` projections.actions2.script,`+
` projections.actions2.timeout,`+
` projections.actions2.allowed_to_fail`+
` FROM projections.actions2`),
[]string{
"id",
"creation_date",
@@ -319,17 +319,17 @@ func Test_ActionPrepares(t *testing.T) {
prepare: prepareActionQuery,
want: want{
sqlExpectations: mockQueryErr(
regexp.QuoteMeta(`SELECT projections.actions.id,`+
` projections.actions.creation_date,`+
` projections.actions.change_date,`+
` projections.actions.resource_owner,`+
` projections.actions.sequence,`+
` projections.actions.action_state,`+
` projections.actions.name,`+
` projections.actions.script,`+
` projections.actions.timeout,`+
` projections.actions.allowed_to_fail`+
` FROM projections.actions`),
regexp.QuoteMeta(`SELECT projections.actions2.id,`+
` projections.actions2.creation_date,`+
` projections.actions2.change_date,`+
` projections.actions2.resource_owner,`+
` projections.actions2.sequence,`+
` projections.actions2.action_state,`+
` projections.actions2.name,`+
` projections.actions2.script,`+
` projections.actions2.timeout,`+
` projections.actions2.allowed_to_fail`+
` FROM projections.actions2`),
sql.ErrConnDone,
),
err: func(err error) (error, bool) {
+17 -35
View File
@@ -7,12 +7,10 @@ import (
"time"
sq "github.com/Masterminds/squirrel"
"github.com/lib/pq"
"github.com/zitadel/zitadel/internal/api/authz"
"github.com/zitadel/logging"
"github.com/zitadel/zitadel/internal/api/authz"
"github.com/zitadel/zitadel/internal/database"
"github.com/zitadel/zitadel/internal/domain"
"github.com/zitadel/zitadel/internal/errors"
"github.com/zitadel/zitadel/internal/query/projection"
@@ -39,23 +37,23 @@ type App struct {
}
type OIDCApp struct {
RedirectURIs []string
ResponseTypes []domain.OIDCResponseType
GrantTypes []domain.OIDCGrantType
RedirectURIs database.StringArray
ResponseTypes database.EnumArray[domain.OIDCResponseType]
GrantTypes database.EnumArray[domain.OIDCGrantType]
AppType domain.OIDCApplicationType
ClientID string
AuthMethodType domain.OIDCAuthMethodType
PostLogoutRedirectURIs []string
PostLogoutRedirectURIs database.StringArray
Version domain.OIDCVersion
ComplianceProblems []string
ComplianceProblems database.StringArray
IsDevMode bool
AccessTokenType domain.OIDCTokenType
AssertAccessTokenRole bool
AssertIDTokenRole bool
AssertIDTokenUserinfo bool
ClockSkew time.Duration
AdditionalOrigins []string
AllowedOrigins []string
AdditionalOrigins database.StringArray
AllowedOrigins database.StringArray
}
type APIApp struct {
@@ -613,7 +611,7 @@ func prepareClientIDsQuery() (sq.SelectBuilder, func(*sql.Rows) ([]string, error
LeftJoin(join(AppAPIConfigColumnAppID, AppColumnID)).
LeftJoin(join(AppOIDCConfigColumnAppID, AppColumnID)).
PlaceholderFormat(sq.Dollar), func(rows *sql.Rows) ([]string, error) {
ids := []string{}
ids := database.StringArray{}
for rows.Next() {
var apiID sql.NullString
@@ -639,19 +637,19 @@ type sqlOIDCConfig struct {
appID sql.NullString
version sql.NullInt32
clientID sql.NullString
redirectUris pq.StringArray
redirectUris database.StringArray
applicationType sql.NullInt16
authMethodType sql.NullInt16
postLogoutRedirectUris pq.StringArray
postLogoutRedirectUris database.StringArray
devMode sql.NullBool
accessTokenType sql.NullInt16
accessTokenRoleAssertion sql.NullBool
iDTokenRoleAssertion sql.NullBool
iDTokenUserinfoAssertion sql.NullBool
clockSkew sql.NullInt64
additionalOrigins pq.StringArray
responseTypes pq.Int32Array
grantTypes pq.Int32Array
additionalOrigins database.StringArray
responseTypes database.EnumArray[domain.OIDCResponseType]
grantTypes database.EnumArray[domain.OIDCGrantType]
}
func (c sqlOIDCConfig) set(app *App) {
@@ -672,8 +670,8 @@ func (c sqlOIDCConfig) set(app *App) {
AssertIDTokenUserinfo: c.iDTokenUserinfoAssertion.Bool,
ClockSkew: time.Duration(c.clockSkew.Int64),
AdditionalOrigins: c.additionalOrigins,
ResponseTypes: oidcResponseTypesToDomain(c.responseTypes),
GrantTypes: oidcGrantTypesToDomain(c.grantTypes),
ResponseTypes: c.responseTypes,
GrantTypes: c.grantTypes,
}
compliance := domain.GetOIDCCompliance(app.OIDCConfig.Version, app.OIDCConfig.AppType, app.OIDCConfig.GrantTypes, app.OIDCConfig.ResponseTypes, app.OIDCConfig.AuthMethodType, app.OIDCConfig.RedirectURIs)
app.OIDCConfig.ComplianceProblems = compliance.Problems
@@ -698,19 +696,3 @@ func (c sqlAPIConfig) set(app *App) {
AuthMethodType: domain.APIAuthMethodType(c.authMethod.Int16),
}
}
func oidcResponseTypesToDomain(t pq.Int32Array) []domain.OIDCResponseType {
types := make([]domain.OIDCResponseType, len(t))
for i, typ := range t {
types[i] = domain.OIDCResponseType(typ)
}
return types
}
func oidcGrantTypesToDomain(t pq.Int32Array) []domain.OIDCGrantType {
types := make([]domain.OIDCGrantType, len(t))
for i, typ := range t {
types[i] = domain.OIDCGrantType(typ)
}
return types
}
+210 -211
View File
@@ -9,104 +9,103 @@ import (
"testing"
"time"
"github.com/lib/pq"
"github.com/zitadel/zitadel/internal/database"
"github.com/zitadel/zitadel/internal/domain"
errs "github.com/zitadel/zitadel/internal/errors"
)
var (
expectedAppQuery = regexp.QuoteMeta(`SELECT projections.apps.id,` +
` projections.apps.name,` +
` projections.apps.project_id,` +
` projections.apps.creation_date,` +
` projections.apps.change_date,` +
` projections.apps.resource_owner,` +
` projections.apps.state,` +
` projections.apps.sequence,` +
expectedAppQuery = regexp.QuoteMeta(`SELECT projections.apps2.id,` +
` projections.apps2.name,` +
` projections.apps2.project_id,` +
` projections.apps2.creation_date,` +
` projections.apps2.change_date,` +
` projections.apps2.resource_owner,` +
` projections.apps2.state,` +
` projections.apps2.sequence,` +
// api config
` projections.apps_api_configs.app_id,` +
` projections.apps_api_configs.client_id,` +
` projections.apps_api_configs.auth_method,` +
` projections.apps2_api_configs.app_id,` +
` projections.apps2_api_configs.client_id,` +
` projections.apps2_api_configs.auth_method,` +
// oidc config
` projections.apps_oidc_configs.app_id,` +
` projections.apps_oidc_configs.version,` +
` projections.apps_oidc_configs.client_id,` +
` projections.apps_oidc_configs.redirect_uris,` +
` projections.apps_oidc_configs.response_types,` +
` projections.apps_oidc_configs.grant_types,` +
` projections.apps_oidc_configs.application_type,` +
` projections.apps_oidc_configs.auth_method_type,` +
` projections.apps_oidc_configs.post_logout_redirect_uris,` +
` projections.apps_oidc_configs.is_dev_mode,` +
` projections.apps_oidc_configs.access_token_type,` +
` projections.apps_oidc_configs.access_token_role_assertion,` +
` projections.apps_oidc_configs.id_token_role_assertion,` +
` projections.apps_oidc_configs.id_token_userinfo_assertion,` +
` projections.apps_oidc_configs.clock_skew,` +
` projections.apps_oidc_configs.additional_origins` +
` FROM projections.apps` +
` LEFT JOIN projections.apps_api_configs ON projections.apps.id = projections.apps_api_configs.app_id` +
` LEFT JOIN projections.apps_oidc_configs ON projections.apps.id = projections.apps_oidc_configs.app_id`)
expectedAppsQuery = regexp.QuoteMeta(`SELECT projections.apps.id,` +
` projections.apps.name,` +
` projections.apps.project_id,` +
` projections.apps.creation_date,` +
` projections.apps.change_date,` +
` projections.apps.resource_owner,` +
` projections.apps.state,` +
` projections.apps.sequence,` +
` projections.apps2_oidc_configs.app_id,` +
` projections.apps2_oidc_configs.version,` +
` projections.apps2_oidc_configs.client_id,` +
` projections.apps2_oidc_configs.redirect_uris,` +
` projections.apps2_oidc_configs.response_types,` +
` projections.apps2_oidc_configs.grant_types,` +
` projections.apps2_oidc_configs.application_type,` +
` projections.apps2_oidc_configs.auth_method_type,` +
` projections.apps2_oidc_configs.post_logout_redirect_uris,` +
` projections.apps2_oidc_configs.is_dev_mode,` +
` projections.apps2_oidc_configs.access_token_type,` +
` projections.apps2_oidc_configs.access_token_role_assertion,` +
` projections.apps2_oidc_configs.id_token_role_assertion,` +
` projections.apps2_oidc_configs.id_token_userinfo_assertion,` +
` projections.apps2_oidc_configs.clock_skew,` +
` projections.apps2_oidc_configs.additional_origins` +
` FROM projections.apps2` +
` LEFT JOIN projections.apps2_api_configs ON projections.apps2.id = projections.apps2_api_configs.app_id` +
` LEFT JOIN projections.apps2_oidc_configs ON projections.apps2.id = projections.apps2_oidc_configs.app_id`)
expectedAppsQuery = regexp.QuoteMeta(`SELECT projections.apps2.id,` +
` projections.apps2.name,` +
` projections.apps2.project_id,` +
` projections.apps2.creation_date,` +
` projections.apps2.change_date,` +
` projections.apps2.resource_owner,` +
` projections.apps2.state,` +
` projections.apps2.sequence,` +
// api config
` projections.apps_api_configs.app_id,` +
` projections.apps_api_configs.client_id,` +
` projections.apps_api_configs.auth_method,` +
` projections.apps2_api_configs.app_id,` +
` projections.apps2_api_configs.client_id,` +
` projections.apps2_api_configs.auth_method,` +
// oidc config
` projections.apps_oidc_configs.app_id,` +
` projections.apps_oidc_configs.version,` +
` projections.apps_oidc_configs.client_id,` +
` projections.apps_oidc_configs.redirect_uris,` +
` projections.apps_oidc_configs.response_types,` +
` projections.apps_oidc_configs.grant_types,` +
` projections.apps_oidc_configs.application_type,` +
` projections.apps_oidc_configs.auth_method_type,` +
` projections.apps_oidc_configs.post_logout_redirect_uris,` +
` projections.apps_oidc_configs.is_dev_mode,` +
` projections.apps_oidc_configs.access_token_type,` +
` projections.apps_oidc_configs.access_token_role_assertion,` +
` projections.apps_oidc_configs.id_token_role_assertion,` +
` projections.apps_oidc_configs.id_token_userinfo_assertion,` +
` projections.apps_oidc_configs.clock_skew,` +
` projections.apps_oidc_configs.additional_origins,` +
` projections.apps2_oidc_configs.app_id,` +
` projections.apps2_oidc_configs.version,` +
` projections.apps2_oidc_configs.client_id,` +
` projections.apps2_oidc_configs.redirect_uris,` +
` projections.apps2_oidc_configs.response_types,` +
` projections.apps2_oidc_configs.grant_types,` +
` projections.apps2_oidc_configs.application_type,` +
` projections.apps2_oidc_configs.auth_method_type,` +
` projections.apps2_oidc_configs.post_logout_redirect_uris,` +
` projections.apps2_oidc_configs.is_dev_mode,` +
` projections.apps2_oidc_configs.access_token_type,` +
` projections.apps2_oidc_configs.access_token_role_assertion,` +
` projections.apps2_oidc_configs.id_token_role_assertion,` +
` projections.apps2_oidc_configs.id_token_userinfo_assertion,` +
` projections.apps2_oidc_configs.clock_skew,` +
` projections.apps2_oidc_configs.additional_origins,` +
` COUNT(*) OVER ()` +
` FROM projections.apps` +
` LEFT JOIN projections.apps_api_configs ON projections.apps.id = projections.apps_api_configs.app_id` +
` LEFT JOIN projections.apps_oidc_configs ON projections.apps.id = projections.apps_oidc_configs.app_id`)
expectedAppIDsQuery = regexp.QuoteMeta(`SELECT projections.apps_api_configs.client_id,` +
` projections.apps_oidc_configs.client_id` +
` FROM projections.apps` +
` LEFT JOIN projections.apps_api_configs ON projections.apps.id = projections.apps_api_configs.app_id` +
` LEFT JOIN projections.apps_oidc_configs ON projections.apps.id = projections.apps_oidc_configs.app_id`)
expectedProjectIDByAppQuery = regexp.QuoteMeta(`SELECT projections.apps.project_id` +
` FROM projections.apps` +
` LEFT JOIN projections.apps_api_configs ON projections.apps.id = projections.apps_api_configs.app_id` +
` LEFT JOIN projections.apps_oidc_configs ON projections.apps.id = projections.apps_oidc_configs.app_id`)
expectedProjectByAppQuery = regexp.QuoteMeta(`SELECT projections.projects.id,` +
` projections.projects.creation_date,` +
` projections.projects.change_date,` +
` projections.projects.resource_owner,` +
` projections.projects.state,` +
` projections.projects.sequence,` +
` projections.projects.name,` +
` projections.projects.project_role_assertion,` +
` projections.projects.project_role_check,` +
` projections.projects.has_project_check,` +
` projections.projects.private_labeling_setting` +
` FROM projections.projects` +
` JOIN projections.apps ON projections.projects.id = projections.apps.project_id` +
` LEFT JOIN projections.apps_api_configs ON projections.apps.id = projections.apps_api_configs.app_id` +
` LEFT JOIN projections.apps_oidc_configs ON projections.apps.id = projections.apps_oidc_configs.app_id`)
` FROM projections.apps2` +
` LEFT JOIN projections.apps2_api_configs ON projections.apps2.id = projections.apps2_api_configs.app_id` +
` LEFT JOIN projections.apps2_oidc_configs ON projections.apps2.id = projections.apps2_oidc_configs.app_id`)
expectedAppIDsQuery = regexp.QuoteMeta(`SELECT projections.apps2_api_configs.client_id,` +
` projections.apps2_oidc_configs.client_id` +
` FROM projections.apps2` +
` LEFT JOIN projections.apps2_api_configs ON projections.apps2.id = projections.apps2_api_configs.app_id` +
` LEFT JOIN projections.apps2_oidc_configs ON projections.apps2.id = projections.apps2_oidc_configs.app_id`)
expectedProjectIDByAppQuery = regexp.QuoteMeta(`SELECT projections.apps2.project_id` +
` FROM projections.apps2` +
` LEFT JOIN projections.apps2_api_configs ON projections.apps2.id = projections.apps2_api_configs.app_id` +
` LEFT JOIN projections.apps2_oidc_configs ON projections.apps2.id = projections.apps2_oidc_configs.app_id`)
expectedProjectByAppQuery = regexp.QuoteMeta(`SELECT projections.projects2.id,` +
` projections.projects2.creation_date,` +
` projections.projects2.change_date,` +
` projections.projects2.resource_owner,` +
` projections.projects2.state,` +
` projections.projects2.sequence,` +
` projections.projects2.name,` +
` projections.projects2.project_role_assertion,` +
` projections.projects2.project_role_check,` +
` projections.projects2.has_project_check,` +
` projections.projects2.private_labeling_setting` +
` FROM projections.projects2` +
` JOIN projections.apps2 ON projections.projects2.id = projections.apps2.project_id` +
` LEFT JOIN projections.apps2_api_configs ON projections.apps2.id = projections.apps2_api_configs.app_id` +
` LEFT JOIN projections.apps2_oidc_configs ON projections.apps2.id = projections.apps2_oidc_configs.app_id`)
appCols = []string{
appCols = database.StringArray{
"id",
"name",
"project_id",
@@ -312,19 +311,19 @@ func Test_AppsPrepare(t *testing.T) {
"app-id",
domain.OIDCVersionV1,
"oidc-client-id",
pq.StringArray{"https://redirect.to/me"},
pq.Int32Array{int32(domain.OIDCResponseTypeIDTokenToken)},
pq.Int32Array{int32(domain.OIDCGrantTypeImplicit)},
database.StringArray{"https://redirect.to/me"},
database.EnumArray[domain.OIDCResponseType]{domain.OIDCResponseTypeIDTokenToken},
database.EnumArray[domain.OIDCGrantType]{domain.OIDCGrantTypeImplicit},
domain.OIDCApplicationTypeUserAgent,
domain.OIDCAuthMethodTypeNone,
pq.StringArray{"post.logout.ch"},
database.StringArray{"post.logout.ch"},
true,
domain.OIDCTokenTypeJWT,
true,
true,
true,
1 * time.Second,
pq.StringArray{"additional.origin"},
database.StringArray{"additional.origin"},
},
},
),
@@ -346,21 +345,21 @@ func Test_AppsPrepare(t *testing.T) {
OIDCConfig: &OIDCApp{
Version: domain.OIDCVersionV1,
ClientID: "oidc-client-id",
RedirectURIs: []string{"https://redirect.to/me"},
ResponseTypes: []domain.OIDCResponseType{domain.OIDCResponseTypeIDTokenToken},
GrantTypes: []domain.OIDCGrantType{domain.OIDCGrantTypeImplicit},
RedirectURIs: database.StringArray{"https://redirect.to/me"},
ResponseTypes: database.EnumArray[domain.OIDCResponseType]{domain.OIDCResponseTypeIDTokenToken},
GrantTypes: database.EnumArray[domain.OIDCGrantType]{domain.OIDCGrantTypeImplicit},
AppType: domain.OIDCApplicationTypeUserAgent,
AuthMethodType: domain.OIDCAuthMethodTypeNone,
PostLogoutRedirectURIs: []string{"post.logout.ch"},
PostLogoutRedirectURIs: database.StringArray{"post.logout.ch"},
IsDevMode: true,
AccessTokenType: domain.OIDCTokenTypeJWT,
AssertAccessTokenRole: true,
AssertIDTokenRole: true,
AssertIDTokenUserinfo: true,
ClockSkew: 1 * time.Second,
AdditionalOrigins: []string{"additional.origin"},
AdditionalOrigins: database.StringArray{"additional.origin"},
ComplianceProblems: nil,
AllowedOrigins: []string{"https://redirect.to", "additional.origin"},
AllowedOrigins: database.StringArray{"https://redirect.to", "additional.origin"},
},
},
},
@@ -391,19 +390,19 @@ func Test_AppsPrepare(t *testing.T) {
"app-id",
domain.OIDCVersionV1,
"oidc-client-id",
pq.StringArray{"https://redirect.to/me"},
pq.Int32Array{int32(domain.OIDCResponseTypeIDTokenToken)},
pq.Int32Array{int32(domain.OIDCGrantTypeImplicit)},
database.StringArray{"https://redirect.to/me"},
database.EnumArray[domain.OIDCResponseType]{domain.OIDCResponseTypeIDTokenToken},
database.EnumArray[domain.OIDCGrantType]{domain.OIDCGrantTypeImplicit},
domain.OIDCApplicationTypeUserAgent,
domain.OIDCAuthMethodTypeNone,
pq.StringArray{"post.logout.ch"},
database.StringArray{"post.logout.ch"},
false,
domain.OIDCTokenTypeJWT,
false,
false,
true,
1 * time.Second,
pq.StringArray{"additional.origin"},
database.StringArray{"additional.origin"},
},
},
),
@@ -425,21 +424,21 @@ func Test_AppsPrepare(t *testing.T) {
OIDCConfig: &OIDCApp{
Version: domain.OIDCVersionV1,
ClientID: "oidc-client-id",
RedirectURIs: []string{"https://redirect.to/me"},
ResponseTypes: []domain.OIDCResponseType{domain.OIDCResponseTypeIDTokenToken},
GrantTypes: []domain.OIDCGrantType{domain.OIDCGrantTypeImplicit},
RedirectURIs: database.StringArray{"https://redirect.to/me"},
ResponseTypes: database.EnumArray[domain.OIDCResponseType]{domain.OIDCResponseTypeIDTokenToken},
GrantTypes: database.EnumArray[domain.OIDCGrantType]{domain.OIDCGrantTypeImplicit},
AppType: domain.OIDCApplicationTypeUserAgent,
AuthMethodType: domain.OIDCAuthMethodTypeNone,
PostLogoutRedirectURIs: []string{"post.logout.ch"},
PostLogoutRedirectURIs: database.StringArray{"post.logout.ch"},
IsDevMode: false,
AccessTokenType: domain.OIDCTokenTypeJWT,
AssertAccessTokenRole: false,
AssertIDTokenRole: false,
AssertIDTokenUserinfo: true,
ClockSkew: 1 * time.Second,
AdditionalOrigins: []string{"additional.origin"},
AdditionalOrigins: database.StringArray{"additional.origin"},
ComplianceProblems: nil,
AllowedOrigins: []string{"https://redirect.to", "additional.origin"},
AllowedOrigins: database.StringArray{"https://redirect.to", "additional.origin"},
},
},
},
@@ -470,19 +469,19 @@ func Test_AppsPrepare(t *testing.T) {
"app-id",
domain.OIDCVersionV1,
"oidc-client-id",
pq.StringArray{"https://redirect.to/me"},
pq.Int32Array{int32(domain.OIDCResponseTypeIDTokenToken)},
pq.Int32Array{int32(domain.OIDCGrantTypeImplicit)},
database.StringArray{"https://redirect.to/me"},
database.EnumArray[domain.OIDCResponseType]{domain.OIDCResponseTypeIDTokenToken},
database.EnumArray[domain.OIDCGrantType]{domain.OIDCGrantTypeImplicit},
domain.OIDCApplicationTypeUserAgent,
domain.OIDCAuthMethodTypeNone,
pq.StringArray{"post.logout.ch"},
database.StringArray{"post.logout.ch"},
true,
domain.OIDCTokenTypeJWT,
true,
false,
true,
1 * time.Second,
pq.StringArray{"additional.origin"},
database.StringArray{"additional.origin"},
},
},
),
@@ -504,21 +503,21 @@ func Test_AppsPrepare(t *testing.T) {
OIDCConfig: &OIDCApp{
Version: domain.OIDCVersionV1,
ClientID: "oidc-client-id",
RedirectURIs: []string{"https://redirect.to/me"},
ResponseTypes: []domain.OIDCResponseType{domain.OIDCResponseTypeIDTokenToken},
GrantTypes: []domain.OIDCGrantType{domain.OIDCGrantTypeImplicit},
RedirectURIs: database.StringArray{"https://redirect.to/me"},
ResponseTypes: database.EnumArray[domain.OIDCResponseType]{domain.OIDCResponseTypeIDTokenToken},
GrantTypes: database.EnumArray[domain.OIDCGrantType]{domain.OIDCGrantTypeImplicit},
AppType: domain.OIDCApplicationTypeUserAgent,
AuthMethodType: domain.OIDCAuthMethodTypeNone,
PostLogoutRedirectURIs: []string{"post.logout.ch"},
PostLogoutRedirectURIs: database.StringArray{"post.logout.ch"},
IsDevMode: true,
AccessTokenType: domain.OIDCTokenTypeJWT,
AssertAccessTokenRole: true,
AssertIDTokenRole: false,
AssertIDTokenUserinfo: true,
ClockSkew: 1 * time.Second,
AdditionalOrigins: []string{"additional.origin"},
AdditionalOrigins: database.StringArray{"additional.origin"},
ComplianceProblems: nil,
AllowedOrigins: []string{"https://redirect.to", "additional.origin"},
AllowedOrigins: database.StringArray{"https://redirect.to", "additional.origin"},
},
},
},
@@ -549,19 +548,19 @@ func Test_AppsPrepare(t *testing.T) {
"app-id",
domain.OIDCVersionV1,
"oidc-client-id",
pq.StringArray{"https://redirect.to/me"},
pq.Int32Array{int32(domain.OIDCResponseTypeIDTokenToken)},
pq.Int32Array{int32(domain.OIDCGrantTypeImplicit)},
database.StringArray{"https://redirect.to/me"},
database.EnumArray[domain.OIDCResponseType]{domain.OIDCResponseTypeIDTokenToken},
database.EnumArray[domain.OIDCGrantType]{domain.OIDCGrantTypeImplicit},
domain.OIDCApplicationTypeUserAgent,
domain.OIDCAuthMethodTypeNone,
pq.StringArray{"post.logout.ch"},
database.StringArray{"post.logout.ch"},
false,
domain.OIDCTokenTypeJWT,
false,
true,
true,
1 * time.Second,
pq.StringArray{"additional.origin"},
database.StringArray{"additional.origin"},
},
},
),
@@ -583,21 +582,21 @@ func Test_AppsPrepare(t *testing.T) {
OIDCConfig: &OIDCApp{
Version: domain.OIDCVersionV1,
ClientID: "oidc-client-id",
RedirectURIs: []string{"https://redirect.to/me"},
ResponseTypes: []domain.OIDCResponseType{domain.OIDCResponseTypeIDTokenToken},
GrantTypes: []domain.OIDCGrantType{domain.OIDCGrantTypeImplicit},
RedirectURIs: database.StringArray{"https://redirect.to/me"},
ResponseTypes: database.EnumArray[domain.OIDCResponseType]{domain.OIDCResponseTypeIDTokenToken},
GrantTypes: database.EnumArray[domain.OIDCGrantType]{domain.OIDCGrantTypeImplicit},
AppType: domain.OIDCApplicationTypeUserAgent,
AuthMethodType: domain.OIDCAuthMethodTypeNone,
PostLogoutRedirectURIs: []string{"post.logout.ch"},
PostLogoutRedirectURIs: database.StringArray{"post.logout.ch"},
IsDevMode: false,
AccessTokenType: domain.OIDCTokenTypeJWT,
AssertAccessTokenRole: false,
AssertIDTokenRole: true,
AssertIDTokenUserinfo: true,
ClockSkew: 1 * time.Second,
AdditionalOrigins: []string{"additional.origin"},
AdditionalOrigins: database.StringArray{"additional.origin"},
ComplianceProblems: nil,
AllowedOrigins: []string{"https://redirect.to", "additional.origin"},
AllowedOrigins: database.StringArray{"https://redirect.to", "additional.origin"},
},
},
},
@@ -628,19 +627,19 @@ func Test_AppsPrepare(t *testing.T) {
"app-id",
domain.OIDCVersionV1,
"oidc-client-id",
pq.StringArray{"https://redirect.to/me"},
pq.Int32Array{int32(domain.OIDCResponseTypeIDTokenToken)},
pq.Int32Array{int32(domain.OIDCGrantTypeImplicit)},
database.StringArray{"https://redirect.to/me"},
database.EnumArray[domain.OIDCResponseType]{domain.OIDCResponseTypeIDTokenToken},
database.EnumArray[domain.OIDCGrantType]{domain.OIDCGrantTypeImplicit},
domain.OIDCApplicationTypeUserAgent,
domain.OIDCAuthMethodTypeNone,
pq.StringArray{"post.logout.ch"},
database.StringArray{"post.logout.ch"},
false,
domain.OIDCTokenTypeJWT,
true,
true,
true,
1 * time.Second,
pq.StringArray{"additional.origin"},
database.StringArray{"additional.origin"},
},
},
),
@@ -662,21 +661,21 @@ func Test_AppsPrepare(t *testing.T) {
OIDCConfig: &OIDCApp{
Version: domain.OIDCVersionV1,
ClientID: "oidc-client-id",
RedirectURIs: []string{"https://redirect.to/me"},
ResponseTypes: []domain.OIDCResponseType{domain.OIDCResponseTypeIDTokenToken},
GrantTypes: []domain.OIDCGrantType{domain.OIDCGrantTypeImplicit},
RedirectURIs: database.StringArray{"https://redirect.to/me"},
ResponseTypes: database.EnumArray[domain.OIDCResponseType]{domain.OIDCResponseTypeIDTokenToken},
GrantTypes: database.EnumArray[domain.OIDCGrantType]{domain.OIDCGrantTypeImplicit},
AppType: domain.OIDCApplicationTypeUserAgent,
AuthMethodType: domain.OIDCAuthMethodTypeNone,
PostLogoutRedirectURIs: []string{"post.logout.ch"},
PostLogoutRedirectURIs: database.StringArray{"post.logout.ch"},
IsDevMode: false,
AccessTokenType: domain.OIDCTokenTypeJWT,
AssertAccessTokenRole: true,
AssertIDTokenRole: true,
AssertIDTokenUserinfo: true,
ClockSkew: 1 * time.Second,
AdditionalOrigins: []string{"additional.origin"},
AdditionalOrigins: database.StringArray{"additional.origin"},
ComplianceProblems: nil,
AllowedOrigins: []string{"https://redirect.to", "additional.origin"},
AllowedOrigins: database.StringArray{"https://redirect.to", "additional.origin"},
},
},
},
@@ -707,19 +706,19 @@ func Test_AppsPrepare(t *testing.T) {
"oidc-app-id",
domain.OIDCVersionV1,
"oidc-client-id",
pq.StringArray{"https://redirect.to/me"},
pq.Int32Array{int32(domain.OIDCResponseTypeIDTokenToken)},
pq.Int32Array{int32(domain.OIDCGrantTypeImplicit)},
database.StringArray{"https://redirect.to/me"},
database.EnumArray[domain.OIDCResponseType]{domain.OIDCResponseTypeIDTokenToken},
database.EnumArray[domain.OIDCGrantType]{domain.OIDCGrantTypeImplicit},
domain.OIDCApplicationTypeUserAgent,
domain.OIDCAuthMethodTypeNone,
pq.StringArray{"post.logout.ch"},
database.StringArray{"post.logout.ch"},
true,
domain.OIDCTokenTypeJWT,
true,
true,
true,
1 * time.Second,
pq.StringArray{"additional.origin"},
database.StringArray{"additional.origin"},
},
{
"api-app-id",
@@ -772,21 +771,21 @@ func Test_AppsPrepare(t *testing.T) {
OIDCConfig: &OIDCApp{
Version: domain.OIDCVersionV1,
ClientID: "oidc-client-id",
RedirectURIs: []string{"https://redirect.to/me"},
ResponseTypes: []domain.OIDCResponseType{domain.OIDCResponseTypeIDTokenToken},
GrantTypes: []domain.OIDCGrantType{domain.OIDCGrantTypeImplicit},
RedirectURIs: database.StringArray{"https://redirect.to/me"},
ResponseTypes: database.EnumArray[domain.OIDCResponseType]{domain.OIDCResponseTypeIDTokenToken},
GrantTypes: database.EnumArray[domain.OIDCGrantType]{domain.OIDCGrantTypeImplicit},
AppType: domain.OIDCApplicationTypeUserAgent,
AuthMethodType: domain.OIDCAuthMethodTypeNone,
PostLogoutRedirectURIs: []string{"post.logout.ch"},
PostLogoutRedirectURIs: database.StringArray{"post.logout.ch"},
IsDevMode: true,
AccessTokenType: domain.OIDCTokenTypeJWT,
AssertAccessTokenRole: true,
AssertIDTokenRole: true,
AssertIDTokenUserinfo: true,
ClockSkew: 1 * time.Second,
AdditionalOrigins: []string{"additional.origin"},
AdditionalOrigins: database.StringArray{"additional.origin"},
ComplianceProblems: nil,
AllowedOrigins: []string{"https://redirect.to", "additional.origin"},
AllowedOrigins: database.StringArray{"https://redirect.to", "additional.origin"},
},
},
{
@@ -993,19 +992,19 @@ func Test_AppPrepare(t *testing.T) {
"app-id",
domain.OIDCVersionV1,
"oidc-client-id",
pq.StringArray{"https://redirect.to/me"},
pq.Int32Array{int32(domain.OIDCResponseTypeIDTokenToken)},
pq.Int32Array{int32(domain.OIDCGrantTypeImplicit)},
database.StringArray{"https://redirect.to/me"},
database.EnumArray[domain.OIDCResponseType]{domain.OIDCResponseTypeIDTokenToken},
database.EnumArray[domain.OIDCGrantType]{domain.OIDCGrantTypeImplicit},
domain.OIDCApplicationTypeUserAgent,
domain.OIDCAuthMethodTypeNone,
pq.StringArray{"post.logout.ch"},
database.StringArray{"post.logout.ch"},
true,
domain.OIDCTokenTypeJWT,
true,
true,
true,
1 * time.Second,
pq.StringArray{"additional.origin"},
database.StringArray{"additional.origin"},
},
},
),
@@ -1022,21 +1021,21 @@ func Test_AppPrepare(t *testing.T) {
OIDCConfig: &OIDCApp{
Version: domain.OIDCVersionV1,
ClientID: "oidc-client-id",
RedirectURIs: []string{"https://redirect.to/me"},
ResponseTypes: []domain.OIDCResponseType{domain.OIDCResponseTypeIDTokenToken},
GrantTypes: []domain.OIDCGrantType{domain.OIDCGrantTypeImplicit},
RedirectURIs: database.StringArray{"https://redirect.to/me"},
ResponseTypes: database.EnumArray[domain.OIDCResponseType]{domain.OIDCResponseTypeIDTokenToken},
GrantTypes: database.EnumArray[domain.OIDCGrantType]{domain.OIDCGrantTypeImplicit},
AppType: domain.OIDCApplicationTypeUserAgent,
AuthMethodType: domain.OIDCAuthMethodTypeNone,
PostLogoutRedirectURIs: []string{"post.logout.ch"},
PostLogoutRedirectURIs: database.StringArray{"post.logout.ch"},
IsDevMode: true,
AccessTokenType: domain.OIDCTokenTypeJWT,
AssertAccessTokenRole: true,
AssertIDTokenRole: true,
AssertIDTokenUserinfo: true,
ClockSkew: 1 * time.Second,
AdditionalOrigins: []string{"additional.origin"},
AdditionalOrigins: database.StringArray{"additional.origin"},
ComplianceProblems: nil,
AllowedOrigins: []string{"https://redirect.to", "additional.origin"},
AllowedOrigins: database.StringArray{"https://redirect.to", "additional.origin"},
},
},
},
@@ -1065,19 +1064,19 @@ func Test_AppPrepare(t *testing.T) {
"app-id",
domain.OIDCVersionV1,
"oidc-client-id",
pq.StringArray{"https://redirect.to/me"},
pq.Int32Array{int32(domain.OIDCResponseTypeIDTokenToken)},
pq.Int32Array{int32(domain.OIDCGrantTypeImplicit)},
database.StringArray{"https://redirect.to/me"},
database.EnumArray[domain.OIDCResponseType]{domain.OIDCResponseTypeIDTokenToken},
database.EnumArray[domain.OIDCGrantType]{domain.OIDCGrantTypeImplicit},
domain.OIDCApplicationTypeUserAgent,
domain.OIDCAuthMethodTypeNone,
pq.StringArray{"post.logout.ch"},
database.StringArray{"post.logout.ch"},
false,
domain.OIDCTokenTypeJWT,
true,
true,
true,
1 * time.Second,
pq.StringArray{"additional.origin"},
database.StringArray{"additional.origin"},
},
},
),
@@ -1094,21 +1093,21 @@ func Test_AppPrepare(t *testing.T) {
OIDCConfig: &OIDCApp{
Version: domain.OIDCVersionV1,
ClientID: "oidc-client-id",
RedirectURIs: []string{"https://redirect.to/me"},
ResponseTypes: []domain.OIDCResponseType{domain.OIDCResponseTypeIDTokenToken},
GrantTypes: []domain.OIDCGrantType{domain.OIDCGrantTypeImplicit},
RedirectURIs: database.StringArray{"https://redirect.to/me"},
ResponseTypes: database.EnumArray[domain.OIDCResponseType]{domain.OIDCResponseTypeIDTokenToken},
GrantTypes: database.EnumArray[domain.OIDCGrantType]{domain.OIDCGrantTypeImplicit},
AppType: domain.OIDCApplicationTypeUserAgent,
AuthMethodType: domain.OIDCAuthMethodTypeNone,
PostLogoutRedirectURIs: []string{"post.logout.ch"},
PostLogoutRedirectURIs: database.StringArray{"post.logout.ch"},
IsDevMode: false,
AccessTokenType: domain.OIDCTokenTypeJWT,
AssertAccessTokenRole: true,
AssertIDTokenRole: true,
AssertIDTokenUserinfo: true,
ClockSkew: 1 * time.Second,
AdditionalOrigins: []string{"additional.origin"},
AdditionalOrigins: database.StringArray{"additional.origin"},
ComplianceProblems: nil,
AllowedOrigins: []string{"https://redirect.to", "additional.origin"},
AllowedOrigins: database.StringArray{"https://redirect.to", "additional.origin"},
},
},
},
@@ -1137,19 +1136,19 @@ func Test_AppPrepare(t *testing.T) {
"app-id",
domain.OIDCVersionV1,
"oidc-client-id",
pq.StringArray{"https://redirect.to/me"},
pq.Int32Array{int32(domain.OIDCResponseTypeIDTokenToken)},
pq.Int32Array{int32(domain.OIDCGrantTypeImplicit)},
database.StringArray{"https://redirect.to/me"},
database.EnumArray[domain.OIDCResponseType]{domain.OIDCResponseTypeIDTokenToken},
database.EnumArray[domain.OIDCGrantType]{domain.OIDCGrantTypeImplicit},
domain.OIDCApplicationTypeUserAgent,
domain.OIDCAuthMethodTypeNone,
pq.StringArray{"post.logout.ch"},
database.StringArray{"post.logout.ch"},
true,
domain.OIDCTokenTypeJWT,
false,
true,
true,
1 * time.Second,
pq.StringArray{"additional.origin"},
database.StringArray{"additional.origin"},
},
},
),
@@ -1166,21 +1165,21 @@ func Test_AppPrepare(t *testing.T) {
OIDCConfig: &OIDCApp{
Version: domain.OIDCVersionV1,
ClientID: "oidc-client-id",
RedirectURIs: []string{"https://redirect.to/me"},
ResponseTypes: []domain.OIDCResponseType{domain.OIDCResponseTypeIDTokenToken},
GrantTypes: []domain.OIDCGrantType{domain.OIDCGrantTypeImplicit},
RedirectURIs: database.StringArray{"https://redirect.to/me"},
ResponseTypes: database.EnumArray[domain.OIDCResponseType]{domain.OIDCResponseTypeIDTokenToken},
GrantTypes: database.EnumArray[domain.OIDCGrantType]{domain.OIDCGrantTypeImplicit},
AppType: domain.OIDCApplicationTypeUserAgent,
AuthMethodType: domain.OIDCAuthMethodTypeNone,
PostLogoutRedirectURIs: []string{"post.logout.ch"},
PostLogoutRedirectURIs: database.StringArray{"post.logout.ch"},
IsDevMode: true,
AccessTokenType: domain.OIDCTokenTypeJWT,
AssertAccessTokenRole: false,
AssertIDTokenRole: true,
AssertIDTokenUserinfo: true,
ClockSkew: 1 * time.Second,
AdditionalOrigins: []string{"additional.origin"},
AdditionalOrigins: database.StringArray{"additional.origin"},
ComplianceProblems: nil,
AllowedOrigins: []string{"https://redirect.to", "additional.origin"},
AllowedOrigins: database.StringArray{"https://redirect.to", "additional.origin"},
},
},
},
@@ -1209,19 +1208,19 @@ func Test_AppPrepare(t *testing.T) {
"app-id",
domain.OIDCVersionV1,
"oidc-client-id",
pq.StringArray{"https://redirect.to/me"},
pq.Int32Array{int32(domain.OIDCResponseTypeIDTokenToken)},
pq.Int32Array{int32(domain.OIDCGrantTypeImplicit)},
database.StringArray{"https://redirect.to/me"},
database.EnumArray[domain.OIDCResponseType]{domain.OIDCResponseTypeIDTokenToken},
database.EnumArray[domain.OIDCGrantType]{domain.OIDCGrantTypeImplicit},
domain.OIDCApplicationTypeUserAgent,
domain.OIDCAuthMethodTypeNone,
pq.StringArray{"post.logout.ch"},
database.StringArray{"post.logout.ch"},
true,
domain.OIDCTokenTypeJWT,
true,
false,
true,
1 * time.Second,
pq.StringArray{"additional.origin"},
database.StringArray{"additional.origin"},
},
},
),
@@ -1238,21 +1237,21 @@ func Test_AppPrepare(t *testing.T) {
OIDCConfig: &OIDCApp{
Version: domain.OIDCVersionV1,
ClientID: "oidc-client-id",
RedirectURIs: []string{"https://redirect.to/me"},
ResponseTypes: []domain.OIDCResponseType{domain.OIDCResponseTypeIDTokenToken},
GrantTypes: []domain.OIDCGrantType{domain.OIDCGrantTypeImplicit},
RedirectURIs: database.StringArray{"https://redirect.to/me"},
ResponseTypes: database.EnumArray[domain.OIDCResponseType]{domain.OIDCResponseTypeIDTokenToken},
GrantTypes: database.EnumArray[domain.OIDCGrantType]{domain.OIDCGrantTypeImplicit},
AppType: domain.OIDCApplicationTypeUserAgent,
AuthMethodType: domain.OIDCAuthMethodTypeNone,
PostLogoutRedirectURIs: []string{"post.logout.ch"},
PostLogoutRedirectURIs: database.StringArray{"post.logout.ch"},
IsDevMode: true,
AccessTokenType: domain.OIDCTokenTypeJWT,
AssertAccessTokenRole: true,
AssertIDTokenRole: false,
AssertIDTokenUserinfo: true,
ClockSkew: 1 * time.Second,
AdditionalOrigins: []string{"additional.origin"},
AdditionalOrigins: database.StringArray{"additional.origin"},
ComplianceProblems: nil,
AllowedOrigins: []string{"https://redirect.to", "additional.origin"},
AllowedOrigins: database.StringArray{"https://redirect.to", "additional.origin"},
},
},
},
@@ -1281,19 +1280,19 @@ func Test_AppPrepare(t *testing.T) {
"app-id",
domain.OIDCVersionV1,
"oidc-client-id",
pq.StringArray{"https://redirect.to/me"},
pq.Int32Array{int32(domain.OIDCResponseTypeIDTokenToken)},
pq.Int32Array{int32(domain.OIDCGrantTypeImplicit)},
database.StringArray{"https://redirect.to/me"},
database.EnumArray[domain.OIDCResponseType]{domain.OIDCResponseTypeIDTokenToken},
database.EnumArray[domain.OIDCGrantType]{domain.OIDCGrantTypeImplicit},
domain.OIDCApplicationTypeUserAgent,
domain.OIDCAuthMethodTypeNone,
pq.StringArray{"post.logout.ch"},
database.StringArray{"post.logout.ch"},
true,
domain.OIDCTokenTypeJWT,
true,
true,
false,
1 * time.Second,
pq.StringArray{"additional.origin"},
database.StringArray{"additional.origin"},
},
},
),
@@ -1310,21 +1309,21 @@ func Test_AppPrepare(t *testing.T) {
OIDCConfig: &OIDCApp{
Version: domain.OIDCVersionV1,
ClientID: "oidc-client-id",
RedirectURIs: []string{"https://redirect.to/me"},
ResponseTypes: []domain.OIDCResponseType{domain.OIDCResponseTypeIDTokenToken},
GrantTypes: []domain.OIDCGrantType{domain.OIDCGrantTypeImplicit},
RedirectURIs: database.StringArray{"https://redirect.to/me"},
ResponseTypes: database.EnumArray[domain.OIDCResponseType]{domain.OIDCResponseTypeIDTokenToken},
GrantTypes: database.EnumArray[domain.OIDCGrantType]{domain.OIDCGrantTypeImplicit},
AppType: domain.OIDCApplicationTypeUserAgent,
AuthMethodType: domain.OIDCAuthMethodTypeNone,
PostLogoutRedirectURIs: []string{"post.logout.ch"},
PostLogoutRedirectURIs: database.StringArray{"post.logout.ch"},
IsDevMode: true,
AccessTokenType: domain.OIDCTokenTypeJWT,
AssertAccessTokenRole: true,
AssertIDTokenRole: true,
AssertIDTokenUserinfo: false,
ClockSkew: 1 * time.Second,
AdditionalOrigins: []string{"additional.origin"},
AdditionalOrigins: database.StringArray{"additional.origin"},
ComplianceProblems: nil,
AllowedOrigins: []string{"https://redirect.to", "additional.origin"},
AllowedOrigins: database.StringArray{"https://redirect.to", "additional.origin"},
},
},
},
@@ -1382,7 +1381,7 @@ func Test_AppIDsPrepare(t *testing.T) {
want: want{
sqlExpectations: mockQueries(
expectedAppIDsQuery,
[]string{"client_id", "client_id"},
database.StringArray{"client_id", "client_id"},
[][]driver.Value{
{
"app-id",
@@ -1399,7 +1398,7 @@ func Test_AppIDsPrepare(t *testing.T) {
want: want{
sqlExpectations: mockQueries(
expectedAppIDsQuery,
[]string{"client_id", "client_id"},
database.StringArray{"client_id", "client_id"},
[][]driver.Value{
{
nil,
@@ -1474,7 +1473,7 @@ func Test_ProjectIDByAppPrepare(t *testing.T) {
want: want{
sqlExpectations: mockQuery(
expectedProjectIDByAppQuery,
[]string{"project_id"},
database.StringArray{"project_id"},
[]driver.Value{"project-id"},
),
},
+1 -1
View File
@@ -194,7 +194,7 @@ func prepareLatestSequence() (sq.SelectBuilder, func(*sql.Row) (*LatestSequence,
return sq.Select(
CurrentSequenceColCurrentSequence.identifier(),
CurrentSequenceColTimestamp.identifier()).
From(currentSequencesTable.identifier() + " AS OF SYSTEM TIME '-1ms'").PlaceholderFormat(sq.Dollar),
From(currentSequencesTable.identifier()).PlaceholderFormat(sq.Dollar),
func(row *sql.Row) (*LatestSequence, error) {
seq := new(LatestSequence)
err := row.Scan(
+1 -4
View File
@@ -5,7 +5,6 @@ import (
"database/sql"
sq "github.com/Masterminds/squirrel"
"github.com/lib/pq"
"github.com/zitadel/zitadel/internal/api/authz"
@@ -117,7 +116,6 @@ func prepareInstanceMembersQuery() (sq.SelectBuilder, func(*sql.Rows) (*Members,
for rows.Next() {
member := new(Member)
roles := pq.StringArray{}
var (
preferredLoginName = sql.NullString{}
@@ -135,7 +133,7 @@ func prepareInstanceMembersQuery() (sq.SelectBuilder, func(*sql.Rows) (*Members,
&member.Sequence,
&member.ResourceOwner,
&member.UserID,
&roles,
&member.Roles,
&preferredLoginName,
&email,
&firstName,
@@ -151,7 +149,6 @@ func prepareInstanceMembersQuery() (sq.SelectBuilder, func(*sql.Rows) (*Members,
return nil, err
}
member.Roles = roles
member.PreferredLoginName = preferredLoginName.String
member.Email = email.String
member.FirstName = firstName.String
+20 -20
View File
@@ -8,7 +8,7 @@ import (
"regexp"
"testing"
"github.com/lib/pq"
"github.com/zitadel/zitadel/internal/database"
)
var (
@@ -20,18 +20,18 @@ var (
", members.user_id" +
", members.roles" +
", projections.login_names.login_name" +
", projections.users2_humans.email" +
", projections.users2_humans.first_name" +
", projections.users2_humans.last_name" +
", projections.users2_humans.display_name" +
", projections.users2_machines.name" +
", projections.users2_humans.avatar_key" +
", projections.users3_humans.email" +
", projections.users3_humans.first_name" +
", projections.users3_humans.last_name" +
", projections.users3_humans.display_name" +
", projections.users3_machines.name" +
", projections.users3_humans.avatar_key" +
", COUNT(*) OVER () " +
"FROM projections.instance_members as members " +
"LEFT JOIN projections.users2_humans " +
"ON members.user_id = projections.users2_humans.user_id " +
"LEFT JOIN projections.users2_machines " +
"ON members.user_id = projections.users2_machines.user_id " +
"FROM projections.instance_members2 AS members " +
"LEFT JOIN projections.users3_humans " +
"ON members.user_id = projections.users3_humans.user_id " +
"LEFT JOIN projections.users3_machines " +
"ON members.user_id = projections.users3_machines.user_id " +
"LEFT JOIN projections.login_names " +
"ON members.user_id = projections.login_names.user_id " +
"WHERE projections.login_names.is_primary = $1")
@@ -92,7 +92,7 @@ func Test_IAMMemberPrepares(t *testing.T) {
uint64(20211206),
"ro",
"user-id",
pq.StringArray{"role-1", "role-2"},
database.StringArray{"role-1", "role-2"},
"[email protected]",
"[email protected]",
"first-name",
@@ -115,7 +115,7 @@ func Test_IAMMemberPrepares(t *testing.T) {
Sequence: 20211206,
ResourceOwner: "ro",
UserID: "user-id",
Roles: []string{"role-1", "role-2"},
Roles: database.StringArray{"role-1", "role-2"},
PreferredLoginName: "[email protected]",
Email: "[email protected]",
FirstName: "first-name",
@@ -140,7 +140,7 @@ func Test_IAMMemberPrepares(t *testing.T) {
uint64(20211206),
"ro",
"user-id",
pq.StringArray{"role-1", "role-2"},
database.StringArray{"role-1", "role-2"},
"[email protected]",
nil,
nil,
@@ -163,7 +163,7 @@ func Test_IAMMemberPrepares(t *testing.T) {
Sequence: 20211206,
ResourceOwner: "ro",
UserID: "user-id",
Roles: []string{"role-1", "role-2"},
Roles: database.StringArray{"role-1", "role-2"},
PreferredLoginName: "[email protected]",
Email: "",
FirstName: "",
@@ -188,7 +188,7 @@ func Test_IAMMemberPrepares(t *testing.T) {
uint64(20211206),
"ro",
"user-id-1",
pq.StringArray{"role-1", "role-2"},
database.StringArray{"role-1", "role-2"},
"[email protected]",
"[email protected]",
"first-name",
@@ -203,7 +203,7 @@ func Test_IAMMemberPrepares(t *testing.T) {
uint64(20211206),
"ro",
"user-id-2",
pq.StringArray{"role-1", "role-2"},
database.StringArray{"role-1", "role-2"},
"[email protected]",
nil,
nil,
@@ -226,7 +226,7 @@ func Test_IAMMemberPrepares(t *testing.T) {
Sequence: 20211206,
ResourceOwner: "ro",
UserID: "user-id-1",
Roles: []string{"role-1", "role-2"},
Roles: database.StringArray{"role-1", "role-2"},
PreferredLoginName: "[email protected]",
Email: "[email protected]",
FirstName: "first-name",
@@ -240,7 +240,7 @@ func Test_IAMMemberPrepares(t *testing.T) {
Sequence: 20211206,
ResourceOwner: "ro",
UserID: "user-id-2",
Roles: []string{"role-1", "role-2"},
Roles: database.StringArray{"role-1", "role-2"},
PreferredLoginName: "[email protected]",
Email: "",
FirstName: "",
+4 -4
View File
@@ -7,9 +7,9 @@ import (
"time"
sq "github.com/Masterminds/squirrel"
"github.com/lib/pq"
"github.com/zitadel/zitadel/internal/api/authz"
"github.com/zitadel/zitadel/internal/database"
"github.com/zitadel/zitadel/internal/crypto"
"github.com/zitadel/zitadel/internal/domain"
@@ -42,7 +42,7 @@ type OIDCIDP struct {
ClientID string
ClientSecret *crypto.CryptoValue
Issuer string
Scopes []string
Scopes database.StringArray
DisplayNameMapping domain.OIDCMappingField
UsernameMapping domain.OIDCMappingField
AuthorizationEndpoint string
@@ -307,7 +307,7 @@ func prepareIDPByIDQuery() (sq.SelectBuilder, func(*sql.Row) (*IDP, error)) {
oidcClientID := sql.NullString{}
oidcClientSecret := new(crypto.CryptoValue)
oidcIssuer := sql.NullString{}
oidcScopes := pq.StringArray{}
oidcScopes := database.StringArray{}
oidcDisplayNameMapping := sql.NullInt32{}
oidcUsernameMapping := sql.NullInt32{}
oidcAuthorizationEndpoint := sql.NullString{}
@@ -419,7 +419,7 @@ func prepareIDPsQuery() (sq.SelectBuilder, func(*sql.Rows) (*IDPs, error)) {
oidcClientID := sql.NullString{}
oidcClientSecret := new(crypto.CryptoValue)
oidcIssuer := sql.NullString{}
oidcScopes := pq.StringArray{}
oidcScopes := database.StringArray{}
oidcDisplayNameMapping := sql.NullInt32{}
oidcUsernameMapping := sql.NullInt32{}
oidcAuthorizationEndpoint := sql.NullString{}
+5 -5
View File
@@ -12,12 +12,12 @@ import (
)
var (
loginPolicyIDPLinksQuery = regexp.QuoteMeta(`SELECT projections.idp_login_policy_links.idp_id,` +
` projections.idps.name,` +
` projections.idps.type,` +
loginPolicyIDPLinksQuery = regexp.QuoteMeta(`SELECT projections.idp_login_policy_links2.idp_id,` +
` projections.idps2.name,` +
` projections.idps2.type,` +
` COUNT(*) OVER ()` +
` FROM projections.idp_login_policy_links` +
` LEFT JOIN projections.idps ON projections.idp_login_policy_links.idp_id = projections.idps.id`)
` FROM projections.idp_login_policy_links2` +
` LEFT JOIN projections.idps2 ON projections.idp_login_policy_links2.idp_id = projections.idps2.id`)
loginPolicyIDPLinksCols = []string{
"idp_id",
"name",
+304 -305
View File
@@ -8,9 +8,8 @@ import (
"regexp"
"testing"
"github.com/lib/pq"
"github.com/zitadel/zitadel/internal/crypto"
"github.com/zitadel/zitadel/internal/database"
"github.com/zitadel/zitadel/internal/domain"
errs "github.com/zitadel/zitadel/internal/errors"
)
@@ -31,33 +30,33 @@ func Test_IDPPrepares(t *testing.T) {
prepare: prepareIDPByIDQuery,
want: want{
sqlExpectations: mockQuery(
regexp.QuoteMeta(`SELECT projections.idps.id,`+
` projections.idps.resource_owner,`+
` projections.idps.creation_date,`+
` projections.idps.change_date,`+
` projections.idps.sequence,`+
` projections.idps.state,`+
` projections.idps.name,`+
` projections.idps.styling_type,`+
` projections.idps.owner_type,`+
` projections.idps.auto_register,`+
` projections.idps_oidc_config.idp_id,`+
` projections.idps_oidc_config.client_id,`+
` projections.idps_oidc_config.client_secret,`+
` projections.idps_oidc_config.issuer,`+
` projections.idps_oidc_config.scopes,`+
` projections.idps_oidc_config.display_name_mapping,`+
` projections.idps_oidc_config.username_mapping,`+
` projections.idps_oidc_config.authorization_endpoint,`+
` projections.idps_oidc_config.token_endpoint,`+
` projections.idps_jwt_config.idp_id,`+
` projections.idps_jwt_config.issuer,`+
` projections.idps_jwt_config.keys_endpoint,`+
` projections.idps_jwt_config.header_name,`+
` projections.idps_jwt_config.endpoint`+
` FROM projections.idps`+
` LEFT JOIN projections.idps_oidc_config ON projections.idps.id = projections.idps_oidc_config.idp_id`+
` LEFT JOIN projections.idps_jwt_config ON projections.idps.id = projections.idps_jwt_config.idp_id`),
regexp.QuoteMeta(`SELECT projections.idps2.id,`+
` projections.idps2.resource_owner,`+
` projections.idps2.creation_date,`+
` projections.idps2.change_date,`+
` projections.idps2.sequence,`+
` projections.idps2.state,`+
` projections.idps2.name,`+
` projections.idps2.styling_type,`+
` projections.idps2.owner_type,`+
` projections.idps2.auto_register,`+
` projections.idps2_oidc_config.idp_id,`+
` projections.idps2_oidc_config.client_id,`+
` projections.idps2_oidc_config.client_secret,`+
` projections.idps2_oidc_config.issuer,`+
` projections.idps2_oidc_config.scopes,`+
` projections.idps2_oidc_config.display_name_mapping,`+
` projections.idps2_oidc_config.username_mapping,`+
` projections.idps2_oidc_config.authorization_endpoint,`+
` projections.idps2_oidc_config.token_endpoint,`+
` projections.idps2_jwt_config.idp_id,`+
` projections.idps2_jwt_config.issuer,`+
` projections.idps2_jwt_config.keys_endpoint,`+
` projections.idps2_jwt_config.header_name,`+
` projections.idps2_jwt_config.endpoint`+
` FROM projections.idps2`+
` LEFT JOIN projections.idps2_oidc_config ON projections.idps2.id = projections.idps2_oidc_config.idp_id`+
` LEFT JOIN projections.idps2_jwt_config ON projections.idps2.id = projections.idps2_jwt_config.idp_id`),
nil,
nil,
),
@@ -75,33 +74,33 @@ func Test_IDPPrepares(t *testing.T) {
prepare: prepareIDPByIDQuery,
want: want{
sqlExpectations: mockQuery(
regexp.QuoteMeta(`SELECT projections.idps.id,`+
` projections.idps.resource_owner,`+
` projections.idps.creation_date,`+
` projections.idps.change_date,`+
` projections.idps.sequence,`+
` projections.idps.state,`+
` projections.idps.name,`+
` projections.idps.styling_type,`+
` projections.idps.owner_type,`+
` projections.idps.auto_register,`+
` projections.idps_oidc_config.idp_id,`+
` projections.idps_oidc_config.client_id,`+
` projections.idps_oidc_config.client_secret,`+
` projections.idps_oidc_config.issuer,`+
` projections.idps_oidc_config.scopes,`+
` projections.idps_oidc_config.display_name_mapping,`+
` projections.idps_oidc_config.username_mapping,`+
` projections.idps_oidc_config.authorization_endpoint,`+
` projections.idps_oidc_config.token_endpoint,`+
` projections.idps_jwt_config.idp_id,`+
` projections.idps_jwt_config.issuer,`+
` projections.idps_jwt_config.keys_endpoint,`+
` projections.idps_jwt_config.header_name,`+
` projections.idps_jwt_config.endpoint`+
` FROM projections.idps`+
` LEFT JOIN projections.idps_oidc_config ON projections.idps.id = projections.idps_oidc_config.idp_id`+
` LEFT JOIN projections.idps_jwt_config ON projections.idps.id = projections.idps_jwt_config.idp_id`),
regexp.QuoteMeta(`SELECT projections.idps2.id,`+
` projections.idps2.resource_owner,`+
` projections.idps2.creation_date,`+
` projections.idps2.change_date,`+
` projections.idps2.sequence,`+
` projections.idps2.state,`+
` projections.idps2.name,`+
` projections.idps2.styling_type,`+
` projections.idps2.owner_type,`+
` projections.idps2.auto_register,`+
` projections.idps2_oidc_config.idp_id,`+
` projections.idps2_oidc_config.client_id,`+
` projections.idps2_oidc_config.client_secret,`+
` projections.idps2_oidc_config.issuer,`+
` projections.idps2_oidc_config.scopes,`+
` projections.idps2_oidc_config.display_name_mapping,`+
` projections.idps2_oidc_config.username_mapping,`+
` projections.idps2_oidc_config.authorization_endpoint,`+
` projections.idps2_oidc_config.token_endpoint,`+
` projections.idps2_jwt_config.idp_id,`+
` projections.idps2_jwt_config.issuer,`+
` projections.idps2_jwt_config.keys_endpoint,`+
` projections.idps2_jwt_config.header_name,`+
` projections.idps2_jwt_config.endpoint`+
` FROM projections.idps2`+
` LEFT JOIN projections.idps2_oidc_config ON projections.idps2.id = projections.idps2_oidc_config.idp_id`+
` LEFT JOIN projections.idps2_jwt_config ON projections.idps2.id = projections.idps2_jwt_config.idp_id`),
[]string{
"id",
"resource_owner",
@@ -146,7 +145,7 @@ func Test_IDPPrepares(t *testing.T) {
"oidc-client-id",
nil,
"oidc-issuer",
pq.StringArray{"scope"},
database.StringArray{"scope"},
domain.OIDCMappingFieldEmail,
domain.OIDCMappingFieldPreferredLoginName,
"auth.endpoint.ch",
@@ -176,7 +175,7 @@ func Test_IDPPrepares(t *testing.T) {
ClientID: "oidc-client-id",
ClientSecret: &crypto.CryptoValue{},
Issuer: "oidc-issuer",
Scopes: []string{"scope"},
Scopes: database.StringArray{"scope"},
DisplayNameMapping: domain.OIDCMappingFieldEmail,
UsernameMapping: domain.OIDCMappingFieldPreferredLoginName,
AuthorizationEndpoint: "auth.endpoint.ch",
@@ -189,33 +188,33 @@ func Test_IDPPrepares(t *testing.T) {
prepare: prepareIDPByIDQuery,
want: want{
sqlExpectations: mockQuery(
regexp.QuoteMeta(`SELECT projections.idps.id,`+
` projections.idps.resource_owner,`+
` projections.idps.creation_date,`+
` projections.idps.change_date,`+
` projections.idps.sequence,`+
` projections.idps.state,`+
` projections.idps.name,`+
` projections.idps.styling_type,`+
` projections.idps.owner_type,`+
` projections.idps.auto_register,`+
` projections.idps_oidc_config.idp_id,`+
` projections.idps_oidc_config.client_id,`+
` projections.idps_oidc_config.client_secret,`+
` projections.idps_oidc_config.issuer,`+
` projections.idps_oidc_config.scopes,`+
` projections.idps_oidc_config.display_name_mapping,`+
` projections.idps_oidc_config.username_mapping,`+
` projections.idps_oidc_config.authorization_endpoint,`+
` projections.idps_oidc_config.token_endpoint,`+
` projections.idps_jwt_config.idp_id,`+
` projections.idps_jwt_config.issuer,`+
` projections.idps_jwt_config.keys_endpoint,`+
` projections.idps_jwt_config.header_name,`+
` projections.idps_jwt_config.endpoint`+
` FROM projections.idps`+
` LEFT JOIN projections.idps_oidc_config ON projections.idps.id = projections.idps_oidc_config.idp_id`+
` LEFT JOIN projections.idps_jwt_config ON projections.idps.id = projections.idps_jwt_config.idp_id`),
regexp.QuoteMeta(`SELECT projections.idps2.id,`+
` projections.idps2.resource_owner,`+
` projections.idps2.creation_date,`+
` projections.idps2.change_date,`+
` projections.idps2.sequence,`+
` projections.idps2.state,`+
` projections.idps2.name,`+
` projections.idps2.styling_type,`+
` projections.idps2.owner_type,`+
` projections.idps2.auto_register,`+
` projections.idps2_oidc_config.idp_id,`+
` projections.idps2_oidc_config.client_id,`+
` projections.idps2_oidc_config.client_secret,`+
` projections.idps2_oidc_config.issuer,`+
` projections.idps2_oidc_config.scopes,`+
` projections.idps2_oidc_config.display_name_mapping,`+
` projections.idps2_oidc_config.username_mapping,`+
` projections.idps2_oidc_config.authorization_endpoint,`+
` projections.idps2_oidc_config.token_endpoint,`+
` projections.idps2_jwt_config.idp_id,`+
` projections.idps2_jwt_config.issuer,`+
` projections.idps2_jwt_config.keys_endpoint,`+
` projections.idps2_jwt_config.header_name,`+
` projections.idps2_jwt_config.endpoint`+
` FROM projections.idps2`+
` LEFT JOIN projections.idps2_oidc_config ON projections.idps2.id = projections.idps2_oidc_config.idp_id`+
` LEFT JOIN projections.idps2_jwt_config ON projections.idps2.id = projections.idps2_jwt_config.idp_id`),
[]string{
"id",
"resource_owner",
@@ -299,33 +298,33 @@ func Test_IDPPrepares(t *testing.T) {
prepare: prepareIDPByIDQuery,
want: want{
sqlExpectations: mockQuery(
regexp.QuoteMeta(`SELECT projections.idps.id,`+
` projections.idps.resource_owner,`+
` projections.idps.creation_date,`+
` projections.idps.change_date,`+
` projections.idps.sequence,`+
` projections.idps.state,`+
` projections.idps.name,`+
` projections.idps.styling_type,`+
` projections.idps.owner_type,`+
` projections.idps.auto_register,`+
` projections.idps_oidc_config.idp_id,`+
` projections.idps_oidc_config.client_id,`+
` projections.idps_oidc_config.client_secret,`+
` projections.idps_oidc_config.issuer,`+
` projections.idps_oidc_config.scopes,`+
` projections.idps_oidc_config.display_name_mapping,`+
` projections.idps_oidc_config.username_mapping,`+
` projections.idps_oidc_config.authorization_endpoint,`+
` projections.idps_oidc_config.token_endpoint,`+
` projections.idps_jwt_config.idp_id,`+
` projections.idps_jwt_config.issuer,`+
` projections.idps_jwt_config.keys_endpoint,`+
` projections.idps_jwt_config.header_name,`+
` projections.idps_jwt_config.endpoint`+
` FROM projections.idps`+
` LEFT JOIN projections.idps_oidc_config ON projections.idps.id = projections.idps_oidc_config.idp_id`+
` LEFT JOIN projections.idps_jwt_config ON projections.idps.id = projections.idps_jwt_config.idp_id`),
regexp.QuoteMeta(`SELECT projections.idps2.id,`+
` projections.idps2.resource_owner,`+
` projections.idps2.creation_date,`+
` projections.idps2.change_date,`+
` projections.idps2.sequence,`+
` projections.idps2.state,`+
` projections.idps2.name,`+
` projections.idps2.styling_type,`+
` projections.idps2.owner_type,`+
` projections.idps2.auto_register,`+
` projections.idps2_oidc_config.idp_id,`+
` projections.idps2_oidc_config.client_id,`+
` projections.idps2_oidc_config.client_secret,`+
` projections.idps2_oidc_config.issuer,`+
` projections.idps2_oidc_config.scopes,`+
` projections.idps2_oidc_config.display_name_mapping,`+
` projections.idps2_oidc_config.username_mapping,`+
` projections.idps2_oidc_config.authorization_endpoint,`+
` projections.idps2_oidc_config.token_endpoint,`+
` projections.idps2_jwt_config.idp_id,`+
` projections.idps2_jwt_config.issuer,`+
` projections.idps2_jwt_config.keys_endpoint,`+
` projections.idps2_jwt_config.header_name,`+
` projections.idps2_jwt_config.endpoint`+
` FROM projections.idps2`+
` LEFT JOIN projections.idps2_oidc_config ON projections.idps2.id = projections.idps2_oidc_config.idp_id`+
` LEFT JOIN projections.idps2_jwt_config ON projections.idps2.id = projections.idps2_jwt_config.idp_id`),
[]string{
"id",
"resource_owner",
@@ -402,33 +401,33 @@ func Test_IDPPrepares(t *testing.T) {
prepare: prepareIDPByIDQuery,
want: want{
sqlExpectations: mockQueryErr(
regexp.QuoteMeta(`SELECT projections.idps.id,`+
` projections.idps.resource_owner,`+
` projections.idps.creation_date,`+
` projections.idps.change_date,`+
` projections.idps.sequence,`+
` projections.idps.state,`+
` projections.idps.name,`+
` projections.idps.styling_type,`+
` projections.idps.owner_type,`+
` projections.idps.auto_register,`+
` projections.idps_oidc_config.idp_id,`+
` projections.idps_oidc_config.client_id,`+
` projections.idps_oidc_config.client_secret,`+
` projections.idps_oidc_config.issuer,`+
` projections.idps_oidc_config.scopes,`+
` projections.idps_oidc_config.display_name_mapping,`+
` projections.idps_oidc_config.username_mapping,`+
` projections.idps_oidc_config.authorization_endpoint,`+
` projections.idps_oidc_config.token_endpoint,`+
` projections.idps_jwt_config.idp_id,`+
` projections.idps_jwt_config.issuer,`+
` projections.idps_jwt_config.keys_endpoint,`+
` projections.idps_jwt_config.header_name,`+
` projections.idps_jwt_config.endpoint`+
` FROM projections.idps`+
` LEFT JOIN projections.idps_oidc_config ON projections.idps.id = projections.idps_oidc_config.idp_id`+
` LEFT JOIN projections.idps_jwt_config ON projections.idps.id = projections.idps_jwt_config.idp_id`),
regexp.QuoteMeta(`SELECT projections.idps2.id,`+
` projections.idps2.resource_owner,`+
` projections.idps2.creation_date,`+
` projections.idps2.change_date,`+
` projections.idps2.sequence,`+
` projections.idps2.state,`+
` projections.idps2.name,`+
` projections.idps2.styling_type,`+
` projections.idps2.owner_type,`+
` projections.idps2.auto_register,`+
` projections.idps2_oidc_config.idp_id,`+
` projections.idps2_oidc_config.client_id,`+
` projections.idps2_oidc_config.client_secret,`+
` projections.idps2_oidc_config.issuer,`+
` projections.idps2_oidc_config.scopes,`+
` projections.idps2_oidc_config.display_name_mapping,`+
` projections.idps2_oidc_config.username_mapping,`+
` projections.idps2_oidc_config.authorization_endpoint,`+
` projections.idps2_oidc_config.token_endpoint,`+
` projections.idps2_jwt_config.idp_id,`+
` projections.idps2_jwt_config.issuer,`+
` projections.idps2_jwt_config.keys_endpoint,`+
` projections.idps2_jwt_config.header_name,`+
` projections.idps2_jwt_config.endpoint`+
` FROM projections.idps2`+
` LEFT JOIN projections.idps2_oidc_config ON projections.idps2.id = projections.idps2_oidc_config.idp_id`+
` LEFT JOIN projections.idps2_jwt_config ON projections.idps2.id = projections.idps2_jwt_config.idp_id`),
sql.ErrConnDone,
),
err: func(err error) (error, bool) {
@@ -445,34 +444,34 @@ func Test_IDPPrepares(t *testing.T) {
prepare: prepareIDPsQuery,
want: want{
sqlExpectations: mockQueries(
regexp.QuoteMeta(`SELECT projections.idps.id,`+
` projections.idps.resource_owner,`+
` projections.idps.creation_date,`+
` projections.idps.change_date,`+
` projections.idps.sequence,`+
` projections.idps.state,`+
` projections.idps.name,`+
` projections.idps.styling_type,`+
` projections.idps.owner_type,`+
` projections.idps.auto_register,`+
` projections.idps_oidc_config.idp_id,`+
` projections.idps_oidc_config.client_id,`+
` projections.idps_oidc_config.client_secret,`+
` projections.idps_oidc_config.issuer,`+
` projections.idps_oidc_config.scopes,`+
` projections.idps_oidc_config.display_name_mapping,`+
` projections.idps_oidc_config.username_mapping,`+
` projections.idps_oidc_config.authorization_endpoint,`+
` projections.idps_oidc_config.token_endpoint,`+
` projections.idps_jwt_config.idp_id,`+
` projections.idps_jwt_config.issuer,`+
` projections.idps_jwt_config.keys_endpoint,`+
` projections.idps_jwt_config.header_name,`+
` projections.idps_jwt_config.endpoint,`+
regexp.QuoteMeta(`SELECT projections.idps2.id,`+
` projections.idps2.resource_owner,`+
` projections.idps2.creation_date,`+
` projections.idps2.change_date,`+
` projections.idps2.sequence,`+
` projections.idps2.state,`+
` projections.idps2.name,`+
` projections.idps2.styling_type,`+
` projections.idps2.owner_type,`+
` projections.idps2.auto_register,`+
` projections.idps2_oidc_config.idp_id,`+
` projections.idps2_oidc_config.client_id,`+
` projections.idps2_oidc_config.client_secret,`+
` projections.idps2_oidc_config.issuer,`+
` projections.idps2_oidc_config.scopes,`+
` projections.idps2_oidc_config.display_name_mapping,`+
` projections.idps2_oidc_config.username_mapping,`+
` projections.idps2_oidc_config.authorization_endpoint,`+
` projections.idps2_oidc_config.token_endpoint,`+
` projections.idps2_jwt_config.idp_id,`+
` projections.idps2_jwt_config.issuer,`+
` projections.idps2_jwt_config.keys_endpoint,`+
` projections.idps2_jwt_config.header_name,`+
` projections.idps2_jwt_config.endpoint,`+
` COUNT(*) OVER ()`+
` FROM projections.idps`+
` LEFT JOIN projections.idps_oidc_config ON projections.idps.id = projections.idps_oidc_config.idp_id`+
` LEFT JOIN projections.idps_jwt_config ON projections.idps.id = projections.idps_jwt_config.idp_id`),
` FROM projections.idps2`+
` LEFT JOIN projections.idps2_oidc_config ON projections.idps2.id = projections.idps2_oidc_config.idp_id`+
` LEFT JOIN projections.idps2_jwt_config ON projections.idps2.id = projections.idps2_jwt_config.idp_id`),
nil,
nil,
),
@@ -490,34 +489,34 @@ func Test_IDPPrepares(t *testing.T) {
prepare: prepareIDPsQuery,
want: want{
sqlExpectations: mockQueries(
regexp.QuoteMeta(`SELECT projections.idps.id,`+
` projections.idps.resource_owner,`+
` projections.idps.creation_date,`+
` projections.idps.change_date,`+
` projections.idps.sequence,`+
` projections.idps.state,`+
` projections.idps.name,`+
` projections.idps.styling_type,`+
` projections.idps.owner_type,`+
` projections.idps.auto_register,`+
` projections.idps_oidc_config.idp_id,`+
` projections.idps_oidc_config.client_id,`+
` projections.idps_oidc_config.client_secret,`+
` projections.idps_oidc_config.issuer,`+
` projections.idps_oidc_config.scopes,`+
` projections.idps_oidc_config.display_name_mapping,`+
` projections.idps_oidc_config.username_mapping,`+
` projections.idps_oidc_config.authorization_endpoint,`+
` projections.idps_oidc_config.token_endpoint,`+
` projections.idps_jwt_config.idp_id,`+
` projections.idps_jwt_config.issuer,`+
` projections.idps_jwt_config.keys_endpoint,`+
` projections.idps_jwt_config.header_name,`+
` projections.idps_jwt_config.endpoint,`+
regexp.QuoteMeta(`SELECT projections.idps2.id,`+
` projections.idps2.resource_owner,`+
` projections.idps2.creation_date,`+
` projections.idps2.change_date,`+
` projections.idps2.sequence,`+
` projections.idps2.state,`+
` projections.idps2.name,`+
` projections.idps2.styling_type,`+
` projections.idps2.owner_type,`+
` projections.idps2.auto_register,`+
` projections.idps2_oidc_config.idp_id,`+
` projections.idps2_oidc_config.client_id,`+
` projections.idps2_oidc_config.client_secret,`+
` projections.idps2_oidc_config.issuer,`+
` projections.idps2_oidc_config.scopes,`+
` projections.idps2_oidc_config.display_name_mapping,`+
` projections.idps2_oidc_config.username_mapping,`+
` projections.idps2_oidc_config.authorization_endpoint,`+
` projections.idps2_oidc_config.token_endpoint,`+
` projections.idps2_jwt_config.idp_id,`+
` projections.idps2_jwt_config.issuer,`+
` projections.idps2_jwt_config.keys_endpoint,`+
` projections.idps2_jwt_config.header_name,`+
` projections.idps2_jwt_config.endpoint,`+
` COUNT(*) OVER ()`+
` FROM projections.idps`+
` LEFT JOIN projections.idps_oidc_config ON projections.idps.id = projections.idps_oidc_config.idp_id`+
` LEFT JOIN projections.idps_jwt_config ON projections.idps.id = projections.idps_jwt_config.idp_id`),
` FROM projections.idps2`+
` LEFT JOIN projections.idps2_oidc_config ON projections.idps2.id = projections.idps2_oidc_config.idp_id`+
` LEFT JOIN projections.idps2_jwt_config ON projections.idps2.id = projections.idps2_jwt_config.idp_id`),
[]string{
"id",
"resource_owner",
@@ -564,7 +563,7 @@ func Test_IDPPrepares(t *testing.T) {
"oidc-client-id",
nil,
"oidc-issuer",
pq.StringArray{"scope"},
database.StringArray{"scope"},
domain.OIDCMappingFieldEmail,
domain.OIDCMappingFieldPreferredLoginName,
"auth.endpoint.ch",
@@ -600,7 +599,7 @@ func Test_IDPPrepares(t *testing.T) {
ClientID: "oidc-client-id",
ClientSecret: &crypto.CryptoValue{},
Issuer: "oidc-issuer",
Scopes: []string{"scope"},
Scopes: database.StringArray{"scope"},
DisplayNameMapping: domain.OIDCMappingFieldEmail,
UsernameMapping: domain.OIDCMappingFieldPreferredLoginName,
AuthorizationEndpoint: "auth.endpoint.ch",
@@ -615,34 +614,34 @@ func Test_IDPPrepares(t *testing.T) {
prepare: prepareIDPsQuery,
want: want{
sqlExpectations: mockQueries(
regexp.QuoteMeta(`SELECT projections.idps.id,`+
` projections.idps.resource_owner,`+
` projections.idps.creation_date,`+
` projections.idps.change_date,`+
` projections.idps.sequence,`+
` projections.idps.state,`+
` projections.idps.name,`+
` projections.idps.styling_type,`+
` projections.idps.owner_type,`+
` projections.idps.auto_register,`+
` projections.idps_oidc_config.idp_id,`+
` projections.idps_oidc_config.client_id,`+
` projections.idps_oidc_config.client_secret,`+
` projections.idps_oidc_config.issuer,`+
` projections.idps_oidc_config.scopes,`+
` projections.idps_oidc_config.display_name_mapping,`+
` projections.idps_oidc_config.username_mapping,`+
` projections.idps_oidc_config.authorization_endpoint,`+
` projections.idps_oidc_config.token_endpoint,`+
` projections.idps_jwt_config.idp_id,`+
` projections.idps_jwt_config.issuer,`+
` projections.idps_jwt_config.keys_endpoint,`+
` projections.idps_jwt_config.header_name,`+
` projections.idps_jwt_config.endpoint,`+
regexp.QuoteMeta(`SELECT projections.idps2.id,`+
` projections.idps2.resource_owner,`+
` projections.idps2.creation_date,`+
` projections.idps2.change_date,`+
` projections.idps2.sequence,`+
` projections.idps2.state,`+
` projections.idps2.name,`+
` projections.idps2.styling_type,`+
` projections.idps2.owner_type,`+
` projections.idps2.auto_register,`+
` projections.idps2_oidc_config.idp_id,`+
` projections.idps2_oidc_config.client_id,`+
` projections.idps2_oidc_config.client_secret,`+
` projections.idps2_oidc_config.issuer,`+
` projections.idps2_oidc_config.scopes,`+
` projections.idps2_oidc_config.display_name_mapping,`+
` projections.idps2_oidc_config.username_mapping,`+
` projections.idps2_oidc_config.authorization_endpoint,`+
` projections.idps2_oidc_config.token_endpoint,`+
` projections.idps2_jwt_config.idp_id,`+
` projections.idps2_jwt_config.issuer,`+
` projections.idps2_jwt_config.keys_endpoint,`+
` projections.idps2_jwt_config.header_name,`+
` projections.idps2_jwt_config.endpoint,`+
` COUNT(*) OVER ()`+
` FROM projections.idps`+
` LEFT JOIN projections.idps_oidc_config ON projections.idps.id = projections.idps_oidc_config.idp_id`+
` LEFT JOIN projections.idps_jwt_config ON projections.idps.id = projections.idps_jwt_config.idp_id`),
` FROM projections.idps2`+
` LEFT JOIN projections.idps2_oidc_config ON projections.idps2.id = projections.idps2_oidc_config.idp_id`+
` LEFT JOIN projections.idps2_jwt_config ON projections.idps2.id = projections.idps2_jwt_config.idp_id`),
[]string{
"id",
"resource_owner",
@@ -735,34 +734,34 @@ func Test_IDPPrepares(t *testing.T) {
prepare: prepareIDPsQuery,
want: want{
sqlExpectations: mockQueries(
regexp.QuoteMeta(`SELECT projections.idps.id,`+
` projections.idps.resource_owner,`+
` projections.idps.creation_date,`+
` projections.idps.change_date,`+
` projections.idps.sequence,`+
` projections.idps.state,`+
` projections.idps.name,`+
` projections.idps.styling_type,`+
` projections.idps.owner_type,`+
` projections.idps.auto_register,`+
` projections.idps_oidc_config.idp_id,`+
` projections.idps_oidc_config.client_id,`+
` projections.idps_oidc_config.client_secret,`+
` projections.idps_oidc_config.issuer,`+
` projections.idps_oidc_config.scopes,`+
` projections.idps_oidc_config.display_name_mapping,`+
` projections.idps_oidc_config.username_mapping,`+
` projections.idps_oidc_config.authorization_endpoint,`+
` projections.idps_oidc_config.token_endpoint,`+
` projections.idps_jwt_config.idp_id,`+
` projections.idps_jwt_config.issuer,`+
` projections.idps_jwt_config.keys_endpoint,`+
` projections.idps_jwt_config.header_name,`+
` projections.idps_jwt_config.endpoint,`+
regexp.QuoteMeta(`SELECT projections.idps2.id,`+
` projections.idps2.resource_owner,`+
` projections.idps2.creation_date,`+
` projections.idps2.change_date,`+
` projections.idps2.sequence,`+
` projections.idps2.state,`+
` projections.idps2.name,`+
` projections.idps2.styling_type,`+
` projections.idps2.owner_type,`+
` projections.idps2.auto_register,`+
` projections.idps2_oidc_config.idp_id,`+
` projections.idps2_oidc_config.client_id,`+
` projections.idps2_oidc_config.client_secret,`+
` projections.idps2_oidc_config.issuer,`+
` projections.idps2_oidc_config.scopes,`+
` projections.idps2_oidc_config.display_name_mapping,`+
` projections.idps2_oidc_config.username_mapping,`+
` projections.idps2_oidc_config.authorization_endpoint,`+
` projections.idps2_oidc_config.token_endpoint,`+
` projections.idps2_jwt_config.idp_id,`+
` projections.idps2_jwt_config.issuer,`+
` projections.idps2_jwt_config.keys_endpoint,`+
` projections.idps2_jwt_config.header_name,`+
` projections.idps2_jwt_config.endpoint,`+
` COUNT(*) OVER ()`+
` FROM projections.idps`+
` LEFT JOIN projections.idps_oidc_config ON projections.idps.id = projections.idps_oidc_config.idp_id`+
` LEFT JOIN projections.idps_jwt_config ON projections.idps.id = projections.idps_jwt_config.idp_id`),
` FROM projections.idps2`+
` LEFT JOIN projections.idps2_oidc_config ON projections.idps2.id = projections.idps2_oidc_config.idp_id`+
` LEFT JOIN projections.idps2_jwt_config ON projections.idps2.id = projections.idps2_jwt_config.idp_id`),
[]string{
"id",
"resource_owner",
@@ -848,34 +847,34 @@ func Test_IDPPrepares(t *testing.T) {
prepare: prepareIDPsQuery,
want: want{
sqlExpectations: mockQueries(
regexp.QuoteMeta(`SELECT projections.idps.id,`+
` projections.idps.resource_owner,`+
` projections.idps.creation_date,`+
` projections.idps.change_date,`+
` projections.idps.sequence,`+
` projections.idps.state,`+
` projections.idps.name,`+
` projections.idps.styling_type,`+
` projections.idps.owner_type,`+
` projections.idps.auto_register,`+
` projections.idps_oidc_config.idp_id,`+
` projections.idps_oidc_config.client_id,`+
` projections.idps_oidc_config.client_secret,`+
` projections.idps_oidc_config.issuer,`+
` projections.idps_oidc_config.scopes,`+
` projections.idps_oidc_config.display_name_mapping,`+
` projections.idps_oidc_config.username_mapping,`+
` projections.idps_oidc_config.authorization_endpoint,`+
` projections.idps_oidc_config.token_endpoint,`+
` projections.idps_jwt_config.idp_id,`+
` projections.idps_jwt_config.issuer,`+
` projections.idps_jwt_config.keys_endpoint,`+
` projections.idps_jwt_config.header_name,`+
` projections.idps_jwt_config.endpoint,`+
regexp.QuoteMeta(`SELECT projections.idps2.id,`+
` projections.idps2.resource_owner,`+
` projections.idps2.creation_date,`+
` projections.idps2.change_date,`+
` projections.idps2.sequence,`+
` projections.idps2.state,`+
` projections.idps2.name,`+
` projections.idps2.styling_type,`+
` projections.idps2.owner_type,`+
` projections.idps2.auto_register,`+
` projections.idps2_oidc_config.idp_id,`+
` projections.idps2_oidc_config.client_id,`+
` projections.idps2_oidc_config.client_secret,`+
` projections.idps2_oidc_config.issuer,`+
` projections.idps2_oidc_config.scopes,`+
` projections.idps2_oidc_config.display_name_mapping,`+
` projections.idps2_oidc_config.username_mapping,`+
` projections.idps2_oidc_config.authorization_endpoint,`+
` projections.idps2_oidc_config.token_endpoint,`+
` projections.idps2_jwt_config.idp_id,`+
` projections.idps2_jwt_config.issuer,`+
` projections.idps2_jwt_config.keys_endpoint,`+
` projections.idps2_jwt_config.header_name,`+
` projections.idps2_jwt_config.endpoint,`+
` COUNT(*) OVER ()`+
` FROM projections.idps`+
` LEFT JOIN projections.idps_oidc_config ON projections.idps.id = projections.idps_oidc_config.idp_id`+
` LEFT JOIN projections.idps_jwt_config ON projections.idps.id = projections.idps_jwt_config.idp_id`),
` FROM projections.idps2`+
` LEFT JOIN projections.idps2_oidc_config ON projections.idps2.id = projections.idps2_oidc_config.idp_id`+
` LEFT JOIN projections.idps2_jwt_config ON projections.idps2.id = projections.idps2_jwt_config.idp_id`),
[]string{
"id",
"resource_owner",
@@ -949,7 +948,7 @@ func Test_IDPPrepares(t *testing.T) {
"oidc-client-id",
nil,
"oidc-issuer",
pq.StringArray{"scope"},
database.StringArray{"scope"},
domain.OIDCMappingFieldEmail,
domain.OIDCMappingFieldPreferredLoginName,
"auth.endpoint.ch",
@@ -1025,7 +1024,7 @@ func Test_IDPPrepares(t *testing.T) {
ClientID: "oidc-client-id",
ClientSecret: &crypto.CryptoValue{},
Issuer: "oidc-issuer",
Scopes: []string{"scope"},
Scopes: database.StringArray{"scope"},
DisplayNameMapping: domain.OIDCMappingFieldEmail,
UsernameMapping: domain.OIDCMappingFieldPreferredLoginName,
AuthorizationEndpoint: "auth.endpoint.ch",
@@ -1059,34 +1058,34 @@ func Test_IDPPrepares(t *testing.T) {
prepare: prepareIDPsQuery,
want: want{
sqlExpectations: mockQueryErr(
regexp.QuoteMeta(`SELECT projections.idps.id,`+
` projections.idps.resource_owner,`+
` projections.idps.creation_date,`+
` projections.idps.change_date,`+
` projections.idps.sequence,`+
` projections.idps.state,`+
` projections.idps.name,`+
` projections.idps.styling_type,`+
` projections.idps.owner_type,`+
` projections.idps.auto_register,`+
` projections.idps_oidc_config.idp_id,`+
` projections.idps_oidc_config.client_id,`+
` projections.idps_oidc_config.client_secret,`+
` projections.idps_oidc_config.issuer,`+
` projections.idps_oidc_config.scopes,`+
` projections.idps_oidc_config.display_name_mapping,`+
` projections.idps_oidc_config.username_mapping,`+
` projections.idps_oidc_config.authorization_endpoint,`+
` projections.idps_oidc_config.token_endpoint,`+
` projections.idps_jwt_config.idp_id,`+
` projections.idps_jwt_config.issuer,`+
` projections.idps_jwt_config.keys_endpoint,`+
` projections.idps_jwt_config.header_name,`+
` projections.idps_jwt_config.endpoint,`+
regexp.QuoteMeta(`SELECT projections.idps2.id,`+
` projections.idps2.resource_owner,`+
` projections.idps2.creation_date,`+
` projections.idps2.change_date,`+
` projections.idps2.sequence,`+
` projections.idps2.state,`+
` projections.idps2.name,`+
` projections.idps2.styling_type,`+
` projections.idps2.owner_type,`+
` projections.idps2.auto_register,`+
` projections.idps2_oidc_config.idp_id,`+
` projections.idps2_oidc_config.client_id,`+
` projections.idps2_oidc_config.client_secret,`+
` projections.idps2_oidc_config.issuer,`+
` projections.idps2_oidc_config.scopes,`+
` projections.idps2_oidc_config.display_name_mapping,`+
` projections.idps2_oidc_config.username_mapping,`+
` projections.idps2_oidc_config.authorization_endpoint,`+
` projections.idps2_oidc_config.token_endpoint,`+
` projections.idps2_jwt_config.idp_id,`+
` projections.idps2_jwt_config.issuer,`+
` projections.idps2_jwt_config.keys_endpoint,`+
` projections.idps2_jwt_config.header_name,`+
` projections.idps2_jwt_config.endpoint,`+
` COUNT(*) OVER ()`+
` FROM projections.idps`+
` LEFT JOIN projections.idps_oidc_config ON projections.idps.id = projections.idps_oidc_config.idp_id`+
` LEFT JOIN projections.idps_jwt_config ON projections.idps.id = projections.idps_jwt_config.idp_id`),
` FROM projections.idps2`+
` LEFT JOIN projections.idps2_oidc_config ON projections.idps2.id = projections.idps2_oidc_config.idp_id`+
` LEFT JOIN projections.idps2_jwt_config ON projections.idps2.id = projections.idps2_jwt_config.idp_id`),
sql.ErrConnDone,
),
err: func(err error) (error, bool) {
+9 -9
View File
@@ -12,16 +12,16 @@ import (
)
var (
idpUserLinksQuery = regexp.QuoteMeta(`SELECT projections.idp_user_links.idp_id,` +
` projections.idp_user_links.user_id,` +
` projections.idps.name,` +
` projections.idp_user_links.external_user_id,` +
` projections.idp_user_links.display_name,` +
` projections.idps.type,` +
` projections.idp_user_links.resource_owner,` +
idpUserLinksQuery = regexp.QuoteMeta(`SELECT projections.idp_user_links2.idp_id,` +
` projections.idp_user_links2.user_id,` +
` projections.idps2.name,` +
` projections.idp_user_links2.external_user_id,` +
` projections.idp_user_links2.display_name,` +
` projections.idps2.type,` +
` projections.idp_user_links2.resource_owner,` +
` COUNT(*) OVER ()` +
` FROM projections.idp_user_links` +
` LEFT JOIN projections.idps ON projections.idp_user_links.idp_id = projections.idps.id`)
` FROM projections.idp_user_links2` +
` LEFT JOIN projections.idps2 ON projections.idp_user_links2.idp_id = projections.idps2.id`)
idpUserLinksCols = []string{
"idp_id",
"user_id",
+66 -66
View File
@@ -31,18 +31,18 @@ func Test_KeyPrepares(t *testing.T) {
prepare: preparePublicKeysQuery,
want: want{
sqlExpectations: mockQueries(
regexp.QuoteMeta(`SELECT projections.keys.id,`+
` projections.keys.creation_date,`+
` projections.keys.change_date,`+
` projections.keys.sequence,`+
` projections.keys.resource_owner,`+
` projections.keys.algorithm,`+
` projections.keys.use,`+
` projections.keys_public.expiry,`+
` projections.keys_public.key,`+
regexp.QuoteMeta(`SELECT projections.keys2.id,`+
` projections.keys2.creation_date,`+
` projections.keys2.change_date,`+
` projections.keys2.sequence,`+
` projections.keys2.resource_owner,`+
` projections.keys2.algorithm,`+
` projections.keys2.use,`+
` projections.keys2_public.expiry,`+
` projections.keys2_public.key,`+
` COUNT(*) OVER ()`+
` FROM projections.keys`+
` LEFT JOIN projections.keys_public ON projections.keys.id = projections.keys_public.id`),
` FROM projections.keys2`+
` LEFT JOIN projections.keys2_public ON projections.keys2.id = projections.keys2_public.id`),
nil,
nil,
),
@@ -60,18 +60,18 @@ func Test_KeyPrepares(t *testing.T) {
prepare: preparePublicKeysQuery,
want: want{
sqlExpectations: mockQueries(
regexp.QuoteMeta(`SELECT projections.keys.id,`+
` projections.keys.creation_date,`+
` projections.keys.change_date,`+
` projections.keys.sequence,`+
` projections.keys.resource_owner,`+
` projections.keys.algorithm,`+
` projections.keys.use,`+
` projections.keys_public.expiry,`+
` projections.keys_public.key,`+
regexp.QuoteMeta(`SELECT projections.keys2.id,`+
` projections.keys2.creation_date,`+
` projections.keys2.change_date,`+
` projections.keys2.sequence,`+
` projections.keys2.resource_owner,`+
` projections.keys2.algorithm,`+
` projections.keys2.use,`+
` projections.keys2_public.expiry,`+
` projections.keys2_public.key,`+
` COUNT(*) OVER ()`+
` FROM projections.keys`+
` LEFT JOIN projections.keys_public ON projections.keys.id = projections.keys_public.id`),
` FROM projections.keys2`+
` LEFT JOIN projections.keys2_public ON projections.keys2.id = projections.keys2_public.id`),
[]string{
"id",
"creation_date",
@@ -128,18 +128,18 @@ func Test_KeyPrepares(t *testing.T) {
prepare: preparePublicKeysQuery,
want: want{
sqlExpectations: mockQueryErr(
regexp.QuoteMeta(`SELECT projections.keys.id,`+
` projections.keys.creation_date,`+
` projections.keys.change_date,`+
` projections.keys.sequence,`+
` projections.keys.resource_owner,`+
` projections.keys.algorithm,`+
` projections.keys.use,`+
` projections.keys_public.expiry,`+
` projections.keys_public.key,`+
regexp.QuoteMeta(`SELECT projections.keys2.id,`+
` projections.keys2.creation_date,`+
` projections.keys2.change_date,`+
` projections.keys2.sequence,`+
` projections.keys2.resource_owner,`+
` projections.keys2.algorithm,`+
` projections.keys2.use,`+
` projections.keys2_public.expiry,`+
` projections.keys2_public.key,`+
` COUNT(*) OVER ()`+
` FROM projections.keys`+
` LEFT JOIN projections.keys_public ON projections.keys.id = projections.keys_public.id`),
` FROM projections.keys2`+
` LEFT JOIN projections.keys2_public ON projections.keys2.id = projections.keys2_public.id`),
sql.ErrConnDone,
),
err: func(err error) (error, bool) {
@@ -156,18 +156,18 @@ func Test_KeyPrepares(t *testing.T) {
prepare: preparePrivateKeysQuery,
want: want{
sqlExpectations: mockQueries(
regexp.QuoteMeta(`SELECT projections.keys.id,`+
` projections.keys.creation_date,`+
` projections.keys.change_date,`+
` projections.keys.sequence,`+
` projections.keys.resource_owner,`+
` projections.keys.algorithm,`+
` projections.keys.use,`+
` projections.keys_private.expiry,`+
` projections.keys_private.key,`+
regexp.QuoteMeta(`SELECT projections.keys2.id,`+
` projections.keys2.creation_date,`+
` projections.keys2.change_date,`+
` projections.keys2.sequence,`+
` projections.keys2.resource_owner,`+
` projections.keys2.algorithm,`+
` projections.keys2.use,`+
` projections.keys2_private.expiry,`+
` projections.keys2_private.key,`+
` COUNT(*) OVER ()`+
` FROM projections.keys`+
` LEFT JOIN projections.keys_private ON projections.keys.id = projections.keys_private.id`),
` FROM projections.keys2`+
` LEFT JOIN projections.keys2_private ON projections.keys2.id = projections.keys2_private.id`),
nil,
nil,
),
@@ -185,18 +185,18 @@ func Test_KeyPrepares(t *testing.T) {
prepare: preparePrivateKeysQuery,
want: want{
sqlExpectations: mockQueries(
regexp.QuoteMeta(`SELECT projections.keys.id,`+
` projections.keys.creation_date,`+
` projections.keys.change_date,`+
` projections.keys.sequence,`+
` projections.keys.resource_owner,`+
` projections.keys.algorithm,`+
` projections.keys.use,`+
` projections.keys_private.expiry,`+
` projections.keys_private.key,`+
regexp.QuoteMeta(`SELECT projections.keys2.id,`+
` projections.keys2.creation_date,`+
` projections.keys2.change_date,`+
` projections.keys2.sequence,`+
` projections.keys2.resource_owner,`+
` projections.keys2.algorithm,`+
` projections.keys2.use,`+
` projections.keys2_private.expiry,`+
` projections.keys2_private.key,`+
` COUNT(*) OVER ()`+
` FROM projections.keys`+
` LEFT JOIN projections.keys_private ON projections.keys.id = projections.keys_private.id`),
` FROM projections.keys2`+
` LEFT JOIN projections.keys2_private ON projections.keys2.id = projections.keys2_private.id`),
[]string{
"id",
"creation_date",
@@ -255,18 +255,18 @@ func Test_KeyPrepares(t *testing.T) {
prepare: preparePrivateKeysQuery,
want: want{
sqlExpectations: mockQueryErr(
regexp.QuoteMeta(`SELECT projections.keys.id,`+
` projections.keys.creation_date,`+
` projections.keys.change_date,`+
` projections.keys.sequence,`+
` projections.keys.resource_owner,`+
` projections.keys.algorithm,`+
` projections.keys.use,`+
` projections.keys_private.expiry,`+
` projections.keys_private.key,`+
regexp.QuoteMeta(`SELECT projections.keys2.id,`+
` projections.keys2.creation_date,`+
` projections.keys2.change_date,`+
` projections.keys2.sequence,`+
` projections.keys2.resource_owner,`+
` projections.keys2.algorithm,`+
` projections.keys2.use,`+
` projections.keys2_private.expiry,`+
` projections.keys2_private.key,`+
` COUNT(*) OVER ()`+
` FROM projections.keys`+
` LEFT JOIN projections.keys_private ON projections.keys.id = projections.keys_private.id`),
` FROM projections.keys2`+
` LEFT JOIN projections.keys2_private ON projections.keys2.id = projections.keys2_private.id`),
sql.ErrConnDone,
),
err: func(err error) (error, bool) {
+11 -31
View File
@@ -7,9 +7,9 @@ import (
"time"
sq "github.com/Masterminds/squirrel"
"github.com/lib/pq"
"github.com/zitadel/zitadel/internal/api/authz"
"github.com/zitadel/zitadel/internal/database"
"github.com/zitadel/zitadel/internal/domain"
"github.com/zitadel/zitadel/internal/errors"
"github.com/zitadel/zitadel/internal/query/projection"
@@ -24,8 +24,8 @@ type LoginPolicy struct {
AllowUsernamePassword bool
AllowExternalIDPs bool
ForceMFA bool
SecondFactors []domain.SecondFactorType
MultiFactors []domain.MultiFactorType
SecondFactors database.EnumArray[domain.SecondFactorType]
MultiFactors database.EnumArray[domain.MultiFactorType]
PasswordlessType domain.PasswordlessType
IsDefault bool
HidePasswordReset bool
@@ -41,12 +41,12 @@ type LoginPolicy struct {
type SecondFactors struct {
SearchResponse
Factors []domain.SecondFactorType
Factors database.EnumArray[domain.SecondFactorType]
}
type MultiFactors struct {
SearchResponse
Factors []domain.MultiFactorType
Factors database.EnumArray[domain.MultiFactorType]
}
var (
@@ -320,8 +320,6 @@ func prepareLoginPolicyQuery() (sq.SelectBuilder, func(*sql.Rows) (*LoginPolicy,
PlaceholderFormat(sq.Dollar),
func(rows *sql.Rows) (*LoginPolicy, error) {
p := new(LoginPolicy)
secondFactors := pq.Int32Array{}
multiFactors := pq.Int32Array{}
defaultRedirectURI := sql.NullString{}
links := make([]*IDPLoginPolicyLink, 0)
for rows.Next() {
@@ -339,8 +337,8 @@ func prepareLoginPolicyQuery() (sq.SelectBuilder, func(*sql.Rows) (*LoginPolicy,
&p.AllowUsernamePassword,
&p.AllowExternalIDPs,
&p.ForceMFA,
&secondFactors,
&multiFactors,
&p.SecondFactors,
&p.MultiFactors,
&p.PasswordlessType,
&p.IsDefault,
&p.HidePasswordReset,
@@ -376,14 +374,6 @@ func prepareLoginPolicyQuery() (sq.SelectBuilder, func(*sql.Rows) (*LoginPolicy,
return nil, errors.ThrowNotFound(nil, "QUERY-QsUBJ", "Errors.LoginPolicy.NotFound")
}
p.DefaultRedirectURI = defaultRedirectURI.String
p.MultiFactors = make([]domain.MultiFactorType, len(multiFactors))
for i, mfa := range multiFactors {
p.MultiFactors[i] = domain.MultiFactorType(mfa)
}
p.SecondFactors = make([]domain.SecondFactorType, len(secondFactors))
for i, mfa := range secondFactors {
p.SecondFactors[i] = domain.SecondFactorType(mfa)
}
p.IDPLinks = links
return p, nil
}
@@ -395,9 +385,8 @@ func prepareLoginPolicy2FAsQuery() (sq.SelectBuilder, func(*sql.Row) (*SecondFac
).From(loginPolicyTable.identifier()).PlaceholderFormat(sq.Dollar),
func(row *sql.Row) (*SecondFactors, error) {
p := new(SecondFactors)
secondFactors := pq.Int32Array{}
err := row.Scan(
&secondFactors,
&p.Factors,
)
if err != nil {
if errs.Is(err, sql.ErrNoRows) {
@@ -406,11 +395,7 @@ func prepareLoginPolicy2FAsQuery() (sq.SelectBuilder, func(*sql.Row) (*SecondFac
return nil, errors.ThrowInternal(err, "QUERY-Mr6H3", "Errors.Internal")
}
p.Factors = make([]domain.SecondFactorType, len(secondFactors))
p.Count = uint64(len(secondFactors))
for i, mfa := range secondFactors {
p.Factors[i] = domain.SecondFactorType(mfa)
}
p.Count = uint64(len(p.Factors))
return p, nil
}
}
@@ -421,9 +406,8 @@ func prepareLoginPolicyMFAsQuery() (sq.SelectBuilder, func(*sql.Row) (*MultiFact
).From(loginPolicyTable.identifier()).PlaceholderFormat(sq.Dollar),
func(row *sql.Row) (*MultiFactors, error) {
p := new(MultiFactors)
multiFactors := pq.Int32Array{}
err := row.Scan(
&multiFactors,
&p.Factors,
)
if err != nil {
if errs.Is(err, sql.ErrNoRows) {
@@ -432,11 +416,7 @@ func prepareLoginPolicyMFAsQuery() (sq.SelectBuilder, func(*sql.Row) (*MultiFact
return nil, errors.ThrowInternal(err, "QUERY-Mr6H3", "Errors.Internal")
}
p.Factors = make([]domain.MultiFactorType, len(multiFactors))
p.Count = uint64(len(multiFactors))
for i, mfa := range multiFactors {
p.Factors[i] = domain.MultiFactorType(mfa)
}
p.Count = uint64(len(p.Factors))
return p, nil
}
}
+34 -36
View File
@@ -9,8 +9,7 @@ import (
"testing"
"time"
"github.com/lib/pq"
"github.com/zitadel/zitadel/internal/database"
"github.com/zitadel/zitadel/internal/domain"
errs "github.com/zitadel/zitadel/internal/errors"
)
@@ -51,14 +50,14 @@ func Test_LoginPolicyPrepares(t *testing.T) {
` projections.login_policies.mfa_init_skip_lifetime,`+
` projections.login_policies.second_factor_check_lifetime,`+
` projections.login_policies.multi_factor_check_lifetime,`+
` projections.idp_login_policy_links.idp_id,`+
` projections.idps.name,`+
` projections.idps.type`+
` projections.idp_login_policy_links2.idp_id,`+
` projections.idps2.name,`+
` projections.idps2.type`+
` FROM projections.login_policies`+
` LEFT JOIN projections.idp_login_policy_links ON `+
` projections.login_policies.aggregate_id = projections.idp_login_policy_links.aggregate_id`+
` LEFT JOIN projections.idps ON`+
` projections.idp_login_policy_links.idp_id = projections.idps.id`),
` LEFT JOIN projections.idp_login_policy_links2 ON `+
` projections.login_policies.aggregate_id = projections.idp_login_policy_links2.aggregate_id`+
` LEFT JOIN projections.idps2 ON`+
` projections.idp_login_policy_links2.idp_id = projections.idps2.id`),
nil,
nil,
),
@@ -96,14 +95,14 @@ func Test_LoginPolicyPrepares(t *testing.T) {
` projections.login_policies.mfa_init_skip_lifetime,`+
` projections.login_policies.second_factor_check_lifetime,`+
` projections.login_policies.multi_factor_check_lifetime,`+
` projections.idp_login_policy_links.idp_id,`+
` projections.idps.name,`+
` projections.idps.type`+
` projections.idp_login_policy_links2.idp_id,`+
` projections.idps2.name,`+
` projections.idps2.type`+
` FROM projections.login_policies`+
` LEFT JOIN projections.idp_login_policy_links ON `+
` projections.login_policies.aggregate_id = projections.idp_login_policy_links.aggregate_id`+
` LEFT JOIN projections.idps ON`+
` projections.idp_login_policy_links.idp_id = projections.idps.id`),
` LEFT JOIN projections.idp_login_policy_links2 ON `+
` projections.login_policies.aggregate_id = projections.idp_login_policy_links2.aggregate_id`+
` LEFT JOIN projections.idps2 ON`+
` projections.idp_login_policy_links2.idp_id = projections.idps2.id`),
[]string{
"aggregate_id",
"creation_date",
@@ -138,8 +137,8 @@ func Test_LoginPolicyPrepares(t *testing.T) {
true,
true,
true,
pq.Int32Array{int32(domain.SecondFactorTypeOTP)},
pq.Int32Array{int32(domain.MultiFactorTypeU2FWithPIN)},
database.EnumArray[domain.SecondFactorType]{domain.SecondFactorTypeOTP},
database.EnumArray[domain.MultiFactorType]{domain.MultiFactorTypeU2FWithPIN},
domain.PasswordlessTypeAllowed,
true,
true,
@@ -165,8 +164,8 @@ func Test_LoginPolicyPrepares(t *testing.T) {
AllowUsernamePassword: true,
AllowExternalIDPs: true,
ForceMFA: true,
SecondFactors: []domain.SecondFactorType{domain.SecondFactorTypeOTP},
MultiFactors: []domain.MultiFactorType{domain.MultiFactorTypeU2FWithPIN},
SecondFactors: database.EnumArray[domain.SecondFactorType]{domain.SecondFactorTypeOTP},
MultiFactors: database.EnumArray[domain.MultiFactorType]{domain.MultiFactorTypeU2FWithPIN},
PasswordlessType: domain.PasswordlessTypeAllowed,
IsDefault: true,
HidePasswordReset: true,
@@ -211,14 +210,14 @@ func Test_LoginPolicyPrepares(t *testing.T) {
` projections.login_policies.mfa_init_skip_lifetime,`+
` projections.login_policies.second_factor_check_lifetime,`+
` projections.login_policies.multi_factor_check_lifetime,`+
` projections.idp_login_policy_links.idp_id,`+
` projections.idps.name,`+
` projections.idps.type`+
` projections.idp_login_policy_links2.idp_id,`+
` projections.idps2.name,`+
` projections.idps2.type`+
` FROM projections.login_policies`+
` LEFT JOIN projections.idp_login_policy_links ON `+
` projections.login_policies.aggregate_id = projections.idp_login_policy_links.aggregate_id`+
` LEFT JOIN projections.idps ON`+
` projections.idp_login_policy_links.idp_id = projections.idps.id`),
` LEFT JOIN projections.idp_login_policy_links2 ON `+
` projections.login_policies.aggregate_id = projections.idp_login_policy_links2.aggregate_id`+
` LEFT JOIN projections.idps2 ON`+
` projections.idp_login_policy_links2.idp_id = projections.idps2.id`),
sql.ErrConnDone,
),
err: func(err error) (error, bool) {
@@ -262,7 +261,7 @@ func Test_LoginPolicyPrepares(t *testing.T) {
"second_factors",
},
[]driver.Value{
pq.Int32Array{int32(domain.SecondFactorTypeOTP)},
database.EnumArray[domain.SecondFactorType]{domain.SecondFactorTypeOTP},
},
),
},
@@ -270,7 +269,7 @@ func Test_LoginPolicyPrepares(t *testing.T) {
SearchResponse: SearchResponse{
Count: 1,
},
Factors: []domain.SecondFactorType{domain.SecondFactorTypeOTP},
Factors: database.EnumArray[domain.SecondFactorType]{domain.SecondFactorTypeOTP},
},
},
{
@@ -284,11 +283,11 @@ func Test_LoginPolicyPrepares(t *testing.T) {
"second_factors",
},
[]driver.Value{
pq.Int32Array{},
database.EnumArray[domain.SecondFactorType]{},
},
),
},
object: &SecondFactors{Factors: []domain.SecondFactorType{}},
object: &SecondFactors{Factors: database.EnumArray[domain.SecondFactorType]{}},
},
{
name: "prepareLoginPolicy2FAsQuery sql err",
@@ -308,7 +307,6 @@ func Test_LoginPolicyPrepares(t *testing.T) {
},
object: nil,
},
{
name: "prepareLoginPolicyMFAsQuery no result",
prepare: prepareLoginPolicyMFAsQuery,
@@ -341,7 +339,7 @@ func Test_LoginPolicyPrepares(t *testing.T) {
"multi_factors",
},
[]driver.Value{
pq.Int32Array{int32(domain.MultiFactorTypeU2FWithPIN)},
database.EnumArray[domain.MultiFactorType]{domain.MultiFactorTypeU2FWithPIN},
},
),
},
@@ -349,7 +347,7 @@ func Test_LoginPolicyPrepares(t *testing.T) {
SearchResponse: SearchResponse{
Count: 1,
},
Factors: []domain.MultiFactorType{domain.MultiFactorTypeU2FWithPIN},
Factors: database.EnumArray[domain.MultiFactorType]{domain.MultiFactorTypeU2FWithPIN},
},
},
{
@@ -363,11 +361,11 @@ func Test_LoginPolicyPrepares(t *testing.T) {
"multi_factors",
},
[]driver.Value{
pq.Int32Array{},
database.EnumArray[domain.MultiFactorType]{},
},
),
},
object: &MultiFactors{Factors: []domain.MultiFactorType{}},
object: &MultiFactors{Factors: database.EnumArray[domain.MultiFactorType]{}},
},
{
name: "prepareLoginPolicyMFAsQuery sql err",
+2 -1
View File
@@ -3,6 +3,7 @@ package query
import (
"time"
"github.com/zitadel/zitadel/internal/database"
"github.com/zitadel/zitadel/internal/query/projection"
sq "github.com/Masterminds/squirrel"
@@ -52,7 +53,7 @@ type Member struct {
ResourceOwner string
UserID string
Roles []string
Roles database.StringArray
PreferredLoginName string
Email string
FirstName string
+1 -4
View File
@@ -9,7 +9,6 @@ import (
"github.com/zitadel/zitadel/internal/query/projection"
sq "github.com/Masterminds/squirrel"
"github.com/lib/pq"
)
var (
@@ -120,7 +119,6 @@ func prepareOrgMembersQuery() (sq.SelectBuilder, func(*sql.Rows) (*Members, erro
member := new(Member)
var (
roles = pq.StringArray{}
preferredLoginName = sql.NullString{}
email = sql.NullString{}
firstName = sql.NullString{}
@@ -136,7 +134,7 @@ func prepareOrgMembersQuery() (sq.SelectBuilder, func(*sql.Rows) (*Members, erro
&member.Sequence,
&member.ResourceOwner,
&member.UserID,
&roles,
&member.Roles,
&preferredLoginName,
&email,
&firstName,
@@ -152,7 +150,6 @@ func prepareOrgMembersQuery() (sq.SelectBuilder, func(*sql.Rows) (*Members, erro
return nil, err
}
member.Roles = roles
member.PreferredLoginName = preferredLoginName.String
member.Email = email.String
member.FirstName = firstName.String
+20 -20
View File
@@ -8,7 +8,7 @@ import (
"regexp"
"testing"
"github.com/lib/pq"
"github.com/zitadel/zitadel/internal/database"
)
var (
@@ -20,18 +20,18 @@ var (
", members.user_id" +
", members.roles" +
", projections.login_names.login_name" +
", projections.users2_humans.email" +
", projections.users2_humans.first_name" +
", projections.users2_humans.last_name" +
", projections.users2_humans.display_name" +
", projections.users2_machines.name" +
", projections.users2_humans.avatar_key" +
", projections.users3_humans.email" +
", projections.users3_humans.first_name" +
", projections.users3_humans.last_name" +
", projections.users3_humans.display_name" +
", projections.users3_machines.name" +
", projections.users3_humans.avatar_key" +
", COUNT(*) OVER () " +
"FROM projections.org_members as members " +
"LEFT JOIN projections.users2_humans " +
"ON members.user_id = projections.users2_humans.user_id " +
"LEFT JOIN projections.users2_machines " +
"ON members.user_id = projections.users2_machines.user_id " +
"FROM projections.org_members2 AS members " +
"LEFT JOIN projections.users3_humans " +
"ON members.user_id = projections.users3_humans.user_id " +
"LEFT JOIN projections.users3_machines " +
"ON members.user_id = projections.users3_machines.user_id " +
"LEFT JOIN projections.login_names " +
"ON members.user_id = projections.login_names.user_id " +
"WHERE projections.login_names.is_primary = $1")
@@ -92,7 +92,7 @@ func Test_OrgMemberPrepares(t *testing.T) {
uint64(20211206),
"ro",
"user-id",
pq.StringArray{"role-1", "role-2"},
database.StringArray{"role-1", "role-2"},
"[email protected]",
"[email protected]",
"first-name",
@@ -115,7 +115,7 @@ func Test_OrgMemberPrepares(t *testing.T) {
Sequence: 20211206,
ResourceOwner: "ro",
UserID: "user-id",
Roles: []string{"role-1", "role-2"},
Roles: database.StringArray{"role-1", "role-2"},
PreferredLoginName: "[email protected]",
Email: "[email protected]",
FirstName: "first-name",
@@ -140,7 +140,7 @@ func Test_OrgMemberPrepares(t *testing.T) {
uint64(20211206),
"ro",
"user-id",
pq.StringArray{"role-1", "role-2"},
database.StringArray{"role-1", "role-2"},
"[email protected]",
nil,
nil,
@@ -163,7 +163,7 @@ func Test_OrgMemberPrepares(t *testing.T) {
Sequence: 20211206,
ResourceOwner: "ro",
UserID: "user-id",
Roles: []string{"role-1", "role-2"},
Roles: database.StringArray{"role-1", "role-2"},
PreferredLoginName: "[email protected]",
Email: "",
FirstName: "",
@@ -188,7 +188,7 @@ func Test_OrgMemberPrepares(t *testing.T) {
uint64(20211206),
"ro",
"user-id-1",
pq.StringArray{"role-1", "role-2"},
database.StringArray{"role-1", "role-2"},
"[email protected]",
"[email protected]",
"first-name",
@@ -203,7 +203,7 @@ func Test_OrgMemberPrepares(t *testing.T) {
uint64(20211206),
"ro",
"user-id-2",
pq.StringArray{"role-1", "role-2"},
database.StringArray{"role-1", "role-2"},
"[email protected]",
nil,
nil,
@@ -226,7 +226,7 @@ func Test_OrgMemberPrepares(t *testing.T) {
Sequence: 20211206,
ResourceOwner: "ro",
UserID: "user-id-1",
Roles: []string{"role-1", "role-2"},
Roles: database.StringArray{"role-1", "role-2"},
PreferredLoginName: "[email protected]",
Email: "[email protected]",
FirstName: "first-name",
@@ -240,7 +240,7 @@ func Test_OrgMemberPrepares(t *testing.T) {
Sequence: 20211206,
ResourceOwner: "ro",
UserID: "user-id-2",
Roles: []string{"role-1", "role-2"},
Roles: database.StringArray{"role-1", "role-2"},
PreferredLoginName: "[email protected]",
Email: "",
FirstName: "",
+2 -2
View File
@@ -7,9 +7,9 @@ import (
"time"
sq "github.com/Masterminds/squirrel"
"github.com/lib/pq"
"github.com/zitadel/zitadel/internal/api/authz"
"github.com/zitadel/zitadel/internal/database"
"github.com/zitadel/zitadel/internal/query/projection"
"github.com/zitadel/zitadel/internal/domain"
@@ -92,7 +92,7 @@ type ProjectGrant struct {
ProjectName string
GrantedOrgID string
OrgName string
GrantedRoleKeys pq.StringArray
GrantedRoleKeys database.StringArray
ResourceOwnerName string
}
+1 -4
View File
@@ -5,7 +5,6 @@ import (
"database/sql"
sq "github.com/Masterminds/squirrel"
"github.com/lib/pq"
"github.com/zitadel/zitadel/internal/api/authz"
@@ -133,7 +132,6 @@ func prepareProjectGrantMembersQuery() (sq.SelectBuilder, func(*sql.Rows) (*Memb
for rows.Next() {
member := new(Member)
roles := pq.StringArray{}
var (
preferredLoginName = sql.NullString{}
@@ -151,7 +149,7 @@ func prepareProjectGrantMembersQuery() (sq.SelectBuilder, func(*sql.Rows) (*Memb
&member.Sequence,
&member.ResourceOwner,
&member.UserID,
&roles,
&member.Roles,
&preferredLoginName,
&email,
&firstName,
@@ -167,7 +165,6 @@ func prepareProjectGrantMembersQuery() (sq.SelectBuilder, func(*sql.Rows) (*Memb
return nil, err
}
member.Roles = roles
member.PreferredLoginName = preferredLoginName.String
member.Email = email.String
member.FirstName = firstName.String
+22 -22
View File
@@ -8,7 +8,7 @@ import (
"regexp"
"testing"
"github.com/lib/pq"
"github.com/zitadel/zitadel/internal/database"
)
var (
@@ -20,22 +20,22 @@ var (
", members.user_id" +
", members.roles" +
", projections.login_names.login_name" +
", projections.users2_humans.email" +
", projections.users2_humans.first_name" +
", projections.users2_humans.last_name" +
", projections.users2_humans.display_name" +
", projections.users2_machines.name" +
", projections.users2_humans.avatar_key" +
", projections.users3_humans.email" +
", projections.users3_humans.first_name" +
", projections.users3_humans.last_name" +
", projections.users3_humans.display_name" +
", projections.users3_machines.name" +
", projections.users3_humans.avatar_key" +
", COUNT(*) OVER () " +
"FROM projections.project_grant_members as members " +
"LEFT JOIN projections.users2_humans " +
"ON members.user_id = projections.users2_humans.user_id " +
"LEFT JOIN projections.users2_machines " +
"ON members.user_id = projections.users2_machines.user_id " +
"FROM projections.project_grant_members2 AS members " +
"LEFT JOIN projections.users3_humans " +
"ON members.user_id = projections.users3_humans.user_id " +
"LEFT JOIN projections.users3_machines " +
"ON members.user_id = projections.users3_machines.user_id " +
"LEFT JOIN projections.login_names " +
"ON members.user_id = projections.login_names.user_id " +
"LEFT JOIN projections.project_grants " +
"ON members.grant_id = projections.project_grants.grant_id " +
"LEFT JOIN projections.project_grants2 " +
"ON members.grant_id = projections.project_grants2.grant_id " +
"WHERE projections.login_names.is_primary = $1")
projectGrantMembersColumns = []string{
"creation_date",
@@ -94,7 +94,7 @@ func Test_ProjectGrantMemberPrepares(t *testing.T) {
uint64(20211206),
"ro",
"user-id",
pq.StringArray{"role-1", "role-2"},
database.StringArray{"role-1", "role-2"},
"[email protected]",
"[email protected]",
"first-name",
@@ -117,7 +117,7 @@ func Test_ProjectGrantMemberPrepares(t *testing.T) {
Sequence: 20211206,
ResourceOwner: "ro",
UserID: "user-id",
Roles: []string{"role-1", "role-2"},
Roles: database.StringArray{"role-1", "role-2"},
PreferredLoginName: "[email protected]",
Email: "[email protected]",
FirstName: "first-name",
@@ -142,7 +142,7 @@ func Test_ProjectGrantMemberPrepares(t *testing.T) {
uint64(20211206),
"ro",
"user-id",
pq.StringArray{"role-1", "role-2"},
database.StringArray{"role-1", "role-2"},
"[email protected]",
nil,
nil,
@@ -165,7 +165,7 @@ func Test_ProjectGrantMemberPrepares(t *testing.T) {
Sequence: 20211206,
ResourceOwner: "ro",
UserID: "user-id",
Roles: []string{"role-1", "role-2"},
Roles: database.StringArray{"role-1", "role-2"},
PreferredLoginName: "[email protected]",
Email: "",
FirstName: "",
@@ -190,7 +190,7 @@ func Test_ProjectGrantMemberPrepares(t *testing.T) {
uint64(20211206),
"ro",
"user-id-1",
pq.StringArray{"role-1", "role-2"},
database.StringArray{"role-1", "role-2"},
"[email protected]",
"[email protected]",
"first-name",
@@ -205,7 +205,7 @@ func Test_ProjectGrantMemberPrepares(t *testing.T) {
uint64(20211206),
"ro",
"user-id-2",
pq.StringArray{"role-1", "role-2"},
database.StringArray{"role-1", "role-2"},
"[email protected]",
nil,
nil,
@@ -228,7 +228,7 @@ func Test_ProjectGrantMemberPrepares(t *testing.T) {
Sequence: 20211206,
ResourceOwner: "ro",
UserID: "user-id-1",
Roles: []string{"role-1", "role-2"},
Roles: database.StringArray{"role-1", "role-2"},
PreferredLoginName: "[email protected]",
Email: "[email protected]",
FirstName: "first-name",
@@ -242,7 +242,7 @@ func Test_ProjectGrantMemberPrepares(t *testing.T) {
Sequence: 20211206,
ResourceOwner: "ro",
UserID: "user-id-2",
Roles: []string{"role-1", "role-2"},
Roles: database.StringArray{"role-1", "role-2"},
PreferredLoginName: "[email protected]",
Email: "",
FirstName: "",
+203 -204
View File
@@ -8,8 +8,7 @@ import (
"regexp"
"testing"
"github.com/lib/pq"
"github.com/zitadel/zitadel/internal/database"
"github.com/zitadel/zitadel/internal/domain"
errs "github.com/zitadel/zitadel/internal/errors"
)
@@ -30,23 +29,23 @@ func Test_ProjectGrantPrepares(t *testing.T) {
prepare: prepareProjectGrantsQuery,
want: want{
sqlExpectations: mockQueries(
regexp.QuoteMeta(` SELECT projections.project_grants.project_id,`+
` projections.project_grants.grant_id,`+
` projections.project_grants.creation_date,`+
` projections.project_grants.change_date,`+
` projections.project_grants.resource_owner,`+
` projections.project_grants.state,`+
` projections.project_grants.sequence,`+
` projections.projects.name,`+
` projections.project_grants.granted_org_id,`+
regexp.QuoteMeta(` SELECT projections.project_grants2.project_id,`+
` projections.project_grants2.grant_id,`+
` projections.project_grants2.creation_date,`+
` projections.project_grants2.change_date,`+
` projections.project_grants2.resource_owner,`+
` projections.project_grants2.state,`+
` projections.project_grants2.sequence,`+
` projections.projects2.name,`+
` projections.project_grants2.granted_org_id,`+
` o.name,`+
` projections.project_grants.granted_role_keys,`+
` projections.project_grants2.granted_role_keys,`+
` r.name,`+
` COUNT(*) OVER () `+
` FROM projections.project_grants `+
` LEFT JOIN projections.projects ON projections.project_grants.project_id = projections.projects.id `+
` LEFT JOIN projections.orgs as r ON projections.project_grants.resource_owner = r.id`+
` LEFT JOIN projections.orgs as o ON projections.project_grants.granted_org_id = o.id`),
` FROM projections.project_grants2 `+
` LEFT JOIN projections.projects2 ON projections.project_grants2.project_id = projections.projects2.id `+
` LEFT JOIN projections.orgs AS r ON projections.project_grants2.resource_owner = r.id`+
` LEFT JOIN projections.orgs AS o ON projections.project_grants2.granted_org_id = o.id`),
nil,
nil,
),
@@ -58,23 +57,23 @@ func Test_ProjectGrantPrepares(t *testing.T) {
prepare: prepareProjectGrantsQuery,
want: want{
sqlExpectations: mockQueries(
regexp.QuoteMeta(` SELECT projections.project_grants.project_id,`+
` projections.project_grants.grant_id,`+
` projections.project_grants.creation_date,`+
` projections.project_grants.change_date,`+
` projections.project_grants.resource_owner,`+
` projections.project_grants.state,`+
` projections.project_grants.sequence,`+
` projections.projects.name,`+
` projections.project_grants.granted_org_id,`+
regexp.QuoteMeta(` SELECT projections.project_grants2.project_id,`+
` projections.project_grants2.grant_id,`+
` projections.project_grants2.creation_date,`+
` projections.project_grants2.change_date,`+
` projections.project_grants2.resource_owner,`+
` projections.project_grants2.state,`+
` projections.project_grants2.sequence,`+
` projections.projects2.name,`+
` projections.project_grants2.granted_org_id,`+
` o.name,`+
` projections.project_grants.granted_role_keys,`+
` projections.project_grants2.granted_role_keys,`+
` r.name,`+
` COUNT(*) OVER ()`+
` FROM projections.project_grants`+
` LEFT JOIN projections.projects ON projections.project_grants.project_id = projections.projects.id`+
` LEFT JOIN projections.orgs as r ON projections.project_grants.resource_owner = r.id`+
` LEFT JOIN projections.orgs as o ON projections.project_grants.granted_org_id = o.id`),
` FROM projections.project_grants2`+
` LEFT JOIN projections.projects2 ON projections.project_grants2.project_id = projections.projects2.id`+
` LEFT JOIN projections.orgs AS r ON projections.project_grants2.resource_owner = r.id`+
` LEFT JOIN projections.orgs AS o ON projections.project_grants2.granted_org_id = o.id`),
[]string{
"project_id",
"grant_id",
@@ -102,7 +101,7 @@ func Test_ProjectGrantPrepares(t *testing.T) {
"project-name",
"org-id",
"org-name",
pq.StringArray{"role-key"},
database.StringArray{"role-key"},
"ro-name",
},
},
@@ -124,7 +123,7 @@ func Test_ProjectGrantPrepares(t *testing.T) {
ProjectName: "project-name",
GrantedOrgID: "org-id",
OrgName: "org-name",
GrantedRoleKeys: pq.StringArray{"role-key"},
GrantedRoleKeys: database.StringArray{"role-key"},
ResourceOwnerName: "ro-name",
},
},
@@ -135,23 +134,23 @@ func Test_ProjectGrantPrepares(t *testing.T) {
prepare: prepareProjectGrantsQuery,
want: want{
sqlExpectations: mockQueries(
regexp.QuoteMeta(` SELECT projections.project_grants.project_id,`+
` projections.project_grants.grant_id,`+
` projections.project_grants.creation_date,`+
` projections.project_grants.change_date,`+
` projections.project_grants.resource_owner,`+
` projections.project_grants.state,`+
` projections.project_grants.sequence,`+
` projections.projects.name,`+
` projections.project_grants.granted_org_id,`+
regexp.QuoteMeta(` SELECT projections.project_grants2.project_id,`+
` projections.project_grants2.grant_id,`+
` projections.project_grants2.creation_date,`+
` projections.project_grants2.change_date,`+
` projections.project_grants2.resource_owner,`+
` projections.project_grants2.state,`+
` projections.project_grants2.sequence,`+
` projections.projects2.name,`+
` projections.project_grants2.granted_org_id,`+
` o.name,`+
` projections.project_grants.granted_role_keys,`+
` projections.project_grants2.granted_role_keys,`+
` r.name,`+
` COUNT(*) OVER () `+
` FROM projections.project_grants `+
` LEFT JOIN projections.projects ON projections.project_grants.project_id = projections.projects.id `+
` LEFT JOIN projections.orgs as r ON projections.project_grants.resource_owner = r.id`+
` LEFT JOIN projections.orgs as o ON projections.project_grants.granted_org_id = o.id`),
` FROM projections.project_grants2 `+
` LEFT JOIN projections.projects2 ON projections.project_grants2.project_id = projections.projects2.id `+
` LEFT JOIN projections.orgs AS r ON projections.project_grants2.resource_owner = r.id`+
` LEFT JOIN projections.orgs AS o ON projections.project_grants2.granted_org_id = o.id`),
[]string{
"project_id",
"grant_id",
@@ -179,7 +178,7 @@ func Test_ProjectGrantPrepares(t *testing.T) {
nil,
"org-id",
"org-name",
pq.StringArray{"role-key"},
database.StringArray{"role-key"},
"ro-name",
},
},
@@ -201,7 +200,7 @@ func Test_ProjectGrantPrepares(t *testing.T) {
ProjectName: "",
GrantedOrgID: "org-id",
OrgName: "org-name",
GrantedRoleKeys: pq.StringArray{"role-key"},
GrantedRoleKeys: database.StringArray{"role-key"},
ResourceOwnerName: "ro-name",
},
},
@@ -212,23 +211,23 @@ func Test_ProjectGrantPrepares(t *testing.T) {
prepare: prepareProjectGrantsQuery,
want: want{
sqlExpectations: mockQueries(
regexp.QuoteMeta(` SELECT projections.project_grants.project_id,`+
` projections.project_grants.grant_id,`+
` projections.project_grants.creation_date,`+
` projections.project_grants.change_date,`+
` projections.project_grants.resource_owner,`+
` projections.project_grants.state,`+
` projections.project_grants.sequence,`+
` projections.projects.name,`+
` projections.project_grants.granted_org_id,`+
regexp.QuoteMeta(` SELECT projections.project_grants2.project_id,`+
` projections.project_grants2.grant_id,`+
` projections.project_grants2.creation_date,`+
` projections.project_grants2.change_date,`+
` projections.project_grants2.resource_owner,`+
` projections.project_grants2.state,`+
` projections.project_grants2.sequence,`+
` projections.projects2.name,`+
` projections.project_grants2.granted_org_id,`+
` o.name,`+
` projections.project_grants.granted_role_keys,`+
` projections.project_grants2.granted_role_keys,`+
` r.name,`+
` COUNT(*) OVER () `+
` FROM projections.project_grants `+
` LEFT JOIN projections.projects ON projections.project_grants.project_id = projections.projects.id `+
` LEFT JOIN projections.orgs as r ON projections.project_grants.resource_owner = r.id`+
` LEFT JOIN projections.orgs as o ON projections.project_grants.granted_org_id = o.id`),
` FROM projections.project_grants2 `+
` LEFT JOIN projections.projects2 ON projections.project_grants2.project_id = projections.projects2.id `+
` LEFT JOIN projections.orgs AS r ON projections.project_grants2.resource_owner = r.id`+
` LEFT JOIN projections.orgs AS o ON projections.project_grants2.granted_org_id = o.id`),
[]string{
"project_id",
"grant_id",
@@ -256,7 +255,7 @@ func Test_ProjectGrantPrepares(t *testing.T) {
"project-name",
"org-id",
nil,
pq.StringArray{"role-key"},
database.StringArray{"role-key"},
"ro-name",
},
},
@@ -278,7 +277,7 @@ func Test_ProjectGrantPrepares(t *testing.T) {
ProjectName: "project-name",
GrantedOrgID: "org-id",
OrgName: "",
GrantedRoleKeys: pq.StringArray{"role-key"},
GrantedRoleKeys: database.StringArray{"role-key"},
ResourceOwnerName: "ro-name",
},
},
@@ -289,23 +288,23 @@ func Test_ProjectGrantPrepares(t *testing.T) {
prepare: prepareProjectGrantsQuery,
want: want{
sqlExpectations: mockQueries(
regexp.QuoteMeta(` SELECT projections.project_grants.project_id,`+
` projections.project_grants.grant_id,`+
` projections.project_grants.creation_date,`+
` projections.project_grants.change_date,`+
` projections.project_grants.resource_owner,`+
` projections.project_grants.state,`+
` projections.project_grants.sequence,`+
` projections.projects.name,`+
` projections.project_grants.granted_org_id,`+
regexp.QuoteMeta(` SELECT projections.project_grants2.project_id,`+
` projections.project_grants2.grant_id,`+
` projections.project_grants2.creation_date,`+
` projections.project_grants2.change_date,`+
` projections.project_grants2.resource_owner,`+
` projections.project_grants2.state,`+
` projections.project_grants2.sequence,`+
` projections.projects2.name,`+
` projections.project_grants2.granted_org_id,`+
` o.name,`+
` projections.project_grants.granted_role_keys,`+
` projections.project_grants2.granted_role_keys,`+
` r.name,`+
` COUNT(*) OVER () `+
` FROM projections.project_grants `+
` LEFT JOIN projections.projects ON projections.project_grants.project_id = projections.projects.id `+
` LEFT JOIN projections.orgs as r ON projections.project_grants.resource_owner = r.id`+
` LEFT JOIN projections.orgs as o ON projections.project_grants.granted_org_id = o.id`),
` FROM projections.project_grants2 `+
` LEFT JOIN projections.projects2 ON projections.project_grants2.project_id = projections.projects2.id `+
` LEFT JOIN projections.orgs AS r ON projections.project_grants2.resource_owner = r.id`+
` LEFT JOIN projections.orgs AS o ON projections.project_grants2.granted_org_id = o.id`),
[]string{
"project_id",
"grant_id",
@@ -333,7 +332,7 @@ func Test_ProjectGrantPrepares(t *testing.T) {
"project-name",
"org-id",
"org-name",
pq.StringArray{"role-key"},
database.StringArray{"role-key"},
nil,
},
},
@@ -355,7 +354,7 @@ func Test_ProjectGrantPrepares(t *testing.T) {
ProjectName: "project-name",
GrantedOrgID: "org-id",
OrgName: "org-name",
GrantedRoleKeys: pq.StringArray{"role-key"},
GrantedRoleKeys: database.StringArray{"role-key"},
ResourceOwnerName: "",
},
},
@@ -366,23 +365,23 @@ func Test_ProjectGrantPrepares(t *testing.T) {
prepare: prepareProjectGrantsQuery,
want: want{
sqlExpectations: mockQueries(
regexp.QuoteMeta(` SELECT projections.project_grants.project_id,`+
` projections.project_grants.grant_id,`+
` projections.project_grants.creation_date,`+
` projections.project_grants.change_date,`+
` projections.project_grants.resource_owner,`+
` projections.project_grants.state,`+
` projections.project_grants.sequence,`+
` projections.projects.name,`+
` projections.project_grants.granted_org_id,`+
regexp.QuoteMeta(` SELECT projections.project_grants2.project_id,`+
` projections.project_grants2.grant_id,`+
` projections.project_grants2.creation_date,`+
` projections.project_grants2.change_date,`+
` projections.project_grants2.resource_owner,`+
` projections.project_grants2.state,`+
` projections.project_grants2.sequence,`+
` projections.projects2.name,`+
` projections.project_grants2.granted_org_id,`+
` o.name,`+
` projections.project_grants.granted_role_keys,`+
` projections.project_grants2.granted_role_keys,`+
` r.name,`+
` COUNT(*) OVER () `+
` FROM projections.project_grants `+
` LEFT JOIN projections.projects ON projections.project_grants.project_id = projections.projects.id `+
` LEFT JOIN projections.orgs as r ON projections.project_grants.resource_owner = r.id`+
` LEFT JOIN projections.orgs as o ON projections.project_grants.granted_org_id = o.id`),
` FROM projections.project_grants2 `+
` LEFT JOIN projections.projects2 ON projections.project_grants2.project_id = projections.projects2.id `+
` LEFT JOIN projections.orgs AS r ON projections.project_grants2.resource_owner = r.id`+
` LEFT JOIN projections.orgs AS o ON projections.project_grants2.granted_org_id = o.id`),
[]string{
"project_id",
"grant_id",
@@ -410,7 +409,7 @@ func Test_ProjectGrantPrepares(t *testing.T) {
"project-name",
"org-id",
"org-name",
pq.StringArray{"role-key"},
database.StringArray{"role-key"},
"ro-name",
},
{
@@ -424,7 +423,7 @@ func Test_ProjectGrantPrepares(t *testing.T) {
"project-name",
"org-id",
"org-name",
pq.StringArray{"role-key"},
database.StringArray{"role-key"},
"ro-name",
},
},
@@ -446,7 +445,7 @@ func Test_ProjectGrantPrepares(t *testing.T) {
ProjectName: "project-name",
GrantedOrgID: "org-id",
OrgName: "org-name",
GrantedRoleKeys: pq.StringArray{"role-key"},
GrantedRoleKeys: database.StringArray{"role-key"},
ResourceOwnerName: "ro-name",
},
{
@@ -460,7 +459,7 @@ func Test_ProjectGrantPrepares(t *testing.T) {
ProjectName: "project-name",
GrantedOrgID: "org-id",
OrgName: "org-name",
GrantedRoleKeys: pq.StringArray{"role-key"},
GrantedRoleKeys: database.StringArray{"role-key"},
ResourceOwnerName: "ro-name",
},
},
@@ -471,23 +470,23 @@ func Test_ProjectGrantPrepares(t *testing.T) {
prepare: prepareProjectGrantsQuery,
want: want{
sqlExpectations: mockQueryErr(
regexp.QuoteMeta(` SELECT projections.project_grants.project_id,`+
` projections.project_grants.grant_id,`+
` projections.project_grants.creation_date,`+
` projections.project_grants.change_date,`+
` projections.project_grants.resource_owner,`+
` projections.project_grants.state,`+
` projections.project_grants.sequence,`+
` projections.projects.name,`+
` projections.project_grants.granted_org_id,`+
regexp.QuoteMeta(` SELECT projections.project_grants2.project_id,`+
` projections.project_grants2.grant_id,`+
` projections.project_grants2.creation_date,`+
` projections.project_grants2.change_date,`+
` projections.project_grants2.resource_owner,`+
` projections.project_grants2.state,`+
` projections.project_grants2.sequence,`+
` projections.projects2.name,`+
` projections.project_grants2.granted_org_id,`+
` o.name,`+
` projections.project_grants.granted_role_keys,`+
` projections.project_grants2.granted_role_keys,`+
` r.name,`+
` COUNT(*) OVER () `+
` FROM projections.project_grants `+
` LEFT JOIN projections.projects ON projections.project_grants.project_id = projections.projects.id `+
` LEFT JOIN projections.orgs as r ON projections.project_grants.resource_owner = r.id`+
` LEFT JOIN projections.orgs as o ON projections.project_grants.granted_org_id = o.id`),
` FROM projections.project_grants2 `+
` LEFT JOIN projections.projects2 ON projections.project_grants2.project_id = projections.projects2.id `+
` LEFT JOIN projections.orgs AS r ON projections.project_grants2.resource_owner = r.id`+
` LEFT JOIN projections.orgs AS o ON projections.project_grants2.granted_org_id = o.id`),
sql.ErrConnDone,
),
err: func(err error) (error, bool) {
@@ -504,22 +503,22 @@ func Test_ProjectGrantPrepares(t *testing.T) {
prepare: prepareProjectGrantQuery,
want: want{
sqlExpectations: mockQueries(
regexp.QuoteMeta(` SELECT projections.project_grants.project_id,`+
` projections.project_grants.grant_id,`+
` projections.project_grants.creation_date,`+
` projections.project_grants.change_date,`+
` projections.project_grants.resource_owner,`+
` projections.project_grants.state,`+
` projections.project_grants.sequence,`+
` projections.projects.name,`+
` projections.project_grants.granted_org_id,`+
regexp.QuoteMeta(` SELECT projections.project_grants2.project_id,`+
` projections.project_grants2.grant_id,`+
` projections.project_grants2.creation_date,`+
` projections.project_grants2.change_date,`+
` projections.project_grants2.resource_owner,`+
` projections.project_grants2.state,`+
` projections.project_grants2.sequence,`+
` projections.projects2.name,`+
` projections.project_grants2.granted_org_id,`+
` o.name,`+
` projections.project_grants.granted_role_keys,`+
` projections.project_grants2.granted_role_keys,`+
` r.name`+
` FROM projections.project_grants `+
` LEFT JOIN projections.projects ON projections.project_grants.project_id = projections.projects.id `+
` LEFT JOIN projections.orgs as r ON projections.project_grants.resource_owner = r.id`+
` LEFT JOIN projections.orgs as o ON projections.project_grants.granted_org_id = o.id`),
` FROM projections.project_grants2 `+
` LEFT JOIN projections.projects2 ON projections.project_grants2.project_id = projections.projects2.id `+
` LEFT JOIN projections.orgs AS r ON projections.project_grants2.resource_owner = r.id`+
` LEFT JOIN projections.orgs AS o ON projections.project_grants2.granted_org_id = o.id`),
nil,
nil,
),
@@ -537,22 +536,22 @@ func Test_ProjectGrantPrepares(t *testing.T) {
prepare: prepareProjectGrantQuery,
want: want{
sqlExpectations: mockQuery(
regexp.QuoteMeta(` SELECT projections.project_grants.project_id,`+
` projections.project_grants.grant_id,`+
` projections.project_grants.creation_date,`+
` projections.project_grants.change_date,`+
` projections.project_grants.resource_owner,`+
` projections.project_grants.state,`+
` projections.project_grants.sequence,`+
` projections.projects.name,`+
` projections.project_grants.granted_org_id,`+
regexp.QuoteMeta(` SELECT projections.project_grants2.project_id,`+
` projections.project_grants2.grant_id,`+
` projections.project_grants2.creation_date,`+
` projections.project_grants2.change_date,`+
` projections.project_grants2.resource_owner,`+
` projections.project_grants2.state,`+
` projections.project_grants2.sequence,`+
` projections.projects2.name,`+
` projections.project_grants2.granted_org_id,`+
` o.name,`+
` projections.project_grants.granted_role_keys,`+
` projections.project_grants2.granted_role_keys,`+
` r.name`+
` FROM projections.project_grants `+
` LEFT JOIN projections.projects ON projections.project_grants.project_id = projections.projects.id `+
` LEFT JOIN projections.orgs as r ON projections.project_grants.resource_owner = r.id`+
` LEFT JOIN projections.orgs as o ON projections.project_grants.granted_org_id = o.id`),
` FROM projections.project_grants2 `+
` LEFT JOIN projections.projects2 ON projections.project_grants2.project_id = projections.projects2.id `+
` LEFT JOIN projections.orgs AS r ON projections.project_grants2.resource_owner = r.id`+
` LEFT JOIN projections.orgs AS o ON projections.project_grants2.granted_org_id = o.id`),
[]string{
"project_id",
"grant_id",
@@ -578,7 +577,7 @@ func Test_ProjectGrantPrepares(t *testing.T) {
"project-name",
"org-id",
"org-name",
pq.StringArray{"role-key"},
database.StringArray{"role-key"},
"ro-name",
},
),
@@ -594,7 +593,7 @@ func Test_ProjectGrantPrepares(t *testing.T) {
ProjectName: "project-name",
GrantedOrgID: "org-id",
OrgName: "org-name",
GrantedRoleKeys: pq.StringArray{"role-key"},
GrantedRoleKeys: database.StringArray{"role-key"},
ResourceOwnerName: "ro-name",
},
},
@@ -603,22 +602,22 @@ func Test_ProjectGrantPrepares(t *testing.T) {
prepare: prepareProjectGrantQuery,
want: want{
sqlExpectations: mockQuery(
regexp.QuoteMeta(` SELECT projections.project_grants.project_id,`+
` projections.project_grants.grant_id,`+
` projections.project_grants.creation_date,`+
` projections.project_grants.change_date,`+
` projections.project_grants.resource_owner,`+
` projections.project_grants.state,`+
` projections.project_grants.sequence,`+
` projections.projects.name,`+
` projections.project_grants.granted_org_id,`+
regexp.QuoteMeta(` SELECT projections.project_grants2.project_id,`+
` projections.project_grants2.grant_id,`+
` projections.project_grants2.creation_date,`+
` projections.project_grants2.change_date,`+
` projections.project_grants2.resource_owner,`+
` projections.project_grants2.state,`+
` projections.project_grants2.sequence,`+
` projections.projects2.name,`+
` projections.project_grants2.granted_org_id,`+
` o.name,`+
` projections.project_grants.granted_role_keys,`+
` projections.project_grants2.granted_role_keys,`+
` r.name`+
` FROM projections.project_grants `+
` LEFT JOIN projections.projects ON projections.project_grants.project_id = projections.projects.id `+
` LEFT JOIN projections.orgs as r ON projections.project_grants.resource_owner = r.id`+
` LEFT JOIN projections.orgs as o ON projections.project_grants.granted_org_id = o.id`),
` FROM projections.project_grants2 `+
` LEFT JOIN projections.projects2 ON projections.project_grants2.project_id = projections.projects2.id `+
` LEFT JOIN projections.orgs AS r ON projections.project_grants2.resource_owner = r.id`+
` LEFT JOIN projections.orgs AS o ON projections.project_grants2.granted_org_id = o.id`),
[]string{
"project_id",
"grant_id",
@@ -644,7 +643,7 @@ func Test_ProjectGrantPrepares(t *testing.T) {
"project-name",
"org-id",
nil,
pq.StringArray{"role-key"},
database.StringArray{"role-key"},
"ro-name",
},
),
@@ -660,7 +659,7 @@ func Test_ProjectGrantPrepares(t *testing.T) {
ProjectName: "project-name",
GrantedOrgID: "org-id",
OrgName: "",
GrantedRoleKeys: pq.StringArray{"role-key"},
GrantedRoleKeys: database.StringArray{"role-key"},
ResourceOwnerName: "ro-name",
},
},
@@ -669,22 +668,22 @@ func Test_ProjectGrantPrepares(t *testing.T) {
prepare: prepareProjectGrantQuery,
want: want{
sqlExpectations: mockQuery(
regexp.QuoteMeta(` SELECT projections.project_grants.project_id,`+
` projections.project_grants.grant_id,`+
` projections.project_grants.creation_date,`+
` projections.project_grants.change_date,`+
` projections.project_grants.resource_owner,`+
` projections.project_grants.state,`+
` projections.project_grants.sequence,`+
` projections.projects.name,`+
` projections.project_grants.granted_org_id,`+
regexp.QuoteMeta(` SELECT projections.project_grants2.project_id,`+
` projections.project_grants2.grant_id,`+
` projections.project_grants2.creation_date,`+
` projections.project_grants2.change_date,`+
` projections.project_grants2.resource_owner,`+
` projections.project_grants2.state,`+
` projections.project_grants2.sequence,`+
` projections.projects2.name,`+
` projections.project_grants2.granted_org_id,`+
` o.name,`+
` projections.project_grants.granted_role_keys,`+
` projections.project_grants2.granted_role_keys,`+
` r.name`+
` FROM projections.project_grants `+
` LEFT JOIN projections.projects ON projections.project_grants.project_id = projections.projects.id `+
` LEFT JOIN projections.orgs as r ON projections.project_grants.resource_owner = r.id`+
` LEFT JOIN projections.orgs as o ON projections.project_grants.granted_org_id = o.id`),
` FROM projections.project_grants2 `+
` LEFT JOIN projections.projects2 ON projections.project_grants2.project_id = projections.projects2.id `+
` LEFT JOIN projections.orgs AS r ON projections.project_grants2.resource_owner = r.id`+
` LEFT JOIN projections.orgs AS o ON projections.project_grants2.granted_org_id = o.id`),
[]string{
"project_id",
"grant_id",
@@ -710,7 +709,7 @@ func Test_ProjectGrantPrepares(t *testing.T) {
"project-name",
"org-id",
"org-name",
pq.StringArray{"role-key"},
database.StringArray{"role-key"},
nil,
},
),
@@ -726,7 +725,7 @@ func Test_ProjectGrantPrepares(t *testing.T) {
ProjectName: "project-name",
GrantedOrgID: "org-id",
OrgName: "org-name",
GrantedRoleKeys: pq.StringArray{"role-key"},
GrantedRoleKeys: database.StringArray{"role-key"},
ResourceOwnerName: "",
},
},
@@ -735,22 +734,22 @@ func Test_ProjectGrantPrepares(t *testing.T) {
prepare: prepareProjectGrantQuery,
want: want{
sqlExpectations: mockQuery(
regexp.QuoteMeta(` SELECT projections.project_grants.project_id,`+
` projections.project_grants.grant_id,`+
` projections.project_grants.creation_date,`+
` projections.project_grants.change_date,`+
` projections.project_grants.resource_owner,`+
` projections.project_grants.state,`+
` projections.project_grants.sequence,`+
` projections.projects.name,`+
` projections.project_grants.granted_org_id,`+
regexp.QuoteMeta(` SELECT projections.project_grants2.project_id,`+
` projections.project_grants2.grant_id,`+
` projections.project_grants2.creation_date,`+
` projections.project_grants2.change_date,`+
` projections.project_grants2.resource_owner,`+
` projections.project_grants2.state,`+
` projections.project_grants2.sequence,`+
` projections.projects2.name,`+
` projections.project_grants2.granted_org_id,`+
` o.name,`+
` projections.project_grants.granted_role_keys,`+
` projections.project_grants2.granted_role_keys,`+
` r.name`+
` FROM projections.project_grants `+
` LEFT JOIN projections.projects ON projections.project_grants.project_id = projections.projects.id `+
` LEFT JOIN projections.orgs as r ON projections.project_grants.resource_owner = r.id`+
` LEFT JOIN projections.orgs as o ON projections.project_grants.granted_org_id = o.id`),
` FROM projections.project_grants2 `+
` LEFT JOIN projections.projects2 ON projections.project_grants2.project_id = projections.projects2.id `+
` LEFT JOIN projections.orgs AS r ON projections.project_grants2.resource_owner = r.id`+
` LEFT JOIN projections.orgs AS o ON projections.project_grants2.granted_org_id = o.id`),
[]string{
"project_id",
"grant_id",
@@ -776,7 +775,7 @@ func Test_ProjectGrantPrepares(t *testing.T) {
nil,
"org-id",
"org-name",
pq.StringArray{"role-key"},
database.StringArray{"role-key"},
"ro-name",
},
),
@@ -792,7 +791,7 @@ func Test_ProjectGrantPrepares(t *testing.T) {
ProjectName: "",
GrantedOrgID: "org-id",
OrgName: "org-name",
GrantedRoleKeys: pq.StringArray{"role-key"},
GrantedRoleKeys: database.StringArray{"role-key"},
ResourceOwnerName: "ro-name",
},
},
@@ -801,22 +800,22 @@ func Test_ProjectGrantPrepares(t *testing.T) {
prepare: prepareProjectGrantQuery,
want: want{
sqlExpectations: mockQueryErr(
regexp.QuoteMeta(` SELECT projections.project_grants.project_id,`+
` projections.project_grants.grant_id,`+
` projections.project_grants.creation_date,`+
` projections.project_grants.change_date,`+
` projections.project_grants.resource_owner,`+
` projections.project_grants.state,`+
` projections.project_grants.sequence,`+
` projections.projects.name,`+
` projections.project_grants.granted_org_id,`+
regexp.QuoteMeta(` SELECT projections.project_grants2.project_id,`+
` projections.project_grants2.grant_id,`+
` projections.project_grants2.creation_date,`+
` projections.project_grants2.change_date,`+
` projections.project_grants2.resource_owner,`+
` projections.project_grants2.state,`+
` projections.project_grants2.sequence,`+
` projections.projects2.name,`+
` projections.project_grants2.granted_org_id,`+
` o.name,`+
` projections.project_grants.granted_role_keys,`+
` projections.project_grants2.granted_role_keys,`+
` r.name`+
` FROM projections.project_grants `+
` LEFT JOIN projections.projects ON projections.project_grants.project_id = projections.projects.id `+
` LEFT JOIN projections.orgs as r ON projections.project_grants.resource_owner = r.id`+
` LEFT JOIN projections.orgs as o ON projections.project_grants.granted_org_id = o.id`),
` FROM projections.project_grants2 `+
` LEFT JOIN projections.projects2 ON projections.project_grants2.project_id = projections.projects2.id `+
` LEFT JOIN projections.orgs AS r ON projections.project_grants2.resource_owner = r.id`+
` LEFT JOIN projections.orgs AS o ON projections.project_grants2.granted_org_id = o.id`),
sql.ErrConnDone,
),
err: func(err error) (error, bool) {
+1 -4
View File
@@ -5,7 +5,6 @@ import (
"database/sql"
sq "github.com/Masterminds/squirrel"
"github.com/lib/pq"
"github.com/zitadel/zitadel/internal/api/authz"
@@ -119,7 +118,6 @@ func prepareProjectMembersQuery() (sq.SelectBuilder, func(*sql.Rows) (*Members,
for rows.Next() {
member := new(Member)
roles := pq.StringArray{}
var (
preferredLoginName = sql.NullString{}
@@ -137,7 +135,7 @@ func prepareProjectMembersQuery() (sq.SelectBuilder, func(*sql.Rows) (*Members,
&member.Sequence,
&member.ResourceOwner,
&member.UserID,
&roles,
&member.Roles,
&preferredLoginName,
&email,
&firstName,
@@ -153,7 +151,6 @@ func prepareProjectMembersQuery() (sq.SelectBuilder, func(*sql.Rows) (*Members,
return nil, err
}
member.Roles = roles
member.PreferredLoginName = preferredLoginName.String
member.Email = email.String
member.FirstName = firstName.String
+20 -20
View File
@@ -8,7 +8,7 @@ import (
"regexp"
"testing"
"github.com/lib/pq"
"github.com/zitadel/zitadel/internal/database"
)
var (
@@ -20,18 +20,18 @@ var (
", members.user_id" +
", members.roles" +
", projections.login_names.login_name" +
", projections.users2_humans.email" +
", projections.users2_humans.first_name" +
", projections.users2_humans.last_name" +
", projections.users2_humans.display_name" +
", projections.users2_machines.name" +
", projections.users2_humans.avatar_key" +
", projections.users3_humans.email" +
", projections.users3_humans.first_name" +
", projections.users3_humans.last_name" +
", projections.users3_humans.display_name" +
", projections.users3_machines.name" +
", projections.users3_humans.avatar_key" +
", COUNT(*) OVER () " +
"FROM projections.project_members as members " +
"LEFT JOIN projections.users2_humans " +
"ON members.user_id = projections.users2_humans.user_id " +
"LEFT JOIN projections.users2_machines " +
"ON members.user_id = projections.users2_machines.user_id " +
"FROM projections.project_members2 AS members " +
"LEFT JOIN projections.users3_humans " +
"ON members.user_id = projections.users3_humans.user_id " +
"LEFT JOIN projections.users3_machines " +
"ON members.user_id = projections.users3_machines.user_id " +
"LEFT JOIN projections.login_names " +
"ON members.user_id = projections.login_names.user_id " +
"WHERE projections.login_names.is_primary = $1")
@@ -92,7 +92,7 @@ func Test_ProjectMemberPrepares(t *testing.T) {
uint64(20211206),
"ro",
"user-id",
pq.StringArray{"role-1", "role-2"},
database.StringArray{"role-1", "role-2"},
"[email protected]",
"[email protected]",
"first-name",
@@ -115,7 +115,7 @@ func Test_ProjectMemberPrepares(t *testing.T) {
Sequence: 20211206,
ResourceOwner: "ro",
UserID: "user-id",
Roles: []string{"role-1", "role-2"},
Roles: database.StringArray{"role-1", "role-2"},
PreferredLoginName: "[email protected]",
Email: "[email protected]",
FirstName: "first-name",
@@ -140,7 +140,7 @@ func Test_ProjectMemberPrepares(t *testing.T) {
uint64(20211206),
"ro",
"user-id",
pq.StringArray{"role-1", "role-2"},
database.StringArray{"role-1", "role-2"},
"[email protected]",
nil,
nil,
@@ -163,7 +163,7 @@ func Test_ProjectMemberPrepares(t *testing.T) {
Sequence: 20211206,
ResourceOwner: "ro",
UserID: "user-id",
Roles: []string{"role-1", "role-2"},
Roles: database.StringArray{"role-1", "role-2"},
PreferredLoginName: "[email protected]",
Email: "",
FirstName: "",
@@ -188,7 +188,7 @@ func Test_ProjectMemberPrepares(t *testing.T) {
uint64(20211206),
"ro",
"user-id-1",
pq.StringArray{"role-1", "role-2"},
database.StringArray{"role-1", "role-2"},
"[email protected]",
"[email protected]",
"first-name",
@@ -203,7 +203,7 @@ func Test_ProjectMemberPrepares(t *testing.T) {
uint64(20211206),
"ro",
"user-id-2",
pq.StringArray{"role-1", "role-2"},
database.StringArray{"role-1", "role-2"},
"[email protected]",
nil,
nil,
@@ -226,7 +226,7 @@ func Test_ProjectMemberPrepares(t *testing.T) {
Sequence: 20211206,
ResourceOwner: "ro",
UserID: "user-id-1",
Roles: []string{"role-1", "role-2"},
Roles: database.StringArray{"role-1", "role-2"},
PreferredLoginName: "[email protected]",
Email: "[email protected]",
FirstName: "first-name",
@@ -240,7 +240,7 @@ func Test_ProjectMemberPrepares(t *testing.T) {
Sequence: 20211206,
ResourceOwner: "ro",
UserID: "user-id-2",
Roles: []string{"role-1", "role-2"},
Roles: database.StringArray{"role-1", "role-2"},
PreferredLoginName: "[email protected]",
Email: "",
FirstName: "",
+84 -84
View File
@@ -44,19 +44,19 @@ func Test_ProjectPrepares(t *testing.T) {
prepare: prepareProjectsQuery,
want: want{
sqlExpectations: mockQueries(
regexp.QuoteMeta(`SELECT projections.projects.id,`+
` projections.projects.creation_date,`+
` projections.projects.change_date,`+
` projections.projects.resource_owner,`+
` projections.projects.state,`+
` projections.projects.sequence,`+
` projections.projects.name,`+
` projections.projects.project_role_assertion,`+
` projections.projects.project_role_check,`+
` projections.projects.has_project_check,`+
` projections.projects.private_labeling_setting,`+
regexp.QuoteMeta(`SELECT projections.projects2.id,`+
` projections.projects2.creation_date,`+
` projections.projects2.change_date,`+
` projections.projects2.resource_owner,`+
` projections.projects2.state,`+
` projections.projects2.sequence,`+
` projections.projects2.name,`+
` projections.projects2.project_role_assertion,`+
` projections.projects2.project_role_check,`+
` projections.projects2.has_project_check,`+
` projections.projects2.private_labeling_setting,`+
` COUNT(*) OVER ()`+
` FROM projections.projects`),
` FROM projections.projects2`),
nil,
nil,
),
@@ -68,19 +68,19 @@ func Test_ProjectPrepares(t *testing.T) {
prepare: prepareProjectsQuery,
want: want{
sqlExpectations: mockQueries(
regexp.QuoteMeta(`SELECT projections.projects.id,`+
` projections.projects.creation_date,`+
` projections.projects.change_date,`+
` projections.projects.resource_owner,`+
` projections.projects.state,`+
` projections.projects.sequence,`+
` projections.projects.name,`+
` projections.projects.project_role_assertion,`+
` projections.projects.project_role_check,`+
` projections.projects.has_project_check,`+
` projections.projects.private_labeling_setting,`+
regexp.QuoteMeta(`SELECT projections.projects2.id,`+
` projections.projects2.creation_date,`+
` projections.projects2.change_date,`+
` projections.projects2.resource_owner,`+
` projections.projects2.state,`+
` projections.projects2.sequence,`+
` projections.projects2.name,`+
` projections.projects2.project_role_assertion,`+
` projections.projects2.project_role_check,`+
` projections.projects2.has_project_check,`+
` projections.projects2.private_labeling_setting,`+
` COUNT(*) OVER ()`+
` FROM projections.projects`),
` FROM projections.projects2`),
[]string{
"id",
"creation_date",
@@ -138,19 +138,19 @@ func Test_ProjectPrepares(t *testing.T) {
prepare: prepareProjectsQuery,
want: want{
sqlExpectations: mockQueries(
regexp.QuoteMeta(`SELECT projections.projects.id,`+
` projections.projects.creation_date,`+
` projections.projects.change_date,`+
` projections.projects.resource_owner,`+
` projections.projects.state,`+
` projections.projects.sequence,`+
` projections.projects.name,`+
` projections.projects.project_role_assertion,`+
` projections.projects.project_role_check,`+
` projections.projects.has_project_check,`+
` projections.projects.private_labeling_setting,`+
regexp.QuoteMeta(`SELECT projections.projects2.id,`+
` projections.projects2.creation_date,`+
` projections.projects2.change_date,`+
` projections.projects2.resource_owner,`+
` projections.projects2.state,`+
` projections.projects2.sequence,`+
` projections.projects2.name,`+
` projections.projects2.project_role_assertion,`+
` projections.projects2.project_role_check,`+
` projections.projects2.has_project_check,`+
` projections.projects2.private_labeling_setting,`+
` COUNT(*) OVER ()`+
` FROM projections.projects`),
` FROM projections.projects2`),
[]string{
"id",
"creation_date",
@@ -234,19 +234,19 @@ func Test_ProjectPrepares(t *testing.T) {
prepare: prepareProjectsQuery,
want: want{
sqlExpectations: mockQueryErr(
regexp.QuoteMeta(`SELECT projections.projects.id,`+
` projections.projects.creation_date,`+
` projections.projects.change_date,`+
` projections.projects.resource_owner,`+
` projections.projects.state,`+
` projections.projects.sequence,`+
` projections.projects.name,`+
` projections.projects.project_role_assertion,`+
` projections.projects.project_role_check,`+
` projections.projects.has_project_check,`+
` projections.projects.private_labeling_setting,`+
regexp.QuoteMeta(`SELECT projections.projects2.id,`+
` projections.projects2.creation_date,`+
` projections.projects2.change_date,`+
` projections.projects2.resource_owner,`+
` projections.projects2.state,`+
` projections.projects2.sequence,`+
` projections.projects2.name,`+
` projections.projects2.project_role_assertion,`+
` projections.projects2.project_role_check,`+
` projections.projects2.has_project_check,`+
` projections.projects2.private_labeling_setting,`+
` COUNT(*) OVER ()`+
` FROM projections.projects`),
` FROM projections.projects2`),
sql.ErrConnDone,
),
err: func(err error) (error, bool) {
@@ -263,18 +263,18 @@ func Test_ProjectPrepares(t *testing.T) {
prepare: prepareProjectQuery,
want: want{
sqlExpectations: mockQueries(
`SELECT projections.projects.id,`+
` projections.projects.creation_date,`+
` projections.projects.change_date,`+
` projections.projects.resource_owner,`+
` projections.projects.state,`+
` projections.projects.sequence,`+
` projections.projects.name,`+
` projections.projects.project_role_assertion,`+
` projections.projects.project_role_check,`+
` projections.projects.has_project_check,`+
` projections.projects.private_labeling_setting`+
` FROM projections.projects`,
`SELECT projections.projects2.id,`+
` projections.projects2.creation_date,`+
` projections.projects2.change_date,`+
` projections.projects2.resource_owner,`+
` projections.projects2.state,`+
` projections.projects2.sequence,`+
` projections.projects2.name,`+
` projections.projects2.project_role_assertion,`+
` projections.projects2.project_role_check,`+
` projections.projects2.has_project_check,`+
` projections.projects2.private_labeling_setting`+
` FROM projections.projects2`,
nil,
nil,
),
@@ -292,18 +292,18 @@ func Test_ProjectPrepares(t *testing.T) {
prepare: prepareProjectQuery,
want: want{
sqlExpectations: mockQuery(
regexp.QuoteMeta(`SELECT projections.projects.id,`+
` projections.projects.creation_date,`+
` projections.projects.change_date,`+
` projections.projects.resource_owner,`+
` projections.projects.state,`+
` projections.projects.sequence,`+
` projections.projects.name,`+
` projections.projects.project_role_assertion,`+
` projections.projects.project_role_check,`+
` projections.projects.has_project_check,`+
` projections.projects.private_labeling_setting`+
` FROM projections.projects`),
regexp.QuoteMeta(`SELECT projections.projects2.id,`+
` projections.projects2.creation_date,`+
` projections.projects2.change_date,`+
` projections.projects2.resource_owner,`+
` projections.projects2.state,`+
` projections.projects2.sequence,`+
` projections.projects2.name,`+
` projections.projects2.project_role_assertion,`+
` projections.projects2.project_role_check,`+
` projections.projects2.has_project_check,`+
` projections.projects2.private_labeling_setting`+
` FROM projections.projects2`),
[]string{
"id",
"creation_date",
@@ -351,18 +351,18 @@ func Test_ProjectPrepares(t *testing.T) {
prepare: prepareProjectQuery,
want: want{
sqlExpectations: mockQueryErr(
regexp.QuoteMeta(`SELECT projections.projects.id,`+
` projections.projects.creation_date,`+
` projections.projects.change_date,`+
` projections.projects.resource_owner,`+
` projections.projects.state,`+
` projections.projects.sequence,`+
` projections.projects.name,`+
` projections.projects.project_role_assertion,`+
` projections.projects.project_role_check,`+
` projections.projects.has_project_check,`+
` projections.projects.private_labeling_setting`+
` FROM projections.projects`),
regexp.QuoteMeta(`SELECT projections.projects2.id,`+
` projections.projects2.creation_date,`+
` projections.projects2.change_date,`+
` projections.projects2.resource_owner,`+
` projections.projects2.state,`+
` projections.projects2.sequence,`+
` projections.projects2.name,`+
` projections.projects2.project_role_assertion,`+
` projections.projects2.project_role_check,`+
` projections.projects2.has_project_check,`+
` projections.projects2.private_labeling_setting`+
` FROM projections.projects2`),
sql.ErrConnDone,
),
err: func(err error) (error, bool) {
+2 -2
View File
@@ -12,7 +12,7 @@ import (
)
const (
ActionTable = "projections.actions"
ActionTable = "projections.actions2"
ActionIDCol = "id"
ActionCreationDateCol = "creation_date"
ActionChangeDateCol = "change_date"
@@ -49,7 +49,7 @@ func newActionProjection(ctx context.Context, config crdb.StatementHandlerConfig
crdb.NewColumn(ActionAllowedToFailCol, crdb.ColumnTypeBool, crdb.Default(false)),
},
crdb.NewPrimaryKey(ActionInstanceIDCol, ActionIDCol),
crdb.WithIndex(crdb.NewIndex("ro_idx", []string{ActionResourceOwnerCol})),
crdb.WithIndex(crdb.NewIndex("actions_ro_idx", []string{ActionResourceOwnerCol})),
),
)
p.StatementHandler = crdb.NewStatementHandler(ctx, config)
+5 -5
View File
@@ -40,7 +40,7 @@ func TestActionProjection_reduces(t *testing.T) {
executer: &testExecuter{
executions: []execution{
{
expectedStmt: "INSERT INTO projections.actions (id, creation_date, change_date, resource_owner, instance_id, sequence, name, script, timeout, allowed_to_fail, action_state) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11)",
expectedStmt: "INSERT INTO projections.actions2 (id, creation_date, change_date, resource_owner, instance_id, sequence, name, script, timeout, allowed_to_fail, action_state) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11)",
expectedArgs: []interface{}{
"agg-id",
anyArg{},
@@ -77,7 +77,7 @@ func TestActionProjection_reduces(t *testing.T) {
executer: &testExecuter{
executions: []execution{
{
expectedStmt: "UPDATE projections.actions SET (change_date, sequence, name, script) = ($1, $2, $3, $4) WHERE (id = $5)",
expectedStmt: "UPDATE projections.actions2 SET (change_date, sequence, name, script) = ($1, $2, $3, $4) WHERE (id = $5)",
expectedArgs: []interface{}{
anyArg{},
uint64(15),
@@ -108,7 +108,7 @@ func TestActionProjection_reduces(t *testing.T) {
executer: &testExecuter{
executions: []execution{
{
expectedStmt: "UPDATE projections.actions SET (change_date, sequence, action_state) = ($1, $2, $3) WHERE (id = $4)",
expectedStmt: "UPDATE projections.actions2 SET (change_date, sequence, action_state) = ($1, $2, $3) WHERE (id = $4)",
expectedArgs: []interface{}{
anyArg{},
uint64(15),
@@ -138,7 +138,7 @@ func TestActionProjection_reduces(t *testing.T) {
executer: &testExecuter{
executions: []execution{
{
expectedStmt: "UPDATE projections.actions SET (change_date, sequence, action_state) = ($1, $2, $3) WHERE (id = $4)",
expectedStmt: "UPDATE projections.actions2 SET (change_date, sequence, action_state) = ($1, $2, $3) WHERE (id = $4)",
expectedArgs: []interface{}{
anyArg{},
uint64(15),
@@ -168,7 +168,7 @@ func TestActionProjection_reduces(t *testing.T) {
executer: &testExecuter{
executions: []execution{
{
expectedStmt: "DELETE FROM projections.actions WHERE (id = $1)",
expectedStmt: "DELETE FROM projections.actions2 WHERE (id = $1)",
expectedArgs: []interface{}{
"agg-id",
},
+20 -21
View File
@@ -3,8 +3,7 @@ package projection
import (
"context"
"github.com/lib/pq"
"github.com/zitadel/zitadel/internal/database"
"github.com/zitadel/zitadel/internal/domain"
"github.com/zitadel/zitadel/internal/errors"
"github.com/zitadel/zitadel/internal/eventstore"
@@ -14,7 +13,7 @@ import (
)
const (
AppProjectionTable = "projections.apps"
AppProjectionTable = "projections.apps2"
AppAPITable = AppProjectionTable + "_" + appAPITableSuffix
AppOIDCTable = AppProjectionTable + "_" + appOIDCTableSuffix
@@ -76,9 +75,9 @@ func newAppProjection(ctx context.Context, config crdb.StatementHandlerConfig) *
crdb.NewColumn(AppColumnState, crdb.ColumnTypeEnum),
crdb.NewColumn(AppColumnSequence, crdb.ColumnTypeInt64),
},
crdb.NewPrimaryKey(AppColumnID, AppColumnInstanceID),
crdb.WithIndex(crdb.NewIndex("project_id_idx", []string{AppColumnProjectID})),
crdb.WithConstraint(crdb.NewConstraint("id_unique", []string{AppColumnID})),
crdb.NewPrimaryKey(AppColumnInstanceID, AppColumnID),
crdb.WithIndex(crdb.NewIndex("app_project_id_idx", []string{AppColumnProjectID})),
crdb.WithConstraint(crdb.NewConstraint("app_id_unique", []string{AppColumnID})),
),
crdb.NewSuffixedTable([]*crdb.Column{
crdb.NewColumn(AppAPIConfigColumnAppID, crdb.ColumnTypeText),
@@ -87,15 +86,15 @@ func newAppProjection(ctx context.Context, config crdb.StatementHandlerConfig) *
crdb.NewColumn(AppAPIConfigColumnClientSecret, crdb.ColumnTypeJSONB, crdb.Nullable()),
crdb.NewColumn(AppAPIConfigColumnAuthMethod, crdb.ColumnTypeEnum),
},
crdb.NewPrimaryKey(AppAPIConfigColumnAppID, AppAPIConfigColumnInstanceID),
crdb.NewPrimaryKey(AppAPIConfigColumnInstanceID, AppAPIConfigColumnAppID),
appAPITableSuffix,
crdb.WithForeignKey(crdb.NewForeignKeyOfPublicKeys("fk_api_ref_apps")),
crdb.WithIndex(crdb.NewIndex("client_id_idx", []string{AppAPIConfigColumnClientID})),
crdb.WithIndex(crdb.NewIndex("api_client_id_idx", []string{AppAPIConfigColumnClientID})),
),
crdb.NewSuffixedTable([]*crdb.Column{
crdb.NewColumn(AppOIDCConfigColumnAppID, crdb.ColumnTypeText),
crdb.NewColumn(AppOIDCConfigColumnInstanceID, crdb.ColumnTypeText),
crdb.NewColumn(AppOIDCConfigColumnVersion, crdb.ColumnTypeText),
crdb.NewColumn(AppOIDCConfigColumnVersion, crdb.ColumnTypeEnum),
crdb.NewColumn(AppOIDCConfigColumnClientID, crdb.ColumnTypeText),
crdb.NewColumn(AppOIDCConfigColumnClientSecret, crdb.ColumnTypeJSONB, crdb.Nullable()),
crdb.NewColumn(AppOIDCConfigColumnRedirectUris, crdb.ColumnTypeTextArray, crdb.Nullable()),
@@ -112,10 +111,10 @@ func newAppProjection(ctx context.Context, config crdb.StatementHandlerConfig) *
crdb.NewColumn(AppOIDCConfigColumnClockSkew, crdb.ColumnTypeInt64, crdb.Default(0)),
crdb.NewColumn(AppOIDCConfigColumnAdditionalOrigins, crdb.ColumnTypeTextArray, crdb.Nullable()),
},
crdb.NewPrimaryKey(AppOIDCConfigColumnAppID, AppOIDCConfigColumnInstanceID),
crdb.NewPrimaryKey(AppOIDCConfigColumnInstanceID, AppOIDCConfigColumnAppID),
appOIDCTableSuffix,
crdb.WithForeignKey(crdb.NewForeignKeyOfPublicKeys("fk_oidc_ref_apps")),
crdb.WithIndex(crdb.NewIndex("client_id_idx", []string{AppOIDCConfigColumnClientID})),
crdb.WithIndex(crdb.NewIndex("oidc_client_id_idx", []string{AppOIDCConfigColumnClientID})),
),
)
p.StatementHandler = crdb.NewStatementHandler(ctx, config)
@@ -401,19 +400,19 @@ func (p *appProjection) reduceOIDCConfigAdded(event eventstore.Event) (*handler.
handler.NewCol(AppOIDCConfigColumnVersion, e.Version),
handler.NewCol(AppOIDCConfigColumnClientID, e.ClientID),
handler.NewCol(AppOIDCConfigColumnClientSecret, e.ClientSecret),
handler.NewCol(AppOIDCConfigColumnRedirectUris, pq.StringArray(e.RedirectUris)),
handler.NewCol(AppOIDCConfigColumnResponseTypes, pq.Array(e.ResponseTypes)),
handler.NewCol(AppOIDCConfigColumnGrantTypes, pq.Array(e.GrantTypes)),
handler.NewCol(AppOIDCConfigColumnRedirectUris, database.StringArray(e.RedirectUris)),
handler.NewCol(AppOIDCConfigColumnResponseTypes, database.EnumArray[domain.OIDCResponseType](e.ResponseTypes)),
handler.NewCol(AppOIDCConfigColumnGrantTypes, database.EnumArray[domain.OIDCGrantType](e.GrantTypes)),
handler.NewCol(AppOIDCConfigColumnApplicationType, e.ApplicationType),
handler.NewCol(AppOIDCConfigColumnAuthMethodType, e.AuthMethodType),
handler.NewCol(AppOIDCConfigColumnPostLogoutRedirectUris, pq.StringArray(e.PostLogoutRedirectUris)),
handler.NewCol(AppOIDCConfigColumnPostLogoutRedirectUris, database.StringArray(e.PostLogoutRedirectUris)),
handler.NewCol(AppOIDCConfigColumnDevMode, e.DevMode),
handler.NewCol(AppOIDCConfigColumnAccessTokenType, e.AccessTokenType),
handler.NewCol(AppOIDCConfigColumnAccessTokenRoleAssertion, e.AccessTokenRoleAssertion),
handler.NewCol(AppOIDCConfigColumnIDTokenRoleAssertion, e.IDTokenRoleAssertion),
handler.NewCol(AppOIDCConfigColumnIDTokenUserinfoAssertion, e.IDTokenUserinfoAssertion),
handler.NewCol(AppOIDCConfigColumnClockSkew, e.ClockSkew),
handler.NewCol(AppOIDCConfigColumnAdditionalOrigins, pq.StringArray(e.AdditionalOrigins)),
handler.NewCol(AppOIDCConfigColumnAdditionalOrigins, database.StringArray(e.AdditionalOrigins)),
},
crdb.WithTableSuffix(appOIDCTableSuffix),
),
@@ -441,13 +440,13 @@ func (p *appProjection) reduceOIDCConfigChanged(event eventstore.Event) (*handle
cols = append(cols, handler.NewCol(AppOIDCConfigColumnVersion, *e.Version))
}
if e.RedirectUris != nil {
cols = append(cols, handler.NewCol(AppOIDCConfigColumnRedirectUris, pq.StringArray(*e.RedirectUris)))
cols = append(cols, handler.NewCol(AppOIDCConfigColumnRedirectUris, database.StringArray(*e.RedirectUris)))
}
if e.ResponseTypes != nil {
cols = append(cols, handler.NewCol(AppOIDCConfigColumnResponseTypes, pq.Array(*e.ResponseTypes)))
cols = append(cols, handler.NewCol(AppOIDCConfigColumnResponseTypes, database.EnumArray[domain.OIDCResponseType](*e.ResponseTypes)))
}
if e.GrantTypes != nil {
cols = append(cols, handler.NewCol(AppOIDCConfigColumnGrantTypes, pq.Array(*e.GrantTypes)))
cols = append(cols, handler.NewCol(AppOIDCConfigColumnGrantTypes, database.EnumArray[domain.OIDCGrantType](*e.GrantTypes)))
}
if e.ApplicationType != nil {
cols = append(cols, handler.NewCol(AppOIDCConfigColumnApplicationType, *e.ApplicationType))
@@ -456,7 +455,7 @@ func (p *appProjection) reduceOIDCConfigChanged(event eventstore.Event) (*handle
cols = append(cols, handler.NewCol(AppOIDCConfigColumnAuthMethodType, *e.AuthMethodType))
}
if e.PostLogoutRedirectUris != nil {
cols = append(cols, handler.NewCol(AppOIDCConfigColumnPostLogoutRedirectUris, pq.StringArray(*e.PostLogoutRedirectUris)))
cols = append(cols, handler.NewCol(AppOIDCConfigColumnPostLogoutRedirectUris, database.StringArray(*e.PostLogoutRedirectUris)))
}
if e.DevMode != nil {
cols = append(cols, handler.NewCol(AppOIDCConfigColumnDevMode, *e.DevMode))
@@ -477,7 +476,7 @@ func (p *appProjection) reduceOIDCConfigChanged(event eventstore.Event) (*handle
cols = append(cols, handler.NewCol(AppOIDCConfigColumnClockSkew, *e.ClockSkew))
}
if e.AdditionalOrigins != nil {
cols = append(cols, handler.NewCol(AppOIDCConfigColumnAdditionalOrigins, pq.StringArray(*e.AdditionalOrigins)))
cols = append(cols, handler.NewCol(AppOIDCConfigColumnAdditionalOrigins, database.StringArray(*e.AdditionalOrigins)))
}
if len(cols) == 0 {
+29 -30
View File
@@ -4,8 +4,7 @@ import (
"testing"
"time"
"github.com/lib/pq"
"github.com/zitadel/zitadel/internal/database"
"github.com/zitadel/zitadel/internal/domain"
"github.com/zitadel/zitadel/internal/errors"
"github.com/zitadel/zitadel/internal/eventstore"
@@ -45,7 +44,7 @@ func TestAppProjection_reduces(t *testing.T) {
executer: &testExecuter{
executions: []execution{
{
expectedStmt: "INSERT INTO projections.apps (id, name, project_id, creation_date, change_date, resource_owner, instance_id, state, sequence) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9)",
expectedStmt: "INSERT INTO projections.apps2 (id, name, project_id, creation_date, change_date, resource_owner, instance_id, state, sequence) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9)",
expectedArgs: []interface{}{
"app-id",
"my-app",
@@ -83,7 +82,7 @@ func TestAppProjection_reduces(t *testing.T) {
executer: &testExecuter{
executions: []execution{
{
expectedStmt: "UPDATE projections.apps SET (name, change_date, sequence) = ($1, $2, $3) WHERE (id = $4) AND (instance_id = $5)",
expectedStmt: "UPDATE projections.apps2 SET (name, change_date, sequence) = ($1, $2, $3) WHERE (id = $4) AND (instance_id = $5)",
expectedArgs: []interface{}{
"my-app",
anyArg{},
@@ -116,7 +115,7 @@ func TestAppProjection_reduces(t *testing.T) {
executer: &testExecuter{
executions: []execution{
{
expectedStmt: "UPDATE projections.apps SET (state, change_date, sequence) = ($1, $2, $3) WHERE (id = $4) AND (instance_id = $5)",
expectedStmt: "UPDATE projections.apps2 SET (state, change_date, sequence) = ($1, $2, $3) WHERE (id = $4) AND (instance_id = $5)",
expectedArgs: []interface{}{
domain.AppStateInactive,
anyArg{},
@@ -149,7 +148,7 @@ func TestAppProjection_reduces(t *testing.T) {
executer: &testExecuter{
executions: []execution{
{
expectedStmt: "UPDATE projections.apps SET (state, change_date, sequence) = ($1, $2, $3) WHERE (id = $4) AND (instance_id = $5)",
expectedStmt: "UPDATE projections.apps2 SET (state, change_date, sequence) = ($1, $2, $3) WHERE (id = $4) AND (instance_id = $5)",
expectedArgs: []interface{}{
domain.AppStateActive,
anyArg{},
@@ -182,7 +181,7 @@ func TestAppProjection_reduces(t *testing.T) {
executer: &testExecuter{
executions: []execution{
{
expectedStmt: "DELETE FROM projections.apps WHERE (id = $1) AND (instance_id = $2)",
expectedStmt: "DELETE FROM projections.apps2 WHERE (id = $1) AND (instance_id = $2)",
expectedArgs: []interface{}{
"app-id",
"instance-id",
@@ -210,7 +209,7 @@ func TestAppProjection_reduces(t *testing.T) {
executer: &testExecuter{
executions: []execution{
{
expectedStmt: "DELETE FROM projections.apps WHERE (project_id = $1) AND (instance_id = $2)",
expectedStmt: "DELETE FROM projections.apps2 WHERE (project_id = $1) AND (instance_id = $2)",
expectedArgs: []interface{}{
"agg-id",
"instance-id",
@@ -243,7 +242,7 @@ func TestAppProjection_reduces(t *testing.T) {
executer: &testExecuter{
executions: []execution{
{
expectedStmt: "INSERT INTO projections.apps_api_configs (app_id, instance_id, client_id, client_secret, auth_method) VALUES ($1, $2, $3, $4, $5)",
expectedStmt: "INSERT INTO projections.apps2_api_configs (app_id, instance_id, client_id, client_secret, auth_method) VALUES ($1, $2, $3, $4, $5)",
expectedArgs: []interface{}{
"app-id",
"instance-id",
@@ -253,7 +252,7 @@ func TestAppProjection_reduces(t *testing.T) {
},
},
{
expectedStmt: "UPDATE projections.apps SET (change_date, sequence) = ($1, $2) WHERE (id = $3) AND (instance_id = $4)",
expectedStmt: "UPDATE projections.apps2 SET (change_date, sequence) = ($1, $2) WHERE (id = $3) AND (instance_id = $4)",
expectedArgs: []interface{}{
anyArg{},
uint64(15),
@@ -288,7 +287,7 @@ func TestAppProjection_reduces(t *testing.T) {
executer: &testExecuter{
executions: []execution{
{
expectedStmt: "UPDATE projections.apps_api_configs SET (client_secret, auth_method) = ($1, $2) WHERE (app_id = $3) AND (instance_id = $4)",
expectedStmt: "UPDATE projections.apps2_api_configs SET (client_secret, auth_method) = ($1, $2) WHERE (app_id = $3) AND (instance_id = $4)",
expectedArgs: []interface{}{
anyArg{},
domain.APIAuthMethodTypePrivateKeyJWT,
@@ -297,7 +296,7 @@ func TestAppProjection_reduces(t *testing.T) {
},
},
{
expectedStmt: "UPDATE projections.apps SET (change_date, sequence) = ($1, $2) WHERE (id = $3) AND (instance_id = $4)",
expectedStmt: "UPDATE projections.apps2 SET (change_date, sequence) = ($1, $2) WHERE (id = $3) AND (instance_id = $4)",
expectedArgs: []interface{}{
anyArg{},
uint64(15),
@@ -352,7 +351,7 @@ func TestAppProjection_reduces(t *testing.T) {
executer: &testExecuter{
executions: []execution{
{
expectedStmt: "UPDATE projections.apps_api_configs SET (client_secret) = ($1) WHERE (app_id = $2) AND (instance_id = $3)",
expectedStmt: "UPDATE projections.apps2_api_configs SET (client_secret) = ($1) WHERE (app_id = $2) AND (instance_id = $3)",
expectedArgs: []interface{}{
anyArg{},
"app-id",
@@ -360,7 +359,7 @@ func TestAppProjection_reduces(t *testing.T) {
},
},
{
expectedStmt: "UPDATE projections.apps SET (change_date, sequence) = ($1, $2) WHERE (id = $3) AND (instance_id = $4)",
expectedStmt: "UPDATE projections.apps2 SET (change_date, sequence) = ($1, $2) WHERE (id = $3) AND (instance_id = $4)",
expectedArgs: []interface{}{
anyArg{},
uint64(15),
@@ -408,30 +407,30 @@ func TestAppProjection_reduces(t *testing.T) {
executer: &testExecuter{
executions: []execution{
{
expectedStmt: "INSERT INTO projections.apps_oidc_configs (app_id, instance_id, version, client_id, client_secret, redirect_uris, response_types, grant_types, application_type, auth_method_type, post_logout_redirect_uris, is_dev_mode, access_token_type, access_token_role_assertion, id_token_role_assertion, id_token_userinfo_assertion, clock_skew, additional_origins) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14, $15, $16, $17, $18)",
expectedStmt: "INSERT INTO projections.apps2_oidc_configs (app_id, instance_id, version, client_id, client_secret, redirect_uris, response_types, grant_types, application_type, auth_method_type, post_logout_redirect_uris, is_dev_mode, access_token_type, access_token_role_assertion, id_token_role_assertion, id_token_userinfo_assertion, clock_skew, additional_origins) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14, $15, $16, $17, $18)",
expectedArgs: []interface{}{
"app-id",
"instance-id",
domain.OIDCVersionV1,
"client-id",
anyArg{},
pq.StringArray{"redirect.one.ch", "redirect.two.ch"},
pq.Array([]domain.OIDCResponseType{1, 2}),
pq.Array([]domain.OIDCGrantType{1, 2}),
database.StringArray{"redirect.one.ch", "redirect.two.ch"},
database.EnumArray[domain.OIDCResponseType]{1, 2},
database.EnumArray[domain.OIDCGrantType]{1, 2},
domain.OIDCApplicationTypeNative,
domain.OIDCAuthMethodTypeNone,
pq.StringArray{"logout.one.ch", "logout.two.ch"},
database.StringArray{"logout.one.ch", "logout.two.ch"},
true,
domain.OIDCTokenTypeJWT,
true,
true,
true,
1 * time.Microsecond,
pq.StringArray{"origin.one.ch", "origin.two.ch"},
database.StringArray{"origin.one.ch", "origin.two.ch"},
},
},
{
expectedStmt: "UPDATE projections.apps SET (change_date, sequence) = ($1, $2) WHERE (id = $3) AND (instance_id = $4)",
expectedStmt: "UPDATE projections.apps2 SET (change_date, sequence) = ($1, $2) WHERE (id = $3) AND (instance_id = $4)",
expectedArgs: []interface{}{
anyArg{},
uint64(15),
@@ -477,28 +476,28 @@ func TestAppProjection_reduces(t *testing.T) {
executer: &testExecuter{
executions: []execution{
{
expectedStmt: "UPDATE projections.apps_oidc_configs SET (version, redirect_uris, response_types, grant_types, application_type, auth_method_type, post_logout_redirect_uris, is_dev_mode, access_token_type, access_token_role_assertion, id_token_role_assertion, id_token_userinfo_assertion, clock_skew, additional_origins) = ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14) WHERE (app_id = $15) AND (instance_id = $16)",
expectedStmt: "UPDATE projections.apps2_oidc_configs SET (version, redirect_uris, response_types, grant_types, application_type, auth_method_type, post_logout_redirect_uris, is_dev_mode, access_token_type, access_token_role_assertion, id_token_role_assertion, id_token_userinfo_assertion, clock_skew, additional_origins) = ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14) WHERE (app_id = $15) AND (instance_id = $16)",
expectedArgs: []interface{}{
domain.OIDCVersionV1,
pq.StringArray{"redirect.one.ch", "redirect.two.ch"},
pq.Array([]domain.OIDCResponseType{1, 2}),
pq.Array([]domain.OIDCGrantType{1, 2}),
database.StringArray{"redirect.one.ch", "redirect.two.ch"},
database.EnumArray[domain.OIDCResponseType]{1, 2},
database.EnumArray[domain.OIDCGrantType]{1, 2},
domain.OIDCApplicationTypeNative,
domain.OIDCAuthMethodTypeNone,
pq.StringArray{"logout.one.ch", "logout.two.ch"},
database.StringArray{"logout.one.ch", "logout.two.ch"},
true,
domain.OIDCTokenTypeJWT,
true,
true,
true,
1 * time.Microsecond,
pq.StringArray{"origin.one.ch", "origin.two.ch"},
database.StringArray{"origin.one.ch", "origin.two.ch"},
"app-id",
"instance-id",
},
},
{
expectedStmt: "UPDATE projections.apps SET (change_date, sequence) = ($1, $2) WHERE (id = $3) AND (instance_id = $4)",
expectedStmt: "UPDATE projections.apps2 SET (change_date, sequence) = ($1, $2) WHERE (id = $3) AND (instance_id = $4)",
expectedArgs: []interface{}{
anyArg{},
uint64(15),
@@ -553,7 +552,7 @@ func TestAppProjection_reduces(t *testing.T) {
executer: &testExecuter{
executions: []execution{
{
expectedStmt: "UPDATE projections.apps_oidc_configs SET (client_secret) = ($1) WHERE (app_id = $2) AND (instance_id = $3)",
expectedStmt: "UPDATE projections.apps2_oidc_configs SET (client_secret) = ($1) WHERE (app_id = $2) AND (instance_id = $3)",
expectedArgs: []interface{}{
anyArg{},
"app-id",
@@ -561,7 +560,7 @@ func TestAppProjection_reduces(t *testing.T) {
},
},
{
expectedStmt: "UPDATE projections.apps SET (change_date, sequence) = ($1, $2) WHERE (id = $3) AND (instance_id = $4)",
expectedStmt: "UPDATE projections.apps2 SET (change_date, sequence) = ($1, $2) WHERE (id = $3) AND (instance_id = $4)",
expectedArgs: []interface{}{
anyArg{},
uint64(15),
+7
View File
@@ -109,6 +109,13 @@ func (p *customTextProjection) reduceSet(event eventstore.Event) (*handler.State
}
return crdb.NewUpsertStatement(
&customTextEvent,
[]handler.Column{
handler.NewCol(CustomTextInstanceIDCol, nil),
handler.NewCol(CustomTextAggregateIDCol, nil),
handler.NewCol(CustomTextTemplateCol, nil),
handler.NewCol(CustomTextKeyCol, nil),
handler.NewCol(CustomTextLanguageCol, nil),
},
[]handler.Column{
handler.NewCol(CustomTextAggregateIDCol, customTextEvent.Aggregate().ID),
handler.NewCol(CustomTextInstanceIDCol, customTextEvent.Aggregate().InstanceID),
@@ -44,7 +44,7 @@ func TestCustomTextProjection_reduces(t *testing.T) {
executer: &testExecuter{
executions: []execution{
{
expectedStmt: "UPSERT INTO projections.custom_texts (aggregate_id, instance_id, creation_date, change_date, sequence, is_default, template, language, key, text) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10)",
expectedStmt: "INSERT INTO projections.custom_texts (aggregate_id, instance_id, creation_date, change_date, sequence, is_default, template, language, key, text) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10) ON CONFLICT (instance_id, aggregate_id, template, key, language) DO UPDATE SET (creation_date, change_date, sequence, is_default, text) = (EXCLUDED.creation_date, EXCLUDED.change_date, EXCLUDED.sequence, EXCLUDED.is_default, EXCLUDED.text)",
expectedArgs: []interface{}{
"agg-id",
"instance-id",
@@ -152,7 +152,7 @@ func TestCustomTextProjection_reduces(t *testing.T) {
executer: &testExecuter{
executions: []execution{
{
expectedStmt: "UPSERT INTO projections.custom_texts (aggregate_id, instance_id, creation_date, change_date, sequence, is_default, template, language, key, text) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10)",
expectedStmt: "INSERT INTO projections.custom_texts (aggregate_id, instance_id, creation_date, change_date, sequence, is_default, template, language, key, text) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10) ON CONFLICT (instance_id, aggregate_id, template, key, language) DO UPDATE SET (creation_date, change_date, sequence, is_default, text) = (EXCLUDED.creation_date, EXCLUDED.change_date, EXCLUDED.sequence, EXCLUDED.is_default, EXCLUDED.text)",
expectedArgs: []interface{}{
"agg-id",
"instance-id",
@@ -1,8 +0,0 @@
package projection
const (
FailedEventsColumnProjectionName = "projection_name"
FailedEventsColumnFailedSequence = "failed_sequence"
FailedEventsColumnFailureCount = "failure_count"
FailedEventsColumnError = "error"
)
+9 -10
View File
@@ -3,8 +3,7 @@ package projection
import (
"context"
"github.com/lib/pq"
"github.com/zitadel/zitadel/internal/database"
"github.com/zitadel/zitadel/internal/domain"
"github.com/zitadel/zitadel/internal/errors"
"github.com/zitadel/zitadel/internal/eventstore"
@@ -16,7 +15,7 @@ import (
)
const (
IDPTable = "projections.idps"
IDPTable = "projections.idps2"
IDPOIDCTable = IDPTable + "_" + IDPOIDCSuffix
IDPJWTTable = IDPTable + "_" + IDPJWTSuffix
@@ -78,9 +77,9 @@ func newIDPProjection(ctx context.Context, config crdb.StatementHandlerConfig) *
crdb.NewColumn(IDPAutoRegisterCol, crdb.ColumnTypeBool, crdb.Default(false)),
crdb.NewColumn(IDPTypeCol, crdb.ColumnTypeEnum, crdb.Nullable()),
},
crdb.NewPrimaryKey(IDPIDCol, IDPInstanceIDCol),
crdb.WithIndex(crdb.NewIndex("ro_idx", []string{IDPResourceOwnerCol})),
crdb.WithConstraint(crdb.NewConstraint("id_unique", []string{IDPIDCol})),
crdb.NewPrimaryKey(IDPInstanceIDCol, IDPIDCol),
crdb.WithIndex(crdb.NewIndex("idp_ro_idx", []string{IDPResourceOwnerCol})),
crdb.WithConstraint(crdb.NewConstraint("idp_id_unique", []string{IDPIDCol})),
),
crdb.NewSuffixedTable([]*crdb.Column{
crdb.NewColumn(OIDCConfigIDPIDCol, crdb.ColumnTypeText),
@@ -94,7 +93,7 @@ func newIDPProjection(ctx context.Context, config crdb.StatementHandlerConfig) *
crdb.NewColumn(OIDCConfigAuthorizationEndpointCol, crdb.ColumnTypeText, crdb.Nullable()),
crdb.NewColumn(OIDCConfigTokenEndpointCol, crdb.ColumnTypeText, crdb.Nullable()),
},
crdb.NewPrimaryKey(OIDCConfigIDPIDCol, OIDCConfigInstanceIDCol),
crdb.NewPrimaryKey(OIDCConfigInstanceIDCol, OIDCConfigIDPIDCol),
IDPOIDCSuffix,
crdb.WithForeignKey(crdb.NewForeignKeyOfPublicKeys("fk_oidc_ref_idp")),
),
@@ -106,7 +105,7 @@ func newIDPProjection(ctx context.Context, config crdb.StatementHandlerConfig) *
crdb.NewColumn(JWTConfigHeaderNameCol, crdb.ColumnTypeText, crdb.Nullable()),
crdb.NewColumn(JWTConfigEndpointCol, crdb.ColumnTypeText, crdb.Nullable()),
},
crdb.NewPrimaryKey(JWTConfigIDPIDCol, JWTConfigInstanceIDCol),
crdb.NewPrimaryKey(JWTConfigInstanceIDCol, JWTConfigIDPIDCol),
IDPJWTSuffix,
crdb.WithForeignKey(crdb.NewForeignKeyOfPublicKeys("fk_jwt_ref_idp")),
),
@@ -374,7 +373,7 @@ func (p *idpProjection) reduceOIDCConfigAdded(event eventstore.Event) (*handler.
handler.NewCol(OIDCConfigClientIDCol, idpEvent.ClientID),
handler.NewCol(OIDCConfigClientSecretCol, idpEvent.ClientSecret),
handler.NewCol(OIDCConfigIssuerCol, idpEvent.Issuer),
handler.NewCol(OIDCConfigScopesCol, pq.StringArray(idpEvent.Scopes)),
handler.NewCol(OIDCConfigScopesCol, database.StringArray(idpEvent.Scopes)),
handler.NewCol(OIDCConfigDisplayNameMappingCol, idpEvent.IDPDisplayNameMapping),
handler.NewCol(OIDCConfigUsernameMappingCol, idpEvent.UserNameMapping),
handler.NewCol(OIDCConfigAuthorizationEndpointCol, idpEvent.AuthorizationEndpoint),
@@ -414,7 +413,7 @@ func (p *idpProjection) reduceOIDCConfigChanged(event eventstore.Event) (*handle
cols = append(cols, handler.NewCol(OIDCConfigTokenEndpointCol, *idpEvent.TokenEndpoint))
}
if idpEvent.Scopes != nil {
cols = append(cols, handler.NewCol(OIDCConfigScopesCol, pq.StringArray(idpEvent.Scopes)))
cols = append(cols, handler.NewCol(OIDCConfigScopesCol, database.StringArray(idpEvent.Scopes)))
}
if idpEvent.IDPDisplayNameMapping != nil {
cols = append(cols, handler.NewCol(OIDCConfigDisplayNameMappingCol, *idpEvent.IDPDisplayNameMapping))
@@ -14,7 +14,7 @@ import (
)
const (
IDPLoginPolicyLinkTable = "projections.idp_login_policy_links"
IDPLoginPolicyLinkTable = "projections.idp_login_policy_links2"
IDPLoginPolicyLinkIDPIDCol = "idp_id"
IDPLoginPolicyLinkAggregateIDCol = "aggregate_id"
@@ -46,7 +46,7 @@ func newIDPLoginPolicyLinkProjection(ctx context.Context, config crdb.StatementH
crdb.NewColumn(IDPLoginPolicyLinkProviderTypeCol, crdb.ColumnTypeText),
},
crdb.NewPrimaryKey(IDPLoginPolicyLinkInstanceIDCol, IDPLoginPolicyLinkAggregateIDCol, IDPLoginPolicyLinkIDPIDCol),
crdb.WithIndex(crdb.NewIndex("ro_idx", []string{IDPLoginPolicyLinkResourceOwnerCol})),
crdb.WithIndex(crdb.NewIndex("link_ro_idx", []string{IDPLoginPolicyLinkResourceOwnerCol})),
),
)
p.StatementHandler = crdb.NewStatementHandler(ctx, config)
@@ -43,7 +43,7 @@ func TestIDPLoginPolicyLinkProjection_reduces(t *testing.T) {
executer: &testExecuter{
executions: []execution{
{
expectedStmt: "INSERT INTO projections.idp_login_policy_links (idp_id, aggregate_id, creation_date, change_date, sequence, resource_owner, instance_id, provider_type) VALUES ($1, $2, $3, $4, $5, $6, $7, $8)",
expectedStmt: "INSERT INTO projections.idp_login_policy_links2 (idp_id, aggregate_id, creation_date, change_date, sequence, resource_owner, instance_id, provider_type) VALUES ($1, $2, $3, $4, $5, $6, $7, $8)",
expectedArgs: []interface{}{
"idp-config-id",
"agg-id",
@@ -80,7 +80,7 @@ func TestIDPLoginPolicyLinkProjection_reduces(t *testing.T) {
executer: &testExecuter{
executions: []execution{
{
expectedStmt: "DELETE FROM projections.idp_login_policy_links WHERE (idp_id = $1) AND (aggregate_id = $2)",
expectedStmt: "DELETE FROM projections.idp_login_policy_links2 WHERE (idp_id = $1) AND (aggregate_id = $2)",
expectedArgs: []interface{}{
"idp-config-id",
"agg-id",
@@ -111,7 +111,7 @@ func TestIDPLoginPolicyLinkProjection_reduces(t *testing.T) {
executer: &testExecuter{
executions: []execution{
{
expectedStmt: "DELETE FROM projections.idp_login_policy_links WHERE (idp_id = $1) AND (aggregate_id = $2)",
expectedStmt: "DELETE FROM projections.idp_login_policy_links2 WHERE (idp_id = $1) AND (aggregate_id = $2)",
expectedArgs: []interface{}{
"idp-config-id",
"agg-id",
@@ -142,7 +142,7 @@ func TestIDPLoginPolicyLinkProjection_reduces(t *testing.T) {
executer: &testExecuter{
executions: []execution{
{
expectedStmt: "INSERT INTO projections.idp_login_policy_links (idp_id, aggregate_id, creation_date, change_date, sequence, resource_owner, instance_id, provider_type) VALUES ($1, $2, $3, $4, $5, $6, $7, $8)",
expectedStmt: "INSERT INTO projections.idp_login_policy_links2 (idp_id, aggregate_id, creation_date, change_date, sequence, resource_owner, instance_id, provider_type) VALUES ($1, $2, $3, $4, $5, $6, $7, $8)",
expectedArgs: []interface{}{
"idp-config-id",
"agg-id",
@@ -179,7 +179,7 @@ func TestIDPLoginPolicyLinkProjection_reduces(t *testing.T) {
executer: &testExecuter{
executions: []execution{
{
expectedStmt: "DELETE FROM projections.idp_login_policy_links WHERE (idp_id = $1) AND (aggregate_id = $2)",
expectedStmt: "DELETE FROM projections.idp_login_policy_links2 WHERE (idp_id = $1) AND (aggregate_id = $2)",
expectedArgs: []interface{}{
"idp-config-id",
"agg-id",
@@ -210,7 +210,7 @@ func TestIDPLoginPolicyLinkProjection_reduces(t *testing.T) {
executer: &testExecuter{
executions: []execution{
{
expectedStmt: "DELETE FROM projections.idp_login_policy_links WHERE (idp_id = $1) AND (aggregate_id = $2)",
expectedStmt: "DELETE FROM projections.idp_login_policy_links2 WHERE (idp_id = $1) AND (aggregate_id = $2)",
expectedArgs: []interface{}{
"idp-config-id",
"agg-id",
@@ -238,7 +238,7 @@ func TestIDPLoginPolicyLinkProjection_reduces(t *testing.T) {
executer: &testExecuter{
executions: []execution{
{
expectedStmt: "DELETE FROM projections.idp_login_policy_links WHERE (resource_owner = $1)",
expectedStmt: "DELETE FROM projections.idp_login_policy_links2 WHERE (resource_owner = $1)",
expectedArgs: []interface{}{
"agg-id",
},
@@ -267,7 +267,7 @@ func TestIDPLoginPolicyLinkProjection_reduces(t *testing.T) {
executer: &testExecuter{
executions: []execution{
{
expectedStmt: "DELETE FROM projections.idp_login_policy_links WHERE (idp_id = $1) AND (resource_owner = $2)",
expectedStmt: "DELETE FROM projections.idp_login_policy_links2 WHERE (idp_id = $1) AND (resource_owner = $2)",
expectedArgs: []interface{}{
"idp-config-id",
"ro-id",
@@ -297,7 +297,7 @@ func TestIDPLoginPolicyLinkProjection_reduces(t *testing.T) {
executer: &testExecuter{
executions: []execution{
{
expectedStmt: "DELETE FROM projections.idp_login_policy_links WHERE (idp_id = $1) AND (resource_owner = $2)",
expectedStmt: "DELETE FROM projections.idp_login_policy_links2 WHERE (idp_id = $1) AND (resource_owner = $2)",
expectedArgs: []interface{}{
"idp-config-id",
"ro-id",
+31 -32
View File
@@ -3,8 +3,7 @@ package projection
import (
"testing"
"github.com/lib/pq"
"github.com/zitadel/zitadel/internal/database"
"github.com/zitadel/zitadel/internal/domain"
"github.com/zitadel/zitadel/internal/errors"
"github.com/zitadel/zitadel/internal/eventstore"
@@ -48,7 +47,7 @@ func TestIDPProjection_reduces(t *testing.T) {
executer: &testExecuter{
executions: []execution{
{
expectedStmt: "INSERT INTO projections.idps (id, creation_date, change_date, sequence, resource_owner, instance_id, state, name, styling_type, auto_register, owner_type) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11)",
expectedStmt: "INSERT INTO projections.idps2 (id, creation_date, change_date, sequence, resource_owner, instance_id, state, name, styling_type, auto_register, owner_type) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11)",
expectedArgs: []interface{}{
"idp-config-id",
anyArg{},
@@ -90,7 +89,7 @@ func TestIDPProjection_reduces(t *testing.T) {
executer: &testExecuter{
executions: []execution{
{
expectedStmt: "UPDATE projections.idps SET (name, styling_type, auto_register, change_date, sequence) = ($1, $2, $3, $4, $5) WHERE (id = $6) AND (instance_id = $7)",
expectedStmt: "UPDATE projections.idps2 SET (name, styling_type, auto_register, change_date, sequence) = ($1, $2, $3, $4, $5) WHERE (id = $6) AND (instance_id = $7)",
expectedArgs: []interface{}{
"custom-zitadel-instance",
domain.IDPConfigStylingTypeGoogle,
@@ -125,7 +124,7 @@ func TestIDPProjection_reduces(t *testing.T) {
executer: &testExecuter{
executions: []execution{
{
expectedStmt: "UPDATE projections.idps SET (state, change_date, sequence) = ($1, $2, $3) WHERE (id = $4) AND (instance_id = $5)",
expectedStmt: "UPDATE projections.idps2 SET (state, change_date, sequence) = ($1, $2, $3) WHERE (id = $4) AND (instance_id = $5)",
expectedArgs: []interface{}{
domain.IDPConfigStateInactive,
anyArg{},
@@ -158,7 +157,7 @@ func TestIDPProjection_reduces(t *testing.T) {
executer: &testExecuter{
executions: []execution{
{
expectedStmt: "UPDATE projections.idps SET (state, change_date, sequence) = ($1, $2, $3) WHERE (id = $4) AND (instance_id = $5)",
expectedStmt: "UPDATE projections.idps2 SET (state, change_date, sequence) = ($1, $2, $3) WHERE (id = $4) AND (instance_id = $5)",
expectedArgs: []interface{}{
domain.IDPConfigStateActive,
anyArg{},
@@ -191,7 +190,7 @@ func TestIDPProjection_reduces(t *testing.T) {
executer: &testExecuter{
executions: []execution{
{
expectedStmt: "DELETE FROM projections.idps WHERE (id = $1) AND (instance_id = $2)",
expectedStmt: "DELETE FROM projections.idps2 WHERE (id = $1) AND (instance_id = $2)",
expectedArgs: []interface{}{
"idp-config-id",
"instance-id",
@@ -233,7 +232,7 @@ func TestIDPProjection_reduces(t *testing.T) {
executer: &testExecuter{
executions: []execution{
{
expectedStmt: "UPDATE projections.idps SET (change_date, sequence, type) = ($1, $2, $3) WHERE (id = $4) AND (instance_id = $5)",
expectedStmt: "UPDATE projections.idps2 SET (change_date, sequence, type) = ($1, $2, $3) WHERE (id = $4) AND (instance_id = $5)",
expectedArgs: []interface{}{
anyArg{},
uint64(15),
@@ -243,14 +242,14 @@ func TestIDPProjection_reduces(t *testing.T) {
},
},
{
expectedStmt: "INSERT INTO projections.idps_oidc_config (idp_id, instance_id, client_id, client_secret, issuer, scopes, display_name_mapping, username_mapping, authorization_endpoint, token_endpoint) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10)",
expectedStmt: "INSERT INTO projections.idps2_oidc_config (idp_id, instance_id, client_id, client_secret, issuer, scopes, display_name_mapping, username_mapping, authorization_endpoint, token_endpoint) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10)",
expectedArgs: []interface{}{
"idp-config-id",
"instance-id",
"client-id",
anyArg{},
"issuer",
pq.StringArray{"profile"},
database.StringArray{"profile"},
domain.OIDCMappingFieldUnspecified,
domain.OIDCMappingFieldPreferredLoginName,
"https://api.zitadel.ch/authorize",
@@ -293,7 +292,7 @@ func TestIDPProjection_reduces(t *testing.T) {
executer: &testExecuter{
executions: []execution{
{
expectedStmt: "UPDATE projections.idps SET (change_date, sequence) = ($1, $2) WHERE (id = $3) AND (instance_id = $4)",
expectedStmt: "UPDATE projections.idps2 SET (change_date, sequence) = ($1, $2) WHERE (id = $3) AND (instance_id = $4)",
expectedArgs: []interface{}{
anyArg{},
uint64(15),
@@ -302,14 +301,14 @@ func TestIDPProjection_reduces(t *testing.T) {
},
},
{
expectedStmt: "UPDATE projections.idps_oidc_config SET (client_id, client_secret, issuer, authorization_endpoint, token_endpoint, scopes, display_name_mapping, username_mapping) = ($1, $2, $3, $4, $5, $6, $7, $8) WHERE (idp_id = $9) AND (instance_id = $10)",
expectedStmt: "UPDATE projections.idps2_oidc_config SET (client_id, client_secret, issuer, authorization_endpoint, token_endpoint, scopes, display_name_mapping, username_mapping) = ($1, $2, $3, $4, $5, $6, $7, $8) WHERE (idp_id = $9) AND (instance_id = $10)",
expectedArgs: []interface{}{
"client-id",
anyArg{},
"issuer",
"https://api.zitadel.ch/authorize",
"https://api.zitadel.ch/token",
pq.StringArray{"profile"},
database.StringArray{"profile"},
domain.OIDCMappingFieldUnspecified,
domain.OIDCMappingFieldPreferredLoginName,
"idp-config-id",
@@ -364,7 +363,7 @@ func TestIDPProjection_reduces(t *testing.T) {
executer: &testExecuter{
executions: []execution{
{
expectedStmt: "UPDATE projections.idps SET (change_date, sequence, type) = ($1, $2, $3) WHERE (id = $4) AND (instance_id = $5)",
expectedStmt: "UPDATE projections.idps2 SET (change_date, sequence, type) = ($1, $2, $3) WHERE (id = $4) AND (instance_id = $5)",
expectedArgs: []interface{}{
anyArg{},
uint64(15),
@@ -374,7 +373,7 @@ func TestIDPProjection_reduces(t *testing.T) {
},
},
{
expectedStmt: "INSERT INTO projections.idps_jwt_config (idp_id, instance_id, endpoint, issuer, keys_endpoint, header_name) VALUES ($1, $2, $3, $4, $5, $6)",
expectedStmt: "INSERT INTO projections.idps2_jwt_config (idp_id, instance_id, endpoint, issuer, keys_endpoint, header_name) VALUES ($1, $2, $3, $4, $5, $6)",
expectedArgs: []interface{}{
"idp-config-id",
"instance-id",
@@ -412,7 +411,7 @@ func TestIDPProjection_reduces(t *testing.T) {
executer: &testExecuter{
executions: []execution{
{
expectedStmt: "UPDATE projections.idps SET (change_date, sequence) = ($1, $2) WHERE (id = $3) AND (instance_id = $4)",
expectedStmt: "UPDATE projections.idps2 SET (change_date, sequence) = ($1, $2) WHERE (id = $3) AND (instance_id = $4)",
expectedArgs: []interface{}{
anyArg{},
uint64(15),
@@ -421,7 +420,7 @@ func TestIDPProjection_reduces(t *testing.T) {
},
},
{
expectedStmt: "UPDATE projections.idps_jwt_config SET (endpoint, issuer, keys_endpoint, header_name) = ($1, $2, $3, $4) WHERE (idp_id = $5) AND (instance_id = $6)",
expectedStmt: "UPDATE projections.idps2_jwt_config SET (endpoint, issuer, keys_endpoint, header_name) = ($1, $2, $3, $4) WHERE (idp_id = $5) AND (instance_id = $6)",
expectedArgs: []interface{}{
"https://api.zitadel.ch/jwt",
"issuer",
@@ -479,7 +478,7 @@ func TestIDPProjection_reduces(t *testing.T) {
executer: &testExecuter{
executions: []execution{
{
expectedStmt: "INSERT INTO projections.idps (id, creation_date, change_date, sequence, resource_owner, instance_id, state, name, styling_type, auto_register, owner_type) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11)",
expectedStmt: "INSERT INTO projections.idps2 (id, creation_date, change_date, sequence, resource_owner, instance_id, state, name, styling_type, auto_register, owner_type) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11)",
expectedArgs: []interface{}{
"idp-config-id",
anyArg{},
@@ -521,7 +520,7 @@ func TestIDPProjection_reduces(t *testing.T) {
executer: &testExecuter{
executions: []execution{
{
expectedStmt: "UPDATE projections.idps SET (name, styling_type, auto_register, change_date, sequence) = ($1, $2, $3, $4, $5) WHERE (id = $6) AND (instance_id = $7)",
expectedStmt: "UPDATE projections.idps2 SET (name, styling_type, auto_register, change_date, sequence) = ($1, $2, $3, $4, $5) WHERE (id = $6) AND (instance_id = $7)",
expectedArgs: []interface{}{
"custom-zitadel-instance",
domain.IDPConfigStylingTypeGoogle,
@@ -556,7 +555,7 @@ func TestIDPProjection_reduces(t *testing.T) {
executer: &testExecuter{
executions: []execution{
{
expectedStmt: "UPDATE projections.idps SET (state, change_date, sequence) = ($1, $2, $3) WHERE (id = $4) AND (instance_id = $5)",
expectedStmt: "UPDATE projections.idps2 SET (state, change_date, sequence) = ($1, $2, $3) WHERE (id = $4) AND (instance_id = $5)",
expectedArgs: []interface{}{
domain.IDPConfigStateInactive,
anyArg{},
@@ -589,7 +588,7 @@ func TestIDPProjection_reduces(t *testing.T) {
executer: &testExecuter{
executions: []execution{
{
expectedStmt: "UPDATE projections.idps SET (state, change_date, sequence) = ($1, $2, $3) WHERE (id = $4) AND (instance_id = $5)",
expectedStmt: "UPDATE projections.idps2 SET (state, change_date, sequence) = ($1, $2, $3) WHERE (id = $4) AND (instance_id = $5)",
expectedArgs: []interface{}{
domain.IDPConfigStateActive,
anyArg{},
@@ -622,7 +621,7 @@ func TestIDPProjection_reduces(t *testing.T) {
executer: &testExecuter{
executions: []execution{
{
expectedStmt: "DELETE FROM projections.idps WHERE (id = $1) AND (instance_id = $2)",
expectedStmt: "DELETE FROM projections.idps2 WHERE (id = $1) AND (instance_id = $2)",
expectedArgs: []interface{}{
"idp-config-id",
"instance-id",
@@ -664,7 +663,7 @@ func TestIDPProjection_reduces(t *testing.T) {
executer: &testExecuter{
executions: []execution{
{
expectedStmt: "UPDATE projections.idps SET (change_date, sequence, type) = ($1, $2, $3) WHERE (id = $4) AND (instance_id = $5)",
expectedStmt: "UPDATE projections.idps2 SET (change_date, sequence, type) = ($1, $2, $3) WHERE (id = $4) AND (instance_id = $5)",
expectedArgs: []interface{}{
anyArg{},
uint64(15),
@@ -674,14 +673,14 @@ func TestIDPProjection_reduces(t *testing.T) {
},
},
{
expectedStmt: "INSERT INTO projections.idps_oidc_config (idp_id, instance_id, client_id, client_secret, issuer, scopes, display_name_mapping, username_mapping, authorization_endpoint, token_endpoint) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10)",
expectedStmt: "INSERT INTO projections.idps2_oidc_config (idp_id, instance_id, client_id, client_secret, issuer, scopes, display_name_mapping, username_mapping, authorization_endpoint, token_endpoint) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10)",
expectedArgs: []interface{}{
"idp-config-id",
"instance-id",
"client-id",
anyArg{},
"issuer",
pq.StringArray{"profile"},
database.StringArray{"profile"},
domain.OIDCMappingFieldUnspecified,
domain.OIDCMappingFieldPreferredLoginName,
"https://api.zitadel.ch/authorize",
@@ -724,7 +723,7 @@ func TestIDPProjection_reduces(t *testing.T) {
executer: &testExecuter{
executions: []execution{
{
expectedStmt: "UPDATE projections.idps SET (change_date, sequence) = ($1, $2) WHERE (id = $3) AND (instance_id = $4)",
expectedStmt: "UPDATE projections.idps2 SET (change_date, sequence) = ($1, $2) WHERE (id = $3) AND (instance_id = $4)",
expectedArgs: []interface{}{
anyArg{},
uint64(15),
@@ -733,14 +732,14 @@ func TestIDPProjection_reduces(t *testing.T) {
},
},
{
expectedStmt: "UPDATE projections.idps_oidc_config SET (client_id, client_secret, issuer, authorization_endpoint, token_endpoint, scopes, display_name_mapping, username_mapping) = ($1, $2, $3, $4, $5, $6, $7, $8) WHERE (idp_id = $9) AND (instance_id = $10)",
expectedStmt: "UPDATE projections.idps2_oidc_config SET (client_id, client_secret, issuer, authorization_endpoint, token_endpoint, scopes, display_name_mapping, username_mapping) = ($1, $2, $3, $4, $5, $6, $7, $8) WHERE (idp_id = $9) AND (instance_id = $10)",
expectedArgs: []interface{}{
"client-id",
anyArg{},
"issuer",
"https://api.zitadel.ch/authorize",
"https://api.zitadel.ch/token",
pq.StringArray{"profile"},
database.StringArray{"profile"},
domain.OIDCMappingFieldUnspecified,
domain.OIDCMappingFieldPreferredLoginName,
"idp-config-id",
@@ -795,7 +794,7 @@ func TestIDPProjection_reduces(t *testing.T) {
executer: &testExecuter{
executions: []execution{
{
expectedStmt: "UPDATE projections.idps SET (change_date, sequence, type) = ($1, $2, $3) WHERE (id = $4) AND (instance_id = $5)",
expectedStmt: "UPDATE projections.idps2 SET (change_date, sequence, type) = ($1, $2, $3) WHERE (id = $4) AND (instance_id = $5)",
expectedArgs: []interface{}{
anyArg{},
uint64(15),
@@ -805,7 +804,7 @@ func TestIDPProjection_reduces(t *testing.T) {
},
},
{
expectedStmt: "INSERT INTO projections.idps_jwt_config (idp_id, instance_id, endpoint, issuer, keys_endpoint, header_name) VALUES ($1, $2, $3, $4, $5, $6)",
expectedStmt: "INSERT INTO projections.idps2_jwt_config (idp_id, instance_id, endpoint, issuer, keys_endpoint, header_name) VALUES ($1, $2, $3, $4, $5, $6)",
expectedArgs: []interface{}{
"idp-config-id",
"instance-id",
@@ -843,7 +842,7 @@ func TestIDPProjection_reduces(t *testing.T) {
executer: &testExecuter{
executions: []execution{
{
expectedStmt: "UPDATE projections.idps SET (change_date, sequence) = ($1, $2) WHERE (id = $3) AND (instance_id = $4)",
expectedStmt: "UPDATE projections.idps2 SET (change_date, sequence) = ($1, $2) WHERE (id = $3) AND (instance_id = $4)",
expectedArgs: []interface{}{
anyArg{},
uint64(15),
@@ -852,7 +851,7 @@ func TestIDPProjection_reduces(t *testing.T) {
},
},
{
expectedStmt: "UPDATE projections.idps_jwt_config SET (endpoint, issuer, keys_endpoint, header_name) = ($1, $2, $3, $4) WHERE (idp_id = $5) AND (instance_id = $6)",
expectedStmt: "UPDATE projections.idps2_jwt_config SET (endpoint, issuer, keys_endpoint, header_name) = ($1, $2, $3, $4) WHERE (idp_id = $5) AND (instance_id = $6)",
expectedArgs: []interface{}{
"https://api.zitadel.ch/jwt",
"issuer",
+2 -2
View File
@@ -13,7 +13,7 @@ import (
)
const (
IDPUserLinkTable = "projections.idp_user_links"
IDPUserLinkTable = "projections.idp_user_links2"
IDPUserLinkIDPIDCol = "idp_id"
IDPUserLinkUserIDCol = "user_id"
IDPUserLinkExternalUserIDCol = "external_user_id"
@@ -46,7 +46,7 @@ func newIDPUserLinkProjection(ctx context.Context, config crdb.StatementHandlerC
crdb.NewColumn(IDPUserLinkDisplayNameCol, crdb.ColumnTypeText),
},
crdb.NewPrimaryKey(IDPUserLinkInstanceIDCol, IDPUserLinkIDPIDCol, IDPUserLinkExternalUserIDCol),
crdb.WithIndex(crdb.NewIndex("user_idx", []string{IDPUserLinkUserIDCol})),
crdb.WithIndex(crdb.NewIndex("idp_user_idx", []string{IDPUserLinkUserIDCol})),
),
)
p.StatementHandler = crdb.NewStatementHandler(ctx, config)
@@ -44,7 +44,7 @@ func TestIDPUserLinkProjection_reduces(t *testing.T) {
executer: &testExecuter{
executions: []execution{
{
expectedStmt: "INSERT INTO projections.idp_user_links (idp_id, user_id, external_user_id, creation_date, change_date, sequence, resource_owner, instance_id, display_name) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9)",
expectedStmt: "INSERT INTO projections.idp_user_links2 (idp_id, user_id, external_user_id, creation_date, change_date, sequence, resource_owner, instance_id, display_name) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9)",
expectedArgs: []interface{}{
"idp-config-id",
"agg-id",
@@ -82,7 +82,7 @@ func TestIDPUserLinkProjection_reduces(t *testing.T) {
executer: &testExecuter{
executions: []execution{
{
expectedStmt: "DELETE FROM projections.idp_user_links WHERE (idp_id = $1) AND (user_id = $2) AND (external_user_id = $3)",
expectedStmt: "DELETE FROM projections.idp_user_links2 WHERE (idp_id = $1) AND (user_id = $2) AND (external_user_id = $3)",
expectedArgs: []interface{}{
"idp-config-id",
"agg-id",
@@ -114,7 +114,7 @@ func TestIDPUserLinkProjection_reduces(t *testing.T) {
executer: &testExecuter{
executions: []execution{
{
expectedStmt: "DELETE FROM projections.idp_user_links WHERE (idp_id = $1) AND (user_id = $2) AND (external_user_id = $3)",
expectedStmt: "DELETE FROM projections.idp_user_links2 WHERE (idp_id = $1) AND (user_id = $2) AND (external_user_id = $3)",
expectedArgs: []interface{}{
"idp-config-id",
"agg-id",
@@ -143,7 +143,7 @@ func TestIDPUserLinkProjection_reduces(t *testing.T) {
executer: &testExecuter{
executions: []execution{
{
expectedStmt: "DELETE FROM projections.idp_user_links WHERE (resource_owner = $1)",
expectedStmt: "DELETE FROM projections.idp_user_links2 WHERE (resource_owner = $1)",
expectedArgs: []interface{}{
"agg-id",
},
@@ -170,7 +170,7 @@ func TestIDPUserLinkProjection_reduces(t *testing.T) {
executer: &testExecuter{
executions: []execution{
{
expectedStmt: "DELETE FROM projections.idp_user_links WHERE (user_id = $1)",
expectedStmt: "DELETE FROM projections.idp_user_links2 WHERE (user_id = $1)",
expectedArgs: []interface{}{
"agg-id",
},
@@ -199,7 +199,7 @@ func TestIDPUserLinkProjection_reduces(t *testing.T) {
executer: &testExecuter{
executions: []execution{
{
expectedStmt: "DELETE FROM projections.idp_user_links WHERE (idp_id = $1) AND (resource_owner = $2)",
expectedStmt: "DELETE FROM projections.idp_user_links2 WHERE (idp_id = $1) AND (resource_owner = $2)",
expectedArgs: []interface{}{
"idp-config-id",
"ro-id",
@@ -229,7 +229,7 @@ func TestIDPUserLinkProjection_reduces(t *testing.T) {
executer: &testExecuter{
executions: []execution{
{
expectedStmt: "DELETE FROM projections.idp_user_links WHERE (idp_id = $1) AND (resource_owner = $2)",
expectedStmt: "DELETE FROM projections.idp_user_links2 WHERE (idp_id = $1) AND (resource_owner = $2)",
expectedArgs: []interface{}{
"idp-config-id",
"ro-id",
+2 -2
View File
@@ -12,7 +12,7 @@ import (
)
const (
InstanceMemberProjectionTable = "projections.instance_members"
InstanceMemberProjectionTable = "projections.instance_members2"
InstanceMemberIAMIDCol = "id"
)
@@ -29,7 +29,7 @@ func newInstanceMemberProjection(ctx context.Context, config crdb.StatementHandl
crdb.NewTable(
append(memberColumns, crdb.NewColumn(InstanceColumnID, crdb.ColumnTypeText)),
crdb.NewPrimaryKey(MemberInstanceID, InstanceColumnID, MemberUserIDCol),
crdb.WithIndex(crdb.NewIndex("user_idx", []string{MemberUserIDCol})),
crdb.WithIndex(crdb.NewIndex("inst_memb_user_idx", []string{MemberUserIDCol})),
),
)
@@ -3,8 +3,7 @@ package projection
import (
"testing"
"github.com/lib/pq"
"github.com/zitadel/zitadel/internal/database"
"github.com/zitadel/zitadel/internal/errors"
"github.com/zitadel/zitadel/internal/eventstore"
"github.com/zitadel/zitadel/internal/eventstore/handler"
@@ -44,10 +43,10 @@ func TestInstanceMemberProjection_reduces(t *testing.T) {
executer: &testExecuter{
executions: []execution{
{
expectedStmt: "INSERT INTO projections.instance_members (user_id, roles, creation_date, change_date, sequence, resource_owner, instance_id, id) VALUES ($1, $2, $3, $4, $5, $6, $7, $8)",
expectedStmt: "INSERT INTO projections.instance_members2 (user_id, roles, creation_date, change_date, sequence, resource_owner, instance_id, id) VALUES ($1, $2, $3, $4, $5, $6, $7, $8)",
expectedArgs: []interface{}{
"user-id",
pq.StringArray{"role"},
database.StringArray{"role"},
anyArg{},
anyArg{},
uint64(15),
@@ -81,9 +80,9 @@ func TestInstanceMemberProjection_reduces(t *testing.T) {
executer: &testExecuter{
executions: []execution{
{
expectedStmt: "UPDATE projections.instance_members SET (roles, change_date, sequence) = ($1, $2, $3) WHERE (user_id = $4)",
expectedStmt: "UPDATE projections.instance_members2 SET (roles, change_date, sequence) = ($1, $2, $3) WHERE (user_id = $4)",
expectedArgs: []interface{}{
pq.StringArray{"role", "changed"},
database.StringArray{"role", "changed"},
anyArg{},
uint64(15),
"user-id",
@@ -113,7 +112,7 @@ func TestInstanceMemberProjection_reduces(t *testing.T) {
executer: &testExecuter{
executions: []execution{
{
expectedStmt: "DELETE FROM projections.instance_members WHERE (user_id = $1)",
expectedStmt: "DELETE FROM projections.instance_members2 WHERE (user_id = $1)",
expectedArgs: []interface{}{
"user-id",
},
@@ -142,7 +141,7 @@ func TestInstanceMemberProjection_reduces(t *testing.T) {
executer: &testExecuter{
executions: []execution{
{
expectedStmt: "DELETE FROM projections.instance_members WHERE (user_id = $1)",
expectedStmt: "DELETE FROM projections.instance_members2 WHERE (user_id = $1)",
expectedArgs: []interface{}{
"user-id",
},
@@ -169,7 +168,7 @@ func TestInstanceMemberProjection_reduces(t *testing.T) {
executer: &testExecuter{
executions: []execution{
{
expectedStmt: "DELETE FROM projections.instance_members WHERE (user_id = $1)",
expectedStmt: "DELETE FROM projections.instance_members2 WHERE (user_id = $1)",
expectedArgs: []interface{}{
"agg-id",
},
+5 -5
View File
@@ -13,7 +13,7 @@ import (
)
const (
KeyProjectionTable = "projections.keys"
KeyProjectionTable = "projections.keys2"
KeyPrivateTable = KeyProjectionTable + "_" + privateKeyTableSuffix
KeyPublicTable = KeyProjectionTable + "_" + publicKeyTableSuffix
@@ -59,8 +59,8 @@ func newKeyProjection(ctx context.Context, config crdb.StatementHandlerConfig, k
crdb.NewColumn(KeyColumnAlgorithm, crdb.ColumnTypeText, crdb.Default("")),
crdb.NewColumn(KeyColumnUse, crdb.ColumnTypeEnum, crdb.Default(0)),
},
crdb.NewPrimaryKey(KeyColumnID, KeyColumnInstanceID),
crdb.WithConstraint(crdb.NewConstraint("id_unique", []string{KeyColumnID})),
crdb.NewPrimaryKey(KeyColumnInstanceID, KeyColumnID),
crdb.WithConstraint(crdb.NewConstraint("key_id_unique", []string{KeyColumnID})),
),
crdb.NewSuffixedTable([]*crdb.Column{
crdb.NewColumn(KeyPrivateColumnID, crdb.ColumnTypeText),
@@ -68,7 +68,7 @@ func newKeyProjection(ctx context.Context, config crdb.StatementHandlerConfig, k
crdb.NewColumn(KeyPrivateColumnExpiry, crdb.ColumnTypeTimestamp),
crdb.NewColumn(KeyPrivateColumnKey, crdb.ColumnTypeJSONB),
},
crdb.NewPrimaryKey(KeyPrivateColumnID, KeyPrivateColumnInstanceID),
crdb.NewPrimaryKey(KeyPrivateColumnInstanceID, KeyPrivateColumnID),
privateKeyTableSuffix,
crdb.WithForeignKey(crdb.NewForeignKeyOfPublicKeys("fk_private_ref_keys")),
),
@@ -78,7 +78,7 @@ func newKeyProjection(ctx context.Context, config crdb.StatementHandlerConfig, k
crdb.NewColumn(KeyPublicColumnExpiry, crdb.ColumnTypeTimestamp),
crdb.NewColumn(KeyPublicColumnKey, crdb.ColumnTypeBytes),
},
crdb.NewPrimaryKey(KeyPublicColumnID, KeyPublicColumnInstanceID),
crdb.NewPrimaryKey(KeyPublicColumnInstanceID, KeyPublicColumnID),
publicKeyTableSuffix,
crdb.WithForeignKey(crdb.NewForeignKeyOfPublicKeys("fk_public_ref_keys")),
),
+3 -3
View File
@@ -43,7 +43,7 @@ func TestKeyProjection_reduces(t *testing.T) {
executer: &testExecuter{
executions: []execution{
{
expectedStmt: "INSERT INTO projections.keys (id, creation_date, change_date, resource_owner, instance_id, sequence, algorithm, use) VALUES ($1, $2, $3, $4, $5, $6, $7, $8)",
expectedStmt: "INSERT INTO projections.keys2 (id, creation_date, change_date, resource_owner, instance_id, sequence, algorithm, use) VALUES ($1, $2, $3, $4, $5, $6, $7, $8)",
expectedArgs: []interface{}{
"agg-id",
anyArg{},
@@ -56,7 +56,7 @@ func TestKeyProjection_reduces(t *testing.T) {
},
},
{
expectedStmt: "INSERT INTO projections.keys_private (id, instance_id, expiry, key) VALUES ($1, $2, $3, $4)",
expectedStmt: "INSERT INTO projections.keys2_private (id, instance_id, expiry, key) VALUES ($1, $2, $3, $4)",
expectedArgs: []interface{}{
"agg-id",
"instance-id",
@@ -70,7 +70,7 @@ func TestKeyProjection_reduces(t *testing.T) {
},
},
{
expectedStmt: "INSERT INTO projections.keys_public (id, instance_id, expiry, key) VALUES ($1, $2, $3, $4)",
expectedStmt: "INSERT INTO projections.keys2_public (id, instance_id, expiry, key) VALUES ($1, $2, $3, $4)",
expectedArgs: []interface{}{
"agg-id",
"instance-id",
@@ -332,6 +332,11 @@ func (p *labelPolicyProjection) reduceActivated(event eventstore.Event) (*handle
}
return crdb.NewCopyStatement(
event,
[]handler.Column{
handler.NewCol(LabelPolicyInstanceIDCol, nil),
handler.NewCol(LabelPolicyIDCol, nil),
handler.NewCol(LabelPolicyStateCol, nil),
},
[]handler.Column{
handler.NewCol(LabelPolicyChangeDateCol, event.CreationDate()),
handler.NewCol(LabelPolicySequenceCol, event.Sequence()),
@@ -146,7 +146,7 @@ func TestLabelPolicyProjection_reduces(t *testing.T) {
executer: &testExecuter{
executions: []execution{
{
expectedStmt: "UPSERT INTO projections.label_policies (change_date, sequence, state, creation_date, resource_owner, instance_id, id, is_default, hide_login_name_suffix, font_url, watermark_disabled, should_error_popup, light_primary_color, light_warn_color, light_background_color, light_font_color, light_logo_url, light_icon_url, dark_primary_color, dark_warn_color, dark_background_color, dark_font_color, dark_logo_url, dark_icon_url) SELECT $1, $2, $3, creation_date, resource_owner, instance_id, id, is_default, hide_login_name_suffix, font_url, watermark_disabled, should_error_popup, light_primary_color, light_warn_color, light_background_color, light_font_color, light_logo_url, light_icon_url, dark_primary_color, dark_warn_color, dark_background_color, dark_font_color, dark_logo_url, dark_icon_url FROM projections.label_policies AS copy_table WHERE copy_table.id = $4 AND copy_table.state = $5 AND copy_table.instance_id = $6",
expectedStmt: "INSERT INTO projections.label_policies (change_date, sequence, state, creation_date, resource_owner, instance_id, id, is_default, hide_login_name_suffix, font_url, watermark_disabled, should_error_popup, light_primary_color, light_warn_color, light_background_color, light_font_color, light_logo_url, light_icon_url, dark_primary_color, dark_warn_color, dark_background_color, dark_font_color, dark_logo_url, dark_icon_url) SELECT $1, $2, $3, creation_date, resource_owner, instance_id, id, is_default, hide_login_name_suffix, font_url, watermark_disabled, should_error_popup, light_primary_color, light_warn_color, light_background_color, light_font_color, light_logo_url, light_icon_url, dark_primary_color, dark_warn_color, dark_background_color, dark_font_color, dark_logo_url, dark_icon_url FROM projections.label_policies AS copy_table WHERE copy_table.id = $4 AND copy_table.state = $5 AND copy_table.instance_id = $6 ON CONFLICT (instance_id, id, state) DO UPDATE SET (change_date, sequence, state, creation_date, resource_owner, instance_id, id, is_default, hide_login_name_suffix, font_url, watermark_disabled, should_error_popup, light_primary_color, light_warn_color, light_background_color, light_font_color, light_logo_url, light_icon_url, dark_primary_color, dark_warn_color, dark_background_color, dark_font_color, dark_logo_url, dark_icon_url) = ($1, $2, $3, EXCLUDED.creation_date, EXCLUDED.resource_owner, EXCLUDED.instance_id, EXCLUDED.id, EXCLUDED.is_default, EXCLUDED.hide_login_name_suffix, EXCLUDED.font_url, EXCLUDED.watermark_disabled, EXCLUDED.should_error_popup, EXCLUDED.light_primary_color, EXCLUDED.light_warn_color, EXCLUDED.light_background_color, EXCLUDED.light_font_color, EXCLUDED.light_logo_url, EXCLUDED.light_icon_url, EXCLUDED.dark_primary_color, EXCLUDED.dark_warn_color, EXCLUDED.dark_background_color, EXCLUDED.dark_font_color, EXCLUDED.dark_logo_url, EXCLUDED.dark_icon_url)",
expectedArgs: []interface{}{
anyArg{},
uint64(15),
@@ -609,7 +609,7 @@ func TestLabelPolicyProjection_reduces(t *testing.T) {
executer: &testExecuter{
executions: []execution{
{
expectedStmt: "UPSERT INTO projections.label_policies (change_date, sequence, state, creation_date, resource_owner, instance_id, id, is_default, hide_login_name_suffix, font_url, watermark_disabled, should_error_popup, light_primary_color, light_warn_color, light_background_color, light_font_color, light_logo_url, light_icon_url, dark_primary_color, dark_warn_color, dark_background_color, dark_font_color, dark_logo_url, dark_icon_url) SELECT $1, $2, $3, creation_date, resource_owner, instance_id, id, is_default, hide_login_name_suffix, font_url, watermark_disabled, should_error_popup, light_primary_color, light_warn_color, light_background_color, light_font_color, light_logo_url, light_icon_url, dark_primary_color, dark_warn_color, dark_background_color, dark_font_color, dark_logo_url, dark_icon_url FROM projections.label_policies AS copy_table WHERE copy_table.id = $4 AND copy_table.state = $5 AND copy_table.instance_id = $6",
expectedStmt: "INSERT INTO projections.label_policies (change_date, sequence, state, creation_date, resource_owner, instance_id, id, is_default, hide_login_name_suffix, font_url, watermark_disabled, should_error_popup, light_primary_color, light_warn_color, light_background_color, light_font_color, light_logo_url, light_icon_url, dark_primary_color, dark_warn_color, dark_background_color, dark_font_color, dark_logo_url, dark_icon_url) SELECT $1, $2, $3, creation_date, resource_owner, instance_id, id, is_default, hide_login_name_suffix, font_url, watermark_disabled, should_error_popup, light_primary_color, light_warn_color, light_background_color, light_font_color, light_logo_url, light_icon_url, dark_primary_color, dark_warn_color, dark_background_color, dark_font_color, dark_logo_url, dark_icon_url FROM projections.label_policies AS copy_table WHERE copy_table.id = $4 AND copy_table.state = $5 AND copy_table.instance_id = $6 ON CONFLICT (instance_id, id, state) DO UPDATE SET (change_date, sequence, state, creation_date, resource_owner, instance_id, id, is_default, hide_login_name_suffix, font_url, watermark_disabled, should_error_popup, light_primary_color, light_warn_color, light_background_color, light_font_color, light_logo_url, light_icon_url, dark_primary_color, dark_warn_color, dark_background_color, dark_font_color, dark_logo_url, dark_icon_url) = ($1, $2, $3, EXCLUDED.creation_date, EXCLUDED.resource_owner, EXCLUDED.instance_id, EXCLUDED.id, EXCLUDED.is_default, EXCLUDED.hide_login_name_suffix, EXCLUDED.font_url, EXCLUDED.watermark_disabled, EXCLUDED.should_error_popup, EXCLUDED.light_primary_color, EXCLUDED.light_warn_color, EXCLUDED.light_background_color, EXCLUDED.light_font_color, EXCLUDED.light_logo_url, EXCLUDED.light_icon_url, EXCLUDED.dark_primary_color, EXCLUDED.dark_warn_color, EXCLUDED.dark_background_color, EXCLUDED.dark_font_color, EXCLUDED.dark_logo_url, EXCLUDED.dark_icon_url)",
expectedArgs: []interface{}{
anyArg{},
uint64(15),
+4 -4
View File
@@ -44,8 +44,8 @@ const (
var (
viewStmt = fmt.Sprintf("SELECT"+
" user_id"+
" , IF(%[1]s, CONCAT(%[2]s, '@', domain), %[2]s) AS login_name"+
" , IFNULL(%[3]s, true) AS %[3]s"+
" , (CASE WHEN %[1]s THEN CONCAT(%[2]s, '@', domain) ELSE %[2]s END) AS login_name"+
" , COALESCE(%[3]s, true) AS %[3]s"+
" , %[4]s"+
" FROM ("+
" SELECT"+
@@ -62,12 +62,12 @@ var (
" , users.%[2]s"+
" , users.%[4]s"+
" , users.%[5]s"+
" , IFNULL(policy_custom.%[1]s, policy_default.%[1]s) AS %[1]s"+
" , COALESCE(policy_custom.%[1]s, policy_default.%[1]s) AS %[1]s"+
" FROM %[7]s users"+
" LEFT JOIN %[8]s policy_custom on policy_custom.%[9]s = users.%[5]s AND policy_custom.%[10]s = users.%[4]s"+
" LEFT JOIN %[8]s policy_default on policy_default.%[11]s = true AND policy_default.%[10]s = users.%[4]s) policy_users"+
" LEFT JOIN %[12]s domains ON policy_users.%[1]s AND policy_users.%[5]s = domains.%[13]s AND policy_users.%[10]s = domains.%[14]s"+
");",
") AS login_names;",
LoginNamePoliciesMustBeDomainCol,
LoginNameUserUserNameCol,
LoginNameDomainIsPrimaryCol,
+3 -4
View File
@@ -1,8 +1,7 @@
package projection
import (
"github.com/lib/pq"
"github.com/zitadel/zitadel/internal/database"
"github.com/zitadel/zitadel/internal/eventstore"
"github.com/zitadel/zitadel/internal/eventstore/handler"
"github.com/zitadel/zitadel/internal/eventstore/handler/crdb"
@@ -57,7 +56,7 @@ func reduceMemberAdded(e member.MemberAddedEvent, opts ...reduceMemberOpt) (*han
config := reduceMemberConfig{
cols: []handler.Column{
handler.NewCol(MemberUserIDCol, e.UserID),
handler.NewCol(MemberRolesCol, pq.StringArray(e.Roles)),
handler.NewCol(MemberRolesCol, database.StringArray(e.Roles)),
handler.NewCol(MemberCreationDate, e.CreationDate()),
handler.NewCol(MemberChangeDate, e.CreationDate()),
handler.NewCol(MemberSequence, e.Sequence()),
@@ -75,7 +74,7 @@ func reduceMemberAdded(e member.MemberAddedEvent, opts ...reduceMemberOpt) (*han
func reduceMemberChanged(e member.MemberChangedEvent, opts ...reduceMemberOpt) (*handler.Statement, error) {
config := reduceMemberConfig{
cols: []handler.Column{
handler.NewCol(MemberRolesCol, pq.StringArray(e.Roles)),
handler.NewCol(MemberRolesCol, database.StringArray(e.Roles)),
handler.NewCol(MemberChangeDate, e.CreationDate()),
handler.NewCol(MemberSequence, e.Sequence()),
},
@@ -45,7 +45,7 @@ func TestMessageTextProjection_reduces(t *testing.T) {
executer: &testExecuter{
executions: []execution{
{
expectedStmt: "UPSERT INTO projections.message_texts (aggregate_id, instance_id, creation_date, change_date, sequence, state, type, language, title) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9)",
expectedStmt: "INSERT INTO projections.message_texts (aggregate_id, instance_id, creation_date, change_date, sequence, state, type, language, title) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9) ON CONFLICT (instance_id, aggregate_id, type, language) DO UPDATE SET (creation_date, change_date, sequence, state, title) = (EXCLUDED.creation_date, EXCLUDED.change_date, EXCLUDED.sequence, EXCLUDED.state, EXCLUDED.title)",
expectedArgs: []interface{}{
"agg-id",
"instance-id",
@@ -85,7 +85,7 @@ func TestMessageTextProjection_reduces(t *testing.T) {
executer: &testExecuter{
executions: []execution{
{
expectedStmt: "UPSERT INTO projections.message_texts (aggregate_id, instance_id, creation_date, change_date, sequence, state, type, language, pre_header) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9)",
expectedStmt: "INSERT INTO projections.message_texts (aggregate_id, instance_id, creation_date, change_date, sequence, state, type, language, pre_header) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9) ON CONFLICT (instance_id, aggregate_id, type, language) DO UPDATE SET (creation_date, change_date, sequence, state, pre_header) = (EXCLUDED.creation_date, EXCLUDED.change_date, EXCLUDED.sequence, EXCLUDED.state, EXCLUDED.pre_header)",
expectedArgs: []interface{}{
"agg-id",
"instance-id",
@@ -125,7 +125,7 @@ func TestMessageTextProjection_reduces(t *testing.T) {
executer: &testExecuter{
executions: []execution{
{
expectedStmt: "UPSERT INTO projections.message_texts (aggregate_id, instance_id, creation_date, change_date, sequence, state, type, language, subject) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9)",
expectedStmt: "INSERT INTO projections.message_texts (aggregate_id, instance_id, creation_date, change_date, sequence, state, type, language, subject) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9) ON CONFLICT (instance_id, aggregate_id, type, language) DO UPDATE SET (creation_date, change_date, sequence, state, subject) = (EXCLUDED.creation_date, EXCLUDED.change_date, EXCLUDED.sequence, EXCLUDED.state, EXCLUDED.subject)",
expectedArgs: []interface{}{
"agg-id",
"instance-id",
@@ -165,7 +165,7 @@ func TestMessageTextProjection_reduces(t *testing.T) {
executer: &testExecuter{
executions: []execution{
{
expectedStmt: "UPSERT INTO projections.message_texts (aggregate_id, instance_id, creation_date, change_date, sequence, state, type, language, greeting) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9)",
expectedStmt: "INSERT INTO projections.message_texts (aggregate_id, instance_id, creation_date, change_date, sequence, state, type, language, greeting) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9) ON CONFLICT (instance_id, aggregate_id, type, language) DO UPDATE SET (creation_date, change_date, sequence, state, greeting) = (EXCLUDED.creation_date, EXCLUDED.change_date, EXCLUDED.sequence, EXCLUDED.state, EXCLUDED.greeting)",
expectedArgs: []interface{}{
"agg-id",
"instance-id",
@@ -205,7 +205,7 @@ func TestMessageTextProjection_reduces(t *testing.T) {
executer: &testExecuter{
executions: []execution{
{
expectedStmt: "UPSERT INTO projections.message_texts (aggregate_id, instance_id, creation_date, change_date, sequence, state, type, language, text) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9)",
expectedStmt: "INSERT INTO projections.message_texts (aggregate_id, instance_id, creation_date, change_date, sequence, state, type, language, text) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9) ON CONFLICT (instance_id, aggregate_id, type, language) DO UPDATE SET (creation_date, change_date, sequence, state, text) = (EXCLUDED.creation_date, EXCLUDED.change_date, EXCLUDED.sequence, EXCLUDED.state, EXCLUDED.text)",
expectedArgs: []interface{}{
"agg-id",
"instance-id",
@@ -245,7 +245,7 @@ func TestMessageTextProjection_reduces(t *testing.T) {
executer: &testExecuter{
executions: []execution{
{
expectedStmt: "UPSERT INTO projections.message_texts (aggregate_id, instance_id, creation_date, change_date, sequence, state, type, language, button_text) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9)",
expectedStmt: "INSERT INTO projections.message_texts (aggregate_id, instance_id, creation_date, change_date, sequence, state, type, language, button_text) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9) ON CONFLICT (instance_id, aggregate_id, type, language) DO UPDATE SET (creation_date, change_date, sequence, state, button_text) = (EXCLUDED.creation_date, EXCLUDED.change_date, EXCLUDED.sequence, EXCLUDED.state, EXCLUDED.button_text)",
expectedArgs: []interface{}{
"agg-id",
"instance-id",
@@ -285,7 +285,7 @@ func TestMessageTextProjection_reduces(t *testing.T) {
executer: &testExecuter{
executions: []execution{
{
expectedStmt: "UPSERT INTO projections.message_texts (aggregate_id, instance_id, creation_date, change_date, sequence, state, type, language, footer_text) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9)",
expectedStmt: "INSERT INTO projections.message_texts (aggregate_id, instance_id, creation_date, change_date, sequence, state, type, language, footer_text) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9) ON CONFLICT (instance_id, aggregate_id, type, language) DO UPDATE SET (creation_date, change_date, sequence, state, footer_text) = (EXCLUDED.creation_date, EXCLUDED.change_date, EXCLUDED.sequence, EXCLUDED.state, EXCLUDED.footer_text)",
expectedArgs: []interface{}{
"agg-id",
"instance-id",
@@ -610,7 +610,7 @@ func TestMessageTextProjection_reduces(t *testing.T) {
executer: &testExecuter{
executions: []execution{
{
expectedStmt: "UPSERT INTO projections.message_texts (aggregate_id, instance_id, creation_date, change_date, sequence, state, type, language, title) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9)",
expectedStmt: "INSERT INTO projections.message_texts (aggregate_id, instance_id, creation_date, change_date, sequence, state, type, language, title) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9) ON CONFLICT (instance_id, aggregate_id, type, language) DO UPDATE SET (creation_date, change_date, sequence, state, title) = (EXCLUDED.creation_date, EXCLUDED.change_date, EXCLUDED.sequence, EXCLUDED.state, EXCLUDED.title)",
expectedArgs: []interface{}{
"agg-id",
"instance-id",
+8 -1
View File
@@ -152,7 +152,14 @@ func (p *messageTextProjection) reduceAdded(event eventstore.Event) (*handler.St
}
return crdb.NewUpsertStatement(
&templateEvent,
cols), nil
[]handler.Column{
handler.NewCol(MessageTextInstanceIDCol, nil),
handler.NewCol(MessageTextAggregateIDCol, nil),
handler.NewCol(MessageTextTypeCol, nil),
handler.NewCol(MessageTextLanguageCol, nil),
},
cols,
), nil
}
func (p *messageTextProjection) reduceRemoved(event eventstore.Event) (*handler.Statement, error) {
+2 -2
View File
@@ -12,7 +12,7 @@ import (
)
const (
OrgMemberProjectionTable = "projections.org_members"
OrgMemberProjectionTable = "projections.org_members2"
OrgMemberOrgIDCol = "org_id"
)
@@ -28,7 +28,7 @@ func newOrgMemberProjection(ctx context.Context, config crdb.StatementHandlerCon
crdb.NewTable(
append(memberColumns, crdb.NewColumn(OrgMemberOrgIDCol, crdb.ColumnTypeText)),
crdb.NewPrimaryKey(MemberInstanceID, OrgMemberOrgIDCol, MemberUserIDCol),
crdb.WithIndex(crdb.NewIndex("user_idx", []string{MemberUserIDCol})),
crdb.WithIndex(crdb.NewIndex("org_memb_user_idx", []string{MemberUserIDCol})),
),
)
p.StatementHandler = crdb.NewStatementHandler(ctx, config)
+9 -10
View File
@@ -3,8 +3,7 @@ package projection
import (
"testing"
"github.com/lib/pq"
"github.com/zitadel/zitadel/internal/database"
"github.com/zitadel/zitadel/internal/errors"
"github.com/zitadel/zitadel/internal/eventstore"
"github.com/zitadel/zitadel/internal/eventstore/handler"
@@ -44,10 +43,10 @@ func TestOrgMemberProjection_reduces(t *testing.T) {
executer: &testExecuter{
executions: []execution{
{
expectedStmt: "INSERT INTO projections.org_members (user_id, roles, creation_date, change_date, sequence, resource_owner, instance_id, org_id) VALUES ($1, $2, $3, $4, $5, $6, $7, $8)",
expectedStmt: "INSERT INTO projections.org_members2 (user_id, roles, creation_date, change_date, sequence, resource_owner, instance_id, org_id) VALUES ($1, $2, $3, $4, $5, $6, $7, $8)",
expectedArgs: []interface{}{
"user-id",
pq.StringArray{"role"},
database.StringArray{"role"},
anyArg{},
anyArg{},
uint64(15),
@@ -81,9 +80,9 @@ func TestOrgMemberProjection_reduces(t *testing.T) {
executer: &testExecuter{
executions: []execution{
{
expectedStmt: "UPDATE projections.org_members SET (roles, change_date, sequence) = ($1, $2, $3) WHERE (user_id = $4) AND (org_id = $5)",
expectedStmt: "UPDATE projections.org_members2 SET (roles, change_date, sequence) = ($1, $2, $3) WHERE (user_id = $4) AND (org_id = $5)",
expectedArgs: []interface{}{
pq.StringArray{"role", "changed"},
database.StringArray{"role", "changed"},
anyArg{},
uint64(15),
"user-id",
@@ -114,7 +113,7 @@ func TestOrgMemberProjection_reduces(t *testing.T) {
executer: &testExecuter{
executions: []execution{
{
expectedStmt: "DELETE FROM projections.org_members WHERE (user_id = $1) AND (org_id = $2)",
expectedStmt: "DELETE FROM projections.org_members2 WHERE (user_id = $1) AND (org_id = $2)",
expectedArgs: []interface{}{
"user-id",
"agg-id",
@@ -144,7 +143,7 @@ func TestOrgMemberProjection_reduces(t *testing.T) {
executer: &testExecuter{
executions: []execution{
{
expectedStmt: "DELETE FROM projections.org_members WHERE (user_id = $1) AND (org_id = $2)",
expectedStmt: "DELETE FROM projections.org_members2 WHERE (user_id = $1) AND (org_id = $2)",
expectedArgs: []interface{}{
"user-id",
"agg-id",
@@ -172,7 +171,7 @@ func TestOrgMemberProjection_reduces(t *testing.T) {
executer: &testExecuter{
executions: []execution{
{
expectedStmt: "DELETE FROM projections.org_members WHERE (user_id = $1)",
expectedStmt: "DELETE FROM projections.org_members2 WHERE (user_id = $1)",
expectedArgs: []interface{}{
"agg-id",
},
@@ -199,7 +198,7 @@ func TestOrgMemberProjection_reduces(t *testing.T) {
executer: &testExecuter{
executions: []execution{
{
expectedStmt: "DELETE FROM projections.org_members WHERE (org_id = $1)",
expectedStmt: "DELETE FROM projections.org_members2 WHERE (org_id = $1)",
expectedArgs: []interface{}{
"agg-id",
},
+2 -2
View File
@@ -12,7 +12,7 @@ import (
)
const (
ProjectProjectionTable = "projections.projects"
ProjectProjectionTable = "projections.projects2"
ProjectColumnID = "id"
ProjectColumnCreationDate = "creation_date"
@@ -52,7 +52,7 @@ func newProjectProjection(ctx context.Context, config crdb.StatementHandlerConfi
crdb.NewColumn(ProjectColumnPrivateLabelingSetting, crdb.ColumnTypeEnum),
},
crdb.NewPrimaryKey(ProjectColumnInstanceID, ProjectColumnID),
crdb.WithIndex(crdb.NewIndex("ro_idx", []string{ProjectColumnResourceOwner})),
crdb.WithIndex(crdb.NewIndex("project_ro_idx", []string{ProjectColumnResourceOwner})),
),
)
p.StatementHandler = crdb.NewStatementHandler(ctx, config)
+6 -7
View File
@@ -3,8 +3,7 @@ package projection
import (
"context"
"github.com/lib/pq"
"github.com/zitadel/zitadel/internal/database"
"github.com/zitadel/zitadel/internal/domain"
"github.com/zitadel/zitadel/internal/errors"
"github.com/zitadel/zitadel/internal/eventstore"
@@ -14,7 +13,7 @@ import (
)
const (
ProjectGrantProjectionTable = "projections.project_grants"
ProjectGrantProjectionTable = "projections.project_grants2"
ProjectGrantColumnGrantID = "grant_id"
ProjectGrantColumnCreationDate = "creation_date"
@@ -50,7 +49,7 @@ func newProjectGrantProjection(ctx context.Context, config crdb.StatementHandler
crdb.NewColumn(ProjectGrantColumnRoleKeys, crdb.ColumnTypeTextArray, crdb.Nullable()),
},
crdb.NewPrimaryKey(ProjectGrantColumnInstanceID, ProjectGrantColumnGrantID),
crdb.WithIndex(crdb.NewIndex("ro_idx", []string{ProjectGrantColumnResourceOwner})),
crdb.WithIndex(crdb.NewIndex("pg_ro_idx", []string{ProjectGrantColumnResourceOwner})),
crdb.WithIndex(crdb.NewIndex("granted_org_idx", []string{ProjectGrantColumnGrantedOrgID})),
),
)
@@ -113,7 +112,7 @@ func (p *projectGrantProjection) reduceProjectGrantAdded(event eventstore.Event)
handler.NewCol(ProjectGrantColumnState, domain.ProjectGrantStateActive),
handler.NewCol(ProjectGrantColumnSequence, e.Sequence()),
handler.NewCol(ProjectGrantColumnGrantedOrgID, e.GrantedOrgID),
handler.NewCol(ProjectGrantColumnRoleKeys, pq.StringArray(e.RoleKeys)),
handler.NewCol(ProjectGrantColumnRoleKeys, database.StringArray(e.RoleKeys)),
},
), nil
}
@@ -128,7 +127,7 @@ func (p *projectGrantProjection) reduceProjectGrantChanged(event eventstore.Even
[]handler.Column{
handler.NewCol(ProjectColumnChangeDate, e.CreationDate()),
handler.NewCol(ProjectGrantColumnSequence, e.Sequence()),
handler.NewCol(ProjectGrantColumnRoleKeys, pq.StringArray(e.RoleKeys)),
handler.NewCol(ProjectGrantColumnRoleKeys, database.StringArray(e.RoleKeys)),
},
[]handler.Condition{
handler.NewCond(ProjectGrantColumnGrantID, e.GrantID),
@@ -147,7 +146,7 @@ func (p *projectGrantProjection) reduceProjectGrantCascadeChanged(event eventsto
[]handler.Column{
handler.NewCol(ProjectGrantColumnChangeDate, e.CreationDate()),
handler.NewCol(ProjectGrantColumnSequence, e.Sequence()),
handler.NewCol(ProjectGrantColumnRoleKeys, pq.StringArray(e.RoleKeys)),
handler.NewCol(ProjectGrantColumnRoleKeys, database.StringArray(e.RoleKeys)),
},
[]handler.Condition{
handler.NewCond(ProjectGrantColumnGrantID, e.GrantID),
@@ -14,7 +14,7 @@ import (
)
const (
ProjectGrantMemberProjectionTable = "projections.project_grant_members"
ProjectGrantMemberProjectionTable = "projections.project_grant_members2"
ProjectGrantMemberProjectIDCol = "project_id"
ProjectGrantMemberGrantIDCol = "grant_id"
)
@@ -34,7 +34,7 @@ func newProjectGrantMemberProjection(ctx context.Context, config crdb.StatementH
crdb.NewColumn(ProjectGrantMemberGrantIDCol, crdb.ColumnTypeText),
),
crdb.NewPrimaryKey(MemberInstanceID, ProjectGrantMemberProjectIDCol, ProjectGrantMemberGrantIDCol, MemberUserIDCol),
crdb.WithIndex(crdb.NewIndex("user_idx", []string{MemberUserIDCol})),
crdb.WithIndex(crdb.NewIndex("proj_grant_memb_user_idx", []string{MemberUserIDCol})),
),
)
@@ -3,8 +3,7 @@ package projection
import (
"testing"
"github.com/lib/pq"
"github.com/zitadel/zitadel/internal/database"
"github.com/zitadel/zitadel/internal/errors"
"github.com/zitadel/zitadel/internal/eventstore"
"github.com/zitadel/zitadel/internal/eventstore/handler"
@@ -46,10 +45,10 @@ func TestProjectGrantMemberProjection_reduces(t *testing.T) {
executer: &testExecuter{
executions: []execution{
{
expectedStmt: "INSERT INTO projections.project_grant_members (user_id, roles, creation_date, change_date, sequence, resource_owner, instance_id, project_id, grant_id) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9)",
expectedStmt: "INSERT INTO projections.project_grant_members2 (user_id, roles, creation_date, change_date, sequence, resource_owner, instance_id, project_id, grant_id) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9)",
expectedArgs: []interface{}{
"user-id",
pq.StringArray{"role"},
database.StringArray{"role"},
anyArg{},
anyArg{},
uint64(15),
@@ -85,9 +84,9 @@ func TestProjectGrantMemberProjection_reduces(t *testing.T) {
executer: &testExecuter{
executions: []execution{
{
expectedStmt: "UPDATE projections.project_grant_members SET (roles, change_date, sequence) = ($1, $2, $3) WHERE (user_id = $4) AND (project_id = $5) AND (grant_id = $6)",
expectedStmt: "UPDATE projections.project_grant_members2 SET (roles, change_date, sequence) = ($1, $2, $3) WHERE (user_id = $4) AND (project_id = $5) AND (grant_id = $6)",
expectedArgs: []interface{}{
pq.StringArray{"role", "changed"},
database.StringArray{"role", "changed"},
anyArg{},
uint64(15),
"user-id",
@@ -120,7 +119,7 @@ func TestProjectGrantMemberProjection_reduces(t *testing.T) {
executer: &testExecuter{
executions: []execution{
{
expectedStmt: "DELETE FROM projections.project_grant_members WHERE (user_id = $1) AND (project_id = $2) AND (grant_id = $3)",
expectedStmt: "DELETE FROM projections.project_grant_members2 WHERE (user_id = $1) AND (project_id = $2) AND (grant_id = $3)",
expectedArgs: []interface{}{
"user-id",
"agg-id",
@@ -152,7 +151,7 @@ func TestProjectGrantMemberProjection_reduces(t *testing.T) {
executer: &testExecuter{
executions: []execution{
{
expectedStmt: "DELETE FROM projections.project_grant_members WHERE (user_id = $1) AND (project_id = $2) AND (grant_id = $3)",
expectedStmt: "DELETE FROM projections.project_grant_members2 WHERE (user_id = $1) AND (project_id = $2) AND (grant_id = $3)",
expectedArgs: []interface{}{
"user-id",
"agg-id",
@@ -181,7 +180,7 @@ func TestProjectGrantMemberProjection_reduces(t *testing.T) {
executer: &testExecuter{
executions: []execution{
{
expectedStmt: "DELETE FROM projections.project_grant_members WHERE (user_id = $1)",
expectedStmt: "DELETE FROM projections.project_grant_members2 WHERE (user_id = $1)",
expectedArgs: []interface{}{
"agg-id",
},
@@ -208,7 +207,7 @@ func TestProjectGrantMemberProjection_reduces(t *testing.T) {
executer: &testExecuter{
executions: []execution{
{
expectedStmt: "DELETE FROM projections.project_grant_members WHERE (resource_owner = $1)",
expectedStmt: "DELETE FROM projections.project_grant_members2 WHERE (resource_owner = $1)",
expectedArgs: []interface{}{
"agg-id",
},
@@ -235,7 +234,7 @@ func TestProjectGrantMemberProjection_reduces(t *testing.T) {
executer: &testExecuter{
executions: []execution{
{
expectedStmt: "DELETE FROM projections.project_grant_members WHERE (project_id = $1)",
expectedStmt: "DELETE FROM projections.project_grant_members2 WHERE (project_id = $1)",
expectedArgs: []interface{}{
"agg-id",
},
@@ -262,7 +261,7 @@ func TestProjectGrantMemberProjection_reduces(t *testing.T) {
executer: &testExecuter{
executions: []execution{
{
expectedStmt: "DELETE FROM projections.project_grant_members WHERE (grant_id = $1) AND (project_id = $2)",
expectedStmt: "DELETE FROM projections.project_grant_members2 WHERE (grant_id = $1) AND (project_id = $2)",
expectedArgs: []interface{}{
"grant-id",
"agg-id",
+11 -12
View File
@@ -3,8 +3,7 @@ package projection
import (
"testing"
"github.com/lib/pq"
"github.com/zitadel/zitadel/internal/database"
"github.com/zitadel/zitadel/internal/domain"
"github.com/zitadel/zitadel/internal/errors"
"github.com/zitadel/zitadel/internal/eventstore"
@@ -41,7 +40,7 @@ func TestProjectGrantProjection_reduces(t *testing.T) {
executer: &testExecuter{
executions: []execution{
{
expectedStmt: "DELETE FROM projections.project_grants WHERE (project_id = $1)",
expectedStmt: "DELETE FROM projections.project_grants2 WHERE (project_id = $1)",
expectedArgs: []interface{}{
"agg-id",
},
@@ -68,7 +67,7 @@ func TestProjectGrantProjection_reduces(t *testing.T) {
executer: &testExecuter{
executions: []execution{
{
expectedStmt: "DELETE FROM projections.project_grants WHERE (grant_id = $1) AND (project_id = $2)",
expectedStmt: "DELETE FROM projections.project_grants2 WHERE (grant_id = $1) AND (project_id = $2)",
expectedArgs: []interface{}{
"grant-id",
"agg-id",
@@ -96,7 +95,7 @@ func TestProjectGrantProjection_reduces(t *testing.T) {
executer: &testExecuter{
executions: []execution{
{
expectedStmt: "UPDATE projections.project_grants SET (change_date, sequence, state) = ($1, $2, $3) WHERE (grant_id = $4) AND (project_id = $5)",
expectedStmt: "UPDATE projections.project_grants2 SET (change_date, sequence, state) = ($1, $2, $3) WHERE (grant_id = $4) AND (project_id = $5)",
expectedArgs: []interface{}{
anyArg{},
uint64(15),
@@ -127,7 +126,7 @@ func TestProjectGrantProjection_reduces(t *testing.T) {
executer: &testExecuter{
executions: []execution{
{
expectedStmt: "UPDATE projections.project_grants SET (change_date, sequence, state) = ($1, $2, $3) WHERE (grant_id = $4) AND (project_id = $5)",
expectedStmt: "UPDATE projections.project_grants2 SET (change_date, sequence, state) = ($1, $2, $3) WHERE (grant_id = $4) AND (project_id = $5)",
expectedArgs: []interface{}{
anyArg{},
uint64(15),
@@ -158,11 +157,11 @@ func TestProjectGrantProjection_reduces(t *testing.T) {
executer: &testExecuter{
executions: []execution{
{
expectedStmt: "UPDATE projections.project_grants SET (change_date, sequence, granted_role_keys) = ($1, $2, $3) WHERE (grant_id = $4) AND (project_id = $5)",
expectedStmt: "UPDATE projections.project_grants2 SET (change_date, sequence, granted_role_keys) = ($1, $2, $3) WHERE (grant_id = $4) AND (project_id = $5)",
expectedArgs: []interface{}{
anyArg{},
uint64(15),
pq.StringArray{"admin", "user"},
database.StringArray{"admin", "user"},
"grant-id",
"agg-id",
},
@@ -189,11 +188,11 @@ func TestProjectGrantProjection_reduces(t *testing.T) {
executer: &testExecuter{
executions: []execution{
{
expectedStmt: "UPDATE projections.project_grants SET (change_date, sequence, granted_role_keys) = ($1, $2, $3) WHERE (grant_id = $4) AND (project_id = $5)",
expectedStmt: "UPDATE projections.project_grants2 SET (change_date, sequence, granted_role_keys) = ($1, $2, $3) WHERE (grant_id = $4) AND (project_id = $5)",
expectedArgs: []interface{}{
anyArg{},
uint64(15),
pq.StringArray{"admin", "user"},
database.StringArray{"admin", "user"},
"grant-id",
"agg-id",
},
@@ -220,7 +219,7 @@ func TestProjectGrantProjection_reduces(t *testing.T) {
executer: &testExecuter{
executions: []execution{
{
expectedStmt: "INSERT INTO projections.project_grants (grant_id, project_id, creation_date, change_date, resource_owner, instance_id, state, sequence, granted_org_id, granted_role_keys) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10)",
expectedStmt: "INSERT INTO projections.project_grants2 (grant_id, project_id, creation_date, change_date, resource_owner, instance_id, state, sequence, granted_org_id, granted_role_keys) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10)",
expectedArgs: []interface{}{
"grant-id",
"agg-id",
@@ -231,7 +230,7 @@ func TestProjectGrantProjection_reduces(t *testing.T) {
domain.ProjectGrantStateActive,
uint64(15),
"granted-org-id",
pq.StringArray{"admin", "user"},
database.StringArray{"admin", "user"},
},
},
},
+2 -2
View File
@@ -14,7 +14,7 @@ import (
)
const (
ProjectMemberProjectionTable = "projections.project_members"
ProjectMemberProjectionTable = "projections.project_members2"
ProjectMemberProjectIDCol = "project_id"
)
@@ -32,7 +32,7 @@ func newProjectMemberProjection(ctx context.Context, config crdb.StatementHandle
crdb.NewColumn(ProjectMemberProjectIDCol, crdb.ColumnTypeText),
),
crdb.NewPrimaryKey(MemberInstanceID, ProjectMemberProjectIDCol, MemberUserIDCol),
crdb.WithIndex(crdb.NewIndex("user_idx", []string{MemberUserIDCol})),
crdb.WithIndex(crdb.NewIndex("proj_memb_user_idx", []string{MemberUserIDCol})),
),
)
@@ -3,8 +3,7 @@ package projection
import (
"testing"
"github.com/lib/pq"
"github.com/zitadel/zitadel/internal/database"
"github.com/zitadel/zitadel/internal/errors"
"github.com/zitadel/zitadel/internal/eventstore"
"github.com/zitadel/zitadel/internal/eventstore/handler"
@@ -45,10 +44,10 @@ func TestProjectMemberProjection_reduces(t *testing.T) {
executer: &testExecuter{
executions: []execution{
{
expectedStmt: "INSERT INTO projections.project_members (user_id, roles, creation_date, change_date, sequence, resource_owner, instance_id, project_id) VALUES ($1, $2, $3, $4, $5, $6, $7, $8)",
expectedStmt: "INSERT INTO projections.project_members2 (user_id, roles, creation_date, change_date, sequence, resource_owner, instance_id, project_id) VALUES ($1, $2, $3, $4, $5, $6, $7, $8)",
expectedArgs: []interface{}{
"user-id",
pq.StringArray{"role"},
database.StringArray{"role"},
anyArg{},
anyArg{},
uint64(15),
@@ -82,9 +81,9 @@ func TestProjectMemberProjection_reduces(t *testing.T) {
executer: &testExecuter{
executions: []execution{
{
expectedStmt: "UPDATE projections.project_members SET (roles, change_date, sequence) = ($1, $2, $3) WHERE (user_id = $4) AND (project_id = $5)",
expectedStmt: "UPDATE projections.project_members2 SET (roles, change_date, sequence) = ($1, $2, $3) WHERE (user_id = $4) AND (project_id = $5)",
expectedArgs: []interface{}{
pq.StringArray{"role", "changed"},
database.StringArray{"role", "changed"},
anyArg{},
uint64(15),
"user-id",
@@ -115,7 +114,7 @@ func TestProjectMemberProjection_reduces(t *testing.T) {
executer: &testExecuter{
executions: []execution{
{
expectedStmt: "DELETE FROM projections.project_members WHERE (user_id = $1) AND (project_id = $2)",
expectedStmt: "DELETE FROM projections.project_members2 WHERE (user_id = $1) AND (project_id = $2)",
expectedArgs: []interface{}{
"user-id",
"agg-id",
@@ -145,7 +144,7 @@ func TestProjectMemberProjection_reduces(t *testing.T) {
executer: &testExecuter{
executions: []execution{
{
expectedStmt: "DELETE FROM projections.project_members WHERE (user_id = $1) AND (project_id = $2)",
expectedStmt: "DELETE FROM projections.project_members2 WHERE (user_id = $1) AND (project_id = $2)",
expectedArgs: []interface{}{
"user-id",
"agg-id",
@@ -173,7 +172,7 @@ func TestProjectMemberProjection_reduces(t *testing.T) {
executer: &testExecuter{
executions: []execution{
{
expectedStmt: "DELETE FROM projections.project_members WHERE (user_id = $1)",
expectedStmt: "DELETE FROM projections.project_members2 WHERE (user_id = $1)",
expectedArgs: []interface{}{
"agg-id",
},
@@ -200,7 +199,7 @@ func TestProjectMemberProjection_reduces(t *testing.T) {
executer: &testExecuter{
executions: []execution{
{
expectedStmt: "DELETE FROM projections.project_members WHERE (resource_owner = $1)",
expectedStmt: "DELETE FROM projections.project_members2 WHERE (resource_owner = $1)",
expectedArgs: []interface{}{
"agg-id",
},
@@ -227,7 +226,7 @@ func TestProjectMemberProjection_reduces(t *testing.T) {
executer: &testExecuter{
executions: []execution{
{
expectedStmt: "DELETE FROM projections.project_members WHERE (project_id = $1)",
expectedStmt: "DELETE FROM projections.project_members2 WHERE (project_id = $1)",
expectedArgs: []interface{}{
"agg-id",
},
+5 -5
View File
@@ -39,7 +39,7 @@ func TestProjectProjection_reduces(t *testing.T) {
executer: &testExecuter{
executions: []execution{
{
expectedStmt: "DELETE FROM projections.projects WHERE (id = $1)",
expectedStmt: "DELETE FROM projections.projects2 WHERE (id = $1)",
expectedArgs: []interface{}{
"agg-id",
},
@@ -66,7 +66,7 @@ func TestProjectProjection_reduces(t *testing.T) {
executer: &testExecuter{
executions: []execution{
{
expectedStmt: "UPDATE projections.projects SET (change_date, sequence, state) = ($1, $2, $3) WHERE (id = $4)",
expectedStmt: "UPDATE projections.projects2 SET (change_date, sequence, state) = ($1, $2, $3) WHERE (id = $4)",
expectedArgs: []interface{}{
anyArg{},
uint64(15),
@@ -96,7 +96,7 @@ func TestProjectProjection_reduces(t *testing.T) {
executer: &testExecuter{
executions: []execution{
{
expectedStmt: "UPDATE projections.projects SET (change_date, sequence, state) = ($1, $2, $3) WHERE (id = $4)",
expectedStmt: "UPDATE projections.projects2 SET (change_date, sequence, state) = ($1, $2, $3) WHERE (id = $4)",
expectedArgs: []interface{}{
anyArg{},
uint64(15),
@@ -126,7 +126,7 @@ func TestProjectProjection_reduces(t *testing.T) {
executer: &testExecuter{
executions: []execution{
{
expectedStmt: "UPDATE projections.projects SET (change_date, sequence, name, project_role_assertion, project_role_check, has_project_check, private_labeling_setting) = ($1, $2, $3, $4, $5, $6, $7) WHERE (id = $8)",
expectedStmt: "UPDATE projections.projects2 SET (change_date, sequence, name, project_role_assertion, project_role_check, has_project_check, private_labeling_setting) = ($1, $2, $3, $4, $5, $6, $7) WHERE (id = $8)",
expectedArgs: []interface{}{
anyArg{},
uint64(15),
@@ -178,7 +178,7 @@ func TestProjectProjection_reduces(t *testing.T) {
executer: &testExecuter{
executions: []execution{
{
expectedStmt: "INSERT INTO projections.projects (id, creation_date, change_date, resource_owner, instance_id, sequence, name, project_role_assertion, project_role_check, has_project_check, private_labeling_setting, state) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12)",
expectedStmt: "INSERT INTO projections.projects2 (id, creation_date, change_date, resource_owner, instance_id, sequence, name, project_role_assertion, project_role_check, has_project_check, private_labeling_setting, state) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12)",
expectedArgs: []interface{}{
"agg-id",
anyArg{},
@@ -11,7 +11,7 @@ import (
)
const (
SecretGeneratorProjectionTable = "projections.secret_generators"
SecretGeneratorProjectionTable = "projections.secret_generators2"
SecretGeneratorColumnGeneratorType = "generator_type"
SecretGeneratorColumnAggregateID = "aggregate_id"
@@ -38,7 +38,7 @@ func newSecretGeneratorProjection(ctx context.Context, config crdb.StatementHand
config.Reducers = p.reducers()
config.InitCheck = crdb.NewTableCheck(
crdb.NewTable([]*crdb.Column{
crdb.NewColumn(SecretGeneratorColumnGeneratorType, crdb.ColumnTypeText),
crdb.NewColumn(SecretGeneratorColumnGeneratorType, crdb.ColumnTypeEnum),
crdb.NewColumn(SecretGeneratorColumnAggregateID, crdb.ColumnTypeText),
crdb.NewColumn(SecretGeneratorColumnCreationDate, crdb.ColumnTypeTimestamp),
crdb.NewColumn(SecretGeneratorColumnChangeDate, crdb.ColumnTypeTimestamp),
@@ -40,7 +40,7 @@ func TestSecretGeneratorProjection_reduces(t *testing.T) {
executer: &testExecuter{
executions: []execution{
{
expectedStmt: "DELETE FROM projections.secret_generators WHERE (aggregate_id = $1) AND (generator_type = $2)",
expectedStmt: "DELETE FROM projections.secret_generators2 WHERE (aggregate_id = $1) AND (generator_type = $2)",
expectedArgs: []interface{}{
"agg-id",
domain.SecretGeneratorTypeInitCode,
@@ -68,7 +68,7 @@ func TestSecretGeneratorProjection_reduces(t *testing.T) {
executer: &testExecuter{
executions: []execution{
{
expectedStmt: "UPDATE projections.secret_generators SET (change_date, sequence, length, expiry, include_lower_letters, include_upper_letters, include_digits, include_symbols) = ($1, $2, $3, $4, $5, $6, $7, $8) WHERE (aggregate_id = $9) AND (generator_type = $10)",
expectedStmt: "UPDATE projections.secret_generators2 SET (change_date, sequence, length, expiry, include_lower_letters, include_upper_letters, include_digits, include_symbols) = ($1, $2, $3, $4, $5, $6, $7, $8) WHERE (aggregate_id = $9) AND (generator_type = $10)",
expectedArgs: []interface{}{
anyArg{},
uint64(15),
@@ -104,7 +104,7 @@ func TestSecretGeneratorProjection_reduces(t *testing.T) {
executer: &testExecuter{
executions: []execution{
{
expectedStmt: "INSERT INTO projections.secret_generators (aggregate_id, generator_type, creation_date, change_date, resource_owner, instance_id, sequence, length, expiry, include_lower_letters, include_upper_letters, include_digits, include_symbols) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13)",
expectedStmt: "INSERT INTO projections.secret_generators2 (aggregate_id, generator_type, creation_date, change_date, resource_owner, instance_id, sequence, length, expiry, include_lower_letters, include_upper_letters, include_digits, include_symbols) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13)",
expectedArgs: []interface{}{
"agg-id",
domain.SecretGeneratorTypeInitCode,
+11 -3
View File
@@ -17,7 +17,7 @@ type userProjection struct {
}
const (
UserTable = "projections.users2"
UserTable = "projections.users3"
UserHumanTable = UserTable + "_" + UserHumanSuffix
UserMachineTable = UserTable + "_" + UserMachineSuffix
UserNotifyTable = UserTable + "_" + UserNotifySuffix
@@ -89,8 +89,8 @@ func newUserProjection(ctx context.Context, config crdb.StatementHandlerConfig)
},
crdb.NewPrimaryKey(UserIDCol, UserInstanceIDCol),
crdb.WithIndex(crdb.NewIndex("username_idx", []string{UserUsernameCol})),
crdb.WithIndex(crdb.NewIndex("ro_idx", []string{UserResourceOwnerCol})),
crdb.WithConstraint(crdb.NewConstraint("id_unique", []string{UserIDCol})),
crdb.WithIndex(crdb.NewIndex("user_ro_idx", []string{UserResourceOwnerCol})),
crdb.WithConstraint(crdb.NewConstraint("user_id_unique", []string{UserIDCol})),
),
crdb.NewSuffixedTable([]*crdb.Column{
crdb.NewColumn(HumanUserIDCol, crdb.ColumnTypeText),
@@ -709,6 +709,10 @@ func (p *userProjection) reduceHumanPhoneVerified(event eventstore.Event) (*hand
crdb.WithTableSuffix(UserHumanSuffix),
),
crdb.AddCopyStatement(
[]handler.Column{
handler.NewCol(NotifyUserIDCol, nil),
handler.NewCol(NotifyInstanceIDCol, nil),
},
[]handler.Column{
handler.NewCol(NotifyUserIDCol, nil),
handler.NewCol(NotifyInstanceIDCol, nil),
@@ -799,6 +803,10 @@ func (p *userProjection) reduceHumanEmailVerified(event eventstore.Event) (*hand
crdb.WithTableSuffix(UserHumanSuffix),
),
crdb.AddCopyStatement(
[]handler.Column{
handler.NewCol(NotifyUserIDCol, nil),
handler.NewCol(NotifyInstanceIDCol, nil),
},
[]handler.Column{
handler.NewCol(NotifyUserIDCol, nil),
handler.NewCol(NotifyInstanceIDCol, nil),

Some files were not shown because too many files have changed in this diff Show More