diff --git a/src/error.rs b/src/error.rs index 5d6da93..bac192a 100755 --- a/src/error.rs +++ b/src/error.rs @@ -22,7 +22,7 @@ pub enum NekrochanError { CapcodeFormatError, #[error("E-mail nesmí mít více než 256 znaků.")] EmailFormatError, - #[error("Obsah nesmí mít více než 4000 znaků")] + #[error("Obsah nesmí mít více než 10000 znaků.")] ContentFormatError, #[error("Nástěnka /{}/ neexistuje.", .0)] BoardNotFound(String), @@ -30,6 +30,8 @@ pub enum NekrochanError { AccountNotFound(String), #[error("Příspěvek /{}/{} neexistuje.", .0, .1)] PostNotFound(String, i32), + #[error("Žádný takový ban pro tuto IP adresu neexistuje.")] + BanNotFound, #[error("Nedostatečná oprávnění.")] InsufficientPermissionError, #[error("Nesprávné přihlašovací údaje.")] @@ -70,6 +72,10 @@ pub enum NekrochanError { FileLimitError(usize), #[error("Nesprávné heslo pro příspěvek #{}.", .0)] IncorrectPasswordError(i32), + #[error("Tento ban už byl odvolán.")] + AlreadyAppealedError, + #[error("Tento ban nelze odvolat.")] + UnappealableError, // 500 #[error("Nadnástěnka nebyla inicializována.")] OverboardError, @@ -193,41 +199,45 @@ impl From for NekrochanError { impl ResponseError for NekrochanError { fn status_code(&self) -> StatusCode { match self { - NekrochanError::FileError(_, _) => StatusCode::BAD_REQUEST, - NekrochanError::UsernameFormatError => StatusCode::BAD_REQUEST, - NekrochanError::PasswordFormatError => StatusCode::BAD_REQUEST, - NekrochanError::IdFormatError => StatusCode::BAD_REQUEST, - NekrochanError::BoardNameFormatError => StatusCode::BAD_REQUEST, - NekrochanError::DescriptionFormatError => StatusCode::BAD_REQUEST, - NekrochanError::PostNameFormatError => StatusCode::BAD_REQUEST, - NekrochanError::CapcodeFormatError => StatusCode::BAD_REQUEST, - NekrochanError::EmailFormatError => StatusCode::BAD_REQUEST, - NekrochanError::ContentFormatError => StatusCode::BAD_REQUEST, - NekrochanError::BoardNotFound(_) => StatusCode::NOT_FOUND, - NekrochanError::AccountNotFound(_) => StatusCode::NOT_FOUND, - NekrochanError::PostNotFound(_, _) => StatusCode::NOT_FOUND, - NekrochanError::InsufficientPermissionError => StatusCode::FORBIDDEN, - NekrochanError::IncorrectCredentialError => StatusCode::UNAUTHORIZED, - NekrochanError::InvalidPageError => StatusCode::NOT_FOUND, - NekrochanError::InvalidAuthError => StatusCode::NOT_FOUND, - NekrochanError::NotLoggedInError => StatusCode::UNAUTHORIZED, - NekrochanError::OwnerDeletionError => StatusCode::FORBIDDEN, + NekrochanError::FileError(_, _) + | NekrochanError::UsernameFormatError + | NekrochanError::PasswordFormatError + | NekrochanError::IdFormatError + | NekrochanError::BoardNameFormatError + | NekrochanError::DescriptionFormatError + | NekrochanError::PostNameFormatError + | NekrochanError::CapcodeFormatError + | NekrochanError::EmailFormatError + | NekrochanError::ContentFormatError + | NekrochanError::ReplyReplyError + | NekrochanError::NoContentError + | NekrochanError::NoFileError + | NekrochanError::EmptyPostError + | NekrochanError::RequiredCaptchaError + | NekrochanError::SolvedCaptchaError + | NekrochanError::NoPostsError + | NekrochanError::FileLimitError(_) + | NekrochanError::AlreadyAppealedError + | NekrochanError::UnappealableError => StatusCode::BAD_REQUEST, + NekrochanError::BoardNotFound(_) + | NekrochanError::AccountNotFound(_) + | NekrochanError::PostNotFound(_, _) + | NekrochanError::BanNotFound + | NekrochanError::InvalidPageError + | NekrochanError::InvalidAuthError => StatusCode::NOT_FOUND, + NekrochanError::InsufficientPermissionError + | NekrochanError::ReplyLimitError + | NekrochanError::ThreadLockError + | NekrochanError::BoardLockError(_) + | NekrochanError::OwnerDeletionError => StatusCode::FORBIDDEN, + NekrochanError::IncorrectCredentialError + | NekrochanError::NotLoggedInError + | NekrochanError::IncorrectCaptchaError + | NekrochanError::IncorrectPasswordError(_) => StatusCode::UNAUTHORIZED, NekrochanError::HeaderError(_) => StatusCode::BAD_GATEWAY, - NekrochanError::BoardLockError(_) => StatusCode::FORBIDDEN, - NekrochanError::ThreadLockError => StatusCode::FORBIDDEN, - NekrochanError::ReplyReplyError => StatusCode::BAD_REQUEST, - NekrochanError::ReplyLimitError => StatusCode::FORBIDDEN, - NekrochanError::NoContentError => StatusCode::BAD_REQUEST, - NekrochanError::NoFileError => StatusCode::BAD_REQUEST, - NekrochanError::EmptyPostError => StatusCode::BAD_REQUEST, - NekrochanError::RequiredCaptchaError => StatusCode::BAD_REQUEST, - NekrochanError::IncorrectCaptchaError => StatusCode::UNAUTHORIZED, - NekrochanError::SolvedCaptchaError => StatusCode::BAD_REQUEST, - NekrochanError::NoPostsError => StatusCode::BAD_REQUEST, - NekrochanError::FileLimitError(_) => StatusCode::BAD_REQUEST, - NekrochanError::IncorrectPasswordError(_) => StatusCode::UNAUTHORIZED, - NekrochanError::OverboardError => StatusCode::INTERNAL_SERVER_ERROR, - NekrochanError::InternalError => StatusCode::INTERNAL_SERVER_ERROR, + NekrochanError::OverboardError | NekrochanError::InternalError => { + StatusCode::INTERNAL_SERVER_ERROR + } } } } diff --git a/src/main.rs b/src/main.rs index 4900ccd..2bdc35a 100755 --- a/src/main.rs +++ b/src/main.rs @@ -71,6 +71,7 @@ async fn run() -> Result<(), Error> { .service(web::actions::user_post_actions::user_post_actions) .service(web::actions::staff_post_actions::staff_post_actions) .service(web::actions::report_posts::report_posts) + .service(web::actions::appeal_ban::appeal_ban) .service(web::login::login_get) .service(web::login::login_post) .service(web::logout::logout) diff --git a/src/web/actions/appeal_ban.rs b/src/web/actions/appeal_ban.rs new file mode 100644 index 0000000..b6777a6 --- /dev/null +++ b/src/web/actions/appeal_ban.rs @@ -0,0 +1,54 @@ +use actix_web::{post, web::Data, HttpRequest, HttpResponse}; +use serde::Deserialize; + +use super::ActionTemplate; +use crate::{ + ctx::Ctx, + db::models::Ban, + error::NekrochanError, + qsform::QsForm, + web::{ + tcx::{ip_from_req, TemplateCtx}, + template_response, + }, +}; + +#[derive(Deserialize)] +pub struct AppealBanForm { + pub id: i32, + pub appeal: String, +} + +#[post("/actions/appeal-ban")] +pub async fn appeal_ban( + ctx: Data, + req: HttpRequest, + QsForm(form): QsForm, +) -> Result { + let tcx = TemplateCtx::new(&ctx, &req).await?; + let (ip, _) = ip_from_req(&req)?; + + let ban = Ban::read_by_id(&ctx, form.id) + .await? + .ok_or(NekrochanError::BanNotFound)?; + + if !ban.ip_range.contains(ip) { + return Err(NekrochanError::BanNotFound); + } + + if ban.appeal.is_some() { + return Err(NekrochanError::AlreadyAppealedError); + } + + if !ban.appealable { + return Err(NekrochanError::UnappealableError); + } + + let appeal = form.appeal.trim().into(); + ban.update_appeal(&ctx, appeal).await?; + + template_response(&ActionTemplate { + tcx, + response: "Ban byl úspěšně odvolán.".into(), + }) +} diff --git a/src/web/actions/create_post.rs b/src/web/actions/create_post.rs index a0c819a..2cdbf05 100644 --- a/src/web/actions/create_post.rs +++ b/src/web/actions/create_post.rs @@ -159,7 +159,7 @@ pub async fn create_post( return Err(NekrochanError::NoContentError); } - if content_nomarkup.len() > 4000 { + if content_nomarkup.len() > 10000 { return Err(NekrochanError::ContentFormatError); } diff --git a/src/web/actions/mod.rs b/src/web/actions/mod.rs index f5a27e6..66aa05c 100644 --- a/src/web/actions/mod.rs +++ b/src/web/actions/mod.rs @@ -4,6 +4,7 @@ use super::tcx::TemplateCtx; use crate::{ctx::Ctx, db::models::Post}; pub mod create_post; +pub mod appeal_ban; pub mod report_posts; pub mod staff_post_actions; pub mod user_post_actions; diff --git a/templates/banned.html b/templates/banned.html index bc7aa15..3b3c419 100644 --- a/templates/banned.html +++ b/templates/banned.html @@ -44,6 +44,7 @@ {% else %} Můžeš se pokusit svůj ban odvolat:
+
Odvolání