ruby-on-rails - 活跃的管理员、设计和权威 (Pundit::PolicyScopingNotPerformedError)

标签 ruby-on-rails devise activeadmin pundit

我有一个带有 Devise 的现有 Rails 应用程序验证 User型号和 Pundit针对 Enrollment 进行身份验证链接的型号User给我的Company模型。两个UserCompany位于公寓 gem 的公共(public)架构中。我不怀疑公寓是问题的一部分,但我想我会提到它。

我使用 AdminUser 类添加了 Active Admin - 我想让我的管理员用户与应用程序用户分开。

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

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

如果我尝试我的模型,例如 /admin/users Pundit 似乎忽略了 active_admin 策略并转到主要应用程序策略。在我的情况下,应用程序会抛出异常,因为它需要 EnrollmentAdminUser 相比.

如果我禁用:
##/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

How to get Active Admin to work with Pundit after login

我希望在这篇文章 ( Can you disable Pundit with Devise and Active Admin? ) 中一起禁用 Pundit,但如果能完成这项工作会很好。

更新

我有解决方法,但我仍然不知道这是否应该开箱即用,而且我有一些奇怪的问题导致了这一切。要点更新。

我最终使用:

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

还有一点:

Documentation for conditional before_action/before_filter

以及下面的一些答案。我强行插入一个过滤器以强制 AA 对 AA 内部的资源和集合调用授权。接下来是添加策略范围,但我的大脑现在太疼了。

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

更新 2

嗯……我觉得我说得太早了。这一切只有在我以常规 User 身份登录时才有效。 - 我如果我注销它会再次崩溃。

最佳答案

@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 语法在 Controller 范围内执行的能力,以限制使用 :only 的执行。然后因为 before_filter 发生在 inherrited_resources 过滤器之后,我们可以访问“资源”,我们可以像通常对任何模型实例一样授权它。见:https://github.com/activeadmin/activeadmin/issues/1108#issuecomment-14711733

首先需要策略范围的原因是因为正常的权威安装需要 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

它期望对所有索引操作的模型进行策略范围调用。仪表板 Controller 默认呈现索引操作,因此需要这个 before_filter hack。

关于ruby-on-rails - 活跃的管理员、设计和权威 (Pundit::PolicyScopingNotPerformedError),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34664645/

相关文章:

javascript - Rails 4 - 强制浏览器执行 javascript 响应而不是显示文本

mysql - 数据库级别的 Rails 舍入 float

ruby-on-rails - Rails 4 设计多用户模型 STI

ruby-on-rails - 设计和 AJAX : Can't verify CSRF token authenticity after sign in

ruby-on-rails - 从 Rake 任务登录 Devise

ruby-on-rails - Rails3 管理界面框架

ruby-on-rails - 由于 MimeMagic gem 不再存在,无法再在 Rails 上捆绑安装所有需要 Paperclip 的应用程序吗?

ruby-on-rails - 路由: resource_path or resource_url?

ruby-on-rails - friendly_id slug 在更新时没有改变

ruby-on-rails - 使用 Active Admin 和 Elastic Search 时 Ransack::Search 的未定义方法 `each'?