Пример #1
0
def test_render(certificate, endpoint):
    from lemur.certificates.schemas import certificate_notification_output_schema

    new_cert = CertificateFactory()
    new_cert.replaces.append(certificate)

    certificates = [certificate_notification_output_schema.dump(certificate).data]

    template = env.get_template('{}.html'.format('expiration'))

    with open(os.path.join(dir_path, 'expiration-rendered.html'), 'w') as f:
        body = template.render(dict(certificates=certificates, hostname='lemur.test.example.com'))
        f.write(body)

    template = env.get_template('{}.html'.format('rotation'))

    certificate.endpoints.append(endpoint)

    with open(os.path.join(dir_path, 'rotation-rendered.html'), 'w') as f:
        body = template.render(
            dict(
                certificate=certificate_notification_output_schema.dump(certificate).data,
                hostname='lemur.test.example.com'
            )
        )
        f.write(body)
Пример #2
0
def test_render(certificate, endpoint):
    from lemur.certificates.schemas import certificate_notification_output_schema

    new_cert = CertificateFactory()
    new_cert.replaces.append(certificate)

    data = {
        'certificates': [certificate_notification_output_schema.dump(certificate).data],
        'options': [{'name': 'interval', 'value': 10}, {'name': 'unit', 'value': 'days'}]
    }

    template = env.get_template('{}.html'.format('expiration'))

    with open(os.path.join(dir_path, 'expiration-rendered.html'), 'w') as f:
        body = template.render(dict(message=data, hostname='lemur.test.example.com'))
        f.write(body)

    template = env.get_template('{}.html'.format('rotation'))

    certificate.endpoints.append(endpoint)

    with open(os.path.join(dir_path, 'rotation-rendered.html'), 'w') as f:
        body = template.render(
            dict(
                certificate=certificate_notification_output_schema.dump(certificate).data,
                hostname='lemur.test.example.com'
            )
        )
        f.write(body)
Пример #3
0
def test_render(certificate, endpoint):
    from lemur.certificates.schemas import certificate_notification_output_schema

    new_cert = CertificateFactory()
    new_cert.replaces.append(certificate)

    data = {
        'certificates':
        [certificate_notification_output_schema.dump(certificate).data],
        'options': [{
            'name': 'interval',
            'value': 10
        }, {
            'name': 'unit',
            'value': 'days'
        }]
    }

    template = env.get_template('{}.html'.format('expiration'))

    with open(os.path.join(dir_path, 'expiration-rendered.html'), 'w') as f:
        body = template.render(
            dict(message=data, hostname='lemur.test.example.com'))
        f.write(body)

    template = env.get_template('{}.html'.format('rotation'))

    certificate.endpoints.append(endpoint)

    with open(os.path.join(dir_path, 'rotation-rendered.html'), 'w') as f:
        body = template.render(
            dict(certificate=certificate_notification_output_schema.dump(
                certificate).data,
                 hostname='lemur.test.example.com'))
        f.write(body)
Пример #4
0
def send_expiration_notifications(exclude):
    """
    This function will check for upcoming certificate expiration,
    and send out notification emails at given intervals.
    """
    success = failure = 0

    # security team gets all
    security_email = current_app.config.get('LEMUR_SECURITY_TEAM_EMAIL')

    security_data = []
    for owner, notification_group in get_eligible_certificates(exclude=exclude).items():

        for notification_label, certificates in notification_group.items():
            notification_data = []

            notification = certificates[0][0]

            for data in certificates:
                n, certificate = data
                cert_data = certificate_notification_output_schema.dump(certificate).data
                notification_data.append(cert_data)
                security_data.append(cert_data)

            if send_notification('expiration', notification_data, [owner], notification):
                success += 1
            else:
                failure += 1

            if send_notification('expiration', security_data, security_email, notification):
                success += 1
            else:
                failure += 1

    return success, failure
