]> Untitled Git - lemmy.git/blob - crates/api_crud/src/user/read.rs
Check user accepted before sending jwt in password reset (fixes #2591) (#2597)
[lemmy.git] / crates / api_crud / src / user / read.rs
1 use crate::PerformCrud;
2 use actix_web::web::Data;
3 use lemmy_api_common::{
4   person::{GetPersonDetails, GetPersonDetailsResponse},
5   utils::{check_private_instance, get_local_user_view_from_jwt_opt},
6 };
7 use lemmy_apub::{fetcher::resolve_actor_identifier, objects::person::ApubPerson};
8 use lemmy_db_schema::{
9   source::{local_site::LocalSite, person::Person},
10   utils::post_to_comment_sort_type,
11 };
12 use lemmy_db_views::{comment_view::CommentQuery, post_view::PostQuery};
13 use lemmy_db_views_actor::structs::{CommunityModeratorView, PersonViewSafe};
14 use lemmy_utils::{error::LemmyError, ConnectionId};
15 use lemmy_websocket::LemmyContext;
16
17 #[async_trait::async_trait(?Send)]
18 impl PerformCrud for GetPersonDetails {
19   type Response = GetPersonDetailsResponse;
20
21   #[tracing::instrument(skip(self, context, _websocket_id))]
22   async fn perform(
23     &self,
24     context: &Data<LemmyContext>,
25     _websocket_id: Option<ConnectionId>,
26   ) -> Result<GetPersonDetailsResponse, LemmyError> {
27     let data: &GetPersonDetails = self;
28
29     // Check to make sure a person name or an id is given
30     if data.username.is_none() && data.person_id.is_none() {
31       return Err(LemmyError::from_message("no_id_given"));
32     }
33
34     let local_user_view =
35       get_local_user_view_from_jwt_opt(data.auth.as_ref(), context.pool(), context.secret())
36         .await?;
37     let local_site = LocalSite::read(context.pool()).await?;
38
39     check_private_instance(&local_user_view, &local_site)?;
40
41     let person_details_id = match data.person_id {
42       Some(id) => id,
43       None => {
44         if let Some(username) = &data.username {
45           resolve_actor_identifier::<ApubPerson, Person>(username, context, true)
46             .await
47             .map_err(|e| e.with_message("couldnt_find_that_username_or_email"))?
48             .id
49         } else {
50           return Err(LemmyError::from_message(
51             "couldnt_find_that_username_or_email",
52           ));
53         }
54       }
55     };
56
57     // You don't need to return settings for the user, since this comes back with GetSite
58     // `my_user`
59     let person_view = PersonViewSafe::read(context.pool(), person_details_id).await?;
60
61     let sort = data.sort;
62     let page = data.page;
63     let limit = data.limit;
64     let saved_only = data.saved_only;
65     let community_id = data.community_id;
66     let local_user = local_user_view.map(|l| l.local_user);
67     let local_user_clone = local_user.clone();
68
69     let posts_query = PostQuery::builder()
70       .pool(context.pool())
71       .sort(sort)
72       .saved_only(saved_only)
73       .local_user(local_user.as_ref())
74       .community_id(community_id)
75       .page(page)
76       .limit(limit);
77
78     // If its saved only, you don't care what creator it was
79     // Or, if its not saved, then you only want it for that specific creator
80     let posts = if !saved_only.unwrap_or(false) {
81       posts_query
82         .creator_id(Some(person_details_id))
83         .build()
84         .list()
85     } else {
86       posts_query.build().list()
87     }
88     .await?;
89
90     let comments_query = CommentQuery::builder()
91       .pool(context.pool())
92       .local_user(local_user_clone.as_ref())
93       .sort(sort.map(post_to_comment_sort_type))
94       .saved_only(saved_only)
95       .show_deleted_and_removed(Some(false))
96       .community_id(community_id)
97       .page(page)
98       .limit(limit);
99
100     // If its saved only, you don't care what creator it was
101     // Or, if its not saved, then you only want it for that specific creator
102     let comments = if !saved_only.unwrap_or(false) {
103       comments_query
104         .creator_id(Some(person_details_id))
105         .build()
106         .list()
107     } else {
108       comments_query.build().list()
109     }
110     .await?;
111
112     let moderates = CommunityModeratorView::for_person(context.pool(), person_details_id).await?;
113
114     // Return the jwt
115     Ok(GetPersonDetailsResponse {
116       person_view,
117       moderates,
118       comments,
119       posts,
120     })
121   }
122 }