lib/authority/controller.rb in authority-2.7.0 vs lib/authority/controller.rb in authority-2.8.0

- old
+ new

@@ -5,21 +5,34 @@ extend ActiveSupport::Concern include ActiveSupport::Rescuable unless defined?(Rails) def self.security_violation_callback Proc.new do |exception| - # Through the magic of ActiveSupport's `Proc#bind`, `ActionController::Base#rescue_from` + # Through the magic of `instance_exec` `ActionController::Base#rescue_from` # can call this proc and make `self` the actual controller instance self.send(Authority.configuration.security_violation_handler, exception) end end included do rescue_from(Authority::SecurityViolation, :with => Authority::Controller.security_violation_callback) class_attribute :authority_resource, :instance_reader => false end + attr_writer :authorization_performed + + def authorization_performed? + !!@authorization_performed + end + + def ensure_authorization_performed(options = {}) + return if authorization_performed? + return if options[:if] && !send(options[:if]) + return if options[:unless] && send(options[:unless]) + raise AuthorizationNotPerformed, "No authorization was performed for #{self.class.to_s}##{self.action_name}" + end + module ClassMethods # Sets up before_filter to ensure user is allowed to perform a given controller action # # @param [Class OR Symbol] resource_or_finder - class whose authorizer @@ -47,10 +60,17 @@ set multiple actions in one shot. Please update your controllers \ accordingly. (called from #{caller.first})".squeeze(' ') authority_actions(action_map) end + # Convenience wrapper for instance method + def ensure_authorization_performed(options = {}) + after_filter(options.slice(:only, :except)) do |controller_instance| + controller_instance.ensure_authorization_performed(options) + end + end + # The controller action to authority action map used for determining # which Rails actions map to which authority actions (ex: index to read) # # @return [Hash] A duplicated copy of the configured controller_action_map def authority_action_map @@ -72,11 +92,13 @@ # `action_name` comes from ActionController authority_action = self.class.authority_action_map[action_name.to_sym] if authority_action.nil? raise MissingAction.new("No authority action defined for #{action_name}") end + Authority.enforce(authority_action, authority_resource, authority_user, *options) + self.authorization_performed = true end # Renders a static file to minimize the chances of further errors. # # @param [Exception] error, an error that indicates the user tried to perform a forbidden action. @@ -110,9 +132,10 @@ # @return [Object] the user object returned from sending the user_method def authority_user send(Authority.configuration.user_method) end - class MissingAction < StandardError ; end - class MissingResource < StandardError ; end + class MissingAction < StandardError ; end + class MissingResource < StandardError ; end + class AuthorizationNotPerformed < StandardError ; end end end