Add validation of special chars on system values

Setting a system value with special characters will get sysinv in a
dirty state and unreachable. E.g.: `system modify -n='º'`. This is
caused because isystem DB won't accept these special chars.

This work adds a validation on the PATCH method of the SystemController
blocking any special character that is not accepted.

Test Plan:

PASS: Verify special characters won't be accepted on system values
PASS: Verify system installation/bootstrap executes properly
PASS: Verify the system works properly after setting a value with any of
the accepted characters: 'a-zA-Z0-9!@#$%^&*()_+-=[]{};:'"|,.<>/? '
PASS: Verify system https_enabled can be properly toggled

Closes-Bug: 1952008
Signed-off-by: Rafael Camargos <RafaelLucas.Camargos@windriver.com>
Change-Id: I1844e6af40c7b82f2c5a6e995947b1c166f82e0d
This commit is contained in:
Rafael Camargos 2021-11-23 21:18:31 -03:00
parent ced5ccd805
commit f096dcf159
2 changed files with 46 additions and 16 deletions

View File

@ -23,6 +23,7 @@ import jsonpatch
import os
import pecan
from pecan import rest
import re
import six
import wsme
from wsme import types as wtypes
@ -407,9 +408,14 @@ class SystemController(rest.RestController):
change_dc_role = False
vswitch_type = None
new_system_mode = None
ALLOWED_CHARS = r"^[a-zA-Z0-9!@#$%^&*()_+\-=\[\]{};:\'\"|,.<>\/? ]*$"
# prevent description field from being updated
for p in jsonpatch.JsonPatch(patch):
if p['value'] is not None and not re.match(ALLOWED_CHARS, p['value']):
raise wsme.exc.ClientSideError(_("System values must not "
"contain special characters."))
if p['path'] == '/software_version':
raise wsme.exc.ClientSideError(_("software_version field "
"cannot be modified."))

View File

@ -1,3 +1,4 @@
# -*- coding: utf-8 -*-
#
# Copyright (c) 2021 Wind River Systems, Inc.
#
@ -52,35 +53,58 @@ class TestSystemUpdate(TestSystem):
super(TestSystemUpdate, self).setUp()
self.system = dbutils.create_test_isystem()
def test_update_valid_system_values_0(self):
update = {
"name": "StarlingX #0",
"timezone": "UCT",
"description": "System Description",
"contact": "John Doe",
"location": "Earth",
"latitude": "00.11223344556677 N",
"longitude": "-00.11223344556677 W",
"security_feature": "spectre_meltdown_v1",
}
self._patch_and_check(self._get_path(self.system.uuid),
update)
def test_update_valid_system_values_1(self):
update = {
"name": "StarlingX #1",
"timezone": "CET",
"description": "[System Description!]",
"contact": "Mr. John Doe",
"location": "Mars",
"latitude": None,
"longitude": None,
"security_feature": "spectre_meltdown_all",
}
self._patch_and_check(self._get_path(self.system.uuid),
update)
def test_update_name_invalid_chars(self):
update = {"name": "Nõt à vªlid nâmë"}
self._patch_and_check(self._get_path(self.system.uuid),
update, expect_errors=True)
def test_update_latitude_longer_than_30_chars(self):
update = {"latitude": "00.0000000111111111122222222223"}
self._patch_and_check(self._get_path(self.system.uuid),
update, expect_errors=True)
def test_update_latitude_valid_length(self):
update = {"latitude": "00.11223344556677"}
def test_update_latitude_invalid_chars(self):
update = {"latitude": u"99.99999° N"}
self._patch_and_check(self._get_path(self.system.uuid),
update)
def test_update_latitude_null_value(self):
update = {"latitude": None}
self._patch_and_check(self._get_path(self.system.uuid),
update)
update, expect_errors=True)
def test_update_longitude_longer_than_30_chars(self):
update = {"longitude": "00.0000000111111111122222222223"}
self._patch_and_check(self._get_path(self.system.uuid),
update, expect_errors=True)
def test_update_longitude_valid_length(self):
update = {"longitude": "-00.11223344556677"}
def test_update_longitude_invalid_chars(self):
update = {"longitude": u"99.99999° W"}
self._patch_and_check(self._get_path(self.system.uuid),
update)
def test_update_longitude_null_value(self):
update = {"longitude": None}
self._patch_and_check(self._get_path(self.system.uuid),
update)
update, expect_errors=True)
class TestSystemUpdateModeFromSimplex(TestSystem):