Bump pkcs7_digest algorithm to sha256 (#22408)

* Bump pkcs7_digest to sha256

* Bump minimum version to 58, removing redundant min versions

* TMP: remove print

* Update src/olympia/constants/base.py

Co-authored-by: Mathieu Pillard <diox@users.noreply.github.com>

* Update src/olympia/constants/base.py

Co-authored-by: Mathieu Pillard <diox@users.noreply.github.com>

* TMP: remove unecessary app versions

* TMP: better assertion

* TMP: remove unecessary tests

* TMP: use msg format for string extraction

* TMP: update comment

* TMP: Rvert markdown conversion

* TMP: get or create voer versions

* TMP: use error logger for error logging

* TMP: reformatting

* Update docs/topics/development/testing.rst

Co-authored-by: Mathieu Pillard <diox@users.noreply.github.com>

* Update src/olympia/lib/crypto/signing.py

* Update src/olympia/constants/base.py

* Update src/olympia/files/utils.py

* Update docs/topics/development/testing.rst

Co-authored-by: William Durand <will+git@drnd.me>

* TMP: Log debug

---------

Co-authored-by: Mathieu Pillard <diox@users.noreply.github.com>
Co-authored-by: William Durand <will+git@drnd.me>
This commit is contained in:
Kevin Meinhardt 2024-06-25 16:31:46 +02:00 коммит произвёл GitHub
Родитель feecaba6a3
Коммит 834c3ec451
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: B5690EEEBB952194
21 изменённых файлов: 205 добавлений и 216 удалений

Просмотреть файл

@ -112,6 +112,28 @@ External calls
Connecting to remote services in tests is not recommended, developers should
mock_ out those calls instead.
Fixtures
~~~~~~~~
Some tests rely on zipped `.xpi` files to simulate working with addon artifacts directly.
In order to modify these files you have to unzip/zip the contents (`learn more`_).
To unzip the `.xpi` run:
.. code-block:: bash
unzip <path-to-xpi> -d output
This will inflate the contents to the ./output directory. Make your modifications and then run:
.. code-block:: bash
cd ./output
zip -r -FS ../<path-to-xpi>
To deflate the contents back to the original location. Notice we `cd` into the output directory so
`path-to-xpi` should be relative to the `output` directory.
Why Tests Fail
--------------
Tests usually fail for one of two reasons: The code has changed or the data has
@ -140,3 +162,5 @@ need to recompile the .mo files manually, for example::
.. _`pytest-django`: https://pytest-django.readthedocs.io/en/latest/
.. _mock: http://pypi.python.org/pypi/mock
.. _fixtures: http://pytest.org/en/latest/fixture.html
.. _learn more: https://extensionworkshop.com/documentation/publish/package-your-extension/#package-linux

Просмотреть файл

@ -2607,12 +2607,15 @@ class TestAddonFromUpload(UploadMixin, TestCase):
versions = {
amo.DEFAULT_WEBEXT_MIN_VERSION,
amo.DEFAULT_WEBEXT_MIN_VERSION_ANDROID,
amo.DEFAULT_WEBEXT_MIN_VERSION_NO_ID,
amo.DEFAULT_WEBEXT_MAX_VERSION,
}
for version in versions:
AppVersion.objects.create(application=amo.FIREFOX.id, version=version)
AppVersion.objects.create(application=amo.ANDROID.id, version=version)
AppVersion.objects.get_or_create(
application=amo.FIREFOX.id, version=version
)
AppVersion.objects.get_or_create(
application=amo.ANDROID.id, version=version
)
def setUp(self):
super().setUp()
@ -2626,7 +2629,7 @@ class TestAddonFromUpload(UploadMixin, TestCase):
application=application.id,
min=AppVersion.objects.get(
application=application.id,
version=amo.DEFAULT_WEBEXT_MIN_VERSION_NO_ID,
version=amo.DEFAULT_WEBEXT_MIN_VERSION,
),
max=AppVersion.objects.get(application=application.id, version='*'),
)

Просмотреть файл

