Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

Authorization usage helper view

  • Loading branch information...
commit 0f9ecaeaaa2b28840591587cc29cf155309480a6 1 parent 2c200d2
@stffn authored
View
19 app/controllers/authorization_usages_controller.rb
@@ -0,0 +1,19 @@
+if Authorization::activate_authorization_rules_browser?
+
+require File.join(File.dirname(__FILE__), %w{.. .. lib maintenance})
+
+class AuthorizationUsagesController < ApplicationController
+ helper :authorization_rules
+ filter_access_to :all, :require => :read
+ # TODO set context?
+
+ def index
+ respond_to do |format|
+ format.html do
+ @auth_usages_by_controller = Authorization::Maintenance::Usage.usages_by_controller
+ end
+ end
+ end
+end
+
+end # activate_authorization_rules_browser?
View
35 app/helpers/authorization_rules_helper.rb
@@ -29,7 +29,8 @@ def link_to_graph (title, options = {})
def navigation
link_to("Rules", authorization_rules_path) << ' | ' <<
- link_to("Graphical view", graph_authorization_rules_path) #<< ' | ' <<
+ link_to("Graphical view", graph_authorization_rules_path) << ' | ' <<
+ link_to("Usages", authorization_usages_path) #<< ' | ' <<
# 'Edit | ' <<
# link_to("XACML export", :action => 'index', :format => 'xacml')
end
@@ -48,4 +49,36 @@ def role_color (role, fill = false)
def role_fill_color (role)
role_color(role, true)
end
+
+ def auth_usage_info_classes (auth_info)
+ classes = []
+ if auth_info[:controller_permissions]
+ if auth_info[:controller_permissions][0]
+ classes << "catch-all" if auth_info[:controller_permissions][0].actions.include?(:all)
+ classes << "default-privilege" unless auth_info[:controller_permissions][0].privilege
+ classes << "default-context" unless auth_info[:controller_permissions][0].context
+ classes << "no-attribute-check" unless auth_info[:controller_permissions][0].attribute_check
+ end
+ else
+ classes << "unprotected"
+ end
+ classes * " "
+ end
+
+ def auth_usage_info_title (auth_info)
+ titles = []
+ if auth_usage_info_classes(auth_info) =~ /unprotected/
+ titles << "No filter_access_to call protects this action"
+ end
+ if auth_usage_info_classes(auth_info) =~ /no-attribute-check/
+ titles << "Action is not protected with attribute check"
+ end
+ if auth_usage_info_classes(auth_info) =~ /default-privilege/
+ titles << "Privilege set automatically from action name by :all rule"
+ end
+ if auth_usage_info_classes(auth_info) =~ /default-context/
+ titles << "Context set automatically from controller name by filter_access_to call without :context option"
+ end
+ titles * ". "
+ end
end
View
33 app/views/authorization_usages/index.html.erb
@@ -0,0 +1,33 @@
+<h1>Authorization Usage</h1>
+<p>Filter rules in actions by controller:</p>
+<p><%= navigation %></p>
+<style type="text/css">
+ .auth-usages th { text-align: left; padding-top: 1em }
+ .auth-usages td { padding-right: 1em }
+ .auth-usages tr.unprotected { background: #FFA399 }
+ .auth-usages tr.no-attribute-check { background: #FFE599 }
+ /*.auth-usages tr.catch-all td.privilege,*/
+ .auth-usages tr.default-privilege td.privilege,
+ .auth-usages tr.default-context td.context { color: #888888 }
+</style>
+<table class="auth-usages">
+ <% @auth_usages_by_controller.keys.sort {|c1, c2| c1.name <=> c2.name}.each do |controller| %>
+ <% default_context = controller.controller_name.to_sym rescue nil %>
+ <tr>
+ <th colspan="3"><%= h controller.controller_name %></th>
+ </tr>
+ <% @auth_usages_by_controller[controller].keys.sort {|c1, c2| c1.to_s <=> c2.to_s}.each do |action| %>
+ <% auth_info = @auth_usages_by_controller[controller][action] %>
+ <% first_permission = auth_info[:controller_permissions] && auth_info[:controller_permissions][0] %>
+ <tr class="<%= auth_usage_info_classes(auth_info) %>" title="<%= auth_usage_info_title(auth_info) %>">
+ <td><%= h action %></td>
+ <% if first_permission %>
+ <td class="privilege"><%= h auth_info[:privilege] || action %></td>
+ <td class="context"><%= h auth_info[:context] || default_context %></td>
+ <% else %>
+ <td></td><td></td>
+ <% end %>
+ </tr>
+ <% end %>
+ <% end %>
+</table>
View
1  config/routes.rb
@@ -1,5 +1,6 @@
ActionController::Routing::Routes.draw do |map|
if Authorization::activate_authorization_rules_browser?
map.resources :authorization_rules, :only => :index, :collection => {:graph => :get}
+ map.resources :authorization_usages, :only => :index
end
end
View
2  lib/in_controller.rb
@@ -245,7 +245,7 @@ def filter_access_permissions? # :nodoc:
end
class ControllerPermission # :nodoc:
- attr_reader :actions, :privilege, :context
+ attr_reader :actions, :privilege, :context, :attribute_check
def initialize (actions, privilege, context, attribute_check = false,
load_object_model = nil, load_object_method = nil,
filter_block = nil)
View
2  lib/in_model.rb
@@ -87,7 +87,7 @@ def self.using_access_control (options = {})
:include_read => false
}.merge(options)
context = (options[:context] || self.table_name).to_sym
-
+
class_eval do
before_create do |object|
Authorization::Engine.instance.permit!(:create, :object => object,
View
56 lib/maintenance.rb
@@ -49,6 +49,62 @@ def with_user (user)
ensure
Authorization.current_user = prev_user
end
+
+ # Module for grouping usage-related helper methods
+ module Usage
+ # Delivers a hash of {ControllerClass => usage_info_hash},
+ # where usage_info_hash has the form of
+ def self.usages_by_controller
+ # load each application controller
+ begin
+ Dir.foreach(File.join(RAILS_ROOT, %w{app controllers})) do |entry|
+ if entry =~ /^\w+_controller\.rb$/
+ require File.join(RAILS_ROOT, %w{app controllers}, entry)
+ end
+ end
+ rescue Errno::ENOENT
+ end
+ controllers = []
+ ObjectSpace.each_object(Class) do |obj|
+ controllers << obj if obj.ancestors.include?(ActionController::Base) and
+ !%w{ActionController::Base ApplicationController}.include?(obj.name)
+ end
+
+ controllers.inject({}) do |memo, controller|
+ catchall_permissions = []
+ permission_by_action = {}
+ controller.all_filter_access_permissions.each do |controller_permissions|
+ catchall_permissions << controller_permissions if controller_permissions.actions.include?(:all)
+ controller_permissions.actions.reject {|action| action == :all}.each do |action|
+ permission_by_action[action] = controller_permissions
+ end
+ end
+
+ actions = controller.public_instance_methods(false) - controller.hidden_actions
+ memo[controller] = actions.inject({}) do |actions_memo, action|
+ action_sym = action.to_sym
+ actions_memo[action_sym] =
+ if permission_by_action[action_sym]
+ {
+ :privilege => permission_by_action[action_sym].privilege,
+ :context => permission_by_action[action_sym].context,
+ :controller_permissions => [permission_by_action[action_sym]]
+ }
+ elsif !catchall_permissions.empty?
+ {
+ :privilege => catchall_permissions[0].privilege,
+ :context => catchall_permissions[0].context,
+ :controller_permissions => catchall_permissions
+ }
+ else
+ {}
+ end
+ actions_memo
+ end
+ memo
+ end
+ end
+ end
end
# TestHelper provides assert methods and controller request methods which
View
15 test/maintenance_test.rb
@@ -0,0 +1,15 @@
+require File.join(File.dirname(__FILE__), 'test_helper.rb')
+require File.join(File.dirname(__FILE__), %w{.. lib maintenance})
+
+class MaintenanceTest < Test::Unit::TestCase
+
+ def test_usages_by_controllers
+ usage_test_controller = Class.new(ActionController::Base)
+ usage_test_controller.send(:define_method, :an_action) {}
+ usage_test_controller.filter_access_to :an_action
+
+ assert Authorization::Maintenance::Usage::usages_by_controller.
+ include?(usage_test_controller)
+ end
+
+end
Please sign in to comment.
Something went wrong with that request. Please try again.