grosser-ssl_requirement 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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
+