def inject_ids(self): """ For packaged webapps, adds a META-INF/ids.json file with a JSON document like the following: {"app_id": "6106d3b3-881a-4ddf-9dec-6b2bf8ff8341", "version_id": 42} """ app = self.version.addon if not (app.type == amo.ADDON_WEBAPP and app.is_packaged): return filename = 'META-INF/ids.json' ids = { 'app_id': app.guid, 'version_id': self.version_id, } zf = SafeUnzip(self.file_path, mode='a') zf.is_valid() # Check if there's already a META-INF/ids.json. try: zf.zip.getinfo(filename) zf.close() return except KeyError: pass # Not found, we need to add it. zf.zip.writestr(filename, json.dumps(ids)) zf.close()
def fetch_icon(webapp, **kw): """Downloads a webapp icon from the location specified in the manifest. Returns False if icon was not able to be retrieved """ log.info(u'[1@None] Fetching icon for webapp %s.' % webapp.name) manifest = webapp.get_manifest_json() if not manifest or not 'icons' 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: 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(webapp.get_latest_file().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.message)) # Set the icon type to empty. webapp.update(icon_type='') return False size_error_message = _('Your icon must be less than %s bytes.') 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
def fetch_icon(webapp, **kw): """Downloads a webapp icon from the location specified in the manifest. Returns False if icon was not able to be retrieved """ log.info(u'[1@None] Fetching icon for webapp %s.' % webapp.name) manifest = webapp.get_manifest_json() if not manifest or not 'icons' 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(webapp.get_latest_file().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
def write_watermarked_addon(self, dest, data): """ Writes the watermarked addon to the destination given the addons install.rdf data. """ directory = os.path.dirname(dest) if not os.path.exists(directory): os.makedirs(directory) shutil.copyfile(self.file_path, dest) outzip = SafeUnzip(dest, mode='w') outzip.is_valid() outzip.zip.writestr('install.rdf', str(data))
def watermark_install_rdf(self, user): """ Reads the install_rdf out of an addon and writes the user information into it. """ inzip = SafeUnzip(self.file_path) inzip.is_valid() try: install = inzip.extract_path("install.rdf") data = RDF(install) data.set(user.email, self.version.addon.get_watermark_hash(user)) except Exception, e: log.error("Could not alter install.rdf in file: %s for %s, %s" % (self.pk, user.pk, e)) raise
def watermark_install_rdf(self, user): """ Reads the install_rdf out of an addon and writes the user information into it. """ inzip = SafeUnzip(self.file_path) inzip.is_valid() try: install = inzip.extract_path('install.rdf') data = RDF(install) data.set(user.email, self.version.addon.get_watermark_hash(user)) except Exception, e: log.error('Could not alter install.rdf in file: %s for %s, %s' % (self.pk, user.pk, e)) raise
def inject_ids(self): """ For packaged webapps, adds a META-INF/ids.json file with a JSON document like the following: {"id": "6106d3b3-881a-4ddf-9dec-6b2bf8ff8341", "version": 42} """ app = self.version.addon if not (app.type == amo.ADDON_WEBAPP and app.is_packaged): return filename = 'META-INF/ids.json' ids = { 'id': app.guid, 'version': self.version_id, } zf = SafeUnzip(self.file_path, mode='a') zf.is_valid() zf.zip.writestr(filename, json.dumps(ids)) zf.close()
def get_localepicker(self): """ For a file that is part of a language pack, extract the chrome/localepicker.properties file and return as a string. """ start = time.time() zip = SafeUnzip(self.file_path) if not zip.is_valid(fatal=False): return '' try: manifest = zip.extract_path('chrome.manifest') except KeyError, e: log.info('No file named: chrome.manifest in file: %s' % self.pk) return ''
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()
def test_is_secure(self): zip = SafeUnzip(self.xpi_path('signed')) zip.is_valid() assert zip.is_signed()
def test_unzip_not_fatal(self): zip = SafeUnzip(get_file('search.xml')) assert not zip.is_valid(fatal=False)
def get_rdf(self, tmp): assert tmp unzip = SafeUnzip(tmp) unzip.is_valid() return RDF(unzip.extract_path('install.rdf'))
def is_signed(self, path): unz = SafeUnzip(path) assert unz.is_valid() assert unz.is_signed()
def test_unzip_not_fatal(self): zip = SafeUnzip(self.xpi_path('search.xml')) assert not zip.is_valid(fatal=False)
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')
def test_not_secure(self): zip = SafeUnzip(self.xpi_path('extension')) zip.is_valid() assert not zip.is_signed()
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")