Class: Karst::Web::BrowserIdentity

Inherits:
Object
  • Object
show all
Defined in:
lib/karst/web/browser_identity.rb

Overview

State-changing browser identity operations and their same-session CSRF token. Rails controller CSRF is unavailable because /karst is served at the Rack boundary, before Action Controller dispatch.

Constant Summary collapse

TOKEN_KEY =
"karst.csrf_token"
ACTIVE_KEY =
"karst.browser_identity_active"
SCOPE_KEY =

The exact Devise/Warden scope the currently assumed identity was established under (see Identity.assume_browser), retained for the lifetime of the browser session so #clear can hand it straight back to Identity.clear_browser instead of that having to guess which of several selected sources produced the principal being cleared.

"karst.browser_identity_scope"

Instance Method Summary collapse

Constructor Details

#initialize(request) ⇒ BrowserIdentity

Returns a new instance of BrowserIdentity.



23
24
25
# File 'lib/karst/web/browser_identity.rb', line 23

def initialize(request)
  @request = request
end

Instance Method Details

#active?Boolean

Returns:

  • (Boolean)


31
32
33
# File 'lib/karst/web/browser_identity.rb', line 31

def active?
  session[ACTIVE_KEY] == true
end

#assume(params) ⇒ Object



35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
# File 'lib/karst/web/browser_identity.rb', line 35

def assume(params)
  verify_token!(params["csrf_token"])
  target = return_path(params["path"])
  principal = Identity.resolve(model_name: params["principal_type"], id: params["principal_id"])
  raise Identity::Unavailable, "principal is not in the configured source" unless principal

  scope = Identity.assume_browser(@request, principal)
  # Authentication hooks may clear or replace the host session. Rebuild
  # Karst's control state only after that transition, and invalidate the
  # token which authorized it rather than carrying pre-assumption state
  # into the assumed identity.
  session[ACTIVE_KEY] = true
  session[SCOPE_KEY] = scope&.to_s
  rotate_token!
  target
end

#clear(params) ⇒ Object



52
53
54
55
56
57
58
59
60
# File 'lib/karst/web/browser_identity.rb', line 52

def clear(params)
  verify_token!(params["csrf_token"])
  target = return_path(params["path"])
  scope = session[SCOPE_KEY]
  Identity.clear_browser(@request, scope: scope&.to_sym)
  session.delete(ACTIVE_KEY)
  session.delete(SCOPE_KEY)
  target
end

#tokenObject



27
28
29
# File 'lib/karst/web/browser_identity.rb', line 27

def token
  session[TOKEN_KEY] ||= SecureRandom.hex(32)
end