mirror of
https://github.com/zitadel/zitadel
synced 2024-11-22 00:39:36 +00:00
41ae35f2ef
# 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>
235 lines
6.2 KiB
Go
235 lines
6.2 KiB
Go
package query
|
|
|
|
import (
|
|
"context"
|
|
"database/sql"
|
|
"encoding/json"
|
|
"errors"
|
|
|
|
sq "github.com/Masterminds/squirrel"
|
|
|
|
"github.com/zitadel/zitadel/internal/api/authz"
|
|
"github.com/zitadel/zitadel/internal/database"
|
|
"github.com/zitadel/zitadel/internal/domain"
|
|
"github.com/zitadel/zitadel/internal/query/projection"
|
|
"github.com/zitadel/zitadel/internal/telemetry/tracing"
|
|
"github.com/zitadel/zitadel/internal/zerrors"
|
|
)
|
|
|
|
type UserSchemas struct {
|
|
SearchResponse
|
|
UserSchemas []*UserSchema
|
|
}
|
|
|
|
func (e *UserSchemas) SetState(s *State) {
|
|
e.State = s
|
|
}
|
|
|
|
type UserSchema struct {
|
|
domain.ObjectDetails
|
|
State domain.UserSchemaState
|
|
Type string
|
|
Revision uint32
|
|
Schema json.RawMessage
|
|
PossibleAuthenticators database.NumberArray[domain.AuthenticatorType]
|
|
}
|
|
|
|
type UserSchemaSearchQueries struct {
|
|
SearchRequest
|
|
Queries []SearchQuery
|
|
}
|
|
|
|
var (
|
|
userSchemaTable = table{
|
|
name: projection.UserSchemaTable,
|
|
instanceIDCol: projection.UserSchemaInstanceIDCol,
|
|
}
|
|
UserSchemaIDCol = Column{
|
|
name: projection.UserSchemaIDCol,
|
|
table: userSchemaTable,
|
|
}
|
|
UserSchemaCreationDateCol = Column{
|
|
name: projection.UserSchemaCreationDateCol,
|
|
table: userSchemaTable,
|
|
}
|
|
UserSchemaChangeDateCol = Column{
|
|
name: projection.UserSchemaChangeDateCol,
|
|
table: userSchemaTable,
|
|
}
|
|
UserSchemaInstanceIDCol = Column{
|
|
name: projection.UserSchemaInstanceIDCol,
|
|
table: userSchemaTable,
|
|
}
|
|
UserSchemaSequenceCol = Column{
|
|
name: projection.UserSchemaSequenceCol,
|
|
table: userSchemaTable,
|
|
}
|
|
UserSchemaStateCol = Column{
|
|
name: projection.UserSchemaStateCol,
|
|
table: userSchemaTable,
|
|
}
|
|
UserSchemaTypeCol = Column{
|
|
name: projection.UserSchemaTypeCol,
|
|
table: userSchemaTable,
|
|
}
|
|
UserSchemaRevisionCol = Column{
|
|
name: projection.UserSchemaRevisionCol,
|
|
table: userSchemaTable,
|
|
}
|
|
UserSchemaSchemaCol = Column{
|
|
name: projection.UserSchemaSchemaCol,
|
|
table: userSchemaTable,
|
|
}
|
|
UserSchemaPossibleAuthenticatorsCol = Column{
|
|
name: projection.UserSchemaPossibleAuthenticatorsCol,
|
|
table: userSchemaTable,
|
|
}
|
|
)
|
|
|
|
func (q *Queries) GetUserSchemaByID(ctx context.Context, id string) (userSchema *UserSchema, err error) {
|
|
ctx, span := tracing.NewSpan(ctx)
|
|
defer func() { span.EndWithError(err) }()
|
|
|
|
eq := sq.Eq{
|
|
UserSchemaIDCol.identifier(): id,
|
|
UserSchemaInstanceIDCol.identifier(): authz.GetInstance(ctx).InstanceID(),
|
|
}
|
|
|
|
query, scan := prepareUserSchemaQuery()
|
|
return genericRowQuery[*UserSchema](ctx, q.client, query.Where(eq), scan)
|
|
}
|
|
|
|
func (q *Queries) SearchUserSchema(ctx context.Context, queries *UserSchemaSearchQueries) (userSchemas *UserSchemas, err error) {
|
|
ctx, span := tracing.NewSpan(ctx)
|
|
defer func() { span.EndWithError(err) }()
|
|
|
|
eq := sq.Eq{
|
|
UserSchemaInstanceIDCol.identifier(): authz.GetInstance(ctx).InstanceID(),
|
|
}
|
|
|
|
query, scan := prepareUserSchemasQuery()
|
|
return genericRowsQueryWithState[*UserSchemas](ctx, q.client, userSchemaTable, combineToWhereStmt(query, queries.toQuery, eq), scan)
|
|
}
|
|
|
|
func (q *UserSchemaSearchQueries) toQuery(query sq.SelectBuilder) sq.SelectBuilder {
|
|
query = q.SearchRequest.toQuery(query)
|
|
for _, q := range q.Queries {
|
|
query = q.toQuery(query)
|
|
}
|
|
return query
|
|
}
|
|
|
|
func NewUserSchemaTypeSearchQuery(value string, comparison TextComparison) (SearchQuery, error) {
|
|
return NewTextQuery(UserSchemaTypeCol, value, comparison)
|
|
}
|
|
|
|
func NewUserSchemaIDSearchQuery(value string, comparison TextComparison) (SearchQuery, error) {
|
|
return NewTextQuery(UserSchemaIDCol, value, comparison)
|
|
}
|
|
|
|
func NewUserSchemaStateSearchQuery(value domain.UserSchemaState) (SearchQuery, error) {
|
|
return NewNumberQuery(UserSchemaStateCol, value, NumberEquals)
|
|
}
|
|
|
|
func prepareUserSchemaQuery() (sq.SelectBuilder, func(*sql.Row) (*UserSchema, error)) {
|
|
return sq.Select(
|
|
UserSchemaIDCol.identifier(),
|
|
UserSchemaCreationDateCol.identifier(),
|
|
UserSchemaChangeDateCol.identifier(),
|
|
UserSchemaSequenceCol.identifier(),
|
|
UserSchemaInstanceIDCol.identifier(),
|
|
UserSchemaStateCol.identifier(),
|
|
UserSchemaTypeCol.identifier(),
|
|
UserSchemaRevisionCol.identifier(),
|
|
UserSchemaSchemaCol.identifier(),
|
|
UserSchemaPossibleAuthenticatorsCol.identifier(),
|
|
).
|
|
From(userSchemaTable.identifier()).
|
|
PlaceholderFormat(sq.Dollar),
|
|
func(row *sql.Row) (*UserSchema, error) {
|
|
u := new(UserSchema)
|
|
var schema database.ByteArray[byte]
|
|
err := row.Scan(
|
|
&u.ID,
|
|
&u.CreationDate,
|
|
&u.EventDate,
|
|
&u.Sequence,
|
|
&u.ResourceOwner,
|
|
&u.State,
|
|
&u.Type,
|
|
&u.Revision,
|
|
&schema,
|
|
&u.PossibleAuthenticators,
|
|
)
|
|
|
|
if err != nil {
|
|
if errors.Is(err, sql.ErrNoRows) {
|
|
return nil, zerrors.ThrowNotFound(err, "QUERY-SAF3t", "Errors.UserSchema.NotExists")
|
|
}
|
|
return nil, zerrors.ThrowInternal(err, "QUERY-WRB2Q", "Errors.Internal")
|
|
}
|
|
|
|
u.Schema = json.RawMessage(schema)
|
|
|
|
return u, nil
|
|
}
|
|
}
|
|
|
|
func prepareUserSchemasQuery() (sq.SelectBuilder, func(*sql.Rows) (*UserSchemas, error)) {
|
|
return sq.Select(
|
|
UserSchemaIDCol.identifier(),
|
|
UserSchemaCreationDateCol.identifier(),
|
|
UserSchemaChangeDateCol.identifier(),
|
|
UserSchemaSequenceCol.identifier(),
|
|
UserSchemaInstanceIDCol.identifier(),
|
|
UserSchemaStateCol.identifier(),
|
|
UserSchemaTypeCol.identifier(),
|
|
UserSchemaRevisionCol.identifier(),
|
|
UserSchemaSchemaCol.identifier(),
|
|
UserSchemaPossibleAuthenticatorsCol.identifier(),
|
|
countColumn.identifier()).
|
|
From(userSchemaTable.identifier()).
|
|
PlaceholderFormat(sq.Dollar),
|
|
func(rows *sql.Rows) (*UserSchemas, error) {
|
|
schemas := make([]*UserSchema, 0)
|
|
var (
|
|
schema database.ByteArray[byte]
|
|
count uint64
|
|
)
|
|
|
|
for rows.Next() {
|
|
u := new(UserSchema)
|
|
err := rows.Scan(
|
|
&u.ID,
|
|
&u.CreationDate,
|
|
&u.EventDate,
|
|
&u.Sequence,
|
|
&u.ResourceOwner,
|
|
&u.State,
|
|
&u.Type,
|
|
&u.Revision,
|
|
&schema,
|
|
&u.PossibleAuthenticators,
|
|
&count,
|
|
)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
u.Schema = json.RawMessage(schema)
|
|
schemas = append(schemas, u)
|
|
}
|
|
|
|
if err := rows.Close(); err != nil {
|
|
return nil, zerrors.ThrowInternal(err, "QUERY-Lwj2e", "Errors.Query.CloseRows")
|
|
}
|
|
|
|
return &UserSchemas{
|
|
UserSchemas: schemas,
|
|
SearchResponse: SearchResponse{
|
|
Count: count,
|
|
},
|
|
}, nil
|
|
}
|
|
}
|