merge(13): bring main forward — unblocks the crate's test build
The lane merged main at0c4826f8, one commit before0de67ca6added auth/auth_rationale to PortMapping's test constructors in prod_orchestrator.rs. That left the lane unable to compile ANY test in the archipelago crate, which is why 13-05 could not observe its 13 tests pass (window 19). Not a defect in this phase's work — just staleness. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> # Conflicts: # core/archipelago/src/main.rs
This commit is contained in:
@@ -0,0 +1,59 @@
|
||||
//! `security.app-gate-status` — what the app gate is actually enforcing.
|
||||
//!
|
||||
//! The gate rolls out per app (an app must be pinned to loopback before the
|
||||
//! gate can claim its port — see `appgate::listener`), so for a while every
|
||||
//! node is partially protected. "Partially" is only safe if it is *visible*:
|
||||
//! this is the RPC that lets the UI say which app ports are still reachable
|
||||
//! without a credential, instead of the operator having to port-scan their
|
||||
//! own node to find out.
|
||||
|
||||
use anyhow::Result;
|
||||
|
||||
use super::RpcHandler;
|
||||
|
||||
impl RpcHandler {
|
||||
pub(in crate::api::rpc) async fn handle_app_gate_status(&self) -> Result<serde_json::Value> {
|
||||
let status = crate::appgate::listener::shared_status();
|
||||
let status = status.read().await.clone();
|
||||
let port_map = self.app_gate.port_map().await;
|
||||
|
||||
// Exemptions are reported alongside, and with their manifest
|
||||
// rationale, because "which ports are open and why" is the actual
|
||||
// question — a list of unprotected ports without the deliberate ones
|
||||
// next to it invites someone to "fix" LND's gRPC port and break every
|
||||
// remote wallet.
|
||||
let exempt: Vec<serde_json::Value> = port_map
|
||||
.exempt_ports()
|
||||
.iter()
|
||||
.map(|e| {
|
||||
serde_json::json!({
|
||||
"port": e.port,
|
||||
"app_id": e.app_id,
|
||||
"protocol": e.protocol,
|
||||
"rationale": e.rationale,
|
||||
})
|
||||
})
|
||||
.collect();
|
||||
|
||||
let gated: Vec<serde_json::Value> = port_map
|
||||
.gated_ports()
|
||||
.map(|g| {
|
||||
serde_json::json!({
|
||||
"port": g.port,
|
||||
"app_id": g.app_id,
|
||||
"app_name": g.app_name,
|
||||
})
|
||||
})
|
||||
.collect();
|
||||
|
||||
Ok(serde_json::json!({
|
||||
// The headline. False means this node still has app ports that
|
||||
// answer without authentication.
|
||||
"fully_enforced": status.is_fully_enforced(),
|
||||
"claimed": status.claimed,
|
||||
"unprotected": status.unprotected,
|
||||
"gated": gated,
|
||||
"exempt": exempt,
|
||||
}))
|
||||
}
|
||||
}
|
||||
@@ -470,6 +470,7 @@ impl RpcHandler {
|
||||
"server.set-location" => self.handle_server_set_location(params).await,
|
||||
|
||||
// System monitoring
|
||||
"security.app-gate-status" => self.handle_app_gate_status().await,
|
||||
"system.get-hostname" => self.handle_system_get_hostname().await,
|
||||
"system.stats" => self.handle_system_stats().await,
|
||||
"system.processes" => self.handle_system_processes().await,
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
mod analytics;
|
||||
mod appgate;
|
||||
mod ark;
|
||||
mod assistant_chat;
|
||||
mod auth;
|
||||
@@ -94,6 +95,11 @@ pub struct RpcHandler {
|
||||
port_allocator: Arc<tokio::sync::Mutex<PortAllocator>>,
|
||||
pub session_store: SessionStore,
|
||||
login_rate_limiter: LoginRateLimiter,
|
||||
/// Authentication in front of every app port. Built here rather than in
|
||||
/// `server.rs` so it shares this handler's session store and login rate
|
||||
/// limiter — an attacker must not get a fresh budget of password guesses
|
||||
/// by moving from the dashboard to an app port.
|
||||
pub(crate) app_gate: Arc<crate::appgate::AppGate>,
|
||||
endpoint_rate_limiter: EndpointRateLimiter,
|
||||
response_cache: ResponseCache,
|
||||
mesh_service: Arc<tokio::sync::RwLock<Option<crate::mesh::MeshService>>>,
|
||||
@@ -158,6 +164,13 @@ impl RpcHandler {
|
||||
});
|
||||
}
|
||||
|
||||
let app_gate = Arc::new(crate::appgate::AppGate::new(
|
||||
session_store.clone(),
|
||||
auth_manager.clone(),
|
||||
login_rate_limiter.clone(),
|
||||
config.data_dir.clone(),
|
||||
));
|
||||
|
||||
Ok(Self {
|
||||
config,
|
||||
auth_manager,
|
||||
@@ -168,6 +181,7 @@ impl RpcHandler {
|
||||
port_allocator,
|
||||
session_store,
|
||||
login_rate_limiter,
|
||||
app_gate,
|
||||
endpoint_rate_limiter,
|
||||
response_cache: ResponseCache::new(5),
|
||||
mesh_service: Arc::new(tokio::sync::RwLock::new(None)),
|
||||
|
||||
Reference in New Issue
Block a user