标签: pundit

未定义的方法“授权”与 Pundit

我已经在我的 Rails 应用程序中安装了 gem Pundit,并仔细按照自述文件中的说明进行操作。

但是,当我在任何控制器中使用授权时,我收到错误消息“未定义的方法‘授权’为 .

此外,当我尝试在视图中使用“policy”时,我收到错误“未定义的方法‘policy’”。

就好像根本没有安装 Pundit 一样!

我在我的应用程序控制器中包含了 Pundit。

我有一个包含我所有策略的 ApplicationPolicy 文件,然后是从应用程序策略继承的每种记录类型的策略文件。

出于某种原因,我无法将我的任何代码粘贴到这个问题中,所以我希望我已经包含了足够的信息!

我很感激任何想法。

ruby-on-rails pundit

5
推荐指数
1
解决办法
3294
查看次数

登录后如何使Active Admin与Pundit一起使用

我已经向我的应用程序添加了配置pundit addapter授权

config.authorization_adapter = ActiveAdmin::PunditAdapter
Run Code Online (Sandbox Code Playgroud)

当我使用admin@example.com凭据登录时,出现此错误。

Pundit::NotDefinedError in Admin::Dashboard#index
unable to find policy AdminUserPolicy

Extracted source (around line #2):

insert_tag active_admin_application.view_factory["page"]
Run Code Online (Sandbox Code Playgroud)

所以我在我的policy / active_admin文件夹中创建了这些文件

adminuser_policy.rb

module ActiveAdmin
class AdminUserPolicy < ApplicationPolicy
class Scope < Struct.new(:user, :scope)
  def resolve
    scope
  end
end
def home?
true
end

def index?
true 
end
def show?
true 
end
def new?
true
end

def create?
 true
end

def update?
true 
end

  def destroy?
    true 
 end
end
Run Code Online (Sandbox Code Playgroud)

结束

page_policy.rb

module ActiveAdmin
class PagePolicy < ApplicationPolicy
  class Scope …
Run Code Online (Sandbox Code Playgroud)

ruby ruby-on-rails activeadmin ruby-on-rails-4 pundit

5
推荐指数
1
解决办法
3079
查看次数

如何使用Pundit允许的属性自动删除Active Admin表单输入?

我有一个Rails 4应用程序使用Active Admin 1.0.0.pre1和pundit 0.3.0进行授权,到目前为止一直运行良好,但我很难找到一个好的方法根据用户的角色自动定制表单.

鉴于这些模型:

ActiveAdmin.register AdminUser do
  permit_params do
    Pundit.policy(current_admin_user, resource).permitted_attributes
  end

  form do |f|
    f.inputs "Admin Details" do
      f.input :role, as: :select, collection: [:manager, :admin]
      f.input :email, as: :email
      f.input :password
      f.input :password_confirmation
    end
    f.actions
  end
end

class AdminUserPolicy < ApplicationPolicy
  def permitted_attributes
    attributes = [:email, :password, :password_confirmation]
    attributes += [:role] if user.has_role? :super_admin
    attributes
  end
end
Run Code Online (Sandbox Code Playgroud)

我想将role输入从表单中自动删除.

一种选择可能是:

  permitted_attributes = Pundit.policy(current_admin_user, resource).permitted_attributes

  form do |f|
    f.inputs "Admin Details" do
      f.input :role if permitted_attributes.include? :role …
Run Code Online (Sandbox Code Playgroud)

activeadmin ruby-on-rails-4 pundit

5
推荐指数
1
解决办法
1032
查看次数

使用rails 4中的pundit跳过对特定控制器的授权

我使用rails 4,设计用于身份验证,Pundit用于授权.我已经限制我的应用程序通过以下代码检查每个控制器上的授权.

class ApplicationController < ActionController::Base
  include Pundit
  after_action :verify_authorized
  #.....
end
Run Code Online (Sandbox Code Playgroud)

但是,我想在我的应用程序中跳过对两个特定控制器的授权(它们向公众开放,用户无需登录).如何在不删除ApplicationController中的verify_authorized的情况下实现它?

ruby-on-rails devise pundit

5
推荐指数
2
解决办法
5450
查看次数

安全地显示上传了paperclip gem的图像

默认情况下:paperclip gem存储公共目录中的所有附件.

出于安全原因,我不想将附件存储在公共目录中,因此我将它们保存uploads在应用程序根目录下的目录中:

class Post < ActiveRecord::Base
  belongs_to :user

  has_attached_file :some_image, path: ":rails_root/uploads/:attachment/:id/:style/:filename"
  do_not_validate_attachment_file_type :some_image
end
Run Code Online (Sandbox Code Playgroud)

我没有指定url选项,因为我不想为每个图像附件添加网址.如果指定了url:那么具有该url的任何人都可以访问该图像.这不安全.

user#show页面中:我想实际显示图像.如果我使用所有的回形针默认值,那么我可以这样做,因为图像在公共目录中,图像将有一个网址:

<p>
  <strong>Some image:</strong>
  <%= image_tag @post.some_image %>
</p>
Run Code Online (Sandbox Code Playgroud)

看来如果我将图像附件保存在公共目录之外并且没有指定URL(再次:这样做以保护图像),那么图像将不会在视图中呈现.

我知道如何通过pundit gem 在整个应用程序中进行授权.但是,当该图像可公开访问时,授权图像是无用的.因此,我尝试通过删除URL并将图像保存在公共目录之外来使图像无法公开访问,但随后图像不再在视图中呈现.

更新:我的问题归结为:我的图像保存在我的rails应用程序中.使用回形针:有没有办法在视图中安全地显示图像?换句话说:设置它使图像没有自己独立的URL(因为带有该URL的任何人都可以访问该图像,使该图像不安全).以下是安全显示图像的一些示例:

  • 示例#1:仅在用户登录时显示图像.(图像没有自己独立的URL,因此没有其他方法可以访问图像)
  • 示例#2:仅在用户与此图像关联时显示图像.(图像没有自己独立的网址,因此没有其他方法可以访问图像)

其他更新:我知道我可以安全地发送一个send_file允许用户下载图像的文件,但这不是我想要做的.我不希望用户下载图像.相反:我希望用户能够在网页上实际看到图像.我想在页面上安全地显示/渲染图像.使用send_file(据我所知)允许用户下载文件.它不会在页面上呈现图像.

ruby ruby-on-rails paperclip pundit

5
推荐指数
1
解决办法
828
查看次数

索引中的权威授权

我最近一直在阅读pundit gem的自述文件,并注意到他们从未在控制器中授权索引视图.(相反,他们使用范围).

他们给出了很好的推理,因为索引页面通常包含元素列表,通过控制生成的列表,您可以有效地控制页面上的数据.但是,偶尔也可能希望阻止访问索引页面本身.(而不是允许访问空白索引页.)我的问题是,执行此操作的正确方法是什么?

到目前为止,我已经提出了几种可能性,并且有以下几个类:

  • 一个模型 MyModel
  • 一个控制器 MyModelsController
  • 一项政策 MyModelPolicy

在我的控制器的索引方法中,解决此问题的推荐方法如下:

def index
  @my_models = policy_Scope(MyModel)
end
Run Code Online (Sandbox Code Playgroud)

然后,这将允许访问索引页面,但会将结果过滤到该用户可以看到的内容.(EG没有结果无法访问.)

但是为了阻止对索引页面本身的访问,我得到了两种不同的可能性:

def index
  @my_models = policy_Scope(MyModel)
  authorize @my_models
end
Run Code Online (Sandbox Code Playgroud)

要么

def index
  @my_models = policy_Scope(MyModel)
  authorize MyModel
end
Run Code Online (Sandbox Code Playgroud)

哪一个是正确的路径,还是有一个不同的替代选择?

ruby-on-rails pundit

5
推荐指数
2
解决办法
2410
查看次数

获得 Pundit 授权使用 Rails 5 上的命名空间

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

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

应用程序正在运行:

  • 轨道5
  • 设计用于身份验证
  • 专家授权

admins例如我的命名空间。

route.rb文件如下所示:

# config/routes.rb

devise_for :admins

root: 'cars#index'
resources :cars

namespace :admin do
  root 'cars#index'
  resources :cars
end
Run Code Online (Sandbox Code Playgroud)

我已经设置了 PunditApplicationPolicy并让命名空间与 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 = …
Run Code Online (Sandbox Code Playgroud)

ruby ruby-on-rails pundit ruby-on-rails-5

5
推荐指数
1
解决办法
1953
查看次数

Rails:使用 RSpec 进行测试授权 (Pundit)

我想使用 RSpec 彻底测试 Rails 应用程序授权设置 (Pundit)。

  1. Pundit 文档和其他值得尊敬的来源建议为 Pundit 策略类编写单元测试。这些测试是测试行为(好)还是实施细节(坏)?

  2. 如果我们实际上正在测试行为,那么如果我们最终从 Pundit 切换到另一个授权 gem 或滚动我们自己的授权,我们的测试难道不应该仍然通过吗?

  3. 假设对该authorize方法的调用被意外地从控制器操作中删除,使其开放供公共访问。权威人士的政策测试将不断通过。如果我们没有其他测试涵盖这一点,我们的测试套件可能都是绿色的,而我们的应用程序存在严重的安全漏洞。我们怎样才能避免这种情况呢?也许为 Pundit 控制器类编写单元测试,为控制器单独进行单元测试并模拟authorize控制器测试中的方法以确保调用它们?

编辑:再想一想,我对类的实现细节和公共 API 之间的差异做出了判断。调用特定的公共方法、传递特定的参数并期望特定的返回值是对任何类进行单元测试(和使用)的要求。请忽略第3项,因为我原来的论点是无效的。

  1. 我们可以编写使用不同用户角色登录的控制器或请求规范,调用控制器操作并断言是否授予或拒绝访问,而不是测试 Pundit 策略类。在这种方法中,即使我们切换到另一个授权 gem,测试也会继续通过。此外,如果authorize不调用该方法,它们也会失败。然而,这些将是集成测试,并且应该比单元测试 Pundit 策略类慢。这是否是测试授权设置的更好方法?

提前致谢。

testing tdd rspec ruby-on-rails pundit

5
推荐指数
1
解决办法
2748
查看次数

你如何邀请其他用户加入Clearance and Pundit的"团队"或"账户"或"项目"?

我有一个关于Clearance和Pundit的Rails应用程序,我正在尝试创建"团队","团队负责人"可以邀请其他用户加入他们的团队.我愿做类似的东西devise_invitable,但间隙.

以下是我的计划:

  1. 通过注册表单注册该站点的用户将自动分配一个唯一的团队ID,并成为"团队负责人".他们在表单上看不到此ID.(可以这样做的另一种方法是创建一个在注册时保存的唯一团队名称.)最好的方法是创建一个before_filter,用于在注册时分配团队ID和团队负责人吗?

  2. 团队ID或名称将是唯一的,每个用户只能属于一个团队.协会看起来像这样:

    球队

    has_many :users
    
    Run Code Online (Sandbox Code Playgroud)

    用户

    belongs_to :team
    
    Run Code Online (Sandbox Code Playgroud)
  3. 一旦这个"团队领导"创建帐户,此用户可以邀请其他用户通过填写用户#新形式类似于间隙注册表单(姓名,电子邮件等),这种形式会造成用户加入团队,将他们分配给团队领导团队.可以为它们分配一个随机密码以提供给Clearance,以便新用户通过验证.

  4. 一旦用户由团队负责人创建,他们将使用随机生成的密码保存在数据库中,并将Mailer发送给与标准清除密码重置邮件程序类似的受邀用户.它只是给他们一个通知,他们已被邀请加入团队,并提供重置密码然后登录的链接.它基本上是清除密码重置梅勒与不同的副本.

这是一个不错的策略还是有一个更广泛使用的模式,我缺少用ClearancePundit来解决这个问题?我从来没有用Rails做过这样的事情,所以我不知道这是否是一种使用Clearance的管道式磁带方式.

ruby ruby-on-rails user-accounts clearance pundit

5
推荐指数
1
解决办法
245
查看次数

有没有办法在请求规范中模拟 Pundit 策略授权?

我正在使用 Pundit 在我的 Rails 应用程序上进行授权,并且正在对我的请求进行单元测试。我已经成功测试了该策略,但现在我想验证我的请求是否正在使用该策略。我想以通用的方式做到这一点,我可以在任何请求规范中使用它(无论控制器、操作和策略如何)。老实说,在这一点上,我会遵循一种对所有请求通用的“期望任何策略都能获得授权”的说法。

对于索引操作(使用策略范围)很简单:

在请求描述中我说

RSpec.describe 'GET /companies', type: :request do
  include_context 'invokes policy scope'
end
Run Code Online (Sandbox Code Playgroud)

然后我将共享上下文定义为:

RSpec.shared_context 'invokes policy scope', shared_context: :metadata do
  before do
    expect(Pundit).to receive(:policy_scope!) do |user_context, relation|
      expect(user_context.user).to eq(user)
      expect(user_context.current_group).to eq(group)

      relation
    end
  end
end
Run Code Online (Sandbox Code Playgroud)

但我该如何对授权方法做同样的事情呢?我不知道哪个具体策略将接收它,也不知道哪个具体控制器将调用authorize.

我不明白为什么 pundit 不提供自定义匹配器来验证某个请求实际上正在调用给定的策略,或者“模拟”授权/未授权的场景,因此我测试我的请求是否返回正确的状态代码。

有任何想法吗?

rspec ruby-on-rails rspec-rails pundit

5
推荐指数
1
解决办法
2685
查看次数