mirror of
https://github.com/andwati/zitadel.git
synced 2026-11-14 01:45:12 +00:00
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:
co-authored by
Livio Amstutz
Elio Bischof
parent
d6c9815945
commit
77b4fc5487
@@ -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))
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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, " ")
|
||||
}
|
||||
@@ -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)
|
||||
}
|
||||
@@ -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...)
|
||||
|
||||
|
||||
@@ -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 ""
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
@@ -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"}},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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"`
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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
@@ -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
@@ -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"},
|
||||
),
|
||||
},
|
||||
|
||||
@@ -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(
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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: "",
|
||||
|
||||
@@ -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{}
|
||||
|
||||
@@ -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
@@ -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) {
|
||||
|
||||
@@ -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
@@ -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) {
|
||||
|
||||
@@ -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
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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",
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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: "",
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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: "",
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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: "",
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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",
|
||||
},
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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),
|
||||
|
||||
@@ -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"
|
||||
)
|
||||
@@ -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",
|
||||
|
||||
@@ -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",
|
||||
|
||||
@@ -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",
|
||||
|
||||
@@ -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",
|
||||
},
|
||||
|
||||
@@ -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")),
|
||||
),
|
||||
|
||||
@@ -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),
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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",
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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",
|
||||
},
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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",
|
||||
|
||||
@@ -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"},
|
||||
},
|
||||
},
|
||||
},
|
||||
|
||||
@@ -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",
|
||||
},
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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
Reference in New Issue
Block a user