diff --git a/.gitignore b/.gitignore index 38a8564..6234c03 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,4 @@ /target database/target *.db +.env diff --git a/Cargo.lock b/Cargo.lock index d9283ec..7e376ff 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -34,6 +34,27 @@ dependencies = [ "trust-dns-resolver", ] +[[package]] +name = "actix-files" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "193b22cb1f7b4ff12a4eb2415d6d19e47e44ea93e05930b30d05375ea29d3529" +dependencies = [ + "actix-http", + "actix-service", + "actix-web", + "bitflags", + "bytes", + "derive_more", + "futures-core", + "futures-util", + "log", + "mime", + "mime_guess", + "percent-encoding", + "v_htmlescape", +] + [[package]] name = "actix-http" version = "1.0.1" @@ -809,7 +830,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ac746a5f3bbfdadd6106868134545e684693d54d9d44f6e9588a7d54af0bf980" dependencies = [ "typenum", - "version_check", + "version_check 0.9.2", ] [[package]] @@ -919,6 +940,7 @@ dependencies = [ name = "image-api" version = "0.1.0" dependencies = [ + "actix-files", "actix-rt", "actix-web", "bcrypt", @@ -1098,6 +1120,16 @@ version = "0.3.16" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2a60c7ce501c71e03a9c9c0d35b861413ae925bd979cc7a4e30d060069aaac8d" +[[package]] +name = "mime_guess" +version = "2.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2684d4c2e97d99848d30b324b00c8fcc7e5c897b7cbb5819b09e7c90e8baf212" +dependencies = [ + "mime", + "unicase", +] + [[package]] name = "miniz_oxide" version = "0.3.7" @@ -1169,6 +1201,16 @@ dependencies = [ "winapi 0.3.9", ] +[[package]] +name = "nom" +version = "4.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2ad2a91a8e869eeb30b9cb3119ae87773a8f4ae617f41b1eb9c154b2905f7bd6" +dependencies = [ + "memchr", + "version_check 0.1.5", +] + [[package]] name = "num-bigint" version = "0.2.6" @@ -1754,6 +1796,15 @@ version = "1.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "373c8a200f9e67a0c95e62a4f52fbf80c23b4381c05a17845531982fa99e6b33" +[[package]] +name = "unicase" +version = "2.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "50f37be617794602aabbeee0be4f259dc1778fabe05e2d67ee8f79326d5cb4f6" +dependencies = [ + "version_check 0.9.2", +] + [[package]] name = "unicode-bidi" version = "0.3.4" @@ -1801,12 +1852,49 @@ dependencies = [ "percent-encoding", ] +[[package]] +name = "v_escape" +version = "0.7.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "660b101c07b5d0863deb9e7fb3138777e858d6d2a79f9e6049a27d1cc77c6da6" +dependencies = [ + "v_escape_derive", +] + +[[package]] +name = "v_escape_derive" +version = "0.5.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c2ca2a14bc3fc5b64d188b087a7d3a927df87b152e941ccfbc66672e20c467ae" +dependencies = [ + "nom", + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "v_htmlescape" +version = "0.4.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e33e939c0d8cf047514fb6ba7d5aac78bc56677a6938b2ee67000b91f2e97e41" +dependencies = [ + "cfg-if", + "v_escape", +] + [[package]] name = "vcpkg" version = "0.2.10" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6454029bf181f092ad1b853286f23e2c507d8e8194d01d92da4a55c274a5508c" +[[package]] +name = "version_check" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "914b1a6776c4c929a602fafd8bc742e06365d4bcbe48c30f9cca5824f70dc9dd" + [[package]] name = "version_check" version = "0.9.2" diff --git a/Cargo.toml b/Cargo.toml index 19c5a76..6e1bfab 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -9,6 +9,7 @@ edition = "2018" [dependencies] actix-web = "2.0" actix-rt = "1.0" +actix-files = "0.2.2" futures = "0.3.5" jsonwebtoken = "7.2.0" serde = "1.0" diff --git a/src/files.rs b/src/files.rs index cfdf444..b217140 100644 --- a/src/files.rs +++ b/src/files.rs @@ -9,7 +9,7 @@ pub fn list_files(dir: PathBuf) -> io::Result> { .filter(|entry| is_image_or_video(&entry.path()) || entry.file_type().unwrap().is_dir()) .map(|entry| entry.path()) .map(|path: PathBuf| { - let relative = path.strip_prefix(std::env::current_dir().unwrap()).unwrap(); + let relative = path.strip_prefix(dotenv::var("BASE_PATH").unwrap()).unwrap(); relative.to_path_buf() }) .collect::>(); diff --git a/src/main.rs b/src/main.rs index 428ad0e..057269f 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,7 +1,8 @@ #[macro_use] extern crate diesel; -use actix_web::web::{HttpResponse, Json}; +use actix_files::NamedFile; +use actix_web::web::{HttpResponse, HttpRequest, Json}; use actix_web::{get, post, App, HttpServer, Responder}; use chrono::{Duration, Utc}; use data::{LoginRequest, ThumbnailRequest}; @@ -55,24 +56,45 @@ async fn list_photos(_claims: Claims, req: Json) -> impl Respo println!("{}", req.path); let path = &req.path; + if let Some(path) = is_valid_path(path) { + let files = list_files(path); + HttpResponse::Ok().json(files.unwrap_or_default()) + } else { + HttpResponse::BadRequest().finish() + } +} + +fn is_valid_path(path: &str) -> Option { match path { - path if path.contains("..") => HttpResponse::BadRequest().finish(), + path if path.contains("..") => None, path => { let path = PathBuf::from(path); if path.is_relative() { - let mut full_path = std::env::current_dir().unwrap(); + let mut full_path = PathBuf::from(dotenv::var("BASE_PATH").unwrap()); full_path.push(path); - let files = list_files(full_path); - HttpResponse::Ok().json(files.unwrap_or_default()) + Some(full_path) } else { - HttpResponse::BadRequest().finish() + None } } } } +#[get("/image")] +async fn image(_claims: Claims, request: HttpRequest, req: Json) -> impl Responder { + if let Some(path) = is_valid_path(&req.path) { + if let Ok(file) = NamedFile::open(path) { + file.into_response(&request).unwrap() + } else { + HttpResponse::NotFound().finish() + } + } else { + HttpResponse::NotFound().finish() + } +} + #[actix_rt::main] async fn main() -> std::io::Result<()> { HttpServer::new(|| { @@ -80,6 +102,7 @@ async fn main() -> std::io::Result<()> { .service(login) .service(list_photos) .service(register) + .service(image) }) .bind("127.0.0.1:8088")? .run()