From 19eaba2b7ad4b20701dc076d8847605571846656 Mon Sep 17 00:00:00 2001 From: Chris Joel <0xcda7a@gmail.com> Date: Mon, 12 Feb 2024 09:45:56 -0800 Subject: [PATCH] fix: some fixes for downstream cloud hosting work: * Cyclic dependency issues downstream: * Remove vestigial getrandom dep from noosphere-core (add notes to the usage in noosphere-core after further investigation) * Remove deprecated (due to cyclic dep issues) `serde-serialize` feature from wasm-bindgen * Make gateway routing traits public * Provide blanket implementations of `JobClient` for `Arc` * Scope `GatewayManager::ucan_store()` by gateway sphere identity, as well as other GatewayManager methods (in lieu of counterpart) --- Cargo.lock | 3 -- Cargo.toml | 1 - rust/noosphere-core/Cargo.toml | 2 -- rust/noosphere-core/src/api/mod.rs | 1 + .../src/extractors/authority.rs | 4 +-- .../noosphere-gateway/src/extractors/scope.rs | 9 ++++-- rust/noosphere-gateway/src/gateway_manager.rs | 10 +++---- .../src/handlers/v0alpha1/push.rs | 4 +-- .../src/handlers/v0alpha2/push.rs | 4 +-- rust/noosphere-gateway/src/jobs/client.rs | 10 +++++++ .../src/jobs/processors/syndication.rs | 8 ++--- .../src/single_tenant/gateway_manager.rs | 29 +++++++++++++------ .../src/single_tenant/job_client.rs | 4 +-- .../single_tenant/sphere_context_resolver.rs | 2 +- rust/noosphere-storage/Cargo.toml | 2 +- rust/noosphere-ucan/Cargo.toml | 4 ++- 16 files changed, 59 insertions(+), 38 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 2a6373dc8..b61e2139e 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3342,7 +3342,6 @@ dependencies = [ "fastcdc", "futures", "futures-util", - "getrandom", "gloo-net", "http 1.1.0", "instant", @@ -5719,8 +5718,6 @@ source = "registry+/~https://github.com/rust-lang/crates.io-index" checksum = "4be2531df63900aeb2bca0daaaddec08491ee64ceecbee5076636a3b026795a8" dependencies = [ "cfg-if", - "serde", - "serde_json", "wasm-bindgen-macro", ] diff --git a/Cargo.toml b/Cargo.toml index d42424837..6b84cfaa0 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -94,4 +94,3 @@ web-sys = { version = "0.3" } [profile.release] opt-level = 'z' lto = true - diff --git a/rust/noosphere-core/Cargo.toml b/rust/noosphere-core/Cargo.toml index 52ad26654..6bef116c6 100644 --- a/rust/noosphere-core/Cargo.toml +++ b/rust/noosphere-core/Cargo.toml @@ -73,8 +73,6 @@ tokio = { workspace = true, features = ["full"] } tracing-subscriber = { workspace = true } [target.'cfg(target_arch = "wasm32")'.dependencies] -# NOTE: This is needed so that rand can be included in WASM builds -getrandom = { workspace = true, features = ["js"] } gloo-net = { workspace = true } wasm-streams = { workspace = true } wasm-bindgen = { workspace = true } diff --git a/rust/noosphere-core/src/api/mod.rs b/rust/noosphere-core/src/api/mod.rs index baeab3252..1fbc38f1e 100644 --- a/rust/noosphere-core/src/api/mod.rs +++ b/rust/noosphere-core/src/api/mod.rs @@ -11,3 +11,4 @@ pub mod v0alpha2; pub use client::*; pub use data::*; +pub use route::*; diff --git a/rust/noosphere-gateway/src/extractors/authority.rs b/rust/noosphere-gateway/src/extractors/authority.rs index 479d2bead..2927641c0 100644 --- a/rust/noosphere-gateway/src/extractors/authority.rs +++ b/rust/noosphere-gateway/src/extractors/authority.rs @@ -50,7 +50,7 @@ where let capability = generate_capability(counterpart_str, required_ability); let db = self .manager - .ucan_store() + .ucan_store(&gateway_scope.gateway) .await .map_err(|_| StatusCode::INTERNAL_SERVER_ERROR)?; @@ -70,7 +70,7 @@ where debug!("Authorized!"); return self .manager - .sphere_context(&gateway_scope.counterpart) + .sphere_context(&gateway_scope.gateway) .await .map_err(|_| StatusCode::INTERNAL_SERVER_ERROR); } diff --git a/rust/noosphere-gateway/src/extractors/scope.rs b/rust/noosphere-gateway/src/extractors/scope.rs index 8b739e07f..a9d0439e0 100644 --- a/rust/noosphere-gateway/src/extractors/scope.rs +++ b/rust/noosphere-gateway/src/extractors/scope.rs @@ -23,6 +23,8 @@ use noosphere_core::context::SphereContext; pub struct GatewayScope { /// [Did] of the client counterpart sphere. pub counterpart: Did, + /// [Did] of the managed gateway sphere. + pub gateway: Did, /// [Did] of the author of the managed gateway sphere. pub gateway_identity: Did, sphere_context_marker: PhantomData, @@ -31,9 +33,10 @@ pub struct GatewayScope { impl GatewayScope { /// Creates a new [GatewayScope]. - pub fn new(gateway_identity: Did, counterpart: Did) -> Self { + pub fn new(gateway_identity: Did, gateway: Did, counterpart: Did) -> Self { Self { gateway_identity, + gateway, counterpart, sphere_context_marker: PhantomData, storage_marker: PhantomData, @@ -54,7 +57,7 @@ where parts: &mut Parts, state: &Arc, ) -> Result { - let (gateway_identity, counterpart) = state.gateway_scope(parts).await?; - Ok(GatewayScope::new(gateway_identity, counterpart)) + let (gateway_identity, gateway, counterpart) = state.gateway_scope(parts).await?; + Ok(GatewayScope::new(gateway_identity, gateway, counterpart)) } } diff --git a/rust/noosphere-gateway/src/gateway_manager.rs b/rust/noosphere-gateway/src/gateway_manager.rs index 52f60dfe5..144b6d89a 100644 --- a/rust/noosphere-gateway/src/gateway_manager.rs +++ b/rust/noosphere-gateway/src/gateway_manager.rs @@ -29,14 +29,14 @@ where /// An optional [Url] to configure CORS layers. fn cors_origin(&self) -> Option; - /// A sphere-agnostic block store for authorization. - async fn ucan_store(&self) -> Result>; + /// Retrieve a [UcanStore] for `sphere_identity`. + async fn ucan_store(&self, sphere_identity: &Did) -> Result>; - /// Retrieve a sphere context that maps to `counterpart`. - async fn sphere_context(&self, counterpart: &Did) -> Result; + /// Retrieve a sphere context that maps to `sphere_identity`. + async fn sphere_context(&self, sphere_identity: &Did) -> Result; /// Extract the specified gateway identity (0) and counterpart (1) /// from an [axum] request. This function should be deterministic in /// order to take advantage of caching. - async fn gateway_scope(&self, parts: &mut Parts) -> Result<(Did, Did), StatusCode>; + async fn gateway_scope(&self, parts: &mut Parts) -> Result<(Did, Did, Did), StatusCode>; } diff --git a/rust/noosphere-gateway/src/handlers/v0alpha1/push.rs b/rust/noosphere-gateway/src/handlers/v0alpha1/push.rs index c138478f2..985dcc925 100644 --- a/rust/noosphere-gateway/src/handlers/v0alpha1/push.rs +++ b/rust/noosphere-gateway/src/handlers/v0alpha1/push.rs @@ -301,7 +301,7 @@ where if let Err(error) = self .job_runner_client .submit(GatewayJob::NameSystemResolveSince { - identity: self.gateway_scope.counterpart.to_owned(), + identity: self.gateway_scope.gateway.to_owned(), since: self.request_body.local_base, }) { @@ -323,7 +323,7 @@ where // an explicit publish action. Move this to the publish handler when we // have added it to the gateway. if let Err(error) = self.job_runner_client.submit(GatewayJob::IpfsSyndication { - identity: self.gateway_scope.counterpart.to_owned(), + identity: self.gateway_scope.gateway.to_owned(), name_publish_on_success, }) { warn!("Failed to queue IPFS syndication job: {}", error); diff --git a/rust/noosphere-gateway/src/handlers/v0alpha2/push.rs b/rust/noosphere-gateway/src/handlers/v0alpha2/push.rs index 9daf5d37a..0bf41d9ce 100644 --- a/rust/noosphere-gateway/src/handlers/v0alpha2/push.rs +++ b/rust/noosphere-gateway/src/handlers/v0alpha2/push.rs @@ -331,7 +331,7 @@ where if let Err(error) = self .job_runner_client .submit(GatewayJob::NameSystemResolveAll { - identity: self.gateway_scope.counterpart.to_owned(), + identity: self.gateway_scope.gateway.to_owned(), }) { warn!("Failed to request name system resolutions: {}", error); @@ -354,7 +354,7 @@ where // an explicit publish action. Move this to the publish handler when we // have added it to the gateway. if let Err(error) = self.job_runner_client.submit(GatewayJob::IpfsSyndication { - identity: self.gateway_scope.counterpart.to_owned(), + identity: self.gateway_scope.gateway.to_owned(), name_publish_on_success, }) { warn!("Failed to queue IPFS syndication job: {}", error); diff --git a/rust/noosphere-gateway/src/jobs/client.rs b/rust/noosphere-gateway/src/jobs/client.rs index 3bcf97495..23a5e630e 100644 --- a/rust/noosphere-gateway/src/jobs/client.rs +++ b/rust/noosphere-gateway/src/jobs/client.rs @@ -1,5 +1,6 @@ use crate::jobs::GatewayJob; use anyhow::Result; +use std::{ops::Deref, sync::Arc}; /// [JobClient] allows a gateway or other service /// to submit jobs to be processed. @@ -7,3 +8,12 @@ pub trait JobClient: Send + Sync { /// Submit a [GatewayJob] to be processed. fn submit(&self, job: GatewayJob) -> Result<()>; } + +impl JobClient for Arc +where + T: JobClient, +{ + fn submit(&self, job: GatewayJob) -> Result<()> { + self.deref().submit(job) + } +} diff --git a/rust/noosphere-gateway/src/jobs/processors/syndication.rs b/rust/noosphere-gateway/src/jobs/processors/syndication.rs index c980befc4..e53f1178e 100644 --- a/rust/noosphere-gateway/src/jobs/processors/syndication.rs +++ b/rust/noosphere-gateway/src/jobs/processors/syndication.rs @@ -78,7 +78,7 @@ where // Take a lock on the `SphereContext` and look up the most recent // syndication checkpoint for this Kubo node - let (sphere_revision, mut syndication_checkpoint, db, counterpart_identity) = { + let (sphere_revision, mut syndication_checkpoint, db, sphere_identity) = { let db = { let context = context.sphere_context().await?; context.db().clone() @@ -87,7 +87,7 @@ where let counterpart_identity = db.require_key::<_, Did>(COUNTERPART).await?; let sphere = context.to_sphere().await?; let content = sphere.get_content().await?; - + let sphere_identity = context.identity().await?; let counterpart_revision = *content.require(&counterpart_identity).await?; let syndication_checkpoint = match context.read(&checkpoint_key).await? { @@ -121,7 +121,7 @@ where counterpart_revision, syndication_checkpoint, db, - counterpart_identity, + sphere_identity, ) }; @@ -196,7 +196,7 @@ where Ok( name_publish_on_success.map(|record| GatewayJob::NameSystemPublish { - identity: counterpart_identity, + identity: sphere_identity, record, }), ) diff --git a/rust/noosphere-gateway/src/single_tenant/gateway_manager.rs b/rust/noosphere-gateway/src/single_tenant/gateway_manager.rs index 3e1efa236..13e9de43c 100644 --- a/rust/noosphere-gateway/src/single_tenant/gateway_manager.rs +++ b/rust/noosphere-gateway/src/single_tenant/gateway_manager.rs @@ -43,8 +43,11 @@ where name_resolver_api: Url, cors_origin: Option, ) -> Result { - let gateway_identity = context.sphere_context().await?.author().did().await?; - let gateway_scope = GatewayScope::new(gateway_identity, counterpart); + let (gateway, gateway_identity) = { + let ctx = context.sphere_context().await?; + (ctx.identity().to_owned(), ctx.author().did().await?) + }; + let gateway_scope = GatewayScope::new(gateway_identity, gateway, counterpart); let context_resolver = SingleTenantContextResolver::new(context.clone(), gateway_scope.clone()); let job_client = Arc::new( @@ -88,19 +91,27 @@ where self.cors_origin.to_owned() } - async fn ucan_store(&self) -> Result> { - let context = self.context.sphere_context().await?; - let db = context.db().to_block_store(); - Ok(UcanStore(db)) + async fn ucan_store(&self, sphere_identity: &Did) -> Result> { + match &self.gateway_scope.gateway == sphere_identity { + true => { + let context = self.context.sphere_context().await?; + let db = context.db().to_block_store(); + Ok(UcanStore(db)) + } + false => Err(anyhow::anyhow!( + "No ucan store found with identity: {sphere_identity}." + )), + } } - async fn sphere_context(&self, counterpart: &Did) -> Result { - self.context_resolver.get_context(counterpart).await + async fn sphere_context(&self, sphere_identity: &Did) -> Result { + self.context_resolver.get_context(sphere_identity).await } - async fn gateway_scope(&self, _: &mut Parts) -> Result<(Did, Did), StatusCode> { + async fn gateway_scope(&self, _: &mut Parts) -> Result<(Did, Did, Did), StatusCode> { Ok(( self.gateway_scope.gateway_identity.clone(), + self.gateway_scope.gateway.clone(), self.gateway_scope.counterpart.clone(), )) } diff --git a/rust/noosphere-gateway/src/single_tenant/job_client.rs b/rust/noosphere-gateway/src/single_tenant/job_client.rs index 2c5fef4da..2900c3d3e 100644 --- a/rust/noosphere-gateway/src/single_tenant/job_client.rs +++ b/rust/noosphere-gateway/src/single_tenant/job_client.rs @@ -91,7 +91,7 @@ where } } -impl JobClient for Arc> +impl JobClient for SingleTenantJobClient where C: HasMutableSphereContext, S: Storage + 'static, @@ -136,7 +136,7 @@ where C: HasMutableSphereContext + 'static, S: Storage + 'static, { - let identity = scope.counterpart; + let identity = scope.gateway; let _ = tokio::join!( schedule( &queue, diff --git a/rust/noosphere-gateway/src/single_tenant/sphere_context_resolver.rs b/rust/noosphere-gateway/src/single_tenant/sphere_context_resolver.rs index a724abd4e..220b26edc 100644 --- a/rust/noosphere-gateway/src/single_tenant/sphere_context_resolver.rs +++ b/rust/noosphere-gateway/src/single_tenant/sphere_context_resolver.rs @@ -40,7 +40,7 @@ where S: Storage + 'static, { async fn get_context(&self, did: &Did) -> Result { - match &self.gateway_scope.counterpart == did { + match &self.gateway_scope.gateway == did { true => Ok(self.context.clone()), false => Err(anyhow!( "No sphere context found with gateway identity: {did}." diff --git a/rust/noosphere-storage/Cargo.toml b/rust/noosphere-storage/Cargo.toml index e325fefb7..a0cedab4e 100644 --- a/rust/noosphere-storage/Cargo.toml +++ b/rust/noosphere-storage/Cargo.toml @@ -50,7 +50,7 @@ rocksdb = { version = "0.22.0", optional = true } [target.'cfg(target_arch = "wasm32")'.dependencies] tokio = { workspace = true, features = ["sync", "macros"] } -wasm-bindgen = { workspace = true, features = ["serde-serialize"] } +wasm-bindgen = { workspace = true } wasm-bindgen-futures = { workspace = true } serde-wasm-bindgen = { workspace = true } js-sys = { workspace = true } diff --git a/rust/noosphere-ucan/Cargo.toml b/rust/noosphere-ucan/Cargo.toml index 40d2c1322..0e5bb0fa2 100644 --- a/rust/noosphere-ucan/Cargo.toml +++ b/rust/noosphere-ucan/Cargo.toml @@ -54,7 +54,9 @@ wasm-bindgen-futures = { workspace = true, optional = true } js-sys = { workspace = true, optional = true } [target.'cfg(target_arch = "wasm32")'.dependencies] -# NOTE: This is needed so that rand can be included in WASM builds +# NOTE: This is a transitive dependency used by other +# crypto/random crates that requires us setting the "js" +# in order to provide the functionality in JS environments. getrandom = { workspace = true, features = ["js"] } [dev-dependencies]