-
Notifications
You must be signed in to change notification settings - Fork 1
/
basic_authentication.rb
65 lines (64 loc) · 2.56 KB
/
basic_authentication.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
module Camping #:nodoc:
# Camping::BasicAuth can be mixed into a camping application to get Basic Authentication support
# in the application. The module defines a <tt>service</tt> method that only continues the
# request chain when proper credentials are given.
#
# == Getting Started
#
# To activate Basic Authentication for your application:
#
# 1. <tt>require 'basic_autentication'</tt> (make sure it's in the ruby search path)
# 2. Mixin the module: <tt>module YourApp; include Camping::BasicAuth end</tt>. If there are
# more modules included into you application which wrap the <tt>service</tt> method, make sure
# BasicAuth is the first. This way basic authentication will always be performed before
# running other application code.
# 3. Define an <tt>authenticate</tt> method on your application module that takes a username
# and password. The method should return true when the username and password are correct.
# Examples:
#
# module Blog
# def authenticate(u, p)
# [u,p] == ['admin','flapper30]
# end
# module_function :authenticate
# end
#
# or
#
# module Wiki
# def authenticate(u, p)
# Models::User.find_by_username_and_password u, p
# end
# module_function :authenticate
# end
#
# 4. <tt>service</tt> sets <tt>@username</tt> to the username of the person who logged in.
module BasicAuth
# Reads the username and password from the headers and returns them.
def credentials
if d = %w{REDIRECT_X_HTTP_AUTHORIZATION X-HTTP_AUTHORIZATION HTTP_AUTHORIZATION}.inject([]) \
{ |d,h| env.has_key?(h) ? env[h].to_s.split : d }
return Base64.decode64(d[1]).split(':')[0..1] if d[0] == 'Basic'
end
end
# The <tt>service</tt> method, when mixed into your application module, wraps around the
# <tt>service</tt> method defined by Camping. It halts execution of the controllers when
# your <tt>authenticate</tt> method returns false. See the module documentation how to
# define your own <tt>authenticate</tt> method.
def service(*a)
@username, password = credentials
app = self.class.name.gsub(/^(\w+)::.+$/, '\1')
if Kernel.const_get(app).authenticate @username, password
s = super(*a)
else
@status = 401
@headers['Content-type'] = 'text/plain'
@headers['Status'] = 'Unauthorized'
@headers['WWW-Authenticate'] = "Basic realm=\"#{app}\""
@body = 'Unauthorized'
s = self
end
s
end
end
end