Пример #1
0
    def test_sign_file_multi_package(self):
        with amo.tests.copy_file('apps/files/fixtures/files/multi-package.xpi',
                                 self.file_.file_path,
                                 overwrite=True):
            self.file_.update(is_multi_package=True)
            self.assert_not_signed()
            # Make sure the internal XPIs aren't signed either.
            folder = tempfile.mkdtemp()
            try:
                extract_xpi(self.file_.file_path, folder)
                assert not packaged.is_signed(
                    os.path.join(folder, 'random_extension.xpi'))
                assert not packaged.is_signed(
                    os.path.join(folder, 'random_theme.xpi'))
            finally:
                amo.utils.rm_local_tmp_dir(folder)

            packaged.sign_file(self.file_, settings.SIGNING_SERVER)
            assert self.file_.is_signed
            assert self.file_.cert_serial_num
            assert self.file_.hash
            # It's not the multi-package itself that is signed.
            assert not packaged.is_signed(self.file_.file_path)
            # It's the internal xpi.
            folder = tempfile.mkdtemp()
            try:
                extract_xpi(self.file_.file_path, folder)
                assert packaged.is_signed(
                    os.path.join(folder, 'random_extension.xpi'))
                # And only the one that is an extension.
                assert not packaged.is_signed(
                    os.path.join(folder, 'random_theme.xpi'))
            finally:
                amo.utils.rm_local_tmp_dir(folder)
Пример #2
0
    def process_public(self):
        """Set an addons files to public."""
        if self.review_type == 'preliminary':
            raise AssertionError('Preliminary addons cannot be made public.')

        # Sign addon.
        for file_ in self.files:
            sign_file(file_, settings.SIGNING_SERVER)

        # Hold onto the status before we change it.
        status = self.addon.status

        self.set_files(amo.STATUS_PUBLIC, self.files, copy_to_mirror=True)

        self.log_action(amo.LOG.APPROVE_VERSION)
        template = u'%s_to_public' % self.review_type
        subject = u'Mozilla Add-ons: %s %s Fully Reviewed'
        if not self.addon.is_listed:
            template = u'unlisted_to_reviewed'
            subject = u'Mozilla Add-ons: %s %s signed and ready to download'
        self.notify_email(template, subject)

        log.info(u'Making %s files %s public' %
                 (self.addon, ', '.join([f.filename for f in self.files])))
        log.info(u'Sending email for %s' % (self.addon))

        # Assign reviewer incentive scores.
        if self.request:
            ReviewerScore.award_points(self.request.amo_user, self.addon,
                                       status)
Пример #3
0
    def process_preliminary(self, auto_validation=False):
        """Set an addon to preliminary."""
        # Sign addon.
        for file_ in self.files:
            sign_file(file_, settings.PRELIMINARY_SIGNING_SERVER)

        # Hold onto the status before we change it.
        status = self.addon.status

        changes = {"status": amo.STATUS_LITE}
        if self.addon.status in (amo.STATUS_PUBLIC, amo.STATUS_LITE_AND_NOMINATED):
            changes["highest_status"] = amo.STATUS_LITE

        template = u"%s_to_preliminary" % self.review_type
        subject = u"Mozilla Add-ons: %s %s Preliminary Reviewed"
        if self.review_type == "preliminary" and self.addon.status == amo.STATUS_LITE_AND_NOMINATED:
            template = u"nominated_to_nominated"
        if not self.addon.is_listed:
            template = u"unlisted_to_reviewed"
            if auto_validation:
                template = u"unlisted_to_reviewed_auto"
            subject = u"Mozilla Add-ons: %s %s signed and ready to download"

        self.set_addon(**changes)
        self.set_files(amo.STATUS_LITE, self.files, copy_to_mirror=True)

        self.log_action(amo.LOG.PRELIMINARY_VERSION)
        self.notify_email(template, subject)

        log.info(u"Making %s preliminary" % (self.addon))
        log.info(u"Sending email for %s" % (self.addon))

        if self.request and not auto_validation:
            # Assign reviewer incentive scores.
            ReviewerScore.award_points(self.request.user, self.addon, status)
Пример #4
0
    def process_public(self, auto_validation=False):
        """Set an addons files to public."""
        if self.review_type == "preliminary":
            raise AssertionError("Preliminary addons cannot be made public.")

        # Sign addon.
        for file_ in self.files:
            sign_file(file_, settings.SIGNING_SERVER)

        # Hold onto the status before we change it.
        status = self.addon.status

        self.set_files(amo.STATUS_PUBLIC, self.files, copy_to_mirror=True)

        self.log_action(amo.LOG.APPROVE_VERSION)
        template = u"%s_to_public" % self.review_type
        subject = u"Mozilla Add-ons: %s %s Fully Reviewed"
        if not self.addon.is_listed:
            template = u"unlisted_to_reviewed"
            if auto_validation:
                template = u"unlisted_to_reviewed_auto"
            subject = u"Mozilla Add-ons: %s %s signed and ready to download"
        self.notify_email(template, subject)

        log.info(u"Making %s files %s public" % (self.addon, ", ".join([f.filename for f in self.files])))
        log.info(u"Sending email for %s" % (self.addon))

        # Assign reviewer incentive scores.
        if self.request and not auto_validation:
            ReviewerScore.award_points(self.request.user, self.addon, status)
