use super::*; #[serde(untagged)] #[derive(Serialize, Deserialize, Debug)] pub enum SharedAcceptedObjects { Create(Create), Update(Update), } impl SharedAcceptedObjects { fn object(&self) -> Option<&BaseBox> { match self { SharedAcceptedObjects::Create(c) => c.create_props.get_object_base_box(), SharedAcceptedObjects::Update(u) => u.update_props.get_object_base_box(), } } } /// Handler for all incoming activities to user inboxes. pub async fn shared_inbox( request: HttpRequest, input: web::Json, db: DbPoolParam, chat_server: ChatServerParam, ) -> Result { // TODO: would be nice if we could do the signature check here, but we cant access the actor property let activity = input.into_inner(); let conn = &db.get().unwrap(); let json = serde_json::to_string(&activity)?; debug!("Shared inbox received activity: {}", json); let object = activity.object().cloned().unwrap(); match (activity, object.kind()) { (SharedAcceptedObjects::Create(c), Some("Note")) => { receive_create_comment(&c, &request, &conn, chat_server) } (SharedAcceptedObjects::Create(c), Some("Page")) => { receive_create_post(&c, &request, &conn, chat_server) } (SharedAcceptedObjects::Update(u), Some("Note")) => { receive_update_comment(&u, &request, &conn, chat_server) } (SharedAcceptedObjects::Update(u), Some("Page")) => { receive_update_post(&u, &request, &conn, chat_server) } _ => Err(format_err!("Unknown incoming activity type.")), } } fn receive_create_post( create: &Create, request: &HttpRequest, conn: &PgConnection, chat_server: ChatServerParam, ) -> Result { let page = create .create_props .get_object_base_box() .to_owned() .unwrap() .to_owned() .to_concrete::()?; let user_uri = create .create_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())?; let post = PostForm::from_apub(&page, &conn)?; let inserted_post = Post::create(conn, &post)?; // Refetch the view let post_view = PostView::read(&conn, inserted_post.id, None)?; let res = PostResponse { post: post_view }; chat_server.do_send(SendPost { op: UserOperation::CreatePost, post: res, my_id: None, }); Ok(HttpResponse::Ok().finish()) } fn receive_create_comment( create: &Create, request: &HttpRequest, conn: &PgConnection, chat_server: ChatServerParam, ) -> Result { let note = create .create_props .get_object_base_box() .to_owned() .unwrap() .to_owned() .to_concrete::()?; let user_uri = create .create_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())?; let comment = CommentForm::from_apub(¬e, &conn)?; let inserted_comment = Comment::create(conn, &comment)?; // Refetch the view let comment_view = CommentView::read(&conn, inserted_comment.id, None)?; // TODO get those recipient actor ids from somewhere let recipient_ids = vec![]; let res = CommentResponse { comment: comment_view, recipient_ids, }; chat_server.do_send(SendComment { op: UserOperation::CreateComment, comment: res, my_id: None, }); Ok(HttpResponse::Ok().finish()) } fn receive_update_post( update: &Update, request: &HttpRequest, conn: &PgConnection, chat_server: ChatServerParam, ) -> Result { let page = update .update_props .get_object_base_box() .to_owned() .unwrap() .to_owned() .to_concrete::()?; let user_uri = update .update_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())?; let post = PostForm::from_apub(&page, conn)?; let post_id = Post::read_from_apub_id(conn, &post.ap_id)?.id; Post::update(conn, post_id, &post)?; // Refetch the view let post_view = PostView::read(&conn, post_id, None)?; let res = PostResponse { post: post_view }; chat_server.do_send(SendPost { op: UserOperation::EditPost, post: res, my_id: None, }); Ok(HttpResponse::Ok().finish()) } fn receive_update_comment( update: &Update, request: &HttpRequest, conn: &PgConnection, chat_server: ChatServerParam, ) -> Result { let note = update .update_props .get_object_base_box() .to_owned() .unwrap() .to_owned() .to_concrete::()?; let user_uri = update .update_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())?; let comment = CommentForm::from_apub(¬e, &conn)?; let comment_id = Comment::read_from_apub_id(conn, &comment.ap_id)?.id; Comment::update(conn, comment_id, &comment)?; // Refetch the view let comment_view = CommentView::read(&conn, comment_id, None)?; // TODO get those recipient actor ids from somewhere let recipient_ids = vec![]; let res = CommentResponse { comment: comment_view, recipient_ids, }; chat_server.do_send(SendComment { op: UserOperation::EditComment, comment: res, my_id: None, }); Ok(HttpResponse::Ok().finish()) }