I have an admin views where only the administrator is allowed to view. I am using pundit to authorize the application.
How do I deny all users but admin to the admin views without creating policies (and decorate each controller with authorize ) for each admin controllers? If there is a shorter solution.
Thanks
What you're trying to do violates the nature of MVC and is a pretty bad idea.
While you can authorize in the view:
# In views
<% if policy(:dashboard).show? %>
<%= link_to 'Dashboard', dashboard_path %>
<% end %>
Thats for authorizing chunks of the view not entire actions.
The reason for this is that authorization systems like pundit work by raising an exception which is caught in the controller to render the "error" page or redirect. An unauthorised action should also return a different HTTP response code. Doing this when the view has already started to render is to late in the response cycle and would cause a double render error as the server may already have started sending the response.
Instead you can create a headless policy:
class AdminPolicy < Struct.new(:user, :admin)
def admin?
user.admin?
end
end
And you can use it like so:
# app/controllers/concerns/administrated.rb
module Administrated
extends ActiveSupport::Concern
included do
before_action :authorize_admin
end
def authorize_admin
authorize(:admin, :admin?)
end
end
class ThingsController < ApplicationController
include Administrated
end