rubycs-declarative_authorization 0.3.0

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 (37) hide show
  1. data/CHANGELOG +70 -0
  2. data/MIT-LICENSE +20 -0
  3. data/README.rdoc +9 -0
  4. data/Rakefile +43 -0
  5. data/app/controllers/authorization_rules_controller.rb +114 -0
  6. data/app/controllers/authorization_usages_controller.rb +23 -0
  7. data/app/helpers/authorization_rules_helper.rb +100 -0
  8. data/app/views/authorization_rules/graph.dot.erb +49 -0
  9. data/app/views/authorization_rules/graph.html.erb +39 -0
  10. data/app/views/authorization_rules/index.html.erb +16 -0
  11. data/app/views/authorization_usages/index.html.erb +45 -0
  12. data/authorization_rules.dist.rb +20 -0
  13. data/config/locales/en.declarative_authorization.yml +35 -0
  14. data/config/locales/ro.declarative_authorization.yml +35 -0
  15. data/config/routes.rb +6 -0
  16. data/garlic_example.rb +20 -0
  17. data/init.rb +5 -0
  18. data/lib/declarative_authorization.rb +15 -0
  19. data/lib/declarative_authorization/authorization.rb +578 -0
  20. data/lib/declarative_authorization/authorization_rules_analyzer.rb +138 -0
  21. data/lib/declarative_authorization/helper.rb +56 -0
  22. data/lib/declarative_authorization/in_controller.rb +343 -0
  23. data/lib/declarative_authorization/in_model.rb +125 -0
  24. data/lib/declarative_authorization/maintenance.rb +174 -0
  25. data/lib/declarative_authorization/obligation_scope.rb +292 -0
  26. data/lib/declarative_authorization/rails_legacy.rb +14 -0
  27. data/lib/declarative_authorization/reader.rb +430 -0
  28. data/test/authorization_rules_analyzer_test.rb +123 -0
  29. data/test/authorization_test.rb +779 -0
  30. data/test/controller_test.rb +361 -0
  31. data/test/dsl_reader_test.rb +157 -0
  32. data/test/helper_test.rb +133 -0
  33. data/test/maintenance_test.rb +15 -0
  34. data/test/model_test.rb +1143 -0
  35. data/test/schema.sql +53 -0
  36. data/test/test_helper.rb +99 -0
  37. metadata +97 -0
