Update dependencies, disable registration and improve path handling
This commit is contained in:
535
Cargo.lock
generated
535
Cargo.lock
generated
File diff suppressed because it is too large
Load Diff
13
Cargo.toml
13
Cargo.toml
@@ -7,15 +7,16 @@ edition = "2018"
|
|||||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
actix-web = "3.0"
|
actix-web = "3"
|
||||||
actix-rt = "1.0"
|
actix-rt = "1"
|
||||||
actix-files = "0.3.0"
|
actix-files = "0.4"
|
||||||
actix-multipart = "0.3.0"
|
actix-multipart = "0.3.0"
|
||||||
|
actix-cors="0.5"
|
||||||
futures = "0.3.5"
|
futures = "0.3.5"
|
||||||
jsonwebtoken = "7.2.0"
|
jsonwebtoken = "7.2.0"
|
||||||
serde = "1.0"
|
serde = "1"
|
||||||
serde_json = "1.0"
|
serde_json = "1"
|
||||||
diesel = { version = "1.4.4", features = ["sqlite"] }
|
diesel = { version = "1.4.5", features = ["sqlite"] }
|
||||||
hmac = "0.7.1"
|
hmac = "0.7.1"
|
||||||
sha2 = "0.8.2"
|
sha2 = "0.8.2"
|
||||||
chrono = "0.4.11"
|
chrono = "0.4.11"
|
||||||
|
|||||||
@@ -1,10 +1,11 @@
|
|||||||
use actix_web::error::ErrorUnauthorized;
|
|
||||||
use actix_web::{dev, http::header, Error, FromRequest, HttpRequest};
|
|
||||||
use futures::future::{err, ok, Ready};
|
|
||||||
use jsonwebtoken::{decode, Algorithm, DecodingKey, Validation};
|
|
||||||
use serde::{Deserialize, Serialize};
|
|
||||||
use std::str::FromStr;
|
use std::str::FromStr;
|
||||||
|
|
||||||
|
use actix_web::{dev, Error, FromRequest, http::header, HttpRequest};
|
||||||
|
use actix_web::error::ErrorUnauthorized;
|
||||||
|
use futures::future::{err, ok, Ready};
|
||||||
|
use jsonwebtoken::{Algorithm, decode, DecodingKey, Validation};
|
||||||
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
#[derive(Serialize)]
|
#[derive(Serialize)]
|
||||||
pub struct Token<'a> {
|
pub struct Token<'a> {
|
||||||
pub token: &'a str,
|
pub token: &'a str,
|
||||||
@@ -17,7 +18,7 @@ pub struct Claims {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn secret_key() -> String {
|
pub fn secret_key() -> String {
|
||||||
dotenv::var("SECRET_KEY").unwrap()
|
dotenv::var("SECRET_KEY").expect("SECRET_KEY env not set!")
|
||||||
}
|
}
|
||||||
|
|
||||||
impl FromStr for Claims {
|
impl FromStr for Claims {
|
||||||
|
|||||||
43
src/files.rs
43
src/files.rs
@@ -1,9 +1,11 @@
|
|||||||
use path_absolutize::*;
|
|
||||||
use std::ffi::OsStr;
|
use std::ffi::OsStr;
|
||||||
use std::fs::read_dir;
|
use std::fs::read_dir;
|
||||||
use std::io;
|
use std::io;
|
||||||
|
use std::io::Error;
|
||||||
use std::path::{Path, PathBuf};
|
use std::path::{Path, PathBuf};
|
||||||
|
|
||||||
|
use path_absolutize::*;
|
||||||
|
|
||||||
pub fn list_files(dir: PathBuf) -> io::Result<Vec<PathBuf>> {
|
pub fn list_files(dir: PathBuf) -> io::Result<Vec<PathBuf>> {
|
||||||
let files = read_dir(dir)?
|
let files = read_dir(dir)?
|
||||||
.map(|res| res.unwrap())
|
.map(|res| res.unwrap())
|
||||||
@@ -43,13 +45,20 @@ pub fn is_valid_path(path: &str) -> Option<PathBuf> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn is_valid_full_path(base: &Path, path: &str) -> Option<PathBuf> {
|
fn is_valid_full_path(base: &Path, path: &str) -> Option<PathBuf> {
|
||||||
let path = PathBuf::from(path);
|
let mut path = PathBuf::from(path);
|
||||||
if path.is_relative() {
|
if path.is_relative() {
|
||||||
let mut full_path = PathBuf::from(base);
|
let mut full_path = PathBuf::from(base);
|
||||||
full_path.push(&path);
|
full_path.push(&path);
|
||||||
full_path
|
is_path_above_base_dir(base, &mut full_path).ok()
|
||||||
.absolutize()
|
} else if let Ok(path) = is_path_above_base_dir(base, &mut path) {
|
||||||
.and_then(|p| {
|
Some(path)
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn is_path_above_base_dir(base: &Path, full_path: &mut PathBuf) -> Result<PathBuf, Error> {
|
||||||
|
full_path.absolutize().and_then(|p| {
|
||||||
if p.starts_with(base) {
|
if p.starts_with(base) {
|
||||||
Ok(p.into_owned())
|
Ok(p.into_owned())
|
||||||
} else {
|
} else {
|
||||||
@@ -59,28 +68,14 @@ fn is_valid_full_path(base: &Path, path: &str) -> Option<PathBuf> {
|
|||||||
))
|
))
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.ok()
|
|
||||||
} else if let Ok(path) = path.absolutize().and_then(|path| {
|
|
||||||
if path.starts_with(base) {
|
|
||||||
Ok(path.into_owned())
|
|
||||||
} else {
|
|
||||||
Err(io::Error::new(
|
|
||||||
io::ErrorKind::Other,
|
|
||||||
"Path below base directory",
|
|
||||||
))
|
|
||||||
}
|
|
||||||
}) {
|
|
||||||
Some(path)
|
|
||||||
} else {
|
|
||||||
None
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use super::*;
|
|
||||||
use std::env;
|
use std::env;
|
||||||
use std::fs::{create_dir_all, File};
|
use std::fs::File;
|
||||||
|
|
||||||
|
use super::*;
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn directory_traversal_test() {
|
fn directory_traversal_test() {
|
||||||
@@ -104,8 +99,6 @@ mod tests {
|
|||||||
let path = "relative/path/test.png";
|
let path = "relative/path/test.png";
|
||||||
let mut test_file = PathBuf::from(&base);
|
let mut test_file = PathBuf::from(&base);
|
||||||
test_file.push(path);
|
test_file.push(path);
|
||||||
create_dir_all(test_file.parent().unwrap()).unwrap();
|
|
||||||
File::create(test_file).unwrap();
|
|
||||||
|
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
Some(PathBuf::from("/tmp/relative/path/test.png")),
|
Some(PathBuf::from("/tmp/relative/path/test.png")),
|
||||||
@@ -125,8 +118,6 @@ mod tests {
|
|||||||
let path = "relative/path/test.png";
|
let path = "relative/path/test.png";
|
||||||
let mut test_file = PathBuf::from(&base);
|
let mut test_file = PathBuf::from(&base);
|
||||||
test_file.push(path);
|
test_file.push(path);
|
||||||
create_dir_all(test_file.parent().unwrap()).unwrap();
|
|
||||||
File::create(test_file).unwrap();
|
|
||||||
|
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
Some(PathBuf::from("/tmp/relative/path/test.png")),
|
Some(PathBuf::from("/tmp/relative/path/test.png")),
|
||||||
|
|||||||
@@ -49,7 +49,7 @@ async fn login(creds: Json<LoginRequest>) -> impl Responder {
|
|||||||
if let Some(user) = get_user(&creds.username, &creds.password) {
|
if let Some(user) = get_user(&creds.username, &creds.password) {
|
||||||
let claims = Claims {
|
let claims = Claims {
|
||||||
sub: user.id.to_string(),
|
sub: user.id.to_string(),
|
||||||
exp: (Utc::now() + Duration::days(3)).timestamp(),
|
exp: (Utc::now() + Duration::days(5)).timestamp(),
|
||||||
};
|
};
|
||||||
let token = encode(
|
let token = encode(
|
||||||
&Header::default(),
|
&Header::default(),
|
||||||
@@ -287,7 +287,7 @@ async fn create_thumbnails() {
|
|||||||
.map(|entry| (image::open(entry.path()), entry.path().to_path_buf()))
|
.map(|entry| (image::open(entry.path()), entry.path().to_path_buf()))
|
||||||
.filter(|(img, _)| img.is_ok())
|
.filter(|(img, _)| img.is_ok())
|
||||||
.map(|(img, path)| (img.unwrap(), path))
|
.map(|(img, path)| (img.unwrap(), path))
|
||||||
.map(|(image, path)| (image.thumbnail(200, 200), path))
|
.map(|(image, path)| (image.thumbnail(200, u32::MAX), path))
|
||||||
.map(|(image, path)| {
|
.map(|(image, path)| {
|
||||||
let relative_path = &path.strip_prefix(&images).unwrap();
|
let relative_path = &path.strip_prefix(&images).unwrap();
|
||||||
let thumb_path = Path::new(thumbnail_directory).join(relative_path);
|
let thumb_path = Path::new(thumbnail_directory).join(relative_path);
|
||||||
@@ -332,7 +332,6 @@ async fn main() -> std::io::Result<()> {
|
|||||||
|
|
||||||
HttpServer::new(|| {
|
HttpServer::new(|| {
|
||||||
App::new()
|
App::new()
|
||||||
.service(register)
|
|
||||||
.service(login)
|
.service(login)
|
||||||
.service(list_photos)
|
.service(list_photos)
|
||||||
.service(get_image)
|
.service(get_image)
|
||||||
|
|||||||
Reference in New Issue
Block a user