WIP: Verify permissions in shared inbox
This commit is contained in:
parent
cfa40e482a
commit
a2e2b762d7
2 changed files with 58 additions and 9 deletions
|
@ -38,6 +38,7 @@ use crate::{
|
|||
},
|
||||
db::user_view::UserView,
|
||||
};
|
||||
use crate::apub::ActorType;
|
||||
|
||||
// Fetch nodeinfo metadata from a remote instance.
|
||||
fn _fetch_node_info(domain: &str) -> Result<NodeInfo, Error> {
|
||||
|
@ -245,6 +246,22 @@ pub fn get_or_fetch_and_upsert_remote_community(
|
|||
}
|
||||
}
|
||||
|
||||
pub fn get_or_fetch_and_upsert_remote_actor(
|
||||
apub_id: &str,
|
||||
conn: &PgConnection,
|
||||
) -> Result<Box<dyn ActorType>, Error> {
|
||||
let user = get_or_fetch_and_upsert_remote_user(apub_id, &conn);
|
||||
if user.is_ok() {
|
||||
return Ok(Box::new(user?));
|
||||
}
|
||||
let community = get_or_fetch_and_upsert_remote_community(apub_id, &conn);
|
||||
if community.is_ok() {
|
||||
return Ok(Box::new(community?));
|
||||
} else {
|
||||
todo!() // need proper error handling
|
||||
}
|
||||
}
|
||||
|
||||
fn upsert_post(post_form: &PostForm, conn: &PgConnection) -> Result<Post, Error> {
|
||||
let existing = Post::read_from_apub_id(conn, &post_form.ap_id);
|
||||
match existing {
|
||||
|
|
|
@ -9,7 +9,6 @@ use crate::{
|
|||
fetcher::{
|
||||
get_or_fetch_and_insert_remote_comment,
|
||||
get_or_fetch_and_insert_remote_post,
|
||||
get_or_fetch_and_upsert_remote_community,
|
||||
get_or_fetch_and_upsert_remote_user,
|
||||
},
|
||||
FromApub,
|
||||
|
@ -47,6 +46,10 @@ use diesel::PgConnection;
|
|||
use failure::{Error, _core::fmt::Debug};
|
||||
use log::debug;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use http::Uri;
|
||||
use crate::apub::ActorType;
|
||||
use crate::apub::fetcher::get_or_fetch_and_upsert_remote_actor;
|
||||
use activitystreams::primitives::XsdAnyUri;
|
||||
|
||||
#[serde(untagged)]
|
||||
#[derive(Serialize, Deserialize, Debug)]
|
||||
|
@ -127,14 +130,8 @@ pub async fn shared_inbox(
|
|||
// TODO: this is hacky, we should probably send the community id directly somehow
|
||||
let to = cc.replace("/followers", "");
|
||||
|
||||
// TODO: this is ugly
|
||||
match get_or_fetch_and_upsert_remote_user(&sender.to_string(), &conn) {
|
||||
Ok(u) => verify(&request, &u),
|
||||
Err(_) => {
|
||||
let c = get_or_fetch_and_upsert_remote_community(&sender.to_string(), &conn)?;
|
||||
verify(&request, &c)
|
||||
}
|
||||
}?;
|
||||
let actor = get_or_fetch_and_upsert_remote_actor(&sender.to_string(), &conn)?;
|
||||
verify(&request, actor.as_ref())?;
|
||||
|
||||
match (activity, object.kind()) {
|
||||
(SharedAcceptedObjects::Create(c), Some("Page")) => {
|
||||
|
@ -142,6 +139,9 @@ pub async fn shared_inbox(
|
|||
announce_activity_if_valid::<Create>(*c, &to, sender, conn)
|
||||
}
|
||||
(SharedAcceptedObjects::Update(u), Some("Page")) => {
|
||||
// TODO: need to get the object::attributed_to here
|
||||
// (ideally from the database in case we received malicious data)
|
||||
verify_update_valid(actor, object)?;
|
||||
receive_update_post(&u, &conn, chat_server)?;
|
||||
announce_activity_if_valid::<Update>(*u, &to, sender, conn)
|
||||
}
|
||||
|
@ -154,10 +154,12 @@ pub async fn shared_inbox(
|
|||
announce_activity_if_valid::<Dislike>(*d, &to, sender, conn)
|
||||
}
|
||||
(SharedAcceptedObjects::Delete(d), Some("Page")) => {
|
||||
//verify_delete_valid()?;
|
||||
receive_delete_post(&d, &conn, chat_server)?;
|
||||
announce_activity_if_valid::<Delete>(*d, &to, sender, conn)
|
||||
}
|
||||
(SharedAcceptedObjects::Remove(r), Some("Page")) => {
|
||||
//verify_remove_valid()?;
|
||||
receive_remove_post(&r, &conn, chat_server)?;
|
||||
announce_activity_if_valid::<Remove>(*r, &to, sender, conn)
|
||||
}
|
||||
|
@ -166,6 +168,7 @@ pub async fn shared_inbox(
|
|||
announce_activity_if_valid::<Create>(*c, &to, sender, conn)
|
||||
}
|
||||
(SharedAcceptedObjects::Update(u), Some("Note")) => {
|
||||
verify_update_valid(actor, u.object_props.get_id().unwrap())?;
|
||||
receive_update_comment(&u, &conn, chat_server)?;
|
||||
announce_activity_if_valid::<Update>(*u, &to, sender, conn)
|
||||
}
|
||||
|
@ -178,26 +181,33 @@ pub async fn shared_inbox(
|
|||
announce_activity_if_valid::<Dislike>(*d, &to, sender, conn)
|
||||
}
|
||||
(SharedAcceptedObjects::Delete(d), Some("Note")) => {
|
||||
//verify_delete_valid()?;
|
||||
receive_delete_comment(&d, &conn, chat_server)?;
|
||||
announce_activity_if_valid::<Delete>(*d, &to, sender, conn)
|
||||
}
|
||||
(SharedAcceptedObjects::Remove(r), Some("Note")) => {
|
||||
//verify_remove_valid()?;
|
||||
receive_remove_comment(&r, &conn, chat_server)?;
|
||||
announce_activity_if_valid::<Remove>(*r, &to, sender, conn)
|
||||
}
|
||||
(SharedAcceptedObjects::Delete(d), Some("Group")) => {
|
||||
//verify_delete_valid()?;
|
||||
receive_delete_community(&d, &conn, chat_server)?;
|
||||
announce_activity_if_valid::<Delete>(*d, &to, sender, conn)
|
||||
}
|
||||
(SharedAcceptedObjects::Remove(r), Some("Group")) => {
|
||||
//verify_remove_valid()?;
|
||||
receive_remove_community(&r, &conn, chat_server)?;
|
||||
announce_activity_if_valid::<Remove>(*r, &to, sender, conn)
|
||||
}
|
||||
// TODO: for any undo, we should check if the activity to be undone exists
|
||||
(SharedAcceptedObjects::Undo(u), Some("Delete")) => {
|
||||
//verify_delete_valid()?;
|
||||
receive_undo_delete(&u, &conn, chat_server)?;
|
||||
announce_activity_if_valid::<Undo>(*u, &to, sender, conn)
|
||||
}
|
||||
(SharedAcceptedObjects::Undo(u), Some("Remove")) => {
|
||||
//verify_remove_valid()?;
|
||||
receive_undo_remove(&u, &conn, chat_server)?;
|
||||
announce_activity_if_valid::<Undo>(*u, &to, sender, conn)
|
||||
}
|
||||
|
@ -221,6 +231,12 @@ where
|
|||
A: Activity + Base + Serialize + Debug,
|
||||
{
|
||||
let community = Community::read_from_actor_id(conn, &community_uri)?;
|
||||
// TODO: only allow specific types of activities here:
|
||||
// - create/like/dislike page/note
|
||||
// - update only from the same user that created a page/note
|
||||
// - undo for the activities above
|
||||
// - delete or undo delete only from the user that created the object
|
||||
// - remove only for local admins or local mods of the community
|
||||
if community.local {
|
||||
let sending_user = get_or_fetch_and_upsert_remote_user(&sender.to_string(), &conn)?;
|
||||
Community::do_announce(activity, &community, &sending_user, conn)
|
||||
|
@ -1613,3 +1629,19 @@ fn receive_undo_like_post(
|
|||
|
||||
Ok(HttpResponse::Ok().finish())
|
||||
}
|
||||
|
||||
fn verify_update_valid(actor_id: Box<dyn ActorType>, object: &BaseBox) -> Result<(), Error> {
|
||||
|
||||
todo!()
|
||||
// can only come from the user that created the object
|
||||
}
|
||||
|
||||
fn verify_delete_valid(actor_id: Box<dyn ActorType>, object_id: Uri) -> Result<(), Error> {
|
||||
todo!()
|
||||
// can only come from the user that created the object
|
||||
}
|
||||
|
||||
fn verify_remove_valid(actor_id: Box<dyn ActorType>, object_id: Uri, community: &Community) -> Result<(), Error> {
|
||||
todo!()
|
||||
// can only come from admins or mods on the instance of the community
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue