From 44a35e651741afb6c417da47d636e4380cdd225f Mon Sep 17 00:00:00 2001 From: Santo Cariotti Date: Sat, 13 Mar 2021 10:17:02 +0100 Subject: feat: add get all repos from db --- src/repository/routes.rs | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) create mode 100644 src/repository/routes.rs (limited to 'src/repository/routes.rs') diff --git a/src/repository/routes.rs b/src/repository/routes.rs new file mode 100644 index 0000000..ebfff8e --- /dev/null +++ b/src/repository/routes.rs @@ -0,0 +1,23 @@ +use crate::config::AppState; +use crate::repository::models::Repository; +use actix_web::{web, HttpResponse, Responder}; +use slog::info; + +async fn index(state: web::Data) -> impl Responder { + let result = Repository::find_all(state.pool.clone()).await; + match result { + Ok(repos) => { + info!(state.log, "GET /repo/ 200"); + HttpResponse::Ok().json(repos) + } + _ => { + info!(state.log, "GET /repo/ 500"); + HttpResponse::BadRequest() + .body("Error trying to read all repositories from database") + } + } +} + +pub fn config(cfg: &mut web::ServiceConfig) { + cfg.service(web::resource("/repo/").route(web::get().to(index))); +} -- cgit v1.2.3-18-g5258 From 3232579f29d1c91e70e7dc76305d6589c4acbaae Mon Sep 17 00:00:00 2001 From: Santo Cariotti Date: Sun, 14 Mar 2021 00:39:27 +0100 Subject: chore: get repos error in json mode --- src/repository/routes.rs | 18 ++++++++---------- 1 file changed, 8 insertions(+), 10 deletions(-) (limited to 'src/repository/routes.rs') diff --git a/src/repository/routes.rs b/src/repository/routes.rs index ebfff8e..6b3a942 100644 --- a/src/repository/routes.rs +++ b/src/repository/routes.rs @@ -1,23 +1,21 @@ use crate::config::AppState; +use crate::errors::AppErrorResponse; use crate::repository::models::Repository; use actix_web::{web, HttpResponse, Responder}; use slog::info; async fn index(state: web::Data) -> impl Responder { let result = Repository::find_all(state.pool.clone()).await; + info!(state.log, "GET /repo/"); match result { - Ok(repos) => { - info!(state.log, "GET /repo/ 200"); - HttpResponse::Ok().json(repos) - } - _ => { - info!(state.log, "GET /repo/ 500"); - HttpResponse::BadRequest() - .body("Error trying to read all repositories from database") - } + Ok(repos) => HttpResponse::Ok().json(repos), + _ => HttpResponse::BadRequest().json(AppErrorResponse { + detail: "Error trying to read all repositories from database" + .to_string(), + }), } } pub fn config(cfg: &mut web::ServiceConfig) { - cfg.service(web::resource("/repo/").route(web::get().to(index))); + cfg.service(web::resource("/repo{_:/?}").route(web::get().to(index))) } -- cgit v1.2.3-18-g5258 From f7932c366bab2f5d0726f4d1cdf5b9dbeddf92eb Mon Sep 17 00:00:00 2001 From: Santo Cariotti Date: Sun, 14 Mar 2021 00:39:37 +0100 Subject: feat: find repo by id --- src/repository/routes.rs | 15 +++++++++++++++ 1 file changed, 15 insertions(+) (limited to 'src/repository/routes.rs') diff --git a/src/repository/routes.rs b/src/repository/routes.rs index 6b3a942..634d210 100644 --- a/src/repository/routes.rs +++ b/src/repository/routes.rs @@ -3,6 +3,7 @@ use crate::errors::AppErrorResponse; use crate::repository::models::Repository; use actix_web::{web, HttpResponse, Responder}; use slog::info; +use uuid::Uuid; async fn index(state: web::Data) -> impl Responder { let result = Repository::find_all(state.pool.clone()).await; @@ -16,6 +17,20 @@ async fn index(state: web::Data) -> impl Responder { } } +async fn get_repo( + state: web::Data, + id: web::Path<(Uuid,)>, +) -> impl Responder { + let result = Repository::find(state.pool.clone(), &id.0).await; + info!(state.log, "GET /repo/{}/", id.0); + result + .map(|repo| HttpResponse::Ok().json(repo)) + .map_err(|e| e) +} + 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)), + ); } -- cgit v1.2.3-18-g5258 From 6acc53da212e7506fd33534fd5cf9baa0d01e4ea Mon Sep 17 00:00:00 2001 From: Santo Cariotti Date: Sun, 14 Mar 2021 12:55:21 +0100 Subject: chore: add docs --- src/repository/routes.rs | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'src/repository/routes.rs') diff --git a/src/repository/routes.rs b/src/repository/routes.rs index 634d210..0683b47 100644 --- a/src/repository/routes.rs +++ b/src/repository/routes.rs @@ -5,9 +5,12 @@ use actix_web::{web, HttpResponse, Responder}; use slog::info; use uuid::Uuid; +/// Endpoint used for retrieve all repositories async fn index(state: web::Data) -> impl Responder { let result = Repository::find_all(state.pool.clone()).await; info!(state.log, "GET /repo/"); + + // If raises an `Err`, returns an error in JSON format match result { Ok(repos) => HttpResponse::Ok().json(repos), _ => HttpResponse::BadRequest().json(AppErrorResponse { @@ -17,12 +20,16 @@ async fn index(state: web::Data) -> impl Responder { } } +/// Endpoint used for retrieve a repository that matches with an `id`. +/// It is a String, casted in an Uuid format. async fn get_repo( state: web::Data, id: web::Path<(Uuid,)>, ) -> impl Responder { let result = Repository::find(state.pool.clone(), &id.0).await; info!(state.log, "GET /repo/{}/", id.0); + + // `map_err` is also used when repo is not found result .map(|repo| HttpResponse::Ok().json(repo)) .map_err(|e| e) -- cgit v1.2.3-18-g5258 From 6afd0e59f62889d44b90193f0d8581668eae9c28 Mon Sep 17 00:00:00 2001 From: Santo Cariotti Date: Sun, 14 Mar 2021 13:00:59 +0100 Subject: fix: parse uuid fields for get repo --- src/repository/routes.rs | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) (limited to 'src/repository/routes.rs') diff --git a/src/repository/routes.rs b/src/repository/routes.rs index 0683b47..56e42ab 100644 --- a/src/repository/routes.rs +++ b/src/repository/routes.rs @@ -24,9 +24,17 @@ async fn index(state: web::Data) -> impl Responder { /// It is a String, casted in an Uuid format. async fn get_repo( state: web::Data, - id: web::Path<(Uuid,)>, + id: web::Path<(String,)>, ) -> impl Responder { - let result = Repository::find(state.pool.clone(), &id.0).await; + // I have to match the &id.0 because if it's not a valid Uuid, the server + // must response "Repository not found". + // If I pass a not valid Uuid to Repository::find() it raises an error. + let uuid: Uuid = match Uuid::parse_str(&id.0) { + Ok(x) => x, + Err(_) => Uuid::parse_str("00000000000000000000000000000000").unwrap(), + }; + + let result = Repository::find(state.pool.clone(), &uuid).await; info!(state.log, "GET /repo/{}/", id.0); // `map_err` is also used when repo is not found -- cgit v1.2.3-18-g5258 From bf6c4bd75168671a5a0e53f7390ebd4796a6bd57 Mon Sep 17 00:00:00 2001 From: Santo Cariotti Date: Sun, 14 Mar 2021 15:39:00 +0100 Subject: chore: add helpers module --- src/repository/routes.rs | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) (limited to 'src/repository/routes.rs') diff --git a/src/repository/routes.rs b/src/repository/routes.rs index 56e42ab..c13af7f 100644 --- a/src/repository/routes.rs +++ b/src/repository/routes.rs @@ -1,5 +1,6 @@ use crate::config::AppState; use crate::errors::AppErrorResponse; +use crate::helpers::uuid_from_string; use crate::repository::models::Repository; use actix_web::{web, HttpResponse, Responder}; use slog::info; @@ -29,10 +30,7 @@ async fn get_repo( // I have to match the &id.0 because if it's not a valid Uuid, the server // must response "Repository not found". // If I pass a not valid Uuid to Repository::find() it raises an error. - let uuid: Uuid = match Uuid::parse_str(&id.0) { - Ok(x) => x, - Err(_) => Uuid::parse_str("00000000000000000000000000000000").unwrap(), - }; + let uuid: Uuid = uuid_from_string(&id.0); let result = Repository::find(state.pool.clone(), &uuid).await; info!(state.log, "GET /repo/{}/", id.0); -- cgit v1.2.3-18-g5258 From 6b81a3cb99bc109726282d3e661f6b5ac5dde4c2 Mon Sep 17 00:00:00 2001 From: Santo Cariotti Date: Sun, 14 Mar 2021 22:20:35 +0100 Subject: feat: add DELETE method --- src/repository/routes.rs | 57 +++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 51 insertions(+), 6 deletions(-) (limited to 'src/repository/routes.rs') 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, + 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)), + ), + ); } -- cgit v1.2.3-18-g5258 From 4048dd774c817462c0a692f0f94d979290e725ee Mon Sep 17 00:00:00 2001 From: Santo Cariotti Date: Tue, 16 Mar 2021 10:54:28 +0100 Subject: feat: create repository --- src/repository/routes.rs | 24 ++++++++++++++++++++++-- 1 file changed, 22 insertions(+), 2 deletions(-) (limited to 'src/repository/routes.rs') diff --git a/src/repository/routes.rs b/src/repository/routes.rs index 54bb35d..a0f4db5 100644 --- a/src/repository/routes.rs +++ b/src/repository/routes.rs @@ -1,7 +1,7 @@ use crate::config::AppState; use crate::errors::{AppError, AppErrorResponse, AppErrorType}; use crate::helpers::uuid_from_string; -use crate::repository::models::Repository; +use crate::repository::models::{Repository, RepositoryData}; use actix_web::http::header; use actix_web::{web, HttpRequest, HttpResponse, Responder}; use slog::info; @@ -80,11 +80,31 @@ async fn delete_repo( .map_err(|e| e) } +async fn create_repo( + req: HttpRequest, + payload: web::Json, + state: web::Data, +) -> impl Responder { + info!(state.log, "POST /repo/"); + let request_from_ip = HttpRequest::peer_addr(&req); + let result = + Repository::create(state.pool.clone(), &payload, request_from_ip) + .await; + + result + .map(|repo| HttpResponse::Ok().json(repo)) + .map_err(|e| e) +} + /// Routes for repository. TODO: create endpoint for UPDATE method pub fn config(cfg: &mut web::ServiceConfig) { cfg.service( web::scope("/repo") - .service(web::resource("{_:/?}").route(web::get().to(index))) + .service( + web::resource("{_:/?}") + .route(web::get().to(index)) + .route(web::post().to(create_repo)), + ) .service( web::resource("/{id}{_:/?}") .route(web::get().to(get_repo)) -- cgit v1.2.3-18-g5258