X-Git-Url: http://these/git/?a=blobdiff_plain;f=crates%2Fapub%2Fsrc%2Fapi%2Fresolve_object.rs;h=f5a703c9927999a76a1718428bcc82a17f0ab8a2;hb=c8063f3267cf2b3622f1fdc69128c6b55feefbbc;hp=c4fb2e9b8c0a236e006233747ee4d93e575a777c;hpb=eb78af9b02a05a65aa56748a947c13ca1560ba89;p=lemmy.git diff --git a/crates/apub/src/api/resolve_object.rs b/crates/apub/src/api/resolve_object.rs index c4fb2e9b..f5a703c9 100644 --- a/crates/apub/src/api/resolve_object.rs +++ b/crates/apub/src/api/resolve_object.rs @@ -1,66 +1,68 @@ -use crate::{ - api::PerformApub, - fetcher::search::{search_query_to_object_id, SearchableObjects}, +use crate::fetcher::search::{ + search_query_to_object_id, + search_query_to_object_id_local, + SearchableObjects, }; -use actix_web::web::Data; +use activitypub_federation::config::Data; +use actix_web::web::{Json, Query}; use diesel::NotFound; use lemmy_api_common::{ context::LemmyContext, site::{ResolveObject, ResolveObjectResponse}, - utils::{check_private_instance, get_local_user_view_from_jwt_opt}, + utils::{check_private_instance, local_user_view_from_jwt_opt}, }; use lemmy_db_schema::{newtypes::PersonId, source::local_site::LocalSite, utils::DbPool}; use lemmy_db_views::structs::{CommentView, PostView}; -use lemmy_db_views_actor::structs::{CommunityView, PersonViewSafe}; -use lemmy_utils::{error::LemmyError, ConnectionId}; +use lemmy_db_views_actor::structs::{CommunityView, PersonView}; +use lemmy_utils::error::{LemmyError, LemmyErrorExt2, LemmyErrorType}; -#[async_trait::async_trait(?Send)] -impl PerformApub for ResolveObject { - type Response = ResolveObjectResponse; +#[tracing::instrument(skip(context))] +pub async fn resolve_object( + data: Query, + context: Data, +) -> Result, LemmyError> { + let local_user_view = local_user_view_from_jwt_opt(data.auth.as_ref(), &context).await; + let local_site = LocalSite::read(&mut context.pool()).await?; + check_private_instance(&local_user_view, &local_site)?; + let person_id = local_user_view.map(|v| v.person.id); + // If we get a valid personId back we can safely assume that the user is authenticated, + // if there's no personId then the JWT was missing or invalid. + let is_authenticated = person_id.is_some(); - #[tracing::instrument(skip(context, _websocket_id))] - async fn perform( - &self, - context: &Data, - _websocket_id: Option, - ) -> Result { - let local_user_view = - get_local_user_view_from_jwt_opt(self.auth.as_ref(), context.pool(), context.secret()) - .await?; - let local_site = LocalSite::read(context.pool()).await?; - check_private_instance(&local_user_view, &local_site)?; - - // In release builds only allow for authenticated users to fetch remote objects - let local_only = local_user_view.is_none() && cfg!(not(debug_assertions)); - let res = search_query_to_object_id(&self.q, local_only, context) - .await - .map_err(|e| e.with_message("couldnt_find_object"))?; - convert_response(res, local_user_view.map(|l| l.person.id), context.pool()) - .await - .map_err(|e| e.with_message("couldnt_find_object")) + let res = if is_authenticated { + // user is fully authenticated; allow remote lookups as well. + search_query_to_object_id(&data.q, &context).await + } else { + // user isn't authenticated only allow a local search. + search_query_to_object_id_local(&data.q, &context).await } + .with_lemmy_type(LemmyErrorType::CouldntFindObject)?; + + convert_response(res, person_id, &mut context.pool()) + .await + .with_lemmy_type(LemmyErrorType::CouldntFindObject) } async fn convert_response( object: SearchableObjects, user_id: Option, - pool: &DbPool, -) -> Result { + pool: &mut DbPool<'_>, +) -> Result, LemmyError> { use SearchableObjects::*; let removed_or_deleted; let mut res = ResolveObjectResponse::default(); match object { Person(p) => { removed_or_deleted = p.deleted; - res.person = Some(PersonViewSafe::read(pool, p.id).await?) + res.person = Some(PersonView::read(pool, p.id).await?) } Community(c) => { removed_or_deleted = c.deleted || c.removed; - res.community = Some(CommunityView::read(pool, c.id, user_id).await?) + res.community = Some(CommunityView::read(pool, c.id, user_id, false).await?) } Post(p) => { removed_or_deleted = p.deleted || p.removed; - res.post = Some(PostView::read(pool, p.id, user_id).await?) + res.post = Some(PostView::read(pool, p.id, user_id, false).await?) } Comment(c) => { removed_or_deleted = c.deleted || c.removed; @@ -71,5 +73,5 @@ async fn convert_response( if removed_or_deleted { return Err(NotFound {}.into()); } - Ok(res) + Ok(Json(res)) }