Fix shared action pre-selection and additional actions leakage on edit

This commit is contained in:
Jason Novinger
2026-03-03 15:38:00 -06:00
parent 637ebf642c
commit 3f2734d5b8
2 changed files with 44 additions and 3 deletions

View File

@@ -430,17 +430,20 @@ class ObjectPermissionForm(forms.ModelForm):
# Pre-select registered actions
selected_registered = []
consumed_actions = set()
for ct in self.instance.object_types.all():
model_key = f'{ct.app_label}.{ct.model}'
if model_key in model_actions:
for ma in model_actions[model_key]:
if ma.name in remaining_actions:
selected_registered.append(f'{model_key}.{ma.name}')
remaining_actions.remove(ma.name)
consumed_actions.add(ma.name)
self.fields['registered_actions'].initial = selected_registered
# Remaining actions go to the additional actions field
self.fields['actions'].initial = remaining_actions
self.initial['actions'] = [
a for a in remaining_actions if a not in consumed_actions
]
# Populate initial data for a new ObjectPermission
elif self.initial:

View File

@@ -1,8 +1,12 @@
from django.test import TestCase
from dcim.models import Site
from core.models import ObjectType
from dcim.models import Device, Site
from netbox.registry import registry
from users.forms.model_forms import ObjectPermissionForm
from users.models import ObjectPermission
from utilities.permissions import ModelAction, register_model_actions
from virtualization.models import VirtualMachine
class ModelActionTest(TestCase):
@@ -75,3 +79,37 @@ class RegisterModelActionsTest(TestCase):
self.assertEqual(len(actions), 2)
self.assertEqual(actions[0].name, 'first')
self.assertEqual(actions[1].name, 'second')
class ObjectPermissionFormTest(TestCase):
def setUp(self):
self.original_actions = dict(registry['model_actions'])
def tearDown(self):
registry['model_actions'].clear()
registry['model_actions'].update(self.original_actions)
def test_shared_action_preselection(self):
register_model_actions(Device, [ModelAction('render_config')])
register_model_actions(VirtualMachine, [ModelAction('render_config')])
device_ct = ObjectType.objects.get_for_model(Device)
vm_ct = ObjectType.objects.get_for_model(VirtualMachine)
permission = ObjectPermission.objects.create(
name='Test Permission',
actions=['view', 'render_config'],
)
permission.object_types.set([device_ct, vm_ct])
form = ObjectPermissionForm(instance=permission)
initial = form.fields['registered_actions'].initial
self.assertIn('dcim.device.render_config', initial)
self.assertIn('virtualization.virtualmachine.render_config', initial)
# Should not leak into the additional actions field
self.assertEqual(form.initial['actions'], [])
permission.delete()