Пример #5
0
    def process_preliminary(self, auto_validation=False):
        """Set an addons files to preliminary."""
        # Sign addon.
        for file_ in self.files:
            sign_file(file_, settings.PRELIMINARY_SIGNING_SERVER)

        # Hold onto the status before we change it.
        status = self.addon.status

        self.set_files(amo.STATUS_LITE, self.files, copy_to_mirror=True)

        self.log_action(amo.LOG.PRELIMINARY_VERSION)
        template = u'%s_to_preliminary' % self.review_type
        subject = u'Mozilla Add-ons: %s %s Preliminary Reviewed'
        if not self.addon.is_listed:
            template = u'unlisted_to_reviewed'
            if auto_validation:
                template = u'unlisted_to_reviewed_auto'
            subject = u'Mozilla Add-ons: %s %s signed and ready to download'
        self.notify_email(template, subject)

        log.info(u'Making %s files %s preliminary' %
                 (self.addon, ', '.join([f.filename for f in self.files])))
        log.info(u'Sending email for %s' % (self.addon))

        if self.request and not auto_validation:
            # Assign reviewer incentive scores.
            ReviewerScore.award_points(self.request.amo_user, self.addon,
                                       status)
Пример #6
0
def sign_addons(addon_ids, force=False, **kw):
    log.info('[{0}] Signing addons.'.format(addon_ids))
    for version in Version.objects.filter(
            addon_id__in=addon_ids, addon__type=amo.ADDON_EXTENSION):
        # We need to bump the version number of the file and the Version, so
        # the Firefox extension update mecanism picks this new signed version
        # and installs it.
        if force:
            to_sign = version.files.all()
        else:
            to_sign = [f for f in version.files.all() if not f.is_signed]
        if not to_sign:
            log.info('Not signing addon {0}, version {1} (no files or already '
                     'signed)'.format(version.addon, version))
            continue
        log.info('Signing addon {0}, version {1}'.format(version.addon,
                                                         version))
        try:
            for file_obj in to_sign:
                bump_version_number(file_obj)
                sign_file(file_obj)
            # Now update the Version model.
            version.update(version='{0}.1'.format(version.version))
        except (SigningError, zipfile.BadZipFile) as e:
            log.warning(
                'Failed signing version {0}: {1}.'.format(version.pk, e))
Пример #7
0
 def test_sign_file_non_ascii_filename(self):
     src = self.file_.file_path
     self.file_.update(filename=u'jétpack.xpi')
     shutil.move(src, self.file_.file_path)
     self.assert_not_signed()
     packaged.sign_file(self.file_, settings.SIGNING_SERVER)
     self.assert_signed()
Пример #8
0
    def process_public(self):
        """Set an addons files to public."""
        if self.review_type == 'preliminary':
            raise AssertionError('Preliminary addons cannot be made public.')

        # Sign addon.
        for file_ in self.files:
            sign_file(file_, settings.SIGNING_SERVER)

        # Hold onto the status before we change it.
        status = self.addon.status

        self.set_files(amo.STATUS_PUBLIC, self.files, copy_to_mirror=True)

        self.log_action(amo.LOG.APPROVE_VERSION)
        template = u'%s_to_public' % self.review_type
        subject = u'Mozilla Add-ons: %s %s Fully Reviewed'
        if not self.addon.is_listed:
            template = u'unlisted_to_reviewed'
            subject = u'Mozilla Add-ons: %s %s signed and ready to download'
        self.notify_email(template, subject)

        log.info(u'Making %s files %s public' %
                 (self.addon, ', '.join([f.filename for f in self.files])))
        log.info(u'Sending email for %s' % (self.addon))

        # Assign reviewer incentive scores.
        if self.request:
            ReviewerScore.award_points(self.request.amo_user, self.addon,
                                       status)
Пример #9
0
    def process_preliminary(self, auto_validation=False):
        """Set an addons files to preliminary."""
        # Sign addon.
        for file_ in self.files:
            sign_file(file_, settings.PRELIMINARY_SIGNING_SERVER)

        # Hold onto the status before we change it.
        status = self.addon.status

        self.set_files(amo.STATUS_LITE, self.files, copy_to_mirror=True)

        self.log_action(amo.LOG.PRELIMINARY_VERSION)
        template = u'%s_to_preliminary' % self.review_type
        subject = u'Mozilla Add-ons: %s %s Preliminary Reviewed'
        if not self.addon.is_listed:
            template = u'unlisted_to_reviewed'
            if auto_validation:
                template = u'unlisted_to_reviewed_auto'
            subject = u'Mozilla Add-ons: %s %s signed and ready to download'
        self.notify_email(template, subject)

        log.info(u'Making %s files %s preliminary' %
                 (self.addon, ', '.join([f.filename for f in self.files])))
        log.info(u'Sending email for %s' % (self.addon))

        if self.request and not auto_validation:
            # Assign reviewer incentive scores.
            ReviewerScore.award_points(self.request.amo_user, self.addon,
                                       status)
Пример #10
0
    def process_public(self, auto_validation=False):
        """Set an addon to public."""
        if self.review_type == 'preliminary':
            raise AssertionError('Preliminary addons cannot be made public.')

        # Sign addon.
        for file_ in self.files:
            sign_file(file_, settings.SIGNING_SERVER)

        # Hold onto the status before we change it.
        status = self.addon.status

        # Save files first, because set_addon checks to make sure there
        # is at least one public file or it won't make the addon public.
        self.set_files(amo.STATUS_PUBLIC, self.files, copy_to_mirror=True)
        self.set_addon(highest_status=amo.STATUS_PUBLIC,
                       status=amo.STATUS_PUBLIC)

        self.log_action(amo.LOG.APPROVE_VERSION)
        template = u'%s_to_public' % self.review_type
        subject = u'Mozilla Add-ons: %s %s Fully Reviewed'
        if not self.addon.is_listed:
            template = u'unlisted_to_reviewed'
            if auto_validation:
                template = u'unlisted_to_reviewed_auto'
            subject = u'Mozilla Add-ons: %s %s signed and ready to download'
        self.notify_email(template, subject)

        log.info(u'Making %s public' % (self.addon))
        log.info(u'Sending email for %s' % (self.addon))

        # Assign reviewer incentive scores.
        if self.request and not auto_validation:
            ReviewerScore.award_points(self.request.user, self.addon, status)
