diff --git a/Cargo.lock b/Cargo.lock index 790615f9c..ba40552e5 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -796,6 +796,15 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "771fe0050b883fcc3ea2359b1a96bcfbc090b7116eae7c3c512c7a083fdf23d3" +[[package]] +name = "bs58" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f5353f36341f7451062466f0b755b96ac3a9547e4d7f6b70d603fc721a7d7896" +dependencies = [ + "tinyvec", +] + [[package]] name = "bstr" version = "1.4.0" @@ -2771,7 +2780,7 @@ version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9e2d584751cecb2aabaa56106be6be91338a60a0f4e420cf2af639204f596fc1" dependencies = [ - "bs58", + "bs58 0.4.0", "ed25519-dalek", "log", "multiaddr", @@ -3584,7 +3593,7 @@ dependencies = [ "serde_bytes", "serde_json", "strum", - "strum_macros", + "strum_macros 0.24.3", "tiny-bip39", "tokio", "tokio-stream", @@ -3621,7 +3630,7 @@ dependencies = [ "serde", "serde_json", "strum", - "strum_macros", + "strum_macros 0.24.3", "thiserror", "tokio", "tokio-stream", @@ -3961,7 +3970,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "58341485071825827b7f03cf7efd1cb21e6a709bea778fb50227fd45d2f361b4" dependencies = [ "arrayref", - "bs58", + "bs58 0.4.0", "byteorder", "data-encoding", "multihash 0.13.2", @@ -4114,14 +4123,13 @@ checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" [[package]] name = "pkcs1" -version = "0.4.1" +version = "0.7.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eff33bdbdfc54cc98a2eca766ebdec3e1b8fb7387523d5c9c9a2891da856f719" +checksum = "c8ffb9f10fa047879315e6625af03c164b16962a5368d724ed16323b68ace47f" dependencies = [ - "der 0.6.1", - "pkcs8 0.9.0", - "spki 0.6.0", - "zeroize", + "der 0.7.6", + "pkcs8 0.10.2", + "spki 0.7.2", ] [[package]] @@ -4614,20 +4622,22 @@ dependencies = [ [[package]] name = "rsa" -version = "0.8.2" +version = "0.9.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "55a77d189da1fee555ad95b7e50e7457d91c0e089ec68ca69ad2989413bbdab4" +checksum = "6ab43bb47d23c1a631b4b680199a45255dce26fa9ab2fa902581f624ff13e6a8" dependencies = [ "byteorder", + "const-oid", "digest 0.10.7", "num-bigint-dig", "num-integer", "num-iter", "num-traits", "pkcs1", - "pkcs8 0.9.0", + "pkcs8 0.10.2", "rand_core 0.6.4", "signature 2.1.0", + "spki 0.7.2", "subtle", "zeroize", ] @@ -5240,6 +5250,19 @@ dependencies = [ "syn 1.0.109", ] +[[package]] +name = "strum_macros" +version = "0.25.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fe9f3bd7d2e45dcc5e265fbb88d6513e4747d8ef9444cf01a533119bce28a157" +dependencies = [ + "heck", + "proc-macro2", + "quote", + "rustversion", + "syn 2.0.16", +] + [[package]] name = "stun" version = "0.4.4" @@ -5778,15 +5801,15 @@ checksum = "497961ef93d974e23eb6f433eb5fe1b7930b659f06d12dec6fc44a8f554c0bba" [[package]] name = "ucan" -version = "0.3.2" +version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f2d1efb030f1b24acd7f6a84ef7346d4b6f390000c5304f1d4db11428b9ac5bb" +checksum = "b3722c8cba706d28123758300ca0738852b5132b37a7c656f59b9484ac8f2435" dependencies = [ "anyhow", "async-recursion", "async-trait", "base64 0.21.0", - "bs58", + "bs58 0.5.0", "cid 0.10.1", "futures", "getrandom 0.2.9", @@ -5798,20 +5821,20 @@ dependencies = [ "serde", "serde_json", "strum", - "strum_macros", + "strum_macros 0.25.0", "unsigned-varint 0.7.1", "url", ] [[package]] name = "ucan-key-support" -version = "0.1.6" +version = "0.1.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "09c8af03a21853cc6e1edf43a28aa2d6712b5d1692c75777896cd9bf09d56d9c" +checksum = "204146152a164519150c4e9c27f9a728c04d50b7f8a4668c33e5f84d2e536226" dependencies = [ "anyhow", "async-trait", - "bs58", + "bs58 0.5.0", "ed25519-zebra", "js-sys", "log", diff --git a/Cargo.toml b/Cargo.toml index 767a43c3b..81a651fa2 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -25,8 +25,8 @@ tracing = { version = "0.1" } tracing-subscriber = { version = "~0.3.16", features = ["env-filter", "tracing-log"] } thiserror = { version = "1" } gloo-timers = { version = "0.2", features = ["futures"] } -ucan = { version = "0.3.2" } -ucan-key-support = { version = "0.1.6" } +ucan = { version = "0.4.0" } +ucan-key-support = { version = "0.1.7" } libipld = { version = "0.16" } libipld-core = { version = "0.16" } libipld-cbor = { version = "0.16" } diff --git a/c/example/main.c b/c/example/main.c index 1b363baba..61bf2368a 100644 --- a/c/example/main.c +++ b/c/example/main.c @@ -95,6 +95,7 @@ void test_errors() { assert(error_message != NULL); assert(ns_error_code_get(error) == NS_ERROR_CODE_OTHER); + ns_error_free(error); ns_string_free(error_message); ns_free(noosphere); } diff --git a/rust/noosphere-api/src/client.rs b/rust/noosphere-api/src/client.rs index be12a37b4..144cf758f 100644 --- a/rust/noosphere-api/src/client.rs +++ b/rust/noosphere-api/src/client.rs @@ -13,7 +13,7 @@ use libipld_cbor::DagCborCodec; use noosphere_car::CarReader; use noosphere_core::{ - authority::{Author, SphereAction, SphereReference}, + authority::{generate_capability, Author, SphereAbility, SphereReference}, data::{Link, MemoIpld}, }; use noosphere_storage::{block_deserialize, block_serialize}; @@ -22,7 +22,7 @@ use tokio_stream::{Stream, StreamExt}; use tokio_util::io::StreamReader; use ucan::{ builder::UcanBuilder, - capability::{Capability, Resource, With}, + capability::CapabilityView, crypto::{did::DidParser, KeyMaterial}, store::{UcanJwtStore, UcanStore}, ucan::Ucan, @@ -82,14 +82,7 @@ where let (jwt, ucan_headers) = Self::make_bearer_token( &gateway_identity, author, - &Capability { - with: With::Resource { - kind: Resource::Scoped(SphereReference { - did: sphere_identity.to_string(), - }), - }, - can: SphereAction::Fetch, - }, + &generate_capability(sphere_identity, SphereAbility::Fetch), &store, ) .await?; @@ -123,7 +116,7 @@ where async fn make_bearer_token( gateway_identity: &str, author: &Author, - capability: &Capability, + capability: &CapabilityView, store: &S, ) -> Result<(String, HeaderMap)> { let mut signable = UcanBuilder::default() @@ -206,14 +199,7 @@ where debug!("Client replicating {} from {}", memo_version, url); - let capability = Capability { - with: With::Resource { - kind: Resource::Scoped(SphereReference { - did: self.sphere_identity.clone(), - }), - }, - can: SphereAction::Fetch, - }; + let capability = generate_capability(&self.sphere_identity, SphereAbility::Fetch); let (token, ucan_headers) = Self::make_bearer_token( &self.session.gateway_identity, @@ -258,15 +244,7 @@ where debug!("Client fetching blocks from {}", url); - let capability = Capability { - with: With::Resource { - kind: Resource::Scoped(SphereReference { - did: self.sphere_identity.clone(), - }), - }, - can: SphereAction::Fetch, - }; - + let capability = generate_capability(&self.sphere_identity, SphereAbility::Fetch); let (token, ucan_headers) = Self::make_bearer_token( &self.session.gateway_identity, &self.author, @@ -321,15 +299,7 @@ where push_body.sphere, url ); - let capability = Capability { - with: With::Resource { - kind: Resource::Scoped(SphereReference { - did: self.sphere_identity.clone(), - }), - }, - can: SphereAction::Push, - }; - + let capability = generate_capability(&self.sphere_identity, SphereAbility::Push); let (token, ucan_headers) = Self::make_bearer_token( &self.session.gateway_identity, &self.author, diff --git a/rust/noosphere-api/src/data.rs b/rust/noosphere-api/src/data.rs index 396183e34..76d61442e 100644 --- a/rust/noosphere-api/src/data.rs +++ b/rust/noosphere-api/src/data.rs @@ -3,7 +3,7 @@ use std::{fmt::Display, str::FromStr}; use anyhow::{anyhow, Result}; use cid::Cid; use noosphere_core::{ - authority::{SphereAction, SphereReference, SPHERE_SEMANTICS}, + authority::{generate_capability, SphereAbility, SPHERE_SEMANTICS}, data::{Bundle, Did, Jwt, Link, MemoIpld}, }; use noosphere_storage::{base64_decode, base64_encode}; @@ -11,7 +11,6 @@ use reqwest::StatusCode; use serde::{Deserialize, Deserializer, Serialize}; use thiserror::Error; use ucan::{ - capability::{Capability, Resource, With}, chain::ProofChain, crypto::{did::DidParser, KeyMaterial}, store::UcanStore, @@ -227,15 +226,7 @@ impl IdentifyResponse { return Err(anyhow!("Wrong audience!")); } - let capability = Capability { - with: With::Resource { - kind: Resource::Scoped(SphereReference { - did: self.sphere_identity.to_string(), - }), - }, - can: SphereAction::Push, - }; - + let capability = generate_capability(&self.sphere_identity, SphereAbility::Push); let capability_infos = proof.reduce_capabilities(&SPHERE_SEMANTICS); for capability_info in capability_infos { diff --git a/rust/noosphere-cli/src/native/commands/auth.rs b/rust/noosphere-cli/src/native/commands/auth.rs index 82c7ab518..611703f74 100644 --- a/rust/noosphere-cli/src/native/commands/auth.rs +++ b/rust/noosphere-cli/src/native/commands/auth.rs @@ -3,18 +3,12 @@ use std::{convert::TryFrom, str::FromStr}; use anyhow::{anyhow, Result}; use cid::Cid; use noosphere_core::{ - authority::{SphereAction, SphereReference}, + authority::{generate_capability, SphereAbility}, data::{DelegationIpld, Link, RevocationIpld}, view::{Sphere, SphereMutation}, }; use serde_json::{json, Value}; -use ucan::{ - builder::UcanBuilder, - capability::{Capability, Resource, With}, - crypto::KeyMaterial, - store::UcanJwtStore, - Ucan, -}; +use ucan::{builder::UcanBuilder, crypto::KeyMaterial, store::UcanJwtStore, Ucan}; use tokio_stream::StreamExt; @@ -76,28 +70,24 @@ You will be able to add a new one after the old one is revoked"#, let my_did = my_key.get_did().await?; let latest_sphere_cid = db.require_version(&sphere_did).await?; let authorization = workspace.authorization().await?; - let authorization_expiry: u64 = { + let authorization_expiry: Option = { let ucan = authorization.resolve_ucan(&db).await?; - *ucan.expires_at() + ucan.expires_at().to_owned() }; - let mut signable = UcanBuilder::default() + let mut builder = UcanBuilder::default() .issued_by(&my_key) .for_audience(did) - .claiming_capability(&Capability { - with: With::Resource { - kind: Resource::Scoped(SphereReference { - did: sphere_did.to_string(), - }), - }, - can: SphereAction::Authorize, - }) - .with_expiration(authorization_expiry) - .with_nonce() - // TODO(ucan-wg/rs-ucan#32): Clean this up when we can use a CID as an authorization - // .witnessed_by(&authorization) - .build()?; + .claiming_capability(&generate_capability(&sphere_did, SphereAbility::Authorize)) + .with_nonce(); + // TODO(ucan-wg/rs-ucan#32): Clean this up when we can use a CID as an authorization + // .witnessed_by(&authorization) + + if let Some(exp) = authorization_expiry { + builder = builder.with_expiration(exp); + } + let mut signable = builder.build()?; signable .proofs .push(Cid::try_from(&authorization)?.to_string()); diff --git a/rust/noosphere-core/Cargo.toml b/rust/noosphere-core/Cargo.toml index d53d53f2b..3cfd365a9 100644 --- a/rust/noosphere-core/Cargo.toml +++ b/rust/noosphere-core/Cargo.toml @@ -36,6 +36,7 @@ anyhow = "^1" fastcdc = "3" futures = "~0.3" serde = { workspace = true } +serde_json = { workspace = true } byteorder = "^1.4" base64 = "0.21" ed25519-zebra = "^3" @@ -58,7 +59,6 @@ sentry-tracing = { workspace = true, optional = true } [dev-dependencies] wasm-bindgen-test = { workspace = true } serde_bytes = "~0.11" -serde_json = { workspace = true } [target.'cfg(not(target_arch = "wasm32"))'.dependencies] tokio = { version = "^1", features = ["full"] } diff --git a/rust/noosphere-core/src/authority/author.rs b/rust/noosphere-core/src/authority/author.rs index 1ff365dd5..5fe4943e6 100644 --- a/rust/noosphere-core/src/authority/author.rs +++ b/rust/noosphere-core/src/authority/author.rs @@ -1,19 +1,19 @@ use crate::{ authority::{ - generate_ed25519_key, Authorization, SphereAction, SphereReference, SPHERE_SEMANTICS, - SUPPORTED_KEYS, + generate_ed25519_key, Authorization, SphereAbility, SPHERE_SEMANTICS, SUPPORTED_KEYS, }, data::Did, }; use anyhow::{anyhow, Result}; use noosphere_storage::{SphereDb, Storage}; use ucan::{ - capability::{Capability, Resource, With}, chain::ProofChain, crypto::{did::DidParser, KeyMaterial}, }; use ucan_key_support::ed25519::Ed25519KeyMaterial; +use super::generate_capability; + /// The level of access that a given user has to a related resource. Broadly, /// a user will always have either read/write access (to their own sphere) or /// else read-only access (to all other spheres). @@ -79,14 +79,7 @@ where return Ok(Access::ReadOnly); } - let read_write_capability = Capability { - with: With::Resource { - kind: Resource::Scoped(SphereReference { - did: sphere_identity.to_string(), - }), - }, - can: SphereAction::Push, - }; + let read_write_capability = generate_capability(sphere_identity, SphereAbility::Push); let mut did_parser = DidParser::new(SUPPORTED_KEYS); let proof_chain = ProofChain::from_ucan(ucan, None, &mut did_parser, db).await?; diff --git a/rust/noosphere-core/src/authority/capability.rs b/rust/noosphere-core/src/authority/capability.rs index d1b4a0b75..4db0516eb 100644 --- a/rust/noosphere-core/src/authority/capability.rs +++ b/rust/noosphere-core/src/authority/capability.rs @@ -1,9 +1,12 @@ use anyhow::{anyhow, Result}; -use ucan::capability::{Action, Capability, CapabilitySemantics, Resource, Scope, With}; +use serde_json::json; +use ucan::capability::{ + Ability, CapabilitySemantics, CapabilityView, Resource, ResourceUri, Scope, +}; use url::Url; #[derive(PartialEq, Eq, PartialOrd, Ord, Clone, Debug)] -pub enum SphereAction { +pub enum SphereAbility { /// May read information about a sphere from a counterpart Fetch, /// May push an updated sphere lineage to a counterpart @@ -14,29 +17,29 @@ pub enum SphereAction { Authorize, } -impl Action for SphereAction {} +impl Ability for SphereAbility {} -impl ToString for SphereAction { +impl ToString for SphereAbility { fn to_string(&self) -> String { match self { - SphereAction::Authorize => "sphere/authorize", - SphereAction::Publish => "sphere/publish", - SphereAction::Push => "sphere/push", - SphereAction::Fetch => "sphere/fetch", + SphereAbility::Authorize => "sphere/authorize", + SphereAbility::Publish => "sphere/publish", + SphereAbility::Push => "sphere/push", + SphereAbility::Fetch => "sphere/fetch", } .into() } } -impl TryFrom for SphereAction { +impl TryFrom for SphereAbility { type Error = anyhow::Error; fn try_from(value: String) -> Result { Ok(match value.as_str() { - "sphere/authorize" => SphereAction::Authorize, - "sphere/publish" => SphereAction::Publish, - "sphere/push" => SphereAction::Push, - "sphere/fetch" => SphereAction::Fetch, + "sphere/authorize" => SphereAbility::Authorize, + "sphere/publish" => SphereAbility::Publish, + "sphere/push" => SphereAbility::Push, + "sphere/fetch" => SphereAbility::Fetch, _ => return Err(anyhow!("Unrecognized action: {:?}", value)), }) } @@ -77,37 +80,40 @@ impl TryFrom for SphereReference { pub struct SphereSemantics {} -impl CapabilitySemantics for SphereSemantics {} +impl CapabilitySemantics for SphereSemantics {} pub const SPHERE_SEMANTICS: SphereSemantics = SphereSemantics {}; /// Generates a [Capability] struct representing permissions in a [LinkRecord]. /// /// ``` -/// use noosphere_core::{authority::{generate_capability, SphereAction, SphereReference}}; -/// use ucan::capability::{Capability, Resource, With}; +/// use noosphere_core::{authority::{generate_capability, SphereAbility, SphereReference}}; +/// use ucan::capability::{CapabilityView, ResourceUri, Resource}; +/// use serde_json::json; /// /// let identity = "did:key:z6MkoE19WHXJzpLqkxbGP7uXdJX38sWZNUWwyjcuCmjhPpUP"; -/// let expected_capability = Capability { -/// with: With::Resource { -/// kind: Resource::Scoped(SphereReference { +/// let expected_capability = CapabilityView { +/// resource: Resource::Resource { +/// kind: ResourceUri::Scoped(SphereReference { /// did: identity.to_owned(), /// }), /// }, -/// can: SphereAction::Publish, +/// ability: SphereAbility::Publish, +/// caveat: json!({}), /// }; -/// assert_eq!(generate_capability(&identity, SphereAction::Publish), expected_capability); +/// assert_eq!(generate_capability(&identity, SphereAbility::Publish), expected_capability); /// ``` pub fn generate_capability( identity: &str, - action: SphereAction, -) -> Capability { - Capability { - with: With::Resource { - kind: Resource::Scoped(SphereReference { + ability: SphereAbility, +) -> CapabilityView { + CapabilityView { + resource: Resource::Resource { + kind: ResourceUri::Scoped(SphereReference { did: identity.to_owned(), }), }, - can: action, + ability, + caveat: json!({}), } } diff --git a/rust/noosphere-core/src/data/address.rs b/rust/noosphere-core/src/data/address.rs index 786af3287..1cfb63032 100644 --- a/rust/noosphere-core/src/data/address.rs +++ b/rust/noosphere-core/src/data/address.rs @@ -1,4 +1,4 @@ -use crate::authority::{generate_capability, SphereAction, SPHERE_SEMANTICS, SUPPORTED_KEYS}; +use crate::authority::{generate_capability, SphereAbility, SPHERE_SEMANTICS, SUPPORTED_KEYS}; use anyhow::Result; use cid::Cid; use libipld_cbor::DagCborCodec; @@ -12,6 +12,8 @@ use super::{Did, IdentitiesIpld, Jwt, Link, MemoIpld}; #[cfg(docs)] use crate::data::SphereIpld; +pub const LINK_RECORD_FACT_NAME: &str = "link"; + /// A subdomain of a [SphereIpld] that pertains to the management and recording of /// the petnames associated with the sphere. #[derive(Debug, Eq, PartialEq, Clone, Serialize, Deserialize, Hash)] @@ -80,16 +82,16 @@ impl LinkRecord { // We're interested in the validity of the proof at the time // of publishing. let now_time = if let Some(nbf) = token.not_before() { - nbf.to_owned() + Some(nbf.to_owned()) } else { - token.expires_at() - 1 + token.expires_at().as_ref().map(|exp| exp - 1) }; let proof = - ProofChain::from_ucan(token.to_owned(), Some(now_time), &mut did_parser, store).await?; + ProofChain::from_ucan(token.to_owned(), now_time, &mut did_parser, store).await?; { - let desired_capability = generate_capability(&identity, SphereAction::Publish); + let desired_capability = generate_capability(&identity, SphereAbility::Publish); let mut has_capability = false; for capability_info in proof.reduce_capabilities(&SPHERE_SEMANTICS) { let capability = capability_info.capability; @@ -132,33 +134,23 @@ impl LinkRecord { return None; }; - for fact in facts { - match fact.as_object() { - Some(fields) => match fields.get("link") { - Some(cid_string) => { - match Cid::try_from(cid_string.as_str().unwrap_or_default()) { - Ok(cid) => return Some(cid.into()), - Err(error) => { - warn!( - "Could not parse '{}' as name record link: {}", - cid_string, error - ); - continue; - } + for (name, value) in facts.iter() { + if name == LINK_RECORD_FACT_NAME { + return match value.as_str() { + Some(link) => match Cid::try_from(link) { + Ok(cid) => Some(cid.into()), + Err(error) => { + warn!("Could not parse '{}' as name record link: {}", link, error); + None } - } + }, None => { - warn!("No 'link' field in fact, skipping..."); - continue; + warn!("Link record fact value must be a string."); + None } - }, - None => { - warn!("Fact is not an object, skipping..."); - continue; - } + }; } } - warn!("No facts contained a link!"); None } @@ -344,7 +336,6 @@ mod tests { view::{Sphere, SPHERE_LIFETIME}, }; use noosphere_storage::{MemoryStorage, SphereDb, UcanStore}; - use serde_json::json; use ucan::{builder::UcanBuilder, crypto::KeyMaterial, store::UcanJwtStore}; #[cfg(target_arch = "wasm32")] @@ -359,20 +350,21 @@ mod tests { link: &Cid, proofs: Option<&Vec>, ) -> Result { - let capability = generate_capability(sphere_id, SphereAction::Publish); - let fact = json!({ "link": link.to_string() }); + let capability = generate_capability(sphere_id, SphereAbility::Publish); let mut builder = UcanBuilder::default() .issued_by(issuer) .for_audience(sphere_id) .claiming_capability(&capability) - .with_fact(fact); + .with_fact(LINK_RECORD_FACT_NAME, link.to_string()); if let Some(proofs) = proofs { let mut earliest_expiry: u64 = u64::MAX; for token in proofs { - earliest_expiry = *token.expires_at().min(&earliest_expiry); - builder = builder.witnessed_by(token); + if let Some(exp) = token.expires_at() { + earliest_expiry = *exp.min(&earliest_expiry); + builder = builder.witnessed_by(token, None); + } } builder = builder.with_expiration(earliest_expiry); } else { @@ -431,7 +423,7 @@ mod tests { .with_lifetime(SPHERE_LIFETIME) .claiming_capability(&generate_capability( &sphere_identity, - SphereAction::Publish, + SphereAbility::Publish, )) .build()? .sign() @@ -454,10 +446,10 @@ mod tests { .for_audience(&sphere_identity) .claiming_capability(&generate_capability( &sphere_identity, - SphereAction::Publish, + SphereAbility::Publish, )) - .with_fact(json!({ "link": &cid_link.to_string() })) - .witnessed_by(&delegate_ucan) + .with_fact(LINK_RECORD_FACT_NAME, cid_link.to_string()) + .witnessed_by(&delegate_ucan, None) .with_expiration(ucan::time::now() - 1234) .build()? .sign() @@ -486,10 +478,10 @@ mod tests { .for_audience(&sphere_identity) .with_lifetime(1000) .claiming_capability(&generate_capability( - &sphere_identity, - SphereAction::Publish, + sphere_identity.as_str(), + SphereAbility::Publish, )) - .with_fact(json!({ "invalid_fact": cid_address })) + .with_fact("invalid-fact", cid_address.to_owned()) .build()? .sign() .await? @@ -499,7 +491,7 @@ mod tests { let capability = generate_capability( &Did(generate_ed25519_key().get_did().await?), - SphereAction::Publish, + SphereAbility::Publish, ); expect_failure( "fails when capability resource does not match sphere identity", @@ -509,7 +501,7 @@ mod tests { .for_audience(&sphere_identity) .with_lifetime(1000) .claiming_capability(&capability) - .with_fact(json!({ "link": cid_address.clone() })) + .with_fact(LINK_RECORD_FACT_NAME, cid_address.to_owned()) .build()? .sign() .await? @@ -527,9 +519,9 @@ mod tests { .with_lifetime(1000) .claiming_capability(&generate_capability( &sphere_identity, - SphereAction::Publish, + SphereAbility::Publish, )) - .with_fact(json!({ "link": cid_address.clone() })) + .with_fact(LINK_RECORD_FACT_NAME, cid_address.to_owned()) .build()? .sign() .await? @@ -545,18 +537,17 @@ mod tests { async fn test_link_record_convert() -> Result<()> { let sphere_key = generate_ed25519_key(); let identity = Did::from(sphere_key.get_did().await?); - let capability = generate_capability(&identity, SphereAction::Publish); + let capability = generate_capability(&identity, SphereAbility::Publish); let cid_address = "bafyr4iagi6t6khdrtbhmyjpjgvdlwv6pzylxhuhstxhkdp52rju7er325i"; let link = Cid::from_str(cid_address)?; let maybe_link = Some(link.into()); - let fact = json!({ "link": cid_address }); let ucan = UcanBuilder::default() .issued_by(&sphere_key) .for_audience(&identity) .with_lifetime(1000) .claiming_capability(&capability) - .with_fact(fact) + .with_fact(LINK_RECORD_FACT_NAME, cid_address.to_owned()) .build()? .sign() .await?; @@ -678,10 +669,10 @@ mod tests { let delegated_ucan = UcanBuilder::default() .issued_by(&owner_key) .for_audience(&delegatee_did) - .witnessed_by(&ucan) + .witnessed_by(&ucan, None) .claiming_capability(&generate_capability( &sphere_identity, - SphereAction::Publish, + SphereAbility::Publish, )) .with_lifetime(120) .build()? @@ -691,15 +682,13 @@ mod tests { let link_record_ucan = UcanBuilder::default() .issued_by(&delegatee_key) .for_audience(&sphere_identity) - .witnessed_by(&delegated_ucan) + .witnessed_by(&delegated_ucan, None) .claiming_capability(&generate_capability( &sphere_identity, - SphereAction::Publish, + SphereAbility::Publish, )) .with_lifetime(120) - .with_fact(json!({ - "link": sphere.cid().to_string() - })) + .with_fact(LINK_RECORD_FACT_NAME, sphere.cid().to_string()) .build()? .sign() .await?; diff --git a/rust/noosphere-core/src/data/sphere.rs b/rust/noosphere-core/src/data/sphere.rs index c2f1bd6a5..25ec203c9 100644 --- a/rust/noosphere-core/src/data/sphere.rs +++ b/rust/noosphere-core/src/data/sphere.rs @@ -60,18 +60,13 @@ mod tests { use anyhow::Result; use ed25519_zebra::{SigningKey as Ed25519PrivateKey, VerificationKey as Ed25519PublicKey}; use libipld_cbor::DagCborCodec; - use ucan::{ - builder::UcanBuilder, - capability::{Capability, Resource, With}, - crypto::KeyMaterial, - store::UcanJwtStore, - }; + use ucan::{builder::UcanBuilder, crypto::KeyMaterial, store::UcanJwtStore}; use ucan_key_support::ed25519::Ed25519KeyMaterial; #[cfg(target_arch = "wasm32")] use wasm_bindgen_test::wasm_bindgen_test; use crate::{ - authority::{SphereAction, SphereReference}, + authority::{generate_capability, SphereAbility}, data::{ContentType, Did, Header, MemoIpld, SphereIpld}, view::Sphere, }; @@ -105,14 +100,7 @@ mod tests { body: sphere_cid, }; - let capability: Capability = Capability { - with: With::Resource { - kind: Resource::Scoped(SphereReference { - did: identity.to_string(), - }), - }, - can: SphereAction::Authorize, - }; + let capability = generate_capability(&identity, SphereAbility::Authorize); let authorization = UcanBuilder::default() .issued_by(&identity_credential) @@ -161,15 +149,7 @@ mod tests { body: sphere_cid, }; - let capability: Capability = Capability { - with: With::Resource { - kind: Resource::Scoped(SphereReference { - did: identity.to_string(), - }), - }, - can: SphereAction::Authorize, - }; - + let capability = generate_capability(&identity, SphereAbility::Authorize); let authorization = UcanBuilder::default() .issued_by(&identity_credential) .for_audience(&authorized) diff --git a/rust/noosphere-core/src/view/mutation.rs b/rust/noosphere-core/src/view/mutation.rs index 0b7ae07fe..a96a10b20 100644 --- a/rust/noosphere-core/src/view/mutation.rs +++ b/rust/noosphere-core/src/view/mutation.rs @@ -3,7 +3,7 @@ use libipld_cbor::DagCborCodec; use ucan::{builder::UcanBuilder, crypto::KeyMaterial}; use crate::{ - authority::{generate_capability, Authorization, SphereAction}, + authority::{generate_capability, Authorization, SphereAbility}, data::{ ChangelogIpld, DelegationIpld, Did, IdentityIpld, Jwt, Link, MapOperation, MemoIpld, RevocationIpld, VersionedMapKey, VersionedMapValue, @@ -49,10 +49,10 @@ impl SphereRevision { .issued_by(credential) .for_audience(&self.sphere_identity) .with_lifetime(120) - .witnessed_by(&witness_ucan) + .witnessed_by(&witness_ucan, None) .claiming_capability(&generate_capability( &self.sphere_identity, - SphereAction::Publish, + SphereAbility::Publish, )) .with_nonce() .build()? diff --git a/rust/noosphere-core/src/view/sphere.rs b/rust/noosphere-core/src/view/sphere.rs index 67389a78b..120cc1b76 100644 --- a/rust/noosphere-core/src/view/sphere.rs +++ b/rust/noosphere-core/src/view/sphere.rs @@ -8,7 +8,6 @@ use tokio_stream::StreamExt; use ucan::{ builder::UcanBuilder, - capability::{Capability, Resource, With}, chain::ProofChain, crypto::{did::DidParser, KeyMaterial}, store::UcanJwtStore, @@ -18,7 +17,7 @@ use ucan::{ use crate::{ authority::{ ed25519_key_to_mnemonic, generate_capability, generate_ed25519_key, restore_ed25519_key, - Authorization, SphereAction, SphereReference, SPHERE_SEMANTICS, SUPPORTED_KEYS, + Authorization, SphereAbility, SPHERE_SEMANTICS, SUPPORTED_KEYS, }, data::{ Bundle, ChangelogIpld, ContentType, DelegationIpld, Did, Header, IdentityIpld, Link, @@ -620,15 +619,7 @@ impl Sphere { memo.headers .push((Header::Version.to_string(), Version::V0.to_string())); - let capability = Capability { - with: With::Resource { - kind: Resource::Scoped(SphereReference { - did: sphere_did.to_string(), - }), - }, - can: SphereAction::Authorize, - }; - + let capability = generate_capability(&sphere_did, SphereAbility::Authorize); let ucan = UcanBuilder::default() .issued_by(&sphere_key) .for_audience(owner_did) @@ -702,15 +693,7 @@ impl Sphere { } }; - let authorize_capability = Capability { - with: With::Resource { - kind: Resource::Scoped(SphereReference { - did: sphere_did.to_string(), - }), - }, - can: SphereAction::Authorize, - }; - + let authorize_capability = generate_capability(&sphere_did, SphereAbility::Authorize); let mut proof_is_valid = false; for info in proof_chain.reduce_capabilities(&SPHERE_SEMANTICS) { @@ -824,16 +807,16 @@ impl Sphere { // Check the proof's provenance and that it enables the signer to sign let now_time = if let Some(nbf) = ucan.not_before() { - nbf.to_owned() + Some(nbf.to_owned()) } else { - ucan.expires_at() - 1 + ucan.expires_at().as_ref().map(|exp| exp - 1) }; let ucan_store = UcanStore(self.store.clone()); - let proof = - ProofChain::from_ucan(ucan, Some(now_time), &mut did_parser, &ucan_store).await?; + let proof = ProofChain::from_ucan(ucan, now_time, &mut did_parser, &ucan_store).await?; - let desired_capability = generate_capability(&sphere_ipld.identity, SphereAction::Push); + let desired_capability = + generate_capability(&sphere_ipld.identity, SphereAbility::Push); for capability_info in proof.reduce_capabilities(&SPHERE_SEMANTICS) { let capability = capability_info.capability; @@ -924,7 +907,6 @@ mod tests { use tokio_stream::StreamExt; use ucan::{ builder::UcanBuilder, - capability::{Capability, Resource, With}, crypto::{did::DidParser, KeyMaterial}, }; @@ -934,15 +916,15 @@ mod tests { #[cfg(target_arch = "wasm32")] wasm_bindgen_test::wasm_bindgen_test_configure!(run_in_browser); + use super::*; use crate::{ authority::{ - ed25519_key_to_mnemonic, generate_ed25519_key, Authorization, SphereAction, - SphereReference, SUPPORTED_KEYS, + ed25519_key_to_mnemonic, generate_ed25519_key, Authorization, SphereAbility, + SUPPORTED_KEYS, }, data::{Bundle, DelegationIpld, IdentityIpld, Link, MemoIpld, RevocationIpld}, view::{Sphere, SphereMutation, Timeline}, }; - use noosphere_storage::{BlockStore, MemoryStore, Store, UcanStore}; #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] @@ -1114,16 +1096,12 @@ mod tests { UcanBuilder::default() .issued_by(&owner_key) .for_audience(&next_owner_did) - .claiming_capability(&Capability { - with: With::Resource { - kind: Resource::Scoped(SphereReference { - did: sphere.get_identity().await.unwrap().to_string(), - }), - }, - can: SphereAction::Publish, - }) - .witnessed_by(&ucan) - .with_expiration(*ucan.expires_at()) + .claiming_capability(&generate_capability( + &sphere.get_identity().await.unwrap().to_string(), + SphereAbility::Publish, + )) + .witnessed_by(&ucan, None) + .with_expiration(ucan.expires_at().unwrap()) .build() .unwrap() .sign() diff --git a/rust/noosphere-gateway/src/authority.rs b/rust/noosphere-gateway/src/authority.rs index 445ea97bd..907d09552 100644 --- a/rust/noosphere-gateway/src/authority.rs +++ b/rust/noosphere-gateway/src/authority.rs @@ -9,12 +9,14 @@ use axum::{ TypedHeader, }; use libipld_core::cid::Cid; -use noosphere_core::authority::{SphereAction, SphereReference, SPHERE_SEMANTICS}; +use noosphere_core::authority::{SphereAbility, SphereReference, SPHERE_SEMANTICS}; use noosphere_sphere::SphereContext; use noosphere_storage::NativeStorage; use tokio::sync::Mutex; -use ucan::{capability::Capability, chain::ProofChain, crypto::KeyMaterial, store::UcanJwtStore}; +use ucan::{ + capability::CapabilityView, chain::ProofChain, crypto::KeyMaterial, store::UcanJwtStore, +}; use super::GatewayScope; @@ -38,7 +40,7 @@ where { pub fn try_authorize( &self, - capability: &Capability, + capability: &CapabilityView, ) -> Result<(), StatusCode> { let capability_infos = self.proof.reduce_capabilities(&SPHERE_SEMANTICS); diff --git a/rust/noosphere-gateway/src/route/fetch.rs b/rust/noosphere-gateway/src/route/fetch.rs index 47832b411..b105be019 100644 --- a/rust/noosphere-gateway/src/route/fetch.rs +++ b/rust/noosphere-gateway/src/route/fetch.rs @@ -6,7 +6,7 @@ use axum::{body::StreamBody, extract::Query, http::StatusCode, Extension}; use bytes::Bytes; use noosphere_api::data::FetchParameters; use noosphere_core::{ - authority::{SphereAction, SphereReference}, + authority::{generate_capability, SphereAbility}, data::{Link, MemoIpld}, view::Sphere, }; @@ -14,10 +14,7 @@ use noosphere_ipfs::{IpfsStore, KuboClient}; use noosphere_sphere::{car_stream, memo_history_stream, HasSphereContext}; use noosphere_storage::{BlockStoreRetry, SphereDb, Storage}; use tokio_stream::{Stream, StreamExt}; -use ucan::{ - capability::{Capability, Resource, With}, - crypto::KeyMaterial, -}; +use ucan::crypto::KeyMaterial; use crate::{authority::GatewayAuthority, GatewayScope}; @@ -34,14 +31,10 @@ where K: KeyMaterial + Clone, S: Storage + 'static, { - authority.try_authorize(&Capability { - with: With::Resource { - kind: Resource::Scoped(SphereReference { - did: scope.counterpart.to_string(), - }), - }, - can: SphereAction::Fetch, - })?; + authority.try_authorize(&generate_capability( + &scope.counterpart, + SphereAbility::Fetch, + ))?; let sphere_context = sphere_context.sphere_context().await.map_err(|err| { error!("{err}"); StatusCode::INTERNAL_SERVER_ERROR diff --git a/rust/noosphere-gateway/src/route/identify.rs b/rust/noosphere-gateway/src/route/identify.rs index a1fe39337..560a88a2f 100644 --- a/rust/noosphere-gateway/src/route/identify.rs +++ b/rust/noosphere-gateway/src/route/identify.rs @@ -1,7 +1,7 @@ use crate::{authority::GatewayAuthority, GatewayScope}; use axum::{http::StatusCode, response::IntoResponse, Extension, Json}; use noosphere_api::data::IdentifyResponse; -use noosphere_core::authority::{generate_capability, SphereAction}; +use noosphere_core::authority::{generate_capability, SphereAbility}; use noosphere_sphere::HasSphereContext; use noosphere_storage::Storage; use ucan::crypto::KeyMaterial; @@ -20,7 +20,7 @@ where authority.try_authorize(&generate_capability( &scope.counterpart, - SphereAction::Fetch, + SphereAbility::Fetch, ))?; let sphere_context = sphere_context diff --git a/rust/noosphere-gateway/src/route/push.rs b/rust/noosphere-gateway/src/route/push.rs index fa0d71a84..1cb3a2307 100644 --- a/rust/noosphere-gateway/src/route/push.rs +++ b/rust/noosphere-gateway/src/route/push.rs @@ -6,7 +6,7 @@ use axum::{http::StatusCode, Extension}; use noosphere_api::data::{PushBody, PushError, PushResponse}; use noosphere_core::{ - authority::{SphereAction, SphereReference}, + authority::{generate_capability, SphereAbility}, data::{Bundle, Link, LinkRecord, MapOperation, MemoIpld}, view::Sphere, }; @@ -14,7 +14,6 @@ use noosphere_sphere::{HasMutableSphereContext, SphereContentWrite, SphereCursor use noosphere_storage::Storage; use tokio::sync::mpsc::UnboundedSender; use tokio_stream::StreamExt; -use ucan::capability::{Capability, Resource, With}; use ucan::crypto::KeyMaterial; use crate::{ @@ -57,14 +56,10 @@ where return Err(StatusCode::FORBIDDEN); } - authority.try_authorize(&Capability { - with: With::Resource { - kind: Resource::Scoped(SphereReference { - did: gateway_scope.counterpart.to_string(), - }), - }, - can: SphereAction::Push, - })?; + authority.try_authorize(&generate_capability( + &gateway_scope.counterpart, + SphereAbility::Push, + ))?; let gateway_push_routine = GatewayPushRoutine { sphere_context, diff --git a/rust/noosphere-gateway/src/route/replicate.rs b/rust/noosphere-gateway/src/route/replicate.rs index 7c3d15440..4d6a34a52 100644 --- a/rust/noosphere-gateway/src/route/replicate.rs +++ b/rust/noosphere-gateway/src/route/replicate.rs @@ -12,7 +12,7 @@ use cid::Cid; use libipld_cbor::DagCborCodec; use noosphere_api::data::ReplicateParameters; use noosphere_core::{ - authority::{generate_capability, SphereAction}, + authority::{generate_capability, SphereAbility}, data::{ContentType, MemoIpld}, }; use noosphere_ipfs::{IpfsStore, KuboClient}; @@ -58,7 +58,7 @@ where authority.try_authorize(&generate_capability( &scope.counterpart, - SphereAction::Fetch, + SphereAbility::Fetch, ))?; let db = sphere_context @@ -167,7 +167,7 @@ mod tests { use anyhow::Result; use noosphere_core::{ authority::{ - generate_capability, generate_ed25519_key, Author, Authorization, SphereAction, + generate_capability, generate_ed25519_key, Author, Authorization, SphereAbility, }, data::{DelegationIpld, RevocationIpld}, }; @@ -288,9 +288,9 @@ mod tests { .for_audience(&to_be_revoked_did) .claiming_capability(&generate_capability( &sphere_context.identity().await?, - SphereAction::Publish, + SphereAbility::Publish, )) - .witnessed_by(&author_ucan) + .witnessed_by(&author_ucan, None) .with_lifetime(6000) .with_nonce() .build()? diff --git a/rust/noosphere-gateway/src/worker/name_system.rs b/rust/noosphere-gateway/src/worker/name_system.rs index ec7ddd0d9..09f5e55a8 100644 --- a/rust/noosphere-gateway/src/worker/name_system.rs +++ b/rust/noosphere-gateway/src/worker/name_system.rs @@ -499,10 +499,12 @@ where #[cfg(test)] mod tests { - use noosphere_core::authority::{generate_capability, SphereAction}; + use noosphere_core::{ + authority::{generate_capability, SphereAbility}, + data::LINK_RECORD_FACT_NAME, + }; use noosphere_ns::helpers::KeyValueNameResolver; use noosphere_sphere::helpers::{simulated_sphere_context, SimulationAccess}; - use serde_json::json; use ucan::builder::UcanBuilder; use super::*; @@ -517,10 +519,11 @@ mod tests { UcanBuilder::default() .issued_by(&context.author().key) .for_audience(identity) - .claiming_capability(&generate_capability(identity, SphereAction::Publish)) + .claiming_capability(&generate_capability(identity, SphereAbility::Publish)) .with_lifetime(1000) .with_fact( - json!({ "link": "bafyr4iagi6t6khdrtbhmyjpjgvdlwv6pzylxhuhstxhkdp52rju7er325i" }), + LINK_RECORD_FACT_NAME, + "bafyr4iagi6t6khdrtbhmyjpjgvdlwv6pzylxhuhstxhkdp52rju7er325i".to_owned(), ) .build() .unwrap() @@ -536,10 +539,11 @@ mod tests { UcanBuilder::default() .issued_by(&context.author().key) .for_audience(identity) - .claiming_capability(&generate_capability(identity, SphereAction::Publish)) + .claiming_capability(&generate_capability(identity, SphereAbility::Publish)) .with_expiration(ucan::time::now() - 1000) .with_fact( - json!({ "link": "bafyr4iagi6t6khdrtbhmyjpjgvdlwv6pzylxhuhstxhkdp52rju7er325i" }), + LINK_RECORD_FACT_NAME, + "bafyr4iagi6t6khdrtbhmyjpjgvdlwv6pzylxhuhstxhkdp52rju7er325i".to_owned(), ) .build() .unwrap() diff --git a/rust/noosphere-ns/src/bin/orb-ns/cli/mod.rs b/rust/noosphere-ns/src/bin/orb-ns/cli/mod.rs index 90d07d2f6..8301b6f7c 100644 --- a/rust/noosphere-ns/src/bin/orb-ns/cli/mod.rs +++ b/rust/noosphere-ns/src/bin/orb-ns/cli/mod.rs @@ -12,12 +12,11 @@ mod test { use anyhow::Result; use cid::Cid; use noosphere::key::{InsecureKeyStorage, KeyStorage}; - use noosphere_core::authority::{generate_capability, SphereAction}; - use noosphere_core::data::{Did, LinkRecord}; + use noosphere_core::authority::{generate_capability, SphereAbility}; + use noosphere_core::data::{Did, LinkRecord, LINK_RECORD_FACT_NAME}; use noosphere_core::view::SPHERE_LIFETIME; use noosphere_ns::{Multiaddr, PeerId}; use serde::Deserialize; - use serde_json::json; use tokio; use tokio::sync::oneshot; use ucan::builder::UcanBuilder; @@ -126,8 +125,8 @@ mod test { let ucan = UcanBuilder::default() .issued_by(&key_b) .for_audience(&id_b) - .claiming_capability(&generate_capability(&id_b, SphereAction::Publish)) - .with_fact(json!({ "link": cid_link.to_string() })) + .claiming_capability(&generate_capability(&id_b, SphereAbility::Publish)) + .with_fact(LINK_RECORD_FACT_NAME, cid_link.to_string()) .with_lifetime(SPHERE_LIFETIME) .build()? .sign() diff --git a/rust/noosphere-ns/src/dht_client.rs b/rust/noosphere-ns/src/dht_client.rs index be9c59577..9dcd0729a 100644 --- a/rust/noosphere-ns/src/dht_client.rs +++ b/rust/noosphere-ns/src/dht_client.rs @@ -97,13 +97,12 @@ pub mod test { use cid::Cid; use libp2p::multiaddr::Protocol; use noosphere_core::{ - authority::{generate_capability, generate_ed25519_key, SphereAction}, - data::Did, + authority::{generate_capability, generate_ed25519_key, SphereAbility}, + data::{Did, LINK_RECORD_FACT_NAME}, tracing::initialize_tracing, view::SPHERE_LIFETIME, }; use noosphere_storage::{MemoryStorage, SphereDb}; - use serde_json::json; use std::sync::Arc; use tokio::sync::Mutex; use ucan::{builder::UcanBuilder, crypto::KeyMaterial}; @@ -179,9 +178,9 @@ pub mod test { .for_audience(&sphere_identity) .claiming_capability(&generate_capability( &sphere_identity, - SphereAction::Publish, + SphereAbility::Publish, )) - .with_fact(json!({ "link": link.to_string() })) + .with_fact(LINK_RECORD_FACT_NAME, link.to_string()) .with_lifetime(SPHERE_LIFETIME) .build()? .sign() diff --git a/rust/noosphere-ns/src/name_resolver.rs b/rust/noosphere-ns/src/name_resolver.rs index e0e6cdc60..9489f9c20 100644 --- a/rust/noosphere-ns/src/name_resolver.rs +++ b/rust/noosphere-ns/src/name_resolver.rs @@ -43,12 +43,11 @@ pub mod test { use super::*; use cid::Cid; use noosphere_core::{ - authority::{generate_capability, generate_ed25519_key, SphereAction}, - data::Did, + authority::{generate_capability, generate_ed25519_key, SphereAbility}, + data::{Did, LINK_RECORD_FACT_NAME}, tracing::initialize_tracing, view::SPHERE_LIFETIME, }; - use serde_json::json; use ucan::{builder::UcanBuilder, crypto::KeyMaterial}; pub async fn test_name_resolver_simple(resolver: N) -> Result<()> { @@ -63,9 +62,9 @@ pub mod test { .for_audience(&sphere_identity) .claiming_capability(&generate_capability( &sphere_identity, - SphereAction::Publish, + SphereAbility::Publish, )) - .with_fact(json!({ "link": link.to_string() })) + .with_fact(LINK_RECORD_FACT_NAME, link.to_string()) .with_lifetime(SPHERE_LIFETIME) .build()? .sign() diff --git a/rust/noosphere-ns/tests/ns_test.rs b/rust/noosphere-ns/tests/ns_test.rs index e232a6d1d..c95fdb9ab 100644 --- a/rust/noosphere-ns/tests/ns_test.rs +++ b/rust/noosphere-ns/tests/ns_test.rs @@ -4,8 +4,8 @@ use anyhow::Result; use cid::Cid; use noosphere_core::{ - authority::{generate_capability, generate_ed25519_key, SphereAction}, - data::Did, + authority::{generate_capability, generate_ed25519_key, SphereAbility}, + data::{Did, LINK_RECORD_FACT_NAME}, tracing::initialize_tracing, view::SPHERE_LIFETIME, }; @@ -13,7 +13,6 @@ use noosphere_ns::{helpers::NameSystemNetwork, DhtClient}; use noosphere_storage::{derive_cid, MemoryStorage, SphereDb}; use libipld_cbor::DagCborCodec; -use serde_json::json; use ucan::{builder::UcanBuilder, crypto::KeyMaterial, store::UcanJwtStore, time::now, Ucan}; use ucan_key_support::ed25519::Ed25519KeyMaterial; @@ -35,7 +34,7 @@ impl PseudoSphere { let sphere_id = Did(sphere_key.get_did().await?); // Delegate `sphere_key`'s publishing authority to `owner_key` - let delegate_capability = generate_capability(&sphere_id, SphereAction::Publish); + let delegate_capability = generate_capability(&sphere_id, SphereAbility::Publish); let delegation = UcanBuilder::default() .issued_by(&sphere_key) .for_audience(&owner_id) @@ -57,9 +56,12 @@ impl PseudoSphere { UcanBuilder::default() .issued_by(&self.owner_key) .for_audience(&self.sphere_id) - .claiming_capability(&generate_capability(&self.sphere_id, SphereAction::Publish)) - .with_fact(json!({ "link": &cid.to_string() })) - .witnessed_by(&self.delegation) + .claiming_capability(&generate_capability( + &self.sphere_id, + SphereAbility::Publish, + )) + .with_fact(LINK_RECORD_FACT_NAME, cid.to_string()) + .witnessed_by(&self.delegation, None) } pub async fn write_proofs_to_store(&self, store: &mut S) -> Result<()> { @@ -90,7 +92,7 @@ async fn test_name_system_peer_propagation() -> Result<()> { ns_1.put_record( sphere_1 .generate_record(sphere_1_cid_1) - .with_expiration(*sphere_1.delegation.expires_at()) + .with_expiration(sphere_1.delegation.expires_at().unwrap()) .build()? .sign() .await? @@ -120,7 +122,7 @@ async fn test_name_system_peer_propagation() -> Result<()> { ns_1.put_record( sphere_1 .generate_record(sphere_1_cid_2) - .with_expiration(*sphere_1.delegation.expires_at()) + .with_expiration(sphere_1.delegation.expires_at().unwrap()) .build()? .sign() .await? @@ -143,7 +145,7 @@ async fn test_name_system_peer_propagation() -> Result<()> { ns_2.put_record( sphere_2 .generate_record(sphere_2_cid_1) - .with_expiration(*sphere_2.delegation.expires_at()) + .with_expiration(sphere_2.delegation.expires_at().unwrap()) .build()? .sign() .await? diff --git a/rust/noosphere-sphere/src/context.rs b/rust/noosphere-sphere/src/context.rs index 0e4b1af25..37b76d497 100644 --- a/rust/noosphere-sphere/src/context.rs +++ b/rust/noosphere-sphere/src/context.rs @@ -237,8 +237,8 @@ mod tests { use anyhow::Result; use noosphere_core::{ - authority::{generate_capability, SphereAction}, - data::{ContentType, LinkRecord}, + authority::{generate_capability, SphereAbility}, + data::{ContentType, LinkRecord, LINK_RECORD_FACT_NAME}, tracing::initialize_tracing, }; @@ -250,7 +250,6 @@ mod tests { helpers::{make_valid_link_record, simulated_sphere_context, SimulationAccess}, HasMutableSphereContext, HasSphereContext, SphereContentWrite, SpherePetnameWrite, }; - use serde_json::json; #[cfg(target_arch = "wasm32")] wasm_bindgen_test::wasm_bindgen_test_configure!(run_in_browser); @@ -344,15 +343,14 @@ mod tests { .unwrap() .resolve_ucan(&db) .await?, + None, ) .claiming_capability(&generate_capability( &sphere_identity, - SphereAction::Publish, + SphereAbility::Publish, )) .with_lifetime(120) - .with_fact(json!({ - "link": version.to_string() - })) + .with_fact(LINK_RECORD_FACT_NAME, version.to_string()) .build()? .sign() .await?, diff --git a/rust/noosphere-sphere/src/helpers.rs b/rust/noosphere-sphere/src/helpers.rs index cb3958a3b..360e9697b 100644 --- a/rust/noosphere-sphere/src/helpers.rs +++ b/rust/noosphere-sphere/src/helpers.rs @@ -4,12 +4,11 @@ use std::sync::Arc; use anyhow::Result; use noosphere_core::{ - authority::{generate_capability, generate_ed25519_key, Author, SphereAction}, - data::{ContentType, Did, Link, LinkRecord}, + authority::{generate_capability, generate_ed25519_key, Author, SphereAbility}, + data::{ContentType, Did, Link, LinkRecord, LINK_RECORD_FACT_NAME}, view::Sphere, }; use noosphere_storage::{BlockStore, MemoryStorage, SphereDb, TrackingStorage, UcanStore}; -use serde_json::json; use tokio::{io::AsyncReadExt, sync::Mutex}; use ucan::{builder::UcanBuilder, crypto::KeyMaterial, store::UcanJwtStore}; use ucan_key_support::ed25519::Ed25519KeyMaterial; @@ -82,15 +81,13 @@ where UcanBuilder::default() .issued_by(&owner_key) .for_audience(&sphere_identity) - .witnessed_by(&ucan_proof) + .witnessed_by(&ucan_proof, None) .claiming_capability(&generate_capability( &sphere_identity, - SphereAction::Publish, + SphereAbility::Publish, )) .with_lifetime(120) - .with_fact(json!({ - "link": sphere.cid().to_string() - })) + .with_fact(LINK_RECORD_FACT_NAME, sphere.cid().to_string()) .build()? .sign() .await?, @@ -215,15 +212,14 @@ pub async fn make_sphere_context_with_peer_chain( .resolve_ucan(&db) .await .unwrap(), + None, ) .claiming_capability(&generate_capability( &next_identity, - SphereAction::Publish, + SphereAbility::Publish, )) .with_lifetime(120) - .with_fact(json!({ - "link": version.to_string() - })) + .with_fact(LINK_RECORD_FACT_NAME, version.to_string()) .build() .unwrap() .sign() diff --git a/rust/noosphere-sphere/src/sync/strategy.rs b/rust/noosphere-sphere/src/sync/strategy.rs index 59891e3e6..6a97bcb27 100644 --- a/rust/noosphere-sphere/src/sync/strategy.rs +++ b/rust/noosphere-sphere/src/sync/strategy.rs @@ -3,18 +3,13 @@ use std::{collections::BTreeMap, marker::PhantomData}; use anyhow::{anyhow, Result}; use noosphere_api::data::{FetchParameters, PushBody, PushResponse}; use noosphere_core::{ - authority::{SphereAction, SphereReference}, - data::{Did, IdentityIpld, Jwt, Link, MemoIpld}, + authority::{generate_capability, SphereAbility}, + data::{Did, IdentityIpld, Jwt, Link, MemoIpld, LINK_RECORD_FACT_NAME}, view::{Sphere, Timeline}, }; use noosphere_storage::{KeyValueStore, SphereDb, Storage}; -use serde_json::json; use tokio_stream::StreamExt; -use ucan::{ - builder::UcanBuilder, - capability::{Capability, Resource, With}, - crypto::KeyMaterial, -}; +use ucan::{builder::UcanBuilder, crypto::KeyMaterial}; use crate::{ metadata::COUNTERPART, HasMutableSphereContext, SpherePetnameRead, SpherePetnameWrite, @@ -355,19 +350,13 @@ where let name_record = Jwt(UcanBuilder::default() .issued_by(&context.author().key) .for_audience(local_sphere_identity) - .witnessed_by(&authorization) - .claiming_capability(&Capability { - with: With::Resource { - kind: Resource::Scoped(SphereReference { - did: local_sphere_identity.to_string(), - }), - }, - can: SphereAction::Publish, - }) + .witnessed_by(&authorization, None) + .claiming_capability(&generate_capability( + local_sphere_identity, + SphereAbility::Publish, + )) .with_lifetime(120) - .with_fact(json!({ - "link": local_sphere_tip.to_string() - })) + .with_fact(LINK_RECORD_FACT_NAME, local_sphere_tip.to_string()) .build()? .sign() .await?