From 49cf0c8a9aee2f777d60ed31176e32a933ffa5b5 Mon Sep 17 00:00:00 2001 From: Geometrically <18202329+Geometrically@users.noreply.github.com> Date: Mon, 22 Apr 2024 17:46:56 -0700 Subject: [PATCH] Fix user deletion (#907) * Fix user deletion * run prep+fmt * Update validators --- ...c13b66ced32452152f20e8fa5df4b3d14f292.json | 22 +++++++++++ ...94b6dd666f2e27e192937b82f25895e9bc975.json | 22 +++++++++++ src/auth/checks.rs | 6 +-- src/database/models/user_item.rs | 38 ++++++++++++++++++- src/routes/v3/version_creation.rs | 10 ++++- src/search/mod.rs | 7 +++- 6 files changed, 98 insertions(+), 7 deletions(-) create mode 100644 .sqlx/query-531e556fa37da6b74aab2e539bcc13b66ced32452152f20e8fa5df4b3d14f292.json create mode 100644 .sqlx/query-54f62537bf546f8ad8185357a8294b6dd666f2e27e192937b82f25895e9bc975.json diff --git a/.sqlx/query-531e556fa37da6b74aab2e539bcc13b66ced32452152f20e8fa5df4b3d14f292.json b/.sqlx/query-531e556fa37da6b74aab2e539bcc13b66ced32452152f20e8fa5df4b3d14f292.json new file mode 100644 index 00000000..d05f826d --- /dev/null +++ b/.sqlx/query-531e556fa37da6b74aab2e539bcc13b66ced32452152f20e8fa5df4b3d14f292.json @@ -0,0 +1,22 @@ +{ + "db_name": "PostgreSQL", + "query": "\n SELECT t.id\n FROM threads t\n INNER JOIN reports r ON t.report_id = r.id AND (r.user_id = $1 OR r.reporter = $1)\n WHERE report_id IS NOT NULL\n ", + "describe": { + "columns": [ + { + "ordinal": 0, + "name": "id", + "type_info": "Int8" + } + ], + "parameters": { + "Left": [ + "Int8" + ] + }, + "nullable": [ + false + ] + }, + "hash": "531e556fa37da6b74aab2e539bcc13b66ced32452152f20e8fa5df4b3d14f292" +} diff --git a/.sqlx/query-54f62537bf546f8ad8185357a8294b6dd666f2e27e192937b82f25895e9bc975.json b/.sqlx/query-54f62537bf546f8ad8185357a8294b6dd666f2e27e192937b82f25895e9bc975.json new file mode 100644 index 00000000..dd409b26 --- /dev/null +++ b/.sqlx/query-54f62537bf546f8ad8185357a8294b6dd666f2e27e192937b82f25895e9bc975.json @@ -0,0 +1,22 @@ +{ + "db_name": "PostgreSQL", + "query": "\n SELECT id\n FROM collections\n WHERE user_id = $1\n ", + "describe": { + "columns": [ + { + "ordinal": 0, + "name": "id", + "type_info": "Int8" + } + ], + "parameters": { + "Left": [ + "Int8" + ] + }, + "nullable": [ + false + ] + }, + "hash": "54f62537bf546f8ad8185357a8294b6dd666f2e27e192937b82f25895e9bc975" +} diff --git a/src/auth/checks.rs b/src/auth/checks.rs index fe3a7878..f769984e 100644 --- a/src/auth/checks.rs +++ b/src/auth/checks.rs @@ -61,8 +61,7 @@ pub async fn filter_visible_projects( pool, hide_unlisted, ) - .await - .unwrap(); + .await?; projects.retain(|x| filtered_project_ids.contains(&x.inner.id)); Ok(projects.into_iter().map(|x| x.into()).collect()) } @@ -193,8 +192,7 @@ pub async fn filter_visible_versions( pool, redis, ) - .await - .unwrap(); + .await?; versions.retain(|x| filtered_version_ids.contains(&x.inner.id)); Ok(versions.into_iter().map(|x| x.into()).collect()) } diff --git a/src/database/models/user_item.rs b/src/database/models/user_item.rs index 06b73d52..5c93cba2 100644 --- a/src/database/models/user_item.rs +++ b/src/database/models/user_item.rs @@ -1,5 +1,6 @@ use super::ids::{ProjectId, UserId}; -use super::CollectionId; +use super::{CollectionId, ThreadId}; +use crate::database::models; use crate::database::models::{DatabaseError, OrganizationId}; use crate::database::redis::RedisPool; use crate::models::ids::base62_impl::{parse_base62, to_base62}; @@ -454,6 +455,41 @@ impl User { .execute(&mut **transaction) .await?; + let user_collections = sqlx::query!( + " + SELECT id + FROM collections + WHERE user_id = $1 + ", + id as UserId, + ) + .fetch_many(&mut **transaction) + .try_filter_map(|e| async { Ok(e.right().map(|x| CollectionId(x.id))) }) + .try_collect::>() + .await?; + + for collection_id in user_collections { + models::Collection::remove(collection_id, transaction, &redis).await?; + } + + let report_threads = sqlx::query!( + " + SELECT t.id + FROM threads t + INNER JOIN reports r ON t.report_id = r.id AND (r.user_id = $1 OR r.reporter = $1) + WHERE report_id IS NOT NULL + ", + id as UserId, + ) + .fetch_many(&mut **transaction) + .try_filter_map(|e| async { Ok(e.right().map(|x| ThreadId(x.id))) }) + .try_collect::>() + .await?; + + for thread_id in report_threads { + models::Thread::remove_full(thread_id, transaction).await?; + } + sqlx::query!( " DELETE FROM reports diff --git a/src/routes/v3/version_creation.rs b/src/routes/v3/version_creation.rs index 6bbd7e83..c8a3e7c6 100644 --- a/src/routes/v3/version_creation.rs +++ b/src/routes/v3/version_creation.rs @@ -877,7 +877,9 @@ pub async fn upload_file( } let data = data.freeze(); - let primary = (version_files.iter().all(|x| !x.primary) && !ignore_primary) + let primary = (validation_result.is_passed() + && version_files.iter().all(|x| !x.primary) + && !ignore_primary) || force_primary || total_files_len == 1; @@ -911,6 +913,12 @@ pub async fn upload_file( )); } + if let ValidationResult::Warning(msg) = validation_result { + if primary { + return Err(CreateError::InvalidInput(msg.to_string())); + } + } + version_files.push(VersionFileBuilder { filename: file_name.to_string(), url: format!("{cdn_url}/{file_path_encode}"), diff --git a/src/search/mod.rs b/src/search/mod.rs index e5d105bd..db397b5f 100644 --- a/src/search/mod.rs +++ b/src/search/mod.rs @@ -191,7 +191,12 @@ pub async fn search_for_project( let offset: usize = info.offset.as_deref().unwrap_or("0").parse()?; let index = info.index.as_deref().unwrap_or("relevance"); - let limit = info.limit.as_deref().unwrap_or("10").parse::()?.min(100); + let limit = info + .limit + .as_deref() + .unwrap_or("10") + .parse::()? + .min(100); let sort = get_sort_index(config, index)?; let meilisearch_index = client.get_index(sort.0).await?;