core: notify submitter if they are already subscribed
parent
0e4f2a85b3
commit
1beac75e37
|
@ -206,21 +206,65 @@ impl Connection {
|
|||
}
|
||||
}
|
||||
PostAction::Reject { reason } => {
|
||||
/* FIXME - Notify submitter */
|
||||
trace!("PostAction::Reject {{ reason: {} }}", reason);
|
||||
//futures::executor::block_on(conn.mail_transaction(&post.bytes, b)).unwrap();
|
||||
log::info!("PostAction::Reject {{ reason: {} }}", reason);
|
||||
for f in env.from() {
|
||||
/* send error notice to e-mail sender */
|
||||
self.send_reply_with_list_template(
|
||||
TemplateRenderContext {
|
||||
template: Template::GENERIC_FAILURE,
|
||||
default_fn: Some(Template::default_generic_failure),
|
||||
list: &list,
|
||||
context: minijinja::context! {
|
||||
list => &list,
|
||||
subject => format!("Your post to {} was rejected.", list.id),
|
||||
details => &reason,
|
||||
},
|
||||
queue: Queue::Out,
|
||||
comment: format!("PostAction::Reject {{ reason: {} }}", reason),
|
||||
},
|
||||
std::iter::once(Cow::Borrowed(f)),
|
||||
)?;
|
||||
}
|
||||
return Err(PostRejected(reason).into());
|
||||
}
|
||||
PostAction::Defer { reason } => {
|
||||
trace!("PostAction::Defer {{ reason: {} }}", reason);
|
||||
/*
|
||||
* - FIXME Notify submitter
|
||||
* - FIXME Save in database */
|
||||
for f in env.from() {
|
||||
/* send error notice to e-mail sender */
|
||||
self.send_reply_with_list_template(
|
||||
TemplateRenderContext {
|
||||
template: Template::GENERIC_FAILURE,
|
||||
default_fn: Some(Template::default_generic_failure),
|
||||
list: &list,
|
||||
context: minijinja::context! {
|
||||
list => &list,
|
||||
subject => format!("Your post to {} was deferred.", list.id),
|
||||
details => &reason,
|
||||
},
|
||||
queue: Queue::Out,
|
||||
comment: format!("PostAction::Defer {{ reason: {} }}", reason),
|
||||
},
|
||||
std::iter::once(Cow::Borrowed(f)),
|
||||
)?;
|
||||
}
|
||||
self.insert_to_queue(QueueEntry::new(
|
||||
Queue::Deferred,
|
||||
Some(list.pk),
|
||||
Some(Cow::Borrowed(&post_env)),
|
||||
&bytes,
|
||||
Some(format!("PostAction::Defer {{ reason: {} }}", reason)),
|
||||
)?)?;
|
||||
return Err(PostRejected(reason).into());
|
||||
}
|
||||
PostAction::Hold => {
|
||||
trace!("PostAction::Hold");
|
||||
/* FIXME - Save in database */
|
||||
self.insert_to_queue(QueueEntry::new(
|
||||
Queue::Hold,
|
||||
Some(list.pk),
|
||||
Some(Cow::Borrowed(&post_env)),
|
||||
&bytes,
|
||||
Some("PostAction::Hold".to_string()),
|
||||
)?)?;
|
||||
return Err(PostRejected("Hold".into()).into());
|
||||
}
|
||||
}
|
||||
|
@ -245,12 +289,35 @@ impl Connection {
|
|||
env.from(),
|
||||
list
|
||||
);
|
||||
|
||||
let approval_needed = post_policy
|
||||
.as_ref()
|
||||
.map(|p| p.approval_needed)
|
||||
.unwrap_or(false);
|
||||
for f in env.from() {
|
||||
let email_from = f.get_email();
|
||||
if self
|
||||
.list_subscription_by_address(list.pk, &email_from)
|
||||
.is_ok()
|
||||
{
|
||||
/* send error notice to e-mail sender */
|
||||
self.send_reply_with_list_template(
|
||||
TemplateRenderContext {
|
||||
template: Template::GENERIC_FAILURE,
|
||||
default_fn: Some(Template::default_generic_failure),
|
||||
list,
|
||||
context: minijinja::context! {
|
||||
list => &list,
|
||||
subject => format!("You are already subscribed to {}.", list.id),
|
||||
details => "No action has been taken since you are already subscribed to the list.",
|
||||
},
|
||||
queue: Queue::Out,
|
||||
comment: format!("Address {} is already subscribed to list {}", f, list.id),
|
||||
},
|
||||
std::iter::once(Cow::Borrowed(f)),
|
||||
)?;
|
||||
continue;
|
||||
}
|
||||
|
||||
let subscription = ListSubscription {
|
||||
pk: 0,
|
||||
list: list.pk,
|
||||
|
@ -368,6 +435,10 @@ impl Connection {
|
|||
list_owners.iter().map(|owner| Cow::Owned(owner.address())),
|
||||
)?;
|
||||
} else {
|
||||
log::trace!(
|
||||
"Added subscription to list {list:?} for address {f:?}, sending \
|
||||
confirmation."
|
||||
);
|
||||
self.send_reply_with_list_template(
|
||||
TemplateRenderContext {
|
||||
template: Template::SUBSCRIPTION_CONFIRMATION,
|
||||
|
|
|
@ -61,7 +61,7 @@ impl Queue {
|
|||
}
|
||||
|
||||
/// A queue entry.
|
||||
#[derive(Clone, Debug, Deserialize, Serialize, PartialEq, Eq)]
|
||||
#[derive(Clone, Deserialize, Serialize, PartialEq, Eq)]
|
||||
pub struct QueueEntry {
|
||||
/// Database primary key.
|
||||
pub pk: i64,
|
||||
|
@ -93,6 +93,28 @@ impl std::fmt::Display for QueueEntry {
|
|||
}
|
||||
}
|
||||
|
||||
impl std::fmt::Debug for QueueEntry {
|
||||
fn fmt(&self, fmt: &mut std::fmt::Formatter) -> std::fmt::Result {
|
||||
fmt.debug_struct(stringify!(QueueEntry))
|
||||
.field("pk", &self.pk)
|
||||
.field("queue", &self.queue)
|
||||
.field("list", &self.list)
|
||||
.field("comment", &self.comment)
|
||||
.field("to_addresses", &self.to_addresses)
|
||||
.field("from_address", &self.from_address)
|
||||
.field("subject", &self.subject)
|
||||
.field("message_id", &self.message_id)
|
||||
.field("message length", &self.message.len())
|
||||
.field(
|
||||
"message",
|
||||
&format!("{:.15}", String::from_utf8_lossy(&self.message)),
|
||||
)
|
||||
.field("timestamp", &self.timestamp)
|
||||
.field("datetime", &self.datetime)
|
||||
.finish()
|
||||
}
|
||||
}
|
||||
|
||||
impl QueueEntry {
|
||||
/// Create new entry.
|
||||
pub fn new(
|
||||
|
@ -125,6 +147,7 @@ impl QueueEntry {
|
|||
impl Connection {
|
||||
/// Insert a received email into a queue.
|
||||
pub fn insert_to_queue(&self, mut entry: QueueEntry) -> Result<DbVal<QueueEntry>> {
|
||||
log::trace!("Inserting to queue: {entry}");
|
||||
let mut stmt = self.connection.prepare(
|
||||
"INSERT INTO queue(which, list, comment, to_addresses, from_address, subject, \
|
||||
message_id, message, timestamp, datetime) VALUES(?, ?, ?, ?, ?, ?, ?, ?, ?, ?) \
|
||||
|
|
|
@ -144,6 +144,16 @@ impl PostFilter for AddListHeaders {
|
|||
let (mut headers, body) = melib::email::parser::mail(&post.bytes).unwrap();
|
||||
let sender = format!("<{}>", ctx.list.address);
|
||||
headers.push((&b"Sender"[..], sender.as_bytes()));
|
||||
let mut subject = format!("[{}] ", ctx.list.id).into_bytes();
|
||||
if let Some((_, subj_val)) = headers
|
||||
.iter_mut()
|
||||
.find(|(k, _)| k.eq_ignore_ascii_case(b"Subject"))
|
||||
{
|
||||
subject.extend(subj_val.iter().cloned());
|
||||
*subj_val = subject.as_slice();
|
||||
} else {
|
||||
headers.push((&b"Subject"[..], subject.as_slice()));
|
||||
}
|
||||
|
||||
let list_id = Some(ctx.list.id_header());
|
||||
let list_help = ctx.list.help_header();
|
||||
|
@ -233,9 +243,6 @@ impl PostFilter for FinalizeRecipients {
|
|||
trace!("Subscription gets copy");
|
||||
recipients.push(subscription.address());
|
||||
}
|
||||
// TODO:
|
||||
// - check for duplicates (To,Cc,Bcc)
|
||||
// - send confirmation to submitter
|
||||
}
|
||||
ctx.scheduled_jobs.push(MailJob::Send { recipients });
|
||||
if !digests.is_empty() {
|
||||
|
|
|
@ -86,7 +86,10 @@ impl Template {
|
|||
pk: -1,
|
||||
name: Self::GENERIC_FAILURE.to_string(),
|
||||
list: None,
|
||||
subject: Some("Your e-mail was not processed successfully.".to_string()),
|
||||
subject: Some(
|
||||
"{{ subject if subject else \"Your e-mail was not processed successfully.\" }}"
|
||||
.to_string(),
|
||||
),
|
||||
headers_json: None,
|
||||
body: "{{ details|safe if details else \"The list owners and administrators have been \
|
||||
notified.\" }}"
|
||||
|
@ -100,7 +103,10 @@ impl Template {
|
|||
pk: -1,
|
||||
name: Self::GENERIC_SUCCESS.to_string(),
|
||||
list: None,
|
||||
subject: Some("Your e-mail was processed successfully.".to_string()),
|
||||
subject: Some(
|
||||
"{{ subject if subject else \"Your e-mail was processed successfully.\" }}"
|
||||
.to_string(),
|
||||
),
|
||||
headers_json: None,
|
||||
body: "{{ details|safe if details else \"\" }}".to_string(),
|
||||
}
|
||||
|
|
|
@ -158,7 +158,7 @@ impl Handler for MyHandler {
|
|||
self.stored.lock().unwrap().push((to.clone(), env));
|
||||
}
|
||||
Err(err) => {
|
||||
eprintln!("envelope parse error {}", err);
|
||||
panic!("envelope parse error {}", err);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -168,8 +168,7 @@ impl Handler for MyHandler {
|
|||
.push(((ip, domain), Message::Helo));
|
||||
return OK;
|
||||
}
|
||||
log::error!("last self.mails item was not Message::Data: {last:?}");
|
||||
INTERNAL_ERROR
|
||||
panic!("last self.mails item was not Message::Data: {last:?}"); //INTERNAL_ERROR
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -313,7 +312,23 @@ fn test_smtp() {
|
|||
.unwrap();
|
||||
}
|
||||
}));
|
||||
assert_eq!(handler.stored.lock().unwrap().len(), 2);
|
||||
let stored = handler.stored.lock().unwrap();
|
||||
assert_eq!(stored.len(), 3);
|
||||
assert_eq!(&stored[0].0, "japoeunp@example.com");
|
||||
assert_eq!(
|
||||
&stored[0].1.subject(),
|
||||
"Your post to foo-chat was rejected."
|
||||
);
|
||||
assert_eq!(
|
||||
&stored[1].1.subject(),
|
||||
"[foo-chat] thankful that I had the chance to written report, that I could learn and let \
|
||||
alone the chance $4454.32"
|
||||
);
|
||||
assert_eq!(
|
||||
&stored[2].1.subject(),
|
||||
"[foo-chat] thankful that I had the chance to written report, that I could learn and let \
|
||||
alone the chance $4454.32"
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
|
Loading…
Reference in New Issue