has_global_session 0.8.10 → 0.9.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.
- data/has_global_session.gemspec +3 -3
- data/lib/has_global_session/global_session.rb +1 -8
- data/lib/has_global_session/rails/action_controller_instance_methods.rb +127 -0
- data/lib/has_global_session/rails.rb +4 -0
- data/lib/has_global_session.rb +1 -1
- data/rails/init.rb +4 -5
- data/rails_generators/global_session_authority/global_session_authority_generator.rb +32 -0
- data/rails_generators/global_session_config/USAGE +2 -0
- data/rails_generators/global_session_config/global_session_config_generator.rb +19 -0
- data/rails_generators/global_session_config/templates/global_session.yml.erb +51 -0
- metadata +10 -5
- data/rails/action_controller_instance_methods.rb +0 -106
data/has_global_session.gemspec
CHANGED
@@ -7,7 +7,7 @@ spec = Gem::Specification.new do |s|
|
|
7
7
|
s.required_ruby_version = Gem::Requirement.new(">= 1.8.7")
|
8
8
|
|
9
9
|
s.name = 'has_global_session'
|
10
|
-
s.version = '0.
|
10
|
+
s.version = '0.9.0'
|
11
11
|
s.date = '2010-07-01'
|
12
12
|
|
13
13
|
s.authors = ['Tony Spataro']
|
@@ -27,11 +27,11 @@ spec = Gem::Specification.new do |s|
|
|
27
27
|
basedir = File.dirname(__FILE__)
|
28
28
|
candidates = ['has_global_session.gemspec', 'init.rb', 'MIT-LICENSE', 'README.rdoc'] +
|
29
29
|
Dir['lib/**/*'] +
|
30
|
-
Dir['rails/**/*']
|
30
|
+
Dir['rails/**/*'] +
|
31
|
+
Dir['rails_generators/**/*']
|
31
32
|
s.files = candidates.sort
|
32
33
|
end
|
33
34
|
|
34
35
|
if $PROGRAM_NAME == __FILE__
|
35
|
-
Gem.manage_gems if Gem::RubyGemsVersion.to_f < 1.0
|
36
36
|
Gem::Builder.new(spec).build
|
37
37
|
end
|
@@ -7,7 +7,7 @@ require 'uuidtools'
|
|
7
7
|
|
8
8
|
module HasGlobalSession
|
9
9
|
class GlobalSession
|
10
|
-
attr_reader :id, :authority, :created_at, :expired_at
|
10
|
+
attr_reader :id, :authority, :created_at, :expired_at, :directory
|
11
11
|
|
12
12
|
def initialize(directory, cookie=nil)
|
13
13
|
@schema_signed = Set.new((Configuration['attributes']['signed']))
|
@@ -189,13 +189,6 @@ module HasGlobalSession
|
|
189
189
|
@insecure = insecure
|
190
190
|
@signature = signature
|
191
191
|
@cookie = cookie
|
192
|
-
|
193
|
-
#Auto-renew session if needed
|
194
|
-
renew = Configuration['renew']
|
195
|
-
if @directory.local_authority_name &&
|
196
|
-
renew && @expired_at < renew.to_i.minutes.from_now.utc
|
197
|
-
renew!
|
198
|
-
end
|
199
192
|
end
|
200
193
|
|
201
194
|
def create_from_scratch
|
@@ -0,0 +1,127 @@
|
|
1
|
+
module HasGlobalSession
|
2
|
+
module Rails
|
3
|
+
module ActionControllerInstanceMethods
|
4
|
+
def self.included(base)
|
5
|
+
if Configuration['integrated']
|
6
|
+
base.alias_method_chain :session, :global_session
|
7
|
+
end
|
8
|
+
|
9
|
+
base.before_filter :global_session_read_cookie
|
10
|
+
base.before_filter :global_session_auto_renew
|
11
|
+
base.after_filter :global_session_update_cookie
|
12
|
+
end
|
13
|
+
|
14
|
+
def global_session
|
15
|
+
@global_session
|
16
|
+
end
|
17
|
+
|
18
|
+
def session_with_global_session
|
19
|
+
if global_session
|
20
|
+
unless @integrated_session && (@integrated_session.global == @global_session)
|
21
|
+
@integrated_session =
|
22
|
+
IntegratedSession.new(session_without_global_session, global_session)
|
23
|
+
end
|
24
|
+
return @integrated_session
|
25
|
+
else
|
26
|
+
return session_without_global_session
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
def global_session_read_cookie
|
31
|
+
directory = global_session_create_directory
|
32
|
+
cookie_name = Configuration['cookie']['name']
|
33
|
+
cookie = cookies[cookie_name]
|
34
|
+
|
35
|
+
begin
|
36
|
+
#unserialize the global session from the cookie, or
|
37
|
+
#initialize a new global session if cookie == nil
|
38
|
+
@global_session = GlobalSession.new(directory, cookie)
|
39
|
+
return true
|
40
|
+
rescue Exception => e
|
41
|
+
#silently recover from any error by initializing a new global session
|
42
|
+
@global_session = GlobalSession.new(directory)
|
43
|
+
#give the Rails app a chance to handle the exception
|
44
|
+
#unless it's an ExpiredSession, which we handle transparently
|
45
|
+
raise e unless e.is_a?(ExpiredSession)
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
def global_session_auto_renew
|
50
|
+
#Auto-renew session if needed
|
51
|
+
renew = Configuration['renew']
|
52
|
+
if @global_session.directory.local_authority_name && renew &&
|
53
|
+
@global_session.expired_at < renew.to_i.minutes.from_now.utc
|
54
|
+
@global_session.renew!
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
def global_session_update_cookie
|
59
|
+
name = Configuration['cookie']['name']
|
60
|
+
domain = Configuration['cookie']['domain']
|
61
|
+
|
62
|
+
begin
|
63
|
+
if @global_session && @global_session.valid?
|
64
|
+
value = @global_session.to_s
|
65
|
+
expires = Configuration['ephemeral'] ? nil : @global_session.expired_at
|
66
|
+
|
67
|
+
unless (cookies[name] == value)
|
68
|
+
#Update the cookie only if its value has changed
|
69
|
+
cookies[name] = {:value => value, :domain=>domain, :expires=>expires}
|
70
|
+
end
|
71
|
+
else
|
72
|
+
#No valid session? Write an empty cookie.
|
73
|
+
cookies[name] = {:value=>nil, :domain=>domain, :expires=>Time.at(0)}
|
74
|
+
end
|
75
|
+
rescue Exception => e
|
76
|
+
#silently recover from any error by wiping the cookie
|
77
|
+
cookies[name] = {:value=>nil, :domain=>domain, :expires=>Time.at(0)}
|
78
|
+
#give the Rails app a chance to handle the exception
|
79
|
+
raise e
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
83
|
+
def log_processing
|
84
|
+
if logger && logger.info?
|
85
|
+
log_processing_for_request_id
|
86
|
+
log_processing_for_parameters
|
87
|
+
end
|
88
|
+
end
|
89
|
+
|
90
|
+
def log_processing_for_request_id
|
91
|
+
if global_session && global_session.id
|
92
|
+
session_id = global_session.id + " (#{session[:session_id]})"
|
93
|
+
elsif session[:session_id]
|
94
|
+
session_id = session[:session_id]
|
95
|
+
elsif request.session_options[:id]
|
96
|
+
session_id = request.session_options[:id]
|
97
|
+
end
|
98
|
+
|
99
|
+
request_id = "\n\nProcessing #{self.class.name}\##{action_name} "
|
100
|
+
request_id << "to #{params[:format]} " if params[:format]
|
101
|
+
request_id << "(for #{request_origin.split[0]}) [#{request.method.to_s.upcase}]"
|
102
|
+
request_id << "\n Session ID: #{session_id}" if session_id
|
103
|
+
|
104
|
+
logger.info(request_id)
|
105
|
+
end
|
106
|
+
|
107
|
+
def log_processing_for_parameters
|
108
|
+
parameters = respond_to?(:filter_parameters) ? filter_parameters(params) : params.dup
|
109
|
+
parameters = parameters.except!(:controller, :action, :format, :_method)
|
110
|
+
|
111
|
+
logger.info " Parameters: #{parameters.inspect}" unless parameters.empty?
|
112
|
+
end
|
113
|
+
|
114
|
+
private
|
115
|
+
|
116
|
+
def global_session_create_directory
|
117
|
+
if (klass = Configuration['directory'])
|
118
|
+
klass = klass.constantize
|
119
|
+
else
|
120
|
+
klass = Directory
|
121
|
+
end
|
122
|
+
|
123
|
+
return klass.new(File.join(RAILS_ROOT, 'config', 'authorities'))
|
124
|
+
end
|
125
|
+
end
|
126
|
+
end
|
127
|
+
end
|
data/lib/has_global_session.rb
CHANGED
@@ -12,7 +12,7 @@ require 'uuidtools'
|
|
12
12
|
require 'json'
|
13
13
|
require 'active_support'
|
14
14
|
|
15
|
-
#Require
|
15
|
+
#Require the core suite of HasGlobalSession classes and modules
|
16
16
|
basedir = File.dirname(__FILE__)
|
17
17
|
require File.join(basedir, 'has_global_session', 'configuration')
|
18
18
|
require File.join(basedir, 'has_global_session', 'directory')
|
data/rails/init.rb
CHANGED
@@ -1,5 +1,6 @@
|
|
1
1
|
basedir = File.expand_path(File.join(File.dirname(__FILE__), '..'))
|
2
|
-
|
2
|
+
libdir = File.join(basedir, 'lib')
|
3
|
+
require File.join(libdir, 'has_global_session')
|
3
4
|
|
4
5
|
config_file = File.join(RAILS_ROOT, 'config', 'global_session.yml')
|
5
6
|
|
@@ -9,14 +10,12 @@ if File.exist?(config_file)
|
|
9
10
|
HasGlobalSession::Configuration.config_file = config_file
|
10
11
|
HasGlobalSession::Configuration.environment = RAILS_ENV
|
11
12
|
|
12
|
-
require File.join(
|
13
|
+
require File.join(libdir, 'has_global_session', 'rails')
|
13
14
|
|
14
15
|
# Enable ActionController integration.
|
15
16
|
class ActionController::Base
|
16
17
|
def self.has_global_session
|
17
|
-
include HasGlobalSession::ActionControllerInstanceMethods
|
18
|
-
before_filter :global_session_read_cookie
|
19
|
-
after_filter :global_session_update_cookie
|
18
|
+
include HasGlobalSession::Rails::ActionControllerInstanceMethods
|
20
19
|
end
|
21
20
|
end
|
22
21
|
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
class GlobalSessionAuthorityGenerator < Rails::Generator::Base
|
2
|
+
def initialize(runtime_args, runtime_options = {})
|
3
|
+
super
|
4
|
+
|
5
|
+
@app_name = File.basename(RAILS_ROOT)
|
6
|
+
@auth_name = args.shift
|
7
|
+
raise ArgumentError, "Must specify name for global session authority, e.g. 'mycoolapp'" unless @auth_name
|
8
|
+
end
|
9
|
+
|
10
|
+
def manifest
|
11
|
+
record do |m|
|
12
|
+
new_key = OpenSSL::PKey::RSA.generate( 1024 )
|
13
|
+
new_public = new_key.public_key.to_pem
|
14
|
+
new_private = new_key.to_pem
|
15
|
+
|
16
|
+
dest_dir = File.join(RAILS_ROOT, 'config', 'authorities')
|
17
|
+
FileUtils.mkdir_p(dest_dir)
|
18
|
+
|
19
|
+
File.open(File.join(dest_dir, @auth_name + ".pub"), 'w') do |f|
|
20
|
+
f.puts new_public
|
21
|
+
end
|
22
|
+
|
23
|
+
File.open(File.join(dest_dir, @auth_name + ".key"), 'w') do |f|
|
24
|
+
f.puts new_private
|
25
|
+
end
|
26
|
+
|
27
|
+
puts "***"
|
28
|
+
puts "*** Don't forget to delete config/authorities/#{@auth_name}.key"
|
29
|
+
puts "***"
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
class GlobalSessionConfigGenerator < Rails::Generator::Base
|
2
|
+
def initialize(runtime_args, runtime_options = {})
|
3
|
+
super
|
4
|
+
|
5
|
+
@app_name = File.basename(RAILS_ROOT)
|
6
|
+
@app_domain = args.shift
|
7
|
+
raise ArgumentError, "Must specify DNS domain for global session cookie, e.g. 'example.com'" unless @app_domain
|
8
|
+
end
|
9
|
+
|
10
|
+
def manifest
|
11
|
+
record do |m|
|
12
|
+
|
13
|
+
m.template 'global_session.yml.erb',
|
14
|
+
'config/global_session.yml',
|
15
|
+
:assigns=>{:app_name=>@app_name,
|
16
|
+
:app_domain=>@app_domain}
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,51 @@
|
|
1
|
+
# Common settings of the global session (that apply to all Rails environments)
|
2
|
+
# are listed here. These may be overidden in the environment-specific section.
|
3
|
+
common:
|
4
|
+
attributes:
|
5
|
+
# Signed attributes of the global session
|
6
|
+
signed:
|
7
|
+
- user
|
8
|
+
# Untrusted attributes of the global session
|
9
|
+
insecure:
|
10
|
+
- account
|
11
|
+
# Enable local session integration in order to use the ActionController
|
12
|
+
# method #session to access both local AND global session state, with
|
13
|
+
# global attributes always taking precedence over local attributes.
|
14
|
+
integrated: true
|
15
|
+
ephemeral: false
|
16
|
+
|
17
|
+
# Test/spec runs
|
18
|
+
test:
|
19
|
+
timeout: 15 #minutes
|
20
|
+
renew: 5 #minutes before expiration
|
21
|
+
cookie:
|
22
|
+
name: _session_gbl
|
23
|
+
domain: localhost
|
24
|
+
#the name of the local authority (optional)
|
25
|
+
authority: test
|
26
|
+
#which authorities this app will trust
|
27
|
+
trust:
|
28
|
+
- test
|
29
|
+
|
30
|
+
# Development mode
|
31
|
+
development:
|
32
|
+
timeout: 60
|
33
|
+
renew: 15
|
34
|
+
cookie:
|
35
|
+
name: _session_gbl
|
36
|
+
domain: localhost
|
37
|
+
authority: development
|
38
|
+
trust:
|
39
|
+
- development
|
40
|
+
- production
|
41
|
+
|
42
|
+
# Production mode
|
43
|
+
production:
|
44
|
+
timeout: 60
|
45
|
+
renew: 15
|
46
|
+
cookie:
|
47
|
+
name: _session_gbl
|
48
|
+
domain: <%= app_domain %>
|
49
|
+
authority: production
|
50
|
+
trust:
|
51
|
+
- production
|
metadata
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: has_global_session
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
hash:
|
4
|
+
hash: 59
|
5
5
|
prerelease: false
|
6
6
|
segments:
|
7
7
|
- 0
|
8
|
-
-
|
9
|
-
-
|
10
|
-
version: 0.
|
8
|
+
- 9
|
9
|
+
- 0
|
10
|
+
version: 0.9.0
|
11
11
|
platform: ruby
|
12
12
|
authors:
|
13
13
|
- Tony Spataro
|
@@ -117,8 +117,13 @@ files:
|
|
117
117
|
- lib/has_global_session/encoding.rb
|
118
118
|
- lib/has_global_session/global_session.rb
|
119
119
|
- lib/has_global_session/integrated_session.rb
|
120
|
-
- rails
|
120
|
+
- lib/has_global_session/rails.rb
|
121
|
+
- lib/has_global_session/rails/action_controller_instance_methods.rb
|
121
122
|
- rails/init.rb
|
123
|
+
- rails_generators/global_session_authority/global_session_authority_generator.rb
|
124
|
+
- rails_generators/global_session_config/USAGE
|
125
|
+
- rails_generators/global_session_config/global_session_config_generator.rb
|
126
|
+
- rails_generators/global_session_config/templates/global_session.yml.erb
|
122
127
|
has_rdoc: true
|
123
128
|
homepage: http://github.com/xeger/has_global_session
|
124
129
|
licenses: []
|
@@ -1,106 +0,0 @@
|
|
1
|
-
module HasGlobalSession
|
2
|
-
module ActionControllerInstanceMethods
|
3
|
-
def self.included(base)
|
4
|
-
if Configuration['integrated']
|
5
|
-
base.alias_method_chain :session, :global_session
|
6
|
-
end
|
7
|
-
end
|
8
|
-
|
9
|
-
def global_session
|
10
|
-
@global_session
|
11
|
-
end
|
12
|
-
|
13
|
-
def session_with_global_session
|
14
|
-
if global_session
|
15
|
-
unless @integrated_session && (@integrated_session.global == @global_session)
|
16
|
-
@integrated_session =
|
17
|
-
IntegratedSession.new(session_without_global_session, global_session)
|
18
|
-
end
|
19
|
-
return @integrated_session
|
20
|
-
else
|
21
|
-
return session_without_global_session
|
22
|
-
end
|
23
|
-
end
|
24
|
-
|
25
|
-
def global_session_read_cookie
|
26
|
-
if (klass = Configuration['directory'])
|
27
|
-
klass = klass.constantize
|
28
|
-
else
|
29
|
-
klass = Directory
|
30
|
-
end
|
31
|
-
|
32
|
-
directory = klass.new(File.join(RAILS_ROOT, 'config', 'authorities'))
|
33
|
-
cookie_name = Configuration['cookie']['name']
|
34
|
-
cookie = cookies[cookie_name]
|
35
|
-
|
36
|
-
begin
|
37
|
-
#unserialize the global session from the cookie, or
|
38
|
-
#initialize a new global session if cookie == nil
|
39
|
-
@global_session = GlobalSession.new(directory, cookie)
|
40
|
-
return true
|
41
|
-
rescue Exception => e
|
42
|
-
#silently recover from any error by initializing a new global session
|
43
|
-
@global_session = GlobalSession.new(directory)
|
44
|
-
#give the Rails app a chance to handle the exception
|
45
|
-
#unless it's an ExpiredSession, which we handle transparently
|
46
|
-
raise e unless e.is_a?(ExpiredSession)
|
47
|
-
end
|
48
|
-
end
|
49
|
-
|
50
|
-
def global_session_update_cookie
|
51
|
-
name = Configuration['cookie']['name']
|
52
|
-
domain = Configuration['cookie']['domain']
|
53
|
-
|
54
|
-
begin
|
55
|
-
if @global_session && @global_session.valid?
|
56
|
-
value = @global_session.to_s
|
57
|
-
expires = Configuration['ephemeral'] ? nil : @global_session.expired_at
|
58
|
-
|
59
|
-
unless (cookies[name] == value)
|
60
|
-
#Update the cookie only if its value has changed
|
61
|
-
cookies[name] = {:value => value, :domain=>domain, :expires=>expires}
|
62
|
-
end
|
63
|
-
else
|
64
|
-
#No valid session? Write an empty cookie.
|
65
|
-
cookies[name] = {:value=>nil, :domain=>domain, :expires=>Time.at(0)}
|
66
|
-
end
|
67
|
-
rescue Exception => e
|
68
|
-
#silently recover from any error by wiping the cookie
|
69
|
-
cookies[name] = {:value=>nil, :domain=>domain, :expires=>Time.at(0)}
|
70
|
-
#give the Rails app a chance to handle the exception
|
71
|
-
raise e
|
72
|
-
end
|
73
|
-
end
|
74
|
-
|
75
|
-
def log_processing
|
76
|
-
if logger && logger.info?
|
77
|
-
log_processing_for_request_id
|
78
|
-
log_processing_for_parameters
|
79
|
-
end
|
80
|
-
end
|
81
|
-
|
82
|
-
def log_processing_for_request_id()
|
83
|
-
if global_session && global_session.id
|
84
|
-
session_id = global_session.id + " (#{session[:session_id]})"
|
85
|
-
elsif session[:session_id]
|
86
|
-
session_id = session[:session_id]
|
87
|
-
elsif request.session_options[:id]
|
88
|
-
session_id = request.session_options[:id]
|
89
|
-
end
|
90
|
-
|
91
|
-
request_id = "\n\nProcessing #{self.class.name}\##{action_name} "
|
92
|
-
request_id << "to #{params[:format]} " if params[:format]
|
93
|
-
request_id << "(for #{request_origin.split[0]}) [#{request.method.to_s.upcase}]"
|
94
|
-
request_id << "\n Session ID: #{session_id}" if session_id
|
95
|
-
|
96
|
-
logger.info(request_id)
|
97
|
-
end
|
98
|
-
|
99
|
-
def log_processing_for_parameters
|
100
|
-
parameters = respond_to?(:filter_parameters) ? filter_parameters(params) : params.dup
|
101
|
-
parameters = parameters.except!(:controller, :action, :format, :_method)
|
102
|
-
|
103
|
-
logger.info " Parameters: #{parameters.inspect}" unless parameters.empty?
|
104
|
-
end
|
105
|
-
end
|
106
|
-
end
|