Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion rustdocs/source_json/willow25.json

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion rustdocs/source_json/willow_data_model.json

Large diffs are not rendered by default.

50 changes: 17 additions & 33 deletions src/code_samples/tut_caps/01.rs
Original file line number Diff line number Diff line change
@@ -1,37 +1,21 @@
use willow_25::{
AccessMode, Area, AreaSubspace, Capability, NamespaceId25, Path, Range, SubspaceId25,
};
use rand::rngs::OsRng;
use willow25::prelude::*;

fn main() {
// Owned capabilities

let (alfie_id, alfie_key) = SubspaceId25::new();
let (my_namespace, my_namespace_secret) = NamespaceId25::new_owned();

let root_cap = Capability::new_owned(
my_namespace,
&my_namespace_secret,
alfie_id.clone(),
AccessMode::Read,
)
.unwrap();

println!("An owned namespace capability: {:#?}", root_cap);

let (betty_id, betty_key) = SubspaceId25::new();

let only_blogs_area = Area::new(
AreaSubspace::Any,
Path::from_slices(&["blog"]).unwrap(),
Range::new_open(0),
let mut csprng = OsRng;

let (alfie_id, alfie_secret) =
randomly_generate_subspace(&mut csprng);
let communal_namespace_id =
NamespaceId::from_bytes(&[17; 32]);

// Create a new communal capability.
// To use it, we'll need Alfie's secret.
let communal_cap =
WriteCapability::new_communal(
communal_namespace_id.clone(),
alfie_id.clone(),
);

let cap_for_betty = root_cap
.delegate(&alfie_key, &betty_id, &only_blogs_area)
.unwrap();

println!(
"A delegated owned namespace cap for Betty: {:#?}",
cap_for_betty
);
}
println!("A communal capability: {:#?}", communal_cap);
}
15 changes: 14 additions & 1 deletion src/code_samples/tut_caps/01_output.txt
Original file line number Diff line number Diff line change
@@ -1 +1,14 @@
TODO - Nicer printing of objects!
A communal capability: WriteCapability {
genesis: Communal(
CommunalGenesis {
access_mode: Write,
namespace_key: NamespaceId(
-1111111111111111111111111111111111111111111111111111111111111111,
),
user_key: SubspaceId(
e28e9da138838ebed5eabdbaa7d4ed8bfc10213be3c3df1b2cb38a7585e38957,
),
},
),
delegations: [],
}
89 changes: 34 additions & 55 deletions src/code_samples/tut_caps/02.rs
Original file line number Diff line number Diff line change
@@ -1,61 +1,40 @@
use willow_25::{
AccessMode, Area, AreaSubspace, Capability, NamespaceId25, Path, Range, SubspaceId25,
};
use rand::rngs::OsRng;
use willow25::prelude::*;