Пример #5
0
def send_expiration_notifications(exclude):
    """
    This function will check for upcoming certificate expiration,
    and send out notification emails at given intervals.
    """
    success = failure = 0

    # security team gets all
    security_email = current_app.config.get("LEMUR_SECURITY_TEAM_EMAIL")

    security_data = []
    for owner, notification_group in get_eligible_certificates(
            exclude=exclude).items():

        for notification_label, certificates in notification_group.items():
            notification_data = []

            notification = certificates[0][0]

            for data in certificates:
                n, certificate = data
                cert_data = certificate_notification_output_schema.dump(
                    certificate).data
                notification_data.append(cert_data)
                security_data.append(cert_data)

            if send_notification("expiration", notification_data, [owner],
                                 notification):
                success += 1
            else:
                failure += 1

            notification_recipient = get_plugin_option("recipients",
                                                       notification.options)
            if notification_recipient:
                notification_recipient = notification_recipient.split(",")
                # removing owner and security_email from notification_recipient
                notification_recipient = [
                    i for i in notification_recipient
                    if i not in security_email and i != owner
                ]

            if (notification_recipient):
                if send_notification(
                        "expiration",
                        notification_data,
                        notification_recipient,
                        notification,
                ):
                    success += 1
                else:
                    failure += 1

            if send_notification("expiration", security_data, security_email,
                                 notification):
                success += 1
            else:
                failure += 1

    return success, failure
Пример #6
0
def test_render_reissued_with_no_endpoints(certificate):
    new_cert = CertificateFactory()
    new_cert.replaces.append(certificate)

    assert render_html(
        "reissued_with_no_endpoints", get_options(),
        certificate_notification_output_schema.dump(new_cert).data)
Пример #7
0
def test_format_nonexpiration(certificate, endpoint):
    data = [certificate_notification_output_schema.dump(certificate).data]

    for certificate in data:
        expected_message = {
            "notification_type":
            "not-expiration",
            "certificate_name":
            certificate["name"],
            "expires":
            arrow.get(
                certificate["validityEnd"]).format("YYYY-MM-DDTHH:mm:ss"),
            "issuer":
            certificate["issuer"],
            "id":
            certificate["id"],
            "endpoints_detected":
            0,
            "owner":
            certificate["owner"],
            "details":
            "https://lemur.example.com/#/certificates/{name}".format(
                name=certificate["name"])
        }
        # We don't currently support any SNS notifications besides expiration;
        # when we do, this test will probably need to be refactored.
        # For now, this is a placeholder proving empty options works as long as it's not "expiration" type
        assert expected_message == json.loads(
            format_message(certificate, "not-expiration", None))
Пример #8
0
def send_expiring_deployed_certificate_notifications(certificates):
    """
    Send an email to the owner of all provided certificates indicating that the certs are still deployed
    but expiring soon.
    """
    success = failure = 0
    notification_type = "expiring_deployed_certificate"
    security_email = current_app.config.get("LEMUR_SECURITY_TEAM_EMAIL")

    for owner, owner_certs in certificates:
        notification_data = []
        # eventually we also want to use the options configured on the cert's notification(s) to notify the owner
        # for now, we'll just email the security team
        email_recipients = security_email
        for certificate, domains_and_ports in owner_certs:
            cert_data = certificate_notification_output_schema.dump(
                certificate).data
            # we add the domain info into the cert dump in order to reuse existing common email formatting logic
            domain_and_port_data = []
            for domain, ports in domains_and_ports.items():
                domain_and_port_data.append({"domain": domain, "ports": ports})
            cert_data["domains_and_ports"] = domain_and_port_data
            notification_data.append(cert_data)
        if send_default_notification(notification_type, notification_data,
                                     email_recipients):
            success += 1
        else:
            failure += 1

    return success, failure
Пример #9
0
def send_expiration_notifications(exclude, disabled_notification_plugins, disable_security_team_emails=False):
    """
    This function will check for upcoming certificate expiration,
    and send out notification emails at given intervals.
    """
    success = failure = 0

    # security team gets all expiration emails (if enabled)
    security_email = current_app.config.get("LEMUR_SECURITY_TEAM_EMAIL")
    # if disabled, don't explicitly include the security team here
    # note that you will ALSO need to disable the DEFAULT_SECURITY_X_DAY notifications to truly turn these off
    if disable_security_team_emails:
        security_email = []

    for owner, notification_group in get_eligible_certificates(exclude=exclude).items():

        for notification_label, certificates in notification_group.items():
            notification_data = []

            notification = certificates[0][0]

            # skip sending the notification if the plugin is marked as disabled
            if notification.plugin.slug not in disabled_notification_plugins:

                for data in certificates:
                    n, certificate = data
                    cert_data = certificate_notification_output_schema.dump(
                        certificate
                    ).data
                    notification_data.append(cert_data)

                email_recipients = notification.plugin.get_recipients(notification.options, security_email + [owner])
                # Plugin will ONLY use the provided recipients if it's email; any other notification plugin ignores them
                if send_plugin_notification(
                        "expiration", notification_data, email_recipients, notification
                ):
                    success += len(email_recipients)
                else:
                    failure += len(email_recipients)
                # If we're using an email plugin, we're done,
                #   since "security_email + [owner]" were added as email_recipients.
                # If we're not using an email plugin, we also need to send an email to the security team and owner,
                #   since the plugin notification didn't send anything to them.
                if notification.plugin.slug != "email-notification":
                    # If the plugin wasn't email, it only sent one notification, so set the success/failure
                    # to the correct value (1) at this point
                    if success:
                        success, failure = 1, 0
                    else:
                        success, failure = 0, 1
                    # If email-notification plugin is disabled, we won't sent these extra notifications.
                    if "email-notification" not in disabled_notification_plugins:
                        if send_default_notification(
                                "expiration", notification_data, email_recipients, notification.options
                        ):
                            success += len(email_recipients)
                        else:
                            failure += len(email_recipients)

    return success, failure
Пример #10
0
def send_authority_expiration_notifications():
    """
    This function will check for upcoming certificate authority certificate expiration,
    and send out notification emails at configured intervals.
    """
    success = failure = 0

    # security team gets all
    security_email = current_app.config.get("LEMUR_SECURITY_TEAM_EMAIL")

    for owner, owner_cert_groups in get_eligible_authority_certificates().items():
        for interval, certificates in owner_cert_groups.items():
            notification_data = []

            for certificate in certificates:
                cert_data = certificate_notification_output_schema.dump(
                    certificate
                ).data
                cert_data['self_signed'] = is_selfsigned(certificate.parsed_cert)
                cert_data['issued_cert_count'] = certificates_service.get_issued_cert_count_for_authority(certificate.root_authority)
                notification_data.append(cert_data)

            email_recipients = security_email + [owner]
            if send_default_notification(
                    "authority_expiration", notification_data, email_recipients,
                    notification_options=[{'name': 'interval', 'value': interval}]
            ):
                success = len(email_recipients)
            else:
                failure = len(email_recipients)

    return success, failure
Пример #11
0
def test_formatting(certificate):
    from lemur.plugins.lemur_slack.plugin import create_expiration_attachments
    from lemur.certificates.schemas import certificate_notification_output_schema
    data = [certificate_notification_output_schema.dump(certificate).data]

    attachment = {
        'title': certificate.name,
        'color': 'danger',
        'fields': [
            {
                'short': True,
                'value': '*****@*****.**',
                'title': 'Owner'
            },
            {
                'short': True,
                'value': u'Wednesday, January 1, 2020',
                'title': 'Expires'
            }, {
                'short': True,
                'value': 0,
                'title': 'Endpoints Detected'
            }
        ],
        'title_link': 'https://lemur.example.com/#/certificates/{name}'.format(name=certificate.name),
        'mrkdwn_in': ['text'],
        'text': '',
        'fallback': ''
    }

    assert attachment == create_expiration_attachments(data)[0]
