1

在我的 rails 应用程序中,我正在使用 Devise 对应用程序中的用户进行身份验证。它给了我变量,比如current_user.id哪个是当前登录用户的用户 ID。

在我的应用程序中,每个用户都是至少一个组的成员。任何用户都可以创建一个或多个 Trinket,并且可以将每个 Trinket 分配给他们的一个组。

所以,这是我的模型:

User has_many :memberships
User has_many :groups, :through => :memberships

Group has_many :memberships
Group has_many :users, :through => :memberships
Group has_many :trinkets

Trinket belongs_to :group

所以有我的模型!一切都很好!

当用户更新 Trinket 时,他们可以将该 Trinket 分配给他们的一个组。

但是,有一个安全漏洞!如果有人查看 Trinket/edit 或 Trinket/new 页面,复制 HTML 源代码,更改表单中的<SELECT><INPUT>标记的值,他们实际上可以将他们的 Trinket 提交到其他人的 GroupID。

我想在模型或控制器中添加一个验证,以便确认用户在将提交的值写入数据库之前确实有权使用它们。在这种情况下,我想查看此 Trinket 的 GroupID 是否是其中的 GroupID,User.find(current_user.id).groups但我无法弄清楚如何在 Trinket 模型中进行验证。

任何人都知道如何验证用户是否正在尝试将值分配给实际上有权分配它的东西?Devise 或其他 gem 是否有办法检查用户提交数据的关联?

当前的 Trinket 模型文件只有:

attr_accessible :trinketname, :group_id
validates_presence_of :trinketname

希望这是有道理的。帮助表示赞赏!:-)

版本:Rails 3.2.13、Ruby 1.9.3p392、Devise 2.2.4。我protect_from_forgery的 application_controller.rb 文件中有。

4

2 回答 2

1

您可以if在您的操作中添加一个声明。这可能是不准确的,但我希望它能够理解这一点:

 def create
   if trinket.group_id == current_user.group_id
     trinket.new(params[:trinket])
       if trinket.save
         redirect_to somewhere
       else 
         render :new
       end
   else      
    flash[:warn] "You're not allowed"
 end
于 2013-05-10T03:04:31.193 回答
1

你需要的是授权。

考虑使用众多可用的授权框架之一来实现您的目标。

CanCan瑞安·贝茨(Ryan Bates)的作品是经过最广泛的战斗测试的作品之一。

更新:能力可以:

class Ability
  include CanCan::Ability

  def initialize(user)
    can :manage, Trinket, group: { id: user.group_ids }
  end
end
于 2013-05-10T03:25:39.950 回答