forked from Github-Mirrors/canaille
ACL filters are no more LDAP filters but user attribute mappings.
This commit is contained in:
parent
3884a1d37c
commit
edb64cbfe1
7 changed files with 84 additions and 31 deletions
|
@ -13,6 +13,7 @@ Changed
|
|||
- Moved OIDC related configuration entries in ``OIDC``
|
||||
- Moved ``LDAP`` configuration entry to ``BACKENDS.LDAP``
|
||||
- Bumped to htmx 1.9.0 :pr:`124`
|
||||
- ACL filters are no more LDAP filters but user attribute mappings. :pr:`125`
|
||||
|
||||
Fixed
|
||||
*****
|
||||
|
|
|
@ -91,18 +91,25 @@ GROUP_BASE = "ou=groups,dc=mydomain,dc=tld"
|
|||
# A 'user' variable is available.
|
||||
# GROUP_USER_FILTER = "member={user.dn}"
|
||||
|
||||
[ACL]
|
||||
# You can define access controls that define what users can do on canaille
|
||||
# An access control consists in a FILTER to match users, a list of PERMISSIONS
|
||||
# matched users will be able to perform, and fields users will be able
|
||||
# to READ and WRITE. Users matching several filters will cumulate permissions.
|
||||
#
|
||||
# A 'FILTER' parameter that is a LDAP filter used to determine if a user
|
||||
# belongs to an access control. If absent, all the users will match this
|
||||
# access control. If your LDAP server has the 'memberof' overlay, you can
|
||||
# filter against group membership.
|
||||
# 'FILTER' parameter can be:
|
||||
# - absent, in which case all the users will match this access control
|
||||
# - a mapping where keys are user attributes name and the values those user
|
||||
# attribute values. All the values must be matched for the user to be part
|
||||
# of the access control.
|
||||
# - a list of those mappings. If a user values match at least one mapping,
|
||||
# then the user will be part of the access control
|
||||
#
|
||||
# Here are some examples
|
||||
# FILTER = 'uid=admin'
|
||||
# FILTER = 'memberof=cn=admins,ou=groups,dc=mydomain,dc=tld'
|
||||
# FILTER = {'user_name': 'admin'}
|
||||
# FILTER =
|
||||
# - {'groups': 'admin'}
|
||||
# - {'groups': 'moderators'}
|
||||
#
|
||||
# The 'PERMISSIONS' parameter that is an list of items the users in the access
|
||||
# control will be able to manage. 'PERMISSIONS' is optionnal. Values can be:
|
||||
|
@ -142,7 +149,7 @@ WRITE = [
|
|||
]
|
||||
|
||||
[ACL.ADMIN]
|
||||
FILTER = "memberof=cn=moderators,ou=groups,dc=mydomain,dc=tld"
|
||||
FILTER = {"groups": "admins"}
|
||||
PERMISSIONS = [
|
||||
"manage_users",
|
||||
"manage_groups",
|
||||
|
|
|
@ -63,6 +63,27 @@ class User(LDAPObject):
|
|||
|
||||
return user
|
||||
|
||||
@classmethod
|
||||
def acl_filter_to_ldap_filter(cls, filter_):
|
||||
if isinstance(filter_, dict):
|
||||
return (
|
||||
"(&"
|
||||
+ "".join(
|
||||
f"({cls.attribute_table.get(key, key)}={value})"
|
||||
for key, value in filter_.items()
|
||||
)
|
||||
+ ")"
|
||||
)
|
||||
|
||||
if isinstance(filter_, list):
|
||||
return (
|
||||
"(|"
|
||||
+ "".join(cls.acl_filter_to_ldap_filter(mapping) for mapping in filter_)
|
||||
+ ")"
|
||||
)
|
||||
|
||||
return filter_
|
||||
|
||||
def load_groups(self):
|
||||
group_filter = (
|
||||
current_app.config["BACKENDS"]["LDAP"]
|
||||
|
@ -159,9 +180,9 @@ class User(LDAPObject):
|
|||
conn = self.ldap_connection()
|
||||
|
||||
for access_group_name, details in current_app.config["ACL"].items():
|
||||
if not details.get("FILTER") or (
|
||||
self.id
|
||||
and conn.search_s(self.id, ldap.SCOPE_SUBTREE, details["FILTER"])
|
||||
filter_ = self.acl_filter_to_ldap_filter(details.get("FILTER"))
|
||||
if not filter_ or (
|
||||
self.id and conn.search_s(self.id, ldap.SCOPE_SUBTREE, filter_)
|
||||
):
|
||||
self.permissions |= set(details.get("PERMISSIONS", []))
|
||||
self.read |= set(details.get("READ", []))
|
||||
|
|
|
@ -92,18 +92,25 @@ GROUP_BASE = "ou=groups,dc=mydomain,dc=tld"
|
|||
# A 'user' variable is available.
|
||||
# GROUP_USER_FILTER = "member={user.dn}"
|
||||
|
||||
[ACL]
|
||||
# You can define access controls that define what users can do on canaille
|
||||
# An access control consists in a FILTER to match users, a list of PERMISSIONS
|
||||
# matched users will be able to perform, and fields users will be able
|
||||
# to READ and WRITE. Users matching several filters will cumulate permissions.
|
||||
#
|
||||
# A 'FILTER' parameter that is a LDAP filter used to determine if a user
|
||||
# belongs to an access control. If absent, all the users will match this
|
||||
# access control. If your LDAP server has the 'memberof' overlay, you can
|
||||
# filter against group membership.
|
||||
# 'FILTER' parameter can be:
|
||||
# - absent, in which case all the users will match this access control
|
||||
# - a mapping where keys are user attributes name and the values those user
|
||||
# attribute values. All the values must be matched for the user to be part
|
||||
# of the access control.
|
||||
# - a list of those mappings. If a user values match at least one mapping,
|
||||
# then the user will be part of the access control
|
||||
#
|
||||
# Here are some examples
|
||||
# FILTER = 'uid=admin'
|
||||
# FILTER = 'memberof=cn=admins,ou=groups,dc=mydomain,dc=tld'
|
||||
# FILTER = {'user_name': 'admin'}
|
||||
# FILTER =
|
||||
# - {'groups': 'admin'}
|
||||
# - {'groups': 'moderators'}
|
||||
#
|
||||
# The 'PERMISSIONS' parameter that is an list of items the users in the access
|
||||
# control will be able to manage. 'PERMISSIONS' is optionnal. Values can be:
|
||||
|
@ -143,7 +150,7 @@ WRITE = [
|
|||
]
|
||||
|
||||
[ACL.ADMIN]
|
||||
FILTER = "memberof=cn=admins,ou=groups,dc=mydomain,dc=tld"
|
||||
FILTER = {"groups": "admins"}
|
||||
PERMISSIONS = [
|
||||
"manage_users",
|
||||
"manage_groups",
|
||||
|
@ -154,7 +161,7 @@ PERMISSIONS = [
|
|||
WRITE = ["groups"]
|
||||
|
||||
[ACL.HALF_ADMIN]
|
||||
FILTER = "memberof=cn=moderators,ou=groups,dc=mydomain,dc=tld"
|
||||
FILTER = {"groups": "moderators"}
|
||||
PERMISSIONS = ["manage_users", "manage_groups", "delete_account"]
|
||||
WRITE = ["groups"]
|
||||
|
||||
|
|
|
@ -92,18 +92,25 @@ GROUP_BASE = "ou=groups,dc=mydomain,dc=tld"
|
|||
# A 'user' variable is available.
|
||||
# GROUP_USER_FILTER = "member={user.dn}"
|
||||
|
||||
[ACL]
|
||||
# You can define access controls that define what users can do on canaille
|
||||
# An access control consists in a FILTER to match users, a list of PERMISSIONS
|
||||
# matched users will be able to perform, and fields users will be able
|
||||
# to READ and WRITE. Users matching several filters will cumulate permissions.
|
||||
#
|
||||
# A 'FILTER' parameter that is a LDAP filter used to determine if a user
|
||||
# belongs to an access control. If absent, all the users will match this
|
||||
# access control. If your LDAP server has the 'memberof' overlay, you can
|
||||
# filter against group membership.
|
||||
# 'FILTER' parameter can be:
|
||||
# - absent, in which case all the users will match this access control
|
||||
# - a mapping where keys are user attributes name and the values those user
|
||||
# attribute values. All the values must be matched for the user to be part
|
||||
# of the access control.
|
||||
# - a list of those mappings. If a user values match at least one mapping,
|
||||
# then the user will be part of the access control
|
||||
#
|
||||
# Here are some examples
|
||||
# FILTER = 'uid=admin'
|
||||
# FILTER = 'memberof=cn=admins,ou=groups,dc=mydomain,dc=tld'
|
||||
# FILTER = {'user_name': 'admin'}
|
||||
# FILTER =
|
||||
# - {'groups': 'admin'}
|
||||
# - {'groups': 'moderators'}
|
||||
#
|
||||
# The 'PERMISSIONS' parameter that is an list of items the users in the access
|
||||
# control will be able to manage. 'PERMISSIONS' is optionnal. Values can be:
|
||||
|
@ -143,7 +150,7 @@ WRITE = [
|
|||
]
|
||||
|
||||
[ACL.ADMIN]
|
||||
FILTER = "memberof=cn=admins,ou=groups,dc=mydomain,dc=tld"
|
||||
FILTER = {"groups": "admins"}
|
||||
PERMISSIONS = [
|
||||
"manage_users",
|
||||
"manage_groups",
|
||||
|
@ -154,7 +161,7 @@ PERMISSIONS = [
|
|||
WRITE = ["groups"]
|
||||
|
||||
[ACL.HALF_ADMIN]
|
||||
FILTER = "memberof=cn=moderators,ou=groups,dc=mydomain,dc=tld"
|
||||
FILTER = {"groups": "moderators"}
|
||||
PERMISSIONS = ["manage_users", "manage_groups", "delete_account"]
|
||||
WRITE = ["groups"]
|
||||
|
||||
|
|
|
@ -132,9 +132,19 @@ The 'READ' and 'WRITE' attributes are the LDAP attributes of the user
|
|||
object that users will be able to read and/or write.
|
||||
|
||||
:FILTER:
|
||||
*Optional.* A filter to test on the users to test if they belong to this ACL.
|
||||
If absent, all the users will have the permissions in this ACL.
|
||||
e.g. ``uid=admin`` or ``memberof=cn=admin,ou=groups,dc=mydomain,dc=tld``
|
||||
*Optional.* It can be:
|
||||
|
||||
- absent, in which case all the users will have the permissions in this ACL.
|
||||
- a mapping where keys are user attributes name and the values those user
|
||||
attribute values. All the values must be matched for the user to be part
|
||||
of the access control.
|
||||
- a list of those mappings. If a user values match at least one mapping,
|
||||
then the user will be part of the access control
|
||||
|
||||
Here are some examples:
|
||||
|
||||
- ``FILTER = {'user_name': 'admin'}``
|
||||
- ``FILTER = [{'groups': 'admin'}, {'groups': 'moderators'}]``
|
||||
|
||||
:PERMISSIONS:
|
||||
*Optional.* A list of items the users in the access control will be able to manage. Values can be:
|
||||
|
|
|
@ -115,7 +115,7 @@ def configuration(slapd_server, smtpd):
|
|||
],
|
||||
},
|
||||
"ADMIN": {
|
||||
"FILTER": "(|(uid=admin)(sn=admin))",
|
||||
"FILTER": [{"user_name": "admin"}, {"family_name": "admin"}],
|
||||
"PERMISSIONS": [
|
||||
"manage_users",
|
||||
"manage_oidc",
|
||||
|
@ -128,7 +128,7 @@ def configuration(slapd_server, smtpd):
|
|||
],
|
||||
},
|
||||
"MODERATOR": {
|
||||
"FILTER": "(|(uid=moderator)(sn=moderator))",
|
||||
"FILTER": [{"user_name": "moderator"}, {"family_name": "moderator"}],
|
||||
"PERMISSIONS": ["manage_users", "manage_groups", "delete_account"],
|
||||
"WRITE": [
|
||||
"groups",
|
||||
|
|
Loading…
Reference in a new issue