2 use crate::settings::Settings;
3 use crate::{generate_random_string, send_email};
5 use diesel::PgConnection;
8 #[derive(Serialize, Deserialize, Debug)]
10 username_or_email: String,
14 #[derive(Serialize, Deserialize)]
17 email: Option<String>,
19 password_verify: String,
24 #[derive(Serialize, Deserialize)]
25 pub struct SaveUserSettings {
28 default_sort_type: i16,
29 default_listing_type: i16,
31 avatar: Option<String>,
32 email: Option<String>,
33 matrix_user_id: Option<String>,
34 new_password: Option<String>,
35 new_password_verify: Option<String>,
36 old_password: Option<String>,
38 send_notifications_to_email: bool,
42 #[derive(Serialize, Deserialize)]
43 pub struct LoginResponse {
47 #[derive(Serialize, Deserialize)]
48 pub struct GetUserDetails {
50 username: Option<String>,
54 community_id: Option<i32>,
59 #[derive(Serialize, Deserialize)]
60 pub struct GetUserDetailsResponse {
62 follows: Vec<CommunityFollowerView>,
63 moderates: Vec<CommunityModeratorView>,
64 comments: Vec<CommentView>,
66 admins: Vec<UserView>,
69 #[derive(Serialize, Deserialize)]
70 pub struct GetRepliesResponse {
71 replies: Vec<ReplyView>,
74 #[derive(Serialize, Deserialize)]
75 pub struct GetUserMentionsResponse {
76 mentions: Vec<UserMentionView>,
79 #[derive(Serialize, Deserialize)]
80 pub struct MarkAllAsRead {
84 #[derive(Serialize, Deserialize)]
91 #[derive(Serialize, Deserialize)]
92 pub struct AddAdminResponse {
93 admins: Vec<UserView>,
96 #[derive(Serialize, Deserialize)]
100 reason: Option<String>,
101 expires: Option<i64>,
105 #[derive(Serialize, Deserialize)]
106 pub struct BanUserResponse {
111 #[derive(Serialize, Deserialize)]
112 pub struct GetReplies {
120 #[derive(Serialize, Deserialize)]
121 pub struct GetUserMentions {
129 #[derive(Serialize, Deserialize)]
130 pub struct EditUserMention {
131 user_mention_id: i32,
136 #[derive(Serialize, Deserialize, Clone)]
137 pub struct UserMentionResponse {
138 mention: UserMentionView,
141 #[derive(Serialize, Deserialize)]
142 pub struct DeleteAccount {
147 #[derive(Serialize, Deserialize)]
148 pub struct PasswordReset {
152 #[derive(Serialize, Deserialize, Clone)]
153 pub struct PasswordResetResponse {}
155 #[derive(Serialize, Deserialize)]
156 pub struct PasswordChange {
159 password_verify: String,
162 #[derive(Serialize, Deserialize)]
163 pub struct CreatePrivateMessage {
165 pub recipient_id: i32,
169 #[derive(Serialize, Deserialize)]
170 pub struct EditPrivateMessage {
172 content: Option<String>,
173 deleted: Option<bool>,
178 #[derive(Serialize, Deserialize)]
179 pub struct GetPrivateMessages {
186 #[derive(Serialize, Deserialize, Clone)]
187 pub struct PrivateMessagesResponse {
188 messages: Vec<PrivateMessageView>,
191 #[derive(Serialize, Deserialize, Clone)]
192 pub struct PrivateMessageResponse {
193 message: PrivateMessageView,
196 #[derive(Serialize, Deserialize, Debug)]
197 pub struct UserJoin {
201 #[derive(Serialize, Deserialize, Clone)]
202 pub struct UserJoinResponse {
206 impl Perform<LoginResponse> for Oper<Login> {
207 fn perform(&self, conn: &PgConnection) -> Result<LoginResponse, Error> {
208 let data: &Login = &self.data;
210 // Fetch that username / email
211 let user: User_ = match User_::find_by_email_or_username(&conn, &data.username_or_email) {
213 Err(_e) => return Err(APIError::err("couldnt_find_that_username_or_email").into()),
216 // Verify the password
217 let valid: bool = verify(&data.password, &user.password_encrypted).unwrap_or(false);
219 return Err(APIError::err("password_incorrect").into());
223 Ok(LoginResponse { jwt: user.jwt() })
227 impl Perform<LoginResponse> for Oper<Register> {
228 fn perform(&self, conn: &PgConnection) -> Result<LoginResponse, Error> {
229 let data: &Register = &self.data;
231 // Make sure site has open registration
232 if let Ok(site) = SiteView::read(&conn) {
233 if !site.open_registration {
234 return Err(APIError::err("registration_closed").into());
238 // Make sure passwords match
239 if data.password != data.password_verify {
240 return Err(APIError::err("passwords_dont_match").into());
243 if let Err(slurs) = slur_check(&data.username) {
244 return Err(APIError::err(&slurs_vec_to_str(slurs)).into());
247 // Make sure there are no admins
248 if data.admin && !UserView::admins(&conn)?.is_empty() {
249 return Err(APIError::err("admin_already_created").into());
252 // Register the new user
253 let user_form = UserForm {
254 name: data.username.to_owned(),
255 fedi_name: Settings::get().hostname.to_owned(),
256 email: data.email.to_owned(),
257 matrix_user_id: None,
259 password_encrypted: data.password.to_owned(),
260 preferred_username: None,
264 show_nsfw: data.show_nsfw,
265 theme: "darkly".into(),
266 default_sort_type: SortType::Hot as i16,
267 default_listing_type: ListingType::Subscribed as i16,
268 lang: "browser".into(),
270 send_notifications_to_email: false,
274 let inserted_user = match User_::register(&conn, &user_form) {
277 let err_type = if e.to_string()
278 == "duplicate key value violates unique constraint \"user__email_key\""
280 "email_already_exists"
282 "user_already_exists"
285 return Err(APIError::err(err_type).into());
289 // Create the main community if it doesn't exist
290 let main_community: Community = match Community::read(&conn, 2) {
293 let community_form = CommunityForm {
294 name: "main".to_string(),
295 title: "The Default Community".to_string(),
296 description: Some("The Default Community".to_string()),
299 creator_id: inserted_user.id,
304 Community::create(&conn, &community_form).unwrap()
308 // Sign them up for main community no matter what
309 let community_follower_form = CommunityFollowerForm {
310 community_id: main_community.id,
311 user_id: inserted_user.id,
314 let _inserted_community_follower =
315 match CommunityFollower::follow(&conn, &community_follower_form) {
317 Err(_e) => return Err(APIError::err("community_follower_already_exists").into()),
320 // If its an admin, add them as a mod and follower to main
322 let community_moderator_form = CommunityModeratorForm {
323 community_id: main_community.id,
324 user_id: inserted_user.id,
327 let _inserted_community_moderator =
328 match CommunityModerator::join(&conn, &community_moderator_form) {
330 Err(_e) => return Err(APIError::err("community_moderator_already_exists").into()),
336 jwt: inserted_user.jwt(),
341 impl Perform<LoginResponse> for Oper<SaveUserSettings> {
342 fn perform(&self, conn: &PgConnection) -> Result<LoginResponse, Error> {
343 let data: &SaveUserSettings = &self.data;
345 let claims = match Claims::decode(&data.auth) {
346 Ok(claims) => claims.claims,
347 Err(_e) => return Err(APIError::err("not_logged_in").into()),
350 let user_id = claims.id;
352 let read_user = User_::read(&conn, user_id)?;
354 let email = match &data.email {
355 Some(email) => Some(email.to_owned()),
356 None => read_user.email,
359 let password_encrypted = match &data.new_password {
360 Some(new_password) => {
361 match &data.new_password_verify {
362 Some(new_password_verify) => {
363 // Make sure passwords match
364 if new_password != new_password_verify {
365 return Err(APIError::err("passwords_dont_match").into());
368 // Check the old password
369 match &data.old_password {
370 Some(old_password) => {
372 verify(old_password, &read_user.password_encrypted).unwrap_or(false);
374 return Err(APIError::err("password_incorrect").into());
376 User_::update_password(&conn, user_id, &new_password)?.password_encrypted
378 None => return Err(APIError::err("password_incorrect").into()),
381 None => return Err(APIError::err("passwords_dont_match").into()),
384 None => read_user.password_encrypted,
387 let user_form = UserForm {
388 name: read_user.name,
389 fedi_name: read_user.fedi_name,
391 matrix_user_id: data.matrix_user_id.to_owned(),
392 avatar: data.avatar.to_owned(),
394 preferred_username: read_user.preferred_username,
395 updated: Some(naive_now()),
396 admin: read_user.admin,
397 banned: read_user.banned,
398 show_nsfw: data.show_nsfw,
399 theme: data.theme.to_owned(),
400 default_sort_type: data.default_sort_type,
401 default_listing_type: data.default_listing_type,
402 lang: data.lang.to_owned(),
403 show_avatars: data.show_avatars,
404 send_notifications_to_email: data.send_notifications_to_email,
407 let updated_user = match User_::update(&conn, user_id, &user_form) {
410 let err_type = if e.to_string()
411 == "duplicate key value violates unique constraint \"user__email_key\""
413 "email_already_exists"
415 "user_already_exists"
418 return Err(APIError::err(err_type).into());
424 jwt: updated_user.jwt(),
429 impl Perform<GetUserDetailsResponse> for Oper<GetUserDetails> {
430 fn perform(&self, conn: &PgConnection) -> Result<GetUserDetailsResponse, Error> {
431 let data: &GetUserDetails = &self.data;
433 let user_claims: Option<Claims> = match &data.auth {
434 Some(auth) => match Claims::decode(&auth) {
435 Ok(claims) => Some(claims.claims),
441 let user_id = match &user_claims {
442 Some(claims) => Some(claims.id),
446 let show_nsfw = match &user_claims {
447 Some(claims) => claims.show_nsfw,
451 let sort = SortType::from_str(&data.sort)?;
453 let user_details_id = match data.user_id {
456 match User_::read_from_name(
461 .unwrap_or_else(|| "admin".to_string()),
464 Err(_e) => return Err(APIError::err("couldnt_find_that_username_or_email").into()),
469 let user_view = UserView::read(&conn, user_details_id)?;
471 let mut posts_query = PostQueryBuilder::create(&conn)
473 .show_nsfw(show_nsfw)
474 .saved_only(data.saved_only)
475 .for_community_id(data.community_id)
480 let mut comments_query = CommentQueryBuilder::create(&conn)
482 .saved_only(data.saved_only)
487 // If its saved only, you don't care what creator it was
488 // Or, if its not saved, then you only want it for that specific creator
489 if !data.saved_only {
490 posts_query = posts_query.for_creator_id(user_details_id);
491 comments_query = comments_query.for_creator_id(user_details_id);
494 let posts = posts_query.list()?;
495 let comments = comments_query.list()?;
497 let follows = CommunityFollowerView::for_user(&conn, user_details_id)?;
498 let moderates = CommunityModeratorView::for_user(&conn, user_details_id)?;
499 let site_creator_id = Site::read(&conn, 1)?.creator_id;
500 let mut admins = UserView::admins(&conn)?;
501 let creator_index = admins.iter().position(|r| r.id == site_creator_id).unwrap();
502 let creator_user = admins.remove(creator_index);
503 admins.insert(0, creator_user);
506 Ok(GetUserDetailsResponse {
517 impl Perform<AddAdminResponse> for Oper<AddAdmin> {
518 fn perform(&self, conn: &PgConnection) -> Result<AddAdminResponse, Error> {
519 let data: &AddAdmin = &self.data;
521 let claims = match Claims::decode(&data.auth) {
522 Ok(claims) => claims.claims,
523 Err(_e) => return Err(APIError::err("not_logged_in").into()),
526 let user_id = claims.id;
528 // Make sure user is an admin
529 if !UserView::read(&conn, user_id)?.admin {
530 return Err(APIError::err("not_an_admin").into());
533 let read_user = User_::read(&conn, data.user_id)?;
535 // TODO make addadmin easier
536 let user_form = UserForm {
537 name: read_user.name,
538 fedi_name: read_user.fedi_name,
539 email: read_user.email,
540 matrix_user_id: read_user.matrix_user_id,
541 avatar: read_user.avatar,
542 password_encrypted: read_user.password_encrypted,
543 preferred_username: read_user.preferred_username,
544 updated: Some(naive_now()),
546 banned: read_user.banned,
547 show_nsfw: read_user.show_nsfw,
548 theme: read_user.theme,
549 default_sort_type: read_user.default_sort_type,
550 default_listing_type: read_user.default_listing_type,
551 lang: read_user.lang,
552 show_avatars: read_user.show_avatars,
553 send_notifications_to_email: read_user.send_notifications_to_email,
556 match User_::update(&conn, data.user_id, &user_form) {
558 Err(_e) => return Err(APIError::err("couldnt_update_user").into()),
562 let form = ModAddForm {
563 mod_user_id: user_id,
564 other_user_id: data.user_id,
565 removed: Some(!data.added),
568 ModAdd::create(&conn, &form)?;
570 let site_creator_id = Site::read(&conn, 1)?.creator_id;
571 let mut admins = UserView::admins(&conn)?;
572 let creator_index = admins.iter().position(|r| r.id == site_creator_id).unwrap();
573 let creator_user = admins.remove(creator_index);
574 admins.insert(0, creator_user);
576 Ok(AddAdminResponse { admins })
580 impl Perform<BanUserResponse> for Oper<BanUser> {
581 fn perform(&self, conn: &PgConnection) -> Result<BanUserResponse, Error> {
582 let data: &BanUser = &self.data;
584 let claims = match Claims::decode(&data.auth) {
585 Ok(claims) => claims.claims,
586 Err(_e) => return Err(APIError::err("not_logged_in").into()),
589 let user_id = claims.id;
591 // Make sure user is an admin
592 if !UserView::read(&conn, user_id)?.admin {
593 return Err(APIError::err("not_an_admin").into());
596 let read_user = User_::read(&conn, data.user_id)?;
598 // TODO make bans and addadmins easier
599 let user_form = UserForm {
600 name: read_user.name,
601 fedi_name: read_user.fedi_name,
602 email: read_user.email,
603 matrix_user_id: read_user.matrix_user_id,
604 avatar: read_user.avatar,
605 password_encrypted: read_user.password_encrypted,
606 preferred_username: read_user.preferred_username,
607 updated: Some(naive_now()),
608 admin: read_user.admin,
610 show_nsfw: read_user.show_nsfw,
611 theme: read_user.theme,
612 default_sort_type: read_user.default_sort_type,
613 default_listing_type: read_user.default_listing_type,
614 lang: read_user.lang,
615 show_avatars: read_user.show_avatars,
616 send_notifications_to_email: read_user.send_notifications_to_email,
619 match User_::update(&conn, data.user_id, &user_form) {
621 Err(_e) => return Err(APIError::err("couldnt_update_user").into()),
625 let expires = match data.expires {
626 Some(time) => Some(naive_from_unix(time)),
630 let form = ModBanForm {
631 mod_user_id: user_id,
632 other_user_id: data.user_id,
633 reason: data.reason.to_owned(),
634 banned: Some(data.ban),
638 ModBan::create(&conn, &form)?;
640 let user_view = UserView::read(&conn, data.user_id)?;
649 impl Perform<GetRepliesResponse> for Oper<GetReplies> {
650 fn perform(&self, conn: &PgConnection) -> Result<GetRepliesResponse, Error> {
651 let data: &GetReplies = &self.data;
653 let claims = match Claims::decode(&data.auth) {
654 Ok(claims) => claims.claims,
655 Err(_e) => return Err(APIError::err("not_logged_in").into()),
658 let user_id = claims.id;
660 let sort = SortType::from_str(&data.sort)?;
662 let replies = ReplyQueryBuilder::create(&conn, user_id)
664 .unread_only(data.unread_only)
669 Ok(GetRepliesResponse { replies })
673 impl Perform<GetUserMentionsResponse> for Oper<GetUserMentions> {
674 fn perform(&self, conn: &PgConnection) -> Result<GetUserMentionsResponse, Error> {
675 let data: &GetUserMentions = &self.data;
677 let claims = match Claims::decode(&data.auth) {
678 Ok(claims) => claims.claims,
679 Err(_e) => return Err(APIError::err("not_logged_in").into()),
682 let user_id = claims.id;
684 let sort = SortType::from_str(&data.sort)?;
686 let mentions = UserMentionQueryBuilder::create(&conn, user_id)
688 .unread_only(data.unread_only)
693 Ok(GetUserMentionsResponse { mentions })
697 impl Perform<UserMentionResponse> for Oper<EditUserMention> {
698 fn perform(&self, conn: &PgConnection) -> Result<UserMentionResponse, Error> {
699 let data: &EditUserMention = &self.data;
701 let claims = match Claims::decode(&data.auth) {
702 Ok(claims) => claims.claims,
703 Err(_e) => return Err(APIError::err("not_logged_in").into()),
706 let user_id = claims.id;
708 let user_mention = UserMention::read(&conn, data.user_mention_id)?;
710 let user_mention_form = UserMentionForm {
711 recipient_id: user_id,
712 comment_id: user_mention.comment_id,
713 read: data.read.to_owned(),
716 let _updated_user_mention =
717 match UserMention::update(&conn, user_mention.id, &user_mention_form) {
718 Ok(comment) => comment,
719 Err(_e) => return Err(APIError::err("couldnt_update_comment").into()),
722 let user_mention_view = UserMentionView::read(&conn, user_mention.id, user_id)?;
724 Ok(UserMentionResponse {
725 mention: user_mention_view,
730 impl Perform<GetRepliesResponse> for Oper<MarkAllAsRead> {
731 fn perform(&self, conn: &PgConnection) -> Result<GetRepliesResponse, Error> {
732 let data: &MarkAllAsRead = &self.data;
734 let claims = match Claims::decode(&data.auth) {
735 Ok(claims) => claims.claims,
736 Err(_e) => return Err(APIError::err("not_logged_in").into()),
739 let user_id = claims.id;
741 let replies = ReplyQueryBuilder::create(&conn, user_id)
747 for reply in &replies {
748 let comment_form = CommentForm {
749 content: reply.to_owned().content,
750 parent_id: reply.to_owned().parent_id,
751 post_id: reply.to_owned().post_id,
752 creator_id: reply.to_owned().creator_id,
756 updated: reply.to_owned().updated,
759 let _updated_comment = match Comment::update(&conn, reply.id, &comment_form) {
760 Ok(comment) => comment,
761 Err(_e) => return Err(APIError::err("couldnt_update_comment").into()),
766 let mentions = UserMentionQueryBuilder::create(&conn, user_id)
772 for mention in &mentions {
773 let mention_form = UserMentionForm {
774 recipient_id: mention.to_owned().recipient_id,
775 comment_id: mention.to_owned().id,
779 let _updated_mention =
780 match UserMention::update(&conn, mention.user_mention_id, &mention_form) {
781 Ok(mention) => mention,
782 Err(_e) => return Err(APIError::err("couldnt_update_comment").into()),
787 let messages = PrivateMessageQueryBuilder::create(&conn, user_id)
793 for message in &messages {
794 let private_message_form = PrivateMessageForm {
796 creator_id: message.to_owned().creator_id,
797 recipient_id: message.to_owned().recipient_id,
803 let _updated_message = match PrivateMessage::update(&conn, message.id, &private_message_form)
805 Ok(message) => message,
806 Err(_e) => return Err(APIError::err("couldnt_update_private_message").into()),
810 Ok(GetRepliesResponse { replies: vec![] })
814 impl Perform<LoginResponse> for Oper<DeleteAccount> {
815 fn perform(&self, conn: &PgConnection) -> Result<LoginResponse, Error> {
816 let data: &DeleteAccount = &self.data;
818 let claims = match Claims::decode(&data.auth) {
819 Ok(claims) => claims.claims,
820 Err(_e) => return Err(APIError::err("not_logged_in").into()),
823 let user_id = claims.id;
825 let user: User_ = User_::read(&conn, user_id)?;
827 // Verify the password
828 let valid: bool = verify(&data.password, &user.password_encrypted).unwrap_or(false);
830 return Err(APIError::err("password_incorrect").into());
834 let comments = CommentQueryBuilder::create(&conn)
835 .for_creator_id(user_id)
836 .limit(std::i64::MAX)
839 for comment in &comments {
840 let comment_form = CommentForm {
841 content: "*Permananently Deleted*".to_string(),
842 parent_id: comment.to_owned().parent_id,
843 post_id: comment.to_owned().post_id,
844 creator_id: comment.to_owned().creator_id,
848 updated: Some(naive_now()),
851 let _updated_comment = match Comment::update(&conn, comment.id, &comment_form) {
852 Ok(comment) => comment,
853 Err(_e) => return Err(APIError::err("couldnt_update_comment").into()),
858 let posts = PostQueryBuilder::create(&conn)
859 .sort(&SortType::New)
860 .for_creator_id(user_id)
861 .limit(std::i64::MAX)
865 let post_form = PostForm {
866 name: "*Permananently Deleted*".to_string(),
867 url: Some("https://deleted.com".to_string()),
868 body: Some("*Permananently Deleted*".to_string()),
869 creator_id: post.to_owned().creator_id,
870 community_id: post.to_owned().community_id,
873 nsfw: post.to_owned().nsfw,
876 updated: Some(naive_now()),
879 let _updated_post = match Post::update(&conn, post.id, &post_form) {
881 Err(_e) => return Err(APIError::err("couldnt_update_post").into()),
886 jwt: data.auth.to_owned(),
891 impl Perform<PasswordResetResponse> for Oper<PasswordReset> {
892 fn perform(&self, conn: &PgConnection) -> Result<PasswordResetResponse, Error> {
893 let data: &PasswordReset = &self.data;
896 let user: User_ = match User_::find_by_email(&conn, &data.email) {
898 Err(_e) => return Err(APIError::err("couldnt_find_that_username_or_email").into()),
901 // Generate a random token
902 let token = generate_random_string();
905 PasswordResetRequest::create_token(&conn, user.id, &token)?;
907 // Email the pure token to the user.
908 // TODO no i18n support here.
909 let user_email = &user.email.expect("email");
910 let subject = &format!("Password reset for {}", user.name);
911 let hostname = &format!("https://{}", Settings::get().hostname); //TODO add https for now.
912 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);
913 match send_email(subject, user_email, &user.name, html) {
915 Err(_e) => return Err(APIError::err(&_e).into()),
918 Ok(PasswordResetResponse {})
922 impl Perform<LoginResponse> for Oper<PasswordChange> {
923 fn perform(&self, conn: &PgConnection) -> Result<LoginResponse, Error> {
924 let data: &PasswordChange = &self.data;
926 // Fetch the user_id from the token
927 let user_id = PasswordResetRequest::read_from_token(&conn, &data.token)?.user_id;
929 // Make sure passwords match
930 if data.password != data.password_verify {
931 return Err(APIError::err("passwords_dont_match").into());
934 // Update the user with the new password
935 let updated_user = match User_::update_password(&conn, user_id, &data.password) {
937 Err(_e) => return Err(APIError::err("couldnt_update_user").into()),
942 jwt: updated_user.jwt(),
947 impl Perform<PrivateMessageResponse> for Oper<CreatePrivateMessage> {
948 fn perform(&self, conn: &PgConnection) -> Result<PrivateMessageResponse, Error> {
949 let data: &CreatePrivateMessage = &self.data;
951 let claims = match Claims::decode(&data.auth) {
952 Ok(claims) => claims.claims,
953 Err(_e) => return Err(APIError::err("not_logged_in").into()),
956 let user_id = claims.id;
958 let hostname = &format!("https://{}", Settings::get().hostname);
960 // Check for a site ban
961 if UserView::read(&conn, user_id)?.banned {
962 return Err(APIError::err("site_ban").into());
965 let content_slurs_removed = remove_slurs(&data.content.to_owned());
967 let private_message_form = PrivateMessageForm {
968 content: Some(content_slurs_removed.to_owned()),
970 recipient_id: data.recipient_id,
976 let inserted_private_message = match PrivateMessage::create(&conn, &private_message_form) {
977 Ok(private_message) => private_message,
979 return Err(APIError::err("couldnt_create_private_message").into());
983 // Send notifications to the recipient
984 let recipient_user = User_::read(&conn, data.recipient_id)?;
985 if recipient_user.send_notifications_to_email {
986 if let Some(email) = recipient_user.email {
987 let subject = &format!(
988 "{} - Private Message from {}",
989 Settings::get().hostname,
993 "<h1>Private Message</h1><br><div>{} - {}</div><br><a href={}/inbox>inbox</a>",
994 claims.username, &content_slurs_removed, hostname
996 match send_email(subject, &email, &recipient_user.name, html) {
998 Err(e) => eprintln!("{}", e),
1003 let message = PrivateMessageView::read(&conn, inserted_private_message.id)?;
1005 Ok(PrivateMessageResponse { message })
1009 impl Perform<PrivateMessageResponse> for Oper<EditPrivateMessage> {
1010 fn perform(&self, conn: &PgConnection) -> Result<PrivateMessageResponse, Error> {
1011 let data: &EditPrivateMessage = &self.data;
1013 let claims = match Claims::decode(&data.auth) {
1014 Ok(claims) => claims.claims,
1015 Err(_e) => return Err(APIError::err("not_logged_in").into()),
1018 let user_id = claims.id;
1020 let orig_private_message = PrivateMessage::read(&conn, data.edit_id)?;
1022 // Check for a site ban
1023 if UserView::read(&conn, user_id)?.banned {
1024 return Err(APIError::err("site_ban").into());
1027 // Check to make sure they are the creator (or the recipient marking as read
1028 if !(data.read.is_some() && orig_private_message.recipient_id.eq(&user_id)
1029 || orig_private_message.creator_id.eq(&user_id))
1031 return Err(APIError::err("no_private_message_edit_allowed").into());
1034 let content_slurs_removed = match &data.content {
1035 Some(content) => Some(remove_slurs(content)),
1039 let private_message_form = PrivateMessageForm {
1040 content: content_slurs_removed,
1041 creator_id: orig_private_message.creator_id,
1042 recipient_id: orig_private_message.recipient_id,
1043 deleted: data.deleted.to_owned(),
1044 read: data.read.to_owned(),
1045 updated: if data.read.is_some() {
1046 orig_private_message.updated
1052 let _updated_private_message =
1053 match PrivateMessage::update(&conn, data.edit_id, &private_message_form) {
1054 Ok(private_message) => private_message,
1055 Err(_e) => return Err(APIError::err("couldnt_update_private_message").into()),
1058 let message = PrivateMessageView::read(&conn, data.edit_id)?;
1060 Ok(PrivateMessageResponse { message })
1064 impl Perform<PrivateMessagesResponse> for Oper<GetPrivateMessages> {
1065 fn perform(&self, conn: &PgConnection) -> Result<PrivateMessagesResponse, Error> {
1066 let data: &GetPrivateMessages = &self.data;
1068 let claims = match Claims::decode(&data.auth) {
1069 Ok(claims) => claims.claims,
1070 Err(_e) => return Err(APIError::err("not_logged_in").into()),
1073 let user_id = claims.id;
1075 let messages = PrivateMessageQueryBuilder::create(&conn, user_id)
1078 .unread_only(data.unread_only)
1081 Ok(PrivateMessagesResponse { messages })
1085 impl Perform<UserJoinResponse> for Oper<UserJoin> {
1086 fn perform(&self, _conn: &PgConnection) -> Result<UserJoinResponse, Error> {
1087 let data: &UserJoin = &self.data;
1089 let claims = match Claims::decode(&data.auth) {
1090 Ok(claims) => claims.claims,
1091 Err(_e) => return Err(APIError::err("not_logged_in").into()),
1094 let user_id = claims.id;
1095 Ok(UserJoinResponse { user_id })