acs_mail_lite::inbound_email_context (private)

 acs_mail_lite::inbound_email_context \
    [ -header_array_name header_array_name ] \
    [ -header_name_list header_name_list ]

Defined in packages/acs-mail-lite/tcl/email-inbound-procs.tcl

Returns openacs data associated with original outbound email in the header_array_name and as an ordered list of values: package_id, party_id, object_id, other, datetime_cs datetime_cs is the time in seconds since Tcl epoch. other can be most any data represented in SQL text. By accessing all email headers, various scenarios of OpenACS sender and replies can be checked to increase likelihood of retrieving data in context of email. Array indexes have suffix aml_ added to index name: aml_package_id, aml_party_id, aml_object_id, aml_other, aml_datetime_cs If a value is not found, an empty string is returned for the value.

Switches:
-header_array_name
(optional)
-header_name_list
(optional)
See Also:

Partial Call Graph (max 5 caller/called nodes):
%3 acs_mail_lite::imap_check_incoming acs_mail_lite::imap_check_incoming (private) acs_mail_lite::inbound_email_context acs_mail_lite::inbound_email_context acs_mail_lite::imap_check_incoming->acs_mail_lite::inbound_email_context acs_mail_lite::maildir_check_incoming acs_mail_lite::maildir_check_incoming (private) acs_mail_lite::maildir_check_incoming->acs_mail_lite::inbound_email_context acs_mail_lite::bounce_prefix acs_mail_lite::bounce_prefix (private) acs_mail_lite::inbound_email_context->acs_mail_lite::bounce_prefix acs_mail_lite::unique_id_parse acs_mail_lite::unique_id_parse (private) acs_mail_lite::inbound_email_context->acs_mail_lite::unique_id_parse

