From a5d05569dfa0802ebe6e7ee96aee434fe43f3e92 Mon Sep 17 00:00:00 2001 From: Felix Yan Date: Sat, 9 Feb 2019 01:49:15 +0800 Subject: Make Package.signature return str key_id We use the attribute in many places, but it's a "bytes" object in pgpdump that messes up the remaining logic. Let's just wrap it from the very beginning. --- main/models.py | 4 ++-- main/utils.py | 9 +++++++++ 2 files changed, 11 insertions(+), 2 deletions(-) diff --git a/main/models.py b/main/models.py index 18980ae5..2c6651b8 100644 --- a/main/models.py +++ b/main/models.py @@ -7,7 +7,7 @@ from django.contrib.auth.models import User from django.contrib.sites.models import Site from .fields import PositiveBigIntegerField -from .utils import set_created_field, DependStandin +from .utils import set_created_field, DependStandin, SignatureWrapper from devel.models import DeveloperKey from packages.alpm import AlpmAPI @@ -142,7 +142,7 @@ class Package(models.Model): return None data = BinaryData(self.signature_bytes) packets = list(data.packets()) - return packets[0] + return SignatureWrapper(packets[0]) @property def signer(self): diff --git a/main/utils.py b/main/utils.py index f0b10ef5..141f26c2 100644 --- a/main/utils.py +++ b/main/utils.py @@ -6,6 +6,7 @@ except ImportError: import hashlib import markdown from markdown.extensions import Extension +from pgpdump.packet import SignaturePacket from django.core.cache import cache from django.db import connections, router @@ -165,4 +166,12 @@ class DependStandin(object): self.deptype = first.deptype self.pkg = first.pkg.base_package() or PackageStandin(first.pkg) + +class SignatureWrapper(SignaturePacket): + 'Decode key_id from raw SignaturePacket' + def __init__(self, packet): + for field in ("sig_version", "creation_time", "expiration_time"): + setattr(self, field, getattr(packet, field)) + self.key_id = str(packet.key_id) if packet.key_id else None + # vim: set ts=4 sw=4 et: -- cgit v1.2.3-55-g3dc8 From bdcfe1628762fd727afac3f68203e5b970937bde Mon Sep 17 00:00:00 2001 From: Felix Yan Date: Sat, 9 Feb 2019 01:57:18 +0800 Subject: Fix also call_gpg's output --- devel/management/commands/pgp_import.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/devel/management/commands/pgp_import.py b/devel/management/commands/pgp_import.py index 2188de3c..a0b9cbec 100644 --- a/devel/management/commands/pgp_import.py +++ b/devel/management/commands/pgp_import.py @@ -79,7 +79,7 @@ def call_gpg(keyring, *args): if proc.returncode != 0: logger.error(errdata) raise subprocess.CalledProcessError(proc.returncode, gpg_cmd) - return outdata + return outdata.decode("utf-8") class KeyData(object): -- cgit v1.2.3-55-g3dc8 From 24406b2764ecfd9923136feae9031e08b40ef85b Mon Sep 17 00:00:00 2001 From: Felix Yan Date: Sat, 9 Feb 2019 02:02:09 +0800 Subject: Use .decode() instead of str() --- main/utils.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/main/utils.py b/main/utils.py index 141f26c2..2dc066da 100644 --- a/main/utils.py +++ b/main/utils.py @@ -172,6 +172,6 @@ class SignatureWrapper(SignaturePacket): def __init__(self, packet): for field in ("sig_version", "creation_time", "expiration_time"): setattr(self, field, getattr(packet, field)) - self.key_id = str(packet.key_id) if packet.key_id else None + self.key_id = packet.key_id.decode() if packet.key_id else None # vim: set ts=4 sw=4 et: -- cgit v1.2.3-55-g3dc8 From e58c11fd52eb9c3ffca7412b5560982fcec16239 Mon Sep 17 00:00:00 2001 From: Jelle van der Waa Date: Sat, 9 Feb 2019 16:13:14 +0100 Subject: tests: add test for pgp_import keys Add a test to check the pgp_import functionality with one key, by patching call_pgp so there is no need of a local pacman keyring. --- devel/tests/test_pgp_import.py | 36 +++++++++++++++++++++++++++++++++++- 1 file changed, 35 insertions(+), 1 deletion(-) diff --git a/devel/tests/test_pgp_import.py b/devel/tests/test_pgp_import.py index 2b41b980..f01e73a3 100644 --- a/devel/tests/test_pgp_import.py +++ b/devel/tests/test_pgp_import.py @@ -1,12 +1,46 @@ +from unittest.mock import patch + from django.core.management import call_command from django.core.management.base import CommandError from django.test import TransactionTestCase +CREATED = 1541685162 +USER = 'John Doe ' +ID1 = 'D6C055F238843F1C' +ID2 = 'D8AFDDA07A5B6EDFA7D8CCDAD6D055F927843F1C' +ID3 = 'B588C0234ECADD3F0BBBEEBA44F9F02E089294E7' + +SIG_DATA = [ + 'pub:-:4096:1:{id1}:{created}:::-:::scESCA::::::23::0:'.format(id1=ID1, created=CREATED), + 'fpr:::::::::{id2}:'.format(id2=ID2), + 'uid:-::::{created}::{id3}::{user}::::::::::0:'.format(created=CREATED, id3=ID3, user=USER), + 'sig:::1:{id1}:{created}::::{user}:13x::{id2}:::10:'.format(id1=ID1, created=CREATED, user=USER, id2=ID2) +] + + class PGPImportTest(TransactionTestCase): fixtures = ['main/fixtures/arches.json', 'main/fixtures/repos.json'] - def test_pgp_import(self): + def test_pgp_import_error(self): with self.assertRaises(CommandError) as e: call_command('pgp_import') self.assertIn('keyring_path', str(e.exception)) + + @patch('devel.management.commands.pgp_import.call_gpg') + def test_pgp_import_garbage_data(self, mock_call_gpg): + mock_call_gpg.return_value = 'barf' + with patch('devel.management.commands.pgp_import.logger') as logger: + call_command('pgp_import', '/tmp') + logger.info.assert_called() + logger.info.assert_any_call('created %d, updated %d signatures', 0, 0) + logger.info.assert_any_call('created %d, updated %d keys', 0, 0) + + @patch('devel.management.commands.pgp_import.call_gpg') + def test_pgp_import(self, mock_call_gpg): + mock_call_gpg.return_value = '\n'.join(SIG_DATA) + with patch('devel.management.commands.pgp_import.logger') as logger: + call_command('pgp_import', '/tmp') + logger.info.assert_called() + logger.info.assert_any_call('created %d, updated %d signatures', 0, 0) + logger.info.assert_any_call('created %d, updated %d keys', 1, 0) -- cgit v1.2.3-55-g3dc8