mirror of
https://github.com/zitadel/zitadel.git
synced 2025-08-12 00:07:36 +00:00
fix: generalise permission check for query user information (#8458)
# Which Problems Are Solved IDPLinks list and other list endpoints can provide you with empty results if the used user has no permission for the information. # How the Problems Are Solved List endpoints with subelements to users, and provided userIDQuery, will return a PermissionDenied error if no permission for the user exsists. # Additional Changes Function to check for permission is re-used from the GetUserByID. # Additional Context Closes #8451
This commit is contained in:
@@ -4,6 +4,7 @@ import (
|
||||
"context"
|
||||
"database/sql"
|
||||
"errors"
|
||||
"slices"
|
||||
"time"
|
||||
|
||||
sq "github.com/Masterminds/squirrel"
|
||||
@@ -98,27 +99,12 @@ type AuthMethods struct {
|
||||
AuthMethods []*AuthMethod
|
||||
}
|
||||
|
||||
func (l *AuthMethods) RemoveNoPermission(ctx context.Context, permissionCheck domain.PermissionCheck) {
|
||||
removableIndexes := make([]int, 0)
|
||||
for i := range l.AuthMethods {
|
||||
ctxData := authz.GetCtxData(ctx)
|
||||
if ctxData.UserID != l.AuthMethods[i].UserID {
|
||||
if err := permissionCheck(ctx, domain.PermissionUserRead, l.AuthMethods[i].ResourceOwner, l.AuthMethods[i].UserID); err != nil {
|
||||
removableIndexes = append(removableIndexes, i)
|
||||
}
|
||||
}
|
||||
}
|
||||
removed := 0
|
||||
for _, removeIndex := range removableIndexes {
|
||||
l.AuthMethods = removeAuthMethod(l.AuthMethods, removeIndex-removed)
|
||||
removed++
|
||||
}
|
||||
// reset count as some users could be removed
|
||||
l.SearchResponse.Count = uint64(len(l.AuthMethods))
|
||||
}
|
||||
|
||||
func removeAuthMethod(slice []*AuthMethod, s int) []*AuthMethod {
|
||||
return append(slice[:s], slice[s+1:]...)
|
||||
func authMethodsCheckPermission(ctx context.Context, methods *AuthMethods, permissionCheck domain.PermissionCheck) {
|
||||
methods.AuthMethods = slices.DeleteFunc(methods.AuthMethods,
|
||||
func(method *AuthMethod) bool {
|
||||
return userCheckPermission(ctx, method.ResourceOwner, method.UserID, permissionCheck) != nil
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
type AuthMethod struct {
|
||||
@@ -144,7 +130,34 @@ type UserAuthMethodSearchQueries struct {
|
||||
Queries []SearchQuery
|
||||
}
|
||||
|
||||
func (q *Queries) SearchUserAuthMethods(ctx context.Context, queries *UserAuthMethodSearchQueries, withOwnerRemoved bool) (userAuthMethods *AuthMethods, err error) {
|
||||
func (q *UserAuthMethodSearchQueries) hasUserID() bool {
|
||||
for _, query := range q.Queries {
|
||||
if query.Col() == UserAuthMethodColumnUserID {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func (q *Queries) SearchUserAuthMethods(ctx context.Context, queries *UserAuthMethodSearchQueries, permissionCheck domain.PermissionCheck) (userAuthMethods *AuthMethods, err error) {
|
||||
methods, err := q.searchUserAuthMethods(ctx, queries, false)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if permissionCheck != nil && len(methods.AuthMethods) > 0 {
|
||||
// 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 {
|
||||
return nil, err
|
||||
}
|
||||
} else {
|
||||
authMethodsCheckPermission(ctx, methods, permissionCheck)
|
||||
}
|
||||
}
|
||||
return methods, nil
|
||||
}
|
||||
|
||||
func (q *Queries) searchUserAuthMethods(ctx context.Context, queries *UserAuthMethodSearchQueries, withOwnerRemoved bool) (userAuthMethods *AuthMethods, err error) {
|
||||
ctx, span := tracing.NewSpan(ctx)
|
||||
defer func() { span.EndWithError(err) }()
|
||||
|
||||
|
Reference in New Issue
Block a user