From d3d5f98dfd03ad82476ddc897617d0374620aa4b Mon Sep 17 00:00:00 2001 From: alemi Date: Fri, 12 Apr 2024 22:21:23 +0200 Subject: [PATCH] feat: authorized fetch on activities and objects --- src/model/addressing.rs | 14 ++++++++++++++ src/routes/activitypub/activity.rs | 25 ++++++++++++------------- src/routes/activitypub/object.rs | 18 ++++++++++++++---- 3 files changed, 40 insertions(+), 17 deletions(-) diff --git a/src/model/addressing.rs b/src/model/addressing.rs index b5c552ef..7c75ebd6 100644 --- a/src/model/addressing.rs +++ b/src/model/addressing.rs @@ -101,4 +101,18 @@ impl Entity { select } + + pub fn find_objects() -> Select { + let mut select = Entity::find() + .select_only() + .join(sea_orm::JoinType::InnerJoin, Relation::Object.def()); + // INNERJOIN: filter out addressings for which we don't have an activity anymore + // TODO we could in theory return just the link or fetch them again, just ignoring them is mehh + + for col in crate::model::object::Column::iter() { + select = select.select_column_as(col, format!("{}{}", crate::model::object::Entity.table_name(), col.to_string())); + } + + select + } } diff --git a/src/routes/activitypub/activity.rs b/src/routes/activitypub/activity.rs index 71261906..ebdb4fc4 100644 --- a/src/routes/activitypub/activity.rs +++ b/src/routes/activitypub/activity.rs @@ -1,6 +1,6 @@ use axum::{extract::{Path, State}, http::StatusCode}; -use sea_orm::EntityTrait; -use crate::{model::{self, activity, object}, server::Context}; +use sea_orm::{ColumnTrait, QueryFilter}; +use crate::{model::{self, addressing::EmbeddedActivity}, server::{auth::AuthIdentity, Context}}; use apb::{ActivityMut, ObjectMut, BaseMut, Node}; use super::{jsonld::LD, JsonLD}; @@ -20,20 +20,19 @@ pub fn ap_activity(activity: model::activity::Model) -> serde_json::Value { .set_bcc(Node::Empty) } -pub async fn view(State(ctx) : State, Path(id): Path) -> Result, StatusCode> { - match activity::Entity::find_by_id(ctx.aid(id)) - .find_also_related(object::Entity) +pub async fn view( + State(ctx): State, + Path(id): Path, + AuthIdentity(auth): AuthIdentity, +) -> Result, StatusCode> { + match model::addressing::Entity::find_activities() + .filter(model::activity::Column::Id.eq(ctx.aid(id))) + .filter(auth.filter_condition()) + .into_model::() .one(ctx.db()) .await { - Ok(Some((activity, Some(object)))) => Ok(JsonLD( - ap_activity(activity) - .set_object(Node::object(super::object::ap_object(object))) - .ld_context() - )), - Ok(Some((activity, None))) => Ok(JsonLD( - ap_activity(activity).ld_context() - )), + Ok(Some(activity)) => Ok(JsonLD(serde_json::Value::from(activity).ld_context())), Ok(None) => Err(StatusCode::NOT_FOUND), Err(e) => { tracing::error!("error querying for activity: {e}"); diff --git a/src/routes/activitypub/object.rs b/src/routes/activitypub/object.rs index f0e85b6a..8399719a 100644 --- a/src/routes/activitypub/object.rs +++ b/src/routes/activitypub/object.rs @@ -1,8 +1,8 @@ use axum::{extract::{Path, State}, http::StatusCode}; -use sea_orm::EntityTrait; +use sea_orm::{ColumnTrait, QueryFilter}; use apb::{ObjectMut, BaseMut, Node}; -use crate::{model::{self, object}, server::Context}; +use crate::{model, server::{auth::AuthIdentity, Context}}; use super::{jsonld::LD, JsonLD}; @@ -23,8 +23,18 @@ pub fn ap_object(object: model::object::Model) -> serde_json::Value { .set_bcc(Node::Empty) } -pub async fn view(State(ctx) : State, Path(id): Path) -> Result, StatusCode> { - match object::Entity::find_by_id(ctx.oid(id)).one(ctx.db()).await { +pub async fn view( + State(ctx): State, + Path(id): Path, + AuthIdentity(auth): AuthIdentity, +) -> Result, StatusCode> { + match model::addressing::Entity::find_objects() + .filter(model::object::Column::Id.eq(ctx.oid(id))) + .filter(auth.filter_condition()) + .into_model::() + .one(ctx.db()) + .await + { Ok(Some(object)) => Ok(JsonLD(ap_object(object).ld_context())), Ok(None) => Err(StatusCode::NOT_FOUND), Err(e) => {