has_global_session 0.8.1 → 0.8.2

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