Пример #11
0
 def test_sign_file_non_ascii_filename(self):
     src = self.file_.file_path
     self.file_.update(filename=u'jétpack.xpi')
     shutil.move(src, self.file_.file_path)
     self.assert_not_signed()
     packaged.sign_file(self.file_, settings.SIGNING_SERVER)
     self.assert_signed()
Пример #12
0
    def process_public(self, auto_validation=False):
        """Set an addon to public."""
        if self.review_type == 'preliminary':
            raise AssertionError('Preliminary addons cannot be made public.')

        # Sign addon.
        for file_ in self.files:
            sign_file(file_, settings.SIGNING_SERVER)

        # Hold onto the status before we change it.
        status = self.addon.status

        # Save files first, because set_addon checks to make sure there
        # is at least one public file or it won't make the addon public.
        self.set_files(amo.STATUS_PUBLIC, self.files, copy_to_mirror=True)
        self.set_addon(highest_status=amo.STATUS_PUBLIC,
                       status=amo.STATUS_PUBLIC)

        self.log_action(amo.LOG.APPROVE_VERSION)
        template = u'%s_to_public' % self.review_type
        subject = u'Mozilla Add-ons: %s %s Fully Reviewed'
        if not self.addon.is_listed:
            template = u'unlisted_to_reviewed'
            if auto_validation:
                template = u'unlisted_to_reviewed_auto'
            subject = u'Mozilla Add-ons: %s %s signed and ready to download'
        self.notify_email(template, subject)

        log.info(u'Making %s public' % (self.addon))
        log.info(u'Sending email for %s' % (self.addon))

        # Assign reviewer incentive scores.
        if self.request and not auto_validation:
            ReviewerScore.award_points(self.request.user, self.addon, status)
Пример #13
0
    def test_sign_file_multi_package(self):
        with amo.tests.copy_file('apps/files/fixtures/files/multi-package.xpi',
                                 self.file_.file_path,
                                 overwrite=True):
            self.file_.update(is_multi_package=True)
            self.assert_not_signed()
            # Make sure the internal XPIs aren't signed either.
            folder = tempfile.mkdtemp()
            try:
                extract_xpi(self.file_.file_path, folder)
                assert not packaged.is_signed(
                    os.path.join(folder, 'random_extension.xpi'))
                assert not packaged.is_signed(
                    os.path.join(folder, 'random_theme.xpi'))
            finally:
                amo.utils.rm_local_tmp_dir(folder)

            packaged.sign_file(self.file_, settings.SIGNING_SERVER)
            assert self.file_.is_signed
            assert self.file_.cert_serial_num
            assert self.file_.hash
            # It's not the multi-package itself that is signed.
            assert not packaged.is_signed(self.file_.file_path)
            # It's the internal xpi.
            folder = tempfile.mkdtemp()
            try:
                extract_xpi(self.file_.file_path, folder)
                assert packaged.is_signed(
                    os.path.join(folder, 'random_extension.xpi'))
                # And only the one that is an extension.
                assert not packaged.is_signed(
                    os.path.join(folder, 'random_theme.xpi'))
            finally:
                amo.utils.rm_local_tmp_dir(folder)
Пример #14
0
 def test_sign_file(self):
     self.assert_not_signed()
     packaged.sign_file(self.file_, settings.SIGNING_SERVER)
     self.assert_signed()
     # Make sure there's two newlines at the end of the mozilla.sf file (see
     # bug 1158938).
     with zipfile.ZipFile(self.file_.file_path, mode='r') as zf:
         with zf.open('META-INF/mozilla.sf', 'r') as mozillasf:
             assert mozillasf.read().endswith('\n\n')
Пример #15
0
 def test_sign_file(self):
     self.assert_not_signed()
     packaged.sign_file(self.file_, settings.SIGNING_SERVER)
     self.assert_signed()
     # Make sure there's two newlines at the end of the mozilla.sf file (see
     # bug 1158938).
     with zipfile.ZipFile(self.file_.file_path, mode='r') as zf:
         with zf.open('META-INF/mozilla.sf', 'r') as mozillasf:
             assert mozillasf.read().endswith('\n\n')
Пример #16
0
    def test_supports_firefox_old_default_to_compatible(self):
        max_appversion = self.version.apps.first().max

        # Old, and default to compatible.
        max_appversion.update(version=settings.MIN_D2C_VERSION, version_int=version_int(settings.MIN_D2C_VERSION))
        self.file_.update(binary_components=False, strict_compatibility=False)
        self.assert_not_signed()
        packaged.sign_file(self.file_, settings.SIGNING_SERVER)
        self.assert_signed()
Пример #17
0
 def test_no_sign_missing_file(self):
     os.unlink(self.file_.file_path)
     assert not self.file_.is_signed
     assert not self.file_.cert_serial_num
     assert not self.file_.hash
     packaged.sign_file(self.file_, settings.SIGNING_SERVER)
     assert not self.file_.is_signed
     assert not self.file_.cert_serial_num
     assert not self.file_.hash
     assert not packaged.is_signed(self.file_.file_path)
