From e10f09614659efdf20ed518ae852a1e185207a06 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Oddbj=C3=B8rn=20Gr=C3=B8dem?= <29732646+oddgrd@users.noreply.github.com> Date: Tue, 15 Nov 2022 10:29:04 +0100 Subject: [PATCH] feat: verify project exists before sending destroy task (#474) --- gateway/src/api/latest.rs | 27 +++++++++++++++++++++++---- gateway/src/lib.rs | 17 +++++++++++++++++ 2 files changed, 40 insertions(+), 4 deletions(-) diff --git a/gateway/src/api/latest.rs b/gateway/src/api/latest.rs index b2505d819..abdc9145a 100644 --- a/gateway/src/api/latest.rs +++ b/gateway/src/api/latest.rs @@ -124,6 +124,18 @@ async fn delete_project( ) -> Result, Error> { let project_name = project.clone(); + let state = service.find_project(&project_name).await?; + + let mut response = project::Response { + name: project_name.to_string(), + state: state.into(), + }; + + if response.state == shuttle_common::models::project::State::Destroyed { + return Ok(AxumJson(response)); + } + + // if project exists and isn't `Destroyed`, send destroy task service .new_task() .project(project) @@ -132,10 +144,8 @@ async fn delete_project( .send(&sender) .await?; - let response = project::Response { - name: project_name.to_string(), - state: shuttle_common::models::project::State::Destroying, - }; + response.state = shuttle_common::models::project::State::Destroying; + Ok(AxumJson(response)) } @@ -356,6 +366,15 @@ pub mod tests { .await .unwrap(); + // delete returns 404 for project that doesn't exist + router + .call(delete_project("resurrections").with_header(&authorization)) + .map_ok(|resp| { + assert_eq!(resp.status(), StatusCode::NOT_FOUND); + }) + .await + .unwrap(); + Ok(()) } diff --git a/gateway/src/lib.rs b/gateway/src/lib.rs index e297467c4..7834a5188 100644 --- a/gateway/src/lib.rs +++ b/gateway/src/lib.rs @@ -893,5 +893,22 @@ pub mod tests { break; } }); + + // Attempting to delete already Destroyed project will return Destroyed + api_client + .request( + Request::delete("/projects/matrix") + .with_header(&authorization) + .body(Body::empty()) + .unwrap(), + ) + .map_ok(|resp| { + assert_eq!(resp.status(), StatusCode::OK); + let resp = + serde_json::from_slice::(resp.body().as_slice()).unwrap(); + assert_eq!(resp.state, project::State::Destroyed); + }) + .await + .unwrap(); } }