mirror of
https://github.com/zitadel/zitadel.git
synced 2025-08-11 19:07:30 +00:00
feat: option to disallow public org registration (#6917)
* feat: return 404 or 409 if org reg disallowed * fix: system limit permissions * feat: add iam limits api * feat: disallow public org registrations on default instance * add integration test * test: integration * fix test * docs: describe public org registrations * avoid updating docs deps * fix system limits integration test * silence integration tests * fix linting * ignore strange linter complaints * review * improve reset properties naming * redefine the api * use restrictions aggregate * test query * simplify and test projection * test commands * fix unit tests * move integration test * support restrictions on default instance * also test GetRestrictions * self review * lint * abstract away resource owner * fix tests * lint
This commit is contained in:
@@ -119,7 +119,7 @@ func NewUpsertStatement(event eventstore.Event, conflictCols []Column, values []
|
||||
config.err = ErrNoValues
|
||||
}
|
||||
|
||||
updateCols, updateVals := getUpdateCols(cols, conflictTarget)
|
||||
updateCols, updateVals := getUpdateCols(values, conflictTarget)
|
||||
if len(updateCols) == 0 || len(updateVals) == 0 {
|
||||
config.err = ErrNoValues
|
||||
}
|
||||
@@ -141,17 +141,38 @@ func NewUpsertStatement(event eventstore.Event, conflictCols []Column, values []
|
||||
return NewStatement(event, exec(config, q, opts))
|
||||
}
|
||||
|
||||
func getUpdateCols(cols, conflictTarget []string) (updateCols, updateVals []string) {
|
||||
var _ ValueContainer = (*onlySetValueOnInsert)(nil)
|
||||
|
||||
type onlySetValueOnInsert struct {
|
||||
Table string
|
||||
Value interface{}
|
||||
}
|
||||
|
||||
func (c *onlySetValueOnInsert) GetValue() interface{} {
|
||||
return c.Value
|
||||
}
|
||||
|
||||
func OnlySetValueOnInsert(table string, value interface{}) *onlySetValueOnInsert {
|
||||
return &onlySetValueOnInsert{
|
||||
Table: table,
|
||||
Value: value,
|
||||
}
|
||||
}
|
||||
|
||||
func getUpdateCols(cols []Column, 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 i := len(cols) - 1; i >= 0; i-- {
|
||||
col := cols[i]
|
||||
table := "EXCLUDED"
|
||||
if onlyOnInsert, ok := col.Value.(*onlySetValueOnInsert); ok {
|
||||
table = onlyOnInsert.Table
|
||||
}
|
||||
updateCols[i] = col.Name
|
||||
updateVals[i] = table + "." + col.Name
|
||||
for _, conflict := range conflictTarget {
|
||||
if conflict == updateCols[i] {
|
||||
if conflict == col.Name {
|
||||
copy(updateCols[i:], updateCols[i+1:])
|
||||
updateCols[len(updateCols)-1] = ""
|
||||
updateCols = updateCols[:len(updateCols)-1]
|
||||
@@ -383,6 +404,10 @@ func NewCopyStatement(event eventstore.Event, conflictCols, from, to []Column, n
|
||||
return NewStatement(event, exec(config, q, opts))
|
||||
}
|
||||
|
||||
type ValueContainer interface {
|
||||
GetValue() interface{}
|
||||
}
|
||||
|
||||
func columnsToQuery(cols []Column) (names []string, parameters []string, values []interface{}) {
|
||||
names = make([]string, len(cols))
|
||||
values = make([]interface{}, len(cols))
|
||||
@@ -390,10 +415,13 @@ func columnsToQuery(cols []Column) (names []string, parameters []string, values
|
||||
var parameterIndex int
|
||||
for i, col := range cols {
|
||||
names[i] = col.Name
|
||||
if c, ok := col.Value.(Column); ok {
|
||||
switch c := col.Value.(type) {
|
||||
case Column:
|
||||
parameters[i] = c.Name
|
||||
continue
|
||||
} else {
|
||||
case ValueContainer:
|
||||
values[parameterIndex] = c.GetValue()
|
||||
default:
|
||||
values[parameterIndex] = col.Value
|
||||
}
|
||||
parameters[i] = "$" + strconv.Itoa(parameterIndex+1)
|
||||
|
@@ -358,7 +358,7 @@ func TestNewUpsertStatement(t *testing.T) {
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "correct UPDATE single col",
|
||||
name: "correct *onlySetValueOnInsert",
|
||||
args: args{
|
||||
table: "my_table",
|
||||
event: &testEvent{
|
||||
@@ -372,11 +372,18 @@ func TestNewUpsertStatement(t *testing.T) {
|
||||
values: []Column{
|
||||
{
|
||||
Name: "col1",
|
||||
Value: "val",
|
||||
Value: "val1",
|
||||
},
|
||||
{
|
||||
Name: "col2",
|
||||
Value: "val",
|
||||
Value: "val2",
|
||||
},
|
||||
{
|
||||
Name: "col3",
|
||||
Value: &onlySetValueOnInsert{
|
||||
Table: "some.table",
|
||||
Value: "val3",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
@@ -388,8 +395,53 @@ func TestNewUpsertStatement(t *testing.T) {
|
||||
executer: &wantExecuter{
|
||||
params: []params{
|
||||
{
|
||||
query: "INSERT INTO my_table (col1, col2) VALUES ($1, $2) ON CONFLICT (col1) DO UPDATE SET col2 = EXCLUDED.col2",
|
||||
args: []interface{}{"val", "val"},
|
||||
query: "INSERT INTO my_table (col1, col2, col3) VALUES ($1, $2, $3) ON CONFLICT (col1) DO UPDATE SET (col2, col3) = (EXCLUDED.col2, some.table.col3)",
|
||||
args: []interface{}{"val1", "val2", "val3"},
|
||||
},
|
||||
},
|
||||
shouldExecute: true,
|
||||
},
|
||||
isErr: func(err error) bool {
|
||||
return err == nil
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "correct all *onlySetValueOnInsert",
|
||||
args: args{
|
||||
table: "my_table",
|
||||
event: &testEvent{
|
||||
aggregateType: "agg",
|
||||
sequence: 1,
|
||||
previousSequence: 0,
|
||||
},
|
||||
conflictCols: []Column{
|
||||
NewCol("col1", nil),
|
||||
},
|
||||
values: []Column{
|
||||
{
|
||||
Name: "col1",
|
||||
Value: "val1",
|
||||
},
|
||||
{
|
||||
Name: "col2",
|
||||
Value: &onlySetValueOnInsert{
|
||||
Table: "some.table",
|
||||
Value: "val2",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
want: want{
|
||||
table: "my_table",
|
||||
aggregateType: "agg",
|
||||
sequence: 1,
|
||||
previousSequence: 1,
|
||||
executer: &wantExecuter{
|
||||
params: []params{
|
||||
{
|
||||
query: "INSERT INTO my_table (col1, col2) VALUES ($1, $2) ON CONFLICT (col1) DO UPDATE SET col2 = some.table.col2",
|
||||
args: []interface{}{"val1", "val2"},
|
||||
},
|
||||
},
|
||||
shouldExecute: true,
|
||||
|
Reference in New Issue
Block a user