예제 #1
0
파일: forms.py 프로젝트: waseem18/zamboni
    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,
                })
예제 #2
0
 def test_is_broken(self):
     zip = SafeUnzip(self.packaged_app_path('signed.zip'))
     zip.is_valid()
     sf_re = re.compile('^META\-INF/(\w+)\.sf$')
     for info in zip.info:
         if sf_re.match(info.filename):
             info.filename = 'META-INF/foo.foo'
             break
     assert not zip.is_signed()
예제 #3
0
    def manifest_contents(self):
        fp = get_file(self.fileorpath)
        if zipfile.is_zipfile(fp):
            zf = SafeUnzip(fp)
            zf.is_valid()  # Raises forms.ValidationError if problems.
            try:
                data = zf.extract_path('manifest.json')
            except KeyError:
                raise forms.ValidationError(
                    _('The file "manifest.json" was not found at the root '
                      'of the zip archive.'))
        else:
            raise forms.ValidationError(
                _('Addons need to be packaged into a valid zip archive.'))

        return self.decode_manifest(data)
예제 #4
0
 def validate_file(self, file_obj):
     """
     Verify that the upload is a valid zip file that contains a
     manifest.json file.
     """
     if file_obj.content_type not in self.valid_content_types:
         self.error('BAD_CONTENT_TYPE')
     try:
         self.zipfile = SafeUnzip(file_obj)
         try:
             # Will throw ValidationError if necessary.
             self.zipfile.is_valid()
         except ValidationError as e:
             raise ParseError(unicode(e))
         except (BadZipfile, IOError):
             self.error('INVALID_ZIP')
         manifest = self.zipfile.extract_path('manifest.json')
     except KeyError:
         self.error('NO_MANIFEST')
     return manifest
예제 #5
0
 def test_unzip_total_file_size_limit(self):
     # There are no files over 100 kb in that zip, but the total is over.
     zip = SafeUnzip(self.packaged_app_path('full-tpa.zip'))
     self.assertRaises(forms.ValidationError, zip.is_valid)
예제 #6
0
 def test_is_secure(self):
     zip = SafeUnzip(self.packaged_app_path('signed.zip'))
     zip.is_valid()
     assert zip.is_signed()
예제 #7
0
 def test_not_secure(self):
     zip = SafeUnzip(self.packaged_app_path('mozball.zip'))
     zip.is_valid()
     assert not zip.is_signed()
예제 #8
0
 def test_extract_path(self):
     zip = SafeUnzip(self.packaged_app_path('mozball.zip'))
     assert zip.is_valid()
     desc_string = '"description": "Exciting Open Web development action!"'
     assert desc_string in zip.extract_path('manifest.webapp')
예제 #9
0
 def test_unzip_not_fatal(self):
     zip = SafeUnzip(self.manifest_path('mozball.webapp'))
     assert not zip.is_valid(fatal=False)
예제 #10
0
 def test_unzip_fatal(self):
     zip = SafeUnzip(self.manifest_path('mozball.webapp'))
     self.assertRaises(zipfile.BadZipfile, zip.is_valid)
예제 #11
0
 def test_unzip_limit(self):
     zip = SafeUnzip(self.packaged_app_path('full-tpa.zip'))
     self.assertRaises(forms.ValidationError, zip.is_valid)
예제 #12
0
def fetch_icon(pk, file_pk=None, **kw):
    """
    Downloads a webapp icon from the location specified in the manifest.

    Returns False if icon was not able to be retrieved

    If `file_pk` is not provided it will use the file from the app's
    `current_version`.

    """
    webapp = Webapp.objects.get(pk=pk)
    log.info(u'[1@None] Fetching icon for webapp %s.' % webapp.name)
    if file_pk:
        file_obj = File.objects.get(pk=file_pk)
    else:
        file_obj = (webapp.current_version and
                    webapp.current_version.all_files[0])
    manifest = webapp.get_manifest_json(file_obj)

    if not manifest or 'icons' not in manifest:
        # Set the icon type to empty.
        webapp.update(icon_type='')
        return

    try:
        biggest = max(int(size) for size in manifest['icons'])
    except ValueError:
        log.error('No icon to fetch for webapp "%s"' % webapp.name)
        return False

    icon_url = manifest['icons'][str(biggest)]
    if icon_url.startswith('data:image'):
        image_string = icon_url.split('base64,')[1]
        content = base64.decodestring(image_string)
    else:
        if webapp.is_packaged:
            # Get icons from package.
            if icon_url.startswith('/'):
                icon_url = icon_url[1:]
            try:
                zf = SafeUnzip(private_storage.open(file_obj.file_path))
                zf.is_valid()
                content = zf.extract_path(icon_url)
            except (KeyError, forms.ValidationError):  # Not found in archive.
                log.error(u'[Webapp:%s] Icon %s not found in archive'
                          % (webapp, icon_url))
                return False
        else:
            if not urlparse.urlparse(icon_url).scheme:
                icon_url = webapp.origin + icon_url

            try:
                response = _fetch_content(icon_url)
            except Exception, e:
                log.error(u'[Webapp:%s] Failed to fetch icon for webapp: %s'
                          % (webapp, e))
                # Set the icon type to empty.
                webapp.update(icon_type='')
                return False

            try:
                content = get_content_and_check_size(
                    response, settings.MAX_ICON_UPLOAD_SIZE)
            except ResponseTooLargeException:
                log.warning(u'[Webapp:%s] Icon exceeds maximum size.' % webapp)
                return False
예제 #13
0
 def test_unzip_fatal(self):
     zip = SafeUnzip(self.xpi_path('search.xml'))
     self.assertRaises(zipfile.BadZipfile, zip.is_valid)
예제 #14
0
 def test_unzip_limit(self):
     zip = SafeUnzip(self.xpi_path('langpack-localepicker'))
     self.assertRaises(forms.ValidationError, zip.is_valid)
예제 #15
0
 def test_is_broken(self):
     zip = SafeUnzip(self.xpi_path('signed'))
     zip.is_valid()
     zip.info[2].filename = 'META-INF/foo.sf'
     assert not zip.is_signed()
예제 #16
0
 def test_is_secure(self):
     zip = SafeUnzip(self.xpi_path('signed'))
     zip.is_valid()
     assert zip.is_signed()
예제 #17
0
 def test_not_secure(self):
     zip = SafeUnzip(self.xpi_path('extension'))
     zip.is_valid()
     assert not zip.is_signed()
예제 #18
0
 def test_extract_path(self):
     zip = SafeUnzip(self.xpi_path('langpack-localepicker'))
     assert zip.is_valid()
     assert 'locale browser de' in zip.extract_path('chrome.manifest')
예제 #19
0
 def test_unzip_not_fatal(self):
     zip = SafeUnzip(self.xpi_path('search.xml'))
     assert not zip.is_valid(fatal=False)