EzDevInfo.com

pundit

Minimal authorization through OO design and pure Ruby classes

Pundit authorizaton for files uploaded with Refile gem

How would I do authorization on files uploaded with Refile gem using Pundit? I have uploaded files which should be restricted to the user that uploaded them, but anyone with the url that Refile's attachment_url generates can access the file. Since Refile uses it's own Sinatra app, there's no rails controller for me to call Pundit's authorize method in.


Source: (StackOverflow)

Implementing scopes in Pundit

I am using the Pundit gem (with Devise and Rolify) to restrict access to information based on logged-in user roles.

At this time I have three roles for my User model defined: Admin, Client Admin, and Customer Admin.

A User belongs_to a Customer. Customer has_many Users.

I have successfully implemented a Pundit policy when indexing the Customer model. Admins and Client Admins can see all Customers. Customer Admin can only see their OWN record.

The problem lies when I am trying to restrict the show method of the Customer controller. Admins and Client Admins can see all Customers. However, the Customer Admin should only be able to see his own record. But as it stands the Customer Admin can input any id in the URL and see any Customer record.

I'm fuzzy on the scoping. It's my understanding that the Policy methods (i.e. index? and show?) are to restrict WHO can perform these actions and the Scoping methods restrict WHICH RECORDS can be obtained. I'm having trouble composing the correct scope for the above scenario.

Here's the Customer controller:

class CustomersController < ApplicationController
  before_action :set_customer, only: [:show, :edit, :update, :destroy]
  after_action :verify_authorized

  # GET /customers
  # GET /customers.json
  def index
    @customers = policy_scope(Customer)
    authorize Customer
  end

  # GET /customers/1
  # GET /customers/1.json
  def show
    authorize @customer
  end

  # GET /customers/new
  def new
    @customer = Customer.new
    authorize @customer
  end

  # GET /customers/1/edit
  def edit
    authorize @customer
  end

  # POST /customers
  # POST /customers.json
  def create
    @customer = Customer.new(customer_params)
    authorize @customer

    respond_to do |format|
      if @customer.save
        format.html { redirect_to @customer, notice: 'Customer was successfully created.' }
        format.json { render :show, status: :created, location: @customer }
      else
        format.html { render :new }
        format.json { render json: @customer.errors, status: :unprocessable_entity }
      end
    end
  end

  # PATCH/PUT /customers/1
  # PATCH/PUT /customers/1.json
  def update
    authorize @customer
    respond_to do |format|
      if @customer.update(customer_params)
        format.html { redirect_to @customer, notice: 'Customer was successfully updated.' }
        format.json { render :show, status: :ok, location: @customer }
      else
        format.html { render :edit }
        format.json { render json: @customer.errors, status: :unprocessable_entity }
      end
    end
  end

  # DELETE /customers/1
  # DELETE /customers/1.json
  def destroy
    authorize @customer
    @customer.destroy
    respond_to do |format|
      format.html { redirect_to customers_url, notice: 'Customer was successfully destroyed.' }
      format.json { head :no_content }
    end
  end

  private
    # Use callbacks to share common setup or constraints between actions.
    def set_customer
      @customer = Customer.find(params[:id])
    end

    # Never trust parameters from the scary internet, only allow the white list through.
    def customer_params
      params.require(:customer).permit(:name, :parent_customer_id, :customer_type, :active, :currency)
    end
end

And here is the Customer policy:

class CustomerPolicy < ApplicationPolicy

  def index?
    # Admins, ClientAdmins, and CustomerAdmins can index customers (see Scope class for filters)
    @user.has_role? :admin or @user.has_role? :client_admin or @user.has_role? :customer_admin
  end

  def show?
    # Admins, ClientAdmins, and CustomerAdmins can see any customer details
    @user.has_role? :admin or @user.has_role? :client_admin or @user.has_role? :customer_admin
  end

  def update?
    # Only Admins and ClientAdmins can update customer details
    @user.has_role? :admin  or @user.has_role? :client_admin
  end

  def destroy?
    @user.has_role? :admin or @user.has_role? :client_admin
  end

  class Scope < Struct.new(:user, :scope)
    def resolve
      if (user.has_role? :admin or user.has_role? :client_admin)
        # Admins and ClientAdmins can see all Customers
        scope.where(:parent_id => nil)
      elsif user.has_role? :customer_admin
        # Customer Admins can only see their own Customer
        scope.where(:id => user.customer) # THIS DOES NOT APPEAR TO GET INVOKED BY THE SHOW METHOD OF THE CONTROLLER
      end
    end    

    def show?
      # NOT SURE WHAT TO PUT IN HERE
    end
  end
