file.py 1.9 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556
  1. import urllib.parse
  2. from flask import request
  3. from flask_restful import marshal_with, reqparse
  4. import services
  5. from controllers.web import api
  6. from controllers.web.error import FileTooLargeError, NoFileUploadedError, TooManyFilesError, UnsupportedFileTypeError
  7. from controllers.web.wraps import WebApiResource
  8. from core.helper import ssrf_proxy
  9. from fields.file_fields import file_fields, remote_file_info_fields
  10. from services.file_service import FileService
  11. class FileApi(WebApiResource):
  12. @marshal_with(file_fields)
  13. def post(self, app_model, end_user):
  14. # get file from request
  15. file = request.files["file"]
  16. parser = reqparse.RequestParser()
  17. parser.add_argument("source", type=str, required=False, location="args")
  18. source = parser.parse_args().get("source")
  19. # check file
  20. if "file" not in request.files:
  21. raise NoFileUploadedError()
  22. if len(request.files) > 1:
  23. raise TooManyFilesError()
  24. try:
  25. upload_file = FileService.upload_file(file=file, user=end_user, source=source)
  26. except services.errors.file.FileTooLargeError as file_too_large_error:
  27. raise FileTooLargeError(file_too_large_error.description)
  28. except services.errors.file.UnsupportedFileTypeError:
  29. raise UnsupportedFileTypeError()
  30. return upload_file, 201
  31. class RemoteFileInfoApi(WebApiResource):
  32. @marshal_with(remote_file_info_fields)
  33. def get(self, url):
  34. decoded_url = urllib.parse.unquote(url)
  35. try:
  36. response = ssrf_proxy.head(decoded_url)
  37. return {
  38. "file_type": response.headers.get("Content-Type", "application/octet-stream"),
  39. "file_length": int(response.headers.get("Content-Length", -1)),
  40. }
  41. except Exception as e:
  42. return {"error": str(e)}, 400
  43. api.add_resource(FileApi, "/files/upload")
  44. api.add_resource(RemoteFileInfoApi, "/remote-files/<path:url>")