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:
+38
-35
@@ -1,51 +1,54 @@
|
||||
# retoor <retoor@molodetz.nl>
|
||||
|
||||
MARK = "_apitest_dbapi_crud"
|
||||
from devplacepy.database import get_table, purge
|
||||
from devplacepy.utils import generate_uid
|
||||
|
||||
MARK = "_apitest_dbapi_readonly"
|
||||
|
||||
|
||||
def test_list_requires_auth(client):
|
||||
assert client.get("/dbapi/users").status_code == 403
|
||||
|
||||
|
||||
def test_crud_round_trip(client, auth):
|
||||
created = client.post(
|
||||
def test_reads_work(client, auth):
|
||||
uid = generate_uid()
|
||||
get_table("bookmarks").insert(
|
||||
{
|
||||
"uid": uid,
|
||||
"user_uid": MARK,
|
||||
"target_type": "post",
|
||||
"target_uid": "t1",
|
||||
"deleted_at": None,
|
||||
"deleted_by": None,
|
||||
}
|
||||
)
|
||||
try:
|
||||
listing = client.get(f"/dbapi/bookmarks?filter.user_uid={MARK}", headers=auth)
|
||||
assert listing.status_code == 200
|
||||
assert listing.json()["count"] == 1
|
||||
|
||||
got = client.get(f"/dbapi/bookmarks/uid/{uid}", headers=auth)
|
||||
assert got.status_code == 200
|
||||
assert got.json()["row"]["uid"] == uid
|
||||
finally:
|
||||
purge("bookmarks", user_uid=MARK)
|
||||
|
||||
|
||||
def test_writes_are_not_available(client, auth):
|
||||
insert = client.post(
|
||||
"/dbapi/bookmarks",
|
||||
json={"user_uid": MARK, "target_type": "post", "target_uid": "t1"},
|
||||
headers=auth,
|
||||
)
|
||||
assert created.status_code == 200
|
||||
row = created.json()["row"]
|
||||
uid = row["uid"]
|
||||
assert row["deleted_at"] is None
|
||||
try:
|
||||
got = client.get(f"/dbapi/bookmarks/uid/{uid}", headers=auth)
|
||||
assert got.json()["row"]["uid"] == uid
|
||||
|
||||
updated = client.patch(
|
||||
f"/dbapi/bookmarks/uid/{uid}", json={"target_uid": "t2"}, headers=auth
|
||||
)
|
||||
assert updated.json()["row"]["target_uid"] == "t2"
|
||||
|
||||
deleted = client.delete(f"/dbapi/bookmarks/uid/{uid}", headers=auth)
|
||||
assert deleted.json()["mode"] == "soft"
|
||||
live = client.get(f"/dbapi/bookmarks?filter.user_uid={MARK}", headers=auth)
|
||||
assert live.json()["count"] == 0
|
||||
with_deleted = client.get(
|
||||
f"/dbapi/bookmarks?filter.user_uid={MARK}&include_deleted=true", headers=auth
|
||||
)
|
||||
assert with_deleted.json()["count"] == 1
|
||||
|
||||
restored = client.post(f"/dbapi/bookmarks/uid/{uid}/restore", headers=auth)
|
||||
assert restored.json()["row"]["deleted_at"] is None
|
||||
finally:
|
||||
client.delete(f"/dbapi/bookmarks/uid/{uid}?hard=true", headers=auth)
|
||||
|
||||
|
||||
def test_insert_unknown_column_is_400(client, auth):
|
||||
response = client.post(
|
||||
"/dbapi/bookmarks", json={"user_uid": MARK, "no_such_col": 1}, headers=auth
|
||||
assert insert.status_code in (404, 405)
|
||||
patched = client.patch(
|
||||
"/dbapi/bookmarks/uid/whatever", json={"target_uid": "t2"}, headers=auth
|
||||
)
|
||||
assert response.status_code == 400
|
||||
assert patched.status_code in (404, 405)
|
||||
removed = client.delete("/dbapi/bookmarks/uid/whatever", headers=auth)
|
||||
assert removed.status_code in (404, 405)
|
||||
restored = client.post("/dbapi/bookmarks/uid/whatever/restore", headers=auth)
|
||||
assert restored.status_code in (404, 405)
|
||||
|
||||
|
||||
def test_get_missing_row_is_404(client, auth):
|
||||
|
||||
Reference in New Issue
Block a user