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