使用CanCan的上下文感知授权 [英] Context aware authorization using CanCan
问题描述
我想使用CanCan处理我的权限。我的网站具有许多不同的权限级别,其中大多数是上下文相关的。例如,以下是我3个主要模型中的关系:
I want to use CanCan to handle my permissions. My site has many different permissions levels, and most of them are context aware. For instance, Here are the relations in my 3 main models:
class User < ActiveRecord::Base
has_many :league_relations
has_many :leagues, :through => :league_relations
end
class League < ActiveRecord::Base
has_many :league_relations
has_many :users, :through => :league_relations
end
class LeagueRelation < ActiveRecord::Base
belongs_to :user
belongs_to :league
end
注意,LeagueRelations是Leagues的嵌套资源。我想做的是允许用户修改联赛,并根据League_relation中存储的数据评估每个用户的授权。然后,我希望用户仅基于用户模型中存储的数据来修改联盟关系。
Note, LeagueRelations is a nested resource of Leagues. What I want to do is allow a user to modify leagues, and gauge each user's authorization based off of data stored in league_relation. I would then like a user to modify league relation, based only the data stored in the user model.
简而言之:我基本上希望将LeagueRelations用于授权League操作,以及用于授权LeagueRelations操作的用户。即League_relation.owner = true以删除联赛,但是user.owner吗?必须为true才能删除LeagueRelation。在联盟控制器内部时,如何基于League_Relation的属性进行授权,以及如何在其他模型上的其他控制器中对其他操作进行授权。如果您需要更多说明,请发表评论。
To be succinct: I basically want LeagueRelations to be used to authorize League actions, and Users to be used to authorize LeagueRelations actions. i.e. league_relation.owner = true to delete a League, but user.owner? must be true to delete a LeagueRelation. How can I authorize based on the attributes of league_relation when inside the league controller, and authorize other actions in other controllers on other models. Please leave a comment if you need more clarification.
谢谢。
推荐答案
<好的,我解决了这个问题。我的用例在CanCan README的开头被简要提及,但我错过了。您可以在app / models /中定义新的Ability类,这些类具有不同于current_user的其他参数。为此,您将以下内容放入控制器中:
Ok, I solved the problem. My use case is briefly mentioned in the beginning of the CanCan README and I missed it. You can define new Ability classes in app/models/ that take in a different parameter other than current_user. To do so, you put the following in your controller:
def current_ability
if params[:controller] == 'leagues'
@current_ability = LeagueAbility.new(current_user_league_relation)
elsif params[:controller] == 'league_relations'
@current_ability = LeagueRelationAbility.new(current_user_league_relation)
else
@current_ability = Ability.new(current_user)
end
end
现在您可以在app / models /中创建League_ability.rb。
Now you can create league_ability.rb in app/models/.
class LeagueAbility
include CanCan::Ability
def initialize(league_relation)
league_relation ||= LeagueRelation.new
if league_relation.owner?
can :manage, League, :id => league_relation.league_id
elsif league_relation.moderator?
can :manage, League, :id => league_relation.league_id
cannot [:delete, :destroy], League
else
can :read, League
can :create, League
end
end
end
要注意的一件事是,这取决于您的应用程序控制器在中调用方法一个儿童班。希望有帮助!
One thing to note is that this relies on your application controller calling a method in a child class. Hope that helps!
这篇关于使用CanCan的上下文感知授权的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!