diff --git a/.gitea/workflows/action.yml b/.gitea/workflows/action.yml index 5800d8f..3aa015f 100644 --- a/.gitea/workflows/action.yml +++ b/.gitea/workflows/action.yml @@ -11,7 +11,7 @@ env: jobs: test: runs-on: ubuntu-latest - container: git.hofer.link/ruderverein-donau-linz/rowing-ci:20240118 + container: git.hofer.link/ruderverein-donau-linz/rowing-ci:20240215 steps: - uses: actions/checkout@v3 - name: Run Test DB Script @@ -46,7 +46,7 @@ jobs: deploy-staging: runs-on: ubuntu-latest - container: git.hofer.link/ruderverein-donau-linz/rowing-ci:20240118 + container: git.hofer.link/ruderverein-donau-linz/rowing-ci:20240215 needs: [test] if: github.ref == 'refs/heads/staging' steps: @@ -97,7 +97,7 @@ jobs: deploy-main: runs-on: ubuntu-latest - container: git.hofer.link/ruderverein-donau-linz/rowing-ci:20240118 + container: git.hofer.link/ruderverein-donau-linz/rowing-ci:20240215 needs: [test] if: github.ref == 'refs/heads/main' steps: diff --git a/Dockerfile b/Dockerfile index 5db574a..cbc154d 100644 --- a/Dockerfile +++ b/Dockerfile @@ -5,7 +5,7 @@ # 2. Tag the image: `docker tag git.hofer.link/ruderverein-donau-linz/rowing-ci:` # 3. Push the image: `docker push git.hofer.link/ruderverein-donau-linz/rowing-ci:` -FROM rust:1.75.0 +FROM rust:1.76 RUN apt-get update && apt-get install -y sqlite3 diff --git a/src/model/mail.rs b/src/model/mail.rs index 5a99aec..6df129c 100644 --- a/src/model/mail.rs +++ b/src/model/mail.rs @@ -1,8 +1,9 @@ -use std::error::Error; +use std::{error::Error, fs}; use lettre::{ - message::header::ContentType, transport::smtp::authentication::Credentials, Message, - SmtpTransport, Transport, + message::{header::ContentType, Attachment, MultiPart, SinglePart}, + transport::smtp::authentication::Credentials, + Message, SmtpTransport, Transport, }; use sqlx::SqlitePool; @@ -13,7 +14,7 @@ use super::{family::Family, log::Log, role::Role, user::User}; pub struct Mail {} impl Mail { - pub async fn send(db: &SqlitePool, data: MailToSend, smtp_pw: String) -> bool { + pub async fn send(db: &SqlitePool, data: MailToSend<'_>, smtp_pw: String) -> bool { let mut email = Message::builder() .from( "ASKÖ Ruderverein Donau Linz " @@ -45,13 +46,23 @@ impl Mail { } } - // TODO: handle attachments + let mut multipart = MultiPart::mixed().singlepart(SinglePart::plain(data.body)); - let email = email - .subject(data.subject) - .header(ContentType::TEXT_PLAIN) - .body(String::from(data.body)) - .unwrap(); + for temp_file in &data.files { + let content = fs::read(temp_file.path().unwrap()).unwrap(); + let media_type = format!("{}", temp_file.content_type().unwrap().media_type()); + let content_type = ContentType::parse(&media_type).unwrap(); + let attachment = Attachment::new(format!( + "{}.{}", + temp_file.name().unwrap(), + temp_file.content_type().unwrap().extension().unwrap() + )) + .body(content, content_type); + + multipart = multipart.singlepart(attachment); + } + + let email = email.subject(data.subject).multipart(multipart).unwrap(); let creds = Credentials::new("no-reply@rudernlinz.at".to_owned(), smtp_pw); diff --git a/src/model/role.rs b/src/model/role.rs index 111b18b..f66120c 100644 --- a/src/model/role.rs +++ b/src/model/role.rs @@ -51,7 +51,7 @@ WHERE name like ? FROM user u JOIN user_role ur ON u.id = ur.user_id JOIN role r ON ur.role_id = r.id - WHERE r.id = {}", + WHERE r.id = {} AND deleted=0;", self.id ); diff --git a/src/tera/admin/mail.rs b/src/tera/admin/mail.rs index 450c513..fee06ab 100644 --- a/src/tera/admin/mail.rs +++ b/src/tera/admin/mail.rs @@ -1,4 +1,5 @@ use rocket::form::Form; +use rocket::fs::TempFile; use rocket::response::{Flash, Redirect}; use rocket::{get, request::FlashMessage, routes, Route, State}; use rocket::{post, FromForm}; @@ -39,18 +40,17 @@ async fn fee(db: &State, _admin: AdminUser, config: &State) } #[derive(FromForm, Debug)] -pub struct MailToSend { - //<'a> { +pub struct MailToSend<'a> { pub(crate) role_id: i32, pub(crate) subject: String, pub(crate) body: String, - //pub(crate) files: Vec>, + pub(crate) files: Vec>, } #[post("/mail", data = "")] async fn update( db: &State, - data: Form, + data: Form>, config: &State, _admin: AdminUser, ) -> Flash {