Access control / Authorization

HIGH
grafana/grafana
Commit: adc5f2542e79
Affected: 12.4.0 and earlier
2026-06-08 12:44 UTC

Description

The commit implements a config-driven, capability-based provisioning resource model and gates provisioning actions behind an enabled/disabled flag per resource. It replaces hardcoded, per-resource flags with a shared, config-derived set of resources and enforces authorization boundaries by: - Computing the effective set of resources from configuration (and registered extras) and exposing an Enabled/Disabled state per resource. - Routing requests for non-built-in groups to an aggregated API server only if a valid aggregated_server_url is configured, otherwise failing fast at startup. - Providing ResourceClients abstraction to ensure only enabled resources are acted upon by provisioning consumers (authorizer, folder-annotation writer, export, migrate, quota, etc.). - Rejecting write/act requests for resources that are not enabled or not supported, via startup validation and gate checks. - Surfacing the full declared set (including disabled ones) through the settings endpoint for frontend visibility, while ensuring the provisioning pipeline only processes enabled resources. This addresses an authorization/access-control risk where provisioning endpoints could be invoked for resources that should be disabled or misrouted to inappropriate API servers. The new gating and validation reduce exposure by ensuring that disabled resources cannot be acted upon and that routing is explicit and config-driven. Impact: prior to this patch, resource enablement was less explicit and could permit unintended access or misrouting under certain misconfigurations. The patch fixes this by introducing strict, config-driven controls and centralized resource gating.

Commit Details

Author: Roberto Jiménez Sánchez

Date: 2026-06-08 11:57 UTC

Message:

