|
13 | 13 | from ipam.models import ASN, RIR, VLAN, VRF |
14 | 14 | from netbox.api.serializers import GenericObjectSerializer |
15 | 15 | from tenancy.models import Tenant |
16 | | -from users.models import User |
| 16 | +from users.constants import TOKEN_PREFIX |
| 17 | +from users.models import Token, User |
17 | 18 | from utilities.testing import APITestCase, APIViewTestCases, create_test_device, disable_logging |
18 | 19 | from virtualization.models import Cluster, ClusterType |
19 | 20 | from wireless.choices import WirelessChannelChoices |
@@ -1306,7 +1307,6 @@ class DeviceTest(APIViewTestCases.APIViewTestCase): |
1306 | 1307 | } |
1307 | 1308 | user_permissions = ( |
1308 | 1309 | 'dcim.view_site', 'dcim.view_rack', 'dcim.view_location', 'dcim.view_devicerole', 'dcim.view_devicetype', |
1309 | | - 'extras.view_configtemplate', |
1310 | 1310 | ) |
1311 | 1311 |
|
1312 | 1312 | @classmethod |
@@ -1486,12 +1486,58 @@ def test_render_config(self): |
1486 | 1486 | device.config_template = configtemplate |
1487 | 1487 | device.save() |
1488 | 1488 |
|
1489 | | - self.add_permissions('dcim.add_device') |
1490 | | - url = reverse('dcim-api:device-detail', kwargs={'pk': device.pk}) + 'render-config/' |
| 1489 | + self.add_permissions('dcim.render_config_device', 'dcim.view_device') |
| 1490 | + url = reverse('dcim-api:device-render-config', kwargs={'pk': device.pk}) |
1491 | 1491 | response = self.client.post(url, {}, format='json', **self.header) |
1492 | 1492 | self.assertHttpStatus(response, status.HTTP_200_OK) |
1493 | 1493 | self.assertEqual(response.data['content'], f'Config for device {device.name}') |
1494 | 1494 |
|
| 1495 | + def test_render_config_without_permission(self): |
| 1496 | + configtemplate = ConfigTemplate.objects.create( |
| 1497 | + name='Config Template 1', |
| 1498 | + template_code='Config for device {{ device.name }}' |
| 1499 | + ) |
| 1500 | + |
| 1501 | + device = Device.objects.first() |
| 1502 | + device.config_template = configtemplate |
| 1503 | + device.save() |
| 1504 | + |
| 1505 | + # No permissions added - user has no render_config permission |
| 1506 | + url = reverse('dcim-api:device-render-config', kwargs={'pk': device.pk}) |
| 1507 | + response = self.client.post(url, {}, format='json', **self.header) |
| 1508 | + self.assertHttpStatus(response, status.HTTP_404_NOT_FOUND) |
| 1509 | + |
| 1510 | + def test_render_config_token_write_enabled(self): |
| 1511 | + configtemplate = ConfigTemplate.objects.create( |
| 1512 | + name='Config Template 1', |
| 1513 | + template_code='Config for device {{ device.name }}' |
| 1514 | + ) |
| 1515 | + |
| 1516 | + device = Device.objects.first() |
| 1517 | + device.config_template = configtemplate |
| 1518 | + device.save() |
| 1519 | + |
| 1520 | + self.add_permissions('dcim.render_config_device', 'dcim.view_device') |
| 1521 | + url = reverse('dcim-api:device-render-config', kwargs={'pk': device.pk}) |
| 1522 | + |
| 1523 | + # Request without token auth should fail with PermissionDenied |
| 1524 | + response = self.client.post(url, {}, format='json') |
| 1525 | + self.assertHttpStatus(response, status.HTTP_403_FORBIDDEN) |
| 1526 | + |
| 1527 | + # Create token with write_enabled=False |
| 1528 | + token = Token.objects.create(version=2, user=self.user, write_enabled=False) |
| 1529 | + token_header = f'Bearer {TOKEN_PREFIX}{token.key}.{token.token}' |
| 1530 | + |
| 1531 | + # Request with write-disabled token should fail |
| 1532 | + response = self.client.post(url, {}, format='json', HTTP_AUTHORIZATION=token_header) |
| 1533 | + self.assertHttpStatus(response, status.HTTP_403_FORBIDDEN) |
| 1534 | + |
| 1535 | + # Enable write and retry |
| 1536 | + token.write_enabled = True |
| 1537 | + token.save() |
| 1538 | + response = self.client.post(url, {}, format='json', HTTP_AUTHORIZATION=token_header) |
| 1539 | + self.assertHttpStatus(response, status.HTTP_200_OK) |
| 1540 | + |
1495 | 1541 |
|
1496 | 1542 | class ModuleTest(APIViewTestCases.APIViewTestCase): |
1497 | 1543 | model = Module |
|
0 commit comments