Class: HasGlobalSession::GlobalSession
- Inherits:
-
Object
- Object
- HasGlobalSession::GlobalSession
- Defined in:
- lib/has_global_session/global_session.rb
Overview
Ladies and gentlemen: the one and only, star of the show, GLOBAL SESSION!
GlobalSession is designed to act as much like a Hash as possible. You can use most of the methods you would use with Hash: [], has_key?, each, etc. It has a few additional methods that are specific to itself, mostly involving whether it’s expired, valid, supports a certain key, etc.
Instance Attribute Summary collapse
-
#authority ⇒ Object
readonly
Returns the value of attribute authority.
-
#created_at ⇒ Object
readonly
Returns the value of attribute created_at.
-
#directory ⇒ Object
readonly
Returns the value of attribute directory.
-
#expired_at ⇒ Object
readonly
Returns the value of attribute expired_at.
-
#id ⇒ Object
readonly
Returns the value of attribute id.
Instance Method Summary collapse
-
#[](key) ⇒ Object
Lookup a value by its key.
-
#[]=(key, value) ⇒ Object
Set a value in the global session hash.
-
#each_pair(&block) ⇒ Object
Iterate over each key/value pair.
-
#has_key?(key) ⇒ Boolean
Determine whether this session contains a value with the specified key.
-
#initialize(directory, cookie = nil, valid_signature_digest = nil) ⇒ GlobalSession
constructor
Create a new global session object.
-
#invalidate! ⇒ Object
Invalidate this session by reporting its UUID to the Directory.
-
#keys ⇒ Object
Return the keys that are currently present in the global session.
-
#renew! ⇒ Object
Renews this global session, changing its expiry timestamp into the future.
-
#signature_digest ⇒ Object
Return the SHA1 hash of the most recently-computed RSA signature of this session.
-
#supports_key?(key) ⇒ Boolean
Determine whether the global session schema allows a given key to be placed in the global session.
-
#to_s ⇒ Object
Serialize the session to a form suitable for use with HTTP cookies.
-
#valid? ⇒ Boolean
Determine whether the session is valid.
-
#values ⇒ Object
Return the values that are currently present in the global session.
Constructor Details
#initialize(directory, cookie = nil, valid_signature_digest = nil) ⇒ GlobalSession
Create a new global session object.
Parameters
- directory(Directory)
-
directory implementation that the session should use for various operations
- cookie(String)
-
Optional, serialized global session cookie. If none is supplied, a new session is created.
- valid_signature_digest(String)
-
Optional, already-trusted signature. If supplied, the expensive RSA-verify operation will be skipped if the cookie’s signature matches the value supplied.
Raise
- InvalidSession
-
if the session contained in the cookie has been invalidated
- ExpiredSession
-
if the session contained in the cookie has expired
- MalformedCookie
-
if the cookie was corrupt or malformed
- SecurityError
-
if signature is invalid or cookie is not signed by a trusted authority
31 32 33 34 35 36 37 38 39 40 41 42 43 44 |
# File 'lib/has_global_session/global_session.rb', line 31 def initialize(directory, =nil, valid_signature_digest=nil) @configuration = directory.configuration @schema_signed = Set.new((@configuration['attributes']['signed'])) @schema_insecure = Set.new((@configuration['attributes']['insecure'])) @directory = directory if && !.empty? (, valid_signature_digest) elsif @directory. create_from_scratch else create_invalid end end |
Instance Attribute Details
#authority ⇒ Object (readonly)
Returns the value of attribute authority.
17 18 19 |
# File 'lib/has_global_session/global_session.rb', line 17 def @authority end |
#created_at ⇒ Object (readonly)
Returns the value of attribute created_at.
17 18 19 |
# File 'lib/has_global_session/global_session.rb', line 17 def created_at @created_at end |
#directory ⇒ Object (readonly)
Returns the value of attribute directory.
17 18 19 |
# File 'lib/has_global_session/global_session.rb', line 17 def directory @directory end |
#expired_at ⇒ Object (readonly)
Returns the value of attribute expired_at.
17 18 19 |
# File 'lib/has_global_session/global_session.rb', line 17 def expired_at @expired_at end |
#id ⇒ Object (readonly)
Returns the value of attribute id.
17 18 19 |
# File 'lib/has_global_session/global_session.rb', line 17 def id @id end |
Instance Method Details
#[](key) ⇒ Object
Lookup a value by its key.
Parameters
- key(String)
-
the key
Return
- value(Object)
-
The value associated with
key
, or nil ifkey
is not present
149 150 151 |
# File 'lib/has_global_session/global_session.rb', line 149 def [](key) @signed[key] || @insecure[key] end |
#[]=(key, value) ⇒ Object
Set a value in the global session hash. If the supplied key is denoted as secure by the global session schema, causes a new signature to be computed when the session is next serialized.
Parameters
- key(String)
-
The key to set
- value(Object)
-
The value to set
Return
- value(Object)
-
Always returns the value that was set
Raise
- InvalidSession
-
if the session has been invalidated (and therefore can’t be written to)
- ArgumentError
-
if the configuration doesn’t define the specified key as part of the global session
- NoAuthority
-
if the specified key is secure and the local node is not an authority
- UnserializableType
-
if the specified value can’t be serialized as JSON
169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 |
# File 'lib/has_global_session/global_session.rb', line 169 def []=(key, value) raise InvalidSession unless valid? #Ensure that the value is serializable (will raise if not) canonicalize(value) if @schema_signed.include?(key) @signed[key] = value @dirty_secure = true elsif @schema_insecure.include?(key) @insecure[key] = value @dirty_insecure = true else raise ArgumentError, "Attribute '#{key}' is not specified in global session configuration" end return value end |
#each_pair(&block) ⇒ Object
Iterate over each key/value pair
Block
An iterator which will be called with each key/value pair
Return
Returns the value of the last expression evaluated by the block
137 138 139 140 |
# File 'lib/has_global_session/global_session.rb', line 137 def each_pair(&block) # :yields: |key, value| @signed.each_pair(&block) @insecure.each_pair(&block) end |
#has_key?(key) ⇒ Boolean
Determine whether this session contains a value with the specified key.
Parameters
- key(String)
-
The name of the key
Return
- contained(true|false)
-
Whether the session currently has a value for the specified key.
110 111 112 |
# File 'lib/has_global_session/global_session.rb', line 110 def has_key?(key) @signed.has_key(key) || @insecure.has_key?(key) end |
#invalidate! ⇒ Object
Invalidate this session by reporting its UUID to the Directory.
Return
- unknown(Object)
-
Returns whatever the Directory returns
193 194 195 |
# File 'lib/has_global_session/global_session.rb', line 193 def invalidate! @directory.report_invalid_session(@id, @expired_at) end |
#keys ⇒ Object
Return the keys that are currently present in the global session.
Return
- keys(Array)
-
List of keys contained in the global session
118 119 120 |
# File 'lib/has_global_session/global_session.rb', line 118 def keys @signed.keys + @insecure.keys end |
#renew! ⇒ Object
Renews this global session, changing its expiry timestamp into the future. Causes a new signature will be computed when the session is next serialized.
Return
- true
-
Always returns true
202 203 204 205 206 |
# File 'lib/has_global_session/global_session.rb', line 202 def renew! @expired_at = @configuration['timeout'].to_i.minutes.from_now.utc @dirty_secure = true end |
#signature_digest ⇒ Object
Return the SHA1 hash of the most recently-computed RSA signature of this session. This isn’t really intended for the end user; it exists so the Web framework integration code can optimize request speed by caching the most recently verified signature in the local session and avoid re-verifying it on every request.
Return
- digest(String)
-
SHA1 hex-digest of most-recently-computed signature
215 216 217 |
# File 'lib/has_global_session/global_session.rb', line 215 def signature_digest @signature ? digest(@signature) : nil end |
#supports_key?(key) ⇒ Boolean
Determine whether the global session schema allows a given key to be placed in the global session.
Parameters
- key(String)
-
The name of the key
Return
- supported(true|false)
-
Whether the specified key is supported
99 100 101 |
# File 'lib/has_global_session/global_session.rb', line 99 def supports_key?(key) @schema_signed.include?(key) || @schema_insecure.include?(key) end |
#to_s ⇒ Object
Serialize the session to a form suitable for use with HTTP cookies. If any secure attributes have changed since the session was instantiated, compute a fresh RSA signature.
Return
- cookie(String)
-
The B64cookie-encoded Zlib-compressed JSON-serialized global session hash
61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 |
# File 'lib/has_global_session/global_session.rb', line 61 def to_s if @cookie && !@dirty_insecure && !@dirty_secure #use cached cookie if nothing has changed return @cookie end hash = {'id'=>@id, 'tc'=>@created_at.to_i, 'te'=>@expired_at.to_i, 'ds'=>@signed} if @signature && !@dirty_secure #use cached signature unless we've changed secure state = @authority else = @directory. hash['a'] = digest = canonical_digest(hash) @signature = Encoding::Base64Cookie.dump(@directory.private_key.private_encrypt(digest)) end hash['dx'] = @insecure hash['s'] = @signature hash['a'] = json = Encoding::JSON.dump(hash) zbin = Zlib::Deflate.deflate(json, Zlib::BEST_COMPRESSION) return Encoding::Base64Cookie.dump(zbin) end |
#valid? ⇒ Boolean
Determine whether the session is valid. This method simply delegates to the directory associated with this session.
Return
- valid(true|false)
-
True if the session is valid, false otherwise
51 52 53 |
# File 'lib/has_global_session/global_session.rb', line 51 def valid? @directory.valid_session?(@id, @expired_at) end |
#values ⇒ Object
Return the values that are currently present in the global session.
Return
- values(Array)
-
List of values contained in the global session
126 127 128 |
# File 'lib/has_global_session/global_session.rb', line 126 def values @signed.values + @insecure.values end |