From 8605b81e7b106d424f149b645d51c74ae2930050 Mon Sep 17 00:00:00 2001 From: Radical Date: Sat, 24 May 2025 01:09:17 +0200 Subject: [PATCH] style: cargo clippy && format --- build.rs | 4 +- src/api/v1/auth/login.rs | 33 +++-- src/api/v1/auth/mod.rs | 11 +- src/api/v1/auth/refresh.rs | 18 +-- src/api/v1/auth/register.rs | 18 ++- src/api/v1/auth/revoke.rs | 18 ++- src/api/v1/invites/id.rs | 2 +- src/api/v1/servers/mod.rs | 11 +- src/api/v1/servers/uuid/channels/mod.rs | 5 +- .../v1/servers/uuid/channels/uuid/messages.rs | 5 +- src/api/v1/servers/uuid/channels/uuid/mod.rs | 7 +- .../v1/servers/uuid/channels/uuid/socket.rs | 11 +- src/api/v1/servers/uuid/icon.rs | 21 ++- src/api/v1/servers/uuid/invites/mod.rs | 2 +- src/api/v1/servers/uuid/mod.rs | 4 +- src/api/v1/servers/uuid/roles/mod.rs | 5 +- src/api/v1/servers/uuid/roles/uuid.rs | 5 +- src/api/v1/stats.rs | 2 +- src/api/v1/users/me.rs | 22 ++- src/api/v1/users/mod.rs | 8 +- src/api/v1/users/uuid.rs | 8 +- src/config.rs | 2 +- src/error.rs | 25 ++-- src/main.rs | 38 +++-- src/structs.rs | 134 ++++++++++-------- src/utils.rs | 33 +++-- 26 files changed, 274 insertions(+), 178 deletions(-) diff --git a/build.rs b/build.rs index 284ad12..3a8149e 100644 --- a/build.rs +++ b/build.rs @@ -1,3 +1,3 @@ fn main() { - println!("cargo:rerun-if-changed=migrations"); -} \ No newline at end of file + println!("cargo:rerun-if-changed=migrations"); +} diff --git a/src/api/v1/auth/login.rs b/src/api/v1/auth/login.rs index 8ad345e..c3e8bc7 100644 --- a/src/api/v1/auth/login.rs +++ b/src/api/v1/auth/login.rs @@ -2,13 +2,17 @@ use std::time::{SystemTime, UNIX_EPOCH}; use actix_web::{HttpResponse, post, web}; use argon2::{PasswordHash, PasswordVerifier}; -use diesel::{dsl::insert_into, ExpressionMethods, QueryDsl}; +use diesel::{ExpressionMethods, QueryDsl, dsl::insert_into}; use diesel_async::RunQueryDsl; use serde::Deserialize; use uuid::Uuid; use crate::{ - error::Error, api::v1::auth::{EMAIL_REGEX, PASSWORD_REGEX, USERNAME_REGEX}, schema::*, utils::{generate_access_token, generate_refresh_token, refresh_token_cookie}, Data + Data, + api::v1::auth::{EMAIL_REGEX, PASSWORD_REGEX, USERNAME_REGEX}, + error::Error, + schema::*, + utils::{generate_access_token, generate_refresh_token, refresh_token_cookie}, }; use super::Response; @@ -79,34 +83,45 @@ async fn login( ) -> Result { let mut conn = data.pool.get().await?; - let parsed_hash = PasswordHash::new(&database_password).map_err(|e| Error::PasswordHashError(e.to_string()))?; + let parsed_hash = PasswordHash::new(&database_password) + .map_err(|e| Error::PasswordHashError(e.to_string()))?; if data .argon2 .verify_password(request_password.as_bytes(), &parsed_hash) .is_err() { - return Err(Error::Unauthorized("Wrong username or password".to_string())); + return Err(Error::Unauthorized( + "Wrong username or password".to_string(), + )); } let refresh_token = generate_refresh_token()?; let access_token = generate_access_token()?; - let current_time = SystemTime::now() - .duration_since(UNIX_EPOCH)? - .as_secs() as i64; + let current_time = SystemTime::now().duration_since(UNIX_EPOCH)?.as_secs() as i64; use refresh_tokens::dsl as rdsl; insert_into(refresh_tokens::table) - .values((rdsl::token.eq(&refresh_token), rdsl::uuid.eq(uuid), rdsl::created_at.eq(current_time), rdsl::device_name.eq(device_name))) + .values(( + rdsl::token.eq(&refresh_token), + rdsl::uuid.eq(uuid), + rdsl::created_at.eq(current_time), + rdsl::device_name.eq(device_name), + )) .execute(&mut conn) .await?; use access_tokens::dsl as adsl; insert_into(access_tokens::table) - .values((adsl::token.eq(&access_token), adsl::refresh_token.eq(&refresh_token), adsl::uuid.eq(uuid), adsl::created_at.eq(current_time))) + .values(( + adsl::token.eq(&access_token), + adsl::refresh_token.eq(&refresh_token), + adsl::uuid.eq(uuid), + adsl::created_at.eq(current_time), + )) .execute(&mut conn) .await?; diff --git a/src/api/v1/auth/mod.rs b/src/api/v1/auth/mod.rs index 249ec4b..2bc0d0b 100644 --- a/src/api/v1/auth/mod.rs +++ b/src/api/v1/auth/mod.rs @@ -10,7 +10,7 @@ use regex::Regex; use serde::Serialize; use uuid::Uuid; -use crate::{error::Error, Conn, schema::access_tokens::dsl}; +use crate::{Conn, error::Error, schema::access_tokens::dsl}; mod login; mod refresh; @@ -39,10 +39,7 @@ pub fn web() -> Scope { .service(revoke::res) } -pub async fn check_access_token( - access_token: &str, - conn: &mut Conn, -) -> Result { +pub async fn check_access_token(access_token: &str, conn: &mut Conn) -> Result { let (uuid, created_at): (Uuid, i64) = dsl::access_tokens .filter(dsl::token.eq(access_token)) .select((dsl::uuid, dsl::created_at)) @@ -56,9 +53,7 @@ pub async fn check_access_token( } })?; - let current_time = SystemTime::now() - .duration_since(UNIX_EPOCH)? - .as_secs() as i64; + let current_time = SystemTime::now().duration_since(UNIX_EPOCH)?.as_secs() as i64; let lifetime = current_time - created_at; diff --git a/src/api/v1/auth/refresh.rs b/src/api/v1/auth/refresh.rs index 468945d..303748a 100644 --- a/src/api/v1/auth/refresh.rs +++ b/src/api/v1/auth/refresh.rs @@ -1,11 +1,17 @@ use actix_web::{HttpRequest, HttpResponse, post, web}; -use diesel::{delete, update, ExpressionMethods, QueryDsl}; +use diesel::{ExpressionMethods, QueryDsl, delete, update}; use diesel_async::RunQueryDsl; use log::error; use std::time::{SystemTime, UNIX_EPOCH}; use crate::{ - error::Error, schema::{access_tokens::{self, dsl}, refresh_tokens::{self, dsl as rdsl}}, utils::{generate_access_token, generate_refresh_token, refresh_token_cookie}, Data + Data, + error::Error, + schema::{ + access_tokens::{self, dsl}, + refresh_tokens::{self, dsl as rdsl}, + }, + utils::{generate_access_token, generate_refresh_token, refresh_token_cookie}, }; use super::Response; @@ -20,9 +26,7 @@ pub async fn res(req: HttpRequest, data: web::Data) -> Result) -> Result 1987200 { let new_refresh_token = generate_refresh_token(); diff --git a/src/api/v1/auth/register.rs b/src/api/v1/auth/register.rs index 3add620..75aeb9d 100644 --- a/src/api/v1/auth/register.rs +++ b/src/api/v1/auth/register.rs @@ -5,14 +5,22 @@ use argon2::{ PasswordHasher, password_hash::{SaltString, rand_core::OsRng}, }; -use diesel::{dsl::insert_into, ExpressionMethods}; +use diesel::{ExpressionMethods, dsl::insert_into}; use diesel_async::RunQueryDsl; use serde::{Deserialize, Serialize}; use uuid::Uuid; use super::Response; use crate::{ - api::v1::auth::{EMAIL_REGEX, PASSWORD_REGEX, USERNAME_REGEX}, error::Error, schema::{access_tokens::{self, dsl as adsl}, refresh_tokens::{self, dsl as rdsl}, users::{self, dsl as udsl}}, utils::{generate_access_token, generate_refresh_token, refresh_token_cookie}, Data + Data, + api::v1::auth::{EMAIL_REGEX, PASSWORD_REGEX, USERNAME_REGEX}, + error::Error, + schema::{ + access_tokens::{self, dsl as adsl}, + refresh_tokens::{self, dsl as rdsl}, + users::{self, dsl as udsl}, + }, + utils::{generate_access_token, generate_refresh_token, refresh_token_cookie}, }; #[derive(Deserialize)] @@ -107,9 +115,7 @@ pub async fn res( let refresh_token = generate_refresh_token()?; let access_token = generate_access_token()?; - let current_time = SystemTime::now() - .duration_since(UNIX_EPOCH)? - .as_secs() as i64; + let current_time = SystemTime::now().duration_since(UNIX_EPOCH)?.as_secs() as i64; insert_into(refresh_tokens::table) .values(( @@ -133,7 +139,7 @@ pub async fn res( return Ok(HttpResponse::Ok() .cookie(refresh_token_cookie(refresh_token)) - .json(Response { access_token })) + .json(Response { access_token })); } Ok(HttpResponse::InternalServerError().finish()) diff --git a/src/api/v1/auth/revoke.rs b/src/api/v1/auth/revoke.rs index 116ed5c..2e95884 100644 --- a/src/api/v1/auth/revoke.rs +++ b/src/api/v1/auth/revoke.rs @@ -1,10 +1,17 @@ use actix_web::{HttpRequest, HttpResponse, post, web}; use argon2::{PasswordHash, PasswordVerifier}; -use diesel::{delete, ExpressionMethods, QueryDsl}; +use diesel::{ExpressionMethods, QueryDsl, delete}; use diesel_async::RunQueryDsl; use serde::Deserialize; -use crate::{api::v1::auth::check_access_token, error::Error, schema::users::dsl as udsl, schema::refresh_tokens::{self, dsl as rdsl}, utils::get_auth_header, Data}; +use crate::{ + Data, + api::v1::auth::check_access_token, + error::Error, + schema::refresh_tokens::{self, dsl as rdsl}, + schema::users::dsl as udsl, + utils::get_auth_header, +}; #[derive(Deserialize)] struct RevokeRequest { @@ -33,14 +40,17 @@ pub async fn res( .get_result(&mut conn) .await?; - let hashed_password = PasswordHash::new(&database_password).map_err(|e| Error::PasswordHashError(e.to_string()))?; + let hashed_password = PasswordHash::new(&database_password) + .map_err(|e| Error::PasswordHashError(e.to_string()))?; if data .argon2 .verify_password(revoke_request.password.as_bytes(), &hashed_password) .is_err() { - return Err(Error::Unauthorized("Wrong username or password".to_string())); + return Err(Error::Unauthorized( + "Wrong username or password".to_string(), + )); } delete(refresh_tokens::table) diff --git a/src/api/v1/invites/id.rs b/src/api/v1/invites/id.rs index 67f10af..601d9db 100644 --- a/src/api/v1/invites/id.rs +++ b/src/api/v1/invites/id.rs @@ -1,9 +1,9 @@ use actix_web::{HttpRequest, HttpResponse, get, post, web}; use crate::{ - error::Error, Data, api::v1::auth::check_access_token, + error::Error, structs::{Guild, Invite, Member}, utils::get_auth_header, }; diff --git a/src/api/v1/servers/mod.rs b/src/api/v1/servers/mod.rs index 8e2e186..76a4c16 100644 --- a/src/api/v1/servers/mod.rs +++ b/src/api/v1/servers/mod.rs @@ -1,9 +1,15 @@ -use actix_web::{get, post, web, HttpRequest, HttpResponse, Scope}; +use actix_web::{HttpRequest, HttpResponse, Scope, get, post, web}; use serde::Deserialize; mod uuid; -use crate::{error::Error, api::v1::auth::check_access_token, structs::{Guild, StartAmountQuery}, utils::get_auth_header, Data}; +use crate::{ + Data, + api::v1::auth::check_access_token, + error::Error, + structs::{Guild, StartAmountQuery}, + utils::get_auth_header, +}; #[derive(Deserialize)] struct GuildInfo { @@ -63,4 +69,3 @@ pub async fn get( Ok(HttpResponse::Ok().json(guilds)) } - diff --git a/src/api/v1/servers/uuid/channels/mod.rs b/src/api/v1/servers/uuid/channels/mod.rs index 4348422..0c515ef 100644 --- a/src/api/v1/servers/uuid/channels/mod.rs +++ b/src/api/v1/servers/uuid/channels/mod.rs @@ -1,7 +1,7 @@ use crate::{ - error::Error, Data, api::v1::auth::check_access_token, + error::Error, structs::{Channel, Member}, utils::get_auth_header, }; @@ -43,8 +43,7 @@ pub async fn get( let channels = Channel::fetch_all(&data.pool, guild_uuid).await?; - data - .set_cache_key(format!("{}_channels", guild_uuid), channels.clone(), 1800) + data.set_cache_key(format!("{}_channels", guild_uuid), channels.clone(), 1800) .await?; Ok(HttpResponse::Ok().json(channels)) diff --git a/src/api/v1/servers/uuid/channels/uuid/messages.rs b/src/api/v1/servers/uuid/channels/uuid/messages.rs index 954651e..66ec80d 100644 --- a/src/api/v1/servers/uuid/channels/uuid/messages.rs +++ b/src/api/v1/servers/uuid/channels/uuid/messages.rs @@ -1,7 +1,7 @@ use crate::{ - error::Error, Data, api::v1::auth::check_access_token, + error::Error, structs::{Channel, Member}, utils::get_auth_header, }; @@ -41,8 +41,7 @@ pub async fn get( } else { channel = Channel::fetch_one(&mut conn, channel_uuid).await?; - data - .set_cache_key(format!("{}", channel_uuid), channel.clone(), 60) + data.set_cache_key(format!("{}", channel_uuid), channel.clone(), 60) .await?; } diff --git a/src/api/v1/servers/uuid/channels/uuid/mod.rs b/src/api/v1/servers/uuid/channels/uuid/mod.rs index 4cf6013..54f90a7 100644 --- a/src/api/v1/servers/uuid/channels/uuid/mod.rs +++ b/src/api/v1/servers/uuid/channels/uuid/mod.rs @@ -2,14 +2,14 @@ pub mod messages; pub mod socket; use crate::{ - error::Error, Data, api::v1::auth::check_access_token, + error::Error, structs::{Channel, Member}, utils::get_auth_header, }; -use uuid::Uuid; use actix_web::{HttpRequest, HttpResponse, delete, get, web}; +use uuid::Uuid; #[get("{uuid}/channels/{channel_uuid}")] pub async fn get( @@ -37,8 +37,7 @@ pub async fn get( let channel = Channel::fetch_one(&mut conn, channel_uuid).await?; - data - .set_cache_key(format!("{}", channel_uuid), channel.clone(), 60) + data.set_cache_key(format!("{}", channel_uuid), channel.clone(), 60) .await?; Ok(HttpResponse::Ok().json(channel)) diff --git a/src/api/v1/servers/uuid/channels/uuid/socket.rs b/src/api/v1/servers/uuid/channels/uuid/socket.rs index 14cb7d9..8938842 100644 --- a/src/api/v1/servers/uuid/channels/uuid/socket.rs +++ b/src/api/v1/servers/uuid/channels/uuid/socket.rs @@ -26,7 +26,7 @@ pub async fn echo( // Get uuids from path let (guild_uuid, channel_uuid) = path.into_inner(); - let mut conn = data.pool.get().await.map_err(|e| crate::error::Error::from(e))?; + let mut conn = data.pool.get().await.map_err(crate::error::Error::from)?; // Authorize client using auth header let uuid = check_access_token(auth_header, &mut conn).await?; @@ -42,8 +42,7 @@ pub async fn echo( } else { channel = Channel::fetch_one(&mut conn, channel_uuid).await?; - data - .set_cache_key(format!("{}", channel_uuid), channel.clone(), 60) + data.set_cache_key(format!("{}", channel_uuid), channel.clone(), 60) .await?; } @@ -54,7 +53,11 @@ pub async fn echo( // aggregate continuation frames up to 1MiB .max_continuation_size(2_usize.pow(20)); - let mut pubsub = data.cache_pool.get_async_pubsub().await.map_err(|e| crate::error::Error::from(e))?; + let mut pubsub = data + .cache_pool + .get_async_pubsub() + .await + .map_err(crate::error::Error::from)?; let mut session_2 = session_1.clone(); diff --git a/src/api/v1/servers/uuid/icon.rs b/src/api/v1/servers/uuid/icon.rs index 297afa9..2155f55 100644 --- a/src/api/v1/servers/uuid/icon.rs +++ b/src/api/v1/servers/uuid/icon.rs @@ -1,8 +1,14 @@ -use actix_web::{put, web, HttpRequest, HttpResponse}; -use uuid::Uuid; +use actix_web::{HttpRequest, HttpResponse, put, web}; use futures_util::StreamExt as _; +use uuid::Uuid; -use crate::{error::Error, api::v1::auth::check_access_token, structs::{Guild, Member}, utils::get_auth_header, Data}; +use crate::{ + Data, + api::v1::auth::check_access_token, + error::Error, + structs::{Guild, Member}, + utils::get_auth_header, +}; #[put("{uuid}/icon")] pub async fn upload( @@ -30,7 +36,14 @@ pub async fn upload( bytes.extend_from_slice(&item?); } - guild.set_icon(&data.bunny_cdn, &mut conn, data.config.bunny.cdn_url.clone(), bytes).await?; + guild + .set_icon( + &data.bunny_cdn, + &mut conn, + data.config.bunny.cdn_url.clone(), + bytes, + ) + .await?; Ok(HttpResponse::Ok().finish()) } diff --git a/src/api/v1/servers/uuid/invites/mod.rs b/src/api/v1/servers/uuid/invites/mod.rs index badb3e0..13ad378 100644 --- a/src/api/v1/servers/uuid/invites/mod.rs +++ b/src/api/v1/servers/uuid/invites/mod.rs @@ -3,9 +3,9 @@ use serde::Deserialize; use uuid::Uuid; use crate::{ - error::Error, Data, api::v1::auth::check_access_token, + error::Error, structs::{Guild, Member}, utils::get_auth_header, }; diff --git a/src/api/v1/servers/uuid/mod.rs b/src/api/v1/servers/uuid/mod.rs index 47eff03..887fd06 100644 --- a/src/api/v1/servers/uuid/mod.rs +++ b/src/api/v1/servers/uuid/mod.rs @@ -2,14 +2,14 @@ use actix_web::{HttpRequest, HttpResponse, Scope, get, web}; use uuid::Uuid; mod channels; +mod icon; mod invites; mod roles; -mod icon; use crate::{ - error::Error, Data, api::v1::auth::check_access_token, + error::Error, structs::{Guild, Member}, utils::get_auth_header, }; diff --git a/src/api/v1/servers/uuid/roles/mod.rs b/src/api/v1/servers/uuid/roles/mod.rs index a2912f9..fe25d39 100644 --- a/src/api/v1/servers/uuid/roles/mod.rs +++ b/src/api/v1/servers/uuid/roles/mod.rs @@ -3,9 +3,9 @@ use actix_web::{HttpRequest, HttpResponse, get, post, web}; use serde::Deserialize; use crate::{ - error::Error, Data, api::v1::auth::check_access_token, + error::Error, structs::{Member, Role}, utils::get_auth_header, }; @@ -43,8 +43,7 @@ pub async fn get( let roles = Role::fetch_all(&mut conn, guild_uuid).await?; - data - .set_cache_key(format!("{}_roles", guild_uuid), roles.clone(), 1800) + data.set_cache_key(format!("{}_roles", guild_uuid), roles.clone(), 1800) .await?; Ok(HttpResponse::Ok().json(roles)) diff --git a/src/api/v1/servers/uuid/roles/uuid.rs b/src/api/v1/servers/uuid/roles/uuid.rs index 3279d16..8ca3cc5 100644 --- a/src/api/v1/servers/uuid/roles/uuid.rs +++ b/src/api/v1/servers/uuid/roles/uuid.rs @@ -1,7 +1,7 @@ use crate::{ - error::Error, Data, api::v1::auth::check_access_token, + error::Error, structs::{Member, Role}, utils::get_auth_header, }; @@ -34,8 +34,7 @@ pub async fn get( let role = Role::fetch_one(&mut conn, role_uuid).await?; - data - .set_cache_key(format!("{}", role_uuid), role.clone(), 60) + data.set_cache_key(format!("{}", role_uuid), role.clone(), 60) .await?; Ok(HttpResponse::Ok().json(role)) diff --git a/src/api/v1/stats.rs b/src/api/v1/stats.rs index 6ab8d64..0b9567e 100644 --- a/src/api/v1/stats.rs +++ b/src/api/v1/stats.rs @@ -5,8 +5,8 @@ use diesel::QueryDsl; use diesel_async::RunQueryDsl; use serde::Serialize; -use crate::error::Error; use crate::Data; +use crate::error::Error; use crate::schema::users::dsl::{users, uuid}; const VERSION: Option<&'static str> = option_env!("CARGO_PKG_VERSION"); diff --git a/src/api/v1/users/me.rs b/src/api/v1/users/me.rs index 9647002..83d02db 100644 --- a/src/api/v1/users/me.rs +++ b/src/api/v1/users/me.rs @@ -1,8 +1,10 @@ -use actix_web::{get, patch, web, HttpRequest, HttpResponse}; -use actix_multipart::form::{json::Json as MpJson, tempfile::TempFile, MultipartForm}; +use actix_multipart::form::{MultipartForm, json::Json as MpJson, tempfile::TempFile}; +use actix_web::{HttpRequest, HttpResponse, get, patch, web}; use serde::Deserialize; -use crate::{error::Error, structs::Me, api::v1::auth::check_access_token, utils::get_auth_header, Data}; +use crate::{ + Data, api::v1::auth::check_access_token, error::Error, structs::Me, utils::get_auth_header, +}; #[get("/me")] pub async fn res(req: HttpRequest, data: web::Data) -> Result { @@ -35,7 +37,11 @@ struct UploadForm { } #[patch("/me")] -pub async fn update(req: HttpRequest, MultipartForm(form): MultipartForm, data: web::Data) -> Result { +pub async fn update( + req: HttpRequest, + MultipartForm(form): MultipartForm, + data: web::Data, +) -> Result { let headers = req.headers(); let auth_header = get_auth_header(headers)?; @@ -51,7 +57,13 @@ pub async fn update(req: HttpRequest, MultipartForm(form): MultipartForm HttpResponse { debug!("{:?}", self); - error!("{}: {}", self.status_code(), self.to_string()); + error!("{}: {}", self.status_code(), self); HttpResponse::build(self.status_code()) .insert_header(ContentType::json()) @@ -79,8 +86,6 @@ struct WebError { impl WebError { fn new(message: String) -> Self { - Self { - message, - } + Self { message } } } diff --git a/src/main.rs b/src/main.rs index 8fa2121..1209051 100644 --- a/src/main.rs +++ b/src/main.rs @@ -2,24 +2,25 @@ use actix_cors::Cors; use actix_web::{App, HttpServer, web}; use argon2::Argon2; use clap::Parser; -use error::Error; -use simple_logger::SimpleLogger; use diesel_async::pooled_connection::AsyncDieselConnectionManager; use diesel_async::pooled_connection::deadpool::Pool; +use error::Error; +use simple_logger::SimpleLogger; use std::time::SystemTime; mod config; use config::{Config, ConfigBuilder}; -use diesel_migrations::{embed_migrations, EmbeddedMigrations, MigrationHarness}; +use diesel_migrations::{EmbeddedMigrations, MigrationHarness, embed_migrations}; pub const MIGRATIONS: EmbeddedMigrations = embed_migrations!(); -type Conn = deadpool::managed::Object>; +type Conn = + deadpool::managed::Object>; mod api; +pub mod error; +pub mod schema; pub mod structs; pub mod utils; -pub mod schema; -pub mod error; #[derive(Parser, Debug)] #[command(version, about, long_about = None)] @@ -30,7 +31,10 @@ struct Args { #[derive(Clone)] pub struct Data { - pub pool: deadpool::managed::Pool, Conn>, + pub pool: deadpool::managed::Pool< + AsyncDieselConnectionManager, + Conn, + >, pub cache_pool: redis::Client, pub config: Config, pub argon2: Argon2<'static>, @@ -53,27 +57,33 @@ async fn main() -> Result<(), Error> { let web = config.web.clone(); // create a new connection pool with the default config - let pool_config = AsyncDieselConnectionManager::::new(config.database.url()); + let pool_config = + AsyncDieselConnectionManager::::new(config.database.url()); let pool = Pool::builder(pool_config).build()?; let cache_pool = redis::Client::open(config.cache_database.url())?; let mut bunny_cdn = bunny_api_tokio::Client::new(config.bunny.api_key.clone()).await?; - bunny_cdn.storage.init(config.bunny.endpoint.clone(), config.bunny.storage_zone.clone())?; + bunny_cdn.storage.init( + config.bunny.endpoint.clone(), + config.bunny.storage_zone.clone(), + )?; let database_url = config.database.url(); tokio::task::spawn_blocking(move || { - use diesel::prelude::Connection; - use diesel_async::async_connection_wrapper::AsyncConnectionWrapper; + use diesel::prelude::Connection; + use diesel_async::async_connection_wrapper::AsyncConnectionWrapper; - - let mut conn = AsyncConnectionWrapper::::establish(&database_url)?; + let mut conn = + AsyncConnectionWrapper::::establish(&database_url)?; conn.run_pending_migrations(MIGRATIONS)?; Ok::<_, Box>(()) - }).await?.unwrap(); + }) + .await? + .unwrap(); /* **Stored for later possible use** diff --git a/src/structs.rs b/src/structs.rs index e593996..c86bc5b 100644 --- a/src/structs.rs +++ b/src/structs.rs @@ -1,14 +1,20 @@ -use diesel::{delete, insert_into, prelude::{Insertable, Queryable}, update, ExpressionMethods, QueryDsl, Selectable, SelectableHelper}; +use actix_web::web::BytesMut; +use diesel::{ + ExpressionMethods, QueryDsl, Selectable, SelectableHelper, delete, insert_into, + prelude::{Insertable, Queryable}, + update, +}; +use diesel_async::{RunQueryDsl, pooled_connection::AsyncDieselConnectionManager}; use serde::{Deserialize, Serialize}; -use uuid::Uuid; -use diesel_async::{pooled_connection::AsyncDieselConnectionManager, RunQueryDsl}; use tokio::task; use url::Url; -use actix_web::web::BytesMut; +use uuid::Uuid; -use crate::{error::Error, schema::*, utils::image_check, Conn, Data}; +use crate::{Conn, Data, error::Error, schema::*, utils::image_check}; -fn load_or_empty(query_result: Result, diesel::result::Error>) -> Result, diesel::result::Error> { +fn load_or_empty( + query_result: Result, diesel::result::Error>, +) -> Result, diesel::result::Error> { match query_result { Ok(vec) => Ok(vec), Err(diesel::result::Error::NotFound) => Ok(Vec::new()), @@ -34,7 +40,7 @@ impl ChannelBuilder { .filter(channel_uuid.eq(self.uuid)) .select(ChannelPermission::as_select()) .load(conn) - .await + .await, )?; Ok(Channel { @@ -66,7 +72,10 @@ pub struct ChannelPermission { impl Channel { pub async fn fetch_all( - pool: &deadpool::managed::Pool, Conn>, + pool: &deadpool::managed::Pool< + AsyncDieselConnectionManager, + Conn, + >, guild_uuid: Uuid, ) -> Result, Error> { let mut conn = pool.get().await?; @@ -77,21 +86,18 @@ impl Channel { .filter(dsl::guild_uuid.eq(guild_uuid)) .select(ChannelBuilder::as_select()) .load(&mut conn) - .await + .await, )?; let channel_futures = channel_builders.iter().map(async move |c| { let mut conn = pool.get().await?; c.clone().build(&mut conn).await }); - + futures::future::try_join_all(channel_futures).await } - pub async fn fetch_one( - conn: &mut Conn, - channel_uuid: Uuid, - ) -> Result { + pub async fn fetch_one(conn: &mut Conn, channel_uuid: Uuid) -> Result { use channels::dsl; let channel_builder: ChannelBuilder = dsl::channels .filter(dsl::uuid.eq(channel_uuid)) @@ -114,7 +120,7 @@ impl Channel { let new_channel = ChannelBuilder { uuid: channel_uuid, - guild_uuid: guild_uuid, + guild_uuid, name: name.clone(), description: description.clone(), }; @@ -133,11 +139,11 @@ impl Channel { permissions: vec![], }; - data - .set_cache_key(channel_uuid.to_string(), channel.clone(), 1800) + data.set_cache_key(channel_uuid.to_string(), channel.clone(), 1800) .await?; - data.del_cache_key(format!("{}_channels", guild_uuid)).await?; + data.del_cache_key(format!("{}_channels", guild_uuid)) + .await?; Ok(channel) } @@ -166,7 +172,7 @@ impl Channel { .limit(amount) .offset(offset) .load(conn) - .await + .await, )?; Ok(messages) @@ -257,8 +263,8 @@ impl GuildBuilder { description: self.description, icon: self.icon.and_then(|i| i.parse().ok()), owner_uuid: self.owner_uuid, - roles: roles, - member_count: member_count, + roles, + member_count, }) } } @@ -287,7 +293,10 @@ impl Guild { } pub async fn fetch_amount( - pool: &deadpool::managed::Pool, Conn>, + pool: &deadpool::managed::Pool< + AsyncDieselConnectionManager, + Conn, + >, offset: i64, amount: i64, ) -> Result, Error> { @@ -302,7 +311,7 @@ impl Guild { .offset(offset) .limit(amount) .load(&mut conn) - .await + .await, )?; // Process each guild concurrently @@ -368,7 +377,7 @@ impl Guild { .filter(dsl::guild_uuid.eq(self.uuid)) .select(Invite::as_select()) .load(conn) - .await + .await, )?; Ok(invites) @@ -385,7 +394,7 @@ impl Guild { if let Some(id) = custom_id { invite_id = id; if invite_id.len() > 32 { - return Err(Error::BadRequest("MAX LENGTH".to_string())) + return Err(Error::BadRequest("MAX LENGTH".to_string())); } } else { let charset = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"; @@ -408,14 +417,18 @@ impl Guild { } // FIXME: Horrible security - pub async fn set_icon(&mut self, bunny_cdn: &bunny_api_tokio::Client, conn: &mut Conn, cdn_url: Url, icon: BytesMut) -> Result<(), Error> { + pub async fn set_icon( + &mut self, + bunny_cdn: &bunny_api_tokio::Client, + conn: &mut Conn, + cdn_url: Url, + icon: BytesMut, + ) -> Result<(), Error> { let icon_clone = icon.clone(); let image_type = task::spawn_blocking(move || image_check(icon_clone)).await??; if let Some(icon) = &self.icon { - let relative_url = icon - .path() - .trim_start_matches('/'); + let relative_url = icon.path().trim_start_matches('/'); bunny_cdn.storage.delete(relative_url).await?; } @@ -452,26 +465,20 @@ pub struct Role { } impl Role { - pub async fn fetch_all( - conn: &mut Conn, - guild_uuid: Uuid, - ) -> Result, Error> { + pub async fn fetch_all(conn: &mut Conn, guild_uuid: Uuid) -> Result, Error> { use roles::dsl; let roles: Vec = load_or_empty( dsl::roles .filter(dsl::guild_uuid.eq(guild_uuid)) .select(Role::as_select()) .load(conn) - .await + .await, )?; Ok(roles) } - pub async fn fetch_one( - conn: &mut Conn, - role_uuid: Uuid, - ) -> Result { + pub async fn fetch_one(conn: &mut Conn, role_uuid: Uuid) -> Result { use roles::dsl; let role: Role = dsl::roles .filter(dsl::uuid.eq(role_uuid)) @@ -482,11 +489,7 @@ impl Role { Ok(role) } - pub async fn new( - conn: &mut Conn, - guild_uuid: Uuid, - name: String, - ) -> Result { + pub async fn new(conn: &mut Conn, guild_uuid: Uuid, name: String) -> Result { let role_uuid = Uuid::now_v7(); let role = Role { @@ -534,22 +537,18 @@ impl Member { user_uuid: Uuid, guild_uuid: Uuid, ) -> Result { - use guild_members::dsl; - let member: Member = dsl::guild_members - .filter(dsl::user_uuid.eq(user_uuid)) - .filter(dsl::guild_uuid.eq(guild_uuid)) - .select(Member::as_select()) - .get_result(conn) - .await?; + use guild_members::dsl; + let member: Member = dsl::guild_members + .filter(dsl::user_uuid.eq(user_uuid)) + .filter(dsl::guild_uuid.eq(guild_uuid)) + .select(Member::as_select()) + .get_result(conn) + .await?; Ok(member) } - pub async fn new( - conn: &mut Conn, - user_uuid: Uuid, - guild_uuid: Uuid, - ) -> Result { + pub async fn new(conn: &mut Conn, user_uuid: Uuid, guild_uuid: Uuid) -> Result { let member_uuid = Uuid::now_v7(); let member = Member { @@ -629,7 +628,11 @@ impl User { Ok(user) } - pub async fn fetch_amount(conn: &mut Conn, offset: i64, amount: i64) -> Result, Error> { + pub async fn fetch_amount( + conn: &mut Conn, + offset: i64, + amount: i64, + ) -> Result, Error> { use users::dsl; let users: Vec = load_or_empty( dsl::users @@ -637,7 +640,7 @@ impl User { .offset(offset) .select(User::as_select()) .load(conn) - .await + .await, )?; Ok(users) @@ -668,23 +671,30 @@ impl Me { Ok(me) } - pub async fn set_avatar(&mut self, bunny_cdn: &bunny_api_tokio::Client, conn: &mut Conn, cdn_url: Url, avatar: BytesMut) -> Result<(), Error> { + pub async fn set_avatar( + &mut self, + bunny_cdn: &bunny_api_tokio::Client, + conn: &mut Conn, + cdn_url: Url, + avatar: BytesMut, + ) -> Result<(), Error> { let avatar_clone = avatar.clone(); let image_type = task::spawn_blocking(move || image_check(avatar_clone)).await??; if let Some(avatar) = &self.avatar { let avatar_url: Url = avatar.parse()?; - let relative_url = avatar_url - .path() - .trim_start_matches('/'); + let relative_url = avatar_url.path().trim_start_matches('/'); bunny_cdn.storage.delete(relative_url).await?; } let path = format!("avatar/{}/avatar.{}", self.uuid, image_type); - bunny_cdn.storage.upload(path.clone(), avatar.into()).await?; + bunny_cdn + .storage + .upload(path.clone(), avatar.into()) + .await?; let avatar_url = cdn_url.join(&path)?; diff --git a/src/utils.rs b/src/utils.rs index 4e9d435..f9a5705 100644 --- a/src/utils.rs +++ b/src/utils.rs @@ -1,6 +1,7 @@ use actix_web::{ - cookie::{time::Duration, Cookie, SameSite}, - http::header::HeaderMap, web::BytesMut, + cookie::{Cookie, SameSite, time::Duration}, + http::header::HeaderMap, + web::BytesMut, }; use bindet::FileType; use getrandom::fill; @@ -8,29 +9,35 @@ use hex::encode; use redis::RedisError; use serde::Serialize; -use crate::{error::Error, Data}; +use crate::{Data, error::Error}; pub fn get_auth_header(headers: &HeaderMap) -> Result<&str, Error> { let auth_token = headers.get(actix_web::http::header::AUTHORIZATION); if auth_token.is_none() { - return Err(Error::Unauthorized("No authorization header provided".to_string())); + return Err(Error::Unauthorized( + "No authorization header provided".to_string(), + )); } let auth_raw = auth_token.unwrap().to_str()?; let mut auth = auth_raw.split_whitespace(); - let auth_type = auth.nth(0); + let auth_type = auth.next(); - let auth_value = auth.nth(0); + let auth_value = auth.next(); if auth_type.is_none() { - return Err(Error::BadRequest("Authorization header is empty".to_string())); + return Err(Error::BadRequest( + "Authorization header is empty".to_string(), + )); } else if auth_type.is_some_and(|at| at != "Bearer") { - return Err(Error::BadRequest("Only token auth is supported".to_string())); + return Err(Error::BadRequest( + "Only token auth is supported".to_string(), + )); } - + if auth_value.is_none() { return Err(Error::BadRequest("No token provided".to_string())); } @@ -67,13 +74,15 @@ pub fn image_check(icon: BytesMut) -> Result { if let Ok(Some(file_type)) = detect { if file_type.likely_to_be == vec![FileType::Jpg] { - return Ok(String::from("jpg")) + return Ok(String::from("jpg")); } else if file_type.likely_to_be == vec![FileType::Png] { - return Ok(String::from("png")) + return Ok(String::from("png")); } } - Err(Error::BadRequest("Uploaded file is not an image".to_string())) + Err(Error::BadRequest( + "Uploaded file is not an image".to_string(), + )) } impl Data {