feat: add routes to upload and download binaries

Arnaud Vergnet requested to merge topic/default/binary-upload into branch/default

This MR adds support for managing binaries. It allows the user to:

  • get the base 64 representation of a file in RQL requests. Note that this adds a ~30% binary size overhead due to the encoding.
  • directly download the file using the route /binary?eid=<EID>&attribute=<ATTRIBUTE>. While it requires a dedicated request, it does not add any overhead and is more suited for large files.
  • upload binaries using the /rql in multipart/form-data

OpenAPI limitations

Due to a bug in openapi-core, we were not able to make OpenApi validation work on the multipart form data using from the specification file (see code comments).

Instead, we manually decode the multipart data and run the JSON validation on the decoded data. The drawback is that the parameters format is not available from the OpenAPI spec (but is described in the description).

Security

The route using multipart/form-data is vulnerable to CSRF attacks so it needs proper protection. As we don't want to restrict usage of the API to HTML forms, we can't use CSRF Tokens. We use instead CSRF custom headers:

This defense relies on the browser's same-origin policy (SOP) restriction that only JavaScript can be used to add a custom header, and only within its origin. By default, browsers do not allow JavaScript to make cross origin requests with custom headers. Only JavaScript that you serve from your origin can add these headers

The MR thus requires the X-Client-Type: <YOUR_CLIENT> header parameter (where <YOUR_CLIENT> can be anything) to be present on all routes, JSON and multipart alike. Even if JSON POST and GET routes do not need it, I felt it was easier to understand if every route requires the custom header.

Edited by Arnaud Vergnet

Merge request reports