feat: add global inbox get, which respects privacy
This commit is contained in:
parent
2ac7fa0588
commit
28ba5f1b40
4 changed files with 45 additions and 19 deletions
|
@ -1,20 +1,45 @@
|
||||||
use axum::{extract::State, http::StatusCode, Json};
|
use axum::{extract::{Query, State}, http::StatusCode};
|
||||||
use sea_orm::{EntityTrait, QueryOrder, QuerySelect};
|
use sea_orm::{ColumnTrait, Condition, EntityTrait, QueryFilter, QueryOrder, QuerySelect};
|
||||||
|
|
||||||
use crate::{model, server::Context};
|
use crate::{activitystream::{object::collection::{page::CollectionPageMut, CollectionMut, CollectionType}, BaseMut, Node}, model, server::Context, url};
|
||||||
|
|
||||||
use super::JsonLD;
|
use super::{activity::ap_activity, jsonld::LD, JsonLD, Pagination, PUBLIC_TARGET};
|
||||||
|
|
||||||
|
|
||||||
pub async fn get(State(ctx) : State<Context>, Json(_object): Json<serde_json::Value>) -> Result<JsonLD<serde_json::Value>, StatusCode> {
|
pub async fn get(State(ctx) : State<Context>, Query(page): Query<Pagination>) -> Result<JsonLD<serde_json::Value>, StatusCode> {
|
||||||
match model::activity::Entity::find()
|
let limit = page.batch.unwrap_or(20).min(100);
|
||||||
.order_by(model::activity::Column::Published, sea_orm::Order::Desc)
|
let offset = page.offset.unwrap_or(0);
|
||||||
.limit(20)
|
if let Some(true) = page.page {
|
||||||
.all(ctx.db())
|
match model::addressing::Entity::find()
|
||||||
.await
|
.filter(Condition::all().add(model::addressing::Column::Actor.eq(PUBLIC_TARGET)))
|
||||||
{
|
.order_by(model::addressing::Column::Published, sea_orm::Order::Desc)
|
||||||
Ok(x) => todo!(),
|
.find_also_related(model::activity::Entity) // TODO join also with objects
|
||||||
Err(_e) => Err(StatusCode::INTERNAL_SERVER_ERROR),
|
.limit(limit)
|
||||||
|
.offset(offset)
|
||||||
|
.all(ctx.db())
|
||||||
|
.await
|
||||||
|
{
|
||||||
|
Ok(x) => Ok(JsonLD(serde_json::Value::new_object()
|
||||||
|
.set_id(Some(&url!(ctx, "/inbox")))
|
||||||
|
.set_collection_type(Some(CollectionType::OrderedCollection))
|
||||||
|
.set_part_of(Node::link(url!(ctx, "/inbox")))
|
||||||
|
.set_next(Node::link(url!(ctx, "/inbox?page=true&offset={}", offset+limit)))
|
||||||
|
.set_ordered_items(Node::array(
|
||||||
|
x.into_iter()
|
||||||
|
.filter_map(|(_, a)| Some(ap_activity(a?)))
|
||||||
|
.collect()
|
||||||
|
))
|
||||||
|
.ld_context()
|
||||||
|
)),
|
||||||
|
Err(_e) => Err(StatusCode::INTERNAL_SERVER_ERROR),
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
Ok(JsonLD(serde_json::Value::new_object()
|
||||||
|
.set_id(Some(&url!(ctx, "/inbox")))
|
||||||
|
.set_collection_type(Some(CollectionType::OrderedCollection))
|
||||||
|
.set_first(Node::link(url!(ctx, "/inbox?page=true")))
|
||||||
|
.ld_context()
|
||||||
|
))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -8,6 +8,7 @@ pub struct Model {
|
||||||
pub actor: String,
|
pub actor: String,
|
||||||
pub activity: String,
|
pub activity: String,
|
||||||
pub object: Option<String>,
|
pub object: Option<String>,
|
||||||
|
pub published: ChronoDateTimeUtc,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]
|
#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]
|
||||||
|
|
|
@ -8,8 +8,10 @@ pub async fn serve(db: DatabaseConnection, domain: String) {
|
||||||
// core server inbox/outbox, maybe for feeds? TODO do we need these?
|
// core server inbox/outbox, maybe for feeds? TODO do we need these?
|
||||||
.route("/", get(ap::view))
|
.route("/", get(ap::view))
|
||||||
// TODO shared inboxes and instance stream will come later, just use users *boxes for now
|
// TODO shared inboxes and instance stream will come later, just use users *boxes for now
|
||||||
// .route("/inbox", post(ap::inbox))
|
.route("/inbox", get(ap::inbox::get))
|
||||||
// .route("/outbox", get(ap::outbox))
|
// .route("/inbox", post(ap::inbox::post))
|
||||||
|
// .route("/outbox", get(ap::outbox::get))
|
||||||
|
// .route("/outbox", get(ap::outbox::post))
|
||||||
// .well-known and discovery
|
// .well-known and discovery
|
||||||
.route("/.well-known/webfinger", get(ap::well_known::webfinger))
|
.route("/.well-known/webfinger", get(ap::well_known::webfinger))
|
||||||
.route("/.well-known/host-meta", get(ap::well_known::host_meta))
|
.route("/.well-known/host-meta", get(ap::well_known::host_meta))
|
||||||
|
@ -26,8 +28,8 @@ pub async fn serve(db: DatabaseConnection, domain: String) {
|
||||||
.route("/objects/:id", get(ap::object::view))
|
.route("/objects/:id", get(ap::object::view))
|
||||||
.with_state(crate::server::Context::new(db, domain));
|
.with_state(crate::server::Context::new(db, domain));
|
||||||
|
|
||||||
// run our app with hyper, listening globally on port 3000
|
// run our app with hyper, listening locally on port 3000
|
||||||
let listener = tokio::net::TcpListener::bind("0.0.0.0:3000").await.unwrap();
|
let listener = tokio::net::TcpListener::bind("127.0.0.1:3000").await.unwrap();
|
||||||
|
|
||||||
axum::serve(listener, app)
|
axum::serve(listener, app)
|
||||||
.await
|
.await
|
||||||
|
|
|
@ -1,8 +1,6 @@
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
|
|
||||||
use axum::{routing::{get, post}, Router};
|
|
||||||
use sea_orm::DatabaseConnection;
|
use sea_orm::DatabaseConnection;
|
||||||
use crate::activitypub as ap;
|
|
||||||
|
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
pub struct Context(Arc<ContextInner>);
|
pub struct Context(Arc<ContextInner>);
|
||||||
|
|
Loading…
Reference in a new issue