Skip to content

Commit 3276661

Browse files
committed
handle hex_property in list
1 parent 35ce57a commit 3276661

File tree

8 files changed

+120
-100
lines changed

8 files changed

+120
-100
lines changed

stix2/datastore/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -212,7 +212,7 @@ def add(self, *args, **kwargs):
212212
"""
213213
try:
214214
return self.sink.add(*args, **kwargs)
215-
except AttributeError as ex:
215+
except AttributeError:
216216
msg = "%s has no data sink to put objects in"
217217
raise AttributeError(msg % self.__class__.__name__)
218218

stix2/datastore/relational_db/database_backends/database_backend_base.py

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,13 @@
11
from typing import Any
22

3-
from sqlalchemy import (
4-
create_engine, Boolean, Float, Integer, LargeBinary, Text, TIMESTAMP,
5-
)
3+
from sqlalchemy import Boolean, Float, Integer, Text, create_engine
64
from sqlalchemy_utils import create_database, database_exists, drop_database
75

86
from stix2.base import (
9-
_DomainObject, _Extension, _MetaObject, _Observable, _RelationshipObject,
10-
_STIXBase,
7+
_DomainObject, _MetaObject, _Observable, _RelationshipObject,
118
)
129

10+
1311
class DatabaseBackend:
1412
def __init__(self, database_connection_url, force_recreate=False, **kwargs: Any):
1513
self.database_connection_url = database_connection_url

stix2/datastore/relational_db/database_backends/postgres_backend.py

Lines changed: 2 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,13 @@
11
import os
22
from typing import Any
33

4-
from sqlalchemy import (
5-
TIMESTAMP, LargeBinary, Text,
6-
)
4+
from sqlalchemy import TIMESTAMP, LargeBinary, Text
75
from sqlalchemy.schema import CreateSchema
86

97
from stix2.base import (
10-
_DomainObject, _Extension, _MetaObject, _Observable, _RelationshipObject,
11-
_STIXBase,
8+
_DomainObject, _MetaObject, _Observable, _RelationshipObject,
129
)
1310
from stix2.datastore.relational_db.utils import schema_for
14-
from stix2.properties import (
15-
BinaryProperty, BooleanProperty, DictionaryProperty,
16-
EmbeddedObjectProperty, EnumProperty, ExtensionsProperty, FloatProperty,
17-
HashesProperty, HexProperty, IDProperty, IntegerProperty, ListProperty,
18-
ObjectReferenceProperty, Property, ReferenceProperty, StringProperty,
19-
TimestampProperty, TypeProperty,
20-
)
2111

2212
from .database_backend_base import DatabaseBackend
2313

stix2/datastore/relational_db/input_creation.py

Lines changed: 17 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -248,7 +248,11 @@ def generate_insert_information( # noqa: F811
248248
return insert_statements
249249
else:
250250
if db_backend.array_allowed():
251-
return {name: stix_object[name]}
251+
if isinstance(self.contained, HexProperty):
252+
return {name: [bytes.fromhex(x) for x in stix_object[name]]}
253+
else:
254+
return {name: stix_object[name]}
255+
252256
else:
253257
insert_statements = list()
254258
table = data_sink.tables_dictionary[
@@ -258,13 +262,14 @@ def generate_insert_information( # noqa: F811
258262
)
259263
]
260264
for elem in stix_object[name]:
261-
bindings = {"id": stix_object["id"], name: elem}
265+
bindings = {
266+
"id": stix_object["id"],
267+
name: bytes.fromhex(elem) if isinstance(self.contained, HexProperty) else elem,
268+
}
262269
insert_statements.append(insert(table).values(bindings))
263270
return insert_statements
264271

265272

266-
267-
268273
@add_method(ReferenceProperty)
269274
def generate_insert_information(self, name, stix_object, **kwargs): # noqa: F811
270275
return {name: stix_object[name]}
@@ -300,7 +305,6 @@ def generate_insert_for_array_in_table(table, values, foreign_key_value, column_
300305

301306

302307
def generate_insert_for_external_references(data_sink, stix_object):
303-
db_backend = data_sink.db_backend
304308
insert_statements = list()
305309
next_id = None
306310
object_table = data_sink.tables_dictionary["common.external_references"]
@@ -395,20 +399,23 @@ def generate_insert_for_core(data_sink, stix_object, core_properties, stix_type_
395399
core_insert_statement = insert(core_table).values(core_bindings)
396400
insert_statements.append(core_insert_statement)
397401

398-
if "labels" in stix_object:
402+
if "labels" in stix_object and "labels" in child_table_properties:
399403
label_table_name = canonicalize_table_name(core_table.name + "_labels", data_sink.db_backend.schema_for_core())
400404
labels_table = data_sink.tables_dictionary[label_table_name]
401405
insert_statements.extend(
402406
generate_insert_for_array_in_table(
403407
labels_table,
404408
stix_object["labels"],
405409
stix_object["id"],
406-
column_name="label"
407-
))
410+
column_name="label",
411+
),
412+
)
408413

409414
if "object_marking_refs" in stix_object:
410-
object_marking_table_name = canonicalize_table_name("object_marking_refs",
411-
data_sink.db_backend.schema_for_core())
415+
object_marking_table_name = canonicalize_table_name(
416+
"object_marking_refs",
417+
data_sink.db_backend.schema_for_core(),
418+
)
412419
if stix_type_name != "sco":
413420
object_markings_ref_table = data_sink.tables_dictionary[object_marking_table_name + "_sdo"]
414421
else:

stix2/datastore/relational_db/relational_db.py

Lines changed: 9 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,14 @@
1-
from sqlalchemy import MetaData, create_engine, delete, select
2-
from sqlalchemy.schema import CreateSchema, CreateTable, Sequence
3-
from sqlalchemy_utils import create_database, database_exists, drop_database
1+
from sqlalchemy import MetaData, delete
2+
from sqlalchemy.schema import CreateTable, Sequence
43

5-
from stix2.base import (
6-
_DomainObject, _MetaObject, _Observable, _RelationshipObject, _STIXBase,
7-
)
4+
from stix2.base import _STIXBase
85
from stix2.datastore import DataSink, DataSource, DataStoreMixin
96
from stix2.datastore.relational_db.input_creation import (
107
generate_insert_for_object,
118
)
129
from stix2.datastore.relational_db.query import read_object
1310
from stix2.datastore.relational_db.table_creation import create_table_objects
14-
from stix2.datastore.relational_db.utils import (
15-
canonicalize_table_name, schema_for, table_name_for,
16-
)
11+
from stix2.datastore.relational_db.utils import canonicalize_table_name
1712
from stix2.parsing import parse
1813

1914

@@ -88,6 +83,7 @@ def __init__(
8883
source=RelationalDBSource(
8984
db_backend,
9085
metadata=self.metadata,
86+
allow_custom=allow_custom,
9187
),
9288
sink=RelationalDBSink(
9389
db_backend,
@@ -190,9 +186,10 @@ def next_id(self):
190186
with self.db_backend.database_connection.begin() as trans:
191187
return trans.execute(self.sequence)
192188

189+
193190
class RelationalDBSource(DataSource):
194191
def __init__(
195-
self, db_backend, *stix_object_classes, metadata=None,
192+
self, db_backend, allow_custom, *stix_object_classes, metadata=None,
196193
):
197194
"""
198195
Initialize this source. Only one of stix_object_classes and metadata
@@ -217,6 +214,8 @@ def __init__(
217214

218215
self.db_backend = db_backend
219216

217+
self.allow_custom = allow_custom
218+
220219
if metadata:
221220
self.metadata = metadata
222221
else:

stix2/datastore/relational_db/relational_db_testing.py

Lines changed: 40 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,7 @@ def malware_with_all_required_properties():
6464
ref2 = stix2.v21.ExternalReference(
6565
source_name="ACME Threat Intel",
6666
description="Threat report",
67-
url="http://www.example.com/threat-report.pdf"
67+
url="http://www.example.com/threat-report.pdf",
6868
)
6969
now = dt.datetime(2016, 5, 12, 8, 17, 27, tzinfo=pytz.utc)
7070

@@ -203,10 +203,10 @@ def custom_obj():
203203

204204
@stix2.CustomObject(
205205
"test-object", [
206-
("prop_name", stix2.properties.ListProperty(stix2.properties.BinaryProperty()))
206+
("prop_name", stix2.properties.ListProperty(stix2.properties.BinaryProperty())),
207207
],
208208
"extension-definition--15de9cdb-3515-4271-8479-8141154c5647",
209-
is_sdo=True
209+
is_sdo=True,
210210
)
211211
class TestClass:
212212
pass
@@ -215,71 +215,76 @@ class TestClass:
215215
def test_binary_list():
216216
return TestClass(prop_name=["AREi", "7t3M"])
217217

218+
218219
@stix2.CustomObject(
219220
"test2-object", [
220-
("prop_name", stix2.properties.ListProperty(
221-
stix2.properties.HexProperty()
222-
))
221+
(
222+
"prop_name", stix2.properties.ListProperty(
223+
stix2.properties.HexProperty(),
224+
),
225+
),
223226
],
224227
"extension-definition--15de9cdb-4567-4271-8479-8141154c5647",
225-
is_sdo=True
226-
)
227-
228+
is_sdo=True,
229+
)
228230
class Test2Class:
229-
pass
231+
pass
232+
230233

