Esempio n. 1
0
    def get_file(self, hash_id: str) -> Optional[bytes]:
        """
        Retrieve a file from the fileserver identified with the given id. The convention is to use the sha1sum of the
        content to identify it.

        :param hash_id: The id of the content/file to retrieve from the server.
        :return: The content in the form of a bytestring or none is the content does not exist.
        """
        def call() -> typing.Awaitable[Result]:
            return self.get_client().get_file(hash_id)

        result = self.run_sync(call)
        if result.code == 404:
            return None
        elif result.result and result.code == 200:
            file_contents = base64.b64decode(result.result["content"])
            actual_hash_of_file = hash_file(file_contents)
            if hash_id != actual_hash_of_file:
                raise Exception(
                    f"File hash verification failed, expected: {hash_id} but got {actual_hash_of_file}"
                )
            return file_contents
        else:
            raise Exception("An error occurred while retrieving file %s" %
                            hash_id)
Esempio n. 2
0
    async def upload_code(self, env: data.Environment, code_id: int,
                          resource: str, sources: JsonType) -> Apireturn:
        code = await data.Code.get_version(environment=env.id,
                                           version=code_id,
                                           resource=resource)
        if code is not None:
            raise ServerError(
                "Code for this version has already been uploaded.")

        hasherrors = any((k != hash_file(content[2].encode())
                          for k, content in sources.items()))
        if hasherrors:
            return 400, {
                "message": "Hashes in source map do not match to source_code"
            }

        for file_hash in self.file_slice.stat_file_internal(sources.keys()):
            self.file_slice.upload_file_internal(
                file_hash, sources[file_hash][2].encode())

        compact = {
            code_hash: (file_name, module, req)
            for code_hash, (file_name, module, _, req) in sources.items()
        }

        code = data.Code(environment=env.id,
                         version=code_id,
                         resource=resource,
                         source_refs=compact)
        await code.insert()

        return 200
Esempio n. 3
0
    def upload_file_internal(self, file_hash: str, content: bytes) -> None:
        file_name = os.path.join(self.server_slice._server_storage["files"],
                                 file_hash)

        if os.path.exists(file_name):
            raise ServerError("A file with this id already exists.")

        if hash_file(content) != file_hash:
            raise BadRequest("The hash does not match the content")

        with open(file_name, "wb+") as fd:
            fd.write(content)
Esempio n. 4
0
    def upload_file(self, content: Union[str, bytes]) -> str:
        """
        Upload a file to the configuration server. This operation is not
        executed in the transaction.
        """
        bcontent: bytes

        if not isinstance(content, bytes):
            bcontent = content.encode("utf-8")
        else:
            bcontent = content

        hash_id = hash_file(bcontent)
        self._file_store[hash_id] = bcontent

        return hash_id
Esempio n. 5
0
    def get_file_internal(self, file_hash: str) -> bytes:
        """get_file, but on return code 200, content is not encoded """

        file_name = os.path.join(self.server_slice._server_storage["files"],
                                 file_hash)

        if not os.path.exists(file_name):
            raise NotFound()

        with open(file_name, "rb") as fd:
            content = fd.read()
            actualhash = hash_file(content)
            if actualhash == file_hash:
                return content

            # handle corrupt file
            if opt.server_delete_currupt_files.get():
                LOGGER.error(
                    "File corrupt, expected hash %s but found %s at %s, Deleting file",
                    file_hash, actualhash, file_name)
                try:
                    os.remove(file_name)
                except OSError:
                    LOGGER.exception("Failed to delete file %s", file_name)
                    raise ServerError(
                        f"File corrupt, expected hash {file_hash} but found {actualhash}. Failed to delete file, please "
                        "contact the server administrator")

                raise ServerError(
                    f"File corrupt, expected hash {file_hash} but found {actualhash}. "
                    "Deleting file, please re-upload the corrupt file.")
            else:
                LOGGER.error(
                    "File corrupt, expected hash %s but found %s at %s",
                    file_hash, actualhash, file_name)
                raise ServerError(
                    f"File corrupt, expected hash {file_hash} but found {actualhash}, please contact the server administrator"
                )
Esempio n. 6
0
def make_source(collector, filename, module, source, req):
    myhash = hash_file(source.encode())
    collector[myhash] = [filename, module, source, req]
    return collector