ruby-on-railsrubyactioncontroller

Does Rails come with a "not authorized" exception?


I am writing an application that uses plain old Ruby objects (POROs) to abstract authorization logic out of controllers.

Currently, I have a custom exception class called NotAuthorized that I rescue_from at the controller level, but I was curious to know: Does Rails 4 already come with an exception to indicate that an action was not authorized? Am I reinventing the wheel by implementing this exception?

Clarification: The raise AuthorizationException is not happening anywhere inside of a controller, it is happening inside of a completely decoupled PORO outside of the controller. The object has no knowledge of HTTP, routes or controllers.


Solution

  • Rails doesn't seem to map an exception to :unauthorized.

    The default mappings are defined in activerecord/lib/active_record/railtie.rb:

    config.action_dispatch.rescue_responses.merge!(
      'ActiveRecord::RecordNotFound'   => :not_found,
      'ActiveRecord::StaleObjectError' => :conflict,
      'ActiveRecord::RecordInvalid'    => :unprocessable_entity,
      'ActiveRecord::RecordNotSaved'   => :unprocessable_entity
    )
    

    and actionpack/lib/action_dispatch/middleware/exception_wrapper.rb:

    @@rescue_responses.merge!(
      'ActionController::RoutingError'             => :not_found,
      'AbstractController::ActionNotFound'         => :not_found,
      'ActionController::MethodNotAllowed'         => :method_not_allowed,
      'ActionController::UnknownHttpMethod'        => :method_not_allowed,
      'ActionController::NotImplemented'           => :not_implemented,
      'ActionController::UnknownFormat'            => :not_acceptable,
      'ActionController::InvalidAuthenticityToken' => :unprocessable_entity,
      'ActionDispatch::ParamsParser::ParseError'   => :bad_request,
      'ActionController::BadRequest'               => :bad_request,
      'ActionController::ParameterMissing'         => :bad_request
    )
    

    You could add a custom exception from within your application's configuration (or a custom Railtie):

    Your::Application.configure do
    
      config.action_dispatch.rescue_responses.merge!(
        'AuthorizationException' => :unauthorized
      )
    
      # ...
    
    end
    

    Or simply use rescue_from.