diff --git a/Cargo.lock b/Cargo.lock index 1b8b81f..3a48a10 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1200,9 +1200,9 @@ dependencies = [ [[package]] name = "json-ld" -version = "0.12.1" +version = "0.15.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3e445d0986fc6a6e8bbe8b2c4ba0c847b7bebd201046cc37df645d632eb4202a" +checksum = "804a027f535a94f560af7182e1c5c1cbffba579e783392c5699743aab6442106" dependencies = [ "contextual", "futures", @@ -1219,9 +1219,9 @@ dependencies = [ [[package]] name = "json-ld-compaction" -version = "0.12.1" +version = "0.15.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cd69243e6b268c66c9cdd6f1aab73bd0d4f6df617d53e8d77238b676a9ab01c3" +checksum = "36937a7179489ee0ca59d85a5ed1efe03ef868b02929fa51c08cf2d9a6e63df0" dependencies = [ "contextual", "derivative", @@ -1241,9 +1241,9 @@ dependencies = [ [[package]] name = "json-ld-context-processing" -version = "0.12.1" +version = "0.15.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6162a8b000517178a4a23f546fa7fef31a0cac466393ef922a351d8e6041fb8f" +checksum = "bbb70837608ba8283480ceb11b1ad3efa034b497c8a89c1ab09213a2629f0b1c" dependencies = [ "contextual", "futures", @@ -1258,9 +1258,9 @@ dependencies = [ [[package]] name = "json-ld-core" -version = "0.12.1" +version = "0.15.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f103ff1c30bf42b3b7d09c69cbe12869e5ad42497638c5199d83de6fd7d7b13e" +checksum = "646445c329f5bd9fd0f2c04575fb91e708e4a78275ed92e832383495c3beb4a9" dependencies = [ "contextual", "derivative", @@ -1287,9 +1287,9 @@ dependencies = [ [[package]] name = "json-ld-expansion" -version = "0.12.1" +version = "0.15.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7ec3b334e7ae66e64a139ac34f38d3559dd82e7a0deed8891d1897a933a006cc" +checksum = "670588e31f803452f48df6b2e028859884ff00ff16cf3690109f5ca7a9746044" dependencies = [ "contextual", "derivative", @@ -1308,9 +1308,9 @@ dependencies = [ [[package]] name = "json-ld-syntax" -version = "0.12.1" +version = "0.15.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2fe7e17ed956850ff813815c960dcf3ab80604d72a2590ddebf8112509fb3722" +checksum = "8b133204002b55ee696ee8c531e5b125fc78e2fb34b6b3c4d8ffbe0cd51d9e6d" dependencies = [ "contextual", "decoded-char", @@ -2012,15 +2012,17 @@ dependencies = [ [[package]] name = "rdf-types" -version = "0.12.19" +version = "0.15.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "63d95f82a1f30f2d62e77b775ef4863f67ffafef1fc2c95ebfb55f3750be55df" +checksum = "d937485610ef88fde97044e8613bdbe8f585f75ab7a665f0d37b9a283621a0c8" dependencies = [ "contextual", + "indexmap 1.9.3", "iref", "langtag", "locspan", "locspan-derive", + "thiserror", ] [[package]] diff --git a/Cargo.toml b/Cargo.toml index c92fb02..89192ed 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -13,9 +13,9 @@ bytes = "1.3" chrono = { version = "0.4", features = [ "alloc", "clock", "serde" ] } dotenvy = "0.15.6" futures = "0.3" -hashbrown = "0.13" +hashbrown = "0.13.1" iref = "2.2" -json-ld = { version = "0.12" } +json-ld = { version = "0.15.0" } jsonwebtoken = { version = "8", default-features = false } locspan = "0.7" log = "0.4" @@ -23,7 +23,7 @@ mime = "0.3" openssl = "0.10" pretty_env_logger = "0.5.0" rand = "0.8" -rdf-types = "0.12" +rdf-types = "0.15.4" reqwest = { version = "0.11", features = [ "rustls" ] } rsa = { version = "0.9.2", features = [ "sha2" ] } serde = { version = "1.0", features = [ "derive" ] } diff --git a/src/ap/loader.rs b/src/ap/loader.rs index 82f8a27..d0df3fe 100644 --- a/src/ap/loader.rs +++ b/src/ap/loader.rs @@ -14,12 +14,13 @@ use crate::state::AppState; use bytes::Bytes; use futures::future::{BoxFuture, FutureExt}; use hashbrown::HashSet; -use iref::{Iri, IriBuf}; +use iref::Iri; use json_ld::{ syntax::{Parse, Value}, Loader, Profile, RemoteDocument, }; use locspan::{Meta, Span}; +use rdf_types::vocabulary::IriIndex; use rdf_types::{IriVocabulary, IriVocabularyMut}; use reqwest::{ header::{ACCEPT, CONTENT_TYPE, LINK, LOCATION}, @@ -35,7 +36,7 @@ use crate::util::http::{ Response, }; -pub struct CachedLoader> { +pub struct CachedLoader> { state: AppState, parser: Box>, } @@ -104,10 +105,13 @@ impl CachedLoader< return Err(Error::NotFound); } - debug!(target: "ap", "downloading {}", vocabulary.iri(&url).unwrap().as_str()); + let iri = vocabulary + .iri(&url) + .ok_or_else(|| Error::MalformedApub(String::from("Unresolved IRI")))?; + debug!(target: "ap", "downloading {iri}"); let response = http::get( &self.state, - vocabulary.iri(&url).unwrap().as_str(), + iri.as_str(), headers! { ACCEPT => ACCEPT_ACTIVITY_PUB, }, @@ -181,7 +185,7 @@ impl CachedLoader< } None => { break Err(Error::MalformedApub(String::from( - "Missing Location leader in HTTP redirect", + "Missing Location header in HTTP redirect", ))) } } @@ -215,8 +219,12 @@ impl CachedLoader< ))); } - let u = link.href().resolved(vocabulary.iri(url).unwrap()); - context_url = Some(vocabulary.insert(u.as_iri())); + let iri_buf = link.href().resolved( + vocabulary + .iri(url) + .ok_or_else(|| Error::MalformedApub(String::from("Unresolved IRI")))?, + ); + context_url = Some(vocabulary.insert(iri_buf.as_iri())); } } } diff --git a/src/ap/processor.rs b/src/ap/processor.rs index ed604e1..9090e4c 100644 --- a/src/ap/processor.rs +++ b/src/ap/processor.rs @@ -1,38 +1,37 @@ -use async_trait::async_trait; -use iref::{Iri, IriBuf}; use json_ld::{ - object::TypeRef, - syntax::{MetaValue, Parse, Value}, - Expand, IndexedObject, Loader, RemoteDocument, + syntax::{Parse, Value}, + Expand, RemoteDocument, }; -use locspan::{Meta, Span}; -use rdf_types::{vocabulary::Index, BlankIdBuf, IndexVocabulary, IriVocabulary, IriVocabularyMut}; -use serde::{Deserialize, Serialize}; -use static_iref::iri; -use std::fmt; +use rdf_types::{IndexVocabulary, IriVocabulary}; use crate::ap::loader::CachedLoader; use crate::core::*; -use crate::job::Job; use crate::state::AppState; -/// Main API for handling ActivityPub ingress, called by [`InboxWorker`]. -pub async fn process_document(state: &AppState, raw: &String) -> Result<()> { +/// Main API for handling ActivityPub ingress, called by [`crate::job::inbox::InboxWorker`]. +pub async fn process_document(state: &AppState, raw: &str) -> Result<()> { + let mut vocab: IndexVocabulary = IndexVocabulary::new(); + let document = Value::parse_str(raw, |span| span) .map_err(|e| Error::MalformedApub(format!("Could not parse document: {e}")))?; + let rd = RemoteDocument::new( None, Some("application/activity+json".parse().unwrap()), document, ); let mut loader = CachedLoader::new(state.clone()); - let rd = rd.expand(&mut loader).await.unwrap(); + let rd = rd.expand_with(&mut vocab, &mut loader).await.unwrap(); // this loop will usually only run once (one object per request) for object in rd.into_value() { - let id = object.id().ok_or(Error::MalformedApub(String::from( - "Document does not have an id", - )))?; + let id = object + .id() + .and_then(|i| i.as_iri()) + .and_then(|index| vocab.iri(index)) + .ok_or(Error::MalformedApub(String::from( + "Document does not have an id", + )))?; let mut typ = None; for t in object.types() { typ = Some(t); @@ -40,6 +39,8 @@ pub async fn process_document(state: &AppState, raw: &String) -> Result<()> { let typ = typ.ok_or(Error::MalformedApub(String::from( "Document does not have a type", )))?; + // just for testing some stuff + let typ = typ.as_iri().and_then(|index| vocab.iri(index)).unwrap(); debug!("Object id=\"{id}\" type=\"{typ}\""); }