RewriteGALAddressesToSMTP.py 3.8 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091
  1. # kopano-dagent RewriteGALAddressesToSMTP
  2. # (c) 2017 Hein-Pieter van Braam <hp@tmm.cx>
  3. # (C) 2020 Christoph Haas <christoph.h@sprinternet.at>
  4. # Licensed under the GPU Affero GPL v3 (or at your option any later version)
  5. # See LICENSE file for details
  6. import MAPI
  7. import email
  8. from email.utils import getaddresses
  9. from email.header import decode_header
  10. from MAPI.Util import *
  11. from plugintemplates import *
  12. class RewriteGALAddressesToSMTP(IMapiDAgentPlugin):
  13. def __init__(self, logger):
  14. IMapiDAgentPlugin.__init__(self, logger)
  15. def DecodeHeaderToUTF8(self, header) -> str:
  16. decodedHeaderParts = decode_header(header)
  17. strHeader = ""
  18. for headerText, headerEncoding in decodedHeaderParts:
  19. if headerEncoding is None:
  20. if isinstance(headerText, str):
  21. strHeader += headerText # already a string
  22. else:
  23. strHeader += headerText.decode('ASCII')
  24. else:
  25. strHeader += headerText.decode(headerEncoding)
  26. return strHeader
  27. def GetKopanoRecipient(self, emailAddr: bytes, kopanoRecipients: list) -> list:
  28. for rcpt in kopanoRecipients:
  29. if SPropValue(PR_EMAIL_ADDRESS, emailAddr) in rcpt:
  30. return rcpt
  31. return None
  32. # PreDelivery hook entry point
  33. def PreDelivery(self, session, addrbook, store, folder, message):
  34. # Load headers and extract To: and CC: headers
  35. headers = message.GetProps([PR_TRANSPORT_MESSAGE_HEADERS], 0)[0].Value
  36. msg = email.message_from_bytes(headers)
  37. to_addrs = getaddresses(msg.get_all('to', []))
  38. cc_addrs = getaddresses(msg.get_all('cc', []))
  39. # First load all original recipients for the message
  40. orig_to_addrs = []
  41. orig_cc_addrs = []
  42. rcptTable = message.GetRecipientTable(0)
  43. #rcptTable.SetColumns([PR_EMAIL_ADDRESS, PR_ADDRTYPE], 0) # no specific columns means: load all columns
  44. origRcpts = rcptTable.QueryRows(10, 0)
  45. while origRcpts and len(origRcpts) > 0:
  46. for origRcpt in origRcpts:
  47. if SPropValue(PR_RECIPIENT_TYPE, MAPI_TO) in origRcpt:
  48. orig_to_addrs.append(origRcpt)
  49. if SPropValue(PR_RECIPIENT_TYPE, MAPI_CC) in origRcpt:
  50. orig_cc_addrs.append(origRcpt)
  51. origRcpts = rcptTable.QueryRows(10, 0) # Read the next 10 recipients
  52. # Now replace alias addresses with the SMTP address type
  53. names = []
  54. for addr in to_addrs:
  55. kopanoRcpt = self.GetKopanoRecipient(bytes(addr[1], encoding='utf8'), orig_to_addrs)
  56. if kopanoRcpt is not None:
  57. names.append(kopanoRcpt) # keep original To: entry
  58. else:
  59. names.append([
  60. SPropValue(PR_RECIPIENT_TYPE, MAPI_TO),
  61. SPropValue(PR_DISPLAY_NAME, bytes(self.DecodeHeaderToUTF8(addr[0]), encoding="utf8")),
  62. SPropValue(PR_ADDRTYPE, bytes('SMTP', encoding="utf8")),
  63. SPropValue(PR_EMAIL_ADDRESS, bytes(addr[1], encoding='utf8')),
  64. ])
  65. for addr in cc_addrs:
  66. kopanoRcpt = self.GetKopanoRecipient(bytes(addr[1], encoding='utf8'), orig_cc_addrs)
  67. if kopanoRcpt is not None:
  68. names.append(kopanoRcpt) # keep original CC: entry
  69. else:
  70. names.append([
  71. SPropValue(PR_RECIPIENT_TYPE, MAPI_CC),
  72. SPropValue(PR_DISPLAY_NAME, bytes(self.DecodeHeaderToUTF8(addr[0]), encoding="utf8")),
  73. SPropValue(PR_ADDRTYPE, bytes('SMTP', encoding="utf8")),
  74. SPropValue(PR_EMAIL_ADDRESS, bytes(addr[1], encoding='utf8')),
  75. ])
  76. if len(names) > 0: # double check, avoid empty recipients
  77. message.ModifyRecipients(0, names)
  78. return MP_CONTINUE,