Compare commits
1 Commits
fix/multip
...
fix/cascad
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
f8eb4ea84d |
@@ -237,5 +237,92 @@ pub async fn delete_repository(
|
|||||||
.delete_many(doc! { "repo_id": &id })
|
.delete_many(doc! { "repo_id": &id })
|
||||||
.await;
|
.await;
|
||||||
|
|
||||||
|
// Cascade delete DAST targets linked to this repo, and all their downstream data
|
||||||
|
// (scan runs, findings, pentest sessions, attack chains, messages)
|
||||||
|
if let Ok(mut cursor) = db.dast_targets().find(doc! { "repo_id": &id }).await {
|
||||||
|
use futures_util::StreamExt;
|
||||||
|
while let Some(Ok(target)) = cursor.next().await {
|
||||||
|
let target_id = target.id.map(|oid| oid.to_hex()).unwrap_or_default();
|
||||||
|
if !target_id.is_empty() {
|
||||||
|
cascade_delete_dast_target(db, &target_id).await;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Also delete pentest sessions linked directly to this repo (not via target)
|
||||||
|
if let Ok(mut cursor) = db.pentest_sessions().find(doc! { "repo_id": &id }).await {
|
||||||
|
use futures_util::StreamExt;
|
||||||
|
while let Some(Ok(session)) = cursor.next().await {
|
||||||
|
let session_id = session.id.map(|oid| oid.to_hex()).unwrap_or_default();
|
||||||
|
if !session_id.is_empty() {
|
||||||
|
let _ = db
|
||||||
|
.attack_chain_nodes()
|
||||||
|
.delete_many(doc! { "session_id": &session_id })
|
||||||
|
.await;
|
||||||
|
let _ = db
|
||||||
|
.pentest_messages()
|
||||||
|
.delete_many(doc! { "session_id": &session_id })
|
||||||
|
.await;
|
||||||
|
// Delete DAST findings produced by this session
|
||||||
|
let _ = db
|
||||||
|
.dast_findings()
|
||||||
|
.delete_many(doc! { "session_id": &session_id })
|
||||||
|
.await;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
let _ = db
|
||||||
|
.pentest_sessions()
|
||||||
|
.delete_many(doc! { "repo_id": &id })
|
||||||
|
.await;
|
||||||
|
|
||||||
Ok(Json(serde_json::json!({ "status": "deleted" })))
|
Ok(Json(serde_json::json!({ "status": "deleted" })))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Cascade-delete a DAST target and all its downstream data.
|
||||||
|
async fn cascade_delete_dast_target(db: &crate::database::Database, target_id: &str) {
|
||||||
|
// Delete pentest sessions for this target (and their attack chains + messages)
|
||||||
|
if let Ok(mut cursor) = db
|
||||||
|
.pentest_sessions()
|
||||||
|
.find(doc! { "target_id": target_id })
|
||||||
|
.await
|
||||||
|
{
|
||||||
|
use futures_util::StreamExt;
|
||||||
|
while let Some(Ok(session)) = cursor.next().await {
|
||||||
|
let session_id = session.id.map(|oid| oid.to_hex()).unwrap_or_default();
|
||||||
|
if !session_id.is_empty() {
|
||||||
|
let _ = db
|
||||||
|
.attack_chain_nodes()
|
||||||
|
.delete_many(doc! { "session_id": &session_id })
|
||||||
|
.await;
|
||||||
|
let _ = db
|
||||||
|
.pentest_messages()
|
||||||
|
.delete_many(doc! { "session_id": &session_id })
|
||||||
|
.await;
|
||||||
|
let _ = db
|
||||||
|
.dast_findings()
|
||||||
|
.delete_many(doc! { "session_id": &session_id })
|
||||||
|
.await;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
let _ = db
|
||||||
|
.pentest_sessions()
|
||||||
|
.delete_many(doc! { "target_id": target_id })
|
||||||
|
.await;
|
||||||
|
|
||||||
|
// Delete DAST scan runs and their findings
|
||||||
|
let _ = db
|
||||||
|
.dast_findings()
|
||||||
|
.delete_many(doc! { "target_id": target_id })
|
||||||
|
.await;
|
||||||
|
let _ = db
|
||||||
|
.dast_scan_runs()
|
||||||
|
.delete_many(doc! { "target_id": target_id })
|
||||||
|
.await;
|
||||||
|
|
||||||
|
// Delete the target itself
|
||||||
|
if let Ok(oid) = mongodb::bson::oid::ObjectId::parse_str(target_id) {
|
||||||
|
let _ = db.dast_targets().delete_one(doc! { "_id": oid }).await;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user