Skip to content

Commit 84abe37

Browse files
authored
[fix] Fixed REST API can creates device configs inadvertently #699
Fixes #699
1 parent 22590a4 commit 84abe37

File tree

2 files changed

+39
-0
lines changed

2 files changed

+39
-0
lines changed

openwisp_controller/config/api/serializers.py

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,8 @@
1010
from openwisp_users.api.mixins import FilterSerializerByOrgManaged
1111
from openwisp_utils.api.serializers import ValidatedModelSerializer
1212

13+
from .. import settings as app_settings
14+
1315
Template = load_model('config', 'Template')
1416
Vpn = load_model('config', 'Vpn')
1517
Device = load_model('config', 'Device')
@@ -149,6 +151,16 @@ def _create_config(self, device, config_data):
149151
raise serializers.ValidationError({'config': error.messages})
150152

151153
def _update_config(self, device, config_data):
154+
if (
155+
config_data.get('backend') == app_settings.DEFAULT_BACKEND
156+
and not config_data.get('templates')
157+
and not config_data.get('context')
158+
and not config_data.get('config')
159+
):
160+
# Do not create Config object if config_data only
161+
# contains the default value.
162+
# See https://github.com/openwisp/openwisp-controller/issues/699
163+
return
152164
if not device._has_config():
153165
return self._create_config(device, config_data)
154166
config_templates = self._get_config_templates(config_data)

openwisp_controller/config/tests/test_api.py

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
from django.contrib.auth.models import Permission
22
from django.test import TestCase
3+
from django.test.client import BOUNDARY, MULTIPART_CONTENT, encode_multipart
34
from django.test.testcases import TransactionTestCase
45
from django.urls import reverse
56
from openwisp_ipam.tests import CreateModelsMixin as CreateIpamModelsMixin
@@ -10,6 +11,7 @@
1011
from openwisp_users.tests.utils import TestOrganizationMixin
1112
from openwisp_utils.tests import capture_any_output, catch_signal
1213

14+
from .. import settings as app_settings
1315
from ..signals import group_templates_changed
1416
from .utils import (
1517
CreateConfigTemplateMixin,
@@ -354,6 +356,31 @@ def test_device_put_api(self):
354356
self.assertEqual(d1.organization, org)
355357
self.assertEqual(d1.config.backend, 'netjsonconfig.OpenWisp')
356358

359+
def test_device_put_api_with_default_config_values(self):
360+
device = self._create_device(name='test-device')
361+
path = reverse('config_api:device_detail', args=[device.pk])
362+
org = self._get_org()
363+
data = {
364+
'name': 'change-test-device',
365+
'organization': org.pk,
366+
'mac_address': device.mac_address,
367+
'config.backend': app_settings.DEFAULT_BACKEND,
368+
'config.templates': [],
369+
'config.context': 'null',
370+
'config.config': 'null',
371+
}
372+
self.assertEqual(Config.objects.count(), 0)
373+
response = self.client.put(
374+
path, encode_multipart(BOUNDARY, data), content_type=MULTIPART_CONTENT
375+
)
376+
self.assertEqual(response.status_code, 200)
377+
self.assertEqual(response.data['name'], 'change-test-device')
378+
self.assertEqual(response.data['organization'], org.pk)
379+
device.refresh_from_db()
380+
self.assertEqual(device.name, 'change-test-device')
381+
self.assertEqual(device.organization, org)
382+
self.assertEqual(Config.objects.count(), 0)
383+
357384
def test_device_api_change_config_backend(self):
358385
t1 = self._create_template(name='t1', backend='netjsonconfig.OpenWrt')
359386
t2 = self._create_template(name='t2', backend='netjsonconfig.OpenWisp')

0 commit comments

Comments
 (0)