1
0
Fork 0
forked from alemi/upub

feat: proxy should work for anything, more options

This commit is contained in:
əlemi 2024-06-07 06:20:25 +02:00
parent 8284130890
commit 43aea48816
Signed by: alemi
GPG key ID: A4895B84D311642C
5 changed files with 38 additions and 34 deletions

3
Cargo.lock generated
View file

@ -4782,6 +4782,7 @@ dependencies = [
"tower-http",
"tracing",
"upub",
"uriproxy",
]
[[package]]
@ -4834,7 +4835,7 @@ dependencies = [
[[package]]
name = "uriproxy"
version = "0.1.0"
version = "0.1.1"
dependencies = [
"base64 0.22.1",
]

View file

@ -26,6 +26,7 @@ axum = "0.7"
tower-http = { version = "0.5", features = ["cors", "trace"] }
httpsign = { path = "../../utils/httpsign/", features = ["axum"] }
apb = { path = "../../apb", features = ["unstructured", "orm", "activitypub-fe", "activitypub-counters", "litepub", "ostatus", "toot", "jsonld"] }
uriproxy = { path = "../../utils/uriproxy" }
sea-orm = { version = "0.12", features = ["macros", "sqlx-sqlite", "runtime-tokio-rustls"] }
# nodeinfo = "0.0.2" # the version on crates.io doesn't re-export necessary types to build the struct!!!
nodeinfo = { git = "https://codeberg.org/thefederationinfo/nodeinfo-rs", rev = "e865094804" }

View file

@ -1,9 +1,9 @@
use apb::{LD, ActorMut, BaseMut, ObjectMut, PublicKeyMut};
use axum::{extract::{Query, State}, http::HeaderMap, response::{IntoResponse, Redirect, Response}, Form, Json};
use axum::{extract::{Path, Query, State}, http::{HeaderMap, HeaderName, HeaderValue}, response::{IntoResponse, Redirect, Response}, Form, Json};
use reqwest::Method;
use upub::{traits::Fetcher, Context};
use crate::{builders::JsonLD, AuthIdentity};
use crate::{builders::JsonLD, AuthIdentity, Identity};
pub async fn view(
@ -39,55 +39,56 @@ pub async fn view(
).into_response())
}
pub async fn proxy_path(
State(ctx): State<Context>,
AuthIdentity(auth): AuthIdentity,
Path(uri): Path<String>,
) -> crate::ApiResult<impl IntoResponse> {
let query = uriproxy::expand(&uri)
.ok_or_else(crate::ApiError::bad_request)?;
proxy(ctx, query, auth).await
}
#[derive(Debug, serde::Deserialize)]
pub struct FetchPath {
id: String,
pub struct ProxyQuery {
uri: String,
}
pub async fn proxy_get(
State(ctx): State<Context>,
Query(query): Query<FetchPath>,
AuthIdentity(auth): AuthIdentity,
) -> crate::ApiResult<Json<serde_json::Value>> {
// only local users can request fetches
if !ctx.cfg().security.allow_public_debugger && !auth.is_local() {
return Err(crate::ApiError::unauthorized());
}
Ok(Json(
Context::request(
Method::GET,
&query.id,
None,
ctx.base(),
ctx.pkey(),
&format!("{}+proxy", ctx.domain()),
)
.await?
.json::<serde_json::Value>()
.await?
))
Query(query): Query<ProxyQuery>,
) -> crate::ApiResult<impl IntoResponse> {
proxy(ctx, query.uri, auth).await
}
pub async fn proxy_form(
State(ctx): State<Context>,
AuthIdentity(auth): AuthIdentity,
Form(query): Form<FetchPath>,
) -> crate::ApiResult<Json<serde_json::Value>> {
Form(query): Form<String>,
) -> crate::ApiResult<impl IntoResponse> {
proxy(ctx, query, 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() {
if !ctx.cfg().security.allow_public_debugger && !auth.is_local() {
return Err(crate::ApiError::unauthorized());
}
Ok(Json(
Context::request(
let resp = Context::request(
Method::GET,
&query.id,
&query,
None,
ctx.base(),
ctx.pkey(),
&format!("{}+proxy", ctx.domain()),
)
.await?
.json::<serde_json::Value>()
.await?
.error_for_status()?;
Ok((
resp.headers().clone(),
resp.bytes().await?.to_vec(),
))
}

View file

@ -21,8 +21,9 @@ impl ActivityPubRouter for Router<upub::Context> {
// core server inbox/outbox, maybe for feeds? TODO do we need these?
.route("/", get(ap::application::view))
// fetch route, to debug and retreive remote objects
.route("/proxy", get(ap::application::proxy_get))
.route("/proxy", post(ap::application::proxy_form))
.route("/proxy", get(ap::application::proxy_get))
.route("/proxy/:uri", get(ap::application::proxy_path))
// TODO shared inboxes and instance stream will come later, just use users *boxes for now
.route("/inbox", post(ap::inbox::post))
.route("/inbox", get(ap::inbox::get))

View file

@ -31,7 +31,7 @@ pub fn DebugPage() -> impl IntoView {
},
}
} else {
debug_fetch(&format!("{URL_BASE}/proxy?id={query}"), auth, set_error).await
debug_fetch(&format!("{URL_BASE}/proxy?uri={query}"), auth, set_error).await
}
}
);