fn main() {
// Owned capabilities

let (alfie_id, alfie_key) = SubspaceId25::new();
let (my_namespace, my_namespace_secret) = NamespaceId25::new_owned();

let root_cap = Capability::new_owned(
my_namespace,
&my_namespace_secret,
alfie_id.clone(),
AccessMode::Read,
)
.unwrap();

println!("An owned namespace capability: {:#?}", root_cap);

let (betty_id, betty_key) = SubspaceId25::new();

let only_blogs_area = Area::new(
AreaSubspace::Any,
Path::from_slices(&["blog"]).unwrap(),
Range::new_open(0),
let mut csprng = OsRng;

let (alfie_id, alfie_secret) =
randomly_generate_subspace(&mut csprng);
let communal_namespace_id =
NamespaceId::from_bytes(&[17; 32]);

// Create a new communal capability.
// To use it, we'll need Alfie's secret.
let communal_cap =
WriteCapability::new_communal(
communal_namespace_id.clone(),
alfie_id.clone(),
);

let cap_for_betty = root_cap
.delegate(&alfie_key, &betty_id, &only_blogs_area)
.unwrap();

println!(
"A delegated owned namespace cap for Betty: {:#?}",
cap_for_betty
println!("A communal capability: {:#?}", communal_cap);

let entry_communal = Entry::builder()
.namespace_id(communal_namespace_id.clone())
.subspace_id(alfie_id.clone())
.path(path!("/ideas"))
.timestamp(12345)
.payload(b"chocolate with mustard")
.build().unwrap();

// Authorise the entry using the communal
// capability and Alfie's secret.
let communal_authed = entry_communal
.into_authorised_entry(
&communal_cap,
&alfie_secret,
);

// Communal capabilities

let communal_namespace = NamespaceId25::new_communal();

let alfie_communal_cap =
Capability::new_communal(communal_namespace.clone(), alfie_id, AccessMode::Write).unwrap();

println!(
"A communal namespace cap for Alfie: {:#?}",
alfie_communal_cap
);

let betty_communal_cap = Capability::new_communal(
communal_namespace.clone(),
betty_id.clone(),
AccessMode::Write,
)
.unwrap();

println!(
"A communal namespace cap for betty: {:#?}",
betty_communal_cap
);
}
assert!(communal_authed.is_ok());
println!("Entry for communal namespace was authorised!");
}
16 changes: 15 additions & 1 deletion src/code_samples/tut_caps/02_output.txt
Original file line number Diff line number Diff line change
@@ -1 +1,15 @@
TODO - Nicer printing of objects!
A communal capability: WriteCapability {
genesis: Communal(
CommunalGenesis {
access_mode: Write,
namespace_key: NamespaceId(
-1111111111111111111111111111111111111111111111111111111111111111,
),
user_key: SubspaceId(
e28e9da138838ebed5eabdbaa7d4ed8bfc10213be3c3df1b2cb38a7585e38957,
),
},
),
delegations: [],
}
Entry for communal namespace was authorised!
167 changes: 77 additions & 90 deletions src/code_samples/tut_caps/03.rs
Original file line number Diff line number Diff line change
@@ -1,96 +1,83 @@
use willow_25::{
AccessMode, Area, AreaSubspace, AuthorisedEntry, Capability, Entry, NamespaceId25, Path,
PayloadDigest25, Range, SubspaceId25,
};
use rand::rngs::OsRng;
use willow25::prelude::*;

fn main() {
// Owned capabilities

let (alfie_id, alfie_key) = SubspaceId25::new();
let (my_namespace, my_namespace_secret) = NamespaceId25::new_owned();

let root_cap = Capability::new_owned(
my_namespace,
&my_namespace_secret,
alfie_id.clone(),
AccessMode::Read,
)
.unwrap();

println!("An owned namespace capability: {:#?}", root_cap);

let (betty_id, betty_key) = SubspaceId25::new();

let only_blogs_area = Area::new(
AreaSubspace::Any,
Path::from_slices(&["blog"]).unwrap(),
Range::new_open(0),
);

let cap_for_betty = root_cap
.delegate(&alfie_key, &betty_id, &only_blogs_area)
.unwrap();

println!(
"A delegated owned namespace cap for Betty: {:#?}",
cap_for_betty
);

// Communal capabilities

let communal_namespace = NamespaceId25::new_communal();

let alfie_communal_cap =
Capability::new_communal(communal_namespace.clone(), alfie_id, AccessMode::Write).unwrap();

println!(
"A communal namespace cap for Alfie: {:#?}",
alfie_communal_cap
);

let betty_communal_cap = Capability::new_communal(
communal_namespace.clone(),
betty_id.clone(),
AccessMode::Write,
)
.unwrap();

println!(
"A communal namespace cap for betty: {:#?}",
betty_communal_cap
);

// Authorised entries

let betty_entry = Entry::new(
communal_namespace.clone(),
betty_id.clone(),
Path::new_empty(),
100,
0,
PayloadDigest25::default(),
let mut csprng = OsRng;

let (alfie_id, alfie_secret) =
randomly_generate_subspace(&mut csprng);
let communal_namespace_id =
NamespaceId::from_bytes(&[17; 32]);

// Create a new communal capability.
// To use it, we'll need Alfie's secret.
let communal_cap =
WriteCapability::new_communal(
communal_namespace_id.clone(),
alfie_id.clone(),
);

let valid_token = betty_communal_cap
.authorisation_token(&betty_entry, betty_key)
.unwrap();

let authorised_entry = AuthorisedEntry::new(betty_entry, valid_token).unwrap();

println!("An authorised entry: {:?}", authorised_entry);

let (_muriarty_id, muriarty_key) = SubspaceId25::new();

let malicious_entry = Entry::new(
communal_namespace,
betty_id,
Path::from_slices(&["i", "stink"]).unwrap(),
100,
0,
PayloadDigest25::default(),
println!("A communal capability: {:#?}", communal_cap);

let entry_communal = Entry::builder()
.namespace_id(communal_namespace_id.clone())
.subspace_id(alfie_id.clone())
.path(path!("/ideas"))
.timestamp(12345)
.payload(b"chocolate with mustard")
.build().unwrap();

// Authorise the entry using the communal
// capability and Alfie's secret.
let communal_authed = entry_communal
.into_authorised_entry(
&communal_cap,
&alfie_secret,
);

let signing_error = betty_communal_cap.authorisation_token(&malicious_entry, muriarty_key);

println!("A signing error: {:?}", signing_error);
}
assert!(communal_authed.is_ok());
println!("Entry for communal namespace was authorised!");

// Create the keypair of an owned namespace.
let (owned_namespace_id, namespace_secret) =
randomly_generate_owned_namespace(&mut csprng);

// Create a new owned capability by using
// the namespace secret.
// To delegate it, we'll need Alfie's secret.
let mut owned_cap = WriteCapability::new_owned(&namespace_secret, alfie_id);

// Create a keypair for Betty.
let (betty_id, betty_secret) =
randomly_generate_subspace(&mut csprng);

// Delegate our owned cap to Betty,
// restricting her to her own subspace.
// To use it, we'll need Betty's secret.
owned_cap.delegate(
&alfie_secret,
Area::new_subspace_area(betty_id.clone()),
betty_id.clone(),
);

println!(
"A delegated owned capability: {:#?}",
owned_cap,
);

let entry_owned = Entry::builder()
.namespace_id(owned_namespace_id.clone())
.subspace_id(betty_id)
.path(path!("/blog"))
.timestamp(45689)
.payload(b"worried about alfie...")
.build().unwrap();

// Authorise the entry using the owned
// capability and Betty's secret.
let owned_authed = entry_owned
.into_authorised_entry(&owned_cap, &betty_secret);

assert!(owned_authed.is_ok());
println!("Entry for owned namespace was authorised!")
}
Loading