use std::path::Path;
use std::sync::Arc;
use kcode_k1_access::{
AccessId, Authorizations, K1Access, ModelId, OwnerSubject, SubsystemId, Target, TxId, UserId,
ViewerSubject,
};
use kcode_k1_access_kmap::{
AccessProfile, ConnectionSpec, ConnectionTier, K1AccessKmap, Measurement,
MeasurementImportance, Node, OpenMode, Weight,
};
use kcode_k1_access_profiles::{
AuthorizationProfile, K1AccessProfiles, ProfileOwner, ProfileSelection, ProfileViewer,
};
use kcode_k1_groups::{ALL_MODELS, K1Groups};
use kcode_k1_kmap::K1Kmap;
use kcode_k1_peering::K1Peering;
use kcode_k1_txn_ordering::K1TxnOrdering;
const ORIGINAL_TITLE: &str = "shared root";
const UPDATED_TITLE: &str = "shared root after authorized update";
pub fn verify() -> Result<(), String> {
let temporary =
tempfile::tempdir().map_err(|_| "create temporary root: local I/O error".to_string())?;
let root = temporary.path().to_path_buf();
let stack = Stack::open(&root)?;
let visible = create_leaf(
&stack,
user(1),
ProfileSelection::Inline(shared_profile_definition()?),
"visible child",
)?;
let hidden = create_leaf(&stack, user(1), ProfileSelection::BuiltIn, "hidden child")?;
let third_party = create_leaf(
&stack,
user(3),
ProfileSelection::BuiltIn,
"third-party child",
)?;
let root_id = create(
&stack,
user(1),
ProfileSelection::Inline(shared_profile_definition()?),
ORIGINAL_TITLE,
vec![edge(&visible), edge(&hidden)],
"create shared root",
)?;
verify_projection(&stack, &root_id, &visible, &hidden, ORIGINAL_TITLE)?;
verify_open(&stack, &root_id, &visible, &hidden)?;
verify_update_authority(&stack, &root_id, &visible, &hidden, &third_party)?;
let before_measurement = visible_weight(&stack, &root_id)?;
expect_unavailable(
stack
.facade
.apply_measurements(user(2), model(2), vec![measurement(&root_id, &visible)]),
"viewer measurement",
)?;
equal_weight(
visible_weight(&stack, &root_id)?,
before_measurement,
"denied measurement changed weight",
)?;
operation(
stack
.facade
.apply_measurements(user(1), model(1), vec![measurement(&root_id, &visible)]),
"apply owner measurement",
)?;
let measured_weight = visible_weight(&stack, &root_id)?;
require(
measured_weight != before_measurement,
"owner measurement did not change weight",
)?;
expect_unavailable(
stack.facade.create_node(
user(1),
model(1),
ProfileSelection::BuiltIn,
"rejected creation".to_string(),
"rejected navigation".to_string(),
"rejected narrative".to_string(),
vec![edge(&third_party)],
),
"creation with third-party target",
)?;
verify_bad_wrappers(&stack)?;
drop(stack);
let reopened = Stack::open(&root)?;
let after_restart = get(&reopened, user(2), model(2), &root_id, "restart root")?;
require(
after_restart.title == UPDATED_TITLE,
"authorized title did not survive restart",
)?;
equal_weight(
visible_edge(
&after_restart,
&visible,
"restart projection did not retain its single visible edge",
)?,
measured_weight,
"measured weight did not survive restart",
)?;
expect_unavailable(
reopened.facade.get_node(user(2), model(2), hidden),
"restart hidden direct read",
)
}
struct Stack {
_ordering: Arc<K1TxnOrdering>,
_peering: Arc<K1Peering>,
_groups: Arc<K1Groups>,
_profiles: Arc<K1AccessProfiles>,
access: Arc<K1Access>,
_kmap: Arc<K1Kmap>,
facade: K1AccessKmap,
}
impl Stack {
fn open(root: &Path) -> Result<Self, String> {
let path = |name| root.join(name);
let ordering = Arc::new(operation(
K1TxnOrdering::open(&path("ordering")),
"open transaction ordering",
)?);
let peering = Arc::new(operation(
K1Peering::open(&path("peering"), ordering.clone()),
"open peering",
)?);
let groups = Arc::new(operation(
K1Groups::open(&path("groups"), ordering.clone(), peering.clone()),
"open groups",
)?);
let profiles = Arc::new(operation(
K1AccessProfiles::open(&path("profiles"), ordering.clone(), peering.clone()),
"open access profiles",
)?);
let access = Arc::new(operation(
K1Access::open(
&path("access"),
ordering.clone(),
peering.clone(),
groups.clone(),
),
"open access",
)?);
let kmap = Arc::new(operation(
K1Kmap::open(&path("kmap"), ordering.clone(), peering.clone()),
"open kmap",
)?);
let facade = operation(
K1AccessKmap::open(access.clone(), profiles.clone(), kmap.clone()),
"open access-kmap facade",
)?;
Ok(Self {
_ordering: ordering,
_peering: peering,
_groups: groups,
_profiles: profiles,
access,
_kmap: kmap,
facade,
})
}
}
fn user(byte: u8) -> UserId {
UserId::from_tx_id(TxId::from_bytes([byte; 12]))
}
fn model(byte: u8) -> ModelId {
ModelId::from_bytes([byte; 32])
}
fn shared_profile_definition() -> Result<AuthorizationProfile, String> {
operation(
AuthorizationProfile::new(
vec![ProfileOwner::RequestUser],
vec![
ProfileViewer::User(user(2)),
ProfileViewer::Group(ALL_MODELS),
],
),
"build shared authorization profile",
)
}
fn edge(target: &AccessId) -> ConnectionSpec {
ConnectionSpec {
target: *target,
tier: ConnectionTier::Navigation,
}
}
fn measurement(source: &AccessId, target: &AccessId) -> Measurement {
Measurement {
source: *source,
target: *target,
useful: false,
importance: MeasurementImportance::NonCritical,
}
}
fn create_leaf(
stack: &Stack,
owner: UserId,
profile: AccessProfile,
title: &str,
) -> Result<AccessId, String> {
create(
stack,
owner,
profile,
title,
Vec::new(),
"create fixture leaf",
)
}
fn create(
stack: &Stack,
owner: UserId,
profile: AccessProfile,
title: &str,
connections: Vec<ConnectionSpec>,
label: &str,
) -> Result<AccessId, String> {
let revision = operation(
stack.facade.create_node(
owner,
model(1),
profile,
title.to_string(),
format!("navigation for {title}"),
format!("narrative for {title}"),
connections,
),
label,
)?;
Ok(revision.access_id())
}
fn get(
stack: &Stack,
request_user: UserId,
request_model: ModelId,
id: &AccessId,
label: &str,
) -> Result<Node, String> {
operation(
stack.facade.get_node(request_user, request_model, *id),
label,
)
}
fn visible_edge(node: &Node, visible: &AccessId, message: &str) -> Result<Weight, String> {
require(
node.connections.len() == 1 && node.connections[0].target == *visible,
message,
)?;
Ok(node.connections[0].weight)
}
fn verify_projection(
stack: &Stack,
root: &AccessId,
visible: &AccessId,
hidden: &AccessId,
expected_title: &str,
) -> Result<(), String> {
let projected = get(stack, user(2), model(2), root, "get projected root")?;
require(
projected.access_id == *root,
"projection returned wrong root",
)?;
require(
projected.title == expected_title,
"projection changed title",
)?;
visible_edge(
&projected,
visible,
"projection did not preserve exactly the visible edge",
)?;
expect_unavailable(
stack.facade.get_node(user(2), model(2), *hidden),
"hidden direct read",
)
}
fn verify_open(
stack: &Stack,
root: &AccessId,
visible: &AccessId,
hidden: &AccessId,
) -> Result<(), String> {
let opened = operation(
stack
.facade
.open_node(user(2), model(2), *root, 10.0, 0.0, OpenMode::Full),
"open projected root",
)?;
let contains = |id| opened.nodes.iter().any(|node| &node.access_id == id);
require(
contains(root)
&& contains(visible)
&& !contains(hidden)
&& opened
.nodes
.iter()
.all(|node| &node.access_id == root || &node.access_id == visible),
"full traversal projection was incorrect",
)
}
fn verify_update_authority(
stack: &Stack,
root: &AccessId,
visible: &AccessId,
hidden: &AccessId,
third_party: &AccessId,
) -> Result<(), String> {
expect_unavailable(
stack.facade.update_node(
user(2),
model(2),
*root,
Some("viewer edit".to_string()),
None,
None,
Vec::new(),
),
"viewer update",
)?;
let unchanged = get(stack, user(1), model(1), root, "read after viewer update")?;
require(unchanged.title == ORIGINAL_TITLE, "viewer changed title")?;
let connections_before = unchanged.connections.clone();
expect_unavailable(
stack.facade.update_node(
user(1),
model(1),
*root,
Some("must not commit".to_string()),
None,
None,
vec![edge(visible), edge(hidden), edge(third_party)],
),
"update with third-party target",
)?;
let denied = get(stack, user(1), model(1), root, "read after target denial")?;
require(
denied.title == ORIGINAL_TITLE && denied.connections == connections_before,
"target denial committed changes",
)?;
operation(
stack.facade.update_node(
user(1),
model(1),
*root,
Some(UPDATED_TITLE.to_string()),
None,
None,
vec![edge(visible), edge(hidden)],
),
"authorized title update",
)?;
let projected = get(stack, user(2), model(2), root, "read authorized title")?;
require(
projected.title == UPDATED_TITLE,
"authorized title is not visible to viewer",
)?;
visible_edge(
&projected,
visible,
"authorized title update changed projection",
)?;
Ok(())
}
fn visible_weight(stack: &Stack, root: &AccessId) -> Result<Weight, String> {
let projected = get(stack, user(2), model(2), root, "read visible weight")?;
visible_edge(
&projected,
&projected.connections[0].target,
"visible edge missing while reading weight",
)
}
fn verify_bad_wrappers(stack: &Stack) -> Result<(), String> {
for (subsystem, bytes, subsystem_label, create_label, read_label) in [
(
"k1-kmap",
vec![91; 11],
"build kmap subsystem",
"create malformed wrapper",
"malformed wrapper read",
),
(
"not-kmap",
vec![92; 12],
"build non-kmap subsystem",
"create wrong-subsystem wrapper",
"wrong-subsystem wrapper read",
),
] {
let target = Target::new(
operation(SubsystemId::from_str(subsystem), subsystem_label)?,
bytes,
);
let authorizations = operation(
Authorizations::new(
vec![OwnerSubject::User(user(1))],
vec![ViewerSubject::Group(ALL_MODELS)],
),
"build wrapper authorizations",
)?;
let wrapper = operation(stack.access.create(target, authorizations), create_label)?;
expect_unavailable(
stack
.facade
.get_node(user(1), model(1), wrapper.access_id()),
read_label,
)?;
}
Ok(())
}
fn operation<T>(result: Result<T, String>, label: &str) -> Result<T, String> {
result.map_err(|error| format!("{label}: {error}"))
}
fn expect_unavailable<T>(result: Result<T, String>, label: &str) -> Result<(), String> {
match result {
Err(error) if error == "node unavailable" => Ok(()),
_ => Err(format!("{label}: expected exact generic unavailability")),
}
}
fn require(condition: bool, message: &str) -> Result<(), String> {
if condition {
Ok(())
} else {
Err(message.to_string())
}
}
fn equal_weight(actual: Weight, expected: Weight, message: &str) -> Result<(), String> {
require(actual == expected, message)
}
#[cfg(test)]
mod tests {
#[test]
fn real_stack_conformance() {
super::verify().expect("K1 Access–Kmap conformance failed");
}
}