From 804f22779dca03e6af86be143a9c947b3e099c85 Mon Sep 17 00:00:00 2001 From: Jeremy Stretch Date: Fri, 20 Oct 2023 14:46:36 -0400 Subject: [PATCH] Introduce DEFAULT_ACTION_PERMISSIONS constant --- netbox/dcim/views.py | 85 +++++---------------------- netbox/extras/views.py | 13 +--- netbox/netbox/constants.py | 9 +++ netbox/netbox/views/generic/mixins.py | 18 +++--- netbox/virtualization/views.py | 7 +-- 5 files changed, 39 insertions(+), 93 deletions(-) diff --git a/netbox/dcim/views.py b/netbox/dcim/views.py index 247ce422b..0f5768173 100644 --- a/netbox/dcim/views.py +++ b/netbox/dcim/views.py @@ -20,6 +20,7 @@ from circuits.models import Circuit, CircuitTermination from extras.views import ObjectConfigContextView from ipam.models import ASN, IPAddress, Prefix, VLAN, VLANGroup from ipam.tables import InterfaceVLANTable +from netbox.constants import DEFAULT_ACTION_PERMISSIONS from netbox.views import generic from tenancy.views import ObjectContactsView from utilities.forms import ConfirmationForm @@ -47,11 +48,7 @@ CABLE_TERMINATION_TYPES = { class DeviceComponentsView(generic.ObjectChildrenView): actions = { - 'add': {'add'}, - 'import': {'add'}, - 'export': {'view'}, - 'bulk_edit': {'change'}, - 'bulk_delete': {'delete'}, + **DEFAULT_ACTION_PERMISSIONS, 'bulk_rename': {'change'}, 'bulk_disconnect': {'change'}, } @@ -1978,11 +1975,7 @@ class DeviceModuleBaysView(DeviceComponentsView): filterset = filtersets.ModuleBayFilterSet template_name = 'dcim/device/modulebays.html' actions = { - 'add': {'add'}, - 'import': {'add'}, - 'export': {'view'}, - 'bulk_edit': {'change'}, - 'bulk_delete': {'delete'}, + **DEFAULT_ACTION_PERMISSIONS, 'bulk_rename': {'change'}, } tab = ViewTab( @@ -2001,11 +1994,7 @@ class DeviceDeviceBaysView(DeviceComponentsView): filterset = filtersets.DeviceBayFilterSet template_name = 'dcim/device/devicebays.html' actions = { - 'add': {'add'}, - 'import': {'add'}, - 'export': {'view'}, - 'bulk_edit': {'change'}, - 'bulk_delete': {'delete'}, + **DEFAULT_ACTION_PERMISSIONS, 'bulk_rename': {'change'}, } tab = ViewTab( @@ -2024,11 +2013,7 @@ class DeviceInventoryView(DeviceComponentsView): filterset = filtersets.InventoryItemFilterSet template_name = 'dcim/device/inventory.html' actions = { - 'add': {'add'}, - 'import': {'add'}, - 'export': {'view'}, - 'bulk_edit': {'change'}, - 'bulk_delete': {'delete'}, + **DEFAULT_ACTION_PERMISSIONS, 'bulk_rename': {'change'}, } tab = ViewTab( @@ -2209,11 +2194,7 @@ class ConsolePortListView(generic.ObjectListView): table = tables.ConsolePortTable template_name = 'dcim/component_list.html' actions = { - 'add': {'add'}, - 'import': {'add'}, - 'export': {'view'}, - 'bulk_edit': {'change'}, - 'bulk_delete': {'delete'}, + **DEFAULT_ACTION_PERMISSIONS, 'bulk_rename': {'change'}, } @@ -2281,11 +2262,7 @@ class ConsoleServerPortListView(generic.ObjectListView): table = tables.ConsoleServerPortTable template_name = 'dcim/component_list.html' actions = { - 'add': {'add'}, - 'import': {'add'}, - 'export': {'view'}, - 'bulk_edit': {'change'}, - 'bulk_delete': {'delete'}, + **DEFAULT_ACTION_PERMISSIONS, 'bulk_rename': {'change'}, } @@ -2353,11 +2330,7 @@ class PowerPortListView(generic.ObjectListView): table = tables.PowerPortTable template_name = 'dcim/component_list.html' actions = { - 'add': {'add'}, - 'import': {'add'}, - 'export': {'view'}, - 'bulk_edit': {'change'}, - 'bulk_delete': {'delete'}, + **DEFAULT_ACTION_PERMISSIONS, 'bulk_rename': {'change'}, } @@ -2425,11 +2398,7 @@ class PowerOutletListView(generic.ObjectListView): table = tables.PowerOutletTable template_name = 'dcim/component_list.html' actions = { - 'add': {'add'}, - 'import': {'add'}, - 'export': {'view'}, - 'bulk_edit': {'change'}, - 'bulk_delete': {'delete'}, + **DEFAULT_ACTION_PERMISSIONS, 'bulk_rename': {'change'}, } @@ -2497,11 +2466,7 @@ class InterfaceListView(generic.ObjectListView): table = tables.InterfaceTable template_name = 'dcim/component_list.html' actions = { - 'add': {'add'}, - 'import': {'add'}, - 'export': {'view'}, - 'bulk_edit': {'change'}, - 'bulk_delete': {'delete'}, + **DEFAULT_ACTION_PERMISSIONS, 'bulk_rename': {'change'}, } @@ -2617,11 +2582,7 @@ class FrontPortListView(generic.ObjectListView): table = tables.FrontPortTable template_name = 'dcim/component_list.html' actions = { - 'add': {'add'}, - 'import': {'add'}, - 'export': {'view'}, - 'bulk_edit': {'change'}, - 'bulk_delete': {'delete'}, + **DEFAULT_ACTION_PERMISSIONS, 'bulk_rename': {'change'}, } @@ -2689,11 +2650,7 @@ class RearPortListView(generic.ObjectListView): table = tables.RearPortTable template_name = 'dcim/component_list.html' actions = { - 'add': {'add'}, - 'import': {'add'}, - 'export': {'view'}, - 'bulk_edit': {'change'}, - 'bulk_delete': {'delete'}, + **DEFAULT_ACTION_PERMISSIONS, 'bulk_rename': {'change'}, } @@ -2761,11 +2718,7 @@ class ModuleBayListView(generic.ObjectListView): table = tables.ModuleBayTable template_name = 'dcim/component_list.html' actions = { - 'add': {'add'}, - 'import': {'add'}, - 'export': {'view'}, - 'bulk_edit': {'change'}, - 'bulk_delete': {'delete'}, + **DEFAULT_ACTION_PERMISSIONS, 'bulk_rename': {'change'}, } @@ -2825,11 +2778,7 @@ class DeviceBayListView(generic.ObjectListView): table = tables.DeviceBayTable template_name = 'dcim/component_list.html' actions = { - 'add': {'add'}, - 'import': {'add'}, - 'export': {'view'}, - 'bulk_edit': {'change'}, - 'bulk_delete': {'delete'}, + **DEFAULT_ACTION_PERMISSIONS, 'bulk_rename': {'change'}, } @@ -2958,11 +2907,7 @@ class InventoryItemListView(generic.ObjectListView): table = tables.InventoryItemTable template_name = 'dcim/component_list.html' actions = { - 'add': {'add'}, - 'import': {'add'}, - 'export': {'view'}, - 'bulk_edit': {'change'}, - 'bulk_delete': {'delete'}, + **DEFAULT_ACTION_PERMISSIONS, 'bulk_rename': {'change'}, } diff --git a/netbox/extras/views.py b/netbox/extras/views.py index a4a6d05c9..0e8e3b0ea 100644 --- a/netbox/extras/views.py +++ b/netbox/extras/views.py @@ -16,6 +16,7 @@ from core.tables import JobTable from extras.dashboard.forms import DashboardWidgetAddForm, DashboardWidgetForm from extras.dashboard.utils import get_widget_class from netbox.config import get_config, PARAMS +from netbox.constants import DEFAULT_ACTION_PERMISSIONS from netbox.views import generic from utilities.forms import ConfirmationForm, get_field_value from utilities.htmx import is_htmx @@ -211,11 +212,7 @@ class ExportTemplateListView(generic.ObjectListView): table = tables.ExportTemplateTable template_name = 'extras/exporttemplate_list.html' actions = { - 'add': {'add'}, - 'import': {'add'}, - 'export': {'view'}, - 'bulk_edit': {'change'}, - 'bulk_delete': {'delete'}, + **DEFAULT_ACTION_PERMISSIONS, 'bulk_sync': {'sync'}, } @@ -589,11 +586,7 @@ class ConfigTemplateListView(generic.ObjectListView): table = tables.ConfigTemplateTable template_name = 'extras/configtemplate_list.html' actions = { - 'add': {'add'}, - 'import': {'add'}, - 'export': {'view'}, - 'bulk_edit': {'change'}, - 'bulk_delete': {'delete'}, + **DEFAULT_ACTION_PERMISSIONS, 'bulk_sync': {'sync'}, } diff --git a/netbox/netbox/constants.py b/netbox/netbox/constants.py index 2f4ee8e6b..faddf8c21 100644 --- a/netbox/netbox/constants.py +++ b/netbox/netbox/constants.py @@ -27,3 +27,12 @@ ADVISORY_LOCK_KEYS = { 'inventoryitem': 105700, 'inventoryitemtemplate': 105800, } + +# Default view action permission mapping +DEFAULT_ACTION_PERMISSIONS = { + 'add': {'add'}, + 'import': {'add'}, + 'export': {'view'}, + 'bulk_edit': {'change'}, + 'bulk_delete': {'delete'}, +} diff --git a/netbox/netbox/views/generic/mixins.py b/netbox/netbox/views/generic/mixins.py index b4dfadd4c..d01c534bb 100644 --- a/netbox/netbox/views/generic/mixins.py +++ b/netbox/netbox/views/generic/mixins.py @@ -1,5 +1,6 @@ import warnings +from netbox.constants import DEFAULT_ACTION_PERMISSIONS from utilities.permissions import get_permission_for_model __all__ = ( @@ -9,14 +10,15 @@ __all__ = ( class ActionsMixin: - # Map action names to the set of required permissions for each - actions = { - 'add': {'add'}, - 'import': {'add'}, - 'export': {'view'}, - 'bulk_edit': {'change'}, - 'bulk_delete': {'delete'}, - } + """ + Maps action names to the set of required permissions for each. Object list views reference this mapping to + determine whether to render the applicable button for each action: The button will be rendered only if the user + possesses the specified permission(s). + + Standard actions include: add, import, export, bulk_edit, and bulk_delete. Some views extend this default map + with custom actions, such as bulk_sync. + """ + actions = DEFAULT_ACTION_PERMISSIONS def get_permitted_actions(self, user, model=None): """ diff --git a/netbox/virtualization/views.py b/netbox/virtualization/views.py index 634389804..798d1fc4d 100644 --- a/netbox/virtualization/views.py +++ b/netbox/virtualization/views.py @@ -16,6 +16,7 @@ from dcim.tables import DeviceTable from extras.views import ObjectConfigContextView from ipam.models import IPAddress from ipam.tables import InterfaceVLANTable +from netbox.constants import DEFAULT_ACTION_PERMISSIONS from netbox.views import generic from tenancy.views import ObjectContactsView from utilities.utils import count_related @@ -360,11 +361,7 @@ class VirtualMachineInterfacesView(generic.ObjectChildrenView): filterset = filtersets.VMInterfaceFilterSet template_name = 'virtualization/virtualmachine/interfaces.html' actions = { - 'add': {'add'}, - 'import': {'add'}, - 'export': {'view'}, - 'bulk_edit': {'change'}, - 'bulk_delete': {'delete'}, + **DEFAULT_ACTION_PERMISSIONS, 'bulk_rename': {'change'}, } tab = ViewTab(