graylog2-declarative_authorization 0.5.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (44) hide show
  1. data/CHANGELOG +153 -0
  2. data/MIT-LICENSE +20 -0
  3. data/README.rdoc +529 -0
  4. data/Rakefile +35 -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 +218 -0
  8. data/app/views/authorization_rules/_change.erb +58 -0
  9. data/app/views/authorization_rules/_show_graph.erb +44 -0
  10. data/app/views/authorization_rules/_suggestions.erb +48 -0
  11. data/app/views/authorization_rules/change.html.erb +169 -0
  12. data/app/views/authorization_rules/graph.dot.erb +68 -0
  13. data/app/views/authorization_rules/graph.html.erb +47 -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 +20 -0
  18. data/garlic_example.rb +20 -0
  19. data/init.rb +5 -0
  20. data/lib/declarative_authorization.rb +17 -0
  21. data/lib/declarative_authorization/authorization.rb +705 -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 +68 -0
  27. data/lib/declarative_authorization/in_controller.rb +645 -0
  28. data/lib/declarative_authorization/in_model.rb +162 -0
  29. data/lib/declarative_authorization/maintenance.rb +212 -0
  30. data/lib/declarative_authorization/obligation_scope.rb +354 -0
  31. data/lib/declarative_authorization/rails_legacy.rb +22 -0
  32. data/lib/declarative_authorization/railsengine.rb +6 -0
  33. data/lib/declarative_authorization/reader.rb +521 -0
  34. data/lib/tasks/authorization_tasks.rake +82 -0
  35. data/test/authorization_test.rb +1104 -0
  36. data/test/controller_filter_resource_access_test.rb +511 -0
  37. data/test/controller_test.rb +480 -0
  38. data/test/dsl_reader_test.rb +178 -0
  39. data/test/helper_test.rb +247 -0
  40. data/test/maintenance_test.rb +46 -0
  41. data/test/model_test.rb +1883 -0
  42. data/test/schema.sql +55 -0
  43. data/test/test_helper.rb +152 -0
  44. metadata +112 -0
