From 0887bc00a775ce8096c7f7830fb2d9ba92d1ab6c Mon Sep 17 00:00:00 2001
From: Benjamin Bertrand <benjamin.bertrand@esss.se>
Date: Tue, 26 Nov 2019 15:55:59 +0100
Subject: [PATCH] Fix regexp for ICS id validation

Validation worked in the models because fullmatch is used but in the
Regexp validators from wtforms, only match is called.

The form validator didn't catch "AAA1100".
Test added for this.

JIRA INFRA-1569 #action In Progress
---
 app/inventory/forms.py          |  5 ++++-
 app/validators.py               |  2 +-
 tests/functional/test_models.py |  7 +++++++
 tests/functional/test_web.py    | 14 ++++++++++++++
 4 files changed, 26 insertions(+), 2 deletions(-)

diff --git a/app/inventory/forms.py b/app/inventory/forms.py
index f146e45..be25524 100644
--- a/app/inventory/forms.py
+++ b/app/inventory/forms.py
@@ -31,7 +31,10 @@ class ItemForm(CSEntryForm):
         "ICS id",
         validators=[
             validators.InputRequired(),
-            validators.Regexp(ICS_ID_RE),
+            validators.Regexp(
+                ICS_ID_RE,
+                message="The ICS id shall be composed of 3 letters and 3 digits.",
+            ),
             Unique(models.Item, "ics_id"),
         ],
     )
diff --git a/app/validators.py b/app/validators.py
index 642da1d..afdba7f 100644
--- a/app/validators.py
+++ b/app/validators.py
@@ -14,7 +14,7 @@ import re
 import sqlalchemy as sa
 from wtforms import ValidationError, SelectField
 
-ICS_ID_RE = re.compile(r"[A-Z]{3}[0-9]{3}")
+ICS_ID_RE = re.compile(r"^[A-Z]{3}[0-9]{3}$")
 HOST_NAME_RE = re.compile(r"^[a-z0-9\-]{2,20}$")
 INTERFACE_NAME_RE = re.compile(r"^[a-z0-9\-]{2,25}$")
 VLAN_NAME_RE = re.compile(r"^[A-Za-z0-9\-]{3,25}$")
diff --git a/tests/functional/test_models.py b/tests/functional/test_models.py
index c501486..377a1dc 100644
--- a/tests/functional/test_models.py
+++ b/tests/functional/test_models.py
@@ -799,3 +799,10 @@ def test_interface_name_length(db, host_factory, interface_factory):
     with pytest.raises(ValidationError) as excinfo:
         interface_factory(name=interface_name + "y", host=host1)
     assert r"Interface name shall match [a-z0-9\-]{2,25}" in str(excinfo.value)
+
+
+@pytest.mark.parametrize("ics_id", ("123", "AA123", "AAA1234"))
+def test_item_invalid_ics_id(db, item_factory, ics_id):
+    with pytest.raises(ValidationError) as excinfo:
+        item_factory(ics_id=ics_id)
+    assert r"ICS id shall match [A-Z]{3}[0-9]{3}" in str(excinfo.value)
diff --git a/tests/functional/test_web.py b/tests/functional/test_web.py
index 53c1c55..c4bdda2 100644
--- a/tests/functional/test_web.py
+++ b/tests/functional/test_web.py
@@ -652,3 +652,17 @@ def test_create_network_no_vlan(
     assert network.vlan_name == vlan_name
     assert network.address == form["address"]
     assert network.vlan_id is None
+
+
+def test_create_item_invalid_ics_id(logged_rw_client):
+    ics_id = "AAA1100"
+    form = {
+        "ics_id": ics_id,
+        "serial_number": "12345",
+    }
+    response = logged_rw_client.post(
+        f"/inventory/items/create", data=form, follow_redirects=True
+    )
+    assert response.status_code == 200
+    assert b"Register new item" in response.data
+    assert b"The ICS id shall be composed of 3 letters and 3 digits" in response.data
-- 
GitLab