feat: add log-server (ring buffer) and permission-manager (grant/revoke/check) system servers

This commit is contained in:
2026-10-18 03:14:48 +02:00
parent 919e918c0a
commit 36cab28506
15 changed files with 631 additions and 12 deletions

View File

@@ -0,0 +1,2 @@
mod protocol;
mod server;

View File

@@ -0,0 +1,59 @@
use crate::protocol::*;
use server_framework::{Decode, Encode};
#[test]
fn request_capability_roundtrip() {
let req = PermissionRequest::RequestCapability { process: 5, kind: CapabilityKind::Camera };
assert_eq!(PermissionRequest::decode(req.encode()), Some(req));
}
#[test]
fn revoke_capability_roundtrip() {
let req = PermissionRequest::RevokeCapability { process: 3, kind: CapabilityKind::Network };
assert_eq!(PermissionRequest::decode(req.encode()), Some(req));
}
#[test]
fn check_capability_roundtrip() {
let req = PermissionRequest::CheckCapability { process: 1, kind: CapabilityKind::Storage };
assert_eq!(PermissionRequest::decode(req.encode()), Some(req));
}
#[test]
fn list_granted_roundtrip() {
let req = PermissionRequest::ListGranted { process: 7 };
assert_eq!(PermissionRequest::decode(req.encode()), Some(req));
}
#[test]
fn all_kinds_roundtrip() {
let kinds = [
CapabilityKind::Display, CapabilityKind::Input, CapabilityKind::AudioPlayback,
CapabilityKind::AudioCapture, CapabilityKind::Camera, CapabilityKind::Storage,
CapabilityKind::Network, CapabilityKind::Gps, CapabilityKind::Bluetooth,
];
for kind in kinds {
let req = PermissionRequest::RequestCapability { process: 0, kind };
assert_eq!(PermissionRequest::decode(req.encode()), Some(req));
}
}
#[test]
fn response_roundtrips() {
let responses = [
PermissionResponse::Granted,
PermissionResponse::Denied,
PermissionResponse::Revoked,
PermissionResponse::HasCapability(true),
PermissionResponse::HasCapability(false),
PermissionResponse::GrantedList(0b101),
];
for resp in responses {
assert_eq!(PermissionResponse::decode(resp.encode()), Some(resp));
}
}
#[test]
fn invalid_request_returns_none() {
assert!(PermissionRequest::decode([99, 0, 0, 0]).is_none());
}

View File

@@ -0,0 +1,85 @@
use crate::protocol::*;
use crate::server::PermissionManager;
use server_framework::Server;
#[test]
fn new_manager_has_no_grants() {
let mut mgr = PermissionManager::new();
let resp = mgr.handle(PermissionRequest::CheckCapability {
process: 0,
kind: CapabilityKind::Camera,
});
assert_eq!(resp, PermissionResponse::HasCapability(false));
}
#[test]
fn grant_then_check() {
let mut mgr = PermissionManager::new();
mgr.handle(PermissionRequest::RequestCapability {
process: 1,
kind: CapabilityKind::Network,
});
let resp = mgr.handle(PermissionRequest::CheckCapability {
process: 1,
kind: CapabilityKind::Network,
});
assert_eq!(resp, PermissionResponse::HasCapability(true));
}
#[test]
fn grant_does_not_affect_other_process() {
let mut mgr = PermissionManager::new();
mgr.handle(PermissionRequest::RequestCapability {
process: 1,
kind: CapabilityKind::Camera,
});
let resp = mgr.handle(PermissionRequest::CheckCapability {
process: 2,
kind: CapabilityKind::Camera,
});
assert_eq!(resp, PermissionResponse::HasCapability(false));
}
#[test]
fn revoke_removes_grant() {
let mut mgr = PermissionManager::new();
mgr.handle(PermissionRequest::RequestCapability {
process: 0,
kind: CapabilityKind::Storage,
});
mgr.handle(PermissionRequest::RevokeCapability {
process: 0,
kind: CapabilityKind::Storage,
});
let resp = mgr.handle(PermissionRequest::CheckCapability {
process: 0,
kind: CapabilityKind::Storage,
});
assert_eq!(resp, PermissionResponse::HasCapability(false));
}
#[test]
fn list_granted_returns_bitfield() {
let mut mgr = PermissionManager::new();
mgr.handle(PermissionRequest::RequestCapability {
process: 0,
kind: CapabilityKind::Display,
});
mgr.handle(PermissionRequest::RequestCapability {
process: 0,
kind: CapabilityKind::Network,
});
let resp = mgr.handle(PermissionRequest::ListGranted { process: 0 });
// Display=bit 0, Network=bit 6 → 0b1000001 = 65
assert_eq!(resp, PermissionResponse::GrantedList(0b1000001));
}
#[test]
fn out_of_range_process_denied() {
let mut mgr = PermissionManager::new();
let resp = mgr.handle(PermissionRequest::RequestCapability {
process: 999,
kind: CapabilityKind::Camera,
});
assert_eq!(resp, PermissionResponse::Denied);
}