From 476b790b0e6e9852832e148b71855fc2553be0ab Mon Sep 17 00:00:00 2001 From: Jakub Kadlcik Date: Thu, 7 Dec 2023 21:31:09 +0100 Subject: [PATCH] keygen: try to export a key to find whether it exists This seems to be much faster than `--list-secret-keys` on our production instance. --- keygen/src/copr_keygen/logic.py | 6 +++--- keygen/tests/test_logic.py | 7 +++++-- 2 files changed, 8 insertions(+), 5 deletions(-) diff --git a/keygen/src/copr_keygen/logic.py b/keygen/src/copr_keygen/logic.py index 97367c986..babc74fb3 100644 --- a/keygen/src/copr_keygen/logic.py +++ b/keygen/src/copr_keygen/logic.py @@ -73,7 +73,7 @@ def user_exists(app, mail): :raises: GpgErrorException """ - cmd = gpg_cmd + ["--list-secret-keys", "--with-colons", "<{0}>".format(mail)] + cmd = gpg_cmd + ["--armor", "--batch", "--export", "<{0}>".format(mail)] try: handle = Popen(cmd, stdout=PIPE, stderr=PIPE) @@ -83,12 +83,12 @@ def user_exists(app, mail): raise GpgErrorException(msg="unhandled exception during gpg call", cmd=" ".join(cmd), err=e) - if handle.returncode == 0: + if "BEGIN PGP PUBLIC KEY BLOCK" in stdout.decode("utf-8"): # TODO: validate that the key is ultimately trusted log.debug("user {} has keys in keyring".format(mail)) ensure_passphrase_exist(app, mail) return True - elif "error reading key" in stderr.decode(): + elif "nothing exported" in stderr.decode("utf-8"): log.debug("user {} not found in keyring".format(mail)) return False else: diff --git a/keygen/tests/test_logic.py b/keygen/tests/test_logic.py index 0a9be2247..004082b95 100644 --- a/keygen/tests/test_logic.py +++ b/keygen/tests/test_logic.py @@ -103,12 +103,15 @@ def communicate(self): @mock.patch("copr_keygen.logic.Popen") class TestUserExists(TestCase): def test_exists(self, popen, ensure_passphrase): - popen.return_value = MockPopenHandle(0) + stdout = "-----BEGIN PGP PUBLIC KEY BLOCK-----\n\nmQENB..." + popen.return_value = MockPopenHandle(stdout=stdout) ensure_passphrase.return_value = True assert logic.user_exists(app, TEST_EMAIL) def test_not_exists(self, popen, ensure_passphrase): - popen.return_value = MockPopenHandle(1, stderr="error reading key") + # The exit code for the GPG command is zero even on failure + stderr = "gpg: WARNING: nothing exported" + popen.return_value = MockPopenHandle(0, stderr=stderr) ensure_passphrase.return_value = True assert not logic.user_exists(app, TEST_EMAIL)