make compatible with caddy reverse proxy for local https
This commit is contained in:
@@ -21,6 +21,7 @@ serde = { version = "1.0", features = ["derive"] }
|
||||
serde_json = "1.0"
|
||||
common = { path = "../common" }
|
||||
uuid = { version = "1", features = ["v4", "serde"] }
|
||||
rust-s3 = "0.32.3"
|
||||
|
||||
[dependencies.mongodb]
|
||||
version = "2.2.0"
|
||||
|
||||
@@ -1 +1,2 @@
|
||||
pub mod photos_api;
|
||||
pub mod user_api;
|
||||
|
||||
57
backend/src/api/photos_api.rs
Normal file
57
backend/src/api/photos_api.rs
Normal file
@@ -0,0 +1,57 @@
|
||||
use actix_session::Session;
|
||||
use actix_web::{
|
||||
post,
|
||||
web::{Data, Json},
|
||||
HttpResponse,
|
||||
};
|
||||
use s3::bucket::Bucket;
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
use crate::repository::mongodb_repo::MongoRepo;
|
||||
|
||||
#[derive(Debug, Deserialize, Serialize)]
|
||||
pub struct PhotosWrapper {
|
||||
photos: Vec<String>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Deserialize, Serialize)]
|
||||
pub struct PhotosUrlsWrapper {
|
||||
photos: Vec<(String, String)>,
|
||||
}
|
||||
|
||||
// Return an opaque 500 while preserving the error's root cause for logging.
|
||||
fn e500<T>(e: T) -> actix_web::Error
|
||||
where
|
||||
T: std::fmt::Debug + std::fmt::Display + 'static,
|
||||
{
|
||||
actix_web::error::ErrorInternalServerError(e)
|
||||
}
|
||||
|
||||
#[post("/api/photos/upload")]
|
||||
pub async fn get_presigned_post_urls(
|
||||
db: Data<MongoRepo>,
|
||||
bucket: Data<Bucket>,
|
||||
request: Json<PhotosWrapper>,
|
||||
session: Session,
|
||||
) -> Result<HttpResponse, actix_web::Error> {
|
||||
let Some(user_id) = session.get::<String>("user_id").map_err(e500)? else {
|
||||
return Ok(HttpResponse::Unauthorized().body("Not authorized"));
|
||||
};
|
||||
|
||||
let Ok(_) = db.get_user(&user_id).await else {
|
||||
return Ok(HttpResponse::Unauthorized().body("Not authorized"));
|
||||
};
|
||||
|
||||
let photos: Vec<(String, String)> = request
|
||||
.photos
|
||||
.iter()
|
||||
.map(|x| {
|
||||
(
|
||||
x.clone(),
|
||||
bucket.presign_put(format!("/{x}"), 86400, None).unwrap(),
|
||||
)
|
||||
})
|
||||
.collect();
|
||||
|
||||
Ok(HttpResponse::Ok().json(PhotosUrlsWrapper { photos }))
|
||||
}
|
||||
@@ -2,10 +2,15 @@ mod api;
|
||||
mod models;
|
||||
mod repository;
|
||||
|
||||
use api::photos_api::get_presigned_post_urls;
|
||||
use api::user_api::{create_user, delete_user, get_user, is_logged_in, login, update_user};
|
||||
use common::OutputPicture;
|
||||
use repository::mongodb_repo::MongoRepo;
|
||||
|
||||
use s3::bucket::Bucket;
|
||||
use s3::creds::Credentials;
|
||||
use s3::region::Region;
|
||||
|
||||
use actix_cors::Cors;
|
||||
use actix_session::{
|
||||
config::CookieContentSecurity, storage::CookieSessionStore, SessionMiddleware,
|
||||
@@ -63,19 +68,44 @@ async fn main() -> std::io::Result<()> {
|
||||
log::info!("starting HTTP server at http://{}:{}", host, port);
|
||||
|
||||
let db = MongoRepo::init().await;
|
||||
let db_data = Data::new(db);
|
||||
let db = Data::new(db);
|
||||
|
||||
let bucket_name = "photos";
|
||||
let region = Region::Custom {
|
||||
region: "minio".parse().unwrap(),
|
||||
endpoint: "http://127.0.0.1:9000".to_owned(),
|
||||
};
|
||||
let credentials = Credentials {
|
||||
access_key: Some("OPyibtgH1RISFIPs".to_owned()),
|
||||
secret_key: Some("LesNB0p5oZEcJy3rACHEloityS1Y6nYc".to_owned()),
|
||||
security_token: None,
|
||||
session_token: None,
|
||||
expiration: None,
|
||||
};
|
||||
let bucket = if let Ok(mut bucket) = Bucket::new(bucket_name, region, credentials) {
|
||||
bucket.set_path_style();
|
||||
bucket
|
||||
} else {
|
||||
panic!("Could not create bucket");
|
||||
};
|
||||
let bucket = Data::new(bucket);
|
||||
|
||||
HttpServer::new(move || {
|
||||
let cors = Cors::default()
|
||||
.allowed_origin("http://localhost:8080")
|
||||
.allowed_origin_fn(|origin, _req_head| origin.as_bytes().starts_with(b"localhost"))
|
||||
.allowed_origin_fn(|origin, _req_head| {
|
||||
origin
|
||||
.as_bytes()
|
||||
.windows("localhost".len())
|
||||
.filter(|&x| x == "localhost".as_bytes())
|
||||
.count()
|
||||
> 0
|
||||
})
|
||||
.allowed_methods(vec!["GET", "POST"])
|
||||
.allowed_headers(vec![http::header::AUTHORIZATION, http::header::ACCEPT])
|
||||
.allowed_header(http::header::CONTENT_TYPE)
|
||||
.max_age(3600);
|
||||
|
||||
App::new()
|
||||
// .app_data(web::Data::new(pool.clone()))
|
||||
.wrap(cors)
|
||||
.wrap(
|
||||
SessionMiddleware::builder(
|
||||
@@ -85,10 +115,11 @@ async fn main() -> std::io::Result<()> {
|
||||
.cookie_content_security(CookieContentSecurity::Private)
|
||||
.build(),
|
||||
)
|
||||
.app_data(db_data.clone())
|
||||
.app_data(db.clone())
|
||||
.app_data(bucket.clone())
|
||||
.wrap(middleware::Logger::default())
|
||||
.service(get_presigned_post_urls)
|
||||
.service(get_pictures)
|
||||
// .service(fs::Files::new("/api/pictures/", "./pictures/"))
|
||||
.service(is_logged_in)
|
||||
.service(login)
|
||||
.service(create_user)
|
||||
|
||||
Reference in New Issue
Block a user