Skip to content

Commit

Permalink
Merge pull request #1652 from pbiering/auth-uc-username-support
Browse files Browse the repository at this point in the history
Add: option [auth] uc_username
  • Loading branch information
pbiering authored Dec 14, 2024
2 parents 0d29de6 + 3ebe51a commit 05b8172
Show file tree
Hide file tree
Showing 5 changed files with 30 additions and 0 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
* Improve: avoid automatically invalid cache on upgrade in case no change on cache structure
* Improve: log important module versions on startup
* Improve: auth.ldap config shown on startup, terminate in case no password is supplied for bind user
* Add: option [auth] uc_username for uppercase conversion (similar to existing lc_username)

## 3.3.1

Expand Down
11 changes: 11 additions & 0 deletions DOCUMENTATION.md
Original file line number Diff line number Diff line change
Expand Up @@ -923,6 +923,17 @@ providers like ldap, kerberos

Default: `False`

Note: cannot be enabled together with `uc_username`

##### uc_username

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

Default: `False`

Note: cannot be enabled together with `lc_username`

##### strip_domain

Strip domain from username
Expand Down
9 changes: 9 additions & 0 deletions radicale/auth/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ class BaseAuth:

_ldap_groups: Set[str] = set([])
_lc_username: bool
_uc_username: bool
_strip_domain: bool

def __init__(self, configuration: "config.Configuration") -> None:
Expand All @@ -67,7 +68,13 @@ def __init__(self, configuration: "config.Configuration") -> None:
"""
self.configuration = configuration
self._lc_username = configuration.get("auth", "lc_username")
self._uc_username = configuration.get("auth", "uc_username")
self._strip_domain = configuration.get("auth", "strip_domain")
logger.info("auth.strip_domain: %s", self._strip_domain)
logger.info("auth.lc_username: %s", self._lc_username)
logger.info("auth.uc_username: %s", self._uc_username)
if self._lc_username is True and self._uc_username is True:
raise RuntimeError("auth.lc_username and auth.uc_username cannot be enabled together")

def get_external_login(self, environ: types.WSGIEnviron) -> Union[
Tuple[()], Tuple[str, str]]:
Expand Down Expand Up @@ -98,6 +105,8 @@ def _login(self, login: str, password: str) -> str:
def login(self, login: str, password: str) -> str:
if self._lc_username:
login = login.lower()
if self._uc_username:
login = login.upper()
if self._strip_domain:
login = login.split('@')[0]
return self._login(login, password)
4 changes: 4 additions & 0 deletions radicale/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -247,6 +247,10 @@ def json_str(value: Any) -> dict:
"value": "False",
"help": "strip domain from username",
"type": bool}),
("uc_username", {
"value": "False",
"help": "convert username to uppercase, must be true for case-insensitive auth providers",
"type": bool}),
("lc_username", {
"value": "False",
"help": "convert username to lowercase, must be true for case-insensitive auth providers",
Expand Down
5 changes: 5 additions & 0 deletions radicale/tests/test_auth.py
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,11 @@ def test_htpasswd_lc_username(self) -> None:
self._test_htpasswd("plain", "tmp:bepo", (
("tmp", "bepo", True), ("TMP", "bepo", True), ("tmp1", "bepo", False)))

def test_htpasswd_uc_username(self) -> None:
self.configure({"auth": {"uc_username": "True"}})
self._test_htpasswd("plain", "TMP:bepo", (
("tmp", "bepo", True), ("TMP", "bepo", True), ("TMP1", "bepo", False)))

def test_htpasswd_strip_domain(self) -> None:
self.configure({"auth": {"strip_domain": "True"}})
self._test_htpasswd("plain", "tmp:bepo", (
Expand Down

0 comments on commit 05b8172

Please sign in to comment.