如何为 Pundit 添加无所不能的用户级别
how to add an omnipotent user level to Pundit
我查看了文档并进行了一些搜索,但我没有看到全能用户(超级用户)级别的选项,也没有看到如何创建。
有没有人看到或创建了这样做的原因?我认为可以绑定到核心身份验证系统,但我不确定在哪里进行绑定。
非常感谢..
执行此操作的唯一方法是让您的授权检查 return 对于已指定 "super user." 的用户或角色是否为真,因此,它看起来像这样:
def update?
*normal authorization logic* or is_superuser?
end
def edit?
*normal authorization logic* or is_superuser?
end
#etc...
private
def is_superuser?
# configure how to determine who the super users are and return true/false
end
您可以在 ApplicationPolicy
中定义 is_superuser?
私有方法,假设您从 Application Policy 继承了 class 级别的策略;否则,您将需要在每个策略中定义它。
我找到了一个更简单的方法,通过使用 ApplicationPolicy 的继承。我为访问方法设置了别名,并在调用其中任何一个之前绑定了一个超级用户测试。如果用户是超级用户,我只是 return true。我在初始化时这样做,然后我需要将实例方法定义为别名。
ALIAS_PREFIX = '__original_'
def initialize(user, record)
@user = user
@record = record
[:index?,:show?,:create?,:new?, :update?, :edit?, :destroy?].each do |access_method|
alias_name = ALIAS_PREFIX+access_method.to_s
aliasing_original_method(access_method,alias_name)
self.class.send(:define_method, access_method) do |*args|
superuser? ? (return true) : send(alias_name, *args)
end
end
end
private
def superuser?
#whatever you want to define a super user
end
def aliasing_original_method(old_name, new_name)
self.class.send(:alias_method, new_name, old_name)
self.class.send(:private, new_name)
end
在 [AnyFile] 政策中我这样做:
def initialize(user, record)
super(user, record)
end
这将确保子策略中每个方法的真实 return。
[更新]
第一个解决方案有点混乱,我对 ruby(和截止日期)的了解不允许我进一步推进。不管怎样,我找到了另一种方法。因为我总是将用户的角色转换成套写形式,所以我在 ApplicationPolicy 中实现了一个 for_roles 方法。
def for_roles(*args,&block)
return true if superuser?
if args.include?(:all) || (@user.role_symbols & args).any?
block.call
else false
end
end
然后,在任何政策中,你可以做例如
for_roles(:client_admin,:technician) do
#any rule computation, DB request you want
end
#or
for_roles(:all) do
#any rule computation, DB request you want
end
我查看了文档并进行了一些搜索,但我没有看到全能用户(超级用户)级别的选项,也没有看到如何创建。
有没有人看到或创建了这样做的原因?我认为可以绑定到核心身份验证系统,但我不确定在哪里进行绑定。
非常感谢..
执行此操作的唯一方法是让您的授权检查 return 对于已指定 "super user." 的用户或角色是否为真,因此,它看起来像这样:
def update?
*normal authorization logic* or is_superuser?
end
def edit?
*normal authorization logic* or is_superuser?
end
#etc...
private
def is_superuser?
# configure how to determine who the super users are and return true/false
end
您可以在 ApplicationPolicy
中定义 is_superuser?
私有方法,假设您从 Application Policy 继承了 class 级别的策略;否则,您将需要在每个策略中定义它。
我找到了一个更简单的方法,通过使用 ApplicationPolicy 的继承。我为访问方法设置了别名,并在调用其中任何一个之前绑定了一个超级用户测试。如果用户是超级用户,我只是 return true。我在初始化时这样做,然后我需要将实例方法定义为别名。
ALIAS_PREFIX = '__original_'
def initialize(user, record)
@user = user
@record = record
[:index?,:show?,:create?,:new?, :update?, :edit?, :destroy?].each do |access_method|
alias_name = ALIAS_PREFIX+access_method.to_s
aliasing_original_method(access_method,alias_name)
self.class.send(:define_method, access_method) do |*args|
superuser? ? (return true) : send(alias_name, *args)
end
end
end
private
def superuser?
#whatever you want to define a super user
end
def aliasing_original_method(old_name, new_name)
self.class.send(:alias_method, new_name, old_name)
self.class.send(:private, new_name)
end
在 [AnyFile] 政策中我这样做:
def initialize(user, record)
super(user, record)
end
这将确保子策略中每个方法的真实 return。
[更新]
第一个解决方案有点混乱,我对 ruby(和截止日期)的了解不允许我进一步推进。不管怎样,我找到了另一种方法。因为我总是将用户的角色转换成套写形式,所以我在 ApplicationPolicy 中实现了一个 for_roles 方法。
def for_roles(*args,&block)
return true if superuser?
if args.include?(:all) || (@user.role_symbols & args).any?
block.call
else false
end
end
然后,在任何政策中,你可以做例如
for_roles(:client_admin,:technician) do
#any rule computation, DB request you want
end
#or
for_roles(:all) do
#any rule computation, DB request you want
end