Filter out variant the user is not allowed to update

With a product with mutiple variant, we can end in a scenario where a
user sees variant associated to producer it doesn't have permission for.
This prevents the user from updating any variant. This fix filter out
variant a user shoudn't be seeing
This commit is contained in:
Gaetan Craig-Riou
2025-10-22 15:06:53 +11:00
parent 61f8b5c7f4
commit 25d55fec24
5 changed files with 23 additions and 14 deletions

View File

@@ -11,7 +11,8 @@ module Admin
def index
fetch_products
render "index",
locals: { producers:, categories:, tax_category_options:, available_tags:, flash: }
locals: { producer_options:, categories:, tax_category_options:, available_tags:,
flash:, allowed_producers: }
session[:products_return_to_url] = request.url
end
@@ -32,7 +33,8 @@ module Admin
render "index", status: :unprocessable_entity,
locals: {
producers:, categories:, tax_category_options:, available_tags:, flash:
producer_options:, categories:, tax_category_options:, available_tags:,
flash:
}
end
end
@@ -88,7 +90,7 @@ module Admin
flash.now[:success] = t('.success')
@product_index = "-#{@cloned_product.id}"
@producer_options = producers
@producer_options = producer_options
@category_options = categories
@tax_category_options = tax_category_options
rescue ActiveRecord::ActiveRecordError => e
@@ -132,10 +134,13 @@ module Admin
end
end
def producers
producers = OpenFoodNetwork::Permissions.new(spree_current_user)
def allowed_producers
OpenFoodNetwork::Permissions.new(spree_current_user)
.managed_product_enterprises.is_primary_producer.by_name
producers.map { |p| [p.name, p.id] }
end
def producer_options
allowed_producers.map { |p| [p.name, p.id] }
end
def categories

View File

@@ -1,4 +1,4 @@
-# locals: (products:, pagy:, search_term:, producer_options:, producer_id:, category_options:, category_id:, tax_category_options:, available_tags:, tags:, flashes:, display_search_filter:)
-# locals: (products:, pagy:, search_term:, producer_options:, producer_id:, category_options:, category_id:, tax_category_options:, available_tags:, tags:, flashes:, display_search_filter:, allowed_producers:)
%turbo-frame#products-content{ target: "_top", refresh: "morph" }
.spinner-overlay{ "data-controller": "loading", "data-products-target": "loading", class: "hidden" }
.spinner-container
@@ -18,7 +18,7 @@
.container.results
.sixteen.columns
= render partial: 'sort', locals: { pagy:, search_term:, producer_id:, category_id:, tags: }
= render partial: 'table', locals: { products:, producer_options:, category_options:, tax_category_options: }
= render partial: 'table', locals: { products:, producer_options:, category_options:, tax_category_options: , allowed_producers: }
- if pagy.present? && pagy.pages > 1
= render partial: 'admin/shared/stimulus_pagination', locals: { pagy: pagy }
- else

View File

@@ -1,4 +1,4 @@
-# locals: (form:, product:, product_index:, producer_options:, category_options:, tax_category_options:)
-# locals: (form:, product:, product_index:, producer_options:, category_options:, tax_category_options:, allowed_producers:)
= form.fields_for("products", product, index: product_index) do |product_form|
%tbody.relaxed{ id: dom_id(product), data: { 'record-id': product_form.object.id,
controller: "nested-form product",
@@ -8,6 +8,8 @@
= render partial: 'product_row', locals: { f: product_form, product:, product_index: }
- product.variants.each_with_index do |variant, variant_index|
- next unless allowed_producers.include?(variant.supplier)
= form.fields_for("products][#{product_index}][variants_attributes", variant, index: variant_index) do |variant_form|
%tr.condensed{ id: dom_id(variant), 'data-controller': "variant", 'class': "nested-form-wrapper", 'data-new-record': variant.new_record? ? "true" : false }
= render partial: 'variant_row', locals: { variant:, f: variant_form, category_options:, tax_category_options:, producer_options: }

View File

@@ -1,4 +1,4 @@
-# locals: (products:, producer_options:, category_options:, tax_category_options:)
-# locals: (products:, producer_options:, category_options:, tax_category_options:, allowed_producers:)
= form_with url: admin_products_bulk_update_path, method: :post, id: "products-form",
builder: BulkFormBuilder,
html: { data: { 'turbo-frame': "_self",
@@ -70,4 +70,4 @@
%th.align-left.col-inherits_properties= t('admin.products_page.columns.inherits_properties')
%th.align-right= t('admin.products_page.columns.actions')
- products.each_with_index do |product, product_index|
= render partial: 'product_variant_row', locals: { form:, product:, product_index:, producer_options:, category_options:, tax_category_options: }
= render partial: 'product_variant_row', locals: { form:, product:, product_index:, producer_options:, category_options:, tax_category_options: , allowed_producers:}

View File

@@ -1,4 +1,4 @@
-# locals: (producers:, categories:, tax_category_options:, available_tags:, flash:)
-# locals: (producer_options:, categories:, tax_category_options:, available_tags:, flash:, allowed_producers:)
- content_for :page_title do
= t('.header.title')
- content_for :page_actions do
@@ -14,11 +14,13 @@
#products_v3_page{ 'data-turbo': true }
= render partial: "content", locals: { products: @products, pagy: @pagy, search_term: @search_term,
producer_options: producers, producer_id: @producer_id,
producer_options:, producer_id: @producer_id,
category_options: categories, category_id: @category_id,
tax_category_options:, available_tags:, tags: @tags,
flashes: flash,
display_search_filter: (@products.any? || @search_term.present? || @category_id.present?) }
display_search_filter: (@products.any? || @search_term.present? || @category_id.present?),
allowed_producers:}
- %w[product variant].each do |object_type|
= render partial: 'delete_modal', locals: { object_type: }
#modal-component