From d2c929d23f30cba40adaa68763cdcd529f98a2a5 Mon Sep 17 00:00:00 2001 From: Tomas Cohen Arazi Date: Tue, 29 Jul 2025 18:20:34 -0300 Subject: [PATCH] Bug 40545: Add utility script for resetting 2FA settings This adds a command-line utility script that allows administrators to reset a patron's two-factor authentication settings when they lose access to their authenticator device. The script uses the new Koha::Patron methods and provides: * Parameter validation (mutually exclusive userid/cardnumber/patron_id) * User-friendly error messages and feedback * Verification that patron has 2FA enabled before attempting reset To test: 1. Enable TwoFactorAuthentication system preference 2. Set up 2FA for a test patron 3. Run: $ ktd --shell k$ perl misc/admin/reset_2fa.pl --userid => SUCCESS: Script resets 2FA and shows confirmation message 4. Verify patron can log in with password only 5. Test error cases: - No parameters: shows usage message - Multiple parameters: shows mutual exclusivity error - Non-existent user: shows user not found error - User without 2FA: shows informational message => SUCCESS: All scenarios work as expected 6. Sign off :-D Signed-off-by: David Nind --- misc/admin/reset_2fa.pl | 150 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 150 insertions(+) create mode 100755 misc/admin/reset_2fa.pl diff --git a/misc/admin/reset_2fa.pl b/misc/admin/reset_2fa.pl new file mode 100755 index 00000000000..91a0942cba1 --- /dev/null +++ b/misc/admin/reset_2fa.pl @@ -0,0 +1,150 @@ +#!/usr/bin/perl + +# This file is part of Koha. +# +# Copyright 2025 Koha Development Team +# +# Koha is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3 of the License, or +# (at your option) any later version. +# +# Koha is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with Koha; if not, see . + +use Modern::Perl; + +use Getopt::Long qw( GetOptions ); +use Pod::Usage qw( pod2usage ); + +use Koha::Patrons; +use Koha::Script; + +my ( $help, $cardnumber, $patron_id, $userid ); +GetOptions( + 'help|?' => \$help, + 'userid=s' => \$userid, + 'patron_id=s' => \$patron_id, + 'cardnumber=s' => \$cardnumber, +); + +pod2usage(1) if $help; + +# Validate that exactly one parameter is provided (mutually exclusive) +my $param_count = grep { defined } ( $userid, $patron_id, $cardnumber ); + +if ( $param_count == 0 ) { + pod2usage("Error: One of --userid, --patron_id, or --cardnumber is required"); +} elsif ( $param_count > 1 ) { + pod2usage("Error: Only one of --userid, --patron_id, or --cardnumber can be specified"); +} + +# Build search filter based on the provided parameter +my $filter = {}; +my $search_type; + +if ($userid) { + $filter->{userid} = $userid; + $search_type = "userid '$userid'"; +} elsif ($cardnumber) { + $filter->{cardnumber} = $cardnumber; + $search_type = "cardnumber '$cardnumber'"; +} elsif ($patron_id) { + $filter->{borrowernumber} = $patron_id; + $search_type = "patron_id '$patron_id'"; +} + +# Find the patron +my $patrons = Koha::Patrons->search($filter); + +unless ( $patrons->count > 0 ) { + say "Error: No patron found with $search_type"; + exit 1; +} + +my $patron = $patrons->next; + +# Check if patron actually has 2FA enabled +unless ( $patron->has_2fa_enabled ) { + say "Patron " + . $patron->cardnumber . " (" + . $patron->firstname . " " + . $patron->surname + . ") does not have 2FA enabled."; + exit 0; +} + +# Display patron information and current status +say "Resetting 2FA for patron:"; +say " Card number: " . $patron->cardnumber; +say " Name: " . $patron->firstname . " " . $patron->surname; +say " Current auth method: " . ( $patron->auth_method || 'password' ); + +# Reset 2FA settings using the new method +eval { $patron->reset_2fa; }; + +if ($@) { + say "Error: Failed to reset 2FA settings: $@"; + exit 1; +} + +say "Success: 2FA has been reset for patron " . $patron->cardnumber; + +=head1 NAME + +reset_2fa.pl - Reset the 2FA setting for the Koha user + +=head1 SYNOPSIS + +reset_2fa.pl --userid +reset_2fa.pl --patron_id +reset_2fa.pl --cardnumber + + Options: + -?|--help brief help message + --userid the userid to be used to find the patron + --patron_id the borrowernumber for the patron + --cardnumber the cardnumber for the patron + + Note: Only one of --userid, --patron_id, or --cardnumber should be specified. + +=head1 OPTIONS + +=over 8 + +=item B<--help|-?> + +Print a brief help message and exits + +=item B<--userid> + +The patron's userid (for finding the patron). Mutually exclusive with other options. + +=item B<--patron_id> + +The patron's internal id (borrowernumber) for finding the patron. Mutually exclusive with other options. + +=item B<--cardnumber> + +Patron's cardnumber (for finding the patron). Mutually exclusive with other options. + +=back + +=head1 DESCRIPTION + +A simple script to reset an existing user's 2FA authentication settings. + +This script will: +- Find the patron using the specified identifier +- Check if the patron has 2FA enabled +- Reset the patron's 2FA setting + +The script requires exactly one of the patron identification parameters and will +exit with an error if none or multiple parameters are provided. + +=cut -- 2.39.5