end

Success!! Thanks to the headstart given to me by railscard, the trick was to modify the show? method in the Customer policy file like the following:

  def show?
    # Admins, ClientAdmins, and CustomerAdmins can see any customer details
    # Students cannot see customer details

    return true if user.has_role?(:admin) || user.has_role?(:client_admin)
    return true if user.customer_id == @record.id && user.has_role?(:customer_admin)
    false
  end

Note that I had to use the @record instance variable, as that's what the Application policy class uses to refer to the record being passed in by the authorize method.

Thanks!!


Source: (StackOverflow)

Advertisements

CanCan not fully supported in Rails 4 [closed]

It seems that Ryan Bates stopped developing CanCan. Rails 4 is nos fully supported. And, ready4rails4 says that it isn't work.

Should I replace CanCan for another authorization library?

Regards


Source: (StackOverflow)

Accessing session parameters in Pundit policy

It appears that Pundit policy does not access session parameters. As constructs does not reconize session as a valid variable or method. Is there any way to access session or other params?

class MyModelPolicy
  def create?
    @contructs = Construct.where(['id = ?', session[:construct_id]]).all
  end
end

Source: (StackOverflow)

Rails/Pundit ArgumentError

In an exercise, I'm trying to create authorization such that a user needs to be either the post's owner or the general administrator, on top of being present and logged-in to update a post. I am trying to implement a pundit policy (using Devise for authentication).

The PostController Class:

class PostsController < ApplicationController
  ...
  def edit
    @post = Post.find(params[:id])
    authorize @post
  end
  ...
end

The ApplicationPolicy Class:

class ApplicationPolicy
  attr_reader :user, :record
  def initialize(user, record)
    @user = user
    @record = record
  end
  ...
  def update?
    user.present? && (record.user == user || user.role?(:admin))
  end
  def edit?
    update?
  end
  def destroy?
    update?
  end
  ...
end

* The User model* :

  class User < ActiveRecord::Base
   # Include default devise modules. Others available are:
   # :confirmable, :lockable, :timeoutable and :omniauthable
   devise :database_authenticatable, :registerable,
          :recoverable, :rememberable, :trackable, :validatable, :confirmable
   has_many :posts
   def role?(base_role)
     role == base_role.to_s
   end
 end

I got stuck with the Argument Error: wrong number of arguments (2 for 1). My understanding is that the policy method is part of the Pundit module, and it initializes and returns a new policy object with the given record and current_user as the implicit user. Can someone help me shed a light into this issue?

ERROR MESSAGE:

Showing /home/vagrant/code/bloccit/app/views/posts/show.html.erb where line #3 raised:

<h1><%= @post.title %></h1>

 <% if policy(@post).edit? %> #This is the line where the error is raised.
 <%= link_to "Edit", edit_post_path(@post), class: 'btn btn-success' %>
<% end %>

wrong number of arguments (2 for 1)

Full error trace :

