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.
- data/LICENSE +26 -0
- data/README.md +79 -0
- data/app/assets/javascripts/admin/spree_admin_roles_and_access.js +1 -0
- data/app/assets/javascripts/store/spree_admin_roles_and_access.js +1 -0
- data/app/assets/stylesheets/admin/spree_admin_roles_and_access.css +3 -0
- data/app/assets/stylesheets/store/spree_admin_roles_and_access.css +3 -0
- data/app/controllers/spree/admin/base_controller_decorator.rb +23 -0
- data/app/controllers/spree/admin/roles_controller.rb +21 -0
- data/app/models/spree/ability_decorator.rb +33 -0
- data/app/models/spree/permission.rb +19 -0
- data/app/models/spree/role_decorator.rb +19 -0
- data/app/models/spree/user_decorator.rb +3 -0
- data/app/overrides/add_roles_to_admin_configuration_sidebar.rb +8 -0
- data/app/views/spree/admin/roles/_form.html.erb +19 -0
- data/app/views/spree/admin/roles/edit.html.erb +2 -0
- data/app/views/spree/admin/roles/index.html.erb +32 -0
- data/app/views/spree/admin/roles/new.html.erb +2 -0
- data/config/initializers/cancan_ability.rb +31 -0
- data/config/initializers/cancan_controller_additions.rb +11 -0
- data/config/initializers/cancan_rule.rb +50 -0
- data/config/initializers/constants.rb +2 -0
- data/config/locales/en.yml +9 -0
- data/config/routes.rb +5 -0
- data/db/migrate/20130709104101_create_spree_permissions.rb +13 -0
- data/db/migrate/20130709104945_create_spree_roles_permissions.rb +11 -0
- data/db/migrate/20130709105614_add_editable_is_default_and_index_on_editable_is_default_and_name_to_spree_roles.rb +10 -0
- data/lib/generators/spree_admin_roles_and_access/install/install_generator.rb +31 -0
- data/lib/spree/permissions.rb +60 -0
- data/lib/spree_admin_roles_and_access.rb +2 -0
- data/lib/spree_admin_roles_and_access/engine.rb +22 -0
- data/lib/tasks/populate.rake +17 -0
- 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.
|
data/README.md
ADDED
@@ -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,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,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,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,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,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"
|
data/config/routes.rb
ADDED
@@ -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,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: []
|