forked from alemi/upub
chore: merge branch 'dev' of alemi.dev into dev
This commit is contained in:
commit
39add30876
3 changed files with 38 additions and 21 deletions
|
@ -40,6 +40,11 @@ pub async fn page(
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
macro_rules! pretty_json {
|
||||||
|
($json:ident) => {
|
||||||
|
serde_json::to_string_pretty(&$json).expect("failed serializing to string serde_json::Value")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
pub async fn post(
|
pub async fn post(
|
||||||
|
@ -47,16 +52,19 @@ pub async fn post(
|
||||||
AuthIdentity(auth): AuthIdentity,
|
AuthIdentity(auth): AuthIdentity,
|
||||||
Json(activity): Json<serde_json::Value>
|
Json(activity): Json<serde_json::Value>
|
||||||
) -> crate::Result<()> {
|
) -> crate::Result<()> {
|
||||||
|
if !matches!(auth, Identity::Remote(_)) {
|
||||||
|
tracing::warn!("refusing unauthorized activity: {}", pretty_json!(activity));
|
||||||
match auth {
|
match auth {
|
||||||
Identity::Remote(_server) => {},
|
|
||||||
Identity::Local(_user) => return Err(UpubError::forbidden()),
|
Identity::Local(_user) => return Err(UpubError::forbidden()),
|
||||||
Identity::Anonymous => return Err(UpubError::unauthorized()),
|
Identity::Anonymous => return Err(UpubError::unauthorized()),
|
||||||
|
_ => {},
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO we could process Links and bare Objects maybe, but probably out of AP spec?
|
// TODO we could process Links and bare Objects maybe, but probably out of AP spec?
|
||||||
match activity.activity_type().ok_or_else(UpubError::bad_request)? {
|
match activity.activity_type().ok_or_else(UpubError::bad_request)? {
|
||||||
ActivityType::Activity => {
|
ActivityType::Activity => {
|
||||||
tracing::warn!("skipping unprocessable base activity: {}", serde_json::to_string_pretty(&activity).unwrap());
|
tracing::warn!("skipping unprocessable base activity: {}", pretty_json!(activity));
|
||||||
Err(StatusCode::UNPROCESSABLE_ENTITY.into()) // won't ingest useless stuff
|
Err(StatusCode::UNPROCESSABLE_ENTITY.into()) // won't ingest useless stuff
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -71,7 +79,7 @@ pub async fn post(
|
||||||
// ActivityType::Announce => Ok(ctx.announce(activity).await?),
|
// ActivityType::Announce => Ok(ctx.announce(activity).await?),
|
||||||
|
|
||||||
_x => {
|
_x => {
|
||||||
tracing::info!("received unimplemented activity on inbox: {}", serde_json::to_string_pretty(&activity).unwrap());
|
tracing::info!("received unimplemented activity on inbox: {}", pretty_json!(activity));
|
||||||
Err(StatusCode::NOT_IMPLEMENTED.into())
|
Err(StatusCode::NOT_IMPLEMENTED.into())
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,7 +4,7 @@ use apb::{BaseMut, CollectionMut, CollectionPageMut};
|
||||||
use openssl::rsa::Rsa;
|
use openssl::rsa::Rsa;
|
||||||
use sea_orm::{ColumnTrait, DatabaseConnection, EntityTrait, QueryFilter, QuerySelect, SelectColumns, Set};
|
use sea_orm::{ColumnTrait, DatabaseConnection, EntityTrait, QueryFilter, QuerySelect, SelectColumns, Set};
|
||||||
|
|
||||||
use crate::{model, routes::activitypub::jsonld::LD};
|
use crate::{model, routes::activitypub::jsonld::LD, server::fetcher::Fetcher};
|
||||||
|
|
||||||
use super::dispatcher::Dispatcher;
|
use super::dispatcher::Dispatcher;
|
||||||
|
|
||||||
|
@ -176,23 +176,31 @@ impl Context {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn deliver_to(&self, aid: &str, from: &str, targets: &[String]) -> crate::Result<()> {
|
pub async fn deliver_to(&self, aid: &str, from: &str, targets: &[String]) -> crate::Result<()> {
|
||||||
let deliveries : Vec<model::delivery::ActiveModel> = targets
|
let mut deliveries = Vec::new();
|
||||||
.iter()
|
for target in targets.iter()
|
||||||
.filter(|to| !to.is_empty())
|
.filter(|to| !to.is_empty())
|
||||||
.filter(|to| Context::server(to) != self.base())
|
.filter(|to| Context::server(to) != self.base())
|
||||||
.filter(|to| to != &apb::target::PUBLIC)
|
.filter(|to| to != &apb::target::PUBLIC)
|
||||||
.map(|to| model::delivery::ActiveModel {
|
{
|
||||||
|
// TODO fetch concurrently
|
||||||
|
match self.fetch_user(target).await {
|
||||||
|
Ok(model::user::Model { inbox: Some(inbox), .. }) => deliveries.push(
|
||||||
|
model::delivery::ActiveModel {
|
||||||
id: sea_orm::ActiveValue::NotSet,
|
id: sea_orm::ActiveValue::NotSet,
|
||||||
actor: Set(from.to_string()),
|
actor: Set(from.to_string()),
|
||||||
// TODO we should resolve each user by id and check its inbox because we can't assume
|
// TODO we should resolve each user by id and check its inbox because we can't assume
|
||||||
// it's /users/{id}/inbox for every software, but oh well it's waaaaay easier now
|
// it's /users/{id}/inbox for every software, but oh well it's waaaaay easier now
|
||||||
target: Set(format!("{}/inbox", to)),
|
target: Set(inbox),
|
||||||
activity: Set(aid.to_string()),
|
activity: Set(aid.to_string()),
|
||||||
created: Set(chrono::Utc::now()),
|
created: Set(chrono::Utc::now()),
|
||||||
not_before: Set(chrono::Utc::now()),
|
not_before: Set(chrono::Utc::now()),
|
||||||
attempt: Set(0),
|
attempt: Set(0),
|
||||||
})
|
}
|
||||||
.collect();
|
),
|
||||||
|
Ok(_) => tracing::error!("resolved target but missing inbox: '{target}', skipping delivery"),
|
||||||
|
Err(e) => tracing::error!("failed resolving target inbox: {e}, skipping delivery to '{target}'"),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if !deliveries.is_empty() {
|
if !deliveries.is_empty() {
|
||||||
model::delivery::Entity::insert_many(deliveries)
|
model::delivery::Entity::insert_many(deliveries)
|
||||||
|
|
|
@ -149,6 +149,7 @@ impl apb::server::Inbox for Context {
|
||||||
async fn delete(&self, activity: serde_json::Value) -> crate::Result<()> {
|
async fn delete(&self, activity: serde_json::Value) -> crate::Result<()> {
|
||||||
// TODO verify the signature before just deleting lmao
|
// TODO verify the signature before just deleting lmao
|
||||||
let oid = activity.object().id().ok_or(UpubError::bad_request())?;
|
let oid = activity.object().id().ok_or(UpubError::bad_request())?;
|
||||||
|
tracing::info!("deleting '{oid}'");
|
||||||
// TODO maybe we should keep the tombstone?
|
// TODO maybe we should keep the tombstone?
|
||||||
model::user::Entity::delete_by_id(&oid).exec(self.db()).await.info_failed("failed deleting from users");
|
model::user::Entity::delete_by_id(&oid).exec(self.db()).await.info_failed("failed deleting from users");
|
||||||
model::activity::Entity::delete_by_id(&oid).exec(self.db()).await.info_failed("failed deleting from activities");
|
model::activity::Entity::delete_by_id(&oid).exec(self.db()).await.info_failed("failed deleting from activities");
|
||||||
|
|
Loading…
Reference in a new issue