Class: CurrentScope::Current
- Inherits:
-
ActiveSupport::CurrentAttributes
- Object
- ActiveSupport::CurrentAttributes
- CurrentScope::Current
- Defined in:
- app/models/current_scope/current.rb
Overview
The ambient authorization context. Request- and job-scoped: Rails resets CurrentAttributes around every unit of execution, so the subject can never leak between requests, jobs, or test examples.
Two identities live here:
- user — the EFFECTIVE subject every permission check reads.
- actor — the REAL principal behind the request (the pretender's
`true_user`). It falls back to `user`, so attribution always
reads `actor` with no nil branch. They differ only while
impersonating: actor = the admin, user = the impersonated subject.
Instance Method Summary collapse
-
#actor ⇒ Object
Falls back to the effective subject, so actor is never nil when user is set — callers attribute to
actorwithout a nil branch. -
#impersonating? ⇒ Boolean
True only while a distinct real actor stands behind the effective subject (act-as).
-
#memoized_org_role(subject) ⇒ Object
Memoize the org-role lookup for
subjectfor the rest of this request/job. -
#reset_org_role_cache ⇒ Object
Drop the memo — called on any org-role write so a later check in the same request sees the change.
Instance Method Details
#actor ⇒ Object
Falls back to the effective subject, so actor is never nil when user is
set — callers attribute to actor without a nil branch.
ROUND-TRIP HAZARD: the reader answers with the fallback, not stored
state. Snapshot/restore code (Current.set, Object#with, anything that
reads #actor to write it back) would pin the fallback as an explicit
actor and restore a stale identity once user changes — read the raw
attributes hash instead, as TestHelpers#with_current_user does.
43 44 45 |
# File 'app/models/current_scope/current.rb', line 43 def actor super || user end |
#impersonating? ⇒ Boolean
True only while a distinct real actor stands behind the effective subject (act-as). THE definition of "impersonating" — the Permissions mixin and the mutation guard both delegate here, so the view-level read-only signal and the write gate can never drift apart.
51 52 53 |
# File 'app/models/current_scope/current.rb', line 51 def impersonating? user.present? && actor != user end |
#memoized_org_role(subject) ⇒ Object
Memoize the org-role lookup for subject for the rest of this request/job.
Keyed by subject so a check that spans several subjects stays correct.
Caches nil (no role) too, so a repeated "no grant" check is one query, not N.
58 59 60 61 62 63 64 65 66 |
# File 'app/models/current_scope/current.rb', line 58 def memoized_org_role(subject) return yield if subject.nil? cache = (self.org_role_cache ||= {}) key = [ subject.class.name, subject.id ] return cache[key] if cache.key?(key) cache[key] = yield end |
#reset_org_role_cache ⇒ Object
Drop the memo — called on any org-role write so a later check in the same request sees the change.
70 71 72 |
# File 'app/models/current_scope/current.rb', line 70 def reset_org_role_cache self.org_role_cache = nil end |