CLI tool for migrating PDS

Resolve identity to avoid asking for current PDS URL and fix auth for data migration

Changed files
+590 -53
src
+473 -8
Cargo.lock
···
]
[[package]]
name = "atrium-api"
version = "0.25.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
···
"serde",
"serde_bytes",
"serde_json",
-
"thiserror",
"tokio",
"trait-variant",
]
···
"dashmap",
"lru",
"moka",
-
"thiserror",
"tokio",
"trait-variant",
"web-time",
]
[[package]]
name = "atrium-xrpc"
version = "0.12.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
···
"serde",
"serde_html_form",
"serde_json",
-
"thiserror",
"trait-variant",
]
···
checksum = "1628fb46dfa0b37568d12e5edd512553eccf6a22a78e8bde00bb4aed84d5bdbf"
[[package]]
name = "bytes"
version = "1.10.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
···
]
[[package]]
name = "crossbeam-channel"
version = "0.5.14"
source = "registry+https://github.com/rust-lang/crates.io-index"
···
]
[[package]]
name = "equivalent"
version = "1.0.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
···
checksum = "05f29059c0c2090612e8d742178b0580d2dc940c837851ad723096f87af6663e"
[[package]]
name = "futures-macro"
version = "0.3.31"
source = "registry+https://github.com/rust-lang/crates.io-index"
···
"libc",
"log",
"rustversion",
-
"windows",
]
[[package]]
···
]
[[package]]
name = "http"
version = "1.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
···
]
[[package]]
name = "ipld-core"
version = "0.4.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
···
"rustc_version",
"smallvec",
"tagptr",
-
"thiserror",
"uuid",
]
···
version = "1.21.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cde51589ab56b20a6f686b2c68f7a0bd6add753d697abf720d63f8db3ab7b1ad"
[[package]]
name = "openssl"
···
version = "0.1.0"
dependencies = [
"atrium-api",
"atrium-xrpc-client",
"tokio",
]
···
checksum = "350e9b48cbc6b0e028b0473b114454c6316e57336ee184ceab6e53f72c178b3e"
[[package]]
name = "proc-macro2"
version = "1.0.94"
source = "registry+https://github.com/rust-lang/crates.io-index"
···
]
[[package]]
name = "redox_syscall"
version = "0.5.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
···
"wasm-bindgen-futures",
"web-sys",
"windows-registry",
]
[[package]]
···
dependencies = [
"cfg-if",
"fastrand",
-
"getrandom",
"once_cell",
"rustix",
"windows-sys 0.59.0",
···
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b6aaf5339b578ea85b50e080feb250a3e8ae8cfcdff9a461c9ec2904bc923f52"
dependencies = [
-
"thiserror-impl",
]
[[package]]
···
version = "1.0.69"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4fee6c4efc90059e10f81e6d42c60a18f76588c3d74cb83a0b242a2b6c7504c1"
dependencies = [
"proc-macro2",
"quote",
···
"displaydoc",
"zerovec",
]
[[package]]
name = "tokio"
···
checksum = "784e0ac535deb450455cbfa28a6f0df145ea1bb7ae51b821cf5e7927fdcfbdd0"
dependencies = [
"pin-project-lite",
"tracing-core",
]
[[package]]
name = "tracing-core"
version = "0.1.33"
source = "registry+https://github.com/rust-lang/crates.io-index"
···
version = "0.8.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "eb066959b24b5196ae73cb057f45598450d2c5f71460e98c49b738086eff9c06"
[[package]]
name = "url"
···
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e0f540e3240398cce6128b64ba83fdbdd86129c16a3aa1a3a252efd66eb3d587"
dependencies = [
-
"getrandom",
]
[[package]]
···
]
[[package]]
name = "winapi"
version = "0.3.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
···
[[package]]
name = "windows"
version = "0.58.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dd04d41d93c4992d421894c18c8b43496aa748dd4c081bac0dc93eb0489272b6"
···
[[package]]
name = "windows-sys"
version = "0.52.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d"
···
[[package]]
name = "windows-targets"
version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973"
···
[[package]]
name = "windows_aarch64_gnullvm"
version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3"
···
[[package]]
name = "windows_aarch64_msvc"
version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469"
···
version = "0.53.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c7651a1f62a11b8cbd5e0d42526e55f2c99886c77e007179efff86c2b137e66c"
[[package]]
name = "windows_i686_gnu"
···
[[package]]
name = "windows_i686_msvc"
version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66"
···
[[package]]
name = "windows_x86_64_gnu"
version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78"
···
[[package]]
name = "windows_x86_64_gnullvm"
version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d"
···
[[package]]
name = "windows_x86_64_msvc"
version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec"
···
checksum = "271414315aff87387382ec3d271b52d7ae78726f5d44ac98b4f4030c91880486"
[[package]]
name = "wit-bindgen-rt"
version = "0.33.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
···
"quote",
"syn",
"synstructure",
]
[[package]]
···
]
[[package]]
+
name = "async-recursion"
+
version = "1.1.1"
+
source = "registry+https://github.com/rust-lang/crates.io-index"
+
checksum = "3b43422f69d8ff38f95f1b2bb76517c91589a924d1559a0e935d7c8ce0274c11"
+
dependencies = [
+
"proc-macro2",
+
"quote",
+
"syn",
+
]
+
+
[[package]]
+
name = "async-trait"
+
version = "0.1.83"
+
source = "registry+https://github.com/rust-lang/crates.io-index"
+
checksum = "721cae7de5c34fbb2acd27e21e6d2cf7b886dce0c27388d46c4e6c47ea4318dd"
+
dependencies = [
+
"proc-macro2",
+
"quote",
+
"syn",
+
]
+
+
[[package]]
name = "atrium-api"
version = "0.25.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
···
"serde",
"serde_bytes",
"serde_json",
+
"thiserror 1.0.69",
"tokio",
"trait-variant",
]
···
"dashmap",
"lru",
"moka",
+
"thiserror 1.0.69",
"tokio",
"trait-variant",
"web-time",
]
[[package]]
+
name = "atrium-identity"
+
version = "0.1.1"
+
source = "registry+https://github.com/rust-lang/crates.io-index"
+
checksum = "116fec95d2b8088f3e2c064f38bc5ceb6977ea1ce9e2ffd510d19304ded14b1c"
+
dependencies = [
+
"atrium-api",
+
"atrium-common",
+
"atrium-xrpc",
+
"hickory-proto 0.24.4",
+
"serde",
+
"serde_html_form",
+
"serde_json",
+
"thiserror 1.0.69",
+
"trait-variant",
+
]
+
+
[[package]]
name = "atrium-xrpc"
version = "0.12.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
···
"serde",
"serde_html_form",
"serde_json",
+
"thiserror 1.0.69",
"trait-variant",
]
···
checksum = "1628fb46dfa0b37568d12e5edd512553eccf6a22a78e8bde00bb4aed84d5bdbf"
[[package]]
+
name = "byteorder"
+
version = "1.5.0"
+
source = "registry+https://github.com/rust-lang/crates.io-index"
+
checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b"
+
+
[[package]]
name = "bytes"
version = "1.10.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
···
]
[[package]]
+
name = "critical-section"
+
version = "1.2.0"
+
source = "registry+https://github.com/rust-lang/crates.io-index"
+
checksum = "790eea4361631c5e7d22598ecd5723ff611904e3344ce8720784c93e3d83d40b"
+
+
[[package]]
name = "crossbeam-channel"
version = "0.5.14"
source = "registry+https://github.com/rust-lang/crates.io-index"
···
]
[[package]]
+
name = "enum-as-inner"
+
version = "0.6.1"
+
source = "registry+https://github.com/rust-lang/crates.io-index"
+
checksum = "a1e6a265c649f3f5979b601d26f1d05ada116434c87741c9493cb56218f76cbc"
+
dependencies = [
+
"heck",
+
"proc-macro2",
+
"quote",
+
"syn",
+
]
+
+
[[package]]
name = "equivalent"
version = "1.0.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
···
checksum = "05f29059c0c2090612e8d742178b0580d2dc940c837851ad723096f87af6663e"
[[package]]
+
name = "futures-io"
+
version = "0.3.31"
+
source = "registry+https://github.com/rust-lang/crates.io-index"
+
checksum = "9e5c1b78ca4aae1ac06c48a526a655760685149f0d465d21f37abfe57ce075c6"
+
+
[[package]]
name = "futures-macro"
version = "0.3.31"
source = "registry+https://github.com/rust-lang/crates.io-index"
···
"libc",
"log",
"rustversion",
+
"windows 0.58.0",
+
]
+
+
[[package]]
+
name = "getrandom"
+
version = "0.2.15"
+
source = "registry+https://github.com/rust-lang/crates.io-index"
+
checksum = "c4567c8db10ae91089c99af84c68c38da3ec2f087c3f82960bcdbf3656b6f4d7"
+
dependencies = [
+
"cfg-if",
+
"libc",
+
"wasi 0.11.0+wasi-snapshot-preview1",
]
[[package]]
···
]
[[package]]
+
name = "heck"
+
version = "0.5.0"
+
source = "registry+https://github.com/rust-lang/crates.io-index"
+
checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea"
+
+
[[package]]
+
name = "hickory-proto"
+
version = "0.24.4"
+
source = "registry+https://github.com/rust-lang/crates.io-index"
+
checksum = "92652067c9ce6f66ce53cc38d1169daa36e6e7eb7dd3b63b5103bd9d97117248"
+
dependencies = [
+
"async-trait",
+
"cfg-if",
+
"data-encoding",
+
"enum-as-inner",
+
"futures-channel",
+
"futures-io",
+
"futures-util",
+
"idna",
+
"ipnet",
+
"once_cell",
+
"rand 0.8.5",
+
"thiserror 1.0.69",
+
"tinyvec",
+
"tracing",
+
"url",
+
]
+
+
[[package]]
+
name = "hickory-proto"
+
version = "0.25.1"
+
source = "registry+https://github.com/rust-lang/crates.io-index"
+
checksum = "6d844af74f7b799e41c78221be863bade11c430d46042c3b49ca8ae0c6d27287"
+
dependencies = [
+
"async-recursion",
+
"async-trait",
+
"cfg-if",
+
"critical-section",
+
"data-encoding",
+
"enum-as-inner",
+
"futures-channel",
+
"futures-io",
+
"futures-util",
+
"idna",
+
"ipnet",
+
"once_cell",
+
"rand 0.9.0",
+
"ring",
+
"thiserror 2.0.12",
+
"tinyvec",
+
"tokio",
+
"tracing",
+
"url",
+
]
+
+
[[package]]
+
name = "hickory-resolver"
+
version = "0.25.1"
+
source = "registry+https://github.com/rust-lang/crates.io-index"
+
checksum = "a128410b38d6f931fcc6ca5c107a3b02cabd6c05967841269a4ad65d23c44331"
+
dependencies = [
+
"cfg-if",
+
"futures-util",
+
"hickory-proto 0.25.1",
+
"ipconfig",
+
"moka",
+
"once_cell",
+
"parking_lot",
+
"rand 0.9.0",
+
"resolv-conf",
+
"smallvec",
+
"thiserror 2.0.12",
+
"tokio",
+
"tracing",
+
]
+
+
[[package]]
+
name = "hostname"
+
version = "0.4.0"
+
source = "registry+https://github.com/rust-lang/crates.io-index"
+
checksum = "f9c7c7c8ac16c798734b8a24560c1362120597c40d5e1459f09498f8f6c8f2ba"
+
dependencies = [
+
"cfg-if",
+
"libc",
+
"windows 0.52.0",
+
]
+
+
[[package]]
name = "http"
version = "1.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
···
]
[[package]]
+
name = "ipconfig"
+
version = "0.3.2"
+
source = "registry+https://github.com/rust-lang/crates.io-index"
+
checksum = "b58db92f96b720de98181bbbe63c831e87005ab460c1bf306eb2622b4707997f"
+
dependencies = [
+
"socket2",
+
"widestring",
+
"windows-sys 0.48.0",
+
"winreg",
+
]
+
+
[[package]]
name = "ipld-core"
version = "0.4.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
···
"rustc_version",
"smallvec",
"tagptr",
+
"thiserror 1.0.69",
"uuid",
]
···
version = "1.21.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cde51589ab56b20a6f686b2c68f7a0bd6add753d697abf720d63f8db3ab7b1ad"
+
dependencies = [
+
"critical-section",
+
"portable-atomic",
+
]
[[package]]
name = "openssl"
···
version = "0.1.0"
dependencies = [
"atrium-api",
+
"atrium-common",
+
"atrium-identity",
"atrium-xrpc-client",
+
"hickory-resolver",
"tokio",
]
···
checksum = "350e9b48cbc6b0e028b0473b114454c6316e57336ee184ceab6e53f72c178b3e"
[[package]]
+
name = "ppv-lite86"
+
version = "0.2.20"
+
source = "registry+https://github.com/rust-lang/crates.io-index"
+
checksum = "77957b295656769bb8ad2b6a6b09d897d94f05c41b069aede1fcdaa675eaea04"
+
dependencies = [
+
"zerocopy 0.7.35",
+
]
+
+
[[package]]
name = "proc-macro2"
version = "1.0.94"
source = "registry+https://github.com/rust-lang/crates.io-index"
···
]
[[package]]
+
name = "rand"
+
version = "0.8.5"
+
source = "registry+https://github.com/rust-lang/crates.io-index"
+
checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404"
+
dependencies = [
+
"libc",
+
"rand_chacha 0.3.1",
+
"rand_core 0.6.4",
+
]
+
+
[[package]]
+
name = "rand"
+
version = "0.9.0"
+
source = "registry+https://github.com/rust-lang/crates.io-index"
+
checksum = "3779b94aeb87e8bd4e834cee3650289ee9e0d5677f976ecdb6d219e5f4f6cd94"
+
dependencies = [
+
"rand_chacha 0.9.0",
+
"rand_core 0.9.3",
+
"zerocopy 0.8.23",
+
]
+
+
[[package]]
+
name = "rand_chacha"
+
version = "0.3.1"
+
source = "registry+https://github.com/rust-lang/crates.io-index"
+
checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88"
+
dependencies = [
+
"ppv-lite86",
+
"rand_core 0.6.4",
+
]
+
+
[[package]]
+
name = "rand_chacha"
+
version = "0.9.0"
+
source = "registry+https://github.com/rust-lang/crates.io-index"
+
checksum = "d3022b5f1df60f26e1ffddd6c66e8aa15de382ae63b3a0c1bfc0e4d3e3f325cb"
+
dependencies = [
+
"ppv-lite86",
+
"rand_core 0.9.3",
+
]
+
+
[[package]]
+
name = "rand_core"
+
version = "0.6.4"
+
source = "registry+https://github.com/rust-lang/crates.io-index"
+
checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c"
+
dependencies = [
+
"getrandom 0.2.15",
+
]
+
+
[[package]]
+
name = "rand_core"
+
version = "0.9.3"
+
source = "registry+https://github.com/rust-lang/crates.io-index"
+
checksum = "99d9a13982dcf210057a8a78572b2217b667c3beacbf3a0d8b454f6f82837d38"
+
dependencies = [
+
"getrandom 0.3.1",
+
]
+
+
[[package]]
name = "redox_syscall"
version = "0.5.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
···
"wasm-bindgen-futures",
"web-sys",
"windows-registry",
+
]
+
+
[[package]]
+
name = "resolv-conf"
+
version = "0.7.1"
+
source = "registry+https://github.com/rust-lang/crates.io-index"
+
checksum = "48375394603e3dd4b2d64371f7148fd8c7baa2680e28741f2cb8d23b59e3d4c4"
+
dependencies = [
+
"hostname",
+
]
+
+
[[package]]
+
name = "ring"
+
version = "0.17.14"
+
source = "registry+https://github.com/rust-lang/crates.io-index"
+
checksum = "a4689e6c2294d81e88dc6261c768b63bc4fcdb852be6d1352498b114f61383b7"
+
dependencies = [
+
"cc",
+
"cfg-if",
+
"getrandom 0.2.15",
+
"libc",
+
"untrusted",
+
"windows-sys 0.52.0",
]
[[package]]
···
dependencies = [
"cfg-if",
"fastrand",
+
"getrandom 0.3.1",
"once_cell",
"rustix",
"windows-sys 0.59.0",
···
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b6aaf5339b578ea85b50e080feb250a3e8ae8cfcdff9a461c9ec2904bc923f52"
dependencies = [
+
"thiserror-impl 1.0.69",
+
]
+
+
[[package]]
+
name = "thiserror"
+
version = "2.0.12"
+
source = "registry+https://github.com/rust-lang/crates.io-index"
+
checksum = "567b8a2dae586314f7be2a752ec7474332959c6460e02bde30d702a66d488708"
+
dependencies = [
+
"thiserror-impl 2.0.12",
]
[[package]]
···
version = "1.0.69"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4fee6c4efc90059e10f81e6d42c60a18f76588c3d74cb83a0b242a2b6c7504c1"
+
dependencies = [
+
"proc-macro2",
+
"quote",
+
"syn",
+
]
+
+
[[package]]
+
name = "thiserror-impl"
+
version = "2.0.12"
+
source = "registry+https://github.com/rust-lang/crates.io-index"
+
checksum = "7f7cf42b4507d8ea322120659672cf1b9dbb93f8f2d4ecfd6e51350ff5b17a1d"
dependencies = [
"proc-macro2",
"quote",
···
"displaydoc",
"zerovec",
]
+
+
[[package]]
+
name = "tinyvec"
+
version = "1.6.0"
+
source = "registry+https://github.com/rust-lang/crates.io-index"
+
checksum = "87cc5ceb3875bb20c2890005a4e226a4651264a5c75edb2421b52861a0a0cb50"
+
dependencies = [
+
"tinyvec_macros",
+
]
+
+
[[package]]
+
name = "tinyvec_macros"
+
version = "0.1.1"
+
source = "registry+https://github.com/rust-lang/crates.io-index"
+
checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20"
[[package]]
name = "tokio"
···
checksum = "784e0ac535deb450455cbfa28a6f0df145ea1bb7ae51b821cf5e7927fdcfbdd0"
dependencies = [
"pin-project-lite",
+
"tracing-attributes",
"tracing-core",
]
[[package]]
+
name = "tracing-attributes"
+
version = "0.1.28"
+
source = "registry+https://github.com/rust-lang/crates.io-index"
+
checksum = "395ae124c09f9e6918a2310af6038fba074bcf474ac352496d5910dd59a2226d"
+
dependencies = [
+
"proc-macro2",
+
"quote",
+
"syn",
+
]
+
+
[[package]]
name = "tracing-core"
version = "0.1.33"
source = "registry+https://github.com/rust-lang/crates.io-index"
···
version = "0.8.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "eb066959b24b5196ae73cb057f45598450d2c5f71460e98c49b738086eff9c06"
+
+
[[package]]
+
name = "untrusted"
+
version = "0.9.0"
+
source = "registry+https://github.com/rust-lang/crates.io-index"
+
checksum = "8ecb6da28b8a351d773b68d5825ac39017e680750f980f3a1a85cd8dd28a47c1"
[[package]]
name = "url"
···
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e0f540e3240398cce6128b64ba83fdbdd86129c16a3aa1a3a252efd66eb3d587"
dependencies = [
+
"getrandom 0.3.1",
]
[[package]]
···
]
[[package]]
+
name = "widestring"
+
version = "1.2.0"
+
source = "registry+https://github.com/rust-lang/crates.io-index"
+
checksum = "dd7cf3379ca1aac9eea11fba24fd7e315d621f8dfe35c8d7d2be8b793726e07d"
+
+
[[package]]
name = "winapi"
version = "0.3.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
···
[[package]]
name = "windows"
+
version = "0.52.0"
+
source = "registry+https://github.com/rust-lang/crates.io-index"
+
checksum = "e48a53791691ab099e5e2ad123536d0fff50652600abaf43bbf952894110d0be"
+
dependencies = [
+
"windows-core 0.52.0",
+
"windows-targets 0.52.6",
+
]
+
+
[[package]]
+
name = "windows"
version = "0.58.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dd04d41d93c4992d421894c18c8b43496aa748dd4c081bac0dc93eb0489272b6"
···
[[package]]
name = "windows-sys"
+
version = "0.48.0"
+
source = "registry+https://github.com/rust-lang/crates.io-index"
+
checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9"
+
dependencies = [
+
"windows-targets 0.48.5",
+
]
+
+
[[package]]
+
name = "windows-sys"
version = "0.52.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d"
···
[[package]]
name = "windows-targets"
+
version = "0.48.5"
+
source = "registry+https://github.com/rust-lang/crates.io-index"
+
checksum = "9a2fa6e2155d7247be68c096456083145c183cbbbc2764150dda45a87197940c"
+
dependencies = [
+
"windows_aarch64_gnullvm 0.48.5",
+
"windows_aarch64_msvc 0.48.5",
+
"windows_i686_gnu 0.48.5",
+
"windows_i686_msvc 0.48.5",
+
"windows_x86_64_gnu 0.48.5",
+
"windows_x86_64_gnullvm 0.48.5",
+
"windows_x86_64_msvc 0.48.5",
+
]
+
+
[[package]]
+
name = "windows-targets"
version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973"
···
[[package]]
name = "windows_aarch64_gnullvm"
+
version = "0.48.5"
+
source = "registry+https://github.com/rust-lang/crates.io-index"
+
checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8"
+
+
[[package]]
+
name = "windows_aarch64_gnullvm"
version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3"
···
[[package]]
name = "windows_aarch64_msvc"
+
version = "0.48.5"
+
source = "registry+https://github.com/rust-lang/crates.io-index"
+
checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc"
+
+
[[package]]
+
name = "windows_aarch64_msvc"
version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469"
···
version = "0.53.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c7651a1f62a11b8cbd5e0d42526e55f2c99886c77e007179efff86c2b137e66c"
+
+
[[package]]
+
name = "windows_i686_gnu"
+
version = "0.48.5"
+
source = "registry+https://github.com/rust-lang/crates.io-index"
+
checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e"
[[package]]
name = "windows_i686_gnu"
···
[[package]]
name = "windows_i686_msvc"
+
version = "0.48.5"
+
source = "registry+https://github.com/rust-lang/crates.io-index"
+
checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406"
+
+
[[package]]
+
name = "windows_i686_msvc"
version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66"
···
[[package]]
name = "windows_x86_64_gnu"
+
version = "0.48.5"
+
source = "registry+https://github.com/rust-lang/crates.io-index"
+
checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e"
+
+
[[package]]
+
name = "windows_x86_64_gnu"
version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78"
···
[[package]]
name = "windows_x86_64_gnullvm"
+
version = "0.48.5"
+
source = "registry+https://github.com/rust-lang/crates.io-index"
+
checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc"
+
+
[[package]]
+
name = "windows_x86_64_gnullvm"
version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d"
···
[[package]]
name = "windows_x86_64_msvc"
+
version = "0.48.5"
+
source = "registry+https://github.com/rust-lang/crates.io-index"
+
checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538"
+
+
[[package]]
+
name = "windows_x86_64_msvc"
version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec"
···
checksum = "271414315aff87387382ec3d271b52d7ae78726f5d44ac98b4f4030c91880486"
[[package]]
+
name = "winreg"
+
version = "0.50.0"
+
source = "registry+https://github.com/rust-lang/crates.io-index"
+
checksum = "524e57b2c537c0f9b1e69f1965311ec12182b4122e45035b1508cd24d2adadb1"
+
dependencies = [
+
"cfg-if",
+
"windows-sys 0.48.0",
+
]
+
+
[[package]]
name = "wit-bindgen-rt"
version = "0.33.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
···
"quote",
"syn",
"synstructure",
+
]
+
+
[[package]]
+
name = "zerocopy"
+
version = "0.7.35"
+
source = "registry+https://github.com/rust-lang/crates.io-index"
+
checksum = "1b9b4fd18abc82b8136838da5d50bae7bdea537c574d8dc1a34ed098d6c166f0"
+
dependencies = [
+
"byteorder",
+
"zerocopy-derive 0.7.35",
+
]
+
+
[[package]]
+
name = "zerocopy"
+
version = "0.8.23"
+
source = "registry+https://github.com/rust-lang/crates.io-index"
+
checksum = "fd97444d05a4328b90e75e503a34bad781f14e28a823ad3557f0750df1ebcbc6"
+
dependencies = [
+
"zerocopy-derive 0.8.23",
+
]
+
+
[[package]]
+
name = "zerocopy-derive"
+
version = "0.7.35"
+
source = "registry+https://github.com/rust-lang/crates.io-index"
+
checksum = "fa4f8080344d4671fb4e831a13ad1e68092748387dfc4f55e356242fae12ce3e"
+
dependencies = [
+
"proc-macro2",
+
"quote",
+
"syn",
+
]
+
+
[[package]]
+
name = "zerocopy-derive"
+
version = "0.8.23"
+
source = "registry+https://github.com/rust-lang/crates.io-index"
+
checksum = "6352c01d0edd5db859a63e2605f4ea3183ddbd15e2c4a9e7d32184df75e4f154"
+
dependencies = [
+
"proc-macro2",
+
"quote",
+
"syn",
]
[[package]]
+3
Cargo.toml
···
[dependencies]
atrium-api = { version = "0.25.0", default-features = false, features = ["agent", "bluesky"] }
atrium-xrpc-client = "0.5.11"
tokio = { version = "1.44.0", features = ["macros", "rt-multi-thread"]}
···
[dependencies]
atrium-api = { version = "0.25.0", default-features = false, features = ["agent", "bluesky"] }
+
atrium-common = "0.1.0"
+
atrium-identity = { version = "0.1.1", features = ["doh-handle-resolver"] }
atrium-xrpc-client = "0.5.11"
+
hickory-resolver = "0.25.1"
tokio = { version = "1.44.0", features = ["macros", "rt-multi-thread"]}
+21 -9
src/jwt.rs
···
-
use atrium_api::xrpc::{
-
http::{Request, Response},
-
types::AuthorizationToken,
-
HttpClient, XrpcClient,
};
use atrium_xrpc_client::reqwest::ReqwestClient;
-
pub struct JwtAuthedClient {
token: String,
inner: ReqwestClient,
}
-
impl JwtAuthedClient {
-
pub fn new(base_uri: impl AsRef<str>, token: String) -> Self {
Self {
token,
inner: ReqwestClient::new(base_uri),
}
}
}
-
impl HttpClient for JwtAuthedClient {
async fn send_http(
&self,
request: Request<Vec<u8>>,
···
}
}
-
impl XrpcClient for JwtAuthedClient {
fn base_uri(&self) -> String {
self.inner.base_uri()
}
···
Some(AuthorizationToken::Bearer(self.token.clone()))
}
}
···
+
use atrium_api::{
+
agent::SessionManager,
+
types::string::Did,
+
xrpc::{
+
http::{Request, Response},
+
types::AuthorizationToken,
+
HttpClient, XrpcClient,
+
},
};
use atrium_xrpc_client::reqwest::ReqwestClient;
+
pub struct JwtSessionManager {
+
did: Did,
token: String,
inner: ReqwestClient,
}
+
impl JwtSessionManager {
+
pub fn new(did: Did, token: String, base_uri: impl AsRef<str>) -> Self {
Self {
+
did,
token,
inner: ReqwestClient::new(base_uri),
}
}
}
+
impl HttpClient for JwtSessionManager {
async fn send_http(
&self,
request: Request<Vec<u8>>,
···
}
}
+
impl XrpcClient for JwtSessionManager {
fn base_uri(&self) -> String {
self.inner.base_uri()
}
···
Some(AuthorizationToken::Bearer(self.token.clone()))
}
}
+
+
impl SessionManager for JwtSessionManager {
+
async fn did(&self) -> Option<Did> {
+
Some(self.did.clone())
+
}
+
}
+93 -36
src/main.rs
···
use atrium_api::{
-
agent::atp_agent::{store::MemorySessionStore, AtpAgent},
app::bsky::actor::{get_preferences, put_preferences},
com::atproto::{
-
repo::list_missing_blobs,
server::{create_account, get_service_auth},
sync::{get_blob, get_repo, list_blobs},
},
-
types::string::{Handle, Nsid},
};
use atrium_xrpc_client::reqwest::ReqwestClient;
use std::{
-
io::{self, Write}, sync::Arc
};
mod jwt;
fn readln(message: Option<impl Into<String>>) -> std::io::Result<Arc<str>> {
if let Some(message) = message {
print!("{}", message.into());
···
#[tokio::main]
async fn main() {
println!("Please log in to your current PDS. Authenticated access is needed throughout the migration process");
-
let old_pds_url = match readln(Some("The URL of your current PDS: ")) {
Ok(string) => string,
Err(err) => {
-
println!("Could not read the URL of your current PDS due to error: {err}");
return;
}
};
-
let identity = match readln(Some("Identifier (handle, did or email): ")) {
Ok(string) => string.trim().to_string(),
Err(err) => {
-
println!("Could not read username due to error: {err}");
return;
}
};
-
let password = match readln(Some("Password: ")) {
-
Ok(string) => string.trim().to_string(),
Err(err) => {
-
println!("Could not read password due to error: {err}");
return;
}
};
-
println!("Authenticating with your PDS");
-
let old_agent = AtpAgent::new(
-
ReqwestClient::new(&old_pds_url),
MemorySessionStore::default(),
);
-
if let Err(err) = old_agent.login(identity, password).await {
-
println!("Failed to log in to your account on your current PDS due to error: {err}");
return;
};
-
println!("Log in successful!");
println!();
// Create new account
···
}
};
let new_pds_did = &describe_res.did;
-
let service_jwt_res = match old_agent
.api
.com
.atproto
···
}
};
-
let new_agent = AtpAgent::new(
-
jwt::JwtAuthedClient::new(&new_pds_url, service_jwt_res.token.clone()),
-
MemorySessionStore::default(),
-
);
-
match new_agent
.api
.com
.atproto
.server
.create_account(
create_account::InputData {
-
did: old_agent.did().await,
email: Some(email.to_string()),
-
handle,
invite_code,
password: Some(password.to_string()),
plc_op: None,
···
return;
}
}
println!("Successfully created account on your new PDS!");
println!();
// Migrate data
println!("Migrating your data");
-
let car = match old_agent
.api
.com
.atproto
.sync
.get_repo(
get_repo::ParametersData {
-
did: old_agent.did().await.unwrap(),
since: None,
}
.into(),
···
return;
}
};
match new_agent.api.com.atproto.repo.import_repo(car).await {
Ok(_) => (),
···
}
println!("Repository successfully migrated");
-
let mut listed_blobs = match old_agent
.api
.com
.atproto
···
.list_blobs(
list_blobs::ParametersData {
cursor: None,
-
did: old_agent.did().await.unwrap(),
limit: None,
since: None,
}
···
};
for cid in listed_blobs.cids.iter() {
-
let blob = match old_agent
.api
.com
.atproto
···
.get_blob(
get_blob::ParametersData {
cid: cid.to_owned(),
-
did: old_agent.did().await.unwrap(),
}
.into(),
)
···
let mut cursor = listed_blobs.cursor.clone();
while cursor.is_some() {
-
listed_blobs = match old_agent
.api
.com
.atproto
···
.list_blobs(
list_blobs::ParametersData {
cursor: cursor.clone(),
-
did: old_agent.did().await.unwrap(),
limit: None,
since: None,
}
···
};
for cid in listed_blobs.cids.iter() {
-
let blob = match old_agent
.api
.com
.atproto
···
.get_blob(
get_blob::ParametersData {
cid: cid.to_owned(),
-
did: old_agent.did().await.unwrap(),
}
.into(),
)
···
}
println!("Blobs successfully migrated!");
-
let prefs = match old_agent
.api
.app
.bsky
···
use atrium_api::{
+
agent::{
+
atp_agent::{store::MemorySessionStore, AtpAgent},
+
Agent,
+
},
app::bsky::actor::{get_preferences, put_preferences},
com::atproto::{
server::{create_account, get_service_auth},
sync::{get_blob, get_repo, list_blobs},
},
+
types::string::{Did, Handle, Nsid},
+
};
+
use atrium_common::resolver::Resolver;
+
use atrium_identity::{
+
did::{CommonDidResolver, CommonDidResolverConfig},
+
handle::{AtprotoHandleResolver, AtprotoHandleResolverConfig, DnsTxtResolver},
+
identity_resolver::{IdentityResolver, IdentityResolverConfig},
};
use atrium_xrpc_client::reqwest::ReqwestClient;
+
use hickory_resolver::TokioResolver;
use std::{
+
io::{self, Write},
+
sync::Arc,
};
mod jwt;
+
struct HickoryDnsTxtResolver {
+
resolver: TokioResolver,
+
}
+
+
impl Default for HickoryDnsTxtResolver {
+
fn default() -> Self {
+
Self {
+
resolver: TokioResolver::builder_tokio().unwrap().build(),
+
}
+
}
+
}
+
+
impl DnsTxtResolver for HickoryDnsTxtResolver {
+
async fn resolve(
+
&self,
+
query: &str,
+
) -> core::result::Result<Vec<String>, Box<dyn std::error::Error + Send + Sync + 'static>> {
+
Ok(self
+
.resolver
+
.txt_lookup(query)
+
.await?
+
.iter()
+
.map(|txt| txt.to_string())
+
.collect())
+
}
+
}
+
fn readln(message: Option<impl Into<String>>) -> std::io::Result<Arc<str>> {
if let Some(message) = message {
print!("{}", message.into());
···
#[tokio::main]
async fn main() {
println!("Please log in to your current PDS. Authenticated access is needed throughout the migration process");
+
let identifier = match readln(Some("Identifier (handle or did): ")) {
Ok(string) => string,
Err(err) => {
+
println!("Could not read username due to error: {err}");
return;
}
};
+
let password = match readln(Some("Password: ")) {
Ok(string) => string.trim().to_string(),
Err(err) => {
+
println!("Could not read password due to error: {err}");
return;
}
};
+
+
let identity_resolver = IdentityResolver::new(IdentityResolverConfig {
+
did_resolver: CommonDidResolver::new(CommonDidResolverConfig {
+
plc_directory_url: String::from("https://plc.directory"),
+
http_client: ReqwestClient::new("").into(),
+
}),
+
handle_resolver: AtprotoHandleResolver::new(AtprotoHandleResolverConfig {
+
dns_txt_resolver: HickoryDnsTxtResolver::default(),
+
http_client: ReqwestClient::new("").into(),
+
}),
+
});
+
let identity = match identity_resolver.resolve(identifier.as_ref()).await {
+
Ok(identity) => identity,
Err(err) => {
+
println!("Could not resolve identity from identifier {identifier} due to error: {err}");
return;
}
};
+
+
let current_agent = AtpAgent::new(
+
ReqwestClient::new(&identity.pds),
MemorySessionStore::default(),
);
+
if let Err(err) = current_agent.login(identifier, password).await {
+
println!(
+
"Failed to log in to your account on your current PDS at {} due to error: {err}",
+
&identity.pds
+
);
return;
};
+
println!("Log in at {} was successful!", &identity.pds);
println!();
// Create new account
···
}
};
let new_pds_did = &describe_res.did;
+
let service_jwt_res = match current_agent
.api
.com
.atproto
···
}
};
+
let new_jwt_agent = Agent::new(jwt::JwtSessionManager::new(
+
Did::new(identity.did.clone()).unwrap(),
+
service_jwt_res.token.clone(),
+
&new_pds_url,
+
));
+
match new_jwt_agent
.api
.com
.atproto
.server
.create_account(
create_account::InputData {
+
did: current_agent.did().await,
email: Some(email.to_string()),
+
handle: handle.clone(),
invite_code,
password: Some(password.to_string()),
plc_op: None,
···
return;
}
}
+
if let Err(err) = new_agent.login(handle.clone(), password).await {
+
println!("Failed to log in to your account on your new PDS due to error: {err}");
+
return;
+
};
println!("Successfully created account on your new PDS!");
println!();
// Migrate data
println!("Migrating your data");
+
let car = match current_agent
.api
.com
.atproto
.sync
.get_repo(
get_repo::ParametersData {
+
did: current_agent.did().await.unwrap(),
since: None,
}
.into(),
···
return;
}
};
+
println!("CAR file downloaded");
match new_agent.api.com.atproto.repo.import_repo(car).await {
Ok(_) => (),
···
}
println!("Repository successfully migrated");
+
let mut listed_blobs = match current_agent
.api
.com
.atproto
···
.list_blobs(
list_blobs::ParametersData {
cursor: None,
+
did: current_agent.did().await.unwrap(),
limit: None,
since: None,
}
···
};
for cid in listed_blobs.cids.iter() {
+
let blob = match current_agent
.api
.com
.atproto
···
.get_blob(
get_blob::ParametersData {
cid: cid.to_owned(),
+
did: current_agent.did().await.unwrap(),
}
.into(),
)
···
let mut cursor = listed_blobs.cursor.clone();
while cursor.is_some() {
+
listed_blobs = match current_agent
.api
.com
.atproto
···
.list_blobs(
list_blobs::ParametersData {
cursor: cursor.clone(),
+
did: current_agent.did().await.unwrap(),
limit: None,
since: None,
}
···
};
for cid in listed_blobs.cids.iter() {
+
let blob = match current_agent
.api
.com
.atproto
···
.get_blob(
get_blob::ParametersData {
cid: cid.to_owned(),
+
did: current_agent.did().await.unwrap(),
}
.into(),
)
···
}
println!("Blobs successfully migrated!");
+
let prefs = match current_agent
.api
.app
.bsky