activerecord (4.0.10) lib/active_record/attribute_methods/query.rb:35:in `attribute?'
activemodel (4.0.10) lib/active_model/attribute_methods.rb:383:in `role?'
app/policies/application_policy.rb:26:in `update?'
app/policies/application_policy.rb:30:in `edit?'
app/views/posts/show.html.erb:3:in `_app_views_posts_show_html_erb__322214668_90107450'
actionpack (4.0.10) lib/action_view/template.rb:143:in `block in render'
activesupport (4.0.10) lib/active_support/notifications.rb:161:in `instrument'
actionpack (4.0.10) lib/action_view/template.rb:141:in `render'
actionpack (4.0.10) lib/action_view/renderer/template_renderer.rb:49:in `block (2 levels) in render_template'
actionpack (4.0.10) lib/action_view/renderer/abstract_renderer.rb:38:in `block in instrument'
activesupport (4.0.10) lib/active_support/notifications.rb:159:in `block in instrument'
activesupport (4.0.10) lib/active_support/notifications/instrumenter.rb:20:in `instrument'
activesupport (4.0.10) lib/active_support/notifications.rb:159:in `instrument'
actionpack (4.0.10) lib/action_view/renderer/abstract_renderer.rb:38:in `instrument'
actionpack (4.0.10) lib/action_view/renderer/template_renderer.rb:48:in `block in render_template'
actionpack (4.0.10) lib/action_view/renderer/template_renderer.rb:56:in `render_with_layout'
actionpack (4.0.10) lib/action_view/renderer/template_renderer.rb:47:in `render_template'
actionpack (4.0.10) lib/action_view/renderer/template_renderer.rb:17:in `render'
actionpack (4.0.10) lib/action_view/renderer/renderer.rb:42:in `render_template'
actionpack (4.0.10) lib/action_view/renderer/renderer.rb:23:in `render'
actionpack (4.0.10) lib/abstract_controller/rendering.rb:127:in `_render_template'
actionpack (4.0.10) lib/action_controller/metal/streaming.rb:219:in `_render_template'
actionpack (4.0.10) lib/abstract_controller/rendering.rb:120:in `render_to_body'
actionpack (4.0.10) lib/action_controller/metal/rendering.rb:33:in `render_to_body'
actionpack (4.0.10) lib/action_controller/metal/renderers.rb:26:in `render_to_body'
actionpack (4.0.10) lib/abstract_controller/rendering.rb:97:in `render'
actionpack (4.0.10) lib/action_controller/metal/rendering.rb:16:in `render'
actionpack (4.0.10) lib/action_controller/metal/instrumentation.rb:41:in `block (2 levels) in render'
activesupport (4.0.10) lib/active_support/core_ext/benchmark.rb:12:in `block in ms'
/home/vagrant/.rvm/rubies/ruby-2.0.0-p576/lib/ruby/2.0.0/benchmark.rb:296:in `realtime'
activesupport (4.0.10) lib/active_support/core_ext/benchmark.rb:12:in `ms'
actionpack (4.0.10) lib/action_controller/metal/instrumentation.rb:41:in `block in render'
actionpack (4.0.10) lib/action_controller/metal/instrumentation.rb:84:in `cleanup_view_runtime'
activerecord (4.0.10) lib/active_record/railties/controller_runtime.rb:25:in `cleanup_view_runtime'
actionpack (4.0.10) lib/action_controller/metal/instrumentation.rb:40:in `render'
actionpack (4.0.10) lib/action_controller/metal/implicit_render.rb:10:in `default_render'
actionpack (4.0.10) lib/action_controller/metal/implicit_render.rb:5:in `send_action'
actionpack (4.0.10) lib/abstract_controller/base.rb:189:in `process_action'
actionpack (4.0.10) lib/action_controller/metal/rendering.rb:10:in `process_action'
actionpack (4.0.10) lib/abstract_controller/callbacks.rb:18:in `block in process_action'
activesupport (4.0.10) lib/active_support/callbacks.rb:413:in `_run__423379461__process_action__callbacks'
activesupport (4.0.10) lib/active_support/callbacks.rb:80:in `run_callbacks'
actionpack (4.0.10) lib/abstract_controller/callbacks.rb:17:in `process_action'
actionpack (4.0.10) lib/action_controller/metal/rescue.rb:29:in `process_action'
actionpack (4.0.10) lib/action_controller/metal/instrumentation.rb:31:in `block in process_action'
activesupport (4.0.10) lib/active_support/notifications.rb:159:in `block in instrument'
activesupport (4.0.10) lib/active_support/notifications/instrumenter.rb:20:in `instrument'
activesupport (4.0.10) lib/active_support/notifications.rb:159:in `instrument'
actionpack (4.0.10) lib/action_controller/metal/instrumentation.rb:30:in `process_action'
actionpack (4.0.10) lib/action_controller/metal/params_wrapper.rb:250:in `process_action'
activerecord (4.0.10) lib/active_record/railties/controller_runtime.rb:18:in `process_action'
actionpack (4.0.10) lib/abstract_controller/base.rb:136:in `process'
actionpack (4.0.10) lib/abstract_controller/rendering.rb:44:in `process'
actionpack (4.0.10) lib/action_controller/metal.rb:195:in `dispatch'
actionpack (4.0.10) lib/action_controller/metal/rack_delegation.rb:13:in `dispatch'
actionpack (4.0.10) lib/action_controller/metal.rb:231:in `block in action'
actionpack (4.0.10) lib/action_dispatch/routing/route_set.rb:82:in `call'
actionpack (4.0.10) lib/action_dispatch/routing/route_set.rb:82:in `dispatch'
actionpack (4.0.10) lib/action_dispatch/routing/route_set.rb:50:in `call'
actionpack (4.0.10) lib/action_dispatch/journey/router.rb:71:in `block in call'
actionpack (4.0.10) lib/action_dispatch/journey/router.rb:59:in `each'
actionpack (4.0.10) lib/action_dispatch/journey/router.rb:59:in `call'
actionpack (4.0.10) lib/action_dispatch/routing/route_set.rb:676:in `call'
warden (1.2.3) lib/warden/manager.rb:35:in `block in call'
warden (1.2.3) lib/warden/manager.rb:34:in `catch'
warden (1.2.3) lib/warden/manager.rb:34:in `call'
rack (1.5.2) lib/rack/etag.rb:23:in `call'
rack (1.5.2) lib/rack/conditionalget.rb:25:in `call'
rack (1.5.2) lib/rack/head.rb:11:in `call'
actionpack (4.0.10) lib/action_dispatch/middleware/params_parser.rb:27:in `call'
actionpack (4.0.10) lib/action_dispatch/middleware/flash.rb:241:in `call'
rack (1.5.2) lib/rack/session/abstract/id.rb:225:in `context'
rack (1.5.2) lib/rack/session/abstract/id.rb:220:in `call'
actionpack (4.0.10) lib/action_dispatch/middleware/cookies.rb:486:in `call'
activerecord (4.0.10) lib/active_record/query_cache.rb:36:in `call'
activerecord (4.0.10) lib/active_record/connection_adapters/abstract/connection_pool.rb:626:in `call'
activerecord (4.0.10) lib/active_record/migration.rb:373:in `call'
actionpack (4.0.10) lib/action_dispatch/middleware/callbacks.rb:29:in `block in call'
activesupport (4.0.10) lib/active_support/callbacks.rb:373:in `_run__474745028__call__callbacks'
activesupport (4.0.10) lib/active_support/callbacks.rb:80:in `run_callbacks'
actionpack (4.0.10) lib/action_dispatch/middleware/callbacks.rb:27:in `call'
actionpack (4.0.10) lib/action_dispatch/middleware/reloader.rb:64:in `call'
actionpack (4.0.10) lib/action_dispatch/middleware/remote_ip.rb:76:in `call'
actionpack (4.0.10) lib/action_dispatch/middleware/debug_exceptions.rb:17:in `call'
actionpack (4.0.10) lib/action_dispatch/middleware/show_exceptions.rb:30:in `call'
railties (4.0.10) lib/rails/rack/logger.rb:38:in `call_app'
railties (4.0.10) lib/rails/rack/logger.rb:20:in `block in call'
activesupport (4.0.10) lib/active_support/tagged_logging.rb:68:in `block in tagged'
activesupport (4.0.10) lib/active_support/tagged_logging.rb:26:in `tagged'
activesupport (4.0.10) lib/active_support/tagged_logging.rb:68:in `tagged'
railties (4.0.10) lib/rails/rack/logger.rb:20:in `call'
actionpack (4.0.10) lib/action_dispatch/middleware/request_id.rb:21:in `call'
rack (1.5.2) lib/rack/methodoverride.rb:21:in `call'
rack (1.5.2) lib/rack/runtime.rb:17:in `call'
activesupport (4.0.10) lib/active_support/cache/strategy/local_cache.rb:83:in `call'
rack (1.5.2) lib/rack/lock.rb:17:in `call'
actionpack (4.0.10) lib/action_dispatch/middleware/static.rb:64:in `call'
rack (1.5.2) lib/rack/sendfile.rb:112:in `call'
railties (4.0.10) lib/rails/engine.rb:511:in `call'
railties (4.0.10) lib/rails/application.rb:97:in `call'
rack (1.5.2) lib/rack/lock.rb:17:in `call'
rack (1.5.2) lib/rack/content_length.rb:14:in `call'
rack (1.5.2) lib/rack/handler/webrick.rb:60:in `service'
/home/vagrant/.rvm/rubies/ruby-2.0.0-p576/lib/ruby/2.0.0/webrick/httpserver.rb:138:in `service'
/home/vagrant/.rvm/rubies/ruby-2.0.0-p576/lib/ruby/2.0.0/webrick/httpserver.rb:94:in `run'
/home/vagrant/.rvm/rubies/ruby-2.0.0-p576/lib/ruby/2.0.0/webrick/server.rb:295:in `block in start_thread'