Пример #12
0
def send_rotation_notification(certificate, notification_plugin=None):
    """
    Sends a report to certificate owners when their certificate has been
    rotated.

    :param certificate:
    :param notification_plugin:
    :return:
    """
    status = FAILURE_METRIC_STATUS
    if not notification_plugin:
        notification_plugin = plugins.get(current_app.config.get('LEMUR_DEFAULT_NOTIFICATION_PLUGIN'))

    data = certificate_notification_output_schema.dump(certificate).data

    try:
        notification_plugin.send('rotation', data, [data['owner']])
        status = SUCCESS_METRIC_STATUS
    except Exception as e:
        current_app.logger.error('Unable to send notification to {}.'.format(data['owner']), exc_info=True)
        sentry.captureException()

    metrics.send('notification', 'counter', 1, metric_tags={'status': status, 'event_type': 'rotation'})

    if status == SUCCESS_METRIC_STATUS:
        return True
Пример #13
0
def test_render_expiration(certificate, endpoint):
    new_cert = CertificateFactory()
    new_cert.replaces.append(certificate)

    assert render_html(
        "expiration", get_options(),
        [certificate_notification_output_schema.dump(certificate).data])
Пример #14
0
def send_expiration_notifications(exclude):
    """
    This function will check for upcoming certificate expiration,
    and send out notification emails at given intervals.
    """
    success = failure = 0

    # security team gets all
    security_email = current_app.config.get('LEMUR_SECURITY_TEAM_EMAIL')

    security_data = []
    for owner, notification_group in get_eligible_certificates(exclude=exclude).items():

        for notification_label, certificates in notification_group.items():
            notification_data = []

            notification = certificates[0][0]

            for data in certificates:
                n, certificate = data
                cert_data = certificate_notification_output_schema.dump(certificate).data
                notification_data.append(cert_data)
                security_data.append(cert_data)

            if send_notification('expiration', notification_data, [owner], notification):
                success += 1
            else:
                failure += 1

    if send_notification('expiration', security_data, security_email, notification):
        success += 1
    else:
        failure += 1

    return success, failure
Пример #15
0
def send_reissue_no_endpoints_notification(new_cert):
    data = certificate_notification_output_schema.dump(new_cert).data
    data["security_email"] = current_app.config.get(
        "LEMUR_SECURITY_TEAM_EMAIL")
    email_recipients = [data["owner"]] + data["security_email"]
    return send_default_notification("reissued_with_no_endpoints", data,
                                     email_recipients)
Пример #16
0
def send_reissue_no_endpoints_notification(old_cert, new_cert):
    # The notifications should not be able to cause a reissue failure, so surround with a try.
    try:
        # Endpoints get moved from old to new cert during rotation, so the new cert won't have endpoints yet;
        # instead, we have to check the old cert for endpoints.
        if not old_cert.endpoints:
            excluded_destinations = current_app.config.get(
                "LEMUR_REISSUE_NOTIFICATION_EXCLUDED_DESTINATIONS", [])
            has_excluded_destination = excluded_destinations and old_cert.destinations and \
                [d for d in old_cert.destinations if d.label in excluded_destinations]
            if not has_excluded_destination:
                data = certificate_notification_output_schema.dump(
                    new_cert).data
                data["security_email"] = current_app.config.get(
                    "LEMUR_SECURITY_TEAM_EMAIL")
                email_recipients = [data["owner"]] + data["security_email"]
                email_tags = {
                    "old_cert_id": old_cert.id,
                    "new_cert_id": new_cert.id,
                    "new_cert_name": new_cert.name,
                    "new_cert_owner": new_cert.owner
                }
                return send_default_notification("reissued_with_no_endpoints",
                                                 data,
                                                 email_recipients,
                                                 email_tags=email_tags)
    except Exception:
        current_app.logger.warn(
            f"Error sending reissue notification for certificate: {old_cert.name}",
            exc_info=True)
