spree_admin_roles_and_access 2.0.0 → 3.2.1.beta

Sign up to get free protection for your applications and to get access to all the features.
Files changed (49) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +76 -39
  3. data/app/assets/javascripts/spree/backend/spree_admin_roles_and_access.js +84 -1
  4. data/app/assets/stylesheets/spree/backend/spree_admin_roles_and_access.css +131 -1
  5. data/app/controllers/spree/admin/base_controller_decorator.rb +4 -0
  6. data/app/controllers/spree/admin/default_admin_dashboards_controller.rb +13 -0
  7. data/app/controllers/spree/admin/permission_sets_controller.rb +26 -0
  8. data/app/controllers/spree/admin/roles_controller.rb +5 -5
  9. data/app/models/spree/ability_decorator.rb +6 -5
  10. data/app/models/spree/permission.rb +11 -3
  11. data/app/models/spree/permission_set.rb +11 -0
  12. data/app/models/spree/permissions_permission_set.rb +6 -0
  13. data/app/models/spree/role_decorator.rb +8 -2
  14. data/app/models/spree/roles_permission.rb +5 -0
  15. data/app/models/spree/roles_permission_set.rb +6 -0
  16. data/app/models/spree/user_decorator.rb +2 -1
  17. data/app/overrides/spree/admin/roles/_form/add_permission_sets_to_role_form.html.erb.deface +28 -0
  18. data/app/overrides/spree/admin/shared/sub_menu/_configuration/add_permission_sets_To_configuration_sub_menu.html.erb.deface +2 -0
  19. data/app/views/spree/admin/default_admin_dashboards/show.html.erb +1 -0
  20. data/app/views/spree/admin/permission_sets/_form.html.erb +49 -0
  21. data/app/views/spree/admin/permission_sets/_permission_pane.html.erb +19 -0
  22. data/app/views/spree/admin/permission_sets/edit.html.erb +12 -0
  23. data/app/views/spree/admin/permission_sets/index.html.erb +33 -0
  24. data/app/views/spree/admin/permission_sets/new.html.erb +12 -0
  25. data/app/views/spree/admin/permissions/_form.html.erb +37 -6
  26. data/app/views/spree/admin/permissions/index.html.erb +0 -2
  27. data/app/views/spree/admin/shared/_checkbox_list_pane.html.erb +20 -0
  28. data/config/initializers/auth.rb +13 -0
  29. data/config/initializers/cancan_ability.rb +1 -1
  30. data/config/initializers/cancan_controller_additions.rb +3 -3
  31. data/config/initializers/constants.rb +2 -2
  32. data/config/locales/en.yml +15 -1
  33. data/config/routes.rb +2 -0
  34. data/db/migrate/20130709104101_create_spree_permissions.rb +4 -4
  35. data/db/migrate/20130709104945_create_spree_roles_permissions.rb +3 -3
  36. data/db/migrate/20130709105614_add_editable_is_default_and_index_on_editable_is_default_and_name_to_spree_roles.rb +2 -3
  37. data/db/migrate/20170503090436_create_spree_permission_sets.rb +9 -0
  38. data/db/migrate/20170503091013_create_spree_roles_permission_sets.rb +8 -0
  39. data/db/migrate/20170503101648_create_spree_permissions_permission_sets.rb +8 -0
  40. data/db/migrate/20170508082615_add_description_to_permissions_and_permission_sets.rb +6 -0
  41. data/db/migrate/20170508082722_add_display_boolean_to_permission_sets.rb +5 -0
  42. data/db/migrate/20170508091139_deprecate_legacy_roles_and_permissions.rb +29 -0
  43. data/db/migrate/20170509082144_remove_column_boolean_from_permissions.rb +5 -0
  44. data/db/migrate/20170509090346_add_admin_boolean_to_roles.rb +5 -0
  45. data/lib/generators/spree_admin_roles_and_access/install/install_generator.rb +3 -3
  46. data/lib/spree/permissions.rb +7 -7
  47. data/lib/tasks/populate.rake +354 -72
  48. metadata +70 -17
  49. data/app/overrides/spree/admin/roles/_form/add_permissions_to_role_form.html.erb.deface +0 -13
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 64146eca6e414833fc625640dbcf12effbd80543
4
- data.tar.gz: f611e1895d9ca6dbde6c3dfeca952b06f3461690
3
+ metadata.gz: a17455fffb63fe6f9be0ea4e21d5c55676c485ae
4
+ data.tar.gz: 3e7af0767d716a00d0b2ee0260a0e32bf756456e
5
5
  SHA512:
