rhi

Coordinated trade for connected markets
git clone https://radroots.dev/git/rhi.git
Log | Files | Refs | README | LICENSE

services_hardening_admin_identity_offline.rs (3581B)


      1 #![forbid(unsafe_code)]
      2 
      3 use rhi::RhiAdminRoute;
      4 use serde_json::Value;
      5 
      6 const OFFLINE_IDENTITY_CONTRACT: &str =
      7     include_str!("../contracts/services_hardening/admin_identity_offline.v1.json");
      8 const OPERATOR_CONTRACT: &str =
      9     include_str!("../contracts/services_hardening/operator_contract.v1.json");
     10 const ADMIN_SOURCE: &str = include_str!("../src/admin_v1.rs");
     11 const ROOT_SOURCE: &str = include_str!("../src/lib.rs");
     12 
     13 #[test]
     14 fn final_identity_policy_is_offline_only_and_inventory_is_exact() {
     15     let policy: Value =
     16         serde_json::from_str(OFFLINE_IDENTITY_CONTRACT).expect("offline identity contract");
     17     let operator: Value = serde_json::from_str(OPERATOR_CONTRACT).expect("operator contract");
     18 
     19     assert_eq!(policy["schema"], "radroots.rhi.admin-identity-offline.v1");
     20     assert_eq!(policy["contract_version"], 1);
     21     assert_eq!(policy["final_inventory"]["route_count"], 20);
     22     assert_eq!(policy["final_inventory"]["model_count"], 33);
     23     assert_eq!(
     24         policy["identity_rotation"]["mode"],
     25         "offline_create_new_configuration_apply_restart"
     26     );
     27     assert_eq!(policy["identity_rotation"]["unix_admin_mutation"], false);
     28     assert_eq!(
     29         policy["peer_authorization"]["grants_identity_provider_authority"],
     30         false
     31     );
     32     assert_eq!(
     33         policy["peer_authorization"]["grants_direct_sqlite_authority"],
     34         false
     35     );
     36 
     37     let routes = operator["admin"]["routes"].as_array().expect("routes");
     38     let models = operator["admin"]["models"].as_object().expect("models");
     39     let types = operator["admin"]["types"].as_object().expect("types");
     40     assert_eq!(routes.len(), 20);
     41     assert_eq!(models.len(), 33);
     42     assert_eq!(RhiAdminRoute::ALL.len(), 20);
     43     assert_eq!(RhiAdminRoute::ACTIVE, RhiAdminRoute::ALL);
     44 
     45     for removed in policy["removed_live_routes"]
     46         .as_array()
     47         .expect("removed routes")
     48     {
     49         let path = removed["path"].as_str().expect("removed path");
     50         let operation_id = removed["operation_id"]
     51             .as_str()
     52             .expect("removed operation ID");
     53         assert!(routes.iter().all(|route| route["path"] != path));
     54         assert!(
     55             routes
     56                 .iter()
     57                 .all(|route| route["operation_id"] != operation_id)
     58         );
     59     }
     60     for removed in policy["removed_models"].as_array().expect("removed models") {
     61         assert!(!models.contains_key(removed.as_str().expect("model name")));
     62     }
     63     for removed in policy["removed_operator_types"]
     64         .as_array()
     65         .expect("removed operator types")
     66     {
     67         assert!(!types.contains_key(removed.as_str().expect("type name")));
     68     }
     69 }
     70 
     71 #[test]
     72 fn removed_live_identity_surface_cannot_reenter_the_adapter_or_root_api() {
     73     for forbidden in [
     74         "IdentityRekey",
     75         "IdentityReplace",
     76         "identity_rekey_request_v1",
     77         "identity_replace_request_v1",
     78         "identity_mutation_receipt_v1",
     79         "build_rhi_identity",
     80         "direct_sqlite",
     81     ] {
     82         assert!(
     83             !ADMIN_SOURCE.contains(forbidden),
     84             "forbidden admin surface `{forbidden}`"
     85         );
     86         assert!(
     87             !ROOT_SOURCE.contains(forbidden),
     88             "forbidden root surface `{forbidden}`"
     89         );
     90     }
     91     for required in [
     92         "pub const ALL: [Self; 20]",
     93         "pub const ACTIVE: [Self; 20] = Self::ALL",
     94         "Live identity rekey and replace are absent by final offline-only policy",
     95     ] {
     96         assert!(
     97             ADMIN_SOURCE.contains(required),
     98             "missing guard `{required}`"
     99         );
    100     }
    101 }