forked from Github-Mirrors/canaille
USER_FILTER is parsed with jinja
This commit is contained in:
parent
f19cc8a497
commit
fd66f86a72
9 changed files with 38 additions and 23 deletions
10
CHANGES.rst
10
CHANGES.rst
|
@ -3,11 +3,19 @@ All notable changes to this project will be documented in this file.
|
||||||
The format is based on `Keep a Changelog <https://keepachangelog.com/en/1.0.0/>`_,
|
The format is based on `Keep a Changelog <https://keepachangelog.com/en/1.0.0/>`_,
|
||||||
and this project adheres to `Semantic Versioning <https://semver.org/spec/v2.0.0.html>`_.
|
and this project adheres to `Semantic Versioning <https://semver.org/spec/v2.0.0.html>`_.
|
||||||
|
|
||||||
|
🚨Configuration files must be updated.🚨
|
||||||
|
Check the new format with ``git diff 0.0.29 0.0.30 canaille/conf/config.sample.toml``
|
||||||
|
|
||||||
Added
|
Added
|
||||||
*****
|
*****
|
||||||
|
|
||||||
- Configuration option to disable javascript :pr:`141`
|
- Configuration option to disable javascript :pr:`141`
|
||||||
|
|
||||||
|
Changed
|
||||||
|
*******
|
||||||
|
|
||||||
|
- ``USER_FILTER`` is parsed with jinja.
|
||||||
|
|
||||||
[0.0.29] - 2023-06-30
|
[0.0.29] - 2023-06-30
|
||||||
=====================
|
=====================
|
||||||
|
|
||||||
|
@ -28,7 +36,7 @@ Fixed
|
||||||
=====================
|
=====================
|
||||||
|
|
||||||
🚨Configuration files must be updated.🚨
|
🚨Configuration files must be updated.🚨
|
||||||
Check the new format with ``git diff 0.0.27 0.0.26 canaille/conf/config.sample.toml``
|
Check the new format with ``git diff 0.0.26 0.0.27 canaille/conf/config.sample.toml``
|
||||||
|
|
||||||
Added
|
Added
|
||||||
*****
|
*****
|
||||||
|
|
|
@ -219,13 +219,13 @@ class Backend(BaseBackend):
|
||||||
)
|
)
|
||||||
placeholders = []
|
placeholders = []
|
||||||
|
|
||||||
if "cn={login}" in user_filter:
|
if "cn={{login" in user_filter.replace(" ", ""):
|
||||||
placeholders.append(_("John Doe"))
|
placeholders.append(_("John Doe"))
|
||||||
|
|
||||||
if "uid={login}" in user_filter:
|
if "uid={{login" in user_filter.replace(" ", ""):
|
||||||
placeholders.append(_("jdoe"))
|
placeholders.append(_("jdoe"))
|
||||||
|
|
||||||
if "mail={login}" in user_filter or not placeholders:
|
if "mail={{login" in user_filter.replace(" ", "") or not placeholders:
|
||||||
placeholders.append(_("john@doe.com"))
|
placeholders.append(_("john@doe.com"))
|
||||||
|
|
||||||
return _(" or ").join(placeholders)
|
return _(" or ").join(placeholders)
|
||||||
|
|
|
@ -44,11 +44,14 @@ class User(canaille.core.models.User, LDAPObject):
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def get_from_login(cls, login=None, **kwargs):
|
def get_from_login(cls, login=None, **kwargs):
|
||||||
|
raw_filter = current_app.config["BACKENDS"]["LDAP"].get(
|
||||||
|
"USER_FILTER", User.DEFAULT_FILTER
|
||||||
|
)
|
||||||
filter = (
|
filter = (
|
||||||
(
|
(
|
||||||
current_app.config["BACKENDS"]["LDAP"]
|
current_app.jinja_env.from_string(raw_filter).render(
|
||||||
.get("USER_FILTER", User.DEFAULT_FILTER)
|
login=ldap.filter.escape_filter_chars(login)
|
||||||
.format(login=ldap.filter.escape_filter_chars(login))
|
)
|
||||||
)
|
)
|
||||||
if login
|
if login
|
||||||
else None
|
else None
|
||||||
|
|
|
@ -81,9 +81,10 @@ USER_BASE = "ou=users,dc=mydomain,dc=tld"
|
||||||
# The attribute to identify an object in the User dn.
|
# The attribute to identify an object in the User dn.
|
||||||
# USER_RDN = "uid"
|
# USER_RDN = "uid"
|
||||||
|
|
||||||
# Filter to match users on sign in. Supports a variable
|
# Filter to match users on sign in. Jinja syntax is supported
|
||||||
# {login} that can be used to compare against several fields:
|
# and a `login` variable is available containing the value
|
||||||
# USER_FILTER = "(|(uid={login})(mail={login}))"
|
# passed in the login field.
|
||||||
|
# USER_FILTER = "(|(uid={{ login }})(mail={{ login }}))"
|
||||||
|
|
||||||
# Where to search for groups?
|
# Where to search for groups?
|
||||||
GROUP_BASE = "ou=groups,dc=mydomain,dc=tld"
|
GROUP_BASE = "ou=groups,dc=mydomain,dc=tld"
|
||||||
|
|
|
@ -82,9 +82,10 @@ USER_BASE = "ou=users,dc=mydomain,dc=tld"
|
||||||
# The attribute to identify an object in the User dn.
|
# The attribute to identify an object in the User dn.
|
||||||
USER_RDN = "uid"
|
USER_RDN = "uid"
|
||||||
|
|
||||||
# Filter to match users on sign in. Supports a variable
|
# Filter to match users on sign in. Jinja syntax is supported
|
||||||
# {login} that can be used to compare against several fields:
|
# and a `login` variable is available containing the value
|
||||||
# USER_FILTER = "(|(uid={login})(mail={login}))"
|
# passed in the login field.
|
||||||
|
# USER_FILTER = "(|(uid={{ login }})(mail={{ login }}))"
|
||||||
|
|
||||||
# Where to search for groups?
|
# Where to search for groups?
|
||||||
GROUP_BASE = "ou=groups,dc=mydomain,dc=tld"
|
GROUP_BASE = "ou=groups,dc=mydomain,dc=tld"
|
||||||
|
|
|
@ -82,9 +82,10 @@ USER_BASE = "ou=users,dc=mydomain,dc=tld"
|
||||||
# The attribute to identify an object in the User dn.
|
# The attribute to identify an object in the User dn.
|
||||||
# USER_RDN = "uid"
|
# USER_RDN = "uid"
|
||||||
|
|
||||||
# Filter to match users on sign in. Supports a variable
|
# Filter to match users on sign in. Jinja syntax is supported
|
||||||
# {login} that can be used to compare against several fields:
|
# and a `login` variable is available containing the value
|
||||||
# USER_FILTER = "(|(uid={login})(mail={login}))"
|
# passed in the login field.
|
||||||
|
# USER_FILTER = "(|(uid={{ login }})(mail={{ login }}))"
|
||||||
|
|
||||||
# Where to search for groups?
|
# Where to search for groups?
|
||||||
GROUP_BASE = "ou=groups,dc=mydomain,dc=tld"
|
GROUP_BASE = "ou=groups,dc=mydomain,dc=tld"
|
||||||
|
|
|
@ -115,8 +115,9 @@ BACKENDS.LDAP
|
||||||
|
|
||||||
:USER_FILTER:
|
:USER_FILTER:
|
||||||
*Optional.* The filter to match users on sign in.
|
*Optional.* The filter to match users on sign in.
|
||||||
Supports a variable {login} that can be used to compare against several LDAP attributes.
|
Jinja syntax is supported and a `login` variable is available containing
|
||||||
Defaults to ``(|(uid={login})(mail={login}))``
|
the value passed in the login field.
|
||||||
|
Defaults to ``(|(uid={{ login }})(mail={{ login }}))``
|
||||||
|
|
||||||
:GROUP_BASE:
|
:GROUP_BASE:
|
||||||
**Required.** The DN where of the node in which LDAP groups will be created and searched for.
|
**Required.** The DN where of the node in which LDAP groups will be created and searched for.
|
||||||
|
|
|
@ -35,7 +35,7 @@ def ldap_configuration(configuration, slapd_server):
|
||||||
"BIND_PW": slapd_server.root_pw,
|
"BIND_PW": slapd_server.root_pw,
|
||||||
"USER_BASE": "ou=users",
|
"USER_BASE": "ou=users",
|
||||||
"USER_RDN": "uid",
|
"USER_RDN": "uid",
|
||||||
"USER_FILTER": "(uid={login})",
|
"USER_FILTER": "(uid={{ login }})",
|
||||||
"GROUP_BASE": "ou=groups",
|
"GROUP_BASE": "ou=groups",
|
||||||
"TIMEOUT": 0.1,
|
"TIMEOUT": 0.1,
|
||||||
},
|
},
|
||||||
|
|
|
@ -280,20 +280,20 @@ def test_ldap_cannot_create_groups(testclient, configuration, backend):
|
||||||
|
|
||||||
|
|
||||||
def test_login_placeholder(testclient):
|
def test_login_placeholder(testclient):
|
||||||
testclient.app.config["BACKENDS"]["LDAP"]["USER_FILTER"] = "(uid={login})"
|
testclient.app.config["BACKENDS"]["LDAP"]["USER_FILTER"] = "(uid={{ login }})"
|
||||||
placeholder = testclient.get("/login").form["login"].attrs["placeholder"]
|
placeholder = testclient.get("/login").form["login"].attrs["placeholder"]
|
||||||
assert placeholder == "jdoe"
|
assert placeholder == "jdoe"
|
||||||
|
|
||||||
testclient.app.config["BACKENDS"]["LDAP"]["USER_FILTER"] = "(cn={login})"
|
testclient.app.config["BACKENDS"]["LDAP"]["USER_FILTER"] = "(cn={{ login }})"
|
||||||
placeholder = testclient.get("/login").form["login"].attrs["placeholder"]
|
placeholder = testclient.get("/login").form["login"].attrs["placeholder"]
|
||||||
assert placeholder == "John Doe"
|
assert placeholder == "John Doe"
|
||||||
|
|
||||||
testclient.app.config["BACKENDS"]["LDAP"]["USER_FILTER"] = "(mail={login})"
|
testclient.app.config["BACKENDS"]["LDAP"]["USER_FILTER"] = "(mail={{ login }})"
|
||||||
placeholder = testclient.get("/login").form["login"].attrs["placeholder"]
|
placeholder = testclient.get("/login").form["login"].attrs["placeholder"]
|
||||||
assert placeholder == "john@doe.com"
|
assert placeholder == "john@doe.com"
|
||||||
|
|
||||||
testclient.app.config["BACKENDS"]["LDAP"][
|
testclient.app.config["BACKENDS"]["LDAP"][
|
||||||
"USER_FILTER"
|
"USER_FILTER"
|
||||||
] = "(|(uid={login})(mail={login}))"
|
] = "(|(uid={{ login }})(mail={{ login }}))"
|
||||||
placeholder = testclient.get("/login").form["login"].attrs["placeholder"]
|
placeholder = testclient.get("/login").form["login"].attrs["placeholder"]
|
||||||
assert placeholder == "jdoe or john@doe.com"
|
assert placeholder == "jdoe or john@doe.com"
|
||||||
|
|
Loading…
Reference in a new issue