From 760037cfc8d61f22de4fc0793b4eb26384efe8fc Mon Sep 17 00:00:00 2001 From: Chris van der Loo Date: Sat, 5 Sep 2026 14:01:38 -0400 Subject: [PATCH] refactor: bound native repository reads and remove unused dependencies --- packages/server/Cargo.toml | 5 ++--- packages/server/src/files/repository.rs | 21 +++++++++++++-------- packages/server/tests/support/mod.rs | 2 -- 3 files changed, 15 insertions(+), 13 deletions(-) diff --git a/packages/server/Cargo.toml b/packages/server/Cargo.toml index 28b8dfa..e90bdea 100644 --- a/packages/server/Cargo.toml +++ b/packages/server/Cargo.toml @@ -7,7 +7,6 @@ default-run = "crate-server" [dependencies] anyhow = "1" -async-trait = "0.1" atrium-api = { version = "0.25.8", default-features = false } atrium-common = "0.1.4" atrium-identity = "0.1.9" @@ -24,14 +23,13 @@ mime = "0.3" percent-encoding = "2" jose-jwk = { version = "0.1.2", features = ["p256"], default-features = false } p256 = { version = "0.13", features = ["ecdsa"] } -poem = { version = "3.1", features = ["test", "cookie"] } +poem = { version = "3.1", features = ["cookie"] } poem-openapi = { version = "5.1", features = ["chrono", "cookie", "swagger-ui"] } rand = "0.9" reqwest = { version = "0.12", default-features = false, features = ["rustls-tls", "stream"] } rusqlite = { version = "0.37", features = ["bundled"] } serde = { version = "1", features = ["derive"] } serde_json = "1" -serde_urlencoded = "0.7" sha2 = "0.10" thiserror = "2" tokio = { version = "1", features = ["full"] } @@ -40,4 +38,5 @@ tracing-subscriber = { version = "0.3", features = ["env-filter"] } url = "2" [dev-dependencies] +poem = { version = "3.1", features = ["test"] } tempfile = "3" diff --git a/packages/server/src/files/repository.rs b/packages/server/src/files/repository.rs index e2c84b8..1141cc8 100644 --- a/packages/server/src/files/repository.rs +++ b/packages/server/src/files/repository.rs @@ -3,10 +3,10 @@ use crate::{ error::{ApiError, Result}, pds::rpc, }; -use async_trait::async_trait; use crate_protocol::Space; use serde::{Deserialize, Serialize}; use serde_json::{Value, json}; +use std::future::Future; #[derive(Clone, Debug)] pub struct Record { @@ -34,11 +34,10 @@ pub enum Write { Delete { collection: String, rkey: String }, } -#[async_trait] pub trait Repository: Sync { - async fn get(&self, collection: &str, id: &str) -> Result; - async fn list(&self, collection: &str) -> Result>; - async fn apply(&self, writes: Vec) -> Result<()>; + fn get(&self, collection: &str, id: &str) -> impl Future> + Send; + fn list(&self, collection: &str) -> impl Future>> + Send; + fn apply(&self, writes: Vec) -> impl Future> + Send; } pub struct PdsRepository<'a> { @@ -64,7 +63,6 @@ struct Listing { cursor: Option, } -#[async_trait] impl Repository for PdsRepository<'_> { async fn get(&self, collection: &str, id: &str) -> Result { atrium_api::types::string::RecordKey::new(id.into()).map_err(ApiError::bad)?; @@ -84,6 +82,7 @@ impl Repository for PdsRepository<'_> { async fn list(&self, collection: &str) -> Result> { let mut records = Vec::new(); let mut cursor = None::; + let mut seen = std::collections::HashSet::new(); loop { let mut params = json!({"space":self.space.uri,"repo":self.did,"collection":collection,"limit":100}); @@ -94,7 +93,10 @@ impl Repository for PdsRepository<'_> { rpc::query::(self.session, "com.atproto.space.listRecords", params).await; let page = match output { Ok(page) => page, - Err(error) if error.code == "RepoNotFound" || error.code == "SpaceNotFound" => { + Err(error) + if cursor.is_none() + && (error.code == "RepoNotFound" || error.code == "SpaceNotFound") => + { return Ok(records); } Err(error) => return Err(error.into()), @@ -104,10 +106,13 @@ impl Repository for PdsRepository<'_> { revision: record.cid, value: record.value, })); + if records.len() > 10_000 { + return Err(ApiError::too_large()); + } if page.cursor.is_none() { return Ok(records); } - if page.cursor == cursor { + if !seen.insert(page.cursor.clone()) { return Err(ApiError::upstream("The PDS repeated a pagination cursor.")); } cursor = page.cursor; diff --git a/packages/server/tests/support/mod.rs b/packages/server/tests/support/mod.rs index 50da9ed..5bd4e55 100644 --- a/packages/server/tests/support/mod.rs +++ b/packages/server/tests/support/mod.rs @@ -1,4 +1,3 @@ -use async_trait::async_trait; use crate_protocol::{BlobRef, FileRecord}; use crate_server::{ error::{ApiError, Result}, @@ -33,7 +32,6 @@ pub fn file(name: &str, parent: Option<&str>, directory: bool) -> FileRecord { } } -#[async_trait] impl Repository for MemoryRepository { async fn get(&self, collection: &str, id: &str) -> Result { self.0 -- 2.51.2