Пример #18
0
 def test_no_sign_missing_file(self):
     os.unlink(self.file_.file_path)
     assert not self.file_.is_signed
     assert not self.file_.cert_serial_num
     assert not self.file_.hash
     packaged.sign_file(self.file_, settings.SIGNING_SERVER)
     assert not self.file_.is_signed
     assert not self.file_.cert_serial_num
     assert not self.file_.hash
     assert not packaged.is_signed(self.file_.file_path)
Пример #19
0
    def test_supports_firefox_old_not_default_to_compatible(self):
        max_appversion = self.version.apps.first().max

        # Old, and not default to compatible.
        max_appversion.update(version=settings.MIN_D2C_VERSION,
                              version_int=version_int(
                                  settings.MIN_D2C_VERSION))
        self.file_.update(binary_components=True, strict_compatibility=True)
        self.assert_not_signed()
        packaged.sign_file(self.file_, settings.SIGNING_SERVER)
        self.assert_not_signed()
Пример #20
0
    def test_supports_firefox_android_old_not_default_to_compatible(self):
        max_appversion = self.version.apps.first().max

        # Old, and not default to compatible.
        max_appversion.update(application=amo.ANDROID.id,
                              version=settings.MIN_D2C_VERSION,
                              version_int=version_int(
                                  settings.MIN_D2C_VERSION))
        self.file_.update(binary_components=True, strict_compatibility=True)
        self.assert_not_signed()
        packaged.sign_file(self.file_, settings.SIGNING_SERVER)
        self.assert_not_signed()
Пример #21
0
    def test_supports_firefox_android_recent_not_default_to_compatible(self):
        max_appversion = self.version.apps.first().max

        # Recent, not default to compatible.
        max_appversion.update(application=amo.ANDROID.id,
                              version=settings.MIN_NOT_D2C_VERSION,
                              version_int=version_int(
                                  settings.MIN_NOT_D2C_VERSION))
        self.file_.update(binary_components=True, strict_compatibility=True)
        self.assert_not_signed()
        packaged.sign_file(self.file_, settings.SIGNING_SERVER)
        self.assert_signed()
Пример #22
0
    def test_sign_file_multi_package(self):
        with amo.tests.copy_file("apps/files/fixtures/files/multi-package.xpi", self.file_.file_path, overwrite=True):
            self.file_.update(is_multi_package=True)
            self.assert_not_signed()

            packaged.sign_file(self.file_, settings.SIGNING_SERVER)
            self.assert_not_signed()
            # The multi-package itself isn't signed.
            assert not packaged.is_signed(self.file_.file_path)
            # The internal extensions aren't either.
            folder = tempfile.mkdtemp()
            try:
                extract_xpi(self.file_.file_path, folder)
                # The extension isn't.
                assert not packaged.is_signed(os.path.join(folder, "random_extension.xpi"))
                # And the theme isn't either.
                assert not packaged.is_signed(os.path.join(folder, "random_theme.xpi"))
            finally:
                amo.utils.rm_local_tmp_dir(folder)
Пример #23
0
    def test_sign_file_multi_package(self):
        with amo.tests.copy_file('apps/files/fixtures/files/multi-package.xpi',
                                 self.file_.file_path, overwrite=True):
            self.file_.update(is_multi_package=True)
            self.assert_not_signed()

            packaged.sign_file(self.file_, settings.SIGNING_SERVER)
            self.assert_not_signed()
            # The multi-package itself isn't signed.
            assert not packaged.is_signed(self.file_.file_path)
            # The internal extensions aren't either.
            folder = tempfile.mkdtemp()
            try:
                extract_xpi(self.file_.file_path, folder)
                # The extension isn't.
                assert not packaged.is_signed(
                    os.path.join(folder, 'random_extension.xpi'))
                # And the theme isn't either.
                assert not packaged.is_signed(
                    os.path.join(folder, 'random_theme.xpi'))
            finally:
                amo.utils.rm_local_tmp_dir(folder)
Пример #24
0
    def process_preliminary(self, auto_validation=False):
        """Set an addon to preliminary."""
        # Sign addon.
        for file_ in self.files:
            sign_file(file_, settings.PRELIMINARY_SIGNING_SERVER)

        # Hold onto the status before we change it.
        status = self.addon.status

        changes = {'status': amo.STATUS_LITE}
        if (self.addon.status
                in (amo.STATUS_PUBLIC, amo.STATUS_LITE_AND_NOMINATED)):
            changes['highest_status'] = amo.STATUS_LITE

        template = u'%s_to_preliminary' % self.review_type
        subject = u'Mozilla Add-ons: %s %s Preliminary Reviewed'
        if (self.review_type == 'preliminary'
                and self.addon.status == amo.STATUS_LITE_AND_NOMINATED):
            template = u'nominated_to_nominated'
        if not self.addon.is_listed:
            template = u'unlisted_to_reviewed'
            if auto_validation:
                template = u'unlisted_to_reviewed_auto'
            subject = u'Mozilla Add-ons: %s %s signed and ready to download'

        self.set_addon(**changes)
        self.set_files(amo.STATUS_LITE, self.files, copy_to_mirror=True)

        self.log_action(amo.LOG.PRELIMINARY_VERSION)
        self.notify_email(template, subject)

        log.info(u'Making %s preliminary' % (self.addon))
        log.info(u'Sending email for %s' % (self.addon))

        if self.request and not auto_validation:
            # Assign reviewer incentive scores.
            ReviewerScore.award_points(self.request.user, self.addon, status)
