Merge branch 'main' into clean-transactional-propsal

This commit is contained in:
adlerhurst
2025-07-25 18:16:20 +02:00
987 changed files with 106221 additions and 36435 deletions

View File

@@ -0,0 +1,144 @@
package projection
import (
"context"
"crypto/md5"
"encoding/hex"
"fmt"
"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/org"
"github.com/zitadel/zitadel/internal/zerrors"
)
const (
HostedLoginTranslationTable = "projections.hosted_login_translations"
HostedLoginTranslationInstanceIDCol = "instance_id"
HostedLoginTranslationCreationDateCol = "creation_date"
HostedLoginTranslationChangeDateCol = "change_date"
HostedLoginTranslationAggregateIDCol = "aggregate_id"
HostedLoginTranslationAggregateTypeCol = "aggregate_type"
HostedLoginTranslationSequenceCol = "sequence"
HostedLoginTranslationLocaleCol = "locale"
HostedLoginTranslationFileCol = "file"
HostedLoginTranslationEtagCol = "etag"
)
type hostedLoginTranslationProjection struct{}
func newHostedLoginTranslationProjection(ctx context.Context, config handler.Config) *handler.Handler {
return handler.NewHandler(ctx, &config, new(hostedLoginTranslationProjection))
}
// Init implements [handler.initializer]
func (p *hostedLoginTranslationProjection) Init() *old_handler.Check {
return handler.NewTableCheck(
handler.NewTable([]*handler.InitColumn{
handler.NewColumn(HostedLoginTranslationInstanceIDCol, handler.ColumnTypeText),
handler.NewColumn(HostedLoginTranslationCreationDateCol, handler.ColumnTypeTimestamp),
handler.NewColumn(HostedLoginTranslationChangeDateCol, handler.ColumnTypeTimestamp),
handler.NewColumn(HostedLoginTranslationAggregateIDCol, handler.ColumnTypeText),
handler.NewColumn(HostedLoginTranslationAggregateTypeCol, handler.ColumnTypeText),
handler.NewColumn(HostedLoginTranslationSequenceCol, handler.ColumnTypeInt64),
handler.NewColumn(HostedLoginTranslationLocaleCol, handler.ColumnTypeText),
handler.NewColumn(HostedLoginTranslationFileCol, handler.ColumnTypeJSONB),
handler.NewColumn(HostedLoginTranslationEtagCol, handler.ColumnTypeText),
},
handler.NewPrimaryKey(
HostedLoginTranslationInstanceIDCol,
HostedLoginTranslationAggregateIDCol,
HostedLoginTranslationAggregateTypeCol,
HostedLoginTranslationLocaleCol,
),
),
)
}
func (hltp *hostedLoginTranslationProjection) Name() string {
return HostedLoginTranslationTable
}
func (hltp *hostedLoginTranslationProjection) Reducers() []handler.AggregateReducer {
return []handler.AggregateReducer{
{
Aggregate: org.AggregateType,
EventReducers: []handler.EventReducer{
{
Event: org.HostedLoginTranslationSet,
Reduce: hltp.reduceSet,
},
},
},
{
Aggregate: instance.AggregateType,
EventReducers: []handler.EventReducer{
{
Event: instance.HostedLoginTranslationSet,
Reduce: hltp.reduceSet,
},
},
},
}
}
func (hltp *hostedLoginTranslationProjection) reduceSet(e eventstore.Event) (*handler.Statement, error) {
switch e := e.(type) {
case *org.HostedLoginTranslationSetEvent:
orgEvent := *e
return handler.NewUpsertStatement(
&orgEvent,
[]handler.Column{
handler.NewCol(HostedLoginTranslationInstanceIDCol, nil),
handler.NewCol(HostedLoginTranslationAggregateIDCol, nil),
handler.NewCol(HostedLoginTranslationAggregateTypeCol, nil),
handler.NewCol(HostedLoginTranslationLocaleCol, nil),
},
[]handler.Column{
handler.NewCol(HostedLoginTranslationInstanceIDCol, orgEvent.Aggregate().InstanceID),
handler.NewCol(HostedLoginTranslationAggregateIDCol, orgEvent.Aggregate().ID),
handler.NewCol(HostedLoginTranslationAggregateTypeCol, orgEvent.Aggregate().Type),
handler.NewCol(HostedLoginTranslationCreationDateCol, handler.OnlySetValueOnInsert(HostedLoginTranslationTable, orgEvent.CreationDate())),
handler.NewCol(HostedLoginTranslationChangeDateCol, orgEvent.CreationDate()),
handler.NewCol(HostedLoginTranslationSequenceCol, orgEvent.Sequence()),
handler.NewCol(HostedLoginTranslationLocaleCol, orgEvent.Language),
handler.NewCol(HostedLoginTranslationFileCol, orgEvent.Translation),
handler.NewCol(HostedLoginTranslationEtagCol, hltp.computeEtag(orgEvent.Translation)),
},
), nil
case *instance.HostedLoginTranslationSetEvent:
instanceEvent := *e
return handler.NewUpsertStatement(
&instanceEvent,
[]handler.Column{
handler.NewCol(HostedLoginTranslationInstanceIDCol, nil),
handler.NewCol(HostedLoginTranslationAggregateIDCol, nil),
handler.NewCol(HostedLoginTranslationAggregateTypeCol, nil),
handler.NewCol(HostedLoginTranslationLocaleCol, nil),
},
[]handler.Column{
handler.NewCol(HostedLoginTranslationInstanceIDCol, instanceEvent.Aggregate().InstanceID),
handler.NewCol(HostedLoginTranslationAggregateIDCol, instanceEvent.Aggregate().ID),
handler.NewCol(HostedLoginTranslationAggregateTypeCol, instanceEvent.Aggregate().Type),
handler.NewCol(HostedLoginTranslationCreationDateCol, handler.OnlySetValueOnInsert(HostedLoginTranslationTable, instanceEvent.CreationDate())),
handler.NewCol(HostedLoginTranslationChangeDateCol, instanceEvent.CreationDate()),
handler.NewCol(HostedLoginTranslationSequenceCol, instanceEvent.Sequence()),
handler.NewCol(HostedLoginTranslationLocaleCol, instanceEvent.Language),
handler.NewCol(HostedLoginTranslationFileCol, instanceEvent.Translation),
handler.NewCol(HostedLoginTranslationEtagCol, hltp.computeEtag(instanceEvent.Translation)),
},
), nil
default:
return nil, zerrors.ThrowInvalidArgumentf(nil, "PROJE-AZshaa", "reduce.wrong.event.type %v", []eventstore.EventType{org.HostedLoginTranslationSet})
}
}
func (hltp *hostedLoginTranslationProjection) computeEtag(translation map[string]any) string {
hash := md5.Sum(fmt.Append(nil, translation))
return hex.EncodeToString(hash[:])
}