Source: (StackOverflow)

Why are `scope`-oriented actions (particularly `index` actions) treated differently in Pundit?

I am writing with respect to https://github.com/elabs/pundit#scopes

I am under the impression that authorization should answer the question Are you allowed access to this resource?, i.e. a true/false answer. This is the case with all actions except index, which, according to Pundit's docs, should return different ActiveRecord::Relation's depending on who is asking. For example, an admin gets scope.all, while a regular user gets scope.where(:published => true).

app/policies/post_policy.rb

class Scope < Struct.new(:user, :scope)
  def resolve
    if user.admin?
      scope.all
    else
      scope.where(:published => true)
    end
  end
end

app/controllers/posts_controller.rb

def index
  @posts = policy_scope(Post)
end

My reservation is that this is a slippery slope, and soon I will be adding presentation to the scopes (e.g. scope.all.order('created_at ASC')) -- and it just feels weird doing so in an authorization policy.

Of course I could move that to the controller...

def index
    @post = policy_scope(post)
    if user.admin?
        @post = @post.order( 'created_at ASC' )
    end
end

...but is that the controller's job? And I don't think it would be right to add such a call to the view. So maybe it should be a model method?

What would you say are the pros/cons of doing the following instead?

app/controllers/posts_controller.rb

This keeps index just like the other methods, with one call to authorize, and one call to a model method.

