From 1eaa3524d5021b4b9086656566e91aefa8e21812 Mon Sep 17 00:00:00 2001 From: catborise Date: Fri, 23 Oct 2026 13:28:06 +0300 Subject: [PATCH] fix(accounts): a VM's only owner can be edited when one owner is allowed With "Multiple Owner for VM" off, the ownership form counted the ownership being edited as another owner, so changing the only owner's rights (change, delete, console) always failed with "Instance owned by another user". The check now leaves out the ownership being edited; a second owner is still refused. --- accounts/forms.py | 3 ++- accounts/tests/test_views.py | 18 ++++++++++++++++++ 2 files changed, 20 insertions(+), 1 deletion(-) diff --git a/accounts/forms.py b/accounts/forms.py index d4c7e567..f9ed733d 100644 --- a/accounts/forms.py +++ b/accounts/forms.py @@ -20,7 +20,8 @@ class UserInstanceForm(ModelForm): def clean_instance(self): instance = self.cleaned_data["instance"] if app_settings.ALLOW_INSTANCE_MULTIPLE_OWNER == "False": - exists = UserInstance.objects.filter(instance=instance) + # the ownership being edited is not another owner + exists = UserInstance.objects.filter(instance=instance).exclude(pk=self.instance.pk) if exists: raise ValidationError(_("Instance owned by another user")) diff --git a/accounts/tests/test_views.py b/accounts/tests/test_views.py index 0d9d6547..41e58e87 100644 --- a/accounts/tests/test_views.py +++ b/accounts/tests/test_views.py @@ -1,3 +1,4 @@ +from appsettings.models import AppSettings from appsettings.settings import app_settings from computes.models import Compute from django.conf import settings @@ -293,3 +294,20 @@ class AccountsTestCase(TestCase): } ) self.assertFalse(form.is_valid()) + + +class SingleOwnerEditTests(TestCase): + """With one owner per VM, the owner's own rights can still be changed.""" + + def test_the_only_owner_is_edited(self): + AppSettings.objects.filter(key="ALLOW_INSTANCE_MULTIPLE_OWNER").update(value="False") + admin = get_user_model().objects.create_superuser("audit-admin", "audit@example.com", "pw") + bob = get_user_model().objects.create_user("bob") + compute = Compute.objects.create(name="c1", hostname="127.0.0.1", login="", password="", type=4) + vm = Instance.objects.create(compute=compute, name="vm", uuid="99999999-9999-9999-9999-999999999999") + ui = UserInstance.objects.create(user=bob, instance=vm) + self.client.force_login(admin) + response = self.client.post(reverse("accounts:user_instance_update", args=[ui.pk]), {"is_vnc": "on"}) + self.assertRedirects(response, reverse("accounts:account", args=[bob.pk]), fetch_redirect_response=False) + ui.refresh_from_db() + self.assertTrue(ui.is_vnc)