Пример #25
0
    def process_preliminary(self):
        """Set an addon to preliminary."""
        # Sign addon.
        for file_ in self.files:
            sign_file(file_, settings.PRELIMINARY_SIGNING_SERVER)

        # Hold onto the status before we change it.
        status = self.addon.status

        changes = {'status': amo.STATUS_LITE}
        if (self.addon.status in (amo.STATUS_PUBLIC,
                                  amo.STATUS_LITE_AND_NOMINATED)):
            changes['highest_status'] = amo.STATUS_LITE

        template = u'%s_to_preliminary' % self.review_type
        subject = u'Mozilla Add-ons: %s %s Preliminary Reviewed'
        if (self.review_type == 'preliminary' and
                self.addon.status == amo.STATUS_LITE_AND_NOMINATED):
            template = u'nominated_to_nominated'
        if not self.addon.is_listed:
            template = u'unlisted_to_reviewed'
            subject = u'Mozilla Add-ons: %s %s signed and ready to download'

        self.set_addon(**changes)
        self.set_files(amo.STATUS_LITE, self.files, copy_to_mirror=True)

        self.log_action(amo.LOG.PRELIMINARY_VERSION)
        self.notify_email(template, subject)

        log.info(u'Making %s preliminary' % (self.addon))
        log.info(u'Sending email for %s' % (self.addon))

        if self.request:
            # Assign reviewer incentive scores.
            ReviewerScore.award_points(self.request.amo_user, self.addon,
                                       status)
Пример #26
0
 def test_no_sign_hotfix_addons(self):
     """Don't sign hotfix addons."""
     for hotfix_guid in settings.HOTFIX_ADDON_GUIDS:
         self.addon.update(guid=hotfix_guid)
         packaged.sign_file(self.file_, settings.SIGNING_SERVER)
         self.assert_not_signed()
Пример #27
0
 def test_non_xpi(self):
     self.file1.update(filename='foo.txt')
     with pytest.raises(packaged.SigningError):
         packaged.sign_file(self.file1)
Пример #28
0
 def test_no_server_prelim(self):
     with self.settings(PRELIMINARY_SIGNING_SERVER=''):
         packaged.sign_file(self.file_, settings.PRELIMINARY_SIGNING_SERVER)
     self.assert_not_signed()
Пример #29
0
 def test_no_server_full(self):
     with self.settings(SIGNING_SERVER=''):
         packaged.sign_file(self.file_, settings.SIGNING_SERVER)
     self.assert_not_signed()
Пример #30
0
def resign_files(file_ids, **kw):
    """Used to force re-signing the files.

    This is used in the 'resign_files' management command. We need to
    re-sign the files that were signed with the wrong certificate (see bug
    1225036).

    It also bumps the version number of the file and the Version, so the
    Firefox extension update mecanism picks this new signed version and
    installs it.
    """
    log.info(u'[{0}] Signing files.'.format(len(file_ids)))

    addons_emailed = set()
    for file_ in File.objects.filter(id__in=file_ids):
        # We only resign files that have been reviewed and signed.
        if file_.status not in amo.REVIEWED_STATUSES:
            log.info(u'Not re-signing file {0}, not reviewed'.format(file_.pk))
            continue
        if not file_.is_signed:
            log.info(u'Not re-signing file {0}, not signed'.format(file_.pk))
            continue

        log.info(u'Re-signing file {0}'.format(file_.pk))

        bumped_version_number = u'{0}.1-signed'.format(file_.version.version)
        bump_version = False  # Did we resign the file?
        if not os.path.isfile(file_.file_path):
            log.info(u'File {0} does not exist, skip'.format(file_.pk))
            continue
        # Save the original file, before bumping the version.
        backup_path = u'{0}.backup_signature'.format(file_.file_path)
        shutil.copy(file_.file_path, backup_path)
        try:
            # Need to bump the version (modify install.rdf or package.json)
            # before the file is signed.
            update_version_number(file_, bumped_version_number)
            if file_.status == amo.STATUS_PUBLIC:
                server = settings.SIGNING_SERVER
            else:
                server = settings.PRELIMINARY_SIGNING_SERVER
            signed = bool(sign_file(file_, server))
            if signed:  # Bump the version number if at least one signed.
                bump_version = True
            else:  # We didn't sign, so revert the version bump.
                shutil.move(backup_path, file_.file_path)
        except:
            log.error(u'Failed signing file {0}'.format(file_.pk),
                      exc_info=True)
            # Revert the version bump, restore the backup.
            shutil.move(backup_path, file_.file_path)

        # Now update the Version model, if we resigned the file.
        if bump_version:
            version = file_.version
            version.update(version=bumped_version_number,
                           version_int=version_int(bumped_version_number))
            addon = version.addon
            if addon.pk not in addons_emailed:
                # Send a mail to the owners/devs warning them we've
                # automatically signed their addon.
                qs = (AddonUser.objects
                      .filter(role=amo.AUTHOR_ROLE_OWNER, addon=addon)
                      .exclude(user__email=None))
                emails = qs.values_list('user__email', flat=True)
                subject = MAIL_RESIGN_SUBJECT.format(addon=addon.name)
                message = MAIL_RESIGN_MESSAGE.format(
                    addon=addon.name,
                    addon_url=amo.helpers.absolutify(
                        addon.get_dev_url(action='versions')))
                amo.utils.send_mail(
                    subject, message, recipient_list=emails,
                    fail_silently=True,
                    headers={'Reply-To': '*****@*****.**'})
                addons_emailed.add(addon.pk)
Пример #31
0
 def test_is_signed(self):
     assert not packaged.is_signed(self.file_.file_path)
     packaged.sign_file(self.file_, settings.SIGNING_SERVER)
     assert packaged.is_signed(self.file_.file_path)
Пример #32
0
 def test_no_sign_hotfix_addons(self):
     """Don't sign hotfix addons."""
     for hotfix_guid in settings.HOTFIX_ADDON_GUIDS:
         self.addon.update(guid=hotfix_guid)
         packaged.sign_file(self.file_, settings.SIGNING_SERVER)
         self.assert_not_signed()
