def sign_file(self): """Sign the original file (`file_path`), then move signed extension file to the signed path (`signed_file_path`) on public storage. The original file remains on private storage. Return the signed file size.""" if not self.extension.uuid: raise SigningError('Need uuid to be set to sign') if not self.pk: raise SigningError('Need version pk to be set to sign') ids = json.dumps({ # 'id' needs to be an unique identifier not shared with anything # else (other extensions, langpacks, webapps...), but should not # change when there is an update. 'id': self.extension.uuid, # 'version' should be an integer and should be monotonically # increasing. 'version': self.pk }) with statsd.timer('extensions.sign'): try: # This will read the file from self.file_path, generate a # signature and write the signed file to self.signed_file_path. sign_app(private_storage.open(self.file_path), self.signed_file_path, ids) except SigningError: log.info('[ExtensionVersion:%s] Signing failed' % self.pk) self.remove_public_signed_file() # Clean up. raise return public_storage.size(self.signed_file_path)
def sign_file(self): """Sign the original file (`file_path`), then move signed extension file to the signed path (`signed_file_path`) on public storage. The original file remains on private storage. Return the signed file size.""" if not self.extension.uuid: raise SigningError('Need uuid to be set to sign') if not self.pk: raise SigningError('Need version pk to be set to sign') if self.extension.is_blocked(): raise SigningError('Trying to signed a blocked extension') ids = json.dumps({ # 'id' needs to be an unique identifier not shared with anything # else (other extensions, langpacks, webapps...), but should not # change when there is an update. 'id': self.extension.uuid, # 'version' should be an integer and should be monotonically # increasing. 'version': self.pk }) with statsd.timer('extensions.sign'): try: # This will read the file from self.file_path, generate a # signature and write the signed file to self.signed_file_path. sign_app(private_storage.open(self.file_path), self.signed_file_path, ids) except SigningError: log.info('[ExtensionVersion:%s] Signing failed' % self.pk) self.remove_public_signed_file() # Clean up. raise return public_storage.size(self.signed_file_path)
def get_cached_minifest(app_or_langpack, force=False): """ Create a "mini" manifest for a packaged app or langpack and cache it (Call with `force=True` to bypass existing cache). Note that platform expects name/developer/locales to match the data from the real manifest in the package, so it needs to be read from the zip file. Returns a tuple with the minifest contents and the corresponding etag. """ cache_prefix = 1 # Change this if you are modifying what enters the cache. cache_key = "{0}:{1}:{2}:manifest".format(cache_prefix, app_or_langpack._meta.model_name, app_or_langpack.pk) if not force: cached_data = cache.get(cache_key) if cached_data: return cached_data sign_if_packaged = getattr(app_or_langpack, "sign_if_packaged", None) if sign_if_packaged is None: # Langpacks are already signed when we generate the manifest and have # a file_path attribute. signed_file_path = app_or_langpack.file_path else: # sign_if_packaged() will return the signed path. But to call it, we # need a current version. If we don't have one, return an empty # manifest, bypassing caching so that when a version does become # available it can get picked up correctly. if not app_or_langpack.current_version: return "{}" signed_file_path = sign_if_packaged() manifest = app_or_langpack.get_manifest_json() package_path = app_or_langpack.get_package_path() data = {"size": public_storage.size(signed_file_path), "package_path": package_path} if hasattr(app_or_langpack, "current_version"): data["version"] = app_or_langpack.current_version.version data["release_notes"] = app_or_langpack.current_version.releasenotes file_hash = app_or_langpack.current_version.all_files[0].hash else: # LangPacks have no version model, the version number is an attribute # and they don't have release notes. data["version"] = app_or_langpack.version # File hash is not stored for langpacks, but file_version changes with # every new upload so we can use that instead. file_hash = unicode(app_or_langpack.file_version) for key in ["developer", "icons", "locales", "name"]: if key in manifest: data[key] = manifest[key] data = json.dumps(data, cls=JSONEncoder) etag = hashlib.sha256() etag.update(data) if file_hash: etag.update(file_hash) rval = (data, etag.hexdigest()) cache.set(cache_key, rval, None) return rval
def get_cached_minifest(app_or_langpack, force=False): """ Create a "mini" manifest for a packaged app or langpack and cache it (Call with `force=True` to bypass existing cache). Note that platform expects name/developer/locales to match the data from the real manifest in the package, so it needs to be read from the zip file. Returns a tuple with the minifest contents and the corresponding etag. """ cache_prefix = 1 # Change this if you are modifying what enters the cache. cache_key = '{0}:{1}:{2}:manifest'.format(cache_prefix, app_or_langpack._meta.model_name, app_or_langpack.pk) if not force: cached_data = cache.get(cache_key) if cached_data: return cached_data sign_if_packaged = getattr(app_or_langpack, 'sign_if_packaged', None) if sign_if_packaged is None: # Langpacks are already signed when we generate the manifest and have # a file_path attribute. signed_file_path = app_or_langpack.file_path else: # sign_if_packaged() will return the signed path. But to call it, we # need a current version. If we don't have one, return an empty # manifest, bypassing caching so that when a version does become # available it can get picked up correctly. if not app_or_langpack.current_version: return '{}' signed_file_path = sign_if_packaged() manifest = app_or_langpack.get_manifest_json() package_path = app_or_langpack.get_package_path() data = { 'size': public_storage.size(signed_file_path), 'package_path': package_path, } if hasattr(app_or_langpack, 'current_version'): data['version'] = app_or_langpack.current_version.version data['release_notes'] = app_or_langpack.current_version.releasenotes file_hash = app_or_langpack.current_version.all_files[0].hash else: # LangPacks have no version model, the version number is an attribute # and they don't have release notes. data['version'] = app_or_langpack.version # File hash is not stored for langpacks, but file_version changes with # every new upload so we can use that instead. file_hash = unicode(app_or_langpack.file_version) for key in ['developer', 'icons', 'locales', 'name']: if key in manifest: data[key] = manifest[key] data = json.dumps(data, cls=JSONEncoder) etag = hashlib.sha256() etag.update(data) if file_hash: etag.update(file_hash) rval = (data, etag.hexdigest()) cache.set(cache_key, rval, None) return rval