feat: added object feed endpoints
This commit is contained in:
parent
88915adff7
commit
07e537e454
4 changed files with 97 additions and 13 deletions
47
upub/routes/src/activitypub/actor/feed.rs
Normal file
47
upub/routes/src/activitypub/actor/feed.rs
Normal file
|
@ -0,0 +1,47 @@
|
||||||
|
use axum::extract::{Path, Query, State};
|
||||||
|
use sea_orm::{sea_query::IntoCondition, ColumnTrait};
|
||||||
|
|
||||||
|
use upub::Context;
|
||||||
|
|
||||||
|
use crate::{activitypub::Pagination, builders::JsonLD, AuthIdentity, Identity};
|
||||||
|
|
||||||
|
pub async fn get(
|
||||||
|
State(ctx): State<Context>,
|
||||||
|
Path(id): Path<String>,
|
||||||
|
AuthIdentity(auth): AuthIdentity,
|
||||||
|
) -> crate::ApiResult<JsonLD<serde_json::Value>> {
|
||||||
|
match auth {
|
||||||
|
Identity::Anonymous => Err(crate::ApiError::forbidden()),
|
||||||
|
Identity::Remote { .. } => Err(crate::ApiError::forbidden()),
|
||||||
|
Identity::Local { id: user, .. } => if ctx.uid(&id) == user {
|
||||||
|
crate::builders::collection(&upub::url!(ctx, "/actors/{id}/feed"), None)
|
||||||
|
} else {
|
||||||
|
Err(crate::ApiError::forbidden())
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub async fn page(
|
||||||
|
State(ctx): State<Context>,
|
||||||
|
Path(id): Path<String>,
|
||||||
|
AuthIdentity(auth): AuthIdentity,
|
||||||
|
Query(page): Query<Pagination>,
|
||||||
|
) -> crate::ApiResult<JsonLD<serde_json::Value>> {
|
||||||
|
let Identity::Local { id: uid, internal } = &auth else {
|
||||||
|
// local inbox is only for local users
|
||||||
|
return Err(crate::ApiError::forbidden());
|
||||||
|
};
|
||||||
|
if uid != &ctx.uid(&id) {
|
||||||
|
return Err(crate::ApiError::forbidden());
|
||||||
|
}
|
||||||
|
|
||||||
|
crate::builders::paginate_activities(
|
||||||
|
upub::url!(ctx, "/actors/{id}/feed/page"),
|
||||||
|
upub::model::addressing::Column::Actor.eq(*internal).into_condition(),
|
||||||
|
ctx.db(),
|
||||||
|
page,
|
||||||
|
auth.my_id(),
|
||||||
|
false,
|
||||||
|
)
|
||||||
|
.await
|
||||||
|
}
|
|
@ -23,6 +23,10 @@ pub async fn view(
|
||||||
.set_actor_type(Some(apb::ActorType::Application))
|
.set_actor_type(Some(apb::ActorType::Application))
|
||||||
.set_name(Some(&ctx.cfg().instance.name))
|
.set_name(Some(&ctx.cfg().instance.name))
|
||||||
.set_summary(Some(&ctx.cfg().instance.description))
|
.set_summary(Some(&ctx.cfg().instance.description))
|
||||||
|
.set_streams(apb::Node::links(vec![
|
||||||
|
upub::url!(ctx, "/feed"),
|
||||||
|
upub::url!(ctx, "/local"),
|
||||||
|
]))
|
||||||
.set_inbox(apb::Node::link(upub::url!(ctx, "/inbox")))
|
.set_inbox(apb::Node::link(upub::url!(ctx, "/inbox")))
|
||||||
.set_outbox(apb::Node::link(upub::url!(ctx, "/outbox")))
|
.set_outbox(apb::Node::link(upub::url!(ctx, "/outbox")))
|
||||||
.set_published(Some(ctx.actor().published))
|
.set_published(Some(ctx.actor().published))
|
||||||
|
|
29
upub/routes/src/activitypub/feed.rs
Normal file
29
upub/routes/src/activitypub/feed.rs
Normal file
|
@ -0,0 +1,29 @@
|
||||||
|
use axum::extract::{Query, State};
|
||||||
|
use upub::Context;
|
||||||
|
|
||||||
|
use crate::{AuthIdentity, builders::JsonLD};
|
||||||
|
|
||||||
|
use super::Pagination;
|
||||||
|
|
||||||
|
|
||||||
|
pub async fn get(
|
||||||
|
State(ctx): State<Context>,
|
||||||
|
) -> crate::ApiResult<JsonLD<serde_json::Value>> {
|
||||||
|
crate::builders::collection(&upub::url!(ctx, "/feed"), None)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub async fn page(
|
||||||
|
State(ctx): State<Context>,
|
||||||
|
AuthIdentity(auth): AuthIdentity,
|
||||||
|
Query(page): Query<Pagination>,
|
||||||
|
) -> crate::ApiResult<JsonLD<serde_json::Value>> {
|
||||||
|
crate::builders::paginate_objects(
|
||||||
|
upub::url!(ctx, "/feed/page"),
|
||||||
|
auth.filter_objects(),
|
||||||
|
ctx.db(),
|
||||||
|
page,
|
||||||
|
auth.my_id(),
|
||||||
|
false,
|
||||||
|
)
|
||||||
|
.await
|
||||||
|
}
|
|
@ -1,6 +1,7 @@
|
||||||
pub mod user;
|
pub mod actor;
|
||||||
pub mod inbox;
|
pub mod inbox;
|
||||||
pub mod outbox;
|
pub mod outbox;
|
||||||
|
pub mod feed;
|
||||||
pub mod object;
|
pub mod object;
|
||||||
pub mod activity;
|
pub mod activity;
|
||||||
pub mod application;
|
pub mod application;
|
||||||
|
@ -24,13 +25,14 @@ impl ActivityPubRouter for Router<upub::Context> {
|
||||||
.route("/proxy", post(ap::application::proxy_form))
|
.route("/proxy", post(ap::application::proxy_form))
|
||||||
.route("/proxy", get(ap::application::proxy_get))
|
.route("/proxy", get(ap::application::proxy_get))
|
||||||
.route("/proxy/:uri", get(ap::application::proxy_path))
|
.route("/proxy/:uri", get(ap::application::proxy_path))
|
||||||
// TODO shared inboxes and instance stream will come later, just use users *boxes for now
|
|
||||||
.route("/inbox", post(ap::inbox::post))
|
.route("/inbox", post(ap::inbox::post))
|
||||||
.route("/inbox", get(ap::inbox::get))
|
.route("/inbox", get(ap::inbox::get))
|
||||||
.route("/inbox/page", get(ap::inbox::page))
|
.route("/inbox/page", get(ap::inbox::page))
|
||||||
.route("/outbox", post(ap::outbox::post))
|
.route("/outbox", post(ap::outbox::post))
|
||||||
.route("/outbox", get(ap::outbox::get))
|
.route("/outbox", get(ap::outbox::get))
|
||||||
.route("/outbox/page", get(ap::outbox::page))
|
.route("/outbox/page", get(ap::outbox::page))
|
||||||
|
.route("/feed", get(ap::feed::get))
|
||||||
|
.route("/feed/page", get(ap::feed::page))
|
||||||
// AUTH routes
|
// AUTH routes
|
||||||
.route("/auth", put(ap::auth::register))
|
.route("/auth", put(ap::auth::register))
|
||||||
.route("/auth", post(ap::auth::login))
|
.route("/auth", post(ap::auth::login))
|
||||||
|
@ -42,17 +44,19 @@ impl ActivityPubRouter for Router<upub::Context> {
|
||||||
.route("/.well-known/oauth-authorization-server", get(ap::well_known::oauth_authorization_server))
|
.route("/.well-known/oauth-authorization-server", get(ap::well_known::oauth_authorization_server))
|
||||||
.route("/nodeinfo/:version", get(ap::well_known::nodeinfo))
|
.route("/nodeinfo/:version", get(ap::well_known::nodeinfo))
|
||||||
// actor routes
|
// actor routes
|
||||||
.route("/actors/:id", get(ap::user::view))
|
.route("/actors/:id", get(ap::actor::view))
|
||||||
.route("/actors/:id/inbox", post(ap::user::inbox::post))
|
.route("/actors/:id/inbox", post(ap::actor::inbox::post))
|
||||||
.route("/actors/:id/inbox", get(ap::user::inbox::get))
|
.route("/actors/:id/inbox", get(ap::actor::inbox::get))
|
||||||
.route("/actors/:id/inbox/page", get(ap::user::inbox::page))
|
.route("/actors/:id/inbox/page", get(ap::actor::inbox::page))
|
||||||
.route("/actors/:id/outbox", post(ap::user::outbox::post))
|
.route("/actors/:id/outbox", post(ap::actor::outbox::post))
|
||||||
.route("/actors/:id/outbox", get(ap::user::outbox::get))
|
.route("/actors/:id/outbox", get(ap::actor::outbox::get))
|
||||||
.route("/actors/:id/outbox/page", get(ap::user::outbox::page))
|
.route("/actors/:id/outbox/page", get(ap::actor::outbox::page))
|
||||||
.route("/actors/:id/followers", get(ap::user::following::get::<false>))
|
.route("/actors/:id/feed", get(ap::actor::feed::get))
|
||||||
.route("/actors/:id/followers/page", get(ap::user::following::page::<false>))
|
.route("/actors/:id/feed/page", get(ap::actor::feed::page))
|
||||||
.route("/actors/:id/following", get(ap::user::following::get::<true>))
|
.route("/actors/:id/followers", get(ap::actor::following::get::<false>))
|
||||||
.route("/actors/:id/following/page", get(ap::user::following::page::<true>))
|
.route("/actors/:id/followers/page", get(ap::actor::following::page::<false>))
|
||||||
|
.route("/actors/:id/following", get(ap::actor::following::get::<true>))
|
||||||
|
.route("/actors/:id/following/page", get(ap::actor::following::page::<true>))
|
||||||
// activities
|
// activities
|
||||||
.route("/activities/:id", get(ap::activity::view))
|
.route("/activities/:id", get(ap::activity::view))
|
||||||
// specific object routes
|
// specific object routes
|
||||||
|
|
Loading…
Reference in a new issue