hyaenidae/profiles/src/apub/actions/apub/like.rs
asonix 29bdf064e9 Profiles: Update profile delete to profile suspend
Clear profile data on suspend
Clear comment body on delete
Update Unfollow and Unblock operations to only delete apub IDs if present
2021-01-14 20:41:53 -06:00

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 })))
}