data/CHANGELOG ADDED
@@ -0,0 +1,70 @@
1
+
2
+ ** RELEASE 0.3 (April 20, 2009) **
3
+
4
+ * New option :join_by for has_permission_on to allow AND'ing of statements in one has_permission_on block [sb]
5
+
6
+ * Allow using_access_control to be called directly on ActiveRecord::Base, globally enabling model security [sb]
7
+
8
+ * New operator: intersects_with, comparing two Enumerables in if_attribute [sb]
9
+
10
+ * Improved if_permitted_to syntax: if the attribute is left out, permissions are checked on for the current object [sb]
11
+
12
+ * Added #has_role_with_hierarchy? method to retrieve explicit and calculated roles [jeremyf]
13
+
14
+ * Added a simple rules analyzer to help improve authorization rules [sb]
15
+
16
+ * Gemified plugin. Needed to restructure the lib path contents [sb]
17
+
18
+ * Added handling of Authorization::AuthorizationInController::ClassMethods.filter_access_to parameters that are of the form [:show, :update] instead of just :show, :update. [jeremyf]
19
+
20
+ * Added authorization usage helper for checking filter_access_to usage in controllers [sb]
21
+
22
+ * Added a authorization rules browser. See README for more information [sb]
23
+
24
+ * Added Model.using_access_control? to check if a model has model security activated [sb]
25
+
26
+ * Changed Authorization::ObligationScope#map_table_alias_for [Brian Langenfeld]
27
+ * Fixed to prevent bad aliases from being produced.
28
+
29
+ * Changed Authorization::Attribute#validate? [Brian Langenfeld]
30
+ * Encountering a nil value when evaluating an attribute now raises a NilAttributeValueError, instead of an AuthorizationError. We leave it to the caller to decide what to do about it.
31
+
32
+ * Changed Authorization::Engine#permit! [Brian Langenfeld]
33
+ * We now convert incoming privileges to symbols (e.g. 'read' is made equivalent to :read). This ensures the privileges will match those defined in the authorization rules file.
34
+ * The method now properly infers context when checking against an association (e.g. user.posts). We do this by leveraging ActiveRecord builder method 'new' to instantiate a proper object we can work with.
35
+ * When testing rules for positive results (via Authorization::Attribute#validate?), we now rescue NilAttributeValueError exceptions, simply causing the rule to return a negative result (instead of barfing).
36
+
37
+ * Changed Authorization::ObligationScope#rebuild_join_options! [Brian Langenfeld]
38
+ * If we're dealing with multiple obligations we have to check (i.e. ones that result in OR'd conditions), we now use :include instead of :joins for our generated scope. This does seem like a kludge, but until ActiveRecord scopes support unions (for checking obligations individually and consolidating the results), we don't have much choice. Something to revisit later, for sure.
39
+
40
+ ** RELEASE 0.2 (February 2, 2009) **
41
+
42
+ * added negative operators: is_not, not_in, does_not_contain [sb]
43
+
44
+ * changed user.roles to user.role_symbols to reduce interferance with associations [sb]
45
+
46
+ * Ruby 1.9 and Rails 2.3 compatibility [sb]
47
+
48
+ * if_permitted_to for has_permission_on blocks for DRYer auth rules [sb]
49
+
50
+ * ObligationScope rewrite of query rewriting [Brian Langenfeld]
51
+
52
+ * changed exception hierarchy to begin at StandardError [sb]
53
+
54
+ * :is_in operator [sb]
55
+
56
+ * added has_role? helper [sb]
57
+
58
+ * made plugin thread-safe [sb]
59
+
60
+ * added maintenance and test helpers [sb]
61
+
62
+ * changed default permission denied response to 403 Forbidden [sb]
63
+
64
+ * descriptions for titles and roles [sb]
65
+
66
+ * fixed for PostgreSQL [Mark Mansour]
67
+
68
+ * improved DSL syntax: allow for array of contexts in has_permission_on [sb]
69
+
70
+ ** RELEASE 0.1 (August 22, 2008) **
data/MIT-LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2008 [name of plugin creator]
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.rdoc ADDED
@@ -0,0 +1,9 @@
1
+ = Declarative Authorization with I18n support
2
+
3
+ This is a fork of Steffen Bartsch's declarative_authorization[http://github.com/stffn/declarative_authorization/tree] equipped with localization
4
+ based on Rails default I18n.
5
+
6
+
7
+ = Usage
8
+
9
+
data/Rakefile ADDED
@@ -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,114 @@
1
+ if Authorization::activate_authorization_rules_browser?
2
+
3
+ require File.join(File.dirname(__FILE__), %w{.. .. lib declarative_authorization authorization_rules_analyzer})
4
+
5
+ begin
6
+ # for nice auth_rules output:
7
+ require "parse_tree"
8
+ require "parse_tree_extensions"
9
+ require "ruby2ruby"
10
+ rescue LoadError; end
11
+
12
+ class AuthorizationRulesController < ApplicationController
13
+ unloadable
14
+
15
+ filter_access_to :all, :require => :read
16
+ def index
17
+ respond_to do |format|
18
+ format.html do
19
+ @auth_rules_script = File.read("#{RAILS_ROOT}/config/authorization_rules.rb")
20
+ end
21
+ end
22
+ end
23
+
24
+ def graph
25
+ if params[:format] == "svg"
26
+ render :text => dot_to_svg(auth_to_dot(graph_options)),
27
+ :content_type => "image/svg+xml"
28
+ end
29
+ end
30
+
31
+ private
32
+ def auth_to_dot (options = {})
33
+ options = {
34
+ :effective_role_privs => true,
35
+ :privilege_hierarchy => false,
36
+ :only_relevant_contexts => true,
37
+ :filter_roles => nil,
38
+ :filter_contexts => nil,
39
+ :highlight_privilege => nil
40
+ }.merge(options)
41
+
42
+ @highlight_privilege = options[:highlight_privilege]
43
+ @roles = authorization_engine.roles
44
+ @roles = @roles.select {|r| r == options[:filter_roles] } if options[:filter_roles]
45
+ @role_hierarchy = authorization_engine.role_hierarchy
46
+ @privilege_hierarchy = authorization_engine.privilege_hierarchy
47
+
48
+ @contexts = authorization_engine.auth_rules.
49
+ collect {|ar| ar.contexts.to_a}.flatten.uniq
50
+ @contexts = @contexts.select {|c| c == options[:filter_contexts] } if options[:filter_contexts]
51
+ @context_privs = {}
52
+ @role_privs = {}
53
+ authorization_engine.auth_rules.each do |auth_rule|
54
+ @role_privs[auth_rule.role] ||= []
55
+ auth_rule.contexts.
56
+ select {|c| options[:filter_contexts].nil? or c == options[:filter_contexts]}.
57
+ each do |context|
58
+ @context_privs[context] ||= []
59
+ @context_privs[context] += auth_rule.privileges.to_a
60
+ @context_privs[context].uniq!
61
+ @role_privs[auth_rule.role] += auth_rule.privileges.collect {|p| [context, p, auth_rule.attributes.empty?, auth_rule.to_long_s]}
62
+ end
63
+ end
64
+
65
+ if options[:effective_role_privs]
66
+ @roles.each do |role|
67
+ @role_privs[role] ||= []
68
+ (@role_hierarchy[role] || []).each do |lower_role|
69
+ @role_privs[role].concat(@role_privs[lower_role]).uniq!
70
+ end
71
+ end
72
+ end
73
+
74
+ if options[:only_relevant_contexts]
75
+ @contexts.delete_if {|context| @roles.all? {|role| !@role_privs[role] || !@role_privs[role].any? {|info| info[0] == context}}}
76
+ end
77
+
78
+ if options[:privilege_hierarchy]
79
+ @context_privs.each do |context, privs|
80
+ privs.each do |priv|
81
+ context_lower_privs = (@privilege_hierarchy[priv] || []).
82
+ select {|p,c| c.nil? or c == context}.
83
+ collect {|p,c| p}
84
+ privs.concat(context_lower_privs).uniq!
85
+ end
86
+ end
87
+ end
88
+
89
+ render_to_string :template => 'authorization_rules/graph.dot.erb', :layout => false
90
+ end
91
+
92
+ def dot_to_svg (dot_data)
93
+ gv = IO.popen("#{Authorization.dot_path} -q -Tsvg", "w+")
94
+ gv.puts dot_data
95
+ gv.close_write
96
+ gv.read
97
+ rescue IOError, Errno::EPIPE => e
98
+ raise Exception, "#{I18n.t(:error_in_call_to_graphviz, :scope => [:declarative_authorization])}: #{e}"
99
+ end
100
+
101
+ def graph_options
102
+ {
103
+ :effective_role_privs => !params[:effective_role_privs].blank?,
104
+ :privilege_hierarchy => !params[:privilege_hierarchy].blank?,
105
+ :filter_roles => params[:filter_roles].blank? ? nil : params[:filter_roles].to_sym,
106
+ :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
108
+ }
109
+ end
110
+ end
111
+
112
+ else
113
+ class AuthorizationRulesController < ApplicationController; end
114
+ 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,100 @@
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', 'includes', 'privilege', 'to'],
7
+ :operator => ['is', 'contains'],
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::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] ||= []
31
+ memo[report.line] << report
32
+ memo
33
+ end
34
+ reports_by_line.each do |line, reports|
35
+ note = %Q{<span class="note" title="#{reports.first.type}: #{reports.first.message}">[i]</span>}
36
+ marked_up_by_line[line - 1] = note + marked_up_by_line[line - 1]
37
+ end
38
+ marked_up_by_line * "\n"
39
+ end
40
+
41
+ def link_to_graph (title, options = {})
42
+ type = options[:type] || ''
43
+ link_to_function title, "$$('object')[0].data = '#{url_for :action => 'index', :format => 'svg', :type => type}'"
44
+ end
45
+
46
+ def navigation
47
+ link_to(I18n.t(:rules, :scope => [:declarative_authorization]), authorization_rules_path) << ' | ' <<
48
+ link_to(I18n.t(:graphical_view, :scope => [:declarative_authorization]), graph_authorization_rules_path) << ' | ' <<
49
+ link_to(I18n.t(:usages, :scope => [:declarative_authorization]), authorization_usages_path) #<< ' | ' <<
50
+ # 'Edit | ' <<
51
+ # link_to("XACML export", :action => 'index', :format => 'xacml')
52
+ end
53
+
54
+ def role_color (role, fill = false)
55
+ fill_colors = %w{#ffdddd #ddffdd #ddddff #ffffdd #ffddff #ddffff}
56
+ colors = %w{#dd0000 #00dd00 #0000dd #dddd00 #dd00dd #00dddd}
57
+ @@role_colors ||= {}
58
+ @@role_colors[role] ||= begin
59
+ idx = @@role_colors.length % colors.length
60
+ [colors[idx], fill_colors[idx]]
61
+ end
62
+ @@role_colors[role][fill ? 1 : 0]
63
+ end
64
+
65
+ def role_fill_color (role)
66
+ role_color(role, true)
67
+ end
68
+
69
+ def auth_usage_info_classes (auth_info)
70
+ classes = []
71
+ if auth_info[:controller_permissions]
72
+ if auth_info[:controller_permissions][0]
73
+ classes << "catch-all" if auth_info[:controller_permissions][0].actions.include?(:all)
74
+ classes << "default-privilege" unless auth_info[:controller_permissions][0].privilege
75
+ classes << "default-context" unless auth_info[:controller_permissions][0].context
76
+ classes << "no-attribute-check" unless auth_info[:controller_permissions][0].attribute_check
77
+ end
78
+ else
79
+ classes << "unprotected"
80
+ end
81
+ classes * " "
82
+ end
83
+
84
+ def auth_usage_info_title (auth_info)
85
+ titles = []
86
+ if auth_usage_info_classes(auth_info) =~ /unprotected/
87
+ titles << I18n.t(:no_filter_access_to_call_protects_this_action, :scope => [:declarative_authorization])
88
+ end
89
+ if auth_usage_info_classes(auth_info) =~ /no-attribute-check/
90
+ titles << I18n.t(:action_is_not_protected_with_attribute_check, :scope => [:declarative_authorization])
91
+ end
92
+ if auth_usage_info_classes(auth_info) =~ /default-privilege/
93
+ titles << I18n.t(:privilege_set_automatically_from_action_name_by_all_rule, :scope => [:declarative_authorization])
94
+ end
95
+ if auth_usage_info_classes(auth_info) =~ /default-context/
96
+ titles << I18n.t(:context_set_automatically_from_controller_name_by_filter_access_to_call_without_context_option, :scope => [:declarative_authorization])
97
+ end
98
+ titles * ". "
99
+ end
100
+ end
@@ -0,0 +1,49 @@
1
+
2
+ digraph rules {
3
+ compound = true
4
+ edge [arrowhead=open]
5
+ node [shape=box,fontname="sans-serif",fontsize="16"]
6
+ fontname="sans-serif";fontsize="16"
7
+ ranksep = "0.3"
8
+ //concentrate = true
9
+ rankdir = TB
10
+ {
11
+ node [shape=ellipse,style=filled]
12
+ //rank = source
13
+ <% @roles.each do |role| %>
14
+ "<%= role.inspect %>" [fillcolor="<%= role_fill_color(role) %>"]
15
+ // ,URL="javascript:set_filter({roles: '<%= role %>'})"
16
+ <% end %>
17
+ <% @roles.each do |role| %>
18
+ <% (@role_hierarchy[role] || []).each do |lower_role| %>
19
+ "<%= role.inspect %>" -> "<%= lower_role.inspect %>" [constraint=false,arrowhead=empty]
20
+ <% end %>
21
+ <% end %>
22
+ }
23
+
24
+ <% @contexts.each do |context| %>
25
+ subgraph cluster_<%= context %> {
26
+ label = "<%= context.inspect %>"
27
+ style=filled; fillcolor="#eeeeee"
28
+ node[fillcolor=white,style=filled]
29
+ <% (@context_privs[context] || []).each do |priv| %>
30
+ <%= priv %>_<%= context %> [label="<%= priv.inspect %>"<%= ',fontcolor="#ff0000"' if @highlight_privilege == priv %>]
31
+ <% end %>
32
+ <% (@context_privs[context] || []).each do |priv| %>
33
+ <% (@privilege_hierarchy[priv] || []).
34
+ select {|p,c| (c.nil? or c == context) and @context_privs[context].include?(p)}.
35
+ each do |lower_priv, c| %>
36
+ <%= priv %>_<%= context %> -> <%= lower_priv %>_<%= context %> [arrowhead=empty]
37
+ <% end %>
38
+ <% end %>
39
+ //read_conferences -> update_conferences [style=invis]
40
+ //create_conferences -> delete_conferences [style=invis]
41
+ }
42
+ <% end %>
43
+
44
+ <% @roles.each do |role| %>
45
+ <% (@role_privs[role] || []).each do |context, privilege, unconditionally, attribute_string| %>
46
+ "<%= role.inspect %>" -> <%= privilege %>_<%= context %> [color="<%= role_color(role) %>", minlen=3<%= ", arrowhead=opendot, URL=\"javascript:\", edgetooltip=\"#{attribute_string.gsub('"','')}\"" unless unconditionally %>]
47
+ <% end %>
48
+ <% end %>
49
+ }
@@ -0,0 +1,39 @@
1
+ <h1><%= I18n.t(:authorization_rules_graph, :scope => [:declarative_authorization]) %></h1>
2
+ <p><%= I18n.t(:currently_active_rules_in_this_application, :scope => [:declarative_authorization]) %></p>
3
+ <p><%= navigation %></p>
4
+
5
+ <% javascript_tag do %>
6
+ function update_graph (form) {
7
+ base_url = "<%= url_for :format => 'svg' %>";
8
+ $('graph').data = base_url + '?' + form.serialize();
9
+ }
10
+
11
+ function set_filter (filter) {
12
+ for (f in filter) {
13
+ var select = $("filter_" + f);
14
+ if (select) {
15
+ var opt = select.down("option[value='"+ filter[f] + "']");
16
+ if (opt) {
17
+ opt.selected = true;
18
+ update_graph(select.form);
19
+ }
20
+ }
21
+ }
22
+ }
23
+ <% end %>
24
+ <p>
25
+ <% form_tag do %>
26
+ <%#= link_to_graph I18n.t(:rules, :scope => [:declarative_authorization]) %>
27
+ <%#= link_to_graph I18n.t(:privilege_hierarchy, :scope => [:declarative_authorization]), :type => 'priv_hierarchy' %>
28
+
29
+ <%= select_tag "filter_roles", options_for_select([[I18n.t(:all_rules, :scope => [:declarative_authorization]),'']] + controller.authorization_engine.roles.map(&:to_s).sort), :onchange => 'update_graph(this.form)' %>
30
+ <%= select_tag "filter_contexts", options_for_select([[I18n.t(:all_contexts, :scope => [:declarative_authorization]),'']] + controller.authorization_engine.auth_rules.collect {|ar| ar.contexts.to_a}.flatten.uniq.map(&:to_s).sort), :onchange => 'update_graph(this.form)' %>
31
+ <%= check_box_tag "effective_role_privs", "1", false, :onclick => 'update_graph(this.form)' %> <%= label_tag "effective_role_privs", I18n.t(:effective_privileges, :scope => [:declarative_authorization]) %>
32
+ <%= check_box_tag "privilege_hierarchy", "1", false, :onclick => 'update_graph(this.form)' %> <%= label_tag "privilege_hierarchy", I18n.t(:show_full_privilege_hierarchy, :scope => [:declarative_authorization]) %>
33
+ <% end %>
34
+ </p>
35
+ <div style="margin: 1em;border:1px solid #ccc;max-width:95%">
36
+ <object id="graph" data="<%= url_for :format => 'svg' %>" type="image/svg+xml" style="max-width:100%"/>
37
+ </div>
38
+ <%= button_to_function I18n.t(:zoom_in, :scope => [:declarative_authorization]), '$("graph").style.maxWidth = "";$(this).toggle();$(this).next().toggle()' %>
39
+ <%= button_to_function I18n.t(:zoom_out, :scope => [:declarative_authorization]), '$("graph").style.maxWidth = "100%";$(this).toggle();$(this).previous().toggle()', :style => 'display:none' %>