Пример #33
0
            addon = Addon.from_upload(upload, [amo.PLATFORM_ALL.id], data=data)
            AddonUser(addon=addon, user=owner).save()
            version = addon.versions.get()

            addon.status = amo.STATUS_PUBLIC
            if addon.default_locale.lower() == lang.lower():
                addon.target_locale = addon.default_locale

            addon.save()

            log.info('[@None] Created new "{0}" language pack, version {1}'
                     .format(xpi, data['version']))

        file_ = version.files.get()
        if is_beta:
            sign_file(file_, settings.PRELIMINARY_SIGNING_SERVER)
        else:
            # Not `version.files.update`, because we need to trigger save
            # hooks.
            file_.update(status=amo.STATUS_PUBLIC)
            sign_file(file_, settings.SIGNING_SERVER)

        addon.update_version()


@task
def celery_error(**kw):
    """
    This task raises an exception from celery to test error logging and
    Sentry hookup.
    """
Пример #34
0
            AddonUser(addon=addon, user=owner).save()
            version = addon.versions.get()

            addon.status = amo.STATUS_PUBLIC
            if addon.default_locale.lower() == lang.lower():
                addon.target_locale = addon.default_locale

            addon.save()

            log.info(
                '[@None] Created new "{0}" language pack, version {1}'.format(
                    xpi, data['version']))

        file_ = version.files.get()
        if is_beta:
            sign_file(file_, settings.PRELIMINARY_SIGNING_SERVER)
        else:
            # Not `version.files.update`, because we need to trigger save
            # hooks.
            file_.update(status=amo.STATUS_PUBLIC)
            sign_file(file_, settings.SIGNING_SERVER)

        addon.update_version()


@task
def celery_error(**kw):
    """
    This task raises an exception from celery to test error logging and
    Sentry hookup.
    """
Пример #35
0
def fix_let_scope_bustage_in_addons(addon_ids):
    """Used to fix the "let scope bustage" (bug 1224686) in the last version of
    the provided add-ons.

    This is used in the 'fix_let_scope_bustage' management commands.

    It also bumps the version number of the file and the Version, so the
    Firefox extension update mecanism picks this new fixed version and installs
    it.
    """
    log.info(u'[{0}] Fixing addons.'.format(len(addon_ids)))

    addons_emailed = []
    for addon in Addon.objects.filter(id__in=addon_ids):
        # We only care about the latest added version for each add-on.
        version = addon.versions.first()
        log.info(u'Fixing addon {0}, version {1}'.format(addon, version))

        bumped_version_number = u'{0}.1-let-fixed'.format(version.version)
        for file_obj in version.files.all():
            if not os.path.isfile(file_obj.file_path):
                log.info(u'File {0} does not exist, skip'.format(file_obj.pk))
                continue
            # Save the original file, before bumping the version.
            backup_path = u'{0}.backup_let_fix'.format(file_obj.file_path)
            shutil.copy(file_obj.file_path, backup_path)
            try:
                # Apply the fix itself.
                fix_let_scope_bustage_in_xpi(file_obj.file_path)
            except:
                log.error(u'Failed fixing file {0}'.format(file_obj.pk),
                          exc_info=True)
                # Revert the fix by restoring the backup.
                shutil.move(backup_path, file_obj.file_path)
                continue  # We move to the next file.
            # Need to bump the version (modify install.rdf or package.json)
            # before the file is signed.
            update_version_number(file_obj, bumped_version_number)
            if file_obj.is_signed:  # Only sign if it was already signed.
                if file_obj.status == amo.STATUS_PUBLIC:
                    server = settings.SIGNING_SERVER
                else:
                    server = settings.PRELIMINARY_SIGNING_SERVER
                sign_file(file_obj, server)
            # Now update the Version model.
            version.update(version=bumped_version_number,
                           version_int=version_int(bumped_version_number))
            addon = version.addon
            if addon.pk not in addons_emailed:
                # Send a mail to the owners/devs warning them we've
                # automatically fixed their addon.
                qs = (AddonUser.objects
                      .filter(role=amo.AUTHOR_ROLE_OWNER, addon=addon)
                      .exclude(user__email__isnull=True))
                emails = qs.values_list('user__email', flat=True)
                subject = MAIL_SUBJECT.format(addon=addon.name)
                message = MAIL_MESSAGE.format(
                    addon=addon.name,
                    addon_url=amo.helpers.absolutify(
                        addon.get_dev_url(action='versions')))
                amo.utils.send_mail(
                    subject, message, recipient_list=emails,
                    fail_silently=True,
                    headers={'Reply-To': '*****@*****.**'})
                addons_emailed.append(addon.pk)
Пример #36
0
 def test_no_server_prelim(self):
     with self.settings(PRELIMINARY_SIGNING_SERVER=''):
         packaged.sign_file(self.file_, settings.PRELIMINARY_SIGNING_SERVER)
     self.assert_not_signed()
Пример #37
0
 def test_no_server_full(self):
     with self.settings(SIGNING_SERVER=''):
         packaged.sign_file(self.file_, settings.SIGNING_SERVER)
     self.assert_not_signed()
Пример #38
0
 def test_is_signed(self):
     assert not packaged.is_signed(self.file_.file_path)
     packaged.sign_file(self.file_, settings.SIGNING_SERVER)
     assert packaged.is_signed(self.file_.file_path)
