torrust_index/services/
proxy.rs

1//! Image cache proxy.
2//!
3//! The image cache proxy is a service that allows users to proxy images
4//! through the server.
5//!
6//! Sample URL:
7//!
8//! <http://0.0.0.0:3001/v1/proxy/image/https%3A%2F%2Fupload.wikimedia.org%2Fwikipedia%2Fcommons%2Fthumb%2F2%2F21%2FMandel_zoom_00_mandelbrot_set.jpg%2F1280px-Mandel_zoom_00_mandelbrot_set.jpg>
9use std::sync::Arc;
10
11use bytes::Bytes;
12
13use super::authorization::{self, ACTION};
14use crate::cache::image::manager::{Error, ImageCacheService};
15use crate::models::user::UserId;
16
17pub struct Service {
18    image_cache_service: Arc<ImageCacheService>,
19    authorization_service: Arc<authorization::Service>,
20}
21
22impl Service {
23    #[must_use]
24    pub fn new(image_cache_service: Arc<ImageCacheService>, authorization_service: Arc<authorization::Service>) -> Self {
25        Self {
26            image_cache_service,
27            authorization_service,
28        }
29    }
30
31    /// It gets image by URL and caches it.
32    ///
33    /// # Errors
34    ///
35    /// It returns an error if:
36    ///
37    /// * The image URL is unreachable.
38    /// * The image URL is not an image.
39    /// * The image is too big.
40    /// * The user quota is met.
41    pub async fn get_image_by_url(&self, url: &str, maybe_user_id: Option<UserId>) -> Result<Bytes, Error> {
42        let Some(user_id) = maybe_user_id else {
43            return Err(Error::Unauthenticated);
44        };
45
46        self.authorization_service
47            .authorize(ACTION::GetImageByUrl, maybe_user_id)
48            .await
49            .map_err(|_| Error::Unauthenticated)?;
50
51        self.image_cache_service.get_image_by_url(url, user_id).await
52    }
53}