def index
  authorize(Post)
  @posts = Post.index(current_user)
end

app/policies/post_policy.rb

This simply gives a true/false answer. Are you authorized? Yes or no.

def index?
    user.admin? || user.regular_user?
end

app/models/post.rb

And in the model we can get as fancy as we like.

def self.index(user)
  if user.admin?
    Post.all.order('created_at ASC')
  else
    Post.where(user_id: user.id)
  end
end

Thoughts?


Source: (StackOverflow)

Using Pundit with namespace

In my project, i have pretty common namespace "admin".

namespace :admin do
    resources :users, except: :show
end

I use Pundit gem to set proper authorization, but i found it difficult to use with controllers within namespace. my policies are organised as below

-policies
    -admin
        user_policy.rb
    application_policy.rb
    admin_policy.rb
    awesome_policy.rb

very similar to controllers.

However, when inside the controller i use "authorize" method i get nothing but an error, informing that app is "unable to find UserPolicy". My UserPolicy looks like this:

class Admin::UserPolicy < AdminPolicy
end

So what is the problem, what should I do to make Pundit see those policies inside namespace?


Source: (StackOverflow)

Authorizing an array of ID's with the Pundit gem

I have a multiple select box for a has_many association. The params come in as:

foo_ids: ["1", "2", "3"]

Using strong parameters, I do not permit this attribute because I would like to authorize it myself so people cannot just put whatever they want in it.

