|
|
@ -1,5 +1,6 @@ |
|
|
|
# kopano-dagent RewriteGALAddressesToSMTP |
|
|
|
# (c) 2017 Hein-Pieter van Braam <hp@tmm.cx> |
|
|
|
# (C) 2020 Christoph Haas <christoph.h@sprinternet.at> |
|
|
|
# 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])), |
|
|
|
]) |
|
|
|
|
|
|
|
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: |
|
|
|
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_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, |