2 use crate::settings::Settings;
3 use crate::{generate_random_string, send_email};
5 use diesel::PgConnection;
9 #[derive(Serialize, Deserialize, Debug)]
11 username_or_email: String,
15 #[derive(Serialize, Deserialize)]
18 email: Option<String>,
20 password_verify: String,
25 #[derive(Serialize, Deserialize)]
26 pub struct SaveUserSettings {
29 default_sort_type: i16,
30 default_listing_type: i16,
32 avatar: Option<String>,
33 email: Option<String>,
34 matrix_user_id: Option<String>,
35 new_password: Option<String>,
36 new_password_verify: Option<String>,
37 old_password: Option<String>,
39 send_notifications_to_email: bool,
43 #[derive(Serialize, Deserialize)]
44 pub struct LoginResponse {
48 #[derive(Serialize, Deserialize)]
49 pub struct GetUserDetails {
51 username: Option<String>,
55 community_id: Option<i32>,
60 #[derive(Serialize, Deserialize)]
61 pub struct GetUserDetailsResponse {
63 follows: Vec<CommunityFollowerView>,
64 moderates: Vec<CommunityModeratorView>,
65 comments: Vec<CommentView>,
67 admins: Vec<UserView>,
70 #[derive(Serialize, Deserialize)]
71 pub struct GetRepliesResponse {
72 replies: Vec<ReplyView>,
75 #[derive(Serialize, Deserialize)]
76 pub struct GetUserMentionsResponse {
77 mentions: Vec<UserMentionView>,
80 #[derive(Serialize, Deserialize)]
81 pub struct MarkAllAsRead {
85 #[derive(Serialize, Deserialize)]
92 #[derive(Serialize, Deserialize)]
93 pub struct AddAdminResponse {
94 admins: Vec<UserView>,
97 #[derive(Serialize, Deserialize)]
101 reason: Option<String>,
102 expires: Option<i64>,
106 #[derive(Serialize, Deserialize)]
107 pub struct BanUserResponse {
112 #[derive(Serialize, Deserialize)]
113 pub struct GetReplies {
121 #[derive(Serialize, Deserialize)]
122 pub struct GetUserMentions {
130 #[derive(Serialize, Deserialize)]
131 pub struct EditUserMention {
132 user_mention_id: i32,
137 #[derive(Serialize, Deserialize, Clone)]
138 pub struct UserMentionResponse {
139 mention: UserMentionView,
142 #[derive(Serialize, Deserialize)]
143 pub struct DeleteAccount {
148 #[derive(Serialize, Deserialize)]
149 pub struct PasswordReset {
153 #[derive(Serialize, Deserialize, Clone)]
154 pub struct PasswordResetResponse {}
156 #[derive(Serialize, Deserialize)]
157 pub struct PasswordChange {
160 password_verify: String,
163 #[derive(Serialize, Deserialize)]
164 pub struct CreatePrivateMessage {
166 pub recipient_id: i32,
170 #[derive(Serialize, Deserialize)]
171 pub struct EditPrivateMessage {
173 content: Option<String>,
174 deleted: Option<bool>,
179 #[derive(Serialize, Deserialize)]
180 pub struct GetPrivateMessages {
187 #[derive(Serialize, Deserialize, Clone)]
188 pub struct PrivateMessagesResponse {
189 messages: Vec<PrivateMessageView>,
192 #[derive(Serialize, Deserialize, Clone)]
193 pub struct PrivateMessageResponse {
194 message: PrivateMessageView,
197 #[derive(Serialize, Deserialize, Debug)]
198 pub struct UserJoin {
202 #[derive(Serialize, Deserialize, Clone)]
203 pub struct UserJoinResponse {
207 impl Perform<LoginResponse> for Oper<Login> {
208 fn perform(&self, conn: &PgConnection) -> Result<LoginResponse, Error> {
209 let data: &Login = &self.data;
211 // Fetch that username / email
212 let user: User_ = match User_::find_by_email_or_username(&conn, &data.username_or_email) {
214 Err(_e) => return Err(APIError::err("couldnt_find_that_username_or_email").into()),
217 // Verify the password
218 let valid: bool = verify(&data.password, &user.password_encrypted).unwrap_or(false);
220 return Err(APIError::err("password_incorrect").into());
224 Ok(LoginResponse { jwt: user.jwt() })
228 impl Perform<LoginResponse> for Oper<Register> {
229 fn perform(&self, conn: &PgConnection) -> Result<LoginResponse, Error> {
230 let data: &Register = &self.data;
232 // Make sure site has open registration
233 if let Ok(site) = SiteView::read(&conn) {
234 if !site.open_registration {
235 return Err(APIError::err("registration_closed").into());
239 // Make sure passwords match
240 if data.password != data.password_verify {
241 return Err(APIError::err("passwords_dont_match").into());
244 if let Err(slurs) = slur_check(&data.username) {
245 return Err(APIError::err(&slurs_vec_to_str(slurs)).into());
248 // Make sure there are no admins
249 if data.admin && !UserView::admins(&conn)?.is_empty() {
250 return Err(APIError::err("admin_already_created").into());
253 // Register the new user
254 let user_form = UserForm {
255 name: data.username.to_owned(),
256 fedi_name: Settings::get().hostname.to_owned(),
257 email: data.email.to_owned(),
258 matrix_user_id: None,
260 password_encrypted: data.password.to_owned(),
261 preferred_username: None,
265 show_nsfw: data.show_nsfw,
266 theme: "darkly".into(),
267 default_sort_type: SortType::Hot as i16,
268 default_listing_type: ListingType::Subscribed as i16,
269 lang: "browser".into(),
271 send_notifications_to_email: false,
275 let inserted_user = match User_::register(&conn, &user_form) {
278 let err_type = if e.to_string()
279 == "duplicate key value violates unique constraint \"user__email_key\""
281 "email_already_exists"
283 "user_already_exists"
286 return Err(APIError::err(err_type).into());
290 // Create the main community if it doesn't exist
291 let main_community: Community = match Community::read(&conn, 2) {
294 let community_form = CommunityForm {
295 name: "main".to_string(),
296 title: "The Default Community".to_string(),
297 description: Some("The Default Community".to_string()),
300 creator_id: inserted_user.id,
305 Community::create(&conn, &community_form).unwrap()
309 // Sign them up for main community no matter what
310 let community_follower_form = CommunityFollowerForm {
311 community_id: main_community.id,
312 user_id: inserted_user.id,
315 let _inserted_community_follower =
316 match CommunityFollower::follow(&conn, &community_follower_form) {
318 Err(_e) => return Err(APIError::err("community_follower_already_exists").into()),
321 // If its an admin, add them as a mod and follower to main
323 let community_moderator_form = CommunityModeratorForm {
324 community_id: main_community.id,
325 user_id: inserted_user.id,
328 let _inserted_community_moderator =
329 match CommunityModerator::join(&conn, &community_moderator_form) {
331 Err(_e) => return Err(APIError::err("community_moderator_already_exists").into()),
337 jwt: inserted_user.jwt(),
342 impl Perform<LoginResponse> for Oper<SaveUserSettings> {
343 fn perform(&self, conn: &PgConnection) -> Result<LoginResponse, Error> {
344 let data: &SaveUserSettings = &self.data;
346 let claims = match Claims::decode(&data.auth) {
347 Ok(claims) => claims.claims,
348 Err(_e) => return Err(APIError::err("not_logged_in").into()),
351 let user_id = claims.id;
353 let read_user = User_::read(&conn, user_id)?;
355 let email = match &data.email {
356 Some(email) => Some(email.to_owned()),
357 None => read_user.email,
360 let password_encrypted = match &data.new_password {
361 Some(new_password) => {
362 match &data.new_password_verify {
363 Some(new_password_verify) => {
364 // Make sure passwords match
365 if new_password != new_password_verify {
366 return Err(APIError::err("passwords_dont_match").into());
369 // Check the old password
370 match &data.old_password {
371 Some(old_password) => {
373 verify(old_password, &read_user.password_encrypted).unwrap_or(false);
375 return Err(APIError::err("password_incorrect").into());
377 User_::update_password(&conn, user_id, &new_password)?.password_encrypted
379 None => return Err(APIError::err("password_incorrect").into()),
382 None => return Err(APIError::err("passwords_dont_match").into()),
385 None => read_user.password_encrypted,
388 let user_form = UserForm {
389 name: read_user.name,
390 fedi_name: read_user.fedi_name,
392 matrix_user_id: data.matrix_user_id.to_owned(),
393 avatar: data.avatar.to_owned(),
395 preferred_username: read_user.preferred_username,
396 updated: Some(naive_now()),
397 admin: read_user.admin,
398 banned: read_user.banned,
399 show_nsfw: data.show_nsfw,
400 theme: data.theme.to_owned(),
401 default_sort_type: data.default_sort_type,
402 default_listing_type: data.default_listing_type,
403 lang: data.lang.to_owned(),
404 show_avatars: data.show_avatars,
405 send_notifications_to_email: data.send_notifications_to_email,
408 let updated_user = match User_::update(&conn, user_id, &user_form) {
411 let err_type = if e.to_string()
412 == "duplicate key value violates unique constraint \"user__email_key\""
414 "email_already_exists"
416 "user_already_exists"
419 return Err(APIError::err(err_type).into());
425 jwt: updated_user.jwt(),
430 impl Perform<GetUserDetailsResponse> for Oper<GetUserDetails> {
431 fn perform(&self, conn: &PgConnection) -> Result<GetUserDetailsResponse, Error> {
432 let data: &GetUserDetails = &self.data;
434 let user_claims: Option<Claims> = match &data.auth {
435 Some(auth) => match Claims::decode(&auth) {
436 Ok(claims) => Some(claims.claims),
442 let user_id = match &user_claims {
443 Some(claims) => Some(claims.id),
447 let show_nsfw = match &user_claims {
448 Some(claims) => claims.show_nsfw,
452 let sort = SortType::from_str(&data.sort)?;
454 let user_details_id = match data.user_id {
457 match User_::read_from_name(
462 .unwrap_or_else(|| "admin".to_string()),
465 Err(_e) => return Err(APIError::err("couldnt_find_that_username_or_email").into()),
470 let mut user_view = UserView::read(&conn, user_details_id)?;
472 let mut posts_query = PostQueryBuilder::create(&conn)
474 .show_nsfw(show_nsfw)
475 .saved_only(data.saved_only)
476 .for_community_id(data.community_id)
481 let mut comments_query = CommentQueryBuilder::create(&conn)
483 .saved_only(data.saved_only)
488 // If its saved only, you don't care what creator it was
489 // Or, if its not saved, then you only want it for that specific creator
490 if !data.saved_only {
491 posts_query = posts_query.for_creator_id(user_details_id);
492 comments_query = comments_query.for_creator_id(user_details_id);
495 let posts = posts_query.list()?;
496 let comments = comments_query.list()?;
498 let follows = CommunityFollowerView::for_user(&conn, user_details_id)?;
499 let moderates = CommunityModeratorView::for_user(&conn, user_details_id)?;
500 let site_creator_id = Site::read(&conn, 1)?.creator_id;
501 let mut admins = UserView::admins(&conn)?;
502 let creator_index = admins.iter().position(|r| r.id == site_creator_id).unwrap();
503 let creator_user = admins.remove(creator_index);
504 admins.insert(0, creator_user);
506 // If its not the same user, remove the email
507 if let Some(user_id) = user_id {
508 if user_details_id != user_id {
509 user_view.email = None;
512 user_view.email = None;
516 Ok(GetUserDetailsResponse {
527 impl Perform<AddAdminResponse> for Oper<AddAdmin> {
528 fn perform(&self, conn: &PgConnection) -> Result<AddAdminResponse, Error> {
529 let data: &AddAdmin = &self.data;
531 let claims = match Claims::decode(&data.auth) {
532 Ok(claims) => claims.claims,
533 Err(_e) => return Err(APIError::err("not_logged_in").into()),
536 let user_id = claims.id;
538 // Make sure user is an admin
539 if !UserView::read(&conn, user_id)?.admin {
540 return Err(APIError::err("not_an_admin").into());
543 let read_user = User_::read(&conn, data.user_id)?;
545 // TODO make addadmin easier
546 let user_form = UserForm {
547 name: read_user.name,
548 fedi_name: read_user.fedi_name,
549 email: read_user.email,
550 matrix_user_id: read_user.matrix_user_id,
551 avatar: read_user.avatar,
552 password_encrypted: read_user.password_encrypted,
553 preferred_username: read_user.preferred_username,
554 updated: Some(naive_now()),
556 banned: read_user.banned,
557 show_nsfw: read_user.show_nsfw,
558 theme: read_user.theme,
559 default_sort_type: read_user.default_sort_type,
560 default_listing_type: read_user.default_listing_type,
561 lang: read_user.lang,
562 show_avatars: read_user.show_avatars,
563 send_notifications_to_email: read_user.send_notifications_to_email,
566 match User_::update(&conn, data.user_id, &user_form) {
568 Err(_e) => return Err(APIError::err("couldnt_update_user").into()),
572 let form = ModAddForm {
573 mod_user_id: user_id,
574 other_user_id: data.user_id,
575 removed: Some(!data.added),
578 ModAdd::create(&conn, &form)?;
580 let site_creator_id = Site::read(&conn, 1)?.creator_id;
581 let mut admins = UserView::admins(&conn)?;
582 let creator_index = admins.iter().position(|r| r.id == site_creator_id).unwrap();
583 let creator_user = admins.remove(creator_index);
584 admins.insert(0, creator_user);
586 Ok(AddAdminResponse { admins })
590 impl Perform<BanUserResponse> for Oper<BanUser> {
591 fn perform(&self, conn: &PgConnection) -> Result<BanUserResponse, Error> {
592 let data: &BanUser = &self.data;
594 let claims = match Claims::decode(&data.auth) {
595 Ok(claims) => claims.claims,
596 Err(_e) => return Err(APIError::err("not_logged_in").into()),
599 let user_id = claims.id;
601 // Make sure user is an admin
602 if !UserView::read(&conn, user_id)?.admin {
603 return Err(APIError::err("not_an_admin").into());
606 let read_user = User_::read(&conn, data.user_id)?;
608 // TODO make bans and addadmins easier
609 let user_form = UserForm {
610 name: read_user.name,
611 fedi_name: read_user.fedi_name,
612 email: read_user.email,
613 matrix_user_id: read_user.matrix_user_id,
614 avatar: read_user.avatar,
615 password_encrypted: read_user.password_encrypted,
616 preferred_username: read_user.preferred_username,
617 updated: Some(naive_now()),
618 admin: read_user.admin,
620 show_nsfw: read_user.show_nsfw,
621 theme: read_user.theme,
622 default_sort_type: read_user.default_sort_type,
623 default_listing_type: read_user.default_listing_type,
624 lang: read_user.lang,
625 show_avatars: read_user.show_avatars,
626 send_notifications_to_email: read_user.send_notifications_to_email,
629 match User_::update(&conn, data.user_id, &user_form) {
631 Err(_e) => return Err(APIError::err("couldnt_update_user").into()),
635 let expires = match data.expires {
636 Some(time) => Some(naive_from_unix(time)),
640 let form = ModBanForm {
641 mod_user_id: user_id,
642 other_user_id: data.user_id,
643 reason: data.reason.to_owned(),
644 banned: Some(data.ban),
648 ModBan::create(&conn, &form)?;
650 let user_view = UserView::read(&conn, data.user_id)?;
659 impl Perform<GetRepliesResponse> for Oper<GetReplies> {
660 fn perform(&self, conn: &PgConnection) -> Result<GetRepliesResponse, Error> {
661 let data: &GetReplies = &self.data;
663 let claims = match Claims::decode(&data.auth) {
664 Ok(claims) => claims.claims,
665 Err(_e) => return Err(APIError::err("not_logged_in").into()),
668 let user_id = claims.id;
670 let sort = SortType::from_str(&data.sort)?;
672 let replies = ReplyQueryBuilder::create(&conn, user_id)
674 .unread_only(data.unread_only)
679 Ok(GetRepliesResponse { replies })
683 impl Perform<GetUserMentionsResponse> for Oper<GetUserMentions> {
684 fn perform(&self, conn: &PgConnection) -> Result<GetUserMentionsResponse, Error> {
685 let data: &GetUserMentions = &self.data;
687 let claims = match Claims::decode(&data.auth) {
688 Ok(claims) => claims.claims,
689 Err(_e) => return Err(APIError::err("not_logged_in").into()),
692 let user_id = claims.id;
694 let sort = SortType::from_str(&data.sort)?;
696 let mentions = UserMentionQueryBuilder::create(&conn, user_id)
698 .unread_only(data.unread_only)
703 Ok(GetUserMentionsResponse { mentions })
707 impl Perform<UserMentionResponse> for Oper<EditUserMention> {
708 fn perform(&self, conn: &PgConnection) -> Result<UserMentionResponse, Error> {
709 let data: &EditUserMention = &self.data;
711 let claims = match Claims::decode(&data.auth) {
712 Ok(claims) => claims.claims,
713 Err(_e) => return Err(APIError::err("not_logged_in").into()),
716 let user_id = claims.id;
718 let user_mention = UserMention::read(&conn, data.user_mention_id)?;
720 let user_mention_form = UserMentionForm {
721 recipient_id: user_id,
722 comment_id: user_mention.comment_id,
723 read: data.read.to_owned(),
726 let _updated_user_mention =
727 match UserMention::update(&conn, user_mention.id, &user_mention_form) {
728 Ok(comment) => comment,
729 Err(_e) => return Err(APIError::err("couldnt_update_comment").into()),
732 let user_mention_view = UserMentionView::read(&conn, user_mention.id, user_id)?;
734 Ok(UserMentionResponse {
735 mention: user_mention_view,
740 impl Perform<GetRepliesResponse> for Oper<MarkAllAsRead> {
741 fn perform(&self, conn: &PgConnection) -> Result<GetRepliesResponse, Error> {
742 let data: &MarkAllAsRead = &self.data;
744 let claims = match Claims::decode(&data.auth) {
745 Ok(claims) => claims.claims,
746 Err(_e) => return Err(APIError::err("not_logged_in").into()),
749 let user_id = claims.id;
751 let replies = ReplyQueryBuilder::create(&conn, user_id)
757 for reply in &replies {
758 let comment_form = CommentForm {
759 content: reply.to_owned().content,
760 parent_id: reply.to_owned().parent_id,
761 post_id: reply.to_owned().post_id,
762 creator_id: reply.to_owned().creator_id,
766 updated: reply.to_owned().updated,
769 let _updated_comment = match Comment::update(&conn, reply.id, &comment_form) {
770 Ok(comment) => comment,
771 Err(_e) => return Err(APIError::err("couldnt_update_comment").into()),
776 let mentions = UserMentionQueryBuilder::create(&conn, user_id)
782 for mention in &mentions {
783 let mention_form = UserMentionForm {
784 recipient_id: mention.to_owned().recipient_id,
785 comment_id: mention.to_owned().id,
789 let _updated_mention =
790 match UserMention::update(&conn, mention.user_mention_id, &mention_form) {
791 Ok(mention) => mention,
792 Err(_e) => return Err(APIError::err("couldnt_update_comment").into()),
797 let messages = PrivateMessageQueryBuilder::create(&conn, user_id)
803 for message in &messages {
804 let private_message_form = PrivateMessageForm {
806 creator_id: message.to_owned().creator_id,
807 recipient_id: message.to_owned().recipient_id,
813 let _updated_message = match PrivateMessage::update(&conn, message.id, &private_message_form)
815 Ok(message) => message,
816 Err(_e) => return Err(APIError::err("couldnt_update_private_message").into()),
820 Ok(GetRepliesResponse { replies: vec![] })
824 impl Perform<LoginResponse> for Oper<DeleteAccount> {
825 fn perform(&self, conn: &PgConnection) -> Result<LoginResponse, Error> {
826 let data: &DeleteAccount = &self.data;
828 let claims = match Claims::decode(&data.auth) {
829 Ok(claims) => claims.claims,
830 Err(_e) => return Err(APIError::err("not_logged_in").into()),
833 let user_id = claims.id;
835 let user: User_ = User_::read(&conn, user_id)?;
837 // Verify the password
838 let valid: bool = verify(&data.password, &user.password_encrypted).unwrap_or(false);
840 return Err(APIError::err("password_incorrect").into());
844 let comments = CommentQueryBuilder::create(&conn)
845 .for_creator_id(user_id)
846 .limit(std::i64::MAX)
849 for comment in &comments {
850 let comment_form = CommentForm {
851 content: "*Permananently Deleted*".to_string(),
852 parent_id: comment.to_owned().parent_id,
853 post_id: comment.to_owned().post_id,
854 creator_id: comment.to_owned().creator_id,
858 updated: Some(naive_now()),
861 let _updated_comment = match Comment::update(&conn, comment.id, &comment_form) {
862 Ok(comment) => comment,
863 Err(_e) => return Err(APIError::err("couldnt_update_comment").into()),
868 let posts = PostQueryBuilder::create(&conn)
869 .sort(&SortType::New)
870 .for_creator_id(user_id)
871 .limit(std::i64::MAX)
875 let post_form = PostForm {
876 name: "*Permananently Deleted*".to_string(),
877 url: Some("https://deleted.com".to_string()),
878 body: Some("*Permananently Deleted*".to_string()),
879 creator_id: post.to_owned().creator_id,
880 community_id: post.to_owned().community_id,
883 nsfw: post.to_owned().nsfw,
886 updated: Some(naive_now()),
888 embed_description: None,
893 let _updated_post = match Post::update(&conn, post.id, &post_form) {
895 Err(_e) => return Err(APIError::err("couldnt_update_post").into()),
900 jwt: data.auth.to_owned(),
905 impl Perform<PasswordResetResponse> for Oper<PasswordReset> {
906 fn perform(&self, conn: &PgConnection) -> Result<PasswordResetResponse, Error> {
907 let data: &PasswordReset = &self.data;
910 let user: User_ = match User_::find_by_email(&conn, &data.email) {
912 Err(_e) => return Err(APIError::err("couldnt_find_that_username_or_email").into()),
915 // Generate a random token
916 let token = generate_random_string();
919 PasswordResetRequest::create_token(&conn, user.id, &token)?;
921 // Email the pure token to the user.
922 // TODO no i18n support here.
923 let user_email = &user.email.expect("email");
924 let subject = &format!("Password reset for {}", user.name);
925 let hostname = &format!("https://{}", Settings::get().hostname); //TODO add https for now.
926 let html = &format!("<h1>Password Reset Request for {}</h1><br><a href={}/password_change/{}>Click here to reset your password</a>", user.name, hostname, &token);
927 match send_email(subject, user_email, &user.name, html) {
929 Err(_e) => return Err(APIError::err(&_e).into()),
932 Ok(PasswordResetResponse {})
936 impl Perform<LoginResponse> for Oper<PasswordChange> {
937 fn perform(&self, conn: &PgConnection) -> Result<LoginResponse, Error> {
938 let data: &PasswordChange = &self.data;
940 // Fetch the user_id from the token
941 let user_id = PasswordResetRequest::read_from_token(&conn, &data.token)?.user_id;
943 // Make sure passwords match
944 if data.password != data.password_verify {
945 return Err(APIError::err("passwords_dont_match").into());
948 // Update the user with the new password
949 let updated_user = match User_::update_password(&conn, user_id, &data.password) {
951 Err(_e) => return Err(APIError::err("couldnt_update_user").into()),
956 jwt: updated_user.jwt(),
961 impl Perform<PrivateMessageResponse> for Oper<CreatePrivateMessage> {
962 fn perform(&self, conn: &PgConnection) -> Result<PrivateMessageResponse, Error> {
963 let data: &CreatePrivateMessage = &self.data;
965 let claims = match Claims::decode(&data.auth) {
966 Ok(claims) => claims.claims,
967 Err(_e) => return Err(APIError::err("not_logged_in").into()),
970 let user_id = claims.id;
972 let hostname = &format!("https://{}", Settings::get().hostname);
974 // Check for a site ban
975 if UserView::read(&conn, user_id)?.banned {
976 return Err(APIError::err("site_ban").into());
979 let content_slurs_removed = remove_slurs(&data.content.to_owned());
981 let private_message_form = PrivateMessageForm {
982 content: Some(content_slurs_removed.to_owned()),
984 recipient_id: data.recipient_id,
990 let inserted_private_message = match PrivateMessage::create(&conn, &private_message_form) {
991 Ok(private_message) => private_message,
993 return Err(APIError::err("couldnt_create_private_message").into());
997 // Send notifications to the recipient
998 let recipient_user = User_::read(&conn, data.recipient_id)?;
999 if recipient_user.send_notifications_to_email {
1000 if let Some(email) = recipient_user.email {
1001 let subject = &format!(
1002 "{} - Private Message from {}",
1003 Settings::get().hostname,
1006 let html = &format!(
1007 "<h1>Private Message</h1><br><div>{} - {}</div><br><a href={}/inbox>inbox</a>",
1008 claims.username, &content_slurs_removed, hostname
1010 match send_email(subject, &email, &recipient_user.name, html) {
1012 Err(e) => error!("{}", e),
1017 let message = PrivateMessageView::read(&conn, inserted_private_message.id)?;
1019 Ok(PrivateMessageResponse { message })
1023 impl Perform<PrivateMessageResponse> for Oper<EditPrivateMessage> {
1024 fn perform(&self, conn: &PgConnection) -> Result<PrivateMessageResponse, Error> {
1025 let data: &EditPrivateMessage = &self.data;
1027 let claims = match Claims::decode(&data.auth) {
1028 Ok(claims) => claims.claims,
1029 Err(_e) => return Err(APIError::err("not_logged_in").into()),
1032 let user_id = claims.id;
1034 let orig_private_message = PrivateMessage::read(&conn, data.edit_id)?;
1036 // Check for a site ban
1037 if UserView::read(&conn, user_id)?.banned {
1038 return Err(APIError::err("site_ban").into());
1041 // Check to make sure they are the creator (or the recipient marking as read
1042 if !(data.read.is_some() && orig_private_message.recipient_id.eq(&user_id)
1043 || orig_private_message.creator_id.eq(&user_id))
1045 return Err(APIError::err("no_private_message_edit_allowed").into());
1048 let content_slurs_removed = match &data.content {
1049 Some(content) => Some(remove_slurs(content)),
1053 let private_message_form = PrivateMessageForm {
1054 content: content_slurs_removed,
1055 creator_id: orig_private_message.creator_id,
1056 recipient_id: orig_private_message.recipient_id,
1057 deleted: data.deleted.to_owned(),
1058 read: data.read.to_owned(),
1059 updated: if data.read.is_some() {
1060 orig_private_message.updated
1066 let _updated_private_message =
1067 match PrivateMessage::update(&conn, data.edit_id, &private_message_form) {
1068 Ok(private_message) => private_message,
1069 Err(_e) => return Err(APIError::err("couldnt_update_private_message").into()),
1072 let message = PrivateMessageView::read(&conn, data.edit_id)?;
1074 Ok(PrivateMessageResponse { message })
1078 impl Perform<PrivateMessagesResponse> for Oper<GetPrivateMessages> {
1079 fn perform(&self, conn: &PgConnection) -> Result<PrivateMessagesResponse, Error> {
1080 let data: &GetPrivateMessages = &self.data;
1082 let claims = match Claims::decode(&data.auth) {
1083 Ok(claims) => claims.claims,
1084 Err(_e) => return Err(APIError::err("not_logged_in").into()),
1087 let user_id = claims.id;
1089 let messages = PrivateMessageQueryBuilder::create(&conn, user_id)
1092 .unread_only(data.unread_only)
1095 Ok(PrivateMessagesResponse { messages })
1099 impl Perform<UserJoinResponse> for Oper<UserJoin> {
1100 fn perform(&self, _conn: &PgConnection) -> Result<UserJoinResponse, Error> {
1101 let data: &UserJoin = &self.data;
1103 let claims = match Claims::decode(&data.auth) {
1104 Ok(claims) => claims.claims,
1105 Err(_e) => return Err(APIError::err("not_logged_in").into()),
1108 let user_id = claims.id;
1109 Ok(UserJoinResponse { user_id })