CLI app for developers prototyping atproto functionality
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

build: add axum 0.8 dependency; common: add Clock trait

Added axum 0.8 with minimal features (http1, json, tokio) to support
the in-process fake authorization server. Created Clock trait in
src/common/oauth/clock.rs with RealClock implementation returning
Unix seconds. Includes smoke test verifying reasonable timestamp.

Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>

+113
+79
Cargo.lock
··· 160 160 "async-trait", 161 161 "atrium-api", 162 162 "atrium-xrpc-client", 163 + "axum", 163 164 "base64", 164 165 "bytes", 165 166 "ciborium", ··· 277 278 ] 278 279 279 280 [[package]] 281 + name = "axum" 282 + version = "0.8.9" 283 + source = "registry+https://github.com/rust-lang/crates.io-index" 284 + checksum = "31b698c5f9a010f6573133b09e0de5408834d0c82f8d7475a89fc1867a71cd90" 285 + dependencies = [ 286 + "axum-core", 287 + "bytes", 288 + "futures-util", 289 + "http", 290 + "http-body", 291 + "http-body-util", 292 + "hyper", 293 + "hyper-util", 294 + "itoa", 295 + "matchit", 296 + "memchr", 297 + "mime", 298 + "percent-encoding", 299 + "pin-project-lite", 300 + "serde_core", 301 + "serde_json", 302 + "serde_path_to_error", 303 + "sync_wrapper", 304 + "tokio", 305 + "tower", 306 + "tower-layer", 307 + "tower-service", 308 + ] 309 + 310 + [[package]] 311 + name = "axum-core" 312 + version = "0.5.6" 313 + source = "registry+https://github.com/rust-lang/crates.io-index" 314 + checksum = "08c78f31d7b1291f7ee735c1c6780ccde7785daae9a9206026862dab7d8792d1" 315 + dependencies = [ 316 + "bytes", 317 + "futures-core", 318 + "http", 319 + "http-body", 320 + "http-body-util", 321 + "mime", 322 + "pin-project-lite", 323 + "sync_wrapper", 324 + "tower-layer", 325 + "tower-service", 326 + ] 327 + 328 + [[package]] 280 329 name = "backtrace" 281 330 version = "0.3.76" 282 331 source = "registry+https://github.com/rust-lang/crates.io-index" ··· 1287 1336 checksum = "6dbf3de79e51f3d586ab4cb9d5c3e2c14aa28ed23d180cf89b4df0454a69cc87" 1288 1337 1289 1338 [[package]] 1339 + name = "httpdate" 1340 + version = "1.0.3" 1341 + source = "registry+https://github.com/rust-lang/crates.io-index" 1342 + checksum = "df3b46402a9d5adb4c86a0cf463f42e19994e3ee891101b1841f30a545cb49a9" 1343 + 1344 + [[package]] 1290 1345 name = "humantime" 1291 1346 version = "2.3.0" 1292 1347 source = "registry+https://github.com/rust-lang/crates.io-index" ··· 1314 1369 "http", 1315 1370 "http-body", 1316 1371 "httparse", 1372 + "httpdate", 1317 1373 "itoa", 1318 1374 "pin-project-lite", 1319 1375 "smallvec", ··· 1773 1829 ] 1774 1830 1775 1831 [[package]] 1832 + name = "matchit" 1833 + version = "0.8.4" 1834 + source = "registry+https://github.com/rust-lang/crates.io-index" 1835 + checksum = "47e1ffaa40ddd1f3ed91f717a33c8c0ee23fff369e3aa8772b9605cc1d22f4c3" 1836 + 1837 + [[package]] 1776 1838 name = "memchr" 1777 1839 version = "2.8.0" 1778 1840 source = "registry+https://github.com/rust-lang/crates.io-index" ··· 1807 1869 "quote", 1808 1870 "syn", 1809 1871 ] 1872 + 1873 + [[package]] 1874 + name = "mime" 1875 + version = "0.3.17" 1876 + source = "registry+https://github.com/rust-lang/crates.io-index" 1877 + checksum = "6877bb514081ee2a7ff5ef9de3281f14a4dd4bceac4c09388074a6b5df8a139a" 1810 1878 1811 1879 [[package]] 1812 1880 name = "miniz_oxide" ··· 2683 2751 "serde", 2684 2752 "serde_core", 2685 2753 "zmij", 2754 + ] 2755 + 2756 + [[package]] 2757 + name = "serde_path_to_error" 2758 + version = "0.1.20" 2759 + source = "registry+https://github.com/rust-lang/crates.io-index" 2760 + checksum = "10a9ff822e371bb5403e391ecd83e182e0e77ba7f6fe0160b795797109d1b457" 2761 + dependencies = [ 2762 + "itoa", 2763 + "serde", 2764 + "serde_core", 2686 2765 ] 2687 2766 2688 2767 [[package]]
+1
Cargo.toml
··· 22 22 # strings. 23 23 base64 = "0.22" 24 24 atrium-xrpc-client = { version = "0.5", default-features = false, features = ["reqwest"] } 25 + axum = { version = "0.8", default-features = false, features = ["http1", "json", "tokio"] } 25 26 bytes = "1.10" 26 27 ciborium = "0.2" 27 28 clap = { version = "4.6", features = ["derive"] }
+1
src/common/oauth.rs
··· 1 1 //! OAuth 2.0 + JOSE primitives shared across the `test oauth *` command family. 2 2 3 + pub mod clock; 3 4 pub mod jws;
+32
src/common/oauth/clock.rs
··· 1 + use std::time::{Duration, SystemTime, UNIX_EPOCH}; 2 + 3 + /// A clock source. `RealClock` uses `SystemTime::now()`; tests inject 4 + /// a `FakeClock` with a fixed or manually advanced instant. 5 + pub trait Clock: Send + Sync { 6 + fn now_unix_seconds(&self) -> u64; 7 + } 8 + 9 + pub struct RealClock; 10 + 11 + impl Clock for RealClock { 12 + fn now_unix_seconds(&self) -> u64 { 13 + SystemTime::now() 14 + .duration_since(UNIX_EPOCH) 15 + .unwrap_or(Duration::ZERO) 16 + .as_secs() 17 + } 18 + } 19 + 20 + #[cfg(test)] 21 + mod tests { 22 + use super::*; 23 + 24 + #[test] 25 + fn real_clock_returns_reasonable_unix_seconds() { 26 + let clock = RealClock; 27 + let now = clock.now_unix_seconds(); 28 + // Check that the returned timestamp is in a reasonable range 29 + // (after 2023-11-14, which is 1700000000 Unix seconds). 30 + assert!(now > 1_700_000_000, "Clock returned unreasonable timestamp"); 31 + } 32 + }