summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSanto Cariotti <santo@dcariotti.me>2021-03-14 22:20:35 +0100
committerSanto Cariotti <santo@dcariotti.me>2021-03-14 22:20:35 +0100
commit6b81a3cb99bc109726282d3e661f6b5ac5dde4c2 (patch)
tree73c4b5a0f029261164946127952e0d245002a10c
parent4b25bf3976b787bec97151c5c284f2fdf1f9c255 (diff)
feat: add DELETE method
-rw-r--r--README.md1
-rw-r--r--src/repository/models.rs32
-rw-r--r--src/repository/routes.rs57
3 files changed, 84 insertions, 6 deletions
diff --git a/README.md b/README.md
index e4b8d22..93de202 100644
--- a/README.md
+++ b/README.md
@@ -11,4 +11,5 @@ PG.HOST=<host>
PG.PORT=<port>
PG.DBNAME=<db>
PG.POOL.MAX_SIZE=<poolsize>
+SECRET_KEY=
```
diff --git a/src/repository/models.rs b/src/repository/models.rs
index c480cbe..bcddcf1 100644
--- a/src/repository/models.rs
+++ b/src/repository/models.rs
@@ -59,4 +59,36 @@ impl Repository {
}),
}
}
+
+ /// Find a repository and delete it, but before check if "Authorization"
+ /// matches with SECRET_KEY
+ pub async fn delete(
+ pool: Pool,
+ id: &Uuid,
+ ) -> Result<Repository, AppError> {
+ let client = get_client(pool.clone()).await.unwrap();
+ let statement = client
+ .prepare(
+ "
+ DELETE FROM repository
+ WHERE id=$1
+ RETURNING *
+ ",
+ )
+ .await?;
+
+ let repo = client
+ .query_opt(&statement, &[&id])
+ .await?
+ .map(|row| Repository::from_row_ref(&row).unwrap());
+
+ match repo {
+ Some(repo) => Ok(repo),
+ None => Err(AppError {
+ error_type: AppErrorType::NotFoundError,
+ cause: None,
+ message: Some("Repository not found".to_string()),
+ }),
+ }
+ }
}
diff --git a/src/repository/routes.rs b/src/repository/routes.rs
index c13af7f..54bb35d 100644
--- a/src/repository/routes.rs
+++ b/src/repository/routes.rs
@@ -1,9 +1,11 @@
use crate::config::AppState;
-use crate::errors::AppErrorResponse;
+use crate::errors::{AppError, AppErrorResponse, AppErrorType};
use crate::helpers::uuid_from_string;
use crate::repository::models::Repository;
-use actix_web::{web, HttpResponse, Responder};
+use actix_web::http::header;
+use actix_web::{web, HttpRequest, HttpResponse, Responder};
use slog::info;
+use std::env;
use uuid::Uuid;
/// Endpoint used for retrieve all repositories
@@ -41,9 +43,52 @@ async fn get_repo(
.map_err(|e| e)
}
+/// Endpoint used for delete repository.
+/// It uses a SECRET_KEY used like an API key
+async fn delete_repo(
+ req: HttpRequest,
+ state: web::Data<AppState>,
+ id: web::Path<(String,)>,
+) -> impl Responder {
+ let uuid: Uuid = uuid_from_string(&id.0);
+ match req.headers().get(header::AUTHORIZATION) {
+ Some(x)
+ if x.to_str().unwrap()
+ != env::var("SECRET_KEY").unwrap_or("".to_string()) =>
+ {
+ info!(state.log, "DELETE /repo/{}/ 401", id.0);
+ return Err(AppError {
+ error_type: AppErrorType::AuthorizationError,
+ message: Some(
+ "You must provide a valid Authorization".to_string(),
+ ),
+ cause: None,
+ });
+ }
+ Some(_) => {}
+ None => {
+ info!(state.log, "DELETE /repo/{}/ 400", id.0);
+ return Ok(HttpResponse::BadRequest().body(""));
+ }
+ };
+
+ let result = Repository::delete(state.pool.clone(), &uuid).await;
+ info!(state.log, "DELETE /repo/{}/", id.0);
+
+ result
+ .map(|_| HttpResponse::NoContent().body(""))
+ .map_err(|e| e)
+}
+
+/// Routes for repository. TODO: create endpoint for UPDATE method
pub fn config(cfg: &mut web::ServiceConfig) {
- cfg.service(web::resource("/repo{_:/?}").route(web::get().to(index)))
- .service(
- web::resource("/repo/{id}{_:/?}").route(web::get().to(get_repo)),
- );
+ cfg.service(
+ web::scope("/repo")
+ .service(web::resource("{_:/?}").route(web::get().to(index)))
+ .service(
+ web::resource("/{id}{_:/?}")
+ .route(web::get().to(get_repo))
+ .route(web::delete().to(delete_repo)),
+ ),
+ );
}