• Home

  • Custom Ecommerce
  • Application Development
  • Database Consulting
  • Cloud Hosting
  • Systems Integration
  • Legacy Business Systems
  • Security & Compliance
  • GIS

  • Expertise

  • About Us
  • Our Team
  • Clients
  • Blog
  • Careers

  • CasePointer

  • VisionPort

  • Contact
  • Our Blog

    Ongoing observations by End Point Dev people

    Spree Authorization Failure for Customized Role

    Matt Galvin

    By Matt Galvin
    September 22, 2014

    Hello again all. Recently I was working on another Spree site running Spree 2.1.1. The client wanted to create some custom roles. For example, the client wanted there to be a Sales Manager role. A Sales Manager could log in and have read and write access to all the orders. However, a sales manager should not have read/write access to products, configuration, promotions, users, etc. This was easily accomplished by following the steps in the Spree documentation. As I will describe, this documentation assumes that the custom role will have access to Orders#index.

    The client wanted to create a second custom role that had create, read, update and delete access to the Training model and nothing more. The training model belongs to a taxon and has a unique event date and taxon id. An example would be a training instance with an event date of September 9th, 2014 that belongs to a taxon with the name “Fire Safety 101” and a description “Teaching fire safety in accordance with OSHA standards. 10 hours and lunch is provided”. So, I planned to create a training personnel role that should be able to log in and only have read/write access to Trainings. However, the Spree documentation did not provide an explanation on how to create a custom role that does not have read or write access to orders.


    Following the pattern described in the Spree documentation for creating custom roles and their respective authorization, I created an ability_decorator.rb with the contents:

    class AbilityDecorator
         include CanCan::Ability
         def initialize(user)
           if user.respond_to?(:has_spree_role?) && user.has_spree_role?('sales_manager')
             can [:admin, :index, :show], Spree::Order
           if user.respond_to?(:has_spree_role?) && user.has_spree_role?('training')
             can [:admin, :manage], Spree::Training

    However, after creating a training user and attempting to log in, I got an unauthorized error. So, I checked the logs:

    The log output above shows that while I was logged in as a user with the training role, the application was checking for authorization on Spree::Admin::OrdersController#index (the orders list page), because the base admin URL ("/admin") points to this controller action. I reviewed the Devise documentation to modify where a user with the training role is redirected to upon login (via Spree Auth Devise’s after_sign_in method), as shown in the code shown below.

    def after_sign_in_path_for(resource)
        stored_location_for(resource) ||
          if resource.is_a?(Spree::User) && resource.has_spree_role?('training')

    After making this change, I tried once again and was able to successfully log in as a training user and only have the desired access to Trainings.


    To summarize, if you’d like to have a custom role and not give them access to Orders, you will need to make some adjustments outside the steps listed in Spree’s documentation for custom role authorization.

    ruby rails spree