mirror of
https://github.com/zitadel/zitadel.git
synced 2025-08-11 20:37:30 +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:
@@ -104,6 +104,18 @@ func authMethodsCheckPermission(ctx context.Context, methods *AuthMethods, permi
|
||||
)
|
||||
}
|
||||
|
||||
func userAuthMethodPermissionCheckV2(ctx context.Context, query sq.SelectBuilder, enabled bool) sq.SelectBuilder {
|
||||
if !enabled {
|
||||
return query
|
||||
}
|
||||
return query.Where(PermissionClause(
|
||||
ctx,
|
||||
UserAuthMethodColumnResourceOwner,
|
||||
domain.PermissionUserRead,
|
||||
OwnedRowsPermissionOption(UserIDCol),
|
||||
))
|
||||
}
|
||||
|
||||
type AuthMethod struct {
|
||||
UserID string
|
||||
CreationDate time.Time
|
||||
@@ -137,11 +149,12 @@ func (q *UserAuthMethodSearchQueries) hasUserID() bool {
|
||||
}
|
||||
|
||||
func (q *Queries) SearchUserAuthMethods(ctx context.Context, queries *UserAuthMethodSearchQueries, permissionCheck domain.PermissionCheck) (userAuthMethods *AuthMethods, err error) {
|
||||
methods, err := q.searchUserAuthMethods(ctx, queries)
|
||||
permissionCheckV2 := PermissionV2(ctx, permissionCheck)
|
||||
methods, err := q.searchUserAuthMethods(ctx, queries, permissionCheckV2)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if permissionCheck != nil && len(methods.AuthMethods) > 0 {
|
||||
if permissionCheck != nil && len(methods.AuthMethods) > 0 && !permissionCheckV2 {
|
||||
// when userID for query is provided, only one check has to be done
|
||||
if queries.hasUserID() {
|
||||
if err := userCheckPermission(ctx, methods.AuthMethods[0].ResourceOwner, methods.AuthMethods[0].UserID, permissionCheck); err != nil {
|
||||
@@ -154,11 +167,12 @@ func (q *Queries) SearchUserAuthMethods(ctx context.Context, queries *UserAuthMe
|
||||
return methods, nil
|
||||
}
|
||||
|
||||
func (q *Queries) searchUserAuthMethods(ctx context.Context, queries *UserAuthMethodSearchQueries) (userAuthMethods *AuthMethods, err error) {
|
||||
func (q *Queries) searchUserAuthMethods(ctx context.Context, queries *UserAuthMethodSearchQueries, permissionCheckV2 bool) (userAuthMethods *AuthMethods, err error) {
|
||||
ctx, span := tracing.NewSpan(ctx)
|
||||
defer func() { span.EndWithError(err) }()
|
||||
|
||||
query, scan := prepareUserAuthMethodsQuery()
|
||||
query = userAuthMethodPermissionCheckV2(ctx, query, permissionCheckV2)
|
||||
stmt, args, err := queries.toQuery(query).Where(sq.Eq{UserAuthMethodColumnInstanceID.identifier(): authz.GetInstance(ctx).InstanceID()}).ToSql()
|
||||
if err != nil {
|
||||
return nil, zerrors.ThrowInvalidArgument(err, "QUERY-j9NJd", "Errors.Query.InvalidRequest")
|
||||
|
Reference in New Issue
Block a user