mirror of
https://github.com/GNS3/gns3-server.git
synced 2026-08-27 20:40:13 +03:00
feat: fix permission check logic to properly handle ACE and user isolation
Implement the correct three-step permission check logic: - Step 1: ACE check - basic access permission (get projects user has ACE for) - Step 2: Filter ace_projects by created_by - user's own projects (project sharing only through resource pools) - Step 3: Resource pool projects (projects shared through resource pools) This fixes the design flaw where: - ACE check could bypass user isolation with broad ACE configurations - seen_project_ids mechanism prevented proper layered checking - Project sharing was confused with direct ACE configuration The new logic ensures: - User isolation works even with broad ACE (path='/', propagate=True) - Project sharing is only available through resource pools (clear design) - Proper layered checking without seen blocking mechanism
This commit is contained in:
parent
265d0ff860
commit
ee36a9aec2
@ -86,32 +86,29 @@ async def get_projects(
|
||||
|
||||
controller = Controller.instance()
|
||||
projects = []
|
||||
seen_project_ids = set()
|
||||
|
||||
if current_user.is_superadmin:
|
||||
# super admin sees all projects
|
||||
return [p.asdict() for p in controller.projects.values()]
|
||||
|
||||
# Layer 1: ACE strategy check - explicitly authorized projects
|
||||
# Check projects where user has specific ACE (shared by other users)
|
||||
# Step 1: ACE check - basic access permission
|
||||
# Get projects user has ACE for (basic access control)
|
||||
ace_projects = []
|
||||
for project in controller.projects.values():
|
||||
project_path = f"/projects/{project.id}"
|
||||
if await rbac_repo.check_user_has_privilege(current_user.user_id, project_path, "Project.Audit"):
|
||||
if project.id not in seen_project_ids:
|
||||
projects.append(project.asdict())
|
||||
seen_project_ids.add(project.id)
|
||||
ace_projects.append(project)
|
||||
|
||||
# Layer 2: Ownership check - user's own projects
|
||||
# If no ACE strategy, filter by created_by
|
||||
user_projects = [p.asdict() for p in controller.projects.values()
|
||||
if p.created_by == current_user.username and p.id not in seen_project_ids]
|
||||
# Step 2: Filter ace_projects by created_by - user's own projects
|
||||
# Project sharing is only available through resource pools
|
||||
user_projects = [p.asdict() for p in ace_projects if p.created_by == current_user.username]
|
||||
projects.extend(user_projects)
|
||||
|
||||
# Layer 3: Resource pools - team shared projects
|
||||
# Step 3: Resource pool projects
|
||||
# Projects shared through resource pools
|
||||
user_pool_resources = await rbac_repo.get_user_pool_resources(current_user.user_id, "Project.Audit")
|
||||
project_ids_in_pools = [str(r.resource_id) for r in user_pool_resources if r.resource_type == "project"]
|
||||
pool_projects = [p.asdict() for p in controller.projects.values()
|
||||
if p.id in project_ids_in_pools and p.id not in seen_project_ids]
|
||||
pool_projects = [p.asdict() for p in controller.projects.values() if p.id in project_ids_in_pools]
|
||||
projects.extend(pool_projects)
|
||||
|
||||
return projects
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user