Provisioning: Capability-based config-driven supported resources (#125856) * Provisioning: Introduce flag-gated seam for supported resources Add SupportedResources and SupportsFolderAnnotationResources constructors that accept a featuremgmt.FeatureToggles checker and today return exactly the static SupportedProvisioningResources / SupportsFolderAnnotation sets. This establishes a single seam where future flag-gated resources can be appended, without changing current behaviour and without adding any new resource or feature flag. Migrate the pipeline consumers (export loop, export quota stats, migrate cleanup, authorizer, folder-annotation write path) to call the constructors instead of ranging over the package vars directly. The constructors tolerate a nil checker; no flag is consulted yet, so the effective set is identical to today. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * Provisioning: Make supported-resource set a ResourceClients concern Move the supported-resource set behind the ResourceClients interface and register extra types through the client factory instead of a flag-gated package function. - SupportedResources() and SupportsFolderAnnotationResources() are now methods on ResourceClients, returning the static base set plus any extra resources registered with the factory. - NewClientFactory / NewClientFactoryForMultipleAPIServers accept variadic SupportedResource registrations ({GVR, SupportsFolderAnnotation}); the factory threads them into the namespaced clients. - Consumers (authorizer, folder-annotation write path, export loop, quota stats, migrate cleanup) resolve the set through the clients they already hold; NewAuthorizer now takes a ResourceClients. No behaviour change today: with no registered extras the effective set equals the current static set. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * Provisioning: Collapse supported-resource accessors into one method Address review: precompute the supported set and expose it through a single interface method. - SupportedResources() now returns []SupportedResource (each carrying its folder-annotation flag), replacing the separate SupportsFolderAnnotationResources. - The merged base + registered set is computed once per factory and reused by every ResourceClients it produces, instead of merging on each call. - Consumers read .GVR / .SupportsFolderAnnotation off the entries; the folder-annotation write path uses a supportsFolderAnnotation helper. Adds a unit test for resources.go covering that the folder annotation is not written for resources that do not support folders (and the contrasting case that it is). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * Provisioning: Drive the supported-resource set from config Per the agreed design (git-ui-sync #1167), make the provisionable resource set config-driven with a sensible default, instead of a package-level var. This supersedes the per-resource feature-flag approach. - New [provisioning] keys: resources and folder_resources (both default to "dashboards | folders"), parsed into cfg.ProvisioningResources / cfg.ProvisioningFolderResources, mirroring allowed_targets / repository_types. - resources.BuildSupportedResources(resourceNames, folderResourceNames) maps the configured short names to the effective []SupportedResource (folder_resources is the subset that carries the folder annotation). Unknown names fail fast. - register.go builds the set from cfg and threads it through NewAPIBuilder into NewClientFactory; ResourceClients.SupportedResources() exposes it. With no config the factory falls back to the static SupportedProvisioningResources. - The effective set is surfaced on the settings endpoint (RepositoryViewList .availableResources) the way allowed_targets is, so the frontend can read it. Adding a resource is now a config change (folder-contained kinds go in both lists; org-scoped kinds only in resources) — no feature flag, no codegen. Kind/version are still resolved at runtime via discovery; folder-scope is supplied by folder_resources until it can be declared as kind metadata. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * Provisioning: Config carries the group+kind+folder triplet per resource Address review: drive the supported set entirely from config with no hardcoded name→GVR map, and identify resources by GroupKind (the API version and plural resource are resolved at runtime via discovery). - Each resource is declared in its own [provisioning.resources.<kind>.<group>] section (mirroring the per-resource [unified_storage.<resource>.<group>] convention), with a folder=<bool> key (extensible for future per-kind settings). cfg.ProvisioningResources holds the parsed {Group, Kind, SupportsFolderAnnotation} triplets; defaults to folders + dashboards. - resources.SupportedResource is now {schema.GroupKind, SupportsFolderAnnotation}. Consumers that need the plural resource (authorizer bulk checks + resolveFileGVR, export loop, migrate cleanup, export quota counter) resolve it via clients.ForKind. resolveFileGVR now matches on Group+Kind (a kind that shares a group is no longer mis-authorized as the first kind in that group). - The folder-annotation write path matches on the parsed GVK; no discovery needed. - The effective set is surfaced on the settings endpoint as "<kind>.<group>" identifiers (RepositoryViewList.availableResources), with an integration test. Folder support is configured per kind because, although unified storage tracks it (apistore.StorageOptions.EnableFolderSupport), it is server-side and not exposed via the API/discovery, so a remote provisioning operator cannot read it. Declaring folder-scope as discoverable kind metadata is a follow-up that would drop the config. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * Provisioning: Regenerate frontend API client for availableResources Run `yarn workspace @grafana/api-clients generate-apis` after adding RepositoryViewList.availableResources to the OpenAPI: regenerates the processed specs in @grafana/openapi and the RTK Query types in @grafana/api-clients, so the frontend client exposes the new field. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * Provisioning: Add extra-resources settings integration test + lint fix - Simplify routes.go to r.String() (staticcheck QF1008: drop redundant embedded GroupKind selector). - Add a ProvisioningResources option to testinfra.GrafanaOpts that writes [provisioning.resources.<kind>.<group>] sections. - Add an integration test asserting a resource added purely through configuration is surfaced on the settings endpoint (availableResources). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * Provisioning: Surface supported resources as enabled-aware triplets Address review on the settings endpoint shape: - availableResources is now a list of structured descriptors (SupportedResource) carrying group, kind, supportsFolderAnnotation and enabled — not opaque strings, and the folder field is clearly named. - Each [provisioning.resources.<kind>.<group>] section gains an enabled key (default true). Disabled resources are still declared and surfaced, but the pipeline (authorizer/export/migrate/quota) acts only on enabled ones — ResourceClients.SupportedResources() returns the enabled subset, while the settings endpoint surfaces the full declared set. - defaults.ini declares library panels and playlists as disabled by default (folders + dashboards remain enabled). Regenerated deepcopy, OpenAPI (Go + snapshots + @grafana/openapi specs) and the @grafana/api-clients RTK Query types. Adds/extends settings + client unit tests and the settings-endpoint integration tests (default set incl. disabled, and an extra resource added via config). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * Provisioning: Thread supported resources into the operator; rename to EnableFolderSupport - The operator (multi-API-server path) now builds the supported set from cfg.ProvisioningResources and passes it to NewClientFactoryForMultipleAPIServers, matching the in-process register.go wiring. - Rename the folder field/setting/JSON to EnableFolderSupport / enableFolderSupport, matching unified storage's apistore.StorageOptions.EnableFolderSupport and its camelCase config-key convention. Config key folder -> enableFolderSupport. Regenerated OpenAPI (Go + snapshots + @grafana/openapi) and the @grafana/api-clients RTK Query types. Updated unit tests. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * Provisioning: Config-driven strict-validation exemption + parser support gate; operator aggregated URL - Strict-validation exemption is now config-driven (P0.5): per-resource skipStrictValidation key (default false), replacing the hardcoded `gvr == DashboardResource` check in the parser. Dashboards keep the exemption via defaults.ini / the static fallback set. - The parser now rejects resources that are not enabled/supported with a ResourceValidationError, driven by the enabled supported set. - Operator: add an aggregated_server_url [operator] key; enabled resources whose API group has no dedicated server URL are served by the aggregated API server (fails loudly if a resource needs it and it is unset). The operator also passes SkipStrictValidation through. Unit tests: parser skip-strict-validation wiring and unsupported-resource rejection. (folder field/key already renamed to EnableFolderSupport/enableFolderSupport.) Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * Provisioning: Integration test for rejecting a disabled resource via files API Writing a playlist (declared but disabled by default) through the files endpoint is rejected as a client error referencing resource enablement/support. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * Provisioning: Operator explicitly skips built-in groups for the aggregated server Dashboards, folders and provisioning have dedicated server URLs, so skip those groups explicitly when assigning the aggregated API server URL to extra resources. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * Provisioning: Capability-based supported resources (shared grammar + parser) Reshape the config-driven supported set to a single shared grammar, parser and type, per the capability-based design: - One INI key `[provisioning] resources` = comma-separated tokens `<group>/<Kind>[:cap...]`. Capabilities (all default off): folder (folder-scoped), skipvalidation (skip validation), disabled (declared but inert). No more per-resource sections or enabled/folder bools. - resources.SupportedResource is now {schema.GroupKind; Capabilities sets.Set[string]} with IsActive()/IsValidated()/IsFolderScoped(); the shared resources.ParseSupportedResources([]string) parses+validates the whole list (strict, fails fast at startup) and is the single entry point for both OSS and the (future) enterprise MT side. - pkg/setting holds the raw []string token list (parsed in register.go and the operator, avoiding a setting->resources import cycle). - Settings endpoint surfaces availableResources as {group, kind, capabilities[]}. - defaults.ini: folders + dashboards (folder), library panels (folder, disabled), playlists (disabled). Regenerated deepcopy, OpenAPI (Go + snapshots + @grafana/openapi) and the @grafana/api-clients RTK Query types. Updated unit + integration tests. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * Provisioning: Revert parser support-gate and strict-validation changes The parser support-gate and per-resource skip-validation belong to separate draft PRs. Restore parser.go to its pre-PR state (dashboard exemption hack), drop the now-unused isSupportedResource/skipsStrictValidation helpers, and remove the tests that exercised the reverted gate. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * Provisioning: Re-attach availableResources $ref in OpenAPI post-processing The settings connector adds RepositoryViewList to the served spec via an empty ReferenceCallback, which strips array-item $refs. RepositoryViewList.items is manually re-attached; do the same for the new availableResources field so its SupportedResource element type resolves instead of degrading to {default:{}}. Regenerate the v0alpha1/v1beta1 OpenAPI snapshots to match. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * Provisioning: Surface availableResources as enabled/disabled, not capabilities The settings endpoint only needs to tell the frontend which declared resources are active and which are disabled, not the full internal capability set. Replace SupportedResource.capabilities[] with a single disabled bool on the API DTO (derived from the internal capability model via IsActive). Drop the now-unused CapabilityList helper, regenerate deepcopy/openapi/snapshots and the frontend RTK Query client, and update the settings integration test. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * Provisioning: Regenerate deepcopy/openapi via codegen Run hack/update-codegen.sh so the generated deepcopy and openapi for the SupportedResource disabled-bool change match canonical generator output (function ordering, shallow-copy for AvailableResources, violation list), fixing the CODEGEN_VERIFY check. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>

Triage Assessment

Vulnerability Type: Access control / Authorization

Confidence: HIGH

Reasoning:

The change enforces capability-based, config-driven provisioning with an enabled/disabled flag for resources and routes requests only to enabled resources. It introduces validation that rejects requests for resources that are not enabled and routes resources to the correct API server (aggregated vs dedicated), including tests asserting that a disabled resource is rejected. This hardens access to provisioning resources and prevents potential misuse of disabled resources or misrouting, addressing authorization/access-control vulnerabilities in provisioning.

Verification Assessment

Vulnerability Type: Access control / Authorization

Confidence: HIGH

Affected Versions: 12.4.0 and earlier

Code Diff

diff --git a/apps/provisioning/pkg/apis/provisioning/v0alpha1/settings.go b/apps/provisioning/pkg/apis/provisioning/v0alpha1/settings.go index 4decb049da1d2..8be7e1efaf2b1 100644 --- a/apps/provisioning/pkg/apis/provisioning/v0alpha1/settings.go +++ b/apps/provisioning/pkg/apis/provisioning/v0alpha1/settings.go @@ -21,10 +21,33 @@ type RepositoryViewList struct { // AvailableRepositoryTypes is the list of repository types supported in this instance (e.g. git, bitbucket, github, etc) AvailableRepositoryTypes []RepositoryType `json:"availableRepositoryTypes,omitempty"` + // AvailableResources is the list of resource types declared for provisioning in this + // instance, including disabled ones (see SupportedResource.Disabled). + AvailableResources []SupportedResource `json:"availableResources,omitempty"` + // +mapType=atomic Items []RepositoryView `json:"items"` } +// SupportedResource describes a resource type declared for provisioning. A resource is +// identified by its group and kind; the API version and plural resource are resolved at +// runtime via discovery, so they are not part of this descriptor. +type SupportedResource struct { + // Group is the API group of the resource (e.g. "dashboard.grafana.app"). + Group string `json:"group"` + + // Kind is the kind of the resource (e.g. "Dashboard"). + Kind string `json:"kind"` + + // Disabled reports whether the resource is declared but not acted on by provisioning. + // Active resources omit this field. + Disabled bool `json:"disabled,omitempty"` +} + +func (SupportedResource) OpenAPIModelName() string { + return OpenAPIPrefix + "SupportedResource" +} + func (RepositoryViewList) OpenAPIModelName() string { return OpenAPIPrefix + "RepositoryViewList" } diff --git a/conf/defaults.ini b/conf/defaults.ini index cefd01bc79346..8e8fa0dedfa8f 100644 --- a/conf/defaults.ini +++ b/conf/defaults.ini @@ -2451,6 +2451,16 @@ max_file_size = 5242880 # host. Analogous to [rendering] callback_url for the image renderer plugin. public_root_url = +# Resources that can be managed from the UI through provisioning, comma-separated, each as +# "<group>/<Kind>[:cap...]". The API version and plural resource are resolved at runtime via +# discovery, so only the group and kind are configured. Capabilities (all default to off): +# folder - folder-scoped; carries the folder annotation on write (else org-scoped) +# skipvalidation - skip validation on write (else validated) +# disabled - declared but not acted on; still surfaced on the settings endpoint +# Adding or enabling a resource is a config change. Library panels and playlists are declared +# but disabled by default. +resources = folder.grafana.app/Folder:folder, dashboard.grafana.app/Dashboard:folder, dashboard.grafana.app/LibraryPanel:folder:disabled, playlist.grafana.app/Playlist:disabled + #################################### Unified Storage #################################### [unified_storage] # index_path is the path where unified storage can store its index files for search. diff --git a/packages/grafana-api-clients/src/clients/rtkq/provisioning/v0alpha1/endpoints.gen.ts b/packages/grafana-api-clients/src/clients/rtkq/provisioning/v0alpha1/endpoints.gen.ts index 708f3aa5682f7..97454f720da64 100644 --- a/packages/grafana-api-clients/src/clients/rtkq/provisioning/v0alpha1/endpoints.gen.ts +++ b/packages/grafana-api-clients/src/clients/rtkq/provisioning/v0alpha1/endpoints.gen.ts @@ -2285,6 +2285,14 @@ export type WebhookResponse = { /** Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds */ kind?: string; }; +export type SupportedResource = { + /** Disabled reports whether the resource is declared but not acted on by provisioning. Active resources omit this field. */ + disabled?: boolean; + /** Group is the API group of the resource (e.g. "dashboard.grafana.app"). */ + group: string; + /** Kind is the kind of the resource (e.g. "Dashboard"). */ + kind: string; +}; export type RepositoryView = { /** For git, this is the target branch */ branch?: string; @@ -2327,6 +2335,8 @@ export type RepositoryViewList = { apiVersion?: string; /** AvailableRepositoryTypes is the list of repository types supported in this instance (e.g. git, bitbucket, github, etc) */ availableRepositoryTypes?: ('bitbucket' | 'git' | 'github' | 'githubEnterprise' | 'gitlab' | 'local')[]; + /** AvailableResources is the list of resource types declared for provisioning in this instance, including disabled ones (see SupportedResource.Disabled). */ + availableResources?: SupportedResource[]; items: RepositoryView[]; /** Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds */ kind?: string; diff --git a/packages/grafana-openapi/src/apis/provisioning.grafana.app-v0alpha1.json b/packages/grafana-openapi/src/apis/provisioning.grafana.app-v0alpha1.json index 1cfa8a0b510ee..3df59e07237e7 100644 --- a/packages/grafana-openapi/src/apis/provisioning.grafana.app-v0alpha1.json +++ b/packages/grafana-openapi/src/apis/provisioning.grafana.app-v0alpha1.json @@ -5553,6 +5553,17 @@ "enum": ["bitbucket", "git", "github", "githubEnterprise", "gitlab", "local"] } }, + "availableResources": { + "description": "AvailableResources is the list of resource types declared for provisioning in this instance, including disabled ones (see SupportedResource.Disabled).", + "type": "array", + "items": { + "allOf": [ + { + "$ref": "#/components/schemas/SupportedResource" + } + ] + } + }, "items": { "type": "array", "items": { @@ -5945,6 +5956,27 @@ } } }, + "SupportedResource": { + "description": "SupportedResource describes a resource type declared for provisioning. A resource is identified by its group and kind; the API version and plural resource are resolved at runtime via discovery, so they are not part of this descriptor.", + "type": "object", + "required": ["group", "kind"], + "properties": { + "disabled": { + "description": "Disabled reports whether the resource is declared but not acted on by provisioning. Active resources omit this field.", + "type": "boolean" + }, + "group": { + "description": "Group is the API group of the resource (e.g. \"dashboard.grafana.app\").", + "type": "string", + "default": "" + }, + "kind": { + "description": "Kind is the kind of the resource (e.g. \"Dashboard\").", + "type": "string", + "default": "" + } + } + }, "SyncJobOptions": { "type": "object", "required": ["incremental"], diff --git a/packages/grafana-openapi/src/apis/provisioning.grafana.app-v1beta1.json b/packages/grafana-openapi/src/apis/provisioning.grafana.app-v1beta1.json index 1f2e7914f05a8..b10c78f50ec9d 100644 --- a/packages/grafana-openapi/src/apis/provisioning.grafana.app-v1beta1.json +++ b/packages/grafana-openapi/src/apis/provisioning.grafana.app-v1beta1.json @@ -5169,6 +5169,17 @@ "enum": ["bitbucket", "git", "github", "githubEnterprise", "gitlab", "local"] } }, + "availableResources": { + "description": "AvailableResources is the list of resource types declared for provisioning in this instance, including disabled ones (see SupportedResource.Disabled).", + "type": "array", + "items": { + "allOf": [ + { + "$ref": "#/components/schemas/SupportedResource" + } + ] + } + }, "items": { "type": "array", "items": { @@ -5496,6 +5507,27 @@ } } }, + "SupportedResource": { + "description": "SupportedResource describes a resource type declared for provisioning. A resource is identified by its group and kind; the API version and plural resource are resolved at runtime via discovery, so they are not part of this descriptor.", + "type": "object", + "required": ["group", "kind"], + "properties": { + "disabled": { + "description": "Disabled reports whether the resource is declared but not acted on by provisioning. Active resources omit this field.", + "type": "boolean" + }, + "group": { + "description": "Group is the API group of the resource (e.g. \"dashboard.grafana.app\").", + "type": "string", + "default": "" + }, + "kind": { + "description": "Kind is the kind of the resource (e.g. \"Dashboard\").", + "type": "string", + "default": "" + } + } + }, "SyncJobOptions": { "type": "object", "required": ["incremental"], diff --git a/pkg/operators/provisioning/config.go b/pkg/operators/provisioning/config.go index afecfac39e21a..c84dd93f0e55b 100644 --- a/pkg/operators/provisioning/config.go +++ b/pkg/operators/provisioning/config.go @@ -92,6 +92,7 @@ type ControllerConfig struct { // provisioning_server_public_url = // dashboards_server_url = // folders_server_url = +// aggregated_server_url = // folders_api_version = // tls_insecure = // tls_cert_file = @@ -209,11 +210,42 @@ func (c *ControllerConfig) Clients() (resources.ClientFactory, error) { return nil, fmt.Errorf("folders_server_url is required in [operator] section") } provisioningServerURL := operatorSec.Key("provisioning_server_url").String() + // aggregated_server_url serves resource groups that do not have a dedicated server URL + // (e.g. newly provisionable kinds in their own API group). Dashboards and folders keep + // their dedicated URLs for backwards compatibility. + aggregatedServerURL := operatorSec.Key("aggregated_server_url").String() apiServerURLs := map[string]string{ resources.DashboardResource.Group: dashboardsServerURL, resources.FolderResource.Group: foldersServerURL, provisioning.GROUP: provisioningServerURL, } + + supportedResources, err := resources.ParseSupportedResources(c.Settings.ProvisioningResources) + if err != nil { + return nil, fmt.Errorf("invalid [provisioning] resources configuration: %w", err) + } + + // Dashboards and folders have dedicated server URLs; everything else is served by the + // aggregated API server. Skip the built-in groups, then ensure every other active + // resource's group resolves to the aggregated server — failing loudly if a resource needs + // it and it is unset, rather than hitting "no clients provider for group" at request time. + for _, r := range supportedResources { + if !r.IsActive() { + continue + } + switch r.Group { + case resources.DashboardResource.Group, resources.FolderResource.Group, provisioning.GROUP: + continue // built-in groups with dedicated server URLs + } + if _, ok := apiServerURLs[r.Group]; ok { + continue + } + if aggregatedServerURL == "" { + return nil, fmt.Errorf("aggregated_server_url is required in [operator] section to serve resource %s/%s", r.Group, r.Kind) + } + apiServerURLs[r.Group] = aggregatedServerURL + } + configProviders := make(map[string]apiserver.RestConfigProvider) tlsConfigForTransport, err := rest.TLSConfigFor(&rest.Config{TLSClientConfig: tlsConfig}) @@ -247,7 +279,7 @@ func (c *ControllerConfig) Clients() (resources.ClientFactory, error) { configProviders[group] = NewDirectConfigProvider(config) } - clients := resources.NewClientFactoryForMultipleAPIServers(configProviders) + clients := resources.NewClientFactoryForMultipleAPIServers(configProviders, supportedResources...) c.clients = clients return clients, nil } diff --git a/pkg/registry/apis/provisioning/files.go b/pkg/registry/apis/provisioning/files.go index 02d73188e0184..4ccb9a3e0f3a5 100644 --- a/pkg/registry/apis/provisioning/files.go +++ b/pkg/registry/apis/provisioning/files.go @@ -183,7 +183,7 @@ func (c *filesConnector) createDualReadWriter(ctx context.Context, repo reposito } folders := resources.NewFolderManager(readWriter, folderClient, resources.NewEmptyFolderTree(), folderGVK, resources.WithFolderMetadataEnabled(c.folderMetadataEnabled)) - authorizer := resources.NewAuthorizer(repo.Config(), readWriter, c.access, c.folderMetadataEnabled) + authorizer := resources.NewAuthorizer(repo.Config(), readWriter, c.access, clients, c.folderMetadataEnabled) return resources.NewDualReadWriter(readWriter, parser, folders, authorizer, c.folderMetadataEnabled), authorizer, nil } diff --git a/pkg/registry/apis/provisioning/files_test.go b/pkg/registry/apis/provisioning/files_test.go index 92e9823e75cf6..5d402afeece55 100644 --- a/pkg/registry/apis/provisioning/files_test.go +++ b/pkg/registry/apis/provisioning/files_test.go @@ -515,7 +515,7 @@ func TestHandleGetRawFile(t *testing.T) { }, } mockReadWriter.EXPECT().Config().Return(repo).Maybe() - authorizer := resources.NewAuthorizer(repo, mockReadWriter, mockAccess, false) + authorizer := resources.NewAuthorizer(repo, mockReadWriter, mockAccess, resources.NewMockResourceClients(t), false) if tt.readError != nil { mockReadWriter.EXPECT().Read(mock.Anything, tt.path, "").Return(nil, tt.readError) @@ -568,7 +568,7 @@ func TestHandleGetRawFile_FolderScopedAuth(t *testing.T) { Check(mock.Anything, mock.Anything, mock.Anything). Return(apierrors.NewForbidden(provisioningapi.RepositoryResourceInfo.GroupResource(), "team-a", errors.New("denied"))) - authorizer := resources.NewAuthorizer(repo, mockReadWriter, mockAccess, false) + authorizer := resources.NewAuthorizer(repo, mockReadWriter, mockAccess, resources.NewMockResourceClients(t), false) connector := &filesConnector{access: mockAccess} _, err := connector.handleGetRawFile( @@ -612,7 +612,7 @@ func TestHandleGetRawFile_MaxFileSize(t *testing.T) { mockAccess.EXPECT().Check(mock.Anything, mock.Anything, mock.Anything).Return(nil).Maybe() mockReadWriter.EXPECT().Config().Return(repo).Maybe() - authorizer := resources.NewAuthorizer(repo, mockReadWriter, mockAccess, false) + authorizer := resources.NewAuthorizer(repo, mockReadWriter, mockAccess, resources.NewMockResourceClients(t), false) mockReadWriter.EX ... [truncated]
← Back to Alerts View on GitHub →