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.
- data/CHANGELOG +83 -0
- data/MIT-LICENSE +20 -0
- data/README.rdoc +510 -0
- data/Rakefile +43 -0
- data/app/controllers/authorization_rules_controller.rb +259 -0
- data/app/controllers/authorization_usages_controller.rb +23 -0
- data/app/helpers/authorization_rules_helper.rb +187 -0
- data/app/views/authorization_rules/_change.erb +58 -0
- data/app/views/authorization_rules/_show_graph.erb +37 -0
- data/app/views/authorization_rules/_suggestions.erb +48 -0
- data/app/views/authorization_rules/change.html.erb +152 -0
- data/app/views/authorization_rules/graph.dot.erb +68 -0
- data/app/views/authorization_rules/graph.html.erb +40 -0
- data/app/views/authorization_rules/index.html.erb +17 -0
- data/app/views/authorization_usages/index.html.erb +36 -0
- data/authorization_rules.dist.rb +20 -0
- data/config/routes.rb +7 -0
- data/garlic_example.rb +20 -0
- data/init.rb +5 -0
- data/lib/declarative_authorization.rb +15 -0
- data/lib/declarative_authorization/authorization.rb +634 -0
- 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 +620 -0
- data/lib/declarative_authorization/development_support/development_support.rb +243 -0
- data/lib/declarative_authorization/helper.rb +60 -0
- data/lib/declarative_authorization/in_controller.rb +597 -0
- data/lib/declarative_authorization/in_model.rb +159 -0
- data/lib/declarative_authorization/maintenance.rb +182 -0
- data/lib/declarative_authorization/obligation_scope.rb +308 -0
- data/lib/declarative_authorization/rails_legacy.rb +14 -0
- data/lib/declarative_authorization/reader.rb +441 -0
- data/test/authorization_test.rb +827 -0
- data/test/controller_filter_resource_access_test.rb +394 -0
- data/test/controller_test.rb +386 -0
- data/test/dsl_reader_test.rb +157 -0
- data/test/helper_test.rb +171 -0
- data/test/maintenance_test.rb +46 -0
- data/test/model_test.rb +1308 -0
- data/test/schema.sql +54 -0
- data/test/test_helper.rb +118 -0
- metadata +106 -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(&: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
|
+
<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 * ', ' %></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;"> </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,37 @@
|
|
1
|
+
<% javascript_tag do %>
|
2
|
+
function show_graph (privilege, context, user_ids) {
|
3
|
+
var params = {
|
4
|
+
privilege_hierarchy: 1,
|
5
|
+
highlight_privilege: privilege,
|
6
|
+
filter_contexts: context
|
7
|
+
};
|
8
|
+
if (user_ids)
|
9
|
+
params['user_ids[]'] = user_ids;
|
10
|
+
show_graph_with_params('graph', params);
|
11
|
+
}
|
12
|
+
|
13
|
+
var graph_params = {};
|
14
|
+
function show_graph_with_params (graph_id, params) {
|
15
|
+
graph_params[graph_id] = params;
|
16
|
+
base_url = "<%= graph_authorization_rules_path('svg') %>";
|
17
|
+
$(graph_id).data = base_url + '?' + Object.toQueryString(params);
|
18
|
+
$(graph_id).up().show();
|
19
|
+
}
|
20
|
+
|
21
|
+
function update_graph_params (graph_id, params) {
|
22
|
+
show_graph_with_params(graph_id,
|
23
|
+
$H(graph_params[graph_id] || {}).merge(params).toObject());
|
24
|
+
}
|
25
|
+
|
26
|
+
function toggle_graph_params (graph_id) {
|
27
|
+
var opts = {}
|
28
|
+
$A(arguments).slice(1).each(function (param) {
|
29
|
+
opts[param] = graph_params[graph_id][param] ? null : '1';
|
30
|
+
});
|
31
|
+
update_graph_params(graph_id, opts)
|
32
|
+
}
|
33
|
+
<% end %>
|
34
|
+
<div id="graph-container" style="display:none">
|
35
|
+
<%= link_to_function "Hide", "$('graph-container').hide()", :class => 'important' %><br/>
|
36
|
+
<object id="graph" data="" type="image/svg+xml" style="max-width:100%;margin-top: 0.5em"/>
|
37
|
+
</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>
|
18
|
+
<span class="unimportant">Complexity</span> <strong><%= approach.weight %></strong>
|
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 #{pluralize grouped_approach.similar_approaches.length, "suggestion"} 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 #{pluralize(@grouped_approaches.length - 3, 'group')}", "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,152 @@
|
|
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
|
+
<style type="text/css">
|
12
|
+
.action-options label { display: block; float: left; width: 7em; padding-bottom: 0.5em }
|
13
|
+
.action-options label.inline { display: inline; float: none }
|
14
|
+
.action-options select { float: left; }
|
15
|
+
.action-options br { clear: both; }
|
16
|
+
.action-options { margin-bottom: 2em }
|
17
|
+
.change-options { margin-bottom: 1em }
|
18
|
+
.change-options td.user_id { display: none }
|
19
|
+
.change-options td { padding-right: 1em; padding-left: 0.5em }
|
20
|
+
.change-options thead td { border-bottom: 1px solid lightgrey }
|
21
|
+
.change-options thead td.choose { text-align: center; font-weight: bold }
|
22
|
+
.change-options tr.permitted td.yes,
|
23
|
+
.change-options tr.not-permitted td.no { background: #FFE599 }
|
24
|
+
.submit { margin-top: 0 }
|
25
|
+
.submit input { font-weight: bold; font-size: 120% }
|
26
|
+
#suggest-result {
|
27
|
+
position: absolute; left: 55%; right: 10px;
|
28
|
+
border-left: 1px solid grey;
|
29
|
+
padding-left: 2em;
|
30
|
+
z-index: 10;
|
31
|
+
}
|
32
|
+
#suggest-result>ul { padding-left: 0 }
|
33
|
+
#suggest-result>ul>li { list-style: none; margin-bottom: 1em }
|
34
|
+
#suggest-result>ul>li.secondary { padding-left: 2em }
|
35
|
+
#suggest-result li { padding-left: 0 }
|
36
|
+
#suggest-result ul ul { padding-left: 2em }
|
37
|
+
#suggest-result .ord { float: left; display: block; width: 2em; font-weight: bold; color: grey }
|
38
|
+
.show-approach, .show-others-in-group { visibility: hidden }
|
39
|
+
.prohibit { text-decoration: none; visibility: hidden }
|
40
|
+
li:hover .show-approach, li:hover .prohibit,
|
41
|
+
li:hover .show-others-in-group { visibility: visible }
|
42
|
+
#suggest-graph-container {
|
43
|
+
background: white; border:1px solid grey;
|
44
|
+
position:fixed; z-index: 20;
|
45
|
+
left:10%; bottom: 10%; right: 10%; top: 10%;
|
46
|
+
padding: 0.5em
|
47
|
+
}
|
48
|
+
#graph-container {
|
49
|
+
background: white; margin: 1em; border:1px solid grey; padding: 0.5em;
|
50
|
+
max-width:50%; position:fixed; z-index: 20; right:0;
|
51
|
+
}
|
52
|
+
.unimportant, .remove, .prohibit { color: grey }
|
53
|
+
.important { font-weight: bold }
|
54
|
+
.remove { cursor: pointer }
|
55
|
+
</style>
|
56
|
+
<% javascript_tag do %>
|
57
|
+
function suggest_changes (refresh) {
|
58
|
+
if (!refresh)
|
59
|
+
$("suggest-result").innerHTML = "Searching...";
|
60
|
+
$("suggest-result").show();
|
61
|
+
new Ajax.Updater({success: 'suggest-result'}, '<%= suggest_change_authorization_rules_path %>', {
|
62
|
+
method: 'get',
|
63
|
+
onFailure: function(request) {
|
64
|
+
$("suggest-result").innerHTML = "Error while searching."
|
65
|
+
},
|
66
|
+
parameters: $H($('change').down('form').serialize(true)).merge(refresh ? {show_all: "true"} : {}).toQueryString()
|
67
|
+
});
|
68
|
+
if (!refresh)
|
69
|
+
location.hash = 'suggest-result';
|
70
|
+
}
|
71
|
+
|
72
|
+
function show_suggest_graph (changes, filter_roles_params, filter_context, user_ids) {
|
73
|
+
var params = {changes: changes, highlight_privilege: $F('privilege')};
|
74
|
+
if (filter_context)
|
75
|
+
params['filter_contexts'] = filter_context;
|
76
|
+
if (user_ids)
|
77
|
+
params['user_ids[]'] = user_ids;
|
78
|
+
show_graph_with_params('suggest-graph', params);
|
79
|
+
}
|
80
|
+
|
81
|
+
document.observe('dom:loaded', function() {
|
82
|
+
install_change_observers();
|
83
|
+
});
|
84
|
+
|
85
|
+
function install_change_observers () {
|
86
|
+
$$('#change select').each(function (el) {
|
87
|
+
el.observe('change', function (event) {
|
88
|
+
var form = $('change').down('form');
|
89
|
+
new Ajax.Updater({success: 'change'}, '<%= url_for %>', {
|
90
|
+
parameters: Form.serializeElements(form.select('select').concat(form.getInputs('radio', 'affected_users')), true),
|
91
|
+
method: 'get',
|
92
|
+
onComplete: function () {
|
93
|
+
install_change_observers();
|
94
|
+
if ($('graph-container').visible())
|
95
|
+
show_current_permissions();
|
96
|
+
}
|
97
|
+
});
|
98
|
+
});
|
99
|
+
});
|
100
|
+
$('prohibited_actions').observe('click', function (event) {
|
101
|
+
var target = event.findElement();
|
102
|
+
if (target.hasClassName('remove')) {
|
103
|
+
target.up().remove();
|
104
|
+
if ($('prohibited_actions').childElements().length == 0)
|
105
|
+
$('prohibited_actions').previous().hide();
|
106
|
+
suggest_changes();
|
107
|
+
}
|
108
|
+
});
|
109
|
+
}
|
110
|
+
|
111
|
+
function show_current_permissions () {
|
112
|
+
show_graph($F('privilege'), $F('context')/*, relevant_user_ids()*/);
|
113
|
+
}
|
114
|
+
|
115
|
+
function show_all_groups () {
|
116
|
+
$$('#suggest-result>ul>li.primary').invoke("show");
|
117
|
+
}
|
118
|
+
|
119
|
+
function show_group_approaches (group_no) {
|
120
|
+
$$('#suggest-result>ul>li.secondary.group-' + group_no).invoke("show");
|
121
|
+
$$('#suggest-result>ul>li.primary.group-' + group_no + ' a.show-others-in-group').invoke("hide");
|
122
|
+
}
|
123
|
+
|
124
|
+
function hide_group_approaches (group_no) {
|
125
|
+
$$('#suggest-result>ul>li.secondary.group-' + group_no).invoke("hide");
|
126
|
+
$$('#suggest-result>ul>li.primary.group-' + group_no + ' a.show-others-in-group').invoke("show");
|
127
|
+
}
|
128
|
+
|
129
|
+
function relevant_user_ids () {
|
130
|
+
return $$('#change .user_id').collect(function (el) {
|
131
|
+
return el.innerHTML;
|
132
|
+
}).reject(function (id) {
|
133
|
+
return $('user_' + id + '_permission_undetermined').checked;
|
134
|
+
});
|
135
|
+
}
|
136
|
+
|
137
|
+
var prohibited_action_template =
|
138
|
+
new Template('<li>#{description} <span class="remove">[x]</span><input type="hidden" name="prohibited_action[]" value="#{action}"></li>');
|
139
|
+
function prohibit_action (action, description) {
|
140
|
+
$('prohibited_actions').previous().show();
|
141
|
+
$('prohibited_actions').insert(
|
142
|
+
{bottom: prohibited_action_template.evaluate({action: action, description: description}) }
|
143
|
+
);
|
144
|
+
suggest_changes(true);
|
145
|
+
}
|
146
|
+
<% end %>
|
147
|
+
|
148
|
+
<div id="suggest-result" style="display:none"></div>
|
149
|
+
|
150
|
+
<div id="change">
|
151
|
+
<%= render 'change' %>
|
152
|
+
</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) %>"]
|
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 = "<%= context.inspect %>"
|
46
|
+
style=filled; fillcolor="#eeeeee"
|
47
|
+
node[fillcolor=white,style=filled]
|
48
|
+
<% (@context_privs[context] || []).each do |priv| %>
|
49
|
+
<%= priv %>_<%= context %> [label="<%= priv.inspect %>"<%= ',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,40 @@
|
|
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
|
+
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 "Rules" %>
|
27
|
+
<%#= link_to_graph "Privilege hierarchy", :type => 'priv_hierarchy' %>
|
28
|
+
|
29
|
+
<%= select_tag "filter_roles", options_for_select([["All roles",'']] + controller.authorization_engine.roles.map(&:to_s).sort), :onchange => 'update_graph(this.form)' %>
|
30
|
+
<%= 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)' %>
|
31
|
+
<%= check_box_tag "effective_role_privs", "1", false, :onclick => 'update_graph(this.form)' %> <%= label_tag "effective_role_privs", "Effective privileges" %>
|
32
|
+
<%= check_box_tag "privilege_hierarchy", "1", false, :onclick => 'update_graph(this.form)' %> <%= label_tag "privilege_hierarchy", "Show full privilege hierarchy" %>
|
33
|
+
<%= check_box_tag "stacked_roles", "1", false, :onclick => 'update_graph(this.form)' %> <%= label_tag "stacked_roles", "Stacked roles" %>
|
34
|
+
<% end %>
|
35
|
+
</p>
|
36
|
+
<div style="margin: 1em;border:1px solid #ccc;max-width:95%">
|
37
|
+
<object id="graph" data="<%= url_for :format => 'svg' %>" type="image/svg+xml" style="max-width:100%"/>
|
38
|
+
</div>
|
39
|
+
<%= button_to_function "Zoom in", '$("graph").style.maxWidth = "";$(this).toggle();$(this).next().toggle()' %>
|
40
|
+
<%= 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>
|
@@ -0,0 +1,36 @@
|
|
1
|
+
<h1>Authorization Usage</h1>
|
2
|
+
<%= render 'authorization_rules/show_graph' %>
|
3
|
+
<p>Filter rules in actions by controller:</p>
|
4
|
+
<p><%= navigation %></p>
|
5
|
+
<style type="text/css">
|
6
|
+
.auth-usages th { text-align: left; padding-top: 1em }
|
7
|
+
.auth-usages td { padding-right: 1em }
|
8
|
+
.auth-usages tr.action { cursor: pointer }
|
9
|
+
.auth-usages tr.unprotected { background: #FFA399 }
|
10
|
+
.auth-usages tr.no-attribute-check { background: #FFE599 }
|
11
|
+
/*.auth-usages tr.catch-all td.privilege,*/
|
12
|
+
.auth-usages tr.default-privilege td.privilege,
|
13
|
+
.auth-usages tr.default-context td.context { color: #888888 }
|
14
|
+
#graph-container {margin: 1em; border:1px solid #ccc; max-width:50%; position:fixed; right:0;}
|
15
|
+
</style>
|
16
|
+
<table class="auth-usages">
|
17
|
+
<% @auth_usages_by_controller.keys.sort {|c1, c2| c1.name <=> c2.name}.each do |controller| %>
|
18
|
+
<% default_context = controller.controller_name.to_sym rescue nil %>
|
19
|
+
<tr>
|
20
|
+
<th colspan="3"><%= h controller.controller_name %></th>
|
21
|
+
</tr>
|
22
|
+
<% @auth_usages_by_controller[controller].keys.sort {|c1, c2| c1.to_s <=> c2.to_s}.each do |action| %>
|
23
|
+
<% auth_info = @auth_usages_by_controller[controller][action] %>
|
24
|
+
<% first_permission = auth_info[:controller_permissions] && auth_info[:controller_permissions][0] %>
|
25
|
+
<tr class="action <%= auth_usage_info_classes(auth_info) %>" title="<%= auth_usage_info_title(auth_info) %>" onclick="show_graph('<%= auth_info[:privilege] || action %>','<%= auth_info[:context] || default_context %>')">
|
26
|
+
<td><%= h action %></td>
|
27
|
+
<% if first_permission %>
|
28
|
+
<td class="privilege"><%= h auth_info[:privilege] || action %></td>
|
29
|
+
<td class="context"><%= h auth_info[:context] || default_context %></td>
|
30
|
+
<% else %>
|
31
|
+
<td></td><td></td>
|
32
|
+
<% end %>
|
33
|
+
</tr>
|
34
|
+
<% end %>
|
35
|
+
<% end %>
|
36
|
+
</table>
|