asonix
83b447b780
- Fix image federation - Enable submission & comment create/update federation - Improve checks to ensure we don't federate when we don't need to
130 lines
4 KiB
Rust
130 lines
4 KiB
Rust
use crate::{
|
|
apub::actions::{apub::require_federation, CreateReact, DeleteReact},
|
|
recover, Action, Context, Error, KeyOwner, RecoverableError, Required,
|
|
};
|
|
use activitystreams::prelude::*;
|
|
|
|
pub(crate) fn like(
|
|
like: &activitystreams::activity::Like,
|
|
key_owner: Option<KeyOwner>,
|
|
ctx: &Context,
|
|
) -> Result<Result<Box<dyn Action>, RecoverableError>, Error> {
|
|
let like_id = like.id_unchecked().req("like id")?;
|
|
|
|
// Double create
|
|
if ctx.apub.object(like_id)?.is_some() {
|
|
return Err(Error::Invalid);
|
|
}
|
|
|
|
let actor = like.actor()?.as_single_id().req("like actor id")?;
|
|
require_federation(key_owner, actor, ctx)?;
|
|
|
|
let object = like.object().as_single_id().req("like object id")?;
|
|
let react = like
|
|
.content()
|
|
.req("content")?
|
|
.as_single_xsd_string()
|
|
.req("content string")?;
|
|
let published = like.published().req("published")?;
|
|
|
|
let actor_id = recover!(actor, ctx.apub.id_for_apub(actor)?);
|
|
let actor_id = actor_id.profile().req("like actor id as profile id")?;
|
|
if let Some(actor_profile) = ctx.store.profiles.by_id(actor_id)? {
|
|
if actor_profile.is_suspended() {
|
|
return Err(Error::Invalid);
|
|
}
|
|
} else {
|
|
return Err(Error::Invalid);
|
|
}
|
|
|
|
let object_id = recover!(object, ctx.apub.id_for_apub(object)?);
|
|
|
|
if let Some(submission_id) = object_id.submission() {
|
|
return Ok(Ok(Box::new(CreateReact {
|
|
like_apub_id: Some(like_id.to_owned()),
|
|
submission_id,
|
|
profile_id: actor_id,
|
|
comment_id: None,
|
|
react: react.to_owned(),
|
|
published: published.into(),
|
|
})));
|
|
}
|
|
|
|
if let Some(comment_id) = object_id.comment() {
|
|
let submission_id = ctx
|
|
.store
|
|
.comments
|
|
.by_id(comment_id)?
|
|
.req("comment by id")?
|
|
.submission_id();
|
|
|
|
return Ok(Ok(Box::new(CreateReact {
|
|
like_apub_id: Some(like_id.to_owned()),
|
|
submission_id,
|
|
profile_id: actor_id,
|
|
comment_id: Some(comment_id),
|
|
react: react.to_owned(),
|
|
published: published.into(),
|
|
})));
|
|
}
|
|
|
|
Err(Error::Invalid)
|
|
}
|
|
|
|
pub(crate) fn undo_like(
|
|
undo: &activitystreams::activity::Undo,
|
|
like: &activitystreams::activity::Like,
|
|
key_owner: Option<KeyOwner>,
|
|
ctx: &Context,
|
|
) -> Result<Result<Box<dyn Action>, RecoverableError>, Error> {
|
|
let like_id = like.id_unchecked().req("like id")?;
|
|
let undo_actor_id = undo.actor()?.as_single_id().req("undo actor id")?;
|
|
require_federation(key_owner, undo_actor_id, ctx)?;
|
|
|
|
let actor_id = like.actor()?.as_single_id().req("like actor id")?;
|
|
|
|
if undo_actor_id != actor_id {
|
|
return Err(Error::Invalid);
|
|
}
|
|
|
|
let actor_id = recover!(actor_id, ctx.apub.id_for_apub(actor_id)?);
|
|
let actor_id = actor_id.profile().req("like actor id as profile id")?;
|
|
if let Some(actor_profile) = ctx.store.profiles.by_id(actor_id)? {
|
|
if actor_profile.is_suspended() {
|
|
return Err(Error::Invalid);
|
|
}
|
|
} else {
|
|
return Err(Error::Invalid);
|
|
}
|
|
|
|
let object_id = like.object().as_single_id().req("like object id")?;
|
|
let object_id = recover!(object_id, ctx.apub.id_for_apub(object_id)?);
|
|
|
|
let react_id = recover!(like_id, ctx.apub.id_for_apub(like_id)?);
|
|
let react_id = react_id.react().req("like id as react id")?;
|
|
|
|
let react = ctx.store.reacts.by_id(react_id)?.req("react by id")?;
|
|
|
|
if react.profile_id() != actor_id {
|
|
return Err(Error::Invalid);
|
|
}
|
|
|
|
if let Some(comment_id) = react.comment_id() {
|
|
let object_id = object_id.comment().req("like object id as comment id")?;
|
|
|
|
if comment_id != object_id {
|
|
return Err(Error::Invalid);
|
|
}
|
|
} else {
|
|
let object_id = object_id
|
|
.submission()
|
|
.req("like object id as submission id")?;
|
|
|
|
if react.submission_id() != object_id {
|
|
return Err(Error::Invalid);
|
|
}
|
|
}
|
|
|
|
Ok(Ok(Box::new(DeleteReact { react_id })))
|
|
}
|