def update
  bar.foos = authorized_foos
  bar.update(baz_params)
  respond_with bar
end

private

  def authorized_foos
    foos = Foo.find(params[:baz][:foo_ids])
    foos.each do |foo|
      authorize foo, :manage?
    end
  end

This approach is going to force me to find all of the foos, loop through them, and authorize each one individually. Is there an easier way to manage has_many authorization, preferably with the Pundit gem?


Source: (StackOverflow)

How to automatically remove Active Admin form inputs with Pundit permitted attributes?

I have a Rails 4 app using Active Admin 1.0.0.pre1 in conjunction with pundit 0.3.0 for authorization which has worked flawlessly thus far, but I'm having trouble figuring out a good way automatically customize forms based on a user's role.

Given these models:

ActiveAdmin.register AdminUser do
  permit_params do
    Pundit.policy(current_admin_user, resource).permitted_attributes
  end

  form do |f|
    f.inputs "Admin Details" do
      f.input :role, as: :select, collection: [:manager, :admin]
      f.input :email, as: :email
      f.input :password
      f.input :password_confirmation
    end
    f.actions
  end
end

class AdminUserPolicy < ApplicationPolicy
  def permitted_attributes
    attributes = [:email, :password, :password_confirmation]
    attributes += [:role] if user.has_role? :super_admin
    attributes
  end
end

I'd like for the role input to be automatically removed from the form.

One option would be something along the lines of:

  permitted_attributes = Pundit.policy(current_admin_user, resource).permitted_attributes

  form do |f|
    f.inputs "Admin Details" do
      f.input :role if permitted_attributes.include? :role
      f.input :email
      f.input :password
      f.input :password_confirmation
    end
    f.actions
  end

but, that approach requires the developer to remember which attributes should be checked, seems prone to forgetfulness and isn't exactly DRY. Perhaps, I am going about this the wrong way? All suggestions welcome.


Source: (StackOverflow)

How to test Pundit policies with Minitest?

Gemfile

gem 'pundit', '~> 0.2.1'

app/controllers/application_controller.rb

class ApplicationController < ActionController::Base

  include Pundit
  ...

app/policies/application_policy.rb

class ApplicationPolicy < Struct.new(:user, :record)
  def index?  ; false;                              end
  def show?   ; scope.where(id: record.id).exists?; end
  def create? ; false;                              end
  def new?    ; create?;                            end
  def update? ; false;                              end
  def edit?   ; update?;                            end
  def destroy?; false;                              end
  def scope
    Pundit.policy_scope!(user, record.class)
  end
end

app/policies/book_policy.rb

class BookPolicy < ApplicationPolicy

  def create?
    record.new_record?
  end

  def new?
    create?      end

  def show?
    record.published? || user == record.user || user.is?(:admin)
  end

end

app/controllers/books_controller.rb

class BooksController < ApplicationController
  before_action :set_book, only: [:show, :edit, :update, :destroy]
  before_action :authenticate_user!, except: [:show]

  after_action :verify_authorized, except: :index
  after_action :verify_policy_scoped, only: :index

  # GET /books/1
  def show
    authorize(@book)
  end

  # GET /books/new
  def new
    @book = Book.new
    authorize(@book)
  end

  # POST /books
  def create
    @book = current_user.books.build(book_params)
    authorize(@book)

    if @book.save
      redirect_to @book, notice: 'Your book was successfully created.'
    else
      render action: 'new'
    end
  end

private
    def set_book
      @book = Book.find(params[:id])
    end

    def book_params
      params.require(:book).permit(:title, :description)
    end
end

test/factories/factories.rb

FactoryGirl.define do

  factory :user do
    sequence(:email) { |n| "email#{n}@x.com" }
    password  '12345678'
    password_confirmation  '12345678'
  end

  factory :book do
    title  'xx'
    user
  end

end

Source: (StackOverflow)

Pundit Headless Policy

I'm using pundit for access control in the admin section of my app. I have a dashboards controller that looks like this:

