mirror of
https://github.com/LemmyNet/lemmy.git
synced 2024-11-14 00:14:03 +00:00
Let community announce posts
This commit is contained in:
parent
b08574fd57
commit
5753c4feaa
4 changed files with 100 additions and 30 deletions
|
@ -283,19 +283,7 @@ impl ActorType for Community {
|
||||||
Ok(
|
Ok(
|
||||||
CommunityFollowerView::for_community(conn, self.id)?
|
CommunityFollowerView::for_community(conn, self.id)?
|
||||||
.into_iter()
|
.into_iter()
|
||||||
// TODO eventually this will have to use the inbox or shared_inbox column, meaning that view
|
.map(|c| get_shared_inbox(&c.user_actor_id))
|
||||||
// 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()
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.filter(|s| !s.is_empty())
|
.filter(|s| !s.is_empty())
|
||||||
.unique()
|
.unique()
|
||||||
.collect(),
|
.collect(),
|
||||||
|
|
|
@ -12,18 +12,26 @@ use crate::{
|
||||||
},
|
},
|
||||||
routes::{ChatServerParam, DbPoolParam},
|
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 actix_web::{web, HttpRequest, HttpResponse, Result};
|
||||||
use diesel::PgConnection;
|
use diesel::PgConnection;
|
||||||
use failure::{Error, _core::fmt::Debug};
|
use failure::{Error, _core::fmt::Debug};
|
||||||
use log::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)]
|
#[serde(untagged)]
|
||||||
#[derive(Deserialize, Debug)]
|
#[derive(Deserialize, Debug)]
|
||||||
pub enum CommunityAcceptedObjects {
|
pub enum CommunityAcceptedObjects {
|
||||||
Follow(Follow),
|
Follow(Follow),
|
||||||
Undo(Undo),
|
Undo(Undo),
|
||||||
|
Create(Create),
|
||||||
|
Update(Update),
|
||||||
|
Delete(Delete),
|
||||||
|
Remove(Remove),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl CommunityAcceptedObjects {
|
impl CommunityAcceptedObjects {
|
||||||
|
@ -38,6 +46,7 @@ impl CommunityAcceptedObjects {
|
||||||
.to_owned()
|
.to_owned()
|
||||||
.into_concrete::<Follow>()?,
|
.into_concrete::<Follow>()?,
|
||||||
),
|
),
|
||||||
|
_ => todo!()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -49,13 +58,20 @@ pub async fn community_inbox(
|
||||||
input: web::Json<CommunityAcceptedObjects>,
|
input: web::Json<CommunityAcceptedObjects>,
|
||||||
path: web::Path<String>,
|
path: web::Path<String>,
|
||||||
db: DbPoolParam,
|
db: DbPoolParam,
|
||||||
_chat_server: ChatServerParam,
|
chat_server: ChatServerParam,
|
||||||
) -> Result<HttpResponse, Error> {
|
) -> Result<HttpResponse, Error> {
|
||||||
let input = input.into_inner();
|
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!(
|
debug!(
|
||||||
"Community {} received activity {:?}",
|
"Community {} received activity {:?}",
|
||||||
&community_name, &input
|
&community.name, &input
|
||||||
);
|
);
|
||||||
let follow = input.follow()?;
|
let follow = input.follow()?;
|
||||||
let user_uri = follow
|
let user_uri = follow
|
||||||
|
@ -77,8 +93,27 @@ pub async fn community_inbox(
|
||||||
verify(&request, &user)?;
|
verify(&request, &user)?;
|
||||||
|
|
||||||
match input {
|
match input {
|
||||||
CommunityAcceptedObjects::Follow(f) => handle_follow(&f, &user, &community, &conn),
|
CommunityAcceptedObjects::Follow(f) => {
|
||||||
CommunityAcceptedObjects::Undo(u) => handle_undo_follow(&u, &user, &community, &conn),
|
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)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -122,3 +157,50 @@ fn handle_undo_follow(
|
||||||
|
|
||||||
Ok(HttpResponse::Ok().finish())
|
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())
|
||||||
|
}
|
||||||
|
|
|
@ -241,7 +241,7 @@ impl ApubObjectType for Post {
|
||||||
|
|
||||||
insert_activity(&conn, creator.id, &create, true)?;
|
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(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -264,7 +264,7 @@ impl ApubObjectType for Post {
|
||||||
|
|
||||||
insert_activity(&conn, creator.id, &update, true)?;
|
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(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -288,7 +288,7 @@ impl ApubObjectType for Post {
|
||||||
insert_activity(&conn, self.creator_id, &delete, true)?;
|
insert_activity(&conn, self.creator_id, &delete, true)?;
|
||||||
|
|
||||||
let community = Community::read(conn, self.community_id)?;
|
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(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -328,7 +328,7 @@ impl ApubObjectType for Post {
|
||||||
insert_activity(&conn, self.creator_id, &undo, true)?;
|
insert_activity(&conn, self.creator_id, &undo, true)?;
|
||||||
|
|
||||||
let community = Community::read(conn, self.community_id)?;
|
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(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -352,7 +352,7 @@ impl ApubObjectType for Post {
|
||||||
insert_activity(&conn, mod_.id, &remove, true)?;
|
insert_activity(&conn, mod_.id, &remove, true)?;
|
||||||
|
|
||||||
let community = Community::read(conn, self.community_id)?;
|
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(())
|
Ok(())
|
||||||
}
|
}
|
||||||
fn send_undo_remove(&self, mod_: &User_, conn: &PgConnection) -> Result<(), Error> {
|
fn send_undo_remove(&self, mod_: &User_, conn: &PgConnection) -> Result<(), Error> {
|
||||||
|
@ -390,7 +390,7 @@ impl ApubObjectType for Post {
|
||||||
insert_activity(&conn, mod_.id, &undo, true)?;
|
insert_activity(&conn, mod_.id, &undo, true)?;
|
||||||
|
|
||||||
let community = Community::read(conn, self.community_id)?;
|
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(())
|
Ok(())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -414,7 +414,7 @@ impl ApubLikeableType for Post {
|
||||||
|
|
||||||
insert_activity(&conn, creator.id, &like, true)?;
|
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(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -436,7 +436,7 @@ impl ApubLikeableType for Post {
|
||||||
|
|
||||||
insert_activity(&conn, creator.id, &dislike, true)?;
|
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(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -474,7 +474,7 @@ impl ApubLikeableType for Post {
|
||||||
|
|
||||||
insert_activity(&conn, creator.id, &undo, true)?;
|
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(())
|
Ok(())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue