# 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 import MAPI import email from email.utils import getaddresses from email.header import decode_header from MAPI.Util import * from plugintemplates import * class RewriteGALAddressesToSMTP(IMapiDAgentPlugin): def __init__(self, logger): IMapiDAgentPlugin.__init__(self, logger) 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_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: 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,