From 3a055896851623ebdc6cc7226b87f0bb8a6ae7b3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marco=20Trevisan=20=28Trevi=C3=B1o=29?= Date: Thu, 28 Jan 2021 21:15:05 +0100 Subject: [PATCH] utils/delete: Add ability to delete single user fingerprints by finger name Each user can now be followed by an `-f`/`--finger` parameter that when available will be used to delete a single fingerprint for the user. Add tests --- tests/fprintd.py | 44 ++++++++++++++++++++ tests/test_fprintd_utils.py | 2 +- utils/delete.c | 80 ++++++++++++++++++++++++++++++++----- 3 files changed, 116 insertions(+), 10 deletions(-) diff --git a/tests/fprintd.py b/tests/fprintd.py index 9207501..fd8fae9 100644 --- a/tests/fprintd.py +++ b/tests/fprintd.py @@ -2936,6 +2936,50 @@ class FPrintdUtilsTest(FPrintdVirtualStorageDeviceBaseTest): self.assertNotEqual(delete.wait(), 0) self.assertLess(delete.wait(), 128) + def test_delete_single_finger(self): + self.device.Claim('(s)', 'testuser') + enrolled, enroll_map = self.enroll_multiple_images() + self.addCleanup(self.try_release) + self.device.Release() + + finger_name = enrolled[0] + delete, out = self.util_start('delete', ['testuser', + '-f', finger_name]) + + out.check_line('Using device {}'.format( + self.device.get_object_path()), get_timeout()) + + out.check_line('Fingerprint {} of user {} deleted on {}'.format( + finger_name, 'testuser', self.driver_name), get_timeout()) + self.assertEqual(delete.wait(), 0) + + remaining = self.device.ListEnrolledFingers('(s)', 'testuser') + self.assertNotIn(finger_name, remaining) + self.assertCountEqual(enrolled[1:], remaining) + + def test_delete_multiple_users_single_finger(self): + self.addCleanup(self.try_release) + enroll_map, enrolled_prints_info = self.enroll_users_images() + delete_args = [] + for user, print_info in enroll_map.items(): + for f in print_info: + delete_args.append(user) + delete_args.append('-f') + delete_args.append(f) + + delete, out = self.util_start('delete', delete_args) + out.check_line('Using device {}'.format( + self.device.get_object_path()), get_timeout()) + + for user, print_info in enroll_map.items(): + for f in print_info: + out.check_line('Fingerprint {} of user {} deleted on {}'.format( + f, user, self.driver_name), get_timeout()) + + self.assertEqual(delete.wait(), 0) + with self.assertFprintError('NoEnrolledPrints'): + self.device.ListEnrolledFingers('(s)', 'testuser') + def test_enroll(self): self.device.Claim('(s)', self.get_current_user()) self.set_keep_alive(True) diff --git a/tests/test_fprintd_utils.py b/tests/test_fprintd_utils.py index 0b4e96f..f10d4b0 100755 --- a/tests/test_fprintd_utils.py +++ b/tests/test_fprintd_utils.py @@ -160,7 +160,7 @@ class TestFprintdUtils(TestFprintdUtilsBase): def test_fprintd_delete(self): # Delete fingerprints out, ret = self.run_utility_process('delete', ['toto']) - self.assertRegex(out, rb'Fingerprints deleted') + self.assertRegex(out, rb'Fingerprints of user toto deleted') self.assertEqual(ret, 0) # Doesn't have fingerprints diff --git a/utils/delete.c b/utils/delete.c index 427529e..07c0fd8 100644 --- a/utils/delete.c +++ b/utils/delete.c @@ -50,8 +50,23 @@ create_manager (void) } } +static gboolean +delete_user_prints (FprintDBusDevice *dev, + const char *fingername, + GError **error) +{ + if (fingername) + return fprint_dbus_device_call_delete_enrolled_finger_sync (dev, fingername, + NULL, error); + else + return fprint_dbus_device_call_delete_enrolled_fingers2_sync (dev, NULL, + error); +} + static void -delete_fingerprints (FprintDBusDevice *dev, const char *username) +delete_fingerprints (FprintDBusDevice *dev, + const char *username, + const char *fingername) { g_autoptr(GError) error = NULL; @@ -61,8 +76,7 @@ delete_fingerprints (FprintDBusDevice *dev, const char *username) exit (1); } - if (!fprint_dbus_device_call_delete_enrolled_fingers2_sync (dev, NULL, - &error)) + if (!delete_user_prints (dev, fingername, &error)) { gboolean ignore_error = FALSE; if (g_dbus_error_is_remote_error (error)) @@ -91,8 +105,13 @@ delete_fingerprints (FprintDBusDevice *dev, const char *username) } else { - g_print ("Fingerprints deleted on %s\n", - fprint_dbus_device_get_name (dev)); + if (fingername) + g_print ("Fingerprint %s of user %s deleted on %s\n", + fingername, username, + fprint_dbus_device_get_name (dev)); + else + g_print ("Fingerprints of user %s deleted on %s\n", username, + fprint_dbus_device_get_name (dev)); } g_clear_error (&error); @@ -104,10 +123,12 @@ delete_fingerprints (FprintDBusDevice *dev, const char *username) } static void -process_devices (char **argv) +process_devices (guint argc, char **argv) { + g_autoptr(GOptionContext) option_context = NULL; g_autoptr(GError) error = NULL; g_auto(GStrv) devices = NULL; + char *fingername = NULL; char *path; guint num_devices; guint i; @@ -133,6 +154,15 @@ process_devices (char **argv) g_print ("Device at %s\n", path); } + + const GOptionEntry user_options[] = { + { "finger", 'f', 0, G_OPTION_ARG_STRING, &fingername, "Finger selected to verify (default is automatic)", NULL }, + { NULL } + }; + + option_context = g_option_context_new (NULL); + g_option_context_add_main_entries (option_context, user_options, NULL); + for (i = 0; devices[i] != NULL; i++) { g_autoptr(FprintDBusDevice) dev = NULL; @@ -148,7 +178,39 @@ process_devices (char **argv) path, NULL, NULL); for (j = 1; argv[j] != NULL; j++) - delete_fingerprints (dev, argv[j]); + { + const char *username = argv[j]; + fingername = NULL; + + if (argc > j + 1 && argv[j + 1][0] == '-') + { + g_autoptr(GError) local_error = NULL; + g_autoptr(GPtrArray) user_args = NULL; + + user_args = g_ptr_array_new_full (3, NULL); + g_ptr_array_add (user_args, argv[j]); + g_ptr_array_add (user_args, argv[j + 1]); + + if (argc > j + 2) + g_ptr_array_add (user_args, argv[j + 2]); + + int new_argc = user_args->len; + char **new_argv = (char **) user_args->pdata; + + if (!g_option_context_parse (option_context, &new_argc, + &new_argv, &local_error)) + { + g_print ("couldn't parse command-line options: %s\n", + local_error->message); + j += 1; + continue; + } + + j += 2; + } + + delete_fingerprints (dev, username, fingername); + } } } @@ -164,7 +226,7 @@ main (int argc, char **argv) g_option_context_set_ignore_unknown_options (option_context, TRUE); g_option_context_set_summary (option_context, - " [usernames ...]"); + " [-f finger-name [usernames [-f finger-name ]...]"); if (!g_option_context_parse (option_context, &argc, &argv, &local_error)) { @@ -182,7 +244,7 @@ main (int argc, char **argv) } create_manager (); - process_devices (argv); + process_devices (argc, argv); return 0; }