global_session 3.2.10 → 3.3.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|