class Pundit::Context

Attributes

policy_cache[R]

@api private

user[R]

Public Class Methods

new(user:, policy_cache: CacheStore::NullStore.instance) click to toggle source
# File lib/pundit/context.rb, line 5
def initialize(user:, policy_cache: CacheStore::NullStore.instance)
  @user = user
  @policy_cache = policy_cache
end

Public Instance Methods

authorize(possibly_namespaced_record, query:, policy_class:) click to toggle source

Retrieves the policy for the given record, initializing it with the record and user and finally throwing an error if the user is not authorized to perform the given action.

@param user [Object] the user that initiated the action @param possibly_namespaced_record [Object, Array] the object we’re checking permissions of @param query [Symbol, String] the predicate method to check on the policy (e.g. ‘:show?`) @param policy_class [Class] the policy class we want to force use of @raise [NotAuthorizedError] if the given query method returned false @return [Object] Always returns the passed object record

# File lib/pundit/context.rb, line 25
def authorize(possibly_namespaced_record, query:, policy_class:)
  record = pundit_model(possibly_namespaced_record)
  policy = if policy_class
    policy_class.new(user, record)
  else
    policy!(possibly_namespaced_record)
  end

  raise NotAuthorizedError, query: query, record: record, policy: policy unless policy.public_send(query)

  record
end
policy(record) click to toggle source

Retrieves the policy for the given record.

@see github.com/varvet/pundit#policies @param user [Object] the user that initiated the action @param record [Object] the object we’re retrieving the policy for @raise [InvalidConstructorError] if the policy constructor called incorrectly @return [Object, nil] instance of policy class with query methods

# File lib/pundit/context.rb, line 86
def policy(record)
  cached_find(record, &:policy)
end
policy!(record) click to toggle source

Retrieves the policy for the given record. Raises if not found.

@see github.com/varvet/pundit#policies @param user [Object] the user that initiated the action @param record [Object] the object we’re retrieving the policy for @raise [NotDefinedError] if the policy cannot be found @raise [InvalidConstructorError] if the policy constructor called incorrectly @return [Object] instance of policy class with query methods

# File lib/pundit/context.rb, line 98
def policy!(record)
  cached_find(record, &:policy!)
end
policy_scope(scope) click to toggle source

Retrieves the policy scope for the given record.

@see github.com/varvet/pundit#scopes @param user [Object] the user that initiated the action @param scope [Object] the object we’re retrieving the policy scope for @raise [InvalidConstructorError] if the policy constructor called incorrectly @return [Scope{#resolve}, nil] instance of scope class which can resolve to a scope

# File lib/pundit/context.rb, line 45
def policy_scope(scope)
  policy_scope_class = policy_finder(scope).scope
  return unless policy_scope_class

  begin
    policy_scope = policy_scope_class.new(user, pundit_model(scope))
  rescue ArgumentError
    raise InvalidConstructorError, "Invalid #<#{policy_scope_class}> constructor is called"
  end

  policy_scope.resolve
end
policy_scope!(scope) click to toggle source

Retrieves the policy scope for the given record. Raises if not found.

@see github.com/varvet/pundit#scopes @param user [Object] the user that initiated the action @param scope [Object] the object we’re retrieving the policy scope for @raise [NotDefinedError] if the policy scope cannot be found @raise [InvalidConstructorError] if the policy constructor called incorrectly @return [Scope{#resolve}] instance of scope class which can resolve to a scope

# File lib/pundit/context.rb, line 66
def policy_scope!(scope)
  policy_scope_class = policy_finder(scope).scope!
  return unless policy_scope_class

  begin
    policy_scope = policy_scope_class.new(user, pundit_model(scope))
  rescue ArgumentError
    raise InvalidConstructorError, "Invalid #<#{policy_scope_class}> constructor is called"
  end

  policy_scope.resolve
end

Private Instance Methods

cached_find(record) { |policy_finder(record)| ... } click to toggle source
# File lib/pundit/context.rb, line 104
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
      klass.new(user, model)
    rescue ArgumentError
      raise InvalidConstructorError, "Invalid #<#{klass}> constructor is called"
    end
  end
end
policy_finder(record) click to toggle source
# File lib/pundit/context.rb, line 119
def policy_finder(record)
  PolicyFinder.new(record)
end
pundit_model(record) click to toggle source
# File lib/pundit/context.rb, line 123
def pundit_model(record)
  record.is_a?(Array) ? record.last : record
end