feat(marketplace): serve plugin presets from the catalog - #409
Open
ChielTimmermans wants to merge 2 commits into
Open
feat(marketplace): serve plugin presets from the catalog#409ChielTimmermans wants to merge 2 commits into
ChielTimmermans wants to merge 2 commits into
Conversation
Presets are storefront curation — the plugins page uses them as a browse filter — but catalog.v1 had no equivalent, so that page still called organization.v1.PluginService.ListPresets. It now reads everything from the catalog. appstore.presets and appstore.preset_plugins had no RLS at all, so migration 037 enables it on both and adds four policies: unrestricted for fun_fundament_api, which keeps organization-api's own ListPresets working, and reads for fun_marketplace_catalog_api. Preset rows are public curation and readable unconditionally, as categories are; membership is gated through the plugin's own policy, the same EXISTS categories_plugins uses, so a preset never names a RESTRICTED or soft-deleted listing. That policy is not sufficient on its own, and a test caught it: since migration 036 relaxed plugins_select_catalog, a public-but-unpublished plugin is visible at table level, so a draft leaked into preset membership. PresetPluginsList carries the published check for the same reason PluginList and PublisherList do — the storefront's own rule now lives in the queries. The console's plugins page drops its organization.v1 client entirely. The cluster-side views keep theirs: they list plugins to name what is installed, and the catalog only returns PUBLIC listings.
The image did not build: defclient moved to catalog.v1 but both Dockerfiles still copied organization-api/pkg/proto and never copied marketplace-api's, so the build context was missing the package it now imports. plugin-controller is not in the CI build matrix, which is why nothing caught it — reproduced and fixed against a real `docker build` of both images. `just plugins sandbox-catalog` also failed on any machine that had run the old sandbox-orgapi recipe: the new NodePort Service asks for the same fixed 30080 the old one still holds, and the relay rename meant `docker rm -f` no longer matched the container binding the host port. The recipe now removes both first.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Stacked on #408. Adds
catalog.v1.ListPresetsso the console's plugins page reads the whole storefront from the catalog — presets were the lastorganization.v1call left on that page.schema (migration 037)
appstore.presetsandappstore.preset_pluginshad no RLS at all. 037 enables it on both and adds four policies: unrestricted forfun_fundament_api(keeps organization-api's ownListPresetsworking — enabling RLS without it would have silently emptied that endpoint), and reads forfun_marketplace_catalog_api.Preset rows are public curation, readable unconditionally as categories are. Membership is gated through the plugin's own policy — the same
EXISTScategories_plugins_select_cataloguses — so a preset never names a RESTRICTED or soft-deleted listing.the part worth reviewing
That policy is not sufficient on its own, and
TestListPresetsOmitsHiddenPluginsFromMembershipcaught it: since #395's migration 036 relaxedplugins_select_catalogto let the catalog serve plugin-controller unpublished manifests, a public-but-unpublished plugin is visible at table level — so a draft leaked into preset membership.PresetPluginsListcarries thepublished IS NOT NULLcheck for the same reasonPluginList,PluginGetByIDandPublisherListdo.This is the first case of that trade-off biting: every new catalog query has to remember the storefront rule the policy no longer enforces.
console
The plugins page drops its
organization.v1client entirely. The cluster-side views (cluster-plugins,cluster-details,shared-plugins-form) keep theirs — they list plugins to name what is installed, and the catalog only returns PUBLIC listings, so moving them would hide an organization's own private plugins from its clusters.verification
go build ./...,go test ./marketplace-api/...,golangci-lintcleandb/fundament.sqlregenerated from the model (pgmodeler-cli --pgsql-ver 18.0), diff scoped to the preset policiesapp.spec.tsand theobservable-client.tslint error both pre-exist on master)