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