File Coverage

blib/lib/CatalystX/SimpleLogin/Controller/Login.pm
Criterion Covered Total %
statement 55 56 98.2
branch 5 6 83.3
condition n/a
subroutine 20 20 100.0
pod 9 9 100.0
total 89 91 97.8


line stmt bran cond sub pod time code
1             package CatalystX::SimpleLogin::Controller::Login;
2 9     9   6571 use Moose;
  9         25  
  9         102  
3 9     9   64395 use MooseX::Types::Moose qw/ HashRef ArrayRef ClassName Object Str Int/;
  9         460453  
  9         86  
4 9     9   55344 use MooseX::Types::Common::String qw/ NonEmptySimpleStr /;
  9         872603  
  9         68  
5 9     9   30870 use CatalystX::SimpleLogin::Form::Login;
  9         4654  
  9         454  
6 9     9   85 use namespace::autoclean;
  9         23  
  9         99  
7              
8 9     9   797 BEGIN { extends 'Catalyst::Controller'; }
9              
10             with qw(
11             CatalystX::Component::Traits
12             Catalyst::Component::ContextClosure
13             );
14              
15             has '+_trait_merge' => (default => 1);
16              
17             __PACKAGE__->config(
18             traits => [qw/
19             WithRedirect
20             RenderAsTTTemplate
21             Logout
22             /],
23             remember_me_expiry => 999999999,
24             );
25              
26             sub BUILD {
27 8     8 1 39998 my $self = shift;
28 8         312 $self->login_form; # Build login form at construction time
29             }
30              
31             has login_form_class => (
32             isa => ClassName,
33             is => 'rw',
34             default => 'CatalystX::SimpleLogin::Form::Login',
35             );
36              
37             has login_form_class_roles => (
38             isa => ArrayRef[NonEmptySimpleStr],
39             is => 'ro',
40             default => sub { [] },
41             );
42              
43             has login_form => (
44             isa => Object,
45             is => 'ro',
46             lazy_build => 1,
47             );
48              
49             has login_form_args => (
50             isa => HashRef,
51             is => 'ro',
52             default => sub { {} },
53             );
54              
55             has remember_me_expiry => (
56             isa => Int,
57             is => 'ro',
58             );
59              
60             has login_form_stash_key => (
61             is => 'ro',
62             isa => Str,
63             default => 'login_form',
64             );
65              
66             has render_login_form_stash_key => (
67             is => 'ro',
68             isa => Str,
69             default => 'render_login_form',
70             );
71              
72             with 'MooseX::RelatedClassRoles' => { name => 'login_form' };
73              
74             sub _build_login_form {
75 8     8   25 my $self = shift;
76 0         0 $self->apply_login_form_class_roles(@{$self->login_form_class_roles})
77 8 50       51 if scalar @{$self->login_form_class_roles}; # FIXME - Should MX::RelatedClassRoles
  8         369  
78             # do this automagically?
79 8         332 return $self->login_form_class->new($self->login_form_args);
80             }
81              
82             sub render_login_form {
83 5     5 1 18 my ($self, $ctx, $form) = @_;
84 5         56 return $form->render;
85             }
86              
87             sub not_required
88             :Chained('/')
89             :PathPart('')
90             :CaptureArgs(0)
91 9     9 1 511193 {}
  9     17   26  
  9         92  
92              
93             sub required
94             :Chained('/')
95             :PathPart('')
96             :CaptureArgs(0)
97             :Does('NeedsLogin')
98 9     9 1 11094 {}
  9     2   25  
  9         39  
99              
100             sub login
101             :Chained('not_required')
102             :PathPart('login')
103             :Args(0)
104             {
105 16     16 1 6294 my ($self, $ctx) = @_;
106 16         564 my $form = $self->login_form;
107 16         70 my $p = $ctx->req->parameters;
108              
109 16 100       1319 if( $form->process(ctx => $ctx, params => $p) ) {
110 8         19280 $ctx->change_session_id;
111              
112 8         19758 $self->remember_me($ctx, $form->field( 'remember' )->value);
113              
114 8         5072 $self->do_post_login_redirect($ctx);
115             }
116              
117             $ctx->stash(
118             $self->login_form_stash_key => $form,
119             $self->render_login_form_stash_key => $self->make_context_closure(sub {
120 5     5   30696 my ($ctx) = @_;
121 5         60 $self->render_login_form($ctx, $form);
122 16         54138 }, $ctx),
123             );
124 9     9   9202 }
  9         24  
  9         45  
