-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
validators, form_process rewrite, form_config
- Loading branch information
1 parent
47d7fcb
commit 1619570
Showing
10 changed files
with
310 additions
and
61 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,5 +1,7 @@ | ||
SERVER_IP=127.0.0.1:8080 | ||
SMTP_USER=your_smtp_user | ||
# !! LOCALHOST: 127.0.0.1:8080 | ||
# !! IP SHOULD BE DECLARED IN FORMAT IP:PORT | ||
SERVER_IP=your_ip | ||
SMTP_PASS=your_smtp_pass | ||
SMTP_HOST=your_smtp_host | ||
DATABASE_URL=postgres://user:password@host/database | ||
DATABASE_URL=postgres://user:password@host/database | ||
SMTP_USER=your_smtp_user |
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
use regex::Regex; | ||
|
||
pub trait EmailValidator { | ||
fn is_valid(&self, email: &str) -> bool; | ||
} | ||
|
||
pub struct EmailRegexValidator { | ||
regex: Regex, | ||
} | ||
|
||
impl EmailRegexValidator { | ||
pub fn new() -> Self { | ||
let regex = Regex::new(r"^[a-zA-Z0-9.!#$%&'*+/=?^_`{|}~-]+@[a-zA-Z0-9-]+(?:\.[a-zA-Z0-9-]+)*$").unwrap(); | ||
Self { regex } | ||
} | ||
} | ||
|
||
impl EmailValidator for EmailRegexValidator { | ||
fn is_valid(&self, email: &str) -> bool { | ||
self.regex.is_match(email) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,113 @@ | ||
use crate::email_validator::{EmailRegexValidator, EmailValidator}; | ||
use crate::input_validator::NonEmptyInputValidator; | ||
use std::env; | ||
use tera::Context; | ||
|
||
pub trait FormConfig { | ||
fn set_email(&mut self, email: String); | ||
fn set_name(&mut self, name: String); | ||
fn set_message_body(&mut self, message_body: String); | ||
fn smtp_user(&self) -> String; | ||
fn smtp_pass(&self) -> String; | ||
fn smtp_host(&self) -> String; | ||
fn input_validator(&self) -> &NonEmptyInputValidator; | ||
fn message_printed(&mut self) -> &mut bool; | ||
fn email(&self) -> String; | ||
fn name(&self) -> String; | ||
fn message_body(&self) -> String; | ||
fn context(&mut self) -> &mut Context; | ||
fn email_validator(&self) -> &dyn EmailValidator; | ||
} | ||
|
||
pub struct FormConfigImpl { | ||
smtp_user: String, | ||
smtp_pass: String, | ||
smtp_host: String, | ||
email_validator: EmailRegexValidator, | ||
input_validator: NonEmptyInputValidator, | ||
message_printed: bool, | ||
email: String, | ||
name: String, | ||
message_body: String, | ||
context: Context, | ||
} | ||
|
||
impl FormConfigImpl { | ||
pub fn new() -> Self { | ||
let smtp_user = env::var("SMTP_USER").expect("SMTP_USER must be set"); | ||
let smtp_pass = env::var("SMTP_PASS").expect("SMTP_PASS must be set"); | ||
let smtp_host = env::var("SMTP_HOST").expect("SMTP_HOST must be set"); | ||
let email_validator = EmailRegexValidator::new(); | ||
let input_validator = NonEmptyInputValidator; | ||
let mut context = Context::new(); | ||
context.insert("name", "User"); | ||
context.insert("context", "Rust Form"); | ||
|
||
Self { | ||
smtp_user, | ||
smtp_pass, | ||
smtp_host, | ||
email_validator, | ||
input_validator, | ||
message_printed: false, | ||
email: String::new(), | ||
name: String::new(), | ||
message_body: String::new(), | ||
context, | ||
} | ||
} | ||
} | ||
|
||
impl FormConfig for FormConfigImpl { | ||
fn smtp_user(&self) -> String { | ||
self.smtp_user.clone() | ||
} | ||
|
||
fn smtp_pass(&self) -> String { | ||
self.smtp_pass.clone() | ||
} | ||
|
||
fn smtp_host(&self) -> String { | ||
self.smtp_host.clone() | ||
} | ||
|
||
fn email_validator(&self) -> &dyn EmailValidator { | ||
&self.email_validator | ||
} | ||
|
||
fn input_validator(&self) -> &NonEmptyInputValidator { | ||
&self.input_validator | ||
} | ||
|
||
fn message_printed(&mut self) -> &mut bool { | ||
&mut self.message_printed | ||
} | ||
|
||
fn email(&self) -> String { | ||
self.email.clone() | ||
} | ||
|
||
fn name(&self) -> String { | ||
self.name.clone() | ||
} | ||
|
||
fn message_body(&self) -> String { | ||
self.message_body.clone() | ||
} | ||
|
||
fn context(&mut self) -> &mut Context { | ||
&mut self.context | ||
} | ||
|
||
fn set_email(&mut self, email: String) { | ||
self.email = email; | ||
} | ||
|
||
fn set_name(&mut self, name: String) { | ||
self.name = name; | ||
} | ||
|
||
fn set_message_body(&mut self, message_body: String) { | ||
self.message_body = message_body; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,81 +1,77 @@ | ||
use crate::input_validator::InputValidator; | ||
use crate::form_config::{FormConfig, FormConfigImpl}; | ||
use crate::{log_info, log_warn, log_error}; | ||
use crate::log::{info, error, warn}; | ||
use crate::time::current_time; | ||
|
||
use actix_web::{web, HttpResponse}; | ||
use lettre::{Message, SmtpTransport, Transport}; | ||
use lettre::transport::smtp::authentication::Credentials; | ||
use tera::{Context, Tera}; | ||
use std::env; | ||
use tera::{Tera}; | ||
|
||
#[allow(non_snake_case)] | ||
pub async fn process_form(form: web::Form<std::collections::HashMap<String, String>>) -> HttpResponse { | ||
|
||
let mut context = Context::new(); // create a new Tera context | ||
context.insert("name", "User"); | ||
context.insert("context", "Rust Form"); | ||
|
||
// defining SMTP server credentials as static variables | ||
let SMTP_USER = env::var("SMTP_USER").expect("SMTP_USER must be set"); // get the SMTP_USER from the .env file | ||
let SMTP_PASS = env::var("SMTP_PASS").expect("SMTP_PASS must be set"); // get the SMTP_PASS from the .env file | ||
let SMTP_HOST = env::var("SMTP_HOST").expect("SMTP_HOST must be set"); // get the SMTP_HOST from the .env file | WITHOUT SSL:// OR TLS://!!! | ||
let now = current_time(); | ||
let mut config = FormConfigImpl::new(); | ||
|
||
let mut email = String::new(); | ||
let mut name = String::new(); | ||
let mut message_body = String::new(); | ||
|
||
for (key, value) in form.into_inner() { // iterate over the form data | ||
match value.is_empty() { | ||
true => { | ||
context.insert("error", &format!("{} cannot be empty", key)); | ||
match (name.is_empty(), email.is_empty(), message_body.is_empty()) { | ||
for (key, value) in form.into_inner() { | ||
match config.input_validator().is_valid(&value) { | ||
false => { | ||
config.context().insert("error", &format!("{} cannot be empty", key)); | ||
match (config.name().is_empty(), config.email().is_empty(), config.message_body().is_empty()) { | ||
(true, true, true) => { | ||
context.insert("error", "smtp is not magic, type smth"); | ||
println!("User is bruh"); | ||
//if !*config.message_printed() { | ||
config.context().insert("error", "smtp is not magic, type smth"); | ||
log_error!(&now, "User didn't entered anything for: {}", key); | ||
// *config.message_printed() = true; | ||
//} | ||
}, | ||
_ => println!("User didn't entered {}", key), | ||
_ => log_warn!(&now, "User didn't entered {}", key), | ||
} | ||
continue; | ||
} | ||
false => { | ||
context.insert(key.as_str(), &value); | ||
println!("User entered {} for {}", value, key); | ||
true => { | ||
config.context().insert(key.as_str(), &value); | ||
log_info!(&now, "User entered {} for {}", value, key); | ||
match key.as_str() { | ||
"email" => email = value, | ||
"name" => name = value, | ||
"message" => message_body = value, | ||
"email" => config.set_email(value), | ||
"name" => config.set_name(value), | ||
"message" => config.set_message_body(value), | ||
_ => (), | ||
} | ||
} | ||
} | ||
} | ||
// creating let with SMTP credentials | ||
let credentials = Credentials::new(SMTP_USER.to_string(), SMTP_PASS.to_string()); | ||
|
||
|
||
// creating let for an SMTP transport | ||
// i was trying to make relay(SMTP_SERVER) but it looks like that relay doesn't like this idk why | ||
let mailer = SmtpTransport::relay(&SMTP_HOST) | ||
let credentials = Credentials::new(config.smtp_user(), config.smtp_pass()); | ||
let mailer = SmtpTransport::relay(&config.smtp_host()) | ||
.unwrap() | ||
.credentials(credentials) | ||
.build(); | ||
|
||
match (email.is_empty() || !email.contains('@'), SMTP_USER.is_empty() || !SMTP_USER.contains('@')) { // validate the email address and SMTP username | ||
(true, _) => context.insert("error", "Invalid email address"), | ||
(_, true) => context.insert("error", "Invalid SMTP username"), | ||
(false, false) => { | ||
let message = Message::builder() // create an email message | ||
.from(SMTP_USER.parse().unwrap()) | ||
.to(email.parse().unwrap()) | ||
match (config.email_validator().is_valid(&config.email()), config.email_validator().is_valid(&config.smtp_user())) { | ||
(false, _) => config.context().insert("error", "Invalid email address"), | ||
(_, false) => config.context().insert("error", "Invalid SMTP username"), | ||
(true, true) => { | ||
let message = Message::builder() | ||
.from(config.smtp_user().parse().unwrap()) | ||
.to(config.email().parse().unwrap()) | ||
.subject("Form Submission") | ||
.body(format!( | ||
"Thank you for your submission, {}!\n\nYour message:\n{}", | ||
name, message_body | ||
config.name(), config.message_body() | ||
)) | ||
.unwrap(); | ||
|
||
// send the email message | ||
match mailer.send(&message) { | ||
Ok(_) => println!("Email sended: {}", email), | ||
Err(e) => eprintln!("Error sending email: {:?}", e), | ||
Ok(_) => log_info!(&now, "Email sended: {}", config.email()), | ||
Err(e) => log_error!(&now, "Error sending email: {:?}", e), | ||
} | ||
} | ||
} | ||
let body = Tera::one_off(include_str!("templates/form.tera"), &context, false).unwrap(); // render the template with the context | ||
HttpResponse::Ok().body(body) // return the rendered template as the response body | ||
|
||
|
||
let body = Tera::one_off(include_str!("templates/form.tera"), &config.context(), false).unwrap(); | ||
HttpResponse::Ok().body(body) | ||
} |
Oops, something went wrong.