Sending a password protected file over exchangelib

405 Views Asked by At

I need to send a daily email with an excel file that must be password protected. I have been using exchangelib for my email needs so far. I would prefer not to switch / add a different library if possible.

sending emails with attachments has not been a problem, just figuring out how to password protect and send. I thought I got close with this solution, compressing and sending as a zip file, but can't seem to attach the zip archive, just the contents.

from exchangelib import Message, Account, FileAttachment
from pyminizip import compress

m = Message(
    account=Account(...),
    subject="Some Subject",
    to_recipients=['[email protected]']
)

xl_file_path = 'temp.xlsx'
zip_archive = 'secure.zip'
password = 'HomerSimpson'

compress(
    xl_file_path,
    None,
    zip_archive,
    password,
    5
)

with open(zip_archive, 'wb') as f:
    zip_archive_content = f.read()

m.attach(FileAttachment(
    name=zip_archive,
    content=zip_archive_content
))

m.send()

When this gets sent, it is actually sending the original excel file. To prove it to myself, when the attachment is downloaded and given a ".xlsx" extension instead of ".zip" it opens right up.

I am aware that there is password protection in the openpyxl library, but that is a weak protection (does not encrypt). My understanding is that the compress function is actually encrypting the data - which is what I want.

My hope is that I am just missing something simple about sending a zip archive as an attachment, but would accept other alternatives to password protecting the file or if there really is no other option - switching to a different method for sending emails.

Thoughts?

Edit

I did verify that the secure.zip archive is in the same directory as this script and does work correctly when opening manually (i.e. it contains my Excel file and is password protected).

1

There are 1 best solutions below

0
On

Thank you Erik in the comments. Setting content_type='application/zip' in the FileAttachment is what I needed.

m.attach(FileAttachment(
    name=name,
    content=content,
    content_type='application/zip',
))