module Pundit

@api public

Constants

SUFFIX
VERSION

Public Class Methods

authorize(user, record, query, policy_class: nil) 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 record [Object] 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.rb, line 69
def authorize(user, record, query, policy_class: nil)
  policy = policy_class ? policy_class.new(user, record) : policy!(user, record)

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

  record
end
policy(user, 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.rb, line 125
def policy(user, record)
  policy = PolicyFinder.new(record).policy
  policy.new(user, pundit_model(record)) if policy
rescue ArgumentError
  raise InvalidConstructorError, "Invalid #<#{policy}> constructor is called"
end
policy!(user, 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 [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.rb, line 140
def policy!(user, record)
  policy = PolicyFinder.new(record).policy!
  policy.new(user, pundit_model(record))
rescue ArgumentError
  raise InvalidConstructorError, "Invalid #<#{policy}> constructor is called"
end
policy_scope(user, 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.rb, line 84
def policy_scope(user, scope)
  policy_scope_class = PolicyFinder.new(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!(user, 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 [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.rb, line 105
def policy_scope!(user, scope)
  policy_scope_class = PolicyFinder.new(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 Class Methods

pundit_model(record) click to toggle source
# File lib/pundit.rb, line 149
def pundit_model(record)
  record.is_a?(Array) ? record.last : record
end

Protected Instance Methods

authorize(record, query = nil, policy_class: nil) click to toggle source

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

@param record [Object] the object we’re checking permissions of @param query [Symbol, String] the predicate method to check on the policy (e.g. ‘:show?`).

If omitted then this defaults to the Rails controller action name.

@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.rb, line 216
def authorize(record, query = nil, policy_class: nil)
  query ||= "#{action_name}?"

  @_pundit_policy_authorized = true

  policy = policy_class ? policy_class.new(pundit_user, record) : policy(record)

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

  record
end
permitted_attributes(record, action = action_name) click to toggle source

Retrieves a set of permitted attributes from the policy by instantiating the policy class for the given record and calling ‘permitted_attributes` on it, or `permitted_attributes_for_{action}` if `action` is defined. It then infers what key the record should have in the params hash and retrieves the permitted attributes from the params hash under that key.

@see github.com/varvet/pundit#strong-parameters @param record [Object] the object we’re retrieving permitted attributes for @param action [Symbol, String] the name of the action being performed on the record (e.g. ‘:update`).

If omitted then this defaults to the Rails controller action name.

@return [Hash{String => Object}] the permitted attributes

# File lib/pundit.rb, line 275
def permitted_attributes(record, action = action_name)
  policy = policy(record)
  method_name = if policy.respond_to?("permitted_attributes_for_#{action}")
    "permitted_attributes_for_#{action}"
  else
    "permitted_attributes"
  end
  pundit_params_for(record).permit(*policy.public_send(method_name))
end
policies() click to toggle source

Cache of policies. You should not rely on this method.

@api private rubocop:disable Naming/MemoizedInstanceVariableName

# File lib/pundit.rb, line 297
def policies
  @_pundit_policies ||= {}
end
policy(record) click to toggle source

Retrieves the policy for the given record.

@see github.com/varvet/pundit#policies @param record [Object] the object we’re retrieving the policy for @return [Object, nil] instance of policy class with query methods

# File lib/pundit.rb, line 260
def policy(record)
  policies[record] ||= Pundit.policy!(pundit_user, record)
end
policy_scope(scope, policy_scope_class: nil) click to toggle source

Retrieves the policy scope for the given record.

@see github.com/varvet/pundit#scopes @param scope [Object] the object we’re retrieving the policy scope for @param policy_scope_class [Class] the policy scope class we want to force use of @return [Scope{#resolve}, nil] instance of scope class which can resolve to a scope

# File lib/pundit.rb, line 250
def policy_scope(scope, policy_scope_class: nil)
  @_pundit_policy_scoped = true
  policy_scope_class ? policy_scope_class.new(pundit_user, scope).resolve : pundit_policy_scope(scope)
end
policy_scopes() click to toggle source

Cache of policy scope. You should not rely on this method.

@api private rubocop:disable Naming/MemoizedInstanceVariableName

# File lib/pundit.rb, line 306
def policy_scopes
  @_pundit_policy_scopes ||= {}
end
pundit_params_for(record) click to toggle source

Retrieves the params for the given record.

@param record [Object] the object we’re retrieving params for @return [ActionController::Parameters] the params

# File lib/pundit.rb, line 289
def pundit_params_for(record)
  params.require(PolicyFinder.new(record).param_key)
end
pundit_policy_authorized?() click to toggle source

@return [Boolean] whether authorization has been performed, i.e. whether

one {#authorize} or {#skip_authorization} has been called
# File lib/pundit.rb, line 174
def pundit_policy_authorized?
  !!@_pundit_policy_authorized
end
pundit_policy_scoped?() click to toggle source

@return [Boolean] whether policy scoping has been performed, i.e. whether

one {#policy_scope} or {#skip_policy_scope} has been called
# File lib/pundit.rb, line 180
def pundit_policy_scoped?
  !!@_pundit_policy_scoped
end
pundit_user() click to toggle source

Hook method which allows customizing which user is passed to policies and scopes initialized by {#authorize}, {#policy} and {#policy_scope}.

@see github.com/varvet/pundit#customize-pundit-user @return [Object] the user object to be used with pundit

# File lib/pundit.rb, line 316
def pundit_user
  current_user
end
skip_authorization() click to toggle source

Allow this action not to perform authorization.

@see github.com/varvet/pundit#ensuring-policies-and-scopes-are-used @return [void]

# File lib/pundit.rb, line 232
def skip_authorization
  @_pundit_policy_authorized = true
end
skip_policy_scope() click to toggle source

Allow this action not to perform policy scoping.

@see github.com/varvet/pundit#ensuring-policies-and-scopes-are-used @return [void]

# File lib/pundit.rb, line 240
def skip_policy_scope
  @_pundit_policy_scoped = true
end
verify_authorized() click to toggle source

Raises an error if authorization has not been performed, usually used as an ‘after_action` filter to prevent programmer error in forgetting to call {#authorize} or {#skip_authorization}.

@see github.com/varvet/pundit#ensuring-policies-and-scopes-are-used @raise [AuthorizationNotPerformedError] if authorization has not been performed @return [void]

# File lib/pundit.rb, line 191
def verify_authorized
  raise AuthorizationNotPerformedError, self.class unless pundit_policy_authorized?
end
verify_policy_scoped() click to toggle source

Raises an error if policy scoping has not been performed, usually used as an ‘after_action` filter to prevent programmer error in forgetting to call {#policy_scope} or {#skip_policy_scope} in index actions.

@see github.com/varvet/pundit#ensuring-policies-and-scopes-are-used @raise [AuthorizationNotPerformedError] if policy scoping has not been performed @return [void]

# File lib/pundit.rb, line 202
def verify_policy_scoped
  raise PolicyScopingNotPerformedError, self.class unless pundit_policy_scoped?
end

Private Instance Methods

pundit_policy_scope(scope) click to toggle source
# File lib/pundit.rb, line 322
def pundit_policy_scope(scope)
  policy_scopes[scope] ||= Pundit.policy_scope!(pundit_user, scope)
end