From 7081a432116688f6fc6bd37b77fe84cb94cd5ecf Mon Sep 17 00:00:00 2001 From: Alex Buckley Date: Tue, 5 May 2020 09:18:46 +0000 Subject: [PATCH] Bug 25090: Allow libraries to verify OPAC self registrations These patchsets add two new sysprefs (to replace PatronSelfRegistrationVerifyByEmail), they are: * PatronSelfRegistrationVerifyByEmailToLibrary - Library verifies OPAC self registrations before a record is added to borrowers database table * PatronSelfRegistrationVerifyByEmailToPatron - Patron must verify their email before a record is added to borrowers database table ---------- 4 possible email verification workflow scenarios: 1) library verification = disabled & patron verification = disabled : 1a) Patron submits OPAC self reg form 1b) Patron account created immediately 2) library verification = enabled & patron verification = disabled : 2a) Patron submits OPAC self reg form 2b) Koha sends notice to library to review registration 2c) Library approves reg by clicking verification link in notice 2d) Patron account is created 2e) Password reset link emailed to patron 3) library verification = disabled & patron verification = enabled : 3a) Patron submits OPAC self reg form 3b) Koha sends verification email to patron 3c) Patron clicks verification link in notice 3d) Patron account is created 4) library verification = enabled & patron verification = enabled : 4a) Patron submits OPAC self reg form 4b) Koha sends verification email to patron to verify email 4c) Patron clicks verification link in notice 4d) Koha sends notice to library to review registration 4e) Library approves reg by clicking verification link in notice 4f) Patron account created 4g) Password reset link emailed to patron ----------- Test plan (in each test plan step where you must fill in OPAC self reg form please use a different email address): 1. Apply patch and restart plack 2. Update database: cd installer/data/mysql sudo koha-shell ./updatedatabase.pl 3. Observe 2 new sysprefs in same line in editor (and observe PatronSelfRegistrationVerifyByEmail syspref has been removed): * PatronSelfRegistrationVerifyByEmailToLibrary - Set to 'None' by default * PatronSelfRegistrationVerifyByEmailToPatron - Set to "Don't require" by default. (Exception: If PatronSelfRegistrationVerifyByEmail syspref was enabled before applying this patch then PatronSelfregistrationVerifyByEmailToPatron will now be enabled). [Test scenario 1] 4. Set the following sysprefs: * PatronSelfRegistration - enabled * OpacResetPassword - enabled * PatronSelfRegistrationVerifyByEmailToLibrary - 'None' * PatronSelfRegistrationVerifyByEmailToPatron - "Don't require" Also set different values in: * KohaAdminEmailAddress syspref * ReplyToAddress syspref * branch email address (Administration > Libraries) 5. Visit OPAC, fill in, submit OPAC registration form 6. Observe your patron account has been created immediately and you can login [Test scenario 2] 6. Set PatronSelfRegistrationVerifyByEmailToLibrary to 'email address of branch' 7. Repeat step 5 and query the database: select to_address, content from message_queue where letter_code='STAFF_VER_OPAC_REG'; 8. Observe the verification email's to_address is library branch email address (i.e. set in Administration > Libraries ) and the notice contains the following information: * Card number * Name: title firstname surname * Physical address: streetnumber, streettype, address, address2, city, state, zipcode, country * Email * Phone * Mobile * Fax * Secondary email * Secondary phone * Home library * Temporary patron category And a verification link 9. Query database again: select count(*) from borrowers where email=; select count(*) from borrower_modifications where email=; The first query returns 0 (as the patron account has not been added to borrowers table), the second query has 1 as patron in borrower_modifications table. 10. Click verification link in notice and query database: select * from borrowers where email= 11. Observe the patron account has now been added to the borrowers table 12. Query database: select to_address, content from message_queue where letter_code='SELF_REG_APPROVED'; 13. Observe password reset link emailed to patron, click on the link and observe the password reset page loads with the patrons username and email pre-filled 14. Set PatronSelfRegistrationVerifyByEmailToLibrary to 'KohaAdminEmailAddress' 15. Repeat step 7 observing the verification email's to_address is ReplytoDefault syspref value (if this is not set then KohaAdminEmailAddress i.e. fallback same as EmailPurchaseSuggestions syspref). 16. Repeat steps 9, 10, 11, 12, 13 which should all have the same outcomes [Test scenario 3] 17. Set PatronSelfRegistrationVerifyByEmailToPatron to "Require" PatronSelfRegistrationVerifyByEmailToLibrary to "None" 18. Repeat step 5 19. Query the database with these 4 queries (explanations of what outputs to expect are hypehnated below each query: select to_address, content from message_queue where letter_code='OPAC_REG_VERIFY'; - You'll see 1 new OPAC_REG_VERIFY notice sent to the patrons inputted email select to_address, content from message_queue where letter_code='STAFF_VER_OPAC_REG'; - You'll see no new STAFF_VER_OPAC_REG notice generated (because PatronSelfRegistrationVerifyByEmailToLibrary is set to "None") select count(*) from borrowers where email=; - Returns 0 as patron account not added to borrowers table yet select count(*) from borrower_modifications where email=; - Returns 1 as patron account is in borrower_modifications table 20. Click verification link in OPAC_REG_VERIFY notice and query database: select count(*) from borrowers where email= This returns 1 as patron account now in borrowers table [Test scenario 4] 21. Set PatronSelfRegistrationVerifyByEmailToLibrary = 'email address of branch' 22. Repeat steps 5 and query the database: select to_address, content from message_queue where letter_code='PATRON_AND_LIB_VER'; - You'll see 1 new PATRON_AND_LIB_VER notice sent to the patrons inputted email select to_address, content from message_queue where letter_code='OPAC_REG_VERIFY'; - You'll see no new OPAC_REG_VERIFY notice as when library & patron verification are both enabled the PATRON_AND_LIB_VER notice is sent to the patron instead select to_address, content from message_queue where letter_code='STAFF_VER_OPAC_REG'; - You'll see no new STAFF_VER_OPAC_REG notice generated (it is generated later on in the workflow of scenario 4) select count(*) from borrowers where email=; - Returns 0 as patron account not added to borrowers table yet select count(*) from borrower_modifications where email=; - Returns 1 as patron account is in borrower_modifications table 23. Click verification link in PATRON_AND_LIB_VER notice 24. Query the database: select to_address, content from message_queue where letter_code='OPAC_REG_VERIFY'; - Returns no new OPAC_REG_VERIFY notice select to_address, content from message_queue where letter_code='STAFF_VER_OPAC_REG'; - This returns a row result. Note it contains patron details for librarians to review and the to_address is the library branch email. select count(*) from borrowers where email=; - This returns 0 as library still hasn't verified patron account can be created yet select count(*) from borrower_modifications where email=; - This returns a row result as patron account still in borrower_modifications table 25. Click on verification link in STAFF_VER_OPAC_REG notice 26. Query the database: select count(*) from borrowers where email=; - This returns a row result as patron account created select to_address, content from message_queue where letter_code='SELF_REG_APPROVED'; - This returns a row result with the to_address being the patrons email. Click on the password reset link in the notice and observe the password reset page pre-fills with the patron username and email. 27. Run tests: sudo koha-shell prove xt prove t Sponsored-By: Mental Health Education Resource Centre, NZ --- opac/opac-memberentry.pl | 80 +++++++++++++++++++----- opac/opac-password-recovery.pl | 8 ++- opac/opac-registration-verify.pl | 131 ++++++++++++++++++++++++++++++++------- 3 files changed, 180 insertions(+), 39 deletions(-) diff --git a/opac/opac-memberentry.pl b/opac/opac-memberentry.pl index faf32e8285..cd368c381d 100755 --- a/opac/opac-memberentry.pl +++ b/opac/opac-memberentry.pl @@ -157,9 +157,11 @@ if ( $action eq 'create' ) { $template->param( patron_attribute_classes => GeneratePatronAttributesForm( undef, $attributes ) ); } else { + my $patronverification = C4::Context->boolean_preference('PatronSelfRegistrationVerifyByEmailToPatron'); + my $libraryverification = C4::Context->preference('PatronSelfRegistrationVerifyByEmailToLibrary'); if ( - C4::Context->boolean_preference( - 'PatronSelfRegistrationVerifyByEmail') + $patronverification + || $libraryverification ) { ( $template, $borrowernumber, $cookie ) = get_template_and_user( @@ -182,28 +184,78 @@ if ( $action eq 'create' ) { Koha::Patron::Modification->new( \%borrower )->store(); - #Send verification email - my $letter = C4::Letters::GetPreparedLetter( - module => 'members', - letter_code => 'OPAC_REG_VERIFY', - lang => 'default', # Patron does not have a preferred language defined yet - tables => { - borrower_modifications => $verification_token, - }, - ); + my $letter_code; + my $action; + my $toaddress; + my $letter; + if ($patronverification && !$libraryverification) { + $action = 'patrontoverify'; + } elsif ($patronverification && $libraryverification) { + $action = 'patronandlibrarytoverify'; + } else { + $action = 'librarytoverify'; + } + $template->param( action => $action ); + + if ($action eq 'patrontoverify') { + # Send verification email to patron + $letter_code = 'OPAC_REG_VERIFY'; + $letter = C4::Letters::GetPreparedLetter( + module => 'members', + letter_code => $letter_code, + lang => 'default', # Patron does not have a preferred language defined yet + tables => { + borrower_modifications => $verification_token, + }, + ); + $toaddress = $borrower{'email'}; + } elsif ($action eq 'patronandlibrarytoverify') { + $letter_code = 'PATRON_AND_LIB_VER'; + $letter = C4::Letters::GetPreparedLetter( + module => 'members', + letter_code => $letter_code, + lang => 'default', + tables => { + borrower_modifications => $verification_token, + }, + ); + $toaddress = $borrower{'email'}; + } else { + # Send verification email to library + $letter_code = 'STAFF_VER_OPAC_REG'; + $letter = C4::Letters::GetPreparedLetter( + module => 'members', + letter_code => $letter_code, + lang => 'default', # Patron does not have a preferred language defined yet + tables => { + borrower_modifications => $verification_token, + }, + ); + if ($libraryverification eq "BranchEmailAddress") { + my $library = Koha::Libraries->find( $borrower{branchcode} ); + $toaddress = $library->branchreplyto + || $library->branchemail + || C4::Context->preference('ReplytoDefault') + || C4::Context->preference('KohaAdminEmailAddress') + } elsif ($libraryverification eq "KohaAdminEmailAddress") { + $toaddress = C4::Context->preference('ReplytoDefault') + || C4::Context->preference('KohaAdminEmailAddress'); + } + } C4::Letters::EnqueueLetter( { letter => $letter, message_transport_type => 'email', - to_address => $borrower{'email'}, + to_address => $toaddress, from_address => C4::Context->preference('KohaAdminEmailAddress'), } ); + my $num_letters_attempted = C4::Letters::SendQueuedMessages( { - letter_code => 'OPAC_REG_VERIFY' - } ); + letter_code => $letter_code + } ); } else { ( $template, $borrowernumber, $cookie ) = get_template_and_user( diff --git a/opac/opac-password-recovery.pl b/opac/opac-password-recovery.pl index a695165b56..92786f7935 100755 --- a/opac/opac-password-recovery.pl +++ b/opac/opac-password-recovery.pl @@ -34,6 +34,8 @@ my $uniqueKey = $query->param('uniqueKey'); my $username = $query->param('username') // q{}; my $borrower_number; +$borrower_number = $query->param('borrowernumber') if ($query->param('borrowernumber')); + #errors my $hasError; @@ -208,7 +210,11 @@ elsif ($uniqueKey) { #reset password form ); } else { #password recovery form (to send email) - $template->param( password_recovery => 1 ); + my $borrower = Koha::Patrons->find($borrower_number); + $template->param( email => $borrower->email, username => $borrower->userid ) if $borrower; + $template->param( + password_recovery => 1, + ); } output_html_with_http_headers $query, $cookie, $template->output; diff --git a/opac/opac-registration-verify.pl b/opac/opac-registration-verify.pl index d408d5c5ae..ddce1a7553 100755 --- a/opac/opac-registration-verify.pl +++ b/opac/opac-registration-verify.pl @@ -58,33 +58,116 @@ if ( } ); - my $patron_attrs = $m->unblessed; - $patron_attrs->{password} ||= Koha::AuthUtils::generate_password; - my $consent_dt = delete $patron_attrs->{gdpr_proc_consent}; - $patron_attrs->{categorycode} ||= C4::Context->preference('PatronSelfRegistrationDefaultCategory'); - delete $patron_attrs->{timestamp}; - delete $patron_attrs->{verification_token}; - delete $patron_attrs->{changed_fields}; - my $patron = Koha::Patron->new( $patron_attrs )->store; - - Koha::Patron::Consent->new({ borrowernumber => $patron->borrowernumber, type => 'GDPR_PROCESSING', given_on => $consent_dt })->store if $consent_dt; - - if ($patron) { - $m->delete(); - C4::Form::MessagingPreferences::handle_form_action($cgi, { borrowernumber => $patron->borrowernumber }, $template, 1, C4::Context->preference('PatronSelfRegistrationDefaultCategory') ) if C4::Context->preference('EnhancedMessagingPreferences'); - - $template->param( password_cleartext => $patron->plain_text_password ); - $template->param( borrower => $patron ); - $template->param( - PatronSelfRegistrationAdditionalInstructions => - C4::Context->preference( - 'PatronSelfRegistrationAdditionalInstructions') + my $libraryhasverified = $cgi->param('approved'); + my $needlibraryverification = C4::Context->preference('PatronSelfRegistrationVerifyByEmailToLibrary'); + + my $action; + if ( $libraryhasverified && $needlibraryverification ) { + $action = 'libraryhasverified'; + } elsif ( !$libraryhasverified && $needlibraryverification ) { + $action = 'librarytoverify'; + } else { + $action = 'nolibraryverification'; + } + + $template->param( action => $action ); + + if ($action eq 'nolibraryverification' || $action eq 'libraryhasverified') { + + # Create account as library verification not required or already done + my $patron_attrs = $m->unblessed; + $patron_attrs->{password} ||= Koha::AuthUtils::generate_password; + my $consent_dt = delete $patron_attrs->{gdpr_proc_consent}; + $patron_attrs->{categorycode} ||= C4::Context->preference('PatronSelfRegistrationDefaultCategory'); + delete $patron_attrs->{timestamp}; + delete $patron_attrs->{verification_token}; + delete $patron_attrs->{changed_fields}; + my $patron = Koha::Patron->new( $patron_attrs )->store; + + # If library verification required then send password reset email directly to patron + if ($needlibraryverification) { + my $letter = C4::Letters::GetPreparedLetter( + module => 'members', + letter_code => 'SELF_REG_APPROVED', + lang => 'default', # Patron does not have a preferred language defined yet + tables => { + borrowers => $patron->borrowernumber, + }, + ); + + C4::Letters::EnqueueLetter( + { + letter => $letter, + message_transport_type => 'email', + to_address => $patron->email, + from_address => C4::Context->preference('KohaAdminEmailAddress'), + } + ); + + my $num_letters_attempted = C4::Letters::SendQueuedMessages( { + letter_code => 'SELF_REG_APPROVED' + } ); + } + + Koha::Patron::Consent->new({ borrowernumber => $patron->borrowernumber, type => 'GDPR_PROCESSING', given_on => $consent_dt })->store if $consent_dt; + + if ($patron) { + $m->delete(); + C4::Form::MessagingPreferences::handle_form_action($cgi, { borrowernumber => $patron->borrowernumber }, $template, 1, C4::Context->preference('PatronSelfRegistrationDefaultCategory') ) if C4::Context->preference('EnhancedMessagingPreferences'); + + $template->param( password_cleartext => $patron->plain_text_password ); + $template->param( borrower => $patron ); + $template->param( + PatronSelfRegistrationAdditionalInstructions => + C4::Context->preference( + 'PatronSelfRegistrationAdditionalInstructions') + ); + + my ($theme, $news_lang, $availablethemes) = C4::Templates::themelanguage(C4::Context->config('opachtdocs'),'opac-registration-confirmation.tt','opac',$cgi); + $template->param( news_lang => $news_lang ); + } + + } else { + + # Send verification email to library to approve + my $toaddress; + if ($needlibraryverification eq "BranchEmailAddress" ) { + my $library = Koha::Libraries->find( $m->branchcode ); + $toaddress = $library->branchreplyto + || $library->branchemail + || C4::Context->preferences('ReplytoDefault') + || C4::Context->preferences('KohaAdminEmailAddress') + } + elsif ( $needlibraryverification eq "KohaAdminEmailAddress" ) { + $toaddress = C4::Context->preference('ReplytoDefault') + || C4::Context->preference('KohaAdminEmailAddress'); + } + + my $patron_attrs = $m->unblessed; + my $letter; + # Send verification email to library + $letter = C4::Letters::GetPreparedLetter( + module => 'members', + letter_code => 'STAFF_VER_OPAC_REG', + lang => 'default', # Patron does not have a preferred language defined yet + tables => { + borrower_modifications => $patron_attrs->{verification_token}, + }, ); - my ($theme, $news_lang, $availablethemes) = C4::Templates::themelanguage(C4::Context->config('opachtdocs'),'opac-registration-confirmation.tt','opac',$cgi); - $template->param( news_lang => $news_lang ); + C4::Letters::EnqueueLetter( + { + letter => $letter, + message_transport_type => 'email', + to_address => $toaddress, + from_address => + C4::Context->preference('KohaAdminEmailAddress'), + } + ); + my $num_letters_attempted = C4::Letters::SendQueuedMessages( { + letter_code => 'STAFF_VER_OPAC_REG' + } ); } - } else { ( $template, $borrowernumber, $cookie ) = get_template_and_user( -- 2.11.0