From d00dd9d2956b7a4f28339712344810092600ec65 Mon Sep 17 00:00:00 2001 From: Mathias Petermann Date: Tue, 29 Sep 2020 14:29:23 +0200 Subject: [PATCH 001/314] Initial structure for ACME http challenge --- lemur/plugins/lemur_acme/plugin.py | 94 +++++++++++++++++++++++++++++- setup.py | 1 + 2 files changed, 94 insertions(+), 1 deletion(-) diff --git a/lemur/plugins/lemur_acme/plugin.py b/lemur/plugins/lemur_acme/plugin.py index 8bc1485f..d1c86017 100644 --- a/lemur/plugins/lemur_acme/plugin.py +++ b/lemur/plugins/lemur_acme/plugin.py @@ -26,6 +26,7 @@ from flask import current_app from lemur.authorizations import service as authorization_service from lemur.common.utils import generate_private_key +from lemur.destinations import service as destination_service from lemur.dns_providers import service as dns_provider_service from lemur.exceptions import InvalidAuthority, InvalidConfiguration, UnknownProvider from lemur.extensions import metrics, sentry @@ -436,7 +437,7 @@ class ACMEIssuerPlugin(IssuerPlugin): title = "Acme" slug = "acme-issuer" description = ( - "Enables the creation of certificates via ACME CAs (including Let's Encrypt)" + "Enables the creation of certificates via ACME CAs (including Let's Encrypt), using the DNS-01 challenge" ) version = acme.VERSION @@ -746,3 +747,94 @@ class ACMEIssuerPlugin(IssuerPlugin): def cancel_ordered_certificate(self, pending_cert, **kwargs): # Needed to override issuer function. pass + + +class ACMEHttpIssuerPlugin(IssuerPlugin): + title = "Acme HTTP-01" + slug = "acme-http-issuer" + description = ( + "Enables the creation of certificates via ACME CAs (including Let's Encrypt), using the HTTP-01 challenge" + ) + version = acme.VERSION + + author = "Netflix" + author_url = "https://github.com/netflix/lemur.git" + + destination_list = [] + + options = [ + { + "name": "acme_url", + "type": "str", + "required": True, + "validation": "/^http[s]?://(?:[a-zA-Z]|[0-9]|[$-_@.&+]|[!*\(\),]|(?:%[0-9a-fA-F][0-9a-fA-F]))+$/", + "helpMessage": "Must be a valid web url starting with http[s]://", + }, + { + "name": "telephone", + "type": "str", + "default": "", + "helpMessage": "Telephone to use", + }, + { + "name": "email", + "type": "str", + "default": "", + "validation": "/^?([-a-zA-Z0-9.`?{}]+@\w+\.\w+)$/", + "helpMessage": "Email to use", + }, + { + "name": "certificate", + "type": "textarea", + "default": "", + "validation": "/^-----BEGIN CERTIFICATE-----/", + "helpMessage": "Certificate to use", + }, + { + "name": "tokenDestination", + "type": "select", + "required": True, + "available": destination_list, + "helpMessage": "The destination to use to deploy the token.", + }, + ] + + def __init__(self, *args, **kwargs): + super(ACMEHttpIssuerPlugin, self).__init__(*args, **kwargs) + + if len(self.destination_list) == 0: + destinations = destination_service.get_all() + for destination in destinations: + # we only want to use sftp destinations here + if destination.plugin_name == "sftp-destination": + self.destination_list.append(destination.label) + + def create_certificate(self, csr, issuer_options): + pass + + @staticmethod + def create_authority(options): + """ + Creates an authority, this authority is then used by Lemur to allow a user + to specify which Certificate Authority they want to sign their certificate. + + :param options: + :return: + """ + role = {"username": "", "password": "", "name": "acme"} + plugin_options = options.get("plugin", {}).get("plugin_options") + if not plugin_options: + error = "Invalid options for lemur_acme plugin: {}".format(options) + current_app.logger.error(error) + raise InvalidConfiguration(error) + # Define static acme_root based off configuration variable by default. However, if user has passed a + # certificate, use this certificate as the root. + acme_root = current_app.config.get("ACME_ROOT") + for option in plugin_options: + if option.get("name") == "certificate": + acme_root = option.get("value") + return acme_root, "", [role] + + def cancel_ordered_certificate(self, pending_cert, **kwargs): + # Needed to override issuer function. + pass \ No newline at end of file diff --git a/setup.py b/setup.py index 4da14c3d..7fcbc101 100644 --- a/setup.py +++ b/setup.py @@ -132,6 +132,7 @@ setup( 'lemur.plugins': [ 'verisign_issuer = lemur.plugins.lemur_verisign.plugin:VerisignIssuerPlugin', 'acme_issuer = lemur.plugins.lemur_acme.plugin:ACMEIssuerPlugin', + 'acme_http_issuer = lemur.plugins.lemur_acme.plugin:ACMEHttpIssuerPlugin', 'aws_destination = lemur.plugins.lemur_aws.plugin:AWSDestinationPlugin', 'aws_source = lemur.plugins.lemur_aws.plugin:AWSSourcePlugin', 'aws_s3 = lemur.plugins.lemur_aws.plugin:S3DestinationPlugin', From 348d8477dd3303fe400d0d2eca46cc845a5f1818 Mon Sep 17 00:00:00 2001 From: Mathias Petermann Date: Tue, 29 Sep 2020 14:57:32 +0200 Subject: [PATCH 002/314] Refactor destination plugin, to allow upload of ACME http-challenge tokens --- lemur/plugins/lemur_sftp/plugin.py | 57 +++++++++++++++++++----------- 1 file changed, 36 insertions(+), 21 deletions(-) diff --git a/lemur/plugins/lemur_sftp/plugin.py b/lemur/plugins/lemur_sftp/plugin.py index 66784048..7c4e93c4 100644 --- a/lemur/plugins/lemur_sftp/plugin.py +++ b/lemur/plugins/lemur_sftp/plugin.py @@ -16,6 +16,7 @@ .. moduleauthor:: Dmitry Zykov https://github.com/DmitryZykov """ +from os import path import paramiko @@ -95,18 +96,14 @@ class SFTPDestinationPlugin(DestinationPlugin): }, ] + # this is called when using this as a default destination plugin def upload(self, name, body, private_key, cert_chain, options, **kwargs): current_app.logger.debug("SFTP destination plugin is started") cn = common_name(parse_certificate(body)) - host = self.get_option("host", options) - port = self.get_option("port", options) - user = self.get_option("user", options) - password = self.get_option("password", options) - ssh_priv_key = self.get_option("privateKeyPath", options) - ssh_priv_key_pass = self.get_option("privateKeyPass", options) dst_path = self.get_option("destinationPath", options) + dst_path_cn = dst_path + "/" + cn export_format = self.get_option("exportFormat", options) # prepare files for upload @@ -121,6 +118,31 @@ class SFTPDestinationPlugin(DestinationPlugin): # store chain in the separate file files[cn + ".ca.bundle.pem"] = cert_chain + self.upload_file(dst_path_cn, files, options) + + # this is called from the acme http challenge + def upload_acme_token(self, token, thumbprint, options, **kwargs): + + current_app.logger.debug("SFTP destination plugin is started for HTTP-01 challenge") + + dst_path = self.get_option("destinationPath", options) + dst_path = path.join(dst_path, "/.well-known/acme-challenge/") + + # prepare files for upload + files = {token: thumbprint} + + self.upload_file(dst_path, files, options) + + # here the file is uploaded for real, this helps to keep this class DRY + def upload_file(self, dst_path, files, options): + + host = self.get_option("host", options) + port = self.get_option("port", options) + user = self.get_option("user", options) + password = self.get_option("password", options) + ssh_priv_key = self.get_option("privateKeyPath", options) + ssh_priv_key_pass = self.get_option("privateKeyPass", options) + # upload files try: current_app.logger.debug( @@ -156,33 +178,26 @@ class SFTPDestinationPlugin(DestinationPlugin): sftp.mkdir(dst_path) except IOError: current_app.logger.debug("{0} already exist, resuming".format(dst_path)) - try: - dst_path_cn = dst_path + "/" + cn - current_app.logger.debug("Creating {0}".format(dst_path_cn)) - sftp.mkdir(dst_path_cn) - except IOError: - current_app.logger.debug( - "{0} already exist, resuming".format(dst_path_cn) - ) # upload certificate files to the sftp destination for filename, data in files.items(): current_app.logger.debug( - "Uploading {0} to {1}".format(filename, dst_path_cn) + "Uploading {0} to {1}".format(filename, dst_path) ) try: - with sftp.open(dst_path_cn + "/" + filename, "w") as f: + with sftp.open(dst_path + "/" + filename, "w") as f: f.write(data) - except (PermissionError) as permerror: + except PermissionError as permerror: if permerror.errno == 13: current_app.logger.debug( - "Uploading {0} to {1} returned Permission Denied Error, making file writable and retrying".format(filename, dst_path_cn) + "Uploading {0} to {1} returned Permission Denied Error, making file writable and retrying".format( + filename, dst_path) ) - sftp.chmod(dst_path_cn + "/" + filename, 0o600) - with sftp.open(dst_path_cn + "/" + filename, "w") as f: + sftp.chmod(dst_path + "/" + filename, 0o600) + with sftp.open(dst_path + "/" + filename, "w") as f: f.write(data) # read only for owner, -r-------- - sftp.chmod(dst_path_cn + "/" + filename, 0o400) + sftp.chmod(dst_path + "/" + filename, 0o400) ssh.close() From 3012995c76e87b29ab30d5c3077c3e228852c4d6 Mon Sep 17 00:00:00 2001 From: Mathias Petermann Date: Tue, 29 Sep 2020 18:32:30 +0200 Subject: [PATCH 003/314] Improve naming, make it possible to create directories recursively with SFTP --- lemur/plugins/lemur_sftp/plugin.py | 52 ++++++++++++++++++++++-------- 1 file changed, 38 insertions(+), 14 deletions(-) diff --git a/lemur/plugins/lemur_sftp/plugin.py b/lemur/plugins/lemur_sftp/plugin.py index 7c4e93c4..f2a8c9bf 100644 --- a/lemur/plugins/lemur_sftp/plugin.py +++ b/lemur/plugins/lemur_sftp/plugin.py @@ -16,7 +16,7 @@ .. moduleauthor:: Dmitry Zykov https://github.com/DmitryZykov """ -from os import path +from os import path, walk import paramiko @@ -121,15 +121,17 @@ class SFTPDestinationPlugin(DestinationPlugin): self.upload_file(dst_path_cn, files, options) # this is called from the acme http challenge - def upload_acme_token(self, token, thumbprint, options, **kwargs): + def upload_acme_token(self, token_path, token, options, **kwargs): current_app.logger.debug("SFTP destination plugin is started for HTTP-01 challenge") dst_path = self.get_option("destinationPath", options) - dst_path = path.join(dst_path, "/.well-known/acme-challenge/") + dst_path = path.join(dst_path, ".well-known/acme-challenge/") + + _, filename = path.split(token_path) # prepare files for upload - files = {token: thumbprint} + files = {filename: token} self.upload_file(dst_path, files, options) @@ -169,15 +171,37 @@ class SFTPDestinationPlugin(DestinationPlugin): ) raise paramiko.ssh_exception.AuthenticationException + # split the path into it's segments, so we can create it recursively + allparts = [] + path_copy = dst_path + while True: + parts = path.split(path_copy) + if parts[0] == path_copy: # sentinel for absolute paths + allparts.insert(0, parts[0]) + break + elif parts[1] == path_copy: # sentinel for relative paths + allparts.insert(0, parts[1]) + break + else: + path_copy = parts[0] + allparts.insert(0, parts[1]) + # open the sftp session inside the ssh connection sftp = ssh.open_sftp() - # make sure that the destination path exist - try: - current_app.logger.debug("Creating {0}".format(dst_path)) - sftp.mkdir(dst_path) - except IOError: - current_app.logger.debug("{0} already exist, resuming".format(dst_path)) + # make sure that the destination path exists, recursively + remote_path = allparts[0] + for part in allparts: + try: + if part != "/" and part != "": + remote_path = path.join(remote_path, part); + sftp.stat(remote_path) + except IOError: + current_app.logger.debug("{0} doesn't exist, trying to create it".format(remote_path)) + try: + sftp.mkdir(remote_path) + except IOError as ioerror: + current_app.logger.debug("Couldn't create {0}, error message: {1}".format(remote_path, ioerror)) # upload certificate files to the sftp destination for filename, data in files.items(): @@ -185,7 +209,7 @@ class SFTPDestinationPlugin(DestinationPlugin): "Uploading {0} to {1}".format(filename, dst_path) ) try: - with sftp.open(dst_path + "/" + filename, "w") as f: + with sftp.open(path.join(dst_path, filename), "w") as f: f.write(data) except PermissionError as permerror: if permerror.errno == 13: @@ -193,11 +217,11 @@ class SFTPDestinationPlugin(DestinationPlugin): "Uploading {0} to {1} returned Permission Denied Error, making file writable and retrying".format( filename, dst_path) ) - sftp.chmod(dst_path + "/" + filename, 0o600) - with sftp.open(dst_path + "/" + filename, "w") as f: + sftp.chmod(path.join(dst_path, filename), 0o600) + with sftp.open(path.join(dst_path, filename), "w") as f: f.write(data) # read only for owner, -r-------- - sftp.chmod(dst_path + "/" + filename, 0o400) + sftp.chmod(path.join(dst_path, filename), 0o400) ssh.close() From e06bdcf2a3d75a598a09b73f613d0e59b8604774 Mon Sep 17 00:00:00 2001 From: Mathias Petermann Date: Tue, 29 Sep 2020 18:33:40 +0200 Subject: [PATCH 004/314] Implement create_certificate for HTTP-01 challenge --- lemur/plugins/lemur_acme/plugin.py | 73 ++++++++++++++++++++++++------ 1 file changed, 60 insertions(+), 13 deletions(-) diff --git a/lemur/plugins/lemur_acme/plugin.py b/lemur/plugins/lemur_acme/plugin.py index d1c86017..f8165c4d 100644 --- a/lemur/plugins/lemur_acme/plugin.py +++ b/lemur/plugins/lemur_acme/plugin.py @@ -30,6 +30,8 @@ from lemur.destinations import service as destination_service from lemur.dns_providers import service as dns_provider_service from lemur.exceptions import InvalidAuthority, InvalidConfiguration, UnknownProvider from lemur.extensions import metrics, sentry + +from lemur.plugins.base import plugins from lemur.plugins import lemur_acme as acme from lemur.plugins.bases import IssuerPlugin from lemur.plugins.lemur_acme import cloudflare, dyn, route53, ultradns, powerdns @@ -83,19 +85,19 @@ class AcmeHandler(object): def maybe_add_extension(self, host, dns_provider_options): if dns_provider_options and dns_provider_options.get( - "acme_challenge_extension" + "acme_challenge_extension" ): host = host + dns_provider_options.get("acme_challenge_extension") return host def start_dns_challenge( - self, - acme_client, - account_number, - host, - dns_provider, - order, - dns_provider_options, + self, + acme_client, + account_number, + host, + dns_provider, + order, + dns_provider_options, ): current_app.logger.debug("Starting DNS challenge for {0}".format(host)) @@ -210,12 +212,12 @@ class AcmeHandler(object): if current_app.config.get("IDENTRUST_CROSS_SIGNED_LE_ICA", False) \ and datetime.datetime.now() < datetime.datetime.strptime( - current_app.config.get("IDENTRUST_CROSS_SIGNED_LE_ICA_EXPIRATION_DATE", "17/03/21"), '%d/%m/%y'): + current_app.config.get("IDENTRUST_CROSS_SIGNED_LE_ICA_EXPIRATION_DATE", "17/03/21"), '%d/%m/%y'): pem_certificate_chain = current_app.config.get("IDENTRUST_CROSS_SIGNED_LE_ICA") else: pem_certificate_chain = orderr.fullchain_pem[ - len(pem_certificate) : # noqa - ].lstrip() + len(pem_certificate): # noqa + ].lstrip() current_app.logger.debug( "{0} {1}".format(type(pem_certificate), type(pem_certificate_chain)) @@ -692,6 +694,7 @@ class ACMEIssuerPlugin(IssuerPlugin): account_number = None provider_type = None + acme_client.new_order() domains = self.acme.get_domains(issuer_options) if not create_immediately: # Create pending authorizations that we'll need to do the creation @@ -810,7 +813,51 @@ class ACMEHttpIssuerPlugin(IssuerPlugin): self.destination_list.append(destination.label) def create_certificate(self, csr, issuer_options): - pass + """ + Creates an ACME certificate using the HTTP-01 challenge. + + :param csr: + :param issuer_options: + :return: :raise Exception: + """ + self.acme = AcmeHandler() + authority = issuer_options.get("authority") + create_immediately = issuer_options.get("create_immediately", False) + acme_client, registration = self.acme.setup_acme_client(authority) + + orderr = acme_client.new_order(csr) + challenge = None + + for authz in orderr.authorizations: + # Choosing challenge. + # authz.body.challenges is a set of ChallengeBody objects. + for i in authz.body.challenges: + # Find the supported challenge. + if isinstance(i.chall, challenges.HTTP01): + challenge = i + + if challenge is None: + raise Exception('HTTP-01 challenge was not offered by the CA server.') + else: + # Here we probably should create a pending certificate and make use of celery, but for now + # I'll ignore all of that + for option in json.loads(issuer_options["authority"].options): + if option["name"] == "tokenDestination": + token_destination = destination_service.get_by_label(option["value"]) + + if token_destination is None: + raise Exception('No token_destination configured for this authority. Cant complete HTTP-01 challenge') + + destination_plugin = plugins.get(token_destination.plugin_name) + destination_plugin.upload_acme_token(challenge.chall.path, challenge.chall.token, token_destination.options) + + current_app.logger.info("Uploaded HTTP-01 challenge token, trying to poll and finalize the order") + + pem_certificate, pem_certificate_chain = self.acme.request_certificate( + acme_client, orderr.authorizations, csr + ) + # TODO add external ID (if possible) + return pem_certificate, pem_certificate_chain, None @staticmethod def create_authority(options): @@ -837,4 +884,4 @@ class ACMEHttpIssuerPlugin(IssuerPlugin): def cancel_ordered_certificate(self, pending_cert, **kwargs): # Needed to override issuer function. - pass \ No newline at end of file + pass From b93d271f318d56935f741e1846e8525c890c2f81 Mon Sep 17 00:00:00 2001 From: Mathias Petermann Date: Wed, 30 Sep 2020 08:39:41 +0200 Subject: [PATCH 005/314] Fix flake8 --- lemur/plugins/lemur_acme/plugin.py | 2 +- lemur/plugins/lemur_sftp/plugin.py | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/lemur/plugins/lemur_acme/plugin.py b/lemur/plugins/lemur_acme/plugin.py index f8165c4d..d42573df 100644 --- a/lemur/plugins/lemur_acme/plugin.py +++ b/lemur/plugins/lemur_acme/plugin.py @@ -212,7 +212,7 @@ class AcmeHandler(object): if current_app.config.get("IDENTRUST_CROSS_SIGNED_LE_ICA", False) \ and datetime.datetime.now() < datetime.datetime.strptime( - current_app.config.get("IDENTRUST_CROSS_SIGNED_LE_ICA_EXPIRATION_DATE", "17/03/21"), '%d/%m/%y'): + current_app.config.get("IDENTRUST_CROSS_SIGNED_LE_ICA_EXPIRATION_DATE", "17/03/21"), '%d/%m/%y'): pem_certificate_chain = current_app.config.get("IDENTRUST_CROSS_SIGNED_LE_ICA") else: pem_certificate_chain = orderr.fullchain_pem[ diff --git a/lemur/plugins/lemur_sftp/plugin.py b/lemur/plugins/lemur_sftp/plugin.py index f2a8c9bf..e44052d2 100644 --- a/lemur/plugins/lemur_sftp/plugin.py +++ b/lemur/plugins/lemur_sftp/plugin.py @@ -16,7 +16,7 @@ .. moduleauthor:: Dmitry Zykov https://github.com/DmitryZykov """ -from os import path, walk +from os import path import paramiko @@ -194,7 +194,7 @@ class SFTPDestinationPlugin(DestinationPlugin): for part in allparts: try: if part != "/" and part != "": - remote_path = path.join(remote_path, part); + remote_path = path.join(remote_path, part) sftp.stat(remote_path) except IOError: current_app.logger.debug("{0} doesn't exist, trying to create it".format(remote_path)) From b2de9866528ade2fe815ae2656ab90b602e17b62 Mon Sep 17 00:00:00 2001 From: Mathias Petermann Date: Wed, 30 Sep 2020 09:24:26 +0200 Subject: [PATCH 006/314] Split tests into handler, and dns specifics --- .../tests/{test_acme.py => test_acme_dns.py} | 88 +------- .../lemur_acme/tests/test_acme_handler.py | 194 ++++++++++++++++++ 2 files changed, 196 insertions(+), 86 deletions(-) rename lemur/plugins/lemur_acme/tests/{test_acme.py => test_acme_dns.py} (81%) create mode 100644 lemur/plugins/lemur_acme/tests/test_acme_handler.py diff --git a/lemur/plugins/lemur_acme/tests/test_acme.py b/lemur/plugins/lemur_acme/tests/test_acme_dns.py similarity index 81% rename from lemur/plugins/lemur_acme/tests/test_acme.py rename to lemur/plugins/lemur_acme/tests/test_acme_dns.py index ab246563..8074ca93 100644 --- a/lemur/plugins/lemur_acme/tests/test_acme.py +++ b/lemur/plugins/lemur_acme/tests/test_acme_dns.py @@ -8,7 +8,7 @@ from lemur.common.utils import generate_private_key from mock import MagicMock -class TestAcme(unittest.TestCase): +class TestAcmeDns(unittest.TestCase): @patch("lemur.plugins.lemur_acme.plugin.dns_provider_service") def setUp(self, mock_dns_provider_service): self.ACMEIssuerPlugin = plugin.ACMEIssuerPlugin() @@ -39,19 +39,6 @@ class TestAcme(unittest.TestCase): result = yield self.acme.get_dns_challenges(host, mock_authz) self.assertEqual(result, mock_entry) - def test_strip_wildcard(self): - expected = ("example.com", False) - result = self.acme.strip_wildcard("example.com") - self.assertEqual(expected, result) - - expected = ("example.com", True) - result = self.acme.strip_wildcard("*.example.com") - self.assertEqual(expected, result) - - def test_authz_record(self): - a = plugin.AuthorizationRecord("host", "authz", "challenge", "id") - self.assertEqual(type(a), plugin.AuthorizationRecord) - @patch("acme.client.Client") @patch("lemur.plugins.lemur_acme.plugin.current_app") @patch("lemur.plugins.lemur_acme.plugin.len", return_value=1) @@ -68,7 +55,7 @@ class TestAcme(unittest.TestCase): from acme import challenges c = challenges.DNS01() - mock_entry.chall = TestAcme.test_complete_dns_challenge_fail + mock_entry.chall = TestAcmeDns.test_complete_dns_challenge_fail mock_authz.body.resolved_combinations.append(mock_entry) mock_acme.request_domain_challenges = Mock(return_value=mock_authz) mock_dns_provider = Mock() @@ -336,77 +323,6 @@ class TestAcme(unittest.TestCase): dyn = provider.get_dns_provider("dyn") assert dyn - @patch("lemur.plugins.lemur_acme.plugin.AcmeHandler.setup_acme_client") - @patch("lemur.plugins.lemur_acme.plugin.current_app") - @patch("lemur.plugins.lemur_acme.plugin.authorization_service") - @patch("lemur.plugins.lemur_acme.plugin.dns_provider_service") - @patch("lemur.plugins.lemur_acme.plugin.AcmeHandler.get_authorizations") - @patch("lemur.plugins.lemur_acme.plugin.AcmeHandler.finalize_authorizations") - @patch("lemur.plugins.lemur_acme.plugin.AcmeHandler.request_certificate") - def test_get_ordered_certificate( - self, - mock_request_certificate, - mock_finalize_authorizations, - mock_get_authorizations, - mock_dns_provider_service, - mock_authorization_service, - mock_current_app, - mock_acme, - ): - mock_client = Mock() - mock_acme.return_value = (mock_client, "") - mock_request_certificate.return_value = ("pem_certificate", "chain") - - mock_cert = Mock() - mock_cert.external_id = 1 - - provider = plugin.ACMEIssuerPlugin() - provider.get_dns_provider = Mock() - result = provider.get_ordered_certificate(mock_cert) - self.assertEqual( - result, {"body": "pem_certificate", "chain": "chain", "external_id": "1"} - ) - - @patch("lemur.plugins.lemur_acme.plugin.AcmeHandler.setup_acme_client") - @patch("lemur.plugins.lemur_acme.plugin.current_app") - @patch("lemur.plugins.lemur_acme.plugin.authorization_service") - @patch("lemur.plugins.lemur_acme.plugin.dns_provider_service") - @patch("lemur.plugins.lemur_acme.plugin.AcmeHandler.get_authorizations") - @patch("lemur.plugins.lemur_acme.plugin.AcmeHandler.finalize_authorizations") - @patch("lemur.plugins.lemur_acme.plugin.AcmeHandler.request_certificate") - def test_get_ordered_certificates( - self, - mock_request_certificate, - mock_finalize_authorizations, - mock_get_authorizations, - mock_dns_provider_service, - mock_authorization_service, - mock_current_app, - mock_acme, - ): - mock_client = Mock() - mock_acme.return_value = (mock_client, "") - mock_request_certificate.return_value = ("pem_certificate", "chain") - - mock_cert = Mock() - mock_cert.external_id = 1 - - mock_cert2 = Mock() - mock_cert2.external_id = 2 - - provider = plugin.ACMEIssuerPlugin() - provider.get_dns_provider = Mock() - result = provider.get_ordered_certificates([mock_cert, mock_cert2]) - self.assertEqual(len(result), 2) - self.assertEqual( - result[0]["cert"], - {"body": "pem_certificate", "chain": "chain", "external_id": "1"}, - ) - self.assertEqual( - result[1]["cert"], - {"body": "pem_certificate", "chain": "chain", "external_id": "2"}, - ) - @patch("lemur.plugins.lemur_acme.plugin.AcmeHandler.setup_acme_client") @patch("lemur.plugins.lemur_acme.plugin.dns_provider_service") @patch("lemur.plugins.lemur_acme.plugin.current_app") diff --git a/lemur/plugins/lemur_acme/tests/test_acme_handler.py b/lemur/plugins/lemur_acme/tests/test_acme_handler.py new file mode 100644 index 00000000..60ebf409 --- /dev/null +++ b/lemur/plugins/lemur_acme/tests/test_acme_handler.py @@ -0,0 +1,194 @@ +import unittest +from unittest.mock import patch, Mock + +from cryptography.x509 import DNSName +from lemur.plugins.lemur_acme import plugin +from mock import MagicMock + + +class TestAcmeHandler(unittest.TestCase): + @patch("lemur.plugins.lemur_acme.plugin.dns_provider_service") + def setUp(self, mock_dns_provider_service): + self.acme = plugin.AcmeHandler() + mock_dns_provider = Mock() + mock_dns_provider.name = "cloudflare" + mock_dns_provider.credentials = "{}" + mock_dns_provider.provider_type = "cloudflare" + self.acme.dns_providers_for_domain = { + "www.test.com": [mock_dns_provider], + "test.fakedomain.net": [mock_dns_provider], + } + + def test_strip_wildcard(self): + expected = ("example.com", False) + result = self.acme.strip_wildcard("example.com") + self.assertEqual(expected, result) + + expected = ("example.com", True) + result = self.acme.strip_wildcard("*.example.com") + self.assertEqual(expected, result) + + def test_authz_record(self): + a = plugin.AuthorizationRecord("host", "authz", "challenge", "id") + self.assertEqual(type(a), plugin.AuthorizationRecord) + + def test_setup_acme_client_fail(self): + mock_authority = Mock() + mock_authority.options = [] + with self.assertRaises(Exception): + self.acme.setup_acme_client(mock_authority) + + @patch("lemur.plugins.lemur_acme.plugin.BackwardsCompatibleClientV2") + @patch("lemur.plugins.lemur_acme.plugin.current_app") + def test_setup_acme_client_success(self, mock_current_app, mock_acme): + mock_authority = Mock() + mock_authority.options = '[{"name": "mock_name", "value": "mock_value"}]' + mock_client = Mock() + mock_registration = Mock() + mock_registration.uri = "http://test.com" + mock_client.register = mock_registration + mock_client.agree_to_tos = Mock(return_value=True) + mock_acme.return_value = mock_client + mock_current_app.config = {} + result_client, result_registration = self.acme.setup_acme_client(mock_authority) + assert result_client + assert result_registration + + @patch('lemur.plugins.lemur_acme.plugin.current_app') + def test_get_domains_single(self, mock_current_app): + options = {"common_name": "test.netflix.net"} + result = self.acme.get_domains(options) + self.assertEqual(result, [options["common_name"]]) + + @patch("lemur.plugins.lemur_acme.plugin.current_app") + def test_get_domains_multiple(self, mock_current_app): + options = { + "common_name": "test.netflix.net", + "extensions": { + "sub_alt_names": {"names": [DNSName("test2.netflix.net"), DNSName("test3.netflix.net")]} + }, + } + result = self.acme.get_domains(options) + self.assertEqual( + result, [options["common_name"], "test2.netflix.net", "test3.netflix.net"] + ) + + @patch("lemur.plugins.lemur_acme.plugin.current_app") + def test_get_domains_san(self, mock_current_app): + options = { + "common_name": "test.netflix.net", + "extensions": { + "sub_alt_names": {"names": [DNSName("test.netflix.net"), DNSName("test2.netflix.net")]} + }, + } + result = self.acme.get_domains(options) + self.assertEqual( + result, [options["common_name"], "test2.netflix.net"] + ) + + @patch( + "lemur.plugins.lemur_acme.plugin.AcmeHandler.start_dns_challenge", + return_value="test", + ) + def test_get_authorizations(self, mock_start_dns_challenge): + mock_order = Mock() + mock_order.body.identifiers = [] + mock_domain = Mock() + mock_order.body.identifiers.append(mock_domain) + mock_order_info = Mock() + mock_order_info.account_number = 1 + mock_order_info.domains = ["test.fakedomain.net"] + result = self.acme.get_authorizations( + "acme_client", mock_order, mock_order_info + ) + self.assertEqual(result, ["test"]) + + @patch( + "lemur.plugins.lemur_acme.plugin.AcmeHandler.complete_dns_challenge", + return_value="test", + ) + def test_finalize_authorizations(self, mock_complete_dns_challenge): + mock_authz = [] + mock_authz_record = MagicMock() + mock_authz_record.authz = Mock() + mock_authz_record.change_id = 1 + mock_authz_record.dns_challenge.validation_domain_name = Mock() + mock_authz_record.dns_challenge.validation = Mock() + mock_authz.append(mock_authz_record) + mock_dns_provider = Mock() + mock_dns_provider.delete_txt_record = Mock() + + mock_acme_client = Mock() + result = self.acme.finalize_authorizations(mock_acme_client, mock_authz) + self.assertEqual(result, mock_authz) + + @patch("lemur.plugins.lemur_acme.plugin.AcmeHandler.setup_acme_client") + @patch("lemur.plugins.lemur_acme.plugin.current_app") + @patch("lemur.plugins.lemur_acme.plugin.authorization_service") + @patch("lemur.plugins.lemur_acme.plugin.dns_provider_service") + @patch("lemur.plugins.lemur_acme.plugin.AcmeHandler.get_authorizations") + @patch("lemur.plugins.lemur_acme.plugin.AcmeHandler.finalize_authorizations") + @patch("lemur.plugins.lemur_acme.plugin.AcmeHandler.request_certificate") + def test_get_ordered_certificate( + self, + mock_request_certificate, + mock_finalize_authorizations, + mock_get_authorizations, + mock_dns_provider_service, + mock_authorization_service, + mock_current_app, + mock_acme, + ): + mock_client = Mock() + mock_acme.return_value = (mock_client, "") + mock_request_certificate.return_value = ("pem_certificate", "chain") + + mock_cert = Mock() + mock_cert.external_id = 1 + + provider = plugin.ACMEIssuerPlugin() + provider.get_dns_provider = Mock() + result = provider.get_ordered_certificate(mock_cert) + self.assertEqual( + result, {"body": "pem_certificate", "chain": "chain", "external_id": "1"} + ) + + @patch("lemur.plugins.lemur_acme.plugin.AcmeHandler.setup_acme_client") + @patch("lemur.plugins.lemur_acme.plugin.current_app") + @patch("lemur.plugins.lemur_acme.plugin.authorization_service") + @patch("lemur.plugins.lemur_acme.plugin.dns_provider_service") + @patch("lemur.plugins.lemur_acme.plugin.AcmeHandler.get_authorizations") + @patch("lemur.plugins.lemur_acme.plugin.AcmeHandler.finalize_authorizations") + @patch("lemur.plugins.lemur_acme.plugin.AcmeHandler.request_certificate") + def test_get_ordered_certificates( + self, + mock_request_certificate, + mock_finalize_authorizations, + mock_get_authorizations, + mock_dns_provider_service, + mock_authorization_service, + mock_current_app, + mock_acme, + ): + mock_client = Mock() + mock_acme.return_value = (mock_client, "") + mock_request_certificate.return_value = ("pem_certificate", "chain") + + mock_cert = Mock() + mock_cert.external_id = 1 + + mock_cert2 = Mock() + mock_cert2.external_id = 2 + + provider = plugin.ACMEIssuerPlugin() + provider.get_dns_provider = Mock() + result = provider.get_ordered_certificates([mock_cert, mock_cert2]) + self.assertEqual(len(result), 2) + self.assertEqual( + result[0]["cert"], + {"body": "pem_certificate", "chain": "chain", "external_id": "1"}, + ) + self.assertEqual( + result[1]["cert"], + {"body": "pem_certificate", "chain": "chain", "external_id": "2"}, + ) From d6719b729c93aaa1806f901a8efb8197b04f6e0b Mon Sep 17 00:00:00 2001 From: Mathias Petermann Date: Wed, 30 Sep 2020 10:23:49 +0200 Subject: [PATCH 007/314] Implement some test for AcmeHttpIssuerPlugin --- .../lemur_acme/tests/test_acme_http.py | 122 ++++++++++++++++++ 1 file changed, 122 insertions(+) create mode 100644 lemur/plugins/lemur_acme/tests/test_acme_http.py diff --git a/lemur/plugins/lemur_acme/tests/test_acme_http.py b/lemur/plugins/lemur_acme/tests/test_acme_http.py new file mode 100644 index 00000000..f6183062 --- /dev/null +++ b/lemur/plugins/lemur_acme/tests/test_acme_http.py @@ -0,0 +1,122 @@ +import unittest +from unittest.mock import patch, Mock + +from acme import challenges +from lemur.plugins.lemur_acme import plugin +from mock import MagicMock + + +class TestAcmeHttp(unittest.TestCase): + @patch("lemur.plugins.lemur_acme.plugin.dns_provider_service") + @patch("lemur.plugins.lemur_acme.plugin.destination_service") + def setUp(self, mock_dns_provider_service, mock_destination_provider): + self.ACMEHttpIssuerPlugin = plugin.ACMEHttpIssuerPlugin() + self.acme = plugin.AcmeHandler() + mock_dns_provider = Mock() + mock_dns_provider.name = "cloudflare" + mock_dns_provider.credentials = "{}" + mock_dns_provider.provider_type = "cloudflare" + self.acme.dns_providers_for_domain = { + "www.test.com": [mock_dns_provider], + "test.fakedomain.net": [mock_dns_provider], + } + mock_destination_provider = Mock() + mock_destination_provider.label = "mock-sftp-destination" + mock_destination_provider.plugin_name = "sftp-destination" + self.ACMEHttpIssuerPlugin.destination_list = ["mock-sftp-destination", "mock-s3-destination"] + + @patch("acme.client.Client") + @patch("OpenSSL.crypto", return_value="mock_cert") + @patch("josepy.util.ComparableX509") + @patch("lemur.plugins.lemur_acme.plugin.AcmeHandler.get_dns_challenges") + @patch("lemur.plugins.lemur_acme.plugin.current_app") + def test_request_certificate( + self, + mock_current_app, + mock_get_dns_challenges, + mock_jose, + mock_crypto, + mock_acme, + ): + mock_cert_response = Mock() + mock_cert_response.body = "123" + mock_cert_response_full = [mock_cert_response, True] + mock_acme.poll_and_request_issuance = Mock(return_value=mock_cert_response_full) + mock_authz = [] + mock_authz_record = MagicMock() + mock_authz_record.authz = Mock() + mock_authz.append(mock_authz_record) + mock_acme.fetch_chain = Mock(return_value="mock_chain") + mock_crypto.dump_certificate = Mock(return_value=b"chain") + mock_order = Mock() + mock_current_app.config = {} + self.acme.request_certificate(mock_acme, [], mock_order) + + @patch("lemur.plugins.lemur_acme.plugin.current_app") + def test_create_authority(self, mock_current_app): + mock_current_app.config = Mock() + options = { + "plugin": {"plugin_options": [{"name": "certificate", "value": "123"}]} + } + acme_root, b, role = self.ACMEHttpIssuerPlugin.create_authority(options) + self.assertEqual(acme_root, "123") + self.assertEqual(b, "") + self.assertEqual(role, [{"username": "", "password": "", "name": "acme"}]) + + @patch("lemur.plugins.lemur_acme.plugin.AcmeHandler.setup_acme_client") + @patch("lemur.plugins.base.manager.PluginManager.get") + @patch("lemur.plugins.lemur_acme.plugin.destination_service") + @patch("lemur.plugins.lemur_acme.plugin.dns_provider_service") + @patch("lemur.plugins.lemur_acme.plugin.current_app") + @patch("lemur.plugins.lemur_acme.plugin.AcmeHandler.get_authorizations") + @patch("lemur.plugins.lemur_acme.plugin.AcmeHandler.finalize_authorizations") + @patch("lemur.plugins.lemur_acme.plugin.AcmeHandler.request_certificate") + @patch("lemur.plugins.lemur_acme.plugin.authorization_service") + def test_create_certificate( + self, + mock_authorization_service, + mock_request_certificate, + mock_finalize_authorizations, + mock_get_authorizations, + mock_current_app, + mock_dns_provider_service, + mock_destination_service, + mock_plugin_manager_get, + mock_acme, + ): + provider = plugin.ACMEHttpIssuerPlugin() + mock_authority = Mock() + mock_authority.options = '[{"name": "tokenDestination", "value": "mock-sftp-destination"}]' + + mock_order_resource = Mock() + mock_order_resource.authorizations = [Mock()] + mock_order_resource.authorizations[0].body.challenges = [Mock()] + mock_order_resource.authorizations[0].body.challenges[0].chall = challenges.HTTP01(token=b'\x0f\x1c\xbe#od\xd1\x9c\xa6j\\\xa4\r\xed\xe5\xbf0pz\xeaxnl)\xea[i\xbc\x95\x08\x96\x1f') + + mock_client = Mock() + mock_client.new_order.return_value = mock_order_resource + mock_acme.return_value = (mock_client, "") + + mock_dns_provider = Mock() + mock_dns_provider.credentials = '{"account_id": 1}' + mock_dns_provider.provider_type = "route53" + mock_dns_provider_service.get.return_value = mock_dns_provider + + mock_destination = Mock() + mock_destination.label = "mock-sftp-destination" + mock_destination.plugin_name = "SFTPDestinationPlugin" + mock_destination_service.get_by_label.return_value = mock_destination + + mock_destination_plugin = Mock() + mock_destination_plugin.upload_acme_token.return_value = True + mock_plugin_manager_get.return_value = mock_destination_plugin + + issuer_options = { + "authority": mock_authority, + "tokenDestination": "mock-sftp-destination", + "common_name": "test.netflix.net", + } + csr = "123" + mock_request_certificate.return_value = ("pem_certificate", "chain") + result = provider.create_certificate(csr, issuer_options) + assert result From 76dcfbd528aa3a835e0062be0685ee5cba7edbca Mon Sep 17 00:00:00 2001 From: Mathias Petermann Date: Wed, 30 Sep 2020 11:35:27 +0200 Subject: [PATCH 008/314] Add more tests --- lemur/plugins/lemur_acme/plugin.py | 1 + .../lemur_acme/tests/test_acme_http.py | 132 +++++++++++++----- 2 files changed, 100 insertions(+), 33 deletions(-) diff --git a/lemur/plugins/lemur_acme/plugin.py b/lemur/plugins/lemur_acme/plugin.py index d42573df..a3d15b6d 100644 --- a/lemur/plugins/lemur_acme/plugin.py +++ b/lemur/plugins/lemur_acme/plugin.py @@ -841,6 +841,7 @@ class ACMEHttpIssuerPlugin(IssuerPlugin): else: # Here we probably should create a pending certificate and make use of celery, but for now # I'll ignore all of that + token_destination = None for option in json.loads(issuer_options["authority"].options): if option["name"] == "tokenDestination": token_destination = destination_service.get_by_label(option["value"]) diff --git a/lemur/plugins/lemur_acme/tests/test_acme_http.py b/lemur/plugins/lemur_acme/tests/test_acme_http.py index f6183062..14d46344 100644 --- a/lemur/plugins/lemur_acme/tests/test_acme_http.py +++ b/lemur/plugins/lemur_acme/tests/test_acme_http.py @@ -3,7 +3,6 @@ from unittest.mock import patch, Mock from acme import challenges from lemur.plugins.lemur_acme import plugin -from mock import MagicMock class TestAcmeHttp(unittest.TestCase): @@ -25,33 +24,6 @@ class TestAcmeHttp(unittest.TestCase): mock_destination_provider.plugin_name = "sftp-destination" self.ACMEHttpIssuerPlugin.destination_list = ["mock-sftp-destination", "mock-s3-destination"] - @patch("acme.client.Client") - @patch("OpenSSL.crypto", return_value="mock_cert") - @patch("josepy.util.ComparableX509") - @patch("lemur.plugins.lemur_acme.plugin.AcmeHandler.get_dns_challenges") - @patch("lemur.plugins.lemur_acme.plugin.current_app") - def test_request_certificate( - self, - mock_current_app, - mock_get_dns_challenges, - mock_jose, - mock_crypto, - mock_acme, - ): - mock_cert_response = Mock() - mock_cert_response.body = "123" - mock_cert_response_full = [mock_cert_response, True] - mock_acme.poll_and_request_issuance = Mock(return_value=mock_cert_response_full) - mock_authz = [] - mock_authz_record = MagicMock() - mock_authz_record.authz = Mock() - mock_authz.append(mock_authz_record) - mock_acme.fetch_chain = Mock(return_value="mock_chain") - mock_crypto.dump_certificate = Mock(return_value=b"chain") - mock_order = Mock() - mock_current_app.config = {} - self.acme.request_certificate(mock_acme, [], mock_order) - @patch("lemur.plugins.lemur_acme.plugin.current_app") def test_create_authority(self, mock_current_app): mock_current_app.config = Mock() @@ -97,11 +69,6 @@ class TestAcmeHttp(unittest.TestCase): mock_client.new_order.return_value = mock_order_resource mock_acme.return_value = (mock_client, "") - mock_dns_provider = Mock() - mock_dns_provider.credentials = '{"account_id": 1}' - mock_dns_provider.provider_type = "route53" - mock_dns_provider_service.get.return_value = mock_dns_provider - mock_destination = Mock() mock_destination.label = "mock-sftp-destination" mock_destination.plugin_name = "SFTPDestinationPlugin" @@ -120,3 +87,102 @@ class TestAcmeHttp(unittest.TestCase): mock_request_certificate.return_value = ("pem_certificate", "chain") result = provider.create_certificate(csr, issuer_options) assert result + + @patch("lemur.plugins.lemur_acme.plugin.AcmeHandler.setup_acme_client") + @patch("lemur.plugins.base.manager.PluginManager.get") + @patch("lemur.plugins.lemur_acme.plugin.destination_service") + @patch("lemur.plugins.lemur_acme.plugin.dns_provider_service") + @patch("lemur.plugins.lemur_acme.plugin.current_app") + @patch("lemur.plugins.lemur_acme.plugin.AcmeHandler.get_authorizations") + @patch("lemur.plugins.lemur_acme.plugin.AcmeHandler.finalize_authorizations") + @patch("lemur.plugins.lemur_acme.plugin.AcmeHandler.request_certificate") + @patch("lemur.plugins.lemur_acme.plugin.authorization_service") + def test_create_certificate_missing_destination_token( + self, + mock_authorization_service, + mock_request_certificate, + mock_finalize_authorizations, + mock_get_authorizations, + mock_current_app, + mock_dns_provider_service, + mock_destination_service, + mock_plugin_manager_get, + mock_acme, + ): + provider = plugin.ACMEHttpIssuerPlugin() + mock_authority = Mock() + mock_authority.options = '[{"name": "mock_name", "value": "mock_value"}]' + + mock_order_resource = Mock() + mock_order_resource.authorizations = [Mock()] + mock_order_resource.authorizations[0].body.challenges = [Mock()] + mock_order_resource.authorizations[0].body.challenges[0].chall = challenges.HTTP01( + token=b'\x0f\x1c\xbe#od\xd1\x9c\xa6j\\\xa4\r\xed\xe5\xbf0pz\xeaxnl)\xea[i\xbc\x95\x08\x96\x1f') + + mock_client = Mock() + mock_client.new_order.return_value = mock_order_resource + mock_acme.return_value = (mock_client, "") + + mock_destination = Mock() + mock_destination.label = "mock-sftp-destination" + mock_destination.plugin_name = "SFTPDestinationPlugin" + mock_destination_service.get_by_label.return_value = mock_destination + + mock_destination_plugin = Mock() + mock_destination_plugin.upload_acme_token.return_value = True + mock_plugin_manager_get.return_value = mock_destination_plugin + + issuer_options = { + "authority": mock_authority, + "tokenDestination": "mock-sftp-destination", + "common_name": "test.netflix.net", + } + csr = "123" + mock_request_certificate.return_value = ("pem_certificate", "chain") + with self.assertRaisesRegexp(Exception, "No token_destination configured"): + provider.create_certificate(csr, issuer_options) + + @patch("lemur.plugins.lemur_acme.plugin.AcmeHandler.setup_acme_client") + @patch("lemur.plugins.base.manager.PluginManager.get") + @patch("lemur.plugins.lemur_acme.plugin.destination_service") + @patch("lemur.plugins.lemur_acme.plugin.dns_provider_service") + @patch("lemur.plugins.lemur_acme.plugin.current_app") + @patch("lemur.plugins.lemur_acme.plugin.AcmeHandler.get_authorizations") + @patch("lemur.plugins.lemur_acme.plugin.AcmeHandler.finalize_authorizations") + @patch("lemur.plugins.lemur_acme.plugin.AcmeHandler.request_certificate") + @patch("lemur.plugins.lemur_acme.plugin.authorization_service") + def test_create_certificate_missing_http_challenge( + self, + mock_authorization_service, + mock_request_certificate, + mock_finalize_authorizations, + mock_get_authorizations, + mock_current_app, + mock_dns_provider_service, + mock_destination_service, + mock_plugin_manager_get, + mock_acme, + ): + provider = plugin.ACMEHttpIssuerPlugin() + mock_authority = Mock() + mock_authority.options = '[{"name": "tokenDestination", "value": "mock-sftp-destination"}]' + + mock_order_resource = Mock() + mock_order_resource.authorizations = [Mock()] + mock_order_resource.authorizations[0].body.challenges = [Mock()] + mock_order_resource.authorizations[0].body.challenges[0].chall = challenges.DNS01( + token=b'\x0f\x1c\xbe#od\xd1\x9c\xa6j\\\xa4\r\xed\xe5\xbf0pz\xeaxnl)\xea[i\xbc\x95\x08\x96\x1f') + + mock_client = Mock() + mock_client.new_order.return_value = mock_order_resource + mock_acme.return_value = (mock_client, "") + + issuer_options = { + "authority": mock_authority, + "tokenDestination": "mock-sftp-destination", + "common_name": "test.netflix.net", + } + csr = "123" + mock_request_certificate.return_value = ("pem_certificate", "chain") + with self.assertRaisesRegexp(Exception, "HTTP-01 challenge was not offered"): + provider.create_certificate(csr, issuer_options) From e3e5ef7d66a35cfcb35ddefd3dbeb0e143e43206 Mon Sep 17 00:00:00 2001 From: Mathias Petermann Date: Wed, 30 Sep 2020 11:56:12 +0200 Subject: [PATCH 009/314] Refactor AcmeHandler, Move DNS stuff into AcmeDnsHandler --- lemur/plugins/lemur_acme/plugin.py | 264 +++++++++--------- .../plugins/lemur_acme/tests/test_acme_dns.py | 119 +++++++- .../lemur_acme/tests/test_acme_handler.py | 119 +------- .../lemur_acme/tests/test_acme_http.py | 30 +- 4 files changed, 250 insertions(+), 282 deletions(-) diff --git a/lemur/plugins/lemur_acme/plugin.py b/lemur/plugins/lemur_acme/plugin.py index a3d15b6d..c82ac529 100644 --- a/lemur/plugins/lemur_acme/plugin.py +++ b/lemur/plugins/lemur_acme/plugin.py @@ -48,33 +48,6 @@ class AuthorizationRecord(object): class AcmeHandler(object): - def __init__(self): - self.dns_providers_for_domain = {} - try: - self.all_dns_providers = dns_provider_service.get_all_dns_providers() - except Exception as e: - metrics.send("AcmeHandler_init_error", "counter", 1) - sentry.captureException() - current_app.logger.error(f"Unable to fetch DNS Providers: {e}") - self.all_dns_providers = [] - - def get_dns_challenges(self, host, authorizations): - """Get dns challenges for provided domain""" - - domain_to_validate, is_wildcard = self.strip_wildcard(host) - dns_challenges = [] - for authz in authorizations: - if not authz.body.identifier.value.lower() == domain_to_validate.lower(): - continue - if is_wildcard and not authz.body.wildcard: - continue - if not is_wildcard and authz.body.wildcard: - continue - for combo in authz.body.challenges: - if isinstance(combo.chall, challenges.DNS01): - dns_challenges.append(combo) - - return dns_challenges def strip_wildcard(self, host): """Removes the leading *. and returns Host and whether it was removed or not (True/False)""" @@ -90,91 +63,6 @@ class AcmeHandler(object): host = host + dns_provider_options.get("acme_challenge_extension") return host - def start_dns_challenge( - self, - acme_client, - account_number, - host, - dns_provider, - order, - dns_provider_options, - ): - current_app.logger.debug("Starting DNS challenge for {0}".format(host)) - - change_ids = [] - dns_challenges = self.get_dns_challenges(host, order.authorizations) - host_to_validate, _ = self.strip_wildcard(host) - host_to_validate = self.maybe_add_extension( - host_to_validate, dns_provider_options - ) - - if not dns_challenges: - sentry.captureException() - metrics.send("start_dns_challenge_error_no_dns_challenges", "counter", 1) - raise Exception("Unable to determine DNS challenges from authorizations") - - for dns_challenge in dns_challenges: - change_id = dns_provider.create_txt_record( - dns_challenge.validation_domain_name(host_to_validate), - dns_challenge.validation(acme_client.client.net.key), - account_number, - ) - change_ids.append(change_id) - - return AuthorizationRecord( - host, order.authorizations, dns_challenges, change_ids - ) - - def complete_dns_challenge(self, acme_client, authz_record): - current_app.logger.debug( - "Finalizing DNS challenge for {0}".format( - authz_record.authz[0].body.identifier.value - ) - ) - dns_providers = self.dns_providers_for_domain.get(authz_record.host) - if not dns_providers: - metrics.send("complete_dns_challenge_error_no_dnsproviders", "counter", 1) - raise Exception( - "No DNS providers found for domain: {}".format(authz_record.host) - ) - - for dns_provider in dns_providers: - # Grab account number (For Route53) - dns_provider_options = json.loads(dns_provider.credentials) - account_number = dns_provider_options.get("account_id") - dns_provider_plugin = self.get_dns_provider(dns_provider.provider_type) - for change_id in authz_record.change_id: - try: - dns_provider_plugin.wait_for_dns_change( - change_id, account_number=account_number - ) - except Exception: - metrics.send("complete_dns_challenge_error", "counter", 1) - sentry.captureException() - current_app.logger.debug( - f"Unable to resolve DNS challenge for change_id: {change_id}, account_id: " - f"{account_number}", - exc_info=True, - ) - raise - - for dns_challenge in authz_record.dns_challenge: - response = dns_challenge.response(acme_client.client.net.key) - - verified = response.simple_verify( - dns_challenge.chall, - authz_record.host, - acme_client.client.net.key.public_key(), - ) - - if not verified: - metrics.send("complete_dns_challenge_verification_error", "counter", 1) - raise ValueError("Failed verification") - - time.sleep(5) - res = acme_client.answer_challenge(dns_challenge, response) - current_app.logger.debug(f"answer_challenge response: {res}") - def request_certificate(self, acme_client, authorizations, order): for authorization in authorizations: for authz in authorization.authz: @@ -310,6 +198,135 @@ class AcmeHandler(object): current_app.logger.debug("Got these domains: {0}".format(domains)) return domains + +class AcmeDnsHandler(AcmeHandler): + + def __init__(self): + self.dns_providers_for_domain = {} + try: + self.all_dns_providers = dns_provider_service.get_all_dns_providers() + except Exception as e: + metrics.send("AcmeHandler_init_error", "counter", 1) + sentry.captureException() + current_app.logger.error(f"Unable to fetch DNS Providers: {e}") + self.all_dns_providers = [] + + def get_dns_challenges(self, host, authorizations): + """Get dns challenges for provided domain""" + + domain_to_validate, is_wildcard = self.strip_wildcard(host) + dns_challenges = [] + for authz in authorizations: + if not authz.body.identifier.value.lower() == domain_to_validate.lower(): + continue + if is_wildcard and not authz.body.wildcard: + continue + if not is_wildcard and authz.body.wildcard: + continue + for combo in authz.body.challenges: + if isinstance(combo.chall, challenges.DNS01): + dns_challenges.append(combo) + + return dns_challenges + + def get_dns_provider(self, type): + provider_types = { + "cloudflare": cloudflare, + "dyn": dyn, + "route53": route53, + "ultradns": ultradns, + "powerdns": powerdns + } + provider = provider_types.get(type) + if not provider: + raise UnknownProvider("No such DNS provider: {}".format(type)) + return provider + + def start_dns_challenge( + self, + acme_client, + account_number, + host, + dns_provider, + order, + dns_provider_options, + ): + current_app.logger.debug("Starting DNS challenge for {0}".format(host)) + + change_ids = [] + dns_challenges = self.get_dns_challenges(host, order.authorizations) + host_to_validate, _ = self.strip_wildcard(host) + host_to_validate = self.maybe_add_extension( + host_to_validate, dns_provider_options + ) + + if not dns_challenges: + sentry.captureException() + metrics.send("start_dns_challenge_error_no_dns_challenges", "counter", 1) + raise Exception("Unable to determine DNS challenges from authorizations") + + for dns_challenge in dns_challenges: + change_id = dns_provider.create_txt_record( + dns_challenge.validation_domain_name(host_to_validate), + dns_challenge.validation(acme_client.client.net.key), + account_number, + ) + change_ids.append(change_id) + + return AuthorizationRecord( + host, order.authorizations, dns_challenges, change_ids + ) + + def complete_dns_challenge(self, acme_client, authz_record): + current_app.logger.debug( + "Finalizing DNS challenge for {0}".format( + authz_record.authz[0].body.identifier.value + ) + ) + dns_providers = self.dns_providers_for_domain.get(authz_record.host) + if not dns_providers: + metrics.send("complete_dns_challenge_error_no_dnsproviders", "counter", 1) + raise Exception( + "No DNS providers found for domain: {}".format(authz_record.host) + ) + + for dns_provider in dns_providers: + # Grab account number (For Route53) + dns_provider_options = json.loads(dns_provider.credentials) + account_number = dns_provider_options.get("account_id") + dns_provider_plugin = self.get_dns_provider(dns_provider.provider_type) + for change_id in authz_record.change_id: + try: + dns_provider_plugin.wait_for_dns_change( + change_id, account_number=account_number + ) + except Exception: + metrics.send("complete_dns_challenge_error", "counter", 1) + sentry.captureException() + current_app.logger.debug( + f"Unable to resolve DNS challenge for change_id: {change_id}, account_id: " + f"{account_number}", + exc_info=True, + ) + raise + + for dns_challenge in authz_record.dns_challenge: + response = dns_challenge.response(acme_client.client.net.key) + + verified = response.simple_verify( + dns_challenge.chall, + authz_record.host, + acme_client.client.net.key.public_key(), + ) + + if not verified: + metrics.send("complete_dns_challenge_verification_error", "counter", 1) + raise ValueError("Failed verification") + + time.sleep(5) + res = acme_client.answer_challenge(dns_challenge, response) + current_app.logger.debug(f"answer_challenge response: {res}") + def get_authorizations(self, acme_client, order, order_info): authorizations = [] @@ -421,19 +438,6 @@ class AcmeHandler(object): sentry.captureException() pass - def get_dns_provider(self, type): - provider_types = { - "cloudflare": cloudflare, - "dyn": dyn, - "route53": route53, - "ultradns": ultradns, - "powerdns": powerdns - } - provider = provider_types.get(type) - if not provider: - raise UnknownProvider("No such DNS provider: {}".format(type)) - return provider - class ACMEIssuerPlugin(IssuerPlugin): title = "Acme" @@ -487,7 +491,7 @@ class ACMEIssuerPlugin(IssuerPlugin): super(ACMEIssuerPlugin, self).__init__(*args, **kwargs) def get_dns_provider(self, type): - self.acme = AcmeHandler() + self.acme = AcmeDnsHandler() provider_types = { "cloudflare": cloudflare, @@ -502,14 +506,14 @@ class ACMEIssuerPlugin(IssuerPlugin): return provider def get_all_zones(self, dns_provider): - self.acme = AcmeHandler() + self.acme = AcmeDnsHandler() dns_provider_options = json.loads(dns_provider.credentials) account_number = dns_provider_options.get("account_id") dns_provider_plugin = self.get_dns_provider(dns_provider.provider_type) return dns_provider_plugin.get_zones(account_number=account_number) def get_ordered_certificate(self, pending_cert): - self.acme = AcmeHandler() + self.acme = AcmeDnsHandler() acme_client, registration = self.acme.setup_acme_client(pending_cert.authority) order_info = authorization_service.get(pending_cert.external_id) if pending_cert.dns_provider_id: @@ -555,7 +559,7 @@ class ACMEIssuerPlugin(IssuerPlugin): return cert def get_ordered_certificates(self, pending_certs): - self.acme = AcmeHandler() + self.acme = AcmeDnsHandler() pending = [] certs = [] for pending_cert in pending_certs: @@ -665,7 +669,7 @@ class ACMEIssuerPlugin(IssuerPlugin): :param issuer_options: :return: :raise Exception: """ - self.acme = AcmeHandler() + self.acme = AcmeDnsHandler() authority = issuer_options.get("authority") create_immediately = issuer_options.get("create_immediately", False) acme_client, registration = self.acme.setup_acme_client(authority) diff --git a/lemur/plugins/lemur_acme/tests/test_acme_dns.py b/lemur/plugins/lemur_acme/tests/test_acme_dns.py index 8074ca93..6b4371d6 100644 --- a/lemur/plugins/lemur_acme/tests/test_acme_dns.py +++ b/lemur/plugins/lemur_acme/tests/test_acme_dns.py @@ -12,7 +12,7 @@ class TestAcmeDns(unittest.TestCase): @patch("lemur.plugins.lemur_acme.plugin.dns_provider_service") def setUp(self, mock_dns_provider_service): self.ACMEIssuerPlugin = plugin.ACMEIssuerPlugin() - self.acme = plugin.AcmeHandler() + self.acme = plugin.AcmeDnsHandler() mock_dns_provider = Mock() mock_dns_provider.name = "cloudflare" mock_dns_provider.credentials = "{}" @@ -42,7 +42,7 @@ class TestAcmeDns(unittest.TestCase): @patch("acme.client.Client") @patch("lemur.plugins.lemur_acme.plugin.current_app") @patch("lemur.plugins.lemur_acme.plugin.len", return_value=1) - @patch("lemur.plugins.lemur_acme.plugin.AcmeHandler.get_dns_challenges") + @patch("lemur.plugins.lemur_acme.plugin.AcmeDnsHandler.get_dns_challenges") def test_start_dns_challenge( self, mock_get_dns_challenges, mock_len, mock_app, mock_acme ): @@ -124,7 +124,7 @@ class TestAcmeDns(unittest.TestCase): @patch("acme.client.Client") @patch("OpenSSL.crypto", return_value="mock_cert") @patch("josepy.util.ComparableX509") - @patch("lemur.plugins.lemur_acme.plugin.AcmeHandler.get_dns_challenges") + @patch("lemur.plugins.lemur_acme.plugin.AcmeDnsHandler.get_dns_challenges") @patch("lemur.plugins.lemur_acme.plugin.current_app") def test_request_certificate( self, @@ -326,9 +326,9 @@ class TestAcmeDns(unittest.TestCase): @patch("lemur.plugins.lemur_acme.plugin.AcmeHandler.setup_acme_client") @patch("lemur.plugins.lemur_acme.plugin.dns_provider_service") @patch("lemur.plugins.lemur_acme.plugin.current_app") - @patch("lemur.plugins.lemur_acme.plugin.AcmeHandler.get_authorizations") - @patch("lemur.plugins.lemur_acme.plugin.AcmeHandler.finalize_authorizations") - @patch("lemur.plugins.lemur_acme.plugin.AcmeHandler.request_certificate") + @patch("lemur.plugins.lemur_acme.plugin.AcmeDnsHandler.get_authorizations") + @patch("lemur.plugins.lemur_acme.plugin.AcmeDnsHandler.finalize_authorizations") + @patch("lemur.plugins.lemur_acme.plugin.AcmeDnsHandler.request_certificate") @patch("lemur.plugins.lemur_acme.plugin.authorization_service") def test_create_certificate( self, @@ -360,3 +360,110 @@ class TestAcmeDns(unittest.TestCase): mock_request_certificate.return_value = ("pem_certificate", "chain") result = provider.create_certificate(csr, issuer_options) assert result + + @patch( + "lemur.plugins.lemur_acme.plugin.AcmeDnsHandler.start_dns_challenge", + return_value="test", + ) + def test_get_authorizations(self, mock_start_dns_challenge): + mock_order = Mock() + mock_order.body.identifiers = [] + mock_domain = Mock() + mock_order.body.identifiers.append(mock_domain) + mock_order_info = Mock() + mock_order_info.account_number = 1 + mock_order_info.domains = ["test.fakedomain.net"] + result = self.acme.get_authorizations( + "acme_client", mock_order, mock_order_info + ) + self.assertEqual(result, ["test"]) + + @patch( + "lemur.plugins.lemur_acme.plugin.AcmeDnsHandler.complete_dns_challenge", + return_value="test", + ) + def test_finalize_authorizations(self, mock_complete_dns_challenge): + mock_authz = [] + mock_authz_record = MagicMock() + mock_authz_record.authz = Mock() + mock_authz_record.change_id = 1 + mock_authz_record.dns_challenge.validation_domain_name = Mock() + mock_authz_record.dns_challenge.validation = Mock() + mock_authz.append(mock_authz_record) + mock_dns_provider = Mock() + mock_dns_provider.delete_txt_record = Mock() + + mock_acme_client = Mock() + result = self.acme.finalize_authorizations(mock_acme_client, mock_authz) + self.assertEqual(result, mock_authz) + + @patch("lemur.plugins.lemur_acme.plugin.AcmeHandler.setup_acme_client") + @patch("lemur.plugins.lemur_acme.plugin.current_app") + @patch("lemur.plugins.lemur_acme.plugin.authorization_service") + @patch("lemur.plugins.lemur_acme.plugin.dns_provider_service") + @patch("lemur.plugins.lemur_acme.plugin.AcmeDnsHandler.get_authorizations") + @patch("lemur.plugins.lemur_acme.plugin.AcmeDnsHandler.finalize_authorizations") + @patch("lemur.plugins.lemur_acme.plugin.AcmeDnsHandler.request_certificate") + def test_get_ordered_certificate( + self, + mock_request_certificate, + mock_finalize_authorizations, + mock_get_authorizations, + mock_dns_provider_service, + mock_authorization_service, + mock_current_app, + mock_acme, + ): + mock_client = Mock() + mock_acme.return_value = (mock_client, "") + mock_request_certificate.return_value = ("pem_certificate", "chain") + + mock_cert = Mock() + mock_cert.external_id = 1 + + provider = plugin.ACMEIssuerPlugin() + provider.get_dns_provider = Mock() + result = provider.get_ordered_certificate(mock_cert) + self.assertEqual( + result, {"body": "pem_certificate", "chain": "chain", "external_id": "1"} + ) + + @patch("lemur.plugins.lemur_acme.plugin.AcmeHandler.setup_acme_client") + @patch("lemur.plugins.lemur_acme.plugin.current_app") + @patch("lemur.plugins.lemur_acme.plugin.authorization_service") + @patch("lemur.plugins.lemur_acme.plugin.dns_provider_service") + @patch("lemur.plugins.lemur_acme.plugin.AcmeDnsHandler.get_authorizations") + @patch("lemur.plugins.lemur_acme.plugin.AcmeDnsHandler.finalize_authorizations") + @patch("lemur.plugins.lemur_acme.plugin.AcmeDnsHandler.request_certificate") + def test_get_ordered_certificates( + self, + mock_request_certificate, + mock_finalize_authorizations, + mock_get_authorizations, + mock_dns_provider_service, + mock_authorization_service, + mock_current_app, + mock_acme, + ): + mock_client = Mock() + mock_acme.return_value = (mock_client, "") + mock_request_certificate.return_value = ("pem_certificate", "chain") + + mock_cert = Mock() + mock_cert.external_id = 1 + + mock_cert2 = Mock() + mock_cert2.external_id = 2 + + provider = plugin.ACMEIssuerPlugin() + provider.get_dns_provider = Mock() + result = provider.get_ordered_certificates([mock_cert, mock_cert2]) + self.assertEqual(len(result), 2) + self.assertEqual( + result[0]["cert"], + {"body": "pem_certificate", "chain": "chain", "external_id": "1"}, + ) + self.assertEqual( + result[1]["cert"], + {"body": "pem_certificate", "chain": "chain", "external_id": "2"}, + ) diff --git a/lemur/plugins/lemur_acme/tests/test_acme_handler.py b/lemur/plugins/lemur_acme/tests/test_acme_handler.py index 60ebf409..b586aa9f 100644 --- a/lemur/plugins/lemur_acme/tests/test_acme_handler.py +++ b/lemur/plugins/lemur_acme/tests/test_acme_handler.py @@ -3,21 +3,11 @@ from unittest.mock import patch, Mock from cryptography.x509 import DNSName from lemur.plugins.lemur_acme import plugin -from mock import MagicMock class TestAcmeHandler(unittest.TestCase): - @patch("lemur.plugins.lemur_acme.plugin.dns_provider_service") - def setUp(self, mock_dns_provider_service): + def setUp(self): self.acme = plugin.AcmeHandler() - mock_dns_provider = Mock() - mock_dns_provider.name = "cloudflare" - mock_dns_provider.credentials = "{}" - mock_dns_provider.provider_type = "cloudflare" - self.acme.dns_providers_for_domain = { - "www.test.com": [mock_dns_provider], - "test.fakedomain.net": [mock_dns_provider], - } def test_strip_wildcard(self): expected = ("example.com", False) @@ -85,110 +75,3 @@ class TestAcmeHandler(unittest.TestCase): self.assertEqual( result, [options["common_name"], "test2.netflix.net"] ) - - @patch( - "lemur.plugins.lemur_acme.plugin.AcmeHandler.start_dns_challenge", - return_value="test", - ) - def test_get_authorizations(self, mock_start_dns_challenge): - mock_order = Mock() - mock_order.body.identifiers = [] - mock_domain = Mock() - mock_order.body.identifiers.append(mock_domain) - mock_order_info = Mock() - mock_order_info.account_number = 1 - mock_order_info.domains = ["test.fakedomain.net"] - result = self.acme.get_authorizations( - "acme_client", mock_order, mock_order_info - ) - self.assertEqual(result, ["test"]) - - @patch( - "lemur.plugins.lemur_acme.plugin.AcmeHandler.complete_dns_challenge", - return_value="test", - ) - def test_finalize_authorizations(self, mock_complete_dns_challenge): - mock_authz = [] - mock_authz_record = MagicMock() - mock_authz_record.authz = Mock() - mock_authz_record.change_id = 1 - mock_authz_record.dns_challenge.validation_domain_name = Mock() - mock_authz_record.dns_challenge.validation = Mock() - mock_authz.append(mock_authz_record) - mock_dns_provider = Mock() - mock_dns_provider.delete_txt_record = Mock() - - mock_acme_client = Mock() - result = self.acme.finalize_authorizations(mock_acme_client, mock_authz) - self.assertEqual(result, mock_authz) - - @patch("lemur.plugins.lemur_acme.plugin.AcmeHandler.setup_acme_client") - @patch("lemur.plugins.lemur_acme.plugin.current_app") - @patch("lemur.plugins.lemur_acme.plugin.authorization_service") - @patch("lemur.plugins.lemur_acme.plugin.dns_provider_service") - @patch("lemur.plugins.lemur_acme.plugin.AcmeHandler.get_authorizations") - @patch("lemur.plugins.lemur_acme.plugin.AcmeHandler.finalize_authorizations") - @patch("lemur.plugins.lemur_acme.plugin.AcmeHandler.request_certificate") - def test_get_ordered_certificate( - self, - mock_request_certificate, - mock_finalize_authorizations, - mock_get_authorizations, - mock_dns_provider_service, - mock_authorization_service, - mock_current_app, - mock_acme, - ): - mock_client = Mock() - mock_acme.return_value = (mock_client, "") - mock_request_certificate.return_value = ("pem_certificate", "chain") - - mock_cert = Mock() - mock_cert.external_id = 1 - - provider = plugin.ACMEIssuerPlugin() - provider.get_dns_provider = Mock() - result = provider.get_ordered_certificate(mock_cert) - self.assertEqual( - result, {"body": "pem_certificate", "chain": "chain", "external_id": "1"} - ) - - @patch("lemur.plugins.lemur_acme.plugin.AcmeHandler.setup_acme_client") - @patch("lemur.plugins.lemur_acme.plugin.current_app") - @patch("lemur.plugins.lemur_acme.plugin.authorization_service") - @patch("lemur.plugins.lemur_acme.plugin.dns_provider_service") - @patch("lemur.plugins.lemur_acme.plugin.AcmeHandler.get_authorizations") - @patch("lemur.plugins.lemur_acme.plugin.AcmeHandler.finalize_authorizations") - @patch("lemur.plugins.lemur_acme.plugin.AcmeHandler.request_certificate") - def test_get_ordered_certificates( - self, - mock_request_certificate, - mock_finalize_authorizations, - mock_get_authorizations, - mock_dns_provider_service, - mock_authorization_service, - mock_current_app, - mock_acme, - ): - mock_client = Mock() - mock_acme.return_value = (mock_client, "") - mock_request_certificate.return_value = ("pem_certificate", "chain") - - mock_cert = Mock() - mock_cert.external_id = 1 - - mock_cert2 = Mock() - mock_cert2.external_id = 2 - - provider = plugin.ACMEIssuerPlugin() - provider.get_dns_provider = Mock() - result = provider.get_ordered_certificates([mock_cert, mock_cert2]) - self.assertEqual(len(result), 2) - self.assertEqual( - result[0]["cert"], - {"body": "pem_certificate", "chain": "chain", "external_id": "1"}, - ) - self.assertEqual( - result[1]["cert"], - {"body": "pem_certificate", "chain": "chain", "external_id": "2"}, - ) diff --git a/lemur/plugins/lemur_acme/tests/test_acme_http.py b/lemur/plugins/lemur_acme/tests/test_acme_http.py index 14d46344..ea81b5c4 100644 --- a/lemur/plugins/lemur_acme/tests/test_acme_http.py +++ b/lemur/plugins/lemur_acme/tests/test_acme_http.py @@ -6,19 +6,11 @@ from lemur.plugins.lemur_acme import plugin class TestAcmeHttp(unittest.TestCase): - @patch("lemur.plugins.lemur_acme.plugin.dns_provider_service") @patch("lemur.plugins.lemur_acme.plugin.destination_service") - def setUp(self, mock_dns_provider_service, mock_destination_provider): + def setUp(self, mock_destination_provider): self.ACMEHttpIssuerPlugin = plugin.ACMEHttpIssuerPlugin() self.acme = plugin.AcmeHandler() - mock_dns_provider = Mock() - mock_dns_provider.name = "cloudflare" - mock_dns_provider.credentials = "{}" - mock_dns_provider.provider_type = "cloudflare" - self.acme.dns_providers_for_domain = { - "www.test.com": [mock_dns_provider], - "test.fakedomain.net": [mock_dns_provider], - } + mock_destination_provider = Mock() mock_destination_provider.label = "mock-sftp-destination" mock_destination_provider.plugin_name = "sftp-destination" @@ -38,20 +30,14 @@ class TestAcmeHttp(unittest.TestCase): @patch("lemur.plugins.lemur_acme.plugin.AcmeHandler.setup_acme_client") @patch("lemur.plugins.base.manager.PluginManager.get") @patch("lemur.plugins.lemur_acme.plugin.destination_service") - @patch("lemur.plugins.lemur_acme.plugin.dns_provider_service") @patch("lemur.plugins.lemur_acme.plugin.current_app") - @patch("lemur.plugins.lemur_acme.plugin.AcmeHandler.get_authorizations") - @patch("lemur.plugins.lemur_acme.plugin.AcmeHandler.finalize_authorizations") @patch("lemur.plugins.lemur_acme.plugin.AcmeHandler.request_certificate") @patch("lemur.plugins.lemur_acme.plugin.authorization_service") def test_create_certificate( self, mock_authorization_service, mock_request_certificate, - mock_finalize_authorizations, - mock_get_authorizations, mock_current_app, - mock_dns_provider_service, mock_destination_service, mock_plugin_manager_get, mock_acme, @@ -91,20 +77,14 @@ class TestAcmeHttp(unittest.TestCase): @patch("lemur.plugins.lemur_acme.plugin.AcmeHandler.setup_acme_client") @patch("lemur.plugins.base.manager.PluginManager.get") @patch("lemur.plugins.lemur_acme.plugin.destination_service") - @patch("lemur.plugins.lemur_acme.plugin.dns_provider_service") @patch("lemur.plugins.lemur_acme.plugin.current_app") - @patch("lemur.plugins.lemur_acme.plugin.AcmeHandler.get_authorizations") - @patch("lemur.plugins.lemur_acme.plugin.AcmeHandler.finalize_authorizations") @patch("lemur.plugins.lemur_acme.plugin.AcmeHandler.request_certificate") @patch("lemur.plugins.lemur_acme.plugin.authorization_service") def test_create_certificate_missing_destination_token( self, mock_authorization_service, mock_request_certificate, - mock_finalize_authorizations, - mock_get_authorizations, mock_current_app, - mock_dns_provider_service, mock_destination_service, mock_plugin_manager_get, mock_acme, @@ -145,20 +125,14 @@ class TestAcmeHttp(unittest.TestCase): @patch("lemur.plugins.lemur_acme.plugin.AcmeHandler.setup_acme_client") @patch("lemur.plugins.base.manager.PluginManager.get") @patch("lemur.plugins.lemur_acme.plugin.destination_service") - @patch("lemur.plugins.lemur_acme.plugin.dns_provider_service") @patch("lemur.plugins.lemur_acme.plugin.current_app") - @patch("lemur.plugins.lemur_acme.plugin.AcmeHandler.get_authorizations") - @patch("lemur.plugins.lemur_acme.plugin.AcmeHandler.finalize_authorizations") @patch("lemur.plugins.lemur_acme.plugin.AcmeHandler.request_certificate") @patch("lemur.plugins.lemur_acme.plugin.authorization_service") def test_create_certificate_missing_http_challenge( self, mock_authorization_service, mock_request_certificate, - mock_finalize_authorizations, - mock_get_authorizations, mock_current_app, - mock_dns_provider_service, mock_destination_service, mock_plugin_manager_get, mock_acme, From 66cab6abd3e76e818e5987cacea83e6853204c78 Mon Sep 17 00:00:00 2001 From: Mathias Petermann Date: Wed, 30 Sep 2020 17:40:15 +0200 Subject: [PATCH 010/314] Make http-01 challenge work for SAN certificates --- lemur/plugins/lemur_acme/plugin.py | 45 ++++++++++++++++++++++++------ 1 file changed, 37 insertions(+), 8 deletions(-) diff --git a/lemur/plugins/lemur_acme/plugin.py b/lemur/plugins/lemur_acme/plugin.py index c82ac529..841531a5 100644 --- a/lemur/plugins/lemur_acme/plugin.py +++ b/lemur/plugins/lemur_acme/plugin.py @@ -830,17 +830,17 @@ class ACMEHttpIssuerPlugin(IssuerPlugin): acme_client, registration = self.acme.setup_acme_client(authority) orderr = acme_client.new_order(csr) - challenge = None + chall = [] for authz in orderr.authorizations: # Choosing challenge. # authz.body.challenges is a set of ChallengeBody objects. for i in authz.body.challenges: # Find the supported challenge. if isinstance(i.chall, challenges.HTTP01): - challenge = i + chall.append(i) - if challenge is None: + if len(chall) == 0: raise Exception('HTTP-01 challenge was not offered by the CA server.') else: # Here we probably should create a pending certificate and make use of celery, but for now @@ -854,13 +854,42 @@ class ACMEHttpIssuerPlugin(IssuerPlugin): raise Exception('No token_destination configured for this authority. Cant complete HTTP-01 challenge') destination_plugin = plugins.get(token_destination.plugin_name) - destination_plugin.upload_acme_token(challenge.chall.path, challenge.chall.token, token_destination.options) - current_app.logger.info("Uploaded HTTP-01 challenge token, trying to poll and finalize the order") + for challenge in chall: + response, validation = challenge.response_and_validation(acme_client.net.key) + + destination_plugin.upload_acme_token(challenge.chall.path, validation, token_destination.options) + + # Let the CA server know that we are ready for the challenge. + acme_client.answer_challenge(challenge, response) + + current_app.logger.info("Uploaded HTTP-01 challenge tokens, trying to poll and finalize the order") + + # Wait for challenge status and then issue a certificate. + + for authz in orderr.authorizations: + authzr, resp = acme_client.poll(authz) + current_app.logger.info(authzr.body.status) + + # It is possible to set a deadline time. + finalized_orderr = acme_client.finalize_order(orderr, datetime.datetime.now() + datetime.timedelta(minutes=1)) + + pem_certificate = OpenSSL.crypto.dump_certificate( + OpenSSL.crypto.FILETYPE_PEM, + OpenSSL.crypto.load_certificate( + OpenSSL.crypto.FILETYPE_PEM, finalized_orderr.fullchain_pem + ), + ).decode() + + if current_app.config.get("IDENTRUST_CROSS_SIGNED_LE_ICA", False) \ + and datetime.datetime.now() < datetime.datetime.strptime( + current_app.config.get("IDENTRUST_CROSS_SIGNED_LE_ICA_EXPIRATION_DATE", "17/03/21"), '%d/%m/%y'): + pem_certificate_chain = current_app.config.get("IDENTRUST_CROSS_SIGNED_LE_ICA") + else: + pem_certificate_chain = finalized_orderr.fullchain_pem[ + len(pem_certificate): # noqa + ].lstrip() - pem_certificate, pem_certificate_chain = self.acme.request_certificate( - acme_client, orderr.authorizations, csr - ) # TODO add external ID (if possible) return pem_certificate, pem_certificate_chain, None From d24fae0bacf0aad20ed088097cbceab308739147 Mon Sep 17 00:00:00 2001 From: Mathias Petermann Date: Wed, 30 Sep 2020 17:40:51 +0200 Subject: [PATCH 011/314] Fix permissions on acme token upload, dont append well-known automatically --- lemur/plugins/lemur_acme/plugin.py | 3 +-- lemur/plugins/lemur_sftp/plugin.py | 5 ++--- 2 files changed, 3 insertions(+), 5 deletions(-) diff --git a/lemur/plugins/lemur_acme/plugin.py b/lemur/plugins/lemur_acme/plugin.py index 841531a5..a3d3fffe 100644 --- a/lemur/plugins/lemur_acme/plugin.py +++ b/lemur/plugins/lemur_acme/plugin.py @@ -866,7 +866,6 @@ class ACMEHttpIssuerPlugin(IssuerPlugin): current_app.logger.info("Uploaded HTTP-01 challenge tokens, trying to poll and finalize the order") # Wait for challenge status and then issue a certificate. - for authz in orderr.authorizations: authzr, resp = acme_client.poll(authz) current_app.logger.info(authzr.body.status) @@ -883,7 +882,7 @@ class ACMEHttpIssuerPlugin(IssuerPlugin): if current_app.config.get("IDENTRUST_CROSS_SIGNED_LE_ICA", False) \ and datetime.datetime.now() < datetime.datetime.strptime( - current_app.config.get("IDENTRUST_CROSS_SIGNED_LE_ICA_EXPIRATION_DATE", "17/03/21"), '%d/%m/%y'): + current_app.config.get("IDENTRUST_CROSS_SIGNED_LE_ICA_EXPIRATION_DATE", "17/03/21"), '%d/%m/%y'): pem_certificate_chain = current_app.config.get("IDENTRUST_CROSS_SIGNED_LE_ICA") else: pem_certificate_chain = finalized_orderr.fullchain_pem[ diff --git a/lemur/plugins/lemur_sftp/plugin.py b/lemur/plugins/lemur_sftp/plugin.py index e44052d2..1c974a28 100644 --- a/lemur/plugins/lemur_sftp/plugin.py +++ b/lemur/plugins/lemur_sftp/plugin.py @@ -126,7 +126,6 @@ class SFTPDestinationPlugin(DestinationPlugin): current_app.logger.debug("SFTP destination plugin is started for HTTP-01 challenge") dst_path = self.get_option("destinationPath", options) - dst_path = path.join(dst_path, ".well-known/acme-challenge/") _, filename = path.split(token_path) @@ -220,8 +219,8 @@ class SFTPDestinationPlugin(DestinationPlugin): sftp.chmod(path.join(dst_path, filename), 0o600) with sftp.open(path.join(dst_path, filename), "w") as f: f.write(data) - # read only for owner, -r-------- - sftp.chmod(path.join(dst_path, filename), 0o400) + # most likely the upload user isn't the webuser, -rw-r--r-- + sftp.chmod(path.join(dst_path, filename), 0o644) ssh.close() From 41ea59d7e39119f993ca33238f7f5b0fdf0da508 Mon Sep 17 00:00:00 2001 From: Mathias Petermann Date: Thu, 1 Oct 2020 08:08:55 +0200 Subject: [PATCH 012/314] Remove unneeded polling --- lemur/plugins/lemur_acme/plugin.py | 5 ----- 1 file changed, 5 deletions(-) diff --git a/lemur/plugins/lemur_acme/plugin.py b/lemur/plugins/lemur_acme/plugin.py index a3d3fffe..f02133a4 100644 --- a/lemur/plugins/lemur_acme/plugin.py +++ b/lemur/plugins/lemur_acme/plugin.py @@ -865,11 +865,6 @@ class ACMEHttpIssuerPlugin(IssuerPlugin): current_app.logger.info("Uploaded HTTP-01 challenge tokens, trying to poll and finalize the order") - # Wait for challenge status and then issue a certificate. - for authz in orderr.authorizations: - authzr, resp = acme_client.poll(authz) - current_app.logger.info(authzr.body.status) - # It is possible to set a deadline time. finalized_orderr = acme_client.finalize_order(orderr, datetime.datetime.now() + datetime.timedelta(minutes=1)) From 215070b327c98def2d1e86a33d874cd010ede67f Mon Sep 17 00:00:00 2001 From: Mathias Petermann Date: Thu, 1 Oct 2020 08:09:17 +0200 Subject: [PATCH 013/314] Fix create_certificate tests --- .../lemur_acme/tests/test_acme_http.py | 19 ++++++++++++++++--- 1 file changed, 16 insertions(+), 3 deletions(-) diff --git a/lemur/plugins/lemur_acme/tests/test_acme_http.py b/lemur/plugins/lemur_acme/tests/test_acme_http.py index ea81b5c4..2e2ae0fb 100644 --- a/lemur/plugins/lemur_acme/tests/test_acme_http.py +++ b/lemur/plugins/lemur_acme/tests/test_acme_http.py @@ -46,13 +46,23 @@ class TestAcmeHttp(unittest.TestCase): mock_authority = Mock() mock_authority.options = '[{"name": "tokenDestination", "value": "mock-sftp-destination"}]' + mock_current_app.config = {} + mock_order_resource = Mock() mock_order_resource.authorizations = [Mock()] mock_order_resource.authorizations[0].body.challenges = [Mock()] - mock_order_resource.authorizations[0].body.challenges[0].chall = challenges.HTTP01(token=b'\x0f\x1c\xbe#od\xd1\x9c\xa6j\\\xa4\r\xed\xe5\xbf0pz\xeaxnl)\xea[i\xbc\x95\x08\x96\x1f') + mock_order_resource.authorizations[0].body.challenges[0].response_and_validation.return_value = (Mock(), "Anything-goes") + mock_order_resource.authorizations[0].body.challenges[0].chall = challenges.HTTP01( + token=b'\x0f\x1c\xbe#od\xd1\x9c\xa6j\\\xa4\r\xed\xe5\xbf0pz\xeaxnl)\xea[i\xbc\x95\x08\x96\x1f') mock_client = Mock() mock_client.new_order.return_value = mock_order_resource + mock_client.answer_challenge.return_value = True + + mock_finalized_order = Mock() + mock_finalized_order.fullchain_pem = "-----BEGIN CERTIFICATE-----\nMIIEqzCCApOgAwIBAgIRAIvhKg5ZRO08VGQx8JdhT+UwDQYJKoZIhvcNAQELBQAw\nGjEYMBYGA1UEAwwPRmFrZSBMRSBSb290IFgxMB4XDTE2MDUyMzIyMDc1OVoXDTM2\nMDUyMzIyMDc1OVowIjEgMB4GA1UEAwwXRmFrZSBMRSBJbnRlcm1lZGlhdGUgWDEw\nggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDtWKySDn7rWZc5ggjz3ZB0\n8jO4xti3uzINfD5sQ7Lj7hzetUT+wQob+iXSZkhnvx+IvdbXF5/yt8aWPpUKnPym\noLxsYiI5gQBLxNDzIec0OIaflWqAr29m7J8+NNtApEN8nZFnf3bhehZW7AxmS1m0\nZnSsdHw0Fw+bgixPg2MQ9k9oefFeqa+7Kqdlz5bbrUYV2volxhDFtnI4Mh8BiWCN\nxDH1Hizq+GKCcHsinDZWurCqder/afJBnQs+SBSL6MVApHt+d35zjBD92fO2Je56\ndhMfzCgOKXeJ340WhW3TjD1zqLZXeaCyUNRnfOmWZV8nEhtHOFbUCU7r/KkjMZO9\nAgMBAAGjgeMwgeAwDgYDVR0PAQH/BAQDAgGGMBIGA1UdEwEB/wQIMAYBAf8CAQAw\nHQYDVR0OBBYEFMDMA0a5WCDMXHJw8+EuyyCm9Wg6MHoGCCsGAQUFBwEBBG4wbDA0\nBggrBgEFBQcwAYYoaHR0cDovL29jc3Auc3RnLXJvb3QteDEubGV0c2VuY3J5cHQu\nb3JnLzA0BggrBgEFBQcwAoYoaHR0cDovL2NlcnQuc3RnLXJvb3QteDEubGV0c2Vu\nY3J5cHQub3JnLzAfBgNVHSMEGDAWgBTBJnSkikSg5vogKNhcI5pFiBh54DANBgkq\nhkiG9w0BAQsFAAOCAgEABYSu4Il+fI0MYU42OTmEj+1HqQ5DvyAeyCA6sGuZdwjF\nUGeVOv3NnLyfofuUOjEbY5irFCDtnv+0ckukUZN9lz4Q2YjWGUpW4TTu3ieTsaC9\nAFvCSgNHJyWSVtWvB5XDxsqawl1KzHzzwr132bF2rtGtazSqVqK9E07sGHMCf+zp\nDQVDVVGtqZPHwX3KqUtefE621b8RI6VCl4oD30Olf8pjuzG4JKBFRFclzLRjo/h7\nIkkfjZ8wDa7faOjVXx6n+eUQ29cIMCzr8/rNWHS9pYGGQKJiY2xmVC9h12H99Xyf\nzWE9vb5zKP3MVG6neX1hSdo7PEAb9fqRhHkqVsqUvJlIRmvXvVKTwNCP3eCjRCCI\nPTAvjV+4ni786iXwwFYNz8l3PmPLCyQXWGohnJ8iBm+5nk7O2ynaPVW0U2W+pt2w\nSVuvdDM5zGv2f9ltNWUiYZHJ1mmO97jSY/6YfdOUH66iRtQtDkHBRdkNBsMbD+Em\n2TgBldtHNSJBfB3pm9FblgOcJ0FSWcUDWJ7vO0+NTXlgrRofRT6pVywzxVo6dND0\nWzYlTWeUVsO40xJqhgUQRER9YLOLxJ0O6C8i0xFxAMKOtSdodMB3RIwt7RFQ0uyt\nn5Z5MqkYhlMI3J1tPRTp1nEt9fyGspBOO05gi148Qasp+3N+svqKomoQglNoAxU=\n-----END CERTIFICATE-----\n-----BEGIN CERTIFICATE-----\nMIIEqzCCApOgAwIBAgIRAIvhKg5ZRO08VGQx8JdhT+UwDQYJKoZIhvcNAQELBQAw\nGjEYMBYGA1UEAwwPRmFrZSBMRSBSb290IFgxMB4XDTE2MDUyMzIyMDc1OVoXDTM2\nMDUyMzIyMDc1OVowIjEgMB4GA1UEAwwXRmFrZSBMRSBJbnRlcm1lZGlhdGUgWDEw\nggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDtWKySDn7rWZc5ggjz3ZB0\n8jO4xti3uzINfD5sQ7Lj7hzetUT+wQob+iXSZkhnvx+IvdbXF5/yt8aWPpUKnPym\noLxsYiI5gQBLxNDzIec0OIaflWqAr29m7J8+NNtApEN8nZFnf3bhehZW7AxmS1m0\nZnSsdHw0Fw+bgixPg2MQ9k9oefFeqa+7Kqdlz5bbrUYV2volxhDFtnI4Mh8BiWCN\nxDH1Hizq+GKCcHsinDZWurCqder/afJBnQs+SBSL6MVApHt+d35zjBD92fO2Je56\ndhMfzCgOKXeJ340WhW3TjD1zqLZXeaCyUNRnfOmWZV8nEhtHOFbUCU7r/KkjMZO9\nAgMBAAGjgeMwgeAwDgYDVR0PAQH/BAQDAgGGMBIGA1UdEwEB/wQIMAYBAf8CAQAw\nHQYDVR0OBBYEFMDMA0a5WCDMXHJw8+EuyyCm9Wg6MHoGCCsGAQUFBwEBBG4wbDA0\nBggrBgEFBQcwAYYoaHR0cDovL29jc3Auc3RnLXJvb3QteDEubGV0c2VuY3J5cHQu\nb3JnLzA0BggrBgEFBQcwAoYoaHR0cDovL2NlcnQuc3RnLXJvb3QteDEubGV0c2Vu\nY3J5cHQub3JnLzAfBgNVHSMEGDAWgBTBJnSkikSg5vogKNhcI5pFiBh54DANBgkq\nhkiG9w0BAQsFAAOCAgEABYSu4Il+fI0MYU42OTmEj+1HqQ5DvyAeyCA6sGuZdwjF\nUGeVOv3NnLyfofuUOjEbY5irFCDtnv+0ckukUZN9lz4Q2YjWGUpW4TTu3ieTsaC9\nAFvCSgNHJyWSVtWvB5XDxsqawl1KzHzzwr132bF2rtGtazSqVqK9E07sGHMCf+zp\nDQVDVVGtqZPHwX3KqUtefE621b8RI6VCl4oD30Olf8pjuzG4JKBFRFclzLRjo/h7\nIkkfjZ8wDa7faOjVXx6n+eUQ29cIMCzr8/rNWHS9pYGGQKJiY2xmVC9h12H99Xyf\nzWE9vb5zKP3MVG6neX1hSdo7PEAb9fqRhHkqVsqUvJlIRmvXvVKTwNCP3eCjRCCI\nPTAvjV+4ni786iXwwFYNz8l3PmPLCyQXWGohnJ8iBm+5nk7O2ynaPVW0U2W+pt2w\nSVuvdDM5zGv2f9ltNWUiYZHJ1mmO97jSY/6YfdOUH66iRtQtDkHBRdkNBsMbD+Em\n2TgBldtHNSJBfB3pm9FblgOcJ0FSWcUDWJ7vO0+NTXlgrRofRT6pVywzxVo6dND0\nWzYlTWeUVsO40xJqhgUQRER9YLOLxJ0O6C8i0xFxAMKOtSdodMB3RIwt7RFQ0uyt\nn5Z5MqkYhlMI3J1tPRTp1nEt9fyGspBOO05gi148Qasp+3N+svqKomoQglNoAxU=\n-----END CERTIFICATE-----\n" + mock_client.finalize_order.return_value = mock_finalized_order + mock_acme.return_value = (mock_client, "") mock_destination = Mock() @@ -71,8 +81,11 @@ class TestAcmeHttp(unittest.TestCase): } csr = "123" mock_request_certificate.return_value = ("pem_certificate", "chain") - result = provider.create_certificate(csr, issuer_options) - assert result + pem_certificate, pem_certificate_chain, _ = provider.create_certificate(csr, issuer_options) + + self.assertEqual(pem_certificate, "-----BEGIN CERTIFICATE-----\nMIIEqzCCApOgAwIBAgIRAIvhKg5ZRO08VGQx8JdhT+UwDQYJKoZIhvcNAQELBQAw\nGjEYMBYGA1UEAwwPRmFrZSBMRSBSb290IFgxMB4XDTE2MDUyMzIyMDc1OVoXDTM2\nMDUyMzIyMDc1OVowIjEgMB4GA1UEAwwXRmFrZSBMRSBJbnRlcm1lZGlhdGUgWDEw\nggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDtWKySDn7rWZc5ggjz3ZB0\n8jO4xti3uzINfD5sQ7Lj7hzetUT+wQob+iXSZkhnvx+IvdbXF5/yt8aWPpUKnPym\noLxsYiI5gQBLxNDzIec0OIaflWqAr29m7J8+NNtApEN8nZFnf3bhehZW7AxmS1m0\nZnSsdHw0Fw+bgixPg2MQ9k9oefFeqa+7Kqdlz5bbrUYV2volxhDFtnI4Mh8BiWCN\nxDH1Hizq+GKCcHsinDZWurCqder/afJBnQs+SBSL6MVApHt+d35zjBD92fO2Je56\ndhMfzCgOKXeJ340WhW3TjD1zqLZXeaCyUNRnfOmWZV8nEhtHOFbUCU7r/KkjMZO9\nAgMBAAGjgeMwgeAwDgYDVR0PAQH/BAQDAgGGMBIGA1UdEwEB/wQIMAYBAf8CAQAw\nHQYDVR0OBBYEFMDMA0a5WCDMXHJw8+EuyyCm9Wg6MHoGCCsGAQUFBwEBBG4wbDA0\nBggrBgEFBQcwAYYoaHR0cDovL29jc3Auc3RnLXJvb3QteDEubGV0c2VuY3J5cHQu\nb3JnLzA0BggrBgEFBQcwAoYoaHR0cDovL2NlcnQuc3RnLXJvb3QteDEubGV0c2Vu\nY3J5cHQub3JnLzAfBgNVHSMEGDAWgBTBJnSkikSg5vogKNhcI5pFiBh54DANBgkq\nhkiG9w0BAQsFAAOCAgEABYSu4Il+fI0MYU42OTmEj+1HqQ5DvyAeyCA6sGuZdwjF\nUGeVOv3NnLyfofuUOjEbY5irFCDtnv+0ckukUZN9lz4Q2YjWGUpW4TTu3ieTsaC9\nAFvCSgNHJyWSVtWvB5XDxsqawl1KzHzzwr132bF2rtGtazSqVqK9E07sGHMCf+zp\nDQVDVVGtqZPHwX3KqUtefE621b8RI6VCl4oD30Olf8pjuzG4JKBFRFclzLRjo/h7\nIkkfjZ8wDa7faOjVXx6n+eUQ29cIMCzr8/rNWHS9pYGGQKJiY2xmVC9h12H99Xyf\nzWE9vb5zKP3MVG6neX1hSdo7PEAb9fqRhHkqVsqUvJlIRmvXvVKTwNCP3eCjRCCI\nPTAvjV+4ni786iXwwFYNz8l3PmPLCyQXWGohnJ8iBm+5nk7O2ynaPVW0U2W+pt2w\nSVuvdDM5zGv2f9ltNWUiYZHJ1mmO97jSY/6YfdOUH66iRtQtDkHBRdkNBsMbD+Em\n2TgBldtHNSJBfB3pm9FblgOcJ0FSWcUDWJ7vO0+NTXlgrRofRT6pVywzxVo6dND0\nWzYlTWeUVsO40xJqhgUQRER9YLOLxJ0O6C8i0xFxAMKOtSdodMB3RIwt7RFQ0uyt\nn5Z5MqkYhlMI3J1tPRTp1nEt9fyGspBOO05gi148Qasp+3N+svqKomoQglNoAxU=\n-----END CERTIFICATE-----\n") + self.assertEqual(pem_certificate_chain, + "-----BEGIN CERTIFICATE-----\nMIIEqzCCApOgAwIBAgIRAIvhKg5ZRO08VGQx8JdhT+UwDQYJKoZIhvcNAQELBQAw\nGjEYMBYGA1UEAwwPRmFrZSBMRSBSb290IFgxMB4XDTE2MDUyMzIyMDc1OVoXDTM2\nMDUyMzIyMDc1OVowIjEgMB4GA1UEAwwXRmFrZSBMRSBJbnRlcm1lZGlhdGUgWDEw\nggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDtWKySDn7rWZc5ggjz3ZB0\n8jO4xti3uzINfD5sQ7Lj7hzetUT+wQob+iXSZkhnvx+IvdbXF5/yt8aWPpUKnPym\noLxsYiI5gQBLxNDzIec0OIaflWqAr29m7J8+NNtApEN8nZFnf3bhehZW7AxmS1m0\nZnSsdHw0Fw+bgixPg2MQ9k9oefFeqa+7Kqdlz5bbrUYV2volxhDFtnI4Mh8BiWCN\nxDH1Hizq+GKCcHsinDZWurCqder/afJBnQs+SBSL6MVApHt+d35zjBD92fO2Je56\ndhMfzCgOKXeJ340WhW3TjD1zqLZXeaCyUNRnfOmWZV8nEhtHOFbUCU7r/KkjMZO9\nAgMBAAGjgeMwgeAwDgYDVR0PAQH/BAQDAgGGMBIGA1UdEwEB/wQIMAYBAf8CAQAw\nHQYDVR0OBBYEFMDMA0a5WCDMXHJw8+EuyyCm9Wg6MHoGCCsGAQUFBwEBBG4wbDA0\nBggrBgEFBQcwAYYoaHR0cDovL29jc3Auc3RnLXJvb3QteDEubGV0c2VuY3J5cHQu\nb3JnLzA0BggrBgEFBQcwAoYoaHR0cDovL2NlcnQuc3RnLXJvb3QteDEubGV0c2Vu\nY3J5cHQub3JnLzAfBgNVHSMEGDAWgBTBJnSkikSg5vogKNhcI5pFiBh54DANBgkq\nhkiG9w0BAQsFAAOCAgEABYSu4Il+fI0MYU42OTmEj+1HqQ5DvyAeyCA6sGuZdwjF\nUGeVOv3NnLyfofuUOjEbY5irFCDtnv+0ckukUZN9lz4Q2YjWGUpW4TTu3ieTsaC9\nAFvCSgNHJyWSVtWvB5XDxsqawl1KzHzzwr132bF2rtGtazSqVqK9E07sGHMCf+zp\nDQVDVVGtqZPHwX3KqUtefE621b8RI6VCl4oD30Olf8pjuzG4JKBFRFclzLRjo/h7\nIkkfjZ8wDa7faOjVXx6n+eUQ29cIMCzr8/rNWHS9pYGGQKJiY2xmVC9h12H99Xyf\nzWE9vb5zKP3MVG6neX1hSdo7PEAb9fqRhHkqVsqUvJlIRmvXvVKTwNCP3eCjRCCI\nPTAvjV+4ni786iXwwFYNz8l3PmPLCyQXWGohnJ8iBm+5nk7O2ynaPVW0U2W+pt2w\nSVuvdDM5zGv2f9ltNWUiYZHJ1mmO97jSY/6YfdOUH66iRtQtDkHBRdkNBsMbD+Em\n2TgBldtHNSJBfB3pm9FblgOcJ0FSWcUDWJ7vO0+NTXlgrRofRT6pVywzxVo6dND0\nWzYlTWeUVsO40xJqhgUQRER9YLOLxJ0O6C8i0xFxAMKOtSdodMB3RIwt7RFQ0uyt\nn5Z5MqkYhlMI3J1tPRTp1nEt9fyGspBOO05gi148Qasp+3N+svqKomoQglNoAxU=\n-----END CERTIFICATE-----\n") @patch("lemur.plugins.lemur_acme.plugin.AcmeHandler.setup_acme_client") @patch("lemur.plugins.base.manager.PluginManager.get") From 81b078604c7f3d183420b2f6ce8c62aebbff7143 Mon Sep 17 00:00:00 2001 From: Mathias Petermann Date: Tue, 6 Oct 2020 11:04:04 +0200 Subject: [PATCH 014/314] Implement revoke certificate for ACME --- lemur/plugins/lemur_acme/plugin.py | 71 ++++++++++++++++++- .../lemur_acme/tests/test_acme_handler.py | 28 ++++++++ 2 files changed, 97 insertions(+), 2 deletions(-) diff --git a/lemur/plugins/lemur_acme/plugin.py b/lemur/plugins/lemur_acme/plugin.py index f02133a4..b8cbdc55 100644 --- a/lemur/plugins/lemur_acme/plugin.py +++ b/lemur/plugins/lemur_acme/plugin.py @@ -49,6 +49,29 @@ class AuthorizationRecord(object): class AcmeHandler(object): + def reuse_account(self, authority): + if not authority.options: + raise InvalidAuthority("Invalid authority. Options not set") + existing_key = False + existing_regr = False + + for option in json.loads(authority.options): + if option["name"] == "acme_private_key" and option["value"]: + existing_key = True + if option["name"] == "acme_regr" and option["value"]: + existing_regr = True + + if not existing_key and current_app.config.get("ACME_PRIVATE_KEY"): + existing_key = True + + if not existing_regr and current_app.config.get("ACME_REGR"): + existing_regr = True + + if existing_key and existing_regr: + return True + else: + return False + def strip_wildcard(self, host): """Removes the leading *. and returns Host and whether it was removed or not (True/False)""" prefix = "*." @@ -755,6 +778,28 @@ class ACMEIssuerPlugin(IssuerPlugin): # Needed to override issuer function. pass + def revoke_certificate(self, certificate, comments): + self.acme = AcmeDnsHandler() + if not self.acme.reuse_account(certificate.authority): + raise InvalidConfiguration("There is no ACME account saved, unable to revoke the certificate.") + acme_client, _ = self.acme.setup_acme_client(certificate.authority) + + fullchain_com = jose.ComparableX509( + OpenSSL.crypto.load_certificate( + OpenSSL.crypto.FILETYPE_PEM, certificate.body)) + + try: + acme_client.revoke(fullchain_com, 0) # revocation reason = 0 + except (errors.ConflictError, errors.ClientError, errors.Error) as e: + # Certificate already revoked. + current_app.logger.error("Certificate revocation failed with message: " + e.detail) + metrics.send("acme_revoke_certificate_failure", "counter", 1) + return False + + current_app.logger.warning("Certificate succesfully revoked: " + certificate.name) + metrics.send("acme_revoke_certificate_success", "counter", 1) + return True + class ACMEHttpIssuerPlugin(IssuerPlugin): title = "Acme HTTP-01" @@ -884,8 +929,8 @@ class ACMEHttpIssuerPlugin(IssuerPlugin): len(pem_certificate): # noqa ].lstrip() - # TODO add external ID (if possible) - return pem_certificate, pem_certificate_chain, None + # validation is a random string, we use it as external id, to make it possible to implement revoke_certificate + return pem_certificate, pem_certificate_chain, validation[0:128] @staticmethod def create_authority(options): @@ -913,3 +958,25 @@ class ACMEHttpIssuerPlugin(IssuerPlugin): def cancel_ordered_certificate(self, pending_cert, **kwargs): # Needed to override issuer function. pass + + def revoke_certificate(self, certificate, comments): + self.acme = AcmeHandler() + if not self.acme.reuse_account(certificate.authority): + raise InvalidConfiguration("There is no ACME account saved, unable to revoke the certificate.") + acme_client, _ = self.acme.setup_acme_client(certificate.authority) + + fullchain_com = jose.ComparableX509( + OpenSSL.crypto.load_certificate( + OpenSSL.crypto.FILETYPE_PEM, certificate.body)) + + try: + acme_client.revoke(fullchain_com, 0) # revocation reason = 0 + except (errors.ConflictError, errors.ClientError, errors.Error) as e: + # Certificate already revoked. + current_app.logger.error("Certificate revocation failed with message: " + e.detail) + metrics.send("acme_revoke_certificate_failure", "counter", 1) + return False + + current_app.logger.warning("Certificate succesfully revoked: " + certificate.name) + metrics.send("acme_revoke_certificate_success", "counter", 1) + return True diff --git a/lemur/plugins/lemur_acme/tests/test_acme_handler.py b/lemur/plugins/lemur_acme/tests/test_acme_handler.py index b586aa9f..57ddcee6 100644 --- a/lemur/plugins/lemur_acme/tests/test_acme_handler.py +++ b/lemur/plugins/lemur_acme/tests/test_acme_handler.py @@ -28,6 +28,34 @@ class TestAcmeHandler(unittest.TestCase): with self.assertRaises(Exception): self.acme.setup_acme_client(mock_authority) + def test_reuse_account_not_defined(self): + mock_authority = Mock() + mock_authority.options = [] + with self.assertRaises(Exception): + self.acme.reuse_account(mock_authority) + + def test_reuse_account_from_authority(self): + mock_authority = Mock() + mock_authority.options = '[{"name": "acme_private_key", "value": "PRIVATE_KEY"}, {"name": "acme_regr", "value": "ACME_REGR"}]' + + self.assertTrue(self.acme.reuse_account(mock_authority)) + + @patch("lemur.plugins.lemur_acme.plugin.current_app") + def test_reuse_account_from_config(self, mock_current_app): + mock_authority = Mock() + mock_authority.options = '[{"name": "mock_name", "value": "mock_value"}]' + mock_current_app.config = {"ACME_PRIVATE_KEY": "PRIVATE_KEY", "ACME_REGR": "ACME_REGR"} + + self.assertTrue(self.acme.reuse_account(mock_authority)) + + @patch("lemur.plugins.lemur_acme.plugin.current_app") + def test_reuse_account_no_configuration(self, mock_current_app): + mock_authority = Mock() + mock_authority.options = '[{"name": "mock_name", "value": "mock_value"}]' + mock_current_app.config = {} + + self.assertFalse(self.acme.reuse_account(mock_authority)) + @patch("lemur.plugins.lemur_acme.plugin.BackwardsCompatibleClientV2") @patch("lemur.plugins.lemur_acme.plugin.current_app") def test_setup_acme_client_success(self, mock_current_app, mock_acme): From 235653b55842022588faddff10d1bd9c5d8734c4 Mon Sep 17 00:00:00 2001 From: Mathias Petermann Date: Wed, 7 Oct 2020 11:43:17 +0200 Subject: [PATCH 015/314] Refactor destination selection for acme-http authorities, to load destinations dynamically --- lemur/plugins/lemur_acme/plugin.py | 9 ++------- .../angular/authorities/authority/authority.js | 8 +++++++- .../authorities/authority/options.tpl.html | 17 +++++++++++++++++ 3 files changed, 26 insertions(+), 8 deletions(-) diff --git a/lemur/plugins/lemur_acme/plugin.py b/lemur/plugins/lemur_acme/plugin.py index b8cbdc55..106103d2 100644 --- a/lemur/plugins/lemur_acme/plugin.py +++ b/lemur/plugins/lemur_acme/plugin.py @@ -721,7 +721,6 @@ class ACMEIssuerPlugin(IssuerPlugin): account_number = None provider_type = None - acme_client.new_order() domains = self.acme.get_domains(issuer_options) if not create_immediately: # Create pending authorizations that we'll need to do the creation @@ -844,9 +843,8 @@ class ACMEHttpIssuerPlugin(IssuerPlugin): }, { "name": "tokenDestination", - "type": "select", + "type": "destinationSelect", "required": True, - "available": destination_list, "helpMessage": "The destination to use to deploy the token.", }, ] @@ -871,7 +869,6 @@ class ACMEHttpIssuerPlugin(IssuerPlugin): """ self.acme = AcmeHandler() authority = issuer_options.get("authority") - create_immediately = issuer_options.get("create_immediately", False) acme_client, registration = self.acme.setup_acme_client(authority) orderr = acme_client.new_order(csr) @@ -888,12 +885,10 @@ class ACMEHttpIssuerPlugin(IssuerPlugin): if len(chall) == 0: raise Exception('HTTP-01 challenge was not offered by the CA server.') else: - # Here we probably should create a pending certificate and make use of celery, but for now - # I'll ignore all of that token_destination = None for option in json.loads(issuer_options["authority"].options): if option["name"] == "tokenDestination": - token_destination = destination_service.get_by_label(option["value"]) + token_destination = destination_service.get(option["value"]) if token_destination is None: raise Exception('No token_destination configured for this authority. Cant complete HTTP-01 challenge') diff --git a/lemur/static/app/angular/authorities/authority/authority.js b/lemur/static/app/angular/authorities/authority/authority.js index a449cff5..82f38a92 100644 --- a/lemur/static/app/angular/authorities/authority/authority.js +++ b/lemur/static/app/angular/authorities/authority/authority.js @@ -34,7 +34,7 @@ angular.module('lemur') }; }) - .controller('AuthorityCreateController', function ($scope, $uibModalInstance, AuthorityService, AuthorityApi, LemurRestangular, RoleService, PluginService, WizardHandler, toaster) { + .controller('AuthorityCreateController', function ($scope, $uibModalInstance, AuthorityService, AuthorityApi, LemurRestangular, RoleService, PluginService, WizardHandler, toaster, DestinationService) { $scope.authority = LemurRestangular.restangularizeElement(null, {}, 'authorities'); // set the defaults AuthorityService.getDefaults($scope.authority).then(function () { @@ -52,6 +52,12 @@ angular.module('lemur') }); }); + $scope.getDestinations = function() { + return DestinationService.findDestinationsByName('').then(function(destinations) { + $scope.destinations = destinations; + }); + }; + $scope.getAuthoritiesByName = function (value) { return AuthorityService.findAuthorityByName(value).then(function (authorities) { $scope.authorities = authorities; diff --git a/lemur/static/app/angular/authorities/authority/options.tpl.html b/lemur/static/app/angular/authorities/authority/options.tpl.html index adf8eacc..e683c688 100644 --- a/lemur/static/app/angular/authorities/authority/options.tpl.html +++ b/lemur/static/app/angular/authorities/authority/options.tpl.html @@ -72,11 +72,28 @@
+ + + + + {{$select.selected.label}} + +
+ + + +
+
+ +
+
+ +
+ +
+
@@ -40,7 +61,7 @@
From d2abe59e6ecf8d5aebd801dfb0fe95abd0058d34 Mon Sep 17 00:00:00 2001 From: Albert Tugushev Date: Wed, 2 Dec 2020 13:44:25 +0700 Subject: [PATCH 095/314] Use --no-emit-index-url instead of deprecated --no-index in pip-compile --- Makefile | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Makefile b/Makefile index 3312a41d..e8d900b1 100644 --- a/Makefile +++ b/Makefile @@ -115,10 +115,10 @@ endif @echo "--> Updating Python requirements" pip install --upgrade pip pip install --upgrade pip-tools - pip-compile --output-file requirements.txt requirements.in -U --no-index - pip-compile --output-file requirements-docs.txt requirements-docs.in -U --no-index - pip-compile --output-file requirements-dev.txt requirements-dev.in -U --no-index - pip-compile --output-file requirements-tests.txt requirements-tests.in -U --no-index + pip-compile --output-file requirements.txt requirements.in -U --no-emit-index-url + pip-compile --output-file requirements-docs.txt requirements-docs.in -U --no-emit-index-url + pip-compile --output-file requirements-dev.txt requirements-dev.in -U --no-emit-index-url + pip-compile --output-file requirements-tests.txt requirements-tests.in -U --no-emit-index-url @echo "--> Done updating Python requirements" @echo "--> Removing python-ldap from requirements-docs.txt" grep -v "python-ldap" requirements-docs.txt > tempreqs && mv tempreqs requirements-docs.txt From 3b19863a96b7476440fadca48f5f91ce74f9d519 Mon Sep 17 00:00:00 2001 From: sirferl Date: Wed, 2 Dec 2020 13:24:01 +0100 Subject: [PATCH 096/314] adding source plugin code" --- lemur/plugins/lemur_entrust/plugin.py | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/lemur/plugins/lemur_entrust/plugin.py b/lemur/plugins/lemur_entrust/plugin.py index 924345eb..7aa915c5 100644 --- a/lemur/plugins/lemur_entrust/plugin.py +++ b/lemur/plugins/lemur_entrust/plugin.py @@ -314,6 +314,31 @@ class EntrustSourcePlugin(SourcePlugin): author = "sirferl" author_url = "https://github.com/sirferl/lemur" + def __init__(self, *args, **kwargs): + """Initialize the issuer with the appropriate details.""" + required_vars = [ + "ENTRUST_API_CERT", + "ENTRUST_API_KEY", + "ENTRUST_API_USER", + "ENTRUST_API_PASS", + "ENTRUST_URL", + "ENTRUST_ROOT", + "ENTRUST_NAME", + "ENTRUST_EMAIL", + "ENTRUST_PHONE", + ] + validate_conf(current_app, required_vars) + + self.session = requests.Session() + cert_file = current_app.config.get("ENTRUST_API_CERT") + key_file = current_app.config.get("ENTRUST_API_KEY") + user = current_app.config.get("ENTRUST_API_USER") + password = current_app.config.get("ENTRUST_API_PASS") + self.session.cert = (cert_file, key_file) + self.session.auth = (user, password) + self.session.hooks = dict(response=log_status_code) + super(EntrustSourcePlugin, self).__init__(*args, **kwargs) + def get_certificates(self, options, **kwargs): # Not needed for ENTRUST raise NotImplementedError("Not implemented\n", self, options, **kwargs) From 9b2ac32d701183ecaaca3438396d38312c046c51 Mon Sep 17 00:00:00 2001 From: sirferl Date: Wed, 2 Dec 2020 15:50:51 +0100 Subject: [PATCH 097/314] added source functionality --- lemur/plugins/lemur_entrust/plugin.py | 58 ++++++++++++++++++++++++++- 1 file changed, 56 insertions(+), 2 deletions(-) diff --git a/lemur/plugins/lemur_entrust/plugin.py b/lemur/plugins/lemur_entrust/plugin.py index 7aa915c5..34669eef 100644 --- a/lemur/plugins/lemur_entrust/plugin.py +++ b/lemur/plugins/lemur_entrust/plugin.py @@ -313,6 +313,15 @@ class EntrustSourcePlugin(SourcePlugin): author = "sirferl" author_url = "https://github.com/sirferl/lemur" + options = [ + { + "name": "dummy", + "type": "str", + "required": False, + "validation": "/^[0-9]{12,12}$/", + "helpMessage": "Just to prevent error", + } + ] def __init__(self, *args, **kwargs): """Initialize the issuer with the appropriate details.""" @@ -340,8 +349,53 @@ class EntrustSourcePlugin(SourcePlugin): super(EntrustSourcePlugin, self).__init__(*args, **kwargs) def get_certificates(self, options, **kwargs): - # Not needed for ENTRUST - raise NotImplementedError("Not implemented\n", self, options, **kwargs) + """ Fetch all Entrust certificates """ + base_url = current_app.config.get("ENTRUST_URL") + host = base_url.replace('/enterprise/v2','') + + get_url = f"{base_url}/certificates" + certs =[] + offset = 0 + while True: + response = self.session.get(get_url, + params={ + "status": "ACTIVE", + "isThirdParty": "false", + "fields": "uri,dn", + "offset": offset + } + ) + try: + data = json.loads(response.content) + except ValueError: + # catch an empty jason object here + data = {'response': 'No detailed message'} + status_code = response.status_code + if status_code > 399: + raise Exception(f"ENTRUST error: {msg.get(status_code, status_code)}\n{data['errors']}") + # current_app.logger.info(f"recevied: {data['summary']}") + for c in data["certificates"]: + download_url = "{0}{1}".format( + host, c["uri"] + ) + cert_response = self.session.get(download_url) + certificate = json.loads(cert_response.content) + # current_app.logger.info(f"Result: {certificate}") + # normalize serial + serial = str(int(certificate["serialNumber"], 16)) + cert = { + "body": certificate["endEntityCert"], + "serial": serial, + "external_id": str(certificate["trackingId"]), + } + certs.append(cert) + if data["summary"]["limit"] * offset >= data["summary"]["total"]: + break + else: + offset += 1 + current_app.logger.info(f"Result: {certs}") + return certs + def get_endpoints(self, options, **kwargs): # There are no endpoints in ENTRUST From a0517d26fa75646caedf44758cce971d11041642 Mon Sep 17 00:00:00 2001 From: sirferl Date: Wed, 2 Dec 2020 16:05:34 +0100 Subject: [PATCH 098/314] lint errors fixed --- lemur/plugins/lemur_entrust/plugin.py | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/lemur/plugins/lemur_entrust/plugin.py b/lemur/plugins/lemur_entrust/plugin.py index 34669eef..c2d9caef 100644 --- a/lemur/plugins/lemur_entrust/plugin.py +++ b/lemur/plugins/lemur_entrust/plugin.py @@ -351,17 +351,17 @@ class EntrustSourcePlugin(SourcePlugin): def get_certificates(self, options, **kwargs): """ Fetch all Entrust certificates """ base_url = current_app.config.get("ENTRUST_URL") - host = base_url.replace('/enterprise/v2','') + host = base_url.replace('/enterprise/v2', '') get_url = f"{base_url}/certificates" - certs =[] + certs = [] offset = 0 - while True: - response = self.session.get(get_url, + while True: + response = self.session.get(get_url, params={ - "status": "ACTIVE", + "status": "ACTIVE", "isThirdParty": "false", - "fields": "uri,dn", + "fields": "uri,dn", "offset": offset } ) @@ -372,7 +372,7 @@ class EntrustSourcePlugin(SourcePlugin): data = {'response': 'No detailed message'} status_code = response.status_code if status_code > 399: - raise Exception(f"ENTRUST error: {msg.get(status_code, status_code)}\n{data['errors']}") + raise Exception(f"ENTRUST error: {status_code}\n{data['errors']}") # current_app.logger.info(f"recevied: {data['summary']}") for c in data["certificates"]: download_url = "{0}{1}".format( @@ -391,11 +391,10 @@ class EntrustSourcePlugin(SourcePlugin): certs.append(cert) if data["summary"]["limit"] * offset >= data["summary"]["total"]: break - else: + else: offset += 1 current_app.logger.info(f"Result: {certs}") return certs - def get_endpoints(self, options, **kwargs): # There are no endpoints in ENTRUST From 85d99ded730d8155c2778b0cd64191d4108fe5dd Mon Sep 17 00:00:00 2001 From: Jasmine Schladen Date: Wed, 2 Dec 2020 09:20:09 -0800 Subject: [PATCH 099/314] Add email notifications for CA cert expiry --- docs/administration.rst | 9 + docs/developer/plugins/index.rst | 5 +- docs/production/index.rst | 20 +- lemur/common/celery.py | 36 ++++ lemur/notifications/cli.py | 29 ++- lemur/notifications/messaging.py | 79 ++++++++ .../templates/authority_expiration.html | 172 ++++++++++++++++++ lemur/tests/test_messaging.py | 45 +++++ 8 files changed, 390 insertions(+), 5 deletions(-) create mode 100644 lemur/plugins/lemur_email/templates/authority_expiration.html diff --git a/docs/administration.rst b/docs/administration.rst index 3ef484be..94b15829 100644 --- a/docs/administration.rst +++ b/docs/administration.rst @@ -348,6 +348,15 @@ Lemur supports sending certificate expiration notifications through SES and SMTP LEMUR_SECURITY_TEAM_EMAIL_INTERVALS = [15, 2] +.. data:: LEMUR_AUTHORITY_CERT_EXPIRATION_EMAIL_INTERVALS + :noindex: + + Notification interval set for CA certificate expiration notifications. If unspecified, the value [365, 180] is used (roughly one year and 6 months). + + :: + + LEMUR_AUTHORITY_CERT_EXPIRATION_EMAIL_INTERVALS = [365, 180] + Celery Options --------------- diff --git a/docs/developer/plugins/index.rst b/docs/developer/plugins/index.rst index c2a8c48a..ad45692e 100644 --- a/docs/developer/plugins/index.rst +++ b/docs/developer/plugins/index.rst @@ -215,12 +215,13 @@ Notification ------------ Lemur includes the ability to create Email notifications by **default**. These notifications -currently come in the form of expiration and rotation notices. Lemur periodically checks certificate expiration dates and +currently come in the form of expiration and rotation notices for all certificates, expiration notices for CA certificates, +and ACME certificate creation failure notices. Lemur periodically checks certificate expiration dates and determines if a given certificate is eligible for notification. There are currently only two parameters used to determine if a certificate is eligible; validity expiration (date the certificate is no longer valid) and the number of days the current date (UTC) is from that expiration date. -Expiration notifications can also be configured for Slack or AWS SNS. Rotation notifications are not configurable. +Certificate expiration notifications can also be configured for Slack or AWS SNS. Other notifications are not configurable. Notifications sent to a certificate owner and security team (`LEMUR_SECURITY_TEAM_EMAIL`) can currently only be sent via email. There are currently two objects that are available for notification plugins. The first is `NotificationPlugin`, which is the base object for diff --git a/docs/production/index.rst b/docs/production/index.rst index c6f561ca..d6e925a4 100644 --- a/docs/production/index.rst +++ b/docs/production/index.rst @@ -325,7 +325,7 @@ celery tasks or cron jobs that run these commands. There are currently three commands that could/should be run on a periodic basis: -- `notify` +- `notify expirations` and `notify authority_expirations` - `check_revoked` - `sync` @@ -334,13 +334,15 @@ If you are using LetsEncrypt, you must also run the following: - `fetch_all_pending_acme_certs` - `remove_old_acme_certs` -How often you run these commands is largely up to the user. `notify` and `check_revoked` are typically run at least once a day. +How often you run these commands is largely up to the user. `notify` should be run once a day (more often will result in +duplicate notifications). `check_revoked` is typically run at least once a day. `sync` is typically run every 15 minutes. `fetch_all_pending_acme_certs` should be ran frequently (Every minute is fine). `remove_old_acme_certs` can be ran more rarely, such as once every week. Example cron entries:: 0 22 * * * lemuruser export LEMUR_CONF=/Users/me/.lemur/lemur.conf.py; /www/lemur/bin/lemur notify expirations + 0 22 * * * lemuruser export LEMUR_CONF=/Users/me/.lemur/lemur.conf.py; /www/lemur/bin/lemur notify authority_expirations */15 * * * * lemuruser export LEMUR_CONF=/Users/me/.lemur/lemur.conf.py; /www/lemur/bin/lemur source sync -s all 0 22 * * * lemuruser export LEMUR_CONF=/Users/me/.lemur/lemur.conf.py; /www/lemur/bin/lemur certificate check_revoked @@ -382,6 +384,20 @@ Example Celery configuration (To be placed in your configuration file):: 'expires': 180 }, 'schedule': crontab(hour="*"), + }, + 'notify_expirations': { + 'task': 'lemur.common.celery.notify_expirations', + 'options': { + 'expires': 180 + }, + 'schedule': crontab(hour=22, minute=0), + }, + 'notify_authority_expirations': { + 'task': 'lemur.common.celery.notify_authority_expirations', + 'options': { + 'expires': 180 + }, + 'schedule': crontab(hour=22, minute=0), } } diff --git a/lemur/common/celery.py b/lemur/common/celery.py index f9d58bd9..f428927e 100644 --- a/lemur/common/celery.py +++ b/lemur/common/celery.py @@ -820,6 +820,42 @@ def notify_expirations(): return log_data +@celery.task(soft_time_limit=3600) +def notify_authority_expirations(): + """ + This celery task notifies about expiring certificate authority certs + :return: + """ + function = f"{__name__}.{sys._getframe().f_code.co_name}" + task_id = None + if celery.current_task: + task_id = celery.current_task.request.id + + log_data = { + "function": function, + "message": "notify for certificate authority cert expiration", + "task_id": task_id, + } + + if task_id and is_task_active(function, task_id, None): + log_data["message"] = "Skipping task: Task is already active" + current_app.logger.debug(log_data) + return + + current_app.logger.debug(log_data) + try: + cli_notification.authority_expirations() + except SoftTimeLimitExceeded: + log_data["message"] = "Notify expiring CA Time limit exceeded." + current_app.logger.error(log_data) + sentry.captureException() + metrics.send("celery.timeout", "counter", 1, metric_tags={"function": function}) + return + + metrics.send(f"{function}.success", "counter", 1) + return log_data + + @celery.task(soft_time_limit=3600) def enable_autorotate_for_certs_attached_to_endpoint(): """ diff --git a/lemur/notifications/cli.py b/lemur/notifications/cli.py index a2848117..7012e9c8 100644 --- a/lemur/notifications/cli.py +++ b/lemur/notifications/cli.py @@ -10,6 +10,7 @@ from flask_script import Manager from lemur.constants import SUCCESS_METRIC_STATUS, FAILURE_METRIC_STATUS from lemur.extensions import sentry, metrics from lemur.notifications.messaging import send_expiration_notifications +from lemur.notifications.messaging import send_authority_expiration_notifications manager = Manager(usage="Handles notification related tasks.") @@ -24,7 +25,7 @@ manager = Manager(usage="Handles notification related tasks.") ) def expirations(exclude): """ - Runs Lemur's notification engine, that looks for expired certificates and sends + Runs Lemur's notification engine, that looks for expiring certificates and sends notifications out to those that have subscribed to them. Every certificate receives notifications by default. When expiration notifications are handled outside of Lemur @@ -50,3 +51,29 @@ def expirations(exclude): metrics.send( "expiration_notification_job", "counter", 1, metric_tags={"status": status} ) + + +def authority_expirations(): + """ + Runs Lemur's notification engine, that looks for expiring certificate authority certificates and sends + notifications out to the security team and owner. + + :return: + """ + status = FAILURE_METRIC_STATUS + try: + print("Starting to notify subscribers about expiring certificate authority certificates!") + success, failed = send_authority_expiration_notifications() + print( + "Finished notifying subscribers about expiring certificate authority certificates! " + "Sent: {success} Failed: {failed}".format( + success=success, failed=failed + ) + ) + status = SUCCESS_METRIC_STATUS + except Exception as e: + sentry.captureException() + + metrics.send( + "authority_expiration_notification_job", "counter", 1, metric_tags={"status": status} + ) diff --git a/lemur/notifications/messaging.py b/lemur/notifications/messaging.py index 2658e1a0..9b299a24 100644 --- a/lemur/notifications/messaging.py +++ b/lemur/notifications/messaging.py @@ -62,6 +62,34 @@ def get_certificates(exclude=None): return certs +def get_expiring_authority_certificates(): + """ + Finds all certificate authority certificates that are eligible for expiration notifications. + :return: + """ + now = arrow.utcnow() + authority_expiration_intervals = current_app.config.get("LEMUR_AUTHORITY_CERT_EXPIRATION_EMAIL_INTERVALS", + [365, 180]) + max_not_after = now + timedelta(days=max(authority_expiration_intervals) + 1) + + q = ( + database.db.session.query(Certificate) + .filter(Certificate.not_after < max_not_after) + .filter(Certificate.notify == true()) + .filter(Certificate.expired == false()) + .filter(Certificate.revoked == false()) + .filter(Certificate.root_authority_id.isnot(None)) + .filter(Certificate.authority_id.is_(None)) + ) + + certs = [] + for c in windowed_query(q, Certificate.id, 10000): + days_remaining = (c.not_after - now).days + if days_remaining in authority_expiration_intervals: + certs.append(c) + return certs + + def get_eligible_certificates(exclude=None): """ Finds all certificates that are eligible for certificate expiration notification. @@ -90,6 +118,25 @@ def get_eligible_certificates(exclude=None): return certificates +def get_eligible_authority_certificates(): + """ + Finds all certificate authority certificates that are eligible for certificate expiration notification. + Returns the set of all eligible CA certificates, grouped by owner and interval, with a list of applicable certs. + :return: + """ + certificates = defaultdict(dict) + all_certs = get_expiring_authority_certificates() + now = arrow.utcnow() + + # group by owner + for owner, owner_certs in groupby(all_certs, lambda x: x.owner): + # group by expiration interval + for interval, interval_certs in groupby(owner_certs, lambda x: (x.not_after - now).days): + certificates[owner][interval] = list(interval_certs) # list(c for c in interval_certs) + + return certificates + + def send_plugin_notification(event_type, data, recipients, notification): """ Executes the plugin and handles failure. @@ -176,6 +223,38 @@ def send_expiration_notifications(exclude): return success, failure +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 + 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 + + def send_default_notification(notification_type, data, targets, notification_options=None): """ Sends a report to the specified target via the default notification plugin. Applicable for any notification_type. diff --git a/lemur/plugins/lemur_email/templates/authority_expiration.html b/lemur/plugins/lemur_email/templates/authority_expiration.html new file mode 100644 index 00000000..2c077bf5 --- /dev/null +++ b/lemur/plugins/lemur_email/templates/authority_expiration.html @@ -0,0 +1,172 @@ + + + + + + + + Lemur + + +
+ + + + + + + + + + +
+ + + + + + + + + + + + + + + + + + + + +
+ + + + + + +
+ Lemur +
+
+ + + + + + + + + + + + + + +
+ Your CA certificate(s) are expiring in {{ message.options | interval }} days! +
+
+ + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + +
+ Hi, +
+
This is a Lemur CA certificate expiration notice. The follow CA certificates are expiring soon; + please take manual action to renew them if necessary. You may also disable notifications via the + Notify toggle in Lemur if they are no longer in use. + + + {% for certificate in message.certificates %} + + + + + + {% if not loop.last %} + + + + {% endif %} + {% endfor %} + +
+ {{ certificate.name }} +
+ + {{ certificate.endpoints | length }} Endpoints +
{{ certificate.owner }} +
{{ certificate.validityEnd | time }} + Details +
+
+
+ Your action is required if the above CA certificates are still needed. +
+
Best,
Lemur +
+ + + + + + +
*All expiration times are in UTC
+
+
+
+ + + + + + + + + +
You received this mandatory email announcement to update you about + important changes to your TLS certificate. +
+
© 2020 Lemur
+
+
+
+
diff --git a/lemur/tests/test_messaging.py b/lemur/tests/test_messaging.py index 13b6c9b3..9a9a5ad3 100644 --- a/lemur/tests/test_messaging.py +++ b/lemur/tests/test_messaging.py @@ -5,6 +5,7 @@ import boto3 import pytest from freezegun import freeze_time from moto import mock_ses +from lemur.tests.factories import AuthorityFactory, CertificateFactory @mock_ses @@ -125,3 +126,47 @@ def test_send_pending_failure_notification(notification_plugin, async_issuer_plu verify_sender_email() assert send_pending_failure_notification(pending_certificate) + + +def test_get_authority_certificates(): + from lemur.notifications.messaging import get_expiring_authority_certificates + + certificate_1 = create_cert_that_expires_in_days(180) + certificate_2 = create_cert_that_expires_in_days(365) + create_cert_that_expires_in_days(364) + create_cert_that_expires_in_days(366) + create_cert_that_expires_in_days(179) + create_cert_that_expires_in_days(181) + create_cert_that_expires_in_days(1) + + assert set(get_expiring_authority_certificates()) == {certificate_1, certificate_2} + + +@mock_ses +def test_send_authority_expiration_notifications(): + from lemur.notifications.messaging import send_authority_expiration_notifications + verify_sender_email() + + create_cert_that_expires_in_days(180) + create_cert_that_expires_in_days(180) # two on the same day results in a single email + create_cert_that_expires_in_days(365) + create_cert_that_expires_in_days(364) + create_cert_that_expires_in_days(366) + create_cert_that_expires_in_days(179) + create_cert_that_expires_in_days(181) + create_cert_that_expires_in_days(1) + + assert send_authority_expiration_notifications() == (2, 0) + + +def create_cert_that_expires_in_days(days): + now = arrow.utcnow() + not_after = now + timedelta(days=days, hours=1) # a bit more than specified since we'll check in the future + + authority = AuthorityFactory() + certificate = CertificateFactory() + certificate.not_after = not_after + certificate.notify = True + certificate.root_authority_id = authority.id + certificate.authority_id = None + return certificate From 4b93c81adda18fda63927f94b3bdb80f0032178b Mon Sep 17 00:00:00 2001 From: Jasmine Schladen Date: Wed, 2 Dec 2020 11:46:18 -0800 Subject: [PATCH 100/314] Fix typo --- lemur/plugins/lemur_email/templates/authority_expiration.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lemur/plugins/lemur_email/templates/authority_expiration.html b/lemur/plugins/lemur_email/templates/authority_expiration.html index 2c077bf5..e4ae8199 100644 --- a/lemur/plugins/lemur_email/templates/authority_expiration.html +++ b/lemur/plugins/lemur_email/templates/authority_expiration.html @@ -75,7 +75,7 @@ -
This is a Lemur CA certificate expiration notice. The follow CA certificates are expiring soon; +
This is a Lemur CA certificate expiration notice. The following CA certificates are expiring soon; please take manual action to renew them if necessary. You may also disable notifications via the Notify toggle in Lemur if they are no longer in use. Date: Wed, 2 Dec 2020 17:19:53 -0800 Subject: [PATCH 101/314] Fix the docs, attempt #2 --- requirements-docs.in | 2 +- requirements-docs.txt | 1 - 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/requirements-docs.in b/requirements-docs.in index d04d510b..f025a85d 100644 --- a/requirements-docs.in +++ b/requirements-docs.in @@ -1,7 +1,7 @@ # Note: python-ldap from requirements breaks due to readthedocs.io not having the correct header files # The `make up-reqs` will update all requirement text files, and forcibly remove python-ldap # from requirements-docs.txt --r requirements.txt +# However, dependabot doesn't use `make up-reqs`, so `-r requirements.txt` has been removed completely. sphinx sphinxcontrib-httpdomain sphinx-rtd-theme diff --git a/requirements-docs.txt b/requirements-docs.txt index c612db5c..4cdfab85 100644 --- a/requirements-docs.txt +++ b/requirements-docs.txt @@ -79,7 +79,6 @@ pyrfc3339==1.1 # via -r requirements.txt, acme python-dateutil==2.8.1 # via -r requirements.txt, alembic, arrow, botocore python-editor==1.0.4 # via -r requirements.txt, alembic python-json-logger==0.1.11 # via -r requirements.txt, logmatic-python -python-ldap==3.3.1 # via -r requirements.txt pytz==2019.3 # via -r requirements.txt, acme, babel, celery, flask-restful, pyrfc3339 pyyaml==5.3.1 # via -r requirements.txt, cloudflare raven[flask]==6.10.0 # via -r requirements.txt From 33bb17779d71c387133562d6b74ac826ab4d9e37 Mon Sep 17 00:00:00 2001 From: sayali Date: Wed, 2 Dec 2020 18:07:36 -0800 Subject: [PATCH 102/314] Handle revoke not implemented and add comments --- lemur/certificates/views.py | 27 +++++++++++++++++++-------- 1 file changed, 19 insertions(+), 8 deletions(-) diff --git a/lemur/certificates/views.py b/lemur/certificates/views.py index da6c426b..c72702fe 100644 --- a/lemur/certificates/views.py +++ b/lemur/certificates/views.py @@ -1413,6 +1413,11 @@ class CertificateRevoke(AuthenticatedResource): Host: example.com Accept: application/json, text/javascript + { + "crlReason": "affiliationChanged", + "comments": "Additional details if any" + } + **Example response**: .. sourcecode:: http @@ -1422,12 +1427,13 @@ class CertificateRevoke(AuthenticatedResource): Content-Type: text/javascript { - 'id': 1 + "id": 1 } :reqheader Authorization: OAuth token to authenticate :statuscode 200: no error - :statuscode 403: unauthenticated + :statuscode 403: unauthenticated or cert attached to LB + :statuscode 400: encountered error, more details in error message """ cert = service.get(certificate_id) @@ -1459,13 +1465,18 @@ class CertificateRevoke(AuthenticatedResource): 403, ) - error_message = service.revoke(cert, data) - log_service.create(g.current_user, "revoke_cert", certificate=cert) - - if error_message: - return dict(message=f"Certificate (id:{cert.id}) is revoked - {error_message}"), 400 - return dict(id=cert.id) + try: + error_message = service.revoke(cert, data) + log_service.create(g.current_user, "revoke_cert", certificate=cert) + if error_message: + return dict(message=f"Certificate (id:{cert.id}) is revoked - {error_message}"), 400 + return dict(id=cert.id) + except NotImplementedError as ne: + return dict(message=f"Revoke is not implemented for issuer of this certificate"), 400 + except Exception as e: + sentry.captureException() + return dict(message=f"Failed to revoke: {str(e)}"), 400 api.add_resource( CertificateRevoke, From 5ca0c83a07d3ca8f7839309249e332c028c33e79 Mon Sep 17 00:00:00 2001 From: sayali Date: Wed, 2 Dec 2020 18:08:19 -0800 Subject: [PATCH 103/314] CLI support single cert revoke --- lemur/certificates/cli.py | 23 ++++++++++++++++------- 1 file changed, 16 insertions(+), 7 deletions(-) diff --git a/lemur/certificates/cli.py b/lemur/certificates/cli.py index b3634d5e..1f288c70 100644 --- a/lemur/certificates/cli.py +++ b/lemur/certificates/cli.py @@ -619,9 +619,8 @@ def clear_pending(): v.clear_pending_certificates() -@manager.option( - "-p", "--path", dest="path", help="Absolute file path to a Lemur query csv." -) +@manager.option("-p", "--path", dest="path", help="Absolute file path to a Lemur query csv.") +@manager.option("-id", "--certid", dest="cert_id", help="ID of the certificate to be revoked") @manager.option("-r", "--reason", dest="reason", default="unspecified", help="CRL Reason as per RFC 5280 section 5.3.1") @manager.option("-m", "--message", dest="message", help="Message explaining reason for revocation") @manager.option( @@ -632,10 +631,17 @@ def clear_pending(): default=False, help="Persist changes.", ) -def revoke(path, reason, message, commit): +def revoke(path, cert_id, reason, message, commit): """ Revokes given certificate. """ + if not path and not cert_id: + print("[!] No input certificates mentioned to revoke") + return + if path and cert_id: + print("[!] Please mention single certificate id (-id) or input file (-p)") + return + if commit: print("[!] Running in COMMIT mode.") @@ -645,9 +651,12 @@ def revoke(path, reason, message, commit): reason = CRLReason.unspecified.name comments = {"comments": message, "crl_reason": reason} - with open(path, "r") as f: - for x in f.readlines()[2:]: - worker(x, commit, comments) + if cert_id: + worker(cert_id, commit, comments) + else: + with open(path, "r") as f: + for x in f.readlines()[2:]: + worker(x, commit, comments) @manager.command From 03a758decaec8cc014ed695b83d4011c8da2ab08 Mon Sep 17 00:00:00 2001 From: sayali Date: Wed, 2 Dec 2020 18:12:19 -0800 Subject: [PATCH 104/314] lint fixes --- lemur/certificates/views.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/lemur/certificates/views.py b/lemur/certificates/views.py index c72702fe..56d0a9c8 100644 --- a/lemur/certificates/views.py +++ b/lemur/certificates/views.py @@ -1473,11 +1473,12 @@ class CertificateRevoke(AuthenticatedResource): return dict(message=f"Certificate (id:{cert.id}) is revoked - {error_message}"), 400 return dict(id=cert.id) except NotImplementedError as ne: - return dict(message=f"Revoke is not implemented for issuer of this certificate"), 400 + return dict(message="Revoke is not implemented for issuer of this certificate"), 400 except Exception as e: sentry.captureException() return dict(message=f"Failed to revoke: {str(e)}"), 400 + api.add_resource( CertificateRevoke, "/certificates//revoke", From 18464020704d33c757c0d118138325594c91f121 Mon Sep 17 00:00:00 2001 From: sayali Date: Wed, 2 Dec 2020 18:51:38 -0800 Subject: [PATCH 105/314] Updating user guide --- docs/guide/certificate_extensions.png | Bin 128033 -> 114789 bytes docs/guide/create_authority.png | Bin 45505 -> 136109 bytes docs/guide/create_authority_options.png | Bin 58300 -> 134704 bytes docs/guide/create_certificate.png | Bin 56781 -> 75996 bytes docs/guide/index.rst | 16 +++++++++------- docs/guide/upload_certificate.png | Bin 74355 -> 84598 bytes 6 files changed, 9 insertions(+), 7 deletions(-) diff --git a/docs/guide/certificate_extensions.png b/docs/guide/certificate_extensions.png index f0c3b38f844d2767d61f6a035cf0229ae2a58205..d159e568f18773fd72cbaed3db28168827dd62ea 100644 GIT binary patch literal 114789 zcmeFZbySq!_clz4BBBT?0um}AEes(;3rG(N(xuWdG()Gsheo*yf?JDO(ta3m3JQaaWGduqLx3ypRSq>$fO`9ZoR>%SJ#k@_jMJoLN?ehoS*{h zH@rx`OH3|8@>!fflagZgipeBi#f2ykg}>QD1YU(pROHvb_rp&;rTp5y4YbMK?H~Ty z&7b1uq;Qcr|0XlzsBlw8#RHI7mQ2g_+lu*@)7(2ez?Yv8KOw$yCF5b>$5SuDJ8_|} z?p!MOx<*XA48L+kdHPa0lLqlSXpf{_730_EAnMz0st+IDNq8Qq9dpSQZ$>C?n&0^T zrDRVLLc-;$voi@ovF{}v&Fg!IXJ<{dXJ==w)P#gvTp1H~c())%*fG%HGBB>1rrHW- zDk^yF!1E#r&w>Am-Lr6Zwg>a@xVpM>yMnmw9L;%ng@uKA9`f<<@o@n;xSZT=onN|f**e|- zPa!|ckuh~LcC@s2wzRWlJTLdHdu|Hqr(HU8&I4JT7aX*($Jp|kk! z@%`_|f4=;`fB0{eI=`#r<>dwaS?3?G{`;vY&w1DX7>fUl^S`OUK#N}%<@q&f;+Ol^ zB_#3iB=Hnvq@KIsuZ&-GyD2-=yb(?QSn0us2aQV4i16{HuHSr4ex36L;mzknMDTkE zA5EfXQWu_)KP!7mv~sC8`Eu_w54#VwZ{pspqY}%IC>2MA&nmVAXYLG+wVmkIQ$a+R zm@uePDo^G5Wr9nLet5rrNygo{gpShsCVTgfMBueHet@9Qb#h5Oe4?Mf{FN!X!^86+ zsfxQc4h{|-wyYLPac{%^D$dXM0{;t4g=t8UVWaLVV`EAIgzuS;PK`~XjI1p4XbA@q zR6&0D@2d8V82R|r_#cTlOus2IfNQ37CfQ;d+$+UC*hT~eDL6X@)X3Z^`m@n^1l0GR zR#`mjNENAt>J!!qSP!QhH_F}iANP$Mr#DPG=W7DB=&ZiNntW(>Nn zO>i}xohIu$$dcvj?Jdc~JFE=zE*`Cl@VReh%V1n&(~tIyS(!%A#J|QEXv;cR#yEpk ziGHHRV+xhv7;Xdb2%&V;_)_&VbD@LjkgmCqA72`FnTnREPN|Gm*fh8cqgGBO?Ls3W zY8j=Zq$nt&3iQNFmBhXF%Nj7H5z5Je0wXZp2^icNcbI*HTmR9>$?3#LZ&R0U$K2nK?Yjq8&tnP_!Mx_Wl zz$wH<51v*OH z0^VFgwqq6`1xQvFf|lbZ`*VBE%1&$oZ&vo1-?f#U&NI)K?+k|!-kx(C=!oy(bRsM6 zmv06~f~%M1>1TG=nmA1Qa>HP7vjPPDfk7rCTNZbb&+Gb{MQoa<)aXPXcaP1qRYr z<qWzr~M?(U}|f@gDapR&SG=>ycw{ zCA^E;52F*&CH5LNs<9nse=UBXo#wmxt+SqA7>ZsqpkG=q<8P{di#l|NIgHo4gy`+; zV%F>l1;;F+#n}u4X708a0?p;B< zkrb25O2vivVP^Ku$MM{GxeM{GbV9i!#r^b7C9s>;N8vcfsb+sC4V4PtgWx$^KhG{P z=-ftIx_l_KwR+rh?WFh9#?J2WS`z~YZ+TGOmNSh?L?AufS}XgGsB^a^i$?lk$aLzv zu<&qLM6u7o+^VDQEq*096r(AUV`&wRwCVy03@Ow7nhJa(HIAtRHQYVf;Nb~daI#4( zyT;hp_}2Rq)zrJ$#^dB`l8C)`kmtl;&cLaJI40N{xo`fB0zDwkF(j8(G8t?Bn`*82xy%d#IY`u#$ zG#-(IjAH@MBaT+%<>*(LE?mA*=92E78+d#$l)mbaMoLKR#hE1RtoXeDIyK)ms7LZU z+h}$90IqnpybY{m)e7-G-U!^pxlRs$@jcv#ztQHss9kGVx?Qy+e&+Q_UuQ-U8)Lb7 z`{?90?Q?4_q^$uwSwZ^npKzhRWuIC*35-e~bl6x5E^?Lb@a=e}@y$RVaT(`^(b~yS z3Nld!&!Q|jTxCcYjRD7r#Qswjl~V&lPn-ta7@Z=)%x^x;rogI_^Z?XZIjCTrVqSpT zTR4sBFP)sSd2Jr2b|fn2BlcMQz~n{LjEi)e99RL1HW>3hbxX4~=KSN>onpmTxw=Rc zaY$!~9kUN+`BVeNu*@OjT?rqVrvu}UMA6ozI^wE_ghLd>LvFCK+cli#c4T~0taF?j zJ3&*yQe*DtWcv4N8Ih@0=n*D=3!y@mz5IgXjD@^qQ$LM7YaB)DsB8;c^}ANQ`gWOm za|FBlBs%#?pKxV50`wsqS8CORWJG2sIicNkJ9^O!u#NZz58zNQq&!#?V1rJHL`p>(_a#@upwBpR+oL~J-TLgCl8kH zqv<%O=*FN>a8=nj=ly+g&}-Pt?E7$47SHU{+A^Dw$DoN_zO9R?0Ud)cf9>Z;9fHG? zNfF|1C+k)fxGam77c64Tn$JSldGo!f`zDiX101Ib;x5oA6q!|w{-#jUU#K-n3^TgQ zz&2!n8P+^Fz^0G+;euG}zo(4&emC;vCPxJ<3JX}!2-=IM_Ik2fN1^Fg4*M&uqUP$Hu%GZT zT(x6Xow@DlTk{yKPNRp5-dW?`L@W+dJ2F=#u8PWCtX}-2khjpdP{Rsm7Ul32SH<2L z!KstYqZ7?o8g*O^<9#+~N%~5`ACil5Hw7%j9gb}T$0{98>@>REr<%oGw;a@k>b4Pj zcj-vkQsug0)keyV3p*3U73R^YX=*oXe#tx?-DdM{*nan2&kaEM3zsH$^Q^2j4H@y5 z^_k)jAB{LKdL=x}%7P7f&i)ABMNNXIAaJf4tAWw9t-VRs(b_l5-&@0Ivt@#!YB(lC zSd5+Aci!xMStMN$g|`;##%_KBuhEWtvdnT<)p;xlJ3F~Hx?$!)HcGeIa#18<+vI}h zKaeorl1!rq)i+ezoc9+u)*I3gxgsWVpbZ5mNIeH8dqsv?;84U4Ptr*UocTyoIkOaF3t(d!j#MA~Ga$j42Go0N5=TR)vr8Vfdev4r za1VGLWUV*z8x(dY7V@K%r-hVEMbrlgN0eZdW$D&tdS`xAeW3nKn>4miL_Dib`1UR7 zSvhvF{B7EalS>xji)tHqb+i$AV$goIYiqbXt75asbiV%nT$EC9a>gfwh$V7!j%3_2 zgo?)$j&CJc07#}nwgcAZ8LJ&Q8uh_#WwjmXe3=N=X=7H0iS69 zu~+p}S~qY7x}_7@tc*b%sE?J@jSP)e}s@g06+xAkuP zphsR$H|I#BrOh(w8`n5WJ}LHF2iBc!&T%MITM1C8+{xaF<2sSc+^$Qs=DzW4c-S`b zU6`%CZ_~9zSUiuB4PS7%TGkWj@`5{x^VbqTC10nmdYeX46`tVlc*+ef&QV9u?u3QX zo;6llNr<&+$|g}?7YjkJK6-il=)i8y*KD_)&XxsT39*XTDi)=!YTWhs{0P)#yo0P# z-(4AjB3{J9G}Vv$c|KTjVQ1bCI+@CNcWDu2Z=VXLX0y~qX{6^7F)om=a#artx3WL)g3@b5!D}I}X-`Rl+*-9{QFT3p_?P2u@B4CIz>y}0VqbPyte$X?6Uo=k z4_4>WNC(?OClPN-THvm@s-XqyD(|hGr`8|E3$@Oy53RJKF?!6Q)}ry{*bDpMh^u1* zTNWEWSHWyyN#Bw)>Scm@E09Dz^@y(tR#Qu&n32j{`S_A9j38`nf(<~%X$vFPVo zj393o{edULDHtueD7N?x7IB3P75h;o@3c89!8|wo0KH1TWMD9 z4waf_1X-f8^?H}zSLHO@j5K=IdQJyiP?s2y*7QlslJmA)TlBxkAdomQ&1XHxu&Z=9 z>5Gc8E`@ij_VH|ll{EH1&<^WUJ_nBbtQDV$cxkFEiIoTiQ&E+u)IAL6h^j<*9G9Np zC}aMsZ`PU9_^+=*Vm7} zGMEe$+~l)cy;8T4JMTE|qB56t%~Pq)F}Blv%_%(u8$irOQ#S6bPMWV%SVA`a?kY9o z);vnysXG^cA!*>O!>%bz2-G@Z)mlBcAsTD3_jM4uS}C=(&O^*XV;xUpoLBCYDhGN2 zRtVm6vJc-o?SE0-mnGKeHr}wA<<6ZfR9tJkdGB6ud-kMn1wKY#NZ*dds199|FZBVW zQff9X@Pd?-w6>+e^h^dQcG1nyvh|$NnJvcaXY+indRMvsa5>mq_-)ptbQ zB8xK(NL*?VPmhP4S%1!`sU@$G46Tmw7hJ5;>XbDqeo^IDk%a~O%sxE}`Zq2)reXZQw z8mo7SZnQa}kZ?QkL~{+R;&c~ooJ_CkY=k41JYrhy?SXvJ}xOK z^Vhrvr7i;le9$Es5Dc2HCs&*EoPWK$JPz%yUVyDL@a@{U1I|?f*+MoD4CY4%ULG}z zq0oWQff{Hsv=Yk)LDh+Meb^C8msV`^thdfJ3^9zK(e8A1QO^Hp)R$Y^(VyQm!kJnU zFE}${%b)l}Oz6T-2(X?fIc*nW$hEALzC5V1U-5B`15<4suNC%2!&~Bf-t(6^508uV z7j53H6!HYJ>bagCH<@n5p;i$VptLr&G-SO>-ut1&(`vUSkBD%8EDm8c2qR!QD6RJXRgl)ZcIuC%zzq;>8xq^DfSxHYt*kftb(E1A3@x9y81 zs5%||&F4w1*TLop6_M4Eacellk;a?uGvT!fR)cy`+g1pw{76hiEZ)W3Dm`yc>|oh_ z{!#P+modv#%ZW^tX|N@?}sEdC8fIKO=XK1B%@P^<~Q9AXSZwV;F zN<1Ut=i>C%9+nP%#IA#<>3AhvFDP`3&93Prx8bz)ERkvtW?xCKD^!;`j->bH zyz7+9voyFo#Ori84(b_srugz8hbq;#E^KGTOB`)u2e+#EhwkqR=tPOQ;F-7?g7PvS-<5l z`TB^Mn(EVHT^IM6u-e(`A;W4O`07NXbp>|7K}S_=N4eriZFIQYm{sS~0z*%byt9Yz zNnW(zqcxGf8L*2-C+f+#^Nb4LtFQ5b3q33GTRsA7yVYVR6>}!TB}IwkRThor=}MPk zw$p4IbL!|=w-rmZ<~ml#SKKF8PjVL|)|TB4^UZNo!fQ_MrISvodL!nB!s{rZ`?%$c z^ftatt~cQ&#v@4rjlw;MDi0>`aNGBtA))KuQv09Zp2K~S`gAf>zmsaF z{EDYZOqJ}DGmB)Z_N&={x>lZ_9Woo5JM>#F?=%`=*_XR*tbK4$? zVauuFS{agL^(x%_Ny;XL8p&uBXG`dE^IAqEhz%SSNRE`N0cHHh1J_kiL5_kvwwD#Q zH+~B4=5zvVXVqc{|0n95aqS~nou)UQx5)7L7pTD|+QG)10gbIIkJ^^w*SZ3)#7xl5l7Ktv*U=h5t1hj z5j|6|b=LGCV*d%|V)~Yrpf+{)T5Qpz*A|!Ay^u<&0Q30IcUnlA2o9MiD;I9ln#X>Op>#0Jdt*Xoz? zL3Kf{nw$gNWLk7m^V6_^~}ax+_^?1 zU2DkNB(G_x8A8~cC6~qYxijgbY~GKd>9N4Qit)uA=`&hR!^{}5-65kkcbph}X(ZQH zrO-haJ(Gew5cRyN5HIRG>9V#nG|4&FIm-i{P)!wr>YJw-+wL`wxo`d>E++;tA4?I0 zW{wYKcW?;~yK+?gBD43U7~7Al#plGIcce%bu8r08g%9W3x`Rr5|3K8eCEi0%FNCwEOGC%WxPn^ z)ioX`NMpaxk_qJ~9Us5e#~V#mpN?M5_uoms72#B!H(movT1{hBP2*4Wn-;_qAL7Nr zjX>mw?0&uT1J}_+H`uBZ)3Et{C3Zs5X>Z=m^UsuXSC25S?VfCi4y^vO$dX?vpUZ-` zjvzJ|%0J$5{hnC-unwGtsVba~>^fxaSSmK$DOFB+B$Xs+ZF&0ODH477aVU0dEnnOk z_k`M(MM5EeVJ&aeddSfC25NATft!CTCN4^IW;>0wdMLX|XerZoJxH+Yu~GTM^%+EN zh;xzX)=FVeQjdAzP$|e)?WZxtKa?Cm+;P{bq>?W&Mlxo!JT{qyC4%RKL~?Ne*){6d zvaxYx)H%sRvGtO2+IFS;_5I676LkSB4+i67?1sx)%?vR$O1DFjdChY*e(pWS{AS^{ zDrT`aTtJ!62r#vF@7LPGt58A~8EdW_G0*Zc4HyUxuZnozq7fC5og9F97J8;=h+qG& z^~ztFlCdw&vOndLzZ2;K|JL$g35EB7q@%$tmopzwkBW@U%f7komD`0*waQ`Jmn^6h zymjis_qGO5{9;h2D?cG)q%M9yO~2x^Yd_J?zr|njYaU@EAhdUc1pT(Eoj*Wm|pq!%!!}R z+-4c&-!oSP%-o9;VUfRQP90bf|5NP$3PkBkMqJQMYSrY$VpZ=lO|A~-bes*!M9np?bD|kiLbitMgO1;%!u_Jono=|C2 z!;cF&l0T-gBNTyuEcVDcg1|kw@8ut*)f)5#no<&Yp*}COultf(#LJ_~p8XU6Kt=7g z1czdpO z0TFcZ+05;~Q=^H1%p^&DzaaO&J9_atqlHogP21n8iA<8+aSGijfAkz^ntTMXGd=nr z{hbQ5C7?z*V4nZ46GGAhsIE7wmG|#d783F*QwsjPKV}4IbMJkiI(mWdzf<`X{4%(r zGla?hItU`^f$FwDI{cC>{~qj-3Iul(ozrZ*lfDFALzaxgvt>3YDCp@|_dInP+}^K9 zlo=&W^eYDh1lSxc50yrbIGG_cWl3|Mcc`h=t`77Tji7uagvjpw!ZM70l7qJxEw(ni z28(pKyeGZo0ET&S(8?Wy+w25&DQIgaz`3|c0cjeoQK+d<{^}dReCkrr(sCHo!)jDw z*bJT&JkPi4+LLd)YFkN4b$XxG7;?yLp@(=?w=z+!#0@VBj^WZ96uU_J=Lkg#07s&l z8#i3}#a4fx*z8mbVU&=aVZJ)Nq%%=O&*ubCPykPl?bUJCxA(p63@!M~y$`nm+w7+v zVyLjwd`w=N#}j}t=9=SpUUo5pPGr=_YQ9)0zJ!93l4D~d&r2xfd*e)NSS&!bbdYv6 z$#=&of(rg{Um=(Gzf+n_(N5Z4fTb7rO5of#NANe~e(*Y&leg@d7R=YnDkom zI_Xjicznp+yYKpaEt=)~8<7`*DQLail z%h4|G+;2dS4<{~cwsJdB+`EA2A{KC~XngJn7$EncBNehf`wjuehsZ99n{>>w!8fXh zwzs+@5@ET)u)Y3e(yNziaNpY6kYnynvw;k)m@f4^$OX|1kuuL@8GSXD!cz}>gWr=t zmDr5^^6tB7EKjt4og;Jo)`P9o)8$e*dFWQ-MCJb05oe;Hs!qh5@0r2NA>FY-HAgHO z8ec6kQ+ReH5xoQE%7c7Mp0ZA^T3h$KBLeFbQ)3u@Ln5IdA5KoqJFVmj=eE$qtu>uh zU|=i5cfWML_Fd^|!{ymF6w4|d945cF^*lGNBf(KBnEKVx*4_qpQc7j+$klQ9C~P~B zIFwl_F2=5jnweJ6CK3`MKE2x4nGsiR+=`r)VCfhv)&mTZb^TW|YlQ5l`A1tx%p3yn? zIiVjgt|05%j7`Yqdwi z8%~gBLHnr}Jx*5Ce6#97;o&vN<3Ieare59pR6FjS8#rnz_^6Lj<+VVUpUR$PYAE|% z>VfsQy|%}eVTsYVaB82v63OenLM2p6oF;JQp#-^>2aBuI(Gh?tRk0=D0?x|9;^WDc z4(e&M^%Rf8e4WNSEJ}H@>ZK5Gc+2r4pW{z9eB+?%Dr?Wu7N-$SYkMr55LErjh@hGbMsS+c2yX+!D#V3 zY>lb^kU1eLlID?T&g*w$up;!TE} z>#{aaYP&RCPSC2q9oPDCroXE2!>yB05a_YTE!?feQpf494z>9N7cLK*Hfo;anbuPu z?K+mmuQ<-M4#Dv=#v?l;#5{M0i@`s>@6AtCJ=)8}zxRu@JRjSy#HMNf$w?+pnsc#t zE!5wd1VhL(r7-&>GbX>kiQnuz$kOIF*P74|-=Bcne=sK#oooWrf^sFxj zp{Q?@QaaAI%As8r3AaNf3G9wOi8zJaO5Cckbc*+KF}suMq(UgZvSv0vMu>X6lDH*e zz`JAUbGoRN?2UoDMx=-Dh@cqYC4u1-%bofxFi_=3ialruMhlxYeCJj>{CRx9!Jz8%)Qa^LGq#kqH!)s$Gpa^3MdZi(PEl1%i0zQ z9YZWO-LuEGujL)! zxc{{hz(6AdkW~6;_-X@&+qyYdrvl-9l*kLcIqQGKP(_)!@Tqoy#jVe^(NYHv3p;6; zo7clV5#{RzKIkN})*5MswuUa|Ha_m%$}uFe(F|qyeU4sYy4C%HtCB!a z%&FT_ox+H~dV=5(0!kg6OjQ2r*+fAP_LARB#%l-YOjo)!7jN_AK^H^TsYVHbWpFFR z+|9YQ#+^QEXgO46YiyO%dS0c{GHs}khb%&1W`l2ws=JPUt!oE~RmkC>b++8K^ zx9^I3dtl;Uxt_Z%vZ*miqouO`Y%BR~07dcF^XN2adx-92cV*3=HFjfteAkXQ@)&HQ zuZeB93%{BYtjYAUkyvIJ310I`9?mrHwNJjbM(<=V}8B;H7aYc&YnRU;x zU`KkBA7GB^a$MPWr~}q(j>pc@bbr@P8g>AoMJHC8$$toVn>|2Re2)6iixl3r0CLFf zN?^g%LZb_AHZ4~TeBLP2x2lqJhYr>c>5K=4-FF7?*M3I=H`Yh z4Oue|84Nvomi(7*t>lYyklpNkv;K*t^7xK18JGDkD zo5Q>_rkf1WCV+5)dH?wAyK=y9LHlU^{()_O?JDo2uY@Mpb@d({!{V&1G5+rzflowm zzj@_7_0)uK^F_h^UcUv5-4lhZCqttyWbZ_g#u4J&_YsGqw^WDW<}s|$29PcL=x!&qQ#J$#h8-1+fJ`ONB4%@wlSX&w z#nR#??DpQra%k1#W19V6&o%lm44+89^J4Gm>46E8O9TYGRv})0&ImyX|3MNw;sI2e z!b$TJjpL!HrjiHAwOIya@d?ceN;b+ikN4y%Rgi!$Auexg2604RWZiuP8{9{KAxZcu##PH}hrw=3)sk|Qb4sGE$m=UATEE&fGK;0vn?oauH zr|{pR=w2&7^d2-~{z2Q&q?<)2Y}=Y8Jbo_^lKcwJ$Q}ao4h;!Y(QGHlPDzz&kwU+! zNdNKjCF}@*anUR3;@(LOW6R9&Mu(YY=D@}9#ln@5X!6^1qHfIqc&qm)*4;KF(74CV z#)T1LQr@I6{Fne>-b?*C_J)5bb!yBR)PiKgyRx=%YB#O3mlFD)Z=QsS3vfMUeJ_dd zI#_vgpN6P$tTMjJ);n*!$!+6aKD3_w3E)d!kREq4wO9>fQaN}?}NSY{Hj$$mtQQr*O4k*v3nGC~? zsMFqb@#x~tqAe%-KbqIeo?&oL;7cxkvQPSs)?JIO_-r{59L6;=LgMu4;kLJ2u5#)< zR!BD1Pq^|DyZN2{l*TZtc~;RqI`rZQ;~QoMB*yGApy?XjLN7g@e_@kMYrJ zsTkcVXTq8igY*~*W<{pD!;7oF-4L(Lk!nCrT6?I2^vrRi0=w!)%o&ui7LmJM0S6TH zX_FA!%$X%;Oel4qN^V)?wpYFuKrt{0wf^a~&aLL3(U+^Ay_fc*wzw+rDnryU%fs*Q z?|U0pREe1OnF$SBr;0=4s4+KfSSdR!C${Db7e0Z_ZFC)X__uOL_`8;SLthk8yHe59 zr;XjU`Ari@;`!rU>K5Z8>=7`|<@vm84rqO<1xZ^s%Pa{2CtUen$m&>~?Af36gCyhf zB|wO!n!jI(ee-5E5^#hX_D(YWZKwmJNb@&l$-VZFWp}6AKV?cJib#Ikr1E0x+@EUn zdFF1IgP7gwt>1%=PgIczh(AHk7y8_P%0GR5K(0~^ZOz;MaWY6UCZDqg|5Grqw}7E| zV^X<1=g4!~DrBoIt9jB}%9$15j~w9p^~4FkD2b zg5T_ld&miVD7yWiNAGT`WxENJ@H|%zcGZ<_Q6{laKWG(DrL(BC3f!Q)sNQ=t9D z&YxCFuT_*sS4`Ev9aYF==O)GW^wYk3&DTFckV#4NkCXR~oJ)~6c(hPFtY*r|Mz<}$ zP7;hVtAT8O*#m)QRwVoRL=3D|p0X1`PouKwnl3Ng7Oa;!jE!mit)KEKNH(<{Izfm5 zhRMVJ|0p_&2%1QQvi#i@;K_d**jhPqVa9)_DpN38Aek&6um6Nrm$Kym_Djs_&flpf zQIhg3sjPbG^XospR9NqEvps8g^CmFx=)~|Ak0I01wUzi>A%Wj z2vZtiukQ0&sk{2f`>^Ux2$<<$lM1Y*vHJ@SQ{~`EB}cR&%urV6kvtUuMy%CDVr=8h z)7&ASKYt#BTIviVypxM`s}%u1Efyd&DQb9Fd$G5=5}K*J$fuU0sNso_1H=flW7_jSX$x1`<;_NXl5u=D57{mIVs-}bz>W%uNT!AtJtoU#*MA;zpA!CM z@(%yEFnLKm8*-wf6N>j5NS&sHyFv_yIsFdsR9yk?kl&_hm zw*TjjRr6oI^!DYXz}j7>&G3)@H)_WspvWgm#MM@(!lYcZXU-uJ3=I}NJ0?~8`1Fm; zlU4qfu{%1I9@R0N8j7P;w#Kz>U%$4O@rcKh_d!dZgwgQ1e7}*eo>$VDz&oDi00_>_ zgR&3j_IzYdmK<}xSN=ek9ZP78PNn%M*dcd$0zjbIuf8erISpRXskKezx10F9+P505 zo(p+@U+yZ>WypX>D|t1V2G0u6Q$m!}c~xrcFf3XFCD7Fm?`33U+PfsqOe(xc67#4* z=JE)ymo<(1`)-MQSbfY*(0}m!i%}aJOg*`e#XDB5v^Sj=X=MZz-Y1U24xEb9uZ+hq z$XHgRigAYV%VsZqXU*6QOOoIUgp#;X*AmC=cAscyaE$uAm-}Z@#U2WhmV;9RJsHq5 z5ASDzyGg6D9{^(mbw}!+4V6BMfL^$)jR@zUmSOKe>jlPE;`dD89D7Z=s>1GlLt<7w zR2scjCrf}NV++UcH7a!mWjVg66+V@zB6+fwGUit5Uo|G=$&Y$blPB z@qau#T5DRVp%a0%mw}{`eXQz!Q=Td>a-hrdg3#r9Yg!DWb&CXPw&z~S?(Gxam!I9( zbSkpFj!+Lq%3i*9_SnAenr=p19ZCl>WI5wi0K&hlhN_V{X5<2w?)+C5g27MsPmjub z>zt?-_vKk#F&C=s&Bii(4pgB%B{6N8SFOG>nmtVsTj`!irMPj2vqg%n3+wci$iP#1 zo$^k~ms1g&fZE&9-t3kHp;;_SRK^69bk1lGsT-M?*!#E%7*>sZhFe-y$X!LWR^SAeIExWaRO30dTu+FwnP@g2OB9SWQ zP7^#6xk+VA$V=ARFY{WK^--TqE-`eeXeg`Z?%fY87UNu_1JyPI;9ZKEVgs{^w6@Ob zxw0Xc=;2ev_*U3YXg(D{E`NZTzu@4x*c4=nq(pSz;&K#}zHWn%sre7FD;<1;?cT{n zuNSY`$-MYqSoJUH!b_wg%zHxhBUV*AzFd>I*Cn z5(sON6nFELi~^q=HQCixLotvi;rma%$ConF5TO%6a<`IgGQvapu1o;xqjD|!4NrYi zBW?HD{kp~6+}+{-YLDeJ*c3nLRC7xvwx7?WJ&%Ge6|tdO8)G)EcaTBStNTp)L~Eq&P0;O{35xglW5d#rG9mNE)J|#pr!&}J+=?$(ZX5LUb)F;h=#Qctb713HqHs? zv|P?5wLDnbp)g%f5lm4f``EA6wrv@&PBxKwjUh5XRw=3I)n_qTeYNi<1W4h)f6PP& zWZKG^wfJZ9u!Bc^%iYU8p&y7xY05@scD*wMmSBo0dRCQyJ;HIW31&cue9Q70s{j!X;fcTewU)sYQw>}&7U-U`WA8vh{?7wpljM|tP|owH(L0)-MvBPysd-Sv%_G zeCnuvD6+%9e;K4xeg7hC1n-A-KYkzCM(3kXZ|MCX8hh$(p_V;UNRl_oL}sNeB=Te5 z4N1{%B3(hM{LM%x0ffs#Oc))y;dphRBosod+Ldp>uFeiF4CX&KIB&I2#Fm3uzQ_3kLCCw1QUgDDy|V0WM^l88%HVF_O10`EWH;UaG?ujf)k1Ll-MvLZ4J^RXx z@ODg1d@9oxV@V~Sw@^;=@PNGzZPJ>F8s^5CeUyc}(DPG9+~Csb2*+-sxh>;WfE9&@ z-lB7v!1m%jE&W2xntPPG+^e8oWg(=JiYF5iE~ivt;a4l+SVx9qX*E@C*Il7zyteta5NfLs~@rsIgjv>81e7y;5QmBvH>xonvMf%W4T7V zB2~WfPm)Mf>%~T7mj()XNN;u4?!ZNRP|9&?>f0xdS#6pqK=>B_0eBU{O4*}4{lQzrrhCqrwtvG8>>r4Z$p;B~MD+BHFzx7WyOD`k!*k8r zxw-UYFDERIG1PSwv4$@9c@DVtFl+V85Pr-u+l+i=rfm4w-gOlAqyLbm%&I4mvpRX^ z;8v=o<0Lw4-lvo4;k+-HI;aMBgYGDovS#5*D$U1bahLABP0OAj1O7)lcZ{%ikgPvh zh)9hK=&REm1zNW=mf2siFj9leQu-VCUJ_g+8?M5<$P177zSY%eQMxn%+f%5u9ml~^ z!=3>lIx*RneP(QCYR-R}Ti{Wh*Kla8PCx)<1t=9P#^O5eUJFRgWV4RLU7UGql}6;h zEYd%jGZUK0Q!0}?xw1yQ8FO*TcGWZe{L=do!h%2?=#|r15M_~pDWQ-zv(yKGY{x1! za{KwATm_ZHQfO!{EiloiojHHLX5QqUp*v3Wh(yZu6A8VVx}xT%&&1r|#uK#4*@&OY zYbMkiW-jyyg}6(cJc`09UO83rn+)x)x1&c2F&z!RRavzsMi*nMUfR(SYPlyv_RuBn ziP&HzZ8m*rblSpgu$ZB_uP9(Nr(V`-uE}q51^Ym@tm_Tn;$Uh~Am0MRb#5;8Z{b0G z8x9`a#h#WU1vN>q+WwUUfCR%j1QYA$bD1wdcVvcYSbvQ2e{>FpY-UnsExh5<-Hs&z z)8_QesS`drk^4nMR76Wg9u$JSL(m&v&rOFr2vFibt}e`?&ij$GLimxcHLdWH%91sc zzIyP6yhliQc^@@>YB@9wx3B{??h~yQK_NceDsnSK21B#-`*9oc19C(c#(rnyQ4VsU}P##?^P7yh1x5?%}Ch zHb!v$(HgP)tX-Gsku}SytHMS;fSBdW{OgC`lNaEk<(cn+P4SyUyGGYH;><2(bgpQ zRV7PdBg9s^ywq#NEMQE_D+LVLtgb142-tKn4G}Zdr4ikE zSDqXo7ba2OJ9Y3*x>|E?oAn;LKkf#hbe|t6#MBC-Se{10SB=aw+uAlAYs;cEOpg>= zS+R*p!%wc6se_coWpaxAm!)7NC1qOmjepA%qjb(JRwWl85=7fgw!;&6-5pqzK90+T z#Fr9Z{kehcTP{ah!e20O3B7B6%a*a$-ACoF{*&i@N19d?U8 zs>#*Sn{2d#MYTNcyEhB~haly|!$5bc^@Ao-eIvz_Hil?Z;1Y(kyme$nO{3kU;ojuw z$HLOC_ih;@1v&VB-y@m1DlXaG7|GB5mGt(Cc`FbCv&g`6eX} zX~l8w`hoBCnwX49RMb}!E?V*{U>N9m2!v6I2nt*>5jA9ZCJ{0TguJn6Uy45u|6hCJ z&GGW(%ijDx0j?LZhEQiNWc=LfrVpD2J47^!p0 ztE#Jv1)}#P&mFk53^eqB2xU~A8FHFAB>RPbKyTFuN^P!!-Ime`i+=C!i$0HgQuy+2 zXtcRBfJD0#UQ-?l*zFs`(Ge0aUqeu8w)|Izk{NsI=Fc=wS$)rT@>WJ0l?pV9Z7aNr znat5CH77tceMh?4I*gV5}!EsukAizhQm3>ZYr8UUvfMf%14NHRYP4L*+Z z`!d>8sF1)F7~2!fz#S?Ud)8C^KR#T9wpzDtk2tDgL`(q_p~BL&vuO@mB9x&23@O09 znE3824a^~b+^2+2mN~q}h;4ScZ$Z0nnFf5xMcJ0^R3V6s#5|m%O_A};;N57c^d!b5 zE5P6C+*Xw%bL1=w*A@q^9B};iQjoq=B{3s%+~B@rmtijuy#fTZD!XswU@7TJaaU;` zX=|3~veAX5n)h^00{3jx_~&3@Vp?$6p1bY$s=5E#?M+7y9$o)=Z~y~xdSe~Cr*lR& z4~`JA87_NYg~$qn{^;u>Mi$o!MgxJK(z~nU(KdxNvzAjibEy;Fb74c1$~DLj#P{u* zcETGldt!Q8l}hI}CEyws3&1EtExf7M!=0o%-*txZxq7-yc{GyULAH5-{UR%&uHG6> zXI%M8EN#iGaCyf<)Bf|d8ECU+hY5ikpt6Epy!uxez}uiBVd&`dqkQ8jafZXU{mTCr zd+!|-)z*EBDiQ@GDM|)ON)7^&qY4s5$yst}a&F04BqKSCpyZr$&Pj5Uqe#v|H}DqU z@q9iw$v4@-LY-h1t}*P3(8F~$_Hkfs;2L8>rLaUVzhn1DBGu_nAW z4@`J0U|~Y%Reg!@N^E4{;PEh5hK^Sa?%_@?Y`W$jEaiF`Yr+8Uk}N&ahG~fe zh5OIq?aOS^#>} ziRy18tQ%gQ=mtUTkgLmDu~0H$mX8d|k*D*!R-K;5?(58nWW)f;tQ*-JlX$AG(n}kw z8EI16sO;Te#gz?cKHQutWsRQqvHBuF#M9so5ZkHz_O&NK3i%JhC!xR z+OV%T<1SIlTjvwzOHRra7No=KvX-i&h1UUpQC zvD}1E0jRAS83+lM@NFlZg_2e8PV=~ zG^@XxAuL6}GzSaulfb3R;5NO?1A5{>cRuGYM4j9(d!ipx^E+;ZPn8<;2TaLBV*gxd z?swsfY5+AZ(|@^ znRS9ss!=5$Zmclz>GkZfHd+s6i)M0mY)cV*&xs|FG5b8SCg>=4Iso6XGN)IlK5c+* zIc(BAo>qF@iG9LBko+B)@zty0itUVc{F1=w&u@BR_46fKJlnU0|BfN90d`7VB(;Yo zxjKzrSZ7;y)l2V*0juFOVWaOunDDq7x%>ABny1qtyFRCAlUQ*^L1v?07RS5wIyyJX z5OeL_F;i~cTNCFyuZ&OlS!c(k_${jzpTja!3bpIc=lW|mr;mqfzi-|u!_0_zwKi+# znmUdBrgGy!naknYv`F6TY+nqi8vBj46ly-co`FXjQ){0(p6Rd^bar%fs4>=F^*JSItir_}?(3l*QG zLg&$+rPv}QwYNPU@<`dWpBmo4REFcpf(e<8F7JIzHnNQX+_s`I5BRZDV_5&leFOQV zpSdoBuzq}e{I|vxNdS)TkE`Dk8~J+Xrd4?=NHS0?4?L+**#L=|xnm1uKoOn`$u{veTZBH~noXi~3-}{;K zEk_9Ow4$cKK}ZUn{}hLk8)t-<_5Coxky#6980GtH%K~hn4zumQ%oebooVd>?+j;JM zD~JIo4I3eoDqFSIpY?4S!Y*4;4YM8Lu=r5-a2LFCM=p@s3d7tKbjb5Lsf{G6vmyLJ z>;!g*<8=XkL5~o|g1c^lO{-(9gMr^@O<((zf(m!n=UB}I0}7Jgr`SRZ_~lt@Rtw7= zmU5&^8T#y#q|x6>>rFaHmk6OmTDph(_p!Erj}t*KngD`PzY~dSir-h2sx&|jV)@e9 z-T(WyoBZfNeLP+8)y{9B-c4kdM*wbTLOcy47fkr7lD+HqM+IJF{JLhSKG>=q(r_0( z>+ZI4s3(rEmE3UT3Mkko_4exY)fu}*8l{dQTl0;=!#f1@a$Ud|Zr0<~+GkkGGg!m! zWd#S=)&_rbEdkF`gcunRh?4xLzvd<|&wq=l(dca`zou#cgE4xdC)P#v7}#G>vCmbn z3D<7vRhCT3d2xW$5c|Z;K0p7HsCueUz2U&jl%tl%_ux+W(FVN|OYTDg`b(o*qE6Xr zUlc#*JTbNPnVDK+fpcsF<0Yv=71y3x-nmkk;AY8(-vjyvKujj#ps`tMKgIhBlg?sx zkc(F~2kLijUFetAR@>vT<1Lo}Y!Zff_tOwys6@L2@aG6XTUm+dc zbnM5SuW!DV^mjRY-}7{Kg!TbHJ?yT6sto@;wbE&Xq8r1tJR7q7`9Adh&XvKQh}7e# zSX102^uJ4a*GUIW_^X?V_<)8`tm9kwBD6@wzLN~HwZ7OIaBV5LbpV8)_byH^CNUJV z9m#69C+6MDZ^lIFZJv$vUb9NCqb`dZSs!CqwBBz12s5KgJh7ZVT?y9H=^-hkM>cl_ zB&QF6sP~54z3P+2Y>iTuO#BvkE7EVl5qc(5c*M=bl#gl5hH%d7KbLlb#=JYMHLPcm~t(j;7Y ztLd`t3e`I2APMHpr(757(O1x8E|-knKF^(I;QTL@py-Lj3GoIgZhK-DeG@{{}_Yj ze$hr8_wO9B?+-2MIXFh<+<+5B zX0+PF(J1QZb=ncv@|+@%Hq` z`-JZ2W&8#%QNV4|ssJpsI)u#Xj~srCmOES<5|qTdafH*Vq_90!D)uM+i}JdbFjz!y))pi!*E-*_EI;`}ZLE5*Ay-}Vj8ExE}il*>%mP3IeY-d!9^!e(v0ucyY} zH`ukCpBVoUI<8n@q4w3qP*$ztU3^*XDfw5G!iMewNTtIQ{qeno=NxuxA0$*%3oLm5 zQ#kDZU`}$>-N}In#&g_CG}BT zZnivR`yOPjZmPbdKr1D>K&u9jr5*S#^*cj@8jNMLwxMR5zco4wrpMg*1(2&Ale^AV)jL_@Sv{b0!(Gd8qgNB)FTSNh@L@62AulT*%cFk))Gw~S<2 z;KtuO0IoIy| z!3ZM(Yy`vQfX>gqy&#@Veym_C{r}$&`x-2puaB@=|HBCT5uPMO=HWHZT=@@QJA4)e zKqj<+w-r>CS+>$cuvQ7f0Ab?1`X?%61Wnpa*au5SA1~ME^|#mibzzMYE-=YNE0ETv1I+*)8rW$EB&jb6pAx!t8BD%Et5y4bW>L1H96|H`W{c8n|5RGAe3gw&{q+CN1^fQYO%EPw&+J6sk zYj4kTc2-rbS^=)i?H5~;xKAB^L<5|RQZ3XQ1yf40YwC&=KxKxV17wOB&ii*$^}tJR zF;n*H_6rHg#g=C@j~;bZY`dkTrRhF?^CcV^E%kyV$SJwb2rgVX z=q(Jdhn{v_X}diGf!)%0?cqS}ir>19txrK!)l>Kf4Zr5b=e@D5FQ(=H@zO(2 zx<_fkZ*DUu4KQlkTNQV7lwB}}=V$7j=k@bzGu=aWT;*?3<3$my(8<|0?fN)3Qt^q(lC3h5_c zzcbUc@nh1ckeS=Lhq+_9P|!eJFfy;j(ASkr8dp92{1qU$^e{5g@=v$BTYq44tiPN8=1Zc zMJV5n+fqwys9$Z5O^J=?G=gEpYv;zq>bO4x8O%<_s}^Km^(Tj?O+KgbO!|5RMGefc zN(FB#0}}cU0Rq<@SN!QSsMz5fdS%Ndnr)isej#cYhp10s>8q-$z9*7^-uN%J;T5b3 z6#nu!I<;B#drNi|<*3*N5!Ze=6?r;x>wU@8=E{XJk#s|5-)cfOo+~Q=sM)LpKYOKu zkomL4R7r_jr{lGH#e#>w-`Qj@?XyPZj-^I2xtqi#*VKFXPOZ+hmHBLe&Jvo(dC+K% z!$%Aj;`fd&-zwzeEzLmW7YiyDTDI}5KmJzCP<^{s^p|4BH%-2_v>$F)z@%O_WZ(KB z>in3v>gIds5~c}Ni@hO81XUyX6S&=S@^l*Igy8mHOce4y%O>(0o@~V*98XZ^br)zw zoDeze%(SbUCxawJj{Mz%DACjJS5y2rdyjHhuqbMd=J;>E5($4;fB&l@3eqE`2o|Ng z3LBK|L(qG^L(o^0M+}r?H@}XEx)xqt$Z>2MNtKY4tl)GzrO?-waysqIzz48qtOlx$ zpG$tr>MwfPfBCfBJo_V)y5gL`Ga%*+c}r zNFHSIj3h--)p1#{v~p**@qQqwb9N|&a6#h1D!i*9a5U%m>wA(uY|OqqUOQH80h}WA zwJt$-MAtk*veP>y<+vRNjlqi~L0OC`0=nWJ0K~484ifkD#TWS9&ytJ~117H9h3AJ? zNh*aZ(`6g>f?^bU9$VA2hie1F=Cuj?H`EUY)=1I=ixezsUAGff*k*EwMg6OxfZ7>l zzcJFCz|{zofN6hw?(3wSqbjx8{%#Psn*ZPsmh?pa^`T@U@YMBrjf`{H`GMSuz!KLY zU)|%gep_tTEu99cMZ%xxoJ_AV^&zc@?0k(%liY+SmTOi+7p41@x@qdeSa0xb14J3z z#UCi;DZDz}XSZ|J-Scklf#*+9u)G6Z1)fW914jWt3XMw0*!*g*3R}7dvkOQSoxb&wYK_$dAwpx7KfBsX~HWc{u5AKT9RH!RF;NTjeO{vvD{{sh2x^Ps+TXxBOf;5UduRNl09|NH_Yl~3U&Pi5BkDN z<>l;vj+a2YTD~2-<(`dpPt0RurTrcrF+BENZ0~O1CmoxU)^qjB-TdP=iMCp9>Nt-? z!>7f?mZC*r=}-P45FFBi#FJJd=oN!UDng^aI+Z7{uv-CW{=Y!{RNDl~0YS{%Wbdin ztSYJ%RSQ-Arb)h<{|meneqxO98^1nvvd9a1y^*V0_l$8(am`P>v0(~pvP6OqOFDkN zCFf($Cdm7uR^gCS%#)+;*HLelcw9`!o7q$gjqB)&zGcgsc76J20jwG#Yv#sq3@&_h zn{K$R50EYCw;*&WVi|V}Z}*joKX0@(x&ZpsQJ=T{0pk8GvmRRqDwp0E6KzRf_Ka40 z-1B&n$5@?xb@y>u~7sFq%r@6Uro%uig&=23#D-MoxM5~%{{ZN|y zA&(BTK4kRE8t^;(c&OiB$B`LLVYtRk<>Ip%(nK|0prJ3l5jwgvDD#L^j;Tbtg@j#K z*8_qfV59s~%{l>9o?HS3#EVZzC_^I}MQ*wvzK=!k+FaC$?jfmBK}~qX==3J<`=127 zU{w85guL?6+f%E`+DoeRs!iu5)H!|N;xOzkhuu9qWpsYC5|_1}<8*8s-$AciXm12G z7=g;uss-)vu|8vaLwWzXzY_tZxw`e;GhaPa!?^n=5sz`g?yU(oShe6TCg*Bazb8G$ z+%21@cuP9*T-RR(Nu)@ShlpZW8$N-rE0n}li34A*`eGF<<*HbkWko1wFjJN%x%lv$ zZNWGGexQr33H6%OlHRkVNt?3dy~~k*UhxG8&BCLZp@1P=i>G&5sYR)L{jCc@tBaRm zI}IuKGB4&0>y-D*^ujUWJ21VWYk>c8MPvm{%?wJLym6)G>UBfqTAgvhweMqQvF?a&Yhwv?QCFB!H3Zfqw z;bQwtl5MNl3($L2b(OtkSe0gd)FFlqsHcFs3?>iye z=Xsx{HP>s)qsZ1!C;7fowk7j%l4{G&r*~%|m8_v3hy`DwEi2_Jv5ResV;8s0z1pjVh9m(8#o%T}Kp?Q~hO|7{m*WbPiI?rUIyG!= zIjbR?Ai`f=m}Kr zVywl{ib#o{4-+EwfD~q=p870^8}WVQbMAX?gUBQ{nHh3oz(6 z7PrN(gJNMQjTfE{OVB3sIbt|@Ge`bRDNGkf(~z{7r}hsU89fAp7jt>*{N*M$vjd6P zGg$e>w9cayo_TvNj2CZ%FOs;>_oh2ww@X7m348B*J%Nw)2bb@k`x6_@CCsm`Hlj9u zl$7*7bZbK|dFOIyO0-!u?hth56vsMMW=iehV8BWB@im?Ngu&Cvp-(S(JYaY&fmmO7 zg}c7GT^V*f(dc5Ht3@rO+zK}8UtJ4HJh$XUbRar~)=-vDsAA%T(YVo9nIHl|UTT?L z4eNA8+nVx!hd3fgdO;#4L0q|m5i-Pf2HBbQdPq(0Hcyy?j7O4S*@rJmA}hAlbJN7v zI+og{>l~#QXvM}~)V1bcOpuk684 zm78v^!GIb~nrwQ>PWLzZgM~{U%Jut8GqWAMT&!6Y!rAE~O$tKj9C8o)zG;W6$u`wJ z?Yo7AIT12O=N|Rd|hXQI00shX#QD1+xcgFK`far+myVlmW9CCF6~^7`0suF^$!s?bcHgM zTZF-p|NessL7E9BWJ!ShpFRDroeA0J#xo5z-Qq|8{(~>~&G!{UbOZliJxPi*^22AL zOdu|G`pSg)$4H2%KJ>I<>L}geI2~IlAS@=wXG4D5E=B2NrA>>8PkHm7kMkzFE@|+7 zUM<*zwP@7BG%#phrYINa@KIM@)k}mWYIK)y{PS%}FP>*N$hkl0u!pugk82Tbd}eo2 z>Ts28N=7CZuA}EEKv3iC%tpqtYFCw-jX(S2xmnVChD$n6Qck{Y`>HbVayty3_2?1W#BOa5_7;Ea~k zBExIk(RqP?&R|dE8F|l){{Oj=KOV~eJdyvisf9ZR;qohe54@qN!zhGf06He!7gt>7 zB%dnu5%{rf*d{%-Sp~cn8|lJAoyM$V8ksoB42htOUK|RcX!z-_)X{f#8tpn~OWpz4 zn{Lp9rVR$u0LBIzWmDwj z77@qGOvwnO{NCxkLE&{8mxH@&q|Yjqs}XJ|TWZ%Cc$w)pIT-$AC}0N0RM{*`Ewu$f zo_WLMV4<3nH~Eov8alUf2oV}CKaL(tS?rXy1w~En&|jUVOXjH-_owbQ7LH$n+J7YU zbmwIxja0r8i`${L4FJ2v@sUYs3pD*P zhHQ$L==!FQ2k9sC+I1+8B~{PWG|WywEH)pGv;a9I0(88PWpN-{RS83r`;KpC1g~*?;+?Ai5 zM;G?k+;0smi6x*9^-x=ldSAgkahwOK74rTzpu&K&_I}}nF>b8%=T(Gf?Jm20dtiAi zKuycEDyt^cD=aP#03I{_4J3nSF#m1HbcHLgM{`~5^C45vYmCs8NE151#5Bt|Fx|8L z>#f1XN4nI)w#q%g@^c(a6;^SFL(0j&TBTk_azknqo|?4@A`4gm4<G5 z3HBEi!Aa~XHQ@pUaZTi7_TH{m=J&>K?_{WvOH>ilTKa45~| zT3Y2{sCkALvvW^nx|ieEUGCK&KOo;gsumBp)3ZS3Q?{a_QyvXqj_DJ=cPm9(lMS*g zI@L_Ojj^%-X39apcOBHKOw#?4xy(=eB*F-_950Hc9d|Fq72|OmevFw^rZeq#LI?@ z9g;KnE&-h;cSG;C#P=yy&MfJ84nsqDMZWFEf#Ks<8JXaEn+V@SH^-UPir>a33E4dd z=7Chtg70#sn@Sx$2)*cuU>yP^hTph6d)%`f++a2O_cuu_~PtbhM^siplfEHYPF{O z2{A*x>(v)Xwe`L?Idr9Kv1V{0++-_3G! zm5-QfoGp~9O$TAZjyY-O(|N^~jYeyf#HSSth!l{YV91z(zikb zC4$LiQ2;&9!9rV*8Mg}!8Qb?nhB}n35>GizL{x3JREn($TaKSX=v^Aba~b)R=JtqxOoe2d#N@VJC!Luy`05y;1knng~CM7a|h6>FMqdZjIl;o=yI}N`n0nI zLwszzN{DJDg@gqlrjh5^0*1Zg{kEV#$Hu-JPrb213ZXkXsj#~y|E*?At8z0phA4Vj zE*wgv%U#sdKEO7$zQF&C12ya#5tnM?j3rfnQ`?vDalPqy~C{W6?o{v5tFT90@BMEYJ zdl>g}a}Cf&3q9+2Khm+h&&RE|^mG;yjWMrL?;2t-kn{|gx-iFvtQ+jk33m9Lq+pRh zdDFU~uvaF9v^P=Q_#xJ$l$3M6=<)*9%sK6%?TY$E=oj=hM_<&8JCgvVJnk;NMDL{7 zdnrb#RcF8dQTx(T;MrNo3$wWyzmdbvIgYd|`NHVt_XvvBSbw@`Jmrbf6xVX=0RrOv z(7mF8pE_>i_cswN_PxK$k~3HL>eCC!&poRsw`83skvLVR&pz(cG$sB#9MYSn zcgE6tP)Ep))e%a>y4|>A((=511?bn_uJxl#7B)>URFNM8<2)c7jy>9dX$Z1by>JKQ z@&qop;@;j(40@BrfE&pCOfdKq!r^vMlI_aRCV{(w`WhYp8=Y$ONELc;HsBm?gA>F2 zdZ1!<%x__a@h1=T_=nPua&lqIj5*A`JN)Xpr|3;utFl_Q-vIbC+GyVa!~UZtukdIFt~$|(agihDI4D85Jb7{e zr*M6+tDt5&mGRME^x>_yjSaWnq;13P3Ux!#B#2N&oj%-eC*GpYB%rco^Q~0d3?t>u z+@ySjOJ`tpzt5BWEt`Nw*_Yum=&MgZ8}Ehl+DGAWB2LHKCYGVPDQ&?D3jqEGP>w z{FPoT$l|4C_hYD`Q(~p*#m$$US1Q$fsOF7fW;={q>rZ7=>8s<8_Ao$2xb)vZ?%h+D z;m}5j`&ia8jWd7pbrml~KmHz}@x{(qX_%C`j!tVJZp-9XJ2Y&4iMW)BqI6cNwF5-$MEp;haZ%q3E#Pc-r0SC(Oj%o5RYvF$(lb z3rJ*={qAM{3`b#*XZFp*B~5ncw1s<~O#uoTbtdtnd1}&oLpM^`p_r!p>|upwZ%Fp`!K z_FcU6s+i{7M!QZ+?8G)c39PzMly&XuC8rM)_1QYvZZiSDlBAhuo}cLGX@t%9s{M14 zg&bZ+xgd@JKmQ7pTN!-LkjHHH+kOh7Ojvl)sE+(BFOw4<%$y z@K+KOpo+$`i(y*`h((JL(sCuxc6mXG#cp$TIzQf>3cnoXg*-rS7DvKEBjGnnTIgn9 zd!&{kvN>yr4r{ApL`(&@f(pw<1945IL3M*2mR;6DGZ?dcOUy!w1vdQ-RyzB_E=H}g zxnM`oJTEceARbS#fH<<|+F)5+4o?U}ToGR-&ov~6PP8R}!@7x*`Hs9!{D`4L!xC8F zXe#hVWBkgJg9%yR?6v~9^U1qyfZ2>x>R9ETt2F4hzyG>v2@g_7cs616DaM^nHkTL< z7A(dp^J*@K?sk_}?8CQd_6npHZnc)D_8Pn`x2QO^U@z=o(_S7MXMpjL8(o{PK96%L z2T^@7t$fKn>k`}~D9V+43tMN2^FDr!MZfSE1>#q#@5LqqveEADAOo>6U1pi5OMC>b z=wYJ^RKgpc#CqJga*}LbqBl5JwAj*hN{#yQ!eq$#CId`-ntk*HgU0VUQaEfnn>li2 zy69MOY+V3viwYNe&{cQ5NZQJ`AYNaeMUsPmSN`QPmA8VABnkJ7^ut68pBUZNx*PyG z_bfCEW1zwvevEV6Itr+$8Adk1C*^XDF345SfBzoE;8`0Y3gD`Zip8W(C4Rnf*YI0${ByAFB2UKzf(W1rUdvP$r@N%{(x_&6Stn-eA zsX^>_j6=vgd*OHy6L1eG^o>PZ*A|_m_Jx6}Iadpne>HbL4b3?FPuX7(gWg8~ctmmP z`?0QZx zFLHFQIHN)o`b69!`x()29^k7s9iq0joz1zqCggcA9`kUNjTKIaw4U-gY~^KG0Ruoj zom=vS5k{BM@frbaPiR`%SWzdMh1x!^wg`6 z$QcO%F~5{x87?304({v#)<)-YM{u@}7L9MSgHndGR6Q!l0e{GsrL(9^n+m?O7T{Ja zq3%ETym?_y5GlIgjC)q(dG05H{op6J#Zi1r`|(=bo3^Ru+Ri2iXgl1!KPX3{J_Wxtnw#@RWiSxO1dm1{#+l~G#a*5r?~S20fH_< z6DzPAMwpG|n*5ylq10%8A_CvO$*fP|E7MU1ZL!c9ASP|~Su}Chd64p)pIE>+t~26^ zsbYU*;L&c;yHT&LU`|$*PoYb< zi|kI7t~0QO6H;VYot1p_8gTG&;(Ta774f$hKnFkj(d;`Dtd<+Q^Nra{>kh;L+->jg z!D6sz)A+QrlS7Xw%kEFu=uRZ-Hx>!6J!1ttmd+=`(8 zCV6^Uy6M2qJ@jrsN(l^jVU$emy0G9L!YA^b|8EGph3}^8^xP0p3*v(fT^V52x6tJs zz;6iZT74fXd=va;B2LA&?OnD^{L5B^&{ZB)>1n-K&(&>ba`r+jz3e@SMHJBA7yeM< zVc!+r%;6@)G#l#Lt1h{4jIqE)fUY*zcqN})sd2e{o4AHZeXeQ3iuaV}KjB#5cK}L0 zJipg;`43kA9}L^q6zQG3Mx2nK1?iudsE7o;$S~n>;f<5jKfy z!v7kOIN)VNm?e)x^5RdJ7Izq&``Hnr=LP+r1A_hy40_AahTihOFye=N;M{@kC`DKQ z8W6n%Fd+Yj4b|F39PqyoRYF4_+>2{ZVK7p4~c;u?l(*qBz!GZp~$!qK3G zpX6$f(pIp|8S_K%7}zmy)|r#>mrta&283AG>O#+tzFrFuHg$?^s~sk-uiTD*aBZAJ z?l=29`ipxa(nbYxv_QLpsn^0tZs#YFfP5Nno&WPDhs)9T2;g7)>SSw{dcQwv%XU?$ zLa=?l%ErfEpH?OCD#o<7r`#dFHltIAn?7%G(PR4%{`||~U`Ax5>2X!-R{&m#Ot9_)gvm`e4n8v`k?Bb^M8LcP=*_X{C&j2$uP#n& z=3Z31tp2OCg=>j1^o`I`o|&Hz*UPHb@tfD&-lFzR2w|T%{4!wYJfNB*SGh2HP^i!f zRUcL+;0qjf>OWgG&KF*AjO7{_yG{DkX-v)N>7$5TBaVw$Q+2fI zu>vh~Eg?t?BfV?_Wpb^3B-BW^%69Cw>1@{LtqZ%tapxbSkK?%^?*VYw;^+&YvumvM zm^rZVWy~EWlw3E%^7*-vI>!8X@_;|uy6{4YwItK7^#XUc!4rskAoMQUpeuZMTr{xgZz!ubFo%5JDGGz2bF;2z<6HI*arE3h zu&As6=x2OTrC~9@qZPw*TICpM?cD=`_$9-#ICe8^LfYPmi(8SeZbZje_&UUfIrTX1!3D$!lc_FJw z5%+V`v^l8VnyY!Ejc~I!AK|n=G}kbf(02Qr%guT8%lz2rpPkbDNPm3S;k+pw@4U47J$Zb$ZYaFK!C0H-gL9^aKw)c50m*l^nD|;P3KX&qxi!h zP+d&t^RNmQtrD@QJkT)aS&nipsqX%vQIT4vHJ<5I$wyZ{vp0pbAkm9VHd@dsHDW%F z)5D#s*q*=##{7war3^l&_}amEM&Y5EEVz~14VKiK@5WzNmr$6q_pOtxafwwLKe=^g zYLpgy^HF5_Pz#P1P#t!IM>onJedv>P$>)zoUbSA==WxSEH&MVP!?pJ|aoB-XV?Os> zMUCzDw9++S9?#?AV%zG%(~0=h^veAfEtqZ$bD){H*&$yt+guLjeU>g@F7L2&U%*2) z;Yo>OrJDw<7zu|N$(*EM-C=XwEYJ=xU03Gnp^8}+Qf^(Zsw1rettYG+zClqOM4OsF z)j1C<9v6^tUI{&U^6<`;_6ql@r2=V@aGuANmusrHeas`ZHx&?Aj@_#$dTEy4kQa3Y z#)390o3-@9e?>Sg)Hg$8T9(xeQ@v>vKpR->pdWx@g^{YhQpkj=j?4EzwK;sdKy%8r zgYik1GpglAjZD12o1(=RfZu0NmNJe;Hx0ObS%!HyaIYm`-|__6CJRrsDBE3rcrbh$Re;05y-l|qa7!Gt6eye%aMBG7+kua&OIkY~aSRKDkJsc}*f_Lu=4f-X z(a3tMZ{ai8ACrhIpgEM{F6d9KB}kZtV_LBsslMytrtgL7>R{EFUZapC1H#A;!~*ga zw9v^cS{=}FIJPqIl#6;}Suxsh>Smm)bX_Wf&;8EKsA|LJWhJTma!BBgo0s`Q4@4hv zh|%kzxB5{f(ym2`-Iz+eH@%q$sS4GD$#&6Q>S7Sk;nR?mFv+UVv*{!J<64r07)d#z z<{JrOS#^|~@83nsZ8(*EN`sX?^0N{JN7>}B=nOCRMk_V-PIXw3;EVAN%URd&j5j(y z5UqyYYDrd%KckPSYI=?}po>dXsNa=U3E-)CU@x!}>Xm2+YL>&{GFV-EPVK(RN>Apv zf%{<>eq7nc9%UWdqRzn9&MeeuKz5-}v}m3p1=D#EHa&e)4J%2;N0bKyc9 z1RKSjTPo^p4~Hsb`H!o_s;Cfn-dK*aeU09NPfjBo>ZNIhH_7J4GoA%+I0{5hR_WEd z{&?H*?)V;&q<<->g)j#X88~-64H@bNi@`<@;cxD9^FIz_vvRC6e z{heym-eTLeEpXlbA!uFD)XE+%Y0%cSs90l9VrcTLi3Q8|~(|ynEQoVc7R22s3Y9dF{n!<;7`6JEl@}C@K5%QUp~J z*5QdJdvI?`eXT6r;8G1{3v9t{dGm%Q)q{qfI`cX)-0gbk@t8~Kyu&8La;JRc-L+)* zB8#a~_~BiR3I2*jul5<2IoEA0GW@-|*Ut6U5UQJD7vdN+chxKkmIsB+AE8r85YbRe znc#;v<((Ovw=TA-!A3Ioj~y$`VRLJSmDAXRy4HPD#i5rDPo9nyGyNw$5J9FAk=H=x z9o|~YMFy?L8K+9ljD*T6lyg@2*D>wn*see&VTxhNY#i}s-BxW?`?R)Qg;@zVLt7O) z>hVDt29Y>AZKSKkT!|FuBAgMwny3GPd#;Joco1Fe5#EVkwQ&&$%6{-f`cp2?fO4mO zS`K4B+PU}frx#(-`kj{?hk^d;iP~os0;uK_`4OPF(RDiSG{NB{!$BB#uLb>PumT6P zwYS_nG0#IfhA9TLDZVWx1V7pQBsO6)kapp&d1oHkx*v<}u!M~Va`gSxdH51R)T`kd zxq%cx#<{uDzL`9ES=*G(+n?V0y>!K1rjoiuLP0|IJ-T#G8>zB+UEg7oyu51{^$cIz zMAM^d6n%4|GE95$x_)Pnht-Gc{ooA@v>hv~T@ppz!9njd(s?poZRj;dH0f&GdD}wR z+$}?*;o*^dR5&_L?B8#k&kaEc-m<`ppW4sGNMn4ONrpakhAB3>YrzQnM2QSrh@ht% zUooDuIk(kzsh3+o81)-Z`TC|G3&V@6iit zpqmuw2h3E`9P%(M%utA?o7XPU0fCqT&{`(VLx0|dhw(BNiOzy{GK zBCR>5bpJ>-`r{-S=FMw9u8X}Gacy;ky~$(#cqS(_1Cs>z#P7^exdpG00iq+>;CX&) zdP2F&Y7y}B)l=`eZd8#SPAtVcP4M1{%eU>S2=d~p8gAkCx>^Si%F6Jkfb)gslo5xh zr3TxN?>UT)p1Q?mTvRNuP+Q;~GVGI=s}}3W^V%As;7En9vOmJigNzIPbh>#O$zPJf z#~E@gz(otFc>^kdA#T>wZeC1pc_u6>n;NKS)_15HE z_?Yj{AmP%d8{&$N&m?+=62%3IsX1c-((z=dHIoW|9OTap^2U{Dr~poe-pDZ*L0+Y>7UlE$YuC?9{B>_+~WO(%E9FGL?@mcSCz+#PH>V z<`}J-xKlhMHoZ2gazOY1HAW~tUY16q_AMAAl9)Qr=`Yy9Yv>xFm~L|s_!H5%iI0wY z(r3;a-V7RCGi0EPqM4hUvpram%I-Yc+ryQYmzM%ujWoklVGkA_tGV#MK$&64Dv+X3 zp6<@a{@f>!EHfFl*wk@q=93eF(@TacWIT7f(AWWZi0#Q1QFl1iCkasEOB0_QpRI?! zsH=02LB$p#zzOTCIM$>D?o*_E_LA4#7Co*mDrah)3%d zGwU?G8v#V^?2o`fPYp#|!SIUrDr__#{`CVX@ACtXXr0YE_lufq(gASmU|sH%wGTEa z4JAg6kGsZ zYP(po!S{2I#4^KKITnCa>4;|D0$_z$pmIIMip;)`){ac3tC$Ik6b z1}ETC`P6P|sJNf*2xsbC36Ddg(kTWPJgDELrKQts6{?d}vR;acvMELwr!!`l`Z z(;ceN6;Ui+Obc6)-zW#vmD_h8J-UEnzu7$l4uGFEPOS{zmOPFG36EF$qU*1>+xdEy z7KViKH{>Iy2)I4G_JTni4)VtH8P?E9MUIZ&6Sz5Fq*t$5?`3|>1fC~E=Me_G@)P? zAf5qu(HGHRR4%|yrMKt3I*|MVNR2`B28t-n=Wk*jX)6LofcfSr5ObHgMSPOrPDv`M zxXBzEj5`2~9Zg9h6PIJIs=UcPg1+K(dWVqlJg>k1owL6lc|po2p#N17FZpLs-v!cG z;p4h$dZlae@s z1Q>$Wc4uuVU3SuaaS4Tt?S%cJr02(-wOejaE!G(I=I?ay7nzOSp7lMm0d%HE*DT5u zVJJ&)4C_bG8|yoJehr|N(xctkiprKx=>hA8J>~z!-dhG$*|vS(l7ciU-JK#J-CYu* zbhk9p-60?yqI4-pcQ;ChG%UKiJKuesbzS%Qyfg32JI}}a8#9i?TE{w$ef!66Lq1sT zc#NU4S#?t%@d{XOpwA=S_lF9DzH3XY32jr-IcyzMi*QeW*5iEsksGi1_k8o6dms1~ z5wvEBuWUw?belc%_e5^=hx$1yls{iB>B52^GZ`(dW+Aaj)f>|3&%2SwRj7Lt=_Tm8 znX$@+A;i>XYAr=~><4#q_Pyd}cINTI=YhMU(G0)qM~_=B?(3u;B3w68T@K?U|5Ey8 zf%&A1gca5bw#BTTZoS=}vqv@Z|JXWe%~FEZ3-6DnI7sL{FZ~3EDaS!+d#tzscC$N% zQu6kWR*8uGd~5XWMz6+>5GP54WW-l>p1n=|2@7!Rj|~_zB{PG+^5JkedhZwD;I~ z5GX|~{kk{jslU9y<3n%cn-ky7czp^mD$iQUc|uM6<~AmrJv%!1UG|A6C(gG$Ap^;r z=7vvSX8!%GkN^n-=maYA$Acp3-K>7;J0J`1afzc;Q!A!v)5w3#*mB2*-|U{g$^%-4QKvBj>`Z07G6qfi=A$T7DfM2 zK}lFXl4u=BdA=uv>$Cd8DX;l#^cd_39$BS450Jd+q&@huVl`E(+t*Qm1hL`wxD23v zoz(3*rm({%2#ritTQTP-tR+(qaW&}Um>{#GGo#B!Egi5^2PyhOJIKB-eYV@7SX0HWso3MHq zb(tO_C*rYx2C4SlcYsK?Ak1b<8<%_E@uKwvOOa+yz545BUJ8smQ^kP3r8Hp(=iY14 zAVh-dkm0uJiuEM7cl2x5Et6FT7z5hRkcnlU1T&-#)U+N5H{26}089ysM z8)w30QdcTB9>iYt7O|=HK!a&#HK?&&;LJ?HaNamqu02N=zXh)BTh~}tTbp0~dSg4mYH{(-tSGq^ z^>wL#_=04&&?BeNMy$XGzt)CdkU%ODpaCR6O`?N(r-Y*wTA8p_dPm#9%c_U#78hD_ zqTXXFk=B9K4d#u()VNHsMs04*!?4!A$B+$NnjjO`G*8b7f+#KdThtMBBJK?G5U?$e z!(sFut=#JCD|1JWhUz`*fY${jiHlFlVQC4OqqKvLpXY)=j3&X!_#amAAqgiHrAV-} zS+JdcywBTnPMsT4&qKe#w$52FEqe(h)Ve@@3?AK+1QKc2SKjU1_?M%PI(Wj3rPG(> zGfkWRlw54-VQ47aO*>68d#s*8`94TgT~Kzi?E84h+^v$Fnlp~=S1>q55+ z2vh#fRlcc4=Wm9uyP%|<^f|6Y*pH0R_obL|T*ZR}j&3j~8LGolR?t@sYzMRGbMK`r z1Z)7hd=wSJK73OOl65dk4)y3H?_Ccuv%shI`S&%AKiyffWgs{) zFQ=X$O|O6y2r)70);1WMEyW?yJ;}5sN2N~DpVvdLpmA=h^=VI#$AH?J_rJ8ck*cEx zv}-qiXYq}#-;DC2W7~7jAjK7puyw5xOn4LXI>t*yk(!%I#Y?~g|De@8-P~sF zwEaj$MN(EH?R_$^J88fJcENwOLkLxj9>)sab#eXqh##r6^?W?So75RA<{l|vD7sBo zGUqI@c)|Ji$fjJn;N6}}4Kw6=!{zI7(urT4H8l21GUxNszy3!N6Yi|oqph2z)Sn(x z(Gx;1li5td+(a5e+|I<$Tf;WpcLn9*t+JSSUod~i0uo#9LTJ-eEnOe%Ydi&Vn_Xp@yHO#0lu-Z z@pWvt=X#TVvqO)+#Ugl?4&3xPH{7!AXKc4uf2SGXFDKQ^R8)1Ny3Etg&H98dpm6-v zrM5}N<9Ic6k)_m49Lb>YScdw!Bi_q)LX!b=6q|;ZCCG-aEXKG_P#>3IzQjIEc(zqs zc>?Gtyc@kw-Z+_%CL)u-G;$NBDdn7nl>TxG(76y z21?db3bag?rmwNY<(b{qhLUG=>HMWiF#2(^%c7K2PL(K8`if-L)YJerR@WBm5`x`E z26m4SQ3VGDOb;kx@a6@D?8|F8u84G`GX~prPd>NGTSyRpR$NJ0$|gc>g=|G?DKH-+ zk0zm3@>MHP}un=8o#JM>=18$E?NKQ@J&oBN47ztrlGy{(Oi0k6{rB2;L<4 z-hqdwEv16 zEJcIJ!TejFS6?V`v=A@D&+RaNKn@KBmoXI7WNypP&)+#Z`d0bdYy9`q8$;=R zAd7WdEfp&siY>F+oq5v_MiIi}<)0^NGkAQ?M4|ZX>x?@A70c;9gEGgf^i=Mrn+h(3 z9PWXQ54xP7V^ug>&VJ8}_gitcB^%Wl$P?9!12k zGhR`{q|x{~81-Ibf3}ITNV6vTL~^*!P_0Ba4m>qtfWTj?%-_le(h@Nya%$H%1#hxd zeNA+9kXh!Y%AV%fuQ3$wAFF=enZMJTF8y$)H5XDk;)+x)6-6Qg(1POyrUIW@xf-q1 zqe5WmHhu)HlAvtkL2E#uN8!XU<^Q8Y2XbgDd4s-3Wj#~L<}wJYQL7&cq7kp_zgV8M zw!!W5qW*RJA%h_VsWdCPT1+e?D%liq5Vy$pA@xqu>P=*%?g(}RvXGGFh3#BDHKQt1 z+^E^0bR-dvBUvJq4EA)>4aOfuqY6+oy1H1{fkq}oq@lAu{E~XUaxR-_g?MyYgDWWR zfy1M&NJMm{p6Tn!@26l_c!Jz#7CGQ2=YlyNP{E%u19G>QMoXI%ItjPF=!Cs=Pi*cO zY{>*2pWS$PplMZEjDtu@W%Y_6NH*ZGXc#xr zhft{%V^pz}8Ff`#OL;+yTHS9b2r*u3^jwK3%mvqDnG%45^z_XJ$=2)^p@!jhPYO?X zihzr1v#888;ziRR&bN>LPZtKGo}R(03=`DcDe>uGb|glA6gJBT}PVx zC=nHF*JW7;*Vrc;JR7$|4h<8_=%6wFev8j|$bKf<#id%ho3K z%%tPKp{XP_y=+Gccri8lU2*N_32y!DTC&1%#Uy4Zj=lTyIVK<;V9h|h@ znL~R{aeaK?$3!EMJwf#IVBX* zc=JujYu(SUMQC0V(JH3%tFT_y<%17KL$#PFnc*PDwLkA;jH{k%Kqsvm0azMIZe8p^ zU#}~Zw|j(7GWKEMZo)zD!5_08Sijx=K_^xG;v|inMqLpx-v$We02%^5U<=gw=%ot0 zFnwxGEnEDPEK+MYdXK))Ax7na0YD zqa)RJXza2}Kij^`_Iwa?al7BGW72AVXE&tZOpBUX0{)0tkOtVU2XZ1|T!@@R(}1N#%iOrn+YbTFPjmP5%c#3vwbeL9E2p~C(oK2Yq&LBVn#*+f8fX=kfvCNz`N}Gu{bV?BLweptwT~st ze52mCp;rOD>LWQa?0a45KKluPY4IKll{>^OLWxE97b?C}DGHY3WZ)-sd|v6@jcE>B z8~8+gZd^JgrHh}QtswGm$%eb*die2lhfCPUuy}fvJ}w88Ta}AvyBI1Le+PaZ1S$y6 z#Iu#62KoZk`{IC+C!l-+sV*{JXcmg#8s_Q|*C(2(HaF{B_oP>@OaiUdDPH~-y?{rt zk^1P#jEF2-0I#S`e=UoDfT!%yF%di#&Q-xcx+;UCi&wrdXEg#&VrA=uXSnlO2ci}bL0J4o?jkK zYEZG9({?5&RK6TUbei!#|9P&acnM;sNS?>jPI1|-RI9!c5!fo_W_=(x|LrNiL^^wy zmJLA^=C0n;Ufk%P5rk^Zch$*6cRP84&%2)bOsT9;qx9P+!x)1^4TKXCLS;zZPQvUl zggRANrzIsnWzZfN`mWT#;}ah1J8p@vTRpm@D$?dSd_SOr1bpmGVvTd}fhInPx}G$M zzo!&MUoz)+zD?S9xNmp+^2*%*#R{BPB~u)hZg;b}?H0Rn>7DpT8q`o@eeS^q$@icz z{>G=nBP4qC3r!jPZhrdXr%MTm?@>Ml?6+dnfFnrxdMQuAOYhsu?Qtj77a4o!7kKR- z3?LCwXdr4oY4%C&i9yX_zxSC6E2OasNIcR2L_@7v>01$+bB1yyL8BgsLV5MEN#A{e zg$SF35s6HD@}*j_2o%Po_^IpWxyM!m;!;N^Vq!r}`1^FI*cqsLgT5V9f+)86{9)bS@c%%jeV^Mes zBDx*oAedkpK94Y?uXTnXNuzG>4qz+14`G)Bx7F%V4W2-gcCy82U)aQ6BCaB=iWgds zc-g}6-)T9o_v5oGDZVEZHWEnE_kPNJibPf)Zn_PkKakq_`4V{kQx;^AVovESOiIYb_eOXB>|bbPiYrvP8(0X2L0pidB}sY=$41%lXi-&2UIk@R)@KjF8$-}Wigs&vhCPmzqo z%Z7W`Pq_mrsZqI2I1un~?(=5%Fii&YPmXsDgim`v z+#4s<%uWDXit`gf8}1YYMMc+Ci&~67=R3O3`@oB-g?{$!$&#oF9i90|HKG(jFIi}?tLH7J?R1We%CM>$ zs%{Hq@DepUM$Gv&JlTY&r>FLhM{C+xE_qCO9)&3jPM<=^Yca51KxH6z0m{HK`&@={ zyWgT-mws+Wch?uJEx1!8@3=W}z7QOxz3Puk<{Q!yqc1Ae>ncBQ5d*K}L`J5m-`-e$ zz~U0x^>Ig(Kqa%^fLWE0w{Tx=@lsny6V@Bu1uV?R#ebT~NJ${~0pqYVV<$-#d--b@ zTK@3}cGISoi)RbP+n!0g#O3H={-IW25KDeK$|haxM|%N;ywL^MEM1TX#D`W*3m56P zK@aH5E4SEwy_bp`{bV`EAeQMj5-`=C-o(Kf`c#mE{@5U9w;gG(PhWQ?BR%;2x}@vu zaB(8Dra7I8u%t>jO@_Su_mO#EDHb7$xd@30ah`M|M#bm$gRdA zuNV$C&<=XHs88IUb*Mnk__~+j;#+e}G0{mhrUG6x8e4uxj1oKxh2*6w>Pnk09!fEJ zC0fU9D>rQOY7AaqRVA19Za1 zDo_<3EtOUrQe%$~-p$J*F;5X{R2=?ohp`OgDo3R3qCey+OgZTvh6Cmfg^YO%8tg&!u>Dq7`LvP{hRX zS%@)V?NS1AiP1hDSu zL6g-k?+ToNNFxgJfRy-b#+Bn9GenjHGaUAZi!g31J08l}l0{@+YKvH3s5-9qn}-r| zr5VIbRZ9uqm0GXD{?~i$iw!anK_C+$TneD7ioA}Si?mL_P zDqatOtpaTJ+0ICgxmYMJOYRy+O` zkFY%cjCJJfS9=WEm_w=)UZ-=4&3hbpfnY`GE9(jMSXxDLkZ@0Ic@QKAM4%^wxjf7wex`=m(@$0h{ zCPe=8amW<$U5d#R`O<~N2?{=-!M;A?O}7yyHQ3DNI?3y7QBn|$K}ZgQ;$;g&S!?Nt zXqf3|JDq)&frUCNlwu*S_)!q^tFuY`5}kwnIiGGW9X=Fs%w53L`SEA~AYt#CjJljb zjo1&By~}E{xQT=hJSpm#b4VRF-1|CZp6V75kfuA;+X5CXG;9wHetO{SSeehRI#9x= zH;qJ1@_r2G<6(3Bz=iXl%$DB+pC6q-#NC2c8)CFCoFCxB$O8YFXaezmRO3pk#EhSK1WB9FE5;VYXA|Bm~1eODAI z3Vg&x%JlK%?`$w@5+vK*I!(N;b6W{6)T)uJwt+C@Jv9M$9YyZ1|mfRLCL;g(eCiVQ5Zd)?+x^o{S-s%xfd#T~yIB5XTCngeN%n z6JS4C{q!}~a+B+-c{|4D;{tdEW>xB6F-Tkzj zQi7(!wiZy3cL_w?{+rxP4_hKg;PY0>u!#y25eb!4@U=p^AT?lFN2idko=#>7O7^$i z1e8kR!4n25f(n>Sn}5)1&4Q|2>Wq^LlYW}oLNjQTM3H`%FGo|azNpx$Im2Q%W$FR4 z-yJf>AV}eu^sbu!%8nCT6k&KNr4$#?B>@Bz3eBvsYcEfbxTpm;fY zc1Z`ilD8f!de4olA(f+Ns(goVX~pKF-=sGb7NqxPoE$wszZxlUEQEAD5h5Awc(=}% zuTha`6EOLty-apZ5&rDXve6=M;fKf6VYt490-Vap!8=kGHq}gCtV(#G0fdWK(}Cu(Gt3Vs>jPB@ZS5ek zl1KZr&pJYVw$?lwJd{*|bYt2jJ`G#ul2j9nTgs%?R~dg_3U20M3p5+~(k54{0oBVwi#(+i&A>12cHLIz zlyHoaA3C#a<2Tr^g;@cr{004XO^KHoC7~k0ZqQLLyy@XYYjtw8_-z|D&1*mpU+OKi4(%>gK}Z6b83CL{ZIR+BelvB>IJIS@F%modtm?jc0$D< zay7YmXtv0vX7J%K8sX#)Kt7er)mLtl@cFXd^FjPCg- zkM!qD&_THXuQGveirlINkAV|N2q4Ja`ba2&0QrjeL7 zZsY}XrkWygqgiAkg~Ssbr!m*%T{MGFNi0E_f{fu=PDGx6#5aH>=Z#y#Oj(JM$bIDV zg)s&d9`-qB+ofQy>)$MZKm`i^r~b?!;{ytq1UjTsUEsZcwK{C^kihsk;jJ>ePyg@e zHf)kg)Gc^k_Xw-c zBE$pJ9N1&cv;XyWlS4Ze(wiR^Y9c|*gB=b-^+4Avx6SNqwZTTmasXHON3U76qxc?xb;Tw$9-z)`)7i&61ALQkB_|O^*p1za}Tdqq-lE_>MS>szbA! zts#&`?(?p)^AD3Qz~8N6aLp*3B)$b3OZ+ZH)4#n=EnNDDBo`>6zQ53-_ZjZG+fbD7 zV77@7T4{k0soxY#=2?io6pHtQLp0YYWdTfc8P0NHo?o0xA&Jy->x>hNp}>U-EcQ0Q zPN=njLR%E)pwO0lXo@Yzw&h`FQ(du8oz-dFS}2OhTUZ~_v{;+cZ?Es{KSyW)>jO~T zK#~hDOXNj_A-HRdXZ`Yo0`Bqpf+MsvkQMB>4_F#BL-$cl6~0l+m&=zZnzK6BEH9Xq zGK7zC{2LHmCY5Hx_|PQ6E#;yYRf+s9k8r|pTwJ<+yq`Kx2g=#|Vb;zb9M#SC?smJl zM7f>JH}d%C@~d>VZriB9$B>YN8GIxRah+$aHx*(EDLcnI7Fmqq=zWeEgNTI(_k?g3 z#vs+fiMhBWNc4j`b08XZ?wgfs?+K@q^tv)Kj(CyUEd;4@hFp4$a$`1wc6DNHxXgnF zrvnC`2QN{nVugCAMTv4Qk(;gzlgh@ z&R47Ss?lXbwp(8=mu4RiL1C4=W6EiM-MY@hI4R6Y=G9acKKcaP$;g+)UrI1&(ot9xYqhAZ52b$}ow+s|VmI93 zCHb%85(c%f93%vL^$cC46`?uu9$ti9v&tenzM7TS(dWi_e>wZvb8(hHVZY6ZqVK9! zr5K-O>8yT^Y1c|)Q7%QxZ_U<)N9tZWq|dKk*{}5$kdcj_2|nY4=fmfB^?hYNqC_gD zAD<wCc}y#!b-mGz;MSYWViQzQKPM9i$7 z_UQFCL(nUy?N{F0fvMjZ-bj0Hi6Gz7_7-9Vy^<}{20}W=`O?-#|^;RoM!b$kbwdDPjy-%x`!mln7+pI zo{Ai1+cBE9*1tR$4oQvw(5)hDceK! z)>ctp*<=JnE}2#w7`$vBCS_^1{ODsqI6to-t0_9=Kfi~^9B}9zqi4YE6(N2N-^bQk z^y=l#?9Jz2jQ{mrSdo;>9X{Q3YW{0z=cb2|jB*?y95VeE9)uea{B4mR($(euB^uCD z3+E2V*zza;Eu{SQJ}=_I=T-9j@-k%p&yW2h)RhwdD1no<>B#E8UOA}9;A@1LF|v+# z5nA;pspKDgw4E~SyP1^JUlr5;xrF|hk0V9EYhg4?I}!Uo;UKLt$l$O0-#_Ai---WQ zmy@{Nh;zj>x@c=x7j5^~`r2CfFTu#*<7oACk_ z5O7wIarZ~@aV`Kp1FV{gef@<^CV^qxYJ#;ipd%P91`If|fJsUXJTvcDf;}j54vdH@ z=^jVRL11`Pvjs5^vF6KV6roAaeLgTmXQ2$}9X+XhHP%_-#C(z7B%k771SaoK>^>mVLZyqH8p7UEekbI%2UTzF`fjM%<`5Ds%(wjduE0Pf2z73&NUrQ~Y>VJS~{a5dG@mGA91yO1To!;(&+CX(E)B>yBJM6O7s8`}YpT0`D<}tD#WdUp^KheV|Ob4_~P9Nk82k*I9SJUwVk|*kjS=)?>8FyY#&eAW|?8YXXnmqWFB+ zDOBZX^ewnJu)0X@f<%W}XXbQytxBBU4JG&e8?~*e`~X!O*oO1BsW%r3Z;ywBd@N18 zzAK0MQvx_{!k`Xsm_V^@TMt)8rNA@D0MMepH{>ap0*DRcZ_{NmP5=NEc}DzA5xhXA zt=o|A>H5+A*D{}9G=0$Abt{hGZ^U_#7%AkGxCb&`3*JJ>Zt7gsR?|#};(4k?^-Nmz z%HHYhYFVCG5;Ik{%r5)$Wi)rjkVDVIW6iw2uEkJhu!kcXq=ecg=>IvuA-_%JT=7n1 z(wM2_#_vKWnqp~iK8SU-$fSgB2z#4rMb#kZukIj|MCNA>qg`$squp#TVZVN>VDI(0uW>$x3zX@K3iPri;GEZ*g-WKUgcoWez_Wjs?ZKvAE3N-7xnbLGy8;N-S=efINg`lcVi`4i z9S1rB7K}t`dbN5Yi_WzmUTgh9A(bZL-4At*1}_26OR&HvE&pV?&Zt4VOxt5`hC`#= zu}qc8CC>rtoh}G>#TZFNZEpwyG(7JCxG(n5BwWOFgjD@R2w(shq_K@fl4^@_*|rK4 z+)3DN0skQQp=JTM>^)b~ivkz^#NMZ>_#Lr+H;A7rfqnC&`YE*n)6ejP=+5or;}1xk z5x7E1CBdy}mf4aM{6AFX$tO$nMu*7KC~wm=*Cv0H#4lRbHY~B5C5h}-@OhTo@^?{3c`|S&&q0Oz)haYA>aoQ~(#O&9*^V7+5I{50H=QQuM zYHjAyl|jI&CxxC}0YMJ*sqzYcWGL`x7x$|WpApV5!-xwVQ>gfIxbn&Vr@hsXHS zgz-#-Z_mly%il)IcCheFYjJ&1+B}fLqvL&qM-LK{(LmhUyn8Dv!{>5dxG1F34I+@n zVb>TW{tCJPu5CQB8tShA7{LL#O&(g-O;Z&vHO$Fsxo!DdWbg2; zhel<$TtjEZsO9roqlv;b8cHej&(9e@_jQIo%~4)^vfgc1u`cge$30o#f^kRMeCDnN zQDWeAzLrTB{a)+cglJmsI|KWf&(1F^1RZN#2bF|PnzSP&r<4NW_@-W1w5%SJfqXa^b82^%8R+K3&SLDe4TQdyg#$tpQD& z!jodHnndNoTiu(PjVc>Hwxc%=2hfh$$&JGvLD8+@W9zM)`3OKp>8;opGCoiFqTDQs z@5hF;HFiaNrW+akF^0loki$atX(Q?RD%!rQ(4n6_BG>YalSS{KPIIEnYz^2x)B|M2 zcLKUdh!)#ic?FPMl#O&HYRoYQVkMJL3t8YIypr)ZLu#1@@6L$>5gaVu>LnnvyJPN^ zw4nErI{0vnE?!_Bpse$f@;SeIz%laOD=zPETY+u4imtGDiM};cX`cTWOSj3bdEnFT zta`O)K8dh{LqWbzU(LbP`Cx)hgX84J;r^RH8}ibvLVhpvD>GL@->9xsSZ!eoTtQ0T z>%Vfizjga6adR#t1C+zH@9Df-UXJ@UR`cKZvNqMlW+5)ops~L7+o(2mPlZ$r97!0T z`Xn=*&C^MjjtIZ>d7}KyQ3E=;$)pPg%yZofyLA#(fzXt>3yFGXY1H67uyjrzI~054 z^DuPRVN0gHkHbRB&=|#8U-fddg0nzj68J?_ch@WNER_(6$$MI`eO55LIP;DeY^B+n zZ~9(dXq^C>Zsuw-j+ucg7lANP$b#NW|;e?MV{-Yoe-DbGb?M z?wDRK_=tq8iJWk};Su9hp+<{bdiqU1kATBjK7f_cOYHce6S3L{hByZh@;UpjhlyZ& z93%RuPyfo_K|~{>2yaZZDCh(FeZ;cU901Kx3V58x8ifS0&6mK;a7+TJReWLl2pg#y5j#$)f1(D8KS720hxrtoWdq~ccp z2(wDZd^Z0Du;~-*_S{Xi(l-fS4sIht?N$2wDv~98&0t;nqfMgsvh@tpzh}88mU@)3 zVk)FOxD^@iCx^BQh4`loo%RfFeEYXfWQ&|Q%$kl~n}zn_>^a?05{|T3FWyH#wJ^q& zjm>OqQ$gK-0bL6D;&&Kqp;t8SkY2auIDSY1tp6fbFu)q$cwP%#UY`+e4+bgdZ={2x z;a7S%%RZj*K`4Q$vUDBq3|Kdx@=w3u^IS?^**`b#Sza3{PHiY()gDu=dZEMD19p>) zd);W&peHh@Yob{)?tdo-sbx+$ax!fCeR^#QawU>Q)9{U+w8lke^IB?xE3KB_`2orZ zK?FlIh1Pajcf&ju69D})ChY%vD=7RuSWjs(n4(d?r?g1^@t2vj@Fc+o+%+NwDr^o| zWn#Z+UICcG+(DJ>o8$s8SGIG!n#I|BbtdywX zM_pKHbE`X2**sTmvgo3_%oR8MOMNA+yM268R3$va1BW}HDJd6wn&+!Fl{*_1zR6Am zLB-DQU$>lDEi+*Nk8aD{4+v@#lYoBr)`MODuqf$CFPt2)H>n<@W#!Slp6U?#>W}hT zLg3%g7_m<+SSDyuciO3h90xBa_^YoV2+|LjIgD2j$6jFIzPB zvx|7Fxg!Q`fe|a8i`J_n>|ci#jQ6y=EDC-3?V9MOUVDK;Bl#v$t1N8U^S#~BavS^& ztUYWu(L*$sYDQb$_@ioZJqfwG-Szo=OPkWotunElI zcirX-xiDdQSK0nxGFr8*qn*N!J3-k4JEV>L_qSQ%pA8+7fzA|ZKh-d>R zw)i<(zlTPXY1J#6F?Bt&T0KNs7O$mbp<0qu-dV*Og7MQgbY!K7ByVKHSceAP2SRMp z`CJs}RXux|0=y%X9~i~N&th^WfFatZ<&ru|-(Dq3R5A=J15 zMyh_xHmI*!Mb+ME6d7216c$>$)+kA#jtHmaEm#^6jz%5r62AB{!5`2NA(Hqryy?`$ zt}lpR?L|B0t)Nk4vdT+5_$c3A6^1aU#euKEf4?a*&<`NYT(335=3_~9G<=S2Tt9nk zf%*~zv@X5o!_>IA8wj_2(lNI>?3?hH|-Eir)7(n zZ0(}%R0hmDn{JmvD8Ax~E{OTZeQsVHNawKh-1yOE!j+==y*C=UCE_Xk2j7ukv&~?W zNW#JfQVMewzI{eDiCPu{*q|q=(qhOQk&iD36K(oADiCATv(Jrwg)w6#BoNvp*>%0* zy+)EXECHK_L^sgxgUb;a$$8g6cA$)l@EZyO>^c9WB!^+XS%=bYgi&?#hx8*z(84+J z*}llUe0T~+YG=)rBi<7`QfBn{j=v)dA(!a`#e(mvFKlLs=X>+tIMTcda_72fxfd?) zTI`nmotYI1XF1SBl%A>&f`#805B{xmd3||$KEJ;oKA;8trCQCOBXwY+^zT^=mlmfF zJ%5gd)rL-%Bo+AHNJ;6_6^`DwTjlhCpeLD2N2G>v_OrQ`$2HDko;mA023GiNlPz0(2_W$SemHU5shZvM?h!qTuzBcb<)kERQ7ctf;^ zvj#=Fm|V2+cu_pY(knmX}Rb*y~Up)}#_xw}nQ#B9bq9%ehk5 ztQe0keqNF(Q}MbdeGd4TwTaqZh0}&3dCx}lIoWUw;Rz~Ji--(hELDv}X7IW;gD0gr zQr7k~rTXK;+OSFs;*^)gjO&`(w(YQ=>M3f`XBWUU@ttp$yH0|&>qJln!No5ZO(YN% znaOsg?q_38hwPOY85!M2fQ?6X7%FXBad-&sW2P9_6iRBSor>JJ_L`Z=1h3GAp zNo7!M(Qs~k<}1syhHZ^Bk5A`@NA+^u)BETrE(3*~o5qiI0ZL7l^}F>#gP-|hJ-CGN$J6D@U^vs2dvFIbSQ*OfTvhZt={}-f8yC+BI!${K$%>$R0qdL zMd@n{?zs1HfpS#5EyTQ+i1;G!y25cEo-*ZGi{k~NpfTZ=@@A}{wu#%rTR;s)&$E^i zRPQYJVA~pIE$I**8O+)t{0YL(T$vAZW94vmCgQZP6GC)Yc0Fw~21(J8PGMx5NtDrn zTe>*HZqk-?nn|={Vs%r(rSWZv%*g>(DB4tLB6&BZG@GRn_fCc7KT=~S7_f=rR|{lg z4j?rx)hUu;crucx7sDc~FNe^=c=xpef+Juh4Ejx&a@X_m3>9^MHL(@5Hviu0bO<9u zzDGbY62s)DYWUg_G)R+0Gf|)?l_qrJ^zf?K?8Y29sH72`3@Ii9?<$}!7f(j#1 zN+dGybv)PQAWic~2CxHTs9G&!9;LpfYd|BI@JYTOs0efO?g)+?mXpgU{+JXN^byOQ z^kfqXkB1er8V+EB#5=*m=p)N^*U$3hkLYx3t{B zCaH+?J%R+^gy%I(3^C+3PMv5Ix=m^1CF>d&JdjlGLq@Fi%A_F62^P>QrC- zOuwx92_jl%f13nEHJNn*7>nsepY8ta%Cz<%*XG6C)l^ia5+Q!YzHq*P8bX zb{xkkd_p;49tWPFHaIpT4fRV1EsKCSqUcn)tJROcbVNSkVO2!Oq#@fB1E9|87%h{| z((5J#up(6m4oi#0J1wK{8Ci%r*j*GgS`8U5Dl>S0+@A>R*fmvU?+VEapS3vw1;Ue- zH{(N-fLjOeV>L4mh{ft&;R5Li@y)x}26O)9YY#PJY1jHNyFj^wzeJshdp!DALa?=q zLO6HND8?znb4eAxhEFUwlRpduaK;oQ1(twdx<}jB zzkc{12y^Jyt$gsegOT1Ful|~u|NGxPWugCz+AHy2R)sLE2(TV-;K|bdT3PcCxyesa z##a{dJ!h!=UnYh$84~zj{*O9G|K&+g9nvF80H)n(nQoIuQdjMNh0LHoZ_yL# ztt<$bh5zfcrB zV+>MhU8ntql)BY$mgeCNl7dr|CYb(4u{Az%E?BFw^tkKEoWB=1*%C~bOWJd6+mH4d2Rmt z0s>!q59INsE3_#+}olFSMb^Xkr)I z=yQ+;_Q}!fs5X0EK~*t#kMor2bugwxZ5w^muCqNL5jq25xGYt~JEGM;wef#0XyH6; zaBcpmU10A2`SU0Lb)6ev8Y5Twq1o-{%OJOWRo^~;Q$%wHVrAFW^ zuWi(KS!_L$27=Ws5tnnZUQ0380oY>&a&ME6U~2R}^uLF-e?C;qz~W0!Yypb*8xVq_ zQ%YOxO(GYQB*rraTi!rH4ID&B_-k2oby1w^t9)#t1AK_%K`YIo4-%6tRoNcg`SjPr zw~g|;@jM#4s6c>=68E80LiYc(XrzJ;qKf%LVoO@!1c+{Bzw*loq%FTtDW-|0uaN#v zN6}AF3i_EdvQ5-(`kMR+&>LwKzfdJ}+Qx$VCNh&=G@y>i0esodw+Iw%WpBSL$hN~H z4_L-gDHJ~Epfk_*K8v>NwKt=)!XV*~ZV!3_9i7)eI1tnZO`vV&FI;T&IfGHeT&kpu zYR#XF`x51y59X->njE(zNUnb~-qdgQAMf$cFOXDVmu~2g$FVi0_~0=S*m`l_0O6Ms zpny5tu1`Z-VJBJ^gmcBc80|8}k-P(M7s`wph;F3~jYEj9dd};+3d{v(@;0{>PK!NXqHid1b@&M0IX_63bDv(oS zz$2GY=zxq(72OBa{JHw7)1w4NRVbmq|FruCkl!qbYw*@t|Bnk^6Z#peyj`Fd0Q(#d zh$=`*a|`h|tm&=5d;lJyYdBZxK*^y2DW{Ph0FPajGUyOlC04(ee0G9J zb`(`d%2v9Ji#7RgYOfVysq&qR3g0#qi+?=4+TK+w*2aQ*Twd3X(X)UX$82L`V>+CW z@xqtm=+jp?JQf>mXcX94=qHCAAy~v&UuiR^y8Ocd+-%1_LEWr(iR8{CF#4FTzbs(9 z()(jVLb_O#LF5XYI0kNvu?j6;a@&Dj*)nNNZl%Q)v`1b2khJ3ti?7k%UAj%~Yi7-b z30k{TA8v2w^_%y=!o@1a8jjQler@e`89=^-mrI7Hwj<#2S!(QjW6~zUUkPus0jxH* z@Nj(g#Pqt>^U9vISEew3T|#!yM^4Idwa($oyc9Dob<1JctYNu0<@*(6~7oB^%)ZLRG5!S`lC+)Ybj}K!Nuq= z->L1kqt$q~_BWfyInx*R8w{CbP91%jyA(0;VPHndIggX5TVlafzMfWQyPhnI<#Qns zG8Z#^9A4hyc_j+0!XFjMuiUa;tH>$u&X#o*qdV(69S$*2ouC(LoAKd}98A@nY~;9~ zF>tafB=d@~ncdIutJUaQUmdid_`k3Hm|-a`>{eTk6NkP}e5M~3GjY8KZtx&B-Sdus z-K3WatOC`e;< zWG4IwhtuO3=ey@yyJg*I#GLA2v1JC6QntxmeS~{N11QY*0*j@3dijM;gB;XM^5~&O3WYJpNhgT7_xO932TmF0pa==&R;e2o@V zud?8n(~TF>ZzXHHU0!GYYEe-4CQ-n;oHinc^e+HwN_gwW4(W#WgfQx*=5 z9>c)bs_4drjq%*IAw6LW#tRXqn&DD|Y!?f=-OV?|Q`A?VTEP15$|4J(mnB zg@qfB1phQs=q19QsU&{evtQd*X^I!!*RFGVH4L^P?4UDH_(&p=>eew$xP50LnyRw= zuAo++)0^+zoYNIYavsBX#Ob%tEae1=(jT-l~m_P_xw;LX~wQSB@G z$K#3;h;*HlFG|FHKKUR7^h z*eD=KC?N_+w{&+m(%p?nr-Vp%DAFYjN_RIK5K+3jk!~fW@7hN_p4V@T`v-jYo^b|) z0l4@6)mn2t^9kivQeYA|zIDesHrm+8(xzXVvvh^)pAuMjib_~kcdGS^O%|C0F!k(* zO=Bv8@@jQMnO#4(UNyW7*Wh=!0s{AuUsDUC{k}3Q`Q}<%-7VYtC(jrO-a8Vhr?J;R zdEWu1nlf&CM>@=g2!NM{TW@if0&2qNd45=Q?#5AbSnKtLlWhwyHlGKpKr-*+R)V^0 zcd=D5e%WOGp7s2Wru`^%N}TDbvlF-zjZTl#;(ivT$z<3KYSV1Vek*rvq|`GN858Ro zUp{)Dt}35f2&?BOrPRu}lSBDg&(*Hz4y%P#;tT#8;fftFEq>`2;Hci-#M3h@%+?k*eBkmgj%B%>;B~!^W84Pc9)Gyrzd?mwk0geB zrOOZtsE)hWS?ecw{_QBuRlw;v*2Jnj%Z!0*x^`YyAl4QB;J%(C>8tdp(r|YikUd+x z5bwKaNN(>LQfGo@AZ%N?ZlZ{1?QZw83JuhU?q>5Iy$RY#nMVlSaV)WG`P9A2YEH-V zgUCL7(7C{o>3-L?x^<09iFmh4BYDVx(cvnjoy!QpdaAqvQW>tYSxarLl*GE09gbpC zDb?T5ohNy*GhTAQWWK1c_1#DSkKG{@B?42C&K^|VqZ14%I9h1y7mSG%GVi1Y$BXtg z#40^wCFm@rFqP7pTk3j(QFl7uSqBc-N52np37IL^T2)E-sN56(D50V3<}AKXDQ$96 zz+mTePUS>m=|OdWtDf=%54D1Wb-?Un_|g=o^}Y%0Xpf$Y$s8xH0=0rl!4Q&%N|?QI zjQA9E&b959b5qDO7qCH?J(So{hO0Gd8zDjgcTuBv7tJOo+C+nnc1}=>G!-q=H$HzM zA8Pd>7Qh*!&U#lFI8ihyeDLw&ja02fSUn2dm3TOw`i{>HuMv+& zCtU00#oqG7mA}GgHNFxTFdUmYyY(_eCCP*+(XuQ)4B*qEVv9^xbQkHL4}hP@)unwW ztz_v8ck|Q0#z6jK^Fb}kM zjyUAVfyBpsn?;}op^N7xjso%rp^LGzMIZYoTk}PcwQrV$!`2z%`PQ`e;M`@jg@G0{ zM~~M&$@0#uZ_yLpi$&U?`~D=@r4st_SPt)M=Wr*ViMSypluMQEcXrC+gsWcNbiwO| zL0mK?l$8wbw+qAHy>tIeT5A>%9Vj@g$5=nqlkE+9x#K5VX!hW3^Up#2&n}@ciyR;6&1_E_h0ay;LL9%O5tNDvw`veI;*&0&ZYt+-nU&0SS zS9VVjqxq?XH$B-}k0!Hz(u=ut&gs~@ZofM9)JQ<`+i2QQn0{tbI)TiA5^=5?+}61d zC_o}Qvq0C9Cl;y8cS{*xgX+{SsJ3L+@TwwlAlEyf@#6B_X;EP_Sx7U?<>Z|(Akjn=TSNOg_4A9Qb*7j{{C@lR{xS1#`>qdNs@wVB6q zbrRUv=GfIJ(R)ZuN6mINKBMC0y>Fh|(ah{TFob)J;WxemuF6b2ONHYWE4&}NQIK#Z zIy{V@7K477!8BLv=dQsETP?)dT1)$2Wv&?$`7^;;>6jn2u!Ju@9C-sto@pmv9$$yj z6o?-rlTTqEo&F#Xva~9T@&PYu)6Hgc6Tb&;7HBuA&$DsM#3R8-2 z2{2^i@eH~Kh+SGA{545*2*|LW4ZnCBWn!mmq@vtl)*fyJA_*KX`YZ{Bvpj=Xc{AEd z*#8%CXxx*q)*-^6(*j^$UGDnkzs2COukn zuKvaGlQ?o}c9GXb)-TfFk37+eNXV23@Ht8k%u$=#4yAxeuFA)O?a13DTJ0*+*yr6b z-GRs^<1;Uss_As<_Vrzqki;7Ui`E3O)Ghz; z;K{-I`G)w6H!ajh5E+&q2RIBL9koB32}^usnL~KgTRg}^U-~#zSUBS>nlY_un-cym zI&OA`3BS|cOx^e(F4=oL{}Ys~RYH|PR6TA|hm6jHkHDMi`SQneM=*{5etabc;QZlX z^>FKdMa&t=FbuXC7ii^IO5{TgPB^cL1d=lvC_|rV)>xgu>=^YWL8IHzaw6AYG0=$9 zS{r4iWdRUtY3YPa@r+<1N)%pFD{i9r6m>9Clm!P-nIx z0-XEKy&@QikE-9giF6_E8zSwpcwcFi=+#@fwW_KgCY4!q9TocV5C*|I6 ziH?d?F!3!SsGR^g(EWyJPV3IIpsQF4XO(g*12g81YFnIToEBt=8UJ{pkV|Eb+wQUly}&txd*TexMjyCDZ9w@V=QSx&;u0-N@p zLDV!n7KTosC8UKsU+WE5-Vm3-YFrJ_L26Vlj!p3 zn|}jbE&Hp>EyQogDl-GD%8bzPwjZVP@OR<6v^Q$|_49mmTeaSU!9Njgun1v@I4%Ep z0`LrxuDu*8c*^B~SI}O#UAv z5C)l>6!tFJi;pP-PyT}KxY3|oa;Gva)&E6)V1XrJPCv3eZ_4i&)L)-$i5rS{4zxUz z{|oO-je>H?o40IO|FH0(fSvCOluOQi_J-rHpaTa{=w|;dx2pRu+%`fCaLHHZ=qBR+ z;*ujnx#a)y!5ZJ%FN@nXQ+$vWOFHWp+nKLuu7<3gN*PKlmyg$kk!(_Rkk&1!$&fFsN zuFe(_q~oY7Kn6j#qDTD-H@xTtVO8zb=kT4w-Dx)I+;krt9GsnkL9^K}U!D#aax*>n z7^2xqC{5XXfkxBdeo`oxe4GMMV6_d~{>fJxU;<1TO?G%)QTa=*A>0NpTAPRGz{4*F z*G>i#!~g=CzV7c6t-63`RHywO{hklbZ7hI~r~0gC#&BbJjwU$=TMpW%oy@w&3Svz+ zA_RED09Y+`O2D(AJOfvl_=m`QX`o*3d0q*!1XNJ4Xs-+=b(!1`S1WcGT68PT2T8#b z|A;zUy-)-5?36IBQg1XlZWc|PBzuvC-3zevSU1kJ9j|`8kS7CKnY;M)}bq z(|~CcMXz0XS8IK)!KbTFo2}0;H4yn>Pn(|@MK6~&T=NrdDyW^}tBoSfFGeaVLWy_> zSDS`kWPnohDs|;Isthl_bVM|Oo6~#1DVDvUpw>a2NGom;HAS{^;MnZ&%K=k;X zNqecp(zMmNb0^*+Fn;O^M2^jN-eM(A<|w-jgkC|Qy{vRT7*-$2kq02M?DK`@AeHL; zBIn&P5paQO52neYn%`Dp&2`-HsQ;tPo|_tuer zts6gJpkO=#R2F##U|%(oFw!|?#BJIw$Z?;#oFQ0^C`S$5YDCVZ{}WsneoPS)sb><{==Z(txoT zCbf~n-hCX#W&-YdLpm3*ye9hG3Q+2{)S>Y9Cb61L>?b-L={4HChNAw7Y|C}up=p)U zWsg+ri)?`e{d9kp9Qi9%6!3GD0%;lj7X*CXa=-(%PV ztrrVi`O95reHyT6)nfXRSbKph-`5hsS6tsAUZL>EcKB}Y_OpdOv$-?a`rg!6AHLQ} zFe^R3s$IUG%X!?Yg#CrTp*8X9+zYV{-09Rm^xN$}Dx8!WD%+)&f8H2~=M$e73wJ;K zzY%xc_Kwa}~XKP1}HVj%kb6S;8dvTb=^)t_m8+OKLH#o1m&W4M*sL)L=0hr6D?vRwCq=;bf@W=);1QOkj1abfna!ugZ2e8$NgL!}- zujS$~TP(aUDAs9F5##gNFCGAHg$Z!3OPbp}UYErX&)5({S+>Ilkj1ikE?7qVO=)iF zNgC@~;>9bYgW3|u??g9a!}_QD^CgI!-_l#k;7{$y74N@y-klOjbU9j=x17p{tUHLI zrV4xCnnYCFPU=Kta5GXVqz;|1(nmVDd=|(rdPgkauC_>ZRa)ZRp=RDD^m7}^poG<# z5$v7)DC0#B2d;tgQRTCwX&hCjFTl?&^NdAC!1R#a?=k~a_#)=z;;&;y0G#1PMA!g2 zb*Q;T{Mx49CuLYU$%t=5PAwQV*=k#uIt3m1UJh%u+fkw{fk8{aJMk-zeJLZAGM_Ov*dVw;B>&Sn z)qqD6$6a4!QS;+y^d~4d0CsYX_7$esp)QUrfJE3DbTmITaVe%%Q9j4Pglksv3D;D$L|libRq>PsMRsl_MrJf}(rN>lZBZgC7)L zm;49!tWTnmGDl-MZF$+wfcH`ItaRKZ_9M>F<%KxD$ys4o+&KRVqh&ZRB1TQ%)0z0t zCj&z(jZq(x9ck!eqCdjd{^JNRBh9wUATl|6eOA&rZy~pKtIwQk zn(I?|toJE%iV(1M%%8QX1^5tZ_QSsZ=Ni!WzX}2HradHbVlm#gr^1Cl-xa@SNh8OI6bU0vtSiy*LI<%T ze34uVwsQ_clcNlyRhbH_^(`*jc1N)P8^Wtn+l9(*sezv+P=13zm03G@{JC6*I0RNil^^gx*iecOo7k0XH3Ulxf4wj(|6{HWNwZvav}~3d%zfWlm8)w zRA#Hts-n_C?F*tKG28C6S=Zy`?1VK%Fg7fS6!5<4nxN$W={B%L0?(b-FJkuy;N%a4 zeIvwrf`EEOa0H@{=odt4H}~p5zZ;0_tYvkSQ1DThCqB&j7-eV^tw*+BB#;IiNHw~B z?U!^M#|^5s9W}VPnp5;~FKV1DRDW7hw_a3yZCdfR9fk8LLbxx!sgnO@%H}s61Xy_p za@M!43D1V>bIixQ&&yHlR3+1e&eRu_RJHU-wY!*3K0mt$}{$=-ID{FZX@0s1mGeRJD$W~!6yH~&b$<$9J;++9!j8Tk>NhTfnTLH7F7uWtTDEOQj3p&F0% zpgO~B<%A`ueZU4@0A}nH#j)uh8Jd>;_}EPMEtd4Z9NEC1h~V|Tww}~L)uY}aJ``m-e`<2^Y9Muf(!zm2-58`dGHnm^{wVOnu(p#ORN!sFFG}Lq(B!i(F^-3zYPJ2 z8z?ZuyyU-srF6FN*{yGKjmjHLPqyyJibZ6!5b_Trargx6r^m0}v%%dyxnMR znx3j`6tL7$GmK~yi(;C~en3!=fl?pnf=619*y3@kc*4UsZ`U*(k%j*0wlsLvV8HxG%~*288TEUGPAXPk-{~oifD<;=ALT88Cvs` ziBTQ~;F2b0mIuGdcJ6SJz6tuYKhTT6I>_42<$tHDI`wfUD~5&s0XHJJTL)fbOw0TQ z(;!l|O?RQWuV~r+^@|M>fZy=!v*}9zF-3zO%2Fm2zu62osrehf34o3X>IZEo|H5wq z0O@HxlPhBUFA9kR8Wg`-5v+>;d5Zr1iY5cjRlowb#?R{iH>XLejR%TOMO^l2{Ebdg zgQNTZ;z5vcTeN8Jfq6Sn&4DBq8bIVktIPqqaBOf(0r*DR*AnC|77UzE@e>P*!oPmV z7x7;_#;md2{TryG0S3);zIY44#KB1{pOLHWCH4ahn&N3dEl~mU9Xb%b7Y8hObrsL2 zAum=M=UROX0ZoX}(DQpxhSO)XLtw~}`zZ`(kelKcT9k6h$hb@aWZ#&KdP6HwpyiGM zTP~<$ZWPJ#T^BK~B#neXzx+At>;|p7d7%ljIqGNjliUM`@5-3DI-foVBEu085yh~X zD*)6)IBM_vAC`@;rPD???otD&AbX0FT4k4sQ9?Z~(PUtYagAmoUwj2Mo#Ri1_qQ)y zf?fP)K(G(;65^8B%w&V_;|9nL!W#z&OSPJ0!kJoq>N18-%8?5kmWi_m2fZj|;_}xk z02tB()Rj=K*?I*C^p*iaqhrAv-DF;uN_zcTaVP~Z(hIO2ae1HDtJFf`oUEd<0J~{BYQpgd>bllYCfVtteTlw%*5Gq% zP~L<3`V(jezjw#;g+x}q3KD7_XrY&l@8wCCQQdJn2bpg zbNpDY0y$$Dz}R4Oqwp27W=2FB?+@xA1@rTREuWL4g)&3pYc$$>b%Wm?h@G&k=zltS zMFq_FHk<&1FheW^{hZxK&2Z!TYv;WTXcpQLxWep5?}U8P1s7}et#8#Q2Vc6>6$+l< zk9`M>mioe3mkiLFdi82?FBao$V`BPq2CEs6Dig2&WW+B0fM2)>4rDQn>nDY!^8>ox z_8Wy zm0fq`6{>e^KlF3#2tjA6G8-H_nSv^y8{E}(VVpL4N(Ptx`CJb|CqE*#&FV7q$nE+fp8i;e z1Skk%8&9lym&JTuSI*G5_SII}Osk|39eo5WEp7LcebO=mNX!~tf^>ND`0AO-@F={P6v#{{Xo%%PcH$K7x(d%ngiON8a8Sg zwu|jpK15FATmS@JxK!du1E^H4Q!WpL>=P6#_g~@M&qTW-A@sT zCtN;Y+(FWFyj2BNMY`bC^9X`b+j?IT1JrZ*3-ApfPvNvX`LL_i+g{7^6!oB3o!O8L zWT0Hk2c%?^u6$OAg1tuEnirZZjRr!2t-Z{2r~BWQ&WzjIybtwS>XbBgfauu3aB=$X zMDw?s<+>b+-gU>7byQ_+uL8~12n`D5#|t}9GEPiR*xGs3#z>t#G49C@lcO9>!yl2$ z(1=;o5*P9hav0e;5PeXsJ}_QWUyBX6s49)l`?;#36*{fnC2ECg+P^p|roTXS9a1`# z>hk?i~?= zcX{GQe(1==GiG6ZN?_34sSHr%`k)Qwf}@0!Al^i_WX7&iU7M}aCuN>{Z=(rFc1J+u zyH~ONEJ$$K!3I%Dsi`U&0bup(4*dSmWge=fN5vaEa$;~zjcrRBg~;eWF)gS?@t-wX z*xX{f-8Mf5=&(xVa~f;RmTMub$Dg7+frxl#a_Yqg)0tzMnI3)Mf^dC>XZg+Razb9f z*B>_UjtuT$Dwk%fDw5t;L%{BS0!Z~EcQCc9o~tK(J5;H*U=iy1@FH9QjDh{w%=?Cq zHqhuKs$VBRbXB1V1ket1<@X~2iy@3_NLFbO%0?n#PmF$xyUcWjQ%Ef>qi&-pqFzH` z@$4F1+;{M?e+}b&W$-gV%(t&_%qMBU$R2ed3|t+Ef9kWMcz2vfH**f26fk7R7x~l? z?-NS_Ix9l-0meAmhpTdE_@zRVWCX4NW1EyKOB|iqWa&J}y{9@xx(2~W&fb&pX2j*E8A+!M_*?VOV5kE`=F>mY7hfT)r( zi=+lfcMJt;6_sv%jnQi<^sIwUS$KNdRMwLv;|Z03^3enQyXEU7$y)>l-GCo$zb_Rv zzJI1DER8KL+mE~FenAf`p&2G+?Y@eDR9o{g_>MzCu&C7U)G9i^y4x_FNJmgFwxPp* z5VI1n5HJ(37kki**2MQfBf2pkZoX@?`84S%rk7YjcIq(+6T0R8V~!tK1BJ(!`yvB5)w&J zOEfXTA^ut}g)@yPUn+q}%hGQ-OF1a2&2rjpF<&Xdb;n-nRDe*EvX3ceqZtb=7g8lUE@OBW8>V|R zLOIQj2gyHXpJRo#%Oa|3L7p}Ak3h4q-kpug>Z8j(o}*j&?A0V0-ygQi`{SicWB~0C zxMJJWVr$cWUVv%x%JKQLKlVps34$NVIjfO8P%njOOxO179)Q%(qA^qD($`3yCN%?O z`5|x6Xpm6g3Y02Rk2kk=g5P@G$9#M=U)&4-NhJUsNd=Q_y=gzHegH#jdnqO~lO*^` zvENB7GqUyee3tvUcgVU^I)$`K%k$UD-0Pjjg2cZimBpan(6$6Rtc6&Z^=1)_cQ6Te zwNUXmN|`_e_@p05<07O8MSD&C66c1mY?O?Q@{<<(;~qT!*vF+Bx@w=k0A)sRwsh;( z06jM84F+yr@uQ8g3k|@IQ;DW`m4P&$`==4U*A=~6*hXtX1y@0mOc?~vjQ&uAMciK8 zD8eU>wOW!!R;bAB`8y#qaakLs*684%OaUJ{93yInfROtmjDBDOGO|Idkx!k%X{&ZL zoxAM{<0q6`0IF7J`#7N%lZ}jnqt)^A4+P@Y64jFM@cuDcD*dV_Oj+ltCf>yB=f*cg zuU@@+du&L!|7*JL>!5&743|e?lxFyl0LFU`P2CqkJRs1h-4H!;nDx~+7|W6DEWzON z1u$*e7Dfc}5!DCFlCSeNh}}zd#|y`^zos;BA#wWiFotegz|(DI`v=J-@k%@``NRXS zApDe#89CqXGe;t$0Xq&wa6Ax?D-%W4Qzt6u#*j(KoHw`{64E>jd(<(GN{oW+3$vb5 zfPkp3HXOtYN4D;gpbl$;@%#%$Gu>!ze;gQeZBxJDjxe`aY9obelJOl>v5=^OE7SYa zE}P_1xkc#of>5w061IO>@q|B(^f!O~v8`)&+NTRhIY4kZV+|P2|oZ2KjA112pCsW;?KOMJExLG~K@fxj9|AoQ~$hS!}JZnBl zaB^=3wB|W2wn_OUOO8 z1DLlLsmqn2=VqWqVZZaJ*?xYq04WiKn+zAwyhHEm>n0ZJh|8g)Rq-*7*j@hywtedm99Cb(y>^-i+lYh|%Oi;%^;RU3SJEI)F^FmUN$h zpdgwEi6xU(lT-et)B8kIv5F2|V(0g02ZuZdmhYm}Z3Bk}>A-IfK3NZo3gnB1={oGw zjzW9t{}7gAAGYx-0dGzfYnlE8(ERx@qZWs7*hBJOPKsj$C39Fw1I$B++t5rHF5{se zc;SljQ{I~U?Z7JbWUdv+th;a3G9RJ*!UCWMg18hv{tvNU1}W_9@Lj=F(3ti2DSy4 z+N8gTBF0dl;hk>ho4c35;Wf1xG+mmh>Md`JNe-L@J$ z$jc*3PfvHeINl2Z|av+t@n#boR_3FUK&`aq$${0vrHKOqUd-<{?0S_}j z%S@!5^go;r)1RCV+C4zAhR#L*5#kIIOgl-ndf%Z0K~n1#OE$Yg<%%@6W&S1A=RbaQ zK{+5>m6VRx7cTm%nua+sSz^JxiH6=Zm!}6{Ql-<=hg(G{7W}roV1&<7jJ3>_b>sIY z3{{l*MJo92M-vmW+R{Q+= zZ2D#V!y=dYOKc-KrWdqpj}jl zeFelGQ_!|o-nMza#$w9_LZ71#-199Sn$6AFT_Cst6lL1g@%=qe%m5gonN2s@M^c1l z2=~MnkpM1F?UUhI-CDbZeB}=^KnzlIX`;7QI1QTAEzo5`<&YrGG+}qPPIDwrmI-7l zjZD6>pQQ!4B3CqqQju}G(u?l$bU!**K4s_VO6e_Q??)gpMi+J-wV74vtOnq zS2|6id7(aP1oXk~?CysMvtih7mI#Ag7*1cH4X5Gl_8J{DpkgdvTi$LF0)U&=to#4d zygB`B-p2Q%fOTVH5?kJm`_d|KdCxKVf>!BzU{?~z0kD#c))z;?jW-nw|9DY-j6f-M zakZxdu*ul@#o#>|bL%ztt+g7Z!GoPe;1@v5qL$a00mdu^*T#=E5q^mMEdhC73kQN z?1IsWX`x0$oq!r7%WC=ck!_m$&DREY3#GxnLEx=y1FRHt<&5aXjG^72ri%X(9gDq!2F0yoHk(jsni-Q}mPEw>2{N*3jW3 z9%!_JYN8t`Adg>y?JzvsABN_4EB(*n@Js(X7$X+#%Tl)c>HCVeOc4GmkZo6ggyZ@Q z691BV?qiB>`3o1gU2RrS$i!)7I!t4dqfpGDgacf_?YNo!c5B(-b%V+6<)P0=rKz-=0oGa@RXVL_ZWqj=-4xXCE?-^4(i7e{4gYvN{Jp zQs7Gzbxj)wQD1i-h)-{6l+6a@nDP4}!hl=Ghlsjm?A3wi034oTtE{}Zw6gE}eKnPG z#HzkCQY-JVb>t*;4OKaStcNdB&%8DBwG`Zscg^-Yw$)d^ym!Ba!lf^49`Do<^0-g& z-;Ah~x-r9ZVm>)mzmHl(TIqRBYqawm=}|ZR?-m!j@A`vD0|SyUKOrYlTUxoz^dT!y zlUWT+(AJ2zwYry1&o#8}lwZD^)hJZ6oS%Z)tN}H5+|E}$!nfHfIkfJjn$cvX7gxT1 z+gH&Y?%^Eu40vC+b>;@$s0G9ECeNxEQ=@C21-$`%rX)v(Z6Sf?L@VG5bXRk=3y$QR z@Rc!$1|q36s^MxkI=`k@6A@qf_+uyE@NKc^F+O90(%fgo$5ih=)IF65e~uA@A<@_O z=d+Vc!9NbAnCg1v_W^Sgn1PE&63Kh-kIveNHaM>3SdDMH3xPNgR*jPIi83Ez%aQ8n z+Hz81sb1`oV>fDVP_>UvifIR|F{tL&`N=yFS+}7Q@e3!jTjrP10BiY2ULSUof(lUs z2P3l*9{G-NzxWETuaV^+Wct-Uc3gB3`Iw*A`hwGTw!3C$(pl*d0oQw@#?Y{&K1!H6 zc{V@OJFrjhvy^tQP=}HS-;xpXxeO6!i)3OKoebAU{3mNf7%oe!t@Ek$=A%v(sWxvY z>Mq05{fpylMOf)Y+t<>hk3hnH+v4GRqGKV+jCPB&07d{buZC?03B^dkH7i&RiKW$_f+Zg~S_-cF$ zxg4#RTQkzSPacTG{;r0h+Z@IPy#Ky(uy>jk8FDD7ir+vs3-lgsAV`zDY>)AJMInPj zAbCLE2Hd!WwUMPVHxY8nmmAwk&ob=aK88&+&A#5NLq43$YR%T@pPBi}X`h~F07sI2 zCs;VkcD%6xCShLzks5b*ED1E|*U()qiRPBqC5Xwy$)K z{n@^MZsiz-@Q(#p)m~IF|5Z+6{=fYbKABz`t4Jo{rJxc{BtRW2U?)orSH$I{*Mo=4r**s zEUtTh?Dc=10l%dO!1I9LK<@vj{jFd z^l$$@Mt|Tlp!@9=3&-CdIFJ^c`>Z!9LBF$cfB%8-H&El>BVx+^t63oNQvxpN4F6YO zlpjJKuCQk6;~Wm2!)YT0alWCxQq&~#GE#ZI{=S)^Msy^h{r6;Cr2>4NJBGqzVn#;p z&mS0gaDS1`W$O60xY#lGkZ<5T?b3Ttf1evEP{B8o!P#I{5(X9?L-_X>ep=z7b!9s| zvEM)V=U1Xs!b8}+OpfHfFmOmDzrPS+kysp2bA^-s{=q-L%6dp*aW4(0;laPJ34Mu3 z6pU)OxRlR--U)o?H-wB)9W)R&_vbaicfL;%kY@OMr$~WeoR=XB!Uh1epv^ z696??2H0^>h`?odw0K?C>NPqKPb6}`zy!f--tV@()q)h#`Dq?fDa74DM1%K026c7f zT~s_N&>sc#fto?T!C|?XLOwz6>*v=y>rLL*$$BmB>d>hws7zi&hPXf}#E$!O+F*)X z0A{O9LspPWNZmCN7SpL?=0=CpH{b>l1Bi65@h3Nkpg~#y0LLyHQ)&V!nX|Xd@k+wTi(|f~xvwWE$+S%xN&N`f#2l!8?U(W1Q2U8oWD4i1M zA7EEs{}?^1H12S3c)3>yRb$;;?I@m~jnQ<+?`U@?b6Dq>p3T~O^n!G*Z26R0V0KHV zd%BZ8Z`$sE&S^vlxC+k)QYqD31h@O}%CQ*rw0K>%AMNJ6a&w!8IWTsMB;vD5-RWX# zy&px!gjL~^F5sb|Q*HAENU3An1A--`hF-4qm;(R9H_itWVzip2c$+mqKQpp*jV^~V+f_S%Icsn@Y3L&zgn}hEoG-y9cW2J6;H3N@RK=eu!-98p6kPt?yy=*s2_h+{%;yRqq9*}}n5M-*JXCB@7`Dvkx41c< zcR2PcKxx#|uUnTba($Q8@{j_*eCsvx!_Ttec!F-uw~ffFpCbs#fqE^r(oD-_`6H8b zu~x-#908jEPf;I6HJEx&8(WmM8i)b24wFGk43~>OT({xlPzwz0Vyzd$%PCMMK$scQ z%6fmwb8r)L9 z=QvueR84z*AdTF0e=b_ajL&tS|MZ-mbT>I4dWw| z$@WCuIZ(2$-gU4;@UyW{8mpHU-#ZrICZS&Y)@*|K1TT(9+NTelkX0|4!`2SHgjpmp z_n`H5;;xN)A3^Se+>Q0MuY&jFt`4n*JQmI}*4LBYU^A>=Mjf9wl*Q3$E)eZZefQcL zuc}ik(Cgf1(r^6a&1hKB=dI!HFt`8Xl5P4J(`qTVKz^t8{n-a;pK?CflmS;fo@Z~b zhf7;5c@q^p5I9P-t7L%Bfz2Jfd8W&yWM{s{Y>3ybc}SL3WIP(paTyVP zxpL`@hThZt0}Zow*!k17wnZriDfWsz9*K8YXK+bL19ZH`YoH-Mlf6D-*R~jTU2(|!B zsr6ScRI8%fjAt@z-yh82;u5cfXllz@tRtQ8kJExMyzB1(8y9;}lPKo%+}dic{`DqC zC0KH&uYn8r>r+Q=X&iCO$$fpk=6;^sjK-0S(|pS}=Cv-j@tQI-*T9MHP3?!ULJRkC zJu#^fU)a{h>1s5pG!8oaZKY=M*Pa^1{LbHeap5-E7NtX?tw{1{o<^j;thk@2=X|bq zkMJ-L_MIRxm41Vx#Bu7W5h`0t)x`m5?N5&jRH^ou)xFSeZ!XJ>^wDc}m)Dy!>O>iRIlZ$Mu8B7gOaVchfg}Bn1`k|$^6ksw$NePLfyimw@KL6RW%roB5DVr7443! zk$WsykIN*r8l}%qoNFs2o2?7UvpDTKV~Og5eI`@t2^76l%D<;gd>d~``kv;c{ff_ zYK<^_z>WG0I~Dmt9X~4^x_=C^K8>L4Qjdn{+PYkr`ti@s_keb3wB=!z zx?p2ZDrw*V)+XkL!pJzuWQpMpq-^(i%V&=!P4$r)igXmE0YGKn!UV< zq|RotHdkL9H9kn>B4m$EQ95#qucrD;HpJDcP_Ns(D|;S!H4-gkRN@I*QiGyuo_zEH zWQT!Qk=7|!&JN`1N=k#Iirv(P*8Zqr&-3)U4Fj&QN-)`4u$A2~l=u?Yd#tv_wl&<6 zmu7w1oku)r+k!r)+X`GV`TEoX3Vl8>e0~roWfoP(D|HX!;*}%}qyqH$t1`JE*Rr zQ?(*F2b=dah2zJRC*JW7s#U(1}-Wng>!|A)C^db~-R!|f;i96U5s6yuE3iF}kUlw3?C-a;{O-FP99Mxp%)OxjT}#LuE()|lXOW9Rd77U7 zgBWK`35f1V>68*ooT=G?a%<*L(l)jU9QHw6ZuXM{{P#yVm&uufJ}652?Pr(mPs`7W zPR`3ZeDHVwbY$WX;rncQJFU{1(TfIgmLegU`W#2Y$07Dc(t{oz9<%3`q}R)Zri@8v zrIfM>bA&25TJz|9FSkZ0FW;LJe#|>@*_>KHD;t%NlZkgfF_sW>R?v(&hU_x%7LU4) zc#IPf?WLs%*=M2Zcx9X&zswK>c|}zp-!l!MF}k_A;eL=O^~QB|IN2(n0x|7~KkQNk zJR}R%%g8`HVhoNUJ%JvF_rT7Zw-@|gh&B+mse_0!N@+U?A1T-TY08A=bqVS?;IqSSoq+DRDNrA@d*W9ajD60!>@}RwP^fy=~-lmWp#=WDq{A zKJ4ZoOYL^n`b z<-xz}4fNL--{IhGAK1%;|NX+{t3KS+_VW}=Z3$k5cMshcQ3#4kZS`5K}J{aP> zck#maXjveW=@ZD>Nb(wX0)2|D3z%2MgO&|yJheJAZXE*>i9lLy?Pk-0)PLXN+Ye;u zJETu1*I4&8ed3+*wY_N$g04tjwo>q; zc)g~V^4|Dd?RRZK?n?ZJFA+d#7QcJmaZB*>POZ0>PrS`^Wp`Fb2qmz>j2zZ?Ecox| zUefi=?5~rAw>bdrThMM|(q1nymB$ew|2rV`e68t`J>8!s$CYPRFEV48Rn2Rkq8@ch zAQ6G%n|lEoh8TWrM-W$#3``vi?xGS|+~F*7_!#&d>RYA@O)_2kniEzDIx5zebB{gb zJWe_7r-7FId9*&CYgev3evVyQBQ$Wk0c<+O230bg_6roycILgr8|m(t9GeDEqx5dE znXh(=GW7riL@v_c#aU{98}Yx-3Aod~)q@)WJ|+X`-to9BA3qNVOtbjhe!QmkL^A@u zm(_9^f~xz;Fft*07m8xRXbHf4vNvCud``7$G0_FfA7$AETfYyq+^3RyOI(Hz-(uIHKYW!w#t|Rk8Lb!KD6Wr;f5T_AUBoy#U5mf zjJ;!Noo;Y&_uME=t9*7&>*}*P^Z+!s0*ewhgSvxdtrcIYuh)8;DHfg1uU4UyVEppy z!(JFyqB*0{FjqjY6>>}A@=%4=>l=^x{^v5g!Me|o4SAjyJJAxx-u*}-lC3_@G&dI!Hbt}pC+vuAbJ&NuAVGkSo-!4Pz>^?3*l5sT9}3Ksop zYC@nHQckJX7T=aP@U_{?0_kJZ#tD$Yozqf%zFkuNEyvN%sNMYr+`Cz?U!0eFeZAXl=F{b>?D5v$h%`BVidY>gQ zH_X*GW_8jk%)bBM4=-K`<1|BtQU5g{=M3Cw-^}4^=$?#c0?2z`iy5^q@9g z!@ee}c5kMuSexy7^_~@#B52Rm1`P~*V<^J{dazf&YZ@}_-Hj-l%x5I_8ByOJFEc4y z2Ekq;2`ljbeLH?$aIPGtzJxBTaw`yIp!EWaUFe*AS496Gd zVdB=Lgmh10nNg)czFZxV8UfpSz?UPV))yf~3GWR#G0whx%A+yf4C#jGq z58+#pmyop69}K#+V`GV;f;XG0u7att8UJ&3L-F8P_ER2lFj8LV1)*^@dz_W>8TQ?# z(KJAG848f!i}Kmag`FNJ^KA0n#k# zE|Km=P?7FjqymdtEOH^e&-MJ?N8z3M_U!$~p4s2b_n&hQuDI8AU)Oma=MjH^NVkJP zWNRi_A^qBlffeK!+P_&j5hgu9(~UARfqqKAJ@#h0c>-T{=8IT<4|#TjmW!WkNSZ%m z#`)cUmg?UY;uGh-5rW;>)6Noug|8TD^87>kKVY*f*->ra9Om!iR|Bfl6sCX_pEe} z$9;v#OQs|mFftXh!$h*t2--Y}X!`|Jz)xAK$Fe(;yVKf#NK!cl)u$RUz(_#Lv_)}Qu;RKL2a7R#-$nFDg=Bc-B`##4djkhwpp8ox1 zmO{kc5qvjrk_&TfpDNfczuodf>E>hX2#xgBOl`Rk< z?T%g3I&PPcQD8lRkR2ghsMxmrI1$9}uoxK15Eo3w;Zf3G4p_lk3a0RjEKgddb5u)W z`3oPq#5qLnSk?3nk;L_X3d6>D`4A8X!MJe97P8{F`}2p_*gtUNJ!f!P07Z2^fOmsc zE+zWyL1L!;&SF0s0@(PHZTuQlbDxT;msrMR-1LQ0O4eaGmWEOmhC;U zuPb+dL2hY`n#>>#2yDmj}u{j=j=eAt`tb@&vTrH43*2G8JC8ma8`jEjX3&~7a5 zAyBJqLSZrd4sVDh!G|ZQC5oqEy8DuN&F>YCZ3R?KYm~5RBv=Ljb2<-2LLo#0486j7 zLWStN*B#|{J$BdAWIx^>Ep%+p7WqVmiJI>$4xv}DTs3<-n+%C-jbk1ddxsGPiq!Pk zGFKt56x*K#?bU%FD8@)Dyl20??<$vLA`>(W9f1&u0N(yl%Xvk`s^X0?%q@?-GN8Vc zqv!W90;R><*jTQ((YRkp7PD1ROeJ{p0FRrm;_z8kEup}innhL~tC7&WU-xA|pkd*e zP6ix}&+8S&+4G-Iy&E$@KA9$Ou4U$|A;|P6=LvkASv3hFBEwrVY3%wlPX#6J{ae{4 zhC!*@IrrR#gXBVoHZA(pR%(CAO3y=u!EtneupzF&r&4K&Wm-`_hf|}s#IE}GSam3_ z2*-^PFgq)|Og|}hZJwTg>K%J2)qk#62XgPik=U($z7A}vN$y5=#Qu6c$yno>$$pih z+qmZ!huCP9+;3|?OuAl4@l_&~z^#EX2MU+gs49~HQcx;`{D}>RS)%8!6~qeG;WpGazPxgruwk2_ZujDub0Aim0^NYo)Rgu9xqb>^fXE>7BDE z`C$89k@P{Q*=k(jhO&h=l=8#Dt?@MaN zuc=MDV!7pdKdB%TTBGxT3?>6CgN3}@olaeM`KDcSOGo0!Y5_q=t~Gq4d)Ul^g_-;WMVwf(;^gzsA_u*+l`?+MTR`w3> zYvTW|6G|~S&>NN#o;N0tc1(EI>!b|SQ*-Y@aynjpt^HYJL##B#(2wP2E}*YKe! zC`mG>*~{AvRcNz(_ToQyFpw1uqjlC(%Jk+peXyZ zN$U*tr0|FhM0d5PPLSa^4UzJoEgc{>_@2&IsFB+gr$dI6Lp zG)jr$4r;pc1tM=t)TNS9vOJu!^Io*n-SQe5jatN9^XGpC-}g2w{-8Z`uz*e5Uy3 zZ8Nt1D68U7@YgQekBp=&{$;2ZLwv~zrVa~i75C1Rq_bKB;SWwsa*XD@pu|J>Pn_uW1E6U3BfwVo@J z67WK2iTSi+o+ckNwAMk9zwdq3eKswA5I0X1gh$VAF{+JZ=Mxg~6YbVW9M-oZdh%V#ZNRTM4W8?_lPxT1{W=%VSe0IsV({--br~ z0<2o&73wno_~Uk82q_rVpv7}!@Su0}I(ppVHt-=eam}pO(zEPA%i-jNh^XS>c1<3^ zocH=?t}JD)ad~|RdG;|jqgHuqjcihNmAJrddoR31qa;|==fndzH(SjJhPE3iZ@zAi zW)(g`wa}BPI>u@;mN*r)XyPW}Nnn17NrgDK<4uS(s-1{TV7Lu!x^Jn`c|G9*-3}cE zeBzqXrby}zL{+R_O9&4*JT=7yg3o3wAFvG!y5 zdAGN`moPQkN_|;6^sQs&jKaHXJ~INv52l5B;=8x0eh{sK2T^Zb%l5W>6C(3zW+$(2 zoI->=7E*~Cju=`T&62sdL<*Io1EsHacZ#&YW@rH zECFv~n&hPxe&Q!jhj$2;jZc$Y@BQpHbD5flBzsSMv;PC{oMQ%L=S%z}-+!0cKQM=Q zvPkVI+H>msfB*1*it?8-K;F=Fy?B_saYGfZ+PGy<9PBdAoIq@^;_Tg73gR4RFGU$K1 zhkxExq!bRex^I%YhhM=4m>xI!5krT#B3{-wR>=E+y2Gz92@Dd6Y__7mh$rqAO`Hd| z2`Sa9!>{lIm?`fybxi;M5;!tS9WC5rR-w~}Um=JIu9j8zd^mJ_{?85m&+YjC?gmpk zlsrkoX2tQ1At(y#>h;k{Q!rOugLA-WZBI}o)`s1 zgPljU#D7+~NGOisgu2-&l4%q6t~k6crb4Q!d|gcQSDv0EsNF|`>Ey_rCSD!20f)5+ z4##4a{Xrw0m!+}329-cL0++S#hK<3z?*+EaE!6>EommEj&>;1+?i5uoFVVnhQdVYA zVw}dFudJ*z_uR;>1O`F4X>X>~hNWOK2*tnjZRVbV$Ug*Ffcx?qBP$I;h*s(^6c%}u zWZ}s7ms!<*qJ%Hv_~3jV1JdqsLNe_7KgLnq-e3`U;Q$z>Bv1XU+$M3@!fDYvoLTE9 zHy8_^apb4DI;61*4S3Vbx4*=K1!bKIQJAU?K52kjCL_!T%_&A)Tn&)B;GJIoD2@KK z$^SIbJ)zTt(gB)p7+ub=qX9t$)47}d*;*ms?Dul!UA;1$_@$7)=m&Mz@fj0B`eiDQ z78|o%VZZ%RruJ#)K1z+eXJre+MGxOqKKi;wUPXhGx;GjcYeEHuBnHGkO4cey19zf=1wEp6>!0Rp54_nb0 zgzlbqF`z9Ks@yh{*6NkU5ntb3l9`U!s<7Yh65ME@dN%ZtG3ow?pkEE(K|T^ z{Dv;*rgj(|KF)nxL(e%E$YsVpNt$Ig(wQYse!$!^_VZ%aG@v& zZj613!R|t;S*2AXF0YLtTF5ODO>29Ug=pqUiHU)4X7!`eH*095WO&q5uwB>1J1TDR zyAQ2_Bj>DOkrp(1ul>5#lSt4WXKxOKqs7D+ zhfomu4~k55B>1rJZkV_?p_(@;?Pgbk;=bLo)4gCJ=_4yA=KCQKi{>AwmDu2knur9c zO|P7E(2bOfw^tVuZIyjHlfE~i4EM%2#&)U8uDfOUy7I zv~l>DzNhl4!@QV+(yd2w5kKHe~re*idIc|$Z2#r@gjm#HTdQI%DOuT@P~o)jssov2PV z?ftZU>i5DIV=TQ!@q%I4w@_@hU1O6YJxA!8Cye2L)Lcw16>7l~eVbqlHJa7Qzatu%NI_!LO`Sc*{Q!roP z#0OwP6^j-Tpoz%$cy#1zd_5v`%lQ<#JWk7y?c3)D99+OqV9n&%Hb>j7P7@Vq?h_%C z5(O=QPP7;3@cR1P_7_f&>a{WaM6I@=`Q5QTL(ivWDR^zZ_N@al(-?k2(7gPXgmDOm z-$R$_!Zc}L^|^I3ey5emQx^7}bRI*6LSKfs_2!wsCJI_ZD;o|}((N(@qCPGycH8dg zWXytX@DtOs9xzVch%v2hM{#0Dr(?`Us^=yy=3#Vfy=^w)2f<~gdZbsk=#Jh_zqF9G zqDSYe`$q|f>Xg4bMw$Pu$^@Lf_T4uHx6GW(vqe<(>_*eDHT&x!1~RHc9x{l})+k>V z^?Ws$?HFRDbyA1hDw*U+iK8XDatG& z>;{+GB1qzFYR`D}V(tN$*2;7STj69U<}17hSxv@ln(L-HZ-v-UI<4eI3uhYvDSuVr z7k7H#FWK2&y5-wxaZx{Vh9@G2oHnFDG}#Ki|#E7 zUaQyHrqx!}vkc`Y{Xz;)JkpuT@)|-~l@v0`0k^cD*Ft+uOTtbmV(fbW$LhuTe<=-b z2xh9g!IEmho38w5`ab0A8Mqj~GN~^kS$!N77{07Swf(o)SCXNAy~*}lH0SBrqU`lN zNFd~~8j3wX_TKY%H5t0ByUa{9W+SG5u-bk;T&wXmXzJS%6y4_TF@lKH;YaLVNB=9? z(K|V09lF66=w*o?YXt?B0SDReTzK7e=P$(w1j2l%uyIY_;oXvqlF=@%=zKcgcRg@R zAiB2E5s&D{x}a0rHSsZ&okm;(Ek*_=yDK8i+wJW_e@ejGkee_OnG~3(#ylEpPGvf4 zy0y^FHo4w!h9A-YkX}9#;R4uh=a~xvXU#(njc#NJ4s<}2Jb0IHI1R_D(P(0zCRnhR zb`yQ^=;XlKWv(Od{bCEG#*-c#`12c&0i%|hO0hX`?W_p3>(T2PWj9%MJQ+VFo3b(om{(KqS9&+|Rba=Pxl+GM_iKUlEM5E|KO^zM9dNQf@ zLdE1hSjm4yR-RGUF^#z)(R6lMtHxa}oK1%nM{>5C?QZmqsd$|poyLK4-foK#rk`ql zJTB21`#nwYz{kI#HvX1q2&TyTqsRI>3CvefEN9Nm!@T03D#Z%UGqFc>`5ZV)SV)Lu zf!{iaRQnb+wpoIAM9HQAh21>hU0=JMVTAY&k9jV?iIlvo7)UjEh0loNW^%F0T8w&Jvh7gmfd_ZUzj^pV9`!TXy#D<~b02Z=9F(HdnNq4Vlq>72J%t=-#Ata7lQ?+by| z&}7I_ct@uim7+Pgf|D?4v`;mUvRmy543=Q5ocQLuai$|UPJ}r(9ug8rEn;h+iWc)F z3Mv^hWxR^YV#^83@6~L^F?|)kkXi(i-n@TCz0Bs-!a$kWyUPrW zE}+YWk(_i!aL$9}pKLM<1FnM1tOt0tXJ5R;4L;XSB0cow%tWSKUL?0Y++HgPIHuX& zO!s1QCP^XXe(Rij8<%B|H~{!ELzSz=MAfcw3!_=S5T5pUYhz#HyB`HQmhsuqq+!F- zM2ucrBZ#G&mVY(GXmvVlug%hv=W>}2*RDm!IJD2+-&oXX&VU|oJRZ;eLyk^~^t;PU z<^giCoN~Ader#=V7JHsA!mKZyHqLb=Vh3~&AO+AzstT|Y$hn6H!%f&aoCqJgdT-N)`*c>yE+4pzgZ z*KvUP>f!?g>rJNcoZxVlCxff2)2(4Zc9ll8X)U-*cWLKP1+F7W zh*n(5ns3(6%2R>G5>awKisZ4<4am}_$Ytf>xcYaCJV`x%2k(2$W>Q-Sf54-3#m@Fl zTng)V*@$7iyFk!CD@E}nqskc9i}{=&Dc!uvZBB!!+3*_a*A0z? z+&0?dgqP2wXL`mJT)yJY)OKDEVBuYt&}O^=aY$yqI(tJkaXVFxIf8E31$BPcJC?(x z4#E!60}ek@ANFkymzkxF^nkHfs+=51i;KiK_qUo+TkC3N`BTY2n+mSQcPt-h0>7~J z+kg8%*q|u$0D!tnSqq4(`D|M30|Vh--`*R!6ml9@0N+5vcKEK4SC~s}|NWMaLNPIX zm=@_Frd0c3p8YgI>!PuAU4<&O8Hu+>(_OFVcvqL~?4{{}KT&6Cst~(>asJEtZ{fDT z`!#HF0_3=&u3ix7(@O^PfoEo&qg+JAoCZGvzqr5NXvc7*4l)*QSk-!dS-Fqq^HOm_ zVPixB03{ft9LqO&uN5e+b1D~%_gq?dNsUDhv|d2g3Ox&eK!aYo);y7hGvI+;i3S`d z0R4`zsb*IuKM3Qy#3hKYJXvxwU?FuzGlngH$$z)dM4JlA9#m zKD)oEP;S1js^d^18dQ+(%X)VOcph8r50)fMGArJy7e@jiC&9(ameya*VdH_0oRKXb=_ zL;%;|c$4%#MA;CbK8?c;zxdYC{=r-Sc`bOusGDE@614w036BFNnK&*s5&TzEfcuvu zu)~7J|8_~ZBleB=(Y&N_E{ScKa+|4l!2i(#a-06%a^k%4er=iPfz785cxoDVm+GDr ziZwVu4DzMTPe@YTEN`2G-)ZS3pw3ReMX4amzyUpEpaE3%SJA>AqxGsHwuk=k?y1`X zUG)lPAlh<&qM5Is*OR5uF6e-2qlgehkqnmE`sz1EKW;*>v4LpGx*f-8yUe0ZGdhY$ z)^AjuN&y8C!0HQ56b|5A0Df;H%(!D}&k|lGpC%eQx@o2 z`ib9Hf_AQQSH+Bs&-@MKQa;2{^`03o^(5%I;6y`I(F#JFvZk<~U*)z8B&HbJrY)&EYKo)p;u-Yw3AvVEh0hKfTduQ{#Idz7h6AY^I8#ez;lyEpU z*pa{|D}+s<*dpsen5n~z?&iuR{l3o;>>i_<{C>~j#$$Jw3|~A0B{>cXqxB*7_q&d> zKjF2Ti5Jv?GpR9@ppV2g~cocX7d#Ljd9aK~p zlg?0aYV!_EWML4ib(SdE&SS!xcExO8NB`&7<)3FX*4#{n#8k^3NVpg;C#Ha>t@2nJ zSQ{EH9;M&YxtaU)%QIewwU5RDBcMbaw!w|9{IBwaf&WYMZClH}&ty=W)k7&280Wrl z^Ukx6Z-QRpp3Z+tSlsQB^~}CV(#ZyL8wDBiTwdv8CH4?3k?I$*aNTI&CzRaDGW~5` zSx7{%fYWLEiiMGRj%ej$0)jP$X!6F$brY9rZ*^C3Uy-?*y&B@+GTX~Pf;{$uzy(QW zFn?-c8PJ?UCoaWqT?q1!%M;_~vhGO;i7Z5+$9+KZ=qdd7lbobplES}2IeQ%|y!X*S z!xR#A3eAwC7DZ5B;!bl2hNkM8s?T2er7(spGx3k&CH#fvxq2boHSc zqzc5zFka>UT(Vy1mR8l{l$71VQO``u^5hm^*@!b_>;tu#52ikKed^UXe-8bBl z!vB2bB?|)L;o)I^D;v$(*;a&v+E6-#&)>zOF?b8zYO9dzb?~-PUU<_Brj|w6m)v$g zzn+=}zDU)!JjR0>yoViV?bLUjR#8o`=%-pC1i^rV`8l$fWhFpeK-`xloK@?-(DoW3 z{|Q#m|4inWlt7$PGl6aSQ)xI((K{uO^#nmjW$4VKP_;jsE~f}0mEGHrbAj_c4^?b| zG!5U;vABGNmmw#dkwvS*-Q3p%vN4-jH*-*hi1uvm!Lm$-kcKLG?t}a8c<0I6Y3R<< z6UaHJegVth5g7|h%^~jKwSjp7VId_Ec5TE0Do7G*?RmM6x0T{$Hpfbz*H4pt*7SUL z_uu96&(B494&=%wIsE@DqJOUHUU+&vIJZpc^r0SS=?xqWk{?a*4_!SO1t-+N@U2$| z@9D`G;&3$FY~l1iboHeiAhPC`p@&Z=0btTipED%?+vxu@n4*Ib6gSU7~#>hnUa z5p^}?;9UZFHSXki8FBy6Rj*v!Ag$G3`QT~=c{PmU1nOjO9=a+rfE&Xx-mPz|vxpU912>67dFv5{qM(Bi}o?;@nWeZAY^*o!hi!92IfImhx z?kY}M>N==_s~K>a-CzJc^a-d$EC^PuLgd>E^th&2Qa>a}yZ_+84%zf)U`H~v`Cp>> z0Y0kmFU@8t=0lazd{z5j>hq5~S;D-|W@C}Uw$K_jA6IVqJhp ztOoVHiz^a{hd9T{gRyvR2T zxXUFQ7ljHnF5Q1?VKE`W`X zBYCB#CXGg6v63#`MGM|tPhmb_anN=z5I&n!c#C=pq_rEC>JUV5nWf@Ry=isBY!;=& zuf;@Z^80c84m-5MJHM+0KMPvrR4UiCo>$xUh|sRI|9(Smt_P=Dh;sbyH)~UOMuA!L zH*HD7_bi%7b7;pj?bJ->dQ8Mix>IH7!x&Y##nijY9MiQyInOOdm?H(|^^;|&mE%{0 zGVT2+c>3HW*D4ZC*5@AEz}cOl(ckdUw@E&V`x~W;kcT_6d7Aqf_ZmNrWxE>fC-~j7A~L>#*lgv^ znu(ALbbgNS29C^sBunfoU+2$vY^T(y2GGReO)>!iPL8fHN-IO!oMU(^irB>kvrCLK zc-q*>+1+lWk8`Etb6f=1N^EItKNXt%3PHG?P`9rZAMzmxdV+YON~{Zx_wMo2<#uoP zJc3X){*s)H5}|tDqK!M{bVNgGa&e3}h%iwClC>pwd8`(XUOhYOnDj91Lt;IN?Nk$O z)~M-qOl7zHlghy^lD8!r2J>ku@*SyokZXC>qQe1r`X+;)%B~5!4->cp-!cS(O{6lE zbB3HbA z`6XdrbXpr?ez3q7hVi4=?}EE)9N4=DKs8DQFM5X;`UR=2Q-emf+h^V`U{fA_($v2H zf&BW`O@2;kkMxb%?sn`8<1z@GIi4FeU2dVzNW@vCm#57^-^$BI!B zB|1)Q{ut2#GZL?QvBeWc`q^c{aLeE(cku zovAXE;8y++G}AmYwoLB~uMXxLl!&RV7Z*y(g%F$dP|9e{B>gjyY>h0Mgo)(H#Aj~X zlY2W=Ryk-2w>{CN#59)1p|V>Y$_elq$#*xx;q)IT(PHl$#jhUDQ%v(c#FETOGSCv#!HM7;oIg`yg^{ z{n$|R!&E!<3aT#QCvkh}{mFO(JI7ZS9IVj@7LB%Pjmj56F%4<_<$+Bh!1zr{h2p*( zpKn7^Rl^U+*e=X8SNpTILqHN=_9bqg9j6Aj9sWQeOt+;_L&~?qWlwF}QAny*Q=wqw z_GGBYMb&U;&$lOg_qDNSwn0qK#K;H8Rn6hH?mlk5voDEHPZjsK7!B|hS!npheiO^M zu4S&{zFCG=>U7fMGV2Kj6*mGE=b^2Vt*JYG)WX`ACRS)S$3hcDc|6=s>D=yhHwZ-G z?@>NRkNz@P-fQ$RA-pk~Aw%(C zpY!jxvS12;Z-y+kd`|kTld?3$koXxahTV@evNHw08)$XLNOpzpO0(E|Md0Ya-z?Tj zF{`|-iqe>7L<&-MUl0YJLdVG`dq1z2!=$nnTW2arE@En(wK{1xnpE)8gOy`JwS6{M z9{qNEvO8em8t)j!vU`Q*PdV<@AU6JX!K7Q)(5iBx;Gzd+v}(cSvt7a|q5;mw+=3Lx zTW?FqZRwS^@>?N!t+1Xo!hHC09#_mL<)90r7(Y?MT88=jb0AkqaJH+cfYVs5pVjht z?U?}PhpB!nnSvfqROg}cFe}r$9NIC-Op{PQZr8XGuYATqW9P1KRSUW`M6L>U|0-&E5Jb+rF~1?)iSfn;_NA+j zRMtJMiN%JPMqH0)}K>gy_+Z@|Gc+es>jrv5S$$i@jnYjsi<0I6$WT#^*^;`%<};*#VT zo_}~J)kyik%f8;9Uz)Rah27E88K5S2QS&IA|9JsDRE#icX>u>WR>3NgSjAp$SJ9V} zDeS(}nZ{kiDv{&m)mAiQtb%`rk+(mLM*95bLU+3b_ij**Z5(A^wV~Z>sV#G1C$XCp z{BLy!TbhEXq!RAEN_GjzNmgH_qdQV<>U*tx(=~sv#-hbE0o5K?vRS>EnuZp%m!EI$ zSbsIT)iUN@k)mb74p2^;$!a2oF|nS^8>#K@AoR5ueJR}PFoyUtB4J3FP)M^Q z1N^5L2g|RuLZ>Uy(|?O|_?K75Nr61VpqB)1EB|hm@UPk=puoC3S}A=0w_=8Wy%Yib z0bff0Fw#I7c0?4J6r85@?|c38uGIL@&|eq1L3pTjUrNVUTM@pt0s^7)R;%|6+`c>q zkm^`ZvdlgSIj0E7w=k&VNIdq}%bq1AB~XsHRI5egm1Ikpd;IbdZ4i!A_1UJ}%sAS+LSszbEz1z7Ex41LbK>T2>Gc&yE9 zvm8^|r{e8OllD15-lbmltO#dmCCCMCdk)!=lpXAk8CAn}Hg$4Wk!v3bJe|RTCm1YX z#c>XKp)3#k2rO!Lx>Ua_{FW;ioHqkQzj2exKF zk<{^20{lcUFa#eOf^bzPpA$r3(0^}d?4pE(2R(7bD2F${02$8RCcnEWPcH6Hwi*>f znAYI9IK%+6R+|klrn(MhqpMn9v6bsPTUT9Vk+3#pRs<343b8=?EW<;Bf1Nez3lVqK z3*go+hm<%K@T3@bK6C$&cLCZgON~^H7ZK&aFu!G1yFEtPt@{>7 zZ9|q=jf4Yj@Q0hNY z790Gp_EWwC^KA;l+3iY8%urE1WmgzZmNJf712l8kO{+(ol;`?EK(IE66b4?kM%K{$ zX=uQcc(lhE(0@m@NgRT%%@O0_(D3;rnc51~$K&DjoDFN2@FVR?Cogh%$b}T=NawUm z=l%NnocpiF2e+q4;$#P2B-D_al}H%0FtCXT1)LW=5NG>hZzQ<rigWvWM?pmR^D0e!fPm|re=(jt1 zLN5eJus}IA^qtgum99IGIG%oZ|# z0PC+k{q+sm!}E0VtPI_T;V({|m;Cs^Z<|g+&EnBZ5&ToewGIolI>C&)-N7^xAhiaw>!dp|6laVkCF* zfXt<~;3%RkCe#eU_FyY*Ra~mR#pM0j`;2dm@hHw`2%7)x9DsnqgSShOSz~mQ@m!%q zD9yTfx@ViNo|OK}VCBDt1fIV5YmVmP*^Mx_NH`(Mao{5Y@j(qYG)TPvM_m6;HBl>u z8ya}09==M=j2jv#B^`2*pdP;ti-Sb8`|#DXmvKXbbR~jA3v($DW-`9uB>Prb&@yw>7hif7M8u)J4jUx|Vt%FI;<;z@$cCjNzDbK$_ zCpg?ljsUm2Mu5$SfK79x~v}FQ%atzj<>j@|eX-pM$r2{G3+RP;BlGQD*woZdw&n>BVwt4->tJx1*}r{iX82w;_f9{8$4VQQw#I2P z{OH+tKZbv~bLZ9Bje?BgTG5$ywXOe+W8e1S%?I24O&A9+lz~md50IdT@!A^60EAk1 zvGBk6cxUI#h}UlL9&#m8x<8(Gdgxja=}HZCV=z5JE{YrCact2wK{vlkfxa)AIbo}3 zixr~ED;&`I`|@#ns(cD&uBQ=~3^==@+fVINjN`9XIj^^F zrdd3_VxICve*hFcYl|bz_)*|Zb9u;&IMrGHFOe9E1XJaZ6E}l`oWVYzQ)T{j=y+ z4KN_Gnf}25KV>MSh736uHdulI=?YdO%PqUNpDQy2CvYma$h=c=^VR8UV;=#EMX<9! zJ*exv|K9|^=iRns{0^bp&cE;IojCA}DV&yppV<(bQ;{rj^i}(t~7A>l~j4B zT+@WJ;>1*qeZj`_^6Z%HyRQIbI~f0sciMH%l{=(H`&@u+i&!KwK@fuuY-;Y+-*bX5^&s4?8ntK z$hgFQjP+P;4R6zpxUE}Rk+nXT+t8Oab`BKm+udfJ@fJ{K7rO#knN|{eE#GqFiH7{@ zOp$5F^mb$jy$tJ^`-VReV+;Z3tzK$HEgo}CE1ySW{TXP-g{4?d?s{?Q1CN%#>`~C; zTP;Ad((JkCGg2#etk?mK{K%l-(d_1vT=VVbO^J-&n?*cQ$0&)u0z(9>`KzrkPQRBD z+!x)zL52Ir=FBfvoW&D%Sca`?l3qd0u@EKO4WSW7ALZH2p1+DqnNhS8dQ#zl8PYDy zLKaKK#ce-;AIXBOYEfIzWt$<6ZEO{?IV44i-}a1_3%PAc&zHDOcMwtCkpL>lov zzg#3|2o9X6-?zdDjc2BJ5fIlfB#RuCo)J9zN%`y1linA#E-B^4pL9qdxmZ)6TU~G?nUTP&~<7?TlofKUe z&xFSgt>a=ehmm1y*;gkFLpQo|ab=|PRoVL=3aRUgKDUX^Hwf^nPhvVFP}$n# zv1YV$f7GH=WVyqvY57u&37FTWY2CDy8%k%97?sv2=bXVk=^Jy;Sg1HgPH;{2bLE1# zpIbp=qEJFHVD%MB2h6kPrU&RaX};QJoXMMCLr@}_*o;a_c~LWsJGP=mX+3>~#B|ir z?DqLu6=2#k{LQAaU(XJEL6bqPuCC5zaz2WyCOdDQFLE(pq};xwxnMMo!I>CLUh*;P zsu=Am37<~u3&SRv$RT?(K_}(|wUjj@p)ume+Y59^>C-W_a)Ng1$GBUYM=ZMJ*lJ8o z_}5S^fqW`5;1t65<$gP5l}&U(@qK@1<3b~?s`+%zk^DnDs<> zC->2Je=4TkEgd?(Z|=GbG|9@kgS;zs_4R@QlpV`%v~q1X&)PXi(@RK7BERiCS@D+T zQTmJ1Kv6b%(fTM)+PAFFN4W)0*OZG{Db{#}JujzQ9Eqad|BV`(3X=SA!uZK}3rBl! zGi!w=YguUk%YK&(+dzNt4&;z54iCmIh7WZi_*o$LcY4fb{%iz4>O$E};(LoA;8RcE za$cKhJfQ(J*WwGAG&En44dlj--&5s&(cHM<60i5{8Fm$Q-cQOBw`P45Q5(*Ey$erlQcxZ&O_|TuWxBGHo zq@sWIOzDIncVj^tAHO7-TM~z)d^D$Mq07Xj-JDPg{$eD1o4cM~)WAkg&2nV&wFg1n zPvQ*6;(oBXJ@ULiKRatu{Cji6WnkHAL=JHut-RS%pwMiVihQ=X80LS~K$t}SSknnA zXAw%b$>nPm-OnA!d*DI+(pH!u8YMI@-$3MWXN2EgfbtOYRbICC)NrAliNo79A#zwD znMz5iF`nY|QytV|M&b*dNofMs`#z%$=4o~Pm$r_~H?z(gtqLajet z`Et$vMa^?Vx1J-YPD!c_+3yot_YvEgHW_EGI;15hC;yma2+@c9(8L1KIp%;!R(6uj zz7y7Fh_6&~8;zbj<>Zkj*i{+6Sc~THR&4b8IXv<}(>XoEte(Y>Ptpj?WBB9D`sd9N zk!woFBXefwb87OlOt7tSHHk@yQxe@N1=1m@#f!gxzv%RRqwvBc*lEqP-!JO;HH4!U z^TG31#35Hj1ux3^gnq4n2Wh+8M1c%2%*@%+t!6NB0s*ObMS_s4P^D8P?+*-(pg zs1UQB_dQe(rGefanc;%wwLP#Qp8bFM!s8|FCQK(BvakJw5hM*0Q};tvadG_wk{{TM zYfsdwcjyNZr3$PwZVCAK_%Eh%4}E|sEhvc_RF~%PRHaN!O+O?V59WuRp>VFS%5je%^z_{&&W2%v>+D z>eo)xdp6mx)Bgi-zsc(D#jxdHaR^&}M~1bNOpia&Yz%WK|NONf6_P4P$dVax>eMp( z+{6isvXn74rhI|phhDY>Zgutg#=>qJ|2`uHUo=BRM1;-$vHif!)tV5tn%{L73U@2F zjMU55T!7{mP-r@+yoIeA?)F#KXuo&wo`g;bW`s`1b@LUcRo`&mZhe5vRAFCQ^Knwm zTMP`1D}BiQ)dkzSuZYP=ynZQJS$p*g%Pi(6g^I*cDmAthc3~Vtak_J7mO~8=Ai8+? zt|0iCzPfRAgZ#>sTP#ls3q_IPSy2{c3c|bMlumYqMp3-B;)ZRJ3^`R>uZf1W-JRaG zRun4efai8p<=$3iY<~G|7p!DzwUfk zTT!y`H1_1^=z#e#GsfdK(^$Ek!BkV&)Z2!*;I#eK&nyKm8lRZ}OOa?T+JD-uqBc8< z-9A`r{U_mtNpO`4HB1d#9RG4G-(|xx%{Zcl;Nv(K2S-xNMl*#Wi#_vG98j%~H7ID4jZg=Mtrbined%BTxwC@x#8Jp}dLZ*}k{{xega z(3mI{EyPk!f-*o`%FPg-a#(eg)*mjIpo%@`64|&rTEW5R4eDQy z;Ux62J20Sg4tL9or&=q|%W}&z!ye%Edybv_ZP^h#cJ_CJ7wjpMF4X0Fjr6hkBtw0^ z)@HSrDJX90#Zs8jpKGjAa$lc$aaS&qlu}#$HBm)(HMptM=6meBM+lgFieXVU%5dHF z@1I;KXb;M3_eYR(nGV_P9N55*;EkQahhw5*qyQCiPD(+6l%heU_toXxwWQf#2O7B> zH*X61j{5}>5)!U{);s)gf`!Mlh6nbqgck>3U1Sv5_;Jta#~)Lpf3_Ld|JC1isN5on zIJmugdRpON{`vON11lde(|d6B^wjmkQh=o_04J<=2M^n+D5e8AkszS|SE!FG8>?}- zIa$Ik2Tu(={L^riDb!c?;PD_*`#-y(5$4bb6G?zQ^3_VA!h--^^|>vuGZgV!?{wrQC-x_u?-nqYOp52@!>S~kAOu0XzmNAn43ZH-=tebf z?7et=m+sK-JFWn~y3pxE%g&PuW=5OK-zGW^9@sc|SLiUj`@hK_;%_hKJx&*EZfOZ+ z(I}BpGyVuBnUdb#-i$q)o7;{0Wcy-`(#pJvk@y5tI|FG{yfk=tUdjxd0%P3+RTeS& z25)=(EyApXnBdv++QIMYCXT9M!Bb|SVOGE@g&47~wyv`7G=%H4?z4HPI3!&j%~ZdC z#OpL`E(rW0gxtzumY4B^!~gyJ5U*n=9zfIio_YSFl++sp==2`!ZV}NiGh@bXrA1dm z-nFW?j}I*)W0OmfkrO0ID_1yBoPsjyGgDg~kV_2)6`J)Y-?+RlaC$XHhZ-?^B|MTZ zEK1a;?Yiu=IbOd(%f;18DU$W1Xwqw&DiqE-re(a=s12N7%p;)OF$V=bmeJIa$fRas zdg!oI{Gh8lAHBZg?IV_~`<{d5R%x){NX%7L8Ih;)oV;0j)oC6yT!Z))bf!0P;|Tie zOWUcv!Os`cIn9vY2#niO$;cY?ky}&P_le*CulBwxs;R9}R}n=-L_}Zms`MsJwjwCKNk_Us=)DCjv`~alLkTURga8r`+BbrZ) zdO(PbjJxnzIj!){?Lm@RYtAV#za1S%Ee?JXT3O5BUDre$Kh1tk?(=A9vm0^L5&;mS z57OblyEt-URiRVRkeDgG-vu`(5%H;BY_DI%Y}7Zv=Y3Y*Qm{1`=j+0_0Wlr>ElAsZ zu|L}hn_!vXs?$yS=CtY0XO}MeYASs^DRqE!gi!*4(Zip*{!9}bRQ`@On}}PQk=2t2 zY1AV*q-jpg!JwR+-%?*4UjWqNa5PS*Usgc%(tf5H8bdx zH;D)Z7=+f9IxRl~t~|T9JQtA;B{&gleR=A_qu{O(p2wnfRTFFSFMHs&bBB^Z17*WWQ$RlKfr4TY{ z7Cp-3YzI4ubK^huX{2v(JT#*S|MiRVUvJw0ozr-W=mjdT6f|)YQmYLDpdKt9c;65pEWm8~ z>uK&A<0c4*ucsVHnva{<>PlEud42y4=oW*3?2{YbTliSPc{fo3*ZEG;YH!8i+1}O3 z2R$;?s>o3pbKocOHmLPUaW3XyB-xa07cK%)Yt{ z>`YWli8fdl$ou2Ej#xkMo~~R^ejHvVW3|tQOBdZb{-4sakjWQ2UThBMPVge3+4tfyTaj&1)T-NTGdB0IhKi`Jy z8b!BHPQ3q7FFjVqzP|EtF>adeum+9fS}*>#8W-NZzd&N^iu#OoSaU~rM`vXzP@X>@ zh2is!A{`uP>Jt#RK*y02cme}`70=1J5)s^q0TKDyz7nNw{?!v>8EA6I$aI= zMcAFm#9(WzNIm!cI#;bmFW0{|N@8eeVk!XXCRVu^jjzXc1?`~%PA$u^LnOfVNz9?E z+!RweoHJ^^FFL$;%BnBpE%27>znhf(PS*uZ9TMM9anAlY=6c%-R^Uf%YRZFY*o#b zOD|ZXm6vsOgin&SXHf;pHwXG$k}E*|B8p&gu;(c>o!yaogc48tv2erpiAh#GW{uFi z8#jM`gj}F3u!T$a7ojBGh@U8PHmI(VxFWA0-AvH-%D0U#K^fcG30tx^eRKEgku?~7 z&p$3Cz;&4NByJ-28v9qGp+V6=jQsO8Ej`>cuyM4Xx#$$PhpM>o^TBW%ob6XWGGBpL z-nc);>fFL9t0tEQ<=<6=^w3sFQ26l+BhI*O7MRgEzZ#M%Cb+Rg1vn07K{jvic%o@7 zH*X%+EzRo?RlQd4*rK$EO9c*(EFR`;_MNbe+qq=C$|L1+7x~&T{UBy!#qqrv zS9HhkkYoAc=jur>?TXJc-)OKgq<3%1wqNzhlwFRkwjF(GQ*2mm6xIj?AzBriIEB^< zA42!An2FTv#|vds&kg%<@?5~{2P+x~Y!8G&lXmtkH ze$=DrGmjH1FzVVLp)ANOx@&LW>6MyVGgmH{z#mCk+q;G3r0s=TeAS@aODL^VA9INt zLH0zh@me%=d=8W#ld0GCy*8CgHY^@qHo+{O$WX~fcR}^};Kkl&mE%E$0ZBW?o=uB+ z9Y`~#l}CQ(Mks$(*;bkMIc0tq3yaNB53laDX$IN+K|;jZUlLf=1rH6S+Fz|nclnxGc_MqKWh6N$!GkSXW%bg6im@#2{T%7`u20_;IO771&t5i^uUA+)%v%+i_*SW- zeo9=uuJB|M7PBIzznrqu_f99%M)_+`XvQo`#9wt3K3w&u#6;;P)pdMlN{P(}yM1>s zx4c3)40XKGP&ZuLV0P>{7lRf*eE9+TA(a~jcQSL^Qm%hve0KY@ysg>$fr4Zo!(GB) zx3rQ+@gmvI`^8I(DK6&?>F9pqMJ8?#R2hfDFNTikF3arPl3On*z78WaG4d}oB#MPb zfBN+4O&Jvg?zL$>W-?WQg+BP9#MV{yxGQ$>m$enNSp!NK6>LsjNsf z*BC9}#jKK??k~K#bV0baOX>*8>bqlw3ekPqKc$uwQ=c*n@x6^!_{c1$ySoWji%YuW zSgYOndD;KLu+)BFfewN-HygK3B`tEJ)U&5rYlmFCN?u}*UYE;z{9_n|ps|!L_j#Ij zvHgQuNE# zFPk>6Ut8F+%)1%aGp*0YI=Yob#Sd|MY4GvieQYm87x5Zd9XxQS1+52XgY&FkmVC=d z*1ex{VYpAXcpTcDXgtSA_oz1VD7~M}4g-mwL|8ZHgkPv>KxgN;k8n~_Qg3b$*98$y zEo6IKw?=ZlOMrHU3fF~acUWqmhnCj6WZ_o`A3q+hJ|oe5-{HP4E9>ochb4V6g@HfW z0WtAAZ$ac2J~1E#Mb9kcS!ud=!~%W4?Yxd9OnNYtS})t$)h6O4H`6bTVDGB2>K^fl zNl(czbvTT;l9)9d3RL(jXFVwF>1*G18}jA2x#_jbi4~U?q-^bSLwhyG)^jGV;967T zIMNA458^j-_z)XcUqx-9bAEP?8f)nY^^)0*FY)(kau6N`>>UhAxUPlx!_Pi{1`k@V+}c9nqj?-G@E zKzJAzC^XmGc6uAJv-8by!OWGZ0)%-roEDPUNgtP-v*=@m*k@t86F<1Sx49sxrUZmP z)b%`Hls;H`JI^!n3&99U_R++(`f9$FTwv7?(bKoIZJ2(?jOi9fmmt?Q@1Xe?s?YZj zP=ey+GDEx0x=KDqttC?Luscebfnp%w$b{mpQQx6TAH^Tm`4Fjkl97#YQdW<`&iCkW z1g!deWJ_QXBg@)h^QprMw8`BGu40(KsbWZ-%Qfta(b(=~=$8(XqUAHBLv{G4Uo4Vq z#%x(ES9F9m>H9>PM+8-N^Zb`wnG$}ncMy{txvzIT_;HRrL|}^C-r%0%@}&f3?k@7D zl6~(rTrS%hAU6=#c%Tv4<>RPQdo1bNyee0UvXFboZDG|FVRO2J5nGF@(90}=I8K=H zVG$HkUk$4^o!xMNSUY8~++ws^S3bL4F8|>Q^ZM1)s=CGSoOcee-ssgrE5hVM%gEvT z@7x)Mz>c~$shLG0tOqlkY;(4% z!sQO~)Vw$8CE%nTA<%mEDPt+}ZDcbXas3xhLf*nWGMWimJ9rf@BB8%eu|IUsSmQZT&X7F^|s8 zAH;RuBh;Ko8JP25?i4Pt+t0D<@~9egBPyrt=pOn)3s_GkWp?wCd%{&P=^j?jy*AIg4=yNCI1)2_ZGHo1m-iZq)M zp7HMYjdrw!dQZx}$=6^Z*vbg!egz*|)&%y=BqNITWzW82Scpfo5__{tar&wrYh1tn zX9(No*vE*7WlJ58RYi(-tU{*!8*C5mDH~2SwB<=)T*kmA93?%^7F#3*;>GvRDAW(c zR9F0(SL`o@=;_fI)=Q@@H2dPOe>p|ctY|2pFu2Fd7i!~?A<{Iy70k+k31L{nxbowC zaA;;b0jj$J@L{*IOLP&?oxLcHrY!SqQf%4$d!kZ0z z7{cL!lB7RbOBzjD$dGu)gpXGx`s+jP$5#%=Px3L)7t%is?m1v)Vp#G#Fj#TwX@ov~ z+7owIAl^PzG5G~|6S9puLgP96A$*&sNrp@FK0BPIsJ!-!?%UJ027+*Z^|4A-}G1V2~-Q` z=Xj7#x>$<#3yA0Gdz(po&ez?JkyK~5K`VK;J8}8SZ?Y7y9n%6J=A-N9ek0wFa8w}j zB&2|vxqr#d{`wUHa$)$Q-XFs-{ry(~S@jyE$sU721Fi!oH-t0exQcN~>Im=z+|n^X zEd3Dx7Ow~2I6{{Hxs3mp%N0~OLOg|ph0oo*7bi#c-w-|k{cmZ!OS~wb{`}liYD(Vt zw(fg+YA4YXIy!2aJ)K+uowQG)k}t1n**(=BBKrqpZ15&+Zd%^Barar&jC-B?{QK;)OlY?OA~6^7R2|Y$pTc3GO9uDo{&(Oih*^As^ufmvrp9m zQVVRJzNbS9Mxwro<$1;cpeXx(G9Ay8JK(G1ZFQaF{|9wcxluy+`2_knTZ_`>g){j$ zP)0kWW0;P8xhIFo|3G4y{`e;eSv2 zzaIkG+5g)}AZL7viHym5Q}*nieAa(W8;?WCUeNY|X5lim^@igV7RcHtCSPD()Qb-c z{D*2h5+^tTQU`3PT-cRn&%$#dV5PLmH(YH>_fNXf|5`F0 z`;v>8kkIQS%^eegEqde>epfiHNBkAiALhG%rp#jaj;HOA*p97hR93Dfw&=~4EW=q! z%9syh4-pFmOo&C-K+G1}y^f(KR%Ppv-HS|D*jyTu=u_3dwO@~)kXO9LKXrg0Rt@rl zQFHMXZvjH3L37Ai?uXj4Y|g<8?rld0oay)S*^pe^?8jksd1F^1QCv}TVJG5N?rQyI z0oxApcMImk+K5EU{GlEdNy|=4N#L>|ou`zHOZMX`+)R*v_$rH2tWH!-kcj zjc$pzvBs(V#M;~@{`SPkD_(llTGICwi`E;gmF?Md!dX$G#-p-Wj}7_s%V2p>IT_1) zeDbdbNB?L1?>Twu^XFrxrl!c8sEk=IUDEP6>GaRNs_ ziTzD_g39}!KY#Y58KD`ve2e!c=F}>B^_=Ha0ELYAC|pjtiDaL;N0QT2UTJ9brUTMw z(CyioCGBZ&&%z=nD?7Ubguu*wg>S46>`d0Lssd0xTdCJxXm#xLI#Lrcw*ueS`TC6y z0mu=c=t)$Om-pX0AZc9jB3)EgQ;VV98s|GjVZ@^cnLrmFP7GDPYPqztIV|c#Dj72y zc#xUxzDfm(3_7DyQw49Sdw{+!zp-*nhToQV!Jk}2rp0j&|3As!c1&kdnD4BnwZG|h z=orL5RDB*=j=xY=Cd74T(_Oy?!=ld!zpa$&Os@RJuRUgUwZvgIKTSZdnoS^ycyL45 z&v$&luQHhpq(F$Y;hfRb5%9D_qcGQ9>_lvMd)#-7=Mc&32aOzmG)U-2L~F_lg2XSv z)t+HvKfcn^QtYIA{vHXfnczLbD`Ydof25pgq?rV%Zs-4aRe2;ZjPX?TB6c;!_q4Z1 zfN7%L?@-DJY+pqk#TQSxYNp+#T(+j;}_) zKcjCmT(lJ<11hRsAMRheB5ED;ky+eG(rtO6!-&Jytv&9Uc8mKHhY6 z4g8`Y_-^aqNGe(c_br)F2*1P2tKzk}bWO^Ar2;opjAlo~2}HL97DqGN*F0IN!`b&% z8T;*5j(g7EHtb>Z-7){kU@Mpf>|MUZ;6h`#hG4_m^+oidivHo47vKZd=j_Jnbc*Vh ztgkrX?1bD`Y=2GKc#?BF!Zy`~*3UvPMMwJU+@@9jXk8JU2MTjYwmLqyDmf_{VRy9yXm zwXXF-jIo;!M@tSypm}d=&_SD1s4ypaa7t?txy#C2;W;m%6yf4gU48@dvbb_g4Cb5D zh&E({KLQi~=-#BjJC*fFpY?CVExb4NSywsAn}+6tY{ni-BPk7i<;$8>Oq`32o9f~d zGn6PWOn86@yEJIALeOV>TImuaBM%h=f5d|zt*(7M*ZQxvG?iS9`S)>slC0j#Prevd z7ma(&s;`5#&5?9<+%O3{pUONdfoJpEYbh_J%2Ya36>O|1wjHl|a+K%Kd>=%Mzhsj3 z0*s<}S$DV3AqZodD=hB;mIXo4O*w(tw(!^?*wKTRlz3wKjI%94y@UvBgg32yrNX;; z-7%`!tH%+O_|0d8qs?*vc2B9h88o^ za?-d49AOv(m<|=dYJo-?x5wY!+CR=DXWb&L$(qvxy%YK4W6qCd+fH zY5NTX2D6dzCc1=-=*cKe)VgVeWbFMwecXH$H|s_w}_8bsXhKw5Khe@l+NTyA&d;5_T= zz(S+_ayubB3L|ZZo%tY0Yd5sN_Kik*Y~lWV&pc|2sYPlr$pK#Vf$0ll+{Ra2&?fQo zx4Cjn_-(erp7o!3hvl%qw{}Xbf4{mm2U88?^*`ztz5w!-t0iNaj1THfBD&CfIk{0{ zu3nv<>P6AIl|9j2h3A7cM`t>iCowvXzTi!)9495VI5($hzJB`VghN(40ThSnqF_>((Oh{q|8x##mXS8%nmUKN@ek-{WM*TTa%V> z0gu`4Ve_4k+5Mo|SvoV^kN}ZqQl#2CaciPltI}F$Oi?SaMMti|o z6}pv}ZWlpL@wR<~KGU{jCT1eO?m==|g=x_8lJFAb<(of->SDQHM=NOem)D3{)pvKXEnwjPuvdP1Fhy= zeZ{6Tr%#UwX*BL~b8wJSC%xIe1)*P@ss+Jv*t~KFwCp+qN>7@b()_03LQ{!+*{Z`DPP6L6Nllfbhb0x;c~59i9da(UIt4?!Gs?wH zyCHk{)cWOcx8ea2I~0QG3dpf#@tY2b^0(X#%FKcxu9KbSb2Os(XtZ zK=^~tAWgmR*?uHaq5i(?-Wq&vXTD9fcyb;QZ|wVm)RyY!OQQ+-%_|b4CeOo2NqH{* z=Tv7^#+pi`Q(LWe_ooUQY5K$YB!q3XB8$5&M@Fe-qhQxF2^1mP#UoxJXgD_ig=kh( z!oXary@P7>rwdgLXM7a1@g%=r1Dg{$;vu{%$k!~$P2k@cHL>gZR9Y4ENrO0@1r*ce zA0)q|M!P(Z&+#OLRVRzuG1=7fSYO1l3@oGJXgBkLm5;SNYd=l!py1ZR7WK=UNF~_5 zf~tAF^XpwaNTE+y`P7K1KpJ%H%)3XA&(0*zcCPBoXa02gL9gdgCgrlgt`yE%8StrG ztKMLVoO_}xnNb5cy@MtDI={aC(6w6xBJ&eqtwr?bzO1a~-U{^i1k{Hdcd0W7Llrf9zgw+6iR7l+;IT67FfFs(Rk>Shx9 zer1V)#L`$|O@Eg~LbCA___M8@`Lt0-bIJOQo=c150$#5uE?g}!t?Q8{s3Fh(%BVe* zF|qU-FzKo{%#8C{`od%WGreWK*Kcwa3ZtT-VPw(6a^k(dOk7CGA`K<5%56_^jGcA{ zvxqGssYhs$vvGbXnCwHeMejj-m+nqF2yg5s7TJK^>i{rWXgrUqZ>nF}EdZf&omDl^ zwJ+2UfQ>S4WQ2RYOZc#qpuZsIC4CUJCut=`o2A4?if`Cy9m{c8G6gPsXFT_Az)vZM?f5HZCU8J?gY2~Fo`Q}OknX(_>hMTo)p{AHC$esetM*=cH^Hg4VQfp zD3>zr)Uove(`GLBzN&fg^svJXm(IiR?t|n!xh>y+R&@4P>tqG)K6cy;!NM&=Tux9N zZIm0oP8|M|0A)}WCXZhj_laM$TxO{-0%BTBnA?=vPfNu-SX9m#EGna}s4(Jzg&W)Q z+=gCsO>Um|v?L%j(I`)1E{7Y@uzNG|VzuQln)L_Xt-7?6=T|nsf?- zRS;oUYhUV^3R317C=cOzgou&ycz%k$-kH12N++ih{=6WI4nFw}WM^VhmMrF{}#x1f7Yy!^qEGm2NsD_xJ+ z6<^zXbEAQj)9JaCZ4UYrcf7ZRyp$ zuW_!ses&c%l~MhR)b*Z2Qf)!cW3yx@s>Z7;VlSts<14e(6#UjTPXihO)$K2E*jUc+ z&x?7+Y1;!QMPz?}*XISzMNXd*Hz;??wX&KoStku0w+si|0u<@l|4H5X7hd1&4sfg{ z(C7IZrVf1Nk>IG}r6+$u`v2Y;uB8Atc6E7F_^;dkH>P%^n~hXB=Hmf&jicgCDG*d~ z46VO>6F}gcw8#7=N3wIEYVAptIj)6PJkmldEBt+X|GzJ{nUeC)Kh4lpmgGvQk3G-r zJZ%0q2697%%ZiGc+7-90vEx-Djgcce@ozff@n`Zkf%k!QwZ>EE^e8A{R}h3U+quV% zEEqVFof6+thj20e#AW;oZ)vo*&o-&%T`$Vj&g~KMJ8+*YcqW+RZ}7LzARy%WPtKe` zFbx_!(P$eaJWkr{KeF~r7bJF!$9i*RTey>=jU|S5g5)1Rj;l2aRV+3n5iM(+9%uLW zi_HyvzQn|Y?L3*<8JqX{_*q4Xl9U%R^mJEnU%0KKjYHnQk3r(jAo|;SqkJuO7^~|i zG1ZzwDGmNcjE%BhDH~pkuFia?fiFPUd~&nUuv)_?K};u3aNnrEzrUgUnc#h(7qLFl zUITF}Z-&TUNE=`)E`iOPGJ~CuQWa-WjOmqJqEE&d8}*kxB_|D2+H1&e&4C>hCl{B# zL6t4nix(ncm(OBm&;OUT;>QpA*D{*K+o}RqQlqCnOCK9@{_;ivT8pd+?&5{Vq1uZ# zjw%cs2S$!Z6x`qd)RE8|3-RNF+z~)jA(^dW$B$kCqcN6Nr2hDsLxBBA_o`^s@uQs} znYk4Gdlr(lod4;itd}d`9ElF{VxCj literal 128033 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 a3pzqo$q#hx)}dE$A6ZEyiQ+fL@Ba%3xuezq diff --git a/docs/guide/create_authority.png b/docs/guide/create_authority.png index 46d284367ff79eac9d6df5ac7b588023d6c73867..f57165e3571c41ee479ebeae3ee0e80932953a57 100644 GIT binary patch literal 136109 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

`BZx95gc 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

q^ey{OOt%P_^-~4cQe5-cX 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 literal 58300 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 abiwd`rbjKr!t5OI_fk^+dEqmI5B~>e%Fc8E diff --git a/docs/guide/create_certificate.png b/docs/guide/create_certificate.png index 61c9afb79956fcb7c31464e92f125471bc0f0402..362994059d45cf015e313055079df312467939ce 100644 GIT binary patch literal 75996 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�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

f9p4GK9*MQ= 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 diff --git a/docs/guide/index.rst b/docs/guide/index.rst index 32a966f2..b06a95e0 100644 --- a/docs/guide/index.rst +++ b/docs/guide/index.rst @@ -37,18 +37,20 @@ Create a New Certificate .. figure:: create_certificate.png - Enter an owner, short description and the authority you wish to issue this certificate. - Enter a common name into the certificate, if no validity range is selected two years is - the default. + Enter an owner, common name, short description and certificate authority you wish to issue this certificate. + Depending upon the selected CA, the UI displays default validity of the certificate. You can select different + validity by entering a custom date, if supported by the CA. + + You can also add `Subject Alternate Names` or SAN for certificates that need to include more than one domains, + The first domain is the Common Name and all other domains are added here as DNSName entries. You can add notification options and upload the created certificate to a destination, both of these are editable features and can be changed after the certificate has been created. .. figure:: certificate_extensions.png - These options are typically for advanced users, the one exception is the `Subject Alternate Names` or SAN. - For certificates that need to include more than one domains, the first domain is the Common Name and all - other domains are added here as DNSName entries. + These options are typically for advanced users. Lemur creates ECC based certificate (ECCPRIME256V1 in particular) + by default. One can change the key type using the dropdown option listed here. Import an Existing Certificate @@ -58,7 +60,7 @@ Import an Existing Certificate Enter an owner, short description and public certificate. If there are intermediates and private keys Lemur will track them just as it does if the certificate were created through Lemur. Lemur generates - a certificate name but you can override that by passing a value to the `Custom Name` field. + a certificate name but you can override that by passing a value to the `Custom Certificate Name` field. You can add notification options and upload the created certificate to a destination, both of these are editable features and can be changed after the certificate has been created. diff --git a/docs/guide/upload_certificate.png b/docs/guide/upload_certificate.png index f3848b08bffff88a00b73ef141cf7eccc3977fc9..da5e83ff83bbced9449318651553ece717c18c01 100644 GIT binary patch literal 84598 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℘D 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 literal 74355 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 z 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 Date: Wed, 2 Dec 2020 18:52:26 -0800 Subject: [PATCH 106/314] Added celery task details to quick start --- docs/quickstart/index.rst | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/docs/quickstart/index.rst b/docs/quickstart/index.rst index 82bfc357..e0aef0d5 100644 --- a/docs/quickstart/index.rst +++ b/docs/quickstart/index.rst @@ -323,6 +323,12 @@ unlock Decrypts sensitive key material - used to decrypt the secrets stored in source during deployment. +Automated celery tasks +~~~~~~~~~~~~~~~~~~~~~~ + +Please refer to :ref:`Periodic Tasks ` to learn more about task scheduling in Lemur. + + What's Next? ------------ From 9a1cb658530140899905275e46563dc764e0c6d0 Mon Sep 17 00:00:00 2001 From: sayali Date: Wed, 2 Dec 2020 19:07:46 -0800 Subject: [PATCH 107/314] Update create_authority_options image --- docs/guide/create_authority_options.png | Bin 134704 -> 49286 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/docs/guide/create_authority_options.png b/docs/guide/create_authority_options.png index dcc815944432163f2407d89b88aade778378d538..f360ad0bd211713c15d2d0b59061d1e62632ba2a 100644 GIT binary patch literal 49286 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 bep}RfV?(#qDgtfxfj<>R&0G05@B9A`U^GyY literal 134704 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

`BZx95gc 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

q^ey{OOt%P_^-~4cQe5-cX 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 From f0f13ce97b2ee9536ca20e3c08bb923276003c6e Mon Sep 17 00:00:00 2001 From: sirferl Date: Thu, 3 Dec 2020 08:30:54 +0100 Subject: [PATCH 108/314] Removed commented log lines Added logging of number of downloaded certificates --- lemur/plugins/lemur_entrust/plugin.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/lemur/plugins/lemur_entrust/plugin.py b/lemur/plugins/lemur_entrust/plugin.py index c2d9caef..8c50fd6e 100644 --- a/lemur/plugins/lemur_entrust/plugin.py +++ b/lemur/plugins/lemur_entrust/plugin.py @@ -355,6 +355,7 @@ class EntrustSourcePlugin(SourcePlugin): get_url = f"{base_url}/certificates" certs = [] + processed_certs = 0 offset = 0 while True: response = self.session.get(get_url, @@ -373,14 +374,12 @@ class EntrustSourcePlugin(SourcePlugin): status_code = response.status_code if status_code > 399: raise Exception(f"ENTRUST error: {status_code}\n{data['errors']}") - # current_app.logger.info(f"recevied: {data['summary']}") for c in data["certificates"]: download_url = "{0}{1}".format( host, c["uri"] ) cert_response = self.session.get(download_url) certificate = json.loads(cert_response.content) - # current_app.logger.info(f"Result: {certificate}") # normalize serial serial = str(int(certificate["serialNumber"], 16)) cert = { @@ -389,11 +388,12 @@ class EntrustSourcePlugin(SourcePlugin): "external_id": str(certificate["trackingId"]), } certs.append(cert) + processed_certs += 1 if data["summary"]["limit"] * offset >= data["summary"]["total"]: break else: offset += 1 - current_app.logger.info(f"Result: {certs}") + current_app.logger.info(f"Retrieved {processed_certs} ertificates") return certs def get_endpoints(self, options, **kwargs): From c635e0f76e7774cfd1ed6a80a67587c10a2defea Mon Sep 17 00:00:00 2001 From: sirferl Date: Thu, 3 Dec 2020 09:24:49 +0100 Subject: [PATCH 109/314] added CSR, Owner, Cert type and extended key usage from Entrust --- lemur/plugins/lemur_entrust/plugin.py | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/lemur/plugins/lemur_entrust/plugin.py b/lemur/plugins/lemur_entrust/plugin.py index 8c50fd6e..5f758fed 100644 --- a/lemur/plugins/lemur_entrust/plugin.py +++ b/lemur/plugins/lemur_entrust/plugin.py @@ -20,13 +20,14 @@ def log_status_code(r, *args, **kwargs): :param kwargs: :return: """ - log_data = { - "reason": (r.reason if r.reason else ""), - "status_code": r.status_code, - "url": (r.url if r.url else ""), - } - metrics.send(f"entrust_status_code_{r.status_code}", "counter", 1) - current_app.logger.info(log_data) + if r.status_code != 200: + log_data = { + "reason": (r.reason if r.reason else ""), + "status_code": r.status_code, + "url": (r.url if r.url else ""), + } + metrics.send(f"entrust_status_code_{r.status_code}", "counter", 1) + current_app.logger.info(log_data) def determine_end_date(end_date): @@ -386,6 +387,9 @@ class EntrustSourcePlugin(SourcePlugin): "body": certificate["endEntityCert"], "serial": serial, "external_id": str(certificate["trackingId"]), + "csr": certificate["csr"], + "owner": certificate["tracking"]["requesterEmail"], + "description": f"Type: Entrust {certificate['certType']}\nExtended Key Usage: {certificate['eku']}" } certs.append(cert) processed_certs += 1 From 2813186b139bc0db04d0efefae38850bb633fdf1 Mon Sep 17 00:00:00 2001 From: sirferl Date: Thu, 3 Dec 2020 10:17:47 +0100 Subject: [PATCH 110/314] lint errors --- lemur/plugins/lemur_entrust/plugin.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lemur/plugins/lemur_entrust/plugin.py b/lemur/plugins/lemur_entrust/plugin.py index 5f758fed..a89de587 100644 --- a/lemur/plugins/lemur_entrust/plugin.py +++ b/lemur/plugins/lemur_entrust/plugin.py @@ -388,7 +388,7 @@ class EntrustSourcePlugin(SourcePlugin): "serial": serial, "external_id": str(certificate["trackingId"]), "csr": certificate["csr"], - "owner": certificate["tracking"]["requesterEmail"], + "owner": certificate["tracking"]["requesterEmail"], "description": f"Type: Entrust {certificate['certType']}\nExtended Key Usage: {certificate['eku']}" } certs.append(cert) From 589df0e230d9fe4a047c10fc1b31594c288704aa Mon Sep 17 00:00:00 2001 From: Jasmine Schladen Date: Thu, 3 Dec 2020 11:30:34 -0800 Subject: [PATCH 111/314] PR feedback --- docs/administration.rst | 101 ++++++++++++++++-- docs/production/index.rst | 2 +- lemur/notifications/cli.py | 8 +- lemur/notifications/messaging.py | 2 +- .../templates/authority_expiration.html | 4 +- lemur/tests/test_messaging.py | 32 +++--- 6 files changed, 113 insertions(+), 36 deletions(-) diff --git a/docs/administration.rst b/docs/administration.rst index 94b15829..ae393ac0 100644 --- a/docs/administration.rst +++ b/docs/administration.rst @@ -262,22 +262,101 @@ and are used when Lemur creates the CSR for your certificates. LEMUR_DEFAULT_AUTHORITY = "verisign" +.. _NotificationOptions: + Notification Options -------------------- -Lemur currently has very basic support for notifications. Currently only expiration notifications are supported. Actual notification -is handled by the notification plugins that you have configured. Lemur ships with the 'Email' notification that allows expiration emails -to be sent to subscribers. +Lemur supports a small variety of notification types through a set of notification plugins. +By default, Lemur configures a standard set of email notifications for all certificates. -Templates for expiration emails are located under `lemur/plugins/lemur_email/templates` and can be modified for your needs. -Notifications are sent to the certificate creator, owner and security team as specified by the `LEMUR_SECURITY_TEAM_EMAIL` configuration parameter. +**Plugin-capable notifications** -Certificates marked as inactive will **not** be notified of upcoming expiration. This enables a user to essentially -silence the expiration. If a certificate is active and is expiring the above will be notified according to the `LEMUR_DEFAULT_EXPIRATION_NOTIFICATION_INTERVALS` or -30, 15, 2 days before expiration if no intervals are set. +These notifications can be configured to use all available notification plugins. -Lemur supports sending certificate expiration notifications through SES and SMTP. +Supported types: +* Certificate expiration + +**Email-only notifications** + +These notifications can only be sent via email and cannot use other notification plugins. + +Supported types: + +* CA certificate expiration +* Pending ACME certificate failure +* Certificate rotation (currently disabled in code) + +**Default notifications** + +When a certificate is created, the following email notifications are created for it if they do not exist. +If these notifications already exist, they will be associated with the new certificate. + +* ``DEFAULT__X_DAY``, where X is the set of values specified in ``LEMUR_DEFAULT_EXPIRATION_NOTIFICATION_INTERVALS`` and defaults to 30, 15, and 2 if not specified. The owner's username will replace ````. +* ``DEFAULT_SECURITY_X_DAY``, where X is the set of values specified in ``LEMUR_SECURITY_TEAM_EMAIL_INTERVALS`` and defaults to ``LEMUR_DEFAULT_EXPIRATION_NOTIFICATION_INTERVALS`` if not specified (which also defaults to 30, 15, and 2 if not specified). + +These notifications can be disabled if desired. They can also be unassociated with a specific certificate. + +**Disabling notifications** + +Notifications can be disabled either for an individual certificate (which disables all notifications for that certificate) +or for an individual notification object (which disables that notification for all associated certificates). +At present, disabling a notification object will only disable certificate expiration notifications, and not other types, +since other notification types don't use notification objects. + +**Certificate expiration** + +Certificate expiration notifications are sent when the scheduled task to send certificate expiration notifications runs +(see :ref:`PeriodicTasks`). Specific patterns of certificate names may be excluded using ``--exclude`` (when using +cron; you may specify this multiple times for multiple patterns) or via the config option ``EXCLUDE_CN_FROM_NOTIFICATION`` +(when using celery; this is a list configuration option, meaning you specify multiple values, such as +``['exclude', 'also exclude']``). The specified exclude pattern will match if found anywhere in the certificate name. + +When the periodic task runs, Lemur checks for certificates meeting the following conditions: + +* Certificate has notifications enabled +* Certificate is not expired +* Certificate is not revoked +* Certificate name does not match the `exclude` parameter +* Certificate has at least one associated notification object +* That notification is active +* That notification's configured interval and unit match the certificate's remaining lifespan + +All eligible certificates are then grouped by owner and applicable notification. For each notification and certificate group, +Lemur will send the expiration notification using whichever plugin was configured for that notification object. +In addition, Lemur will send an email to the certificate owner and security team (as specified by the +``LEMUR_SECURITY_TEAM_EMAIL`` configuration parameter). + +**CA certificate expiration** + +Certificate authority certificate expiration notifications are sent when the scheduled task to send authority certificate +expiration notifications runs (see :ref:`PeriodicTasks`). Notifications are sent via the intervals configured in the +configuration parameter ``LEMUR_AUTHORITY_CERT_EXPIRATION_EMAIL_INTERVALS``, with a default of 365 and 180 days. + +When the periodic task runs, Lemur checks for certificates meeting the following conditions: + +* Certificate has notifications enabled +* Certificate is not expired +* Certificate is not revoked +* Certificate is associated with a CA +* Certificate's remaining lifespan matches one of the configured intervals + +All eligible certificates are then grouped by owner and expiration interval. For each interval and certificate group, +Lemur will send the CA certificate expiration notification via email to the certificate owner and security team +(as specified by the ``LEMUR_SECURITY_TEAM_EMAIL`` configuration parameter). + +**Pending ACME certificate failure** + +Whenever a pending ACME certificate fails to be issued, Lemur will send a notification via email to the certificate owner +and security team (as specified by the ``LEMUR_SECURITY_TEAM_EMAIL`` configuration parameter). This email is not sent if +the pending certificate had notifications disabled. + +**Email notifications** + +Templates for emails are located under `lemur/plugins/lemur_email/templates` and can be modified for your needs. + +The following configuration options are supported: .. data:: LEMUR_EMAIL_SENDER :noindex: @@ -318,7 +397,7 @@ Lemur supports sending certificate expiration notifications through SES and SMTP :: - LEMUR_EMAIL = 'lemur.example.com' + LEMUR_EMAIL = 'lemur@example.com' .. data:: LEMUR_SECURITY_TEAM_EMAIL @@ -333,7 +412,7 @@ Lemur supports sending certificate expiration notifications through SES and SMTP .. data:: LEMUR_DEFAULT_EXPIRATION_NOTIFICATION_INTERVALS :noindex: - Lemur notification intervals + Lemur notification intervals. If unspecified, the value [30, 15, 2] is used. :: diff --git a/docs/production/index.rst b/docs/production/index.rst index 93bad406..106f6b99 100644 --- a/docs/production/index.rst +++ b/docs/production/index.rst @@ -325,7 +325,7 @@ celery tasks or cron jobs that run these commands. There are currently three commands that could/should be run on a periodic basis: -- `notify expirations` and `notify authority_expirations` +- `notify expirations` and `notify authority_expirations` (see :ref:`NotificationOptions` for configuration info) - `check_revoked` - `sync` diff --git a/lemur/notifications/cli.py b/lemur/notifications/cli.py index 7012e9c8..3c29693b 100644 --- a/lemur/notifications/cli.py +++ b/lemur/notifications/cli.py @@ -40,9 +40,7 @@ def expirations(exclude): print("Starting to notify subscribers about expiring certificates!") success, failed = send_expiration_notifications(exclude) print( - "Finished notifying subscribers about expiring certificates! Sent: {success} Failed: {failed}".format( - success=success, failed=failed - ) + f"Finished notifying subscribers about expiring certificates! Sent: {success} Failed: {failed}" ) status = SUCCESS_METRIC_STATUS except Exception as e: @@ -66,9 +64,7 @@ def authority_expirations(): success, failed = send_authority_expiration_notifications() print( "Finished notifying subscribers about expiring certificate authority certificates! " - "Sent: {success} Failed: {failed}".format( - success=success, failed=failed - ) + f"Sent: {success} Failed: {failed}" ) status = SUCCESS_METRIC_STATUS except Exception as e: diff --git a/lemur/notifications/messaging.py b/lemur/notifications/messaging.py index 9b299a24..5aa6b3ee 100644 --- a/lemur/notifications/messaging.py +++ b/lemur/notifications/messaging.py @@ -132,7 +132,7 @@ def get_eligible_authority_certificates(): for owner, owner_certs in groupby(all_certs, lambda x: x.owner): # group by expiration interval for interval, interval_certs in groupby(owner_certs, lambda x: (x.not_after - now).days): - certificates[owner][interval] = list(interval_certs) # list(c for c in interval_certs) + certificates[owner][interval] = list(interval_certs) return certificates diff --git a/lemur/plugins/lemur_email/templates/authority_expiration.html b/lemur/plugins/lemur_email/templates/authority_expiration.html index e4ae8199..984a7483 100644 --- a/lemur/plugins/lemur_email/templates/authority_expiration.html +++ b/lemur/plugins/lemur_email/templates/authority_expiration.html @@ -76,7 +76,9 @@

ln8WK64 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%0AM=_%$7N@BPS88h^6Z87t|E;$}LE9yoFE@>HluW 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 literal 45505 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 diff --git a/docs/guide/create_authority_options.png b/docs/guide/create_authority_options.png index 2f765a192c0d4419e513edb0b66523d168db1774..dcc815944432163f2407d89b88aade778378d538 100644 GIT binary patch literal 134704 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


This is a Lemur CA certificate expiration notice. The following CA certificates are expiring soon; - please take manual action to renew them if necessary. You may also disable notifications via the + please take manual action to renew them if necessary. Note that rotating a root CA requires + advanced planing and the respective trustStores need to be updated. A sub-CA, on the other hand, + does not require any changes to the trustStore. You may also disable notifications via the Notify toggle in Lemur if they are no longer in use. diff --git a/lemur/tests/test_messaging.py b/lemur/tests/test_messaging.py index 9a9a5ad3..0845d468 100644 --- a/lemur/tests/test_messaging.py +++ b/lemur/tests/test_messaging.py @@ -131,13 +131,13 @@ def test_send_pending_failure_notification(notification_plugin, async_issuer_plu def test_get_authority_certificates(): from lemur.notifications.messaging import get_expiring_authority_certificates - certificate_1 = create_cert_that_expires_in_days(180) - certificate_2 = create_cert_that_expires_in_days(365) - create_cert_that_expires_in_days(364) - create_cert_that_expires_in_days(366) - create_cert_that_expires_in_days(179) - create_cert_that_expires_in_days(181) - create_cert_that_expires_in_days(1) + certificate_1 = create_ca_cert_that_expires_in_days(180) + certificate_2 = create_ca_cert_that_expires_in_days(365) + create_ca_cert_that_expires_in_days(364) + create_ca_cert_that_expires_in_days(366) + create_ca_cert_that_expires_in_days(179) + create_ca_cert_that_expires_in_days(181) + create_ca_cert_that_expires_in_days(1) assert set(get_expiring_authority_certificates()) == {certificate_1, certificate_2} @@ -147,19 +147,19 @@ def test_send_authority_expiration_notifications(): from lemur.notifications.messaging import send_authority_expiration_notifications verify_sender_email() - create_cert_that_expires_in_days(180) - create_cert_that_expires_in_days(180) # two on the same day results in a single email - create_cert_that_expires_in_days(365) - create_cert_that_expires_in_days(364) - create_cert_that_expires_in_days(366) - create_cert_that_expires_in_days(179) - create_cert_that_expires_in_days(181) - create_cert_that_expires_in_days(1) + create_ca_cert_that_expires_in_days(180) + create_ca_cert_that_expires_in_days(180) # two on the same day results in a single email + create_ca_cert_that_expires_in_days(365) + create_ca_cert_that_expires_in_days(364) + create_ca_cert_that_expires_in_days(366) + create_ca_cert_that_expires_in_days(179) + create_ca_cert_that_expires_in_days(181) + create_ca_cert_that_expires_in_days(1) assert send_authority_expiration_notifications() == (2, 0) -def create_cert_that_expires_in_days(days): +def create_ca_cert_that_expires_in_days(days): now = arrow.utcnow() not_after = now + timedelta(days=days, hours=1) # a bit more than specified since we'll check in the future From 4afd425d9f6081b7d8e68260a34bab32ad4e24e8 Mon Sep 17 00:00:00 2001 From: Hossein Shafagh Date: Thu, 3 Dec 2020 12:07:59 -0800 Subject: [PATCH 112/314] improved text --- lemur/plugins/lemur_entrust/plugin.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lemur/plugins/lemur_entrust/plugin.py b/lemur/plugins/lemur_entrust/plugin.py index 83547a20..e8410603 100644 --- a/lemur/plugins/lemur_entrust/plugin.py +++ b/lemur/plugins/lemur_entrust/plugin.py @@ -394,7 +394,7 @@ class EntrustSourcePlugin(SourcePlugin): "external_id": str(certificate["trackingId"]), "csr": certificate["csr"], "owner": certificate["tracking"]["requesterEmail"], - "description": f"Type: Entrust {certificate['certType']}\nExtended Key Usage: {certificate['eku']}" + "description": f"Imported by Lemur; Type: Entrust {certificate['certType']}\nExtended Key Usage: {certificate['eku']}" } certs.append(cert) processed_certs += 1 From 42957cffc7e08f2830a844e3006946f7e9b413f6 Mon Sep 17 00:00:00 2001 From: Jasmine Schladen Date: Thu, 3 Dec 2020 16:10:36 -0800 Subject: [PATCH 113/314] PR feedback: add config option to enable rotation emails, add cert count and type to email --- docs/administration.rst | 8 +++++++- lemur/certificates/service.py | 10 ++++++++++ lemur/common/celery.py | 5 +++-- lemur/notifications/messaging.py | 5 ++++- .../lemur_email/templates/authority_expiration.html | 7 ++++++- 5 files changed, 30 insertions(+), 5 deletions(-) diff --git a/docs/administration.rst b/docs/administration.rst index ae393ac0..1415e598 100644 --- a/docs/administration.rst +++ b/docs/administration.rst @@ -286,7 +286,7 @@ Supported types: * CA certificate expiration * Pending ACME certificate failure -* Certificate rotation (currently disabled in code) +* Certificate rotation **Default notifications** @@ -352,6 +352,12 @@ Whenever a pending ACME certificate fails to be issued, Lemur will send a notifi and security team (as specified by the ``LEMUR_SECURITY_TEAM_EMAIL`` configuration parameter). This email is not sent if the pending certificate had notifications disabled. +**Certificate rotation** + +Whenever a cert is rotated, Lemur will send a notification via email to the certificate owner. This notification is +disabled by default; to enable it, you must set the option ``--notify`` (when using cron) or the configuration parameter +``ENABLE_ROTATION_NOTIFICATION`` (when using celery). + **Email notifications** Templates for emails are located under `lemur/plugins/lemur_email/templates` and can be modified for your needs. diff --git a/lemur/certificates/service.py b/lemur/certificates/service.py index 3d3e2ca0..f205da3f 100644 --- a/lemur/certificates/service.py +++ b/lemur/certificates/service.py @@ -864,3 +864,13 @@ def cleanup_after_revoke(certificate): database.update(certificate) return error_message + + +def get_issued_cert_count_for_authority(authority): + """ + Returns the count of certs issued by the specified authority. + + :return: + """ + query = database.session_query(Certificate.id).filter(Authority.id == authority.id) + return database.get_count(query) diff --git a/lemur/common/celery.py b/lemur/common/celery.py index f428927e..9dc4bd0a 100644 --- a/lemur/common/celery.py +++ b/lemur/common/celery.py @@ -656,11 +656,12 @@ def certificate_rotate(**kwargs): current_app.logger.debug(log_data) try: + notify = current_app.config.get("ENABLE_ROTATION_NOTIFICATION", None) if region: log_data["region"] = region - cli_certificate.rotate_region(None, None, None, None, True, region) + cli_certificate.rotate_region(None, None, None, notify, True, region) else: - cli_certificate.rotate(None, None, None, None, True) + cli_certificate.rotate(None, None, None, notify, True) except SoftTimeLimitExceeded: log_data["message"] = "Certificate rotate: Time limit exceeded." current_app.logger.error(log_data) diff --git a/lemur/notifications/messaging.py b/lemur/notifications/messaging.py index 5aa6b3ee..75d829b1 100644 --- a/lemur/notifications/messaging.py +++ b/lemur/notifications/messaging.py @@ -19,9 +19,10 @@ from sqlalchemy import and_ from sqlalchemy.sql.expression import false, true from lemur import database +from lemur.certificates import service as certificates_service from lemur.certificates.models import Certificate from lemur.certificates.schemas import certificate_notification_output_schema -from lemur.common.utils import windowed_query +from lemur.common.utils import windowed_query, is_selfsigned from lemur.constants import FAILURE_METRIC_STATUS, SUCCESS_METRIC_STATUS from lemur.extensions import metrics, sentry from lemur.pending_certificates.schemas import pending_certificate_output_schema @@ -241,6 +242,8 @@ def send_authority_expiration_notifications(): 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] diff --git a/lemur/plugins/lemur_email/templates/authority_expiration.html b/lemur/plugins/lemur_email/templates/authority_expiration.html index 984a7483..7c343417 100644 --- a/lemur/plugins/lemur_email/templates/authority_expiration.html +++ b/lemur/plugins/lemur_email/templates/authority_expiration.html @@ -91,7 +91,12 @@ {{ certificate.name }}
- {{ certificate.endpoints | length }} Endpoints + {% if certificate.self_signed %} + Root + {% else %} + Subordinate + {% endif %} CA +
{{ certificate.issued_cert_count }} issued certificates
{{ certificate.owner }}
{{ certificate.validityEnd | time }} Details From 576c69c8e571df37f0f4459e540fb7eb945720fb Mon Sep 17 00:00:00 2001 From: Jasmine Schladen Date: Thu, 3 Dec 2020 17:56:39 -0800 Subject: [PATCH 114/314] Fix DB query for cert count for authority --- lemur/certificates/service.py | 3 +-- lemur/tests/test_certificates.py | 12 ++++++++++++ 2 files changed, 13 insertions(+), 2 deletions(-) diff --git a/lemur/certificates/service.py b/lemur/certificates/service.py index f205da3f..b22090b6 100644 --- a/lemur/certificates/service.py +++ b/lemur/certificates/service.py @@ -872,5 +872,4 @@ def get_issued_cert_count_for_authority(authority): :return: """ - query = database.session_query(Certificate.id).filter(Authority.id == authority.id) - return database.get_count(query) + return database.db.session.query(Certificate).filter(Certificate.authority_id == authority.id).count() diff --git a/lemur/tests/test_certificates.py b/lemur/tests/test_certificates.py index a0a03e65..7c96c491 100644 --- a/lemur/tests/test_certificates.py +++ b/lemur/tests/test_certificates.py @@ -1377,3 +1377,15 @@ def test_boolean_filter(client): headers=VALID_ADMIN_HEADER_TOKEN, ) assert resp.status_code == 200 + + +def test_issued_cert_count_for_authority(authority): + from lemur.tests.factories import CertificateFactory + from lemur.certificates.service import get_issued_cert_count_for_authority + + # create a few certs issued by the authority + CertificateFactory(authority=authority, name="test_issued_cert_count_for_authority1") + CertificateFactory(authority=authority, name="test_issued_cert_count_for_authority2") + CertificateFactory(authority=authority, name="test_issued_cert_count_for_authority3") + + assert get_issued_cert_count_for_authority(authority) == 3 From 29aeb9b298c8eac6696acfe7a8f82b7274cc0d8a Mon Sep 17 00:00:00 2001 From: Jasmine Schladen Date: Thu, 3 Dec 2020 17:59:13 -0800 Subject: [PATCH 115/314] Subordinate -> Intermediate wording --- lemur/plugins/lemur_email/templates/authority_expiration.html | 2 +- lemur/tests/test_certificates.py | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/lemur/plugins/lemur_email/templates/authority_expiration.html b/lemur/plugins/lemur_email/templates/authority_expiration.html index 7c343417..30cfb3fd 100644 --- a/lemur/plugins/lemur_email/templates/authority_expiration.html +++ b/lemur/plugins/lemur_email/templates/authority_expiration.html @@ -94,7 +94,7 @@ {% if certificate.self_signed %} Root {% else %} - Subordinate + Intermediate {% endif %} CA
{{ certificate.issued_cert_count }} issued certificates
{{ certificate.owner }} diff --git a/lemur/tests/test_certificates.py b/lemur/tests/test_certificates.py index 7c96c491..c33743d0 100644 --- a/lemur/tests/test_certificates.py +++ b/lemur/tests/test_certificates.py @@ -1383,6 +1383,8 @@ def test_issued_cert_count_for_authority(authority): from lemur.tests.factories import CertificateFactory from lemur.certificates.service import get_issued_cert_count_for_authority + assert get_issued_cert_count_for_authority(authority) == 0 + # create a few certs issued by the authority CertificateFactory(authority=authority, name="test_issued_cert_count_for_authority1") CertificateFactory(authority=authority, name="test_issued_cert_count_for_authority2") From 2b65ab8972613b93e2314cddd265b2db4f96142f Mon Sep 17 00:00:00 2001 From: sirferl Date: Fri, 4 Dec 2020 13:54:39 +0100 Subject: [PATCH 116/314] Corrected delivery of TLS format --- lemur/plugins/lemur_kubernetes/plugin.py | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/lemur/plugins/lemur_kubernetes/plugin.py b/lemur/plugins/lemur_kubernetes/plugin.py index 79207636..b8ea3d1b 100644 --- a/lemur/plugins/lemur_kubernetes/plugin.py +++ b/lemur/plugins/lemur_kubernetes/plugin.py @@ -10,6 +10,7 @@ .. moduleauthor:: Mikhail Khodorovskiy """ +import base64 import itertools import os @@ -17,7 +18,7 @@ import requests from flask import current_app from lemur.common.defaults import common_name -from lemur.common.utils import parse_certificate, base64encode +from lemur.common.utils import parse_certificate from lemur.plugins.bases import DestinationPlugin DEFAULT_API_VERSION = "v1" @@ -72,6 +73,12 @@ def _resolve_uri(k8s_base_uri, namespace, kind, name=None, api_ver=DEFAULT_API_V ) +# Performs Base64 encoding of string to string using the base64.b64encode() function +# which encodes bytes to bytes. +def base64encode(string): + return base64.b64encode(string.encode()).decode() + + def build_secret(secret_format, secret_name, body, private_key, cert_chain): secret = { "apiVersion": "v1", @@ -89,7 +96,7 @@ def build_secret(secret_format, secret_name, body, private_key, cert_chain): if secret_format == "TLS": secret["type"] = "kubernetes.io/tls" secret["data"] = { - "tls.crt": base64encode(body), + "tls.crt": base64encode("%s\n%s" % (body, cert_chain)), "tls.key": base64encode(private_key), } if secret_format == "Certificate": From a02b3789881629f34084a68cb92b95c4b14a7927 Mon Sep 17 00:00:00 2001 From: sirferl Date: Fri, 4 Dec 2020 14:12:21 +0100 Subject: [PATCH 117/314] Removed local base64encode and use common.utils version --- lemur/plugins/lemur_kubernetes/plugin.py | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) diff --git a/lemur/plugins/lemur_kubernetes/plugin.py b/lemur/plugins/lemur_kubernetes/plugin.py index b8ea3d1b..66d5fbe8 100644 --- a/lemur/plugins/lemur_kubernetes/plugin.py +++ b/lemur/plugins/lemur_kubernetes/plugin.py @@ -10,7 +10,6 @@ .. moduleauthor:: Mikhail Khodorovskiy """ -import base64 import itertools import os @@ -18,7 +17,7 @@ import requests from flask import current_app from lemur.common.defaults import common_name -from lemur.common.utils import parse_certificate +from lemur.common.utils import parse_certificate, base64encode from lemur.plugins.bases import DestinationPlugin DEFAULT_API_VERSION = "v1" @@ -73,12 +72,6 @@ def _resolve_uri(k8s_base_uri, namespace, kind, name=None, api_ver=DEFAULT_API_V ) -# Performs Base64 encoding of string to string using the base64.b64encode() function -# which encodes bytes to bytes. -def base64encode(string): - return base64.b64encode(string.encode()).decode() - - def build_secret(secret_format, secret_name, body, private_key, cert_chain): secret = { "apiVersion": "v1", From be46623a7ff41d50e2300d6b2897c870810267e5 Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Mon, 7 Dec 2020 13:32:42 +0000 Subject: [PATCH 118/314] Bump faker from 4.17.1 to 5.0.0 Bumps [faker](https://github.com/joke2k/faker) from 4.17.1 to 5.0.0. - [Release notes](https://github.com/joke2k/faker/releases) - [Changelog](https://github.com/joke2k/faker/blob/master/CHANGELOG.md) - [Commits](https://github.com/joke2k/faker/compare/v4.17.1...v5.0.0) Signed-off-by: dependabot-preview[bot] --- requirements-tests.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements-tests.txt b/requirements-tests.txt index 90bb7b5e..9f6b3a11 100644 --- a/requirements-tests.txt +++ b/requirements-tests.txt @@ -24,7 +24,7 @@ decorator==4.4.2 # via networkx docker==4.2.0 # via moto ecdsa==0.14.1 # via moto, python-jose, sshpubkeys factory-boy==3.1.0 # via -r requirements-tests.in -faker==4.17.1 # via -r requirements-tests.in, factory-boy +faker==5.0.0 # via -r requirements-tests.in, factory-boy fakeredis==1.4.5 # via -r requirements-tests.in flask==1.1.2 # via pytest-flask freezegun==1.0.0 # via -r requirements-tests.in From 61ed4ea84d3936824e2fbf2887bb9ca807dfd2c6 Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Mon, 7 Dec 2020 18:34:11 +0000 Subject: [PATCH 119/314] Bump bandit from 1.6.2 to 1.6.3 Bumps [bandit](https://github.com/PyCQA/bandit) from 1.6.2 to 1.6.3. - [Release notes](https://github.com/PyCQA/bandit/releases) - [Commits](https://github.com/PyCQA/bandit/compare/1.6.2...1.6.3) Signed-off-by: dependabot-preview[bot] --- requirements-tests.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements-tests.txt b/requirements-tests.txt index 9f6b3a11..02e922ec 100644 --- a/requirements-tests.txt +++ b/requirements-tests.txt @@ -8,7 +8,7 @@ appdirs==1.4.3 # via black attrs==19.3.0 # via jsonschema, pytest aws-sam-translator==1.22.0 # via cfn-lint aws-xray-sdk==2.5.0 # via moto -bandit==1.6.2 # via -r requirements-tests.in +bandit==1.6.3 # via -r requirements-tests.in black==20.8b1 # via -r requirements-tests.in boto3==1.16.25 # via aws-sam-translator, moto boto==2.49.0 # via moto From 9eca783c7ed27458e69be5a6d7e2f7ddf0ef1f46 Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Mon, 7 Dec 2020 18:43:27 +0000 Subject: [PATCH 120/314] Bump acme from 1.9.0 to 1.10.1 Bumps [acme](https://github.com/letsencrypt/letsencrypt) from 1.9.0 to 1.10.1. - [Release notes](https://github.com/letsencrypt/letsencrypt/releases) - [Commits](https://github.com/letsencrypt/letsencrypt/compare/v1.9.0...v1.10.1) Signed-off-by: dependabot-preview[bot] --- requirements-docs.txt | 95 ++++--------------------------------------- requirements.txt | 2 +- 2 files changed, 10 insertions(+), 87 deletions(-) diff --git a/requirements-docs.txt b/requirements-docs.txt index 4cdfab85..21f8d196 100644 --- a/requirements-docs.txt +++ b/requirements-docs.txt @@ -4,92 +4,22 @@ # # pip-compile --no-index --output-file=requirements-docs.txt requirements-docs.in # -acme==1.9.0 # via -r requirements.txt alabaster==0.7.12 # via sphinx -alembic-autogenerate-enums==0.0.2 # via -r requirements.txt -alembic==1.4.2 # via -r requirements.txt, flask-migrate -amqp==2.5.2 # via -r requirements.txt, kombu -aniso8601==8.0.0 # via -r requirements.txt, flask-restful -arrow==0.17.0 # via -r requirements.txt -asyncpool==1.0 # via -r requirements.txt babel==2.8.0 # via sphinx -bcrypt==3.1.7 # via -r requirements.txt, flask-bcrypt, paramiko -beautifulsoup4==4.9.1 # via -r requirements.txt, cloudflare -billiard==3.6.3.0 # via -r requirements.txt, celery -blinker==1.4 # via -r requirements.txt, flask-mail, flask-principal, raven -boto3==1.16.25 # via -r requirements.txt -botocore==1.19.25 # via -r requirements.txt, boto3, s3transfer -celery[redis]==4.4.2 # via -r requirements.txt -certifi==2020.11.8 # via -r requirements.txt, requests -certsrv==2.1.1 # via -r requirements.txt -cffi==1.14.0 # via -r requirements.txt, bcrypt, cryptography, pynacl -chardet==3.0.4 # via -r requirements.txt, requests -click==7.1.2 # via -r requirements.txt, flask -cloudflare==2.8.13 # via -r requirements.txt -cryptography==3.2.1 # via -r requirements.txt, acme, josepy, paramiko, pyopenssl, requests -dnspython3==1.15.0 # via -r requirements.txt -dnspython==1.15.0 # via -r requirements.txt, dnspython3 +certifi==2020.11.8 # via requests +chardet==3.0.4 # via requests docutils==0.15.2 # via sphinx -dyn==1.8.1 # via -r requirements.txt -flask-bcrypt==0.7.1 # via -r requirements.txt -flask-cors==3.0.9 # via -r requirements.txt -flask-mail==0.9.1 # via -r requirements.txt -flask-migrate==2.5.3 # via -r requirements.txt -flask-principal==0.4.0 # via -r requirements.txt -flask-replicated==1.4 # via -r requirements.txt -flask-restful==0.3.8 # via -r requirements.txt -flask-script==2.0.6 # via -r requirements.txt -flask-sqlalchemy==2.4.4 # via -r requirements.txt, flask-migrate -flask==1.1.2 # via -r requirements.txt, flask-bcrypt, flask-cors, flask-mail, flask-migrate, flask-principal, flask-restful, flask-script, flask-sqlalchemy, raven -future==0.18.2 # via -r requirements.txt -gunicorn==20.0.4 # via -r requirements.txt -hvac==0.10.5 # via -r requirements.txt -idna==2.9 # via -r requirements.txt, requests +idna==2.9 # via requests imagesize==1.2.0 # via sphinx -inflection==0.5.1 # via -r requirements.txt -itsdangerous==1.1.0 # via -r requirements.txt, flask -javaobj-py3==0.4.0.1 # via -r requirements.txt, pyjks -jinja2==2.11.2 # via -r requirements.txt, flask, sphinx -jmespath==0.9.5 # via -r requirements.txt, boto3, botocore -josepy==1.3.0 # via -r requirements.txt, acme -jsonlines==1.2.0 # via -r requirements.txt, cloudflare -kombu==4.6.8 # via -r requirements.txt, celery -lockfile==0.12.2 # via -r requirements.txt -logmatic-python==0.1.7 # via -r requirements.txt -mako==1.1.2 # via -r requirements.txt, alembic -markupsafe==1.1.1 # via -r requirements.txt, jinja2, mako -marshmallow-sqlalchemy==0.23.1 # via -r requirements.txt -marshmallow==2.20.4 # via -r requirements.txt, marshmallow-sqlalchemy -ndg-httpsclient==0.5.1 # via -r requirements.txt +jinja2==2.11.2 # via sphinx +markupsafe==1.1.1 # via jinja2 packaging==20.3 # via sphinx -paramiko==2.7.2 # via -r requirements.txt -pem==20.1.0 # via -r requirements.txt -psycopg2==2.8.6 # via -r requirements.txt -pyasn1-modules==0.2.8 # via -r requirements.txt, pyjks, python-ldap -pyasn1==0.4.8 # via -r requirements.txt, ndg-httpsclient, pyasn1-modules, pyjks, python-ldap -pycparser==2.20 # via -r requirements.txt, cffi -pycryptodomex==3.9.7 # via -r requirements.txt, pyjks pygments==2.6.1 # via sphinx -pyjks==20.0.0 # via -r requirements.txt -pyjwt==1.7.1 # via -r requirements.txt -pynacl==1.3.0 # via -r requirements.txt, paramiko -pyopenssl==20.0.0 # via -r requirements.txt, acme, josepy, ndg-httpsclient, requests pyparsing==2.4.7 # via packaging -pyrfc3339==1.1 # via -r requirements.txt, acme -python-dateutil==2.8.1 # via -r requirements.txt, alembic, arrow, botocore -python-editor==1.0.4 # via -r requirements.txt, alembic -python-json-logger==0.1.11 # via -r requirements.txt, logmatic-python -pytz==2019.3 # via -r requirements.txt, acme, babel, celery, flask-restful, pyrfc3339 -pyyaml==5.3.1 # via -r requirements.txt, cloudflare -raven[flask]==6.10.0 # via -r requirements.txt -redis==3.5.3 # via -r requirements.txt, celery -requests-toolbelt==0.9.1 # via -r requirements.txt, acme -requests[security]==2.25.0 # via -r requirements.txt, acme, certsrv, cloudflare, hvac, requests-toolbelt, sphinx -retrying==1.3.3 # via -r requirements.txt -s3transfer==0.3.3 # via -r requirements.txt, boto3 -six==1.15.0 # via -r requirements.txt, acme, bcrypt, cryptography, flask-cors, flask-restful, hvac, josepy, jsonlines, packaging, pynacl, pyopenssl, python-dateutil, retrying, sphinxcontrib-httpdomain, sqlalchemy-utils +pytz==2019.3 # via babel +requests==2.25.0 # via sphinx +six==1.15.0 # via packaging, sphinxcontrib-httpdomain snowballstemmer==2.0.0 # via sphinx -soupsieve==2.0.1 # via -r requirements.txt, beautifulsoup4 sphinx-rtd-theme==0.5.0 # via -r requirements-docs.in sphinx==3.3.1 # via -r requirements-docs.in, sphinx-rtd-theme, sphinxcontrib-httpdomain sphinxcontrib-applehelp==1.0.2 # via sphinx @@ -99,14 +29,7 @@ sphinxcontrib-httpdomain==1.7.0 # via -r requirements-docs.in sphinxcontrib-jsmath==1.0.1 # via sphinx sphinxcontrib-qthelp==1.0.3 # via sphinx sphinxcontrib-serializinghtml==1.1.4 # via sphinx -sqlalchemy-utils==0.36.8 # via -r requirements.txt -sqlalchemy==1.3.16 # via -r requirements.txt, alembic, flask-sqlalchemy, marshmallow-sqlalchemy, sqlalchemy-utils -tabulate==0.8.7 # via -r requirements.txt -twofish==0.3.0 # via -r requirements.txt, pyjks -urllib3==1.25.8 # via -r requirements.txt, botocore, requests -vine==1.3.0 # via -r requirements.txt, amqp, celery -werkzeug==1.0.1 # via -r requirements.txt, flask -xmltodict==0.12.0 # via -r requirements.txt +urllib3==1.25.8 # via requests # The following packages are considered to be unsafe in a requirements file: # setuptools diff --git a/requirements.txt b/requirements.txt index 20698495..8d70b3d5 100644 --- a/requirements.txt +++ b/requirements.txt @@ -4,7 +4,7 @@ # # pip-compile --no-index --output-file=requirements.txt requirements.in # -acme==1.9.0 # via -r requirements.in +acme==1.10.1 # via -r requirements.in alembic-autogenerate-enums==0.0.2 # via -r requirements.in alembic==1.4.2 # via flask-migrate amqp==2.5.2 # via kombu From a3b7453886b8d343dd8c486e5d91f2bfd0a785f7 Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Mon, 7 Dec 2020 18:54:59 +0000 Subject: [PATCH 121/314] Bump boto3 from 1.16.25 to 1.16.30 Bumps [boto3](https://github.com/boto/boto3) from 1.16.25 to 1.16.30. - [Release notes](https://github.com/boto/boto3/releases) - [Changelog](https://github.com/boto/boto3/blob/develop/CHANGELOG.rst) - [Commits](https://github.com/boto/boto3/compare/1.16.25...1.16.30) Signed-off-by: dependabot-preview[bot] --- requirements-tests.txt | 4 ++-- requirements.txt | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/requirements-tests.txt b/requirements-tests.txt index 02e922ec..888524aa 100644 --- a/requirements-tests.txt +++ b/requirements-tests.txt @@ -10,9 +10,9 @@ aws-sam-translator==1.22.0 # via cfn-lint aws-xray-sdk==2.5.0 # via moto bandit==1.6.3 # via -r requirements-tests.in black==20.8b1 # via -r requirements-tests.in -boto3==1.16.25 # via aws-sam-translator, moto +boto3==1.16.30 # via aws-sam-translator, moto boto==2.49.0 # via moto -botocore==1.19.25 # via aws-xray-sdk, boto3, moto, s3transfer +botocore==1.19.30 # via aws-xray-sdk, boto3, moto, s3transfer certifi==2020.11.8 # via requests cffi==1.14.0 # via cryptography cfn-lint==0.29.5 # via moto diff --git a/requirements.txt b/requirements.txt index 8d70b3d5..4bd34fe0 100644 --- a/requirements.txt +++ b/requirements.txt @@ -15,8 +15,8 @@ bcrypt==3.1.7 # via flask-bcrypt, paramiko beautifulsoup4==4.9.1 # via cloudflare billiard==3.6.3.0 # via celery blinker==1.4 # via flask-mail, flask-principal, raven -boto3==1.16.25 # via -r requirements.in -botocore==1.19.25 # via -r requirements.in, boto3, s3transfer +boto3==1.16.30 # via -r requirements.in +botocore==1.19.30 # via -r requirements.in, boto3, s3transfer celery[redis]==4.4.2 # via -r requirements.in certifi==2020.11.8 # via -r requirements.in, requests certsrv==2.1.1 # via -r requirements.in From cdb5535ae02228ef56fdd0468f73acb889d6018b Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Mon, 7 Dec 2020 19:06:23 +0000 Subject: [PATCH 122/314] Bump certifi from 2020.11.8 to 2020.12.5 Bumps [certifi](https://github.com/certifi/python-certifi) from 2020.11.8 to 2020.12.5. - [Release notes](https://github.com/certifi/python-certifi/releases) - [Commits](https://github.com/certifi/python-certifi/compare/2020.11.08...2020.12.05) Signed-off-by: dependabot-preview[bot] --- requirements-dev.txt | 2 +- requirements-docs.txt | 2 +- requirements-tests.txt | 2 +- requirements.txt | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/requirements-dev.txt b/requirements-dev.txt index 5ffcb1e4..defb70b1 100644 --- a/requirements-dev.txt +++ b/requirements-dev.txt @@ -6,7 +6,7 @@ # appdirs==1.4.3 # via virtualenv bleach==3.1.4 # via readme-renderer -certifi==2020.11.8 # via requests +certifi==2020.12.5 # via requests cffi==1.14.0 # via cryptography cfgv==3.1.0 # via pre-commit chardet==3.0.4 # via requests diff --git a/requirements-docs.txt b/requirements-docs.txt index 21f8d196..624b6981 100644 --- a/requirements-docs.txt +++ b/requirements-docs.txt @@ -6,7 +6,7 @@ # alabaster==0.7.12 # via sphinx babel==2.8.0 # via sphinx -certifi==2020.11.8 # via requests +certifi==2020.12.5 # via requests chardet==3.0.4 # via requests docutils==0.15.2 # via sphinx idna==2.9 # via requests diff --git a/requirements-tests.txt b/requirements-tests.txt index 888524aa..336e31a4 100644 --- a/requirements-tests.txt +++ b/requirements-tests.txt @@ -13,7 +13,7 @@ black==20.8b1 # via -r requirements-tests.in boto3==1.16.30 # via aws-sam-translator, moto boto==2.49.0 # via moto botocore==1.19.30 # via aws-xray-sdk, boto3, moto, s3transfer -certifi==2020.11.8 # via requests +certifi==2020.12.5 # via requests cffi==1.14.0 # via cryptography cfn-lint==0.29.5 # via moto chardet==3.0.4 # via requests diff --git a/requirements.txt b/requirements.txt index 4bd34fe0..1a2c572d 100644 --- a/requirements.txt +++ b/requirements.txt @@ -18,7 +18,7 @@ blinker==1.4 # via flask-mail, flask-principal, raven boto3==1.16.30 # via -r requirements.in botocore==1.19.30 # via -r requirements.in, boto3, s3transfer celery[redis]==4.4.2 # via -r requirements.in -certifi==2020.11.8 # via -r requirements.in, requests +certifi==2020.12.5 # via -r requirements.in, requests certsrv==2.1.1 # via -r requirements.in cffi==1.14.0 # via bcrypt, cryptography, pynacl chardet==3.0.4 # via requests From f171e84a5eaf2b4c5c96af6cead89fa56c61a01c Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Mon, 7 Dec 2020 19:15:58 +0000 Subject: [PATCH 123/314] Bump cloudflare from 2.8.13 to 2.8.14 Bumps [cloudflare](https://github.com/cloudflare/python-cloudflare) from 2.8.13 to 2.8.14. - [Release notes](https://github.com/cloudflare/python-cloudflare/releases) - [Changelog](https://github.com/cloudflare/python-cloudflare/blob/master/CHANGELOG.md) - [Commits](https://github.com/cloudflare/python-cloudflare/compare/2.8.13...2.8.14) Signed-off-by: dependabot-preview[bot] --- requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index 1a2c572d..1fbea8ae 100644 --- a/requirements.txt +++ b/requirements.txt @@ -23,7 +23,7 @@ certsrv==2.1.1 # via -r requirements.in cffi==1.14.0 # via bcrypt, cryptography, pynacl chardet==3.0.4 # via requests click==7.1.2 # via flask -cloudflare==2.8.13 # via -r requirements.in +cloudflare==2.8.14 # via -r requirements.in cryptography==3.2.1 # via -r requirements.in, acme, josepy, paramiko, pyopenssl, requests dnspython3==1.15.0 # via -r requirements.in dnspython==1.15.0 # via dnspython3 From 94ba1e77dd2b1ae6187fa16e1ea34c3ff14f7e95 Mon Sep 17 00:00:00 2001 From: Jasmine Schladen Date: Mon, 7 Dec 2020 18:33:31 -0800 Subject: [PATCH 124/314] Improve formatting for multiword email notification types --- lemur/plugins/lemur_email/plugin.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/lemur/plugins/lemur_email/plugin.py b/lemur/plugins/lemur_email/plugin.py index 214586ab..b3e706e8 100644 --- a/lemur/plugins/lemur_email/plugin.py +++ b/lemur/plugins/lemur_email/plugin.py @@ -108,7 +108,8 @@ class EmailNotificationPlugin(ExpirationNotificationPlugin): if not targets: return - subject = "Lemur: {0} Notification".format(notification_type.capitalize()) + readable_notification_type = ' '.join(map(lambda x: x.capitalize(), notification_type.split('_'))) + subject = f"Lemur: {readable_notification_type} Notification" body = render_html(notification_type, options, message) From 5e33eee5c8661755789d5c4fa78d40437303947a Mon Sep 17 00:00:00 2001 From: sirferl Date: Tue, 8 Dec 2020 10:53:28 +0100 Subject: [PATCH 125/314] make options for sources optional --- lemur/sources/views.py | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) diff --git a/lemur/sources/views.py b/lemur/sources/views.py index 3b4deab7..bc104e33 100644 --- a/lemur/sources/views.py +++ b/lemur/sources/views.py @@ -156,12 +156,19 @@ class SourcesList(AuthenticatedResource): :reqheader Authorization: OAuth token to authenticate :statuscode 200: no error """ - return service.create( - data["label"], - data["plugin"]["slug"], - data["plugin"]["plugin_options"], - data["description"], - ) + if "plugin_options" in data["plugin"]: + return service.create( + data["label"], + data["plugin"]["slug"], + data["plugin"]["plugin_options"], + data["description"], + ) + else: + return service.create( + data["label"], + data["plugin"]["slug"], + data["description"], + ) class Sources(AuthenticatedResource): From 9a380528683814132d78e797a594ceff7ba9ef48 Mon Sep 17 00:00:00 2001 From: sirferl Date: Tue, 8 Dec 2020 11:03:08 +0100 Subject: [PATCH 126/314] Lint - whitespace error fixed --- lemur/sources/views.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lemur/sources/views.py b/lemur/sources/views.py index bc104e33..9c31bdb7 100644 --- a/lemur/sources/views.py +++ b/lemur/sources/views.py @@ -156,7 +156,7 @@ class SourcesList(AuthenticatedResource): :reqheader Authorization: OAuth token to authenticate :statuscode 200: no error """ - if "plugin_options" in data["plugin"]: + if "plugin_options" in data["plugin"]: return service.create( data["label"], data["plugin"]["slug"], From 8a10b861be65f7913d5041cc90027e20b7f32719 Mon Sep 17 00:00:00 2001 From: sirferl Date: Tue, 8 Dec 2020 11:05:55 +0100 Subject: [PATCH 127/314] options not needed any more --- lemur/plugins/lemur_entrust/plugin.py | 9 --------- 1 file changed, 9 deletions(-) diff --git a/lemur/plugins/lemur_entrust/plugin.py b/lemur/plugins/lemur_entrust/plugin.py index 83547a20..a4cb9a12 100644 --- a/lemur/plugins/lemur_entrust/plugin.py +++ b/lemur/plugins/lemur_entrust/plugin.py @@ -319,15 +319,6 @@ class EntrustSourcePlugin(SourcePlugin): author = "sirferl" author_url = "https://github.com/sirferl/lemur" - options = [ - { - "name": "dummy", - "type": "str", - "required": False, - "validation": "/^[0-9]{12,12}$/", - "helpMessage": "Just to prevent error", - } - ] def __init__(self, *args, **kwargs): """Initialize the issuer with the appropriate details.""" From b93c0282150a567cc16b706ac2583bc5cfb1002d Mon Sep 17 00:00:00 2001 From: sirferl Date: Tue, 8 Dec 2020 11:07:09 +0100 Subject: [PATCH 128/314] source plugin: options not needed any more --- lemur/plugins/lemur_adcs/plugin.py | 9 --------- 1 file changed, 9 deletions(-) diff --git a/lemur/plugins/lemur_adcs/plugin.py b/lemur/plugins/lemur_adcs/plugin.py index d2efe83f..495885a0 100644 --- a/lemur/plugins/lemur_adcs/plugin.py +++ b/lemur/plugins/lemur_adcs/plugin.py @@ -77,15 +77,6 @@ class ADCSSourcePlugin(SourcePlugin): author = "sirferl" author_url = "https://github.com/sirferl/lemur" - options = [ - { - "name": "dummy", - "type": "str", - "required": False, - "validation": "/^[0-9]{12,12}$/", - "helpMessage": "Just to prevent error", - } - ] def get_certificates(self, options, **kwargs): adcs_server = current_app.config.get("ADCS_SERVER") From eab55323979aec08407838a479442c6acf159d43 Mon Sep 17 00:00:00 2001 From: Jasmine Schladen Date: Tue, 8 Dec 2020 11:41:41 -0800 Subject: [PATCH 129/314] Add expiration summary email for security team --- docs/administration.rst | 13 ++ docs/developer/index.rst | 2 +- docs/production/index.rst | 12 +- lemur/common/celery.py | 36 ++++ lemur/notifications/cli.py | 24 +++ lemur/notifications/messaging.py | 106 ++++++++++ .../templates/expiration_summary.html | 194 ++++++++++++++++++ lemur/tests/test_messaging.py | 38 +++- 8 files changed, 421 insertions(+), 4 deletions(-) create mode 100644 lemur/plugins/lemur_email/templates/expiration_summary.html diff --git a/docs/administration.rst b/docs/administration.rst index 1415e598..4c755e7b 100644 --- a/docs/administration.rst +++ b/docs/administration.rst @@ -287,6 +287,7 @@ Supported types: * CA certificate expiration * Pending ACME certificate failure * Certificate rotation +* Security certificate expiration summary **Default notifications** @@ -358,6 +359,18 @@ Whenever a cert is rotated, Lemur will send a notification via email to the cert disabled by default; to enable it, you must set the option ``--notify`` (when using cron) or the configuration parameter ``ENABLE_ROTATION_NOTIFICATION`` (when using celery). +**Security certificate expiration summary** + +If you enable the Celery or cron task to send this notification type, Lemur will send a summary of all +certificates with upcoming expiration date that matches one of the intervals configured in the +``LEMUR_SECURITY_TEAM_EMAIL_INTERVALS`` configuration parameter (with the same fallbacks as noted above). +Note that certificates will be included in this summary even if they do not have any associated notifications. + +This notification type also supports the same ``--exclude`` and ``EXCLUDE_CN_FROM_NOTIFICATION`` options as expiration emails. + +NOTE: At present, this summary email essentially duplicates the certificate expiration notifications, since all +certificate expiration notifications are also sent to the security team. This issue will be fixed in the future. + **Email notifications** Templates for emails are located under `lemur/plugins/lemur_email/templates` and can be modified for your needs. diff --git a/docs/developer/index.rst b/docs/developer/index.rst index 0033c3f4..bff53a96 100644 --- a/docs/developer/index.rst +++ b/docs/developer/index.rst @@ -54,7 +54,7 @@ of Lemur. You'll want to make sure you have a few things on your local system fi * pip * virtualenv (ideally virtualenvwrapper) * node.js (for npm and building css/javascript) -+* `PostgreSQL `_ +* `PostgreSQL `_ Once you've got all that, the rest is simple: diff --git a/docs/production/index.rst b/docs/production/index.rst index 106f6b99..fa0a7dec 100644 --- a/docs/production/index.rst +++ b/docs/production/index.rst @@ -323,9 +323,9 @@ Periodic Tasks Lemur contains a few tasks that are run and scheduled basis, currently the recommend way to run these tasks is to create celery tasks or cron jobs that run these commands. -There are currently three commands that could/should be run on a periodic basis: +The following commands that could/should be run on a periodic basis: -- `notify expirations` and `notify authority_expirations` (see :ref:`NotificationOptions` for configuration info) +- `notify expirations` `notify authority_expirations`, and `notify security_expiration_summary` (see :ref:`NotificationOptions` for configuration info) - `check_revoked` - `sync` @@ -343,6 +343,7 @@ Example cron entries:: 0 22 * * * lemuruser export LEMUR_CONF=/Users/me/.lemur/lemur.conf.py; /www/lemur/bin/lemur notify expirations 0 22 * * * lemuruser export LEMUR_CONF=/Users/me/.lemur/lemur.conf.py; /www/lemur/bin/lemur notify authority_expirations + 0 22 * * * lemuruser export LEMUR_CONF=/Users/me/.lemur/lemur.conf.py; /www/lemur/bin/lemur notify security_expiration_summary */15 * * * * lemuruser export LEMUR_CONF=/Users/me/.lemur/lemur.conf.py; /www/lemur/bin/lemur source sync -s all 0 22 * * * lemuruser export LEMUR_CONF=/Users/me/.lemur/lemur.conf.py; /www/lemur/bin/lemur certificate check_revoked @@ -398,6 +399,13 @@ Example Celery configuration (To be placed in your configuration file):: 'expires': 180 }, 'schedule': crontab(hour=22, minute=0), + }, + 'send_security_expiration_summary': { + 'task': 'lemur.common.celery.send_security_expiration_summary', + 'options': { + 'expires': 180 + }, + 'schedule': crontab(hour=22, minute=0), } } diff --git a/lemur/common/celery.py b/lemur/common/celery.py index 9dc4bd0a..574d6ec5 100644 --- a/lemur/common/celery.py +++ b/lemur/common/celery.py @@ -857,6 +857,42 @@ def notify_authority_expirations(): return log_data +@celery.task(soft_time_limit=3600) +def send_security_expiration_summary(): + """ + This celery task sends a summary about expiring certificates to the security team. TODO document + :return: + """ + function = f"{__name__}.{sys._getframe().f_code.co_name}" + task_id = None + if celery.current_task: + task_id = celery.current_task.request.id + + log_data = { + "function": function, + "message": "send summary for certificate expiration", + "task_id": task_id, + } + + if task_id and is_task_active(function, task_id, None): + log_data["message"] = "Skipping task: Task is already active" + current_app.logger.debug(log_data) + return + + current_app.logger.debug(log_data) + try: + cli_notification.send_security_expiration_summary() + except SoftTimeLimitExceeded: + log_data["message"] = "Send summary for expiring certs Time limit exceeded." + current_app.logger.error(log_data) + sentry.captureException() + metrics.send("celery.timeout", "counter", 1, metric_tags={"function": function}) + return + + metrics.send(f"{function}.success", "counter", 1) + return log_data + + @celery.task(soft_time_limit=3600) def enable_autorotate_for_certs_attached_to_endpoint(): """ diff --git a/lemur/notifications/cli.py b/lemur/notifications/cli.py index 3c29693b..d86028c0 100644 --- a/lemur/notifications/cli.py +++ b/lemur/notifications/cli.py @@ -11,6 +11,7 @@ from lemur.constants import SUCCESS_METRIC_STATUS, FAILURE_METRIC_STATUS from lemur.extensions import sentry, metrics from lemur.notifications.messaging import send_expiration_notifications from lemur.notifications.messaging import send_authority_expiration_notifications +from lemur.notifications.messaging import send_security_expiration_summary manager = Manager(usage="Handles notification related tasks.") @@ -73,3 +74,26 @@ def authority_expirations(): metrics.send( "authority_expiration_notification_job", "counter", 1, metric_tags={"status": status} ) + + +def security_expiration_summary(exclude): + """ + Sends a summary email with info on all expiring certs (that match the configured expiry intervals). + + :return: + """ + status = FAILURE_METRIC_STATUS + try: + print("Starting to notify security team about expiring certificates!") + success, failed = send_security_expiration_summary(exclude) + print( + "Finished notifying security team about expiring certificates! " + f"Sent: {success} Failed: {failed}" + ) + status = SUCCESS_METRIC_STATUS + except Exception: + sentry.captureException() + + metrics.send( + "security_expiration_notification_job", "counter", 1, metric_tags={"status": status} + ) diff --git a/lemur/notifications/messaging.py b/lemur/notifications/messaging.py index 75d829b1..e121e09a 100644 --- a/lemur/notifications/messaging.py +++ b/lemur/notifications/messaging.py @@ -63,6 +63,44 @@ def get_certificates(exclude=None): return certs +def get_certificates_for_security_summary_email(exclude=None): + """ + Finds all certificates that are eligible for expiration notifications for the security expiration summary. + :param exclude: + :return: + """ + now = arrow.utcnow() + expiration_summary_intervals = current_app.config.get("LEMUR_SECURITY_TEAM_EMAIL_INTERVALS", # first priority + current_app.config.get( # second priority + "LEMUR_DEFAULT_EXPIRATION_NOTIFICATION_INTERVALS", + [30, 15, 2] # third priority + ) + ) + max_not_after = now + timedelta(days=max(expiration_summary_intervals) + 1) + + q = ( + database.db.session.query(Certificate) + .filter(Certificate.not_after <= max_not_after) + .filter(Certificate.notify == true()) + .filter(Certificate.expired == false()) + .filter(Certificate.revoked == false()) + ) + + exclude_conditions = [] + if exclude: + for e in exclude: + exclude_conditions.append(~Certificate.name.ilike("%{}%".format(e))) + + q = q.filter(and_(*exclude_conditions)) + + certs = [] + for c in windowed_query(q, Certificate.id, 10000): + days_remaining = (c.not_after - now).days + if days_remaining in expiration_summary_intervals: + certs.append(c) + return certs + + def get_expiring_authority_certificates(): """ Finds all certificate authority certificates that are eligible for expiration notifications. @@ -119,6 +157,18 @@ def get_eligible_certificates(exclude=None): return certificates +def get_eligible_security_summary_certs(exclude=None): + certificates = defaultdict(list) + all_certs = get_certificates_for_security_summary_email(exclude=exclude) + now = arrow.utcnow() + + # group by expiration interval + for interval, interval_certs in groupby(all_certs, lambda x: (x.not_after - now).days): + certificates[interval] = list(interval_certs) + + return certificates + + def get_eligible_authority_certificates(): """ Finds all certificate authority certificates that are eligible for certificate expiration notification. @@ -370,3 +420,59 @@ def needs_notification(certificate): if days == interval: notifications.append(notification) return notifications + + +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": f"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 diff --git a/lemur/plugins/lemur_email/templates/expiration_summary.html b/lemur/plugins/lemur_email/templates/expiration_summary.html new file mode 100644 index 00000000..d2e98196 --- /dev/null +++ b/lemur/plugins/lemur_email/templates/expiration_summary.html @@ -0,0 +1,194 @@ + + + + + + + + Lemur + + +
+
+ + + + + + + + + +
+ + + + + + + + + + + + + + + + + + + + +
+ + + + + + +
+ Lemur +
+
+ + + + + + + + + + + + + + +
+ Lemur certificate expiration summary +
+
+ + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + +
+ Hi, +
+
This is a summary of all certificates expiring soon. + Only certificates matching the configured expiration intervals are included here. + Certificates with notifications disabled have been omitted. + + + {% for interval_and_certs in message["certificates"] | sort(attribute="interval") %} + + + + + + + + + {% for certificate in interval_and_certs["certificates"] %} + + + + + + {% if not loop.last %} + + + + {% endif %} + {% endfor %} + {% endfor %} + +
+ +
Expiring in {{ interval_and_certs["interval"] }} days
+
+
+ + {{ certificate.name }} + + + {% if certificate.endpoints | length > 0 %} + +
{{ certificate.endpoints | length }} Endpoints +
+ {% else %} +
{{ certificate.endpoints | length }} Endpoints + {% endif %} +
{{ certificate.owner }} +
{{ certificate.validityEnd | time }} + Details +
+
+
+ Please take action if any of the above certificates are still needed. +
+
Best,
Lemur +
+ + + + + + +
*All expiration times are in UTC
+
+
+
+ + + + + + + + + +
You received this mandatory email announcement to update you about + important changes to your TLS certificate. +
+
© 2020 Lemur +
+
+
+
+ diff --git a/lemur/tests/test_messaging.py b/lemur/tests/test_messaging.py index 0845d468..85032c00 100644 --- a/lemur/tests/test_messaging.py +++ b/lemur/tests/test_messaging.py @@ -5,7 +5,7 @@ import boto3 import pytest from freezegun import freeze_time from moto import mock_ses -from lemur.tests.factories import AuthorityFactory, CertificateFactory +from lemur.tests.factories import AuthorityFactory, CertificateFactory, EndpointFactory @mock_ses @@ -112,6 +112,26 @@ def test_send_expiration_notification_with_no_notifications( assert send_expiration_notifications([]) == (0, 0) +@mock_ses +def test_send_expiration_summary_notification(certificate, notification, notification_plugin): + from lemur.notifications.messaging import send_security_expiration_summary + verify_sender_email() + + # we don't actually test the email contents, but adding an assortment of certs here is useful for step debugging + # to confirm the produced email body looks like we expect + create_cert_that_expires_in_days(2) + create_cert_that_expires_in_days(2) + create_cert_that_expires_in_days(2) + create_cert_that_expires_in_days(30) + create_cert_that_expires_in_days(30) + create_cert_that_expires_in_days(15) + create_cert_that_expires_in_days(20) + create_cert_that_expires_in_days(1) + create_cert_that_expires_in_days(100) + + assert send_security_expiration_summary([]) + + @mock_ses def test_send_rotation_notification(notification_plugin, certificate): from lemur.notifications.messaging import send_rotation_notification @@ -170,3 +190,19 @@ def create_ca_cert_that_expires_in_days(days): certificate.root_authority_id = authority.id certificate.authority_id = None return certificate + + +def create_cert_that_expires_in_days(days): + from random import randrange + + now = arrow.utcnow() + not_after = now + timedelta(days=days, hours=1) # a bit more than specified since we'll check in the future + + certificate = CertificateFactory() + certificate.not_after = not_after + certificate.notify = True + endpoints = [] + for i in range(0, randrange(0, 5)): + endpoints.append(EndpointFactory()) + certificate.endpoints = endpoints + return certificate From 065e4d3964d5e1f7276b7a1511e7879266a6cfb7 Mon Sep 17 00:00:00 2001 From: Jasmine Schladen Date: Tue, 8 Dec 2020 11:46:55 -0800 Subject: [PATCH 130/314] Add new configuration for summary email intervals --- docs/administration.rst | 2 +- lemur/notifications/messaging.py | 7 +------ lemur/tests/test_messaging.py | 5 ++--- 3 files changed, 4 insertions(+), 10 deletions(-) diff --git a/docs/administration.rst b/docs/administration.rst index 4c755e7b..fb576b9c 100644 --- a/docs/administration.rst +++ b/docs/administration.rst @@ -363,7 +363,7 @@ disabled by default; to enable it, you must set the option ``--notify`` (when us If you enable the Celery or cron task to send this notification type, Lemur will send a summary of all certificates with upcoming expiration date that matches one of the intervals configured in the -``LEMUR_SECURITY_TEAM_EMAIL_INTERVALS`` configuration parameter (with the same fallbacks as noted above). +``LEMUR_EXPIRATION_SUMMARY_EMAIL_INTERVALS`` configuration parameter (with a fallback of 14 days). Note that certificates will be included in this summary even if they do not have any associated notifications. This notification type also supports the same ``--exclude`` and ``EXCLUDE_CN_FROM_NOTIFICATION`` options as expiration emails. diff --git a/lemur/notifications/messaging.py b/lemur/notifications/messaging.py index e121e09a..b472a5f7 100644 --- a/lemur/notifications/messaging.py +++ b/lemur/notifications/messaging.py @@ -70,12 +70,7 @@ def get_certificates_for_security_summary_email(exclude=None): :return: """ now = arrow.utcnow() - expiration_summary_intervals = current_app.config.get("LEMUR_SECURITY_TEAM_EMAIL_INTERVALS", # first priority - current_app.config.get( # second priority - "LEMUR_DEFAULT_EXPIRATION_NOTIFICATION_INTERVALS", - [30, 15, 2] # third priority - ) - ) + expiration_summary_intervals = current_app.config.get("LEMUR_EXPIRATION_SUMMARY_EMAIL_INTERVALS", [14]) max_not_after = now + timedelta(days=max(expiration_summary_intervals) + 1) q = ( diff --git a/lemur/tests/test_messaging.py b/lemur/tests/test_messaging.py index 85032c00..c1c9b24a 100644 --- a/lemur/tests/test_messaging.py +++ b/lemur/tests/test_messaging.py @@ -119,10 +119,9 @@ def test_send_expiration_summary_notification(certificate, notification, notific # we don't actually test the email contents, but adding an assortment of certs here is useful for step debugging # to confirm the produced email body looks like we expect + for i in range(1, 6): + create_cert_that_expires_in_days(14) create_cert_that_expires_in_days(2) - create_cert_that_expires_in_days(2) - create_cert_that_expires_in_days(2) - create_cert_that_expires_in_days(30) create_cert_that_expires_in_days(30) create_cert_that_expires_in_days(15) create_cert_that_expires_in_days(20) From 15d43d6c270b5c81470f6834570c9962428bfea2 Mon Sep 17 00:00:00 2001 From: Jasmine Schladen Date: Tue, 8 Dec 2020 12:09:53 -0800 Subject: [PATCH 131/314] Fix lint errors --- lemur/notifications/messaging.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/lemur/notifications/messaging.py b/lemur/notifications/messaging.py index b472a5f7..9a55ab3a 100644 --- a/lemur/notifications/messaging.py +++ b/lemur/notifications/messaging.py @@ -75,10 +75,10 @@ def get_certificates_for_security_summary_email(exclude=None): q = ( database.db.session.query(Certificate) - .filter(Certificate.not_after <= max_not_after) - .filter(Certificate.notify == true()) - .filter(Certificate.expired == false()) - .filter(Certificate.revoked == false()) + .filter(Certificate.not_after <= max_not_after) + .filter(Certificate.notify == true()) + .filter(Certificate.expired == false()) + .filter(Certificate.revoked == false()) ) exclude_conditions = [] @@ -434,7 +434,7 @@ def send_security_expiration_summary(exclude=None): notification_type = "expiration_summary" log_data = { "function": function, - "message": f"Sending expiration summary notification for to security team", + "message": "Sending expiration summary notification for to security team", "notification_type": notification_type, "notification_plugin": notification_plugin.slug, } From 512b1acfddbdc2558717e53791303651a63c4f8d Mon Sep 17 00:00:00 2001 From: Jasmine Schladen Date: Tue, 8 Dec 2020 18:29:48 -0800 Subject: [PATCH 132/314] PR feedback: use days threshold instead of interval set, etc. --- docs/administration.rst | 4 ++-- lemur/common/celery.py | 4 ++-- lemur/notifications/messaging.py | 6 +++--- lemur/tests/test_messaging.py | 7 +++++-- 4 files changed, 12 insertions(+), 9 deletions(-) diff --git a/docs/administration.rst b/docs/administration.rst index fb576b9c..bd0b5f96 100644 --- a/docs/administration.rst +++ b/docs/administration.rst @@ -362,8 +362,8 @@ disabled by default; to enable it, you must set the option ``--notify`` (when us **Security certificate expiration summary** If you enable the Celery or cron task to send this notification type, Lemur will send a summary of all -certificates with upcoming expiration date that matches one of the intervals configured in the -``LEMUR_EXPIRATION_SUMMARY_EMAIL_INTERVALS`` configuration parameter (with a fallback of 14 days). +certificates with upcoming expiration date that occurs within the number of days specified by the +``LEMUR_EXPIRATION_SUMMARY_EMAIL_THRESHOLD_DAYS`` configuration parameter (with a fallback of 14 days). Note that certificates will be included in this summary even if they do not have any associated notifications. This notification type also supports the same ``--exclude`` and ``EXCLUDE_CN_FROM_NOTIFICATION`` options as expiration emails. diff --git a/lemur/common/celery.py b/lemur/common/celery.py index 574d6ec5..578592dc 100644 --- a/lemur/common/celery.py +++ b/lemur/common/celery.py @@ -860,7 +860,7 @@ def notify_authority_expirations(): @celery.task(soft_time_limit=3600) def send_security_expiration_summary(): """ - This celery task sends a summary about expiring certificates to the security team. TODO document + This celery task sends a summary about expiring certificates to the security team. :return: """ function = f"{__name__}.{sys._getframe().f_code.co_name}" @@ -881,7 +881,7 @@ def send_security_expiration_summary(): current_app.logger.debug(log_data) try: - cli_notification.send_security_expiration_summary() + cli_notification.security_expiration_summary(current_app.config.get("EXCLUDE_CN_FROM_NOTIFICATION", [])) except SoftTimeLimitExceeded: log_data["message"] = "Send summary for expiring certs Time limit exceeded." current_app.logger.error(log_data) diff --git a/lemur/notifications/messaging.py b/lemur/notifications/messaging.py index 9a55ab3a..1d7bda4c 100644 --- a/lemur/notifications/messaging.py +++ b/lemur/notifications/messaging.py @@ -70,8 +70,8 @@ def get_certificates_for_security_summary_email(exclude=None): :return: """ now = arrow.utcnow() - expiration_summary_intervals = current_app.config.get("LEMUR_EXPIRATION_SUMMARY_EMAIL_INTERVALS", [14]) - max_not_after = now + timedelta(days=max(expiration_summary_intervals) + 1) + threshold_days = current_app.config.get("LEMUR_EXPIRATION_SUMMARY_EMAIL_THRESHOLD_DAYS", 14) + max_not_after = now + timedelta(days=threshold_days + 1) q = ( database.db.session.query(Certificate) @@ -91,7 +91,7 @@ def get_certificates_for_security_summary_email(exclude=None): certs = [] for c in windowed_query(q, Certificate.id, 10000): days_remaining = (c.not_after - now).days - if days_remaining in expiration_summary_intervals: + if days_remaining <= threshold_days: certs.append(c) return certs diff --git a/lemur/tests/test_messaging.py b/lemur/tests/test_messaging.py index c1c9b24a..d897f931 100644 --- a/lemur/tests/test_messaging.py +++ b/lemur/tests/test_messaging.py @@ -119,8 +119,11 @@ def test_send_expiration_summary_notification(certificate, notification, notific # we don't actually test the email contents, but adding an assortment of certs here is useful for step debugging # to confirm the produced email body looks like we expect - for i in range(1, 6): - create_cert_that_expires_in_days(14) + create_cert_that_expires_in_days(14) + create_cert_that_expires_in_days(12) + create_cert_that_expires_in_days(9) + create_cert_that_expires_in_days(7) + create_cert_that_expires_in_days(7) create_cert_that_expires_in_days(2) create_cert_that_expires_in_days(30) create_cert_that_expires_in_days(15) From 22d9ef77988f45db24a1059274ec28306723b8b5 Mon Sep 17 00:00:00 2001 From: sayali Date: Tue, 8 Dec 2020 19:20:28 -0800 Subject: [PATCH 133/314] Upgrade gulp to 4.0.2 --- gulp/build.js | 93 +++++++++++++++++++++++++------------------------- gulp/server.js | 17 ++++++--- gulp/watch.js | 12 ------- package.json | 2 +- 4 files changed, 60 insertions(+), 64 deletions(-) delete mode 100644 gulp/watch.js diff --git a/gulp/build.js b/gulp/build.js index 5aca8094..11919d7f 100644 --- a/gulp/build.js +++ b/gulp/build.js @@ -29,24 +29,24 @@ var gulp = require('gulp'), replace = require('gulp-replace'), argv = require('yargs').argv; -gulp.task('default', ['clean'], function () { - gulp.start('fonts', 'styles'); -}); - -gulp.task('clean', function (cb) { +gulp.task('clean', async function (cb) { del(['.tmp', 'lemur/static/dist'], cb); }); -gulp.task('test', function (done) { +gulp.task('default', gulp.series('clean', function () { + gulp.start('fonts', 'styles'); +})); + +gulp.task('test', gulp.series(function (done) { new karma.Server({ configFile: __dirname + '/karma.conf.js', singleRun: true }, function() { done(); }).start(); -}); +})); -gulp.task('dev:fonts', function () { +gulp.task('dev:fonts', async function () { var fileList = [ 'bower_components/bootstrap/dist/fonts/*', 'bower_components/fontawesome/fonts/*' @@ -56,7 +56,7 @@ gulp.task('dev:fonts', function () { .pipe(gulp.dest('.tmp/fonts')); }); -gulp.task('dev:styles', function () { +gulp.task('dev:styles', async function () { var baseContent = '@import "bower_components/bootstrap/less/bootstrap.less";@import "bower_components/bootswatch/$theme$/variables.less";@import "bower_components/bootswatch/$theme$/bootswatch.less";@import "bower_components/bootstrap/less/utilities.less";'; var isBootswatchFile = function (file) { @@ -74,7 +74,6 @@ gulp.task('dev:styles', function () { var fileList = [ 'bower_components/bootswatch/sandstone/bootswatch.less', 'bower_components/fontawesome/css/font-awesome.css', - 'bower_components/angular-spinkit/src/angular-spinkit.css', 'bower_components/angular-chart.js/dist/angular-chart.css', 'bower_components/angular-loading-bar/src/loading-bar.css', 'bower_components/angular-ui-switch/angular-ui-switch.css', @@ -100,7 +99,7 @@ gulp.task('dev:styles', function () { // http://stackoverflow.com/questions/21719833/gulp-how-to-add-src-files-in-the-middle-of-a-pipe // https://github.com/gulpjs/gulp/blob/master/docs/recipes/using-multiple-sources-in-one-task.md - return merge(stream, gulp.src(['.tmp/styles/font-awesome.css', '.tmp/styles/lemur.css'])) + return merge(stream, gulp.src(['.tmp/styles/font-awesome.css', '.tmp/styles/lemur.css'], { allowEmpty: true })) .pipe(concat('style-' + themeName + '.css')); }))) .pipe(plumber()) @@ -129,14 +128,14 @@ function string_src(filename, string) { return src; } -gulp.task('dev:scripts', function () { +gulp.task('dev:scripts', async function () { return gulp.src(['lemur/static/app/angular/**/*.js']) .pipe(jshint()) .pipe(jshint.reporter('jshint-stylish')) .pipe(size()); }); -gulp.task('build:extras', function () { +gulp.task('build:extras', async function () { return gulp.src(['lemur/static/app/*.*', '!lemur/static/app/*.html']) .pipe(gulp.dest('lemur/static/dist')); }); @@ -162,7 +161,7 @@ function injectHtml(isDev) { })) .pipe( gulpif(!isDev, - inject(gulp.src('lemur/static/dist/ngviews/ngviews.min.js'), { + inject(gulp.src('lemur/static/dist/ngviews/ngviews.min.js', { allowEmpty: true }), { starttag: '', addRootSlash: false }) @@ -170,15 +169,11 @@ function injectHtml(isDev) { ).pipe(gulp.dest('.tmp/')); } -gulp.task('dev:inject', ['dev:styles', 'dev:scripts'], function () { +gulp.task('dev:inject', gulp.series(gulp.parallel('dev:styles', 'dev:scripts'), function () { return injectHtml(true); -}); +})); -gulp.task('build:inject', ['dev:styles', 'dev:scripts', 'build:ngviews'], function () { - return injectHtml(false); -}); - -gulp.task('build:ngviews', function () { +gulp.task('build:ngviews', async function () { return gulp.src(['lemur/static/app/angular/**/*.html']) .pipe(minifyHtml({ empty: true, @@ -189,7 +184,11 @@ gulp.task('build:ngviews', function () { .pipe(size()); }); -gulp.task('build:html', ['dev:styles', 'dev:scripts', 'build:ngviews', 'build:inject'], function () { +gulp.task('build:inject', gulp.series(gulp.parallel('dev:styles', 'dev:scripts', 'build:ngviews'), function () { + return injectHtml(false); +})); + +gulp.task('build:html', gulp.series(gulp.parallel('dev:styles', 'dev:scripts', 'build:ngviews', 'build:inject'), function () { var jsFilter = filter(['**/*.js'], {'restore': true}); var cssFilter = filter(['**/*.css'], {'restore': true}); @@ -203,14 +202,14 @@ gulp.task('build:html', ['dev:styles', 'dev:scripts', 'build:ngviews', 'build:in .pipe(useref()) .pipe(gulp.dest('lemur/static/dist')) .pipe(size()); -}); +})); -gulp.task('build:fonts', ['dev:fonts'], function () { +gulp.task('build:fonts', gulp.series('dev:fonts', function () { return gulp.src('.tmp/fonts/**/*') .pipe(gulp.dest('lemur/static/dist/fonts')); -}); +})); -gulp.task('build:images', function () { +gulp.task('build:images', async function () { return gulp.src('lemur/static/app/images/**/*') .pipe(cache(imagemin({ optimizationLevel: 3, @@ -221,8 +220,8 @@ gulp.task('build:images', function () { .pipe(size()); }); -gulp.task('package:strip', function () { - return gulp.src(['lemur/static/dist/scripts/main*']) +gulp.task('package:strip', async function () { + return gulp.src('lemur/static/dist/scripts/main*') .pipe(replace('http:\/\/localhost:3000', '')) .pipe(replace('http:\/\/localhost:8000', '')) .pipe(useref()) @@ -230,7 +229,22 @@ gulp.task('package:strip', function () { .pipe(size()); }); -gulp.task('addUrlContextPath',['addUrlContextPath:revreplace'], function(){ +gulp.task('addUrlContextPath:revision', async function(){ + return gulp.src(['lemur/static/dist/**/*.css','lemur/static/dist/**/*.js']) + .pipe(rev()) + .pipe(gulp.dest('lemur/static/dist')) + .pipe(rev.manifest()) + .pipe(gulp.dest('lemur/static/dist')) +}); + +gulp.task('addUrlContextPath:revreplace', gulp.series('addUrlContextPath:revision', function(){ + // var manifest = gulp.src("lemur/static/dist/rev-manifest.json"); + // var urlContextPathExists = argv.urlContextPath ? true : false; + return gulp.src( "lemur/static/dist/index.html") + .pipe(gulp.dest('lemur/static/dist')); +})); + +gulp.task('addUrlContextPath', gulp.series('addUrlContextPath:revreplace', async function(){ var urlContextPathExists = argv.urlContextPath ? true : false; ['lemur/static/dist/scripts/main*.js', 'lemur/static/dist/angular/**/*.html'] @@ -242,23 +256,8 @@ gulp.task('addUrlContextPath',['addUrlContextPath:revreplace'], function(){ return file.base; })) }) -}); - -gulp.task('addUrlContextPath:revision', function(){ - return gulp.src(['lemur/static/dist/**/*.css','lemur/static/dist/**/*.js']) - .pipe(rev()) - .pipe(gulp.dest('lemur/static/dist')) - .pipe(rev.manifest()) - .pipe(gulp.dest('lemur/static/dist')) -}) - -gulp.task('addUrlContextPath:revreplace', ['addUrlContextPath:revision'], function(){ - var manifest = gulp.src("lemur/static/dist/rev-manifest.json"); - var urlContextPathExists = argv.urlContextPath ? true : false; - return gulp.src( "lemur/static/dist/index.html") - .pipe(gulp.dest('lemur/static/dist')); -}) +})); -gulp.task('build', ['build:ngviews', 'build:inject', 'build:images', 'build:fonts', 'build:html', 'build:extras']); -gulp.task('package', ['addUrlContextPath', 'package:strip']); +gulp.task('build', gulp.series(gulp.parallel('build:ngviews', 'build:inject', 'build:images', 'build:fonts', 'build:html', 'build:extras'))); +gulp.task('package', gulp.series(gulp.parallel('addUrlContextPath', 'package:strip'))); diff --git a/gulp/server.js b/gulp/server.js index 6c61273e..804ca115 100644 --- a/gulp/server.js +++ b/gulp/server.js @@ -38,7 +38,16 @@ function browserSyncInit(baseDir, files, browser) { } -gulp.task('serve', ['watch'], function () { +gulp.task('watch', gulp.series(['dev:styles', 'dev:scripts', 'dev:inject', 'dev:fonts'], function (done) { + gulp.watch('app/styles/**/*.less', gulp.parallel('dev:styles')); + gulp.watch('app/styles/**/*.css', gulp.parallel('dev:styles')); + gulp.watch('app/**/*.js', gulp.parallel('dev:scripts')); + gulp.watch('app/images/**/*', gulp.parallel('build:images')); + gulp.watch('bower.json', gulp.parallel('dev:inject')); + done(); +})); + +gulp.task('serve', gulp.series('watch', function () { browserSyncInit([ '.tmp', 'lemur/static/app' @@ -51,9 +60,9 @@ gulp.task('serve', ['watch'], function () { 'lemur/static/app/angular/**/*', 'lemur/static/app/index.html' ]); -}); +})); -gulp.task('serve:dist', ['build'], function () { +gulp.task('serve:dist', gulp.series('build', function () { browserSyncInit('lemur/static/dist'); -}); +})); diff --git a/gulp/watch.js b/gulp/watch.js deleted file mode 100644 index 460a935b..00000000 --- a/gulp/watch.js +++ /dev/null @@ -1,12 +0,0 @@ -'use strict'; - -var gulp = require('gulp'); - - -gulp.task('watch', ['dev:styles', 'dev:scripts', 'dev:inject', 'dev:fonts'] ,function () { - gulp.watch('app/styles/**/*.less', ['dev:styles']); - gulp.watch('app/styles/**/*.css', ['dev:styles']); - gulp.watch('app/**/*.js', ['dev:scripts']); - gulp.watch('app/images/**/*', ['build:images']); - gulp.watch('bower.json', ['dev:inject']); -}); diff --git a/package.json b/package.json index c4105e01..962d0a69 100644 --- a/package.json +++ b/package.json @@ -59,7 +59,7 @@ "test": "gulp test" }, "devDependencies": { - "gulp": "^3.9.1", + "gulp": "^4.0.2", "jshint": "^2.11.0", "karma-chrome-launcher": "^2.0.0" } From 8bab89262cc668f08b70c59f486781cb789c2de0 Mon Sep 17 00:00:00 2001 From: sayali Date: Tue, 8 Dec 2020 19:21:03 -0800 Subject: [PATCH 134/314] lodash upgrade 4.17.20 --- bower.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bower.json b/bower.json index 8a042a8d..ed6d6bf6 100644 --- a/bower.json +++ b/bower.json @@ -29,7 +29,7 @@ "satellizer": "~0.13.4", "angular-ui-router": "~0.2.15", "font-awesome": "~4.5.0", - "lodash": "~4.0.1", + "lodash": "~4.17.20", "underscore": "~1.8.3", "angular-smart-table": "2.1.8", "angular-strap": ">= 2.2.2", From cf652952ff2807f66ddb0108558a3f356e1e0497 Mon Sep 17 00:00:00 2001 From: sayali Date: Tue, 8 Dec 2020 19:21:38 -0800 Subject: [PATCH 135/314] karma version update ^5.2.3 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 962d0a69..17dc98e3 100644 --- a/package.json +++ b/package.json @@ -41,7 +41,7 @@ "gulp-util": "^3.0.1", "http-proxy": ">=1.18.1", "jshint-stylish": "^2.2.1", - "karma": "^4.4.1", + "karma": "^5.2.3", "karma-jasmine": "^1.1.0", "main-bower-files": "^2.13.1", "merge-stream": "^1.0.1", From 856c2da15c18ba92e594f6eda344b3220e2cd51a Mon Sep 17 00:00:00 2001 From: sayali Date: Tue, 8 Dec 2020 19:22:01 -0800 Subject: [PATCH 136/314] yargs version update ^16.0.0 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 17dc98e3..2f1e8f84 100644 --- a/package.json +++ b/package.json @@ -48,7 +48,7 @@ "require-dir": "~0.3.0", "streamqueue": "^1.1.1", "uglify-save-license": "^0.4.1", - "yargs": "^7.0.2" + "yargs": "^16.0.0" }, "scripts": { "postinstall": "node_modules/.bin/bower install --allow-root --config.interactive=false", From e62e07c9291328462c74dbb31fb1630c43809ffd Mon Sep 17 00:00:00 2001 From: sayali Date: Tue, 8 Dec 2020 20:02:57 -0800 Subject: [PATCH 137/314] remove gulp-replace-task --- package.json | 1 - 1 file changed, 1 deletion(-) diff --git a/package.json b/package.json index 2f1e8f84..f2d87ab7 100644 --- a/package.json +++ b/package.json @@ -31,7 +31,6 @@ "gulp-print": "^2.0.1", "gulp-protractor": "^4.1.1", "gulp-replace": "~0.5.3", - "gulp-replace-task": "~0.11.0", "gulp-rev": "^7.1.2", "gulp-rev-replace": "^0.4.3", "gulp-serve": "~1.4.0", From 6e41f74908f944b39e162caea8e690f060803f0c Mon Sep 17 00:00:00 2001 From: sayali Date: Wed, 9 Dec 2020 14:32:06 -0800 Subject: [PATCH 138/314] Remove parallel task fixing issue of CSS not loading, though it works in dev --- gulp/build.js | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/gulp/build.js b/gulp/build.js index 11919d7f..653a1f1c 100644 --- a/gulp/build.js +++ b/gulp/build.js @@ -169,7 +169,7 @@ function injectHtml(isDev) { ).pipe(gulp.dest('.tmp/')); } -gulp.task('dev:inject', gulp.series(gulp.parallel('dev:styles', 'dev:scripts'), function () { +gulp.task('dev:inject', gulp.series(['dev:styles', 'dev:scripts'], function () { return injectHtml(true); })); @@ -184,11 +184,11 @@ gulp.task('build:ngviews', async function () { .pipe(size()); }); -gulp.task('build:inject', gulp.series(gulp.parallel('dev:styles', 'dev:scripts', 'build:ngviews'), function () { +gulp.task('build:inject', gulp.series(['dev:styles', 'dev:scripts', 'build:ngviews'], function () { return injectHtml(false); })); -gulp.task('build:html', gulp.series(gulp.parallel('dev:styles', 'dev:scripts', 'build:ngviews', 'build:inject'), function () { +gulp.task('build:html', gulp.series(['dev:styles', 'dev:scripts', 'build:ngviews', 'build:inject'], function () { var jsFilter = filter(['**/*.js'], {'restore': true}); var cssFilter = filter(['**/*.css'], {'restore': true}); @@ -259,5 +259,5 @@ gulp.task('addUrlContextPath', gulp.series('addUrlContextPath:revreplace', async })); -gulp.task('build', gulp.series(gulp.parallel('build:ngviews', 'build:inject', 'build:images', 'build:fonts', 'build:html', 'build:extras'))); -gulp.task('package', gulp.series(gulp.parallel('addUrlContextPath', 'package:strip'))); +gulp.task('build', gulp.series(['build:ngviews', 'build:inject', 'build:images', 'build:fonts', 'build:html', 'build:extras'])); +gulp.task('package', gulp.series(['addUrlContextPath', 'package:strip'])); From 1547cc3e60024b375ef6eda29557deb77b1426de Mon Sep 17 00:00:00 2001 From: sayali Date: Wed, 9 Dec 2020 19:29:14 -0800 Subject: [PATCH 139/314] Fixing duplicate task execution --- gulp/build.js | 8 ++++---- gulp/server.js | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/gulp/build.js b/gulp/build.js index 653a1f1c..17419ea5 100644 --- a/gulp/build.js +++ b/gulp/build.js @@ -188,7 +188,7 @@ gulp.task('build:inject', gulp.series(['dev:styles', 'dev:scripts', 'build:ngvie return injectHtml(false); })); -gulp.task('build:html', gulp.series(['dev:styles', 'dev:scripts', 'build:ngviews', 'build:inject'], function () { +gulp.task('build:html', gulp.series('build:inject', function () { var jsFilter = filter(['**/*.js'], {'restore': true}); var cssFilter = filter(['**/*.css'], {'restore': true}); @@ -238,8 +238,8 @@ gulp.task('addUrlContextPath:revision', async function(){ }); gulp.task('addUrlContextPath:revreplace', gulp.series('addUrlContextPath:revision', function(){ - // var manifest = gulp.src("lemur/static/dist/rev-manifest.json"); - // var urlContextPathExists = argv.urlContextPath ? true : false; + var manifest = gulp.src("lemur/static/dist/rev-manifest.json"); + var urlContextPathExists = argv.urlContextPath ? true : false; return gulp.src( "lemur/static/dist/index.html") .pipe(gulp.dest('lemur/static/dist')); })); @@ -259,5 +259,5 @@ gulp.task('addUrlContextPath', gulp.series('addUrlContextPath:revreplace', async })); -gulp.task('build', gulp.series(['build:ngviews', 'build:inject', 'build:images', 'build:fonts', 'build:html', 'build:extras'])); +gulp.task('build', gulp.series(['build:images', 'build:fonts', 'build:html', 'build:extras'])); gulp.task('package', gulp.series(['addUrlContextPath', 'package:strip'])); diff --git a/gulp/server.js b/gulp/server.js index 804ca115..ccc29ac2 100644 --- a/gulp/server.js +++ b/gulp/server.js @@ -38,7 +38,7 @@ function browserSyncInit(baseDir, files, browser) { } -gulp.task('watch', gulp.series(['dev:styles', 'dev:scripts', 'dev:inject', 'dev:fonts'], function (done) { +gulp.task('watch', gulp.series(['dev:inject', 'dev:fonts'], function (done) { gulp.watch('app/styles/**/*.less', gulp.parallel('dev:styles')); gulp.watch('app/styles/**/*.css', gulp.parallel('dev:styles')); gulp.watch('app/**/*.js', gulp.parallel('dev:scripts')); From 785ef6adb58bdd8c051436ba67615740c1ccdb1d Mon Sep 17 00:00:00 2001 From: sayali Date: Wed, 9 Dec 2020 19:45:36 -0800 Subject: [PATCH 140/314] Uncommented rev-manifest: allowEmpty --- gulp/build.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gulp/build.js b/gulp/build.js index 17419ea5..c864037a 100644 --- a/gulp/build.js +++ b/gulp/build.js @@ -238,7 +238,7 @@ gulp.task('addUrlContextPath:revision', async function(){ }); gulp.task('addUrlContextPath:revreplace', gulp.series('addUrlContextPath:revision', function(){ - var manifest = gulp.src("lemur/static/dist/rev-manifest.json"); + var manifest = gulp.src("lemur/static/dist/rev-manifest.json", { allowEmpty: true }); var urlContextPathExists = argv.urlContextPath ? true : false; return gulp.src( "lemur/static/dist/index.html") .pipe(gulp.dest('lemur/static/dist')); From 42dd8e3f47b249e3a7873fbde74f360fc8688713 Mon Sep 17 00:00:00 2001 From: sayali Date: Wed, 9 Dec 2020 20:03:57 -0800 Subject: [PATCH 141/314] Revert "Uncommented rev-manifest: allowEmpty" This reverts commit 785ef6adb58bdd8c051436ba67615740c1ccdb1d. --- gulp/build.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gulp/build.js b/gulp/build.js index c864037a..17419ea5 100644 --- a/gulp/build.js +++ b/gulp/build.js @@ -238,7 +238,7 @@ gulp.task('addUrlContextPath:revision', async function(){ }); gulp.task('addUrlContextPath:revreplace', gulp.series('addUrlContextPath:revision', function(){ - var manifest = gulp.src("lemur/static/dist/rev-manifest.json", { allowEmpty: true }); + var manifest = gulp.src("lemur/static/dist/rev-manifest.json"); var urlContextPathExists = argv.urlContextPath ? true : false; return gulp.src( "lemur/static/dist/index.html") .pipe(gulp.dest('lemur/static/dist')); From 575642fa49b98d001828c10d0dee7ada3cca2d84 Mon Sep 17 00:00:00 2001 From: sayali Date: Wed, 9 Dec 2020 20:04:11 -0800 Subject: [PATCH 142/314] Revert "Fixing duplicate task execution" This reverts commit 1547cc3e60024b375ef6eda29557deb77b1426de. --- gulp/build.js | 8 ++++---- gulp/server.js | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/gulp/build.js b/gulp/build.js index 17419ea5..653a1f1c 100644 --- a/gulp/build.js +++ b/gulp/build.js @@ -188,7 +188,7 @@ gulp.task('build:inject', gulp.series(['dev:styles', 'dev:scripts', 'build:ngvie return injectHtml(false); })); -gulp.task('build:html', gulp.series('build:inject', function () { +gulp.task('build:html', gulp.series(['dev:styles', 'dev:scripts', 'build:ngviews', 'build:inject'], function () { var jsFilter = filter(['**/*.js'], {'restore': true}); var cssFilter = filter(['**/*.css'], {'restore': true}); @@ -238,8 +238,8 @@ gulp.task('addUrlContextPath:revision', async function(){ }); gulp.task('addUrlContextPath:revreplace', gulp.series('addUrlContextPath:revision', function(){ - var manifest = gulp.src("lemur/static/dist/rev-manifest.json"); - var urlContextPathExists = argv.urlContextPath ? true : false; + // var manifest = gulp.src("lemur/static/dist/rev-manifest.json"); + // var urlContextPathExists = argv.urlContextPath ? true : false; return gulp.src( "lemur/static/dist/index.html") .pipe(gulp.dest('lemur/static/dist')); })); @@ -259,5 +259,5 @@ gulp.task('addUrlContextPath', gulp.series('addUrlContextPath:revreplace', async })); -gulp.task('build', gulp.series(['build:images', 'build:fonts', 'build:html', 'build:extras'])); +gulp.task('build', gulp.series(['build:ngviews', 'build:inject', 'build:images', 'build:fonts', 'build:html', 'build:extras'])); gulp.task('package', gulp.series(['addUrlContextPath', 'package:strip'])); diff --git a/gulp/server.js b/gulp/server.js index ccc29ac2..804ca115 100644 --- a/gulp/server.js +++ b/gulp/server.js @@ -38,7 +38,7 @@ function browserSyncInit(baseDir, files, browser) { } -gulp.task('watch', gulp.series(['dev:inject', 'dev:fonts'], function (done) { +gulp.task('watch', gulp.series(['dev:styles', 'dev:scripts', 'dev:inject', 'dev:fonts'], function (done) { gulp.watch('app/styles/**/*.less', gulp.parallel('dev:styles')); gulp.watch('app/styles/**/*.css', gulp.parallel('dev:styles')); gulp.watch('app/**/*.js', gulp.parallel('dev:scripts')); From 34588c9513fd9a564af2e134c4e085eb21118286 Mon Sep 17 00:00:00 2001 From: sayali Date: Wed, 9 Dec 2020 20:07:07 -0800 Subject: [PATCH 143/314] Revert "Remove parallel task" This reverts commit 6e41f74908f944b39e162caea8e690f060803f0c. --- gulp/build.js | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/gulp/build.js b/gulp/build.js index 653a1f1c..11919d7f 100644 --- a/gulp/build.js +++ b/gulp/build.js @@ -169,7 +169,7 @@ function injectHtml(isDev) { ).pipe(gulp.dest('.tmp/')); } -gulp.task('dev:inject', gulp.series(['dev:styles', 'dev:scripts'], function () { +gulp.task('dev:inject', gulp.series(gulp.parallel('dev:styles', 'dev:scripts'), function () { return injectHtml(true); })); @@ -184,11 +184,11 @@ gulp.task('build:ngviews', async function () { .pipe(size()); }); -gulp.task('build:inject', gulp.series(['dev:styles', 'dev:scripts', 'build:ngviews'], function () { +gulp.task('build:inject', gulp.series(gulp.parallel('dev:styles', 'dev:scripts', 'build:ngviews'), function () { return injectHtml(false); })); -gulp.task('build:html', gulp.series(['dev:styles', 'dev:scripts', 'build:ngviews', 'build:inject'], function () { +gulp.task('build:html', gulp.series(gulp.parallel('dev:styles', 'dev:scripts', 'build:ngviews', 'build:inject'), function () { var jsFilter = filter(['**/*.js'], {'restore': true}); var cssFilter = filter(['**/*.css'], {'restore': true}); @@ -259,5 +259,5 @@ gulp.task('addUrlContextPath', gulp.series('addUrlContextPath:revreplace', async })); -gulp.task('build', gulp.series(['build:ngviews', 'build:inject', 'build:images', 'build:fonts', 'build:html', 'build:extras'])); -gulp.task('package', gulp.series(['addUrlContextPath', 'package:strip'])); +gulp.task('build', gulp.series(gulp.parallel('build:ngviews', 'build:inject', 'build:images', 'build:fonts', 'build:html', 'build:extras'))); +gulp.task('package', gulp.series(gulp.parallel('addUrlContextPath', 'package:strip'))); From 892a668bf59ca68e07b6ae3650c896369ec10f89 Mon Sep 17 00:00:00 2001 From: sayali Date: Wed, 9 Dec 2020 20:07:25 -0800 Subject: [PATCH 144/314] Revert "Upgrade gulp to 4.0.2" This reverts commit 22d9ef77988f45db24a1059274ec28306723b8b5. --- gulp/build.js | 93 +++++++++++++++++++++++++------------------------- gulp/server.js | 17 +++------ gulp/watch.js | 12 +++++++ package.json | 2 +- 4 files changed, 64 insertions(+), 60 deletions(-) create mode 100644 gulp/watch.js diff --git a/gulp/build.js b/gulp/build.js index 11919d7f..5aca8094 100644 --- a/gulp/build.js +++ b/gulp/build.js @@ -29,24 +29,24 @@ var gulp = require('gulp'), replace = require('gulp-replace'), argv = require('yargs').argv; -gulp.task('clean', async function (cb) { +gulp.task('default', ['clean'], function () { + gulp.start('fonts', 'styles'); +}); + +gulp.task('clean', function (cb) { del(['.tmp', 'lemur/static/dist'], cb); }); -gulp.task('default', gulp.series('clean', function () { - gulp.start('fonts', 'styles'); -})); - -gulp.task('test', gulp.series(function (done) { +gulp.task('test', function (done) { new karma.Server({ configFile: __dirname + '/karma.conf.js', singleRun: true }, function() { done(); }).start(); -})); +}); -gulp.task('dev:fonts', async function () { +gulp.task('dev:fonts', function () { var fileList = [ 'bower_components/bootstrap/dist/fonts/*', 'bower_components/fontawesome/fonts/*' @@ -56,7 +56,7 @@ gulp.task('dev:fonts', async function () { .pipe(gulp.dest('.tmp/fonts')); }); -gulp.task('dev:styles', async function () { +gulp.task('dev:styles', function () { var baseContent = '@import "bower_components/bootstrap/less/bootstrap.less";@import "bower_components/bootswatch/$theme$/variables.less";@import "bower_components/bootswatch/$theme$/bootswatch.less";@import "bower_components/bootstrap/less/utilities.less";'; var isBootswatchFile = function (file) { @@ -74,6 +74,7 @@ gulp.task('dev:styles', async function () { var fileList = [ 'bower_components/bootswatch/sandstone/bootswatch.less', 'bower_components/fontawesome/css/font-awesome.css', + 'bower_components/angular-spinkit/src/angular-spinkit.css', 'bower_components/angular-chart.js/dist/angular-chart.css', 'bower_components/angular-loading-bar/src/loading-bar.css', 'bower_components/angular-ui-switch/angular-ui-switch.css', @@ -99,7 +100,7 @@ gulp.task('dev:styles', async function () { // http://stackoverflow.com/questions/21719833/gulp-how-to-add-src-files-in-the-middle-of-a-pipe // https://github.com/gulpjs/gulp/blob/master/docs/recipes/using-multiple-sources-in-one-task.md - return merge(stream, gulp.src(['.tmp/styles/font-awesome.css', '.tmp/styles/lemur.css'], { allowEmpty: true })) + return merge(stream, gulp.src(['.tmp/styles/font-awesome.css', '.tmp/styles/lemur.css'])) .pipe(concat('style-' + themeName + '.css')); }))) .pipe(plumber()) @@ -128,14 +129,14 @@ function string_src(filename, string) { return src; } -gulp.task('dev:scripts', async function () { +gulp.task('dev:scripts', function () { return gulp.src(['lemur/static/app/angular/**/*.js']) .pipe(jshint()) .pipe(jshint.reporter('jshint-stylish')) .pipe(size()); }); -gulp.task('build:extras', async function () { +gulp.task('build:extras', function () { return gulp.src(['lemur/static/app/*.*', '!lemur/static/app/*.html']) .pipe(gulp.dest('lemur/static/dist')); }); @@ -161,7 +162,7 @@ function injectHtml(isDev) { })) .pipe( gulpif(!isDev, - inject(gulp.src('lemur/static/dist/ngviews/ngviews.min.js', { allowEmpty: true }), { + inject(gulp.src('lemur/static/dist/ngviews/ngviews.min.js'), { starttag: '', addRootSlash: false }) @@ -169,11 +170,15 @@ function injectHtml(isDev) { ).pipe(gulp.dest('.tmp/')); } -gulp.task('dev:inject', gulp.series(gulp.parallel('dev:styles', 'dev:scripts'), function () { +gulp.task('dev:inject', ['dev:styles', 'dev:scripts'], function () { return injectHtml(true); -})); +}); -gulp.task('build:ngviews', async function () { +gulp.task('build:inject', ['dev:styles', 'dev:scripts', 'build:ngviews'], function () { + return injectHtml(false); +}); + +gulp.task('build:ngviews', function () { return gulp.src(['lemur/static/app/angular/**/*.html']) .pipe(minifyHtml({ empty: true, @@ -184,11 +189,7 @@ gulp.task('build:ngviews', async function () { .pipe(size()); }); -gulp.task('build:inject', gulp.series(gulp.parallel('dev:styles', 'dev:scripts', 'build:ngviews'), function () { - return injectHtml(false); -})); - -gulp.task('build:html', gulp.series(gulp.parallel('dev:styles', 'dev:scripts', 'build:ngviews', 'build:inject'), function () { +gulp.task('build:html', ['dev:styles', 'dev:scripts', 'build:ngviews', 'build:inject'], function () { var jsFilter = filter(['**/*.js'], {'restore': true}); var cssFilter = filter(['**/*.css'], {'restore': true}); @@ -202,14 +203,14 @@ gulp.task('build:html', gulp.series(gulp.parallel('dev:styles', 'dev:scripts', ' .pipe(useref()) .pipe(gulp.dest('lemur/static/dist')) .pipe(size()); -})); +}); -gulp.task('build:fonts', gulp.series('dev:fonts', function () { +gulp.task('build:fonts', ['dev:fonts'], function () { return gulp.src('.tmp/fonts/**/*') .pipe(gulp.dest('lemur/static/dist/fonts')); -})); +}); -gulp.task('build:images', async function () { +gulp.task('build:images', function () { return gulp.src('lemur/static/app/images/**/*') .pipe(cache(imagemin({ optimizationLevel: 3, @@ -220,8 +221,8 @@ gulp.task('build:images', async function () { .pipe(size()); }); -gulp.task('package:strip', async function () { - return gulp.src('lemur/static/dist/scripts/main*') +gulp.task('package:strip', function () { + return gulp.src(['lemur/static/dist/scripts/main*']) .pipe(replace('http:\/\/localhost:3000', '')) .pipe(replace('http:\/\/localhost:8000', '')) .pipe(useref()) @@ -229,22 +230,7 @@ gulp.task('package:strip', async function () { .pipe(size()); }); -gulp.task('addUrlContextPath:revision', async function(){ - return gulp.src(['lemur/static/dist/**/*.css','lemur/static/dist/**/*.js']) - .pipe(rev()) - .pipe(gulp.dest('lemur/static/dist')) - .pipe(rev.manifest()) - .pipe(gulp.dest('lemur/static/dist')) -}); - -gulp.task('addUrlContextPath:revreplace', gulp.series('addUrlContextPath:revision', function(){ - // var manifest = gulp.src("lemur/static/dist/rev-manifest.json"); - // var urlContextPathExists = argv.urlContextPath ? true : false; - return gulp.src( "lemur/static/dist/index.html") - .pipe(gulp.dest('lemur/static/dist')); -})); - -gulp.task('addUrlContextPath', gulp.series('addUrlContextPath:revreplace', async function(){ +gulp.task('addUrlContextPath',['addUrlContextPath:revreplace'], function(){ var urlContextPathExists = argv.urlContextPath ? true : false; ['lemur/static/dist/scripts/main*.js', 'lemur/static/dist/angular/**/*.html'] @@ -256,8 +242,23 @@ gulp.task('addUrlContextPath', gulp.series('addUrlContextPath:revreplace', async return file.base; })) }) -})); +}); + +gulp.task('addUrlContextPath:revision', function(){ + return gulp.src(['lemur/static/dist/**/*.css','lemur/static/dist/**/*.js']) + .pipe(rev()) + .pipe(gulp.dest('lemur/static/dist')) + .pipe(rev.manifest()) + .pipe(gulp.dest('lemur/static/dist')) +}) + +gulp.task('addUrlContextPath:revreplace', ['addUrlContextPath:revision'], function(){ + var manifest = gulp.src("lemur/static/dist/rev-manifest.json"); + var urlContextPathExists = argv.urlContextPath ? true : false; + return gulp.src( "lemur/static/dist/index.html") + .pipe(gulp.dest('lemur/static/dist')); +}) -gulp.task('build', gulp.series(gulp.parallel('build:ngviews', 'build:inject', 'build:images', 'build:fonts', 'build:html', 'build:extras'))); -gulp.task('package', gulp.series(gulp.parallel('addUrlContextPath', 'package:strip'))); +gulp.task('build', ['build:ngviews', 'build:inject', 'build:images', 'build:fonts', 'build:html', 'build:extras']); +gulp.task('package', ['addUrlContextPath', 'package:strip']); diff --git a/gulp/server.js b/gulp/server.js index 804ca115..6c61273e 100644 --- a/gulp/server.js +++ b/gulp/server.js @@ -38,16 +38,7 @@ function browserSyncInit(baseDir, files, browser) { } -gulp.task('watch', gulp.series(['dev:styles', 'dev:scripts', 'dev:inject', 'dev:fonts'], function (done) { - gulp.watch('app/styles/**/*.less', gulp.parallel('dev:styles')); - gulp.watch('app/styles/**/*.css', gulp.parallel('dev:styles')); - gulp.watch('app/**/*.js', gulp.parallel('dev:scripts')); - gulp.watch('app/images/**/*', gulp.parallel('build:images')); - gulp.watch('bower.json', gulp.parallel('dev:inject')); - done(); -})); - -gulp.task('serve', gulp.series('watch', function () { +gulp.task('serve', ['watch'], function () { browserSyncInit([ '.tmp', 'lemur/static/app' @@ -60,9 +51,9 @@ gulp.task('serve', gulp.series('watch', function () { 'lemur/static/app/angular/**/*', 'lemur/static/app/index.html' ]); -})); +}); -gulp.task('serve:dist', gulp.series('build', function () { +gulp.task('serve:dist', ['build'], function () { browserSyncInit('lemur/static/dist'); -})); +}); diff --git a/gulp/watch.js b/gulp/watch.js new file mode 100644 index 00000000..460a935b --- /dev/null +++ b/gulp/watch.js @@ -0,0 +1,12 @@ +'use strict'; + +var gulp = require('gulp'); + + +gulp.task('watch', ['dev:styles', 'dev:scripts', 'dev:inject', 'dev:fonts'] ,function () { + gulp.watch('app/styles/**/*.less', ['dev:styles']); + gulp.watch('app/styles/**/*.css', ['dev:styles']); + gulp.watch('app/**/*.js', ['dev:scripts']); + gulp.watch('app/images/**/*', ['build:images']); + gulp.watch('bower.json', ['dev:inject']); +}); diff --git a/package.json b/package.json index f2d87ab7..828f8899 100644 --- a/package.json +++ b/package.json @@ -58,7 +58,7 @@ "test": "gulp test" }, "devDependencies": { - "gulp": "^4.0.2", + "gulp": "^3.9.1", "jshint": "^2.11.0", "karma-chrome-launcher": "^2.0.0" } From 4ac432ce8782db055cdd7ae57623645a4de1faf5 Mon Sep 17 00:00:00 2001 From: csine-nflx Date: Sun, 13 Dec 2020 00:03:21 -0800 Subject: [PATCH 145/314] Creating variable to store cname_delegation state and creating cname delegation metric --- lemur/plugins/lemur_acme/acme_handlers.py | 17 ++++++++++------- .../lemur_acme/tests/test_acme_handler.py | 2 +- 2 files changed, 11 insertions(+), 8 deletions(-) diff --git a/lemur/plugins/lemur_acme/acme_handlers.py b/lemur/plugins/lemur_acme/acme_handlers.py index 83dfb1ba..78c160b2 100644 --- a/lemur/plugins/lemur_acme/acme_handlers.py +++ b/lemur/plugins/lemur_acme/acme_handlers.py @@ -36,12 +36,13 @@ from retrying import retry class AuthorizationRecord(object): - def __init__(self, domain, target_domain, authz, dns_challenge, change_id): + def __init__(self, domain, target_domain, authz, dns_challenge, change_id, cname_delegation): self.domain = domain self.target_domain = target_domain self.authz = authz self.dns_challenge = dns_challenge self.change_id = change_id + self.cname_delegation = cname_delegation class AcmeHandler(object): @@ -305,6 +306,7 @@ class AcmeDnsHandler(AcmeHandler): current_app.logger.debug(f"Starting DNS challenge for {domain} using target domain {target_domain}.") change_ids = [] + cname_delegation = domain != target_domain dns_challenges = self.get_dns_challenges(domain, order.authorizations) host_to_validate, _ = self.strip_wildcard(target_domain) host_to_validate = self.maybe_add_extension(host_to_validate, dns_provider_options) @@ -315,9 +317,7 @@ class AcmeDnsHandler(AcmeHandler): raise Exception("Unable to determine DNS challenges from authorizations") for dns_challenge in dns_challenges: - - # Only prepend '_acme-challenge' if not using CNAME redirection - if domain == target_domain: + if not cname_delegation: host_to_validate = dns_challenge.validation_domain_name(host_to_validate) change_id = dns_provider.create_txt_record( @@ -328,7 +328,7 @@ class AcmeDnsHandler(AcmeHandler): change_ids.append(change_id) return AuthorizationRecord( - domain, target_domain, order.authorizations, dns_challenges, change_ids + domain, target_domain, order.authorizations, dns_challenges, change_ids, cname_delegation ) def complete_dns_challenge(self, acme_client, authz_record): @@ -395,6 +395,9 @@ class AcmeDnsHandler(AcmeHandler): if cname_result: target_domain = cname_result self.autodetect_dns_providers(target_domain) + metrics.send( + "get_authorizations_cname_delegation_for_domain", "counter", 1, metric_tags={"domain": domain} + ) if not self.dns_providers_for_domain.get(target_domain): metrics.send( @@ -455,7 +458,7 @@ class AcmeDnsHandler(AcmeHandler): account_number = dns_provider_options.get("account_id") host_to_validate, _ = self.strip_wildcard(authz_record.target_domain) host_to_validate = self.maybe_add_extension(host_to_validate, dns_provider_options) - if authz_record.domain == authz_record.target_domain: + if not authz_record.cname_delegation: host_to_validate = challenges.DNS01().validation_domain_name(host_to_validate) dns_provider_plugin.delete_txt_record( authz_record.change_id, @@ -492,7 +495,7 @@ class AcmeDnsHandler(AcmeHandler): dns_provider_plugin = self.get_dns_provider(dns_provider.provider_type) for dns_challenge in dns_challenges: - if authz_record.domain == authz_record.target_domain: + if not authz_record.cname_delegation: host_to_validate = dns_challenge.validation_domain_name(host_to_validate) try: dns_provider_plugin.delete_txt_record( diff --git a/lemur/plugins/lemur_acme/tests/test_acme_handler.py b/lemur/plugins/lemur_acme/tests/test_acme_handler.py index cfc18c83..324af5ac 100644 --- a/lemur/plugins/lemur_acme/tests/test_acme_handler.py +++ b/lemur/plugins/lemur_acme/tests/test_acme_handler.py @@ -30,7 +30,7 @@ class TestAcmeHandler(unittest.TestCase): self.assertEqual(expected, result) def test_authz_record(self): - a = acme_handlers.AuthorizationRecord("domain", "host", "authz", "challenge", "id") + a = acme_handlers.AuthorizationRecord("domain", "host", "authz", "challenge", "id", "cname_delegation") self.assertEqual(type(a), acme_handlers.AuthorizationRecord) def test_setup_acme_client_fail(self): From 58f40a7b86a37bcb333f3dae1c994591e57220d4 Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Mon, 14 Dec 2020 17:11:30 +0000 Subject: [PATCH 146/314] Bump pre-commit from 2.9.2 to 2.9.3 Bumps [pre-commit](https://github.com/pre-commit/pre-commit) from 2.9.2 to 2.9.3. - [Release notes](https://github.com/pre-commit/pre-commit/releases) - [Changelog](https://github.com/pre-commit/pre-commit/blob/master/CHANGELOG.md) - [Commits](https://github.com/pre-commit/pre-commit/compare/v2.9.2...v2.9.3) Signed-off-by: dependabot-preview[bot] --- requirements-dev.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements-dev.txt b/requirements-dev.txt index defb70b1..f3bffd82 100644 --- a/requirements-dev.txt +++ b/requirements-dev.txt @@ -24,7 +24,7 @@ keyring==21.2.0 # via twine mccabe==0.6.1 # via flake8 nodeenv==1.5.0 # via -r requirements-dev.in, pre-commit pkginfo==1.5.0.1 # via twine -pre-commit==2.9.2 # via -r requirements-dev.in +pre-commit==2.9.3 # via -r requirements-dev.in pycodestyle==2.6.0 # via flake8 pycparser==2.20 # via cffi pyflakes==2.2.0 # via flake8 From 1165ab5eb7919a003808195b025603ba53ce2eab Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Mon, 14 Dec 2020 17:22:03 +0000 Subject: [PATCH 147/314] Bump bandit from 1.6.3 to 1.7.0 Bumps [bandit](https://github.com/PyCQA/bandit) from 1.6.3 to 1.7.0. - [Release notes](https://github.com/PyCQA/bandit/releases) - [Commits](https://github.com/PyCQA/bandit/compare/1.6.3...1.7.0) Signed-off-by: dependabot-preview[bot] --- requirements-tests.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements-tests.txt b/requirements-tests.txt index 336e31a4..a49972e6 100644 --- a/requirements-tests.txt +++ b/requirements-tests.txt @@ -8,7 +8,7 @@ appdirs==1.4.3 # via black attrs==19.3.0 # via jsonschema, pytest aws-sam-translator==1.22.0 # via cfn-lint aws-xray-sdk==2.5.0 # via moto -bandit==1.6.3 # via -r requirements-tests.in +bandit==1.7.0 # via -r requirements-tests.in black==20.8b1 # via -r requirements-tests.in boto3==1.16.30 # via aws-sam-translator, moto boto==2.49.0 # via moto From bfbb2372c29e837990ef6bd2355fa879047e0131 Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Mon, 14 Dec 2020 17:32:30 +0000 Subject: [PATCH 148/314] Bump faker from 5.0.0 to 5.0.1 Bumps [faker](https://github.com/joke2k/faker) from 5.0.0 to 5.0.1. - [Release notes](https://github.com/joke2k/faker/releases) - [Changelog](https://github.com/joke2k/faker/blob/master/CHANGELOG.md) - [Commits](https://github.com/joke2k/faker/compare/v5.0.0...v5.0.1) Signed-off-by: dependabot-preview[bot] --- requirements-tests.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements-tests.txt b/requirements-tests.txt index a49972e6..383fd694 100644 --- a/requirements-tests.txt +++ b/requirements-tests.txt @@ -24,7 +24,7 @@ decorator==4.4.2 # via networkx docker==4.2.0 # via moto ecdsa==0.14.1 # via moto, python-jose, sshpubkeys factory-boy==3.1.0 # via -r requirements-tests.in -faker==5.0.0 # via -r requirements-tests.in, factory-boy +faker==5.0.1 # via -r requirements-tests.in, factory-boy fakeredis==1.4.5 # via -r requirements-tests.in flask==1.1.2 # via pytest-flask freezegun==1.0.0 # via -r requirements-tests.in From 5f8a1b480e04c0976708157082f6b8a3e5bc3b0d Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Mon, 14 Dec 2020 17:44:02 +0000 Subject: [PATCH 149/314] Bump celery[redis] from 4.4.2 to 5.0.4 Bumps [celery[redis]](https://github.com/celery/celery) from 4.4.2 to 5.0.4. - [Release notes](https://github.com/celery/celery/releases) - [Changelog](https://github.com/celery/celery/blob/master/Changelog.rst) - [Commits](https://github.com/celery/celery/compare/4.4.2...v5.0.4) Signed-off-by: dependabot-preview[bot] --- requirements.txt | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/requirements.txt b/requirements.txt index 1fbea8ae..e876fb95 100644 --- a/requirements.txt +++ b/requirements.txt @@ -7,7 +7,7 @@ acme==1.10.1 # via -r requirements.in alembic-autogenerate-enums==0.0.2 # via -r requirements.in alembic==1.4.2 # via flask-migrate -amqp==2.5.2 # via kombu +amqp==5.0.2 # via kombu aniso8601==8.0.0 # via flask-restful arrow==0.17.0 # via -r requirements.in asyncpool==1.0 # via -r requirements.in @@ -17,12 +17,15 @@ billiard==3.6.3.0 # via celery blinker==1.4 # via flask-mail, flask-principal, raven boto3==1.16.30 # via -r requirements.in botocore==1.19.30 # via -r requirements.in, boto3, s3transfer -celery[redis]==4.4.2 # via -r requirements.in +celery[redis]==5.0.4 # via -r requirements.in certifi==2020.12.5 # via -r requirements.in, requests certsrv==2.1.1 # via -r requirements.in cffi==1.14.0 # via bcrypt, cryptography, pynacl chardet==3.0.4 # via requests -click==7.1.2 # via flask +click-didyoumean==0.0.3 # via celery +click-plugins==1.1.1 # via celery +click-repl==0.1.6 # via celery +click==7.1.2 # via celery, click-didyoumean, click-plugins, click-repl, flask cloudflare==2.8.14 # via -r requirements.in cryptography==3.2.1 # via -r requirements.in, acme, josepy, paramiko, pyopenssl, requests dnspython3==1.15.0 # via -r requirements.in @@ -49,7 +52,7 @@ jinja2==2.11.2 # via -r requirements.in, flask jmespath==0.9.5 # via boto3, botocore josepy==1.3.0 # via acme jsonlines==1.2.0 # via cloudflare -kombu==4.6.8 # via celery +kombu==5.0.2 # via celery lockfile==0.12.2 # via -r requirements.in logmatic-python==0.1.7 # via -r requirements.in mako==1.1.2 # via alembic @@ -59,6 +62,7 @@ marshmallow==2.20.4 # via -r requirements.in, marshmallow-sqlalchemy ndg-httpsclient==0.5.1 # via -r requirements.in paramiko==2.7.2 # via -r requirements.in pem==20.1.0 # via -r requirements.in +prompt-toolkit==3.0.8 # via click-repl psycopg2==2.8.6 # via -r requirements.in pyasn1-modules==0.2.8 # via pyjks, python-ldap pyasn1==0.4.8 # via ndg-httpsclient, pyasn1-modules, pyjks, python-ldap @@ -81,14 +85,15 @@ requests-toolbelt==0.9.1 # via acme requests[security]==2.25.0 # via -r requirements.in, acme, certsrv, cloudflare, hvac, requests-toolbelt retrying==1.3.3 # via -r requirements.in s3transfer==0.3.3 # via boto3 -six==1.15.0 # via -r requirements.in, acme, bcrypt, cryptography, flask-cors, flask-restful, hvac, josepy, jsonlines, pynacl, pyopenssl, python-dateutil, retrying, sqlalchemy-utils +six==1.15.0 # via -r requirements.in, acme, bcrypt, click-repl, cryptography, flask-cors, flask-restful, hvac, josepy, jsonlines, pynacl, pyopenssl, python-dateutil, retrying, sqlalchemy-utils soupsieve==2.0.1 # via beautifulsoup4 sqlalchemy-utils==0.36.8 # via -r requirements.in sqlalchemy==1.3.16 # via alembic, flask-sqlalchemy, marshmallow-sqlalchemy, sqlalchemy-utils tabulate==0.8.7 # via -r requirements.in twofish==0.3.0 # via pyjks urllib3==1.25.8 # via botocore, requests -vine==1.3.0 # via amqp, celery +vine==5.0.0 # via amqp, celery +wcwidth==0.2.5 # via prompt-toolkit werkzeug==1.0.1 # via flask xmltodict==0.12.0 # via -r requirements.in From aaba3aab7ad73af80b1a31476e79b44df81b9f89 Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Mon, 14 Dec 2020 17:56:00 +0000 Subject: [PATCH 150/314] Bump botocore from 1.19.30 to 1.19.35 Bumps [botocore](https://github.com/boto/botocore) from 1.19.30 to 1.19.35. - [Release notes](https://github.com/boto/botocore/releases) - [Changelog](https://github.com/boto/botocore/blob/develop/CHANGELOG.rst) - [Commits](https://github.com/boto/botocore/compare/1.19.30...1.19.35) Signed-off-by: dependabot-preview[bot] --- requirements-tests.txt | 2 +- requirements.txt | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/requirements-tests.txt b/requirements-tests.txt index 383fd694..e2bc0c06 100644 --- a/requirements-tests.txt +++ b/requirements-tests.txt @@ -12,7 +12,7 @@ bandit==1.7.0 # via -r requirements-tests.in black==20.8b1 # via -r requirements-tests.in boto3==1.16.30 # via aws-sam-translator, moto boto==2.49.0 # via moto -botocore==1.19.30 # via aws-xray-sdk, boto3, moto, s3transfer +botocore==1.19.35 # via aws-xray-sdk, boto3, moto, s3transfer certifi==2020.12.5 # via requests cffi==1.14.0 # via cryptography cfn-lint==0.29.5 # via moto diff --git a/requirements.txt b/requirements.txt index e876fb95..d5fce120 100644 --- a/requirements.txt +++ b/requirements.txt @@ -16,7 +16,7 @@ beautifulsoup4==4.9.1 # via cloudflare billiard==3.6.3.0 # via celery blinker==1.4 # via flask-mail, flask-principal, raven boto3==1.16.30 # via -r requirements.in -botocore==1.19.30 # via -r requirements.in, boto3, s3transfer +botocore==1.19.35 # via -r requirements.in, boto3, s3transfer celery[redis]==5.0.4 # via -r requirements.in certifi==2020.12.5 # via -r requirements.in, requests certsrv==2.1.1 # via -r requirements.in From ad5a773712f9c164bc489dea18ffa94f0a8a48ef Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Mon, 14 Dec 2020 18:07:24 +0000 Subject: [PATCH 151/314] Bump cryptography from 3.2.1 to 3.3.1 Bumps [cryptography](https://github.com/pyca/cryptography) from 3.2.1 to 3.3.1. - [Release notes](https://github.com/pyca/cryptography/releases) - [Changelog](https://github.com/pyca/cryptography/blob/master/CHANGELOG.rst) - [Commits](https://github.com/pyca/cryptography/compare/3.2.1...3.3.1) Signed-off-by: dependabot-preview[bot] --- requirements-dev.txt | 2 +- requirements-tests.txt | 2 +- requirements.txt | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/requirements-dev.txt b/requirements-dev.txt index f3bffd82..50c5d08b 100644 --- a/requirements-dev.txt +++ b/requirements-dev.txt @@ -11,7 +11,7 @@ cffi==1.14.0 # via cryptography cfgv==3.1.0 # via pre-commit chardet==3.0.4 # via requests colorama==0.4.3 # via twine -cryptography==3.2.1 # via secretstorage +cryptography==3.3.1 # via secretstorage distlib==0.3.0 # via virtualenv docutils==0.16 # via readme-renderer filelock==3.0.12 # via virtualenv diff --git a/requirements-tests.txt b/requirements-tests.txt index e2bc0c06..31690ed9 100644 --- a/requirements-tests.txt +++ b/requirements-tests.txt @@ -19,7 +19,7 @@ cfn-lint==0.29.5 # via moto chardet==3.0.4 # via requests click==7.1.2 # via black, flask coverage==5.3 # via -r requirements-tests.in -cryptography==3.2.1 # via moto, python-jose, sshpubkeys +cryptography==3.3.1 # via moto, python-jose, sshpubkeys decorator==4.4.2 # via networkx docker==4.2.0 # via moto ecdsa==0.14.1 # via moto, python-jose, sshpubkeys diff --git a/requirements.txt b/requirements.txt index d5fce120..6e96db66 100644 --- a/requirements.txt +++ b/requirements.txt @@ -27,7 +27,7 @@ click-plugins==1.1.1 # via celery click-repl==0.1.6 # via celery click==7.1.2 # via celery, click-didyoumean, click-plugins, click-repl, flask cloudflare==2.8.14 # via -r requirements.in -cryptography==3.2.1 # via -r requirements.in, acme, josepy, paramiko, pyopenssl, requests +cryptography==3.3.1 # via -r requirements.in, acme, josepy, paramiko, pyopenssl, requests dnspython3==1.15.0 # via -r requirements.in dnspython==1.15.0 # via dnspython3 dyn==1.8.1 # via -r requirements.in From b89dc7dc6c187f2417d30c4d289ec5fe74436bfc Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Mon, 14 Dec 2020 18:17:57 +0000 Subject: [PATCH 152/314] Bump pytest from 6.1.2 to 6.2.0 Bumps [pytest](https://github.com/pytest-dev/pytest) from 6.1.2 to 6.2.0. - [Release notes](https://github.com/pytest-dev/pytest/releases) - [Changelog](https://github.com/pytest-dev/pytest/blob/master/CHANGELOG.rst) - [Commits](https://github.com/pytest-dev/pytest/compare/6.1.2...6.2.0) Signed-off-by: dependabot-preview[bot] --- requirements-tests.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements-tests.txt b/requirements-tests.txt index 31690ed9..1d2ca5d0 100644 --- a/requirements-tests.txt +++ b/requirements-tests.txt @@ -61,7 +61,7 @@ pyparsing==2.4.7 # via packaging pyrsistent==0.16.0 # via jsonschema pytest-flask==1.1.0 # via -r requirements-tests.in pytest-mock==3.3.1 # via -r requirements-tests.in -pytest==6.1.2 # via -r requirements-tests.in, pytest-flask, pytest-mock +pytest==6.2.0 # via -r requirements-tests.in, pytest-flask, pytest-mock python-dateutil==2.8.1 # via botocore, faker, freezegun, moto python-jose[cryptography]==3.1.0 # via moto pytz==2019.3 # via moto From 8ac304039695df5cf64e8855b530a49239b2749f Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Mon, 14 Dec 2020 18:28:11 +0000 Subject: [PATCH 153/314] Bump boto3 from 1.16.30 to 1.16.35 Bumps [boto3](https://github.com/boto/boto3) from 1.16.30 to 1.16.35. - [Release notes](https://github.com/boto/boto3/releases) - [Changelog](https://github.com/boto/boto3/blob/develop/CHANGELOG.rst) - [Commits](https://github.com/boto/boto3/compare/1.16.30...1.16.35) Signed-off-by: dependabot-preview[bot] --- requirements-tests.txt | 2 +- requirements.txt | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/requirements-tests.txt b/requirements-tests.txt index 1d2ca5d0..a3f4b4b7 100644 --- a/requirements-tests.txt +++ b/requirements-tests.txt @@ -10,7 +10,7 @@ aws-sam-translator==1.22.0 # via cfn-lint aws-xray-sdk==2.5.0 # via moto bandit==1.7.0 # via -r requirements-tests.in black==20.8b1 # via -r requirements-tests.in -boto3==1.16.30 # via aws-sam-translator, moto +boto3==1.16.35 # via aws-sam-translator, moto boto==2.49.0 # via moto botocore==1.19.35 # via aws-xray-sdk, boto3, moto, s3transfer certifi==2020.12.5 # via requests diff --git a/requirements.txt b/requirements.txt index 6e96db66..f7c396da 100644 --- a/requirements.txt +++ b/requirements.txt @@ -15,7 +15,7 @@ bcrypt==3.1.7 # via flask-bcrypt, paramiko beautifulsoup4==4.9.1 # via cloudflare billiard==3.6.3.0 # via celery blinker==1.4 # via flask-mail, flask-principal, raven -boto3==1.16.30 # via -r requirements.in +boto3==1.16.35 # via -r requirements.in botocore==1.19.35 # via -r requirements.in, boto3, s3transfer celery[redis]==5.0.4 # via -r requirements.in certifi==2020.12.5 # via -r requirements.in, requests From 787ca4f860bafcf3ef375ef186271b7a0b25905d Mon Sep 17 00:00:00 2001 From: Jasmine Schladen Date: Tue, 15 Dec 2020 13:03:55 -0800 Subject: [PATCH 154/314] Fix incorrect expectation of return type for summary emails in notification cli, and add 1 to days in summary email --- lemur/notifications/cli.py | 8 +++----- .../plugins/lemur_email/templates/expiration_summary.html | 3 +-- 2 files changed, 4 insertions(+), 7 deletions(-) diff --git a/lemur/notifications/cli.py b/lemur/notifications/cli.py index d86028c0..a26dc8c5 100644 --- a/lemur/notifications/cli.py +++ b/lemur/notifications/cli.py @@ -85,15 +85,13 @@ def security_expiration_summary(exclude): status = FAILURE_METRIC_STATUS try: print("Starting to notify security team about expiring certificates!") - success, failed = send_security_expiration_summary(exclude) + status = send_security_expiration_summary(exclude) print( - "Finished notifying security team about expiring certificates! " - f"Sent: {success} Failed: {failed}" + "Finished notifying security team about expiring certificates!" ) - status = SUCCESS_METRIC_STATUS except Exception: sentry.captureException() metrics.send( - "security_expiration_notification_job", "counter", 1, metric_tags={"status": status} + "security_expiration_summary_notification_job", "counter", 1, metric_tags={"status": status} ) diff --git a/lemur/plugins/lemur_email/templates/expiration_summary.html b/lemur/plugins/lemur_email/templates/expiration_summary.html index d2e98196..ca6b3c6a 100644 --- a/lemur/plugins/lemur_email/templates/expiration_summary.html +++ b/lemur/plugins/lemur_email/templates/expiration_summary.html @@ -77,7 +77,6 @@

This is a summary of all certificates expiring soon. - Only certificates matching the configured expiration intervals are included here. Certificates with notifications disabled have been omitted. @@ -87,7 +86,7 @@ From de98586c133735ff8173f7827a70637c2d30c3af Mon Sep 17 00:00:00 2001 From: Jasmine Schladen Date: Tue, 15 Dec 2020 13:05:55 -0800 Subject: [PATCH 155/314] Undo metric name change --- lemur/notifications/cli.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lemur/notifications/cli.py b/lemur/notifications/cli.py index a26dc8c5..0a76bad5 100644 --- a/lemur/notifications/cli.py +++ b/lemur/notifications/cli.py @@ -93,5 +93,5 @@ def security_expiration_summary(exclude): sentry.captureException() metrics.send( - "security_expiration_summary_notification_job", "counter", 1, metric_tags={"status": status} + "security_expiration_notification_job", "counter", 1, metric_tags={"status": status} ) From 33e46d4a5349fe67fb2ac25e76af231cdd18681c Mon Sep 17 00:00:00 2001 From: Jasmine Schladen Date: Tue, 15 Dec 2020 13:37:24 -0800 Subject: [PATCH 156/314] Fix return type --- lemur/notifications/cli.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/lemur/notifications/cli.py b/lemur/notifications/cli.py index 0a76bad5..042a54fb 100644 --- a/lemur/notifications/cli.py +++ b/lemur/notifications/cli.py @@ -85,10 +85,12 @@ def security_expiration_summary(exclude): status = FAILURE_METRIC_STATUS try: print("Starting to notify security team about expiring certificates!") - status = send_security_expiration_summary(exclude) + success = send_security_expiration_summary(exclude) print( - "Finished notifying security team about expiring certificates!" + f"Finished notifying security team about expiring certificates! Success: {success}" ) + if success: + status = SUCCESS_METRIC_STATUS except Exception: sentry.captureException() From 405aef31608d74eacddaee64a56453ba8b13fb85 Mon Sep 17 00:00:00 2001 From: Hossein Shafagh Date: Wed, 16 Dec 2020 09:30:54 -0800 Subject: [PATCH 157/314] reverting Bump celery[redis] from 4.4.2 to 5.0.4 #3305 --- requirements.in | 2 +- requirements.txt | 17 ++++++----------- 2 files changed, 7 insertions(+), 12 deletions(-) diff --git a/requirements.in b/requirements.in index ed2093c9..1eb96f97 100644 --- a/requirements.in +++ b/requirements.in @@ -6,7 +6,7 @@ arrow asyncpool boto3 botocore -celery[redis] +celery[redis]==4.4.2 # need to first resolve the module not found error https://github.com/celery/celery/issues/6406 certifi certsrv CloudFlare diff --git a/requirements.txt b/requirements.txt index f7c396da..981c38b7 100644 --- a/requirements.txt +++ b/requirements.txt @@ -7,7 +7,7 @@ acme==1.10.1 # via -r requirements.in alembic-autogenerate-enums==0.0.2 # via -r requirements.in alembic==1.4.2 # via flask-migrate -amqp==5.0.2 # via kombu +amqp==2.5.2 # via kombu aniso8601==8.0.0 # via flask-restful arrow==0.17.0 # via -r requirements.in asyncpool==1.0 # via -r requirements.in @@ -17,15 +17,12 @@ billiard==3.6.3.0 # via celery blinker==1.4 # via flask-mail, flask-principal, raven boto3==1.16.35 # via -r requirements.in botocore==1.19.35 # via -r requirements.in, boto3, s3transfer -celery[redis]==5.0.4 # via -r requirements.in +celery[redis]==4.4.2 # via -r requirements.in certifi==2020.12.5 # via -r requirements.in, requests certsrv==2.1.1 # via -r requirements.in cffi==1.14.0 # via bcrypt, cryptography, pynacl chardet==3.0.4 # via requests -click-didyoumean==0.0.3 # via celery -click-plugins==1.1.1 # via celery -click-repl==0.1.6 # via celery -click==7.1.2 # via celery, click-didyoumean, click-plugins, click-repl, flask +click==7.1.2 # flask cloudflare==2.8.14 # via -r requirements.in cryptography==3.3.1 # via -r requirements.in, acme, josepy, paramiko, pyopenssl, requests dnspython3==1.15.0 # via -r requirements.in @@ -52,7 +49,7 @@ jinja2==2.11.2 # via -r requirements.in, flask jmespath==0.9.5 # via boto3, botocore josepy==1.3.0 # via acme jsonlines==1.2.0 # via cloudflare -kombu==5.0.2 # via celery +kombu==4.6.8 # via celery lockfile==0.12.2 # via -r requirements.in logmatic-python==0.1.7 # via -r requirements.in mako==1.1.2 # via alembic @@ -62,7 +59,6 @@ marshmallow==2.20.4 # via -r requirements.in, marshmallow-sqlalchemy ndg-httpsclient==0.5.1 # via -r requirements.in paramiko==2.7.2 # via -r requirements.in pem==20.1.0 # via -r requirements.in -prompt-toolkit==3.0.8 # via click-repl psycopg2==2.8.6 # via -r requirements.in pyasn1-modules==0.2.8 # via pyjks, python-ldap pyasn1==0.4.8 # via ndg-httpsclient, pyasn1-modules, pyjks, python-ldap @@ -85,15 +81,14 @@ requests-toolbelt==0.9.1 # via acme requests[security]==2.25.0 # via -r requirements.in, acme, certsrv, cloudflare, hvac, requests-toolbelt retrying==1.3.3 # via -r requirements.in s3transfer==0.3.3 # via boto3 -six==1.15.0 # via -r requirements.in, acme, bcrypt, click-repl, cryptography, flask-cors, flask-restful, hvac, josepy, jsonlines, pynacl, pyopenssl, python-dateutil, retrying, sqlalchemy-utils +six==1.15.0 # via -r requirements.in, acme, bcrypt, cryptography, flask-cors, flask-restful, hvac, josepy, jsonlines, pynacl, pyopenssl, python-dateutil, retrying, sqlalchemy-utils soupsieve==2.0.1 # via beautifulsoup4 sqlalchemy-utils==0.36.8 # via -r requirements.in sqlalchemy==1.3.16 # via alembic, flask-sqlalchemy, marshmallow-sqlalchemy, sqlalchemy-utils tabulate==0.8.7 # via -r requirements.in twofish==0.3.0 # via pyjks urllib3==1.25.8 # via botocore, requests -vine==5.0.0 # via amqp, celery -wcwidth==0.2.5 # via prompt-toolkit +vine==1.3.0 # via amqp, celery werkzeug==1.0.1 # via flask xmltodict==0.12.0 # via -r requirements.in From 3598953512e503bc89ee12d202af614dc615d879 Mon Sep 17 00:00:00 2001 From: Tim Gates Date: Wed, 30 Dec 2020 08:20:38 +1100 Subject: [PATCH 158/314] docs: fix simple typo, userame -> username There is a small typo in docs/quickstart/index.rst. Should read `username` rather than `userame`. --- docs/quickstart/index.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/quickstart/index.rst b/docs/quickstart/index.rst index e0aef0d5..6ca5ff58 100644 --- a/docs/quickstart/index.rst +++ b/docs/quickstart/index.rst @@ -130,7 +130,7 @@ Once created, you will need to update the configuration file with information ab vi ~/.lemur/lemur.conf.py .. note:: If you are unfamiliar with the SQLALCHEMY_DATABASE_URI string it can be broken up like so: - ``postgresql://userame:password@:/`` + ``postgresql://username:password@:/`` Before Lemur will run you need to fill in a few required variables in the configuration file: From d2e9493397e1e1083a08bcf55813b543fd2d9037 Mon Sep 17 00:00:00 2001 From: Jasmine Schladen Date: Mon, 4 Jan 2021 16:03:15 -0800 Subject: [PATCH 159/314] Add additional wording around LEMUR_ENCRYPTION_KEYS --- docs/administration.rst | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/docs/administration.rst b/docs/administration.rst index bd0b5f96..c0bf006f 100644 --- a/docs/administration.rst +++ b/docs/administration.rst @@ -151,6 +151,14 @@ Specifying the `SQLALCHEMY_MAX_OVERFLOW` to 0 will enforce limit to not create c to start. Multiple keys can be provided to facilitate key rotation. The first key in the list is used for encryption and all keys are tried for decryption until one works. Each key must be 32 URL safe base-64 encoded bytes. + Only fields of type `Vault` will be encrypted. At present, only the following fields are encrypted: + * `certificates.private_key` + * `pending_certificates.private_key` + * `dns_providers.credentials` + * `roles.password` + + For implementation details, see `Vault` in `utils.py`. + Running lemur create_config will securely generate a key for your configuration file. If you would like to generate your own, we recommend the following method: From 3bb5c323efb1667e5e4efa844a478343aca492a6 Mon Sep 17 00:00:00 2001 From: Jasmine Schladen Date: Mon, 4 Jan 2021 16:13:07 -0800 Subject: [PATCH 160/314] Fix formatting --- docs/administration.rst | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/docs/administration.rst b/docs/administration.rst index c0bf006f..59611c0f 100644 --- a/docs/administration.rst +++ b/docs/administration.rst @@ -151,13 +151,14 @@ Specifying the `SQLALCHEMY_MAX_OVERFLOW` to 0 will enforce limit to not create c to start. Multiple keys can be provided to facilitate key rotation. The first key in the list is used for encryption and all keys are tried for decryption until one works. Each key must be 32 URL safe base-64 encoded bytes. - Only fields of type `Vault` will be encrypted. At present, only the following fields are encrypted: - * `certificates.private_key` - * `pending_certificates.private_key` - * `dns_providers.credentials` - * `roles.password` + Only fields of type ``Vault`` will be encrypted. At present, only the following fields are encrypted: - For implementation details, see `Vault` in `utils.py`. + * ``certificates.private_key`` + * ``pending_certificates.private_key`` + * ``dns_providers.credentials`` + * ``roles.password`` + + For implementation details, see ``Vault`` in ``utils.py``. Running lemur create_config will securely generate a key for your configuration file. If you would like to generate your own, we recommend the following method: From 63b5d24f396f8f0d8abaa0834cdb7043e7de9750 Mon Sep 17 00:00:00 2001 From: Hossein Shafagh Date: Mon, 4 Jan 2021 19:31:21 -0800 Subject: [PATCH 161/314] idna at different versions for requirement vs. requirement-test --- requirements-tests.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements-tests.txt b/requirements-tests.txt index a3f4b4b7..d327ae16 100644 --- a/requirements-tests.txt +++ b/requirements-tests.txt @@ -31,7 +31,7 @@ freezegun==1.0.0 # via -r requirements-tests.in future==0.18.2 # via aws-xray-sdk gitdb==4.0.4 # via gitpython gitpython==3.1.1 # via bandit -idna==2.8 # via moto, requests +idna==2.9 # via moto, requests importlib-metadata==1.6.0 # via jsonpickle iniconfig==1.0.1 # via pytest itsdangerous==1.1.0 # via flask From 84b54100755985fbce6213621e5e8c2c3f824f55 Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Tue, 5 Jan 2021 06:37:45 +0000 Subject: [PATCH 162/314] Bump requests from 2.25.0 to 2.25.1 Bumps [requests](https://github.com/psf/requests) from 2.25.0 to 2.25.1. - [Release notes](https://github.com/psf/requests/releases) - [Changelog](https://github.com/psf/requests/blob/master/HISTORY.md) - [Commits](https://github.com/psf/requests/compare/v2.25.0...v2.25.1) Signed-off-by: dependabot-preview[bot] --- requirements-dev.txt | 2 +- requirements-docs.txt | 2 +- requirements-tests.txt | 2 +- requirements.txt | 4 ++-- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/requirements-dev.txt b/requirements-dev.txt index 50c5d08b..3675a042 100644 --- a/requirements-dev.txt +++ b/requirements-dev.txt @@ -32,7 +32,7 @@ pygments==2.6.1 # via readme-renderer pyyaml==5.3.1 # via -r requirements-dev.in, pre-commit readme-renderer==25.0 # via twine requests-toolbelt==0.9.1 # via twine -requests==2.25.0 # via requests-toolbelt, twine +requests==2.25.1 # via requests-toolbelt, twine rfc3986==1.4.0 # via twine secretstorage==3.1.2 # via keyring six==1.15.0 # via bleach, cryptography, readme-renderer, virtualenv diff --git a/requirements-docs.txt b/requirements-docs.txt index 624b6981..c081b17c 100644 --- a/requirements-docs.txt +++ b/requirements-docs.txt @@ -17,7 +17,7 @@ packaging==20.3 # via sphinx pygments==2.6.1 # via sphinx pyparsing==2.4.7 # via packaging pytz==2019.3 # via babel -requests==2.25.0 # via sphinx +requests==2.25.1 # via sphinx six==1.15.0 # via packaging, sphinxcontrib-httpdomain snowballstemmer==2.0.0 # via sphinx sphinx-rtd-theme==0.5.0 # via -r requirements-docs.in diff --git a/requirements-tests.txt b/requirements-tests.txt index d327ae16..34100a75 100644 --- a/requirements-tests.txt +++ b/requirements-tests.txt @@ -69,7 +69,7 @@ pyyaml==5.3.1 # via -r requirements-tests.in, bandit, cfn-lint, moto redis==3.5.3 # via fakeredis regex==2020.4.4 # via black requests-mock==1.8.0 # via -r requirements-tests.in -requests==2.25.0 # via docker, moto, requests-mock, responses +requests==2.25.1 # via docker, moto, requests-mock, responses responses==0.10.12 # via moto rsa==4.0 # via python-jose s3transfer==0.3.3 # via boto3 diff --git a/requirements.txt b/requirements.txt index 981c38b7..4589ca13 100644 --- a/requirements.txt +++ b/requirements.txt @@ -22,7 +22,7 @@ certifi==2020.12.5 # via -r requirements.in, requests certsrv==2.1.1 # via -r requirements.in cffi==1.14.0 # via bcrypt, cryptography, pynacl chardet==3.0.4 # via requests -click==7.1.2 # flask +click==7.1.2 # via flask cloudflare==2.8.14 # via -r requirements.in cryptography==3.3.1 # via -r requirements.in, acme, josepy, paramiko, pyopenssl, requests dnspython3==1.15.0 # via -r requirements.in @@ -78,7 +78,7 @@ pyyaml==5.3.1 # via -r requirements.in, cloudflare raven[flask]==6.10.0 # via -r requirements.in redis==3.5.3 # via -r requirements.in, celery requests-toolbelt==0.9.1 # via acme -requests[security]==2.25.0 # via -r requirements.in, acme, certsrv, cloudflare, hvac, requests-toolbelt +requests[security]==2.25.1 # via -r requirements.in, acme, certsrv, cloudflare, hvac, requests-toolbelt retrying==1.3.3 # via -r requirements.in s3transfer==0.3.3 # via boto3 six==1.15.0 # via -r requirements.in, acme, bcrypt, cryptography, flask-cors, flask-restful, hvac, josepy, jsonlines, pynacl, pyopenssl, python-dateutil, retrying, sqlalchemy-utils From 6668592ffee3200b1184f1caa8673468b0dfa4c6 Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Tue, 5 Jan 2021 18:36:41 +0000 Subject: [PATCH 163/314] Bump sphinx from 3.3.1 to 3.4.2 Bumps [sphinx](https://github.com/sphinx-doc/sphinx) from 3.3.1 to 3.4.2. - [Release notes](https://github.com/sphinx-doc/sphinx/releases) - [Changelog](https://github.com/sphinx-doc/sphinx/blob/3.x/CHANGES) - [Commits](https://github.com/sphinx-doc/sphinx/compare/v3.3.1...v3.4.2) Signed-off-by: dependabot-preview[bot] --- requirements-docs.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements-docs.txt b/requirements-docs.txt index c081b17c..73bb0277 100644 --- a/requirements-docs.txt +++ b/requirements-docs.txt @@ -21,7 +21,7 @@ requests==2.25.1 # via sphinx six==1.15.0 # via packaging, sphinxcontrib-httpdomain snowballstemmer==2.0.0 # via sphinx sphinx-rtd-theme==0.5.0 # via -r requirements-docs.in -sphinx==3.3.1 # via -r requirements-docs.in, sphinx-rtd-theme, sphinxcontrib-httpdomain +sphinx==3.4.2 # via -r requirements-docs.in, sphinx-rtd-theme, sphinxcontrib-httpdomain sphinxcontrib-applehelp==1.0.2 # via sphinx sphinxcontrib-devhelp==1.0.2 # via sphinx sphinxcontrib-htmlhelp==1.0.3 # via sphinx From 53c5381d5bd106b14745780364ff4bc295a9ff63 Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Tue, 5 Jan 2021 18:47:34 +0000 Subject: [PATCH 164/314] Bump factory-boy from 3.1.0 to 3.2.0 Bumps [factory-boy](https://github.com/FactoryBoy/factory_boy) from 3.1.0 to 3.2.0. - [Release notes](https://github.com/FactoryBoy/factory_boy/releases) - [Changelog](https://github.com/FactoryBoy/factory_boy/blob/master/docs/changelog.rst) - [Commits](https://github.com/FactoryBoy/factory_boy/compare/3.1.0...3.2.0) Signed-off-by: dependabot-preview[bot] --- requirements-tests.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements-tests.txt b/requirements-tests.txt index 34100a75..1d62d8b3 100644 --- a/requirements-tests.txt +++ b/requirements-tests.txt @@ -23,7 +23,7 @@ cryptography==3.3.1 # via moto, python-jose, sshpubkeys decorator==4.4.2 # via networkx docker==4.2.0 # via moto ecdsa==0.14.1 # via moto, python-jose, sshpubkeys -factory-boy==3.1.0 # via -r requirements-tests.in +factory-boy==3.2.0 # via -r requirements-tests.in faker==5.0.1 # via -r requirements-tests.in, factory-boy fakeredis==1.4.5 # via -r requirements-tests.in flask==1.1.2 # via pytest-flask From f33f3e1af5a0701c69e2c09658192bdfa75fe0ca Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Tue, 5 Jan 2021 19:00:10 +0000 Subject: [PATCH 165/314] Bump invoke from 1.4.1 to 1.5.0 Bumps [invoke](https://github.com/bitprophet/alabaster) from 1.4.1 to 1.5.0. - [Release notes](https://github.com/bitprophet/alabaster/releases) - [Changelog](https://github.com/bitprophet/alabaster/blob/master/docs/changelog.rst) - [Commits](https://github.com/bitprophet/alabaster/commits) Signed-off-by: dependabot-preview[bot] --- requirements-dev.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements-dev.txt b/requirements-dev.txt index 3675a042..1cb7e72c 100644 --- a/requirements-dev.txt +++ b/requirements-dev.txt @@ -18,7 +18,7 @@ filelock==3.0.12 # via virtualenv flake8==3.8.4 # via -r requirements-dev.in identify==1.4.14 # via pre-commit idna==2.9 # via requests -invoke==1.4.1 # via -r requirements-dev.in +invoke==1.5.0 # via -r requirements-dev.in jeepney==0.4.3 # via keyring, secretstorage keyring==21.2.0 # via twine mccabe==0.6.1 # via flake8 From 7916a8ca90b4e1f23383ab84183ee7678fa6f766 Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Tue, 5 Jan 2021 19:12:21 +0000 Subject: [PATCH 166/314] Bump hvac from 0.10.5 to 0.10.6 Bumps [hvac](https://github.com/hvac/hvac) from 0.10.5 to 0.10.6. - [Release notes](https://github.com/hvac/hvac/releases) - [Changelog](https://github.com/hvac/hvac/blob/develop/CHANGELOG.md) - [Commits](https://github.com/hvac/hvac/compare/v0.10.5...v0.10.6) Signed-off-by: dependabot-preview[bot] --- requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index 4589ca13..00e72dfb 100644 --- a/requirements.txt +++ b/requirements.txt @@ -40,7 +40,7 @@ flask-sqlalchemy==2.4.4 # via -r requirements.in, flask-migrate flask==1.1.2 # via -r requirements.in, flask-bcrypt, flask-cors, flask-mail, flask-migrate, flask-principal, flask-restful, flask-script, flask-sqlalchemy, raven future==0.18.2 # via -r requirements.in gunicorn==20.0.4 # via -r requirements.in -hvac==0.10.5 # via -r requirements.in +hvac==0.10.6 # via -r requirements.in idna==2.9 # via requests inflection==0.5.1 # via -r requirements.in itsdangerous==1.1.0 # via flask From d725a9fdcf1fd40f937a3e0a792b218fea1e8614 Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Tue, 5 Jan 2021 19:29:39 +0000 Subject: [PATCH 167/314] Bump twine from 3.2.0 to 3.3.0 Bumps [twine](https://github.com/pypa/twine) from 3.2.0 to 3.3.0. - [Release notes](https://github.com/pypa/twine/releases) - [Changelog](https://github.com/pypa/twine/blob/master/docs/changelog.rst) - [Commits](https://github.com/pypa/twine/compare/3.2.0...3.3.0) Signed-off-by: dependabot-preview[bot] --- requirements-dev.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements-dev.txt b/requirements-dev.txt index 1cb7e72c..af69b1cf 100644 --- a/requirements-dev.txt +++ b/requirements-dev.txt @@ -38,7 +38,7 @@ secretstorage==3.1.2 # via keyring six==1.15.0 # via bleach, cryptography, readme-renderer, virtualenv toml==0.10.0 # via pre-commit tqdm==4.45.0 # via twine -twine==3.2.0 # via -r requirements-dev.in +twine==3.3.0 # via -r requirements-dev.in urllib3==1.25.8 # via requests virtualenv==20.0.17 # via pre-commit webencodings==0.5.1 # via bleach From aad48ab28911ad3757a66d722c10cd28ad7d5783 Mon Sep 17 00:00:00 2001 From: Hossein Shafagh Date: Tue, 5 Jan 2021 11:33:11 -0800 Subject: [PATCH 168/314] Reducing Travis CI email noise # Dependbot cancels Travis before rebase and triggers too many emails --- .travis.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.travis.yml b/.travis.yml index f9db8d3b..5f59badb 100644 --- a/.travis.yml +++ b/.travis.yml @@ -51,3 +51,4 @@ notifications: - lemur@netflix.com on_success: never on_failure: always + on_cancel: never # Dependbot cancels Travis before rebase and triggers too many emails From ae49840add2ba06d2e25213535c43bd010b9741c Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Tue, 5 Jan 2021 19:43:40 +0000 Subject: [PATCH 169/314] Bump cloudflare from 2.8.14 to 2.8.15 Bumps [cloudflare](https://github.com/cloudflare/python-cloudflare) from 2.8.14 to 2.8.15. - [Release notes](https://github.com/cloudflare/python-cloudflare/releases) - [Changelog](https://github.com/cloudflare/python-cloudflare/blob/master/CHANGELOG.md) - [Commits](https://github.com/cloudflare/python-cloudflare/compare/2.8.14...2.8.15) Signed-off-by: dependabot-preview[bot] --- requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index 00e72dfb..b01ac31c 100644 --- a/requirements.txt +++ b/requirements.txt @@ -23,7 +23,7 @@ certsrv==2.1.1 # via -r requirements.in cffi==1.14.0 # via bcrypt, cryptography, pynacl chardet==3.0.4 # via requests click==7.1.2 # via flask -cloudflare==2.8.14 # via -r requirements.in +cloudflare==2.8.15 # via -r requirements.in cryptography==3.3.1 # via -r requirements.in, acme, josepy, paramiko, pyopenssl, requests dnspython3==1.15.0 # via -r requirements.in dnspython==1.15.0 # via dnspython3 From 92312ff4f7f3b611f65fb27b25d93d893d284a81 Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Tue, 5 Jan 2021 20:01:47 +0000 Subject: [PATCH 170/314] Bump pytest from 6.2.0 to 6.2.1 Bumps [pytest](https://github.com/pytest-dev/pytest) from 6.2.0 to 6.2.1. - [Release notes](https://github.com/pytest-dev/pytest/releases) - [Changelog](https://github.com/pytest-dev/pytest/blob/master/CHANGELOG.rst) - [Commits](https://github.com/pytest-dev/pytest/compare/6.2.0...6.2.1) Signed-off-by: dependabot-preview[bot] --- requirements-tests.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements-tests.txt b/requirements-tests.txt index 1d62d8b3..0d7d8e38 100644 --- a/requirements-tests.txt +++ b/requirements-tests.txt @@ -61,7 +61,7 @@ pyparsing==2.4.7 # via packaging pyrsistent==0.16.0 # via jsonschema pytest-flask==1.1.0 # via -r requirements-tests.in pytest-mock==3.3.1 # via -r requirements-tests.in -pytest==6.2.0 # via -r requirements-tests.in, pytest-flask, pytest-mock +pytest==6.2.1 # via -r requirements-tests.in, pytest-flask, pytest-mock python-dateutil==2.8.1 # via botocore, faker, freezegun, moto python-jose[cryptography]==3.1.0 # via moto pytz==2019.3 # via moto From 9470f71e34841b6b09424f34733c23efed358d4f Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Tue, 5 Jan 2021 20:20:24 +0000 Subject: [PATCH 171/314] Bump pytest-mock from 3.3.1 to 3.5.0 Bumps [pytest-mock](https://github.com/pytest-dev/pytest-mock) from 3.3.1 to 3.5.0. - [Release notes](https://github.com/pytest-dev/pytest-mock/releases) - [Changelog](https://github.com/pytest-dev/pytest-mock/blob/master/CHANGELOG.rst) - [Commits](https://github.com/pytest-dev/pytest-mock/compare/v3.3.1...v3.5.0) Signed-off-by: dependabot-preview[bot] --- requirements-tests.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements-tests.txt b/requirements-tests.txt index 0d7d8e38..309a1cee 100644 --- a/requirements-tests.txt +++ b/requirements-tests.txt @@ -60,7 +60,7 @@ pyflakes==2.2.0 # via -r requirements-tests.in pyparsing==2.4.7 # via packaging pyrsistent==0.16.0 # via jsonschema pytest-flask==1.1.0 # via -r requirements-tests.in -pytest-mock==3.3.1 # via -r requirements-tests.in +pytest-mock==3.5.0 # via -r requirements-tests.in pytest==6.2.1 # via -r requirements-tests.in, pytest-flask, pytest-mock python-dateutil==2.8.1 # via botocore, faker, freezegun, moto python-jose[cryptography]==3.1.0 # via moto From 836591e1652db70c10ee2340b18251af657a4356 Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Tue, 5 Jan 2021 20:39:51 +0000 Subject: [PATCH 172/314] Bump coverage from 5.3 to 5.3.1 Bumps [coverage](https://github.com/nedbat/coveragepy) from 5.3 to 5.3.1. - [Release notes](https://github.com/nedbat/coveragepy/releases) - [Changelog](https://github.com/nedbat/coveragepy/blob/master/CHANGES.rst) - [Commits](https://github.com/nedbat/coveragepy/compare/coverage-5.3...coverage-5.3.1) Signed-off-by: dependabot-preview[bot] --- requirements-tests.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements-tests.txt b/requirements-tests.txt index 309a1cee..82087d8c 100644 --- a/requirements-tests.txt +++ b/requirements-tests.txt @@ -18,7 +18,7 @@ cffi==1.14.0 # via cryptography cfn-lint==0.29.5 # via moto chardet==3.0.4 # via requests click==7.1.2 # via black, flask -coverage==5.3 # via -r requirements-tests.in +coverage==5.3.1 # via -r requirements-tests.in cryptography==3.3.1 # via moto, python-jose, sshpubkeys decorator==4.4.2 # via networkx docker==4.2.0 # via moto From 3bc6090963d5d0b370ee6749e3b20d3ba2a0f976 Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Tue, 5 Jan 2021 21:02:33 +0000 Subject: [PATCH 173/314] Bump pyopenssl from 20.0.0 to 20.0.1 Bumps [pyopenssl](https://github.com/pyca/pyopenssl) from 20.0.0 to 20.0.1. - [Release notes](https://github.com/pyca/pyopenssl/releases) - [Changelog](https://github.com/pyca/pyopenssl/blob/master/CHANGELOG.rst) - [Commits](https://github.com/pyca/pyopenssl/compare/20.0.0...20.0.1) Signed-off-by: dependabot-preview[bot] --- requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index b01ac31c..c4e1a61f 100644 --- a/requirements.txt +++ b/requirements.txt @@ -67,7 +67,7 @@ pycryptodomex==3.9.7 # via pyjks pyjks==20.0.0 # via -r requirements.in pyjwt==1.7.1 # via -r requirements.in pynacl==1.3.0 # via paramiko -pyopenssl==20.0.0 # via -r requirements.in, acme, josepy, ndg-httpsclient, requests +pyopenssl==20.0.1 # via -r requirements.in, acme, josepy, ndg-httpsclient, requests pyrfc3339==1.1 # via acme python-dateutil==2.8.1 # via alembic, arrow, botocore python-editor==1.0.4 # via alembic From 5f317068014ae0df200cb058d244b8dce11fa77f Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Tue, 5 Jan 2021 21:14:41 +0000 Subject: [PATCH 174/314] Bump faker from 5.0.1 to 5.3.0 Bumps [faker](https://github.com/joke2k/faker) from 5.0.1 to 5.3.0. - [Release notes](https://github.com/joke2k/faker/releases) - [Changelog](https://github.com/joke2k/faker/blob/master/CHANGELOG.md) - [Commits](https://github.com/joke2k/faker/compare/v5.0.1...v5.3.0) Signed-off-by: dependabot-preview[bot] --- requirements-tests.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements-tests.txt b/requirements-tests.txt index 82087d8c..8dea7c86 100644 --- a/requirements-tests.txt +++ b/requirements-tests.txt @@ -24,7 +24,7 @@ decorator==4.4.2 # via networkx docker==4.2.0 # via moto ecdsa==0.14.1 # via moto, python-jose, sshpubkeys factory-boy==3.2.0 # via -r requirements-tests.in -faker==5.0.1 # via -r requirements-tests.in, factory-boy +faker==5.3.0 # via -r requirements-tests.in, factory-boy fakeredis==1.4.5 # via -r requirements-tests.in flask==1.1.2 # via pytest-flask freezegun==1.0.0 # via -r requirements-tests.in From 0e04e79260a2b4f4e3b1d5d9b326d1341462385f Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Tue, 5 Jan 2021 21:52:48 +0000 Subject: [PATCH 175/314] Bump botocore from 1.19.35 to 1.19.49 Bumps [botocore](https://github.com/boto/botocore) from 1.19.35 to 1.19.49. - [Release notes](https://github.com/boto/botocore/releases) - [Changelog](https://github.com/boto/botocore/blob/develop/CHANGELOG.rst) - [Commits](https://github.com/boto/botocore/compare/1.19.35...1.19.49) Signed-off-by: dependabot-preview[bot] --- requirements-tests.txt | 2 +- requirements.txt | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/requirements-tests.txt b/requirements-tests.txt index 8dea7c86..a36d18f1 100644 --- a/requirements-tests.txt +++ b/requirements-tests.txt @@ -12,7 +12,7 @@ bandit==1.7.0 # via -r requirements-tests.in black==20.8b1 # via -r requirements-tests.in boto3==1.16.35 # via aws-sam-translator, moto boto==2.49.0 # via moto -botocore==1.19.35 # via aws-xray-sdk, boto3, moto, s3transfer +botocore==1.19.49 # via aws-xray-sdk, boto3, moto, s3transfer certifi==2020.12.5 # via requests cffi==1.14.0 # via cryptography cfn-lint==0.29.5 # via moto diff --git a/requirements.txt b/requirements.txt index c4e1a61f..f9aa9576 100644 --- a/requirements.txt +++ b/requirements.txt @@ -16,7 +16,7 @@ beautifulsoup4==4.9.1 # via cloudflare billiard==3.6.3.0 # via celery blinker==1.4 # via flask-mail, flask-principal, raven boto3==1.16.35 # via -r requirements.in -botocore==1.19.35 # via -r requirements.in, boto3, s3transfer +botocore==1.19.49 # via -r requirements.in, boto3, s3transfer celery[redis]==4.4.2 # via -r requirements.in certifi==2020.12.5 # via -r requirements.in, requests certsrv==2.1.1 # via -r requirements.in From 596aa8ca953e246f8289c198e7975e5d01249e9a Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Tue, 5 Jan 2021 22:04:37 +0000 Subject: [PATCH 176/314] Bump boto3 from 1.16.35 to 1.16.49 Bumps [boto3](https://github.com/boto/boto3) from 1.16.35 to 1.16.49. - [Release notes](https://github.com/boto/boto3/releases) - [Changelog](https://github.com/boto/boto3/blob/develop/CHANGELOG.rst) - [Commits](https://github.com/boto/boto3/compare/1.16.35...1.16.49) Signed-off-by: dependabot-preview[bot] --- requirements-tests.txt | 2 +- requirements.txt | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/requirements-tests.txt b/requirements-tests.txt index a36d18f1..d9fc4641 100644 --- a/requirements-tests.txt +++ b/requirements-tests.txt @@ -10,7 +10,7 @@ aws-sam-translator==1.22.0 # via cfn-lint aws-xray-sdk==2.5.0 # via moto bandit==1.7.0 # via -r requirements-tests.in black==20.8b1 # via -r requirements-tests.in -boto3==1.16.35 # via aws-sam-translator, moto +boto3==1.16.49 # via aws-sam-translator, moto boto==2.49.0 # via moto botocore==1.19.49 # via aws-xray-sdk, boto3, moto, s3transfer certifi==2020.12.5 # via requests diff --git a/requirements.txt b/requirements.txt index f9aa9576..222a61ff 100644 --- a/requirements.txt +++ b/requirements.txt @@ -15,7 +15,7 @@ bcrypt==3.1.7 # via flask-bcrypt, paramiko beautifulsoup4==4.9.1 # via cloudflare billiard==3.6.3.0 # via celery blinker==1.4 # via flask-mail, flask-principal, raven -boto3==1.16.35 # via -r requirements.in +boto3==1.16.49 # via -r requirements.in botocore==1.19.49 # via -r requirements.in, boto3, s3transfer celery[redis]==4.4.2 # via -r requirements.in certifi==2020.12.5 # via -r requirements.in, requests From 8f16402c0a4cbab85c447697db2d858becccc47b Mon Sep 17 00:00:00 2001 From: sayali Date: Tue, 5 Jan 2021 18:13:09 -0800 Subject: [PATCH 177/314] Config to change algo to ECC during reissue --- lemur/certificates/service.py | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/lemur/certificates/service.py b/lemur/certificates/service.py index b22090b6..5999760f 100644 --- a/lemur/certificates/service.py +++ b/lemur/certificates/service.py @@ -795,6 +795,15 @@ def reissue_certificate(certificate, replace=None, user=None): else: primitives["description"] = f"{reissue_message_prefix}{certificate.id}" + # Rotate the certificate to ECCPRIME256V1 if cert owner is present in the configured list + # This is a temporary change intending to rotate certificates to ECC, if opted in by certificate owners + # Unless identified a use case, this will be removed in mid-Q2 2021 + ecc_reissue_owner_list = current_app.config.get("ROTATE_TO_ECC_OWNER_LIST", []) + ecc_reissue_exclude_cn_list = current_app.config.get("ECC_NON_COMPATIBLE_COMMON_NAMES", []) + + if (certificate.owner in ecc_reissue_owner_list) and (certificate.cn not in ecc_reissue_exclude_cn_list): + primitives["key_type"] = "ECCPRIME256V1" + new_cert = create(**primitives) return new_cert From 396e3afdfa40aacc55d1737e1e9941854ebdb30f Mon Sep 17 00:00:00 2001 From: sayali Date: Tue, 5 Jan 2021 18:14:57 -0800 Subject: [PATCH 178/314] Fix @pytest.yield_fixture deprecation Use @pytest.fixture instead; they are the same. --- lemur/tests/conftest.py | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/lemur/tests/conftest.py b/lemur/tests/conftest.py index 2efd65d9..f388acc6 100644 --- a/lemur/tests/conftest.py +++ b/lemur/tests/conftest.py @@ -56,7 +56,7 @@ def pytest_runtest_makereport(item, call): parent._previousfailed = item -@pytest.yield_fixture(scope="session") +@pytest.fixture(scope="session") def app(request): """ Creates a new Flask application for a test duration. @@ -73,7 +73,7 @@ def app(request): ctx.pop() -@pytest.yield_fixture(scope="session") +@pytest.fixture(scope="session") def db(app, request): _db.drop_all() _db.engine.execute(text("CREATE EXTENSION IF NOT EXISTS pg_trgm")) @@ -92,7 +92,7 @@ def db(app, request): _db.drop_all() -@pytest.yield_fixture(scope="function") +@pytest.fixture(scope="function") def session(db, request): """ Creates a new database session with (with working transaction) @@ -103,7 +103,7 @@ def session(db, request): db.session.rollback() -@pytest.yield_fixture(scope="function") +@pytest.fixture(scope="function") def client(app, session, client): yield client @@ -276,14 +276,14 @@ def source_plugin(): return TestSourcePlugin -@pytest.yield_fixture(scope="function") +@pytest.fixture(scope="function") def logged_in_user(session, app): with app.test_request_context(): identity_changed.send(current_app._get_current_object(), identity=Identity(1)) yield -@pytest.yield_fixture(scope="function") +@pytest.fixture(scope="function") def logged_in_admin(session, app): with app.test_request_context(): identity_changed.send(current_app._get_current_object(), identity=Identity(2)) From ba050028ca2c3c537e2b02a9cd776242174d6a1c Mon Sep 17 00:00:00 2001 From: sayali Date: Wed, 6 Jan 2021 11:28:18 -0800 Subject: [PATCH 179/314] Paginate valid certificate fetch API --- lemur/certificates/service.py | 12 ++++++++++-- lemur/certificates/views.py | 20 ++++++++++++++------ lemur/database.py | 4 +++- 3 files changed, 27 insertions(+), 9 deletions(-) diff --git a/lemur/certificates/service.py b/lemur/certificates/service.py index 5999760f..e6414933 100644 --- a/lemur/certificates/service.py +++ b/lemur/certificates/service.py @@ -563,10 +563,15 @@ def query_common_name(common_name, args): :return: """ owner = args.pop("owner") + page = args.pop("page") + count = args.pop("count") + + paginate = page and count + query = database.session_query(Certificate) if paginate else Certificate.query + # only not expired certificates current_time = arrow.utcnow() - - query = Certificate.query.filter(Certificate.not_after >= current_time.format("YYYY-MM-DD"))\ + query = query.filter(Certificate.not_after >= current_time.format("YYYY-MM-DD"))\ .filter(not_(Certificate.revoked))\ .filter(not_(Certificate.replaced.any())) # ignore rotated certificates to avoid duplicates @@ -577,6 +582,9 @@ def query_common_name(common_name, args): # if common_name is a wildcard ('%'), no need to include it in the query query = query.filter(Certificate.cn.ilike(common_name)) + if paginate: + return database.paginate(query, page, count) + return query.all() diff --git a/lemur/certificates/views.py b/lemur/certificates/views.py index 56d0a9c8..47c076fc 100644 --- a/lemur/certificates/views.py +++ b/lemur/certificates/views.py @@ -51,17 +51,20 @@ class CertificatesListValid(AuthenticatedResource): """ .. http:get:: /certificates/valid/ - The current list of not-expired certificates for a given common name, and owner + The current list of not-expired certificates for a given common name, and owner. The API offers + optional pagination. One can send page number(>=1) and desired count per page. The returned data + contains total number of certificates which can help in determining the last page. Pagination + will not be offered if page or count info is not sent or if it is zero. **Example request**: .. sourcecode:: http - GET /certificates/valid?filter=cn;*.test.example.net&owner=joe@example.com + GET /certificates/valid?filter=cn;*.test.example.net&owner=joe@example.com&page=1&count=20 HTTP/1.1 Host: example.com Accept: application/json, text/javascript - **Example response**: + **Example response (with single cert to be concise)**: .. sourcecode:: http @@ -128,10 +131,15 @@ class CertificatesListValid(AuthenticatedResource): :statuscode 403: unauthenticated """ - parser = paginated_parser.copy() - args = parser.parse_args() + # using non-paginated parser to ensure backward compatibility + self.reqparse.add_argument("filter", type=str, location="args") + self.reqparse.add_argument("owner", type=str, location="args") + self.reqparse.add_argument("count", type=int, location="args") + self.reqparse.add_argument("page", type=int, location="args") + + args = self.reqparse.parse_args() args["user"] = g.user - common_name = args["filter"].split(";")[1] + common_name = args.pop("filter").split(";")[1] return service.query_common_name(common_name, args) diff --git a/lemur/database.py b/lemur/database.py index a9610325..0453c381 100644 --- a/lemur/database.py +++ b/lemur/database.py @@ -225,7 +225,9 @@ def paginate(query, page, count): :param page: :param count: """ - return query.paginate(page, count) + total = get_count(query) + items = query.paginate(page, count).items + return dict(items=items, total=total, current=len(items)) def update_list(model, model_attr, item_model, items): From 8a9b729478a2367210ec162829949e0049315fd1 Mon Sep 17 00:00:00 2001 From: Benjamin Greschbach Date: Thu, 7 Jan 2021 14:11:14 +0100 Subject: [PATCH 180/314] update language --- lemur/static/app/angular/notifications/view/view.tpl.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lemur/static/app/angular/notifications/view/view.tpl.html b/lemur/static/app/angular/notifications/view/view.tpl.html index 05a5fe51..5cf2d6b4 100644 --- a/lemur/static/app/angular/notifications/view/view.tpl.html +++ b/lemur/static/app/angular/notifications/view/view.tpl.html @@ -1,7 +1,7 @@

Notifications - you have to speak up son!

+ you have to speak up engineer!
From 00c9d49f4b47bb7330ab3f9cd3d9cba1966f8c8e Mon Sep 17 00:00:00 2001 From: Hossein Shafagh Date: Thu, 7 Jan 2021 16:14:17 -0800 Subject: [PATCH 181/314] Update view.tpl.html additional suggestion --- lemur/static/app/angular/notifications/view/view.tpl.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lemur/static/app/angular/notifications/view/view.tpl.html b/lemur/static/app/angular/notifications/view/view.tpl.html index 5cf2d6b4..03b7283c 100644 --- a/lemur/static/app/angular/notifications/view/view.tpl.html +++ b/lemur/static/app/angular/notifications/view/view.tpl.html @@ -1,7 +1,7 @@

Notifications - you have to speak up engineer!

+ you have to speak up!
From 65bd472b086bcb64d3cbfb87fdbeb37b9ee43cc6 Mon Sep 17 00:00:00 2001 From: Hossein Shafagh Date: Thu, 7 Jan 2021 18:33:04 -0800 Subject: [PATCH 182/314] Ensuring that ACME plugin can handle longer chains: MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Particularly with respect to this announcement: https://letsencrypt.org/2020/12/21/extending-android-compatibility.html Subscriber Certificate < – R3 < – ISRG Root X1 < – DST Root CA X3 --- .../lemur_acme/tests/test_acme_http.py | 149 +++++++++++++++++- 1 file changed, 144 insertions(+), 5 deletions(-) diff --git a/lemur/plugins/lemur_acme/tests/test_acme_http.py b/lemur/plugins/lemur_acme/tests/test_acme_http.py index 5a546165..543325ee 100644 --- a/lemur/plugins/lemur_acme/tests/test_acme_http.py +++ b/lemur/plugins/lemur_acme/tests/test_acme_http.py @@ -1,8 +1,8 @@ import unittest from unittest.mock import patch, Mock -from flask import Flask from acme import challenges +from flask import Flask from lemur.plugins.lemur_acme import plugin @@ -51,7 +51,8 @@ class TestAcmeHttp(unittest.TestCase): mock_order_resource = Mock() mock_order_resource.authorizations = [Mock()] mock_order_resource.authorizations[0].body.challenges = [Mock()] - mock_order_resource.authorizations[0].body.challenges[0].response_and_validation.return_value = (Mock(), "Anything-goes") + mock_order_resource.authorizations[0].body.challenges[0].response_and_validation.return_value = ( + Mock(), "Anything-goes") mock_order_resource.authorizations[0].body.challenges[0].chall = challenges.HTTP01( token=b'\x0f\x1c\xbe#od\xd1\x9c\xa6j\\\xa4\r\xed\xe5\xbf0pz\xeaxnl)\xea[i\xbc\x95\x08\x96\x1f') @@ -60,7 +61,91 @@ class TestAcmeHttp(unittest.TestCase): mock_client.answer_challenge.return_value = True mock_finalized_order = Mock() - mock_finalized_order.fullchain_pem = "-----BEGIN CERTIFICATE-----\nMIIEqzCCApOgAwIBAgIRAIvhKg5ZRO08VGQx8JdhT+UwDQYJKoZIhvcNAQELBQAw\nGjEYMBYGA1UEAwwPRmFrZSBMRSBSb290IFgxMB4XDTE2MDUyMzIyMDc1OVoXDTM2\nMDUyMzIyMDc1OVowIjEgMB4GA1UEAwwXRmFrZSBMRSBJbnRlcm1lZGlhdGUgWDEw\nggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDtWKySDn7rWZc5ggjz3ZB0\n8jO4xti3uzINfD5sQ7Lj7hzetUT+wQob+iXSZkhnvx+IvdbXF5/yt8aWPpUKnPym\noLxsYiI5gQBLxNDzIec0OIaflWqAr29m7J8+NNtApEN8nZFnf3bhehZW7AxmS1m0\nZnSsdHw0Fw+bgixPg2MQ9k9oefFeqa+7Kqdlz5bbrUYV2volxhDFtnI4Mh8BiWCN\nxDH1Hizq+GKCcHsinDZWurCqder/afJBnQs+SBSL6MVApHt+d35zjBD92fO2Je56\ndhMfzCgOKXeJ340WhW3TjD1zqLZXeaCyUNRnfOmWZV8nEhtHOFbUCU7r/KkjMZO9\nAgMBAAGjgeMwgeAwDgYDVR0PAQH/BAQDAgGGMBIGA1UdEwEB/wQIMAYBAf8CAQAw\nHQYDVR0OBBYEFMDMA0a5WCDMXHJw8+EuyyCm9Wg6MHoGCCsGAQUFBwEBBG4wbDA0\nBggrBgEFBQcwAYYoaHR0cDovL29jc3Auc3RnLXJvb3QteDEubGV0c2VuY3J5cHQu\nb3JnLzA0BggrBgEFBQcwAoYoaHR0cDovL2NlcnQuc3RnLXJvb3QteDEubGV0c2Vu\nY3J5cHQub3JnLzAfBgNVHSMEGDAWgBTBJnSkikSg5vogKNhcI5pFiBh54DANBgkq\nhkiG9w0BAQsFAAOCAgEABYSu4Il+fI0MYU42OTmEj+1HqQ5DvyAeyCA6sGuZdwjF\nUGeVOv3NnLyfofuUOjEbY5irFCDtnv+0ckukUZN9lz4Q2YjWGUpW4TTu3ieTsaC9\nAFvCSgNHJyWSVtWvB5XDxsqawl1KzHzzwr132bF2rtGtazSqVqK9E07sGHMCf+zp\nDQVDVVGtqZPHwX3KqUtefE621b8RI6VCl4oD30Olf8pjuzG4JKBFRFclzLRjo/h7\nIkkfjZ8wDa7faOjVXx6n+eUQ29cIMCzr8/rNWHS9pYGGQKJiY2xmVC9h12H99Xyf\nzWE9vb5zKP3MVG6neX1hSdo7PEAb9fqRhHkqVsqUvJlIRmvXvVKTwNCP3eCjRCCI\nPTAvjV+4ni786iXwwFYNz8l3PmPLCyQXWGohnJ8iBm+5nk7O2ynaPVW0U2W+pt2w\nSVuvdDM5zGv2f9ltNWUiYZHJ1mmO97jSY/6YfdOUH66iRtQtDkHBRdkNBsMbD+Em\n2TgBldtHNSJBfB3pm9FblgOcJ0FSWcUDWJ7vO0+NTXlgrRofRT6pVywzxVo6dND0\nWzYlTWeUVsO40xJqhgUQRER9YLOLxJ0O6C8i0xFxAMKOtSdodMB3RIwt7RFQ0uyt\nn5Z5MqkYhlMI3J1tPRTp1nEt9fyGspBOO05gi148Qasp+3N+svqKomoQglNoAxU=\n-----END CERTIFICATE-----\n-----BEGIN CERTIFICATE-----\nMIIEqzCCApOgAwIBAgIRAIvhKg5ZRO08VGQx8JdhT+UwDQYJKoZIhvcNAQELBQAw\nGjEYMBYGA1UEAwwPRmFrZSBMRSBSb290IFgxMB4XDTE2MDUyMzIyMDc1OVoXDTM2\nMDUyMzIyMDc1OVowIjEgMB4GA1UEAwwXRmFrZSBMRSBJbnRlcm1lZGlhdGUgWDEw\nggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDtWKySDn7rWZc5ggjz3ZB0\n8jO4xti3uzINfD5sQ7Lj7hzetUT+wQob+iXSZkhnvx+IvdbXF5/yt8aWPpUKnPym\noLxsYiI5gQBLxNDzIec0OIaflWqAr29m7J8+NNtApEN8nZFnf3bhehZW7AxmS1m0\nZnSsdHw0Fw+bgixPg2MQ9k9oefFeqa+7Kqdlz5bbrUYV2volxhDFtnI4Mh8BiWCN\nxDH1Hizq+GKCcHsinDZWurCqder/afJBnQs+SBSL6MVApHt+d35zjBD92fO2Je56\ndhMfzCgOKXeJ340WhW3TjD1zqLZXeaCyUNRnfOmWZV8nEhtHOFbUCU7r/KkjMZO9\nAgMBAAGjgeMwgeAwDgYDVR0PAQH/BAQDAgGGMBIGA1UdEwEB/wQIMAYBAf8CAQAw\nHQYDVR0OBBYEFMDMA0a5WCDMXHJw8+EuyyCm9Wg6MHoGCCsGAQUFBwEBBG4wbDA0\nBggrBgEFBQcwAYYoaHR0cDovL29jc3Auc3RnLXJvb3QteDEubGV0c2VuY3J5cHQu\nb3JnLzA0BggrBgEFBQcwAoYoaHR0cDovL2NlcnQuc3RnLXJvb3QteDEubGV0c2Vu\nY3J5cHQub3JnLzAfBgNVHSMEGDAWgBTBJnSkikSg5vogKNhcI5pFiBh54DANBgkq\nhkiG9w0BAQsFAAOCAgEABYSu4Il+fI0MYU42OTmEj+1HqQ5DvyAeyCA6sGuZdwjF\nUGeVOv3NnLyfofuUOjEbY5irFCDtnv+0ckukUZN9lz4Q2YjWGUpW4TTu3ieTsaC9\nAFvCSgNHJyWSVtWvB5XDxsqawl1KzHzzwr132bF2rtGtazSqVqK9E07sGHMCf+zp\nDQVDVVGtqZPHwX3KqUtefE621b8RI6VCl4oD30Olf8pjuzG4JKBFRFclzLRjo/h7\nIkkfjZ8wDa7faOjVXx6n+eUQ29cIMCzr8/rNWHS9pYGGQKJiY2xmVC9h12H99Xyf\nzWE9vb5zKP3MVG6neX1hSdo7PEAb9fqRhHkqVsqUvJlIRmvXvVKTwNCP3eCjRCCI\nPTAvjV+4ni786iXwwFYNz8l3PmPLCyQXWGohnJ8iBm+5nk7O2ynaPVW0U2W+pt2w\nSVuvdDM5zGv2f9ltNWUiYZHJ1mmO97jSY/6YfdOUH66iRtQtDkHBRdkNBsMbD+Em\n2TgBldtHNSJBfB3pm9FblgOcJ0FSWcUDWJ7vO0+NTXlgrRofRT6pVywzxVo6dND0\nWzYlTWeUVsO40xJqhgUQRER9YLOLxJ0O6C8i0xFxAMKOtSdodMB3RIwt7RFQ0uyt\nn5Z5MqkYhlMI3J1tPRTp1nEt9fyGspBOO05gi148Qasp+3N+svqKomoQglNoAxU=\n-----END CERTIFICATE-----\n" + mock_finalized_order.fullchain_pem = """ +-----BEGIN CERTIFICATE----- +MIIEqzCCApOgAwIBAgIRAIvhKg5ZRO08VGQx8JdhT+UwDQYJKoZIhvcNAQELBQAw +GjEYMBYGA1UEAwwPRmFrZSBMRSBSb290IFgxMB4XDTE2MDUyMzIyMDc1OVoXDTM2 +MDUyMzIyMDc1OVowIjEgMB4GA1UEAwwXRmFrZSBMRSBJbnRlcm1lZGlhdGUgWDEw +ggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDtWKySDn7rWZc5ggjz3ZB0 +8jO4xti3uzINfD5sQ7Lj7hzetUT+wQob+iXSZkhnvx+IvdbXF5/yt8aWPpUKnPym +oLxsYiI5gQBLxNDzIec0OIaflWqAr29m7J8+NNtApEN8nZFnf3bhehZW7AxmS1m0 +ZnSsdHw0Fw+bgixPg2MQ9k9oefFeqa+7Kqdlz5bbrUYV2volxhDFtnI4Mh8BiWCN +xDH1Hizq+GKCcHsinDZWurCqder/afJBnQs+SBSL6MVApHt+d35zjBD92fO2Je56 +dhMfzCgOKXeJ340WhW3TjD1zqLZXeaCyUNRnfOmWZV8nEhtHOFbUCU7r/KkjMZO9 +AgMBAAGjgeMwgeAwDgYDVR0PAQH/BAQDAgGGMBIGA1UdEwEB/wQIMAYBAf8CAQAw +HQYDVR0OBBYEFMDMA0a5WCDMXHJw8+EuyyCm9Wg6MHoGCCsGAQUFBwEBBG4wbDA0 +BggrBgEFBQcwAYYoaHR0cDovL29jc3Auc3RnLXJvb3QteDEubGV0c2VuY3J5cHQu +b3JnLzA0BggrBgEFBQcwAoYoaHR0cDovL2NlcnQuc3RnLXJvb3QteDEubGV0c2Vu +Y3J5cHQub3JnLzAfBgNVHSMEGDAWgBTBJnSkikSg5vogKNhcI5pFiBh54DANBgkq +hkiG9w0BAQsFAAOCAgEABYSu4Il+fI0MYU42OTmEj+1HqQ5DvyAeyCA6sGuZdwjF +UGeVOv3NnLyfofuUOjEbY5irFCDtnv+0ckukUZN9lz4Q2YjWGUpW4TTu3ieTsaC9 +AFvCSgNHJyWSVtWvB5XDxsqawl1KzHzzwr132bF2rtGtazSqVqK9E07sGHMCf+zp +DQVDVVGtqZPHwX3KqUtefE621b8RI6VCl4oD30Olf8pjuzG4JKBFRFclzLRjo/h7 +IkkfjZ8wDa7faOjVXx6n+eUQ29cIMCzr8/rNWHS9pYGGQKJiY2xmVC9h12H99Xyf +zWE9vb5zKP3MVG6neX1hSdo7PEAb9fqRhHkqVsqUvJlIRmvXvVKTwNCP3eCjRCCI +PTAvjV+4ni786iXwwFYNz8l3PmPLCyQXWGohnJ8iBm+5nk7O2ynaPVW0U2W+pt2w +SVuvdDM5zGv2f9ltNWUiYZHJ1mmO97jSY/6YfdOUH66iRtQtDkHBRdkNBsMbD+Em +2TgBldtHNSJBfB3pm9FblgOcJ0FSWcUDWJ7vO0+NTXlgrRofRT6pVywzxVo6dND0 +WzYlTWeUVsO40xJqhgUQRER9YLOLxJ0O6C8i0xFxAMKOtSdodMB3RIwt7RFQ0uyt +n5Z5MqkYhlMI3J1tPRTp1nEt9fyGspBOO05gi148Qasp+3N+svqKomoQglNoAxU= +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIIEqzCCApOgAwIBAgIRAIvhKg5ZRO08VGQx8JdhT+UwDQYJKoZIhvcNAQELBQAw +GjEYMBYGA1UEAwwPRmFrZSBMRSBSb290IFgxMB4XDTE2MDUyMzIyMDc1OVoXDTM2 +MDUyMzIyMDc1OVowIjEgMB4GA1UEAwwXRmFrZSBMRSBJbnRlcm1lZGlhdGUgWDEw +ggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDtWKySDn7rWZc5ggjz3ZB0 +8jO4xti3uzINfD5sQ7Lj7hzetUT+wQob+iXSZkhnvx+IvdbXF5/yt8aWPpUKnPym +oLxsYiI5gQBLxNDzIec0OIaflWqAr29m7J8+NNtApEN8nZFnf3bhehZW7AxmS1m0 +ZnSsdHw0Fw+bgixPg2MQ9k9oefFeqa+7Kqdlz5bbrUYV2volxhDFtnI4Mh8BiWCN +xDH1Hizq+GKCcHsinDZWurCqder/afJBnQs+SBSL6MVApHt+d35zjBD92fO2Je56 +dhMfzCgOKXeJ340WhW3TjD1zqLZXeaCyUNRnfOmWZV8nEhtHOFbUCU7r/KkjMZO9 +AgMBAAGjgeMwgeAwDgYDVR0PAQH/BAQDAgGGMBIGA1UdEwEB/wQIMAYBAf8CAQAw +HQYDVR0OBBYEFMDMA0a5WCDMXHJw8+EuyyCm9Wg6MHoGCCsGAQUFBwEBBG4wbDA0 +BggrBgEFBQcwAYYoaHR0cDovL29jc3Auc3RnLXJvb3QteDEubGV0c2VuY3J5cHQu +b3JnLzA0BggrBgEFBQcwAoYoaHR0cDovL2NlcnQuc3RnLXJvb3QteDEubGV0c2Vu +Y3J5cHQub3JnLzAfBgNVHSMEGDAWgBTBJnSkikSg5vogKNhcI5pFiBh54DANBgkq +hkiG9w0BAQsFAAOCAgEABYSu4Il+fI0MYU42OTmEj+1HqQ5DvyAeyCA6sGuZdwjF +UGeVOv3NnLyfofuUOjEbY5irFCDtnv+0ckukUZN9lz4Q2YjWGUpW4TTu3ieTsaC9 +AFvCSgNHJyWSVtWvB5XDxsqawl1KzHzzwr132bF2rtGtazSqVqK9E07sGHMCf+zp +DQVDVVGtqZPHwX3KqUtefE621b8RI6VCl4oD30Olf8pjuzG4JKBFRFclzLRjo/h7 +IkkfjZ8wDa7faOjVXx6n+eUQ29cIMCzr8/rNWHS9pYGGQKJiY2xmVC9h12H99Xyf +zWE9vb5zKP3MVG6neX1hSdo7PEAb9fqRhHkqVsqUvJlIRmvXvVKTwNCP3eCjRCCI +PTAvjV+4ni786iXwwFYNz8l3PmPLCyQXWGohnJ8iBm+5nk7O2ynaPVW0U2W+pt2w +SVuvdDM5zGv2f9ltNWUiYZHJ1mmO97jSY/6YfdOUH66iRtQtDkHBRdkNBsMbD+Em +2TgBldtHNSJBfB3pm9FblgOcJ0FSWcUDWJ7vO0+NTXlgrRofRT6pVywzxVo6dND0 +WzYlTWeUVsO40xJqhgUQRER9YLOLxJ0O6C8i0xFxAMKOtSdodMB3RIwt7RFQ0uyt +n5Z5MqkYhlMI3J1tPRTp1nEt9fyGspBOO05gi148Qasp+3N+svqKomoQglNoAxU= +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIIFATCCAumgAwIBAgIRAKc9ZKBASymy5TLOEp57N98wDQYJKoZIhvcNAQELBQAw +GjEYMBYGA1UEAwwPRmFrZSBMRSBSb290IFgxMB4XDTE2MDMyMzIyNTM0NloXDTM2 +MDMyMzIyNTM0NlowGjEYMBYGA1UEAwwPRmFrZSBMRSBSb290IFgxMIICIjANBgkq +hkiG9w0BAQEFAAOCAg8AMIICCgKCAgEA+pYHvQw5iU3v2b3iNuYNKYgsWD6KU7aJ +diddtZQxSWYzUI3U0I1UsRPTxnhTifs/M9NW4ZlV13ZfB7APwC8oqKOIiwo7IwlP +xg0VKgyz+kT8RJfYr66PPIYP0fpTeu42LpMJ+CKo9sbpgVNDZN2z/qiXrRNX/VtG +TkPV7a44fZ5bHHVruAxvDnylpQxJobtCBWlJSsbIRGFHMc2z88eUz9NmIOWUKGGj +EmP76x8OfRHpIpuxRSCjn0+i9+hR2siIOpcMOGd+40uVJxbRRP5ZXnUFa2fF5FWd +O0u0RPI8HON0ovhrwPJY+4eWKkQzyC611oLPYGQ4EbifRsTsCxUZqyUuStGyp8oa +aoSKfF6X0+KzGgwwnrjRTUpIl19A92KR0Noo6h622OX+4sZiO/JQdkuX5w/HupK0 +A0M0WSMCvU6GOhjGotmh2VTEJwHHY4+TUk0iQYRtv1crONklyZoAQPD76hCrC8Cr +IbgsZLfTMC8TWUoMbyUDgvgYkHKMoPm0VGVVuwpRKJxv7+2wXO+pivrrUl2Q9fPe +Kk055nJLMV9yPUdig8othUKrRfSxli946AEV1eEOhxddfEwBE3Lt2xn0hhiIedbb +Ftf/5kEWFZkXyUmMJK8Ra76Kus2ABueUVEcZ48hrRr1Hf1N9n59VbTUaXgeiZA50 +qXf2bymE6F8CAwEAAaNCMEAwDgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMB +Af8wHQYDVR0OBBYEFMEmdKSKRKDm+iAo2FwjmkWIGHngMA0GCSqGSIb3DQEBCwUA +A4ICAQBCPw74M9X/Xx04K1VAES3ypgQYH5bf9FXVDrwhRFSVckria/7dMzoF5wln +uq9NGsjkkkDg17AohcQdr8alH4LvPdxpKr3BjpvEcmbqF8xH+MbbeUEnmbSfLI8H +sefuhXF9AF/9iYvpVNC8FmJ0OhiVv13VgMQw0CRKkbtjZBf8xaEhq/YqxWVsgOjm +dm5CAQ2X0aX7502x8wYRgMnZhA5goC1zVWBVAi8yhhmlhhoDUfg17cXkmaJC5pDd +oenZ9NVhW8eDb03MFCrWNvIh89DDeCGWuWfDltDq0n3owyL0IeSn7RfpSclpxVmV +/53jkYjwIgxIG7Gsv0LKMbsf6QdBcTjhvfZyMIpBRkTe3zuHd2feKzY9lEkbRvRQ +zbh4Ps5YBnG6CKJPTbe2hfi3nhnw/MyEmF3zb0hzvLWNrR9XW3ibb2oL3424XOwc +VjrTSCLzO9Rv6s5wi03qoWvKAQQAElqTYRHhynJ3w6wuvKYF5zcZF3MDnrVGLbh1 +Q9ePRFBCiXOQ6wPLoUhrrbZ8LpFUFYDXHMtYM7P9sc9IAWoONXREJaO08zgFtMp4 +8iyIYUyQAbsvx8oD2M8kRvrIRSrRJSl6L957b4AFiLIQ/GgV2curs0jje7Edx34c +idWw1VrejtwclobqNMVtG3EiPUIpJGpbMcJgbiLSmKkrvQtGng== +-----END CERTIFICATE----- +""" mock_client.poll_and_finalize.return_value = mock_finalized_order mock_acme.return_value = (mock_client, "") @@ -84,8 +169,62 @@ class TestAcmeHttp(unittest.TestCase): pem_certificate, pem_certificate_chain, _ = provider.create_certificate(csr, issuer_options) self.assertEqual(pem_certificate, "-----BEGIN CERTIFICATE-----\nMIIEqzCCApOgAwIBAgIRAIvhKg5ZRO08VGQx8JdhT+UwDQYJKoZIhvcNAQELBQAw\nGjEYMBYGA1UEAwwPRmFrZSBMRSBSb290IFgxMB4XDTE2MDUyMzIyMDc1OVoXDTM2\nMDUyMzIyMDc1OVowIjEgMB4GA1UEAwwXRmFrZSBMRSBJbnRlcm1lZGlhdGUgWDEw\nggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDtWKySDn7rWZc5ggjz3ZB0\n8jO4xti3uzINfD5sQ7Lj7hzetUT+wQob+iXSZkhnvx+IvdbXF5/yt8aWPpUKnPym\noLxsYiI5gQBLxNDzIec0OIaflWqAr29m7J8+NNtApEN8nZFnf3bhehZW7AxmS1m0\nZnSsdHw0Fw+bgixPg2MQ9k9oefFeqa+7Kqdlz5bbrUYV2volxhDFtnI4Mh8BiWCN\nxDH1Hizq+GKCcHsinDZWurCqder/afJBnQs+SBSL6MVApHt+d35zjBD92fO2Je56\ndhMfzCgOKXeJ340WhW3TjD1zqLZXeaCyUNRnfOmWZV8nEhtHOFbUCU7r/KkjMZO9\nAgMBAAGjgeMwgeAwDgYDVR0PAQH/BAQDAgGGMBIGA1UdEwEB/wQIMAYBAf8CAQAw\nHQYDVR0OBBYEFMDMA0a5WCDMXHJw8+EuyyCm9Wg6MHoGCCsGAQUFBwEBBG4wbDA0\nBggrBgEFBQcwAYYoaHR0cDovL29jc3Auc3RnLXJvb3QteDEubGV0c2VuY3J5cHQu\nb3JnLzA0BggrBgEFBQcwAoYoaHR0cDovL2NlcnQuc3RnLXJvb3QteDEubGV0c2Vu\nY3J5cHQub3JnLzAfBgNVHSMEGDAWgBTBJnSkikSg5vogKNhcI5pFiBh54DANBgkq\nhkiG9w0BAQsFAAOCAgEABYSu4Il+fI0MYU42OTmEj+1HqQ5DvyAeyCA6sGuZdwjF\nUGeVOv3NnLyfofuUOjEbY5irFCDtnv+0ckukUZN9lz4Q2YjWGUpW4TTu3ieTsaC9\nAFvCSgNHJyWSVtWvB5XDxsqawl1KzHzzwr132bF2rtGtazSqVqK9E07sGHMCf+zp\nDQVDVVGtqZPHwX3KqUtefE621b8RI6VCl4oD30Olf8pjuzG4JKBFRFclzLRjo/h7\nIkkfjZ8wDa7faOjVXx6n+eUQ29cIMCzr8/rNWHS9pYGGQKJiY2xmVC9h12H99Xyf\nzWE9vb5zKP3MVG6neX1hSdo7PEAb9fqRhHkqVsqUvJlIRmvXvVKTwNCP3eCjRCCI\nPTAvjV+4ni786iXwwFYNz8l3PmPLCyQXWGohnJ8iBm+5nk7O2ynaPVW0U2W+pt2w\nSVuvdDM5zGv2f9ltNWUiYZHJ1mmO97jSY/6YfdOUH66iRtQtDkHBRdkNBsMbD+Em\n2TgBldtHNSJBfB3pm9FblgOcJ0FSWcUDWJ7vO0+NTXlgrRofRT6pVywzxVo6dND0\nWzYlTWeUVsO40xJqhgUQRER9YLOLxJ0O6C8i0xFxAMKOtSdodMB3RIwt7RFQ0uyt\nn5Z5MqkYhlMI3J1tPRTp1nEt9fyGspBOO05gi148Qasp+3N+svqKomoQglNoAxU=\n-----END CERTIFICATE-----\n") - self.assertEqual(pem_certificate_chain, - "-----BEGIN CERTIFICATE-----\nMIIEqzCCApOgAwIBAgIRAIvhKg5ZRO08VGQx8JdhT+UwDQYJKoZIhvcNAQELBQAw\nGjEYMBYGA1UEAwwPRmFrZSBMRSBSb290IFgxMB4XDTE2MDUyMzIyMDc1OVoXDTM2\nMDUyMzIyMDc1OVowIjEgMB4GA1UEAwwXRmFrZSBMRSBJbnRlcm1lZGlhdGUgWDEw\nggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDtWKySDn7rWZc5ggjz3ZB0\n8jO4xti3uzINfD5sQ7Lj7hzetUT+wQob+iXSZkhnvx+IvdbXF5/yt8aWPpUKnPym\noLxsYiI5gQBLxNDzIec0OIaflWqAr29m7J8+NNtApEN8nZFnf3bhehZW7AxmS1m0\nZnSsdHw0Fw+bgixPg2MQ9k9oefFeqa+7Kqdlz5bbrUYV2volxhDFtnI4Mh8BiWCN\nxDH1Hizq+GKCcHsinDZWurCqder/afJBnQs+SBSL6MVApHt+d35zjBD92fO2Je56\ndhMfzCgOKXeJ340WhW3TjD1zqLZXeaCyUNRnfOmWZV8nEhtHOFbUCU7r/KkjMZO9\nAgMBAAGjgeMwgeAwDgYDVR0PAQH/BAQDAgGGMBIGA1UdEwEB/wQIMAYBAf8CAQAw\nHQYDVR0OBBYEFMDMA0a5WCDMXHJw8+EuyyCm9Wg6MHoGCCsGAQUFBwEBBG4wbDA0\nBggrBgEFBQcwAYYoaHR0cDovL29jc3Auc3RnLXJvb3QteDEubGV0c2VuY3J5cHQu\nb3JnLzA0BggrBgEFBQcwAoYoaHR0cDovL2NlcnQuc3RnLXJvb3QteDEubGV0c2Vu\nY3J5cHQub3JnLzAfBgNVHSMEGDAWgBTBJnSkikSg5vogKNhcI5pFiBh54DANBgkq\nhkiG9w0BAQsFAAOCAgEABYSu4Il+fI0MYU42OTmEj+1HqQ5DvyAeyCA6sGuZdwjF\nUGeVOv3NnLyfofuUOjEbY5irFCDtnv+0ckukUZN9lz4Q2YjWGUpW4TTu3ieTsaC9\nAFvCSgNHJyWSVtWvB5XDxsqawl1KzHzzwr132bF2rtGtazSqVqK9E07sGHMCf+zp\nDQVDVVGtqZPHwX3KqUtefE621b8RI6VCl4oD30Olf8pjuzG4JKBFRFclzLRjo/h7\nIkkfjZ8wDa7faOjVXx6n+eUQ29cIMCzr8/rNWHS9pYGGQKJiY2xmVC9h12H99Xyf\nzWE9vb5zKP3MVG6neX1hSdo7PEAb9fqRhHkqVsqUvJlIRmvXvVKTwNCP3eCjRCCI\nPTAvjV+4ni786iXwwFYNz8l3PmPLCyQXWGohnJ8iBm+5nk7O2ynaPVW0U2W+pt2w\nSVuvdDM5zGv2f9ltNWUiYZHJ1mmO97jSY/6YfdOUH66iRtQtDkHBRdkNBsMbD+Em\n2TgBldtHNSJBfB3pm9FblgOcJ0FSWcUDWJ7vO0+NTXlgrRofRT6pVywzxVo6dND0\nWzYlTWeUVsO40xJqhgUQRER9YLOLxJ0O6C8i0xFxAMKOtSdodMB3RIwt7RFQ0uyt\nn5Z5MqkYhlMI3J1tPRTp1nEt9fyGspBOO05gi148Qasp+3N+svqKomoQglNoAxU=\n-----END CERTIFICATE-----\n") + self.assertEqual(pem_certificate_chain, """-----BEGIN CERTIFICATE----- +MIIEqzCCApOgAwIBAgIRAIvhKg5ZRO08VGQx8JdhT+UwDQYJKoZIhvcNAQELBQAw +GjEYMBYGA1UEAwwPRmFrZSBMRSBSb290IFgxMB4XDTE2MDUyMzIyMDc1OVoXDTM2 +MDUyMzIyMDc1OVowIjEgMB4GA1UEAwwXRmFrZSBMRSBJbnRlcm1lZGlhdGUgWDEw +ggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDtWKySDn7rWZc5ggjz3ZB0 +8jO4xti3uzINfD5sQ7Lj7hzetUT+wQob+iXSZkhnvx+IvdbXF5/yt8aWPpUKnPym +oLxsYiI5gQBLxNDzIec0OIaflWqAr29m7J8+NNtApEN8nZFnf3bhehZW7AxmS1m0 +ZnSsdHw0Fw+bgixPg2MQ9k9oefFeqa+7Kqdlz5bbrUYV2volxhDFtnI4Mh8BiWCN +xDH1Hizq+GKCcHsinDZWurCqder/afJBnQs+SBSL6MVApHt+d35zjBD92fO2Je56 +dhMfzCgOKXeJ340WhW3TjD1zqLZXeaCyUNRnfOmWZV8nEhtHOFbUCU7r/KkjMZO9 +AgMBAAGjgeMwgeAwDgYDVR0PAQH/BAQDAgGGMBIGA1UdEwEB/wQIMAYBAf8CAQAw +HQYDVR0OBBYEFMDMA0a5WCDMXHJw8+EuyyCm9Wg6MHoGCCsGAQUFBwEBBG4wbDA0 +BggrBgEFBQcwAYYoaHR0cDovL29jc3Auc3RnLXJvb3QteDEubGV0c2VuY3J5cHQu +b3JnLzA0BggrBgEFBQcwAoYoaHR0cDovL2NlcnQuc3RnLXJvb3QteDEubGV0c2Vu +Y3J5cHQub3JnLzAfBgNVHSMEGDAWgBTBJnSkikSg5vogKNhcI5pFiBh54DANBgkq +hkiG9w0BAQsFAAOCAgEABYSu4Il+fI0MYU42OTmEj+1HqQ5DvyAeyCA6sGuZdwjF +UGeVOv3NnLyfofuUOjEbY5irFCDtnv+0ckukUZN9lz4Q2YjWGUpW4TTu3ieTsaC9 +AFvCSgNHJyWSVtWvB5XDxsqawl1KzHzzwr132bF2rtGtazSqVqK9E07sGHMCf+zp +DQVDVVGtqZPHwX3KqUtefE621b8RI6VCl4oD30Olf8pjuzG4JKBFRFclzLRjo/h7 +IkkfjZ8wDa7faOjVXx6n+eUQ29cIMCzr8/rNWHS9pYGGQKJiY2xmVC9h12H99Xyf +zWE9vb5zKP3MVG6neX1hSdo7PEAb9fqRhHkqVsqUvJlIRmvXvVKTwNCP3eCjRCCI +PTAvjV+4ni786iXwwFYNz8l3PmPLCyQXWGohnJ8iBm+5nk7O2ynaPVW0U2W+pt2w +SVuvdDM5zGv2f9ltNWUiYZHJ1mmO97jSY/6YfdOUH66iRtQtDkHBRdkNBsMbD+Em +2TgBldtHNSJBfB3pm9FblgOcJ0FSWcUDWJ7vO0+NTXlgrRofRT6pVywzxVo6dND0 +WzYlTWeUVsO40xJqhgUQRER9YLOLxJ0O6C8i0xFxAMKOtSdodMB3RIwt7RFQ0uyt +n5Z5MqkYhlMI3J1tPRTp1nEt9fyGspBOO05gi148Qasp+3N+svqKomoQglNoAxU= +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIIFATCCAumgAwIBAgIRAKc9ZKBASymy5TLOEp57N98wDQYJKoZIhvcNAQELBQAw +GjEYMBYGA1UEAwwPRmFrZSBMRSBSb290IFgxMB4XDTE2MDMyMzIyNTM0NloXDTM2 +MDMyMzIyNTM0NlowGjEYMBYGA1UEAwwPRmFrZSBMRSBSb290IFgxMIICIjANBgkq +hkiG9w0BAQEFAAOCAg8AMIICCgKCAgEA+pYHvQw5iU3v2b3iNuYNKYgsWD6KU7aJ +diddtZQxSWYzUI3U0I1UsRPTxnhTifs/M9NW4ZlV13ZfB7APwC8oqKOIiwo7IwlP +xg0VKgyz+kT8RJfYr66PPIYP0fpTeu42LpMJ+CKo9sbpgVNDZN2z/qiXrRNX/VtG +TkPV7a44fZ5bHHVruAxvDnylpQxJobtCBWlJSsbIRGFHMc2z88eUz9NmIOWUKGGj +EmP76x8OfRHpIpuxRSCjn0+i9+hR2siIOpcMOGd+40uVJxbRRP5ZXnUFa2fF5FWd +O0u0RPI8HON0ovhrwPJY+4eWKkQzyC611oLPYGQ4EbifRsTsCxUZqyUuStGyp8oa +aoSKfF6X0+KzGgwwnrjRTUpIl19A92KR0Noo6h622OX+4sZiO/JQdkuX5w/HupK0 +A0M0WSMCvU6GOhjGotmh2VTEJwHHY4+TUk0iQYRtv1crONklyZoAQPD76hCrC8Cr +IbgsZLfTMC8TWUoMbyUDgvgYkHKMoPm0VGVVuwpRKJxv7+2wXO+pivrrUl2Q9fPe +Kk055nJLMV9yPUdig8othUKrRfSxli946AEV1eEOhxddfEwBE3Lt2xn0hhiIedbb +Ftf/5kEWFZkXyUmMJK8Ra76Kus2ABueUVEcZ48hrRr1Hf1N9n59VbTUaXgeiZA50 +qXf2bymE6F8CAwEAAaNCMEAwDgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMB +Af8wHQYDVR0OBBYEFMEmdKSKRKDm+iAo2FwjmkWIGHngMA0GCSqGSIb3DQEBCwUA +A4ICAQBCPw74M9X/Xx04K1VAES3ypgQYH5bf9FXVDrwhRFSVckria/7dMzoF5wln +uq9NGsjkkkDg17AohcQdr8alH4LvPdxpKr3BjpvEcmbqF8xH+MbbeUEnmbSfLI8H +sefuhXF9AF/9iYvpVNC8FmJ0OhiVv13VgMQw0CRKkbtjZBf8xaEhq/YqxWVsgOjm +dm5CAQ2X0aX7502x8wYRgMnZhA5goC1zVWBVAi8yhhmlhhoDUfg17cXkmaJC5pDd +oenZ9NVhW8eDb03MFCrWNvIh89DDeCGWuWfDltDq0n3owyL0IeSn7RfpSclpxVmV +/53jkYjwIgxIG7Gsv0LKMbsf6QdBcTjhvfZyMIpBRkTe3zuHd2feKzY9lEkbRvRQ +zbh4Ps5YBnG6CKJPTbe2hfi3nhnw/MyEmF3zb0hzvLWNrR9XW3ibb2oL3424XOwc +VjrTSCLzO9Rv6s5wi03qoWvKAQQAElqTYRHhynJ3w6wuvKYF5zcZF3MDnrVGLbh1 +Q9ePRFBCiXOQ6wPLoUhrrbZ8LpFUFYDXHMtYM7P9sc9IAWoONXREJaO08zgFtMp4 +8iyIYUyQAbsvx8oD2M8kRvrIRSrRJSl6L957b4AFiLIQ/GgV2curs0jje7Edx34c +idWw1VrejtwclobqNMVtG3EiPUIpJGpbMcJgbiLSmKkrvQtGng== +-----END CERTIFICATE-----""") @patch("lemur.plugins.lemur_acme.plugin.AcmeHandler.setup_acme_client") @patch("lemur.plugins.base.manager.PluginManager.get") From ce693d5a1e1e03974e6bad13e2a83f7decfb94ca Mon Sep 17 00:00:00 2001 From: Hossein Shafagh Date: Thu, 7 Jan 2021 18:34:07 -0800 Subject: [PATCH 183/314] spacing --- lemur/plugins/lemur_acme/tests/test_acme_http.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/lemur/plugins/lemur_acme/tests/test_acme_http.py b/lemur/plugins/lemur_acme/tests/test_acme_http.py index 543325ee..0df9e6b2 100644 --- a/lemur/plugins/lemur_acme/tests/test_acme_http.py +++ b/lemur/plugins/lemur_acme/tests/test_acme_http.py @@ -224,7 +224,8 @@ VjrTSCLzO9Rv6s5wi03qoWvKAQQAElqTYRHhynJ3w6wuvKYF5zcZF3MDnrVGLbh1 Q9ePRFBCiXOQ6wPLoUhrrbZ8LpFUFYDXHMtYM7P9sc9IAWoONXREJaO08zgFtMp4 8iyIYUyQAbsvx8oD2M8kRvrIRSrRJSl6L957b4AFiLIQ/GgV2curs0jje7Edx34c idWw1VrejtwclobqNMVtG3EiPUIpJGpbMcJgbiLSmKkrvQtGng== ------END CERTIFICATE-----""") +-----END CERTIFICATE----- +""") @patch("lemur.plugins.lemur_acme.plugin.AcmeHandler.setup_acme_client") @patch("lemur.plugins.base.manager.PluginManager.get") From 6311e7a2832bbc0146aae05805aa18e1484e64de Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Mon, 11 Jan 2021 13:26:45 +0000 Subject: [PATCH 184/314] Bump acme from 1.10.1 to 1.11.0 Bumps [acme](https://github.com/letsencrypt/letsencrypt) from 1.10.1 to 1.11.0. - [Release notes](https://github.com/letsencrypt/letsencrypt/releases) - [Commits](https://github.com/letsencrypt/letsencrypt/compare/v1.10.1...v1.11.0) Signed-off-by: dependabot-preview[bot] --- requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index 222a61ff..4c3f7593 100644 --- a/requirements.txt +++ b/requirements.txt @@ -4,7 +4,7 @@ # # pip-compile --no-index --output-file=requirements.txt requirements.in # -acme==1.10.1 # via -r requirements.in +acme==1.11.0 # via -r requirements.in alembic-autogenerate-enums==0.0.2 # via -r requirements.in alembic==1.4.2 # via flask-migrate amqp==2.5.2 # via kombu From 3b254ac1533bd2f331c2339b7a2f1b36312b8f5b Mon Sep 17 00:00:00 2001 From: sayali Date: Mon, 11 Jan 2021 10:39:27 -0800 Subject: [PATCH 185/314] Upgrade to gulp 4.0.2 --- gulp/build.js | 100 +++++++++++++++++++++++-------------------------- gulp/server.js | 12 ++++-- gulp/watch.js | 17 +++++---- package.json | 2 +- 4 files changed, 66 insertions(+), 65 deletions(-) diff --git a/gulp/build.js b/gulp/build.js index 5aca8094..d86ce425 100644 --- a/gulp/build.js +++ b/gulp/build.js @@ -21,7 +21,6 @@ var gulp = require('gulp'), useref = require('gulp-useref'), filter = require('gulp-filter'), rev = require('gulp-rev'), - revReplace = require('gulp-rev-replace'), imagemin = require('gulp-imagemin'), minifyHtml = require('gulp-minify-html'), bowerFiles = require('main-bower-files'), @@ -29,16 +28,19 @@ var gulp = require('gulp'), replace = require('gulp-replace'), argv = require('yargs').argv; -gulp.task('default', ['clean'], function () { - gulp.start('fonts', 'styles'); + +gulp.task('clean', function (done) { + del(['.tmp', 'lemur/static/dist'], done); + done(); }); -gulp.task('clean', function (cb) { - del(['.tmp', 'lemur/static/dist'], cb); -}); +gulp.task('default', gulp.series(['clean'], function () { + gulp.start('fonts', 'styles'); +})); gulp.task('test', function (done) { - new karma.Server({ + // returning the promise + return new karma.Server({ configFile: __dirname + '/karma.conf.js', singleRun: true }, function() { @@ -47,25 +49,25 @@ gulp.task('test', function (done) { }); gulp.task('dev:fonts', function () { - var fileList = [ + let fileList = [ 'bower_components/bootstrap/dist/fonts/*', 'bower_components/fontawesome/fonts/*' ]; return gulp.src(fileList) - .pipe(gulp.dest('.tmp/fonts')); + .pipe(gulp.dest('.tmp/fonts')); // returns a stream making it async }); gulp.task('dev:styles', function () { - var baseContent = '@import "bower_components/bootstrap/less/bootstrap.less";@import "bower_components/bootswatch/$theme$/variables.less";@import "bower_components/bootswatch/$theme$/bootswatch.less";@import "bower_components/bootstrap/less/utilities.less";'; - var isBootswatchFile = function (file) { + let baseContent = '@import "bower_components/bootstrap/less/bootstrap.less";@import "bower_components/bootswatch/$theme$/variables.less";@import "bower_components/bootswatch/$theme$/bootswatch.less";@import "bower_components/bootstrap/less/utilities.less";'; + let isBootswatchFile = function (file) { - var suffix = 'bootswatch.less'; + let suffix = 'bootswatch.less'; return file.path.indexOf(suffix, file.path.length - suffix.length) !== -1; }; - var isBootstrapFile = function (file) { - var suffix = 'bootstrap-', + let isBootstrapFile = function (file) { + let suffix = 'bootstrap-', fileName = path.basename(file.path); return fileName.indexOf(suffix) === 0; @@ -74,7 +76,6 @@ gulp.task('dev:styles', function () { var fileList = [ 'bower_components/bootswatch/sandstone/bootswatch.less', 'bower_components/fontawesome/css/font-awesome.css', - 'bower_components/angular-spinkit/src/angular-spinkit.css', 'bower_components/angular-chart.js/dist/angular-chart.css', 'bower_components/angular-loading-bar/src/loading-bar.css', 'bower_components/angular-ui-switch/angular-ui-switch.css', @@ -87,7 +88,7 @@ gulp.task('dev:styles', function () { return gulp.src(fileList) .pipe(gulpif(isBootswatchFile, foreach(function (stream, file) { - var themeName = path.basename(path.dirname(file.path)), + let themeName = path.basename(path.dirname(file.path)), content = replaceAll(baseContent, '$theme$', themeName), file2 = string_src('bootstrap-' + themeName + '.less', content); @@ -95,12 +96,12 @@ gulp.task('dev:styles', function () { }))) .pipe(less()) .pipe(gulpif(isBootstrapFile, foreach(function (stream, file) { - var fileName = path.basename(file.path), + let fileName = path.basename(file.path), themeName = fileName.substring(fileName.indexOf('-') + 1, fileName.indexOf('.')); // http://stackoverflow.com/questions/21719833/gulp-how-to-add-src-files-in-the-middle-of-a-pipe // https://github.com/gulpjs/gulp/blob/master/docs/recipes/using-multiple-sources-in-one-task.md - return merge(stream, gulp.src(['.tmp/styles/font-awesome.css', '.tmp/styles/lemur.css'])) + return merge(stream, gulp.src(['.tmp/styles/font-awesome.css', '.tmp/styles/lemur.css'], { allowEmpty: true })) .pipe(concat('style-' + themeName + '.css')); }))) .pipe(plumber()) @@ -121,7 +122,7 @@ function replaceAll(string, find, replace) { } function string_src(filename, string) { - var src = require('stream').Readable({ objectMode: true }); + let src = require('stream').Readable({ objectMode: true }); src._read = function () { this.push(new gutil.File({ cwd: '', base: '', path: filename, contents: new Buffer(string) })); this.push(null); @@ -162,7 +163,7 @@ function injectHtml(isDev) { })) .pipe( gulpif(!isDev, - inject(gulp.src('lemur/static/dist/ngviews/ngviews.min.js'), { + inject(gulp.src('lemur/static/dist/ngviews/ngviews.min.js', { allowEmpty: true }), { starttag: '', addRootSlash: false }) @@ -170,13 +171,9 @@ function injectHtml(isDev) { ).pipe(gulp.dest('.tmp/')); } -gulp.task('dev:inject', ['dev:styles', 'dev:scripts'], function () { +gulp.task('dev:inject', gulp.series(['dev:styles', 'dev:scripts'], function () { return injectHtml(true); -}); - -gulp.task('build:inject', ['dev:styles', 'dev:scripts', 'build:ngviews'], function () { - return injectHtml(false); -}); +})); gulp.task('build:ngviews', function () { return gulp.src(['lemur/static/app/angular/**/*.html']) @@ -189,9 +186,13 @@ gulp.task('build:ngviews', function () { .pipe(size()); }); -gulp.task('build:html', ['dev:styles', 'dev:scripts', 'build:ngviews', 'build:inject'], function () { - var jsFilter = filter(['**/*.js'], {'restore': true}); - var cssFilter = filter(['**/*.css'], {'restore': true}); +gulp.task('build:inject', gulp.series(['dev:styles', 'dev:scripts', 'build:ngviews'], function () { + return injectHtml(false); +})); + +gulp.task('build:html', gulp.series(['build:inject'], function () { + let jsFilter = filter(['**/*.js'], {'restore': true}); + let cssFilter = filter(['**/*.css'], {'restore': true}); return gulp.src('.tmp/index.html') .pipe(jsFilter) @@ -203,12 +204,12 @@ gulp.task('build:html', ['dev:styles', 'dev:scripts', 'build:ngviews', 'build:in .pipe(useref()) .pipe(gulp.dest('lemur/static/dist')) .pipe(size()); -}); +})); -gulp.task('build:fonts', ['dev:fonts'], function () { +gulp.task('build:fonts', gulp.series(['dev:fonts'], function () { return gulp.src('.tmp/fonts/**/*') .pipe(gulp.dest('lemur/static/dist/fonts')); -}); +})); gulp.task('build:images', function () { return gulp.src('lemur/static/app/images/**/*') @@ -230,35 +231,28 @@ gulp.task('package:strip', function () { .pipe(size()); }); -gulp.task('addUrlContextPath',['addUrlContextPath:revreplace'], function(){ - var urlContextPathExists = argv.urlContextPath ? true : false; - ['lemur/static/dist/scripts/main*.js', - 'lemur/static/dist/angular/**/*.html'] - .forEach(function(file){ - return gulp.src(file) - .pipe(gulpif(urlContextPathExists, replace('api/', argv.urlContextPath + '/api/'))) - .pipe(gulpif(urlContextPathExists, replace('/angular/', '/' + argv.urlContextPath + '/angular/'))) - .pipe(gulp.dest(function(file){ - return file.base; - })) - }) -}); - gulp.task('addUrlContextPath:revision', function(){ return gulp.src(['lemur/static/dist/**/*.css','lemur/static/dist/**/*.js']) .pipe(rev()) .pipe(gulp.dest('lemur/static/dist')) .pipe(rev.manifest()) .pipe(gulp.dest('lemur/static/dist')) -}) +}); -gulp.task('addUrlContextPath:revreplace', ['addUrlContextPath:revision'], function(){ - var manifest = gulp.src("lemur/static/dist/rev-manifest.json"); - var urlContextPathExists = argv.urlContextPath ? true : false; +gulp.task('addUrlContextPath:revreplace', gulp.series(['addUrlContextPath:revision'], function(){ return gulp.src( "lemur/static/dist/index.html") .pipe(gulp.dest('lemur/static/dist')); -}) +})); +gulp.task('addUrlContextPath', gulp.series(['addUrlContextPath:revreplace'], function(){ + let urlContextPathExists = argv.urlContextPath ? true : false; + return gulp.src(['lemur/static/dist/scripts/main*.js', 'lemur/static/dist/angular/**/*.html']) + .pipe(gulpif(urlContextPathExists, replace('api/', argv.urlContextPath + '/api/'))) + .pipe(gulpif(urlContextPathExists, replace('/angular/', '/' + argv.urlContextPath + '/angular/'))) + .pipe(gulp.dest(function(file){ + return file.base; + })) +})); -gulp.task('build', ['build:ngviews', 'build:inject', 'build:images', 'build:fonts', 'build:html', 'build:extras']); -gulp.task('package', ['addUrlContextPath', 'package:strip']); +gulp.task('build', gulp.series(['build:images', 'build:fonts', 'build:html', 'build:extras'])); +gulp.task('package', gulp.series(['addUrlContextPath', 'package:strip'])); diff --git a/gulp/server.js b/gulp/server.js index 6c61273e..0c4af91a 100644 --- a/gulp/server.js +++ b/gulp/server.js @@ -1,6 +1,7 @@ 'use strict'; var gulp = require('gulp'); +const watch = require('./watch') var browserSync = require('browser-sync'); var httpProxy = require('http-proxy'); @@ -38,7 +39,7 @@ function browserSyncInit(baseDir, files, browser) { } -gulp.task('serve', ['watch'], function () { +gulp.task('serve', gulp.series(['watch'], function (done) { browserSyncInit([ '.tmp', 'lemur/static/app' @@ -51,9 +52,12 @@ gulp.task('serve', ['watch'], function () { 'lemur/static/app/angular/**/*', 'lemur/static/app/index.html' ]); -}); + + done(); +})); -gulp.task('serve:dist', ['build'], function () { +gulp.task('serve:dist', gulp.series(['build'], function (done) { browserSyncInit('lemur/static/dist'); -}); + done(); +})); diff --git a/gulp/watch.js b/gulp/watch.js index 460a935b..a406eea3 100644 --- a/gulp/watch.js +++ b/gulp/watch.js @@ -3,10 +3,13 @@ var gulp = require('gulp'); -gulp.task('watch', ['dev:styles', 'dev:scripts', 'dev:inject', 'dev:fonts'] ,function () { - gulp.watch('app/styles/**/*.less', ['dev:styles']); - gulp.watch('app/styles/**/*.css', ['dev:styles']); - gulp.watch('app/**/*.js', ['dev:scripts']); - gulp.watch('app/images/**/*', ['build:images']); - gulp.watch('bower.json', ['dev:inject']); -}); +const watch = gulp.task('watch', gulp.series(['dev:inject', 'dev:fonts'] ,function (done) { + gulp.watch('app/styles/**/*.less', gulp.series('dev:styles')); + gulp.watch('app/styles/**/*.css', gulp.series('dev:styles')); + gulp.watch('app/**/*.js', gulp.series('dev:scripts')); + gulp.watch('app/images/**/*', gulp.series('build:images')); + gulp.watch('bower.json', gulp.series('dev:inject')); + done(); +})); + +module.exports = {watch:watch} diff --git a/package.json b/package.json index 828f8899..f2d87ab7 100644 --- a/package.json +++ b/package.json @@ -58,7 +58,7 @@ "test": "gulp test" }, "devDependencies": { - "gulp": "^3.9.1", + "gulp": "^4.0.2", "jshint": "^2.11.0", "karma-chrome-launcher": "^2.0.0" } From 7de2257bf864ca3e379edaea72041944bdd16733 Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Mon, 11 Jan 2021 19:10:01 +0000 Subject: [PATCH 186/314] Bump sphinx-rtd-theme from 0.5.0 to 0.5.1 Bumps [sphinx-rtd-theme](https://github.com/readthedocs/sphinx_rtd_theme) from 0.5.0 to 0.5.1. - [Release notes](https://github.com/readthedocs/sphinx_rtd_theme/releases) - [Changelog](https://github.com/readthedocs/sphinx_rtd_theme/blob/master/docs/changelog.rst) - [Commits](https://github.com/readthedocs/sphinx_rtd_theme/compare/0.5.0...0.5.1) Signed-off-by: dependabot-preview[bot] --- requirements-docs.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements-docs.txt b/requirements-docs.txt index 73bb0277..ebf0edc0 100644 --- a/requirements-docs.txt +++ b/requirements-docs.txt @@ -20,7 +20,7 @@ pytz==2019.3 # via babel requests==2.25.1 # via sphinx six==1.15.0 # via packaging, sphinxcontrib-httpdomain snowballstemmer==2.0.0 # via sphinx -sphinx-rtd-theme==0.5.0 # via -r requirements-docs.in +sphinx-rtd-theme==0.5.1 # via -r requirements-docs.in sphinx==3.4.2 # via -r requirements-docs.in, sphinx-rtd-theme, sphinxcontrib-httpdomain sphinxcontrib-applehelp==1.0.2 # via sphinx sphinxcontrib-devhelp==1.0.2 # via sphinx From b04dc06109d186870f362d7e5274639ca37077c5 Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Mon, 11 Jan 2021 19:20:33 +0000 Subject: [PATCH 187/314] Bump sphinx from 3.4.2 to 3.4.3 Bumps [sphinx](https://github.com/sphinx-doc/sphinx) from 3.4.2 to 3.4.3. - [Release notes](https://github.com/sphinx-doc/sphinx/releases) - [Changelog](https://github.com/sphinx-doc/sphinx/blob/3.x/CHANGES) - [Commits](https://github.com/sphinx-doc/sphinx/compare/v3.4.2...v3.4.3) Signed-off-by: dependabot-preview[bot] --- requirements-docs.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements-docs.txt b/requirements-docs.txt index ebf0edc0..f5c94cea 100644 --- a/requirements-docs.txt +++ b/requirements-docs.txt @@ -21,7 +21,7 @@ requests==2.25.1 # via sphinx six==1.15.0 # via packaging, sphinxcontrib-httpdomain snowballstemmer==2.0.0 # via sphinx sphinx-rtd-theme==0.5.1 # via -r requirements-docs.in -sphinx==3.4.2 # via -r requirements-docs.in, sphinx-rtd-theme, sphinxcontrib-httpdomain +sphinx==3.4.3 # via -r requirements-docs.in, sphinx-rtd-theme, sphinxcontrib-httpdomain sphinxcontrib-applehelp==1.0.2 # via sphinx sphinxcontrib-devhelp==1.0.2 # via sphinx sphinxcontrib-htmlhelp==1.0.3 # via sphinx From 4eb5a2634634bc5811fc61625fe30f2d69faceef Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Mon, 11 Jan 2021 19:32:30 +0000 Subject: [PATCH 188/314] Bump pytest-mock from 3.5.0 to 3.5.1 Bumps [pytest-mock](https://github.com/pytest-dev/pytest-mock) from 3.5.0 to 3.5.1. - [Release notes](https://github.com/pytest-dev/pytest-mock/releases) - [Changelog](https://github.com/pytest-dev/pytest-mock/blob/master/CHANGELOG.rst) - [Commits](https://github.com/pytest-dev/pytest-mock/compare/v3.5.0...v3.5.1) Signed-off-by: dependabot-preview[bot] --- requirements-tests.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements-tests.txt b/requirements-tests.txt index d9fc4641..83c0c5f3 100644 --- a/requirements-tests.txt +++ b/requirements-tests.txt @@ -60,7 +60,7 @@ pyflakes==2.2.0 # via -r requirements-tests.in pyparsing==2.4.7 # via packaging pyrsistent==0.16.0 # via jsonschema pytest-flask==1.1.0 # via -r requirements-tests.in -pytest-mock==3.5.0 # via -r requirements-tests.in +pytest-mock==3.5.1 # via -r requirements-tests.in pytest==6.2.1 # via -r requirements-tests.in, pytest-flask, pytest-mock python-dateutil==2.8.1 # via botocore, faker, freezegun, moto python-jose[cryptography]==3.1.0 # via moto From bca995b1ff600d4124e04a410ff2009cea7ae447 Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Mon, 11 Jan 2021 19:44:23 +0000 Subject: [PATCH 189/314] Bump flask-cors from 3.0.9 to 3.0.10 Bumps [flask-cors](https://github.com/corydolphin/flask-cors) from 3.0.9 to 3.0.10. - [Release notes](https://github.com/corydolphin/flask-cors/releases) - [Changelog](https://github.com/corydolphin/flask-cors/blob/master/CHANGELOG.md) - [Commits](https://github.com/corydolphin/flask-cors/compare/3.0.9...3.0.10) Signed-off-by: dependabot-preview[bot] --- requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index 4c3f7593..48048994 100644 --- a/requirements.txt +++ b/requirements.txt @@ -29,7 +29,7 @@ dnspython3==1.15.0 # via -r requirements.in dnspython==1.15.0 # via dnspython3 dyn==1.8.1 # via -r requirements.in flask-bcrypt==0.7.1 # via -r requirements.in -flask-cors==3.0.9 # via -r requirements.in +flask-cors==3.0.10 # via -r requirements.in flask-mail==0.9.1 # via -r requirements.in flask-migrate==2.5.3 # via -r requirements.in flask-principal==0.4.0 # via -r requirements.in From aa8d5f097e12d30f9e96449d6a91a2b76137c868 Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Mon, 11 Jan 2021 19:56:28 +0000 Subject: [PATCH 190/314] Bump botocore from 1.19.49 to 1.19.51 Bumps [botocore](https://github.com/boto/botocore) from 1.19.49 to 1.19.51. - [Release notes](https://github.com/boto/botocore/releases) - [Changelog](https://github.com/boto/botocore/blob/develop/CHANGELOG.rst) - [Commits](https://github.com/boto/botocore/compare/1.19.49...1.19.51) Signed-off-by: dependabot-preview[bot] --- requirements-tests.txt | 2 +- requirements.txt | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/requirements-tests.txt b/requirements-tests.txt index 83c0c5f3..7980268a 100644 --- a/requirements-tests.txt +++ b/requirements-tests.txt @@ -12,7 +12,7 @@ bandit==1.7.0 # via -r requirements-tests.in black==20.8b1 # via -r requirements-tests.in boto3==1.16.49 # via aws-sam-translator, moto boto==2.49.0 # via moto -botocore==1.19.49 # via aws-xray-sdk, boto3, moto, s3transfer +botocore==1.19.51 # via aws-xray-sdk, boto3, moto, s3transfer certifi==2020.12.5 # via requests cffi==1.14.0 # via cryptography cfn-lint==0.29.5 # via moto diff --git a/requirements.txt b/requirements.txt index 48048994..79ebfdf0 100644 --- a/requirements.txt +++ b/requirements.txt @@ -16,7 +16,7 @@ beautifulsoup4==4.9.1 # via cloudflare billiard==3.6.3.0 # via celery blinker==1.4 # via flask-mail, flask-principal, raven boto3==1.16.49 # via -r requirements.in -botocore==1.19.49 # via -r requirements.in, boto3, s3transfer +botocore==1.19.51 # via -r requirements.in, boto3, s3transfer celery[redis]==4.4.2 # via -r requirements.in certifi==2020.12.5 # via -r requirements.in, requests certsrv==2.1.1 # via -r requirements.in From 3a5d9c212d6a311d3e9805c3905b00cd27421233 Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Mon, 11 Jan 2021 20:09:33 +0000 Subject: [PATCH 191/314] Bump boto3 from 1.16.49 to 1.16.51 Bumps [boto3](https://github.com/boto/boto3) from 1.16.49 to 1.16.51. - [Release notes](https://github.com/boto/boto3/releases) - [Changelog](https://github.com/boto/boto3/blob/develop/CHANGELOG.rst) - [Commits](https://github.com/boto/boto3/compare/1.16.49...1.16.51) Signed-off-by: dependabot-preview[bot] --- requirements-tests.txt | 2 +- requirements.txt | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/requirements-tests.txt b/requirements-tests.txt index 7980268a..02f996ca 100644 --- a/requirements-tests.txt +++ b/requirements-tests.txt @@ -10,7 +10,7 @@ aws-sam-translator==1.22.0 # via cfn-lint aws-xray-sdk==2.5.0 # via moto bandit==1.7.0 # via -r requirements-tests.in black==20.8b1 # via -r requirements-tests.in -boto3==1.16.49 # via aws-sam-translator, moto +boto3==1.16.51 # via aws-sam-translator, moto boto==2.49.0 # via moto botocore==1.19.51 # via aws-xray-sdk, boto3, moto, s3transfer certifi==2020.12.5 # via requests diff --git a/requirements.txt b/requirements.txt index 79ebfdf0..550a0279 100644 --- a/requirements.txt +++ b/requirements.txt @@ -15,7 +15,7 @@ bcrypt==3.1.7 # via flask-bcrypt, paramiko beautifulsoup4==4.9.1 # via cloudflare billiard==3.6.3.0 # via celery blinker==1.4 # via flask-mail, flask-principal, raven -boto3==1.16.49 # via -r requirements.in +boto3==1.16.51 # via -r requirements.in botocore==1.19.51 # via -r requirements.in, boto3, s3transfer celery[redis]==4.4.2 # via -r requirements.in certifi==2020.12.5 # via -r requirements.in, requests From dc2cbc055d009ad44e9c311096be3a696113166c Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Mon, 11 Jan 2021 20:19:12 +0000 Subject: [PATCH 192/314] Bump faker from 5.3.0 to 5.4.1 Bumps [faker](https://github.com/joke2k/faker) from 5.3.0 to 5.4.1. - [Release notes](https://github.com/joke2k/faker/releases) - [Changelog](https://github.com/joke2k/faker/blob/master/CHANGELOG.md) - [Commits](https://github.com/joke2k/faker/compare/v5.3.0...v5.4.1) Signed-off-by: dependabot-preview[bot] --- requirements-tests.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements-tests.txt b/requirements-tests.txt index 02f996ca..cb1365fb 100644 --- a/requirements-tests.txt +++ b/requirements-tests.txt @@ -24,7 +24,7 @@ decorator==4.4.2 # via networkx docker==4.2.0 # via moto ecdsa==0.14.1 # via moto, python-jose, sshpubkeys factory-boy==3.2.0 # via -r requirements-tests.in -faker==5.3.0 # via -r requirements-tests.in, factory-boy +faker==5.4.1 # via -r requirements-tests.in, factory-boy fakeredis==1.4.5 # via -r requirements-tests.in flask==1.1.2 # via pytest-flask freezegun==1.0.0 # via -r requirements-tests.in From 7343ea3433fc350bf014400199cfab542a7e36aa Mon Sep 17 00:00:00 2001 From: Jasmine Schladen Date: Wed, 13 Jan 2021 11:15:11 -0800 Subject: [PATCH 193/314] Update Docker docs --- docs/developer/index.rst | 18 +++++++++++++++--- docs/quickstart/index.rst | 4 ++-- 2 files changed, 17 insertions(+), 5 deletions(-) diff --git a/docs/developer/index.rst b/docs/developer/index.rst index bff53a96..8569dda5 100644 --- a/docs/developer/index.rst +++ b/docs/developer/index.rst @@ -48,7 +48,17 @@ Developing Against HEAD ----------------------- We try to make it easy to get up and running in a development environment using a git checkout -of Lemur. You'll want to make sure you have a few things on your local system first: +of Lemur. There are two ways to run Lemur locally: directly on your development machine, or +in a Docker container. + +**Running in a Docker container** + +Look at the `lemur-docker `_ project. +Usage instructions are self-contained in the README for that project. + +**Running directly on your development machine** + +You'll want to make sure you have a few things on your local system first: * python-dev (if you're on OS X, you already have this) * pip @@ -99,7 +109,9 @@ You'll likely want to make some changes to the default configuration (we recomme Running tests with Docker and docker-compose ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -Alternatively you can use Docker and docker-compose for running the tests with ``docker-compose run test``. +If you just want to run tests in a Docker container, you can use Docker and docker-compose for running the tests with ``docker-compose run test`` directly in the ``lemur`` project. + +(For running the Lemur service in Docker, see `lemur-docker `_.) Coding Standards @@ -152,7 +164,7 @@ You'll notice that the test suite is structured based on where the code lives, a Static Media ------------ -Lemur uses a library that compiles it's static media assets (LESS and JS files) automatically. If you're developing using +Lemur uses a library that compiles its static media assets (LESS and JS files) automatically. If you're developing using runserver you'll see changes happen not only in the original files, but also the minified or processed versions of the file. If you've made changes and need to compile them by hand for any reason, you can do so by running: diff --git a/docs/quickstart/index.rst b/docs/quickstart/index.rst index e0aef0d5..e2f3476f 100644 --- a/docs/quickstart/index.rst +++ b/docs/quickstart/index.rst @@ -3,7 +3,7 @@ Quickstart This guide will step you through setting up a Python-based virtualenv, installing the required packages, and configuring the basic web service. This guide assumes a clean Ubuntu 14.04 instance, commands may differ based on the OS and configuration being used. -Pressed for time? See the Lemur docker file on `Github `_. +For a quicker alternative, see the Lemur docker file on `Github `_. Dependencies @@ -16,7 +16,7 @@ Some basic prerequisites which you'll need in order to run Lemur: * PostgreSQL 9.4 or greater * Nginx -.. note:: Lemur was built with in AWS in mind. This means that things such as databases (RDS), mail (SES), and TLS (ELB), are largely handled for us. Lemur does **not** require AWS to function. Our guides and documentation try to be as generic as possible and are not intended to document every step of launching Lemur into a given environment. +.. note:: Lemur was built with AWS in mind. This means that things such as databases (RDS), mail (SES), and TLS (ELB), are largely handled for us. Lemur does **not** require AWS to function. Our guides and documentation try to be as generic as possible and are not intended to document every step of launching Lemur into a given environment. Installing Build Dependencies From 358f07b4c3adca7d7a8d8989e8d3c5e36e3405ab Mon Sep 17 00:00:00 2001 From: sayali Date: Fri, 15 Jan 2021 15:45:39 -0800 Subject: [PATCH 194/314] Select export type p12 for openssl --- .../static/app/angular/certificates/certificate/export.tpl.html | 1 + 1 file changed, 1 insertion(+) diff --git a/lemur/static/app/angular/certificates/certificate/export.tpl.html b/lemur/static/app/angular/certificates/certificate/export.tpl.html index 620c6585..67fc6a81 100644 --- a/lemur/static/app/angular/certificates/certificate/export.tpl.html +++ b/lemur/static/app/angular/certificates/certificate/export.tpl.html @@ -25,6 +25,7 @@ From f5cd7ecbd5fcc2f68c35933f03ff5885c0cfb3a6 Mon Sep 17 00:00:00 2001 From: Hossein Shafagh Date: Fri, 15 Jan 2021 16:35:47 -0800 Subject: [PATCH 195/314] adding rate limit for Enturst --- lemur/certificates/cli.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/lemur/certificates/cli.py b/lemur/certificates/cli.py index 1f288c70..d78f267a 100644 --- a/lemur/certificates/cli.py +++ b/lemur/certificates/cli.py @@ -11,6 +11,7 @@ from flask_principal import Identity, identity_changed from flask_script import Manager from sqlalchemy import or_ from tabulate import tabulate +from time import sleep from lemur import database from lemur.authorities.models import Authority @@ -761,7 +762,10 @@ def deactivate_entrust_certificates(): certificates = get_all_valid_certs(['entrust-issuer']) entrust_plugin = plugins.get('entrust-issuer') - for cert in certificates: + for index, cert in enumerate(certificates, start=1): + if (index % 10) == 0: + # Entrust enforces a 10 request per 30s rate limit + sleep(30) try: response = entrust_plugin.deactivate_certificate(cert) if response == 200: From 4afdc13b0362a5aa103fd3c99be2e2246db38cd8 Mon Sep 17 00:00:00 2001 From: Hossein Shafagh Date: Fri, 15 Jan 2021 16:44:05 -0800 Subject: [PATCH 196/314] adding config to use the default clientID --- lemur/plugins/lemur_entrust/plugin.py | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/lemur/plugins/lemur_entrust/plugin.py b/lemur/plugins/lemur_entrust/plugin.py index 903bd7a9..bc7a8689 100644 --- a/lemur/plugins/lemur_entrust/plugin.py +++ b/lemur/plugins/lemur_entrust/plugin.py @@ -80,7 +80,6 @@ def process_options(options, client_id): "eku": "SERVER_AND_CLIENT_AUTH", "certType": product_type, "certExpiryDate": validity_end, - # "keyType": "RSA", Entrust complaining about this parameter "tracking": tracking_data, "org": options.get("organization"), "clientId": client_id @@ -229,7 +228,11 @@ class EntrustIssuerPlugin(IssuerPlugin): except requests.exceptions.RequestException as e: raise Exception(f"Error for Getting Organization {e}") - client_id = get_client_id(response, issuer_options.get("organization")) + if current_app.config.get("ENTRUST_USE_DEFAULT_CLIENT_ID"): + # The ID of the primary client is 1. + client_id = 1 + else: + client_id = get_client_id(response, issuer_options.get("organization")) log_data = { "function": f"{__name__}.{sys._getframe().f_code.co_name}", "message": f"Organization id: {client_id}" From 45dfb1beb34f5a77d019d8c387417a498e23117b Mon Sep 17 00:00:00 2001 From: Hossein Shafagh Date: Fri, 15 Jan 2021 16:44:23 -0800 Subject: [PATCH 197/314] documentation --- docs/administration.rst | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/docs/administration.rst b/docs/administration.rst index 59611c0f..025b47b1 100644 --- a/docs/administration.rst +++ b/docs/administration.rst @@ -941,6 +941,12 @@ The following parameters have to be set in the configuration files. If there is a config variable ENTRUST_PRODUCT_ take the value as cert product name else default to "STANDARD_SSL". Refer to the API documentation for valid products names. +.. data:: ENTRUST_USE_DEFAULT_CLIENT_ID + :noindex: + + If set to True, Entrust will use the primary client ID of 1, which applies to most use-case. + Otherwise, Entrust will first lookup the clientId before ordering the certificate. + Verisign Issuer Plugin ~~~~~~~~~~~~~~~~~~~~~~ From fef7c7a907df30cc572e0e9cf1d488332c6581ab Mon Sep 17 00:00:00 2001 From: Hossein Shafagh Date: Fri, 15 Jan 2021 16:49:14 -0800 Subject: [PATCH 198/314] support for cross-signed subCA --- lemur/plugins/lemur_entrust/plugin.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/lemur/plugins/lemur_entrust/plugin.py b/lemur/plugins/lemur_entrust/plugin.py index 903bd7a9..cf7d2307 100644 --- a/lemur/plugins/lemur_entrust/plugin.py +++ b/lemur/plugins/lemur_entrust/plugin.py @@ -9,7 +9,7 @@ from lemur.constants import CRLReason from lemur.plugins import lemur_entrust as entrust from lemur.plugins.bases import IssuerPlugin, SourcePlugin from lemur.extensions import metrics -from lemur.common.utils import validate_conf +from lemur.common.utils import validate_conf, get_key_type_from_certificate def log_status_code(r, *args, **kwargs): @@ -251,6 +251,9 @@ class EntrustIssuerPlugin(IssuerPlugin): else: chain = response_dict['chainCerts'][1] + if current_app.config.get("ENTRUST_CROSS_SIGNED_RSA") and get_key_type_from_certificate(cert) == "RSA2048": + chain = current_app.config.get("ENTRUST_CROSS_SIGNED_RSA") + log_data["message"] = "Received Chain" log_data["options"] = f"chain: {chain}" current_app.logger.info(log_data) From 685cea47683fcccc4152accb1a865494f5c0bb7f Mon Sep 17 00:00:00 2001 From: Hossein Shafagh Date: Fri, 15 Jan 2021 16:51:24 -0800 Subject: [PATCH 199/314] documentation --- docs/administration.rst | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/docs/administration.rst b/docs/administration.rst index 59611c0f..818a24c4 100644 --- a/docs/administration.rst +++ b/docs/administration.rst @@ -941,6 +941,12 @@ The following parameters have to be set in the configuration files. If there is a config variable ENTRUST_PRODUCT_ take the value as cert product name else default to "STANDARD_SSL". Refer to the API documentation for valid products names. +.. data:: ENTRUST_CROSS_SIGNED_RSA + :noindex: + + This is optional. Entrut provides support for cross-signed subCAS. One can set ENTRUST_CROSS_SIGNED_RSA to the respective cross-signed subCA PEM, such as L1K, Lemur will replace the retrieved subCA with ENTRUST_CROSS_SIGNED_RSA. + + Verisign Issuer Plugin ~~~~~~~~~~~~~~~~~~~~~~ From d914d37e6b04fdc849732cdbbff82c1d8eae7fd4 Mon Sep 17 00:00:00 2001 From: Hossein Shafagh Date: Fri, 15 Jan 2021 16:52:32 -0800 Subject: [PATCH 200/314] typo --- docs/administration.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/administration.rst b/docs/administration.rst index 818a24c4..15cff1f8 100644 --- a/docs/administration.rst +++ b/docs/administration.rst @@ -944,7 +944,7 @@ The following parameters have to be set in the configuration files. .. data:: ENTRUST_CROSS_SIGNED_RSA :noindex: - This is optional. Entrut provides support for cross-signed subCAS. One can set ENTRUST_CROSS_SIGNED_RSA to the respective cross-signed subCA PEM, such as L1K, Lemur will replace the retrieved subCA with ENTRUST_CROSS_SIGNED_RSA. + This is optional. Entrust provides support for cross-signed subCAS. One can set ENTRUST_CROSS_SIGNED_RSA to the respective cross-signed subCA PEM, such as L1K, Lemur will replace the retrieved subCA with ENTRUST_CROSS_SIGNED_RSA. Verisign Issuer Plugin From a62a562a61e597317bf1078645042c608aa3fe21 Mon Sep 17 00:00:00 2001 From: Hossein Shafagh Date: Fri, 15 Jan 2021 17:17:56 -0800 Subject: [PATCH 201/314] Update cli.py correct index begin --- lemur/certificates/cli.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lemur/certificates/cli.py b/lemur/certificates/cli.py index d78f267a..4b4b22e9 100644 --- a/lemur/certificates/cli.py +++ b/lemur/certificates/cli.py @@ -762,7 +762,7 @@ def deactivate_entrust_certificates(): certificates = get_all_valid_certs(['entrust-issuer']) entrust_plugin = plugins.get('entrust-issuer') - for index, cert in enumerate(certificates, start=1): + for index, cert in enumerate(certificates): if (index % 10) == 0: # Entrust enforces a 10 request per 30s rate limit sleep(30) From ca40dd4cd9c80c4c44011cdbda61e254ec2f90c4 Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Mon, 18 Jan 2021 13:31:51 +0000 Subject: [PATCH 202/314] Bump boto3 from 1.16.51 to 1.16.56 Bumps [boto3](https://github.com/boto/boto3) from 1.16.51 to 1.16.56. - [Release notes](https://github.com/boto/boto3/releases) - [Changelog](https://github.com/boto/boto3/blob/develop/CHANGELOG.rst) - [Commits](https://github.com/boto/boto3/compare/1.16.51...1.16.56) Signed-off-by: dependabot-preview[bot] --- requirements-tests.txt | 4 ++-- requirements.txt | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/requirements-tests.txt b/requirements-tests.txt index cb1365fb..4ef8ff41 100644 --- a/requirements-tests.txt +++ b/requirements-tests.txt @@ -10,9 +10,9 @@ aws-sam-translator==1.22.0 # via cfn-lint aws-xray-sdk==2.5.0 # via moto bandit==1.7.0 # via -r requirements-tests.in black==20.8b1 # via -r requirements-tests.in -boto3==1.16.51 # via aws-sam-translator, moto +boto3==1.16.56 # via aws-sam-translator, moto boto==2.49.0 # via moto -botocore==1.19.51 # via aws-xray-sdk, boto3, moto, s3transfer +botocore==1.19.56 # via aws-xray-sdk, boto3, moto, s3transfer certifi==2020.12.5 # via requests cffi==1.14.0 # via cryptography cfn-lint==0.29.5 # via moto diff --git a/requirements.txt b/requirements.txt index 550a0279..98690794 100644 --- a/requirements.txt +++ b/requirements.txt @@ -15,8 +15,8 @@ bcrypt==3.1.7 # via flask-bcrypt, paramiko beautifulsoup4==4.9.1 # via cloudflare billiard==3.6.3.0 # via celery blinker==1.4 # via flask-mail, flask-principal, raven -boto3==1.16.51 # via -r requirements.in -botocore==1.19.51 # via -r requirements.in, boto3, s3transfer +boto3==1.16.56 # via -r requirements.in +botocore==1.19.56 # via -r requirements.in, boto3, s3transfer celery[redis]==4.4.2 # via -r requirements.in certifi==2020.12.5 # via -r requirements.in, requests certsrv==2.1.1 # via -r requirements.in From 3df63469e623ba23057679f2aff6e61bd1b57a64 Mon Sep 17 00:00:00 2001 From: Hossein Shafagh Date: Mon, 18 Jan 2021 11:57:49 -0800 Subject: [PATCH 203/314] retry --- lemur/plugins/lemur_entrust/plugin.py | 1 + 1 file changed, 1 insertion(+) diff --git a/lemur/plugins/lemur_entrust/plugin.py b/lemur/plugins/lemur_entrust/plugin.py index bc7a8689..422bd4fb 100644 --- a/lemur/plugins/lemur_entrust/plugin.py +++ b/lemur/plugins/lemur_entrust/plugin.py @@ -87,6 +87,7 @@ def process_options(options, client_id): return data +@retry(stop_max_attempt_number=5, wait_fixed=1000) def get_client_id(my_response, organization): """ Helper function for parsing responses from the Entrust API. From 09a5b256fba50b2ea6232f8786ea266298a9e20d Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Mon, 18 Jan 2021 20:29:37 +0000 Subject: [PATCH 204/314] Bump faker from 5.4.1 to 5.6.1 Bumps [faker](https://github.com/joke2k/faker) from 5.4.1 to 5.6.1. - [Release notes](https://github.com/joke2k/faker/releases) - [Changelog](https://github.com/joke2k/faker/blob/master/CHANGELOG.md) - [Commits](https://github.com/joke2k/faker/compare/v5.4.1...v5.6.1) Signed-off-by: dependabot-preview[bot] --- requirements-tests.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements-tests.txt b/requirements-tests.txt index 4ef8ff41..6ee2eed2 100644 --- a/requirements-tests.txt +++ b/requirements-tests.txt @@ -24,7 +24,7 @@ decorator==4.4.2 # via networkx docker==4.2.0 # via moto ecdsa==0.14.1 # via moto, python-jose, sshpubkeys factory-boy==3.2.0 # via -r requirements-tests.in -faker==5.4.1 # via -r requirements-tests.in, factory-boy +faker==5.6.1 # via -r requirements-tests.in, factory-boy fakeredis==1.4.5 # via -r requirements-tests.in flask==1.1.2 # via pytest-flask freezegun==1.0.0 # via -r requirements-tests.in From e6a414a069d819b2cc593de7f9f2ad999239b219 Mon Sep 17 00:00:00 2001 From: Hossein Shafagh Date: Mon, 18 Jan 2021 14:04:01 -0800 Subject: [PATCH 205/314] moving clientID logic into the respective method, that we want to bypass. --- lemur/plugins/lemur_entrust/plugin.py | 34 +++++++++++++++------------ 1 file changed, 19 insertions(+), 15 deletions(-) diff --git a/lemur/plugins/lemur_entrust/plugin.py b/lemur/plugins/lemur_entrust/plugin.py index 422bd4fb..1efc350e 100644 --- a/lemur/plugins/lemur_entrust/plugin.py +++ b/lemur/plugins/lemur_entrust/plugin.py @@ -88,14 +88,27 @@ def process_options(options, client_id): @retry(stop_max_attempt_number=5, wait_fixed=1000) -def get_client_id(my_response, organization): +def get_client_id(session, organization): """ - Helper function for parsing responses from the Entrust API. - :param content: - :return: :raise Exception: + Helper function for looking up clientID pased on Organization and parsing the response. + :param session: + :param organization: the validated org with Entrust, for instance "Company, Inc." + :return: ClientID + :raise Exception: """ + + # get the organization ID + url = current_app.config.get("ENTRUST_URL") + "/organizations" try: - d = json.loads(my_response.content) + response = session.get(url, timeout=(15, 40)) + except requests.exceptions.Timeout: + raise Exception("Timeout for Getting Organizations") + except requests.exceptions.RequestException as e: + raise Exception(f"Error for Getting Organization {e}") + + # parse the response + try: + d = json.loads(response.content) except ValueError: # catch an empty json object here d = {'response': 'No detailed message'} @@ -220,20 +233,11 @@ class EntrustIssuerPlugin(IssuerPlugin): } current_app.logger.info(log_data) - # firstly we need the organization ID - url = current_app.config.get("ENTRUST_URL") + "/organizations" - try: - response = self.session.get(url, timeout=(15, 40)) - except requests.exceptions.Timeout: - raise Exception("Timeout for Getting Organizations") - except requests.exceptions.RequestException as e: - raise Exception(f"Error for Getting Organization {e}") - if current_app.config.get("ENTRUST_USE_DEFAULT_CLIENT_ID"): # The ID of the primary client is 1. client_id = 1 else: - client_id = get_client_id(response, issuer_options.get("organization")) + client_id = get_client_id(self.session, issuer_options.get("organization")) log_data = { "function": f"{__name__}.{sys._getframe().f_code.co_name}", "message": f"Organization id: {client_id}" From d5d89ec757ee4226b9de9e009c37d12559822441 Mon Sep 17 00:00:00 2001 From: sayali Date: Wed, 20 Jan 2021 12:00:58 -0800 Subject: [PATCH 206/314] Return empty result instead of 500 if page number exceeds total Removed current since it was not returned by lemur and it's easy to determine --- lemur/database.py | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/lemur/database.py b/lemur/database.py index 0453c381..2ba5cddd 100644 --- a/lemur/database.py +++ b/lemur/database.py @@ -9,6 +9,7 @@ .. moduleauthor:: Kevin Glisson """ +import math from inflection import underscore from sqlalchemy import exc, func, distinct from sqlalchemy.orm import make_transient, lazyload @@ -219,15 +220,20 @@ def sort(query, model, field, direction): def paginate(query, page, count): """ - Returns the items given the count and page specified + Returns the items given the count and page specified. The items would be an empty list + if page number exceeds max page number based on count per page and total number of records. - :param query: - :param page: - :param count: + :param query: search query + :param page: current page number + :param count: results per page """ total = get_count(query) + # Check if input page is higher than total number of pages based on count per page and total + # In such a case Flask-SQLAlchemy pagination call results in 404 + if math.ceil(total / count) < page: + return dict(items=[], total=total) items = query.paginate(page, count).items - return dict(items=items, total=total, current=len(items)) + return dict(items=items, total=total) def update_list(model, model_attr, item_model, items): From 7add8ab40851f26acde509b2edce8f9f41eff757 Mon Sep 17 00:00:00 2001 From: manager Date: Tue, 26 Jan 2021 10:32:26 +0300 Subject: [PATCH 207/314] multiple fixes docker alpine build --- docker/Dockerfile | 10 +- docker/docker-compose.yml | 21 ++-- docker/entrypoint | 4 +- docker/src/lemur.conf.py | 231 +++++++++++++++++++++++++++++++++----- 4 files changed, 224 insertions(+), 42 deletions(-) diff --git a/docker/Dockerfile b/docker/Dockerfile index d12c55ee..b79e2576 100644 --- a/docker/Dockerfile +++ b/docker/Dockerfile @@ -1,4 +1,4 @@ -FROM alpine:3.8 +FROM python:3.7.9-alpine3.12 ARG VERSION ENV VERSION master @@ -12,7 +12,7 @@ ENV group lemur RUN addgroup -S ${group} -g ${gid} && \ adduser -D -S ${user} -G ${group} -u ${uid} && \ - apk --update add python3 libldap postgresql-client nginx supervisor curl tzdata openssl bash && \ + apk add --no-cache --update python3 py-pip libldap postgresql-client nginx supervisor curl tzdata openssl bash && \ apk --update add --virtual build-dependencies \ git \ tar \ @@ -39,10 +39,12 @@ RUN addgroup -S ${group} -g ${gid} && \ pip3 install --upgrade setuptools && \ mkdir -p /run/nginx/ /etc/nginx/ssl/ && \ chown -R $user:$group /opt/lemur/ /home/lemur/.lemur/ - + WORKDIR /opt/lemur -RUN npm install --unsafe-perm && \ +RUN echo "Running with python:" && python -c 'import platform; print(platform.python_version())' && \ + echo "Running with nodejs:" && node -v && \ + npm install --unsafe-perm && \ pip3 install -e . && \ node_modules/.bin/gulp build && \ node_modules/.bin/gulp package --urlContextPath=${URLCONTEXT} && \ diff --git a/docker/docker-compose.yml b/docker/docker-compose.yml index 77293f43..acf0c761 100644 --- a/docker/docker-compose.yml +++ b/docker/docker-compose.yml @@ -1,9 +1,12 @@ version: '3' +volumes: + pg_data: { } + services: postgres: - image: "postgres:10" - restart: always + image: "postgres:13.1-alpine" + restart: on-failure volumes: - pg_data:/var/lib/postgresql/data env_file: @@ -11,7 +14,9 @@ services: lemur: # image: "netlix-lemur:latest" - build: . + restart: on-failure + build: + context: . depends_on: - postgres - redis @@ -19,11 +24,9 @@ services: - lemur-env - pgsql-env ports: - - 80:80 - - 443:443 + - 87:80 + - 447:443 redis: - image: "redis:alpine" - -volumes: - pg_data: {} + image: "redis:alpine3.12" + restart: on-failure diff --git a/docker/entrypoint b/docker/entrypoint index 3f25951a..8e15acb9 100644 --- a/docker/entrypoint +++ b/docker/entrypoint @@ -14,10 +14,10 @@ export LEMUR_ADMIN_PASSWORD="${LEMUR_ADMIN_PASSWORD:-admin}" export SQLALCHEMY_DATABASE_URI="postgresql://$POSTGRES_USER:$POSTGRES_PASSWORD@$POSTGRES_HOST:$POSTGRES_PORT/$POSTGRES_DB" -PGPASSWORD=$POSTGRES_PASSWORD psql -h $POSTGRES_HOST -p $POSTGRES_PORT -U $POSTGRES_USER -d $POSTGRES_DB --command 'select 1;' +PGPASSWORD=$POSTGRES_PASSWORD psql -h "$POSTGRES_HOST" -p "$POSTGRES_PORT" -U "$POSTGRES_USER" -d "$POSTGRES_DB" --command 'select 1;' echo " # Create Postgres trgm extension" -PGPASSWORD=$POSTGRES_PASSWORD psql -h $POSTGRES_HOST -p $POSTGRES_PORT -U $POSTGRES_USER -d $POSTGRES_DB --command 'CREATE EXTENSION IF NOT EXISTS pg_trgm;' +PGPASSWORD=$POSTGRES_PASSWORD psql -h "$POSTGRES_HOST" -p "$POSTGRES_PORT" -U "$POSTGRES_USER" -d "$POSTGRES_DB" --command 'CREATE EXTENSION IF NOT EXISTS pg_trgm;' echo " # Done" if [ -z "${SKIP_SSL}" ]; then diff --git a/docker/src/lemur.conf.py b/docker/src/lemur.conf.py index 4bcaeef9..c814c756 100644 --- a/docker/src/lemur.conf.py +++ b/docker/src/lemur.conf.py @@ -1,11 +1,18 @@ -import os +import os.path import random import string +from celery.schedules import crontab + import base64 -from ast import literal_eval _basedir = os.path.abspath(os.path.dirname(__file__)) +# See the Lemur docs (https://lemur.readthedocs.org) for more information on configuration + +LOG_LEVEL = str(os.environ.get('LOG_LEVEL', 'DEBUG')) +LOG_FILE = str(os.environ.get('LOG_FILE', '/home/lemur/.lemur/lemur.log')) +LOG_JSON = True + CORS = os.environ.get("CORS") == "True" debug = os.environ.get("DEBUG") == "True" @@ -17,44 +24,214 @@ def get_random_secret(length): return secret_key + ''.join(random.choice(string.digits) for x in range(round(length / 4))) +# This is the secret key used by Flask session management SECRET_KEY = repr(os.environ.get('SECRET_KEY', get_random_secret(32).encode('utf8'))) +# You should consider storing these separately from your config LEMUR_TOKEN_SECRET = repr(os.environ.get('LEMUR_TOKEN_SECRET', base64.b64encode(get_random_secret(32).encode('utf8')))) +# This must match the key for whichever DB the container is using - this could be a dump of dev or test, or a unique key LEMUR_ENCRYPTION_KEYS = repr(os.environ.get('LEMUR_ENCRYPTION_KEYS', - base64.b64encode(get_random_secret(32).encode('utf8')))) + base64.b64encode(get_random_secret(32).encode('utf8')).decode('utf8'))) -LEMUR_ALLOWED_DOMAINS = [] +REDIS_HOST = 'redis' +REDIS_PORT = 6379 +REDIS_DB = 0 +CELERY_RESULT_BACKEND = f'redis://{REDIS_HOST}:{REDIS_PORT}' +CELERY_BROKER_URL = f'redis://{REDIS_HOST}:{REDIS_PORT}' +CELERY_IMPORTS = ('lemur.common.celery') +CELERYBEAT_SCHEDULE = { + # All tasks are disabled by default. Enable any tasks you wish to run. + # 'fetch_all_pending_acme_certs': { + # 'task': 'lemur.common.celery.fetch_all_pending_acme_certs', + # 'options': { + # 'expires': 180 + # }, + # 'schedule': crontab(minute="*"), + # }, + # 'remove_old_acme_certs': { + # 'task': 'lemur.common.celery.remove_old_acme_certs', + # 'options': { + # 'expires': 180 + # }, + # 'schedule': crontab(hour=8, minute=0, day_of_week=5), + # }, + # 'clean_all_sources': { + # 'task': 'lemur.common.celery.clean_all_sources', + # 'options': { + # 'expires': 180 + # }, + # 'schedule': crontab(hour=5, minute=0, day_of_week=5), + # }, + # 'sync_all_sources': { + # 'task': 'lemur.common.celery.sync_all_sources', + # 'options': { + # 'expires': 180 + # }, + # 'schedule': crontab(hour="*/2", minute=0), + # # this job is running 30min before endpoints_expire which deletes endpoints which were not updated + # }, + # 'sync_source_destination': { + # 'task': 'lemur.common.celery.sync_source_destination', + # 'options': { + # 'expires': 180 + # }, + # 'schedule': crontab(hour="*/2", minute=15), + # }, + # 'report_celery_last_success_metrics': { + # 'task': 'lemur.common.celery.report_celery_last_success_metrics', + # 'options': { + # 'expires': 180 + # }, + # 'schedule': crontab(minute="*"), + # }, + # 'certificate_reissue': { + # 'task': 'lemur.common.celery.certificate_reissue', + # 'options': { + # 'expires': 180 + # }, + # 'schedule': crontab(hour=9, minute=0), + # }, + # 'certificate_rotate': { + # 'task': 'lemur.common.celery.certificate_rotate', + # 'options': { + # 'expires': 180 + # }, + # 'schedule': crontab(hour=10, minute=0), + # }, + # 'endpoints_expire': { + # 'task': 'lemur.common.celery.endpoints_expire', + # 'options': { + # 'expires': 180 + # }, + # 'schedule': crontab(hour="*/2", minute=30), + # # this job is running 30min after sync_all_sources which updates endpoints + # }, + # 'get_all_zones': { + # 'task': 'lemur.common.celery.get_all_zones', + # 'options': { + # 'expires': 180 + # }, + # 'schedule': crontab(minute="*/30"), + # }, + # 'check_revoked': { + # 'task': 'lemur.common.celery.check_revoked', + # 'options': { + # 'expires': 180 + # }, + # 'schedule': crontab(hour=10, minute=0), + # } + # 'enable_autorotate_for_certs_attached_to_endpoint': { + # 'task': 'lemur.common.celery.enable_autorotate_for_certs_attached_to_endpoint', + # 'options': { + # 'expires': 180 + # }, + # 'schedule': crontab(hour=10, minute=0), + # } + # 'notify_expirations': { + # 'task': 'lemur.common.celery.notify_expirations', + # 'options': { + # 'expires': 180 + # }, + # 'schedule': crontab(hour=10, minute=0), + # }, + # 'notify_authority_expirations': { + # 'task': 'lemur.common.celery.notify_authority_expirations', + # 'options': { + # 'expires': 180 + # }, + # 'schedule': crontab(hour=10, minute=0), + # }, + # 'send_security_expiration_summary': { + # 'task': 'lemur.common.celery.send_security_expiration_summary', + # 'options': { + # 'expires': 180 + # }, + # 'schedule': crontab(hour=10, minute=0, day_of_week='mon-fri'), + # } +} +CELERY_TIMEZONE = 'UTC' -LEMUR_EMAIL = '' -LEMUR_SECURITY_TEAM_EMAIL = [] +SQLALCHEMY_ENABLE_FLASK_REPLICATED = False +SQLALCHEMY_DATABASE_URI = os.environ.get('SQLALCHEMY_DATABASE_URI', 'postgresql://lemur:lemur@localhost:5432/lemur') -ALLOW_CERT_DELETION = os.environ.get('ALLOW_CERT_DELETION') == "True" +SQLALCHEMY_TRACK_MODIFICATIONS = False +SQLALCHEMY_ECHO = True +SQLALCHEMY_POOL_RECYCLE = 499 +SQLALCHEMY_POOL_TIMEOUT = 20 -LEMUR_DEFAULT_COUNTRY = str(os.environ.get('LEMUR_DEFAULT_COUNTRY','')) -LEMUR_DEFAULT_STATE = str(os.environ.get('LEMUR_DEFAULT_STATE','')) -LEMUR_DEFAULT_LOCATION = str(os.environ.get('LEMUR_DEFAULT_LOCATION','')) -LEMUR_DEFAULT_ORGANIZATION = str(os.environ.get('LEMUR_DEFAULT_ORGANIZATION','')) -LEMUR_DEFAULT_ORGANIZATIONAL_UNIT = str(os.environ.get('LEMUR_DEFAULT_ORGANIZATIONAL_UNIT','')) +LEMUR_EMAIL = 'lemur@example.com' +LEMUR_SECURITY_TEAM_EMAIL = ['security@example.com'] +LEMUR_SECURITY_TEAM_EMAIL_INTERVALS = [15, 2] +LEMUR_DEFAULT_EXPIRATION_NOTIFICATION_INTERVALS = [30, 15, 2] +LEMUR_EMAIL_SENDER = 'smtp' -LEMUR_DEFAULT_ISSUER_PLUGIN = str(os.environ.get('LEMUR_DEFAULT_ISSUER_PLUGIN','')) -LEMUR_DEFAULT_AUTHORITY = str(os.environ.get('LEMUR_DEFAULT_AUTHORITY','')) +# mail configuration +# MAIL_SERVER = 'mail.example.com' + +PUBLIC_CA_MAX_VALIDITY_DAYS = 397 +DEFAULT_VALIDITY_DAYS = 365 + +LEMUR_OWNER_EMAIL_IN_SUBJECT = False + +LEMUR_DEFAULT_COUNTRY = str(os.environ.get('LEMUR_DEFAULT_COUNTRY', 'US')) +LEMUR_DEFAULT_STATE = str(os.environ.get('LEMUR_DEFAULT_STATE', 'California')) +LEMUR_DEFAULT_LOCATION = str(os.environ.get('LEMUR_DEFAULT_LOCATION', 'Los Gatos')) +LEMUR_DEFAULT_ORGANIZATION = str(os.environ.get('LEMUR_DEFAULT_ORGANIZATION', 'Example, Inc.')) +LEMUR_DEFAULT_ORGANIZATIONAL_UNIT = str(os.environ.get('LEMUR_DEFAULT_ORGANIZATIONAL_UNIT', '')) + +LEMUR_DEFAULT_AUTHORITY = str(os.environ.get('LEMUR_DEFAULT_AUTHORITY', 'ExampleCa')) + +LEMUR_DEFAULT_ROLE = 'operator' ACTIVE_PROVIDERS = [] - METRIC_PROVIDERS = [] -LOG_LEVEL = str(os.environ.get('LOG_LEVEL','DEBUG')) -LOG_FILE = str(os.environ.get('LOG_FILE','/home/lemur/.lemur/lemur.log')) +# Authority Settings - These will change depending on which authorities you are +# using +current_path = os.path.dirname(os.path.realpath(__file__)) -SQLALCHEMY_DATABASE_URI = os.environ.get('SQLALCHEMY_DATABASE_URI','postgresql://lemur:lemur@localhost:5432/lemur') +# DNS Settings -LDAP_DEBUG = os.environ.get('LDAP_DEBUG') == "True" -LDAP_AUTH = os.environ.get('LDAP_AUTH') == "True" -LDAP_IS_ACTIVE_DIRECTORY = os.environ.get('LDAP_IS_ACTIVE_DIRECTORY') == "True" -LDAP_BIND_URI = str(os.environ.get('LDAP_BIND_URI','')) -LDAP_BASE_DN = str(os.environ.get('LDAP_BASE_DN','')) -LDAP_EMAIL_DOMAIN = str(os.environ.get('LDAP_EMAIL_DOMAIN','')) -LDAP_USE_TLS = str(os.environ.get('LDAP_USE_TLS','')) -LDAP_REQUIRED_GROUP = str(os.environ.get('LDAP_REQUIRED_GROUP','')) -LDAP_GROUPS_TO_ROLES = literal_eval(os.environ.get('LDAP_GROUPS_TO_ROLES') or "{}") +# exclude logging missing SAN, since we can have certs from private CAs with only cn, prod parity +LOG_SSL_SUBJ_ALT_NAME_ERRORS = False + +ACME_DNS_PROVIDER_TYPES = {"items": [ + { + 'name': 'route53', + 'requirements': [ + { + 'name': 'account_id', + 'type': 'int', + 'required': True, + 'helpMessage': 'AWS Account number' + }, + ] + }, + { + 'name': 'cloudflare', + 'requirements': [ + { + 'name': 'email', + 'type': 'str', + 'required': True, + 'helpMessage': 'Cloudflare Email' + }, + { + 'name': 'key', + 'type': 'str', + 'required': True, + 'helpMessage': 'Cloudflare Key' + }, + ] + }, + { + 'name': 'dyn', + }, + { + 'name': 'ultradns', + }, +]} + +# Authority plugins which support revocation +SUPPORTED_REVOCATION_AUTHORITY_PLUGINS = ['acme-issuer'] From 5c15e1690d32559b27eb07a9fe1948988364c546 Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Tue, 26 Jan 2021 22:48:40 +0000 Subject: [PATCH 208/314] Bump boto3 from 1.16.56 to 1.16.60 Bumps [boto3](https://github.com/boto/boto3) from 1.16.56 to 1.16.60. - [Release notes](https://github.com/boto/boto3/releases) - [Changelog](https://github.com/boto/boto3/blob/develop/CHANGELOG.rst) - [Commits](https://github.com/boto/boto3/compare/1.16.56...1.16.60) Signed-off-by: dependabot-preview[bot] --- requirements-tests.txt | 323 +++++++++++++++++++++++++++---------- requirements.txt | 350 +++++++++++++++++++++++++++++++---------- 2 files changed, 502 insertions(+), 171 deletions(-) diff --git a/requirements-tests.txt b/requirements-tests.txt index 6ee2eed2..e0dea764 100644 --- a/requirements-tests.txt +++ b/requirements-tests.txt @@ -4,90 +4,245 @@ # # pip-compile --no-index --output-file=requirements-tests.txt requirements-tests.in # -appdirs==1.4.3 # via black -attrs==19.3.0 # via jsonschema, pytest -aws-sam-translator==1.22.0 # via cfn-lint -aws-xray-sdk==2.5.0 # via moto -bandit==1.7.0 # via -r requirements-tests.in -black==20.8b1 # via -r requirements-tests.in -boto3==1.16.56 # via aws-sam-translator, moto -boto==2.49.0 # via moto -botocore==1.19.56 # via aws-xray-sdk, boto3, moto, s3transfer -certifi==2020.12.5 # via requests -cffi==1.14.0 # via cryptography -cfn-lint==0.29.5 # via moto -chardet==3.0.4 # via requests -click==7.1.2 # via black, flask -coverage==5.3.1 # via -r requirements-tests.in -cryptography==3.3.1 # via moto, python-jose, sshpubkeys -decorator==4.4.2 # via networkx -docker==4.2.0 # via moto -ecdsa==0.14.1 # via moto, python-jose, sshpubkeys -factory-boy==3.2.0 # via -r requirements-tests.in -faker==5.6.1 # via -r requirements-tests.in, factory-boy -fakeredis==1.4.5 # via -r requirements-tests.in -flask==1.1.2 # via pytest-flask -freezegun==1.0.0 # via -r requirements-tests.in -future==0.18.2 # via aws-xray-sdk -gitdb==4.0.4 # via gitpython -gitpython==3.1.1 # via bandit -idna==2.9 # via moto, requests -importlib-metadata==1.6.0 # via jsonpickle -iniconfig==1.0.1 # via pytest -itsdangerous==1.1.0 # via flask -jinja2==2.11.2 # via flask, moto -jmespath==0.9.5 # via boto3, botocore -jsondiff==1.1.2 # via moto -jsonpatch==1.25 # via cfn-lint -jsonpickle==1.4 # via aws-xray-sdk -jsonpointer==2.0 # via jsonpatch -jsonschema==3.2.0 # via aws-sam-translator, cfn-lint -markupsafe==1.1.1 # via jinja2, moto -mock==4.0.2 # via moto -more-itertools==8.2.0 # via moto -moto==1.3.16 # via -r requirements-tests.in -mypy-extensions==0.4.3 # via black -networkx==2.4 # via cfn-lint -nose==1.3.7 # via -r requirements-tests.in -packaging==20.3 # via pytest -pathspec==0.8.0 # via black -pbr==5.4.5 # via stevedore -pluggy==0.13.1 # via pytest -py==1.9.0 # via pytest -pyasn1==0.4.8 # via python-jose, rsa -pycparser==2.20 # via cffi -pyflakes==2.2.0 # via -r requirements-tests.in -pyparsing==2.4.7 # via packaging -pyrsistent==0.16.0 # via jsonschema -pytest-flask==1.1.0 # via -r requirements-tests.in -pytest-mock==3.5.1 # via -r requirements-tests.in -pytest==6.2.1 # via -r requirements-tests.in, pytest-flask, pytest-mock -python-dateutil==2.8.1 # via botocore, faker, freezegun, moto -python-jose[cryptography]==3.1.0 # via moto -pytz==2019.3 # via moto -pyyaml==5.3.1 # via -r requirements-tests.in, bandit, cfn-lint, moto -redis==3.5.3 # via fakeredis -regex==2020.4.4 # via black -requests-mock==1.8.0 # via -r requirements-tests.in -requests==2.25.1 # via docker, moto, requests-mock, responses -responses==0.10.12 # via moto -rsa==4.0 # via python-jose -s3transfer==0.3.3 # via boto3 -six==1.15.0 # via aws-sam-translator, bandit, cfn-lint, cryptography, docker, ecdsa, fakeredis, jsonschema, moto, packaging, pyrsistent, python-dateutil, python-jose, requests-mock, responses, stevedore, websocket-client -smmap==3.0.2 # via gitdb -sortedcontainers==2.1.0 # via fakeredis -sshpubkeys==3.1.0 # via moto -stevedore==1.32.0 # via bandit -text-unidecode==1.3 # via faker -toml==0.10.1 # via black, pytest -typed-ast==1.4.1 # via black -typing-extensions==3.7.4.3 # via black -urllib3==1.25.8 # via botocore, requests -websocket-client==0.57.0 # via docker -werkzeug==1.0.1 # via flask, moto, pytest-flask -wrapt==1.12.1 # via aws-xray-sdk -xmltodict==0.12.0 # via moto -zipp==3.1.0 # via importlib-metadata, moto +appdirs==1.4.3 + # via black +attrs==19.3.0 + # via + # jsonschema + # pytest +aws-sam-translator==1.22.0 + # via cfn-lint +aws-xray-sdk==2.5.0 + # via moto +bandit==1.7.0 + # via -r requirements-tests.in +black==20.8b1 + # via -r requirements-tests.in +boto3==1.16.60 + # via + # aws-sam-translator + # moto +boto==2.49.0 + # via moto +botocore==1.19.60 + # via + # aws-xray-sdk + # boto3 + # moto + # s3transfer +certifi==2020.12.5 + # via requests +cffi==1.14.0 + # via cryptography +cfn-lint==0.29.5 + # via moto +chardet==3.0.4 + # via requests +click==7.1.2 + # via + # black + # flask +coverage==5.3.1 + # via -r requirements-tests.in +cryptography==3.3.1 + # via + # moto + # python-jose + # sshpubkeys +decorator==4.4.2 + # via networkx +docker==4.2.0 + # via moto +ecdsa==0.14.1 + # via + # moto + # python-jose + # sshpubkeys +factory-boy==3.2.0 + # via -r requirements-tests.in +faker==5.6.1 + # via + # -r requirements-tests.in + # factory-boy +fakeredis==1.4.5 + # via -r requirements-tests.in +flask==1.1.2 + # via pytest-flask +freezegun==1.0.0 + # via -r requirements-tests.in +future==0.18.2 + # via aws-xray-sdk +gitdb==4.0.4 + # via gitpython +gitpython==3.1.1 + # via bandit +idna==2.9 + # via + # moto + # requests +importlib-metadata==1.6.0 + # via jsonpickle +iniconfig==1.0.1 + # via pytest +itsdangerous==1.1.0 + # via flask +jinja2==2.11.2 + # via + # flask + # moto +jmespath==0.9.5 + # via + # boto3 + # botocore +jsondiff==1.1.2 + # via moto +jsonpatch==1.25 + # via cfn-lint +jsonpickle==1.4 + # via aws-xray-sdk +jsonpointer==2.0 + # via jsonpatch +jsonschema==3.2.0 + # via + # aws-sam-translator + # cfn-lint +markupsafe==1.1.1 + # via + # jinja2 + # moto +mock==4.0.2 + # via moto +more-itertools==8.2.0 + # via moto +moto==1.3.16 + # via -r requirements-tests.in +mypy-extensions==0.4.3 + # via black +networkx==2.4 + # via cfn-lint +nose==1.3.7 + # via -r requirements-tests.in +packaging==20.3 + # via pytest +pathspec==0.8.0 + # via black +pbr==5.4.5 + # via stevedore +pluggy==0.13.1 + # via pytest +py==1.9.0 + # via pytest +pyasn1==0.4.8 + # via + # python-jose + # rsa +pycparser==2.20 + # via cffi +pyflakes==2.2.0 + # via -r requirements-tests.in +pyparsing==2.4.7 + # via packaging +pyrsistent==0.16.0 + # via jsonschema +pytest-flask==1.1.0 + # via -r requirements-tests.in +pytest-mock==3.5.1 + # via -r requirements-tests.in +pytest==6.2.1 + # via + # -r requirements-tests.in + # pytest-flask + # pytest-mock +python-dateutil==2.8.1 + # via + # botocore + # faker + # freezegun + # moto +python-jose[cryptography]==3.1.0 + # via moto +pytz==2019.3 + # via moto +pyyaml==5.3.1 + # via + # -r requirements-tests.in + # bandit + # cfn-lint + # moto +redis==3.5.3 + # via fakeredis +regex==2020.4.4 + # via black +requests-mock==1.8.0 + # via -r requirements-tests.in +requests==2.25.1 + # via + # docker + # moto + # requests-mock + # responses +responses==0.10.12 + # via moto +rsa==4.0 + # via python-jose +s3transfer==0.3.3 + # via boto3 +six==1.15.0 + # via + # aws-sam-translator + # bandit + # cfn-lint + # cryptography + # docker + # ecdsa + # fakeredis + # jsonschema + # moto + # packaging + # pyrsistent + # python-dateutil + # python-jose + # requests-mock + # responses + # stevedore + # websocket-client +smmap==3.0.2 + # via gitdb +sortedcontainers==2.1.0 + # via fakeredis +sshpubkeys==3.1.0 + # via moto +stevedore==1.32.0 + # via bandit +text-unidecode==1.3 + # via faker +toml==0.10.1 + # via + # black + # pytest +typed-ast==1.4.1 + # via black +typing-extensions==3.7.4.3 + # via black +urllib3==1.25.8 + # via + # botocore + # requests +websocket-client==0.57.0 + # via docker +werkzeug==1.0.1 + # via + # flask + # moto + # pytest-flask +wrapt==1.12.1 + # via aws-xray-sdk +xmltodict==0.12.0 + # via moto +zipp==3.1.0 + # via + # importlib-metadata + # moto # The following packages are considered to be unsafe in a requirements file: # setuptools diff --git a/requirements.txt b/requirements.txt index 98690794..424c18e9 100644 --- a/requirements.txt +++ b/requirements.txt @@ -4,93 +4,269 @@ # # pip-compile --no-index --output-file=requirements.txt requirements.in # -acme==1.11.0 # via -r requirements.in -alembic-autogenerate-enums==0.0.2 # via -r requirements.in -alembic==1.4.2 # via flask-migrate -amqp==2.5.2 # via kombu -aniso8601==8.0.0 # via flask-restful -arrow==0.17.0 # via -r requirements.in -asyncpool==1.0 # via -r requirements.in -bcrypt==3.1.7 # via flask-bcrypt, paramiko -beautifulsoup4==4.9.1 # via cloudflare -billiard==3.6.3.0 # via celery -blinker==1.4 # via flask-mail, flask-principal, raven -boto3==1.16.56 # via -r requirements.in -botocore==1.19.56 # via -r requirements.in, boto3, s3transfer -celery[redis]==4.4.2 # via -r requirements.in -certifi==2020.12.5 # via -r requirements.in, requests -certsrv==2.1.1 # via -r requirements.in -cffi==1.14.0 # via bcrypt, cryptography, pynacl -chardet==3.0.4 # via requests -click==7.1.2 # via flask -cloudflare==2.8.15 # via -r requirements.in -cryptography==3.3.1 # via -r requirements.in, acme, josepy, paramiko, pyopenssl, requests -dnspython3==1.15.0 # via -r requirements.in -dnspython==1.15.0 # via dnspython3 -dyn==1.8.1 # via -r requirements.in -flask-bcrypt==0.7.1 # via -r requirements.in -flask-cors==3.0.10 # via -r requirements.in -flask-mail==0.9.1 # via -r requirements.in -flask-migrate==2.5.3 # via -r requirements.in -flask-principal==0.4.0 # via -r requirements.in -flask-replicated==1.4 # via -r requirements.in -flask-restful==0.3.8 # via -r requirements.in -flask-script==2.0.6 # via -r requirements.in -flask-sqlalchemy==2.4.4 # via -r requirements.in, flask-migrate -flask==1.1.2 # via -r requirements.in, flask-bcrypt, flask-cors, flask-mail, flask-migrate, flask-principal, flask-restful, flask-script, flask-sqlalchemy, raven -future==0.18.2 # via -r requirements.in -gunicorn==20.0.4 # via -r requirements.in -hvac==0.10.6 # via -r requirements.in -idna==2.9 # via requests -inflection==0.5.1 # via -r requirements.in -itsdangerous==1.1.0 # via flask -javaobj-py3==0.4.0.1 # via pyjks -jinja2==2.11.2 # via -r requirements.in, flask -jmespath==0.9.5 # via boto3, botocore -josepy==1.3.0 # via acme -jsonlines==1.2.0 # via cloudflare -kombu==4.6.8 # via celery -lockfile==0.12.2 # via -r requirements.in -logmatic-python==0.1.7 # via -r requirements.in -mako==1.1.2 # via alembic -markupsafe==1.1.1 # via jinja2, mako -marshmallow-sqlalchemy==0.23.1 # via -r requirements.in -marshmallow==2.20.4 # via -r requirements.in, marshmallow-sqlalchemy -ndg-httpsclient==0.5.1 # via -r requirements.in -paramiko==2.7.2 # via -r requirements.in -pem==20.1.0 # via -r requirements.in -psycopg2==2.8.6 # via -r requirements.in -pyasn1-modules==0.2.8 # via pyjks, python-ldap -pyasn1==0.4.8 # via ndg-httpsclient, pyasn1-modules, pyjks, python-ldap -pycparser==2.20 # via cffi -pycryptodomex==3.9.7 # via pyjks -pyjks==20.0.0 # via -r requirements.in -pyjwt==1.7.1 # via -r requirements.in -pynacl==1.3.0 # via paramiko -pyopenssl==20.0.1 # via -r requirements.in, acme, josepy, ndg-httpsclient, requests -pyrfc3339==1.1 # via acme -python-dateutil==2.8.1 # via alembic, arrow, botocore -python-editor==1.0.4 # via alembic -python-json-logger==0.1.11 # via logmatic-python -python-ldap==3.3.1 # via -r requirements.in -pytz==2019.3 # via acme, celery, flask-restful, pyrfc3339 -pyyaml==5.3.1 # via -r requirements.in, cloudflare -raven[flask]==6.10.0 # via -r requirements.in -redis==3.5.3 # via -r requirements.in, celery -requests-toolbelt==0.9.1 # via acme -requests[security]==2.25.1 # via -r requirements.in, acme, certsrv, cloudflare, hvac, requests-toolbelt -retrying==1.3.3 # via -r requirements.in -s3transfer==0.3.3 # via boto3 -six==1.15.0 # via -r requirements.in, acme, bcrypt, cryptography, flask-cors, flask-restful, hvac, josepy, jsonlines, pynacl, pyopenssl, python-dateutil, retrying, sqlalchemy-utils -soupsieve==2.0.1 # via beautifulsoup4 -sqlalchemy-utils==0.36.8 # via -r requirements.in -sqlalchemy==1.3.16 # via alembic, flask-sqlalchemy, marshmallow-sqlalchemy, sqlalchemy-utils -tabulate==0.8.7 # via -r requirements.in -twofish==0.3.0 # via pyjks -urllib3==1.25.8 # via botocore, requests -vine==1.3.0 # via amqp, celery -werkzeug==1.0.1 # via flask -xmltodict==0.12.0 # via -r requirements.in +acme==1.11.0 + # via -r requirements.in +alembic-autogenerate-enums==0.0.2 + # via -r requirements.in +alembic==1.4.2 + # via flask-migrate +amqp==2.5.2 + # via kombu +aniso8601==8.0.0 + # via flask-restful +arrow==0.17.0 + # via -r requirements.in +asyncpool==1.0 + # via -r requirements.in +bcrypt==3.1.7 + # via + # flask-bcrypt + # paramiko +beautifulsoup4==4.9.1 + # via cloudflare +billiard==3.6.3.0 + # via celery +blinker==1.4 + # via + # flask-mail + # flask-principal + # raven +boto3==1.16.60 + # via -r requirements.in +botocore==1.19.60 + # via + # -r requirements.in + # boto3 + # s3transfer +celery[redis]==4.4.2 + # via -r requirements.in +certifi==2020.12.5 + # via + # -r requirements.in + # requests +certsrv==2.1.1 + # via -r requirements.in +cffi==1.14.0 + # via + # bcrypt + # cryptography + # pynacl +chardet==3.0.4 + # via requests +click==7.1.2 + # via flask +cloudflare==2.8.15 + # via -r requirements.in +cryptography==3.3.1 + # via + # -r requirements.in + # acme + # josepy + # paramiko + # pyopenssl + # requests +dnspython3==1.15.0 + # via -r requirements.in +dnspython==1.15.0 + # via dnspython3 +dyn==1.8.1 + # via -r requirements.in +flask-bcrypt==0.7.1 + # via -r requirements.in +flask-cors==3.0.10 + # via -r requirements.in +flask-mail==0.9.1 + # via -r requirements.in +flask-migrate==2.5.3 + # via -r requirements.in +flask-principal==0.4.0 + # via -r requirements.in +flask-replicated==1.4 + # via -r requirements.in +flask-restful==0.3.8 + # via -r requirements.in +flask-script==2.0.6 + # via -r requirements.in +flask-sqlalchemy==2.4.4 + # via + # -r requirements.in + # flask-migrate +flask==1.1.2 + # via + # -r requirements.in + # flask-bcrypt + # flask-cors + # flask-mail + # flask-migrate + # flask-principal + # flask-restful + # flask-script + # flask-sqlalchemy + # raven +future==0.18.2 + # via -r requirements.in +gunicorn==20.0.4 + # via -r requirements.in +hvac==0.10.6 + # via -r requirements.in +idna==2.9 + # via requests +inflection==0.5.1 + # via -r requirements.in +itsdangerous==1.1.0 + # via flask +javaobj-py3==0.4.0.1 + # via pyjks +jinja2==2.11.2 + # via + # -r requirements.in + # flask +jmespath==0.9.5 + # via + # boto3 + # botocore +josepy==1.3.0 + # via acme +jsonlines==1.2.0 + # via cloudflare +kombu==4.6.8 + # via celery +lockfile==0.12.2 + # via -r requirements.in +logmatic-python==0.1.7 + # via -r requirements.in +mako==1.1.2 + # via alembic +markupsafe==1.1.1 + # via + # jinja2 + # mako +marshmallow-sqlalchemy==0.23.1 + # via -r requirements.in +marshmallow==2.20.4 + # via + # -r requirements.in + # marshmallow-sqlalchemy +ndg-httpsclient==0.5.1 + # via -r requirements.in +paramiko==2.7.2 + # via -r requirements.in +pem==20.1.0 + # via -r requirements.in +psycopg2==2.8.6 + # via -r requirements.in +pyasn1-modules==0.2.8 + # via + # pyjks + # python-ldap +pyasn1==0.4.8 + # via + # ndg-httpsclient + # pyasn1-modules + # pyjks + # python-ldap +pycparser==2.20 + # via cffi +pycryptodomex==3.9.7 + # via pyjks +pyjks==20.0.0 + # via -r requirements.in +pyjwt==1.7.1 + # via -r requirements.in +pynacl==1.3.0 + # via paramiko +pyopenssl==20.0.1 + # via + # -r requirements.in + # acme + # josepy + # ndg-httpsclient + # requests +pyrfc3339==1.1 + # via acme +python-dateutil==2.8.1 + # via + # alembic + # arrow + # botocore +python-editor==1.0.4 + # via alembic +python-json-logger==0.1.11 + # via logmatic-python +python-ldap==3.3.1 + # via -r requirements.in +pytz==2019.3 + # via + # acme + # celery + # flask-restful + # pyrfc3339 +pyyaml==5.3.1 + # via + # -r requirements.in + # cloudflare +raven[flask]==6.10.0 + # via -r requirements.in +redis==3.5.3 + # via + # -r requirements.in + # celery +requests-toolbelt==0.9.1 + # via acme +requests[security]==2.25.1 + # via + # -r requirements.in + # acme + # certsrv + # cloudflare + # hvac + # requests-toolbelt +retrying==1.3.3 + # via -r requirements.in +s3transfer==0.3.3 + # via boto3 +six==1.15.0 + # via + # -r requirements.in + # acme + # bcrypt + # cryptography + # flask-cors + # flask-restful + # hvac + # josepy + # jsonlines + # pynacl + # pyopenssl + # python-dateutil + # retrying + # sqlalchemy-utils +soupsieve==2.0.1 + # via beautifulsoup4 +sqlalchemy-utils==0.36.8 + # via -r requirements.in +sqlalchemy==1.3.16 + # via + # alembic + # flask-sqlalchemy + # marshmallow-sqlalchemy + # sqlalchemy-utils +tabulate==0.8.7 + # via -r requirements.in +twofish==0.3.0 + # via pyjks +urllib3==1.25.8 + # via + # botocore + # requests +vine==1.3.0 + # via + # amqp + # celery +werkzeug==1.0.1 + # via flask +xmltodict==0.12.0 + # via -r requirements.in # The following packages are considered to be unsafe in a requirements file: # setuptools From 0d13aa3c71a876873679c437ec5bed1c3caea33e Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Tue, 26 Jan 2021 23:16:03 +0000 Subject: [PATCH 209/314] Bump freezegun from 1.0.0 to 1.1.0 Bumps [freezegun](https://github.com/spulec/freezegun) from 1.0.0 to 1.1.0. - [Release notes](https://github.com/spulec/freezegun/releases) - [Changelog](https://github.com/spulec/freezegun/blob/master/CHANGELOG) - [Commits](https://github.com/spulec/freezegun/compare/1.0.0...1.1.0) Signed-off-by: dependabot-preview[bot] --- requirements-tests.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements-tests.txt b/requirements-tests.txt index e0dea764..32e709d0 100644 --- a/requirements-tests.txt +++ b/requirements-tests.txt @@ -68,7 +68,7 @@ fakeredis==1.4.5 # via -r requirements-tests.in flask==1.1.2 # via pytest-flask -freezegun==1.0.0 +freezegun==1.1.0 # via -r requirements-tests.in future==0.18.2 # via aws-xray-sdk From b3c06eb6c8e4b10f20f475e0700d32c766d3b019 Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Tue, 26 Jan 2021 23:30:58 +0000 Subject: [PATCH 210/314] Bump faker from 5.6.1 to 5.8.0 Bumps [faker](https://github.com/joke2k/faker) from 5.6.1 to 5.8.0. - [Release notes](https://github.com/joke2k/faker/releases) - [Changelog](https://github.com/joke2k/faker/blob/master/CHANGELOG.md) - [Commits](https://github.com/joke2k/faker/compare/v5.6.1...v5.8.0) Signed-off-by: dependabot-preview[bot] --- requirements-tests.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements-tests.txt b/requirements-tests.txt index 32e709d0..e1807d16 100644 --- a/requirements-tests.txt +++ b/requirements-tests.txt @@ -60,7 +60,7 @@ ecdsa==0.14.1 # sshpubkeys factory-boy==3.2.0 # via -r requirements-tests.in -faker==5.6.1 +faker==5.8.0 # via # -r requirements-tests.in # factory-boy From 643d94714b4e45373a2099fb4671a210a427e1b3 Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Tue, 26 Jan 2021 23:44:26 +0000 Subject: [PATCH 211/314] Bump flask-migrate from 2.5.3 to 2.6.0 Bumps [flask-migrate](https://github.com/miguelgrinberg/flask-migrate) from 2.5.3 to 2.6.0. - [Release notes](https://github.com/miguelgrinberg/flask-migrate/releases) - [Changelog](https://github.com/miguelgrinberg/Flask-Migrate/blob/master/CHANGES.md) - [Commits](https://github.com/miguelgrinberg/flask-migrate/compare/v2.5.3...v2.6.0) Signed-off-by: dependabot-preview[bot] --- requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index 424c18e9..ef60ec93 100644 --- a/requirements.txt +++ b/requirements.txt @@ -77,7 +77,7 @@ flask-cors==3.0.10 # via -r requirements.in flask-mail==0.9.1 # via -r requirements.in -flask-migrate==2.5.3 +flask-migrate==2.6.0 # via -r requirements.in flask-principal==0.4.0 # via -r requirements.in From c464130f90d9fe6ad35807788bf0fd9c0e9ff692 Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Tue, 26 Jan 2021 23:55:37 +0000 Subject: [PATCH 212/314] Bump pyyaml from 5.3.1 to 5.4.1 Bumps [pyyaml](https://github.com/yaml/pyyaml) from 5.3.1 to 5.4.1. - [Release notes](https://github.com/yaml/pyyaml/releases) - [Changelog](https://github.com/yaml/pyyaml/blob/master/CHANGES) - [Commits](https://github.com/yaml/pyyaml/compare/5.3.1...5.4.1) Signed-off-by: dependabot-preview[bot] --- requirements-dev.txt | 126 ++++++++++++++++++++++++++++------------- requirements-tests.txt | 2 +- requirements.txt | 2 +- 3 files changed, 90 insertions(+), 40 deletions(-) diff --git a/requirements-dev.txt b/requirements-dev.txt index af69b1cf..e0df0ccd 100644 --- a/requirements-dev.txt +++ b/requirements-dev.txt @@ -4,44 +4,94 @@ # # pip-compile --no-index --output-file=requirements-dev.txt requirements-dev.in # -appdirs==1.4.3 # via virtualenv -bleach==3.1.4 # via readme-renderer -certifi==2020.12.5 # via requests -cffi==1.14.0 # via cryptography -cfgv==3.1.0 # via pre-commit -chardet==3.0.4 # via requests -colorama==0.4.3 # via twine -cryptography==3.3.1 # via secretstorage -distlib==0.3.0 # via virtualenv -docutils==0.16 # via readme-renderer -filelock==3.0.12 # via virtualenv -flake8==3.8.4 # via -r requirements-dev.in -identify==1.4.14 # via pre-commit -idna==2.9 # via requests -invoke==1.5.0 # via -r requirements-dev.in -jeepney==0.4.3 # via keyring, secretstorage -keyring==21.2.0 # via twine -mccabe==0.6.1 # via flake8 -nodeenv==1.5.0 # via -r requirements-dev.in, pre-commit -pkginfo==1.5.0.1 # via twine -pre-commit==2.9.3 # via -r requirements-dev.in -pycodestyle==2.6.0 # via flake8 -pycparser==2.20 # via cffi -pyflakes==2.2.0 # via flake8 -pygments==2.6.1 # via readme-renderer -pyyaml==5.3.1 # via -r requirements-dev.in, pre-commit -readme-renderer==25.0 # via twine -requests-toolbelt==0.9.1 # via twine -requests==2.25.1 # via requests-toolbelt, twine -rfc3986==1.4.0 # via twine -secretstorage==3.1.2 # via keyring -six==1.15.0 # via bleach, cryptography, readme-renderer, virtualenv -toml==0.10.0 # via pre-commit -tqdm==4.45.0 # via twine -twine==3.3.0 # via -r requirements-dev.in -urllib3==1.25.8 # via requests -virtualenv==20.0.17 # via pre-commit -webencodings==0.5.1 # via bleach +appdirs==1.4.3 + # via virtualenv +bleach==3.1.4 + # via readme-renderer +certifi==2020.12.5 + # via requests +cffi==1.14.0 + # via cryptography +cfgv==3.1.0 + # via pre-commit +chardet==3.0.4 + # via requests +colorama==0.4.3 + # via twine +cryptography==3.3.1 + # via secretstorage +distlib==0.3.0 + # via virtualenv +docutils==0.16 + # via readme-renderer +filelock==3.0.12 + # via virtualenv +flake8==3.8.4 + # via -r requirements-dev.in +identify==1.4.14 + # via pre-commit +idna==2.9 + # via requests +invoke==1.5.0 + # via -r requirements-dev.in +jeepney==0.4.3 + # via + # keyring + # secretstorage +keyring==21.2.0 + # via twine +mccabe==0.6.1 + # via flake8 +nodeenv==1.5.0 + # via + # -r requirements-dev.in + # pre-commit +pkginfo==1.5.0.1 + # via twine +pre-commit==2.9.3 + # via -r requirements-dev.in +pycodestyle==2.6.0 + # via flake8 +pycparser==2.20 + # via cffi +pyflakes==2.2.0 + # via flake8 +pygments==2.6.1 + # via readme-renderer +pyyaml==5.4.1 + # via + # -r requirements-dev.in + # pre-commit +readme-renderer==25.0 + # via twine +requests-toolbelt==0.9.1 + # via twine +requests==2.25.1 + # via + # requests-toolbelt + # twine +rfc3986==1.4.0 + # via twine +secretstorage==3.1.2 + # via keyring +six==1.15.0 + # via + # bleach + # cryptography + # readme-renderer + # virtualenv +toml==0.10.0 + # via pre-commit +tqdm==4.45.0 + # via twine +twine==3.3.0 + # via -r requirements-dev.in +urllib3==1.25.8 + # via requests +virtualenv==20.0.17 + # via pre-commit +webencodings==0.5.1 + # via bleach # The following packages are considered to be unsafe in a requirements file: # setuptools diff --git a/requirements-tests.txt b/requirements-tests.txt index e1807d16..729ddb7c 100644 --- a/requirements-tests.txt +++ b/requirements-tests.txt @@ -163,7 +163,7 @@ python-jose[cryptography]==3.1.0 # via moto pytz==2019.3 # via moto -pyyaml==5.3.1 +pyyaml==5.4.1 # via # -r requirements-tests.in # bandit diff --git a/requirements.txt b/requirements.txt index ef60ec93..9ea8d3bc 100644 --- a/requirements.txt +++ b/requirements.txt @@ -201,7 +201,7 @@ pytz==2019.3 # celery # flask-restful # pyrfc3339 -pyyaml==5.3.1 +pyyaml==5.4.1 # via # -r requirements.in # cloudflare From 859d4e584590903ff8099475564786d6da361ba4 Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Wed, 27 Jan 2021 00:07:15 +0000 Subject: [PATCH 213/314] Bump pem from 20.1.0 to 21.1.0 Bumps [pem](https://github.com/hynek/pem) from 20.1.0 to 21.1.0. - [Release notes](https://github.com/hynek/pem/releases) - [Changelog](https://github.com/hynek/pem/blob/master/CHANGELOG.rst) - [Commits](https://github.com/hynek/pem/compare/20.1.0...21.1.0) Signed-off-by: dependabot-preview[bot] --- requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index 9ea8d3bc..7390c54a 100644 --- a/requirements.txt +++ b/requirements.txt @@ -151,7 +151,7 @@ ndg-httpsclient==0.5.1 # via -r requirements.in paramiko==2.7.2 # via -r requirements.in -pem==20.1.0 +pem==21.1.0 # via -r requirements.in psycopg2==2.8.6 # via -r requirements.in From b9be18f281c91bb7bb2d23f1119e5c99a3456801 Mon Sep 17 00:00:00 2001 From: sayali Date: Wed, 27 Jan 2021 19:10:13 -0800 Subject: [PATCH 214/314] Role and User update logs --- lemur/auth/views.py | 7 ++++--- lemur/logs/service.py | 15 ++++++++++++++- lemur/roles/service.py | 11 ++++++++++- lemur/users/service.py | 6 ++++++ 4 files changed, 34 insertions(+), 5 deletions(-) diff --git a/lemur/auth/views.py b/lemur/auth/views.py index eaed419d..fe3b8cf5 100644 --- a/lemur/auth/views.py +++ b/lemur/auth/views.py @@ -20,6 +20,7 @@ from lemur.common.utils import get_psuedo_random_string from lemur.users import service as user_service from lemur.roles import service as role_service +from lemur.logs import service as log_service from lemur.auth.service import create_token, fetch_token_header, get_rsa_public_key from lemur.auth import ldap @@ -184,8 +185,6 @@ def create_user_roles(profile): current_app.config["LEMUR_DEFAULT_ROLE"], description="This is the default Lemur role.", ) - if not default.third_party: - role_service.set_third_party(default.id, third_party_status=True) roles.append(default) return roles @@ -198,7 +197,7 @@ def update_user(user, profile, roles): :param profile: :param roles: """ - + log_service.audit_log("TEST", user.name, "Edit role") # if we get an sso user create them an account if not user: user = user_service.create( @@ -215,6 +214,8 @@ def update_user(user, profile, roles): for ur in user.roles: if not ur.third_party: roles.append(ur) + else: + log_service.audit_log("unassign_role", ur.name, f"Un-assigning the role for {user.name}") # update any changes to the user user_service.update( diff --git a/lemur/logs/service.py b/lemur/logs/service.py index f4949911..96b4b14f 100644 --- a/lemur/logs/service.py +++ b/lemur/logs/service.py @@ -7,7 +7,7 @@ :license: Apache, see LICENSE for more details. .. moduleauthor:: Kevin Glisson """ -from flask import current_app +from flask import current_app, g from lemur import database from lemur.logs.models import Log @@ -34,6 +34,19 @@ def create(user, type, certificate=None): database.commit() +def audit_log(action, entity, message): + """ + Logs given action + :param action: The action being logged e.g. assign_role, create_role etc + :param entity: The entity undergoing the action e.g. name of the role + :param message: Additional info e.g. Role being assigned to user X + :return: + """ + current_app.logger.info( + f"[lemur-audit] action: {action}, user: {g.current_user.email}, entity: {entity} [{message}]" + ) + + def get_all(): """ Retrieve all logs from the database. diff --git a/lemur/roles/service.py b/lemur/roles/service.py index fa4c9c97..cb733d40 100644 --- a/lemur/roles/service.py +++ b/lemur/roles/service.py @@ -12,6 +12,7 @@ from lemur import database from lemur.roles.models import Role from lemur.users.models import User +from lemur.logs import service as log_service def update(role_id, name, description, users): @@ -29,6 +30,8 @@ def update(role_id, name, description, users): role.description = description role.users = users database.update(role) + + log_service.audit_log("update_role", name, f"Role with id {role_id} updated") return role @@ -44,6 +47,8 @@ def set_third_party(role_id, third_party_status=False): role = get(role_id) role.third_party = third_party_status database.update(role) + + log_service.audit_log("update_role", role.name, f"Updated third_party_status={third_party_status}") return role @@ -71,6 +76,7 @@ def create( if users: role.users = users + log_service.audit_log("create_role", name, "Creating new role") return database.create(role) @@ -101,7 +107,10 @@ def delete(role_id): :param role_id: :return: """ - return database.delete(get(role_id)) + + role = get(role_id) + log_service.audit_log("delete_role", role.name, "Deleting role") + return database.delete(role) def render(args): diff --git a/lemur/users/service.py b/lemur/users/service.py index 8fb91aa3..a67f0262 100644 --- a/lemur/users/service.py +++ b/lemur/users/service.py @@ -8,6 +8,7 @@ .. moduleauthor:: Kevin Glisson """ from lemur import database +from lemur.logs import service as log_service from lemur.users.models import User @@ -31,6 +32,7 @@ def create(username, password, email, active, profile_picture, roles): profile_picture=profile_picture, ) user.roles = roles + log_service.audit_log("create_user", username, f"Creating new user") return database.create(user) @@ -52,6 +54,8 @@ def update(user_id, username, email, active, profile_picture, roles): user.active = active user.profile_picture = profile_picture update_roles(user, roles) + + log_service.audit_log("update_user", username, f"Updating user with id {user_id}") return database.update(user) @@ -70,6 +74,7 @@ def update_roles(user, roles): break else: user.roles.remove(ur) + log_service.audit_log("unassign_role", ur.name, f"Un-assigning the role for user {user.username}") for r in roles: for ur in user.roles: @@ -77,6 +82,7 @@ def update_roles(user, roles): break else: user.roles.append(r) + log_service.audit_log("assign_role", ur.name, f"Assigning the role to user {user.username}") def get(user_id): From f14a236739853c70ed426bb2f0fdc2b05a7082f7 Mon Sep 17 00:00:00 2001 From: sayali Date: Wed, 27 Jan 2021 22:57:33 -0800 Subject: [PATCH 215/314] lint fix --- lemur/users/service.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lemur/users/service.py b/lemur/users/service.py index a67f0262..293288ce 100644 --- a/lemur/users/service.py +++ b/lemur/users/service.py @@ -32,7 +32,7 @@ def create(username, password, email, active, profile_picture, roles): profile_picture=profile_picture, ) user.roles = roles - log_service.audit_log("create_user", username, f"Creating new user") + log_service.audit_log("create_user", username, "Creating new user") return database.create(user) From fe2fc0eadd2ff3e4d46210b9c2ed7a3951ee5a4e Mon Sep 17 00:00:00 2001 From: sayali Date: Thu, 28 Jan 2021 11:19:47 -0800 Subject: [PATCH 216/314] PR comments --- lemur/auth/views.py | 1 - lemur/users/service.py | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/lemur/auth/views.py b/lemur/auth/views.py index fe3b8cf5..5bf80201 100644 --- a/lemur/auth/views.py +++ b/lemur/auth/views.py @@ -197,7 +197,6 @@ def update_user(user, profile, roles): :param profile: :param roles: """ - log_service.audit_log("TEST", user.name, "Edit role") # if we get an sso user create them an account if not user: user = user_service.create( diff --git a/lemur/users/service.py b/lemur/users/service.py index 293288ce..ffc81f5c 100644 --- a/lemur/users/service.py +++ b/lemur/users/service.py @@ -82,7 +82,7 @@ def update_roles(user, roles): break else: user.roles.append(r) - log_service.audit_log("assign_role", ur.name, f"Assigning the role to user {user.username}") + log_service.audit_log("assign_role", r.name, f"Assigning the role to user {user.username}") def get(user_id): From ed57a5a45af148734b0fb037af5daf85c65e176f Mon Sep 17 00:00:00 2001 From: sayali Date: Thu, 28 Jan 2021 13:43:25 -0800 Subject: [PATCH 217/314] Keep default role third-party (old code) --- lemur/auth/views.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/lemur/auth/views.py b/lemur/auth/views.py index 5bf80201..f9eb11d0 100644 --- a/lemur/auth/views.py +++ b/lemur/auth/views.py @@ -185,6 +185,8 @@ def create_user_roles(profile): current_app.config["LEMUR_DEFAULT_ROLE"], description="This is the default Lemur role.", ) + if not default.third_party: + role_service.set_third_party(default.id, third_party_status=True) roles.append(default) return roles From b9b3ae2286d9486c2657e8f6e69cc7fb4395996d Mon Sep 17 00:00:00 2001 From: Hossein Shafagh Date: Thu, 28 Jan 2021 15:38:59 -0800 Subject: [PATCH 218/314] better exception handling --- lemur/certificates/cli.py | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/lemur/certificates/cli.py b/lemur/certificates/cli.py index 4b4b22e9..8f4d9ca7 100644 --- a/lemur/certificates/cli.py +++ b/lemur/certificates/cli.py @@ -119,6 +119,11 @@ def request_rotation(endpoint, certificate, message, commit): status = SUCCESS_METRIC_STATUS except Exception as e: + sentry.captureException(extra={"certificate_name": str(certificate.name), + "endpoint": str(endpoint.dnsname)}) + current_app.logger.exception( + f"Error rotating certificate: {certificate.name}", exc_info=True + ) print( "[!] Failed to rotate endpoint {0} to certificate {1} reason: {2}".format( endpoint.name, certificate.name, e From c26db968d2c504eae8a1e8f2f674d8c8abb0768e Mon Sep 17 00:00:00 2001 From: Hossein Shafagh Date: Thu, 28 Jan 2021 15:43:21 -0800 Subject: [PATCH 219/314] better logging --- lemur/certificates/cli.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/lemur/certificates/cli.py b/lemur/certificates/cli.py index 8f4d9ca7..2bf0a152 100644 --- a/lemur/certificates/cli.py +++ b/lemur/certificates/cli.py @@ -130,7 +130,9 @@ def request_rotation(endpoint, certificate, message, commit): ) ) - metrics.send("endpoint_rotation", "counter", 1, metric_tags={"status": status}) + metrics.send("endpoint_rotation", "counter", 1, metric_tags={"status": status, + "certificate_name": str(certificate.name), + "endpoint": str(endpoint.dnsname)}) def request_reissue(certificate, commit): From de762d2e535429d78194e97a233f76b746ee3932 Mon Sep 17 00:00:00 2001 From: Hossein Shafagh Date: Thu, 28 Jan 2021 15:43:59 -0800 Subject: [PATCH 220/314] better logging --- lemur/certificates/cli.py | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/lemur/certificates/cli.py b/lemur/certificates/cli.py index 2bf0a152..24f8f59a 100644 --- a/lemur/certificates/cli.py +++ b/lemur/certificates/cli.py @@ -231,7 +231,7 @@ def rotate(endpoint_name, new_certificate_name, old_certificate_name, message, c print( f"[+] Rotating endpoint: {endpoint.name} to certificate {new_cert.name}" ) - log_data["message"] = "Rotating endpoint" + log_data["message"] = "Rotating one endpoint" log_data["endpoint"] = endpoint.dnsname log_data["certificate"] = new_cert.name request_rotation(endpoint, new_cert, message, commit) @@ -425,7 +425,6 @@ def rotate_region(endpoint_name, new_certificate_name, old_certificate_name, mes 1, metric_tags={ "region": region, - "old_certificate_name": str(old_cert), "new_certificate_name": str(endpoint.certificate.replaced[0].name), "endpoint_name": str(endpoint.dnsname), }, @@ -450,7 +449,6 @@ def rotate_region(endpoint_name, new_certificate_name, old_certificate_name, mes 1, metric_tags={ "status": FAILURE_METRIC_STATUS, - "old_certificate_name": str(old_cert), "new_certificate_name": str(endpoint.certificate.replaced[0].name), "endpoint_name": str(endpoint.dnsname), "message": str(message), From 92dabe5d43bcf0b57285de280ca98eaa9b4fed20 Mon Sep 17 00:00:00 2001 From: Hossein Shafagh Date: Thu, 28 Jan 2021 15:44:10 -0800 Subject: [PATCH 221/314] ineffective line --- lemur/certificates/cli.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/lemur/certificates/cli.py b/lemur/certificates/cli.py index 24f8f59a..b1b84492 100644 --- a/lemur/certificates/cli.py +++ b/lemur/certificates/cli.py @@ -239,8 +239,6 @@ def rotate(endpoint_name, new_certificate_name, old_certificate_name, message, c elif old_cert and new_cert: print(f"[+] Rotating all endpoints from {old_cert.name} to {new_cert.name}") - - log_data["message"] = "Rotating all endpoints" log_data["certificate"] = new_cert.name log_data["certificate_old"] = old_cert.name log_data["message"] = "Rotating endpoint from old to new cert" From 80f83efec2055dc037332a7e0eba22f9ba8f37c5 Mon Sep 17 00:00:00 2001 From: Hossein Shafagh Date: Thu, 28 Jan 2021 15:44:19 -0800 Subject: [PATCH 222/314] todo --- lemur/certificates/cli.py | 1 + 1 file changed, 1 insertion(+) diff --git a/lemur/certificates/cli.py b/lemur/certificates/cli.py index b1b84492..56dd9260 100644 --- a/lemur/certificates/cli.py +++ b/lemur/certificates/cli.py @@ -374,6 +374,7 @@ def rotate_region(endpoint_name, new_certificate_name, old_certificate_name, mes :param message: Send a rotation notification to the certificates owner. :param commit: Persist changes. :param region: Region in which to rotate the endpoint. + #todo: merge this method with rotate() """ if commit: print("[!] Running in COMMIT mode.") From 089796a84957961a36ef66e285f9eab90e97fea2 Mon Sep 17 00:00:00 2001 From: Hossein Shafagh Date: Thu, 28 Jan 2021 15:47:41 -0800 Subject: [PATCH 223/314] bug, intention was to skip a region --- lemur/certificates/cli.py | 1 + 1 file changed, 1 insertion(+) diff --git a/lemur/certificates/cli.py b/lemur/certificates/cli.py index 56dd9260..85b62c41 100644 --- a/lemur/certificates/cli.py +++ b/lemur/certificates/cli.py @@ -428,6 +428,7 @@ def rotate_region(endpoint_name, new_certificate_name, old_certificate_name, mes "endpoint_name": str(endpoint.dnsname), }, ) + continue if len(endpoint.certificate.replaced) == 1: log_data["certificate"] = endpoint.certificate.replaced[0].name From e250a613444d5a9b7d3aa9f83ccb6ca6dc4b89d1 Mon Sep 17 00:00:00 2001 From: Hossein Shafagh Date: Thu, 28 Jan 2021 15:48:39 -0800 Subject: [PATCH 224/314] fixing the message bug --- lemur/certificates/cli.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lemur/certificates/cli.py b/lemur/certificates/cli.py index 85b62c41..e3ce99f6 100644 --- a/lemur/certificates/cli.py +++ b/lemur/certificates/cli.py @@ -250,7 +250,6 @@ def rotate(endpoint_name, new_certificate_name, old_certificate_name, message, c else: print("[+] Rotating all endpoints that have new certificates available") - log_data["message"] = "Rotating all endpoints that have new certificates available" for endpoint in endpoint_service.get_all_pending_rotation(): log_data["endpoint"] = endpoint.dnsname if len(endpoint.certificate.replaced) == 1: @@ -284,6 +283,7 @@ def rotate(endpoint_name, new_certificate_name, old_certificate_name, message, c f"[!] Failed to rotate endpoint {endpoint.name} reason: " "Multiple replacement certificates found." ) + log_data["message"] = "Rotating endpoint from old to new cert" status = SUCCESS_METRIC_STATUS print("[+] Done!") From 0d7e8d77e48bb48d76c28b869876a8073b84f348 Mon Sep 17 00:00:00 2001 From: Hossein Shafagh Date: Thu, 28 Jan 2021 15:49:00 -0800 Subject: [PATCH 225/314] comments --- lemur/certificates/cli.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/lemur/certificates/cli.py b/lemur/certificates/cli.py index e3ce99f6..52bcae3a 100644 --- a/lemur/certificates/cli.py +++ b/lemur/certificates/cli.py @@ -249,6 +249,8 @@ def rotate(endpoint_name, new_certificate_name, old_certificate_name, message, c current_app.logger.info(log_data) else: + # no certificate name or endpoint was provided, so we will now fetch all endpoints, + # which have are attached to a certificate that has been replaced print("[+] Rotating all endpoints that have new certificates available") for endpoint in endpoint_service.get_all_pending_rotation(): log_data["endpoint"] = endpoint.dnsname From 63e9fdd0e19621788bf3581fa9902c7eb2964e00 Mon Sep 17 00:00:00 2001 From: Hossein Shafagh Date: Thu, 28 Jan 2021 15:50:02 -0800 Subject: [PATCH 226/314] rotate also in case of multiple certificates replacing the old one, just select the first one! --- lemur/certificates/cli.py | 43 +++++++++++---------------------------- 1 file changed, 12 insertions(+), 31 deletions(-) diff --git a/lemur/certificates/cli.py b/lemur/certificates/cli.py index 52bcae3a..a4c10808 100644 --- a/lemur/certificates/cli.py +++ b/lemur/certificates/cli.py @@ -253,39 +253,20 @@ def rotate(endpoint_name, new_certificate_name, old_certificate_name, message, c # which have are attached to a certificate that has been replaced print("[+] Rotating all endpoints that have new certificates available") for endpoint in endpoint_service.get_all_pending_rotation(): - log_data["endpoint"] = endpoint.dnsname - if len(endpoint.certificate.replaced) == 1: - print( - f"[+] Rotating {endpoint.name} to {endpoint.certificate.replaced[0].name}" - ) - log_data["certificate"] = endpoint.certificate.replaced[0].name - request_rotation( - endpoint, endpoint.certificate.replaced[0], message, commit - ) - current_app.logger.info(log_data) - else: - log_data["message"] = "Failed to rotate endpoint due to Multiple replacement certificates found" - print(log_data) - metrics.send( - "endpoint_rotation", - "counter", - 1, - metric_tags={ - "status": FAILURE_METRIC_STATUS, - "old_certificate_name": str(old_cert), - "new_certificate_name": str( - endpoint.certificate.replaced[0].name - ), - "endpoint_name": str(endpoint.name), - "message": str(message), - }, - ) - print( - f"[!] Failed to rotate endpoint {endpoint.name} reason: " - "Multiple replacement certificates found." - ) log_data["message"] = "Rotating endpoint from old to new cert" + if len(endpoint.certificate.replaced) > 1: + log_data["message"] = f"Multiple replacement certificates found, going with the first one out of " \ + f"{len(endpoint.certificate.replaced)}" + + log_data["endpoint"] = endpoint.dnsname + log_data["certificate"] = endpoint.certificate.replaced[0].name + request_rotation(endpoint, endpoint.certificate.replaced[0], message, commit) + print(log_data) + print( + f"[+] Rotating {endpoint.name} to {endpoint.certificate.replaced[0].name}" + ) + current_app.logger.info(log_data) status = SUCCESS_METRIC_STATUS print("[+] Done!") From b80b6d0959a1652f80f34b86878d6a74a983fb2d Mon Sep 17 00:00:00 2001 From: Hossein Shafagh Date: Thu, 28 Jan 2021 15:50:16 -0800 Subject: [PATCH 227/314] same change for rotate region --- lemur/certificates/cli.py | 21 +++++++++------------ 1 file changed, 9 insertions(+), 12 deletions(-) diff --git a/lemur/certificates/cli.py b/lemur/certificates/cli.py index a4c10808..0fee8fc2 100644 --- a/lemur/certificates/cli.py +++ b/lemur/certificates/cli.py @@ -413,18 +413,15 @@ def rotate_region(endpoint_name, new_certificate_name, old_certificate_name, mes ) continue - if len(endpoint.certificate.replaced) == 1: - log_data["certificate"] = endpoint.certificate.replaced[0].name - log_data["message"] = "Rotating all endpoints in region" - print(log_data) - current_app.logger.info(log_data) - request_rotation(endpoint, endpoint.certificate.replaced[0], message, commit) - status = SUCCESS_METRIC_STATUS - else: - status = FAILURE_METRIC_STATUS - log_data["message"] = "Failed to rotate endpoint due to Multiple replacement certificates found" - print(log_data) - current_app.logger.info(log_data) + log_data["certificate"] = endpoint.certificate.replaced[0].name + log_data["message"] = "Rotating all endpoints in region" + if len(endpoint.certificate.replaced) > 1: + log_data["message"] = f"Multiple replacement certificates found, going with the first one out of " \ + f"{len(endpoint.certificate.replaced)}" + + request_rotation(endpoint, endpoint.certificate.replaced[0], message, commit) + print(log_data) + current_app.logger.info(log_data) metrics.send( "endpoint_rotation_region", From 895d5e6ec72604ca9daae68d7f8d05e0a07dab61 Mon Sep 17 00:00:00 2001 From: Hossein Shafagh Date: Thu, 28 Jan 2021 15:58:01 -0800 Subject: [PATCH 228/314] lint --- lemur/certificates/cli.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lemur/certificates/cli.py b/lemur/certificates/cli.py index 0fee8fc2..dac7680d 100644 --- a/lemur/certificates/cli.py +++ b/lemur/certificates/cli.py @@ -131,7 +131,7 @@ def request_rotation(endpoint, certificate, message, commit): ) metrics.send("endpoint_rotation", "counter", 1, metric_tags={"status": status, - "certificate_name": str(certificate.name), + "certificate_name": str(certificate.name), "endpoint": str(endpoint.dnsname)}) From 20792dfe3a3fe6754f2a4810fa4b18b6aeeea9e1 Mon Sep 17 00:00:00 2001 From: sayali Date: Thu, 28 Jan 2021 15:58:12 -0800 Subject: [PATCH 229/314] Club role assignment logs --- lemur/auth/views.py | 8 ++++++-- lemur/users/service.py | 12 ++++++++++-- 2 files changed, 16 insertions(+), 4 deletions(-) diff --git a/lemur/auth/views.py b/lemur/auth/views.py index f9eb11d0..85a8f636 100644 --- a/lemur/auth/views.py +++ b/lemur/auth/views.py @@ -212,12 +212,16 @@ def update_user(user, profile, roles): else: # we add 'lemur' specific roles, so they do not get marked as removed + removed_roles = [] for ur in user.roles: if not ur.third_party: roles.append(ur) - else: - log_service.audit_log("unassign_role", ur.name, f"Un-assigning the role for {user.name}") + elif ur not in roles: + # This is a role assigned in lemur, but not returned by sso during current login + removed_roles.append(ur.name) + if removed_roles: + log_service.audit_log("unassign_role", user.name, f"Un-assigning roles {removed_roles}") # update any changes to the user user_service.update( user.id, diff --git a/lemur/users/service.py b/lemur/users/service.py index ffc81f5c..d708d295 100644 --- a/lemur/users/service.py +++ b/lemur/users/service.py @@ -68,21 +68,29 @@ def update_roles(user, roles): :param user: :param roles: """ + removed_roles = [] for ur in user.roles: for r in roles: if r.id == ur.id: break else: user.roles.remove(ur) - log_service.audit_log("unassign_role", ur.name, f"Un-assigning the role for user {user.username}") + removed_roles.append(ur.name) + if removed_roles: + log_service.audit_log("unassign_role", user.username, f"Un-assigning roles {removed_roles}") + + added_roles = [] for r in roles: for ur in user.roles: if r.id == ur.id: break else: user.roles.append(r) - log_service.audit_log("assign_role", r.name, f"Assigning the role to user {user.username}") + added_roles.append(r.name) + + if added_roles: + log_service.audit_log("assign_role", user.username, f"Assigning roles {added_roles}") def get(user_id): From c3e0597ef1f537462be1e6fd2c71bca0b7790039 Mon Sep 17 00:00:00 2001 From: Hossein Shafagh Date: Thu, 28 Jan 2021 16:53:15 -0800 Subject: [PATCH 230/314] introducing ACME_ADDITIONAL_ATTEMPTS --- lemur/common/celery.py | 3 ++- lemur/constants.py | 3 +++ lemur/pending_certificates/cli.py | 4 +++- 3 files changed, 8 insertions(+), 2 deletions(-) diff --git a/lemur/common/celery.py b/lemur/common/celery.py index 578592dc..f852e459 100644 --- a/lemur/common/celery.py +++ b/lemur/common/celery.py @@ -20,6 +20,7 @@ from flask import current_app from lemur.authorities.service import get as get_authority from lemur.certificates import cli as cli_certificate from lemur.common.redis import RedisHandler +from lemur.constants import ACME_ADDITIONAL_ATTEMPTS from lemur.destinations import service as destinations_service from lemur.dns_providers import cli as cli_dns_providers from lemur.endpoints import cli as cli_endpoints @@ -301,7 +302,7 @@ def fetch_acme_cert(id): error_log["last_error"] = cert.get("last_error") error_log["cn"] = pending_cert.cn - if pending_cert.number_attempts > 4: + if pending_cert.number_attempts > ACME_ADDITIONAL_ATTEMPTS: error_log["message"] = "Deleting pending certificate" send_pending_failure_notification( pending_cert, notify_owner=pending_cert.notify diff --git a/lemur/constants.py b/lemur/constants.py index 64bee4c3..e89160f5 100644 --- a/lemur/constants.py +++ b/lemur/constants.py @@ -12,6 +12,9 @@ NONSTANDARD_NAMING_TEMPLATE = "{issuer}-{not_before}-{not_after}" SUCCESS_METRIC_STATUS = "success" FAILURE_METRIC_STATUS = "failure" +# when ACME attempts to resolve a certificate try in total 3 times +ACME_ADDITIONAL_ATTEMPTS = 2 + CERTIFICATE_KEY_TYPES = [ "RSA2048", "RSA4096", diff --git a/lemur/pending_certificates/cli.py b/lemur/pending_certificates/cli.py index 2ff29f10..73b0ce2b 100644 --- a/lemur/pending_certificates/cli.py +++ b/lemur/pending_certificates/cli.py @@ -12,10 +12,12 @@ from flask import current_app from flask_script import Manager from lemur.authorities.service import get as get_authority +from lemur.constants import ACME_ADDITIONAL_ATTEMPTS from lemur.notifications.messaging import send_pending_failure_notification from lemur.pending_certificates import service as pending_certificate_service from lemur.plugins.base import plugins + manager = Manager(usage="Handles pending certificate related tasks.") @@ -107,7 +109,7 @@ def fetch_all_acme(): error_log["last_error"] = cert.get("last_error") error_log["cn"] = pending_cert.cn - if pending_cert.number_attempts > 4: + if pending_cert.number_attempts > ACME_ADDITIONAL_ATTEMPTS: error_log["message"] = "Marking pending certificate as resolved" send_pending_failure_notification( pending_cert, notify_owner=pending_cert.notify From da8d3f42d279e6682139eac4177f1a951d542617 Mon Sep 17 00:00:00 2001 From: Hossein Shafagh Date: Thu, 28 Jan 2021 16:53:42 -0800 Subject: [PATCH 231/314] documenting number of attempts --- docs/administration.rst | 3 +++ 1 file changed, 3 insertions(+) diff --git a/docs/administration.rst b/docs/administration.rst index 9af08407..3d4bad7c 100644 --- a/docs/administration.rst +++ b/docs/administration.rst @@ -362,6 +362,9 @@ Whenever a pending ACME certificate fails to be issued, Lemur will send a notifi and security team (as specified by the ``LEMUR_SECURITY_TEAM_EMAIL`` configuration parameter). This email is not sent if the pending certificate had notifications disabled. +Lemur will attempt 3x times to resolve a pending certificate. +This can at times result into 3 duplicate certificates, if all certificate attempts get resolved. + **Certificate rotation** Whenever a cert is rotated, Lemur will send a notification via email to the certificate owner. This notification is From 9b0cc3bbef4b15a3be17c80cb5eb75391655cc9f Mon Sep 17 00:00:00 2001 From: Hossein Shafagh Date: Thu, 28 Jan 2021 16:54:06 -0800 Subject: [PATCH 232/314] consolidating the documentation for acme --- docs/administration.rst | 31 ++++++++++++++----------------- 1 file changed, 14 insertions(+), 17 deletions(-) diff --git a/docs/administration.rst b/docs/administration.rst index 3d4bad7c..f150296b 100644 --- a/docs/administration.rst +++ b/docs/administration.rst @@ -823,6 +823,20 @@ ACME Plugin Enables delegated DNS domain validation using CNAMES. When enabled, Lemur will attempt to follow CNAME records to authoritative DNS servers when creating DNS-01 challenges. +The following configration properties are optional for the ACME plugin to use. They allow reusing an existing ACME +account. See :ref:`Using a pre-existing ACME account ` for more details. + + +.. data:: ACME_PRIVATE_KEY + :noindex: + + This is the private key, the account was registered with (in JWK format) + +.. data:: ACME_REGR + :noindex: + + This is the registration for the ACME account, the most important part is the uri attribute (in JSON) + Active Directory Certificate Services Plugin ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -1339,23 +1353,6 @@ The following configuration properties are required to use the PowerDNS ACME Plu File/Dir path to CA Bundle: Verifies the TLS certificate was issued by a Certificate Authority in the provided CA bundle. -ACME Plugin -~~~~~~~~~~~~ - -The following configration properties are optional for the ACME plugin to use. They allow reusing an existing ACME -account. See :ref:`Using a pre-existing ACME account ` for more details. - - -.. data:: ACME_PRIVATE_KEY - :noindex: - - This is the private key, the account was registered with (in JWK format) - -.. data:: ACME_REGR - :noindex: - - This is the registration for the ACME account, the most important part is the uri attribute (in JSON) - .. _CommandLineInterface: Command Line Interface From 77a50e0abfa749874cede765dc774d4fb3b628e8 Mon Sep 17 00:00:00 2001 From: sayali Date: Thu, 28 Jan 2021 17:56:12 -0800 Subject: [PATCH 233/314] API Key logs --- lemur/api_keys/service.py | 9 ++++++++- lemur/logs/service.py | 3 ++- 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/lemur/api_keys/service.py b/lemur/api_keys/service.py index ea681a62..3cb896aa 100644 --- a/lemur/api_keys/service.py +++ b/lemur/api_keys/service.py @@ -7,6 +7,7 @@ """ from lemur import database from lemur.api_keys.models import ApiKey +from lemur.logs import service as log_service def get(aid): @@ -24,6 +25,7 @@ def delete(access_key): :param access_key: :return: """ + log_service.audit_log("delete_api_key", access_key.name, "Deleting the API key") database.delete(access_key) @@ -34,8 +36,9 @@ def revoke(aid): :return: """ api_key = get(aid) - setattr(api_key, "revoked", False) + setattr(api_key, "revoked", True) + log_service.audit_log("revoke_api_key", api_key.name, "Revoking API key") return database.update(api_key) @@ -55,6 +58,9 @@ def create(**kwargs): :return: """ api_key = ApiKey(**kwargs) + # this logs only metadata about the api key + log_service.audit_log("create_api_key", api_key.name, f"Creating the API key {api_key}") + database.create(api_key) return api_key @@ -69,6 +75,7 @@ def update(api_key, **kwargs): for key, value in kwargs.items(): setattr(api_key, key, value) + log_service.audit_log("update_api_key", api_key.name, f"Update summary - {kwargs}") return database.update(api_key) diff --git a/lemur/logs/service.py b/lemur/logs/service.py index 96b4b14f..f569a05d 100644 --- a/lemur/logs/service.py +++ b/lemur/logs/service.py @@ -42,8 +42,9 @@ def audit_log(action, entity, message): :param message: Additional info e.g. Role being assigned to user X :return: """ + user = g.current_user.email if hasattr(g, 'current_user') else "LEMUR" current_app.logger.info( - f"[lemur-audit] action: {action}, user: {g.current_user.email}, entity: {entity} [{message}]" + f"[lemur-audit] action: {action}, user: {user}, entity: {entity}, details:{message}" ) From 38fc80fb470a2edb7374c7289ebf734a7e67891b Mon Sep 17 00:00:00 2001 From: sayali Date: Thu, 28 Jan 2021 17:59:35 -0800 Subject: [PATCH 234/314] space --- lemur/logs/service.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lemur/logs/service.py b/lemur/logs/service.py index f569a05d..5e5f30db 100644 --- a/lemur/logs/service.py +++ b/lemur/logs/service.py @@ -44,7 +44,7 @@ def audit_log(action, entity, message): """ user = g.current_user.email if hasattr(g, 'current_user') else "LEMUR" current_app.logger.info( - f"[lemur-audit] action: {action}, user: {user}, entity: {entity}, details:{message}" + f"[lemur-audit] action: {action}, user: {user}, entity: {entity}, details: {message}" ) From fb2a352b1327d1468fae286a86e982b31e00d5dd Mon Sep 17 00:00:00 2001 From: sergerdn <64213648+sergerdn@users.noreply.github.com> Date: Fri, 29 Jan 2021 07:23:54 +0300 Subject: [PATCH 235/314] update OS and deps versions --- docs/quickstart/index.rst | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/docs/quickstart/index.rst b/docs/quickstart/index.rst index 0fa55a09..a0056f34 100644 --- a/docs/quickstart/index.rst +++ b/docs/quickstart/index.rst @@ -1,7 +1,8 @@ Quickstart ********** -This guide will step you through setting up a Python-based virtualenv, installing the required packages, and configuring the basic web service. This guide assumes a clean Ubuntu 14.04 instance, commands may differ based on the OS and configuration being used. +This guide will step you through setting up a Python-based virtualenv, installing the required packages, and configuring the basic web service. +This guide assumes a clean Ubuntu 18.04/20.04 instance, commands may differ based on the OS and configuration being used. For a quicker alternative, see the Lemur docker file on `Github `_. @@ -11,11 +12,13 @@ Dependencies Some basic prerequisites which you'll need in order to run Lemur: -* A UNIX-based operating system (we test on Ubuntu, develop on OS X) +* A UNIX-based operating system (we test on Ubuntu, develop on macOS) * Python 3.7 or greater * PostgreSQL 9.4 or greater * Nginx +* Node v10.x (LTS) or greater +.. note:: Ubuntu 18.04 supported by default Python 3.6.x and Node v8.x .. note:: Lemur was built with AWS in mind. This means that things such as databases (RDS), mail (SES), and TLS (ELB), are largely handled for us. Lemur does **not** require AWS to function. Our guides and documentation try to be as generic as possible and are not intended to document every step of launching Lemur into a given environment. From e1f5bfe41a9590804553d8e917e4a36b751e136e Mon Sep 17 00:00:00 2001 From: sergerdn <64213648+sergerdn@users.noreply.github.com> Date: Fri, 29 Jan 2021 08:39:55 +0300 Subject: [PATCH 236/314] remove nodejs-legacy from deps --- docs/quickstart/index.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/quickstart/index.rst b/docs/quickstart/index.rst index a0056f34..959cca4f 100644 --- a/docs/quickstart/index.rst +++ b/docs/quickstart/index.rst @@ -30,7 +30,7 @@ If installing Lemur on a bare Ubuntu OS you will need to grab the following pack .. code-block:: bash sudo apt-get update - sudo apt-get install nodejs nodejs-legacy python-pip python-dev python3-dev libpq-dev build-essential libssl-dev libffi-dev libsasl2-dev libldap2-dev nginx git supervisor npm postgresql + sudo apt-get install nodejs npm python-pip python-dev python3-dev libpq-dev build-essential libssl-dev libffi-dev libsasl2-dev libldap2-dev nginx git supervisor postgresql .. note:: PostgreSQL is only required if your database is going to be on the same host as the webserver. npm is needed if you're installing Lemur from the source (e.g., from git). From 7f16d44b4863cbb223b3a5cc7dab06d2288c69f7 Mon Sep 17 00:00:00 2001 From: sergerdn <64213648+sergerdn@users.noreply.github.com> Date: Fri, 29 Jan 2021 09:57:03 +0300 Subject: [PATCH 237/314] add make test-build-js add python38 to Travis --- .travis.yml | 54 +++++++++++++++++++++++++++++++++++++++++++---------- Makefile | 8 +++++++- tox.ini | 2 +- 3 files changed, 52 insertions(+), 12 deletions(-) diff --git a/.travis.yml b/.travis.yml index 5f59badb..189d863e 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,16 +1,43 @@ -language: python -dist: bionic - node_js: - - "6.2.0" + - "10" -addons: - postgresql: "9.4" - -matrix: +jobs: include: - - python: "3.7" + - name: "python3.7-postgresql-9.4-bionic" + dist: bionic + language: python + python: "3.7" env: TOXENV=py37 + addons: + postgresql: "9.4" + - name: "python3.7-postgresql-10-bionic" + dist: bionic + language: python + python: "3.7" + env: TOXENV=py37 + addons: + postgresql: '10' + apt: + packages: + - postgresql-10 + - postgresql-client-10 + - postgresql-server-dev-10 + services: + - postgresql + - name: "python3.8-postgresql-12-focal" + dist: focal + language: python + python: "3.8" + env: TOXENV=py38 + addons: + postgresql: '12' + apt: + packages: + - postgresql-12 + - postgresql-client-12 + - postgresql-server-dev-12 + services: + - postgresql cache: directories: @@ -27,6 +54,12 @@ env: - BOTO_CONFIG=/doesnotexist before_script: + - sudo systemctl stop postgresql + # the port may have been auto-configured to use 5433 if it thought 5422 was already in use, + # for some reason it happens very often + # https://github.com/travis-ci/travis-build/blob/master/lib/travis/build/bash/travis_setup_postgresql.bash#L52 + - sudo sed -i -e 's/5433/5432/' /etc/postgresql/*/main/postgresql.conf + - sudo systemctl restart postgresql - psql -c "create database lemur;" -U postgres - psql -c "create user lemur with password 'lemur;'" -U postgres - psql lemur -c "create extension IF NOT EXISTS pg_trgm;" -U postgres @@ -40,6 +73,7 @@ install: script: - make test + - make test-build-js - bandit -r . -ll -ii -x lemur/tests/,docs after_success: @@ -51,4 +85,4 @@ notifications: - lemur@netflix.com on_success: never on_failure: always - on_cancel: never # Dependbot cancels Travis before rebase and triggers too many emails + on_cancel: never # Dependbot cancels Travis before rebase and triggers too many emails diff --git a/Makefile b/Makefile index e8d900b1..f1f84e2f 100644 --- a/Makefile +++ b/Makefile @@ -101,6 +101,12 @@ lint-js: npm run lint @echo "" +test-build-js: + @echo "--> Running JavaScript build" + npm install gulp + ./node_modules/.bin/gulp build && node_modules/.bin/gulp package + @echo "" + coverage: develop coverage run --source=lemur -m py.test coverage html @@ -132,4 +138,4 @@ checkout-pr: git fetch upstream pull/$(pr)/head:pr-$(pr) -.PHONY: develop dev-postgres dev-docs setup-git build clean update-submodules test testloop test-cli test-js test-python lint lint-python lint-js coverage publish release +.PHONY: develop dev-postgres dev-docs setup-git build clean update-submodules test testloop test-cli test-js test-python lint lint-python lint-js test-build-js coverage publish release diff --git a/tox.ini b/tox.ini index d3ad8944..7a77a4d3 100644 --- a/tox.ini +++ b/tox.ini @@ -1,2 +1,2 @@ [tox] -envlist = py37 +envlist = py37,py38 From 5c5a34c2060254123319c9b25dbd161a8633f0b2 Mon Sep 17 00:00:00 2001 From: Hossein Shafagh Date: Fri, 29 Jan 2021 10:12:42 -0800 Subject: [PATCH 238/314] language --- docs/quickstart/index.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/quickstart/index.rst b/docs/quickstart/index.rst index 959cca4f..3056029d 100644 --- a/docs/quickstart/index.rst +++ b/docs/quickstart/index.rst @@ -16,9 +16,9 @@ Some basic prerequisites which you'll need in order to run Lemur: * Python 3.7 or greater * PostgreSQL 9.4 or greater * Nginx -* Node v10.x (LTS) or greater +* Node v10.x (LTS) -.. note:: Ubuntu 18.04 supported by default Python 3.6.x and Node v8.x +.. note:: Ubuntu 18.04 supports by default Python 3.6.x and Node v8.x .. note:: Lemur was built with AWS in mind. This means that things such as databases (RDS), mail (SES), and TLS (ELB), are largely handled for us. Lemur does **not** require AWS to function. Our guides and documentation try to be as generic as possible and are not intended to document every step of launching Lemur into a given environment. From d5f678f70cc8976fc711034bf16ba8ffd9d5385b Mon Sep 17 00:00:00 2001 From: Hossein Shafagh Date: Fri, 29 Jan 2021 10:46:58 -0800 Subject: [PATCH 239/314] language --- lemur/certificates/cli.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lemur/certificates/cli.py b/lemur/certificates/cli.py index dac7680d..f881b9b6 100644 --- a/lemur/certificates/cli.py +++ b/lemur/certificates/cli.py @@ -249,8 +249,8 @@ def rotate(endpoint_name, new_certificate_name, old_certificate_name, message, c current_app.logger.info(log_data) else: - # no certificate name or endpoint was provided, so we will now fetch all endpoints, - # which have are attached to a certificate that has been replaced + # No certificate name or endpoint is provided. We will now fetch all endpoints, + # which are associated with a certificate that has been replaced print("[+] Rotating all endpoints that have new certificates available") for endpoint in endpoint_service.get_all_pending_rotation(): From 6df1b2985c4e12b8c42280c527911e422e687a3f Mon Sep 17 00:00:00 2001 From: Hossein Shafagh Date: Fri, 29 Jan 2021 10:49:18 -0800 Subject: [PATCH 240/314] removing duplicate print --- lemur/certificates/cli.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/lemur/certificates/cli.py b/lemur/certificates/cli.py index f881b9b6..e00f6ea7 100644 --- a/lemur/certificates/cli.py +++ b/lemur/certificates/cli.py @@ -262,7 +262,6 @@ def rotate(endpoint_name, new_certificate_name, old_certificate_name, message, c log_data["endpoint"] = endpoint.dnsname log_data["certificate"] = endpoint.certificate.replaced[0].name request_rotation(endpoint, endpoint.certificate.replaced[0], message, commit) - print(log_data) print( f"[+] Rotating {endpoint.name} to {endpoint.certificate.replaced[0].name}" ) @@ -420,7 +419,6 @@ def rotate_region(endpoint_name, new_certificate_name, old_certificate_name, mes f"{len(endpoint.certificate.replaced)}" request_rotation(endpoint, endpoint.certificate.replaced[0], message, commit) - print(log_data) current_app.logger.info(log_data) metrics.send( From 5fb98f747cfe45446a2b2139e528c40c296d5e4f Mon Sep 17 00:00:00 2001 From: Hossein Shafagh Date: Fri, 29 Jan 2021 15:45:51 -0800 Subject: [PATCH 241/314] comment --- lemur/certificates/service.py | 1 + 1 file changed, 1 insertion(+) diff --git a/lemur/certificates/service.py b/lemur/certificates/service.py index e6414933..b9bc16f0 100644 --- a/lemur/certificates/service.py +++ b/lemur/certificates/service.py @@ -388,6 +388,7 @@ def create(**kwargs): cert = Certificate(**kwargs) kwargs["creator"].certificates.append(cert) else: + # ACME path cert = PendingCertificate(**kwargs) kwargs["creator"].pending_certificates.append(cert) From 31b20e0a30de160a8d17d49e5a551dd8a015b5b0 Mon Sep 17 00:00:00 2001 From: Hossein Shafagh Date: Fri, 29 Jan 2021 15:46:22 -0800 Subject: [PATCH 242/314] ensuring a resolved job doesn't get resolved twice --- lemur/common/celery.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/lemur/common/celery.py b/lemur/common/celery.py index f852e459..d5faf578 100644 --- a/lemur/common/celery.py +++ b/lemur/common/celery.py @@ -274,7 +274,8 @@ def fetch_acme_cert(id): real_cert = cert.get("cert") # It's necessary to reload the pending cert due to detached instance: http://sqlalche.me/e/bhk3 pending_cert = pending_certificate_service.get(cert.get("pending_cert").id) - if not pending_cert: + if not pending_cert or pending_cert.resolved: + # pending_cert is cleared or it was resolved by another process log_data[ "message" ] = "Pending certificate doesn't exist anymore. Was it resolved by another process?" From 69f21234f3350be22495775bf18f2f05ac28ff76 Mon Sep 17 00:00:00 2001 From: sergerdn <64213648+sergerdn@users.noreply.github.com> Date: Sat, 30 Jan 2021 05:26:57 +0300 Subject: [PATCH 243/314] remove test-build-js --- .travis.yml | 1 - Makefile | 8 +------- 2 files changed, 1 insertion(+), 8 deletions(-) diff --git a/.travis.yml b/.travis.yml index 189d863e..311d3630 100644 --- a/.travis.yml +++ b/.travis.yml @@ -73,7 +73,6 @@ install: script: - make test - - make test-build-js - bandit -r . -ll -ii -x lemur/tests/,docs after_success: diff --git a/Makefile b/Makefile index f1f84e2f..e8d900b1 100644 --- a/Makefile +++ b/Makefile @@ -101,12 +101,6 @@ lint-js: npm run lint @echo "" -test-build-js: - @echo "--> Running JavaScript build" - npm install gulp - ./node_modules/.bin/gulp build && node_modules/.bin/gulp package - @echo "" - coverage: develop coverage run --source=lemur -m py.test coverage html @@ -138,4 +132,4 @@ checkout-pr: git fetch upstream pull/$(pr)/head:pr-$(pr) -.PHONY: develop dev-postgres dev-docs setup-git build clean update-submodules test testloop test-cli test-js test-python lint lint-python lint-js test-build-js coverage publish release +.PHONY: develop dev-postgres dev-docs setup-git build clean update-submodules test testloop test-cli test-js test-python lint lint-python lint-js coverage publish release From 50fe03bab46702f35aff395618ae616ca7b15b5b Mon Sep 17 00:00:00 2001 From: sergerdn <64213648+sergerdn@users.noreply.github.com> Date: Sat, 30 Jan 2021 05:35:52 +0300 Subject: [PATCH 244/314] add make test-js, minor modification in gulp build --- .travis.yml | 14 +- gulp/build.js | 415 +++++++++++++++++++++++---------------------- gulp/karma.conf.js | 48 +++--- package.json | 8 +- 4 files changed, 255 insertions(+), 230 deletions(-) diff --git a/.travis.yml b/.travis.yml index 311d3630..585a8f9a 100644 --- a/.travis.yml +++ b/.travis.yml @@ -10,6 +10,9 @@ jobs: env: TOXENV=py37 addons: postgresql: "9.4" + chrome: stable + services: + - xvfb - name: "python3.7-postgresql-10-bionic" dist: bionic language: python @@ -17,6 +20,7 @@ jobs: env: TOXENV=py37 addons: postgresql: '10' + chrome: stable apt: packages: - postgresql-10 @@ -24,6 +28,7 @@ jobs: - postgresql-server-dev-10 services: - postgresql + - xvfb - name: "python3.8-postgresql-12-focal" dist: focal language: python @@ -31,6 +36,7 @@ jobs: env: TOXENV=py38 addons: postgresql: '12' + chrome: stable apt: packages: - postgresql-12 @@ -38,6 +44,7 @@ jobs: - postgresql-server-dev-12 services: - postgresql + - xvfb cache: directories: @@ -53,6 +60,9 @@ env: # https://github.com/travis-ci/travis-ci/issues/5246#issuecomment-166460882 - BOTO_CONFIG=/doesnotexist +before_install: + - export CHROME_BIN=/usr/bin/google-chrome + before_script: - sudo systemctl stop postgresql # the port may have been auto-configured to use 5433 if it thought 5422 was already in use, @@ -64,8 +74,9 @@ before_script: - psql -c "create user lemur with password 'lemur;'" -U postgres - psql lemur -c "create extension IF NOT EXISTS pg_trgm;" -U postgres - npm config set registry https://registry.npmjs.org - - npm install -g bower + - npm install -g npm@latest bower - pip install --upgrade setuptools + - export DISPLAY=:99.0 install: - pip install coveralls @@ -74,6 +85,7 @@ install: script: - make test - bandit -r . -ll -ii -x lemur/tests/,docs + - make test-js after_success: - coveralls diff --git a/gulp/build.js b/gulp/build.js index d86ce425..667f28e8 100644 --- a/gulp/build.js +++ b/gulp/build.js @@ -1,257 +1,260 @@ 'use strict'; var gulp = require('gulp'), - minifycss = require('gulp-minify-css'), - concat = require('gulp-concat'), - less = require('gulp-less'), - gulpif = require('gulp-if'), - gutil = require('gulp-util'), - foreach = require('gulp-foreach'), - path =require('path'), - merge = require('merge-stream'), - del = require('del'), - size = require('gulp-size'), - plumber = require('gulp-plumber'), - autoprefixer = require('gulp-autoprefixer'), - jshint = require('gulp-jshint'), - inject = require('gulp-inject'), - cache = require('gulp-cache'), - ngAnnotate = require('gulp-ng-annotate'), - csso = require('gulp-csso'), - useref = require('gulp-useref'), - filter = require('gulp-filter'), - rev = require('gulp-rev'), - imagemin = require('gulp-imagemin'), - minifyHtml = require('gulp-minify-html'), - bowerFiles = require('main-bower-files'), - karma = require('karma'), - replace = require('gulp-replace'), - argv = require('yargs').argv; - - -gulp.task('clean', function (done) { - del(['.tmp', 'lemur/static/dist'], done); - done(); -}); - -gulp.task('default', gulp.series(['clean'], function () { - gulp.start('fonts', 'styles'); -})); - -gulp.task('test', function (done) { - // returning the promise - return new karma.Server({ - configFile: __dirname + '/karma.conf.js', - singleRun: true - }, function() { - done(); - }).start(); -}); - -gulp.task('dev:fonts', function () { - let fileList = [ - 'bower_components/bootstrap/dist/fonts/*', - 'bower_components/fontawesome/fonts/*' - ]; - - return gulp.src(fileList) - .pipe(gulp.dest('.tmp/fonts')); // returns a stream making it async -}); - -gulp.task('dev:styles', function () { - let baseContent = '@import "bower_components/bootstrap/less/bootstrap.less";@import "bower_components/bootswatch/$theme$/variables.less";@import "bower_components/bootswatch/$theme$/bootswatch.less";@import "bower_components/bootstrap/less/utilities.less";'; - let isBootswatchFile = function (file) { - - let suffix = 'bootswatch.less'; - return file.path.indexOf(suffix, file.path.length - suffix.length) !== -1; - }; - - let isBootstrapFile = function (file) { - let suffix = 'bootstrap-', - fileName = path.basename(file.path); - - return fileName.indexOf(suffix) === 0; - }; - - var fileList = [ - 'bower_components/bootswatch/sandstone/bootswatch.less', - 'bower_components/fontawesome/css/font-awesome.css', - 'bower_components/angular-chart.js/dist/angular-chart.css', - 'bower_components/angular-loading-bar/src/loading-bar.css', - 'bower_components/angular-ui-switch/angular-ui-switch.css', - 'bower_components/angular-wizard/dist/angular-wizard.css', - 'bower_components/ng-table/dist/ng-table.css', - 'bower_components/angularjs-toaster/toaster.css', - 'bower_components/angular-ui-select/dist/select.css', - 'lemur/static/app/styles/lemur.css' - ]; - - return gulp.src(fileList) - .pipe(gulpif(isBootswatchFile, foreach(function (stream, file) { - let themeName = path.basename(path.dirname(file.path)), - content = replaceAll(baseContent, '$theme$', themeName), - file2 = string_src('bootstrap-' + themeName + '.less', content); - - return file2; - }))) - .pipe(less()) - .pipe(gulpif(isBootstrapFile, foreach(function (stream, file) { - let fileName = path.basename(file.path), - themeName = fileName.substring(fileName.indexOf('-') + 1, fileName.indexOf('.')); - - // http://stackoverflow.com/questions/21719833/gulp-how-to-add-src-files-in-the-middle-of-a-pipe - // https://github.com/gulpjs/gulp/blob/master/docs/recipes/using-multiple-sources-in-one-task.md - return merge(stream, gulp.src(['.tmp/styles/font-awesome.css', '.tmp/styles/lemur.css'], { allowEmpty: true })) - .pipe(concat('style-' + themeName + '.css')); - }))) - .pipe(plumber()) - .pipe(concat('styles.css')) - .pipe(minifycss()) - .pipe(autoprefixer('last 1 version')) - .pipe(gulp.dest('.tmp/styles')) - .pipe(size()); -}); + minifycss = require('gulp-minify-css'), + concat = require('gulp-concat'), + less = require('gulp-less'), + gulpif = require('gulp-if'), + gutil = require('gulp-util'), + foreach = require('gulp-foreach'), + path = require('path'), + merge = require('merge-stream'), + del = require('del'), + size = require('gulp-size'), + plumber = require('gulp-plumber'), + autoprefixer = require('gulp-autoprefixer'), + jshint = require('gulp-jshint'), + inject = require('gulp-inject'), + cache = require('gulp-cache'), + ngAnnotate = require('gulp-ng-annotate'), + csso = require('gulp-csso'), + useref = require('gulp-useref'), + filter = require('gulp-filter'), + rev = require('gulp-rev'), + imagemin = require('gulp-imagemin'), + minifyHtml = require('gulp-minify-html'), + bowerFiles = require('main-bower-files'), + karma = require('karma'), + replace = require('gulp-replace'), + argv = require('yargs').argv; // http://stackoverflow.com/questions/1144783/replacing-all-occurrences-of-a-string-in-javascript function escapeRegExp(string) { - return string.replace(/([.*+?^=!:${}()|\[\]\/\\])/g, '\\$1'); + return string.replace(/([.*+?^=!:${}()|\[\]\/\\])/g, '\\$1'); } function replaceAll(string, find, replace) { - return string.replace(new RegExp(escapeRegExp(find), 'g'), replace); + return string.replace(new RegExp(escapeRegExp(find), 'g'), replace); } -function string_src(filename, string) { - let src = require('stream').Readable({ objectMode: true }); - src._read = function () { - this.push(new gutil.File({ cwd: '', base: '', path: filename, contents: new Buffer(string) })); - this.push(null); - }; - return src; +function stringSrc(filename, string) { + let src = require('stream').Readable({objectMode: true}); + src._read = function () { + this.push(new gutil.File({cwd: '', base: '', path: filename, contents: new Buffer(string)})); + this.push(null); + }; + return src; } +gulp.task('clean', function (done) { + del(['.tmp', 'lemur/static/dist'], done); + done(); +}); + +gulp.task('default', gulp.series(['clean'], function () { + gulp.start('fonts', 'styles'); +})); + +gulp.task('test', function (done) { + new karma.Server({ + configFile: __dirname + '/karma.conf.js', + singleRun: true + }, function (err) { + if (err === 0) { + done(); + } else { + // if karma server failed to start raise error + done(new gutil.PluginError('karma', { + message: 'Karma Tests failed' + })); + } + }).start(); +}); + +gulp.task('dev:fonts', function () { + let fileList = [ + 'bower_components/bootstrap/dist/fonts/*', + 'bower_components/fontawesome/fonts/*' + ]; + + return gulp.src(fileList) + .pipe(gulp.dest('.tmp/fonts')); // returns a stream making it async +}); + +gulp.task('dev:styles', function () { + let baseContent = '@import "bower_components/bootstrap/less/bootstrap.less";@import "bower_components/bootswatch/$theme$/variables.less";@import "bower_components/bootswatch/$theme$/bootswatch.less";@import "bower_components/bootstrap/less/utilities.less";'; + let isBootswatchFile = function (file) { + + let suffix = 'bootswatch.less'; + return file.path.indexOf(suffix, file.path.length - suffix.length) !== -1; + }; + + let isBootstrapFile = function (file) { + let suffix = 'bootstrap-', + fileName = path.basename(file.path); + + return fileName.indexOf(suffix) === 0; + }; + + let fileList = [ + 'bower_components/bootswatch/sandstone/bootswatch.less', + 'bower_components/fontawesome/css/font-awesome.css', + 'bower_components/angular-chart.js/dist/angular-chart.css', + 'bower_components/angular-loading-bar/src/loading-bar.css', + 'bower_components/angular-ui-switch/angular-ui-switch.css', + 'bower_components/angular-wizard/dist/angular-wizard.css', + 'bower_components/ng-table/dist/ng-table.css', + 'bower_components/angularjs-toaster/toaster.css', + 'bower_components/angular-ui-select/dist/select.css', + 'lemur/static/app/styles/lemur.css' + ]; + + return gulp.src(fileList) + .pipe(gulpif(isBootswatchFile, foreach(function (stream, file) { + let themeName = path.basename(path.dirname(file.path)), + content = replaceAll(baseContent, '$theme$', themeName); + return stringSrc('bootstrap-' + themeName + '.less', content); + }))) + .pipe(less()) + .pipe(gulpif(isBootstrapFile, foreach(function (stream, file) { + let fileName = path.basename(file.path), + themeName = fileName.substring(fileName.indexOf('-') + 1, fileName.indexOf('.')); + + // http://stackoverflow.com/questions/21719833/gulp-how-to-add-src-files-in-the-middle-of-a-pipe + // https://github.com/gulpjs/gulp/blob/master/docs/recipes/using-multiple-sources-in-one-task.md + return merge(stream, gulp.src(['.tmp/styles/font-awesome.css', '.tmp/styles/lemur.css'], {allowEmpty: true})) + .pipe(concat('style-' + themeName + '.css')); + }))) + .pipe(plumber()) + .pipe(concat('styles.css')) + .pipe(minifycss()) + .pipe(autoprefixer('last 1 version')) + .pipe(gulp.dest('.tmp/styles')) + .pipe(size()); +}); + gulp.task('dev:scripts', function () { - return gulp.src(['lemur/static/app/angular/**/*.js']) - .pipe(jshint()) - .pipe(jshint.reporter('jshint-stylish')) - .pipe(size()); + return gulp.src(['lemur/static/app/angular/**/*.js']) + .pipe(jshint()) + .pipe(jshint.reporter('jshint-stylish')) + .pipe(size()); }); gulp.task('build:extras', function () { - return gulp.src(['lemur/static/app/*.*', '!lemur/static/app/*.html']) - .pipe(gulp.dest('lemur/static/dist')); + return gulp.src(['lemur/static/app/*.*', '!lemur/static/app/*.html']) + .pipe(gulp.dest('lemur/static/dist')); }); function injectHtml(isDev) { - return gulp.src('lemur/static/app/index.html') - .pipe( - inject(gulp.src(bowerFiles({ base: 'app' })), { - starttag: '', - addRootSlash: false, - ignorePath: isDev ? ['lemur/static/app/', '.tmp/'] : null - }) - ) - .pipe(inject(gulp.src(['lemur/static/app/angular/**/*.js']), { - starttag: '', - addRootSlash: false, - ignorePath: isDev ? ['lemur/static/app/', '.tmp/'] : null - })) - .pipe(inject(gulp.src(['.tmp/styles/**/*.css']), { - starttag: '', - addRootSlash: false, - ignorePath: isDev ? ['lemur/static/app/', '.tmp/'] : null - })) - .pipe( - gulpif(!isDev, - inject(gulp.src('lemur/static/dist/ngviews/ngviews.min.js', { allowEmpty: true }), { - starttag: '', - addRootSlash: false - }) - ) - ).pipe(gulp.dest('.tmp/')); + return gulp.src('lemur/static/app/index.html') + .pipe( + inject(gulp.src(bowerFiles({base: 'app'})), { + starttag: '', + addRootSlash: false, + ignorePath: isDev ? ['lemur/static/app/', '.tmp/'] : null + }) + ) + .pipe(inject(gulp.src(['lemur/static/app/angular/**/*.js']), { + starttag: '', + addRootSlash: false, + ignorePath: isDev ? ['lemur/static/app/', '.tmp/'] : null + })) + .pipe(inject(gulp.src(['.tmp/styles/**/*.css']), { + starttag: '', + addRootSlash: false, + ignorePath: isDev ? ['lemur/static/app/', '.tmp/'] : null + })) + .pipe( + gulpif(!isDev, + inject(gulp.src('lemur/static/dist/ngviews/ngviews.min.js', {allowEmpty: true}), { + starttag: '', + addRootSlash: false + }) + ) + ).pipe(gulp.dest('.tmp/')); } gulp.task('dev:inject', gulp.series(['dev:styles', 'dev:scripts'], function () { - return injectHtml(true); + return injectHtml(true); })); gulp.task('build:ngviews', function () { - return gulp.src(['lemur/static/app/angular/**/*.html']) - .pipe(minifyHtml({ - empty: true, - spare: true, - quotes: true - })) - .pipe(gulp.dest('lemur/static/dist/angular')) - .pipe(size()); + return gulp.src(['lemur/static/app/angular/**/*.html']) + .pipe(minifyHtml({ + empty: true, + spare: true, + quotes: true + })) + .pipe(gulp.dest('lemur/static/dist/angular')) + .pipe(size()); }); gulp.task('build:inject', gulp.series(['dev:styles', 'dev:scripts', 'build:ngviews'], function () { - return injectHtml(false); + return injectHtml(false); })); gulp.task('build:html', gulp.series(['build:inject'], function () { - let jsFilter = filter(['**/*.js'], {'restore': true}); - let cssFilter = filter(['**/*.css'], {'restore': true}); + let jsFilter = filter(['**/*.js'], {'restore': true}); + let cssFilter = filter(['**/*.css'], {'restore': true}); - return gulp.src('.tmp/index.html') - .pipe(jsFilter) - .pipe(ngAnnotate()) - .pipe(jsFilter.restore) - .pipe(cssFilter) - .pipe(csso()) - .pipe(cssFilter.restore) - .pipe(useref()) - .pipe(gulp.dest('lemur/static/dist')) - .pipe(size()); + return gulp.src('.tmp/index.html') + .pipe(jsFilter) + .pipe(ngAnnotate()) + .pipe(jsFilter.restore) + .pipe(cssFilter) + .pipe(csso()) + .pipe(cssFilter.restore) + .pipe(useref()) + .pipe(gulp.dest('lemur/static/dist')) + .pipe(size()); })); gulp.task('build:fonts', gulp.series(['dev:fonts'], function () { - return gulp.src('.tmp/fonts/**/*') - .pipe(gulp.dest('lemur/static/dist/fonts')); + return gulp.src('.tmp/fonts/**/*') + .pipe(gulp.dest('lemur/static/dist/fonts')); })); gulp.task('build:images', function () { - return gulp.src('lemur/static/app/images/**/*') - .pipe(cache(imagemin({ - optimizationLevel: 3, - progressive: true, - interlaced: true - }))) - .pipe(gulp.dest('lemur/static/dist/images')) - .pipe(size()); + return gulp.src('lemur/static/app/images/**/*') + .pipe(cache(imagemin({ + optimizationLevel: 3, + progressive: true, + interlaced: true + }))) + .pipe(gulp.dest('lemur/static/dist/images')) + .pipe(size()); }); gulp.task('package:strip', function () { - return gulp.src(['lemur/static/dist/scripts/main*']) - .pipe(replace('http:\/\/localhost:3000', '')) - .pipe(replace('http:\/\/localhost:8000', '')) - .pipe(useref()) - .pipe(gulp.dest('lemur/static/dist/scripts')) - .pipe(size()); + return gulp.src(['lemur/static/dist/scripts/main*']) + .pipe(replace('http:\/\/localhost:3000', '')) + .pipe(replace('http:\/\/localhost:8000', '')) + .pipe(useref()) + .pipe(gulp.dest('lemur/static/dist/scripts')) + .pipe(size()); }); -gulp.task('addUrlContextPath:revision', function(){ - return gulp.src(['lemur/static/dist/**/*.css','lemur/static/dist/**/*.js']) - .pipe(rev()) - .pipe(gulp.dest('lemur/static/dist')) - .pipe(rev.manifest()) - .pipe(gulp.dest('lemur/static/dist')) +gulp.task('addUrlContextPath:revision', function () { + return gulp.src(['lemur/static/dist/**/*.css', 'lemur/static/dist/**/*.js']) + .pipe(rev()) + .pipe(gulp.dest('lemur/static/dist')) + .pipe(rev.manifest()) + .pipe(gulp.dest('lemur/static/dist')); }); -gulp.task('addUrlContextPath:revreplace', gulp.series(['addUrlContextPath:revision'], function(){ - return gulp.src( "lemur/static/dist/index.html") - .pipe(gulp.dest('lemur/static/dist')); +gulp.task('addUrlContextPath:revreplace', gulp.series(['addUrlContextPath:revision'], function () { + return gulp.src('lemur/static/dist/index.html') + .pipe(gulp.dest('lemur/static/dist')); })); -gulp.task('addUrlContextPath', gulp.series(['addUrlContextPath:revreplace'], function(){ - let urlContextPathExists = argv.urlContextPath ? true : false; - return gulp.src(['lemur/static/dist/scripts/main*.js', 'lemur/static/dist/angular/**/*.html']) - .pipe(gulpif(urlContextPathExists, replace('api/', argv.urlContextPath + '/api/'))) - .pipe(gulpif(urlContextPathExists, replace('/angular/', '/' + argv.urlContextPath + '/angular/'))) - .pipe(gulp.dest(function(file){ - return file.base; - })) +gulp.task('addUrlContextPath', gulp.series(['addUrlContextPath:revreplace'], function () { + let urlContextPathExists = !!argv.urlContextPath; + return gulp.src(['lemur/static/dist/scripts/main*.js', 'lemur/static/dist/angular/**/*.html']) + .pipe(gulpif(urlContextPathExists, replace('api/', argv.urlContextPath + '/api/'))) + .pipe(gulpif(urlContextPathExists, replace('/angular/', '/' + argv.urlContextPath + '/angular/'))) + .pipe(gulp.dest(function (file) { + return file.base; + })); })); gulp.task('build', gulp.series(['build:images', 'build:fonts', 'build:html', 'build:extras'])); diff --git a/gulp/karma.conf.js b/gulp/karma.conf.js index b9777c7a..4950db36 100644 --- a/gulp/karma.conf.js +++ b/gulp/karma.conf.js @@ -1,27 +1,37 @@ // Contents of: config/karma.conf.js +'use strict'; + module.exports = function (config) { - config.set({ - basePath : '../', + config.set({ + basePath: '../', - // Fix for "JASMINE is not supported anymore" warning - frameworks : ["jasmine"], + // Fix for "JASMINE is not supported anymore" warning + frameworks: ['jasmine'], - files : [ - 'app/lib/angular/angular.js', - 'app/lib/angular/angular-*.js', - 'test/lib/angular/angular-mocks.js', - 'app/js/**/*.js', - 'test/unit/**/*.js' - ], + files: [ + 'app/lib/angular/angular.js', + 'app/lib/angular/angular-*.js', + 'test/lib/angular/angular-mocks.js', + 'app/js/**/*.js', + 'test/unit/**/*.js' + ], - autoWatch : true, + autoWatch: true, - browsers : ['Chrome'], + browsers: [process.env.TRAVIS ? 'Chrome_travis_ci' : 'Chrome'], + customLaunchers: { + 'Chrome_travis_ci': { + base: 'Chrome', + flags: ['--no-sandbox', '--disable-setuid-sandbox', '--disable-gpu',], + }, + }, - junitReporter : { - outputFile : 'test_out/unit.xml', - suite : 'unit' - //... - } - }); + junitReporter: { + outputFile: 'test_out/unit.xml', + suite: 'unit' + //... + }, + + failOnEmptyTestSuite: false, + }); }; \ No newline at end of file diff --git a/package.json b/package.json index f2d87ab7..71421a64 100644 --- a/package.json +++ b/package.json @@ -37,11 +37,10 @@ "gulp-size": "^2.1.0", "gulp-uglify": "^2.0.0", "gulp-useref": "^3.1.2", - "gulp-util": "^3.0.1", "http-proxy": ">=1.18.1", "jshint-stylish": "^2.2.1", - "karma": "^5.2.3", - "karma-jasmine": "^1.1.0", + "karma": "^6.0.3", + "karma-jasmine": "^4.0.1", "main-bower-files": "^2.13.1", "merge-stream": "^1.0.1", "require-dir": "~0.3.0", @@ -59,7 +58,8 @@ }, "devDependencies": { "gulp": "^4.0.2", + "gulp-util": "^3.0.8", "jshint": "^2.11.0", - "karma-chrome-launcher": "^2.0.0" + "karma-chrome-launcher": "^3.1.0" } } From 5fd167ad20141e767d3c1d41cf40e84d4e843b46 Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Mon, 1 Feb 2021 18:23:44 +0000 Subject: [PATCH 245/314] Bump pre-commit from 2.9.3 to 2.10.0 Bumps [pre-commit](https://github.com/pre-commit/pre-commit) from 2.9.3 to 2.10.0. - [Release notes](https://github.com/pre-commit/pre-commit/releases) - [Changelog](https://github.com/pre-commit/pre-commit/blob/master/CHANGELOG.md) - [Commits](https://github.com/pre-commit/pre-commit/compare/v2.9.3...v2.10.0) Signed-off-by: dependabot-preview[bot] --- requirements-dev.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements-dev.txt b/requirements-dev.txt index e0df0ccd..65c44416 100644 --- a/requirements-dev.txt +++ b/requirements-dev.txt @@ -48,7 +48,7 @@ nodeenv==1.5.0 # pre-commit pkginfo==1.5.0.1 # via twine -pre-commit==2.9.3 +pre-commit==2.10.0 # via -r requirements-dev.in pycodestyle==2.6.0 # via flake8 From 144d576d03b15016c70973e54bf0021b4b8f23f5 Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Mon, 1 Feb 2021 18:34:59 +0000 Subject: [PATCH 246/314] Bump coverage from 5.3.1 to 5.4 Bumps [coverage](https://github.com/nedbat/coveragepy) from 5.3.1 to 5.4. - [Release notes](https://github.com/nedbat/coveragepy/releases) - [Changelog](https://github.com/nedbat/coveragepy/blob/master/CHANGES.rst) - [Commits](https://github.com/nedbat/coveragepy/compare/coverage-5.3.1...coverage-5.4) Signed-off-by: dependabot-preview[bot] --- requirements-tests.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements-tests.txt b/requirements-tests.txt index 729ddb7c..ae8c4163 100644 --- a/requirements-tests.txt +++ b/requirements-tests.txt @@ -42,7 +42,7 @@ click==7.1.2 # via # black # flask -coverage==5.3.1 +coverage==5.4 # via -r requirements-tests.in cryptography==3.3.1 # via From 88dd4d61e299dc03e86bc069c1e90bcbefa52ce9 Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Mon, 1 Feb 2021 18:51:13 +0000 Subject: [PATCH 247/314] Bump pytest from 6.2.1 to 6.2.2 Bumps [pytest](https://github.com/pytest-dev/pytest) from 6.2.1 to 6.2.2. - [Release notes](https://github.com/pytest-dev/pytest/releases) - [Changelog](https://github.com/pytest-dev/pytest/blob/master/CHANGELOG.rst) - [Commits](https://github.com/pytest-dev/pytest/compare/6.2.1...6.2.2) Signed-off-by: dependabot-preview[bot] --- requirements-tests.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements-tests.txt b/requirements-tests.txt index ae8c4163..79d4e269 100644 --- a/requirements-tests.txt +++ b/requirements-tests.txt @@ -148,7 +148,7 @@ pytest-flask==1.1.0 # via -r requirements-tests.in pytest-mock==3.5.1 # via -r requirements-tests.in -pytest==6.2.1 +pytest==6.2.2 # via # -r requirements-tests.in # pytest-flask From c9462ea8b7702f40484044800c890d646ce7702c Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Mon, 1 Feb 2021 19:06:39 +0000 Subject: [PATCH 248/314] Bump jinja2 from 2.11.2 to 2.11.3 Bumps [jinja2](https://github.com/pallets/jinja) from 2.11.2 to 2.11.3. - [Release notes](https://github.com/pallets/jinja/releases) - [Changelog](https://github.com/pallets/jinja/blob/master/CHANGES.rst) - [Commits](https://github.com/pallets/jinja/compare/2.11.2...2.11.3) Signed-off-by: dependabot-preview[bot] --- requirements-docs.txt | 83 +++++++++++++++++++++++++++++------------- requirements-tests.txt | 2 +- requirements.txt | 2 +- 3 files changed, 59 insertions(+), 28 deletions(-) diff --git a/requirements-docs.txt b/requirements-docs.txt index f5c94cea..e6674f70 100644 --- a/requirements-docs.txt +++ b/requirements-docs.txt @@ -4,32 +4,63 @@ # # pip-compile --no-index --output-file=requirements-docs.txt requirements-docs.in # -alabaster==0.7.12 # via sphinx -babel==2.8.0 # via sphinx -certifi==2020.12.5 # via requests -chardet==3.0.4 # via requests -docutils==0.15.2 # via sphinx -idna==2.9 # via requests -imagesize==1.2.0 # via sphinx -jinja2==2.11.2 # via sphinx -markupsafe==1.1.1 # via jinja2 -packaging==20.3 # via sphinx -pygments==2.6.1 # via sphinx -pyparsing==2.4.7 # via packaging -pytz==2019.3 # via babel -requests==2.25.1 # via sphinx -six==1.15.0 # via packaging, sphinxcontrib-httpdomain -snowballstemmer==2.0.0 # via sphinx -sphinx-rtd-theme==0.5.1 # via -r requirements-docs.in -sphinx==3.4.3 # via -r requirements-docs.in, sphinx-rtd-theme, sphinxcontrib-httpdomain -sphinxcontrib-applehelp==1.0.2 # via sphinx -sphinxcontrib-devhelp==1.0.2 # via sphinx -sphinxcontrib-htmlhelp==1.0.3 # via sphinx -sphinxcontrib-httpdomain==1.7.0 # via -r requirements-docs.in -sphinxcontrib-jsmath==1.0.1 # via sphinx -sphinxcontrib-qthelp==1.0.3 # via sphinx -sphinxcontrib-serializinghtml==1.1.4 # via sphinx -urllib3==1.25.8 # via requests +alabaster==0.7.12 + # via sphinx +babel==2.8.0 + # via sphinx +certifi==2020.12.5 + # via requests +chardet==3.0.4 + # via requests +docutils==0.15.2 + # via sphinx +idna==2.9 + # via requests +imagesize==1.2.0 + # via sphinx +jinja2==2.11.3 + # via sphinx +markupsafe==1.1.1 + # via jinja2 +packaging==20.3 + # via sphinx +pygments==2.6.1 + # via sphinx +pyparsing==2.4.7 + # via packaging +pytz==2019.3 + # via babel +requests==2.25.1 + # via sphinx +six==1.15.0 + # via + # packaging + # sphinxcontrib-httpdomain +snowballstemmer==2.0.0 + # via sphinx +sphinx-rtd-theme==0.5.1 + # via -r requirements-docs.in +sphinx==3.4.3 + # via + # -r requirements-docs.in + # sphinx-rtd-theme + # sphinxcontrib-httpdomain +sphinxcontrib-applehelp==1.0.2 + # via sphinx +sphinxcontrib-devhelp==1.0.2 + # via sphinx +sphinxcontrib-htmlhelp==1.0.3 + # via sphinx +sphinxcontrib-httpdomain==1.7.0 + # via -r requirements-docs.in +sphinxcontrib-jsmath==1.0.1 + # via sphinx +sphinxcontrib-qthelp==1.0.3 + # via sphinx +sphinxcontrib-serializinghtml==1.1.4 + # via sphinx +urllib3==1.25.8 + # via requests # The following packages are considered to be unsafe in a requirements file: # setuptools diff --git a/requirements-tests.txt b/requirements-tests.txt index 79d4e269..8d13db92 100644 --- a/requirements-tests.txt +++ b/requirements-tests.txt @@ -86,7 +86,7 @@ iniconfig==1.0.1 # via pytest itsdangerous==1.1.0 # via flask -jinja2==2.11.2 +jinja2==2.11.3 # via # flask # moto diff --git a/requirements.txt b/requirements.txt index 7390c54a..dd9e869b 100644 --- a/requirements.txt +++ b/requirements.txt @@ -117,7 +117,7 @@ itsdangerous==1.1.0 # via flask javaobj-py3==0.4.0.1 # via pyjks -jinja2==2.11.2 +jinja2==2.11.3 # via # -r requirements.in # flask From 9883173450c8626a4a9356cfa74c53a331dbbd5f Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Mon, 1 Feb 2021 19:18:40 +0000 Subject: [PATCH 249/314] Bump boto3 from 1.16.60 to 1.16.63 Bumps [boto3](https://github.com/boto/boto3) from 1.16.60 to 1.16.63. - [Release notes](https://github.com/boto/boto3/releases) - [Changelog](https://github.com/boto/boto3/blob/develop/CHANGELOG.rst) - [Commits](https://github.com/boto/boto3/compare/1.16.60...1.16.63) Signed-off-by: dependabot-preview[bot] --- requirements-tests.txt | 4 ++-- requirements.txt | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/requirements-tests.txt b/requirements-tests.txt index 8d13db92..87d46e5a 100644 --- a/requirements-tests.txt +++ b/requirements-tests.txt @@ -18,13 +18,13 @@ bandit==1.7.0 # via -r requirements-tests.in black==20.8b1 # via -r requirements-tests.in -boto3==1.16.60 +boto3==1.16.63 # via # aws-sam-translator # moto boto==2.49.0 # via moto -botocore==1.19.60 +botocore==1.19.63 # via # aws-xray-sdk # boto3 diff --git a/requirements.txt b/requirements.txt index dd9e869b..c9c9f104 100644 --- a/requirements.txt +++ b/requirements.txt @@ -31,9 +31,9 @@ blinker==1.4 # flask-mail # flask-principal # raven -boto3==1.16.60 +boto3==1.16.63 # via -r requirements.in -botocore==1.19.60 +botocore==1.19.63 # via # -r requirements.in # boto3 From 189adcb9279db7ba698357f208fba1527d04c0db Mon Sep 17 00:00:00 2001 From: Hossein Shafagh Date: Mon, 1 Feb 2021 12:55:57 -0800 Subject: [PATCH 250/314] resolving the of index error --- lemur/certificates/cli.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lemur/certificates/cli.py b/lemur/certificates/cli.py index e00f6ea7..0a51cedc 100644 --- a/lemur/certificates/cli.py +++ b/lemur/certificates/cli.py @@ -261,10 +261,10 @@ def rotate(endpoint_name, new_certificate_name, old_certificate_name, message, c log_data["endpoint"] = endpoint.dnsname log_data["certificate"] = endpoint.certificate.replaced[0].name - request_rotation(endpoint, endpoint.certificate.replaced[0], message, commit) print( f"[+] Rotating {endpoint.name} to {endpoint.certificate.replaced[0].name}" ) + request_rotation(endpoint, endpoint.certificate.replaced[0], message, commit) current_app.logger.info(log_data) status = SUCCESS_METRIC_STATUS @@ -427,7 +427,7 @@ def rotate_region(endpoint_name, new_certificate_name, old_certificate_name, mes 1, metric_tags={ "status": FAILURE_METRIC_STATUS, - "new_certificate_name": str(endpoint.certificate.replaced[0].name), + "new_certificate_name": str(log_data["certificate"]), "endpoint_name": str(endpoint.dnsname), "message": str(message), "region": str(region), From 002e73e1844b33b05eef274335f2c92e34a2d38c Mon Sep 17 00:00:00 2001 From: sayali Date: Mon, 1 Feb 2021 15:46:22 -0800 Subject: [PATCH 251/314] Indentation --- gulp/build.js | 366 ++++++++++++++++++++++----------------------- gulp/karma.conf.js | 52 +++---- 2 files changed, 209 insertions(+), 209 deletions(-) diff --git a/gulp/build.js b/gulp/build.js index 667f28e8..405cacc8 100644 --- a/gulp/build.js +++ b/gulp/build.js @@ -1,260 +1,260 @@ 'use strict'; var gulp = require('gulp'), - minifycss = require('gulp-minify-css'), - concat = require('gulp-concat'), - less = require('gulp-less'), - gulpif = require('gulp-if'), - gutil = require('gulp-util'), - foreach = require('gulp-foreach'), - path = require('path'), - merge = require('merge-stream'), - del = require('del'), - size = require('gulp-size'), - plumber = require('gulp-plumber'), - autoprefixer = require('gulp-autoprefixer'), - jshint = require('gulp-jshint'), - inject = require('gulp-inject'), - cache = require('gulp-cache'), - ngAnnotate = require('gulp-ng-annotate'), - csso = require('gulp-csso'), - useref = require('gulp-useref'), - filter = require('gulp-filter'), - rev = require('gulp-rev'), - imagemin = require('gulp-imagemin'), - minifyHtml = require('gulp-minify-html'), - bowerFiles = require('main-bower-files'), - karma = require('karma'), - replace = require('gulp-replace'), - argv = require('yargs').argv; + minifycss = require('gulp-minify-css'), + concat = require('gulp-concat'), + less = require('gulp-less'), + gulpif = require('gulp-if'), + gutil = require('gulp-util'), + foreach = require('gulp-foreach'), + path = require('path'), + merge = require('merge-stream'), + del = require('del'), + size = require('gulp-size'), + plumber = require('gulp-plumber'), + autoprefixer = require('gulp-autoprefixer'), + jshint = require('gulp-jshint'), + inject = require('gulp-inject'), + cache = require('gulp-cache'), + ngAnnotate = require('gulp-ng-annotate'), + csso = require('gulp-csso'), + useref = require('gulp-useref'), + filter = require('gulp-filter'), + rev = require('gulp-rev'), + imagemin = require('gulp-imagemin'), + minifyHtml = require('gulp-minify-html'), + bowerFiles = require('main-bower-files'), + karma = require('karma'), + replace = require('gulp-replace'), + argv = require('yargs').argv; // http://stackoverflow.com/questions/1144783/replacing-all-occurrences-of-a-string-in-javascript function escapeRegExp(string) { - return string.replace(/([.*+?^=!:${}()|\[\]\/\\])/g, '\\$1'); + return string.replace(/([.*+?^=!:${}()|\[\]\/\\])/g, '\\$1'); } function replaceAll(string, find, replace) { - return string.replace(new RegExp(escapeRegExp(find), 'g'), replace); + return string.replace(new RegExp(escapeRegExp(find), 'g'), replace); } function stringSrc(filename, string) { - let src = require('stream').Readable({objectMode: true}); - src._read = function () { - this.push(new gutil.File({cwd: '', base: '', path: filename, contents: new Buffer(string)})); - this.push(null); - }; - return src; + let src = require('stream').Readable({objectMode: true}); + src._read = function () { + this.push(new gutil.File({cwd: '', base: '', path: filename, contents: new Buffer(string)})); + this.push(null); + }; + return src; } gulp.task('clean', function (done) { - del(['.tmp', 'lemur/static/dist'], done); - done(); + del(['.tmp', 'lemur/static/dist'], done); + done(); }); gulp.task('default', gulp.series(['clean'], function () { - gulp.start('fonts', 'styles'); + gulp.start('fonts', 'styles'); })); gulp.task('test', function (done) { - new karma.Server({ - configFile: __dirname + '/karma.conf.js', - singleRun: true - }, function (err) { - if (err === 0) { - done(); - } else { - // if karma server failed to start raise error - done(new gutil.PluginError('karma', { - message: 'Karma Tests failed' - })); - } - }).start(); + new karma.Server({ + configFile: __dirname + '/karma.conf.js', + singleRun: true + }, function (err) { + if (err === 0) { + done(); + } else { + // if karma server failed to start raise error + done(new gutil.PluginError('karma', { + message: 'Karma Tests failed' + })); + } + }).start(); }); gulp.task('dev:fonts', function () { - let fileList = [ - 'bower_components/bootstrap/dist/fonts/*', - 'bower_components/fontawesome/fonts/*' - ]; + let fileList = [ + 'bower_components/bootstrap/dist/fonts/*', + 'bower_components/fontawesome/fonts/*' + ]; - return gulp.src(fileList) - .pipe(gulp.dest('.tmp/fonts')); // returns a stream making it async + return gulp.src(fileList) + .pipe(gulp.dest('.tmp/fonts')); // returns a stream making it async }); gulp.task('dev:styles', function () { - let baseContent = '@import "bower_components/bootstrap/less/bootstrap.less";@import "bower_components/bootswatch/$theme$/variables.less";@import "bower_components/bootswatch/$theme$/bootswatch.less";@import "bower_components/bootstrap/less/utilities.less";'; - let isBootswatchFile = function (file) { + let baseContent = '@import "bower_components/bootstrap/less/bootstrap.less";@import "bower_components/bootswatch/$theme$/variables.less";@import "bower_components/bootswatch/$theme$/bootswatch.less";@import "bower_components/bootstrap/less/utilities.less";'; + let isBootswatchFile = function (file) { - let suffix = 'bootswatch.less'; - return file.path.indexOf(suffix, file.path.length - suffix.length) !== -1; - }; + let suffix = 'bootswatch.less'; + return file.path.indexOf(suffix, file.path.length - suffix.length) !== -1; + }; - let isBootstrapFile = function (file) { - let suffix = 'bootstrap-', - fileName = path.basename(file.path); + let isBootstrapFile = function (file) { + let suffix = 'bootstrap-', + fileName = path.basename(file.path); - return fileName.indexOf(suffix) === 0; - }; + return fileName.indexOf(suffix) === 0; + }; - let fileList = [ - 'bower_components/bootswatch/sandstone/bootswatch.less', - 'bower_components/fontawesome/css/font-awesome.css', - 'bower_components/angular-chart.js/dist/angular-chart.css', - 'bower_components/angular-loading-bar/src/loading-bar.css', - 'bower_components/angular-ui-switch/angular-ui-switch.css', - 'bower_components/angular-wizard/dist/angular-wizard.css', - 'bower_components/ng-table/dist/ng-table.css', - 'bower_components/angularjs-toaster/toaster.css', - 'bower_components/angular-ui-select/dist/select.css', - 'lemur/static/app/styles/lemur.css' - ]; + let fileList = [ + 'bower_components/bootswatch/sandstone/bootswatch.less', + 'bower_components/fontawesome/css/font-awesome.css', + 'bower_components/angular-chart.js/dist/angular-chart.css', + 'bower_components/angular-loading-bar/src/loading-bar.css', + 'bower_components/angular-ui-switch/angular-ui-switch.css', + 'bower_components/angular-wizard/dist/angular-wizard.css', + 'bower_components/ng-table/dist/ng-table.css', + 'bower_components/angularjs-toaster/toaster.css', + 'bower_components/angular-ui-select/dist/select.css', + 'lemur/static/app/styles/lemur.css' + ]; - return gulp.src(fileList) - .pipe(gulpif(isBootswatchFile, foreach(function (stream, file) { - let themeName = path.basename(path.dirname(file.path)), - content = replaceAll(baseContent, '$theme$', themeName); - return stringSrc('bootstrap-' + themeName + '.less', content); - }))) - .pipe(less()) - .pipe(gulpif(isBootstrapFile, foreach(function (stream, file) { - let fileName = path.basename(file.path), - themeName = fileName.substring(fileName.indexOf('-') + 1, fileName.indexOf('.')); + return gulp.src(fileList) + .pipe(gulpif(isBootswatchFile, foreach(function (stream, file) { + let themeName = path.basename(path.dirname(file.path)), + content = replaceAll(baseContent, '$theme$', themeName); + return stringSrc('bootstrap-' + themeName + '.less', content); + }))) + .pipe(less()) + .pipe(gulpif(isBootstrapFile, foreach(function (stream, file) { + let fileName = path.basename(file.path), + themeName = fileName.substring(fileName.indexOf('-') + 1, fileName.indexOf('.')); - // http://stackoverflow.com/questions/21719833/gulp-how-to-add-src-files-in-the-middle-of-a-pipe - // https://github.com/gulpjs/gulp/blob/master/docs/recipes/using-multiple-sources-in-one-task.md - return merge(stream, gulp.src(['.tmp/styles/font-awesome.css', '.tmp/styles/lemur.css'], {allowEmpty: true})) - .pipe(concat('style-' + themeName + '.css')); - }))) - .pipe(plumber()) - .pipe(concat('styles.css')) - .pipe(minifycss()) - .pipe(autoprefixer('last 1 version')) - .pipe(gulp.dest('.tmp/styles')) - .pipe(size()); + // http://stackoverflow.com/questions/21719833/gulp-how-to-add-src-files-in-the-middle-of-a-pipe + // https://github.com/gulpjs/gulp/blob/master/docs/recipes/using-multiple-sources-in-one-task.md + return merge(stream, gulp.src(['.tmp/styles/font-awesome.css', '.tmp/styles/lemur.css'], {allowEmpty: true})) + .pipe(concat('style-' + themeName + '.css')); + }))) + .pipe(plumber()) + .pipe(concat('styles.css')) + .pipe(minifycss()) + .pipe(autoprefixer('last 1 version')) + .pipe(gulp.dest('.tmp/styles')) + .pipe(size()); }); gulp.task('dev:scripts', function () { - return gulp.src(['lemur/static/app/angular/**/*.js']) - .pipe(jshint()) - .pipe(jshint.reporter('jshint-stylish')) - .pipe(size()); + return gulp.src(['lemur/static/app/angular/**/*.js']) + .pipe(jshint()) + .pipe(jshint.reporter('jshint-stylish')) + .pipe(size()); }); gulp.task('build:extras', function () { - return gulp.src(['lemur/static/app/*.*', '!lemur/static/app/*.html']) - .pipe(gulp.dest('lemur/static/dist')); + return gulp.src(['lemur/static/app/*.*', '!lemur/static/app/*.html']) + .pipe(gulp.dest('lemur/static/dist')); }); function injectHtml(isDev) { - return gulp.src('lemur/static/app/index.html') - .pipe( - inject(gulp.src(bowerFiles({base: 'app'})), { - starttag: '', - addRootSlash: false, - ignorePath: isDev ? ['lemur/static/app/', '.tmp/'] : null - }) - ) - .pipe(inject(gulp.src(['lemur/static/app/angular/**/*.js']), { - starttag: '', - addRootSlash: false, - ignorePath: isDev ? ['lemur/static/app/', '.tmp/'] : null - })) - .pipe(inject(gulp.src(['.tmp/styles/**/*.css']), { - starttag: '', - addRootSlash: false, - ignorePath: isDev ? ['lemur/static/app/', '.tmp/'] : null - })) - .pipe( - gulpif(!isDev, - inject(gulp.src('lemur/static/dist/ngviews/ngviews.min.js', {allowEmpty: true}), { - starttag: '', - addRootSlash: false - }) - ) - ).pipe(gulp.dest('.tmp/')); + return gulp.src('lemur/static/app/index.html') + .pipe( + inject(gulp.src(bowerFiles({base: 'app'})), { + starttag: '', + addRootSlash: false, + ignorePath: isDev ? ['lemur/static/app/', '.tmp/'] : null + }) + ) + .pipe(inject(gulp.src(['lemur/static/app/angular/**/*.js']), { + starttag: '', + addRootSlash: false, + ignorePath: isDev ? ['lemur/static/app/', '.tmp/'] : null + })) + .pipe(inject(gulp.src(['.tmp/styles/**/*.css']), { + starttag: '', + addRootSlash: false, + ignorePath: isDev ? ['lemur/static/app/', '.tmp/'] : null + })) + .pipe( + gulpif(!isDev, + inject(gulp.src('lemur/static/dist/ngviews/ngviews.min.js', {allowEmpty: true}), { + starttag: '', + addRootSlash: false + }) + ) + ).pipe(gulp.dest('.tmp/')); } gulp.task('dev:inject', gulp.series(['dev:styles', 'dev:scripts'], function () { - return injectHtml(true); + return injectHtml(true); })); gulp.task('build:ngviews', function () { - return gulp.src(['lemur/static/app/angular/**/*.html']) - .pipe(minifyHtml({ - empty: true, - spare: true, - quotes: true - })) - .pipe(gulp.dest('lemur/static/dist/angular')) - .pipe(size()); + return gulp.src(['lemur/static/app/angular/**/*.html']) + .pipe(minifyHtml({ + empty: true, + spare: true, + quotes: true + })) + .pipe(gulp.dest('lemur/static/dist/angular')) + .pipe(size()); }); gulp.task('build:inject', gulp.series(['dev:styles', 'dev:scripts', 'build:ngviews'], function () { - return injectHtml(false); + return injectHtml(false); })); gulp.task('build:html', gulp.series(['build:inject'], function () { - let jsFilter = filter(['**/*.js'], {'restore': true}); - let cssFilter = filter(['**/*.css'], {'restore': true}); + let jsFilter = filter(['**/*.js'], {'restore': true}); + let cssFilter = filter(['**/*.css'], {'restore': true}); - return gulp.src('.tmp/index.html') - .pipe(jsFilter) - .pipe(ngAnnotate()) - .pipe(jsFilter.restore) - .pipe(cssFilter) - .pipe(csso()) - .pipe(cssFilter.restore) - .pipe(useref()) - .pipe(gulp.dest('lemur/static/dist')) - .pipe(size()); + return gulp.src('.tmp/index.html') + .pipe(jsFilter) + .pipe(ngAnnotate()) + .pipe(jsFilter.restore) + .pipe(cssFilter) + .pipe(csso()) + .pipe(cssFilter.restore) + .pipe(useref()) + .pipe(gulp.dest('lemur/static/dist')) + .pipe(size()); })); gulp.task('build:fonts', gulp.series(['dev:fonts'], function () { - return gulp.src('.tmp/fonts/**/*') - .pipe(gulp.dest('lemur/static/dist/fonts')); + return gulp.src('.tmp/fonts/**/*') + .pipe(gulp.dest('lemur/static/dist/fonts')); })); gulp.task('build:images', function () { - return gulp.src('lemur/static/app/images/**/*') - .pipe(cache(imagemin({ - optimizationLevel: 3, - progressive: true, - interlaced: true - }))) - .pipe(gulp.dest('lemur/static/dist/images')) - .pipe(size()); + return gulp.src('lemur/static/app/images/**/*') + .pipe(cache(imagemin({ + optimizationLevel: 3, + progressive: true, + interlaced: true + }))) + .pipe(gulp.dest('lemur/static/dist/images')) + .pipe(size()); }); gulp.task('package:strip', function () { - return gulp.src(['lemur/static/dist/scripts/main*']) - .pipe(replace('http:\/\/localhost:3000', '')) - .pipe(replace('http:\/\/localhost:8000', '')) - .pipe(useref()) - .pipe(gulp.dest('lemur/static/dist/scripts')) - .pipe(size()); + return gulp.src(['lemur/static/dist/scripts/main*']) + .pipe(replace('http:\/\/localhost:3000', '')) + .pipe(replace('http:\/\/localhost:8000', '')) + .pipe(useref()) + .pipe(gulp.dest('lemur/static/dist/scripts')) + .pipe(size()); }); gulp.task('addUrlContextPath:revision', function () { - return gulp.src(['lemur/static/dist/**/*.css', 'lemur/static/dist/**/*.js']) - .pipe(rev()) - .pipe(gulp.dest('lemur/static/dist')) - .pipe(rev.manifest()) - .pipe(gulp.dest('lemur/static/dist')); + return gulp.src(['lemur/static/dist/**/*.css', 'lemur/static/dist/**/*.js']) + .pipe(rev()) + .pipe(gulp.dest('lemur/static/dist')) + .pipe(rev.manifest()) + .pipe(gulp.dest('lemur/static/dist')); }); gulp.task('addUrlContextPath:revreplace', gulp.series(['addUrlContextPath:revision'], function () { - return gulp.src('lemur/static/dist/index.html') - .pipe(gulp.dest('lemur/static/dist')); + return gulp.src('lemur/static/dist/index.html') + .pipe(gulp.dest('lemur/static/dist')); })); gulp.task('addUrlContextPath', gulp.series(['addUrlContextPath:revreplace'], function () { - let urlContextPathExists = !!argv.urlContextPath; - return gulp.src(['lemur/static/dist/scripts/main*.js', 'lemur/static/dist/angular/**/*.html']) - .pipe(gulpif(urlContextPathExists, replace('api/', argv.urlContextPath + '/api/'))) - .pipe(gulpif(urlContextPathExists, replace('/angular/', '/' + argv.urlContextPath + '/angular/'))) - .pipe(gulp.dest(function (file) { - return file.base; - })); + let urlContextPathExists = !!argv.urlContextPath; + return gulp.src(['lemur/static/dist/scripts/main*.js', 'lemur/static/dist/angular/**/*.html']) + .pipe(gulpif(urlContextPathExists, replace('api/', argv.urlContextPath + '/api/'))) + .pipe(gulpif(urlContextPathExists, replace('/angular/', '/' + argv.urlContextPath + '/angular/'))) + .pipe(gulp.dest(function (file) { + return file.base; + })); })); gulp.task('build', gulp.series(['build:images', 'build:fonts', 'build:html', 'build:extras'])); diff --git a/gulp/karma.conf.js b/gulp/karma.conf.js index 4950db36..1f535220 100644 --- a/gulp/karma.conf.js +++ b/gulp/karma.conf.js @@ -2,36 +2,36 @@ 'use strict'; module.exports = function (config) { - config.set({ - basePath: '../', + config.set({ + basePath: '../', - // Fix for "JASMINE is not supported anymore" warning - frameworks: ['jasmine'], + // Fix for "JASMINE is not supported anymore" warning + frameworks: ['jasmine'], - files: [ - 'app/lib/angular/angular.js', - 'app/lib/angular/angular-*.js', - 'test/lib/angular/angular-mocks.js', - 'app/js/**/*.js', - 'test/unit/**/*.js' - ], + files: [ + 'app/lib/angular/angular.js', + 'app/lib/angular/angular-*.js', + 'test/lib/angular/angular-mocks.js', + 'app/js/**/*.js', + 'test/unit/**/*.js' + ], - autoWatch: true, + autoWatch: true, - browsers: [process.env.TRAVIS ? 'Chrome_travis_ci' : 'Chrome'], - customLaunchers: { - 'Chrome_travis_ci': { - base: 'Chrome', - flags: ['--no-sandbox', '--disable-setuid-sandbox', '--disable-gpu',], - }, - }, + browsers: [process.env.TRAVIS ? 'Chrome_travis_ci' : 'Chrome'], + customLaunchers: { + 'Chrome_travis_ci': { + base: 'Chrome', + flags: ['--no-sandbox', '--disable-setuid-sandbox', '--disable-gpu',], + }, + }, - junitReporter: { - outputFile: 'test_out/unit.xml', - suite: 'unit' - //... - }, + junitReporter: { + outputFile: 'test_out/unit.xml', + suite: 'unit' + //... + }, - failOnEmptyTestSuite: false, - }); + failOnEmptyTestSuite: false, + }); }; \ No newline at end of file From 9fe912892b9833a02272e73a35835bc7809eb415 Mon Sep 17 00:00:00 2001 From: Hossein Shafagh Date: Mon, 1 Feb 2021 15:51:55 -0800 Subject: [PATCH 252/314] added missing new line --- gulp/karma.conf.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gulp/karma.conf.js b/gulp/karma.conf.js index 1f535220..1e8d1715 100644 --- a/gulp/karma.conf.js +++ b/gulp/karma.conf.js @@ -34,4 +34,4 @@ module.exports = function (config) { failOnEmptyTestSuite: false, }); -}; \ No newline at end of file +}; From e242b4eaea6493cf9fae3e49187f0e8652945634 Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Tue, 2 Feb 2021 18:01:52 +0000 Subject: [PATCH 253/314] [Security] Bump bleach from 3.1.4 to 3.3.0 Bumps [bleach](https://github.com/mozilla/bleach) from 3.1.4 to 3.3.0. **This update includes a security fix.** - [Release notes](https://github.com/mozilla/bleach/releases) - [Changelog](https://github.com/mozilla/bleach/blob/master/CHANGES) - [Commits](https://github.com/mozilla/bleach/compare/v3.1.4...v3.3.0) Signed-off-by: dependabot-preview[bot] --- requirements-dev.txt | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/requirements-dev.txt b/requirements-dev.txt index 65c44416..d7a402c6 100644 --- a/requirements-dev.txt +++ b/requirements-dev.txt @@ -6,7 +6,7 @@ # appdirs==1.4.3 # via virtualenv -bleach==3.1.4 +bleach==3.3.0 # via readme-renderer certifi==2020.12.5 # via requests @@ -46,6 +46,8 @@ nodeenv==1.5.0 # via # -r requirements-dev.in # pre-commit +packaging==20.9 + # via bleach pkginfo==1.5.0.1 # via twine pre-commit==2.10.0 @@ -58,6 +60,8 @@ pyflakes==2.2.0 # via flake8 pygments==2.6.1 # via readme-renderer +pyparsing==2.4.7 + # via packaging pyyaml==5.4.1 # via # -r requirements-dev.in From 234f49cac62e4d0f75e07b8ea4cfbfea831cdb34 Mon Sep 17 00:00:00 2001 From: Jasmine Schladen Date: Tue, 2 Feb 2021 17:20:51 -0800 Subject: [PATCH 254/314] Correct typos on API key creation response page --- lemur/static/app/angular/api_keys/api_key/api_key.tpl.html | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lemur/static/app/angular/api_keys/api_key/api_key.tpl.html b/lemur/static/app/angular/api_keys/api_key/api_key.tpl.html index 948b8940..83186cec 100644 --- a/lemur/static/app/angular/api_keys/api_key/api_key.tpl.html +++ b/lemur/static/app/angular/api_keys/api_key/api_key.tpl.html @@ -51,8 +51,8 @@
-
Expiring in {{ interval_and_certs["interval"] }} days
+
Expiring in {{ interval_and_certs["interval"] + 1 }} days
+ + + + + + + + + +
+ + + + + + + + + + + + + + + + + + + + +
+ + + + + + +
+ Lemur +
+
+ + + + + + + + + + + + + + +
+ Your certificate has been revoked! +
+
+ + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + +
+ Hi, +
This is a Lemur certificate revocation notice. +
+ + + + + + + + +
+ {{ message.certificates.name }} + +
{{ message.certificates.endpoints | length }} Endpoints +
{{ message.certificates.owner }} +
{{ message.certificates.validityEnd | time }} +
{{ message.certificates.status }} +
Details +
+
+
+ If this revocation was unexpected, please reach out to {{ ", ".join(message.certificates.security_email) }}. +
+
Best,
Lemur +
+ + + + + + +
*All times are in UTC
+
+
+
+ + + + + + + + + +
You received this mandatory email announcement to update you about + important changes to your TLS certificate. +
+
© 2016 Lemur
+
+
+
+ diff --git a/lemur/tests/factories.py b/lemur/tests/factories.py index fea4c59a..dd655510 100644 --- a/lemur/tests/factories.py +++ b/lemur/tests/factories.py @@ -55,6 +55,7 @@ class RotationPolicyFactory(BaseFactory): class CertificateFactory(BaseFactory): """Certificate factory.""" + id = Sequence(lambda n: n) name = Sequence(lambda n: "certificate{0}".format(n)) chain = INTERMEDIATE_CERT_STR body = SAN_CERT_STR From 3a6c80df9a3cabaaf61d98c90d267a1922b74173 Mon Sep 17 00:00:00 2001 From: Jasmine Schladen Date: Wed, 3 Feb 2021 17:09:03 -0800 Subject: [PATCH 257/314] Remove file --- .../lemur_email/templates/revocation.html | 163 ------------------ 1 file changed, 163 deletions(-) delete mode 100644 lemur/plugins/lemur_email/templates/revocation.html diff --git a/lemur/plugins/lemur_email/templates/revocation.html b/lemur/plugins/lemur_email/templates/revocation.html deleted file mode 100644 index 58625786..00000000 --- a/lemur/plugins/lemur_email/templates/revocation.html +++ /dev/null @@ -1,163 +0,0 @@ - - - - - - - - Lemur - - -
- - - - - - - - - - -
- - - - - - - - - - - - - - - - - - - - -
- - - - - - -
- Lemur -
-
- - - - - - - - - - - - - - -
- Your certificate has been revoked! -
-
- - - - - - - - - - - - -
- - - - - - - - - - - - - - - - - - - - - -
- Hi, -
This is a Lemur certificate revocation notice. -
- - - - - - - - -
- {{ message.certificates.name }} - -
{{ message.certificates.endpoints | length }} Endpoints -
{{ message.certificates.owner }} -
{{ message.certificates.validityEnd | time }} -
{{ message.certificates.status }} -
Details -
-
-
- If this revocation was unexpected, please reach out to {{ ", ".join(message.certificates.security_email) }}. -
-
Best,
Lemur -
- - - - - - -
*All times are in UTC
-
-
-
- - - - - - - - - -
You received this mandatory email announcement to update you about - important changes to your TLS certificate. -
-
© 2016 Lemur
-
-
-
-
From b2afb2b38afa4350ea7431b5469dc3665f4b105f Mon Sep 17 00:00:00 2001 From: Jasmine Schladen Date: Wed, 3 Feb 2021 17:10:18 -0800 Subject: [PATCH 258/314] Remove unnecessary ID from factory --- lemur/tests/factories.py | 1 - 1 file changed, 1 deletion(-) diff --git a/lemur/tests/factories.py b/lemur/tests/factories.py index dd655510..fea4c59a 100644 --- a/lemur/tests/factories.py +++ b/lemur/tests/factories.py @@ -55,7 +55,6 @@ class RotationPolicyFactory(BaseFactory): class CertificateFactory(BaseFactory): """Certificate factory.""" - id = Sequence(lambda n: n) name = Sequence(lambda n: "certificate{0}".format(n)) chain = INTERMEDIATE_CERT_STR body = SAN_CERT_STR From 9a0f0002598cae94eeb31dc6ad45a2fbe4a2c861 Mon Sep 17 00:00:00 2001 From: Jasmine Schladen Date: Thu, 4 Feb 2021 13:29:10 -0800 Subject: [PATCH 259/314] Add Content-Type to all sample requests --- lemur/api_keys/views.py | 4 ++++ lemur/auth/views.py | 1 + lemur/authorities/views.py | 2 ++ lemur/certificates/views.py | 6 ++++++ lemur/destinations/views.py | 2 ++ lemur/notifications/views.py | 2 ++ lemur/pending_certificates/views.py | 2 ++ lemur/roles/views.py | 2 ++ lemur/sources/views.py | 2 ++ lemur/users/views.py | 2 ++ 10 files changed, 25 insertions(+) diff --git a/lemur/api_keys/views.py b/lemur/api_keys/views.py index ee09d3f7..367feb07 100644 --- a/lemur/api_keys/views.py +++ b/lemur/api_keys/views.py @@ -105,6 +105,7 @@ class ApiKeyList(AuthenticatedResource): POST /keys HTTP/1.1 Host: example.com Accept: application/json, text/javascript + Content-Type: application/json;charset=UTF-8 { "name": "my custom name", @@ -225,6 +226,7 @@ class ApiKeyUserList(AuthenticatedResource): POST /users/1/keys HTTP/1.1 Host: example.com Accept: application/json, text/javascript + Content-Type: application/json;charset=UTF-8 { "name": "my custom name" @@ -332,6 +334,7 @@ class ApiKeys(AuthenticatedResource): PUT /keys/1 HTTP/1.1 Host: example.com Accept: application/json, text/javascript + Content-Type: application/json;charset=UTF-8 { "name": "new_name", @@ -474,6 +477,7 @@ class UserApiKeys(AuthenticatedResource): PUT /users/1/keys/1 HTTP/1.1 Host: example.com Accept: application/json, text/javascript + Content-Type: application/json;charset=UTF-8 { "name": "new_name", diff --git a/lemur/auth/views.py b/lemur/auth/views.py index d982b810..6b8dd87f 100644 --- a/lemur/auth/views.py +++ b/lemur/auth/views.py @@ -268,6 +268,7 @@ class Login(Resource): POST /auth/login HTTP/1.1 Host: example.com Accept: application/json, text/javascript + Content-Type: application/json;charset=UTF-8 { "username": "test", diff --git a/lemur/authorities/views.py b/lemur/authorities/views.py index 49bce63e..094a5a74 100644 --- a/lemur/authorities/views.py +++ b/lemur/authorities/views.py @@ -130,6 +130,7 @@ class AuthoritiesList(AuthenticatedResource): POST /authorities HTTP/1.1 Host: example.com Accept: application/json, text/javascript + Content-Type: application/json;charset=UTF-8 { "country": "US", @@ -301,6 +302,7 @@ class Authorities(AuthenticatedResource): PUT /authorities/1 HTTP/1.1 Host: example.com Accept: application/json, text/javascript + Content-Type: application/json;charset=UTF-8 { "name": "TestAuthority5", diff --git a/lemur/certificates/views.py b/lemur/certificates/views.py index 47c076fc..8d4e6954 100644 --- a/lemur/certificates/views.py +++ b/lemur/certificates/views.py @@ -377,6 +377,7 @@ class CertificatesList(AuthenticatedResource): POST /certificates HTTP/1.1 Host: example.com Accept: application/json, text/javascript + Content-Type: application/json;charset=UTF-8 { "owner": "secure@example.net", @@ -526,6 +527,7 @@ class CertificatesUpload(AuthenticatedResource): POST /certificates/upload HTTP/1.1 Host: example.com Accept: application/json, text/javascript + Content-Type: application/json;charset=UTF-8 { "owner": "joe@example.com", @@ -792,6 +794,7 @@ class Certificates(AuthenticatedResource): PUT /certificates/1 HTTP/1.1 Host: example.com Accept: application/json, text/javascript + Content-Type: application/json;charset=UTF-8 { "owner": "jimbob@example.com", @@ -931,6 +934,7 @@ class Certificates(AuthenticatedResource): POST /certificates/1/update/notify HTTP/1.1 Host: example.com Accept: application/json, text/javascript + Content-Type: application/json;charset=UTF-8 { "notify": false @@ -1299,6 +1303,7 @@ class CertificateExport(AuthenticatedResource): PUT /certificates/1/export HTTP/1.1 Host: example.com Accept: application/json, text/javascript + Content-Type: application/json;charset=UTF-8 { "export": { @@ -1420,6 +1425,7 @@ class CertificateRevoke(AuthenticatedResource): POST /certificates/1/revoke HTTP/1.1 Host: example.com Accept: application/json, text/javascript + Content-Type: application/json;charset=UTF-8 { "crlReason": "affiliationChanged", diff --git a/lemur/destinations/views.py b/lemur/destinations/views.py index 072ff34e..6de6f74f 100644 --- a/lemur/destinations/views.py +++ b/lemur/destinations/views.py @@ -113,6 +113,7 @@ class DestinationsList(AuthenticatedResource): POST /destinations HTTP/1.1 Host: example.com Accept: application/json, text/javascript + Content-Type: application/json;charset=UTF-8 { "description": "test33", @@ -264,6 +265,7 @@ class Destinations(AuthenticatedResource): POST /destinations/1 HTTP/1.1 Host: example.com Accept: application/json, text/javascript + Content-Type: application/json;charset=UTF-8 { diff --git a/lemur/notifications/views.py b/lemur/notifications/views.py index f6eef655..19111d33 100644 --- a/lemur/notifications/views.py +++ b/lemur/notifications/views.py @@ -126,6 +126,7 @@ class NotificationsList(AuthenticatedResource): POST /notifications HTTP/1.1 Host: example.com Accept: application/json, text/javascript + Content-Type: application/json;charset=UTF-8 { "description": "a test", @@ -314,6 +315,7 @@ class Notifications(AuthenticatedResource): POST /notifications/1 HTTP/1.1 Host: example.com Accept: application/json, text/javascript + Content-Type: application/json;charset=UTF-8 **Example response**: diff --git a/lemur/pending_certificates/views.py b/lemur/pending_certificates/views.py index 4651aed7..e70c8c3b 100644 --- a/lemur/pending_certificates/views.py +++ b/lemur/pending_certificates/views.py @@ -224,6 +224,7 @@ class PendingCertificates(AuthenticatedResource): PUT /pending certificates/1 HTTP/1.1 Host: example.com Accept: application/json, text/javascript + Content-Type: application/json;charset=UTF-8 { "owner": "jimbob@example.com", @@ -465,6 +466,7 @@ class PendingCertificatesUpload(AuthenticatedResource): POST /certificates/1/upload HTTP/1.1 Host: example.com Accept: application/json, text/javascript + Content-Type: application/json;charset=UTF-8 { "body": "-----BEGIN CERTIFICATE-----...", diff --git a/lemur/roles/views.py b/lemur/roles/views.py index 1e12f24b..238bb1b7 100644 --- a/lemur/roles/views.py +++ b/lemur/roles/views.py @@ -106,6 +106,7 @@ class RolesList(AuthenticatedResource): POST /roles HTTP/1.1 Host: example.com Accept: application/json, text/javascript + Content-Type: application/json;charset=UTF-8 { "name": "role3", @@ -265,6 +266,7 @@ class Roles(AuthenticatedResource): PUT /roles/1 HTTP/1.1 Host: example.com Accept: application/json, text/javascript + Content-Type: application/json;charset=UTF-8 { "name": "role1", diff --git a/lemur/sources/views.py b/lemur/sources/views.py index 9c31bdb7..bf3aa3fd 100644 --- a/lemur/sources/views.py +++ b/lemur/sources/views.py @@ -106,6 +106,7 @@ class SourcesList(AuthenticatedResource): POST /sources HTTP/1.1 Host: example.com Accept: application/json, text/javascript + Content-Type: application/json;charset=UTF-8 { "options": [ @@ -237,6 +238,7 @@ class Sources(AuthenticatedResource): POST /sources/1 HTTP/1.1 Host: example.com Accept: application/json, text/javascript + Content-Type: application/json;charset=UTF-8 { "options": [ diff --git a/lemur/users/views.py b/lemur/users/views.py index 06729177..4bb07a0b 100644 --- a/lemur/users/views.py +++ b/lemur/users/views.py @@ -108,6 +108,7 @@ class UsersList(AuthenticatedResource): POST /users HTTP/1.1 Host: example.com Accept: application/json, text/javascript + Content-Type: application/json;charset=UTF-8 { "username": "user3", @@ -208,6 +209,7 @@ class Users(AuthenticatedResource): PUT /users/1 HTTP/1.1 Host: example.com Accept: application/json, text/javascript + Content-Type: application/json;charset=UTF-8 { "username": "user1", From 240c76b3cbcdbbd7fa69d9b9ba88ba8d47812b2d Mon Sep 17 00:00:00 2001 From: Hossein Shafagh Date: Fri, 5 Feb 2021 11:47:47 -0800 Subject: [PATCH 260/314] support for Entrust cross-signed EC --- lemur/plugins/lemur_entrust/plugin.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/lemur/plugins/lemur_entrust/plugin.py b/lemur/plugins/lemur_entrust/plugin.py index 14bf9646..7187e5ee 100644 --- a/lemur/plugins/lemur_entrust/plugin.py +++ b/lemur/plugins/lemur_entrust/plugin.py @@ -259,8 +259,10 @@ class EntrustIssuerPlugin(IssuerPlugin): else: chain = response_dict['chainCerts'][1] - if current_app.config.get("ENTRUST_CROSS_SIGNED_RSA") and get_key_type_from_certificate(cert) == "RSA2048": - chain = current_app.config.get("ENTRUST_CROSS_SIGNED_RSA") + if current_app.config.get("ENTRUST_CROSS_SIGNED_RSA_L1K") and get_key_type_from_certificate(cert) == "RSA2048": + chain = current_app.config.get("ENTRUST_CROSS_SIGNED_RSA_L1K") + if current_app.config.get("ENTRUST_CROSS_SIGNED_ECC_L1F") and get_key_type_from_certificate(cert) == "ECCPRIME256V1": + chain = current_app.config.get("ENTRUST_CROSS_SIGNED_ECC_L1F") log_data["message"] = "Received Chain" log_data["options"] = f"chain: {chain}" From db13d8c0015ef3362627ef493682bb66278a45c6 Mon Sep 17 00:00:00 2001 From: Hossein Shafagh Date: Fri, 5 Feb 2021 11:51:30 -0800 Subject: [PATCH 261/314] documentation --- docs/administration.rst | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/docs/administration.rst b/docs/administration.rst index f150296b..3f282369 100644 --- a/docs/administration.rst +++ b/docs/administration.rst @@ -959,10 +959,16 @@ The following parameters have to be set in the configuration files. If there is a config variable ENTRUST_PRODUCT_ take the value as cert product name else default to "STANDARD_SSL". Refer to the API documentation for valid products names. -.. data:: ENTRUST_CROSS_SIGNED_RSA +.. data:: ENTRUST_CROSS_SIGNED_RSA_L1K :noindex: - This is optional. Entrust provides support for cross-signed subCAS. One can set ENTRUST_CROSS_SIGNED_RSA to the respective cross-signed subCA PEM, such as L1K, Lemur will replace the retrieved subCA with ENTRUST_CROSS_SIGNED_RSA. + This is optional. Entrust provides support for cross-signed subCAS. One can set ENTRUST_CROSS_SIGNED_RSA_L1K to the respective cross-signed RSA-based subCA PEM and Lemur will replace the retrieved subCA with ENTRUST_CROSS_SIGNED_RSA_L1K. + + +.. data:: ENTRUST_CROSS_SIGNED_ECC_L1F + :noindex: + + This is optional. Entrust provides support for cross-signed subCAS. One can set ENTRUST_CROSS_SIGNED_ECC_L1F to the respective cross-signed EC-based subCA PEM and Lemur will replace the retrieved subCA with ENTRUST_CROSS_SIGNED_ECC_L1F. .. data:: ENTRUST_USE_DEFAULT_CLIENT_ID From 72ef9f090d3d24b64c908068d888d4d3dc3739fb Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Mon, 8 Feb 2021 13:34:11 +0000 Subject: [PATCH 262/314] Bump faker from 5.8.0 to 6.0.0 Bumps [faker](https://github.com/joke2k/faker) from 5.8.0 to 6.0.0. - [Release notes](https://github.com/joke2k/faker/releases) - [Changelog](https://github.com/joke2k/faker/blob/master/CHANGELOG.md) - [Commits](https://github.com/joke2k/faker/compare/v5.8.0...v6.0.0) Signed-off-by: dependabot-preview[bot] --- requirements-tests.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements-tests.txt b/requirements-tests.txt index 87d46e5a..44a6ce9b 100644 --- a/requirements-tests.txt +++ b/requirements-tests.txt @@ -60,7 +60,7 @@ ecdsa==0.14.1 # sshpubkeys factory-boy==3.2.0 # via -r requirements-tests.in -faker==5.8.0 +faker==6.0.0 # via # -r requirements-tests.in # factory-boy From 2f318a30218a83454960d8a77e57ccae0a7259f0 Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Mon, 8 Feb 2021 17:12:33 +0000 Subject: [PATCH 263/314] Bump pre-commit from 2.10.0 to 2.10.1 Bumps [pre-commit](https://github.com/pre-commit/pre-commit) from 2.10.0 to 2.10.1. - [Release notes](https://github.com/pre-commit/pre-commit/releases) - [Changelog](https://github.com/pre-commit/pre-commit/blob/master/CHANGELOG.md) - [Commits](https://github.com/pre-commit/pre-commit/compare/v2.10.0...v2.10.1) Signed-off-by: dependabot-preview[bot] --- requirements-dev.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements-dev.txt b/requirements-dev.txt index d7a402c6..ea97d006 100644 --- a/requirements-dev.txt +++ b/requirements-dev.txt @@ -50,7 +50,7 @@ packaging==20.9 # via bleach pkginfo==1.5.0.1 # via twine -pre-commit==2.10.0 +pre-commit==2.10.1 # via -r requirements-dev.in pycodestyle==2.6.0 # via flake8 From fb9986fefdd7b7653b7ea76c009398fdcb676925 Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Mon, 8 Feb 2021 17:29:38 +0000 Subject: [PATCH 264/314] Bump hvac from 0.10.6 to 0.10.8 Bumps [hvac](https://github.com/hvac/hvac) from 0.10.6 to 0.10.8. - [Release notes](https://github.com/hvac/hvac/releases) - [Changelog](https://github.com/hvac/hvac/blob/develop/CHANGELOG.md) - [Commits](https://github.com/hvac/hvac/compare/v0.10.6...v0.10.8) Signed-off-by: dependabot-preview[bot] --- requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index c9c9f104..00bf2c91 100644 --- a/requirements.txt +++ b/requirements.txt @@ -107,7 +107,7 @@ future==0.18.2 # via -r requirements.in gunicorn==20.0.4 # via -r requirements.in -hvac==0.10.6 +hvac==0.10.8 # via -r requirements.in idna==2.9 # via requests From c2fb41f817ae21c2a71377a9de72b2e95d2a04ec Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Mon, 8 Feb 2021 17:55:53 +0000 Subject: [PATCH 265/314] Bump acme from 1.11.0 to 1.12.0 Bumps [acme](https://github.com/letsencrypt/letsencrypt) from 1.11.0 to 1.12.0. - [Release notes](https://github.com/letsencrypt/letsencrypt/releases) - [Commits](https://github.com/letsencrypt/letsencrypt/compare/v1.11.0...v1.12.0) Signed-off-by: dependabot-preview[bot] --- requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index 00bf2c91..6cff4b0d 100644 --- a/requirements.txt +++ b/requirements.txt @@ -4,7 +4,7 @@ # # pip-compile --no-index --output-file=requirements.txt requirements.in # -acme==1.11.0 +acme==1.12.0 # via -r requirements.in alembic-autogenerate-enums==0.0.2 # via -r requirements.in From 73b1edf0967509386aa069bb4a83842757db54fd Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Mon, 8 Feb 2021 18:16:11 +0000 Subject: [PATCH 266/314] Bump boto3 from 1.16.63 to 1.17.3 Bumps [boto3](https://github.com/boto/boto3) from 1.16.63 to 1.17.3. - [Release notes](https://github.com/boto/boto3/releases) - [Changelog](https://github.com/boto/boto3/blob/develop/CHANGELOG.rst) - [Commits](https://github.com/boto/boto3/compare/1.16.63...1.17.3) Signed-off-by: dependabot-preview[bot] --- requirements-tests.txt | 4 ++-- requirements.txt | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/requirements-tests.txt b/requirements-tests.txt index 44a6ce9b..8771ca2e 100644 --- a/requirements-tests.txt +++ b/requirements-tests.txt @@ -18,13 +18,13 @@ bandit==1.7.0 # via -r requirements-tests.in black==20.8b1 # via -r requirements-tests.in -boto3==1.16.63 +boto3==1.17.3 # via # aws-sam-translator # moto boto==2.49.0 # via moto -botocore==1.19.63 +botocore==1.20.3 # via # aws-xray-sdk # boto3 diff --git a/requirements.txt b/requirements.txt index 6cff4b0d..fdbfae87 100644 --- a/requirements.txt +++ b/requirements.txt @@ -31,9 +31,9 @@ blinker==1.4 # flask-mail # flask-principal # raven -boto3==1.16.63 +boto3==1.17.3 # via -r requirements.in -botocore==1.19.63 +botocore==1.20.3 # via # -r requirements.in # boto3 From 6c33cd0bf3d39dbb21823a8aade8b115aa2890b8 Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Mon, 8 Feb 2021 18:48:21 +0000 Subject: [PATCH 267/314] Bump cryptography from 3.3.1 to 3.4.2 Bumps [cryptography](https://github.com/pyca/cryptography) from 3.3.1 to 3.4.2. - [Release notes](https://github.com/pyca/cryptography/releases) - [Changelog](https://github.com/pyca/cryptography/blob/3.4.2/CHANGELOG.rst) - [Commits](https://github.com/pyca/cryptography/compare/3.3.1...3.4.2) Signed-off-by: dependabot-preview[bot] --- requirements-dev.txt | 3 +-- requirements-tests.txt | 3 +-- requirements.txt | 3 +-- 3 files changed, 3 insertions(+), 6 deletions(-) diff --git a/requirements-dev.txt b/requirements-dev.txt index ea97d006..a4603adb 100644 --- a/requirements-dev.txt +++ b/requirements-dev.txt @@ -18,7 +18,7 @@ chardet==3.0.4 # via requests colorama==0.4.3 # via twine -cryptography==3.3.1 +cryptography==3.4.2 # via secretstorage distlib==0.3.0 # via virtualenv @@ -81,7 +81,6 @@ secretstorage==3.1.2 six==1.15.0 # via # bleach - # cryptography # readme-renderer # virtualenv toml==0.10.0 diff --git a/requirements-tests.txt b/requirements-tests.txt index 8771ca2e..961f4e68 100644 --- a/requirements-tests.txt +++ b/requirements-tests.txt @@ -44,7 +44,7 @@ click==7.1.2 # flask coverage==5.4 # via -r requirements-tests.in -cryptography==3.3.1 +cryptography==3.4.2 # via # moto # python-jose @@ -192,7 +192,6 @@ six==1.15.0 # aws-sam-translator # bandit # cfn-lint - # cryptography # docker # ecdsa # fakeredis diff --git a/requirements.txt b/requirements.txt index fdbfae87..cf457308 100644 --- a/requirements.txt +++ b/requirements.txt @@ -57,7 +57,7 @@ click==7.1.2 # via flask cloudflare==2.8.15 # via -r requirements.in -cryptography==3.3.1 +cryptography==3.4.2 # via # -r requirements.in # acme @@ -230,7 +230,6 @@ six==1.15.0 # -r requirements.in # acme # bcrypt - # cryptography # flask-cors # flask-restful # hvac From 0c1701314ad7945b87b0c5b5499303e7011c8ede Mon Sep 17 00:00:00 2001 From: sayali Date: Wed, 10 Feb 2021 12:03:46 -0800 Subject: [PATCH 268/314] User memberships --- docs/administration.rst | 27 +++++++++++++++++ docs/developer/plugins/index.rst | 11 +++++++ lemur/auth/views.py | 50 ++++++++++++++++++++++++++++++-- lemur/plugins/bases/__init__.py | 1 + lemur/plugins/bases/tls.py | 20 +++++++++++++ 5 files changed, 106 insertions(+), 3 deletions(-) create mode 100644 lemur/plugins/bases/tls.py diff --git a/docs/administration.rst b/docs/administration.rst index 3f282369..3623f311 100644 --- a/docs/administration.rst +++ b/docs/administration.rst @@ -712,6 +712,33 @@ For more information about how to use social logins, see: `Satellizer """ +import json + import jwt import base64 import requests @@ -23,7 +25,7 @@ from lemur.roles import service as role_service from lemur.logs import service as log_service from lemur.auth.service import create_token, fetch_token_header, get_rsa_public_key from lemur.auth import ldap - +from lemur.plugins.base import plugins mod = Blueprint("auth", __name__) api = Api(mod) @@ -138,6 +140,44 @@ def retrieve_user(user_api_url, access_token): return user, profile +def retrieve_user_memberships(user_api_url, user_membership_api_url, access_token): + user, profile = retrieve_user(user_api_url, access_token) + + if user_membership_api_url is None: + return user, profile + """ + Potentially, below code can be made more generic i.e., plugin driven. Unaware of the usage of this + code across the community, current implementation is config driven. Without user_membership_api_url + configured, it is backward compatible. + """ + + # put user id in url + user_membership_api_url = user_membership_api_url.replace("%user_id%", profile["userId"]) + + headers = {"Content-Type": "application/json"} + data = {"relation": "DIRECT_ONLY", "groupFilter": {"type": "GOOGLE"}, "size": 500} + + tls_provider = plugins.get(current_app.config.get("PING_USER_MEMBERSHIP_TLS_PROVIDER")) + + # retrieve information about the current user + session = tls_provider.session(current_app.config.get("PING_USER_MEMBERSHIP_SERVICE")) + r = session.post(user_membership_api_url, data=json.dumps(data), headers=headers) + + user_membership = {"email": profile["email"], + "thumbnailPhotoUrl": profile["thumbnailPhotoUrl"], + "googleGroups": []} + + if r.status_code == 200: + response = r.json() + membership_details = response["data"] + for membership in membership_details: + user_membership["googleGroups"].append(membership["membership"]["name"]) + + return user, user_membership + + current_app.logger.error(f"Response Code:{r.status_code} {r.text}") + + def create_user_roles(profile): """Creates new roles based on profile information. @@ -375,7 +415,6 @@ class Ping(Resource): # you can either discover these dynamically or simply configure them access_token_url = current_app.config.get("PING_ACCESS_TOKEN_URL") - user_api_url = current_app.config.get("PING_USER_API_URL") secret = current_app.config.get("PING_SECRET") @@ -391,7 +430,12 @@ class Ping(Resource): error_code = validate_id_token(id_token, args["clientId"], jwks_url) if error_code: return error_code - user, profile = retrieve_user(user_api_url, access_token) + + user, profile = retrieve_user_memberships( + current_app.config.get("PING_USER_API_URL"), + current_app.config.get("PING_USER_MEMBERSHIP_URL"), + access_token + ) roles = create_user_roles(profile) update_user(user, profile, roles) diff --git a/lemur/plugins/bases/__init__.py b/lemur/plugins/bases/__init__.py index 9ce6289b..71ee2eb3 100644 --- a/lemur/plugins/bases/__init__.py +++ b/lemur/plugins/bases/__init__.py @@ -3,3 +3,4 @@ from .issuer import IssuerPlugin # noqa from .source import SourcePlugin # noqa from .notification import NotificationPlugin, ExpirationNotificationPlugin # noqa from .export import ExportPlugin # noqa +from .tls import TLSPlugin # noqa diff --git a/lemur/plugins/bases/tls.py b/lemur/plugins/bases/tls.py new file mode 100644 index 00000000..509ecd62 --- /dev/null +++ b/lemur/plugins/bases/tls.py @@ -0,0 +1,20 @@ +""" +.. module: lemur.plugins.bases.tls + :platform: Unix + :copyright: (c) 2021 by Netflix Inc., see AUTHORS for more + :license: Apache, see LICENSE for more details. + +.. moduleauthor:: Sayali Charhate +""" +from lemur.plugins.base import Plugin + + +class TLSPlugin(Plugin): + """ + This is the base class from which all supported + tls session providers will inherit from. + """ + type = "tls" + + def session(self, server_application): + raise NotImplementedError From a4f3ffa2d8fa4ed196b4ee449708b00c491352a3 Mon Sep 17 00:00:00 2001 From: sayali Date: Wed, 10 Feb 2021 12:12:52 -0800 Subject: [PATCH 269/314] never set admin third party --- lemur/auth/views.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lemur/auth/views.py b/lemur/auth/views.py index 9106665d..3ba3bbb3 100644 --- a/lemur/auth/views.py +++ b/lemur/auth/views.py @@ -196,7 +196,7 @@ def create_user_roles(profile): description="This is a google group based role created by Lemur", third_party=True, ) - if not role.third_party: + if (group != 'admin') and (not role.third_party): role = role_service.set_third_party(role.id, third_party_status=True) roles.append(role) else: From c71f3bfb5c557d15115703e21f1f59ae57418f2b Mon Sep 17 00:00:00 2001 From: sayali Date: Wed, 10 Feb 2021 13:14:31 -0800 Subject: [PATCH 270/314] membership API pagination --- lemur/auth/views.py | 33 ++++++++++++++++++--------------- 1 file changed, 18 insertions(+), 15 deletions(-) diff --git a/lemur/auth/views.py b/lemur/auth/views.py index 3ba3bbb3..83b67f6a 100644 --- a/lemur/auth/views.py +++ b/lemur/auth/views.py @@ -150,32 +150,35 @@ def retrieve_user_memberships(user_api_url, user_membership_api_url, access_toke code across the community, current implementation is config driven. Without user_membership_api_url configured, it is backward compatible. """ + tls_provider = plugins.get(current_app.config.get("PING_USER_MEMBERSHIP_TLS_PROVIDER")) # put user id in url user_membership_api_url = user_membership_api_url.replace("%user_id%", profile["userId"]) + session = tls_provider.session(current_app.config.get("PING_USER_MEMBERSHIP_SERVICE")) headers = {"Content-Type": "application/json"} data = {"relation": "DIRECT_ONLY", "groupFilter": {"type": "GOOGLE"}, "size": 500} - - tls_provider = plugins.get(current_app.config.get("PING_USER_MEMBERSHIP_TLS_PROVIDER")) - - # retrieve information about the current user - session = tls_provider.session(current_app.config.get("PING_USER_MEMBERSHIP_SERVICE")) - r = session.post(user_membership_api_url, data=json.dumps(data), headers=headers) - user_membership = {"email": profile["email"], "thumbnailPhotoUrl": profile["thumbnailPhotoUrl"], "googleGroups": []} + while True: + # retrieve information about the current user memberships + r = session.post(user_membership_api_url, data=json.dumps(data), headers=headers) - if r.status_code == 200: - response = r.json() - membership_details = response["data"] - for membership in membership_details: - user_membership["googleGroups"].append(membership["membership"]["name"]) + if r.status_code == 200: + response = r.json() + membership_details = response["data"] + for membership in membership_details: + user_membership["googleGroups"].append(membership["membership"]["name"]) - return user, user_membership - - current_app.logger.error(f"Response Code:{r.status_code} {r.text}") + if "nextPageToken" in response and response["nextPageToken"]: + data["nextPageToken"] = response["nextPageToken"] + else: + break + else: + current_app.logger.error(f"Response Code:{r.status_code} {r.text}") + break + return user, user_membership def create_user_roles(profile): From 533985ca356d48373f023a1176e670a14e23c1a7 Mon Sep 17 00:00:00 2001 From: sayali Date: Wed, 10 Feb 2021 18:09:20 -0800 Subject: [PATCH 271/314] pyjwt from 1.7.1 to 2.0.1 --- lemur/auth/service.py | 2 +- requirements.txt | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/lemur/auth/service.py b/lemur/auth/service.py index f954ce51..1705e0c9 100644 --- a/lemur/auth/service.py +++ b/lemur/auth/service.py @@ -77,7 +77,7 @@ def create_token(user, aid=None, ttl=None): else: payload["exp"] = ttl token = jwt.encode(payload, current_app.config["LEMUR_TOKEN_SECRET"]) - return token.decode("unicode_escape") + return token def login_required(f): diff --git a/requirements.txt b/requirements.txt index cf457308..28f34dfb 100644 --- a/requirements.txt +++ b/requirements.txt @@ -171,7 +171,7 @@ pycryptodomex==3.9.7 # via pyjks pyjks==20.0.0 # via -r requirements.in -pyjwt==1.7.1 +pyjwt==2.0.1 # via -r requirements.in pynacl==1.3.0 # via paramiko From 51e90f6fb240d0f279da1f726aa96c0c0ccb02a0 Mon Sep 17 00:00:00 2001 From: sayali Date: Wed, 10 Feb 2021 20:05:08 -0800 Subject: [PATCH 272/314] ECCPRIME256V1 as default for cert create API --- lemur/certificates/schemas.py | 4 ++-- lemur/tests/test_certificates.py | 7 ++++++- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/lemur/certificates/schemas.py b/lemur/certificates/schemas.py index 691e554d..1f99139a 100644 --- a/lemur/certificates/schemas.py +++ b/lemur/certificates/schemas.py @@ -89,7 +89,7 @@ class CertificateInputSchema(CertificateCreationSchema): csr = fields.String(allow_none=True, validate=validators.csr) key_type = fields.String( - validate=validate.OneOf(CERTIFICATE_KEY_TYPES), missing="RSA2048" + validate=validate.OneOf(CERTIFICATE_KEY_TYPES), missing="ECCPRIME256V1" ) notify = fields.Boolean(default=True) @@ -160,7 +160,7 @@ class CertificateInputSchema(CertificateCreationSchema): if data.get("body"): data["key_type"] = utils.get_key_type_from_certificate(data["body"]) else: - data["key_type"] = "RSA2048" # default value + data["key_type"] = "ECCPRIME256V1" # default value return missing.convert_validity_years(data) diff --git a/lemur/tests/test_certificates.py b/lemur/tests/test_certificates.py index c33743d0..962c40b4 100644 --- a/lemur/tests/test_certificates.py +++ b/lemur/tests/test_certificates.py @@ -325,6 +325,7 @@ def test_certificate_input_schema(client, authority): # make sure the defaults got set assert data["common_name"] == "test.example.com" assert data["country"] == "US" + assert data["key_type"] == "ECCPRIME256V1" assert len(data.keys()) == 19 @@ -349,10 +350,12 @@ def test_certificate_input_with_extensions(client, authority): }, }, "dnsProvider": None, + "keyType": "RSA2048" } data, errors = CertificateInputSchema().load(input_data) assert not errors + assert data["key_type"] == "RSA2048" def test_certificate_input_schema_parse_csr(authority): @@ -387,9 +390,11 @@ def test_certificate_input_schema_parse_csr(authority): data, errors = CertificateInputSchema().load(input_data) + assert not errors for san in data["extensions"]["sub_alt_names"]["names"]: assert san.value == test_san_dns - assert not errors + + assert data["key_type"] == "RSA2048" def test_certificate_out_of_range_date(client, authority): From ecf0997778517a051e3a43b71bd91a4c7aa2e8b7 Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Mon, 15 Feb 2021 13:32:06 +0000 Subject: [PATCH 273/314] Bump faker from 6.0.0 to 6.1.1 Bumps [faker](https://github.com/joke2k/faker) from 6.0.0 to 6.1.1. - [Release notes](https://github.com/joke2k/faker/releases) - [Changelog](https://github.com/joke2k/faker/blob/master/CHANGELOG.md) - [Commits](https://github.com/joke2k/faker/compare/v6.0.0...v6.1.1) Signed-off-by: dependabot-preview[bot] --- requirements-tests.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements-tests.txt b/requirements-tests.txt index 961f4e68..eecb0bbc 100644 --- a/requirements-tests.txt +++ b/requirements-tests.txt @@ -60,7 +60,7 @@ ecdsa==0.14.1 # sshpubkeys factory-boy==3.2.0 # via -r requirements-tests.in -faker==6.0.0 +faker==6.1.1 # via # -r requirements-tests.in # factory-boy From 4c5fb1f34e7b4504e8bc3d1ef505af2723ccac18 Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Mon, 15 Feb 2021 17:47:04 +0000 Subject: [PATCH 274/314] Bump sphinx from 3.4.3 to 3.5.0 Bumps [sphinx](https://github.com/sphinx-doc/sphinx) from 3.4.3 to 3.5.0. - [Release notes](https://github.com/sphinx-doc/sphinx/releases) - [Changelog](https://github.com/sphinx-doc/sphinx/blob/3.x/CHANGES) - [Commits](https://github.com/sphinx-doc/sphinx/compare/v3.4.3...v3.5.0) Signed-off-by: dependabot-preview[bot] --- requirements-docs.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements-docs.txt b/requirements-docs.txt index e6674f70..2e76e73f 100644 --- a/requirements-docs.txt +++ b/requirements-docs.txt @@ -40,7 +40,7 @@ snowballstemmer==2.0.0 # via sphinx sphinx-rtd-theme==0.5.1 # via -r requirements-docs.in -sphinx==3.4.3 +sphinx==3.5.0 # via # -r requirements-docs.in # sphinx-rtd-theme From 2c6abd7fe839eaa9d59720b66ff01eff237dd10c Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Mon, 15 Feb 2021 18:07:56 +0000 Subject: [PATCH 275/314] Bump botocore from 1.20.3 to 1.20.7 Bumps [botocore](https://github.com/boto/botocore) from 1.20.3 to 1.20.7. - [Release notes](https://github.com/boto/botocore/releases) - [Changelog](https://github.com/boto/botocore/blob/develop/CHANGELOG.rst) - [Commits](https://github.com/boto/botocore/compare/1.20.3...1.20.7) Signed-off-by: dependabot-preview[bot] --- requirements-tests.txt | 2 +- requirements.txt | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/requirements-tests.txt b/requirements-tests.txt index eecb0bbc..afdc8c55 100644 --- a/requirements-tests.txt +++ b/requirements-tests.txt @@ -24,7 +24,7 @@ boto3==1.17.3 # moto boto==2.49.0 # via moto -botocore==1.20.3 +botocore==1.20.7 # via # aws-xray-sdk # boto3 diff --git a/requirements.txt b/requirements.txt index 28f34dfb..a919fd13 100644 --- a/requirements.txt +++ b/requirements.txt @@ -33,7 +33,7 @@ blinker==1.4 # raven boto3==1.17.3 # via -r requirements.in -botocore==1.20.3 +botocore==1.20.7 # via # -r requirements.in # boto3 From 85d6cd1bfa61eccfef16f6eb2ad910d6ffa93002 Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Mon, 15 Feb 2021 18:36:46 +0000 Subject: [PATCH 276/314] Bump boto3 from 1.17.3 to 1.17.7 Bumps [boto3](https://github.com/boto/boto3) from 1.17.3 to 1.17.7. - [Release notes](https://github.com/boto/boto3/releases) - [Changelog](https://github.com/boto/boto3/blob/develop/CHANGELOG.rst) - [Commits](https://github.com/boto/boto3/compare/1.17.3...1.17.7) Signed-off-by: dependabot-preview[bot] --- requirements-tests.txt | 2 +- requirements.txt | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/requirements-tests.txt b/requirements-tests.txt index afdc8c55..50709ffc 100644 --- a/requirements-tests.txt +++ b/requirements-tests.txt @@ -18,7 +18,7 @@ bandit==1.7.0 # via -r requirements-tests.in black==20.8b1 # via -r requirements-tests.in -boto3==1.17.3 +boto3==1.17.7 # via # aws-sam-translator # moto diff --git a/requirements.txt b/requirements.txt index a919fd13..d50f38bd 100644 --- a/requirements.txt +++ b/requirements.txt @@ -31,7 +31,7 @@ blinker==1.4 # flask-mail # flask-principal # raven -boto3==1.17.3 +boto3==1.17.7 # via -r requirements.in botocore==1.20.7 # via From 683d9cd76950ac5f26c3e71f58955f214a256517 Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Mon, 15 Feb 2021 19:05:11 +0000 Subject: [PATCH 277/314] Bump cryptography from 3.4.2 to 3.4.5 Bumps [cryptography](https://github.com/pyca/cryptography) from 3.4.2 to 3.4.5. - [Release notes](https://github.com/pyca/cryptography/releases) - [Changelog](https://github.com/pyca/cryptography/blob/main/CHANGELOG.rst) - [Commits](https://github.com/pyca/cryptography/compare/3.4.2...3.4.5) Signed-off-by: dependabot-preview[bot] --- requirements-dev.txt | 2 +- requirements-tests.txt | 2 +- requirements.txt | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/requirements-dev.txt b/requirements-dev.txt index a4603adb..576ccd48 100644 --- a/requirements-dev.txt +++ b/requirements-dev.txt @@ -18,7 +18,7 @@ chardet==3.0.4 # via requests colorama==0.4.3 # via twine -cryptography==3.4.2 +cryptography==3.4.5 # via secretstorage distlib==0.3.0 # via virtualenv diff --git a/requirements-tests.txt b/requirements-tests.txt index 50709ffc..e7bc7e0c 100644 --- a/requirements-tests.txt +++ b/requirements-tests.txt @@ -44,7 +44,7 @@ click==7.1.2 # flask coverage==5.4 # via -r requirements-tests.in -cryptography==3.4.2 +cryptography==3.4.5 # via # moto # python-jose diff --git a/requirements.txt b/requirements.txt index d50f38bd..c6a21ef7 100644 --- a/requirements.txt +++ b/requirements.txt @@ -57,7 +57,7 @@ click==7.1.2 # via flask cloudflare==2.8.15 # via -r requirements.in -cryptography==3.4.2 +cryptography==3.4.5 # via # -r requirements.in # acme From e9860ee72ae773f316bae6d0161e28ae1b29825a Mon Sep 17 00:00:00 2001 From: Jasmine Schladen Date: Tue, 16 Feb 2021 17:54:57 -0800 Subject: [PATCH 278/314] Fix TTL calculation for API keys --- lemur/auth/service.py | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/lemur/auth/service.py b/lemur/auth/service.py index 1705e0c9..6ce9a5b6 100644 --- a/lemur/auth/service.py +++ b/lemur/auth/service.py @@ -75,7 +75,7 @@ def create_token(user, aid=None, ttl=None): if ttl == -1: del payload["exp"] else: - payload["exp"] = ttl + payload["exp"] = datetime.utcnow() + timedelta(days=ttl) token = jwt.encode(payload, current_app.config["LEMUR_TOKEN_SECRET"]) return token @@ -116,9 +116,8 @@ def login_required(f): return dict(message="Token has been revoked"), 403 if access_key.ttl != -1: current_time = datetime.utcnow() - expired_time = datetime.fromtimestamp( - access_key.issued_at + access_key.ttl - ) + # API key uses days + expired_time = datetime.fromtimestamp(access_key.issued_at) + timedelta(days=access_key.ttl) if current_time >= expired_time: return dict(message="Token has expired"), 403 From 42044e99aef1a55b5e759e11f29e60670484d7cc Mon Sep 17 00:00:00 2001 From: Jasmine Schladen Date: Tue, 16 Feb 2021 18:07:37 -0800 Subject: [PATCH 279/314] Attempt to fix docs build --- requirements-docs.in | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/requirements-docs.in b/requirements-docs.in index f025a85d..e0df9714 100644 --- a/requirements-docs.in +++ b/requirements-docs.in @@ -1,7 +1,11 @@ # Note: python-ldap from requirements breaks due to readthedocs.io not having the correct header files # The `make up-reqs` will update all requirement text files, and forcibly remove python-ldap # from requirements-docs.txt -# However, dependabot doesn't use `make up-reqs`, so `-r requirements.txt` has been removed completely. +# However, dependabot doesn't use `make up-reqs`, so we have to replicate the necessary dependencies here +# Without including these dependencies, the docs are unable to include generated autodocs +Flask + +# docs specific sphinx sphinxcontrib-httpdomain sphinx-rtd-theme From 8cabffcb70d4f9b3553a883a21cc162b1ffd1f81 Mon Sep 17 00:00:00 2001 From: Jasmine Schladen Date: Tue, 16 Feb 2021 18:13:04 -0800 Subject: [PATCH 280/314] Attempt to fix docs build --- requirements-docs.txt | 2 ++ 1 file changed, 2 insertions(+) diff --git a/requirements-docs.txt b/requirements-docs.txt index 2e76e73f..c33a9f9f 100644 --- a/requirements-docs.txt +++ b/requirements-docs.txt @@ -18,6 +18,8 @@ idna==2.9 # via requests imagesize==1.2.0 # via sphinx +flask==1.1.2 + # manual debug jinja2==2.11.3 # via sphinx markupsafe==1.1.1 From e607210fe9a8157ad05b6ac737fd2247e39e1736 Mon Sep 17 00:00:00 2001 From: Jasmine Schladen Date: Tue, 16 Feb 2021 18:22:07 -0800 Subject: [PATCH 281/314] Add .readthedocs.yml file --- .readthedocs.yml | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) create mode 100644 .readthedocs.yml diff --git a/.readthedocs.yml b/.readthedocs.yml new file mode 100644 index 00000000..54eb8741 --- /dev/null +++ b/.readthedocs.yml @@ -0,0 +1,22 @@ +# .readthedocs.yml +# Read the Docs configuration file +# See https://docs.readthedocs.io/en/stable/config-file/v2.html for details + +# Required +version: 2 + +# Build documentation in the docs/ directory with Sphinx +sphinx: + configuration: docs/conf.py + +# Build docs in all formats (html, pdf, epub) +formats: all + +# Set the version of Python and requirements required to build the docs +python: + version: 3.7 + install: + - requirements: requirements-docs.txt + - method: setuptools + path: . + system_packages: true \ No newline at end of file From 160ecd926d9b2af205b758129b0e7a1b2ec1e377 Mon Sep 17 00:00:00 2001 From: Jasmine Schladen Date: Wed, 17 Feb 2021 09:42:07 -0800 Subject: [PATCH 282/314] Debug docs --- .../lemur_email/templates/revocation.html | 163 ++++++++++++++++++ requirements-docs.in | 1 + requirements-docs.txt | 2 + 3 files changed, 166 insertions(+) create mode 100644 lemur/plugins/lemur_email/templates/revocation.html diff --git a/lemur/plugins/lemur_email/templates/revocation.html b/lemur/plugins/lemur_email/templates/revocation.html new file mode 100644 index 00000000..58625786 --- /dev/null +++ b/lemur/plugins/lemur_email/templates/revocation.html @@ -0,0 +1,163 @@ + + + + + + + + Lemur + + +
+ + + + + + + + + + +
+ + + + + + + + + + + + + + + + + + + + +
+ + + + + + +
+ Lemur +
+
+ + + + + + + + + + + + + + +
+ Your certificate has been revoked! +
+
+ + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + +
+ Hi, +
This is a Lemur certificate revocation notice. +
+ + + + + + + + +
+ {{ message.certificates.name }} + +
{{ message.certificates.endpoints | length }} Endpoints +
{{ message.certificates.owner }} +
{{ message.certificates.validityEnd | time }} +
{{ message.certificates.status }} +
Details +
+
+
+ If this revocation was unexpected, please reach out to {{ ", ".join(message.certificates.security_email) }}. +
+
Best,
Lemur +
+ + + + + + +
*All times are in UTC
+
+
+
+ + + + + + + + + +
You received this mandatory email announcement to update you about + important changes to your TLS certificate. +
+
© 2016 Lemur
+
+
+
+
diff --git a/requirements-docs.in b/requirements-docs.in index e0df9714..f2551059 100644 --- a/requirements-docs.in +++ b/requirements-docs.in @@ -4,6 +4,7 @@ # However, dependabot doesn't use `make up-reqs`, so we have to replicate the necessary dependencies here # Without including these dependencies, the docs are unable to include generated autodocs Flask +flask_replicated # docs specific sphinx diff --git a/requirements-docs.txt b/requirements-docs.txt index c33a9f9f..7d094b77 100644 --- a/requirements-docs.txt +++ b/requirements-docs.txt @@ -20,6 +20,8 @@ imagesize==1.2.0 # via sphinx flask==1.1.2 # manual debug +flask-replicated==1.4 + # manual debug jinja2==2.11.3 # via sphinx markupsafe==1.1.1 From 058877d76b9d46e728d68b65439222928a4edc5f Mon Sep 17 00:00:00 2001 From: Jasmine Schladen Date: Wed, 17 Feb 2021 09:47:52 -0800 Subject: [PATCH 283/314] Remove accidental file --- .../lemur_email/templates/revocation.html | 163 ------------------ 1 file changed, 163 deletions(-) delete mode 100644 lemur/plugins/lemur_email/templates/revocation.html diff --git a/lemur/plugins/lemur_email/templates/revocation.html b/lemur/plugins/lemur_email/templates/revocation.html deleted file mode 100644 index 58625786..00000000 --- a/lemur/plugins/lemur_email/templates/revocation.html +++ /dev/null @@ -1,163 +0,0 @@ - - - - - - - - Lemur - - -
- - - - - - - - - - -
- - - - - - - - - - - - - - - - - - - - -
- - - - - - -
- Lemur -
-
- - - - - - - - - - - - - - -
- Your certificate has been revoked! -
-
- - - - - - - - - - - - -
- - - - - - - - - - - - - - - - - - - - - -
- Hi, -
This is a Lemur certificate revocation notice. -
- - - - - - - - -
- {{ message.certificates.name }} - -
{{ message.certificates.endpoints | length }} Endpoints -
{{ message.certificates.owner }} -
{{ message.certificates.validityEnd | time }} -
{{ message.certificates.status }} -
Details -
-
-
- If this revocation was unexpected, please reach out to {{ ", ".join(message.certificates.security_email) }}. -
-
Best,
Lemur -
- - - - - - -
*All times are in UTC
-
-
-
- - - - - - - - - -
You received this mandatory email announcement to update you about - important changes to your TLS certificate. -
-
© 2016 Lemur
-
-
-
-
From 45b84bd08831a392156ca914816dff6e7fdfbdc4 Mon Sep 17 00:00:00 2001 From: Jasmine Schladen Date: Wed, 17 Feb 2021 12:44:02 -0800 Subject: [PATCH 284/314] Debug docs --- requirements-docs.in | 1 + requirements-docs.txt | 2 ++ 2 files changed, 3 insertions(+) diff --git a/requirements-docs.in b/requirements-docs.in index f2551059..a308f0ad 100644 --- a/requirements-docs.in +++ b/requirements-docs.in @@ -5,6 +5,7 @@ # Without including these dependencies, the docs are unable to include generated autodocs Flask flask_replicated +logmatic-python # docs specific sphinx diff --git a/requirements-docs.txt b/requirements-docs.txt index 7d094b77..0db302f7 100644 --- a/requirements-docs.txt +++ b/requirements-docs.txt @@ -24,6 +24,8 @@ flask-replicated==1.4 # manual debug jinja2==2.11.3 # via sphinx +logmatic-python==0.1.7 + # manual debug markupsafe==1.1.1 # via jinja2 packaging==20.3 From e29ebb4b61d6f14d8ff3e11c8b19d9028d869d84 Mon Sep 17 00:00:00 2001 From: Jasmine Schladen Date: Wed, 17 Feb 2021 12:44:32 -0800 Subject: [PATCH 285/314] Add arrow --- requirements-docs.in | 1 + requirements-docs.txt | 2 ++ 2 files changed, 3 insertions(+) diff --git a/requirements-docs.in b/requirements-docs.in index a308f0ad..987b5b34 100644 --- a/requirements-docs.in +++ b/requirements-docs.in @@ -3,6 +3,7 @@ # from requirements-docs.txt # However, dependabot doesn't use `make up-reqs`, so we have to replicate the necessary dependencies here # Without including these dependencies, the docs are unable to include generated autodocs +arrow Flask flask_replicated logmatic-python diff --git a/requirements-docs.txt b/requirements-docs.txt index 0db302f7..8c7735ff 100644 --- a/requirements-docs.txt +++ b/requirements-docs.txt @@ -6,6 +6,8 @@ # alabaster==0.7.12 # via sphinx +arrow==0.17.0 + # manual debug babel==2.8.0 # via sphinx certifi==2020.12.5 From ec9e1c0dd08d9ab8a0ad85bd4987c94b7cd78952 Mon Sep 17 00:00:00 2001 From: Jasmine Schladen Date: Wed, 17 Feb 2021 12:53:49 -0800 Subject: [PATCH 286/314] Add cryptography --- requirements-docs.in | 1 + requirements-docs.txt | 2 ++ 2 files changed, 3 insertions(+) diff --git a/requirements-docs.in b/requirements-docs.in index 987b5b34..bf8c22a2 100644 --- a/requirements-docs.in +++ b/requirements-docs.in @@ -4,6 +4,7 @@ # However, dependabot doesn't use `make up-reqs`, so we have to replicate the necessary dependencies here # Without including these dependencies, the docs are unable to include generated autodocs arrow +cryptography Flask flask_replicated logmatic-python diff --git a/requirements-docs.txt b/requirements-docs.txt index 8c7735ff..71282c7b 100644 --- a/requirements-docs.txt +++ b/requirements-docs.txt @@ -14,6 +14,8 @@ certifi==2020.12.5 # via requests chardet==3.0.4 # via requests +cryptography==3.4.5 + # manual debug docutils==0.15.2 # via sphinx idna==2.9 From b265ecf588067a2ae973486b6a3a78d616bca8e0 Mon Sep 17 00:00:00 2001 From: Jasmine Schladen Date: Wed, 17 Feb 2021 12:56:27 -0800 Subject: [PATCH 287/314] Make sure it's still broken if we add everything --- requirements-docs.in | 1 + requirements-docs.txt | 262 ++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 263 insertions(+) diff --git a/requirements-docs.in b/requirements-docs.in index bf8c22a2..a90c30d7 100644 --- a/requirements-docs.in +++ b/requirements-docs.in @@ -3,6 +3,7 @@ # from requirements-docs.txt # However, dependabot doesn't use `make up-reqs`, so we have to replicate the necessary dependencies here # Without including these dependencies, the docs are unable to include generated autodocs +-r requirements.txt arrow cryptography Flask diff --git a/requirements-docs.txt b/requirements-docs.txt index 71282c7b..6f641617 100644 --- a/requirements-docs.txt +++ b/requirements-docs.txt @@ -71,6 +71,268 @@ sphinxcontrib-serializinghtml==1.1.4 # via sphinx urllib3==1.25.8 # via requests +acme==1.12.0 + # via -r requirements.in +alembic-autogenerate-enums==0.0.2 + # via -r requirements.in +alembic==1.4.2 + # via flask-migrate +amqp==2.5.2 + # via kombu +aniso8601==8.0.0 + # via flask-restful +arrow==0.17.0 + # via -r requirements.in +asyncpool==1.0 + # via -r requirements.in +bcrypt==3.1.7 + # via + # flask-bcrypt + # paramiko +beautifulsoup4==4.9.1 + # via cloudflare +billiard==3.6.3.0 + # via celery +blinker==1.4 + # via + # flask-mail + # flask-principal + # raven +boto3==1.17.7 + # via -r requirements.in +botocore==1.20.7 + # via + # -r requirements.in + # boto3 + # s3transfer +celery[redis]==4.4.2 + # via -r requirements.in +certifi==2020.12.5 + # via + # -r requirements.in + # requests +certsrv==2.1.1 + # via -r requirements.in +cffi==1.14.0 + # via + # bcrypt + # cryptography + # pynacl +chardet==3.0.4 + # via requests +click==7.1.2 + # via flask +cloudflare==2.8.15 + # via -r requirements.in +cryptography==3.4.5 + # via + # -r requirements.in + # acme + # josepy + # paramiko + # pyopenssl + # requests +dnspython3==1.15.0 + # via -r requirements.in +dnspython==1.15.0 + # via dnspython3 +dyn==1.8.1 + # via -r requirements.in +flask-bcrypt==0.7.1 + # via -r requirements.in +flask-cors==3.0.10 + # via -r requirements.in +flask-mail==0.9.1 + # via -r requirements.in +flask-migrate==2.6.0 + # via -r requirements.in +flask-principal==0.4.0 + # via -r requirements.in +flask-replicated==1.4 + # via -r requirements.in +flask-restful==0.3.8 + # via -r requirements.in +flask-script==2.0.6 + # via -r requirements.in +flask-sqlalchemy==2.4.4 + # via + # -r requirements.in + # flask-migrate +flask==1.1.2 + # via + # -r requirements.in + # flask-bcrypt + # flask-cors + # flask-mail + # flask-migrate + # flask-principal + # flask-restful + # flask-script + # flask-sqlalchemy + # raven +future==0.18.2 + # via -r requirements.in +gunicorn==20.0.4 + # via -r requirements.in +hvac==0.10.8 + # via -r requirements.in +idna==2.9 + # via requests +inflection==0.5.1 + # via -r requirements.in +itsdangerous==1.1.0 + # via flask +javaobj-py3==0.4.0.1 + # via pyjks +jinja2==2.11.3 + # via + # -r requirements.in + # flask +jmespath==0.9.5 + # via + # boto3 + # botocore +josepy==1.3.0 + # via acme +jsonlines==1.2.0 + # via cloudflare +kombu==4.6.8 + # via celery +lockfile==0.12.2 + # via -r requirements.in +logmatic-python==0.1.7 + # via -r requirements.in +mako==1.1.2 + # via alembic +markupsafe==1.1.1 + # via + # jinja2 + # mako +marshmallow-sqlalchemy==0.23.1 + # via -r requirements.in +marshmallow==2.20.4 + # via + # -r requirements.in + # marshmallow-sqlalchemy +ndg-httpsclient==0.5.1 + # via -r requirements.in +paramiko==2.7.2 + # via -r requirements.in +pem==21.1.0 + # via -r requirements.in +psycopg2==2.8.6 + # via -r requirements.in +pyasn1-modules==0.2.8 + # via + # pyjks + # python-ldap +pyasn1==0.4.8 + # via + # ndg-httpsclient + # pyasn1-modules + # pyjks + # python-ldap +pycparser==2.20 + # via cffi +pycryptodomex==3.9.7 + # via pyjks +pyjks==20.0.0 + # via -r requirements.in +pyjwt==2.0.1 + # via -r requirements.in +pynacl==1.3.0 + # via paramiko +pyopenssl==20.0.1 + # via + # -r requirements.in + # acme + # josepy + # ndg-httpsclient + # requests +pyrfc3339==1.1 + # via acme +python-dateutil==2.8.1 + # via + # alembic + # arrow + # botocore +python-editor==1.0.4 + # via alembic +python-json-logger==0.1.11 + # via logmatic-python +python-ldap==3.3.1 + # via -r requirements.in +pytz==2019.3 + # via + # acme + # celery + # flask-restful + # pyrfc3339 +pyyaml==5.4.1 + # via + # -r requirements.in + # cloudflare +raven[flask]==6.10.0 + # via -r requirements.in +redis==3.5.3 + # via + # -r requirements.in + # celery +requests-toolbelt==0.9.1 + # via acme +requests[security]==2.25.1 + # via + # -r requirements.in + # acme + # certsrv + # cloudflare + # hvac + # requests-toolbelt +retrying==1.3.3 + # via -r requirements.in +s3transfer==0.3.3 + # via boto3 +six==1.15.0 + # via + # -r requirements.in + # acme + # bcrypt + # flask-cors + # flask-restful + # hvac + # josepy + # jsonlines + # pynacl + # pyopenssl + # python-dateutil + # retrying + # sqlalchemy-utils +soupsieve==2.0.1 + # via beautifulsoup4 +sqlalchemy-utils==0.36.8 + # via -r requirements.in +sqlalchemy==1.3.16 + # via + # alembic + # flask-sqlalchemy + # marshmallow-sqlalchemy + # sqlalchemy-utils +tabulate==0.8.7 + # via -r requirements.in +twofish==0.3.0 + # via pyjks +urllib3==1.25.8 + # via + # botocore + # requests +vine==1.3.0 + # via + # amqp + # celery +werkzeug==1.0.1 + # via flask +xmltodict==0.12.0 + # via -r requirements.in # The following packages are considered to be unsafe in a requirements file: # setuptools From 938b962a327c3722329065b44f84758b3ccc7a8b Mon Sep 17 00:00:00 2001 From: Jasmine Schladen Date: Wed, 17 Feb 2021 13:05:14 -0800 Subject: [PATCH 288/314] Undo add everything, add just sqlalchemy --- requirements-docs.in | 2 +- requirements-docs.txt | 264 +----------------------------------------- 2 files changed, 3 insertions(+), 263 deletions(-) diff --git a/requirements-docs.in b/requirements-docs.in index a90c30d7..755d0697 100644 --- a/requirements-docs.in +++ b/requirements-docs.in @@ -3,10 +3,10 @@ # from requirements-docs.txt # However, dependabot doesn't use `make up-reqs`, so we have to replicate the necessary dependencies here # Without including these dependencies, the docs are unable to include generated autodocs --r requirements.txt arrow cryptography Flask +Flask-SQLAlchemy flask_replicated logmatic-python diff --git a/requirements-docs.txt b/requirements-docs.txt index 6f641617..2beae50f 100644 --- a/requirements-docs.txt +++ b/requirements-docs.txt @@ -26,6 +26,8 @@ flask==1.1.2 # manual debug flask-replicated==1.4 # manual debug +flask-sqlalchemy==2.4.4 + # manual debug jinja2==2.11.3 # via sphinx logmatic-python==0.1.7 @@ -71,268 +73,6 @@ sphinxcontrib-serializinghtml==1.1.4 # via sphinx urllib3==1.25.8 # via requests -acme==1.12.0 - # via -r requirements.in -alembic-autogenerate-enums==0.0.2 - # via -r requirements.in -alembic==1.4.2 - # via flask-migrate -amqp==2.5.2 - # via kombu -aniso8601==8.0.0 - # via flask-restful -arrow==0.17.0 - # via -r requirements.in -asyncpool==1.0 - # via -r requirements.in -bcrypt==3.1.7 - # via - # flask-bcrypt - # paramiko -beautifulsoup4==4.9.1 - # via cloudflare -billiard==3.6.3.0 - # via celery -blinker==1.4 - # via - # flask-mail - # flask-principal - # raven -boto3==1.17.7 - # via -r requirements.in -botocore==1.20.7 - # via - # -r requirements.in - # boto3 - # s3transfer -celery[redis]==4.4.2 - # via -r requirements.in -certifi==2020.12.5 - # via - # -r requirements.in - # requests -certsrv==2.1.1 - # via -r requirements.in -cffi==1.14.0 - # via - # bcrypt - # cryptography - # pynacl -chardet==3.0.4 - # via requests -click==7.1.2 - # via flask -cloudflare==2.8.15 - # via -r requirements.in -cryptography==3.4.5 - # via - # -r requirements.in - # acme - # josepy - # paramiko - # pyopenssl - # requests -dnspython3==1.15.0 - # via -r requirements.in -dnspython==1.15.0 - # via dnspython3 -dyn==1.8.1 - # via -r requirements.in -flask-bcrypt==0.7.1 - # via -r requirements.in -flask-cors==3.0.10 - # via -r requirements.in -flask-mail==0.9.1 - # via -r requirements.in -flask-migrate==2.6.0 - # via -r requirements.in -flask-principal==0.4.0 - # via -r requirements.in -flask-replicated==1.4 - # via -r requirements.in -flask-restful==0.3.8 - # via -r requirements.in -flask-script==2.0.6 - # via -r requirements.in -flask-sqlalchemy==2.4.4 - # via - # -r requirements.in - # flask-migrate -flask==1.1.2 - # via - # -r requirements.in - # flask-bcrypt - # flask-cors - # flask-mail - # flask-migrate - # flask-principal - # flask-restful - # flask-script - # flask-sqlalchemy - # raven -future==0.18.2 - # via -r requirements.in -gunicorn==20.0.4 - # via -r requirements.in -hvac==0.10.8 - # via -r requirements.in -idna==2.9 - # via requests -inflection==0.5.1 - # via -r requirements.in -itsdangerous==1.1.0 - # via flask -javaobj-py3==0.4.0.1 - # via pyjks -jinja2==2.11.3 - # via - # -r requirements.in - # flask -jmespath==0.9.5 - # via - # boto3 - # botocore -josepy==1.3.0 - # via acme -jsonlines==1.2.0 - # via cloudflare -kombu==4.6.8 - # via celery -lockfile==0.12.2 - # via -r requirements.in -logmatic-python==0.1.7 - # via -r requirements.in -mako==1.1.2 - # via alembic -markupsafe==1.1.1 - # via - # jinja2 - # mako -marshmallow-sqlalchemy==0.23.1 - # via -r requirements.in -marshmallow==2.20.4 - # via - # -r requirements.in - # marshmallow-sqlalchemy -ndg-httpsclient==0.5.1 - # via -r requirements.in -paramiko==2.7.2 - # via -r requirements.in -pem==21.1.0 - # via -r requirements.in -psycopg2==2.8.6 - # via -r requirements.in -pyasn1-modules==0.2.8 - # via - # pyjks - # python-ldap -pyasn1==0.4.8 - # via - # ndg-httpsclient - # pyasn1-modules - # pyjks - # python-ldap -pycparser==2.20 - # via cffi -pycryptodomex==3.9.7 - # via pyjks -pyjks==20.0.0 - # via -r requirements.in -pyjwt==2.0.1 - # via -r requirements.in -pynacl==1.3.0 - # via paramiko -pyopenssl==20.0.1 - # via - # -r requirements.in - # acme - # josepy - # ndg-httpsclient - # requests -pyrfc3339==1.1 - # via acme -python-dateutil==2.8.1 - # via - # alembic - # arrow - # botocore -python-editor==1.0.4 - # via alembic -python-json-logger==0.1.11 - # via logmatic-python -python-ldap==3.3.1 - # via -r requirements.in -pytz==2019.3 - # via - # acme - # celery - # flask-restful - # pyrfc3339 -pyyaml==5.4.1 - # via - # -r requirements.in - # cloudflare -raven[flask]==6.10.0 - # via -r requirements.in -redis==3.5.3 - # via - # -r requirements.in - # celery -requests-toolbelt==0.9.1 - # via acme -requests[security]==2.25.1 - # via - # -r requirements.in - # acme - # certsrv - # cloudflare - # hvac - # requests-toolbelt -retrying==1.3.3 - # via -r requirements.in -s3transfer==0.3.3 - # via boto3 -six==1.15.0 - # via - # -r requirements.in - # acme - # bcrypt - # flask-cors - # flask-restful - # hvac - # josepy - # jsonlines - # pynacl - # pyopenssl - # python-dateutil - # retrying - # sqlalchemy-utils -soupsieve==2.0.1 - # via beautifulsoup4 -sqlalchemy-utils==0.36.8 - # via -r requirements.in -sqlalchemy==1.3.16 - # via - # alembic - # flask-sqlalchemy - # marshmallow-sqlalchemy - # sqlalchemy-utils -tabulate==0.8.7 - # via -r requirements.in -twofish==0.3.0 - # via pyjks -urllib3==1.25.8 - # via - # botocore - # requests -vine==1.3.0 - # via - # amqp - # celery -werkzeug==1.0.1 - # via flask -xmltodict==0.12.0 - # via -r requirements.in # The following packages are considered to be unsafe in a requirements file: # setuptools From 91f6f752db94aa3c64df17cb27095cf732ebfb98 Mon Sep 17 00:00:00 2001 From: Jasmine Schladen Date: Wed, 17 Feb 2021 13:08:40 -0800 Subject: [PATCH 289/314] Add inflection --- requirements-docs.in | 1 + requirements-docs.txt | 2 ++ 2 files changed, 3 insertions(+) diff --git a/requirements-docs.in b/requirements-docs.in index 755d0697..bc58be7e 100644 --- a/requirements-docs.in +++ b/requirements-docs.in @@ -8,6 +8,7 @@ cryptography Flask Flask-SQLAlchemy flask_replicated +inflection logmatic-python # docs specific diff --git a/requirements-docs.txt b/requirements-docs.txt index 2beae50f..89a4ea93 100644 --- a/requirements-docs.txt +++ b/requirements-docs.txt @@ -28,6 +28,8 @@ flask-replicated==1.4 # manual debug flask-sqlalchemy==2.4.4 # manual debug +inflection==0.5.1 + # manual debug jinja2==2.11.3 # via sphinx logmatic-python==0.1.7 From bfa1c067d97e8b5534c557ec0ae1ade8d4aff90a Mon Sep 17 00:00:00 2001 From: Jasmine Schladen Date: Wed, 17 Feb 2021 13:12:10 -0800 Subject: [PATCH 290/314] Add flask-migrate --- requirements-docs.in | 1 + requirements-docs.txt | 2 ++ 2 files changed, 3 insertions(+) diff --git a/requirements-docs.in b/requirements-docs.in index bc58be7e..8da716ad 100644 --- a/requirements-docs.in +++ b/requirements-docs.in @@ -6,6 +6,7 @@ arrow cryptography Flask +Flask-Migrate Flask-SQLAlchemy flask_replicated inflection diff --git a/requirements-docs.txt b/requirements-docs.txt index 89a4ea93..99e8dd83 100644 --- a/requirements-docs.txt +++ b/requirements-docs.txt @@ -24,6 +24,8 @@ imagesize==1.2.0 # via sphinx flask==1.1.2 # manual debug +flask-migrate==2.6.0 + # manual debug flask-replicated==1.4 # manual debug flask-sqlalchemy==2.4.4 From abdf544e06ec04a18de6382bffb03cbbd44af3b2 Mon Sep 17 00:00:00 2001 From: Jasmine Schladen Date: Wed, 17 Feb 2021 13:16:16 -0800 Subject: [PATCH 291/314] Add flask-restful --- requirements-docs.in | 1 + requirements-docs.txt | 2 ++ 2 files changed, 3 insertions(+) diff --git a/requirements-docs.in b/requirements-docs.in index 8da716ad..992755e0 100644 --- a/requirements-docs.in +++ b/requirements-docs.in @@ -7,6 +7,7 @@ arrow cryptography Flask Flask-Migrate +Flask-RESTful Flask-SQLAlchemy flask_replicated inflection diff --git a/requirements-docs.txt b/requirements-docs.txt index 99e8dd83..d749780b 100644 --- a/requirements-docs.txt +++ b/requirements-docs.txt @@ -28,6 +28,8 @@ flask-migrate==2.6.0 # manual debug flask-replicated==1.4 # manual debug +flask-restful==0.3.8 + # manual debug flask-sqlalchemy==2.4.4 # manual debug inflection==0.5.1 From c0c1022a5b9309cd31de6129510b18b495e521ff Mon Sep 17 00:00:00 2001 From: Jasmine Schladen Date: Wed, 17 Feb 2021 13:18:49 -0800 Subject: [PATCH 292/314] Add flask-bcrypt --- requirements-docs.in | 1 + requirements-docs.txt | 2 ++ 2 files changed, 3 insertions(+) diff --git a/requirements-docs.in b/requirements-docs.in index 992755e0..fcad63ef 100644 --- a/requirements-docs.in +++ b/requirements-docs.in @@ -6,6 +6,7 @@ arrow cryptography Flask +Flask-Bcrypt Flask-Migrate Flask-RESTful Flask-SQLAlchemy diff --git a/requirements-docs.txt b/requirements-docs.txt index d749780b..b613e052 100644 --- a/requirements-docs.txt +++ b/requirements-docs.txt @@ -24,6 +24,8 @@ imagesize==1.2.0 # via sphinx flask==1.1.2 # manual debug +flask-bcrypt==0.7.1 + # manual debug flask-migrate==2.6.0 # manual debug flask-replicated==1.4 From bbdacaccf916595afe6b9339144f0047ffa0f288 Mon Sep 17 00:00:00 2001 From: Jasmine Schladen Date: Wed, 17 Feb 2021 13:22:25 -0800 Subject: [PATCH 293/314] Add flask-principal --- requirements-docs.in | 1 + requirements-docs.txt | 2 ++ 2 files changed, 3 insertions(+) diff --git a/requirements-docs.in b/requirements-docs.in index fcad63ef..d2b2239c 100644 --- a/requirements-docs.in +++ b/requirements-docs.in @@ -8,6 +8,7 @@ cryptography Flask Flask-Bcrypt Flask-Migrate +Flask-Principal Flask-RESTful Flask-SQLAlchemy flask_replicated diff --git a/requirements-docs.txt b/requirements-docs.txt index b613e052..e596b829 100644 --- a/requirements-docs.txt +++ b/requirements-docs.txt @@ -28,6 +28,8 @@ flask-bcrypt==0.7.1 # manual debug flask-migrate==2.6.0 # manual debug +flask-principal==0.4.0 + # manual debug flask-replicated==1.4 # manual debug flask-restful==0.3.8 From 6aff89c1dc0c1ab9361787271def25a86c9208bf Mon Sep 17 00:00:00 2001 From: Jasmine Schladen Date: Wed, 17 Feb 2021 13:26:13 -0800 Subject: [PATCH 294/314] Add flask-mail, flask-script --- requirements-docs.in | 2 ++ requirements-docs.txt | 4 ++++ 2 files changed, 6 insertions(+) diff --git a/requirements-docs.in b/requirements-docs.in index d2b2239c..88c14dc3 100644 --- a/requirements-docs.in +++ b/requirements-docs.in @@ -7,9 +7,11 @@ arrow cryptography Flask Flask-Bcrypt +Flask-Mail Flask-Migrate Flask-Principal Flask-RESTful +Flask-Script Flask-SQLAlchemy flask_replicated inflection diff --git a/requirements-docs.txt b/requirements-docs.txt index e596b829..ad97eaed 100644 --- a/requirements-docs.txt +++ b/requirements-docs.txt @@ -26,6 +26,8 @@ flask==1.1.2 # manual debug flask-bcrypt==0.7.1 # manual debug +flask-mail==0.9.1 + # manual debug flask-migrate==2.6.0 # manual debug flask-principal==0.4.0 @@ -34,6 +36,8 @@ flask-replicated==1.4 # manual debug flask-restful==0.3.8 # manual debug +flask-script==2.0.6 + # manual debug flask-sqlalchemy==2.4.4 # manual debug inflection==0.5.1 From 5e46e2adf031162214430bd09a16f8d3c728261a Mon Sep 17 00:00:00 2001 From: Jasmine Schladen Date: Wed, 17 Feb 2021 13:38:15 -0800 Subject: [PATCH 295/314] Add raven --- requirements-docs.in | 1 + requirements-docs.txt | 2 ++ 2 files changed, 3 insertions(+) diff --git a/requirements-docs.in b/requirements-docs.in index 88c14dc3..ade68fba 100644 --- a/requirements-docs.in +++ b/requirements-docs.in @@ -16,6 +16,7 @@ Flask-SQLAlchemy flask_replicated inflection logmatic-python +raven[flask] # docs specific sphinx diff --git a/requirements-docs.txt b/requirements-docs.txt index ad97eaed..f8b71f8f 100644 --- a/requirements-docs.txt +++ b/requirements-docs.txt @@ -56,6 +56,8 @@ pyparsing==2.4.7 # via packaging pytz==2019.3 # via babel +raven[flask]==6.10.0 + # manual debug requests==2.25.1 # via sphinx six==1.15.0 From 1ab4fe278dfa8657bf99f0e2c4fd7b59bddf5e8a Mon Sep 17 00:00:00 2001 From: Jasmine Schladen Date: Wed, 17 Feb 2021 13:41:27 -0800 Subject: [PATCH 296/314] Add flask-cors --- requirements-docs.in | 1 + requirements-docs.txt | 2 ++ 2 files changed, 3 insertions(+) diff --git a/requirements-docs.in b/requirements-docs.in index ade68fba..11c4c1d1 100644 --- a/requirements-docs.in +++ b/requirements-docs.in @@ -7,6 +7,7 @@ arrow cryptography Flask Flask-Bcrypt +Flask-Cors Flask-Mail Flask-Migrate Flask-Principal diff --git a/requirements-docs.txt b/requirements-docs.txt index f8b71f8f..56bfd882 100644 --- a/requirements-docs.txt +++ b/requirements-docs.txt @@ -26,6 +26,8 @@ flask==1.1.2 # manual debug flask-bcrypt==0.7.1 # manual debug +flask-cors==3.0.10 + # manual debug flask-mail==0.9.1 # manual debug flask-migrate==2.6.0 From e9e79309c55a3faadfbc4dbc3621a7aec6c4cab6 Mon Sep 17 00:00:00 2001 From: Jasmine Schladen Date: Wed, 17 Feb 2021 13:43:49 -0800 Subject: [PATCH 297/314] Add sqlalchemy-utils --- requirements-docs.in | 1 + requirements-docs.txt | 2 ++ 2 files changed, 3 insertions(+) diff --git a/requirements-docs.in b/requirements-docs.in index 11c4c1d1..9dee5474 100644 --- a/requirements-docs.in +++ b/requirements-docs.in @@ -18,6 +18,7 @@ flask_replicated inflection logmatic-python raven[flask] +SQLAlchemy-Utils # docs specific sphinx diff --git a/requirements-docs.txt b/requirements-docs.txt index 56bfd882..9fdaeb63 100644 --- a/requirements-docs.txt +++ b/requirements-docs.txt @@ -89,6 +89,8 @@ sphinxcontrib-qthelp==1.0.3 # via sphinx sphinxcontrib-serializinghtml==1.1.4 # via sphinx +sqlalchemy-utils==0.36.8 + # manual debug urllib3==1.25.8 # via requests From 6aa6986a143eabf65ef489191178cc4c264b5586 Mon Sep 17 00:00:00 2001 From: Jasmine Schladen Date: Wed, 17 Feb 2021 13:45:55 -0800 Subject: [PATCH 298/314] Add pem --- requirements-docs.in | 1 + requirements-docs.txt | 2 ++ 2 files changed, 3 insertions(+) diff --git a/requirements-docs.in b/requirements-docs.in index 9dee5474..b6c8d2f4 100644 --- a/requirements-docs.in +++ b/requirements-docs.in @@ -17,6 +17,7 @@ Flask-SQLAlchemy flask_replicated inflection logmatic-python +pem raven[flask] SQLAlchemy-Utils diff --git a/requirements-docs.txt b/requirements-docs.txt index 9fdaeb63..7d99dd51 100644 --- a/requirements-docs.txt +++ b/requirements-docs.txt @@ -52,6 +52,8 @@ markupsafe==1.1.1 # via jinja2 packaging==20.3 # via sphinx +pem==21.1.0 + # manual debug pygments==2.6.1 # via sphinx pyparsing==2.4.7 From 8086d7afc068719e887645d79961e588478503f2 Mon Sep 17 00:00:00 2001 From: Jasmine Schladen Date: Wed, 17 Feb 2021 13:47:59 -0800 Subject: [PATCH 299/314] Add marshmallow --- requirements-docs.in | 2 ++ requirements-docs.txt | 4 ++++ 2 files changed, 6 insertions(+) diff --git a/requirements-docs.in b/requirements-docs.in index b6c8d2f4..46650ccc 100644 --- a/requirements-docs.in +++ b/requirements-docs.in @@ -17,6 +17,8 @@ Flask-SQLAlchemy flask_replicated inflection logmatic-python +marshmallow-sqlalchemy +marshmallow<2.20.5 #schema duplicate issues https://github.com/marshmallow-code/marshmallow-sqlalchemy/issues/121 pem raven[flask] SQLAlchemy-Utils diff --git a/requirements-docs.txt b/requirements-docs.txt index 7d99dd51..f175d8d0 100644 --- a/requirements-docs.txt +++ b/requirements-docs.txt @@ -50,6 +50,10 @@ logmatic-python==0.1.7 # manual debug markupsafe==1.1.1 # via jinja2 +marshmallow-sqlalchemy==0.23.1 + # manual debug +marshmallow==2.20.4 + # manual debug packaging==20.3 # via sphinx pem==21.1.0 From bfe3358b16582977e2eb75dfa6e844d4d85f7cce Mon Sep 17 00:00:00 2001 From: Jasmine Schladen Date: Wed, 17 Feb 2021 13:50:05 -0800 Subject: [PATCH 300/314] Add pyjwt --- requirements-docs.in | 1 + requirements-docs.txt | 2 ++ 2 files changed, 3 insertions(+) diff --git a/requirements-docs.in b/requirements-docs.in index 46650ccc..d82ea511 100644 --- a/requirements-docs.in +++ b/requirements-docs.in @@ -20,6 +20,7 @@ logmatic-python marshmallow-sqlalchemy marshmallow<2.20.5 #schema duplicate issues https://github.com/marshmallow-code/marshmallow-sqlalchemy/issues/121 pem +pyjwt raven[flask] SQLAlchemy-Utils diff --git a/requirements-docs.txt b/requirements-docs.txt index f175d8d0..d815df7d 100644 --- a/requirements-docs.txt +++ b/requirements-docs.txt @@ -60,6 +60,8 @@ pem==21.1.0 # manual debug pygments==2.6.1 # via sphinx +pyjwt==2.0.1 + # manual debug pyparsing==2.4.7 # via packaging pytz==2019.3 From 40e5c60c397ab47fce24de9cacb01183a90ccdc3 Mon Sep 17 00:00:00 2001 From: Jasmine Schladen Date: Wed, 17 Feb 2021 13:52:20 -0800 Subject: [PATCH 301/314] Fix some doc warnings --- CHANGELOG.rst | 4 ++-- docs/administration.rst | 6 +++--- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/CHANGELOG.rst b/CHANGELOG.rst index 67b792f8..8fb4f8ed 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -2,7 +2,7 @@ Changelog ========= 0.8.0 - `2020-11-13` -~~~~~~~~~~~~~~ +~~~~~~~~~~~~~~~~~~~~ This release comes after more than two years and contains many interesting new features and improvements. In addition to multiple new plugins, such as ACME-http01, ADCS, PowerDNS, UltraDNS, Entrust, SNS, many of Lemur's existing @@ -84,7 +84,7 @@ Upgrading 0.7 - `2018-05-07` -~~~~~~~~~~~~~~ +~~~~~~~~~~~~~~~~~~ This release adds LetsEncrypt support with DNS providers Dyn, Route53, and Cloudflare, and expands on the pending certificate functionality. The linux_dst plugin will also be deprecated and removed. diff --git a/docs/administration.rst b/docs/administration.rst index 3623f311..706c4027 100644 --- a/docs/administration.rst +++ b/docs/administration.rst @@ -1640,7 +1640,7 @@ Slack AWS (Source) ----- +------------ :Authors: Kevin Glisson , @@ -1653,7 +1653,7 @@ AWS (Source) AWS (Destination) ----- +----------------- :Authors: Kevin Glisson , @@ -1666,7 +1666,7 @@ AWS (Destination) AWS (SNS Notification) ------ +---------------------- :Authors: Jasmine Schladen From 8c666b7f0bd5f2f00be4d4ad92efd07125e70e41 Mon Sep 17 00:00:00 2001 From: Jasmine Schladen Date: Wed, 17 Feb 2021 13:53:22 -0800 Subject: [PATCH 302/314] Add gunicorn --- requirements-docs.in | 1 + requirements-docs.txt | 2 ++ 2 files changed, 3 insertions(+) diff --git a/requirements-docs.in b/requirements-docs.in index d82ea511..22161779 100644 --- a/requirements-docs.in +++ b/requirements-docs.in @@ -15,6 +15,7 @@ Flask-RESTful Flask-Script Flask-SQLAlchemy flask_replicated +gunicorn inflection logmatic-python marshmallow-sqlalchemy diff --git a/requirements-docs.txt b/requirements-docs.txt index d815df7d..79e44b94 100644 --- a/requirements-docs.txt +++ b/requirements-docs.txt @@ -42,6 +42,8 @@ flask-script==2.0.6 # manual debug flask-sqlalchemy==2.4.4 # manual debug +gunicorn==20.0.4 + # manual debug inflection==0.5.1 # manual debug jinja2==2.11.3 From dfad5ae968df2612b891a4a80618f2ffc93649ee Mon Sep 17 00:00:00 2001 From: Jasmine Schladen Date: Wed, 17 Feb 2021 13:56:04 -0800 Subject: [PATCH 303/314] Add pyopenssl --- requirements-docs.in | 1 + requirements-docs.txt | 2 ++ 2 files changed, 3 insertions(+) diff --git a/requirements-docs.in b/requirements-docs.in index 22161779..99d16b29 100644 --- a/requirements-docs.in +++ b/requirements-docs.in @@ -22,6 +22,7 @@ marshmallow-sqlalchemy marshmallow<2.20.5 #schema duplicate issues https://github.com/marshmallow-code/marshmallow-sqlalchemy/issues/121 pem pyjwt +pyOpenSSL raven[flask] SQLAlchemy-Utils diff --git a/requirements-docs.txt b/requirements-docs.txt index 79e44b94..1c53e890 100644 --- a/requirements-docs.txt +++ b/requirements-docs.txt @@ -64,6 +64,8 @@ pygments==2.6.1 # via sphinx pyjwt==2.0.1 # manual debug +pyopenssl==20.0.1 + # manual debug pyparsing==2.4.7 # via packaging pytz==2019.3 From c4a896ecf214f28832e1d01102864ae645121766 Mon Sep 17 00:00:00 2001 From: Jasmine Schladen Date: Wed, 17 Feb 2021 14:00:42 -0800 Subject: [PATCH 304/314] Add josepy --- CHANGELOG.rst | 21 ++++++--------------- docs/administration.rst | 6 +++--- requirements-docs.in | 1 + requirements-docs.txt | 2 ++ 4 files changed, 12 insertions(+), 18 deletions(-) diff --git a/CHANGELOG.rst b/CHANGELOG.rst index 8fb4f8ed..22a9341f 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -121,8 +121,7 @@ Happy Holidays! This is a big release with lots of bug fixes and features. Below Features: -* Per-certificate rotation policies, requires a database migration. The default rotation policy for all certificates. -is 30 days. Every certificate will gain a policy regardless of if auto-rotation is used. +* Per-certificate rotation policies, requires a database migration. The default rotation policy for all certificates is 30 days. Every certificate will gain a policy regardless of if auto-rotation is used. * Adds per-user API Keys, allows users to issue multiple long-lived API tokens with the same permission as the user creating them. * Adds the ability to revoke certificates from the Lemur UI/API, this is currently only supported for the digicert CIS and cfssl plugins. * Allow destinations to support an export function. Useful for file system destinations e.g. S3 to specify the export plugin you wish to run before being sent to the destination. @@ -166,13 +165,9 @@ Big thanks to neilschelly for quite a lot of improvements to the `lemur-cryptogr Other Highlights: -* Closed `#501 `_ - Endpoint resource as now kept in sync via an -expiration mechanism. Such that non-existant endpoints gracefully fall out of Lemur. Certificates are never -removed from Lemur. -* Closed `#551 `_ - Added the ability to create a 4096 bit key during certificate -creation. Closed `#528 `_ to ensure that issuer plugins supported the new 4096 bit keys. -* Closed `#566 `_ - Fixed an issue changing the notification status for certificates -without private keys. +* Closed `#501 `_ - Endpoint resource as now kept in sync via an expiration mechanism. Such that non-existant endpoints gracefully fall out of Lemur. Certificates are never removed from Lemur. +* Closed `#551 `_ - Added the ability to create a 4096 bit key during certificate creation. Closed `#528 `_ to ensure that issuer plugins supported the new 4096 bit keys. +* Closed `#566 `_ - Fixed an issue changing the notification status for certificates without private keys. * Closed `#594 `_ - Added `replaced` field indicating if a certificate has been superseded. * Closed `#602 `_ - AWS plugin added support for ALBs for endpoint tracking. @@ -196,12 +191,8 @@ Upgrading There have been quite a few issues closed in this release. Some notables: -* Closed `#284 `_ - Created new models for `Endpoints` created associated -AWS ELB endpoint tracking code. This was the major stated goal of this milestone and should serve as the basis for -future enhancements of Lemur's certificate 'deployment' capabilities. - -* Closed `#334 `_ - Lemur not has the ability -to restrict certificate expiration dates to weekdays. +* Closed `#284 `_ - Created new models for `Endpoints` created associated AWS ELB endpoint tracking code. This was the major stated goal of this milestone and should serve as the basis for future enhancements of Lemur's certificate 'deployment' capabilities. +* Closed `#334 `_ - Lemur not has the ability to restrict certificate expiration dates to weekdays. Several fixes/tweaks to Lemurs python3 support (thanks chadhendrie!) diff --git a/docs/administration.rst b/docs/administration.rst index 706c4027..5cf398d5 100644 --- a/docs/administration.rst +++ b/docs/administration.rst @@ -78,13 +78,13 @@ Basic Configuration The default connection pool size is 5 for sqlalchemy managed connections. Depending on the number of Lemur instances, please specify per instance connection pool size. Below is an example to set connection pool size to 10. - :: + :: SQLALCHEMY_POOL_SIZE = 10 .. warning:: -This is an optional setting but important to review and set for optimal database connection usage and for overall database performance. + This is an optional setting but important to review and set for optimal database connection usage and for overall database performance. .. data:: SQLALCHEMY_MAX_OVERFLOW :noindex: @@ -99,7 +99,7 @@ This is an optional setting but important to review and set for optimal database .. note:: -Specifying the `SQLALCHEMY_MAX_OVERFLOW` to 0 will enforce limit to not create connections above specified pool size. + Specifying the `SQLALCHEMY_MAX_OVERFLOW` to 0 will enforce limit to not create connections above specified pool size. .. data:: LEMUR_ALLOW_WEEKEND_EXPIRATION diff --git a/requirements-docs.in b/requirements-docs.in index 99d16b29..2254ea54 100644 --- a/requirements-docs.in +++ b/requirements-docs.in @@ -17,6 +17,7 @@ Flask-SQLAlchemy flask_replicated gunicorn inflection +josepy logmatic-python marshmallow-sqlalchemy marshmallow<2.20.5 #schema duplicate issues https://github.com/marshmallow-code/marshmallow-sqlalchemy/issues/121 diff --git a/requirements-docs.txt b/requirements-docs.txt index 1c53e890..b9149ee0 100644 --- a/requirements-docs.txt +++ b/requirements-docs.txt @@ -48,6 +48,8 @@ inflection==0.5.1 # manual debug jinja2==2.11.3 # via sphinx +josepy==1.3.0 + # manual debug logmatic-python==0.1.7 # manual debug markupsafe==1.1.1 From d4643d760a3e1db6662460295e64df88b12cba04 Mon Sep 17 00:00:00 2001 From: Jasmine Schladen Date: Wed, 17 Feb 2021 14:07:06 -0800 Subject: [PATCH 305/314] Add dnspython3 --- docs/administration.rst | 4 ++++ lemur/certificates/views.py | 1 + requirements-docs.in | 1 + requirements-docs.txt | 4 ++++ 4 files changed, 10 insertions(+) diff --git a/docs/administration.rst b/docs/administration.rst index 5cf398d5..4cf8e769 100644 --- a/docs/administration.rst +++ b/docs/administration.rst @@ -174,6 +174,7 @@ Basic Configuration .. data:: PUBLIC_CA_MAX_VALIDITY_DAYS :noindex: + Use this config to override the limit of 397 days of validity for certificates issued by CA/Browser compliant authorities. The authorities with cab_compliant option set to true will use this config. The example below overrides the default validity of 397 days and sets it to 365 days. @@ -185,6 +186,7 @@ Basic Configuration .. data:: DEFAULT_VALIDITY_DAYS :noindex: + Use this config to override the default validity of 365 days for certificates offered through Lemur UI. Any CA which is not CA/Browser Forum compliant will be using this value as default validity to be displayed on UI. Please note that this config is used for cert issuance only through Lemur UI. The example below overrides the default validity @@ -904,10 +906,12 @@ Active Directory Certificate Services Plugin .. data:: ADCS_START :noindex: + Used in ADCS-Sourceplugin. Minimum id of the first certificate to be returned. ID is increased by one until ADCS_STOP. Missing cert-IDs are ignored .. data:: ADCS_STOP :noindex: + Used for ADCS-Sourceplugin. Maximum id of the certificates returned. diff --git a/lemur/certificates/views.py b/lemur/certificates/views.py index 8d4e6954..f453ac4f 100644 --- a/lemur/certificates/views.py +++ b/lemur/certificates/views.py @@ -59,6 +59,7 @@ class CertificatesListValid(AuthenticatedResource): **Example request**: .. sourcecode:: http + GET /certificates/valid?filter=cn;*.test.example.net&owner=joe@example.com&page=1&count=20 HTTP/1.1 Host: example.com diff --git a/requirements-docs.in b/requirements-docs.in index 2254ea54..b60359dd 100644 --- a/requirements-docs.in +++ b/requirements-docs.in @@ -5,6 +5,7 @@ # Without including these dependencies, the docs are unable to include generated autodocs arrow cryptography +dnspython3 Flask Flask-Bcrypt Flask-Cors diff --git a/requirements-docs.txt b/requirements-docs.txt index b9149ee0..2cff64db 100644 --- a/requirements-docs.txt +++ b/requirements-docs.txt @@ -16,6 +16,10 @@ chardet==3.0.4 # via requests cryptography==3.4.5 # manual debug +dnspython3==1.15.0 + # manual debug +dnspython==1.15.0 + # manual debug docutils==0.15.2 # via sphinx idna==2.9 From 824a4b5910d1ebc1037be3bb2113b2f277bef115 Mon Sep 17 00:00:00 2001 From: Jasmine Schladen Date: Wed, 17 Feb 2021 14:17:37 -0800 Subject: [PATCH 306/314] add acme, boto, xmltodict --- docs/developer/plugins/index.rst | 9 +++++---- docs/production/index.rst | 2 +- docs/quickstart/index.rst | 6 ++++-- requirements-docs.in | 4 ++++ requirements-docs.txt | 8 ++++++++ 5 files changed, 22 insertions(+), 7 deletions(-) diff --git a/docs/developer/plugins/index.rst b/docs/developer/plugins/index.rst index 3834b0b9..8ce50014 100644 --- a/docs/developer/plugins/index.rst +++ b/docs/developer/plugins/index.rst @@ -154,9 +154,10 @@ An issuer may take some time to actually issue a certificate for an order. In t # retrieve an order, and check if there is an issued certificate attached to it `cancel_ordered_certificate()` should be implemented to allow an ordered certificate to be canceled before it is issued:: - def cancel_ordered_certificate(self, pending_cert, **kwargs): - # pending_cert should contain the necessary information to match an order - # kwargs can be given to provide information to the issuer for canceling + + def cancel_ordered_certificate(self, pending_cert, **kwargs): + # pending_cert should contain the necessary information to match an order + # kwargs can be given to provide information to the issuer for canceling Destination ----------- @@ -286,7 +287,7 @@ The `ExportPlugin` object requires the implementation of one function:: Custom TLS Provider ------- +------------------- Managing TLS at the enterprise scale could be hard and often organizations offer custom wrapper implementations. It could be ideal to use those while making calls to internal services. The `TLSPlugin` would help to achieve this. It requires the diff --git a/docs/production/index.rst b/docs/production/index.rst index fa0a7dec..3082ee4a 100644 --- a/docs/production/index.rst +++ b/docs/production/index.rst @@ -501,7 +501,7 @@ rely on celery to create the DNS record. This will change when we implement mix To create a HTTP compatible Authority, you first need to create a new destination that will be used to deploy the challenge token. Visit `Admin` -> `Destination` and click `Create`. The path you provide for the destination needs to -be the exact path that is called when the ACME providers calls ``http:///.well-known/acme-challenge/`. The +be the exact path that is called when the ACME providers calls `http:///.well-known/acme-challenge/`. The token part will be added dynamically by the acme_upload. Currently only the SFTP and S3 Bucket destination support the ACME HTTP challenge. diff --git a/docs/quickstart/index.rst b/docs/quickstart/index.rst index 3056029d..cf6d3c32 100644 --- a/docs/quickstart/index.rst +++ b/docs/quickstart/index.rst @@ -148,7 +148,7 @@ Before Lemur will run you need to fill in a few required variables in the config LEMUR_DEFAULT_ORGANIZATIONAL_UNIT Set Up Postgres --------------- +--------------- For production, a dedicated database is recommended, for this guide we will assume postgres has been installed and is on the same machine that Lemur is installed on. @@ -186,6 +186,7 @@ In addition to creating a new user, Lemur also creates a few default email notif Your database installation requires the pg_trgm extension. If you do not have this installed already, you can allow the script to install this for you by adding the SUPERUSER permission to the lemur database user. .. code-block:: bash + sudo -u postgres -i psql postgres=# ALTER USER lemur WITH SUPERUSER @@ -202,6 +203,7 @@ Additional notifications can be created through the UI or API. See :ref:`Creati .. note:: If you added the SUPERUSER permission to the lemur database user above, it is recommended you revoke that permission now. .. code-block:: bash + sudo -u postgres -i psql postgres=# ALTER USER lemur WITH NOSUPERUSER @@ -210,7 +212,7 @@ Additional notifications can be created through the UI or API. See :ref:`Creati .. note:: It is recommended that once the ``lemur`` user is created that you create individual users for every day access. There is currently no way for a user to self enroll for Lemur access, they must have an administrator create an account for them or be enrolled automatically through SSO. This can be done through the CLI or UI. See :ref:`Creating Users ` and :ref:`Command Line Interface ` for details. Set Up a Reverse Proxy ---------------------- +---------------------- By default, Lemur runs on port 8000. Even if you change this, under normal conditions you won't be able to bind to port 80. To get around this (and to avoid running Lemur as a privileged user, which you shouldn't), we need to set up a simple web proxy. There are many different web servers you can use for this, we like and recommend Nginx. diff --git a/requirements-docs.in b/requirements-docs.in index b60359dd..b21ada07 100644 --- a/requirements-docs.in +++ b/requirements-docs.in @@ -3,7 +3,10 @@ # from requirements-docs.txt # However, dependabot doesn't use `make up-reqs`, so we have to replicate the necessary dependencies here # Without including these dependencies, the docs are unable to include generated autodocs +acme arrow +boto3 +botocore cryptography dnspython3 Flask @@ -27,6 +30,7 @@ pyjwt pyOpenSSL raven[flask] SQLAlchemy-Utils +xmltodict # docs specific sphinx diff --git a/requirements-docs.txt b/requirements-docs.txt index 2cff64db..cfbeb3e5 100644 --- a/requirements-docs.txt +++ b/requirements-docs.txt @@ -4,12 +4,18 @@ # # pip-compile --no-index --output-file=requirements-docs.txt requirements-docs.in # +acme==1.12.0 + # manual debug alabaster==0.7.12 # via sphinx arrow==0.17.0 # manual debug babel==2.8.0 # via sphinx +boto3==1.17.7 + # manual debug +botocore==1.20.7 + # manual debug certifi==2020.12.5 # via requests chardet==3.0.4 @@ -111,6 +117,8 @@ sqlalchemy-utils==0.36.8 # manual debug urllib3==1.25.8 # via requests +xmltodict==0.12.0 + # manual debug # The following packages are considered to be unsafe in a requirements file: # setuptools From 47121906f521c0d81912404c18b6ea6655d51aa9 Mon Sep 17 00:00:00 2001 From: Jasmine Schladen Date: Wed, 17 Feb 2021 14:25:04 -0800 Subject: [PATCH 307/314] Add Cloudflare, retrying --- docs/guide/index.rst | 1 + docs/quickstart/index.rst | 4 ++-- requirements-docs.in | 2 ++ requirements-docs.txt | 4 ++++ 4 files changed, 9 insertions(+), 2 deletions(-) diff --git a/docs/guide/index.rst b/docs/guide/index.rst index b06a95e0..f3efcb14 100644 --- a/docs/guide/index.rst +++ b/docs/guide/index.rst @@ -65,6 +65,7 @@ Import an Existing Certificate You can add notification options and upload the created certificate to a destination, both of these are editable features and can be changed after the certificate has been created. +.. _CreateANewUser: Create a New User ~~~~~~~~~~~~~~~~~ diff --git a/docs/quickstart/index.rst b/docs/quickstart/index.rst index cf6d3c32..f972c2ef 100644 --- a/docs/quickstart/index.rst +++ b/docs/quickstart/index.rst @@ -191,7 +191,7 @@ Your database installation requires the pg_trgm extension. If you do not have th psql postgres=# ALTER USER lemur WITH SUPERUSER -Additional notifications can be created through the UI or API. See :ref:`Creating Notifications ` and :ref:`Command Line Interface ` for details. +Additional notifications can be created through the UI or API. See :ref:`Notification Options ` and :ref:`Command Line Interface ` for details. **Make note of the password used as this will be used during first login to the Lemur UI.** @@ -209,7 +209,7 @@ Additional notifications can be created through the UI or API. See :ref:`Creati postgres=# ALTER USER lemur WITH NOSUPERUSER -.. note:: It is recommended that once the ``lemur`` user is created that you create individual users for every day access. There is currently no way for a user to self enroll for Lemur access, they must have an administrator create an account for them or be enrolled automatically through SSO. This can be done through the CLI or UI. See :ref:`Creating Users ` and :ref:`Command Line Interface ` for details. +.. note:: It is recommended that once the ``lemur`` user is created that you create individual users for every day access. There is currently no way for a user to self enroll for Lemur access, they must have an administrator create an account for them or be enrolled automatically through SSO. This can be done through the CLI or UI. See :ref:`Creating a New User ` and :ref:`Command Line Interface ` for details. Set Up a Reverse Proxy ---------------------- diff --git a/requirements-docs.in b/requirements-docs.in index b21ada07..6b8f5a81 100644 --- a/requirements-docs.in +++ b/requirements-docs.in @@ -7,6 +7,7 @@ acme arrow boto3 botocore +CloudFlare cryptography dnspython3 Flask @@ -29,6 +30,7 @@ pem pyjwt pyOpenSSL raven[flask] +retrying SQLAlchemy-Utils xmltodict diff --git a/requirements-docs.txt b/requirements-docs.txt index cfbeb3e5..f3e967c6 100644 --- a/requirements-docs.txt +++ b/requirements-docs.txt @@ -20,6 +20,8 @@ certifi==2020.12.5 # via requests chardet==3.0.4 # via requests +cloudflare==2.8.15 + # manual debug cryptography==3.4.5 # manual debug dnspython3==1.15.0 @@ -84,6 +86,8 @@ pytz==2019.3 # via babel raven[flask]==6.10.0 # manual debug +retrying==1.3.3 + # manual debug requests==2.25.1 # via sphinx six==1.15.0 From e464e62d01912325df6c33bbaa42fcf94ff4f2a2 Mon Sep 17 00:00:00 2001 From: Jasmine Schladen Date: Wed, 17 Feb 2021 14:33:00 -0800 Subject: [PATCH 308/314] Add dyn --- docs/developer/plugins/index.rst | 3 +-- requirements-docs.in | 1 + requirements-docs.txt | 2 ++ 3 files changed, 4 insertions(+), 2 deletions(-) diff --git a/docs/developer/plugins/index.rst b/docs/developer/plugins/index.rst index 8ce50014..517b5a0d 100644 --- a/docs/developer/plugins/index.rst +++ b/docs/developer/plugins/index.rst @@ -145,8 +145,7 @@ The `IssuerPlugin` doesn't have any options like Destination, Source, and Notifi any fields you might need to submit a request to a third party. If there are additional options you need in your plugin feel free to open an issue, or look into adding additional options to issuers yourself. -Asynchronous Certificates -^^^^^^^^^^^^^^^^^^^^^^^^^ +**Asynchronous Certificates** An issuer may take some time to actually issue a certificate for an order. In this case, a `PendingCertificate` is returned, which holds information to recreate a `Certificate` object at a later time. Then, `get_ordered_certificate()` should be run periodically via `python manage.py pending_certs fetch -i all` to attempt to retrieve an ordered certificate:: def get_ordered_ceriticate(self, order_id): diff --git a/requirements-docs.in b/requirements-docs.in index 6b8f5a81..93dd3968 100644 --- a/requirements-docs.in +++ b/requirements-docs.in @@ -10,6 +10,7 @@ botocore CloudFlare cryptography dnspython3 +dyn Flask Flask-Bcrypt Flask-Cors diff --git a/requirements-docs.txt b/requirements-docs.txt index f3e967c6..b18706ae 100644 --- a/requirements-docs.txt +++ b/requirements-docs.txt @@ -30,6 +30,8 @@ dnspython==1.15.0 # manual debug docutils==0.15.2 # via sphinx +dyn==1.8.1 + # manual debug idna==2.9 # via requests imagesize==1.2.0 From 40f62a0ad7abb4792ca44cc9755e87a4e1aa5ed5 Mon Sep 17 00:00:00 2001 From: Jasmine Schladen Date: Wed, 17 Feb 2021 14:35:55 -0800 Subject: [PATCH 309/314] Add tabulate --- requirements-docs.in | 1 + requirements-docs.txt | 2 ++ 2 files changed, 3 insertions(+) diff --git a/requirements-docs.in b/requirements-docs.in index 93dd3968..07b3e987 100644 --- a/requirements-docs.in +++ b/requirements-docs.in @@ -33,6 +33,7 @@ pyOpenSSL raven[flask] retrying SQLAlchemy-Utils +tabulate xmltodict # docs specific diff --git a/requirements-docs.txt b/requirements-docs.txt index b18706ae..41d5133b 100644 --- a/requirements-docs.txt +++ b/requirements-docs.txt @@ -121,6 +121,8 @@ sphinxcontrib-serializinghtml==1.1.4 # via sphinx sqlalchemy-utils==0.36.8 # manual debug +tabulate==0.8.7 + # manual debug urllib3==1.25.8 # via requests xmltodict==0.12.0 From 24c1415983a75eb29d77d7554e06efb614c33c4b Mon Sep 17 00:00:00 2001 From: Jasmine Schladen Date: Wed, 17 Feb 2021 14:47:53 -0800 Subject: [PATCH 310/314] Fix AuthoritiesList post --- lemur/authorities/views.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/lemur/authorities/views.py b/lemur/authorities/views.py index 094a5a74..aa3fbf6d 100644 --- a/lemur/authorities/views.py +++ b/lemur/authorities/views.py @@ -218,8 +218,7 @@ class AuthoritiesList(AuthenticatedResource): :arg parent: the parent authority if this is to be a subca :arg signingAlgorithm: algorithm used to sign the authority :arg keyType: key type - :arg sensitivity: the sensitivity of the root key, for CloudCA this determines if the root keys are stored - in an HSM + :arg sensitivity: the sensitivity of the root key, for CloudCA this determines if the root keys are stored in an HSM :arg keyName: name of the key to store in the HSM (CloudCA) :arg serialNumber: serial number of the authority :arg firstSerial: specifies the starting serial number for certificates issued off of this authority From 5f2e32ff92bf4d8af9407c07ffc28342dd74b635 Mon Sep 17 00:00:00 2001 From: Jasmine Schladen Date: Wed, 17 Feb 2021 14:52:28 -0800 Subject: [PATCH 311/314] Fix AuthorityVisualizations --- lemur/authorities/views.py | 59 +++++++++++++++++++++++++++----------- 1 file changed, 42 insertions(+), 17 deletions(-) diff --git a/lemur/authorities/views.py b/lemur/authorities/views.py index aa3fbf6d..800c9975 100644 --- a/lemur/authorities/views.py +++ b/lemur/authorities/views.py @@ -493,23 +493,48 @@ class CertificateAuthority(AuthenticatedResource): class AuthorityVisualizations(AuthenticatedResource): def get(self, authority_id): """ - {"name": "flare", - "children": [ - { - "name": "analytics", - "children": [ - { - "name": "cluster", - "children": [ - {"name": "AgglomerativeCluster", "size": 3938}, - {"name": "CommunityStructure", "size": 3812}, - {"name": "HierarchicalCluster", "size": 6714}, - {"name": "MergeEdge", "size": 743} - ] - } - ] - } - ]} + .. http:get:: /authorities/1/visualize + + Authority visualization + + **Example request**: + + .. sourcecode:: http + + GET /certificates/1/visualize HTTP/1.1 + Host: example.com + Accept: application/json, text/javascript + + **Example response**: + + .. sourcecode:: http + + HTTP/1.1 200 OK + Vary: Accept + Content-Type: text/javascript + + {"name": "flare", + "children": [ + { + "name": "analytics", + "children": [ + { + "name": "cluster", + "children": [ + {"name": "AgglomerativeCluster", "size": 3938}, + {"name": "CommunityStructure", "size": 3812}, + {"name": "HierarchicalCluster", "size": 6714}, + {"name": "MergeEdge", "size": 743} + ] + } + ] + } + ] + } + + :reqheader Authorization: OAuth token to authenticate + :statuscode 200: no error + :statuscode 403: unauthenticated """ authority = service.get(authority_id) return dict( From 00c64ba52faae3de639426d41f4c6508a4563352 Mon Sep 17 00:00:00 2001 From: Jasmine Schladen Date: Wed, 17 Feb 2021 15:02:49 -0800 Subject: [PATCH 312/314] More doc style fixes --- lemur/authorities/views.py | 50 +++++++++++++++---------------- lemur/plugins/lemur_aws/plugin.py | 3 +- 2 files changed, 27 insertions(+), 26 deletions(-) diff --git a/lemur/authorities/views.py b/lemur/authorities/views.py index 800c9975..16441719 100644 --- a/lemur/authorities/views.py +++ b/lemur/authorities/views.py @@ -132,31 +132,31 @@ class AuthoritiesList(AuthenticatedResource): Accept: application/json, text/javascript Content-Type: application/json;charset=UTF-8 - { - "country": "US", - "state": "California", - "location": "Los Gatos", - "organization": "Netflix", - "organizationalUnit": "Operations", - "type": "root", - "signingAlgorithm": "sha256WithRSA", - "sensitivity": "medium", - "keyType": "RSA2048", - "plugin": { - "slug": "cloudca-issuer" - }, - "name": "TimeTestAuthority5", - "owner": "secure@example.com", - "description": "test", - "commonName": "AcommonName", - "validityYears": "20", - "extensions": { - "subAltNames": { - "names": [] - }, - "custom": [] - } - } + { + "country": "US", + "state": "California", + "location": "Los Gatos", + "organization": "Netflix", + "organizationalUnit": "Operations", + "type": "root", + "signingAlgorithm": "sha256WithRSA", + "sensitivity": "medium", + "keyType": "RSA2048", + "plugin": { + "slug": "cloudca-issuer" + }, + "name": "TimeTestAuthority5", + "owner": "secure@example.com", + "description": "test", + "commonName": "AcommonName", + "validityYears": "20", + "extensions": { + "subAltNames": { + "names": [] + }, + "custom": [] + } + } **Example response**: diff --git a/lemur/plugins/lemur_aws/plugin.py b/lemur/plugins/lemur_aws/plugin.py index efcce4d0..61c64dab 100644 --- a/lemur/plugins/lemur_aws/plugin.py +++ b/lemur/plugins/lemur_aws/plugin.py @@ -450,7 +450,8 @@ class S3DestinationPlugin(ExportDestinationPlugin): def upload_acme_token(self, token_path, token, options, **kwargs): """ - This is called from the acme http challenge + This is called from the acme http challenge + :param self: :param token_path: :param token: From da9e949e89a86b5a1d82af1f62b2f207c0026eb6 Mon Sep 17 00:00:00 2001 From: Jasmine Schladen Date: Wed, 17 Feb 2021 15:08:36 -0800 Subject: [PATCH 313/314] Remove extra spaces --- lemur/destinations/service.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/lemur/destinations/service.py b/lemur/destinations/service.py index 7bae57f0..5e302c6d 100644 --- a/lemur/destinations/service.py +++ b/lemur/destinations/service.py @@ -21,7 +21,7 @@ def create(label, plugin_name, options, description=None): :param label: Destination common name :param description: - :rtype : Destination + :rtype: Destination :return: New destination """ # remove any sub-plugin objects before try to save the json options @@ -50,7 +50,7 @@ def update(destination_id, label, plugin_name, options, description): :param plugin_name: :param options: :param description: - :rtype : Destination + :rtype: Destination :return: """ destination = get(destination_id) @@ -81,7 +81,7 @@ def get(destination_id): Retrieves an destination by its lemur assigned ID. :param destination_id: Lemur assigned ID - :rtype : Destination + :rtype: Destination :return: """ return database.get(Destination, destination_id) From 360e4c61540d0202c044ea35160d7fc0c4d5f461 Mon Sep 17 00:00:00 2001 From: Jasmine Schladen Date: Wed, 17 Feb 2021 15:10:15 -0800 Subject: [PATCH 314/314] Remove extra spaces --- lemur/notifications/service.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/lemur/notifications/service.py b/lemur/notifications/service.py index 5bc5f3e1..fd8ba20f 100644 --- a/lemur/notifications/service.py +++ b/lemur/notifications/service.py @@ -94,7 +94,7 @@ def create(label, plugin_name, options, description, certificates): :param options: :param description: :param certificates: - :rtype : Notification + :rtype: Notification :return: """ notification = Notification( @@ -115,7 +115,7 @@ def update(notification_id, label, plugin_name, options, description, active, ce :param description: :param active: :param certificates: - :rtype : Notification + :rtype: Notification :return: """ notification = get(notification_id) @@ -144,7 +144,7 @@ def get(notification_id): Retrieves an notification by its lemur assigned ID. :param notification_id: Lemur assigned ID - :rtype : Notification + :rtype: Notification :return: """ return database.get(Notification, notification_id)