我在使用 Rspec 测试 Pundit 策略范围时遇到了障碍。基本上,我试图测试范围内的返回值是否严格限于用户。因此,我循环遍历为用户返回的所有问题,并确保 id 等于用户。
这是绿色的,但是当它是非公民角色时它会失败,因为 Scope 调用仅返回一个 Issue 对象。这不是什么大问题,因为每个角色都有一个 .where() 的范围,但这是一种代码味道,我可能做错了一些事情。
我有一个执行该操作的 IssueController
class IssuePolicy < ApplicationPolicy
class Scope < Struct.new(:user, :scope)
def resolve
if user.role == 'citizen'
scope.where(:user_id => user.id)
else
scope
end
end
end
Run Code Online (Sandbox Code Playgroud)
为了在 rspec 中测试这一点,我必须这样做
require 'spec_helper'
describe IssuePolicy do
before(:each) do
@user = FactoryGirl.create(:user)
@issue = FactoryGirl.create(:issue)
@last_issue = FactoryGirl.create(:issue, user_id: User.last.id + 1)
end
context "for a citizen" do
before(:each) do
@user.update(role: 'citizen')
end
it "should only return their posts on …
Run Code Online (Sandbox Code Playgroud) 我正在通过rails composer(https://github.com/RailsApps/rails-composer)安装自定义应用程序.代码:https://github.com/gtheys/worke_rs
当我尝试运行rspec规范时,我得到了
› rake spec
/Users/gtheys/.rbenv/versions/2.1.2/bin/ruby -I/Users/gtheys/.rbenv/versions/2.1.2/lib/ruby/gems/2.1.0/gems/rspec-core-3.1.2/lib:/Users/gtheys/.rbenv/versions/2.1.2/lib/ruby/gems/2.1.0/gems/rspec-support-3.1.0/lib /Users/gtheys/.rbenv/versions/2.1.2/lib/ruby/gems/2.1.0/gems/rspec-core-3.1.2/exe/rspec --pattern spec/\*\*\{,/\*/\*\*\}/\*_spec.rb
/Users/gtheys/Code/worke_rs/spec/policies/user_policy_spec.rb:8:in `block in <top (required)>': undefined method `permissions' for RSpec::ExampleGroups::UserPolicy:Class (NoMethodError)
from /Users/gtheys/.rbenv/versions/2.1.2/lib/ruby/gems/2.1.0/gems/rspec-core-3.1.2/lib/rspec/core/example_group.rb:335:in `module_exec'
from /Users/gtheys/.rbenv/versions/2.1.2/lib/ruby/gems/2.1.0/gems/rspec-core-3.1.2/lib/rspec/core/example_group.rb:335:in `subclass'
from /Users/gtheys/.rbenv/versions/2.1.2/lib/ruby/gems/2.1.0/gems/rspec-core-3.1.2/lib/rspec/core/example_group.rb:229:in `block in define_example_group_method'
from /Users/gtheys/.rbenv/versions/2.1.2/lib/ruby/gems/2.1.0/gems/rspec-core-3.1.2/lib/rspec/core/dsl.rb:41:in `block in expose_example_group_alias'
from /Users/gtheys/.rbenv/versions/2.1.2/lib/ruby/gems/2.1.0/gems/rspec-core-3.1.2/lib/rspec/core/dsl.rb:79:in `block (2 levels) in expose_example_group_alias_globally'
from /Users/gtheys/Code/worke_rs/spec/policies/user_policy_spec.rb:1:in `<top (required)>'
from /Users/gtheys/.rbenv/versions/2.1.2/lib/ruby/gems/2.1.0/gems/activesupport-4.1.4/lib/active_support/dependencies.rb:241:in `load'
from /Users/gtheys/.rbenv/versions/2.1.2/lib/ruby/gems/2.1.0/gems/activesupport-4.1.4/lib/active_support/dependencies.rb:241:in `block in load'
from /Users/gtheys/.rbenv/versions/2.1.2/lib/ruby/gems/2.1.0/gems/activesupport-4.1.4/lib/active_support/dependencies.rb:232:in `load_dependency'
from /Users/gtheys/.rbenv/versions/2.1.2/lib/ruby/gems/2.1.0/gems/activesupport-4.1.4/lib/active_support/dependencies.rb:241:in `load'
from /Users/gtheys/.rbenv/versions/2.1.2/lib/ruby/gems/2.1.0/gems/rspec-core-3.1.2/lib/rspec/core/configuration.rb:1105:in `block in load_spec_files'
from /Users/gtheys/.rbenv/versions/2.1.2/lib/ruby/gems/2.1.0/gems/rspec-core-3.1.2/lib/rspec/core/configuration.rb:1105:in `each'
from /Users/gtheys/.rbenv/versions/2.1.2/lib/ruby/gems/2.1.0/gems/rspec-core-3.1.2/lib/rspec/core/configuration.rb:1105:in `load_spec_files'
from …
Run Code Online (Sandbox Code Playgroud) 我当前的Index操作如下所示:
def index
@proposals = current_user.proposals
end
Run Code Online (Sandbox Code Playgroud)
但我想这样做:
def index
@proposals = policy_scope(Proposal)
end
Run Code Online (Sandbox Code Playgroud)
我和has_and_belongs_to
之间有关系.User
Proposal
我开始Pundit
在我的应用程序中使用gem,但我不知道如何定义范围以便为普通用户提供上面显示的行为.
我想做这样的事情:
class Scope < Scope
def resolve
if user.admin?
scope.all
else
user.proposals # HOW DO I DO THIS WITH THE SCOPE?
end
end
end
Run Code Online (Sandbox Code Playgroud)
如何user.proposals
使用范围变量?我知道,如果我有一个has_many
和belongs_to
关系,我可以这样做:
else
scope.where(user_id: user.id) # RIGHT?
end
Run Code Online (Sandbox Code Playgroud)
但就HABTM而言,我不知道该怎么做.
有帮助吗?
ruby ruby-on-rails has-and-belongs-to-many ruby-on-rails-4 pundit
寻求一些帮助,我是 Rspec 和 pundit 的菜鸟,我正在按照一个示例来设置 pundit 并对其进行测试,但所有测试都失败了
NameError:
uninitialized constant UserPolicy
# ./spec/policies/user_policy_spec.rb:1:in `<top (required)>'
No examples found.
Run Code Online (Sandbox Code Playgroud)
需要一些帮助来找出原因,因为我不知道:(
使用:
配置/初始化器/pundit.rb
module PunditHelper
extend ActiveSupport::Concern
included do
include Pundit
rescue_from Pundit::NotAuthorizedError, with: :user_not_authorized
end
private
def user_not_authorized
flash[:alert] = "Access denied."
redirect_to (request.referrer || root_path)
end
end
ApplicationController.send :include, PunditHelper
Run Code Online (Sandbox Code Playgroud)
应用程序/策略/user_policy.rb
class UserPolicy
include ApplicationHelper
attr_reader :current_user, :model
def initialize(current_user, model)
@current_user = current_user …
Run Code Online (Sandbox Code Playgroud) 如何使用 Pundit Gem 检索所有用户策略和范围?我需要返回一个包含所有用户策略的 json 对象来检查前端 javascript 模板中的权限。
使用 CanCanCan gem,我可以做这样的事情:
class Ability
include CanCan::Ability
# ....
def to_list
rules.map do |rule|
object = { actions: rule.actions, subject: rule.subjects.map{ |s| s.is_a?(Symbol) ? s : s.name } }
object[:conditions] = rule.conditions unless rule.conditions.blank?
object[:inverted] = true unless rule.base_behavior
object
end
end
end
Run Code Online (Sandbox Code Playgroud)
可以用 Pundit 做同样的事情吗?
说我有一个属于用户模型的文档模型。用户has_many文档。DocumentPolicy可能包括此...
def edit?
document.user_id == user.id
end
Run Code Online (Sandbox Code Playgroud)
但是,如果...要编辑文档怎么办,您还必须能够编辑该文档的父级(用户)。然后,该策略可能如下所示。
def edit?
document.user_id == user.id &&
policy(user).edit?
end
Run Code Online (Sandbox Code Playgroud)
这导致错误:
undefined method `policy' for #<DocumentPolicy
Run Code Online (Sandbox Code Playgroud)
我很好奇是否有更好的方法可以做到这一点。我处理不正确吗?似乎其他人会想做的事情……所以,我希望能对其他人如何做到这一点有所了解。
我正在为我的学校作业授权,这是一个Reddit克隆.我刚刚向Pundit Gem介绍了用户角色的授权,即管理员,主持人,会员和访客.
我必须这样做:
管理员和版主应该看到所有帖子,会员应该只看到自己的帖子,而访客应该看不到帖子.
以普通用户身份登录,您只能看到自己创建的帖子.
application_policy.rb
class ApplicationPolicy
attr_reader :user, :record
def initialize(user, record)
@user = user
@record = record
end
def index?
false
end
def show?
scope.where(:id => record.id).exists?
end
def create?
# Checks if user exists and is logged in
user.present?
end
def new?
create?
end
def update?
# Checks if user is logged in, the owner or admin
user.present? && (record.user == user || user.admin?)
end
def edit?
update?
end
def destroy?
update?
end
def scope
record.class …
Run Code Online (Sandbox Code Playgroud) 我正在学习使用Pundit进行授权。但是我看到的是资源授权而不是页面授权。如果用户无权使用pundit访问该页面,我希望将其重定向到未经授权的页面。
例如
class OnlyAdminCanVisitController < ApplicationController
before_filter :admin_authenticate
Run Code Online (Sandbox Code Playgroud)
停止非管理员角色的用户。
另外,我想处理如下的组合方案(考虑到有Admin,Manager,Employee,Outsider等4个角色。下面的设计显然很糟糕)
class AdminManagerCanVisitController < ApplicationController
before_filter :admin_or_manager_authenticate
class AdminEmployeeCanVisitController < ApplicationController
before_filter :admin_or_employee_authenticate
class AdminOutsiderCanVisitController < ApplicationController
before_filter :admin_or_outsider_authenticate
class AdminManagerEmployeeCanVisitController < ApplicationController
before_filter :admin_or_manager_employee_authenticate
Run Code Online (Sandbox Code Playgroud)
我有4个角色,并且想为这些控制器编写允许任意组合授权的权威策略。
让我知道专家是否旨在解决这个问题。
谢谢
我有一个管理员视图,只有管理员可以查看。我正在使用专家来授权应用程序。
如何在不为每个管理控制器创建策略(并使用 authorize 装饰每个控制器)的情况下拒绝除 admin 之外的所有用户访问管理视图?如果有更短的解决方案。
谢谢
我使用 pundit 来处理我的 API 策略,我有一个项目显示,在某些情况下可以禁止用户,而在其他情况下只是受到限制。我所说的受限是指现在被禁止,但如果他付费,他就可以访问它。因此,我需要我的 API 使用特定代码 ( 402 Payment Required
) 进行响应,以便客户端可以邀请用户付款以解锁节目。
403
这是我当前的代码,它仅在 pundit 返回 false 时做出响应。
为了保持干燥和干净,最好在哪里实现返回403
OR 的条件?402
class Api::V1::ItemController < Api::V1::BaseController
def show
@item = Item.find(params[:id])
authorize @item
end
end
class ItemPolicy < ApplicationPolicy
def show?
return true if record.public?
# 403 will be generated, that's ok.
return false if !record.band.members.include?(user)
# If that condition is false I want to generate a 402 error at the end, not a 403.
user.premium?
end
end …
Run Code Online (Sandbox Code Playgroud)