forked from alemi/upub
fix: make @context addition explicit
also moved things around: object() is now into LD trait
This commit is contained in:
parent
483076b6b2
commit
c4f677097b
9 changed files with 63 additions and 59 deletions
|
@ -1,8 +1,8 @@
|
|||
use axum::{extract::{Path, State}, http::StatusCode};
|
||||
use sea_orm::EntityTrait;
|
||||
use crate::{activitystream::{prelude::*, Node}, model::{activity, object}, server::Context};
|
||||
use crate::{activitystream::{object::activity::ActivityMut, Base, Node}, model::{activity, object}, server::Context};
|
||||
|
||||
use super::JsonLD;
|
||||
use super::{jsonld::LD, JsonLD};
|
||||
|
||||
|
||||
pub async fn view(State(ctx) : State<Context>, Path(id): Path<String>) -> Result<JsonLD<serde_json::Value>, StatusCode> {
|
||||
|
@ -11,7 +11,12 @@ pub async fn view(State(ctx) : State<Context>, Path(id): Path<String>) -> Result
|
|||
.one(ctx.db())
|
||||
.await
|
||||
{
|
||||
Ok(Some((activity, object))) => Ok(JsonLD(activity.underlying_json_object().set_object(Node::maybe_object(object)))),
|
||||
Ok(Some((activity, object))) => Ok(JsonLD(
|
||||
activity
|
||||
.underlying_json_object()
|
||||
.set_object(Node::maybe_object(object))
|
||||
.ld_context()
|
||||
)),
|
||||
Ok(None) => Err(StatusCode::NOT_FOUND),
|
||||
Err(e) => {
|
||||
tracing::error!("error querying for activity: {e}");
|
||||
|
|
|
@ -1,26 +1,34 @@
|
|||
// got this from https://github.com/kitsune-soc/kitsune/blob/b023a12b687dd9a274233a5a9950f2de5e192344/kitsune/src/http/responder.rs
|
||||
// i was trying to do it with middlewares but this is way cleaner
|
||||
use axum::response::{IntoResponse, Response};
|
||||
|
||||
use axum::{
|
||||
response::{IntoResponse, Response},
|
||||
Json,
|
||||
};
|
||||
use serde::Serialize;
|
||||
|
||||
pub struct JsonLD<T>(pub T);
|
||||
|
||||
impl<T> IntoResponse for JsonLD<T>
|
||||
where
|
||||
T: Serialize,
|
||||
{
|
||||
fn into_response(self) -> Response {
|
||||
(
|
||||
[(
|
||||
"Content-Type",
|
||||
"application/ld+json; profile=\"https://www.w3.org/ns/activitystreams\"",
|
||||
)],
|
||||
Json(self.0),
|
||||
)
|
||||
.into_response()
|
||||
pub trait LD {
|
||||
fn ld_context(self) -> Self;
|
||||
fn new_object() -> serde_json::Value {
|
||||
serde_json::Value::Object(serde_json::Map::default())
|
||||
}
|
||||
}
|
||||
|
||||
impl LD for serde_json::Value {
|
||||
fn ld_context(mut self) -> Self {
|
||||
if let Some(obj) = self.as_object_mut() {
|
||||
obj.insert(
|
||||
"@context".to_string(),
|
||||
serde_json::Value::Array(vec![
|
||||
serde_json::Value::String("https://www.w3.org/ns/activitystreams".into())
|
||||
]),
|
||||
);
|
||||
} else {
|
||||
tracing::warn!("cannot add @context to json value different than object");
|
||||
}
|
||||
self
|
||||
}
|
||||
}
|
||||
|
||||
// got this from https://github.com/kitsune-soc/kitsune/blob/b023a12b687dd9a274233a5a9950f2de5e192344/kitsune/src/http/responder.rs
|
||||
// i was trying to do it with middlewares but this is way cleaner
|
||||
pub struct JsonLD<T>(pub T);
|
||||
impl<T: serde::Serialize> IntoResponse for JsonLD<T> {
|
||||
fn into_response(self) -> Response {
|
||||
// headers body
|
||||
([("Content-Type", "application/ld+json")], axum::Json(self.0)).into_response()
|
||||
}
|
||||
}
|
||||
|
|
|
@ -7,7 +7,9 @@ pub use jsonld::JsonLD;
|
|||
use axum::{extract::State, http::StatusCode, Json};
|
||||
use sea_orm::{EntityTrait, IntoActiveModel};
|
||||
|
||||
use crate::{activitystream::{self, object::{activity::{Activity, ActivityType}, actor::{ActorMut, ActorType}, ObjectMut, ObjectType}, Base, BaseMut, BaseType, Node}, model, server::Context, url};
|
||||
use crate::{activitystream::{object::{activity::{Activity, ActivityType}, actor::{ActorMut, ActorType}, ObjectMut, ObjectType}, Base, BaseMut, BaseType, Node}, model, server::Context, url};
|
||||
|
||||
use self::jsonld::LD;
|
||||
|
||||
pub const PUBLIC_TARGET : &str = "https://www.w3.org/ns/activitystreams#Public";
|
||||
|
||||
|
@ -38,7 +40,7 @@ pub struct Page {
|
|||
|
||||
pub async fn view(State(ctx): State<Context>) -> Result<Json<serde_json::Value>, StatusCode> {
|
||||
Ok(Json(
|
||||
activitystream::object()
|
||||
serde_json::Value::new_object()
|
||||
.set_actor_type(Some(ActorType::Application))
|
||||
.set_id(Some(&url!(ctx, "")))
|
||||
.set_name(Some("μpub"))
|
||||
|
|
|
@ -1,12 +1,11 @@
|
|||
use std::sync::Arc;
|
||||
use crate::activitystream::prelude::*;
|
||||
|
||||
use axum::{extract::{Path, Query, State}, http::StatusCode, Json};
|
||||
use sea_orm::{ColumnTrait, Condition, DatabaseConnection, EntityTrait, IntoActiveModel, Order, QueryFilter, QueryOrder, QuerySelect};
|
||||
|
||||
use crate::{activitystream::{self, object::{activity::ActivityType, collection::CollectionType, ObjectType}, BaseType, Node}, model::{self, activity, object, user}, server::Context, url};
|
||||
use crate::{activitystream::{object::{activity::{Activity, ActivityMut, ActivityType}, collection::{page::CollectionPageMut, CollectionMut, CollectionType}, ObjectType}, Base, BaseMut, BaseType, Node}, model::{self, activity, object, user}, server::Context, url};
|
||||
|
||||
use super::JsonLD;
|
||||
use super::{jsonld::LD, JsonLD};
|
||||
|
||||
pub async fn list(State(_db) : State<Arc<DatabaseConnection>>) -> Result<JsonLD<serde_json::Value>, StatusCode> {
|
||||
todo!()
|
||||
|
@ -14,7 +13,7 @@ pub async fn list(State(_db) : State<Arc<DatabaseConnection>>) -> Result<JsonLD<
|
|||
|
||||
pub async fn view(State(ctx) : State<Context>, Path(id): Path<String>) -> Result<JsonLD<serde_json::Value>, StatusCode> {
|
||||
match user::Entity::find_by_id(ctx.uid(id)).one(ctx.db()).await {
|
||||
Ok(Some(user)) => Ok(JsonLD(user.underlying_json_object())),
|
||||
Ok(Some(user)) => Ok(JsonLD(user.underlying_json_object().ld_context())),
|
||||
Ok(None) => Err(StatusCode::NOT_FOUND),
|
||||
Err(e) => {
|
||||
tracing::error!("error querying for user: {e}");
|
||||
|
@ -59,7 +58,7 @@ pub async fn outbox(
|
|||
.map(|(a, o)| a.underlying_json_object().set_object(Node::maybe_object(o)))
|
||||
.collect();
|
||||
Ok(JsonLD(
|
||||
activitystream::object()
|
||||
serde_json::Value::new_object()
|
||||
// TODO set id, calculate uri from given args
|
||||
.set_collection_type(Some(CollectionType::OrderedCollectionPage))
|
||||
.set_part_of(Node::link(url!(ctx, "/users/{id}/outbox")))
|
||||
|
@ -71,7 +70,7 @@ pub async fn outbox(
|
|||
|
||||
} else {
|
||||
Ok(JsonLD(
|
||||
crate::activitystream::object()
|
||||
serde_json::Value::new_object()
|
||||
.set_id(Some(&url!(ctx, "/users/{id}/outbox")))
|
||||
.set_collection_type(Some(CollectionType::OrderedCollection))
|
||||
.set_first(Node::link(url!(ctx, "/users/{id}/outbox?page=true")))
|
||||
|
|
|
@ -32,17 +32,6 @@ pub trait Base {
|
|||
fn underlying_json_object(self) -> serde_json::Value;
|
||||
}
|
||||
|
||||
pub fn raw_object() -> serde_json::Value { serde_json::Value::Object(serde_json::Map::default()) }
|
||||
pub fn object() -> serde_json::Value {
|
||||
let mut map = serde_json::Map::default();
|
||||
map.insert(
|
||||
"@context".to_string(),
|
||||
serde_json::Value::Array(vec![
|
||||
serde_json::Value::String("https://www.w3.org/ns/activitystreams".into())
|
||||
]),
|
||||
);
|
||||
serde_json::Value::Object(map)
|
||||
}
|
||||
|
||||
pub trait BaseMut {
|
||||
fn set_id(self, val: Option<&str>) -> Self;
|
||||
|
|
|
@ -8,8 +8,7 @@ strenum! {
|
|||
Application,
|
||||
Group,
|
||||
Organization,
|
||||
Person,
|
||||
Object;
|
||||
Person;
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
use sea_orm::{entity::prelude::*, FromJsonQueryResult};
|
||||
|
||||
use crate::activitystream::{self, link::Link, object::{activity::{Activity, ActivityMut, ActivityType}, actor::Actor, Object, ObjectMut, ObjectType}, Base, BaseMut, BaseType, Node};
|
||||
use crate::{activitypub::jsonld::LD, activitystream::{link::Link, object::{activity::{Activity, ActivityMut, ActivityType}, actor::Actor, Object, ObjectMut, ObjectType}, Base, BaseMut, BaseType, Node}};
|
||||
|
||||
#[derive(Clone, Debug, Default, PartialEq, Eq, serde::Serialize, serde::Deserialize, FromJsonQueryResult)]
|
||||
pub struct Audience(pub Vec<String>);
|
||||
|
@ -80,7 +80,7 @@ impl Base for Model {
|
|||
}
|
||||
|
||||
fn underlying_json_object(self) -> serde_json::Value {
|
||||
activitystream::object()
|
||||
serde_json::Value::new_object()
|
||||
.set_id(Some(&self.id))
|
||||
.set_activity_type(Some(self.activity_type))
|
||||
.set_actor(Node::link(self.actor))
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
use sea_orm::entity::prelude::*;
|
||||
use crate::activitystream::prelude::*;
|
||||
|
||||
use crate::activitystream::{object::ObjectType, BaseType, Node};
|
||||
use crate::{activitypub::jsonld::LD, activitystream::{object::{ObjectMut, ObjectType}, BaseMut, BaseType, Node}};
|
||||
|
||||
#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq)]
|
||||
#[sea_orm(table_name = "objects")]
|
||||
|
@ -54,7 +53,7 @@ impl crate::activitystream::Base for Model {
|
|||
}
|
||||
|
||||
fn underlying_json_object(self) -> serde_json::Value {
|
||||
crate::activitystream::object()
|
||||
serde_json::Value::new_object()
|
||||
.set_id(Some(&self.id))
|
||||
.set_object_type(Some(self.object_type))
|
||||
.set_attributed_to(Node::maybe_link(self.attributed_to))
|
||||
|
|
|
@ -1,7 +1,11 @@
|
|||
use sea_orm::entity::prelude::*;
|
||||
use crate::activitystream::object::document::DocumentType;
|
||||
use crate::activitystream::prelude::*;
|
||||
use crate::activitypub::jsonld::LD;
|
||||
use crate::activitystream::key::{PublicKey as _, PublicKeyMut as _};
|
||||
use crate::activitystream::object::actor::ActorMut as _;
|
||||
use crate::activitystream::object::document::{DocumentMut as _, DocumentType};
|
||||
|
||||
use crate::activitystream::object::ObjectMut as _;
|
||||
use crate::activitystream::{BaseMut as _, Object as _};
|
||||
use crate::{activitypub, activitystream::{object::actor::ActorType, BaseType, Node, ObjectType}};
|
||||
|
||||
#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq)]
|
||||
|
@ -71,7 +75,7 @@ impl crate::activitystream::Base for Model {
|
|||
}
|
||||
|
||||
fn underlying_json_object(self) -> serde_json::Value {
|
||||
crate::activitystream::object()
|
||||
serde_json::Value::new_object()
|
||||
.set_id(Some(&self.id))
|
||||
.set_actor_type(Some(self.actor_type))
|
||||
.set_name(self.name.as_deref())
|
||||
|
@ -87,7 +91,6 @@ impl crate::activitystream::Base for Model {
|
|||
.set_public_key(self.public_key())
|
||||
.set_discoverable(Some(true))
|
||||
.set_endpoints(None) // TODO dirty fix to put an empty object
|
||||
.underlying_json_object()
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -103,7 +106,7 @@ impl crate::activitystream::object::Object for Model {
|
|||
fn icon(&self) -> Node<impl Image> {
|
||||
match &self.icon {
|
||||
Some(x) => Node::object(
|
||||
crate::activitystream::raw_object()
|
||||
serde_json::Value::new_object()
|
||||
.set_document_type(Some(DocumentType::Image))
|
||||
.set_url(Node::link(x.clone()))
|
||||
),
|
||||
|
@ -114,7 +117,7 @@ impl crate::activitystream::object::Object for Model {
|
|||
fn image(&self) -> Node<impl Image> {
|
||||
match &self.image {
|
||||
Some(x) => Node::object(
|
||||
crate::activitystream::raw_object()
|
||||
serde_json::Value::new_object()
|
||||
.set_document_type(Some(DocumentType::Image))
|
||||
.set_url(Node::link(x.clone()))
|
||||
),
|
||||
|
@ -154,7 +157,7 @@ impl crate::activitystream::object::actor::Actor for Model {
|
|||
|
||||
fn public_key(&self) -> Node<impl crate::activitystream::key::PublicKey> {
|
||||
Node::object(
|
||||
crate::activitystream::raw_object()
|
||||
serde_json::Value::new_object()
|
||||
.set_id(Some(&format!("{}#main-key", self.id))) // TODO is this some standard??
|
||||
.set_public_key_pem(&self.public_key)
|
||||
.set_owner(Some(&self.id))
|
||||
|
|
Loading…
Reference in a new issue