102 lines
3.3 KiB
Rust
102 lines
3.3 KiB
Rust
use actix_web::{error, web, HttpResponse};
|
|
use handlebars::Handlebars;
|
|
use lettre::{message::header::ContentType, Message, SmtpTransport, Transport};
|
|
use log::debug;
|
|
use rand::{distributions::Alphanumeric, thread_rng, Rng};
|
|
use serde_json::json;
|
|
use terminwahl_typen::{Nutzer, PlannedAppointment, RequestState};
|
|
|
|
use crate::db::{self, write::confirm_appointments, Pool};
|
|
|
|
pub async fn save_appointments_json(
|
|
pool: web::Data<Pool>,
|
|
mailer: web::Data<SmtpTransport>,
|
|
handlebars: web::Data<Handlebars<'_>>,
|
|
input: web::Json<(Vec<PlannedAppointment>, Nutzer)>,
|
|
) -> Result<HttpResponse, error::Error> {
|
|
debug!("Extracting data");
|
|
let (appointments, nutzer) = input.into_inner();
|
|
debug!("Saving user");
|
|
let nutzer_id = db::write::save_nutzer(&pool, &nutzer)
|
|
.await
|
|
.map_err(error::ErrorInternalServerError)?;
|
|
debug!("Saving appointments");
|
|
let validation_key: String = thread_rng()
|
|
.sample_iter(&Alphanumeric)
|
|
.take(30)
|
|
.map(char::from)
|
|
.collect();
|
|
db::write::save_appointments(&pool, &appointments, nutzer_id, &validation_key)
|
|
.await
|
|
.map_err(error::ErrorInternalServerError)?;
|
|
|
|
let mail_result = send_confirmation_request(&nutzer, &validation_key, &handlebars, &mailer);
|
|
|
|
Ok(HttpResponse::Ok().json(mail_result))
|
|
}
|
|
|
|
pub fn send_confirmation_request(
|
|
nutzer: &Nutzer,
|
|
validation_key: &str,
|
|
handlebars: &Handlebars,
|
|
mailer: &SmtpTransport,
|
|
) -> RequestState {
|
|
let data = json! {
|
|
{
|
|
"nutzer": nutzer,
|
|
"validation_key": validation_key
|
|
}};
|
|
debug!("{:?}", handlebars.get_templates());
|
|
if let Ok(email_text) = handlebars.render("email_confirm", &data) {
|
|
let email = match Message::builder()
|
|
.from(
|
|
"Franz Dietrich <franz.dietrich@uhlandshoehe.de>"
|
|
.parse()
|
|
.expect("Should not fail"),
|
|
)
|
|
.to(
|
|
match format!("{} <{}>", nutzer.name, nutzer.email).parse() {
|
|
Ok(v) => v,
|
|
Err(_) => return RequestState::Error,
|
|
},
|
|
)
|
|
.subject("Elternsprechtag: Bestätigen Sie Ihre Termine")
|
|
.header(ContentType::TEXT_PLAIN)
|
|
.body(
|
|
match lettre::message::Body::new_with_encoding(
|
|
email_text,
|
|
lettre::message::header::ContentTransferEncoding::Base64,
|
|
) {
|
|
Ok(body) => body,
|
|
Err(_) => return RequestState::Error,
|
|
},
|
|
) {
|
|
Ok(message) => message,
|
|
Err(_) => return RequestState::Error,
|
|
};
|
|
|
|
// Send the email
|
|
match mailer.send(&email) {
|
|
Ok(_) => RequestState::Success,
|
|
Err(e) => {
|
|
debug!("Failed to send: {e}");
|
|
RequestState::Error
|
|
}
|
|
}
|
|
} else {
|
|
RequestState::Error
|
|
}
|
|
}
|
|
|
|
pub async fn confirm_validation_key(
|
|
pool: web::Data<Pool>,
|
|
mailer: web::Data<SmtpTransport>,
|
|
handlebars: web::Data<Handlebars<'_>>,
|
|
validation_key: web::Path<String>,
|
|
) -> Result<HttpResponse, error::Error> {
|
|
match confirm_appointments(&pool, &validation_key).await {
|
|
Ok(_) => Ok(HttpResponse::Ok().json(RequestState::Success)),
|
|
Err(e) => Err(error::ErrorBadRequest(e)),
|
|
}
|
|
}
|