Add rate limiting
This commit is contained in:
@ -1,7 +1,8 @@
|
||||
use crate::constants::StaticConstraints;
|
||||
use crate::services::users_service;
|
||||
use crate::controllers::HttpResult;
|
||||
use crate::services::rate_limiter_service::RatedAction;
|
||||
use crate::services::{rate_limiter_service, users_service};
|
||||
use actix_remote_ip::RemoteIP;
|
||||
use actix_web::error::ErrorInternalServerError;
|
||||
use actix_web::{web, HttpResponse};
|
||||
|
||||
#[derive(serde::Deserialize)]
|
||||
@ -11,11 +12,12 @@ pub struct CreateAccountBody {
|
||||
}
|
||||
|
||||
/// Create a new account
|
||||
pub async fn create_account(
|
||||
_remote_ip: RemoteIP,
|
||||
req: web::Json<CreateAccountBody>,
|
||||
) -> actix_web::Result<HttpResponse> {
|
||||
// TODO : rate limiting
|
||||
pub async fn create_account(remote_ip: RemoteIP, req: web::Json<CreateAccountBody>) -> HttpResult {
|
||||
// Rate limiting
|
||||
if rate_limiter_service::should_block_action(remote_ip.0, RatedAction::CreateAccount).await? {
|
||||
return Ok(HttpResponse::TooManyRequests().finish());
|
||||
}
|
||||
rate_limiter_service::record_action(remote_ip.0, RatedAction::CreateAccount).await?;
|
||||
|
||||
// Check if email is valid
|
||||
if !mailchecker::is_valid(&req.email) {
|
||||
@ -30,25 +32,14 @@ pub async fn create_account(
|
||||
}
|
||||
|
||||
// Check if email is already attached to an account
|
||||
match users_service::exists_email(&req.email).await {
|
||||
Ok(false) => {}
|
||||
Ok(true) => {
|
||||
return Ok(HttpResponse::Conflict()
|
||||
.json("An account with the same email address already exists!"));
|
||||
}
|
||||
Err(e) => {
|
||||
log::error!("Failed to check email existence! {}", e);
|
||||
return Err(ErrorInternalServerError(e));
|
||||
}
|
||||
if users_service::exists_email(&req.email).await? {
|
||||
return Ok(
|
||||
HttpResponse::Conflict().json("An account with the same email address already exists!")
|
||||
);
|
||||
}
|
||||
|
||||
// Create the account
|
||||
let user_id = users_service::create_account(&req.name, &req.email)
|
||||
.await
|
||||
.map_err(|e| {
|
||||
log::error!("Failed to create user! {e}");
|
||||
ErrorInternalServerError(e)
|
||||
})?;
|
||||
let user_id = users_service::create_account(&req.name, &req.email).await?;
|
||||
|
||||
// TODO : trigger reset password (send mail)
|
||||
|
||||
|
35
geneit_backend/src/controllers/mod.rs
Normal file
35
geneit_backend/src/controllers/mod.rs
Normal file
@ -0,0 +1,35 @@
|
||||
//! # API controller
|
||||
|
||||
use actix_web::body::BoxBody;
|
||||
use actix_web::HttpResponse;
|
||||
use std::fmt::{Debug, Display, Formatter};
|
||||
|
||||
pub mod auth_controller;
|
||||
pub mod config_controller;
|
||||
|
||||
/// Custom error to ease controller writing
|
||||
#[derive(Debug)]
|
||||
pub struct HttpErr {
|
||||
err: anyhow::Error,
|
||||
}
|
||||
|
||||
impl Display for HttpErr {
|
||||
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
|
||||
std::fmt::Display::fmt(&self.err, f)
|
||||
}
|
||||
}
|
||||
|
||||
impl actix_web::error::ResponseError for HttpErr {
|
||||
fn error_response(&self) -> HttpResponse<BoxBody> {
|
||||
log::error!("Error while processing request! {}", self);
|
||||
HttpResponse::InternalServerError().body("Failed to execute request!")
|
||||
}
|
||||
}
|
||||
|
||||
impl From<anyhow::Error> for HttpErr {
|
||||
fn from(err: anyhow::Error) -> HttpErr {
|
||||
HttpErr { err }
|
||||
}
|
||||
}
|
||||
|
||||
pub type HttpResult = Result<HttpResponse, HttpErr>;
|
Reference in New Issue
Block a user