effective_roles 1.3.1 → 1.3.2
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.
- checksums.yaml +4 -4
- data/README.md +16 -0
- data/app/helpers/effective_roles_helper.rb +88 -0
- data/app/views/effective/roles/_summary_table.html.haml +12 -0
- data/lib/effective_roles.rb +59 -0
- data/lib/effective_roles/version.rb +1 -1
- data/lib/generators/templates/effective_roles.rb +9 -0
- metadata +3 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: bc53981f7c579c5ff33a87070f1d0a761c2d7fc2
|
4
|
+
data.tar.gz: eb79c31edb80c855541bf78a35eb717b22849af9
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 5f8bc2e438991c33a6eca9a851763d698f9ee664f21757336137901dac1b52f517f2f7c2f0c99b0cd6dd48c8c5505e08eb7f5b29c23c25e9052d2789a16822b8
|
7
|
+
data.tar.gz: 9ed90a7550a6ead52c3a49d43e315fec04e262f8947de555bc7c930128cf00e4f284b2c215c2d6a012c42ced234a6d953a69cd8fd03fa4f3ea0f42e152d1c852
|
data/README.md
CHANGED
@@ -211,6 +211,22 @@ simple_form_for @user do |f|
|
|
211
211
|
= f.input :roles, :collection => EffectiveRoles.roles_collection(f.object, current_user), :as => :check_boxes
|
212
212
|
```
|
213
213
|
|
214
|
+
## Summary table
|
215
|
+
|
216
|
+
Use the `effective_roles_summary_table` view helper to output a table of the actual permission levels for each role and ActiveRecord object combination.
|
217
|
+
|
218
|
+
You can customize the helper function with the following keys: roles, only, except, plus and additionally
|
219
|
+
|
220
|
+
```ruby
|
221
|
+
effective_roles_summary_table(roles: [:admin, :superadmin], only: [Post, Event])
|
222
|
+
effective_roles_summary_table(except: [Post, User])
|
223
|
+
effective_roles_summary_table(plus: [Reports::PostReport]) # Add a non ActiveRecord object to the output, sorted with the other model names
|
224
|
+
effective_roles_summary_table(additionally: [Reports::PostReport]) # Add a non ActiveRecord object to the output, after the other models
|
225
|
+
effective_roles_summary_table(plus: {post_report: :export}) # A custom permission based on a symbol
|
226
|
+
```
|
227
|
+
|
228
|
+
You can override the `effective_roles_authorization_label(klass)` method for better control of the label display.
|
229
|
+
|
214
230
|
## Bitmask Implementation
|
215
231
|
|
216
232
|
The underlying role information for any acts_as_role_restricted ActiveRecord object is stored in that object's roles_mask field.
|
@@ -10,4 +10,92 @@ module EffectiveRolesHelper
|
|
10
10
|
|
11
11
|
render :partial => 'effective/roles/roles_fields', :locals => opts
|
12
12
|
end
|
13
|
+
|
14
|
+
# Output a table of permissions for each role based on current permissions
|
15
|
+
|
16
|
+
# effective_roles_summary_table(roles: [:admin, :superadmin], only: [Post, Event])
|
17
|
+
# effective_roles_summary_table(except: [Post, User])
|
18
|
+
# effective_roles_summary_table(aditionally: [Report::PostReport, User])
|
19
|
+
def effective_roles_summary_table(opts = {})
|
20
|
+
roles = Array(opts[:roles]).presence || EffectiveRoles.roles
|
21
|
+
|
22
|
+
if opts[:only].present?
|
23
|
+
klasses = Array(opts[:only])
|
24
|
+
render partial: '/effective/roles/summary_table', locals: {klasses: klasses, roles: roles}
|
25
|
+
return
|
26
|
+
end
|
27
|
+
|
28
|
+
# Figure out all klasses (ActiveRecord objects)
|
29
|
+
tables = ActiveRecord::Base.connection.tables - ['schema_migrations', 'delayed_jobs']
|
30
|
+
|
31
|
+
klasses = ActiveRecord::Base.descendants.map do |model|
|
32
|
+
model if (model.respond_to?(:table_name) && tables.include?(model.table_name))
|
33
|
+
end.compact
|
34
|
+
|
35
|
+
if opts[:except]
|
36
|
+
klasses = klasses - Array(opts[:except])
|
37
|
+
end
|
38
|
+
|
39
|
+
if opts[:plus]
|
40
|
+
klasses = klasses + Array(opts[:plus])
|
41
|
+
end
|
42
|
+
|
43
|
+
klasses = klasses.sort do |a, b|
|
44
|
+
a = a.respond_to?(:name) ? a.name : a.to_s
|
45
|
+
b = b.respond_to?(:name) ? b.name : b.to_s
|
46
|
+
|
47
|
+
a_namespaces = a.split('::')
|
48
|
+
b_namespaces = b.split('::')
|
49
|
+
|
50
|
+
if a_namespaces.length != b_namespaces.length
|
51
|
+
a_namespaces.length <=> b_namespaces.length
|
52
|
+
else
|
53
|
+
a <=> b
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
if opts[:additionally]
|
58
|
+
klasses = klasses + Array(opts[:additionally])
|
59
|
+
end
|
60
|
+
|
61
|
+
render partial: '/effective/roles/summary_table', locals: {klasses: klasses, roles: roles}
|
62
|
+
end
|
63
|
+
|
64
|
+
def effective_roles_authorization_badge(level)
|
65
|
+
case level
|
66
|
+
when :manage
|
67
|
+
content_tag(:span, 'Full', class: 'label label-success')
|
68
|
+
when :update
|
69
|
+
content_tag(:span, 'Edit', class: 'label label-success')
|
70
|
+
when :update_own
|
71
|
+
content_tag(:span, 'Edit Own', class: 'label label-info')
|
72
|
+
when :create
|
73
|
+
content_tag(:span, 'Create', class: 'label label-success')
|
74
|
+
when :show
|
75
|
+
content_tag(:span, 'Read only', class: 'label label-warning')
|
76
|
+
when :index
|
77
|
+
content_tag(:span, 'Read only', class: 'label label-warning')
|
78
|
+
when :destroy
|
79
|
+
content_tag(:span, 'Delete only', class: 'label label-warning')
|
80
|
+
when :none
|
81
|
+
content_tag(:span, 'No Access', class: 'label label-danger')
|
82
|
+
when :unknown
|
83
|
+
content_tag(:span, 'Unknown', class: 'label')
|
84
|
+
else
|
85
|
+
content_tag(:span, level.to_s.titleize, class: 'label label-success')
|
86
|
+
end
|
87
|
+
end
|
88
|
+
|
89
|
+
def effective_roles_authorization_label(klass)
|
90
|
+
klass = klass.keys.first if klass.kind_of?(Hash)
|
91
|
+
|
92
|
+
label = (klass.respond_to?(:name) ? klass.name : klass.to_s)
|
93
|
+
|
94
|
+
['Effective::Datatables::', 'Effective::'].each do |replace|
|
95
|
+
label = label.sub(replace, '')
|
96
|
+
end
|
97
|
+
|
98
|
+
label
|
99
|
+
end
|
100
|
+
|
13
101
|
end
|
@@ -0,0 +1,12 @@
|
|
1
|
+
%table.table
|
2
|
+
%thead
|
3
|
+
%th
|
4
|
+
- roles.each do |role|
|
5
|
+
%th.text-center= role
|
6
|
+
%tbody
|
7
|
+
- klasses.each do |klass|
|
8
|
+
%tr
|
9
|
+
%td= effective_roles_authorization_label(klass)
|
10
|
+
- roles.each do |role|
|
11
|
+
%td.text-center
|
12
|
+
= effective_roles_authorization_badge(EffectiveRoles.authorization_level(controller, role, klass))
|
data/lib/effective_roles.rb
CHANGED
@@ -8,6 +8,8 @@ module EffectiveRoles
|
|
8
8
|
mattr_accessor :assignable_roles
|
9
9
|
mattr_accessor :disabled_roles
|
10
10
|
|
11
|
+
mattr_accessor :authorization_method_for_summary_table
|
12
|
+
|
11
13
|
def self.setup
|
12
14
|
yield self
|
13
15
|
end
|
@@ -48,6 +50,63 @@ module EffectiveRoles
|
|
48
50
|
user.roles.map { |role| assignable[role] }.flatten.compact.uniq
|
49
51
|
end
|
50
52
|
|
53
|
+
# This is used by the effective_roles_summary_table helper method
|
54
|
+
def self.authorization_level(controller, role, resource)
|
55
|
+
auth_method = authorization_method_for_summary_table
|
56
|
+
|
57
|
+
return :unknown unless (auth_method.respond_to?(:call) || auth_method.kind_of?(Symbol))
|
58
|
+
return :unknown unless (controller.current_user rescue nil).respond_to?(:roles=)
|
59
|
+
|
60
|
+
controller.instance_variable_set(:@current_ability, nil)
|
61
|
+
controller.current_user.roles = [role]
|
62
|
+
resource = (resource.new() rescue resource)
|
63
|
+
|
64
|
+
# Custom actions
|
65
|
+
if resource.kind_of?(Hash)
|
66
|
+
resource.each do |key, value|
|
67
|
+
return value if (controller.instance_exec(controller, value, key, &auth_method) rescue false)
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
# Check for Manage
|
72
|
+
return :manage if (
|
73
|
+
(controller.instance_exec(controller, :create, resource, &auth_method) rescue false) &&
|
74
|
+
(controller.instance_exec(controller, :update, resource, &auth_method) rescue false) &&
|
75
|
+
(controller.instance_exec(controller, :show, resource, &auth_method) rescue false) &&
|
76
|
+
(controller.instance_exec(controller, :destroy, resource, &auth_method) rescue false)
|
77
|
+
)
|
78
|
+
|
79
|
+
# Check for Update
|
80
|
+
return :update if (controller.instance_exec(controller, :update, resource, &auth_method) rescue false)
|
81
|
+
|
82
|
+
# Check for Update Own
|
83
|
+
if resource.respond_to?('user=')
|
84
|
+
resource.user = controller.current_user
|
85
|
+
return :update_own if (controller.instance_exec(controller, :update, resource, &auth_method) rescue false)
|
86
|
+
resource.user = nil
|
87
|
+
elsif resource.respond_to?('user_id=')
|
88
|
+
resource.user_id = controller.current_user.id
|
89
|
+
return :update_own if (controller.instance_exec(controller, :update, resource, &auth_method) rescue false)
|
90
|
+
resource.user_id = nil
|
91
|
+
elsif resource.kind_of?(User)
|
92
|
+
return :update_own if (controller.instance_exec(controller, :update, controller.current_user, &auth_method) rescue false)
|
93
|
+
end
|
94
|
+
|
95
|
+
# Check for Create
|
96
|
+
return :create if (controller.instance_exec(controller, :create, resource, &auth_method) rescue false)
|
97
|
+
|
98
|
+
# Check for Show
|
99
|
+
return :show if (controller.instance_exec(controller, :show, resource, &auth_method) rescue false)
|
100
|
+
|
101
|
+
# Check for Index
|
102
|
+
return :index if (controller.instance_exec(controller, :index, resource, &auth_method) rescue false)
|
103
|
+
|
104
|
+
# Check for Destroy
|
105
|
+
return :destroy if (controller.instance_exec(controller, :destroy, resource, &auth_method) rescue false)
|
106
|
+
|
107
|
+
:none
|
108
|
+
end
|
109
|
+
|
51
110
|
private
|
52
111
|
|
53
112
|
def self.role_description(role, obj = nil)
|
@@ -77,4 +77,13 @@ EffectiveRoles.setup do |config|
|
|
77
77
|
}
|
78
78
|
|
79
79
|
|
80
|
+
# config.authorization_method_for_summary_table
|
81
|
+
# This has absolutely no affect on the any logic involving roles
|
82
|
+
# It's purely for the effective_roles_summary_table() helper method
|
83
|
+
#
|
84
|
+
# It should match the authorization check used by your application
|
85
|
+
#
|
86
|
+
# Use CanCan: can?(action, resource)
|
87
|
+
config.authorization_method_for_summary_table = Proc.new { |controller, action, resource| true }
|
88
|
+
|
80
89
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: effective_roles
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.3.
|
4
|
+
version: 1.3.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Code and Effect
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2015-
|
11
|
+
date: 2015-10-28 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rails
|
@@ -165,6 +165,7 @@ files:
|
|
165
165
|
- app/helpers/effective_roles_helper.rb
|
166
166
|
- app/models/concerns/acts_as_role_restricted.rb
|
167
167
|
- app/views/effective/roles/_roles_fields.html.haml
|
168
|
+
- app/views/effective/roles/_summary_table.html.haml
|
168
169
|
- lib/effective_roles.rb
|
169
170
|
- lib/effective_roles/engine.rb
|
170
171
|
- lib/effective_roles/version.rb
|