1
0
mirror of https://github.com/netbox-community/netbox.git synced 2024-05-10 07:54:54 +00:00

Closes #12325: Disable the Django admin UI by default (#15008)

* Disable the Django admin UI by default

* Remove outdated references to the admin UI

* Update tests
This commit is contained in:
Jeremy Stretch
2024-02-05 11:44:52 -05:00
committed by GitHub
parent 93b77cb4f0
commit 5d9311eecf
19 changed files with 67 additions and 34 deletions

View File

@ -73,7 +73,7 @@ You should be redirected to Microsoft's authentication portal. Enter the usernam
If successful, you will be redirected back to the NetBox UI, and will be logged in as the AD user. You can verify this by navigating to your profile (using the button at top right).
This user account has been replicated locally to NetBox, and can now be assigned groups and permissions within the NetBox admin UI.
This user account has been replicated locally to NetBox, and can now be assigned groups and permissions within NetBox.
## Troubleshooting

View File

@ -67,4 +67,4 @@ You should be redirected to Okta's authentication portal. Enter the username/ema
If successful, you will be redirected back to the NetBox UI, and will be logged in as the Okta user. You can verify this by navigating to your profile (using the button at top right).
This user account has been replicated locally to NetBox, and can now be assigned groups and permissions within the NetBox admin UI.
This user account has been replicated locally to NetBox, and can now be assigned groups and permissions within NetBox.

View File

@ -4,7 +4,7 @@
Local user accounts and groups can be created in NetBox under the "Authentication and Authorization" section of the administrative user interface. This interface is available only to users with the "staff" permission enabled.
At a minimum, each user account must have a username and password set. User accounts may also denote a first name, last name, and email address. [Permissions](../permissions.md) may also be assigned to users and/or groups within the admin UI.
At a minimum, each user account must have a username and password set. User accounts may also denote a first name, last name, and email address. [Permissions](../permissions.md) may also be assigned to individual users and/or groups as needed.
## Remote Authentication

View File

