use crate::core::ribosome::CallContext;
use crate::core::ribosome::RibosomeT;
use std::sync::Arc;
use wasmer::RuntimeError;
pub fn capability_grants(
_ribosome: Arc<impl RibosomeT>,
_call_context: Arc<CallContext>,
_input: (),
) -> Result<(), RuntimeError> {
unimplemented!();
}
#[cfg(test)]
#[cfg(feature = "slow_tests")]
pub mod wasm_test {
use crate::test_utils::RibosomeTestFixture;
use ::fixt::prelude::*;
use hdk::prelude::*;
use holochain_types::fixt::CapSecretFixturator;
use holochain_wasm_test_utils::TestWasm;
use matches::assert_matches;
#[tokio::test(flavor = "multi_thread")]
async fn ribosome_capability_secret_test() {
holochain_trace::test_run();
let RibosomeTestFixture {
conductor, alice, ..
} = RibosomeTestFixture::new(TestWasm::Capability).await;
let _: CapSecret = conductor.call(&alice, "cap_secret", ()).await;
}
#[tokio::test(flavor = "multi_thread")]
async fn ribosome_transferable_cap_grant() {
holochain_trace::test_run();
let RibosomeTestFixture {
conductor, alice, ..
} = RibosomeTestFixture::new(TestWasm::Capability).await;
let secret: CapSecret = conductor.call(&alice, "cap_secret", ()).await;
let action: ActionHash = conductor
.call(&alice, "transferable_cap_grant", secret)
.await;
let maybe_record: Option<Record> = conductor.call(&alice, "get_entry", action).await;
let entry_secret: CapSecret = maybe_record
.and_then(|record| {
let cap_grant_entry = record.entry().to_grant_option().unwrap();
match cap_grant_entry.access {
CapAccess::Transferable { secret, .. } => Some(secret),
_ => None,
}
})
.unwrap();
assert_eq!(entry_secret, secret);
}
#[tokio::test(flavor = "multi_thread")]
async fn ribosome_authorized_call() -> anyhow::Result<()> {
holochain_trace::test_run();
let RibosomeTestFixture {
conductor,
alice,
bob,
bob_pubkey,
..
} = RibosomeTestFixture::new(TestWasm::Capability).await;
#[derive(serde::Serialize, serde::Deserialize, SerializedBytes, Debug)]
pub struct CapFor(CapSecret, AgentPubKey);
let original_secret = CapSecretFixturator::new(Unpredictable).next().unwrap();
let output: ZomeCallResponse = conductor
.call(
&alice,
"try_cap_claim",
CapFor(original_secret, bob_pubkey.clone()),
)
.await;
assert_matches!(output, ZomeCallResponse::Unauthorized(..));
let original_grant_hash: ActionHash = conductor
.call(&bob, "transferable_cap_grant", original_secret)
.await;
let response: ZomeCallResponse = conductor
.call(
&alice,
"try_cap_claim",
CapFor(original_secret, bob_pubkey.clone()),
)
.await;
assert_eq!(
response,
ZomeCallResponse::Ok(ExternIO::encode(()).unwrap()),
);
let new_grant_action_hash: ActionHash = conductor
.call(&bob, "roll_cap_grant", original_grant_hash)
.await;
let output: Option<Record> = conductor
.call(&bob, "get_entry", new_grant_action_hash.clone())
.await;
let new_secret: CapSecret = match output {
Some(record) => match record.entry().to_grant_option() {
Some(zome_call_cap_grant) => match zome_call_cap_grant.access {
CapAccess::Transferable { secret, .. } => secret,
_ => unreachable!(),
},
_ => unreachable!(),
},
_ => unreachable!("Couldn't get {:?}", new_grant_action_hash),
};
let output: ZomeCallResponse = conductor
.call(
&alice,
"try_cap_claim",
CapFor(original_secret, bob_pubkey.clone()),
)
.await;
assert_matches!(output, ZomeCallResponse::Unauthorized(..));
let output: ZomeCallResponse = conductor
.call(
&alice,
"try_cap_claim",
CapFor(new_secret, bob_pubkey.clone()),
)
.await;
assert_eq!(output, ZomeCallResponse::Ok(ExternIO::encode(()).unwrap()),);
let _: ActionHash = conductor
.call(&bob, "delete_cap_grant", new_grant_action_hash)
.await;
let output: ZomeCallResponse = conductor
.call(
&alice,
"try_cap_claim",
CapFor(original_secret, bob_pubkey.clone()),
)
.await;
assert_matches!(output, ZomeCallResponse::Unauthorized(..));
let output: ZomeCallResponse = conductor
.call(
&alice,
"try_cap_claim",
CapFor(new_secret, bob_pubkey.clone()),
)
.await;
assert_matches!(output, ZomeCallResponse::Unauthorized(..));
let mut conductor = conductor;
conductor.shutdown().await;
Ok(())
}
}