Fix rejected files showing in hash routes (#375)

* Fix rejected files showing in hash routes

* Run prepare and formatter

* Add modrinth.com exception for callback URLs

* run fmt
This commit is contained in:
Geometrically
2022-06-18 14:09:37 -07:00
committed by GitHub
parent 782bb11894
commit cd514285d9
8 changed files with 237 additions and 181 deletions

2
.env
View File

@@ -42,4 +42,4 @@ RATE_LIMIT_IGNORE_IPS='["127.0.0.1"]'
WHITELISTED_MODPACK_DOMAINS='["cdn.modrinth.com", "edge.forgecdn.net", "github.com", "raw.githubusercontent.com"]' WHITELISTED_MODPACK_DOMAINS='["cdn.modrinth.com", "edge.forgecdn.net", "github.com", "raw.githubusercontent.com"]'
ALLOWED_CALLBACK_URLS='["localhost", ".modrinth.com", "modrinth.com", "-modrinth.vercel.app"]' ALLOWED_CALLBACK_URLS='["localhost", ".modrinth.com", "-modrinth.vercel.app"]'

2
Cargo.lock generated
View File

@@ -1441,7 +1441,7 @@ dependencies = [
[[package]] [[package]]
name = "labrinth" name = "labrinth"
version = "2.4.2" version = "2.4.3"
dependencies = [ dependencies = [
"actix", "actix",
"actix-cors", "actix-cors",

View File

@@ -1,6 +1,6 @@
[package] [package]
name = "labrinth" name = "labrinth"
version = "2.4.2" version = "2.4.3"
#Team members, please add your emails and usernames #Team members, please add your emails and usernames
authors = ["geometrically <jai.a@tuta.io>", "Redblueflame <contact@redblueflame.com>", "Aeledfyr <aeledfyr@gmail.com>", "Charalampos Fanoulis <yo@fanoulis.dev>", "AppleTheGolden <scotsbox@protonmail.com>"] authors = ["geometrically <jai.a@tuta.io>", "Redblueflame <contact@redblueflame.com>", "Aeledfyr <aeledfyr@gmail.com>", "Charalampos Fanoulis <yo@fanoulis.dev>", "AppleTheGolden <scotsbox@protonmail.com>"]
edition = "2018" edition = "2018"

View File

@@ -1,44 +1,5 @@
{ {
"db": "PostgreSQL", "db": "PostgreSQL",
"002a7e9d3ccfb94348b1e7ad93b923aab9d2c377e41bc2cc22e3a94d799d44de": {
"query": "\n SELECT f.url url, f.id id, f.version_id version_id, v.mod_id project_id FROM hashes h\n INNER JOIN files f ON h.file_id = f.id\n INNER JOIN versions v ON v.id = f.version_id\n WHERE h.algorithm = $2 AND h.hash = $1\n ",
"describe": {
"columns": [
{
"ordinal": 0,
"name": "url",
"type_info": "Varchar"
},
{
"ordinal": 1,
"name": "id",
"type_info": "Int8"
},
{
"ordinal": 2,
"name": "version_id",
"type_info": "Int8"
},
{
"ordinal": 3,
"name": "project_id",
"type_info": "Int8"
}
],
"parameters": {
"Left": [
"Bytea",
"Text"
]
},
"nullable": [
false,
false,
false,
false
]
}
},
"017c9fd0c8103c590489453a25b3317e6790a21f388bcf7ec8c93cd26255f368": { "017c9fd0c8103c590489453a25b3317e6790a21f388bcf7ec8c93cd26255f368": {
"query": "\n SELECT id, team_id, role, permissions, accepted\n FROM team_members\n WHERE (user_id = $1 AND accepted = TRUE)\n ", "query": "\n SELECT id, team_id, role, permissions, accepted\n FROM team_members\n WHERE (user_id = $1 AND accepted = TRUE)\n ",
"describe": { "describe": {
@@ -198,6 +159,28 @@
"nullable": [] "nullable": []
} }
}, },
"091f325c84d0cf6dfe6933567c58fea815912ba613ffb3536466770d71ea613e": {
"query": "\n SELECT f.version_id version_id\n FROM hashes h\n INNER JOIN files f ON h.file_id = f.id\n INNER JOIN versions v on f.version_id = v.id\n INNER JOIN mods m on v.mod_id = m.id\n INNER JOIN statuses s on m.status = s.id\n WHERE h.algorithm = $2 AND h.hash = $1 AND s.status != $3\n ",
"describe": {
"columns": [
{
"ordinal": 0,
"name": "version_id",
"type_info": "Int8"
}
],
"parameters": {
"Left": [
"Bytea",
"Text",
"Text"
]
},
"nullable": [
false
]
}
},
"0a1a470c12b84c7e171f0f51e8e541e9abe8bbee17fc441a5054e1dfd5607c05": { "0a1a470c12b84c7e171f0f51e8e541e9abe8bbee17fc441a5054e1dfd5607c05": {
"query": "\n UPDATE versions\n SET name = $1\n WHERE (id = $2)\n ", "query": "\n UPDATE versions\n SET name = $1\n WHERE (id = $2)\n ",
"describe": { "describe": {
@@ -211,27 +194,6 @@
"nullable": [] "nullable": []
} }
}, },
"0a1e0cbcdfe68e111326e2dc070e7903d4abb92180c7957f2408b4d6f810c2e5": {
"query": "\n SELECT v.mod_id project_id FROM hashes h\n INNER JOIN files f ON h.file_id = f.id\n INNER JOIN versions v ON v.id = f.version_id\n WHERE h.algorithm = $2 AND h.hash = $1\n ",
"describe": {
"columns": [
{
"ordinal": 0,
"name": "project_id",
"type_info": "Int8"
}
],
"parameters": {
"Left": [
"Bytea",
"Text"
]
},
"nullable": [
false
]
}
},
"0ca11a32b2860e4f5c3d20892a5be3cb419e084f42ba0f98e09b9995027fcc4e": { "0ca11a32b2860e4f5c3d20892a5be3cb419e084f42ba0f98e09b9995027fcc4e": {
"query": "\n SELECT id FROM statuses\n WHERE status = $1\n ", "query": "\n SELECT id FROM statuses\n WHERE status = $1\n ",
"describe": { "describe": {
@@ -760,6 +722,46 @@
"nullable": [] "nullable": []
} }
}, },
"292da3eec2cc7d7eb635fa123be1b1387e9e91466f007e10101053fdb9874e3f": {
"query": "\n SELECT f.url url, f.id id, f.version_id version_id, v.mod_id project_id FROM hashes h\n INNER JOIN files f ON h.file_id = f.id\n INNER JOIN versions v ON v.id = f.version_id\n INNER JOIN mods m on v.mod_id = m.id\n INNER JOIN statuses s on m.status = s.id\n WHERE h.algorithm = $2 AND h.hash = $1 AND s.status != $3\n ",
"describe": {
"columns": [
{
"ordinal": 0,
"name": "url",
"type_info": "Varchar"
},
{
"ordinal": 1,
"name": "id",
"type_info": "Int8"
},
{
"ordinal": 2,
"name": "version_id",
"type_info": "Int8"
},
{
"ordinal": 3,
"name": "project_id",
"type_info": "Int8"
}
],
"parameters": {
"Left": [
"Bytea",
"Text",
"Text"
]
},
"nullable": [
false,
false,
false,
false
]
}
},
"29e657d26f0fb24a766f5b5eb6a94d01d1616884d8ca10e91536e974d5b585a6": { "29e657d26f0fb24a766f5b5eb6a94d01d1616884d8ca10e91536e974d5b585a6": {
"query": "\n INSERT INTO loaders_versions (loader_id, version_id)\n VALUES ($1, $2)\n ", "query": "\n INSERT INTO loaders_versions (loader_id, version_id)\n VALUES ($1, $2)\n ",
"describe": { "describe": {
@@ -1051,6 +1053,40 @@
"nullable": [] "nullable": []
} }
}, },
"3b1fba1ce47e94c0301c8a234bc7609e3c62fc02acd1485283c0f824cff2d69b": {
"query": "\n SELECT h.hash hash, h.algorithm algorithm, f.version_id version_id FROM hashes h\n INNER JOIN files f ON h.file_id = f.id\n INNER JOIN versions v ON v.id = f.version_id\n INNER JOIN mods m on v.mod_id = m.id\n INNER JOIN statuses s on m.status = s.id\n WHERE h.algorithm = $2 AND h.hash = ANY($1::bytea[]) AND s.status != $3\n ",
"describe": {
"columns": [
{
"ordinal": 0,
"name": "hash",
"type_info": "Bytea"
},
{
"ordinal": 1,
"name": "algorithm",
"type_info": "Varchar"
},
{
"ordinal": 2,
"name": "version_id",
"type_info": "Int8"
}
],
"parameters": {
"Left": [
"ByteaArray",
"Text",
"Text"
]
},
"nullable": [
false,
false,
false
]
}
},
"3bdcbfa5abe43cc9b4f996f147277a7f6921cca00f82cad0ef5d85032c761a36": { "3bdcbfa5abe43cc9b4f996f147277a7f6921cca00f82cad0ef5d85032c761a36": {
"query": "\n DELETE FROM mod_follows\n WHERE follower_id = $1 AND mod_id = $2\n ", "query": "\n DELETE FROM mod_follows\n WHERE follower_id = $1 AND mod_id = $2\n ",
"describe": { "describe": {
@@ -1438,51 +1474,6 @@
"nullable": [] "nullable": []
} }
}, },
"4ed40527a52e96490066653f3838c763180835a14c6f8dc6a5e54667d9d7ffef": {
"query": "\n SELECT f.url url, h.hash hash, h.algorithm algorithm, f.version_id version_id, v.mod_id project_id FROM hashes h\n INNER JOIN files f ON h.file_id = f.id\n INNER JOIN versions v ON v.id = f.version_id\n WHERE h.algorithm = $2 AND h.hash = ANY($1::bytea[])\n ",
"describe": {
"columns": [
{
"ordinal": 0,
"name": "url",
"type_info": "Varchar"
},
{
"ordinal": 1,
"name": "hash",
"type_info": "Bytea"
},
{
"ordinal": 2,
"name": "algorithm",
"type_info": "Varchar"
},
{
"ordinal": 3,
"name": "version_id",
"type_info": "Int8"
},
{
"ordinal": 4,
"name": "project_id",
"type_info": "Int8"
}
],
"parameters": {
"Left": [
"ByteaArray",
"Text"
]
},
"nullable": [
false,
false,
false,
false,
false
]
}
},
"4f307a8851b0cab7870798ba017955c8ebaba7444791dd65ffebcbac32d3585d": { "4f307a8851b0cab7870798ba017955c8ebaba7444791dd65ffebcbac32d3585d": {
"query": "\n INSERT INTO states (id, url)\n VALUES ($1, $2)\n ", "query": "\n INSERT INTO states (id, url)\n VALUES ($1, $2)\n ",
"describe": { "describe": {
@@ -2699,6 +2690,28 @@
"nullable": [] "nullable": []
} }
}, },
"740424ba1af7b0cf85d6031365d2c026e0b0003fb618bb82eeebcdad9599774a": {
"query": "\n SELECT v.mod_id project_id FROM hashes h\n INNER JOIN files f ON h.file_id = f.id\n INNER JOIN versions v ON v.id = f.version_id\n INNER JOIN mods m on v.mod_id = m.id\n INNER JOIN statuses s on m.status = s.id\n WHERE h.algorithm = $2 AND h.hash = $1 AND s.status != $3\n ",
"describe": {
"columns": [
{
"ordinal": 0,
"name": "project_id",
"type_info": "Int8"
}
],
"parameters": {
"Left": [
"Bytea",
"Text",
"Text"
]
},
"nullable": [
false
]
}
},
"75a860ca8087536a9fcf932846341c8bd322d314231bb8acac124d1cea93270b": { "75a860ca8087536a9fcf932846341c8bd322d314231bb8acac124d1cea93270b": {
"query": "\n SELECT mf.mod_id FROM mod_follows mf\n WHERE mf.follower_id = $1\n ", "query": "\n SELECT mf.mod_id FROM mod_follows mf\n WHERE mf.follower_id = $1\n ",
"describe": { "describe": {
@@ -3672,6 +3685,52 @@
"nullable": [] "nullable": []
} }
}, },
"9b231e09e8a1e56cca49bf82f9a605e3d13b9e6a1cfc6357b5f544d3d9a89dfd": {
"query": "\n SELECT f.url url, h.hash hash, h.algorithm algorithm, f.version_id version_id, v.mod_id project_id FROM hashes h\n INNER JOIN files f ON h.file_id = f.id\n INNER JOIN versions v ON v.id = f.version_id\n INNER JOIN mods m on v.mod_id = m.id\n INNER JOIN statuses s on m.status = s.id\n WHERE h.algorithm = $2 AND h.hash = ANY($1::bytea[]) AND s.status != $3\n ",
"describe": {
"columns": [
{
"ordinal": 0,
"name": "url",
"type_info": "Varchar"
},
{
"ordinal": 1,
"name": "hash",
"type_info": "Bytea"
},
{
"ordinal": 2,
"name": "algorithm",
"type_info": "Varchar"
},
{
"ordinal": 3,
"name": "version_id",
"type_info": "Int8"
},
{
"ordinal": 4,
"name": "project_id",
"type_info": "Int8"
}
],
"parameters": {
"Left": [
"ByteaArray",
"Text",
"Text"
]
},
"nullable": [
false,
false,
false,
false,
false
]
}
},
"9ceca63fb11f35f09f77bb9db175a1ac74dfcc2200c8134866922742fbbedea3": { "9ceca63fb11f35f09f77bb9db175a1ac74dfcc2200c8134866922742fbbedea3": {
"query": "\n UPDATE dependencies\n SET dependency_id = $2\n WHERE dependency_id = $1\n ", "query": "\n UPDATE dependencies\n SET dependency_id = $2\n WHERE dependency_id = $1\n ",
"describe": { "describe": {
@@ -6001,39 +6060,6 @@
"nullable": [] "nullable": []
} }
}, },
"f30bff55ee84fb390c6c240d5a46826f8e2481b701d956f38b484f140f23e2dc": {
"query": "\n SELECT h.hash hash, h.algorithm algorithm, f.version_id version_id FROM hashes h\n INNER JOIN files f ON h.file_id = f.id\n WHERE h.algorithm = $2 AND h.hash = ANY($1::bytea[])\n ",
"describe": {
"columns": [
{
"ordinal": 0,
"name": "hash",
"type_info": "Bytea"
},
{
"ordinal": 1,
"name": "algorithm",
"type_info": "Varchar"
},
{
"ordinal": 2,
"name": "version_id",
"type_info": "Int8"
}
],
"parameters": {
"Left": [
"ByteaArray",
"Text"
]
},
"nullable": [
false,
false,
false
]
}
},
"f3a8ad4a802dde0eb9304078e0368066e7d48121dfe73a63b2911b0998840a79": { "f3a8ad4a802dde0eb9304078e0368066e7d48121dfe73a63b2911b0998840a79": {
"query": "\n SELECT id FROM users\n WHERE LOWER(username) = LOWER($1)\n ", "query": "\n SELECT id FROM users\n WHERE LOWER(username) = LOWER($1)\n ",
"describe": { "describe": {

View File

@@ -118,8 +118,8 @@ impl Notification {
id: NotificationId, id: NotificationId,
executor: E, executor: E,
) -> Result<Option<Self>, sqlx::error::Error> ) -> Result<Option<Self>, sqlx::error::Error>
where where
E: sqlx::Executor<'a, Database = sqlx::Postgres>, E: sqlx::Executor<'a, Database = sqlx::Postgres>,
{ {
let result = sqlx::query!( let result = sqlx::query!(
" "
@@ -138,19 +138,24 @@ impl Notification {
if let Some(row) = result { if let Some(row) = result {
let mut actions: Vec<NotificationAction> = Vec::new(); let mut actions: Vec<NotificationAction> = Vec::new();
row.actions.unwrap_or_default().split(" ~~~~ ").for_each(|x| { row.actions
let action: Vec<&str> = x.split(" |||| ").collect(); .unwrap_or_default()
.split(" ~~~~ ")
.for_each(|x| {
let action: Vec<&str> = x.split(" |||| ").collect();
if action.len() >= 3 { if action.len() >= 3 {
actions.push(NotificationAction { actions.push(NotificationAction {
id: NotificationActionId(action[0].parse().unwrap_or(0)), id: NotificationActionId(
notification_id: id, action[0].parse().unwrap_or(0),
title: action[1].to_string(), ),
action_route_method: action[3].to_string(), notification_id: id,
action_route: action[2].to_string(), title: action[1].to_string(),
}); action_route_method: action[3].to_string(),
} action_route: action[2].to_string(),
}); });
}
});
Ok(Some(Notification { Ok(Some(Notification {
id, id,
@@ -172,12 +177,13 @@ impl Notification {
notification_ids: Vec<NotificationId>, notification_ids: Vec<NotificationId>,
exec: E, exec: E,
) -> Result<Vec<Notification>, sqlx::Error> ) -> Result<Vec<Notification>, sqlx::Error>
where where
E: sqlx::Executor<'a, Database = sqlx::Postgres> + Copy, E: sqlx::Executor<'a, Database = sqlx::Postgres> + Copy,
{ {
use futures::stream::TryStreamExt; use futures::stream::TryStreamExt;
let notification_ids_parsed: Vec<i64> = notification_ids.into_iter().map(|x| x.0).collect(); let notification_ids_parsed: Vec<i64> =
notification_ids.into_iter().map(|x| x.0).collect();
sqlx::query!( sqlx::query!(
" "
SELECT n.id, n.user_id, n.title, n.text, n.link, n.created, n.read, n.type notification_type, SELECT n.id, n.user_id, n.title, n.text, n.link, n.created, n.read, n.type notification_type,
@@ -231,8 +237,8 @@ impl Notification {
user_id: UserId, user_id: UserId,
exec: E, exec: E,
) -> Result<Vec<Notification>, sqlx::Error> ) -> Result<Vec<Notification>, sqlx::Error>
where where
E: sqlx::Executor<'a, Database = sqlx::Postgres> + Copy, E: sqlx::Executor<'a, Database = sqlx::Postgres> + Copy,
{ {
use futures::stream::TryStreamExt; use futures::stream::TryStreamExt;

View File

@@ -1,4 +1,4 @@
/*! /*!
This auth module is primarily for use within the main website. Applications interacting with the This auth module is primarily for use within the main website. Applications interacting with the
authenticated API (a very small portion - notifications, private projects, editing/creating projects authenticated API (a very small portion - notifications, private projects, editing/creating projects
and versions) should either retrieve the Modrinth GitHub token through the site, or create a personal and versions) should either retrieve the Modrinth GitHub token through the site, or create a personal
@@ -16,6 +16,7 @@ use crate::models::error::ApiError;
use crate::models::ids::base62_impl::{parse_base62, to_base62}; use crate::models::ids::base62_impl::{parse_base62, to_base62};
use crate::models::ids::DecodingError; use crate::models::ids::DecodingError;
use crate::models::users::Role; use crate::models::users::Role;
use crate::parse_strings_from_var;
use crate::util::auth::get_github_user_from_token; use crate::util::auth::get_github_user_from_token;
use actix_web::http::StatusCode; use actix_web::http::StatusCode;
use actix_web::web::{scope, Data, Query, ServiceConfig}; use actix_web::web::{scope, Data, Query, ServiceConfig};
@@ -24,7 +25,6 @@ use serde::{Deserialize, Serialize};
use sqlx::postgres::PgPool; use sqlx::postgres::PgPool;
use thiserror::Error; use thiserror::Error;
use time::OffsetDateTime; use time::OffsetDateTime;
use crate::parse_strings_from_var;
pub fn config(cfg: &mut ServiceConfig) { pub fn config(cfg: &mut ServiceConfig) {
cfg.service(scope("auth").service(auth_callback).service(init)); cfg.service(scope("auth").service(auth_callback).service(init));
@@ -82,7 +82,7 @@ impl actix_web::ResponseError for AuthorizationError {
AuthorizationError::Decoding(..) => "decoding_error", AuthorizationError::Decoding(..) => "decoding_error",
AuthorizationError::Authentication(..) => { AuthorizationError::Authentication(..) => {
"authentication_error" "authentication_error"
}, }
AuthorizationError::Url => "url_error", AuthorizationError::Url => "url_error",
}, },
description: &self.to_string(), description: &self.to_string(),
@@ -114,13 +114,16 @@ pub async fn init(
Query(info): Query<AuthorizationInit>, Query(info): Query<AuthorizationInit>,
client: Data<PgPool>, client: Data<PgPool>,
) -> Result<HttpResponse, AuthorizationError> { ) -> Result<HttpResponse, AuthorizationError> {
let url = url::Url::parse(&info.url).map_err(|_| AuthorizationError::Url)?; let url =
url::Url::parse(&info.url).map_err(|_| AuthorizationError::Url)?;
let allowed_callback_urls = parse_strings_from_var("ALLOWED_CALLBACK_URLS") let allowed_callback_urls =
.unwrap_or_default(); parse_strings_from_var("ALLOWED_CALLBACK_URLS").unwrap_or_default();
let domain = url.domain().ok_or(AuthorizationError::Url)?; let domain = url.domain().ok_or(AuthorizationError::Url)?;
if !allowed_callback_urls.iter().any(|x| domain.ends_with(x)) { if !allowed_callback_urls.iter().any(|x| domain.ends_with(x))
|| domain == "modrinth.com"
{
return Err(AuthorizationError::Url); return Err(AuthorizationError::Url);
} }

View File

@@ -34,12 +34,17 @@ pub async fn get_version_from_hash(
let result = sqlx::query!( let result = sqlx::query!(
" "
SELECT f.version_id version_id FROM hashes h SELECT f.version_id version_id
FROM hashes h
INNER JOIN files f ON h.file_id = f.id INNER JOIN files f ON h.file_id = f.id
WHERE h.algorithm = $2 AND h.hash = $1 INNER JOIN versions v on f.version_id = v.id
INNER JOIN mods m on v.mod_id = m.id
INNER JOIN statuses s on m.status = s.id
WHERE h.algorithm = $2 AND h.hash = $1 AND s.status != $3
", ",
hash.as_bytes(), hash.as_bytes(),
algorithm.algorithm algorithm.algorithm,
models::projects::ProjectStatus::Rejected.to_string()
) )
.fetch_optional(&**pool) .fetch_optional(&**pool)
.await?; .await?;
@@ -81,10 +86,13 @@ pub async fn download_version(
SELECT f.url url, f.id id, f.version_id version_id, v.mod_id project_id FROM hashes h SELECT f.url url, f.id id, f.version_id version_id, v.mod_id project_id FROM hashes h
INNER JOIN files f ON h.file_id = f.id INNER JOIN files f ON h.file_id = f.id
INNER JOIN versions v ON v.id = f.version_id INNER JOIN versions v ON v.id = f.version_id
WHERE h.algorithm = $2 AND h.hash = $1 INNER JOIN mods m on v.mod_id = m.id
INNER JOIN statuses s on m.status = s.id
WHERE h.algorithm = $2 AND h.hash = $1 AND s.status != $3
", ",
hash.as_bytes(), hash.as_bytes(),
algorithm.algorithm algorithm.algorithm,
models::projects::ProjectStatus::Rejected.to_string()
) )
.fetch_optional(&mut *transaction) .fetch_optional(&mut *transaction)
.await?; .await?;
@@ -242,10 +250,13 @@ pub async fn get_update_from_hash(
SELECT v.mod_id project_id FROM hashes h SELECT v.mod_id project_id FROM hashes h
INNER JOIN files f ON h.file_id = f.id INNER JOIN files f ON h.file_id = f.id
INNER JOIN versions v ON v.id = f.version_id INNER JOIN versions v ON v.id = f.version_id
WHERE h.algorithm = $2 AND h.hash = $1 INNER JOIN mods m on v.mod_id = m.id
INNER JOIN statuses s on m.status = s.id
WHERE h.algorithm = $2 AND h.hash = $1 AND s.status != $3
", ",
hash.as_bytes(), hash.as_bytes(),
algorithm.algorithm algorithm.algorithm,
models::projects::ProjectStatus::Rejected.to_string()
) )
.fetch_optional(&**pool) .fetch_optional(&**pool)
.await?; .await?;
@@ -310,10 +321,14 @@ pub async fn get_versions_from_hashes(
" "
SELECT h.hash hash, h.algorithm algorithm, f.version_id version_id FROM hashes h SELECT h.hash hash, h.algorithm algorithm, f.version_id version_id FROM hashes h
INNER JOIN files f ON h.file_id = f.id INNER JOIN files f ON h.file_id = f.id
WHERE h.algorithm = $2 AND h.hash = ANY($1::bytea[]) INNER JOIN versions v ON v.id = f.version_id
INNER JOIN mods m on v.mod_id = m.id
INNER JOIN statuses s on m.status = s.id
WHERE h.algorithm = $2 AND h.hash = ANY($1::bytea[]) AND s.status != $3
", ",
hashes_parsed.as_slice(), hashes_parsed.as_slice(),
file_data.algorithm file_data.algorithm,
models::projects::ProjectStatus::Rejected.to_string()
) )
.fetch_all(&**pool) .fetch_all(&**pool)
.await?; .await?;
@@ -370,10 +385,13 @@ pub async fn download_files(
SELECT f.url url, h.hash hash, h.algorithm algorithm, f.version_id version_id, v.mod_id project_id FROM hashes h SELECT f.url url, h.hash hash, h.algorithm algorithm, f.version_id version_id, v.mod_id project_id FROM hashes h
INNER JOIN files f ON h.file_id = f.id INNER JOIN files f ON h.file_id = f.id
INNER JOIN versions v ON v.id = f.version_id INNER JOIN versions v ON v.id = f.version_id
WHERE h.algorithm = $2 AND h.hash = ANY($1::bytea[]) INNER JOIN mods m on v.mod_id = m.id
INNER JOIN statuses s on m.status = s.id
WHERE h.algorithm = $2 AND h.hash = ANY($1::bytea[]) AND s.status != $3
", ",
hashes_parsed.as_slice(), hashes_parsed.as_slice(),
file_data.algorithm file_data.algorithm,
models::projects::ProjectStatus::Rejected.to_string()
) )
.fetch_all(&mut *transaction) .fetch_all(&mut *transaction)
.await?; .await?;
@@ -421,10 +439,13 @@ pub async fn update_files(
SELECT f.url url, h.hash hash, h.algorithm algorithm, f.version_id version_id, v.mod_id project_id FROM hashes h SELECT f.url url, h.hash hash, h.algorithm algorithm, f.version_id version_id, v.mod_id project_id FROM hashes h
INNER JOIN files f ON h.file_id = f.id INNER JOIN files f ON h.file_id = f.id
INNER JOIN versions v ON v.id = f.version_id INNER JOIN versions v ON v.id = f.version_id
WHERE h.algorithm = $2 AND h.hash = ANY($1::bytea[]) INNER JOIN mods m on v.mod_id = m.id
INNER JOIN statuses s on m.status = s.id
WHERE h.algorithm = $2 AND h.hash = ANY($1::bytea[]) AND s.status != $3
", ",
hashes_parsed.as_slice(), hashes_parsed.as_slice(),
update_data.algorithm update_data.algorithm,
models::projects::ProjectStatus::Rejected.to_string()
) )
.fetch_all(&mut *transaction) .fetch_all(&mut *transaction)
.await?; .await?;

View File

@@ -14,7 +14,7 @@ pub enum AuthenticationError {
#[error("An unknown database error occurred")] #[error("An unknown database error occurred")]
Sqlx(#[from] sqlx::Error), Sqlx(#[from] sqlx::Error),
#[error("Database Error: {0}")] #[error("Database Error: {0}")]
Database(#[from] crate::database::models::DatabaseError), Database(#[from] models::DatabaseError),
#[error("Error while parsing JSON: {0}")] #[error("Error while parsing JSON: {0}")]
SerDe(#[from] serde_json::Error), SerDe(#[from] serde_json::Error),
#[error("Error while communicating to GitHub OAuth2: {0}")] #[error("Error while communicating to GitHub OAuth2: {0}")]