125              
126             sub remember_me
127             {
128 8     8 1 1457 my ($self, $ctx, $remember) = @_;
129 8 100       162 my $expire = $remember ?
130             $self->remember_me_expiry : $ctx->initial_session_expires - time();
131             # set expiry time in storage
132 8         600 $ctx->change_session_expires($expire);
133             # refresh changed expiry time from storage
134 8         1283 $ctx->reset_session_expires;
135             # update cookie TTL
136 8         9255 $ctx->set_session_id($ctx->sessionid);
137             }
138              
139             sub do_post_login_redirect {
140 8     8 1 44 my ($self, $ctx) = @_;
141 8         47 $ctx->res->redirect($self->redirect_after_login_uri($ctx));
142             }
143              
144             sub login_redirect {
145 11     11 1 7605 my ($self, $ctx) = @_;
146 11         273 $ctx->response->redirect($ctx->uri_for($self->action_for("login")));
147 11         28497 $ctx->detach;
148             }
149              
150             sub redirect_after_login_uri {
151 6     6 1 409 my ($self, $ctx) = @_;
152 6         231 $ctx->uri_for($self->_redirect_after_login_uri);
153             }
154              
155             has _redirect_after_login_uri => (
156             is => Str,
157             is => 'ro',
158             init_arg => 'redirect_after_login_uri',
159             default => '/',
160             );
161              
162             1;
163              
164             =head1 NAME
165              
166             CatalystX::SimpleLogin::Controller::Login - Configurable login controller
167              
168             =head1 SYNOPSIS
169              
170             # For simple useage exmple, see CatalystX::SimpleLogin, this is a
171             # full config example
172             __PACKAGE__->config(
173             'Controller::Login' => {
174             traits => [
175             'WithRedirect', # Optional, enables redirect-back feature
176             '-RenderAsTTTemplate', # Optional, allows you to use your own template
177             ],
178             actions => {
179             login => { # Also optional
180             PathPart => ['theloginpage'], # Change login action to /theloginpage
181             },
182             },
183             },
184             );
185              
186             See L<CatalystX::SimpleLogin::Form::Login> for configuring the form.
187              
188             =head1 DESCRIPTION
189              
190             Controller base class which exists to have login roles composed onto it
191             for the login and logout actions.
192              
193             =head1 ATTRIBUTES
194              
195             =head2 login_form_class
196              
197             A class attribute containing the class of the form to be initialised. One
198             can override it in a derived class with the class of a new form, possibly
199             subclassing L<CatalystX::SimpleLogin::Form::Login>. For example:
200              
201             package MyApp::Controller::Login;
202              
203             use Moose;
204              
205             extends('CatalystX::SimpleLogin::Controller::Login');
206              
207             has '+login_form_class' => (
208             default => "MyApp::Form::Login",
209             );
210              
211             1;
212              
213             =head2 login_form_class_roles
214              
215             An attribute containing an array reference of roles to be consumed by
216             the form. One can override it in a similar way to C<login_form_class>:
217              
218             package MyApp::Controller::Login;
219              
220             use Moose;
221              
222             extends('CatalystX::SimpleLogin::Controller::Login');
223              
224             has '+login_form_class_roles' => (
225             default => sub { [qw(MyApp::FormRole::Foo MyApp::FormRole::Bar)] },
226             );
227              
228             1;
229              
230             =head1 METHODS
231              
232             =head2 BUILD
233              
234             Cause form instance to be built at application startup.
235              
236             =head2 do_post_login_redirect
237              
238             This method does a post-login redirect. B<TODO> for BOBTFISH - should it even
239             be public? If it does need to be public, then document it because the Pod
240             coverage test failed.
241              
242             =head2 login
243              
244             Login action.
245              
246             =head2 login_redirect
247              
248             Redirect to the login action.
249              
250             =head2 login_GET
251              
252             Displays the login form
253              
254             =head2 login_POST
255              
256             Processes a submitted login form, and if correct, logs the user in
257             and redirects
258              
259             =head2 not_required
260              
261             A stub action that is anchored at the root of the site ("/") and does not
262             require registration (hence the name).
263              
264             =head2 redirect_after_login_uri
265              
266             If you are using WithRedirect (i.e. by default), then this method is overridden
267             to redirect the user back to the page they initially hit which required
268             authentication.
269              
270             Note that even if the original URI was a post, then the redirect back will only
271             be a GET.
272              
273             If you choose B<NOT> to compose the WithRedirect trait, then you can set the
274             uri users are redirected to with the C<redirect_after_login_uri> config key,
275             or by overriding the redirect_after_login_uri method in your own login
276             controller if you need custom logic.
277              
278             =head2 render_login_form
279              
280             Renders the login form. By default it just calls the form's render method. If
281             you want to do something different, like rendering the form with a template
282             through your view, this is the place to hook into.
283              
284             =head2 required
285              
286             A stub action that is anchored at the root of the site ("/") and does
287             require registration (hence the name).
288              
289             =head2 remember_me
290              
291             An action that is called to deal with whether the remember me flag has
292             been set or not. If it has been it extends the session expiry time.
293              
294             This is only called if there was a successful login so if you want a
295             hook into that part of the process this is a good place to hook into.
296              
297             It is also obviously a good place to hook into if you want to change
298             the behaviour of the remember me flag.
299              
300             =head1 SEE ALSO
301              
302             =over
303              
304             =item L<CatalystX::SimpleLogin::TraitFor::Controller::Login::WithRedirect>
305              
306             =item L<CatalystX::SimpleLogin::Form::Login>
307              
308             =back
309              
310             =head1 AUTHORS
311              
312             See L<CatalystX::SimpleLogin> for authors.
313              
314             =head1 LICENSE
315              
316             See L<CatalystX::SimpleLogin> for license.
317              
318             =cut
319