panmind-sslhelper 0.8.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/README.md ADDED
@@ -0,0 +1,100 @@
1
+ SSLHelper: an SSL plugin for Rails
2
+ ==================================
3
+
4
+ Purpose
5
+ -------
6
+
7
+ This plugin implements the same features as Rails' ssl_requirement plugin,
8
+ plus builds on existing named route helpers by adding `plain_` and `ssl_`
9
+ counterparts.
10
+
11
+ Installation
12
+ ------------
13
+
14
+ Via RubyGems:
15
+
16
+ gem install panmind-sslhelper
17
+
18
+ Or via Rails Plugin:
19
+
20
+ script/plugin install git://github.com/Panmind/ssl_helper.git
21
+
22
+ Usage
23
+ -----
24
+
25
+ After you get the plugin loaded, you'll have `plain_` and `ssl_` counterparts
26
+ to all your named route helpers, e.g.: `ssl_root_url` or `plain_user_url(user)`
27
+
28
+ You can use them in your views, controllers and functional tests, as they were
29
+ built in into the framework.
30
+
31
+ Views:
32
+
33
+ <%= link_to 'login', ssl_login_url %>
34
+ <%= link_to 'home', plain_root_url %>
35
+
36
+ Controllers:
37
+
38
+ def foo
39
+ redirect_to ssl_foos_url
40
+ end
41
+
42
+ Functionals:
43
+
44
+ context "an admin" do
45
+ should "access admin area only via SSL" do
46
+ setup { login_as @admin }
47
+
48
+ without_ssl do
49
+ get :index
50
+ assert_redirected_to ssl_admin_url
51
+ end
52
+
53
+ with_ssl do
54
+ get :index
55
+ assert_response :success
56
+ end
57
+ end
58
+ end
59
+
60
+ The additional `with_ssl`, `without_ssl`, `use_ssl` and `forget_ssl` are
61
+ available in your tests. The first two ones accept blocks evaluated with
62
+ SSL set or unset, the others set/unset SSL for a number of consecutive
63
+ tests (e.g. use them in your `setup` method).
64
+
65
+
66
+ Compatibility
67
+ -------------
68
+
69
+ Tested with Rails 2.3.8 running under Ruby 1.9.1-p378.
70
+
71
+
72
+ Server configuration
73
+ --------------------
74
+
75
+ The plugin relies on the HTTPS server variable, that is set automatically by
76
+ Rails if the `X-Forwarded-Proto` header is set to `https`. To avoid clients
77
+ setting that header, take care to add a `proxy_set_header` in your nginx
78
+ config file, such as:
79
+
80
+ server {
81
+ listen 80;
82
+ #
83
+ # your configuration
84
+ #
85
+ location / {
86
+ proxy_set_header X-Forwarded-Proto http;
87
+ }
88
+ }
89
+
90
+ server {
91
+ listen 443;
92
+ #
93
+ # your configuration
94
+ #
95
+ location / {
96
+ proxy_set_header X-Forwarded-Proto https;
97
+ }
98
+ }
99
+
100
+ For Apache, you're on your own for now :-) more documentation will follow!
data/Rakefile ADDED
@@ -0,0 +1,49 @@
1
+ require 'rake'
2
+ require 'rake/rdoctask'
3
+
4
+ require 'lib/panmind/ssl_helper'
5
+
6
+ begin
7
+ require 'jeweler'
8
+ Jeweler::Tasks.new do |gemspec|
9
+ gemspec.name = 'panmind-sslhelper'
10
+
11
+ gemspec.summary = 'SSL requirement filters and SSL-aware named route helpers for Rails apps'
12
+ gemspec.description = 'SSLHelper provides controller helpers to require/refuse SSL onto ' \
13
+ 'specific actions, test helpers to verify controller behaviours ' \
14
+ 'and named route counterparts (e.g. ssl_login_url) to clean up your '\
15
+ 'view and controller code. HTTP(S) ports are configurable.'
16
+
17
+ gemspec.authors = ['Marcello Barnaba']
18
+ gemspec.email = 'vjt@openssl.it'
19
+ gemspec.homepage = 'http://github.com/Panmind/ssl_helper'
20
+
21
+ gemspec.files = %w( README.md Rakefile rails/init.rb ) + Dir['lib/**/*']
22
+ gemspec.extra_rdoc_files = %w( README.md )
23
+ gemspec.has_rdoc = true
24
+
25
+ gemspec.version = Panmind::SSLHelper::Version
26
+ gemspec.date = '2010-07-31'
27
+
28
+ gemspec.require_path = 'lib'
29
+
30
+ gemspec.add_dependency('rails', '>= 2.3.8')
31
+ end
32
+ rescue LoadError
33
+ puts 'Jeweler not available. Install it with: gem install jeweler'
34
+ end
35
+
36
+ desc 'Generate the rdoc'
37
+ Rake::RDocTask.new do |rdoc|
38
+ rdoc.rdoc_files.add %w( README.md lib/**/*.rb )
39
+
40
+ rdoc.main = 'README.md'
41
+ rdoc.title = 'SSL requirement filters and SSL-aware named route helpers for Rails apps'
42
+ end
43
+
44
+ desc 'Will someone help write tests?'
45
+ task :default do
46
+ puts
47
+ puts 'Can you help in writing tests? Please do :-)'
48
+ puts
49
+ end
@@ -0,0 +1,13 @@
1
+ module Panmind
2
+ module SSLHelper
3
+
4
+ class Railtie
5
+ def self.insert
6
+ ActionController::Routing::Routes.extend(Panmind::SSLHelper::Routing)
7
+ ActionController::Base.instance_eval { include Panmind::SSLHelper::Filters }
8
+ ActiveSupport::TestCase.instance_eval { include Panmind::SSLHelper::TestHelpers } if Rails.env.test?
9
+ end
10
+ end
11
+
12
+ end
13
+ end
@@ -0,0 +1,181 @@
1
+ require 'panmind/ssl_helper/railtie'
2
+
3
+ module Panmind
4
+ module SSLHelper
5
+ Version = '0.8.0'
6
+
7
+ WITH_SSL = {:protocol => 'https'}
8
+ WITHOUT_SSL = {:protocol => 'http' }
9
+
10
+ def self.set(options = {})
11
+ return if Rails.env.test? # Because tests make assumptions we cannot break
12
+
13
+ https_port = (options[:https_port] || 443).to_i
14
+ http_port = (options[:http_port] || 80 ).to_i
15
+
16
+ # if we use non-standard ports we must explictly use them in the URIs
17
+ if https_port != 443 || http_port != 80
18
+ WITH_SSL.update(:port => https_port)
19
+ WITHOUT_SSL.update(:port => http_port)
20
+ end
21
+ end
22
+
23
+ module Routing
24
+ def reload!
25
+ returning super do
26
+ helpers = create_ssl_helpers
27
+ return unless helpers # Not ready yet.
28
+
29
+ classes = [
30
+ ActionController::Base,
31
+ ActionController::Integration::Session,
32
+ ActionController::TestCase,
33
+
34
+ ActionView::Base
35
+ ]
36
+
37
+ # Include the helper_module into each class to patch.
38
+ #
39
+ classes.each {|k| k.instance_eval { include helpers } }
40
+
41
+ # Set the helpers as public in the AC::Integration::Session class
42
+ # for easy testing in the console.
43
+ #
44
+ ActionController::Integration::Session.module_eval do
45
+ public *helpers.instance_methods
46
+ end
47
+ end
48
+ end
49
+
50
+ # Populates the @ssl_helpers module with ssl_ and plain_ helper
51
+ # counterparts for all defined named route helpers.
52
+ #
53
+ # Tries to use the ActionController::Routing::Routes private Rails
54
+ # API, falls back to regexp filtering if it is not available.
55
+ #
56
+ def create_ssl_helpers
57
+ @ssl_helpers ||= Module.new
58
+ return @ssl_helpers if @ssl_helpers.frozen?
59
+
60
+ route_helpers =
61
+ if defined? ActionController::Routing::Routes.named_routes.helpers
62
+ # This is a Private Rails API, so we check whether it's defined
63
+ # and reject all the hash_for_*() and the *_path() helpers.
64
+ #
65
+ ActionController::Routing::Routes.named_routes.helpers.
66
+ reject { |h| h.to_s =~ /(^hash_for)|(path$)/ }
67
+ else
68
+ # Warn the developer and fall back.
69
+ #
70
+ Rails.logger.warn "SSLHelper: AC::Routing::Routes.named_routes disappeared"
71
+ Rails.logger.warn "SSLHelper: falling back to filtering controller methods"
72
+
73
+ ac = ActionController::Base
74
+ skip = /(^hash_for_|^formatted_|polymorphic_|^redirect_)/
75
+ ac.instance_methods.grep(/_url$/) - ac.instance_methods.grep(skip)
76
+ end
77
+
78
+ return if route_helpers.empty?
79
+
80
+ # Create a Module containing all the ssl_ and plain_ helpers
81
+ # that: [1] alter the args they receive with the SSL options
82
+ # and [2] forward the altered args to the Rails' helper.
83
+ #
84
+ @ssl_helpers.module_eval do
85
+ route_helpers.each do |helper|
86
+ ssl, plain = "ssl_#{helper}", "plain_#{helper}"
87
+
88
+ define_method(ssl) { |*args| send(helper, *ssl_alter(args, WITH_SSL)) }
89
+ define_method(plain) { |*args| send(helper, *ssl_alter(args, WITHOUT_SSL)) }
90
+
91
+ protected ssl, plain
92
+ end
93
+
94
+ private
95
+ def ssl_alter(args, with) #:nodoc:
96
+ return args if Rails.env.development?
97
+
98
+ options = args.last.kind_of?(Hash) ? args.pop : {}
99
+ args.push(options.update(with))
100
+ end
101
+ end
102
+
103
+ # No further modification allowed.
104
+ #
105
+ @ssl_helpers.freeze
106
+ end
107
+
108
+ end # REST
109
+
110
+ module Filters
111
+ def self.included(base)
112
+ base.extend(ClassMethods)
113
+ end
114
+
115
+ module ClassMethods
116
+ def require_ssl(options = {})
117
+ return if Rails.env.development?
118
+
119
+ skip_before_filter :ssl_refused, options
120
+ before_filter :ssl_required, options
121
+ end
122
+
123
+ def ignore_ssl(options = {})
124
+ return if Rails.env.development?
125
+
126
+ skip_before_filter :ssl_required, options
127
+ skip_before_filter :ssl_refused, options
128
+ end
129
+
130
+ def refuse_ssl(options = {})
131
+ return if Rails.env.development?
132
+
133
+ skip_before_filter :ssl_required, options
134
+ before_filter :ssl_refused, options
135
+ end
136
+ end
137
+
138
+ protected
139
+ def ssl_required
140
+ redirect_to WITH_SSL.dup unless request.ssl?
141
+ end
142
+
143
+ def ssl_refused
144
+ redirect_to WITHOUT_SSL.dup if request.ssl?
145
+ end
146
+ end # Filters
147
+
148
+ module TestHelpers
149
+ def with_ssl(&block)
150
+ save_ssl_and do
151
+ use_ssl
152
+ block.call
153
+ end
154
+ end
155
+
156
+ def without_ssl(&block)
157
+ save_ssl_and do
158
+ forget_ssl
159
+ block.call
160
+ end
161
+ end
162
+
163
+ def use_ssl
164
+ @request.env['HTTPS'] = 'on'
165
+ @request.env['SERVER_PORT'] = 443
166
+ end
167
+
168
+ def forget_ssl
169
+ @request.env['HTTPS'] = nil
170
+ @request.env['SERVER_PORT'] = 80
171
+ end
172
+
173
+ protected
174
+ def save_ssl_and
175
+ https, port = @request.env.values_at(*%w(HTTPS SERVER_PORT))
176
+ yield
177
+ @request.env.update('HTTPS' => https, 'SERVER_PORT' => port)
178
+ end
179
+ end # TestHelpers
180
+ end # SSLHelper
181
+ end # Panmind
data/rails/init.rb ADDED
@@ -0,0 +1,2 @@
1
+ require 'panmind/ssl_helper/railtie'
2
+ Panmind::SSLHelper::Railtie.insert
metadata ADDED
@@ -0,0 +1,79 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: panmind-sslhelper
3
+ version: !ruby/object:Gem::Version
4
+ prerelease: false
5
+ segments:
6
+ - 0
7
+ - 8
8
+ - 0
9
+ version: 0.8.0
10
+ platform: ruby
11
+ authors:
12
+ - Marcello Barnaba
13
+ autorequire:
14
+ bindir: bin
15
+ cert_chain: []
16
+
17
+ date: 2010-07-31 00:00:00 +02:00
18
+ default_executable:
19
+ dependencies:
20
+ - !ruby/object:Gem::Dependency
21
+ name: rails
22
+ prerelease: false
23
+ requirement: &id001 !ruby/object:Gem::Requirement
24
+ requirements:
25
+ - - ">="
26
+ - !ruby/object:Gem::Version
27
+ segments:
28
+ - 2
29
+ - 3
30
+ - 8
31
+ version: 2.3.8
32
+ type: :runtime
33
+ version_requirements: *id001
34
+ description: SSLHelper provides controller helpers to require/refuse SSL onto specific actions, test helpers to verify controller behaviours and named route counterparts (e.g. ssl_login_url) to clean up your view and controller code. HTTP(S) ports are configurable.
35
+ email: vjt@openssl.it
36
+ executables: []
37
+
38
+ extensions: []
39
+
40
+ extra_rdoc_files:
41
+ - README.md
42
+ files:
43
+ - README.md
44
+ - Rakefile
45
+ - lib/panmind/ssl_helper.rb
46
+ - lib/panmind/ssl_helper/railtie.rb
47
+ - rails/init.rb
48
+ has_rdoc: true
49
+ homepage: http://github.com/Panmind/ssl_helper
50
+ licenses: []
51
+
52
+ post_install_message:
53
+ rdoc_options:
54
+ - --charset=UTF-8
55
+ require_paths:
56
+ - lib
57
+ required_ruby_version: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ">="
60
+ - !ruby/object:Gem::Version
61
+ segments:
62
+ - 0
63
+ version: "0"
64
+ required_rubygems_version: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - ">="
67
+ - !ruby/object:Gem::Version
68
+ segments:
69
+ - 0
70
+ version: "0"
71
+ requirements: []
72
+
73
+ rubyforge_project:
74
+ rubygems_version: 1.3.6
75
+ signing_key:
76
+ specification_version: 3
77
+ summary: SSL requirement filters and SSL-aware named route helpers for Rails apps
78
+ test_files: []
79
+