Bug 8753 - Use Koha::Borrowers instead of C4::Members
[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 qw(SendPasswordRecoveryEmail ValidateBorrowernumber GetValidLinkInfo CompletePasswordRecovery);
13 use Koha::AuthUtils qw(hash_password);
14 use Koha::Borrowers;
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 $minPassLength  = C4::Context->preference('minPasswordLength');
32 my $id             = $query->param('id');
33 my $uniqueKey      = $query->param('uniqueKey');
34 my $username       = $query->param('username');
35 my $borrower_number;
36
37 #errors
38 my $hasError;
39
40 #email form error
41 my $errNoBorrowerFound;
42 my $errNoBorrowerEmail;
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     #try with the main email
54     $email ||= ''; # avoid undef
55     my $borrower;
56     my $search_results;
57     # Find the borrower by his userid or email
58     if( $username ){
59         $search_results = [ Koha::Borrowers->search({ userid => $username }) ];
60     }
61     elsif ( $email ){
62         $search_results = [ Koha::Borrowers->search({-or => {email => $email, emailpro=> $email, B_email=>$email }}) ];
63     }
64     if ( not $search_results ){
65        $hasError            = 1;
66        $errNoBorrowerFound  = 1;
67     }
68     elsif(scalar @$search_results > 1){ # Many matching borrowers
69        $hasError             = 1;
70        $errTooManyEmailFound = 1;
71     }
72     elsif( $borrower = shift @$search_results ){ # One matching borrower
73         $username ||= $borrower->userid;
74         my @emails = ( $borrower->email, $borrower->emailpro, $borrower->B_email );
75         # Is the given email one of the borrower's ?
76         if( $email && !($email ~~ @emails) ){
77              $hasError    = 1;
78              $errBadEmail = 1;
79         }
80         # If we dont have an email yet. Get one of the borrower's email or raise an error.
81         # FIXME: That ugly shift-grep contraption.
82         # $email = shift [ grep { length() } @emails ]
83         # It's supposed to get a non-empty string from the @emails array. There's surely a simpler way
84         elsif( !$email && !($email = shift [ grep { length() } @emails ]) ){
85              $hasError           = 1;
86              $errNoBorrowerEmail = 1;
87         }
88         # Check if a password reset already issued for this borrower AND we are not asking for a new email
89         elsif( ValidateBorrowernumber( $borrower->borrowernumber ) && !$query->param('resendEmail') ){
90             $hasError                = 1;
91             $errAlreadyStartRecovery = 1;
92         }
93     }
94     else{ # 0 matching borrower
95         $hasError           = 1;
96         $errNoBorrowerFound = 1;
97     }
98     if ($hasError) {
99         $template->param(
100             hasError                => 1,
101             errNoBorrowerFound      => $errNoBorrowerFound,
102             errTooManyEmailFound    => $errTooManyEmailFound,
103             errAlreadyStartRecovery => $errAlreadyStartRecovery,
104             errBadEmail             => $errBadEmail,
105             errNoBorrowerEmail      => $errNoBorrowerEmail,
106             password_recovery       => 1,
107             email                   => HTML::Entities::encode($email),
108             username                => $username
109         );
110     }
111     elsif ( SendPasswordRecoveryEmail( $borrower, $email, $query->param('resendEmail') ) ) {#generate uuid and send recovery email
112         $template->param(
113             mail_sent => 1,
114             email     => $email
115         );
116     }
117     else {# if it doesn't work....
118         $template->param(
119             password_recovery => 1,
120             sendmailError     => 1
121         );
122     }
123 }
124 elsif ( $query->param('passwordReset') ) {
125     ( $borrower_number, $username ) = GetValidLinkInfo($uniqueKey);
126     #validate password length & match
127     if (   ($borrower_number)
128         && ( $password eq $repeatPassword )
129         && ( length($password) >= $minPassLength ) )
130     {  #apply changes
131         changepassword( $username, $borrower_number, hash_password($password) );
132         CompletePasswordRecovery($uniqueKey);
133         $template->param(
134             password_reset_done => 1,
135             username            => $username
136         );
137     }
138     else { #errors
139         if ( !$borrower_number ) { #parameters not valid
140             $errLinkNotValid = 1;
141         }
142         elsif ( $password ne $repeatPassword ) { #passwords does not match
143             $errPassNotMatch = 1;
144         }
145         elsif ( length($password) < $minPassLength ) { #password too short
146             $errPassTooShort = 1;
147         }
148         $template->param(
149             new_password    => 1,
150             minPassLength   => $minPassLength,
151             email           => $email,
152             uniqueKey       => $uniqueKey,
153             errLinkNotValid => $errLinkNotValid,
154             errPassNotMatch => $errPassNotMatch,
155             errPassTooShort => $errPassTooShort,
156             hasError        => 1
157         );
158     }
159 }
160 elsif ($uniqueKey) {  #reset password form
161     #check if the link is valid
162     ( $borrower_number, $username ) = GetValidLinkInfo($uniqueKey);
163
164     if ( !$borrower_number ) {
165         $errLinkNotValid = 1;
166     }
167
168     $template->param(
169         new_password    => 1,
170         minPassLength   => $minPassLength,
171         email           => $email,
172         uniqueKey       => $uniqueKey,
173         username        => $username,
174         errLinkNotValid => $errLinkNotValid
175     );
176 }
177 else { #password recovery form (to send email)
178     $template->param( password_recovery => 1 );
179 }
180
181 output_html_with_http_headers $query, $cookie, $template->output;