mirror of
https://github.com/andwati/zitadel.git
synced 2026-11-05 05:42:16 +00:00
# Which Problems Are Solved As part of moving the session API to the relational database, this PR adds the functionality to delete sessions through the session API v2 and the OIDC end_session endpoint. # How the Problems Are Solved - added `SessionDeleteCommand` in domain package - added possibility to pass the session token verifier to the domain package - use feature flag to switch API and OIDC usage from CQRS to relation table - added a `permissionCheck` condition to let permissions be checked directly in the repository / sql - part of it is still a placeholder until actual permission tables are done - added a `session_deleted` table to store (recently) deleted sessions to handle necessary checks / cases like delete my own session, which needs to be idempotent # Additional Changes Fixed `Matches` function of `existsCondition` (as missing an implementation) # Additional Context - closes #11037 --------- Co-authored-by: Stefan Benz <[email protected]>
157 lines
4.1 KiB
Go
157 lines
4.1 KiB
Go
package domain
|
|
|
|
import (
|
|
"context"
|
|
|
|
"github.com/zitadel/zitadel/backend/v3/storage/database"
|
|
"github.com/zitadel/zitadel/backend/v3/storage/eventstore"
|
|
)
|
|
|
|
type InvokeOpt func(*InvokeOpts)
|
|
|
|
func WithOrganizationRepo(repo OrganizationRepository) InvokeOpt {
|
|
return func(opts *InvokeOpts) {
|
|
opts.organizationRepo = repo
|
|
}
|
|
}
|
|
|
|
func WithOrganizationDomainRepo(repo OrganizationDomainRepository) InvokeOpt {
|
|
return func(opts *InvokeOpts) {
|
|
opts.organizationDomainRepo = repo
|
|
}
|
|
}
|
|
|
|
func WithProjectRepo(repo ProjectRepository) InvokeOpt {
|
|
return func(opts *InvokeOpts) {
|
|
opts.projectRepo = repo
|
|
}
|
|
}
|
|
|
|
func WithInstanceRepo(repo InstanceRepository) InvokeOpt {
|
|
return func(opts *InvokeOpts) {
|
|
opts.instanceRepo = repo
|
|
}
|
|
}
|
|
|
|
func WithInstanceDomainRepo(repo InstanceDomainRepository) InvokeOpt {
|
|
return func(opts *InvokeOpts) {
|
|
opts.instanceDomainRepo = repo
|
|
}
|
|
}
|
|
|
|
func WithSessionRepo(repo SessionRepository) InvokeOpt {
|
|
return func(opts *InvokeOpts) {
|
|
opts.sessionRepo = repo
|
|
}
|
|
}
|
|
|
|
func WithUserRepo(repo UserRepository) InvokeOpt {
|
|
return func(opts *InvokeOpts) {
|
|
opts.userRepo = repo
|
|
}
|
|
}
|
|
|
|
func WithLockoutSettingsRepo(repo LockoutSettingsRepository) InvokeOpt {
|
|
return func(opts *InvokeOpts) {
|
|
opts.lockoutSettingRepo = repo
|
|
}
|
|
}
|
|
|
|
func WithPermissionChecker(checker PermissionChecker) InvokeOpt {
|
|
return func(opts *InvokeOpts) {
|
|
opts.Permissions = checker
|
|
}
|
|
}
|
|
|
|
func WithIDPIntentRepo(repo IDPIntentRepository) InvokeOpt {
|
|
return func(opts *InvokeOpts) {
|
|
opts.idpIntentRepo = repo
|
|
}
|
|
}
|
|
|
|
// WithQueryExecutor sets the database client to be used by the command.
|
|
// If not set, the default pool will be used.
|
|
// This is mainly used for testing.
|
|
func WithQueryExecutor(executor database.QueryExecutor) InvokeOpt {
|
|
return func(opts *InvokeOpts) {
|
|
opts.db = executor
|
|
}
|
|
}
|
|
|
|
// WithLegacyEventstore sets the eventstore to be used by the command.
|
|
// If not set, the default one will be used.
|
|
// This is mainly used for testing.
|
|
func WithLegacyEventstore(es eventstore.LegacyEventstore) InvokeOpt {
|
|
return func(opts *InvokeOpts) {
|
|
opts.legacyEventstore = es
|
|
}
|
|
}
|
|
|
|
// WithSessionTokenDecryptor sets the decryptor for session tokens used by the commands.
|
|
// If not set, the default one will be used.
|
|
// This is mainly used for testing
|
|
func WithSessionTokenDecryptor(decryptor SessionTokenDecryptor) InvokeOpt {
|
|
return func(opts *InvokeOpts) {
|
|
opts.sessionTokenDecryptor = decryptor
|
|
}
|
|
}
|
|
|
|
// InvokeOpts are passed to each command
|
|
type InvokeOpts struct {
|
|
// db is the database client.
|
|
// [Executor]s MUST NOT access this field directly, use [InvokeOpts.DB] to access it.
|
|
//
|
|
// [Invoker]s may manipulate this field for example changing it to a transaction.
|
|
// It's their responsibility to restore it after ending the transaction.
|
|
db database.QueryExecutor
|
|
legacyEventstore eventstore.LegacyEventstore
|
|
Invoker Invoker
|
|
Permissions PermissionChecker
|
|
sessionTokenDecryptor SessionTokenDecryptor
|
|
organizationRepo OrganizationRepository
|
|
organizationDomainRepo OrganizationDomainRepository
|
|
projectRepo ProjectRepository
|
|
instanceRepo InstanceRepository
|
|
instanceDomainRepo InstanceDomainRepository
|
|
sessionRepo SessionRepository
|
|
userRepo UserRepository
|
|
idpIntentRepo IDPIntentRepository
|
|
|
|
// Settings repos
|
|
lockoutSettingRepo LockoutSettingsRepository
|
|
}
|
|
|
|
func (o *InvokeOpts) DB() database.QueryExecutor {
|
|
if o.db != nil {
|
|
return o.db
|
|
}
|
|
o.db = pool
|
|
return o.db
|
|
}
|
|
|
|
func (o *InvokeOpts) LegacyEventstore() eventstore.LegacyEventstore {
|
|
if o.legacyEventstore != nil {
|
|
return o.legacyEventstore
|
|
}
|
|
o.legacyEventstore = legacyEventstore
|
|
return o.legacyEventstore
|
|
}
|
|
|
|
func (o *InvokeOpts) Invoke(ctx context.Context, executor Executor) error {
|
|
if o.Invoker == nil {
|
|
return executor.Execute(ctx, o)
|
|
}
|
|
return o.Invoker.Invoke(ctx, executor, o)
|
|
}
|
|
|
|
func DefaultOpts(invoker Invoker) *InvokeOpts {
|
|
if invoker == nil {
|
|
invoker = &noopInvoker{}
|
|
}
|
|
return &InvokeOpts{
|
|
Invoker: invoker,
|
|
Permissions: &noopPermissionChecker{}, // prevent panics for now
|
|
sessionTokenDecryptor: sessionTokenDecryptor,
|
|
}
|
|
}
|