spree_admin_roles_and_access 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (32) hide show
  1. data/LICENSE +26 -0
  2. data/README.md +79 -0
  3. data/app/assets/javascripts/admin/spree_admin_roles_and_access.js +1 -0
  4. data/app/assets/javascripts/store/spree_admin_roles_and_access.js +1 -0
  5. data/app/assets/stylesheets/admin/spree_admin_roles_and_access.css +3 -0
  6. data/app/assets/stylesheets/store/spree_admin_roles_and_access.css +3 -0
  7. data/app/controllers/spree/admin/base_controller_decorator.rb +23 -0
  8. data/app/controllers/spree/admin/roles_controller.rb +21 -0
  9. data/app/models/spree/ability_decorator.rb +33 -0
  10. data/app/models/spree/permission.rb +19 -0
  11. data/app/models/spree/role_decorator.rb +19 -0
  12. data/app/models/spree/user_decorator.rb +3 -0
  13. data/app/overrides/add_roles_to_admin_configuration_sidebar.rb +8 -0
  14. data/app/views/spree/admin/roles/_form.html.erb +19 -0
  15. data/app/views/spree/admin/roles/edit.html.erb +2 -0
  16. data/app/views/spree/admin/roles/index.html.erb +32 -0
  17. data/app/views/spree/admin/roles/new.html.erb +2 -0
  18. data/config/initializers/cancan_ability.rb +31 -0
  19. data/config/initializers/cancan_controller_additions.rb +11 -0
  20. data/config/initializers/cancan_rule.rb +50 -0
  21. data/config/initializers/constants.rb +2 -0
  22. data/config/locales/en.yml +9 -0
  23. data/config/routes.rb +5 -0
  24. data/db/migrate/20130709104101_create_spree_permissions.rb +13 -0
  25. data/db/migrate/20130709104945_create_spree_roles_permissions.rb +11 -0
  26. data/db/migrate/20130709105614_add_editable_is_default_and_index_on_editable_is_default_and_name_to_spree_roles.rb +10 -0
  27. data/lib/generators/spree_admin_roles_and_access/install/install_generator.rb +31 -0
  28. data/lib/spree/permissions.rb +60 -0
  29. data/lib/spree_admin_roles_and_access.rb +2 -0
  30. data/lib/spree_admin_roles_and_access/engine.rb +22 -0
  31. data/lib/tasks/populate.rake +17 -0
  32. metadata +92 -0
