Files
zitadel/backend/v3/domain/invoke_option.go
T
8b90ddb0b5 feat(session): User Check API with relation tables (#11777)
# Which Problems Are Solved

As part of #11035 , this PR implements the user check logic for session
validation

# How the Problems Are Solved

- Add user and session repositories as invoke options, as well as their
mocks to prepare the ground for testing
- Implement the logic for the UserCheck command, following what has been
done on eventstore side
- Add a session permission chek interface to be used during the
`Validate()` part of the Commander

# Additional Context

This is a cherry-picked PR + minor changes, coming from
https://github.com/zitadel/zitadel/pull/11164
- Relates to #11035

---------

Co-authored-by: Silvan <[email protected]>
2026-03-10 09:10:31 +00:00

130 lines
3.3 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 WithPermissionChecker(checker PermissionChecker) InvokeOpt {
return func(opts *InvokeOpts) {
opts.Permissions = checker
}
}
// 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
}
}
// 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.
// Its their responsibility to restore it after ending the transaction.
db database.QueryExecutor
legacyEventstore eventstore.LegacyEventstore
Invoker Invoker
Permissions PermissionChecker
organizationRepo OrganizationRepository
organizationDomainRepo OrganizationDomainRepository
projectRepo ProjectRepository
instanceRepo InstanceRepository
instanceDomainRepo InstanceDomainRepository
sessionRepo SessionRepository
userRepo UserRepository
}
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
}
}