mirror of
https://github.com/netbox-community/netbox.git
synced 2026-04-02 15:37:18 +02:00
Fix shared action pre-selection and additional actions leakage on edit
This commit is contained in:
@@ -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:
|
||||
|
||||
@@ -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()
|
||||
|
||||
Reference in New Issue
Block a user