示例#1
0
import base64
import binascii
import functools
import re

import prometheus_client
import requests
from cryptography import x509
from cryptography.exceptions import InvalidSignature
from cryptography.hazmat.primitives.asymmetric.padding import PKCS1v15
from cryptography.hazmat.primitives.hashes import SHA1
from cryptography.x509 import Certificate

from sns_email import logger

_logger = logger.getChild("sns.signature")

_valid_sns_url = re.compile(r"^https://sns\.[-a-z0-9]+\.amazonaws\.com/")

_certificate_time = prometheus_client.Histogram(
    'sns_email_sns_signature_certificate_seconds',
    'Time spent loading certificate')
_signature_time = prometheus_client.Histogram(
    'sns_email_sns_signature_seconds', 'Time spent computing signature')
_verify_time = prometheus_client.Histogram('sns_email_sns_verify_seconds',
                                           'Time spent verifying signature')


class InvalidSnsSignatureException(Exception):
    pass
示例#2
0
#!/usr/bin/env python
import json
import threading
import time

import prometheus_client

from sns_email import boto_session, _counter_errors, logger
from sns_email.receive import MessageReceiver

_logger = logger.getChild('sqs')

_counter_sqs_poll = prometheus_client.Counter('sns_email_sqs_poll_total',
                                              'SQS poll total')
_counter_sqs = prometheus_client.Counter('sns_email_sqs_received_total',
                                         'SQS received total')


class SqsPoller:
    def __init__(self, receiver: MessageReceiver, queue_url: str, region: str):
        self.receiver = receiver
        self.queue_url = queue_url
        self.region = region

        self.poll_wait_empty = 10 * 60
        self.poll_wait = 10

        self._close = threading.Event()

    def close(self):
        _logger.info("closing.")
示例#3
0
文件: sns.py 项目: fogninid/sns-email
#!/usr/bin/env python
import json
from http import HTTPStatus
from http.server import BaseHTTPRequestHandler, HTTPServer
from typing import Tuple

import prometheus_client

from sns_email import logger, _counter_errors
from sns_email.receive import MessageReceiver
from sns_email.sns_signature import sns_verify_signature, InvalidSnsSignatureException

_logger = logger.getChild('sns')

_counter_sns = prometheus_client.Counter('sns_email_sns_received_total', 'SNS received total')
_counter_sns_time = prometheus_client.Histogram('sns_email_sns_handle_seconds', 'SNS HTTP handle time')


class SnsHandler(BaseHTTPRequestHandler):
    receiver: MessageReceiver = None

    @_counter_sns_time.time()
    def do_POST(self):
        content_length = int(self.headers['Content-Length'])
        try:
            content_bytes = self.rfile.read(content_length)
            _logger.debug("processing message. headers=%s, content=%s", self.headers, content_bytes)
            try:
                body = json.loads(content_bytes)
                sns_verify_signature(body)
            except json.decoder.JSONDecodeError:
示例#4
0
#!/usr/bin/env python
import json
import re

import prometheus_client

import sns_email.deliver
from sns_email import logger, _counter_errors
from sns_email.counter import count

_receive_time = prometheus_client.Histogram('sns_email_receive_seconds', 'Time spent processing receive')

_logger = logger.getChild('receive')


class MessageReceiver:
    def __init__(self, rex=re.compile(".*"), deliver=sns_email.deliver.sendmail_deliver,
                 boto_session=sns_email.boto_session):
        self.deliver = deliver
        self.boto_session = boto_session
        self.rex = rex

    @_receive_time.time()
    def receive_mail(self, message):
        mail = message['mail']

        message_id = mail['messageId']
        with count(message_id) as dup_check:
            if dup_check:
                _logger.info("ignoring duplicate message that was fully processed. message_id=%s", message_id)
                return
示例#5
0
#!/usr/bin/env python
import subprocess

import prometheus_client

from sns_email import logger

_logger = logger.getChild('deliver')

_counter_received = prometheus_client.Counter('sns_email_received_total', 'Received total')


class sendmail_deliver:
    def __init__(self, source, recipients, sendmail_path="/usr/bin/sendmail"):
        self.p = subprocess.Popen([sendmail_path, "-r", source, "-i"] + recipients,
                                  stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
        self.recipients = recipients

    def __enter__(self):
        return self.p.stdin

    def __exit__(self, exc_type, exc_value, exc_traceback):
        if exc_value:
            _logger.info("exception during delivery, aborting process.")
            try:
                self.p.kill()
            except:
                _logger.warning("failed aborting delivery process.", exc_info=True)
            return
        try:
            outs, errs = self.p.communicate(timeout=15)