48 lines
1.8 KiB
Python
48 lines
1.8 KiB
Python
"""RBAC-Durchsetzung: Rolle × Hostgruppe (siehe Konzept 4.6).
|
||
|
||
Eine Rolle gilt fuer einen User entweder, wenn sie ihm DIREKT vergeben wurde
|
||
(user_hostgroup_roles), ODER wenn sie einer Benutzergruppe (user_groups)
|
||
vergeben wurde, in der der User Mitglied ist (group_hostgroup_roles) --
|
||
volle Rollen-Vererbung: jedes Gruppenmitglied erhaelt automatisch alle der
|
||
Gruppe gewaehrten Rollen, ohne individuellen Eintrag."""
|
||
from __future__ import annotations
|
||
|
||
import aiosqlite
|
||
|
||
|
||
async def user_has_role(
|
||
conn: aiosqlite.Connection, *, user_id: int, host_group_id: int, role_name: str
|
||
) -> bool:
|
||
cursor = await conn.execute(
|
||
"""
|
||
SELECT 1 FROM user_hostgroup_roles uhr
|
||
JOIN roles r ON r.id = uhr.role_id
|
||
WHERE uhr.user_id = ?
|
||
AND uhr.host_group_id = ?
|
||
AND r.name = ?
|
||
AND (uhr.expires_at IS NULL OR uhr.expires_at > strftime('%Y-%m-%dT%H:%M:%fZ','now'))
|
||
UNION
|
||
SELECT 1 FROM group_hostgroup_roles ghr
|
||
JOIN roles r ON r.id = ghr.role_id
|
||
JOIN user_group_members ugm ON ugm.user_group_id = ghr.user_group_id
|
||
WHERE ugm.user_id = ?
|
||
AND ghr.host_group_id = ?
|
||
AND r.name = ?
|
||
AND (ghr.expires_at IS NULL OR ghr.expires_at > strftime('%Y-%m-%dT%H:%M:%fZ','now'))
|
||
LIMIT 1
|
||
""",
|
||
(user_id, host_group_id, role_name, user_id, host_group_id, role_name),
|
||
)
|
||
row = await cursor.fetchone()
|
||
return row is not None
|
||
|
||
|
||
async def user_has_role_for_host(
|
||
conn: aiosqlite.Connection, *, user_id: int, host_id: int, role_name: str
|
||
) -> bool:
|
||
cursor = await conn.execute("SELECT host_group_id FROM hosts WHERE id = ?", (host_id,))
|
||
row = await cursor.fetchone()
|
||
if row is None:
|
||
return False
|
||
return await user_has_role(conn, user_id=user_id, host_group_id=row[0], role_name=role_name)
|