Class: Mxrb::RubyApp::SessionManager

Inherits:
Object
  • Object
show all
Defined in:
lib/mxrb/ruby_app/session_manager.rb

Overview

Environment-backed identities and short-lived opaque sessions for the standalone Ruby server. Production deployments can put the same adapter behind their own Rack authentication and provide static bearer tokens.

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(access_control, users: ENV['MXRB_USERS_JSON'], tokens: ENV['MXRB_AUTH_TOKENS'], ttl: ENV.fetch('MXRB_SESSION_TTL', '3600'), clock: -> { Time.now.utc }, store: nil) ⇒ SessionManager

rubocop:disable Metrics/ParameterLists

Raises:

  • (ArgumentError)


20
21
22
23
24
25
26
27
28
29
30
31
# File 'lib/mxrb/ruby_app/session_manager.rb', line 20

def initialize(access_control, users: ENV['MXRB_USERS_JSON'],
               tokens: ENV['MXRB_AUTH_TOKENS'], ttl: ENV.fetch('MXRB_SESSION_TTL', '3600'),
               clock: -> { Time.now.utc }, store: nil)
  @access_control = access_control
  @users = parse_map(users, 'MXRB_USERS_JSON')
  @static_tokens = parse_map(tokens, 'MXRB_AUTH_TOKENS')
  @ttl = Integer(ttl)
  raise ArgumentError, 'session TTL must be positive' unless @ttl.positive?

  @clock = clock
  @store = store || Runtime::MemorySharedStore.new
end

Instance Attribute Details

#ttlObject (readonly)

Returns the value of attribute ttl.



17
18
19
# File 'lib/mxrb/ruby_app/session_manager.rb', line 17

def ttl
  @ttl
end

Instance Method Details

#anonymousObject

rubocop:enable Metrics/ParameterLists



34
35
36
# File 'lib/mxrb/ruby_app/session_manager.rb', line 34

def anonymous
  @access_control.context
end

#authenticate(header) ⇒ Object



38
39
40
41
42
43
44
45
46
47
48
49
# File 'lib/mxrb/ruby_app/session_manager.rb', line 38

def authenticate(header)
  token = bearer_token(header)
  return anonymous unless token

  static = @static_tokens[token]
  return context_for(static) if static

  session = @store.read_session(token, now: @clock.call)
  raise AuthenticationError, 'invalid or expired bearer token' unless session

  context_for(session.identity)
end

#login(username, password) ⇒ Object



51
52
53
54
55
56
57
58
59
60
61
# File 'lib/mxrb/ruby_app/session_manager.rb', line 51

def (username, password)
  identity = authenticated_identity(username, password)

  token = SecureRandom.urlsafe_base64(32)
  expires_at = @clock.call + ttl
  profile = identity.slice('roles', 'user_roles', 'module_roles', 'attributes')
                    .merge('user' => username.to_s)
  context = context_for(profile)
  @store.write_session(token:, identity: profile, expires_at:)
  { token:, expires_at: expires_at.iso8601, user: context.user, roles: context.user_roles }
end

#logout(header) ⇒ Object



63
64
65
66
# File 'lib/mxrb/ruby_app/session_manager.rb', line 63

def logout(header)
  token = bearer_token(header)
  token && @store.delete_session(token)
end