View File

@@ -64,14 +64,6 @@ func (*instanceFeatureProjection) Reducers() []handler.AggregateReducer {
Event: feature_v2.InstanceLoginDefaultOrgEventType,
Reduce: reduceInstanceSetFeature[bool],
},
{
Event: feature_v2.InstanceTriggerIntrospectionProjectionsEventType,
Reduce: reduceInstanceSetFeature[bool],
},
{
Event: feature_v2.InstanceLegacyIntrospectionEventType,
Reduce: reduceInstanceSetFeature[bool],
},
{
Event: feature_v2.InstanceUserSchemaEventType,
Reduce: reduceInstanceSetFeature[bool],
@@ -84,10 +76,6 @@ func (*instanceFeatureProjection) Reducers() []handler.AggregateReducer {
Event: feature_v2.InstanceImprovedPerformanceEventType,
Reduce: reduceInstanceSetFeature[[]feature.ImprovedPerformanceType],
},
{
Event: feature_v2.InstanceWebKeyEventType,
Reduce: reduceInstanceSetFeature[bool],
},
{
Event: feature_v2.InstanceDebugOIDCParentErrorEventType,
Reduce: reduceInstanceSetFeature[bool],

View File

@@ -26,7 +26,7 @@ func TestInstanceFeaturesProjection_reduces(t *testing.T) {
args: args{
event: getEvent(
testEvent(
feature_v2.InstanceLegacyIntrospectionEventType,
feature_v2.SystemUserSchemaEventType,
feature_v2.AggregateType,
[]byte(`{"value": true}`),
), eventstore.GenericEventMapper[feature_v2.SetEvent[bool]]),
@@ -41,7 +41,7 @@ func TestInstanceFeaturesProjection_reduces(t *testing.T) {
expectedStmt: "INSERT INTO projections.instance_features2 (instance_id, key, creation_date, change_date, sequence, value) VALUES ($1, $2, $3, $4, $5, $6) ON CONFLICT (instance_id, key) DO UPDATE SET (creation_date, change_date, sequence, value) = (projections.instance_features2.creation_date, EXCLUDED.change_date, EXCLUDED.sequence, EXCLUDED.value)",
expectedArgs: []interface{}{
"agg-id",
"legacy_introspection",
"user_schema",
anyArg{},
anyArg{},
uint64(15),

View File

@@ -88,6 +88,7 @@ var (
UserSchemaProjection *handler.Handler
WebKeyProjection *handler.Handler
DebugEventsProjection *handler.Handler
HostedLoginTranslationProjection *handler.Handler
ProjectGrantFields *handler.FieldHandler
OrgDomainVerifiedFields *handler.FieldHandler
@@ -183,6 +184,7 @@ func Create(ctx context.Context, sqlClient *database.DB, es handler.EventStore,
UserSchemaProjection = newUserSchemaProjection(ctx, applyCustomConfig(projectionConfig, config.Customizations["user_schemas"]))
WebKeyProjection = newWebKeyProjection(ctx, applyCustomConfig(projectionConfig, config.Customizations["web_keys"]))
DebugEventsProjection = newDebugEventsProjection(ctx, applyCustomConfig(projectionConfig, config.Customizations["debug_events"]))
HostedLoginTranslationProjection = newHostedLoginTranslationProjection(ctx, applyCustomConfig(projectionConfig, config.Customizations["hosted_login_translation"]))
ProjectGrantFields = newFillProjectGrantFields(applyCustomConfig(projectionConfig, config.Customizations[fieldsProjectGrant]))
OrgDomainVerifiedFields = newFillOrgDomainVerifiedFields(applyCustomConfig(projectionConfig, config.Customizations[fieldsOrgDomainVerified]))
@@ -363,5 +365,6 @@ func newProjectionsList() {
UserSchemaProjection,
WebKeyProjection,
DebugEventsProjection,
HostedLoginTranslationProjection,
}
}

View File

@@ -56,14 +56,6 @@ func (*systemFeatureProjection) Reducers() []handler.AggregateReducer {
Event: feature_v2.SystemLoginDefaultOrgEventType,
Reduce: reduceSystemSetFeature[bool],
},
{
Event: feature_v2.SystemTriggerIntrospectionProjectionsEventType,
Reduce: reduceSystemSetFeature[bool],
},
{
Event: feature_v2.SystemLegacyIntrospectionEventType,
Reduce: reduceSystemSetFeature[bool],
},
{
Event: feature_v2.SystemUserSchemaEventType,
Reduce: reduceSystemSetFeature[bool],

View File

@@ -24,7 +24,7 @@ func TestSystemFeaturesProjection_reduces(t *testing.T) {
args: args{
event: getEvent(
testEvent(
feature_v2.SystemLegacyIntrospectionEventType,
feature_v2.SystemUserSchemaEventType,
feature_v2.AggregateType,
[]byte(`{"value": true}`),
), eventstore.GenericEventMapper[feature_v2.SetEvent[bool]]),
@@ -38,7 +38,7 @@ func TestSystemFeaturesProjection_reduces(t *testing.T) {
{
expectedStmt: "INSERT INTO projections.system_features (key, creation_date, change_date, sequence, value) VALUES ($1, $2, $3, $4, $5) ON CONFLICT (key) DO UPDATE SET (creation_date, change_date, sequence, value) = (projections.system_features.creation_date, EXCLUDED.change_date, EXCLUDED.sequence, EXCLUDED.value)",
expectedArgs: []interface{}{
"legacy_introspection",
"user_schema",
anyArg{},
anyArg{},
uint64(15),