willnet_ssl_requirement 0.1.1

Sign up to get free protection for your applications and to get access to all the features.
data/README ADDED
@@ -0,0 +1,43 @@
1
+ SSL Requirement
2
+ ===============
3
+
4
+ SSL requirement adds a declarative way of specifying that certain actions
5
+ should only be allowed to run under SSL, and if they're accessed without it,
6
+ they should be redirected.
7
+
8
+ Example:
9
+
10
+ class ApplicationController < ActiveRecord::Base
11
+ include SslRequirement
12
+ end
13
+
14
+ class AccountController < ApplicationController
15
+ ssl_required :only => [:signup, :payment]
16
+ ssl_allowed :only => :index
17
+
18
+ def signup
19
+ # Non-SSL access will be redirected to SSL
20
+ end
21
+
22
+ def payment
23
+ # Non-SSL access will be redirected to SSL
24
+ end
25
+
26
+ def index
27
+ # This action will work either with or without SSL
28
+ end
29
+
30
+ def other
31
+ # SSL access will be redirected to non-SSL
32
+ end
33
+ end
34
+
35
+ You can overwrite the protected method ssl_required? to rely on other things
36
+ than just the declarative specification. Say, only premium accounts get SSL.
37
+
38
+ P.S.: Beware when you include the SslRequirement module. At the time of
39
+ inclusion, it'll add the before_filter that validates the declarations. Some
40
+ times you'll want to run other before_filters before that. They should then be
41
+ declared ahead of including this module.
42
+
43
+ Copyright (c) 2005 David Heinemeier Hansson, released under the MIT license
@@ -0,0 +1,13 @@
1
+ begin
2
+ require 'jeweler'
3
+ Jeweler::Tasks.new do |gemspec|
4
+ gemspec.name = "willnet_ssl_requirement"
5
+ gemspec.summary = "SSL requirement adds function of ssl redirection"
6
+ gemspec.description = "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."
7
+ gemspec.email = "netwillnet@gmail.com"
8
+ gemspec.homepage = "http://github.com/willnet/ssl_requirement"
9
+ gemspec.authors = ["willnet"]
10
+ end
11
+ rescue LoadError
12
+ puts "Jeweler not available. Install it with: gem install jeweler"
13
+ end
data/VERSION ADDED
@@ -0,0 +1 @@
1
+ 0.1.1
@@ -0,0 +1,88 @@
1
+ # Copyright (c) 2005 David Heinemeier Hansson
2
+ #
3
+ # Permission is hereby granted, free of charge, to any person obtaining
4
+ # a copy of this software and associated documentation files (the
5
+ # "Software"), to deal in the Software without restriction, including
6
+ # without limitation the rights to use, copy, modify, merge, publish,
7
+ # distribute, sublicense, and/or sell copies of the Software, and to
8
+ # permit persons to whom the Software is furnished to do so, subject to
9
+ # the following conditions:
10
+ #
11
+ # The above copyright notice and this permission notice shall be
12
+ # included in all copies or substantial portions of the Software.
13
+ #
14
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ # LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
21
+ module SslRequirement
22
+ def self.included(controller)
23
+ controller.extend(ClassMethods)
24
+ controller.before_filter(:ensure_proper_protocol)
25
+ end
26
+
27
+ module ClassMethods
28
+ # Specifies that the named actions requires an SSL connection to be performed (which is enforced by ensure_proper_protocol).
29
+ def ssl_required(options = {})
30
+ write_inheritable_hash(:ssl_required_options, options)
31
+ end
32
+
33
+ def ssl_allowed(options = {})
34
+ write_inheritable_hash(:ssl_allowed_options, actions)
35
+ end
36
+ end
37
+
38
+ protected
39
+
40
+ # Returns true if the current action is supposed to run as SSL
41
+ def ssl_required?
42
+ result = false
43
+ options = self.class.read_inheritable_attribute(:ssl_required_options)
44
+ if options.nil?
45
+ # do nothing
46
+ elsif options.blank?
47
+ result = true
48
+ elsif only = options[:only]
49
+ only = only.kind_of?(Array) ? only : [only]
50
+ result = only.include?(action_name.to_sym)
51
+ elsif except = options[:except]
52
+ except = except.kind_of?(Array) ? except : [except]
53
+ result = !except.include?(action_name.to_sym)
54
+ end
55
+ result
56
+ end
57
+
58
+ def ssl_allowed?
59
+ result = false
60
+ options = self.class.read_inheritable_attribute(:ssl_allowed_options)
61
+ if options.nil?
62
+ # do nothing
63
+ elsif options.blank?
64
+ result = true
65
+ elsif only = options[:only]
66
+ only = only.kind_of?(Array) ? only : [only]
67
+ result = only.include?(action_name.to_sym)
68
+ elsif except = options[:except]
69
+ except = except.kind_of?(Array) ? except : [except]
70
+ result = !except.include?(action_name.to_sym)
71
+ end
72
+ result
73
+ end
74
+
75
+ private
76
+ def ensure_proper_protocol
77
+ return true if ssl_allowed?
78
+ if ssl_required? && !request.ssl?
79
+ redirect_to "https://" + request.host + request.fullpath
80
+ flash.keep
81
+ return false
82
+ elsif request.ssl? && !ssl_required?
83
+ redirect_to "http://" + request.host + request.fullpath
84
+ flash.keep
85
+ return false
86
+ end
87
+ end
88
+ end
@@ -0,0 +1,47 @@
1
+ # Generated by jeweler
2
+ # DO NOT EDIT THIS FILE DIRECTLY
3
+ # Instead, edit Jeweler::Tasks in Rakefile, and run the gemspec command
4
+ # -*- encoding: utf-8 -*-
5
+
6
+ Gem::Specification.new do |s|
7
+ s.name = %q{ssl_requirement}
8
+ s.version = "0.1.1"
9
+
10
+ s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
+ s.authors = ["willnet"]
12
+ s.date = %q{2010-05-27}
13
+ s.description = %q{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.}
14
+ s.email = %q{netwillnet@gmail.com}
15
+ s.extra_rdoc_files = [
16
+ "README"
17
+ ]
18
+ s.files = [
19
+ "README",
20
+ "Rakefile",
21
+ "VERSION",
22
+ "lib/ssl_requirement.rb",
23
+ "pkg/ssl_requirement-0.0.0.gem",
24
+ "pkg/ssl_requirement-0.1.1.gem",
25
+ "ssl_requirement.gemspec",
26
+ "test/ssl_requirement_test.rb"
27
+ ]
28
+ s.homepage = %q{http://github.com/willnet/ssl_requirement}
29
+ s.rdoc_options = ["--charset=UTF-8"]
30
+ s.require_paths = ["lib"]
31
+ s.rubygems_version = %q{1.3.6}
32
+ s.summary = %q{SSL requirement adds function of ssl redirection}
33
+ s.test_files = [
34
+ "test/ssl_requirement_test.rb"
35
+ ]
36
+
37
+ if s.respond_to? :specification_version then
38
+ current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
39
+ s.specification_version = 3
40
+
41
+ if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
42
+ else
43
+ end
44
+ else
45
+ end
46
+ end
47
+
@@ -0,0 +1,132 @@
1
+ begin
2
+ require 'action_controller'
3
+ rescue LoadError
4
+ if ENV['ACTIONCONTROLLER_PATH'].nil?
5
+ abort <<MSG
6
+ Please set the ACTIONCONTROLLER_PATH environment variable to the directory
7
+ containing the action_controller.rb file.
8
+ MSG
9
+ else
10
+ $LOAD_PATH.unshift << ENV['ACTIONCONTROLLER_PATH']
11
+ begin
12
+ require 'action_controller'
13
+ rescue LoadError
14
+ abort "ActionController could not be found."
15
+ end
16
+ end
17
+ end
18
+
19
+ require 'action_controller/test_process'
20
+ require 'test/unit'
21
+ require "#{File.dirname(__FILE__)}/../lib/ssl_requirement"
22
+
23
+ ActionController::Base.logger = nil
24
+ ActionController::Routing::Routes.reload rescue nil
25
+
26
+ class SslRequirementController < ActionController::Base
27
+ include SslRequirement
28
+
29
+ ssl_required :a, :b
30
+ ssl_allowed :c
31
+
32
+ def a
33
+ render :nothing => true
34
+ end
35
+
36
+ def b
37
+ render :nothing => true
38
+ end
39
+
40
+ def c
41
+ render :nothing => true
42
+ end
43
+
44
+ def d
45
+ render :nothing => true
46
+ end
47
+
48
+ def set_flash
49
+ flash[:foo] = "bar"
50
+ end
51
+ end
52
+
53
+ class SslRequirementTest < Test::Unit::TestCase
54
+ def setup
55
+ @controller = SslRequirementController.new
56
+ @request = ActionController::TestRequest.new
57
+ @response = ActionController::TestResponse.new
58
+ end
59
+
60
+ def test_redirect_to_https_preserves_flash
61
+ get :set_flash
62
+ get :b
63
+ assert_response :redirect
64
+ assert_equal "bar", flash[:foo]
65
+ end
66
+
67
+ def test_not_redirecting_to_https_does_not_preserve_the_flash
68
+ get :set_flash
69
+ get :d
70
+ assert_response :success
71
+ assert_nil flash[:foo]
72
+ end
73
+
74
+ def test_redirect_to_http_preserves_flash
75
+ get :set_flash
76
+ @request.env['HTTPS'] = "on"
77
+ get :d
78
+ assert_response :redirect
79
+ assert_equal "bar", flash[:foo]
80
+ end
81
+
82
+ def test_not_redirecting_to_http_does_not_preserve_the_flash
83
+ get :set_flash
84
+ @request.env['HTTPS'] = "on"
85
+ get :a
86
+ assert_response :success
87
+ assert_nil flash[:foo]
88
+ end
89
+
90
+ def test_required_without_ssl
91
+ assert_not_equal "on", @request.env["HTTPS"]
92
+ get :a
93
+ assert_response :redirect
94
+ assert_match %r{^https://}, @response.headers['Location']
95
+ get :b
96
+ assert_response :redirect
97
+ assert_match %r{^https://}, @response.headers['Location']
98
+ end
99
+
100
+ def test_required_with_ssl
101
+ @request.env['HTTPS'] = "on"
102
+ get :a
103
+ assert_response :success
104
+ get :b
105
+ assert_response :success
106
+ end
107
+
108
+ def test_disallowed_without_ssl
109
+ assert_not_equal "on", @request.env["HTTPS"]
110
+ get :d
111
+ assert_response :success
112
+ end
113
+
114
+ def test_disallowed_with_ssl
115
+ @request.env['HTTPS'] = "on"
116
+ get :d
117
+ assert_response :redirect
118
+ assert_match %r{^http://}, @response.headers['Location']
119
+ end
120
+
121
+ def test_allowed_without_ssl
122
+ assert_not_equal "on", @request.env["HTTPS"]
123
+ get :c
124
+ assert_response :success
125
+ end
126
+
127
+ def test_allowed_with_ssl
128
+ @request.env['HTTPS'] = "on"
129
+ get :c
130
+ assert_response :success
131
+ end
132
+ end
metadata ADDED
@@ -0,0 +1,69 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: willnet_ssl_requirement
3
+ version: !ruby/object:Gem::Version
4
+ prerelease: false
5
+ segments:
6
+ - 0
7
+ - 1
8
+ - 1
9
+ version: 0.1.1
10
+ platform: ruby
11
+ authors:
12
+ - willnet
13
+ autorequire:
14
+ bindir: bin
15
+ cert_chain: []
16
+
17
+ date: 2010-05-27 00:00:00 +09:00
18
+ default_executable:
19
+ dependencies: []
20
+
21
+ description: 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.
22
+ email: netwillnet@gmail.com
23
+ executables: []
24
+
25
+ extensions: []
26
+
27
+ extra_rdoc_files:
28
+ - README
29
+ files:
30
+ - README
31
+ - Rakefile
32
+ - VERSION
33
+ - lib/ssl_requirement.rb
34
+ - pkg/ssl_requirement-0.0.0.gem
35
+ - pkg/ssl_requirement-0.1.1.gem
36
+ - ssl_requirement.gemspec
37
+ - test/ssl_requirement_test.rb
38
+ has_rdoc: true
39
+ homepage: http://github.com/willnet/ssl_requirement
40
+ licenses: []
41
+
42
+ post_install_message:
43
+ rdoc_options:
44
+ - --charset=UTF-8
45
+ require_paths:
46
+ - lib
47
+ required_ruby_version: !ruby/object:Gem::Requirement
48
+ requirements:
49
+ - - ">="
50
+ - !ruby/object:Gem::Version
51
+ segments:
52
+ - 0
53
+ version: "0"
54
+ required_rubygems_version: !ruby/object:Gem::Requirement
55
+ requirements:
56
+ - - ">="
57
+ - !ruby/object:Gem::Version
58
+ segments:
59
+ - 0
60
+ version: "0"
61
+ requirements: []
62
+
63
+ rubyforge_project:
64
+ rubygems_version: 1.3.6
65
+ signing_key:
66
+ specification_version: 3
67
+ summary: SSL requirement adds function of ssl redirection
68
+ test_files:
69
+ - test/ssl_requirement_test.rb