global_session 1.0.0 → 1.0.2
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.
data/global_session.gemspec
CHANGED
@@ -7,8 +7,8 @@ spec = Gem::Specification.new do |s|
|
|
7
7
|
s.required_ruby_version = Gem::Requirement.new(">= 1.8.7")
|
8
8
|
|
9
9
|
s.name = 'global_session'
|
10
|
-
s.version = '1.0.
|
11
|
-
s.date = '2011-01-
|
10
|
+
s.version = '1.0.2'
|
11
|
+
s.date = '2011-01-15'
|
12
12
|
|
13
13
|
s.authors = ['Tony Spataro']
|
14
14
|
s.email = 'code@tracker.xeger.net'
|
@@ -21,11 +21,11 @@ spec = Gem::Specification.new do |s|
|
|
21
21
|
s.add_runtime_dependency('json', [">= 1.1.7"])
|
22
22
|
s.add_runtime_dependency('rack-contrib', [">= 1.0"])
|
23
23
|
|
24
|
-
s.add_development_dependency('rake', ["
|
25
|
-
s.add_development_dependency('ruby-debug', ["
|
26
|
-
s.add_development_dependency('rspec', ["
|
27
|
-
s.add_development_dependency('flexmock', ["
|
28
|
-
s.add_development_dependency('actionpack', ["
|
24
|
+
s.add_development_dependency('rake', [">= 0.8.7"])
|
25
|
+
s.add_development_dependency('ruby-debug', [">= 0.10.3"])
|
26
|
+
s.add_development_dependency('rspec', ["~> 1.3"])
|
27
|
+
s.add_development_dependency('flexmock', ["~> 0.8"])
|
28
|
+
s.add_development_dependency('actionpack', ["~> 2.3"])
|
29
29
|
|
30
30
|
basedir = File.dirname(__FILE__)
|
31
31
|
candidates = ['global_session.gemspec', 'init.rb', 'MIT-LICENSE', 'README.rdoc'] +
|
@@ -1,3 +1,5 @@
|
|
1
|
+
require 'set'
|
2
|
+
|
1
3
|
module GlobalSession
|
2
4
|
# The global session directory, which provides some lookup and decision services
|
3
5
|
# to instances of Session.
|
@@ -29,7 +31,7 @@ module GlobalSession
|
|
29
31
|
# at initialization time.
|
30
32
|
#
|
31
33
|
class Directory
|
32
|
-
attr_reader :configuration, :authorities, :private_key
|
34
|
+
attr_reader :configuration, :authorities, :private_key
|
33
35
|
|
34
36
|
# Create a new Directory.
|
35
37
|
#
|
@@ -52,15 +54,20 @@ module GlobalSession
|
|
52
54
|
raise ConfigurationError, "Expected #{basename} to contain an RSA public key" unless @authorities[authority].public?
|
53
55
|
end
|
54
56
|
|
55
|
-
if
|
56
|
-
key_file = keys.detect { |kf| kf =~ /#{
|
57
|
-
raise ConfigurationError, "Key file #{
|
57
|
+
if local_authority_name
|
58
|
+
key_file = keys.detect { |kf| kf =~ /#{local_authority_name}.key$/ }
|
59
|
+
raise ConfigurationError, "Key file #{local_authority_name}.key not found" unless key_file
|
58
60
|
@private_key = OpenSSL::PKey::RSA.new(File.read(key_file))
|
59
61
|
raise ConfigurationError, "Expected #{key_file} to contain an RSA private key" unless @private_key.private?
|
60
|
-
@local_authority_name = authority_name
|
61
62
|
end
|
63
|
+
|
64
|
+
@invalid_sessions = Set.new
|
62
65
|
end
|
63
66
|
|
67
|
+
def local_authority_name
|
68
|
+
@configuration['authority']
|
69
|
+
end
|
70
|
+
|
64
71
|
# Determine whether this system trusts a particular authority based on
|
65
72
|
# the trust settings specified in Configuration.
|
66
73
|
#
|
@@ -85,11 +92,13 @@ module GlobalSession
|
|
85
92
|
# === Return
|
86
93
|
# valid(true|false):: whether the specified session is valid
|
87
94
|
def valid_session?(uuid, expired_at)
|
88
|
-
expired_at > Time.now
|
95
|
+
(expired_at > Time.now) && !@invalid_sessions.include?(uuid)
|
89
96
|
end
|
90
97
|
|
91
98
|
# Callback used by Session objects to report when the application code calls
|
92
|
-
# #invalidate! on them. The default implementation of this method
|
99
|
+
# #invalidate! on them. The default implementation of this method records
|
100
|
+
# invalid session IDs using an in-memory data structure, which is not ideal
|
101
|
+
# for most implementations.
|
93
102
|
#
|
94
103
|
# uuid(String):: Global session UUID
|
95
104
|
# expired_at(Time):: When the session expired
|
@@ -97,7 +106,7 @@ module GlobalSession
|
|
97
106
|
# === Return
|
98
107
|
# true:: Always returns true
|
99
108
|
def report_invalid_session(uuid, expired_at)
|
100
|
-
|
109
|
+
@invalid_sessions << uuid
|
101
110
|
end
|
102
111
|
end
|
103
112
|
end
|
data/lib/global_session/rack.rb
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
|
1
|
+
require File.expand_path(File.join(File.dirname(__FILE__), "..", "global_session"))
|
2
2
|
|
3
3
|
# Make sure the namespace exists, to satisfy Rails auto-loading
|
4
4
|
module GlobalSession
|
@@ -37,8 +37,20 @@ module GlobalSession
|
|
37
37
|
@configuration = configuration
|
38
38
|
end
|
39
39
|
|
40
|
+
begin
|
41
|
+
klass_name = @configuration['directory'] || 'GlobalSession::Directory'
|
42
|
+
|
43
|
+
#Constantize the type name that was given as a string
|
44
|
+
parts = klass_name.split('::')
|
45
|
+
namespace = Object
|
46
|
+
namespace = namespace.const_get(parts.shift.to_sym) until parts.empty?
|
47
|
+
directory_klass = namespace
|
48
|
+
rescue Exception => e
|
49
|
+
raise ConfigurationError, "Invalid/unknown directory class name #{@configuration['directory']}"
|
50
|
+
end
|
51
|
+
|
40
52
|
if directory.instance_of?(String)
|
41
|
-
@directory =
|
53
|
+
@directory = directory_klass.new(@configuration, directory)
|
42
54
|
else
|
43
55
|
@directory = directory
|
44
56
|
end
|
@@ -47,6 +59,34 @@ module GlobalSession
|
|
47
59
|
@cookie_name = @configuration['cookie']['name']
|
48
60
|
end
|
49
61
|
|
62
|
+
# Rack request chain. Sets up the global session ticket from
|
63
|
+
# the environment and passes it up the chain.
|
64
|
+
def call(env)
|
65
|
+
env['rack.cookies'] = {} unless env['rack.cookies']
|
66
|
+
|
67
|
+
begin
|
68
|
+
read_cookie(env)
|
69
|
+
rescue Exception => e
|
70
|
+
env['global_session'] = Session.new(@directory)
|
71
|
+
handle_error('reading session cookie', env, e)
|
72
|
+
end
|
73
|
+
|
74
|
+
tuple = nil
|
75
|
+
|
76
|
+
begin
|
77
|
+
tuple = @app.call(env)
|
78
|
+
rescue Exception => e
|
79
|
+
handle_error('processing request', env, e)
|
80
|
+
return tuple
|
81
|
+
else
|
82
|
+
renew_cookie(env)
|
83
|
+
update_cookie(env)
|
84
|
+
return tuple
|
85
|
+
end
|
86
|
+
end
|
87
|
+
|
88
|
+
protected
|
89
|
+
|
50
90
|
# Read a cookie from the Rack environment.
|
51
91
|
#
|
52
92
|
# === Parameters
|
@@ -71,7 +111,7 @@ module GlobalSession
|
|
71
111
|
def renew_cookie(env)
|
72
112
|
return unless env['global_session'].directory.local_authority_name
|
73
113
|
return if env['global_session.req.renew'] == false
|
74
|
-
|
114
|
+
|
75
115
|
if (renew = @configuration['renew']) && env['global_session'] &&
|
76
116
|
env['global_session'].expired_at < Time.at(Time.now.utc + 60 * renew.to_i)
|
77
117
|
env['global_session'].renew!
|
@@ -110,6 +150,9 @@ module GlobalSession
|
|
110
150
|
# === Parameters
|
111
151
|
# env(Hash): Rack environment
|
112
152
|
def wipe_cookie(env)
|
153
|
+
return unless env['global_session'].directory.local_authority_name
|
154
|
+
return if env['global_session.req.update'] == false
|
155
|
+
|
113
156
|
domain = @configuration['cookie']['domain'] || env['SERVER_NAME']
|
114
157
|
env['rack.cookies'][@cookie_name] = {:value => nil, :domain => domain, :expires => Time.at(0)}
|
115
158
|
end
|
@@ -123,42 +166,17 @@ module GlobalSession
|
|
123
166
|
# env(Hash): Rack environment
|
124
167
|
# e(Exception): error that happened
|
125
168
|
def handle_error(activity, env, e)
|
126
|
-
|
169
|
+
env['rack.logger'].error("#{e.class} while #{activity}: #{e} #{e.backtrace}") if env['rack.logger']
|
170
|
+
|
171
|
+
if e.is_a?(ClientError) || e.is_a?(SecurityError)
|
127
172
|
env['global_session.error'] = e
|
128
173
|
wipe_cookie(env)
|
129
174
|
elsif e.is_a? ConfigurationError
|
130
|
-
env['rack.logger'].error("#{e.class} while #{activity}: #{e} #{e.backtrace}") if env['rack.logger']
|
131
175
|
env['global_session.error'] = e
|
132
176
|
else
|
133
177
|
raise e
|
134
178
|
end
|
135
179
|
end
|
136
|
-
|
137
|
-
# Rack request chain. Sets up the global session ticket from
|
138
|
-
# the environment and passes it up the chain.
|
139
|
-
def call(env)
|
140
|
-
env['rack.cookies'] = {} unless env['rack.cookies']
|
141
|
-
|
142
|
-
begin
|
143
|
-
read_cookie(env)
|
144
|
-
rescue Exception => e
|
145
|
-
env['global_session'] = Session.new(@directory)
|
146
|
-
handle_error('reading session cookie', env, e)
|
147
|
-
end
|
148
|
-
|
149
|
-
tuple = nil
|
150
|
-
|
151
|
-
begin
|
152
|
-
tuple = @app.call(env)
|
153
|
-
rescue Exception => e
|
154
|
-
handle_error('processing request', env, e)
|
155
|
-
return tuple
|
156
|
-
else
|
157
|
-
renew_cookie(env)
|
158
|
-
update_cookie(env)
|
159
|
-
return tuple
|
160
|
-
end
|
161
|
-
end
|
162
180
|
end
|
163
181
|
end
|
164
182
|
end
|
@@ -19,6 +19,9 @@ module GlobalSession
|
|
19
19
|
unless base.instance_methods.include?("session_without_global_session")
|
20
20
|
base.alias_method_chain :session, :global_session
|
21
21
|
end
|
22
|
+
unless base.instance_methods.include?("log_processing_without_global_session")
|
23
|
+
base.alias_method_chain :log_processing, :global_session
|
24
|
+
end
|
22
25
|
end
|
23
26
|
|
24
27
|
# Shortcut accessor for global session configuration object.
|
@@ -115,16 +118,13 @@ module GlobalSession
|
|
115
118
|
#
|
116
119
|
# === Return
|
117
120
|
# name(Type):: Description
|
118
|
-
def
|
119
|
-
|
120
|
-
log_processing_for_request_id
|
121
|
-
log_processing_for_parameters
|
122
|
-
end
|
123
|
-
end
|
121
|
+
def log_processing_with_global_session
|
122
|
+
return unless logger && logger.info?
|
124
123
|
|
125
|
-
|
126
|
-
|
127
|
-
|
124
|
+
gs = request.env['global_session']
|
125
|
+
|
126
|
+
if gs && gs.id
|
127
|
+
session_id = gs.id + " (#{session[:session_id] || request.session_options[:id]})"
|
128
128
|
elsif session[:session_id]
|
129
129
|
session_id = session[:session_id]
|
130
130
|
elsif request.session_options[:id]
|
@@ -137,9 +137,7 @@ module GlobalSession
|
|
137
137
|
request_id << "\n Session ID: #{session_id}" if session_id
|
138
138
|
|
139
139
|
logger.info(request_id)
|
140
|
-
end
|
141
140
|
|
142
|
-
def log_processing_for_parameters # :nodoc:
|
143
141
|
parameters = respond_to?(:filter_parameters) ? filter_parameters(params) : params.dup
|
144
142
|
parameters = parameters.except!(:controller, :action, :format, :_method)
|
145
143
|
|
metadata
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: global_session
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
hash:
|
4
|
+
hash: 19
|
5
5
|
prerelease: false
|
6
6
|
segments:
|
7
7
|
- 1
|
8
8
|
- 0
|
9
|
-
-
|
10
|
-
version: 1.0.
|
9
|
+
- 2
|
10
|
+
version: 1.0.2
|
11
11
|
platform: ruby
|
12
12
|
authors:
|
13
13
|
- Tony Spataro
|
@@ -15,7 +15,7 @@ autorequire:
|
|
15
15
|
bindir: bin
|
16
16
|
cert_chain: []
|
17
17
|
|
18
|
-
date: 2011-01-
|
18
|
+
date: 2011-01-15 00:00:00 -08:00
|
19
19
|
default_executable:
|
20
20
|
dependencies:
|
21
21
|
- !ruby/object:Gem::Dependency
|
@@ -71,7 +71,7 @@ dependencies:
|
|
71
71
|
requirement: &id004 !ruby/object:Gem::Requirement
|
72
72
|
none: false
|
73
73
|
requirements:
|
74
|
-
- -
|
74
|
+
- - ">="
|
75
75
|
- !ruby/object:Gem::Version
|
76
76
|
hash: 49
|
77
77
|
segments:
|
@@ -87,7 +87,7 @@ dependencies:
|
|
87
87
|
requirement: &id005 !ruby/object:Gem::Requirement
|
88
88
|
none: false
|
89
89
|
requirements:
|
90
|
-
- -
|
90
|
+
- - ">="
|
91
91
|
- !ruby/object:Gem::Version
|
92
92
|
hash: 49
|
93
93
|
segments:
|
@@ -103,14 +103,13 @@ dependencies:
|
|
103
103
|
requirement: &id006 !ruby/object:Gem::Requirement
|
104
104
|
none: false
|
105
105
|
requirements:
|
106
|
-
- -
|
106
|
+
- - ~>
|
107
107
|
- !ruby/object:Gem::Version
|
108
|
-
hash:
|
108
|
+
hash: 9
|
109
109
|
segments:
|
110
110
|
- 1
|
111
111
|
- 3
|
112
|
-
|
113
|
-
version: 1.3.0
|
112
|
+
version: "1.3"
|
114
113
|
type: :development
|
115
114
|
version_requirements: *id006
|
116
115
|
- !ruby/object:Gem::Dependency
|
@@ -119,14 +118,13 @@ dependencies:
|
|
119
118
|
requirement: &id007 !ruby/object:Gem::Requirement
|
120
119
|
none: false
|
121
120
|
requirements:
|
122
|
-
- -
|
121
|
+
- - ~>
|
123
122
|
- !ruby/object:Gem::Version
|
124
|
-
hash:
|
123
|
+
hash: 27
|
125
124
|
segments:
|
126
125
|
- 0
|
127
126
|
- 8
|
128
|
-
|
129
|
-
version: 0.8.6
|
127
|
+
version: "0.8"
|
130
128
|
type: :development
|
131
129
|
version_requirements: *id007
|
132
130
|
- !ruby/object:Gem::Dependency
|
@@ -135,14 +133,13 @@ dependencies:
|
|
135
133
|
requirement: &id008 !ruby/object:Gem::Requirement
|
136
134
|
none: false
|
137
135
|
requirements:
|
138
|
-
- -
|
136
|
+
- - ~>
|
139
137
|
- !ruby/object:Gem::Version
|
140
|
-
hash:
|
138
|
+
hash: 5
|
141
139
|
segments:
|
142
140
|
- 2
|
143
|
-
-
|
144
|
-
|
145
|
-
version: 2.1.2
|
141
|
+
- 3
|
142
|
+
version: "2.3"
|
146
143
|
type: :development
|
147
144
|
version_requirements: *id008
|
148
145
|
description: This plugin for Rails 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.
|