mirror of
https://tangled.org/tranquil.farm/tranquil-pds
synced 2026-09-21 09:44:14 +00:00
Remove a bunch of unnecessary tests & endpoints
This commit is contained in:
+14
-57
@@ -1,75 +1,21 @@
|
||||
use crate::api::proxy_client::proxy_client;
|
||||
use crate::state::AppState;
|
||||
use axum::{
|
||||
Json,
|
||||
extract::{Query, RawQuery, State},
|
||||
extract::{Query, State},
|
||||
http::StatusCode,
|
||||
response::{IntoResponse, Response},
|
||||
};
|
||||
use serde::Deserialize;
|
||||
use serde_json::json;
|
||||
use tracing::{error, info};
|
||||
|
||||
#[derive(Deserialize)]
|
||||
pub struct DescribeRepoInput {
|
||||
pub repo: String,
|
||||
}
|
||||
|
||||
async fn proxy_describe_repo_to_appview(state: &AppState, raw_query: Option<&str>) -> Response {
|
||||
let resolved = match state.appview_registry.get_appview_for_method("com.atproto.repo.describeRepo").await {
|
||||
Some(r) => r,
|
||||
None => {
|
||||
return (
|
||||
StatusCode::NOT_FOUND,
|
||||
Json(json!({"error": "NotFound", "message": "Repo not found"})),
|
||||
)
|
||||
.into_response();
|
||||
}
|
||||
};
|
||||
let target_url = match raw_query {
|
||||
Some(q) => format!("{}/xrpc/com.atproto.repo.describeRepo?{}", resolved.url, q),
|
||||
None => format!("{}/xrpc/com.atproto.repo.describeRepo", resolved.url),
|
||||
};
|
||||
info!("Proxying describeRepo to AppView: {}", target_url);
|
||||
let client = proxy_client();
|
||||
match client.get(&target_url).send().await {
|
||||
Ok(resp) => {
|
||||
let status =
|
||||
StatusCode::from_u16(resp.status().as_u16()).unwrap_or(StatusCode::BAD_GATEWAY);
|
||||
let content_type = resp
|
||||
.headers()
|
||||
.get("content-type")
|
||||
.and_then(|v| v.to_str().ok())
|
||||
.map(|s| s.to_string());
|
||||
match resp.bytes().await {
|
||||
Ok(body) => {
|
||||
let mut builder = Response::builder().status(status);
|
||||
if let Some(ct) = content_type {
|
||||
builder = builder.header("content-type", ct);
|
||||
}
|
||||
builder
|
||||
.body(axum::body::Body::from(body))
|
||||
.unwrap_or_else(|_| {
|
||||
(StatusCode::INTERNAL_SERVER_ERROR, "Internal error").into_response()
|
||||
})
|
||||
}
|
||||
Err(e) => {
|
||||
error!("Error reading AppView response: {:?}", e);
|
||||
(StatusCode::BAD_GATEWAY, Json(json!({"error": "UpstreamError"}))).into_response()
|
||||
}
|
||||
}
|
||||
}
|
||||
Err(e) => {
|
||||
error!("Error proxying to AppView: {:?}", e);
|
||||
(StatusCode::BAD_GATEWAY, Json(json!({"error": "UpstreamError"}))).into_response()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub async fn describe_repo(
|
||||
State(state): State<AppState>,
|
||||
Query(input): Query<DescribeRepoInput>,
|
||||
RawQuery(raw_query): RawQuery,
|
||||
) -> Response {
|
||||
let user_row = if input.repo.starts_with("did:") {
|
||||
sqlx::query!(
|
||||
@@ -90,8 +36,19 @@ pub async fn describe_repo(
|
||||
};
|
||||
let (user_id, handle, did) = match user_row {
|
||||
Ok(Some((id, handle, did))) => (id, handle, did),
|
||||
_ => {
|
||||
return proxy_describe_repo_to_appview(&state, raw_query.as_deref()).await;
|
||||
Ok(None) => {
|
||||
return (
|
||||
StatusCode::NOT_FOUND,
|
||||
Json(json!({"error": "RepoNotFound", "message": "Repo not found"})),
|
||||
)
|
||||
.into_response();
|
||||
}
|
||||
Err(_) => {
|
||||
return (
|
||||
StatusCode::INTERNAL_SERVER_ERROR,
|
||||
Json(json!({"error": "InternalError"})),
|
||||
)
|
||||
.into_response();
|
||||
}
|
||||
};
|
||||
let collections_query = sqlx::query!(
|
||||
|
||||
@@ -31,10 +31,11 @@ pub struct DeleteRecordInput {
|
||||
pub async fn delete_record(
|
||||
State(state): State<AppState>,
|
||||
headers: HeaderMap,
|
||||
axum::extract::OriginalUri(uri): axum::extract::OriginalUri,
|
||||
Json(input): Json<DeleteRecordInput>,
|
||||
) -> Response {
|
||||
let (did, user_id, current_root_cid) =
|
||||
match prepare_repo_write(&state, &headers, &input.repo).await {
|
||||
match prepare_repo_write(&state, &headers, &input.repo, "POST", &uri.to_string()).await {
|
||||
Ok(res) => res,
|
||||
Err(err_res) => return err_res,
|
||||
};
|
||||
|
||||
+28
-119
@@ -1,8 +1,7 @@
|
||||
use crate::api::proxy_client::proxy_client;
|
||||
use crate::state::AppState;
|
||||
use axum::{
|
||||
Json,
|
||||
extract::{Query, RawQuery, State},
|
||||
extract::{Query, State},
|
||||
http::StatusCode,
|
||||
response::{IntoResponse, Response},
|
||||
};
|
||||
@@ -12,7 +11,7 @@ use serde::{Deserialize, Serialize};
|
||||
use serde_json::json;
|
||||
use std::collections::HashMap;
|
||||
use std::str::FromStr;
|
||||
use tracing::{error, info};
|
||||
use tracing::error;
|
||||
|
||||
#[derive(Deserialize)]
|
||||
pub struct GetRecordInput {
|
||||
@@ -22,69 +21,9 @@ pub struct GetRecordInput {
|
||||
pub cid: Option<String>,
|
||||
}
|
||||
|
||||
async fn proxy_get_record_to_appview(state: &AppState, raw_query: Option<&str>) -> Response {
|
||||
let resolved = match state.appview_registry.get_appview_for_method("com.atproto.repo.getRecord").await {
|
||||
Some(r) => r,
|
||||
None => {
|
||||
return (
|
||||
StatusCode::NOT_FOUND,
|
||||
Json(json!({"error": "NotFound", "message": "Repo not found"})),
|
||||
)
|
||||
.into_response();
|
||||
}
|
||||
};
|
||||
let target_url = match raw_query {
|
||||
Some(q) => format!("{}/xrpc/com.atproto.repo.getRecord?{}", resolved.url, q),
|
||||
None => format!("{}/xrpc/com.atproto.repo.getRecord", resolved.url),
|
||||
};
|
||||
info!("Proxying getRecord to AppView: {}", target_url);
|
||||
let client = proxy_client();
|
||||
match client.get(&target_url).send().await {
|
||||
Ok(resp) => {
|
||||
let status =
|
||||
StatusCode::from_u16(resp.status().as_u16()).unwrap_or(StatusCode::BAD_GATEWAY);
|
||||
let content_type = resp
|
||||
.headers()
|
||||
.get("content-type")
|
||||
.and_then(|v| v.to_str().ok())
|
||||
.map(|s| s.to_string());
|
||||
match resp.bytes().await {
|
||||
Ok(body) => {
|
||||
let mut builder = Response::builder().status(status);
|
||||
if let Some(ct) = content_type {
|
||||
builder = builder.header("content-type", ct);
|
||||
}
|
||||
builder
|
||||
.body(axum::body::Body::from(body))
|
||||
.unwrap_or_else(|_| {
|
||||
(StatusCode::INTERNAL_SERVER_ERROR, "Internal error").into_response()
|
||||
})
|
||||
}
|
||||
Err(e) => {
|
||||
error!("Error reading AppView response: {:?}", e);
|
||||
(
|
||||
StatusCode::BAD_GATEWAY,
|
||||
Json(json!({"error": "UpstreamError"})),
|
||||
)
|
||||
.into_response()
|
||||
}
|
||||
}
|
||||
}
|
||||
Err(e) => {
|
||||
error!("Error proxying to AppView: {:?}", e);
|
||||
(
|
||||
StatusCode::BAD_GATEWAY,
|
||||
Json(json!({"error": "UpstreamError"})),
|
||||
)
|
||||
.into_response()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub async fn get_record(
|
||||
State(state): State<AppState>,
|
||||
Query(input): Query<GetRecordInput>,
|
||||
RawQuery(raw_query): RawQuery,
|
||||
) -> Response {
|
||||
let hostname = std::env::var("PDS_HOSTNAME").unwrap_or_else(|_| "localhost".to_string());
|
||||
let user_id_opt = if input.repo.starts_with("did:") {
|
||||
@@ -106,8 +45,19 @@ pub async fn get_record(
|
||||
};
|
||||
let user_id: uuid::Uuid = match user_id_opt {
|
||||
Ok(Some(id)) => id,
|
||||
_ => {
|
||||
return proxy_get_record_to_appview(&state, raw_query.as_deref()).await;
|
||||
Ok(None) => {
|
||||
return (
|
||||
StatusCode::NOT_FOUND,
|
||||
Json(json!({"error": "RepoNotFound", "message": "Repo not found"})),
|
||||
)
|
||||
.into_response();
|
||||
}
|
||||
Err(_) => {
|
||||
return (
|
||||
StatusCode::INTERNAL_SERVER_ERROR,
|
||||
Json(json!({"error": "InternalError"})),
|
||||
)
|
||||
.into_response();
|
||||
}
|
||||
};
|
||||
let record_row = sqlx::query!(
|
||||
@@ -192,61 +142,9 @@ pub struct ListRecordsOutput {
|
||||
pub records: Vec<serde_json::Value>,
|
||||
}
|
||||
|
||||
async fn proxy_list_records_to_appview(state: &AppState, raw_query: Option<&str>) -> Response {
|
||||
let resolved = match state.appview_registry.get_appview_for_method("com.atproto.repo.listRecords").await {
|
||||
Some(r) => r,
|
||||
None => {
|
||||
return (
|
||||
StatusCode::NOT_FOUND,
|
||||
Json(json!({"error": "NotFound", "message": "Repo not found"})),
|
||||
)
|
||||
.into_response();
|
||||
}
|
||||
};
|
||||
let target_url = match raw_query {
|
||||
Some(q) => format!("{}/xrpc/com.atproto.repo.listRecords?{}", resolved.url, q),
|
||||
None => format!("{}/xrpc/com.atproto.repo.listRecords", resolved.url),
|
||||
};
|
||||
info!("Proxying listRecords to AppView: {}", target_url);
|
||||
let client = proxy_client();
|
||||
match client.get(&target_url).send().await {
|
||||
Ok(resp) => {
|
||||
let status =
|
||||
StatusCode::from_u16(resp.status().as_u16()).unwrap_or(StatusCode::BAD_GATEWAY);
|
||||
let content_type = resp
|
||||
.headers()
|
||||
.get("content-type")
|
||||
.and_then(|v| v.to_str().ok())
|
||||
.map(|s| s.to_string());
|
||||
match resp.bytes().await {
|
||||
Ok(body) => {
|
||||
let mut builder = Response::builder().status(status);
|
||||
if let Some(ct) = content_type {
|
||||
builder = builder.header("content-type", ct);
|
||||
}
|
||||
builder
|
||||
.body(axum::body::Body::from(body))
|
||||
.unwrap_or_else(|_| {
|
||||
(StatusCode::INTERNAL_SERVER_ERROR, "Internal error").into_response()
|
||||
})
|
||||
}
|
||||
Err(e) => {
|
||||
error!("Error reading AppView response: {:?}", e);
|
||||
(StatusCode::BAD_GATEWAY, Json(json!({"error": "UpstreamError"}))).into_response()
|
||||
}
|
||||
}
|
||||
}
|
||||
Err(e) => {
|
||||
error!("Error proxying to AppView: {:?}", e);
|
||||
(StatusCode::BAD_GATEWAY, Json(json!({"error": "UpstreamError"}))).into_response()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub async fn list_records(
|
||||
State(state): State<AppState>,
|
||||
Query(input): Query<ListRecordsInput>,
|
||||
RawQuery(raw_query): RawQuery,
|
||||
) -> Response {
|
||||
let hostname = std::env::var("PDS_HOSTNAME").unwrap_or_else(|_| "localhost".to_string());
|
||||
let user_id_opt = if input.repo.starts_with("did:") {
|
||||
@@ -268,8 +166,19 @@ pub async fn list_records(
|
||||
};
|
||||
let user_id: uuid::Uuid = match user_id_opt {
|
||||
Ok(Some(id)) => id,
|
||||
_ => {
|
||||
return proxy_list_records_to_appview(&state, raw_query.as_deref()).await;
|
||||
Ok(None) => {
|
||||
return (
|
||||
StatusCode::NOT_FOUND,
|
||||
Json(json!({"error": "RepoNotFound", "message": "Repo not found"})),
|
||||
)
|
||||
.into_response();
|
||||
}
|
||||
Err(_) => {
|
||||
return (
|
||||
StatusCode::INTERNAL_SERVER_ERROR,
|
||||
Json(json!({"error": "InternalError"})),
|
||||
)
|
||||
.into_response();
|
||||
}
|
||||
};
|
||||
let limit = input.limit.unwrap_or(50).clamp(1, 100);
|
||||
|
||||
@@ -56,8 +56,10 @@ pub async fn prepare_repo_write(
|
||||
state: &AppState,
|
||||
headers: &HeaderMap,
|
||||
repo_did: &str,
|
||||
http_method: &str,
|
||||
http_uri: &str,
|
||||
) -> Result<(String, Uuid, Cid), Response> {
|
||||
let token = crate::auth::extract_bearer_token_from_header(
|
||||
let extracted = crate::auth::extract_auth_token_from_header(
|
||||
headers.get("Authorization").and_then(|h| h.to_str().ok()),
|
||||
)
|
||||
.ok_or_else(|| {
|
||||
@@ -67,15 +69,26 @@ pub async fn prepare_repo_write(
|
||||
)
|
||||
.into_response()
|
||||
})?;
|
||||
let auth_user = crate::auth::validate_bearer_token(&state.db, &token)
|
||||
.await
|
||||
.map_err(|_| {
|
||||
(
|
||||
StatusCode::UNAUTHORIZED,
|
||||
Json(json!({"error": "AuthenticationFailed"})),
|
||||
)
|
||||
.into_response()
|
||||
})?;
|
||||
let dpop_proof = headers
|
||||
.get("DPoP")
|
||||
.and_then(|h| h.to_str().ok());
|
||||
let auth_user = crate::auth::validate_token_with_dpop(
|
||||
&state.db,
|
||||
&extracted.token,
|
||||
extracted.is_dpop,
|
||||
dpop_proof,
|
||||
http_method,
|
||||
http_uri,
|
||||
false,
|
||||
)
|
||||
.await
|
||||
.map_err(|e| {
|
||||
(
|
||||
StatusCode::UNAUTHORIZED,
|
||||
Json(json!({"error": e.to_string()})),
|
||||
)
|
||||
.into_response()
|
||||
})?;
|
||||
if repo_did != auth_user.did {
|
||||
return Err((
|
||||
StatusCode::FORBIDDEN,
|
||||
@@ -172,10 +185,11 @@ pub struct CreateRecordOutput {
|
||||
pub async fn create_record(
|
||||
State(state): State<AppState>,
|
||||
headers: HeaderMap,
|
||||
axum::extract::OriginalUri(uri): axum::extract::OriginalUri,
|
||||
Json(input): Json<CreateRecordInput>,
|
||||
) -> Response {
|
||||
let (did, user_id, current_root_cid) =
|
||||
match prepare_repo_write(&state, &headers, &input.repo).await {
|
||||
match prepare_repo_write(&state, &headers, &input.repo, "POST", &uri.to_string()).await {
|
||||
Ok(res) => res,
|
||||
Err(err_res) => return err_res,
|
||||
};
|
||||
@@ -339,10 +353,11 @@ pub struct PutRecordOutput {
|
||||
pub async fn put_record(
|
||||
State(state): State<AppState>,
|
||||
headers: HeaderMap,
|
||||
axum::extract::OriginalUri(uri): axum::extract::OriginalUri,
|
||||
Json(input): Json<PutRecordInput>,
|
||||
) -> Response {
|
||||
let (did, user_id, current_root_cid) =
|
||||
match prepare_repo_write(&state, &headers, &input.repo).await {
|
||||
match prepare_repo_write(&state, &headers, &input.repo, "POST", &uri.to_string()).await {
|
||||
Ok(res) => res,
|
||||
Err(err_res) => return err_res,
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user