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