grosser-ssl_requirement 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
data/Gemfile ADDED
@@ -0,0 +1,2 @@
1
+ source :rubygems
2
+ gemspec
@@ -0,0 +1,55 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ grosser-ssl_requirement (0.1.0)
5
+ actionpack
6
+
7
+ GEM
8
+ remote: http://rubygems.org/
9
+ specs:
10
+ actionpack (3.1.0)
11
+ activemodel (= 3.1.0)
12
+ activesupport (= 3.1.0)
13
+ builder (~> 3.0.0)
14
+ erubis (~> 2.7.0)
15
+ i18n (~> 0.6)
16
+ rack (~> 1.3.2)
17
+ rack-cache (~> 1.0.3)
18
+ rack-mount (~> 0.8.2)
19
+ rack-test (~> 0.6.1)
20
+ sprockets (~> 2.0.0)
21
+ activemodel (3.1.0)
22
+ activesupport (= 3.1.0)
23
+ bcrypt-ruby (~> 3.0.0)
24
+ builder (~> 3.0.0)
25
+ i18n (~> 0.6)
26
+ activesupport (3.1.0)
27
+ multi_json (~> 1.0)
28
+ bcrypt-ruby (3.0.0)
29
+ builder (3.0.0)
30
+ erubis (2.7.0)
31
+ hike (1.2.1)
32
+ i18n (0.6.0)
33
+ multi_json (1.0.3)
34
+ rack (1.3.2)
35
+ rack-cache (1.0.3)
36
+ rack (>= 0.4)
37
+ rack-mount (0.8.3)
38
+ rack (>= 1.0.0)
39
+ rack-test (0.6.1)
40
+ rack (>= 1.0)
41
+ rake (0.9.2)
42
+ redgreen (1.2.2)
43
+ sprockets (2.0.0)
44
+ hike (~> 1.2)
45
+ rack (~> 1.0)
46
+ tilt (!= 1.3.0, ~> 1.1)
47
+ tilt (1.3.3)
48
+
49
+ PLATFORMS
50
+ ruby
51
+
52
+ DEPENDENCIES
53
+ grosser-ssl_requirement!
54
+ rake
55
+ redgreen
@@ -0,0 +1,88 @@
1
+ ###Fork of ssl_requirement to add
2
+
3
+ - if a action is ssl_allowed and ssl_required -- it is ssl_required
4
+ - support :all
5
+ - `ssl_required` == `ssl_required :all`
6
+ - allow attributes as array `ssl_required [:login, :register]`
7
+ - allow strings as attributes `ssl_required 'login', 'register'` / `ssl_required %w[login register]`
8
+ - running tests
9
+ - ability to overwrite ssl_host, to make custom host changes e.g. `def ssl_host; request.sll? ? 'xxx.com' : 'yyy.com';end`
10
+ - added :except option to exclude actions
11
+ - added rails3 compatibility
12
+
13
+ Install
14
+ =======
15
+ ### As Gem
16
+ ` gem install grosser-ssl_requirement `
17
+
18
+ Add to Gemfile<br/>
19
+ ` gem 'grosser-ssl_requirement', :require => 'ssl_requirement' `
20
+
21
+ ### As plugin
22
+ ` rails plugin install git://github.com/grosser/ssl_requirement.git `
23
+
24
+
25
+ SSL Requirement
26
+ ===============
27
+ - redirect https to http by default
28
+ - redirect http requests to https with `ssl_required`
29
+ - allow https and http with `ssl_allowed`
30
+
31
+ Example:
32
+
33
+ class ApplicationController < ActionController::Base
34
+ include SslRequirement
35
+ end
36
+
37
+ class AccountController < ApplicationController
38
+ ssl_required :signup, :payment
39
+ ssl_allowed :index
40
+
41
+ def signup
42
+ # Non-SSL access will be redirected to SSL
43
+ end
44
+
45
+ def payment
46
+ # Non-SSL access will be redirected to SSL
47
+ end
48
+
49
+ def index
50
+ # This action will work either with or without SSL
51
+ end
52
+
53
+ def other
54
+ # SSL access will be redirected to non-SSL
55
+ end
56
+ end
57
+
58
+ You can overwrite the protected method ssl_required? to rely on other things
59
+ than just the declarative specification. Say, only premium accounts get SSL.
60
+
61
+ When including SslRequirement it adds `before_filter :ensure_proper_protocol`.
62
+
63
+ ### Separate ssl host?
64
+ class ApplicationController < ActionController::Base
65
+ include SslRequirement
66
+
67
+ def ssl_host
68
+ Rails.env.production ? 'myhost.com' : request.host
69
+ end
70
+ end
71
+
72
+ ### No ssl in development? (not recommended, [TATFT](http://dawanda.com/product/3861630-TATFT-Mousepad-Test-all-the-fucking-time))
73
+ class ApplicationController < ActionController::Base
74
+ include SslRequirement
75
+ skip_before_filter :ensure_proper_protocol unless Rails.env.production?
76
+ end
77
+
78
+ Authors
79
+ =======
80
+
81
+ ###Original
82
+ Copyright (c) 2005 David Heinemeier Hansson, released under the MIT license
83
+
84
+ ###Additions
85
+ - [Michael Grosser](http://pragmatig.wordpress.com)
86
+ - [Johndouthat](http://github.com/johndouthat)
87
+ - [Adam Wiggins](http://adam.blog.heroku.com/)
88
+ - [Mark Rambow](https://github.com/markrambow)
@@ -0,0 +1,14 @@
1
+ require "bundler"
2
+ Bundler::GemHelper.install_tasks
3
+
4
+ require 'rake/testtask'
5
+ Rake::TestTask.new do |test|
6
+ test.libs << 'lib'
7
+ test.pattern = 'test/**/*_test.rb'
8
+ test.verbose = true
9
+ end
10
+
11
+ task :default do
12
+ sh "RAILS='~>2' bundle && bundle exec rake test"
13
+ sh "RAILS='~>3' bundle && bundle exec rake test"
14
+ end
@@ -0,0 +1,24 @@
1
+ # -*- encoding: utf-8 -*-
2
+ $:.push File.expand_path("../lib", __FILE__)
3
+ require "ssl_requirement/version"
4
+
5
+ Gem::Specification.new do |s|
6
+ s.name = "grosser-ssl_requirement"
7
+ s.version = SslRequirement::Version::STRING
8
+ s.platform = Gem::Platform::RUBY
9
+ s.authors = ["DHH","Michael Grosser","DaWanda"]
10
+ s.email = ["michael@grosser.it"]
11
+ s.homepage = "http://github.com/grosser/ssl_requirement"
12
+ s.summary = "A fork to add some cool options to ssl_requirement"
13
+ s.description = s.summary
14
+ s.license = "MIT"
15
+
16
+ s.files = `git ls-files`.split("\n")
17
+ s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
18
+ s.require_paths = ["lib"]
19
+
20
+ s.add_dependency "actionpack", ENV["RAILS"]
21
+
22
+ s.add_development_dependency "redgreen"
23
+ s.add_development_dependency "rake"
24
+ end
@@ -0,0 +1,80 @@
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(*actions)
30
+ write_inheritable_array(:ssl_required_actions, actions.flatten)
31
+ end
32
+
33
+ def ssl_allowed(*actions)
34
+ write_inheritable_array(:ssl_allowed_actions, actions.flatten)
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
+ ssl_actions_include_current_action(:ssl_required_actions)
43
+ end
44
+
45
+ def ssl_allowed?
46
+ ssl_actions_include_current_action(:ssl_allowed_actions)
47
+ end
48
+
49
+ def ssl_host
50
+ request.host
51
+ end
52
+
53
+ private
54
+
55
+ def ssl_actions_include_current_action (name)
56
+ actions = self.class.read_inheritable_attribute(name)
57
+ return unless actions
58
+ actions = [:all] if actions.empty?
59
+ return true if actions.include? :all
60
+
61
+ if actions.first.is_a? Hash and actions.first[:except]
62
+ not actions.first[:except].map(&:to_sym).include?(params[:action].to_sym)
63
+ else
64
+ actions.map(&:to_sym).include?(params[:action].to_sym)
65
+ end
66
+ end
67
+
68
+ def ensure_proper_protocol
69
+ must_turn_on = (not request.ssl? and ssl_required?)
70
+ must_turn_off = (request.ssl? and not ssl_allowed? and not ssl_required?)
71
+
72
+ return if not must_turn_on and not must_turn_off
73
+
74
+ protocol = (must_turn_on ? 'https' : 'http')
75
+ path = request.respond_to?(:fullpath) ? request.fullpath : request.request_uri
76
+ redirect_to "#{protocol}://#{ssl_host}#{path}"
77
+ flash.keep
78
+ return false
79
+ end
80
+ end
@@ -0,0 +1,8 @@
1
+ module SslRequirement
2
+ module Version
3
+ MAJOR = 0
4
+ MINOR = 1
5
+ PATCH = 0
6
+ STRING = "#{MAJOR}.#{MINOR}.#{PATCH}"
7
+ end
8
+ end
@@ -0,0 +1,314 @@
1
+ require 'rubygems'
2
+ require 'action_pack'
3
+ require 'action_controller'
4
+ require 'test/unit'
5
+ require 'redgreen'
6
+ $LOAD_PATH << 'lib'
7
+
8
+ if ActionPack::VERSION::MAJOR > 2
9
+ require 'action_dispatch/testing/test_process'
10
+
11
+ ROUTES = ActionDispatch::Routing::RouteSet.new
12
+ ROUTES.draw do
13
+ match ':controller(/:action(/:id(.:format)))'
14
+ end
15
+ ROUTES.finalize!
16
+
17
+ # funky patch to get @routes working, in 'setup' did not work
18
+ module ActionController::TestCase::Behavior
19
+ def process_with_routes(*args)
20
+ @routes = ROUTES
21
+ process_without_routes(*args)
22
+ end
23
+ alias_method_chain :process, :routes
24
+ end
25
+
26
+ class ActionController::Base
27
+ self.view_paths = 'test/views'
28
+
29
+ def self._routes
30
+ ROUTES
31
+ end
32
+ end
33
+ else
34
+ require 'action_controller/test_process'
35
+
36
+ ActionController::Routing::Routes.reload rescue nil
37
+ ActionController::Base.cache_store = :memory_store
38
+
39
+ end
40
+
41
+
42
+
43
+
44
+
45
+ require 'ssl_requirement'
46
+
47
+ class SslRequirementController < ActionController::Base
48
+ include SslRequirement
49
+
50
+ ssl_required :a, :b
51
+ ssl_allowed :c
52
+
53
+ def a
54
+ render :nothing => true
55
+ end
56
+
57
+ def b
58
+ render :nothing => true
59
+ end
60
+
61
+ def c
62
+ render :nothing => true
63
+ end
64
+
65
+ def d
66
+ render :nothing => true
67
+ end
68
+
69
+ def set_flash
70
+ flash[:foo] = "bar"
71
+ render :nothing => true
72
+ end
73
+ end
74
+
75
+ class SslRequirementTest < ActionController::TestCase
76
+ def setup
77
+ @controller = SslRequirementController.new
78
+ @request = ActionController::TestRequest.new
79
+ @response = ActionController::TestResponse.new
80
+ end
81
+
82
+ test "redirect to https preserves flash" do
83
+ get :set_flash
84
+ get :b
85
+ assert_response :redirect
86
+ assert_equal "bar", flash[:foo]
87
+ end
88
+
89
+ test "not redirecting to https does preserve the flash" do
90
+ get :set_flash
91
+ get :d
92
+ assert_response :success
93
+ assert_equal "bar", flash[:foo]
94
+ end
95
+
96
+ test "redirect to http preserves flash" do
97
+ get :set_flash
98
+ @request.env['HTTPS'] = "on"
99
+ get :d
100
+ assert_response :redirect
101
+ assert_equal "bar", flash[:foo]
102
+ end
103
+
104
+ test "not redirecting to http does preserve the flash" do
105
+ get :set_flash
106
+ @request.env['HTTPS'] = "on"
107
+ get :a
108
+ assert_response :success
109
+ assert_equal "bar", flash[:foo]
110
+ end
111
+
112
+ test "required without ssl" do
113
+ assert_not_equal "on", @request.env["HTTPS"]
114
+ get :a
115
+ assert_response :redirect
116
+ assert_match %r{^https://}, @response.headers['Location']
117
+ get :b
118
+ assert_response :redirect
119
+ assert_match %r{^https://}, @response.headers['Location']
120
+ end
121
+
122
+ test "required with ssl" do
123
+ @request.env['HTTPS'] = "on"
124
+ get :a
125
+ assert_response :success
126
+ get :b
127
+ assert_response :success
128
+ end
129
+
130
+ test "disallowed without ssl" do
131
+ assert_not_equal "on", @request.env["HTTPS"]
132
+ get :d
133
+ assert_response :success
134
+ end
135
+
136
+ test "disallowed with ssl" do
137
+ @request.env['HTTPS'] = "on"
138
+ get :d
139
+ assert_response :redirect
140
+ assert_match %r{^http://}, @response.headers['Location']
141
+ end
142
+
143
+ test "allowed without ssl" do
144
+ assert_not_equal "on", @request.env["HTTPS"]
145
+ get :c
146
+ assert_response :success
147
+ end
148
+
149
+ test "allowed with ssl" do
150
+ @request.env['HTTPS'] = "on"
151
+ get :c
152
+ assert_response :success
153
+ end
154
+ end
155
+
156
+ class SslRequiredAllController < ActionController::Base
157
+ include SslRequirement
158
+ ssl_required
159
+
160
+ def a
161
+ render :nothing => true
162
+ end
163
+ end
164
+
165
+
166
+ class SslRequiredAllTest < ActionController::TestCase
167
+ def setup
168
+ @controller = SslRequiredAllController.new
169
+ @request = ActionController::TestRequest.new
170
+ @response = ActionController::TestResponse.new
171
+ end
172
+
173
+ test "allows ssl" do
174
+ @request.env['HTTPS'] = "on"
175
+ get :a
176
+ assert_response :success
177
+ end
178
+
179
+ test "disallowed without ssl" do
180
+ get :a
181
+ assert_response :redirect
182
+ end
183
+ end
184
+
185
+
186
+ class SslAllowedAllController < ActionController::Base
187
+ include SslRequirement
188
+ ssl_allowed :all
189
+
190
+ def a
191
+ render :nothing => true
192
+ end
193
+ end
194
+
195
+ class SslAllowedAllTest < ActionController::TestCase
196
+ def setup
197
+ @controller = SslAllowedAllController.new
198
+ @request = ActionController::TestRequest.new
199
+ @response = ActionController::TestResponse.new
200
+ end
201
+
202
+ test "allows ssl" do
203
+ @request.env['HTTPS'] = "on"
204
+ get :a
205
+ assert_response :success
206
+ end
207
+
208
+ test "allowes without ssl" do
209
+ get :a
210
+ assert_response :success
211
+ end
212
+ end
213
+
214
+
215
+ class SslAllowedAndRequiredController < ActionController::Base
216
+ include SslRequirement
217
+ ssl_allowed
218
+ ssl_required
219
+
220
+ def a
221
+ render :nothing => true
222
+ end
223
+ end
224
+
225
+ class SslAllowedAndRequiredTest < ActionController::TestCase
226
+ def setup
227
+ @controller = SslAllowedAndRequiredController.new
228
+ @request = ActionController::TestRequest.new
229
+ @response = ActionController::TestResponse.new
230
+ end
231
+
232
+ test "allows ssl" do
233
+ @request.env['HTTPS'] = "on"
234
+ get :a
235
+ assert_response :success
236
+ end
237
+
238
+ test "diallowes without ssl" do
239
+ get :a
240
+ assert_response :redirect
241
+ end
242
+ end
243
+
244
+ class SslAllowedAndRequiredController < ActionController::Base
245
+ include SslRequirement
246
+ ssl_required
247
+
248
+ def a
249
+ render :nothing => true
250
+ end
251
+
252
+ protected
253
+
254
+ def ssl_host
255
+ 'www.xxx.com'
256
+ end
257
+ end
258
+
259
+ class SslHostTest < ActionController::TestCase
260
+ def setup
261
+ @controller = SslAllowedAndRequiredController.new
262
+ @request = ActionController::TestRequest.new
263
+ @response = ActionController::TestResponse.new
264
+ end
265
+
266
+ test "uses ssl_host" do
267
+ @request.env['HTTPS'] = "on"
268
+ get :a
269
+ assert_response :success
270
+ end
271
+
272
+ test "diallowes without ssl" do
273
+ @request.path = "/ssl_allowed_and_required/a"
274
+ get :a
275
+ assert_response :redirect
276
+ assert_equal "https://www.xxx.com/ssl_allowed_and_required/a", @response.headers['Location']
277
+ end
278
+ end
279
+
280
+ class SslAllowedWithExceptedMethods < ActionController::Base
281
+ include SslRequirement
282
+ ssl_allowed :except => [:non_secure_method]
283
+
284
+ def secure
285
+ render :nothing => true
286
+ end
287
+
288
+ def non_secure_method
289
+ render :nothing => true
290
+ end
291
+ end
292
+
293
+ class SslAllowedWithExceptedMethodsTest < ActionController::TestCase
294
+ def setup
295
+ @controller = SslAllowedWithExceptedMethods.new
296
+ @request = ActionController::TestRequest.new
297
+ @response = ActionController::TestResponse.new
298
+ end
299
+
300
+ test "uses ssl" do
301
+ @request.env['HTTPS'] = "on"
302
+ get :secure
303
+ assert_response :success
304
+ end
305
+
306
+ test "diallowes with ssl on excluded methods" do
307
+ @request.env['HTTPS'] = "on"
308
+ @request.path = "/ssl_allowed_with_excepted_methods/non_secure_method" #stubed path because testframework does not sets path on rails 3
309
+ get :non_secure_method
310
+ assert_response :redirect
311
+ assert_equal "http://test.host/ssl_allowed_with_excepted_methods/non_secure_method", @response.headers['Location']
312
+ end
313
+ end
314
+
metadata ADDED
@@ -0,0 +1,118 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: grosser-ssl_requirement
3
+ version: !ruby/object:Gem::Version
4
+ hash: 27
5
+ prerelease:
6
+ segments:
7
+ - 0
8
+ - 1
9
+ - 0
10
+ version: 0.1.0
11
+ platform: ruby
12
+ authors:
13
+ - DHH
14
+ - Michael Grosser
15
+ - DaWanda
16
+ autorequire:
17
+ bindir: bin
18
+ cert_chain: []
19
+
20
+ date: 2011-09-07 00:00:00 +02:00
21
+ default_executable:
22
+ dependencies:
23
+ - !ruby/object:Gem::Dependency
24
+ requirement: &id001 !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ">="
28
+ - !ruby/object:Gem::Version
29
+ hash: 3
30
+ segments:
31
+ - 0
32
+ version: "0"
33
+ type: :runtime
34
+ name: actionpack
35
+ version_requirements: *id001
36
+ prerelease: false
37
+ - !ruby/object:Gem::Dependency
38
+ requirement: &id002 !ruby/object:Gem::Requirement
39
+ none: false
40
+ requirements:
41
+ - - ">="
42
+ - !ruby/object:Gem::Version
43
+ hash: 3
44
+ segments:
45
+ - 0
46
+ version: "0"
47
+ type: :development
48
+ name: redgreen
49
+ version_requirements: *id002
50
+ prerelease: false
51
+ - !ruby/object:Gem::Dependency
52
+ requirement: &id003 !ruby/object:Gem::Requirement
53
+ none: false
54
+ requirements:
55
+ - - ">="
56
+ - !ruby/object:Gem::Version
57
+ hash: 3
58
+ segments:
59
+ - 0
60
+ version: "0"
61
+ type: :development
62
+ name: rake
63
+ version_requirements: *id003
64
+ prerelease: false
65
+ description: A fork to add some cool options to ssl_requirement
66
+ email:
67
+ - michael@grosser.it
68
+ executables: []
69
+
70
+ extensions: []
71
+
72
+ extra_rdoc_files: []
73
+
74
+ files:
75
+ - Gemfile
76
+ - Gemfile.lock
77
+ - README.markdown
78
+ - Rakefile
79
+ - grosser-ssl_requirement.gemspec
80
+ - lib/ssl_requirement.rb
81
+ - lib/ssl_requirement/version.rb
82
+ - test/ssl_requirement_test.rb
83
+ has_rdoc: true
84
+ homepage: http://github.com/grosser/ssl_requirement
85
+ licenses:
86
+ - MIT
87
+ post_install_message:
88
+ rdoc_options: []
89
+
90
+ require_paths:
91
+ - lib
92
+ required_ruby_version: !ruby/object:Gem::Requirement
93
+ none: false
94
+ requirements:
95
+ - - ">="
96
+ - !ruby/object:Gem::Version
97
+ hash: 3
98
+ segments:
99
+ - 0
100
+ version: "0"
101
+ required_rubygems_version: !ruby/object:Gem::Requirement
102
+ none: false
103
+ requirements:
104
+ - - ">="
105
+ - !ruby/object:Gem::Version
106
+ hash: 3
107
+ segments:
108
+ - 0
109
+ version: "0"
110
+ requirements: []
111
+
112
+ rubyforge_project:
113
+ rubygems_version: 1.6.2
114
+ signing_key:
115
+ specification_version: 3
116
+ summary: A fork to add some cool options to ssl_requirement
117
+ test_files: []
118
+