feat: restrict backup archive download to primary admin and hide admin-hidden projects from other admins
DevPlace CI / test (push) Failing after 22m57s
DevPlace CI / test (push) Failing after 22m57s
- Add `get_admin_uids()` and `get_primary_admin_uid()` to database.py for resolving the earliest-created admin - Modify `can_view_project()` in content.py so a project hidden by an admin is invisible to other admins (both web UI and REST API) - Update `_download_url()` and `_backup_payload()` in admin/backups.py to accept a `can_download` flag, gating the download endpoint with `is_primary_admin()` - Remove `role` from `_user_facts()` in docs_live.py to avoid leaking admin status in live docs - Update doc summaries in docs_api.py to reflect the new admin-visibility and backup-download semantics
This commit is contained in:
@@ -78,6 +78,16 @@ def _list_slugs(key=None, user_uid=None):
|
||||
params = {"user_uid": user_uid} if user_uid else None
|
||||
r = requests.get(f"{BASE_URL}/projects", headers=_h_project_visibility(key), params=params)
|
||||
return [p["slug"] for p in r.json()["projects"]]
|
||||
def _detail_status(key, slug):
|
||||
return requests.get(
|
||||
f"{BASE_URL}/projects/{slug}", headers=_h_project_visibility(key)
|
||||
).status_code
|
||||
def _file_raw_status(key, slug, path):
|
||||
return requests.get(
|
||||
f"{BASE_URL}/projects/{slug}/files/raw",
|
||||
headers=_h_project_visibility(key),
|
||||
params={"path": path},
|
||||
).status_code
|
||||
|
||||
|
||||
def test_private_project_hidden_from_guest_listing(app_server):
|
||||
@@ -101,6 +111,29 @@ def test_private_project_visible_to_admin(app_server):
|
||||
assert slug in _list_slugs(key=admin_key, user_uid=owner_uid)
|
||||
|
||||
|
||||
def test_admin_private_hidden_from_other_admin(app_server):
|
||||
_, owner_uid, owner_key = _make_admin_project_visibility()
|
||||
_, _, other_admin_key = _make_admin_project_visibility()
|
||||
slug = _create_project_project_visibility(
|
||||
owner_key, "Admin Hidden", is_private=True
|
||||
)["slug"]
|
||||
assert slug not in _list_slugs(key=other_admin_key, user_uid=owner_uid)
|
||||
assert _detail_status(other_admin_key, slug) == 404
|
||||
assert _file_raw_status(other_admin_key, slug, "missing.txt") == 404
|
||||
assert slug in _list_slugs(key=owner_key, user_uid=owner_uid)
|
||||
assert _detail_status(owner_key, slug) == 200
|
||||
|
||||
|
||||
def test_member_private_still_visible_to_admin(app_server):
|
||||
_, owner_uid, owner_key = _signup_project_visibility()
|
||||
_, _, admin_key = _make_admin_project_visibility()
|
||||
slug = _create_project_project_visibility(
|
||||
owner_key, "Member Hidden", is_private=True
|
||||
)["slug"]
|
||||
assert slug in _list_slugs(key=admin_key, user_uid=owner_uid)
|
||||
assert _detail_status(admin_key, slug) == 200
|
||||
|
||||
|
||||
def test_toggle_private_then_public(app_server):
|
||||
_, owner_uid, key = _signup_project_visibility()
|
||||
slug = _create_project_project_visibility(key, "Toggle Privacy")["slug"]
|
||||
|
||||
Reference in New Issue
Block a user