File Coverage

blib/lib/Bracket/Controller/Auth.pm
Criterion Covered Total %
statement 1 3 33.3
branch n/a
condition n/a
subroutine 1 1 100.0
pod n/a
total 2 4 50.0


line stmt bran cond sub pod time code
1             package Bracket::Controller::Auth;
2              
3 1     1   31351 use Moose;
  0            
  0            
4             BEGIN { extends 'Catalyst::Controller' }
5             use Time::HiRes qw/ time /;
6             use Bracket::Form::Register;
7             use Bracket::Form::Login;
8             use Bracket::Form::Password::Change;
9             use Bracket::Form::Password::ResetEmail;
10             use Bracket::Form::Password::Reset;
11              
12             sub debug { 0 }
13             require Data::Dumper if debug;
14              
15              
16             =head1 Name
17              
18             Bracket::Controller::Admin - Functions for admin users
19            
20             =head1 Description
21              
22             Controller with authentication related actions:
23              
24             * register
25             * login/logout
26             * change/reset password
27              
28             =cut
29              
30             has 'register_form' => (
31             isa => 'Bracket::Form::Register',
32             is => 'rw',
33             lazy => 1,
34             default => sub { Bracket::Form::Register->new },
35             );
36              
37             has 'login_form' => (
38             isa => 'Bracket::Form::Login',
39             is => 'rw',
40             lazy => 1,
41             default => sub { Bracket::Form::Login->new },
42             );
43              
44             has 'change_password_form' => (
45             isa => 'Bracket::Form::Password::Change',
46             is => 'rw',
47             lazy => 1,
48             default => sub { Bracket::Form::Password::Change->new },
49             );
50              
51             has 'email_reset_password_link_form' => (
52             isa => 'Bracket::Form::Password::ResetEmail',
53             is => 'rw',
54             lazy => 1,
55             default => sub { Bracket::Form::Password::ResetEmail->new },
56             );
57              
58             has 'reset_password_form' => (
59             isa => 'Bracket::Form::Password::Reset',
60             is => 'rw',
61             lazy => 1,
62             default => sub { Bracket::Form::Password::Reset->new },
63             );
64              
65             sub register : Global {
66             my ($self, $c) = @_;
67              
68             $c->stash(
69             template => 'form/auth/register.tt',
70             form => $self->register_form,
71             );
72              
73             my $new_player = $c->model('DBIC::Player')->new_result({});
74             $self->register_form->process(
75             item => $new_player,
76             params => $c->request->parameters,
77             );
78              
79             # This return on GET (new form) and a POSTed form that's invalid.
80             return if !$self->register_form->is_valid;
81              
82             # At this stage the form has validated
83             $c->flash->{status_msg} = 'Registration succeeded';
84             $c->response->redirect($c->uri_for('/login'));
85             }
86              
87             =head2 login
88              
89             Log in through the authentication system.
90              
91             =cut
92              
93             sub login : Global {
94             my ($self, $c) = @_;
95              
96             $c->stash(
97             template => 'form/auth/login.tt',
98             form => $self->login_form,
99             );
100              
101             $self->login_form->process(params => $c->request->parameters,);
102              
103             # This return on GET (new form) and a POSTed form that's invalid.
104             return if !$self->login_form->is_valid;
105              
106             my $is_authenticated = $c->authenticate(
107             {
108             email => $self->login_form->field('email')->value,
109             password => $self->login_form->field('password')->value,
110             }
111             );
112             if (!$is_authenticated) {
113             my $login_URI = $c->uri_for('/login');
114             $c->response->body("Could not <big><a href='$login_URI'>login</a></big>");
115             $c->detach();
116             }
117              
118             my $user_id = $c->user->id;
119             warn "USER ID: $user_id" if debug;
120              
121             # At this stage the form has validated
122             $c->response->redirect(
123             $c->uri_for($c->controller('Player')->action_for('home')) . "/${user_id}",
124             );
125              
126             }
127              
128             =head2 logout
129            
130             Log in through the authentication system.
131              
132             =cut
133              
134             sub logout : Global {
135             my ($self, $c) = @_;
136              
137             $c->logout;
138             $c->response->redirect($c->uri_for('/login'));
139              
140             return;
141             }
142              
143             =head2 change_password
144              
145             Change player password
146              
147             =cut
148              
149             sub change_password : Global {
150             my ($self, $c) = @_;
151              
152             my $form = $self->change_password_form;
153              
154             $c->stash(
155             template => 'form/auth/change_password.tt',
156             form => $form,
157             );
158             $form->process(
159             item_id => $c->user->id,
160             params => $c->request->parameters,
161             schema => $c->model('DBIC')->schema,
162             );
163              
164             return if !$form->is_valid;
165              
166             $c->flash->{status_msg} = 'Password changed';
167             $c->response->redirect($c->uri_for('/account'));
168              
169             }
170              
171             sub email_reset_password_link : Global {
172             my ($self, $c) = @_;
173              
174             my $form = $self->email_reset_password_link_form;
175             $c->stash(
176             template => 'form/auth/reset_password.tt',
177             form => $form,
178             );
179             $form->process(
180             params => $c->request->parameters,
181             schema => $c->model('DBIC')->schema,
182             );
183             return if !$form->is_valid;
184              
185             # Get user based on email.
186             my $to_email = $form->field('email')->value;
187             my $user = $c->model('DBIC::Player')->find({ email => $to_email });
188              
189             # create and email password reset link
190             my $token = create_token($user->id);
191             my $create_token_coderef = sub {
192             $c->model('DBIC::Token')->create(
193             {
194             player => $user->id,
195             token => $token,
196             type => 'reset_password',
197             }
198             );
199             };
200             eval { $c->model('DBIC')->schema->txn_do($create_token_coderef); };
201             if ($@) {
202             my $message = "Not able to create token\n";
203             warn $message . $@;
204             $c->flash->{status_msg} = $message;
205             }
206             else {
207             $c->forward($self->action_for('email_link'), [ $to_email, $token ]);
208             $c->flash->{status_msg} =
209             "A password reset </strong>link</strong> has been <strong>emailed to you.</strong>";
210             $c->response->redirect($c->uri_for('/message'));
211             }
212             }
213              
214             sub reset_password : Global {
215             my ($self, $c) = @_;
216              
217             my $token = $c->request->query_parameters->{reset_password_token};
218             warn "TOKEN: $token\n" if debug;
219             my ($user_id) = $token =~ /_(\d+)$/;
220             warn "USER ID for RESET: $user_id\n" if debug;
221             my $token_row_object =
222             $c->model('DBIC::Token')
223             ->search({ player => $user_id, token => $token, type => 'reset_password' })->first;
224             if (!$token_row_object) {
225             $c->response->body("Token not found.");
226             $c->detach();
227             }
228              
229             my $form = $self->reset_password_form;
230             my $player_object = $token_row_object->player;
231             $c->stash(
232             template => 'form/auth/reset_password.tt',
233             form => $form,
234             );
235             $form->process(
236             item => $player_object,
237             params => $c->request->body_parameters,
238             schema => $c->model('DBIC')->schema,
239             );
240             return if !$form->is_valid;
241              
242             $c->flash->{status_msg} = "Password has been reset.";
243             $c->response->redirect($c->uri_for('/login'));
244             }
245              
246             sub create_token {
247             my $user_id = shift;
248             return time . rand(10000) . "_${user_id}";
249             }
250              
251             sub email_link : Private {
252             my ($self, $c, $to_email, $token) = @_;
253              
254             use Email::Sender::Simple qw(try_to_sendmail);
255             use Email::Simple;
256             use Email::Simple::Creator;
257             use Email::Sender::Transport::Test;
258              
259             my $link = $c->request->base . 'reset_password?reset_password_token=' . $token;
260             my $admin_email = 'hunter@missoula.org';
261             my $subject = 'Reset password link';
262             my $message = <<"END_MESSAGE";
263             Use the following link to reset your password:
264             $link
265             END_MESSAGE
266              
267             my $email = Email::Simple->create(
268             header => [
269             To => $to_email,
270             From => $admin_email,
271             Subject => $subject,
272             ],
273             body => $message,
274             );
275             my $success = try_to_sendmail($email);
276             }
277              
278             sub message : Global {
279             my ($self, $c) = @_;
280              
281             $c->stash->{template} = 'empty.tt';
282             }
283              
284             1