File Coverage

blib/lib/Catalyst/Plugin/RequireSSL.pm
Criterion Covered Total %
statement 9 48 18.7
branch 0 26 0.0
condition 0 6 0.0
subroutine 3 8 37.5
pod 4 4 100.0
total 16 92 17.3


line stmt bran cond sub pod time code
1             package Catalyst::Plugin::RequireSSL;
2              
3 1     1   924 use strict;
  1         2  
  1         43  
4 1     1   5 use base qw/Class::Accessor::Fast/;
  1         2  
  1         10807  
5 1     1   36720 use MRO::Compat;
  1         14013  
  1         909  
6              
7             our $VERSION = '0.07';
8              
9             __PACKAGE__->mk_accessors( qw/_require_ssl _allow_ssl _ssl_strip_output/ );
10              
11             sub require_ssl {
12 0     0 1   my $c = shift;
13              
14 0           $c->_require_ssl(1);
15              
16 0 0 0       if ( !$c->req->secure && $c->req->method ne "POST" ) {
17 0           my $redir = $c->_redirect_uri('https');
18 0 0         if ( $c->config->{require_ssl}->{disabled} ) {
19 0           $c->log->warn( "RequireSSL: Would have redirected to $redir" );
20             }
21             else {
22 0           $c->_ssl_strip_output(1);
23 0           $c->res->redirect( $redir );
24 0 0         $c->detach if $c->config->{require_ssl}->{detach_on_redirect};
25             }
26             }
27             }
28              
29             sub allow_ssl {
30 0     0 1   my $c = shift;
31              
32 0           $c->_allow_ssl(1);
33             }
34              
35             sub finalize {
36 0     0 1   my $c = shift;
37            
38             # Do not redirect static files (only works with Static::Simple)
39 0 0         if ( $c->isa( "Catalyst::Plugin::Static::Simple" ) ) {
40 0 0         return $c->next::method(@_) if $c->_static_file;
41             }
42            
43             # redirect back to non-SSL mode
44             REDIRECT:
45             {
46             # No redirect if:
47             # we're not in SSL mode
48 0 0         last REDIRECT if !$c->req->secure;
  0            
49             # it's a POST request
50 0 0         last REDIRECT if $c->req->method eq "POST";
51             # we're already required to be in SSL for this request
52 0 0         last REDIRECT if $c->_require_ssl;
53             # or the user doesn't want us to redirect
54 0 0 0       last REDIRECT if $c->config->{require_ssl}->{remain_in_ssl} || $c->_allow_ssl;
55            
56 0           $c->res->redirect( $c->_redirect_uri('http') );
57             }
58              
59             # do not allow any output to be displayed on the insecure page
60 0 0         if ( $c->_ssl_strip_output ) {
61 0           $c->res->body( '' );
62             }
63              
64 0           return $c->next::method(@_);
65             }
66              
67             sub setup {
68 0     0 1   my $c = shift;
69              
70 0           $c->next::method(@_);
71              
72             # disable the plugin when running under certain engines which don't
73             # support SSL
74 0 0         if ( $c->engine =~ /Catalyst::Engine::HTTP/ ) {
75 0           $c->config->{require_ssl}->{disabled} = 1;
76 0           $c->log->warn( "RequireSSL: Disabling SSL redirection while running "
77             . "under " . $c->engine );
78             }
79             }
80              
81             sub _redirect_uri {
82 0     0     my ( $c, $type ) = @_;
83              
84 0 0         if ( !$c->config->{require_ssl}->{$type} ) {
85 0           my $req_uri = $c->req->uri;
86 0           $c->config->{require_ssl}->{$type} =
87             join(':', $req_uri->host, $req_uri->_port);
88             }
89              
90 0           $c->config->{require_ssl}->{$type} =~ s/\/+$//;
91              
92 0           my $redir = $c->req->uri->clone;
93 0           $redir->scheme($type);
94 0           $redir->host_port($c->config->{require_ssl}->{$type});
95              
96 0 0         if ( $c->config->{require_ssl}->{no_cache} ) {
97 0           delete $c->config->{require_ssl}->{$type};
98             }
99            
100 0           return $redir;
101             }
102              
103             1;
104             __END__
105              
106             =head1 NAME
107              
108             Catalyst::Plugin::RequireSSL - Force SSL mode on select pages
109              
110             =head1 SYNOPSIS
111              
112             # in MyApp.pm
113             use Catalyst qw/
114             RequireSSL
115             /;
116             __PACKAGE__->config(
117             require_ssl => {
118             https => 'secure.mydomain.com',
119             http => 'www.mydomain.com',
120             remain_in_ssl => 0,
121             no_cache => 0,
122             detach_on_redirect => 1,
123             },
124             );
125             __PACKAGE__->setup;
126              
127              
128             # in any controller methods that should be secured
129             $c->require_ssl;
130              
131             =head1 DESCRIPTION
132              
133             B<Note:> This module is considered to be deprecated for most purposes. Consider
134             using L<Catalyst::ActionRole::RequireSSL> instead.
135              
136             Use this plugin if you wish to selectively force SSL mode on some of your web
137             pages, for example a user login form or shopping cart.
138              
139             Simply place $c->require_ssl calls in any controller method you wish to be
140             secured.
141              
142             This plugin will automatically disable itself if you are running under the
143             standalone HTTP::Daemon Catalyst server. A warning message will be printed to
144             the log file whenever an SSL redirect would have occurred.
145              
146             =head1 WARNINGS
147              
148             If you utilize different servers or hostnames for non-SSL and SSL requests,
149             and you rely on a session cookie to determine redirection (i.e for a login
150             page), your cookie must be visible to both servers. For more information, see
151             the documentation for the Session plugin you are using.
152              
153             =head1 CONFIGURATION
154              
155             Configuration is optional. You may define the following configuration values:
156              
157             https => $ssl_host
158            
159             If your SSL domain name is different from your non-SSL domain, set this value.
160              
161             http => $non_ssl_host
162            
163             If you have set the https value above, you must also set the hostname of your
164             non-SSL server.
165              
166             remain_in_ssl
167            
168             If you'd like your users to remain in SSL mode after visiting an SSL-required
169             page, you can set this option to 1. By default, this option is disabled and
170             users will be redirected back to non-SSL mode as soon as possible.
171              
172             no_cache
173              
174             If you have a wildcard certificate you will need to set this option if you are
175             using multiple domains on one instance of Catalyst.
176              
177             detach_on_redirect
178              
179             By default C<< $c->require_ssl >> only calls C<< $c->response->redirect >> but
180             does not stop request processing (so it returns and subsequent statements are
181             run). This is probably not what you want. If you set this option to a true
182             value C<< $c->require_ssl >> will call C<< $c->detach >> when it redirects.
183              
184             =head1 METHODS
185              
186             =head2 require_ssl
187              
188             Call require_ssl in any controller method you wish to be secured.
189              
190             $c->require_ssl;
191              
192             The browser will be redirected to the same path on your SSL server. POST
193             requests are never redirected.
194              
195             =head2 allow_ssl
196              
197             Call allow_ssl in any controller method you wish to access both in SSL and
198             non-SSL mode.
199              
200             $c->allow_ssl;
201              
202             The browser will not be redirected, independently of whether the request was
203             made to the SSL or non-SSL server.
204              
205             =head2 setup
206              
207             Disables this plugin if running under an engine which does not support SSL.
208              
209             =head2 finalize
210              
211             Performs the redirect to SSL url if required.
212              
213             =head1 KNOWN ISSUES
214              
215             When viewing an SSL-required page that uses static files served from the
216             Static plugin, the static files are redirected to the non-SSL path.
217              
218             In order to get the correct behaviour where static files are not redirected,
219             you should use the Static::Simple plugin or always serve static files
220             directly from your web server.
221              
222             =head1 SEE ALSO
223              
224             L<Catalyst>, L<Catalyst::ActionRole::RequireSSL>,
225             L<Catalyst::Plugin::Static::Simple>
226              
227             =head1 AUTHOR
228              
229             Andy Grundman, <andy@hybridized.org>
230              
231             =head1 CONTRIBUTORS
232              
233             Simon Elliott <simon@browsing.co.uk> (support for wildcards)
234              
235             =head1 COPYRIGHT
236              
237             This program is free software, you can redistribute it and/or modify it under
238             the same terms as Perl itself.
239              
240             =cut