【问题标题】:pundit policies with namespaces具有命名空间的权威政策
【发布时间】:2014-07-16 19:05:03
【问题描述】:

我的应用程序中有问题模型。

app/models/question.rb

class Question < ActiveRecord::Base
  ...
end

我正在使用 'pundit' gem 进行授权。有两个控制器可以对问题进行一些更改:一个用于注册用户,一个用于管理员。

我正在尝试为控制器创建单独的策略。

app/controllers/questions_controller.rb

class QuestionsController < ApplicationController
   ...
end

app/policies/question_policy.rb

class QuestionPolicy < ApplicationPolicy
  ...
end

app/controllers/admin/questions_controller.rb

class Admin::QuestionsController < Admin::ApplicationController
  ...
end

app/policies/admin/question_policy.rb

class Admin::QuestionPolicy < Admin::ApplicationPolicy
  ...
end

当我尝试在 Admin::QuestionsController 中使用“授权”方法时,它使用 app/policies/question_policy.rb 类而不是来自管理文件夹。

Gem 的文档说这应该像我上面描述的那样工作 (https://github.com/elabs/pundit#namespaced-policies)。

有人可以帮我吗?

【问题讨论】:

    标签: ruby-on-rails-4 namespaces authorization pundit


    【解决方案1】:

    我试图为主应用程序和 ActiveAdmin 获取单独的策略,并通过创建一个自定义的 PunditAdapter 以在 config/initializers/active_admin.rb 中使用来获得一个可行的解决方案

    class NamespacedPunditAdapter < ActiveAdmin::PunditAdapter
      def get_policy(subject, user, resource)
        "ActiveAdmin::#{subject}Policy".constantize.new(user, resource)
      end
    
      def retrieve_policy(subject)
        case subject
        when nil then get_policy(subject, user, resource)
        when Class then get_policy(subject, user, subject.new)
        else
          if subject.class.to_s.split('::')[0] == 'ActiveAdmin'
            Pundit.policy!(user, subject)
          else
            get_policy(subject.class, user, subject)
          end
        end
      end
    
      def scope_collection(collection, _action = Auth::READ)
        return collection if collection.class != Class
        scope = "ActiveAdmin::#{collection}Policy::Scope".constantize
        scope.new(user, collection).resolve
      rescue Pundit::NotDefinedError => e
        if default_policy_class && default_policy_class.const_defined?(:Scope)
          default_policy_class::Scope.new(user, collection).resolve
        else
          raise e
        end
      end
    end
    

    另一种选择是使用ActiveSupport::Concern,正如here所指出的那样

    【讨论】:

      【解决方案2】:

      我在 github 源代码中创建了问题,并以这样的解释关闭:

      文档指的是当前未发布的主分支。您可以参考 Gemfile 中的 github 源代码来使用它。

      # Gemfile
      gem 'pundit', github: 'elabs/pundit'
      A bundle install later your code should work.
      
      You can switch back to a released version on Rubygems as soon as 0.3.0 is out. We're still     discussing a few namespacing issues, but it will come soon.
      

      【讨论】:

        【解决方案3】:

        如果有人仍在寻找此功能,我也需要它来在 ActiveAdmin 和面向最终用户的站点之间拆分授权。我为controller-based namespaced authorizations 构建了一个与 Pundit 兼容的 gem(您的策略将起作用),并且我计划遵循为 pundit 发布的任何功能。它还包括一个 ActiveAdmin 适配器。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2023-03-21
          • 1970-01-01
          • 1970-01-01
          • 2015-01-31
          • 1970-01-01
          • 1970-01-01
          • 2011-06-03
          相关资源
          最近更新 更多