mirror of
https://github.com/netbox-community/netbox.git
synced 2026-04-01 07:03:22 +02:00
* Closes #16681: Introduce render_config permission for configuration rendering Add a new custom permission action `render_config` for rendering device and virtual machine configurations via the REST API. This allows users to render configurations without requiring the `add` permission. Changes: - Add permission check to RenderConfigMixin.render_config() for devices and VMs - Update API tests to use render_config permission instead of add - Add tests verifying permission enforcement (403 without render_config) - Document new permission requirement in configuration-rendering.md Note: Currently requires both render_config AND add permissions due to the automatic POST='add' filter in BaseViewSet.initial(). Removing the add requirement will be addressed in a follow-up commit. * Correct permission denied message and enable translation * Remove add permission requirement for render_config endpoint Remove the add permission requirement from the render-config API endpoint while maintaining token write_enabled enforcement as specified in #16681. Changes: - Add TokenWritePermission class to check token write ability without requiring specific model permissions - Override get_permissions() in RenderConfigMixin to use TokenWritePermission instead of TokenPermissions for render_config action - Replace queryset restriction: use render_config instead of add - Remove add permissions from tests - render_config permission now sufficient - Update tests to expect 404 when permission denied (NetBox standard pattern) Per #16681: 'requirement for write permission makes sense for API calls (because we're accepting and processing arbitrary user data), the specific permission for creating devices does not' * Add render_config permission to ConfigTemplate render endpoint Extend render_config permission requirement to the ConfigTemplate render endpoint per issue comments. Changes: - Add TokenWritePermission check via get_permissions() override in ConfigTemplateViewSet - Restrict queryset to render_config permission in render() method - Add explicit render_config permission check - Add tests for ConfigTemplate.render() with and without permission - Update documentation to include ConfigTemplate endpoint * Address PR feedback on render_config permissions Remove redundant permission checks, add view permission enforcement via chained restrict() calls, and rename ConfigTemplate permission action from render_config to render for consistency. * Address second round of PR feedback on render_config permissions - Remove ConfigTemplate view permission check from render_config endpoint - Add sanity check to TokenWritePermission for non-token auth - Use named URL patterns instead of string concatenation in tests - Remove extras.view_configtemplate from test permissions - Add token write_enabled enforcement tests for all render endpoints * Misc cleanup --------- Co-authored-by: Jeremy Stretch <jstretch@netboxlabs.com>
This commit is contained in:
@@ -3,6 +3,7 @@ import datetime
|
||||
from django.contrib.contenttypes.models import ContentType
|
||||
from django.urls import reverse
|
||||
from django.utils.timezone import make_aware, now
|
||||
from rest_framework import status
|
||||
|
||||
from core.choices import ManagedFileRootPathChoices
|
||||
from core.events import *
|
||||
@@ -11,7 +12,8 @@ from dcim.models import Device, DeviceRole, DeviceType, Manufacturer, Rack, Loca
|
||||
from extras.choices import *
|
||||
from extras.models import *
|
||||
from extras.scripts import BooleanVar, IntegerVar, Script as PythonClass, StringVar
|
||||
from users.models import Group, User
|
||||
from users.constants import TOKEN_PREFIX
|
||||
from users.models import Group, Token, User
|
||||
from utilities.testing import APITestCase, APIViewTestCases
|
||||
|
||||
|
||||
@@ -854,6 +856,47 @@ class ConfigTemplateTest(APIViewTestCases.APIViewTestCase):
|
||||
)
|
||||
ConfigTemplate.objects.bulk_create(config_templates)
|
||||
|
||||
def test_render(self):
|
||||
configtemplate = ConfigTemplate.objects.first()
|
||||
|
||||
self.add_permissions('extras.render_configtemplate', 'extras.view_configtemplate')
|
||||
url = reverse('extras-api:configtemplate-render', kwargs={'pk': configtemplate.pk})
|
||||
response = self.client.post(url, {'foo': 'bar'}, format='json', **self.header)
|
||||
self.assertHttpStatus(response, status.HTTP_200_OK)
|
||||
self.assertEqual(response.data['content'], 'Foo: bar')
|
||||
|
||||
def test_render_without_permission(self):
|
||||
configtemplate = ConfigTemplate.objects.first()
|
||||
|
||||
# No permissions added - user has no render permission
|
||||
url = reverse('extras-api:configtemplate-render', kwargs={'pk': configtemplate.pk})
|
||||
response = self.client.post(url, {'foo': 'bar'}, format='json', **self.header)
|
||||
self.assertHttpStatus(response, status.HTTP_404_NOT_FOUND)
|
||||
|
||||
def test_render_token_write_enabled(self):
|
||||
configtemplate = ConfigTemplate.objects.first()
|
||||
|
||||
self.add_permissions('extras.render_configtemplate', 'extras.view_configtemplate')
|
||||
url = reverse('extras-api:configtemplate-render', kwargs={'pk': configtemplate.pk})
|
||||
|
||||
# Request without token auth should fail with PermissionDenied
|
||||
response = self.client.post(url, {'foo': 'bar'}, format='json')
|
||||
self.assertHttpStatus(response, status.HTTP_403_FORBIDDEN)
|
||||
|
||||
# Create token with write_enabled=False
|
||||
token = Token.objects.create(version=2, user=self.user, write_enabled=False)
|
||||
token_header = f'Bearer {TOKEN_PREFIX}{token.key}.{token.token}'
|
||||
|
||||
# Request with write-disabled token should fail
|
||||
response = self.client.post(url, {'foo': 'bar'}, format='json', HTTP_AUTHORIZATION=token_header)
|
||||
self.assertHttpStatus(response, status.HTTP_403_FORBIDDEN)
|
||||
|
||||
# Enable write and retry
|
||||
token.write_enabled = True
|
||||
token.save()
|
||||
response = self.client.post(url, {'foo': 'bar'}, format='json', HTTP_AUTHORIZATION=token_header)
|
||||
self.assertHttpStatus(response, status.HTTP_200_OK)
|
||||
|
||||
|
||||
class ScriptTest(APITestCase):
|
||||
|
||||
|
||||
Reference in New Issue
Block a user