From f4d7dfb2611fb11512f592830895f0541dfdb26b Mon Sep 17 00:00:00 2001 From: Kitaiti Makoto Date: Wed, 24 Nov 2021 22:50:16 +0900 Subject: [PATCH] Sign GET request to other instances --- plume-common/src/activity_pub/inbox.rs | 29 ++++++++++++++++++------ plume-common/src/activity_pub/request.rs | 4 ++-- plume-models/src/blogs.rs | 4 ++++ plume-models/src/comments.rs | 5 ++++ plume-models/src/follows.rs | 8 +++++-- plume-models/src/likes.rs | 9 ++++++-- plume-models/src/posts.rs | 9 ++++++++ plume-models/src/reshares.rs | 9 ++++++-- plume-models/src/users.rs | 4 ++++ 9 files changed, 66 insertions(+), 15 deletions(-) diff --git a/plume-common/src/activity_pub/inbox.rs b/plume-common/src/activity_pub/inbox.rs index 0f88b5d9..c7625454 100644 --- a/plume-common/src/activity_pub/inbox.rs +++ b/plume-common/src/activity_pub/inbox.rs @@ -1,6 +1,11 @@ -use reqwest::header::{HeaderValue, ACCEPT}; +use reqwest::{ + header::{HeaderValue, HOST}, + Url, +}; use std::fmt::Debug; +use super::{request, sign::Signer}; + /// Represents an ActivityPub inbox. /// /// It routes an incoming Activity through the registered handlers. @@ -311,6 +316,14 @@ pub trait FromId: Sized { id: &str, proxy: Option, ) -> Result, Self::Error)> { + let mut headers = request::headers(); + let url = Url::parse(id).map_err(|_| (None, InboxError::DerefError.into()))?; + if !url.has_host() { + return Err((None, InboxError::DerefError.into())); + } + let host_header_value = HeaderValue::from_str(&url.host_str().expect("Unreachable")) + .map_err(|_| (None, InboxError::DerefError.into()))?; + headers.insert(HOST, host_header_value); if let Some(proxy) = proxy { reqwest::ClientBuilder::new().proxy(proxy) } else { @@ -320,13 +333,13 @@ pub trait FromId: Sized { .build() .map_err(|_| (None, InboxError::DerefError.into()))? .get(id) + .headers(headers.clone()) .header( - ACCEPT, - HeaderValue::from_str( - &super::ap_accept_header() - .into_iter() - .collect::>() - .join(", "), + "Signature", + request::signature( + Self::get_sender(), + &headers, + ("get", url.path(), url.query()), ) .map_err(|_| (None, InboxError::DerefError.into()))?, ) @@ -347,6 +360,8 @@ pub trait FromId: Sized { /// Tries to find a `Self` with a given ID (`id`), using `ctx` (a database) fn from_db(ctx: &C, id: &str) -> Result; + + fn get_sender() -> &'static dyn Signer; } /// Should be implemented by anything representing an ActivityPub actor. diff --git a/plume-common/src/activity_pub/request.rs b/plume-common/src/activity_pub/request.rs index 73e6d6ee..8f20de13 100644 --- a/plume-common/src/activity_pub/request.rs +++ b/plume-common/src/activity_pub/request.rs @@ -118,8 +118,8 @@ type Path<'a> = &'a str; type Query<'a> = &'a str; type RequestTarget<'a> = (Method<'a>, Path<'a>, Option>); -pub fn signature( - signer: &S, +pub fn signature( + signer: &dyn Signer, headers: &HeaderMap, request_target: RequestTarget, ) -> Result { diff --git a/plume-models/src/blogs.rs b/plume-models/src/blogs.rs index da556225..9d0839ae 100644 --- a/plume-models/src/blogs.rs +++ b/plume-models/src/blogs.rs @@ -443,6 +443,10 @@ impl FromId for Blog { }, ) } + + fn get_sender() -> &'static dyn sign::Signer { + Instance::get_local_instance_user().expect("Failed to local instance user") + } } impl AsActor<&PlumeRocket> for Blog { diff --git a/plume-models/src/comments.rs b/plume-models/src/comments.rs index d92ab6c0..0809aab5 100644 --- a/plume-models/src/comments.rs +++ b/plume-models/src/comments.rs @@ -21,6 +21,7 @@ use diesel::{self, ExpressionMethods, QueryDsl, RunQueryDsl, SaveChangesDsl}; use plume_common::{ activity_pub::{ inbox::{AsActor, AsObject, FromId}, + sign::Signer, Id, IntoId, PUBLIC_VISIBILITY, }, utils, @@ -328,6 +329,10 @@ impl FromId for Comment { comm.notify(conn)?; Ok(comm) } + + fn get_sender() -> &'static dyn Signer { + Instance::get_local_instance_user().expect("Failed to local instance user") + } } impl AsObject for Comment { diff --git a/plume-models/src/follows.rs b/plume-models/src/follows.rs index c1669e36..9450b59b 100644 --- a/plume-models/src/follows.rs +++ b/plume-models/src/follows.rs @@ -1,6 +1,6 @@ use crate::{ - ap_url, db_conn::DbConn, notifications::*, schema::follows, users::User, Connection, Error, - Result, CONFIG, + ap_url, db_conn::DbConn, instance::Instance, notifications::*, schema::follows, users::User, + Connection, Error, Result, CONFIG, }; use activitypub::activity::{Accept, Follow as FollowAct, Undo}; use diesel::{self, ExpressionMethods, QueryDsl, RunQueryDsl, SaveChangesDsl}; @@ -183,6 +183,10 @@ impl FromId for Follow { .map_err(|(_, e)| e)?; Follow::accept_follow(conn, &actor, &target, follow, actor.id, target.id) } + + fn get_sender() -> &'static dyn Signer { + Instance::get_local_instance_user().expect("Failed to local instance user") + } } impl AsObject for Follow { diff --git a/plume-models/src/likes.rs b/plume-models/src/likes.rs index b14e7c38..fa092af0 100644 --- a/plume-models/src/likes.rs +++ b/plume-models/src/likes.rs @@ -1,12 +1,13 @@ use crate::{ - db_conn::DbConn, notifications::*, posts::Post, schema::likes, timeline::*, users::User, - Connection, Error, Result, CONFIG, + db_conn::DbConn, instance::Instance, notifications::*, posts::Post, schema::likes, timeline::*, + users::User, Connection, Error, Result, CONFIG, }; use activitypub::activity; use chrono::NaiveDateTime; use diesel::{self, ExpressionMethods, QueryDsl, RunQueryDsl}; use plume_common::activity_pub::{ inbox::{AsActor, AsObject, FromId}, + sign::Signer, Id, IntoId, PUBLIC_VISIBILITY, }; @@ -137,6 +138,10 @@ impl FromId for Like { res.notify(conn)?; Ok(res) } + + fn get_sender() -> &'static dyn Signer { + Instance::get_local_instance_user().expect("Failed to local instance user") + } } impl AsObject for Like { diff --git a/plume-models/src/posts.rs b/plume-models/src/posts.rs index c53f20c1..9a385db9 100644 --- a/plume-models/src/posts.rs +++ b/plume-models/src/posts.rs @@ -15,6 +15,7 @@ use once_cell::sync::Lazy; use plume_common::{ activity_pub::{ inbox::{AsActor, AsObject, FromId}, + sign::Signer, Hashtag, Id, IntoId, Licensed, Source, PUBLIC_VISIBILITY, }, utils::{iri_percent_encode_seg, md_to_html}, @@ -759,6 +760,10 @@ impl FromId for Post { Ok(post) } + + fn get_sender() -> &'static dyn Signer { + Instance::get_local_instance_user().expect("Failed to local instance user") + } } impl AsObject for Post { @@ -830,6 +835,10 @@ impl FromId for PostUpdate { tags: updated.object.object_props.tag, }) } + + fn get_sender() -> &'static dyn Signer { + Instance::get_local_instance_user().expect("Failed to local instance user") + } } impl AsObject for PostUpdate { diff --git a/plume-models/src/reshares.rs b/plume-models/src/reshares.rs index eec86a1e..58400196 100644 --- a/plume-models/src/reshares.rs +++ b/plume-models/src/reshares.rs @@ -1,12 +1,13 @@ use crate::{ - db_conn::DbConn, notifications::*, posts::Post, schema::reshares, timeline::*, users::User, - Connection, Error, Result, CONFIG, + db_conn::DbConn, instance::Instance, notifications::*, posts::Post, schema::reshares, + timeline::*, users::User, Connection, Error, Result, CONFIG, }; use activitypub::activity::{Announce, Undo}; use chrono::NaiveDateTime; use diesel::{self, ExpressionMethods, QueryDsl, RunQueryDsl}; use plume_common::activity_pub::{ inbox::{AsActor, AsObject, FromId}, + sign::Signer, Id, IntoId, PUBLIC_VISIBILITY, }; @@ -162,6 +163,10 @@ impl FromId for Reshare { res.notify(conn)?; Ok(res) } + + fn get_sender() -> &'static dyn Signer { + Instance::get_local_instance_user().expect("Failed to local instance user") + } } impl AsObject for Reshare { diff --git a/plume-models/src/users.rs b/plume-models/src/users.rs index 04e27d5f..b8b6b476 100644 --- a/plume-models/src/users.rs +++ b/plume-models/src/users.rs @@ -1039,6 +1039,10 @@ impl FromId for User { Ok(user) } + + fn get_sender() -> &'static dyn Signer { + Instance::get_local_instance_user().expect("Failed to local instance user") + } } impl AsActor<&DbConn> for User {