mirror of
https://github.com/retspen/webvirtcloud
synced 2026-11-08 19:26:48 +00:00
Settings > Console was one horizontal form, and on a running VM its
Update button was disabled. The owner chose this layout from three
rendered options: the console type on top, then a "VNC connection" card
(listen address, keymap) and a "VNC password" card.
- The password is changed by an action: keep it, generate a new one,
set a new one or remove it. This replaces the Generate and Clear
boxes and their precedence, and an emptied field no longer removes
the password silently. The pane says whether a password is set; the
form no longer carries the password itself.
- A VNC password takes at most 8 bytes: libvirt refuses a longer one
("VNC password is 9 characters long, only 8 permitted"). Generate and
a new VM's random password now make 8 characters; they made 12, which
libvirt 11 refuses. A set password keeps its spaces.
- Every check is in the form, so a refused save changes nothing; before,
a refused password removal still saved the other settings.
- The settings can be saved while the VM runs: they are in the
persistent definition. A line says the running console keeps its
settings until the VM is shut down and started.
- The console type shown and compared is the persistent one; it was the
running VM's, so a pending switch to Serial showed VNC and a later
save could switch again.
- While the saved type is Serial, the VNC settings are not shown or
taken; choosing Serial ignores the posted VNC settings.
85 lines
3.6 KiB
Python
85 lines
3.6 KiB
Python
"""
|
|
The console settings form is rendered only for users who may change console
|
|
settings, which is the rule update_console enforces: a superuser, or an owner
|
|
with both is_change and is_vnc; not for is_staff or the global view_instances
|
|
permission. The form never carries the VNC password: it says whether one is
|
|
set.
|
|
"""
|
|
from unittest.mock import PropertyMock, patch
|
|
|
|
from django.contrib.auth import get_user_model
|
|
from django.contrib.auth.models import Permission
|
|
from django.test import TestCase
|
|
from django.urls import reverse
|
|
|
|
from accounts.models import UserInstance
|
|
from computes.models import Compute
|
|
from instances.models import Instance
|
|
|
|
VNC_PASSWORD = "s3cretVNCpass"
|
|
|
|
|
|
class ConsoleSettingsAccessTestCase(TestCase):
|
|
def setUp(self):
|
|
User = get_user_model()
|
|
view_perm = Permission.objects.get(codename="view_instances")
|
|
self.superuser = User.objects.create_superuser(
|
|
username="vncpw_super", email="vncpw_super@example.com", password="x"
|
|
)
|
|
self.staff_viewer = User.objects.create_user(
|
|
username="vncpw_staff_viewer", password="x", is_staff=True
|
|
)
|
|
self.staff_viewer.user_permissions.add(view_perm)
|
|
self.staff_owner = User.objects.create_user(
|
|
username="vncpw_staff_owner", password="x", is_staff=True
|
|
)
|
|
self.vnc_owner = User.objects.create_user(username="vncpw_vnc_owner", password="x")
|
|
|
|
self.compute = Compute.objects.create(
|
|
name="vncpw-compute", hostname="127.0.0.1:1", login="root", password="", type=1
|
|
)
|
|
self.instance = Instance.objects.create(
|
|
compute=self.compute,
|
|
name="vncpw-vm",
|
|
uuid="cccccccc-dddd-eeee-ffff-000000000000",
|
|
)
|
|
UserInstance.objects.create(
|
|
instance=self.instance, user=self.staff_owner, is_change=True, is_vnc=False
|
|
)
|
|
UserInstance.objects.create(
|
|
instance=self.instance, user=self.vnc_owner, is_change=True, is_vnc=True
|
|
)
|
|
|
|
def _detail_page(self, user):
|
|
self.client.force_login(user)
|
|
with patch("instances.models.wvmInstance") as mock_wvm, patch.object(
|
|
Compute, "status", new_callable=PropertyMock, return_value=True
|
|
):
|
|
proxy = mock_wvm.return_value
|
|
proxy.get_memory.return_value = 1024
|
|
proxy.get_cur_memory.return_value = 1024
|
|
proxy.get_max_memory.return_value = 4096
|
|
proxy.get_networks.return_value = []
|
|
proxy.get_ifaces.return_value = []
|
|
proxy.get_hostdevs.return_value = ([], [], [])
|
|
proxy.get_storages.return_value = []
|
|
proxy.get_console_passwd.return_value = VNC_PASSWORD
|
|
proxy.get_console_type.return_value = "vnc"
|
|
proxy.get_status.return_value = 5
|
|
proxy.get_disk_devices.return_value = []
|
|
proxy.get_media_devices.return_value = []
|
|
proxy.get_net_devices.return_value = []
|
|
response = self.client.get(
|
|
reverse("instances:instance", args=[self.instance.id])
|
|
)
|
|
self.assertEqual(response.status_code, 200)
|
|
return response.content.decode()
|
|
|
|
def test_only_users_who_may_change_the_console_see_its_settings(self):
|
|
form = reverse("instances:update_console", args=[self.instance.id])
|
|
for user, shown in ((self.staff_viewer, False), (self.staff_owner, False),
|
|
(self.vnc_owner, True), (self.superuser, True)):
|
|
with self.subTest(user.username):
|
|
page = self._detail_page(user)
|
|
self.assertEqual(form in page, shown)
|
|
self.assertNotIn(VNC_PASSWORD, page)
|