关于使用命名空间获得 Rails 5 和 Pundit 授权的问题。

对于 Pundit,我想在 Controller 中使用 policy_scope([:admin, @car],它将使用位于以下位置的 Pundit 策略文件: app/policies/admin/car_policy.rb 。我在尝试 Pundit 使用此命名空间时遇到问题 - 没有命名空间,它工作正常。

应用程序正在运行:

  • Rails 5
  • 设计认证
  • Pundit 授权

  • 例如,我的命名空间用于 admins
  • 标准用户 > http://garage.me/cars
  • 管理员用户 > http://garage.me/admin/cars
  • route.rb 文件如下所示:
    # config/routes.rb
    
    devise_for :admins
    
    root: 'cars#index'
    resources :cars
    
    namespace :admin do
      root 'cars#index'
      resources :cars
    end
    

    我已经设置了 Pundit ApplicationPolicy 并让命名空间与 Pundit 的 authorize 方法一起使用:@record = record.is_a?(Array) ? record.last : record
    # app/policies/application_policy.rb
    
    class ApplicationPolicy
      attr_reader :user, :record
    
      def initialize(user, record)
        @user = user
        @record = record.is_a?(Array) ? record.last : record
      end
    
      def scope
        Pundit.policy_scope!(user, record.class)
      end
    
      class Scope
        attr_reader :user, :scope
    
        def initialize(user, scope)
          @user = user
          @scope = scope
        end
    
        def resolve
          scope
        end
      end
    end
    

    Admin::CarsController 这工作 authorize [:admin, @cars]
    class Admin::CarsController < Admin::BaseController
      def index
        @cars = Car.order(created_at: :desc)
        authorize [:admin, @cars]
      end
    
      def show
        @car = Car.find(params[:id])
        authorize [:admin, @car]
      end
    end
    

    但我想使用策略范围
    class Admin::CarPolicy < ApplicationPolicy
      class Scope < Scope
        def resolve
          if user?
            scope.all
          else
            scope.where(published: true)
          end
        end
      end
    
      def update?
        user.admin? or not post.published?
      end
    end
    

    Admin::CarsController
    class Admin::CarssController < Admin::BaseController
      def index
        # @cars = Car.order(created_at: :desc) without a policy scope
        @cars = policy_scope([:admin, @cars]) # With policy scope / doesn't work because of array.
        authorize [:admin, @cars]
      end
    
      def show
        # @car = Car.find(params[:id]) without a policy scope
        @car = policy_scope([:admin, @car]) # With policy scope / doesn't work because of array.
        authorize [:admin, @car]
      end
    end
    

    我收到一个错误,因为 Pundit 没有在寻找 Admin::CarPolicy 。我认为这是因为它是一个数组。

    我想在 Controller 中我可以做类似 policy_scope(Admin::Car) 的事情,但这不起作用:)。

    任何助手都非常感谢。

    更新

    我在 Pundit Github 问题页面上找到了这个:https://github.com/elabs/pundit/pull/391

    这修复了 policy_scope 的命名空间处理,这正是我想要的。

    它更新 policy_scope! 中的 Pudit gem -> lib/pundit.rb 方法。

    从:
    def policy_scope!(user, scope)
      PolicyFinder.new(scope).scope!.new(user, scope).resolve
    end
    

    至:
    def policy_scope!(user, scope)
      model = scope.is_a?(Array) ? scope.last : scope
      PolicyFinder.new(scope).scope!.new(user, model).resolve
    end
    

    我的问题是,如何在我的 Rails 应用程序中使用它?是叫重载还是猴子补丁?

    我想在 pundit.rb 目录中添加一个 config/initializer 并使用 module_eval 但不确定如何执行此操作,因为 policy_scope! 位于 module Punditclass << self 内。

    我认为这会起作用,但它没有 - 假设这是因为 policy_scope! 位于 class << self 内。
    Pundit::module_eval do
      def policy_scope!(user, scope)
        model = scope.is_a?(Array) ? scope.last : scope
        PolicyFinder.new(scope).scope!.new(user, model).resolve
      end
    end
    

    最佳答案

    Medir 在 Pundit Github 问题页面上发布了解决方案。

    只需将您的 application_policy.rb 更改为:

    class ApplicationPolicy
      index? show?....
    
      class Scope
        attr_reader :user, :scope
    
        def initialize(user, scope)
          @user = user
          # @scope = scope
          @scope = scope.is_a?(Array) ? scope.last : scope #This fixes the problem
        end
    
        def resolve
          scope
        end
      end
    end
    

    然后您可以使用:
    policy_scope([:admin, @cars])
    

    关于ruby-on-rails - 在 Rails 5 上使用命名空间获得 Pundit 授权,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/42454424/

    10-13 05:29