zitadel/internal/query/projection/user_schema.go
Livio Spring 7494a7b6d9
feat(api): add possibility to retrieve user schemas (#7614)
This PR extends the user schema service (V3 API) with the possibility to ListUserSchemas and GetUserSchemaByID.
The previously started guide is extended to demonstrate how to retrieve the schema(s) and notes the generated revision property.
2024-03-22 13:26:13 +00:00

204 lines
6.2 KiB
Go

package projection
import (
"context"
"github.com/zitadel/zitadel/internal/domain"
"github.com/zitadel/zitadel/internal/eventstore"
old_handler "github.com/zitadel/zitadel/internal/eventstore/handler"
"github.com/zitadel/zitadel/internal/eventstore/handler/v2"
"github.com/zitadel/zitadel/internal/repository/instance"
"github.com/zitadel/zitadel/internal/repository/user/schema"
)
const (
UserSchemaTable = "projections.user_schemas"
UserSchemaIDCol = "id"
UserSchemaChangeDateCol = "change_date"
UserSchemaSequenceCol = "sequence"
UserSchemaInstanceIDCol = "instance_id"
UserSchemaStateCol = "state"
UserSchemaTypeCol = "type"
UserSchemaRevisionCol = "revision"
UserSchemaSchemaCol = "schema"
UserSchemaPossibleAuthenticatorsCol = "possible_authenticators"
)
type userSchemaProjection struct{}
func newUserSchemaProjection(ctx context.Context, config handler.Config) *handler.Handler {
return handler.NewHandler(ctx, &config, new(userSchemaProjection))
}
func (*userSchemaProjection) Name() string {
return UserSchemaTable
}
func (*userSchemaProjection) Init() *old_handler.Check {
return handler.NewTableCheck(
handler.NewTable([]*handler.InitColumn{
handler.NewColumn(UserSchemaIDCol, handler.ColumnTypeText),
handler.NewColumn(UserSchemaChangeDateCol, handler.ColumnTypeTimestamp),
handler.NewColumn(UserSchemaSequenceCol, handler.ColumnTypeInt64),
handler.NewColumn(UserSchemaStateCol, handler.ColumnTypeEnum),
handler.NewColumn(UserSchemaInstanceIDCol, handler.ColumnTypeText),
handler.NewColumn(UserSchemaTypeCol, handler.ColumnTypeText),
handler.NewColumn(UserSchemaRevisionCol, handler.ColumnTypeInt64),
handler.NewColumn(UserSchemaSchemaCol, handler.ColumnTypeJSONB, handler.Nullable()),
handler.NewColumn(UserSchemaPossibleAuthenticatorsCol, handler.ColumnTypeEnumArray, handler.Nullable()),
},
handler.NewPrimaryKey(UserSchemaInstanceIDCol, UserSchemaIDCol),
),
)
}
func (p *userSchemaProjection) Reducers() []handler.AggregateReducer {
return []handler.AggregateReducer{
{
Aggregate: schema.AggregateType,
EventReducers: []handler.EventReducer{
{
Event: schema.CreatedType,
Reduce: p.reduceCreated,
},
{
Event: schema.UpdatedType,
Reduce: p.reduceUpdated,
},
{
Event: schema.DeactivatedType,
Reduce: p.reduceDeactivated,
},
{
Event: schema.ReactivatedType,
Reduce: p.reduceReactivated,
},
{
Event: schema.DeletedType,
Reduce: p.reduceDeleted,
},
},
},
{
Aggregate: instance.AggregateType,
EventReducers: []handler.EventReducer{
{
Event: instance.InstanceRemovedEventType,
Reduce: reduceInstanceRemovedHelper(UserSchemaInstanceIDCol),
},
},
},
}
}
func (p *userSchemaProjection) reduceCreated(event eventstore.Event) (*handler.Statement, error) {
e, err := assertEvent[*schema.CreatedEvent](event)
if err != nil {
return nil, err
}
return handler.NewCreateStatement(
event,
[]handler.Column{
handler.NewCol(UserSchemaIDCol, event.Aggregate().ID),
handler.NewCol(UserSchemaChangeDateCol, event.CreatedAt()),
handler.NewCol(UserSchemaSequenceCol, event.Sequence()),
handler.NewCol(UserSchemaInstanceIDCol, event.Aggregate().InstanceID),
handler.NewCol(UserSchemaStateCol, domain.UserSchemaStateActive),
handler.NewCol(UserSchemaTypeCol, e.SchemaType),
handler.NewCol(UserSchemaRevisionCol, 1),
handler.NewCol(UserSchemaSchemaCol, e.Schema),
handler.NewCol(UserSchemaPossibleAuthenticatorsCol, e.PossibleAuthenticators),
},
), nil
}
func (p *userSchemaProjection) reduceUpdated(event eventstore.Event) (*handler.Statement, error) {
e, err := assertEvent[*schema.UpdatedEvent](event)
if err != nil {
return nil, err
}
cols := []handler.Column{
handler.NewCol(UserSchemaChangeDateCol, event.CreatedAt()),
handler.NewCol(UserSchemaSequenceCol, event.Sequence()),
}
if e.SchemaType != nil {
cols = append(cols, handler.NewCol(UserSchemaTypeCol, *e.SchemaType))
}
if len(e.Schema) > 0 {
cols = append(cols, handler.NewCol(UserSchemaSchemaCol, e.Schema))
cols = append(cols, handler.NewIncrementCol(UserSchemaRevisionCol, 1))
}
if len(e.PossibleAuthenticators) > 0 {
cols = append(cols, handler.NewCol(UserSchemaPossibleAuthenticatorsCol, e.PossibleAuthenticators))
}
return handler.NewUpdateStatement(
event,
cols,
[]handler.Condition{
handler.NewCond(UserSchemaIDCol, event.Aggregate().ID),
handler.NewCond(UserSchemaInstanceIDCol, event.Aggregate().InstanceID),
},
), nil
}
func (p *userSchemaProjection) reduceDeactivated(event eventstore.Event) (*handler.Statement, error) {
_, err := assertEvent[*schema.DeactivatedEvent](event)
if err != nil {
return nil, err
}
return handler.NewUpdateStatement(
event,
[]handler.Column{
handler.NewCol(UserSchemaChangeDateCol, event.CreatedAt()),
handler.NewCol(UserSchemaSequenceCol, event.Sequence()),
handler.NewCol(UserSchemaStateCol, domain.UserSchemaStateInactive),
},
[]handler.Condition{
handler.NewCond(UserSchemaIDCol, event.Aggregate().ID),
handler.NewCond(UserSchemaInstanceIDCol, event.Aggregate().InstanceID),
},
), nil
}
func (p *userSchemaProjection) reduceReactivated(event eventstore.Event) (*handler.Statement, error) {
_, err := assertEvent[*schema.ReactivatedEvent](event)
if err != nil {
return nil, err
}
return handler.NewUpdateStatement(
event,
[]handler.Column{
handler.NewCol(UserSchemaChangeDateCol, event.CreatedAt()),
handler.NewCol(UserSchemaSequenceCol, event.Sequence()),
handler.NewCol(UserSchemaStateCol, domain.UserSchemaStateActive),
},
[]handler.Condition{
handler.NewCond(UserSchemaIDCol, event.Aggregate().ID),
handler.NewCond(UserSchemaInstanceIDCol, event.Aggregate().InstanceID),
},
), nil
}
func (p *userSchemaProjection) reduceDeleted(event eventstore.Event) (*handler.Statement, error) {
_, err := assertEvent[*schema.DeletedEvent](event)
if err != nil {
return nil, err
}
return handler.NewDeleteStatement(
event,
[]handler.Condition{
handler.NewCond(UserSchemaIDCol, event.Aggregate().ID),
handler.NewCond(UserSchemaInstanceIDCol, event.Aggregate().InstanceID),
},
), nil
}