Class: NebulaToken::MemoryRefreshTokenStore
- Inherits:
-
Object
- Object
- NebulaToken::MemoryRefreshTokenStore
- Includes:
- RefreshTokenStore
- Defined in:
- lib/nebula_token.rb
Overview
Reference store ([N-21]).
Guarded by a mutex, so the compare-and-set methods are atomic under the threaded request concurrency of Puma, Falcon or Sidekiq.
NOT FOR PRODUCTION: state is per-process and lost on restart, so reuse detection does not survive a deploy and does not work behind more than one instance. Implement the six methods over your database instead — start from examples/pg_store.rb, schema in docs/STORE.md.
Instance Method Summary collapse
-
#all ⇒ Object
Test helper: every record currently stored.
-
#delete_expired(now) ⇒ Object
Operational helper: drop records whose family deadline has passed.
- #find_by_selector(selector) ⇒ Object
-
#initialize ⇒ MemoryRefreshTokenStore
constructor
A new instance of MemoryRefreshTokenStore.
- #insert(record) ⇒ Object
- #mark_rotated(selector, from_status, rotated_at, replaced_by_selector) ⇒ Object
- #revoke_family(family_id) ⇒ Object
- #revoke_if_active(selector) ⇒ Object
- #revoke_user(user_id) ⇒ Object
Constructor Details
#initialize ⇒ MemoryRefreshTokenStore
Returns a new instance of MemoryRefreshTokenStore.
409 410 411 412 |
# File 'lib/nebula_token.rb', line 409 def initialize @rows = {} @mutex = Mutex.new end |
Instance Method Details
#all ⇒ Object
Test helper: every record currently stored. Not part of the store contract.
463 464 465 |
# File 'lib/nebula_token.rb', line 463 def all @mutex.synchronize { @rows.values.map(&:dup_record) } end |
#delete_expired(now) ⇒ Object
Operational helper: drop records whose family deadline has passed. Nothing may be deleted before it ([N-15]) — rotated rows ARE the reuse detector.
469 470 471 472 473 474 475 |
# File 'lib/nebula_token.rb', line 469 def delete_expired(now) @mutex.synchronize do expired = @rows.select { |_, row| now >= row.family_expires_at } expired.each_key { |selector| @rows.delete(selector) } expired.size end end |
#find_by_selector(selector) ⇒ Object
414 415 416 |
# File 'lib/nebula_token.rb', line 414 def find_by_selector(selector) @mutex.synchronize { @rows[selector]&.dup_record } end |
#insert(record) ⇒ Object
418 419 420 421 422 423 424 425 426 427 428 429 |
# File 'lib/nebula_token.rb', line 418 def insert(record) @mutex.synchronize do if @rows.key?(record.selector) # An infrastructure failure, not a protocol outcome ([N-20]): mirrors # the primary-key violation a real store would raise. raise "[NEBULA] duplicate selector #{record.selector}" end @rows[record.selector] = record.dup_record end nil end |
#mark_rotated(selector, from_status, rotated_at, replaced_by_selector) ⇒ Object
431 432 433 434 435 436 437 438 439 440 441 442 |
# File 'lib/nebula_token.rb', line 431 def mark_rotated(selector, from_status, rotated_at, replaced_by_selector) want = NebulaToken.normalize_status(from_status) @mutex.synchronize do row = @rows[selector] next false if row.nil? || row.status != want row.status = STATUS_ROTATED row.rotated_at = rotated_at row.replaced_by_selector = replaced_by_selector true end end |
#revoke_family(family_id) ⇒ Object
454 455 456 |
# File 'lib/nebula_token.rb', line 454 def revoke_family(family_id) revoke_where { |row| row.family_id == family_id } end |
#revoke_if_active(selector) ⇒ Object
444 445 446 447 448 449 450 451 452 |
# File 'lib/nebula_token.rb', line 444 def revoke_if_active(selector) @mutex.synchronize do row = @rows[selector] next false unless row&.active? row.status = STATUS_REVOKED true end end |
#revoke_user(user_id) ⇒ Object
458 459 460 |
# File 'lib/nebula_token.rb', line 458 def revoke_user(user_id) revoke_where { |row| row.user_id == user_id } end |