Skip to content
This repository has been archived by the owner on Sep 21, 2024. It is now read-only.

Commit

Permalink
feat: SphereFs is initialized with key material (#140)
Browse files Browse the repository at this point in the history
BREAKING CHANGE: Many APIs that previously asked for bare strings when a
DID string was expected now expect a newtype called `Did` that wraps a
string.

BREAKING CHANGE: APIs that previously expected both a `KeyMaterial` and
an `Authorization` now expect a consolidated construct called an
`Author` that pairs these two things.
  • Loading branch information
cdata authored Nov 13, 2022
1 parent abf9cf6 commit af48061
Show file tree
Hide file tree
Showing 30 changed files with 537 additions and 340 deletions.
30 changes: 12 additions & 18 deletions rust/noosphere-api/src/client.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ use anyhow::Result;
use cid::Cid;
use libipld_cbor::DagCborCodec;

use noosphere_core::authority::{Authorization, SphereAction, SphereReference};
use noosphere_core::authority::{Author, SphereAction, SphereReference};
use noosphere_storage::encoding::{block_deserialize, block_serialize};
use reqwest::{header::HeaderMap, Body};
use ucan::{
Expand All @@ -23,28 +23,26 @@ use url::Url;

pub struct Client<K, S>
where
K: KeyMaterial + 'static,
K: KeyMaterial + Clone + 'static,
S: UcanStore,
{
pub session: IdentifyResponse,
pub sphere_identity: String,
pub api_base: Url,
pub credential: K,
pub authorization: Authorization,
pub author: Author<K>,
pub store: S,
client: reqwest::Client,
}

impl<K, S> Client<K, S>
where
K: KeyMaterial + 'static,
K: KeyMaterial + Clone + 'static,
S: UcanStore,
{
pub async fn identify(
sphere_identity: &str,
api_base: &Url,
credential: K,
authorization: &Authorization,
author: &Author<K>,
did_parser: &mut DidParser,
store: S,
) -> Result<Client<K, S>> {
Expand All @@ -64,8 +62,7 @@ where

let (jwt, ucan_headers) = Self::make_bearer_token(
&gateway_identity,
&credential,
authorization,
author,
&Capability {
with: With::Resource {
kind: Resource::Scoped(SphereReference {
Expand Down Expand Up @@ -98,22 +95,20 @@ where
session: identify_response,
sphere_identity: sphere_identity.into(),
api_base: api_base.clone(),
credential,
authorization: authorization.clone(),
author: author.clone(),
store,
client,
})
}

async fn make_bearer_token(
gateway_identity: &str,
credential: &K,
authorization: &Authorization,
author: &Author<K>,
capability: &Capability<SphereReference, SphereAction>,
store: &S,
) -> Result<(String, HeaderMap)> {
let mut signable = UcanBuilder::default()
.issued_by(credential)
.issued_by(&author.key)
.for_audience(gateway_identity)
.with_lifetime(120)
.claiming_capability(capability)
Expand All @@ -122,6 +117,7 @@ where

let mut ucan_headers = HeaderMap::new();

let authorization = author.require_authorization()?;
let authorization_cid = Cid::try_from(authorization)?;

match authorization.resolve_ucan(store).await {
Expand Down Expand Up @@ -180,8 +176,7 @@ where

let (token, ucan_headers) = Self::make_bearer_token(
&self.session.gateway_identity,
&self.credential,
&self.authorization,
&self.author,
&capability,
&self.store,
)
Expand Down Expand Up @@ -219,8 +214,7 @@ where

let (token, ucan_headers) = Self::make_bearer_token(
&self.session.gateway_identity,
&self.credential,
&self.authorization,
&self.author,
&capability,
&self.store,
)
Expand Down
2 changes: 1 addition & 1 deletion rust/noosphere-cli/src/native/commands/auth.rs
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@ You will be able to add a new one after the old one is revoked"#,
.claiming_capability(&Capability {
with: With::Resource {
kind: Resource::Scoped(SphereReference {
did: sphere_did.clone(),
did: sphere_did.to_string(),
}),
},
can: SphereAction::Authorize,
Expand Down
14 changes: 7 additions & 7 deletions rust/noosphere-cli/src/native/commands/save.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,9 @@ use anyhow::{anyhow, Result};
use cid::Cid;
use globset::Glob;
use libipld_cbor::DagCborCodec;
use noosphere_core::data::Header;
use noosphere_core::{authority::Author, data::Header};
use noosphere_fs::SphereFs;
use noosphere_storage::{interface::BlockStore, memory::MemoryStore};
use ucan::crypto::KeyMaterial;

use crate::native::workspace::{FileReference, Workspace};

Expand Down Expand Up @@ -37,13 +36,14 @@ pub async fn save(matching: Option<Glob>, workspace: &Workspace) -> Result<()> {
db.put_links::<DagCborCodec>(&cid, block).await?;
}

let my_key = workspace.get_local_key().await?;
let my_did = my_key.get_did().await?;
let sphere_did = workspace.get_local_identity().await?;
let latest_sphere_cid = db.require_version(&sphere_did).await?;
let authorization = workspace.get_local_authorization().await?;
let author = Author {
key: workspace.get_local_key().await?,
authorization: Some(workspace.get_local_authorization().await?),
};

let mut fs = SphereFs::at(&sphere_did, &latest_sphere_cid, Some(&my_did), &db);
let mut fs = SphereFs::at(&sphere_did, &latest_sphere_cid, &author, &db).await?;

for (slug, _) in content_changes
.new
Expand Down Expand Up @@ -71,7 +71,7 @@ pub async fn save(matching: Option<Glob>, workspace: &Workspace) -> Result<()> {
fs.remove(slug).await?;
}

let cid = fs.save(&my_key, Some(&authorization), None).await?;
let cid = fs.save(None).await?;

println!("Save complete!\nThe latest sphere revision is {}", cid);
Ok(())
Expand Down
2 changes: 1 addition & 1 deletion rust/noosphere-cli/src/native/commands/serve/authority.rs
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ impl GatewayAuthority {
trace!("Checking capability: {:?}", capability_info.capability);
if capability_info
.originators
.contains(&self.scope.counterpart)
.contains(self.scope.counterpart.as_str())
&& capability_info.capability.enables(capability)
{
debug!("Authorized!");
Expand Down
39 changes: 24 additions & 15 deletions rust/noosphere-cli/src/native/commands/serve/gateway.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ use anyhow::Result;
use axum::http::{HeaderValue, Method};
use axum::routing::{get, put};
use axum::{Extension, Router, Server};
use noosphere_core::data::Did;
use std::net::TcpListener;
use std::sync::Arc;
use tokio::sync::Mutex;
Expand All @@ -20,8 +21,8 @@ use crate::native::commands::serve::tracing::initialize_tracing;

#[derive(Clone, Debug)]
pub struct GatewayScope {
pub identity: String,
pub counterpart: String,
pub identity: Did,
pub counterpart: Did,
}

pub async fn start_gateway<K>(
Expand Down Expand Up @@ -104,7 +105,7 @@ mod tests {
data::{FetchParameters, FetchResponse, PushBody, PushResponse},
};
use noosphere_core::{
authority::SUPPORTED_KEYS,
authority::{Author, SUPPORTED_KEYS},
data::MemoIpld,
view::{Sphere, SphereMutation},
};
Expand Down Expand Up @@ -190,8 +191,10 @@ mod tests {
let client = Client::identify(
&client_sphere_identity,
&api_base,
client_key.clone(),
&client_authorization,
&Author {
key: client_key.clone(),
authorization: Some(client_authorization),
},
&mut did_parser,
client_db,
)
Expand Down Expand Up @@ -276,8 +279,10 @@ mod tests {
let client = Client::identify(
&client_sphere_identity,
&api_base,
client_key.clone(),
&client_authorization,
&Author {
key: client_key.clone(),
authorization: Some(client_authorization),
},
&mut did_parser,
client_db.clone(),
)
Expand All @@ -294,7 +299,7 @@ mod tests {

let push_result = client
.push(&PushBody {
sphere: client_sphere_identity,
sphere: client_sphere_identity.to_string(),
base: None,
tip: *sphere.cid(),
blocks: bundle.clone(),
Expand Down Expand Up @@ -395,8 +400,10 @@ mod tests {
let client = Client::identify(
&client_sphere_identity,
&api_base,
client_key.clone(),
&client_authorization,
&Author {
key: client_key.clone(),
authorization: Some(client_authorization.clone()),
},
&mut did_parser,
client_db.clone(),
)
Expand All @@ -415,7 +422,7 @@ mod tests {

let push_result = client
.push(&PushBody {
sphere: client_sphere_identity.clone(),
sphere: client_sphere_identity.to_string(),
base: None,
tip: *sphere.cid(),
blocks: bundle.clone(),
Expand Down Expand Up @@ -456,7 +463,7 @@ mod tests {

let push_result = client
.push(&PushBody {
sphere: client_sphere_identity,
sphere: client_sphere_identity.to_string(),
base: Some(sphere_cid),
tip: *sphere.cid(),
blocks: bundle,
Expand Down Expand Up @@ -556,8 +563,10 @@ mod tests {
let client = Client::identify(
&client_sphere_identity,
&api_base,
client_key.clone(),
&client_authorization,
&Author {
key: client_key.clone(),
authorization: Some(client_authorization.clone()),
},
&mut did_parser,
client_db.clone(),
)
Expand Down Expand Up @@ -599,7 +608,7 @@ mod tests {

let push_result = client
.push(&PushBody {
sphere: client_sphere_identity,
sphere: client_sphere_identity.to_string(),
base: None,
tip: *sphere.cid(),
blocks: bundle.clone(),
Expand Down
5 changes: 3 additions & 2 deletions rust/noosphere-cli/src/native/commands/serve/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ pub mod route;
pub mod tracing;

use anyhow::{anyhow, Result};
use noosphere_core::data::Did;

use std::net::{IpAddr, TcpListener};

Expand Down Expand Up @@ -32,15 +33,15 @@ pub async fn serve(
let config = Config::from(workspace);

let counterpart = match &config.read().await?.counterpart {
Some(counterpart) => counterpart,
Some(counterpart) => Did(counterpart.clone()),
None => return Err(anyhow!("No counterpart has been configured; you should set it to the DID of the sphere you are personally saving content to: orb config set counterpart <SOME_DID>"))
};

let identity = workspace.get_local_identity().await?;

let gateway_scope = GatewayScope {
identity,
counterpart: counterpart.clone(),
counterpart,
};

gateway::start_gateway(
Expand Down
34 changes: 16 additions & 18 deletions rust/noosphere-cli/src/native/commands/sync.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ use noosphere_api::{
data::{FetchParameters, FetchResponse, PushBody, PushResponse},
};
use noosphere_core::{
authority::{Authorization, SUPPORTED_KEYS},
authority::{Author, SUPPORTED_KEYS},
view::Sphere,
};
use noosphere_storage::{db::SphereDb, interface::Store, memory::MemoryStore};
Expand Down Expand Up @@ -34,8 +34,10 @@ pub async fn sync(workspace: &Workspace) -> Result<()> {

let gateway_url = workspace.get_local_gateway_url().await?;

let authorization = workspace.get_local_authorization().await?;
let key = workspace.get_local_key().await?;
let author = Author {
key: workspace.get_local_key().await?,
authorization: Some(workspace.get_local_authorization().await?),
};

let sphere_identity = workspace.get_local_identity().await?;

Expand All @@ -46,21 +48,13 @@ pub async fn sync(workspace: &Workspace) -> Result<()> {
let client = Client::identify(
&sphere_identity,
&gateway_url,
key.clone(),
&authorization,
&author,
&mut did_parser,
db.clone(),
)
.await?;

sync_remote_changes(
&sphere_identity,
&client,
&key,
Some(&authorization),
&mut db,
)
.await?;
sync_remote_changes(&sphere_identity, &client, &author, &mut db).await?;

push_local_changes(&sphere_identity, &client, &mut db).await?;

Expand All @@ -81,7 +75,7 @@ pub async fn push_local_changes<S, K>(
db: &mut SphereDb<S>,
) -> Result<()>
where
K: KeyMaterial,
K: KeyMaterial + Clone + 'static,
S: Store,
{
let local_sphere_identity = local_sphere_identity.to_string();
Expand Down Expand Up @@ -175,12 +169,11 @@ where
pub async fn sync_remote_changes<K, S>(
local_sphere_identity: &str,
client: &Client<K, SphereDb<S>>,
credential: &K,
authorization: Option<&Authorization>,
author: &Author<K>,
db: &mut SphereDb<S>,
) -> Result<()>
where
K: KeyMaterial,
K: KeyMaterial + Clone + 'static,
S: Store,
{
let local_sphere_identity = local_sphere_identity.to_string();
Expand Down Expand Up @@ -247,7 +240,12 @@ where
(Some(current_tip), Some(old_base), Some(new_base)) => {
println!("Syncing received local sphere revisions...");
let new_tip = Sphere::at(&current_tip, db)
.try_sync(&old_base, &new_base, credential, authorization)
.try_sync(
&old_base,
&new_base,
&author.key,
author.authorization.as_ref(),
)
.await?;

db.set_version(&local_sphere_identity, &new_tip).await?;
Expand Down
Loading

0 comments on commit af48061

Please sign in to comment.