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,
|
db::user_view::UserView,
|
||||||
};
|
};
|
||||||
|
use crate::apub::ActorType;
|
||||||
|
|
||||||
// Fetch nodeinfo metadata from a remote instance.
|
// Fetch nodeinfo metadata from a remote instance.
|
||||||
fn _fetch_node_info(domain: &str) -> Result<NodeInfo, Error> {
|
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> {
|
fn upsert_post(post_form: &PostForm, conn: &PgConnection) -> Result<Post, Error> {
|
||||||
let existing = Post::read_from_apub_id(conn, &post_form.ap_id);
|
let existing = Post::read_from_apub_id(conn, &post_form.ap_id);
|
||||||
match existing {
|
match existing {
|
||||||
|
|
|
@ -9,7 +9,6 @@ use crate::{
|
||||||
fetcher::{
|
fetcher::{
|
||||||
get_or_fetch_and_insert_remote_comment,
|
get_or_fetch_and_insert_remote_comment,
|
||||||
get_or_fetch_and_insert_remote_post,
|
get_or_fetch_and_insert_remote_post,
|
||||||
get_or_fetch_and_upsert_remote_community,
|
|
||||||
get_or_fetch_and_upsert_remote_user,
|
get_or_fetch_and_upsert_remote_user,
|
||||||
},
|
},
|
||||||
FromApub,
|
FromApub,
|
||||||
|
@ -47,6 +46,10 @@ use diesel::PgConnection;
|
||||||
use failure::{Error, _core::fmt::Debug};
|
use failure::{Error, _core::fmt::Debug};
|
||||||
use log::debug;
|
use log::debug;
|
||||||
use serde::{Deserialize, Serialize};
|
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)]
|
#[serde(untagged)]
|
||||||
#[derive(Serialize, Deserialize, Debug)]
|
#[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
|
// TODO: this is hacky, we should probably send the community id directly somehow
|
||||||
let to = cc.replace("/followers", "");
|
let to = cc.replace("/followers", "");
|
||||||
|
|
||||||
// TODO: this is ugly
|
let actor = get_or_fetch_and_upsert_remote_actor(&sender.to_string(), &conn)?;
|
||||||
match get_or_fetch_and_upsert_remote_user(&sender.to_string(), &conn) {
|
verify(&request, actor.as_ref())?;
|
||||||
Ok(u) => verify(&request, &u),
|
|
||||||
Err(_) => {
|
|
||||||
let c = get_or_fetch_and_upsert_remote_community(&sender.to_string(), &conn)?;
|
|
||||||
verify(&request, &c)
|
|
||||||
}
|
|
||||||
}?;
|
|
||||||
|
|
||||||
match (activity, object.kind()) {
|
match (activity, object.kind()) {
|
||||||
(SharedAcceptedObjects::Create(c), Some("Page")) => {
|
(SharedAcceptedObjects::Create(c), Some("Page")) => {
|
||||||
|
@ -142,6 +139,9 @@ pub async fn shared_inbox(
|
||||||
announce_activity_if_valid::<Create>(*c, &to, sender, conn)
|
announce_activity_if_valid::<Create>(*c, &to, sender, conn)
|
||||||
}
|
}
|
||||||
(SharedAcceptedObjects::Update(u), Some("Page")) => {
|
(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)?;
|
receive_update_post(&u, &conn, chat_server)?;
|
||||||
announce_activity_if_valid::<Update>(*u, &to, sender, conn)
|
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)
|
announce_activity_if_valid::<Dislike>(*d, &to, sender, conn)
|
||||||
}
|
}
|
||||||
(SharedAcceptedObjects::Delete(d), Some("Page")) => {
|
(SharedAcceptedObjects::Delete(d), Some("Page")) => {
|
||||||
|
//verify_delete_valid()?;
|
||||||
receive_delete_post(&d, &conn, chat_server)?;
|
receive_delete_post(&d, &conn, chat_server)?;
|
||||||
announce_activity_if_valid::<Delete>(*d, &to, sender, conn)
|
announce_activity_if_valid::<Delete>(*d, &to, sender, conn)
|
||||||
}
|
}
|
||||||
(SharedAcceptedObjects::Remove(r), Some("Page")) => {
|
(SharedAcceptedObjects::Remove(r), Some("Page")) => {
|
||||||
|
//verify_remove_valid()?;
|
||||||
receive_remove_post(&r, &conn, chat_server)?;
|
receive_remove_post(&r, &conn, chat_server)?;
|
||||||
announce_activity_if_valid::<Remove>(*r, &to, sender, conn)
|
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)
|
announce_activity_if_valid::<Create>(*c, &to, sender, conn)
|
||||||
}
|
}
|
||||||
(SharedAcceptedObjects::Update(u), Some("Note")) => {
|
(SharedAcceptedObjects::Update(u), Some("Note")) => {
|
||||||
|
verify_update_valid(actor, u.object_props.get_id().unwrap())?;
|
||||||
receive_update_comment(&u, &conn, chat_server)?;
|
receive_update_comment(&u, &conn, chat_server)?;
|
||||||
announce_activity_if_valid::<Update>(*u, &to, sender, conn)
|
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)
|
announce_activity_if_valid::<Dislike>(*d, &to, sender, conn)
|
||||||
}
|
}
|
||||||
(SharedAcceptedObjects::Delete(d), Some("Note")) => {
|
(SharedAcceptedObjects::Delete(d), Some("Note")) => {
|
||||||
|
//verify_delete_valid()?;
|
||||||
receive_delete_comment(&d, &conn, chat_server)?;
|
receive_delete_comment(&d, &conn, chat_server)?;
|
||||||
announce_activity_if_valid::<Delete>(*d, &to, sender, conn)
|
announce_activity_if_valid::<Delete>(*d, &to, sender, conn)
|
||||||
}
|
}
|
||||||
(SharedAcceptedObjects::Remove(r), Some("Note")) => {
|
(SharedAcceptedObjects::Remove(r), Some("Note")) => {
|
||||||
|
//verify_remove_valid()?;
|
||||||
receive_remove_comment(&r, &conn, chat_server)?;
|
receive_remove_comment(&r, &conn, chat_server)?;
|
||||||
announce_activity_if_valid::<Remove>(*r, &to, sender, conn)
|
announce_activity_if_valid::<Remove>(*r, &to, sender, conn)
|
||||||
}
|
}
|
||||||
(SharedAcceptedObjects::Delete(d), Some("Group")) => {
|
(SharedAcceptedObjects::Delete(d), Some("Group")) => {
|
||||||
|
//verify_delete_valid()?;
|
||||||
receive_delete_community(&d, &conn, chat_server)?;
|
receive_delete_community(&d, &conn, chat_server)?;
|
||||||
announce_activity_if_valid::<Delete>(*d, &to, sender, conn)
|
announce_activity_if_valid::<Delete>(*d, &to, sender, conn)
|
||||||
}
|
}
|
||||||
(SharedAcceptedObjects::Remove(r), Some("Group")) => {
|
(SharedAcceptedObjects::Remove(r), Some("Group")) => {
|
||||||
|
//verify_remove_valid()?;
|
||||||
receive_remove_community(&r, &conn, chat_server)?;
|
receive_remove_community(&r, &conn, chat_server)?;
|
||||||
announce_activity_if_valid::<Remove>(*r, &to, sender, conn)
|
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")) => {
|
(SharedAcceptedObjects::Undo(u), Some("Delete")) => {
|
||||||
|
//verify_delete_valid()?;
|
||||||
receive_undo_delete(&u, &conn, chat_server)?;
|
receive_undo_delete(&u, &conn, chat_server)?;
|
||||||
announce_activity_if_valid::<Undo>(*u, &to, sender, conn)
|
announce_activity_if_valid::<Undo>(*u, &to, sender, conn)
|
||||||
}
|
}
|
||||||
(SharedAcceptedObjects::Undo(u), Some("Remove")) => {
|
(SharedAcceptedObjects::Undo(u), Some("Remove")) => {
|
||||||
|
//verify_remove_valid()?;
|
||||||
receive_undo_remove(&u, &conn, chat_server)?;
|
receive_undo_remove(&u, &conn, chat_server)?;
|
||||||
announce_activity_if_valid::<Undo>(*u, &to, sender, conn)
|
announce_activity_if_valid::<Undo>(*u, &to, sender, conn)
|
||||||
}
|
}
|
||||||
|
@ -221,6 +231,12 @@ where
|
||||||
A: Activity + Base + Serialize + Debug,
|
A: Activity + Base + Serialize + Debug,
|
||||||
{
|
{
|
||||||
let community = Community::read_from_actor_id(conn, &community_uri)?;
|
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 {
|
if community.local {
|
||||||
let sending_user = get_or_fetch_and_upsert_remote_user(&sender.to_string(), &conn)?;
|
let sending_user = get_or_fetch_and_upsert_remote_user(&sender.to_string(), &conn)?;
|
||||||
Community::do_announce(activity, &community, &sending_user, conn)
|
Community::do_announce(activity, &community, &sending_user, conn)
|
||||||
|
@ -1613,3 +1629,19 @@ fn receive_undo_like_post(
|
||||||
|
|
||||||
Ok(HttpResponse::Ok().finish())
|
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