stffn-declarative_authorization 0.3.0 → 0.3.1
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGELOG +9 -0
- data/README.rdoc +22 -6
- data/app/controllers/authorization_rules_controller.rb +135 -14
- data/app/helpers/authorization_rules_helper.rb +96 -13
- data/app/views/authorization_rules/_change.erb +49 -0
- data/app/views/authorization_rules/_show_graph.erb +37 -0
- data/app/views/authorization_rules/_suggestion.erb +9 -0
- data/app/views/authorization_rules/_suggestions.erb +24 -0
- data/app/views/authorization_rules/change.html.erb +124 -0
- data/app/views/authorization_rules/graph.dot.erb +23 -4
- data/app/views/authorization_rules/graph.html.erb +1 -0
- data/app/views/authorization_rules/index.html.erb +3 -2
- data/app/views/authorization_usages/index.html.erb +2 -11
- data/config/routes.rb +2 -1
- data/lib/declarative_authorization/authorization.rb +87 -35
- data/lib/declarative_authorization/development_support/analyzer.rb +252 -0
- data/lib/declarative_authorization/development_support/change_analyzer.rb +253 -0
- data/lib/declarative_authorization/development_support/change_supporter.rb +578 -0
- data/lib/declarative_authorization/development_support/development_support.rb +243 -0
- data/lib/declarative_authorization/helper.rb +6 -2
- data/lib/declarative_authorization/in_controller.rb +254 -26
- data/lib/declarative_authorization/in_model.rb +27 -2
- data/lib/declarative_authorization/maintenance.rb +22 -8
- data/lib/declarative_authorization/obligation_scope.rb +14 -9
- data/lib/declarative_authorization/reader.rb +10 -2
- data/test/authorization_test.rb +44 -0
- data/test/controller_filter_resource_access_test.rb +385 -0
- data/test/controller_test.rb +14 -6
- data/test/helper_test.rb +21 -0
- data/test/maintenance_test.rb +26 -0
- data/test/model_test.rb +28 -0
- data/test/test_helper.rb +14 -1
- metadata +15 -5
- data/lib/declarative_authorization/authorization_rules_analyzer.rb +0 -138
- data/test/authorization_rules_analyzer_test.rb +0 -123
data/CHANGELOG
CHANGED
@@ -1,3 +1,12 @@
|
|
1
|
+
* Simplified controller authorization with filter_resource_access [sb]
|
2
|
+
|
3
|
+
* Allow passing explicit context in addition to object in permitted_to? [Olly Lylo, sb]
|
4
|
+
|
5
|
+
* Change Supporter: suggest changes to authorization rules [sb]
|
6
|
+
|
7
|
+
* Added permitted_to!/? in model [Eike Carls]
|
8
|
+
|
9
|
+
* New test helper: should_(not_)_be_allowed_to(privilege, object_or_context) [sb]
|
1
10
|
|
2
11
|
** RELEASE 0.3 (April 20, 2009) **
|
3
12
|
|
data/README.rdoc
CHANGED
@@ -79,12 +79,26 @@ generated yourself or at http://www.tzi.org/~sbartsch/declarative_authorization
|
|
79
79
|
|
80
80
|
== Controller
|
81
81
|
|
82
|
-
If authentication is in place,
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
82
|
+
If authentication is in place, there are two ways to enable user-specific
|
83
|
+
access control on controller actions. For resource controllers, which more
|
84
|
+
or less follow the CRUD pattern, +filter_resource_access+ is the simplest
|
85
|
+
approach. It sets up instance variables in before filters and calls
|
86
|
+
filter_access_to with the appropriate parameters to protect the CRUD methods.
|
87
|
+
|
88
|
+
class EmployeesController < ApplicationController
|
89
|
+
filter_resource_access
|
90
|
+
...
|
91
|
+
end
|
92
|
+
|
93
|
+
See Authorization::AuthorizationInController::ClassMethods for options on
|
94
|
+
nested resources and custom member and collection actions.
|
95
|
+
|
96
|
+
If you prefer less magic or your controller has no resemblance with the resource
|
97
|
+
controllers, directly calling filter_access_to may be the better option. Examples
|
98
|
+
are given in the following. E.g. the privilege index users is required for
|
99
|
+
action index. This works as a first default configuration for RESTful
|
100
|
+
controllers, with these privileges easily handled in the authorization
|
101
|
+
configuration, which will be described below.
|
88
102
|
|
89
103
|
class EmployeesController < ApplicationController
|
90
104
|
filter_access_to :all
|
@@ -473,10 +487,12 @@ sbartsch at tzi.org
|
|
473
487
|
= Contributors
|
474
488
|
|
475
489
|
Thanks to
|
490
|
+
* Eike Carls
|
476
491
|
* Erik Dahlstrand
|
477
492
|
* Jeremy Friesen
|
478
493
|
* Brian Langenfeld
|
479
494
|
* Geoff Longman
|
495
|
+
* Olly Lylo
|
480
496
|
* Mark Mansour
|
481
497
|
* Mike Vincent
|
482
498
|
|
@@ -1,6 +1,8 @@
|
|
1
1
|
if Authorization::activate_authorization_rules_browser?
|
2
2
|
|
3
|
-
require File.join(File.dirname(__FILE__), %w{.. .. lib declarative_authorization
|
3
|
+
require File.join(File.dirname(__FILE__), %w{.. .. lib declarative_authorization development_support analyzer})
|
4
|
+
require File.join(File.dirname(__FILE__), %w{.. .. lib declarative_authorization development_support change_supporter})
|
5
|
+
require File.join(File.dirname(__FILE__), %w{.. .. lib declarative_authorization development_support development_support})
|
4
6
|
|
5
7
|
begin
|
6
8
|
# for nice auth_rules output:
|
@@ -28,29 +30,105 @@ class AuthorizationRulesController < ApplicationController
|
|
28
30
|
end
|
29
31
|
end
|
30
32
|
|
33
|
+
def change
|
34
|
+
@users = find_all_users
|
35
|
+
@users.sort! {|a, b| a.login <=> b.login }
|
36
|
+
|
37
|
+
@privileges = authorization_engine.auth_rules.collect {|rule| rule.privileges.to_a}.flatten.uniq
|
38
|
+
@privileges = @privileges.collect {|priv| Authorization::DevelopmentSupport::AnalyzerEngine::Privilege.for_sym(priv, authorization_engine).descendants.map(&:to_sym) }.flatten.uniq
|
39
|
+
@privileges.sort_by {|priv| priv.to_s}
|
40
|
+
@privilege = params[:privilege].to_sym rescue @privileges.first
|
41
|
+
@contexts = authorization_engine.auth_rules.collect {|rule| rule.contexts.to_a}.flatten.uniq
|
42
|
+
@context = params[:context].to_sym rescue @contexts.first
|
43
|
+
|
44
|
+
respond_to do |format|
|
45
|
+
format.html
|
46
|
+
format.js do
|
47
|
+
render :partial => 'change'
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
def suggest_change
|
53
|
+
users_permission = params[:user].inject({}) do |memo, (user_id, data)|
|
54
|
+
if data[:permission] != "undetermined"
|
55
|
+
begin
|
56
|
+
memo[find_user_by_id(user_id)] = (data[:permission] == 'yes')
|
57
|
+
rescue ActiveRecord::NotFound
|
58
|
+
end
|
59
|
+
end
|
60
|
+
memo
|
61
|
+
end
|
62
|
+
|
63
|
+
prohibited_actions = (params[:prohibited_action] || []).collect do |spec|
|
64
|
+
deserialize_changes(spec).flatten
|
65
|
+
end
|
66
|
+
|
67
|
+
users_keys = users_permission.keys
|
68
|
+
analyzer = Authorization::DevelopmentSupport::ChangeSupporter.new(authorization_engine)
|
69
|
+
|
70
|
+
privilege = params[:privilege].to_sym
|
71
|
+
context = params[:context].to_sym
|
72
|
+
@context = context
|
73
|
+
@approaches = analyzer.find_approaches_for(:users => users_keys, :prohibited_actions => prohibited_actions) do
|
74
|
+
users.each_with_index do |user, idx|
|
75
|
+
args = [privilege, {:context => context, :user => user}]
|
76
|
+
assert(users_permission[users_keys[idx]] ? permit?(*args) : !permit?(*args))
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
80
|
+
respond_to do |format|
|
81
|
+
format.js do
|
82
|
+
render :partial => 'suggestions'
|
83
|
+
end
|
84
|
+
end
|
85
|
+
end
|
86
|
+
|
31
87
|
private
|
32
88
|
def auth_to_dot (options = {})
|
33
89
|
options = {
|
34
90
|
:effective_role_privs => true,
|
35
91
|
:privilege_hierarchy => false,
|
92
|
+
:stacked_roles => false,
|
36
93
|
:only_relevant_contexts => true,
|
94
|
+
:only_relevant_roles => false,
|
37
95
|
:filter_roles => nil,
|
38
96
|
:filter_contexts => nil,
|
39
|
-
:highlight_privilege => nil
|
97
|
+
:highlight_privilege => nil,
|
98
|
+
:changes => nil,
|
99
|
+
:users => nil
|
40
100
|
}.merge(options)
|
41
101
|
|
102
|
+
@has_changes = options[:changes] && !options[:changes].empty?
|
42
103
|
@highlight_privilege = options[:highlight_privilege]
|
43
|
-
@
|
44
|
-
|
45
|
-
@
|
46
|
-
|
104
|
+
@stacked_roles = options[:stacked_roles]
|
105
|
+
|
106
|
+
@users = options[:users]
|
107
|
+
|
108
|
+
engine = authorization_engine.clone
|
109
|
+
@changes = replay_changes(engine, @users, options[:changes]) if options[:changes]
|
110
|
+
|
111
|
+
options[:filter_roles] ||= @users.collect {|user| user.role_symbols}.flatten.uniq if options[:only_relevant_roles] and @users
|
112
|
+
|
113
|
+
filter_roles_flattened = nil
|
114
|
+
if options[:filter_roles]
|
115
|
+
filter_roles_flattened = options[:filter_roles].collect do |role_sym|
|
116
|
+
Authorization::DevelopmentSupport::AnalyzerEngine::Role.for_sym(role_sym, engine).
|
117
|
+
ancestors.map(&:to_sym) + [role_sym]
|
118
|
+
end.flatten.uniq
|
119
|
+
end
|
120
|
+
|
121
|
+
@roles = engine.roles
|
122
|
+
@roles = @roles.select {|r| filter_roles_flattened.include?(r) } if options[:filter_roles]
|
123
|
+
@role_hierarchy = engine.role_hierarchy
|
124
|
+
@privilege_hierarchy = engine.privilege_hierarchy
|
47
125
|
|
48
|
-
@contexts =
|
126
|
+
@contexts = engine.auth_rules.
|
49
127
|
collect {|ar| ar.contexts.to_a}.flatten.uniq
|
50
128
|
@contexts = @contexts.select {|c| c == options[:filter_contexts] } if options[:filter_contexts]
|
51
129
|
@context_privs = {}
|
52
130
|
@role_privs = {}
|
53
|
-
|
131
|
+
engine.auth_rules.each do |auth_rule|
|
54
132
|
@role_privs[auth_rule.role] ||= []
|
55
133
|
auth_rule.contexts.
|
56
134
|
select {|c| options[:filter_contexts].nil? or c == options[:filter_contexts]}.
|
@@ -64,15 +142,23 @@ class AuthorizationRulesController < ApplicationController
|
|
64
142
|
|
65
143
|
if options[:effective_role_privs]
|
66
144
|
@roles.each do |role|
|
67
|
-
|
68
|
-
|
69
|
-
|
145
|
+
role = Authorization::DevelopmentSupport::AnalyzerEngine::Role.for_sym(role, engine)
|
146
|
+
@role_privs[role.to_sym] ||= []
|
147
|
+
role.ancestors.each do |lower_role|
|
148
|
+
@role_privs[role.to_sym].concat(@role_privs[lower_role.to_sym]).uniq!
|
70
149
|
end
|
71
150
|
end
|
72
151
|
end
|
73
152
|
|
153
|
+
@roles.delete_if do |role|
|
154
|
+
role = Authorization::DevelopmentSupport::AnalyzerEngine::Role.for_sym(role, engine)
|
155
|
+
([role] + role.ancestors).all? {|inner_role| @role_privs[inner_role.to_sym].blank? }
|
156
|
+
end
|
157
|
+
|
74
158
|
if options[:only_relevant_contexts]
|
75
|
-
@contexts.delete_if
|
159
|
+
@contexts.delete_if do |context|
|
160
|
+
@roles.all? {|role| !@role_privs[role] || !@role_privs[role].any? {|info| info[0] == context}}
|
161
|
+
end
|
76
162
|
end
|
77
163
|
|
78
164
|
if options[:privilege_hierarchy]
|
@@ -88,6 +174,20 @@ class AuthorizationRulesController < ApplicationController
|
|
88
174
|
|
89
175
|
render_to_string :template => 'authorization_rules/graph.dot.erb', :layout => false
|
90
176
|
end
|
177
|
+
|
178
|
+
def replay_changes (engine, users, changes)
|
179
|
+
changes.inject({}) do |memo, info|
|
180
|
+
case info[0]
|
181
|
+
when :add_privilege, :add_role
|
182
|
+
Authorization::DevelopmentSupport::AnalyzerEngine.apply_change(engine, info)
|
183
|
+
when :assign_role_to_user
|
184
|
+
user = users.find {|u| u.login == info[2]}
|
185
|
+
user.role_symbols << info[1] if user
|
186
|
+
end
|
187
|
+
(memo[info[0]] ||= Set.new) << info[1..-1]
|
188
|
+
memo
|
189
|
+
end
|
190
|
+
end
|
91
191
|
|
92
192
|
def dot_to_svg (dot_data)
|
93
193
|
gv = IO.popen("#{Authorization.dot_path} -q -Tsvg", "w+")
|
@@ -102,11 +202,32 @@ class AuthorizationRulesController < ApplicationController
|
|
102
202
|
{
|
103
203
|
:effective_role_privs => !params[:effective_role_privs].blank?,
|
104
204
|
:privilege_hierarchy => !params[:privilege_hierarchy].blank?,
|
105
|
-
:
|
205
|
+
:stacked_roles => !params[:stacked_roles].blank?,
|
206
|
+
:only_relevant_roles => !params[:only_relevant_roles].blank?,
|
207
|
+
:filter_roles => params[:filter_roles].blank? ? nil : (params[:filter_roles].is_a?(Array) ? params[:filter_roles].map(&:to_sym) : [params[:filter_roles].to_sym]),
|
106
208
|
:filter_contexts => params[:filter_contexts].blank? ? nil : params[:filter_contexts].to_sym,
|
107
|
-
:highlight_privilege => params[:highlight_privilege].blank? ? nil : params[:highlight_privilege].to_sym
|
209
|
+
:highlight_privilege => params[:highlight_privilege].blank? ? nil : params[:highlight_privilege].to_sym,
|
210
|
+
:changes => deserialize_changes(params[:changes]),
|
211
|
+
:users => params[:user_ids] && params[:user_ids].collect {|user_id| find_user_by_id(user_id)}
|
108
212
|
}
|
109
213
|
end
|
214
|
+
|
215
|
+
def deserialize_changes (changes)
|
216
|
+
if changes
|
217
|
+
changes.split(';').collect do |info|
|
218
|
+
info.split(',').collect do |info_part|
|
219
|
+
info_part[0,1] == ':' ? info_part[1..-1].to_sym : info_part
|
220
|
+
end
|
221
|
+
end
|
222
|
+
end
|
223
|
+
end
|
224
|
+
|
225
|
+
def find_user_by_id (id)
|
226
|
+
User.find(id)
|
227
|
+
end
|
228
|
+
def find_all_users
|
229
|
+
User.all.select {|user| !user.login.blank?}
|
230
|
+
end
|
110
231
|
end
|
111
232
|
|
112
233
|
else
|
@@ -3,8 +3,8 @@ module AuthorizationRulesHelper
|
|
3
3
|
regexps = {
|
4
4
|
:constant => [/(:)(\w+)/],
|
5
5
|
:proc => ['role', 'authorization', 'privileges'],
|
6
|
-
:statement => ['has_permission_on', 'if_attribute', 'includes', 'privilege', 'to'],
|
7
|
-
:operator => ['is', 'contains'],
|
6
|
+
:statement => ['has_permission_on', 'if_attribute', 'if_permitted_to', 'includes', 'privilege', 'to'],
|
7
|
+
:operator => ['is', 'contains', 'is_in', 'is_not', 'is_not_in', 'intersects'],
|
8
8
|
:special => ['user', 'true', 'false'],
|
9
9
|
:preproc => ['do', 'end', /()(=>)/, /()(\{)/, /()(\})/, /()(\[)/, /()(\])/],
|
10
10
|
:comment => [/()(#.*$)/]#,
|
@@ -23,16 +23,17 @@ module AuthorizationRulesHelper
|
|
23
23
|
end
|
24
24
|
|
25
25
|
def policy_analysis_hints (marked_up, policy_data)
|
26
|
-
analyzer = Authorization::Analyzer.new(controller.authorization_engine)
|
26
|
+
analyzer = Authorization::DevelopmentSupport::Analyzer.new(controller.authorization_engine)
|
27
27
|
analyzer.analyze(policy_data)
|
28
28
|
marked_up_by_line = marked_up.split("\n")
|
29
29
|
reports_by_line = analyzer.reports.inject({}) do |memo, report|
|
30
|
-
memo[report.line] ||= []
|
31
|
-
memo[report.line] << report
|
30
|
+
memo[report.line || 1] ||= []
|
31
|
+
memo[report.line || 1] << report
|
32
32
|
memo
|
33
33
|
end
|
34
34
|
reports_by_line.each do |line, reports|
|
35
|
-
|
35
|
+
text = reports.collect {|report| "#{report.type}: #{report.message}"} * " "
|
36
|
+
note = %Q{<span class="note" title="#{h text}">[i]</span>}
|
36
37
|
marked_up_by_line[line - 1] = note + marked_up_by_line[line - 1]
|
37
38
|
end
|
38
39
|
marked_up_by_line * "\n"
|
@@ -45,6 +46,7 @@ module AuthorizationRulesHelper
|
|
45
46
|
|
46
47
|
def navigation
|
47
48
|
link_to("Rules", authorization_rules_path) << ' | ' <<
|
49
|
+
link_to("Change Supporter", change_authorization_rules_path) << ' | ' <<
|
48
50
|
link_to("Graphical view", graph_authorization_rules_path) << ' | ' <<
|
49
51
|
link_to("Usages", authorization_usages_path) #<< ' | ' <<
|
50
52
|
# 'Edit | ' <<
|
@@ -52,20 +54,101 @@ module AuthorizationRulesHelper
|
|
52
54
|
end
|
53
55
|
|
54
56
|
def role_color (role, fill = false)
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
57
|
+
if @has_changes
|
58
|
+
if has_changed(:add_role, role)
|
59
|
+
fill ? '#ddffdd' : '#000000'
|
60
|
+
elsif has_changed(:remove_role, role)
|
61
|
+
fill ? '#ffdddd' : '#000000'
|
62
|
+
else
|
63
|
+
fill ? '#ddddff' : '#000000'
|
64
|
+
end
|
65
|
+
else
|
66
|
+
fill_colors = %w{#ffdddd #ddffdd #ddddff #ffffdd #ffddff #ddffff}
|
67
|
+
colors = %w{#dd0000 #00dd00 #0000dd #dddd00 #dd00dd #00dddd}
|
68
|
+
@@role_colors ||= {}
|
69
|
+
@@role_colors[role] ||= begin
|
70
|
+
idx = @@role_colors.length % colors.length
|
71
|
+
[colors[idx], fill_colors[idx]]
|
72
|
+
end
|
73
|
+
@@role_colors[role][fill ? 1 : 0]
|
61
74
|
end
|
62
|
-
@@role_colors[role][fill ? 1 : 0]
|
63
75
|
end
|
64
76
|
|
65
77
|
def role_fill_color (role)
|
66
78
|
role_color(role, true)
|
67
79
|
end
|
68
80
|
|
81
|
+
def privilege_color (privilege, context, role)
|
82
|
+
has_changed(:add_privilege, privilege, context, role) ? '#00dd00' :
|
83
|
+
(has_changed(:remove_privilege, privilege, context, role) ? '#dd0000' :
|
84
|
+
role_color(role))
|
85
|
+
end
|
86
|
+
|
87
|
+
def describe_step (step, options = {})
|
88
|
+
options = {:with_removal => false}.merge(options)
|
89
|
+
|
90
|
+
case step[0]
|
91
|
+
when :add_privilege
|
92
|
+
dont_assign = prohibit_link(step[0,3],
|
93
|
+
"Add privilege <strong>#{h step[1].to_sym.inspect} #{h step[2].to_sym.inspect}</strong> to any role",
|
94
|
+
"Don't suggest adding #{h step[1].to_sym.inspect} #{h step[2].to_sym.inspect}.", options)
|
95
|
+
"Add privilege <strong>#{h step[1].inspect} #{h step[2].inspect}</strong>#{dont_assign} to role <strong>#{h step[3].to_sym.inspect}</strong>"
|
96
|
+
when :remove_privilege
|
97
|
+
dont_remove = prohibit_link(step[0,3],
|
98
|
+
"Remove privilege <strong>#{h step[1].to_sym.inspect} #{h step[2].to_sym.inspect}</strong> from any role",
|
99
|
+
"Don't suggest removing #{h step[1].to_sym.inspect} #{h step[2].to_sym.inspect}.", options)
|
100
|
+
"Remove privilege <strong>#{h step[1].inspect} #{h step[2].inspect}</strong>#{dont_remove} from role <strong>#{h step[3].to_sym.inspect}</strong>"
|
101
|
+
when :add_role
|
102
|
+
"New role <strong>#{h step[1].to_sym.inspect}</strong>"
|
103
|
+
when :assign_role_to_user
|
104
|
+
dont_assign = prohibit_link(step[0,2],
|
105
|
+
"Assign role <strong>#{h step[1].to_sym.inspect}</strong> to any user",
|
106
|
+
"Don't suggest assigning #{h step[1].to_sym.inspect}.", options)
|
107
|
+
"Assign role <strong>#{h step[1].to_sym.inspect}</strong>#{dont_assign} to <strong>#{h readable_step_info(step[2])}</strong>"
|
108
|
+
when :remove_role_from_user
|
109
|
+
dont_remove = prohibit_link(step[0,2],
|
110
|
+
"Remove role <strong>#{h step[1].to_sym.inspect}</strong> from any user",
|
111
|
+
"Don't suggest removing #{h step[1].to_sym.inspect}.", options)
|
112
|
+
"Remove role <strong>#{h step[1].to_sym.inspect}</strong>#{dont_remove} from <strong>#{h readable_step_info(step[2])}</strong>"
|
113
|
+
else
|
114
|
+
step.collect {|info| readable_step_info(info) }.map {|str| h str } * ', '
|
115
|
+
end + prohibit_link(step, options[:with_removal] ? "#{escape_javascript(describe_step(step))}" : '',
|
116
|
+
"Don't suggest this action.", options)
|
117
|
+
end
|
118
|
+
|
119
|
+
def prohibit_link (step, text, title, options)
|
120
|
+
options[:with_removal] ?
|
121
|
+
' ' + link_to_function("[x]", "prohibit_action('#{serialize_action(step)}', '#{text}')",
|
122
|
+
:class => 'unimportant', :title => title) :
|
123
|
+
''
|
124
|
+
end
|
125
|
+
|
126
|
+
def readable_step_info (info)
|
127
|
+
case info
|
128
|
+
when Symbol then info.inspect
|
129
|
+
when User then info.login
|
130
|
+
else info.to_sym.inspect
|
131
|
+
end
|
132
|
+
end
|
133
|
+
|
134
|
+
def serialize_changes (approach)
|
135
|
+
changes = approach.changes.collect {|step| step.to_a.first.is_a?(Enumerable) ? step.to_a : [step.to_a]}
|
136
|
+
changes.collect {|multi_step| multi_step.collect {|step| serialize_action(step) }}.flatten * ';'
|
137
|
+
end
|
138
|
+
|
139
|
+
def serialize_action (step)
|
140
|
+
step.collect {|info| readable_step_info(info) } * ','
|
141
|
+
end
|
142
|
+
|
143
|
+
def serialize_relevant_roles (approach)
|
144
|
+
{:filter_roles => (Authorization::DevelopmentSupport::AnalyzerEngine.relevant_roles(approach.engine, approach.users).
|
145
|
+
map(&:to_sym) + [:new_role_for_change_analyzer]).uniq}.to_param
|
146
|
+
end
|
147
|
+
|
148
|
+
def has_changed (*args)
|
149
|
+
@changes && @changes[args[0]] && @changes[args[0]].include?(args[1..-1])
|
150
|
+
end
|
151
|
+
|
69
152
|
def auth_usage_info_classes (auth_info)
|
70
153
|
classes = []
|
71
154
|
if auth_info[:controller_permissions]
|
@@ -0,0 +1,49 @@
|
|
1
|
+
<form>
|
2
|
+
<h2>1. Choose permission to change</h2>
|
3
|
+
<p class="action-options">
|
4
|
+
<label>Privilege</label>
|
5
|
+
<%= select_tag :privilege, options_for_select(@privileges.map(&:to_s).sort, @privilege.to_s) %>
|
6
|
+
<br/>
|
7
|
+
<label>On</label>
|
8
|
+
<%= select_tag :context, options_for_select(@contexts.map(&:to_s).sort, @context.to_s) %>
|
9
|
+
<br/>
|
10
|
+
<%= link_to_function "Current permissions", "show_current_permissions()", :class => 'unimportant' %>
|
11
|
+
</p>
|
12
|
+
|
13
|
+
<h2>2. Whose permission should be changed?</h2>
|
14
|
+
<table class="change-options">
|
15
|
+
<thead>
|
16
|
+
<tr>
|
17
|
+
<td>User</td>
|
18
|
+
<td>Current roles</td>
|
19
|
+
<td class="choose">?</td>
|
20
|
+
<td class="choose">Yes</td>
|
21
|
+
<td class="choose">No</td>
|
22
|
+
</tr>
|
23
|
+
</thead>
|
24
|
+
<tbody>
|
25
|
+
<% @users.each do |user| %>
|
26
|
+
<tr class="<%= controller.authorization_engine.permit?(@privilege, :context => @context, :user => user, :skip_attribute_test => true) ? 'permitted' : 'not-permitted' %>">
|
27
|
+
<td class="user_id"><%=h user.id %></td>
|
28
|
+
<td style="font-weight:bold"><%=h user.login %></td>
|
29
|
+
<td><%=h user.role_symbols * ', ' %></td>
|
30
|
+
<td><%= radio_button_tag "user[#{user.id}][permission]", "undetermined", true %></td>
|
31
|
+
<td class="yes"><%= radio_button_tag "user[#{user.id}][permission]", "yes" %></td>
|
32
|
+
<td class="no"><%= radio_button_tag "user[#{user.id}][permission]", "no" %></td>
|
33
|
+
</tr>
|
34
|
+
<% end %>
|
35
|
+
<tr>
|
36
|
+
<td colspan="5" style="text-align:right; padding-top:0.5em" class="unimportant">
|
37
|
+
<span style="background: #FFE599;"> </span> Current permission
|
38
|
+
</td>
|
39
|
+
</tr>
|
40
|
+
</tbody>
|
41
|
+
</table>
|
42
|
+
|
43
|
+
<h2 style="display:none">Prohibited actions</h2>
|
44
|
+
<ul id="prohibited_actions"></ul>
|
45
|
+
|
46
|
+
<p class="submit">
|
47
|
+
<%= button_to_function "Suggest Changes", "suggest_changes()" %>
|
48
|
+
</p>
|
49
|
+
</form>
|