英文:
cancancan get all dynamic permissions
问题
我正在编写一个API,需要向API用户公开所有可用的权限,包括ID和其他信息。
我有以下的结构:
class User < ApplicationRecord
has_many :permissions, dependent: :destroy
end
class Permission < ApplicationRecord
belongs_to :user, dependent: :destroy
end
我有一个名为Ability的类:
class Ability
include CanCan::Ability
def initialize(user)
user_permissions(user)
dynamic_permissions(user)
end
def user_permissions(user)
can :manage, :dashboard if user.admin?
end
def dynamic_permissions(user)
user.permissions.each do |permission|
#...
next branch_permissions(permission) if permission.subject_class == 'branch'
end
end
def branch_permissions(permission)
can permission.action.to_sym, Branch, id: permission.allowed_ids
end
在控制器中,我想要实现所有权限 => can
和 cannot
对于该用户可能的方式。我已经检查了文档,并找到了#permissions。但这不适用于我对分支(dynamic permissions)的动态权限。
因此,我期望以cancancan的方式完成以下操作,提供伪代码:
Ability.new(User.find(params[:id]).dynamic_permissions =>
# {:can=>{:manage=>{"dashboard"=>[]}, :read=>{"Branch"=>['id1', 'id2']}, :index=>{"Branch"=>['id1', 'id2']}, :show=>{"Branch"=>['id1', 'id2']}}, :cannot=>{}}
当前的#permissions
cancancan方法只返回硬编码到ability文件的静态权限,缺少所有动态评估。
{:can=>{:manage=>{"dashboard"=>[]}, :read=>{"Branch"=>[]}, :index=>{"Branch"=>[]}, :show=>{"Branch"=>[]}}, :cannot=>{}}
我知道我可以修改并编写自定义方法来获取所有这些内容,但我想知道实现这一目标的通用方法是什么。
英文:
I'm writing API where I need to expose all available permissions with ids and other info to an api user.
I have the following structure
class User < ApplicationRecord
has_many :permissions, dependent: :destroy
end
class Permission < ApplicationRecord
belongs_to :user, dependent: :destroy
end
and I have ability
class Ability
include CanCan::Ability
def initialize(user)
user_permissions(user)
dynamic_permissions(user)
end
def user_permissions(user)
can :manage, :dashboard if user.admin?
end
def dynamic_permissions(user)
user.permissions.each do |permission|
#...
next branch_permissions(permission) if permission.subject_class == 'branch'
end
end
def branch_permissions(permission)
can permission.action.to_sym, Branch, id: permission.allowed_ids
end
and in controller I want to achieve all permissions => can
and cannot
possible for that user. I have checked docs already and found #permissions. But that doesn't work for dynamic permissions that I have for branch
So I expect the following to be done in cancancan way, providing pseudo-code
Ability.new(User.find(params[:id]).dynamic_permissions =>
# {:can=>{:manage=>{"dashboard"=>[]}, :read=>{"Branch"=>['id1', 'id2']}, :index=>{"Branch"=>['id1', 'id2']}, :show=>{"Branch"=>['id1', 'id2']}}, :cannot=>{}}
Current #permissions
cancancan method returns only static permissions that are hardcoded to ability file missing all dynamic evaluation.
{:can=>{:manage=>{"dashboard"=>[]}, :read=>{"Branch"=>[]}, :index=>{"Branch"=>[]}, :show=>{"Branch"=>[]}}, :cannot=>{}}
I know I can modify and write custom method that will fetch all of that, but I'm wondering what is accepted approach achieving this.
答案1
得分: 0
ok,这实际上很简单。阅读源代码有助于。
def branch_permissions(permission)
can permission.action.to_sym, Branch, id: permission.allowed_ids.map(&:to_sym)
end
这个方法 parse_attributes_from_extra_args 会将符号视为内部状态的属性,然后在权限中显示为我所期望的。您可以将这些符号序列化为字符串。
# Ability.new(User.find(params[:id]).permissions
=> {:can=>{:manage=>{"dashboard"=>[]}, :read=>{"Branch"=>[:id1, :id2]}, :index=>{"Branch"=>['id1', 'id2']}, :show=>{"Branch"=>[:id1, :id2]}}, :cannot=>{}}
英文:
ok, it was actually simple. Reading sources helped.
def branch_permissions(permission)
can permission.action.to_sym, Branch, id: permission.allowed_ids
end
this code should be changed to
def branch_permissions(permission)
can permission.action.to_sym, Branch, id: permission.allowed_ids.map(&:to_sym)
end
This method parse_attributes_from_extra_args will treat symbols as attributes for internal state, and then in permissions will show this as I expected. You can serialize those symbols to string then
# Ability.new(User.find(params[:id]).permissions
=> {:can=>{:manage=>{"dashboard"=>[]}, :read=>{"Branch"=>[:id1, :id2]}, :index=>{"Branch"=>['id1', 'id2']}, :show=>{"Branch"=>[:id1', :id2]}}, :cannot=>{}}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论