forked from alemi/upub
feat: proxy should work for anything, more options
This commit is contained in:
parent
8284130890
commit
43aea48816
5 changed files with 38 additions and 34 deletions
3
Cargo.lock
generated
3
Cargo.lock
generated
|
@ -4782,6 +4782,7 @@ dependencies = [
|
||||||
"tower-http",
|
"tower-http",
|
||||||
"tracing",
|
"tracing",
|
||||||
"upub",
|
"upub",
|
||||||
|
"uriproxy",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
@ -4834,7 +4835,7 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "uriproxy"
|
name = "uriproxy"
|
||||||
version = "0.1.0"
|
version = "0.1.1"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"base64 0.22.1",
|
"base64 0.22.1",
|
||||||
]
|
]
|
||||||
|
|
|
@ -26,6 +26,7 @@ axum = "0.7"
|
||||||
tower-http = { version = "0.5", features = ["cors", "trace"] }
|
tower-http = { version = "0.5", features = ["cors", "trace"] }
|
||||||
httpsign = { path = "../../utils/httpsign/", features = ["axum"] }
|
httpsign = { path = "../../utils/httpsign/", features = ["axum"] }
|
||||||
apb = { path = "../../apb", features = ["unstructured", "orm", "activitypub-fe", "activitypub-counters", "litepub", "ostatus", "toot", "jsonld"] }
|
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"] }
|
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 = "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" }
|
nodeinfo = { git = "https://codeberg.org/thefederationinfo/nodeinfo-rs", rev = "e865094804" }
|
||||||
|
|
|
@ -1,9 +1,9 @@
|
||||||
use apb::{LD, ActorMut, BaseMut, ObjectMut, PublicKeyMut};
|
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 reqwest::Method;
|
||||||
use upub::{traits::Fetcher, Context};
|
use upub::{traits::Fetcher, Context};
|
||||||
|
|
||||||
use crate::{builders::JsonLD, AuthIdentity};
|
use crate::{builders::JsonLD, AuthIdentity, Identity};
|
||||||
|
|
||||||
|
|
||||||
pub async fn view(
|
pub async fn view(
|
||||||
|
@ -39,55 +39,56 @@ pub async fn view(
|
||||||
).into_response())
|
).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)]
|
#[derive(Debug, serde::Deserialize)]
|
||||||
pub struct FetchPath {
|
pub struct ProxyQuery {
|
||||||
id: String,
|
uri: String,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn proxy_get(
|
pub async fn proxy_get(
|
||||||
State(ctx): State<Context>,
|
State(ctx): State<Context>,
|
||||||
Query(query): Query<FetchPath>,
|
|
||||||
AuthIdentity(auth): AuthIdentity,
|
AuthIdentity(auth): AuthIdentity,
|
||||||
) -> crate::ApiResult<Json<serde_json::Value>> {
|
Query(query): Query<ProxyQuery>,
|
||||||
// only local users can request fetches
|
) -> crate::ApiResult<impl IntoResponse> {
|
||||||
if !ctx.cfg().security.allow_public_debugger && !auth.is_local() {
|
proxy(ctx, query.uri, auth).await
|
||||||
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?
|
|
||||||
))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn proxy_form(
|
pub async fn proxy_form(
|
||||||
State(ctx): State<Context>,
|
State(ctx): State<Context>,
|
||||||
AuthIdentity(auth): AuthIdentity,
|
AuthIdentity(auth): AuthIdentity,
|
||||||
Form(query): Form<FetchPath>,
|
Form(query): Form<String>,
|
||||||
) -> crate::ApiResult<Json<serde_json::Value>> {
|
) -> 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
|
// 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());
|
return Err(crate::ApiError::unauthorized());
|
||||||
}
|
}
|
||||||
Ok(Json(
|
|
||||||
Context::request(
|
let resp = Context::request(
|
||||||
Method::GET,
|
Method::GET,
|
||||||
&query.id,
|
&query,
|
||||||
None,
|
None,
|
||||||
ctx.base(),
|
ctx.base(),
|
||||||
ctx.pkey(),
|
ctx.pkey(),
|
||||||
&format!("{}+proxy", ctx.domain()),
|
&format!("{}+proxy", ctx.domain()),
|
||||||
)
|
)
|
||||||
.await?
|
.await?
|
||||||
.json::<serde_json::Value>()
|
.error_for_status()?;
|
||||||
.await?
|
|
||||||
|
Ok((
|
||||||
|
resp.headers().clone(),
|
||||||
|
resp.bytes().await?.to_vec(),
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
|
|
|
@ -21,8 +21,9 @@ impl ActivityPubRouter for Router<upub::Context> {
|
||||||
// core server inbox/outbox, maybe for feeds? TODO do we need these?
|
// core server inbox/outbox, maybe for feeds? TODO do we need these?
|
||||||
.route("/", get(ap::application::view))
|
.route("/", get(ap::application::view))
|
||||||
// fetch route, to debug and retreive remote objects
|
// fetch route, to debug and retreive remote objects
|
||||||
.route("/proxy", get(ap::application::proxy_get))
|
|
||||||
.route("/proxy", post(ap::application::proxy_form))
|
.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
|
// TODO shared inboxes and instance stream will come later, just use users *boxes for now
|
||||||
.route("/inbox", post(ap::inbox::post))
|
.route("/inbox", post(ap::inbox::post))
|
||||||
.route("/inbox", get(ap::inbox::get))
|
.route("/inbox", get(ap::inbox::get))
|
||||||
|
|
|
@ -31,7 +31,7 @@ pub fn DebugPage() -> impl IntoView {
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
} else {
|
} 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
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
Loading…
Reference in a new issue