X-Git-Url: http://these/git/?a=blobdiff_plain;f=crates%2Fapi%2Fsrc%2Flib.rs;h=b297f503f6f9d4abc2115255a55e8ca567bd5fff;hb=3471f3533cb724b2cf6953d563aadfcc9f66c1d2;hp=dbff533eabdd56051e7f237a6210e3b299302c31;hpb=6f3bf4634b0e1cf529c4683d6ee971917e2bfa50;p=lemmy.git diff --git a/crates/api/src/lib.rs b/crates/api/src/lib.rs index dbff533e..b297f503 100644 --- a/crates/api/src/lib.rs +++ b/crates/api/src/lib.rs @@ -1,77 +1,13 @@ -use actix_web::{web, web::Data}; +use actix_web::web::Data; +use base64::{engine::general_purpose::STANDARD_NO_PAD as base64, Engine}; use captcha::Captcha; -use lemmy_api_common::{ - comment::{ - CreateCommentLike, - CreateCommentReport, - ListCommentReports, - ResolveCommentReport, - SaveComment, - }, - community::{ - AddModToCommunity, - BanFromCommunity, - BlockCommunity, - FollowCommunity, - TransferCommunity, - }, - person::{ - AddAdmin, - BanPerson, - BlockPerson, - ChangePassword, - GetBannedPersons, - GetCaptcha, - GetPersonMentions, - GetReplies, - GetReportCount, - GetUnreadCount, - Login, - MarkAllAsRead, - MarkCommentReplyAsRead, - MarkPersonMentionAsRead, - PasswordChangeAfterReset, - PasswordReset, - SaveUserSettings, - VerifyEmail, - }, - post::{ - CreatePostLike, - CreatePostReport, - GetSiteMetadata, - ListPostReports, - LockPost, - MarkPostAsRead, - ResolvePostReport, - SavePost, - StickyPost, - }, - private_message::{ - CreatePrivateMessageReport, - ListPrivateMessageReports, - MarkPrivateMessageAsRead, - ResolvePrivateMessageReport, - }, - site::{ - ApproveRegistrationApplication, - GetModlog, - GetUnreadRegistrationApplicationCount, - LeaveAdmin, - ListRegistrationApplications, - PurgeComment, - PurgeCommunity, - PurgePerson, - PurgePost, - ResolveObject, - Search, - }, - utils::local_site_to_slur_regex, - websocket::{CommunityJoin, ModJoin, PostJoin, UserJoin}, -}; +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_websocket::{serialize_websocket_message, LemmyContext, UserOperation}; -use serde::Deserialize; +use lemmy_utils::{ + error::{LemmyError, LemmyErrorExt, LemmyErrorType}, + utils::slurs::check_slurs, +}; +use std::io::Cursor; mod comment; mod comment_report; @@ -82,226 +18,67 @@ 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; -} - -pub async fn match_websocket_operation( - context: LemmyContext, - id: ConnectionId, - op: UserOperation, - data: &str, -) -> Result { - match op { - // User ops - UserOperation::Login => do_websocket_operation::(context, id, op, data).await, - UserOperation::GetCaptcha => do_websocket_operation::(context, id, op, data).await, - UserOperation::GetReplies => do_websocket_operation::(context, id, op, data).await, - UserOperation::AddAdmin => do_websocket_operation::(context, id, op, data).await, - UserOperation::GetUnreadRegistrationApplicationCount => { - do_websocket_operation::(context, id, op, data).await - } - UserOperation::ListRegistrationApplications => { - do_websocket_operation::(context, id, op, data).await - } - UserOperation::ApproveRegistrationApplication => { - do_websocket_operation::(context, id, op, data).await - } - UserOperation::BanPerson => do_websocket_operation::(context, id, op, data).await, - UserOperation::GetBannedPersons => { - do_websocket_operation::(context, id, op, data).await - } - UserOperation::BlockPerson => { - do_websocket_operation::(context, id, op, data).await - } - UserOperation::GetPersonMentions => { - do_websocket_operation::(context, id, op, data).await - } - UserOperation::MarkPersonMentionAsRead => { - do_websocket_operation::(context, id, op, data).await - } - UserOperation::MarkCommentReplyAsRead => { - do_websocket_operation::(context, id, op, data).await - } - UserOperation::MarkAllAsRead => { - do_websocket_operation::(context, id, op, data).await - } - UserOperation::PasswordReset => { - do_websocket_operation::(context, id, op, data).await - } - UserOperation::PasswordChange => { - do_websocket_operation::(context, id, op, data).await - } - UserOperation::UserJoin => do_websocket_operation::(context, id, op, data).await, - UserOperation::PostJoin => do_websocket_operation::(context, id, op, data).await, - UserOperation::CommunityJoin => { - do_websocket_operation::(context, id, op, data).await - } - UserOperation::ModJoin => do_websocket_operation::(context, id, op, data).await, - UserOperation::SaveUserSettings => { - do_websocket_operation::(context, id, op, data).await - } - UserOperation::ChangePassword => { - do_websocket_operation::(context, id, op, data).await - } - UserOperation::GetReportCount => { - do_websocket_operation::(context, id, op, data).await - } - UserOperation::GetUnreadCount => { - do_websocket_operation::(context, id, op, data).await - } - UserOperation::VerifyEmail => { - do_websocket_operation::(context, id, op, data).await - } - - // Private Message ops - UserOperation::MarkPrivateMessageAsRead => { - do_websocket_operation::(context, id, op, data).await - } - UserOperation::CreatePrivateMessageReport => { - do_websocket_operation::(context, id, op, data).await - } - UserOperation::ResolvePrivateMessageReport => { - do_websocket_operation::(context, id, op, data).await - } - UserOperation::ListPrivateMessageReports => { - do_websocket_operation::(context, id, op, data).await - } - - // Site ops - UserOperation::GetModlog => do_websocket_operation::(context, id, op, data).await, - UserOperation::PurgePerson => { - do_websocket_operation::(context, id, op, data).await - } - UserOperation::PurgeCommunity => { - do_websocket_operation::(context, id, op, data).await - } - UserOperation::PurgePost => do_websocket_operation::(context, id, op, data).await, - UserOperation::PurgeComment => { - do_websocket_operation::(context, id, op, data).await - } - UserOperation::Search => do_websocket_operation::(context, id, op, data).await, - UserOperation::ResolveObject => { - do_websocket_operation::(context, id, op, data).await - } - UserOperation::TransferCommunity => { - do_websocket_operation::(context, id, op, data).await - } - UserOperation::LeaveAdmin => do_websocket_operation::(context, id, op, data).await, - - // Community ops - UserOperation::FollowCommunity => { - do_websocket_operation::(context, id, op, data).await - } - UserOperation::BlockCommunity => { - do_websocket_operation::(context, id, op, data).await - } - UserOperation::BanFromCommunity => { - do_websocket_operation::(context, id, op, data).await - } - UserOperation::AddModToCommunity => { - do_websocket_operation::(context, id, op, data).await - } - - // Post ops - UserOperation::LockPost => do_websocket_operation::(context, id, op, data).await, - UserOperation::StickyPost => do_websocket_operation::(context, id, op, data).await, - UserOperation::CreatePostLike => { - do_websocket_operation::(context, id, op, data).await - } - UserOperation::MarkPostAsRead => { - do_websocket_operation::(context, id, op, data).await - } - UserOperation::SavePost => do_websocket_operation::(context, id, op, data).await, - UserOperation::CreatePostReport => { - do_websocket_operation::(context, id, op, data).await - } - UserOperation::ListPostReports => { - do_websocket_operation::(context, id, op, data).await - } - UserOperation::ResolvePostReport => { - do_websocket_operation::(context, id, op, data).await - } - UserOperation::GetSiteMetadata => { - do_websocket_operation::(context, id, op, data).await - } - - // Comment ops - UserOperation::SaveComment => { - do_websocket_operation::(context, id, op, data).await - } - UserOperation::CreateCommentLike => { - do_websocket_operation::(context, id, op, data).await - } - UserOperation::CreateCommentReport => { - do_websocket_operation::(context, id, op, data).await - } - UserOperation::ListCommentReports => { - do_websocket_operation::(context, id, op, data).await - } - UserOperation::ResolveCommentReport => { - do_websocket_operation::(context, id, op, data).await - } - } -} - -async fn do_websocket_operation<'a, 'b, Data>( - context: LemmyContext, - id: ConnectionId, - op: UserOperation, - data: &str, -) -> Result -where - for<'de> Data: Deserialize<'de> + 'a, - Data: Perform, -{ - let parsed_data: Data = serde_json::from_str(data)?; - let res = parsed_data - .perform(&web::Data::new(context), Some(id)) - .await?; - serialize_websocket_message(&op, &res) + 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 +/// Check size of report pub(crate) fn check_report_reason(reason: &str, local_site: &LocalSite) -> Result<(), LemmyError> { let slur_regex = &local_site_to_slur_regex(local_site); 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::{ @@ -320,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())