lemmy/server/src/apub/community_inbox.rs

136 lines
3.4 KiB
Rust
Raw Normal View History

2020-04-24 14:04:36 +00:00
use super::*;
#[serde(untagged)]
2020-04-17 14:55:28 +00:00
#[derive(Deserialize, Debug)]
pub enum CommunityAcceptedObjects {
Follow(Follow),
2020-05-04 02:41:45 +00:00
Undo(Undo),
}
2020-04-24 19:55:54 +00:00
// TODO Consolidate community and user inboxes into a single shared one
2020-04-17 15:33:55 +00:00
/// Handler for all incoming activities to community inboxes.
pub async fn community_inbox(
2020-04-19 17:35:40 +00:00
request: HttpRequest,
input: web::Json<CommunityAcceptedObjects>,
2020-04-17 17:34:18 +00:00
path: web::Path<String>,
2020-04-24 14:04:36 +00:00
db: DbPoolParam,
chat_server: ChatServerParam,
) -> Result<HttpResponse, Error> {
let input = input.into_inner();
2020-04-24 14:04:36 +00:00
let community_name = path.into_inner();
2020-04-17 14:55:28 +00:00
debug!(
"Community {} received activity {:?}",
2020-04-24 19:55:54 +00:00
&community_name, &input
2020-04-17 14:55:28 +00:00
);
match input {
2020-04-24 19:55:54 +00:00
CommunityAcceptedObjects::Follow(f) => {
handle_follow(&f, &request, &community_name, db, chat_server)
}
2020-05-04 02:41:45 +00:00
CommunityAcceptedObjects::Undo(u) => {
handle_undo_follow(&u, &request, &community_name, db, chat_server)
}
}
}
2020-04-17 15:33:55 +00:00
/// Handle a follow request from a remote user, adding it to the local database and returning an
/// Accept activity.
2020-04-19 17:35:40 +00:00
fn handle_follow(
follow: &Follow,
request: &HttpRequest,
2020-04-24 14:04:36 +00:00
community_name: &str,
db: DbPoolParam,
2020-04-24 19:55:54 +00:00
_chat_server: ChatServerParam,
2020-04-19 17:35:40 +00:00
) -> Result<HttpResponse, Error> {
let user_uri = follow
.follow_props
.get_actor_xsd_any_uri()
.unwrap()
.to_string();
2020-04-24 19:55:54 +00:00
let _community_uri = follow
.follow_props
.get_object_xsd_any_uri()
.unwrap()
.to_string();
2020-04-24 14:04:36 +00:00
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())?;
2020-04-27 22:17:02 +00:00
// Insert the received activity into the activity table
let activity_form = activity::ActivityForm {
user_id: user.id,
data: serde_json::to_value(&follow)?,
local: false,
updated: None,
};
activity::Activity::create(&conn, &activity_form)?;
let community_follower_form = CommunityFollowerForm {
community_id: community.id,
user_id: user.id,
};
2020-04-24 14:04:36 +00:00
// This will fail if they're already a follower, but ignore the error.
CommunityFollower::follow(&conn, &community_follower_form).ok();
2020-04-24 14:04:36 +00:00
2020-04-27 22:17:02 +00:00
community.send_accept_follow(&follow, &conn)?;
Ok(HttpResponse::Ok().finish())
}
2020-05-04 02:41:45 +00:00
fn handle_undo_follow(
undo: &Undo,
request: &HttpRequest,
community_name: &str,
db: DbPoolParam,
_chat_server: ChatServerParam,
) -> Result<HttpResponse, Error> {
let follow = undo
.undo_props
.get_object_base_box()
.to_owned()
.unwrap()
.to_owned()
.into_concrete::<Follow>()?;
let user_uri = follow
.follow_props
.get_actor_xsd_any_uri()
.unwrap()
.to_string();
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())?;
// Insert the received activity into the activity table
let activity_form = activity::ActivityForm {
user_id: user.id,
data: serde_json::to_value(&follow)?,
local: false,
updated: None,
};
activity::Activity::create(&conn, &activity_form)?;
let community_follower_form = CommunityFollowerForm {
community_id: community.id,
user_id: user.id,
};
CommunityFollower::ignore(&conn, &community_follower_form).ok();
Ok(HttpResponse::Ok().finish())
}