asonix
29bdf064e9
Clear profile data on suspend Clear comment body on delete Update Unfollow and Unblock operations to only delete apub IDs if present
113 lines
3.4 KiB
Rust
113 lines
3.4 KiB
Rust
use crate::{
|
|
apub::actions::{CreateReact, DeleteReact},
|
|
recover, Action, Context, Error, RecoverableError, Required,
|
|
};
|
|
use activitystreams::prelude::*;
|
|
|
|
pub(crate) fn like(
|
|
like: &activitystreams::activity::Like,
|
|
ctx: &Context,
|
|
) -> Result<Result<Box<dyn Action>, RecoverableError>, Error> {
|
|
let like_id = like.id_unchecked().req()?;
|
|
|
|
// Double create
|
|
if ctx.apub.object(like_id)?.is_some() {
|
|
return Err(Error::Invalid);
|
|
}
|
|
|
|
let actor = like.actor()?.as_single_id().req()?;
|
|
let object = like.object().as_single_id().req()?;
|
|
let react = like.content().req()?.as_single_xsd_string().req()?;
|
|
let published = like.published().req()?;
|
|
|
|
let actor_id = recover!(actor, ctx.apub.id_for_apub(actor)?);
|
|
let actor_id = actor_id.profile().req()?;
|
|
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!(actor, 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()?.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,
|
|
ctx: &Context,
|
|
) -> Result<Result<Box<dyn Action>, RecoverableError>, Error> {
|
|
let like_id = like.id_unchecked().req()?;
|
|
let undo_actor_id = undo.actor()?.as_single_id().req()?;
|
|
let actor_id = like.actor()?.as_single_id().req()?;
|
|
|
|
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()?;
|
|
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()?;
|
|
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()?;
|
|
|
|
let react = ctx.store.reacts.by_id(react_id)?.req()?;
|
|
|
|
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()?;
|
|
|
|
if comment_id != object_id {
|
|
return Err(Error::Invalid);
|
|
}
|
|
} else {
|
|
let object_id = object_id.submission().req()?;
|
|
|
|
if react.submission_id() != object_id {
|
|
return Err(Error::Invalid);
|
|
}
|
|
}
|
|
|
|
Ok(Ok(Box::new(DeleteReact { react_id })))
|
|
}
|