6
- metadata.gz: a45920143eb48b5918613f6f607ec98a749300f9a7814ed11d64c5ff42544c7da2ac268f5aa64032b8cec1cbdf572d5a1174342f434163468ec1f9975f3017e2
7
- data.tar.gz: 3f26e89a3a966d30a58f19b329b095c59dcc2496e992229b7da4415c2b4f011b0e7e1bff39e9875be1d75ccbf89172ceaa33773ad24c79cba1221b4c39841cb7
6
+ metadata.gz: bac48fa3b25d9b140376843107a32ee10d4a536343d9c5b456d6f3fbfe6cf8ef3aa1a71659f7fd70f0b0de782630b640f0b5aa84e4f3a6f711a3a2b3a751e439
7
+ data.tar.gz: 25a2c4997fc9d53a1c524b5f69c3bf8895d33855c188c584994d4d4ac1e7414256352a763f9eefbb4855393661f97b7a9d4d0ea30617b29486d3e88abe064c07
data/README.md CHANGED
@@ -1,7 +1,14 @@
1
1
  SpreeAdminRolesAndAccess [![Code Climate](https://codeclimate.com/github/vinsol/spree_admin_roles_and_access.png)](https://codeclimate.com/github/vinsol/spree_admin_roles_and_access) [![Build Status](https://travis-ci.org/vinsol/spree_admin_roles_and_access.png?branch=master)](https://travis-ci.org/vinsol/spree_admin_roles_and_access)
2
2
  ========================
3
3
 
4
- This spree extension is build on CanCan to dynamically add new roles and define its access through permissions.
4
+ This spree extension is built on CanCan to dynamically add new roles and define its access through permissions.
5
+
6
+ Screenshots
7
+ -----------
8
+
9
+ ![Permission Sets](/screenshots/admin1.png "Creating Permission Sets")
10
+ ![Roles](/screenshots/admin2.png "Creating Roles from permission sets")
11
+
5
12
 
6
13
  Installation
7
14
  ------------
@@ -12,62 +19,58 @@ Add spree_admin_roles_and_access to your Gemfile:
12
19
  gem 'spree_admin_roles_and_access'
13
20
  ```
14
21
 
15
- But if you are using older version of spree
16
-
17
-
18
- ```ruby
19
- # Spree 2.4.0-rc3
20
- gem 'spree_admin_roles_and_access', '1.3.0'
21
- ```
22
-
23
-
24
- ```ruby
25
- # Spree 2.1.x
26
- gem 'spree_admin_roles_and_access', '1.1.0'
27
- ```
28
-
29
- ```ruby
30
- # Spree 2.0.x
31
- gem 'spree_admin_roles_and_access', '1.0.0'
32
- ```
33
-
34
22
  Bundle your dependencies and run the installation generator:
35
23
 
36
24
  ```shell
37
25
  bundle
38
26
  bundle exec rails g spree_admin_roles_and_access:install
39
27
  bundle exec rake spree_roles:permissions:populate # To populate user and admin roles with their permissions
28
+ bundle exec rake spree_roles:permissions:populate_permission_sets # To set up some convenient permission sets.
40
29
  ```
41
30
 
42
31
  Usage
43
32
  -----
44
33
 
45
- From Admin end, there is a role menu in configuration tab(admin end).
46
- A new Role can be added and its corresponding permissions can also be selected there.
47
- Permission to be chosen can be made only with rails console or a ruby script.
34
+ From Admin end, There are three menu's in the configuration Tab:
35
+
36
+ 1. **Permission:** Describes what the user can do.
37
+ 2. **Permission Set:** A collection of permission describing an aspect of role.
38
+ 3. **Role:** Collection of multiple permission sets which describe the role of user in the organisation. A role can be marked as `admin_accessible` in the role edit page.
39
+ A role marked as such will get a default admin dashboard page in case they land on an admin page on which they do not have access.
48
40
 
49
41
  Types of Permission
42
+ -------------------
43
+
44
+ 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.
45
+ 2. **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.
46
+ 3. **Resource Manage Permission** - Each Resource has an associated admin permission that is required for accessing it. i.e. `can-admin-spree/products`
47
+ 4. **Resource Permission** - What the user is allowed to do with the resource. i.e. `Create`, `Update`, `Delete`, `List` or `Show`.
48
+
49
+
50
50
 
51
- 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.
51
+ Pattern of the permissions
52
+ --------------------------
52
53
 
53
- 2. Default Admin Permission - Because of this permission an admin can go to '/admin' route.
54
+ 1. **Can/cannot** - specifies whether the user with that permission can do or cannot do that task.
55
+ 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.
56
+ 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.
57
+ 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.
54
58
 
55
- 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.
59
+ Some Examples
60
+ -------------
56
61
 
57
- Pattern of the permissions :-
62
+ 1. **can-manage-spree/product** - can perform every action on Spree::Product but not on any other model or subject.
63
+ 2. **can-update-all** - can update all models or subjects.
64
+ 3. **can-update-spree/product** - can update only products, and not users, orders and other things.
65
+ 4. **can-update-spree/product-price** - can update only price of products.
66
+ 5. **can-manage-all** - can perform every action on all models.
58
67
 
59
- 1. Can/cannot - specifies whether the user with that permission can do or cannot do that task.
60
- 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.
61
- 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.
62
- 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.
63
68
 
64
- Some Examples :-
69
+ Permission Sets
70
+ ---------------
71
+
72
+ Once permissions are created you can organize groups of them into permission sets, These permission sets can then be assigned to the user's role which requires them.
65
73
 
66
- 1. can-manage-spree/product - can perform every action on Spree::Product but not on any other model or subject.
67
- 2. can-update-all - can update all models or subjects.
68
- 3. can-update-spree/product - can update only products, and not users, orders and other things.
69
- 4. can-update-spree/product-price - can update only price of products.
70
- 5. can-manage-all - can perform every action on all models.
71
74
 
72
75
  Points to remember
73
76
 
@@ -78,8 +81,21 @@ Points to remember
78
81
  To create a product, can-admin-spree/product is also needed along with can-create-spree/product.
79
82
 
80
83
  3. To define custom cancan permissions, which can not be made with the pattern adopted.
81
- Override a module Permission. And define the permission in a method, and create a permission in the database.
84
+ Override the module Permission. And define the permission in a method, and create a permission in the database. See example of `default-permission`.
85
+
86
+
87
+ Migration from older version
88
+ ----------------------------
89
+
90
+ __v3.2.1 introduces some breaking changes.__
91
+
92
+ After updating the gem version. Run `rails g spree_admin_roles_and_access:install` to get the latest migrations. This includes a migration that generates a permission set per user role. With this, you should be able to continue using the original roles as you were earlier.
93
+
94
+ Additionally you may want to run the rake task `populate_permission_sets` to seed some initial permission sets. You can now gradually opt into seperating user role permissions into appropriate permission sets.
95
+
96
+ The original relationship between roles and permissions can be accessed via, `legacy_roles` & `legacy_permissions`. They are not supported or editable via the admin interfaces and are only mantained for use in our migration task.
82
97
 
98
+ **Note in the previous version read action was only for show. That has been superseded by read action now implying both show and index.**
83
99
 
84
100
  Testing
85
101
  -------
@@ -92,6 +108,27 @@ bundle exec rake test_app
92
108
  bundle exec rspec spec
93
109
  ```
94
110
 
111
+ For older versions of spree
112
+ ----------------------------
113
+
114
+ If you are using older version of spree. You can use the following version, please check the relavent readme for version specific installation guide.
115
+
116
+
117
+ ```ruby
118
+ # Spree 2.4.0-rc3
119
+ gem 'spree_admin_roles_and_access', '1.3.0'
120
+ ```
121
+
122
+ ```ruby
123
+ # Spree 2.1.x
124
+ gem 'spree_admin_roles_and_access', '1.1.0'
125
+ ```
126
+
127
+ ```ruby
128
+ # Spree 2.0.x
129
+ gem 'spree_admin_roles_and_access', '1.0.0'
130
+ ```
131
+
95
132
  Contributing
96
133
  ------------
97
134
 
@@ -109,4 +146,4 @@ Credits
109
146
 
110
147
  [![vinsol.com: Ruby on Rails, iOS and Android developers](http://vinsol.com/vin_logo.png "Ruby on Rails, iOS and Android developers")](http://vinsol.com)
111
148
 
112
- Copyright (c) 2014 [vinsol.com](http://vinsol.com "Ruby on Rails, iOS and Android developers"), released under the New MIT License
149
+ Copyright (c) 2017 [vinsol.com](http://vinsol.com "Ruby on Rails, iOS and Android developers"), released under the New MIT License
@@ -1 +1,84 @@
1
- //= require spree/backend
1
+ //= require spree/backend
2
+
3
+ var SearchableList = (function() {
4
+ var SearchableCheckboxList = function(container) {
5
+ this.$searchBox = $("<div class='input-group input-group-lg col-xs-12'>\
6
+ <input type='text' placeholder='Search..' class='narrow-down-list form-control'></input>\
7
+ <div class='input-group-btn search-icon-btn'>\
8
+ <button class='btn btn-default' type='submit'><i class='glyphicon glyphicon-search'></i></button>\
9
+ </div>\
10
+ </div>");
11
+ this.$container = container;
12
+ container.before(this.$searchBox);
13
+ this.bindEvents();
14
+ };
15
+
16
+ SearchableCheckboxList.prototype.bindEvents = function() {
17
+ this.bindSearch();
18
+ this.bindCheck();
19
+ this.formChange();
20
+ };
21
+
22
+ SearchableCheckboxList.prototype.bindCheck = function() {
23
+ this.$container.find('.list-group-item').on('click', function(e) {
24
+ if (this == e.target) {
25
+ $(this).find('input:checkbox').click();
26
+ }
27
+ });
28
+
29
+ this.$container.find('input:checkbox').on('change', function() {
30
+ var checkbox = $(this);
31
+ var lgItem = checkbox.parents('.list-group-item');
32
+ var lg = checkbox.parents('.list-group');
33
+ var total = lg.find('.list-group-item').length;
34
+ var totalChecked = lg.find('input:checked').length;
35
+ lgItem.toggleClass('list-group-item-success');
36
+ checkbox.parents('.panel').find('.count').text(totalChecked + '/' + total);
37
+ });
38
+ };
39
+
40
+ SearchableCheckboxList.prototype.bindSearch = function() {
41
+ var that = this;
42
+ this.$searchBox.on('keyup', function(e) {
43
+ var value = $(this).find('input').val();
44
+ var pattern = new RegExp(value, "i");
45
+
46
+ that.$container.find('.list-group-item').each(function() {
47
+ if (!($(this).text().search(pattern) >= 0)) {
48
+ $(this).hide();
49
+ } else {
50
+ $(this).show();
51
+ }
52
+ });
53
+ });
54
+ };
55
+
56
+ SearchableCheckboxList.prototype.formChange = function() {
57
+ var that = this;
58
+ var form = this.$container.closest('form');
59
+ var buttons = form.find('button');
60
+ buttons.attr('disabled', true);
61
+ form.find('input:not(.narrow-down-list)').one('keyup', function() {
62
+ buttons.attr('disabled', false);
63
+ });
64
+ form.find('input').on('change', function() {
65
+ buttons.attr('disabled', false);
66
+ });
67
+
68
+ form.on('keypress', function(e) {
69
+ if (e.which === 13){
70
+ e.preventDefault();
71
+ e.stopPropagation();
72
+ return false;
73
+ }
74
+ });
75
+ };
76
+
77
+
78
+
79
+ return SearchableCheckboxList;
80
+ })();
81
+
82
+ $(document).ready(function() {
83
+ $('.searchable-scrollable-list').each(function() { new SearchableList($(this)); });
84
+ });
@@ -1,3 +1,133 @@
1
1
  /*
2
2
  *= require spree/backend
3
- */
3
+ */
4
+
5
+ .searchable-scrollable-list {
6
+ padding-top: 10px;
7
+ width: 100%;
8
+ vertical-align: top;
9
+ display: flex;
10
+ }
11
+
12
+ .scrollable-list-group-item {
13
+ padding-left: 2px;
14
+ padding-right: 2px;
15
+ flex: 1;
16
+ display: inline-block;
17
+ }
18
+
19
+ .inline-input-row {
20
+ width: 100%;
21
+ padding-left: 0px;
22
+ padding-right: 0px;
23
+ padding-top: 10px;
24
+ padding-bottom: 10px;
25
+ margin-left: 0px;
26
+ margin-right: 0px;
27
+ }
28
+
29
+ .inline-input-row > .input-group {
30
+ vertical-align: top;
31
+ width: 49.8%;
32
+ margin: 0;
33
+ padding: 0;
34
+ }
35
+
36
+ .scrollable-list-group-item > .panel > .list-group {
37
+ max-height: 400px;
38
+ overflow-y: scroll;
39
+ }
40
+
41
+ .list-group-item > label {
42
+ text-transform: none;
43
+ }
44
+
45
+ .scrollable-list-group-item > .panel > .list-group > .list-group-item {
46
+ user-select: none;
47
+ cursor: pointer;
48
+ }
49
+
50
+ .scrollable-list-group-item label {
51
+ cursor: pointer;
52
+ }
53
+
54
+
55
+ .centered-floating-buttons {
56
+ }
57
+
58
+ .form-fields-group {
59
+ padding-bottom: 58px;
60
+ }
61
+
62
+ .fixed-bottom-button-group {
63
+ background: #fff;
64
+ text-align: left;
65
+ position: fixed;
66
+ bottom: 0;
67
+ left: 0;
68
+ right: 0;
69
+ padding: 10px;
70
+ z-index: 999;
71
+ padding-left: calc(16% + 45px);
72
+ }
73
+
74
+ .full-width-input {
75
+ min-width: 100%;
76
+ }
77
+
78
+ .help-block-inline {
79
+ display: inline-block;
80
+ padding: 10px;
81
+ }
82
+
83
+
84
+ #permission_set_display_permission {
85
+ margin-left: 20px;
86
+ }
87
+
88
+ #permission_set_permissions_field {
89
+ padding-top: 20px;
90
+ }
91
+
92
+ .checkbox-list-pane.list-group-item label {
93
+ color: #555555;
94
+ }
95
+
96
+ .checkbox-list-pane.list-group-item > label > p {
97
+ padding-top: 0.6em;
98
+ margin-bottom: -0.6em;
99
+ }
100
+
101
+ .checkbox-list-pane.list-group-item > label > p > strong {
102
+ font-size: 1.3em;
103
+ font-weight: 300;
104
+ }
105
+
106
+
107
+ .add-on .input-group-btn > .btn {
108
+ border-left-width:0;left:-2px;
109
+ -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);
110
+ box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);
111
+ }
112
+ /* stop the glowing blue shadow */
113
+ .add-on .form-control:focus {
114
+ box-shadow:none;
115
+ -webkit-box-shadow:none;
116
+ border-color:#cccccc;
117
+ }
118
+
119
+ div.withError > .searchable-scrollable-list > .panel-group > .panel {
120
+ border: 1px solid #F55753;
121
+ }
122
+
123
+ div.withError > div.input-group > input.narrow-down-list {
124
+ border-color: #e0e0e0
125
+ }
126
+
127
+ #main-part.sidebar-collapsed .fixed-bottom-button-group {
128
+ padding-left: 85px;
129
+ }
130
+
131
+ .input-group-btn.search-icon-btn {
132
+ width: 1% !important;
133
+ }
@@ -17,6 +17,10 @@ Spree::Admin::BaseController.class_eval do
17
17
  end
18
18
 
19
19
  private
20
+ def unauthorized
21
+ redirect_unauthorized_access
22
+ end
23
+
20
24
  def new_action?
21
25
  NEW_ACTIONS.include?(params[:action].to_sym)
22
26
  end
@@ -0,0 +1,13 @@
1
+ class Spree::Admin::DefaultAdminDashboardsController < Spree::Admin::BaseController
2
+ skip_before_action :authorize_admin, only: :show
3
+ before_action :authorize_user_has_admin_role, only: :show
4
+
5
+ def show
6
+ end
7
+
8
+ private def authorize_user_has_admin_role
9
+ user = try_spree_current_user
10
+ raise CanCan::AccessDenied unless user.present?
11
+ raise CanCan::AccessDenied unless user.roles.any? { |role| role.admin_accessible? }
12
+ end
13
+ end
@@ -0,0 +1,26 @@
1
+ module Spree
2
+ module Admin
3
+ class PermissionSetsController < ResourceController
4
+ before_action :load_permissions, only: [:edit, :new, :create, :update]
5
+
6
+ def index
7
+ if params[:q]
8
+ params[:q][:s] = params[:q][:s] || 'updated_at desc'
9
+ else
10
+ params[:q] = {}
11
+ params[:q][:s] = "updated_at desc"
12
+ end
13
+ @search = Spree::PermissionSet.ransack(params[:q])
14
+ @permission_sets = @search.result(distinct: true)
15
+ end
16
+
17
+ private def permitted_resource_params
18
+ params.require(:permission_set).permit(:name, :description, :display_permission, permission_ids: [])
19
+ end
20
+
21
+ private def load_permissions
22
+ @permissions = Spree::Permission.visible.all
23
+ end
24
+ end
25
+ end
26
+ end