diff --git a/lemur/notifications/messaging.py b/lemur/notifications/messaging.py index ddf8d875..cd88ebc8 100644 --- a/lemur/notifications/messaging.py +++ b/lemur/notifications/messaging.py @@ -8,24 +8,21 @@ .. moduleauthor:: Kevin Glisson """ -from itertools import groupby from collections import defaultdict +from datetime import timedelta +from itertools import groupby import arrow -from datetime import timedelta from flask import current_app - from sqlalchemy import and_ from lemur import database +from lemur.certificates.models import Certificate +from lemur.certificates.schemas import certificate_notification_output_schema +from lemur.common.utils import windowed_query from lemur.constants import FAILURE_METRIC_STATUS, SUCCESS_METRIC_STATUS from lemur.extensions import metrics, sentry -from lemur.common.utils import windowed_query - -from lemur.certificates.schemas import certificate_notification_output_schema -from lemur.certificates.models import Certificate from lemur.pending_certificates.schemas import pending_certificate_output_schema - from lemur.plugins import plugins from lemur.plugins.utils import get_plugin_option @@ -74,10 +71,11 @@ def get_eligible_certificates(exclude=None): notification_groups = [] for certificate in items: - notification = needs_notification(certificate) + notifications = needs_notification(certificate) - if notification: - notification_groups.append((notification, certificate)) + if notifications: + for notification in notifications: + notification_groups.append((notification, certificate)) # group by notification for notification, items in groupby(notification_groups, lambda x: x[0].label): @@ -133,11 +131,21 @@ def send_expiration_notifications(exclude): notification_data.append(cert_data) security_data.append(cert_data) + notification_recipient = get_plugin_option('recipients', notification.options) + if notification_recipient: + notification_recipient = notification_recipient.split(",") + if send_notification('expiration', notification_data, [owner], notification): success += 1 else: failure += 1 + if notification_recipient and owner != notification_recipient and security_email != 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: @@ -228,6 +236,8 @@ def needs_notification(certificate): now = arrow.utcnow() days = (certificate.not_after - now).days + notifications = [] + for notification in certificate.notifications: if not notification.active or not notification.options: return @@ -248,4 +258,5 @@ def needs_notification(certificate): raise Exception("Invalid base unit for expiration interval: {0}".format(unit)) if days == interval: - return notification + notifications.append(notification) + return notifications diff --git a/requirements-dev.txt b/requirements-dev.txt index 599a1af9..d74b07f9 100644 --- a/requirements-dev.txt +++ b/requirements-dev.txt @@ -7,7 +7,7 @@ aspy.yaml==1.1.1 # via pre-commit bleach==3.0.2 # via readme-renderer cached-property==1.5.1 # via pre-commit -certifi==2018.10.15 # via requests +certifi==2018.11.29 # via requests cfgv==1.1.0 # via pre-commit chardet==3.0.4 # via requests docutils==0.14 # via readme-renderer diff --git a/requirements-docs.txt b/requirements-docs.txt index a9c7a979..35ca4322 100644 --- a/requirements-docs.txt +++ b/requirements-docs.txt @@ -76,7 +76,7 @@ python-editor==1.0.3 pytz==2018.7 pyyaml==3.13 raven[flask]==6.9.0 -redis==3.0.1 +redis==2.10.6 requests-toolbelt==0.8.0 requests[security]==2.20.1 retrying==1.3.3 diff --git a/requirements-tests.txt b/requirements-tests.txt index 72dcbbdb..e328b38a 100644 --- a/requirements-tests.txt +++ b/requirements-tests.txt @@ -8,17 +8,17 @@ asn1crypto==0.24.0 # via cryptography atomicwrites==1.2.1 # via pytest attrs==18.2.0 # via pytest aws-xray-sdk==0.95 # via moto -boto3==1.9.53 # via moto +boto3==1.9.60 # via moto boto==2.49.0 # via moto -botocore==1.12.53 # via boto3, moto, s3transfer -certifi==2018.10.15 # via requests +botocore==1.12.60 # via boto3, moto, s3transfer +certifi==2018.11.29 # via requests cffi==1.11.5 # via cryptography chardet==3.0.4 # via requests click==7.0 # via flask coverage==4.5.2 cryptography==2.4.2 # via moto -docker-pycreds==0.3.0 # via docker -docker==3.5.1 # via moto +docker-pycreds==0.4.0 # via docker +docker==3.6.0 # via moto docutils==0.14 # via botocore ecdsa==0.13 # via python-jose factory-boy==2.11.1 diff --git a/requirements.txt b/requirements.txt index c881799e..fadcfe4b 100644 --- a/requirements.txt +++ b/requirements.txt @@ -4,7 +4,7 @@ # # pip-compile --no-index --output-file requirements.txt requirements.in # -acme==0.28.0 +acme==0.29.1 alembic-autogenerate-enums==0.0.2 alembic==1.0.5 # via flask-migrate amqp==2.3.2 # via kombu @@ -13,12 +13,12 @@ arrow==0.12.1 asn1crypto==0.24.0 # via cryptography asyncpool==1.0 bcrypt==3.1.4 # via flask-bcrypt, paramiko -billiard==3.5.0.4 # via celery +billiard==3.5.0.5 # via celery blinker==1.4 # via flask-mail, flask-principal, raven -boto3==1.9.53 -botocore==1.12.53 +boto3==1.9.60 +botocore==1.12.60 celery[redis]==4.2.1 -certifi==2018.10.15 +certifi==2018.11.29 cffi==1.11.5 # via bcrypt, cryptography, pynacl chardet==3.0.4 # via requests click==7.0 # via flask @@ -46,7 +46,7 @@ jinja2==2.10 jmespath==0.9.3 # via boto3, botocore josepy==1.1.0 # via acme jsonlines==1.2.0 # via cloudflare -kombu==4.2.1 # via celery +kombu==4.2.2 # via celery lockfile==0.12.2 mako==1.0.7 # via alembic markupsafe==1.1.0 # via jinja2, mako @@ -61,7 +61,7 @@ psycopg2==2.7.6.1 pyasn1-modules==0.2.2 # via python-ldap pyasn1==0.4.4 # via ndg-httpsclient, paramiko, pyasn1-modules, python-ldap pycparser==2.19 # via cffi -pyjwt==1.6.4 +pyjwt==1.7.0 pynacl==1.3.0 # via paramiko pyopenssl==18.0.0 pyrfc3339==1.1 # via acme @@ -77,7 +77,7 @@ requests[security]==2.20.1 retrying==1.3.3 s3transfer==0.1.13 # via boto3 six==1.11.0 -sqlalchemy-utils==0.33.8 +sqlalchemy-utils==0.33.9 sqlalchemy==1.2.14 # via alembic, flask-sqlalchemy, marshmallow-sqlalchemy, sqlalchemy-utils tabulate==0.8.2 urllib3==1.24.1 # via botocore, requests