mirror of
https://github.com/Kozea/Radicale.git
synced 2025-04-02 20:57:37 +03:00
Now ldap auth can use ldap and ldap3 also.
This commit is contained in:
parent
5167f12624
commit
8b8d7729a2
1 changed files with 64 additions and 8 deletions
|
@ -24,7 +24,6 @@ Following parameters are needed in the configuration
|
|||
ldap_load_groups If the groups of the authenticated users need to be loaded
|
||||
"""
|
||||
|
||||
import ldap
|
||||
from radicale import auth, config
|
||||
from radicale.log import logger
|
||||
|
||||
|
@ -35,9 +34,18 @@ class Auth(auth.BaseAuth):
|
|||
_ldap_secret: str
|
||||
_ldap_filter: str
|
||||
_ldap_load_groups: bool
|
||||
_ldap_version: 3
|
||||
|
||||
def __init__(self, configuration: config.Configuration) -> None:
|
||||
super().__init__(configuration)
|
||||
try:
|
||||
import ldap3
|
||||
except ImportError as e:
|
||||
try:
|
||||
import ldap
|
||||
self._ldap_version = 2
|
||||
except ImportError as e:
|
||||
raise RuntimeError("LDAP authentication requires the ldap3 module") from e
|
||||
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")
|
||||
|
@ -45,13 +53,7 @@ class Auth(auth.BaseAuth):
|
|||
self._ldap_secret = configuration.get("auth", "ldap_secret")
|
||||
self._ldap_filter = configuration.get("auth", "ldap_filter")
|
||||
|
||||
def login(self, login: str, password: str) -> str:
|
||||
"""Validate credentials.
|
||||
In first step we make a connection to the ldap server with the ldap_reader_dn credential.
|
||||
In next step the DN of the user to authenticate will be searched.
|
||||
In the last step the authentication of the user will be proceeded.
|
||||
|
||||
"""
|
||||
def _login2(self, login: str, password: str) -> str:
|
||||
try:
|
||||
"""Bind as reader dn"""
|
||||
conn = ldap.initialize(self._ldap_uri)
|
||||
|
@ -87,3 +89,57 @@ class Auth(auth.BaseAuth):
|
|||
return login
|
||||
except 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)
|
||||
except self.ldap3.core.exceptions.LDAPSocketOpenError:
|
||||
raise RuntimeError("Unable to reach ldap server")
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
if not conn.bind():
|
||||
raise RuntimeError("Unable to read from ldap server")
|
||||
|
||||
"""Search the user dn"""
|
||||
conn.search(
|
||||
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"""
|
||||
return ""
|
||||
|
||||
user_entry = conn.entries[0].entry_to_json()
|
||||
conn.unbind()
|
||||
user_dn = user_entry['dn']
|
||||
try:
|
||||
"""Try to bind as the user itself"""
|
||||
conn = ldap3.Connection(server, user_dn, password=password)
|
||||
if not conn.bind():
|
||||
return ""
|
||||
if self._ldap_load_groups:
|
||||
tmp = []
|
||||
for g in user_entry['attributes']['memberOf']:
|
||||
tmp.append(g)
|
||||
self._ldap_groups = set(tmp)
|
||||
conn.unbind()
|
||||
return login
|
||||
except Exception:
|
||||
pass
|
||||
return ""
|
||||
|
||||
def login(self, login: str, password: str) -> str:
|
||||
"""Validate credentials.
|
||||
In first step we make a connection to the ldap server with the ldap_reader_dn credential.
|
||||
In next step the DN of the user to authenticate will be searched.
|
||||
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)
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue