<commit_before>import re
import unicodedata

from cryptography import x509
from cryptography.hazmat.primitives.serialization import Encoding
from flask import current_app

from lemur.common.utils import is_selfsigned
from lemur.extensions import sentry
from lemur.constants import SAN_NAMING_TEMPLATE, DEFAULT_NAMING_TEMPLATE


def text_to_slug(value, joiner="-"):
    """
    Normalize a string to a "slug" value, stripping character accents and removing non-alphanum characters.
    A series of non-alphanumeric characters is replaced with the joiner character.
    """

    # Strip all character accents: 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 joiner string. Multiple characters get collapsed into a
    # single joiner. Except, keep 'xn--' used in IDNA domain names as is.
    value = re.sub(r"[^A-Za-z0-9.]+(?<!xn--)", joiner, value)

    # '-' in the beginning or end of string looks ugly.
    return value.strip(joiner)


def certificate_name(common_name, issuer, not_before, not_after, san):
    """
    Create a name for our certificate. A naming standard
    is based on a series of templates. The name includes
    useful information such as Common Name, Validation dates,
    and Issuer.

    :param san:
    :param common_name:
    :param not_after:
    :param issuer:
    :param not_before:
    :rtype: str
    :return:
    """
    if san:
        t = SAN_NAMING_TEMPLATE
    else:
        t = DEFAULT_NAMING_TEMPLATE

    temp = t.format(
        subject=common_name,
        issuer=issuer.replace(" ", ""),
        not_before=not_before.strftime("%Y%m%d"),
        not_after=not_after.strftime("%Y%m%d"),
    )

    temp = temp.replace("*", "WILDCARD")
    return text_to_slug(temp)


def signing_algorithm(cert):
    return cert.signature_hash_algorithm.name


def common_name(cert):
    """
    Attempts to get a sane common name from a given certificate.

    :param cert:
    :return: Common name or None
    """
    try:
        subject_oid = cert.subject.get_attributes_for_oid(x509.OID_COMMON_NAME)
        if len(subject_oid) > 0:
            return subject_oid[0].value.strip()
        return None
    except Exception as e:
        sentry.captureException()
        current_app.logger.error(
            {
                "message": "Unable to get common name",
                "error": e,
                "public_key": cert.public_bytes(Encoding.PEM).decode("utf-8")
            },
            exc_info=True
        )


def organization(cert):
    """
    Attempt to get the organization name from a given certificate.
    :param cert:
    :return:
    """
    try:
        return cert.subject.get_attributes_for_oid(x509.OID_ORGANIZATION_NAME)[
            0
        ].value.strip()
    except Exception as e:
        sentry.captureException()
        current_app.logger.error("Unable to get organization! {0}".format(e))


def organizational_unit(cert):
    """
    Attempt to get the organization unit from a given certificate.
    :param cert:
    :return:
    """
    try:
        ou = cert.subject.get_attributes_for_oid(x509.OID_ORGANIZATIONAL_UNIT_NAME)
        if not ou:
            return None

        return ou[0].value.strip()
    except Exception as e:
        sentry.captureException()
        current_app.logger.error("Unable to get organizational unit! {0}".format(e))


def country(cert):
    """
    Attempt to get the country from a given certificate.
    :param cert:
    :return:
    """
    try:
        return cert.subject.get_attributes_for_oid(x509.OID_COUNTRY_NAME)[
            0
        ].value.strip()
    except Exception as e:
        sentry.captureException()
        current_app.logger.error("Unable to get country! {0}".format(e))


def state(cert):
    """
    Attempt to get the from a given certificate.
    :param cert:
    :return:
    """
    try:
        return cert.subject.get_attributes_for_oid(x509.OID_STATE_OR_PROVINCE_NAME)[
            0
        ].value.strip()
    except Exception as e:
        sentry.captureException()
        current_app.logger.error("Unable to get state! {0}".format(e))


def location(cert):
    """
    Attempt to get the location name from a given certificate.
    :param cert:
    :return:
    """
    try:
        loc = cert.subject.get_attributes_for_oid(x509.OID_LOCALITY_NAME)
        if not loc:
            return None

        return loc[0].value.strip()
    except Exception as e:
        sentry.captureException()<commit_msg>Check if present - Organization, State, Country<commit_after>import re
import unicodedata

from cryptography import x509
from cryptography.hazmat.primitives.serialization import Encoding
from flask import current_app

