use actix_web::{web, web::Data};
-use lemmy_api_common::{comment::*, community::*, person::*, post::*, site::*, websocket::*};
-use lemmy_utils::{ConnectionId, LemmyError};
+use captcha::Captcha;
+use lemmy_api_common::{
+ comment::*,
+ community::*,
+ person::*,
+ post::*,
+ private_message::*,
+ site::*,
+ websocket::*,
+};
+use lemmy_utils::{error::LemmyError, utils::check_slurs, ConnectionId};
use lemmy_websocket::{serialize_websocket_message, LemmyContext, UserOperation};
use serde::Deserialize;
-use std::{env, process::Command};
mod comment;
mod comment_report;
mod post;
mod post_report;
mod private_message;
-pub mod routes;
+mod private_message_report;
mod site;
mod websocket;
op: UserOperation,
data: &str,
) -> Result<String, LemmyError> {
- //TODO: handle commented out actions in crud crate
-
match op {
// User ops
- UserOperation::Login => {
- //do_websocket_operation::<Login>(context, id, op, data).await
- todo!()
- }
- UserOperation::Register => {
- //do_websocket_operation::<Register>(context, id, op, data).await
- todo!()
- }
+ UserOperation::Login => do_websocket_operation::<Login>(context, id, op, data).await,
UserOperation::GetCaptcha => do_websocket_operation::<GetCaptcha>(context, id, op, data).await,
- UserOperation::GetPersonDetails => {
- //do_websocket_operation::<GetPersonDetails>(context, id, op, data).await
- todo!()
- }
UserOperation::GetReplies => do_websocket_operation::<GetReplies>(context, id, op, data).await,
UserOperation::AddAdmin => do_websocket_operation::<AddAdmin>(context, id, op, data).await,
+ UserOperation::GetUnreadRegistrationApplicationCount => {
+ do_websocket_operation::<GetUnreadRegistrationApplicationCount>(context, id, op, data).await
+ }
+ UserOperation::ListRegistrationApplications => {
+ do_websocket_operation::<ListRegistrationApplications>(context, id, op, data).await
+ }
+ UserOperation::ApproveRegistrationApplication => {
+ do_websocket_operation::<ApproveRegistrationApplication>(context, id, op, data).await
+ }
UserOperation::BanPerson => do_websocket_operation::<BanPerson>(context, id, op, data).await,
+ UserOperation::GetBannedPersons => {
+ do_websocket_operation::<GetBannedPersons>(context, id, op, data).await
+ }
+ UserOperation::BlockPerson => {
+ do_websocket_operation::<BlockPerson>(context, id, op, data).await
+ }
UserOperation::GetPersonMentions => {
- //do_websocket_operation::<GetPersonMentions>(context, id, op, data).await
- todo!()
+ do_websocket_operation::<GetPersonMentions>(context, id, op, data).await
}
UserOperation::MarkPersonMentionAsRead => {
do_websocket_operation::<MarkPersonMentionAsRead>(context, id, op, data).await
}
+ UserOperation::MarkCommentReplyAsRead => {
+ do_websocket_operation::<MarkCommentReplyAsRead>(context, id, op, data).await
+ }
UserOperation::MarkAllAsRead => {
do_websocket_operation::<MarkAllAsRead>(context, id, op, data).await
}
- UserOperation::DeleteAccount => {
- //do_websocket_operation::<DeleteAccount>(context, id, op, data).await
- todo!()
- }
UserOperation::PasswordReset => {
do_websocket_operation::<PasswordReset>(context, id, op, data).await
}
UserOperation::PasswordChange => {
- do_websocket_operation::<PasswordChange>(context, id, op, data).await
+ do_websocket_operation::<PasswordChangeAfterReset>(context, id, op, data).await
}
UserOperation::UserJoin => do_websocket_operation::<UserJoin>(context, id, op, data).await,
UserOperation::PostJoin => do_websocket_operation::<PostJoin>(context, id, op, data).await,
UserOperation::SaveUserSettings => {
do_websocket_operation::<SaveUserSettings>(context, id, op, data).await
}
+ UserOperation::ChangePassword => {
+ do_websocket_operation::<ChangePassword>(context, id, op, data).await
+ }
UserOperation::GetReportCount => {
do_websocket_operation::<GetReportCount>(context, id, op, data).await
}
-
- // Private Message ops
- UserOperation::CreatePrivateMessage => {
- //do_websocket_operation::<CreatePrivateMessage>(context, id, op, data).await
- todo!()
- }
- UserOperation::EditPrivateMessage => {
- //do_websocket_operation::<EditPrivateMessage>(context, id, op, data).await
- todo!()
+ UserOperation::GetUnreadCount => {
+ do_websocket_operation::<GetUnreadCount>(context, id, op, data).await
}
- UserOperation::DeletePrivateMessage => {
- //do_websocket_operation::<DeletePrivateMessage>(context, id, op, data).await
- todo!()
+ UserOperation::VerifyEmail => {
+ do_websocket_operation::<VerifyEmail>(context, id, op, data).await
}
+
+ // Private Message ops
UserOperation::MarkPrivateMessageAsRead => {
do_websocket_operation::<MarkPrivateMessageAsRead>(context, id, op, data).await
}
- UserOperation::GetPrivateMessages => {
- //do_websocket_operation::<GetPrivateMessages>(context, id, op, data).await
- todo!()
+ UserOperation::CreatePrivateMessageReport => {
+ do_websocket_operation::<CreatePrivateMessageReport>(context, id, op, data).await
+ }
+ UserOperation::ResolvePrivateMessageReport => {
+ do_websocket_operation::<ResolvePrivateMessageReport>(context, id, op, data).await
+ }
+ UserOperation::ListPrivateMessageReports => {
+ do_websocket_operation::<ListPrivateMessageReports>(context, id, op, data).await
}
// Site ops
UserOperation::GetModlog => do_websocket_operation::<GetModlog>(context, id, op, data).await,
- UserOperation::CreateSite => {
- //do_websocket_operation::<CreateSite>(context, id, op, data).await
- todo!()
- }
- UserOperation::EditSite => {
- //do_websocket_operation::<EditSite>(context, id, op, data).await
- todo!()
- }
- UserOperation::GetSite => {
- //do_websocket_operation::<GetSite>(context, id, op, data).await
- todo!()
+ UserOperation::PurgePerson => {
+ do_websocket_operation::<PurgePerson>(context, id, op, data).await
}
- UserOperation::GetSiteConfig => {
- do_websocket_operation::<GetSiteConfig>(context, id, op, data).await
+ UserOperation::PurgeCommunity => {
+ do_websocket_operation::<PurgeCommunity>(context, id, op, data).await
}
- UserOperation::SaveSiteConfig => {
- do_websocket_operation::<SaveSiteConfig>(context, id, op, data).await
+ UserOperation::PurgePost => do_websocket_operation::<PurgePost>(context, id, op, data).await,
+ UserOperation::PurgeComment => {
+ do_websocket_operation::<PurgeComment>(context, id, op, data).await
}
UserOperation::Search => do_websocket_operation::<Search>(context, id, op, data).await,
+ UserOperation::ResolveObject => {
+ do_websocket_operation::<ResolveObject>(context, id, op, data).await
+ }
UserOperation::TransferCommunity => {
do_websocket_operation::<TransferCommunity>(context, id, op, data).await
}
- UserOperation::TransferSite => {
- do_websocket_operation::<TransferSite>(context, id, op, data).await
- }
+ UserOperation::LeaveAdmin => do_websocket_operation::<LeaveAdmin>(context, id, op, data).await,
// Community ops
- UserOperation::GetCommunity => {
- //do_websocket_operation::<GetCommunity>(context, id, op, data).await
- todo!()
- }
- UserOperation::ListCommunities => {
- //do_websocket_operation::<ListCommunities>(context, id, op, data).await
- todo!()
- }
- UserOperation::CreateCommunity => {
- //do_websocket_operation::<CreateCommunity>(context, id, op, data).await
- todo!()
- }
- UserOperation::EditCommunity => {
- //do_websocket_operation::<EditCommunity>(context, id, op, data).await
- todo!()
- }
- UserOperation::DeleteCommunity => {
- //do_websocket_operation::<DeleteCommunity>(context, id, op, data).await
- todo!()
- }
- UserOperation::RemoveCommunity => {
- //do_websocket_operation::<RemoveCommunity>(context, id, op, data).await
- todo!()
- }
UserOperation::FollowCommunity => {
do_websocket_operation::<FollowCommunity>(context, id, op, data).await
}
- UserOperation::GetFollowedCommunities => {
- do_websocket_operation::<GetFollowedCommunities>(context, id, op, data).await
+ UserOperation::BlockCommunity => {
+ do_websocket_operation::<BlockCommunity>(context, id, op, data).await
}
UserOperation::BanFromCommunity => {
do_websocket_operation::<BanFromCommunity>(context, id, op, data).await
}
// Post ops
- UserOperation::CreatePost => {
- //do_websocket_operation::<CreatePost>(context, id, op, data).await
- todo!()
- }
- UserOperation::GetPost => {
- //do_websocket_operation::<GetPost>(context, id, op, data).await
- todo!()
- }
- UserOperation::GetPosts => {
- //do_websocket_operation::<GetPosts>(context, id, op, data).await
- todo!()
- }
- UserOperation::EditPost => {
- //do_websocket_operation::<EditPost>(context, id, op, data).await
- todo!()
- }
- UserOperation::DeletePost => {
- //do_websocket_operation::<DeletePost>(context, id, op, data).await
- todo!()
- }
- UserOperation::RemovePost => {
- //do_websocket_operation::<RemovePost>(context, id, op, data).await
- todo!()
- }
UserOperation::LockPost => do_websocket_operation::<LockPost>(context, id, op, data).await,
UserOperation::StickyPost => do_websocket_operation::<StickyPost>(context, id, op, data).await,
UserOperation::CreatePostLike => {
do_websocket_operation::<CreatePostLike>(context, id, op, data).await
}
+ UserOperation::MarkPostAsRead => {
+ do_websocket_operation::<MarkPostAsRead>(context, id, op, data).await
+ }
UserOperation::SavePost => do_websocket_operation::<SavePost>(context, id, op, data).await,
UserOperation::CreatePostReport => {
do_websocket_operation::<CreatePostReport>(context, id, op, data).await
UserOperation::ResolvePostReport => {
do_websocket_operation::<ResolvePostReport>(context, id, op, data).await
}
+ UserOperation::GetSiteMetadata => {
+ do_websocket_operation::<GetSiteMetadata>(context, id, op, data).await
+ }
// Comment ops
- UserOperation::CreateComment => {
- //do_websocket_operation::<CreateComment>(context, id, op, data).await
- todo!()
- }
- UserOperation::EditComment => {
- //do_websocket_operation::<EditComment>(context, id, op, data).await
- todo!()
- }
- UserOperation::DeleteComment => {
- //do_websocket_operation::<DeleteComment>(context, id, op, data).await
- todo!()
- }
- UserOperation::RemoveComment => {
- //do_websocket_operation::<RemoveComment>(context, id, op, data).await
- todo!()
- }
- UserOperation::MarkCommentAsRead => {
- do_websocket_operation::<MarkCommentAsRead>(context, id, op, data).await
- }
UserOperation::SaveComment => {
do_websocket_operation::<SaveComment>(context, id, op, data).await
}
- UserOperation::GetComments => {
- //do_websocket_operation::<GetComments>(context, id, op, data).await
- todo!()
- }
UserOperation::CreateCommentLike => {
do_websocket_operation::<CreateCommentLike>(context, id, op, data).await
}
for<'de> Data: Deserialize<'de> + 'a,
Data: Perform,
{
- let parsed_data: Data = serde_json::from_str(&data)?;
+ 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)
}
-pub(crate) fn captcha_espeak_wav_base64(captcha: &str) -> Result<String, LemmyError> {
- let mut built_text = String::new();
+/// Converts the captcha to a base64 encoded wav audio file
+pub(crate) fn captcha_as_wav_base64(captcha: &Captcha) -> String {
+ let letters = captcha.as_wav();
- // Building proper speech text for espeak
- for mut c in captcha.chars() {
- let new_str = if c.is_alphabetic() {
- if c.is_lowercase() {
- c.make_ascii_uppercase();
- format!("lower case {} ... ", c)
- } else {
- c.make_ascii_uppercase();
- format!("capital {} ... ", c)
- }
- } else {
- format!("{} ...", c)
- };
+ let mut concat_letters: Vec<u8> = Vec::new();
- built_text.push_str(&new_str);
+ for letter in letters {
+ let bytes = letter.unwrap_or_default();
+ concat_letters.extend(bytes);
}
- espeak_wav_base64(&built_text)
-}
-
-pub(crate) fn espeak_wav_base64(text: &str) -> Result<String, LemmyError> {
- // Make a temp file path
- let uuid = uuid::Uuid::new_v4().to_string();
- let file_path = format!(
- "{}/lemmy_espeak_{}.wav",
- env::temp_dir().to_string_lossy(),
- &uuid
- );
-
- // Write the wav file
- Command::new("espeak")
- .arg("-w")
- .arg(&file_path)
- .arg(text)
- .status()?;
-
- // Read the wav file bytes
- let bytes = std::fs::read(&file_path)?;
-
- // Delete the file
- std::fs::remove_file(file_path)?;
-
// Convert to base64
- let base64 = base64::encode(bytes);
+ base64::encode(concat_letters)
+}
- Ok(base64)
+/// Check size of report and remove whitespace
+pub(crate) fn check_report_reason(reason: &str, context: &LemmyContext) -> Result<(), LemmyError> {
+ check_slurs(reason, &context.settings().slur_regex())?;
+ if reason.is_empty() {
+ return Err(LemmyError::from_message("report_reason_required"));
+ }
+ if reason.chars().count() > 1000 {
+ return Err(LemmyError::from_message("report_too_long"));
+ }
+ Ok(())
}
#[cfg(test)]
mod tests {
- use crate::{captcha_espeak_wav_base64, check_validator_time};
- use lemmy_api_common::check_validator_time;
- use lemmy_db_queries::{establish_unpooled_connection, source::local_user::LocalUser_, Crud};
- use lemmy_db_schema::source::{
- local_user::{LocalUser, LocalUserForm},
- person::{Person, PersonForm},
+ use lemmy_api_common::utils::check_validator_time;
+ use lemmy_db_schema::{
+ source::{
+ local_user::{LocalUser, LocalUserForm},
+ person::{Person, PersonForm},
+ secret::Secret,
+ },
+ traits::Crud,
+ utils::establish_unpooled_connection,
};
- use lemmy_utils::claims::Claims;
+ use lemmy_utils::{claims::Claims, settings::SETTINGS};
#[test]
fn test_should_not_validate_user_token_after_password_change() {
let conn = establish_unpooled_connection();
+ let secret = Secret::init(&conn).unwrap();
+ let settings = &SETTINGS.to_owned();
let new_person = PersonForm {
name: "Gerry9812".into(),
- preferred_username: None,
- avatar: None,
- banner: None,
- banned: None,
- deleted: None,
- published: None,
- updated: None,
- actor_id: None,
- bio: None,
- local: None,
- private_key: None,
- public_key: None,
- last_refreshed_at: None,
- inbox_url: None,
- shared_inbox_url: None,
+ public_key: Some("pubkey".to_string()),
+ ..PersonForm::default()
};
let inserted_person = Person::create(&conn, &new_person).unwrap();
let local_user_form = LocalUserForm {
- person_id: inserted_person.id,
- email: None,
- matrix_user_id: None,
- password_encrypted: "123456".to_string(),
- admin: None,
- show_nsfw: None,
- theme: None,
- default_sort_type: None,
- default_listing_type: None,
- lang: None,
- show_avatars: None,
- send_notifications_to_email: None,
+ person_id: Some(inserted_person.id),
+ password_encrypted: Some("123456".to_string()),
+ ..LocalUserForm::default()
};
let inserted_local_user = LocalUser::create(&conn, &local_user_form).unwrap();
- let jwt = Claims::jwt(inserted_local_user.id.0).unwrap();
- let claims = Claims::decode(&jwt).unwrap().claims;
+ let jwt = Claims::jwt(
+ inserted_local_user.id.0,
+ &secret.jwt_secret,
+ &settings.hostname,
+ )
+ .unwrap();
+ let claims = Claims::decode(&jwt, &secret.jwt_secret).unwrap().claims;
let check = check_validator_time(&inserted_local_user.validator_time, &claims);
assert!(check.is_ok());
// The check should fail, since the validator time is now newer than the jwt issue time
let updated_local_user =
- LocalUser::update_password(&conn, inserted_local_user.id, &"password111").unwrap();
+ LocalUser::update_password(&conn, inserted_local_user.id, "password111").unwrap();
let check_after = check_validator_time(&updated_local_user.validator_time, &claims);
assert!(check_after.is_err());
let num_deleted = Person::delete(&conn, inserted_person.id).unwrap();
assert_eq!(1, num_deleted);
}
-
- #[test]
- fn test_espeak() {
- assert!(captcha_espeak_wav_base64("WxRt2l").is_ok())
- }
}