has_global_session 0.8.1 → 0.8.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.
@@ -7,17 +7,18 @@ 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.8.1'
11
- s.date = '2010-06-01'
10
+ s.version = '0.8.2'
11
+ s.date = '2010-06-09'
12
12
 
13
13
  s.authors = ['Tony Spataro']
14
14
  s.email = 'code@tracker.xeger.net'
15
15
  s.homepage= 'http://github.com/xeger/has_global_session'
16
16
 
17
17
  s.summary = %q{Secure single-domain session sharing plugin for Rails.}
18
- s.description = %q{This Rails plugin allows several Rails web apps that share the same back-end user database to share session state in a cryptographically secure way, 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.}
18
+ s.description = %q{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.}
19
19
 
20
20
  s.add_runtime_dependency('uuidtools', [">= 1.0.7"])
21
+ s.add_runtime_dependency('json', [">= 1.1.7"])
21
22
 
22
23
  basedir = File.dirname(__FILE__)
23
24
  candidates = ['has_global_session.gemspec', 'init.rb', 'MIT-LICENSE', 'README.rdoc'] +
data/init.rb CHANGED
@@ -1,4 +1,4 @@
1
- # Stub to invoke real init.rb when HasGlobalSession is installed as a Rails
2
- # plugin.
1
+ # Stub to invoke real init.rb when HasGlobalSession is installed as a vendored
2
+ # Rails plugin.
3
3
  basedir = File.dirname(__FILE__)
4
4
  require File.join(basedir, 'rails', 'init')
@@ -23,6 +23,12 @@ module HasGlobalSession
23
23
  end
24
24
  end
25
25
 
26
+ def trusted_authority?(authority)
27
+ Configuration['trust'].blank? ||
28
+ authority == my_authority_name ||
29
+ Configuration['trust'].include?(authority)
30
+ end
31
+
26
32
  def invalidated_session?(uuid)
27
33
  false
28
34
  end
@@ -18,7 +18,7 @@ module HasGlobalSession
18
18
  #User presented us with a cookie; let's decrypt and verify it
19
19
  zbin = Base64.decode64(cookie)
20
20
  json = Zlib::Inflate.inflate(zbin)
21
- hash = ActiveSupport::JSON.decode(json)
21
+ hash = JSON.load(json)
22
22
  @id = hash['id']
23
23
  @created_at = Time.at(hash['tc'].to_i)
24
24
  @expires_at = Time.at(hash['te'].to_i)
@@ -31,14 +31,13 @@ module HasGlobalSession
31
31
  expected = digest(hash)
32
32
  signer = @directory.authorities[@authority]
33
33
  raise SecurityError, "Unknown signing authority #{@authority}" unless signer
34
+
34
35
  got = signer.public_decrypt(Base64.decode64(@signature))
35
36
  unless (got == expected)
36
37
  raise SecurityError, "Signature mismatch on global session cookie; tampering suspected"
37
38
  end
38
39
 
39
- unless Configuration['trust'].blank? ||
40
- @authority = @directory.my_authority_name ||
41
- Configuration['trust'].include?(@authority)
40
+ unless @directory.trusted_authority?(@authority)
42
41
  raise SecurityError, "Global sessions created by #{@authority} are not trusted"
43
42
  end
44
43
 
@@ -49,7 +48,15 @@ module HasGlobalSession
49
48
  else
50
49
  @signed = {}
51
50
  @insecure = {}
52
- @id = UUID.timestamp_create.to_s
51
+
52
+ if defined?(::UUIDTools) # UUIDTools v2
53
+ @id = ::UUIDTools::UUID.timestamp_create.to_s
54
+ elsif defined?(::UUID) # UUIDTools v1
55
+ @id = ::UUID.timestamp_create.to_s
56
+ else
57
+ raise TypeError, "Neither UUIDTools nor UUID defined; unsupported UUIDTools version?"
58
+ end
59
+
53
60
  @created_at = Time.now.utc
54
61
  @authority = @directory.my_authority_name
55
62
  renew!
@@ -88,7 +95,7 @@ module HasGlobalSession
88
95
 
89
96
  hash['s'] = signature
90
97
  hash['a'] = authority
91
- json = hash.to_json #ActiveSupport::JSON.encode(hash) -- why does this expect Data sometimes?!
98
+ json = hash.to_json
92
99
  zbin = Zlib::Deflate.deflate(json, Zlib::BEST_COMPRESSION)
93
100
  return Base64.encode64(zbin)
94
101
  end
@@ -143,21 +150,21 @@ module HasGlobalSession
143
150
  private
144
151
 
145
152
  def digest(input)
146
- canonical = ActiveSupport::JSON.encode(canonicalize(input))
153
+ canonical = canonicalize(input).to_json
147
154
  return Digest::SHA1.new().update(canonical).hexdigest
148
155
  end
149
156
 
150
157
  def canonicalize(input)
151
158
  case input
152
159
  when Hash
153
- output = ActiveSupport::OrderedHash.new
160
+ output = Array.new
154
161
  ordered_keys = input.keys.sort
155
162
  ordered_keys.each do |key|
156
- output[canonicalize(key)] = canonicalize(input[key])
163
+ output << [ canonicalize(key), canonicalize(input[key]) ]
157
164
  end
158
165
  when Array
159
166
  output = input.collect { |x| canonicalize(x) }
160
- when Numeric, String, ActiveSupport::OrderedHash
167
+ when Numeric, String
161
168
  output = input
162
169
  else
163
170
  raise TypeError, "Objects of type #{input.class.name} cannot be serialized in the global session"
@@ -166,4 +173,4 @@ module HasGlobalSession
166
173
  return output
167
174
  end
168
175
  end
