has_global_session 1.0 → 1.1.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 +2 -6
- data/lib/has_global_session.rb +3 -0
- data/lib/has_global_session/configuration.rb +29 -46
- data/lib/has_global_session/directory.rb +5 -4
- data/lib/has_global_session/global_session.rb +4 -3
- data/lib/has_global_session/integrated_session.rb +14 -0
- data/lib/has_global_session/rails.rb +1 -0
- data/lib/has_global_session/rails/action_controller_class_methods.rb +25 -0
- data/lib/has_global_session/rails/action_controller_instance_methods.rb +16 -7
- data/rails/init.rb +3 -11
- metadata +4 -2
data/has_global_session.gemspec
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
# -*- encoding: utf-8 -*-
|
1
|
+
# -*- mode: ruby; encoding: utf-8 -*-
|
2
2
|
|
3
3
|
require 'rubygems'
|
4
4
|
|
@@ -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 = '1.0'
|
10
|
+
s.version = '1.1.0'
|
11
11
|
s.date = '2010-07-27'
|
12
12
|
|
13
13
|
s.authors = ['Tony Spataro']
|
@@ -32,7 +32,3 @@ spec = Gem::Specification.new do |s|
|
|
32
32
|
Dir['rails_generators/**/*']
|
33
33
|
s.files = candidates.sort
|
34
34
|
end
|
35
|
-
|
36
|
-
if $PROGRAM_NAME == __FILE__
|
37
|
-
Gem::Builder.new(spec).build
|
38
|
-
end
|
data/lib/has_global_session.rb
CHANGED
@@ -49,6 +49,9 @@ require 'uuidtools'
|
|
49
49
|
require 'json'
|
50
50
|
require 'active_support'
|
51
51
|
|
52
|
+
#Require Ruby library dependencies
|
53
|
+
require 'openssl'
|
54
|
+
|
52
55
|
#Require the core suite of HasGlobalSession classes and modules
|
53
56
|
basedir = File.dirname(__FILE__)
|
54
57
|
require File.join(basedir, 'has_global_session', 'configuration')
|
@@ -22,6 +22,13 @@ module HasGlobalSession
|
|
22
22
|
# * name
|
23
23
|
# * domain
|
24
24
|
#
|
25
|
+
# === Config Environments
|
26
|
+
# The operational environment of has_global_session defines which section
|
27
|
+
# of the configuration file it gets its settings from. When used with
|
28
|
+
# a web app, the environment should be set to the same environment as
|
29
|
+
# the web app. (If using Rails integration, this happens for you
|
30
|
+
# automatically.)
|
31
|
+
#
|
25
32
|
# === Environment-Specific Settings
|
26
33
|
# The top level of keys in the configuration hash are special; they provide different
|
27
34
|
# sections of settings that apply in different environments. For instance, a Rails
|
@@ -44,55 +51,38 @@ module HasGlobalSession
|
|
44
51
|
# The name and location of the config file depend on the Web framework with which
|
45
52
|
# you are integrating; see HasGlobalSession::Rails for more information.
|
46
53
|
#
|
47
|
-
|
48
|
-
#
|
49
|
-
#
|
50
|
-
# === Return
|
51
|
-
# env(String):: The current configuration environment
|
52
|
-
def self.environment; @environment; end
|
53
|
-
|
54
|
-
# Writer for the environment module-attribute.
|
55
|
-
#
|
56
|
-
# === Parameters
|
57
|
-
# value(String):: Configuration environment from which settings should be read
|
58
|
-
#
|
59
|
-
# === Return
|
60
|
-
# env(String):: The new configuration environment
|
61
|
-
def self.environment=(value); @environment = value; end
|
62
|
-
|
63
|
-
# Reader for the config_file module-attribute.
|
64
|
-
#
|
65
|
-
# === Return
|
66
|
-
# file(String):: Absolute path to configuration file
|
67
|
-
def self.config_file; @config_file; end
|
68
|
-
|
69
|
-
# Writer for the config_file module-attribute.
|
54
|
+
class Configuration
|
55
|
+
# Create a new Configuration objectt
|
70
56
|
#
|
71
57
|
# === Parameters
|
72
|
-
#
|
58
|
+
# config_File(String):: Absolute path to the configuration file
|
59
|
+
# environment(String):: Config file section from which
|
73
60
|
#
|
74
|
-
# ===
|
75
|
-
#
|
76
|
-
|
61
|
+
# === Raise
|
62
|
+
# MissingConfiguration:: if config file is missing or unreadable
|
63
|
+
# TypeError:: if config file does not contain a YAML-serialized Hash
|
64
|
+
def initialize(config_file, environment)
|
65
|
+
raise MissingConfiguration, "Missing or unreadable configuration file" unless File.readable?(config_file)
|
66
|
+
@config = YAML.load(File.read(config_file))
|
67
|
+
@environment = environment
|
68
|
+
raise TypeError, "#{config_file} must contain a Hash!" unless Hash === @config
|
69
|
+
validate
|
70
|
+
end
|
77
71
|
|
78
72
|
# Reader for configuration elements. The reader first checks
|
79
73
|
# the current environment's settings section for the named
|
80
74
|
# value; if not found, it checks the common settings section.
|
81
75
|
#
|
82
76
|
# === Parameters
|
83
|
-
#
|
77
|
+
# key(String):: Name of configuration element to retrieve
|
84
78
|
#
|
85
79
|
# === Return
|
86
|
-
#
|
87
|
-
|
88
|
-
# === Raise
|
89
|
-
# MissingConfiguration:: if config file location is unset, environment is unset, or config file is missing
|
90
|
-
# TypeError:: if config file does not contain a YAML-serialized Hash
|
91
|
-
def self.[](key)
|
80
|
+
# value(String):: the value of the configuration element
|
81
|
+
def [](key)
|
92
82
|
get(key, true)
|
93
83
|
end
|
94
84
|
|
95
|
-
def
|
85
|
+
def validate # :nodoc
|
96
86
|
['attributes/signed', 'integrated', 'cookie/name', 'timeout'].each do |path|
|
97
87
|
elements = path.split '/'
|
98
88
|
object = get(elements.shift, false)
|
@@ -108,17 +98,10 @@ module HasGlobalSession
|
|
108
98
|
|
109
99
|
private
|
110
100
|
|
111
|
-
def
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
@config = YAML.load(File.read(config_file))
|
116
|
-
raise TypeError, "#{config_file} must contain a Hash!" unless Hash === @config
|
117
|
-
validate if validated
|
118
|
-
end
|
119
|
-
if @config.has_key?(environment) &&
|
120
|
-
@config[environment].has_key?(key)
|
121
|
-
return @config[environment][key]
|
101
|
+
def get(key, validated) # :nodoc
|
102
|
+
if @config.has_key?(@environment) &&
|
103
|
+
@config[@environment].has_key?(key)
|
104
|
+
return @config[@environment][key]
|
122
105
|
else
|
123
106
|
@config['common'][key]
|
124
107
|
end
|
@@ -29,7 +29,7 @@ module HasGlobalSession
|
|
29
29
|
# at initialization time.
|
30
30
|
#
|
31
31
|
class Directory
|
32
|
-
attr_reader :authorities, :private_key, :local_authority_name
|
32
|
+
attr_reader :configuration, :authorities, :private_key, :local_authority_name
|
33
33
|
|
34
34
|
# Create a new Directory.
|
35
35
|
#
|
@@ -38,7 +38,8 @@ module HasGlobalSession
|
|
38
38
|
#
|
39
39
|
# ===Raise
|
40
40
|
# ConfigurationError:: if too many or too few keys are found, or if *.key/*.pub files are malformatted
|
41
|
-
def initialize(keystore_directory)
|
41
|
+
def initialize(configuration, keystore_directory)
|
42
|
+
@configuration = configuration
|
42
43
|
certs = Dir[File.join(keystore_directory, '*.pub')]
|
43
44
|
keys = Dir[File.join(keystore_directory, '*.key')]
|
44
45
|
raise ConfigurationError, "Excepted 0 or 1 key files, found #{keys.size}" unless [0, 1].include?(keys.size)
|
@@ -51,7 +52,7 @@ module HasGlobalSession
|
|
51
52
|
raise ConfigurationError, "Expected #{basename} to contain an RSA public key" unless @authorities[authority].public?
|
52
53
|
end
|
53
54
|
|
54
|
-
if (authority_name =
|
55
|
+
if (authority_name = @configuration['authority'])
|
55
56
|
key_file = keys.detect { |kf| kf =~ /#{authority_name}.key$/ }
|
56
57
|
raise ConfigurationError, "Key file #{authority_name}.key not found" unless key_file
|
57
58
|
@private_key = OpenSSL::PKey::RSA.new(File.read(key_file))
|
@@ -69,7 +70,7 @@ module HasGlobalSession
|
|
69
70
|
# === Return
|
70
71
|
# trusted(true|false):: whether the local system trusts sessions signed by the specified authority
|
71
72
|
def trusted_authority?(authority)
|
72
|
-
|
73
|
+
@configuration['trust'].include?(authority)
|
73
74
|
end
|
74
75
|
|
75
76
|
# Determine whether the given session UUID is valid. The default implementation only considers
|
@@ -29,8 +29,9 @@ module HasGlobalSession
|
|
29
29
|
# MalformedCookie:: if the cookie was corrupt or malformed
|
30
30
|
# SecurityError:: if signature is invalid or cookie is not signed by a trusted authority
|
31
31
|
def initialize(directory, cookie=nil, valid_signature_digest=nil)
|
32
|
-
@
|
33
|
-
@
|
32
|
+
@configuration = directory.configuration
|
33
|
+
@schema_signed = Set.new((@configuration['attributes']['signed']))
|
34
|
+
@schema_insecure = Set.new((@configuration['attributes']['insecure']))
|
34
35
|
@directory = directory
|
35
36
|
|
36
37
|
if cookie && !cookie.empty?
|
@@ -200,7 +201,7 @@ module HasGlobalSession
|
|
200
201
|
# true:: Always returns true
|
201
202
|
def renew!
|
202
203
|
authority_check
|
203
|
-
@expired_at =
|
204
|
+
@expired_at = @configuration['timeout'].to_i.minutes.from_now.utc
|
204
205
|
@dirty_secure = true
|
205
206
|
end
|
206
207
|
|
@@ -105,5 +105,19 @@ module HasGlobalSession
|
|
105
105
|
@global.each_pair(&block)
|
106
106
|
@local.each_pair(&block)
|
107
107
|
end
|
108
|
+
|
109
|
+
def respond_to?(meth) # :nodoc:
|
110
|
+
return @global.respond_to?(meth) || @local.respond_to?(meth) || super
|
111
|
+
end
|
112
|
+
|
113
|
+
def method_missing(meth, *args) # :nodoc:
|
114
|
+
if @global.respond_to?(meth)
|
115
|
+
@global.__send__(meth, *args)
|
116
|
+
elsif @local.respond_to?(meth)
|
117
|
+
@local.__send__(meth, *args)
|
118
|
+
else
|
119
|
+
super
|
120
|
+
end
|
121
|
+
end
|
108
122
|
end
|
109
123
|
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
module HasGlobalSession
|
2
|
+
module Rails
|
3
|
+
# Module that is mixed into ActionController's eigenclass; provides access to shared
|
4
|
+
# app-wide data such as the configuration object.
|
5
|
+
module ActionControllerClassMethods
|
6
|
+
def global_session_config
|
7
|
+
unless @global_session_config
|
8
|
+
config_file = File.join(RAILS_ROOT, 'config', 'global_session.yml')
|
9
|
+
@global_session_config = HasGlobalSession::Configuration.new(config_file, RAILS_ENV)
|
10
|
+
@global_session_config.config_file = config_file
|
11
|
+
end
|
12
|
+
|
13
|
+
return @global_session_config
|
14
|
+
end
|
15
|
+
|
16
|
+
def global_session_config=(config)
|
17
|
+
@global_session_config = config
|
18
|
+
end
|
19
|
+
|
20
|
+
def has_global_session
|
21
|
+
include HasGlobalSession::Rails::ActionControllerInstanceMethods
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
@@ -21,6 +21,15 @@ module HasGlobalSession
|
|
21
21
|
base.after_filter :global_session_update_cookie
|
22
22
|
end
|
23
23
|
|
24
|
+
# Shortcut accessor for global session configuration object. Simply delegates to
|
25
|
+
# the class method of the same name defined by ActionController::Base.
|
26
|
+
#
|
27
|
+
# === Return
|
28
|
+
# config(HasGlobalSession::Configuration)
|
29
|
+
def global_session_config
|
30
|
+
ActionController::Base.global_session_config
|
31
|
+
end
|
32
|
+
|
24
33
|
# Global session reader.
|
25
34
|
#
|
26
35
|
# === Return
|
@@ -35,7 +44,7 @@ module HasGlobalSession
|
|
35
44
|
# === Return
|
36
45
|
# session(IntegratedSession):: the integrated session
|
37
46
|
def session_with_global_session
|
38
|
-
if
|
47
|
+
if global_session_config['integrated'] && @global_session
|
39
48
|
unless @integrated_session &&
|
40
49
|
(@integrated_session.local == session_without_global_session) &&
|
41
50
|
(@integrated_session.global == @global_session)
|
@@ -56,7 +65,7 @@ module HasGlobalSession
|
|
56
65
|
# true:: Always returns true
|
57
66
|
def global_session_read_cookie
|
58
67
|
directory = global_session_create_directory
|
59
|
-
cookie_name =
|
68
|
+
cookie_name = global_session_config['cookie']['name']
|
60
69
|
cookie = cookies[cookie_name]
|
61
70
|
|
62
71
|
begin
|
@@ -89,7 +98,7 @@ module HasGlobalSession
|
|
89
98
|
# true:: Always returns true
|
90
99
|
def global_session_auto_renew
|
91
100
|
#Auto-renew session if needed
|
92
|
-
renew =
|
101
|
+
renew = global_session_config['renew']
|
93
102
|
if @global_session &&
|
94
103
|
renew &&
|
95
104
|
@global_session.directory.local_authority_name &&
|
@@ -105,13 +114,13 @@ module HasGlobalSession
|
|
105
114
|
# === Return
|
106
115
|
# true:: Always returns true
|
107
116
|
def global_session_update_cookie
|
108
|
-
name =
|
109
|
-
domain =
|
117
|
+
name = global_session_config['cookie']['name']
|
118
|
+
domain = global_session_config['cookie']['domain'] || request.env['SERVER_NAME']
|
110
119
|
|
111
120
|
begin
|
112
121
|
if @global_session && @global_session.valid?
|
113
122
|
value = @global_session.to_s
|
114
|
-
expires =
|
123
|
+
expires = global_session_config['ephemeral'] ? nil : @global_session.expired_at
|
115
124
|
|
116
125
|
unless (cookies[name] == value)
|
117
126
|
#Update the cookie only if its value has changed
|
@@ -172,7 +181,7 @@ module HasGlobalSession
|
|
172
181
|
private
|
173
182
|
|
174
183
|
def global_session_create_directory # :nodoc:
|
175
|
-
if (klass =
|
184
|
+
if (klass = global_session_config['directory'])
|
176
185
|
klass = klass.constantize
|
177
186
|
else
|
178
187
|
klass = Directory
|
data/rails/init.rb
CHANGED
@@ -1,21 +1,13 @@
|
|
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')
|
4
|
-
|
5
3
|
config_file = File.join(RAILS_ROOT, 'config', 'global_session.yml')
|
6
4
|
|
7
5
|
if File.exist?(config_file)
|
8
|
-
|
9
|
-
# and operating environment.
|
10
|
-
HasGlobalSession::Configuration.config_file = config_file
|
11
|
-
HasGlobalSession::Configuration.environment = RAILS_ENV
|
12
|
-
|
6
|
+
require File.join(libdir, 'has_global_session')
|
13
7
|
require File.join(libdir, 'has_global_session', 'rails')
|
14
8
|
|
15
9
|
# Enable ActionController integration.
|
16
|
-
class ActionController::Base
|
17
|
-
|
18
|
-
include HasGlobalSession::Rails::ActionControllerInstanceMethods
|
19
|
-
end
|
10
|
+
class <<ActionController::Base
|
11
|
+
include HasGlobalSession::Rails::ActionControllerClassMethods
|
20
12
|
end
|
21
13
|
end
|
metadata
CHANGED
@@ -1,12 +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: 19
|
5
5
|
prerelease: false
|
6
6
|
segments:
|
7
7
|
- 1
|
8
|
+
- 1
|
8
9
|
- 0
|
9
|
-
version:
|
10
|
+
version: 1.1.0
|
10
11
|
platform: ruby
|
11
12
|
authors:
|
12
13
|
- Tony Spataro
|
@@ -133,6 +134,7 @@ files:
|
|
133
134
|
- lib/has_global_session/global_session.rb
|
134
135
|
- lib/has_global_session/integrated_session.rb
|
135
136
|
- lib/has_global_session/rails.rb
|
137
|
+
- lib/has_global_session/rails/action_controller_class_methods.rb
|
136
138
|
- lib/has_global_session/rails/action_controller_instance_methods.rb
|
137
139
|
- rails/init.rb
|
138
140
|
- rails_generators/global_session_authority/USAGE
|