update
This commit is contained in:
parent
6b0ce6f057
commit
bcdd5ffa4c
|
@ -416,9 +416,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "flume"
|
name = "flume"
|
||||||
version = "0.10.12"
|
version = "0.10.13"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "843c03199d0c0ca54bc1ea90ac0d507274c28abcc4f691ae8b4eaa375087c76a"
|
checksum = "1ceeb589a3157cac0ab8cc585feb749bd2cea5cb55a6ee802ad72d9fd38303da"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"futures-core",
|
"futures-core",
|
||||||
"futures-sink",
|
"futures-sink",
|
||||||
|
@ -631,7 +631,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70"
|
checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "homedisk-core"
|
name = "homedisk"
|
||||||
version = "0.0.0"
|
version = "0.0.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"anyhow",
|
"anyhow",
|
||||||
|
@ -1740,9 +1740,9 @@ checksum = "360dfd1d6d30e05fda32ace2c8c70e9c0a9da713275777f5a4dbb8a1893930c6"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "tracing"
|
name = "tracing"
|
||||||
version = "0.1.34"
|
version = "0.1.35"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "5d0ecdcb44a79f0fe9844f0c4f33a342cbcbb5117de8001e6ba0dc2351327d09"
|
checksum = "a400e31aa60b9d44a52a8ee0343b5b18566b03a8321e0d321f695cf56e940160"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"cfg-if",
|
"cfg-if",
|
||||||
"log",
|
"log",
|
||||||
|
@ -1752,11 +1752,11 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "tracing-core"
|
name = "tracing-core"
|
||||||
version = "0.1.26"
|
version = "0.1.27"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "f54c8ca710e81886d498c2fd3331b56c93aa248d49de2222ad2742247c60072f"
|
checksum = "7709595b8878a4965ce5e87ebf880a7d39c9afc6837721b21a5a816a8117d921"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"lazy_static",
|
"once_cell",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
# HTTP host
|
# HTTP host
|
||||||
host = "0.0.0.0"
|
host = "0.0.0.0"
|
||||||
# HTTP port
|
# HTTP port
|
||||||
port = 8080
|
port = 8080
|
||||||
# Cors domains
|
# Cors domains
|
||||||
cors = [
|
cors = [
|
||||||
"127.0.0.1:8000",
|
"127.0.0.1:8000",
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
[package]
|
[package]
|
||||||
name = "homedisk-core"
|
name = "homedisk"
|
||||||
authors = ["MedzikUser <nivua1fn@duck.com>"]
|
authors = ["MedzikUser <nivua1fn@duck.com>"]
|
||||||
homepage = "https://github.com/HomeDisk/cloud"
|
homepage = "https://github.com/HomeDisk/cloud"
|
||||||
repository = "https://github.com/HomeDisk/cloud"
|
repository = "https://github.com/HomeDisk/cloud"
|
||||||
|
@ -10,7 +10,7 @@ edition = "2021"
|
||||||
# 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
|
||||||
|
|
||||||
[[bin]]
|
[[bin]]
|
||||||
name = "cloud"
|
name = "homedisk"
|
||||||
path = "./src/main.rs"
|
path = "./src/main.rs"
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
|
|
|
@ -26,18 +26,20 @@ pub async fn handle(
|
||||||
// create user token
|
// create user token
|
||||||
let token = create_token(&user, config.jwt.secret.as_bytes(), config.jwt.expires)?;
|
let token = create_token(&user, config.jwt.secret.as_bytes(), config.jwt.expires)?;
|
||||||
|
|
||||||
|
// Reponse user token
|
||||||
Response::LoggedIn {
|
Response::LoggedIn {
|
||||||
access_token: token,
|
access_token: token,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// error while searching for a user
|
||||||
Err(err) => {
|
Err(err) => {
|
||||||
return match err {
|
return match err {
|
||||||
|
// user not found
|
||||||
Error::UserNotFound => Err(ServerError::AuthError(AuthError::UserNotFound)),
|
Error::UserNotFound => Err(ServerError::AuthError(AuthError::UserNotFound)),
|
||||||
_ => Err(ServerError::AuthError(AuthError::UnknownError(
|
// other error
|
||||||
err.to_string(),
|
_ => Err(ServerError::AuthError(AuthError::Other(err.to_string()))),
|
||||||
))),
|
};
|
||||||
}
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -45,14 +45,15 @@ pub async fn handle(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Err(e) => {
|
// error while searching for a user
|
||||||
if e.to_string().contains("UNIQUE constraint failed") {
|
Err(err) => {
|
||||||
|
// user already exists
|
||||||
|
if err.to_string().contains("UNIQUE constraint failed") {
|
||||||
return Err(ServerError::AuthError(AuthError::UserAlreadyExists));
|
return Err(ServerError::AuthError(AuthError::UserAlreadyExists));
|
||||||
}
|
}
|
||||||
|
|
||||||
return Err(ServerError::AuthError(AuthError::UnknownError(
|
// other error
|
||||||
e.to_string(),
|
return Err(ServerError::AuthError(AuthError::Other(err.to_string())));
|
||||||
)));
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -24,13 +24,12 @@ pub async fn handle(
|
||||||
username: res.username,
|
username: res.username,
|
||||||
},
|
},
|
||||||
|
|
||||||
|
// error while searching for a user
|
||||||
Err(err) => match err {
|
Err(err) => match err {
|
||||||
|
// user not found
|
||||||
Error::UserNotFound => return Err(ServerError::AuthError(AuthError::UserNotFound)),
|
Error::UserNotFound => return Err(ServerError::AuthError(AuthError::UserNotFound)),
|
||||||
_ => {
|
// other error
|
||||||
return Err(ServerError::AuthError(AuthError::UnknownError(
|
_ => return Err(ServerError::AuthError(AuthError::Other(err.to_string()))),
|
||||||
err.to_string(),
|
|
||||||
)))
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -3,7 +3,7 @@ use std::fs;
|
||||||
use axum::{extract::rejection::JsonRejection, Extension, Json};
|
use axum::{extract::rejection::JsonRejection, Extension, Json};
|
||||||
use axum_auth::AuthBearer;
|
use axum_auth::AuthBearer;
|
||||||
use homedisk_database::Database;
|
use homedisk_database::Database;
|
||||||
use homedisk_types::fs::create_dir::{Request, Response};
|
use homedisk_types::fs::create_dir::Request;
|
||||||
use homedisk_types::{
|
use homedisk_types::{
|
||||||
config::Config,
|
config::Config,
|
||||||
errors::{FsError, ServerError},
|
errors::{FsError, ServerError},
|
||||||
|
@ -18,7 +18,7 @@ pub async fn handle(
|
||||||
Extension(config): Extension<Config>,
|
Extension(config): Extension<Config>,
|
||||||
AuthBearer(token): AuthBearer,
|
AuthBearer(token): AuthBearer,
|
||||||
request: Result<Json<Request>, JsonRejection>,
|
request: Result<Json<Request>, JsonRejection>,
|
||||||
) -> Result<Json<Response>, ServerError> {
|
) -> Result<(), ServerError> {
|
||||||
// validate json request
|
// validate json request
|
||||||
let Json(request) = validate_json::<Request>(request)?;
|
let Json(request) = validate_json::<Request>(request)?;
|
||||||
|
|
||||||
|
@ -38,9 +38,10 @@ pub async fn handle(
|
||||||
req_dir = request.path
|
req_dir = request.path
|
||||||
);
|
);
|
||||||
|
|
||||||
// create dirs
|
// create directories
|
||||||
fs::create_dir_all(path)
|
fs::create_dir_all(path)
|
||||||
.map_err(|err| ServerError::FsError(FsError::CreateDirectory(err.to_string())))?;
|
.map_err(|err| ServerError::FsError(FsError::CreateDirectory(err.to_string())))?;
|
||||||
|
|
||||||
Ok(Json(Response { created: true }))
|
// send a blank Response
|
||||||
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
|
@ -45,13 +45,16 @@ pub async fn handle(
|
||||||
// delete file
|
// delete file
|
||||||
if path.is_file() {
|
if path.is_file() {
|
||||||
fs::remove_file(&path)
|
fs::remove_file(&path)
|
||||||
|
// return error
|
||||||
.map_err(|err| ServerError::FsError(FsError::DeleteFile(err.to_string())))?;
|
.map_err(|err| ServerError::FsError(FsError::DeleteFile(err.to_string())))?;
|
||||||
}
|
}
|
||||||
// delete directory
|
// delete directory
|
||||||
else if path.is_dir() {
|
else if path.is_dir() {
|
||||||
fs::remove_dir(&path)
|
fs::remove_dir(&path)
|
||||||
|
// return error
|
||||||
.map_err(|err| ServerError::FsError(FsError::DeleteDirectory(err.to_string())))?;
|
.map_err(|err| ServerError::FsError(FsError::DeleteDirectory(err.to_string())))?;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// send a blank Response
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
|
@ -36,5 +36,6 @@ pub async fn handle(
|
||||||
// read file content
|
// read file content
|
||||||
let content = fs::read(path).unwrap();
|
let content = fs::read(path).unwrap();
|
||||||
|
|
||||||
|
// send file content in Response
|
||||||
Ok(content)
|
Ok(content)
|
||||||
}
|
}
|
||||||
|
|
|
@ -59,19 +59,19 @@ pub async fn handle(
|
||||||
|
|
||||||
// get paths from dir
|
// get paths from dir
|
||||||
let paths = fs::read_dir(&path)
|
let paths = fs::read_dir(&path)
|
||||||
.map_err(|err| ServerError::FsError(FsError::ReadDir(err.to_string())))?;
|
.map_err(|err| ServerError::FsError(FsError::ReadDirectory(err.to_string())))?;
|
||||||
|
|
||||||
let mut files = vec![];
|
let mut files = vec![];
|
||||||
let mut dirs = vec![];
|
let mut dirs = vec![];
|
||||||
|
|
||||||
for f in paths {
|
for f in paths {
|
||||||
// handle Error
|
// handle Error
|
||||||
let f = f.map_err(|err| ServerError::FsError(FsError::UnknownError(err.to_string())))?;
|
let f = f.map_err(|err| ServerError::FsError(FsError::Other(err.to_string())))?;
|
||||||
|
|
||||||
// get path metadata
|
// get path metadata
|
||||||
let metadata = f
|
let metadata = f
|
||||||
.metadata()
|
.metadata()
|
||||||
.map_err(|err| ServerError::FsError(FsError::UnknownError(err.to_string())))?;
|
.map_err(|err| ServerError::FsError(FsError::Other(err.to_string())))?;
|
||||||
|
|
||||||
// get name of the path
|
// get name of the path
|
||||||
let name = f.path().display().to_string().replace(&path, "");
|
let name = f.path().display().to_string().replace(&path, "");
|
||||||
|
@ -80,7 +80,7 @@ pub async fn handle(
|
||||||
if metadata.is_dir() {
|
if metadata.is_dir() {
|
||||||
let size = Byte::from_bytes(
|
let size = Byte::from_bytes(
|
||||||
dir_size(f.path().display().to_string())
|
dir_size(f.path().display().to_string())
|
||||||
.map_err(|err| ServerError::FsError(FsError::UnknownError(err.to_string())))?
|
.map_err(|err| ServerError::FsError(FsError::Other(err.to_string())))?
|
||||||
.into(),
|
.into(),
|
||||||
)
|
)
|
||||||
.get_appropriate_unit(true)
|
.get_appropriate_unit(true)
|
||||||
|
|
|
@ -21,7 +21,7 @@ pub fn validate_path(path: &str) -> Result<(), homedisk_types::errors::ServerErr
|
||||||
// `path` can't contain `..`
|
// `path` can't contain `..`
|
||||||
// to prevent attack attempts because by using a `..` you can access the previous folder
|
// to prevent attack attempts because by using a `..` you can access the previous folder
|
||||||
if path.contains("..") {
|
if path.contains("..") {
|
||||||
return Err(ServerError::FsError(FsError::ReadDir(
|
return Err(ServerError::FsError(FsError::ReadDirectory(
|
||||||
"the `path` must not contain `..`".to_string(),
|
"the `path` must not contain `..`".to_string(),
|
||||||
)));
|
)));
|
||||||
}
|
}
|
||||||
|
@ -29,7 +29,7 @@ pub fn validate_path(path: &str) -> Result<(), homedisk_types::errors::ServerErr
|
||||||
// `path` can't contain `~`
|
// `path` can't contain `~`
|
||||||
// to prevent attack attempts because `~` can get up a directory on `$HOME`
|
// to prevent attack attempts because `~` can get up a directory on `$HOME`
|
||||||
if path.contains('~') {
|
if path.contains('~') {
|
||||||
return Err(ServerError::FsError(FsError::ReadDir(
|
return Err(ServerError::FsError(FsError::ReadDirectory(
|
||||||
"the `path` must not contain `~`".to_string(),
|
"the `path` must not contain `~`".to_string(),
|
||||||
)));
|
)));
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,14 +2,14 @@ use std::io::Write;
|
||||||
use std::{fs, path::Path};
|
use std::{fs, path::Path};
|
||||||
|
|
||||||
use axum::extract::{Multipart, Query};
|
use axum::extract::{Multipart, Query};
|
||||||
use axum::{Extension, Json};
|
use axum::Extension;
|
||||||
use axum_auth::AuthBearer;
|
use axum_auth::AuthBearer;
|
||||||
use futures::TryStreamExt;
|
use futures::TryStreamExt;
|
||||||
use homedisk_database::Database;
|
use homedisk_database::Database;
|
||||||
use homedisk_types::{
|
use homedisk_types::{
|
||||||
config::Config,
|
config::Config,
|
||||||
errors::{FsError, ServerError},
|
errors::{FsError, ServerError},
|
||||||
fs::upload::{Pagination, Response},
|
fs::upload::Pagination,
|
||||||
};
|
};
|
||||||
|
|
||||||
use crate::fs::validate_path;
|
use crate::fs::validate_path;
|
||||||
|
@ -22,7 +22,7 @@ pub async fn handle(
|
||||||
AuthBearer(token): AuthBearer,
|
AuthBearer(token): AuthBearer,
|
||||||
mut multipart: Multipart,
|
mut multipart: Multipart,
|
||||||
query: Query<Pagination>,
|
query: Query<Pagination>,
|
||||||
) -> Result<Json<Response>, ServerError> {
|
) -> Result<(), ServerError> {
|
||||||
// validate user token
|
// validate user token
|
||||||
let token = validate_jwt(config.jwt.secret.as_bytes(), &token)?;
|
let token = validate_jwt(config.jwt.secret.as_bytes(), &token)?;
|
||||||
|
|
||||||
|
@ -47,7 +47,7 @@ pub async fn handle(
|
||||||
|
|
||||||
// create a directory where the file will be placed
|
// create a directory where the file will be placed
|
||||||
// e.g. path ==> `/secret/files/images/screenshot.png`
|
// e.g. path ==> `/secret/files/images/screenshot.png`
|
||||||
// directories up to `/home/homedisk/{username}/secret/files/images/` will be created
|
// directories up to `{storage dir}/{username}/secret/files/images/` will be created
|
||||||
match file_path.parent() {
|
match file_path.parent() {
|
||||||
Some(prefix) => fs::create_dir_all(&prefix)
|
Some(prefix) => fs::create_dir_all(&prefix)
|
||||||
.map_err(|err| ServerError::FsError(FsError::CreateFile(err.to_string())))?,
|
.map_err(|err| ServerError::FsError(FsError::CreateFile(err.to_string())))?,
|
||||||
|
@ -75,5 +75,6 @@ pub async fn handle(
|
||||||
.await
|
.await
|
||||||
.map_err(|err| ServerError::FsError(FsError::WriteFile(err.to_string())))?;
|
.map_err(|err| ServerError::FsError(FsError::WriteFile(err.to_string())))?;
|
||||||
|
|
||||||
Ok(Json(Response { uploaded: true }))
|
// send a blank Response
|
||||||
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,7 +5,9 @@ use rust_utilities::crypto::jsonwebtoken::{Claims, Token};
|
||||||
/// Validate user token
|
/// Validate user token
|
||||||
pub fn validate_jwt(secret: &[u8], token: &str) -> Result<TokenData<Claims>, ServerError> {
|
pub fn validate_jwt(secret: &[u8], token: &str) -> Result<TokenData<Claims>, ServerError> {
|
||||||
match Token::decode(secret, token.to_string()) {
|
match Token::decode(secret, token.to_string()) {
|
||||||
|
// if success return claims
|
||||||
Ok(claims) => Ok(claims),
|
Ok(claims) => Ok(claims),
|
||||||
|
// invalid token
|
||||||
Err(_) => Err(ServerError::AuthError(AuthError::InvalidToken)),
|
Err(_) => Err(ServerError::AuthError(AuthError::InvalidToken)),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -18,6 +20,7 @@ mod tests {
|
||||||
|
|
||||||
use super::validate_jwt;
|
use super::validate_jwt;
|
||||||
|
|
||||||
|
/// Test a token validation
|
||||||
#[test]
|
#[test]
|
||||||
fn validate_token() {
|
fn validate_token() {
|
||||||
let secret = b"secret";
|
let secret = b"secret";
|
||||||
|
|
|
@ -15,14 +15,16 @@ pub fn create_token(user: &User, secret: &[u8], expires: i64) -> Result<String,
|
||||||
/// Search for a user
|
/// Search for a user
|
||||||
pub async fn find_user(db: Database, user_id: String) -> Result<User, ServerError> {
|
pub async fn find_user(db: Database, user_id: String) -> Result<User, ServerError> {
|
||||||
match db.find_user_by_id(user_id).await {
|
match db.find_user_by_id(user_id).await {
|
||||||
|
// if success return user
|
||||||
Ok(user) => Ok(user),
|
Ok(user) => Ok(user),
|
||||||
|
// errors
|
||||||
Err(err) => match err {
|
Err(err) => match err {
|
||||||
|
// user not found
|
||||||
homedisk_database::Error::UserNotFound => {
|
homedisk_database::Error::UserNotFound => {
|
||||||
Err(ServerError::AuthError(AuthError::UserNotFound))
|
Err(ServerError::AuthError(AuthError::UserNotFound))
|
||||||
}
|
}
|
||||||
_ => Err(ServerError::AuthError(AuthError::UnknownError(
|
// other error
|
||||||
err.to_string(),
|
_ => Err(ServerError::AuthError(AuthError::Other(err.to_string()))),
|
||||||
))),
|
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -33,6 +35,7 @@ mod tests {
|
||||||
|
|
||||||
use super::create_token;
|
use super::create_token;
|
||||||
|
|
||||||
|
/// Test a token creation
|
||||||
#[test]
|
#[test]
|
||||||
fn test_create_token() {
|
fn test_create_token() {
|
||||||
let secret = b"secret";
|
let secret = b"secret";
|
||||||
|
|
|
@ -2,4 +2,6 @@ mod auth;
|
||||||
mod jwt;
|
mod jwt;
|
||||||
mod validate_json;
|
mod validate_json;
|
||||||
|
|
||||||
pub use {auth::*, jwt::*, validate_json::*};
|
pub use auth::*;
|
||||||
|
pub use jwt::*;
|
||||||
|
pub use validate_json::*;
|
||||||
|
|
|
@ -6,11 +6,17 @@ pub fn validate_json<Typ>(
|
||||||
payload: Result<Json<Typ>, JsonRejection>,
|
payload: Result<Json<Typ>, JsonRejection>,
|
||||||
) -> Result<Json<Typ>, ServerError> {
|
) -> Result<Json<Typ>, ServerError> {
|
||||||
match payload {
|
match payload {
|
||||||
|
// if success return payload
|
||||||
Ok(payload) => Ok(payload),
|
Ok(payload) => Ok(payload),
|
||||||
|
// mission json in Content-Type Header
|
||||||
Err(JsonRejection::MissingJsonContentType(_)) => Err(ServerError::MissingJsonContentType),
|
Err(JsonRejection::MissingJsonContentType(_)) => Err(ServerError::MissingJsonContentType),
|
||||||
|
// failed to deserialize json
|
||||||
Err(JsonRejection::JsonDataError(_)) => Err(ServerError::JsonDataError),
|
Err(JsonRejection::JsonDataError(_)) => Err(ServerError::JsonDataError),
|
||||||
|
// syntax error in json
|
||||||
Err(JsonRejection::JsonSyntaxError(_)) => Err(ServerError::JsonSyntaxError),
|
Err(JsonRejection::JsonSyntaxError(_)) => Err(ServerError::JsonSyntaxError),
|
||||||
|
// failed to extract the request body
|
||||||
Err(JsonRejection::BytesRejection(_)) => Err(ServerError::BytesRejection),
|
Err(JsonRejection::BytesRejection(_)) => Err(ServerError::BytesRejection),
|
||||||
|
// other error
|
||||||
Err(err) => Err(ServerError::Other(err.to_string())),
|
Err(err) => Err(ServerError::Other(err.to_string())),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,9 +1,9 @@
|
||||||
//! `/auth/login` Request and Response types
|
//! HTTP `/auth/login` Request and Response types
|
||||||
|
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
use zeroize::{Zeroize, ZeroizeOnDrop};
|
use zeroize::{Zeroize, ZeroizeOnDrop};
|
||||||
|
|
||||||
/// `/auth/login` Request
|
/// HTTP `/auth/login` Request
|
||||||
#[derive(Debug, Serialize, Deserialize, Clone, Zeroize, ZeroizeOnDrop)]
|
#[derive(Debug, Serialize, Deserialize, Clone, Zeroize, ZeroizeOnDrop)]
|
||||||
pub struct Request {
|
pub struct Request {
|
||||||
/// Username
|
/// Username
|
||||||
|
@ -12,11 +12,11 @@ pub struct Request {
|
||||||
pub password: String,
|
pub password: String,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// `/auth/login` Response
|
/// HTTP `/auth/login` Response
|
||||||
#[derive(Debug, Serialize, Deserialize, Clone, Zeroize, ZeroizeOnDrop)]
|
#[derive(Debug, Serialize, Deserialize, Clone, Zeroize, ZeroizeOnDrop)]
|
||||||
pub enum Response {
|
pub enum Response {
|
||||||
LoggedIn {
|
LoggedIn {
|
||||||
/// Token of a user
|
/// User access token
|
||||||
access_token: String,
|
access_token: String,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
//! `/auth/whoami` Response type
|
//! HTTP `/auth/whoami` Response type
|
||||||
|
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
/// `/auth/whoami` Response
|
/// HTTP `/auth/whoami` Response
|
||||||
#[derive(Debug, Serialize, Deserialize, Clone)]
|
#[derive(Debug, Serialize, Deserialize, Clone)]
|
||||||
pub struct Response {
|
pub struct Response {
|
||||||
/// Logged user username
|
/// Logged user username
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
//! Typed for a database
|
//! Types for a database
|
||||||
|
|
||||||
mod user;
|
mod user;
|
||||||
|
|
||||||
|
|
|
@ -1,29 +1,31 @@
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
/// `/auth/*` Error
|
/// HTTP `/auth/*` Errors
|
||||||
#[derive(Debug, Clone, Serialize, Deserialize, thiserror::Error)]
|
#[derive(Debug, Clone, Serialize, Deserialize, thiserror::Error)]
|
||||||
pub enum Error {
|
pub enum Error {
|
||||||
|
/// User not found!
|
||||||
|
/// Username or Password incorrect.
|
||||||
#[error("user not found")]
|
#[error("user not found")]
|
||||||
UserNotFound,
|
UserNotFound,
|
||||||
|
/// Cannot create a user because username already exists.
|
||||||
#[error("user already exists")]
|
#[error("user already exists")]
|
||||||
UserAlreadyExists,
|
UserAlreadyExists,
|
||||||
|
/// Username is too short.
|
||||||
#[error("username is too short")]
|
#[error("username is too short")]
|
||||||
UsernameTooShort,
|
UsernameTooShort,
|
||||||
|
/// Username is too long.
|
||||||
#[error("username is too long")]
|
#[error("username is too long")]
|
||||||
UsernameTooLong,
|
UsernameTooLong,
|
||||||
|
/// Password is too short.
|
||||||
#[error("password is too short")]
|
#[error("password is too short")]
|
||||||
PasswordTooShort,
|
PasswordTooShort,
|
||||||
|
/// Failed to generate user token.
|
||||||
#[error("generate jwt token")]
|
#[error("generate jwt token")]
|
||||||
TokenGenerate,
|
TokenGenerate,
|
||||||
|
/// Incorrect user token.
|
||||||
#[error("invalid jwt token")]
|
#[error("invalid jwt token")]
|
||||||
InvalidToken,
|
InvalidToken,
|
||||||
|
/// Other error.
|
||||||
#[error("unknown error - {0}")]
|
#[error("other error - {0}")]
|
||||||
UnknownError(String),
|
Other(String),
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,8 @@
|
||||||
/// Database Error
|
/// Database Error
|
||||||
#[derive(Debug, thiserror::Error)]
|
#[derive(Debug, thiserror::Error)]
|
||||||
pub enum Error {
|
pub enum Error {
|
||||||
|
/// User not found!
|
||||||
|
/// Username or Password incorrect.
|
||||||
#[error("user not found")]
|
#[error("user not found")]
|
||||||
UserNotFound,
|
UserNotFound,
|
||||||
/// sqlx::Error
|
/// sqlx::Error
|
||||||
|
|
|
@ -3,36 +3,37 @@ use serde::{Deserialize, Serialize};
|
||||||
/// `/fs/*` Error
|
/// `/fs/*` Error
|
||||||
#[derive(Debug, Clone, Serialize, Deserialize, thiserror::Error)]
|
#[derive(Debug, Clone, Serialize, Deserialize, thiserror::Error)]
|
||||||
pub enum Error {
|
pub enum Error {
|
||||||
#[error("file already exists")]
|
/// File doesn't exists.
|
||||||
FileAlreadyExists,
|
|
||||||
|
|
||||||
#[error("file doesn't exists")]
|
#[error("file doesn't exists")]
|
||||||
FileDoesNotExist,
|
FileDoesNotExist,
|
||||||
|
/// File already exists.
|
||||||
|
#[error("file already exists")]
|
||||||
|
FileAlreadyExists,
|
||||||
|
/// Error when parsing multipart.
|
||||||
#[error("unexpected multipart error")]
|
#[error("unexpected multipart error")]
|
||||||
MultipartError,
|
MultipartError,
|
||||||
|
/// Failed to create a file.
|
||||||
#[error("create file - {0}")]
|
#[error("create file - {0}")]
|
||||||
CreateFile(String),
|
CreateFile(String),
|
||||||
|
/// Failed to create a directory.
|
||||||
#[error("create dir - {0}")]
|
#[error("create dir - {0}")]
|
||||||
CreateDirectory(String),
|
CreateDirectory(String),
|
||||||
|
/// Failed to delete file.
|
||||||
#[error("delete file - {0}")]
|
#[error("delete file - {0}")]
|
||||||
DeleteFile(String),
|
DeleteFile(String),
|
||||||
|
/// Failed to delete directory.
|
||||||
#[error("delete dir - {0}")]
|
#[error("delete dir - {0}")]
|
||||||
DeleteDirectory(String),
|
DeleteDirectory(String),
|
||||||
|
/// Failed to write content to file.
|
||||||
#[error("write file - {0}")]
|
#[error("write file - {0}")]
|
||||||
WriteFile(String),
|
WriteFile(String),
|
||||||
|
/// Failed decoding base64.
|
||||||
#[error("base64 - {0}")]
|
#[error("base64 - {0}")]
|
||||||
Base64(String),
|
Base64(String),
|
||||||
|
/// Error when paths in directory.
|
||||||
#[error("read dir - {0}")]
|
#[error("read dir - {0}")]
|
||||||
ReadDir(String),
|
ReadDirectory(String),
|
||||||
|
/// Other error.
|
||||||
#[error("unknown error - {0}")]
|
#[error("other error - {0}")]
|
||||||
UnknownError(String),
|
Other(String),
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,27 +6,28 @@ use super::{AuthError, FsError};
|
||||||
#[derive(Debug, Clone, Serialize, Deserialize, thiserror::Error)]
|
#[derive(Debug, Clone, Serialize, Deserialize, thiserror::Error)]
|
||||||
#[serde(tag = "error", content = "error_message", rename_all = "kebab-case")]
|
#[serde(tag = "error", content = "error_message", rename_all = "kebab-case")]
|
||||||
pub enum Error {
|
pub enum Error {
|
||||||
|
/// Auth error.
|
||||||
#[error("auth error - {0}")]
|
#[error("auth error - {0}")]
|
||||||
AuthError(#[from] AuthError),
|
AuthError(#[from] AuthError),
|
||||||
|
/// File System Error.
|
||||||
#[error("fs error - {0}")]
|
#[error("fs error - {0}")]
|
||||||
FsError(#[from] FsError),
|
FsError(#[from] FsError),
|
||||||
|
/// User sends too many requests.
|
||||||
#[error("too may requests, please slow down")]
|
#[error("too may requests, please slow down")]
|
||||||
TooManyRequests,
|
TooManyRequests,
|
||||||
|
/// Missing Json in Content-Type Header.
|
||||||
#[error("missing json content type")]
|
#[error("missing json content type")]
|
||||||
MissingJsonContentType,
|
MissingJsonContentType,
|
||||||
|
/// Failed to deserialize json.
|
||||||
#[error("error deserialize json")]
|
#[error("error deserialize json")]
|
||||||
JsonDataError,
|
JsonDataError,
|
||||||
|
/// Syntax error in JSON
|
||||||
#[error("json syntax error")]
|
#[error("json syntax error")]
|
||||||
JsonSyntaxError,
|
JsonSyntaxError,
|
||||||
|
/// Failed to extract the Request body
|
||||||
#[error("failed to extract the request body")]
|
#[error("failed to extract the request body")]
|
||||||
BytesRejection,
|
BytesRejection,
|
||||||
|
/// Other error
|
||||||
#[error("unknown error - {0}")]
|
#[error("unknown error - {0}")]
|
||||||
Other(String),
|
Other(String),
|
||||||
}
|
}
|
||||||
|
@ -45,7 +46,7 @@ impl axum::response::IntoResponse for Error {
|
||||||
AuthError::PasswordTooShort => StatusCode::NOT_ACCEPTABLE,
|
AuthError::PasswordTooShort => StatusCode::NOT_ACCEPTABLE,
|
||||||
AuthError::TokenGenerate => StatusCode::INTERNAL_SERVER_ERROR,
|
AuthError::TokenGenerate => StatusCode::INTERNAL_SERVER_ERROR,
|
||||||
AuthError::InvalidToken => StatusCode::BAD_REQUEST,
|
AuthError::InvalidToken => StatusCode::BAD_REQUEST,
|
||||||
AuthError::UnknownError(_) => StatusCode::INTERNAL_SERVER_ERROR,
|
AuthError::Other(_) => StatusCode::INTERNAL_SERVER_ERROR,
|
||||||
},
|
},
|
||||||
Self::FsError(ref err) => match err {
|
Self::FsError(ref err) => match err {
|
||||||
FsError::FileAlreadyExists => StatusCode::BAD_REQUEST,
|
FsError::FileAlreadyExists => StatusCode::BAD_REQUEST,
|
||||||
|
@ -57,8 +58,8 @@ impl axum::response::IntoResponse for Error {
|
||||||
FsError::DeleteDirectory(_) => StatusCode::INTERNAL_SERVER_ERROR,
|
FsError::DeleteDirectory(_) => StatusCode::INTERNAL_SERVER_ERROR,
|
||||||
FsError::WriteFile(_) => StatusCode::INTERNAL_SERVER_ERROR,
|
FsError::WriteFile(_) => StatusCode::INTERNAL_SERVER_ERROR,
|
||||||
FsError::Base64(_) => StatusCode::BAD_REQUEST,
|
FsError::Base64(_) => StatusCode::BAD_REQUEST,
|
||||||
FsError::ReadDir(_) => StatusCode::BAD_REQUEST,
|
FsError::ReadDirectory(_) => StatusCode::BAD_REQUEST,
|
||||||
FsError::UnknownError(_) => StatusCode::INTERNAL_SERVER_ERROR,
|
FsError::Other(_) => StatusCode::INTERNAL_SERVER_ERROR,
|
||||||
},
|
},
|
||||||
Self::TooManyRequests => StatusCode::TOO_MANY_REQUESTS,
|
Self::TooManyRequests => StatusCode::TOO_MANY_REQUESTS,
|
||||||
Self::MissingJsonContentType => StatusCode::BAD_REQUEST,
|
Self::MissingJsonContentType => StatusCode::BAD_REQUEST,
|
||||||
|
|
|
@ -2,15 +2,9 @@
|
||||||
|
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
/// `/fs/createdir` Request
|
/// HTTP `/fs/createdir` Request
|
||||||
#[derive(Debug, Serialize, Deserialize, Clone)]
|
#[derive(Debug, Serialize, Deserialize, Clone)]
|
||||||
pub struct Request {
|
pub struct Request {
|
||||||
|
/// Path to directory wich will be created
|
||||||
pub path: String,
|
pub path: String,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// `/fs/createdir` Reponse
|
|
||||||
#[derive(Debug, Serialize, Deserialize, Clone)]
|
|
||||||
pub struct Response {
|
|
||||||
/// Directory created?
|
|
||||||
pub created: bool,
|
|
||||||
}
|
|
||||||
|
|
|
@ -2,9 +2,9 @@
|
||||||
|
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
/// `/fs/delete` Request
|
/// HTTP `/fs/delete` Request
|
||||||
#[derive(Debug, Serialize, Deserialize, Clone)]
|
#[derive(Debug, Serialize, Deserialize, Clone)]
|
||||||
pub struct Request {
|
pub struct Request {
|
||||||
/// Path of file/directory to delete
|
/// Path of file/directory to be delete
|
||||||
pub path: String,
|
pub path: String,
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,9 +2,9 @@
|
||||||
|
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
/// `/fs/download` Request
|
/// HTTP `/fs/download` Request
|
||||||
#[derive(Debug, Serialize, Deserialize, Clone)]
|
#[derive(Debug, Serialize, Deserialize, Clone)]
|
||||||
pub struct Request {
|
pub struct Request {
|
||||||
/// Path of file to download
|
/// Path of file to be download
|
||||||
pub path: String,
|
pub path: String,
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,13 +2,13 @@
|
||||||
|
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
/// `/fs/list` Request
|
/// HTTP `/fs/list` Request
|
||||||
#[derive(Debug, Serialize, Deserialize, Clone)]
|
#[derive(Debug, Serialize, Deserialize, Clone)]
|
||||||
pub struct Request {
|
pub struct Request {
|
||||||
pub path: String,
|
pub path: String,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// `/fs/list` Response
|
/// HTTP `/fs/list` Response
|
||||||
#[derive(Debug, Serialize, Deserialize, Clone)]
|
#[derive(Debug, Serialize, Deserialize, Clone)]
|
||||||
pub struct Response {
|
pub struct Response {
|
||||||
pub files: Vec<FileInfo>,
|
pub files: Vec<FileInfo>,
|
||||||
|
|
|
@ -2,16 +2,9 @@
|
||||||
|
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
/// `/fs/upload` Queries
|
/// HTTP `/fs/upload` Queries
|
||||||
#[derive(Debug, Serialize, Deserialize, Clone)]
|
#[derive(Debug, Serialize, Deserialize, Clone)]
|
||||||
pub struct Pagination {
|
pub struct Pagination {
|
||||||
/// Path where the file will be uploaded
|
/// Path where the file will be uploaded
|
||||||
pub path: String,
|
pub path: String,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// `/fs/upload` Response
|
|
||||||
#[derive(Debug, Serialize, Deserialize, Clone)]
|
|
||||||
pub struct Response {
|
|
||||||
/// The file has been uploaded?
|
|
||||||
pub uploaded: bool,
|
|
||||||
}
|
|
||||||
|
|
Loading…
Reference in New Issue