当前位置:  开发笔记 > 编程语言 > 正文

Active Admin,Devise和Pundit(Pundit :: PolicyScopingNotPerformedError)

如何解决《ActiveAdmin,Devise和Pundit(Pundit::PolicyScopingNotPerformedError)》经验,为你挑选了1个好方法。

我有一个现有的Rails应用程序,用于Devise验证User模型并Pundit根据Enrollment链接User到我的Company模型的模型进行身份验证.双方UserCompany都在公寓宝石的公共架构.我不怀疑公寓是问题的一部分,但我想我会提到它.

我使用AdminUser类添加了Active Admin - 我希望将我的管理员用户与应用用户分开.

如果我尝试访问/admin/admin/dashboard获得:

Pundit::PolicyScopingNotPerformedError at /admin/users
Pundit::PolicyScopingNotPerformedError

如果我尝试像/admin/usersPundit 这样的模型似乎忽略了active_admin策略并转到主应用程序策略.在我的情况下,应用程序会抛出异常,因为它是在等一个EnrollmentVS的AdminUser.

如果我禁用:

##/config/initializers/active_admin.rb
  config.authorization_adapter = ActiveAdmin::PunditAdapter

##/controllers/application_controller
  after_action :verify_authorized, except: [:landing, :dashboard], unless: :devise_controller?
  after_action :verify_policy_scoped, only: [:index]

一切正常,但后来我在主应用程序中失去了Pundit等.

这是我的代码的要点:

https://gist.github.com/jasper502/4b2f1b8b6f21a26c64a5

以下是可以在此问题上找到的相关帖子:

https://gorails.com/forum/using-pundit-with-activeadmin

如何让Active Admin在登录后与Pundit合作

我想在这篇文章中一起禁用Pundit(你可以用Devise和Active Admin禁用Pundit吗?)但是这样做会很好.

UPDATE

我已经解决了,但我仍然不知道这是否应该开箱即用,我有一些奇怪的问题导致所有这一切.要点已更新.

我最终使用:

https://viget.com/extend/8-insanely-useful-activeadmin-customizations

还有一点:

有条件的before_action/before_filter的文档

以下是一点答案.我在过滤器中使用过强制AA来强制AA对AA内的资源和集合进行授权.接下来是添加策略范围,但我的大脑现在伤得太厉害了.

我还必须添加另一个过滤器来绕过仪表板上的身份验证,因为它是无头的.到目前为止似乎工作.

更新2

嗯......我想我说的太快了.这一切都只有在我作为常规登录时才有效User- 如果我退出,它会再次崩溃.



1> Jesse Sanfor..:

@ dan-tappin我想你已经根据你的评论找到了类似的解决方案,但这里是我最后添加到我的每个AA模型注册中的内容:

#app/admin/user.rb
ActiveAdmin.register User do
  controller do
    before_filter :authorize_index, only: :index
    def authorize_index
      policy_scope(User)
    end

    before_filter :authorize_show_edit_destroy, only: [:show, :edit, :destroy]
    def authorize_show_edit_destroy
      authorize resource
    end
  end
end

基本上,这利用了使用普通rails before_filter语法在控制器范围内执行的能力,以便仅使用:来限制执行.然后因为before_filter发生在inherrited_resources过滤器之后,我们可以访问"资源",我们可以像对待任何模型实例一样对其进行授权.请参阅:https://github.com/activeadmin/activeadmin/issues/1108#issuecomment-14711733

首先需要策略范围的原因是因为普通的pundit安装需要application_controller.rb中的以下内容

#app/controllers/application_controller.rb:
class ApplicationController < ActionController::Base
  # Prevent CSRF attacks by raising an exception.
  # For APIs, you may want to use :null_session instead.
  include Pundit
  protect_from_forgery with: :exception

  #before_action :authenticate_is_admin!

  after_action :verify_authorized, except: [:index, :dashboard], unless: :devise_controller?
  after_action :verify_policy_scoped, only: :index, unless: :devise_controller?

  rescue_from Pundit::NotAuthorizedError, with: :user_not_authorized

  private
  def authenticate_admin!
    redirect_to new_user_session_path unless current_user.admin?
  end

  private
  def pundit_user
    current_user
  end

  private
  def user_not_authorized
    flash[:error] = "You are not authorized to perform this action."
    redirect_to(request.referrer || new_user_session_path)
  end
end

它期望对策略范围的调用是所有索引操作的模型.仪表板控制器默认呈现索引操作,因此需要执行此before_filter hack.


谢谢你.而不是admin/{resource} .rb中的第一个`before_filter`,你可以修改ApplicationController:`after_action:verify_policy_scoped,only :: index,除非:: devise_or_pundit_controller?```def devise_or_pundit_controller?devise_controller?|| self.class.name.match(/ ^ Admin /)end`
推荐阅读
凹凸曼00威威_694
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有