make compatible with caddy reverse proxy for local https

This commit is contained in:
Johannes Heuel
2023-03-03 19:56:01 +01:00
parent ac27cba766
commit da5d1edaa7
12 changed files with 738 additions and 20 deletions

View File

@@ -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"

View File

@@ -1 +1,2 @@
pub mod photos_api;
pub mod user_api;

View 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 }))
}

View File

@@ -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)