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