def test_no_manifest_at_root(self):
     with self.assertRaises(forms.ValidationError) as exc:
         WebAppParser().parse(
             self.packaged_app_path('no-manifest-at-root.zip'))
     m = exc.exception.messages[0]
     assert m.startswith('The file "manifest.webapp" was not found'), (
         'Unexpected: %s' % m)
Example #2
0
 def test_name_with_translations_fallback(self, get_json_data):
     get_json_data.return_value = {
         'name': 'Blah',
         'description': 'Blah Description',
         'developer': {
             'name': 'Mozilla Marketplace Testing'
         },
         'default_locale': 'en-US',
         'locales': {
             'fr': {
                 'description': 'Blah Description (fr)',
             },
             'es': {
                 'name': 'Blah (es)',
             }
         }
     }
     # The argument to parse() is supposed to be a filename, it doesn't
     # matter here though since we are mocking get_json_data().
     parsed_results = WebAppParser().parse('')
     eq_(parsed_results['name'].get('fr'), 'Blah')  # Falls back to default.
     eq_(parsed_results['name'].get('es'), 'Blah (es)')
     eq_(parsed_results['name'].get('en-US'), 'Blah')
     eq_(parsed_results['name'].get('de'), None)
     eq_(parsed_results['default_locale'], 'en-US')
Example #3
0
 def test_name_with_translations_and_short_languages(self, get_json_data):
     get_json_data.return_value = {
         'name': 'Blah',
         'developer': {
             'name': 'Mozilla Marketplace Testing'
         },
         'default_locale': 'en',  # Will be transformed to en-US.
         'locales': {
             'fr': {
                 'name': 'Blah (fr)',
             },
             'pt': {
                 'name': 'Blah (pt)',
             }
         }
     }
     # The argument to parse() is supposed to be a filename, it doesn't
     # matter here though since we are mocking get_json_data().
     parsed_results = WebAppParser().parse('')
     eq_(parsed_results['name'].get('fr'), 'Blah (fr)')
     eq_(parsed_results['name'].get('pt-PT'), 'Blah (pt)')
     eq_(parsed_results['name'].get('en-US'), 'Blah')
     eq_(parsed_results['name'].get('de'), None)
     eq_(parsed_results['name'].get('pt'), None)
     eq_(parsed_results['name'].get('en'), None)
     eq_(parsed_results['default_locale'], 'en-US')
 def test_non_ascii(self):
     wm = json.dumps(dict(name=u'まつもとゆきひろ',
                          version='1.0',
                          developer=dict(name=u'まつもとゆきひろ')),
                     encoding='shift-jis')
     wp = WebAppParser().parse(self.webapp(contents=wm))
     eq_(wp['name'], {'en-US': u'まつもとゆきひろ'})
 def test_no_locales(self):
     wp = WebAppParser().parse(
         self.webapp(
             dict(name='foo',
                  version='1.0',
                  description='description',
                  developer=dict(name='bar'))))
     eq_(wp['description']['en-US'], u'description')
