def post(self, identifier): """ --- summary: Generate file download token description: | Returns download token for given file. security: - bearerAuth: [] tags: - file parameters: - in: path name: identifier description: Requested file identifier (SHA256/MD5/SHA1/SHA512) schema: type: string responses: 200: description: File download token, valid for 60 seconds content: application/json: schema: FileDownloadTokenResponseSchema 404: description: | When file doesn't exist, object is not a file or user doesn't have access to this object. """ file = File.access(identifier) if file is None: raise NotFound("Object not found") download_token = file.generate_download_token() schema = FileDownloadTokenResponseSchema() return schema.dump({"token": download_token.decode()})
def post(self, identifier): """ --- summary: Get file download URL description: | Returns download URL for given file. security: - bearerAuth: [] tags: - download parameters: - in: path name: identifier description: Requested file identifier (SHA256/MD5/SHA1/SHA512) schema: type: string responses: 200: description: Absolute download URL for the sample, valid for 60 seconds content: application/json: schema: DownloadURLResponseSchema 404: description: When file doesn't exist, object is not a file or user doesn't have access to this object. """ file = File.access(identifier) if file is None: raise NotFound("Object not found") download_token = file.generate_download_token() schema = DownloadURLResponseSchema() url = api.relative_url_for(DownloadResource, access_token=download_token.decode()) return schema.dump({"url": url})
def post(self, remote_name, identifier): """ --- summary: Push file from local to remote instance description: | Push file from the local instance to the remote instance security: - bearerAuth: [] tags: - remotes parameters: - in: path name: remote_name description: Name of remote instance schema: type: string - in: path name: identifier description: Object identifier (SHA256/SHA512/SHA1/MD5) schema: type: string requestBody: required: false description: Additional options for object push content: application/json: schema: RemoteOptionsRequestSchema responses: 200: description: Information about pushed fie 404: description: | When the name of the remote instance is not figured in the application config or object doesn't exist """ db_object = File.access(identifier) if db_object is None: raise NotFound("Object not found") remote = RemoteAPI(remote_name) options = loads_schema(request.get_data(as_text=True), RemoteOptionsRequestSchema()) response = remote.request( "POST", "file", files={ "file": (db_object.file_name, db_object.open()), "options": (None, json.dumps(options)), }, ).json() logger.info( f"{db_object.type} pushed remote", extra={ "dhash": db_object.dhash, "remote_name": remote_name }, ) return response
def get(self, identifier): """ --- summary: Download file description: | Returns file contents. Optionally accepts file download token to get the file via direct link (without Authorization header) security: - bearerAuth: [] tags: - file parameters: - in: path name: identifier schema: type: string description: File identifier (SHA256/SHA512/SHA1/MD5) - in: query name: token schema: type: string description: | File download token for direct link purpose required: false responses: 200: description: File contents content: application/octet-stream: schema: type: string format: binary 403: description: | When file download token is no longer valid or was generated for different object 404: description: | When file doesn't exist, object is not a file or user doesn't have access to this object. """ access_token = request.args.get("token") if access_token: file_obj = File.get_by_download_token(access_token) if not file_obj: raise Forbidden( "Download token expired, please re-request download.") if not (file_obj.sha1 == identifier or file_obj.sha256 == identifier or file_obj.sha512 == identifier or file_obj.md5 == identifier): raise Forbidden( "Download token doesn't apply to the chosen object. " "Please re-request download.") else: if not g.auth_user: raise Unauthorized("Not authenticated.") file_obj = File.access(identifier) if file_obj is None: raise NotFound("Object not found") return Response( file_obj.iterate(), content_type="application/octet-stream", headers={ "Content-disposition": f"attachment; filename={file_obj.sha256}" }, )
def post(self, identifier: str) -> Tuple[Dict[str, Any], int]: db_file = File.access(identifier) if db_file is None: raise NotFound("Object not found or is not a file") root_uid = send_file_to_karton(db_file) return {"uid": root_uid}, 200