has_global_session 1.0 → 1.1.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -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
@@ -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
- module Configuration
48
- # Reader for the environment module-attribute.
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
- # value(String):: Absolute path to configuration file
58
+ # config_File(String):: Absolute path to the configuration file
59
+ # environment(String):: Config file section from which
73
60
  #
74
- # === Return
75
- # env(String):: The new path to the configuration file
76
- def self.config_file=(value); @config_file= value; end
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
- # name(Type):: Description
77
+ # key(String):: Name of configuration element to retrieve
84
78
  #
85
79
  # === Return
86
- # name(Type):: Description
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 self.validate # :nodoc
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 self.get(key, validated) # :nodoc
112
- unless @config
113
- raise MissingConfiguration, "config_file is nil; cannot read configuration" unless config_file
114
- raise MissingConfiguration, "environment is nil; must be specified" unless environment
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 = Configuration['authority'])
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
- Configuration['trust'].include?(authority)
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
- @schema_signed = Set.new((Configuration['attributes']['signed']))
33
- @schema_insecure = Set.new((Configuration['attributes']['insecure']))
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 = Configuration['timeout'].to_i.minutes.from_now.utc
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
@@ -1,4 +1,5 @@
1
1
  basedir = File.dirname(__FILE__)
2
2
 
3
3
  #Require the files necessary for Rails integration
4
+ require File.join(basedir, 'rails', 'action_controller_class_methods')
4
5
  require File.join(basedir, 'rails', 'action_controller_instance_methods')
@@ -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 Configuration['integrated'] && @global_session
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 = Configuration['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 = Configuration['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 = Configuration['cookie']['name']
109
- domain = Configuration['cookie']['domain'] || request.env['SERVER_NAME']
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 = Configuration['ephemeral'] ? nil : @global_session.expired_at
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 = Configuration['directory'])
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
- # Tie the Configuration module to Rails' filesystem structure
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
- def self.has_global_session
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: 15
4
+ hash: 19
5
5
  prerelease: false
6
6
  segments:
7
7
  - 1
8
+ - 1
8
9
  - 0
9
- version: "1.0"
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