This is Mensatt's image service. It handles uploads of images and serves them.
This section defines the steps an image that is uploaded to this service undergoes from upload to serving.
-
Upload: Typically images are uploaded to this service during creation of reviews in the frontend. Once uploaded, images are rotated, stripped of their EXIF metadata and saved as AVIF in
PENDING_PATH
.Note: Uploading images before a review is submitted is done to speed up the review submission, as the image is likely to be uploaded by the time the user enters their username and/or review text.
Also, images that stay in the pending folder for longer than an hour will be deleted regularly. -
Submission: Once a review is submitted, the image is moved from
PENDING_PATH
toUNAPPROVED_PATH
. -
Approval: Images need to be approved by an administrator. Once an image is approved it is moved fom
UNAPPROVED_PATH
toORIGINAL_PATH
. -
Serving requests: The first time an image (with a specific size and quality) is requested, it gets generated from the image in
ORIGINAL_PATH
and cached toCACHE_PATH
.
Every following request (with the same size and quality) gets served fromCACHE_PATH
.
The paths mentioned here are constant and defined in src/constants.rs
.
Name | Method | Description | Authorization required? |
---|---|---|---|
/upload |
POST | Upload an image. Step 1 of Image Flow. |
no |
/submit/:id |
POST | Submit image with id . Step 2 of Image Flow. |
yes |
/approve/:id |
POST | Approve image with id . Step 3 of Image Flow. |
yes |
/image/:id |
GET | Get image with id . Step 4 of Image Flow. |
no¹ |
/image/:id |
DELETE | Delete image with id . Also deletes it from cache. |
yes |
/unapprove/:id |
POST | Reverse operation of approving. Also deletes image from cache. |
yes |
/rotate |
POST | Rotates an existing image. Requires id and angle parameter. |
yes |
Authorization is done by providing this header in a request:
Authorization: Bearer api_key_goes_here
¹: Authorization is required if you want to view unapproved images
-
Clone this repo on the target machine
-
Build and start the service in the background with
docker compose up -d
The service will be listening on the address defined by
LISTEN_ADDR
insrc/constants.rs
If needed you can manually (re)build the image with
docker compose build
-
Make sure to have
cargo-watch
installed by runningcargo install cargo-watch
Note:
cargo-watch
ist not a requirement for building/running this project, but we found it makes development easier by providing auto reload when a file is changed. For more details on what it does see here. -
Make sure you have
API_KEY_HASH
defined in.env
(see.env.dist
for an example) and source it withexport $(grep -Ev '^\s*(#|;|/|$)' .env | xargs)
Note: The regex ensures empty lines and comments are ignored.
If you want to use any other characters for comments in.env
, make sure to add them to the reqex. -
You can then build and run the current version of the code with
RUST_LOG=mensatt_img=debug cargo watch -w src -x run
where
RUST_LOG=mensatt_img=debug
sets the loglevel formensatt_img
package todebug
If you do not want to (or cannot) use
cargo-watch
, you can also simply runRUST_LOG=mensatt_img=debug cargo run
Configuration is done via a YAML-File. The default path is config.yml
in the current working directory (of the executable).
If desired, the configuration path can be overwritten via the CONFIG_PATH
environment variable.
A sample configuration is provided as config.dist.yml.
Name | Description | Default | Required? |
---|---|---|---|
API_KEY_HASHES |
Argon2id hash of the API key to be used. Can be generated here. Make sure to use Encoded Form. |
- | yes |
CORS_ALLOWED_ORIGINS |
List of allowed CORS origins | - | yes |
CORS_ALLOWED_METHODS |
List of allowed CORS methods | GET |
no |
Configuration options from the configuration file can be overwritten via environment variables.
Note that overriding list values (arrays), works using ';' as the separator. For example, API_KEY_HASHES='HASH_1;HASH:2'
.