Как запретить Gmail удалять встроенные изображения по соображениям безопасности? - PullRequest
0 голосов
/ 28 апреля 2018

Я создал приложение электронной почты для отправки всех файлов .png, найденных в папке, как показано ниже:

import httplib2
import os

from apiclient import discovery
from oauth2client import client
from oauth2client import tools
from oauth2client.file import Storage
from email.mime.text import MIMEText
from email.mime.image import MIMEImage
from email.mime.multipart import MIMEMultipart
import base64
import glob
import uuid
import html
import json

try:
    import argparse
    flags = argparse.ArgumentParser(parents=[tools.argparser]).parse_args()
except ImportError:
    flags = None

# If modifying these scopes, delete your previously saved credentials
# at ~/.credentials/gmail-python-quickstart.json
SCOPES = 'https://www.googleapis.com/auth/gmail.send'
CLIENT_SECRET_FILE = 'json/gmail_secrets.json'
APPLICATION_NAME = 'APP NAME GOES HERE'


def get_credentials():
    """Gets valid user credentials from storage.

    If nothing has been stored, or if the stored credentials are invalid,
    the OAuth2 flow is completed to obtain the new credentials.

    Returns:
        Credentials, the obtained credential.
    """
    credential_dir = '.credentials'
    if not os.path.exists(credential_dir):
        os.makedirs(credential_dir)
    credential_path = os.path.join(credential_dir, 'email-sender.json')

    store = Storage(credential_path)
    credentials = store.get()
    if not credentials or credentials.invalid:
        flow = client.flow_from_clientsecrets(CLIENT_SECRET_FILE, SCOPES)
        flow.user_agent = APPLICATION_NAME
        if flags:
            credentials = tools.run_flow(flow, store, flags)
        else: # Needed only for compatibility with Python 2.6
            credentials = tools.run(flow, store)
    return credentials


# Function to read all images in a folder and send them inline
def create_inline_images_message(log, img_dir, sender, to, subject):
    # Read all image filenames
    img_files = glob.glob(os.path.join(img_dir, '*.png'))

    # Holds MIME formatted images
    msg_images = []

    html_body = u'<h1>Latest Performance Reports</h1>'
    for i_f in img_files:
        img_dict = dict(title = 'Image', path = i_f, cid = str(uuid.uuid4()))

        html_body += u'<div dir="ltr"><img src="cid:{cid}" alt="{alt}"><br></div>'.format(alt=html.escape(img_dict['title'], quote=True), **img_dict)

        msg_images.append(attach_image(img_dict))

    # Base version of message
    msg = MIMEMultipart('related')
    msg['Subject'] = subject
    msg['From'] = sender
    msg['To'] = to

    # Create message
    msg_alternative = MIMEMultipart('alternative')      # Message with plain and html alternatives

    # Plaintext (non-HTML) version of the email
    msg_text = MIMEText(u'Image not working - maybe next time', 'plain', 'utf-8')
    msg_alternative.attach(msg_text)

    # HTML version of email
    msg_html = MIMEText(html_body, 'html', 'utf-8')
    msg_alternative.attach(msg_html)

    # Now add images
    for m_i in msg_images:
        msg_alternative.attach(m_i)

    # Attached alternative to original
    msg.attach(msg_alternative)

    return {'raw': base64.urlsafe_b64encode(msg.as_string().encode()).decode()} 


# Function to return formatted image
def attach_image(img_dict):
    with open(img_dict['path'], 'rb') as file:
        msg_image = MIMEImage(file.read(), name = os.path.basename(img_dict['path']))
        msg_image.add_header('Content-ID', '<{}>'.format(img_dict['cid']))
    return msg_image


# Send a gmail message, user_id = 'me' means the currently authenticated user, service is authenticated Gmail instance
def send_message(service, user_id, message):
    try:
        message = (service.users().messages().send(userId=user_id, body=message).execute())
        return message
    except:
        print('An error occurred')


# Read in all metadata used to drive the script
def load_manifest(): 
    return json.load(open('manifest.json'))


# Main code
def main():
    # Load manifest
    manifest = load_manifest()

    # Use the saved credentials file to authenticate and create authenticated service
    credentials = get_credentials()
    http = credentials.authorize(httplib2.Http())
    service = discovery.build('gmail', 'v1', http=http)

    # Create and read log
    log = []

    # Get email addresses
    sender = manifest['globals']['email_sender']
    to = ','.join(manifest['globals']['email_recipients'])

    # Get folders and rename them to prevent race condition then send emails
    all_folders = os.listdir(manifest['globals']['reports_location'])
    eligible_folders = [f for f in all_folders if not f[-5:] in ['_dump', '_work', '_sent']]
    for f in eligible_folders:
        orig_folder_location = os.path.join(manifest['globals']['reports_location'], f)
        working_folder_location = os.path.join(manifest['globals']['reports_location'], f + '_work')
        finished_folder_location = os.path.join(manifest['globals']['reports_location'], f + '_sent')

        os.rename(orig_folder_location, working_folder_location)

        subject = 'Daily Report {}'.format(f)
        message = create_inline_images_message(log, working_folder_location, sender, to, subject)

        sent_message = send_message(service, 'me', message)

        os.rename(working_folder_location, finished_folder_location)

main()

Это работает отлично, и если я аутентифицируюсь как учетная запись пользователя (например, user1@gmail.com) и использую их для отправки электронного письма, когда я захожу в их почтовый ящик Gmail, появляется сообщение, и изображения встроены в линию. Однако, если я использую user1@gmail.com для отправки в другую учетную запись (например, user2@gmail.com), когда я захожу в их почтовый ящик, изображения не отображаются.

В папке входящих сообщений пользователя user2, если я проверяю заполнитель изображения, тег img удаляет src. Я также заметил, что если перейти к Show Original, в верхней части экрана появятся категории SPF, DKIM и DMARC.

Если я вручную пересылаю сообщение от user1 к user2, изображения отображаются как обычно, но если я установил правило автоматической пересылки для user1 для автоматической пересылки сообщения пользователю user2, тогда изображения снова удаляются.

Я могу только предположить, что это какая-то «функция» безопасности, которая мешает пользователю2 видеть изображения; Из входящей почты user1 я знаю, что формат электронной почты правильный.

Как разрешить не отправляющему пользователю просматривать изображения?

...