diff --git a/RewriteGALAddressesToSMTP.py b/RewriteGALAddressesToSMTP.py index 66c74b9..2013617 100644 --- a/RewriteGALAddressesToSMTP.py +++ b/RewriteGALAddressesToSMTP.py @@ -1,5 +1,6 @@ # kopano-dagent RewriteGALAddressesToSMTP # (c) 2017 Hein-Pieter van Braam +# (C) 2020 Christoph Haas # Licensed under the GPU Affero GPL v3 (or at your option any later version) # See LICENSE file for details @@ -16,37 +17,75 @@ class RewriteGALAddressesToSMTP(IMapiDAgentPlugin): def __init__(self, logger): IMapiDAgentPlugin.__init__(self, logger) - def DecodeHeaderToUTF8(self, header): - decodedHeader = decode_header(header) - headerText, headerEncoding = decodedHeader[0] - if headerEncoding is None: - return unicode(headerText) - else: - return unicode(headerText, headerEncoding, 'ignore') + def DecodeHeaderToUTF8(self, header) -> str: + decodedHeaderParts = decode_header(header) + strHeader = "" + for headerText, headerEncoding in decodedHeaderParts: + if headerEncoding is None: + if isinstance(headerText, str): + strHeader += headerText # already a string + else: + strHeader += headerText.decode('ASCII') + else: + strHeader += headerText.decode(headerEncoding) + return strHeader + + def GetKopanoRecipient(self, emailAddr: bytes, kopanoRecipients: list) -> list: + for rcpt in kopanoRecipients: + if SPropValue(PR_EMAIL_ADDRESS, emailAddr) in rcpt: + return rcpt + return None + + # PreDelivery hook entry point def PreDelivery(self, session, addrbook, store, folder, message): + # Load headers and extract To: and CC: headers headers = message.GetProps([PR_TRANSPORT_MESSAGE_HEADERS], 0)[0].Value - msg = email.message_from_string(headers) + msg = email.message_from_bytes(headers) to_addrs = getaddresses(msg.get_all('to', [])) cc_addrs = getaddresses(msg.get_all('cc', [])) - + + # First load all original recipients for the message + orig_to_addrs = [] + orig_cc_addrs = [] + rcptTable = message.GetRecipientTable(0) + #rcptTable.SetColumns([PR_EMAIL_ADDRESS, PR_ADDRTYPE], 0) # no specific columns means: load all columns + origRcpts = rcptTable.QueryRows(10, 0) + while origRcpts and len(origRcpts) > 0: + for origRcpt in origRcpts: + if SPropValue(PR_RECIPIENT_TYPE, MAPI_TO) in origRcpt: + orig_to_addrs.append(origRcpt) + if SPropValue(PR_RECIPIENT_TYPE, MAPI_CC) in origRcpt: + orig_cc_addrs.append(origRcpt) + origRcpts = rcptTable.QueryRows(10, 0) # Read the next 10 recipients + + + # Now replace alias addresses with the SMTP address type names = [] for addr in to_addrs: - names.append([ - SPropValue(PR_RECIPIENT_TYPE, MAPI_TO), - SPropValue(PR_DISPLAY_NAME_W, self.DecodeHeaderToUTF8(addr[0])), - SPropValue(PR_ADDRTYPE, 'SMTP'), - SPropValue(PR_EMAIL_ADDRESS, unicode(addr[1])), - ]) - - for addr in cc_addrs: - names.append([ - SPropValue(PR_RECIPIENT_TYPE, MAPI_CC), - SPropValue(PR_DISPLAY_NAME_W, self.DecodeHeaderToUTF8(addr[0])), - SPropValue(PR_ADDRTYPE, 'SMTP'), - SPropValue(PR_EMAIL_ADDRESS, unicode(addr[1])), - ]) - - message.ModifyRecipients(0, names) - return MP_CONTINUE, + kopanoRcpt = self.GetKopanoRecipient(bytes(addr[1], encoding='utf8'), orig_to_addrs) + if kopanoRcpt is not None: + names.append(kopanoRcpt) # keep original To: entry + else: + names.append([ + SPropValue(PR_RECIPIENT_TYPE, MAPI_TO), + SPropValue(PR_DISPLAY_NAME, bytes(self.DecodeHeaderToUTF8(addr[0]), encoding="utf8")), + SPropValue(PR_ADDRTYPE, bytes('SMTP', encoding="utf8")), + SPropValue(PR_EMAIL_ADDRESS, bytes(addr[1], encoding='utf8')), + ]) + for addr in cc_addrs: + kopanoRcpt = self.GetKopanoRecipient(bytes(addr[1], encoding='utf8'), orig_cc_addrs) + if kopanoRcpt is not None: + names.append(kopanoRcpt) # keep original CC: entry + else: + names.append([ + SPropValue(PR_RECIPIENT_TYPE, MAPI_CC), + SPropValue(PR_DISPLAY_NAME, bytes(self.DecodeHeaderToUTF8(addr[0]), encoding="utf8")), + SPropValue(PR_ADDRTYPE, bytes('SMTP', encoding="utf8")), + SPropValue(PR_EMAIL_ADDRESS, bytes(addr[1], encoding='utf8')), + ]) + + if len(names) > 0: # double check, avoid empty recipients + message.ModifyRecipients(0, names) + return MP_CONTINUE, \ No newline at end of file