Example #6
0
    def clean_upload(self):
        upload = self.cleaned_data['upload']
        errors = []

        if upload.size > self.max_size:
            errors.append({
                'type': 'error',
                'message': _('Packaged app too large for submission. Packages '
                             'must be smaller than %s.' % filesizeformat(
                                 self.max_size)),
                'tier': 1,
            })
            # Immediately raise an error, do not process the rest of the view,
            # which would read the file.
            raise self.persist_errors(errors, upload)

        manifest = None
        try:
            # Be careful to keep this as in-memory zip reading.
            safe_zip = SafeUnzip(upload, 'r')
            safe_zip.is_valid()  # Will throw ValidationError if necessary.
            manifest = safe_zip.extract_path('manifest.webapp')
        except forms.ValidationError as e:
            errors.append({
                'type': 'error',
                'message': ''.join(e.messages),
                'tier': 1,
            })
        except Exception as e:
            errors.append({
                'type': 'error',
                'message': _('Error extracting manifest from zip file.'),
                'tier': 1,
            })
        finally:
            safe_zip.close()

        origin = None
        if manifest:
            try:
                origin = WebAppParser.decode_manifest(manifest).get('origin')
            except forms.ValidationError as e:
                errors.append({
                    'type': 'error',
                    'message': ''.join(e.messages),
                    'tier': 1,
                })

        if origin:
            try:
                verify_app_domain(origin, packaged=True, exclude=self.addon)
            except forms.ValidationError, e:
                errors.append({
                    'type': 'error',
                    'message': ''.join(e.messages),
                    'tier': 1,
                })
 def test_parse_packaged_BOM(self):
     wp = WebAppParser().parse(self.packaged_app_path('mozBOM.zip'))
     eq_(wp['guid'], None)
     eq_(wp['name']['en-US'], u'Packaged MozBOM ょ')
     eq_(wp['description']['en-US'], u'Exciting BOM action!')
     eq_(wp['description']['es'], u'¡Acción BOM!')
     eq_(wp['description']['it'], u'Azione BOM!')
     eq_(wp['version'], '1.0')
     eq_(wp['default_locale'], 'en-US')
 def test_parse(self):
     wp = WebAppParser().parse(self.webapp_path)
     eq_(wp['guid'], None)
     eq_(wp['description']['en-US'], u'Exciting Open Web development action!')
     # UTF-8 byte string decoded to unicode.
     eq_(wp['description']['es'],
         u'\xa1Acci\xf3n abierta emocionante del desarrollo del Web!')
     eq_(wp['description']['it'],
         u'Azione aperta emozionante di sviluppo di fotoricettore!')
     eq_(wp['version'], '1.0')
     eq_(wp['default_locale'], 'en-US')
Example #9
0
 def test_developer_name(self, get_json_data):
     get_json_data.return_value = {
         'name': 'Blah',
         'developer': {
             'name': 'Mozilla Marketplace Testing'
         }
     }
     # The argument to parse() is supposed to be a filename, it doesn't
     # matter here though since we are mocking get_json_data().
     parsed_results = WebAppParser().parse('')
     eq_(parsed_results['developer_name'], 'Mozilla Marketplace Testing')
Example #10
0
 def test_empty_developer_object(self, get_json_data):
     get_json_data.return_value = {'name': 'Blah', 'developer': {}}
     with self.assertRaises(forms.ValidationError) as e:
         # The argument to parse() is supposed to be a filename, it doesn't
         # matter here though since we are mocking get_json_data().
         WebAppParser().parse('')
     eq_(e.exception.messages, [
         "Developer name is required in the manifest"
         " in order to display it on the app's "
         "listing."
     ])
 def test_parse_packaged(self):
     wp = WebAppParser().parse(self.packaged_app_path('mozball.zip'))
     eq_(wp['guid'], None)
     eq_(wp['name']['en-US'], u'Packaged MozillaBall ょ')
     eq_(wp['description']['en-US'], u'Exciting Open Web development action!')
     eq_(wp['description']['es'],
         u'¡Acción abierta emocionante del desarrollo del Web!')
     eq_(wp['description']['it'],
         u'Azione aperta emozionante di sviluppo di fotoricettore!')
     eq_(wp['version'], '1.0')
     eq_(wp['default_locale'], 'en-US')
 def test_no_manifest_at_root(self):
     path = self.packaged_app_path('no-manifest-at-root.zip')
     if storage_is_remote():
         with open(path) as local_f:
             with storage.open(path, 'w') as remote_f:
                 copyfileobj(local_f, remote_f)
     with self.assertRaises(forms.ValidationError) as exc:
         WebAppParser().parse(path)
     m = exc.exception.messages[0]
     assert m.startswith('The file "manifest.webapp" was not found'), (
         'Unexpected: %s' % m)
