global_session 3.2.10 → 3.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/global_session.gemspec +21 -86
- data/lib/global_session.rb +12 -7
- data/lib/global_session/directory.rb +8 -6
- data/lib/global_session/keystore.rb +28 -6
- data/lib/global_session/rack.rb +1 -1
- data/lib/global_session/session.rb +11 -6
- data/lib/global_session/session/abstract.rb +123 -4
- data/lib/global_session/session/v1.rb +6 -14
- data/lib/global_session/session/v2.rb +9 -17
- data/lib/global_session/session/v3.rb +11 -137
- data/lib/global_session/session/v4.rb +140 -0
- data/lib/global_session/version.rb +3 -0
- metadata +18 -91
- data/.ruby-version +0 -1
- data/.travis.yml +0 -11
- data/CHANGELOG.md +0 -94
- data/LICENSE +0 -20
- data/README.rdoc +0 -298
- data/Rakefile +0 -48
- data/VERSION +0 -1
- data/init.rb +0 -4
- data/rails/init.rb +0 -23
- data/rails_generators/global_session/USAGE +0 -1
- data/rails_generators/global_session/global_session_generator.rb +0 -51
- data/rails_generators/global_session/templates/global_session.yml.erb +0 -41
- data/rails_generators/global_session_authority/USAGE +0 -1
- data/rails_generators/global_session_authority/global_session_authority_generator.rb +0 -53
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: bdc242048b36de58af17de56b0b99eb35749402b
|
4
|
+
data.tar.gz: 21c79fa5ca975c6fd8dddaa623c00f24f385276f
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: b2030dc06623067a3ebbbdbdfda30d465e2d7f84c9cef19fbc9bff55f7ea11e65e656cd10854b0abf0e0f5ee2e6273a54076d99ff0fd85aaaac65fbd552e4bbd
|
7
|
+
data.tar.gz: b2d3249a309714a84b47699adb4bc7531c3a56aaa5a76ea3b2df81a4d2ee778ab75e439e2870089223c212d6f42254eb5874b9debcb92f4030272a987a7c05b1
|
data/global_session.gemspec
CHANGED
@@ -1,91 +1,26 @@
|
|
1
|
-
#
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
# stub: global_session 3.2.9 ruby lib
|
1
|
+
# encoding: utf-8
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'global_session/version'
|
6
5
|
|
7
|
-
Gem::Specification.new do |
|
8
|
-
|
9
|
-
|
6
|
+
Gem::Specification.new do |spec|
|
7
|
+
spec.name = 'global_session'
|
8
|
+
spec.version = GlobalSession::VERSION
|
9
|
+
spec.authors = ['Tony Spataro']
|
10
|
+
spec.email = 'rubygems@rightscale.com'
|
10
11
|
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
s.description = "This Rack middleware allows several web apps in an authentication domain to share session state, facilitating single sign-on in a distributed web app. It only provides session sharing and does not concern itself with authentication or replication of the user database."
|
16
|
-
s.email = "support@rightscale.com"
|
17
|
-
s.extra_rdoc_files = [
|
18
|
-
"LICENSE",
|
19
|
-
"README.rdoc"
|
20
|
-
]
|
21
|
-
s.files = [
|
22
|
-
".ruby-version",
|
23
|
-
".travis.yml",
|
24
|
-
"CHANGELOG.md",
|
25
|
-
"LICENSE",
|
26
|
-
"README.rdoc",
|
27
|
-
"Rakefile",
|
28
|
-
"VERSION",
|
29
|
-
"global_session.gemspec",
|
30
|
-
"init.rb",
|
31
|
-
"lib/global_session.rb",
|
32
|
-
"lib/global_session/configuration.rb",
|
33
|
-
"lib/global_session/directory.rb",
|
34
|
-
"lib/global_session/encoding.rb",
|
35
|
-
"lib/global_session/keystore.rb",
|
36
|
-
"lib/global_session/rack.rb",
|
37
|
-
"lib/global_session/rails.rb",
|
38
|
-
"lib/global_session/rails/action_controller_class_methods.rb",
|
39
|
-
"lib/global_session/rails/action_controller_instance_methods.rb",
|
40
|
-
"lib/global_session/session.rb",
|
41
|
-
"lib/global_session/session/abstract.rb",
|
42
|
-
"lib/global_session/session/v1.rb",
|
43
|
-
"lib/global_session/session/v2.rb",
|
44
|
-
"lib/global_session/session/v3.rb",
|
45
|
-
"rails/init.rb",
|
46
|
-
"rails_generators/global_session/USAGE",
|
47
|
-
"rails_generators/global_session/global_session_generator.rb",
|
48
|
-
"rails_generators/global_session/templates/global_session.yml.erb",
|
49
|
-
"rails_generators/global_session_authority/USAGE",
|
50
|
-
"rails_generators/global_session_authority/global_session_authority_generator.rb"
|
51
|
-
]
|
52
|
-
s.homepage = "https://github.com/rightscale/global_session"
|
53
|
-
s.licenses = ["MIT"]
|
54
|
-
s.required_ruby_version = Gem::Requirement.new("~> 2.0")
|
55
|
-
s.rubygems_version = "2.2.3"
|
56
|
-
s.summary = "Secure single-domain session sharing plugin for Rack and Rails."
|
12
|
+
spec.summary = 'Reusable foundation code.'
|
13
|
+
spec.description = 'A toolkit of useful, reusable foundation code created by RightScale.'
|
14
|
+
spec.homepage = 'https://github.com/rightscale/right_support'
|
15
|
+
spec.license = 'MIT'
|
57
16
|
|
58
|
-
|
59
|
-
|
17
|
+
spec.files = `git ls-files -z`.split("\x0").select { |f| f.match(%r{lib/|gemspec}) }
|
18
|
+
spec.require_paths = ['lib']
|
60
19
|
|
61
|
-
|
62
|
-
s.add_runtime_dependency(%q<json>, ["~> 1.4"])
|
63
|
-
s.add_runtime_dependency(%q<rack-contrib>, ["~> 1.0"])
|
64
|
-
s.add_runtime_dependency(%q<right_support>, ["< 4.0", ">= 2.8.2"])
|
65
|
-
s.add_runtime_dependency(%q<simple_uuid>, [">= 0.2.0"])
|
66
|
-
s.add_development_dependency(%q<ruby-debug>, ["~> 0.10"])
|
67
|
-
s.add_development_dependency(%q<pry>, ["~> 0.10"])
|
68
|
-
s.add_development_dependency(%q<pry-byebug>, ["~> 2.0"])
|
69
|
-
s.add_development_dependency(%q<jeweler>, ["~> 1.8"])
|
70
|
-
else
|
71
|
-
s.add_dependency(%q<json>, ["~> 1.4"])
|
72
|
-
s.add_dependency(%q<rack-contrib>, ["~> 1.0"])
|
73
|
-
s.add_dependency(%q<right_support>, ["< 4.0", ">= 2.8.2"])
|
74
|
-
s.add_dependency(%q<simple_uuid>, [">= 0.2.0"])
|
75
|
-
s.add_dependency(%q<ruby-debug>, ["~> 0.10"])
|
76
|
-
s.add_dependency(%q<pry>, ["~> 0.10"])
|
77
|
-
s.add_dependency(%q<pry-byebug>, ["~> 2.0"])
|
78
|
-
s.add_dependency(%q<jeweler>, ["~> 1.8"])
|
79
|
-
end
|
80
|
-
else
|
81
|
-
s.add_dependency(%q<json>, ["~> 1.4"])
|
82
|
-
s.add_dependency(%q<rack-contrib>, ["~> 1.0"])
|
83
|
-
s.add_dependency(%q<right_support>, ["< 4.0", ">= 2.8.2"])
|
84
|
-
s.add_dependency(%q<simple_uuid>, [">= 0.2.0"])
|
85
|
-
s.add_dependency(%q<ruby-debug>, ["~> 0.10"])
|
86
|
-
s.add_dependency(%q<pry>, ["~> 0.10"])
|
87
|
-
s.add_dependency(%q<pry-byebug>, ["~> 2.0"])
|
88
|
-
s.add_dependency(%q<jeweler>, ["~> 1.8"])
|
89
|
-
end
|
90
|
-
end
|
20
|
+
spec.required_ruby_version = Gem::Requirement.new('~> 2.1')
|
91
21
|
|
22
|
+
spec.add_runtime_dependency('json', ['~> 1.4'])
|
23
|
+
spec.add_runtime_dependency('rack-contrib', ['~> 1.0'])
|
24
|
+
spec.add_runtime_dependency('right_support', ['>= 2.14.1', '< 3.0'])
|
25
|
+
spec.add_runtime_dependency('simple_uuid', ['>= 0.2.0'])
|
26
|
+
end
|
data/lib/global_session.rb
CHANGED
@@ -27,24 +27,26 @@ module GlobalSession
|
|
27
27
|
# The general category of client-side errors. Used solely as a base class.
|
28
28
|
class ClientError < Exception; end
|
29
29
|
|
30
|
-
#
|
30
|
+
# Global session configuration is missing from the environment or filesystem.
|
31
31
|
#
|
32
32
|
class MissingConfiguration < ConfigurationError; end
|
33
33
|
|
34
|
-
#
|
35
|
-
#
|
34
|
+
# The request has a valid session cookie, but the session ID was reported as
|
35
|
+
# invalid by the Directory.
|
36
36
|
#
|
37
37
|
# See Directory#valid_session? for more information.
|
38
38
|
#
|
39
39
|
class InvalidSession < ClientError; end
|
40
40
|
|
41
|
-
#
|
42
|
-
# session has expired.
|
41
|
+
# The request has a valid session cookie, but the session has expired.
|
43
42
|
#
|
44
43
|
class ExpiredSession < ClientError; end
|
45
44
|
|
46
|
-
#
|
47
|
-
|
45
|
+
# The request has a valid session cookie, but the session has expired.
|
46
|
+
class PrematureSession < ExpiredSession; end
|
47
|
+
|
48
|
+
# The request has a session cookie, but the cookie is malformed and cannot be
|
49
|
+
# interpreted as session state.
|
48
50
|
#
|
49
51
|
class MalformedCookie < ClientError
|
50
52
|
attr_reader :cookie
|
@@ -76,6 +78,9 @@ module GlobalSession
|
|
76
78
|
# information.
|
77
79
|
#
|
78
80
|
class NoAuthority < ConfigurationError; end
|
81
|
+
|
82
|
+
# The request has a session cookie, but its signature is invalid.
|
83
|
+
class InvalidSignature < SecurityError; end
|
79
84
|
end
|
80
85
|
|
81
86
|
#Make sure gem dependencies are activated.
|
@@ -28,7 +28,7 @@ module GlobalSession
|
|
28
28
|
# The default implementation is simplistic, but should be suitable for most applications.
|
29
29
|
# Directory is designed to be specialized via subclassing. To override the behavior to
|
30
30
|
# suit your needs, simply create a subclass of Directory and add a configuration file
|
31
|
-
# setting to specify the class name of your implementation:
|
31
|
+
# setting to specify the class name of your implementation:
|
32
32
|
#
|
33
33
|
# common:
|
34
34
|
# directory:
|
@@ -108,21 +108,23 @@ module GlobalSession
|
|
108
108
|
# InvalidSession:: if the session contained in the cookie has been invalidated
|
109
109
|
# ExpiredSession:: if the session contained in the cookie has expired
|
110
110
|
# MalformedCookie:: if the cookie was corrupt or malformed
|
111
|
-
#
|
111
|
+
# InvalidSignature:: if signature is invalid or cookie is not signed by a trusted authority
|
112
112
|
def create_session(cookie=nil)
|
113
113
|
forced_version = configuration['cookie']['version']
|
114
114
|
|
115
115
|
if cookie.nil?
|
116
116
|
# Create a legitimately new session
|
117
117
|
case forced_version
|
118
|
-
when
|
118
|
+
when 4
|
119
|
+
Session::V4.new(self, cookie)
|
120
|
+
when nil, 3
|
119
121
|
Session::V3.new(self, cookie)
|
120
122
|
when 2
|
121
123
|
Session::V2.new(self, cookie)
|
122
124
|
when 1
|
123
125
|
Session::V1.new(self, cookie)
|
124
126
|
else
|
125
|
-
raise ArgumentError, "Unknown value #{forced_version} for configuration.cookie.version"
|
127
|
+
raise ArgumentError, "Unknown value #{forced_version} for configuration.cookie.version"
|
126
128
|
end
|
127
129
|
else
|
128
130
|
warn "GlobalSession::Directory#create_session with an existing session is DEPRECATED -- use #load_session instead"
|
@@ -142,7 +144,7 @@ module GlobalSession
|
|
142
144
|
# InvalidSession:: if the session contained in the cookie has been invalidated
|
143
145
|
# ExpiredSession:: if the session contained in the cookie has expired
|
144
146
|
# MalformedCookie:: if the cookie was corrupt or malformed
|
145
|
-
#
|
147
|
+
# InvalidSignature:: if signature is invalid or cookie is not signed by a trusted authority
|
146
148
|
def load_session(cookie)
|
147
149
|
Session.new(self, cookie)
|
148
150
|
end
|
@@ -170,7 +172,7 @@ module GlobalSession
|
|
170
172
|
def local_authority_name
|
171
173
|
@keystore.private_key_name
|
172
174
|
end
|
173
|
-
|
175
|
+
|
174
176
|
# Determine whether this system trusts a particular named authority based on
|
175
177
|
# the settings specified in Configuration and/or the presence of public key
|
176
178
|
# files on disk.
|
@@ -64,11 +64,23 @@ module GlobalSession
|
|
64
64
|
|
65
65
|
# Factory method to generate a new keypair for use with GlobalSession.
|
66
66
|
#
|
67
|
+
# @param [Integer,String] parameter keylength in bits (for RSA/DSA) or curve name (for EC)
|
67
68
|
# @raise [ArgumentError] if cryptosystem is unknown to OpenSSL
|
68
69
|
# @return [OpenSSL::PKey::PKey] a public/private keypair
|
69
|
-
def self.create_keypair(cryptosystem=:RSA,
|
70
|
+
def self.create_keypair(cryptosystem=:RSA, parameter=nil)
|
70
71
|
factory = OpenSSL::PKey.const_get(cryptosystem)
|
71
|
-
factory.generate
|
72
|
+
if factory.respond_to?(:generate)
|
73
|
+
# parameter-free cryptosystem e.g. RSA, DSA. Default key length 1024,
|
74
|
+
# which is really too small, but whose signatures are quite large.
|
75
|
+
parameter ||= 1024
|
76
|
+
factory.generate( parameter )
|
77
|
+
else
|
78
|
+
# parameterized family of cryptosystems (e.g. EC). Default curve is
|
79
|
+
# compatible with JSON Web Signature (JWS) ES256 algorithm.
|
80
|
+
parameter ||= 'prime256v1'
|
81
|
+
alg = factory.new(parameter)
|
82
|
+
alg.generate_key
|
83
|
+
end
|
72
84
|
rescue NameError => e
|
73
85
|
raise ArgumentError, e.message
|
74
86
|
end
|
@@ -106,9 +118,17 @@ module GlobalSession
|
|
106
118
|
end
|
107
119
|
elsif File.file?(path)
|
108
120
|
name = File.basename(path, '.*')
|
109
|
-
|
121
|
+
pem = File.read(path)
|
122
|
+
|
123
|
+
# Deal with modern ("BEGIN PUBLIC/PRIVATE KEY") and legacy ("BEGIN RSA PUBLIC KEY") formats
|
124
|
+
if pem =~ /BEGIN RSA/
|
125
|
+
key = OpenSSL::PKey::RSA.new(pem)
|
126
|
+
else
|
127
|
+
key = OpenSSL::PKey.read(pem)
|
128
|
+
end
|
129
|
+
|
110
130
|
# ignore private keys (which legacy config allowed to coexist with public keys)
|
111
|
-
unless key.private?
|
131
|
+
unless (key.private? rescue nil) || (key.private_key? rescue nil)
|
112
132
|
if @public_keys.has_key?(name)
|
113
133
|
raise ConfigurationError, "Duplicate public key for authority: #{name}"
|
114
134
|
else
|
@@ -135,8 +155,10 @@ module GlobalSession
|
|
135
155
|
if File.file?(path)
|
136
156
|
if @private_key.nil?
|
137
157
|
name = File.basename(path, '.*')
|
138
|
-
|
139
|
-
|
158
|
+
pem = File.read(path)
|
159
|
+
private_key = OpenSSL::PKey.read(pem)
|
160
|
+
|
161
|
+
raise ConfigurationError, "Expected #{key_file} to contain an RSA private key" unless (private_key.private? rescue nil) || (private_key.private_key? rescue nil)
|
140
162
|
@private_key = private_key
|
141
163
|
@private_key_name = name
|
142
164
|
else
|
data/lib/global_session/rack.rb
CHANGED
@@ -298,7 +298,7 @@ module GlobalSession
|
|
298
298
|
env['rack.logger'].error(msg)
|
299
299
|
end
|
300
300
|
|
301
|
-
if e.is_a?(ClientError) || e.is_a?(
|
301
|
+
if e.is_a?(ClientError) || e.is_a?(InvalidSignature)
|
302
302
|
env['global_session.error'] = e
|
303
303
|
wipe_cookie(env)
|
304
304
|
elsif e.is_a? ConfigurationError
|
@@ -7,6 +7,7 @@ require 'global_session/session/abstract'
|
|
7
7
|
require 'global_session/session/v1'
|
8
8
|
require 'global_session/session/v2'
|
9
9
|
require 'global_session/session/v3'
|
10
|
+
require 'global_session/session/v4'
|
10
11
|
|
11
12
|
# Ladies and gentlemen: the one and only, star of the show, GLOBAL SESSION!
|
12
13
|
#
|
@@ -32,20 +33,24 @@ module GlobalSession::Session
|
|
32
33
|
|
33
34
|
# Decode a global session cookie. Use a heuristic to determine the version.
|
34
35
|
# @raise [GlobalSession::MalformedCookie] if the cookie is not a valid serialized global session
|
35
|
-
def self.new(directory, cookie=nil
|
36
|
+
def self.new(directory, cookie=nil)
|
36
37
|
guess_version(cookie).new(directory, cookie)
|
37
38
|
end
|
38
39
|
|
40
|
+
# Figure out the protocol version of a serialized session cookie.
|
41
|
+
#
|
42
|
+
# @param [String] cookie
|
43
|
+
# @return [Class] implementation class that can probably deserialize cookie
|
39
44
|
def self.guess_version(cookie)
|
40
45
|
case cookie
|
41
|
-
when
|
46
|
+
when V4::HEADER
|
47
|
+
V4
|
48
|
+
when nil, V3::HEADER
|
42
49
|
V3
|
43
|
-
when
|
50
|
+
when V2::HEADER
|
44
51
|
V2
|
45
|
-
when /^eN/ # == zlib-compressed form of "{"
|
46
|
-
V1
|
47
52
|
else
|
48
|
-
V1
|
53
|
+
V1 # due to zlib compression, no foolproof way to spot V1 sessoins
|
49
54
|
end
|
50
55
|
end
|
51
56
|
end
|
@@ -14,7 +14,7 @@ module GlobalSession::Session
|
|
14
14
|
# InvalidSession:: if the session contained in the cookie has been invalidated
|
15
15
|
# ExpiredSession:: if the session contained in the cookie has expired
|
16
16
|
# MalformedCookie:: if the cookie was corrupt or malformed
|
17
|
-
#
|
17
|
+
# InvalidSignature:: if signature is invalid or cookie is not signed by a trusted authority
|
18
18
|
def initialize(directory, cookie=nil)
|
19
19
|
@directory = directory
|
20
20
|
@signed = {}
|
@@ -75,6 +75,80 @@ module GlobalSession::Session
|
|
75
75
|
@cookie.nil?
|
76
76
|
end
|
77
77
|
|
78
|
+
# Return the keys that are currently present in the global session.
|
79
|
+
#
|
80
|
+
# === Return
|
81
|
+
# keys(Array):: List of keys contained in the global session
|
82
|
+
def keys
|
83
|
+
@signed.keys + @insecure.keys
|
84
|
+
end
|
85
|
+
|
86
|
+
# Return the values that are currently present in the global session.
|
87
|
+
#
|
88
|
+
# === Return
|
89
|
+
# values(Array):: List of values contained in the global session
|
90
|
+
def values
|
91
|
+
@signed.values + @insecure.values
|
92
|
+
end
|
93
|
+
|
94
|
+
# Iterate over each key/value pair
|
95
|
+
#
|
96
|
+
# === Block
|
97
|
+
# An iterator which will be called with each key/value pair
|
98
|
+
#
|
99
|
+
# === Return
|
100
|
+
# Returns the value of the last expression evaluated by the block
|
101
|
+
def each_pair(&block) # :yields: |key, value|
|
102
|
+
@signed.each_pair(&block)
|
103
|
+
@insecure.each_pair(&block)
|
104
|
+
end
|
105
|
+
|
106
|
+
# Lookup a value by its key.
|
107
|
+
#
|
108
|
+
# === Parameters
|
109
|
+
# key(String):: the key
|
110
|
+
#
|
111
|
+
# === Return
|
112
|
+
# value(Object):: The value associated with +key+, or nil if +key+ is not present
|
113
|
+
def [](key)
|
114
|
+
key = key.to_s #take care of symbol-style keys
|
115
|
+
@signed[key] || @insecure[key]
|
116
|
+
end
|
117
|
+
|
118
|
+
# Set a value in the global session hash. If the supplied key is denoted as
|
119
|
+
# secure by the global session schema, causes a new signature to be computed
|
120
|
+
# when the session is next serialized.
|
121
|
+
#
|
122
|
+
# === Parameters
|
123
|
+
# key(String):: The key to set
|
124
|
+
# value(Object):: The value to set
|
125
|
+
#
|
126
|
+
# === Return
|
127
|
+
# value(Object):: Always returns the value that was set
|
128
|
+
#
|
129
|
+
# ===Raise
|
130
|
+
# InvalidSession:: if the session has been invalidated (and therefore can't be written to)
|
131
|
+
# ArgumentError:: if the configuration doesn't define the specified key as part of the global session
|
132
|
+
# NoAuthority:: if the specified key is secure and the local node is not an authority
|
133
|
+
# UnserializableType:: if the specified value can't be serialized as JSON
|
134
|
+
def []=(key, value)
|
135
|
+
key = key.to_s #take care of symbol-style keys
|
136
|
+
raise GlobalSession::InvalidSession unless valid?
|
137
|
+
|
138
|
+
if @schema_signed.include?(key)
|
139
|
+
authority_check
|
140
|
+
@signed[key] = value
|
141
|
+
@dirty_secure = true
|
142
|
+
elsif @schema_insecure.include?(key)
|
143
|
+
@insecure[key] = value
|
144
|
+
@dirty_insecure = true
|
145
|
+
else
|
146
|
+
raise ArgumentError, "Attribute '#{key}' is not specified in global session configuration"
|
147
|
+
end
|
148
|
+
|
149
|
+
return value
|
150
|
+
end
|
151
|
+
|
78
152
|
# Determine whether the session is valid. This method simply delegates to the
|
79
153
|
# directory associated with this session.
|
80
154
|
#
|
@@ -88,7 +162,7 @@ module GlobalSession::Session
|
|
88
162
|
#
|
89
163
|
# @return [Boolean] true if something has changed
|
90
164
|
def dirty?
|
91
|
-
!!(new_record? || @dirty_timestamps)
|
165
|
+
!!(new_record? || @dirty_timestamps || @dirty_secure || @dirty_insecure)
|
92
166
|
end
|
93
167
|
|
94
168
|
# Determine whether the global session schema allows a given key to be placed
|
@@ -116,6 +190,34 @@ module GlobalSession::Session
|
|
116
190
|
|
117
191
|
alias key? has_key?
|
118
192
|
|
193
|
+
# Delete a key from the global session attributes. If the key exists,
|
194
|
+
# mark the global session dirty
|
195
|
+
#
|
196
|
+
# @param [String] the key to delete
|
197
|
+
# @return [Object] the value of the key deleted, or nil if not found
|
198
|
+
def delete(key)
|
199
|
+
key = key.to_s #take care of symbol-style keys
|
200
|
+
raise GlobalSession::InvalidSession unless valid?
|
201
|
+
|
202
|
+
if @schema_signed.include?(key)
|
203
|
+
authority_check
|
204
|
+
|
205
|
+
# Only mark dirty if the key actually exists
|
206
|
+
@dirty_secure = true if @signed.keys.include? key
|
207
|
+
value = @signed.delete(key)
|
208
|
+
elsif @schema_insecure.include?(key)
|
209
|
+
|
210
|
+
# Only mark dirty if the key actually exists
|
211
|
+
@dirty_insecure = true if @insecure.keys.include? key
|
212
|
+
value = @insecure.delete(key)
|
213
|
+
else
|
214
|
+
raise ArgumentError, "Attribute '#{key}' is not specified in global session configuration"
|
215
|
+
end
|
216
|
+
|
217
|
+
return value
|
218
|
+
end
|
219
|
+
|
220
|
+
|
119
221
|
# Invalidate this session by reporting its UUID to the Directory.
|
120
222
|
#
|
121
223
|
# === Return
|
@@ -140,6 +242,10 @@ module GlobalSession::Session
|
|
140
242
|
|
141
243
|
private
|
142
244
|
|
245
|
+
def generate_id
|
246
|
+
RightSupport::Data::Base64URL.encode(SecureRandom.random_bytes(8))
|
247
|
+
end
|
248
|
+
|
143
249
|
def authority_check # :nodoc:
|
144
250
|
unless @directory.local_authority_name
|
145
251
|
raise GlobalSession::NoAuthority, 'Cannot change secure session attributes; we are not an authority'
|
@@ -155,7 +261,20 @@ module GlobalSession::Session
|
|
155
261
|
end
|
156
262
|
|
157
263
|
def create_invalid
|
158
|
-
|
264
|
+
@id = nil
|
265
|
+
@created_at = Time.now.utc
|
266
|
+
@expired_at = created_at
|
267
|
+
@signed = {}
|
268
|
+
@insecure = {}
|
269
|
+
@authority = nil
|
270
|
+
end
|
271
|
+
|
272
|
+
# This is called by Object#clone and is used to augment our "shallow clone"
|
273
|
+
# behavior so that we don't share state hashes between clones.
|
274
|
+
def initialize_copy(source)
|
275
|
+
super
|
276
|
+
@signed = ::RightSupport::Data::HashTools.deep_clone2(@signed)
|
277
|
+
@insecure = ::RightSupport::Data::HashTools.deep_clone2(@insecure)
|
159
278
|
end
|
160
279
|
end
|
161
|
-
end
|
280
|
+
end
|