169
- end
176
+ end
@@ -3,28 +3,25 @@ module HasGlobalSession
3
3
  def global_session
4
4
  return @global_session if @global_session
5
5
 
6
- begin
7
- if (klass = Configuration['directory'])
8
- klass = klass.constantize
9
- else
10
- klass = Directory
11
- end
6
+ if (klass = Configuration['directory'])
7
+ klass = klass.constantize
8
+ else
9
+ klass = Directory
10
+ end
12
11
 
13
- directory = klass.new(File.join(RAILS_ROOT, 'config', 'authorities'))
14
- cookie = cookies[Configuration['cookie']['name']]
12
+ directory = klass.new(File.join(RAILS_ROOT, 'config', 'authorities'))
13
+ cookie_name = Configuration['cookie']['name']
14
+ cookie = cookies[cookie_name]
15
15
 
16
- begin
17
- #unserialize the global session from the cookie, or
18
- #initialize a new global session if cookie == nil
19
- @global_session = GlobalSession.new(directory, cookie)
20
- rescue SessionExpired
21
- #if the cookie is present but expired, silently
22
- #initialize a new global session
23
- @global_session = GlobalSession.new(directory)
24
- end
16
+ begin
17
+ #unserialize the global session from the cookie, or
18
+ #initialize a new global session if cookie == nil
19
+ @global_session = GlobalSession.new(directory, cookie)
25
20
  rescue Exception => e
26
- cookies.delete Configuration['cookie']['name']
27
- raise e
21
+ #silently recover from any error by initializing a new global session;
22
+ #the new session will be unauthenticated.
23
+ #TODO log the error
24
+ @global_session = GlobalSession.new(directory)
28
25
  end
29
26
  end
30
27
 
@@ -36,18 +33,16 @@ module HasGlobalSession
36
33
  end
37
34
 
38
35
  def global_session_update_cookie
39
- if @global_session
40
- if @global_session.expired?
41
- options = {:value => nil,
42
- :domain => Configuration['cookie']['domain'],
43
- :expires => Time.at(0)}
44
- else
45
- options = {:value => @global_session.to_s,
46
- :domain => Configuration['cookie']['domain'],
47
- :expires => @global_session.expires_at}
48
- end
36
+ return unless @global_session
49
37
 
50
- cookies[Configuration['cookie']['name']] = options
38
+ cookie_name = Configuration['cookie']['name']
39
+ if @global_session.expired?
40
+ cookies.delete cookie_name
41
+ else
42
+ options = {:value => @global_session.to_s,
43
+ :domain => Configuration['cookie']['domain'],
44
+ :expires => @global_session.expires_at}
45
+ cookies[cookie_name] = options
51
46
  end
52
47
  end
53
48
 
data/rails/init.rb CHANGED
@@ -18,4 +18,4 @@ if File.exist?(config_file)
18
18
  after_filter :global_session_update_cookie
19
19
  end
20
20
  end
21
- end
21
+ end
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: 61
4
+ hash: 59
5
5
  prerelease: false
6
6
  segments:
7
7
  - 0
8
8
  - 8
9
- - 1
10
- version: 0.8.1
9
+ - 2
10
+ version: 0.8.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: 2010-06-01 00:00:00 -07:00
18
+ date: 2010-06-09 00:00:00 -07:00
19
19
  default_executable:
20
20
  dependencies:
21
21
  - !ruby/object:Gem::Dependency
@@ -34,7 +34,23 @@ dependencies:
34
34
  version: 1.0.7
35
35
  type: :runtime
36
36
  version_requirements: *id001
37
- description: This Rails plugin allows several Rails web apps that share the same back-end user database to share session state in a cryptographically secure way, 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.
37
+ - !ruby/object:Gem::Dependency
38
+ name: json
39
+ prerelease: false
40
+ requirement: &id002 !ruby/object:Gem::Requirement
41
+ none: false
42
+ requirements:
43
+ - - ">="
44
+ - !ruby/object:Gem::Version
45
+ hash: 29
46
+ segments:
47
+ - 1
48
+ - 1
49
+ - 7
50
+ version: 1.1.7
51
+ type: :runtime
52
+ version_requirements: *id002
53
+ 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.
38
54
  email: code@tracker.xeger.net
39
55
  executables: []
40
56
 
@@ -47,10 +63,6 @@ files:
47
63
  - README.rdoc
48
64
  - has_global_session.gemspec
49
65
  - init.rb
50
- - lib/generators/global_session_authority/global_session_authority_generator.rb
51
- - lib/generators/global_session_config/USAGE
52
- - lib/generators/global_session_config/global_session_config_generator.rb
53
- - lib/generators/global_session_config/templates/global_session.yml.erb
54
66
  - lib/has_global_session.rb
55
67
  - lib/has_global_session/configuration.rb
56
68
  - lib/has_global_session/directory.rb
@@ -1,32 +0,0 @@
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
@@ -1,2 +0,0 @@
1
- ./script/generate global_session config <DNS domain for cookie>
2
- ./script/generate global_session authority <name of authority>
@@ -1,19 +0,0 @@
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
@@ -1,42 +0,0 @@
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
-
16
- # Test/spec runs
17
- test:
18
- timeout: 900
19
- cookie:
20
- name: __<%= app_name %>_test
21
- domain: localhost
22
- trust:
23
- - test
24
-
25
- # Development mode
26
- development:
27
- timeout: 3600
28
- cookie:
29
- name: __<%= app_name %>_development
30
- domain: localhost
31
- trust:
32
- - development
33
- - production
34
-
35
- # Production mode
36
- production:
37
- timeout: 3600
38
- cookie:
39
- name: __<%= app_name %>_global
40
- domain: <%= app_domain %>
41
- trust:
42
- - production