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.
- data/CHANGELOG +70 -0
- data/MIT-LICENSE +20 -0
- data/README.rdoc +9 -0
- data/Rakefile +43 -0
- data/app/controllers/authorization_rules_controller.rb +114 -0
- data/app/controllers/authorization_usages_controller.rb +23 -0
- data/app/helpers/authorization_rules_helper.rb +100 -0
- data/app/views/authorization_rules/graph.dot.erb +49 -0
- data/app/views/authorization_rules/graph.html.erb +39 -0
- data/app/views/authorization_rules/index.html.erb +16 -0
- data/app/views/authorization_usages/index.html.erb +45 -0
- data/authorization_rules.dist.rb +20 -0
- data/config/locales/en.declarative_authorization.yml +35 -0
- data/config/locales/ro.declarative_authorization.yml +35 -0
- data/config/routes.rb +6 -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 +578 -0
- data/lib/declarative_authorization/authorization_rules_analyzer.rb +138 -0
- data/lib/declarative_authorization/helper.rb +56 -0
- data/lib/declarative_authorization/in_controller.rb +343 -0
- data/lib/declarative_authorization/in_model.rb +125 -0
- data/lib/declarative_authorization/maintenance.rb +174 -0
- data/lib/declarative_authorization/obligation_scope.rb +292 -0
- data/lib/declarative_authorization/rails_legacy.rb +14 -0
- data/lib/declarative_authorization/reader.rb +430 -0
- data/test/authorization_rules_analyzer_test.rb +123 -0
- data/test/authorization_test.rb +779 -0
- data/test/controller_test.rb +361 -0
- data/test/dsl_reader_test.rb +157 -0
- data/test/helper_test.rb +133 -0
- data/test/maintenance_test.rb +15 -0
- data/test/model_test.rb +1143 -0
- data/test/schema.sql +53 -0
- data/test/test_helper.rb +99 -0
- 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
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', /()(=>)/, /()(\{)/, /()(\})/, /()(\[)/, /()(\])/],
|
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' %>
|