Пример #17
0
def test_format_expiration(certificate, endpoint):
    data = [certificate_notification_output_schema.dump(certificate).data]
    options = get_options()

    for certificate in data:
        expected_message = {
            "notification_type":
            "expiration",
            "certificate_name":
            certificate["name"],
            "expires":
            arrow.get(
                certificate["validityEnd"]).format("YYYY-MM-DDTHH:mm:ss"),
            "issuer":
            certificate["issuer"],
            "id":
            certificate["id"],
            "endpoints_detected":
            0,
            "owner":
            certificate["owner"],
            "details":
            "https://lemur.example.com/#/certificates/{name}".format(
                name=certificate["name"]),
            "notification_interval_days":
            10  # 10 days specified in options
        }
        assert expected_message == json.loads(
            format_message(certificate, "expiration", options))
Пример #18
0
def test_send_expiration_notification():
    from lemur.notifications.messaging import send_expiration_notifications

    verify_sender_email(
    )  # emails are sent to owner and security; SNS only used for configured notification
    topic_arn, sqs_client, queue_url = create_and_subscribe_to_topic()

    notification = NotificationFactory(plugin_name="aws-sns")
    notification.options = get_options()

    now = arrow.utcnow()
    in_ten_days = now + timedelta(
        days=10,
        hours=1)  # a bit more than 10 days since we'll check in the future

    certificate = CertificateFactory()
    certificate.not_after = in_ten_days
    certificate.notifications.append(notification)

    assert send_expiration_notifications([],
                                         []) == (3, 0
                                                 )  # owner, SNS, and security

    received_messages = sqs_client.receive_message(
        QueueUrl=queue_url)["Messages"]
    assert len(received_messages) == 1
    expected_message = format_message(
        certificate_notification_output_schema.dump(certificate).data,
        "expiration", notification.options)
    actual_message = json.loads(received_messages[0]["Body"])["Message"]
    assert actual_message == expected_message
Пример #19
0
def send_rotation_notification(certificate, notification_plugin=None):
    """
    Sends a report to certificate owners when their certificate has been
    rotated.

    :param certificate:
    :param notification_plugin:
    :return:
    """
    status = FAILURE_METRIC_STATUS
    if not notification_plugin:
        notification_plugin = plugins.get(
            current_app.config.get('LEMUR_DEFAULT_NOTIFICATION_PLUGIN'))

    data = certificate_notification_output_schema.dump(certificate).data

    try:
        notification_plugin.send('rotation', data, [data['owner']])
        status = SUCCESS_METRIC_STATUS
    except Exception as e:
        sentry.captureException()

    metrics.send('notification',
                 'counter',
                 1,
                 metric_tags={
                     'status': status,
                     'event_type': 'rotation'
                 })

    if status == SUCCESS_METRIC_STATUS:
        return True
Пример #20
0
def test_formatting(certificate):
    from lemur.plugins.lemur_slack.plugin import create_expiration_attachments
    from lemur.certificates.schemas import certificate_notification_output_schema
    data = [certificate_notification_output_schema.dump(certificate).data]

    attachment = {
        'title': certificate.name,
        'color': 'danger',
        'fields': [
            {
                'short': True,
                'value': '*****@*****.**',
                'title': 'Owner'
            },
            {
                'short': True,
                'value': u'Tuesday, December 31, 2047',
                'title': 'Expires'
            }, {
                'short': True,
                'value': 0,
                'title': 'Endpoints Detected'
            }
        ],
        'title_link': 'https://lemur.example.com/#/certificates/{name}'.format(name=certificate.name),
        'mrkdwn_in': ['text'],
        'text': '',
        'fallback': ''
    }

    assert attachment == create_expiration_attachments(data)[0]
Пример #21
0
def send_expiration_notifications():
    """
    This function will check for upcoming certificate expiration,
    and send out notification emails at given intervals.
    """
    sent = 0
    for plugin in plugins.all(plugin_type='notification'):
        notifications = database.db.session.query(Notification)\
            .filter(Notification.plugin_name == plugin.slug)\
            .filter(Notification.active == True).all()  # noqa

        messages = []
        for n in notifications:
            for certificate in n.certificates:
                if needs_notification(certificate):
                    data = certificate_notification_output_schema.dump(
                        certificate).data
                    messages.append((data, n.options))

        for data, options in messages:
            try:
                plugin.send('expiration', data, [data['owner']], options)
                metrics.send('expiration_notification_sent', 'counter', 1)
                sent += 1
            except Exception as e:
                metrics.send('expiration_notification_failure', 'counter', 1)
                current_app.logger.exception(e)
    return sent
