|
@@ -1,32 +1,26 @@
|
|
|
use actix_web::{post, web, HttpResponse, Responder, http::StatusCode, cookie::Cookie};
|
|
use actix_web::{post, web, HttpResponse, Responder, http::StatusCode, cookie::Cookie};
|
|
|
-use mongodb::{bson::doc, Database};
|
|
|
|
|
|
|
+use mongodb::{bson::doc, Database, Collection};
|
|
|
use crate::models::user::{User, NewUserInput};
|
|
use crate::models::user::{User, NewUserInput};
|
|
|
use regex::Regex;
|
|
use regex::Regex;
|
|
|
use crate::http_error::http_error;
|
|
use crate::http_error::http_error;
|
|
|
use crate::dto;
|
|
use crate::dto;
|
|
|
|
|
+use crate::app_error::AppError;
|
|
|
|
|
|
|
|
#[post("/api/user")]
|
|
#[post("/api/user")]
|
|
|
pub async fn create(
|
|
pub async fn create(
|
|
|
db: web::Data<Database>,
|
|
db: web::Data<Database>,
|
|
|
payload: web::Json<NewUserInput>
|
|
payload: web::Json<NewUserInput>
|
|
|
-) -> impl Responder {
|
|
|
|
|
|
|
+) -> Result<HttpResponse, AppError> {
|
|
|
let user_collection = db.collection::<User>("users");
|
|
let user_collection = db.collection::<User>("users");
|
|
|
let email = payload.email.to_lowercase();
|
|
let email = payload.email.to_lowercase();
|
|
|
- if !valid_email(&email) {
|
|
|
|
|
- return http_error(StatusCode::BAD_REQUEST, "Invalid email");
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- match user_collection.find_one(doc!{"email": email}, None).await {
|
|
|
|
|
- Ok(None) => {},
|
|
|
|
|
- Ok(Some(_)) => return http_error(StatusCode::BAD_REQUEST, "User with this email already exists"),
|
|
|
|
|
- Err(_) => return http_error(StatusCode::INTERNAL_SERVER_ERROR, "Unable to verify email")
|
|
|
|
|
- };
|
|
|
|
|
|
|
+ valid_email(&email)?;
|
|
|
|
|
+ user_exists(&user_collection, &email).await?;
|
|
|
|
|
|
|
|
match User::insert(&user_collection, payload.into_inner()).await {
|
|
match User::insert(&user_collection, payload.into_inner()).await {
|
|
|
- Ok(_) => HttpResponse::Ok().body("{'success': 'true'}"),
|
|
|
|
|
|
|
+ Ok(_) => Ok(HttpResponse::Ok().body("{'success': 'true'}")),
|
|
|
Err(e) => {
|
|
Err(e) => {
|
|
|
eprintln!("{}", e);
|
|
eprintln!("{}", e);
|
|
|
- http_error(StatusCode::INTERNAL_SERVER_ERROR, "Failed to create user")
|
|
|
|
|
|
|
+ Ok(http_error(StatusCode::INTERNAL_SERVER_ERROR, "Failed to create user"))
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
@@ -63,14 +57,22 @@ pub async fn login(
|
|
|
.json(response_user(user))
|
|
.json(response_user(user))
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
-fn valid_email(email: &str) -> bool {
|
|
|
|
|
|
|
+fn valid_email(email: &str) -> Result<(), AppError> {
|
|
|
let email_regex: Regex = Regex::new(r#"^(([^<>()\[\]\\.,;:\s@"]+(\.[^<>()\[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}(\.[0-9]{1,3}){3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$"#).unwrap();
|
|
let email_regex: Regex = Regex::new(r#"^(([^<>()\[\]\\.,;:\s@"]+(\.[^<>()\[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}(\.[0-9]{1,3}){3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$"#).unwrap();
|
|
|
|
|
|
|
|
if email_regex.is_match(email) {
|
|
if email_regex.is_match(email) {
|
|
|
- return true;
|
|
|
|
|
|
|
+ return Ok(());
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- false
|
|
|
|
|
|
|
+ Err(AppError::invalid_input("Invalid email address"))
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+async fn user_exists(collection: &Collection<User>, email: &str) -> Result<(), AppError> {
|
|
|
|
|
+ match collection.find_one(doc!{"email": email}, None).await {
|
|
|
|
|
+ Ok(None) => Ok(()),
|
|
|
|
|
+ Ok(Some(_)) => Err(AppError::invalid_input("User with this email already exists")),
|
|
|
|
|
+ Err(_) => Err(AppError::internal_error("Unable to save user data"))
|
|
|
|
|
+ }
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
fn response_user(user: User) -> dto::user::ResponseUser {
|
|
fn response_user(user: User) -> dto::user::ResponseUser {
|