From d1b4bd0181000ada7bf5ef3d6a460a04a4d65f8b Mon Sep 17 00:00:00 2001 From: Thomas Sileo Date: Mon, 15 Aug 2022 21:34:57 +0200 Subject: [PATCH] Improve lookup and handle visibility in threads --- app/actor.py | 10 +++++++--- app/admin.py | 33 +++++++++++++++++++-------------- app/boxes.py | 8 +++++++- app/main.py | 6 +++++- 4 files changed, 38 insertions(+), 19 deletions(-) diff --git a/app/actor.py b/app/actor.py index 17d8f4a..e7d10f1 100644 --- a/app/actor.py +++ b/app/actor.py @@ -168,6 +168,7 @@ async def save_actor(db_session: AsyncSession, ap_actor: ap.RawObject) -> "Actor async def fetch_actor( db_session: AsyncSession, actor_id: str, + save_if_not_found: bool = True, ) -> "ActorModel": if actor_id == LOCAL_ACTOR.ap_id: raise ValueError("local actor should not be fetched") @@ -180,9 +181,12 @@ async def fetch_actor( ).one_or_none() if existing_actor: return existing_actor - - ap_actor = await ap.fetch(actor_id) - return await save_actor(db_session, ap_actor) + else: + if save_if_not_found: + ap_actor = await ap.fetch(actor_id) + return await save_actor(db_session, ap_actor) + else: + raise ap.ObjectNotFoundError @dataclass diff --git a/app/admin.py b/app/admin.py index 294d61e..90ae62b 100644 --- a/app/admin.py +++ b/app/admin.py @@ -88,19 +88,6 @@ async def get_lookup( ap_object = None actors_metadata = {} if query: - requested_object = await boxes.get_anybox_object_by_ap_id(db_session, query) - if requested_object: - if ( - requested_object.ap_type == "Create" - and requested_object.relates_to_anybox_object - ): - query = requested_object.relates_to_anybox_object.ap_id - return RedirectResponse( - request.url_for("admin_object") + f"?ap_id={query}", - status_code=302, - ) - # TODO(ts): redirect to admin_profile if the actor is in DB - try: ap_object = await lookup(db_session, query) except httpx.TimeoutException: @@ -112,6 +99,19 @@ async def get_lookup( error = ap.FetchErrorTypeEnum.INTERNAL_ERROR else: if ap_object.ap_type in ap.ACTOR_TYPES: + try: + await fetch_actor( + db_session, ap_object.ap_id, save_if_not_found=False + ) + except ap.NotAnObjectError: + pass + else: + return RedirectResponse( + request.url_for("admin_profile") + + f"?actor_id={ap_object.ap_id}", + status_code=302, + ) + actors_metadata = await get_actors_metadata( db_session, [ap_object] # type: ignore ) @@ -129,6 +129,7 @@ async def get_lookup( actors_metadata = await get_actors_metadata( db_session, [ap_object.actor] # type: ignore ) + return await templates.render_template( db_session, request, @@ -717,7 +718,11 @@ async def admin_object( if not requested_object: raise HTTPException(status_code=404) - replies_tree = await boxes.get_replies_tree(db_session, requested_object) + replies_tree = await boxes.get_replies_tree( + db_session, + requested_object, + is_current_user_admin=True, + ) return await templates.render_template( db_session, diff --git a/app/boxes.py b/app/boxes.py index 3ccb83f..2186854 100644 --- a/app/boxes.py +++ b/app/boxes.py @@ -1865,13 +1865,17 @@ class ReplyTreeNode: async def get_replies_tree( db_session: AsyncSession, requested_object: AnyboxObject, + is_current_user_admin: bool, ) -> ReplyTreeNode: # XXX: PeerTube video don't use context tree_nodes: list[AnyboxObject] = [] if requested_object.conversation is None: tree_nodes = [requested_object] else: - # TODO: handle visibility + allowed_visibility = [ap.VisibilityEnum.PUBLIC, ap.VisibilityEnum.UNLISTED] + if is_current_user_admin: + allowed_visibility = list(ap.VisibilityEnum) + tree_nodes.extend( ( await db_session.scalars( @@ -1881,6 +1885,7 @@ async def get_replies_tree( == requested_object.conversation, models.InboxObject.ap_type.in_(["Note", "Page", "Article"]), models.InboxObject.is_deleted.is_(False), + models.InboxObject.visibility.in_(allowed_visibility), ) .options(joinedload(models.InboxObject.actor)) ) @@ -1897,6 +1902,7 @@ async def get_replies_tree( == requested_object.conversation, models.OutboxObject.is_deleted.is_(False), models.OutboxObject.ap_type.in_(["Note", "Page", "Article"]), + models.OutboxObject.visibility.in_(allowed_visibility), ) .options( joinedload( diff --git a/app/main.py b/app/main.py index 057c2c0..c081d4e 100644 --- a/app/main.py +++ b/app/main.py @@ -585,7 +585,11 @@ async def outbox_by_public_id( if is_activitypub_requested(request): return ActivityPubResponse(maybe_object.ap_object) - replies_tree = await boxes.get_replies_tree(db_session, maybe_object) + replies_tree = await boxes.get_replies_tree( + db_session, + maybe_object, + is_current_user_admin=is_current_user_admin(request), + ) likes = ( (