},
routes::{ChatServerParam, DbPoolParam},
};
-use activitystreams::activity::{Follow, Undo};
+use activitystreams::activity::{Follow, Undo, Update, Create, Delete, Remove};
use actix_web::{web, HttpRequest, HttpResponse, Result};
use diesel::PgConnection;
use failure::{Error, _core::fmt::Debug};
use log::debug;
-use serde::Deserialize;
+use serde::{Deserialize, Serialize};
+use activitystreams::activity::{Activity, Announce};
+use activitystreams::Base;
+use crate::apub::activities::{populate_object_props, send_activity};
+use activitystreams::BaseBox;
#[serde(untagged)]
#[derive(Deserialize, Debug)]
pub enum CommunityAcceptedObjects {
Follow(Follow),
Undo(Undo),
+ Create(Create),
+ Update(Update),
+ Delete(Delete),
+ Remove(Remove),
}
impl CommunityAcceptedObjects {
.to_owned()
.into_concrete::<Follow>()?,
),
+ _ => todo!()
}
}
}
input: web::Json<CommunityAcceptedObjects>,
path: web::Path<String>,
db: DbPoolParam,
- _chat_server: ChatServerParam,
+ chat_server: ChatServerParam,
) -> Result<HttpResponse, Error> {
let input = input.into_inner();
- let community_name = path.into_inner();
+ let conn = db.get()?;
+ let community = Community::read_from_name(&conn, &path.into_inner())?;
+ if !community.local {
+ return Err(format_err!(
+ "Received activity is addressed to remote community {}",
+ &community.actor_id
+ ));
+ }
debug!(
"Community {} received activity {:?}",
- &community_name, &input
+ &community.name, &input
);
let follow = input.follow()?;
let user_uri = follow
verify(&request, &user)?;
match input {
- CommunityAcceptedObjects::Follow(f) => handle_follow(&f, &user, &community, &conn),
- CommunityAcceptedObjects::Undo(u) => handle_undo_follow(&u, &user, &community, &conn),
+ CommunityAcceptedObjects::Follow(f) => {
+ handle_follow(&f, &user, &community, &conn)
+ }
+ CommunityAcceptedObjects::Undo(u) => {
+ // TODO: if this is an undo<remove> or undo<delete>, we need to announce it instead
+ handle_undo_follow(&u, &user, &community, &conn)
+ }
+ // TODO: we should be able to handle all this with a single wildcard match, but i dont see how
+ // to get the value from that
+ CommunityAcceptedObjects::Create(c) => {
+ do_announce(c, &request, &community, &conn, chat_server)
+ }
+ CommunityAcceptedObjects::Update(u) => {
+ do_announce(u, &request, &community, &conn, chat_server)
+ }
+ CommunityAcceptedObjects::Delete(d) => {
+ do_announce(d, &request, &community, &conn, chat_server)
+ }
+ CommunityAcceptedObjects::Remove(r) => {
+ do_announce(r, &request, &community, &conn, chat_server)
+ }
}
}
Ok(HttpResponse::Ok().finish())
}
+
+fn do_announce<A>(
+ activity: A,
+ _request: &HttpRequest,
+ community: &Community,
+ conn: &PgConnection,
+ _chat_server: ChatServerParam,
+) -> Result<HttpResponse, Error>
+where
+ A: Activity + Base + Serialize,
+{
+ // TODO: checking the signature needs a lot of boilerplate, unless this gets implemented
+ // https://git.asonix.dog/Aardwolf/activitystreams/issues/4
+ /*
+ let user_uri = activity
+ .follow_props
+ .get_actor_xsd_any_uri()
+ .unwrap()
+ .to_string();
+ let user = get_or_fetch_and_upsert_remote_user(&user_uri, &conn)?;
+ verify(&request, &user.public_key.unwrap())?;
+ */
+
+ insert_activity(&conn, -1, &activity, false)?;
+
+ // TODO: handle the sending in community.rs
+ let mut announce = Announce::default();
+ populate_object_props(
+ &mut announce.object_props,
+ vec!(community.get_followers_url()),
+ &format!("{}/announce/{}", community.actor_id, uuid::Uuid::new_v4()),
+ )?;
+ announce
+ .announce_props
+ .set_actor_xsd_any_uri(community.actor_id.to_owned())?
+ .set_object_base_box(BaseBox::from_concrete(activity)?)?;
+
+ insert_activity(&conn, -1, &announce, true)?;
+
+ send_activity(
+ &announce,
+ community,
+ community.get_follower_inboxes(&conn)?,
+ )?;
+
+ Ok(HttpResponse::Ok().finish())
+}
insert_activity(&conn, creator.id, &create, true)?;
- send_activity(&create, creator, community.get_follower_inboxes(&conn)?)?;
+ send_activity(&create, creator, vec!(community.get_inbox_url()))?;
Ok(())
}
insert_activity(&conn, creator.id, &update, true)?;
- send_activity(&update, creator, community.get_follower_inboxes(&conn)?)?;
+ send_activity(&update, creator, vec!(community.get_inbox_url()))?;
Ok(())
}
insert_activity(&conn, self.creator_id, &delete, true)?;
let community = Community::read(conn, self.community_id)?;
- send_activity(&delete, creator, community.get_follower_inboxes(&conn)?)?;
+ send_activity(&delete, creator, vec!(community.get_inbox_url()))?;
Ok(())
}
insert_activity(&conn, self.creator_id, &undo, true)?;
let community = Community::read(conn, self.community_id)?;
- send_activity(&undo, creator, community.get_follower_inboxes(&conn)?)?;
+ send_activity(&undo, creator, vec!(community.get_inbox_url()))?;
Ok(())
}
insert_activity(&conn, mod_.id, &remove, true)?;
let community = Community::read(conn, self.community_id)?;
- send_activity(&remove, mod_, community.get_follower_inboxes(&conn)?)?;
+ send_activity(&remove, mod_, vec!(community.get_inbox_url()))?;
Ok(())
}
fn send_undo_remove(&self, mod_: &User_, conn: &PgConnection) -> Result<(), Error> {
insert_activity(&conn, mod_.id, &undo, true)?;
let community = Community::read(conn, self.community_id)?;
- send_activity(&undo, mod_, community.get_follower_inboxes(&conn)?)?;
+ send_activity(&undo, mod_, vec!(community.get_inbox_url()))?;
Ok(())
}
}
insert_activity(&conn, creator.id, &like, true)?;
- send_activity(&like, creator, community.get_follower_inboxes(&conn)?)?;
+ send_activity(&like, creator, vec!(community.get_inbox_url()))?;
Ok(())
}
insert_activity(&conn, creator.id, &dislike, true)?;
- send_activity(&dislike, creator, community.get_follower_inboxes(&conn)?)?;
+ send_activity(&dislike, creator, vec!(community.get_inbox_url()))?;
Ok(())
}
insert_activity(&conn, creator.id, &undo, true)?;
- send_activity(&undo, creator, community.get_follower_inboxes(&conn)?)?;
+ send_activity(&undo, creator, vec!(community.get_inbox_url()))?;
Ok(())
}
}