data/LICENSE ADDED
@@ -0,0 +1,26 @@
1
+ Copyright (c) 2013 [name of plugin creator]
2
+ All rights reserved.
3
+
4
+ Redistribution and use in source and binary forms, with or without modification,
5
+ are permitted provided that the following conditions are met:
6
+
7
+ * Redistributions of source code must retain the above copyright notice,
8
+ this list of conditions and the following disclaimer.
9
+ * Redistributions in binary form must reproduce the above copyright notice,
10
+ this list of conditions and the following disclaimer in the documentation
11
+ and/or other materials provided with the distribution.
12
+ * Neither the name Spree nor the names of its contributors may be used to
13
+ endorse or promote products derived from this software without specific
14
+ prior written permission.
15
+
16
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17
+ "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18
+ LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19
+ A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
20
+ CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
21
+ EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
22
+ PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
23
+ PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
24
+ LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
25
+ NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
26
+ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
@@ -0,0 +1,79 @@
1
+ SpreeAdminRolesAndAccess
2
+ ========================
3
+
4
+ This spree extension is build on CanCan to dynamically add new roles and define its access through permissions.
5
+
6
+ Installation
7
+ ------------
8
+
9
+ Add spree_admin_roles_and_access to your Gemfile:
10
+
11
+ ```ruby
12
+ gem 'spree_admin_roles_and_access'
13
+ ```
14
+
15
+ Bundle your dependencies and run the installation generator:
16
+
17
+ ```shell
18
+ bundle
19
+ bundle exec rails g spree_admin_roles_and_access:install
20
+ bundle exec rake spree_roles:permissions:populate # To populate user and admin roles with their permissions
21
+ ```
22
+
23
+ Usage
24
+ -----
25
+
26
+ From Admin end, there is a role menu in configuration tab(admin end).
27
+ A new Role can be added and its corresponding permissions can also be selected there.
28
+ Permission to be chosen can be made only with rails console or a ruby script.
29
+
30
+ Types of Permission
31
+
32
+ 1. Default Permission - Basic permissions required by a user to perform task on user end, like creating an order etc. Every role should be provided with this permissions.
33
+
34
+ 2. Default Admin Permission - Because of this permission an admin can go to '/admin' route.
35
+
36
+ 3. Can Manage All - Role with this permission can do everything. This permission is also invisible at admin end. And it should only be given to admin and super admin.
37
+
38
+ Pattern of the permissions :-
39
+
40
+ 1. Can/cannot - specifies whether the user with that permission can do or cannot do that task.
41
+ 2. Action - specifies the action which can be done by that model or subject like update, index, create etc. There is a special action called manage which matches every action.
42
+ 3. Subject - specified the model like products, users etc. of which the permission is given. There is an special subject called all which matches every subject.
43
+ 4. Attributes - specifies the attributes for which the permission is specified. Read-only actions shouldn't require this like index, read etc. But it is more secure if we specify them in other actions like create or update.
44
+
45
+ Some Examples :-
46
+
47
+ 1. can-manage-spree/product - can perform every action on Spree::Product but not on any other model or subject.
48
+ 2. can-update-all - can update all models or subjects.
49
+ 3. can-update-spree/product - can update only products, and not users, orders and other things.
50
+ 4. can-update-spree/product-price - can update only price of products.
51
+ 5. can-manage-all - can perform every action on all models.
52
+
53
+ Points to remember
54
+
55
+ 1. If the controller doesn't have any model associated with it, then we will provide the full controller path like :-
56
+ can-read-spree/admin/pos
57
+
58
+ 2. Every Role should also have admin permission of that particular controller. For eg:-
59
+ To create a product, can-admin-spree/product is also needed along with can-create-spree/product.
60
+
61
+ 3. To define custom cancan permissions, which can not be made with the pattern adopted.
62
+ Override a module Permission. And define the permission in a method, and create a permission in the database.
63
+
64
+
65
+ To Do
66
+ -----
67
+
68
+ To provide a space in admin end, from where permissions can be added dynamically.
69
+
70
+ Testing
71
+ -------
72
+
73
+ Be sure to bundle your dependencies and then create a dummy test app for the specs to run against.
74
+
75
+ ```shell
76
+ bundle
77
+ bundle exec rake test_app
78
+ bundle exec rspec spec
79
+ ```
@@ -0,0 +1 @@
1
+ //= require admin/spree_backend
@@ -0,0 +1 @@
1
+ //= require store/spree_frontend
@@ -0,0 +1,3 @@
1
+ /*
2
+ *= require admin/spree_backend
3
+ */
@@ -0,0 +1,3 @@
1
+ /*
2
+ *= require store/spree_frontend
3
+ */
@@ -0,0 +1,23 @@
1
+ Spree::Admin::BaseController.class_eval do
2
+ def authorize_admin
3
+ begin
4
+ if params[:id]
5
+ record = model_class.where(PARAM_ATTRIBUTE[controller_name] => params[:id]).first
6
+ elsif new_action?
7
+ record = model_class.new
8
+ else
9
+ record = model_class
10
+ raise if record.blank? ## This is done because on some machines model_class returns nil instead of raising an exception.
11
+ end
12
+ rescue
13
+ record = "#{params[:controller]}"
14
+ end
15
+ authorize! :admin, record
16
+ authorize_with_attributes! params[:action].to_sym, record, params[controller_name.singularize]
17
+ end
18
+
19
+ private
20
+ def new_action?
21
+ NEW_ACTIONS.include?(params[:action].to_sym)
22
+ end
23
+ end
@@ -0,0 +1,21 @@
1
+ module Spree
2
+ module Admin
3
+ class RolesController < ResourceController
4
+ before_filter :load_permissions, :only => [:edit, :new, :create, :update]
5
+ before_filter :restrict_unless_editable, :only => [:edit, :update]
6
+
7
+ def index
8
+ @roles = Spree::Role.page(params[:page])
9
+ end
10
+
11
+ private
12
+ def load_permissions
13
+ @permissions = Spree::Permission.visible.all
14
+ end
15
+
16
+ def restrict_unless_editable
17
+ redirect_to admin_roles_path unless @role.editable?
18
+ end
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,33 @@
1
+ module Spree
2
+ Ability.class_eval do
3
+
4
+ def initialize(user)
5
+ self.clear_aliased_actions
6
+
7
+ alias_action :edit, :to => :update
8
+ alias_action :new, :to => :create
9
+ alias_action :new_action, :to => :create
10
+ alias_action :show, :to => :read
11
+ alias_action :delete, :to => :destroy
12
+
13
+ user ||= Spree::User.new
14
+
15
+ user_roles(user).each do |role|
16
+ ability(role, user)
17
+ end
18
+
19
+ Ability.abilities.each do |clazz|
20
+ ability = clazz.send(:new, user)
21
+ @rules = rules + ability.send(:rules)
22
+ end
23
+ end
24
+
25
+ def user_roles(user)
26
+ (roles = user.roles.includes(:permissions)).empty? ? Spree::Role.default_role.includes(:permissions) : roles
27
+ end
28
+
29
+ def ability(role, user)
30
+ role.ability(self, user)
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,19 @@
1
+ module Spree
2
+ class Permission < ActiveRecord::Base
3
+ include Permissions
4
+
5
+ attr_accessible :title, :priority
6
+
7
+ default_scope order(:priority)
8
+
9
+ has_and_belongs_to_many :roles, :join_table => 'spree_roles_permissions', :class_name => 'Spree::Role'
10
+
11
+ validates :title, :presence => true, :uniqueness => true
12
+
13
+ scope :visible, where(:visible => true)
14
+
15
+ def ability(current_ability, user)
16
+ send(title, current_ability, user)
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,19 @@
1
+ Spree::Role.class_eval do
2
+ attr_accessible :name, :permission_ids
3
+
4
+ has_and_belongs_to_many :permissions, :join_table => 'spree_roles_permissions', :class_name => 'Spree::Permission'
5
+
6
+ validates :name, :presence => true, :uniqueness => true
7
+
8
+ def ability(current_ability, user)
9
+ permissions.each do |permission|
10
+ permission.ability(current_ability, user)
11
+ end
12
+ end
13
+
14
+ def has_permission?(permission_title)
15
+ permissions.pluck(:title).include?(permission_title)
16
+ end
17
+
18
+ scope :default_role, where(:is_default => true)
19
+ end
@@ -0,0 +1,3 @@
1
+ Spree.user_class.class_eval do
2
+ has_and_belongs_to_many :roles, :join_table => 'spree_roles_users', :class_name => 'Spree::Role', :foreign_key => :user_id
3
+ end
@@ -0,0 +1,8 @@
1
+ Deface::Override.new(
2
+ :virtual_path => 'spree/admin/shared/_configuration_menu',
3
+ :name => 'add_roles_to_admin_configuration_sidebar',
4
+ :insert_bottom => "[data-hook='admin_configurations_sidebar_menu']",
5
+ :text => %q{
6
+ <%= configurations_sidebar_menu_item Spree.t(:roles), admin_roles_path %>
7
+ }
8
+ )
@@ -0,0 +1,19 @@
1
+ <div>
2
+ <%= render :partial => 'spree/shared/error_messages', :locals => { :target => @role } %>
3
+ </div>
4
+
5
+ <table>
6
+ <%= form_tag [:admin, @role], :method => method do %>
7
+ <tr><td>Name:</td><td><%= text_field_tag 'role[name]', @role.name %></td></tr>
8
+ <tr><td>Permissions:</td>
9
+ <td><% @permissions.each do |permission| %>
10
+ <% if @role.has_permission?(permission.title) %>
11
+ <span class='permission-check-box'><%= check_box_tag 'role[permission_ids][]', permission.id, true %><%= permission.title.gsub('-',' ').titleize %></span>
12
+ <% else %>
13
+ <span class='permission-check-box'><%= check_box_tag 'role[permission_ids][]', permission.id %><%= permission.title.gsub('-',' ').titleize %></span>
14
+ <% end %>
15
+ <br />
16
+ <% end %></td></tr>
17
+ <tr><td></td><td><%= submit_tag %></td></tr>
18
+ <% end %>
19
+ </table>
@@ -0,0 +1,2 @@
1
+ <h1><%= Spree.t(:edit_user) %></h1>
2
+ <%= render :partial => 'form', :locals => { :method => :put } %>
@@ -0,0 +1,32 @@
1
+ <%= render :partial => 'spree/admin/shared/configuration_menu' %>
2
+
3
+ <% content_for :page_title do %>
4
+ <%= Spree.t(:listing_roles) %>
5
+ <% end %>
6
+
7
+ <% content_for :page_actions do %>
8
+ <li>
9
+ <%= button_link_to Spree.t(:new_role), new_admin_role_path %>
10
+ </li>
11
+ <% end %>
12
+
13
+ <%= paginate @roles %>
14
+
15
+ <table class='index'>
16
+ <thead>
17
+ <tr>
18
+ <th>Name</th>
19
+ </tr>
20
+ </thead>
21
+
22
+ <tbody>
23
+ <% @roles.each do |role| %>
24
+ <tr class="<%= cycle('odd', 'even') %>">
25
+ <td class="align-center"><%= role.name %></td>
26
+ <% if role.editable? %>
27
+ <td class="actions"><%= link_to_edit role, :no_text => true, :class => 'edit' %></td>
28
+ <% end %>
29
+ </tr>
30
+ <% end %>
31
+ </tbody>
32
+ </table>
@@ -0,0 +1,2 @@
1
+ <h1><%= Spree.t(:new_user) %></h1>
2
+ <%= render :partial => 'form', :locals => { :method => :post } %>
@@ -0,0 +1,31 @@
1
+ CanCan::Ability.module_eval do
2
+ def relevant_rules(action, subject, attribute = nil)
3
+ rules.reverse.select do |rule|
4
+ rule.expanded_actions = expand_actions(rule.actions)
5
+ rule.relevant? action, subject, attribute
6
+ end
7
+ end
8
+
9
+ def relevant_rules_for_match(action, subject, attribute = nil)
10
+ relevant_rules(action, subject, attribute).each do |rule|
11
+ if rule.only_raw_sql?
12
+ raise ::Exception, "The can? and cannot? call cannot be used with a raw sql 'can' definition. The checking code cannot be determined for #{action.inspect} #{subject.inspect}"
13
+ end
14
+ end
15
+ end
16
+
17
+ def can?(action, subject, attribute = nil)
18
+ match = relevant_rules_for_match(action, subject, attribute).detect do |rule|
19
+ rule.matches_conditions?(action, subject, attribute)
20
+ end
21
+ match ? match.base_behavior : false
22
+ end
23
+
24
+ def can(*args, &block)
25
+ rules << CanCan::Rule.new(true, *args, &block)
26
+ end
27
+
28
+ def cannot(*args, &block)
29
+ rules << CanCan::Rule.new(false, *args, &block)
30
+ end
31
+ end
@@ -0,0 +1,11 @@
1
+ CanCan::ControllerAdditions.class_eval do
2
+ # specs of #authorize_with_attributes! is written in authorize_admin in roles_controller_spec
3
+ def authorize_with_attributes!(action, subject, attributes = [])
4
+ attributes = attributes.keys if attributes.is_a?(Hash)
5
+ if attributes.is_a? Array
6
+ attributes.each { |attribute| authorize!(action, subject, attribute) }
7
+ else
8
+ authorize!(action, subject)
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,50 @@
1
+ CanCan::Rule.class_eval do
2
+ def initialize(base_behavior, action = nil, subject = nil, *extra_args, &block)
3
+ @match_all = action.nil? && subject.nil?
4
+ @base_behavior = base_behavior
5
+ @actions = [action].flatten
6
+ @subjects = [subject].flatten
7
+ @attributes = [extra_args.shift].flatten if extra_args.first.kind_of?(Symbol) || extra_args.first.kind_of?(Array) && extra_args.first.first.kind_of?(Symbol)
8
+ raise ::Exception, "You are not able to supply a block with a hash of conditions in #{action} #{subject} ability. Use either one." if extra_args.first.kind_of?(Hash) && !block.nil?
9
+ @conditions = extra_args.first || {}
10
+ @block = block
11
+ end
12
+
13
+ # Matches the subject, action, and given attribute. Conditions are not checked here.
14
+ def relevant?(action, subject, attribute = nil)
15
+ subject = subject.values.first if subject.class == Hash
16
+ @match_all || (matches_action?(action) && matches_subject?(subject) && matches_attribute?(attribute))
17
+ end
18
+
19
+ # Matches the block or conditions hash
20
+ def matches_conditions?(action, subject, attribute = nil)
21
+ if @match_all
22
+ call_block_with_all(action, subject)
23
+ elsif @block && !subject_class?(subject)
24
+ @block.arity == 1 ? @block.call(subject) : @block.call(subject, attribute)
25
+ elsif @conditions.kind_of?(Hash) && subject.class == Hash
26
+ nested_subject_matches_conditions?(subject)
27
+ elsif @conditions.kind_of?(Hash) && !subject_class?(subject)
28
+ matches_conditions_hash?(subject)
29
+ else
30
+ # Don't stop at "cannot" definitions when there are conditions.
31
+ @conditions.empty? ? true : @base_behavior
32
+ end
33
+ end
34
+
35
+ def attributes?
36
+ @attributes.present?
37
+ end
38
+
39
+ private
40
+
41
+ def matches_attribute?(attribute)
42
+ # don't consider attributes in a cannot clause when not matching - this can probably be refactored
43
+ if !@base_behavior && @attributes && attribute.nil?
44
+ false
45
+ else
46
+ attribute = attribute.is_a?(Array) ? attribute.map(&:to_sym) : attribute.try(:to_sym)
47
+ @attributes.nil? || attribute.nil? || ([attribute].flatten - @attributes).empty?
48
+ end
49
+ end
50
+ end
@@ -0,0 +1,2 @@
1
+ PARAM_ATTRIBUTE = Hash.new(:id).merge({"products" => :permalink, "orders" => :number, "shipments" => :number})
2
+ NEW_ACTIONS = [:new, :create]
@@ -0,0 +1,9 @@
1
+ # Sample localization file for English. Add more files in this directory for other locales.
2
+ # See https://github.com/svenfuchs/rails-i18n/tree/master/rails%2Flocale for starting points.
3
+
4
+ en:
5
+ spree:
6
+ hello: "Hello world"
7
+ new_role: "New Role"
8
+ listing_roles: "Listing Roles"
9
+ roles: "Roles"
@@ -0,0 +1,5 @@
1
+ Spree::Core::Engine.routes.draw do
2
+ namespace :admin do
3
+ resources :roles, :except => [:show, :destroy]
4
+ end
5
+ end
@@ -0,0 +1,13 @@
1
+ class CreateSpreePermissions < ActiveRecord::Migration
2
+ def change
3
+ create_table :spree_permissions do |t|
4
+ t.string :title, :null => false, :unique => true
5
+ t.integer :priority, :default => 0
6
+ t.boolean :visible, :boolean, :default => true
7
+
8
+ t.timestamps
9
+ end
10
+
11
+ add_index :spree_permissions, :visible
12
+ end
13
+ end
@@ -0,0 +1,11 @@
1
+ class CreateSpreeRolesPermissions < ActiveRecord::Migration
2
+ def change
3
+ create_table :spree_roles_permissions, :id => false do |t|
4
+ t.integer :role_id, :null => false
5
+ t.integer :permission_id, :null => false
6
+ end
7
+
8
+ add_index(:spree_roles_permissions, :role_id)
9
+ add_index(:spree_roles_permissions, :permission_id)
10
+ end
11
+ end
@@ -0,0 +1,10 @@
1
+ class AddEditableIsDefaultAndIndexOnEditableIsDefaultAndNameToSpreeRoles < ActiveRecord::Migration
2
+ def change
3
+ add_column :spree_roles, :editable, :boolean, :default => true
4
+ add_column :spree_roles, :is_default, :boolean, :default => false
5
+
6
+ add_index(:spree_roles, :name)
7
+ add_index(:spree_roles, :is_default)
8
+ add_index(:spree_roles, :editable)
9
+ end
10
+ end
@@ -0,0 +1,31 @@
1
+ module SpreeAdminRolesAndAccess
2
+ module Generators
3
+ class InstallGenerator < Rails::Generators::Base
4
+
5
+ class_option :auto_run_migrations, :type => :boolean, :default => false
6
+
7
+ def add_javascripts
8
+ append_file 'app/assets/javascripts/store/all.js', "//= require store/spree_admin_roles_and_access\n"
9
+ append_file 'app/assets/javascripts/admin/all.js', "//= require admin/spree_admin_roles_and_access\n"
10
+ end
11
+
12
+ def add_stylesheets
13
+ inject_into_file 'app/assets/stylesheets/store/all.css', " *= require store/spree_admin_roles_and_access\n", :before => /\*\//, :verbose => true
14
+ inject_into_file 'app/assets/stylesheets/admin/all.css', " *= require admin/spree_admin_roles_and_access\n", :before => /\*\//, :verbose => true
15
+ end
16
+
17
+ def add_migrations
18
+ run 'bundle exec rake railties:install:migrations FROM=spree_admin_roles_and_access'
19
+ end
20
+
21
+ def run_migrations
22
+ run_migrations = options[:auto_run_migrations] || ['', 'y', 'Y'].include?(ask 'Would you like to run the migrations now? [Y/n]')
23
+ if run_migrations
24
+ run 'bundle exec rake db:migrate'
25
+ else
26
+ puts 'Skipping rake db:migrate, don\'t forget to run it!'
27
+ end
28
+ end
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,60 @@
1
+ module Spree
2
+ module Permissions
3
+ def method_missing(name, current_ability, user)
4
+ can, action, subject, attribute = find_action_and_subject(name)
5
+
6
+ Permissions.send(:define_method, name) do |current_ability, user|
7
+ if attribute.nil?
8
+ current_ability.send(can, action, subject)
9
+ else
10
+ current_ability.send(can, action, subject, attribute)
11
+ end
12
+ end
13
+ send(name, current_ability, user) if self.respond_to?(name)
14
+ end
15
+
16
+ define_method('default-permissions') do |current_ability, user|
17
+ current_ability.can [:read, :update, :destroy], Spree.user_class do |resource|
18
+ resource == user
19
+ end
20
+
21
+ current_ability.can [:read, :update], Spree::Order do |order, token|
22
+ order.user == user || (order.token && token == order.token)
23
+ end
24
+
25
+ current_ability.can :create, Spree::Order
26
+ current_ability.can :read, Spree::Address do |address|
27
+ address.user == user
28
+ end
29
+ end
30
+
31
+ define_method('default-admin-permissions') do |current_ability, user|
32
+ current_ability.can :admin, 'spree/admin/overview'
33
+ current_ability.can :index, 'spree/admin/overview'
34
+ end
35
+
36
+ define_method('can-update-spree/users') do |current_ability, user|
37
+ current_ability.can :update, Spree::User
38
+ # The permission of cannot update role_ids was given to user so that no onw with this permission can change role of user.
39
+ current_ability.cannot :update, Spree::User, :role_ids
40
+ end
41
+
42
+ define_method('can-create-spree/users') do |current_ability, user|
43
+ current_ability.can :create, Spree::User
44
+ current_ability.cannot :create, Spree::User, :role_ids
45
+ end
46
+
47
+ private
48
+ def find_action_and_subject(name)
49
+ can, action, subject, attribute = name.to_s.split('-')
50
+
51
+ if subject == 'all'
52
+ return can.to_sym, action.to_sym, subject.to_sym, attribute.try(:to_sym)
53
+ elsif (subject_class = subject.classify.safe_constantize) && subject_class.ancestors.include?(ActiveRecord::Base)
54
+ return can.to_sym, action.to_sym, subject_class, attribute.try(:to_sym)
55
+ else
56
+ return can.to_sym, action.to_sym, subject, attribute.try(:to_sym)
57
+ end
58
+ end
59
+ end
60
+ end
@@ -0,0 +1,2 @@
1
+ require 'spree_core'
2
+ require 'spree_admin_roles_and_access/engine'
@@ -0,0 +1,22 @@
1
+ module SpreeAdminRolesAndAccess
2
+ class Engine < Rails::Engine
3
+ require 'spree/core'
4
+ isolate_namespace Spree
5
+ engine_name 'spree_admin_roles_and_access'
6
+
7
+ config.autoload_paths += %W(#{config.root}/lib)
8
+
9
+ # use rspec for tests
10
+ config.generators do |g|
11
+ g.test_framework :rspec
12
+ end
13
+
14
+ def self.activate
15
+ Dir.glob(File.join(File.dirname(__FILE__), '../../app/**/*_decorator*.rb')) do |c|
16
+ Rails.configuration.cache_classes ? require(c) : load(c)
17
+ end
18
+ end
19
+
20
+ config.to_prepare &method(:activate).to_proc
21
+ end
22
+ end
@@ -0,0 +1,17 @@
1
+ namespace :spree_roles do
2
+ namespace :permissions do
3
+ desc "Create admin username and password"
4
+ task :populate => :environment do
5
+ admin = Spree::Role.where(:name => 'admin').first_or_create!
6
+ user = Spree::Role.where(:name => 'user').first_or_create!
7
+ user.is_default = true
8
+ user.save!
9
+
10
+ permission1 = Spree::Permission.create!(:title => 'can-manage-all', :priority => 0)
11
+ permission2 = Spree::Permission.create!(:title => 'default-permissions', :priority => 1)
12
+
13
+ user.permissions = [permission2]
14
+ admin.permissions = [permission1]
15
+ end
16
+ end
17
+ end
metadata ADDED
@@ -0,0 +1,92 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: spree_admin_roles_and_access
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.0.0
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Nishant 'CyRo' Tuteja
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2014-01-17 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: spree_core
16
+ requirement: !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ~>
20
+ - !ruby/object:Gem::Version
21
+ version: '2.0'
22
+ type: :runtime
23
+ prerelease: false
24
+ version_requirements: !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ~>
28
+ - !ruby/object:Gem::Version
29
+ version: '2.0'
30
+ description:
31
+ email: info@vinsol.com
32
+ executables: []
33
+ extensions: []
34
+ extra_rdoc_files: []
35
+ files:
36
+ - LICENSE
37
+ - README.md
38
+ - app/assets/stylesheets/store/spree_admin_roles_and_access.css
39
+ - app/assets/stylesheets/admin/spree_admin_roles_and_access.css
40
+ - app/assets/javascripts/store/spree_admin_roles_and_access.js
41
+ - app/assets/javascripts/admin/spree_admin_roles_and_access.js
42
+ - app/overrides/add_roles_to_admin_configuration_sidebar.rb
43
+ - app/models/spree/permission.rb
44
+ - app/models/spree/user_decorator.rb
45
+ - app/models/spree/role_decorator.rb
46
+ - app/models/spree/ability_decorator.rb
47
+ - app/controllers/spree/admin/base_controller_decorator.rb
48
+ - app/controllers/spree/admin/roles_controller.rb
49
+ - app/views/spree/admin/roles/_form.html.erb
50
+ - app/views/spree/admin/roles/new.html.erb
51
+ - app/views/spree/admin/roles/edit.html.erb
52
+ - app/views/spree/admin/roles/index.html.erb
53
+ - config/routes.rb
54
+ - config/locales/en.yml
55
+ - config/initializers/cancan_controller_additions.rb
56
+ - config/initializers/constants.rb
57
+ - config/initializers/cancan_ability.rb
58
+ - config/initializers/cancan_rule.rb
59
+ - lib/generators/spree_admin_roles_and_access/install/install_generator.rb
60
+ - lib/spree/permissions.rb
61
+ - lib/spree_admin_roles_and_access.rb
62
+ - lib/spree_admin_roles_and_access/engine.rb
63
+ - lib/tasks/populate.rake
64
+ - db/migrate/20130709104945_create_spree_roles_permissions.rb
65
+ - db/migrate/20130709104101_create_spree_permissions.rb
66
+ - db/migrate/20130709105614_add_editable_is_default_and_index_on_editable_is_default_and_name_to_spree_roles.rb
67
+ homepage: http://vinsol.com
68
+ licenses: []
69
+ post_install_message:
70
+ rdoc_options: []
71
+ require_paths:
72
+ - lib
73
+ required_ruby_version: !ruby/object:Gem::Requirement
74
+ none: false
75
+ requirements:
76
+ - - ! '>='
77
+ - !ruby/object:Gem::Version
78
+ version: 1.9.3
79
+ required_rubygems_version: !ruby/object:Gem::Requirement
80
+ none: false
81
+ requirements:
82
+ - - ! '>='
83
+ - !ruby/object:Gem::Version
84
+ version: '0'
85
+ requirements:
86
+ - none
87
+ rubyforge_project:
88
+ rubygems_version: 1.8.25
89
+ signing_key:
90
+ specification_version: 3
91
+ summary: Dynamically defines roles and grants it permissions
92
+ test_files: []