Implement public debug attach authorization

This commit is contained in:
Michel Paulissen 2026-07-03 21:18:10 +02:00
parent 005b47e4c0
commit f586b48893
5 changed files with 201 additions and 4 deletions

View file

@ -1441,13 +1441,52 @@ fn exec_dap(args: DapArgs) -> Result<()> {
}
fn debug_attach_report(args: DebugAttachArgs) -> Result<Value> {
let dap = dap_binary_path()?.display().to_string();
debug_attach_report_with_dap(args, dap)
}
fn debug_attach_report_with_dap(args: DebugAttachArgs, dap: String) -> Result<Value> {
if let Some(coordinator) = &args.scope.coordinator {
let tenant = args.scope.tenant.clone();
let project = args.scope.project.clone();
let user = args.scope.user.clone();
let process = args.process.clone();
let mut session = JsonLineSession::connect(coordinator)?;
let response = session.request(json!({
"type": "debug_attach",
"tenant": tenant,
"project": project,
"actor_user": user,
"process": process,
}))?;
let authorization = response.get("authorization").cloned().unwrap_or_else(
|| json!({"allowed": false, "reason": "missing authorization response"}),
);
return Ok(json!({
"command": "debug attach",
"process": process,
"coordinator": coordinator,
"tenant": tenant,
"project": project,
"user": user,
"dap": dap,
"authorized": authorization
.get("allowed")
.cloned()
.unwrap_or_else(|| json!(false)),
"authorization": authorization,
"private_website_required": false,
"coordinator_session_requests": session.requests(),
}));
}
Ok(json!({
"command": "debug attach",
"process": args.process,
"coordinator": args.scope.coordinator,
"tenant": args.scope.tenant,
"project": args.scope.project,
"dap": dap_binary_path()?.display().to_string(),
"dap": dap,
"authorized": "unknown_without_coordinator",
"private_website_required": false,
}))
}
@ -4588,6 +4627,54 @@ mod tests {
assert_eq!(suspended["private_website_required"], false);
}
#[test]
fn debug_attach_reports_public_authorization() {
let listener = TcpListener::bind("127.0.0.1:0").unwrap();
let addr = listener.local_addr().unwrap().to_string();
let server = std::thread::spawn(move || {
let (mut stream, _) = listener.accept().unwrap();
let mut reader = BufReader::new(stream.try_clone().unwrap());
let mut line = String::new();
reader.read_line(&mut line).unwrap();
assert!(line.contains(r#""type":"debug_attach""#));
assert!(line.contains(r#""tenant":"tenant""#));
assert!(line.contains(r#""project":"project""#));
assert!(line.contains(r#""actor_user":"user""#));
assert!(line.contains(r#""process":"vp""#));
stream
.write_all(
br#"{"type":"debug_attach","process":"vp","actor":"user","authorization":{"allowed":true,"reason":"debug attach authorized for project"}}"#,
)
.unwrap();
stream.write_all(b"\n").unwrap();
});
let report = debug_attach_report_with_dap(
DebugAttachArgs {
scope: CliScopeArgs {
coordinator: Some(addr),
tenant: "tenant".to_owned(),
project: "project".to_owned(),
user: "user".to_owned(),
json: false,
},
process: "vp".to_owned(),
},
"/tmp/disasmer-debug-dap-test".to_owned(),
)
.unwrap();
server.join().unwrap();
assert_eq!(report["command"], "debug attach");
assert_eq!(report["process"], "vp");
assert_eq!(report["authorized"], true);
assert_eq!(
report["authorization"]["reason"],
"debug attach authorized for project"
);
assert_eq!(report["private_website_required"], false);
}
#[test]
fn human_report_is_text_not_json() {
let report = json!({