File Coverage

blib/lib/CatalystX/SimpleLogin/Controller/Login.pm
Criterion Covered Total %
statement 57 57 100.0
branch 5 6 83.3
condition n/a
subroutine 21 21 100.0
pod 9 9 100.0
total 92 93 98.9


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