Пример #39
0
def sign_addons(addon_ids, force=False, **kw):
    """Used to sign all the versions of an addon.

    This is used in the 'sign_addons' and 'process_addons --task sign_addons'
    management commands.

    It also bumps the version number of the file and the Version, so the
    Firefox extension update mecanism picks this new signed version and
    installs it.
    """
    log.info(u'[{0}] Signing addons.'.format(len(addon_ids)))

    def file_supports_firefox(version):
        """Return a Q object: files supporting at least a firefox version."""
        return Q(version__apps__max__application=amo.FIREFOX.id,
                 version__apps__max__version_int__gte=version_int(version))

    is_default_compatible = Q(binary_components=False,
                              strict_compatibility=False)
    # We only want to sign files that are at least compatible with Firefox
    # MIN_D2C_VERSION, or Firefox MIN_NOT_D2C_VERSION if they are not default
    # to compatible.
    # The signing feature should be supported from Firefox 40 and above, but
    # we're still signing some files that are a bit older just in case.
    ff_version_filter = ((is_default_compatible
                          & file_supports_firefox(settings.MIN_D2C_VERSION)) |
                         (~is_default_compatible & file_supports_firefox(
                             settings.MIN_NOT_D2C_VERSION)))

    addons_emailed = []
    # We only care about extensions.
    for version in Version.objects.filter(addon_id__in=addon_ids,
                                          addon__type=amo.ADDON_EXTENSION):
        # We only sign files that have been reviewed and are compatible with
        # versions of Firefox that are recent enough.
        to_sign = version.files.filter(ff_version_filter,
                                       status__in=amo.REVIEWED_STATUSES)

        if force:
            to_sign = to_sign.all()
        else:
            to_sign = to_sign.filter(is_signed=False)
        if not to_sign:
            log.info(u'Not signing addon {0}, version {1} (no files or already'
                     u' signed)'.format(version.addon, version))
            continue
        log.info(u'Signing addon {0}, version {1}'.format(
            version.addon, version))
        bump_version = False  # Did we sign at least one file?
        for file_obj in to_sign:
            if not os.path.isfile(file_obj.file_path):
                log.info(u'File {0} does not exist, skip'.format(file_obj.pk))
                continue
            # Save the original file, before bumping the version.
            backup_path = u'{0}.backup_signature'.format(file_obj.file_path)
            shutil.copy(file_obj.file_path, backup_path)
            try:
                # Need to bump the version (modify install.rdf or package.json)
                # before the file is signed.
                bump_version_number(file_obj)
                if file_obj.status == amo.STATUS_PUBLIC:
                    server = settings.SIGNING_SERVER
                else:
                    server = settings.PRELIMINARY_SIGNING_SERVER
                signed = bool(sign_file(file_obj, server))
                if signed:  # Bump the version number if at least one signed.
                    bump_version = True
                else:  # We didn't sign, so revert the version bump.
                    shutil.move(backup_path, file_obj.file_path)
            except:
                log.error(u'Failed signing file {0}'.format(file_obj.pk),
                          exc_info=True)
                # Revert the version bump, restore the backup.
                shutil.move(backup_path, file_obj.file_path)
        # Now update the Version model, if we signed at least one file.
        if bump_version:
            bumped_version = _dot_one(version.version)
            version.update(version=bumped_version,
                           version_int=version_int(bumped_version))
            addon = version.addon
            if addon.pk not in addons_emailed:
                # Send a mail to the owners/devs warning them we've
                # automatically signed their addon.
                qs = (AddonUser.objects.filter(
                    role=amo.AUTHOR_ROLE_OWNER,
                    addon=addon).exclude(user__email=None))
                emails = qs.values_list('user__email', flat=True)
                subject = MAIL_SUBJECT.format(addon=addon.name)
                message = MAIL_MESSAGE.format(
                    addon=addon.name,
                    addon_url=amo.helpers.absolutify(
                        addon.get_dev_url(action='versions')))
                amo.utils.send_mail(
                    subject,
                    message,
                    recipient_list=emails,
                    fail_silently=True,
                    headers={'Reply-To': '*****@*****.**'})
                addons_emailed.append(addon.pk)
Пример #40
0
 def test_non_xpi(self):
     self.file1.update(filename='foo.txt')
     with pytest.raises(packaged.SigningError):
         packaged.sign_file(self.file1)
