|
|
@@ -27,6 +27,7 @@ Following parameters are needed in the configuration
|
|
|
from radicale import auth, config
|
|
|
from radicale.log import logger
|
|
|
|
|
|
+
|
|
|
class Auth(auth.BaseAuth):
|
|
|
_ldap_uri: str
|
|
|
_ldap_base: str
|
|
|
@@ -40,33 +41,35 @@ class Auth(auth.BaseAuth):
|
|
|
super().__init__(configuration)
|
|
|
try:
|
|
|
import ldap3
|
|
|
- except ImportError as e:
|
|
|
+ self.ldap3 = ldap3
|
|
|
+ except ImportError:
|
|
|
try:
|
|
|
import ldap
|
|
|
self._ldap_version = 2
|
|
|
+ self.ldap = ldap
|
|
|
except ImportError as e:
|
|
|
raise RuntimeError("LDAP authentication requires the ldap3 module") from e
|
|
|
- self._ldap_uri = configuration.get("auth", "ldap_uri")
|
|
|
+ self._ldap_uri = configuration.get("auth", "ldap_uri")
|
|
|
self._ldap_base = configuration.get("auth", "ldap_base")
|
|
|
self._ldap_reader_dn = configuration.get("auth", "ldap_reader_dn")
|
|
|
self._ldap_load_groups = configuration.get("auth", "ldap_load_groups")
|
|
|
- self._ldap_secret = configuration.get("auth", "ldap_secret")
|
|
|
- self._ldap_filter = configuration.get("auth", "ldap_filter")
|
|
|
+ self._ldap_secret = configuration.get("auth", "ldap_secret")
|
|
|
+ self._ldap_filter = configuration.get("auth", "ldap_filter")
|
|
|
|
|
|
def _login2(self, login: str, password: str) -> str:
|
|
|
try:
|
|
|
"""Bind as reader dn"""
|
|
|
- conn = ldap.initialize(self._ldap_uri)
|
|
|
+ conn = self.ldap.initialize(self._ldap_uri)
|
|
|
conn.protocol_version = 3
|
|
|
- conn.set_option(ldap.OPT_REFERRALS, 0)
|
|
|
+ conn.set_option(self.ldap.OPT_REFERRALS, 0)
|
|
|
conn.simple_bind_s(self._ldap_reader_dn, self._ldap_secret)
|
|
|
"""Search for the dn of user to authenticate"""
|
|
|
- res = conn.search_s(self._ldap_base, ldap.SCOPE_SUBTREE, filterstr=self._ldap_filter.format(login), attrlist=['memberOf'])
|
|
|
+ res = conn.search_s(self._ldap_base, self.ldap.SCOPE_SUBTREE, filterstr=self._ldap_filter.format(login), attrlist=['memberOf'])
|
|
|
if len(res) == 0:
|
|
|
"""User could not be find"""
|
|
|
return ""
|
|
|
user_dn = res[0][0]
|
|
|
- logger.debug("LDAP Auth user: %s",user_dn)
|
|
|
+ logger.debug("LDAP Auth user: %s", user_dn)
|
|
|
"""Close ldap connection"""
|
|
|
conn.unbind()
|
|
|
except Exception:
|
|
|
@@ -74,27 +77,27 @@ class Auth(auth.BaseAuth):
|
|
|
|
|
|
try:
|
|
|
"""Bind as user to authenticate"""
|
|
|
- conn = ldap.initialize(self._ldap_uri)
|
|
|
+ conn = self.ldap.initialize(self._ldap_uri)
|
|
|
conn.protocol_version = 3
|
|
|
- conn.set_option(ldap.OPT_REFERRALS, 0)
|
|
|
- conn.simple_bind_s(user_dn,password)
|
|
|
+ conn.set_option(self.ldap.OPT_REFERRALS, 0)
|
|
|
+ conn.simple_bind_s(user_dn, password)
|
|
|
tmp = []
|
|
|
if self._ldap_load_groups:
|
|
|
tmp = []
|
|
|
for t in res[0][1]['memberOf']:
|
|
|
tmp.append(t.decode('utf-8').split(',')[0][3:])
|
|
|
self._ldap_groups = set(tmp)
|
|
|
- logger.debug("LDAP Auth groups of user: %s",",".join(self._ldap_groups))
|
|
|
+ logger.debug("LDAP Auth groups of user: %s", ",".join(self._ldap_groups))
|
|
|
conn.unbind()
|
|
|
return login
|
|
|
- except ldap.INVALID_CREDENTIALS:
|
|
|
+ except self.ldap.INVALID_CREDENTIALS:
|
|
|
return ""
|
|
|
|
|
|
def _login3(self, login: str, password: str) -> str:
|
|
|
"""Connect the server"""
|
|
|
try:
|
|
|
- server = ldap3.Server(self._ldap_uri)
|
|
|
- conn = ldap3.Connection(server, self._ldap_reader_dn, password=self._ldap_secret)
|
|
|
+ server = self.ldap3.Server(self._ldap_uri)
|
|
|
+ conn = self.ldap3.Connection(server, self._ldap_reader_dn, password=self._ldap_secret)
|
|
|
except self.ldap3.core.exceptions.LDAPSocketOpenError:
|
|
|
raise RuntimeError("Unable to reach ldap server")
|
|
|
except Exception:
|
|
|
@@ -105,10 +108,10 @@ class Auth(auth.BaseAuth):
|
|
|
|
|
|
"""Search the user dn"""
|
|
|
conn.search(
|
|
|
- search_base = self._ldap_base,
|
|
|
- search_filter = self._ldap_filter.format(login),
|
|
|
- search_scope = 'SUBTREE',
|
|
|
- attributes = ['memberOf']
|
|
|
+ search_base=self._ldap_base,
|
|
|
+ search_filter=self._ldap_filter.format(login),
|
|
|
+ search_scope='SUBTREE',
|
|
|
+ attributes=['memberOf']
|
|
|
)
|
|
|
if len(conn.entries) == 0:
|
|
|
"""User could not be find"""
|
|
|
@@ -119,7 +122,7 @@ class Auth(auth.BaseAuth):
|
|
|
user_dn = user_entry['dn']
|
|
|
try:
|
|
|
"""Try to bind as the user itself"""
|
|
|
- conn = ldap3.Connection(server, user_dn, password=password)
|
|
|
+ conn = self.ldap3.Connection(server, user_dn, password=password)
|
|
|
if not conn.bind():
|
|
|
return ""
|
|
|
if self._ldap_load_groups:
|
|
|
@@ -140,6 +143,5 @@ class Auth(auth.BaseAuth):
|
|
|
In the last step the authentication of the user will be proceeded.
|
|
|
"""
|
|
|
if self._ldap_version == 2:
|
|
|
- return _login2(self, login, password)
|
|
|
- return _login3(self, login, password)
|
|
|
-
|
|
|
+ return self._login2(self, login, password)
|
|
|
+ return self._login3(self, login, password)
|