Bug 8753 - Various little things - removing new dependency, changes to errors, textua...
[koha.git] / opac / opac-password-recovery.pl
1 #!/usr/bin/perl
2
3 use strict;
4 use Modern::Perl;
5 use CGI;
6
7 use C4::Auth;
8 use C4::Koha;
9 use C4::Members qw(changepassword);
10 use C4::Output;
11 use C4::Context;
12 use C4::Passwordrecovery
13   qw(SendPasswordRecoveryEmail ValidateBorrowernumber GetValidLinkInfo CompletePasswordRecovery);
14 use Koha::AuthUtils qw(hash_password);
15 use Koha::Borrowers;
16 my $query = new CGI;
17 use HTML::Entities;
18
19 my ( $template, $dummy, $cookie ) = get_template_and_user(
20     {
21         template_name   => "opac-password-recovery.tt",
22         query           => $query,
23         type            => "opac",
24         authnotrequired => 1,
25         debug           => 1,
26     }
27 );
28
29 my $email          = $query->param('email') // q{};
30 my $password       = $query->param('password');
31 my $repeatPassword = $query->param('repeatPassword');
32 my $minPassLength  = C4::Context->preference('minPasswordLength');
33 my $id             = $query->param('id');
34 my $uniqueKey      = $query->param('uniqueKey');
35 my $username       = $query->param('username');
36 my $borrower_number;
37
38 #errors
39 my $hasError;
40
41 #email form error
42 my $errNoBorrowerFound;
43 my $errNoBorrowerEmail;
44 my $errAlreadyStartRecovery;
45 my $errTooManyEmailFound;
46 my $errBadEmail;
47
48 #new password form error
49 my $errLinkNotValid;
50 my $errPassNotMatch;
51 my $errPassTooShort;
52
53 if ( $query->param('sendEmail') || $query->param('resendEmail') ) {
54
55     #try with the main email
56     $email ||= '';    # avoid undef
57     my $borrower;
58     my $search_results;
59
60     # Find the borrower by his userid or email
61     if ($username) {
62         $search_results = [ Koha::Borrowers->search( { userid => $username } ) ];
63     }
64     elsif ($email) {
65         $search_results = [ Koha::Borrowers->search( { -or => { email => $email, emailpro => $email, B_email  => $email } } ) ];
66     }
67     if ( not $search_results || scalar @$search_results > 1 ) {
68         $hasError           = 1;
69         $errNoBorrowerFound = 1;
70     }
71     elsif ( $borrower = shift @$search_results ) {    # One matching borrower
72         $username ||= $borrower->userid;
73         my @emails = ( $borrower->email, $borrower->emailpro, $borrower->B_email );
74
75         # Is the given email one of the borrower's ?
76         if ( $email && !( grep { $_ eq $email } @emails ) ) {
77             $hasError    = 1;
78             $errNoBorrowerFound = 1;
79         }
80
81 # If we dont have an email yet. Get one of the borrower's email or raise an error.
82 # FIXME: That ugly shift-grep contraption.
83 # $email = shift [ grep { length() } @emails ]
84 # It's supposed to get a non-empty string from the @emails array. There's surely a simpler way
85         elsif ( !$email && !( $email = shift [ grep { length() } @emails ] ) ) {
86             $hasError           = 1;
87             $errNoBorrowerFound = 1;
88         }
89
90 # Check if a password reset already issued for this borrower AND we are not asking for a new email
91         elsif ( ValidateBorrowernumber( $borrower->borrowernumber )
92             && !$query->param('resendEmail') )
93         {
94             $hasError                = 1;
95             $errAlreadyStartRecovery = 1;
96         }
97     }
98     else {    # 0 matching borrower
99         $hasError           = 1;
100         $errNoBorrowerFound = 1;
101     }
102     if ($hasError) {
103         $template->param(
104             hasError                => 1,
105             errNoBorrowerFound      => $errNoBorrowerFound,
106             errTooManyEmailFound    => $errTooManyEmailFound,
107             errAlreadyStartRecovery => $errAlreadyStartRecovery,
108             errBadEmail             => $errBadEmail,
109             errNoBorrowerEmail      => $errNoBorrowerEmail,
110             password_recovery       => 1,
111             email                   => HTML::Entities::encode($email),
112             username                => $username
113         );
114     }
115     elsif ( SendPasswordRecoveryEmail( $borrower, $email, $query->param('resendEmail') ) ) {    # generate uuid and send recovery email
116         $template->param(
117             mail_sent => 1,
118             email     => $email
119         );
120     }
121     else {    # if it doesn't work....
122         $template->param(
123             password_recovery => 1,
124             sendmailError     => 1
125         );
126     }
127 }
128 elsif ( $query->param('passwordReset') ) {
129     ( $borrower_number, $username ) = GetValidLinkInfo($uniqueKey);
130
131     #validate password length & match
132     if (   ($borrower_number)
133         && ( $password eq $repeatPassword )
134         && ( length($password) >= $minPassLength ) )
135     {    #apply changes
136         changepassword( $username, $borrower_number, hash_password($password) );
137         CompletePasswordRecovery($uniqueKey);
138         $template->param(
139             password_reset_done => 1,
140             username            => $username
141         );
142     }
143     else {    #errors
144         if ( !$borrower_number ) {    #parameters not valid
145             $errLinkNotValid = 1;
146         }
147         elsif ( $password ne $repeatPassword ) {    #passwords does not match
148             $errPassNotMatch = 1;
149         }
150         elsif ( length($password) < $minPassLength ) {    #password too short
151             $errPassTooShort = 1;
152         }
153         $template->param(
154             new_password    => 1,
155             minPassLength   => $minPassLength,
156             email           => $email,
157             uniqueKey       => $uniqueKey,
158             errLinkNotValid => $errLinkNotValid,
159             errPassNotMatch => $errPassNotMatch,
160             errPassTooShort => $errPassTooShort,
161             hasError        => 1
162         );
163     }
164 }
165 elsif ($uniqueKey) {    #reset password form
166                         #check if the link is valid
167     ( $borrower_number, $username ) = GetValidLinkInfo($uniqueKey);
168
169     if ( !$borrower_number ) {
170         $errLinkNotValid = 1;
171     }
172
173     $template->param(
174         new_password    => 1,
175         minPassLength   => $minPassLength,
176         email           => $email,
177         uniqueKey       => $uniqueKey,
178         username        => $username,
179         errLinkNotValid => $errLinkNotValid,
180         hasError        => ( $errLinkNotValid ? 1 : 0 ),
181     );
182 }
183 else {    #password recovery form (to send email)
184     $template->param( password_recovery => 1 );
185 }
186
187 output_html_with_http_headers $query, $cookie, $template->output;