mirror of
https://github.com/zitadel/zitadel.git
synced 2025-08-11 21:17:32 +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:
@@ -106,12 +106,26 @@ func idpLinksCheckPermission(ctx context.Context, links *IDPUserLinks, permissio
|
||||
)
|
||||
}
|
||||
|
||||
func idpLinksPermissionCheckV2(ctx context.Context, query sq.SelectBuilder, enabled bool, queries *IDPUserLinksSearchQuery) sq.SelectBuilder {
|
||||
if !enabled {
|
||||
return query
|
||||
}
|
||||
return query.Where(PermissionClause(
|
||||
ctx,
|
||||
IDPUserLinkResourceOwnerCol,
|
||||
domain.PermissionUserRead,
|
||||
SingleOrgPermissionOption(queries.Queries),
|
||||
OwnedRowsPermissionOption(IDPUserLinkUserIDCol),
|
||||
))
|
||||
}
|
||||
|
||||
func (q *Queries) IDPUserLinks(ctx context.Context, queries *IDPUserLinksSearchQuery, permissionCheck domain.PermissionCheck) (idps *IDPUserLinks, err error) {
|
||||
links, err := q.idpUserLinks(ctx, queries, false)
|
||||
permissionCheckV2 := PermissionV2(ctx, permissionCheck)
|
||||
links, err := q.idpUserLinks(ctx, queries, permissionCheckV2)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if permissionCheck != nil && len(links.Links) > 0 {
|
||||
if permissionCheck != nil && len(links.Links) > 0 && !permissionCheckV2 {
|
||||
// when userID for query is provided, only one check has to be done
|
||||
if queries.hasUserID() {
|
||||
if err := userCheckPermission(ctx, links.Links[0].ResourceOwner, links.Links[0].UserID, permissionCheck); err != nil {
|
||||
@@ -124,14 +138,15 @@ func (q *Queries) IDPUserLinks(ctx context.Context, queries *IDPUserLinksSearchQ
|
||||
return links, nil
|
||||
}
|
||||
|
||||
func (q *Queries) idpUserLinks(ctx context.Context, queries *IDPUserLinksSearchQuery, withOwnerRemoved bool) (idps *IDPUserLinks, err error) {
|
||||
func (q *Queries) idpUserLinks(ctx context.Context, queries *IDPUserLinksSearchQuery, permissionCheckV2 bool) (idps *IDPUserLinks, err error) {
|
||||
ctx, span := tracing.NewSpan(ctx)
|
||||
defer func() { span.EndWithError(err) }()
|
||||
|
||||
query, scan := prepareIDPUserLinksQuery()
|
||||
eq := sq.Eq{IDPUserLinkInstanceIDCol.identifier(): authz.GetInstance(ctx).InstanceID()}
|
||||
if !withOwnerRemoved {
|
||||
eq[IDPUserLinkOwnerRemovedCol.identifier()] = false
|
||||
query = idpLinksPermissionCheckV2(ctx, query, permissionCheckV2, queries)
|
||||
eq := sq.Eq{
|
||||
IDPUserLinkInstanceIDCol.identifier(): authz.GetInstance(ctx).InstanceID(),
|
||||
IDPUserLinkOwnerRemovedCol.identifier(): false,
|
||||
}
|
||||
stmt, args, err := queries.toQuery(query).Where(eq).ToSql()
|
||||
if err != nil {
|
||||
|
Reference in New Issue
Block a user