feat: add schema user create and remove (#8494)

# Which Problems Are Solved

Added functionality that user with a userschema can be created and
removed.

# How the Problems Are Solved

Added logic and moved APIs so that everything is API v3 conform.

# Additional Changes

- move of user and userschema API to resources folder
- changed testing and parameters
- some renaming

# Additional Context

closes #7308

---------

Co-authored-by: Elio Bischof <elio@zitadel.com>
This commit is contained in:
Stefan Benz
2024-08-28 21:46:45 +02:00
committed by GitHub
parent 90b908c361
commit 41ae35f2ef
61 changed files with 5766 additions and 2247 deletions

View File

@@ -12,9 +12,10 @@ import (
)
const (
UserSchemaTable = "projections.user_schemas"
UserSchemaTable = "projections.user_schemas1"
UserSchemaIDCol = "id"
UserSchemaCreationDateCol = "creation_date"
UserSchemaChangeDateCol = "change_date"
UserSchemaSequenceCol = "sequence"
UserSchemaInstanceIDCol = "instance_id"
@@ -39,6 +40,7 @@ func (*userSchemaProjection) Init() *old_handler.Check {
return handler.NewTableCheck(
handler.NewTable([]*handler.InitColumn{
handler.NewColumn(UserSchemaIDCol, handler.ColumnTypeText),
handler.NewColumn(UserSchemaCreationDateCol, handler.ColumnTypeTimestamp),
handler.NewColumn(UserSchemaChangeDateCol, handler.ColumnTypeTimestamp),
handler.NewColumn(UserSchemaSequenceCol, handler.ColumnTypeInt64),
handler.NewColumn(UserSchemaStateCol, handler.ColumnTypeEnum),
@@ -102,6 +104,7 @@ func (p *userSchemaProjection) reduceCreated(event eventstore.Event) (*handler.S
event,
[]handler.Column{
handler.NewCol(UserSchemaIDCol, event.Aggregate().ID),
handler.NewCol(UserSchemaCreationDateCol, handler.OnlySetValueOnInsert(UserSchemaTable, e.CreationDate())),
handler.NewCol(UserSchemaChangeDateCol, event.CreatedAt()),
handler.NewCol(UserSchemaSequenceCol, event.Sequence()),
handler.NewCol(UserSchemaInstanceIDCol, event.Aggregate().InstanceID),
@@ -130,7 +133,10 @@ func (p *userSchemaProjection) reduceUpdated(event eventstore.Event) (*handler.S
if len(e.Schema) > 0 {
cols = append(cols, handler.NewCol(UserSchemaSchemaCol, e.Schema))
cols = append(cols, handler.NewIncrementCol(UserSchemaRevisionCol, 1))
}
if e.SchemaRevision != nil {
cols = append(cols, handler.NewCol(UserSchemaRevisionCol, *e.SchemaRevision))
}
if len(e.PossibleAuthenticators) > 0 {

View File

@@ -39,10 +39,11 @@ func TestUserSchemaProjection_reduces(t *testing.T) {
executer: &testExecuter{
executions: []execution{
{
expectedStmt: "INSERT INTO projections.user_schemas (id, change_date, sequence, instance_id, state, type, revision, schema, possible_authenticators) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9)",
expectedStmt: "INSERT INTO projections.user_schemas1 (id, creation_date, change_date, sequence, instance_id, state, type, revision, schema, possible_authenticators) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10)",
expectedArgs: []interface{}{
"agg-id",
anyArg{},
anyArg{},
uint64(15),
"instance-id",
domain.UserSchemaStateActive,
@@ -61,9 +62,9 @@ func TestUserSchemaProjection_reduces(t *testing.T) {
args: args{
event: getEvent(
testEvent(
schema.CreatedType,
schema.UpdatedType,
schema.AggregateType,
[]byte(`{"schemaType": "type", "schema": {"$schema":"urn:zitadel:schema:v1","properties":{"name":{"type":"string","urn:zitadel:schema:permission":{"self":"rw"}}},"type":"object"}, "possibleAuthenticators": [1,2]}`),
[]byte(`{"schemaType": "type", "schemaRevision": 2, "schema": {"$schema":"urn:zitadel:schema:v1","properties":{"name":{"type":"string","urn:zitadel:schema:permission":{"self":"rw"}}},"type":"object"}, "possibleAuthenticators": [1,2]}`),
), eventstore.GenericEventMapper[schema.UpdatedEvent]),
},
reduce: (&userSchemaProjection{}).reduceUpdated,
@@ -73,13 +74,13 @@ func TestUserSchemaProjection_reduces(t *testing.T) {
executer: &testExecuter{
executions: []execution{
{
expectedStmt: "UPDATE projections.user_schemas SET (change_date, sequence, type, schema, revision, possible_authenticators) = ($1, $2, $3, $4, revision + $5, $6) WHERE (id = $7) AND (instance_id = $8)",
expectedStmt: "UPDATE projections.user_schemas1 SET (change_date, sequence, type, schema, revision, possible_authenticators) = ($1, $2, $3, $4, $5, $6) WHERE (id = $7) AND (instance_id = $8)",
expectedArgs: []interface{}{
anyArg{},
uint64(15),
"type",
json.RawMessage(`{"$schema":"urn:zitadel:schema:v1","properties":{"name":{"type":"string","urn:zitadel:schema:permission":{"self":"rw"}}},"type":"object"}`),
1,
uint64(2),
[]domain.AuthenticatorType{domain.AuthenticatorTypeUsername, domain.AuthenticatorTypePassword},
"agg-id",
"instance-id",
@@ -106,7 +107,7 @@ func TestUserSchemaProjection_reduces(t *testing.T) {
executer: &testExecuter{
executions: []execution{
{
expectedStmt: "UPDATE projections.user_schemas SET (change_date, sequence, state) = ($1, $2, $3) WHERE (id = $4) AND (instance_id = $5)",
expectedStmt: "UPDATE projections.user_schemas1 SET (change_date, sequence, state) = ($1, $2, $3) WHERE (id = $4) AND (instance_id = $5)",
expectedArgs: []interface{}{
anyArg{},
uint64(15),
@@ -136,7 +137,7 @@ func TestUserSchemaProjection_reduces(t *testing.T) {
executer: &testExecuter{
executions: []execution{
{
expectedStmt: "UPDATE projections.user_schemas SET (change_date, sequence, state) = ($1, $2, $3) WHERE (id = $4) AND (instance_id = $5)",
expectedStmt: "UPDATE projections.user_schemas1 SET (change_date, sequence, state) = ($1, $2, $3) WHERE (id = $4) AND (instance_id = $5)",
expectedArgs: []interface{}{
anyArg{},
uint64(15),
@@ -166,7 +167,7 @@ func TestUserSchemaProjection_reduces(t *testing.T) {
executer: &testExecuter{
executions: []execution{
{
expectedStmt: "DELETE FROM projections.user_schemas WHERE (id = $1) AND (instance_id = $2)",
expectedStmt: "DELETE FROM projections.user_schemas1 WHERE (id = $1) AND (instance_id = $2)",
expectedArgs: []interface{}{
"agg-id",
"instance-id",
@@ -193,7 +194,7 @@ func TestUserSchemaProjection_reduces(t *testing.T) {
executer: &testExecuter{
executions: []execution{
{
expectedStmt: "DELETE FROM projections.user_schemas WHERE (instance_id = $1)",
expectedStmt: "DELETE FROM projections.user_schemas1 WHERE (instance_id = $1)",
expectedArgs: []interface{}{
"agg-id",
},

View File

@@ -26,7 +26,6 @@ func (e *UserSchemas) SetState(s *State) {
}
type UserSchema struct {
ID string
domain.ObjectDetails
State domain.UserSchemaState
Type string
@@ -49,6 +48,10 @@ var (
name: projection.UserSchemaIDCol,
table: userSchemaTable,
}
UserSchemaCreationDateCol = Column{
name: projection.UserSchemaCreationDateCol,
table: userSchemaTable,
}
UserSchemaChangeDateCol = Column{
name: projection.UserSchemaChangeDateCol,
table: userSchemaTable,
@@ -131,6 +134,7 @@ func NewUserSchemaStateSearchQuery(value domain.UserSchemaState) (SearchQuery, e
func prepareUserSchemaQuery() (sq.SelectBuilder, func(*sql.Row) (*UserSchema, error)) {
return sq.Select(
UserSchemaIDCol.identifier(),
UserSchemaCreationDateCol.identifier(),
UserSchemaChangeDateCol.identifier(),
UserSchemaSequenceCol.identifier(),
UserSchemaInstanceIDCol.identifier(),
@@ -147,6 +151,7 @@ func prepareUserSchemaQuery() (sq.SelectBuilder, func(*sql.Row) (*UserSchema, er
var schema database.ByteArray[byte]
err := row.Scan(
&u.ID,
&u.CreationDate,
&u.EventDate,
&u.Sequence,
&u.ResourceOwner,
@@ -173,6 +178,7 @@ func prepareUserSchemaQuery() (sq.SelectBuilder, func(*sql.Row) (*UserSchema, er
func prepareUserSchemasQuery() (sq.SelectBuilder, func(*sql.Rows) (*UserSchemas, error)) {
return sq.Select(
UserSchemaIDCol.identifier(),
UserSchemaCreationDateCol.identifier(),
UserSchemaChangeDateCol.identifier(),
UserSchemaSequenceCol.identifier(),
UserSchemaInstanceIDCol.identifier(),
@@ -195,6 +201,7 @@ func prepareUserSchemasQuery() (sq.SelectBuilder, func(*sql.Rows) (*UserSchemas,
u := new(UserSchema)
err := rows.Scan(
&u.ID,
&u.CreationDate,
&u.EventDate,
&u.Sequence,
&u.ResourceOwner,

View File

@@ -15,19 +15,21 @@ import (
)
var (
prepareUserSchemasStmt = `SELECT projections.user_schemas.id,` +
` projections.user_schemas.change_date,` +
` projections.user_schemas.sequence,` +
` projections.user_schemas.instance_id,` +
` projections.user_schemas.state,` +
` projections.user_schemas.type,` +
` projections.user_schemas.revision,` +
` projections.user_schemas.schema,` +
` projections.user_schemas.possible_authenticators,` +
prepareUserSchemasStmt = `SELECT projections.user_schemas1.id,` +
` projections.user_schemas1.creation_date,` +
` projections.user_schemas1.change_date,` +
` projections.user_schemas1.sequence,` +
` projections.user_schemas1.instance_id,` +
` projections.user_schemas1.state,` +
` projections.user_schemas1.type,` +
` projections.user_schemas1.revision,` +
` projections.user_schemas1.schema,` +
` projections.user_schemas1.possible_authenticators,` +
` COUNT(*) OVER ()` +
` FROM projections.user_schemas`
prepareUserSchemasCols = []string{
"id",
"creation_date",
"change_date",
"sequence",
"instance_id",
@@ -39,18 +41,20 @@ var (
"count",
}
prepareUserSchemaStmt = `SELECT projections.user_schemas.id,` +
` projections.user_schemas.change_date,` +
` projections.user_schemas.sequence,` +
` projections.user_schemas.instance_id,` +
` projections.user_schemas.state,` +
` projections.user_schemas.type,` +
` projections.user_schemas.revision,` +
` projections.user_schemas.schema,` +
` projections.user_schemas.possible_authenticators` +
prepareUserSchemaStmt = `SELECT projections.user_schemas1.id,` +
` projections.user_schemas1.creation_date,` +
` projections.user_schemas1.change_date,` +
` projections.user_schemas1.sequence,` +
` projections.user_schemas1.instance_id,` +
` projections.user_schemas1.state,` +
` projections.user_schemas1.type,` +
` projections.user_schemas1.revision,` +
` projections.user_schemas1.schema,` +
` projections.user_schemas1.possible_authenticators` +
` FROM projections.user_schemas`
prepareUserSchemaCols = []string{
"id",
"creation_date",
"change_date",
"sequence",
"instance_id",
@@ -96,6 +100,7 @@ func Test_UserSchemaPrepares(t *testing.T) {
{
"id",
testNow,
testNow,
uint64(20211109),
"instance-id",
domain.UserSchemaStateActive,
@@ -113,9 +118,10 @@ func Test_UserSchemaPrepares(t *testing.T) {
},
UserSchemas: []*UserSchema{
{
ID: "id",
ObjectDetails: domain.ObjectDetails{
ID: "id",
EventDate: testNow,
CreationDate: testNow,
Sequence: 20211109,
ResourceOwner: "instance-id",
},
@@ -139,6 +145,7 @@ func Test_UserSchemaPrepares(t *testing.T) {
{
"id-1",
testNow,
testNow,
uint64(20211109),
"instance-id",
domain.UserSchemaStateActive,
@@ -150,6 +157,7 @@ func Test_UserSchemaPrepares(t *testing.T) {
{
"id-2",
testNow,
testNow,
uint64(20211110),
"instance-id",
domain.UserSchemaStateInactive,
@@ -167,9 +175,10 @@ func Test_UserSchemaPrepares(t *testing.T) {
},
UserSchemas: []*UserSchema{
{
ID: "id-1",
ObjectDetails: domain.ObjectDetails{
ID: "id-1",
EventDate: testNow,
CreationDate: testNow,
Sequence: 20211109,
ResourceOwner: "instance-id",
},
@@ -180,9 +189,10 @@ func Test_UserSchemaPrepares(t *testing.T) {
PossibleAuthenticators: database.NumberArray[domain.AuthenticatorType]{domain.AuthenticatorTypeUsername, domain.AuthenticatorTypePassword},
},
{
ID: "id-2",
ObjectDetails: domain.ObjectDetails{
ID: "id-2",
EventDate: testNow,
CreationDate: testNow,
Sequence: 20211110,
ResourceOwner: "instance-id",
},
@@ -240,6 +250,7 @@ func Test_UserSchemaPrepares(t *testing.T) {
[]driver.Value{
"id",
testNow,
testNow,
uint64(20211109),
"instance-id",
domain.UserSchemaStateActive,
@@ -251,9 +262,10 @@ func Test_UserSchemaPrepares(t *testing.T) {
),
},
object: &UserSchema{
ID: "id",
ObjectDetails: domain.ObjectDetails{
ID: "id",
EventDate: testNow,
CreationDate: testNow,
Sequence: 20211109,
ResourceOwner: "instance-id",
},