Skip to content

Commit f50c232

Browse files
authored
Merge pull request #4793 from telefonicaid/feature/4792-textunrestricted-metadata
Add TextUnrestricted metadata support (#4792)
2 parents 3ccf9d7 + 827b383 commit f50c232

6 files changed

Lines changed: 468 additions & 2 deletions

File tree

CHANGES_NEXT_RELEASE

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
- Add: avoid forbidden character checks in attribute values using TextUnrestricted metadata (#4792)

doc/manuals/orion-api.md

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -455,6 +455,7 @@ There are some exception cases in which the above restrictions do not apply. In
455455
* HTTP and Kafka custom header values allow the `'` and `"` quote characters to support quoted string literals in JEXL expressions
456456
* Within `ngsi` (i.e. `id`, `type` and attribute values) in [NGSI Payload patching](#ngsi-payload-patching) (to support characters used in the [JEXL support in custom notifications](#jexl-support-in-custom-notifications))
457457
* Whichever attribute value which uses `TextUnrestricted` as attribute type (see [Special Attribute Types](#special-attribute-types) section)
458+
* Whichever attribute value which has a boolean metadata named `TextUnrestricted` with value `true` (see [Special Metadata Types](#special-metadata-types) section)
458459

459460
## Identifiers syntax restrictions
460461

@@ -762,6 +763,23 @@ type has an special semantic for Orion:
762763

763764
* `evalPriority`: used by expression evaluation. Have a look to [this specific section](#evaluation-priority) for details.
764765

766+
* `TextUnrestricted`: when a boolean metadata named `TextUnrestricted` with value `true` is added to an attribute, Orion will skip [syntax restrictions](#general-syntax-restrictions) checkings on the attribute value. This leaves the attribute type free for other custom types. For instance:
767+
768+
```json
769+
{
770+
"funnyAttr": {
771+
"type": "FunnyType",
772+
"value": "Value with <forbidden> characters (like = or ;)",
773+
"metadata": {
774+
"TextUnrestricted": {
775+
"value": true,
776+
"type": "Boolean"
777+
}
778+
}
779+
}
780+
}
781+
```
782+
765783
At the present moment `ignoreType` is supported only for geo-location types, this way allowing a
766784
mechanism to overcome the limit of only one geo-location per entity (more details
767785
in [Geospatial properties of entities](#geospatial-properties-of-entities) section). Support

src/lib/ngsi/ContextAttribute.cpp

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1134,14 +1134,20 @@ std::string ContextAttribute::check(bool asValue, bool relaxForbiddenCheck)
11341134
return "Invalid characters in attribute type";
11351135
}
11361136

1137-
if ((!relaxForbiddenCheck) && (compoundValueP != NULL) && (compoundValueP->childV.size() != 0) && (type != TEXT_UNRESTRICTED_TYPE))
1137+
Metadata* textUnrestrictedMdP = metadataVector.lookupByName(TEXT_UNRESTRICTED_TYPE);
1138+
bool isUnrestricted = (type == TEXT_UNRESTRICTED_TYPE) ||
1139+
(textUnrestrictedMdP != NULL &&
1140+
textUnrestrictedMdP->valueType == orion::ValueTypeBoolean &&
1141+
textUnrestrictedMdP->boolValue == true);
1142+
1143+
if ((!relaxForbiddenCheck) && (compoundValueP != NULL) && (compoundValueP->childV.size() != 0) && (!isUnrestricted))
11381144
{
11391145
return compoundValueP->check("");
11401146
}
11411147

11421148
if (valueType == orion::ValueTypeString)
11431149
{
1144-
if ((!relaxForbiddenCheck) && (type != TEXT_UNRESTRICTED_TYPE) && (forbiddenChars(stringValue.c_str())))
1150+
if ((!relaxForbiddenCheck) && (!isUnrestricted) && (forbiddenChars(stringValue.c_str())))
11451151
{
11461152
alarmMgr.badInput(clientIp, "found a forbidden character in the value of an attribute", stringValue);
11471153
return "Invalid characters in attribute value";
Lines changed: 168 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,168 @@
1+
# Copyright 2026 Telefonica Investigacion y Desarrollo, S.A.U
2+
#
3+
# This file is part of Orion Context Broker.
4+
#
5+
# Orion Context Broker is free software: you can redistribute it and/or
6+
# modify it under the terms of the GNU Affero General Public License as
7+
# published by the Free Software Foundation, either version 3 of the
8+
# License, or (at your option) any later version.
9+
#
10+
# Orion Context Broker is distributed in the hope that it will be useful,
11+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
12+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero
13+
# General Public License for more details.
14+
#
15+
# You should have received a copy of the GNU Affero General Public License
16+
# along with Orion Context Broker. If not, see http://www.gnu.org/licenses/.
17+
#
18+
# For those usages not covered by this license please contact with
19+
# iot_support at tid dot es
20+
21+
# VALGRIND_READY - to mark the test ready for valgrindTestSuite.sh
22+
23+
--NAME--
24+
TextUnrestricted metadata support
25+
26+
--SHELL-INIT--
27+
dbInit CB
28+
brokerStart CB
29+
30+
--SHELL--
31+
32+
#
33+
# 01. Create entity with a custom type attribute containing forbidden characters in value and TextUnrestricted metadata true
34+
# 02. Get the entity and verify attribute value and TextUnrestricted metadata
35+
# 03. Create entity with a custom type attribute containing forbidden characters in value and TextUnrestricted metadata false, get error
36+
# 04. Create entity with a custom type attribute containing forbidden characters in value and TextUnrestricted metadata missing, get error
37+
#
38+
39+
echo '01. Create entity with a custom type attribute containing forbidden characters in value and TextUnrestricted metadata true'
40+
echo '=========================================================================================================================='
41+
payload='{
42+
"id": "E1",
43+
"type": "T",
44+
"A": {
45+
"type": "FunnyType",
46+
"value": "Value with <forbidden> characters (like = or ;)",
47+
"metadata": {
48+
"TextUnrestricted": {
49+
"value": true,
50+
"type": "Boolean"
51+
}
52+
}
53+
}
54+
}'
55+
orionCurl --url /v2/entities --payload "$payload"
56+
echo
57+
echo
58+
59+
60+
echo '02. Get the entity and verify attribute value and TextUnrestricted metadata'
61+
echo '==========================================================================='
62+
orionCurl --url /v2/entities/E1
63+
echo
64+
echo
65+
66+
67+
echo '03. Create entity with a custom type attribute containing forbidden characters in value and TextUnrestricted metadata false, get error'
68+
echo '======================================================================================================================================'
69+
payload='{
70+
"id": "E2",
71+
"type": "T",
72+
"A": {
73+
"type": "FunnyType",
74+
"value": "Value with <forbidden> characters (like = or ;)",
75+
"metadata": {
76+
"TextUnrestricted": {
77+
"value": false,
78+
"type": "Boolean"
79+
}
80+
}
81+
}
82+
}'
83+
orionCurl --url /v2/entities --payload "$payload"
84+
echo
85+
echo
86+
87+
88+
echo '04. Create entity with a custom type attribute containing forbidden characters in value and TextUnrestricted metadata missing, get error'
89+
echo '========================================================================================================================================'
90+
payload='{
91+
"id": "E3",
92+
"type": "T",
93+
"A": {
94+
"type": "FunnyType",
95+
"value": "Value with <forbidden> characters (like = or ;)"
96+
}
97+
}'
98+
orionCurl --url /v2/entities --payload "$payload"
99+
echo
100+
echo
101+
102+
103+
--REGEXPECT--
104+
01. Create entity with a custom type attribute containing forbidden characters in value and TextUnrestricted metadata true
105+
==========================================================================================================================
106+
HTTP/1.1 201 Created
107+
Date: REGEX(.*)
108+
Fiware-Correlator: REGEX([0-9a-f\-]{36})
109+
Location: /v2/entities/E1?type=T
110+
Content-Length: 0
111+
112+
113+
114+
02. Get the entity and verify attribute value and TextUnrestricted metadata
115+
===========================================================================
116+
HTTP/1.1 200 OK
117+
Date: REGEX(.*)
118+
Fiware-Correlator: REGEX([0-9a-f\-]{36})
119+
Content-Type: application/json
120+
Content-Length: REGEX(\d+)
121+
122+
{
123+
"A": {
124+
"metadata": {
125+
"TextUnrestricted": {
126+
"type": "Boolean",
127+
"value": true
128+
}
129+
},
130+
"type": "FunnyType",
131+
"value": "Value with <forbidden> characters (like = or ;)"
132+
},
133+
"id": "E1",
134+
"type": "T"
135+
}
136+
137+
138+
03. Create entity with a custom type attribute containing forbidden characters in value and TextUnrestricted metadata false, get error
139+
======================================================================================================================================
140+
HTTP/1.1 400 Bad Request
141+
Date: REGEX(.*)
142+
Fiware-Correlator: REGEX([0-9a-f\-]{36})
143+
Content-Type: application/json
144+
Content-Length: 76
145+
146+
{
147+
"description": "Invalid characters in attribute value",
148+
"error": "BadRequest"
149+
}
150+
151+
152+
04. Create entity with a custom type attribute containing forbidden characters in value and TextUnrestricted metadata missing, get error
153+
========================================================================================================================================
154+
HTTP/1.1 400 Bad Request
155+
Date: REGEX(.*)
156+
Fiware-Correlator: REGEX([0-9a-f\-]{36})
157+
Content-Type: application/json
158+
Content-Length: 76
159+
160+
{
161+
"description": "Invalid characters in attribute value",
162+
"error": "BadRequest"
163+
}
164+
165+
166+
--TEARDOWN--
167+
brokerStop CB
168+
dbDrop CB
Lines changed: 171 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,171 @@
1+
# Copyright 2026 Telefonica Investigacion y Desarrollo, S.A.U
2+
#
3+
# This file is part of Orion Context Broker.
4+
#
5+
# Orion Context Broker is free software: you can redistribute it and/or
6+
# modify it under the terms of the GNU Affero General Public License as
7+
# published by the Free Software Foundation, either version 3 of the
8+
# License, or (at your option) any later version.
9+
#
10+
# Orion Context Broker is distributed in the hope that it will be useful,
11+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
12+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero
13+
# General Public License for more details.
14+
#
15+
# You should have received a copy of the GNU Affero General Public License
16+
# along with Orion Context Broker. If not, see http://www.gnu.org/licenses/.
17+
#
18+
# For those usages not covered by this license please contact with
19+
# iot_support at tid dot es
20+
21+
# VALGRIND_READY - to mark the test ready for valgrindTestSuite.sh
22+
23+
--NAME--
24+
TextUnrestricted metadata CRUD transitions support
25+
26+
--SHELL-INIT--
27+
dbInit CB
28+
brokerStart CB
29+
30+
--SHELL--
31+
32+
#
33+
# 01. Create entity E with a custom type attribute and no TextUnrestricted metadata
34+
# 02. Update attribute with forbidden chars and NO metadata, get error
35+
# 03. Update attribute with forbidden chars and TextUnrestricted metadata as true
36+
# 04. Update attribute with forbidden chars and TextUnrestricted metadata as false, get error
37+
# 05. Update attribute with forbidden chars and empty metadata to remove it, get error
38+
#
39+
40+
echo '01. Create entity E with a custom type attribute and no TextUnrestricted metadata'
41+
echo '================================================================================='
42+
payload='{
43+
"id": "E",
44+
"type": "T",
45+
"A": {
46+
"type": "FunnyType",
47+
"value": "initial value"
48+
}
49+
}'
50+
orionCurl --url /v2/entities --payload "$payload"
51+
echo
52+
echo
53+
54+
55+
echo '02. Update attribute with forbidden chars and NO metadata, get error'
56+
echo '===================================================================='
57+
payload='{
58+
"value": "Value with <forbidden> characters (like = or ;)"
59+
}'
60+
orionCurl --url /v2/entities/E/attrs/A --payload "$payload" -X PUT
61+
echo
62+
echo
63+
64+
65+
echo '03. Update attribute with forbidden chars and TextUnrestricted metadata as true'
66+
echo '==============================================================================='
67+
payload='{
68+
"value": "Value with <forbidden> characters (like = or ;)",
69+
"metadata": {
70+
"TextUnrestricted": {
71+
"value": true,
72+
"type": "Boolean"
73+
}
74+
}
75+
}'
76+
orionCurl --url /v2/entities/E/attrs/A --payload "$payload" -X PUT
77+
echo
78+
echo
79+
80+
81+
echo '04. Update attribute with forbidden chars and TextUnrestricted metadata as false, get error'
82+
echo '==========================================================================================='
83+
payload='{
84+
"value": "Value with <forbidden> characters (like = or ;)",
85+
"metadata": {
86+
"TextUnrestricted": {
87+
"value": false,
88+
"type": "Boolean"
89+
}
90+
}
91+
}'
92+
orionCurl --url /v2/entities/E/attrs/A --payload "$payload" -X PUT
93+
echo
94+
echo
95+
96+
97+
echo '05. Update attribute with forbidden chars and empty metadata to remove it, get error'
98+
echo '===================================================================================='
99+
payload='{
100+
"value": "Value with <forbidden> characters (like = or ;)",
101+
"metadata": {}
102+
}'
103+
orionCurl --url /v2/entities/E/attrs/A --payload "$payload" -X PUT
104+
echo
105+
echo
106+
107+
108+
--REGEXPECT--
109+
01. Create entity E with a custom type attribute and no TextUnrestricted metadata
110+
=================================================================================
111+
HTTP/1.1 201 Created
112+
Date: REGEX(.*)
113+
Fiware-Correlator: REGEX([0-9a-f\-]{36})
114+
Location: /v2/entities/E?type=T
115+
Content-Length: 0
116+
117+
118+
119+
02. Update attribute with forbidden chars and NO metadata, get error
120+
====================================================================
121+
HTTP/1.1 400 Bad Request
122+
Date: REGEX(.*)
123+
Fiware-Correlator: REGEX([0-9a-f\-]{36})
124+
Content-Type: application/json
125+
Content-Length: 76
126+
127+
{
128+
"description": "Invalid characters in attribute value",
129+
"error": "BadRequest"
130+
}
131+
132+
133+
03. Update attribute with forbidden chars and TextUnrestricted metadata as true
134+
===============================================================================
135+
HTTP/1.1 204 No Content
136+
Date: REGEX(.*)
137+
Fiware-Correlator: REGEX([0-9a-f\-]{36})
138+
139+
140+
141+
04. Update attribute with forbidden chars and TextUnrestricted metadata as false, get error
142+
===========================================================================================
143+
HTTP/1.1 400 Bad Request
144+
Date: REGEX(.*)
145+
Fiware-Correlator: REGEX([0-9a-f\-]{36})
146+
Content-Type: application/json
147+
Content-Length: 76
148+
149+
{
150+
"description": "Invalid characters in attribute value",
151+
"error": "BadRequest"
152+
}
153+
154+
155+
05. Update attribute with forbidden chars and empty metadata to remove it, get error
156+
====================================================================================
157+
HTTP/1.1 400 Bad Request
158+
Date: REGEX(.*)
159+
Fiware-Correlator: REGEX([0-9a-f\-]{36})
160+
Content-Type: application/json
161+
Content-Length: 76
162+
163+
{
164+
"description": "Invalid characters in attribute value",
165+
"error": "BadRequest"
166+
}
167+
168+
169+
--TEARDOWN--
170+
brokerStop CB
171+
dbDrop CB

0 commit comments

Comments
 (0)