Exemplo n.º 1
0
def process(message, sent_to_address=None):
    """
    Handles the dispatching of received messages.

    :param message: The received message
    :type message: ``bytes``

    :param sent_to_address: The address to which the message was sent.
        Necessary in order to determine which package it was sent to.
    """
    assert isinstance(message, six.binary_type), "Message must be given as bytes"
    msg = message_from_bytes(message)

    if sent_to_address is None:
        # No MTA was recognized, the last resort is to try and use the message
        # To header.
        sent_to_address = extract_email_address_from_header(msg["To"])

    if sent_to_address.startswith("bounces+"):
        return handle_bounces(sent_to_address)

    local_part = sent_to_address.split("@")[0]

    # Extract package name
    package_name = get_package_name(local_part)
    # Check loop
    package_email = "{package}@{pts_fqdn}".format(package=package_name, pts_fqdn=PTS_FQDN)
    if package_email in msg.get_all("X-Loop", ()):
        # Bad X-Loop, discard the message
        logger.info("Bad X-Loop, message discarded")
        return

    # Extract keyword
    keyword = get_keyword(local_part, msg)
    # Default keywords require special approvement
    if keyword == "default" and not approved_default(msg):
        logger.info("Discarding default keyword message")
        return

    # Now send the message to subscribers
    add_new_headers(msg, package_name, keyword)
    send_to_subscribers(msg, package_name, keyword)
    send_to_teams(msg, package_name, keyword)
Exemplo n.º 2
0
def process(message):
    """
    The function which actually processes a received command email message.

    :param message: The received command email message.
    :type message: ``bytes``
    """
    assert isinstance(message, six.binary_type), 'Message must be given as bytes'
    msg = message_from_bytes(message)
    # msg = message_from_string(message)
    if 'X-Loop' in msg and PTS_CONTROL_EMAIL in msg.get_all('X-Loop'):
        return
    # Get the first plain-text part of the message
    plain_text_part = next(typed_subpart_iterator(msg, 'text', 'plain'), None)
    if not plain_text_part:
        # There is no plain text in the email
        send_plain_text_warning(msg)
        return

    # Decode the plain text into a unicode string
    try:
        text = get_decoded_message_payload(plain_text_part)
    except UnicodeDecodeError:
        send_plain_text_warning(msg)
        return

    lines = extract_command_from_subject(msg) + text.splitlines()
    # Process the commands
    factory = CommandFactory({
        'email': extract_email_address_from_header(msg['From']),
    })
    confirmation_set = ConfirmationSet()
    processor = CommandProcessor(factory)
    processor.confirmation_set = confirmation_set
    processor.process(lines)

    confirmation_set.ask_confirmation_all()
    # Send a response only if there were some commands processed
    if processor.is_success():
        send_response(
            msg, processor.get_output(), set(confirmation_set.get_emails()))