feat(users): per-user sealed folders users/<id>/{home,apps,data,permissions}; storage SET_USER/LOCK/PURGE; init sign-in/sign-out loop (purge fresh/removed/guest, seed from factory, session start/stop); shell logout; pm user+system app shelves; terminal SIGNED_OUT; per-program stack (gatekeeper 12p); 128K load scratch
This commit is contained in:
@@ -479,6 +479,11 @@ fn only_init_unlocks_and_only_once() {
|
||||
let set = |s: &mut Srv, badge, req| call(s, badge, req).0;
|
||||
let key = |half| StorageRequest::SetKey { half, words: [1, 2] };
|
||||
let seed = |half| StorageRequest::SetSeed { half, words: [3, 4] };
|
||||
let user = StorageRequest::SetUser { id: 7, guest: false };
|
||||
assert_eq!(set(&mut s, 0, key(0)), StorageResponse::Error, "not before saying whose");
|
||||
assert_eq!(set(&mut s, 5, user), StorageResponse::Error, "a client cannot say");
|
||||
assert_eq!(set(&mut s, 0, user), StorageResponse::Ok);
|
||||
assert_eq!(set(&mut s, 0, user), StorageResponse::Error, "once");
|
||||
assert_eq!(set(&mut s, 5, key(0)), StorageResponse::Error, "a client cannot");
|
||||
assert_eq!(set(&mut s, 0, key(0)), StorageResponse::Ok);
|
||||
assert_eq!(set(&mut s, 0, key(0)), StorageResponse::Error, "nor can a half be replaced");
|
||||
@@ -490,3 +495,40 @@ fn only_init_unlocks_and_only_once() {
|
||||
assert!(s.unlocked());
|
||||
assert_eq!(set(&mut s, 0, key(0)), StorageResponse::Error, "once unlocked, never again");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn locking_takes_every_grant_back_and_lets_the_next_user_in() {
|
||||
let mut s = server();
|
||||
let set = |s: &mut Srv, badge, req| call(s, badge, req).0;
|
||||
let init = Client::attach(&mut s, 0);
|
||||
let shell = init.narrowed(&mut s, b"", true);
|
||||
let app = shell.narrowed(&mut s, b"", false);
|
||||
for req in [StorageRequest::SetUser { id: 1, guest: false }, StorageRequest::SetKey { half: 0, words: [1, 2] }, StorageRequest::SetKey { half: 1, words: [1, 2] }, StorageRequest::SetSeed { half: 0, words: [1, 2] }, StorageRequest::SetSeed { half: 1, words: [1, 2] }] {
|
||||
assert_eq!(set(&mut s, 0, req), StorageResponse::Ok);
|
||||
}
|
||||
assert!(s.unlocked());
|
||||
assert_eq!(set(&mut s, shell.badge, StorageRequest::Lock), StorageResponse::Error, "only init signs out");
|
||||
assert_eq!(set(&mut s, 0, StorageRequest::Lock), StorageResponse::Ok);
|
||||
assert!(!s.unlocked());
|
||||
let revoked: Vec<usize> = s.host().revoked.iter().map(|c| badge_of(*c)).collect();
|
||||
assert_eq!(revoked, [shell.badge, app.badge]);
|
||||
assert_eq!(set(&mut s, shell.badge, StorageRequest::FileSize { handle: crate::filesystem::FileHandle::new(0) }), StorageResponse::Denied);
|
||||
assert_eq!(set(&mut s, 0, StorageRequest::SetUser { id: 2, guest: true }), StorageResponse::Ok, "someone else may sign in");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn only_init_purges_only_users_and_only_while_locked() {
|
||||
let mut s = server();
|
||||
let init = Client::attach(&mut s, 0);
|
||||
let shell = init.narrowed(&mut s, b"", true);
|
||||
let purge = |s: &mut Srv, badge: usize, path: &[u8]| {
|
||||
init.put(s, path);
|
||||
call(s, badge, StorageRequest::Purge { path_len: path.len() }).0
|
||||
};
|
||||
assert_eq!(purge(&mut s, shell.badge, b"users/x"), StorageResponse::Error);
|
||||
assert_eq!(purge(&mut s, 0, b"bin"), StorageResponse::Denied);
|
||||
assert_eq!(purge(&mut s, 0, b"users/../bin"), StorageResponse::Denied);
|
||||
assert_eq!(purge(&mut s, 0, b"users/"), StorageResponse::Denied);
|
||||
assert_eq!(purge(&mut s, 0, b"users/x"), StorageResponse::Ok);
|
||||
assert_eq!(purge(&mut s, 0, b"users"), StorageResponse::Ok);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user