]> Untitled Git - lemmy.git/blob - crates/apub/src/api/resolve_object.rs
Replace Option<bool> with bool for PostQuery and CommentQuery (#3819) (#3857)
[lemmy.git] / crates / apub / src / api / resolve_object.rs
1 use crate::fetcher::search::{
2   search_query_to_object_id,
3   search_query_to_object_id_local,
4   SearchableObjects,
5 };
6 use activitypub_federation::config::Data;
7 use actix_web::web::{Json, Query};
8 use diesel::NotFound;
9 use lemmy_api_common::{
10   context::LemmyContext,
11   site::{ResolveObject, ResolveObjectResponse},
12   utils::{check_private_instance, local_user_view_from_jwt_opt},
13 };
14 use lemmy_db_schema::{newtypes::PersonId, source::local_site::LocalSite, utils::DbPool};
15 use lemmy_db_views::structs::{CommentView, PostView};
16 use lemmy_db_views_actor::structs::{CommunityView, PersonView};
17 use lemmy_utils::error::{LemmyError, LemmyErrorExt2, LemmyErrorType};
18
19 #[tracing::instrument(skip(context))]
20 pub async fn resolve_object(
21   data: Query<ResolveObject>,
22   context: Data<LemmyContext>,
23 ) -> Result<Json<ResolveObjectResponse>, LemmyError> {
24   let local_user_view = local_user_view_from_jwt_opt(data.auth.as_ref(), &context).await;
25   let local_site = LocalSite::read(&mut context.pool()).await?;
26   check_private_instance(&local_user_view, &local_site)?;
27   let person_id = local_user_view.map(|v| v.person.id);
28   // If we get a valid personId back we can safely assume that the user is authenticated,
29   // if there's no personId then the JWT was missing or invalid.
30   let is_authenticated = person_id.is_some();
31
32   let res = if is_authenticated {
33     // user is fully authenticated; allow remote lookups as well.
34     search_query_to_object_id(&data.q, &context).await
35   } else {
36     // user isn't authenticated only allow a local search.
37     search_query_to_object_id_local(&data.q, &context).await
38   }
39   .with_lemmy_type(LemmyErrorType::CouldntFindObject)?;
40
41   convert_response(res, person_id, &mut context.pool())
42     .await
43     .with_lemmy_type(LemmyErrorType::CouldntFindObject)
44 }
45
46 async fn convert_response(
47   object: SearchableObjects,
48   user_id: Option<PersonId>,
49   pool: &mut DbPool<'_>,
50 ) -> Result<Json<ResolveObjectResponse>, LemmyError> {
51   use SearchableObjects::*;
52   let removed_or_deleted;
53   let mut res = ResolveObjectResponse::default();
54   match object {
55     Person(p) => {
56       removed_or_deleted = p.deleted;
57       res.person = Some(PersonView::read(pool, p.id).await?)
58     }
59     Community(c) => {
60       removed_or_deleted = c.deleted || c.removed;
61       res.community = Some(CommunityView::read(pool, c.id, user_id, false).await?)
62     }
63     Post(p) => {
64       removed_or_deleted = p.deleted || p.removed;
65       res.post = Some(PostView::read(pool, p.id, user_id, false).await?)
66     }
67     Comment(c) => {
68       removed_or_deleted = c.deleted || c.removed;
69       res.comment = Some(CommentView::read(pool, c.id, user_id).await?)
70     }
71   };
72   // if the object was deleted from database, dont return it
73   if removed_or_deleted {
74     return Err(NotFound {}.into());
75   }
76   Ok(Json(res))
77 }