--- /dev/null
+#!/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