Beispiel #1
0
    def test_repacking_xpi_files(self):
        """Test that repack_fileupload() does repack xpi files (no mocks)"""
        # Take an extension with a directory structure, so that we can test
        # that structure is restored once the file has been moved.
        upload = self.get_upload('unicode-filenames.xpi')
        original_hash = upload.hash
        repack_fileupload(upload.pk)
        upload.reload()
        assert upload.hash.startswith('sha256:')
        assert upload.hash != original_hash

        # Test zip contents
        with zipfile.ZipFile(upload.path) as z:
            contents = sorted(z.namelist())
            assert contents == [
                u'chrome.manifest',
                u'chrome/',
                u'chrome/content/',
                u'chrome/content/ff-overlay.js',
                u'chrome/content/ff-overlay.xul',
                u'chrome/content/overlay.js',
                u'chrome/locale/',
                u'chrome/locale/en-US/',
                u'chrome/locale/en-US/overlay.dtd',
                u'chrome/locale/en-US/overlay.properties',
                u'chrome/skin/',
                u'chrome/skin/overlay.css',
                u'install.rdf',
                u'삮'
            ]
        # Spot-check an individual file.
        info = z.getinfo('install.rdf')
        assert info.file_size == 717
        assert info.compress_size < info.file_size
        assert info.compress_type == zipfile.ZIP_DEFLATED
Beispiel #2
0
    def test_repacking_xpi_files(self):
        """Test that repack_fileupload() does repack xpi files (no mocks)"""
        # Take an extension with a directory structure, so that we can test
        # that structure is restored once the file has been moved.
        upload = self.get_upload('unicode-filenames.xpi')
        original_hash = upload.hash
        repack_fileupload(upload.pk)
        upload.reload()
        assert upload.hash.startswith('sha256:')
        assert upload.hash != original_hash

        # Test zip contents
        with zipfile.ZipFile(upload.path) as z:
            contents = sorted(z.namelist())
            assert contents == [
                u'chrome.manifest', u'chrome/', u'chrome/content/',
                u'chrome/content/ff-overlay.js',
                u'chrome/content/ff-overlay.xul', u'chrome/content/overlay.js',
                u'chrome/locale/', u'chrome/locale/en-US/',
                u'chrome/locale/en-US/overlay.dtd',
                u'chrome/locale/en-US/overlay.properties', u'chrome/skin/',
                u'chrome/skin/overlay.css', u'install.rdf', u'삮'
            ]
        # Spot-check an individual file.
        info = z.getinfo('install.rdf')
        assert info.file_size == 717
        assert info.compress_size < info.file_size
        assert info.compress_type == zipfile.ZIP_DEFLATED
Beispiel #3
0
    def test_normalize_manifest_json(self):
        upload = self.get_upload('webextension.xpi')
        fake_results = {'errors': 0}
        with zipfile.ZipFile(upload.path, 'w') as z:
            manifest_with_comments = """
            {
                // Required
                "manifest_version": 2,
                "name": "My Extension",
                "version": "versionString",
                // Recommended
                "description": "haupt\\u005fstra\\u00dfe"
            }
            """
            z.writestr('manifest.json', manifest_with_comments)

        repack_fileupload(fake_results, upload.pk)
        upload.reload()

        with zipfile.ZipFile(upload.path) as z:
            with z.open('manifest.json') as manifest:
                # Make sure it is valid JSON
                assert json.loads(manifest.read())
                # Read the content again to make sure comments have been
                # removed with a string comparison.
                manifest.seek(0)
                assert manifest.read().decode() == '\n'.join([
                    '{',
                    '  "manifest_version": 2,',
                    '  "name": "My Extension",',
                    '  "version": "versionString",',
                    '  "description": "haupt_stra\\u00dfe"',
                    '}',
                ])
Beispiel #4
0
    def test_repacking_xpi_files(self):
        """Test that repack_fileupload() does repack xpi files (no mocks)"""
        # Take an extension with a directory structure, so that we can test
        # that structure is restored once the file has been moved.
        upload = self.get_upload('unicode-filenames.xpi')
        original_hash = upload.hash
        fake_results = {'errors': 0}
        tmp_dir_before_repacking = sorted(os.listdir(tempfile.gettempdir()))
        repack_fileupload(fake_results, upload.pk)
        upload.reload()
        assert upload.hash.startswith('sha256:')
        assert upload.hash != original_hash

        # Test zip contents
        with zipfile.ZipFile(upload.path) as z:
            contents = sorted(z.namelist())
            assert contents == [
                'index.js',
                'manifest.json',
                '삮',
            ]
        # Spot-check an individual file.
        info = z.getinfo('manifest.json')
        assert info.file_size == 240
        assert info.compress_size < info.file_size
        assert info.compress_type == zipfile.ZIP_DEFLATED
        # Check we cleaned up after ourselves: we shouldn't have left anything
        # in /tmp.
        assert tmp_dir_before_repacking == sorted(os.listdir(tempfile.gettempdir()))
