]> Untitled Git - lemmy.git/blob - crates/apub/src/activities/voting/undo_vote.rs
7a419e879b388bc61b6be26af84cd6d1ca6aeded
[lemmy.git] / crates / apub / src / activities / voting / undo_vote.rs
1 use crate::{
2   activities::{
3     generate_activity_id,
4     verify_person_in_community,
5     voting::{undo_vote_comment, undo_vote_post},
6   },
7   local_instance,
8   objects::{community::ApubCommunity, person::ApubPerson},
9   protocol::{
10     activities::voting::{undo_vote::UndoVote, vote::Vote},
11     InCommunity,
12   },
13   ActorType,
14   PostOrComment,
15 };
16 use activitypub_federation::{
17   core::object_id::ObjectId,
18   data::Data,
19   traits::ActivityHandler,
20   utils::verify_urls_match,
21 };
22 use activitystreams_kinds::activity::UndoType;
23 use lemmy_api_common::context::LemmyContext;
24 use lemmy_utils::error::LemmyError;
25 use url::Url;
26
27 impl UndoVote {
28   pub(in crate::activities::voting) fn new(
29     vote: Vote,
30     actor: &ApubPerson,
31     community: &ApubCommunity,
32     context: &LemmyContext,
33   ) -> Result<Self, LemmyError> {
34     Ok(UndoVote {
35       actor: ObjectId::new(actor.actor_id()),
36       object: vote,
37       kind: UndoType::Undo,
38       id: generate_activity_id(
39         UndoType::Undo,
40         &context.settings().get_protocol_and_hostname(),
41       )?,
42       audience: Some(ObjectId::new(community.actor_id())),
43     })
44   }
45 }
46
47 #[async_trait::async_trait(?Send)]
48 impl ActivityHandler for UndoVote {
49   type DataType = LemmyContext;
50   type Error = LemmyError;
51
52   fn id(&self) -> &Url {
53     &self.id
54   }
55
56   fn actor(&self) -> &Url {
57     self.actor.inner()
58   }
59
60   #[tracing::instrument(skip_all)]
61   async fn verify(
62     &self,
63     context: &Data<LemmyContext>,
64     request_counter: &mut i32,
65   ) -> Result<(), LemmyError> {
66     let community = self.community(context, request_counter).await?;
67     verify_person_in_community(&self.actor, &community, context, request_counter).await?;
68     verify_urls_match(self.actor.inner(), self.object.actor.inner())?;
69     self.object.verify(context, request_counter).await?;
70     Ok(())
71   }
72
73   #[tracing::instrument(skip_all)]
74   async fn receive(
75     self,
76     context: &Data<LemmyContext>,
77     request_counter: &mut i32,
78   ) -> Result<(), LemmyError> {
79     let actor = self
80       .actor
81       .dereference(context, local_instance(context).await, request_counter)
82       .await?;
83     let object = self
84       .object
85       .object
86       .dereference(context, local_instance(context).await, request_counter)
87       .await?;
88     match object {
89       PostOrComment::Post(p) => undo_vote_post(actor, &p, context).await,
90       PostOrComment::Comment(c) => undo_vote_comment(actor, &c, context).await,
91     }
92   }
93 }