fix: remove admin bypass from server access helpers (#9933)#10006
Conversation
In server mode, administrators were auto-granted visibility into every user's private server groups and servers via four _is_admin() bypasses in server_access.py. This made the Object Explorer show a separate top-level "Servers" entry per user when logged in as admin, exposing private connections the admin should have no access to. The Administrator role in pgAdmin governs management of pgAdmin itself (users, preferences) — it is not intended to inherit other users' database credentials and connection state. Cross-user visibility requires explicit sharing (Server.shared=True), same as for any user. Remove the admin bypass from get_server, get_server_group, get_server_groups_for_user, and get_user_server_query. Drop the now- unused _is_admin() helper. Update docstrings to make the policy explicit. Add a regression test (admin attempts to fetch a non-admin user's private server group → expect HTTP 410). The original isolation test only covered non-admin → admin, which is why the regression introduced by 9a76ed8 was not caught.
|
PR changed again? Review this PR in Change Stack to compare snapshots and stay oriented. No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Path: .coderabbit.yaml Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (1)
🚧 Files skipped from review as they are similar to previous changes (1)
WalkthroughRemove Administrator bypass from server and server-group access checks so visibility is limited to resources owned by the current user or explicitly shared; add a regression test that asserts an admin cannot fetch another user’s private server group (GET returns 410). ChangesAdmin Data Isolation
🎯 3 (Moderate) | ⏱️ ~20 minutes 🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Pull request overview
Removes implicit Administrator-role bypasses in centralized server/server-group access helpers to restore strict per-user data isolation in server mode, and adds a regression test to prevent admins from seeing other users’ private server groups unless explicitly shared.
Changes:
- Removed Administrator “see everything” bypass logic from
web/pgadmin/utils/server_access.py. - Updated helper docstrings to clarify that the Administrator role does not inherit other users’ configured connections; sharing requires
Server.shared=True. - Added a regression test ensuring an admin cannot GET another user’s private server group (expects HTTP 410).
Reviewed changes
Copilot reviewed 2 out of 2 changed files in this pull request and generated 1 comment.
| File | Description |
|---|---|
| web/pgadmin/utils/server_access.py | Removes admin bypasses from server access helpers and updates policy docstrings. |
| web/pgadmin/browser/server_groups/tests/test_sg_data_isolation.py | Adds regression coverage for admin→non-admin server group isolation (expects 410). |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
All call sites of get_server() return HTTP 410 Gone when the helper returns None (e.g. servers/__init__.py:1507-1511, debugger/__init__.py: 1808-1812). The docstring incorrectly suggested 404 — predating this PR but adjacent to the lines being touched.
Summary
_is_admin()bypasses inweb/pgadmin/utils/server_access.pythat auto-granted Administrators visibility into every user's private server groups and servers. Drops the now-unused helper.Server.shared=True).AdminCannotSeeOtherUserGroupTestCase) — admin attempts to GET a non-admin's private server group → expects HTTP 410.Background
Fixes #9933.
The four bypasses were introduced in 9a76ed8 ("fix: enforce data isolation and harden shared servers in server mode") as part of the broader data-isolation work, on the assumption that Administrator implied "see everything." That assumption was wrong — pgAdmin's Administrator role exists for managing pgAdmin (users, preferences, via
tools/user_management), not for accessing other users' configured databases.The original
get_all_server_groups()(pre-9.15) had no admin bypass; this PR restores that semantics through the centralized helpers without re-introducing the unfiltered queries the 9a76ed8 work consolidated.The existing data-isolation tests only covered the non-admin → admin direction, which is why the regression slipped through CI. This PR adds the symmetric admin → non-admin case so it cannot regress silently again.
Test plan
python regression/runtests.py --pkg browser.server_groups.tests --modules test_sg_data_isolation→ 3/3 pass (includes the new admin-direction case)python regression/runtests.py --pkg browser.server_groups.servers.tests --modules test_server_data_isolation→ 6/6 pass (existing tests not broken)AssertionError: 200 != 410)pycodestyle --config=.pycodestyleclean on the changed filesSummary by CodeRabbit
Tests
Bug Fixes