]> Untitled Git - lemmy.git/blob - server/src/apub/activities.rs
b5bb9d76c7dffff589c05e65186f0e3514d1c05a
[lemmy.git] / server / src / apub / activities.rs
1 use crate::{
2   apub::{extensions::signatures::sign, is_apub_id_valid, ActorType},
3   db::{activity::insert_activity, community::Community, user::User_},
4 };
5 use activitystreams::{context, object::properties::ObjectProperties, public, Activity, Base};
6 use diesel::PgConnection;
7 use failure::{Error, _core::fmt::Debug};
8 use isahc::prelude::*;
9 use log::debug;
10 use serde::Serialize;
11 use url::Url;
12
13 pub fn populate_object_props(
14   props: &mut ObjectProperties,
15   addressed_ccs: Vec<String>,
16   object_id: &str,
17 ) -> Result<(), Error> {
18   props
19     .set_context_xsd_any_uri(context())?
20     // TODO: the activity needs a seperate id from the object
21     .set_id(object_id)?
22     // TODO: should to/cc go on the Create, or on the Post? or on both?
23     // TODO: handle privacy on the receiving side (at least ignore anything thats not public)
24     .set_to_xsd_any_uri(public())?
25     .set_many_cc_xsd_any_uris(addressed_ccs)?;
26   Ok(())
27 }
28
29 pub fn send_activity_to_community<A>(
30   creator: &User_,
31   conn: &PgConnection,
32   community: &Community,
33   to: Vec<String>,
34   activity: A,
35 ) -> Result<(), Error>
36 where
37   A: Activity + Base + Serialize + Debug,
38 {
39   insert_activity(&conn, creator.id, &activity, true)?;
40
41   // if this is a local community, we need to do an announce from the community instead
42   if community.local {
43     Community::do_announce(activity, &community, creator, conn)?;
44   } else {
45     send_activity(&activity, creator, to)?;
46   }
47   Ok(())
48 }
49
50 /// Send an activity to a list of recipients, using the correct headers etc.
51 pub fn send_activity<A>(activity: &A, actor: &dyn ActorType, to: Vec<String>) -> Result<(), Error>
52 where
53   A: Serialize + Debug,
54 {
55   let json = serde_json::to_string(&activity)?;
56   debug!("Sending activitypub activity {} to {:?}", json, to);
57   for t in to {
58     let to_url = Url::parse(&t)?;
59     if !is_apub_id_valid(&to_url) {
60       debug!("Not sending activity to {} (invalid or blocklisted)", t);
61       continue;
62     }
63     let request = Request::post(t).header("Host", to_url.domain().unwrap());
64     let signature = sign(&request, actor)?;
65     let res = request
66       .header("Signature", signature)
67       .header("Content-Type", "application/json")
68       .body(json.to_owned())?
69       .send()?;
70     debug!("Result for activity send: {:?}", res);
71   }
72   Ok(())
73 }