我正在尝试将inherited_resources和authority集成到我的Rails应用程序中。
我有点卡在最好的地方检查做一个基于资源的控制器动作的能力。下面的代码是权威的例子:
def edit
@llama = Llama.find(params[:id])
authorize_action_for(@llama) # Check to see if you're allowed to edit this llama. failure == SecurityViolation
end
def update
@llama = Llama.find(params[:id])
authorize_action_for(@llama) # Check to see if you're allowed to edit this llama.
@llama.attributes = params[:llama] # Don't save the attributes before authorizing
authorize_action_for(@llama) # Check again, to see if the changes are allowed.
if @llama.save?
# etc
end
因为在inherited_resources中,查找器是抽象出来的,所以我认为在这些抽象的查找器上也附加authorise_action_for
检查会很好。
注意权限在更新(可能是创建)的情况下的双重检查。
我依靠ActiveSupport::Concern
来简化模块。我将关注点存储在app
下名为concerns
的目录中。我把这个叫做inherited_resources_with_authority.rb
,你可能需要修改application.rb
中的autoload_paths
来从这个文件夹加载文件。
module InheritedResourcesWithAuthority
extend ActiveSupport::Concern
included do
inherit_resources
authorize_actions_for :resource_class
alias_method_chain :resource, :authority
alias_method_chain :build_resource, :authority
alias_method_chain :update_resource, :authority
end
protected
def resource_with_authority
resource_without_authority
authorize_action_for(get_resource_ivar)
end
def build_resource_with_authority
build_resource_without_authority
authorize_action_for(get_resource_ivar)
end
def update_resource_with_authority(object, attributes)
object.assign_attributes(*attributes)
authorize_action_for(object)
object.save
end
end
我们基本上链接了重要的inherited_resources
抽象方法,并在必要的地方插入我们的授权代码。最后一个是最棘手的,因为我们不能调用我们链接到的原始方法,所以我们必须在这里复制一些inherited_resources
的代码。
要使用此关注点,只需从控制器调用include InheritedResourcesWithAuthority
。
注意你不能在你的控制器上使用类继承方法来激活inherited_resources
,因为我们已经使用了另一种方法。
全文在此:https://coderwall.com/p/tp5sig
D