ghart-declarative_authorization 0.3.2.4

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 (42) hide show
  1. data/CHANGELOG +83 -0
  2. data/MIT-LICENSE +20 -0
  3. data/README.rdoc +510 -0
  4. data/Rakefile +43 -0
  5. data/app/controllers/authorization_rules_controller.rb +259 -0
  6. data/app/controllers/authorization_usages_controller.rb +23 -0
  7. data/app/helpers/authorization_rules_helper.rb +187 -0
  8. data/app/views/authorization_rules/_change.erb +58 -0
  9. data/app/views/authorization_rules/_show_graph.erb +37 -0
  10. data/app/views/authorization_rules/_suggestions.erb +48 -0
  11. data/app/views/authorization_rules/change.html.erb +152 -0
  12. data/app/views/authorization_rules/graph.dot.erb +68 -0
  13. data/app/views/authorization_rules/graph.html.erb +40 -0
  14. data/app/views/authorization_rules/index.html.erb +17 -0
  15. data/app/views/authorization_usages/index.html.erb +36 -0
  16. data/authorization_rules.dist.rb +20 -0
  17. data/config/routes.rb +7 -0
  18. data/garlic_example.rb +20 -0
  19. data/init.rb +5 -0
  20. data/lib/declarative_authorization.rb +15 -0
  21. data/lib/declarative_authorization/authorization.rb +634 -0
  22. data/lib/declarative_authorization/development_support/analyzer.rb +252 -0
  23. data/lib/declarative_authorization/development_support/change_analyzer.rb +253 -0
  24. data/lib/declarative_authorization/development_support/change_supporter.rb +620 -0
  25. data/lib/declarative_authorization/development_support/development_support.rb +243 -0
  26. data/lib/declarative_authorization/helper.rb +60 -0
  27. data/lib/declarative_authorization/in_controller.rb +597 -0
  28. data/lib/declarative_authorization/in_model.rb +159 -0
  29. data/lib/declarative_authorization/maintenance.rb +182 -0
  30. data/lib/declarative_authorization/obligation_scope.rb +308 -0
  31. data/lib/declarative_authorization/rails_legacy.rb +14 -0
  32. data/lib/declarative_authorization/reader.rb +441 -0
  33. data/test/authorization_test.rb +827 -0
  34. data/test/controller_filter_resource_access_test.rb +394 -0
  35. data/test/controller_test.rb +386 -0
  36. data/test/dsl_reader_test.rb +157 -0
  37. data/test/helper_test.rb +171 -0
  38. data/test/maintenance_test.rb +46 -0
  39. data/test/model_test.rb +1308 -0
  40. data/test/schema.sql +54 -0
  41. data/test/test_helper.rb +118 -0
  42. metadata +106 -0