Пример #22
0
def test_render_expiring_deployed_certificate(certificate):
    verify_sender_email()

    cert_data = certificate_notification_output_schema.dump(certificate).data
    cert_data['domains_and_ports'] = [{'domain': 'subdomain.example.com', 'ports': [443]},
                                      {'domain': 'example.com', 'ports': [443, 444]}]

    assert render_html("expiring_deployed_certificate", get_options(), [cert_data])
Пример #23
0
def test_render_rotation(certificate, endpoint):
    new_cert = CertificateFactory()
    new_cert.replaces.append(certificate)
    new_cert.endpoints.append(endpoint)

    assert render_html(
        "rotation", get_options(),
        certificate_notification_output_schema.dump(new_cert).data)
Пример #24
0
def send_reissue_failed_notification(certificate):
    try:
        data = certificate_notification_output_schema.dump(certificate).data
        data["security_email"] = current_app.config.get("LEMUR_SECURITY_TEAM_EMAIL")
        email_recipients = [data["owner"]] + data["security_email"]
        return send_default_notification("reissue_failed", data, email_recipients)
    except Exception:
        current_app.logger.warn(
            f"Error sending reissue failed notification for certificate: {certificate.name}", exc_info=True
        )
Пример #25
0
def send_security_expiration_summary(exclude=None):
    """
    Sends a report to the security team with a summary of all expiring certificates.
    All expiring certificates are included here, regardless of notification configuration.
    Certificates with notifications disabled are omitted.

    :param exclude:
    :return:
    """
    function = f"{__name__}.{sys._getframe().f_code.co_name}"
    status = FAILURE_METRIC_STATUS
    notification_plugin = plugins.get(
        current_app.config.get("LEMUR_DEFAULT_NOTIFICATION_PLUGIN", "email-notification")
    )
    notification_type = "expiration_summary"
    log_data = {
        "function": function,
        "message": "Sending expiration summary notification for to security team",
        "notification_type": notification_type,
        "notification_plugin": notification_plugin.slug,
    }

    intervals_and_certs = get_eligible_security_summary_certs(exclude)
    security_email = current_app.config.get("LEMUR_SECURITY_TEAM_EMAIL")

    try:
        current_app.logger.debug(log_data)

        message_data = []

        for interval, certs in intervals_and_certs.items():
            cert_data = []
            for certificate in certs:
                cert_data.append(certificate_notification_output_schema.dump(certificate).data)
            interval_data = {"interval": interval, "certificates": cert_data}
            message_data.append(interval_data)

        notification_plugin.send(notification_type, message_data, security_email, None)
        status = SUCCESS_METRIC_STATUS
    except Exception:
        log_data["message"] = f"Unable to send {notification_type} notification for certificates " \
                              f"{intervals_and_certs} to targets {security_email}"
        current_app.logger.error(log_data, exc_info=True)
        sentry.captureException()

    metrics.send(
        "notification",
        "counter",
        1,
        metric_tags={"status": status, "event_type": notification_type, "plugin": notification_plugin.slug},
    )

    if status == SUCCESS_METRIC_STATUS:
        return True
Пример #26
0
def send_rotation_notification(certificate):
    data = certificate_notification_output_schema.dump(certificate).data
    data["security_email"] = current_app.config.get(
        "LEMUR_SECURITY_TEAM_EMAIL")
    email_tags = {
        "cert_id": certificate.id,
        "cert_name": certificate.name,
        "owner": certificate.owner
    }
    return send_default_notification("rotation",
                                     data, [data["owner"]],
                                     email_tags=email_tags)
