From 2d7607bbc13b54a8f16848bc457f252721c0498d Mon Sep 17 00:00:00 2001 From: core Date: Sun, 2 Apr 2023 15:47:50 -0400 Subject: [PATCH] signup --- trifid-api/src/magic_link.rs | 9 ++ trifid-api/src/main.rs | 3 + trifid-api/src/routes/mod.rs | 2 +- .../src/routes/{ => v1}/auth/magic_link.rs | 23 +++- trifid-api/src/routes/{ => v1}/auth/mod.rs | 0 trifid-api/src/routes/v1/mod.rs | 2 + trifid-api/src/routes/v1/signup.rs | 128 ++++++++++++++++++ .../src/{ => entity}/magic_link.rs | 0 .../trifid_api_entities/src/entity/mod.rs | 6 + .../src/{ => entity}/prelude.rs | 0 .../src/{ => entity}/user.rs | 1 - trifid-api/trifid_api_entities/src/lib.rs | 7 +- .../m20230402_162601_create_table_users.rs | 4 +- 13 files changed, 171 insertions(+), 14 deletions(-) create mode 100644 trifid-api/src/magic_link.rs rename trifid-api/src/routes/{ => v1}/auth/magic_link.rs (79%) rename trifid-api/src/routes/{ => v1}/auth/mod.rs (100%) create mode 100644 trifid-api/src/routes/v1/mod.rs create mode 100644 trifid-api/src/routes/v1/signup.rs rename trifid-api/trifid_api_entities/src/{ => entity}/magic_link.rs (100%) create mode 100644 trifid-api/trifid_api_entities/src/entity/mod.rs rename trifid-api/trifid_api_entities/src/{ => entity}/prelude.rs (100%) rename trifid-api/trifid_api_entities/src/{ => entity}/user.rs (95%) diff --git a/trifid-api/src/magic_link.rs b/trifid-api/src/magic_link.rs new file mode 100644 index 0000000..a4b57e7 --- /dev/null +++ b/trifid-api/src/magic_link.rs @@ -0,0 +1,9 @@ +use std::error::Error; +use log::info; + +pub fn send_magic_link(token: &str) -> Result<(), Box> { + // TODO: actually do this + info!("sent magic link {}", token); + + Ok(()) +} \ No newline at end of file diff --git a/trifid-api/src/main.rs b/trifid-api/src/main.rs index 59694e7..ca641df 100644 --- a/trifid-api/src/main.rs +++ b/trifid-api/src/main.rs @@ -15,6 +15,7 @@ pub mod routes; pub mod error; pub mod tokens; pub mod timers; +pub mod magic_link; pub struct AppState { pub conn: DatabaseConnection @@ -60,6 +61,8 @@ async fn main() -> Result<(), Box> { ).into() })) .wrap(RequestIdentifier::with_generator(random_id_no_id)) + .service(routes::v1::auth::magic_link::magic_link_request) + .service(routes::v1::signup::signup_request) }).bind(CONFIG.server.bind)?.run().await?; Ok(()) diff --git a/trifid-api/src/routes/mod.rs b/trifid-api/src/routes/mod.rs index 5696e21..5dd9fd0 100644 --- a/trifid-api/src/routes/mod.rs +++ b/trifid-api/src/routes/mod.rs @@ -1 +1 @@ -pub mod auth; \ No newline at end of file +pub mod v1; \ No newline at end of file diff --git a/trifid-api/src/routes/auth/magic_link.rs b/trifid-api/src/routes/v1/auth/magic_link.rs similarity index 79% rename from trifid-api/src/routes/auth/magic_link.rs rename to trifid-api/src/routes/v1/auth/magic_link.rs index 6c9bd4c..c5ae562 100644 --- a/trifid-api/src/routes/auth/magic_link.rs +++ b/trifid-api/src/routes/v1/auth/magic_link.rs @@ -3,11 +3,12 @@ use actix_web::web::{Data, Json}; use log::error; use sea_orm::{ActiveModelTrait, ColumnTrait, DatabaseConnection, EntityTrait, IntoActiveModel, QueryFilter}; use serde::{Serialize, Deserialize}; -use trifid_api_entities::user::Entity as UserEntity; -use trifid_api_entities::user; +use trifid_api_entities::entity::user::Entity as UserEntity; +use trifid_api_entities::entity::user; use crate::AppState; use crate::config::CONFIG; use crate::error::{APIError, APIErrorsResponse}; +use crate::magic_link::send_magic_link; use crate::timers::expires_in_seconds; use crate::tokens::random_token; @@ -59,12 +60,28 @@ pub async fn magic_link_request(data: Data, req: Json (), + Err(e) => { + error!("error sending magic link: {}", e); + return HttpResponse::InternalServerError().json(APIErrorsResponse { + errors: vec![ + APIError { + code: "ERR_ML_ERROR".to_string(), + message: "There was an error sending the magic link email, please try again later.".to_string(), + path: None, + } + ], + }) + } + } + let active_model = model.into_active_model(); match active_model.insert(&data.conn).await { diff --git a/trifid-api/src/routes/auth/mod.rs b/trifid-api/src/routes/v1/auth/mod.rs similarity index 100% rename from trifid-api/src/routes/auth/mod.rs rename to trifid-api/src/routes/v1/auth/mod.rs diff --git a/trifid-api/src/routes/v1/mod.rs b/trifid-api/src/routes/v1/mod.rs new file mode 100644 index 0000000..becd02a --- /dev/null +++ b/trifid-api/src/routes/v1/mod.rs @@ -0,0 +1,2 @@ +pub mod auth; +pub mod signup; \ No newline at end of file diff --git a/trifid-api/src/routes/v1/signup.rs b/trifid-api/src/routes/v1/signup.rs new file mode 100644 index 0000000..92b5ac8 --- /dev/null +++ b/trifid-api/src/routes/v1/signup.rs @@ -0,0 +1,128 @@ +use actix_web::{HttpResponse, post}; +use actix_web::web::{Data, Json}; +use log::error; +use sea_orm::{ActiveModelTrait, ColumnTrait, DatabaseConnection, EntityTrait, IntoActiveModel, QueryFilter}; +use serde::{Serialize, Deserialize}; +use trifid_api_entities::entity::user::Entity as UserEntity; +use trifid_api_entities::entity::user; +use crate::AppState; +use crate::config::CONFIG; +use crate::error::{APIError, APIErrorsResponse}; +use crate::magic_link::send_magic_link; +use crate::timers::expires_in_seconds; +use crate::tokens::{random_id, random_token}; + +#[derive(Serialize, Deserialize, Clone, Debug)] +pub struct SignupRequest { + pub email: String +} + +#[derive(Serialize, Deserialize, Clone, Debug)] +pub struct SignupResponse { + pub data: Option, + pub metadata: SignupResponseMetadata +} +#[derive(Serialize, Deserialize, Clone, Debug)] +pub struct SignupResponseData {} +#[derive(Serialize, Deserialize, Clone, Debug)] +pub struct SignupResponseMetadata {} + +#[post("/v1/signup")] +pub async fn signup_request(data: Data, req: Json) -> HttpResponse { + let user: Vec = match UserEntity::find().filter(user::Column::Email.eq(&req.email)).all(&data.conn).await { + Ok(r) => r, + Err(e) => { + error!("database error: {}", e); + return HttpResponse::InternalServerError().json(APIErrorsResponse { + errors: vec![ + APIError { + code: "ERR_DB_ERROR".to_string(), + message: "There was an error with the database request, please try again later.".to_string(), + path: None, + } + ], + }) + } + }; + + if user.is_empty() { + return HttpResponse::Unauthorized().json(APIErrorsResponse { + errors: vec![ + APIError { + code: "ERR_USER_EXISTS".to_string(), + message: "That user already exists.".to_string(), + path: None, + } + ], + }) + } + + let model = user::Model { + id: random_id("user"), + email: req.email.clone() + }; + let id = model.id.clone(); + + let active_model = model.into_active_model(); + + match active_model.insert(&data.conn).await { + Ok(_) => (), + Err(e) => { + error!("database error: {}", e); + return HttpResponse::InternalServerError().json(APIErrorsResponse { + errors: vec![ + APIError { + code: "ERR_DB_ERROR".to_string(), + message: "There was an error with the database request, please try again later.".to_string(), + path: None, + } + ], + }) + } + } + + let model = trifid_api_entities::entity::magic_link::Model { + id: random_token("ml"), + user: id, + expires_on: expires_in_seconds(CONFIG.tokens.magic_link_expiry_time_seconds) as i64, + }; + + match send_magic_link(&model.id) { + Ok(_) => (), + Err(e) => { + error!("error sending magic link: {}", e); + return HttpResponse::InternalServerError().json(APIErrorsResponse { + errors: vec![ + APIError { + code: "ERR_ML_ERROR".to_string(), + message: "There was an error sending the magic link email, please try again later.".to_string(), + path: None, + } + ], + }) + } + } + + let active_model = model.into_active_model(); + + match active_model.insert(&data.conn).await { + Ok(_) => (), + Err(e) => { + error!("database error: {}", e); + return HttpResponse::InternalServerError().json(APIErrorsResponse { + errors: vec![ + APIError { + code: "ERR_DB_ERROR".to_string(), + message: "There was an error with the database request, please try again later.".to_string(), + path: None, + } + ], + }) + } + } + + HttpResponse::Ok().json(SignupResponse { + data: None, + metadata: SignupResponseMetadata {} + }) +} \ No newline at end of file diff --git a/trifid-api/trifid_api_entities/src/magic_link.rs b/trifid-api/trifid_api_entities/src/entity/magic_link.rs similarity index 100% rename from trifid-api/trifid_api_entities/src/magic_link.rs rename to trifid-api/trifid_api_entities/src/entity/magic_link.rs diff --git a/trifid-api/trifid_api_entities/src/entity/mod.rs b/trifid-api/trifid_api_entities/src/entity/mod.rs new file mode 100644 index 0000000..3bd313d --- /dev/null +++ b/trifid-api/trifid_api_entities/src/entity/mod.rs @@ -0,0 +1,6 @@ +//! `SeaORM` Entity. Generated by sea-orm-codegen 0.11.2 + +pub mod prelude; + +pub mod magic_link; +pub mod user; diff --git a/trifid-api/trifid_api_entities/src/prelude.rs b/trifid-api/trifid_api_entities/src/entity/prelude.rs similarity index 100% rename from trifid-api/trifid_api_entities/src/prelude.rs rename to trifid-api/trifid_api_entities/src/entity/prelude.rs diff --git a/trifid-api/trifid_api_entities/src/user.rs b/trifid-api/trifid_api_entities/src/entity/user.rs similarity index 95% rename from trifid-api/trifid_api_entities/src/user.rs rename to trifid-api/trifid_api_entities/src/entity/user.rs index 91414d6..f7d4230 100644 --- a/trifid-api/trifid_api_entities/src/user.rs +++ b/trifid-api/trifid_api_entities/src/entity/user.rs @@ -9,7 +9,6 @@ pub struct Model { pub id: String, #[sea_orm(unique)] pub email: String, - pub password_hash: String, } #[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)] diff --git a/trifid-api/trifid_api_entities/src/lib.rs b/trifid-api/trifid_api_entities/src/lib.rs index d1b689d..bccca66 100644 --- a/trifid-api/trifid_api_entities/src/lib.rs +++ b/trifid-api/trifid_api_entities/src/lib.rs @@ -1,6 +1 @@ -//! `SeaORM` Entity. Generated by sea-orm-codegen 0.11.2 - -pub mod prelude; - -pub mod user; -pub mod magic_link; \ No newline at end of file +pub mod entity; \ No newline at end of file diff --git a/trifid-api/trifid_api_migration/src/m20230402_162601_create_table_users.rs b/trifid-api/trifid_api_migration/src/m20230402_162601_create_table_users.rs index 3b54040..1e04c6a 100644 --- a/trifid-api/trifid_api_migration/src/m20230402_162601_create_table_users.rs +++ b/trifid-api/trifid_api_migration/src/m20230402_162601_create_table_users.rs @@ -13,7 +13,6 @@ impl MigrationTrait for Migration { .if_not_exists() .col(ColumnDef::new(User::Id).string().not_null().primary_key()) .col(ColumnDef::new(User::Email).string().not_null().unique_key()) - .col(ColumnDef::new(User::PasswordHash).string().not_null()) .to_owned() ).await } @@ -28,6 +27,5 @@ impl MigrationTrait for Migration { pub enum User { Table, Id, - Email, - PasswordHash, + Email }