1

I've looked through the documentation and did some searching but i don't see an option for an omnipotent user (super user) level, or how one can be created.

Has anyone seen or created a why of doing this? im thinking it may be possible to tie into core authentication system but im not sure where to do the tie-in.

many thanks..

Tom T
  • 432
  • 1
  • 7
  • 21

2 Answers2

0

The only way to do this is to have your authorization checks return true for a user or role that has been designated a "super user." So, it would look like this:

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

You can define the is_superuser? private method in the ApplicationPolicy assuming that you inherit your class level policies from the Application Policy; otherwise, you will need to define it in each policy.

nikkon226
  • 998
  • 6
  • 11
  • Thanks nikkon266 .. i had a feeling this was the only way to do this. i was hoping that i missed a built in method in Pundit it's self. – Tom T Jan 21 '15 at 23:17
0

I've found a way a little DRYer, by using the inheritance of ApplicationPolicy. I alias access methods and I tie a superuser test before invoking any of them. If user is a super user, I simply return true. I do that at initialization before I need the instance method to be defined to be aliased.

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

And in [AnyFile]Policy I do:

def initialize(user, record)
 super(user, record)
end

This will ensure the true return for each method in sub-policy.

[UPDATE]

The first solution is a little messy, and my knowledge in ruby (and deadlines) doesn't permit me to push it farther. Anyway, I've found another way. As I was always switch-casing the roles of users, I've implemented in ApplicationPolicy a for_roles method.

def for_roles(*args,&block)
    return true if superuser?
    if args.include?(:all) || (@user.role_symbols & args).any?
      block.call
    else false
    end
end

Then, in any policy, you can do for example

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
hachpai
  • 196
  • 12