Class: Pundit::Context

Inherits:
Object
  • Object
show all
Defined in:
lib/pundit/context.rb

Overview

Context is intended to be created once per request and user, and it is then used to perform authorization checks throughout the request.

Examples:

Using Sinatra

helpers do
  def current_user = ...

  def pundit
    @pundit ||= Pundit::Context.new(user: current_user)
  end
end

get "/posts/:id" do |id|
  pundit.authorize(Post.find(id), query: :show?)
end
route do |r|
  context = Pundit::Context.new(user:)

  r.get "posts", Integer do |id|
    context.authorize(Post.find(id), query: :show?)
  end
end

Since:

  • v2.3.2

Instance Attribute Summary collapse

Policies collapse

Scopes collapse

Instance Method Summary collapse

Constructor Details

#initialize(user:, policy_cache: CacheStore::NullStore.instance) ⇒ Context

Returns a new instance of Context.

Parameters:

  • user

    later passed to policies and scopes

  • policy_cache (#fetch) (defaults to: CacheStore::NullStore.instance)

    cache store for policies (see e.g. Pundit::CacheStore::NullStore)

See Also:

  • Authorization#pundit

Since:

  • v2.3.2



35
36
37
38
# File 'lib/pundit/context.rb', line 35

def initialize(user:, policy_cache: CacheStore::NullStore.instance)
  @user = user
  @policy_cache = policy_cache
end

Instance Attribute Details

#policy_cacheObject (readonly)

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

See Also:

Since:

  • v2.3.2



48
49
50
# File 'lib/pundit/context.rb', line 48

def policy_cache
  @policy_cache
end

#userObject (readonly)

See Also:

Since:

  • v2.3.2



43
44
45
# File 'lib/pundit/context.rb', line 43

def user
  @user
end

Instance Method Details

#authorize(possibly_namespaced_record, query:, policy_class:) ⇒ 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:

  • 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)

    the policy class we want to force use of

Returns:

  • (Object)

    Always returns the passed object record

Raises:

Since:

  • v2.3.2



62
63
64
65
66
67
68
69
70
71
72
73
# File 'lib/pundit/context.rb', line 62

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) ⇒ Object?

Retrieves the policy for the given record.

Parameters:

  • record (Object)

    the object we’re retrieving the policy for

Returns:

  • (Object, nil)

    instance of policy class with query methods

Raises:

See Also:

Since:

  • v2.3.2



82
83
84
# File 'lib/pundit/context.rb', line 82

def policy(record)
  cached_find(record, &:policy)
end

#policy!(record) ⇒ Object

Retrieves the policy for the given record, or raises if not found.

Parameters:

  • record (Object)

    the object we’re retrieving the policy for

Returns:

  • (Object)

    instance of policy class with query methods

Raises:

See Also:

Since:

  • v2.3.2



94
95
96
# File 'lib/pundit/context.rb', line 94

def policy!(record)
  cached_find(record, &:policy!)
end

#policy_scope(scope) ⇒ Scope{#resolve}?

Retrieves the policy scope for the given record.

Parameters:

  • 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:

Since:

  • v2.3.2



109
110
111
112
113
114
115
116
117
118
119
120
# File 'lib/pundit/context.rb', line 109

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

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

Parameters:

  • 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:

Since:

  • v2.3.2



130
131
132
133
134
135
136
137
138
139
140
# File 'lib/pundit/context.rb', line 130

def policy_scope!(scope)
  policy_scope_class = policy_finder(scope).scope!

  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