update
This commit is contained in:
parent
44e6caf093
commit
6b0ce6f057
|
@ -1,15 +0,0 @@
|
||||||
# EditorConfig is awesome: https://EditorConfig.org
|
|
||||||
|
|
||||||
# top-most EditorConfig file
|
|
||||||
root = true
|
|
||||||
|
|
||||||
[*]
|
|
||||||
indent_style = space
|
|
||||||
indent_size = 4
|
|
||||||
end_of_line = lf
|
|
||||||
charset = utf-8
|
|
||||||
trim_trailing_whitespace = true
|
|
||||||
insert_final_newline = false
|
|
||||||
|
|
||||||
[*.yml]
|
|
||||||
indent_size = 2
|
|
|
@ -2,14 +2,14 @@
|
||||||
# will have compiled files and executables
|
# will have compiled files and executables
|
||||||
/target
|
/target
|
||||||
|
|
||||||
# log files
|
# Logs files
|
||||||
*.log
|
*.log
|
||||||
|
|
||||||
# database
|
# SQLite
|
||||||
*.db
|
*.db
|
||||||
*.db-shm
|
*.db-shm
|
||||||
*.db-wal
|
*.db-wal
|
||||||
|
|
||||||
# ide config
|
# IDE configs
|
||||||
.idea
|
.idea
|
||||||
.vscode
|
.vscode
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
# HomeDisk cloud server
|
# HomeDisk cloud server
|
||||||
|
|
||||||
|
[![docs](https://img.shields.io/badge/docs-rust_docs-fff)](https://homedisk-doc.vercel.app/cloud/)
|
||||||
[![license badge](https://img.shields.io/github/license/MedzikUser/HomeDisk)](https://github.com/MedzikUser/HomeDisk)
|
[![license badge](https://img.shields.io/github/license/MedzikUser/HomeDisk)](https://github.com/MedzikUser/HomeDisk)
|
||||||
[![code size badge](https://img.shields.io/github/languages/code-size/MedzikUser/HomeDisk)](https://github.com/MedzikUser/HomeDisk)
|
[![code size badge](https://img.shields.io/github/languages/code-size/MedzikUser/HomeDisk)](https://github.com/MedzikUser/HomeDisk)
|
||||||
[![total lines badge](https://img.shields.io/tokei/lines/github/MedzikUser/HomeDisk)](https://github.com/MedzikUser/HomeDisk)
|
[![total lines badge](https://img.shields.io/tokei/lines/github/MedzikUser/HomeDisk)](https://github.com/MedzikUser/HomeDisk)
|
||||||
|
|
14
config.toml
14
config.toml
|
@ -1,7 +1,10 @@
|
||||||
# HTTP Server
|
# HTTP Server
|
||||||
[http]
|
[http]
|
||||||
|
# HTTP host
|
||||||
host = "0.0.0.0"
|
host = "0.0.0.0"
|
||||||
port = 8080
|
# HTTP port
|
||||||
|
port = 8080
|
||||||
|
# Cors domains
|
||||||
cors = [
|
cors = [
|
||||||
"127.0.0.1:8000",
|
"127.0.0.1:8000",
|
||||||
"localhost:8000",
|
"localhost:8000",
|
||||||
|
@ -9,9 +12,12 @@ cors = [
|
||||||
|
|
||||||
# Json Web Token
|
# Json Web Token
|
||||||
[jwt]
|
[jwt]
|
||||||
secret = "secret key used to sign tokens" # secret used to sign tokens
|
# JWT Secret string (used to sign tokens)
|
||||||
expires = 24 # validity of token in hours
|
secret = "secret key used to sign tokens"
|
||||||
|
# Token expiration time in hours
|
||||||
|
expires = 24
|
||||||
|
|
||||||
# Storage
|
# Storage
|
||||||
[storage]
|
[storage]
|
||||||
path = "/home/homedisk" # the folder where the user files will be stored
|
# Directory where user files will be stored
|
||||||
|
path = "/home/homedisk"
|
||||||
|
|
|
@ -12,7 +12,7 @@ pub struct Database {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Database {
|
impl Database {
|
||||||
/// Open SQLite Database file
|
/// Open a SQLite database
|
||||||
/// ```ignore,rust
|
/// ```ignore,rust
|
||||||
/// use homedisk_database::Database;
|
/// use homedisk_database::Database;
|
||||||
///
|
///
|
||||||
|
@ -30,7 +30,7 @@ impl Database {
|
||||||
Ok(Self { conn })
|
Ok(Self { conn })
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Create new User
|
/// Create a new User
|
||||||
/// ```ignore,rust
|
/// ```ignore,rust
|
||||||
/// use homedisk_database::{Database, User};
|
/// use homedisk_database::{Database, User};
|
||||||
///
|
///
|
||||||
|
|
|
@ -9,3 +9,22 @@ pub fn validate_jwt(secret: &[u8], token: &str) -> Result<TokenData<Claims>, Ser
|
||||||
Err(_) => Err(ServerError::AuthError(AuthError::InvalidToken)),
|
Err(_) => Err(ServerError::AuthError(AuthError::InvalidToken)),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
use homedisk_database::User;
|
||||||
|
|
||||||
|
use crate::middleware::create_token;
|
||||||
|
|
||||||
|
use super::validate_jwt;
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn validate_token() {
|
||||||
|
let secret = b"secret";
|
||||||
|
let user = User::new("username", "password");
|
||||||
|
|
||||||
|
let token = create_token(&user, secret, 1).unwrap();
|
||||||
|
|
||||||
|
validate_jwt(secret, &token).unwrap();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -26,3 +26,18 @@ pub async fn find_user(db: Database, user_id: String) -> Result<User, ServerErro
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
use homedisk_database::User;
|
||||||
|
|
||||||
|
use super::create_token;
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_create_token() {
|
||||||
|
let secret = b"secret";
|
||||||
|
let user = User::new("username", "password");
|
||||||
|
|
||||||
|
create_token(&user, secret, 1).unwrap();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -3,13 +3,20 @@
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
use zeroize::{Zeroize, ZeroizeOnDrop};
|
use zeroize::{Zeroize, ZeroizeOnDrop};
|
||||||
|
|
||||||
|
/// `/auth/login` Request
|
||||||
#[derive(Debug, Serialize, Deserialize, Clone, Zeroize, ZeroizeOnDrop)]
|
#[derive(Debug, Serialize, Deserialize, Clone, Zeroize, ZeroizeOnDrop)]
|
||||||
pub struct Request {
|
pub struct Request {
|
||||||
|
/// Username
|
||||||
pub username: String,
|
pub username: String,
|
||||||
|
/// Unencrypted user password
|
||||||
pub password: String,
|
pub password: String,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// `/auth/login` Response
|
||||||
#[derive(Debug, Serialize, Deserialize, Clone, Zeroize, ZeroizeOnDrop)]
|
#[derive(Debug, Serialize, Deserialize, Clone, Zeroize, ZeroizeOnDrop)]
|
||||||
pub enum Response {
|
pub enum Response {
|
||||||
LoggedIn { access_token: String },
|
LoggedIn {
|
||||||
|
/// Token of a user
|
||||||
|
access_token: String,
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,7 +2,9 @@
|
||||||
|
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
|
/// `/auth/whoami` Response
|
||||||
#[derive(Debug, Serialize, Deserialize, Clone)]
|
#[derive(Debug, Serialize, Deserialize, Clone)]
|
||||||
pub struct Response {
|
pub struct Response {
|
||||||
|
/// Logged user username
|
||||||
pub username: String,
|
pub username: String,
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,11 +14,11 @@ impl Config {
|
||||||
/// let config = Config::parse().unwrap();
|
/// let config = Config::parse().unwrap();
|
||||||
/// ```
|
/// ```
|
||||||
pub fn parse() -> Result<Config> {
|
pub fn parse() -> Result<Config> {
|
||||||
// config file path
|
// get file path of config file
|
||||||
let config_dir = option_return!(dirs::config_dir(), "find config dir")?;
|
let config_dir = option_return!(dirs::config_dir(), "find config dir")?;
|
||||||
let config_path = format!("{}/homedisk/config.toml", config_dir.to_string_lossy());
|
let config_path = format!("{}/homedisk/config.toml", config_dir.to_string_lossy());
|
||||||
|
|
||||||
// read file
|
// read file content to string
|
||||||
let config = fs::read_to_string(config_path)?;
|
let config = fs::read_to_string(config_path)?;
|
||||||
|
|
||||||
// parse config and return it
|
// parse config and return it
|
||||||
|
|
|
@ -17,16 +17,16 @@ pub struct ConfigHTTP {
|
||||||
pub host: String,
|
pub host: String,
|
||||||
/// Port HTTP Port
|
/// Port HTTP Port
|
||||||
pub port: u16,
|
pub port: u16,
|
||||||
/// CORS Domaing (e.g ["site1.example.com", "site2.example.com"])
|
/// CORS Domains (e.g ["site1.example.com", "site2.example.com"])
|
||||||
pub cors: Vec<String>,
|
pub cors: Vec<String>,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Json Web Token config
|
/// Json Web Token config
|
||||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||||
pub struct ConfigJWT {
|
pub struct ConfigJWT {
|
||||||
/// JWT Secret string
|
/// JWT Secret string (used to sign tokens)
|
||||||
pub secret: String,
|
pub secret: String,
|
||||||
/// Token expiers time in seconds
|
/// Token expiration time in hours
|
||||||
pub expires: i64,
|
pub expires: i64,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -4,8 +4,11 @@ use uuid::Uuid;
|
||||||
/// SQL user table
|
/// SQL user table
|
||||||
#[derive(Debug, sqlx::FromRow)]
|
#[derive(Debug, sqlx::FromRow)]
|
||||||
pub struct User {
|
pub struct User {
|
||||||
|
/// UUID of the user
|
||||||
pub id: String,
|
pub id: String,
|
||||||
|
/// Username
|
||||||
pub username: String,
|
pub username: String,
|
||||||
|
/// Encryped user password
|
||||||
pub password: String,
|
pub password: String,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -33,6 +36,7 @@ impl User {
|
||||||
password.as_bytes(),
|
password.as_bytes(),
|
||||||
));
|
));
|
||||||
|
|
||||||
|
// return `User`
|
||||||
Self {
|
Self {
|
||||||
id,
|
id,
|
||||||
username,
|
username,
|
||||||
|
|
|
@ -33,6 +33,6 @@ pub enum Error {
|
||||||
#[error("read dir - {0}")]
|
#[error("read dir - {0}")]
|
||||||
ReadDir(String),
|
ReadDir(String),
|
||||||
|
|
||||||
#[error("unknown error")]
|
#[error("unknown error - {0}")]
|
||||||
UnknownError(String),
|
UnknownError(String),
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,10 +6,10 @@ 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 {
|
||||||
#[error("auth error: {0}")]
|
#[error("auth error - {0}")]
|
||||||
AuthError(#[from] AuthError),
|
AuthError(#[from] AuthError),
|
||||||
|
|
||||||
#[error("fs error: {0}")]
|
#[error("fs error - {0}")]
|
||||||
FsError(#[from] FsError),
|
FsError(#[from] FsError),
|
||||||
|
|
||||||
#[error("too may requests, please slow down")]
|
#[error("too may requests, please slow down")]
|
||||||
|
@ -27,7 +27,7 @@ pub enum Error {
|
||||||
#[error("failed to extract the request body")]
|
#[error("failed to extract the request body")]
|
||||||
BytesRejection,
|
BytesRejection,
|
||||||
|
|
||||||
#[error("unexpected error - {0}")]
|
#[error("unknown error - {0}")]
|
||||||
Other(String),
|
Other(String),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,11 +1,16 @@
|
||||||
|
//! HTTP `/fs/createdir` Request and Response types
|
||||||
|
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
|
/// `/fs/createdir` Request
|
||||||
#[derive(Debug, Serialize, Deserialize, Clone)]
|
#[derive(Debug, Serialize, Deserialize, Clone)]
|
||||||
pub struct Request {
|
pub struct Request {
|
||||||
pub path: String,
|
pub path: String,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// `/fs/createdir` Reponse
|
||||||
#[derive(Debug, Serialize, Deserialize, Clone)]
|
#[derive(Debug, Serialize, Deserialize, Clone)]
|
||||||
pub struct Response {
|
pub struct Response {
|
||||||
|
/// Directory created?
|
||||||
pub created: bool,
|
pub created: bool,
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,10 @@
|
||||||
|
//! HTTP `/fs/delete` Request type
|
||||||
|
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
|
/// `/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
|
||||||
pub path: String,
|
pub path: String,
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,10 @@
|
||||||
|
//! HTTP `/fs/download` Request type
|
||||||
|
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
|
/// `/fs/download` Request
|
||||||
#[derive(Debug, Serialize, Deserialize, Clone)]
|
#[derive(Debug, Serialize, Deserialize, Clone)]
|
||||||
pub struct Request {
|
pub struct Request {
|
||||||
|
/// Path of file to download
|
||||||
pub path: String,
|
pub path: String,
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,25 +1,36 @@
|
||||||
|
//! HTTP `/fs/list` Request, Response, FileInfo and DirInfo types
|
||||||
|
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
|
/// `/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
|
||||||
#[derive(Debug, Serialize, Deserialize, Clone)]
|
#[derive(Debug, Serialize, Deserialize, Clone)]
|
||||||
pub struct Response {
|
pub struct Response {
|
||||||
pub files: Vec<FileInfo>,
|
pub files: Vec<FileInfo>,
|
||||||
pub dirs: Vec<DirInfo>,
|
pub dirs: Vec<DirInfo>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Info about a file
|
||||||
#[derive(Debug, Serialize, Deserialize, Clone)]
|
#[derive(Debug, Serialize, Deserialize, Clone)]
|
||||||
pub struct FileInfo {
|
pub struct FileInfo {
|
||||||
|
/// File name
|
||||||
pub name: String,
|
pub name: String,
|
||||||
|
/// File size
|
||||||
pub size: String,
|
pub size: String,
|
||||||
|
/// Latest modification of this file
|
||||||
pub modified: String,
|
pub modified: String,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Info about a directory
|
||||||
#[derive(Debug, Serialize, Deserialize, Clone)]
|
#[derive(Debug, Serialize, Deserialize, Clone)]
|
||||||
pub struct DirInfo {
|
pub struct DirInfo {
|
||||||
|
/// Directory name
|
||||||
pub name: String,
|
pub name: String,
|
||||||
|
/// Directory size (size of all files in directory)
|
||||||
pub size: String,
|
pub size: String,
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,11 +1,17 @@
|
||||||
|
//! HTTP `/fs/upload` Request and Response types
|
||||||
|
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
|
/// `/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
|
||||||
pub path: String,
|
pub path: String,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// `/fs/upload` Response
|
||||||
#[derive(Debug, Serialize, Deserialize, Clone)]
|
#[derive(Debug, Serialize, Deserialize, Clone)]
|
||||||
pub struct Response {
|
pub struct Response {
|
||||||
|
/// The file has been uploaded?
|
||||||
pub uploaded: bool,
|
pub uploaded: bool,
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue