mirror of
https://github.com/openfoodfoundation/openfoodnetwork
synced 2026-02-28 01:53:25 +00:00
Merge branch 'master' into docker_scripts
This commit is contained in:
1
Gemfile
1
Gemfile
@@ -117,7 +117,6 @@ gem 'uglifier', '>= 1.0.3'
|
||||
|
||||
gem 'angular-rails-templates', '~> 0.3.0'
|
||||
gem 'foundation-icons-sass-rails'
|
||||
gem 'momentjs-rails'
|
||||
|
||||
gem 'foundation-rails', '= 5.5.2.1'
|
||||
|
||||
|
||||
@@ -463,8 +463,6 @@ GEM
|
||||
mini_racer (0.2.15)
|
||||
libv8 (> 7.3)
|
||||
minitest (4.7.5)
|
||||
momentjs-rails (2.20.1)
|
||||
railties (>= 3.1)
|
||||
money (5.1.1)
|
||||
i18n (~> 0.6.0)
|
||||
msgpack (1.3.3)
|
||||
@@ -770,7 +768,6 @@ DEPENDENCIES
|
||||
knapsack
|
||||
letter_opener (>= 1.4.1)
|
||||
mini_racer (= 0.2.15)
|
||||
momentjs-rails
|
||||
money (= 5.1.1)
|
||||
newrelic_rpm (~> 3.0)
|
||||
oauth2 (~> 1.4.4)
|
||||
|
||||
@@ -71,20 +71,22 @@
|
||||
//= require textAngular.min.js
|
||||
//= require i18n/translations
|
||||
//= require darkswarm/i18n.translate.js
|
||||
//= require moment
|
||||
//= require moment/de.js
|
||||
//= require moment/en-gb.js
|
||||
//= require moment/es.js
|
||||
//= require moment/fr.js
|
||||
//= require moment/it.js
|
||||
//= require moment/nb.js
|
||||
//= require moment/pt-br.js
|
||||
//= require moment/pt.js
|
||||
//= require moment/ru.js
|
||||
//= require moment/sv.js
|
||||
//= require moment/ca.js
|
||||
//= require moment/ar.js
|
||||
//= require moment/tr.js
|
||||
//= require moment/min/moment.min.js
|
||||
//= require moment/locale/ar.js
|
||||
//= require moment/locale/ca.js
|
||||
//= require moment/locale/de.js
|
||||
//= require moment/locale/en-gb.js
|
||||
//= require moment/locale/es.js
|
||||
//= require moment/locale/fil.js
|
||||
//= require moment/locale/fr.js
|
||||
//= require moment/locale/it.js
|
||||
//= require moment/locale/nb.js
|
||||
//= require moment/locale/nl-be.js
|
||||
//= require moment/locale/pt-br.js
|
||||
//= require moment/locale/pt.js
|
||||
//= require moment/locale/ru.js
|
||||
//= require moment/locale/sv.js
|
||||
//= require moment/locale/tr.js
|
||||
|
||||
// foundation
|
||||
//= require ../shared/mm-foundation-tpls-0.9.0-20180826174721.min.js
|
||||
|
||||
@@ -28,20 +28,22 @@
|
||||
#= require angular-backstretch.js
|
||||
#= require angular-flash.min.js
|
||||
#
|
||||
#= require moment
|
||||
#= require moment/de.js
|
||||
#= require moment/en-gb.js
|
||||
#= require moment/es.js
|
||||
#= require moment/fr.js
|
||||
#= require moment/it.js
|
||||
#= require moment/nb.js
|
||||
#= require moment/pt-br.js
|
||||
#= require moment/pt.js
|
||||
#= require moment/ru.js
|
||||
#= require moment/sv.js
|
||||
#= require moment/ca.js
|
||||
#= require moment/ar.js
|
||||
#= require moment/tr.js
|
||||
#= require moment/min/moment.min.js
|
||||
#= require moment/locale/ar.js
|
||||
#= require moment/locale/ca.js
|
||||
#= require moment/locale/de.js
|
||||
#= require moment/locale/en-gb.js
|
||||
#= require moment/locale/es.js
|
||||
#= require moment/locale/fil.js
|
||||
#= require moment/locale/fr.js
|
||||
#= require moment/locale/it.js
|
||||
#= require moment/locale/nb.js
|
||||
#= require moment/locale/nl-be.js
|
||||
#= require moment/locale/pt-br.js
|
||||
#= require moment/locale/pt.js
|
||||
#= require moment/locale/ru.js
|
||||
#= require moment/locale/sv.js
|
||||
#= require moment/locale/tr.js
|
||||
#
|
||||
#= require modernizr
|
||||
#
|
||||
|
||||
366
app/models/spree/ability.rb
Normal file
366
app/models/spree/ability.rb
Normal file
@@ -0,0 +1,366 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
require 'cancan'
|
||||
|
||||
module Spree
|
||||
class Ability
|
||||
include CanCan::Ability
|
||||
|
||||
def initialize(user)
|
||||
clear_aliased_actions
|
||||
|
||||
# override cancan default aliasing (we don't want to differentiate between read and index)
|
||||
alias_action :delete, to: :destroy
|
||||
alias_action :edit, to: :update
|
||||
alias_action :new, to: :create
|
||||
alias_action :new_action, to: :create
|
||||
alias_action :show, to: :read
|
||||
|
||||
user ||= Spree.user_class.new
|
||||
|
||||
if user.respond_to?(:has_spree_role?) && user.has_spree_role?('admin')
|
||||
can :manage, :all
|
||||
else
|
||||
can [:index, :read], Country
|
||||
can [:index, :read], OptionType
|
||||
can [:index, :read], OptionValue
|
||||
can :create, Order
|
||||
can :read, Order do |order, token|
|
||||
order.user == user || order.token && token == order.token
|
||||
end
|
||||
can :update, Order do |order, token|
|
||||
order.user == user || order.token && token == order.token
|
||||
end
|
||||
can [:index, :read], Product
|
||||
can [:index, :read], ProductProperty
|
||||
can [:index, :read], Property
|
||||
can :create, Spree.user_class
|
||||
can [:read, :update, :destroy], Spree.user_class, id: user.id
|
||||
can [:index, :read], State
|
||||
can [:index, :read], StockItem
|
||||
can [:index, :read], StockLocation
|
||||
can [:index, :read], StockMovement
|
||||
can [:index, :read], Taxon
|
||||
can [:index, :read], Taxonomy
|
||||
can [:index, :read], Variant
|
||||
can [:index, :read], Zone
|
||||
end
|
||||
|
||||
add_shopping_abilities user
|
||||
add_base_abilities user if new_user? user
|
||||
add_enterprise_management_abilities user if can_manage_enterprises? user
|
||||
add_group_management_abilities user if can_manage_groups? user
|
||||
add_product_management_abilities user if can_manage_products? user
|
||||
add_order_cycle_management_abilities user if can_manage_order_cycles? user
|
||||
add_order_management_abilities user if can_manage_orders? user
|
||||
add_relationship_management_abilities user if can_manage_relationships? user
|
||||
end
|
||||
|
||||
# New users have no enterprises.
|
||||
def new_user?(user)
|
||||
user.enterprises.blank?
|
||||
end
|
||||
|
||||
# Users can manage an enterprise if they have one.
|
||||
def can_manage_enterprises?(user)
|
||||
user.enterprises.present?
|
||||
end
|
||||
|
||||
# Users can manage a group if they have one.
|
||||
def can_manage_groups?(user)
|
||||
user.owned_groups.present?
|
||||
end
|
||||
|
||||
# Users can manage products if they have an enterprise that is not a profile.
|
||||
def can_manage_products?(user)
|
||||
can_manage_enterprises?(user) &&
|
||||
user.enterprises.any? { |e| e.category != :hub_profile && e.producer_profile_only != true }
|
||||
end
|
||||
|
||||
# Users can manage order cycles if they manage a sells own/any enterprise
|
||||
# OR if they manage a producer which is included in any order cycles
|
||||
def can_manage_order_cycles?(user)
|
||||
can_manage_orders?(user) ||
|
||||
OrderCycle.visible_by(user).any?
|
||||
end
|
||||
|
||||
# Users can manage orders if they have a sells own/any enterprise.
|
||||
def can_manage_orders?(user)
|
||||
( user.enterprises.map(&:sells) & %w(own any) ).any?
|
||||
end
|
||||
|
||||
def can_manage_relationships?(user)
|
||||
can_manage_enterprises? user
|
||||
end
|
||||
|
||||
def add_shopping_abilities(user)
|
||||
can [:destroy], Spree::LineItem do |item|
|
||||
user == item.order.user &&
|
||||
item.order.changes_allowed?
|
||||
end
|
||||
|
||||
can [:cancel], Spree::Order do |order|
|
||||
order.user == user
|
||||
end
|
||||
|
||||
can [:update, :destroy], Spree::CreditCard do |credit_card|
|
||||
credit_card.user == user
|
||||
end
|
||||
|
||||
can [:update], Customer do |customer|
|
||||
customer.user == user
|
||||
end
|
||||
end
|
||||
|
||||
# New users can create an enterprise, and gain other permissions from doing this.
|
||||
def add_base_abilities(_user)
|
||||
can [:create], Enterprise
|
||||
end
|
||||
|
||||
def add_group_management_abilities(user)
|
||||
can [:admin, :index], :overview
|
||||
can [:admin, :index], EnterpriseGroup
|
||||
can [:read, :edit, :update], EnterpriseGroup do |group|
|
||||
user.owned_groups.include? group
|
||||
end
|
||||
end
|
||||
|
||||
def add_enterprise_management_abilities(user)
|
||||
# We perform authorize! on (:create, nil) when creating a new order from admin,
|
||||
# and also (:search, nil) when searching for variants to add to the order
|
||||
can [:create, :search], nil
|
||||
|
||||
can [:admin, :index], :overview
|
||||
|
||||
can [:admin, :index, :read, :create, :edit, :update_positions, :destroy], ProducerProperty
|
||||
|
||||
can [:admin, :map_by_tag, :destroy], TagRule do |tag_rule|
|
||||
user.enterprises.include? tag_rule.enterprise
|
||||
end
|
||||
|
||||
can [:admin, :index, :create], Enterprise
|
||||
can [:read, :edit, :update,
|
||||
:remove_logo, :remove_promo_image, :remove_terms_and_conditions,
|
||||
:bulk_update, :resend_confirmation], Enterprise do |enterprise|
|
||||
OpenFoodNetwork::Permissions.new(user).editable_enterprises.include? enterprise
|
||||
end
|
||||
can [:welcome, :register], Enterprise do |enterprise|
|
||||
enterprise.owner == user
|
||||
end
|
||||
can [:manage_payment_methods,
|
||||
:manage_shipping_methods,
|
||||
:manage_enterprise_fees], Enterprise do |enterprise|
|
||||
user.enterprises.include? enterprise
|
||||
end
|
||||
|
||||
# All enterprises can have fees, though possibly suppliers don't need them?
|
||||
can [:index, :create], EnterpriseFee
|
||||
can [:admin, :read, :edit, :bulk_update, :destroy], EnterpriseFee do |enterprise_fee|
|
||||
user.enterprises.include? enterprise_fee.enterprise
|
||||
end
|
||||
|
||||
can [:admin, :known_users, :customers], :search
|
||||
|
||||
can [:admin, :show], :account
|
||||
|
||||
# For printing own account invoice orders
|
||||
can [:print], Spree::Order do |order|
|
||||
order.user == user
|
||||
end
|
||||
|
||||
can [:admin, :bulk_update], ColumnPreference do |column_preference|
|
||||
column_preference.user == user
|
||||
end
|
||||
|
||||
can [:admin, :connect, :status, :destroy], StripeAccount do |stripe_account|
|
||||
user.enterprises.include? stripe_account.enterprise
|
||||
end
|
||||
|
||||
can [:admin, :create], :manager_invitation
|
||||
end
|
||||
|
||||
def add_product_management_abilities(user)
|
||||
# Enterprise User can only access products that they are a supplier for
|
||||
can [:create], Spree::Product
|
||||
can [:admin, :read, :index, :update,
|
||||
:seo, :group_buy_options,
|
||||
:bulk_update, :clone, :delete,
|
||||
:destroy], Spree::Product do |product|
|
||||
OpenFoodNetwork::Permissions.new(user).managed_product_enterprises.include? product.supplier
|
||||
end
|
||||
|
||||
can [:create], Spree::Variant
|
||||
can [:admin, :index, :read, :edit,
|
||||
:update, :search, :delete, :destroy], Spree::Variant do |variant|
|
||||
OpenFoodNetwork::Permissions.new(user).
|
||||
managed_product_enterprises.include? variant.product.supplier
|
||||
end
|
||||
|
||||
can [:admin, :index, :read, :update, :bulk_update, :bulk_reset], VariantOverride do |vo|
|
||||
next false unless vo.hub.present? && vo.variant.andand.product.andand.supplier.present?
|
||||
|
||||
hub_auth = OpenFoodNetwork::Permissions.new(user).
|
||||
variant_override_hubs.
|
||||
include? vo.hub
|
||||
|
||||
producer_auth = OpenFoodNetwork::Permissions.new(user).
|
||||
variant_override_producers.
|
||||
include? vo.variant.product.supplier
|
||||
|
||||
hub_auth && producer_auth
|
||||
end
|
||||
|
||||
can [:admin, :create, :update], InventoryItem do |ii|
|
||||
next false unless ii.enterprise.present? &&
|
||||
ii.variant.andand.product.andand.supplier.present?
|
||||
|
||||
hub_auth = OpenFoodNetwork::Permissions.new(user).
|
||||
variant_override_hubs.
|
||||
include? ii.enterprise
|
||||
|
||||
producer_auth = OpenFoodNetwork::Permissions.new(user).
|
||||
variant_override_producers.
|
||||
include? ii.variant.product.supplier
|
||||
|
||||
hub_auth && producer_auth
|
||||
end
|
||||
|
||||
can [:admin, :index, :read, :create,
|
||||
:edit, :update_positions, :destroy], Spree::ProductProperty
|
||||
can [:admin, :index, :read, :create, :edit, :update, :destroy], Spree::Image
|
||||
|
||||
can [:admin, :index, :read, :search], Spree::Taxon
|
||||
can [:admin, :index, :read, :create, :edit], Spree::Classification
|
||||
|
||||
can [:admin, :index, :guide, :import, :save, :save_data,
|
||||
:validate_data, :reset_absent_products], ProductImport::ProductImporter
|
||||
|
||||
# Reports page
|
||||
can [:admin, :index, :customers, :orders_and_distributors, :group_buys, :payments,
|
||||
:orders_and_fulfillment, :products_and_inventory, :order_cycle_management, :packing],
|
||||
Spree::Admin::ReportsController
|
||||
add_bulk_coop_abilities
|
||||
add_enterprise_fee_summary_abilities
|
||||
end
|
||||
|
||||
def add_order_cycle_management_abilities(user)
|
||||
can [:admin, :index, :read, :edit, :update, :incoming, :outgoing], OrderCycle do |order_cycle|
|
||||
OrderCycle.visible_by(user).include? order_cycle
|
||||
end
|
||||
can [:admin, :index, :create], Schedule
|
||||
can [:admin, :update, :destroy], Schedule do |schedule|
|
||||
OpenFoodNetwork::Permissions.new(user).editable_schedules.include? schedule
|
||||
end
|
||||
can [:bulk_update, :clone, :destroy, :notify_producers], OrderCycle do |order_cycle|
|
||||
user.enterprises.include? order_cycle.coordinator
|
||||
end
|
||||
can [:for_order_cycle], Enterprise
|
||||
can [:for_order_cycle], EnterpriseFee
|
||||
end
|
||||
|
||||
def add_order_management_abilities(user)
|
||||
can [:index, :create], Spree::Order
|
||||
can [:read, :update, :fire, :resend, :invoice, :print, :print_ticket], Spree::Order do |order|
|
||||
# We allow editing orders with a nil distributor as this state occurs
|
||||
# during the order creation process from the admin backend
|
||||
order.distributor.nil? ||
|
||||
# Enterprise User can access orders that they are a distributor for
|
||||
user.enterprises.include?(order.distributor) ||
|
||||
# Enterprise User can access orders that are placed inside a OC they coordinate
|
||||
order.order_cycle.andand.coordinated_by?(user)
|
||||
end
|
||||
can [:admin, :bulk_management, :managed], Spree::Order do
|
||||
user.admin? || user.enterprises.any?(&:is_distributor)
|
||||
end
|
||||
can [:admin, :create, :show, :poll], :invoice
|
||||
can [:admin, :visible], Enterprise
|
||||
can [:admin, :index, :create, :update, :destroy], :line_item
|
||||
can [:admin, :index, :create], Spree::LineItem
|
||||
can [:destroy, :update], Spree::LineItem do |item|
|
||||
order = item.order
|
||||
user.admin? ||
|
||||
user.enterprises.include?(order.distributor) ||
|
||||
order.order_cycle.andand.coordinated_by?(user)
|
||||
end
|
||||
|
||||
can [:admin, :index, :read, :create, :edit, :update, :fire], Spree::Payment
|
||||
can [:admin, :index, :read, :create, :edit, :update, :fire], Spree::Shipment
|
||||
can [:admin, :index, :read, :create, :edit, :update, :fire], Spree::Adjustment
|
||||
can [:admin, :index, :read, :create, :edit, :update, :fire], Spree::ReturnAuthorization
|
||||
can [:destroy], Spree::Adjustment do |adjustment|
|
||||
if user.admin?
|
||||
true
|
||||
elsif adjustment.adjustable.instance_of? Spree::Order
|
||||
order = adjustment.adjustable
|
||||
user.enterprises.include?(order.distributor) ||
|
||||
order.order_cycle.andand.coordinated_by?(user)
|
||||
elsif adjustment.adjustable.instance_of? Spree::LineItem
|
||||
order = adjustment.adjustable.order
|
||||
user.enterprises.include?(order.distributor) ||
|
||||
order.order_cycle.andand.coordinated_by?(user)
|
||||
end
|
||||
end
|
||||
|
||||
can [:create], OrderCycle
|
||||
|
||||
can [:admin, :index, :read, :create, :edit, :update], ExchangeVariant
|
||||
can [:admin, :index, :read, :create, :edit, :update], Exchange
|
||||
can [:admin, :index, :read, :create, :edit, :update], ExchangeFee
|
||||
|
||||
# Enterprise user can only access payment and shipping methods for their distributors
|
||||
can [:index, :create], Spree::PaymentMethod
|
||||
can [:admin, :read, :update, :fire, :resend,
|
||||
:destroy, :show_provider_preferences], Spree::PaymentMethod do |payment_method|
|
||||
(user.enterprises & payment_method.distributors).any?
|
||||
end
|
||||
|
||||
can [:index, :create], Spree::ShippingMethod
|
||||
can [:admin, :read, :update, :destroy], Spree::ShippingMethod do |shipping_method|
|
||||
(user.enterprises & shipping_method.distributors).any?
|
||||
end
|
||||
|
||||
# Reports page
|
||||
can [:admin, :index, :customers, :group_buys, :sales_tax, :payments,
|
||||
:orders_and_distributors, :orders_and_fulfillment, :products_and_inventory,
|
||||
:order_cycle_management, :xero_invoices], Spree::Admin::ReportsController
|
||||
add_bulk_coop_abilities
|
||||
add_enterprise_fee_summary_abilities
|
||||
|
||||
can [:create], Customer
|
||||
can [:admin, :index, :update,
|
||||
:destroy, :show], Customer, enterprise_id: Enterprise.managed_by(user).pluck(:id)
|
||||
can [:admin, :new, :index], Subscription
|
||||
can [:create, :edit, :update, :cancel, :pause, :unpause], Subscription do |subscription|
|
||||
user.enterprises.include?(subscription.shop)
|
||||
end
|
||||
can [:admin, :build], SubscriptionLineItem
|
||||
can [:destroy], SubscriptionLineItem do |subscription_line_item|
|
||||
user.enterprises.include?(subscription_line_item.subscription.shop)
|
||||
end
|
||||
can [:admin, :edit, :cancel, :resume], ProxyOrder do |proxy_order|
|
||||
user.enterprises.include?(proxy_order.subscription.shop)
|
||||
end
|
||||
end
|
||||
|
||||
def add_relationship_management_abilities(user)
|
||||
can [:admin, :index, :create], EnterpriseRelationship
|
||||
can [:destroy], EnterpriseRelationship do |enterprise_relationship|
|
||||
user.enterprises.include? enterprise_relationship.parent
|
||||
end
|
||||
end
|
||||
|
||||
def add_bulk_coop_abilities
|
||||
# Reveal the report link in spree/admin/reports#index
|
||||
can [:bulk_coop], Spree::Admin::ReportsController
|
||||
# Allow direct access to the report resource
|
||||
can [:admin, :new, :create], :bulk_coop
|
||||
end
|
||||
|
||||
def add_enterprise_fee_summary_abilities
|
||||
# Reveal the report link in spree/admin/reports#index
|
||||
can [:enterprise_fee_summary], Spree::Admin::ReportsController
|
||||
# Allow direct access to the report resource
|
||||
can [:admin, :new, :create], :enterprise_fee_summary
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -1,313 +0,0 @@
|
||||
class AbilityDecorator
|
||||
include CanCan::Ability
|
||||
|
||||
# All abilites are allocated from this initialiser.
|
||||
# Spree also defines other abilities.
|
||||
def initialize(user)
|
||||
add_shopping_abilities user
|
||||
add_base_abilities user if is_new_user? user
|
||||
add_enterprise_management_abilities user if can_manage_enterprises? user
|
||||
add_group_management_abilities user if can_manage_groups? user
|
||||
add_product_management_abilities user if can_manage_products? user
|
||||
add_order_cycle_management_abilities user if can_manage_order_cycles? user
|
||||
add_order_management_abilities user if can_manage_orders? user
|
||||
add_relationship_management_abilities user if can_manage_relationships? user
|
||||
end
|
||||
|
||||
# New users have no enterprises.
|
||||
def is_new_user?(user)
|
||||
user.enterprises.blank?
|
||||
end
|
||||
|
||||
# Users can manage an enterprise if they have one.
|
||||
def can_manage_enterprises?(user)
|
||||
user.enterprises.present?
|
||||
end
|
||||
|
||||
# Users can manage a group if they have one.
|
||||
def can_manage_groups?(user)
|
||||
user.owned_groups.present?
|
||||
end
|
||||
|
||||
# Users can manage products if they have an enterprise that is not a profile.
|
||||
def can_manage_products?(user)
|
||||
can_manage_enterprises?(user) &&
|
||||
user.enterprises.any? { |e| e.category != :hub_profile && e.producer_profile_only != true }
|
||||
end
|
||||
|
||||
# Users can manage order cycles if they manage a sells own/any enterprise
|
||||
# OR if they manage a producer which is included in any order cycles
|
||||
def can_manage_order_cycles?(user)
|
||||
can_manage_orders?(user) ||
|
||||
OrderCycle.visible_by(user).any?
|
||||
end
|
||||
|
||||
# Users can manage orders if they have a sells own/any enterprise.
|
||||
def can_manage_orders?(user)
|
||||
( user.enterprises.map(&:sells) & %w(own any) ).any?
|
||||
end
|
||||
|
||||
def can_manage_relationships?(user)
|
||||
can_manage_enterprises? user
|
||||
end
|
||||
|
||||
def add_shopping_abilities(user)
|
||||
can [:destroy], Spree::LineItem do |item|
|
||||
user == item.order.user &&
|
||||
item.order.changes_allowed?
|
||||
end
|
||||
|
||||
can [:cancel], Spree::Order do |order|
|
||||
order.user == user
|
||||
end
|
||||
|
||||
can [:update, :destroy], Spree::CreditCard do |credit_card|
|
||||
credit_card.user == user
|
||||
end
|
||||
|
||||
can [:update], Customer do |customer|
|
||||
customer.user == user
|
||||
end
|
||||
end
|
||||
|
||||
# New users can create an enterprise, and gain other permissions from doing this.
|
||||
def add_base_abilities(_user)
|
||||
can [:create], Enterprise
|
||||
end
|
||||
|
||||
def add_group_management_abilities(user)
|
||||
can [:admin, :index], :overview
|
||||
can [:admin, :index], EnterpriseGroup
|
||||
can [:read, :edit, :update], EnterpriseGroup do |group|
|
||||
user.owned_groups.include? group
|
||||
end
|
||||
end
|
||||
|
||||
def add_enterprise_management_abilities(user)
|
||||
# Spree performs authorize! on (:create, nil) when creating a new order from admin, and also (:search, nil)
|
||||
# when searching for variants to add to the order
|
||||
can [:create, :search], nil
|
||||
|
||||
can [:admin, :index], :overview
|
||||
|
||||
can [:admin, :index, :read, :create, :edit, :update_positions, :destroy], ProducerProperty
|
||||
|
||||
can [:admin, :map_by_tag, :destroy], TagRule do |tag_rule|
|
||||
user.enterprises.include? tag_rule.enterprise
|
||||
end
|
||||
|
||||
can [:admin, :index, :create], Enterprise
|
||||
can [:read, :edit, :update,
|
||||
:remove_logo, :remove_promo_image, :remove_terms_and_conditions,
|
||||
:bulk_update, :resend_confirmation], Enterprise do |enterprise|
|
||||
OpenFoodNetwork::Permissions.new(user).editable_enterprises.include? enterprise
|
||||
end
|
||||
can [:welcome, :register], Enterprise do |enterprise|
|
||||
enterprise.owner == user
|
||||
end
|
||||
can [:manage_payment_methods, :manage_shipping_methods, :manage_enterprise_fees], Enterprise do |enterprise|
|
||||
user.enterprises.include? enterprise
|
||||
end
|
||||
|
||||
# All enterprises can have fees, though possibly suppliers don't need them?
|
||||
can [:index, :create], EnterpriseFee
|
||||
can [:admin, :read, :edit, :bulk_update, :destroy], EnterpriseFee do |enterprise_fee|
|
||||
user.enterprises.include? enterprise_fee.enterprise
|
||||
end
|
||||
|
||||
can [:admin, :known_users, :customers], :search
|
||||
|
||||
can [:admin, :show], :account
|
||||
|
||||
# For printing own account invoice orders
|
||||
can [:print], Spree::Order do |order|
|
||||
order.user == user
|
||||
end
|
||||
|
||||
can [:admin, :bulk_update], ColumnPreference do |column_preference|
|
||||
column_preference.user == user
|
||||
end
|
||||
|
||||
can [:admin, :connect, :status, :destroy], StripeAccount do |stripe_account|
|
||||
user.enterprises.include? stripe_account.enterprise
|
||||
end
|
||||
|
||||
can [:admin, :create], :manager_invitation
|
||||
end
|
||||
|
||||
def add_product_management_abilities(user)
|
||||
# Enterprise User can only access products that they are a supplier for
|
||||
can [:create], Spree::Product
|
||||
can [:admin, :read, :index, :update,
|
||||
:seo, :group_buy_options,
|
||||
:bulk_update, :clone, :delete,
|
||||
:destroy], Spree::Product do |product|
|
||||
OpenFoodNetwork::Permissions.new(user).managed_product_enterprises.include? product.supplier
|
||||
end
|
||||
|
||||
can [:create], Spree::Variant
|
||||
can [:admin, :index, :read, :edit, :update, :search, :delete, :destroy], Spree::Variant do |variant|
|
||||
OpenFoodNetwork::Permissions.new(user).managed_product_enterprises.include? variant.product.supplier
|
||||
end
|
||||
|
||||
can [:admin, :index, :read, :update, :bulk_update, :bulk_reset], VariantOverride do |vo|
|
||||
next false unless vo.hub.present? && vo.variant.andand.product.andand.supplier.present?
|
||||
|
||||
hub_auth = OpenFoodNetwork::Permissions.new(user).
|
||||
variant_override_hubs.
|
||||
include? vo.hub
|
||||
|
||||
producer_auth = OpenFoodNetwork::Permissions.new(user).
|
||||
variant_override_producers.
|
||||
include? vo.variant.product.supplier
|
||||
|
||||
hub_auth && producer_auth
|
||||
end
|
||||
|
||||
can [:admin, :create, :update], InventoryItem do |ii|
|
||||
next false unless ii.enterprise.present? && ii.variant.andand.product.andand.supplier.present?
|
||||
|
||||
hub_auth = OpenFoodNetwork::Permissions.new(user).
|
||||
variant_override_hubs.
|
||||
include? ii.enterprise
|
||||
|
||||
producer_auth = OpenFoodNetwork::Permissions.new(user).
|
||||
variant_override_producers.
|
||||
include? ii.variant.product.supplier
|
||||
|
||||
hub_auth && producer_auth
|
||||
end
|
||||
|
||||
can [:admin, :index, :read, :create, :edit, :update_positions, :destroy], Spree::ProductProperty
|
||||
can [:admin, :index, :read, :create, :edit, :update, :destroy], Spree::Image
|
||||
|
||||
can [:admin, :index, :read, :search], Spree::Taxon
|
||||
can [:admin, :index, :read, :create, :edit], Spree::Classification
|
||||
|
||||
can [:admin, :index, :guide, :import, :save, :save_data, :validate_data, :reset_absent_products], ProductImport::ProductImporter
|
||||
|
||||
# Reports page
|
||||
can [:admin, :index, :customers, :orders_and_distributors, :group_buys, :payments,
|
||||
:orders_and_fulfillment, :products_and_inventory, :order_cycle_management, :packing],
|
||||
Spree::Admin::ReportsController
|
||||
add_bulk_coop_abilities
|
||||
add_enterprise_fee_summary_abilities
|
||||
end
|
||||
|
||||
def add_order_cycle_management_abilities(user)
|
||||
can [:admin, :index, :read, :edit, :update, :incoming, :outgoing], OrderCycle do |order_cycle|
|
||||
OrderCycle.visible_by(user).include? order_cycle
|
||||
end
|
||||
can [:admin, :index, :create], Schedule
|
||||
can [:admin, :update, :destroy], Schedule do |schedule|
|
||||
OpenFoodNetwork::Permissions.new(user).editable_schedules.include? schedule
|
||||
end
|
||||
can [:bulk_update, :clone, :destroy, :notify_producers], OrderCycle do |order_cycle|
|
||||
user.enterprises.include? order_cycle.coordinator
|
||||
end
|
||||
can [:for_order_cycle], Enterprise
|
||||
can [:for_order_cycle], EnterpriseFee
|
||||
end
|
||||
|
||||
def add_order_management_abilities(user)
|
||||
can [:index, :create], Spree::Order
|
||||
can [:read, :update, :fire, :resend, :invoice, :print, :print_ticket], Spree::Order do |order|
|
||||
# We allow editing orders with a nil distributor as this state occurs
|
||||
# during the order creation process from the admin backend
|
||||
order.distributor.nil? ||
|
||||
# Enterprise User can access orders that they are a distributor for
|
||||
user.enterprises.include?(order.distributor) ||
|
||||
# Enterprise User can access orders that are placed inside a OC they coordinate
|
||||
order.order_cycle.andand.coordinated_by?(user)
|
||||
end
|
||||
can [:admin, :bulk_management, :managed], Spree::Order do
|
||||
user.admin? || user.enterprises.any?(&:is_distributor)
|
||||
end
|
||||
can [:admin, :create, :show, :poll], :invoice
|
||||
can [:admin, :visible], Enterprise
|
||||
can [:admin, :index, :create, :update, :destroy], :line_item
|
||||
can [:admin, :index, :create], Spree::LineItem
|
||||
can [:destroy, :update], Spree::LineItem do |item|
|
||||
order = item.order
|
||||
user.admin? || user.enterprises.include?(order.distributor) || order.order_cycle.andand.coordinated_by?(user)
|
||||
end
|
||||
|
||||
can [:admin, :index, :read, :create, :edit, :update, :fire], Spree::Payment
|
||||
can [:admin, :index, :read, :create, :edit, :update, :fire], Spree::Shipment
|
||||
can [:admin, :index, :read, :create, :edit, :update, :fire], Spree::Adjustment
|
||||
can [:admin, :index, :read, :create, :edit, :update, :fire], Spree::ReturnAuthorization
|
||||
can [:destroy], Spree::Adjustment do |adjustment|
|
||||
# Sharing code with destroying a line item. This should be unified and probably applied for other actions as well.
|
||||
if user.admin?
|
||||
true
|
||||
elsif adjustment.adjustable.instance_of? Spree::Order
|
||||
order = adjustment.adjustable
|
||||
user.enterprises.include?(order.distributor) || order.order_cycle.andand.coordinated_by?(user)
|
||||
elsif adjustment.adjustable.instance_of? Spree::LineItem
|
||||
order = adjustment.adjustable.order
|
||||
user.enterprises.include?(order.distributor) || order.order_cycle.andand.coordinated_by?(user)
|
||||
end
|
||||
end
|
||||
|
||||
can [:create], OrderCycle
|
||||
|
||||
can [:admin, :index, :read, :create, :edit, :update], ExchangeVariant
|
||||
can [:admin, :index, :read, :create, :edit, :update], Exchange
|
||||
can [:admin, :index, :read, :create, :edit, :update], ExchangeFee
|
||||
|
||||
# Enterprise user can only access payment and shipping methods for their distributors
|
||||
can [:index, :create], Spree::PaymentMethod
|
||||
can [:admin, :read, :update, :fire, :resend, :destroy, :show_provider_preferences], Spree::PaymentMethod do |payment_method|
|
||||
(user.enterprises & payment_method.distributors).any?
|
||||
end
|
||||
|
||||
can [:index, :create], Spree::ShippingMethod
|
||||
can [:admin, :read, :update, :destroy], Spree::ShippingMethod do |shipping_method|
|
||||
(user.enterprises & shipping_method.distributors).any?
|
||||
end
|
||||
|
||||
# Reports page
|
||||
can [:admin, :index, :customers, :group_buys, :sales_tax, :payments,
|
||||
:orders_and_distributors, :orders_and_fulfillment, :products_and_inventory,
|
||||
:order_cycle_management, :xero_invoices], Spree::Admin::ReportsController
|
||||
add_bulk_coop_abilities
|
||||
add_enterprise_fee_summary_abilities
|
||||
|
||||
can [:create], Customer
|
||||
can [:admin, :index, :update, :destroy, :show], Customer, enterprise_id: Enterprise.managed_by(user).pluck(:id)
|
||||
can [:admin, :new, :index], Subscription
|
||||
can [:create, :edit, :update, :cancel, :pause, :unpause], Subscription do |subscription|
|
||||
user.enterprises.include?(subscription.shop)
|
||||
end
|
||||
can [:admin, :build], SubscriptionLineItem
|
||||
can [:destroy], SubscriptionLineItem do |subscription_line_item|
|
||||
user.enterprises.include?(subscription_line_item.subscription.shop)
|
||||
end
|
||||
can [:admin, :edit, :cancel, :resume], ProxyOrder do |proxy_order|
|
||||
user.enterprises.include?(proxy_order.subscription.shop)
|
||||
end
|
||||
end
|
||||
|
||||
def add_relationship_management_abilities(user)
|
||||
can [:admin, :index, :create], EnterpriseRelationship
|
||||
can [:destroy], EnterpriseRelationship do |enterprise_relationship|
|
||||
user.enterprises.include? enterprise_relationship.parent
|
||||
end
|
||||
end
|
||||
|
||||
def add_bulk_coop_abilities
|
||||
# Reveal the report link in spree/admin/reports#index
|
||||
can [:bulk_coop], Spree::Admin::ReportsController
|
||||
# Allow direct access to the report resource
|
||||
can [:admin, :new, :create], :bulk_coop
|
||||
end
|
||||
|
||||
def add_enterprise_fee_summary_abilities
|
||||
# Reveal the report link in spree/admin/reports#index
|
||||
can [:enterprise_fee_summary], Spree::Admin::ReportsController
|
||||
# Allow direct access to the report resource
|
||||
can [:admin, :new, :create], :enterprise_fee_summary
|
||||
end
|
||||
end
|
||||
|
||||
Spree::Ability.register_ability(AbilityDecorator)
|
||||
1
config/initializers/assets.rb
Normal file
1
config/initializers/assets.rb
Normal file
@@ -0,0 +1 @@
|
||||
Rails.application.config.assets.paths << Rails.root.join('node_modules')
|
||||
13
package.json
13
package.json
@@ -1,16 +1,19 @@
|
||||
{
|
||||
"name": "openfoodnetwork",
|
||||
"version": "1.7.1",
|
||||
"version": "1.0.0",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/openfoodfoundation/openfoodnetwork"
|
||||
},
|
||||
"devDependencies": {
|
||||
"jasmine-core": "~2.4.1",
|
||||
"karma": "~0.13.22",
|
||||
"karma-chrome-launcher": "~2.2.0",
|
||||
"karma-jasmine": "~0.3.8",
|
||||
"jasmine-core": "~2.4.1",
|
||||
"karma-coffee-preprocessor": "~0.3.0"
|
||||
"karma-coffee-preprocessor": "~0.3.0",
|
||||
"karma-jasmine": "~0.3.8"
|
||||
},
|
||||
"license": "AGPL-1.0"
|
||||
"license": "AGPL-3.0",
|
||||
"dependencies": {
|
||||
"moment": "^2.28.0"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -33,33 +33,6 @@ describe Spree::Admin::UsersController do
|
||||
expect(response).to redirect_to(spree.edit_admin_user_path(test_user))
|
||||
end
|
||||
|
||||
describe "with BarAbility" do
|
||||
class BarAbility
|
||||
include CanCan::Ability
|
||||
|
||||
def initialize(user)
|
||||
user ||= Spree::User.new
|
||||
return unless user.has_spree_role?('bar')
|
||||
|
||||
can [:admin, :index, :show], Spree::Order
|
||||
end
|
||||
end
|
||||
|
||||
it 'should deny access to users with an bar role' do
|
||||
user.spree_roles << Spree::Role.find_or_create_by(name: 'bar')
|
||||
Spree::Ability.register_ability(BarAbility)
|
||||
spree_post :index
|
||||
expect(response).to redirect_to('/unauthorized')
|
||||
end
|
||||
|
||||
it 'should deny access to users with an bar role' do
|
||||
user.spree_roles << Spree::Role.find_or_create_by(name: 'bar')
|
||||
Spree::Ability.register_ability(BarAbility)
|
||||
spree_post :update, id: '9'
|
||||
expect(response).to redirect_to('/unauthorized')
|
||||
end
|
||||
end
|
||||
|
||||
it 'should deny access to users without an admin role' do
|
||||
allow(user).to receive_messages has_spree_role?: false
|
||||
spree_post :index
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
//= require textAngular-rangy.min.js
|
||||
//= require textAngular-sanitize.min.js
|
||||
//= require textAngular.min.js
|
||||
//= require moment
|
||||
//= require moment/min/moment.min.js
|
||||
//= require i18n
|
||||
|
||||
angular.module('templates', [])
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
107
spec/support/ability_helpers.rb
Normal file
107
spec/support/ability_helpers.rb
Normal file
@@ -0,0 +1,107 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
shared_examples_for 'access granted' do
|
||||
it 'should allow read' do
|
||||
expect(subject).to be_able_to(:read, resource, token) if token
|
||||
expect(subject).to be_able_to(:read, resource) unless token
|
||||
end
|
||||
|
||||
it 'should allow create' do
|
||||
expect(subject).to be_able_to(:create, resource, token) if token
|
||||
expect(subject).to be_able_to(:create, resource) unless token
|
||||
end
|
||||
|
||||
it 'should allow update' do
|
||||
expect(subject).to be_able_to(:update, resource, token) if token
|
||||
expect(subject).to be_able_to(:update, resource) unless token
|
||||
end
|
||||
end
|
||||
|
||||
shared_examples_for 'access denied' do
|
||||
it 'should not allow read' do
|
||||
expect(subject).to_not be_able_to(:read, resource)
|
||||
end
|
||||
|
||||
it 'should not allow create' do
|
||||
expect(subject).to_not be_able_to(:create, resource)
|
||||
end
|
||||
|
||||
it 'should not allow update' do
|
||||
expect(subject).to_not be_able_to(:update, resource)
|
||||
end
|
||||
end
|
||||
|
||||
shared_examples_for 'admin granted' do
|
||||
it 'should allow admin' do
|
||||
expect(subject).to be_able_to(:admin, resource, token) if token
|
||||
expect(subject).to be_able_to(:admin, resource) unless token
|
||||
end
|
||||
end
|
||||
|
||||
shared_examples_for 'admin denied' do
|
||||
it 'should not allow admin' do
|
||||
expect(subject).to_not be_able_to(:admin, resource)
|
||||
end
|
||||
end
|
||||
|
||||
shared_examples_for 'index allowed' do
|
||||
it 'should allow index' do
|
||||
expect(subject).to be_able_to(:index, resource)
|
||||
end
|
||||
end
|
||||
|
||||
shared_examples_for 'no index allowed' do
|
||||
it 'should not allow index' do
|
||||
expect(subject).to_not be_able_to(:index, resource)
|
||||
end
|
||||
end
|
||||
|
||||
shared_examples_for 'create only' do
|
||||
it 'should allow create' do
|
||||
expect(subject).to be_able_to(:create, resource)
|
||||
end
|
||||
|
||||
it 'should not allow read' do
|
||||
expect(subject).to_not be_able_to(:read, resource)
|
||||
end
|
||||
|
||||
it 'should not allow update' do
|
||||
expect(subject).to_not be_able_to(:update, resource)
|
||||
end
|
||||
|
||||
it 'should not allow index' do
|
||||
expect(subject).to_not be_able_to(:index, resource)
|
||||
end
|
||||
end
|
||||
|
||||
shared_examples_for 'read only' do
|
||||
it 'should not allow create' do
|
||||
expect(subject).to_not be_able_to(:create, resource)
|
||||
end
|
||||
|
||||
it 'should not allow update' do
|
||||
expect(subject).to_not be_able_to(:update, resource)
|
||||
end
|
||||
|
||||
it 'should allow index' do
|
||||
expect(subject).to be_able_to(:index, resource)
|
||||
end
|
||||
end
|
||||
|
||||
shared_examples_for 'update only' do
|
||||
it 'should not allow create' do
|
||||
expect(subject).to_not be_able_to(:create, resource)
|
||||
end
|
||||
|
||||
it 'should not allow read' do
|
||||
expect(subject).to_not be_able_to(:read, resource)
|
||||
end
|
||||
|
||||
it 'should allow update' do
|
||||
expect(subject).to be_able_to(:update, resource)
|
||||
end
|
||||
|
||||
it 'should not allow index' do
|
||||
expect(subject).to_not be_able_to(:index, resource)
|
||||
end
|
||||
end
|
||||
Reference in New Issue
Block a user