from lemur.common.utils import is_selfsigned
from lemur.extensions import sentry
from lemur.constants import SAN_NAMING_TEMPLATE, DEFAULT_NAMING_TEMPLATE


def text_to_slug(value, joiner="-"):
    """
    Normalize a string to a "slug" value, stripping character accents and removing non-alphanum characters.
    A series of non-alphanumeric characters is replaced with the joiner character.
    """

    # Strip all character accents: 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 joiner string. Multiple characters get collapsed into a
    # single joiner. Except, keep 'xn--' used in IDNA domain names as is.
    value = re.sub(r"[^A-Za-z0-9.]+(?<!xn--)", joiner, value)

    # '-' in the beginning or end of string looks ugly.
    return value.strip(joiner)


def certificate_name(common_name, issuer, not_before, not_after, san):
    """
    Create a name for our certificate. A naming standard
    is based on a series of templates. The name includes
    useful information such as Common Name, Validation dates,
    and Issuer.

    :param san:
    :param common_name:
    :param not_after:
    :param issuer:
    :param not_before:
    :rtype: str
    :return:
    """
    if san:
        t = SAN_NAMING_TEMPLATE
    else:
        t = DEFAULT_NAMING_TEMPLATE

    temp = t.format(
        subject=common_name,
        issuer=issuer.replace(" ", ""),
        not_before=not_before.strftime("%Y%m%d"),
        not_after=not_after.strftime("%Y%m%d"),
    )

    temp = temp.replace("*", "WILDCARD")
    return text_to_slug(temp)


def signing_algorithm(cert):
    return cert.signature_hash_algorithm.name


def common_name(cert):
    """
    Attempts to get a sane common name from a given certificate.

    :param cert:
    :return: Common name or None
    """
    try:
        subject_oid = cert.subject.get_attributes_for_oid(x509.OID_COMMON_NAME)
        if len(subject_oid) > 0:
            return subject_oid[0].value.strip()
        return None
    except Exception as e:
        sentry.captureException()
        current_app.logger.error(
            {
                "message": "Unable to get common name",
                "error": e,
                "public_key": cert.public_bytes(Encoding.PEM).decode("utf-8")
            },
            exc_info=True
        )


def organization(cert):
    """
    Attempt to get the organization name from a given certificate.
    :param cert:
    :return:
    """
    try:
        o = cert.subject.get_attributes_for_oid(x509.OID_ORGANIZATION_NAME)
        if not o:
            return None

        return o[0].value.strip()
    except Exception as e:
        sentry.captureException()
        current_app.logger.error("Unable to get organization! {0}".format(e))


def organizational_unit(cert):
    """
    Attempt to get the organization unit from a given certificate.
    :param cert:
    :return:
    """
    try:
        ou = cert.subject.get_attributes_for_oid(x509.OID_ORGANIZATIONAL_UNIT_NAME)
        if not ou:
            return None

        return ou[0].value.strip()
    except Exception as e:
        sentry.captureException()
        current_app.logger.error("Unable to get organizational unit! {0}".format(e))


def country(cert):
    """
    Attempt to get the country from a given certificate.
    :param cert:
    :return:
    """
    try:
        c = cert.subject.get_attributes_for_oid(x509.OID_COUNTRY_NAME)
        if not c:
            return None

        return c[0].value.strip()
    except Exception as e:
        sentry.captureException()
        current_app.logger.error("Unable to get country! {0}".format(e))


def state(cert):
    """
    Attempt to get the from a given certificate.
    :param cert:
    :return:
    """
    try:
        s = cert.subject.get_attributes_for_oid(x509.OID_STATE_OR_PROVINCE_NAME)
        if not s:
            return None

        return s[0].value.strip()
    except Exception as e:
        sentry.captureException()
        current_app.logger.error("Unable to get state! {0}".format(e))


def location(cert):
    """
    Attempt to get the location name from a given certificate.
    :param cert:
    :return:
    """
    try:
        loc = cert.subject.get_attributes_for_oid(x509.OID_LOCALITY_NAME)
        if not loc:
            return None

        return loc[0].value.strip()
    except Exception as e:
        sentry.captureException()
{'fraction_non_alphanumeric': 0.09635610326144693, 'fraction_numerical': 0.007436523956230744, 'mean_word_length': 2.5945017182130585, 'pattern_counts': {'":': 6, '<': 5, '<?xml version=': 0, '>': 5, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '888485', 'n_tokens_mistral': 2956, 'n_tokens_neox': 2806, 'n_words': 801}