This commit is contained in:
StNicolay 2024-08-04 12:34:46 +03:00
parent bac5584b46
commit 7669a02a95
Signed by: StNicolay
GPG Key ID: 9693D04DCD962B0D
15 changed files with 37 additions and 38 deletions

View File

@ -1,9 +1,6 @@
use futures::Stream; use db::permissions::PermissionType;
use uuid::Uuid;
use crate::Pool; use crate::prelude::*;
use super::permissions::PermissionType;
pub async fn insert( pub async fn insert(
file_id: Uuid, file_id: Uuid,

View File

@ -1,7 +1,4 @@
use futures::{Stream, TryStreamExt}; use crate::{db::permissions::PermissionRaw, prelude::*};
use uuid::Uuid;
use crate::{db::permissions::PermissionRaw, Pool};
use super::permissions::PermissionType; use super::permissions::PermissionType;

View File

@ -1,11 +1,6 @@
use std::collections::HashMap; use std::collections::HashMap;
use axum::http::StatusCode; use crate::prelude::*;
use futures::TryStreamExt as _;
use serde::{Deserialize, Serialize};
use uuid::Uuid;
use crate::Pool;
#[derive(sqlx::Type, Debug, Serialize, Deserialize)] #[derive(sqlx::Type, Debug, Serialize, Deserialize)]
#[sqlx(type_name = "permission")] #[sqlx(type_name = "permission")]

View File

@ -1,8 +1,4 @@
use futures::{stream::BoxStream, Stream, TryStreamExt}; use crate::prelude::*;
use serde::Serialize;
use uuid::Uuid;
use crate::Pool;
/// Creates user and returns its id /// Creates user and returns its id
pub async fn create_user( pub async fn create_user(

View File

@ -52,6 +52,7 @@ pub async fn register(
params params
.validate() .validate()
.map_err(|err| Either::E1((StatusCode::BAD_REQUEST, err.to_string())))?; .map_err(|err| Either::E1((StatusCode::BAD_REQUEST, err.to_string())))?;
let password = HashedBytes::hash_bytes(params.password.as_bytes()).as_bytes(); let password = HashedBytes::hash_bytes(params.password.as_bytes()).as_bytes();
let Some(id) = db::users::create_user(&params.username, &params.email, &password, &pool) let Some(id) = db::users::create_user(&params.username, &params.email, &password, &pool)
.await .await
@ -63,6 +64,7 @@ pub async fn register(
"Either the user name or the email are taken".to_owned(), "Either the user name or the email are taken".to_owned(),
))); )));
}; };
let token = Claims::new(id).encode().map_err(Either::E2)?; let token = Claims::new(id).encode().map_err(Either::E2)?;
Ok(Json(token)) Ok(Json(token))
} }

View File

