Skip to content

GitLab

  • Menu
Projects Groups Snippets
    • Loading...
  • Help
    • Help
    • Support
    • Community forum
    • Submit feedback
    • Contribute to GitLab
  • Sign in
  • Z zobi
  • Project information
    • Project information
    • Activity
    • Labels
    • Members
  • Repository
    • Repository
    • Files
    • Commits
    • Branches
    • Tags
    • Contributors
    • Graph
    • Compare
  • Issues 2
    • Issues 2
    • List
    • Boards
    • Service Desk
    • Milestones
  • Merge requests 0
    • Merge requests 0
  • CI/CD
    • CI/CD
    • Pipelines
    • Jobs
    • Schedules
  • Deployments
    • Deployments
    • Environments
    • Releases
  • Monitor
    • Monitor
    • Incidents
  • Packages & Registries
    • Packages & Registries
    • Infrastructure Registry
  • Analytics
    • Analytics
    • CI/CD
    • Repository
    • Value Stream
  • Wiki
    • Wiki
  • Snippets
    • Snippets
  • Activity
  • Graph
  • Create a new issue
  • Jobs
  • Commits
  • Issue Boards
Collapse sidebar
  • Administrator
  • zobi
  • Issues
  • #3

Closed
Open
Created Apr 24, 2014 by Administrator@rootMaintainer

Pundit scopes + Inherited Resources

Created by: onemanstartup

Hi. I took your code and slightly modified, please look at this. I needed to use additional scope for collection after it was authorized, so only method i came up is path inherited resources. One problem is verification of policies don't work yet. What do you think about this approach? Can be it done differently or not at all? It seems odd for me to keep all scopes in policies.

module Accessable
  module ::InheritedResources
    module BaseHelpers
      def end_of_association_chain
        if association_chain.is_a?(ActiveRecord::Relation)
          apply_scopes_if_available(association_chain)
        elsif chain = association_chain.last
          if method_for_association_chain
            apply_scopes_if_available(chain.send(method_for_association_chain))
          else
            chain
          end
        else
          apply_scopes_if_available(resource_class)
        end
      end
    end
  end

  def self.included base
    base.send :include, Pundit
    base.class_eval do
      before_filter :authorize_resource

      def policy_scope scope
        Pundit.policy_scope!(current_user, scope)
      end

      def policy record
        Pundit.policy!(current_user, record)
      end
    end
  end

  protected

  # Authorize resource, see Policies.
  def authorize_resource
    case action_name
    when build_resources_authorized
      authorize controlled_access_build_resource
    when resources_authorized
      authorize controlled_access_resource
    when collection_authorized
      @association_chain = policy_scope(resource_class)
    else
      authorize resource_class
    end
  end

  private

  def controlled_access_collection c
    policy_scope c
  end

  def collection_authorized
    /index/
  end

  def build_resources_authorized
    /new|create/
  end

  def resources_authorized
    /edit|update|show|destroy/
  end

  def controlled_access_build_resource
    return build_resource if respond_to?(:build_resource)
    resource_class.new params[resource_class.to_s.to_sym]
  end

  def controlled_access_resource
    return resource if respond_to?(:resource)
    resource_class.find(params[:id])
  end
end

class ArticlesController < InheritedResources::Base
  include Accessable
  # after_action :verify_policy_scoped, :only => :index
  respond_to :html
  respond_to :rss, only: :index

  protected

  def collection
    @articles ||= end_of_association_chain.page(params[:page]).per(10).order(:id)
  end

  def build_resource_params
    [params.fetch(resource_instance_name, {}).permit(:title, :short_description, :body, :tag_list, :meta_description, :meta_keywords, :meta_title)]
  end
end
Assignee
Assign to
None
Milestone
None
Assign milestone
Time tracking