Fixes #3582: Enforce view permissions on global search results

This commit is contained in:
Jeremy Stretch 2019-10-09 16:45:33 -04:00
parent 896d58fc3f
commit 0a921d37f8
2 changed files with 32 additions and 3 deletions

View File

@ -9,6 +9,7 @@ v2.6.6 (FUTURE)
* [#3573](https://github.com/netbox-community/netbox/issues/3573) - Ensure consistent display of changelog retention period * [#3573](https://github.com/netbox-community/netbox/issues/3573) - Ensure consistent display of changelog retention period
* [#3574](https://github.com/netbox-community/netbox/issues/3574) - Change `device` to `parent` in interface editing VLAN filtering logic * [#3574](https://github.com/netbox-community/netbox/issues/3574) - Change `device` to `parent` in interface editing VLAN filtering logic
* [#3575](https://github.com/netbox-community/netbox/issues/3575) - Restore label for comments field when bulk editing circuits * [#3575](https://github.com/netbox-community/netbox/issues/3575) - Restore label for comments field when bulk editing circuits
* [#3582](https://github.com/netbox-community/netbox/issues/3582) - Enforce view permissions on global search results
## Enhancements ## Enhancements

View File

@ -40,43 +40,54 @@ SEARCH_MAX_RESULTS = 15
SEARCH_TYPES = OrderedDict(( SEARCH_TYPES = OrderedDict((
# Circuits # Circuits
('provider', { ('provider', {
'permission': 'circuits.view_provider',
'queryset': Provider.objects.all(), 'queryset': Provider.objects.all(),
'filter': ProviderFilter, 'filter': ProviderFilter,
'table': ProviderTable, 'table': ProviderTable,
'url': 'circuits:provider_list', 'url': 'circuits:provider_list',
}), }),
('circuit', { ('circuit', {
'queryset': Circuit.objects.prefetch_related('type', 'provider', 'tenant').prefetch_related('terminations__site'), 'permission': 'circuits.view_circuit',
'queryset': Circuit.objects.prefetch_related(
'type', 'provider', 'tenant'
).prefetch_related(
'terminations__site'
),
'filter': CircuitFilter, 'filter': CircuitFilter,
'table': CircuitTable, 'table': CircuitTable,
'url': 'circuits:circuit_list', 'url': 'circuits:circuit_list',
}), }),
# DCIM # DCIM
('site', { ('site', {
'permission': 'dcim.view_site',
'queryset': Site.objects.prefetch_related('region', 'tenant'), 'queryset': Site.objects.prefetch_related('region', 'tenant'),
'filter': SiteFilter, 'filter': SiteFilter,
'table': SiteTable, 'table': SiteTable,
'url': 'dcim:site_list', 'url': 'dcim:site_list',
}), }),
('rack', { ('rack', {
'permission': 'dcim.view_rack',
'queryset': Rack.objects.prefetch_related('site', 'group', 'tenant', 'role'), 'queryset': Rack.objects.prefetch_related('site', 'group', 'tenant', 'role'),
'filter': RackFilter, 'filter': RackFilter,
'table': RackTable, 'table': RackTable,
'url': 'dcim:rack_list', 'url': 'dcim:rack_list',
}), }),
('rackgroup', { ('rackgroup', {
'permission': 'dcim.view_rackgroup',
'queryset': RackGroup.objects.prefetch_related('site').annotate(rack_count=Count('racks')), 'queryset': RackGroup.objects.prefetch_related('site').annotate(rack_count=Count('racks')),
'filter': RackGroupFilter, 'filter': RackGroupFilter,
'table': RackGroupTable, 'table': RackGroupTable,
'url': 'dcim:rackgroup_list', 'url': 'dcim:rackgroup_list',
}), }),
('devicetype', { ('devicetype', {
'permission': 'dcim.view_devicetype',
'queryset': DeviceType.objects.prefetch_related('manufacturer').annotate(instance_count=Count('instances')), 'queryset': DeviceType.objects.prefetch_related('manufacturer').annotate(instance_count=Count('instances')),
'filter': DeviceTypeFilter, 'filter': DeviceTypeFilter,
'table': DeviceTypeTable, 'table': DeviceTypeTable,
'url': 'dcim:devicetype_list', 'url': 'dcim:devicetype_list',
}), }),
('device', { ('device', {
'permission': 'dcim.view_device',
'queryset': Device.objects.prefetch_related( 'queryset': Device.objects.prefetch_related(
'device_type__manufacturer', 'device_role', 'tenant', 'site', 'rack', 'primary_ip4', 'primary_ip6', 'device_type__manufacturer', 'device_role', 'tenant', 'site', 'rack', 'primary_ip4', 'primary_ip6',
), ),
@ -85,18 +96,21 @@ SEARCH_TYPES = OrderedDict((
'url': 'dcim:device_list', 'url': 'dcim:device_list',
}), }),
('virtualchassis', { ('virtualchassis', {
'permission': 'dcim.view_virtualchassis',
'queryset': VirtualChassis.objects.prefetch_related('master').annotate(member_count=Count('members')), 'queryset': VirtualChassis.objects.prefetch_related('master').annotate(member_count=Count('members')),
'filter': VirtualChassisFilter, 'filter': VirtualChassisFilter,
'table': VirtualChassisTable, 'table': VirtualChassisTable,
'url': 'dcim:virtualchassis_list', 'url': 'dcim:virtualchassis_list',
}), }),
('cable', { ('cable', {
'permission': 'dcim.view_cable',
'queryset': Cable.objects.all(), 'queryset': Cable.objects.all(),
'filter': CableFilter, 'filter': CableFilter,
'table': CableTable, 'table': CableTable,
'url': 'dcim:cable_list', 'url': 'dcim:cable_list',
}), }),
('powerfeed', { ('powerfeed', {
'permission': 'dcim.view_powerfeed',
'queryset': PowerFeed.objects.all(), 'queryset': PowerFeed.objects.all(),
'filter': PowerFeedFilter, 'filter': PowerFeedFilter,
'table': PowerFeedTable, 'table': PowerFeedTable,
@ -104,30 +118,35 @@ SEARCH_TYPES = OrderedDict((
}), }),
# IPAM # IPAM
('vrf', { ('vrf', {
'permission': 'ipam.view_vrf',
'queryset': VRF.objects.prefetch_related('tenant'), 'queryset': VRF.objects.prefetch_related('tenant'),
'filter': VRFFilter, 'filter': VRFFilter,
'table': VRFTable, 'table': VRFTable,
'url': 'ipam:vrf_list', 'url': 'ipam:vrf_list',
}), }),
('aggregate', { ('aggregate', {
'permission': 'ipam.view_aggregate',
'queryset': Aggregate.objects.prefetch_related('rir'), 'queryset': Aggregate.objects.prefetch_related('rir'),
'filter': AggregateFilter, 'filter': AggregateFilter,
'table': AggregateTable, 'table': AggregateTable,
'url': 'ipam:aggregate_list', 'url': 'ipam:aggregate_list',
}), }),
('prefix', { ('prefix', {
'permission': 'ipam.view_prefix',
'queryset': Prefix.objects.prefetch_related('site', 'vrf__tenant', 'tenant', 'vlan', 'role'), 'queryset': Prefix.objects.prefetch_related('site', 'vrf__tenant', 'tenant', 'vlan', 'role'),
'filter': PrefixFilter, 'filter': PrefixFilter,
'table': PrefixTable, 'table': PrefixTable,
'url': 'ipam:prefix_list', 'url': 'ipam:prefix_list',
}), }),
('ipaddress', { ('ipaddress', {
'permission': 'ipam.view_ipaddress',
'queryset': IPAddress.objects.prefetch_related('vrf__tenant', 'tenant'), 'queryset': IPAddress.objects.prefetch_related('vrf__tenant', 'tenant'),
'filter': IPAddressFilter, 'filter': IPAddressFilter,
'table': IPAddressTable, 'table': IPAddressTable,
'url': 'ipam:ipaddress_list', 'url': 'ipam:ipaddress_list',
}), }),
('vlan', { ('vlan', {
'permission': 'ipam.view_vlan',
'queryset': VLAN.objects.prefetch_related('site', 'group', 'tenant', 'role'), 'queryset': VLAN.objects.prefetch_related('site', 'group', 'tenant', 'role'),
'filter': VLANFilter, 'filter': VLANFilter,
'table': VLANTable, 'table': VLANTable,
@ -135,6 +154,7 @@ SEARCH_TYPES = OrderedDict((
}), }),
# Secrets # Secrets
('secret', { ('secret', {
'permission': 'secrets.view_secret',
'queryset': Secret.objects.prefetch_related('role', 'device'), 'queryset': Secret.objects.prefetch_related('role', 'device'),
'filter': SecretFilter, 'filter': SecretFilter,
'table': SecretTable, 'table': SecretTable,
@ -142,6 +162,7 @@ SEARCH_TYPES = OrderedDict((
}), }),
# Tenancy # Tenancy
('tenant', { ('tenant', {
'permission': 'tenancy.view_tenant',
'queryset': Tenant.objects.prefetch_related('group'), 'queryset': Tenant.objects.prefetch_related('group'),
'filter': TenantFilter, 'filter': TenantFilter,
'table': TenantTable, 'table': TenantTable,
@ -149,12 +170,14 @@ SEARCH_TYPES = OrderedDict((
}), }),
# Virtualization # Virtualization
('cluster', { ('cluster', {
'permission': 'virtualization.view_cluster',
'queryset': Cluster.objects.prefetch_related('type', 'group'), 'queryset': Cluster.objects.prefetch_related('type', 'group'),
'filter': ClusterFilter, 'filter': ClusterFilter,
'table': ClusterTable, 'table': ClusterTable,
'url': 'virtualization:cluster_list', 'url': 'virtualization:cluster_list',
}), }),
('virtualmachine', { ('virtualmachine', {
'permission': 'virtualization.view_virtualmachine',
'queryset': VirtualMachine.objects.prefetch_related( 'queryset': VirtualMachine.objects.prefetch_related(
'cluster', 'tenant', 'platform', 'primary_ip4', 'primary_ip6', 'cluster', 'tenant', 'platform', 'primary_ip4', 'primary_ip6',
), ),
@ -244,11 +267,16 @@ class SearchView(View):
if form.is_valid(): if form.is_valid():
# Searching for a single type of object # Searching for a single type of object
obj_types = []
if form.cleaned_data['obj_type']: if form.cleaned_data['obj_type']:
obj_types = [form.cleaned_data['obj_type']] obj_type = form.cleaned_data['obj_type']
if request.user.has_perm(SEARCH_TYPES[obj_type]['permission']):
obj_types.append(form.cleaned_data['obj_type'])
# Searching all object types # Searching all object types
else: else:
obj_types = SEARCH_TYPES.keys() for obj_type in SEARCH_TYPES.keys():
if request.user.has_perm(SEARCH_TYPES[obj_type]['permission']):
obj_types.append(obj_type)
for obj_type in obj_types: for obj_type in obj_types: