mirror of
https://github.com/NVIDIA/OpenShell.git
synced 2026-10-15 05:09:44 +08:00
81 lines
2.9 KiB
Rust
81 lines
2.9 KiB
Rust
// SPDX-FileCopyrightText: Copyright (c) 2025-2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
|
|
// SPDX-License-Identifier: Apache-2.0
|
|
|
|
use openshell_core::proto::SandboxPolicy;
|
|
use openshell_supervisor_middleware::MiddlewareRegistry;
|
|
use tonic::Status;
|
|
|
|
/// Validate implementation-owned middleware config before accepting a policy.
|
|
pub async fn validate_policy(
|
|
registry: &MiddlewareRegistry,
|
|
policy: &SandboxPolicy,
|
|
) -> Result<(), Status> {
|
|
registry
|
|
.validate_policy_configs(policy)
|
|
.await
|
|
.map_err(|error| {
|
|
Status::invalid_argument(format!("policy middleware validation failed: {error}"))
|
|
})
|
|
}
|
|
|
|
#[cfg(test)]
|
|
mod tests {
|
|
use super::*;
|
|
use openshell_core::proto::NetworkMiddlewareConfig;
|
|
|
|
#[tokio::test]
|
|
async fn unregistered_external_middleware_is_rejected_before_admission() {
|
|
let policy = SandboxPolicy {
|
|
network_middlewares: std::collections::HashMap::from([(
|
|
"guard".into(),
|
|
NetworkMiddlewareConfig {
|
|
middleware: "example/content-guard".into(),
|
|
..Default::default()
|
|
},
|
|
)]),
|
|
..Default::default()
|
|
};
|
|
|
|
let error = validate_policy(&MiddlewareRegistry::default(), &policy)
|
|
.await
|
|
.expect_err("unregistered middleware must fail");
|
|
assert_eq!(error.code(), tonic::Code::InvalidArgument);
|
|
assert!(error.message().contains("not registered"));
|
|
}
|
|
|
|
#[tokio::test]
|
|
async fn invalid_builtin_config_is_rejected_by_implementation() {
|
|
let registry = MiddlewareRegistry::connect_services(
|
|
openshell_supervisor_middleware_builtins::services(),
|
|
Vec::new(),
|
|
)
|
|
.await
|
|
.expect("built-in registry");
|
|
let policy = SandboxPolicy {
|
|
network_middlewares: std::collections::HashMap::from([(
|
|
"redactor".into(),
|
|
NetworkMiddlewareConfig {
|
|
middleware: openshell_supervisor_middleware_builtins::BUILTIN_REGEX.into(),
|
|
config: Some(prost_types::Struct {
|
|
fields: std::iter::once((
|
|
"mode".into(),
|
|
prost_types::Value {
|
|
kind: Some(prost_types::value::Kind::StringValue("allow".into())),
|
|
},
|
|
))
|
|
.collect(),
|
|
}),
|
|
..Default::default()
|
|
},
|
|
)]),
|
|
..Default::default()
|
|
};
|
|
|
|
let error = validate_policy(®istry, &policy)
|
|
.await
|
|
.expect_err("invalid built-in config must fail admission");
|
|
assert_eq!(error.code(), tonic::Code::InvalidArgument);
|
|
assert!(error.message().contains("supports only mode: redact"));
|
|
}
|
|
}
|