42
42
from canonical.launchpad.interfaces.launchpad import ILaunchpadCelebrities
43
43
from canonical.launchpad.interfaces.lpstorm import IMasterStore
44
from canonical.launchpad.mail import (
45
signed_message_from_string,
47
44
from canonical.librarian.interfaces import DownloadFailed
48
45
from canonical.librarian.utils import copy_and_close
49
46
from lp.app.errors import NotFoundError
52
49
# that it needs a bit of redesigning here around the publication stuff.
53
50
from lp.archivepublisher.config import getPubConfig
54
51
from lp.archivepublisher.customupload import CustomUploadError
55
from lp.archiveuploader.tagfiles import parse_tagfile_lines
52
from lp.archiveuploader.tagfiles import parse_tagfile_content
56
53
from lp.archiveuploader.utils import safe_fix_maintainer
57
54
from lp.registry.interfaces.person import IPersonSet
58
55
from lp.registry.interfaces.pocket import (
59
56
PackagePublishingPocket,
59
from lp.services.mail.signedmessage import strip_pgp_signature
62
60
from lp.services.propertycache import cachedproperty
63
61
from lp.soyuz.adapters.notification import notify
64
62
from lp.soyuz.enums import (
682
680
"""See `IPackageUpload`."""
683
681
return self.archive.is_ppa
685
def _stripPgpSignature(self, changes_lines):
686
"""Strip any PGP signature from the supplied changes lines."""
687
text = "".join(changes_lines)
688
signed_message = signed_message_from_string(text)
689
# For unsigned '.changes' files we'll get a None `signedContent`.
690
if signed_message.signedContent is not None:
691
return signed_message.signedContent.splitlines(True)
695
def _getChangesDict(self, changes_file_object=None, allow_unsigned=None):
683
def _getChangesDict(self, changes_file_object=None):
696
684
"""Return a dictionary with changes file tags in it."""
698
685
if changes_file_object is None:
699
686
changes_file_object = self.changesfile
700
changes_lines = self.changesfile.read().splitlines(True)
702
changes_lines = changes_file_object.readlines()
687
changes_content = changes_file_object.read()
704
689
# Rewind the file so that the next read starts at offset zero. Please
705
690
# note that a LibraryFileAlias does not support seek operations.
706
691
if hasattr(changes_file_object, "seek"):
707
692
changes_file_object.seek(0)
709
# When the 'changesfile' content comes from a different
710
# `PackageUpload` instance (e.g. when dealing with delayed copies)
711
# we need to be able to specify the "allow unsigned" flag explicitly.
712
# In that case the presence of the signing key is immaterial.
713
if allow_unsigned is None:
714
unsigned = not self.signing_key
716
unsigned = allow_unsigned
717
changes = parse_tagfile_lines(changes_lines, allow_unsigned=unsigned)
694
changes = parse_tagfile_content(changes_content)
719
696
# Leaving the PGP signature on a package uploaded
720
697
# leaves the possibility of someone hijacking the notification
721
698
# and uploading to any archive as the signer.
722
changes_lines = self._stripPgpSignature(changes_lines)
724
return changes, changes_lines
699
return changes, strip_pgp_signature(changes_content).splitlines(True)
726
701
def notify(self, announce_list=None, summary_text=None,
727
changes_file_object=None, logger=None, dry_run=False,
728
allow_unsigned=None):
702
changes_file_object=None, logger=None, dry_run=False):
729
703
"""See `IPackageUpload`."""
730
704
notify(self, announce_list, summary_text, changes_file_object,
731
logger, dry_run, allow_unsigned)
733
707
# XXX julian 2007-05-21:
734
708
# This method should really be IPersonSet.getByUploader but requires