diff --git a/src/lib.rs b/src/lib.rs index a1d7a5b5..248de49a 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -13,17 +13,17 @@ use tokio::sync::RwLock; extern crate clickhouse as clickhouse_crate; use clickhouse_crate::Client; -use governor::{Quota, RateLimiter}; use governor::middleware::StateInformationMiddleware; +use governor::{Quota, RateLimiter}; use util::cors::default_cors; use crate::queue::moderation::AutomatedModerationQueue; +use crate::util::ratelimit::KeyedRateLimiter; use crate::{ queue::payouts::process_payout, search::indexing::index_projects, util::env::{parse_strings_from_var, parse_var}, }; -use crate::util::ratelimit::KeyedRateLimiter; pub mod auth; pub mod clickhouse; diff --git a/src/main.rs b/src/main.rs index 5cd49379..cd572bb1 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,17 +1,13 @@ use actix_web::{App, HttpServer}; use actix_web_prom::PrometheusMetricsBuilder; use env_logger::Env; -use governor::middleware::StateInformationMiddleware; -use governor::{Quota, RateLimiter}; use labrinth::database::redis::RedisPool; use labrinth::file_hosting::S3Host; use labrinth::search; -use labrinth::util::ratelimit::{KeyedRateLimiter, RateLimit}; +use labrinth::util::ratelimit::RateLimit; use labrinth::{check_env_vars, clickhouse, database, file_hosting, queue}; use log::{error, info}; -use std::num::NonZeroU32; use std::sync::Arc; -use std::time::Duration; #[cfg(feature = "jemalloc")] #[global_allocator] @@ -98,7 +94,7 @@ async fn main() -> std::io::Result<()> { let search_config = search::SearchConfig::new(None); - let mut labrinth_config = labrinth::app_setup( + let labrinth_config = labrinth::app_setup( pool.clone(), redis_pool.clone(), search_config.clone(), diff --git a/src/routes/v3/projects.rs b/src/routes/v3/projects.rs index cc8ccffe..5053e7df 100644 --- a/src/routes/v3/projects.rs +++ b/src/routes/v3/projects.rs @@ -453,7 +453,7 @@ pub async fn project_edit( old_status: project_item.inner.status, }, thread_id: project_item.thread_id, - hide_identity: true, + hide_identity: user.role.is_mod(), } .insert(&mut transaction) .await?; diff --git a/src/routes/v3/reports.rs b/src/routes/v3/reports.rs index 1a88e1ca..ae191d29 100644 --- a/src/routes/v3/reports.rs +++ b/src/routes/v3/reports.rs @@ -435,7 +435,7 @@ pub async fn report_edit( MessageBody::ThreadClosure }, thread_id: report.thread_id, - hide_identity: true, + hide_identity: user.role.is_mod(), } .insert(&mut transaction) .await?; diff --git a/src/routes/v3/teams.rs b/src/routes/v3/teams.rs index bb93ebe7..3c2749c5 100644 --- a/src/routes/v3/teams.rs +++ b/src/routes/v3/teams.rs @@ -569,6 +569,7 @@ pub async fn add_team_member( transaction.commit().await?; TeamMember::clear_cache(team_id, &redis).await?; + User::clear_project_cache(&[new_member.user_id.into()], &redis).await?; Ok(HttpResponse::NoContent().body("")) } diff --git a/src/scheduler.rs b/src/scheduler.rs index 63487882..68cb593b 100644 --- a/src/scheduler.rs +++ b/src/scheduler.rs @@ -19,9 +19,9 @@ impl Scheduler { } pub fn run(&mut self, interval: std::time::Duration, mut task: F) - where - F: FnMut() -> R + Send + 'static, - R: std::future::Future + Send + 'static, + where + F: FnMut() -> R + Send + 'static, + R: std::future::Future + Send + 'static, { let future = IntervalStream::new(actix_rt::time::interval(interval)) .for_each_concurrent(2, move |_| task()); @@ -207,4 +207,4 @@ async fn update_versions( } Ok(()) -} \ No newline at end of file +} diff --git a/src/validate/datapack.rs b/src/validate/datapack.rs index 62311005..50639fea 100644 --- a/src/validate/datapack.rs +++ b/src/validate/datapack.rs @@ -9,10 +9,6 @@ impl super::Validator for DataPackValidator { &["zip"] } - fn get_project_types(&self) -> &[&str] { - &["mod"] - } - fn get_supported_loaders(&self) -> &[&str] { &["datapack"] } diff --git a/src/validate/fabric.rs b/src/validate/fabric.rs index 2ee44753..5e22bad3 100644 --- a/src/validate/fabric.rs +++ b/src/validate/fabric.rs @@ -10,10 +10,6 @@ impl super::Validator for FabricValidator { &["jar", "zip"] } - fn get_project_types(&self) -> &[&str] { - &["mod"] - } - fn get_supported_loaders(&self) -> &[&str] { &["fabric"] } diff --git a/src/validate/forge.rs b/src/validate/forge.rs index 04355fcd..77b42b81 100644 --- a/src/validate/forge.rs +++ b/src/validate/forge.rs @@ -10,10 +10,6 @@ impl super::Validator for ForgeValidator { &["jar", "zip"] } - fn get_project_types(&self) -> &[&str] { - &["mod"] - } - fn get_supported_loaders(&self) -> &[&str] { &["forge"] } @@ -47,10 +43,6 @@ impl super::Validator for LegacyForgeValidator { &["jar", "zip"] } - fn get_project_types(&self) -> &[&str] { - &["mod"] - } - fn get_supported_loaders(&self) -> &[&str] { &["forge"] } @@ -71,15 +63,13 @@ impl super::Validator for LegacyForgeValidator { fn validate( &self, - archive: &mut ZipArchive>, + _archive: &mut ZipArchive>, ) -> Result { - if archive.by_name("mcmod.info").is_err() { - return Ok(ValidationResult::Warning( - "Forge mod file does not contain mcmod.info!", - )); - }; - - //TODO: Check if file is a dev JAR? + // if archive.by_name("mcmod.info").is_err() { + // return Ok(ValidationResult::Warning( + // "Forge mod file does not contain mcmod.info!", + // )); + // }; Ok(ValidationResult::Pass) } diff --git a/src/validate/liteloader.rs b/src/validate/liteloader.rs index 50ec802c..af88c027 100644 --- a/src/validate/liteloader.rs +++ b/src/validate/liteloader.rs @@ -9,10 +9,6 @@ impl super::Validator for LiteLoaderValidator { &["litemod", "jar"] } - fn get_project_types(&self) -> &[&str] { - &["mod"] - } - fn get_supported_loaders(&self) -> &[&str] { &["liteloader"] } diff --git a/src/validate/mod.rs b/src/validate/mod.rs index 6254e4cf..148d80b8 100644 --- a/src/validate/mod.rs +++ b/src/validate/mod.rs @@ -77,7 +77,6 @@ pub enum SupportedGameVersions { pub trait Validator: Sync { fn get_file_extensions(&self) -> &[&str]; - fn get_project_types(&self) -> &[&str]; fn get_supported_loaders(&self) -> &[&str]; fn get_supported_game_versions(&self) -> SupportedGameVersions; fn validate( @@ -118,41 +117,28 @@ pub async fn validate_file( transaction: &mut sqlx::Transaction<'_, sqlx::Postgres>, redis: &RedisPool, ) -> Result { - // TODO: This needs to be revisited or removed with v3. - // Currently, it checks if the loader is the modpack loader, and extracts the pack data from it. - // This (and the funnction that calls this) should be refactored such that - // - validators are removed (or altogether reworked) - // - if a mrpack is uploaded, the pack data is extracted and usable to extract dependencies automatically - - // TODO: A test needs to be written for this. - match loaders { - loaders if loaders == vec![Loader("mrpack".to_string())] => { - let game_versions = version_fields - .into_iter() - .find_map(|v| MinecraftGameVersion::try_from_version_field(&v).ok()) - .unwrap_or_default(); - let all_game_versions = - MinecraftGameVersion::list(None, None, &mut *transaction, redis).await?; - validate_minecraft_file( - data, - file_extension, - "modpack".to_string(), - loaders, - game_versions, - all_game_versions, - file_type, - ) - .await - } - _ => Ok(ValidationResult::Pass), - } + let game_versions = version_fields + .into_iter() + .find_map(|v| MinecraftGameVersion::try_from_version_field(&v).ok()) + .unwrap_or_default(); + let all_game_versions = + MinecraftGameVersion::list(None, None, &mut *transaction, redis).await?; + + validate_minecraft_file( + data, + file_extension, + loaders, + game_versions, + all_game_versions, + file_type, + ) + .await } async fn validate_minecraft_file( data: bytes::Bytes, file_extension: String, - mut project_type: String, - mut loaders: Vec, + loaders: Vec, game_versions: Vec, all_game_versions: Vec, file_type: Option, @@ -164,19 +150,18 @@ async fn validate_minecraft_file( if let Some(file_type) = file_type { match file_type { FileType::RequiredResourcePack | FileType::OptionalResourcePack => { - project_type = "resourcepack".to_string(); - loaders = vec![Loader("minecraft".to_string())]; + return PackValidator.validate(&mut zip); } FileType::Unknown => {} } } let mut visited = false; + let mut saved_result = None; for validator in VALIDATORS { - if validator.get_project_types().contains(&&*project_type) - && loaders - .iter() - .any(|x| validator.get_supported_loaders().contains(&&*x.0)) + if loaders + .iter() + .any(|x| validator.get_supported_loaders().contains(&&*x.0)) && game_version_supported( &game_versions, &all_game_versions, @@ -184,13 +169,30 @@ async fn validate_minecraft_file( ) { if validator.get_file_extensions().contains(&&*file_extension) { - return validator.validate(&mut zip); + let result = validator.validate(&mut zip)?; + match result { + ValidationResult::PassWithPackDataAndFiles { .. } => { + saved_result = Some(result); + } + ValidationResult::Pass => { + if saved_result.is_none() { + saved_result = Some(result); + } + } + ValidationResult::Warning(_) => { + return Ok(result); + } + } } else { visited = true; } } } + if let Some(result) = saved_result { + return Ok(result); + } + if visited { if ALWAYS_ALLOWED_EXT.contains(&&*file_extension) { Ok(ValidationResult::Warning( diff --git a/src/validate/modpack.rs b/src/validate/modpack.rs index ad871985..30db5534 100644 --- a/src/validate/modpack.rs +++ b/src/validate/modpack.rs @@ -13,12 +13,8 @@ impl super::Validator for ModpackValidator { &["mrpack"] } - fn get_project_types(&self) -> &[&str] { - &["modpack"] - } - fn get_supported_loaders(&self) -> &[&str] { - &["forge", "fabric", "quilt", "mrpack"] + &["mrpack"] } fn get_supported_game_versions(&self) -> SupportedGameVersions { diff --git a/src/validate/plugin.rs b/src/validate/plugin.rs index 353977f1..a2b7e35c 100644 --- a/src/validate/plugin.rs +++ b/src/validate/plugin.rs @@ -9,10 +9,6 @@ impl super::Validator for PluginYmlValidator { &["zip", "jar"] } - fn get_project_types(&self) -> &[&str] { - &["mod"] - } - fn get_supported_loaders(&self) -> &[&str] { &["bukkit", "spigot", "paper", "purpur"] } @@ -45,10 +41,6 @@ impl super::Validator for BungeeCordValidator { &["zip", "jar"] } - fn get_project_types(&self) -> &[&str] { - &["mod"] - } - fn get_supported_loaders(&self) -> &[&str] { &["bungeecord", "waterfall"] } @@ -81,10 +73,6 @@ impl super::Validator for VelocityValidator { &["zip", "jar"] } - fn get_project_types(&self) -> &[&str] { - &["mod"] - } - fn get_supported_loaders(&self) -> &[&str] { &["velocity"] } @@ -114,10 +102,6 @@ impl super::Validator for SpongeValidator { &["zip", "jar"] } - fn get_project_types(&self) -> &[&str] { - &["mod"] - } - fn get_supported_loaders(&self) -> &[&str] { &["sponge"] } diff --git a/src/validate/quilt.rs b/src/validate/quilt.rs index 66741b8b..f013a323 100644 --- a/src/validate/quilt.rs +++ b/src/validate/quilt.rs @@ -10,10 +10,6 @@ impl super::Validator for QuiltValidator { &["jar", "zip"] } - fn get_project_types(&self) -> &[&str] { - &["mod"] - } - fn get_supported_loaders(&self) -> &[&str] { &["quilt"] } diff --git a/src/validate/resourcepack.rs b/src/validate/resourcepack.rs index 97f041de..aadfc6c3 100644 --- a/src/validate/resourcepack.rs +++ b/src/validate/resourcepack.rs @@ -10,10 +10,6 @@ impl super::Validator for PackValidator { &["zip"] } - fn get_project_types(&self) -> &[&str] { - &["resourcepack"] - } - fn get_supported_loaders(&self) -> &[&str] { &["minecraft"] } @@ -47,10 +43,6 @@ impl super::Validator for TexturePackValidator { &["zip"] } - fn get_project_types(&self) -> &[&str] { - &["resourcepack"] - } - fn get_supported_loaders(&self) -> &[&str] { &["minecraft"] } diff --git a/src/validate/shader.rs b/src/validate/shader.rs index 17b4808e..d2de6c8f 100644 --- a/src/validate/shader.rs +++ b/src/validate/shader.rs @@ -9,10 +9,6 @@ impl super::Validator for ShaderValidator { &["zip"] } - fn get_project_types(&self) -> &[&str] { - &["shader"] - } - fn get_supported_loaders(&self) -> &[&str] { &["optifine", "iris"] } @@ -42,10 +38,6 @@ impl super::Validator for CanvasShaderValidator { &["zip"] } - fn get_project_types(&self) -> &[&str] { - &["shader"] - } - fn get_supported_loaders(&self) -> &[&str] { &["canvas"] } @@ -81,10 +73,6 @@ impl super::Validator for CoreShaderValidator { &["zip"] } - fn get_project_types(&self) -> &[&str] { - &["shader"] - } - fn get_supported_loaders(&self) -> &[&str] { &["vanilla"] }