From 50255bc3517b6a76c9264d92fdc93d4300871568 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: * Remove vestigial getrandom dep * Make gateway routes public * Provide blanket implementations of JobClient for Arc * scope GatewayManager::ucan_store, GatewayManager::get_context, and GatewayJob by gateway sphere's identity rather than counterpart identity. * Nightly lint fixes as needed --- Cargo.lock | 3 -- Cargo.toml | 1 - rust/noosphere-core/Cargo.toml | 2 -- rust/noosphere-core/src/api/mod.rs | 1 + rust/noosphere-core/src/helpers/context.rs | 7 +++-- rust/noosphere-core/src/view/mutation.rs | 2 +- .../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 +- 17 files changed, 62 insertions(+), 40 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index fc885177d..dc0992660 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3336,7 +3336,6 @@ dependencies = [ "fastcdc", "futures", "futures-util", - "getrandom", "gloo-net", "http 1.1.0", "instant", @@ -5679,8 +5678,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 e5307076e..0ec537a01 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 00d014e0c..ac4fe12ce 100644 --- a/rust/noosphere-core/src/api/mod.rs +++ b/rust/noosphere-core/src/api/mod.rs @@ -11,6 +11,7 @@ pub mod v0alpha2; pub use client::*; pub use data::*; +pub use route::*; // Re-export `http::StatusCode` here as our preferred `StatusCode` instance, // disambiguating from other crate's implementations. diff --git a/rust/noosphere-core/src/helpers/context.rs b/rust/noosphere-core/src/helpers/context.rs index 3f95d8bfb..90e789c9f 100644 --- a/rust/noosphere-core/src/helpers/context.rs +++ b/rust/noosphere-core/src/helpers/context.rs @@ -48,10 +48,13 @@ pub async fn simulated_sphere_context( /// Generate a [SphereContext] using the storage provided, intended for tests and /// benchmarks. You can pass a [Access] to control access. -pub async fn generate_sphere_context( +pub async fn generate_sphere_context( profile: Access, mut db: SphereDb, -) -> Result<(Arc>>, Mnemonic)> { +) -> Result<(Arc>>, Mnemonic)> +where + S: Storage + 'static, +{ let owner_key: SphereContextKey = Arc::new(Box::new(generate_ed25519_key())); let owner_did = owner_key.get_did().await?; diff --git a/rust/noosphere-core/src/view/mutation.rs b/rust/noosphere-core/src/view/mutation.rs index 8b84f58c8..925add372 100644 --- a/rust/noosphere-core/src/view/mutation.rs +++ b/rust/noosphere-core/src/view/mutation.rs @@ -258,7 +258,7 @@ where )); } - self.changes = changelog.changes.clone(); + self.changes.clone_from(&changelog.changes); Ok(()) } 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 }