aboutsummaryrefslogtreecommitdiffstats
path: root/actionpack/test
diff options
context:
space:
mode:
authorGregg Kellogg <gregg@Gregg-Kelloggs-MacBook-Pro-24.local>2009-01-29 16:00:07 +0000
committerPratik Naik <pratiknaik@gmail.com>2009-01-29 16:01:59 +0000
commit306cc2b920203cfa51cee82d2fc452484efc72f8 (patch)
treef7bcc99b43765b6299c797dc44c9c7b0263d6394 /actionpack/test
parente6493eb9b76de73afef2706493efd090dfff4ecc (diff)
downloadrails-306cc2b920203cfa51cee82d2fc452484efc72f8.tar.gz
rails-306cc2b920203cfa51cee82d2fc452484efc72f8.tar.bz2
rails-306cc2b920203cfa51cee82d2fc452484efc72f8.zip
Implement HTTP Digest authentication. [#1230 state:resolved] [Gregg Kellogg, Pratik Naik]
Signed-off-by: Pratik Naik <pratiknaik@gmail.com>
Diffstat (limited to 'actionpack/test')
-rw-r--r--actionpack/test/controller/http_digest_authentication_test.rb130
1 files changed, 130 insertions, 0 deletions
diff --git a/actionpack/test/controller/http_digest_authentication_test.rb b/actionpack/test/controller/http_digest_authentication_test.rb
new file mode 100644
index 0000000000..59f7a403b5
--- /dev/null
+++ b/actionpack/test/controller/http_digest_authentication_test.rb
@@ -0,0 +1,130 @@
+require 'abstract_unit'
+
+class HttpDigestAuthenticationTest < ActionController::TestCase
+ class DummyDigestController < ActionController::Base
+ before_filter :authenticate, :only => :index
+ before_filter :authenticate_with_request, :only => :display
+
+ USERS = { 'lifo' => 'world', 'pretty' => 'please' }
+
+ def index
+ render :text => "Hello Secret"
+ end
+
+ def display
+ render :text => 'Definitely Maybe'
+ end
+
+ private
+
+ def authenticate
+ authenticate_or_request_with_http_digest("SuperSecret") do |username|
+ # Return the password
+ USERS[username]
+ end
+ end
+
+ def authenticate_with_request
+ if authenticate_with_http_digest("SuperSecret") { |username| USERS[username] }
+ @logged_in = true
+ else
+ request_http_digest_authentication("SuperSecret", "Authentication Failed")
+ end
+ end
+ end
+
+ AUTH_HEADERS = ['HTTP_AUTHORIZATION', 'X-HTTP_AUTHORIZATION', 'X_HTTP_AUTHORIZATION', 'REDIRECT_X_HTTP_AUTHORIZATION']
+
+ tests DummyDigestController
+
+ AUTH_HEADERS.each do |header|
+ test "successful authentication with #{header.downcase}" do
+ @request.env[header] = encode_credentials(:username => 'lifo', :password => 'world')
+ get :index
+
+ assert_response :success
+ assert_equal 'Hello Secret', @response.body, "Authentication failed for request header #{header}"
+ end
+ end
+
+ AUTH_HEADERS.each do |header|
+ test "unsuccessful authentication with #{header.downcase}" do
+ @request.env[header] = encode_credentials(:username => 'h4x0r', :password => 'world')
+ get :index
+
+ assert_response :unauthorized
+ assert_equal "HTTP Digest: Access denied.\n", @response.body, "Authentication didn't fail for request header #{header}"
+ end
+ end
+
+ test "authentication request without credential" do
+ get :display
+
+ assert_response :unauthorized
+ assert_equal "Authentication Failed", @response.body
+ credentials = decode_credentials(@response.headers['WWW-Authenticate'])
+ assert_equal 'SuperSecret', credentials[:realm]
+ end
+
+ test "authentication request with invalid password" do
+ @request.env['HTTP_AUTHORIZATION'] = encode_credentials(:username => 'pretty', :password => 'foo')
+ get :display
+
+ assert_response :unauthorized
+ assert_equal "Authentication Failed", @response.body
+ end
+
+ test "authentication request with invalid nonce" do
+ @request.env['HTTP_AUTHORIZATION'] = encode_credentials(:username => 'pretty', :password => 'please', :nonce => "xxyyzz")
+ get :display
+
+ assert_response :unauthorized
+ assert_equal "Authentication Failed", @response.body
+ end
+
+ test "authentication request with invalid opaque" do
+ @request.env['HTTP_AUTHORIZATION'] = encode_credentials(:username => 'pretty', :password => 'foo', :opaque => "xxyyzz")
+ get :display
+
+ assert_response :unauthorized
+ assert_equal "Authentication Failed", @response.body
+ end
+
+ test "authentication request with invalid realm" do
+ @request.env['HTTP_AUTHORIZATION'] = encode_credentials(:username => 'pretty', :password => 'foo', :realm => "NotSecret")
+ get :display
+
+ assert_response :unauthorized
+ assert_equal "Authentication Failed", @response.body
+ end
+
+ test "authentication request with valid credential" do
+ @request.env['HTTP_AUTHORIZATION'] = encode_credentials(:username => 'pretty', :password => 'please')
+ get :display
+
+ assert_response :success
+ assert assigns(:logged_in)
+ assert_equal 'Definitely Maybe', @response.body
+ end
+
+ private
+
+ def encode_credentials(options)
+ options.reverse_merge!(:nc => "00000001", :cnonce => "0a4f113b")
+ password = options.delete(:password)
+
+ # Perform unautheticated get to retrieve digest parameters to use on subsequent request
+ get :index
+
+ assert_response :unauthorized
+
+ credentials = decode_credentials(@response.headers['WWW-Authenticate'])
+ credentials.merge!(options)
+ credentials.merge!(:uri => "http://#{@request.host}#{@request.env['REQUEST_URI']}")
+ ActionController::HttpAuthentication::Digest.encode_credentials("GET", credentials, password)
+ end
+
+ def decode_credentials(header)
+ ActionController::HttpAuthentication::Digest.decode_credentials(@response.headers['WWW-Authenticate'])
+ end
+end \ No newline at end of file