X-Git-Url: http://these/git/?a=blobdiff_plain;f=crates%2Fapub%2Fsrc%2Fapi%2Fresolve_object.rs;h=f5a703c9927999a76a1718428bcc82a17f0ab8a2;hb=c8063f3267cf2b3622f1fdc69128c6b55feefbbc;hp=951cd45516a2fdc7b8a2cb5457109ab645f7325b;hpb=3565ad984a0270c7dd29051a9ff6d15fc5a8ed47;p=lemmy.git diff --git a/crates/apub/src/api/resolve_object.rs b/crates/apub/src/api/resolve_object.rs index 951cd455..f5a703c9 100644 --- a/crates/apub/src/api/resolve_object.rs +++ b/crates/apub/src/api/resolve_object.rs @@ -1,47 +1,53 @@ -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 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, local_user_view_from_jwt}, + 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, PersonView}; -use lemmy_utils::error::LemmyError; +use lemmy_utils::error::{LemmyError, LemmyErrorExt2, LemmyErrorType}; -#[async_trait::async_trait] -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))] - async fn perform( - &self, - context: &Data, - ) -> Result { - let local_user_view = local_user_view_from_jwt(&self.auth, context).await?; - let local_site = LocalSite::read(context.pool()).await?; - let person_id = local_user_view.person.id; - check_private_instance(&Some(local_user_view), &local_site)?; - - let res = search_query_to_object_id(&self.q, context) - .await - .map_err(|e| e.with_message("couldnt_find_object"))?; - convert_response(res, 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: PersonId, - pool: &DbPool, -) -> Result { + user_id: Option, + pool: &mut DbPool<'_>, +) -> Result, LemmyError> { use SearchableObjects::*; let removed_or_deleted; let mut res = ResolveObjectResponse::default(); @@ -52,20 +58,20 @@ async fn convert_response( } Community(c) => { removed_or_deleted = c.deleted || c.removed; - res.community = Some(CommunityView::read(pool, c.id, Some(user_id), None).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, Some(user_id), None).await?) + res.post = Some(PostView::read(pool, p.id, user_id, false).await?) } Comment(c) => { removed_or_deleted = c.deleted || c.removed; - res.comment = Some(CommentView::read(pool, c.id, Some(user_id)).await?) + res.comment = Some(CommentView::read(pool, c.id, user_id).await?) } }; // if the object was deleted from database, dont return it if removed_or_deleted { return Err(NotFound {}.into()); } - Ok(res) + Ok(Json(res)) }