From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from firstgate.proxmox.com (firstgate.proxmox.com [212.224.123.68]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits)) (No client certificate requested) by lists.proxmox.com (Postfix) with ESMTPS id AF5A2F17D for ; Thu, 20 Jul 2023 16:34:02 +0200 (CEST) Received: from firstgate.proxmox.com (localhost [127.0.0.1]) by firstgate.proxmox.com (Proxmox) with ESMTP id 428881495E for ; Thu, 20 Jul 2023 16:33:13 +0200 (CEST) Received: from proxmox-new.maurer-it.com (proxmox-new.maurer-it.com [94.136.29.106]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits)) (No client certificate requested) by firstgate.proxmox.com (Proxmox) with ESMTPS for ; Thu, 20 Jul 2023 16:33:11 +0200 (CEST) Received: from proxmox-new.maurer-it.com (localhost.localdomain [127.0.0.1]) by proxmox-new.maurer-it.com (Proxmox) with ESMTP id E9A3A41FEA for ; Thu, 20 Jul 2023 16:33:09 +0200 (CEST) From: Lukas Wagner To: pve-devel@lists.proxmox.com Date: Thu, 20 Jul 2023 16:31:59 +0200 Message-Id: <20230720143236.652292-33-l.wagner@proxmox.com> X-Mailer: git-send-email 2.39.2 In-Reply-To: <20230720143236.652292-1-l.wagner@proxmox.com> References: <20230720143236.652292-1-l.wagner@proxmox.com> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-SPAM-LEVEL: Spam detection results: 0 AWL -0.086 Adjusted score from AWL reputation of From: address BAYES_00 -1.9 Bayes spam probability is 0 to 1% DMARC_MISSING 0.1 Missing DMARC policy KAM_DMARC_STATUS 0.01 Test Rule for DKIM or SPF Failure with Strict Alignment SPF_HELO_NONE 0.001 SPF: HELO does not publish an SPF Record SPF_PASS -0.001 SPF: sender matches SPF record T_SCC_BODY_TEXT_LINE -0.01 - Subject: [pve-devel] [PATCH v4 proxmox-perl-rs 32/69] notify: sendmail: support the `mailto-user` parameter X-BeenThere: pve-devel@lists.proxmox.com X-Mailman-Version: 2.1.29 Precedence: list List-Id: Proxmox VE development discussion List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 20 Jul 2023 14:34:02 -0000 This parameter allows to send mails to the email address configured for users from the product's user database. `proxmox-notify` now has a `Context` that must be set via `proxmox_notify::context::set_context` before the crate is used. Signed-off-by: Lukas Wagner --- pve-rs/Cargo.toml | 1 + pve-rs/src/lib.rs | 3 +- pve-rs/src/notify.rs | 82 +++++++++++++++++++++++++++++++++++++++++++- 3 files changed, 84 insertions(+), 2 deletions(-) diff --git a/pve-rs/Cargo.toml b/pve-rs/Cargo.toml index b28c118..954665f 100644 --- a/pve-rs/Cargo.toml +++ b/pve-rs/Cargo.toml @@ -23,6 +23,7 @@ env_logger = "0.9" hex = "0.4" http = "0.2.7" libc = "0.2" +log = "0.4.17" nix = "0.26" openssl = "0.10.40" serde = "1.0" diff --git a/pve-rs/src/lib.rs b/pve-rs/src/lib.rs index 0d63c28..49483d7 100644 --- a/pve-rs/src/lib.rs +++ b/pve-rs/src/lib.rs @@ -11,10 +11,11 @@ pub mod tfa; #[perlmod::package(name = "Proxmox::Lib::PVE", lib = "pve_rs")] mod export { - use crate::common; + use crate::{common, notify}; #[export] pub fn init() { common::logger::init("PVE_LOG", "info"); + notify::init(); } } diff --git a/pve-rs/src/notify.rs b/pve-rs/src/notify.rs index 08726e5..8def064 100644 --- a/pve-rs/src/notify.rs +++ b/pve-rs/src/notify.rs @@ -1,3 +1,79 @@ +use std::path::Path; + +use log; + +use proxmox_notify::context::Context; + +// Some helpers borrowed and slightly adapted from `proxmox-mail-forward` + +fn normalize_for_return(s: Option<&str>) -> Option { + match s?.trim() { + "" => None, + s => Some(s.to_string()), + } +} + +fn attempt_file_read>(path: P) -> Option { + match proxmox_sys::fs::file_read_optional_string(path) { + Ok(contents) => contents, + Err(err) => { + log::error!("{err}"); + None + } + } +} + +fn lookup_mail_address(content: &str, user: &str) -> Option { + normalize_for_return(content.lines().find_map(|line| { + let fields: Vec<&str> = line.split(':').collect(); + #[allow(clippy::get_first)] // to keep expression style consistent + match fields.get(0)?.trim() == "user" && fields.get(1)?.trim() == user { + true => fields.get(6).copied(), + false => None, + } + })) +} + +#[derive(Debug)] +struct PVEContext; + +impl Context for PVEContext { + fn lookup_email_for_user(&self, user: &str) -> Option { + let content = attempt_file_read("/etc/pve/user.cfg"); + content.and_then(|content| lookup_mail_address(&content, user)) + } +} + +#[cfg(test)] +mod tests { + use crate::notify::lookup_mail_address; + + const USER_CONFIG: &str = " +user:root@pam:1:0:::root@example.com::: +user:test@pve:1:0:::test@example.com::: +user:no-mail@pve:1:0:::::: + "; + + #[test] + fn test_parse_mail() { + assert_eq!( + lookup_mail_address(USER_CONFIG, "root@pam"), + Some("root@example.com".to_string()) + ); + assert_eq!( + lookup_mail_address(USER_CONFIG, "test@pve"), + Some("test@example.com".to_string()) + ); + assert_eq!(lookup_mail_address(USER_CONFIG, "no-mail@pve"), None); + } +} + +static CONTEXT: PVEContext = PVEContext; + +pub fn init() { + proxmox_notify::context::set_context(&CONTEXT) +} + #[perlmod::package(name = "PVE::RS::Notify")] mod export { use anyhow::{bail, Error}; @@ -204,7 +280,8 @@ mod export { fn add_sendmail_endpoint( #[try_from_ref] this: &NotificationConfig, name: String, - mailto: Vec, + mailto: Option>, + mailto_user: Option>, from_address: Option, author: Option, comment: Option, @@ -217,6 +294,7 @@ mod export { &SendmailConfig { name, mailto, + mailto_user, from_address, author, comment, @@ -231,6 +309,7 @@ mod export { #[try_from_ref] this: &NotificationConfig, name: &str, mailto: Option>, + mailto_user: Option>, from_address: Option, author: Option, comment: Option, @@ -248,6 +327,7 @@ mod export { name, &SendmailConfigUpdater { mailto, + mailto_user, from_address, author, comment, -- 2.39.2