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