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",
|
||||
"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",
|
||||
]
|
||||
|
|
|
@ -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" }
|
||||
|
|
|
@ -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(),
|
||||
))
|
||||
}
|
||||
|
|
|
@ -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))
|
||||
|
|
|
@ -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
|
||||
}
|
||||
}
|
||||
);
|
||||
|
|
Loading…
Reference in a new issue