mirror of
				https://github.com/kevinveenbirkenbach/computer-playbook.git
				synced 2025-11-04 04:08:15 +00:00 
			
		
		
		
	Added draft for nested groups
This commit is contained in:
		@@ -1,4 +1,3 @@
 | 
			
		||||
# Todos
 | 
			
		||||
- Implement auto memberof setup
 | 
			
		||||
- Create a Dockerfile (may in an own repository) with memberOf
 | 
			
		||||
- Find a better decoupling solution for nextcloud
 | 
			
		||||
- User Groups and Roles on the proper way
 | 
			
		||||
- Refactor the use of groups as roles in oauth2 proxy
 | 
			
		||||
@@ -35,7 +35,11 @@ docker exec -it ldap ldapsearch -Y EXTERNAL -H ldapi:/// -b "cn=config" "(olcDat
 | 
			
		||||
To execute the following commands set the credentials via:
 | 
			
		||||
 | 
			
		||||
```bash
 | 
			
		||||
export $(grep -Ev '^(#|$)' .env/env | xargs)
 | 
			
		||||
eval $(
 | 
			
		||||
  grep -v '^\s*#' .env/env \
 | 
			
		||||
  | sed -E 's/\s*#.*//' \
 | 
			
		||||
  | sed -E 's/^\s*([A-Za-z_][A-Za-z0-9_]*)\s*=\s*(.*)\s*$/export \1="\2"/'
 | 
			
		||||
)
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
### Show all Entries
 | 
			
		||||
 
 | 
			
		||||
@@ -0,0 +1,77 @@
 | 
			
		||||
def build_ldap_nested_group_entries(applications, users, ldap):
 | 
			
		||||
    """
 | 
			
		||||
    Builds structured LDAP role entries using the global `ldap` configuration.
 | 
			
		||||
    Supports objectClasses: posixGroup (adds gidNumber, memberUid), groupOfNames (adds member).
 | 
			
		||||
    Now nests roles under an application-level OU: application-id/role.
 | 
			
		||||
    """
 | 
			
		||||
 | 
			
		||||
    result = {}
 | 
			
		||||
 | 
			
		||||
    # Base DN components
 | 
			
		||||
    role_dn_base = ldap["dn"]["ou"]["roles"]
 | 
			
		||||
    user_dn_base = ldap["dn"]["ou"]["users"]
 | 
			
		||||
    ldap_user_attr = ldap["user"]["attributes"]["id"]
 | 
			
		||||
 | 
			
		||||
    # Supported objectClass flavors
 | 
			
		||||
    flavors = ldap.get("rbac", {}).get("flavors", [])
 | 
			
		||||
 | 
			
		||||
    for application_id, app_config in applications.items():
 | 
			
		||||
        # Compute the DN for the application-level OU
 | 
			
		||||
        app_ou_dn = f"ou={application_id},{role_dn_base}"
 | 
			
		||||
 | 
			
		||||
        ou_entry = {
 | 
			
		||||
            "dn": app_ou_dn,
 | 
			
		||||
            "objectClass": ["top", "organizationalUnit"],
 | 
			
		||||
            "ou": application_id,
 | 
			
		||||
            "description": f"Roles for application {application_id}" 
 | 
			
		||||
        }
 | 
			
		||||
        result[app_ou_dn] = ou_entry
 | 
			
		||||
 | 
			
		||||
        # Standard roles with an extra 'administrator'
 | 
			
		||||
        base_roles = app_config.get("rbac", {}).get("roles", {})
 | 
			
		||||
        roles = {
 | 
			
		||||
            **base_roles,
 | 
			
		||||
            "administrator": {
 | 
			
		||||
                "description": "Has full administrative access: manage themes, plugins, settings, and users"
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        group_id = app_config.get("group_id")
 | 
			
		||||
 | 
			
		||||
        for role_name, role_conf in roles.items():
 | 
			
		||||
            # Build CN under the application OU
 | 
			
		||||
            cn = role_name
 | 
			
		||||
            dn = f"cn={cn},{app_ou_dn}"
 | 
			
		||||
 | 
			
		||||
            entry = {
 | 
			
		||||
                "dn": dn,
 | 
			
		||||
                "cn": cn,
 | 
			
		||||
                "description": role_conf.get("description", ""),
 | 
			
		||||
                "objectClass": ["top"] + flavors,
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            member_dns = []
 | 
			
		||||
            member_uids = []
 | 
			
		||||
            for username, user_conf in users.items():
 | 
			
		||||
                if role_name in user_conf.get("roles", []):
 | 
			
		||||
                    member_dns.append(f"{ldap_user_attr}={username},{user_dn_base}")
 | 
			
		||||
                    member_uids.append(username)
 | 
			
		||||
 | 
			
		||||
            if "posixGroup" in flavors:
 | 
			
		||||
                entry["gidNumber"] = group_id
 | 
			
		||||
                if member_uids:
 | 
			
		||||
                    entry["memberUid"] = member_uids
 | 
			
		||||
 | 
			
		||||
            if "groupOfNames" in flavors and member_dns:
 | 
			
		||||
                entry["member"] = member_dns
 | 
			
		||||
 | 
			
		||||
            result[dn] = entry
 | 
			
		||||
 | 
			
		||||
    return result
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class FilterModule(object):
 | 
			
		||||
    def filters(self):
 | 
			
		||||
        return {
 | 
			
		||||
            "build_ldap_nested_group_entries": build_ldap_nested_group_entries
 | 
			
		||||
        }
 | 
			
		||||
							
								
								
									
										30
									
								
								roles/docker-ldap/templates/ldif/data/01_rbac_group.ldif.j2
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										30
									
								
								roles/docker-ldap/templates/ldif/data/01_rbac_group.ldif.j2
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,30 @@
 | 
			
		||||
{# 
 | 
			
		||||
@todo: activate
 | 
			
		||||
{% for dn, entry in (applications | build_ldap_role_entries(users, ldap)).items() %}
 | 
			
		||||
 | 
			
		||||
dn: {{ dn }}
 | 
			
		||||
{% for oc in entry.objectClass %}
 | 
			
		||||
objectClass: {{ oc }}
 | 
			
		||||
{% endfor %}
 | 
			
		||||
{% if entry.ou is defined %}
 | 
			
		||||
ou: {{ entry.ou }}
 | 
			
		||||
{% else %}
 | 
			
		||||
cn: {{ entry.cn }}
 | 
			
		||||
{% endif %}
 | 
			
		||||
{% if entry.gidNumber is defined %}
 | 
			
		||||
gidNumber: {{ entry.gidNumber }}
 | 
			
		||||
{% endif %}
 | 
			
		||||
description: {{ entry.description }}
 | 
			
		||||
{% if entry.memberUid is defined %}
 | 
			
		||||
{% for uid in entry.memberUid %}
 | 
			
		||||
memberUid: {{ uid }}
 | 
			
		||||
{% endfor %}
 | 
			
		||||
{% endif %}
 | 
			
		||||
{% if entry.member is defined %}
 | 
			
		||||
{% for m in entry.member %}
 | 
			
		||||
member: {{ m }}
 | 
			
		||||
{% endfor %}
 | 
			
		||||
{% endif %}
 | 
			
		||||
 | 
			
		||||
{% endfor %}
 | 
			
		||||
#}
 | 
			
		||||
		Reference in New Issue
	
	Block a user