Beispiel #5
0
    def test_does_not_normalize_manifest_json_when_addon_is_signed(self):
        upload = self.get_upload('webextension_signed_already.xpi')
        fake_results = {'errors': 0}
        with zipfile.ZipFile(upload.path, 'r') as z:
            with z.open('manifest.json') as manifest:
                original_manifest = manifest.read().decode()

        repack_fileupload(fake_results, upload.pk)
        upload.reload()

        with zipfile.ZipFile(upload.path) as z:
            with z.open('manifest.json') as manifest:
                assert manifest.read().decode() == original_manifest
Beispiel #6
0
 def test_repacking_xpi_files_with_mocks(
         self, extract_zip_mock, shutil_mock, get_sha256_mock,
         move_stored_file_mock):
     """Opposite of test_not_repacking_non_xpi_files() (using same mocks)"""
     upload = self.get_upload('webextension.xpi')
     get_sha256_mock.return_value = 'fakehashfrommock'
     extract_zip_mock.return_value = '/tmp/faketempdir'
     repack_fileupload(upload.pk)
     assert extract_zip_mock.called
     assert shutil_mock.make_archive.called
     assert get_sha256_mock.called
     assert move_stored_file_mock.called
     upload.reload()
     assert upload.hash == 'sha256:fakehashfrommock'
Beispiel #7
0
 def test_not_repacking_non_xpi_files_with_mocks(
         self, extract_zip_mock, shutil_mock, get_sha256_mock,
         move_stored_file_mock):
     """Test we're not repacking non-xpi files"""
     upload = self.get_upload('search.xml')
     old_hash = upload.hash
     assert old_hash.startswith('sha256:')
     repack_fileupload(upload.pk)
     assert not extract_zip_mock.called
     assert not shutil_mock.make_archive.called
     assert not get_sha256_mock.called
     assert not move_stored_file_mock.called
     upload.reload()
     assert upload.hash == old_hash  # Hasn't changed.
Beispiel #8
0
 def test_repacking_xpi_files_with_mocks(self, extract_zip_mock,
                                         shutil_mock, get_sha256_mock,
                                         move_stored_file_mock):
     """Opposite of test_not_repacking_non_xpi_files() (using same mocks)"""
     upload = self.get_upload('webextension.xpi')
     get_sha256_mock.return_value = 'fakehashfrommock'
     extract_zip_mock.return_value = '/tmp/faketempdir'
     repack_fileupload(upload.pk)
     assert extract_zip_mock.called
     assert shutil_mock.make_archive.called
     assert get_sha256_mock.called
     assert move_stored_file_mock.called
     upload.reload()
     assert upload.hash == 'sha256:fakehashfrommock'
Beispiel #9
0
 def test_not_repacking_non_xpi_files_with_mocks(self, extract_zip_mock,
                                                 shutil_mock,
                                                 get_sha256_mock,
                                                 move_stored_file_mock):
     """Test we're not repacking non-xpi files"""
     upload = self.get_upload('search.xml')
     old_hash = upload.hash
     assert old_hash.startswith('sha256:')
     repack_fileupload(upload.pk)
     assert not extract_zip_mock.called
     assert not shutil_mock.make_archive.called
     assert not get_sha256_mock.called
     assert not move_stored_file_mock.called
     upload.reload()
     assert upload.hash == old_hash  # Hasn't changed.
Beispiel #10
0
def validate_upload(upload_pk, channel):
    """
    Repack and then validate a FileUpload.

    This only exists to get repack_fileupload() and validate_file_path()
    into a single task that is wrapped by @validation_task. We do this because
    with Celery < 4.2, on_error is never executed for task chains, so we use
    a task decorated by @validation_task which takes care of it for us. Once
    we upgrade to Celery 4.2, we stop calling repack_fileupload() here and just
    have Validator.task return a chain with those 2 tasks when it's dealing
    with a FileUpload.
    https://github.com/mozilla/addons-server/issues/9068#issuecomment-473255011
    """
    upload = FileUpload.objects.get(pk=upload_pk)
    repack_fileupload(upload.pk)
    return validate_file_path(upload.path, channel)