@@ -0,0 +1,43 @@
1
+ require 'rake'
2
+ require 'rake/testtask'
3
+ require 'rake/rdoctask'
4
+
5
+ desc 'Default: run unit tests.'
6
+ task :default => :test
7
+
8
+ desc 'Test the authorization plugin.'
9
+ Rake::TestTask.new(:test) do |t|
10
+ t.libs << 'lib'
11
+ t.pattern = 'test/**/*_test.rb'
12
+ t.verbose = true
13
+ end
14
+
15
+ desc 'Generate documentation for the authorization plugin.'
16
+ Rake::RDocTask.new(:rdoc) do |rdoc|
17
+ rdoc.rdoc_dir = 'rdoc'
18
+ rdoc.title = 'Authorization'
19
+ rdoc.options << '--line-numbers' << '--inline-source'
20
+ rdoc.options << '--charset' << 'utf-8'
21
+ rdoc.rdoc_files.include('README.rdoc')
22
+ rdoc.rdoc_files.include('CHANGELOG')
23
+ rdoc.rdoc_files.include('lib/**/*.rb')
24
+ end
25
+
26
+ # load up garlic if it's here
27
+ if File.directory?(File.join(File.dirname(__FILE__), 'garlic'))
28
+ require File.join(File.dirname(__FILE__), 'garlic/lib/garlic_tasks')
29
+ require File.join(File.dirname(__FILE__), 'garlic')
30
+ end
31
+
32
+ desc "clone the garlic repo (for running ci tasks)"
33
+ task :get_garlic do
34
+ sh "git clone git://github.com/ianwhite/garlic.git garlic"
35
+ end
36
+
37
+ desc "Expand filelist in src gemspec"
38
+ task :build_gemspec do
39
+ gemspec_data = File.read("declarative_authorization.gemspec.src")
40
+ gemspec_data.gsub!(/\.files = (.*)/) {|m| ".files = #{eval($1).inspect}"}
41
+ File.open("declarative_authorization.gemspec", "w") {|f| f.write(gemspec_data)}
42
+ end
43
+
@@ -0,0 +1,259 @@
1
+ if Authorization::activate_authorization_rules_browser?
2
+
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})
6
+
7
+ begin
8
+ # for nice auth_rules output:
9
+ require "parse_tree"
10
+ require "parse_tree_extensions"
11
+ require "ruby2ruby"
12
+ rescue LoadError; end
13
+
14
+ class AuthorizationRulesController < ApplicationController
15
+ unloadable
16
+
17
+ filter_access_to :all, :require => :read
18
+ def index
19
+ respond_to do |format|
20
+ format.html do
21
+ @auth_rules_script = File.read("#{RAILS_ROOT}/config/authorization_rules.rb")
22
+ end
23
+ end
24
+ end
25
+
26
+ def graph
27
+ if params[:format] == "svg"
28
+ render :text => dot_to_svg(auth_to_dot(graph_options)),
29
+ :content_type => "image/svg+xml"
30
+ end
31
+ end
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 do |priv|
39
+ priv = Authorization::DevelopmentSupport::AnalyzerEngine::Privilege.for_sym(priv, authorization_engine)
40
+ (priv.descendants + priv.ancestors).map(&:to_sym)
41
+ end.flatten.uniq
42
+ @privileges.sort_by {|priv| priv.to_s}
43
+ @privilege = params[:privilege].to_sym rescue @privileges.first
44
+ @contexts = authorization_engine.auth_rules.collect {|rule| rule.contexts.to_a}.flatten.uniq
45
+ @context = params[:context].to_sym rescue @contexts.first
46
+
47
+ respond_to do |format|
48
+ format.html
49
+ format.js do
50
+ render :partial => 'change'
51
+ end
52
+ end
53
+ end
54
+
55
+ def suggest_change
56
+ users_permission = params[:user].inject({}) do |memo, (user_id, data)|
57
+ if data[:permission] != "undetermined"
58
+ begin
59
+ memo[find_user_by_id(user_id)] = (data[:permission] == 'yes')
60
+ rescue ActiveRecord::NotFound
61
+ end
62
+ end
63
+ memo
64
+ end
65
+
66
+ prohibited_actions = (params[:prohibited_action] || []).collect do |spec|
67
+ deserialize_changes(spec).flatten
68
+ end
69
+
70
+ analyzer = Authorization::DevelopmentSupport::ChangeSupporter.new(authorization_engine)
71
+
72
+ privilege = params[:privilege].to_sym
73
+ context = params[:context].to_sym
74
+ all_users = User.all
75
+ @context = context
76
+ @approaches = analyzer.find_approaches_for(:users => all_users, :prohibited_actions => prohibited_actions) do
77
+ users.each_with_index do |user, idx|
78
+ unless users_permission[all_users[idx]].nil?
79
+ args = [privilege, {:context => context, :user => user}]
80
+ assert(users_permission[all_users[idx]] ? permit?(*args) : !permit?(*args))
81
+ end
82
+ end
83
+ end
84
+
85
+ @affected_users = @approaches.each_with_object({}) do |approach, memo|
86
+ memo[approach] = approach.affected_users(authorization_engine, all_users, privilege, context).length
87
+ end
88
+ max_affected_users = @affected_users.values.max
89
+ if params[:affected_users]
90
+ @approaches = @approaches.sort_by do |approach|
91
+ affected_users_count = @affected_users[approach]
92
+ if params[:affected_users] == "many"
93
+ #approach.weight.to_f / [affected_users_count, 0.1].min
94
+ approach.weight + (max_affected_users - affected_users_count) * 10
95
+ else
96
+ #approach.weight * affected_users_count
97
+ approach.weight + affected_users_count * 10
98
+ end
99
+ end
100
+ end
101
+
102
+ @grouped_approaches = analyzer.group_approaches(@approaches)
103
+
104
+ respond_to do |format|
105
+ format.js do
106
+ render :partial => 'suggestions'
107
+ end
108
+ end
109
+ end
110
+
111
+ private
112
+ def auth_to_dot (options = {})
113
+ options = {
114
+ :effective_role_privs => true,
115
+ :privilege_hierarchy => false,
116
+ :stacked_roles => false,
117
+ :only_relevant_contexts => true,
118
+ :only_relevant_roles => false,
119
+ :filter_roles => nil,
120
+ :filter_contexts => nil,
121
+ :highlight_privilege => nil,
122
+ :changes => nil,
123
+ :users => nil
124
+ }.merge(options)
125
+
126
+ @has_changes = options[:changes] && !options[:changes].empty?
127
+ @highlight_privilege = options[:highlight_privilege]
128
+ @stacked_roles = options[:stacked_roles]
129
+
130
+ @users = options[:users]
131
+
132
+ engine = authorization_engine.clone
133
+ @changes = replay_changes(engine, @users, options[:changes]) if options[:changes]
134
+
135
+ options[:filter_roles] ||= @users.collect {|user| user.role_symbols}.flatten.uniq if options[:only_relevant_roles] and @users
136
+
137
+ filter_roles_flattened = nil
138
+ if options[:filter_roles]
139
+ filter_roles_flattened = options[:filter_roles].collect do |role_sym|
140
+ Authorization::DevelopmentSupport::AnalyzerEngine::Role.for_sym(role_sym, engine).
141
+ ancestors.map(&:to_sym) + [role_sym]
142
+ end.flatten.uniq
143
+ end
144
+
145
+ @roles = engine.roles
146
+ @roles = @roles.select {|r| filter_roles_flattened.include?(r) } if options[:filter_roles]
147
+ @role_hierarchy = engine.role_hierarchy
148
+ @privilege_hierarchy = engine.privilege_hierarchy
149
+
150
+ @contexts = engine.auth_rules.
151
+ collect {|ar| ar.contexts.to_a}.flatten.uniq
152
+ @contexts = @contexts.select {|c| c == options[:filter_contexts] } if options[:filter_contexts]
153
+ @context_privs = {}
154
+ @role_privs = {}
155
+ engine.auth_rules.each do |auth_rule|
156
+ @role_privs[auth_rule.role] ||= []
157
+ auth_rule.contexts.
158
+ select {|c| options[:filter_contexts].nil? or c == options[:filter_contexts]}.
159
+ each do |context|
160
+ @context_privs[context] ||= []
161
+ @context_privs[context] += auth_rule.privileges.to_a
162
+ @context_privs[context].uniq!
163
+ @role_privs[auth_rule.role] += auth_rule.privileges.collect {|p| [context, p, auth_rule.attributes.empty?, auth_rule.to_long_s]}
164
+ end
165
+ end
166
+
167
+ if options[:effective_role_privs]
168
+ @roles.each do |role|
169
+ role = Authorization::DevelopmentSupport::AnalyzerEngine::Role.for_sym(role, engine)
170
+ @role_privs[role.to_sym] ||= []
171
+ role.ancestors.each do |lower_role|
172
+ @role_privs[role.to_sym].concat(@role_privs[lower_role.to_sym]).uniq!
173
+ end
174
+ end
175
+ end
176
+
177
+ @roles.delete_if do |role|
178
+ role = Authorization::DevelopmentSupport::AnalyzerEngine::Role.for_sym(role, engine)
179
+ ([role] + role.ancestors).all? {|inner_role| @role_privs[inner_role.to_sym].blank? }
180
+ end
181
+
182
+ if options[:only_relevant_contexts]
183
+ @contexts.delete_if do |context|
184
+ @roles.all? {|role| !@role_privs[role] || !@role_privs[role].any? {|info| info[0] == context}}
185
+ end
186
+ end
187
+
188
+ if options[:privilege_hierarchy]
189
+ @context_privs.each do |context, privs|
190
+ privs.each do |priv|
191
+ context_lower_privs = (@privilege_hierarchy[priv] || []).
192
+ select {|p,c| c.nil? or c == context}.
193
+ collect {|p,c| p}
194
+ privs.concat(context_lower_privs).uniq!
195
+ end
196
+ end
197
+ end
198
+
199
+ render_to_string :template => 'authorization_rules/graph.dot.erb', :layout => false
200
+ end
201
+
202
+ def replay_changes (engine, users, changes)
203
+ changes.inject({}) do |memo, info|
204
+ case info[0]
205
+ when :add_privilege, :add_role
206
+ Authorization::DevelopmentSupport::AnalyzerEngine.apply_change(engine, info)
207
+ when :assign_role_to_user
208
+ user = users.find {|u| u.login == info[2]}
209
+ user.role_symbols << info[1] if user
210
+ end
211
+ (memo[info[0]] ||= Set.new) << info[1..-1]
212
+ memo
213
+ end
214
+ end
215
+
216
+ def dot_to_svg (dot_data)
217
+ gv = IO.popen("#{Authorization.dot_path} -q -Tsvg", "w+")
218
+ gv.puts dot_data
219
+ gv.close_write
220
+ gv.read
221
+ rescue IOError, Errno::EPIPE => e
222
+ raise Exception, "Error in call to graphviz: #{e}"
223
+ end
224
+
225
+ def graph_options
226
+ {
227
+ :effective_role_privs => !params[:effective_role_privs].blank?,
228
+ :privilege_hierarchy => !params[:privilege_hierarchy].blank?,
229
+ :stacked_roles => !params[:stacked_roles].blank?,
230
+ :only_relevant_roles => !params[:only_relevant_roles].blank?,
231
+ :filter_roles => params[:filter_roles].blank? ? nil : (params[:filter_roles].is_a?(Array) ? params[:filter_roles].map(&:to_sym) : [params[:filter_roles].to_sym]),
232
+ :filter_contexts => params[:filter_contexts].blank? ? nil : params[:filter_contexts].to_sym,
233
+ :highlight_privilege => params[:highlight_privilege].blank? ? nil : params[:highlight_privilege].to_sym,
234
+ :changes => deserialize_changes(params[:changes]),
235
+ :users => params[:user_ids] && params[:user_ids].collect {|user_id| find_user_by_id(user_id)}
236
+ }
237
+ end
238
+
239
+ def deserialize_changes (changes)
240
+ if changes
241
+ changes.split(';').collect do |info|
242
+ info.split(',').collect do |info_part|
243
+ info_part[0,1] == ':' ? info_part[1..-1].to_sym : info_part
244
+ end
245
+ end
246
+ end
247
+ end
248
+
249
+ def find_user_by_id (id)
250
+ User.find(id)
251
+ end
252
+ def find_all_users
253
+ User.all.select {|user| !user.login.blank?}
254
+ end
255
+ end
256
+
257
+ else
258
+ class AuthorizationRulesController < ApplicationController; end
259
+ end # activate_authorization_rules_browser?
@@ -0,0 +1,23 @@
1
+ if Authorization::activate_authorization_rules_browser?
2
+
3
+ require File.join(File.dirname(__FILE__), %w{.. .. lib declarative_authorization maintenance})
4
+
5
+ class AuthorizationUsagesController < ApplicationController
6
+ unloadable
7
+
8
+ helper :authorization_rules
9
+ filter_access_to :all, :require => :read
10
+ # TODO set context?
11
+
12
+ def index
13
+ respond_to do |format|
14
+ format.html do
15
+ @auth_usages_by_controller = Authorization::Maintenance::Usage.usages_by_controller
16
+ end
17
+ end
18
+ end
19
+ end
20
+
21
+ else
22
+ class AuthorizationUsagesController < ApplicationController; end
23
+ end # activate_authorization_rules_browser?
@@ -0,0 +1,187 @@
1
+ module AuthorizationRulesHelper
2
+ def syntax_highlight (rules)
3
+ regexps = {
4
+ :constant => [/(:)(\w+)/],
5
+ :proc => ['role', 'authorization', 'privileges'],
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
+ :special => ['user', 'true', 'false'],
9
+ :preproc => ['do', 'end', /()(=&gt;)/, /()(\{)/, /()(\})/, /()(\[)/, /()(\])/],
10
+ :comment => [/()(#.*$)/]#,
11
+ #:privilege => [:read],
12
+ #:context => [:conferences]
13
+ }
14
+ regexps.each do |name, res|
15
+ res.each do |re|
16
+ rules.gsub!(
17
+ re.is_a?(String) ? Regexp.new("(^|[^:])\\b(#{Regexp.escape(re)})\\b") :
18
+ (re.is_a?(Symbol) ? Regexp.new("()(:#{Regexp.escape(re.to_s)})\\b") : re),
19
+ "\\1<span class=\"#{name}\">\\2</span>")
20
+ end
21
+ end
22
+ rules
23
+ end
24
+
25
+ def policy_analysis_hints (marked_up, policy_data)
26
+ analyzer = Authorization::DevelopmentSupport::Analyzer.new(controller.authorization_engine)
27
+ analyzer.analyze(policy_data)
28
+ marked_up_by_line = marked_up.split("\n")
29
+ reports_by_line = analyzer.reports.inject({}) do |memo, report|
30
+ memo[report.line || 1] ||= []
31
+ memo[report.line || 1] << report
32
+ memo
33
+ end
34
+ reports_by_line.each do |line, reports|
35
+ text = reports.collect {|report| "#{report.type}: #{report.message}"} * " "
36
+ note = %Q{<span class="note" title="#{h text}">[i]</span>}
37
+ marked_up_by_line[line - 1] = note + marked_up_by_line[line - 1]
38
+ end
39
+ marked_up_by_line * "\n"
40
+ end
41
+
42
+ def link_to_graph (title, options = {})
43
+ type = options[:type] || ''
44
+ link_to_function title, "$$('object')[0].data = '#{url_for :action => 'index', :format => 'svg', :type => type}'"
45
+ end
46
+
47
+ def navigation
48
+ link_to("Rules", authorization_rules_path) << ' | ' <<
49
+ link_to("Change Support", change_authorization_rules_path) << ' | ' <<
50
+ link_to("Graphical view", graph_authorization_rules_path) << ' | ' <<
51
+ link_to("Usages", authorization_usages_path) #<< ' | ' <<
52
+ # 'Edit | ' <<
53
+ # link_to("XACML export", :action => 'index', :format => 'xacml')
54
+ end
55
+
56
+ def role_color (role, fill = false)
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]
74
+ end
75
+ end
76
+
77
+ def role_fill_color (role)
78
+ role_color(role, true)
79
+ end
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 => 'prohibit', :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
+
152
+ def affected_users_count (approach)
153
+ @affected_users[approach]
154
+ end
155
+
156
+ def auth_usage_info_classes (auth_info)
157
+ classes = []
158
+ if auth_info[:controller_permissions]
159
+ if auth_info[:controller_permissions][0]
160
+ classes << "catch-all" if auth_info[:controller_permissions][0].actions.include?(:all)
161
+ classes << "default-privilege" unless auth_info[:controller_permissions][0].privilege
162
+ classes << "default-context" unless auth_info[:controller_permissions][0].context
163
+ classes << "no-attribute-check" unless auth_info[:controller_permissions][0].attribute_check
164
+ end
165
+ else
166
+ classes << "unprotected"
167
+ end
168
+ classes * " "
169
+ end
170
+
171
+ def auth_usage_info_title (auth_info)
172
+ titles = []
173
+ if auth_usage_info_classes(auth_info) =~ /unprotected/
174
+ titles << "No filter_access_to call protects this action"
175
+ end
176
+ if auth_usage_info_classes(auth_info) =~ /no-attribute-check/
177
+ titles << "Action is not protected with attribute check"
178
+ end
179
+ if auth_usage_info_classes(auth_info) =~ /default-privilege/
180
+ titles << "Privilege set automatically from action name by :all rule"
181
+ end
182
+ if auth_usage_info_classes(auth_info) =~ /default-context/
183
+ titles << "Context set automatically from controller name by filter_access_to call without :context option"
184
+ end
185
+ titles * ". "
186
+ end
187
+ end