class Admin::DashboardsController < AdminController
  def index
    @total_revenue = Order.total_revenue
    authorize :dashboards, :index?
  end

  ...

end

and a policy that looks like this:

class DashboardPolicy < Struct.new(:user, :dashboard)
  def index?
    true
  end
end

When I try to access /admin/dashboards/ I get a Pundit::NotDefinedError, unable to find policy SymbolPolicy for dashboards

I've also tried namespacing the policy and got the same error.


Source: (StackOverflow)

Skip pundit scope on one controller

I want to skip the policy_scope requirement fro Pundit on one controller (home). I have tried this:

 class ApplicationController < ActionController::Base
  include Pundit
  after_action :verify_authorized, :except => :index, unless: :devise_controller?
  after_action :verify_policy_scoped, :only => :index, unless: controller.controller_name == "home"
 end

 class HomeController < ApplicationController
   def index
     redirect_to (new_user_session_path) unless user_signed_in?
     if user_signed_in?
       @user=current_user
     end
    end
  end

But I don't think the controller is defined yet or something? Any thoughts or suggestions?


Source: (StackOverflow)

How to use pundit scopes?

I have just made the switch to Pundit from CanCan. I am unsure of a couple things, and how Pundit is best used. For example.

If you have a resource that can have multiple parent objects, for instance lets say a Goal belongs to an student and instructor. Therefor, a student can have many goals and an instructor can have many goals. In a controller index action you might do:

if params[:student_id].present?
  @account = Student.find(params[:student_id])
  @goals = @account.goals
elsif params[:instructor_id].present?
  @account Instructor.find(params[:instructor_id])
  @goals = @account.goals
end

params are not usable inside policies, so the logic needs to be done here. I think. For what I can tell, if you skip the policy_scope you will get an unauthorized error when viewing the index page for goals.

Would you:

@goals = policy_scope(@account.goals)

OR

@goals = policy_scope(Goal.scoped).where( account_id: @account.id)

What happens when you throw a bunch of includes in the mix?

  @example = policy_scoped(@school.courses.includes(:account => :user, :teacher ))

Or when needed to order...is this correct? policy_scope(Issue.scoped).order("created_at desc")

When using scopes: What is :scope here? Is :scope an instance of the model being evaluated? I've tried accessing its attributes via :scope, but didn't work.

  class Scope < Struct.new(:user, :scope)

Source: (StackOverflow)

How to authorize ActiveAdmin resources with Pundit?

With CanCan, the load_and_authorize_resource helper method could be called in a global before_filter (in the application_controller). This would ensure that all ActiveAdmin controller actions too got authorized inherently.

But with Pundit, there is no such load_and_authorize_resource helper method. All Pundit docs and tutorials talk about calling authorize in every action. I am fine with calling authorize in every action. But in ActiveAdmin, the actions are not exposed by default. Am I supposed to open every action in every controller, and call authorize and then call super?

This seems wrong. So, could someone please tell me how to use Pundit to authorize the actions in ActiveAdmin?

Update:

I know about the Pundit authorization adapter. I am using the master branch of AA and I have configured AA to use the Pundit adapter, as described here. My question is: how do I make use of the adapter? By just setting config.authorization_adapter = ActiveAdmin::PunditAdapter, does it automatically invoke the authorization of every action in ActiveAdmin? I don't think so.

For example, in CanCan, even after setting config.authorization_adapter = ActiveAdmin::CanCanAdapter, you still have to set load_and_authorize_resource as a global before_filter for it to authorize all AA actions automatically.


Source: (StackOverflow)

Rails_admin: Should I have admin_user or user with admin role to manage users and admin panel

In my rails application website visitors can sign up and create content. It uses devise with user model and everything works well.

Now I want to use rails_admin for managing website resources and users etc and only people with administrative previllages should be able to access it.

Should I create a separate AdminUser model for admin panel access or use User model with role of admin, and use some authorization library to manage access.

If I user only one model then I want users to be redirected to admin panel after signin if user is admin and if not then I want user to be redirected to their profile. And which authorization library cancan or pundit will be more suitable in my case.

Thanks!


Source: (StackOverflow)