1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
|
package FixMyStreet::App::Controller::Auth::Phone;
use Moose;
use namespace::autoclean;
BEGIN { extends 'Catalyst::Controller'; }
use FixMyStreet::SMS;
=head1 NAME
FixMyStreet::App::Controller::Auth::Phone - Catalyst Controller
=head1 DESCRIPTION
Controller for phone SMS based authentication
=head1 METHODS
=head2 code
Handle the submission of a code sent by text to a mobile number.
=cut
sub code : Path('') {
my ( $self, $c, $scope, $success_action ) = @_;
$c->stash->{template} = 'auth/smsform.html';
$scope ||= 'phone_sign_in';
$success_action ||= '/auth/process_login';
my $token = $c->stash->{token} = $c->get_param('token');
my $code = $c->get_param('code') || '';
my $data = $c->stash->{token_data} = $c->forward('/auth/get_token', [ $token, $scope ]) || return;
$c->stash->{incorrect_code} = 1, return if $data->{code} ne $code;
$c->detach( $success_action, [ $data, 'phone' ] );
}
=head2 sign_in
When signing in with a mobile phone number, we are sent here.
This sends a text to that number with a confirmation code,
and sets up the token/etc to deal with the response.
=cut
sub sign_in : Private {
my ( $self, $c, $parsed ) = @_;
unless ($parsed->{phone}) {
$c->stash->{username_error} = 'other_phone';
return;
}
unless ($parsed->{may_be_mobile}) {
$c->stash->{username_error} = 'nonmobile';
return;
}
my $password = $c->get_param('password_register');
if ($password) {
return unless $c->forward('/auth/test_password', [ $password ]);
}
(my $number = $parsed->{phone}->format) =~ s/\s+//g;
if ( FixMyStreet->config('SIGNUPS_DISABLED')
&& !$c->model('DB::User')->find({ phone => $number })
&& !$c->stash->{current_user} # don't break the change phone flow
) {
$c->stash->{template} = 'auth/token.html';
return;
}
my $user_params = {};
$user_params->{password} = $password if $password;
my $user = $c->model('DB::User')->new( $user_params );
my $token_data = {
phone => $number,
r => $c->get_param('r'),
name => $c->get_param('name'),
password => $user->password,
};
if ($c->stash->{current_user}) {
$token_data->{old_user_id} = $c->stash->{current_user}->id;
$token_data->{r} = 'auth/change_phone/success';
}
$c->forward('send_token', [ $token_data, 'phone_sign_in', $number ]);
}
sub send_token : Private {
my ( $self, $c, $token_data, $token_scope, $to ) = @_;
my $result = FixMyStreet::SMS->send_token($token_data, $token_scope, $to);
if ($result->{error}) {
$c->log->debug("Failure sending text containing code *$result->{random}*");
$c->stash->{sms_error} = $result->{error};
$c->stash->{username_error} = 'sms_failed';
return;
}
$c->stash->{token} = $result->{token};
$c->log->debug("Sending text containing code *$result->{random}*");
$c->stash->{template} = 'auth/smsform.html';
}
__PACKAGE__->meta->make_immutable;
1;
|