X-Git-Url: http://these/git/?a=blobdiff_plain;f=crates%2Fapi%2Fsrc%2Flib.rs;h=9d3cf211c233ef5da1df63408310b18cb69ef840;hb=92568956353f21649ed9aff68b42699c9d036f30;hp=5904a9b9b1df48f2a8ea695f3c36ff2dbb0f0dcf;hpb=c6c52ab9ccde330b5012f8d0ce4fc8f26628d5cc;p=lemmy.git diff --git a/crates/api/src/lib.rs b/crates/api/src/lib.rs index 5904a9b9..9d3cf211 100644 --- a/crates/api/src/lib.rs +++ b/crates/api/src/lib.rs @@ -1,8 +1,13 @@ use actix_web::web::Data; +use base64::{engine::general_purpose::STANDARD_NO_PAD as base64, Engine}; use captcha::Captcha; use lemmy_api_common::{context::LemmyContext, utils::local_site_to_slur_regex}; use lemmy_db_schema::source::local_site::LocalSite; -use lemmy_utils::{error::LemmyError, utils::check_slurs, ConnectionId}; +use lemmy_utils::{ + error::{LemmyError, LemmyErrorExt, LemmyErrorType}, + utils::slurs::check_slurs, +}; +use std::io::Cursor; mod comment; mod comment_report; @@ -13,32 +18,46 @@ mod post_report; mod private_message; mod private_message_report; mod site; -mod websocket; #[async_trait::async_trait(?Send)] pub trait Perform { - type Response: serde::ser::Serialize + Send; + type Response: serde::ser::Serialize + Send + Clone + Sync; - async fn perform( - &self, - context: &Data, - websocket_id: Option, - ) -> Result; + async fn perform(&self, context: &Data) -> Result; } /// Converts the captcha to a base64 encoded wav audio file -pub(crate) fn captcha_as_wav_base64(captcha: &Captcha) -> String { +pub(crate) fn captcha_as_wav_base64(captcha: &Captcha) -> Result { let letters = captcha.as_wav(); - let mut concat_letters: Vec = Vec::new(); - + // Decode each wav file, concatenate the samples + let mut concat_samples: Vec = Vec::new(); + let mut any_header: Option = None; for letter in letters { - let bytes = letter.unwrap_or_default(); - concat_letters.extend(bytes); + let mut cursor = Cursor::new(letter.unwrap_or_default()); + let (header, samples) = wav::read(&mut cursor)?; + any_header = Some(header); + if let Some(samples16) = samples.as_sixteen() { + concat_samples.extend(samples16); + } else { + return Err(LemmyErrorType::CouldntCreateAudioCaptcha)?; + } } - // Convert to base64 - base64::encode(concat_letters) + // Encode the concatenated result as a wav file + let mut output_buffer = Cursor::new(vec![]); + let header = match any_header { + Some(header) => header, + None => return Err(LemmyErrorType::CouldntCreateAudioCaptcha)?, + }; + wav::write( + header, + &wav::BitDepth::Sixteen(concat_samples), + &mut output_buffer, + ) + .with_lemmy_type(LemmyErrorType::CouldntCreateAudioCaptcha)?; + + Ok(base64.encode(output_buffer.into_inner())) } /// Check size of report and remove whitespace @@ -47,16 +66,19 @@ pub(crate) fn check_report_reason(reason: &str, local_site: &LocalSite) -> Resul check_slurs(reason, slur_regex)?; if reason.is_empty() { - return Err(LemmyError::from_message("report_reason_required")); + return Err(LemmyErrorType::ReportReasonRequired)?; } if reason.chars().count() > 1000 { - return Err(LemmyError::from_message("report_too_long")); + return Err(LemmyErrorType::ReportTooLong)?; } Ok(()) } #[cfg(test)] mod tests { + #![allow(clippy::unwrap_used)] + #![allow(clippy::indexing_slicing)] + use lemmy_api_common::utils::check_validator_time; use lemmy_db_schema::{ source::{ @@ -75,10 +97,13 @@ mod tests { #[serial] async fn test_should_not_validate_user_token_after_password_change() { let pool = &build_db_pool_for_tests().await; + let pool = &mut pool.into(); let secret = Secret::init(pool).await.unwrap(); let settings = &SETTINGS.to_owned(); - let inserted_instance = Instance::create(pool, "my_domain.tld").await.unwrap(); + let inserted_instance = Instance::read_or_create(pool, "my_domain.tld".to_string()) + .await + .unwrap(); let new_person = PersonInsertForm::builder() .name("Gerry9812".into())