fix: finish porting outbox
This commit is contained in:
parent
bbca51a34b
commit
9a04a67d39
1 changed files with 52 additions and 54 deletions
|
@ -1,8 +1,8 @@
|
||||||
use apb::{target::Addressed, Activity, ActivityMut, ActorMut, Base, BaseMut, Node, Object, ObjectMut, PublicKeyMut};
|
use apb::{target::Addressed, Activity, ActivityMut, Base, BaseMut, Node, Object, ObjectMut};
|
||||||
use reqwest::StatusCode;
|
use reqwest::StatusCode;
|
||||||
use sea_orm::{sea_query::Expr, ActiveModelTrait, ActiveValue::{Set, NotSet}, ColumnTrait, EntityTrait, IntoActiveModel, QueryFilter, QuerySelect, SelectColumns};
|
use sea_orm::{sea_query::Expr, ActiveValue::{Set, NotSet, Unchanged}, ColumnTrait, EntityTrait, IntoActiveModel, QueryFilter, QuerySelect, SelectColumns};
|
||||||
|
|
||||||
use crate::{errors::UpubError, model, routes::activitypub::jsonld::LD};
|
use crate::{errors::UpubError, model};
|
||||||
|
|
||||||
use super::{fetcher::Fetcher, normalizer::Normalizer, Context};
|
use super::{fetcher::Fetcher, normalizer::Normalizer, Context};
|
||||||
|
|
||||||
|
@ -343,9 +343,18 @@ impl apb::server::Outbox for Context {
|
||||||
async fn update(&self, uid: String, activity: serde_json::Value) -> crate::Result<String> {
|
async fn update(&self, uid: String, activity: serde_json::Value) -> crate::Result<String> {
|
||||||
let aid = self.aid(&uuid::Uuid::new_v4().to_string());
|
let aid = self.aid(&uuid::Uuid::new_v4().to_string());
|
||||||
let object_node = activity.object().extract().ok_or_else(UpubError::bad_request)?;
|
let object_node = activity.object().extract().ok_or_else(UpubError::bad_request)?;
|
||||||
|
let addressed = activity.addressed();
|
||||||
let target = object_node.id().ok_or_else(UpubError::bad_request)?.to_string();
|
let target = object_node.id().ok_or_else(UpubError::bad_request)?.to_string();
|
||||||
|
|
||||||
|
let activity_model = model::activity::ActiveModel::new(
|
||||||
|
&activity
|
||||||
|
.set_id(Some(&aid))
|
||||||
|
.set_actor(Node::link(uid.clone()))
|
||||||
|
)?;
|
||||||
|
|
||||||
|
model::activity::Entity::insert(activity_model)
|
||||||
|
.exec(self.db()).await?;
|
||||||
|
|
||||||
match object_node.object_type() {
|
match object_node.object_type() {
|
||||||
Some(apb::ObjectType::Actor(_)) => {
|
Some(apb::ObjectType::Actor(_)) => {
|
||||||
let old_actor_model = model::actor::Entity::find_by_ap_id(&target)
|
let old_actor_model = model::actor::Entity::find_by_ap_id(&target)
|
||||||
|
@ -359,68 +368,56 @@ impl apb::server::Outbox for Context {
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut new_actor_model = model::actor::ActiveModel::default();
|
let mut new_actor_model = model::actor::ActiveModel::default();
|
||||||
new_actor_model.internal = Set(old_actor_model.internal);
|
new_actor_model.internal = Unchanged(old_actor_model.internal);
|
||||||
|
|
||||||
if actor_model.name.is_none() { actor_model.name = old_actor_model.name }
|
if let Some(name) = object_node.name() {
|
||||||
if actor_model.summary.is_none() { actor_model.summary = old_actor_model.summary }
|
new_actor_model.name = Set(Some(name.to_string()));
|
||||||
if actor_model.image.is_none() { actor_model.image = old_actor_model.image }
|
}
|
||||||
if actor_model.icon.is_none() { actor_model.icon = old_actor_model.icon }
|
if let Some(summary) = object_node.summary() {
|
||||||
|
new_actor_model.summary = Set(Some(summary.to_string()));
|
||||||
|
}
|
||||||
|
if let Some(image) = object_node.image().id() {
|
||||||
|
new_actor_model.image = Set(Some(image));
|
||||||
|
}
|
||||||
|
if let Some(icon) = object_node.icon().id() {
|
||||||
|
new_actor_model.icon = Set(Some(icon));
|
||||||
|
}
|
||||||
|
new_actor_model.updated = Set(chrono::Utc::now());
|
||||||
|
|
||||||
let mut update_model = actor_model.into_active_model();
|
model::actor::Entity::update(new_actor_model)
|
||||||
update_model.updated = sea_orm::Set(chrono::Utc::now());
|
|
||||||
update_model.reset(model::actor::Column::Name);
|
|
||||||
update_model.reset(model::actor::Column::Summary);
|
|
||||||
update_model.reset(model::actor::Column::Image);
|
|
||||||
update_model.reset(model::actor::Column::Icon);
|
|
||||||
|
|
||||||
model::actor::Entity::update(update_model)
|
|
||||||
.exec(self.db()).await?;
|
.exec(self.db()).await?;
|
||||||
},
|
},
|
||||||
Some(apb::ObjectType::Note) => {
|
Some(apb::ObjectType::Note) => {
|
||||||
let mut object_model = model::object::Model::new(
|
let old_object_model = model::object::Entity::find_by_ap_id(&target)
|
||||||
&object_node.set_published(Some(chrono::Utc::now()))
|
|
||||||
)?;
|
|
||||||
|
|
||||||
let old_object_model = model::object::Entity::find_by_id(&object_model.id)
|
|
||||||
.one(self.db())
|
.one(self.db())
|
||||||
.await?
|
.await?
|
||||||
.ok_or_else(UpubError::not_found)?;
|
.ok_or_else(UpubError::not_found)?;
|
||||||
|
|
||||||
// can't change local objects attributed to nobody
|
if uid != old_object_model.attributed_to.ok_or_else(UpubError::forbidden)? {
|
||||||
let author_id = old_object_model.attributed_to.ok_or_else(UpubError::forbidden)?;
|
|
||||||
if author_id != uid {
|
|
||||||
// can't change objects of others
|
// can't change objects of others
|
||||||
return Err(UpubError::forbidden());
|
return Err(UpubError::forbidden());
|
||||||
}
|
}
|
||||||
|
|
||||||
if object_model.name.is_none() { object_model.name = old_object_model.name }
|
let mut new_object_model = model::object::ActiveModel::default();
|
||||||
if object_model.summary.is_none() { object_model.summary = old_object_model.summary }
|
new_object_model.internal = Unchanged(old_object_model.internal);
|
||||||
if object_model.content.is_none() { object_model.content = old_object_model.content }
|
|
||||||
|
|
||||||
let mut update_model = object_model.into_active_model();
|
if let Some(name) = object_node.name() {
|
||||||
update_model.updated = sea_orm::Set(Some(chrono::Utc::now()));
|
new_object_model.name = Set(Some(name.to_string()));
|
||||||
update_model.reset(model::object::Column::Name);
|
}
|
||||||
update_model.reset(model::object::Column::Summary);
|
if let Some(summary) = object_node.summary() {
|
||||||
update_model.reset(model::object::Column::Content);
|
new_object_model.summary = Set(Some(summary.to_string()));
|
||||||
update_model.reset(model::object::Column::Sensitive);
|
}
|
||||||
|
if let Some(content) = object_node.content() {
|
||||||
|
new_object_model.content = Set(Some(content.to_string()));
|
||||||
|
}
|
||||||
|
new_object_model.updated = Set(chrono::Utc::now());
|
||||||
|
|
||||||
model::object::Entity::update(update_model)
|
model::object::Entity::update(new_object_model)
|
||||||
.exec(self.db()).await?;
|
.exec(self.db()).await?;
|
||||||
},
|
},
|
||||||
_ => return Err(UpubError::Status(StatusCode::NOT_IMPLEMENTED)),
|
_ => return Err(UpubError::Status(StatusCode::NOT_IMPLEMENTED)),
|
||||||
}
|
}
|
||||||
|
|
||||||
let addressed = activity.addressed();
|
|
||||||
let activity_model = model::activity::Model::new(
|
|
||||||
&activity
|
|
||||||
.set_id(Some(&aid))
|
|
||||||
.set_actor(Node::link(uid.clone()))
|
|
||||||
.set_published(Some(chrono::Utc::now()))
|
|
||||||
)?;
|
|
||||||
|
|
||||||
model::activity::Entity::insert(activity_model.into_active_model())
|
|
||||||
.exec(self.db()).await?;
|
|
||||||
|
|
||||||
self.dispatch(&uid, addressed, &aid, None).await?;
|
self.dispatch(&uid, addressed, &aid, None).await?;
|
||||||
|
|
||||||
Ok(aid)
|
Ok(aid)
|
||||||
|
@ -430,26 +427,27 @@ impl apb::server::Outbox for Context {
|
||||||
let aid = self.aid(&uuid::Uuid::new_v4().to_string());
|
let aid = self.aid(&uuid::Uuid::new_v4().to_string());
|
||||||
let activity_targets = activity.addressed();
|
let activity_targets = activity.addressed();
|
||||||
let oid = activity.object().id().ok_or_else(UpubError::bad_request)?;
|
let oid = activity.object().id().ok_or_else(UpubError::bad_request)?;
|
||||||
self.fetch_object(&oid).await?;
|
let obj = self.fetch_object(&oid).await?;
|
||||||
let activity_model = model::activity::Model::new(
|
let internal_uid = model::actor::Entity::ap_to_internal(&uid, self.db()).await?;
|
||||||
|
|
||||||
|
let activity_model = model::activity::ActiveModel::new(
|
||||||
&activity
|
&activity
|
||||||
.set_id(Some(&aid))
|
.set_id(Some(&aid))
|
||||||
.set_published(Some(chrono::Utc::now()))
|
|
||||||
.set_actor(Node::link(uid.clone()))
|
.set_actor(Node::link(uid.clone()))
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
let share_model = model::announce::ActiveModel {
|
let share_model = model::announce::ActiveModel {
|
||||||
internal: NotSet,
|
internal: NotSet,
|
||||||
actor: Set(uid.clone()),
|
actor: Set(internal_uid),
|
||||||
object: Set(oid.clone()),
|
object: Set(obj.internal),
|
||||||
published: Set(chrono::Utc::now()),
|
published: Set(chrono::Utc::now()),
|
||||||
};
|
};
|
||||||
model::announce::Entity::insert(share_model).exec(self.db()).await?;
|
model::activity::Entity::insert(activity_model)
|
||||||
model::activity::Entity::insert(activity_model.into_active_model())
|
|
||||||
.exec(self.db()).await?;
|
.exec(self.db()).await?;
|
||||||
|
model::announce::Entity::insert(share_model).exec(self.db()).await?;
|
||||||
model::object::Entity::update_many()
|
model::object::Entity::update_many()
|
||||||
.col_expr(model::object::Column::Announces, Expr::col(model::object::Column::Announces).add(1))
|
.col_expr(model::object::Column::Announces, Expr::col(model::object::Column::Announces).add(1))
|
||||||
.filter(model::object::Column::Id.eq(oid))
|
.filter(model::object::Column::Internal.eq(obj.internal))
|
||||||
.exec(self.db())
|
.exec(self.db())
|
||||||
.await?;
|
.await?;
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue