1
0
Fork 0
forked from alemi/upub

fix: actually insert addressing on receiving

also some nice utils to handle link vecs
This commit is contained in:
əlemi 2024-03-24 05:49:36 +01:00
parent a0d75d0807
commit 2958107c49
Signed by: alemi
GPG key ID: A4895B84D311642C
3 changed files with 50 additions and 2 deletions

View file

@ -1,7 +1,7 @@
use axum::{extract::{Path, State}, http::StatusCode, Json};
use sea_orm::{sea_query::Expr, ColumnTrait, EntityTrait, IntoActiveModel, QueryFilter};
use crate::{activitypub::JsonLD, activitystream::{object::{activity::{Activity, ActivityType}, ObjectType}, Base, BaseType, Node}, errors::LoggableError, model::{self, activity, object}, server::Context};
use crate::{activitypub::JsonLD, activitystream::{object::{activity::{Activity, ActivityType}, Addressed, ObjectType}, Base, BaseType, Node}, errors::LoggableError, model::{self, activity, addressing, object}, server::Context};
pub async fn inbox(
State(ctx): State<Context>,
@ -88,12 +88,29 @@ pub async fn inbox(
return Err(StatusCode::UNPROCESSABLE_ENTITY);
};
tracing::info!("processing Create activity by {} for {}", activity_entity.actor, activity_entity.object.as_deref().unwrap_or("<embedded>"));
let object_id = obj_entity.id.clone();
let activity_id = activity_entity.id.clone();
object::Entity::insert(obj_entity.into_active_model())
.exec(ctx.db())
.await.map_err(|_| StatusCode::INTERNAL_SERVER_ERROR)?;
activity::Entity::insert(activity_entity.into_active_model())
.exec(ctx.db())
.await.map_err(|_| StatusCode::INTERNAL_SERVER_ERROR)?;
addressing::Entity::insert_many(
object.addressed()
.into_iter()
.map(|actor|
addressing::ActiveModel{
id: sea_orm::ActiveValue::NotSet,
actor: sea_orm::Set(actor),
activity: sea_orm::Set(activity_id.clone()),
object: sea_orm::Set(Some(object_id.clone())),
published: sea_orm::Set(chrono::Utc::now()),
}
)
)
.exec(ctx.db())
.await.map_err(|_| StatusCode::INTERNAL_SERVER_ERROR)?;
Ok(JsonLD(serde_json::Value::Null)) // TODO hmmmmmmmmmmm not the best value to return....
},
Some(BaseType::Object(ObjectType::Activity(_x))) => {

View file

@ -29,7 +29,8 @@ impl<T : super::Base> Node<T> {
}
}
pub fn all(&self) -> Option<Vec<&T>> {
// TODO extremely unforgiving, is this even useful?
pub fn get_items(&self) -> Option<Vec<&T>> {
match self {
Node::Empty | Node::Link(_) => None,
Node::Object(x) => Some(vec![x]),
@ -40,6 +41,24 @@ impl<T : super::Base> Node<T> {
}).collect()),
}
}
pub fn get_links(&self) -> Vec<String> {
match self {
Node::Empty => vec![],
Node::Link(x) => vec![x.href().to_string()],
Node::Object(x) => match x.id() {
Some(x) => vec![x.to_string()],
None => vec![],
},
Node::Array(v) =>
v.iter().filter_map(|x| match x {
Node::Link(x) => Some(x.href().to_string()),
Node::Object(x) => x.id().map(|x| x.to_string()),
// TODO handle array of arrays maybe?
_ => None,
}).collect(),
}
}
pub fn is_empty(&self) -> bool {
match self {

View file

@ -64,6 +64,16 @@ pub trait Object : super::Base {
fn duration(&self) -> Option<&str> { None } // TODO how to parse xsd:duration ?
}
pub trait Addressed : Object {
fn addressed(&self) -> Vec<String> {
let mut to = self.to().get_links();
to.append(&mut self.bto().get_links());
to.append(&mut self.cc().get_links());
to.append(&mut self.bcc().get_links());
to
}
}
pub trait ObjectMut : super::BaseMut {
fn set_object_type(self, val: Option<ObjectType>) -> Self;
fn set_attachment(self, val: Node<impl Object>) -> Self;
@ -135,6 +145,8 @@ impl Object for serde_json::Value {
}
}
impl Addressed for serde_json::Value {}
impl ObjectMut for serde_json::Value {
setter! { object_type -> type ObjectType }
setter! { attachment -> node impl Object }