rack-auth-cookie 0.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/CHANGES +2 -0
- data/MANIFEST +7 -0
- data/README +32 -0
- data/Rakefile +54 -0
- data/lib/rack/auth/cookie.rb +100 -0
- data/rack-auth-cookie.gemspec +21 -0
- data/test/test_rack_auth_cookie.rb +18 -0
- metadata +73 -0
data/CHANGES
ADDED
data/MANIFEST
ADDED
data/README
ADDED
@@ -0,0 +1,32 @@
|
|
1
|
+
= Description
|
2
|
+
The rack-cookie library is a Rack library that uses a cookie as a token to
|
3
|
+
authenticate requests from users that have authenticated earlier using some
|
4
|
+
other way.
|
5
|
+
|
6
|
+
= Prerequisites
|
7
|
+
rack 1.0.0 or later
|
8
|
+
|
9
|
+
= Usage
|
10
|
+
use "Rack::Auth::Cookie", :secret => "foo", :cookie_name => "my_authentication_cookie"
|
11
|
+
|
12
|
+
= Default Fields
|
13
|
+
The default value for cookie_name is "auth_token"
|
14
|
+
|
15
|
+
= Details
|
16
|
+
The "secret" option works exactly as in Rails session cookies. This should be
|
17
|
+
set to a hard-to-guess value (not "foo"!) to protect against cookie forgery.
|
18
|
+
|
19
|
+
This rack library only handles requests that contain a cookie named "auth_token"
|
20
|
+
(or whatever name was passed as the :cookie_name option). If that is not present,
|
21
|
+
the request is forwarded normally with no changes to the environment.
|
22
|
+
|
23
|
+
If the cookie is detected, then it is checked for validity. If valid, then the
|
24
|
+
value for 'AUTH_USER' is copied from the cookie data into the environment. If
|
25
|
+
invalid, then env['AUTH_USER'] is deleted and env['AUTH_FAIL'] is set to an error message explaining what went wrong.
|
26
|
+
|
27
|
+
Note that if env['AUTH_USER'] or env['AUTH_FAIL'] are already set, then the
|
28
|
+
request is forwarded normally with no changes to the environment.
|
29
|
+
|
30
|
+
= Authors
|
31
|
+
Daniel Berger
|
32
|
+
Charlie O'Keefe
|
data/Rakefile
ADDED
@@ -0,0 +1,54 @@
|
|
1
|
+
require 'rake'
|
2
|
+
require 'rake/testtask'
|
3
|
+
require 'rbconfig'
|
4
|
+
|
5
|
+
desc 'Install the rack-auth-cookie library (non-gem)'
|
6
|
+
task :install do
|
7
|
+
dir = File.join(CONFIG['sitelibdir'], 'rack', 'auth')
|
8
|
+
FileUtils.mkdir_p(dir) unless File.exists?(dir)
|
9
|
+
file = 'lib/rack/auth/cookie.rb'
|
10
|
+
FileUtils.cp_r(file, dir, :verbose => true)
|
11
|
+
end
|
12
|
+
|
13
|
+
desc 'Build the gem'
|
14
|
+
task :gem do
|
15
|
+
spec = eval(IO.read('rack-auth-cookie.gemspec'))
|
16
|
+
Gem::Builder.new(spec).build
|
17
|
+
end
|
18
|
+
|
19
|
+
desc 'Install the rack-auth-cookie library as a gem'
|
20
|
+
task :install_gem => [:gem] do
|
21
|
+
file = Dir["*.gem"].first
|
22
|
+
sh "gem install #{file}"
|
23
|
+
end
|
24
|
+
|
25
|
+
desc 'Export the git archive to a .zip, .gz and .bz2 file in your home directory'
|
26
|
+
task :export, :output_file do |t, args|
|
27
|
+
file = args[:output_file]
|
28
|
+
|
29
|
+
sh "git archive --prefix #{file}/ --output #{ENV['HOME']}/#{file}.tar master"
|
30
|
+
|
31
|
+
Dir.chdir(ENV['HOME']) do
|
32
|
+
sh "gzip -f #{ENV['HOME']}/#{file}.tar"
|
33
|
+
end
|
34
|
+
|
35
|
+
sh "git archive --prefix #{file}/ --output #{ENV['HOME']}/#{file}.tar master"
|
36
|
+
|
37
|
+
Dir.chdir(ENV['HOME']) do
|
38
|
+
sh "bzip2 -f #{ENV['HOME']}/#{file}.tar"
|
39
|
+
end
|
40
|
+
|
41
|
+
sh "git archive --prefix #{file}/ --output #{ENV['HOME']}/#{file}.zip --format zip master"
|
42
|
+
|
43
|
+
Dir.chdir(ENV['HOME']) do
|
44
|
+
sh "unzip #{file}.zip"
|
45
|
+
Dir.chdir(file) do
|
46
|
+
sh "rake gem"
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
Rake::TestTask.new do |t|
|
52
|
+
t.verbose = true
|
53
|
+
t.warning = true
|
54
|
+
end
|
@@ -0,0 +1,100 @@
|
|
1
|
+
require 'openssl'
|
2
|
+
require 'rack/request'
|
3
|
+
|
4
|
+
module Rack
|
5
|
+
module Auth
|
6
|
+
class Cookie
|
7
|
+
# Creates a new Rack::Auth::Cookie object. The +cookie_name+ param gives the
|
8
|
+
# name of the cookie used to authenticate the requestor. The default is
|
9
|
+
# 'auth_token'.
|
10
|
+
#
|
11
|
+
def initialize(app, options = {})
|
12
|
+
@app = app
|
13
|
+
@@secret = options[:secret]
|
14
|
+
@@cookie_name = options[:cookie_name] || "auth_token"
|
15
|
+
@@env = {}
|
16
|
+
end
|
17
|
+
|
18
|
+
# The call method we've defined first checks to see if AUTH_USER or
|
19
|
+
# AUTH_FAIL are set in the environment. If either is set, we assume that
|
20
|
+
# the request has already either passed or failed authentication and move on.
|
21
|
+
#
|
22
|
+
# If neither is set, we check for the cookie with the name we've been
|
23
|
+
# configured to use. If present, we attempt to authenticate the user using
|
24
|
+
# the cookie. If successful then AUTH_USER is set to the username.
|
25
|
+
#
|
26
|
+
# If unsuccessful then AUTH_USER is not set and AUTH_FAIL is set to an
|
27
|
+
# appropriate error message.
|
28
|
+
#
|
29
|
+
# It is then up to the application to check for the presence of AUTH_USER
|
30
|
+
# and/or AUTH_FAIL and act as necessary.
|
31
|
+
#
|
32
|
+
def call(env)
|
33
|
+
|
34
|
+
# Do not authenticate if either one of these is set
|
35
|
+
if env['AUTH_USER'] || env['AUTH_FAIL']
|
36
|
+
return @app.call(env)
|
37
|
+
end
|
38
|
+
|
39
|
+
request = Rack::Request.new(env)
|
40
|
+
|
41
|
+
# Only authenticate if there's a cookie in the request named @cookie_name
|
42
|
+
unless request.cookies.has_key?(@@cookie_name)
|
43
|
+
return @app.call(env)
|
44
|
+
end
|
45
|
+
|
46
|
+
begin
|
47
|
+
# Separate the cookie data and the digest
|
48
|
+
cookie_with_digest = request.cookies[@@cookie_name]
|
49
|
+
cookie_data, digest = cookie_with_digest.split("--")
|
50
|
+
|
51
|
+
# Make sure the cookie hasn't been tampered with
|
52
|
+
unless digest == self.class.generate_hmac(cookie_data)
|
53
|
+
env['AUTH_FAIL'] = "Invalid cookie digest!"
|
54
|
+
return @app.call(env)
|
55
|
+
end
|
56
|
+
|
57
|
+
# Unpack the cookie data back to a hash
|
58
|
+
begin
|
59
|
+
cookie_data = cookie_data.unpack("m*").first
|
60
|
+
cookie_data = Marshal.load(cookie_data)
|
61
|
+
rescue
|
62
|
+
env['AUTH_FAIL'] = "Unable to read cookie!"
|
63
|
+
return @app.call(env)
|
64
|
+
end
|
65
|
+
|
66
|
+
# Put the values from the hash into the environment
|
67
|
+
env['AUTH_USER'] = cookie_data['AUTH_USER']
|
68
|
+
|
69
|
+
env['AUTH_TYPE'] = "Cookie"
|
70
|
+
rescue => err
|
71
|
+
env.delete('AUTH_USER')
|
72
|
+
env['AUTH_FAIL'] = "Unexpected failure during Cookie authentication"
|
73
|
+
end
|
74
|
+
|
75
|
+
@app.call(env)
|
76
|
+
end
|
77
|
+
|
78
|
+
def self.cookie_name
|
79
|
+
@@cookie_name
|
80
|
+
end
|
81
|
+
|
82
|
+
def self.create_auth_token(env)
|
83
|
+
# Copy relevant auth info for storage in a token
|
84
|
+
auth_info = Hash.new
|
85
|
+
auth_info['AUTH_USER'] = env['AUTH_USER']
|
86
|
+
|
87
|
+
# Pack the auth_info hash for cookie storage
|
88
|
+
cookie_data = Marshal.dump(auth_info)
|
89
|
+
cookie_data = [cookie_data].pack("m*")
|
90
|
+
|
91
|
+
# Add a digest value to cookie_data to prevent tampering
|
92
|
+
"#{cookie_data}--#{self.generate_hmac(cookie_data)}"
|
93
|
+
end
|
94
|
+
|
95
|
+
def self.generate_hmac(data)
|
96
|
+
OpenSSL::HMAC.hexdigest(OpenSSL::Digest::SHA1.new, @@secret, data)
|
97
|
+
end
|
98
|
+
end
|
99
|
+
end
|
100
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
|
3
|
+
Gem::Specification.new do |gem|
|
4
|
+
gem.name = 'rack-auth-cookie'
|
5
|
+
gem.version = '0.1.0'
|
6
|
+
gem.authors = ["Daniel Berger", "Charlie O'Keefe"]
|
7
|
+
gem.email = 'cokeefe@globe.gov'
|
8
|
+
gem.homepage = 'http://www.github.com/charlieok/rack-auth-cookie'
|
9
|
+
gem.summary = 'A Rack library that authenticates requests using a cookie'
|
10
|
+
gem.test_file = 'test/test_rack_auth_cookie.rb'
|
11
|
+
gem.files = Dir['**/*'].delete_if{ |item| item.include?('git') }
|
12
|
+
|
13
|
+
gem.extra_rdoc_files = ['CHANGES', 'README', 'MANIFEST']
|
14
|
+
|
15
|
+
gem.add_dependency('rack', '>= 1.0.0')
|
16
|
+
|
17
|
+
gem.description = <<-EOF
|
18
|
+
The rack-auth-cookie library provides a Rack middleware interface for
|
19
|
+
authenticating users using a cookie
|
20
|
+
EOF
|
21
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
require 'test/unit'
|
2
|
+
require 'rack/auth/cookie'
|
3
|
+
|
4
|
+
class TC_Rack_Auth_Cookie < Test::Unit::TestCase
|
5
|
+
def setup
|
6
|
+
@app = 1 # Placeholder
|
7
|
+
@env = 1 # Placeholder
|
8
|
+
@rack = Rack::Auth::Cookie.new(@app)
|
9
|
+
end
|
10
|
+
|
11
|
+
def test_constructor_basic
|
12
|
+
assert_nothing_raised{ Rack::Auth::Cookie.new(@app) }
|
13
|
+
end
|
14
|
+
|
15
|
+
def teardown
|
16
|
+
@rack = nil
|
17
|
+
end
|
18
|
+
end
|
metadata
ADDED
@@ -0,0 +1,73 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: rack-auth-cookie
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Daniel Berger
|
8
|
+
- Charlie O'Keefe
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
|
13
|
+
date: 2009-12-17 00:00:00 -07:00
|
14
|
+
default_executable:
|
15
|
+
dependencies:
|
16
|
+
- !ruby/object:Gem::Dependency
|
17
|
+
name: rack
|
18
|
+
type: :runtime
|
19
|
+
version_requirement:
|
20
|
+
version_requirements: !ruby/object:Gem::Requirement
|
21
|
+
requirements:
|
22
|
+
- - ">="
|
23
|
+
- !ruby/object:Gem::Version
|
24
|
+
version: 1.0.0
|
25
|
+
version:
|
26
|
+
description: " The rack-auth-cookie library provides a Rack middleware interface for\n authenticating users using a cookie\n"
|
27
|
+
email: cokeefe@globe.gov
|
28
|
+
executables: []
|
29
|
+
|
30
|
+
extensions: []
|
31
|
+
|
32
|
+
extra_rdoc_files:
|
33
|
+
- CHANGES
|
34
|
+
- README
|
35
|
+
- MANIFEST
|
36
|
+
files:
|
37
|
+
- CHANGES
|
38
|
+
- lib/rack/auth/cookie.rb
|
39
|
+
- MANIFEST
|
40
|
+
- rack-auth-cookie.gemspec
|
41
|
+
- Rakefile
|
42
|
+
- README
|
43
|
+
- test/test_rack_auth_cookie.rb
|
44
|
+
has_rdoc: true
|
45
|
+
homepage: http://www.github.com/charlieok/rack-auth-cookie
|
46
|
+
licenses: []
|
47
|
+
|
48
|
+
post_install_message:
|
49
|
+
rdoc_options: []
|
50
|
+
|
51
|
+
require_paths:
|
52
|
+
- lib
|
53
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
54
|
+
requirements:
|
55
|
+
- - ">="
|
56
|
+
- !ruby/object:Gem::Version
|
57
|
+
version: "0"
|
58
|
+
version:
|
59
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
60
|
+
requirements:
|
61
|
+
- - ">="
|
62
|
+
- !ruby/object:Gem::Version
|
63
|
+
version: "0"
|
64
|
+
version:
|
65
|
+
requirements: []
|
66
|
+
|
67
|
+
rubyforge_project:
|
68
|
+
rubygems_version: 1.3.5
|
69
|
+
signing_key:
|
70
|
+
specification_version: 3
|
71
|
+
summary: A Rack library that authenticates requests using a cookie
|
72
|
+
test_files:
|
73
|
+
- test/test_rack_auth_cookie.rb
|