1
votes

I am learning to use Pundit for authorization. But the way I see it is authorization for resources not pages. I want a user to be redirected to a unauthorized page if he/she is not authorized to visit the page using pundit.

For e.g.

class OnlyAdminCanVisitController < ApplicationController
    before_filter :admin_authenticate

Stops a non-admin role user.

Also, I want to take care of made up scenarios like following(Considering there are 4 roles as Admin,Manager,Employee,Outsider. The design below is obiviously bad)

    class AdminManagerCanVisitController < ApplicationController
        before_filter :admin_or_manager_authenticate

    class AdminEmployeeCanVisitController < ApplicationController
        before_filter :admin_or_employee_authenticate

   class AdminOutsiderCanVisitController < ApplicationController
        before_filter :admin_or_outsider_authenticate

    class AdminManagerEmployeeCanVisitController < ApplicationController
        before_filter :admin_or_manager_employee_authenticate

I have 4 roles and would like to write pundit policies for these controllers which allows any combination of authorizations.

Let me know if pundit is designed to tackle this issue.

Thanks

1

1 Answers

5
votes

There is not much difference between pages and resources actually. So you can solve your problem by rescuing a denied Authorization from your application_controller.rb :

class ApplicationController < ActionController::Base
  include Pundit

  rescue_from Pundit::NotAuthorizedError, with: :user_not_authorized

  protected

  def admin_authenticate
    authorize current_user, :admin?
  end

  private

  def user_not_authorized(exception)
    # Redirect to whatever page you want if not authorized
  end
end

You then need to define your policy. I generally create an admin? method in application_policy.rb (https://github.com/elabs/pundit#policies) so it is spread on my other policies as well :

class ApplicationPolicy
  def admin?
    # Logic to ensure the user is an admin
  end
end

class UserPolicy < ApplicationPolicy
end

Then in your other controllers, just do as you did :

class OnlyAdminCanVisitController < ApplicationController
  before_action :admin_authenticate
end