Maven endpoint support (#180)
* Basic maven endpoint * Clean up maven endpoint * cargo sqlx prepare * Minor cleanup * Remove indentation * Borrow &str instead of &String * Refactor mod_data-getting
This commit is contained in:
parent
b98ad47618
commit
15c56dfcb8
27
Cargo.lock
generated
27
Cargo.lock
generated
@ -1,5 +1,7 @@
|
|||||||
# This file is automatically @generated by Cargo.
|
# This file is automatically @generated by Cargo.
|
||||||
# It is not intended for manual editing.
|
# It is not intended for manual editing.
|
||||||
|
version = 3
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "actix"
|
name = "actix"
|
||||||
version = "0.10.0"
|
version = "0.10.0"
|
||||||
@ -1991,6 +1993,9 @@ dependencies = [
|
|||||||
"sha2",
|
"sha2",
|
||||||
"sqlx",
|
"sqlx",
|
||||||
"thiserror",
|
"thiserror",
|
||||||
|
"xml-rs",
|
||||||
|
"yaserde",
|
||||||
|
"yaserde_derive",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@ -4313,3 +4318,25 @@ name = "xml-rs"
|
|||||||
version = "0.8.3"
|
version = "0.8.3"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "b07db065a5cf61a7e4ba64f29e67db906fb1787316516c4e6e5ff0fea1efcd8a"
|
checksum = "b07db065a5cf61a7e4ba64f29e67db906fb1787316516c4e6e5ff0fea1efcd8a"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "yaserde"
|
||||||
|
version = "0.6.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "bc096efbee9ec8fee0600a15bb4fd651ccc14570cb05b6d4dd66b0325e4a0b5e"
|
||||||
|
dependencies = [
|
||||||
|
"log",
|
||||||
|
"xml-rs",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "yaserde_derive"
|
||||||
|
version = "0.6.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "9af81f1d48039716dd825cf4a7d61d39583f8b12705994abb446bae749a977bb"
|
||||||
|
dependencies = [
|
||||||
|
"heck",
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"syn",
|
||||||
|
]
|
||||||
|
|||||||
@ -22,6 +22,10 @@ actix-ratelimit = "0.3.0"
|
|||||||
meilisearch-sdk = "0.6.0"
|
meilisearch-sdk = "0.6.0"
|
||||||
reqwest = { version = "0.10.8", features = ["json"] }
|
reqwest = { version = "0.10.8", features = ["json"] }
|
||||||
|
|
||||||
|
yaserde = "0.6.0"
|
||||||
|
yaserde_derive = "0.6.0"
|
||||||
|
xml-rs = "0.8.3"
|
||||||
|
|
||||||
serde_json = "1.0"
|
serde_json = "1.0"
|
||||||
serde = { version = "1.0", features = ["derive"] }
|
serde = { version = "1.0", features = ["derive"] }
|
||||||
serde_with = "1.5.1"
|
serde_with = "1.5.1"
|
||||||
|
|||||||
@ -310,6 +310,27 @@
|
|||||||
]
|
]
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"153100dc632392c4d446cc768235d071bac26a0818a4a72d203d8e549f969eea": {
|
||||||
|
"query": "SELECT id FROM versions WHERE mod_id = $1 AND version_number = $2",
|
||||||
|
"describe": {
|
||||||
|
"columns": [
|
||||||
|
{
|
||||||
|
"ordinal": 0,
|
||||||
|
"name": "id",
|
||||||
|
"type_info": "Int8"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"parameters": {
|
||||||
|
"Left": [
|
||||||
|
"Int8",
|
||||||
|
"Text"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"nullable": [
|
||||||
|
false
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
"15b8ea323c2f6d03c2e385d9c46d7f13460764f2f106fd638226c42ae0217f75": {
|
"15b8ea323c2f6d03c2e385d9c46d7f13460764f2f106fd638226c42ae0217f75": {
|
||||||
"query": "\n DELETE FROM notifications\n WHERE user_id = $1\n ",
|
"query": "\n DELETE FROM notifications\n WHERE user_id = $1\n ",
|
||||||
"describe": {
|
"describe": {
|
||||||
@ -4283,6 +4304,32 @@
|
|||||||
"nullable": []
|
"nullable": []
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"cdd51904a4617d8a2616d9ad4b4274fa2e66e87db1825496854021a26798207c": {
|
||||||
|
"query": "\n SELECT version_number, release_channels.channel channel\n FROM versions\n LEFT JOIN release_channels ON release_channels.id = versions.release_channel\n WHERE mod_id = $1\n ",
|
||||||
|
"describe": {
|
||||||
|
"columns": [
|
||||||
|
{
|
||||||
|
"ordinal": 0,
|
||||||
|
"name": "version_number",
|
||||||
|
"type_info": "Varchar"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"ordinal": 1,
|
||||||
|
"name": "channel",
|
||||||
|
"type_info": "Varchar"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"parameters": {
|
||||||
|
"Left": [
|
||||||
|
"Int8"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"nullable": [
|
||||||
|
false,
|
||||||
|
false
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
"cdd7f8f95c308d9474e214d584c03be0466214da1e157f6bc577b76dbef7df86": {
|
"cdd7f8f95c308d9474e214d584c03be0466214da1e157f6bc577b76dbef7df86": {
|
||||||
"query": "\n DELETE FROM hashes\n WHERE file_id = $1\n ",
|
"query": "\n DELETE FROM hashes\n WHERE file_id = $1\n ",
|
||||||
"describe": {
|
"describe": {
|
||||||
|
|||||||
@ -405,7 +405,7 @@ impl Mod {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub async fn get_full_from_slug<'a, 'b, E>(
|
pub async fn get_full_from_slug<'a, 'b, E>(
|
||||||
slug: String,
|
slug: &str,
|
||||||
executor: E,
|
executor: E,
|
||||||
) -> Result<Option<QueryMod>, sqlx::error::Error>
|
) -> Result<Option<QueryMod>, sqlx::error::Error>
|
||||||
where
|
where
|
||||||
|
|||||||
@ -310,6 +310,7 @@ async fn main() -> std::io::Result<()> {
|
|||||||
.configure(routes::reports_config)
|
.configure(routes::reports_config)
|
||||||
.configure(routes::notifications_config),
|
.configure(routes::notifications_config),
|
||||||
)
|
)
|
||||||
|
.service(web::scope("/maven/").configure(routes::maven_config))
|
||||||
.default_service(web::get().to(routes::not_found))
|
.default_service(web::get().to(routes::not_found))
|
||||||
})
|
})
|
||||||
.bind(dotenv::var("BIND_ADDR").unwrap())?
|
.bind(dotenv::var("BIND_ADDR").unwrap())?
|
||||||
|
|||||||
257
src/routes/maven.rs
Normal file
257
src/routes/maven.rs
Normal file
@ -0,0 +1,257 @@
|
|||||||
|
use crate::auth::get_user_from_headers;
|
||||||
|
use crate::database;
|
||||||
|
use crate::models::mods::ModId;
|
||||||
|
use crate::routes::ApiError;
|
||||||
|
use actix_web::{get, web, HttpRequest, HttpResponse};
|
||||||
|
use sqlx::PgPool;
|
||||||
|
use yaserde_derive::YaSerialize;
|
||||||
|
|
||||||
|
#[derive(Default, Debug, Clone, YaSerialize)]
|
||||||
|
#[yaserde(root = "metadata", rename = "metadata")]
|
||||||
|
pub struct Metadata {
|
||||||
|
#[yaserde(rename = "groupId")]
|
||||||
|
group_id: String,
|
||||||
|
#[yaserde(rename = "artifactId")]
|
||||||
|
artifact_id: String,
|
||||||
|
versioning: Versioning,
|
||||||
|
}
|
||||||
|
#[derive(Default, Debug, Clone, YaSerialize)]
|
||||||
|
#[yaserde(rename = "versioning")]
|
||||||
|
pub struct Versioning {
|
||||||
|
latest: String,
|
||||||
|
release: String,
|
||||||
|
versions: Versions,
|
||||||
|
#[yaserde(rename = "lastUpdated")]
|
||||||
|
last_updated: String,
|
||||||
|
}
|
||||||
|
#[derive(Default, Debug, Clone, YaSerialize)]
|
||||||
|
#[yaserde(rename = "versions")]
|
||||||
|
pub struct Versions {
|
||||||
|
#[yaserde(rename = "version")]
|
||||||
|
versions: Vec<String>,
|
||||||
|
}
|
||||||
|
#[derive(Default, Debug, Clone, YaSerialize)]
|
||||||
|
#[yaserde(rename = "project", namespace = "http://maven.apache.org/POM/4.0.0")]
|
||||||
|
pub struct MavenPom {
|
||||||
|
#[yaserde(rename = "xsi:schemaLocation", attribute)]
|
||||||
|
schema_location: String,
|
||||||
|
#[yaserde(rename = "xmlns:xsi", attribute)]
|
||||||
|
xsi: String,
|
||||||
|
#[yaserde(rename = "modelVersion")]
|
||||||
|
model_version: String,
|
||||||
|
#[yaserde(rename = "groupId")]
|
||||||
|
group_id: String,
|
||||||
|
#[yaserde(rename = "artifactId")]
|
||||||
|
artifact_id: String,
|
||||||
|
version: String,
|
||||||
|
name: String,
|
||||||
|
description: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[get("maven/modrinth/{id}/maven-metadata.xml")]
|
||||||
|
pub async fn maven_metadata(
|
||||||
|
req: HttpRequest,
|
||||||
|
info: web::Path<(String,)>,
|
||||||
|
pool: web::Data<PgPool>,
|
||||||
|
) -> Result<HttpResponse, ApiError> {
|
||||||
|
let string = info.into_inner().0;
|
||||||
|
let id_option: Option<ModId> = serde_json::from_str(&*format!("\"{}\"", string)).ok();
|
||||||
|
|
||||||
|
let mod_data = if let Some(id) = id_option {
|
||||||
|
match database::models::Mod::get_full(id.into(), &**pool).await {
|
||||||
|
Ok(Some(data)) => Ok(Some(data)),
|
||||||
|
Ok(None) => database::models::Mod::get_full_from_slug(&string, &**pool).await,
|
||||||
|
Err(e) => Err(e),
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
database::models::Mod::get_full_from_slug(&string, &**pool).await
|
||||||
|
}
|
||||||
|
.map_err(|e| ApiError::DatabaseError(e.into()))?;
|
||||||
|
|
||||||
|
let user_option = get_user_from_headers(req.headers(), &**pool).await.ok();
|
||||||
|
|
||||||
|
let data = if let Some(data) = mod_data {
|
||||||
|
data
|
||||||
|
} else {
|
||||||
|
return Ok(HttpResponse::NotFound().body(""));
|
||||||
|
};
|
||||||
|
|
||||||
|
let mut authorized = !data.status.is_hidden();
|
||||||
|
|
||||||
|
if let Some(user) = user_option {
|
||||||
|
if !authorized {
|
||||||
|
if user.role.is_mod() {
|
||||||
|
authorized = true;
|
||||||
|
} else {
|
||||||
|
let user_id: database::models::ids::UserId = user.id.into();
|
||||||
|
|
||||||
|
let mod_exists = sqlx::query!(
|
||||||
|
"SELECT EXISTS(SELECT 1 FROM team_members WHERE team_id = $1 AND user_id = $2)",
|
||||||
|
data.inner.team_id as database::models::ids::TeamId,
|
||||||
|
user_id as database::models::ids::UserId,
|
||||||
|
)
|
||||||
|
.fetch_one(&**pool)
|
||||||
|
.await
|
||||||
|
.map_err(|e| ApiError::DatabaseError(e.into()))?
|
||||||
|
.exists;
|
||||||
|
|
||||||
|
authorized = mod_exists.unwrap_or(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if !authorized {
|
||||||
|
return Ok(HttpResponse::NotFound().body(""));
|
||||||
|
}
|
||||||
|
let version_names = sqlx::query!(
|
||||||
|
"
|
||||||
|
SELECT version_number, release_channels.channel channel
|
||||||
|
FROM versions
|
||||||
|
LEFT JOIN release_channels ON release_channels.id = versions.release_channel
|
||||||
|
WHERE mod_id = $1
|
||||||
|
",
|
||||||
|
data.inner.id as database::models::ids::ModId
|
||||||
|
)
|
||||||
|
.fetch_all(&**pool)
|
||||||
|
.await
|
||||||
|
.map_err(|e| ApiError::DatabaseError(e.into()))?;
|
||||||
|
|
||||||
|
let respdata = Metadata {
|
||||||
|
group_id: "maven.modrinth".to_string(),
|
||||||
|
artifact_id: string,
|
||||||
|
versioning: Versioning {
|
||||||
|
latest: version_names
|
||||||
|
.last()
|
||||||
|
.map_or("release", |x| &x.version_number)
|
||||||
|
.to_string(),
|
||||||
|
release: version_names
|
||||||
|
.iter()
|
||||||
|
.rfind(|x| x.channel == "release")
|
||||||
|
.map_or("", |x| &x.version_number)
|
||||||
|
.to_string(),
|
||||||
|
versions: Versions {
|
||||||
|
versions: version_names
|
||||||
|
.iter()
|
||||||
|
.map(|x| x.version_number.clone())
|
||||||
|
.collect::<Vec<_>>(),
|
||||||
|
},
|
||||||
|
last_updated: data.inner.updated.format("%Y%m%d%H%M%S").to_string(),
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
Ok(HttpResponse::Ok()
|
||||||
|
.content_type("text/xml")
|
||||||
|
.body(yaserde::ser::to_string(&respdata).map_err(|e| ApiError::XmlError(e))?))
|
||||||
|
}
|
||||||
|
|
||||||
|
#[get("maven/modrinth/{id}/{versionnum}/{file}")]
|
||||||
|
pub async fn version_file(
|
||||||
|
req: HttpRequest,
|
||||||
|
web::Path((string, vnum, file)): web::Path<(String, String, String)>,
|
||||||
|
pool: web::Data<PgPool>,
|
||||||
|
) -> Result<HttpResponse, ApiError> {
|
||||||
|
let id_option: Option<ModId> = serde_json::from_str(&*format!("\"{}\"", string)).ok();
|
||||||
|
|
||||||
|
let mod_data = if let Some(id) = id_option {
|
||||||
|
match database::models::Mod::get_full(id.into(), &**pool).await {
|
||||||
|
Ok(Some(data)) => Ok(Some(data)),
|
||||||
|
Ok(None) => database::models::Mod::get_full_from_slug(&string, &**pool).await,
|
||||||
|
Err(e) => Err(e),
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
database::models::Mod::get_full_from_slug(&string, &**pool).await
|
||||||
|
}
|
||||||
|
.map_err(|e| ApiError::DatabaseError(e.into()))?;
|
||||||
|
|
||||||
|
let user_option = get_user_from_headers(req.headers(), &**pool).await.ok();
|
||||||
|
|
||||||
|
let data = if let Some(data) = mod_data {
|
||||||
|
data
|
||||||
|
} else {
|
||||||
|
return Ok(HttpResponse::NotFound().body(""));
|
||||||
|
};
|
||||||
|
|
||||||
|
let mut authorized = !data.status.is_hidden();
|
||||||
|
|
||||||
|
if let Some(user) = user_option {
|
||||||
|
if !authorized {
|
||||||
|
if user.role.is_mod() {
|
||||||
|
authorized = true;
|
||||||
|
} else {
|
||||||
|
let user_id: database::models::ids::UserId = user.id.into();
|
||||||
|
|
||||||
|
let mod_exists = sqlx::query!(
|
||||||
|
"SELECT EXISTS(SELECT 1 FROM team_members WHERE team_id = $1 AND user_id = $2)",
|
||||||
|
data.inner.team_id as database::models::ids::TeamId,
|
||||||
|
user_id as database::models::ids::UserId,
|
||||||
|
)
|
||||||
|
.fetch_one(&**pool)
|
||||||
|
.await
|
||||||
|
.map_err(|e| ApiError::DatabaseError(e.into()))?
|
||||||
|
.exists;
|
||||||
|
|
||||||
|
authorized = mod_exists.unwrap_or(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if !authorized {
|
||||||
|
return Ok(HttpResponse::NotFound().body(""));
|
||||||
|
}
|
||||||
|
|
||||||
|
let vid = if let Some(vid) = sqlx::query!(
|
||||||
|
"SELECT id FROM versions WHERE mod_id = $1 AND version_number = $2",
|
||||||
|
data.inner.id as database::models::ids::ModId,
|
||||||
|
vnum
|
||||||
|
)
|
||||||
|
.fetch_optional(&**pool)
|
||||||
|
.await
|
||||||
|
.map_err(|e| ApiError::DatabaseError(e.into()))?
|
||||||
|
{
|
||||||
|
vid
|
||||||
|
} else {
|
||||||
|
return Ok(HttpResponse::NotFound().body(""));
|
||||||
|
};
|
||||||
|
|
||||||
|
let version = if let Some(version) =
|
||||||
|
database::models::Version::get_full(database::models::ids::VersionId(vid.id), &**pool)
|
||||||
|
.await
|
||||||
|
.map_err(|e| ApiError::DatabaseError(e.into()))?
|
||||||
|
{
|
||||||
|
version
|
||||||
|
} else {
|
||||||
|
return Ok(HttpResponse::NotFound().body(""));
|
||||||
|
};
|
||||||
|
|
||||||
|
if file == format!("{}-{}.pom", &string, &version.version_number) {
|
||||||
|
let respdata = MavenPom {
|
||||||
|
schema_location:
|
||||||
|
"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"
|
||||||
|
.to_string(),
|
||||||
|
xsi: "http://www.w3.org/2001/XMLSchema-instance".to_string(),
|
||||||
|
model_version: "4.0.0".to_string(),
|
||||||
|
group_id: "maven.modrinth".to_string(),
|
||||||
|
artifact_id: string,
|
||||||
|
version: version.version_number,
|
||||||
|
name: data.inner.title,
|
||||||
|
description: data.inner.description,
|
||||||
|
};
|
||||||
|
return Ok(HttpResponse::Ok()
|
||||||
|
.content_type("text/xml")
|
||||||
|
.body(yaserde::ser::to_string(&respdata).map_err(|e| ApiError::XmlError(e))?));
|
||||||
|
} else {
|
||||||
|
if let Some(selected_file) = version.files.iter().find(|x| x.filename == file) {
|
||||||
|
return Ok(HttpResponse::TemporaryRedirect()
|
||||||
|
.header("Location", &*selected_file.url)
|
||||||
|
.body(""));
|
||||||
|
} else if file == format!("{}-{}.jar", &string, &version.version_number) {
|
||||||
|
if let Some(selected_file) = version.files.iter().last() {
|
||||||
|
return Ok(HttpResponse::TemporaryRedirect()
|
||||||
|
.header("Location", &*selected_file.url)
|
||||||
|
.body(""));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(HttpResponse::NotFound().body(""))
|
||||||
|
}
|
||||||
@ -2,6 +2,7 @@ use actix_web::web;
|
|||||||
|
|
||||||
mod auth;
|
mod auth;
|
||||||
mod index;
|
mod index;
|
||||||
|
mod maven;
|
||||||
mod mod_creation;
|
mod mod_creation;
|
||||||
mod moderation;
|
mod moderation;
|
||||||
mod mods;
|
mod mods;
|
||||||
@ -39,6 +40,11 @@ pub fn mods_config(cfg: &mut web::ServiceConfig) {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn maven_config(cfg: &mut web::ServiceConfig) {
|
||||||
|
cfg.service(maven::maven_metadata);
|
||||||
|
cfg.service(maven::version_file);
|
||||||
|
}
|
||||||
|
|
||||||
pub fn versions_config(cfg: &mut web::ServiceConfig) {
|
pub fn versions_config(cfg: &mut web::ServiceConfig) {
|
||||||
cfg.service(versions::versions_get);
|
cfg.service(versions::versions_get);
|
||||||
cfg.service(version_creation::version_create);
|
cfg.service(version_creation::version_create);
|
||||||
@ -113,6 +119,8 @@ pub enum ApiError {
|
|||||||
FileHostingError(#[from] FileHostingError),
|
FileHostingError(#[from] FileHostingError),
|
||||||
#[error("Internal server error: {0}")]
|
#[error("Internal server error: {0}")]
|
||||||
DatabaseError(#[from] crate::database::models::DatabaseError),
|
DatabaseError(#[from] crate::database::models::DatabaseError),
|
||||||
|
#[error("Internal server error: {0}")]
|
||||||
|
XmlError(String),
|
||||||
#[error("Deserialization error: {0}")]
|
#[error("Deserialization error: {0}")]
|
||||||
JsonError(#[from] serde_json::Error),
|
JsonError(#[from] serde_json::Error),
|
||||||
#[error("Authentication Error: {0}")]
|
#[error("Authentication Error: {0}")]
|
||||||
@ -134,6 +142,7 @@ impl actix_web::ResponseError for ApiError {
|
|||||||
ApiError::DatabaseError(..) => actix_web::http::StatusCode::INTERNAL_SERVER_ERROR,
|
ApiError::DatabaseError(..) => actix_web::http::StatusCode::INTERNAL_SERVER_ERROR,
|
||||||
ApiError::AuthenticationError(..) => actix_web::http::StatusCode::UNAUTHORIZED,
|
ApiError::AuthenticationError(..) => actix_web::http::StatusCode::UNAUTHORIZED,
|
||||||
ApiError::CustomAuthenticationError(..) => actix_web::http::StatusCode::UNAUTHORIZED,
|
ApiError::CustomAuthenticationError(..) => actix_web::http::StatusCode::UNAUTHORIZED,
|
||||||
|
ApiError::XmlError(..) => actix_web::http::StatusCode::INTERNAL_SERVER_ERROR,
|
||||||
ApiError::JsonError(..) => actix_web::http::StatusCode::BAD_REQUEST,
|
ApiError::JsonError(..) => actix_web::http::StatusCode::BAD_REQUEST,
|
||||||
ApiError::SearchError(..) => actix_web::http::StatusCode::INTERNAL_SERVER_ERROR,
|
ApiError::SearchError(..) => actix_web::http::StatusCode::INTERNAL_SERVER_ERROR,
|
||||||
ApiError::IndexingError(..) => actix_web::http::StatusCode::INTERNAL_SERVER_ERROR,
|
ApiError::IndexingError(..) => actix_web::http::StatusCode::INTERNAL_SERVER_ERROR,
|
||||||
@ -150,6 +159,7 @@ impl actix_web::ResponseError for ApiError {
|
|||||||
ApiError::DatabaseError(..) => "database_error",
|
ApiError::DatabaseError(..) => "database_error",
|
||||||
ApiError::AuthenticationError(..) => "unauthorized",
|
ApiError::AuthenticationError(..) => "unauthorized",
|
||||||
ApiError::CustomAuthenticationError(..) => "unauthorized",
|
ApiError::CustomAuthenticationError(..) => "unauthorized",
|
||||||
|
ApiError::XmlError(..) => "xml_error",
|
||||||
ApiError::JsonError(..) => "json_error",
|
ApiError::JsonError(..) => "json_error",
|
||||||
ApiError::SearchError(..) => "search_error",
|
ApiError::SearchError(..) => "search_error",
|
||||||
ApiError::IndexingError(..) => "indexing_error",
|
ApiError::IndexingError(..) => "indexing_error",
|
||||||
|
|||||||
@ -88,7 +88,7 @@ pub async fn mod_slug_get(
|
|||||||
pool: web::Data<PgPool>,
|
pool: web::Data<PgPool>,
|
||||||
) -> Result<HttpResponse, ApiError> {
|
) -> Result<HttpResponse, ApiError> {
|
||||||
let id = info.into_inner().0;
|
let id = info.into_inner().0;
|
||||||
let mod_data = database::models::Mod::get_full_from_slug(id, &**pool)
|
let mod_data = database::models::Mod::get_full_from_slug(&id, &**pool)
|
||||||
.await
|
.await
|
||||||
.map_err(|e| ApiError::DatabaseError(e.into()))?;
|
.map_err(|e| ApiError::DatabaseError(e.into()))?;
|
||||||
let user_option = get_user_from_headers(req.headers(), &**pool).await.ok();
|
let user_option = get_user_from_headers(req.headers(), &**pool).await.ok();
|
||||||
@ -145,12 +145,12 @@ pub async fn mod_get(
|
|||||||
.map_err(|e| ApiError::DatabaseError(e.into()))?;
|
.map_err(|e| ApiError::DatabaseError(e.into()))?;
|
||||||
|
|
||||||
if mod_data.is_none() {
|
if mod_data.is_none() {
|
||||||
mod_data = database::models::Mod::get_full_from_slug(string, &**pool)
|
mod_data = database::models::Mod::get_full_from_slug(&string, &**pool)
|
||||||
.await
|
.await
|
||||||
.map_err(|e| ApiError::DatabaseError(e.into()))?;
|
.map_err(|e| ApiError::DatabaseError(e.into()))?;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
mod_data = database::models::Mod::get_full_from_slug(string, &**pool)
|
mod_data = database::models::Mod::get_full_from_slug(&string, &**pool)
|
||||||
.await
|
.await
|
||||||
.map_err(|e| ApiError::DatabaseError(e.into()))?;
|
.map_err(|e| ApiError::DatabaseError(e.into()))?;
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user