mirror of
https://github.com/zitadel/zitadel.git
synced 2025-08-11 20:57:31 +00:00
perf(query): org permission function for resources (#9677)
# Which Problems Are Solved Classic permission checks execute for every returned row on resource based search APIs. Complete background and problem definition can be found here: https://github.com/zitadel/zitadel/issues/9188 # How the Problems Are Solved - PermissionClause function now support dynamic query building, so it supports multiple cases. - PermissionClause is applied to all list resources which support org level permissions. - Wrap permission logic into wrapper functions so we keep the business logic clean. # Additional Changes - Handle org ID optimization in the query package, so it is reusable for all resources, instead of extracting the filter in the API. - Cleanup and test system user conversion in the authz package. (context middleware) - Fix: `core_integration_db_up` make recipe was missing the postgres service. # Additional Context - Related to https://github.com/zitadel/zitadel/issues/9190
This commit is contained in:
@@ -113,6 +113,22 @@ func sessionCheckPermission(ctx context.Context, resourceOwner string, creator s
|
||||
return permissionCheck(ctx, domain.PermissionSessionRead, resourceOwner, "")
|
||||
}
|
||||
|
||||
func sessionsPermissionCheckV2(ctx context.Context, query sq.SelectBuilder, enabled bool) sq.SelectBuilder {
|
||||
if !enabled {
|
||||
return query
|
||||
}
|
||||
return query.Where(PermissionClause(
|
||||
ctx,
|
||||
SessionColumnResourceOwner,
|
||||
domain.PermissionSessionRead,
|
||||
// Allow if user is creator
|
||||
OwnedRowsPermissionOption(SessionColumnCreator),
|
||||
// Allow if session belongs to the user
|
||||
OwnedRowsPermissionOption(SessionColumnUserID),
|
||||
ConnectionPermissionOption(SessionColumnUserAgentFingerprintID, authz.GetCtxData(ctx).AgentID),
|
||||
))
|
||||
}
|
||||
|
||||
func (q *SessionsSearchQueries) toQuery(query sq.SelectBuilder) sq.SelectBuilder {
|
||||
query = q.SearchRequest.toQuery(query)
|
||||
for _, q := range q.Queries {
|
||||
@@ -282,21 +298,23 @@ func (q *Queries) sessionByID(ctx context.Context, shouldTriggerBulk bool, id st
|
||||
}
|
||||
|
||||
func (q *Queries) SearchSessions(ctx context.Context, queries *SessionsSearchQueries, permissionCheck domain.PermissionCheck) (*Sessions, error) {
|
||||
sessions, err := q.searchSessions(ctx, queries)
|
||||
permissionCheckV2 := PermissionV2(ctx, permissionCheck)
|
||||
sessions, err := q.searchSessions(ctx, queries, permissionCheckV2)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if permissionCheck != nil {
|
||||
if permissionCheck != nil && !permissionCheckV2 {
|
||||
sessionsCheckPermission(ctx, sessions, permissionCheck)
|
||||
}
|
||||
return sessions, nil
|
||||
}
|
||||
|
||||
func (q *Queries) searchSessions(ctx context.Context, queries *SessionsSearchQueries) (sessions *Sessions, err error) {
|
||||
func (q *Queries) searchSessions(ctx context.Context, queries *SessionsSearchQueries, permissionCheckV2 bool) (sessions *Sessions, err error) {
|
||||
ctx, span := tracing.NewSpan(ctx)
|
||||
defer func() { span.EndWithError(err) }()
|
||||
|
||||
query, scan := prepareSessionsQuery()
|
||||
query = sessionsPermissionCheckV2(ctx, query, permissionCheckV2)
|
||||
stmt, args, err := queries.toQuery(query).
|
||||
Where(sq.Eq{
|
||||
SessionColumnInstanceID.identifier(): authz.GetInstance(ctx).InstanceID(),
|
||||
|
Reference in New Issue
Block a user