Module: Parse::AtlasSearch::Session
- Defined in:
- lib/parse/atlas_search/session.rb
Overview
Resolves session tokens to user identities and inherited role sets for ACL-scoped Atlas Search queries.
Atlas Search runs aggregations directly against MongoDB and therefore bypasses Parse Server’s per-request ACL enforcement. To compile a _rperm $match stage (see Parse::ACL.read_predicate) the caller needs to know two things about the requesting session:
1. The +_User.objectId+ that owns the session.
2. The transitive upward closure of role names that user
inherits permissions from (cf. {Parse::Role.all_for_user}).
Both lookups can be expensive — token → user requires a /users/me round-trip, and user → roles can require multiple _Role queries to walk the inheritance graph. Both are cached separately so a single agent turn that runs several Atlas Search tools amortizes the cost.
Two distinct caches:
* +session_cache+: maps +session_token+ to +user_id+. Long
TTL (1 hour default), invalidation profile is logout. Apps
that need sub-TTL revocation must call {.invalidate}
explicitly from their logout path.
* +role_cache+: maps +user_id+ to a +Set+ of role names. Short
TTL (2 minutes default), invalidation profile is role-graph
mutation. Stale role data here yields incorrect ACL
decisions, so the default is conservatively short.
The default cache implementation is process-local (MemoryCache) and guarded by a Mutex. Apps that need shared cross-process caching (Redis, Memcached) may install a replacement via session_cache= / role_cache=; the replacement must respond to get(key), set(key, value, ttl:), and invalidate(key).
Defined Under Namespace
Classes: InvalidSession, MemoryCache, Resolved
Class Method Summary collapse
-
.invalidate(session_token) ⇒ Object
Forget a
session_tokenentry from the session-token cache. -
.invalidate_user_roles(user_id) ⇒ Object
Forget cached role membership for a
user_id. -
.reset_caches! ⇒ Object
Drop every cached entry across both caches.
-
.resolve(session_token) ⇒ Resolved
Resolve a
session_tokento the requesting user and the transitive set of role names whoserole:NAMEpermission strings should be checked against_rperm.
Class Method Details
.invalidate(session_token) ⇒ Object
Forget a session_token entry from the session-token cache. Apps that revoke sessions out-of-band (logout, password reset, admin revoke) should call this from the same path so subsequent Atlas Search requests don’t act on the stale user_id mapping. The role_names cache is keyed on user_id and is not affected — call invalidate_user_roles to clear that separately.
161 162 163 164 |
# File 'lib/parse/atlas_search/session.rb', line 161 def invalidate(session_token) return if session_token.nil? Parse::AtlasSearch.session_cache.invalidate(session_token.to_s) end |
.invalidate_user_roles(user_id) ⇒ Object
Forget cached role membership for a user_id. Call after any _Role.users mutation that affects this user (role grant / revoke, role-graph reshape).
170 171 172 173 |
# File 'lib/parse/atlas_search/session.rb', line 170 def invalidate_user_roles(user_id) return if user_id.nil? Parse::AtlasSearch.role_cache.invalidate(user_id.to_s) end |
.reset_caches! ⇒ Object
Drop every cached entry across both caches. Useful in tests and in startup hooks for processes that fork after warming the cache.
178 179 180 181 |
# File 'lib/parse/atlas_search/session.rb', line 178 def reset_caches! Parse::AtlasSearch.session_cache.clear if Parse::AtlasSearch.session_cache.respond_to?(:clear) Parse::AtlasSearch.role_cache.clear if Parse::AtlasSearch.role_cache.respond_to?(:clear) end |
.resolve(session_token) ⇒ Resolved
Resolve a session_token to the requesting user and the transitive set of role names whose role:NAME permission strings should be checked against _rperm.
nil or empty session_token → anonymous Resolved with user_id: nil and an empty role_names set. The caller decides whether to refuse the request (the require_session_token toggle on Parse::AtlasSearch) or treat as public-only.
Cache layering: token-to-user_id is checked first; on hit the slower /users/me round-trip is skipped. User-to-roles is then checked independently (a single user shared across sessions amortizes the role lookup).
145 146 147 148 149 150 151 |
# File 'lib/parse/atlas_search/session.rb', line 145 def resolve(session_token) return Resolved.new(nil, Set.new) if session_token.nil? || session_token.to_s.empty? user_id = lookup_user_id(session_token.to_s) role_names = lookup_role_names(user_id) Resolved.new(user_id, role_names) end |