feat: add validation to project creation and update endpoints
Some checks failed
ci/woodpecker/push/check_fmt Pipeline failed
Some checks failed
ci/woodpecker/push/check_fmt Pipeline failed
This commit is contained in:
parent
f20802682a
commit
8e460ec6dd
6 changed files with 48 additions and 25 deletions
|
@ -14,3 +14,6 @@ SECRET_KEY=
|
|||
|
||||
# LDAP section
|
||||
LDAP_ADMIN_PASSWORD=
|
||||
|
||||
# Rust log level
|
||||
RUST_LOG=info
|
|
@ -20,6 +20,7 @@ env_logger = "0.11"
|
|||
log = "0.4"
|
||||
|
||||
serde = { version = "1", features = ["derive"] }
|
||||
validator = { version = "0.20.0", features = ["derive"] }
|
||||
sea-orm = { version = "1.1", features = [
|
||||
"sqlx-postgres",
|
||||
"runtime-tokio-rustls",
|
||||
|
|
|
@ -1,18 +1,13 @@
|
|||
use std::path;
|
||||
|
||||
use actix_web::{Result, delete, get, post, put, web};
|
||||
use sea_orm::prelude::Uuid;
|
||||
use serde::Deserialize;
|
||||
|
||||
use crate::dto::project::UpdateProject;
|
||||
use validator::Validate;
|
||||
|
||||
use crate::db::Database;
|
||||
use crate::db::project::CreateProject;
|
||||
use crate::error::ApiError;
|
||||
|
||||
// Maybe move this here into the corresponding DTO file
|
||||
#[derive(Deserialize)]
|
||||
struct CreateProject {
|
||||
name: String,
|
||||
}
|
||||
|
||||
pub fn setup(cfg: &mut actix_web::web::ServiceConfig) {
|
||||
cfg.service(get_project)
|
||||
.service(get_projects)
|
||||
|
@ -45,20 +40,22 @@ async fn get_project(
|
|||
#[post("")]
|
||||
async fn create_project(
|
||||
db: web::Data<Database>,
|
||||
create_project_struct: web::Json<CreateProject>,
|
||||
create_project: web::Json<CreateProject>,
|
||||
) -> Result<web::Json<entity::project::Model>, ApiError> {
|
||||
let result = db.create_project(&create_project_struct.name).await?;
|
||||
create_project.validate()?;
|
||||
let result = db.create_project(create_project.into_inner()).await?;
|
||||
|
||||
Ok(web::Json(result))
|
||||
}
|
||||
|
||||
#[put("")]
|
||||
#[put("/{id}")]
|
||||
async fn update_project(
|
||||
db: web::Data<Database>,
|
||||
update_project_struct: web::Json<UpdateProject>,
|
||||
path: web::Path<Uuid>,
|
||||
update_project: web::Json<CreateProject>,
|
||||
) -> Result<web::Json<entity::project::Model>, ApiError> {
|
||||
let updated_project = db
|
||||
.update_project(update_project_struct.into_inner())
|
||||
.update_project(&path, update_project.into_inner())
|
||||
.await?;
|
||||
|
||||
Ok(web::Json(updated_project))
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
use sea_orm::{ConnectOptions, DatabaseConnection};
|
||||
|
||||
mod group;
|
||||
mod project;
|
||||
pub mod project;
|
||||
mod user;
|
||||
|
||||
#[derive(Clone)]
|
||||
|
|
|
@ -2,12 +2,18 @@ use super::Database;
|
|||
use crate::error::ApiError;
|
||||
use log::debug;
|
||||
|
||||
use crate::dto::project::UpdateProject;
|
||||
|
||||
use entity::project;
|
||||
use sea_orm::ActiveValue::{NotSet, Set, Unchanged};
|
||||
use sea_orm::prelude::Uuid;
|
||||
use sea_orm::{ActiveModelTrait, DeleteResult, EntityTrait};
|
||||
use serde::Deserialize;
|
||||
use validator::Validate;
|
||||
|
||||
#[derive(Deserialize, Validate)]
|
||||
pub struct CreateProject {
|
||||
#[validate(length(min = 3))]
|
||||
name: String,
|
||||
}
|
||||
|
||||
impl Database {
|
||||
pub async fn get_projects(&self) -> Result<Vec<project::Model>, ApiError> {
|
||||
|
@ -30,23 +36,30 @@ impl Database {
|
|||
Ok(project)
|
||||
}
|
||||
|
||||
pub async fn create_project(&self, name: &str) -> Result<project::Model, ApiError> {
|
||||
debug!("Creating project with name: {}", name);
|
||||
pub async fn create_project(
|
||||
&self,
|
||||
create_project: CreateProject,
|
||||
) -> Result<project::Model, ApiError> {
|
||||
debug!("Creating project with name: {}", create_project.name);
|
||||
|
||||
let project = project::ActiveModel {
|
||||
id: NotSet,
|
||||
name: Set(name.to_owned()),
|
||||
name: Set(create_project.name),
|
||||
};
|
||||
|
||||
let project = project.insert(&self.conn).await?;
|
||||
Ok(project)
|
||||
}
|
||||
|
||||
pub async fn update_project(&self, project: UpdateProject) -> Result<project::Model, ApiError> {
|
||||
debug!("Updating project with id: {}", &project.id);
|
||||
pub async fn update_project(
|
||||
&self,
|
||||
id: &Uuid,
|
||||
project: CreateProject,
|
||||
) -> Result<project::Model, ApiError> {
|
||||
debug!("Updating project with id: {}", &id);
|
||||
|
||||
let active_model = project::ActiveModel {
|
||||
id: Unchanged(project.id),
|
||||
id: Unchanged(*id),
|
||||
name: Set(project.name),
|
||||
};
|
||||
|
||||
|
|
|
@ -1,12 +1,18 @@
|
|||
use actix_web::{HttpResponse, ResponseError, http::StatusCode};
|
||||
use actix_web::{HttpResponse, ResponseError, cookie::time::error, http::StatusCode};
|
||||
use thiserror::Error;
|
||||
|
||||
#[derive(Error, Debug)]
|
||||
pub enum ApiError {
|
||||
#[error("Database Error: {0}")]
|
||||
Database(#[from] sea_orm::DbErr),
|
||||
#[error("Unauthorized")]
|
||||
Unauthorized,
|
||||
#[error("Not Found")]
|
||||
NotFound,
|
||||
#[error("Bad Request: {0}")]
|
||||
BadRequest(String),
|
||||
#[error("Validation Error: {0}")]
|
||||
ValidationError(#[from] validator::ValidationErrors),
|
||||
}
|
||||
|
||||
impl ResponseError for ApiError {
|
||||
|
@ -14,6 +20,9 @@ impl ResponseError for ApiError {
|
|||
match self {
|
||||
ApiError::Database(..) => StatusCode::INTERNAL_SERVER_ERROR,
|
||||
ApiError::NotFound => StatusCode::NOT_FOUND,
|
||||
ApiError::Unauthorized => StatusCode::UNAUTHORIZED,
|
||||
ApiError::BadRequest(..) => StatusCode::BAD_REQUEST,
|
||||
ApiError::ValidationError(..) => StatusCode::BAD_REQUEST,
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue