Skip to content

Commit 98106c4

Browse files
author
Bryan Worrell
committed
Added support for ElectronicAddressIdentifiers and OrganisationName/@type in CIQ identity extension
1 parent 630ae8d commit 98106c4

File tree

1 file changed

+128
-18
lines changed

1 file changed

+128
-18
lines changed

stix/extensions/identity/ciq_identity_3_0.py

Lines changed: 128 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
# xml element tree creation
1111
#from xml.etree import cElementTree as et
1212
import lxml.etree as et
13+
from stix.bindings.extensions.identity.ciq_identity_3_0 import XML_NS_XNL
1314

1415
XML_NS_XPIL = "urn:oasis:names:tc:ciq:xpil:3"
1516
XML_NS_XNL = "urn:oasis:names:tc:ciq:xnl:3"
@@ -137,11 +138,12 @@ class STIXCIQIdentity3_0(stix.Entity):
137138
_namespace = "http://stix.mitre.org/extensions/Identity#CIQIdentity3.0-1"
138139
XML_TAG = "{%s}Specification" % _namespace
139140

140-
def __init__(self, party_name=None, languages=None, addresses=None, organisation_info=None):
141+
def __init__(self, party_name=None, languages=None, addresses=None, organisation_info=None, electronic_address_identifiers=None):
141142
self.party_name = party_name
142143
self.languages = languages
143144
self.addresses = addresses
144145
self.organisation_info = organisation_info
146+
self.electronic_address_identifiers = electronic_address_identifiers
145147

146148
@property
147149
def addresses(self):
@@ -202,11 +204,34 @@ def party_name(self, value):
202204
else:
203205
raise ValueError('party_name must be instance of PartyName')
204206

207+
@property
208+
def electronic_address_identifiers(self):
209+
return self._electronic_address_identifiers
210+
211+
@electronic_address_identifiers.setter
212+
def electronic_address_identifiers(self, value):
213+
self._electronic_address_identifiers = []
214+
if not value:
215+
return
216+
elif isinstance(value, list):
217+
for v in value:
218+
self.add_electronic_address_identifier(v)
219+
else:
220+
self.add_electronic_address_identifier(value)
221+
222+
def add_electronic_address_identifier(self, value):
223+
if not value:
224+
return
225+
elif isinstance(value, ElectronicAddressIdentifier):
226+
self.electronic_address_identifiers.append(value)
227+
else:
228+
self.electronic_address_identifiers.append(ElectronicAddressIdentifier(value))
229+
230+
205231
@classmethod
206232
def from_obj(cls, obj, return_obj=None):
207233
if obj is None:
208234
return None
209-
210235
if not return_obj:
211236
return_obj = cls()
212237

@@ -225,7 +250,11 @@ def from_obj(cls, obj, return_obj=None):
225250
organisation_info = obj.findall(OrganisationInfo.XML_TAG)
226251
if organisation_info is not None and len(organisation_info) > 0:
227252
return_obj.organisation_info = OrganisationInfo.from_obj(organisation_info[0])
228-
253+
254+
electronic_address_identifiers = obj.findall("{%s}ElectronicAddressIdentifiers")
255+
if electronic_address_identifiers is not None and len(electronic_address_identifiers) > 0:
256+
return_obj.electronic_address_identifiers = [ElectronicAddressIdentifier.from_obj(x) for x in electronic_address_identifiers[0]]
257+
229258
return return_obj
230259

231260
def to_obj(self, return_obj=None):
@@ -251,6 +280,12 @@ def to_obj(self, return_obj=None):
251280
if self.organisation_info:
252281
return_obj.append(self.organisation_info.to_obj())
253282

283+
if self.electronic_address_identifiers:
284+
eai_root = et.Element("{%s}ElectronicAddressIdentifiers" % XML_NS_XPIL)
285+
return_obj.append(eai_root)
286+
for eai in self.electronic_address_identifiers:
287+
eai_root.append(eai.to_obj())
288+
254289
return return_obj
255290

256291
@classmethod
@@ -263,7 +298,8 @@ def from_dict(cls, dict_repr, return_obj=None):
263298
return_obj.party_name = PartyName.from_dict(dict_repr.get('party_name'))
264299
return_obj.languages = [Language.from_dict(x) for x in dict_repr.get('languages', [])]
265300
return_obj.addresses = [Address.from_dict(x) for x in dict_repr.get('addresses', [])]
266-
301+
return_obj.electronic_address_identifiers = [ElectronicAddressIdentifier.from_dict(x) for x in dict_repr.get('electronic_address_identifiers', [])]
302+
267303
return return_obj
268304

269305
def to_dict(self):
@@ -274,6 +310,8 @@ def to_dict(self):
274310
d['languages'] = [x.to_dict() for x in self.languages]
275311
if self.addresses:
276312
d['addresses'] = [x.to_dict() for x in self.addresses]
313+
if self.electronic_address_identifiers:
314+
d['electronic_address_identifiers'] = [x.to_dict() for x in self.electronic_address_identifiers]
277315
return d
278316

279317
class Address(stix.Entity):
@@ -830,18 +868,25 @@ class OrganisationName(stix.Entity):
830868
_namespace = XML_NS_XNL
831869
XML_TAG = "{%s}OrganisationName" % _namespace
832870

833-
def __init__(self, name_elements=None, sub_division_names=None):
834-
self.name_elements = []
835-
self.subdivision_names = []
836-
837-
if name_elements:
838-
for name_element in name_elements:
839-
self.add_organisation_name_element(name_element)
871+
def __init__(self, name_elements=None, subdivision_names=None, type_=None):
872+
self.type_ = type_
873+
self.name_elements = name_elements
874+
self.subdivision_names = subdivision_names
840875

841-
if sub_division_names:
842-
for name in sub_division_names:
843-
self.add_subdivision_name(name)
876+
@property
877+
def name_elements(self):
878+
return self._name_elements
844879

880+
@name_elements.setter
881+
def name_elements(self, value):
882+
self._name_elements = []
883+
if not value:
884+
return
885+
elif isinstance(value, list):
886+
for v in value:
887+
self.add_organisation_name_element(v)
888+
else:
889+
self.add_organisation_name_element(value)
845890

846891
def add_organisation_name_element(self, value):
847892
if isinstance(value, basestring):
@@ -851,6 +896,20 @@ def add_organisation_name_element(self, value):
851896
else:
852897
raise ValueError('value must be instance of OrganisationNameElement')
853898

899+
@property
900+
def subdivision_names(self):
901+
return self._subdivision_names
902+
903+
@subdivision_names.setter
904+
def subdivision_names(self, value):
905+
self._subdivision_names = []
906+
if not value:
907+
return
908+
elif isinstance(value, list):
909+
for v in value:
910+
self.add_subdivision_name(v)
911+
else:
912+
self.add_subdivision_name(value)
854913

855914
def add_subdivision_name(self, value):
856915
if not isinstance(value, SubDivisionName):
@@ -864,9 +923,10 @@ def to_obj(self, return_obj=None):
864923
root_tag = OrganisationName.XML_TAG
865924
return_obj = et.Element(root_tag)
866925

926+
if self.type_:
927+
return_obj.attrib['{%s}Type' % XML_NS_XNL] = self.type_
867928
for name_element in self.name_elements:
868929
return_obj.append(name_element.to_obj())
869-
870930
for subdivision_name in self.subdivision_names:
871931
return_obj.append(subdivision_name.to_obj())
872932

@@ -876,10 +936,11 @@ def to_obj(self, return_obj=None):
876936
def from_obj(cls, obj, return_obj=None):
877937
if obj is None:
878938
return None
879-
880939
if not return_obj:
881940
return_obj = cls()
882941

942+
return_obj.type_ = obj.attrib.get('{%s}Type' % XML_NS_XNL)
943+
883944
name_elements = obj.findall(OrganisationNameElement.XML_TAG)
884945
if name_elements:
885946
for name_element_obj in name_elements:
@@ -896,6 +957,9 @@ def from_obj(cls, obj, return_obj=None):
896957

897958
def to_dict(self):
898959
d = {}
960+
961+
if self.type_:
962+
d['type'] = self.type_
899963
if self.name_elements:
900964
for ne in self.name_elements:
901965
d.setdefault('name_elements', []).append(ne.to_dict())
@@ -909,20 +973,21 @@ def to_dict(self):
909973
def from_dict(cls, dict_repr, return_obj=None):
910974
if not dict_repr:
911975
return None
912-
913976
if not return_obj:
914977
return_obj = cls()
915978

916979
ne_dicts = dict_repr.get('name_elements', [])
917980
sn_dicts = dict_repr.get('subdivision_names', [])
918981

982+
983+
return_obj.type_ = dict_repr.get('type')
919984
for ne_dict in ne_dicts:
920985
return_obj.add_organisation_name_element(OrganisationNameElement.from_dict(ne_dict))
921-
922986
for sn_dict in sn_dicts:
923987
return_obj.add_subdivision_name(SubDivisionName.from_dict(sn_dict))
924988

925989
return return_obj
990+
926991

927992
class _BaseNameElement(stix.Entity):
928993
'''Do not instantiate directly: use PersonNameElement or OrganisationNameElement'''
@@ -1221,6 +1286,51 @@ def from_dict(cls, d):
12211286
return_obj = cls()
12221287
return_obj.value = d.get('value')
12231288
return return_obj
1289+
1290+
class ElectronicAddressIdentifier(stix.Entity):
1291+
_namespace = XML_NS_XPIL
1292+
XML_TAG = "{%s}ElectronicAddressIdentifier" % _namespace
1293+
1294+
def __init__(self, value=None, type_=None):
1295+
self.type_ = type_
1296+
self.value = value
1297+
1298+
def to_obj(self):
1299+
return_obj = et.Element(self.XML_TAG)
1300+
return_obj.text = self.value
1301+
1302+
if self.type_:
1303+
return_obj.attrib['Type'] = self.type_
1304+
1305+
return return_obj
1306+
1307+
@classmethod
1308+
def from_obj(cls, obj):
1309+
if obj is None:
1310+
return None
1311+
1312+
return_obj = cls()
1313+
return_obj.type_ = obj.attrib.get('Type')
1314+
return_obj.value = obj.text
1315+
return return_obj
1316+
1317+
def to_dict(self):
1318+
d = {}
1319+
if self.value:
1320+
d['value'] = self.value
1321+
if self.type_:
1322+
d['type'] = self.type_
1323+
return d
1324+
1325+
@classmethod
1326+
def from_dict(cls, d):
1327+
if not d:
1328+
return None
1329+
1330+
return_obj = cls()
1331+
return_obj.value = d.get('value')
1332+
return_obj.type_ = d.get('type')
1333+
return return_obj
12241334

12251335
class OrganisationInfo(stix.Entity):
12261336
_namespace = XML_NS_XPIL

0 commit comments

Comments
 (0)