Пример #1
0
def test_bump_version_in_package_json(file_obj):
    with amo.tests.copy_file(
            'apps/files/fixtures/files/new-format-0.0.1.xpi',
            file_obj.file_path):
        utils.update_version_number(file_obj, '0.0.1.1-signed')
        parsed = utils.parse_xpi(file_obj.file_path)
        assert parsed['version'] == '0.0.1.1-signed'
Пример #2
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)
Пример #3
0
def test_bump_version_in_alt_install_rdf(file_obj):
    with amo.tests.copy_file('apps/files/fixtures/files/alt-rdf.xpi',
                             file_obj.file_path):
        utils.update_version_number(file_obj, '2.1.106.1-signed')
        parsed = utils.parse_xpi(file_obj.file_path)
        assert parsed['version'] == '2.1.106.1-signed'
Пример #4
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)
Пример #5
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)
Пример #6
0
def test_bump_version_in_package_json(file_obj):
    with amo.tests.copy_file('apps/files/fixtures/files/new-format-0.0.1.xpi',
                             file_obj.file_path):
        utils.update_version_number(file_obj, '0.0.1.1-signed')
        parsed = utils.parse_xpi(file_obj.file_path)
        assert parsed['version'] == '0.0.1.1-signed'
Пример #7
0
def test_bump_version_in_alt_install_rdf(file_obj):
    with amo.tests.copy_file('apps/files/fixtures/files/alt-rdf.xpi',
                             file_obj.file_path):
        utils.update_version_number(file_obj, '2.1.106.1-signed')
        parsed = utils.parse_xpi(file_obj.file_path)
        assert parsed['version'] == '2.1.106.1-signed'
Пример #8
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)