Пример #27
0
def test_send_expiration_notification_email_disabled():
    from lemur.notifications.messaging import send_expiration_notifications

    topic_arn, sqs_client, queue_url = create_and_subscribe_to_topic()
    notification, certificate = prepare_test()

    assert send_expiration_notifications([], ['email-notification']) == (1, 0)  # SNS only

    received_messages = sqs_client.receive_message(QueueUrl=queue_url)["Messages"]
    assert len(received_messages) == 1
    expected_message = format_message(certificate_notification_output_schema.dump(certificate).data, "expiration",
                                      notification.options)
    actual_message = json.loads(received_messages[0]["Body"])["Message"]
    assert actual_message == expected_message
Пример #28
0
def get_eligible_security_summary_certs(exclude=None):
    message_data = []
    all_certs = get_certificates_for_security_summary_email(exclude=exclude)
    now = arrow.utcnow()

    # group by expiration interval
    for interval, interval_certs in groupby(sorted(all_certs, key=lambda x: (x.not_after - now).days),
                                            lambda x: (x.not_after - now).days):
        cert_data = []
        for certificate in interval_certs:
            cert_data.append(certificate_notification_output_schema.dump(certificate).data)
        interval_data = {"interval": interval, "certificates": cert_data}
        message_data.append(interval_data)

    return message_data
Пример #29
0
def test_render(certificate, endpoint):
    from lemur.certificates.schemas import certificate_notification_output_schema

    new_cert = CertificateFactory()
    new_cert.replaces.append(certificate)

    data = {
        "certificates":
        [certificate_notification_output_schema.dump(certificate).data],
        "options": [
            {
                "name": "interval",
                "value": 10
            },
            {
                "name": "unit",
                "value": "days"
            },
        ],
    }

    template = env.get_template("{}.html".format("expiration"))

    body = template.render(
        dict(message=data, hostname="lemur.test.example.com"))

    template = env.get_template("{}.html".format("rotation"))

    certificate.endpoints.append(endpoint)

    body = template.render(
        dict(
            certificate=certificate_notification_output_schema.dump(
                certificate).data,
            hostname="lemur.test.example.com",
        ))
Пример #30
0
def test_publish(certificate, endpoint):
    data = [certificate_notification_output_schema.dump(certificate).data]

    topic_arn, sqs_client, queue_url = create_and_subscribe_to_topic()

    message_ids = publish(topic_arn, data, "expiration", get_options(), region_name="us-east-1")
    assert len(message_ids) == len(data)
    received_messages = sqs_client.receive_message(QueueUrl=queue_url)["Messages"]

    for certificate in data:
        expected_message_id = message_ids[certificate["name"]]
        actual_message = next(
            (m for m in received_messages if json.loads(m["Body"])["MessageId"] == expected_message_id), None)
        actual_json = json.loads(actual_message["Body"])
        assert actual_json["Message"] == format_message(certificate, "expiration", get_options())
        assert actual_json["Subject"] == "Lemur: Expiration Notification"
Пример #31
0
def send_expiration_notifications(exclude):
    """
    This function will check for upcoming certificate expiration,
    and send out notification emails at given intervals.
    """
    success = failure = 0

    # security team gets all
    security_email = current_app.config.get("LEMUR_SECURITY_TEAM_EMAIL")

    for owner, notification_group in get_eligible_certificates(exclude=exclude).items():

        for notification_label, certificates in notification_group.items():
            notification_data = []

            notification = certificates[0][0]

            for data in certificates:
                n, certificate = data
                cert_data = certificate_notification_output_schema.dump(
                    certificate
                ).data
                notification_data.append(cert_data)

            email_recipients = notification.plugin.get_recipients(notification.options, security_email + [owner])
            # Plugin will ONLY use the provided recipients if it's email; any other notification plugin ignores them
            if send_plugin_notification(
                    "expiration", notification_data, email_recipients, notification
            ):
                success += len(email_recipients)
            else:
                failure += len(email_recipients)
            # If we're using an email plugin, we're done,
            #   since "security_email + [owner]" were added as email_recipients.
            # If we're not using an email plugin, we also need to send an email to the security team and owner,
            #   since the plugin notification didn't send anything to them.
            if notification.plugin.slug != "email-notification":
                if send_default_notification(
                        "expiration", notification_data, email_recipients, notification.options
                ):
                    success = 1 + len(email_recipients)
                else:
                    failure = 1 + len(email_recipients)

    return success, failure
