I need a completely action based authorization mechanism. Yes, pundit
is action based authorization system.
I have some versions of APIs and I want the authorization mechanism support this structure. If you have different version of APIs for same models, in this case I have problem with pundit
.
app
|_ controllers
|_ social
|_ news
|_ blog
|_ api
|_ v1
|_ post_controller.rb
|_ v2
|_ post_controller.rb
I need an authorization mechanism which supports my structure.
Maybe there is proper gem for my requirement but I can’t find it and I wrote my authorization method and put it into ApplicationController
class.
def authorize?(record, query = nil)
controller_namespace = params[:controller]
.split('/')
.inject('') { |a, e| a + '::' + e.classify } klass = "#{controller_namespace}Policy".constantize
policy = klass.new(current_user, record)
query ||= "#{params[:action]}?" unless policy.public_send(query)
error = NotAuthorizedError.new(
"not allowed to #{query} this #{record}"
)
raise error
end true
end
And my post policy class in app/policies/blog/api/v1/
folder:
class Blog::Api::V1::PostPolicy < PolicyBase
attr_reader :user, :record def initialize(user, record)
@user = user
@record = record
end def destroy?
record.own_by? user
end
end
You can put your DRY codes in PolicyBase
class. Now you can use this policy like the following:
class Blog::Api::V1::PostController < ApplicationController
def destroy
post = ::Post.find_by! uid: params[:uid]
authorize? post
# do your job
end ...
end
Thank You.