forked from alemi/upub
feat: added hmac validated proxy route
This commit is contained in:
parent
ff2570e961
commit
89f5b200a8
5 changed files with 39 additions and 2 deletions
3
Cargo.lock
generated
3
Cargo.lock
generated
|
@ -4864,7 +4864,9 @@ version = "0.2.0"
|
|||
dependencies = [
|
||||
"apb",
|
||||
"axum",
|
||||
"base64 0.22.1",
|
||||
"chrono",
|
||||
"hmac",
|
||||
"httpsign",
|
||||
"jrd",
|
||||
"mastodon-async-entities",
|
||||
|
@ -4874,6 +4876,7 @@ dependencies = [
|
|||
"sea-orm",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"sha2",
|
||||
"sha256",
|
||||
"thiserror",
|
||||
"time",
|
||||
|
|
|
@ -68,6 +68,9 @@ pub struct SecurityConfig {
|
|||
#[serde(default)]
|
||||
pub allow_public_debugger: bool,
|
||||
|
||||
#[serde_inline_default("changeme".to_string())]
|
||||
pub proxy_secret: String,
|
||||
|
||||
#[serde_inline_default(true)]
|
||||
pub show_reply_ids: bool,
|
||||
|
||||
|
|
|
@ -13,7 +13,10 @@ readme = "README.md"
|
|||
[dependencies]
|
||||
thiserror = "1"
|
||||
rand = "0.8"
|
||||
sha256 = "1.5"
|
||||
sha2 = "0.10"
|
||||
sha256 = "1.5" # TODO ughhh
|
||||
hmac = "0.12"
|
||||
base64 = "0.22"
|
||||
chrono = { version = "0.4", features = ["serde"] }
|
||||
serde = { version = "1", features = ["derive"] }
|
||||
serde_json = "1"
|
||||
|
|
|
@ -1,9 +1,11 @@
|
|||
use apb::{LD, ActorMut, BaseMut, ObjectMut, PublicKeyMut};
|
||||
use axum::{extract::{Path, Query, State}, http::HeaderMap, response::{IntoResponse, Redirect, Response}, Form};
|
||||
use hmac::{Hmac, Mac};
|
||||
use reqwest::Method;
|
||||
use base64::{engine::general_purpose::URL_SAFE, Engine as _};
|
||||
use upub::{traits::Fetcher, Context};
|
||||
|
||||
use crate::{builders::JsonLD, AuthIdentity, Identity};
|
||||
use crate::{builders::JsonLD, ApiError, AuthIdentity, Identity};
|
||||
|
||||
|
||||
pub async fn view(
|
||||
|
@ -74,6 +76,31 @@ pub async fn proxy_form(
|
|||
proxy(ctx, query, auth).await
|
||||
}
|
||||
|
||||
pub async fn proxy_hmac(
|
||||
State(ctx): State<Context>,
|
||||
AuthIdentity(auth): AuthIdentity,
|
||||
Path(hmac): Path<String>,
|
||||
Path(uri): Path<String>,
|
||||
) -> crate::ApiResult<impl IntoResponse> {
|
||||
let bytes = URL_SAFE.decode(hmac).map_err(|_| ApiError::bad_request())?;
|
||||
let uri =
|
||||
std::str::from_utf8(
|
||||
&URL_SAFE.decode(uri).map_err(|_| ApiError::bad_request())?
|
||||
)
|
||||
.map_err(|_| ApiError::bad_request())?
|
||||
.to_string();
|
||||
|
||||
type HmacSha256 = Hmac<sha2::Sha256>;
|
||||
let mut mac = HmacSha256::new_from_slice(ctx.cfg().security.proxy_secret.as_bytes())
|
||||
.map_err(|_| ApiError::internal_server_error())?;
|
||||
|
||||
mac.update(uri.as_bytes());
|
||||
mac.verify_slice(&bytes)
|
||||
.map_err(|_| ApiError::forbidden())?;
|
||||
|
||||
proxy(ctx, uri, auth).await
|
||||
}
|
||||
|
||||
async fn proxy(ctx: Context, query: String, auth: Identity) -> crate::ApiResult<impl IntoResponse> {
|
||||
// only local users can request fetches
|
||||
if !ctx.cfg().security.allow_public_debugger && !auth.is_local() {
|
||||
|
|
|
@ -25,6 +25,7 @@ impl ActivityPubRouter for Router<upub::Context> {
|
|||
.route("/proxy", post(ap::application::proxy_form))
|
||||
.route("/proxy", get(ap::application::proxy_get))
|
||||
.route("/proxy/:uri", get(ap::application::proxy_path))
|
||||
.route("/proxy/:hmac/:uri", get(ap::application::proxy_hmac))
|
||||
.route("/inbox", post(ap::inbox::post))
|
||||
.route("/inbox", get(ap::inbox::get))
|
||||
.route("/inbox/page", get(ap::inbox::page))
|
||||
|
|
Loading…
Reference in a new issue