@@ -0,0 +1,58 @@
1
+ <form>
2
+ <h2>Which permission to change?</h2>
3
+ <p class="action-options">
4
+ <label>Privilege</label>
5
+ <%= select_tag :privilege, options_for_select(@privileges.map {|p| [human_privilege(p), p.to_s]}.sort, @privilege.to_s) %>
6
+ <br/>
7
+ <label>On</label>
8
+ <%= select_tag :context, options_for_select(@contexts.map {|c| [human_context(c), c.to_s]}.sort, @context.to_s) %>
9
+ <br/>
10
+ <label></label>
11
+ <%= link_to_function "Show current permissions", "show_current_permissions()", :class => 'unimportant' %>
12
+ <br/><br/>
13
+ How many users should be <strong>affected</strong>?
14
+ <br/>
15
+ <label></label>
16
+ <%= radio_button_tag :affected_users, :few, params[:affected_users] == 'few' %>
17
+ <label class="inline">A <strong>few</strong> users</label>
18
+ <%= radio_button_tag :affected_users, :many, params[:affected_users] == 'many' %>
19
+ <label class="inline"><strong>Many</strong> users</label>
20
+ </p>
21
+
22
+ <h2>Whose permission should be changed?</h2>
23
+ <table class="change-options">
24
+ <thead>
25
+ <tr>
26
+ <td>User</td>
27
+ <td>Current roles</td>
28
+ <td class="choose">?</td>
29
+ <td class="choose">Yes</td>
30
+ <td class="choose">No</td>
31
+ </tr>
32
+ </thead>
33
+ <tbody>
34
+ <% @users.each do |user| %>
35
+ <tr class="<%= controller.authorization_engine.permit?(@privilege, :context => @context, :user => user, :skip_attribute_test => true) ? 'permitted' : 'not-permitted' %>">
36
+ <td class="user_id"><%=h user.id %></td>
37
+ <td style="font-weight:bold"><%=h user.login %></td>
38
+ <td><%=h user.role_symbols.map {|r| human_role(r)} * ', ' %></td>
39
+ <td><%= radio_button_tag "user[#{user.id}][permission]", "undetermined", true %></td>
40
+ <td class="yes"><%= radio_button_tag "user[#{user.id}][permission]", "yes" %></td>
41
+ <td class="no"><%= radio_button_tag "user[#{user.id}][permission]", "no" %></td>
42
+ </tr>
43
+ <% end %>
44
+ <tr>
45
+ <td colspan="5" style="text-align:right; padding-top:0.5em" class="unimportant">
46
+ <span style="background: #FFE599;">&nbsp; &nbsp;</span> Current permission
47
+ </td>
48
+ </tr>
49
+ </tbody>
50
+ </table>
51
+
52
+ <h2 style="display:none">Prohibited actions</h2>
53
+ <ul id="prohibited_actions"></ul>
54
+
55
+ <p class="submit">
56
+ <%= button_to_function "Suggest Changes", "suggest_changes()" %>
57
+ </p>
58
+ </form>
@@ -0,0 +1,44 @@
1
+ <% javascript_tag do %>
2
+ if (typeof Prototype != 'object') {
3
+ //load up prototype... it's needed here
4
+ var s = document.createElement('script');
5
+ s.setAttribute('src','http://ajax.googleapis.com/ajax/libs/prototype/1.6.0.3/prototype.js');
6
+ document.getElementsByTagName('body')[0].appendChild(s);
7
+ }
8
+
9
+ function show_graph (privilege, context, user_ids) {
10
+ var params = {
11
+ privilege_hierarchy: 1,
12
+ highlight_privilege: privilege,
13
+ filter_contexts: context
14
+ };
15
+ if (user_ids)
16
+ params['user_ids[]'] = user_ids;
17
+ show_graph_with_params('graph', params);
18
+ }
19
+
20
+ var graph_params = {};
21
+ function show_graph_with_params (graph_id, params) {
22
+ graph_params[graph_id] = params;
23
+ base_url = "<%= graph_authorization_rules_path('svg') %>";
24
+ $(graph_id).data = base_url + '?' + Object.toQueryString(params);
25
+ $(graph_id).up().show();
26
+ }
27
+
28
+ function update_graph_params (graph_id, params) {
29
+ show_graph_with_params(graph_id,
30
+ $H(graph_params[graph_id] || {}).merge(params).toObject());
31
+ }
32
+
33
+ function toggle_graph_params (graph_id) {
34
+ var opts = {}
35
+ $A(arguments).slice(1).each(function (param) {
36
+ opts[param] = graph_params[graph_id][param] ? null : '1';
37
+ });
38
+ update_graph_params(graph_id, opts)
39
+ }
40
+ <% end %>
41
+ <div id="graph-container" style="display:none">
42
+ <%= link_to_function "Hide", "$('graph-container').hide()", :class => 'important' %><br/>
43
+ <object id="graph" data="" type="image/svg+xml" style="max-width:100%;margin-top: 0.5em"/>
44
+ </div>
@@ -0,0 +1,48 @@
1
+ <h2>Suggestions</h2>
2
+
3
+ <% if @approaches.length > 0 %>
4
+ <% if @approaches.first.changes.empty? %>
5
+ <p>No changes necessary.</p>
6
+ <% else %>
7
+ <p class="unimportant">
8
+ <%= pluralize(@approaches.length, 'approach') %> in
9
+ <%= pluralize(@grouped_approaches.length, 'group') %>
10
+ <%= params[:affected_users] ? "– #{params[:affected_users] == 'few' ? "fewer" : "most"} affected users first" : "" %>
11
+ </p>
12
+ <ul>
13
+ <% @grouped_approaches.each_with_index do |grouped_approach, group_index| %>
14
+ <% ([grouped_approach.approach] + grouped_approach.similar_approaches).each_with_index do |approach, index| %>
15
+ <li <%= (group_index < 3 || params[:show_all]) && index == 0 ? '' : 'style="display: none"' %> class="<%= index == 0 ? 'primary' : "secondary" %> group-<%= group_index %>">
16
+ <!--<span class="ord"><%= (index + 1) %></span>-->
17
+ <span class="unimportant">Affected users</span> <strong><%= affected_users_count(approach) %></strong> &nbsp;
18
+ <span class="unimportant">Complexity</span> <strong><%= approach.weight %></strong> &nbsp;
19
+ <%= link_to_function "Diagram", "show_suggest_graph('#{serialize_changes(approach)}', '#{serialize_relevant_roles(approach)}', '#{@context}', relevant_user_ids())", :class => "show-approach" %>
20
+ <ul>
21
+ <% approach.changes.each do |action| %>
22
+ <% (action.to_a[0].is_a?(Enumerable) ? action.to_a : [action.to_a]).each do |step| %>
23
+ <li>
24
+ <%= describe_step(step.to_a, :with_removal => true) %>
25
+ </li>
26
+ <% end %>
27
+ <% end %>
28
+ </ul>
29
+ <% if index == 0 %>
30
+ <% if grouped_approach.similar_approaches.empty? %>
31
+ <span class="unimportant show-others-in-group">No further suggestions in this group</span>
32
+ <% else %>
33
+ <%= link_to_function "Show further <strong>#{pluralize grouped_approach.similar_approaches.length, "suggestion"}</strong> in this group", "show_group_approaches(#{group_index})", :class => "show-others-in-group" %>
34
+ <% end %>
35
+ <% end %>
36
+ <%= link_to_function "Hide further suggestions", "hide_group_approaches(#{group_index})" if index > 0 and index == grouped_approach.similar_approaches.length %>
37
+ </li>
38
+ <% if index == 0 and group_index == 2 and @grouped_approaches.length > 3 %>
39
+ <li <%= !params[:show_all] ? '' : 'style="display: none"' %>><%= link_to_function "Show further <strong>#{pluralize(@grouped_approaches.length - 3, 'group')}</strong>", "show_all_groups(); $(this).up().hide()" %></li>
40
+ <% end %>
41
+ <% end %>
42
+ <% end %>
43
+ </ul>
44
+
45
+ <% end %>
46
+ <% else %>
47
+ <p><strong>No approach found.</strong></p>
48
+ <% end %>
@@ -0,0 +1,169 @@
1
+ <h1>Suggestions on Authorization Rules Change</h1>
2
+ <p><%= navigation %></p>
3
+ <div style="display:none" id="suggest-graph-container">
4
+ <%= link_to_function "Hide", "$(this).up().hide()", :class => 'important' %>
5
+ <%= link_to_function "Toggle stacked roles", "toggle_graph_params('suggest-graph', 'stacked_roles');" %>
6
+ <%= link_to_function "Toggle only users' roles", "toggle_graph_params('suggest-graph', 'only_relevant_roles');" %><br/>
7
+ <object id="suggest-graph" data="" type="image/svg+xml" style="max-width: 98%;max-height: 95%;margin-top: 0.5em"/>
8
+ </div>
9
+ <%= render 'show_graph' %>
10
+
11
+ <div id="spinner" style="display:none">Searching...</div>
12
+
13
+ <style type="text/css">
14
+ .action-options label { display: block; float: left; width: 7em; padding-bottom: 0.5em }
15
+ .action-options label.inline { display: inline; float: none }
16
+ .action-options select { float: left; }
17
+ .action-options br { clear: both; }
18
+ .action-options { margin-bottom: 2em }
19
+ .change-options { margin-bottom: 1em }
20
+ .change-options td.user_id { display: none }
21
+ .change-options td { padding-right: 1em; padding-left: 0.5em }
22
+ .change-options thead td { border-bottom: 1px solid lightgrey }
23
+ .change-options thead td.choose { text-align: center; font-weight: bold }
24
+ .change-options tr.permitted td.yes,
25
+ .change-options tr.not-permitted td.no { background: #FFE599 }
26
+ .submit { margin-top: 0 }
27
+ .submit input { font-weight: bold; font-size: 120% }
28
+ #suggest-result {
29
+ position: absolute; left: 55%; right: 10px;
30
+ border-left: 1px solid grey;
31
+ padding-left: 2em;
32
+ z-index: 10;
33
+ }
34
+ #suggest-result>ul { padding-left: 0 }
35
+ #suggest-result>ul>li { list-style: none; margin-bottom: 1em }
36
+ #suggest-result>ul>li.secondary { padding-left: 2em }
37
+ #suggest-result li { padding-left: 0 }
38
+ #suggest-result ul ul { padding-left: 2em }
39
+ #suggest-result .ord { float: left; display: block; width: 2em; font-weight: bold; color: grey }
40
+ .show-approach, .show-others-in-group { visibility: hidden }
41
+ .prohibit { text-decoration: none; visibility: hidden }
42
+ li:hover .show-approach, li:hover .prohibit,
43
+ li:hover .show-others-in-group { visibility: visible }
44
+ #suggest-graph-container {
45
+ background: white; border:1px solid grey;
46
+ position:fixed; z-index: 20;
47
+ left:10%; bottom: 10%; right: 10%; top: 10%;
48
+ padding: 0.5em
49
+ }
50
+ #graph-container {
51
+ background: white; margin: 1em; border:1px solid grey; padding: 0.5em;
52
+ max-width:50%; position:fixed; z-index: 20; right:0;
53
+ }
54
+ .unimportant, .remove, .prohibit { color: grey }
55
+ .important { font-weight: bold }
56
+ .remove { cursor: pointer }
57
+ #spinner { position: fixed; top: 0; right: 0; background: #FFE599; padding: 1em }
58
+ </style>
59
+ <% javascript_tag do %>
60
+ function suggest_changes (refresh) {
61
+ var opened_groups = $$("#suggest-result>ul>li.secondary").select(function (li) {return li.visible()}).collect(function (li) {
62
+ return li.classNames().toArray()[1].split("-")[1];
63
+ }).uniq();
64
+
65
+ if (refresh)
66
+ $("spinner").show();
67
+ else
68
+ $("suggest-result").innerHTML = "Searching...";
69
+
70
+
71
+ $("suggest-result").show();
72
+ new Ajax.Updater({success: 'suggest-result'}, '<%= suggest_change_authorization_rules_path %>', {
73
+ method: 'get',
74
+ onFailure: function(request) {
75
+ $("suggest-result").innerHTML = "Error while searching."
76
+ },
77
+ onComplete: function () {
78
+ $("spinner").hide();
79
+ opened_groups.each(function (group_no) {
80
+ show_group_approaches(group_no);
81
+ });
82
+ },
83
+ parameters: $H($('change').down('form').serialize(true)).merge(refresh ? {show_all: "true"} : {}).toQueryString()
84
+ });
85
+ if (!refresh)
86
+ location.hash = 'suggest-result';
87
+ }
88
+
89
+ function show_suggest_graph (changes, filter_roles_params, filter_context, user_ids) {
90
+ var params = {changes: changes, highlight_privilege: $F('privilege'), stacked_roles: '1'};
91
+ if (filter_context)
92
+ params['filter_contexts'] = filter_context;
93
+ if (user_ids)
94
+ params['user_ids[]'] = user_ids;
95
+ show_graph_with_params('suggest-graph', params);
96
+ }
97
+
98
+ document.observe('dom:loaded', function() {
99
+ install_change_observers();
100
+ });
101
+
102
+ function install_change_observers () {
103
+ $$('#change select').each(function (el) {
104
+ el.observe('change', function (event) {
105
+ var form = $('change').down('form');
106
+ new Ajax.Updater({success: 'change'}, '<%= url_for %>', {
107
+ parameters: Form.serializeElements(form.select('select').concat(form.getInputs('radio', 'affected_users')), true),
108
+ method: 'get',
109
+ onComplete: function () {
110
+ install_change_observers();
111
+ if ($('graph-container').visible())
112
+ show_current_permissions();
113
+ }
114
+ });
115
+ });
116
+ });
117
+ $('prohibited_actions').observe('click', function (event) {
118
+ var target = event.findElement();
119
+ if (target.hasClassName('remove')) {
120
+ target.up().remove();
121
+ if ($('prohibited_actions').childElements().length == 0)
122
+ $('prohibited_actions').previous().hide();
123
+ suggest_changes();
124
+ }
125
+ });
126
+ }
127
+
128
+ function show_current_permissions () {
129
+ show_graph($F('privilege'), $F('context')/*, relevant_user_ids()*/);
130
+ }
131
+
132
+ function show_all_groups () {
133
+ $$('#suggest-result>ul>li.primary').invoke("show");
134
+ }
135
+
136
+ function show_group_approaches (group_no) {
137
+ $$('#suggest-result>ul>li.secondary.group-' + group_no).invoke("show");
138
+ $$('#suggest-result>ul>li.primary.group-' + group_no + ' a.show-others-in-group').invoke("hide");
139
+ }
140
+
141
+ function hide_group_approaches (group_no) {
142
+ $$('#suggest-result>ul>li.secondary.group-' + group_no).invoke("hide");
143
+ $$('#suggest-result>ul>li.primary.group-' + group_no + ' a.show-others-in-group').invoke("show");
144
+ }
145
+
146
+ function relevant_user_ids () {
147
+ return $$('#change .user_id').collect(function (el) {
148
+ return el.innerHTML;
149
+ }).reject(function (id) {
150
+ return $('user_' + id + '_permission_undetermined').checked;
151
+ });
152
+ }
153
+
154
+ var prohibited_action_template =
155
+ new Template('<li>#{description} <span class="remove">[x]</span><input type="hidden" name="prohibited_action[]" value="#{action}"></li>');
156
+ function prohibit_action (action, description) {
157
+ $('prohibited_actions').previous().show();
158
+ $('prohibited_actions').insert(
159
+ {bottom: prohibited_action_template.evaluate({action: action, description: description}) }
160
+ );
161
+ suggest_changes(true);
162
+ }
163
+ <% end %>
164
+
165
+ <div id="suggest-result" style="display:none"></div>
166
+
167
+ <div id="change">
168
+ <%= render 'change' %>
169
+ </div>
@@ -0,0 +1,68 @@
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
+ <% unless @users.blank? %>
12
+ {
13
+ rank = source
14
+ node [shape=polygon,style=filled,fillcolor="#eeeeee"]
15
+ <% @users.each do |user| %>
16
+ "<%= user.login %>"
17
+ <% end %>
18
+ }
19
+ <% end %>
20
+
21
+ {
22
+ node [shape=ellipse,style=filled]
23
+ <%= @stacked_roles ? '' : "rank = same" %>
24
+ <% @roles.each do |role| %>
25
+ "<%= role.inspect %>" [fillcolor="<%= role_fill_color(role) %>",label="<%= human_role(role) %>"]
26
+ // ,URL="javascript:set_filter({roles: '<%= role %>'})"
27
+ <% end %>
28
+ <% @roles.each do |role| %>
29
+ <% (@role_hierarchy[role] || []).select {|lower_role| @roles.include?(lower_role)}.each do |lower_role| %>
30
+ "<%= role.inspect %>" -> "<%= lower_role.inspect %>" [arrowhead=empty]
31
+ <% end %>
32
+ <% end %>
33
+ }
34
+
35
+ <% unless @users.blank? %>
36
+ <% @users.each do |user| %>
37
+ <% user.role_symbols.select {|role| @roles.include?(role)}.each do |role| %>
38
+ "<%= user.login %>" -> "<%= role.inspect %>" [color="<%= has_changed(:assign_role_to_user, role, user.login) ? '#00dd00' : (has_changed(:remove_role_from_user, role, user.login) ? '#dd0000' : '#000000') %>"]
39
+ <% end %>
40
+ <% end %>
41
+ <% end %>
42
+
43
+ <% @contexts.each do |context| %>
44
+ subgraph cluster_<%= context %> {
45
+ label = "<%= human_context(context) %>"
46
+ style=filled; fillcolor="#eeeeee"
47
+ node[fillcolor=white,style=filled]
48
+ <% (@context_privs[context] || []).each do |priv| %>
49
+ <%= priv %>_<%= context %> [label="<%= human_privilege(priv) %>"<%= ',fontcolor="#ff0000"' if @highlight_privilege == priv %>]
50
+ <% end %>
51
+ <% (@context_privs[context] || []).each do |priv| %>
52
+ <% (@privilege_hierarchy[priv] || []).
53
+ select {|p,c| (c.nil? or c == context) and @context_privs[context].include?(p)}.
54
+ each do |lower_priv, c| %>
55
+ <%= priv %>_<%= context %> -> <%= lower_priv %>_<%= context %> [arrowhead=empty]
56
+ <% end %>
57
+ <% end %>
58
+ //read_conferences -> update_conferences [style=invis]
59
+ //create_conferences -> delete_conferences [style=invis]
60
+ }
61
+ <% end %>
62
+
63
+ <% @roles.each do |role| %>
64
+ <% (@role_privs[role] || []).each do |context, privilege, unconditionally, attribute_string| %>
65
+ "<%= role.inspect %>" -> <%= privilege %>_<%= context %> [color="<%= privilege_color(privilege, context, role) %>", minlen=3<%= ", arrowhead=opendot, URL=\"javascript:\", edgetooltip=\"#{attribute_string.gsub('"','')}\"" unless unconditionally %>]
66
+ <% end %>
67
+ <% end %>
68
+ }
@@ -0,0 +1,47 @@
1
+ <h1>Authorization Rules Graph</h1>
2
+ <p>Currently active rules in this application.</p>
3
+ <p><%= navigation %></p>
4
+
5
+ <% javascript_tag do %>
6
+ if (typeof Prototype != 'object') {
7
+ //load up prototype... it's needed here
8
+ var s = document.createElement('script');
9
+ s.setAttribute('src','http://ajax.googleapis.com/ajax/libs/prototype/1.6.0.3/prototype.js');
10
+ document.getElementsByTagName('body')[0].appendChild(s);
11
+ }
12
+
13
+ function update_graph (form) {
14
+ base_url = "<%= url_for :format => 'svg' %>";
15
+ $('graph').data = base_url + '?' + form.serialize();
16
+ }
17
+
18
+ function set_filter (filter) {
19
+ for (f in filter) {
20
+ var select = $("filter_" + f);
21
+ if (select) {
22
+ var opt = select.down("option[value='"+ filter[f] + "']");
23
+ if (opt) {
24
+ opt.selected = true;
25
+ update_graph(select.form);
26
+ }
27
+ }
28
+ }
29
+ }
30
+ <% end %>
31
+ <p>
32
+ <% form_tag do %>
33
+ <%#= link_to_graph "Rules" %>
34
+ <%#= link_to_graph "Privilege hierarchy", :type => 'priv_hierarchy' %>
35
+
36
+ <%= select_tag "filter_roles", options_for_select([["All roles",'']] + controller.authorization_engine.roles.map(&:to_s).sort), :onchange => 'update_graph(this.form)' %>
37
+ <%= select_tag "filter_contexts", options_for_select([["All contexts",'']] + controller.authorization_engine.auth_rules.collect {|ar| ar.contexts.to_a}.flatten.uniq.map(&:to_s).sort), :onchange => 'update_graph(this.form)' %>
38
+ <%= check_box_tag "effective_role_privs", "1", false, :onclick => 'update_graph(this.form)' %> <%= label_tag "effective_role_privs", "Effective privileges" %>
39
+ <%= check_box_tag "privilege_hierarchy", "1", false, :onclick => 'update_graph(this.form)' %> <%= label_tag "privilege_hierarchy", "Show full privilege hierarchy" %>
40
+ <%= check_box_tag "stacked_roles", "1", false, :onclick => 'update_graph(this.form)' %> <%= label_tag "stacked_roles", "Stacked roles" %>
41
+ <% end %>
42
+ </p>
43
+ <div style="margin: 1em;border:1px solid #ccc;max-width:95%">
44
+ <object id="graph" data="<%= url_for :format => 'svg' %>" type="image/svg+xml" style="max-width:100%"/>
45
+ </div>
46
+ <%= button_to_function "Zoom in", '$("graph").style.maxWidth = "";$(this).toggle();$(this).next().toggle()' %>
47
+ <%= button_to_function "Zoom out", '$("graph").style.maxWidth = "100%";$(this).toggle();$(this).previous().toggle()', :style => 'display:none' %>
@@ -0,0 +1,17 @@
1
+ <h1>Authorization Rules</h1>
2
+ <p>Currently active rules in this application.</p>
3
+ <p><%= navigation %></p>
4
+ <style type="text/css">
5
+ pre .constant {color: #a00;}
6
+ pre .special {color: red;}
7
+ pre .operator {color: red;}
8
+ pre .statement {color: #00a;}
9
+ pre .proc {color: #0a0;}
10
+ pre .privilege, pre .context {font-weight: bold}
11
+ pre .preproc, pre .comment, pre .comment span {color: grey !important;}
12
+ pre .note {color: #a00; position:absolute; cursor: help; left: 15px }
13
+ pre.with-notes {padding-left: 35px}
14
+ </style>
15
+ <pre class="with-notes">
16
+ <%= policy_analysis_hints(syntax_highlight(h(@auth_rules_script)), @auth_rules_script) %>
17
+ </pre>