venuu / jsonapi-authorization

Authorization for JSONAPI::Resource
http://www.rubydoc.info/github/venuu/jsonapi-authorization
MIT License
132 stars 59 forks source link

Trying to add custom error type but having problem #45

Closed shunwen closed 7 years ago

shunwen commented 7 years ago

Hi, thanks for this awesome gem!

I got a problem when I tried to intercept pundit error with my custom jsonapi exception (so it could fall into the normal jsonapi error handling like other errors). I am not sure which part is wrong, could anyone help to take a look at my code, thanks!

I want to create my custom authorizer in lib/jsonapi/authorization/authorizer.rb to replace Pundit::NotAuthorizedError with my custom JSONAPI exception:

module JSONAPI
  module Authorization
    class Authorizer
      attr_reader :authorizer

      def initialize(context)
        @authorizer = JSONAPI::Authorization::DefaultPunditAuthorizer.new(context)
      end

      def method_missing(method, *args)
        @authorizer.send(method, *args)
      rescue Pundit::NotAuthorizedError => e
        action = e.query.delete('?')
        name = (e.record.try(:name) || e.record.class.name).downcase
        raise JSONAPI::Exceptions::NotAuthorizedError.new(action, name)
      end
    end
  end
end

And I defined my JSONAPI::Exceptions::NotAuthorizedError in lib/jsonapi/exceptions/not_authorized_error.rb like this:

module JSONAPI
  module Exceptions
    class NotAuthorizedError < Error
      attr_reader :action, :name

      def initialize(action, name, error_object_overrides = {})
        @action = action
        @name = name
        super(error_object_overrides)
      end

      def errors
        [create_error_object(code: JSONAPI::FORBIDDEN,
                             status: :forbidden,
                             title: 'Not authorized',
                             detail: "Not allowed to #{action} #{name}")]
      end
    end
  end
end

And finally set configuration in config/initializers/jsonapi_resources.rb :

JSONAPI.configure do |config|
  config.default_processor_klass = JSONAPI::Authorization::AuthorizingProcessor
end

JSONAPI::Authorization.configure do |config|
  config.authorizer = JSONAPI::Authorization::Authorizer
end

The problem is that when I test with not authorized action, this error shows up:

Internal Server Error: undefined method `create_error_object' for #<JSONAPI::Exceptions::NotAuthorizedError: {}> 
/MyRailsProject/lib/jsonapi/exceptions/not_authorized_error.rb:13:in `errors'
/.rbenv/versions/2.3.1/lib/ruby/gems/2.3.0/gems/jsonapi-resources-0.8.1/lib/jsonapi/processor.rb:63:in `rescue in process'
/.rbenv/versions/2.3.1/lib/ruby/gems/2.3.0/gems/jsonapi-resources-0.8.1/lib/jsonapi/processor.rb:56:in `process'
/.rbenv/versions/2.3.1/lib/ruby/gems/2.3.0/gems/jsonapi-resources-0.8.1/lib/jsonapi/operation.rb:16:in `process'

I am not sure if I missed anything such that my JSONAPI::Exceptions::NotAuthorizedError class doesn't inherit the create_error_object method from JSONAPI::Exceptions::Error. It would be greate if anyone has time to give me some hint. Thanks!

shunwen commented 7 years ago

Hi all, I found what's wrong. I am using jsonapi-resources 0.8.1, but the method I am trying to use is only on the master branch.