use super::DEFAULT_MAX_MUTATIONS;
use super::routing::Routing;
use client::mock::vault::Vault;
use config_handler::{Config, DevConfig};
use rand;
use routing::{AccountInfo, Action, Authority, ClientError, EntryAction, EntryActions, Event,
FullId, ImmutableData, MessageId, MutableData, PermissionSet, Request, Response,
TYPE_TAG_SESSION_PACKET, User, Value, XorName};
use rust_sodium::crypto::sign;
use std::sync::{Arc, Mutex};
use std::sync::mpsc::{self, Receiver};
use std::time::Duration;
use tiny_keccak::sha3_256;
use utils;
macro_rules! expect_success {
($rx:expr, $msg_id:expr, $res:path) => {
match unwrap!($rx.recv_timeout(Duration::from_secs(10))) {
Event::Response {
response: $res { res, msg_id, }, ..
} => {
assert_eq!(msg_id, $msg_id);
match res {
Ok(value) => value,
Err(err) => panic!("Unexpected error {:?}", err),
}
}
event => panic!("Unexpected event {:?}", event),
}
}
}
macro_rules! expect_failure {
($rx:expr, $msg_id:expr, $res:path, $err:pat) => {
match unwrap!($rx.recv_timeout(Duration::from_secs(10))) {
Event::Response {
response: $res { res, msg_id, }, ..
} => {
assert_eq!(msg_id, $msg_id);
match res {
Ok(_) => panic!("Unexpected success"),
Err($err) => (),
Err(err) => panic!("Unexpected error {:?}", err),
}
}
event => panic!("Unexpected event {:?}", event),
}
}
}
#[test]
fn immutable_data_basics() {
let (mut routing, routing_rx, full_id) = setup();
let owner_key = *full_id.public_id().signing_public_key();
let client_mgr = create_account(&mut routing, &routing_rx, owner_key);
let orig_data = ImmutableData::new(unwrap!(utils::generate_random_vector(100)));
let nae_mgr = Authority::NaeManager(*orig_data.name());
let msg_id = MessageId::new();
unwrap!(routing.get_idata(nae_mgr, *orig_data.name(), msg_id));
expect_failure!(
routing_rx,
msg_id,
Response::GetIData,
ClientError::NoSuchData
);
let msg_id = MessageId::new();
unwrap!(routing.put_idata(client_mgr, orig_data.clone(), msg_id));
expect_success!(routing_rx, msg_id, Response::PutIData);
let msg_id = MessageId::new();
unwrap!(routing.get_idata(nae_mgr, *orig_data.name(), msg_id));
let got_data = expect_success!(routing_rx, msg_id, Response::GetIData);
assert_eq!(got_data, orig_data);
let acct_info = account_info(&mut routing, &routing_rx, client_mgr);
assert_eq!(acct_info.mutations_done, 1);
assert_eq!(acct_info.mutations_available, DEFAULT_MAX_MUTATIONS - 1);
let msg_id = MessageId::new();
unwrap!(routing.put_idata(client_mgr, orig_data.clone(), msg_id));
expect_success!(routing_rx, msg_id, Response::PutIData);
let msg_id = MessageId::new();
unwrap!(routing.get_idata(nae_mgr, *orig_data.name(), msg_id));
let got_data = expect_success!(routing_rx, msg_id, Response::GetIData);
assert_eq!(got_data, orig_data);
let acct_info = account_info(&mut routing, &routing_rx, client_mgr);
assert_eq!(acct_info.mutations_done, 2);
assert_eq!(acct_info.mutations_available, DEFAULT_MAX_MUTATIONS - 2);
}
#[test]
fn mutable_data_basics() {
let (mut routing, routing_rx, full_id) = setup();
let owner_key = *full_id.public_id().signing_public_key();
let client_mgr = create_account(&mut routing, &routing_rx, owner_key);
let name = rand::random();
let tag = 1000u64;
let data = unwrap!(MutableData::new(
name,
tag,
Default::default(),
Default::default(),
btree_set!(owner_key),
));
let nae_mgr = Authority::NaeManager(*data.name());
let msg_id = MessageId::new();
unwrap!(routing.get_mdata_version(nae_mgr, name, tag, msg_id));
expect_failure!(
routing_rx,
msg_id,
Response::GetMDataVersion,
ClientError::NoSuchData
);
let msg_id = MessageId::new();
unwrap!(routing.list_mdata_entries(nae_mgr, name, tag, msg_id));
expect_failure!(
routing_rx,
msg_id,
Response::ListMDataEntries,
ClientError::NoSuchData
);
let msg_id = MessageId::new();
unwrap!(routing.put_mdata(client_mgr, data, msg_id, owner_key));
expect_success!(routing_rx, msg_id, Response::PutMData);
let tag2 = 1001u64;
let data2 = unwrap!(MutableData::new(
name,
tag2,
Default::default(),
Default::default(),
btree_set!(owner_key),
));
let msg_id = MessageId::new();
unwrap!(routing.put_mdata(client_mgr, data2, msg_id, owner_key));
expect_success!(routing_rx, msg_id, Response::PutMData);
let msg_id = MessageId::new();
unwrap!(routing.get_mdata_version(nae_mgr, name, tag, msg_id));
let version = expect_success!(routing_rx, msg_id, Response::GetMDataVersion);
assert_eq!(version, 0);
let msg_id = MessageId::new();
unwrap!(routing.get_mdata(nae_mgr, name, tag, msg_id));
let mdata = expect_success!(routing_rx, msg_id, Response::GetMData);
assert!(mdata.serialised_size() > 0);
let msg_id = MessageId::new();
unwrap!(routing.list_mdata_entries(nae_mgr, name, tag, msg_id));
let entries = expect_success!(routing_rx, msg_id, Response::ListMDataEntries);
assert!(entries.is_empty());
let msg_id = MessageId::new();
unwrap!(routing.list_mdata_keys(nae_mgr, name, tag, msg_id));
let keys = expect_success!(routing_rx, msg_id, Response::ListMDataKeys);
assert!(keys.is_empty());
let msg_id = MessageId::new();
unwrap!(routing.list_mdata_values(nae_mgr, name, tag, msg_id));
let values = expect_success!(routing_rx, msg_id, Response::ListMDataValues);
assert!(values.is_empty());
let key0 = b"key0";
let key1 = b"key1";
let value0_v0 = unwrap!(utils::generate_random_vector(10));
let value1_v0 = unwrap!(utils::generate_random_vector(10));
let actions =
btree_map![
key0.to_vec() => EntryAction::Ins(Value {
content: value0_v0.clone(),
entry_version: 0,
}),
key1.to_vec() => EntryAction::Ins(Value {
content: value1_v0.clone(),
entry_version: 0,
})
];
let msg_id = MessageId::new();
unwrap!(routing.mutate_mdata_entries(
client_mgr,
name,
tag,
actions,
msg_id,
owner_key,
));
expect_success!(routing_rx, msg_id, Response::MutateMDataEntries);
let msg_id = MessageId::new();
unwrap!(routing.list_mdata_entries(nae_mgr, name, tag, msg_id));
let entries = expect_success!(routing_rx, msg_id, Response::ListMDataEntries);
assert_eq!(entries.len(), 2);
let entry = unwrap!(entries.get(&key0[..]));
assert_eq!(entry.content, value0_v0);
assert_eq!(entry.entry_version, 0);
let entry = unwrap!(entries.get(&key1[..]));
assert_eq!(entry.content, value1_v0);
assert_eq!(entry.entry_version, 0);
let msg_id = MessageId::new();
unwrap!(routing.list_mdata_entries(nae_mgr, name, tag2, msg_id));
let entries = expect_success!(routing_rx, msg_id, Response::ListMDataEntries);
assert!(entries.is_empty());
let msg_id = MessageId::new();
unwrap!(routing.list_mdata_keys(nae_mgr, name, tag, msg_id));
let keys = expect_success!(routing_rx, msg_id, Response::ListMDataKeys);
assert_eq!(keys.len(), 2);
assert!(keys.contains(&key0[..]));
assert!(keys.contains(&key1[..]));
let msg_id = MessageId::new();
unwrap!(routing.list_mdata_values(nae_mgr, name, tag, msg_id));
let values = expect_success!(routing_rx, msg_id, Response::ListMDataValues);
assert_eq!(values.len(), 2);
let msg_id = MessageId::new();
unwrap!(routing.get_mdata_value(
nae_mgr,
name,
tag,
key0.to_vec(),
msg_id,
));
let value = expect_success!(routing_rx, msg_id, Response::GetMDataValue);
assert_eq!(value.content, value0_v0);
assert_eq!(value.entry_version, 0);
let key2 = b"key2";
let msg_id = MessageId::new();
unwrap!(routing.get_mdata_value(
nae_mgr,
name,
tag,
key2.to_vec(),
msg_id,
));
expect_failure!(
routing_rx,
msg_id,
Response::GetMDataValue,
ClientError::NoSuchEntry
);
let value0_v1 = unwrap!(utils::generate_random_vector(10));
let value2_v0 = unwrap!(utils::generate_random_vector(10));
let actions =
btree_map![
key0.to_vec() => EntryAction::Update(Value {
content: value0_v1.clone(),
entry_version: 1,
}),
key1.to_vec() => EntryAction::Del(1),
key2.to_vec() => EntryAction::Ins(Value {
content: value2_v0.clone(),
entry_version: 0,
})
];
let msg_id = MessageId::new();
unwrap!(routing.mutate_mdata_entries(
client_mgr,
name,
tag,
actions,
msg_id,
owner_key,
));
expect_success!(routing_rx, msg_id, Response::MutateMDataEntries);
let msg_id = MessageId::new();
unwrap!(routing.list_mdata_entries(nae_mgr, name, tag, msg_id));
let entries = expect_success!(routing_rx, msg_id, Response::ListMDataEntries);
assert_eq!(entries.len(), 3);
let entry = unwrap!(entries.get(&key0[..]));
assert_eq!(entry.content, value0_v1);
assert_eq!(entry.entry_version, 1);
let entry = unwrap!(entries.get(&key1[..]));
assert!(entry.content.is_empty());
assert_eq!(entry.entry_version, 1);
let entry = unwrap!(entries.get(&key2[..]));
assert_eq!(entry.content, value2_v0);
assert_eq!(entry.entry_version, 0);
}
#[test]
fn mutable_data_reclaim() {
let (mut routing, routing_rx, full_id) = setup();
let owner_key = *full_id.public_id().signing_public_key();
let client_mgr = create_account(&mut routing, &routing_rx, owner_key);
let name = rand::random();
let tag = 1000u64;
let data = unwrap!(MutableData::new(
name,
tag,
Default::default(),
Default::default(),
btree_set!(owner_key),
));
let nae_mgr = Authority::NaeManager(*data.name());
let msg_id = MessageId::new();
unwrap!(routing.put_mdata(client_mgr, data, msg_id, owner_key));
expect_success!(routing_rx, msg_id, Response::PutMData);
let key0 = b"key0";
let value0 = unwrap!(utils::generate_random_vector(10));
let actions =
btree_map![
key0.to_vec() => EntryAction::Ins(Value {
content: value0.clone(),
entry_version: 0,
}),
];
let msg_id = MessageId::new();
unwrap!(routing.mutate_mdata_entries(
client_mgr,
name,
tag,
actions,
msg_id,
owner_key,
));
expect_success!(routing_rx, msg_id, Response::MutateMDataEntries);
let actions =
btree_map![
key0.to_vec() => EntryAction::Del(1),
];
let msg_id = MessageId::new();
unwrap!(routing.mutate_mdata_entries(
client_mgr,
name,
tag,
actions,
msg_id,
owner_key,
));
expect_success!(routing_rx, msg_id, Response::MutateMDataEntries);
let actions =
btree_map![
key0.to_vec() => EntryAction::Update(Value {
content: value0.clone(),
entry_version: 2,
})
];
let msg_id = MessageId::new();
unwrap!(routing.mutate_mdata_entries(
client_mgr,
name,
tag,
actions,
msg_id,
owner_key,
));
expect_success!(routing_rx, msg_id, Response::MutateMDataEntries);
let msg_id = MessageId::new();
unwrap!(routing.get_mdata_version(nae_mgr, name, tag, msg_id));
let version = expect_success!(routing_rx, msg_id, Response::GetMDataVersion);
assert_eq!(version, 0);
let actions =
btree_map![
key0.to_vec() => EntryAction::Del(4),
];
let msg_id = MessageId::new();
unwrap!(routing.mutate_mdata_entries(
client_mgr,
name,
tag,
actions,
msg_id,
owner_key,
));
expect_failure!(
routing_rx,
msg_id,
Response::MutateMDataEntries,
ClientError::InvalidEntryActions(_)
);
let actions = btree_map![
key0.to_vec() => EntryAction::Del(3),
];
let msg_id = MessageId::new();
unwrap!(routing.mutate_mdata_entries(
client_mgr,
name,
tag,
actions,
msg_id,
owner_key,
));
expect_success!(routing_rx, msg_id, Response::MutateMDataEntries);
}
#[test]
fn mutable_data_entry_versioning() {
let (mut routing, routing_rx, full_id) = setup();
let owner_key = *full_id.public_id().signing_public_key();
let client_mgr = create_account(&mut routing, &routing_rx, owner_key);
let name = rand::random();
let tag = 1000u64;
let data = unwrap!(MutableData::new(
name,
tag,
Default::default(),
Default::default(),
btree_set!(owner_key),
));
let msg_id = MessageId::new();
unwrap!(routing.put_mdata(client_mgr, data, msg_id, owner_key));
expect_success!(routing_rx, msg_id, Response::PutMData);
let key = b"key0";
let value_v0 = unwrap!(utils::generate_random_vector(10));
let actions = btree_map![
key.to_vec() => EntryAction::Ins(Value {
content: value_v0,
entry_version: 0,
})
];
let msg_id = MessageId::new();
unwrap!(routing.mutate_mdata_entries(
client_mgr,
name,
tag,
actions,
msg_id,
owner_key,
));
expect_success!(routing_rx, msg_id, Response::MutateMDataEntries);
let value_v1 = unwrap!(utils::generate_random_vector(10));
let actions = btree_map![
key.to_vec() => EntryAction::Update(Value {
content: value_v1.clone(),
entry_version: 0,
})
];
let msg_id = MessageId::new();
unwrap!(routing.mutate_mdata_entries(
client_mgr,
name,
tag,
actions,
msg_id,
owner_key,
));
expect_failure!(routing_rx,
msg_id,
Response::MutateMDataEntries,
ClientError::InvalidEntryActions(_));
let actions = EntryActions::new()
.update(key.to_vec(), value_v1.clone(), 314_159_265)
.into();
let msg_id = MessageId::new();
unwrap!(routing.mutate_mdata_entries(client_mgr, name, tag, actions, msg_id, owner_key));
expect_failure!(routing_rx,
msg_id,
Response::MutateMDataEntries,
ClientError::InvalidEntryActions(_));
let actions = btree_map![
key.to_vec() => EntryAction::Update(Value {
content: value_v1.clone(),
entry_version: 1,
})
];
let msg_id = MessageId::new();
unwrap!(routing.mutate_mdata_entries(client_mgr, name, tag, actions, msg_id, owner_key));
expect_success!(routing_rx, msg_id, Response::MutateMDataEntries);
let actions = btree_map![
key.to_vec() => EntryAction::Del(1)
];
let msg_id = MessageId::new();
unwrap!(routing.mutate_mdata_entries(client_mgr, name, tag, actions, msg_id, owner_key));
expect_failure!(routing_rx,
msg_id,
Response::MutateMDataEntries,
ClientError::InvalidEntryActions(_));
let actions = btree_map![
key.to_vec() => EntryAction::Del(2)
];
let msg_id = MessageId::new();
unwrap!(routing.mutate_mdata_entries(client_mgr, name, tag, actions, msg_id, owner_key));
expect_success!(routing_rx, msg_id, Response::MutateMDataEntries);
}
#[test]
fn mutable_data_permissions() {
let (mut routing, routing_rx, full_id) = setup();
let owner_key = *full_id.public_id().signing_public_key();
let client_mgr = create_account(&mut routing, &routing_rx, owner_key);
let name = rand::random();
let tag = 1000u64;
let key0 = b"key0";
let value0_v0 = unwrap!(utils::generate_random_vector(10));
let entries = btree_map![
key0.to_vec() => Value { content: value0_v0, entry_version: 0 }
];
let data = unwrap!(MutableData::new(name,
tag,
Default::default(),
entries,
btree_set!(owner_key)));
let nae_mgr = Authority::NaeManager(*data.name());
let msg_id = MessageId::new();
unwrap!(routing.put_mdata(client_mgr, data, msg_id, owner_key));
expect_success!(routing_rx, msg_id, Response::PutMData);
let msg_id = MessageId::new();
unwrap!(routing.list_mdata_permissions(nae_mgr, name, tag, msg_id));
let permissions = expect_success!(routing_rx, msg_id, Response::ListMDataPermissions);
assert!(permissions.is_empty());
let value0_v1 = unwrap!(utils::generate_random_vector(10));
let actions = EntryActions::new()
.update(key0.to_vec(), value0_v1, 1)
.into();
let msg_id = MessageId::new();
unwrap!(routing.mutate_mdata_entries(client_mgr, name, tag, actions, msg_id, owner_key));
expect_success!(routing_rx, msg_id, Response::MutateMDataEntries);
let (mut app_routing, app_routing_rx, app_full_id) = setup();
let app_sign_key = *app_full_id.public_id().signing_public_key();
let msg_id = MessageId::new();
unwrap!(routing.list_auth_keys_and_version(client_mgr, msg_id));
let (_, version) = expect_success!(routing_rx, msg_id, Response::ListAuthKeysAndVersion);
let msg_id = MessageId::new();
unwrap!(routing.ins_auth_key(client_mgr, app_sign_key, version + 1, msg_id));
expect_success!(routing_rx, msg_id, Response::InsAuthKey);
let value0_v2 = unwrap!(utils::generate_random_vector(10));
let actions = EntryActions::new()
.update(key0.to_vec(), value0_v2.clone(), 2)
.into();
let msg_id = MessageId::new();
unwrap!(app_routing.mutate_mdata_entries(client_mgr, name, tag, actions, msg_id, app_sign_key));
expect_failure!(app_routing_rx,
msg_id,
Response::MutateMDataEntries,
ClientError::AccessDenied);
let perms = PermissionSet::new().allow(Action::Update);
let msg_id = MessageId::new();
unwrap!(app_routing.set_mdata_user_permissions(client_mgr,
name,
tag,
User::Key(app_sign_key),
perms,
1,
msg_id,
app_sign_key));
expect_failure!(app_routing_rx,
msg_id,
Response::SetMDataUserPermissions,
ClientError::AccessDenied);
let actions = EntryActions::new()
.update(key0.to_vec(), value0_v2.clone(), 2)
.into();
let msg_id = MessageId::new();
unwrap!(app_routing.mutate_mdata_entries(client_mgr, name, tag, actions, msg_id, app_sign_key));
expect_failure!(app_routing_rx,
msg_id,
Response::MutateMDataEntries,
ClientError::AccessDenied);
let perms = PermissionSet::new().allow(Action::Insert);
let msg_id = MessageId::new();
unwrap!(routing.set_mdata_user_permissions(client_mgr,
name,
tag,
User::Key(app_sign_key),
perms,
1,
msg_id,
owner_key));
expect_success!(routing_rx, msg_id, Response::SetMDataUserPermissions);
let msg_id = MessageId::new();
unwrap!(routing.get_mdata_version(nae_mgr, name, tag, msg_id));
let version = expect_success!(routing_rx, msg_id, Response::GetMDataVersion);
assert_eq!(version, 1);
let actions = btree_map![
key0.to_vec() => EntryAction::Update(Value {
content: value0_v2.clone(),
entry_version: 2,
})
];
let msg_id = MessageId::new();
unwrap!(app_routing.mutate_mdata_entries(client_mgr, name, tag, actions, msg_id, app_sign_key));
expect_failure!(app_routing_rx,
msg_id,
Response::MutateMDataEntries,
ClientError::AccessDenied);
let key1 = b"key1";
let value1_v0 = unwrap!(utils::generate_random_vector(10));
let actions = btree_map![
key1.to_vec() => EntryAction::Ins(Value {
content: value1_v0,
entry_version: 0,
})
];
let msg_id = MessageId::new();
unwrap!(app_routing.mutate_mdata_entries(client_mgr, name, tag, actions, msg_id, app_sign_key));
expect_success!(app_routing_rx, msg_id, Response::MutateMDataEntries);
let perms = PermissionSet::new().allow(Action::Insert).allow(
Action::Update,
);
let msg_id = MessageId::new();
unwrap!(routing.set_mdata_user_permissions(client_mgr,
name,
tag,
User::Key(app_sign_key),
perms,
1,
msg_id,
owner_key));
expect_failure!(routing_rx,
msg_id,
Response::SetMDataUserPermissions,
ClientError::InvalidSuccessor(_));
let perms = PermissionSet::new().allow(Action::Insert).allow(
Action::Update,
);
let msg_id = MessageId::new();
unwrap!(routing.set_mdata_user_permissions(client_mgr,
name,
tag,
User::Key(app_sign_key),
perms,
2,
msg_id,
owner_key));
expect_success!(routing_rx, msg_id, Response::SetMDataUserPermissions);
let actions = btree_map![
key0.to_vec() => EntryAction::Update(Value {
content: value0_v2,
entry_version: 2,
})
];
let msg_id = MessageId::new();
unwrap!(app_routing.mutate_mdata_entries(client_mgr, name, tag, actions, msg_id, app_sign_key));
expect_success!(app_routing_rx, msg_id, Response::MutateMDataEntries);
let msg_id = MessageId::new();
unwrap!(routing.del_mdata_user_permissions(client_mgr,
name,
tag,
User::Key(app_sign_key),
3,
msg_id,
owner_key));
expect_success!(routing_rx, msg_id, Response::DelMDataUserPermissions);
let key2 = b"key2";
let value2_v0 = unwrap!(utils::generate_random_vector(10));
let actions = EntryActions::new().ins(key2.to_vec(), value2_v0, 0).into();
let msg_id = MessageId::new();
unwrap!(app_routing.mutate_mdata_entries(client_mgr, name, tag, actions, msg_id, app_sign_key));
expect_failure!(app_routing_rx,
msg_id,
Response::MutateMDataEntries,
ClientError::AccessDenied);
let perms = PermissionSet::new().allow(Action::ManagePermissions);
let msg_id = MessageId::new();
unwrap!(routing.set_mdata_user_permissions(client_mgr,
name,
tag,
User::Key(app_sign_key),
perms,
4,
msg_id,
owner_key));
expect_success!(routing_rx, msg_id, Response::SetMDataUserPermissions);
let value1_v1 = unwrap!(utils::generate_random_vector(10));
let actions = EntryActions::new()
.update(key1.to_vec(), value1_v1, 1)
.into();
let msg_id = MessageId::new();
unwrap!(app_routing.mutate_mdata_entries(client_mgr, name, tag, actions, msg_id, app_sign_key));
expect_failure!(app_routing_rx,
msg_id,
Response::MutateMDataEntries,
ClientError::AccessDenied);
let perms = PermissionSet::new().allow(Action::Update);
let msg_id = MessageId::new();
unwrap!(app_routing.set_mdata_user_permissions(client_mgr,
name,
tag,
User::Key(app_sign_key),
perms,
5,
msg_id,
app_sign_key));
expect_success!(app_routing_rx, msg_id, Response::SetMDataUserPermissions);
let value1_v1 = unwrap!(utils::generate_random_vector(10));
let actions = EntryActions::new()
.update(key1.to_vec(), value1_v1, 1)
.into();
let msg_id = MessageId::new();
unwrap!(app_routing.mutate_mdata_entries(client_mgr, name, tag, actions, msg_id, app_sign_key));
expect_success!(app_routing_rx, msg_id, Response::MutateMDataEntries);
let (mut app2_routing, app2_routing_rx, app2_full_id) = setup();
let app2_sign_key = *app2_full_id.public_id().signing_public_key();
let msg_id = MessageId::new();
unwrap!(routing.list_auth_keys_and_version(client_mgr, msg_id));
let (_, version) = expect_success!(routing_rx, msg_id, Response::ListAuthKeysAndVersion);
let msg_id = MessageId::new();
unwrap!(routing.ins_auth_key(client_mgr, app2_sign_key, version + 1, msg_id));
expect_success!(routing_rx, msg_id, Response::InsAuthKey);
let key3 = b"key3";
let value3_v0 = unwrap!(utils::generate_random_vector(10));
let actions = EntryActions::new()
.ins(key3.to_vec(), value3_v0.clone(), 0)
.into();
let msg_id = MessageId::new();
unwrap!(app2_routing.mutate_mdata_entries(client_mgr,
name,
tag,
actions,
msg_id,
app2_sign_key));
expect_failure!(app2_routing_rx,
msg_id,
Response::MutateMDataEntries,
ClientError::AccessDenied);
let perms = PermissionSet::new().allow(Action::Insert);
let msg_id = MessageId::new();
unwrap!(routing.set_mdata_user_permissions(client_mgr,
name,
tag,
User::Anyone,
perms,
6,
msg_id,
owner_key));
expect_success!(routing_rx, msg_id, Response::SetMDataUserPermissions);
let actions = EntryActions::new().ins(key3.to_vec(), value3_v0, 0).into();
let msg_id = MessageId::new();
unwrap!(app2_routing.mutate_mdata_entries(client_mgr,
name,
tag,
actions,
msg_id,
app2_sign_key));
expect_success!(app2_routing_rx, msg_id, Response::MutateMDataEntries);
let msg_id = MessageId::new();
unwrap!(routing.del_mdata_user_permissions(client_mgr,
name,
tag,
User::Anyone,
7,
msg_id,
owner_key));
expect_success!(routing_rx, msg_id, Response::DelMDataUserPermissions);
let key4 = b"key4";
let value4_v0 = unwrap!(utils::generate_random_vector(10));
let actions = EntryActions::new()
.ins(key4.to_vec(), value4_v0.clone(), 0)
.into();
let msg_id = MessageId::new();
unwrap!(app2_routing.mutate_mdata_entries(client_mgr,
name,
tag,
actions,
msg_id,
app2_sign_key));
expect_failure!(app2_routing_rx,
msg_id,
Response::MutateMDataEntries,
ClientError::AccessDenied);
}
#[test]
fn mutable_data_ownership() {
let (mut owner_routing, owner_routing_rx, owner_full_id) = setup();
let owner_key = *owner_full_id.public_id().signing_public_key();
let client_mgr = create_account(&mut owner_routing, &owner_routing_rx, owner_key);
let (mut app_routing, app_routing_rx, app_full_id) = setup();
let app_sign_key = *app_full_id.public_id().signing_public_key();
let msg_id = MessageId::new();
unwrap!(owner_routing.ins_auth_key(client_mgr, app_sign_key, 1, msg_id));
expect_success!(owner_routing_rx, msg_id, Response::InsAuthKey);
let name = rand::random();
let tag = 1000u64;
let data = unwrap!(MutableData::new(name,
tag,
Default::default(),
Default::default(),
btree_set![app_sign_key]));
let msg_id = MessageId::new();
unwrap!(app_routing.put_mdata(client_mgr, data, msg_id, app_sign_key));
expect_failure!(app_routing_rx,
msg_id,
Response::PutMData,
ClientError::InvalidOwners);
let data = unwrap!(MutableData::new(name,
tag,
Default::default(),
Default::default(),
btree_set![owner_key]));
let msg_id = MessageId::new();
unwrap!(owner_routing.put_mdata(client_mgr, data, msg_id, owner_key));
expect_success!(owner_routing_rx, msg_id, Response::PutMData);
let msg_id = MessageId::new();
unwrap!(app_routing.change_mdata_owner(client_mgr,
name,
tag,
btree_set![app_sign_key],
1,
msg_id));
expect_failure!(app_routing_rx,
msg_id,
Response::ChangeMDataOwner,
ClientError::AccessDenied);
let app_client_mgr = create_account(&mut app_routing, &app_routing_rx, app_sign_key);
let msg_id = MessageId::new();
unwrap!(app_routing.change_mdata_owner(app_client_mgr,
name,
tag,
btree_set![app_sign_key],
1,
msg_id));
expect_failure!(app_routing_rx,
msg_id,
Response::ChangeMDataOwner,
ClientError::AccessDenied);
let msg_id = MessageId::new();
unwrap!(owner_routing.change_mdata_owner(client_mgr,
name,
tag,
btree_set![app_sign_key],
1,
msg_id));
expect_success!(owner_routing_rx, msg_id, Response::ChangeMDataOwner);
}
#[test]
fn auth_keys() {
let (mut routing, routing_rx, full_id) = setup();
let owner_key = *full_id.public_id().signing_public_key();
let client_mgr = create_account(&mut routing, &routing_rx, owner_key);
let (auth_key1, _) = sign::gen_keypair();
let (auth_key2, _) = sign::gen_keypair();
let msg_id = MessageId::new();
unwrap!(routing.list_auth_keys_and_version(client_mgr, msg_id));
let (auth_keys, version) = expect_success!(routing_rx, msg_id,
Response::ListAuthKeysAndVersion);
assert!(auth_keys.is_empty());
assert_eq!(version, 0);
let msg_id = MessageId::new();
unwrap!(routing.ins_auth_key(client_mgr, auth_key1, 0, msg_id));
expect_failure!(routing_rx,
msg_id,
Response::InsAuthKey,
ClientError::InvalidSuccessor(_));
let msg_id = MessageId::new();
unwrap!(routing.ins_auth_key(client_mgr, auth_key1, 1, msg_id));
expect_success!(routing_rx, msg_id, Response::InsAuthKey);
let msg_id = MessageId::new();
unwrap!(routing.list_auth_keys_and_version(client_mgr, msg_id));
let (auth_keys, version) = expect_success!(routing_rx, msg_id,
Response::ListAuthKeysAndVersion);
assert_eq!(auth_keys.len(), 1);
assert!(auth_keys.contains(&auth_key1));
assert_eq!(version, 1);
let msg_id = MessageId::new();
unwrap!(routing.del_auth_key(client_mgr, auth_key1, 1, msg_id));
expect_failure!(routing_rx,
msg_id,
Response::DelAuthKey,
ClientError::InvalidSuccessor(_));
let msg_id = MessageId::new();
unwrap!(routing.del_auth_key(client_mgr, auth_key2, 2, msg_id));
expect_failure!(routing_rx,
msg_id,
Response::DelAuthKey,
ClientError::NoSuchKey);
let msg_id = MessageId::new();
unwrap!(routing.del_auth_key(client_mgr, auth_key1, 2, msg_id));
expect_success!(routing_rx, msg_id, Response::DelAuthKey);
let msg_id = MessageId::new();
unwrap!(routing.list_auth_keys_and_version(client_mgr, msg_id));
let (auth_keys, version) = expect_success!(routing_rx, msg_id,
Response::ListAuthKeysAndVersion);
assert!(auth_keys.is_empty());
assert_eq!(version, 2);
}
#[test]
fn low_balance_check() {
for &custom_vault in &[true, false] {
let (mut routing, routing_rx, full_id) = setup_with_config(Config {
dev: Some(DevConfig {
mock_unlimited_mutations: custom_vault,
mock_in_memory_storage: true,
mock_vault_path: None,
}),
});
let owner_key = *full_id.public_id().signing_public_key();
let client_mgr = create_account(&mut routing, &routing_rx, owner_key);
let name = rand::random();
let tag = 1000u64;
let data = unwrap!(MutableData::new(
name,
tag,
Default::default(),
Default::default(),
btree_set!(owner_key),
));
let nae_mgr = Authority::NaeManager(*data.name());
let msg_id = MessageId::new();
unwrap!(routing.put_mdata(client_mgr, data, msg_id, owner_key));
expect_success!(routing_rx, msg_id, Response::PutMData);
let vec_data = unwrap!(utils::generate_random_vector(10));
let data = ImmutableData::new(vec_data);
let msg_id = MessageId::new();
let unlimited_muts = match routing.config().dev {
Some(dev) => dev.mock_unlimited_mutations,
None => false,
};
let mut mutations_available = account_info(&mut routing, &routing_rx, client_mgr)
.mutations_available;
loop {
unwrap!(routing.put_idata(client_mgr, data.clone(), msg_id));
expect_success!(routing_rx, msg_id, Response::PutIData);
mutations_available -= 1;
let acct_info = account_info(&mut routing, &routing_rx, client_mgr);
if acct_info.mutations_available == 0 || mutations_available == 0 {
break;
}
}
if !unlimited_muts {
assert!(!custom_vault);
unwrap!(routing.put_idata(client_mgr, data.clone(), msg_id));
expect_failure!(routing_rx,
msg_id,
Response::PutIData,
ClientError::LowBalance);
} else {
assert!(custom_vault);
unwrap!(routing.put_idata(client_mgr, data, msg_id));
expect_success!(routing_rx,
msg_id,
Response::PutIData);
}
let msg_id = MessageId::new();
unwrap!(routing.get_mdata(nae_mgr, name, tag, msg_id));
let mdata = expect_success!(routing_rx, msg_id, Response::GetMData);
assert!(mdata.serialised_size() > 0);
}
}
#[test]
#[should_panic]
fn invalid_config_mock_vault_path() {
use std;
if std::env::var("SAFE_MOCK_IN_MEMORY_STORAGE").is_ok() {
panic!("This test should run without env vars set.");
}
let (mut routing, routing_rx, full_id) = setup_with_config(Config {
dev: Some(DevConfig {
mock_unlimited_mutations: false,
mock_in_memory_storage: false,
mock_vault_path: Some(String::from("./this_path_should_not_exist")),
}),
});
let owner_key = *full_id.public_id().signing_public_key();
let _ = create_account(&mut routing, &routing_rx, owner_key);
}
#[test]
fn config_mock_vault_path() {
use std;
if std::env::var("SAFE_MOCK_IN_MEMORY_STORAGE").is_ok() {
return;
}
match std::fs::create_dir("./tmp") {
Ok(_) => (),
Err(ref e) if e.kind() == std::io::ErrorKind::AlreadyExists => (),
_ => panic!("Error creating directory"),
}
let (mut routing, routing_rx, full_id) = setup_with_config(Config {
dev: Some(DevConfig {
mock_unlimited_mutations: false,
mock_in_memory_storage: false,
mock_vault_path: Some(String::from("./tmp")),
}),
});
let owner_key = *full_id.public_id().signing_public_key();
let client_mgr = create_account(&mut routing, &routing_rx, owner_key);
let name = rand::random();
let tag = 1000u64;
let data = unwrap!(MutableData::new(
name,
tag,
Default::default(),
Default::default(),
btree_set!(owner_key),
));
let nae_mgr = Authority::NaeManager(*data.name());
let msg_id = MessageId::new();
unwrap!(routing.put_mdata(client_mgr, data, msg_id, owner_key));
expect_success!(routing_rx, msg_id, Response::PutMData);
let msg_id = MessageId::new();
unwrap!(routing.get_mdata(nae_mgr, name, tag, msg_id));
let mdata = expect_success!(routing_rx, msg_id, Response::GetMData);
assert!(mdata.serialised_size() > 0);
unwrap!(std::fs::remove_dir_all("./tmp"));
}
#[test]
fn request_hooks() {
let (mut routing, routing_rx, full_id) = setup();
routing.set_request_hook(move |req| {
match *req {
Request::PutMData { ref data, msg_id, .. } if data.tag() == 10_000u64 => {
Some(Response::PutMData {
res: Ok(()),
msg_id,
})
}
Request::MutateMDataEntries { tag, msg_id, .. } if tag == 12_345u64 => {
Some(Response::MutateMDataEntries {
res: Err(ClientError::from("hello world")),
msg_id,
})
}
_ => None,
}
});
let owner_key = *full_id.public_id().signing_public_key();
let client_mgr = create_account(&mut routing, &routing_rx, owner_key);
let name = rand::random();
let tag = 10_000u64;
let data = unwrap!(MutableData::new(name,
tag,
Default::default(),
Default::default(),
btree_set!(owner_key)));
let msg_id = MessageId::new();
unwrap!(routing.put_mdata(client_mgr, data, msg_id, owner_key));
expect_success!(routing_rx, msg_id, Response::PutMData);
let msg_id = MessageId::new();
unwrap!(routing.get_mdata_version(Authority::NaeManager(name), name, tag, msg_id));
expect_failure!(routing_rx,
msg_id,
Response::GetMDataVersion,
ClientError::NoSuchData);
let name = rand::random();
let tag = 12_345u64;
let data = unwrap!(MutableData::new(name,
tag,
Default::default(),
Default::default(),
btree_set!(owner_key)));
let msg_id = MessageId::new();
unwrap!(routing.put_mdata(client_mgr, data, msg_id, owner_key));
expect_success!(routing_rx, msg_id, Response::PutMData);
let key0 = b"key0";
let value0_v0 = unwrap!(utils::generate_random_vector(10));
let actions = btree_map![
key0.to_vec() => EntryAction::Ins(Value {
content: value0_v0.clone(),
entry_version: 0,
})
];
let msg_id = MessageId::new();
unwrap!(routing.mutate_mdata_entries(client_mgr, name, tag, actions.clone(),
msg_id, owner_key));
expect_failure!(routing_rx,
msg_id,
Response::MutateMDataEntries,
ClientError::NetworkOther(..));
routing.remove_request_hook();
unwrap!(routing.mutate_mdata_entries(client_mgr, name, tag, actions, msg_id, owner_key));
expect_success!(routing_rx, msg_id, Response::MutateMDataEntries);
}
fn setup() -> (Routing, Receiver<Event>, FullId) {
let (routing, routing_rx, full_id) = setup_impl();
(routing, routing_rx, full_id)
}
fn setup_with_config(config: Config) -> (Routing, Receiver<Event>, FullId) {
let (mut routing, routing_rx, full_id) = setup_impl();
routing.set_vault(Arc::new(Mutex::new(Vault::new(config))));
(routing, routing_rx, full_id)
}
fn setup_impl() -> (Routing, Receiver<Event>, FullId) {
let full_id = FullId::new();
let (routing_tx, routing_rx) = mpsc::channel();
let routing = unwrap!(Routing::new(
routing_tx,
Some(full_id.clone()),
None,
Duration::new(0, 0),
));
match unwrap!(routing_rx.recv_timeout(Duration::from_secs(10))) {
Event::Connected => (),
e => panic!("Unexpected event {:?}", e),
}
(routing, routing_rx, full_id)
}
fn create_account(
routing: &mut Routing,
routing_rx: &Receiver<Event>,
owner_key: sign::PublicKey,
) -> Authority<XorName> {
let account_name = XorName(sha3_256(&owner_key[..]));
let account_data = unwrap!(MutableData::new(account_name,
TYPE_TAG_SESSION_PACKET,
Default::default(),
Default::default(),
btree_set![owner_key]));
let msg_id = MessageId::new();
unwrap!(routing.put_mdata(Authority::ClientManager(account_name),
account_data,
msg_id,
owner_key));
expect_success!(routing_rx, msg_id, Response::PutMData);
Authority::ClientManager(account_name)
}
fn account_info(
routing: &mut Routing,
routing_rx: &Receiver<Event>,
dst: Authority<XorName>,
) -> AccountInfo {
let msg_id = MessageId::new();
unwrap!(routing.get_account_info(dst, msg_id));
expect_success!(routing_rx, msg_id, Response::GetAccountInfo)
}