mirror of
https://gitlab.com/veilid/veilid.git
synced 2025-07-27 00:45:39 -04:00
Gate insecure capabilities behind footgun feature
This commit is contained in:
parent
29eeebd9c1
commit
7a2a8ae4cb
15 changed files with 143 additions and 77 deletions
|
@ -8,6 +8,10 @@
|
||||||
- Renamed config structs to better describe their purpose, and remove "Inner" from a struct that's being exposed via the API. ([!402](https://gitlab.com/veilid/veilid/-/merge_requests/402))
|
- Renamed config structs to better describe their purpose, and remove "Inner" from a struct that's being exposed via the API. ([!402](https://gitlab.com/veilid/veilid/-/merge_requests/402))
|
||||||
- `VeilidConfig` -> `VeilidStartupOptions`
|
- `VeilidConfig` -> `VeilidStartupOptions`
|
||||||
- `VeilidConfigInner` -> `VeilidConfig`
|
- `VeilidConfigInner` -> `VeilidConfig`
|
||||||
|
- Gate insecure capabilities behind the new `footgun` feature flag ([#394](https://gitlab.com/veilid/veilid/-/issues/394)), which is disabled by default. ([!400](https://gitlab.com/veilid/veilid/-/merge_requests/400))
|
||||||
|
- Calling `app_call` or `app_message` with a `NodeId` target will throw an error. Use a `PrivateRoute` target instead.
|
||||||
|
- Creating an `Unsafe` routing context will throw and error. Use `Safe` routing context instead.
|
||||||
|
- Any AppCall or AppMessage sent from a direct NodeId will not be received.
|
||||||
|
|
||||||
- veilid-core:
|
- veilid-core:
|
||||||
- **Security** Signed bootstrap v1 added which closes #293: https://gitlab.com/veilid/veilid/-/issues/293
|
- **Security** Signed bootstrap v1 added which closes #293: https://gitlab.com/veilid/veilid/-/issues/293
|
||||||
|
|
|
@ -62,6 +62,10 @@ virtual-network-server = ["veilid-tools/virtual-network-server"]
|
||||||
# GeoIP
|
# GeoIP
|
||||||
geolocation = ["maxminddb", "reqwest"]
|
geolocation = ["maxminddb", "reqwest"]
|
||||||
|
|
||||||
|
# Features that go against "Natural Security" concepts
|
||||||
|
# https://gitlab.com/veilid/veilid/-/issues/420
|
||||||
|
footgun = []
|
||||||
|
|
||||||
### DEPENDENCIES
|
### DEPENDENCIES
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
|
|
|
@ -73,6 +73,11 @@ impl VeilidCoreContext {
|
||||||
veilid_log!(registry info "Veilid API starting up");
|
veilid_log!(registry info "Veilid API starting up");
|
||||||
veilid_log!(registry info "Version: {}", veilid_version_string());
|
veilid_log!(registry info "Version: {}", veilid_version_string());
|
||||||
veilid_log!(registry info "Features: {:?}", veilid_features());
|
veilid_log!(registry info "Features: {:?}", veilid_features());
|
||||||
|
#[cfg(feature = "footgun")]
|
||||||
|
{
|
||||||
|
veilid_log!(registry warn
|
||||||
|
"Footgun feature is enabled. This disables sender privacy protections and should be avoided in production.");
|
||||||
|
}
|
||||||
|
|
||||||
// Register all components
|
// Register all components
|
||||||
registry.register(ProtectedStore::new);
|
registry.register(ProtectedStore::new);
|
||||||
|
|
|
@ -118,6 +118,15 @@ impl RPCProcessor {
|
||||||
.as_ref()
|
.as_ref()
|
||||||
.map(|nr| nr.node_ids().get(crypto_kind).unwrap());
|
.map(|nr| nr.node_ids().get(crypto_kind).unwrap());
|
||||||
|
|
||||||
|
#[cfg(not(feature = "footgun"))]
|
||||||
|
{
|
||||||
|
if sender.is_some() {
|
||||||
|
return Ok(NetworkResult::invalid_message(
|
||||||
|
"Direct NodeId senders are not allowed for AppCall when footgun is disabled",
|
||||||
|
));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Register a waiter for this app call
|
// Register a waiter for this app call
|
||||||
let handle = self.waiting_app_call_table.add_op_waiter(op_id, ());
|
let handle = self.waiting_app_call_table.add_op_waiter(op_id, ());
|
||||||
|
|
||||||
|
|
|
@ -81,6 +81,15 @@ impl RPCProcessor {
|
||||||
.as_ref()
|
.as_ref()
|
||||||
.map(|nr| nr.node_ids().get(crypto_kind).unwrap());
|
.map(|nr| nr.node_ids().get(crypto_kind).unwrap());
|
||||||
|
|
||||||
|
#[cfg(not(feature = "footgun"))]
|
||||||
|
{
|
||||||
|
if sender.is_some() {
|
||||||
|
return Ok(NetworkResult::invalid_message(
|
||||||
|
"Direct NodeId senders are not allowed for AppMessage when footgun is disabled",
|
||||||
|
));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Pass the message up through the update callback
|
// Pass the message up through the update callback
|
||||||
let message = app_message.destructure();
|
let message = app_message.destructure();
|
||||||
(self.update_callback())(VeilidUpdate::AppMessage(Box::new(VeilidAppMessage::new(
|
(self.update_callback())(VeilidUpdate::AppMessage(Box::new(VeilidAppMessage::new(
|
||||||
|
|
|
@ -11,55 +11,35 @@ lazy_static! {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn test_get_dht_value_unopened(api: VeilidAPI) {
|
pub async fn test_get_dht_value_unopened(api: VeilidAPI) {
|
||||||
let rc = api
|
let rc = api.routing_context().unwrap();
|
||||||
.routing_context()
|
|
||||||
.unwrap()
|
|
||||||
.with_safety(SafetySelection::Unsafe(Sequencing::EnsureOrdered))
|
|
||||||
.unwrap();
|
|
||||||
|
|
||||||
let result = rc.get_dht_value(*BOGUS_KEY, 0, false).await;
|
let result = rc.get_dht_value(*BOGUS_KEY, 0, false).await;
|
||||||
assert_err!(result);
|
assert_err!(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn test_open_dht_record_nonexistent_no_writer(api: VeilidAPI) {
|
pub async fn test_open_dht_record_nonexistent_no_writer(api: VeilidAPI) {
|
||||||
let rc = api
|
let rc = api.routing_context().unwrap();
|
||||||
.routing_context()
|
|
||||||
.unwrap()
|
|
||||||
.with_safety(SafetySelection::Unsafe(Sequencing::EnsureOrdered))
|
|
||||||
.unwrap();
|
|
||||||
|
|
||||||
let result = rc.get_dht_value(*BOGUS_KEY, 0, false).await;
|
let result = rc.get_dht_value(*BOGUS_KEY, 0, false).await;
|
||||||
assert_err!(result);
|
assert_err!(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn test_close_dht_record_nonexistent(api: VeilidAPI) {
|
pub async fn test_close_dht_record_nonexistent(api: VeilidAPI) {
|
||||||
let rc = api
|
let rc = api.routing_context().unwrap();
|
||||||
.routing_context()
|
|
||||||
.unwrap()
|
|
||||||
.with_safety(SafetySelection::Unsafe(Sequencing::EnsureOrdered))
|
|
||||||
.unwrap();
|
|
||||||
|
|
||||||
let result = rc.close_dht_record(*BOGUS_KEY).await;
|
let result = rc.close_dht_record(*BOGUS_KEY).await;
|
||||||
assert_err!(result);
|
assert_err!(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn test_delete_dht_record_nonexistent(api: VeilidAPI) {
|
pub async fn test_delete_dht_record_nonexistent(api: VeilidAPI) {
|
||||||
let rc = api
|
let rc = api.routing_context().unwrap();
|
||||||
.routing_context()
|
|
||||||
.unwrap()
|
|
||||||
.with_safety(SafetySelection::Unsafe(Sequencing::EnsureOrdered))
|
|
||||||
.unwrap();
|
|
||||||
|
|
||||||
let result = rc.delete_dht_record(*BOGUS_KEY).await;
|
let result = rc.delete_dht_record(*BOGUS_KEY).await;
|
||||||
assert_err!(result);
|
assert_err!(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn test_create_delete_dht_record_simple(api: VeilidAPI) {
|
pub async fn test_create_delete_dht_record_simple(api: VeilidAPI) {
|
||||||
let rc = api
|
let rc = api.routing_context().unwrap();
|
||||||
.routing_context()
|
|
||||||
.unwrap()
|
|
||||||
.with_safety(SafetySelection::Unsafe(Sequencing::EnsureOrdered))
|
|
||||||
.unwrap();
|
|
||||||
|
|
||||||
let rec = rc
|
let rec = rc
|
||||||
.create_dht_record(DHTSchema::dflt(1).unwrap(), None, Some(CRYPTO_KIND_VLD0))
|
.create_dht_record(DHTSchema::dflt(1).unwrap(), None, Some(CRYPTO_KIND_VLD0))
|
||||||
|
@ -72,11 +52,7 @@ pub async fn test_create_delete_dht_record_simple(api: VeilidAPI) {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn test_create_dht_record_with_owner(api: VeilidAPI) {
|
pub async fn test_create_dht_record_with_owner(api: VeilidAPI) {
|
||||||
let rc = api
|
let rc = api.routing_context().unwrap();
|
||||||
.routing_context()
|
|
||||||
.unwrap()
|
|
||||||
.with_safety(SafetySelection::Unsafe(Sequencing::EnsureOrdered))
|
|
||||||
.unwrap();
|
|
||||||
|
|
||||||
let crypto = api.crypto().unwrap();
|
let crypto = api.crypto().unwrap();
|
||||||
let cs = crypto.get(CRYPTO_KIND_VLD0).unwrap();
|
let cs = crypto.get(CRYPTO_KIND_VLD0).unwrap();
|
||||||
|
@ -99,11 +75,7 @@ pub async fn test_create_dht_record_with_owner(api: VeilidAPI) {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn test_get_dht_record_key(api: VeilidAPI) {
|
pub async fn test_get_dht_record_key(api: VeilidAPI) {
|
||||||
let rc = api
|
let rc = api.routing_context().unwrap();
|
||||||
.routing_context()
|
|
||||||
.unwrap()
|
|
||||||
.with_safety(SafetySelection::Unsafe(Sequencing::EnsureOrdered))
|
|
||||||
.unwrap();
|
|
||||||
|
|
||||||
let crypto = api.crypto().unwrap();
|
let crypto = api.crypto().unwrap();
|
||||||
let cs = crypto.get(CRYPTO_KIND_VLD0).unwrap();
|
let cs = crypto.get(CRYPTO_KIND_VLD0).unwrap();
|
||||||
|
@ -130,11 +102,7 @@ pub async fn test_get_dht_record_key(api: VeilidAPI) {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn test_get_dht_value_nonexistent(api: VeilidAPI) {
|
pub async fn test_get_dht_value_nonexistent(api: VeilidAPI) {
|
||||||
let rc = api
|
let rc = api.routing_context().unwrap();
|
||||||
.routing_context()
|
|
||||||
.unwrap()
|
|
||||||
.with_safety(SafetySelection::Unsafe(Sequencing::EnsureOrdered))
|
|
||||||
.unwrap();
|
|
||||||
|
|
||||||
let rec = rc
|
let rec = rc
|
||||||
.create_dht_record(DHTSchema::dflt(1).unwrap(), None, Some(CRYPTO_KIND_VLD0))
|
.create_dht_record(DHTSchema::dflt(1).unwrap(), None, Some(CRYPTO_KIND_VLD0))
|
||||||
|
@ -149,11 +117,7 @@ pub async fn test_get_dht_value_nonexistent(api: VeilidAPI) {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn test_set_get_dht_value(api: VeilidAPI) {
|
pub async fn test_set_get_dht_value(api: VeilidAPI) {
|
||||||
let rc = api
|
let rc = api.routing_context().unwrap();
|
||||||
.routing_context()
|
|
||||||
.unwrap()
|
|
||||||
.with_safety(SafetySelection::Unsafe(Sequencing::EnsureOrdered))
|
|
||||||
.unwrap();
|
|
||||||
|
|
||||||
let rec = rc
|
let rec = rc
|
||||||
.create_dht_record(DHTSchema::dflt(2).unwrap(), None, Some(CRYPTO_KIND_VLD0))
|
.create_dht_record(DHTSchema::dflt(2).unwrap(), None, Some(CRYPTO_KIND_VLD0))
|
||||||
|
@ -201,11 +165,7 @@ pub async fn test_set_get_dht_value(api: VeilidAPI) {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn test_open_writer_dht_value(api: VeilidAPI) {
|
pub async fn test_open_writer_dht_value(api: VeilidAPI) {
|
||||||
let rc = api
|
let rc = api.routing_context().unwrap();
|
||||||
.routing_context()
|
|
||||||
.unwrap()
|
|
||||||
.with_safety(SafetySelection::Unsafe(Sequencing::EnsureOrdered))
|
|
||||||
.unwrap();
|
|
||||||
|
|
||||||
let rec = rc
|
let rec = rc
|
||||||
.create_dht_record(DHTSchema::dflt(2).unwrap(), None, Some(CRYPTO_KIND_VLD0))
|
.create_dht_record(DHTSchema::dflt(2).unwrap(), None, Some(CRYPTO_KIND_VLD0))
|
||||||
|
|
|
@ -101,6 +101,15 @@ impl RoutingContext {
|
||||||
veilid_log!(self debug
|
veilid_log!(self debug
|
||||||
"RoutingContext::with_safety(self: {:?}, safety_selection: {:?})", self, safety_selection);
|
"RoutingContext::with_safety(self: {:?}, safety_selection: {:?})", self, safety_selection);
|
||||||
|
|
||||||
|
if let SafetySelection::Unsafe(_) = safety_selection {
|
||||||
|
#[cfg(not(feature = "footgun"))]
|
||||||
|
{
|
||||||
|
return Err(VeilidAPIError::generic(
|
||||||
|
"Unsafe routing mode is not allowed without the 'footgun' feature enabled",
|
||||||
|
));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Ok(Self {
|
Ok(Self {
|
||||||
api: self.api.clone(),
|
api: self.api.clone(),
|
||||||
unlocked_inner: Arc::new(RoutingContextUnlockedInner { safety_selection }),
|
unlocked_inner: Arc::new(RoutingContextUnlockedInner { safety_selection }),
|
||||||
|
@ -161,19 +170,12 @@ impl RoutingContext {
|
||||||
.map_err(VeilidAPIError::invalid_target)
|
.map_err(VeilidAPIError::invalid_target)
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////
|
|
||||||
// App-level Messaging
|
|
||||||
|
|
||||||
/// App-level bidirectional call that expects a response to be returned.
|
|
||||||
///
|
|
||||||
/// Veilid apps may use this for arbitrary message passing.
|
|
||||||
///
|
|
||||||
/// * `target` - can be either a direct node id or a private route.
|
|
||||||
/// * `message` - an arbitrary message blob of up to 32768 bytes.
|
|
||||||
///
|
|
||||||
/// Returns an answer blob of up to 32768 bytes.
|
|
||||||
#[instrument(target = "veilid_api", level = "debug", fields(__VEILID_LOG_KEY = self.log_key()), ret, err)]
|
#[instrument(target = "veilid_api", level = "debug", fields(__VEILID_LOG_KEY = self.log_key()), ret, err)]
|
||||||
pub async fn app_call(&self, target: Target, message: Vec<u8>) -> VeilidAPIResult<Vec<u8>> {
|
async fn internal_app_call(
|
||||||
|
&self,
|
||||||
|
target: Target,
|
||||||
|
message: Vec<u8>,
|
||||||
|
) -> VeilidAPIResult<Vec<u8>> {
|
||||||
veilid_log!(self debug
|
veilid_log!(self debug
|
||||||
"RoutingContext::app_call(self: {:?}, target: {:?}, message: {:?})", self, target, message);
|
"RoutingContext::app_call(self: {:?}, target: {:?}, message: {:?})", self, target, message);
|
||||||
|
|
||||||
|
@ -200,14 +202,45 @@ impl RoutingContext {
|
||||||
Ok(answer.answer)
|
Ok(answer.answer)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// App-level unidirectional message that does not expect any value to be returned.
|
#[cfg(feature = "footgun")]
|
||||||
|
////////////////////////////////////////////////////////////////
|
||||||
|
// App-level Messaging
|
||||||
|
|
||||||
|
/// App-level bidirectional call that expects a response to be returned.
|
||||||
///
|
///
|
||||||
/// Veilid apps may use this for arbitrary message passing.
|
/// Veilid apps may use this for arbitrary message passing.
|
||||||
///
|
///
|
||||||
/// * `target` - can be either a direct node id or a private route.
|
/// * `target` - can be either a direct node id or a private route.
|
||||||
/// * `message` - an arbitrary message blob of up to 32768 bytes.
|
/// * `message` - an arbitrary message blob of up to 32768 bytes.
|
||||||
|
///
|
||||||
|
/// Returns an answer blob of up to 32768 bytes.
|
||||||
|
pub async fn app_call(&self, target: Target, message: Vec<u8>) -> VeilidAPIResult<Vec<u8>> {
|
||||||
|
self.internal_app_call(target, message).await
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(not(feature = "footgun"))]
|
||||||
|
////////////////////////////////////////////////////////////////
|
||||||
|
// App-level Messaging
|
||||||
|
|
||||||
|
/// App-level bidirectional call that expects a response to be returned.
|
||||||
|
///
|
||||||
|
/// Veilid apps may use this for arbitrary message passing.
|
||||||
|
///
|
||||||
|
/// * `target` - a private route.
|
||||||
|
/// * `message` - an arbitrary message blob of up to 32768 bytes.
|
||||||
|
///
|
||||||
|
/// Returns an answer blob of up to 32768 bytes.
|
||||||
|
pub async fn app_call(&self, target: Target, message: Vec<u8>) -> VeilidAPIResult<Vec<u8>> {
|
||||||
|
match target {
|
||||||
|
Target::PrivateRoute(_) => self.internal_app_call(target, message).await,
|
||||||
|
Target::NodeId(_) => Err(VeilidAPIError::invalid_target(
|
||||||
|
"Only PrivateRoute targets are allowed without the footgun feature",
|
||||||
|
)),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[instrument(target = "veilid_api", level = "debug", fields(__VEILID_LOG_KEY = self.log_key()), ret, err)]
|
#[instrument(target = "veilid_api", level = "debug", fields(__VEILID_LOG_KEY = self.log_key()), ret, err)]
|
||||||
pub async fn app_message(&self, target: Target, message: Vec<u8>) -> VeilidAPIResult<()> {
|
async fn internal_app_message(&self, target: Target, message: Vec<u8>) -> VeilidAPIResult<()> {
|
||||||
veilid_log!(self debug
|
veilid_log!(self debug
|
||||||
"RoutingContext::app_message(self: {:?}, target: {:?}, message: {:?})", self, target, message);
|
"RoutingContext::app_message(self: {:?}, target: {:?}, message: {:?})", self, target, message);
|
||||||
|
|
||||||
|
@ -233,6 +266,33 @@ impl RoutingContext {
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(feature = "footgun")]
|
||||||
|
/// App-level unidirectional message that does not expect any value to be returned.
|
||||||
|
///
|
||||||
|
/// Veilid apps may use this for arbitrary message passing.
|
||||||
|
///
|
||||||
|
/// * `target` - can be either a direct node id or a private route.
|
||||||
|
/// * `message` - an arbitrary message blob of up to 32768 bytes.
|
||||||
|
pub async fn app_message(&self, target: Target, message: Vec<u8>) -> VeilidAPIResult<()> {
|
||||||
|
self.internal_app_message(target, message).await
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(not(feature = "footgun"))]
|
||||||
|
/// App-level unidirectional message that does not expect any value to be returned.
|
||||||
|
///
|
||||||
|
/// Veilid apps may use this for arbitrary message passing.
|
||||||
|
///
|
||||||
|
/// * `target` - a private route.
|
||||||
|
/// * `message` - an arbitrary message blob of up to 32768 bytes.
|
||||||
|
pub async fn app_message(&self, target: Target, message: Vec<u8>) -> VeilidAPIResult<()> {
|
||||||
|
match target {
|
||||||
|
Target::PrivateRoute(_) => self.internal_app_message(target, message).await,
|
||||||
|
Target::NodeId(_) => Err(VeilidAPIError::invalid_target(
|
||||||
|
"Only PrivateRoute targets are allowed without the footgun feature",
|
||||||
|
)),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
///////////////////////////////////
|
///////////////////////////////////
|
||||||
// DHT Records
|
// DHT Records
|
||||||
|
|
||||||
|
|
|
@ -319,7 +319,7 @@ Future<void> testWatchDHTValues(Stream<VeilidUpdate> updateStream) async {
|
||||||
// as the watch's target
|
// as the watch's target
|
||||||
|
|
||||||
final rcSet = await Veilid.instance.routingContext();
|
final rcSet = await Veilid.instance.routingContext();
|
||||||
final rcWatch = await Veilid.instance.unsafeRoutingContext();
|
final rcWatch = await Veilid.instance.safeRoutingContext();
|
||||||
try {
|
try {
|
||||||
// Make a DHT record
|
// Make a DHT record
|
||||||
var rec = await rcWatch.createDHTRecord(const DHTSchema.dflt(oCnt: 10));
|
var rec = await rcWatch.createDHTRecord(const DHTSchema.dflt(oCnt: 10));
|
||||||
|
|
|
@ -32,6 +32,7 @@ rt-tokio = [
|
||||||
"opentelemetry/rt-tokio",
|
"opentelemetry/rt-tokio",
|
||||||
]
|
]
|
||||||
debug-load = ["dep:ctor", "dep:libc-print", "dep:android_log-sys", "dep:oslog"]
|
debug-load = ["dep:ctor", "dep:libc-print", "dep:android_log-sys", "dep:oslog"]
|
||||||
|
footgun = ["veilid-core/footgun"]
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
veilid-core = { path = "../../veilid-core", default-features = false }
|
veilid-core = { path = "../../veilid-core", default-features = false }
|
||||||
|
|
|
@ -448,11 +448,11 @@ async def test_watch_many_dht_values():
|
||||||
|
|
||||||
# make routing contexts
|
# make routing contexts
|
||||||
# unsafe version for debugging
|
# unsafe version for debugging
|
||||||
rc0 = await (await api0.new_routing_context()).with_safety(SafetySelection.unsafe())
|
# rc0 = await (await api0.new_routing_context()).with_safety(SafetySelection.unsafe())
|
||||||
rc1 = await (await api1.new_routing_context()).with_safety(SafetySelection.unsafe())
|
# rc1 = await (await api1.new_routing_context()).with_safety(SafetySelection.unsafe())
|
||||||
# safe default version
|
# safe default version
|
||||||
# rc0 = await api0.new_routing_context()
|
rc0 = await api0.new_routing_context()
|
||||||
# rc1 = await api1.new_routing_context()
|
rc1 = await api1.new_routing_context()
|
||||||
|
|
||||||
async with rc0, rc1:
|
async with rc0, rc1:
|
||||||
|
|
||||||
|
|
|
@ -34,9 +34,15 @@ async def test_routing_contexts(api_connection: veilid.VeilidAPI):
|
||||||
)
|
)
|
||||||
await rc.release()
|
await rc.release()
|
||||||
|
|
||||||
rc = await (await api_connection.new_routing_context()).with_safety(
|
|
||||||
|
# Test that creating an Unsafe routing context throws an error
|
||||||
|
# as mentioned in the CHANGELOG (footgun feature disabled by default)
|
||||||
|
rc = await api_connection.new_routing_context()
|
||||||
|
with pytest.raises(Exception):
|
||||||
|
rc = await rc.with_safety(
|
||||||
veilid.SafetySelection.unsafe(veilid.Sequencing.PREFER_ORDERED)
|
veilid.SafetySelection.unsafe(veilid.Sequencing.PREFER_ORDERED)
|
||||||
)
|
)
|
||||||
|
|
||||||
await rc.release()
|
await rc.release()
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -18,6 +18,7 @@ path = "src/main.rs"
|
||||||
[features]
|
[features]
|
||||||
default = ["rt-tokio", "veilid-core/default", "otlp-tonic"]
|
default = ["rt-tokio", "veilid-core/default", "otlp-tonic"]
|
||||||
default-async-std = ["rt-async-std", "veilid-core/default-async-std"]
|
default-async-std = ["rt-async-std", "veilid-core/default-async-std"]
|
||||||
|
footgun = ["veilid-core/footgun"]
|
||||||
|
|
||||||
virtual-network = [
|
virtual-network = [
|
||||||
"veilid-core/virtual-network",
|
"veilid-core/virtual-network",
|
||||||
|
|
|
@ -18,6 +18,7 @@ path = "src/lib.rs"
|
||||||
[features]
|
[features]
|
||||||
default = ["veilid-core/default-wasm"]
|
default = ["veilid-core/default-wasm"]
|
||||||
crypto-test = ["veilid-core/crypto-test"]
|
crypto-test = ["veilid-core/crypto-test"]
|
||||||
|
footgun = ["veilid-core/footgun"]
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
veilid-core = { version = "0.4.4", path = "../veilid-core", default-features = false }
|
veilid-core = { version = "0.4.4", path = "../veilid-core", default-features = false }
|
||||||
|
|
|
@ -23,7 +23,7 @@ describe('VeilidRoutingContext', () => {
|
||||||
// }
|
// }
|
||||||
}, veilidCoreStartupConfig);
|
}, veilidCoreStartupConfig);
|
||||||
await veilidClient.attach();
|
await veilidClient.attach();
|
||||||
await asyncCallWithTimeout(waitForPublicAttachment(), 10000);
|
await asyncCallWithTimeout(waitForPublicAttachment(), 30_000);
|
||||||
//console.log("---Started Up---");
|
//console.log("---Started Up---");
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -65,15 +65,21 @@ describe('VeilidRoutingContext', () => {
|
||||||
VeilidRoutingContext.create().withSequencing('EnsureOrdered');
|
VeilidRoutingContext.create().withSequencing('EnsureOrdered');
|
||||||
expect(routingContext instanceof VeilidRoutingContext).toBe(true);
|
expect(routingContext instanceof VeilidRoutingContext).toBe(true);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('should error if unsafe is used', async () => {
|
||||||
|
expect(() => {
|
||||||
|
VeilidRoutingContext.create().withSafety({
|
||||||
|
Unsafe: 'EnsureOrdered',
|
||||||
|
});
|
||||||
|
}).toThrow();
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('operations', () => {
|
describe('operations', () => {
|
||||||
let routingContext: VeilidRoutingContext;
|
let routingContext: VeilidRoutingContext;
|
||||||
|
|
||||||
before('create routing context', () => {
|
before('create routing context', () => {
|
||||||
routingContext = VeilidRoutingContext.create().withSafety({
|
routingContext = VeilidRoutingContext.create();
|
||||||
Unsafe: 'EnsureOrdered',
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('createDhtRecord', () => {
|
describe('createDhtRecord', () => {
|
||||||
|
|
|
@ -75,7 +75,7 @@ describe('veilidClient', function () {
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should call debug command', async function () {
|
it('should call debug command', async function () {
|
||||||
const response = await veilidClient.debug('txtrecord');
|
const response = await veilidClient.debug('help');
|
||||||
expect(response).toBeDefined();
|
expect(response).toBeDefined();
|
||||||
expect(response.length).toBeGreaterThan(0);
|
expect(response.length).toBeGreaterThan(0);
|
||||||
});
|
});
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue