Skip to content

Commit

Permalink
Support loading ldap secret from file
Browse files Browse the repository at this point in the history
  • Loading branch information
bishtawi committed Nov 5, 2024
1 parent 687624a commit ee2af30
Show file tree
Hide file tree
Showing 8 changed files with 33 additions and 13 deletions.
10 changes: 8 additions & 2 deletions DOCUMENTATION.md
Original file line number Diff line number Diff line change
Expand Up @@ -824,7 +824,13 @@ Default:

##### ldap_secret

The password of the ldap_reader_dn. This parameter must be provided if auth type is ldap.
The password of the ldap_reader_dn. Either this parameter or `ldap_secret_file` must be provided if auth type is ldap.

Default:

##### ldap_secret_file

Path of the file containing the password of the ldap_reader_dn. Either this parameter or `ldap_secret` must be provided if auth type is ldap.

Default:

Expand Down Expand Up @@ -869,7 +875,7 @@ Default:

##### lc_username

Сonvert username to lowercase, must be true for case-insensitive auth
Сonvert username to lowercase, must be true for case-insensitive auth
providers like ldap, kerberos

Default: `False`
Expand Down
2 changes: 1 addition & 1 deletion Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ FROM python:3-alpine AS builder
# Version of Radicale (e.g. v3)
ARG VERSION=master

# Optional dependencies (e.g. bcrypt)
# Optional dependencies (e.g. bcrypt or ldap)
ARG DEPENDENCIES=bcrypt

RUN apk add --no-cache --virtual gcc libffi-dev musl-dev \
Expand Down
2 changes: 1 addition & 1 deletion Dockerfile.dev
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
FROM python:3-alpine AS builder

# Optional dependencies (e.g. bcrypt)
# Optional dependencies (e.g. bcrypt or ldap)
ARG DEPENDENCIES=bcrypt

COPY . /app
Expand Down
3 changes: 3 additions & 0 deletions config
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,9 @@
# Password of the reader DN
#ldap_secret = ldapreader-secret

# Path of the file containing password of the reader DN
#ldap_secret_file = /run/secrets/ldap_password

# If the ldap groups of the user need to be loaded
#ldap_load_groups = True

Expand Down
1 change: 1 addition & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ dependencies = [
[project.optional-dependencies]
test = ["pytest>=7", "waitress", "bcrypt"]
bcrypt = ["bcrypt"]
ldap = ["ldap3"]

[project.scripts]
radicale = "radicale.__main__:run"
Expand Down
15 changes: 10 additions & 5 deletions radicale/auth/ldap.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,12 @@
"""
Authentication backend that checks credentials with a ldap server.
Following parameters are needed in the configuration:
ldap_uri The ldap url to the server like ldap://localhost
ldap_base The baseDN of the ldap server
ldap_reader_dn The DN of a ldap user with read access to get the user accounts
ldap_secret The password of the ldap_reader_dn
ldap_filter The search filter to find the user to authenticate by the username
ldap_uri The ldap url to the server like ldap://localhost
ldap_base The baseDN of the ldap server
ldap_reader_dn The DN of a ldap user with read access to get the user accounts
ldap_secret The password of the ldap_reader_dn
ldap_secret_file The path of the file containing the password of the ldap_reader_dn
ldap_filter The search filter to find the user to authenticate by the username
ldap_load_groups If the groups of the authenticated users need to be loaded
Following parameters controls SSL connections:
ldap_use_ssl If the connection
Expand Down Expand Up @@ -64,6 +65,10 @@ def __init__(self, configuration: config.Configuration) -> None:
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")
ldap_secret_file_path = configuration.get("auth", "ldap_secret_file")
if ldap_secret_file_path:
with open(ldap_secret_file_path, 'r') as file:
self._ldap_secret = file.read().rstrip('\n')
if self._ldap_version == 3:
self._ldap_use_ssl = configuration.get("auth", "ldap_use_ssl")
if self._ldap_use_ssl:
Expand Down
10 changes: 7 additions & 3 deletions radicale/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -200,17 +200,21 @@ def json_str(value: Any) -> dict:
"help": "URI to the ldap server",
"type": str}),
("ldap_base", {
"value": "none",
"value": "",
"help": "LDAP base DN of the ldap server",
"type": str}),
("ldap_reader_dn", {
"value": "none",
"value": "",
"help": "the DN of a ldap user with read access to get the user accounts",
"type": str}),
("ldap_secret", {
"value": "none",
"value": "",
"help": "the password of the ldap_reader_dn",
"type": str}),
("ldap_secret_file", {
"value": "",
"help": "path of the file containing the password of the ldap_reader_dn",
"type": str}),
("ldap_filter", {
"value": "(cn={0})",
"help": "the search filter to find the user DN to authenticate by the username",
Expand Down
3 changes: 2 additions & 1 deletion setup.py.legacy
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ install_requires = ["defusedxml", "passlib", "vobject>=0.9.6",
"pika>=1.1.0",
]
bcrypt_requires = ["bcrypt"]
ldap_requires = ["ldap3"]
test_requires = ["pytest>=7", "waitress", *bcrypt_requires]

setup(
Expand All @@ -58,7 +59,7 @@ setup(
package_data={"radicale": [*web_files, "py.typed"]},
entry_points={"console_scripts": ["radicale = radicale.__main__:run"]},
install_requires=install_requires,
extras_require={"test": test_requires, "bcrypt": bcrypt_requires},
extras_require={"test": test_requires, "bcrypt": bcrypt_requires, "ldap": ldap_requires},
keywords=["calendar", "addressbook", "CalDAV", "CardDAV"],
python_requires=">=3.8.0",
classifiers=[
Expand Down

0 comments on commit ee2af30

Please sign in to comment.