2022-12-14 20:18:51 +00:00
|
|
|
import datetime
|
|
|
|
from enum import Enum
|
|
|
|
|
|
|
|
LDAP_NULL_DATE = "000001010000Z"
|
|
|
|
|
|
|
|
|
|
|
|
class Syntax(str, Enum):
|
|
|
|
# fmt: off
|
2023-03-08 22:53:53 +00:00
|
|
|
BINARY = "1.3.6.1.4.1.1466.115.121.1.5"
|
|
|
|
BOOLEAN = "1.3.6.1.4.1.1466.115.121.1.7"
|
2023-03-11 11:37:13 +00:00
|
|
|
CERTIFICATE = "1.3.6.1.4.1.1466.115.121.1.8"
|
|
|
|
COUNTRY_STRING = "1.3.6.1.4.1.1466.115.121.1.11"
|
2023-03-08 22:53:53 +00:00
|
|
|
DISTINGUISHED_NAME = "1.3.6.1.4.1.1466.115.121.1.12"
|
|
|
|
DIRECTORY_STRING = "1.3.6.1.4.1.1466.115.121.1.15"
|
|
|
|
FAX_IMAGE = "1.3.6.1.4.1.1466.115.121.1.23"
|
|
|
|
GENERALIZED_TIME = "1.3.6.1.4.1.1466.115.121.1.24"
|
|
|
|
IA5_STRING = "1.3.6.1.4.1.1466.115.121.1.26"
|
|
|
|
INTEGER = "1.3.6.1.4.1.1466.115.121.1.27"
|
|
|
|
JPEG = "1.3.6.1.4.1.1466.115.121.1.28"
|
|
|
|
NUMERIC_STRING = "1.3.6.1.4.1.1466.115.121.1.36"
|
|
|
|
OCTET_STRING = "1.3.6.1.4.1.1466.115.121.1.40"
|
|
|
|
POSTAL_ADDRESS = "1.3.6.1.4.1.1466.115.121.1.41"
|
|
|
|
PRINTABLE_STRING = "1.3.6.1.4.1.1466.115.121.1.44"
|
|
|
|
TELEPHONE_NUMBER = "1.3.6.1.4.1.1466.115.121.1.50"
|
2023-03-11 11:37:13 +00:00
|
|
|
UTC_TIME = "1.3.6.1.4.1.1466.115.121.1.53"
|
2022-12-14 20:18:51 +00:00
|
|
|
# fmt: on
|
|
|
|
|
|
|
|
|
2022-12-14 23:03:01 +00:00
|
|
|
def ldap_to_python(value, syntax):
|
2023-03-08 22:53:53 +00:00
|
|
|
from .ldapobject import LDAPObject
|
|
|
|
|
2022-12-14 20:18:51 +00:00
|
|
|
if syntax == Syntax.GENERALIZED_TIME:
|
|
|
|
value = value.decode("utf-8")
|
|
|
|
if value == LDAP_NULL_DATE:
|
|
|
|
# python cannot represent datetimes with year 0
|
|
|
|
return datetime.datetime.min
|
2023-03-17 23:38:56 +00:00
|
|
|
if value.endswith("Z"):
|
|
|
|
return datetime.datetime.strptime(value, "%Y%m%d%H%M%SZ").replace(
|
|
|
|
tzinfo=datetime.timezone.utc
|
|
|
|
)
|
|
|
|
return datetime.datetime.strptime(value, "%Y%m%d%H%M%S%z")
|
2022-12-14 20:18:51 +00:00
|
|
|
|
|
|
|
if syntax == Syntax.INTEGER:
|
|
|
|
return int(value.decode("utf-8"))
|
|
|
|
|
|
|
|
if syntax == Syntax.JPEG:
|
|
|
|
return value
|
|
|
|
|
|
|
|
if syntax == Syntax.BOOLEAN:
|
|
|
|
return value.decode("utf-8").upper() == "TRUE"
|
|
|
|
|
2023-03-08 22:53:53 +00:00
|
|
|
if syntax == Syntax.DISTINGUISHED_NAME:
|
2023-02-05 18:08:25 +00:00
|
|
|
return LDAPObject.get(id=value.decode("utf-8"))
|
2023-03-08 22:53:53 +00:00
|
|
|
|
2022-12-14 20:18:51 +00:00
|
|
|
return value.decode("utf-8")
|
|
|
|
|
|
|
|
|
2023-03-08 16:38:36 +00:00
|
|
|
def python_to_ldap(value, syntax, encode=True):
|
|
|
|
encodable = True
|
2022-12-14 20:18:51 +00:00
|
|
|
if syntax == Syntax.GENERALIZED_TIME and isinstance(value, datetime.datetime):
|
|
|
|
if value == datetime.datetime.min:
|
2023-03-08 16:38:36 +00:00
|
|
|
value = LDAP_NULL_DATE
|
2023-03-17 23:38:56 +00:00
|
|
|
elif value.tzinfo == datetime.timezone.utc:
|
2023-03-08 16:38:36 +00:00
|
|
|
value = value.strftime("%Y%m%d%H%M%SZ")
|
2023-03-17 23:38:56 +00:00
|
|
|
else:
|
|
|
|
value = value.strftime("%Y%m%d%H%M%S%z")
|
2022-12-14 20:18:51 +00:00
|
|
|
|
|
|
|
if syntax == Syntax.INTEGER and isinstance(value, int):
|
2023-03-08 16:38:36 +00:00
|
|
|
value = str(value)
|
2022-12-14 20:18:51 +00:00
|
|
|
|
|
|
|
if syntax == Syntax.JPEG:
|
2023-03-08 16:38:36 +00:00
|
|
|
encodable = False
|
2022-12-14 20:18:51 +00:00
|
|
|
|
|
|
|
if syntax == Syntax.BOOLEAN and isinstance(value, bool):
|
2023-03-08 16:38:36 +00:00
|
|
|
value = "TRUE" if value else "FALSE"
|
2022-12-14 20:18:51 +00:00
|
|
|
|
2023-03-08 22:53:53 +00:00
|
|
|
if syntax == Syntax.DISTINGUISHED_NAME:
|
2023-02-05 18:08:25 +00:00
|
|
|
value = value.id
|
2023-03-08 22:53:53 +00:00
|
|
|
|
2023-03-08 16:38:36 +00:00
|
|
|
if not value:
|
|
|
|
return None
|
|
|
|
|
|
|
|
return value.encode() if encode and encodable else value
|