Prepare Actions for use outside of activitypub paths

Catch (but not fix) but related to unfollowing durin blocks
This commit is contained in:
asonix 2021-01-05 00:09:59 -06:00
parent 8552d10cdc
commit 6ffc4e9fa3
20 changed files with 539 additions and 313 deletions

View file

@ -36,7 +36,7 @@ pub(crate) fn block(
if let Some(true) = context.store.profiles.is_local(object)? { if let Some(true) = context.store.profiles.is_local(object)? {
return Ok(Ok(Box::new(CreateBlock { return Ok(Ok(Box::new(CreateBlock {
apub_id: id.to_owned(), block_apub_id: Some(id.to_owned()),
blocked_profile: object, blocked_profile: object,
blocked_by_profile: actor, blocked_by_profile: actor,
published: published.into(), published: published.into(),
@ -59,12 +59,8 @@ pub(crate) fn undo_block(
} }
let block_id = block.id_unchecked().req()?; let block_id = block.id_unchecked().req()?;
let id = recover!(block_id, context.apub.id_for_apub(block_id)?); let id = recover!(block_id, context.apub.id_for_apub(block_id)?);
let id = id.block().req()?; let id = id.block().req()?;
Ok(Ok(Box::new(DeleteBlock { Ok(Ok(Box::new(DeleteBlock { block_id: id })))
apub_id: block_id.to_owned(),
block_id: id,
})))
} }

View file

@ -1,7 +1,7 @@
use crate::{ use crate::{
apub::actions::{ apub::actions::{
AcceptFollowRequest, CreateFollowRequest, DeleteFollow, DeleteFollowRequest, AcceptFollowRequest, CreateFollowRequest, RejectFollowRequest, UndoAcceptFollow,
RejectFollowRequest, UndoFollow, UndoFollowRequest,
}, },
recover, recover,
store::view::Relationship, store::view::Relationship,
@ -52,7 +52,7 @@ pub(crate) fn follow(
let object = object.profile().req()?; let object = object.profile().req()?;
Ok(Ok(Box::new(CreateFollowRequest { Ok(Ok(Box::new(CreateFollowRequest {
apub_id: follow_id.to_owned(), follow_apub_id: Some(follow_id.to_owned()),
followed_profile: object, followed_profile: object,
followed_by_profile: actor, followed_by_profile: actor,
published: published.into(), published: published.into(),
@ -81,7 +81,6 @@ pub(crate) fn reject_follow(
} }
Ok(Ok(Box::new(RejectFollowRequest { Ok(Ok(Box::new(RejectFollowRequest {
apub_id: follow_id.to_owned(),
follow_request_id: id, follow_request_id: id,
}))) })))
} }
@ -111,7 +110,7 @@ pub(crate) fn accept_follow(
} }
Ok(Ok(Box::new(AcceptFollowRequest { Ok(Ok(Box::new(AcceptFollowRequest {
apub_id: accept_id.to_owned(), accept_apub_id: Some(accept_id.to_owned()),
follow_request_id: id, follow_request_id: id,
published: published.into(), published: published.into(),
}))) })))
@ -146,8 +145,8 @@ pub(crate) fn undo_follow(
.by_forward(follow_object, follow_actor)?; .by_forward(follow_object, follow_actor)?;
if let Some(follow_id) = follow_id_opt { if let Some(follow_id) = follow_id_opt {
return Ok(Ok(Box::new(DeleteFollow { return Ok(Ok(Box::new(UndoFollow {
apub_id: follow_object_id.to_owned(), follow_apub_id: follow_object_id.to_owned(),
follow_id, follow_id,
}))); })));
} }
@ -159,10 +158,7 @@ pub(crate) fn undo_follow(
.by_forward(follow_object, follow_actor)? .by_forward(follow_object, follow_actor)?
.req()?; .req()?;
Ok(Ok(Box::new(DeleteFollowRequest { Ok(Ok(Box::new(UndoFollowRequest { follow_request_id })))
apub_id: follow_object_id.to_owned(),
follow_request_id,
})))
} }
pub(crate) fn undo_accept_follow( pub(crate) fn undo_accept_follow(
@ -188,8 +184,8 @@ pub(crate) fn undo_accept_follow(
return Ok(Err(e)); return Ok(Err(e));
} }
Ok(Ok(Box::new(DeleteFollow { Ok(Ok(Box::new(UndoAcceptFollow {
apub_id: follow_id.to_owned(), follow_apub_id: follow_id.to_owned(),
follow_id: id, follow_id: id,
}))) })))
} }

View file

@ -27,7 +27,7 @@ pub(crate) fn like(
if let Some(submission_id) = object_id.submission() { if let Some(submission_id) = object_id.submission() {
return Ok(Ok(Box::new(CreateReact { return Ok(Ok(Box::new(CreateReact {
apub_id: like_id.to_owned(), like_apub_id: Some(like_id.to_owned()),
submission_id, submission_id,
profile_id: actor_id, profile_id: actor_id,
comment_id: None, comment_id: None,
@ -45,7 +45,7 @@ pub(crate) fn like(
.submission_id(); .submission_id();
return Ok(Ok(Box::new(CreateReact { return Ok(Ok(Box::new(CreateReact {
apub_id: like_id.to_owned(), like_apub_id: Some(like_id.to_owned()),
submission_id, submission_id,
profile_id: actor_id, profile_id: actor_id,
comment_id: Some(comment_id), comment_id: Some(comment_id),
@ -99,8 +99,5 @@ pub(crate) fn undo_like(
} }
} }
Ok(Ok(Box::new(DeleteReact { Ok(Ok(Box::new(DeleteReact { react_id })))
apub_id: like_id.to_owned(),
react_id,
})))
} }

View file

@ -62,7 +62,7 @@ pub(crate) fn note(
if let Some(submission_id) = in_reply_to.submission() { if let Some(submission_id) = in_reply_to.submission() {
return Ok(Ok(Box::new(CreateComment { return Ok(Ok(Box::new(CreateComment {
apub_id: note_id.to_owned(), note_apub_id: Some(note_id.to_owned()),
submission_id, submission_id,
profile_id, profile_id,
comment_id: None, comment_id: None,
@ -80,7 +80,7 @@ pub(crate) fn note(
.submission_id(); .submission_id();
return Ok(Ok(Box::new(CreateComment { return Ok(Ok(Box::new(CreateComment {
apub_id: note_id.to_owned(), note_apub_id: Some(note_id.to_owned()),
submission_id, submission_id,
profile_id, profile_id,
comment_id: Some(comment_id), comment_id: Some(comment_id),
@ -129,7 +129,7 @@ pub(crate) fn note(
} }
return Ok(Ok(Box::new(CreateSubmission { return Ok(Ok(Box::new(CreateSubmission {
apub_id: note_id.to_owned(), note_apub_id: Some(note_id.to_owned()),
profile_id, profile_id,
title: title.to_owned(), title: title.to_owned(),
description, description,
@ -198,6 +198,7 @@ pub(crate) fn update_note(
note: &activitystreams::object::Note, note: &activitystreams::object::Note,
context: &Context, context: &Context,
) -> Result<Result<Box<dyn Action>, RecoverableError>, Error> { ) -> Result<Result<Box<dyn Action>, RecoverableError>, Error> {
let update_id = update.id_unchecked().req()?;
let actor_id = update.actor()?.as_single_id().req()?; let actor_id = update.actor()?.as_single_id().req()?;
let attributed_to = note.attributed_to().req()?.as_single_id().req()?; let attributed_to = note.attributed_to().req()?.as_single_id().req()?;
@ -222,7 +223,11 @@ pub(crate) fn update_note(
.and_then(|c| c.as_single_xsd_string()) .and_then(|c| c.as_single_xsd_string())
.map(|s| s.to_owned()); .map(|s| s.to_owned());
return Ok(Ok(Box::new(UpdateComment { comment_id, body }))); return Ok(Ok(Box::new(UpdateComment {
update_apub_id: Some(update_id.to_owned()),
comment_id,
body,
})));
} }
let submission_id = note_id.submission().req()?; let submission_id = note_id.submission().req()?;
@ -304,7 +309,7 @@ pub(crate) fn delete_note(
} }
return Ok(Ok(Box::new(DeleteComment { return Ok(Ok(Box::new(DeleteComment {
apub_id: note_object_id.to_owned(), note_apub_id: note_object_id.to_owned(),
comment_id, comment_id,
}))); })));
} }
@ -316,8 +321,5 @@ pub(crate) fn delete_note(
return Err(Error::Invalid); return Err(Error::Invalid);
} }
Ok(Ok(Box::new(DeleteSubmission { Ok(Ok(Box::new(DeleteSubmission { submission_id })))
apub_id: note_object_id.to_owned(),
submission_id,
})))
} }

View file

@ -82,7 +82,7 @@ pub(crate) fn person(
.unwrap_or(true); .unwrap_or(true);
Ok(Ok(Box::new(CreateProfile { Ok(Ok(Box::new(CreateProfile {
apub_id: id.to_owned(), person_apub_id: Some(id.to_owned()),
owner_source: OwnerSource::Remote(id.to_string()), owner_source: OwnerSource::Remote(id.to_string()),
handle, handle,
domain, domain,
@ -177,8 +177,5 @@ pub(crate) fn delete_person(
let profile_id = recover!(id, context.apub.id_for_apub(id)?); let profile_id = recover!(id, context.apub.id_for_apub(id)?);
let profile_id = profile_id.profile().req()?; let profile_id = profile_id.profile().req()?;
Ok(Ok(Box::new(DeleteProfile { Ok(Ok(Box::new(DeleteProfile { profile_id })))
apub_id: id.to_owned(),
profile_id,
})))
} }

View file

@ -1,17 +1,19 @@
use crate::{ use crate::{
apub::actions::{CreateBlock, DeleteBlock, DeleteFollow, RejectFollowRequest}, apub::actions::{CreateBlock, DeleteBlock, RejectFollowRequest, UndoFollow},
Action, Context, Error, Required, Action, Completed, Context, Error, Required,
}; };
impl Action for CreateBlock { impl Action for CreateBlock {
fn perform(&self, context: &Context) -> Result<(), Error> { fn perform(&self, context: &Context) -> Result<Option<Box<dyn Completed>>, Error> {
let block = context.store.view.blocks.new( let block = context.store.view.blocks.new(
self.blocked_profile, self.blocked_profile,
self.blocked_by_profile, self.blocked_by_profile,
self.published, self.published,
)?; )?;
context.apub.block(&self.apub_id, block.id)?; if let Some(apub_id) = &self.block_apub_id {
context.apub.block(&apub_id, block.id)?;
}
if let Ok(Some(follow_request_id)) = context if let Ok(Some(follow_request_id)) = context
.store .store
@ -19,17 +21,7 @@ impl Action for CreateBlock {
.follow_requests .follow_requests
.by_forward(self.blocked_profile, self.blocked_by_profile) .by_forward(self.blocked_profile, self.blocked_by_profile)
{ {
let apub_id = context Action::perform(&RejectFollowRequest { follow_request_id }, context)?;
.apub
.apub_for_follow_request(follow_request_id)?
.req()?;
Action::perform(
&RejectFollowRequest {
apub_id,
follow_request_id,
},
context,
)?;
} }
if let Ok(Some(follow_request_id)) = context if let Ok(Some(follow_request_id)) = context
@ -38,17 +30,7 @@ impl Action for CreateBlock {
.follow_requests .follow_requests
.by_backward(self.blocked_by_profile, self.blocked_profile) .by_backward(self.blocked_by_profile, self.blocked_profile)
{ {
let apub_id = context Action::perform(&RejectFollowRequest { follow_request_id }, context)?;
.apub
.apub_for_follow_request(follow_request_id)?
.req()?;
Action::perform(
&RejectFollowRequest {
apub_id,
follow_request_id,
},
context,
)?;
} }
if let Ok(Some(follow_id)) = context if let Ok(Some(follow_id)) = context
@ -57,8 +39,17 @@ impl Action for CreateBlock {
.follows .follows
.by_forward(self.blocked_profile, self.blocked_by_profile) .by_forward(self.blocked_profile, self.blocked_by_profile)
{ {
let apub_id = context.apub.apub_for_follow(follow_id)?.req()?; unimplemented!();
Action::perform(&DeleteFollow { apub_id, follow_id }, context)?; /*
let follow_apub_id = context.apub.apub_for_follow_request(follow_id)?.req()?;
Action::perform(
&UndoFollow {
follow_apub_id,
follow_id,
},
context,
)?;
*/
} }
if let Ok(Some(follow_id)) = context if let Ok(Some(follow_id)) = context
@ -67,18 +58,44 @@ impl Action for CreateBlock {
.follows .follows
.by_backward(self.blocked_by_profile, self.blocked_profile) .by_backward(self.blocked_by_profile, self.blocked_profile)
{ {
let apub_id = context.apub.apub_for_follow(follow_id)?.req()?; unimplemented!();
Action::perform(&DeleteFollow { apub_id, follow_id }, context)?; /*
let follow_apub_id = context.apub.apub_for_follow_request(follow_id)?.req()?;
Action::perform(
&DeleteFollow {
follow_apub_id,
follow_id,
},
context,
)?;
*/
} }
Ok(()) if context.is_local(self.blocked_by_profile)? && !context.is_local(self.blocked_profile)? {
return Ok(Some(Box::new(crate::apub::results::Block {
block_id: block.id,
})));
}
Ok(None)
} }
} }
impl Action for DeleteBlock { impl Action for DeleteBlock {
fn perform(&self, context: &Context) -> Result<(), Error> { fn perform(&self, context: &Context) -> Result<Option<Box<dyn Completed>>, Error> {
context.store.view.blocks.remove(self.block_id)?; let opt = context.store.view.blocks.remove(self.block_id)?;
context.apub.delete_object(&self.apub_id)?; let block_apub_id = context.apub.apub_for_block(self.block_id)?.req()?;
Ok(()) context.apub.delete_object(&block_apub_id)?;
if let Some(undo_block) = opt {
if context.is_local(undo_block.0.right)? {
return Ok(Some(Box::new(crate::apub::results::UndoBlock {
block_apub_id,
profile_id: undo_block.0.right,
})));
}
}
Ok(None)
} }
} }

View file

@ -1,10 +1,10 @@
use crate::{ use crate::{
apub::actions::{AnnounceComment, CreateComment, DeleteComment, DeleteReact, UpdateComment}, apub::actions::{AnnounceComment, CreateComment, DeleteComment, DeleteReact, UpdateComment},
Action, Context, Error, Required, Action, Completed, Context, Error, Required,
}; };
impl Action for CreateComment { impl Action for CreateComment {
fn perform(&self, context: &Context) -> Result<(), Error> { fn perform(&self, context: &Context) -> Result<Option<Box<dyn Completed>>, Error> {
let submissioner_id = context let submissioner_id = context
.store .store
.submissions .submissions
@ -37,10 +37,12 @@ impl Action for CreateComment {
self.published, self.published,
)?; )?;
context.apub.comment(&self.apub_id, comment.id())?; if let Some(apub_id) = &self.note_apub_id {
context.apub.comment(apub_id, comment.id())?;
}
if let Some(commenter_id) = comment_data { if let Some(commenter_id) = comment_data {
if let Ok(Some(true)) = context.store.profiles.is_local(commenter_id) { if let Ok(true) = context.is_local(commenter_id) {
context context
.store .store
.view .view
@ -49,7 +51,7 @@ impl Action for CreateComment {
} }
}; };
if let Ok(Some(true)) = context.store.profiles.is_local(submissioner_id) { if let Ok(true) = context.is_local(submissioner_id) {
context context
.store .store
.view .view
@ -57,18 +59,33 @@ impl Action for CreateComment {
.new(submissioner_id, comment.id(), self.published); .new(submissioner_id, comment.id(), self.published);
} }
Ok(()) if context.is_local(self.profile_id)? {
return Ok(Some(Box::new(crate::apub::results::CommentCreated {
comment_id: comment.id(),
})));
}
if context.is_local(submissioner_id)? {
if let Some(apub_id) = &self.note_apub_id {
return Ok(Some(Box::new(crate::apub::results::RemoteCommentCreated {
note_apub_id: apub_id.clone(),
profile_id: submissioner_id,
})));
}
}
Ok(None)
} }
} }
impl Action for AnnounceComment { impl Action for AnnounceComment {
fn perform(&self, _: &Context) -> Result<(), Error> { fn perform(&self, _: &Context) -> Result<Option<Box<dyn Completed>>, Error> {
Ok(()) Ok(None)
} }
} }
impl Action for UpdateComment { impl Action for UpdateComment {
fn perform(&self, context: &Context) -> Result<(), Error> { fn perform(&self, context: &Context) -> Result<Option<Box<dyn Completed>>, Error> {
let comment = context.store.comments.by_id(self.comment_id)?.req()?; let comment = context.store.comments.by_id(self.comment_id)?.req()?;
let mut changes = comment.update(); let mut changes = comment.update();
@ -77,24 +94,45 @@ impl Action for UpdateComment {
} }
context.store.comments.update(&changes)?; context.store.comments.update(&changes)?;
Ok(()) if context.is_local(comment.profile_id())? {
return Ok(Some(Box::new(crate::apub::results::CommentUpdated {
comment_id: comment.id(),
})));
}
let submissioner_id = context
.store
.submissions
.by_id(comment.submission_id())?
.req()?
.profile_id();
if context.is_local(submissioner_id)? {
if let Some(apub_id) = &self.update_apub_id {
return Ok(Some(Box::new(crate::apub::results::RemoteCommentUpdated {
update_apub_id: apub_id.to_owned(),
profile_id: submissioner_id,
})));
}
}
Ok(None)
} }
} }
fn delete_react(react_id: uuid::Uuid, context: &Context) -> Result<(), Error> { fn delete_react(react_id: uuid::Uuid, context: &Context) -> Result<(), Error> {
let apub_id = context.apub.apub_for_react(react_id)?.req()?; Action::perform(&DeleteReact { react_id }, context)?;
Action::perform(&DeleteReact { apub_id, react_id }, context)?;
Ok(()) Ok(())
} }
impl Action for DeleteComment { impl Action for DeleteComment {
fn perform(&self, context: &Context) -> Result<(), Error> { fn perform(&self, context: &Context) -> Result<Option<Box<dyn Completed>>, Error> {
let opt = context.store.comments.delete(self.comment_id)?; let opt = context.store.comments.delete(self.comment_id)?;
context.store.view.comments.remove(self.comment_id); context.store.view.comments.remove(self.comment_id);
context.apub.delete_object(&self.apub_id)?; context.apub.delete_object(&self.note_apub_id)?;
if opt.is_some() { if let Some(undo_comment) = opt {
let comment_id = self.comment_id; let comment_id = undo_comment.0.id();
let context_clone = context.clone(); let context_clone = context.clone();
context.spawn_blocking(move || { context.spawn_blocking(move || {
@ -104,8 +142,28 @@ impl Action for DeleteComment {
} }
} }
}); });
if context.is_local(undo_comment.0.profile_id())? {
return Ok(Some(Box::new(crate::apub::results::CommentCreated {
comment_id: undo_comment.0.id(),
})));
}
let submissioner_id = context
.store
.submissions
.by_id(undo_comment.0.submission_id())?
.req()?
.profile_id();
if context.is_local(submissioner_id)? {
return Ok(Some(Box::new(crate::apub::results::RemoteCommentCreated {
note_apub_id: self.note_apub_id.clone(),
profile_id: submissioner_id,
})));
}
} }
Ok(()) Ok(None)
} }
} }

View file

@ -1,9 +1,44 @@
use crate::{apub::actions::DeleteFollow, Action, Context, Error}; use crate::{
apub::actions::{UndoAcceptFollow, UndoFollow},
Action, Completed, Context, Error, Required,
};
impl Action for DeleteFollow { impl Action for UndoFollow {
fn perform(&self, context: &Context) -> Result<(), Error> { fn perform(&self, context: &Context) -> Result<Option<Box<dyn Completed>>, Error> {
context.store.view.follows.remove(self.follow_id)?; let opt = context.store.view.follows.remove(self.follow_id)?;
context.apub.delete_object(&self.apub_id)?; let accept_apub_id = context.apub.apub_for_follow(self.follow_id)?.req()?;
Ok(()) context.apub.delete_object(&accept_apub_id)?;
context.apub.delete_object(&self.follow_apub_id)?;
if let Some(undo_follow) = opt {
if context.is_local(undo_follow.0.right)? {
return Ok(Some(Box::new(crate::apub::results::UndoFollow {
follow_apub_id: self.follow_apub_id.clone(),
profile_id: undo_follow.0.right,
})));
}
}
Ok(None)
}
}
impl Action for UndoAcceptFollow {
fn perform(&self, context: &Context) -> Result<Option<Box<dyn Completed>>, Error> {
let opt = context.store.view.follows.remove(self.follow_id)?;
let accept_apub_id = context.apub.apub_for_follow(self.follow_id)?.req()?;
context.apub.delete_object(&accept_apub_id)?;
context.apub.delete_object(&self.follow_apub_id)?;
if let Some(undo_follow) = opt {
if context.is_local(undo_follow.0.right)? {
return Ok(Some(Box::new(crate::apub::results::UndoAcceptFollow {
accept_apub_id,
profile_id: undo_follow.0.right,
})));
}
}
Ok(None)
} }
} }

View file

@ -1,12 +1,12 @@
use crate::{ use crate::{
apub::actions::{ apub::actions::{
AcceptFollowRequest, CreateFollowRequest, DeleteFollowRequest, RejectFollowRequest, AcceptFollowRequest, CreateFollowRequest, RejectFollowRequest, UndoFollowRequest,
}, },
Action, Context, Error, Action, Completed, Context, Error, Required,
}; };
impl Action for CreateFollowRequest { impl Action for CreateFollowRequest {
fn perform(&self, context: &Context) -> Result<(), Error> { fn perform(&self, context: &Context) -> Result<Option<Box<dyn Completed>>, Error> {
context.check_block(self.followed_by_profile, self.followed_profile)?; context.check_block(self.followed_by_profile, self.followed_profile)?;
let follow_request = context.store.view.follow_requests.new( let follow_request = context.store.view.follow_requests.new(
@ -15,11 +15,11 @@ impl Action for CreateFollowRequest {
self.published, self.published,
)?; )?;
context if let Some(apub_id) = &self.follow_apub_id {
.apub context.apub.follow_request(apub_id, follow_request.id)?;
.follow_request(&self.apub_id, follow_request.id)?; }
if let Ok(Some(true)) = context.store.profiles.is_local(self.followed_profile) { if let Ok(true) = context.is_local(self.followed_profile) {
context.store.view.follow_request_notifs.new( context.store.view.follow_request_notifs.new(
self.followed_profile, self.followed_profile,
follow_request.id, follow_request.id,
@ -27,12 +27,20 @@ impl Action for CreateFollowRequest {
); );
} }
Ok(()) if context.is_local(self.followed_by_profile)?
&& !context.is_local(self.followed_profile)?
{
return Ok(Some(Box::new(crate::apub::results::Follow {
follow_request_id: follow_request.id,
})));
}
Ok(None)
} }
} }
impl Action for AcceptFollowRequest { impl Action for AcceptFollowRequest {
fn perform(&self, context: &Context) -> Result<(), Error> { fn perform(&self, context: &Context) -> Result<Option<Box<dyn Completed>>, Error> {
let opt = context let opt = context
.store .store
.view .view
@ -52,15 +60,29 @@ impl Action for AcceptFollowRequest {
self.published, self.published,
)?; )?;
context.apub.follow(&self.apub_id, follow.id)?; if let Some(apub_id) = &self.accept_apub_id {
context.apub.follow(apub_id, follow.id)?;
}
if context.is_local(follow.right)? && !context.is_local(follow.left)? {
let follow_apub_id = context
.apub
.apub_for_follow_request(undo_follow_request.0.id)?
.req()?;
return Ok(Some(Box::new(crate::apub::results::AcceptFollow {
follow_apub_id,
profile_id: follow.left,
follow_id: follow.id,
})));
}
} }
Ok(()) Ok(None)
} }
} }
impl Action for RejectFollowRequest { impl Action for RejectFollowRequest {
fn perform(&self, context: &Context) -> Result<(), Error> { fn perform(&self, context: &Context) -> Result<Option<Box<dyn Completed>>, Error> {
let opt = context let opt = context
.store .store
.view .view
@ -68,21 +90,34 @@ impl Action for RejectFollowRequest {
.remove(self.follow_request_id)?; .remove(self.follow_request_id)?;
if let Some(undo_follow_request) = opt { if let Some(undo_follow_request) = opt {
let follow_apub_id = context
.apub
.apub_for_follow_request(self.follow_request_id)?
.req()?;
context.apub.delete_object(&follow_apub_id)?;
context context
.store .store
.view .view
.follow_request_notifs .follow_request_notifs
.remove(undo_follow_request.0.id); .remove(undo_follow_request.0.id);
if context.is_local(undo_follow_request.0.left)?
&& !context.is_local(undo_follow_request.0.right)?
{
return Ok(Some(Box::new(crate::apub::results::RejectFollow {
follow_apub_id,
profile_id: undo_follow_request.0.left,
})));
}
} }
context.apub.delete_object(&self.apub_id)?; Ok(None)
Ok(())
} }
} }
impl Action for DeleteFollowRequest { impl Action for UndoFollowRequest {
fn perform(&self, context: &Context) -> Result<(), Error> { fn perform(&self, context: &Context) -> Result<Option<Box<dyn Completed>>, Error> {
let opt = context let opt = context
.store .store
.view .view
@ -90,15 +125,28 @@ impl Action for DeleteFollowRequest {
.remove(self.follow_request_id)?; .remove(self.follow_request_id)?;
if let Some(undo_follow_request) = opt { if let Some(undo_follow_request) = opt {
let follow_apub_id = context
.apub
.apub_for_follow_request(self.follow_request_id)?
.req()?;
context.apub.delete_object(&follow_apub_id)?;
context context
.store .store
.view .view
.follow_request_notifs .follow_request_notifs
.remove(undo_follow_request.0.id); .remove(undo_follow_request.0.id);
if context.is_local(undo_follow_request.0.right)?
&& !context.is_local(undo_follow_request.0.left)?
{
return Ok(Some(Box::new(crate::apub::results::UndoFollow {
follow_apub_id,
profile_id: undo_follow_request.0.right,
})));
}
} }
context.apub.delete_object(&self.apub_id)?; Ok(None)
Ok(())
} }
} }

View file

@ -15,7 +15,7 @@ mod submission;
pub(crate) use apub::ingest; pub(crate) use apub::ingest;
pub struct CreateReact { pub struct CreateReact {
apub_id: Url, like_apub_id: Option<Url>,
submission_id: Uuid, submission_id: Uuid,
profile_id: Uuid, profile_id: Uuid,
comment_id: Option<Uuid>, comment_id: Option<Uuid>,
@ -24,12 +24,11 @@ pub struct CreateReact {
} }
pub struct DeleteReact { pub struct DeleteReact {
apub_id: Url,
react_id: Uuid, react_id: Uuid,
} }
pub struct CreateComment { pub struct CreateComment {
apub_id: Url, note_apub_id: Option<Url>,
submission_id: Uuid, submission_id: Uuid,
profile_id: Uuid, profile_id: Uuid,
comment_id: Option<Uuid>, comment_id: Option<Uuid>,
@ -40,17 +39,18 @@ pub struct CreateComment {
pub struct AnnounceComment; pub struct AnnounceComment;
pub struct UpdateComment { pub struct UpdateComment {
update_apub_id: Option<Url>,
comment_id: Uuid, comment_id: Uuid,
body: Option<String>, body: Option<String>,
} }
pub struct DeleteComment { pub struct DeleteComment {
apub_id: Url, note_apub_id: Url,
comment_id: Uuid, comment_id: Uuid,
} }
pub struct CreateSubmission { pub struct CreateSubmission {
apub_id: Url, note_apub_id: Option<Url>,
profile_id: Uuid, profile_id: Uuid,
title: String, title: String,
description: Option<String>, description: Option<String>,
@ -69,12 +69,11 @@ pub struct UpdateSubmission {
} }
pub struct DeleteSubmission { pub struct DeleteSubmission {
apub_id: Url,
submission_id: Uuid, submission_id: Uuid,
} }
pub struct CreateProfile { pub struct CreateProfile {
apub_id: Url, person_apub_id: Option<Url>,
owner_source: OwnerSource, owner_source: OwnerSource,
handle: String, handle: String,
domain: String, domain: String,
@ -100,46 +99,47 @@ pub struct UpdateProfile {
} }
pub struct DeleteProfile { pub struct DeleteProfile {
apub_id: Url,
profile_id: Uuid, profile_id: Uuid,
} }
pub struct CreateFollowRequest { pub struct CreateFollowRequest {
apub_id: Url, follow_apub_id: Option<Url>,
followed_profile: Uuid, followed_profile: Uuid,
followed_by_profile: Uuid, followed_by_profile: Uuid,
published: DateTime<Utc>, published: DateTime<Utc>,
} }
pub struct AcceptFollowRequest { pub struct AcceptFollowRequest {
apub_id: Url, accept_apub_id: Option<Url>,
follow_request_id: Uuid, follow_request_id: Uuid,
published: DateTime<Utc>, published: DateTime<Utc>,
} }
pub struct RejectFollowRequest { pub struct RejectFollowRequest {
apub_id: Url,
follow_request_id: Uuid, follow_request_id: Uuid,
} }
pub struct DeleteFollowRequest { pub struct UndoFollowRequest {
apub_id: Url,
follow_request_id: Uuid, follow_request_id: Uuid,
} }
pub struct CreateBlock { pub struct CreateBlock {
apub_id: Url, block_apub_id: Option<Url>,
blocked_profile: Uuid, blocked_profile: Uuid,
blocked_by_profile: Uuid, blocked_by_profile: Uuid,
published: DateTime<Utc>, published: DateTime<Utc>,
} }
pub struct DeleteBlock { pub struct DeleteBlock {
apub_id: Url,
block_id: Uuid, block_id: Uuid,
} }
pub struct DeleteFollow { pub struct UndoFollow {
apub_id: Url, follow_apub_id: Url,
follow_id: Uuid,
}
pub struct UndoAcceptFollow {
follow_apub_id: Url,
follow_id: Uuid, follow_id: Uuid,
} }

View file

@ -1,10 +1,10 @@
use crate::{ use crate::{
apub::actions::{CreateProfile, DeleteProfile, DeleteSubmission, UpdateProfile}, apub::actions::{CreateProfile, DeleteProfile, DeleteSubmission, UpdateProfile},
Action, Context, Error, Required, Action, Completed, Context, Error, Required,
}; };
impl Action for CreateProfile { impl Action for CreateProfile {
fn perform(&self, context: &Context) -> Result<(), Error> { fn perform(&self, context: &Context) -> Result<Option<Box<dyn Completed>>, Error> {
let profile = context.store.profiles.create( let profile = context.store.profiles.create(
self.owner_source.clone(), self.owner_source.clone(),
&self.handle, &self.handle,
@ -38,14 +38,23 @@ impl Action for CreateProfile {
context context
.apub .apub
.store_public_key(profile.id(), &self.public_key_id, &self.public_key)?; .store_public_key(profile.id(), &self.public_key_id, &self.public_key)?;
context.apub.profile(&self.apub_id, profile.id())?;
Ok(()) if let Some(apub_id) = &self.person_apub_id {
context.apub.profile(apub_id, profile.id())?;
}
if profile.owner_source().is_local() {
return Ok(Some(Box::new(crate::apub::results::ProfileCreated {
profile_id: profile.id(),
})));
}
Ok(None)
} }
} }
impl Action for UpdateProfile { impl Action for UpdateProfile {
fn perform(&self, context: &Context) -> Result<(), Error> { fn perform(&self, context: &Context) -> Result<Option<Box<dyn Completed>>, Error> {
let profile = context.store.profiles.by_id(self.profile_id)?.req()?; let profile = context.store.profiles.by_id(self.profile_id)?.req()?;
let mut changes = profile.update(); let mut changes = profile.update();
@ -74,28 +83,30 @@ impl Action for UpdateProfile {
.apub .apub
.store_public_key(profile.id(), &self.public_key_id, &self.public_key)?; .store_public_key(profile.id(), &self.public_key_id, &self.public_key)?;
Ok(()) if profile.owner_source().is_local() {
return Ok(Some(Box::new(crate::apub::results::ProfileUpdated {
profile_id: profile.id(),
})));
}
Ok(None)
} }
} }
fn delete_submission(submission_id: uuid::Uuid, context: &Context) -> Result<(), Error> { fn delete_submission(submission_id: uuid::Uuid, context: &Context) -> Result<(), Error> {
let apub_id = context.apub.apub_for_submission(submission_id)?.req()?; Action::perform(&DeleteSubmission { submission_id }, context)?;
Action::perform(
&DeleteSubmission {
apub_id,
submission_id,
},
context,
)?;
Ok(()) Ok(())
} }
impl Action for DeleteProfile { impl Action for DeleteProfile {
fn perform(&self, context: &Context) -> Result<(), Error> { fn perform(&self, context: &Context) -> Result<Option<Box<dyn Completed>>, Error> {
let opt = context.store.profiles.delete(self.profile_id)?; let profile_id = self.profile_id;
context.apub.delete_object(&self.apub_id)?; let opt = context.store.profiles.delete(profile_id)?;
if let Some(undo_profile) = opt { if let Some(undo_profile) = opt {
let person_apub_id = context.apub.apub_for_profile(profile_id)?.req()?;
context.apub.delete_object(&person_apub_id)?;
if let Some(banner) = undo_profile.0.banner() { if let Some(banner) = undo_profile.0.banner() {
context.spawner.purge_file(banner); context.spawner.purge_file(banner);
} }
@ -103,7 +114,6 @@ impl Action for DeleteProfile {
context.spawner.purge_file(icon); context.spawner.purge_file(icon);
} }
let profile_id = self.profile_id;
let context_clone = context.clone(); let context_clone = context.clone();
context.spawn_blocking(move || { context.spawn_blocking(move || {
@ -113,8 +123,14 @@ impl Action for DeleteProfile {
} }
} }
}); });
if undo_profile.0.owner_source().is_local() {
return Ok(Some(Box::new(crate::apub::results::ProfileDeleted {
profile_id,
})));
}
} }
Ok(()) Ok(None)
} }
} }

View file

@ -1,10 +1,10 @@
use crate::{ use crate::{
apub::actions::{CreateReact, DeleteReact}, apub::actions::{CreateReact, DeleteReact},
Action, Context, Error, Required, Action, Completed, Context, Error, Required,
}; };
impl Action for CreateReact { impl Action for CreateReact {
fn perform(&self, context: &Context) -> Result<(), Error> { fn perform(&self, context: &Context) -> Result<Option<Box<dyn Completed>>, Error> {
let submissioner_id = context let submissioner_id = context
.store .store
.submissions .submissions
@ -37,7 +37,9 @@ impl Action for CreateReact {
self.published, self.published,
)?; )?;
context.apub.react(&self.apub_id, react.id())?; if let Some(apub_id) = &self.like_apub_id {
context.apub.react(&apub_id, react.id())?;
}
let notifier_id = commenter_id.unwrap_or(submissioner_id); let notifier_id = commenter_id.unwrap_or(submissioner_id);
@ -49,16 +51,37 @@ impl Action for CreateReact {
.new(notifier_id, react.id(), self.published); .new(notifier_id, react.id(), self.published);
} }
Ok(()) if context.is_local(react.profile_id())? {
return Ok(Some(Box::new(crate::apub::results::React {
react_id: react.id(),
})));
}
Ok(None)
} }
} }
impl Action for DeleteReact { impl Action for DeleteReact {
fn perform(&self, context: &Context) -> Result<(), Error> { fn perform(&self, context: &Context) -> Result<Option<Box<dyn Completed>>, Error> {
context.store.reacts.delete(self.react_id)?; let react_id = self.react_id;
context.store.view.reacts.remove(self.react_id); let opt = context.store.reacts.delete(react_id)?;
context.apub.delete_object(&self.apub_id)?;
Ok(()) if let Some(undo_react) = opt {
context.store.view.reacts.remove(react_id);
let like_apub_id = context.apub.apub_for_react(react_id)?.req()?;
context.apub.delete_object(&like_apub_id)?;
let profile_id = undo_react.0.profile_id();
if context.is_local(profile_id)? {
return Ok(Some(Box::new(crate::apub::results::UndoReact {
like_apub_id,
profile_id,
})));
}
}
Ok(None)
} }
} }

View file

@ -2,18 +2,20 @@ use crate::{
apub::actions::{ apub::actions::{
AnnounceSubmission, CreateSubmission, DeleteComment, DeleteSubmission, UpdateSubmission, AnnounceSubmission, CreateSubmission, DeleteComment, DeleteSubmission, UpdateSubmission,
}, },
Action, Context, Error, Required, Action, Completed, Context, Error, Required,
}; };
use std::collections::HashSet; use std::collections::HashSet;
impl Action for CreateSubmission { impl Action for CreateSubmission {
fn perform(&self, context: &Context) -> Result<(), Error> { fn perform(&self, context: &Context) -> Result<Option<Box<dyn Completed>>, Error> {
let submission = let submission =
context context
.store .store
.submissions .submissions
.create(self.profile_id, &self.title, self.visibility)?; .create(self.profile_id, &self.title, self.visibility)?;
let submission_id = submission.id();
let mut changes = submission.update(); let mut changes = submission.update();
changes.publish(Some(self.published)); changes.publish(Some(self.published));
if let Some(description) = &self.description { if let Some(description) = &self.description {
@ -28,41 +30,45 @@ impl Action for CreateSubmission {
} }
let submission = context.store.submissions.update_files(&changes)?; let submission = context.store.submissions.update_files(&changes)?;
context.apub.submission(&self.apub_id, submission.id())?; if let Some(apub_id) = &self.note_apub_id {
context.apub.submission(apub_id, submission_id)?;
}
let submission_id = submission.id();
let profile_id = self.profile_id; let profile_id = self.profile_id;
let published = submission.published().req()?; let published = submission.published().req()?;
let context_clone = context.clone(); let context_clone = context.clone();
context.arbiter.send(Box::pin(async move { context.spawn_blocking(move || {
let _ = actix_web::web::block(move || { for follower_id in context_clone.store.view.follows.forward_iter(profile_id) {
for follower_id in context_clone.store.view.follows.forward_iter(profile_id) { if let Ok(Some(true)) = context_clone.store.profiles.is_local(follower_id) {
if let Ok(Some(true)) = context_clone.store.profiles.is_local(follower_id) { context_clone
context_clone.store.view.submissions.new( .store
follower_id, .view
submission_id, .submissions
published, .new(follower_id, submission_id, published);
);
}
} }
Ok(()) as Result<(), ()> }
}) });
.await;
}));
Ok(()) if context.is_local(submission.profile_id())? {
return Ok(Some(Box::new(crate::apub::results::SubmissionCreated {
submission_id,
})));
}
Ok(None)
} }
} }
impl Action for AnnounceSubmission { impl Action for AnnounceSubmission {
fn perform(&self, _: &Context) -> Result<(), Error> { fn perform(&self, _: &Context) -> Result<Option<Box<dyn Completed>>, Error> {
Ok(()) Ok(None)
} }
} }
impl Action for UpdateSubmission { impl Action for UpdateSubmission {
fn perform(&self, context: &Context) -> Result<(), Error> { fn perform(&self, context: &Context) -> Result<Option<Box<dyn Completed>>, Error> {
let submission = context.store.submissions.by_id(self.submission_id)?.req()?; let submission_id = self.submission_id;
let submission = context.store.submissions.by_id(submission_id)?.req()?;
let mut changes = submission.update(); let mut changes = submission.update();
if let Some(title) = &self.title { if let Some(title) = &self.title {
@ -86,15 +92,22 @@ impl Action for UpdateSubmission {
context.spawner.purge_file(file); context.spawner.purge_file(file);
} }
Ok(()) let profile_id = submission.profile_id();
if context.is_local(profile_id)? {
return Ok(Some(Box::new(crate::apub::results::SubmissionUpdated {
submission_id,
})));
}
Ok(None)
} }
} }
fn delete_comment(comment_id: uuid::Uuid, context: &Context) -> Result<(), Error> { fn delete_comment(comment_id: uuid::Uuid, context: &Context) -> Result<(), Error> {
let apub_id = context.apub.apub_for_comment(comment_id)?.req()?; let note_apub_id = context.apub.apub_for_comment(comment_id)?.req()?;
Action::perform( Action::perform(
&DeleteComment { &DeleteComment {
apub_id, note_apub_id,
comment_id, comment_id,
}, },
context, context,
@ -103,12 +116,14 @@ fn delete_comment(comment_id: uuid::Uuid, context: &Context) -> Result<(), Error
} }
impl Action for DeleteSubmission { impl Action for DeleteSubmission {
fn perform(&self, context: &Context) -> Result<(), Error> { fn perform(&self, context: &Context) -> Result<Option<Box<dyn Completed>>, Error> {
let opt = context.store.submissions.delete(self.submission_id)?; let submission_id = self.submission_id;
context.apub.delete_object(&self.apub_id)?; let opt = context.store.submissions.delete(submission_id)?;
if let Some(undo_submission) = opt { if let Some(undo_submission) = opt {
let submission_id = undo_submission.0.id(); let note_apub_id = context.apub.apub_for_submission(submission_id)?.req()?;
context.apub.delete_object(&note_apub_id)?;
let context_clone = context.clone(); let context_clone = context.clone();
context.spawn_blocking(move || { context.spawn_blocking(move || {
for comment_id in context_clone.store.comments.for_submission(submission_id) { for comment_id in context_clone.store.comments.for_submission(submission_id) {
@ -122,13 +137,20 @@ impl Action for DeleteSubmission {
context.spawner.purge_file(*file_id); context.spawner.purge_file(*file_id);
} }
let submission_id = undo_submission.0.id();
let context_clone = context.clone(); let context_clone = context.clone();
context.spawn_blocking(move || { context.spawn_blocking(move || {
context_clone.store.view.submissions.remove(submission_id); context_clone.store.view.submissions.remove(submission_id);
}); });
let profile_id = undo_submission.0.profile_id();
if context.is_local(profile_id)? {
return Ok(Some(Box::new(crate::apub::results::SubmissionDeleted {
profile_id,
submission_id,
})));
}
} }
Ok(()) Ok(None)
} }
} }

View file

@ -1,4 +1,4 @@
use super::{Blocked, Unblocked}; use super::{Block as Blocked, UndoBlock};
use crate::{Completed, Context, Error, Required}; use crate::{Completed, Context, Error, Required};
use activitystreams::{ use activitystreams::{
activity::{Block, Undo}, activity::{Block, Undo},
@ -28,11 +28,10 @@ impl Completed for Blocked {
} }
} }
impl Completed for Unblocked { impl Completed for UndoBlock {
fn to_apub(&self, ctx: &Context) -> Result<AnyBase, Error> { fn to_apub(&self, ctx: &Context) -> Result<AnyBase, Error> {
let person_id = ctx.apub.apub_for_profile(self.profile_id)?.req()?; let person_id = ctx.apub.apub_for_profile(self.profile_id)?.req()?;
let block_id = ctx.apub.apub_for_block(self.block_id)?.req()?; let block = ctx.apub.object(&self.block_apub_id)?.req()?;
let block = ctx.apub.object(&block_id)?.req()?;
let mut undo = Undo::new(person_id, block); let mut undo = Undo::new(person_id, block);
undo.set_id(ctx.apub.info.gen_id()) undo.set_id(ctx.apub.info.gen_id())

View file

@ -1,7 +1,9 @@
use super::{CommentCreated, CommentDeleted, CommentUpdated}; use super::{
CommentCreated, CommentDeleted, CommentUpdated, RemoteCommentCreated, RemoteCommentUpdated,
};
use crate::{store::Comment, Completed, Context, Error, Required}; use crate::{store::Comment, Completed, Context, Error, Required};
use activitystreams::{ use activitystreams::{
activity::{Create, Delete, Update}, activity::{Announce, Create, Delete, Update},
base::AnyBase, base::AnyBase,
context, context,
object::Note, object::Note,
@ -45,6 +47,7 @@ impl Completed for CommentCreated {
let comment = ctx.store.comments.by_id(self.comment_id)?.req()?; let comment = ctx.store.comments.by_id(self.comment_id)?.req()?;
let person_id = ctx.apub.apub_for_profile(comment.profile_id())?.req()?; let person_id = ctx.apub.apub_for_profile(comment.profile_id())?.req()?;
let note_id = ctx.apub.info.gen_id(); let note_id = ctx.apub.info.gen_id();
ctx.apub.comment(&note_id, self.comment_id)?;
let note = build_comment(comment, note_id, person_id.clone(), ctx)?; let note = build_comment(comment, note_id, person_id.clone(), ctx)?;
let mut create = Create::new(person_id, note); let mut create = Create::new(person_id, note);
@ -59,6 +62,23 @@ impl Completed for CommentCreated {
} }
} }
impl Completed for RemoteCommentCreated {
fn to_apub(&self, ctx: &Context) -> Result<AnyBase, Error> {
let comment = ctx.apub.object(&self.note_apub_id)?.req()?;
let person_id = ctx.apub.apub_for_profile(self.profile_id)?.req()?;
let mut announce = Announce::new(person_id, comment);
announce
.set_id(ctx.apub.info.gen_id())
.add_context(context())
.add_context(security());
let announce = announce.into_any_base()?;
ctx.apub.store_object(&announce)?;
Ok(announce)
}
}
impl Completed for CommentUpdated { impl Completed for CommentUpdated {
fn to_apub(&self, ctx: &Context) -> Result<AnyBase, Error> { fn to_apub(&self, ctx: &Context) -> Result<AnyBase, Error> {
let comment = ctx.store.comments.by_id(self.comment_id)?.req()?; let comment = ctx.store.comments.by_id(self.comment_id)?.req()?;
@ -78,11 +98,27 @@ impl Completed for CommentUpdated {
} }
} }
impl Completed for RemoteCommentUpdated {
fn to_apub(&self, ctx: &Context) -> Result<AnyBase, Error> {
let person_id = ctx.apub.apub_for_profile(self.profile_id)?.req()?;
let update = ctx.apub.object(&self.update_apub_id)?.req()?;
let mut announce = Announce::new(person_id, update);
announce
.set_id(ctx.apub.info.gen_id())
.add_context(context())
.add_context(security());
let announce = announce.into_any_base()?;
ctx.apub.store_object(&announce)?;
Ok(announce)
}
}
impl Completed for CommentDeleted { impl Completed for CommentDeleted {
fn to_apub(&self, ctx: &Context) -> Result<AnyBase, Error> { fn to_apub(&self, ctx: &Context) -> Result<AnyBase, Error> {
let person_id = ctx.apub.apub_for_profile(self.profile_id)?.req()?; let person_id = ctx.apub.apub_for_profile(self.profile_id)?.req()?;
let note_id = ctx.apub.apub_for_comment(self.comment_id)?.req()?; let note = ctx.apub.object(&self.note_apub_id)?.req()?;
let note = ctx.apub.object(&note_id)?.req()?;
let mut delete = Delete::new(person_id, note); let mut delete = Delete::new(person_id, note);
delete delete

View file

@ -1,7 +1,4 @@
use super::{ use super::{AcceptFollow, Follow as FollowRequested, RejectFollow, UndoAcceptFollow, UndoFollow};
FollowRequestAccepted, FollowRequestDeleted, FollowRequestRejected, FollowRequested,
UndoneFollowRequestAccepted, Unfollowed,
};
use crate::{Completed, Context, Error, Required}; use crate::{Completed, Context, Error, Required};
use activitystreams::{ use activitystreams::{
activity::{Accept, Follow, Reject, Undo}, activity::{Accept, Follow, Reject, Undo},
@ -23,9 +20,13 @@ impl Completed for FollowRequested {
let object_id = ctx.apub.apub_for_profile(follow.left)?.req()?; let object_id = ctx.apub.apub_for_profile(follow.left)?.req()?;
let published = follow.published; let published = follow.published;
let follow_id = ctx.apub.info.gen_id();
ctx.apub
.follow_request(&follow_id, self.follow_request_id)?;
let mut follow = Follow::new(actor_id, object_id); let mut follow = Follow::new(actor_id, object_id);
follow follow
.set_id(ctx.apub.info.gen_id()) .set_id(follow_id)
.set_published(published.into()) .set_published(published.into())
.add_context(context()) .add_context(context())
.add_context(security()); .add_context(security());
@ -36,34 +37,10 @@ impl Completed for FollowRequested {
} }
} }
impl Completed for FollowRequestDeleted { impl Completed for RejectFollow {
fn to_apub(&self, ctx: &Context) -> Result<AnyBase, Error> { fn to_apub(&self, ctx: &Context) -> Result<AnyBase, Error> {
let person_id = ctx.apub.apub_for_profile(self.profile_id)?.req()?; let person_id = ctx.apub.apub_for_profile(self.profile_id)?.req()?;
let follow_request_id = ctx let follow_request = ctx.apub.object(&self.follow_apub_id)?.req()?;
.apub
.apub_for_follow_request(self.follow_request_id)?
.req()?;
let follow_request = ctx.apub.object(&follow_request_id)?.req()?;
let mut undo = Undo::new(person_id, follow_request);
undo.set_id(ctx.apub.info.gen_id())
.add_context(context())
.add_context(security());
let undo = undo.into_any_base()?;
ctx.apub.store_object(&undo)?;
Ok(undo)
}
}
impl Completed for FollowRequestRejected {
fn to_apub(&self, ctx: &Context) -> Result<AnyBase, Error> {
let person_id = ctx.apub.apub_for_profile(self.profile_id)?.req()?;
let follow_request_id = ctx
.apub
.apub_for_follow_request(self.follow_request_id)?
.req()?;
let follow_request = ctx.apub.object(&follow_request_id)?.req()?;
let mut reject = Reject::new(person_id, follow_request); let mut reject = Reject::new(person_id, follow_request);
reject reject
@ -77,14 +54,10 @@ impl Completed for FollowRequestRejected {
} }
} }
impl Completed for FollowRequestAccepted { impl Completed for AcceptFollow {
fn to_apub(&self, ctx: &Context) -> Result<AnyBase, Error> { fn to_apub(&self, ctx: &Context) -> Result<AnyBase, Error> {
let person_id = ctx.apub.apub_for_profile(self.profile_id)?.req()?; let person_id = ctx.apub.apub_for_profile(self.profile_id)?.req()?;
let follow_request_id = ctx let follow_request = ctx.apub.object(&self.follow_apub_id)?.req()?;
.apub
.apub_for_follow_request(self.follow_request_id)?
.req()?;
let follow_request = ctx.apub.object(&follow_request_id)?.req()?;
let accept_id = ctx.apub.info.gen_id(); let accept_id = ctx.apub.info.gen_id();
ctx.apub.follow(&accept_id, self.follow_id)?; ctx.apub.follow(&accept_id, self.follow_id)?;
@ -101,28 +74,26 @@ impl Completed for FollowRequestAccepted {
} }
} }
impl Completed for UndoneFollowRequestAccepted { impl Completed for UndoAcceptFollow {
fn to_apub(&self, ctx: &Context) -> Result<AnyBase, Error> { fn to_apub(&self, ctx: &Context) -> Result<AnyBase, Error> {
let person_id = ctx.apub.apub_for_profile(self.profile_id)?.req()?; let person_id = ctx.apub.apub_for_profile(self.profile_id)?.req()?;
let follow_id = ctx.apub.apub_for_follow(self.follow_id)?.req()?; let accept = ctx.apub.object(&self.accept_apub_id)?.req()?;
let follow = ctx.apub.object(&follow_id)?.req()?;
let mut undo = Undo::new(person_id, accept);
let mut undo = Undo::new(person_id, follow); undo.set_id(ctx.apub.info.gen_id())
undo.set_id(ctx.apub.info.gen_id()) .add_context(context())
.add_context(context()) .add_context(security());
.add_context(security()); let undo = undo.into_any_base()?;
let undo = undo.into_any_base()?; ctx.apub.store_object(&undo)?;
ctx.apub.store_object(&undo)?;
Ok(undo)
Ok(undo) }
} }
}
impl Completed for UndoFollow {
impl Completed for Unfollowed { fn to_apub(&self, ctx: &Context) -> Result<AnyBase, Error> {
fn to_apub(&self, ctx: &Context) -> Result<AnyBase, Error> { let person_id = ctx.apub.apub_for_profile(self.profile_id)?.req()?;
let person_id = ctx.apub.apub_for_profile(self.profile_id)?.req()?; let follow = ctx.apub.object(&self.follow_apub_id)?.req()?;
let follow_id = ctx.apub.apub_for_follow(self.follow_id)?.req()?;
let follow = ctx.apub.object(&follow_id)?.req()?;
let mut undo = Undo::new(person_id, follow); let mut undo = Undo::new(person_id, follow);
undo.set_id(ctx.apub.info.gen_id()) undo.set_id(ctx.apub.info.gen_id())

View file

@ -1,3 +1,4 @@
use url::Url;
use uuid::Uuid; use uuid::Uuid;
mod block; mod block;
@ -7,88 +8,93 @@ mod profile;
mod react; mod react;
mod submission; mod submission;
pub(crate) struct ProfileCreated { pub(super) struct ProfileCreated {
profile_id: Uuid, pub(super) profile_id: Uuid,
} }
pub(crate) struct ProfileUpdated { pub(super) struct ProfileUpdated {
profile_id: Uuid, pub(super) profile_id: Uuid,
} }
pub(crate) struct ProfileDeleted { pub(super) struct ProfileDeleted {
profile_id: Uuid, pub(super) profile_id: Uuid,
} }
pub(crate) struct SubmissionCreated { pub(super) struct SubmissionCreated {
submission_id: Uuid, pub(super) submission_id: Uuid,
} }
pub(crate) struct SubmissionUpdated { pub(super) struct SubmissionUpdated {
submission_id: Uuid, pub(super) submission_id: Uuid,
} }
pub(crate) struct SubmissionDeleted { pub(super) struct SubmissionDeleted {
profile_id: Uuid, pub(super) profile_id: Uuid,
submission_id: Uuid, pub(super) submission_id: Uuid,
} }
pub(crate) struct CommentCreated { pub(super) struct CommentCreated {
comment_id: Uuid, pub(super) comment_id: Uuid,
} }
pub(crate) struct CommentUpdated { pub(super) struct RemoteCommentCreated {
comment_id: Uuid, pub(super) note_apub_id: Url,
pub(super) profile_id: Uuid,
} }
pub(crate) struct CommentDeleted { pub(super) struct CommentUpdated {
profile_id: Uuid, pub(super) comment_id: Uuid,
comment_id: Uuid,
} }
pub(crate) struct ReactCreated { pub(super) struct RemoteCommentUpdated {
react_id: Uuid, pub(super) update_apub_id: Url,
pub(super) profile_id: Uuid,
} }
pub(crate) struct ReactDeleted { pub(super) struct CommentDeleted {
profile_id: Uuid, pub(super) note_apub_id: Url,
react_id: Uuid, pub(super) profile_id: Uuid,
} }
pub(crate) struct FollowRequested { pub(super) struct React {
follow_request_id: Uuid, pub(super) react_id: Uuid,
} }
pub(crate) struct FollowRequestDeleted { pub(super) struct UndoReact {
profile_id: Uuid, pub(super) like_apub_id: Url,
follow_request_id: Uuid, pub(super) profile_id: Uuid,
} }
pub(crate) struct FollowRequestRejected { pub(super) struct Follow {
profile_id: Uuid, pub(super) follow_request_id: Uuid,
follow_request_id: Uuid,
} }
pub(crate) struct FollowRequestAccepted { pub(super) struct RejectFollow {
profile_id: Uuid, pub(super) follow_apub_id: Url,
follow_id: Uuid, pub(super) profile_id: Uuid,
follow_request_id: Uuid,
} }
pub(crate) struct UndoneFollowRequestAccepted { pub(super) struct AcceptFollow {
profile_id: Uuid, pub(super) follow_apub_id: Url,
follow_id: Uuid, pub(super) profile_id: Uuid,
pub(super) follow_id: Uuid,
} }
pub(crate) struct Unfollowed { pub(super) struct UndoAcceptFollow {
profile_id: Uuid, pub(super) accept_apub_id: Url,
follow_id: Uuid, pub(super) profile_id: Uuid,
} }
pub(crate) struct Blocked { pub(super) struct UndoFollow {
block_id: Uuid, pub(super) follow_apub_id: Url,
pub(super) profile_id: Uuid,
} }
pub(crate) struct Unblocked { pub(super) struct Block {
profile_id: Uuid, pub(super) block_id: Uuid,
block_id: Uuid, }
pub(super) struct UndoBlock {
pub(super) block_apub_id: Url,
pub(super) profile_id: Uuid,
} }

View file

@ -1,4 +1,4 @@
use super::{ReactCreated, ReactDeleted}; use super::{React, UndoReact};
use crate::{Completed, Context, Error, Required}; use crate::{Completed, Context, Error, Required};
use activitystreams::{ use activitystreams::{
activity::{Create, Delete, Like}, activity::{Create, Delete, Like},
@ -8,7 +8,7 @@ use activitystreams::{
public, security, public, security,
}; };
impl Completed for ReactCreated { impl Completed for React {
fn to_apub(&self, ctx: &Context) -> Result<AnyBase, Error> { fn to_apub(&self, ctx: &Context) -> Result<AnyBase, Error> {
let react = ctx.store.reacts.by_id(self.react_id)?.req()?; let react = ctx.store.reacts.by_id(self.react_id)?.req()?;
let person_id = ctx.apub.apub_for_profile(react.profile_id())?.req()?; let person_id = ctx.apub.apub_for_profile(react.profile_id())?.req()?;
@ -46,11 +46,10 @@ impl Completed for ReactCreated {
} }
} }
impl Completed for ReactDeleted { impl Completed for UndoReact {
fn to_apub(&self, ctx: &Context) -> Result<AnyBase, Error> { fn to_apub(&self, ctx: &Context) -> Result<AnyBase, Error> {
let person_id = ctx.apub.apub_for_profile(self.profile_id)?.req()?; let person_id = ctx.apub.apub_for_profile(self.profile_id)?.req()?;
let like_id = ctx.apub.apub_for_react(self.react_id)?.req()?; let like = ctx.apub.object(&self.like_apub_id)?.req()?;
let like = ctx.apub.object(&like_id)?.req()?;
let mut delete = Delete::new(person_id, like); let mut delete = Delete::new(person_id, like);
delete delete

View file

@ -44,6 +44,10 @@ impl Context {
} }
} }
fn is_local(&self, id: Uuid) -> Result<bool, Error> {
Ok(self.store.profiles.is_local(id)?.req()?)
}
fn check_block(&self, left: Uuid, right: Uuid) -> Result<(), Error> { fn check_block(&self, left: Uuid, right: Uuid) -> Result<(), Error> {
let forward = self.store.view.blocks.by_forward(left, right)?.is_some(); let forward = self.store.view.blocks.by_forward(left, right)?.is_some();
let backward = self.store.view.blocks.by_backward(right, left)?.is_some(); let backward = self.store.view.blocks.by_backward(right, left)?.is_some();
@ -105,7 +109,7 @@ enum RecoverableError {
} }
trait Action { trait Action {
fn perform(&self, context: &Context) -> Result<(), Error>; fn perform(&self, context: &Context) -> Result<Option<Box<dyn Completed>>, Error>;
} }
pub trait Completed { pub trait Completed {

View file

@ -81,6 +81,10 @@ impl Profile {
self.id self.id
} }
pub(crate) fn owner_source(&self) -> &OwnerSource {
&self.owner_source
}
pub(crate) fn handle(&self) -> &str { pub(crate) fn handle(&self) -> &str {
&self.handle &self.handle
} }