/stix2/v21/sro.py

https://github.com/oasis-open/cti-python-stix2 · Python · 116 lines · 107 code · 4 blank · 5 comment · 0 complexity · 8e1a336afc49fc4a8a7814c37045b940 MD5 · raw file

  1. """STIX 2.1 Relationship Objects."""
  2. from collections import OrderedDict
  3. from ..properties import (
  4. BooleanProperty, IDProperty, IntegerProperty, ListProperty,
  5. ReferenceProperty, StringProperty, TimestampProperty, TypeProperty,
  6. )
  7. from ..utils import NOW
  8. from .base import _RelationshipObject
  9. from .common import ExternalReference, GranularMarking
  10. class Relationship(_RelationshipObject):
  11. """For more detailed information on this object's properties, see
  12. `the STIX 2.1 specification <https://docs.oasis-open.org/cti/stix/v2.1/cs01/stix-v2.1-cs01.html#_al0fb8fcd9e7>`__.
  13. """
  14. _invalid_source_target_types = ['bundle', 'language-content', 'marking-definition', 'relationship', 'sighting']
  15. _type = 'relationship'
  16. _properties = OrderedDict([
  17. ('type', TypeProperty(_type, spec_version='2.1')),
  18. ('spec_version', StringProperty(fixed='2.1')),
  19. ('id', IDProperty(_type, spec_version='2.1')),
  20. ('created_by_ref', ReferenceProperty(valid_types='identity', spec_version='2.1')),
  21. ('created', TimestampProperty(default=lambda: NOW, precision='millisecond', precision_constraint='min')),
  22. ('modified', TimestampProperty(default=lambda: NOW, precision='millisecond', precision_constraint='min')),
  23. ('relationship_type', StringProperty(required=True)),
  24. ('description', StringProperty()),
  25. ('source_ref', ReferenceProperty(invalid_types=_invalid_source_target_types, spec_version='2.1', required=True)),
  26. ('target_ref', ReferenceProperty(invalid_types=_invalid_source_target_types, spec_version='2.1', required=True)),
  27. ('start_time', TimestampProperty()),
  28. ('stop_time', TimestampProperty()),
  29. ('revoked', BooleanProperty(default=lambda: False)),
  30. ('labels', ListProperty(StringProperty)),
  31. ('confidence', IntegerProperty()),
  32. ('lang', StringProperty()),
  33. ('external_references', ListProperty(ExternalReference)),
  34. ('object_marking_refs', ListProperty(ReferenceProperty(valid_types='marking-definition', spec_version='2.1'))),
  35. ('granular_markings', ListProperty(GranularMarking)),
  36. ])
  37. # Explicitly define the first three kwargs to make readable Relationship declarations.
  38. def __init__(
  39. self, source_ref=None, relationship_type=None,
  40. target_ref=None, **kwargs
  41. ):
  42. # Allow (source_ref, relationship_type, target_ref) as positional args.
  43. if source_ref and not kwargs.get('source_ref'):
  44. kwargs['source_ref'] = source_ref
  45. if relationship_type and not kwargs.get('relationship_type'):
  46. kwargs['relationship_type'] = relationship_type
  47. if target_ref and not kwargs.get('target_ref'):
  48. kwargs['target_ref'] = target_ref
  49. super(Relationship, self).__init__(**kwargs)
  50. def _check_object_constraints(self):
  51. super(self.__class__, self)._check_object_constraints()
  52. start_time = self.get('start_time')
  53. stop_time = self.get('stop_time')
  54. if start_time and stop_time and stop_time <= start_time:
  55. msg = "{0.id} 'stop_time' must be later than 'start_time'"
  56. raise ValueError(msg.format(self))
  57. class Sighting(_RelationshipObject):
  58. """For more detailed information on this object's properties, see
  59. `the STIX 2.1 specification <https://docs.oasis-open.org/cti/stix/v2.1/cs01/stix-v2.1-cs01.html#_7p0n81ikux8f>`__.
  60. """
  61. _type = 'sighting'
  62. _properties = OrderedDict([
  63. ('type', TypeProperty(_type, spec_version='2.1')),
  64. ('spec_version', StringProperty(fixed='2.1')),
  65. ('id', IDProperty(_type, spec_version='2.1')),
  66. ('created_by_ref', ReferenceProperty(valid_types='identity', spec_version='2.1')),
  67. ('created', TimestampProperty(default=lambda: NOW, precision='millisecond', precision_constraint='min')),
  68. ('modified', TimestampProperty(default=lambda: NOW, precision='millisecond', precision_constraint='min')),
  69. ('description', StringProperty()),
  70. ('first_seen', TimestampProperty()),
  71. ('last_seen', TimestampProperty()),
  72. ('count', IntegerProperty(min=0, max=999999999)),
  73. ('sighting_of_ref', ReferenceProperty(valid_types="SDO", spec_version='2.1', required=True)),
  74. ('observed_data_refs', ListProperty(ReferenceProperty(valid_types='observed-data', spec_version='2.1'))),
  75. ('where_sighted_refs', ListProperty(ReferenceProperty(valid_types='identity', spec_version='2.1'))),
  76. ('summary', BooleanProperty()),
  77. ('revoked', BooleanProperty(default=lambda: False)),
  78. ('labels', ListProperty(StringProperty)),
  79. ('confidence', IntegerProperty()),
  80. ('lang', StringProperty()),
  81. ('external_references', ListProperty(ExternalReference)),
  82. ('object_marking_refs', ListProperty(ReferenceProperty(valid_types='marking-definition', spec_version='2.1'))),
  83. ('granular_markings', ListProperty(GranularMarking)),
  84. ])
  85. # Explicitly define the first kwargs to make readable Sighting declarations.
  86. def __init__(self, sighting_of_ref=None, **kwargs):
  87. # Allow sighting_of_ref as a positional arg.
  88. if sighting_of_ref and not kwargs.get('sighting_of_ref'):
  89. kwargs['sighting_of_ref'] = sighting_of_ref
  90. super(Sighting, self).__init__(**kwargs)
  91. def _check_object_constraints(self):
  92. super(self.__class__, self)._check_object_constraints()
  93. first_seen = self.get('first_seen')
  94. last_seen = self.get('last_seen')
  95. if first_seen and last_seen and last_seen <= first_seen:
  96. msg = "{0.id} 'last_seen' must be later than 'first_seen'"
  97. raise ValueError(msg.format(self))