Beispiel #11
0
def validate_upload(upload_pk, channel):
    """
    Repack and then validate a FileUpload.

    This only exists to get repack_fileupload() and validate_file_path()
    into a single task that is wrapped by @validation_task. We do this because
    with Celery < 4.2, on_error is never executed for task chains, so we use
    a task decorated by @validation_task which takes care of it for us. Once
    we upgrade to Celery 4.2, we stop calling repack_fileupload() here and just
    have Validator.task return a chain with those 2 tasks when it's dealing
    with a FileUpload.
    https://github.com/mozilla/addons-server/issues/9068#issuecomment-473255011
    """
    upload = FileUpload.objects.get(pk=upload_pk)
    repack_fileupload(upload.pk)
    return validate_file_path(upload.path, channel)
Beispiel #12
0
 def test_repacking_xpi_files_with_mocks(
     self, extract_to_dest_mock, shutil_mock, get_sha256_mock, move_stored_file_mock
 ):
     """Opposite of test_not_repacking_non_xpi_files() (using same mocks)"""
     upload = self.get_upload('webextension.xpi')
     get_sha256_mock.return_value = 'fakehashfrommock'
     fake_results = {'errors': 0}
     repack_fileupload(fake_results, upload.pk)
     assert extract_to_dest_mock.called
     tempdir = extract_to_dest_mock.call_args[0][0]
     assert tempdir.startswith(tempfile.gettempdir())  # On local filesystem
     assert not tempdir.startswith(settings.TMP_PATH)  # Not on EFS
     assert shutil_mock.make_archive.called
     assert get_sha256_mock.called
     assert move_stored_file_mock.called
     upload.reload()
     assert upload.hash == 'sha256:fakehashfrommock'
Beispiel #13
0
    def test_normalize_manifest_json_with_missing_manifest(self):
        # This file does not have a manifest.json at all but it does not matter
        # since we expect the manifest file to be at the root of the archive.
        upload = self.get_upload('directory-test.xpi')
        fake_results = {'errors': 0}

        results = repack_fileupload(fake_results, upload.pk)

        # If there is an error raised somehow, the `@validation_task` decorator
        # will catch it and return an error.
        assert results['errors'] == 0
Beispiel #14
0
    def test_normalize_manifest_json_with_syntax_error(self):
        upload = self.get_upload('webextension.xpi')
        fake_results = {'errors': 0}
        with zipfile.ZipFile(upload.path, 'w') as z:
            manifest = b'{"manifest_version": 2, THIS_IS_INVALID }'
            z.writestr('manifest.json', manifest)

        results = repack_fileupload(fake_results, upload.pk)

        # If there is an error raised somehow, the `@validation_task` decorator
        # will catch it and return an error.
        assert results['errors'] == 0
Beispiel #15
0
    def test_normalize_manifest_json_with_bom(self):
        upload = self.get_upload('webextension.xpi')
        fake_results = {'errors': 0}
        with zipfile.ZipFile(upload.path, 'w') as z:
            manifest = b'\xef\xbb\xbf{"manifest_version": 2, "name": "..."}'
            z.writestr('manifest.json', manifest)

        repack_fileupload(fake_results, upload.pk)
        upload.reload()

        with zipfile.ZipFile(upload.path) as z:
            with z.open('manifest.json') as manifest:
                # Make sure it is valid JSON
                assert json.loads(manifest.read())
                manifest.seek(0)
                assert manifest.read().decode() == '\n'.join([
                    '{',
                    '  "manifest_version": 2,',
                    '  "name": "..."',
                    '}',
                ])
Beispiel #16
0
    def test_does_not_normalize_manifest_json_when_switch_is_inactive(self):
        upload = self.get_upload('webextension.xpi')
        fake_results = {'errors': 0}
        manifest_with_comments = """
        {
            // Required
            "manifest_version": 2,
            "name": "My Extension",
            "version": "versionString",
            // Recommended
            "description": "haupt\\u005fstra\\u00dfe"
        }
        """
        with zipfile.ZipFile(upload.path, 'w') as z:
            z.writestr('manifest.json', manifest_with_comments)

        repack_fileupload(fake_results, upload.pk)
        upload.reload()

        with zipfile.ZipFile(upload.path) as z:
            with z.open('manifest.json') as manifest:
                assert manifest.read().decode() == manifest_with_comments