aboutsummaryrefslogtreecommitdiffstats
path: root/adenosine-pds/src
diff options
context:
space:
mode:
authorbryan newbold <bnewbold@robocracy.org>2023-02-19 17:01:07 -0800
committerbryan newbold <bnewbold@robocracy.org>2023-02-19 17:19:39 -0800
commitec2bf0c54245cd84f492847d2a1e070919b14a53 (patch)
treedbeb5b28c8b7e06eb9ac192d14ea4fdec81bb1e7 /adenosine-pds/src
parentb8ba815b4cafdff48694d14c994e862738d342ef (diff)
downloadadenosine-ec2bf0c54245cd84f492847d2a1e070919b14a53.tar.gz
adenosine-ec2bf0c54245cd84f492847d2a1e070919b14a53.zip
more refactoring of common code and APIs
Diffstat (limited to 'adenosine-pds/src')
-rw-r--r--adenosine-pds/src/bin/adenosine-pds.rs6
-rw-r--r--adenosine-pds/src/db.rs15
-rw-r--r--adenosine-pds/src/db_bsky.rs (renamed from adenosine-pds/src/bsky.rs)71
-rw-r--r--adenosine-pds/src/lib.rs134
-rw-r--r--adenosine-pds/src/models.rs246
-rw-r--r--adenosine-pds/src/web.rs11
6 files changed, 100 insertions, 383 deletions
diff --git a/adenosine-pds/src/bin/adenosine-pds.rs b/adenosine-pds/src/bin/adenosine-pds.rs
index c16e7e0..c004098 100644
--- a/adenosine-pds/src/bin/adenosine-pds.rs
+++ b/adenosine-pds/src/bin/adenosine-pds.rs
@@ -1,5 +1,7 @@
+use adenosine::com_atproto;
+use adenosine::crypto::KeyPair;
use adenosine::mst;
-use adenosine_pds::models::AccountRequest;
+use adenosine::repo::RepoStore;
use adenosine_pds::*;
use anyhow::Result;
use serde_json::json;
@@ -208,7 +210,7 @@ fn main() -> Result<()> {
public_url,
did_plc,
} => {
- let req = AccountRequest {
+ let req = com_atproto::AccountRequest {
email,
handle: handle.clone(),
password,
diff --git a/adenosine-pds/src/db.rs b/adenosine-pds/src/db.rs
index b694bb5..4cbece6 100644
--- a/adenosine-pds/src/db.rs
+++ b/adenosine-pds/src/db.rs
@@ -1,6 +1,7 @@
-use crate::models::{FollowRecord, Post, RefRecord};
/// ATP database (as distinct from blockstore)
-use crate::{created_at_now, ipld_into_json_value, AtpSession, Did, KeyPair, Tid};
+use crate::{created_at_now, ipld_into_json_value, Did, KeyPair, Tid};
+use adenosine::app_bsky;
+use adenosine::com_atproto;
use anyhow::{anyhow, Result};
use lazy_static::lazy_static;
use libipld::cbor::DagCborCodec;
@@ -105,7 +106,7 @@ impl AtpDatabase {
handle: &str,
password: &str,
keypair: &KeyPair,
- ) -> Result<AtpSession> {
+ ) -> Result<com_atproto::Session> {
let mut stmt = self
.conn
.prepare_cached("SELECT did, password_bcrypt FROM account WHERE handle = ?1")?;
@@ -120,7 +121,7 @@ impl AtpDatabase {
.conn
.prepare_cached("INSERT INTO session (did, jwt) VALUES (?1, ?2)")?;
stmt.execute(params!(did.to_string(), jwt))?;
- Ok(AtpSession {
+ Ok(com_atproto::Session {
did: did.to_string(),
name: handle.to_string(),
accessJwt: jwt.to_string(),
@@ -192,7 +193,7 @@ impl AtpDatabase {
// need to re-compute the CID from DagCbor re-encoding, I guess. bleh.
let block = Block::<DefaultParams>::encode(DagCborCodec, Code::Sha2_256, &val)?;
let cid = *block.cid();
- let post: Post = serde_json::from_value(ipld_into_json_value(val))?;
+ let post: app_bsky::Post = serde_json::from_value(ipld_into_json_value(val))?;
let (reply_to_parent_uri, reply_to_root_uri) = match post.reply {
Some(ref reply) => (Some(reply.parent.uri.clone()), Some(reply.root.uri.clone())),
None => (None, None),
@@ -226,7 +227,7 @@ impl AtpDatabase {
val: Option<Ipld>,
) -> Result<()> {
if let Some(val) = val {
- let ref_obj: RefRecord = serde_json::from_value(ipld_into_json_value(val))?;
+ let ref_obj: app_bsky::RefRecord = serde_json::from_value(ipld_into_json_value(val))?;
let mut stmt = self
.conn
.prepare_cached("INSERT INTO bsky_ref (ref_type, did, tid, subject_uri, subject_cid, created_at) VALUES (?1, ?2, ?3, ?4, ?5, ?6)")?;
@@ -253,7 +254,7 @@ impl AtpDatabase {
pub fn bsky_upsert_follow(&mut self, did: &Did, tid: &Tid, val: Option<Ipld>) -> Result<()> {
if let Some(val) = val {
- let follow: FollowRecord = serde_json::from_value(ipld_into_json_value(val))?;
+ let follow: app_bsky::FollowRecord = serde_json::from_value(ipld_into_json_value(val))?;
let mut stmt = self
.conn
.prepare_cached("INSERT INTO bsky_follow (did, tid, subject_did, created_at) VALUES (?1, ?2, ?3, ?4)")?;
diff --git a/adenosine-pds/src/bsky.rs b/adenosine-pds/src/db_bsky.rs
index caa16f6..ee8e0f3 100644
--- a/adenosine-pds/src/bsky.rs
+++ b/adenosine-pds/src/db_bsky.rs
@@ -1,11 +1,9 @@
-use crate::models::*;
/// Helper functions for doing database and repo operations relating to bluesky endpoints and
/// records
-use crate::{
- ipld_into_json_value, json_value_into_ipld, AtpDatabase, AtpService, Did, Result, Tid,
- XrpcError,
-};
-use adenosine::identifiers::{AtUri, DidOrHost, Nsid};
+use crate::{AtpDatabase, AtpService, Result, XrpcError};
+use adenosine::app_bsky;
+use adenosine::identifiers::{AtUri, Did, DidOrHost, Nsid, Tid};
+use adenosine::ipld::{ipld_into_json_value, json_value_into_ipld};
use adenosine::repo::Mutation;
use anyhow::anyhow;
use libipld::Cid;
@@ -61,7 +59,7 @@ pub fn bsky_mutate_db(db: &mut AtpDatabase, did: &Did, mutations: Vec<Mutation>)
}
// TODO: should probably return Result<Option<Profile>>?
-pub fn bsky_get_profile(srv: &mut AtpService, did: &Did) -> Result<Profile> {
+pub fn bsky_get_profile(srv: &mut AtpService, did: &Did) -> Result<app_bsky::Profile> {
// first get the profile record
let mut profile_cid: Option<Cid> = None;
let commit_cid = match srv.repo.lookup_commit(did)? {
@@ -78,7 +76,7 @@ pub fn bsky_get_profile(srv: &mut AtpService, did: &Did) -> Result<Profile> {
}
let (display_name, description): (Option<String>, Option<String>) =
if let Some(cid) = profile_cid {
- let record: ProfileRecord =
+ let record: app_bsky::ProfileRecord =
serde_json::from_value(ipld_into_json_value(srv.repo.get_ipld(&cid)?))?;
(Some(record.displayName), record.description)
} else {
@@ -104,11 +102,11 @@ pub fn bsky_get_profile(srv: &mut AtpService, did: &Did) -> Result<Profile> {
.conn
.prepare_cached("SELECT COUNT(*) FROM bsky_follow WHERE subject_did = $1")?;
let followers_count: u64 = stmt.query_row(params!(did.to_string()), |row| row.get(0))?;
- let decl = DeclRef {
+ let decl = app_bsky::DeclRef {
actorType: "app.bsky.system.actorUser".to_string(),
cid: "bafyreid27zk7lbis4zw5fz4podbvbs4fc5ivwji3dmrwa6zggnj4bnd57u".to_string(),
};
- Ok(Profile {
+ Ok(app_bsky::Profile {
did: did.to_string(),
handle,
creator: did.to_string(),
@@ -123,7 +121,11 @@ pub fn bsky_get_profile(srv: &mut AtpService, did: &Did) -> Result<Profile> {
})
}
-pub fn bsky_update_profile(srv: &mut AtpService, did: &Did, profile: ProfileRecord) -> Result<()> {
+pub fn bsky_update_profile(
+ srv: &mut AtpService,
+ did: &Did,
+ profile: app_bsky::ProfileRecord,
+) -> Result<()> {
// get the profile record
let mut profile_tid: Option<Tid> = None;
let commit_cid = match srv.repo.lookup_commit(did)? {
@@ -175,7 +177,7 @@ fn feed_row(row: &rusqlite::Row) -> Result<FeedRow> {
})
}
-fn feed_row_to_item(srv: &mut AtpService, row: FeedRow) -> Result<FeedItem> {
+fn feed_row_to_item(srv: &mut AtpService, row: FeedRow) -> Result<app_bsky::FeedItem> {
let record_ipld = srv.repo.get_ipld(&row.item_post_cid)?;
let uri = format!(
"at://{}/{}/{}",
@@ -198,10 +200,10 @@ fn feed_row_to_item(srv: &mut AtpService, row: FeedRow) -> Result<FeedItem> {
.prepare_cached("SELECT COUNT(*) FROM bsky_post WHERE reply_to_parent_uri = $1")?;
let reply_count: u64 = stmt.query_row(params!(uri), |row| row.get(0))?;
- let feed_item = FeedItem {
+ let feed_item = app_bsky::FeedItem {
uri,
cid: row.item_post_cid.to_string(),
- author: User {
+ author: app_bsky::User {
did: row.item_did.to_string(),
handle: row.item_handle,
displayName: None, // TODO: fetch from profile (or cache)
@@ -219,8 +221,8 @@ fn feed_row_to_item(srv: &mut AtpService, row: FeedRow) -> Result<FeedItem> {
Ok(feed_item)
}
-pub fn bsky_get_timeline(srv: &mut AtpService, did: &Did) -> Result<GenericFeed> {
- let mut feed: Vec<FeedItem> = vec![];
+pub fn bsky_get_timeline(srv: &mut AtpService, did: &Did) -> Result<app_bsky::GenericFeed> {
+ let mut feed: Vec<app_bsky::FeedItem> = vec![];
// TODO: also handle reposts
let rows = {
let mut stmt = srv.atp_db
@@ -237,11 +239,11 @@ pub fn bsky_get_timeline(srv: &mut AtpService, did: &Did) -> Result<GenericFeed>
for row in rows {
feed.push(feed_row_to_item(srv, row)?);
}
- Ok(GenericFeed { feed })
+ Ok(app_bsky::GenericFeed { feed })
}
-pub fn bsky_get_author_feed(srv: &mut AtpService, did: &Did) -> Result<GenericFeed> {
- let mut feed: Vec<FeedItem> = vec![];
+pub fn bsky_get_author_feed(srv: &mut AtpService, did: &Did) -> Result<app_bsky::GenericFeed> {
+ let mut feed: Vec<app_bsky::FeedItem> = vec![];
// TODO: also handle reposts
let rows = {
let mut stmt = srv.atp_db
@@ -258,7 +260,7 @@ pub fn bsky_get_author_feed(srv: &mut AtpService, did: &Did) -> Result<GenericFe
for row in rows {
feed.push(feed_row_to_item(srv, row)?);
}
- Ok(GenericFeed { feed })
+ Ok(app_bsky::GenericFeed { feed })
}
// TODO: this is a partial implementation
@@ -267,7 +269,7 @@ pub fn bsky_get_thread(
srv: &mut AtpService,
uri: &AtUri,
_depth: Option<u64>,
-) -> Result<PostThread> {
+) -> Result<app_bsky::PostThread> {
// parse the URI
let did = match uri.repository {
DidOrHost::Did(ref did_type, ref did_body) => {
@@ -283,7 +285,7 @@ pub fn bsky_get_thread(
_ => Err(anyhow!("expected a record in uri: {}", uri))?,
};
- // post itself, as a FeedItem
+ // post itself, as a app_bsky::FeedItem
let post_items = {
let mut stmt = srv.atp_db
.conn
@@ -320,7 +322,7 @@ pub fn bsky_get_thread(
};
for row in rows {
let item = feed_row_to_item(srv, row)?;
- children.push(ThreadItem {
+ children.push(app_bsky::ThreadItem {
uri: item.uri,
cid: item.cid,
author: item.author,
@@ -339,7 +341,7 @@ pub fn bsky_get_thread(
});
}
- let post = ThreadItem {
+ let post = app_bsky::ThreadItem {
uri: post_item.uri,
cid: post_item.cid,
author: post_item.author,
@@ -354,19 +356,20 @@ pub fn bsky_get_thread(
indexedAt: post_item.indexedAt,
myState: None,
};
- Ok(PostThread { thread: post })
+ Ok(app_bsky::PostThread { thread: post })
}
#[test]
fn test_bsky_profile() {
use crate::{create_account, created_at_now};
+ use adenosine::com_atproto;
use libipld::ipld;
let post_nsid = Nsid::from_str("app.bsky.feed.post").unwrap();
let follow_nsid = Nsid::from_str("app.bsky.graph.follow").unwrap();
let mut srv = AtpService::new_ephemeral().unwrap();
- let req = AccountRequest {
+ let req = com_atproto::AccountRequest {
email: "test@bogus.com".to_string(),
handle: "handle.test".to_string(),
password: "bogus".to_string(),
@@ -384,7 +387,7 @@ fn test_bsky_profile() {
assert_eq!(profile.followsCount, 0);
assert_eq!(profile.postsCount, 0);
- let record = ProfileRecord {
+ let record = app_bsky::ProfileRecord {
displayName: "Test Name".to_string(),
description: Some("short description".to_string()),
};
@@ -393,7 +396,7 @@ fn test_bsky_profile() {
assert_eq!(profile.displayName, Some(record.displayName));
assert_eq!(profile.description, record.description);
- let record = ProfileRecord {
+ let record = app_bsky::ProfileRecord {
displayName: "New Test Name".to_string(),
description: Some("longer description".to_string()),
};
@@ -444,6 +447,7 @@ fn test_bsky_profile() {
fn test_bsky_feeds() {
// TODO: test that displayName comes through in feeds and timelines (it does not currently)
use crate::{create_account, created_at_now};
+ use adenosine::com_atproto;
use libipld::ipld;
let post_nsid = Nsid::from_str("app.bsky.feed.post").unwrap();
@@ -453,7 +457,7 @@ fn test_bsky_feeds() {
let mut srv = AtpService::new_ephemeral().unwrap();
let alice_did = {
- let req = AccountRequest {
+ let req = com_atproto::AccountRequest {
email: "alice@bogus.com".to_string(),
handle: "alice.test".to_string(),
password: "bogus".to_string(),
@@ -464,7 +468,7 @@ fn test_bsky_feeds() {
Did::from_str(&session.did).unwrap()
};
let bob_did = {
- let req = AccountRequest {
+ let req = com_atproto::AccountRequest {
email: "bob@bogus.com".to_string(),
handle: "bob.test".to_string(),
password: "bogus".to_string(),
@@ -475,7 +479,7 @@ fn test_bsky_feeds() {
Did::from_str(&session.did).unwrap()
};
let carol_did = {
- let req = AccountRequest {
+ let req = com_atproto::AccountRequest {
email: "carol@bogus.com".to_string(),
handle: "carol.test".to_string(),
password: "bogus".to_string(),
@@ -672,13 +676,14 @@ fn test_bsky_feeds() {
#[test]
fn test_bsky_thread() {
use crate::create_account;
+ use adenosine::com_atproto;
use libipld::ipld;
let post_nsid = Nsid::from_str("app.bsky.feed.post").unwrap();
let mut srv = AtpService::new_ephemeral().unwrap();
let alice_did = {
- let req = AccountRequest {
+ let req = com_atproto::AccountRequest {
email: "alice@bogus.com".to_string(),
handle: "alice.test".to_string(),
password: "bogus".to_string(),
@@ -689,7 +694,7 @@ fn test_bsky_thread() {
Did::from_str(&session.did).unwrap()
};
let bob_did = {
- let req = AccountRequest {
+ let req = com_atproto::AccountRequest {
email: "bob@bogus.com".to_string(),
handle: "bob.test".to_string(),
password: "bogus".to_string(),
diff --git a/adenosine-pds/src/lib.rs b/adenosine-pds/src/lib.rs
index 07905f9..cca9b0d 100644
--- a/adenosine-pds/src/lib.rs
+++ b/adenosine-pds/src/lib.rs
@@ -2,33 +2,51 @@ use adenosine::created_at_now;
use adenosine::identifiers::{AtUri, Did, Nsid, Ticker, Tid};
use anyhow::{anyhow, Result};
use askama::Template;
-use libipld::Cid;
-use libipld::Ipld;
use log::{debug, error, info, warn};
use rouille::{router, Request, Response};
use serde_json::{json, Value};
-use std::collections::BTreeMap;
use std::fmt;
use std::io::Read;
use std::path::PathBuf;
use std::str::FromStr;
use std::sync::Mutex;
-mod bsky;
mod db;
-pub mod models;
+mod db_bsky;
mod web;
-pub use adenosine::crypto::{KeyPair, PubKey};
-pub use adenosine::did;
-pub use adenosine::did::DidDocMeta;
-pub use adenosine::repo::{Mutation, RepoCommit, RepoStore};
-pub use adenosine::ucan_p256::P256KeyMaterial;
-use bsky::*;
-pub use db::AtpDatabase;
-pub use models::*;
+use adenosine::app_bsky;
+use adenosine::com_atproto;
+use adenosine::crypto::KeyPair;
+use adenosine::ipld::{ipld_into_json_value, json_value_into_ipld};
+use adenosine::plc;
+use adenosine::plc::DidDocMeta;
+use adenosine::repo::{Mutation, RepoStore};
+use db::AtpDatabase;
+use db_bsky::*;
use web::*;
+#[derive(Debug)]
+pub enum XrpcError {
+ BadRequest(String),
+ NotFound(String),
+ Forbidden(String),
+ MutexPoisoned,
+}
+
+impl std::error::Error for XrpcError {}
+
+impl fmt::Display for XrpcError {
+ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+ match self {
+ Self::BadRequest(msg) | Self::NotFound(msg) | Self::Forbidden(msg) => {
+ write!(f, "{}", msg)
+ }
+ Self::MutexPoisoned => write!(f, "service mutex poisoned"),
+ }
+ }
+}
+
pub struct AtpService {
pub repo: RepoStore,
pub atp_db: AtpDatabase,
@@ -58,27 +76,6 @@ impl Default for AtpServiceConfig {
}
}
-#[derive(Debug)]
-enum XrpcError {
- BadRequest(String),
- NotFound(String),
- Forbidden(String),
- MutexPoisoned,
-}
-
-impl std::error::Error for XrpcError {}
-
-impl fmt::Display for XrpcError {
- fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
- match self {
- Self::BadRequest(msg) | Self::NotFound(msg) | Self::Forbidden(msg) => {
- write!(f, "{}", msg)
- }
- Self::MutexPoisoned => write!(f, "service mutex poisoned"),
- }
- }
-}
-
/// Helper to take an XRPC result (always a JSON object), and transform it to a rouille response
fn xrpc_wrap<S: serde::Serialize>(resp: Result<S>) -> Response {
match resp {
@@ -256,49 +253,6 @@ impl AtpService {
}
}
-/// Intentionally serializing with this instead of DAG-JSON, because ATP schemas don't encode CID
-/// links in any special way, they just pass the CID as a string.
-fn ipld_into_json_value(val: Ipld) -> Value {
- match val {
- Ipld::Null => Value::Null,
- Ipld::Bool(b) => Value::Bool(b),
- Ipld::Integer(v) => json!(v),
- Ipld::Float(v) => json!(v),
- Ipld::String(s) => Value::String(s),
- Ipld::Bytes(b) => Value::String(data_encoding::BASE64_NOPAD.encode(&b)),
- Ipld::List(l) => Value::Array(l.into_iter().map(ipld_into_json_value).collect()),
- Ipld::Map(m) => Value::Object(serde_json::Map::from_iter(
- m.into_iter().map(|(k, v)| (k, ipld_into_json_value(v))),
- )),
- Ipld::Link(c) => Value::String(c.to_string()),
- }
-}
-
-/// Crude reverse generation
-///
-/// Does not handle base64 to bytes, and the link generation is pretty simple (object elements with
-/// key "car"). Numbers always come through as f64 (float).
-fn json_value_into_ipld(val: Value) -> Ipld {
- match val {
- Value::Null => Ipld::Null,
- Value::Bool(b) => Ipld::Bool(b),
- Value::String(s) => Ipld::String(s),
- // TODO: handle numbers better?
- Value::Number(v) => Ipld::Float(v.as_f64().unwrap()),
- Value::Array(l) => Ipld::List(l.into_iter().map(json_value_into_ipld).collect()),
- Value::Object(m) => {
- let map: BTreeMap<String, Ipld> = BTreeMap::from_iter(m.into_iter().map(|(k, v)| {
- if k == "car" && v.is_string() {
- (k, Ipld::Link(Cid::from_str(v.as_str().unwrap()).unwrap()))
- } else {
- (k, json_value_into_ipld(v))
- }
- }));
- Ipld::Map(map)
- }
- }
-}
-
fn xrpc_required_param(request: &Request, key: &str) -> Result<String> {
Ok(request.get_param(key).ok_or(XrpcError::BadRequest(format!(
"require '{}' query parameter",
@@ -424,7 +378,7 @@ fn xrpc_get_handler(
let mut srv = srv.lock().or(Err(XrpcError::MutexPoisoned))?;
let did_doc = srv.atp_db.get_did_doc(&did)?;
let collections: Vec<String> = srv.repo.collections(&did)?;
- let desc = RepoDescribe {
+ let desc = com_atproto::repo::Describe {
name: did.to_string(), // TODO: handle?
did: did.to_string(),
didDoc: did_doc,
@@ -506,9 +460,9 @@ fn xrpc_get_repo_handler(srv: &Mutex<AtpService>, request: &Request) -> Result<V
pub fn create_account(
srv: &mut AtpService,
- req: &AccountRequest,
+ req: &com_atproto::AccountRequest,
create_did_plc: bool,
-) -> Result<AtpSession> {
+) -> Result<com_atproto::Session> {
// check if account already exists (fast path, also confirmed by database schema)
if srv.atp_db.account_exists(&req.handle, &req.email)? {
Err(XrpcError::BadRequest(
@@ -520,7 +474,7 @@ pub fn create_account(
let (did, did_doc) = if create_did_plc {
// generate DID
- let create_op = did::CreateOp::new(
+ let create_op = plc::CreateOp::new(
req.handle.clone(),
srv.config.public_url.clone(),
&srv.pds_keypair,
@@ -576,7 +530,7 @@ fn xrpc_post_handler(
match method {
"com.atproto.account.create" => {
// validate account request
- let req: AccountRequest = rouille::input::json_input(request)
+ let req: com_atproto::AccountRequest = rouille::input::json_input(request)
.map_err(|e| XrpcError::BadRequest(format!("failed to parse JSON body: {}", e)))?;
// TODO: validate handle, email, recoverykey
let mut srv = srv.lock().unwrap();
@@ -602,7 +556,7 @@ fn xrpc_post_handler(
Ok(json!(sess))
}
"com.atproto.session.create" => {
- let req: SessionRequest = rouille::input::json_input(request)
+ let req: com_atproto::SessionRequest = rouille::input::json_input(request)
.map_err(|e| XrpcError::BadRequest(format!("failed to parse JSON body: {}", e)))?;
let mut srv = srv.lock().unwrap();
let keypair = srv.pds_keypair.clone();
@@ -628,7 +582,7 @@ fn xrpc_post_handler(
.resolve_did(&did)?
.expect("DID matches to a handle");
- Ok(json!(AtpSession {
+ Ok(json!(com_atproto::Session {
did: did.to_string(),
name: handle,
accessJwt: jwt.to_string(),
@@ -653,7 +607,7 @@ fn xrpc_post_handler(
Ok(json!({}))
}
"com.atproto.repo.batchWrite" => {
- let batch: RepoBatchWriteBody = rouille::input::json_input(request)?;
+ let batch: com_atproto::repo::BatchWriteBody = rouille::input::json_input(request)?;
// TODO: validate edits against schemas
let did = Did::from_str(&batch.did)?;
let mut srv = srv.lock().unwrap();
@@ -690,7 +644,7 @@ fn xrpc_post_handler(
}
"com.atproto.repo.createRecord" => {
// TODO: validate edits against schemas
- let create: RepoCreateRecord = rouille::input::json_input(request)?;
+ let create: com_atproto::repo::CreateRecord = rouille::input::json_input(request)?;
let did = Did::from_str(&create.did)?;
let collection = Nsid::from_str(&create.collection)?;
let mut srv = srv.lock().unwrap();
@@ -707,7 +661,7 @@ fn xrpc_post_handler(
}
"com.atproto.repo.putRecord" => {
// TODO: validate edits against schemas
- let put: RepoPutRecord = rouille::input::json_input(request)?;
+ let put: com_atproto::repo::PutRecord = rouille::input::json_input(request)?;
let did = Did::from_str(&put.did)?;
let collection = Nsid::from_str(&put.collection)?;
let tid = Tid::from_str(&put.rkey)?;
@@ -725,7 +679,7 @@ fn xrpc_post_handler(
Ok(json!({}))
}
"com.atproto.repo.deleteRecord" => {
- let delete: RepoDeleteRecord = rouille::input::json_input(request)?;
+ let delete: com_atproto::repo::DeleteRecord = rouille::input::json_input(request)?;
let did = Did::from_str(&delete.did)?;
let collection = Nsid::from_str(&delete.collection)?;
let tid = Tid::from_str(&delete.rkey)?;
@@ -754,7 +708,7 @@ fn xrpc_post_handler(
}
// =========== app.bsky methods
"app.bsky.actor.updateProfile" => {
- let profile: ProfileRecord = rouille::input::json_input(request)?;
+ let profile: app_bsky::ProfileRecord = rouille::input::json_input(request)?;
let mut srv = srv.lock().unwrap();
let auth_did = &xrpc_check_auth_header(&mut srv, request, None)?;
bsky_update_profile(&mut srv, auth_did, profile)?;
@@ -865,7 +819,7 @@ fn repo_view_handler(srv: &Mutex<AtpService>, did: &str, request: &Request) -> R
let commit_cid = &srv.repo.lookup_commit(&did)?.unwrap();
let commit = srv.repo.get_commit(commit_cid)?;
let collections: Vec<String> = srv.repo.collections(&did)?;
- let desc = RepoDescribe {
+ let desc = com_atproto::repo::Describe {
name: did.to_string(), // TODO
did: did.to_string(),
didDoc: did_doc,
diff --git a/adenosine-pds/src/models.rs b/adenosine-pds/src/models.rs
deleted file mode 100644
index f827a7a..0000000
--- a/adenosine-pds/src/models.rs
+++ /dev/null
@@ -1,246 +0,0 @@
-use serde_json::Value;
-
-// =========== com.atproto types (manually entered)
-
-#[allow(non_snake_case)]
-#[derive(Debug, serde::Deserialize, serde::Serialize, PartialEq, Eq)]
-pub struct AccountRequest {
- pub email: String,
- pub handle: String,
- pub password: String,
- pub inviteCode: Option<String>,
- pub recoveryKey: Option<String>,
-}
-
-#[allow(non_snake_case)]
-#[derive(Debug, serde::Deserialize, serde::Serialize, PartialEq, Eq)]
-pub struct SessionRequest {
- pub handle: String,
- pub password: String,
-}
-
-#[allow(non_snake_case)]
-#[derive(Debug, serde::Serialize, serde::Deserialize, Clone, PartialEq, Eq)]
-pub struct AtpSession {
- pub did: String,
- pub name: String,
- pub accessJwt: String,
- pub refreshJwt: String,
-}
-
-#[allow(non_snake_case)]
-#[derive(Debug, serde::Serialize, serde::Deserialize, Clone, PartialEq, Eq)]
-pub struct RepoDescribe {
- pub name: String,
- pub did: String,
- pub didDoc: serde_json::Value,
- pub collections: Vec<String>,
- pub nameIsCorrect: bool,
-}
-
-#[allow(non_snake_case)]
-#[derive(Debug, serde::Serialize, serde::Deserialize, Clone, PartialEq, Eq)]
-pub struct RepoCreateRecord {
- pub did: String,
- pub collection: String,
- pub record: serde_json::Value,
-}
-
-#[allow(non_snake_case)]
-#[derive(Debug, serde::Serialize, serde::Deserialize, Clone, PartialEq, Eq)]
-pub struct RepoPutRecord {
- pub did: String,
- pub collection: String,
- pub rkey: String,
- pub record: serde_json::Value,
-}
-
-#[allow(non_snake_case)]
-#[derive(Debug, serde::Serialize, serde::Deserialize, Clone, PartialEq, Eq)]
-pub struct RepoDeleteRecord {
- pub did: String,
- pub collection: String,
- pub rkey: String,
-}
-
-#[allow(non_snake_case)]
-#[derive(Debug, serde::Serialize, serde::Deserialize, Clone, PartialEq, Eq)]
-pub struct RepoBatchWriteBody {
- pub did: String,
- pub writes: Vec<RepoBatchWrite>,
-}
-
-#[allow(non_snake_case)]
-#[derive(Debug, serde::Serialize, serde::Deserialize, Clone, PartialEq, Eq)]
-pub struct RepoBatchWrite {
- #[serde(rename = "type")]
- pub op_type: String,
- pub collection: String,
- pub rkey: Option<String>,
- pub value: serde_json::Value,
-}
-
-// =========== app.bsky types (manually entered)
-
-#[derive(Debug, serde::Serialize, serde::Deserialize, Clone, PartialEq, Eq)]
-pub struct Subject {
- pub uri: String,
- // TODO: CID is required
- pub cid: Option<String>,
-}
-
-/// Generic over Re-post and Like
-#[allow(non_snake_case)]
-#[derive(Debug, serde::Serialize, serde::Deserialize, Clone, PartialEq, Eq)]
-pub struct RefRecord {
- pub subject: Subject,
- pub createdAt: String,
-}
-
-#[allow(non_snake_case)]
-#[derive(Debug, serde::Serialize, serde::Deserialize, Clone, PartialEq, Eq)]
-pub struct FollowSubject {
- pub did: String,
- // pub declarationCid: String,
-}
-
-#[allow(non_snake_case)]
-#[derive(Debug, serde::Serialize, serde::Deserialize, Clone, PartialEq, Eq)]
-pub struct FollowRecord {
- pub subject: FollowSubject,
- pub createdAt: String,
-}
-
-#[allow(non_snake_case)]
-#[derive(Debug, serde::Serialize, serde::Deserialize, Clone, PartialEq, Eq)]
-pub struct ProfileRecord {
- pub displayName: String,
- pub description: Option<String>,
-}
-
-// app.bsky.system.actorUser or app.bsky.system.actorScene
-#[allow(non_snake_case)]
-#[derive(Debug, serde::Serialize, serde::Deserialize, Clone, PartialEq, Eq)]
-pub struct Declaration {
- pub actorType: String,
-}
-
-// actorType: app.bsky.system.actorUser
-// cid: bafyreid27zk7lbis4zw5fz4podbvbs4fc5ivwji3dmrwa6zggnj4bnd57u
-#[allow(non_snake_case)]
-#[derive(Debug, serde::Serialize, serde::Deserialize, Clone, PartialEq, Eq)]
-pub struct DeclRef {
- pub actorType: String,
- pub cid: String,
-}
-
-#[allow(non_snake_case)]
-#[derive(Debug, serde::Serialize, serde::Deserialize, Clone, PartialEq, Eq)]
-pub struct Profile {
- pub did: String,
- pub declaration: DeclRef,
- pub handle: String,
- // for simple accounts, 'creator' is just the did
- pub creator: String,
- pub displayName: Option<String>,
- pub description: Option<String>,
- pub followersCount: u64,
- pub followsCount: u64,
- pub membersCount: u64,
- pub postsCount: u64,
- pub myState: serde_json::Value,
-}
-
-#[allow(non_snake_case)]
-#[derive(Debug, serde::Serialize, serde::Deserialize, Clone, PartialEq, Eq)]
-pub struct GenericFeed {
- pub feed: Vec<FeedItem>,
-}
-
-#[allow(non_snake_case)]
-#[derive(Debug, serde::Serialize, serde::Deserialize, Clone, PartialEq, Eq)]
-pub struct User {
- pub did: String,
- pub handle: String,
- pub displayName: Option<String>,
-}
-
-#[allow(non_snake_case)]
-#[derive(Debug, serde::Serialize, serde::Deserialize, Clone, PartialEq, Eq)]
-pub struct FeedItem {
- pub uri: String,
- pub cid: String,
- pub author: User,
- pub repostedBy: Option<User>,
- pub record: Value,
- //pub embed?: RecordEmbed | ExternalEmbed | UnknownEmbed,
- pub embed: Option<Value>,
- pub replyCount: u64,
- pub repostCount: u64,
- pub upvoteCount: u64,
- pub downvoteCount: u64,
- pub indexedAt: String,
- pub myState: Option<Value>,
-}
-
-#[allow(non_snake_case)]
-#[derive(Debug, serde::Serialize, serde::Deserialize, Clone, PartialEq, Eq)]
-pub struct Post {
- pub text: String,
- pub reply: Option<PostReply>,
- pub createdAt: Option<String>,
-}
-
-#[allow(non_snake_case)]
-#[derive(Debug, serde::Serialize, serde::Deserialize, Clone, PartialEq, Eq)]
-pub struct PostReply {
- pub parent: Subject,
- pub root: Subject,
-}
-
-#[allow(non_snake_case)]
-#[derive(Debug, serde::Serialize, serde::Deserialize, Clone, PartialEq, Eq)]
-pub struct PostThread {
- pub thread: ThreadItem,
-}
-
-// TODO: 'parent' and 'replies' should allow "NotFoundPost" for references that point to an unknown
-// URI
-#[allow(non_snake_case)]
-#[derive(Debug, serde::Serialize, serde::Deserialize, Clone, PartialEq, Eq)]
-pub struct ThreadItem {
- pub uri: String,
- pub cid: String,
- pub author: User,
- pub record: Value,
- //pub embed?: RecordEmbed | ExternalEmbed | UnknownEmbed,
- pub embed: Option<Value>,
- pub parent: Option<Box<ThreadItem>>,
- pub replyCount: u64,
- pub replies: Option<Vec<ThreadItem>>,
- pub repostCount: u64,
- pub upvoteCount: u64,
- pub downvoteCount: u64,
- pub indexedAt: String,
- pub myState: Option<Value>,
-}
-
-#[allow(non_snake_case)]
-#[derive(Debug, serde::Serialize, serde::Deserialize, Clone, PartialEq, Eq)]
-pub struct FollowTarget {
- // TODO: nested follow list?
- pub subject: Subject,
- pub did: String,
- pub handle: String,
- pub displayName: Option<String>,
- pub createdAt: Option<String>,
- pub indexedAt: String,
-}
-
-#[allow(non_snake_case)]
-#[derive(Debug, serde::Serialize, serde::Deserialize, Clone, PartialEq, Eq)]
-pub struct Follow {
- // TODO: nested follow list?
- pub subject: Subject,
- pub follows: FollowTarget,
-}
diff --git a/adenosine-pds/src/web.rs b/adenosine-pds/src/web.rs
index 0d80b4e..8f15a49 100644
--- a/adenosine-pds/src/web.rs
+++ b/adenosine-pds/src/web.rs
@@ -1,4 +1,5 @@
-use crate::models::*;
+use adenosine::app_bsky;
+use adenosine::com_atproto;
use adenosine::identifiers::{Did, Nsid, Tid};
use adenosine::repo::RepoCommit;
use askama::Template;
@@ -28,8 +29,8 @@ pub struct AboutView {
pub struct AccountView {
pub domain: String,
pub did: Did,
- pub profile: Profile,
- pub feed: Vec<FeedItem>,
+ pub profile: app_bsky::Profile,
+ pub feed: Vec<app_bsky::FeedItem>,
}
#[derive(Template)]
@@ -39,7 +40,7 @@ pub struct ThreadView {
pub did: Did,
pub collection: Nsid,
pub tid: Tid,
- pub post: ThreadItem,
+ pub post: app_bsky::ThreadItem,
}
#[derive(Template)]
@@ -48,7 +49,7 @@ pub struct RepoView {
pub domain: String,
pub did: Did,
pub commit: RepoCommit,
- pub describe: RepoDescribe,
+ pub describe: com_atproto::repo::Describe,
}
#[derive(Template)]