Let community announce posts

This commit is contained in:
Felix 2020-05-06 19:10:36 +02:00
parent dce5f87415
commit a407155550
3 changed files with 109 additions and 35 deletions

View file

@ -278,19 +278,7 @@ impl ActorType for Community {
Ok(
CommunityFollowerView::for_community(conn, self.id)?
.into_iter()
// TODO eventually this will have to use the inbox or shared_inbox column, meaning that view
// will have to change
.map(|c| {
// If the user is local, but the community isn't, get the community shared inbox
// and vice versa
if c.user_local && !c.community_local {
get_shared_inbox(&c.community_actor_id)
} else if !c.user_local && c.community_local {
get_shared_inbox(&c.user_actor_id)
} else {
"".to_string()
}
})
.map(|c| get_shared_inbox(&c.user_actor_id))
.filter(|s| !s.is_empty())
.unique()
.collect(),

View file

@ -1,10 +1,16 @@
use super::*;
use activitystreams::activity::{Activity, Announce};
use activitystreams::Base;
#[serde(untagged)]
#[derive(Deserialize, Debug)]
pub enum CommunityAcceptedObjects {
Follow(Follow),
Undo(Undo),
Follow(Box<Follow>),
Undo(Box<Undo>),
Create(Box<Create>),
Update(Box<Update>),
Delete(Box<Delete>),
Remove(Box<Remove>),
}
// TODO Consolidate community and user inboxes into a single shared one
@ -17,17 +23,39 @@ pub async fn community_inbox(
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
);
match input {
CommunityAcceptedObjects::Follow(f) => {
handle_follow(&f, &request, &community_name, db, chat_server)
handle_follow(&f, &request, &community, &conn, chat_server)
}
CommunityAcceptedObjects::Undo(u) => {
handle_undo_follow(&u, &request, &community_name, db, chat_server)
// TODO: if this is an undo<remove> or undo<delete>, we need to announce it instead
handle_undo_follow(&u, &request, &community, &conn, chat_server)
}
// 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)
}
}
}
@ -37,8 +65,8 @@ pub async fn community_inbox(
fn handle_follow(
follow: &Follow,
request: &HttpRequest,
community_name: &str,
db: DbPoolParam,
community: &Community,
conn: &PgConnection,
_chat_server: ChatServerParam,
) -> Result<HttpResponse, Error> {
let user_uri = follow
@ -46,16 +74,14 @@ fn handle_follow(
.get_actor_xsd_any_uri()
.unwrap()
.to_string();
// TODO: need to check that community_uri == community.actor_id (for all activities)
let _community_uri = follow
.follow_props
.get_object_xsd_any_uri()
.unwrap()
.to_string();
let conn = db.get()?;
let user = get_or_fetch_and_upsert_remote_user(&user_uri, &conn)?;
let community = Community::read_from_name(&conn, &community_name)?;
verify(&request, &user.public_key.unwrap())?;
@ -84,8 +110,8 @@ fn handle_follow(
fn handle_undo_follow(
undo: &Undo,
request: &HttpRequest,
community_name: &str,
db: DbPoolParam,
community: &Community,
conn: &PgConnection,
_chat_server: ChatServerParam,
) -> Result<HttpResponse, Error> {
let follow = undo
@ -108,10 +134,7 @@ fn handle_undo_follow(
.unwrap()
.to_string();
let conn = db.get()?;
let user = get_or_fetch_and_upsert_remote_user(&user_uri, &conn)?;
let community = Community::read_from_name(&conn, &community_name)?;
verify(&request, &user.public_key.unwrap())?;
@ -133,3 +156,65 @@ fn handle_undo_follow(
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 the received activity into the activity table
let activity_form = activity::ActivityForm {
user_id: -1,
data: serde_json::to_value(&activity)?,
local: false,
updated: None,
};
activity::Activity::create(&conn, &activity_form)?;
// TODO: handle the sending in community.rs
let mut announce = Announce::default();
populate_object_props(
&mut announce.object_props,
&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 the sent activity into the activity table
let activity_form = activity::ActivityForm {
user_id: -1,
data: serde_json::to_value(&announce)?,
local: true,
updated: None,
};
activity::Activity::create(&conn, &activity_form)?;
send_activity(
&announce,
&community.private_key.as_ref().unwrap(),
&community.actor_id,
community.get_follower_inboxes(&conn)?,
)?;
Ok(HttpResponse::Ok().finish())
}

View file

@ -145,7 +145,7 @@ impl ApubObjectType for Post {
&create,
&creator.private_key.as_ref().unwrap(),
&creator.actor_id,
community.get_follower_inboxes(&conn)?,
vec![community.get_inbox_url()],
)?;
Ok(())
}
@ -180,7 +180,8 @@ impl ApubObjectType for Post {
&update,
&creator.private_key.as_ref().unwrap(),
&creator.actor_id,
community.get_follower_inboxes(&conn)?,
// TODO: i think we need to do the same thing for all post actions
vec![community.get_inbox_url()],
)?;
Ok(())
}
@ -216,7 +217,7 @@ impl ApubObjectType for Post {
&delete,
&creator.private_key.as_ref().unwrap(),
&creator.actor_id,
community.get_follower_inboxes(&conn)?,
vec![community.get_inbox_url()],
)?;
Ok(())
}
@ -268,7 +269,7 @@ impl ApubObjectType for Post {
&undo,
&creator.private_key.as_ref().unwrap(),
&creator.actor_id,
community.get_follower_inboxes(&conn)?,
vec![community.get_inbox_url()],
)?;
Ok(())
}
@ -304,7 +305,7 @@ impl ApubObjectType for Post {
&remove,
&mod_.private_key.as_ref().unwrap(),
&mod_.actor_id,
community.get_follower_inboxes(&conn)?,
vec![community.get_inbox_url()],
)?;
Ok(())
}
@ -354,7 +355,7 @@ impl ApubObjectType for Post {
&undo,
&mod_.private_key.as_ref().unwrap(),
&mod_.actor_id,
community.get_follower_inboxes(&conn)?,
vec![community.get_inbox_url()],
)?;
Ok(())
}