Пример #32
0
def send_rotation_notification(certificate, notification_plugin=None):
    """
    Sends a report to certificate owners when their certificate has been
    rotated.

    :param certificate:
    :param notification_plugin:
    :return:
    """
    function = f"{__name__}.{sys._getframe().f_code.co_name}"
    log_data = {
        "function": function,
        "message": f"Sending rotation notification for certificate {certificate.name}",
        "notification_type": "rotation",
        "certificate_name": certificate.name,
        "certificate_owner": certificate.owner,
    }
    status = FAILURE_METRIC_STATUS
    if not notification_plugin:
        notification_plugin = plugins.get(
            current_app.config.get("LEMUR_DEFAULT_NOTIFICATION_PLUGIN", "email-notification")
        )

    data = certificate_notification_output_schema.dump(certificate).data

    try:
        notification_plugin.send("rotation", data, [data["owner"]], [])
        status = SUCCESS_METRIC_STATUS
    except Exception as e:
        log_data["message"] = f"Unable to send rotation notification for certificate {certificate.name} " \
                              f"to owner {data['owner']}"
        current_app.logger.error(log_data, exc_info=True)
        sentry.captureException()

    metrics.send(
        "notification",
        "counter",
        1,
        metric_tags={"status": status, "event_type": "rotation"},
    )

    if status == SUCCESS_METRIC_STATUS:
        return True
Пример #33
0
def send_rotation_notification(certificate, notification_plugin=None):
    """
    Sends a report to certificate owners when their certificate as been
    rotated.

    :param certificate:
    :return:
    """
    if not notification_plugin:
        notification_plugin = plugins.get(current_app.config.get('LEMUR_DEFAULT_NOTIFICATION_PLUGIN'))

    data = certificate_notification_output_schema.dump(certificate).data

    try:
        notification_plugin.send('rotation', data, [data['owner']])
        metrics.send('rotation_notification_sent', 'counter', 1)
        return True
    except Exception as e:
        metrics.send('rotation_notification_failure', 'counter', 1)
        current_app.logger.exception(e)
Пример #34
0
def send_rotation_notification(certificate, notification_plugin=None):
    """
    Sends a report to certificate owners when their certificate as been
    rotated.

    :param certificate:
    :return:
    """
    if not notification_plugin:
        notification_plugin = plugins.get(current_app.config.get('LEMUR_DEFAULT_NOTIFICATION_PLUGIN'))

    data = certificate_notification_output_schema.dump(certificate).data

    try:
        notification_plugin.send('rotation', data, [data['owner']])
        metrics.send('rotation_notification_sent', 'counter', 1)
        return True
    except Exception as e:
        sentry.captureException()
        metrics.send('rotation_notification_failure', 'counter', 1)
        current_app.logger.exception(e)
Пример #35
0
def test_formatting(certificate):
    from lemur.plugins.lemur_slack.plugin import create_expiration_attachments
    from lemur.certificates.schemas import certificate_notification_output_schema

    data = [certificate_notification_output_schema.dump(certificate).data]

    attachment = {
        "title":
        certificate.name,
        "color":
        "danger",
        "fields": [
            {
                "short": True,
                "value": "*****@*****.**",
                "title": "Owner"
            },
            {
                "short": True,
                "value": u"Tuesday, December 31, 2047",
                "title": "Expires"
            },
            {
                "short": True,
                "value": 0,
                "title": "Endpoints Detected"
            },
        ],
        "title_link":
        "https://lemur.example.com/#/certificates/{name}".format(
            name=certificate.name),
        "mrkdwn_in": ["text"],
        "text":
        "",
        "fallback":
        "",
    }

    assert attachment == create_expiration_attachments(data)[0]