Files
zitadel/backend/v3/storage/database/repository/session_metadata.go
T
Livio SpringandGitHub 4e6f68c511 feat(relational): implement session repository (#11109)
# Which Problems Are Solved

As part of going to a relation storage model, we need to implement the
repository for handling sessions and their events.

# How the Problems Are Solved

- Adds a migration step to create the necessary tables and types in the
database.
- Adds the repository implementation for sessions.
- Implements a projection handler for session events to handle the
events written by the old command handlers.
- Updates the `Session` type and `SessionRepository` interface:
  - added `CreatorID`
  - Adjusted `Delete` method to return amount of affected columns
  - Removed sub-repository clumns from the main interface
- Added `CreatorIDCondition`, `ExpirationCondition`, `ExistsFactor` and
`ExistsMetadata`
  - Removed `SetUserAgent`
- Methods of `SessionFactor` and `SessionChallenge` have been made
public
- fixed enumer on `SessionFactorType`
- Adds a `JSON` type to the repository package to easy can JSON columns,
resp. jsonb object inside a property of a `JSONArray` object.
- Adds a `NoChange` interface, which can be implemented to signal that a
`Change` interface implementation is not writing any changes to the
statement builder, e.g. `CTEChange`

# Additional Changes

- Fixes the operators enums. `TextOperations` had wrong comments and
`NumberOperations` additionally also had from comparisons.
- Fixes downgrade of migration step 008.

# Additional Context

- closes https://github.com/zitadel/zitadel/issues/10212
2026-01-06 08:08:11 +01:00

72 lines
2.4 KiB
Go

package repository
import "github.com/zitadel/zitadel/backend/v3/storage/database"
type sessionMetadata struct {
}
func (s sessionMetadata) qualifiedTableName() string {
return "zitadel.session_metadata"
}
func (s sessionMetadata) unqualifiedTableName() string {
return "session_metadata"
}
func (s sessionMetadata) PrimaryKeyColumns() []database.Column {
return []database.Column{
s.instanceIDColumn(),
s.sessionIDColumn(),
s.keyColumn(),
}
}
func (s sessionMetadata) instanceIDColumn() database.Column {
return database.NewColumn(s.unqualifiedTableName(), "instance_id")
}
func (s sessionMetadata) sessionIDColumn() database.Column {
return database.NewColumn(s.unqualifiedTableName(), "session_id")
}
func (s sessionMetadata) keyColumn() database.Column {
return database.NewColumn(s.unqualifiedTableName(), "key")
}
func (s sessionMetadata) valueColumn() database.Column {
return database.NewColumn(s.unqualifiedTableName(), "value")
}
// -------------------------------------------------------------
// conditions
// -------------------------------------------------------------
// PrimaryKeyCondition implements [domain.SessionMetadataRepository].
func (s sessionMetadata) PrimaryKeyCondition(instanceID string, sessionID string, key string) database.Condition {
return database.And(
s.InstanceIDCondition(instanceID),
s.SessionIDCondition(sessionID),
s.KeyCondition(database.TextOperationEqual, key),
)
}
// InstanceIDCondition implements [domain.SessionMetadataRepository].
func (s sessionMetadata) InstanceIDCondition(instanceID string) database.Condition {
return database.NewTextCondition(s.instanceIDColumn(), database.TextOperationEqual, instanceID)
}
// SessionIDCondition implements [domain.SessionMetadataRepository].
func (s sessionMetadata) SessionIDCondition(sessionID string) database.Condition {
return database.NewTextCondition(s.sessionIDColumn(), database.TextOperationEqual, sessionID)
}
// KeyCondition implements [domain.SessionMetadataRepository].
func (s sessionMetadata) KeyCondition(op database.TextOperation, key string) database.Condition {
return database.NewTextCondition(s.keyColumn(), op, key)
}
// ValueCondition implements [domain.SessionMetadataRepository].
func (s sessionMetadata) ValueCondition(op database.BytesOperation, value []byte) database.Condition {
return database.NewBytesCondition[[]byte](database.SHA256Column(s.valueColumn()), op, database.SHA256Value(value))
}