rack_hashed_cookie_session 0.0.2

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,23 @@
1
+ = LICENSE
2
+
3
+ (The MIT License)
4
+
5
+ Copyright (c) 2008, 2009 Emanuele Vicentini
6
+
7
+ Permission is hereby granted, free of charge, to any person obtaining a copy
8
+ of this software and associated documentation files (the 'Software'), to deal
9
+ in the Software without restriction, including without limitation the rights
10
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11
+ copies of the Software, and to permit persons to whom the Software is
12
+ furnished to do so, subject to the following conditions:
13
+
14
+ The above copyright notice and this permission notice shall be included in all
15
+ copies or substantial portions of the Software.
16
+
17
+ THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
23
+ SOFTWARE.
@@ -0,0 +1,6 @@
1
+ lib/rack/session/hashed_cookie.rb
2
+ LICENSE.rdoc
3
+ Manifest
4
+ rack_hashed_cookie_session.gemspec
5
+ Rakefile
6
+ README.rdoc
@@ -0,0 +1,48 @@
1
+ = Rack's hashed cookie-based session store
2
+
3
+ Rack::Session::HashedCookie is just a simple port to Rack of the Action
4
+ Controller's cookie-based session store. All the praises to the Rails team,
5
+ all the blames to me.
6
+
7
+ Remember that the session's content is just hashed to ensure that nobody will
8
+ tamper with it, so do not store sensitive data in it.
9
+
10
+ == Basic usage
11
+
12
+ First, install it with:
13
+
14
+ $ sudo gem install rack_hashed_cookie_session
15
+
16
+ Here is how I use it with Sinatra. A rackup-file, a bit spiced up:
17
+
18
+ require 'rubygems'
19
+ require 'sinatra'
20
+ require 'rack/session/hashed_cookie'
21
+
22
+ root_dir = File.dirname(__FILE__)
23
+
24
+ Sinatra::Application.default_options.merge!(
25
+ :views => File.join(root_dir, 'views'),
26
+ :app_file => File.join(root_dir, 'app.rb'),
27
+ :run => false,
28
+ # Explicitly turn off standard cookie session store.
29
+ :sessions => false,
30
+ :env => ENV['RACK_ENV'].nil? ? :development : ENV['RACK_ENV'].to_sym
31
+ )
32
+
33
+ use Rack::Session::HashedCookie, :secret => 'my long, difficultly guessable secret'
34
+
35
+ run Sinatra.application
36
+
37
+ The Sinatra application will use the session normally:
38
+
39
+ get '/' do
40
+ session['user_id'] = 123456
41
+ session['just_a_string'] = 'Hello world!'
42
+ erb :show_the_session
43
+ end
44
+
45
+ template :show_the_session do
46
+ "Hi! Reload the page to see the session:<br>
47
+ <%= session.inspect %>"
48
+ end
@@ -0,0 +1,15 @@
1
+ require 'rubygems'
2
+ require 'echoe'
3
+
4
+ Echoe.new('rack_hashed_cookie_session', '0.0.2') do |s|
5
+ s.author = 'Emanuele Vicentini'
6
+ s.email = 'emanuele.vicentini@gmail.com'
7
+ s.summary = 'Hashed cookie-based session store for Rack'
8
+ s.runtime_dependencies = ['rack']
9
+ s.need_tar_gz = false
10
+ s.project = 'rackhcs'
11
+ s.gemspec_format = :yaml
12
+ s.retain_gemspec = true
13
+ s.rdoc_pattern = /^README|^LICENSE/
14
+ s.url = 'http://github.com/baldowl/rack_hashed_cookie_session'
15
+ end
@@ -0,0 +1,101 @@
1
+ require 'openssl'
2
+
3
+ module Rack
4
+ module Session
5
+ # Port of Action Controller's cookie-based session store (Copyright (c)
6
+ # 2004-2008 David Heinemeier Hansson).
7
+ #
8
+ # Rack::Session::HashedCookie provides simple cookie based session
9
+ # management. The session is a Ruby Hash stored as base64 encoded
10
+ # marshalled data set to :key (default: rack.session).
11
+ #
12
+ # Example:
13
+ #
14
+ # use Rack::Session::Cookie, :key => 'rack.session',
15
+ # :domain => 'foo.com',
16
+ # :path => '/',
17
+ # :expire_after => 2592000,
18
+ # :digest => 'SHA256',
19
+ # :secret => 'my long secret string'
20
+ #
21
+ # All parameters but :secret are optional.
22
+
23
+ class HashedCookie < Cookie
24
+ # Cookies can typically store 4096 bytes.
25
+ MAX = 4096
26
+ SECRET_MIN_LENGTH = 30 # characters
27
+
28
+ def initialize(app, options = {})
29
+ @secret = options.delete(:secret)
30
+ @digest = options.delete(:digest) || 'SHA1'
31
+ super
32
+ ensure_secret_secure(@secret)
33
+ end
34
+
35
+ private
36
+
37
+ # To prevent users from using something insecure like "Password" we make
38
+ # sure that the secret they've provided is at least 30 characters in
39
+ # length.
40
+ def ensure_secret_secure(secret)
41
+ # There's no way we can do this check if they've provided a proc for
42
+ # the secret.
43
+ return true if secret.is_a?(Proc)
44
+
45
+ if secret.nil? || secret.empty? || secret !~ /\S/
46
+ raise ArgumentError, "A secret is required to generate an integrity hash for cookie session data"
47
+ end
48
+
49
+ if secret.length < SECRET_MIN_LENGTH
50
+ raise ArgumentError, %Q(The value you provided for :secret, "#{secret}", is shorter than the minimum length of #{SECRET_MIN_LENGTH} characters)
51
+ end
52
+ end
53
+
54
+ def generate_digest(data)
55
+ key = @secret.respond_to?(:call) ? @secret.call(@session) : @secret
56
+ OpenSSL::HMAC.hexdigest(OpenSSL::Digest::Digest.new(@digest), key, data)
57
+ end
58
+
59
+ def load_session(env)
60
+ request = Rack::Request.new(env)
61
+ session_data = request.cookies[@key]
62
+
63
+ begin
64
+ session_data, digest = session_data.split('--')
65
+ unless digest == generate_digest(session_data)
66
+ env["rack.errors"].puts("Warning! Rack::Session::HashedCookie detected tampered data in the cookie session. Content dropped.")
67
+ raise
68
+ end
69
+ session_data = session_data.unpack("m*").first
70
+ session_data = Marshal.load(session_data)
71
+ env["rack.session"] = session_data
72
+ rescue
73
+ env["rack.session"] = Hash.new
74
+ end
75
+
76
+ env["rack.session.options"] = @default_options.dup
77
+ end
78
+
79
+ def commit_session(env, status, headers, body)
80
+ session_data = Marshal.dump(env["rack.session"])
81
+ session_data = [session_data].pack("m*")
82
+
83
+ digest = generate_digest(session_data)
84
+ session_data = "#{session_data}--#{digest}"
85
+
86
+ options = env["rack.session.options"]
87
+ cookie = Hash.new
88
+ if session_data.size > (MAX - @key.size)
89
+ env["rack.errors"].puts("Warning! Rack::Session::HashedCookie data size exceeds 4K. Content dropped.")
90
+ cookie[:value] = ""
91
+ else
92
+ cookie[:value] = session_data
93
+ end
94
+ cookie[:expires] = Time.now + options[:expire_after] unless options[:expire_after].nil?
95
+ response = Rack::Response.new(body, status, headers)
96
+ response.set_cookie(@key, cookie.merge(options))
97
+ response.to_a
98
+ end
99
+ end
100
+ end
101
+ end
@@ -0,0 +1,80 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: rack_hashed_cookie_session
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.2
5
+ platform: ruby
6
+ authors:
7
+ - Emanuele Vicentini
8
+ autorequire:
9
+ bindir: bin
10
+
11
+ date: 2009-01-05 00:00:00 +01:00
12
+ default_executable:
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: rack
16
+ type: :runtime
17
+ version_requirement:
18
+ version_requirements: !ruby/object:Gem::Requirement
19
+ requirements:
20
+ - - ">="
21
+ - !ruby/object:Gem::Version
22
+ version: "0"
23
+ version:
24
+ - !ruby/object:Gem::Dependency
25
+ name: echoe
26
+ type: :development
27
+ version_requirement:
28
+ version_requirements: !ruby/object:Gem::Requirement
29
+ requirements:
30
+ - - ">="
31
+ - !ruby/object:Gem::Version
32
+ version: "0"
33
+ version:
34
+ description: Hashed cookie-based session store for Rack
35
+ email: emanuele.vicentini@gmail.com
36
+ executables: []
37
+
38
+ extensions: []
39
+
40
+ extra_rdoc_files:
41
+ - LICENSE.rdoc
42
+ - README.rdoc
43
+ files:
44
+ - lib/rack/session/hashed_cookie.rb
45
+ - LICENSE.rdoc
46
+ - Manifest
47
+ - rack_hashed_cookie_session.gemspec
48
+ - Rakefile
49
+ - README.rdoc
50
+ has_rdoc: true
51
+ homepage: http://github.com/baldowl/rack_hashed_cookie_session
52
+ post_install_message:
53
+ rdoc_options:
54
+ - --line-numbers
55
+ - --inline-source
56
+ - --title
57
+ - Rack_hashed_cookie_session
58
+ - --main
59
+ - README.rdoc
60
+ require_paths:
61
+ - lib
62
+ required_ruby_version: !ruby/object:Gem::Requirement
63
+ requirements:
64
+ - - ">="
65
+ - !ruby/object:Gem::Version
66
+ version: "0"
67
+ version:
68
+ required_rubygems_version: !ruby/object:Gem::Requirement
69
+ requirements:
70
+ - - ">="
71
+ - !ruby/object:Gem::Version
72
+ version: "1.2"
73
+ version:
74
+ requirements: []
75
+
76
+ rubyforge_project: rackhcs
77
+ rubygems_version: 1.3.1
78
+ specification_version: 2
79
+ summary: Hashed cookie-based session store for Rack
80
+ test_files: []
metadata ADDED
@@ -0,0 +1,83 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: rack_hashed_cookie_session
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.2
5
+ platform: ruby
6
+ authors:
7
+ - Emanuele Vicentini
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+
12
+ date: 2009-01-05 00:00:00 +01:00
13
+ default_executable:
14
+ dependencies:
15
+ - !ruby/object:Gem::Dependency
16
+ name: rack
17
+ type: :runtime
18
+ version_requirement:
19
+ version_requirements: !ruby/object:Gem::Requirement
20
+ requirements:
21
+ - - ">="
22
+ - !ruby/object:Gem::Version
23
+ version: "0"
24
+ version:
25
+ - !ruby/object:Gem::Dependency
26
+ name: echoe
27
+ type: :development
28
+ version_requirement:
29
+ version_requirements: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: "0"
34
+ version:
35
+ description: Hashed cookie-based session store for Rack
36
+ email: emanuele.vicentini@gmail.com
37
+ executables: []
38
+
39
+ extensions: []
40
+
41
+ extra_rdoc_files:
42
+ - LICENSE.rdoc
43
+ - README.rdoc
44
+ files:
45
+ - lib/rack/session/hashed_cookie.rb
46
+ - LICENSE.rdoc
47
+ - Manifest
48
+ - rack_hashed_cookie_session.gemspec
49
+ - Rakefile
50
+ - README.rdoc
51
+ has_rdoc: true
52
+ homepage: http://github.com/baldowl/rack_hashed_cookie_session
53
+ post_install_message:
54
+ rdoc_options:
55
+ - --line-numbers
56
+ - --inline-source
57
+ - --title
58
+ - Rack_hashed_cookie_session
59
+ - --main
60
+ - README.rdoc
61
+ require_paths:
62
+ - lib
63
+ required_ruby_version: !ruby/object:Gem::Requirement
64
+ requirements:
65
+ - - ">="
66
+ - !ruby/object:Gem::Version
67
+ version: "0"
68
+ version:
69
+ required_rubygems_version: !ruby/object:Gem::Requirement
70
+ requirements:
71
+ - - ">="
72
+ - !ruby/object:Gem::Version
73
+ version: "1.2"
74
+ version:
75
+ requirements: []
76
+
77
+ rubyforge_project: rackhcs
78
+ rubygems_version: 1.3.1
79
+ signing_key:
80
+ specification_version: 2
81
+ summary: Hashed cookie-based session store for Rack
82
+ test_files: []
83
+