@ -885,7 +885,6 @@ class TestAddonViewSetCreate(UploadMixin, AddonViewSetCreateUpdateMixin, TestCas
def setUpTestData(cls):
versions = {
amo.DEFAULT_WEBEXT_MIN_VERSION,
amo.DEFAULT_WEBEXT_MIN_VERSION_NO_ID,
amo.DEFAULT_WEBEXT_MIN_VERSION_ANDROID,
amo.DEFAULT_STATIC_THEME_MIN_VERSION_FIREFOX,
amo.DEFAULT_WEBEXT_DICT_MIN_VERSION_FIREFOX,
@ -1759,7 +1758,12 @@ class TestAddonViewSetCreate(UploadMixin, AddonViewSetCreateUpdateMixin, TestCas
request_data = {
'version': {
'upload': self.upload.uuid,
'compatibility': {'android': {'min': '48.0', 'max': '*'}},
'compatibility': {
'android': {
'min': amo.DEFAULT_WEBEXT_MIN_VERSION_ANDROID,
'max': '*',
}
},
}
}
response = self.request(data=request_data)
@ -2636,7 +2640,7 @@ class TestAddonViewSetUpdatePut(UploadMixin, TestAddonViewSetUpdate):
version_data = super().test_basic()['latest_unlisted_version']
assert version_data['license'] is None
assert version_data['compatibility'] == {
'firefox': {'max': '*', 'min': '42.0'},
'firefox': {'max': '*', 'min': amo.DEFAULT_WEBEXT_MIN_VERSION},
}
assert self.addon.versions.count() == 2
version = self.addon.find_latest_version(channel=None)
@ -2655,7 +2659,7 @@ class TestAddonViewSetUpdatePut(UploadMixin, TestAddonViewSetUpdate):
license
)
assert version_data['compatibility'] == {
'firefox': {'max': '*', 'min': '42.0'},
'firefox': {'max': '*', 'min': amo.DEFAULT_WEBEXT_MIN_VERSION},
}
assert self.addon.versions.count() == 2
version = self.addon.find_latest_version(channel=None)
@ -3284,7 +3288,7 @@ class VersionViewSetCreateUpdateMixin(RequestMixin):
version = self.addon.find_latest_version(channel=None)
assert data['compatibility'] == {
'android': {'max': '*', 'min': amo.MIN_VERSION_FENIX_GENERAL_AVAILABILITY},
'firefox': {'max': '*', 'min': '42.0'},
'firefox': {'max': '*', 'min': amo.DEFAULT_WEBEXT_MIN_VERSION},
}
assert list(version.compatible_apps.keys()) == [amo.FIREFOX, amo.ANDROID]
for avs in version.compatible_apps.values():
@ -3355,7 +3359,11 @@ class VersionViewSetCreateUpdateMixin(RequestMixin):
assert response.data == {'compatibility': ['Unknown min app version specified']}
def test_compatibility_forbidden_range_android(self):
response = self.request(compatibility={'android': {'min': '48.0', 'max': '*'}})
response = self.request(
compatibility={
'android': {'min': amo.DEFAULT_WEBEXT_MIN_VERSION_ANDROID, 'max': '*'}
}
)
assert response.status_code == 400, response.content
assert response.data == {
'compatibility': [
@ -3367,11 +3375,17 @@ class VersionViewSetCreateUpdateMixin(RequestMixin):
# Recommended add-ons for Android don't have that restriction.
self.make_addon_promoted(self.addon, RECOMMENDED, approve_version=True)
response = self.request(compatibility={'android': {'min': '48.0', 'max': '*'}})
response = self.request(
compatibility={
'android': {'min': amo.DEFAULT_WEBEXT_MIN_VERSION_ANDROID, 'max': '*'}
}
)
assert response.status_code == self.SUCCESS_STATUS_CODE, response.content
def test_compatibility_forbidden_range_android_only_min_specified(self):
response = self.request(compatibility={'android': {'min': '48.0'}})
response = self.request(
compatibility={'android': {'min': amo.DEFAULT_WEBEXT_MIN_VERSION_ANDROID}}
)
assert response.status_code == 400, response.content
assert response.data == {
'compatibility': [
@ -3383,7 +3397,9 @@ class VersionViewSetCreateUpdateMixin(RequestMixin):
# Recommended add-ons for Android don't have that restriction.
self.make_addon_promoted(self.addon, RECOMMENDED, approve_version=True)
response = self.request(compatibility={'android': {'min': '48.0'}})
response = self.request(
compatibility={'android': {'min': amo.DEFAULT_WEBEXT_MIN_VERSION_ANDROID}}
)
assert response.status_code == self.SUCCESS_STATUS_CODE, response.content
@staticmethod
@ -3461,7 +3477,6 @@ class TestVersionViewSetCreate(UploadMixin, VersionViewSetCreateUpdateMixin, Tes
def setUpTestData(cls):
versions = {
amo.DEFAULT_WEBEXT_MIN_VERSION,
amo.DEFAULT_WEBEXT_MIN_VERSION_NO_ID,
amo.DEFAULT_WEBEXT_MIN_VERSION_ANDROID,
amo.DEFAULT_STATIC_THEME_MIN_VERSION_FIREFOX,
amo.DEFAULT_WEBEXT_DICT_MIN_VERSION_FIREFOX,
@ -3513,7 +3528,7 @@ class TestVersionViewSetCreate(UploadMixin, VersionViewSetCreateUpdateMixin, Tes
data = response.data
assert data['license'] is None
assert data['compatibility'] == {
'firefox': {'max': '*', 'min': '42.0'},
'firefox': {'max': '*', 'min': amo.DEFAULT_WEBEXT_MIN_VERSION},
}
self.addon.reload()
assert self.addon.versions.count() == 2
@ -3923,7 +3938,6 @@ class TestVersionViewSetUpdate(UploadMixin, VersionViewSetCreateUpdateMixin, Tes
def setUpTestData(cls):
versions = {
amo.DEFAULT_WEBEXT_MIN_VERSION,
amo.DEFAULT_WEBEXT_MIN_VERSION_NO_ID,
amo.DEFAULT_WEBEXT_MIN_VERSION_ANDROID,
amo.DEFAULT_STATIC_THEME_MIN_VERSION_FIREFOX,
amo.DEFAULT_WEBEXT_DICT_MIN_VERSION_FIREFOX,
@ -4667,7 +4681,9 @@ class TestVersionViewSetList(AddonAndVersionViewSetDetailMixin, TestCase):
# shown when requesting to see unlisted stuff explicitly, with the
# right permissions.
self.unlisted_version = version_factory(
addon=self.addon, version='42.0', channel=amo.CHANNEL_UNLISTED
addon=self.addon,
version=amo.DEFAULT_WEBEXT_MIN_VERSION,
channel=amo.CHANNEL_UNLISTED,
)
self._set_tested_url(self.addon.pk)

Просмотреть файл

@ -919,7 +919,6 @@ def version_review_flags_factory(**kw):
def create_default_webext_appversion():
versions = {
amo.DEFAULT_WEBEXT_MIN_VERSION,
amo.DEFAULT_WEBEXT_MIN_VERSION_NO_ID,
amo.DEFAULT_STATIC_THEME_MIN_VERSION_FIREFOX,
amo.DEFAULT_WEBEXT_MAX_VERSION,
amo.DEFAULT_WEBEXT_MIN_VERSION_MV3_FIREFOX,

Просмотреть файл

@ -329,20 +329,19 @@ ADDON_ID = r"""(?P<addon_id>[^/<>"']+)"""
ADDON_UUID = r'(?P<uuid>[\w]{8}-[\w]{4}-[\w]{4}-[\w]{4}-[\w]{12})'
# Default strict_min_version and strict_max_version for WebExtensions
DEFAULT_WEBEXT_MIN_VERSION = '42.0'
# We're signing with SHA256 nowadays, which is only supported in 58.0 or higher
DEFAULT_WEBEXT_MIN_VERSION = '58.0'
DEFAULT_WEBEXT_MAX_VERSION = '*'
# Android only started to support WebExtensions with version 48
DEFAULT_WEBEXT_MIN_VERSION_ANDROID = '48.0'
# Android only started to support WebExtensions with version 48,
# but because we're now signing with SHA256 (see above), the minimum
# version has to be 58.0.
DEFAULT_WEBEXT_MIN_VERSION_ANDROID = '58.0'
# The default version of Firefox that supports WebExtensions without an id
DEFAULT_WEBEXT_MIN_VERSION_NO_ID = '48.0'
# The default version of Firefox that supported `browser_specific_settings`
DEFAULT_WEBEXT_MIN_VERSION_BROWSER_SPECIFIC = '48.0'
# The version of desktop Firefox that first supported static themes.
DEFAULT_STATIC_THEME_MIN_VERSION_FIREFOX = '53.0'
# The version of desktop Firefox that first supported static themes is 53.0,
# but as above because we're now signing with SHA256, the minimum version has
# to be 58.0.
DEFAULT_STATIC_THEME_MIN_VERSION_FIREFOX = '58.0'
# The version of Firefox that first supported webext dictionaries.
# Dicts are not compatible with Firefox for Android, only desktop is relevant.

Просмотреть файл

@ -88,22 +88,11 @@ def test_recreate_previews(pngcrush_image_mock):
class ValidatorTestCase(TestCase):
def setUp(self):
self.create_appversion('firefox', '38.0a1')
# Required for WebExtensions tests.
self.create_appversion('firefox', '*')
self.create_appversion('firefox', '42.0')
self.create_appversion('firefox', '42.*')
self.create_appversion('firefox', '43.0')
# Required for 57-specific tests.
self.create_appversion('android', '38.0a1')
self.create_appversion('android', '*')
self.create_appversion('firefox', '57.0')
# Required for Android tests.
self.create_appversion('android', '42.0')
self.create_appversion('android', '45.0')
self.create_appversion('firefox', amo.DEFAULT_WEBEXT_MIN_VERSION)
self.create_appversion('android', amo.DEFAULT_WEBEXT_MIN_VERSION)
def create_appversion(self, name, version):
return AppVersion.objects.create(application=amo.APPS[name].id, version=version)

Просмотреть файл

@ -266,8 +266,8 @@ def test_extract_theme_properties(zip_file):
amo.DEFAULT_STATIC_THEME_MIN_VERSION_FIREFOX,
}
for version in versions:
AppVersion.objects.create(application=amo.FIREFOX.id, version=version)
AppVersion.objects.create(application=amo.ANDROID.id, version=version)
AppVersion.objects.get_or_create(application=amo.FIREFOX.id, version=version)
AppVersion.objects.get_or_create(application=amo.ANDROID.id, version=version)
addon = addon_factory(
type=amo.ADDON_STATICTHEME,

Просмотреть файл

@ -1370,7 +1370,7 @@ class TestUploadDetail(UploadMixin, TestCase):
@classmethod
def create_appversion(cls, application_name, version):
return AppVersion.objects.create(
return AppVersion.objects.get_or_create(
application=amo.APPS[application_name].id, version=version
)

Просмотреть файл

@ -1124,7 +1124,7 @@ class TestVersionEditCompat(TestVersionEditBase):
data.update(
min=AppVersion.objects.get(
application=amo.FIREFOX.id,
version=amo.DEFAULT_WEBEXT_MIN_VERSION_NO_ID,
version=amo.DEFAULT_WEBEXT_MIN_VERSION,
).pk,
max=AppVersion.objects.get(
application=amo.FIREFOX.id, version=amo.DEFAULT_WEBEXT_MAX_VERSION
@ -1133,7 +1133,7 @@ class TestVersionEditCompat(TestVersionEditBase):
response = self.client.post(self.url, self.formset(data, initial_count=1))
assert response.status_code == 302
av = self.version.apps.get()
assert av.min.version == amo.DEFAULT_WEBEXT_MIN_VERSION_NO_ID
assert av.min.version == amo.DEFAULT_WEBEXT_MIN_VERSION
assert av.max.version == amo.DEFAULT_WEBEXT_MAX_VERSION
assert list(
ActivityLog.objects.exclude(action=amo.LOG.LOG_IN.id).values_list('action')
@ -1235,7 +1235,7 @@ class TestVersionEditCompat(TestVersionEditBase):
# Change Firefox compat
data[0]['min'] = AppVersion.objects.get(
application=amo.FIREFOX.id,
version=amo.DEFAULT_WEBEXT_MIN_VERSION_NO_ID,
version=amo.DEFAULT_WEBEXT_MIN_VERSION,
).pk
data[0]['max'] = AppVersion.objects.get(
application=amo.FIREFOX.id,
@ -1246,7 +1246,7 @@ class TestVersionEditCompat(TestVersionEditBase):
assert self.addon.current_version.apps.all().count() == 2
avs.refresh_from_db()
assert avs.application == amo.FIREFOX.id
assert avs.min.version == amo.DEFAULT_WEBEXT_MIN_VERSION_NO_ID
assert avs.min.version == amo.DEFAULT_WEBEXT_MIN_VERSION
assert avs.max.version == amo.DEFAULT_WEBEXT_MAX_VERSION
assert avs.originated_from == amo.APPVERSIONS_ORIGINATED_FROM_DEVELOPER

Просмотреть файл

@ -298,7 +298,8 @@ def extract_theme_properties(addon, channel):
parsed_data = parse_xpi(
version.file.file.path, addon=addon, user=core.get_user()
)
except (ValidationError, ValueError):
except (ValidationError, ValueError) as exc:
log.debug('Error parsing xpi', exc_info=exc)
# If we can't parse the existing manifest safely return.
return {}
theme_props = parsed_data.get('theme', {})

Двоичный файл не отображается.

Просмотреть файл

@ -19,13 +19,17 @@ class TestExtractHostPermissions(UploadMixin, TestCase):
@classmethod
def setUpTestData(cls):
versions = {
amo.DEFAULT_WEBEXT_MIN_VERSION_NO_ID,
amo.DEFAULT_WEBEXT_MIN_VERSION,
amo.DEFAULT_WEBEXT_MIN_VERSION_ANDROID,
amo.DEFAULT_WEBEXT_MAX_VERSION,
}
for version in versions:
AppVersion.objects.create(application=amo.FIREFOX.id, version=version)
AppVersion.objects.create(application=amo.ANDROID.id, version=version)
AppVersion.objects.get_or_create(
application=amo.FIREFOX.id, version=version
)
AppVersion.objects.get_or_create(
application=amo.ANDROID.id, version=version
)
def setUp(self):
super(TestExtractHostPermissions, self).setUp()

Просмотреть файл

@ -428,7 +428,6 @@ class TestParseXpi(amo.tests.AMOPaths, TestCase):
def setUpTestData(cls):
versions = {
amo.DEFAULT_WEBEXT_MIN_VERSION,
amo.DEFAULT_WEBEXT_MIN_VERSION_NO_ID,
amo.DEFAULT_WEBEXT_MIN_VERSION_ANDROID,
amo.DEFAULT_STATIC_THEME_MIN_VERSION_FIREFOX,
amo.DEFAULT_WEBEXT_DICT_MIN_VERSION_FIREFOX,
@ -436,8 +435,12 @@ class TestParseXpi(amo.tests.AMOPaths, TestCase):
amo.DEFAULT_WEBEXT_MIN_VERSION_MV3_FIREFOX,
}
for version in versions:
AppVersion.objects.create(application=amo.FIREFOX.id, version=version)
AppVersion.objects.create(application=amo.ANDROID.id, version=version)
AppVersion.objects.get_or_create(
application=amo.FIREFOX.id, version=version
)
AppVersion.objects.get_or_create(
application=amo.ANDROID.id, version=version
)
def setUp(self):
self.user = user_factory()
@ -537,12 +540,17 @@ class TestParseXpi(amo.tests.AMOPaths, TestCase):
expected = [
ApplicationsVersions(
application=amo.FIREFOX.id,
min=AppVersion.objects.get(application=amo.FIREFOX.id, version='42.0'),
min=AppVersion.objects.get(
application=amo.FIREFOX.id, version=amo.DEFAULT_WEBEXT_MIN_VERSION
),
max=AppVersion.objects.get(application=amo.FIREFOX.id, version='*'),
),
ApplicationsVersions(
application=amo.ANDROID.id,
min=AppVersion.objects.get(application=amo.ANDROID.id, version='48.0'),
min=AppVersion.objects.get(
application=amo.ANDROID.id,
version=amo.DEFAULT_WEBEXT_MIN_VERSION_ANDROID,
),
max=AppVersion.objects.get(application=amo.ANDROID.id, version='*'),
),
]
@ -554,8 +562,8 @@ class TestParseXpi(amo.tests.AMOPaths, TestCase):
assert avs.max == expected[idx].max
def test_no_parse_apps_error_webextension(self):
AppVersion.objects.create(application=amo.FIREFOX.id, version='57.0')
AppVersion.objects.create(application=amo.ANDROID.id, version='57.0')
AppVersion.objects.create(application=amo.FIREFOX.id, version='59.0')
AppVersion.objects.create(application=amo.ANDROID.id, version='59.0')
assert self.parse(filename='webextension_with_apps_targets.xpi')
assert self.parse(filename='webextension_with_apps_targets.xpi', minimal=False)
@ -1182,7 +1190,6 @@ class TestFileFromUpload(UploadMixin, TestCase):
versions = {
amo.DEFAULT_WEBEXT_MIN_VERSION,
amo.DEFAULT_WEBEXT_MAX_VERSION,
amo.DEFAULT_WEBEXT_MIN_VERSION_NO_ID,
amo.DEFAULT_WEBEXT_MIN_VERSION_ANDROID,
}
for version in versions:

Просмотреть файл

@ -49,7 +49,6 @@ class AppVersionsMixin:
cls.create_appversion('firefox', '36.0') # Incompatible with webexts.
cls.create_appversion('firefox', amo.DEFAULT_WEBEXT_MIN_VERSION)
cls.create_appversion('firefox', amo.DEFAULT_WEBEXT_MAX_VERSION)
cls.create_appversion('firefox', amo.DEFAULT_WEBEXT_MIN_VERSION_NO_ID)
cls.create_appversion('android', amo.DEFAULT_WEBEXT_MIN_VERSION_ANDROID)
cls.create_appversion('android', amo.DEFAULT_WEBEXT_MAX_VERSION)
cls.create_appversion('firefox', amo.DEFAULT_STATIC_THEME_MIN_VERSION_FIREFOX)
@ -195,7 +194,11 @@ class TestManifestJSONExtractor(AppVersionsMixin, TestCase):
}
with pytest.raises(forms.ValidationError) as exc:
self.parse(data)
assert exc.value.message == 'Lowest supported "strict_min_version" is 42.0.'
min_version = amo.DEFAULT_WEBEXT_MIN_VERSION
assert (
exc.value.message
== f'Lowest supported "strict_min_version" is {min_version}.'
)
def test_unknown_strict_min_version(self):
data = {
@ -223,8 +226,11 @@ class TestManifestJSONExtractor(AppVersionsMixin, TestCase):
self.parse(data)
assert exc.value.message == ('Unknown "strict_max_version" 76.0 for Firefox')
def test_strict_min_version_needs_to_be_higher_than_42_if_specified(self):
"""strict_min_version needs to be higher than 42.0 if specified."""
def test_strict_min_version_needs_to_be_higher_than_min_version_if_specified(self):
"""
strict_min_version needs to be higher than amo.DEFAULT_WEBEXT_MIN_VERSION
if specified.
"""
data = {
'applications': {
'gecko': {
@ -233,20 +239,26 @@ class TestManifestJSONExtractor(AppVersionsMixin, TestCase):
}
}
}
min_version = amo.DEFAULT_WEBEXT_MIN_VERSION
with pytest.raises(forms.ValidationError) as exc:
self.parse(data)
assert exc.value.message == 'Lowest supported "strict_min_version" is 42.0.'
assert (
exc.value.message
== f'Lowest supported "strict_min_version" is {min_version}.'
)
def test_apps_use_provided_versions(self):
"""Use the min and max versions if provided."""
firefox_min_version = self.create_appversion('firefox', '47.0')
firefox_max_version = self.create_appversion('firefox', '47.*')
firefox_min_version = self.create_appversion('firefox', '60.0')
firefox_max_version = self.create_appversion('firefox', '60.*')
android_min_version = self.create_appversion('android', '60.0')
android_max_version = self.create_appversion('android', '60.*')
data = {
'applications': {
'gecko': {
'strict_min_version': '>=47.0',
'strict_max_version': '=47.*',
'strict_min_version': '>=60.0',
'strict_max_version': '=60.*',
'id': '@random',
}
}
@ -259,14 +271,10 @@ class TestManifestJSONExtractor(AppVersionsMixin, TestCase):
assert app.min == firefox_min_version
assert app.max == firefox_max_version
# We have no way of specifying a different version for Android when an
# explicit version number is provided... That being said, we know that
# 47.0 is too low for Android, so we silently cap it at 48.0. That
# forces us to also change the max version for android.
app = apps[1]
assert app.application == amo.ANDROID.id
assert app.min.version == amo.DEFAULT_WEBEXT_MIN_VERSION_ANDROID
assert app.max.version == amo.DEFAULT_WEBEXT_MIN_VERSION_ANDROID
assert app.min == android_min_version
assert app.max == android_max_version
# Compatible, but not because of something in the manifest.
# (gecko_android key is absent).
@ -320,13 +328,13 @@ class TestManifestJSONExtractor(AppVersionsMixin, TestCase):
assert len(apps) == 2
app = apps[0]
assert app.application == amo.FIREFOX.id
assert app.min.version == (amo.DEFAULT_WEBEXT_MIN_VERSION_BROWSER_SPECIFIC)
assert app.min.version == (amo.DEFAULT_WEBEXT_MIN_VERSION)
assert app.max.version == amo.DEFAULT_WEBEXT_MAX_VERSION
assert app.originated_from == amo.APPVERSIONS_ORIGINATED_FROM_AUTOMATIC
app = apps[1]
assert app.application == amo.ANDROID.id
assert app.min.version == (amo.DEFAULT_WEBEXT_MIN_VERSION_BROWSER_SPECIFIC)
assert app.min.version == (amo.DEFAULT_WEBEXT_MIN_VERSION_ANDROID)
assert app.max.version == amo.DEFAULT_WEBEXT_MAX_VERSION
assert app.originated_from == amo.APPVERSIONS_ORIGINATED_FROM_AUTOMATIC
@ -357,7 +365,7 @@ class TestManifestJSONExtractor(AppVersionsMixin, TestCase):
assert len(apps) == 2
app = apps[0]
assert app.application == amo.FIREFOX.id
assert app.min.version == amo.DEFAULT_WEBEXT_MIN_VERSION_NO_ID
assert app.min.version == amo.DEFAULT_WEBEXT_MIN_VERSION
assert app.max.version == amo.DEFAULT_WEBEXT_MAX_VERSION
assert app.originated_from == amo.APPVERSIONS_ORIGINATED_FROM_AUTOMATIC
@ -387,7 +395,7 @@ class TestManifestJSONExtractor(AppVersionsMixin, TestCase):
assert len(apps) == 2
app = apps[0]
assert app.application == amo.FIREFOX.id
assert app.min.version == amo.DEFAULT_WEBEXT_MIN_VERSION_NO_ID
assert app.min.version == amo.DEFAULT_WEBEXT_MIN_VERSION
assert app.max.version == amo.DEFAULT_WEBEXT_MAX_VERSION
assert app.originated_from == amo.APPVERSIONS_ORIGINATED_FROM_AUTOMATIC
@ -418,7 +426,7 @@ class TestManifestJSONExtractor(AppVersionsMixin, TestCase):
assert len(apps) == 2
app = apps[0]
assert app.application == amo.FIREFOX.id
assert app.min.version == amo.DEFAULT_WEBEXT_MIN_VERSION_NO_ID
assert app.min.version == amo.DEFAULT_WEBEXT_MIN_VERSION
assert app.max.version == amo.DEFAULT_WEBEXT_MAX_VERSION
assert app.originated_from == amo.APPVERSIONS_ORIGINATED_FROM_AUTOMATIC
@ -438,7 +446,7 @@ class TestManifestJSONExtractor(AppVersionsMixin, TestCase):
data = {
'browser_specific_settings': {
'gecko': {
'strict_min_version': '53.0',
'strict_min_version': amo.DEFAULT_WEBEXT_MIN_VERSION,
},
'gecko_android': {
'strict_min_version': self.HIGHER_THAN_EVERYTHING_ELSE,
@ -451,7 +459,7 @@ class TestManifestJSONExtractor(AppVersionsMixin, TestCase):
assert len(apps) == 2
app = apps[0]
assert app.application == amo.FIREFOX.id
assert app.min.version == '53.0'
assert app.min.version == amo.DEFAULT_WEBEXT_MIN_VERSION
assert app.max.version == amo.DEFAULT_WEBEXT_MAX_VERSION
assert app.originated_from == amo.APPVERSIONS_ORIGINATED_FROM_MANIFEST
@ -483,7 +491,7 @@ class TestManifestJSONExtractor(AppVersionsMixin, TestCase):
assert len(apps) == 2
app = apps[0]
assert app.application == amo.FIREFOX.id
assert app.min.version == amo.DEFAULT_WEBEXT_MIN_VERSION_NO_ID
assert app.min.version == amo.DEFAULT_WEBEXT_MIN_VERSION
assert app.max.version == self.HIGHER_THAN_EVERYTHING_ELSE_STAR
assert app.originated_from == amo.APPVERSIONS_ORIGINATED_FROM_MANIFEST
@ -512,7 +520,7 @@ class TestManifestJSONExtractor(AppVersionsMixin, TestCase):
assert len(apps) == 2
app = apps[0]
assert app.application == amo.FIREFOX.id
assert app.min.version == amo.DEFAULT_WEBEXT_MIN_VERSION_NO_ID
assert app.min.version == amo.DEFAULT_WEBEXT_MIN_VERSION
assert app.max.version == amo.DEFAULT_WEBEXT_MAX_VERSION
assert app.originated_from == amo.APPVERSIONS_ORIGINATED_FROM_AUTOMATIC
@ -616,7 +624,7 @@ class TestManifestJSONExtractor(AppVersionsMixin, TestCase):
apps = self.parse(data)['apps']
assert len(apps) == 2
assert apps[0].application == amo.FIREFOX.id
assert apps[0].min.version == amo.DEFAULT_WEBEXT_MIN_VERSION_NO_ID
assert apps[0].min.version == amo.DEFAULT_WEBEXT_MIN_VERSION
assert apps[0].max.version == amo.DEFAULT_WEBEXT_MAX_VERSION
assert apps[1].application == amo.ANDROID.id
@ -628,25 +636,6 @@ class TestManifestJSONExtractor(AppVersionsMixin, TestCase):
parsed = utils.ManifestJSONExtractor(manifest).parse()
assert parsed['name'] == '...'
def test_raise_error_if_no_optional_id_support(self):
"""
We only support optional ids in Firefox 48+ and will throw an error
otherwise.
"""
data = {
'applications': {
'gecko': {
'strict_min_version': '42.0',
'strict_max_version': '49.0',
}
}
}
with pytest.raises(forms.ValidationError) as exc:
self.parse(data)['apps']
assert exc.value.message == 'Add-on ID is required for Firefox 47 and below.'
def test_comments_are_allowed(self):
json_string = """
{
@ -664,27 +653,6 @@ class TestManifestJSONExtractor(AppVersionsMixin, TestCase):
assert manifest.get('name') == 'My Extension'
def test_dont_skip_apps_because_of_strict_version_incompatibility(self):
# We shouldn't skip adding specific apps to the WebExtension
# no matter any potential incompatibility, e.g
# browser_specific_settings is only supported from Firefox 48.0
# onwards, now if the user specifies strict_min_compat as 42.0
# we shouldn't skip the app because of that. Instead we override the
# value with the known min version that started supporting that.
data = {
'browser_specific_settings': {
'gecko': {'strict_min_version': '42.0', 'id': '@random'}
}
}
apps = self.parse(data)['apps']
assert len(apps) == 2
assert apps[0].application == amo.FIREFOX.id
assert apps[0].min.version == (amo.DEFAULT_WEBEXT_MIN_VERSION_BROWSER_SPECIFIC)
assert apps[1].application == amo.ANDROID.id
assert apps[1].min.version == (amo.DEFAULT_WEBEXT_MIN_VERSION_BROWSER_SPECIFIC)
def test_devtools_page(self):
json_string = """
{
@ -707,11 +675,11 @@ class TestManifestJSONExtractor(AppVersionsMixin, TestCase):
def test_version_not_string(self):
"""Test parsing doesn't fail if version is not a string - that error
should be handled downstream by the linter."""
data = {'version': 42}
assert self.parse(data)['version'] == '42'
data = {'version': 58}
assert self.parse(data)['version'] == '58'
data = {'version': 42.0}
assert self.parse(data)['version'] == '42.0'
data = {'version': 58.0}
assert self.parse(data)['version'] == amo.DEFAULT_WEBEXT_MIN_VERSION
# These are even worse, but what matters is that version stays a string
# in the result.
@ -799,7 +767,7 @@ class TestLanguagePackAndDictionaries(AppVersionsMixin, TestCase):
apps = parsed_data['apps']
assert len(apps) == 1 # Langpacks are not compatible with android.
assert apps[0].application == amo.FIREFOX.id
assert apps[0].min.version == '42.0'
assert apps[0].min.version == amo.DEFAULT_WEBEXT_MIN_VERSION
# The linter should force the langpack to have a strict_max_version,
# so the value here doesn't matter much.
assert apps[0].max.version == '*'
@ -977,25 +945,6 @@ class TestManifestJSONExtractorStaticTheme(TestManifestJSONExtractor):
self.parse(data)
assert exc.value.message == ('Unknown "strict_max_version" 76.0 for Firefox')
def test_dont_skip_apps_because_of_strict_version_incompatibility(self):
# In the parent class this method would bump the min_version to 48.0
# because that's the first version to support
# browser_specific_settings, but in static themes we bump it even
# higher because of the minimum version when we started supporting
# static themes themselves.
data = {
'browser_specific_settings': {
'gecko': {'strict_min_version': '42.0', 'id': '@random'}
}
}
apps = self.parse(data)['apps']
assert len(apps) == 1
assert apps[0].application == amo.FIREFOX.id
assert apps[0].min.version == (amo.DEFAULT_STATIC_THEME_MIN_VERSION_FIREFOX)
assert apps[0].max.version == amo.DEFAULT_WEBEXT_MAX_VERSION
def test_strict_min_version_100(self):
# Overridden because static themes are not compatible with Android.
firefox_min_version = self.create_appversion('firefox', '100.0')
@ -1060,7 +1009,7 @@ class TestManifestJSONExtractorStaticTheme(TestManifestJSONExtractor):
data = {
'browser_specific_settings': {
'gecko': {
'strict_min_version': '53.0',
'strict_min_version': amo.DEFAULT_WEBEXT_MIN_VERSION,
},
'gecko_android': {
'strict_min_version': self.HIGHER_THAN_EVERYTHING_ELSE,
@ -1072,7 +1021,7 @@ class TestManifestJSONExtractorStaticTheme(TestManifestJSONExtractor):
assert len(apps) == 1
app = apps[0]
assert app.application == amo.FIREFOX.id
assert app.min.version == '53.0'
assert app.min.version == amo.DEFAULT_STATIC_THEME_MIN_VERSION_FIREFOX
assert app.max.version == amo.DEFAULT_WEBEXT_MAX_VERSION
def test_gecko_android_strict_min_default_max_with_gecko_alongside(self):
@ -1099,7 +1048,7 @@ class TestManifestJSONExtractorStaticTheme(TestManifestJSONExtractor):
data = {
'browser_specific_settings': {
'gecko_android': {
'strict_min_version': '48.0',
'strict_min_version': amo.DEFAULT_WEBEXT_MIN_VERSION_ANDROID,
},
}
}

Просмотреть файл

@ -280,11 +280,7 @@ class ManifestJSONExtractor:
# WebExt dicts are only compatible with Firefox desktop >= 61.
apps = ((amo.FIREFOX, amo.DEFAULT_WEBEXT_DICT_MIN_VERSION_FIREFOX),)
else:
webext_min_firefox = (
amo.DEFAULT_WEBEXT_MIN_VERSION
if self.get('browser_specific_settings', None) is None
else amo.DEFAULT_WEBEXT_MIN_VERSION_BROWSER_SPECIFIC
)
webext_min_firefox = amo.DEFAULT_WEBEXT_MIN_VERSION
webext_min_android = (
amo.DEFAULT_WEBEXT_MIN_VERSION_GECKO_ANDROID
if self.gecko_android is not EMPTY_FALLBACK_DICT
@ -310,17 +306,6 @@ class ManifestJSONExtractor:
key='min', application=amo.FIREFOX
)
doesnt_support_no_id = (
strict_min_version_firefox
and strict_min_version_firefox
< VersionString(amo.DEFAULT_WEBEXT_MIN_VERSION_NO_ID)
)
if self.guid is None and doesnt_support_no_id:
raise forms.ValidationError(
gettext('Add-on ID is required for Firefox 47 and below.')
)
# If a minimum strict version is specified, it needs to be higher
# than the version when Firefox started supporting WebExtensions.
unsupported_no_matter_what = (
@ -329,25 +314,21 @@ class ManifestJSONExtractor:
< VersionString(amo.DEFAULT_WEBEXT_MIN_VERSION)
)
if unsupported_no_matter_what:
msg = gettext('Lowest supported "strict_min_version" is 42.0.')
raise forms.ValidationError(msg)
msg = gettext('Lowest supported "strict_min_version" is {min_version}.')
raise forms.ValidationError(
msg.format(min_version=amo.DEFAULT_WEBEXT_MIN_VERSION)
)
for app, default_min_version in apps:
strict_min_version_from_manifest = self.get_strict_version_for(
key='min', application=app
)
strict_min_version = strict_min_version_from_manifest
if self.guid is None and not strict_min_version:
strict_min_version = max(
VersionString(amo.DEFAULT_WEBEXT_MIN_VERSION_NO_ID),
VersionString(default_min_version),
)
else:
# strict_min_version for this app shouldn't be lower than the
# default min version for this app.
strict_min_version = max(
strict_min_version, VersionString(default_min_version)
)
# strict_min_version for this app shouldn't be lower than the
# default min version for this app.
strict_min_version = max(
strict_min_version_from_manifest, VersionString(default_min_version)
)
strict_max_version_from_manifest = self.get_strict_version_for(
key='max', application=app

Просмотреть файл

@ -8,9 +8,13 @@ from olympia.landfill.serializers import GenerateAddonsSerializer
class TestGenerateAddonsSerializer(TestCase):
def test_create_installable_addon(self):
Group.objects.create(name='Admins', rules='*:*')
AppVersion.objects.create(application=amo.FIREFOX.id, version='42.0')
AppVersion.objects.create(
application=amo.FIREFOX.id, version=amo.DEFAULT_WEBEXT_MIN_VERSION
)
AppVersion.objects.create(application=amo.FIREFOX.id, version='*')
AppVersion.objects.create(application=amo.ANDROID.id, version='48.0')
AppVersion.objects.create(
application=amo.ANDROID.id, version=amo.DEFAULT_WEBEXT_MIN_VERSION_ANDROID
)
AppVersion.objects.create(application=amo.ANDROID.id, version='*')
serializer = GenerateAddonsSerializer()

Просмотреть файл

@ -111,18 +111,9 @@ def call_signing(file_obj):
'keyid': conf['signer'],
'options': {
'id': get_id(file_obj.version.addon),
# "Add-on variant A params (PKCS7 SHA1 and COSE ES256) work in
# Fx <57, so we can switch to that without breaking backwards
# compatibility"
# https://github.com/mozilla/addons-server/issues/9308
# This means, the pkcs7 sha1 signature is used for backwards
# compatibility and cose sha256 will be used for newer
# Firefox versions.
# The relevant pref in Firefox is
# "security.signed_app_signatures.policy"
# where it's set to COSEAndPKCS7WithSHA1OrSHA256 to match
# these settings.
'pkcs7_digest': 'SHA1',
# Add-ons are dual-signed with PKCS7 SHA256 and COSE ES256
# (requires Fx 58 or greater).
'pkcs7_digest': 'SHA256',
'cose_algorithms': ['ES256'],
},
}

Просмотреть файл

@ -829,7 +829,9 @@ class TestSendPendingRejectionLastWarningNotification(TestCase):
def test_pending_rejection_close_to_deadline_no_cinder_job(self):
author = user_factory()
addon = addon_factory(users=[author], version_kw={'version': '42.0'})
addon = addon_factory(
users=[author], version_kw={'version': amo.DEFAULT_WEBEXT_MIN_VERSION}
)
version_factory(addon=addon, version='42.1')
for version in addon.versions.all():
version_review_flags_factory(
@ -859,7 +861,9 @@ class TestSendPendingRejectionLastWarningNotification(TestCase):
def test_pending_rejection_close_to_deadline_with_cinder_job(self):
author = user_factory()
addon = addon_factory(users=[author], version_kw={'version': '42.0'})
addon = addon_factory(
users=[author], version_kw={'version': amo.DEFAULT_WEBEXT_MIN_VERSION}
)
version = addon.current_version
version_factory(addon=addon, version='42.1')
cinder_job = CinderJob.objects.create(
@ -899,7 +903,9 @@ class TestSendPendingRejectionLastWarningNotification(TestCase):
def test_pending_rejection_one_version_already_disabled(self):
author = user_factory()
addon = addon_factory(users=[author], version_kw={'version': '42.0'})
addon = addon_factory(
users=[author], version_kw={'version': amo.DEFAULT_WEBEXT_MIN_VERSION}
)
current_version = addon.current_version
disabled_version = version_factory(
addon=addon, version='42.1', file_kw={'status': amo.STATUS_DISABLED}
@ -926,7 +932,9 @@ class TestSendPendingRejectionLastWarningNotification(TestCase):
def test_more_recent_version_disabled(self):
author = user_factory()
addon = addon_factory(users=[author], version_kw={'version': '42.0'})
addon = addon_factory(
users=[author], version_kw={'version': amo.DEFAULT_WEBEXT_MIN_VERSION}
)
version1 = addon.current_version
version2 = version_factory(addon=addon, version='42.1')
for version in addon.versions.all():
@ -955,7 +963,9 @@ class TestSendPendingRejectionLastWarningNotification(TestCase):
def test_more_recent_version_deleted(self):
author = user_factory()
addon = addon_factory(users=[author], version_kw={'version': '42.0'})
addon = addon_factory(
users=[author], version_kw={'version': amo.DEFAULT_WEBEXT_MIN_VERSION}
)
version1 = addon.current_version
version2 = version_factory(addon=addon, version='42.1')
for version in addon.versions.all():
@ -983,7 +993,9 @@ class TestSendPendingRejectionLastWarningNotification(TestCase):
def test_more_recent_version_pending_rejection_as_well(self):
author = user_factory()
addon = addon_factory(users=[author], version_kw={'version': '42.0'})
addon = addon_factory(
users=[author], version_kw={'version': amo.DEFAULT_WEBEXT_MIN_VERSION}
)
version1 = addon.current_version
version2 = version_factory(addon=addon, version='42.1')
for version in addon.versions.all():
@ -1014,7 +1026,9 @@ class TestSendPendingRejectionLastWarningNotification(TestCase):
def test_multiple_addons_pending_rejection_close_to_deadline(self):
author1 = user_factory()
addon1 = addon_factory(users=[author1], version_kw={'version': '42.0'})
addon1 = addon_factory(
users=[author1], version_kw={'version': amo.DEFAULT_WEBEXT_MIN_VERSION}
)
version11 = addon1.current_version
version12 = version_factory(addon=addon1, version='42.1')
author2 = user_factory()

Просмотреть файл

@ -2366,7 +2366,9 @@ class TestReviewHelper(TestReviewHelperBase):
old_version = self.review_version
extra_version = version_factory(addon=self.addon, version='3.1')
# Add yet another version we don't want to reject.
self.review_version = version_factory(addon=self.addon, version='42.0')
self.review_version = version_factory(
addon=self.addon, version=amo.DEFAULT_WEBEXT_MIN_VERSION
)
AutoApprovalSummary.objects.create(
version=self.review_version, verdict=amo.AUTO_APPROVED, weight=91
)

Просмотреть файл

@ -4834,7 +4834,7 @@ class TestReview(ReviewBase):
client_id='4815162342',
addon_name='Nâme',
addon_summary='Not used here',
addon_version='42.0',
addon_version=amo.DEFAULT_WEBEXT_MIN_VERSION,
addon_signature=AbuseReport.ADDON_SIGNATURES.UNSIGNED,
application=amo.ANDROID.id,
application_locale='fr_FR',
@ -4861,7 +4861,8 @@ class TestReview(ReviewBase):
'Category',
'Date',
'Reporter',
'Nâme 42.0', # We use the name as submitted in the abuse report.
# We use the name as submitted in the abuse report.
f'Nâme {amo.DEFAULT_WEBEXT_MIN_VERSION}',
'Firefox for Android fr_FR Løst OS 20040922',
'1\xa0day ago',
'Origin: https://example.com/',
@ -5704,7 +5705,7 @@ class TestAbuseReportsView(ReviewerTest):
client_id='4815162342',
addon_name='Nâme',
addon_summary='Not used here',
addon_version='42.0',
addon_version=amo.DEFAULT_WEBEXT_MIN_VERSION,
addon_signature=AbuseReport.ADDON_SIGNATURES.UNSIGNED,
application=amo.ANDROID.id,
application_locale='fr_FR',
@ -5731,7 +5732,8 @@ class TestAbuseReportsView(ReviewerTest):
'Category',
'Date',
'Reporter',
'Nâme 42.0', # We use the name as submitted in the abuse report.
# We use the name as submitted in the abuse report.
f'Nâme {amo.DEFAULT_WEBEXT_MIN_VERSION}',
'Firefox for Android fr_FR Løst OS 20040922',
'1\xa0day ago',
'Origin: https://example.com/',

Просмотреть файл

@ -1678,7 +1678,7 @@ class TestVersionFromUpload(UploadMixin, TestCase):
def setUpTestData(cls):
versions = {
amo.DEFAULT_WEBEXT_MIN_VERSION,
amo.DEFAULT_WEBEXT_MIN_VERSION_NO_ID,
amo.DEFAULT_WEBEXT_MIN_VERSION,
amo.DEFAULT_WEBEXT_MIN_VERSION_ANDROID,
amo.DEFAULT_WEBEXT_MAX_VERSION,
}
@ -1870,7 +1870,7 @@ class TestExtensionVersionFromUpload(TestVersionFromUpload):
)
assert amo.FIREFOX in version.compatible_apps
app = version.compatible_apps[amo.FIREFOX]
assert app.min.version == '42.0'
assert app.min.version == amo.DEFAULT_WEBEXT_MIN_VERSION
assert app.max.version == '*'
def test_compatibility_just_app(self):
@ -1886,7 +1886,7 @@ class TestExtensionVersionFromUpload(TestVersionFromUpload):
)
assert [amo.FIREFOX] == list(version.compatible_apps)
app = version.compatible_apps[amo.FIREFOX]
assert app.min.version == '42.0'
assert app.min.version == amo.DEFAULT_WEBEXT_MIN_VERSION
assert app.max.version == '*'
def test_compatibility_min_max_too(self):
@ -1939,7 +1939,7 @@ class TestExtensionVersionFromUpload(TestVersionFromUpload):
assert amo.ANDROID not in version.compatible_apps
assert amo.FIREFOX in version.compatible_apps
app = version.compatible_apps[amo.FIREFOX]
assert app.min.version == '42.0'
assert app.min.version == amo.DEFAULT_WEBEXT_MIN_VERSION
assert app.max.version == '*'
# Clear cache and check again, it should be updated.
@ -1947,7 +1947,7 @@ class TestExtensionVersionFromUpload(TestVersionFromUpload):
assert amo.ANDROID in version.compatible_apps
assert amo.FIREFOX not in version.compatible_apps
app = version.compatible_apps[amo.ANDROID]
assert app.min.version == '42.0'
assert app.min.version == amo.DEFAULT_WEBEXT_MIN_VERSION
assert app.max.version == '*'
def test_compatible_apps_cloned_if_passed_existing_instances(self):
@ -2872,8 +2872,12 @@ class TestStaticThemeFromUpload(UploadMixin, TestCase):
amo.DEFAULT_WEBEXT_MAX_VERSION,
}
for version in versions:
AppVersion.objects.create(application=amo.FIREFOX.id, version=version)
AppVersion.objects.create(application=amo.ANDROID.id, version=version)
AppVersion.objects.get_or_create(
application=amo.FIREFOX.id, version=version
)
AppVersion.objects.get_or_create(
application=amo.ANDROID.id, version=version
)
def setUp(self):
path = 'src/olympia/devhub/tests/addons/static_theme.zip'