# Path: esteid/util.py
# def camel_2_py(the_dict):
#     new_dict = {}
#     for key, val in the_dict.items():
# 
#         if len(re.sub(r"([A-Z])", r" \1", key).split()) == len(key):
#             parts = [key.lower()]
# 
#         else:
#             key = key.replace("ID", "Id").replace("CRL", "Crl")
#             parts = re.sub(r"([A-Z])", r" \1", key).split()
# 
#         new_dict["_".join([x.lower() for x in parts])] = val
# 
#     return new_dict
# 
# def convert_status(status):
#     if isinstance(status, bool):
#         return status
# 
#     return status.lower() == "ok"
# 
# def convert_time(timestamp):
#     if not timestamp:
#         return None
# 
#     if isinstance(timestamp, datetime):
#         if timezone.is_naive(timestamp):
#             timestamp = timezone.make_aware(timestamp, timezone.utc)
# 
#         return timestamp
# 
#     return timezone.make_aware(datetime.strptime(timestamp, "%Y-%m-%dT%H:%M:%SZ"), timezone.utc)
# 
# def get_instance_converter(cls, prepare_kwargs=camel_2_py):
#     def _convert_instance(value):
#         if isinstance(value, (dict, OrderedDict)):
#             return cls(**prepare_kwargs(value))
# 
#         return value
# 
#     return _convert_instance
# 
# def get_name_from_legacy_common_name(common_name):
#     common_name = common_name.replace("\\,", ",")
#     common_name = common_name.strip().rstrip(",")
# 
#     parts = common_name.split(",")[:-1]
#     parts.reverse()
# 
#     return " ".join(parts).title()
# 
# def get_typed_list_converter(klass):
#     converter = get_instance_converter(klass)
# 
#     def _get_typed_list_converter(value):
#         return [converter(x) for x in value]
# 
#     return _get_typed_list_converter
# 
# def get_typed_list_validator(klass):
#     def _get_typed_list_validator(inst, attr, value):
#         if not isinstance(value, list):
#             raise TypeError("Value MUST be a list")
# 
#         if not all(isinstance(x, klass) for x in value):
#             raise TypeError(f"Value MUST be a list of {klass}")
# 
#     return _get_typed_list_validator


from datetime import datetime
from typing import List, TYPE_CHECKING, Union
from oscrypto.asymmetric import load_certificate
    from oscrypto.asymmetric import Certificate as OsCryptoCertificate
    from asn1crypto.cms import Certificate as Asn1CryptoCertificate
from esteid.util import (
    camel_2_py,
    convert_status,
    convert_time,
    get_instance_converter,
    get_name_from_legacy_common_name,
    get_typed_list_converter,
    get_typed_list_validator,
)
import attr
import pytz
import pyasice
            issuer_serial=str(serial),
            subject=personal["common_name"],
            valid_from=valid_from.replace(microsecond=0).astimezone(pytz.utc),
            valid_to=valid_to.replace(microsecond=0).astimezone(pytz.utc),
        )


@attr.s
class ResponderCertificate(Certificate):
    pass


@attr.s
class Signer(FromDictMixin):
    id_code = attr.ib()

    # Note: This should also support common_name argument coming in
    full_name = attr.ib()

    certificate: Certificate = attr.ib(
        validator=attr.validators.instance_of(Certificate), converter=get_instance_converter(Certificate)
    )

    @staticmethod
    def prepare_kwargs(kwargs):
        kwargs = camel_2_py(kwargs)
        full_name = kwargs.get("full_name", None)

        # If the full_name is None, check common_name field and use that
        if full_name is None:

# Path: esteid/util.py
# def camel_2_py(the_dict):
#     new_dict = {}
#     for key, val in the_dict.items():
# 
#         if len(re.sub(r"([A-Z])", r" \1", key).split()) == len(key):
#             parts = [key.lower()]
# 
#         else:
#             key = key.replace("ID", "Id").replace("CRL", "Crl")
#             parts = re.sub(r"([A-Z])", r" \1", key).split()
# 
#         new_dict["_".join([x.lower() for x in parts])] = val
# 
#     return new_dict
# 
# def convert_status(status):
#     if isinstance(status, bool):
#         return status
# 
#     return status.lower() == "ok"
# 
# def convert_time(timestamp):
#     if not timestamp:
#         return None
# 
#     if isinstance(timestamp, datetime):
#         if timezone.is_naive(timestamp):
#             timestamp = timezone.make_aware(timestamp, timezone.utc)
# 
#         return timestamp
# 
#     return timezone.make_aware(datetime.strptime(timestamp, "%Y-%m-%dT%H:%M:%SZ"), timezone.utc)
# 
# def get_instance_converter(cls, prepare_kwargs=camel_2_py):
#     def _convert_instance(value):
#         if isinstance(value, (dict, OrderedDict)):
#             return cls(**prepare_kwargs(value))
# 
#         return value
# 
#     return _convert_instance
# 
# def get_name_from_legacy_common_name(common_name):
#     common_name = common_name.replace("\\,", ",")
#     common_name = common_name.strip().rstrip(",")
# 
#     parts = common_name.split(",")[:-1]
#     parts.reverse()
# 
#     return " ".join(parts).title()
# 
# def get_typed_list_converter(klass):
#     converter = get_instance_converter(klass)
# 
#     def _get_typed_list_converter(value):
#         return [converter(x) for x in value]
# 
#     return _get_typed_list_converter
# 
# def get_typed_list_validator(klass):
#     def _get_typed_list_validator(inst, attr, value):
#         if not isinstance(value, list):
#             raise TypeError("Value MUST be a list")
# 
#         if not all(isinstance(x, klass) for x in value):
#             raise TypeError(f"Value MUST be a list of {klass}")
# 
#     return _get_typed_list_validator


# Path: esteid/types.py
from datetime import datetime
from typing import List, TYPE_CHECKING, Union
from oscrypto.asymmetric import load_certificate
    from oscrypto.asymmetric import Certificate as OsCryptoCertificate
    from asn1crypto.cms import Certificate as Asn1CryptoCertificate
from esteid.util import (
    camel_2_py,
    convert_status,
    convert_time,
    get_instance_converter,
    get_name_from_legacy_common_name,
    get_typed_list_converter,
    get_typed_list_validator,
)
import attr
import pytz
import pyasice

            issuer_serial=str(serial),
            subject=personal["common_name"],
            valid_from=valid_from.replace(microsecond=0).astimezone(pytz.utc),
            valid_to=valid_to.replace(microsecond=0).astimezone(pytz.utc),
        )


@attr.s
class ResponderCertificate(Certificate):
    pass


@attr.s
class Signer(FromDictMixin):
    id_code = attr.ib()

    # Note: This should also support common_name argument coming in
    full_name = attr.ib()

    certificate: Certificate = attr.ib(
        validator=attr.validators.instance_of(Certificate), converter=get_instance_converter(Certificate)
    )

    @staticmethod
    def prepare_kwargs(kwargs):
        kwargs = camel_2_py(kwargs)
        full_name = kwargs.get("full_name", None)

        # If the full_name is None, check common_name field and use that
        if full_name is None:

            full_name = get_name_from_legacy_common_name(kwargs.pop("common_name", None))