IAM: Use the new authorizer for the User resource (#111479)

* Use the new authorizer for the User resource

* Use accessClient

* Update pkg/services/authz/rbac/mapper.go

Co-authored-by: Gabriel MABILLE <gamab@users.noreply.github.com>

---------

Co-authored-by: Gabriel MABILLE <gamab@users.noreply.github.com>
This commit is contained in:
Misi
2025-09-24 11:32:29 +02:00
committed by GitHub
co-authored by Gabriel MABILLE
parent 33ff6dbb9e
commit 54a347463e
7 changed files with 58 additions and 47 deletions
+2
View File
@@ -110,6 +110,8 @@ func NewMapperRegistry() MapperRegistry {
"folders": newResourceTranslation("folders", "uid", true, false),
},
"iam.grafana.app": {
// Users is a special case. We translate user permissions from id to uid based.
"users": newResourceTranslation("users", "uid", false, true),
"serviceaccounts": newResourceTranslation("serviceaccounts", "uid", false, true),
// Teams is a special case. We translate user permissions from id to uid based.
"teams": newResourceTranslation("teams", "uid", false, true),
+41
View File
@@ -119,6 +119,44 @@ func (s *Service) newTeamNameResolver(ctx context.Context, ns types.NamespaceInf
}, nil
}
func (s *Service) fetchUsers(ctx context.Context, ns types.NamespaceInfo) (map[int64]string, error) {
users, err := s.identityStore.ListUsers(ctx, ns, legacy.ListUserQuery{})
if err != nil {
return nil, fmt.Errorf("could not fetch users: %w", err)
}
userIDs := make(map[int64]string, len(users.Items))
for _, user := range users.Items {
userIDs[user.ID] = user.UID
}
return userIDs, nil
}
// Should return an error if we fail to build the resolver.
func (s *Service) newUserNameResolver(ctx context.Context, ns types.NamespaceInfo) (ScopeResolverFunc, error) {
return func(scope string) (string, error) {
userIDs, err := s.fetchUsers(ctx, ns)
if err != nil {
return "", fmt.Errorf("could not build resolver: %w", err)
}
userIDStr := strings.TrimPrefix(scope, "users:id:")
if userIDStr == "" {
return "", fmt.Errorf("user ID is empty")
}
if userIDStr == "*" {
return "users:uid:*", nil
}
userID, err := strconv.ParseInt(userIDStr, 10, 64)
if err != nil {
return "", fmt.Errorf("invalid user ID %s: %w", userIDStr, err)
}
if userName, ok := userIDs[userID]; ok {
return "users:uid:" + userName, nil
}
return "", fmt.Errorf("user ID %s not found", userIDStr)
}, nil
}
func permissionsDelegateResolverFunc(scope string) (string, error) {
if strings.TrimPrefix(scope, "permissions:type:") == "delegate" {
// The permissions:type:delegate scope does not have any discriminating value,
@@ -138,6 +176,9 @@ func (s *Service) nameResolver(ctx context.Context, ns types.NamespaceInfo, scop
if scopePrefix == "serviceaccounts:id:" {
return s.newServiceAccountNameResolver(ctx, ns)
}
if scopePrefix == "users:id:" {
return s.newUserNameResolver(ctx, ns)
}
// No resolver found for the given scope prefix.
return nil, nil
}