Пример #41
0
def sign_addons(addon_ids, force=False, **kw):
    """Used to sign all the versions of an addon.

    This is used in the 'sign_addons' and 'process_addons --task sign_addons'
    management commands.

    It also bumps the version number of the file and the Version, so the
    Firefox extension update mecanism picks this new signed version and
    installs it.
    """
    log.info(u'[{0}] Signing addons.'.format(len(addon_ids)))

    def file_supports_firefox(version):
        """Return a Q object: files supporting at least a firefox version."""
        return Q(version__apps__max__application__in=SIGN_FOR_APPS,
                 version__apps__max__version_int__gte=version_int(version))

    is_default_compatible = Q(binary_components=False,
                              strict_compatibility=False)
    # We only want to sign files that are at least compatible with Firefox
    # MIN_D2C_VERSION, or Firefox MIN_NOT_D2C_VERSION if they are not default
    # to compatible.
    # The signing feature should be supported from Firefox 40 and above, but
    # we're still signing some files that are a bit older just in case.
    ff_version_filter = (
        (is_default_compatible &
            file_supports_firefox(settings.MIN_D2C_VERSION)) |
        (~is_default_compatible &
            file_supports_firefox(settings.MIN_NOT_D2C_VERSION)))

    addons_emailed = set()
    # We only care about extensions.
    for version in Version.objects.filter(addon_id__in=addon_ids,
                                          addon__type=amo.ADDON_EXTENSION):
        # We only sign files that have been reviewed and are compatible with
        # versions of Firefox that are recent enough.
        to_sign = version.files.filter(ff_version_filter,
                                       status__in=amo.REVIEWED_STATUSES)

        if force:
            to_sign = to_sign.all()
        else:
            to_sign = to_sign.filter(is_signed=False)
        if not to_sign:
            log.info(u'Not signing addon {0}, version {1} (no files or already'
                     u' signed)'.format(version.addon, version))
            continue
        log.info(u'Signing addon {0}, version {1}'.format(version.addon,
                                                          version))
        bumped_version_number = u'{0}.1-signed'.format(version.version)
        signed_at_least_a_file = False  # Did we sign at least one file?
        for file_obj in to_sign:
            if not os.path.isfile(file_obj.file_path):
                log.info(u'File {0} does not exist, skip'.format(file_obj.pk))
                continue
            # Save the original file, before bumping the version.
            backup_path = u'{0}.backup_signature'.format(file_obj.file_path)
            shutil.copy(file_obj.file_path, backup_path)
            try:
                # Need to bump the version (modify install.rdf or package.json)
                # before the file is signed.
                update_version_number(file_obj, bumped_version_number)
                if file_obj.status == amo.STATUS_PUBLIC:
                    server = settings.SIGNING_SERVER
                else:
                    server = settings.PRELIMINARY_SIGNING_SERVER
                signed = bool(sign_file(file_obj, server))
                if signed:  # Bump the version number if at least one signed.
                    signed_at_least_a_file = True
                else:  # We didn't sign, so revert the version bump.
                    shutil.move(backup_path, file_obj.file_path)
            except:
                log.error(u'Failed signing file {0}'.format(file_obj.pk),
                          exc_info=True)
                # Revert the version bump, restore the backup.
                shutil.move(backup_path, file_obj.file_path)
        # Now update the Version model, if we signed at least one file.
        if signed_at_least_a_file:
            version.update(version=bumped_version_number,
                           version_int=version_int(bumped_version_number))
            addon = version.addon
            if addon.pk not in addons_emailed:
                # Send a mail to the owners/devs warning them we've
                # automatically signed their addon.
                qs = (AddonUser.objects
                      .filter(role=amo.AUTHOR_ROLE_OWNER, addon=addon)
                      .exclude(user__email__isnull=True))
                emails = qs.values_list('user__email', flat=True)
                subject = MAIL_SUBJECT.format(addon=addon.name)
                message = MAIL_MESSAGE.format(
                    addon=addon.name,
                    addon_url=amo.helpers.absolutify(
                        addon.get_dev_url(action='versions')))
                amo.utils.send_mail(
                    subject, message, recipient_list=emails,
                    fail_silently=True,
                    headers={'Reply-To': '*****@*****.**'})
                addons_emailed.add(addon.pk)
Пример #42
0
def fix_let_scope_bustage_in_addons(addon_ids):
    """Used to fix the "let scope bustage" (bug 1224686) in the last version of
    the provided add-ons.

    This is used in the 'fix_let_scope_bustage' management commands.

    It also bumps the version number of the file and the Version, so the
    Firefox extension update mecanism picks this new fixed version and installs
    it.
    """
    log.info(u'[{0}] Fixing addons.'.format(len(addon_ids)))

    addons_emailed = []
    for addon in Addon.objects.filter(id__in=addon_ids):
        # We only care about the latest added version for each add-on.
        version = addon.versions.first()
        log.info(u'Fixing addon {0}, version {1}'.format(addon, version))

        bumped_version_number = u'{0}.1-let-fixed'.format(version.version)
        for file_obj in version.files.all():
            if not os.path.isfile(file_obj.file_path):
                log.info(u'File {0} does not exist, skip'.format(file_obj.pk))
                continue
            # Save the original file, before bumping the version.
            backup_path = u'{0}.backup_let_fix'.format(file_obj.file_path)
            shutil.copy(file_obj.file_path, backup_path)
            try:
                # Apply the fix itself.
                fix_let_scope_bustage_in_xpi(file_obj.file_path)
            except:
                log.error(u'Failed fixing file {0}'.format(file_obj.pk),
                          exc_info=True)
                # Revert the fix by restoring the backup.
                shutil.move(backup_path, file_obj.file_path)
                continue  # We move to the next file.
            # Need to bump the version (modify install.rdf or package.json)
            # before the file is signed.
            update_version_number(file_obj, bumped_version_number)
            if file_obj.is_signed:  # Only sign if it was already signed.
                if file_obj.status == amo.STATUS_PUBLIC:
                    server = settings.SIGNING_SERVER
                else:
                    server = settings.PRELIMINARY_SIGNING_SERVER
                sign_file(file_obj, server)
            # Now update the Version model.
            version.update(version=bumped_version_number,
                           version_int=version_int(bumped_version_number))
            addon = version.addon
            if addon.pk not in addons_emailed:
                # Send a mail to the owners/devs warning them we've
                # automatically fixed their addon.
                qs = (AddonUser.objects.filter(
                    role=amo.AUTHOR_ROLE_OWNER,
                    addon=addon).exclude(user__email__isnull=True))
                emails = qs.values_list('user__email', flat=True)
                subject = MAIL_SUBJECT.format(addon=addon.name)
                message = MAIL_MESSAGE.format(
                    addon=addon.name,
                    addon_url=amo.helpers.absolutify(
                        addon.get_dev_url(action='versions')))
                amo.utils.send_mail(
                    subject,
                    message,
                    recipient_list=emails,
                    fail_silently=True,
                    headers={'Reply-To': '*****@*****.**'})
                addons_emailed.append(addon.pk)