Testcases:
No testcase defined.
Source code:
    upvar 1 $header_array_name h_arr
    if { $header_name_list eq "" } {
        set header_name_list [array names h_arr]
    }

    # Here are some procs that help create a message-id or originator
    # or generated unique ids from inbound email headers
    # that are of historical importance in helping
    # shape this proc.
    #    acs_mail_lite::unique_id_create (current)
    #    acs_mail_lite::unique_id_parse (current)
    #    acs_mail_lite::generate_message_id
    #    acs_mail_lite::bounce_address
    #    acs_mail_lite::parse_bounce_address
    #    notification::email::reply_address_prefix
    #    notification::email::reply_address
    #    notification::email::address_domain
    #    notification::email::send
    #    acs_mail_lite::send
    #    mime::uniqueID
    #    acs_mail_lite::send_immediately



    # This proc should be capable of integrating with MailDir based service
    # whether as a legacy support or current choice (instead of IMAP).



    # Note for imap paradigm: message-id should be in form:
    # <unique_id@local_domain.example>
    # and unique_id should map to
    # any package, party and/or object_id so
    # as to not leak info unnecessarily.
    # See table acs_mail_lite_send_msg_id_map
    # and acs_mail_lite::unique_id_create/find/parse


    # Bounce info needs to be placed in an RFC
    # compliant header. Replies can take many forms.
    # This could be a mess.
    # If a service using MailDir switches to use IMAP,
    # should we still try to make the MailDir work?
    # Should this work with MailDir regardless of IMAP?
    # Yes and yes.
    # This should be as generic as possible and include legacy permutations.

    # General constraints:
    # Header field characters limited to US-ASCII characters between 33 and 126
    # inclusive per RFC 5322 2.2 https://tools.ietf.org/html/rfc5322#section-2.2
    # and white-space characters 32 and 9.

    # Per RFC 6532 3.3 and 5322 2.1.1, "Each line of characters must be no more
    # than 998 characters, and should be no more than 78 characters.."
    # A domain name can take up to 253 characters.

    # Setting aside about 60 characters for a signature for a signed message-id
    # should be okay even though it almost guarantees all cases of message_id
    # will be over 78 characters.

    # Unique references are case sensitive per RFC 3464 2.2.1
    # original email's envelope-id value is case sensitive per RFC 3464 2.2.1
    # Angle brackets are used to quote a unique reference


    # According to RFCs,
    # these are the headers to check in a reply indicating original context:

    # original-message-id
    # original-envelope-id
    # message-id            a unique message id per RFC 2822 3.6.4
    #                       assigned by originator per RFC 598 3.4.1
    #                        https://tools.ietf.org/html/rfc5598#section-3.4.1
    #
    # originator            A special case alternate to 'From' header.
    #                       Usually, defined by first SMTP MTA.
    #                       Notices may be sent to this address when
    #                       a bounce notice to the original email's 'From'
    #                       address bounces.
    #                       See RFC 5321 2.3.1
    #                        https://tools.ietf.org/html/rfc5321#section-2.3.1
    #                       and RFC 5598 2.2.1
    #                        https://tools.ietf.org/html/rfc5598#section-2.1
    # msg-id
    # In-Reply-to  space delimited list of unique message ids per RFC 2822 3.6.4
    # References   space delimited list of unique message ids per RFC 2822 3.6.4
    #
    # original-recipient    may contain original 'to' address of party_id
    # original-recipient-address
    #                       is an alternate to original-recipient
    #                       used by RFC 3461 4.2
    #                        https://tools.ietf.org/html/rfc3461#section-4.2
    #                      Recipient could be used as an extra layer
    #                       of authentication after parsing.
    #                      for example
    #                       'from' header is built as:
    #                        party::email -party-id user_id
    #                        in page: forums/www/message-email.tcl
    #

    # check_list should be prioritized to most likely casees first.
    set check_list [list  original-message-id  original-envelope-id  originator  message-id  msg-id  in-reply-to  references  ]
    #
    #
    #
    # existing oacs-5-9 'MailDir' ways to show context or authenticate origin:
    #


    # acs-mail-lite::send_immediately
    # 'from' header defaults to acs_mail_lite parameter FixedSenderEmail
    # 'Reply-to' defaults to 'from' header value.
    # adds a different unique id to 'Return-Path'.
    # example: <bounce-lite-49020-5AA3B467C31BBE655281220B0583195B52956B70-2578@openacs.org>
    # address is built using acs_mail_lite::bounce_address
    # Parsing is done with:
    # acs_mail_lite::parse_bounce_address /acs_mail_lite::parse_email_address/
    # in callback acs_mail_lite::incoming_email -impl acs-mail-lite
    # message-id
    # Content-ID
    # adds same unique id to 'message-id' and 'content-id'.
    # example: <17445.1479806245.127@openacs.wu-wien.ac.at.wu-wien.ac.at>

    # Content-ID is added by proc:  ad_build_mime_message
    # which relies on tcllib mime package
    # in file acs-tcl/tcl/html-email-procs.tcl
    # message-id is built by acs_mail_lite::generate_message_id
    #                     or mime::uniqueID
    #              and used in acs_mail_lite::send_immediately

    # acs_mail_lite::generate_message_id:
    #     return "/clock clicks/./ns_time/.oacs@/address_domain/>"
    # mime::uniqueID:
    #     return "</pid/./clock seconds/./incr mime(cid)/@/info hostname/>"
    #     is defined in ns/lib/tcllib1.18/mime/mime.tcl
    #     mime(cid) is a counter that increments by one each time called.

    lappend check_list content-id


    # To make acs_mail_lite_send_msg_id_map more robust,
    # should it be designed to import other references via a table map
    # so external references can be used?   No.

    # Replaced generic use of mime::uniqueID
    # with acs_mail_lite::unique_id_create
    # Don't assume acs_mail_lite::valid_signature works. It appears to check
    # an unknown form and is orphaned (not used).


    #
    # Notifications package
    #
    # reply-to
    # Mail-Followup-To
    # parameter NotificationSender defaults to
    #     remainder@ acs_mail_lite::address_domain
    # which defaults to:
    #   remainder@ parameter BounceDomain
    #   if set, otherwise to a driver hostname
    # which..
    # adds the same unique id to 'reply-to' and 'mail-followup-to'

    # message-id is a way to generate a dynamic reply-to.

    # example: "openacs.org mailer" <notification-5342759-2960@openacs.org>
    # apparently built in notification::email::send
    # located in file notifications/tcl/notification-email-procs.tcl
    # reply_to built by calling local notification::email::reply_address
    # where:
    # if $object_id or $type_id is empty string:
    #" /address_domain/ mailer  #    </reply_address_prefix/@/address_domain/>"
    # else
    # "/address_domain/ mailer  #    </reply_address_prefix/-$object_id-$type_id@/address_domain/>"
    # where address_domain gets notifications package parameter EmailDomain
    # and defaults to domain from ad_url
    # and where reply_address_prefix gets
    # notifications package parameter EmailReplyAddressPrefix
    # Mail-Followup-To is set to same value, then calls acs_mail_lite::send

    lappend check_list mail-followup-to

    # Contribute x-envelope-from from legacy case in
    # acs_mail_lite::bounce_prefix?
    # No. It's only referenced in a proc doc comment.
    # lappend check_list x-envelope-from


    #
    # A legacy parameter from acs_mail_lite::parse_bounce_address
    #
    set bounce_prefix [acs_mail_lite::bounce_prefix]
    set regexp_str "\[${bounce_prefix}\]-(\[0-9\]+)-(\[^-\]+)-(\[0-9\]*)\@"

    #
    # setup for loop that checks headers
    #

    set context_list [list ]
    set check_list_len [llength $check_list]
    set header_id 0
    set prefix "aml_"
    set h_arr(aml_datetime_cs) ""

    # Check headers for signed context
    while { $header_id < $check_list_len && $h_arr(aml_datetime_cs) eq "" } {
        set header [lindex $check_list $header_id]
        set h_idx [lsearch -exact -nocase $header_name_list $header]
        if { $h_idx > -1 } {
            set h_name [lindex $check_list $h_idx]

            # hv = header value
            if { $header eq "references" } {
                # references header may contain multiple message-ids
                set hv_list [split $h_arr(${h_name}) ]
            } else {
                # header has one vale
                set hv_list [list $h_arr(${h_name})]
            }
            set hv_list_len [llength $hv_list]
            set hv_i 0
            while { $hv_i < $hv_list_len && $h_arr(aml_datetime_cs) eq "" } {
                set hv [lindex $hv_list $hv_i]
                # remove quoting angle brackets if any
                if { [string match "<*>" $hv ] } {
                    set hv [string range $hv 1 end-1]
                }
                set context_list [acs_mail_lite::unique_id_parse  -message_id $hv]
                if { $h_arr(aml_datetime_cs) eq ""
                     && [string match "${bounce_addrs}*" $hv]
                 } {

                    ##code developers of OpenACS core:
                    # Legacy case should be removed for strict, secure
                    # handling of context info

                    # Check legacy case
                    # Regexp code is from acs_mail_lite::parse_bounce_address
                    if { [regexp $regexp_str $hv all user_id signature package_id] } {
                        set context_list [list  package_id $package_id  party_id $user_id  object_id ""  other "" ]
                        set sig_list [split $signature "."]
                        set sig_1 [lindex $sig_list 1]
                        if { [llength $sig_list ] == 3
                             && [string is wideinteger -strict $sig_1]
                         } {
                            lappend context_list datetime_cs $sig_1
                        } else {
                            lappend context_list datetime_cs [clock seconds]
                        }
                    }
                }
                # prefix = "aml_" as in cname becomes:
                #  aml_package_id aml_party_id aml_object_id aml_other aml_datetime_cs
                foreach {n v} $context_list {
                    set cname $prefix
                    append cname $n
                    set h_arr(${cname}$v
                }

                incr hv_i
            }
        }

        incr header_id
    }

    return $context_list
XQL Not present:
PostgreSQL, Oracle
Generic XQL file:
packages/acs-mail-lite/tcl/email-inbound-procs.xql

[ hide source ] | [ make this the default ]
Show another procedure: