feat: inbox/outbox security and obj embedding
This commit is contained in:
parent
0d340185cf
commit
af8d11e75b
6 changed files with 42 additions and 49 deletions
|
@ -5,6 +5,7 @@ use apb::{ActivityMut, ObjectMut, BaseMut, Node};
|
||||||
|
|
||||||
use super::{jsonld::LD, JsonLD};
|
use super::{jsonld::LD, JsonLD};
|
||||||
|
|
||||||
|
// TODO this is used outside /routes, maybe move in model?
|
||||||
pub fn ap_activity(activity: model::activity::Model) -> serde_json::Value {
|
pub fn ap_activity(activity: model::activity::Model) -> serde_json::Value {
|
||||||
serde_json::Value::new_object()
|
serde_json::Value::new_object()
|
||||||
.set_id(Some(&activity.id))
|
.set_id(Some(&activity.id))
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
use axum::{extract::{Query, State}, http::StatusCode};
|
use axum::{extract::{Query, State}, http::StatusCode};
|
||||||
use sea_orm::{ColumnTrait, Condition, EntityTrait, Order, QueryFilter, QueryOrder, QuerySelect};
|
use sea_orm::{Order, QueryFilter, QueryOrder, QuerySelect};
|
||||||
|
|
||||||
use crate::{server::auth::{AuthIdentity, Identity}, errors::UpubError, model, server::Context, url};
|
use crate::{server::auth::AuthIdentity, errors::UpubError, model, server::Context, url};
|
||||||
|
|
||||||
use super::{activity::ap_activity, jsonld::LD, JsonLD, Pagination};
|
use super::{activity::ap_activity, jsonld::LD, JsonLD, Pagination};
|
||||||
|
|
||||||
|
@ -19,14 +19,8 @@ pub async fn page(
|
||||||
) -> Result<JsonLD<serde_json::Value>, UpubError> {
|
) -> Result<JsonLD<serde_json::Value>, UpubError> {
|
||||||
let limit = page.batch.unwrap_or(20).min(50);
|
let limit = page.batch.unwrap_or(20).min(50);
|
||||||
let offset = page.offset.unwrap_or(0);
|
let offset = page.offset.unwrap_or(0);
|
||||||
let mut condition = Condition::any()
|
let activities = model::addressing::Entity::find_activities()
|
||||||
.add(model::addressing::Column::Actor.eq(apb::target::PUBLIC));
|
.filter(auth.filter_condition())
|
||||||
if let Identity::Local(user) = auth {
|
|
||||||
condition = condition
|
|
||||||
.add(model::addressing::Column::Actor.eq(user));
|
|
||||||
}
|
|
||||||
let activities = model::addressing::Entity::find()
|
|
||||||
.filter(condition)
|
|
||||||
.order_by(model::addressing::Column::Published, Order::Asc)
|
.order_by(model::addressing::Column::Published, Order::Asc)
|
||||||
.find_also_related(model::activity::Entity)
|
.find_also_related(model::activity::Entity)
|
||||||
.limit(limit)
|
.limit(limit)
|
||||||
|
|
|
@ -6,6 +6,7 @@ use crate::{model::{self, object}, server::Context};
|
||||||
|
|
||||||
use super::{jsonld::LD, JsonLD};
|
use super::{jsonld::LD, JsonLD};
|
||||||
|
|
||||||
|
// TODO this is used outside /routes, maybe move in model?
|
||||||
pub fn ap_object(object: model::object::Model) -> serde_json::Value {
|
pub fn ap_object(object: model::object::Model) -> serde_json::Value {
|
||||||
serde_json::Value::new_object()
|
serde_json::Value::new_object()
|
||||||
.set_id(Some(&object.id))
|
.set_id(Some(&object.id))
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
use axum::{extract::{Path, Query, State}, http::StatusCode, Json};
|
use axum::{extract::{Path, Query, State}, http::StatusCode, Json};
|
||||||
use sea_orm::{ColumnTrait, Condition, EntityTrait, JoinType, Order, QueryFilter, QueryOrder, QuerySelect, RelationTrait};
|
|
||||||
|
|
||||||
use apb::{server::Inbox, ActivityMut, ActivityType, Base, BaseType, ObjectType};
|
use apb::{server::Inbox, ActivityMut, ActivityType, Base, BaseType, ObjectType};
|
||||||
use crate::{errors::UpubError, model, routes::activitypub::{activity::ap_activity, jsonld::LD, object::ap_object, JsonLD, Pagination}, server::{auth::{AuthIdentity, Identity}, Context}, tools::ActivityWithObject, url};
|
use sea_orm::{ColumnTrait, Condition, QueryFilter, QuerySelect};
|
||||||
|
use crate::{errors::UpubError, model::{self, addressing::EmbeddedActivity}, routes::activitypub::{activity::ap_activity, jsonld::LD, object::ap_object, JsonLD, Pagination}, server::{auth::{AuthIdentity, Identity}, Context}, url};
|
||||||
|
|
||||||
pub async fn get(
|
pub async fn get(
|
||||||
State(ctx): State<Context>,
|
State(ctx): State<Context>,
|
||||||
|
@ -33,20 +33,11 @@ pub async fn page(
|
||||||
Identity::Local(user) => if uid == user {
|
Identity::Local(user) => if uid == user {
|
||||||
let limit = page.batch.unwrap_or(20).min(50);
|
let limit = page.batch.unwrap_or(20).min(50);
|
||||||
let offset = page.offset.unwrap_or(0);
|
let offset = page.offset.unwrap_or(0);
|
||||||
let select = model::addressing::Entity::find()
|
match model::addressing::Entity::find_activities()
|
||||||
.filter(Condition::all().add(model::addressing::Column::Actor.eq(uid)))
|
.filter(Condition::all().add(model::addressing::Column::Actor.eq(&user)))
|
||||||
.order_by(model::addressing::Column::Published, Order::Asc)
|
|
||||||
.select_only();
|
|
||||||
|
|
||||||
match crate::tools::Prefixer::new(select)
|
|
||||||
.add_columns(model::activity::Entity)
|
|
||||||
.add_columns(model::object::Entity)
|
|
||||||
.selector
|
|
||||||
.join(JoinType::LeftJoin, model::activity::Relation::Addressing.def().rev())
|
|
||||||
.join(JoinType::LeftJoin, model::object::Relation::Activity.def().rev())
|
|
||||||
.limit(limit)
|
|
||||||
.offset(offset)
|
.offset(offset)
|
||||||
.into_model::<crate::tools::ActivityWithObject>()
|
.limit(limit)
|
||||||
|
.into_model::<EmbeddedActivity>()
|
||||||
.all(ctx.db())
|
.all(ctx.db())
|
||||||
.await
|
.await
|
||||||
{
|
{
|
||||||
|
@ -57,9 +48,11 @@ pub async fn page(
|
||||||
offset, limit,
|
offset, limit,
|
||||||
activities
|
activities
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.map(|ActivityWithObject { activity, object }| {
|
.map(|EmbeddedActivity { activity, object }| match object {
|
||||||
ap_activity(activity)
|
None => ap_activity(activity),
|
||||||
.set_object(apb::Node::maybe_object(object.map(ap_object)))
|
Some(x) =>
|
||||||
|
ap_activity(activity)
|
||||||
|
.set_object(apb::Node::object(ap_object(x))),
|
||||||
})
|
})
|
||||||
.collect::<Vec<serde_json::Value>>()
|
.collect::<Vec<serde_json::Value>>()
|
||||||
).ld_context()
|
).ld_context()
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
use axum::{extract::{Path, Query, State}, http::StatusCode, Json};
|
use axum::{extract::{Path, Query, State}, http::StatusCode, Json};
|
||||||
use sea_orm::{EntityTrait, Order, QueryOrder, QuerySelect};
|
use sea_orm::{ColumnTrait, Condition, Order, QueryFilter, QueryOrder, QuerySelect};
|
||||||
|
|
||||||
use apb::{server::Outbox, AcceptType, ActivityMut, ActivityType, Base, BaseType, Node, ObjectType, RejectType};
|
use apb::{server::Outbox, AcceptType, ActivityMut, ActivityType, Base, BaseType, Node, ObjectType, RejectType};
|
||||||
use crate::{routes::activitypub::{jsonld::LD, CreationResult, JsonLD, Pagination}, server::auth::{AuthIdentity, Identity}, errors::UpubError, model, server::Context, url};
|
use crate::{errors::UpubError, model::{self, addressing::EmbeddedActivity}, routes::activitypub::{jsonld::LD, CreationResult, JsonLD, Pagination}, server::{auth::{AuthIdentity, Identity}, Context}, url};
|
||||||
|
|
||||||
pub async fn get(
|
pub async fn get(
|
||||||
State(ctx): State<Context>,
|
State(ctx): State<Context>,
|
||||||
|
@ -17,27 +17,19 @@ pub async fn page(
|
||||||
State(ctx): State<Context>,
|
State(ctx): State<Context>,
|
||||||
Path(id): Path<String>,
|
Path(id): Path<String>,
|
||||||
Query(page): Query<Pagination>,
|
Query(page): Query<Pagination>,
|
||||||
AuthIdentity(_auth): AuthIdentity,
|
AuthIdentity(auth): AuthIdentity,
|
||||||
) -> Result<JsonLD<serde_json::Value>, StatusCode> {
|
) -> Result<JsonLD<serde_json::Value>, StatusCode> {
|
||||||
|
let uid = ctx.uid(id.clone());
|
||||||
let limit = page.batch.unwrap_or(20).min(50);
|
let limit = page.batch.unwrap_or(20).min(50);
|
||||||
let offset = page.offset.unwrap_or(0);
|
let offset = page.offset.unwrap_or(0);
|
||||||
|
|
||||||
// let mut conditions = Condition::any()
|
match model::addressing::Entity::find_activities()
|
||||||
// .add(model::addressing::Column::Actor.eq(PUBLIC_TARGET));
|
.filter(Condition::all().add(model::activity::Column::Actor.eq(&uid)))
|
||||||
|
.filter(auth.filter_condition())
|
||||||
// if let Identity::User(ref x) = auth {
|
.order_by(model::addressing::Column::Published, Order::Desc)
|
||||||
// conditions = conditions.add(model::addressing::Column::Actor.eq(x));
|
|
||||||
// }
|
|
||||||
|
|
||||||
// if let Identity::Server(ref x) = auth {
|
|
||||||
// conditions = conditions.add(model::addressing::Column::Server.eq(x));
|
|
||||||
// }
|
|
||||||
|
|
||||||
match model::activity::Entity::find()
|
|
||||||
.find_also_related(model::object::Entity)
|
|
||||||
.order_by(model::activity::Column::Published, Order::Desc)
|
|
||||||
.limit(limit)
|
.limit(limit)
|
||||||
.offset(offset)
|
.offset(offset)
|
||||||
|
.into_model::<EmbeddedActivity>()
|
||||||
.all(ctx.db()).await
|
.all(ctx.db()).await
|
||||||
{
|
{
|
||||||
Err(_e) => Err(StatusCode::INTERNAL_SERVER_ERROR),
|
Err(_e) => Err(StatusCode::INTERNAL_SERVER_ERROR),
|
||||||
|
@ -48,10 +40,10 @@ pub async fn page(
|
||||||
offset, limit,
|
offset, limit,
|
||||||
items
|
items
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.map(|(a, o)| {
|
.map(|EmbeddedActivity { activity, object }| {
|
||||||
let oid = a.object.clone();
|
let oid = activity.object.clone();
|
||||||
super::super::activity::ap_activity(a)
|
super::super::activity::ap_activity(activity)
|
||||||
.set_object(match o {
|
.set_object(match object {
|
||||||
Some(o) => Node::object(super::super::object::ap_object(o)),
|
Some(o) => Node::object(super::super::object::ap_object(o)),
|
||||||
None => Node::maybe_link(oid),
|
None => Node::maybe_link(oid),
|
||||||
})
|
})
|
||||||
|
|
|
@ -13,6 +13,18 @@ pub enum Identity {
|
||||||
Remote(String),
|
Remote(String),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl Identity {
|
||||||
|
pub fn filter_condition(&self) -> Condition {
|
||||||
|
let base_cond = Condition::all().add(model::addressing::Column::Actor.eq(apb::target::PUBLIC));
|
||||||
|
match self {
|
||||||
|
Identity::Anonymous => base_cond,
|
||||||
|
Identity::Local(uid) => base_cond.add(model::addressing::Column::Actor.eq(uid)),
|
||||||
|
Identity::Remote(server) => base_cond.add(model::addressing::Column::Server.eq(server)),
|
||||||
|
// TODO should we allow all users on same server to see? or just specific user??
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub struct AuthIdentity(pub Identity);
|
pub struct AuthIdentity(pub Identity);
|
||||||
|
|
||||||
#[axum::async_trait]
|
#[axum::async_trait]
|
||||||
|
|
Loading…
Reference in a new issue