231234
def test_hex_list():
232235
return Test2Class(
233-
prop_name=["1122", "fedc"]
236+
prop_name=["1122", "fedc"],
234237
)
235238

239+
236240
@stix2.CustomObject(
237241
"test3-object", [
238-
("prop_name",
239-
stix2.properties.DictionaryProperty(
240-
valid_types=[
241-
stix2.properties.IntegerProperty,
242-
stix2.properties.FloatProperty,
243-
stix2.properties.StringProperty
244-
]
245-
)
246-
)
242+
(
243+
"prop_name",
244+
stix2.properties.DictionaryProperty(
245+
valid_types=[
246+
stix2.properties.IntegerProperty,
247+
stix2.properties.FloatProperty,
248+
stix2.properties.StringProperty,
249+
],
250+
),
251+
),
247252
],
248253
"extension-definition--15de9cdb-1234-4271-8479-8141154c5647",
249-
is_sdo=True
250-
)
254+
is_sdo=True,
255+
)
251256
class Test3Class:
252257
pass
253258

254259

255260
def test_dictionary():
256261
return Test3Class(
257-
prop_name={"a": 1, "b": 2.3, "c": "foo"}
262+
prop_name={"a": 1, "b": 2.3, "c": "foo"},
258263
)
259264

260265

261266
def main():
262267
store = RelationalDBStore(
263268
PostgresBackend("postgresql://localhost/stix-data-sink", force_recreate=True),
264-
False,
269+
True,
265270
None,
266271
True,
267272
print_sql=True,
268273
)
269274

270275
if store.sink.db_backend.database_exists:
271276

272-
# td = test_dictionary()
273-
#
274-
# store.add(td)
275-
#
276-
# th = test_hex_list()
277-
#
278-
# store.add(th)
279-
#
280-
# tb = test_binary_list()
281-
#
282-
# store.add(tb)
277+
td = test_dictionary()
278+
279+
store.add(td)
280+
281+
th = test_hex_list()
282+
283+
store.add(th)
284+
285+
tb = test_binary_list()
286+
287+
store.add(tb)
283288

284289
co = custom_obj()
285290

0 commit comments

Comments
 (0)