Module: Pundit

Defined in:
lib/pundit.rb,
lib/pundit/rspec.rb,
lib/pundit/version.rb,
lib/pundit/authorization.rb,
lib/pundit/policy_finder.rb,
lib/generators/pundit/policy/policy_generator.rb,
lib/generators/pundit/install/install_generator.rb

Defined Under Namespace

Classes: AuthorizationNotPerformedError, InvalidConstructorError, NotAuthorizedError, NotDefinedError, PolicyFinder, PolicyScopingNotPerformedError

Constant Summary collapse

SUFFIX =
"Policy"

Class Method Summary collapse

Class Method Details

.authorize(user, possibly_namespaced_record, query, policy_class: nil, cache: {}) ⇒ Object

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.

Parameters:

  • user (Object)

    the user that initiated the action

  • possibly_namespaced_record (Object, Array)

    the object we're checking permissions of

  • query (Symbol, String)

    the predicate method to check on the policy (e.g. :show?)

  • policy_class (Class) (defaults to: nil)

    the policy class we want to force use of

  • cache (#[], #[]=) (defaults to: {})

    a Hash-like object to cache the found policy instance in

Returns:

  • (Object)

    Always returns the passed object record

Raises:



78
79
80
81
82
83
84
85
86
87
88
89
# File 'lib/pundit.rb', line 78

def authorize(user, possibly_namespaced_record, query, policy_class: nil, cache: {})
  record = pundit_model(possibly_namespaced_record)
  policy = if policy_class
    policy_class.new(user, record)
  else
    cache[possibly_namespaced_record] ||= policy!(user, possibly_namespaced_record)
  end

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

  record
end

.included(base) ⇒ Object



57
58
59
60
61
62
63
64
# File 'lib/pundit.rb', line 57

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

.policy(user, record) ⇒ Object?

Retrieves the policy for the given record.

Parameters:

  • user (Object)

    the user that initiated the action

  • record (Object)

    the object we're retrieving the policy for

Returns:

  • (Object, nil)

    instance of policy class with query methods

Raises:

See Also:



139
140
141
142
143
144
# File 'lib/pundit.rb', line 139

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!(user, record) ⇒ Object

Retrieves the policy for the given record.

Parameters:

  • user (Object)

    the user that initiated the action

  • record (Object)

    the object we're retrieving the policy for

Returns:

  • (Object)

    instance of policy class with query methods

Raises:

See Also:



154
155
156
157
158
159
# File 'lib/pundit.rb', line 154

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) ⇒ Scope{#resolve}?

Retrieves the policy scope for the given record.

Parameters:

  • user (Object)

    the user that initiated the action

  • scope (Object)

    the object we're retrieving the policy scope for

Returns:

  • (Scope{#resolve}, nil)

    instance of scope class which can resolve to a scope

Raises:

See Also:



98
99
100
101
102
103
104
105
106
107
108
109
# File 'lib/pundit.rb', line 98

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) ⇒ Scope{#resolve}

Retrieves the policy scope for the given record.

Parameters:

  • user (Object)

    the user that initiated the action

  • scope (Object)

    the object we're retrieving the policy scope for

Returns:

  • (Scope{#resolve})

    instance of scope class which can resolve to a scope

Raises:

See Also:



119
120
121
122
123
124
125
126
127
128
129
130
# File 'lib/pundit.rb', line 119

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