1
0
Fork 0
mirror of https://github.com/retspen/webvirtcloud synced 2026-11-11 12:46:49 +00:00

feat(security): apply Codex review hardening to console tokens and superuser authorization

This commit is contained in:
catborise 2026-09-27 11:30:03 +03:00
parent 1227674d8f
commit 708b986e8e
11 changed files with 168 additions and 26 deletions

View file

@ -23,6 +23,13 @@ class APISecurityTestCase(TestCase):
email="user@example.com",
password="userpassword",
)
self.staff_user = User.objects.create_user(
username="staff_api_user",
email="staff@example.com",
password="staffpassword",
is_staff=True,
is_superuser=False,
)
self.compute = Compute.objects.create(
name="api-test-compute",
hostname="127.0.0.1",
@ -30,6 +37,13 @@ class APISecurityTestCase(TestCase):
password="secret_hypervisor_password",
type=1,
)
self.empty_compute = Compute.objects.create(
name="empty-test-compute",
hostname="127.0.0.1",
login="libvirt_user",
password="secret_hypervisor_password",
type=1,
)
self.flavor = Flavor.objects.create(
label="test-flavor",
vcpu=2,
@ -60,11 +74,16 @@ class APISecurityTestCase(TestCase):
res = self.client.get("/api/v1/computes/")
self.assertIn(res.status_code, [302, 401, 403])
# Regular user - forbidden by IsAdminUser
# Regular user - forbidden by IsSuperUser
self.client.force_login(self.regular_user)
res = self.client.get("/api/v1/computes/")
self.assertEqual(res.status_code, 403)
# Staff user (not superuser) - forbidden by IsSuperUser
self.client.force_login(self.staff_user)
res = self.client.get("/api/v1/computes/")
self.assertEqual(res.status_code, 403)
# Admin user - allowed
self.client.force_login(self.admin)
res = self.client.get("/api/v1/computes/")
@ -72,13 +91,22 @@ class APISecurityTestCase(TestCase):
@patch("computes.utils.refresh_instance_database")
def test_compute_instance_list_isolation(self, mock_refresh):
# Regular user should only see instance1
# Regular user should only see instance1 on compute
self.client.force_login(self.regular_user)
res = self.client.get(f"/api/v1/computes/{self.compute.id}/instances/")
self.assertEqual(res.status_code, 200)
names = [item["name"] for item in res.data]
self.assertIn("inst-user-owned", names)
self.assertNotIn("inst-other-owned", names)
mock_refresh.assert_called_once_with(self.compute)
# Regular user accessing compute where they have NO instances:
# returns empty list without calling refresh_instance_database!
mock_refresh.reset_mock()
res_empty = self.client.get(f"/api/v1/computes/{self.empty_compute.id}/instances/")
self.assertEqual(res_empty.status_code, 200)
self.assertEqual(res_empty.data, [])
mock_refresh.assert_not_called()
# Admin user should see both instances
self.client.force_login(self.admin)
@ -101,6 +129,14 @@ class APISecurityTestCase(TestCase):
)
self.assertEqual(res.status_code, 403)
# Staff user (not superuser) cannot mutate flavors
self.client.force_login(self.staff_user)
res = self.client.post(
"/api/v1/flavor/",
{"label": "staffmutate", "vcpu": 4, "memory": 4096, "disk": 40},
)
self.assertEqual(res.status_code, 403)
res = self.client.delete(f"/api/v1/flavor/{self.flavor.id}/")
self.assertEqual(res.status_code, 403)
@ -109,17 +145,33 @@ class APISecurityTestCase(TestCase):
res = self.client.post("/api/v1/migrate/", {})
self.assertEqual(res.status_code, 403)
self.client.force_login(self.staff_user)
res = self.client.post("/api/v1/migrate/", {})
self.assertEqual(res.status_code, 403)
def test_network_viewset_permissions(self):
self.client.force_login(self.regular_user)
res = self.client.get(f"/api/v1/computes/{self.compute.id}/networks/")
self.assertEqual(res.status_code, 403)
self.client.force_login(self.staff_user)
res = self.client.get(f"/api/v1/computes/{self.compute.id}/networks/")
self.assertEqual(res.status_code, 403)
def test_interface_viewset_permissions(self):
self.client.force_login(self.regular_user)
res = self.client.get(f"/api/v1/computes/{self.compute.id}/interfaces/")
self.assertEqual(res.status_code, 403)
self.client.force_login(self.staff_user)
res = self.client.get(f"/api/v1/computes/{self.compute.id}/interfaces/")
self.assertEqual(res.status_code, 403)
def test_storage_viewset_permissions(self):
self.client.force_login(self.regular_user)
res = self.client.get(f"/api/v1/computes/{self.compute.id}/storages/")
self.assertEqual(res.status_code, 403)
self.client.force_login(self.staff_user)
res = self.client.get(f"/api/v1/computes/{self.compute.id}/storages/")
self.assertEqual(res.status_code, 403)