Skip to content

Commit

Permalink
Added Base.http_basic_authenticate_with to do simple http basic authe…
Browse files Browse the repository at this point in the history
…ntication with a single class method call [DHH]
  • Loading branch information
dhh committed Mar 29, 2011
1 parent aea1477 commit e2b07ee
Show file tree
Hide file tree
Showing 3 changed files with 69 additions and 14 deletions.
37 changes: 37 additions & 0 deletions actionpack/CHANGELOG
Original file line number Diff line number Diff line change
@@ -1,5 +1,42 @@
*Rails 3.1.0 (unreleased)*

* Added Base.http_basic_authenticate_with to do simple http basic authentication with a single class method call [DHH]

class PostsController < ApplicationController
USER_NAME, PASSWORD = "dhh", "secret"

before_filter :authenticate, :except => [ :index ]

def index
render :text => "Everyone can see me!"
end

def edit
render :text => "I'm only accessible if you know the password"
end

private
def authenticate
authenticate_or_request_with_http_basic do |user_name, password|
user_name == USER_NAME && password == PASSWORD
end
end
end

..can now be written as

class PostsController < ApplicationController
http_basic_authenticate_with :name => "dhh", "secret", :except => :index

def index
render :text => "Everyone can see me!"
end

def edit
render :text => "I'm only accessible if you know the password"
end
end

* Allow you to add `force_ssl` into controller to force browser to transfer data via HTTPS protocol on that particular controller. You can also specify `:only` or `:except` to specific it to particular action. [DHH and Prem Sichanugrist]

* Allow FormHelper#form_for to specify the :method as a direct option instead of through the :html hash [DHH]
Expand Down
30 changes: 16 additions & 14 deletions actionpack/lib/action_controller/metal/http_authentication.rb
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,7 @@ module HttpAuthentication
# === Simple \Basic example
#
# class PostsController < ApplicationController
# USER_NAME, PASSWORD = "dhh", "secret"
#
# before_filter :authenticate, :except => [ :index ]
# http_basic_authenticate_with :name => "dhh", "secret", :except => :index
#
# def index
# render :text => "Everyone can see me!"
Expand All @@ -19,15 +17,7 @@ module HttpAuthentication
# def edit
# render :text => "I'm only accessible if you know the password"
# end
#
# private
# def authenticate
# authenticate_or_request_with_http_basic do |user_name, password|
# user_name == USER_NAME && password == PASSWORD
# end
# end
# end
#
# end
#
# === Advanced \Basic example
#
Expand Down Expand Up @@ -115,6 +105,20 @@ module Basic
extend self

module ControllerMethods
extend ActiveSupport::Concern

module ClassMethods
def http_basic_authenticate_with(options = {})
before_filter(options.except(:name, :password, :realm)) do
authenticate_or_request_with_http_basic(options[:realm] || "Application") do
authenticate_or_request_with_http_basic do |name, password|

This comment has been minimized.

Copy link
@exviva

exviva Mar 29, 2011

Contributor

Why is it necessary to call authenticate_or_request_with_http_basic twice?

This comment has been minimized.

Copy link
@dmathieu

dmathieu Mar 29, 2011

Contributor

It's not. See Pull Request #245

This comment has been minimized.

Copy link
@dhh

dhh Mar 29, 2011

Author Member

Ha, how did I miss that? Fixed.

This comment has been minimized.

Copy link
@parndt

parndt Mar 29, 2011

Contributor

Without merging the pull request?

name == options[:name] && password == options[:password]
end
end
end
end
end

def authenticate_or_request_with_http_basic(realm = "Application", &login_procedure)
authenticate_with_http_basic(&login_procedure) || request_http_basic_authentication(realm)
end
Expand Down Expand Up @@ -378,7 +382,6 @@ def opaque(secret_key)
#
# RewriteRule ^(.*)$ dispatch.fcgi [E=X-HTTP_AUTHORIZATION:%{HTTP:Authorization},QSA,L]
module Token

extend self

module ControllerMethods
Expand Down Expand Up @@ -458,6 +461,5 @@ def authentication_request(controller, realm)
controller.__send__ :render, :text => "HTTP Token: Access denied.\n", :status => :unauthorized
end
end

end
end
16 changes: 16 additions & 0 deletions actionpack/test/controller/http_basic_authentication_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ class DummyController < ActionController::Base
before_filter :authenticate_with_request, :only => :display
before_filter :authenticate_long_credentials, :only => :show

http_basic_authenticate_with :name => "David", :password => "Goliath", :only => :search

def index
render :text => "Hello Secret"
end
Expand All @@ -17,6 +19,10 @@ def display
def show
render :text => 'Only for loooooong credentials'
end

def search
render :text => 'All inline'
end

private

Expand Down Expand Up @@ -104,6 +110,16 @@ def authenticate_long_credentials
assert assigns(:logged_in)
assert_equal 'Definitely Maybe', @response.body
end

test "authenticate with class method" do
@request.env['HTTP_AUTHORIZATION'] = encode_credentials('David', 'Goliath')
get :search
assert_response :success

@request.env['HTTP_AUTHORIZATION'] = encode_credentials('David', 'WRONG!')
get :search
assert_response :unauthorized
end

private

Expand Down

1 comment on commit e2b07ee

@dmathieu
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice ! :)

Please sign in to comment.