Repository: oasis-open/cti-python-stix2

Issue:
Sighting: where_sighted_refs enforced with wrong types
STIX 2.1 spec section 5.2 says for the `where_sighted_refs` property of the Sighting relationship:

```
This property MUST reference only Identity or Location SDOs.
```

But the stix2 library only allows Identity.  This should be fixed to also allow Location references.

https://github.com/oasis-open/cti-python-stix2/blob/a751df32c681e3ddfef92f29b91c071b84e91033/stix2/v21/sro.py#L89

Discussion:

Patch:
diff --git a/stix2/v21/sro.py b/stix2/v21/sro.py
index d287373..e6eada6 100644
--- a/stix2/v21/sro.py
+++ b/stix2/v21/sro.py
@@ -86,7 +86,7 @@ class Sighting(_RelationshipObject):
         ('count', IntegerProperty(min=0, max=999999999)),
         ('sighting_of_ref', ReferenceProperty(valid_types="SDO", spec_version='2.1', required=True)),
         ('observed_data_refs', ListProperty(ReferenceProperty(valid_types='observed-data', spec_version='2.1'))),
-        ('where_sighted_refs', ListProperty(ReferenceProperty(valid_types='identity', spec_version='2.1'))),
+        ('where_sighted_refs', ListProperty(ReferenceProperty(valid_types=['identity', 'location'], spec_version='2.1'))),
         ('summary', BooleanProperty()),
         ('revoked', BooleanProperty(default=lambda: False)),
         ('labels', ListProperty(StringProperty)),


Test patch:
diff --git a/stix2/test/v21/test_sighting.py b/stix2/test/v21/test_sighting.py
index 0493b71..0ef5faa 100644
--- a/stix2/test/v21/test_sighting.py
+++ b/stix2/test/v21/test_sighting.py
@@ -5,7 +5,9 @@ import pytz
 
 import stix2
 
-from .constants import IDENTITY_ID, INDICATOR_ID, SIGHTING_ID, SIGHTING_KWARGS
+from .constants import (
+    IDENTITY_ID, INDICATOR_ID, LOCATION_ID, SIGHTING_ID, SIGHTING_KWARGS,
+)
 
 EXPECTED_SIGHTING = """{
     "type": "sighting",
@@ -15,7 +17,8 @@ EXPECTED_SIGHTING = """{
     "modified": "2016-04-06T20:06:37.000Z",
     "sighting_of_ref": "indicator--a740531e-63ff-4e49-a9e1-a0a3eed0e3e7",
     "where_sighted_refs": [
-        "identity--311b2d2d-f010-4473-83ec-1edf84858f4c"
+        "identity--311b2d2d-f010-4473-83ec-1edf84858f4c",
+        "location--a6e9345f-5a15-4c29-8bb3-7dcc5d168d64"
     ]
 }"""
 
@@ -41,7 +44,7 @@ def test_sighting_all_required_properties():
         created=now,
         modified=now,
         sighting_of_ref=INDICATOR_ID,
-        where_sighted_refs=[IDENTITY_ID],
+        where_sighted_refs=[IDENTITY_ID, LOCATION_ID],
     )
     assert str(s) == EXPECTED_SIGHTING
 
@@ -101,6 +104,7 @@ def test_create_sighting_from_objects_rather_than_ids(malware):  # noqa: F811
             "type": "sighting",
             "where_sighted_refs": [
                 IDENTITY_ID,
+                LOCATION_ID,
             ],
         },
     ],
@@ -114,4 +118,4 @@ def test_parse_sighting(data):
     assert sighting.created == dt.datetime(2016, 4, 6, 20, 6, 37, tzinfo=pytz.utc)
     assert sighting.modified == dt.datetime(2016, 4, 6, 20, 6, 37, tzinfo=pytz.utc)
     assert sighting.sighting_of_ref == INDICATOR_ID
-    assert sighting.where_sighted_refs == [IDENTITY_ID]
+    assert sighting.where_sighted_refs == [IDENTITY_ID, LOCATION_ID]