@ -46,4 +46,4 @@ The configuration file may be modified at any time. However, the WSGI service (e
$ sudo systemctl restart netbox
```
Configuration parameters which are set via the admin UI (those listed under "dynamic settings") take effect immediately.
Configuration parameters which are set via the user interface (those listed under "dynamic settings") take effect immediately.

View File

@ -99,6 +99,14 @@ The maximum size (in bytes) of an incoming HTTP request (i.e. `GET` or `POST` da
---
## DJANGO_ADMIN_ENABLED
Default: False
Setting this to True installs the `django.contrib.admin` app and enables the [Django admin UI](https://docs.djangoproject.com/en/5.0/ref/contrib/admin/). This may be necessary to support older plugins which do not integrate with the native NetBox interface.
---
## ENFORCE_GLOBAL_UNIQUE
!!! tip "Dynamic Configuration Parameter"

View File

@ -288,7 +288,7 @@ An IPv4 or IPv6 network with a mask. Returns a `netaddr.IPNetwork` object. Two a
## Running Custom Scripts
!!! note
To run a custom script, a user must be assigned via permissions for `Extras > Script`, `Extras > ScriptModule`, and `Core > ManagedFile` objects. They must also be assigned the `extras.run_script` permission. This is achieved by assigning the user (or group) a permission on the Script object and specifying the `run` action in the admin UI as shown below.
To run a custom script, a user must be assigned via permissions for `Extras > Script`, `Extras > ScriptModule`, and `Core > ManagedFile` objects. They must also be assigned the `extras.run_script` permission. This is achieved by assigning the user (or group) a permission on the Script object and specifying the `run` action as shown below.
![Adding the run action to a permission](../media/admin_ui_run_permission.png)

View File

@ -132,7 +132,7 @@ Once you have created a report, it will appear in the reports list. Initially, r
## Running Reports
!!! note
To run a report, a user must be assigned via permissions for `Extras > Report`, `Extras > ReportModule`, and `Core > ManagedFile` objects. They must also be assigned the `extras.run_report` permission. This is achieved by assigning the user (or group) a permission on the Report object and specifying the `run` action in the admin UI as shown below.
To run a report, a user must be assigned via permissions for `Extras > Report`, `Extras > ReportModule`, and `Core > ManagedFile` objects. They must also be assigned the `extras.run_report` permission. This is achieved by assigning the user (or group) a permission on the Report object and specifying the `run` action as shown below.
![Adding the run action to a permission](../media/admin_ui_run_permission.png)

View File

@ -28,4 +28,4 @@ For more detail, see the reference documentation for NetBox's [conditional logic
## Event Rule Processing
When a change is detected, any resulting events are placed into a Redis queue for processing. This allows the user's request to complete without needing to wait for the outgoing event(s) to be processed. The events are then extracted from the queue by the `rqworker` process. The current event queue and any failed events can be inspected in the admin UI under System > Background Tasks.
When a change is detected, any resulting events are placed into a Redis queue for processing. This allows the user's request to complete without needing to wait for the outgoing event(s) to be processed. The events are then extracted from the queue by the `rqworker` process. The current event queue and any failed events can be inspected under System > Background Tasks.

View File

@ -73,9 +73,9 @@ If no body template is specified, the request body will be populated with a JSON
## Webhook Processing
Using [Event Rules](../features/event-rules.md), when a change is detected, any resulting webhooks are placed into a Redis queue for processing. This allows the user's request to complete without needing to wait for the outgoing webhook(s) to be processed. The webhooks are then extracted from the queue by the `rqworker` process and HTTP requests are sent to their respective destinations. The current webhook queue and any failed webhooks can be inspected in the admin UI under System > Background Tasks.
Using [Event Rules](../features/event-rules.md), when a change is detected, any resulting webhooks are placed into a Redis queue for processing. This allows the user's request to complete without needing to wait for the outgoing webhook(s) to be processed. The webhooks are then extracted from the queue by the `rqworker` process and HTTP requests are sent to their respective destinations. The current webhook queue and any failed webhooks can be inspected under System > Background Tasks.
A request is considered successful if the response has a 2XX status code; otherwise, the request is marked as having failed. Failed requests may be retried manually via the admin UI.
A request is considered successful if the response has a 2XX status code; otherwise, the request is marked as having failed. Failed requests may be requeued manually under System > Background Tasks.
## Troubleshooting
@ -108,4 +108,4 @@ Content-Type: application/x-www-form-urlencoded
Note that `webhook_receiver` does not actually _do_ anything with the information received: It merely prints the request headers and body for inspection.
Now, when the NetBox webhook is triggered and processed, you should see its headers and content appear in the terminal where the webhook receiver is listening. If you don't, check that the `rqworker` process is running and that webhook events are being placed into the queue (visible under the NetBox admin UI).
Now, when the NetBox webhook is triggered and processed, you should see its headers and content appear in the terminal where the webhook receiver is listening. If you don't, check that the `rqworker` process is running and that webhook events are being placed into the queue.

View File

@ -39,6 +39,8 @@ REDIS = {
SECRET_KEY = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789'
DJANGO_ADMIN_ENABLED = True
DEFAULT_PERMISSIONS = {}
LOGGING = {

View File

@ -115,6 +115,7 @@ DEFAULT_PERMISSIONS = getattr(configuration, 'DEFAULT_PERMISSIONS', {
'users.delete_token': ({'user': '$user'},),
})
DEVELOPER = getattr(configuration, 'DEVELOPER', False)
DJANGO_ADMIN_ENABLED = getattr(configuration, 'DJANGO_ADMIN_ENABLED', False)
DOCS_ROOT = getattr(configuration, 'DOCS_ROOT', os.path.join(os.path.dirname(BASE_DIR), 'docs'))
EMAIL = getattr(configuration, 'EMAIL', {})
EVENTS_PIPELINE = getattr(configuration, 'EVENTS_PIPELINE', (
@ -355,7 +356,6 @@ SERVER_EMAIL = EMAIL.get('FROM_EMAIL')
#
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
@ -393,6 +393,9 @@ INSTALLED_APPS = [
'drf_spectacular_sidecar',
]
if DJANGO_ADMIN_ENABLED:
INSTALLED_APPS.insert(0, 'django.contrib.admin')
# Middleware
MIDDLEWARE = [
'graphiql_debug_toolbar.middleware.DebugToolbarMiddleware',

View File

@ -4,23 +4,23 @@ from netbox.plugins.navigation import PluginMenu, PluginMenuButton, PluginMenuIt
items = (
PluginMenuItem(
link='plugins:dummy_plugin:dummy_models',
link='plugins:dummy_plugin:dummy_model_list',
link_text='Item 1',
buttons=(
PluginMenuButton(
link='admin:dummy_plugin_dummymodel_add',
title='Add a new dummy model',
link='plugins:dummy_plugin:dummy_model_add',
title='Button 1',
icon_class='mdi mdi-plus-thick',
),
PluginMenuButton(
link='admin:dummy_plugin_dummymodel_add',
title='Add a new dummy model',
link='plugins:dummy_plugin:dummy_model_add',
title='Button 2',
icon_class='mdi mdi-plus-thick',
),
)
),
PluginMenuItem(
link='plugins:dummy_plugin:dummy_models',
link='plugins:dummy_plugin:dummy_model_list',
link_text='Item 2',
),
)

View File

@ -4,5 +4,6 @@ from . import views
urlpatterns = (
path('models/', views.DummyModelsView.as_view(), name='dummy_models'),
path('models/', views.DummyModelsView.as_view(), name='dummy_model_list'),
path('models/add/', views.DummyModelAddView.as_view(), name='dummy_model_add'),
)

View File

@ -1,3 +1,6 @@
import random
import string
from django.http import HttpResponse
from django.views.generic import View
@ -15,6 +18,20 @@ class DummyModelsView(View):
return HttpResponse(f"Instances: {instance_count}")
class DummyModelAddView(View):
def get(self, request):
return HttpResponse(f"Create an instance")
def post(self, request):
instance = DummyModel(
name=''.join(random.choices(string.ascii_lowercase, k=8)),
number=random.randint(1, 100000)
)
instance.save()
return HttpResponse(f"Instance created")
@register_model_view(Site, 'extra', path='other-stuff')
class ExtraCoreModelView(View):

View File

@ -41,7 +41,7 @@ class PluginTest(TestCase):
def test_views(self):
# Test URL resolution
url = reverse('plugins:dummy_plugin:dummy_models')
url = reverse('plugins:dummy_plugin:dummy_model_list')
self.assertEqual(url, '/plugins/dummy-plugin/models/')
# Test GET request

View File

@ -11,7 +11,6 @@ from netbox.graphql.schema import schema
from netbox.graphql.views import GraphQLView
from netbox.plugins.urls import plugin_patterns, plugin_api_patterns
from netbox.views import HomeView, StaticMediaFailureView, SearchView, htmx
from .admin import admin_site
_patterns = [
@ -70,26 +69,25 @@ _patterns = [
# Plugins
path('plugins/', include((plugin_patterns, 'plugins'))),
path('api/plugins/', include((plugin_api_patterns, 'plugins-api'))),
# Admin
path('admin/', admin_site.urls),
]
# Django admin UI
if settings.DJANGO_ADMIN_ENABLED:
from .admin import admin_site
_patterns.append(path('admin/', admin_site.urls))
# django-debug-toolbar
if settings.DEBUG:
import debug_toolbar
_patterns += [
path('__debug__/', include(debug_toolbar.urls)),
]
_patterns.append(path('__debug__/', include(debug_toolbar.urls)))
# Prometheus metrics
if settings.METRICS_ENABLED:
_patterns += [
path('', include('django_prometheus.urls')),
]
_patterns.append(path('', include('django_prometheus.urls')))
# Prepend BASE_PATH
urlpatterns = [
path('{}'.format(settings.BASE_PATH), include(_patterns))
path(settings.BASE_PATH, include(_patterns))
]
handler404 = 'netbox.views.errors.handler_404'

View File

@ -38,7 +38,7 @@
<td>{% checkmark request.user.is_superuser %}</td>
</tr>
<tr>
<th scope="row">{% trans "Admin Access" %}</th>
<th scope="row">{% trans "Staff" %}</th>
<td>{% checkmark request.user.is_staff %}</td>
</tr>
</table>

View File

@ -45,7 +45,11 @@
<td>{{ param }}</td>
<td>{{ current }}</td>
<td>{{ new }}</td>
<td>{% if current != new %}<img src="{% static 'admin/img/icon-changelink.svg' %}" alt="*" title="{% trans "Changed" %}">{% endif %}</td>
<td>
{% if current != new %}
<i class="mdi mdi-pencil text-warning" title="{% trans "Changed" %}"></i>
{% endif %}
</td>
</tr>
{% endfor %}
</tbody>

View File

@ -9,9 +9,9 @@
</div>
</a>
<div class="dropdown-menu dropdown-menu-end dropdown-menu-arrow">
{% if request.user.is_staff %}
{% if config.DJANGO_ADMIN_ENABLED and request.user.is_staff %}
<a class="dropdown-item" href="{% url 'admin:index' %}">
<i class="mdi mdi-cog"></i> {% trans "Admin" %}
<i class="mdi mdi-cog"></i> {% trans "Django Admin" %}
</a>
{% endif %}
<a href="{% url 'account:profile' %}" class="dropdown-item">