Skip to content

Commit

Permalink
Open cache strategy API up for including user in cache key
Browse files Browse the repository at this point in the history
... and possibly by extension also the `policy_class`.
  • Loading branch information
Burgestrand committed May 8, 2024
1 parent 8136c08 commit 6f04482
Show file tree
Hide file tree
Showing 4 changed files with 16 additions and 13 deletions.
2 changes: 1 addition & 1 deletion lib/pundit.rb
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
require "pundit/authorization"
require "pundit/context"
require "pundit/cache_store/null_store"
require "pundit/cache_store/hash_store"
require "pundit/cache_store/legacy_store"

# @api private
# To avoid name clashes with common Error naming when mixing in Pundit,
Expand Down
2 changes: 1 addition & 1 deletion lib/pundit/authorization.rb
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ module Authorization
def pundit
@pundit ||= Pundit::Context.new(
user: pundit_user,
policy_cache: Pundit::CacheStore::HashStore.new(policies)
policy_cache: Pundit::CacheStore::LegacyStore.new(policies)
)
end

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,14 @@
module Pundit
module CacheStore
# @api private
class HashStore
class LegacyStore
def initialize(hash = {})
@store = hash
end

def fetch(key)
@store[key] ||= yield
def fetch(user:, record:)
_ = user
@store[record] ||= yield
end
end
end
Expand Down
18 changes: 10 additions & 8 deletions lib/pundit/context.rb
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ def policy_scope!(scope)
# @raise [InvalidConstructorError] if the policy constructor called incorrectly
# @return [Object, nil] instance of policy class with query methods
def policy(record)
cached_policy(record, &:policy)
cached_find(record, &:policy)
end

# Retrieves the policy for the given record. Raises if not found.
Expand All @@ -96,20 +96,22 @@ def policy(record)
# @raise [InvalidConstructorError] if the policy constructor called incorrectly
# @return [Object] instance of policy class with query methods
def policy!(record)
cached_policy(record, &:policy!)
cached_find(record, &:policy!)
end

private

def cached_policy(record)
policy_cache.fetch(record) do
policy = yield policy_finder(record)
next unless policy
def cached_find(record)
policy_cache.fetch(user: user, record: record) do
klass = yield policy_finder(record)
next unless klass

model = pundit_model(record)

begin
policy.new(user, pundit_model(record))
klass.new(user, model)
rescue ArgumentError
raise InvalidConstructorError, "Invalid #<#{policy}> constructor is called"
raise InvalidConstructorError, "Invalid #<#{klass}> constructor is called"
end
end
end
Expand Down

0 comments on commit 6f04482

Please sign in to comment.