Skip to content

Instantly share code, notes, and snippets.

@jkraemer
Created October 11, 2010 08:35
Show Gist options
  • Save jkraemer/620213 to your computer and use it in GitHub Desktop.
Save jkraemer/620213 to your computer and use it in GitHub Desktop.
module DigestAuthForFunctionalTests
def authenticate_with_http_digest(user = 'admin', password = 'admin', realm = 'Application')
unless ActionController::Base < ActionController::Testing
ActionController::Base.class_eval { include ActionController::Testing }
end
@controller.instance_eval %Q(
alias real_process_with_new_base_test process_with_new_base_test
def process_with_new_base_test(request, response)
secret = request.env["action_dispatch.secret_token"]
credentials = {
:uri => request.url,
:realm => "#{realm}",
:username => "#{user}",
:nonce => ActionController::HttpAuthentication::Digest.nonce(secret),
:opaque => ActionController::HttpAuthentication::Digest.opaque(secret),
}
request.env['HTTP_AUTHORIZATION'] = ActionController::HttpAuthentication::Digest.encode_credentials(
request.request_method, credentials, "#{password}", false
)
real_process_with_new_base_test(request, response)
end
)
end
end
class ActiveSupport::TestCase
include DigestAuthForFunctionalTests
# use this method to simulate requests authenticated via digest auth:
#
# test "should get show" do
# get :show
# assert_response :unauthorized
# log_in
# get :show
# assert_response :success
# end
def log_in(user = 'admin', pass = 'admin')
authenticate_with_http_digest(user, pass, Backend::BackendController::REALM)
end
end
module DigestAuthForIntegrationTests
def self.included(base)
base.class_eval do
%w(get put post delete).each do |method|
alias_method :"#{method}_without_auth", method
define_method method do |*args|
authorized_request method, *args
end
end
end
end
def username=(user)
@username = user
end
def password=(pass)
@password = pass
end
def password_is_ha1=(password_is_ha1)
@password_is_ha1 = password_is_ha1
end
def authorized_request(method, path, parameters = {})
http_method = method.to_s.upcase
unless @digest_auth_credentials
# make unauthorized request to get the challenge
send :"#{method}_without_auth", path, parameters
assert_response :unauthorized
@digest_auth_credentials = ActionController::HttpAuthentication::Digest.decode_credentials(response.headers['WWW-Authenticate'])
end
credentials = @digest_auth_credentials.merge(:username => @username, :uri => path)
encoded_credentials = ActionController::HttpAuthentication::Digest.encode_credentials(http_method, credentials,
@password, @password_is_ha1)
send :"#{method}_without_auth", path, parameters, { 'HTTP_AUTHORIZATION' => encoded_credentials }
@digest_auth_credentials = nil if response.status == 401
end
end
class ActionDispatch::IntegrationTest
# Use this method to open an authenticated session:
#
# test "should login via digest auth" do
# get '/'
# assert_response :success
# get '/backend'
# assert_response :unauthorized
#
# s = login_with_digest_auth 'admin', 'secret'
# s.get '/backend'
# s.assert_response :success
# end
def login_with_digest_auth(username, password, password_is_ha1 = false)
open_session do |sess|
class << sess
include DigestAuthForIntegrationTests
end
sess.username = username
sess.password = password
sess.password_is_ha1 = password_is_ha1
end
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment