mirror of
https://github.com/retspen/webvirtcloud
synced 2026-11-08 19:26:48 +00:00
fix(instances): only superusers and staff may change the template flag
change_options set is_template for any owner with is_change; the "staff only" rule existed only as a disabled checkbox in the UI. A non-staff owner could mark or unmark templates with a POST, and because a disabled checkbox is not submitted, a non-staff owner who only edited a template's title or description silently unmarked it, which lifted the template-only restrictions. Only change is_template for superusers and staff (for them an unchecked, unsubmitted checkbox still means "not a template"); leave it alone for everyone else.
This commit is contained in:
parent
b1ab1d47fa
commit
385a332197
2 changed files with 77 additions and 2 deletions
71
instances/test_template_flag.py
Normal file
71
instances/test_template_flag.py
Normal file
|
|
@ -0,0 +1,71 @@
|
|||
"""
|
||||
ROADMAP S-22: only superusers and staff may mark or unmark a VM as a template.
|
||||
The UI only disables the checkbox for other users, and a disabled checkbox is
|
||||
not submitted, so the server must not derive is_template from its absence for
|
||||
them.
|
||||
"""
|
||||
from unittest.mock import patch
|
||||
|
||||
from django.contrib.auth import get_user_model
|
||||
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
|
||||
|
||||
|
||||
class TemplateFlagTestCase(TestCase):
|
||||
def setUp(self):
|
||||
User = get_user_model()
|
||||
self.superuser = User.objects.create_superuser(
|
||||
username="tpl_super", email="tpl_super@example.com", password="x"
|
||||
)
|
||||
self.owner = User.objects.create_user(username="tpl_owner", password="x")
|
||||
self.staff_owner = User.objects.create_user(
|
||||
username="tpl_staff_owner", password="x", is_staff=True
|
||||
)
|
||||
self.compute = Compute.objects.create(
|
||||
name="tpl-compute", hostname="127.0.0.1:1", login="root", password="", type=1
|
||||
)
|
||||
self.instance = Instance.objects.create(
|
||||
compute=self.compute,
|
||||
name="tpl-vm",
|
||||
uuid="dddddddd-eeee-ffff-0000-111111111111",
|
||||
)
|
||||
for user in (self.owner, self.staff_owner):
|
||||
UserInstance.objects.create(instance=self.instance, user=user, is_change=True)
|
||||
|
||||
def _change_options(self, user, data):
|
||||
self.client.force_login(user)
|
||||
with patch("instances.models.wvmInstance"):
|
||||
res = self.client.post(
|
||||
reverse("instances:change_options", args=[self.instance.id]), data
|
||||
)
|
||||
self.assertEqual(res.status_code, 302)
|
||||
self.instance.refresh_from_db()
|
||||
|
||||
def _make_template(self):
|
||||
self.instance.is_template = True
|
||||
self.instance.save(update_fields=["is_template"])
|
||||
|
||||
def test_owner_cannot_mark_vm_as_template(self):
|
||||
self._change_options(self.owner, {"title": "t", "is_template": "True"})
|
||||
self.assertFalse(self.instance.is_template)
|
||||
|
||||
def test_owner_editing_title_does_not_unmark_template(self):
|
||||
self._make_template()
|
||||
self._change_options(self.owner, {"title": "new title", "description": ""})
|
||||
self.assertTrue(self.instance.is_template)
|
||||
|
||||
def test_staff_owner_can_mark_and_unmark_template(self):
|
||||
self._change_options(self.staff_owner, {"title": "t", "is_template": "True"})
|
||||
self.assertTrue(self.instance.is_template)
|
||||
# An unchecked checkbox is not submitted: for staff that means "not a template".
|
||||
self._change_options(self.staff_owner, {"title": "t"})
|
||||
self.assertFalse(self.instance.is_template)
|
||||
|
||||
def test_superuser_can_unmark_template(self):
|
||||
self._make_template()
|
||||
self._change_options(self.superuser, {"title": "t"})
|
||||
self.assertFalse(self.instance.is_template)
|
||||
|
|
@ -1711,8 +1711,12 @@ def change_options(request, pk):
|
|||
userinstance = UserInstance(is_change=False)
|
||||
|
||||
if request.user.is_superuser or userinstance.is_change:
|
||||
instance.is_template = bool(request.POST.get("is_template", False))
|
||||
instance.save()
|
||||
# Only superusers and staff may (un)mark templates (ROADMAP S-22). The
|
||||
# checkbox is disabled for everyone else, and a disabled checkbox is
|
||||
# not submitted, so for them the flag must be left alone.
|
||||
if request.user.is_superuser or request.user.is_staff:
|
||||
instance.is_template = bool(request.POST.get("is_template", False))
|
||||
instance.save(update_fields=["is_template"])
|
||||
|
||||
options = {}
|
||||
for post in request.POST:
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue