diff options
author | Galen Guyer <galen@galenguyer.com> | 2022-05-22 18:04:58 -0400 |
---|---|---|
committer | Galen Guyer <galen@galenguyer.com> | 2022-05-22 18:04:58 -0400 |
commit | 962670391865b9a58a50e36453cdf923494de44a (patch) | |
tree | 27e3072715cc693c8de2dd4d60ec26aa217c5a10 | |
parent | 842d0f14b8ef5291dd0cd7ce422a73dd634b14e8 (diff) |
add route to delete records
-rw-r--r-- | src/db/records.rs | 17 | ||||
-rw-r--r-- | src/db/strings.rs | 5 | ||||
-rw-r--r-- | src/main.rs | 6 | ||||
-rw-r--r-- | src/routes/v1/records.rs | 44 |
4 files changed, 70 insertions, 2 deletions
diff --git a/src/db/records.rs b/src/db/records.rs index 1f2e5bf..3b7a97a 100644 --- a/src/db/records.rs +++ b/src/db/records.rs @@ -26,6 +26,7 @@ pub async fn create_record( pub async fn update_record( pool: &Pool<Postgres>, + zone_id: &str, record_id: &Uuid, name: &str, record_type: &str, @@ -39,12 +40,28 @@ pub async fn update_record( .bind(content) .bind(ttl) .bind(record_id) + .bind(zone_id) .fetch_one(&mut transaction) .await?; transaction.commit().await?; Ok(record) } +pub async fn delete_record( + pool: &Pool<Postgres>, + zone_id: &str, + record_id: &Uuid, +) -> Result<(), sqlx::Error> { + let mut transaction = pool.begin().await?; + sqlx::query(&strings::DELETE_RECORD) + .bind(record_id) + .bind(zone_id) + .execute(&mut transaction) + .await?; + transaction.commit().await?; + Ok(()) +} + pub async fn get_records(pool: &Pool<Postgres>, zone_id: &str) -> Result<Vec<Record>, sqlx::Error> { let records = sqlx::query_as::<_, Record>(&strings::GET_RECORDS) .bind(zone_id) diff --git a/src/db/strings.rs b/src/db/strings.rs index ceb71b9..484aa3e 100644 --- a/src/db/strings.rs +++ b/src/db/strings.rs @@ -28,7 +28,10 @@ lazy_static! { INSERT INTO records(zone_id,name,type,content,ttl) VALUES ($1, $2, $3, $4, $5) RETURNING * "; pub(crate) static ref UPDATE_RECORD: &'static str = r" - UPDATE records SET name = $1, type = $2, content = $3, ttl = $4 WHERE id = $5 RETURNING * + UPDATE records SET name = $1, type = $2, content = $3, ttl = $4 WHERE id = $5 AND zone_id = $6 RETURNING * + "; + pub(crate) static ref DELETE_RECORD: &'static str = r" + DELETE FROM records WHERE id = $1 AND zone_id = $2 "; pub(crate) static ref GET_RECORDS: &'static str = r" SELECT id,zone_id,name,type,content,ttl,created_at,modified_at diff --git a/src/main.rs b/src/main.rs index 373f953..d870dc1 100644 --- a/src/main.rs +++ b/src/main.rs @@ -66,7 +66,11 @@ async fn main() { .post(routes::v1::zones::create_zone) .put(routes::v1::records::create_record), ) - .route("/:zone_id/:record_id", put(routes::v1::records::update_record)), + .route( + "/:zone_id/:record_id", + put(routes::v1::records::update_record) + .delete(routes::v1::records::delete_record), + ), ), ), ) diff --git a/src/routes/v1/records.rs b/src/routes/v1/records.rs index 18e0d18..d79e644 100644 --- a/src/routes/v1/records.rs +++ b/src/routes/v1/records.rs @@ -111,6 +111,8 @@ pub async fn update_record( ); } + // TODO: Check to make sure record is within zone + if !data.name.ends_with(&zone.id) { return ( StatusCode::BAD_REQUEST, @@ -120,6 +122,7 @@ pub async fn update_record( let record = db::records::update_record( &pool, + &zone_id, &Uuid::parse_str(&record_id).unwrap(), &data.name, &data.record_type, @@ -137,3 +140,44 @@ pub async fn update_record( (StatusCode::OK, Json(json!(record))) } + +pub async fn delete_record( + Path((zone_id, record_id)): Path<(String, String)>, + Jwt(user): Jwt, + Extension(pool): Extension<Arc<Pool<Postgres>>>, +) -> impl IntoResponse { + let zone = db::zones::get_zone(&pool, &zone_id).await; + + if zone.is_err() { + return ( + StatusCode::NOT_FOUND, + Json(json!({"error": "Zone not found"})), + ); + } + let zone = zone.unwrap(); + + if zone.owner_uuid != user.sub { + return ( + StatusCode::FORBIDDEN, + Json(json!({"error": "You do not have permissions to access this zone"})), + ); + } + + // TODO: Make sure record exists + // TODO: Check to make sure record is within zone + + let result = db::records::delete_record( + &pool, + &zone_id, + &Uuid::parse_str(&record_id).unwrap(), + ) + .await; + if result.is_err() { + return ( + StatusCode::INTERNAL_SERVER_ERROR, + Json(json!({"error": result.unwrap_err().to_string()})), + ); + } + + (StatusCode::OK, Json(json!({"message": format!("Record {} deleted", record_id)}))) +} |