diff --git a/lemur/certificates/models.py b/lemur/certificates/models.py index 9646d856..fcf89243 100644 --- a/lemur/certificates/models.py +++ b/lemur/certificates/models.py @@ -62,7 +62,6 @@ def get_sequence(name): def get_or_increase_name(name): - name = '-'.join(name.strip().split(' ')) certificates = Certificate.query.filter(Certificate.name.ilike('{0}%'.format(name))).all() if not certificates: @@ -138,7 +137,7 @@ class Certificate(db.Model): # when destinations are appended they require a valid name. if kwargs.get('name'): - self.name = get_or_increase_name(kwargs['name']) + self.name = get_or_increase_name(defaults.text_to_slug(kwargs['name'])) else: self.name = get_or_increase_name( defaults.certificate_name(self.cn, self.issuer, self.not_before, self.not_after, self.san)) diff --git a/lemur/common/defaults.py b/lemur/common/defaults.py index bdee6563..d933cb9b 100644 --- a/lemur/common/defaults.py +++ b/lemur/common/defaults.py @@ -1,8 +1,25 @@ +import re +import unicodedata + from cryptography import x509 from flask import current_app from lemur.constants import SAN_NAMING_TEMPLATE, DEFAULT_NAMING_TEMPLATE +def text_to_slug(value): + """Normalize a string to a "slug" value, stripping character accents and removing non-alphanum characters.""" + + # Strip all character accents (ä => a): decompose Unicode characters and then drop combining chars. + value = ''.join(c for c in unicodedata.normalize('NFKD', value) if not unicodedata.combining(c)) + + # Replace all remaining non-alphanumeric characters with '-'. Multiple characters get collapsed into a single dash. + # Except, keep 'xn--' used in IDNA domain names as is. + value = re.sub(r'[^A-Za-z0-9.]+(?