From bbc88b64b149e6f9fd5ea7b6c00d7a8e80cff844 Mon Sep 17 00:00:00 2001 From: Frank Brehm Date: Mon, 16 May 2022 18:44:14 +0200 Subject: [PATCH] Adding lib/pp_admintools/ldap_config.py --- lib/pp_admintools/ldap_config.py | 217 +++++++++++++++++++++++++++++++ 1 file changed, 217 insertions(+) create mode 100644 lib/pp_admintools/ldap_config.py diff --git a/lib/pp_admintools/ldap_config.py b/lib/pp_admintools/ldap_config.py new file mode 100644 index 0000000..718c675 --- /dev/null +++ b/lib/pp_admintools/ldap_config.py @@ -0,0 +1,217 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- +""" +@author: Frank Brehm +@contact: frank.brehm@pixelpark.com +@copyright: © 2022 by Frank Brehm, Berlin +@summary: A module for providing a configuration for applications, + which are performing LDAP actions, like search a.s.o. +""" +from __future__ import absolute_import + +# Standard module +import logging +import copy + +# Third party modules + +# Own modules + +from fb_tools.common import is_sequence, pp, to_bool + +# from .config import ConfigError, BaseConfiguration +from fb_tools.multi_config import MultiConfigError, BaseMultiConfig +from fb_tools.multi_config import DEFAULT_ENCODING + +from fb_tools.obj import FbGenericBaseObject, FbBaseObject + +from . import __version__ as GLOBAL_VERSION +from . import MAX_PORT_NUMBER, DEFAULT_CONFIG_DIR + +from .xlate import XLATOR + +__version__ = '0.1.0' +LOG = logging.getLogger(__name__) + +_ = XLATOR.gettext + +DEFAULT_PORT_LDAP = 389 +DEFAULT_PORT_LDAPS = 636 +DEFAULT_TIMEOUT = 20 + +# ============================================================================= +class LdapConfigError(MultiConfigError): + """Base error class for all exceptions happened during + execution this configured application""" + + pass + + +# ============================================================================= +class LdapConnectionInfo(FbBaseObject): + """Encapsulating all necessary data to connect to a LDAP server.""" + + # ------------------------------------------------------------------------- + def __init__( + self, appname=None, verbose=0, version=__version__, base_dir=None, + host=None, use_ldaps=False, port=DEFAULT_PORT_LDAP, base_dn=None, + bind_dn=None, bind_pw=None, initialized=False): + + self._host = None + self._use_ldaps = False + self._port = DEFAULT_PORT_LDAP + self._base_dn = None + self._bind_dn = None + + super(LdapConnectionInfo, self).__init__( + appname=appname, verbose=verbose, version=version, base_dir=base_dir, + initialized=False) + + self.host = host + self.use_ldaps = use_ldaps + self.port = port + self.base_dn = base_dn + self.base_pw = base_pw + + if initialized: + self.initialized = True + + # ------------------------------------------------------------------------- + def as_dict(self, short=True): + """ + Transforms the elements of the object into a dict + + @param short: don't include local properties in resulting dict. + @type short: bool + + @return: structure as dict + @rtype: dict + """ + + res = super(LdapConnectionInfo, self).as_dict(short=short) + + res['host'] = self.host + res['use_ldaps'] = self.use_ldaps + res['port'] = self.port + res['base_dn'] = self.base_dn + res['base_pw'] = self.base_pw + res['schema'] = self.schema + res['url'] = self.url + + return res + + # ----------------------------------------------------------- + @property + def host(self): + """The host name (or IP address) of the LDAP server.""" + return self._host + + @host.setter + def host(self, value): + if value is None or str(value).strip() == '': + self._host = None + return + self._host = str(value).strip().lower() + + # ----------------------------------------------------------- + @property + def use_ldaps(self): + """Should there be used LDAPS for communicating with the LDAP server?""" + return self.use_ldaps + + @use_ldaps.setter + def use_ldaps(self, value): + self.use_ldaps = to_bool(value) + + # ----------------------------------------------------------- + @property + def port(self): + "The TCP port number of the LDAP server." + return self._api_port + + @port.setter + def port(self, value): + v = int(value) + if v < 1 or v > MAX_PORT_NUMBER: + raise LdapConfigError(_("Invalid port {!r} for LDAP server given.").format(value)) + self._port = v + + # ----------------------------------------------------------- + @property + def bind_dn(self): + """The DN used to connect to the LDAP server, anonymous bind is used, if + this DN is empty or None.""" + return self._bind_dn + + @bind_dn.setter + def bind_dn(self, value): + if value is None or str(value).strip() == '': + self._bind_dn = None + return + self._bind_dn = str(value).strip() + + # ----------------------------------------------------------- + @property + def bind_pw(self): + """The password of the DN used to connect to the LDAP server.""" + return self._bind_pw + + @bind_pw.setter + def bind_pw(self, value): + if value is None or str(value).strip() == '': + self._bind_pw = None + return + self._bind_pw = str(value).strip() + + # ----------------------------------------------------------- + @property + def schema(self): + """The schema as part of the URL to connect to the LDAP server.""" + if self.use_ldaps: + return 'ldaps' + return 'ldap' + + # ----------------------------------------------------------- + @property + def url(self): + """The URL, which ca be used to connect to the LDAP server.""" + if not self.host: + return None + + port = '' + if self.use_ldaps: + if self.port != DEFAULT_PORT_LDAPS: + port = ':{}'.format(self.port) + else: + if self.port != DEFAULT_PORT_LDAP: + port = ':{}'.format(self.port) + + return '{s}://{h}{p}'.format(s=self.schema, h=self.host, p=port) + + # ------------------------------------------------------------------------- + def __repr__(self): + """Typecasting into a string for reproduction.""" + + out = "<%s(" % (self.__class__.__name__) + + fields = [] + fields.append("appname={!r}".format(self.appname)) + fields.append("host={!r}".format(self.host)) + fields.append("use_ldaps={!r}".format(self.use_ldaps)) + fields.append("port={!r}".format(self.port)) + fields.append("base_dn={!r}".format(self.base_dn)) + fields.append("base_pw={!r}".format(self.base_pw)) + fields.append("initialized={!r}".format(self.initialized)) + + out += ", ".join(fields) + ")>" + return out + + +# ============================================================================= +if __name__ == "__main__": + + pass + +# ============================================================================= + +# vim: tabstop=4 expandtab shiftwidth=4 softtabstop=4 list -- 2.39.5