From 2ad6fddf66447c379b3c95797aa26a3edd3fc425 Mon Sep 17 00:00:00 2001
From: Marcel de Rooy <m.de.rooy@rijksmuseum.nl>
Date: Thu, 14 Apr 2022 12:35:30 +0000
Subject: [PATCH] Bug 28998: (follow-up) Add Patron->encode_secret and
 ->decoded_secret
Content-Type: text/plain; charset=utf-8

Test plan:
Run t/db_dependent/Koha/Patron.t

Signed-off-by: Marcel de Rooy <m.de.rooy@rijksmuseum.nl>
Signed-off-by: Martin Renvoize <martin.renvoize@ptfs-europe.com>
---
 Koha/Patron.pm               | 35 +++++++++++++++++++++++++++++++++++
 t/db_dependent/Koha/Patron.t | 19 +++++++++++++++++++
 2 files changed, 54 insertions(+)

diff --git a/Koha/Patron.pm b/Koha/Patron.pm
index c424c30174..0363fe8db4 100644
--- a/Koha/Patron.pm
+++ b/Koha/Patron.pm
@@ -36,6 +36,7 @@ use Koha::CirculationRules;
 use Koha::Club::Enrollments;
 use Koha::Database;
 use Koha::DateUtils qw( dt_from_string );
+use Koha::Encryption;
 use Koha::Exceptions::Password;
 use Koha::Holds;
 use Koha::Old::Checkouts;
@@ -2131,6 +2132,40 @@ sub can_patron_change_staff_only_lists {
     return 0;
 }
 
+=head3
+
+    $patron->encode_secret($secret32);
+
+    Secret (TwoFactorAuth expects it in base32 format) is encrypted.
+    You still need to call ->store.
+
+=cut
+
+sub encode_secret {
+    my ( $self, $secret ) = @_;
+    if( $secret ) {
+        return $self->secret( Koha::Encryption->new->encrypt_hex($secret) );
+    }
+    return $self->secret($secret);
+}
+
+=head3
+
+    my $secret32 = $patron->decoded_secret;
+
+    Decode the patron secret. We expect to get back a base32 string, but this
+    is not checked here. Caller of encode_secret is responsible for that.
+
+=cut
+
+sub decoded_secret {
+    my ( $self ) = @_;
+    if( $self->secret ) {
+        return Koha::Encryption->new->decrypt_hex( $self->secret );
+    }
+    return $self->secret;
+}
+
 =head2 Internal methods
 
 =head3 _type
diff --git a/t/db_dependent/Koha/Patron.t b/t/db_dependent/Koha/Patron.t
index 6418d6066f..d77a4ae17e 100755
--- a/t/db_dependent/Koha/Patron.t
+++ b/t/db_dependent/Koha/Patron.t
@@ -1137,3 +1137,22 @@ subtest 'recalls() tests' => sub {
 
     $schema->storage->txn_rollback;
 };
+
+subtest 'encode_secret and decoded_secret' => sub {
+    plan tests => 5;
+    $schema->storage->txn_begin;
+
+    t::lib::Mocks::mock_config('encryption_key', 't0P_secret');
+
+    my $patron = $builder->build_object({ class => 'Koha::Patrons' });
+    is( $patron->decoded_secret, undef, 'TestBuilder does not initialize it' );
+    $patron->secret(q{});
+    is( $patron->decoded_secret, q{}, 'Empty string case' );
+
+    $patron->encode_secret('encrypt_me'); # Note: lazy testing; should be base32 string normally.
+    is( length($patron->secret) > 0, 1, 'Secret length' );
+    isnt( $patron->secret, 'encrypt_me', 'Encrypted column' );
+    is( $patron->decoded_secret, 'encrypt_me', 'Decrypted column' );
+
+    $schema->storage->txn_rollback;
+};
-- 
2.20.1