Support for dynamic envelope sender addresses

Hi All,

I’m trying to get RT to do something fairly complex with envelope
senders for an extension: I want to encode the transaction ID and the
recipient address with VERP, and I want to use different VERP domains
for privileged and unprivileged users. Something like this:

 priv'd:    rt+11758-privileged=example.com@authmail.example.com
 unpriv'd:  rt+11758-unprivileged=example.com@mail.example.com

First, it looks like RT’s existing VERP support in v4.4.1 using the
VERPPrefix and VERPDomain config values encodes the sender (the
transaction creator), not the recipient, in the generated VERP address.
That doesn’t seem particularly useful for the original purpose of VERP,
that being to make it easy to discover the recipient address affected by
a bounce message. It’s understandable, though, since generating VERP
addresses per-recipient requires that one can never send messages with
more than one recipient.

That’s not really an issue for me since I can use the VERP support in
Postfix (via the -XV sendmail flag) to split up multiple-recipient
messages and generate proper VERP senders. I mostly mention it to
explain why I’m not using the built-in VERP support.

Since I’m planning to use Postfix to generate the actual VERP addresses,
I just need RT to generate envelope senders like this:

 priv'd:    rt+11758@authmail.example.com
 unpriv'd:  rt+11758@mail.example.com

I see two other methods that could be used to set the envelope sender:
SetOutgoingMailFrom plus OverrideOutgoingMailFrom, or setting the
-f flag directly in SendmailArguments. Neither appears to support
CODE refs or any other mechanism for dynamically setting the envelope
sender usable to include the transaction ID. I therefore assume that
I’ll need to patch RT::Interface::Email::SendEmail().

Is it likely that a patch to add a callback capable of setting the
envelope sender in RT::Interface::Email::SendEmail() would be accepted
upstream?

Should such a callback be passed a reference to the array of sendmail
arguments so it can modify them as desired or should it be expected to
return an envelope sender address?

Thanks for your consideration,
Sam Hanes


Is it likely that a patch to add a callback capable of setting the
envelope sender in RT::Interface::Email::SendEmail() would be
accepted upstream?

Should such a callback be passed a reference to the array of sendmail
arguments so it can modify them as desired or should it be expected to
return an envelope sender address?

On looking deeper into the callback mechanism I’m used to I see it’s
Mason-specific. Is there another callback pattern already used in RT for
use in library code like RT::Interface::Email?

Sam Hanes

Hi All,

Hey Sam,

Is it likely that a patch to add a callback capable of setting the
envelope sender in RT::Interface::Email::SendEmail() would be accepted
upstream?

Yeah, we’d happily take such a patch. As you discovered, callbacks are Mason-specific, so can’t be used for this. The way we make library code customizable is by factoring out a small, well-defined method, which a local overlay can then redefine.

A useful technique for this is to take a reference to the original sub reference before redefining it, and then calling it within the redefinition (which works a lot like a subclass dispatching to the superclass’s method). For an example of prior art, see https://github.com/bestpractical/rt-extension-onetimeto/blob/a0da9368643/lib/RT/Extension/OneTimeTo.pm#L83-L97

Should such a callback be passed a reference to the array of sendmail
arguments so it can modify them as desired or should it be expected to
return an envelope sender address?

A method that returns the list of sendmail arguments might be the best fit.

Thanks for your consideration,
Sam Hanes

Thanks,
Shawn

signature.asc (801 Bytes)

Is it likely that a patch to add a callback capable of setting the
envelope sender in RT::Interface::Email::SendEmail() would be accepted
upstream?

Yeah, we’d happily take such a patch. As you discovered, callbacks
are Mason-specific, so can’t be used for this. The way we make
library code customizable is by factoring out a small, well-defined
method, which a local overlay can then redefine.

Should such a callback be passed a reference to the array of sendmail
arguments so it can modify them as desired or should it be expected to
return an envelope sender address?

A method that returns the list of sendmail arguments might be the best fit.

I did eventually put together a patch to add that hook:

That was months ago (Jul 31), but I didn’t submit it at the time because
I hadn’t figured out how to write tests for it yet, and then I had a few
months where I was too busy to work on it. In the intervening time, this
pull request was submitted and merged to 4.2-trunk:

That adds something akin to the functionality I need, and it conflicts
with my patch. Unfortunately it doesn’t quite work for me: I need the
TransactionObj in addition to the TicketObj to do the address mangling I
want, and it only provides the TicketObj. I therefore still need to
submit a change of some kind in order for my use-case to work. Also, I’m
on 4.4.1 and it hasn’t been merged up to 4.4-trunk or master yet.

How should I deal with the conflict?

I see a few paths:

  • Abandon altogether the idea of messing with sendmail arguments.
    Merge the _OutgoingMailFrom patch up to 4.4-trunk or master, then
    land a further patch to pass TransactionObj and the other
    SendEmail parameters to that method.

  • Amend my SendmailArguments patch to also provide the _OutgoingMailFrom
    method, then land it on 4.4-trunk or master. There are two ways I
    could handle the _OutgoingMailFrom method:

    • have _OutgoingMailFrom return undef by default, then add it to the
      sender address fallback chain introduced by my patch at a priority
      lower than SendmailArguments but above OverrideOutgoingMailFrom

    • have _OutgoingMailFrom take over the OverrideOutgoingMailFrom
      section of the fallback chain as it does in the original patch

  • Land my SendmailArguments patch as-is on 4.4-trunk or master and just
    drop the _OutgoingMailFrom method as SendmailArguments provides a
    strict superset of its functionality.

Please let me know how to proceed so I can update my patch as necessary,
add tests, and submit it properly.

Thanks,
Sam Hanes