You've already forked AstralRinth
forked from didirus/AstralRinth
Shulkers of fixes (#327)
* Shulkers of fixes * Fix validation message * Update deps * Bump docker image version
This commit is contained in:
@@ -19,61 +19,51 @@ pub fn config(cfg: &mut ServiceConfig) {
|
||||
#[derive(Error, Debug)]
|
||||
pub enum AuthorizationError {
|
||||
#[error("Environment Error")]
|
||||
EnvError(#[from] dotenv::Error),
|
||||
Env(#[from] dotenv::Error),
|
||||
#[error("An unknown database error occured: {0}")]
|
||||
SqlxDatabaseError(#[from] sqlx::Error),
|
||||
SqlxDatabase(#[from] sqlx::Error),
|
||||
#[error("Database Error: {0}")]
|
||||
DatabaseError(#[from] crate::database::models::DatabaseError),
|
||||
Database(#[from] crate::database::models::DatabaseError),
|
||||
#[error("Error while parsing JSON: {0}")]
|
||||
SerDeError(#[from] serde_json::Error),
|
||||
SerDe(#[from] serde_json::Error),
|
||||
#[error("Error while communicating to GitHub OAuth2")]
|
||||
GithubError(#[from] reqwest::Error),
|
||||
Github(#[from] reqwest::Error),
|
||||
#[error("Invalid Authentication credentials")]
|
||||
InvalidCredentialsError,
|
||||
InvalidCredentials,
|
||||
#[error("Authentication Error: {0}")]
|
||||
AuthenticationError(#[from] crate::util::auth::AuthenticationError),
|
||||
Authentication(#[from] crate::util::auth::AuthenticationError),
|
||||
#[error("Error while decoding Base62")]
|
||||
DecodingError(#[from] DecodingError),
|
||||
Decoding(#[from] DecodingError),
|
||||
}
|
||||
impl actix_web::ResponseError for AuthorizationError {
|
||||
fn status_code(&self) -> StatusCode {
|
||||
match self {
|
||||
AuthorizationError::EnvError(..) => {
|
||||
AuthorizationError::Env(..) => StatusCode::INTERNAL_SERVER_ERROR,
|
||||
AuthorizationError::SqlxDatabase(..) => {
|
||||
StatusCode::INTERNAL_SERVER_ERROR
|
||||
}
|
||||
AuthorizationError::SqlxDatabaseError(..) => {
|
||||
AuthorizationError::Database(..) => {
|
||||
StatusCode::INTERNAL_SERVER_ERROR
|
||||
}
|
||||
AuthorizationError::DatabaseError(..) => {
|
||||
StatusCode::INTERNAL_SERVER_ERROR
|
||||
}
|
||||
AuthorizationError::SerDeError(..) => StatusCode::BAD_REQUEST,
|
||||
AuthorizationError::GithubError(..) => {
|
||||
StatusCode::FAILED_DEPENDENCY
|
||||
}
|
||||
AuthorizationError::InvalidCredentialsError => {
|
||||
StatusCode::UNAUTHORIZED
|
||||
}
|
||||
AuthorizationError::DecodingError(..) => StatusCode::BAD_REQUEST,
|
||||
AuthorizationError::AuthenticationError(..) => {
|
||||
StatusCode::UNAUTHORIZED
|
||||
}
|
||||
AuthorizationError::SerDe(..) => StatusCode::BAD_REQUEST,
|
||||
AuthorizationError::Github(..) => StatusCode::FAILED_DEPENDENCY,
|
||||
AuthorizationError::InvalidCredentials => StatusCode::UNAUTHORIZED,
|
||||
AuthorizationError::Decoding(..) => StatusCode::BAD_REQUEST,
|
||||
AuthorizationError::Authentication(..) => StatusCode::UNAUTHORIZED,
|
||||
}
|
||||
}
|
||||
|
||||
fn error_response(&self) -> HttpResponse {
|
||||
HttpResponse::build(self.status_code()).json(ApiError {
|
||||
error: match self {
|
||||
AuthorizationError::EnvError(..) => "environment_error",
|
||||
AuthorizationError::SqlxDatabaseError(..) => "database_error",
|
||||
AuthorizationError::DatabaseError(..) => "database_error",
|
||||
AuthorizationError::SerDeError(..) => "invalid_input",
|
||||
AuthorizationError::GithubError(..) => "github_error",
|
||||
AuthorizationError::InvalidCredentialsError => {
|
||||
"invalid_credentials"
|
||||
}
|
||||
AuthorizationError::DecodingError(..) => "decoding_error",
|
||||
AuthorizationError::AuthenticationError(..) => {
|
||||
AuthorizationError::Env(..) => "environment_error",
|
||||
AuthorizationError::SqlxDatabase(..) => "database_error",
|
||||
AuthorizationError::Database(..) => "database_error",
|
||||
AuthorizationError::SerDe(..) => "invalid_input",
|
||||
AuthorizationError::Github(..) => "github_error",
|
||||
AuthorizationError::InvalidCredentials => "invalid_credentials",
|
||||
AuthorizationError::Decoding(..) => "decoding_error",
|
||||
AuthorizationError::Authentication(..) => {
|
||||
"authentication_error"
|
||||
}
|
||||
},
|
||||
@@ -159,7 +149,7 @@ pub async fn auth_callback(
|
||||
let duration = result.expires.signed_duration_since(now);
|
||||
|
||||
if duration.num_seconds() < 0 {
|
||||
return Err(AuthorizationError::InvalidCredentialsError);
|
||||
return Err(AuthorizationError::InvalidCredentials);
|
||||
}
|
||||
|
||||
sqlx::query!(
|
||||
@@ -256,6 +246,6 @@ pub async fn auth_callback(
|
||||
.append_header(("Location", &*redirect_url))
|
||||
.json(AuthorizationInit { url: redirect_url }))
|
||||
} else {
|
||||
Err(AuthorizationError::InvalidCredentialsError)
|
||||
Err(AuthorizationError::InvalidCredentials)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -114,7 +114,7 @@ pub async fn maven_metadata(
|
||||
|
||||
Ok(HttpResponse::Ok()
|
||||
.content_type("text/xml")
|
||||
.body(yaserde::ser::to_string(&respdata).map_err(ApiError::XmlError)?))
|
||||
.body(yaserde::ser::to_string(&respdata).map_err(ApiError::Xml)?))
|
||||
}
|
||||
|
||||
fn find_file<'a>(
|
||||
@@ -211,9 +211,9 @@ pub async fn version_file(
|
||||
name: project.inner.title,
|
||||
description: project.inner.description,
|
||||
};
|
||||
return Ok(HttpResponse::Ok().content_type("text/xml").body(
|
||||
yaserde::ser::to_string(&respdata).map_err(ApiError::XmlError)?,
|
||||
));
|
||||
return Ok(HttpResponse::Ok()
|
||||
.content_type("text/xml")
|
||||
.body(yaserde::ser::to_string(&respdata).map_err(ApiError::Xml)?));
|
||||
} else if let Some(selected_file) =
|
||||
find_file(&project_id, &project, &version, &file)
|
||||
{
|
||||
|
||||
@@ -159,66 +159,66 @@ pub fn reports_config(cfg: &mut web::ServiceConfig) {
|
||||
#[derive(thiserror::Error, Debug)]
|
||||
pub enum ApiError {
|
||||
#[error("Environment Error")]
|
||||
EnvError(#[from] dotenv::Error),
|
||||
Env(#[from] dotenv::Error),
|
||||
#[error("Error while uploading file")]
|
||||
FileHostingError(#[from] FileHostingError),
|
||||
FileHosting(#[from] FileHostingError),
|
||||
#[error("Database Error: {0}")]
|
||||
DatabaseError(#[from] crate::database::models::DatabaseError),
|
||||
Database(#[from] crate::database::models::DatabaseError),
|
||||
#[error("Database Error: {0}")]
|
||||
SqlxDatabaseError(#[from] sqlx::Error),
|
||||
SqlxDatabase(#[from] sqlx::Error),
|
||||
#[error("Internal server error: {0}")]
|
||||
XmlError(String),
|
||||
Xml(String),
|
||||
#[error("Deserialization error: {0}")]
|
||||
JsonError(#[from] serde_json::Error),
|
||||
Json(#[from] serde_json::Error),
|
||||
#[error("Authentication Error: {0}")]
|
||||
AuthenticationError(#[from] crate::util::auth::AuthenticationError),
|
||||
Authentication(#[from] crate::util::auth::AuthenticationError),
|
||||
#[error("Authentication Error: {0}")]
|
||||
CustomAuthenticationError(String),
|
||||
CustomAuthentication(String),
|
||||
#[error("Invalid Input: {0}")]
|
||||
InvalidInputError(String),
|
||||
InvalidInput(String),
|
||||
#[error("Error while validating input: {0}")]
|
||||
ValidationError(String),
|
||||
Validation(String),
|
||||
#[error("Search Error: {0}")]
|
||||
SearchError(#[from] meilisearch_sdk::errors::Error),
|
||||
Search(#[from] meilisearch_sdk::errors::Error),
|
||||
#[error("Indexing Error: {0}")]
|
||||
IndexingError(#[from] crate::search::indexing::IndexingError),
|
||||
Indexing(#[from] crate::search::indexing::IndexingError),
|
||||
}
|
||||
|
||||
impl actix_web::ResponseError for ApiError {
|
||||
fn status_code(&self) -> actix_web::http::StatusCode {
|
||||
match self {
|
||||
ApiError::EnvError(..) => {
|
||||
ApiError::Env(..) => {
|
||||
actix_web::http::StatusCode::INTERNAL_SERVER_ERROR
|
||||
}
|
||||
ApiError::DatabaseError(..) => {
|
||||
ApiError::Database(..) => {
|
||||
actix_web::http::StatusCode::INTERNAL_SERVER_ERROR
|
||||
}
|
||||
ApiError::SqlxDatabaseError(..) => {
|
||||
ApiError::SqlxDatabase(..) => {
|
||||
actix_web::http::StatusCode::INTERNAL_SERVER_ERROR
|
||||
}
|
||||
ApiError::AuthenticationError(..) => {
|
||||
ApiError::Authentication(..) => {
|
||||
actix_web::http::StatusCode::UNAUTHORIZED
|
||||
}
|
||||
ApiError::CustomAuthenticationError(..) => {
|
||||
ApiError::CustomAuthentication(..) => {
|
||||
actix_web::http::StatusCode::UNAUTHORIZED
|
||||
}
|
||||
ApiError::XmlError(..) => {
|
||||
ApiError::Xml(..) => {
|
||||
actix_web::http::StatusCode::INTERNAL_SERVER_ERROR
|
||||
}
|
||||
ApiError::JsonError(..) => actix_web::http::StatusCode::BAD_REQUEST,
|
||||
ApiError::SearchError(..) => {
|
||||
ApiError::Json(..) => actix_web::http::StatusCode::BAD_REQUEST,
|
||||
ApiError::Search(..) => {
|
||||
actix_web::http::StatusCode::INTERNAL_SERVER_ERROR
|
||||
}
|
||||
ApiError::IndexingError(..) => {
|
||||
ApiError::Indexing(..) => {
|
||||
actix_web::http::StatusCode::INTERNAL_SERVER_ERROR
|
||||
}
|
||||
ApiError::FileHostingError(..) => {
|
||||
ApiError::FileHosting(..) => {
|
||||
actix_web::http::StatusCode::INTERNAL_SERVER_ERROR
|
||||
}
|
||||
ApiError::InvalidInputError(..) => {
|
||||
ApiError::InvalidInput(..) => {
|
||||
actix_web::http::StatusCode::BAD_REQUEST
|
||||
}
|
||||
ApiError::ValidationError(..) => {
|
||||
ApiError::Validation(..) => {
|
||||
actix_web::http::StatusCode::BAD_REQUEST
|
||||
}
|
||||
}
|
||||
@@ -228,18 +228,18 @@ impl actix_web::ResponseError for ApiError {
|
||||
actix_web::HttpResponse::build(self.status_code()).json(
|
||||
crate::models::error::ApiError {
|
||||
error: match self {
|
||||
ApiError::EnvError(..) => "environment_error",
|
||||
ApiError::SqlxDatabaseError(..) => "database_error",
|
||||
ApiError::DatabaseError(..) => "database_error",
|
||||
ApiError::AuthenticationError(..) => "unauthorized",
|
||||
ApiError::CustomAuthenticationError(..) => "unauthorized",
|
||||
ApiError::XmlError(..) => "xml_error",
|
||||
ApiError::JsonError(..) => "json_error",
|
||||
ApiError::SearchError(..) => "search_error",
|
||||
ApiError::IndexingError(..) => "indexing_error",
|
||||
ApiError::FileHostingError(..) => "file_hosting_error",
|
||||
ApiError::InvalidInputError(..) => "invalid_input",
|
||||
ApiError::ValidationError(..) => "invalid_input",
|
||||
ApiError::Env(..) => "environment_error",
|
||||
ApiError::SqlxDatabase(..) => "database_error",
|
||||
ApiError::Database(..) => "database_error",
|
||||
ApiError::Authentication(..) => "unauthorized",
|
||||
ApiError::CustomAuthentication(..) => "unauthorized",
|
||||
ApiError::Xml(..) => "xml_error",
|
||||
ApiError::Json(..) => "json_error",
|
||||
ApiError::Search(..) => "search_error",
|
||||
ApiError::Indexing(..) => "indexing_error",
|
||||
ApiError::FileHosting(..) => "file_hosting_error",
|
||||
ApiError::InvalidInput(..) => "invalid_input",
|
||||
ApiError::Validation(..) => "invalid_input",
|
||||
},
|
||||
description: &self.to_string(),
|
||||
},
|
||||
|
||||
@@ -105,7 +105,7 @@ pub async fn notification_delete(
|
||||
|
||||
Ok(HttpResponse::NoContent().body(""))
|
||||
} else {
|
||||
Err(ApiError::CustomAuthenticationError(
|
||||
Err(ApiError::CustomAuthentication(
|
||||
"You are not authorized to delete this notification!"
|
||||
.to_string(),
|
||||
))
|
||||
|
||||
@@ -295,7 +295,7 @@ Get logged in user
|
||||
pub async fn project_create_inner(
|
||||
req: HttpRequest,
|
||||
mut payload: Multipart,
|
||||
mut transaction: &mut sqlx::Transaction<'_, sqlx::Postgres>,
|
||||
transaction: &mut sqlx::Transaction<'_, sqlx::Postgres>,
|
||||
file_host: &dyn FileHost,
|
||||
uploaded_files: &mut Vec<UploadedFile>,
|
||||
) -> Result<HttpResponse, CreateError> {
|
||||
@@ -535,7 +535,7 @@ pub async fn project_create_inner(
|
||||
all_game_versions.clone(),
|
||||
version_data.primary_file.is_some(),
|
||||
version_data.primary_file.as_deref() == Some(name),
|
||||
&mut transaction,
|
||||
transaction,
|
||||
)
|
||||
.await?;
|
||||
}
|
||||
|
||||
@@ -102,9 +102,10 @@ pub async fn dependency_list(
|
||||
) -> Result<HttpResponse, ApiError> {
|
||||
let string = info.into_inner().0;
|
||||
|
||||
let result =
|
||||
database::models::Project::get_full_from_slug_or_project_id(&string, &**pool)
|
||||
.await?;
|
||||
let result = database::models::Project::get_full_from_slug_or_project_id(
|
||||
&string, &**pool,
|
||||
)
|
||||
.await?;
|
||||
|
||||
let user_option = get_user_from_headers(req.headers(), &**pool).await.ok();
|
||||
|
||||
@@ -152,7 +153,7 @@ pub async fn dependency_list(
|
||||
database::Project::get_many_full(
|
||||
dependencies
|
||||
.iter()
|
||||
.map(|x| if x.0.is_none() {
|
||||
.filter_map(|x| if x.0.is_none() {
|
||||
if let Some(mod_dependency_id) = x.2 {
|
||||
Some(mod_dependency_id)
|
||||
} else {
|
||||
@@ -161,12 +162,11 @@ pub async fn dependency_list(
|
||||
} else {
|
||||
x.1
|
||||
})
|
||||
.flatten()
|
||||
.collect(),
|
||||
&**pool,
|
||||
),
|
||||
database::Version::get_many_full(
|
||||
dependencies.iter().map(|x| x.0).flatten().collect(),
|
||||
dependencies.iter().filter_map(|x| x.0).collect(),
|
||||
&**pool,
|
||||
)
|
||||
);
|
||||
@@ -282,7 +282,7 @@ pub async fn project_edit(
|
||||
let user = get_user_from_headers(req.headers(), &**pool).await?;
|
||||
|
||||
new_project.validate().map_err(|err| {
|
||||
ApiError::ValidationError(validation_errors_to_string(err, None))
|
||||
ApiError::Validation(validation_errors_to_string(err, None))
|
||||
})?;
|
||||
|
||||
let string = info.into_inner().0;
|
||||
@@ -315,7 +315,7 @@ pub async fn project_edit(
|
||||
|
||||
if let Some(title) = &new_project.title {
|
||||
if !perms.contains(Permissions::EDIT_DETAILS) {
|
||||
return Err(ApiError::CustomAuthenticationError(
|
||||
return Err(ApiError::CustomAuthentication(
|
||||
"You do not have the permissions to edit the title of this project!"
|
||||
.to_string(),
|
||||
));
|
||||
@@ -336,7 +336,7 @@ pub async fn project_edit(
|
||||
|
||||
if let Some(description) = &new_project.description {
|
||||
if !perms.contains(Permissions::EDIT_DETAILS) {
|
||||
return Err(ApiError::CustomAuthenticationError(
|
||||
return Err(ApiError::CustomAuthentication(
|
||||
"You do not have the permissions to edit the description of this project!"
|
||||
.to_string(),
|
||||
));
|
||||
@@ -357,7 +357,7 @@ pub async fn project_edit(
|
||||
|
||||
if let Some(status) = &new_project.status {
|
||||
if !perms.contains(Permissions::EDIT_DETAILS) {
|
||||
return Err(ApiError::CustomAuthenticationError(
|
||||
return Err(ApiError::CustomAuthentication(
|
||||
"You do not have the permissions to edit the status of this project!"
|
||||
.to_string(),
|
||||
));
|
||||
@@ -367,7 +367,7 @@ pub async fn project_edit(
|
||||
|| status == &ProjectStatus::Approved)
|
||||
&& !user.role.is_mod()
|
||||
{
|
||||
return Err(ApiError::CustomAuthenticationError(
|
||||
return Err(ApiError::CustomAuthentication(
|
||||
"You don't have permission to set this status"
|
||||
.to_string(),
|
||||
));
|
||||
@@ -375,7 +375,7 @@ pub async fn project_edit(
|
||||
|
||||
if status == &ProjectStatus::Processing {
|
||||
if project_item.versions.is_empty() {
|
||||
return Err(ApiError::InvalidInputError(String::from(
|
||||
return Err(ApiError::InvalidInput(String::from(
|
||||
"Project submitted for review with no initial versions",
|
||||
)));
|
||||
}
|
||||
@@ -420,7 +420,7 @@ pub async fn project_edit(
|
||||
)
|
||||
.await?
|
||||
.ok_or_else(|| {
|
||||
ApiError::InvalidInputError(
|
||||
ApiError::InvalidInput(
|
||||
"No database entry for status provided.".to_string(),
|
||||
)
|
||||
})?;
|
||||
@@ -457,7 +457,7 @@ pub async fn project_edit(
|
||||
|
||||
if let Some(categories) = &new_project.categories {
|
||||
if !perms.contains(Permissions::EDIT_DETAILS) {
|
||||
return Err(ApiError::CustomAuthenticationError(
|
||||
return Err(ApiError::CustomAuthentication(
|
||||
"You do not have the permissions to edit the categories of this project!"
|
||||
.to_string(),
|
||||
));
|
||||
@@ -481,7 +481,7 @@ pub async fn project_edit(
|
||||
)
|
||||
.await?
|
||||
.ok_or_else(|| {
|
||||
ApiError::InvalidInputError(format!(
|
||||
ApiError::InvalidInput(format!(
|
||||
"Category {} does not exist.",
|
||||
category.clone()
|
||||
))
|
||||
@@ -502,7 +502,7 @@ pub async fn project_edit(
|
||||
|
||||
if let Some(issues_url) = &new_project.issues_url {
|
||||
if !perms.contains(Permissions::EDIT_DETAILS) {
|
||||
return Err(ApiError::CustomAuthenticationError(
|
||||
return Err(ApiError::CustomAuthentication(
|
||||
"You do not have the permissions to edit the issues URL of this project!"
|
||||
.to_string(),
|
||||
));
|
||||
@@ -523,7 +523,7 @@ pub async fn project_edit(
|
||||
|
||||
if let Some(source_url) = &new_project.source_url {
|
||||
if !perms.contains(Permissions::EDIT_DETAILS) {
|
||||
return Err(ApiError::CustomAuthenticationError(
|
||||
return Err(ApiError::CustomAuthentication(
|
||||
"You do not have the permissions to edit the source URL of this project!"
|
||||
.to_string(),
|
||||
));
|
||||
@@ -544,7 +544,7 @@ pub async fn project_edit(
|
||||
|
||||
if let Some(wiki_url) = &new_project.wiki_url {
|
||||
if !perms.contains(Permissions::EDIT_DETAILS) {
|
||||
return Err(ApiError::CustomAuthenticationError(
|
||||
return Err(ApiError::CustomAuthentication(
|
||||
"You do not have the permissions to edit the wiki URL of this project!"
|
||||
.to_string(),
|
||||
));
|
||||
@@ -565,7 +565,7 @@ pub async fn project_edit(
|
||||
|
||||
if let Some(license_url) = &new_project.license_url {
|
||||
if !perms.contains(Permissions::EDIT_DETAILS) {
|
||||
return Err(ApiError::CustomAuthenticationError(
|
||||
return Err(ApiError::CustomAuthentication(
|
||||
"You do not have the permissions to edit the license URL of this project!"
|
||||
.to_string(),
|
||||
));
|
||||
@@ -586,7 +586,7 @@ pub async fn project_edit(
|
||||
|
||||
if let Some(discord_url) = &new_project.discord_url {
|
||||
if !perms.contains(Permissions::EDIT_DETAILS) {
|
||||
return Err(ApiError::CustomAuthenticationError(
|
||||
return Err(ApiError::CustomAuthentication(
|
||||
"You do not have the permissions to edit the discord URL of this project!"
|
||||
.to_string(),
|
||||
));
|
||||
@@ -607,7 +607,7 @@ pub async fn project_edit(
|
||||
|
||||
if let Some(slug) = &new_project.slug {
|
||||
if !perms.contains(Permissions::EDIT_DETAILS) {
|
||||
return Err(ApiError::CustomAuthenticationError(
|
||||
return Err(ApiError::CustomAuthentication(
|
||||
"You do not have the permissions to edit the slug of this project!"
|
||||
.to_string(),
|
||||
));
|
||||
@@ -629,7 +629,7 @@ pub async fn project_edit(
|
||||
.await?;
|
||||
|
||||
if results.exists.unwrap_or(true) {
|
||||
return Err(ApiError::InvalidInputError(
|
||||
return Err(ApiError::InvalidInput(
|
||||
"Slug collides with other project's id!"
|
||||
.to_string(),
|
||||
));
|
||||
@@ -652,7 +652,7 @@ pub async fn project_edit(
|
||||
|
||||
if let Some(new_side) = &new_project.client_side {
|
||||
if !perms.contains(Permissions::EDIT_DETAILS) {
|
||||
return Err(ApiError::CustomAuthenticationError(
|
||||
return Err(ApiError::CustomAuthentication(
|
||||
"You do not have the permissions to edit the side type of this mod!"
|
||||
.to_string(),
|
||||
));
|
||||
@@ -680,7 +680,7 @@ pub async fn project_edit(
|
||||
|
||||
if let Some(new_side) = &new_project.server_side {
|
||||
if !perms.contains(Permissions::EDIT_DETAILS) {
|
||||
return Err(ApiError::CustomAuthenticationError(
|
||||
return Err(ApiError::CustomAuthentication(
|
||||
"You do not have the permissions to edit the side type of this project!"
|
||||
.to_string(),
|
||||
));
|
||||
@@ -708,7 +708,7 @@ pub async fn project_edit(
|
||||
|
||||
if let Some(license) = &new_project.license_id {
|
||||
if !perms.contains(Permissions::EDIT_DETAILS) {
|
||||
return Err(ApiError::CustomAuthenticationError(
|
||||
return Err(ApiError::CustomAuthentication(
|
||||
"You do not have the permissions to edit the license of this project!"
|
||||
.to_string(),
|
||||
));
|
||||
@@ -736,7 +736,7 @@ pub async fn project_edit(
|
||||
|
||||
if let Some(donations) = &new_project.donation_urls {
|
||||
if !perms.contains(Permissions::EDIT_DETAILS) {
|
||||
return Err(ApiError::CustomAuthenticationError(
|
||||
return Err(ApiError::CustomAuthentication(
|
||||
"You do not have the permissions to edit the donation links of this project!"
|
||||
.to_string(),
|
||||
));
|
||||
@@ -760,7 +760,7 @@ pub async fn project_edit(
|
||||
)
|
||||
.await?
|
||||
.ok_or_else(|| {
|
||||
ApiError::InvalidInputError(format!(
|
||||
ApiError::InvalidInput(format!(
|
||||
"Platform {} does not exist.",
|
||||
donation.id.clone()
|
||||
))
|
||||
@@ -784,7 +784,7 @@ pub async fn project_edit(
|
||||
if !user.role.is_mod()
|
||||
&& project_item.status != ProjectStatus::Approved
|
||||
{
|
||||
return Err(ApiError::CustomAuthenticationError(
|
||||
return Err(ApiError::CustomAuthentication(
|
||||
"You do not have the permissions to edit the moderation message of this project!"
|
||||
.to_string(),
|
||||
));
|
||||
@@ -809,7 +809,7 @@ pub async fn project_edit(
|
||||
if !user.role.is_mod()
|
||||
&& project_item.status != ProjectStatus::Approved
|
||||
{
|
||||
return Err(ApiError::CustomAuthenticationError(
|
||||
return Err(ApiError::CustomAuthentication(
|
||||
"You do not have the permissions to edit the moderation message body of this project!"
|
||||
.to_string(),
|
||||
));
|
||||
@@ -830,7 +830,7 @@ pub async fn project_edit(
|
||||
|
||||
if let Some(body) = &new_project.body {
|
||||
if !perms.contains(Permissions::EDIT_BODY) {
|
||||
return Err(ApiError::CustomAuthenticationError(
|
||||
return Err(ApiError::CustomAuthentication(
|
||||
"You do not have the permissions to edit the body of this project!"
|
||||
.to_string(),
|
||||
));
|
||||
@@ -852,7 +852,7 @@ pub async fn project_edit(
|
||||
transaction.commit().await?;
|
||||
Ok(HttpResponse::NoContent().body(""))
|
||||
} else {
|
||||
Err(ApiError::CustomAuthenticationError(
|
||||
Err(ApiError::CustomAuthentication(
|
||||
"You do not have permission to edit this project!".to_string(),
|
||||
))
|
||||
}
|
||||
@@ -889,7 +889,7 @@ pub async fn project_icon_edit(
|
||||
)
|
||||
.await?
|
||||
.ok_or_else(|| {
|
||||
ApiError::InvalidInputError(
|
||||
ApiError::InvalidInput(
|
||||
"The specified project does not exist!".to_string(),
|
||||
)
|
||||
})?;
|
||||
@@ -901,15 +901,15 @@ pub async fn project_icon_edit(
|
||||
&**pool,
|
||||
)
|
||||
.await
|
||||
.map_err(ApiError::DatabaseError)?
|
||||
.map_err(ApiError::Database)?
|
||||
.ok_or_else(|| {
|
||||
ApiError::InvalidInputError(
|
||||
ApiError::InvalidInput(
|
||||
"The specified project does not exist!".to_string(),
|
||||
)
|
||||
})?;
|
||||
|
||||
if !team_member.permissions.contains(Permissions::EDIT_DETAILS) {
|
||||
return Err(ApiError::CustomAuthenticationError(
|
||||
return Err(ApiError::CustomAuthentication(
|
||||
"You don't have permission to edit this project's icon."
|
||||
.to_string(),
|
||||
));
|
||||
@@ -958,7 +958,7 @@ pub async fn project_icon_edit(
|
||||
|
||||
Ok(HttpResponse::NoContent().body(""))
|
||||
} else {
|
||||
Err(ApiError::InvalidInputError(format!(
|
||||
Err(ApiError::InvalidInput(format!(
|
||||
"Invalid format for project icon: {}",
|
||||
ext.ext
|
||||
)))
|
||||
@@ -981,7 +981,7 @@ pub async fn delete_project_icon(
|
||||
)
|
||||
.await?
|
||||
.ok_or_else(|| {
|
||||
ApiError::InvalidInputError(
|
||||
ApiError::InvalidInput(
|
||||
"The specified project does not exist!".to_string(),
|
||||
)
|
||||
})?;
|
||||
@@ -993,15 +993,15 @@ pub async fn delete_project_icon(
|
||||
&**pool,
|
||||
)
|
||||
.await
|
||||
.map_err(ApiError::DatabaseError)?
|
||||
.map_err(ApiError::Database)?
|
||||
.ok_or_else(|| {
|
||||
ApiError::InvalidInputError(
|
||||
ApiError::InvalidInput(
|
||||
"The specified project does not exist!".to_string(),
|
||||
)
|
||||
})?;
|
||||
|
||||
if !team_member.permissions.contains(Permissions::EDIT_DETAILS) {
|
||||
return Err(ApiError::CustomAuthenticationError(
|
||||
return Err(ApiError::CustomAuthentication(
|
||||
"You don't have permission to edit this project's icon."
|
||||
.to_string(),
|
||||
));
|
||||
@@ -1057,7 +1057,7 @@ pub async fn add_gallery_item(
|
||||
crate::util::ext::get_image_content_type(&*ext.ext)
|
||||
{
|
||||
item.validate().map_err(|err| {
|
||||
ApiError::ValidationError(validation_errors_to_string(err, None))
|
||||
ApiError::Validation(validation_errors_to_string(err, None))
|
||||
})?;
|
||||
|
||||
let cdn_url = dotenv::var("CDN_URL")?;
|
||||
@@ -1071,7 +1071,7 @@ pub async fn add_gallery_item(
|
||||
)
|
||||
.await?
|
||||
.ok_or_else(|| {
|
||||
ApiError::InvalidInputError(
|
||||
ApiError::InvalidInput(
|
||||
"The specified project does not exist!".to_string(),
|
||||
)
|
||||
})?;
|
||||
@@ -1083,15 +1083,15 @@ pub async fn add_gallery_item(
|
||||
&**pool,
|
||||
)
|
||||
.await
|
||||
.map_err(ApiError::DatabaseError)?
|
||||
.map_err(ApiError::Database)?
|
||||
.ok_or_else(|| {
|
||||
ApiError::InvalidInputError(
|
||||
ApiError::InvalidInput(
|
||||
"The specified project does not exist!".to_string(),
|
||||
)
|
||||
})?;
|
||||
|
||||
if !team_member.permissions.contains(Permissions::EDIT_DETAILS) {
|
||||
return Err(ApiError::CustomAuthenticationError(
|
||||
return Err(ApiError::CustomAuthentication(
|
||||
"You don't have permission to edit this project's gallery."
|
||||
.to_string(),
|
||||
));
|
||||
@@ -1143,7 +1143,7 @@ pub async fn add_gallery_item(
|
||||
|
||||
Ok(HttpResponse::NoContent().body(""))
|
||||
} else {
|
||||
Err(ApiError::InvalidInputError(format!(
|
||||
Err(ApiError::InvalidInput(format!(
|
||||
"Invalid format for gallery image: {}",
|
||||
ext.ext
|
||||
)))
|
||||
@@ -1182,7 +1182,7 @@ pub async fn edit_gallery_item(
|
||||
let string = info.into_inner().0;
|
||||
|
||||
item.validate().map_err(|err| {
|
||||
ApiError::ValidationError(validation_errors_to_string(err, None))
|
||||
ApiError::Validation(validation_errors_to_string(err, None))
|
||||
})?;
|
||||
|
||||
let project_item = database::models::Project::get_from_slug_or_project_id(
|
||||
@@ -1191,7 +1191,7 @@ pub async fn edit_gallery_item(
|
||||
)
|
||||
.await?
|
||||
.ok_or_else(|| {
|
||||
ApiError::InvalidInputError(
|
||||
ApiError::InvalidInput(
|
||||
"The specified project does not exist!".to_string(),
|
||||
)
|
||||
})?;
|
||||
@@ -1203,15 +1203,15 @@ pub async fn edit_gallery_item(
|
||||
&**pool,
|
||||
)
|
||||
.await
|
||||
.map_err(ApiError::DatabaseError)?
|
||||
.map_err(ApiError::Database)?
|
||||
.ok_or_else(|| {
|
||||
ApiError::InvalidInputError(
|
||||
ApiError::InvalidInput(
|
||||
"The specified project does not exist!".to_string(),
|
||||
)
|
||||
})?;
|
||||
|
||||
if !team_member.permissions.contains(Permissions::EDIT_DETAILS) {
|
||||
return Err(ApiError::CustomAuthenticationError(
|
||||
return Err(ApiError::CustomAuthentication(
|
||||
"You don't have permission to edit this project's gallery."
|
||||
.to_string(),
|
||||
));
|
||||
@@ -1229,7 +1229,7 @@ pub async fn edit_gallery_item(
|
||||
.fetch_optional(&mut *transaction)
|
||||
.await?
|
||||
.ok_or_else(|| {
|
||||
ApiError::InvalidInputError(format!(
|
||||
ApiError::InvalidInput(format!(
|
||||
"Gallery item at URL {} is not part of the project's gallery.",
|
||||
item.url
|
||||
))
|
||||
@@ -1319,7 +1319,7 @@ pub async fn delete_gallery_item(
|
||||
)
|
||||
.await?
|
||||
.ok_or_else(|| {
|
||||
ApiError::InvalidInputError(
|
||||
ApiError::InvalidInput(
|
||||
"The specified project does not exist!".to_string(),
|
||||
)
|
||||
})?;
|
||||
@@ -1331,15 +1331,15 @@ pub async fn delete_gallery_item(
|
||||
&**pool,
|
||||
)
|
||||
.await
|
||||
.map_err(ApiError::DatabaseError)?
|
||||
.map_err(ApiError::Database)?
|
||||
.ok_or_else(|| {
|
||||
ApiError::InvalidInputError(
|
||||
ApiError::InvalidInput(
|
||||
"The specified project does not exist!".to_string(),
|
||||
)
|
||||
})?;
|
||||
|
||||
if !team_member.permissions.contains(Permissions::EDIT_DETAILS) {
|
||||
return Err(ApiError::CustomAuthenticationError(
|
||||
return Err(ApiError::CustomAuthentication(
|
||||
"You don't have permission to edit this project's gallery."
|
||||
.to_string(),
|
||||
));
|
||||
@@ -1357,7 +1357,7 @@ pub async fn delete_gallery_item(
|
||||
.fetch_optional(&mut *transaction)
|
||||
.await?
|
||||
.ok_or_else(|| {
|
||||
ApiError::InvalidInputError(format!(
|
||||
ApiError::InvalidInput(format!(
|
||||
"Gallery item at URL {} is not part of the project's gallery.",
|
||||
item.url
|
||||
))
|
||||
@@ -1403,7 +1403,7 @@ pub async fn project_delete(
|
||||
)
|
||||
.await?
|
||||
.ok_or_else(|| {
|
||||
ApiError::InvalidInputError(
|
||||
ApiError::InvalidInput(
|
||||
"The specified project does not exist!".to_string(),
|
||||
)
|
||||
})?;
|
||||
@@ -1416,9 +1416,9 @@ pub async fn project_delete(
|
||||
&**pool,
|
||||
)
|
||||
.await
|
||||
.map_err(ApiError::DatabaseError)?
|
||||
.map_err(ApiError::Database)?
|
||||
.ok_or_else(|| {
|
||||
ApiError::InvalidInputError(
|
||||
ApiError::InvalidInput(
|
||||
"The specified project does not exist!".to_string(),
|
||||
)
|
||||
})?;
|
||||
@@ -1427,7 +1427,7 @@ pub async fn project_delete(
|
||||
.permissions
|
||||
.contains(Permissions::DELETE_PROJECT)
|
||||
{
|
||||
return Err(ApiError::CustomAuthenticationError(
|
||||
return Err(ApiError::CustomAuthentication(
|
||||
"You don't have permission to delete this project!".to_string(),
|
||||
));
|
||||
}
|
||||
@@ -1463,7 +1463,7 @@ pub async fn project_follow(
|
||||
database::models::Project::get_from_slug_or_project_id(string, &**pool)
|
||||
.await?
|
||||
.ok_or_else(|| {
|
||||
ApiError::InvalidInputError(
|
||||
ApiError::InvalidInput(
|
||||
"The specified project does not exist!".to_string(),
|
||||
)
|
||||
})?;
|
||||
@@ -1512,7 +1512,7 @@ pub async fn project_follow(
|
||||
|
||||
Ok(HttpResponse::NoContent().body(""))
|
||||
} else {
|
||||
Err(ApiError::InvalidInputError(
|
||||
Err(ApiError::InvalidInput(
|
||||
"You are already following this project!".to_string(),
|
||||
))
|
||||
}
|
||||
@@ -1531,7 +1531,7 @@ pub async fn project_unfollow(
|
||||
database::models::Project::get_from_slug_or_project_id(string, &**pool)
|
||||
.await?
|
||||
.ok_or_else(|| {
|
||||
ApiError::InvalidInputError(
|
||||
ApiError::InvalidInput(
|
||||
"The specified project does not exist!".to_string(),
|
||||
)
|
||||
})?;
|
||||
@@ -1580,7 +1580,7 @@ pub async fn project_unfollow(
|
||||
|
||||
Ok(HttpResponse::NoContent().body(""))
|
||||
} else {
|
||||
Err(ApiError::InvalidInputError(
|
||||
Err(ApiError::InvalidInput(
|
||||
"You are not following this project!".to_string(),
|
||||
))
|
||||
}
|
||||
|
||||
@@ -31,7 +31,7 @@ pub async fn report_create(
|
||||
let mut bytes = web::BytesMut::new();
|
||||
while let Some(item) = body.next().await {
|
||||
bytes.extend_from_slice(&item.map_err(|_| {
|
||||
ApiError::InvalidInputError(
|
||||
ApiError::InvalidInput(
|
||||
"Error while parsing request payload!".to_string(),
|
||||
)
|
||||
})?);
|
||||
@@ -46,7 +46,7 @@ pub async fn report_create(
|
||||
)
|
||||
.await?
|
||||
.ok_or_else(|| {
|
||||
ApiError::InvalidInputError(format!(
|
||||
ApiError::InvalidInput(format!(
|
||||
"Invalid report type: {}",
|
||||
new_report.report_type
|
||||
))
|
||||
@@ -91,7 +91,7 @@ pub async fn report_create(
|
||||
)
|
||||
}
|
||||
ItemType::Unknown => {
|
||||
return Err(ApiError::InvalidInputError(format!(
|
||||
return Err(ApiError::InvalidInput(format!(
|
||||
"Invalid report item type: {}",
|
||||
new_report.item_type.as_str()
|
||||
)))
|
||||
|
||||
@@ -74,7 +74,7 @@ pub async fn category_create(
|
||||
)
|
||||
.await?
|
||||
.ok_or_else(|| {
|
||||
ApiError::InvalidInputError(
|
||||
ApiError::InvalidInput(
|
||||
"Specified project type does not exist!".to_string(),
|
||||
)
|
||||
})?;
|
||||
|
||||
@@ -38,7 +38,7 @@ pub async fn team_members_get_project(
|
||||
&**pool,
|
||||
)
|
||||
.await
|
||||
.map_err(ApiError::DatabaseError)?;
|
||||
.map_err(ApiError::Database)?;
|
||||
|
||||
if team_member.is_some() {
|
||||
let team_members: Vec<_> = members_data
|
||||
@@ -80,7 +80,7 @@ pub async fn team_members_get(
|
||||
let team_member =
|
||||
TeamMember::get_from_user_id(id.into(), user.id.into(), &**pool)
|
||||
.await
|
||||
.map_err(ApiError::DatabaseError)?;
|
||||
.map_err(ApiError::Database)?;
|
||||
|
||||
if team_member.is_some() {
|
||||
let team_members: Vec<_> = members_data
|
||||
@@ -119,7 +119,7 @@ pub async fn join_team(
|
||||
|
||||
if let Some(member) = member {
|
||||
if member.accepted {
|
||||
return Err(ApiError::InvalidInputError(
|
||||
return Err(ApiError::InvalidInput(
|
||||
"You are already a member of this team".to_string(),
|
||||
));
|
||||
}
|
||||
@@ -138,7 +138,7 @@ pub async fn join_team(
|
||||
|
||||
transaction.commit().await?;
|
||||
} else {
|
||||
return Err(ApiError::InvalidInputError(
|
||||
return Err(ApiError::InvalidInput(
|
||||
"There is no pending request from this team".to_string(),
|
||||
));
|
||||
}
|
||||
@@ -175,26 +175,26 @@ pub async fn add_team_member(
|
||||
TeamMember::get_from_user_id(team_id, current_user.id.into(), &**pool)
|
||||
.await?
|
||||
.ok_or_else(|| {
|
||||
ApiError::CustomAuthenticationError(
|
||||
ApiError::CustomAuthentication(
|
||||
"You don't have permission to edit members of this team"
|
||||
.to_string(),
|
||||
)
|
||||
})?;
|
||||
|
||||
if !member.permissions.contains(Permissions::MANAGE_INVITES) {
|
||||
return Err(ApiError::CustomAuthenticationError(
|
||||
return Err(ApiError::CustomAuthentication(
|
||||
"You don't have permission to invite users to this team"
|
||||
.to_string(),
|
||||
));
|
||||
}
|
||||
if !member.permissions.contains(new_member.permissions) {
|
||||
return Err(ApiError::InvalidInputError(
|
||||
return Err(ApiError::InvalidInput(
|
||||
"The new member has permissions that you don't have".to_string(),
|
||||
));
|
||||
}
|
||||
|
||||
if new_member.role == crate::models::teams::OWNER_ROLE {
|
||||
return Err(ApiError::InvalidInputError(
|
||||
return Err(ApiError::InvalidInput(
|
||||
"The `Owner` role is restricted to one person".to_string(),
|
||||
));
|
||||
}
|
||||
@@ -207,11 +207,11 @@ pub async fn add_team_member(
|
||||
|
||||
if let Some(req) = request {
|
||||
if req.accepted {
|
||||
return Err(ApiError::InvalidInputError(
|
||||
return Err(ApiError::InvalidInput(
|
||||
"The user is already a member of that team".to_string(),
|
||||
));
|
||||
} else {
|
||||
return Err(ApiError::InvalidInputError(
|
||||
return Err(ApiError::InvalidInput(
|
||||
"There is already a pending member request for this user"
|
||||
.to_string(),
|
||||
));
|
||||
@@ -221,9 +221,7 @@ pub async fn add_team_member(
|
||||
crate::database::models::User::get(member.user_id, &**pool)
|
||||
.await?
|
||||
.ok_or_else(|| {
|
||||
ApiError::InvalidInputError(
|
||||
"An invalid User ID specified".to_string(),
|
||||
)
|
||||
ApiError::InvalidInput("An invalid User ID specified".to_string())
|
||||
})?;
|
||||
|
||||
let new_id =
|
||||
@@ -312,7 +310,7 @@ pub async fn edit_team_member(
|
||||
TeamMember::get_from_user_id(id, current_user.id.into(), &**pool)
|
||||
.await?
|
||||
.ok_or_else(|| {
|
||||
ApiError::CustomAuthenticationError(
|
||||
ApiError::CustomAuthentication(
|
||||
"You don't have permission to edit members of this team"
|
||||
.to_string(),
|
||||
)
|
||||
@@ -321,7 +319,7 @@ pub async fn edit_team_member(
|
||||
TeamMember::get_from_user_id_pending(id, user_id, &**pool)
|
||||
.await?
|
||||
.ok_or_else(|| {
|
||||
ApiError::CustomAuthenticationError(
|
||||
ApiError::CustomAuthentication(
|
||||
"You don't have permission to edit members of this team"
|
||||
.to_string(),
|
||||
)
|
||||
@@ -330,13 +328,13 @@ pub async fn edit_team_member(
|
||||
let mut transaction = pool.begin().await?;
|
||||
|
||||
if &*edit_member_db.role == crate::models::teams::OWNER_ROLE {
|
||||
return Err(ApiError::InvalidInputError(
|
||||
return Err(ApiError::InvalidInput(
|
||||
"The owner of a team cannot be edited".to_string(),
|
||||
));
|
||||
}
|
||||
|
||||
if !member.permissions.contains(Permissions::EDIT_MEMBER) {
|
||||
return Err(ApiError::CustomAuthenticationError(
|
||||
return Err(ApiError::CustomAuthentication(
|
||||
"You don't have permission to edit members of this team"
|
||||
.to_string(),
|
||||
));
|
||||
@@ -344,7 +342,7 @@ pub async fn edit_team_member(
|
||||
|
||||
if let Some(new_permissions) = edit_member.permissions {
|
||||
if !member.permissions.contains(new_permissions) {
|
||||
return Err(ApiError::InvalidInputError(
|
||||
return Err(ApiError::InvalidInput(
|
||||
"The new permissions have permissions that you don't have"
|
||||
.to_string(),
|
||||
));
|
||||
@@ -352,7 +350,7 @@ pub async fn edit_team_member(
|
||||
}
|
||||
|
||||
if edit_member.role.as_deref() == Some(crate::models::teams::OWNER_ROLE) {
|
||||
return Err(ApiError::InvalidInputError(
|
||||
return Err(ApiError::InvalidInput(
|
||||
"The `Owner` role is restricted to one person".to_string(),
|
||||
));
|
||||
}
|
||||
@@ -394,7 +392,7 @@ pub async fn transfer_ownership(
|
||||
)
|
||||
.await?
|
||||
.ok_or_else(|| {
|
||||
ApiError::CustomAuthenticationError(
|
||||
ApiError::CustomAuthentication(
|
||||
"You don't have permission to edit members of this team"
|
||||
.to_string(),
|
||||
)
|
||||
@@ -406,20 +404,20 @@ pub async fn transfer_ownership(
|
||||
)
|
||||
.await?
|
||||
.ok_or_else(|| {
|
||||
ApiError::InvalidInputError(
|
||||
ApiError::InvalidInput(
|
||||
"The new owner specified does not exist".to_string(),
|
||||
)
|
||||
})?;
|
||||
|
||||
if member.role != crate::models::teams::OWNER_ROLE {
|
||||
return Err(ApiError::CustomAuthenticationError(
|
||||
return Err(ApiError::CustomAuthentication(
|
||||
"You don't have permission to edit the ownership of this team"
|
||||
.to_string(),
|
||||
));
|
||||
}
|
||||
|
||||
if !new_member.accepted {
|
||||
return Err(ApiError::InvalidInputError(
|
||||
return Err(ApiError::InvalidInput(
|
||||
"You can only transfer ownership to members who are currently in your team".to_string(),
|
||||
));
|
||||
}
|
||||
@@ -466,7 +464,7 @@ pub async fn remove_team_member(
|
||||
TeamMember::get_from_user_id(id, current_user.id.into(), &**pool)
|
||||
.await?
|
||||
.ok_or_else(|| {
|
||||
ApiError::CustomAuthenticationError(
|
||||
ApiError::CustomAuthentication(
|
||||
"You don't have permission to edit members of this team"
|
||||
.to_string(),
|
||||
)
|
||||
@@ -478,7 +476,7 @@ pub async fn remove_team_member(
|
||||
if let Some(delete_member) = delete_member {
|
||||
if delete_member.role == crate::models::teams::OWNER_ROLE {
|
||||
// The owner cannot be removed from a team
|
||||
return Err(ApiError::CustomAuthenticationError(
|
||||
return Err(ApiError::CustomAuthentication(
|
||||
"The owner can't be removed from a team".to_string(),
|
||||
));
|
||||
}
|
||||
@@ -492,7 +490,7 @@ pub async fn remove_team_member(
|
||||
{
|
||||
TeamMember::delete(id, user_id, &**pool).await?;
|
||||
} else {
|
||||
return Err(ApiError::CustomAuthenticationError(
|
||||
return Err(ApiError::CustomAuthentication(
|
||||
"You do not have permission to remove a member from this team".to_string(),
|
||||
));
|
||||
}
|
||||
@@ -505,7 +503,7 @@ pub async fn remove_team_member(
|
||||
// permission can remove it.
|
||||
TeamMember::delete(id, user_id, &**pool).await?;
|
||||
} else {
|
||||
return Err(ApiError::CustomAuthenticationError(
|
||||
return Err(ApiError::CustomAuthentication(
|
||||
"You do not have permission to cancel a team invite"
|
||||
.to_string(),
|
||||
));
|
||||
|
||||
@@ -24,12 +24,12 @@ pub async fn forge_updates(
|
||||
&id, &**pool,
|
||||
)
|
||||
.await?
|
||||
.ok_or_else(|| ApiError::InvalidInputError(ERROR.to_string()))?;
|
||||
.ok_or_else(|| ApiError::InvalidInput(ERROR.to_string()))?;
|
||||
|
||||
let user_option = get_user_from_headers(req.headers(), &**pool).await.ok();
|
||||
|
||||
if !is_authorized(&project, &user_option, &pool).await? {
|
||||
return Err(ApiError::InvalidInputError(ERROR.to_string()));
|
||||
return Err(ApiError::InvalidInput(ERROR.to_string()));
|
||||
}
|
||||
|
||||
let version_ids = database::models::Version::get_project_versions(
|
||||
|
||||
@@ -166,7 +166,7 @@ pub async fn user_edit(
|
||||
let user = get_user_from_headers(req.headers(), &**pool).await?;
|
||||
|
||||
new_user.validate().map_err(|err| {
|
||||
ApiError::ValidationError(validation_errors_to_string(err, None))
|
||||
ApiError::Validation(validation_errors_to_string(err, None))
|
||||
})?;
|
||||
|
||||
let id_option = crate::database::models::User::get_id_from_username_or_id(
|
||||
@@ -201,7 +201,7 @@ pub async fn user_edit(
|
||||
.execute(&mut *transaction)
|
||||
.await?;
|
||||
} else {
|
||||
return Err(ApiError::InvalidInputError(format!(
|
||||
return Err(ApiError::InvalidInput(format!(
|
||||
"Username {} is taken!",
|
||||
username
|
||||
)));
|
||||
@@ -252,7 +252,7 @@ pub async fn user_edit(
|
||||
|
||||
if let Some(role) = &new_user.role {
|
||||
if !user.role.is_mod() {
|
||||
return Err(ApiError::CustomAuthenticationError(
|
||||
return Err(ApiError::CustomAuthentication(
|
||||
"You do not have the permissions to edit the role of this user!"
|
||||
.to_string(),
|
||||
));
|
||||
@@ -276,7 +276,7 @@ pub async fn user_edit(
|
||||
transaction.commit().await?;
|
||||
Ok(HttpResponse::NoContent().body(""))
|
||||
} else {
|
||||
Err(ApiError::CustomAuthenticationError(
|
||||
Err(ApiError::CustomAuthentication(
|
||||
"You do not have permission to edit this user!".to_string(),
|
||||
))
|
||||
}
|
||||
@@ -313,7 +313,7 @@ pub async fn user_icon_edit(
|
||||
|
||||
if let Some(id) = id_option {
|
||||
if user.id != id.into() && !user.role.is_mod() {
|
||||
return Err(ApiError::CustomAuthenticationError(
|
||||
return Err(ApiError::CustomAuthentication(
|
||||
"You don't have permission to edit this user's icon."
|
||||
.to_string(),
|
||||
));
|
||||
@@ -374,7 +374,7 @@ pub async fn user_icon_edit(
|
||||
Ok(HttpResponse::NotFound().body(""))
|
||||
}
|
||||
} else {
|
||||
Err(ApiError::InvalidInputError(format!(
|
||||
Err(ApiError::InvalidInput(format!(
|
||||
"Invalid format for user icon: {}",
|
||||
ext.ext
|
||||
)))
|
||||
@@ -407,24 +407,18 @@ pub async fn user_delete(
|
||||
|
||||
if let Some(id) = id_option {
|
||||
if !user.role.is_mod() && user.id != id.into() {
|
||||
return Err(ApiError::CustomAuthenticationError(
|
||||
return Err(ApiError::CustomAuthentication(
|
||||
"You do not have permission to delete this user!".to_string(),
|
||||
));
|
||||
}
|
||||
|
||||
let mut transaction = pool.begin().await?;
|
||||
|
||||
let result;
|
||||
if &*removal_type.removal_type == "full" {
|
||||
result = crate::database::models::User::remove_full(
|
||||
id,
|
||||
&mut transaction,
|
||||
)
|
||||
.await?;
|
||||
let result = if &*removal_type.removal_type == "full" {
|
||||
crate::database::models::User::remove_full(id, &mut transaction)
|
||||
.await?
|
||||
} else {
|
||||
result =
|
||||
crate::database::models::User::remove(id, &mut transaction)
|
||||
.await?;
|
||||
crate::database::models::User::remove(id, &mut transaction).await?
|
||||
};
|
||||
|
||||
transaction.commit().await?;
|
||||
@@ -454,7 +448,7 @@ pub async fn user_follows(
|
||||
|
||||
if let Some(id) = id_option {
|
||||
if !user.role.is_mod() && user.id != id.into() {
|
||||
return Err(ApiError::CustomAuthenticationError(
|
||||
return Err(ApiError::CustomAuthentication(
|
||||
"You do not have permission to see the projects this user follows!".to_string(),
|
||||
));
|
||||
}
|
||||
@@ -504,7 +498,7 @@ pub async fn user_notifications(
|
||||
|
||||
if let Some(id) = id_option {
|
||||
if !user.role.is_mod() && user.id != id.into() {
|
||||
return Err(ApiError::CustomAuthenticationError(
|
||||
return Err(ApiError::CustomAuthentication(
|
||||
"You do not have permission to see the notifications of this user!".to_string(),
|
||||
));
|
||||
}
|
||||
|
||||
@@ -64,7 +64,7 @@ pub async fn report_create(
|
||||
let mut bytes = web::BytesMut::new();
|
||||
while let Some(item) = body.next().await {
|
||||
bytes.extend_from_slice(&item.map_err(|_| {
|
||||
ApiError::InvalidInputError(
|
||||
ApiError::InvalidInput(
|
||||
"Error while parsing request payload!".to_string(),
|
||||
)
|
||||
})?);
|
||||
@@ -79,7 +79,7 @@ pub async fn report_create(
|
||||
)
|
||||
.await?
|
||||
.ok_or_else(|| {
|
||||
ApiError::InvalidInputError(format!(
|
||||
ApiError::InvalidInput(format!(
|
||||
"Invalid report type: {}",
|
||||
new_report.report_type
|
||||
))
|
||||
@@ -124,7 +124,7 @@ pub async fn report_create(
|
||||
)
|
||||
}
|
||||
ItemType::Unknown => {
|
||||
return Err(ApiError::InvalidInputError(format!(
|
||||
return Err(ApiError::InvalidInput(format!(
|
||||
"Invalid report item type: {}",
|
||||
new_report.item_type.as_str()
|
||||
)))
|
||||
|
||||
@@ -38,7 +38,7 @@ pub async fn category_create(
|
||||
)
|
||||
.await?
|
||||
.ok_or_else(|| {
|
||||
ApiError::InvalidInputError(
|
||||
ApiError::InvalidInput(
|
||||
"Specified project type does not exist!".to_string(),
|
||||
)
|
||||
})?;
|
||||
|
||||
@@ -42,7 +42,7 @@ pub async fn team_members_get(
|
||||
&**pool,
|
||||
)
|
||||
.await
|
||||
.map_err(ApiError::DatabaseError)?;
|
||||
.map_err(ApiError::Database)?;
|
||||
|
||||
if team_member.is_some() {
|
||||
let team_members: Vec<TeamMember> = members_data
|
||||
|
||||
@@ -66,7 +66,7 @@ pub async fn user_follows(
|
||||
|
||||
if let Some(id) = id_option {
|
||||
if !user.role.is_mod() && user.id != id.into() {
|
||||
return Err(ApiError::CustomAuthenticationError(
|
||||
return Err(ApiError::CustomAuthentication(
|
||||
"You do not have permission to see the projects this user follows!".to_string(),
|
||||
));
|
||||
}
|
||||
|
||||
@@ -269,7 +269,7 @@ pub async fn download_version(
|
||||
)
|
||||
.fetch_optional(&**pool)
|
||||
.await
|
||||
.map_err(|e| ApiError::DatabaseError(e.into()))?;
|
||||
.map_err(|e| ApiError::Database(e.into()))?;
|
||||
|
||||
if let Some(id) = result {
|
||||
Ok(HttpResponse::TemporaryRedirect()
|
||||
@@ -316,9 +316,9 @@ pub async fn delete_file(
|
||||
&**pool,
|
||||
)
|
||||
.await
|
||||
.map_err(ApiError::DatabaseError)?
|
||||
.map_err(ApiError::Database)?
|
||||
.ok_or_else(|| {
|
||||
ApiError::CustomAuthenticationError(
|
||||
ApiError::CustomAuthentication(
|
||||
"You don't have permission to delete this file!"
|
||||
.to_string(),
|
||||
)
|
||||
@@ -328,7 +328,7 @@ pub async fn delete_file(
|
||||
.permissions
|
||||
.contains(Permissions::DELETE_VERSION)
|
||||
{
|
||||
return Err(ApiError::CustomAuthenticationError(
|
||||
return Err(ApiError::CustomAuthentication(
|
||||
"You don't have permission to delete this file!"
|
||||
.to_string(),
|
||||
));
|
||||
|
||||
@@ -103,7 +103,7 @@ pub async fn version_create(
|
||||
async fn version_create_inner(
|
||||
req: HttpRequest,
|
||||
mut payload: Multipart,
|
||||
mut transaction: &mut sqlx::Transaction<'_, sqlx::Postgres>,
|
||||
transaction: &mut sqlx::Transaction<'_, sqlx::Postgres>,
|
||||
file_host: &dyn FileHost,
|
||||
uploaded_files: &mut Vec<UploadedFile>,
|
||||
) -> Result<HttpResponse, CreateError> {
|
||||
@@ -322,7 +322,7 @@ async fn version_create_inner(
|
||||
all_game_versions.clone(),
|
||||
version_data.primary_file.is_some(),
|
||||
version_data.primary_file.as_deref() == Some(name),
|
||||
&mut transaction,
|
||||
transaction,
|
||||
)
|
||||
.await?;
|
||||
}
|
||||
@@ -486,7 +486,7 @@ async fn upload_file_to_version_inner(
|
||||
req: HttpRequest,
|
||||
mut payload: Multipart,
|
||||
client: Data<PgPool>,
|
||||
mut transaction: &mut sqlx::Transaction<'_, sqlx::Postgres>,
|
||||
transaction: &mut sqlx::Transaction<'_, sqlx::Postgres>,
|
||||
file_host: &dyn FileHost,
|
||||
uploaded_files: &mut Vec<UploadedFile>,
|
||||
version_id: models::VersionId,
|
||||
@@ -597,7 +597,7 @@ async fn upload_file_to_version_inner(
|
||||
all_game_versions.clone(),
|
||||
true,
|
||||
false,
|
||||
&mut transaction,
|
||||
transaction,
|
||||
)
|
||||
.await?;
|
||||
}
|
||||
|
||||
@@ -135,9 +135,9 @@ pub async fn delete_file(
|
||||
&**pool,
|
||||
)
|
||||
.await
|
||||
.map_err(ApiError::DatabaseError)?
|
||||
.map_err(ApiError::Database)?
|
||||
.ok_or_else(|| {
|
||||
ApiError::CustomAuthenticationError(
|
||||
ApiError::CustomAuthentication(
|
||||
"You don't have permission to delete this file!"
|
||||
.to_string(),
|
||||
)
|
||||
@@ -147,7 +147,7 @@ pub async fn delete_file(
|
||||
.permissions
|
||||
.contains(Permissions::DELETE_VERSION)
|
||||
{
|
||||
return Err(ApiError::CustomAuthenticationError(
|
||||
return Err(ApiError::CustomAuthentication(
|
||||
"You don't have permission to delete this file!"
|
||||
.to_string(),
|
||||
));
|
||||
@@ -169,7 +169,7 @@ pub async fn delete_file(
|
||||
.await?;
|
||||
|
||||
if files.len() < 2 {
|
||||
return Err(ApiError::InvalidInputError(
|
||||
return Err(ApiError::InvalidInput(
|
||||
"Versions must have at least one file uploaded to them"
|
||||
.to_string(),
|
||||
));
|
||||
|
||||
@@ -28,9 +28,10 @@ pub async fn version_list(
|
||||
) -> Result<HttpResponse, ApiError> {
|
||||
let string = info.into_inner().0;
|
||||
|
||||
let result =
|
||||
database::models::Project::get_full_from_slug_or_project_id(&string, &**pool)
|
||||
.await?;
|
||||
let result = database::models::Project::get_full_from_slug_or_project_id(
|
||||
&string, &**pool,
|
||||
)
|
||||
.await?;
|
||||
|
||||
let user_option = get_user_from_headers(req.headers(), &**pool).await.ok();
|
||||
|
||||
@@ -187,6 +188,7 @@ pub struct EditVersion {
|
||||
pub loaders: Option<Vec<models::projects::Loader>>,
|
||||
pub featured: Option<bool>,
|
||||
pub primary_file: Option<(String, String)>,
|
||||
pub downloads: Option<u32>,
|
||||
}
|
||||
|
||||
#[patch("{id}")]
|
||||
@@ -199,7 +201,7 @@ pub async fn version_edit(
|
||||
let user = get_user_from_headers(req.headers(), &**pool).await?;
|
||||
|
||||
new_version.validate().map_err(|err| {
|
||||
ApiError::ValidationError(validation_errors_to_string(err, None))
|
||||
ApiError::Validation(validation_errors_to_string(err, None))
|
||||
})?;
|
||||
|
||||
let version_id = info.into_inner().0;
|
||||
@@ -227,7 +229,7 @@ pub async fn version_edit(
|
||||
|
||||
if let Some(perms) = permissions {
|
||||
if !perms.contains(Permissions::UPLOAD_VERSION) {
|
||||
return Err(ApiError::CustomAuthenticationError(
|
||||
return Err(ApiError::CustomAuthentication(
|
||||
"You do not have the permissions to edit this version!"
|
||||
.to_string(),
|
||||
));
|
||||
@@ -321,7 +323,7 @@ pub async fn version_edit(
|
||||
)
|
||||
.await?
|
||||
.ok_or_else(|| {
|
||||
ApiError::InvalidInputError(
|
||||
ApiError::InvalidInput(
|
||||
"No database entry for game version provided."
|
||||
.to_string(),
|
||||
)
|
||||
@@ -358,7 +360,7 @@ pub async fn version_edit(
|
||||
)
|
||||
.await?
|
||||
.ok_or_else(|| {
|
||||
ApiError::InvalidInputError(
|
||||
ApiError::InvalidInput(
|
||||
"No database entry for loader provided."
|
||||
.to_string(),
|
||||
)
|
||||
@@ -404,7 +406,7 @@ pub async fn version_edit(
|
||||
.fetch_optional(&**pool)
|
||||
.await?
|
||||
.ok_or_else(|| {
|
||||
ApiError::InvalidInputError(format!(
|
||||
ApiError::InvalidInput(format!(
|
||||
"Specified file with hash {} does not exist.",
|
||||
primary_file.1.clone()
|
||||
))
|
||||
@@ -447,10 +449,38 @@ pub async fn version_edit(
|
||||
.await?;
|
||||
}
|
||||
|
||||
if let Some(downloads) = &new_version.downloads {
|
||||
sqlx::query!(
|
||||
"
|
||||
UPDATE versions
|
||||
SET downloads = $1
|
||||
WHERE (id = $2)
|
||||
",
|
||||
*downloads as i32,
|
||||
id as database::models::ids::VersionId,
|
||||
)
|
||||
.execute(&mut *transaction)
|
||||
.await?;
|
||||
|
||||
let diff = *downloads - (version_item.downloads as u32);
|
||||
|
||||
sqlx::query!(
|
||||
"
|
||||
UPDATE mods
|
||||
SET downloads = downloads + $1
|
||||
WHERE (id = $2)
|
||||
",
|
||||
diff as i32,
|
||||
version_item.project_id as database::models::ids::ProjectId,
|
||||
)
|
||||
.execute(&mut *transaction)
|
||||
.await?;
|
||||
}
|
||||
|
||||
transaction.commit().await?;
|
||||
Ok(HttpResponse::NoContent().body(""))
|
||||
} else {
|
||||
Err(ApiError::CustomAuthenticationError(
|
||||
Err(ApiError::CustomAuthentication(
|
||||
"You do not have permission to edit this version!".to_string(),
|
||||
))
|
||||
}
|
||||
@@ -503,7 +533,7 @@ pub async fn version_count_patch(
|
||||
.execute(pool.as_ref()),
|
||||
)
|
||||
.await
|
||||
.map_err(ApiError::SqlxDatabaseError)?;
|
||||
.map_err(ApiError::SqlxDatabase)?;
|
||||
|
||||
Ok(HttpResponse::Ok().body(""))
|
||||
}
|
||||
@@ -524,9 +554,9 @@ pub async fn version_delete(
|
||||
&**pool,
|
||||
)
|
||||
.await
|
||||
.map_err(ApiError::DatabaseError)?
|
||||
.map_err(ApiError::Database)?
|
||||
.ok_or_else(|| {
|
||||
ApiError::InvalidInputError(
|
||||
ApiError::InvalidInput(
|
||||
"You do not have permission to delete versions in this team".to_string(),
|
||||
)
|
||||
})?;
|
||||
@@ -535,7 +565,7 @@ pub async fn version_delete(
|
||||
.permissions
|
||||
.contains(Permissions::DELETE_VERSION)
|
||||
{
|
||||
return Err(ApiError::CustomAuthenticationError(
|
||||
return Err(ApiError::CustomAuthentication(
|
||||
"You do not have permission to delete versions in this team"
|
||||
.to_string(),
|
||||
));
|
||||
|
||||
Reference in New Issue
Block a user