2 use crate::apub::{gen_keypair_str, make_apub_endpoint, EndpointType};
3 use crate::settings::Settings;
4 use crate::{generate_random_string, send_email};
6 use diesel::PgConnection;
10 #[derive(Serialize, Deserialize, Debug)]
12 username_or_email: String,
16 #[derive(Serialize, Deserialize)]
19 pub email: Option<String>,
21 pub password_verify: String,
26 #[derive(Serialize, Deserialize)]
27 pub struct SaveUserSettings {
30 default_sort_type: i16,
31 default_listing_type: i16,
33 avatar: Option<String>,
34 email: Option<String>,
35 matrix_user_id: Option<String>,
36 new_password: Option<String>,
37 new_password_verify: Option<String>,
38 old_password: Option<String>,
40 send_notifications_to_email: bool,
44 #[derive(Serialize, Deserialize)]
45 pub struct LoginResponse {
49 #[derive(Serialize, Deserialize)]
50 pub struct GetUserDetails {
52 username: Option<String>,
56 community_id: Option<i32>,
61 #[derive(Serialize, Deserialize)]
62 pub struct GetUserDetailsResponse {
64 follows: Vec<CommunityFollowerView>,
65 moderates: Vec<CommunityModeratorView>,
66 comments: Vec<CommentView>,
68 admins: Vec<UserView>,
71 #[derive(Serialize, Deserialize)]
72 pub struct GetRepliesResponse {
73 replies: Vec<ReplyView>,
76 #[derive(Serialize, Deserialize)]
77 pub struct GetUserMentionsResponse {
78 mentions: Vec<UserMentionView>,
81 #[derive(Serialize, Deserialize)]
82 pub struct MarkAllAsRead {
86 #[derive(Serialize, Deserialize)]
93 #[derive(Serialize, Deserialize)]
94 pub struct AddAdminResponse {
95 admins: Vec<UserView>,
98 #[derive(Serialize, Deserialize)]
102 reason: Option<String>,
103 expires: Option<i64>,
107 #[derive(Serialize, Deserialize)]
108 pub struct BanUserResponse {
113 #[derive(Serialize, Deserialize)]
114 pub struct GetReplies {
122 #[derive(Serialize, Deserialize)]
123 pub struct GetUserMentions {
131 #[derive(Serialize, Deserialize)]
132 pub struct EditUserMention {
133 user_mention_id: i32,
138 #[derive(Serialize, Deserialize, Clone)]
139 pub struct UserMentionResponse {
140 mention: UserMentionView,
143 #[derive(Serialize, Deserialize)]
144 pub struct DeleteAccount {
149 #[derive(Serialize, Deserialize)]
150 pub struct PasswordReset {
154 #[derive(Serialize, Deserialize, Clone)]
155 pub struct PasswordResetResponse {}
157 #[derive(Serialize, Deserialize)]
158 pub struct PasswordChange {
161 password_verify: String,
164 #[derive(Serialize, Deserialize)]
165 pub struct CreatePrivateMessage {
167 pub recipient_id: i32,
171 #[derive(Serialize, Deserialize)]
172 pub struct EditPrivateMessage {
174 content: Option<String>,
175 deleted: Option<bool>,
180 #[derive(Serialize, Deserialize)]
181 pub struct GetPrivateMessages {
188 #[derive(Serialize, Deserialize, Clone)]
189 pub struct PrivateMessagesResponse {
190 messages: Vec<PrivateMessageView>,
193 #[derive(Serialize, Deserialize, Clone)]
194 pub struct PrivateMessageResponse {
195 message: PrivateMessageView,
198 #[derive(Serialize, Deserialize, Debug)]
199 pub struct UserJoin {
203 #[derive(Serialize, Deserialize, Clone)]
204 pub struct UserJoinResponse {
208 impl Perform<LoginResponse> for Oper<Login> {
209 fn perform(&self, conn: &PgConnection) -> Result<LoginResponse, Error> {
210 let data: &Login = &self.data;
212 // Fetch that username / email
213 let user: User_ = match User_::find_by_email_or_username(&conn, &data.username_or_email) {
215 Err(_e) => return Err(APIError::err("couldnt_find_that_username_or_email").into()),
218 // Verify the password
219 let valid: bool = verify(&data.password, &user.password_encrypted).unwrap_or(false);
221 return Err(APIError::err("password_incorrect").into());
225 Ok(LoginResponse { jwt: user.jwt() })
229 impl Perform<LoginResponse> for Oper<Register> {
230 fn perform(&self, conn: &PgConnection) -> Result<LoginResponse, Error> {
231 let data: &Register = &self.data;
233 // Make sure site has open registration
234 if let Ok(site) = SiteView::read(&conn) {
235 if !site.open_registration {
236 return Err(APIError::err("registration_closed").into());
240 // Make sure passwords match
241 if data.password != data.password_verify {
242 return Err(APIError::err("passwords_dont_match").into());
245 if let Err(slurs) = slur_check(&data.username) {
246 return Err(APIError::err(&slurs_vec_to_str(slurs)).into());
249 // Make sure there are no admins
250 if data.admin && !UserView::admins(&conn)?.is_empty() {
251 return Err(APIError::err("admin_already_created").into());
254 let (user_public_key, user_private_key) = gen_keypair_str();
256 // Register the new user
257 let user_form = UserForm {
258 name: data.username.to_owned(),
259 email: data.email.to_owned(),
260 matrix_user_id: None,
262 password_encrypted: data.password.to_owned(),
263 preferred_username: None,
267 show_nsfw: data.show_nsfw,
268 theme: "darkly".into(),
269 default_sort_type: SortType::Hot as i16,
270 default_listing_type: ListingType::Subscribed as i16,
271 lang: "browser".into(),
273 send_notifications_to_email: false,
274 actor_id: make_apub_endpoint(EndpointType::User, &data.username).to_string(),
277 private_key: Some(user_private_key),
278 public_key: Some(user_public_key),
279 last_refreshed_at: None,
283 let inserted_user = match User_::register(&conn, &user_form) {
286 let err_type = if e.to_string()
287 == "duplicate key value violates unique constraint \"user__email_key\""
289 "email_already_exists"
291 "user_already_exists"
294 return Err(APIError::err(err_type).into());
298 let (community_public_key, community_private_key) = gen_keypair_str();
300 // Create the main community if it doesn't exist
301 let main_community: Community = match Community::read(&conn, 2) {
304 let default_community_name = "main";
305 let community_form = CommunityForm {
306 name: default_community_name.to_string(),
307 title: "The Default Community".to_string(),
308 description: Some("The Default Community".to_string()),
311 creator_id: inserted_user.id,
315 actor_id: make_apub_endpoint(EndpointType::Community, default_community_name).to_string(),
317 private_key: Some(community_private_key),
318 public_key: Some(community_public_key),
319 last_refreshed_at: None,
322 Community::create(&conn, &community_form).unwrap()
326 // Sign them up for main community no matter what
327 let community_follower_form = CommunityFollowerForm {
328 community_id: main_community.id,
329 user_id: inserted_user.id,
332 let _inserted_community_follower =
333 match CommunityFollower::follow(&conn, &community_follower_form) {
335 Err(_e) => return Err(APIError::err("community_follower_already_exists").into()),
338 // If its an admin, add them as a mod and follower to main
340 let community_moderator_form = CommunityModeratorForm {
341 community_id: main_community.id,
342 user_id: inserted_user.id,
345 let _inserted_community_moderator =
346 match CommunityModerator::join(&conn, &community_moderator_form) {
348 Err(_e) => return Err(APIError::err("community_moderator_already_exists").into()),
354 jwt: inserted_user.jwt(),
359 impl Perform<LoginResponse> for Oper<SaveUserSettings> {
360 fn perform(&self, conn: &PgConnection) -> Result<LoginResponse, Error> {
361 let data: &SaveUserSettings = &self.data;
363 let claims = match Claims::decode(&data.auth) {
364 Ok(claims) => claims.claims,
365 Err(_e) => return Err(APIError::err("not_logged_in").into()),
368 let user_id = claims.id;
370 let read_user = User_::read(&conn, user_id)?;
372 let email = match &data.email {
373 Some(email) => Some(email.to_owned()),
374 None => read_user.email,
377 let password_encrypted = match &data.new_password {
378 Some(new_password) => {
379 match &data.new_password_verify {
380 Some(new_password_verify) => {
381 // Make sure passwords match
382 if new_password != new_password_verify {
383 return Err(APIError::err("passwords_dont_match").into());
386 // Check the old password
387 match &data.old_password {
388 Some(old_password) => {
390 verify(old_password, &read_user.password_encrypted).unwrap_or(false);
392 return Err(APIError::err("password_incorrect").into());
394 User_::update_password(&conn, user_id, &new_password)?.password_encrypted
396 None => return Err(APIError::err("password_incorrect").into()),
399 None => return Err(APIError::err("passwords_dont_match").into()),
402 None => read_user.password_encrypted,
405 let user_form = UserForm {
406 name: read_user.name,
408 matrix_user_id: data.matrix_user_id.to_owned(),
409 avatar: data.avatar.to_owned(),
411 preferred_username: read_user.preferred_username,
412 updated: Some(naive_now()),
413 admin: read_user.admin,
414 banned: read_user.banned,
415 show_nsfw: data.show_nsfw,
416 theme: data.theme.to_owned(),
417 default_sort_type: data.default_sort_type,
418 default_listing_type: data.default_listing_type,
419 lang: data.lang.to_owned(),
420 show_avatars: data.show_avatars,
421 send_notifications_to_email: data.send_notifications_to_email,
422 actor_id: read_user.actor_id,
424 local: read_user.local,
425 private_key: read_user.private_key,
426 public_key: read_user.public_key,
427 last_refreshed_at: None,
430 let updated_user = match User_::update(&conn, user_id, &user_form) {
433 let err_type = if e.to_string()
434 == "duplicate key value violates unique constraint \"user__email_key\""
436 "email_already_exists"
438 "user_already_exists"
441 return Err(APIError::err(err_type).into());
447 jwt: updated_user.jwt(),
452 impl Perform<GetUserDetailsResponse> for Oper<GetUserDetails> {
453 fn perform(&self, conn: &PgConnection) -> Result<GetUserDetailsResponse, Error> {
454 let data: &GetUserDetails = &self.data;
456 let user_claims: Option<Claims> = match &data.auth {
457 Some(auth) => match Claims::decode(&auth) {
458 Ok(claims) => Some(claims.claims),
464 let user_id = match &user_claims {
465 Some(claims) => Some(claims.id),
469 let show_nsfw = match &user_claims {
470 Some(claims) => claims.show_nsfw,
474 let sort = SortType::from_str(&data.sort)?;
476 let user_details_id = match data.user_id {
479 match User_::read_from_name(
484 .unwrap_or_else(|| "admin".to_string()),
487 Err(_e) => return Err(APIError::err("couldnt_find_that_username_or_email").into()),
492 let mut user_view = UserView::read(&conn, user_details_id)?;
494 let mut posts_query = PostQueryBuilder::create(&conn)
496 .show_nsfw(show_nsfw)
497 .saved_only(data.saved_only)
498 .for_community_id(data.community_id)
503 let mut comments_query = CommentQueryBuilder::create(&conn)
505 .saved_only(data.saved_only)
510 // If its saved only, you don't care what creator it was
511 // Or, if its not saved, then you only want it for that specific creator
512 if !data.saved_only {
513 posts_query = posts_query.for_creator_id(user_details_id);
514 comments_query = comments_query.for_creator_id(user_details_id);
517 let posts = posts_query.list()?;
518 let comments = comments_query.list()?;
520 let follows = CommunityFollowerView::for_user(&conn, user_details_id)?;
521 let moderates = CommunityModeratorView::for_user(&conn, user_details_id)?;
522 let site_creator_id = Site::read(&conn, 1)?.creator_id;
523 let mut admins = UserView::admins(&conn)?;
524 let creator_index = admins.iter().position(|r| r.id == site_creator_id).unwrap();
525 let creator_user = admins.remove(creator_index);
526 admins.insert(0, creator_user);
528 // If its not the same user, remove the email
529 if let Some(user_id) = user_id {
530 if user_details_id != user_id {
531 user_view.email = None;
534 user_view.email = None;
538 Ok(GetUserDetailsResponse {
549 impl Perform<AddAdminResponse> for Oper<AddAdmin> {
550 fn perform(&self, conn: &PgConnection) -> Result<AddAdminResponse, Error> {
551 let data: &AddAdmin = &self.data;
553 let claims = match Claims::decode(&data.auth) {
554 Ok(claims) => claims.claims,
555 Err(_e) => return Err(APIError::err("not_logged_in").into()),
558 let user_id = claims.id;
560 // Make sure user is an admin
561 if !UserView::read(&conn, user_id)?.admin {
562 return Err(APIError::err("not_an_admin").into());
565 match User_::add_admin(&conn, user_id, data.added) {
567 Err(_e) => return Err(APIError::err("couldnt_update_user").into()),
571 let form = ModAddForm {
572 mod_user_id: user_id,
573 other_user_id: data.user_id,
574 removed: Some(!data.added),
577 ModAdd::create(&conn, &form)?;
579 let site_creator_id = Site::read(&conn, 1)?.creator_id;
580 let mut admins = UserView::admins(&conn)?;
581 let creator_index = admins.iter().position(|r| r.id == site_creator_id).unwrap();
582 let creator_user = admins.remove(creator_index);
583 admins.insert(0, creator_user);
585 Ok(AddAdminResponse { admins })
589 impl Perform<BanUserResponse> for Oper<BanUser> {
590 fn perform(&self, conn: &PgConnection) -> Result<BanUserResponse, Error> {
591 let data: &BanUser = &self.data;
593 let claims = match Claims::decode(&data.auth) {
594 Ok(claims) => claims.claims,
595 Err(_e) => return Err(APIError::err("not_logged_in").into()),
598 let user_id = claims.id;
600 // Make sure user is an admin
601 if !UserView::read(&conn, user_id)?.admin {
602 return Err(APIError::err("not_an_admin").into());
605 match User_::ban_user(&conn, user_id, data.ban) {
607 Err(_e) => return Err(APIError::err("couldnt_update_user").into()),
611 let expires = match data.expires {
612 Some(time) => Some(naive_from_unix(time)),
616 let form = ModBanForm {
617 mod_user_id: user_id,
618 other_user_id: data.user_id,
619 reason: data.reason.to_owned(),
620 banned: Some(data.ban),
624 ModBan::create(&conn, &form)?;
626 let user_view = UserView::read(&conn, data.user_id)?;
635 impl Perform<GetRepliesResponse> for Oper<GetReplies> {
636 fn perform(&self, conn: &PgConnection) -> Result<GetRepliesResponse, Error> {
637 let data: &GetReplies = &self.data;
639 let claims = match Claims::decode(&data.auth) {
640 Ok(claims) => claims.claims,
641 Err(_e) => return Err(APIError::err("not_logged_in").into()),
644 let user_id = claims.id;
646 let sort = SortType::from_str(&data.sort)?;
648 let replies = ReplyQueryBuilder::create(&conn, user_id)
650 .unread_only(data.unread_only)
655 Ok(GetRepliesResponse { replies })
659 impl Perform<GetUserMentionsResponse> for Oper<GetUserMentions> {
660 fn perform(&self, conn: &PgConnection) -> Result<GetUserMentionsResponse, Error> {
661 let data: &GetUserMentions = &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 mentions = UserMentionQueryBuilder::create(&conn, user_id)
674 .unread_only(data.unread_only)
679 Ok(GetUserMentionsResponse { mentions })
683 impl Perform<UserMentionResponse> for Oper<EditUserMention> {
684 fn perform(&self, conn: &PgConnection) -> Result<UserMentionResponse, Error> {
685 let data: &EditUserMention = &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 user_mention = UserMention::read(&conn, data.user_mention_id)?;
696 let user_mention_form = UserMentionForm {
697 recipient_id: user_id,
698 comment_id: user_mention.comment_id,
699 read: data.read.to_owned(),
702 let _updated_user_mention =
703 match UserMention::update(&conn, user_mention.id, &user_mention_form) {
704 Ok(comment) => comment,
705 Err(_e) => return Err(APIError::err("couldnt_update_comment").into()),
708 let user_mention_view = UserMentionView::read(&conn, user_mention.id, user_id)?;
710 Ok(UserMentionResponse {
711 mention: user_mention_view,
716 impl Perform<GetRepliesResponse> for Oper<MarkAllAsRead> {
717 fn perform(&self, conn: &PgConnection) -> Result<GetRepliesResponse, Error> {
718 let data: &MarkAllAsRead = &self.data;
720 let claims = match Claims::decode(&data.auth) {
721 Ok(claims) => claims.claims,
722 Err(_e) => return Err(APIError::err("not_logged_in").into()),
725 let user_id = claims.id;
727 let replies = ReplyQueryBuilder::create(&conn, user_id)
733 for reply in &replies {
734 match Comment::mark_as_read(&conn, reply.id) {
735 Ok(comment) => comment,
736 Err(_e) => return Err(APIError::err("couldnt_update_comment").into()),
741 let mentions = UserMentionQueryBuilder::create(&conn, user_id)
747 for mention in &mentions {
748 let mention_form = UserMentionForm {
749 recipient_id: mention.to_owned().recipient_id,
750 comment_id: mention.to_owned().id,
754 let _updated_mention =
755 match UserMention::update(&conn, mention.user_mention_id, &mention_form) {
756 Ok(mention) => mention,
757 Err(_e) => return Err(APIError::err("couldnt_update_comment").into()),
762 let messages = PrivateMessageQueryBuilder::create(&conn, user_id)
768 for message in &messages {
769 let private_message_form = PrivateMessageForm {
771 creator_id: message.to_owned().creator_id,
772 recipient_id: message.to_owned().recipient_id,
778 let _updated_message = match PrivateMessage::update(&conn, message.id, &private_message_form)
780 Ok(message) => message,
781 Err(_e) => return Err(APIError::err("couldnt_update_private_message").into()),
785 Ok(GetRepliesResponse { replies: vec![] })
789 impl Perform<LoginResponse> for Oper<DeleteAccount> {
790 fn perform(&self, conn: &PgConnection) -> Result<LoginResponse, Error> {
791 let data: &DeleteAccount = &self.data;
793 let claims = match Claims::decode(&data.auth) {
794 Ok(claims) => claims.claims,
795 Err(_e) => return Err(APIError::err("not_logged_in").into()),
798 let user_id = claims.id;
800 let user: User_ = User_::read(&conn, user_id)?;
802 // Verify the password
803 let valid: bool = verify(&data.password, &user.password_encrypted).unwrap_or(false);
805 return Err(APIError::err("password_incorrect").into());
809 let comments = CommentQueryBuilder::create(&conn)
810 .for_creator_id(user_id)
811 .limit(std::i64::MAX)
814 for comment in &comments {
815 let _updated_comment = match Comment::permadelete(&conn, comment.id) {
816 Ok(comment) => comment,
817 Err(_e) => return Err(APIError::err("couldnt_update_comment").into()),
822 let posts = PostQueryBuilder::create(&conn)
823 .sort(&SortType::New)
824 .for_creator_id(user_id)
825 .limit(std::i64::MAX)
829 let _updated_post = match Post::permadelete(&conn, post.id) {
831 Err(_e) => return Err(APIError::err("couldnt_update_post").into()),
836 jwt: data.auth.to_owned(),
841 impl Perform<PasswordResetResponse> for Oper<PasswordReset> {
842 fn perform(&self, conn: &PgConnection) -> Result<PasswordResetResponse, Error> {
843 let data: &PasswordReset = &self.data;
846 let user: User_ = match User_::find_by_email(&conn, &data.email) {
848 Err(_e) => return Err(APIError::err("couldnt_find_that_username_or_email").into()),
851 // Generate a random token
852 let token = generate_random_string();
855 PasswordResetRequest::create_token(&conn, user.id, &token)?;
857 // Email the pure token to the user.
858 // TODO no i18n support here.
859 let user_email = &user.email.expect("email");
860 let subject = &format!("Password reset for {}", user.name);
861 let hostname = &format!("https://{}", Settings::get().hostname); //TODO add https for now.
862 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);
863 match send_email(subject, user_email, &user.name, html) {
865 Err(_e) => return Err(APIError::err(&_e).into()),
868 Ok(PasswordResetResponse {})
872 impl Perform<LoginResponse> for Oper<PasswordChange> {
873 fn perform(&self, conn: &PgConnection) -> Result<LoginResponse, Error> {
874 let data: &PasswordChange = &self.data;
876 // Fetch the user_id from the token
877 let user_id = PasswordResetRequest::read_from_token(&conn, &data.token)?.user_id;
879 // Make sure passwords match
880 if data.password != data.password_verify {
881 return Err(APIError::err("passwords_dont_match").into());
884 // Update the user with the new password
885 let updated_user = match User_::update_password(&conn, user_id, &data.password) {
887 Err(_e) => return Err(APIError::err("couldnt_update_user").into()),
892 jwt: updated_user.jwt(),
897 impl Perform<PrivateMessageResponse> for Oper<CreatePrivateMessage> {
898 fn perform(&self, conn: &PgConnection) -> Result<PrivateMessageResponse, Error> {
899 let data: &CreatePrivateMessage = &self.data;
901 let claims = match Claims::decode(&data.auth) {
902 Ok(claims) => claims.claims,
903 Err(_e) => return Err(APIError::err("not_logged_in").into()),
906 let user_id = claims.id;
908 let hostname = &format!("https://{}", Settings::get().hostname);
910 // Check for a site ban
911 if UserView::read(&conn, user_id)?.banned {
912 return Err(APIError::err("site_ban").into());
915 let content_slurs_removed = remove_slurs(&data.content.to_owned());
917 let private_message_form = PrivateMessageForm {
918 content: Some(content_slurs_removed.to_owned()),
920 recipient_id: data.recipient_id,
926 let inserted_private_message = match PrivateMessage::create(&conn, &private_message_form) {
927 Ok(private_message) => private_message,
929 return Err(APIError::err("couldnt_create_private_message").into());
933 // Send notifications to the recipient
934 let recipient_user = User_::read(&conn, data.recipient_id)?;
935 if recipient_user.send_notifications_to_email {
936 if let Some(email) = recipient_user.email {
937 let subject = &format!(
938 "{} - Private Message from {}",
939 Settings::get().hostname,
943 "<h1>Private Message</h1><br><div>{} - {}</div><br><a href={}/inbox>inbox</a>",
944 claims.username, &content_slurs_removed, hostname
946 match send_email(subject, &email, &recipient_user.name, html) {
948 Err(e) => error!("{}", e),
953 let message = PrivateMessageView::read(&conn, inserted_private_message.id)?;
955 Ok(PrivateMessageResponse { message })
959 impl Perform<PrivateMessageResponse> for Oper<EditPrivateMessage> {
960 fn perform(&self, conn: &PgConnection) -> Result<PrivateMessageResponse, Error> {
961 let data: &EditPrivateMessage = &self.data;
963 let claims = match Claims::decode(&data.auth) {
964 Ok(claims) => claims.claims,
965 Err(_e) => return Err(APIError::err("not_logged_in").into()),
968 let user_id = claims.id;
970 let orig_private_message = PrivateMessage::read(&conn, data.edit_id)?;
972 // Check for a site ban
973 if UserView::read(&conn, user_id)?.banned {
974 return Err(APIError::err("site_ban").into());
977 // Check to make sure they are the creator (or the recipient marking as read
978 if !(data.read.is_some() && orig_private_message.recipient_id.eq(&user_id)
979 || orig_private_message.creator_id.eq(&user_id))
981 return Err(APIError::err("no_private_message_edit_allowed").into());
984 let content_slurs_removed = match &data.content {
985 Some(content) => Some(remove_slurs(content)),
989 let private_message_form = PrivateMessageForm {
990 content: content_slurs_removed,
991 creator_id: orig_private_message.creator_id,
992 recipient_id: orig_private_message.recipient_id,
993 deleted: data.deleted.to_owned(),
994 read: data.read.to_owned(),
995 updated: if data.read.is_some() {
996 orig_private_message.updated
1002 let _updated_private_message =
1003 match PrivateMessage::update(&conn, data.edit_id, &private_message_form) {
1004 Ok(private_message) => private_message,
1005 Err(_e) => return Err(APIError::err("couldnt_update_private_message").into()),
1008 let message = PrivateMessageView::read(&conn, data.edit_id)?;
1010 Ok(PrivateMessageResponse { message })
1014 impl Perform<PrivateMessagesResponse> for Oper<GetPrivateMessages> {
1015 fn perform(&self, conn: &PgConnection) -> Result<PrivateMessagesResponse, Error> {
1016 let data: &GetPrivateMessages = &self.data;
1018 let claims = match Claims::decode(&data.auth) {
1019 Ok(claims) => claims.claims,
1020 Err(_e) => return Err(APIError::err("not_logged_in").into()),
1023 let user_id = claims.id;
1025 let messages = PrivateMessageQueryBuilder::create(&conn, user_id)
1028 .unread_only(data.unread_only)
1031 Ok(PrivateMessagesResponse { messages })
1035 impl Perform<UserJoinResponse> for Oper<UserJoin> {
1036 fn perform(&self, _conn: &PgConnection) -> Result<UserJoinResponse, Error> {
1037 let data: &UserJoin = &self.data;
1039 let claims = match Claims::decode(&data.auth) {
1040 Ok(claims) => claims.claims,
1041 Err(_e) => return Err(APIError::err("not_logged_in").into()),
1044 let user_id = claims.id;
1045 Ok(UserJoinResponse { user_id })