Example #13
0
def generate_packaged_app(namedict, apptype, categories, developer_name,
                          privacy_policy=None, device_types=(),
                          permissions=(), versions=(),
                          default_locale='en-US', package_file=None,
                          status=4, **kw):
    now = datetime.datetime.now()
    app = app_factory(categories=categories, name=namedict[default_locale],
                      complete=False, rated=True, is_packaged=True,
                      privacy_policy=privacy_policy,
                      version_kw={
                          'version': '1.0',
                          'reviewed': now if status >= 4 else None,
                          '_developer_name': developer_name},
                      file_kw={'status': status})
    if device_types:
        for dt in device_types:
            app.addondevicetype_set.create(device_type=DEVICE_CHOICES_IDS[dt])
    else:
        app.addondevicetype_set.create(device_type=1)
    f = app.latest_version.all_files[0]
    f.update(filename=f.generate_filename())
    fp = os.path.join(app.latest_version.path_prefix, f.filename)
    if package_file:
        package_file_file = open(package_file)
        manifest = WebAppParser().get_json_data(package_file_file)
        AppManifest.objects.create(
            version=app.latest_version, manifest=json.dumps(manifest))
        # copy package_file to storage like a normal app.
        private_storage.save(fp, package_file_file)
        app.update_version()
        return app
    with private_storage.open(fp, 'w') as out:
        generate_app_package(app, out, apptype,
                             permissions, namedict,
                             version=app.latest_version)
    for i, vspec in enumerate(versions, 1):
        st = STATUS_CHOICES_API_LOOKUP[vspec.get("status", "public")]
        rtime = (now + datetime.timedelta(i))
        v = version_factory(version="1." + str(i), addon=app,
                            reviewed=rtime if st >= 4 else None,
                            nomination=rtime if st > 0 else None,
                            created=rtime,
                            file_kw={'status': st},
                            _developer_name=developer_name)
        f = v.files.all()[0]
        f.update(filename=f.generate_filename())
        fp = os.path.join(app.latest_version.path_prefix, f.filename)
        with private_storage.open(fp, 'w') as out:
            generate_app_package(app, out, vspec.get("type", apptype),
                                 vspec.get("permissions", permissions),
                                 namedict, version=v)
        app.update_version()
    return app
Example #14
0
 def test_no_manifest_at_root(self):
     path = self.packaged_app_path('no-manifest-at-root.zip')
     if storage_is_remote():
         copy_stored_file(path,
                          path,
                          src_storage=local_storage,
                          dst_storage=private_storage)
     with self.assertRaises(forms.ValidationError) as exc:
         WebAppParser().parse(private_storage.open(path))
     m = exc.exception.messages[0]
     assert m.startswith('The file "manifest.webapp" was not found'), (
         'Unexpected: %s' % m)
 def test_parse_packaged_BOM(self):
     path = self.packaged_app_path('mozBOM.zip')
     if storage_is_remote():
         with open(path) as local_f:
             with storage.open(path, 'w') as remote_f:
                 copyfileobj(local_f, remote_f)
     wp = WebAppParser().parse(path)
     eq_(wp['guid'], None)
     eq_(wp['name']['en-US'], u'Packaged MozBOM ょ')
     eq_(wp['description']['en-US'], u'Exciting BOM action!')
     eq_(wp['description']['es'], u'¡Acción BOM!')
     eq_(wp['description']['it'], u'Azione BOM!')
     eq_(wp['version'], '1.0')
     eq_(wp['default_locale'], 'en-US')
