* More mod info

* Downloading mods

* Run prepare

* User editing + icon editing

* Finish

* Some fixes

* Fix clippy errors

* Fix hash lookup

* Run prepare

* Run formatter
This commit is contained in:
Geometrically 2020-11-29 14:27:40 -07:00 committed by GitHub
parent 1da5357df6
commit a7be6504a2
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 204 additions and 185 deletions

View File

@ -825,6 +825,51 @@
"nullable": []
}
},
"389088b3ccff3a3c970aba3deef8831cca140b74ffc74e43a1162a9021428820": {
"query": "\n SELECT f.id id, f.version_id version_id, f.filename filename, v.version_number version_number, v.mod_id mod_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": "id",
"type_info": "Int8"
},
{
"ordinal": 1,
"name": "version_id",
"type_info": "Int8"
},
{
"ordinal": 2,
"name": "filename",
"type_info": "Varchar"
},
{
"ordinal": 3,
"name": "version_number",
"type_info": "Varchar"
},
{
"ordinal": 4,
"name": "mod_id",
"type_info": "Int8"
}
],
"parameters": {
"Left": [
"Bytea",
"Text"
]
},
"nullable": [
false,
false,
false,
false,
false
]
}
},
"398ac436f5fe2f6a66544204b9ff01ae1ea1204edf03ffc16de657a861cfe0ba": {
"query": "\n DELETE FROM categories\n WHERE category = $1\n ",
"describe": {
@ -1220,31 +1265,16 @@
"nullable": []
}
},
"55df56cd9938bca0edbf8d91649c8ce6d946125ad64e570ab127f6d9c6061787": {
"query": "\n SELECT version_id, filename FROM files\n INNER JOIN hashes ON hash = $1 AND algorithm = $2\n ",
"5322e7791400b47640f897f3e32d9a0f2915da7d71a34c4e6bf6bd648cfaaa6e": {
"query": "\n DELETE FROM files\n WHERE files.id = $1\n ",
"describe": {
"columns": [
{
"ordinal": 0,
"name": "version_id",
"type_info": "Int8"
},
{
"ordinal": 1,
"name": "filename",
"type_info": "Varchar"
}
],
"columns": [],
"parameters": {
"Left": [
"Bytea",
"Text"
"Int8"
]
},
"nullable": [
false,
false
]
"nullable": []
}
},
"560c3ba57c965c3ebdbe393b062da8a30a8a7116a9bace2aa7de2e8431fe0bc7": {
@ -1489,45 +1519,6 @@
]
}
},
"6a0d8560c0a392f66023b4186834f84d822e797b0c8b5ad360ef93a2c2300319": {
"query": "\n SELECT f.url url, f.id id, f.version_id version_id, v.mod_id mod_id FROM files f\n INNER JOIN versions v ON v.id = f.version_id\n INNER JOIN hashes ON hash = $1 AND algorithm = $2\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": "mod_id",
"type_info": "Int8"
}
],
"parameters": {
"Left": [
"Bytea",
"Text"
]
},
"nullable": [
false,
false,
false,
false
]
}
},
"6b28cb8b54ef57c9b6f03607611f688455f0e2b27eb5deda5a8cbc5b506b4602": {
"query": "\n DELETE FROM mods\n WHERE id = $1\n ",
"describe": {
@ -2042,6 +2033,27 @@
"nullable": []
}
},
"79d30dd9fe16ac93ece0b6272811e1b644bac8f61b446dceca46a16cb69953a1": {
"query": "\n SELECT 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 = $1\n ",
"describe": {
"columns": [
{
"ordinal": 0,
"name": "version_id",
"type_info": "Int8"
}
],
"parameters": {
"Left": [
"Bytea",
"Text"
]
},
"nullable": [
false
]
}
},
"7bbbeecf3246a8e07ad073a07f7d057e0990a810d69ae18cec41de60b704b174": {
"query": "\n SELECT id, user_id, member_name, role, permissions, accepted\n FROM team_members\n WHERE (team_id = $1 AND user_id = $2 AND accepted = TRUE)\n ",
"describe": {
@ -2153,27 +2165,6 @@
"nullable": []
}
},
"96585aa2586e69eeae18f5a0c97a93d2c221c8a97470e5f59839b1a52b2e353a": {
"query": "\n SELECT version_id FROM files\n INNER JOIN hashes ON hash = $1 AND algorithm = $2\n ",
"describe": {
"columns": [
{
"ordinal": 0,
"name": "version_id",
"type_info": "Int8"
}
],
"parameters": {
"Left": [
"Bytea",
"Text"
]
},
"nullable": [
false
]
}
},
"97143e41c18d191d09d244113b7b6cdf5bd6ab89c62ac46d0980d700ab288f48": {
"query": "\n SELECT name FROM side_types\n WHERE id = $1\n ",
"describe": {
@ -2252,18 +2243,6 @@
"nullable": []
}
},
"9ef9174fa003186a07fbf465e9ac083f6d452cf3c702c6ca05b1f3bbc0e30b5a": {
"query": "\n DELETE FROM files\n WHERE files.version_id = $1\n ",
"describe": {
"columns": [],
"parameters": {
"Left": [
"Int8"
]
},
"nullable": []
}
},
"a28188c4840d0f3449379b3bba6b3c4af9483e01f50fd56785317398a59881ca": {
"query": "\n SELECT files.id, files.url, files.filename, files.is_primary FROM files\n WHERE files.version_id = $1\n ",
"describe": {
@ -2338,6 +2317,45 @@
"nullable": []
}
},
"a8f22bd234488500b06855c8258e1e290696adba0766b46640bf87d91b150518": {
"query": "\n SELECT f.url url, f.id id, f.version_id version_id, v.mod_id mod_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": "mod_id",
"type_info": "Int8"
}
],
"parameters": {
"Left": [
"Bytea",
"Text"
]
},
"nullable": [
false,
false,
false,
false
]
}
},
"a90bb6904e1b790c0e29e060dac5ba4c2a6087e07c1197dc1f59f0aff31944c9": {
"query": "\n DELETE FROM states\n WHERE expires < CURRENT_DATE\n ",
"describe": {

View File

@ -459,9 +459,9 @@ impl Mod {
",
inner.client_side.0,
)
.fetch_one(executor)
.await?
.name;
.fetch_one(executor)
.await?
.name;
let server_side = sqlx::query!(
"
@ -470,9 +470,9 @@ impl Mod {
",
inner.server_side.0,
)
.fetch_one(executor)
.await?
.name;
.fetch_one(executor)
.await?
.name;
let license = sqlx::query!(
"
@ -481,8 +481,8 @@ impl Mod {
",
inner.license.0,
)
.fetch_one(executor)
.await?;
.fetch_one(executor)
.await?;
Ok(Some(QueryMod {
inner,
@ -493,7 +493,7 @@ impl Mod {
license_id: license.short,
license_name: license.name,
client_side: crate::models::mods::SideType::from_str(&client_side),
server_side: crate::models::mods::SideType::from_str(&server_side)
server_side: crate::models::mods::SideType::from_str(&server_side),
}))
} else {
Ok(None)

View File

@ -173,11 +173,14 @@ async fn main() -> std::io::Result<()> {
WHERE date < (CURRENT_DATE - INTERVAL '30 minutes ago')
"
)
.execute(&pool_ref)
.await;
.execute(&pool_ref)
.await;
if let Err(e) = downloads_result {
warn!("Deleting old records from temporary table downloads failed: {:?}", e);
warn!(
"Deleting old records from temporary table downloads failed: {:?}",
e
);
}
let states_result = sqlx::query!(
@ -186,16 +189,18 @@ async fn main() -> std::io::Result<()> {
WHERE expires < CURRENT_DATE
"
)
.execute(&pool_ref)
.await;
.execute(&pool_ref)
.await;
if let Err(e) = states_result {
warn!("Deleting old records from temporary table states failed: {:?}", e);
warn!(
"Deleting old records from temporary table states failed: {:?}",
e
);
}
info!("Finished deleting old records from temporary tables");
}
});
let indexing_queue = Arc::new(search::indexing::queue::CreationQueue::new());
@ -260,7 +265,7 @@ async fn main() -> std::io::Result<()> {
scheduler::schedule_versions(&mut scheduler, pool.clone(), skip_initial);
let ip_salt = Pepper {
pepper: crate::models::ids::Base62Id(crate::models::ids::random_base62(11)).to_string()
pepper: crate::models::ids::Base62Id(crate::models::ids::random_base62(11)).to_string(),
};
let allowed_origins = dotenv::var("CORS_ORIGINS")

View File

@ -2,12 +2,12 @@ use super::ApiError;
use crate::auth::check_is_moderator_from_headers;
use crate::database;
use crate::models;
use crate::models::mods::{ModStatus, VersionType, ModId};
use actix_web::{get, web, HttpRequest, HttpResponse};
use serde::{Serialize, Deserialize};
use sqlx::PgPool;
use sqlx::types::chrono::{DateTime, Utc};
use crate::models::mods::{ModId, ModStatus, VersionType};
use crate::models::teams::TeamId;
use actix_web::{get, web, HttpRequest, HttpResponse};
use serde::{Deserialize, Serialize};
use sqlx::types::chrono::{DateTime, Utc};
use sqlx::PgPool;
#[derive(Deserialize)]
pub struct ResultCount {

View File

@ -350,7 +350,9 @@ pub async fn mod_edit(
));
}
if (status == &ModStatus::Rejected || status == &ModStatus::Approved) && !user.role.is_mod() {
if (status == &ModStatus::Rejected || status == &ModStatus::Approved)
&& !user.role.is_mod()
{
return Err(ApiError::CustomAuthenticationError(
"You don't have permission to set this status".to_string(),
));

View File

@ -45,10 +45,7 @@ pub async fn users_get(
.await
.map_err(|e| ApiError::DatabaseError(e.into()))?;
let users: Vec<crate::models::users::User> = users_data
.into_iter()
.map(convert_user)
.collect();
let users: Vec<crate::models::users::User> = users_data.into_iter().map(convert_user).collect();
Ok(HttpResponse::Ok().json(users))
}

View File

@ -1,9 +1,9 @@
use super::ApiError;
use crate::auth::{check_is_moderator_from_headers, get_user_from_headers};
use crate::{database, Pepper};
use crate::file_hosting::FileHost;
use crate::models;
use crate::models::teams::Permissions;
use crate::{database, Pepper};
use actix_web::{delete, get, patch, web, HttpRequest, HttpResponse};
use serde::{Deserialize, Serialize};
use sqlx::PgPool;
@ -117,23 +117,27 @@ pub async fn version_get(
let user_option = get_user_from_headers(req.headers(), &**pool).await.ok();
if let Some(data) = version_data {
if let Some(user) = user_option {
if !data.accepted && !user.role.is_mod() {
let user_id: database::models::ids::UserId = user.id.into();
if !data.accepted {
if let Some(user) = user_option {
if !user.role.is_mod() {
let user_id: database::models::ids::UserId = user.id.into();
let member_exists = sqlx::query!(
"SELECT EXISTS(SELECT 1 FROM team_members tm INNER JOIN mods m ON m.team_id = tm.id AND m.id = $1 WHERE tm.user_id = $2)",
data.mod_id as database::models::ModId,
user_id as database::models::ids::UserId,
)
.fetch_one(&**pool)
.await
.map_err(|e| ApiError::DatabaseError(e.into()))?
.exists;
let member_exists = sqlx::query!(
"SELECT EXISTS(SELECT 1 FROM team_members tm INNER JOIN mods m ON m.team_id = tm.id AND m.id = $1 WHERE tm.user_id = $2)",
data.mod_id as database::models::ModId,
user_id as database::models::ids::UserId,
)
.fetch_one(&**pool)
.await
.map_err(|e| ApiError::DatabaseError(e.into()))?
.exists;
if !member_exists.unwrap_or(false) {
return Ok(HttpResponse::NotFound().body(""));
if !member_exists.unwrap_or(false) {
return Ok(HttpResponse::NotFound().body(""));
}
}
} else {
return Ok(HttpResponse::NotFound().body(""));
}
}
@ -553,8 +557,9 @@ pub async fn get_version_from_hash(
let result = sqlx::query!(
"
SELECT version_id FROM files
INNER JOIN hashes ON hash = $1 AND algorithm = $2
SELECT f.version_id version_id FROM hashes h
INNER JOIN files f ON h.file_id = f.id
WHERE h.algorithm = $2 AND h.hash = $1
",
hash.as_bytes(),
algorithm.algorithm
@ -599,9 +604,10 @@ pub async fn download_version(
let result = sqlx::query!(
"
SELECT f.url url, f.id id, f.version_id version_id, v.mod_id mod_id FROM files f
SELECT f.url url, f.id id, f.version_id version_id, v.mod_id mod_id FROM hashes h
INNER JOIN files f ON h.file_id = f.id
INNER JOIN versions v ON v.id = f.version_id
INNER JOIN hashes ON hash = $1 AND algorithm = $2
WHERE h.algorithm = $2 AND h.hash = $1
",
hash.as_bytes(),
algorithm.algorithm
@ -692,8 +698,10 @@ pub async fn delete_file(
let result = sqlx::query!(
"
SELECT version_id, filename FROM files
INNER JOIN hashes ON hash = $1 AND algorithm = $2
SELECT f.id id, f.version_id version_id, f.filename filename, v.version_number version_number, v.mod_id mod_id FROM hashes h
INNER JOIN files f ON h.file_id = f.id
INNER JOIN versions v ON v.id = f.version_id
WHERE h.algorithm = $2 AND h.hash = $1
",
hash.as_bytes(),
algorithm.algorithm
@ -703,62 +711,51 @@ pub async fn delete_file(
.map_err(|e| ApiError::DatabaseError(e.into()))?;
if let Some(row) = result {
let version_data = database::models::Version::get_full(
database::models::VersionId(row.version_id),
&**pool,
)
.await
.map_err(|e| ApiError::DatabaseError(e.into()))?;
let mut transaction = pool
.begin()
.await
.map_err(|e| ApiError::DatabaseError(e.into()))?;
if let Some(data) = version_data {
let mut transaction = pool
.begin()
.await
.map_err(|e| ApiError::DatabaseError(e.into()))?;
sqlx::query!(
"
sqlx::query!(
"
DELETE FROM hashes
WHERE hash = $1 AND algorithm = $2
",
hash.as_bytes(),
algorithm.algorithm
)
.execute(&mut *transaction)
.await
.map_err(|e| ApiError::DatabaseError(e.into()))?;
hash.as_bytes(),
algorithm.algorithm
)
.execute(&mut *transaction)
.await
.map_err(|e| ApiError::DatabaseError(e.into()))?;
sqlx::query!(
"
sqlx::query!(
"
DELETE FROM files
WHERE files.version_id = $1
WHERE files.id = $1
",
data.id as database::models::ids::VersionId,
row.id,
)
.execute(&mut *transaction)
.await
.map_err(|e| ApiError::DatabaseError(e.into()))?;
let mod_id: models::mods::ModId = database::models::ids::ModId(row.mod_id).into();
file_host
.delete_file_version(
"",
&format!(
"data/{}/versions/{}/{}",
mod_id, row.version_number, row.filename
),
)
.execute(&mut *transaction)
.await?;
transaction
.commit()
.await
.map_err(|e| ApiError::DatabaseError(e.into()))?;
let mod_id: models::mods::ModId = data.mod_id.into();
file_host
.delete_file_version(
"",
&format!(
"data/{}/versions/{}/{}",
mod_id, data.version_number, row.filename
),
)
.await?;
transaction
.commit()
.await
.map_err(|e| ApiError::DatabaseError(e.into()))?;
Ok(HttpResponse::Ok().body(""))
} else {
Ok(HttpResponse::NotFound().body(""))
}
Ok(HttpResponse::Ok().body(""))
} else {
Ok(HttpResponse::NotFound().body(""))
}