From 23416af782a179a658711e958e977e19ae97067b Mon Sep 17 00:00:00 2001 From: bryan newbold Date: Sun, 20 Aug 2023 19:56:22 -0700 Subject: many updates from spring 2023 lex refactor --- adenosine-pds/src/bin/adenosine-pds.rs | 1 + adenosine-pds/src/db.rs | 3 +- adenosine-pds/src/db_bsky.rs | 117 ++++++++++++++++++++------------- adenosine-pds/src/lib.rs | 56 +++++++--------- adenosine-pds/src/web.rs | 6 +- 5 files changed, 101 insertions(+), 82 deletions(-) (limited to 'adenosine-pds/src') diff --git a/adenosine-pds/src/bin/adenosine-pds.rs b/adenosine-pds/src/bin/adenosine-pds.rs index e92c131..5e8842c 100644 --- a/adenosine-pds/src/bin/adenosine-pds.rs +++ b/adenosine-pds/src/bin/adenosine-pds.rs @@ -211,6 +211,7 @@ fn main() -> Result<()> { did_plc, } => { let req = com_atproto::AccountRequest { + did: None, email, handle: handle.clone(), password, diff --git a/adenosine-pds/src/db.rs b/adenosine-pds/src/db.rs index 4cbece6..2dac721 100644 --- a/adenosine-pds/src/db.rs +++ b/adenosine-pds/src/db.rs @@ -124,6 +124,7 @@ impl AtpDatabase { Ok(com_atproto::Session { did: did.to_string(), name: handle.to_string(), + email: None, accessJwt: jwt.to_string(), refreshJwt: jwt, }) @@ -193,7 +194,7 @@ impl AtpDatabase { // need to re-compute the CID from DagCbor re-encoding, I guess. bleh. let block = Block::::encode(DagCborCodec, Code::Sha2_256, &val)?; let cid = *block.cid(); - let post: app_bsky::Post = serde_json::from_value(ipld_into_json_value(val))?; + let post: app_bsky::PostRecord = 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), diff --git a/adenosine-pds/src/db_bsky.rs b/adenosine-pds/src/db_bsky.rs index b80ff4f..c603235 100644 --- a/adenosine-pds/src/db_bsky.rs +++ b/adenosine-pds/src/db_bsky.rs @@ -8,7 +8,6 @@ use adenosine::repo::Mutation; use anyhow::anyhow; use libipld::Cid; use rusqlite::params; -use serde_json::json; use std::str::FromStr; /// Handles updating the database with creation, update, deletion of arbitrary records @@ -59,7 +58,10 @@ pub fn bsky_mutate_db(db: &mut AtpDatabase, did: &Did, mutations: Vec) } // TODO: should probably return Result>? -pub fn bsky_get_profile(srv: &mut AtpService, did: &Did) -> Result { +pub fn bsky_get_profile_detailed( + srv: &mut AtpService, + did: &Did, +) -> Result { // first get the profile record let mut profile_cid: Option = None; let commit_cid = match srv.repo.lookup_commit(did)? { @@ -78,7 +80,7 @@ pub fn bsky_get_profile(srv: &mut AtpService, did: &Did) -> Result Result Result { + let d = bsky_get_profile_detailed(srv, did)?; + Ok(app_bsky::ProfileView { + did: d.did, + handle: d.handle, + displayName: d.displayName, + description: d.description, + avatar: d.avatar, + indexedAt: d.indexedAt, + viewer: d.viewer, + labels: d.labels, }) } @@ -177,9 +190,10 @@ fn feed_row(row: &rusqlite::Row) -> Result { }) } -fn feed_row_to_item(srv: &mut AtpService, row: FeedRow) -> Result { +fn feed_row_to_item(srv: &mut AtpService, row: FeedRow) -> Result { let record_ipld = srv.repo.get_ipld(&row.item_post_cid)?; - let post_record: app_bsky::Post = serde_json::from_value(ipld_into_json_value(record_ipld))?; + let post_record: app_bsky::PostRecord = + serde_json::from_value(ipld_into_json_value(record_ipld))?; let uri = format!( "at://{}/{}/{}", row.item_did, "app.bsky.feed.post", row.item_post_tid @@ -201,31 +215,27 @@ fn feed_row_to_item(srv: &mut AtpService, row: FeedRow) -> Result Result Result { - let mut feed: Vec = vec![]; + let mut feed: Vec = vec![]; // TODO: also handle reposts let rows = { let mut stmt = srv.atp_db @@ -252,11 +262,11 @@ pub fn bsky_get_timeline(srv: &mut AtpService, did: &Did) -> Result Result { - let mut feed: Vec = vec![]; + let mut feed: Vec = vec![]; // TODO: also handle reposts let rows = { let mut stmt = srv.atp_db @@ -273,7 +283,7 @@ pub fn bsky_get_author_feed(srv: &mut AtpService, did: &Did) -> Result Err(anyhow!("expected a record in uri: {}", uri))?, }; - // post itself, as a app_bsky::FeedPostView + // post itself, as a app_bsky::FeedViewPost let post_items = { let mut stmt = srv.atp_db .conn @@ -335,7 +345,7 @@ pub fn bsky_get_thread( }; for row in rows { let item = feed_row_to_item(srv, row)?.post; - children.push(app_bsky::ThreadPostView { + children.push(app_bsky::ThreadViewPost { post: Some(app_bsky::PostView { uri: item.uri, cid: item.cid, @@ -343,11 +353,11 @@ pub fn bsky_get_thread( record: item.record, embed: item.embed, replyCount: item.replyCount, - upvoteCount: item.upvoteCount, - downvoteCount: 0, + likeCount: item.likeCount, repostCount: item.repostCount, indexedAt: item.indexedAt, viewer: None, + labels: None, }), // don't want a loop here parent: None, @@ -356,11 +366,14 @@ pub fn bsky_get_thread( // for "notfound" uri: None, notFound: None, + // for "blocked" variant + blocked: None, + author: None, }); } let pip = post_item.post; - let post = app_bsky::ThreadPostView { + let post = app_bsky::ThreadViewPost { post: Some(app_bsky::PostView { uri: pip.uri, cid: pip.cid, @@ -368,17 +381,20 @@ pub fn bsky_get_thread( record: pip.record, embed: pip.embed, replyCount: pip.replyCount, - upvoteCount: pip.upvoteCount, - downvoteCount: 0, + likeCount: pip.likeCount, repostCount: pip.repostCount, indexedAt: pip.indexedAt, viewer: None, + labels: None, }), parent, replies: Some(children), // for "notfound" variant uri: None, notFound: None, + // for "blocked" variant + blocked: None, + author: None, }; Ok(app_bsky::PostThread { thread: post }) } @@ -394,6 +410,7 @@ fn test_bsky_profile() { let mut srv = AtpService::new_ephemeral().unwrap(); let req = com_atproto::AccountRequest { + did: None, email: "test@bogus.com".to_string(), handle: "handle.test".to_string(), password: "bogus".to_string(), @@ -402,7 +419,7 @@ fn test_bsky_profile() { }; let session = create_account(&mut srv, &req, true).unwrap(); let did = Did::from_str(&session.did).unwrap(); - let profile = bsky_get_profile(&mut srv, &did).unwrap(); + let profile = bsky_get_profile_detailed(&mut srv, &did).unwrap(); assert_eq!(profile.did, session.did); assert_eq!(profile.handle, req.handle); assert_eq!(profile.displayName, None); @@ -412,21 +429,25 @@ fn test_bsky_profile() { assert_eq!(profile.postsCount, 0); let record = app_bsky::ProfileRecord { - displayName: "Test Name".to_string(), + displayName: Some("Test Name".to_string()), description: Some("short description".to_string()), + avatar: None, + banner: None, }; bsky_update_profile(&mut srv, &did, record.clone()).unwrap(); let profile = bsky_get_profile(&mut srv, &did).unwrap(); - assert_eq!(profile.displayName, Some(record.displayName)); + assert_eq!(profile.displayName, record.displayName); assert_eq!(profile.description, record.description); let record = app_bsky::ProfileRecord { - displayName: "New Test Name".to_string(), + displayName: Some("New Test Name".to_string()), description: Some("longer description".to_string()), + avatar: None, + banner: None, }; bsky_update_profile(&mut srv, &did, record.clone()).unwrap(); let profile = bsky_get_profile(&mut srv, &did).unwrap(); - assert_eq!(profile.displayName, Some(record.displayName)); + assert_eq!(profile.displayName, record.displayName); assert_eq!(profile.description, record.description); let mutations = vec![ @@ -461,7 +482,7 @@ fn test_bsky_profile() { .unwrap(); bsky_mutate_db(&mut srv.atp_db, &did, mutations).unwrap(); - let profile = bsky_get_profile(&mut srv, &did).unwrap(); + let profile = bsky_get_profile_detailed(&mut srv, &did).unwrap(); assert_eq!(profile.followersCount, 1); assert_eq!(profile.followsCount, 2); assert_eq!(profile.postsCount, 3); @@ -482,6 +503,7 @@ fn test_bsky_feeds() { let mut srv = AtpService::new_ephemeral().unwrap(); let alice_did = { let req = com_atproto::AccountRequest { + did: None, email: "alice@bogus.com".to_string(), handle: "alice.test".to_string(), password: "bogus".to_string(), @@ -493,6 +515,7 @@ fn test_bsky_feeds() { }; let bob_did = { let req = com_atproto::AccountRequest { + did: None, email: "bob@bogus.com".to_string(), handle: "bob.test".to_string(), password: "bogus".to_string(), @@ -504,6 +527,7 @@ fn test_bsky_feeds() { }; let carol_did = { let req = com_atproto::AccountRequest { + did: None, email: "carol@bogus.com".to_string(), handle: "carol.test".to_string(), password: "bogus".to_string(), @@ -596,7 +620,7 @@ fn test_bsky_feeds() { bsky_mutate_db(&mut srv.atp_db, &carol_did, mutations).unwrap(); // test alice profile: counts should be updated - let alice_profile = bsky_get_profile(&mut srv, &alice_did).unwrap(); + let alice_profile = bsky_get_profile_detailed(&mut srv, &alice_did).unwrap(); assert_eq!(alice_profile.followersCount, 1); assert_eq!(alice_profile.followsCount, 0); assert_eq!(alice_profile.postsCount, 3); @@ -621,18 +645,17 @@ fn test_bsky_feeds() { assert_eq!(alice_feed.feed[2].post.embed, None); assert_eq!(alice_feed.feed[2].post.replyCount, 0); assert_eq!(alice_feed.feed[2].post.repostCount, 0); - assert_eq!(alice_feed.feed[2].post.upvoteCount, 1); - assert_eq!(alice_feed.feed[2].post.downvoteCount, 0); + assert_eq!(alice_feed.feed[2].post.likeCount, 1); assert_eq!(alice_feed.feed[1].post.author.did, alice_did.to_string()); assert_eq!(alice_feed.feed[1].post.replyCount, 0); assert_eq!(alice_feed.feed[1].post.repostCount, 1); - assert_eq!(alice_feed.feed[1].post.upvoteCount, 0); + assert_eq!(alice_feed.feed[1].post.likeCount, 0); assert_eq!(alice_feed.feed[0].post.author.did, alice_did.to_string()); assert_eq!(alice_feed.feed[0].post.replyCount, 1); assert_eq!(alice_feed.feed[0].post.repostCount, 0); - assert_eq!(alice_feed.feed[0].post.upvoteCount, 0); + assert_eq!(alice_feed.feed[0].post.likeCount, 0); // test bob timeline: should include alice posts let bob_timeline = bsky_get_timeline(&mut srv, &bob_did).unwrap(); @@ -687,6 +710,7 @@ fn test_bsky_thread() { let mut srv = AtpService::new_ephemeral().unwrap(); let alice_did = { let req = com_atproto::AccountRequest { + did: None, email: "alice@bogus.com".to_string(), handle: "alice.test".to_string(), password: "bogus".to_string(), @@ -698,6 +722,7 @@ fn test_bsky_thread() { }; let bob_did = { let req = com_atproto::AccountRequest { + did: None, email: "bob@bogus.com".to_string(), handle: "bob.test".to_string(), password: "bogus".to_string(), @@ -758,7 +783,7 @@ fn test_bsky_thread() { assert_eq!(ppost.embed, None); assert_eq!(ppost.replyCount, 1); assert_eq!(ppost.repostCount, 0); - assert_eq!(ppost.upvoteCount, 0); + assert_eq!(ppost.likeCount, 0); assert_eq!(post.replies.as_ref().unwrap().len(), 1); let post_replies = post.replies.unwrap(); diff --git a/adenosine-pds/src/lib.rs b/adenosine-pds/src/lib.rs index c267135..cb41cb9 100644 --- a/adenosine-pds/src/lib.rs +++ b/adenosine-pds/src/lib.rs @@ -303,7 +303,7 @@ fn xrpc_get_handler( ) } "com.atproto.repo.getRecord" => { - let did = Did::from_str(&xrpc_required_param(request, "user")?)?; + let did = Did::from_str(&xrpc_required_param(request, "repo")?)?; let collection = Nsid::from_str(&xrpc_required_param(request, "collection")?)?; let rkey = Tid::from_str(&xrpc_required_param(request, "rkey")?)?; let mut srv = srv.lock().or(Err(XrpcError::MutexPoisoned))?; @@ -317,8 +317,8 @@ fn xrpc_get_handler( Err(e) => Err(e), } } - "com.atproto.sync.getRoot" => { - let did = Did::from_str(&xrpc_required_param(request, "did")?)?; + "com.atproto.sync.getHead" => { + let did = Did::from_str(&xrpc_required_param(request, "repo")?)?; let mut srv = srv.lock().or(Err(XrpcError::MutexPoisoned))?; srv.repo .lookup_commit(&did)? @@ -329,7 +329,7 @@ fn xrpc_get_handler( // TODO: limit, before, after, tid, reverse // TODO: handle non-DID 'user' // TODO: limit result set size - let did = Did::from_str(&xrpc_required_param(request, "user")?)?; + let did = Did::from_str(&xrpc_required_param(request, "repo")?)?; let collection = Nsid::from_str(&xrpc_required_param(request, "collection")?)?; let mut record_list: Vec = vec![]; let mut srv = srv.lock().or(Err(XrpcError::MutexPoisoned))?; @@ -350,15 +350,6 @@ fn xrpc_get_handler( } Ok(json!({ "records": record_list })) } - "com.atproto.session.get" => { - let mut srv = srv.lock().or(Err(XrpcError::MutexPoisoned))?; - let auth_did = &xrpc_check_auth_header(&mut srv, request, None)?; - let handle = srv - .atp_db - .resolve_did(auth_did)? - .expect("registered account has handle"); - Ok(json!({"did": auth_did.to_string(), "handle": handle})) - } "com.atproto.handle.resolve" => { let handle = xrpc_required_param(request, "handle")?; let mut srv = srv.lock().or(Err(XrpcError::MutexPoisoned))?; @@ -370,17 +361,17 @@ fn xrpc_get_handler( } } "com.atproto.repo.describe" => { - let did = Did::from_str(&xrpc_required_param(request, "user")?)?; + let did = Did::from_str(&xrpc_required_param(request, "repo")?)?; let mut srv = srv.lock().or(Err(XrpcError::MutexPoisoned))?; let did_doc = srv.atp_db.get_did_doc(&did)?; let collections: Vec = srv.repo.collections(&did)?; let desc = com_atproto::repo::Describe { - name: did.to_string(), // TODO: handle? + handle: did.to_string(), // TODO: handle? did: did.to_string(), didDoc: did_doc, collections, - nameIsCorrect: true, + handleIsCorrect: true, }; Ok(json!(desc)) } @@ -408,7 +399,7 @@ fn xrpc_get_handler( } "app.bsky.feed.getAuthorFeed" => { // TODO did or handle - let did = Did::from_str(&xrpc_required_param(request, "author")?)?; + let did = Did::from_str(&xrpc_required_param(request, "actor")?)?; let mut srv = srv.lock().unwrap(); Ok(json!(bsky_get_author_feed(&mut srv, &did)?)) } @@ -434,7 +425,7 @@ fn xrpc_get_handler( let _auth_did = &xrpc_check_auth_header(&mut srv, request, None)?; Ok(json!({"count": 0})) } - "app.bsky.notification.list" => { + "app.bsky.notification.listNotifications" => { // TODO: actual implementation let mut srv = srv.lock().or(Err(XrpcError::MutexPoisoned))?; let _auth_did = &xrpc_check_auth_header(&mut srv, request, None)?; @@ -447,7 +438,7 @@ fn xrpc_get_handler( } fn xrpc_get_repo_handler(srv: &Mutex, request: &Request) -> Result> { - let did = Did::from_str(&xrpc_required_param(request, "did")?)?; + let did = Did::from_str(&xrpc_required_param(request, "repo")?)?; let mut srv = srv.lock().or(Err(XrpcError::MutexPoisoned))?; // TODO: don't unwrap here let commit_cid = srv.repo.lookup_commit(&did)?.unwrap(); @@ -520,7 +511,7 @@ fn xrpc_post_handler( request: &Request, ) -> Result { match method { - "com.atproto.account.create" => { + "com.atproto.server.createAccount" => { // validate account request let req: com_atproto::AccountRequest = rouille::input::json_input(request) .map_err(|e| XrpcError::BadRequest(format!("failed to parse JSON body: {e}")))?; @@ -546,18 +537,18 @@ fn xrpc_post_handler( let sess = create_account(&mut srv, &req, true)?; Ok(json!(sess)) } - "com.atproto.session.create" => { + "com.atproto.server.createSession" => { 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(); Ok(json!(srv.atp_db.create_session( - &req.handle, + &req.identifier, &req.password, &keypair )?)) } - "com.atproto.session.refresh" => { + "com.atproto.server.refreshSession" => { // actually just returns current session, because we don't implement refresh let mut srv = srv.lock().unwrap(); let did = xrpc_check_auth_header(&mut srv, request, None)?; @@ -576,11 +567,12 @@ fn xrpc_post_handler( Ok(json!(com_atproto::Session { did: did.to_string(), name: handle, + email: None, accessJwt: jwt.to_string(), refreshJwt: jwt.to_string(), })) } - "com.atproto.session.delete" => { + "com.atproto.server.deleteSession" => { let mut srv = srv.lock().unwrap(); let _did = xrpc_check_auth_header(&mut srv, request, None)?; let header = request @@ -597,10 +589,10 @@ fn xrpc_post_handler( }; Ok(json!({})) } - "com.atproto.repo.batchWrite" => { + "com.atproto.repo.applyWrites" => { let batch: com_atproto::repo::BatchWriteBody = rouille::input::json_input(request)?; // TODO: validate edits against schemas - let did = Did::from_str(&batch.did)?; + let did = Did::from_str(&batch.repo)?; let mut srv = srv.lock().unwrap(); let _auth_did = &xrpc_check_auth_header(&mut srv, request, Some(&did))?; let mut mutations: Vec = Default::default(); @@ -613,12 +605,12 @@ fn xrpc_post_handler( .as_ref() .map(|t| Tid::from_str(t).unwrap()) .unwrap_or_else(|| srv.tid_gen.next_tid()), - json_value_into_ipld(w.value.clone()), + json_value_into_ipld(w.value.clone().unwrap()), ), "update" => Mutation::Update( Nsid::from_str(&w.collection)?, Tid::from_str(w.rkey.as_ref().unwrap())?, - json_value_into_ipld(w.value.clone()), + json_value_into_ipld(w.value.clone().unwrap()), ), "delete" => Mutation::Delete( Nsid::from_str(&w.collection)?, @@ -685,7 +677,7 @@ fn xrpc_post_handler( } "com.atproto.sync.updateRepo" => { // TODO: all other XRPC POST methods removed params (eg, 'did' in this case) - let did = Did::from_str(&xrpc_required_param(request, "did")?)?; + let did = Did::from_str(&xrpc_required_param(request, "repo")?)?; // important that this read is before we take the mutex, because it could be slow! let mut car_bytes: Vec = Default::default(); // TODO: unwrap() @@ -769,7 +761,7 @@ fn account_view_handler( Ok(AccountView { domain: host.to_string(), did: did.clone(), - profile: bsky_get_profile(&mut srv, &did)?, + profile: bsky_get_profile_detailed(&mut srv, &did)?, feed: bsky_get_author_feed(&mut srv, &did)?.feed, } .render()?) @@ -809,11 +801,11 @@ fn repo_view_handler(srv: &Mutex, did: &str, request: &Request) -> R let commit = srv.repo.get_commit(commit_cid)?; let collections: Vec = srv.repo.collections(&did)?; let desc = com_atproto::repo::Describe { - name: did.to_string(), // TODO + handle: did.to_string(), // TODO did: did.to_string(), didDoc: did_doc, collections, - nameIsCorrect: true, + handleIsCorrect: true, }; Ok(RepoView { diff --git a/adenosine-pds/src/web.rs b/adenosine-pds/src/web.rs index fc75a93..80e6f15 100644 --- a/adenosine-pds/src/web.rs +++ b/adenosine-pds/src/web.rs @@ -29,8 +29,8 @@ pub struct AboutView { pub struct AccountView { pub domain: String, pub did: Did, - pub profile: app_bsky::ProfileView, - pub feed: Vec, + pub profile: app_bsky::ProfileViewDetailed, + pub feed: Vec, } #[derive(Template)] @@ -40,7 +40,7 @@ pub struct ThreadView { pub did: Did, pub collection: Nsid, pub tid: Tid, - pub post: app_bsky::ThreadPostView, + pub post: app_bsky::ThreadViewPost, } #[derive(Template)] -- cgit v1.2.3