Example #16
0
 def test_parse_packaged_BOM(self):
     path = self.packaged_app_path('mozBOM.zip')
     if storage_is_remote():
         copy_stored_file(path,
                          path,
                          src_storage=local_storage,
                          dst_storage=private_storage)
     wp = WebAppParser().parse(private_storage.open(path))
     eq_(wp['guid'], None)
     eq_(wp['name']['en-US'], u'Packaged MozBOM ょ')
     eq_(wp['description']['en-US'], u'Exciting BOM action!')
     eq_(wp['description']['es'], u'¡Acción BOM!')
     eq_(wp['description']['it'], u'Azione BOM!')
     eq_(wp['version'], '1.0')
     eq_(wp['default_locale'], 'en-US')
 def test_parse_packaged(self):
     path = self.packaged_app_path('mozball.zip')
     if storage_is_remote():
         with open(path) as local_f:
             with storage.open(path, 'w') as remote_f:
                 copyfileobj(local_f, remote_f)
     wp = WebAppParser().parse(path)
     eq_(wp['guid'], None)
     eq_(wp['name']['en-US'], u'Packaged MozillaBall ょ')
     eq_(wp['description']['en-US'],
         u'Exciting Open Web development action!')
     eq_(wp['description']['es'],
         u'¡Acción abierta emocionante del desarrollo del Web!')
     eq_(wp['description']['it'],
         u'Azione aperta emozionante di sviluppo di fotoricettore!')
     eq_(wp['version'], '1.0')
     eq_(wp['default_locale'], 'en-US')
Example #18
0
    def clean_upload(self):
        upload = self.cleaned_data["upload"]
        errors = []

        if upload.size > self.max_size:
            errors.append(
                {
                    "type": "error",
                    "message": _(
                        "Packaged app too large for submission. Packages "
                        "must be smaller than %s." % filesizeformat(self.max_size)
                    ),
                    "tier": 1,
                }
            )
            # Immediately raise an error, do not process the rest of the view,
            # which would read the file.
            raise self.persist_errors(errors, upload)

        manifest = None
        try:
            # Be careful to keep this as in-memory zip reading.
            manifest = ZipFile(upload, "r").read("manifest.webapp")
        except Exception as e:
            errors.append({"type": "error", "message": _("Error extracting manifest from zip file."), "tier": 1})

        origin = None
        if manifest:
            try:
                origin = WebAppParser.decode_manifest(manifest).get("origin")
            except forms.ValidationError as e:
                errors.append({"type": "error", "message": "".join(e.messages), "tier": 1})

        if origin:
            try:
                verify_app_domain(origin, packaged=True, exclude=self.addon)
            except forms.ValidationError, e:
                errors.append({"type": "error", "message": "".join(e.messages), "tier": 1})
Example #19
0
def import_manifests(ids, **kw):
    for app in Webapp.objects.filter(id__in=ids):
        for version in app.versions.all():
            try:
                file_ = version.files.latest()
                if file_.status == amo.STATUS_DISABLED:
                    file_path = file_.guarded_file_path
                else:
                    file_path = file_.file_path
                manifest = WebAppParser().get_json_data(file_path)
                m, c = AppManifest.objects.get_or_create(
                    version=version, manifest=json.dumps(manifest))
                if c:
                    task_log.info(
                        '[Webapp:%s] Imported manifest for version %s' % (
                            app.id, version.id))
                else:
                    task_log.info(
                        '[Webapp:%s] App manifest exists for version %s' % (
                            app.id, version.id))
            except Exception as e:
                task_log.info('[Webapp:%s] Error loading manifest for version '
                              '%s: %s' % (app.id, version.id, e))
 def test_utf8_bom(self):
     wm = codecs.BOM_UTF8 + json.dumps(self.manifest, encoding='utf8')
     wp = WebAppParser().parse(self.webapp(contents=wm))
     eq_(wp['version'], '1.0')
 def test_syntax_error(self):
     with self.assertRaises(forms.ValidationError) as exc:
         WebAppParser().parse(self.webapp(contents='}]'))
     m = exc.exception.messages[0]
     assert m.startswith('The webapp manifest is not valid JSON.'), (
         'Unexpected: %s' % m)
 def test_no_description(self):
     wp = WebAppParser().parse(
         self.webapp(
             dict(name='foo', version='1.0', developer=dict(name='bar'))))
     eq_(wp['description'], {})