spree_admin_roles_and_access 2.0.0 → 3.2.1.beta

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 (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