pundit icon indicating copy to clipboard operation
pundit copied to clipboard

First pass of Pundit::Context

Open Burgestrand opened this issue 1 year ago • 4 comments

See https://github.com/varvet/pundit/discussions/774 initial draft/rationale.

Caution

  • We're introducing a new method Pundit::Authorization#pundit. This is a namespace that is technically not ours, as this module included in controllers.

Hopefully this allows us to:

  • ... improve/fix existing functionality while staying backwards-compatible, by using dependency injection.
  • ... introduce new functionality without necessarily bloating controllers in Pundit::Authorization.
  • ... introduce an actual API for namespaces rather than overriding authorize/policy.

Burgestrand avatar Mar 01 '24 09:03 Burgestrand

Right now this change is backwards-compatible, possibly with the exception of our new pundit method. We could probably try this out in the wild, and then expand on the Pundit::Context API surface to introduce namespacing.

Burgestrand avatar Mar 07 '24 09:03 Burgestrand

Unless it's far too controversial I'd like to be able to remove the singleton methods on Pundit class in the future, and instead call them through a Pundit::Context. This is only if you're using Pundit outside of Rails.

For those who uses Pundit::Authorization (i.e. Rails), I'm thinking not much would change.

Burgestrand avatar Mar 07 '24 13:03 Burgestrand

@mattzollinhofer I've added some more commits to kinda hint at where I'm going at.

A change I haven't gotten to is passing more information to policy_cache.fetch, at least the user and maybe the passed-in policy_class. Once that's done it would be up to the cache strategy to turn those three into a cache key.

We would achieve backwards-compatibility by having a LegacyCache as default cache, and that cache simply ignores the user and policy_class passed. It would then work just as before.

By then implementing a new cache strategy that's opt-in we can get caching behaviour when passing policy_class. How that looks then later in the view I'm not sure. Maybe we would require passing the overridden policy from the view too, so that the cache key remains the same - otherwise it would be impossible to mix explicit policy_class with pundit-found policy.

Burgestrand avatar Mar 28 '24 09:03 Burgestrand

Another idea I had for this is some shortcuts to how one could override the default behavior in specific controllers, e.g:

class AdminControllerBase < ApplicationController
  def pundit
    @pundit ||= super.with_namespace(Admin)
  end
end

Burgestrand avatar Mar 28 '24 23:03 Burgestrand

Had a few people at RailsConf try this out in their apps, and nothing broke! Thank you all :)

Burgestrand avatar May 08 '24 16:05 Burgestrand