varvet / pundit

Minimal authorization through OO design and pure Ruby classes
MIT License
8.22k stars 625 forks source link

Is there a way to have a Pundit policy return `false` for all policies methods and override them all? #716

Closed jasper502 closed 2 years ago

jasper502 commented 2 years ago

Imagine a model is part of a tier on a subscription plan and then you can setup your views etc. accordingly vs having to add some sort of overriding call with an && in each method.

Burgestrand commented 2 years ago

Hi! I don't understand. Could you elaborate, or show some code?

jasper502 commented 2 years ago

So here is a generic policy for a Project model:

class ProjectPolicy < ApplicationPolicy

  def index?
    account_user.admin? || account_user.member?
  end

  def show?
    account_user.admin? || account_user.member?
  end

  def create?
    account_user.admin? || account_user.member?
  end

  def update?
    account_user.admin? || account_user.member?
  end

  def destroy?
    record.issues.none? && (account_user.admin? || account_user.member?)
  end

  class Scope < Scope
    def resolve
      scope.all
    end
  end
end

Let's say Projects are a paid feature of the app and if you have a free account the current_account can return current_account.allow_projects? = false. In this case all of these policies would return false. I know I can add && current_account.allow_projects? to each but looking to add a single rule that would override them all on a policy by policy basis. I can then sprinkle authorization all over my views and then easily 'turn off' projects with a flick of a switch.