mirror of
https://github.com/MedzikUser/HomeDisk.git
synced 2024-08-14 21:46:53 +00:00
comment code
This commit is contained in:
parent
d6f02632c5
commit
18b6cb21b1
16 changed files with 37 additions and 15 deletions
8
.github/workflows/build-release-binaries.yml
vendored
8
.github/workflows/build-release-binaries.yml
vendored
|
@ -6,10 +6,10 @@ on:
|
||||||
- '**'
|
- '**'
|
||||||
- '!website/**'
|
- '!website/**'
|
||||||
|
|
||||||
# pull_request:
|
# pull_request:
|
||||||
# paths:
|
# paths:
|
||||||
# - '**'
|
# - '**'
|
||||||
# - '!website/**'
|
# - '!website/**'
|
||||||
|
|
||||||
workflow_dispatch:
|
workflow_dispatch:
|
||||||
|
|
||||||
|
|
|
@ -10,12 +10,14 @@ pub enum Error {
|
||||||
Io(std::io::Error),
|
Io(std::io::Error),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// sqlx::Error
|
||||||
impl From<sqlx::Error> for Error {
|
impl From<sqlx::Error> for Error {
|
||||||
fn from(err: sqlx::Error) -> Self {
|
fn from(err: sqlx::Error) -> Self {
|
||||||
Error::SQLx(err)
|
Error::SQLx(err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// std::io::Error
|
||||||
impl From<std::io::Error> for Error {
|
impl From<std::io::Error> for Error {
|
||||||
fn from(err: std::io::Error) -> Self {
|
fn from(err: std::io::Error) -> Self {
|
||||||
Error::Io(err)
|
Error::Io(err)
|
||||||
|
|
|
@ -43,7 +43,7 @@ impl Database {
|
||||||
Ok(self.conn.execute(query).await?)
|
Ok(self.conn.execute(query).await?)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Find user
|
/// Search for a user
|
||||||
/// ```ignore,rust
|
/// ```ignore,rust
|
||||||
/// use homedisk_database::{Database, User};
|
/// use homedisk_database::{Database, User};
|
||||||
///
|
///
|
||||||
|
@ -52,7 +52,7 @@ impl Database {
|
||||||
/// db.find_user(&user.username, &user.password).await?;
|
/// db.find_user(&user.username, &user.password).await?;
|
||||||
/// ```
|
/// ```
|
||||||
pub async fn find_user(&self, username: &str, password: &str) -> Result<User, Error> {
|
pub async fn find_user(&self, username: &str, password: &str) -> Result<User, Error> {
|
||||||
debug!("Searching for user - {}", username);
|
debug!("Searching for a user - {}", username);
|
||||||
|
|
||||||
let query =
|
let query =
|
||||||
sqlx::query_as::<_, User>("SELECT * FROM user WHERE username = ? AND password = ?")
|
sqlx::query_as::<_, User>("SELECT * FROM user WHERE username = ? AND password = ?")
|
||||||
|
@ -74,7 +74,7 @@ impl Database {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Find user by UUID
|
/// Search for a user by UUID
|
||||||
/// ```ignore,rust
|
/// ```ignore,rust
|
||||||
/// use homedisk_database::{Database, User};
|
/// use homedisk_database::{Database, User};
|
||||||
///
|
///
|
||||||
|
@ -111,10 +111,12 @@ mod tests {
|
||||||
|
|
||||||
use crate::{Database, User};
|
use crate::{Database, User};
|
||||||
|
|
||||||
|
/// Utils to open database in tests
|
||||||
async fn open_db() -> Database {
|
async fn open_db() -> Database {
|
||||||
Database::open("sqlite::memory:").await.expect("open db")
|
Database::open("sqlite::memory:").await.expect("open db")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Utils to create a new user in tests
|
||||||
async fn new_user(db: &Database) {
|
async fn new_user(db: &Database) {
|
||||||
// create user table
|
// create user table
|
||||||
db.conn
|
db.conn
|
||||||
|
@ -129,11 +131,13 @@ mod tests {
|
||||||
db.create_user(&user).await.expect("create user");
|
db.create_user(&user).await.expect("create user");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Open database in memory
|
||||||
#[tokio::test]
|
#[tokio::test]
|
||||||
async fn open_db_in_memory() {
|
async fn open_db_in_memory() {
|
||||||
open_db().await;
|
open_db().await;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Create a new user
|
||||||
#[tokio::test]
|
#[tokio::test]
|
||||||
async fn create_user() {
|
async fn create_user() {
|
||||||
let db = open_db().await;
|
let db = open_db().await;
|
||||||
|
@ -141,6 +145,7 @@ mod tests {
|
||||||
new_user(&db).await;
|
new_user(&db).await;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Search for a user
|
||||||
#[tokio::test]
|
#[tokio::test]
|
||||||
async fn find_user() {
|
async fn find_user() {
|
||||||
let db = open_db().await;
|
let db = open_db().await;
|
||||||
|
@ -157,6 +162,7 @@ mod tests {
|
||||||
assert_eq!(res.password, user.password)
|
assert_eq!(res.password, user.password)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Search for a user with an invalid password to see if the user is returned (it shouldn't be)
|
||||||
#[tokio::test]
|
#[tokio::test]
|
||||||
async fn find_user_wrong_password() {
|
async fn find_user_wrong_password() {
|
||||||
let db = open_db().await;
|
let db = open_db().await;
|
||||||
|
@ -173,6 +179,7 @@ mod tests {
|
||||||
assert_eq!(err.to_string(), "user not found")
|
assert_eq!(err.to_string(), "user not found")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Search for a user who does not exist
|
||||||
#[tokio::test]
|
#[tokio::test]
|
||||||
async fn find_user_wrong_username() {
|
async fn find_user_wrong_username() {
|
||||||
let db = open_db().await;
|
let db = open_db().await;
|
||||||
|
@ -189,6 +196,7 @@ mod tests {
|
||||||
assert_eq!(err.to_string(), "user not found")
|
assert_eq!(err.to_string(), "user not found")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Search for a user by UUID
|
||||||
#[tokio::test]
|
#[tokio::test]
|
||||||
async fn find_user_by_id() {
|
async fn find_user_by_id() {
|
||||||
let db = open_db().await;
|
let db = open_db().await;
|
||||||
|
@ -202,13 +210,14 @@ mod tests {
|
||||||
assert_eq!(res.password, user.password)
|
assert_eq!(res.password, user.password)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Search for a user by UUID who does not exist
|
||||||
#[tokio::test]
|
#[tokio::test]
|
||||||
async fn find_user_wrong_id() {
|
async fn find_user_wrong_id() {
|
||||||
let db = open_db().await;
|
let db = open_db().await;
|
||||||
|
|
||||||
new_user(&db).await;
|
new_user(&db).await;
|
||||||
|
|
||||||
let other_user = User::new("other_user", "secret@passphrase123!");
|
let other_user = User::new("other_user", "my secret passphrase");
|
||||||
|
|
||||||
let err = db.find_user_by_id(other_user.id).await.unwrap_err();
|
let err = db.find_user_by_id(other_user.id).await.unwrap_err();
|
||||||
|
|
||||||
|
|
|
@ -8,6 +8,7 @@ use homedisk_types::{
|
||||||
|
|
||||||
use crate::middleware::{create_token, validate_json};
|
use crate::middleware::{create_token, validate_json};
|
||||||
|
|
||||||
|
/// Handle `/auth/login` requests
|
||||||
pub async fn handle(
|
pub async fn handle(
|
||||||
Extension(db): Extension<Database>,
|
Extension(db): Extension<Database>,
|
||||||
Extension(config): Extension<Config>,
|
Extension(config): Extension<Config>,
|
||||||
|
@ -16,10 +17,13 @@ pub async fn handle(
|
||||||
// validate json request
|
// validate json request
|
||||||
let request = validate_json::<Request>(request)?;
|
let request = validate_json::<Request>(request)?;
|
||||||
|
|
||||||
|
// create `User` type
|
||||||
let user = User::new(&request.username, &request.password);
|
let user = User::new(&request.username, &request.password);
|
||||||
|
|
||||||
|
// search for a user in database
|
||||||
let response = match db.find_user(&user.username, &user.password).await {
|
let response = match db.find_user(&user.username, &user.password).await {
|
||||||
Ok(user) => {
|
Ok(user) => {
|
||||||
|
// 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)?;
|
||||||
|
|
||||||
Response::LoggedIn {
|
Response::LoggedIn {
|
||||||
|
|
|
@ -9,6 +9,7 @@ use homedisk_types::{
|
||||||
|
|
||||||
use crate::middleware::validate_jwt;
|
use crate::middleware::validate_jwt;
|
||||||
|
|
||||||
|
/// Handle `/auth/whoami` requests
|
||||||
pub async fn handle(
|
pub async fn handle(
|
||||||
db: Extension<Database>,
|
db: Extension<Database>,
|
||||||
config: Extension<Config>,
|
config: Extension<Config>,
|
||||||
|
|
|
@ -13,6 +13,7 @@ use homedisk_types::{
|
||||||
use crate::fs::validate_path;
|
use crate::fs::validate_path;
|
||||||
use crate::middleware::{find_user, validate_jwt};
|
use crate::middleware::{find_user, validate_jwt};
|
||||||
|
|
||||||
|
/// Handle `/fs/delete` requests
|
||||||
pub async fn handle(
|
pub async fn handle(
|
||||||
Extension(db): Extension<Database>,
|
Extension(db): Extension<Database>,
|
||||||
Extension(config): Extension<Config>,
|
Extension(config): Extension<Config>,
|
||||||
|
|
|
@ -31,6 +31,7 @@ fn dir_size(path: impl Into<PathBuf>) -> io::Result<u64> {
|
||||||
dir_size(fs::read_dir(path.into())?)
|
dir_size(fs::read_dir(path.into())?)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Handle `/fs/list` requests
|
||||||
pub async fn handle(
|
pub async fn handle(
|
||||||
Extension(db): Extension<Database>,
|
Extension(db): Extension<Database>,
|
||||||
Extension(config): Extension<Config>,
|
Extension(config): Extension<Config>,
|
||||||
|
|
|
@ -10,7 +10,7 @@ pub fn app() -> axum::Router {
|
||||||
axum::Router::new()
|
axum::Router::new()
|
||||||
.route("/list", post(list::handle))
|
.route("/list", post(list::handle))
|
||||||
.route("/upload", post(upload::handle))
|
.route("/upload", post(upload::handle))
|
||||||
.route("/delete", delete(upload::handle))
|
.route("/delete", delete(delete::handle))
|
||||||
.route("/download", get(download::handle))
|
.route("/download", get(download::handle))
|
||||||
.route("/createdir", post(create_dir::handle))
|
.route("/createdir", post(create_dir::handle))
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,6 +10,7 @@ use homedisk_types::config::types::Config;
|
||||||
use log::{debug, info};
|
use log::{debug, info};
|
||||||
use tower_http::cors::{AllowOrigin, CorsLayer};
|
use tower_http::cors::{AllowOrigin, CorsLayer};
|
||||||
|
|
||||||
|
/// Handle `/health-check` requests
|
||||||
async fn health_check() -> &'static str {
|
async fn health_check() -> &'static str {
|
||||||
"I'm alive!"
|
"I'm alive!"
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,6 +2,7 @@ use homedisk_types::errors::{AuthError, ServerError};
|
||||||
use jsonwebtoken::TokenData;
|
use jsonwebtoken::TokenData;
|
||||||
use rust_utilities::crypto::jsonwebtoken::{Claims, Token};
|
use rust_utilities::crypto::jsonwebtoken::{Claims, 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()) {
|
||||||
Ok(claims) => Ok(claims),
|
Ok(claims) => Ok(claims),
|
||||||
|
|
|
@ -2,6 +2,7 @@ use homedisk_database::{Database, User};
|
||||||
use homedisk_types::errors::{AuthError, ServerError};
|
use homedisk_types::errors::{AuthError, ServerError};
|
||||||
use rust_utilities::crypto::jsonwebtoken::{Claims, Token};
|
use rust_utilities::crypto::jsonwebtoken::{Claims, Token};
|
||||||
|
|
||||||
|
/// Create user token
|
||||||
pub fn create_token(user: &User, secret: &[u8], expires: i64) -> Result<String, ServerError> {
|
pub fn create_token(user: &User, secret: &[u8], expires: i64) -> Result<String, ServerError> {
|
||||||
let token = Token::new(secret, Claims::new(user.id.clone(), expires));
|
let token = Token::new(secret, Claims::new(user.id.clone(), expires));
|
||||||
|
|
||||||
|
@ -11,6 +12,7 @@ pub fn create_token(user: &User, secret: &[u8], expires: i64) -> Result<String,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// 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 {
|
||||||
Ok(user) => Ok(user),
|
Ok(user) => Ok(user),
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
use axum::{extract::rejection::JsonRejection, Json};
|
use axum::{extract::rejection::JsonRejection, Json};
|
||||||
use homedisk_types::errors::ServerError;
|
use homedisk_types::errors::ServerError;
|
||||||
|
|
||||||
|
/// Validate json request
|
||||||
pub fn validate_json<Typ>(
|
pub fn validate_json<Typ>(
|
||||||
payload: Result<Json<Typ>, JsonRejection>,
|
payload: Result<Json<Typ>, JsonRejection>,
|
||||||
) -> Result<Json<Typ>, ServerError> {
|
) -> Result<Json<Typ>, ServerError> {
|
||||||
|
|
|
@ -9,7 +9,7 @@ use super::types::Config;
|
||||||
impl Config {
|
impl Config {
|
||||||
/// Parse configuration file
|
/// Parse configuration file
|
||||||
pub fn parse() -> Result<Config> {
|
pub fn parse() -> Result<Config> {
|
||||||
// configuration file path
|
// config file path
|
||||||
let config_dir = option_return!(dirs::config_dir(), "get config dir")?;
|
let config_dir = option_return!(dirs::config_dir(), "get 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());
|
||||||
|
|
||||||
|
|
|
@ -23,7 +23,7 @@ impl User {
|
||||||
// change username to lowercase
|
// change username to lowercase
|
||||||
let username = username.to_lowercase();
|
let username = username.to_lowercase();
|
||||||
|
|
||||||
// create user UUID
|
// generate a user UUID
|
||||||
let sha1_name = CryptographicHash::hash(Algorithm::SHA1, username.as_bytes());
|
let sha1_name = CryptographicHash::hash(Algorithm::SHA1, username.as_bytes());
|
||||||
let id = Uuid::new_v5(&Uuid::NAMESPACE_X500, &sha1_name).to_string();
|
let id = Uuid::new_v5(&Uuid::NAMESPACE_X500, &sha1_name).to_string();
|
||||||
|
|
||||||
|
|
|
@ -30,7 +30,7 @@ pub enum ServerError {
|
||||||
#[error("failed to extract the request body")]
|
#[error("failed to extract the request body")]
|
||||||
BytesRejection,
|
BytesRejection,
|
||||||
|
|
||||||
#[error("unexcepted error")]
|
#[error("unexpected error - {0}")]
|
||||||
Other(String),
|
Other(String),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,8 +1,7 @@
|
||||||
pub mod auth;
|
pub mod auth;
|
||||||
pub mod config;
|
pub mod config;
|
||||||
pub mod errors;
|
|
||||||
pub mod macros;
|
|
||||||
|
|
||||||
#[cfg(feature = "database")]
|
#[cfg(feature = "database")]
|
||||||
pub mod database;
|
pub mod database;
|
||||||
|
pub mod errors;
|
||||||
pub mod fs;
|
pub mod fs;
|
||||||
|
pub mod macros;
|
||||||
|
|
Loading…
Reference in a new issue