Class: Strelka::Session::Default

Inherits:
Strelka::Session show all
Extended by:
Configurability, Forwardable, Delegation, MethodUtilities
Includes:
DataUtilities
Defined in:
lib/strelka/session/default.rb

Overview

Default session class -- simple in-memory, cookie-based base-bones session.

Direct Known Subclasses

Db

Constant Summary collapse

CONFIG_DEFAULTS =

Default configuration

{
  cookie_name: 'strelka-session',
  cookie_options: {
    expires: "+1d",
  }
}.freeze

Instance Attribute Summary collapse

Attributes inherited from Strelka::Session

#session_id

Class Method Summary collapse

Instance Method Summary collapse

Methods included from Delegation

def_class_delegators, def_ivar_delegators, def_method_delegators

Methods included from MethodUtilities

attr_predicate, attr_predicate_accessor, singleton_attr_accessor, singleton_attr_reader, singleton_attr_writer, singleton_method_alias, singleton_predicate_accessor, singleton_predicate_reader

Methods included from DataUtilities

autovivify, deep_copy, stringify_keys, symbolify_keys

Methods inherited from Strelka::Session

load, load_or_create

Methods included from AbstractClass

extended, included, #inherited, #pure_virtual

Constructor Details

#initialize(session_id = nil, initial_values = {}) ⇒ Default

Create a new session store using the given hash for initial values.



134
135
136
137
138
139
140
141
# File 'lib/strelka/session/default.rb', line 134

def initialize( session_id=nil, initial_values={} )
  @hash       = Hash.new {|h,k| h[k] = {} }
  @hash.merge!( initial_values )

  @namespace  = nil

  super
end

Dynamic Method Handling

This class handles dynamic methods through the method_missing method

#method_missing(sym, *args) ⇒ Object (protected)

Proxy method: handle getting/setting headers via methods instead of the index operator.



230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
# File 'lib/strelka/session/default.rb', line 230

def method_missing( sym, *args )
  # work magic
  return super unless sym.to_s =~ /^([a-z]\w+)(=)?$/

  # If it's an assignment, the (=)? will have matched
  key, assignment = $1, $2

  method_body = nil
  if assignment
    method_body = self.make_setter( key )
  else
    method_body = self.make_getter( key )
  end

  self.class.send( :define_method, sym, &method_body )
  return self.method( sym ).call( *args )
end

Instance Attribute Details

#namespaceObject

The namespace that determines which subhash of the session is exposed to the application.



162
163
164
# File 'lib/strelka/session/default.rb', line 162

def namespace
  @namespace
end

Class Method Details

.configure(config = nil) ⇒ Object

Configure the session class with the given options, which should be a Hash or an object that has a Hash-like interface.

Valid keys:

[\cookie_name] The name of the cookie that will be used for persisting the session key. [\cookie_options] A hash of options for the session cookie; see Strelka::Cookie for available options.



118
119
120
121
122
123
124
125
126
# File 'lib/strelka/session/default.rb', line 118

def self::configure( config=nil )
  if config
    self.cookie_name = config[:cookie_name]
    self.cookie_options = config[:cookie_options]
  else
    self.cookie_name = CONFIG_DEFAULTS[:cookie_name]
    self.cookie_options = CONFIG_DEFAULTS[:cookie_options].dup
  end
end

.delete_session_data(session_id) ⇒ Object

Delete the data associated with the given session_id from memory.



70
71
72
# File 'lib/strelka/session/default.rb', line 70

def self::delete_session_data( session_id )
  self.sessions.delete( session_id )
end

.get_existing_session_id(request) ⇒ Object

Try to fetch a session ID from the specified request, returning nil if there isn't one.



77
78
79
80
81
82
83
84
85
86
# File 'lib/strelka/session/default.rb', line 77

def self::get_existing_session_id( request )
  cookie = request.cookies[ self.cookie_name ] or return nil

  if cookie.value =~ /^([[:xdigit:]]+)$/i
    return $1
  else
    self.log.warn "Request with a malformed session cookie: %p" % [ request ]
    return nil
  end
end

