lib/pundit.rb
# frozen_string_literal: true
require "active_support"
require "pundit/version"
require "pundit/policy_finder"
require "pundit/authorization"
require "pundit/context"
require "pundit/cache_store/null_store"
require "pundit/cache_store/legacy_store"
# @api private
# To avoid name clashes with common Error naming when mixing in Pundit,
# keep it here with compact class style definition.
class Pundit::Error < StandardError; end # rubocop:disable Style/ClassAndModuleChildren
# @api public
module Pundit
# @api private
# @deprecated See {Pundit::PolicyFinder}
SUFFIX = Pundit::PolicyFinder::SUFFIX
# @api private
# @private
module Generators; end
# Error that will be raised when authorization has failed
class NotAuthorizedError < Error
attr_reader :query, :record, :policy
def initialize(options = {})
if options.is_a? String
message = options
else
@query = options[:query]
@record = options[:record]
@policy = options[:policy]
message = options.fetch(:message) do
record_name = record.is_a?(Class) ? record.to_s : "this #{record.class}"
"not allowed to #{policy.class}##{query} #{record_name}"
end
end
super(message)
end
end
# Error that will be raised if a policy or policy scope constructor is not called correctly.
class InvalidConstructorError < Error; end
# Error that will be raised if a controller action has not called the
# `authorize` or `skip_authorization` methods.
class AuthorizationNotPerformedError < Error; end
# Error that will be raised if a controller action has not called the
# `policy_scope` or `skip_policy_scope` methods.
class PolicyScopingNotPerformedError < AuthorizationNotPerformedError; end
# Error that will be raised if a policy or policy scope is not defined.
class NotDefinedError < Error; end
def self.included(base)
location = caller_locations(1, 1).first
warn <<~WARNING
'include Pundit' is deprecated. Please use 'include Pundit::Authorization' instead.
(called from #{location.label} at #{location.path}:#{location.lineno})
WARNING
base.include Authorization
end
class << self
# @see Pundit::Context#authorize
def authorize(user, record, query, policy_class: nil, cache: nil)
context = if cache
policy_cache = CacheStore::LegacyStore.new(cache)
Context.new(user: user, policy_cache: policy_cache)
else
Context.new(user: user)
end
context.authorize(record, query: query, policy_class: policy_class)
end
# @see Pundit::Context#policy_scope
def policy_scope(user, *args, **kwargs, &block)
Context.new(user: user).policy_scope(*args, **kwargs, &block)
end
# @see Pundit::Context#policy_scope!
def policy_scope!(user, *args, **kwargs, &block)
Context.new(user: user).policy_scope!(*args, **kwargs, &block)
end
# @see Pundit::Context#policy
def policy(user, *args, **kwargs, &block)
Context.new(user: user).policy(*args, **kwargs, &block)
end
# @see Pundit::Context#policy!
def policy!(user, *args, **kwargs, &block)
Context.new(user: user).policy!(*args, **kwargs, &block)
end
end
# @api private
module Helper
def policy_scope(scope)
pundit_policy_scope(scope)
end
end
end