Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

[ssl_requirement plugin] add unit tests and ssl_allowed option (for a…

…ctions that optionally support SSL)
  • Loading branch information...
commit aa2dded823f8a9b378c22ba0159971508918928a 1 parent 79ded84
@jamis jamis authored
Showing with 126 additions and 11 deletions.
  1. +18 −11 README
  2. +10 −0 lib/ssl_requirement.rb
  3. +98 −0 test/ssl_requirement_test.rb
View
29 README
@@ -1,11 +1,9 @@
SSL Requirement
===============
-SSL requirement adds a declarative way of specifying that certain actions should
-only be allowed to run under SSL, and if they're accessed without it, they should
-be redirected.
-
-The methods are: account_url, account_host, and account_domain.
+SSL requirement adds a declarative way of specifying that certain actions
+should only be allowed to run under SSL, and if they're accessed without it,
+they should be redirected.
Example:
@@ -15,6 +13,7 @@ Example:
class AccountController < ApplicationController
ssl_required :signup, :payment
+ ssl_allowed :index
def signup
# Non-SSL access will be redirected to SSL
@@ -23,14 +22,22 @@ Example:
def payment
# Non-SSL access will be redirected to SSL
end
+
+ def index
+ # This action will work either with or without SSL
+ end
+
+ def other
+ # SSL access will be redirected to non-SSL
+ end
end
-You can overwrite the protected method ssl_required? to rely on other things than
-just the declarative specification. Say, only premium accounts get SSL.
+You can overwrite the protected method ssl_required? to rely on other things
+than just the declarative specification. Say, only premium accounts get SSL.
-P.S.: Beware when you include the SslRequirement module. At the time of inclusion,
-it'll add the before_filter that validates the declarations. Some times you'll want to
-run other before_filters before that. They should then be declared ahead of including
-this module.
+P.S.: Beware when you include the SslRequirement module. At the time of
+inclusion, it'll add the before_filter that validates the declarations. Some
+times you'll want to run other before_filters before that. They should then be
+declared ahead of including this module.
Copyright (c) 2005 David Heinemeier Hansson, released under the MIT license
View
10 lib/ssl_requirement.rb
@@ -29,6 +29,10 @@ module ClassMethods
def ssl_required(*actions)
write_inheritable_array(:ssl_required_actions, actions)
end
+
+ def ssl_allowed(*actions)
+ write_inheritable_array(:ssl_allowed_actions, actions)
+ end
end
protected
@@ -36,9 +40,15 @@ def ssl_required(*actions)
def ssl_required?
(self.class.read_inheritable_attribute(:ssl_required_actions) || []).include?(action_name.to_sym)
end
+
+ def ssl_allowed?
+ (self.class.read_inheritable_attribute(:ssl_allowed_actions) || []).include?(action_name.to_sym)
+ end
private
def ensure_proper_protocol
+ return true if ssl_allowed?
+
if ssl_required? && !request.ssl?
redirect_to "https://" + request.host + request.request_uri
return false
View
98 test/ssl_requirement_test.rb
@@ -0,0 +1,98 @@
+begin
+ require 'action_controller'
+rescue LoadError
+ if ENV['ACTIONCONTROLLER_PATH'].nil?
+ abort <<MSG
+Please set the ACTIONCONTROLLER_PATH environment variable to the directory
+containing the action_controller.rb file.
+MSG
+ else
+ $LOAD_PATH.unshift << ENV['ACTIONCONTROLLER_PATH']
+ begin
+ require 'action_controller'
+ rescue LoadError
+ abort "ActionController could not be found."
+ end
+ end
+end
+
+require 'action_controller/test_process'
+require 'test/unit'
+require "#{File.dirname(__FILE__)}/../lib/ssl_requirement"
+
+ActionController::Base.logger = nil
+ActionController::Routing::Routes.reload rescue nil
+
+class SslRequirementController < ActionController::Base
+ include SslRequirement
+
+ ssl_required :a, :b
+ ssl_allowed :c
+
+ def a
+ render :nothing => true
+ end
+
+ def b
+ render :nothing => true
+ end
+
+ def c
+ render :nothing => true
+ end
+
+ def d
+ render :nothing => true
+ end
+end
+
+class SslRequirementTest < Test::Unit::TestCase
+ def setup
+ @controller = SslRequirementController.new
+ @request = ActionController::TestRequest.new
+ @response = ActionController::TestResponse.new
+ end
+
+ def test_required_without_ssl
+ assert_not_equal "on", @request.env["HTTPS"]
+ get :a
+ assert_response :redirect
+ assert_match %r{^https://}, @response.headers['location']
+ get :b
+ assert_response :redirect
+ assert_match %r{^https://}, @response.headers['location']
+ end
+
+ def test_required_with_ssl
+ @request.env['HTTPS'] = "on"
+ get :a
+ assert_response :success
+ get :b
+ assert_response :success
+ end
+
+ def test_disallowed_without_ssl
+ assert_not_equal "on", @request.env["HTTPS"]
+ get :d
+ assert_response :success
+ end
+
+ def test_disallowed_with_ssl
+ @request.env['HTTPS'] = "on"
+ get :d
+ assert_response :redirect
+ assert_match %r{^http://}, @response.headers['location']
+ end
+
+ def test_allowed_without_ssl
+ assert_not_equal "on", @request.env["HTTPS"]
+ get :c
+ assert_response :success
+ end
+
+ def test_allowed_with_ssl
+ @request.env['HTTPS'] = "on"
+ get :c
+ assert_response :success
+ end
+end
Please sign in to comment.
Something went wrong with that request. Please try again.