.get_session_id(request = nil) ⇒ Object

Fetch the session ID from the given request, or create a new one if the request doesn't have the necessary attributes.



91
92
93
94
# File 'lib/strelka/session/default.rb', line 91

def self::get_session_id( request=nil )
  id = self.get_existing_session_id( request ) if request
  return id || SecureRandom.hex
end

.has_session_for?(request) ⇒ Boolean

Return true if the given request has a session token which corresponds to an existing session key.

Returns:



99
100
101
102
103
104
# File 'lib/strelka/session/default.rb', line 99

def self::has_session_for?( request )
  self.log.debug "Checking request (%s/%d) for session." % [ request.sender_id, request.conn_id ]
  id = self.get_existing_session_id( request ) or return false
  self.log.debug "  got a session ID: %p" % [ id ]
  return @sessions.key?( id )
end

.load_session_data(session_id) ⇒ Object

Load a session instance from storage using the given session_id and return it. Returns nil if no session could be loaded.



58
59
60
# File 'lib/strelka/session/default.rb', line 58

def self::load_session_data( session_id )
  return Strelka::DataUtilities.deep_copy( self.sessions[session_id] )
end

.save_session_data(session_id, data) ⇒ Object

Save the given data to memory associated with the given session_id.



64
65
66
# File 'lib/strelka/session/default.rb', line 64

def self::save_session_data( session_id, data )
  self.sessions[ session_id ] = Strelka::DataUtilities.deep_copy( data )
end

Instance Method Details

The name of the session cookie



48
# File 'lib/strelka/session/default.rb', line 48

singleton_attr_accessor :cookie_name

Session cookie options; see Strelka::Cookie for available options.



53
# File 'lib/strelka/session/default.rb', line 53

singleton_attr_accessor :cookie_options

#defaultsessionObject

Configurability API -- use the 'defaultsession' section of the config



26
# File 'lib/strelka/session/default.rb', line 26

config_key :defaultsession

#destroy(response) ⇒ Object

Delete the session from storage and expire the session cookie from the given response.



194
195
196
197
198
199
200
201
202
203
204
205
206
207
# File 'lib/strelka/session/default.rb', line 194

def destroy( response )
  self.log.debug "Destroying session %s" % [ self.session_id ]
  self.class.delete_session_data( self.session_id )

  self.log.debug "Adding expired session cookie to the response"
  session_cookie = Strelka::Cookie.new(
    self.class.cookie_name,
    self.session_id,
    self.class.cookie_options || {}
  )
  session_cookie.expire!

  response.cookies << session_cookie
end

#initialize_cloneObject

Make sure the inner Hash is unique on clones.



151
152
153
# File 'lib/strelka/session/default.rb', line 151

def initialize_clone( * ) # :nodoc:
  @hash = deep_copy( @hash )
end

#initialize_dupObject

Make sure the inner Hash is unique on duplications.



145
146
147
# File 'lib/strelka/session/default.rb', line 145

def initialize_dup( * ) # :nodoc:
  @hash = deep_copy( @hash )
end

#namespaced_hashObject

Return the Hash that corresponds with the current namespace's storage. If no namespace is currently set, returns the entire session store as a Hash of Hashes keyed by namespaces as Symbols.



166
# File 'lib/strelka/session/default.rb', line 166

def_method_delegators :namespaced_hash, :[], :[]=, :delete, :key?

#save(response) ⇒ Object

Save the session to storage and add the session cookie to the given response.



178
179
180
181
182
183
184
185
186
187
188
189
190
# File 'lib/strelka/session/default.rb', line 178

def save( response )
  self.log.debug "Saving session %s" % [ self.session_id ]
  self.class.save_session_data( self.session_id, @hash )
  self.log.debug "Adding session cookie to the response."

  session_cookie = Strelka::Cookie.new(
    self.class.cookie_name,
    self.session_id,
    self.class.cookie_options || {}
  )

  response.cookies << session_cookie
end

#sessionsObject

In-memory session store



44
# File 'lib/strelka/session/default.rb', line 44

singleton_attr_reader :sessions