Customizing Permissions

Authorization in Solidus is built upon the CanCan(Can) gem, which offers an expressive DSL to define and verify user permissions against application resources.

CanCan allows one to avoid access control logic being scattered throughout the application source code. Instead, it enables one to define all user permissions in Ability classes.

Solidus takes this concept to the next level, by allowing to specify different permission sets classes, and assign them to specific user roles.

Let's see in details what these concepts represent and how to manage them.

Roles

Solidus comes with two pre-configured roles: admin and default. User that has_spree_role?(:admin) has access to the admin panel and can manage all resources. User that has_spree_role?(:default) resembles a client or a website visitor, that can view certain resources, manage their shopping carts, etc. Each user can have multiple roles and admin users can change the roles of other users using the Admin panel, under the Users section.

Permission sets

Solidus comes with a list of ready permission sets, that you can find in core/lib/spree/permission_sets , and a Spree.config.roles preference, that you can use to change or extend default permission sets.

By default, roles and permission sets are configured with the following code :

core/lib/spree/app_configuration.rb
Ruby
    
      
# ...

Spree::RoleConfiguration.new.tap do |roles|
  roles.assign_permissions :default, ['Spree::PermissionSets::DefaultCustomer']
  roles.assign_permissions :admin, ['Spree::PermissionSets::SuperUser']
end

# ...

    
  

Which maps a list of permission sets to each role that we can use:

Manage Roles

If we want to add a new role with its own set of permissions to our store then first we must create a new Spree::Role, which can be done in one of the following ways:

  • manually add a row in the spree_roles table by executing Spree::Role.create(name: 'role_name') in the Rails console
  • in one of the configuration files (config/intializers/spree.rb, config/application.rb, db/migrations, db/seeds) add a line Spree::Role.find_or_create_by(name: 'role_name') for each role you wish to create

Now that the new role has been created you can simply assign a new list of permission sets to it, in the Solidus initializer:

config/initializers/spree.rb
Ruby
    
      
Spree.config do |config|
  config.roles.assign_permissions :role_name, ['Spree::PermissionSets::AnotherPermissionSet']
end

    
  

Spree::PermissionSets::AnotherPermissionSet can be selected by the list of the roles provided by Solidus, or alternatively can be a custom role that you have created.

Add a New Permission Set

New permission sets should be created in their own dedicated classes that extend Spree::PermissionSets::Base. Permission rules defined with the CanCan DSL should be created in the activate! method. To add a new permission set you can simply create this new class in lib/spree/permission_sets/:

lib/spree/permission_sets/blog_management.rb
Ruby
    
      
module Spree
  module PermissionSets
    class BlogManagement < PermissionSets::Base
      def activate!
        can :manage, Spree::Page
      end
    end
  end
end

    
  

Finally, remember to load permission sets files in your application configuration, by adding the following code to config/application.rb:

config/application.rb
Ruby
    
      
config.before_initialize do
  Dir.glob(File.join(File.dirname(__FILE__), "../lib/spree/permission_sets/*.rb")) do |c|
    require_dependency(c)
  end
end

    
  

Feedback

Solidus is an open source platform supported by the community. We encourage everyone using Solius to contribute back to the documentation and the code.

If you’re interested in contributing to the docs, get started with the contributing guidelines. If you see something that needs fixing and can’t do it yourself, please send us an email.