@ -1,7 +1,6 @@
use std::collections::{HashMap, HashSet}; use std::collections::{HashMap, HashSet};
use axum::extract::multipart::{self, Multipart}; use axum::extract::multipart::{self, Multipart};
use futures::TryStreamExt;
use tokio::io::AsyncWrite; use tokio::io::AsyncWrite;
use crate::prelude::*; use crate::prelude::*;
@ -47,6 +46,7 @@ pub async fn upload(
.try_collect() .try_collect()
.await .await
.handle_internal()?; .handle_internal()?;
let mut result = HashMap::new(); let mut result = HashMap::new();
while let Ok(Some(mut field)) = multi.next_field().await { while let Ok(Some(mut field)) = multi.next_field().await {
let Some(file_name) = field.file_name().map(ToOwned::to_owned) else { let Some(file_name) = field.file_name().map(ToOwned::to_owned) else {
@ -55,10 +55,15 @@ pub async fn upload(
if existing_names.contains(&file_name) { if existing_names.contains(&file_name) {
continue; continue;
} }
if file_name.len() > 50 {
continue;
}
let Ok((file_id, mut file)) = state.storage.create().await else { let Ok((file_id, mut file)) = state.storage.create().await else {
tracing::warn!("Couldn't create uuid for new file"); tracing::warn!("Couldn't create uuid for new file");
continue; continue;
}; };
let is_success = create_file( let is_success = create_file(
file_id, file_id,
&mut file, &mut file,
@ -72,6 +77,7 @@ pub async fn upload(
let _ = state.storage.delete(file_id).await; let _ = state.storage.delete(file_id).await;
continue; continue;
} }
result.insert(file_name, file_id); result.insert(file_name, file_id);
} }

View File

@ -1,5 +1,3 @@
use futures::TryStreamExt;
use crate::prelude::*; use crate::prelude::*;
#[derive(Deserialize, Debug)] #[derive(Deserialize, Debug)]

View File

@ -1,4 +1,3 @@
use futures::TryStreamExt;
use tokio::try_join; use tokio::try_join;
use super::list::Params; use super::list::Params;
@ -31,10 +30,12 @@ pub async fn structure(
.await .await
.handle_internal()? .handle_internal()?
.ok_or(StatusCode::NOT_FOUND)?; .ok_or(StatusCode::NOT_FOUND)?;
let folder = db::folder::get_by_id(folder_id, &pool) let folder = db::folder::get_by_id(folder_id, &pool)
.await .await
.handle_internal()? .handle_internal()?
.ok_or(StatusCode::NOT_FOUND)?; .ok_or(StatusCode::NOT_FOUND)?;
let mut response: FolderStructure = folder.into(); let mut response: FolderStructure = folder.into();
let mut stack = vec![&mut response]; let mut stack = vec![&mut response];
while let Some(folder) = stack.pop() { while let Some(folder) = stack.pop() {
@ -49,5 +50,6 @@ pub async fn structure(
folder.files = files; folder.files = files;
stack.extend(folder.folders.iter_mut()); stack.extend(folder.folders.iter_mut());
} }
Ok(Json(response)) Ok(Json(response))
} }

View File

@ -1,4 +1,3 @@
use futures::TryStreamExt;
use tokio::try_join; use tokio::try_join;
use crate::prelude::*; use crate::prelude::*;

View File

@ -26,6 +26,14 @@ pub async fn set(
.handle_internal()? .handle_internal()?
.can_manage_guard()?; .can_manage_guard()?;
let folder_info = db::folder::get_by_id(params.folder_id, &pool)
.await
.handle_internal()?
.ok_or(StatusCode::NOT_FOUND)?;
if folder_info.owner_id == params.user_id {
return Err(StatusCode::BAD_REQUEST);
}
db::permissions::insert( db::permissions::insert(
params.user_id, params.user_id,
params.folder_id, params.folder_id,

View File

@ -1,5 +1,3 @@
use futures::TryStreamExt;
use crate::prelude::*; use crate::prelude::*;
pub async fn delete( pub async fn delete(

View File

@ -18,9 +18,9 @@ pub async fn put(
params params
.validate() .validate()
.map_err(|err| (StatusCode::BAD_REQUEST, err.to_string()))?; .map_err(|err| (StatusCode::BAD_REQUEST, err.to_string()))?;
let info = db::users::update(claims.user_id, &params.username, &params.email, &pool) db::users::update(claims.user_id, &params.username, &params.email, &pool)
.await .await
.handle_internal() .handle_internal()
.map_err(|status| (status, String::new()))?; .map_err(|status| (status, String::new()))
Ok(Json(info)) .map(Json)
} }

View File

@ -1,5 +1,3 @@
use futures::{future, TryStreamExt};
use crate::prelude::*; use crate::prelude::*;
#[derive(Deserialize, Debug)] #[derive(Deserialize, Debug)]
@ -11,11 +9,11 @@ pub async fn search(
State(pool): State<Pool>, State(pool): State<Pool>,
Query(params): Query<Params>, Query(params): Query<Params>,
) -> sqlx::Result<Json<Vec<db::users::UserSearch>>, StatusCode> { ) -> sqlx::Result<Json<Vec<db::users::UserSearch>>, StatusCode> {
let users = db::users::search_for_user(&params.search_string, &pool) db::users::search_for_user(&params.search_string, &pool)
.take(20) .take(20)
.try_filter(|user| future::ready(user.similarity > 0.1)) .try_filter(|user| future::ready(user.similarity > 0.1))
.try_collect() .try_collect()
.await .await
.handle_internal()?; .handle_internal()
Ok(Json(users)) .map(Json)
} }

View File

@ -5,14 +5,14 @@ use std::{
}; };
use axum::body::Bytes; use axum::body::Bytes;
use futures::{Stream, StreamExt};
use sha2::Digest as _; use sha2::Digest as _;
use tokio::{ use tokio::{
fs, fs,
io::{AsyncWrite, AsyncWriteExt, BufWriter}, io::{AsyncWrite, AsyncWriteExt, BufWriter},
}; };
use tokio_util::io::StreamReader; use tokio_util::io::StreamReader;
use uuid::Uuid;
use crate::prelude::*;
#[derive(Clone)] #[derive(Clone)]
pub struct FileStorage(Arc<Path>); pub struct FileStorage(Arc<Path>);
@ -95,6 +95,7 @@ impl FileStorage {
const BUF_CAP: usize = 64 * 1024 * 1024; // 64 MiB const BUF_CAP: usize = 64 * 1024 * 1024; // 64 MiB
let mut hash = sha2::Sha512::new(); let mut hash = sha2::Sha512::new();
let mut size: i64 = 0; let mut size: i64 = 0;
let stream = stream.map(|value| { let stream = stream.map(|value| {
let bytes = value.map_err(io::Error::other)?; let bytes = value.map_err(io::Error::other)?;
hash.update(&bytes); hash.update(&bytes);
@ -104,10 +105,12 @@ impl FileStorage {
.ok_or_else(|| io::Error::other(anyhow::anyhow!("Size calculation overflow")))?; .ok_or_else(|| io::Error::other(anyhow::anyhow!("Size calculation overflow")))?;
io::Result::Ok(bytes) io::Result::Ok(bytes)
}); });
let mut reader = StreamReader::new(stream); let mut reader = StreamReader::new(stream);
let mut writer = BufWriter::with_capacity(BUF_CAP, file); let mut writer = BufWriter::with_capacity(BUF_CAP, file);
tokio::io::copy_buf(&mut reader, &mut writer).await?; tokio::io::copy_buf(&mut reader, &mut writer).await?;
writer.flush().await?; writer.flush().await?;
let hash = hash.finalize().to_vec(); let hash = hash.finalize().to_vec();
Ok((hash, size)) Ok((hash, size))
} }

View File

@ -3,6 +3,6 @@ pub use axum::{
extract::{Json, Query, State}, extract::{Json, Query, State},
http::StatusCode, http::StatusCode,
}; };
pub use futures::StreamExt as _; pub use futures::{future, stream::BoxStream, Stream, StreamExt as _, TryStreamExt as _};
pub use serde::{Deserialize, Serialize}; pub use serde::{Deserialize, Serialize};
pub use uuid::Uuid; pub use uuid::Uuid;