Files
2024-02-15 17:01:50 +00:00

1950 lines
54 KiB
Python

from copy import deepcopy
import pytest
from sentry.backup.comparators import (
AutoSuffixComparator,
DatetimeEqualityComparator,
DateUpdatedComparator,
EmailObfuscatingComparator,
EqualOrRemovedComparator,
ForeignKeyComparator,
HashObfuscatingComparator,
IgnoredComparator,
ScrubbedData,
SecretHexComparator,
SubscriptionIDComparator,
UnorderedListComparator,
UserPasswordObfuscatingComparator,
UUID4Comparator,
)
from sentry.backup.dependencies import ImportKind, NormalizedModelName, PrimaryKeyMap, dependencies
from sentry.backup.findings import ComparatorFindingKind, InstanceID
from sentry.utils.json import JSONData
def test_good_comparator_both_sides_existing():
cmp = DateUpdatedComparator("my_date_field")
id = InstanceID("sentry.test", 0)
present: JSONData = {
"model": "test",
"ordinal": 1,
"pk": 1,
"fields": {
"my_date_field": "2023-06-22T23:12:34.567Z",
},
}
assert not cmp.existence(id, present, present)
def test_good_comparator_neither_side_existing():
cmp = DateUpdatedComparator("my_date_field")
id = InstanceID("sentry.test", 0)
missing: JSONData = {
"model": "test",
"ordinal": 1,
"pk": 1,
"fields": {},
}
assert not cmp.existence(id, missing, missing)
def test_bad_comparator_only_one_side_existing():
cmp = DateUpdatedComparator("my_date_field")
id = InstanceID("sentry.test", 0)
present: JSONData = {
"model": "test",
"ordinal": 1,
"pk": 1,
"fields": {
"my_date_field": "2023-06-22T23:12:34.567Z",
},
}
missing: JSONData = {
"model": "test",
"ordinal": 1,
"pk": 1,
"fields": {},
}
res = cmp.existence(id, missing, present)
assert res
assert len(res) == 1
assert res[0]
assert res[0].on == id
assert res[0].kind == ComparatorFindingKind.DateUpdatedComparatorExistenceCheck
assert res[0].left_pk == 1
assert res[0].right_pk == 1
assert "left" in res[0].reason
assert "my_date_field" in res[0].reason
res = cmp.existence(id, present, missing)
assert res
assert len(res) == 1
assert res[0]
assert res[0].kind == ComparatorFindingKind.DateUpdatedComparatorExistenceCheck
assert res[0].on == id
assert res[0].left_pk == 1
assert res[0].right_pk == 1
assert "right" in res[0].reason
assert "my_date_field" in res[0].reason
def test_good_comparator_both_sides_null():
cmp = DateUpdatedComparator("my_date_field")
id = InstanceID("sentry.test", 0)
nulled: JSONData = {
"model": "test",
"ordinal": 1,
"pk": 1,
"fields": {
"my_date_field": None,
},
}
assert not cmp.existence(id, nulled, nulled)
def test_bad_comparator_only_one_side_null():
cmp = DateUpdatedComparator("my_date_field")
id = InstanceID("sentry.test", 0)
present: JSONData = {
"model": "test",
"ordinal": 1,
"pk": 1,
"fields": {
"my_date_field": "2023-06-22T23:12:34.567Z",
},
}
nulled: JSONData = {
"model": "test",
"ordinal": 1,
"pk": 1,
"fields": {
"my_date_field": None,
},
}
res = cmp.existence(id, nulled, present)
assert res
assert len(res) == 1
assert res[0]
assert res[0].on == id
assert res[0].kind == ComparatorFindingKind.DateUpdatedComparatorExistenceCheck
assert res[0].left_pk == 1
assert res[0].right_pk == 1
assert "left" in res[0].reason
assert "my_date_field" in res[0].reason
res = cmp.existence(id, present, nulled)
assert res
assert len(res) == 1
assert res[0]
assert res[0].kind == ComparatorFindingKind.DateUpdatedComparatorExistenceCheck
assert res[0].on == id
assert res[0].left_pk == 1
assert res[0].right_pk == 1
assert "right" in res[0].reason
assert "my_date_field" in res[0].reason
def test_good_comparator_one_side_null_other_side_missing():
cmp = DateUpdatedComparator("my_date_field")
id = InstanceID("sentry.test", 0)
nulled: JSONData = {
"model": "test",
"ordinal": 1,
"pk": 1,
"fields": {
"my_date_field": None,
},
}
missing: JSONData = {
"model": "test",
"ordinal": 1,
"pk": 1,
"fields": {},
}
res = cmp.existence(id, missing, nulled)
assert not res
res = cmp.existence(id, nulled, missing)
assert not res
def test_good_auto_suffix_comparator():
cmp = AutoSuffixComparator("same", "suffixed")
id = InstanceID("sentry.test", 0)
left: JSONData = {
"model": "test",
"ordinal": 1,
"pk": 1,
"fields": {
"same": "foo-bar",
"suffixed": "foo-bar",
},
}
right: JSONData = {
"model": "test",
"ordinal": 1,
"pk": 1,
"fields": {
"same": "foo-bar",
"suffixed": "foo-bar-baz",
},
}
assert not cmp.compare(id, left, right)
def test_bad_auto_suffix_comparator():
cmp = AutoSuffixComparator("same", "suffixed")
id = InstanceID("sentry.test", 0)
left: JSONData = {
"model": "test",
"ordinal": 1,
"pk": 1,
"fields": {
"same": "foo-bar",
"suffixed": "foo-bar",
},
}
right: JSONData = {
"model": "test",
"ordinal": 1,
"pk": 1,
"fields": {
"same": "unequal",
"suffixed": "foo-barbaz",
},
}
res = cmp.compare(id, left, right)
assert res
assert len(res) == 2
assert res[0]
assert res[0].kind == ComparatorFindingKind.AutoSuffixComparator
assert res[0].on == id
assert res[0].left_pk == 1
assert res[0].right_pk == 1
assert "foo-bar" in res[0].reason
assert "unequal" in res[0].reason
assert res[1]
assert res[1].kind == ComparatorFindingKind.AutoSuffixComparator
assert res[1].on == id
assert res[1].left_pk == 1
assert res[1].right_pk == 1
assert "foo-bar" in res[1].reason
assert "foo-barbaz" in res[1].reason
def test_good_auto_suffix_comparator_existence():
cmp = AutoSuffixComparator("auto_suffix_field")
id = InstanceID("sentry.test", 0)
present: JSONData = {
"model": "test",
"ordinal": 1,
"pk": 1,
"fields": {
"auto_suffix_field": "foo-bar",
},
}
missing: JSONData = {
"model": "test",
"ordinal": 1,
"pk": 1,
"fields": {},
}
res = cmp.existence(id, missing, present)
assert res
assert len(res) == 1
assert res[0]
assert res[0].on == id
assert res[0].kind == ComparatorFindingKind.AutoSuffixComparatorExistenceCheck
assert res[0].left_pk == 1
assert res[0].right_pk == 1
assert "left" in res[0].reason
assert "`auto_suffix_field`" in res[0].reason
def test_good_auto_suffix_comparator_scrubbed():
cmp = AutoSuffixComparator("same", "suffixed")
left: JSONData = {
"model": "test",
"ordinal": 1,
"pk": 1,
"fields": {
"same": "foo-bar",
"suffixed": "foo-bar",
},
}
right: JSONData = {
"model": "test",
"ordinal": 1,
"pk": 1,
"fields": {
"same": "foo-bar",
"suffixed": "foo-bar-baz",
},
}
cmp.scrub(left, right)
assert left["scrubbed"]
assert left["scrubbed"]["AutoSuffixComparator::same"] is ScrubbedData()
assert left["scrubbed"]["AutoSuffixComparator::suffixed"] is ScrubbedData()
assert right["scrubbed"]
assert right["scrubbed"]["AutoSuffixComparator::same"] is ScrubbedData()
assert right["scrubbed"]["AutoSuffixComparator::suffixed"] is ScrubbedData()
def test_good_datetime_equality_comparator():
cmp = DatetimeEqualityComparator("my_date_field")
id = InstanceID("sentry.test", 0)
left: JSONData = {
"model": "test",
"ordinal": 1,
"pk": 1,
"fields": {
"my_date_field": "2023-06-22T23:00:00.123Z",
},
}
right: JSONData = {
"model": "test",
"ordinal": 1,
"pk": 1,
"fields": {
"my_date_field": "2023-06-22T23:00:00.123Z",
},
}
assert not cmp.compare(id, left, right)
def test_bad_datetime_equality_comparator():
cmp = DatetimeEqualityComparator("my_date_field")
id = InstanceID("sentry.test", 0)
left: JSONData = {
"model": "test",
"ordinal": 1,
"pk": 1,
"fields": {
"my_date_field": "2023-06-22T00:00:00.000Z",
},
}
right: JSONData = {
"model": "test",
"ordinal": 1,
"pk": 1,
"fields": {
"my_date_field": "2023-06-22T00:00:00.123Z",
},
}
res = cmp.compare(id, left, right)
assert res
assert len(res) == 1
assert res[0]
assert res[0].kind == ComparatorFindingKind.DatetimeEqualityComparator
assert res[0].on == id
assert res[0].left_pk == 1
assert res[0].right_pk == 1
assert "`my_date_field`" in res[0].reason
assert "left value (2023-06-22T00:00:00.000Z)" in res[0].reason
assert "right value (2023-06-22T00:00:00.123Z)" in res[0].reason
def test_good_date_updated_comparator():
cmp = DateUpdatedComparator("my_date_field")
id = InstanceID("sentry.test", 0)
left: JSONData = {
"model": "test",
"ordinal": 1,
"pk": 1,
"fields": {
"my_date_field": "2023-06-22T23:00:00.123Z",
},
}
right: JSONData = {
"model": "test",
"ordinal": 1,
"pk": 1,
"fields": {
"my_date_field": "2023-06-22T23:00:00.123Z",
},
}
assert not cmp.compare(id, left, right)
def test_bad_date_updated_comparator():
cmp = DateUpdatedComparator("my_date_field")
id = InstanceID("sentry.test", 0)
left: JSONData = {
"model": "test",
"ordinal": 1,
"pk": 1,
"fields": {
"my_date_field": "2023-06-22T23:12:34.567Z",
},
}
right: JSONData = {
"model": "test",
"ordinal": 1,
"pk": 1,
"fields": {
"my_date_field": "2023-06-22T23:00:00.001Z",
},
}
res = cmp.compare(id, left, right)
assert res
assert len(res) == 1
assert res[0]
assert res[0].kind == ComparatorFindingKind.DateUpdatedComparator
assert res[0].on == id
assert res[0].left_pk == 1
assert res[0].right_pk == 1
assert "`my_date_field`" in res[0].reason
assert "left value (2023-06-22T23:12:34.567Z)" in res[0].reason
assert "right value (2023-06-22T23:00:00.001Z)" in res[0].reason
def test_good_email_obfuscating_comparator():
cmp = EmailObfuscatingComparator("one_email", "many_emails")
id = InstanceID("sentry.test", 0)
model = {
"model": "test",
"ordinal": 1,
"pk": 1,
"fields": {
"one_email": "[email protected]",
"many_emails": [
"[email protected]",
"[email protected]",
],
},
}
assert not cmp.compare(id, model, model)
def test_bad_email_obfuscating_comparator():
cmp = EmailObfuscatingComparator("one_email", "many_emails")
id = InstanceID("sentry.test", 0)
left: JSONData = {
"model": "test",
"ordinal": 1,
"pk": 1,
"fields": {
"one_email": "[email protected]",
"many_emails": [
"[email protected]",
"[email protected]",
],
},
}
right: JSONData = {
"model": "test",
"ordinal": 1,
"pk": 1,
"fields": {
"one_email": "[email protected]",
"many_emails": [
"[email protected]",
"[email protected]",
],
},
}
res = cmp.compare(id, left, right)
assert res
assert len(res) == 2
assert res[0]
assert res[0].kind == ComparatorFindingKind.EmailObfuscatingComparator
assert res[0].on == id
assert res[0].left_pk == 1
assert res[0].right_pk == 1
assert "[email protected]" in res[0].reason
assert "[email protected]" in res[0].reason
assert res[1]
assert res[1].kind == ComparatorFindingKind.EmailObfuscatingComparator
assert res[1].on == id
assert res[1].left_pk == 1
assert res[1].right_pk == 1
assert "[email protected]" in res[1].reason
assert "[email protected]" in res[1].reason
def test_good_email_obfuscating_comparator_existence():
cmp = EmailObfuscatingComparator("email_obfuscating_field")
id = InstanceID("sentry.test", 0)
present: JSONData = {
"model": "test",
"ordinal": 1,
"pk": 1,
"fields": {
"email_obfuscating_field": "[email protected]",
},
}
missing: JSONData = {
"model": "test",
"ordinal": 1,
"pk": 1,
"fields": {},
}
res = cmp.existence(id, missing, present)
assert res
assert len(res) == 1
assert res[0]
assert res[0].on == id
assert res[0].kind == ComparatorFindingKind.EmailObfuscatingComparatorExistenceCheck
assert res[0].left_pk == 1
assert res[0].right_pk == 1
assert "left" in res[0].reason
assert "`email_obfuscating_field`" in res[0].reason
def test_good_email_obfuscating_comparator_scrubbed():
cmp = EmailObfuscatingComparator("one_email", "many_emails")
left: JSONData = {
"model": "test",
"ordinal": 1,
"pk": 1,
"fields": {
"one_email": "[email protected]",
"many_emails": [
"[email protected]",
"[email protected]",
],
},
}
right: JSONData = {
"model": "test",
"ordinal": 1,
"pk": 1,
"fields": {
"one_email": "[email protected]",
"many_emails": [
"[email protected]",
"[email protected]",
],
},
}
cmp.scrub(left, right)
assert left["scrubbed"]
assert left["scrubbed"]["EmailObfuscatingComparator::one_email"] == ["[email protected]"]
assert left["scrubbed"]["EmailObfuscatingComparator::many_emails"] == [
"[email protected]",
"[email protected]",
]
assert right["scrubbed"]
assert right["scrubbed"]["EmailObfuscatingComparator::one_email"] == ["[email protected]"]
assert right["scrubbed"]["EmailObfuscatingComparator::many_emails"] == [
"[email protected]",
"[email protected]",
]
def test_good_equal_or_removed_comparator_equal():
cmp = EqualOrRemovedComparator("my_field")
id = InstanceID("sentry.test", 0)
present: JSONData = {
"model": "test",
"ordinal": 1,
"pk": 1,
"fields": {
"my_field": "foo",
},
}
assert not cmp.existence(id, present, present)
assert not cmp.compare(id, present, present)
def test_good_equal_or_removed_comparator_not_equal():
cmp = EqualOrRemovedComparator("my_field")
id = InstanceID("sentry.test", 0)
left: JSONData = {
"model": "test",
"ordinal": 1,
"pk": 1,
"fields": {
"my_field": "foo",
},
}
right: JSONData = {
"model": "test",
"ordinal": 1,
"pk": 1,
"fields": {
"my_field": "bar",
},
}
assert not cmp.existence(id, left, right)
res = cmp.compare(id, left, right)
assert res
assert len(res) == 1
assert res[0]
assert res[0].kind == ComparatorFindingKind.EqualOrRemovedComparator
assert res[0].on == id
assert res[0].left_pk == 1
assert res[0].right_pk == 1
assert "my_field" in res[0].reason
assert "foo" in res[0].reason
assert "bar" in res[0].reason
def test_good_equal_or_removed_comparator_neither_side_existing():
cmp = EqualOrRemovedComparator("my_field")
id = InstanceID("sentry.test", 0)
missing: JSONData = {
"model": "test",
"ordinal": 1,
"pk": 1,
"fields": {},
}
assert not cmp.existence(id, missing, missing)
def test_good_equal_or_removed_comparator_only_right_side_missing():
cmp = EqualOrRemovedComparator("my_field")
id = InstanceID("sentry.test", 0)
present: JSONData = {
"model": "test",
"ordinal": 1,
"pk": 1,
"fields": {
"my_field": "foo",
},
}
missing: JSONData = {
"model": "test",
"ordinal": 1,
"pk": 1,
"fields": {},
}
assert not cmp.existence(id, present, missing)
assert not cmp.compare(id, present, missing)
def test_bad_equal_or_removed_comparator_only_left_side_missing():
cmp = EqualOrRemovedComparator("my_field")
id = InstanceID("sentry.test", 0)
present: JSONData = {
"model": "test",
"ordinal": 1,
"pk": 1,
"fields": {
"my_field": "foo",
},
}
missing: JSONData = {
"model": "test",
"ordinal": 1,
"pk": 1,
"fields": {},
}
res = cmp.existence(id, missing, present)
assert res
assert len(res) == 1
assert res[0]
assert res[0].on == id
assert res[0].kind == ComparatorFindingKind.EqualOrRemovedComparatorExistenceCheck
assert res[0].left_pk == 1
assert res[0].right_pk == 1
assert "left" in res[0].reason
assert "my_field" in res[0].reason
def test_good_equal_or_removed_comparator_both_sides_nulled():
cmp = EqualOrRemovedComparator("my_field")
id = InstanceID("sentry.test", 0)
nulled: JSONData = {
"model": "test",
"ordinal": 1,
"pk": 1,
"fields": {
"my_field": None,
},
}
assert not cmp.existence(id, nulled, nulled)
def test_good_equal_or_removed_comparator_only_right_side_nulled():
cmp = EqualOrRemovedComparator("my_field")
id = InstanceID("sentry.test", 0)
present: JSONData = {
"model": "test",
"ordinal": 1,
"pk": 1,
"fields": {
"my_field": "foo",
},
}
missing: JSONData = {
"model": "test",
"ordinal": 1,
"pk": 1,
"fields": {
"my_field": None,
},
}
assert not cmp.existence(id, present, missing)
assert not cmp.compare(id, present, missing)
def test_bad_equal_or_removed_comparator_only_left_side_nulled():
cmp = EqualOrRemovedComparator("my_field")
id = InstanceID("sentry.test", 0)
present: JSONData = {
"model": "test",
"ordinal": 1,
"pk": 1,
"fields": {
"my_field": "foo",
},
}
missing: JSONData = {
"model": "test",
"ordinal": 1,
"pk": 1,
"fields": {
"my_field": None,
},
}
res = cmp.existence(id, missing, present)
assert res
assert len(res) == 1
assert res[0]
assert res[0].on == id
assert res[0].kind == ComparatorFindingKind.EqualOrRemovedComparatorExistenceCheck
assert res[0].left_pk == 1
assert res[0].right_pk == 1
assert "left" in res[0].reason
assert "my_field" in res[0].reason
def test_good_hash_obfuscating_comparator():
cmp = HashObfuscatingComparator("one_hash", "many_hashes")
id = InstanceID("sentry.test", 0)
model: JSONData = {
"model": "test",
"ordinal": 1,
"pk": 1,
"fields": {
"one_hash": "1239fe0ab0afc39b",
"many_hashes": [
"190dae4e",
"1234",
],
},
}
assert not cmp.compare(id, model, model)
def test_bad_hash_obfuscating_comparator():
cmp = HashObfuscatingComparator("one_hash", "many_hashes")
id = InstanceID("sentry.test", 0)
left: JSONData = {
"model": "test",
"ordinal": 1,
"pk": 1,
"fields": {
"one_hash": "1239fe0ab0afc39b",
"many_hashes": [
"190dae4e",
"1234",
],
},
}
right: JSONData = {
"model": "test",
"ordinal": 1,
"pk": 1,
"fields": {
"one_hash": "1249fe0ab0afc39c",
"many_hashes": [
"290dae4f",
"1234",
],
},
}
res = cmp.compare(id, left, right)
assert res
assert len(res) == 2
assert res[0]
assert res[0].kind == ComparatorFindingKind.HashObfuscatingComparator
assert res[0].on == id
assert res[0].left_pk == 1
assert res[0].right_pk == 1
assert "1...e" in res[0].reason
assert "2...f" in res[0].reason
assert res[1]
assert res[1].kind == ComparatorFindingKind.HashObfuscatingComparator
assert res[1].on == id
assert res[1].left_pk == 1
assert res[1].right_pk == 1
assert "123...39b" in res[1].reason
assert "124...39c" in res[1].reason
def test_good_hash_obfuscating_comparator_existence():
cmp = HashObfuscatingComparator("hash_obfuscating_field")
id = InstanceID("sentry.test", 0)
present: JSONData = {
"model": "test",
"ordinal": 1,
"pk": 1,
"fields": {
"hash_obfuscating_field": "foo",
},
}
missing: JSONData = {
"model": "test",
"ordinal": 1,
"pk": 1,
"fields": {},
}
res = cmp.existence(id, missing, present)
assert res
assert len(res) == 1
assert res[0]
assert res[0].on == id
assert res[0].kind == ComparatorFindingKind.HashObfuscatingComparatorExistenceCheck
assert res[0].left_pk == 1
assert res[0].right_pk == 1
assert "left" in res[0].reason
assert "`hash_obfuscating_field`" in res[0].reason
def test_good_hash_obfuscating_comparator_scrubbed():
cmp = HashObfuscatingComparator("one_hash", "many_hashes")
left: JSONData = {
"model": "test",
"ordinal": 1,
"pk": 1,
"fields": {
"one_hash": "1239fe0ab0afc39b",
"many_hashes": [
"190dae4e",
"1234",
],
},
}
right: JSONData = {
"model": "test",
"ordinal": 1,
"pk": 1,
"fields": {
"one_hash": "1249fe0ab0afc39c",
"many_hashes": [
"290dae4f",
"1234",
],
},
}
cmp.scrub(left, right)
assert left["scrubbed"]
assert left["scrubbed"]["HashObfuscatingComparator::one_hash"] == ["123...39b"]
assert left["scrubbed"]["HashObfuscatingComparator::many_hashes"] == [
"1...e",
"...",
]
assert right["scrubbed"]
assert right["scrubbed"]["HashObfuscatingComparator::one_hash"] == ["124...39c"]
assert right["scrubbed"]["HashObfuscatingComparator::many_hashes"] == [
"2...f",
"...",
]
def test_good_foreign_key_comparator():
deps = dependencies()
cmp = ForeignKeyComparator(
{k: v.model for k, v in deps[NormalizedModelName("sentry.UserEmail")].foreign_keys.items()}
)
id = InstanceID("sentry.useremail", 0)
left_pk_map = PrimaryKeyMap()
left_pk_map.insert(NormalizedModelName("sentry.user"), 12, 1, ImportKind.Inserted)
right_pk_map = PrimaryKeyMap()
right_pk_map.insert(NormalizedModelName("sentry.user"), 34, 1, ImportKind.Inserted)
left: JSONData = {
"model": "test",
"ordinal": 1,
"pk": 1,
"fields": {
"user": 12,
"email": "[email protected]",
"validation_hash": "ABC123",
"date_hash_added": "2023-06-23T00:00:00.000Z",
"is_verified": True,
},
}
right: JSONData = {
"model": "test",
"ordinal": 1,
"pk": 1,
"fields": {
"user": 34,
"email": "[email protected]",
"validation_hash": "ABC123",
"date_hash_added": "2023-06-23T00:00:00.000Z",
"is_verified": True,
},
}
cmp.set_primary_key_maps(left_pk_map, right_pk_map)
assert not cmp.compare(id, left, right)
def test_good_foreign_key_comparator_existence():
deps = dependencies()
cmp = ForeignKeyComparator(
{k: v.model for k, v in deps[NormalizedModelName("sentry.UserEmail")].foreign_keys.items()}
)
id = InstanceID("sentry.test", 0)
present: JSONData = {
"model": "test",
"ordinal": 1,
"pk": 1,
"fields": {
"user": 12,
"email": "[email protected]",
"validation_hash": "ABC123",
"date_hash_added": "2023-06-23T00:00:00.000Z",
"is_verified": True,
},
}
missing: JSONData = {
"model": "test",
"ordinal": 1,
"pk": 1,
"fields": {
"email": "[email protected]",
"validation_hash": "ABC123",
"date_hash_added": "2023-06-23T00:00:00.000Z",
"is_verified": True,
},
}
res = cmp.existence(id, missing, present)
assert res
assert len(res) == 1
assert res[0]
assert res[0].on == id
assert res[0].kind == ComparatorFindingKind.ForeignKeyComparatorExistenceCheck
assert res[0].left_pk == 1
assert res[0].right_pk == 1
assert "left" in res[0].reason
assert "`user`" in res[0].reason
def test_good_foreign_key_comparator_scrubbed():
deps = dependencies()
cmp = ForeignKeyComparator(
{k: v.model for k, v in deps[NormalizedModelName("sentry.UserEmail")].foreign_keys.items()}
)
left: JSONData = {
"model": "test",
"ordinal": 1,
"pk": 1,
"fields": {
"user": 12,
"email": "[email protected]",
"validation_hash": "ABC123",
"date_hash_added": "2023-06-23T00:00:00.000Z",
"is_verified": True,
},
}
right = deepcopy(left)
cmp.scrub(left, right)
assert left["scrubbed"]
assert left["scrubbed"]["ForeignKeyComparator::user"] is ScrubbedData()
assert right["scrubbed"]
assert right["scrubbed"]["ForeignKeyComparator::user"] is ScrubbedData()
def test_bad_foreign_key_comparator_set_primary_key_maps_not_called():
deps = dependencies()
cmp = ForeignKeyComparator(
{k: v.model for k, v in deps[NormalizedModelName("sentry.UserEmail")].foreign_keys.items()}
)
id = InstanceID("sentry.useremail", 0)
left_pk_map = PrimaryKeyMap()
left_pk_map.insert(NormalizedModelName("sentry.user"), 12, 1, ImportKind.Inserted)
right_pk_map = PrimaryKeyMap()
right_pk_map.insert(NormalizedModelName("sentry.user"), 34, 1, ImportKind.Inserted)
left: JSONData = {
"model": "test",
"ordinal": 1,
"pk": 1,
"fields": {
"user": 12,
"email": "[email protected]",
"validation_hash": "ABC123",
"date_hash_added": "2023-06-23T00:00:00.000Z",
"is_verified": True,
},
}
right: JSONData = {
"model": "test",
"ordinal": 1,
"pk": 1,
"fields": {
"user": 34,
"email": "[email protected]",
"validation_hash": "ABC123",
"date_hash_added": "2023-06-23T00:00:00.000Z",
"is_verified": True,
},
}
with pytest.raises(RuntimeError):
cmp.compare(id, left, right)
def test_bad_foreign_key_comparator_unequal_mapping():
deps = dependencies()
cmp = ForeignKeyComparator(
{k: v.model for k, v in deps[NormalizedModelName("sentry.UserEmail")].foreign_keys.items()}
)
id = InstanceID("sentry.useremail", 0)
left_pk_map = PrimaryKeyMap()
left_pk_map.insert(NormalizedModelName("sentry.user"), 12, 1, ImportKind.Inserted)
right_pk_map = PrimaryKeyMap()
right_pk_map.insert(NormalizedModelName("sentry.user"), 34, 2, ImportKind.Inserted)
left: JSONData = {
"model": "test",
"ordinal": 1,
"pk": 1,
"fields": {
"user": 12,
"email": "[email protected]",
"validation_hash": "ABC123",
"date_hash_added": "2023-06-23T00:00:00.000Z",
"is_verified": True,
},
}
right: JSONData = {
"model": "test",
"ordinal": 1,
"pk": 1,
"fields": {
"user": 34,
"email": "[email protected]",
"validation_hash": "ABC123",
"date_hash_added": "2023-06-23T00:00:00.000Z",
"is_verified": True,
},
}
cmp.set_primary_key_maps(left_pk_map, right_pk_map)
res = cmp.compare(id, left, right)
assert res
assert len(res) == 1
assert res[0]
assert res[0].kind == ComparatorFindingKind.ForeignKeyComparator
assert res[0].on == id
assert res[0].left_pk == 1
assert res[0].right_pk == 1
assert "`user`" in res[0].reason
assert "left foreign key ordinal (1)" in res[0].reason
assert "right foreign key ordinal (2)" in res[0].reason
def test_bad_foreign_key_comparator_missing_mapping():
deps = dependencies()
cmp = ForeignKeyComparator(
{k: v.model for k, v in deps[NormalizedModelName("sentry.UserEmail")].foreign_keys.items()}
)
id = InstanceID("sentry.useremail", 0)
left_pk_map = PrimaryKeyMap()
right_pk_map = PrimaryKeyMap()
left: JSONData = {
"model": "test",
"ordinal": 1,
"pk": 1,
"fields": {
"user": 12,
"email": "[email protected]",
"validation_hash": "ABC123",
"date_hash_added": "2023-06-23T00:00:00.000Z",
"is_verified": True,
},
}
right: JSONData = {
"model": "test",
"ordinal": 1,
"pk": 1,
"fields": {
"user": 34,
"email": "[email protected]",
"validation_hash": "ABC123",
"date_hash_added": "2023-06-23T00:00:00.000Z",
"is_verified": True,
},
}
cmp.set_primary_key_maps(left_pk_map, right_pk_map)
res = cmp.compare(id, left, right)
assert len(res) == 2
assert res[0]
assert res[0].kind == ComparatorFindingKind.ForeignKeyComparator
assert res[0].on == id
assert res[0].left_pk == 1
assert res[0].right_pk == 1
assert "`user`" in res[0].reason
assert "left foreign key ordinal" in res[0].reason
assert "pk `12`" in res[0].reason
assert res[1]
assert res[1].kind == ComparatorFindingKind.ForeignKeyComparator
assert res[1].on == id
assert res[1].left_pk == 1
assert res[1].right_pk == 1
assert "`user`" in res[1].reason
assert "right foreign key ordinal" in res[1].reason
assert "pk `34`" in res[1].reason
def test_good_ignored_comparator():
cmp = IgnoredComparator("ignored_field")
id = InstanceID("sentry.test", 0)
model: JSONData = {
"model": "test",
"ordinal": 1,
"pk": 1,
"fields": {
"ignored_field": "IGNORE_ME!",
"other_field": "...but still look at me",
},
}
assert not cmp.compare(id, model, model)
def test_good_ignored_comparator_existence():
cmp = IgnoredComparator("ignored_field")
id = InstanceID("sentry.test", 0)
present: JSONData = {
"model": "test",
"ordinal": 1,
"pk": 1,
"fields": {
"ignored_field": "foo",
},
}
missing: JSONData = {
"model": "test",
"ordinal": 1,
"pk": 1,
"fields": {},
}
res = cmp.existence(id, missing, present)
assert not res
def test_good_ignored_comparator_scrubbed():
cmp = IgnoredComparator("ignored_field")
left: JSONData = {
"model": "test",
"ordinal": 1,
"pk": 1,
"fields": {
"ignored_field": "IGNORE_ME!",
"other_field": "...but still look at me",
},
}
right = deepcopy(left)
cmp.scrub(left, right)
assert left["scrubbed"]
assert left["scrubbed"]["IgnoredComparator::ignored_field"] is ScrubbedData()
assert left["scrubbed"].get("IgnoredComparator::other_field") is None
assert right["scrubbed"]
assert right["scrubbed"]["IgnoredComparator::ignored_field"] is ScrubbedData()
assert right["scrubbed"].get("IgnoredComparator::other_field") is None
def test_good_secret_hex_comparator():
cmp = SecretHexComparator(8, "equal", "unequal")
id = InstanceID("sentry.test", 0)
left: JSONData = {
"model": "test",
"ordinal": 1,
"pk": 1,
"fields": {
"equal": "3e04f551c7219550",
"unequal": "3e04f551c7219550",
},
}
right: JSONData = {
"model": "test",
"ordinal": 1,
"pk": 1,
"fields": {
"equal": "3e04f551c7219550",
"unequal": "50a7e2c7e3ca35fc",
},
}
assert not cmp.compare(id, left, right)
def test_bad_secret_hex_comparator():
cmp = SecretHexComparator(8, "same", "invalid_left", "invalid_right")
id = InstanceID("sentry.test", 0)
left: JSONData = {
"model": "test",
"ordinal": 1,
"pk": 1,
"fields": {
"same": "3e04f551c7219550",
"invalid_left": "foo",
"invalid_right": "50a7e2c7e3ca35fc",
},
}
right: JSONData = {
"model": "test",
"ordinal": 1,
"pk": 1,
"fields": {
"same": "3e04f551c7219550",
"invalid_left": "50a7e2c7e3ca35fc",
"invalid_right": "bar",
},
}
res = cmp.compare(id, left, right)
assert res
assert len(res) == 2
assert res[0]
assert res[0].kind == ComparatorFindingKind.SecretHexComparator
assert res[0].on == id
assert res[0].left_pk == 1
assert res[0].right_pk == 1
assert "`invalid_left`" in res[0].reason
assert "left" in res[0].reason
assert "regex" in res[0].reason
assert "foo" in res[0].reason
assert res[1]
assert res[1].kind == ComparatorFindingKind.SecretHexComparator
assert res[1].on == id
assert res[1].left_pk == 1
assert res[1].right_pk == 1
assert "`invalid_right`" in res[1].reason
assert "right" in res[1].reason
assert "regex" in res[1].reason
assert "bar" in res[1].reason
def test_good_secret_hex_comparator_scrubbed():
cmp = SecretHexComparator(8, "secret_hex_field")
left: JSONData = {
"model": "test",
"ordinal": 1,
"pk": 1,
"fields": {
"secret_hex_field": "3e04f551c7219550",
},
}
right: JSONData = {
"model": "test",
"ordinal": 1,
"pk": 1,
"fields": {
"secret_hex_field": "3e04f551c7219550",
},
}
cmp.scrub(left, right)
assert left["scrubbed"]
assert left["scrubbed"]["SecretHexComparator::secret_hex_field"] is ScrubbedData()
assert right["scrubbed"]
assert right["scrubbed"]["SecretHexComparator::secret_hex_field"] is ScrubbedData()
def test_good_subscription_id_comparator():
cmp = SubscriptionIDComparator("subscription_id_field")
id = InstanceID("sentry.test", 0)
left: JSONData = {
"model": "test",
"ordinal": 1,
"pk": 1,
"fields": {
"subscription_id_field": "0/12363aae153911eeac590242ac130004",
},
}
right: JSONData = {
"model": "test",
"ordinal": 1,
"pk": 1,
"fields": {
"subscription_id_field": "0/45663aae153911eeac590242acabc123",
},
}
assert not cmp.compare(id, left, right)
def test_bad_subscription_id_comparator():
cmp = SubscriptionIDComparator("same", "invalid_left", "invalid_right")
id = InstanceID("sentry.test", 0)
left: JSONData = {
"model": "test",
"ordinal": 1,
"pk": 1,
"fields": {
"same": "0/12363aae153911eeac590242ac130004",
"invalid_left": "12363aae153911eeac590242ac130004",
"invalid_right": "0/12363aae153911eeac590242ac130004",
},
}
right: JSONData = {
"model": "test",
"ordinal": 1,
"pk": 1,
"fields": {
"same": "0/12363aae153911eeac590242ac130004",
"invalid_left": "0/12363aae153911eeac590242ac130004",
"invalid_right": "0/foobar",
},
}
res = cmp.compare(id, left, right)
assert res
assert len(res) == 3
assert res[0]
assert res[0].kind == ComparatorFindingKind.SubscriptionIDComparator
assert res[0].on == id
assert res[0].left_pk == 1
assert res[0].right_pk == 1
assert "`same`" in res[0].reason
assert "equal" in res[0].reason
assert "0/12363aae153911eeac590242ac130004" in res[0].reason
assert res[1]
assert res[1].kind == ComparatorFindingKind.SubscriptionIDComparator
assert res[1].on == id
assert res[1].left_pk == 1
assert res[1].right_pk == 1
assert "`invalid_left`" in res[1].reason
assert "left" in res[1].reason
assert "regex" in res[1].reason
assert "12363aae153911eeac590242ac130004" in res[1].reason
assert res[2]
assert res[2].kind == ComparatorFindingKind.SubscriptionIDComparator
assert res[2].on == id
assert res[2].left_pk == 1
assert res[2].right_pk == 1
assert "`invalid_right`" in res[2].reason
assert "right" in res[2].reason
assert "regex" in res[2].reason
assert "0/foobar" in res[2].reason
def test_good_subscription_id_comparator_existence():
cmp = SubscriptionIDComparator("subscription_id_field")
id = InstanceID("sentry.test", 0)
present: JSONData = {
"model": "test",
"ordinal": 1,
"pk": 1,
"fields": {
"subscription_id_field": "0/45663aae153911eeac590242acabc123",
},
}
missing: JSONData = {
"model": "test",
"ordinal": 1,
"pk": 1,
"fields": {},
}
res = cmp.existence(id, missing, present)
assert res
assert len(res) == 1
assert res[0]
assert res[0].on == id
assert res[0].kind == ComparatorFindingKind.SubscriptionIDComparatorExistenceCheck
assert res[0].left_pk == 1
assert res[0].right_pk == 1
assert "left" in res[0].reason
assert "`subscription_id_field`" in res[0].reason
def test_good_subscription_id_comparator_scrubbed():
cmp = SubscriptionIDComparator("subscription_id_field")
left: JSONData = {
"model": "test",
"ordinal": 1,
"pk": 1,
"fields": {
"subscription_id_field": "0/12363aae153911eeac590242ac130004",
},
}
right: JSONData = {
"model": "test",
"ordinal": 1,
"pk": 1,
"fields": {
"subscription_id_field": "0/45663aae153911eeac590242acabc123",
},
}
cmp.scrub(left, right)
assert left["scrubbed"]
assert left["scrubbed"]["SubscriptionIDComparator::subscription_id_field"] is ScrubbedData()
assert right["scrubbed"]
assert right["scrubbed"]["SubscriptionIDComparator::subscription_id_field"] is ScrubbedData()
def test_good_unordered_list_comparator():
cmp = UnorderedListComparator("ordered", "unordered")
id = InstanceID("sentry.test", 0)
left: JSONData = {
"model": "test",
"ordinal": 1,
"pk": 1,
"fields": {
"ordered": ["a", "b", "c"],
"unordered": ["b", "a", "c"],
},
}
right: JSONData = {
"model": "test",
"ordinal": 1,
"pk": 1,
"fields": {
"ordered": ["a", "b", "c"],
"unordered": ["c", "b", "a"],
},
}
assert not cmp.compare(id, left, right)
def test_bad_unordered_list_comparator():
cmp = UnorderedListComparator("unequal")
id = InstanceID("sentry.test", 0)
left: JSONData = {
"model": "test",
"ordinal": 1,
"pk": 1,
"fields": {
"unequal": ["b", "a"],
},
}
right: JSONData = {
"model": "test",
"ordinal": 1,
"pk": 1,
"fields": {
"unequal": ["a", "b", "c"],
},
}
res = cmp.compare(id, left, right)
assert res
assert len(res) == 1
assert res[0]
assert res[0].kind == ComparatorFindingKind.UnorderedListComparator
assert res[0].on == id
assert res[0].left_pk == 1
assert res[0].right_pk == 1
assert "`unequal`" in res[0].reason
assert "not equal" in res[0].reason
assert "['b', 'a']" in res[0].reason
assert "['a', 'b', 'c']" in res[0].reason
def test_good_unordered_list_comparator_existence():
cmp = UnorderedListComparator("unordered_list_field")
id = InstanceID("sentry.test", 0)
present: JSONData = {
"model": "test",
"ordinal": 1,
"pk": 1,
"fields": {
"unordered_list_field": ["a", "b", "c"],
},
}
missing: JSONData = {
"model": "test",
"ordinal": 1,
"pk": 1,
"fields": {},
}
res = cmp.existence(id, missing, present)
assert res
assert len(res) == 1
assert res[0]
assert res[0].on == id
assert res[0].kind == ComparatorFindingKind.UnorderedListComparatorExistenceCheck
assert res[0].left_pk == 1
assert res[0].right_pk == 1
assert "left" in res[0].reason
assert "`unordered_list_field`" in res[0].reason
def test_good_unordered_list_comparator_scrubbed():
cmp = UnorderedListComparator("unordered_list_field")
left: JSONData = {
"model": "test",
"ordinal": 1,
"pk": 1,
"fields": {
"unordered_list_field": ["a", "b", "c"],
},
}
right: JSONData = {
"model": "test",
"ordinal": 1,
"pk": 1,
"fields": {
"unordered_list_field": ["a", "b", "c"],
},
}
cmp.scrub(left, right)
assert left["scrubbed"]
assert left["scrubbed"]["UnorderedListComparator::unordered_list_field"] is ScrubbedData()
assert right["scrubbed"]
assert right["scrubbed"]["UnorderedListComparator::unordered_list_field"] is ScrubbedData()
def test_good_uuid4_comparator():
cmp = UUID4Comparator("guid_field")
id = InstanceID("sentry.test", 0)
left: JSONData = {
"model": "test",
"ordinal": 1,
"pk": 1,
"fields": {
"guid_field": "4c79eea3-8a71-4b99-b291-1f6a906fbb47",
},
}
right: JSONData = {
"model": "test",
"ordinal": 1,
"pk": 1,
"fields": {
"guid_field": "bb41a040-b413-4b89-aa03-179470d9ee05",
},
}
assert not cmp.compare(id, left, right)
def test_bad_uuid4_comparator():
cmp = UUID4Comparator("same", "invalid_left", "invalid_right")
id = InstanceID("sentry.test", 0)
left: JSONData = {
"model": "test",
"ordinal": 1,
"pk": 1,
"fields": {
"same": "4c79eea3-8a71-4b99-b291-1f6a906fbb47",
"invalid_left": "foo",
"invalid_right": "bb41a040-b413-4b89-aa03-179470d9ee05",
},
}
right: JSONData = {
"model": "test",
"ordinal": 1,
"pk": 1,
"fields": {
"same": "4c79eea3-8a71-4b99-b291-1f6a906fbb47",
"invalid_left": "bb41a040-b413-4b89-aa03-179470d9ee05",
"invalid_right": "bar",
},
}
res = cmp.compare(id, left, right)
assert res
assert len(res) == 3
assert res[0]
assert res[0].kind == ComparatorFindingKind.UUID4Comparator
assert res[0].on == id
assert res[0].left_pk == 1
assert res[0].right_pk == 1
assert "`same`" in res[0].reason
assert "equal" in res[0].reason
assert "4c79eea3-8a71-4b99-b291-1f6a906fbb47" in res[0].reason
assert res[1]
assert res[1].kind == ComparatorFindingKind.UUID4Comparator
assert res[1].on == id
assert res[1].left_pk == 1
assert res[1].right_pk == 1
assert "`invalid_left`" in res[1].reason
assert "left" in res[1].reason
assert "regex" in res[1].reason
assert "foo" in res[1].reason
assert res[2]
assert res[2].kind == ComparatorFindingKind.UUID4Comparator
assert res[2].on == id
assert res[2].left_pk == 1
assert res[2].right_pk == 1
assert "`invalid_right`" in res[2].reason
assert "right" in res[2].reason
assert "regex" in res[2].reason
assert "bar" in res[2].reason
def test_good_uuid4_comparator_scrubbed():
cmp = UUID4Comparator("guid_field")
left: JSONData = {
"model": "test",
"ordinal": 1,
"pk": 1,
"fields": {
"guid_field": "4c79eea3-8a71-4b99-b291-1f6a906fbb47",
},
}
right: JSONData = {
"model": "test",
"ordinal": 1,
"pk": 1,
"fields": {
"guid_field": "4c79eea3-8a71-4b99-b291-1f6a906fbb47",
},
}
cmp.scrub(left, right)
assert left["scrubbed"]
assert left["scrubbed"]["UUID4Comparator::guid_field"] is ScrubbedData()
assert right["scrubbed"]
assert right["scrubbed"]["UUID4Comparator::guid_field"] is ScrubbedData()
def test_good_user_password_obfuscating_comparator_claimed_user():
cmp = UserPasswordObfuscatingComparator()
id = InstanceID("sentry.test", 0)
model: JSONData = {
"model": "test",
"ordinal": 1,
"pk": 1,
"fields": {
"is_unclaimed": False,
"password": "pbkdf2_sha256$260000$3v4Cyy3TAhp14YCB8Zh7Gq$SjB35BELrwwfOCaiz8O/SdbvhXq+l02BRpKtwxOCTiw=",
},
}
assert not cmp.compare(id, model, model)
def test_good_user_password_obfuscating_comparator_newly_unclaimed_user():
cmp = UserPasswordObfuscatingComparator()
id = InstanceID("sentry.test", 0)
left: JSONData = {
"model": "test",
"ordinal": 1,
"pk": 1,
"fields": {
"is_unclaimed": False,
"password": "pbkdf2_sha256$260000$3v4Cyy3TAhp14YCB8Zh7Gq$SjB35BELrwwfOCaiz8O/SdbvhXq+l02BRpKtwxOCTiw=",
},
}
right: JSONData = {
"model": "test",
"ordinal": 1,
"pk": 1,
"fields": {
"is_unclaimed": True,
"password": "pbkdf2_sha256$260000$HabqnqSUf1q5nKLC24gRMF$tEH6ZbeBSx21Pk8DJO2w5+/NiEI77N2MS3D6QF+Qayg=",
},
}
assert not cmp.compare(id, left, right)
def test_good_user_password_obfuscating_comparator_already_unclaimed_user():
cmp = UserPasswordObfuscatingComparator()
id = InstanceID("sentry.test", 0)
left: JSONData = {
"model": "test",
"ordinal": 1,
"pk": 1,
"fields": {
"is_unclaimed": True,
"password": "pbkdf2_sha256$260000$3v4Cyy3TAhp14YCB8Zh7Gq$SjB35BELrwwfOCaiz8O/SdbvhXq+l02BRpKtwxOCTiw=",
},
}
right: JSONData = {
"model": "test",
"ordinal": 1,
"pk": 1,
"fields": {
"is_unclaimed": True,
"password": "pbkdf2_sha256$260000$HabqnqSUf1q5nKLC24gRMF$tEH6ZbeBSx21Pk8DJO2w5+/NiEI77N2MS3D6QF+Qayg=",
},
}
assert not cmp.compare(id, left, right)
def test_bad_user_password_obfuscating_comparator_claimed_user():
cmp = UserPasswordObfuscatingComparator()
id = InstanceID("sentry.test", 0)
left: JSONData = {
"model": "test",
"ordinal": 1,
"pk": 1,
"fields": {
"is_unclaimed": False,
"password": "pbkdf2_sha256$260000$3v4Cyy3TAhp14YCB8Zh7Gq$SjB35BELrwwfOCaiz8O/SdbvhXq+l02BRpKtwxOCTiw=",
},
}
right: JSONData = {
"model": "test",
"ordinal": 1,
"pk": 1,
"fields": {
# Absence of `is_unclaimed` is treated as `False`.
"password": "pbkdf2_sha256$260000$HabqnqSUf1q5nKLC24gRMF$tEH6ZbeBSx21Pk8DJO2w5+/NiEI77N2MS3D6QF+Qayg=",
},
}
res = cmp.compare(id, left, right)
assert res
assert len(res) == 1
assert res[0]
assert res[0].kind == ComparatorFindingKind.UserPasswordObfuscatingComparator
assert res[0].on == id
assert res[0].left_pk == 1
assert res[0].right_pk == 1
assert "`password`" in res[0].reason
assert "pbkdf2_sha25...OCTiw=" in res[0].reason
assert "pbkdf2_sha25...+Qayg=" in res[0].reason
def test_bad_user_password_obfuscating_comparator_newly_unclaimed_user():
cmp = UserPasswordObfuscatingComparator()
id = InstanceID("sentry.test", 0)
left: JSONData = {
"model": "test",
"ordinal": 1,
"pk": 1,
"fields": {
# Absence of `is_unclaimed` is treated as `False`.
"password": "pbkdf2_sha256$260000$3v4Cyy3TAhp14YCB8Zh7Gq$SjB35BELrwwfOCaiz8O/SdbvhXq+l02BRpKtwxOCTiw=",
},
}
right: JSONData = {
"model": "test",
"ordinal": 1,
"pk": 1,
"fields": {
"is_unclaimed": True,
"password": "pbkdf2_sha256$260000$3v4Cyy3TAhp14YCB8Zh7Gq$SjB35BELrwwfOCaiz8O/SdbvhXq+l02BRpKtwxOCTiw=",
},
}
res = cmp.compare(id, left, right)
assert res
assert len(res) == 1
assert res[0]
assert res[0].kind == ComparatorFindingKind.UserPasswordObfuscatingComparator
assert res[0].on == id
assert res[0].left_pk == 1
assert res[0].right_pk == 1
assert "`password`" in res[0].reason
assert res[0].reason.count("pbkdf2_sha25...OCTiw=") == 2
def test_bad_user_password_obfuscating_comparator_already_unclaimed_user():
cmp = UserPasswordObfuscatingComparator()
id = InstanceID("sentry.test", 0)
left: JSONData = {
"model": "test",
"ordinal": 1,
"pk": 1,
"fields": {
"is_unclaimed": True,
"password": "pbkdf2_sha256$260000$3v4Cyy3TAhp14YCB8Zh7Gq$SjB35BELrwwfOCaiz8O/SdbvhXq+l02BRpKtwxOCTiw=",
},
}
right: JSONData = {
"model": "test",
"ordinal": 1,
"pk": 1,
"fields": {
"is_unclaimed": True,
"password": "pbkdf2_sha256$260000$3v4Cyy3TAhp14YCB8Zh7Gq$SjB35BELrwwfOCaiz8O/SdbvhXq+l02BRpKtwxOCTiw=",
},
}
res = cmp.compare(id, left, right)
assert res
assert len(res) == 1
assert res[0]
assert res[0].kind == ComparatorFindingKind.UserPasswordObfuscatingComparator
assert res[0].on == id
assert res[0].left_pk == 1
assert res[0].right_pk == 1
assert "`password`" in res[0].reason
assert res[0].reason.count("pbkdf2_sha25...OCTiw=") == 2
def test_bad_user_password_obfuscating_comparator_impossible_newly_claimed_user():
cmp = UserPasswordObfuscatingComparator()
id = InstanceID("sentry.test", 0)
left: JSONData = {
"model": "test",
"ordinal": 1,
"pk": 1,
"fields": {
"is_unclaimed": True,
"password": "pbkdf2_sha256$260000$3v4Cyy3TAhp14YCB8Zh7Gq$SjB35BELrwwfOCaiz8O/SdbvhXq+l02BRpKtwxOCTiw=",
},
}
right: JSONData = {
"model": "test",
"ordinal": 1,
"pk": 1,
"fields": {
"is_unclaimed": False,
"password": "pbkdf2_sha256$260000$3v4Cyy3TAhp14YCB8Zh7Gq$SjB35BELrwwfOCaiz8O/SdbvhXq+l02BRpKtwxOCTiw=",
},
}
res = cmp.compare(id, left, right)
assert res
assert len(res) == 1
assert res[0]
assert res[0].kind == ComparatorFindingKind.UserPasswordObfuscatingComparator
assert res[0].on == id
assert res[0].left_pk == 1
assert res[0].right_pk == 1
assert "`is_unclaimed`" in res[0].reason
assert "cannot claim" in res[0].reason
def test_good_user_password_obfuscating_comparator_existence():
cmp = UserPasswordObfuscatingComparator()
id = InstanceID("sentry.test", 0)
present: JSONData = {
"model": "test",
"ordinal": 1,
"pk": 1,
"fields": {
"password": "pbkdf2_sha256$260000$3v4Cyy3TAhp14YCB8Zh7Gq$SjB35BELrwwfOCaiz8O/SdbvhXq+l02BRpKtwxOCTiw=",
},
}
missing: JSONData = {
"model": "test",
"ordinal": 1,
"pk": 1,
"fields": {},
}
res = cmp.existence(id, missing, present)
assert res
assert len(res) == 1
assert res[0]
assert res[0].on == id
assert res[0].kind == ComparatorFindingKind.UserPasswordObfuscatingComparatorExistenceCheck
assert res[0].left_pk == 1
assert res[0].right_pk == 1
assert "left" in res[0].reason
assert "`password`" in res[0].reason
def test_good_user_password_obfuscating_comparator_scrubbed_long():
cmp = UserPasswordObfuscatingComparator()
left: JSONData = {
"model": "test",
"ordinal": 1,
"pk": 1,
"fields": {
"is_unclaimed": False,
"password": "pbkdf2_sha256$260000$3v4Cyy3TAhp14YCB8Zh7Gq$SjB35BELrwwfOCaiz8O/SdbvhXq+l02BRpKtwxOCTiw=",
},
}
right: JSONData = {
"model": "test",
"ordinal": 1,
"pk": 1,
"fields": {
"is_unclaimed": True,
"password": "pbkdf2_sha256$260000$HabqnqSUf1q5nKLC24gRMF$tEH6ZbeBSx21Pk8DJO2w5+/NiEI77N2MS3D6QF+Qayg=",
},
}
cmp.scrub(left, right)
assert left["scrubbed"]
assert left["scrubbed"]["UserPasswordObfuscatingComparator::password"] == [
"pbkdf2_sha25...OCTiw="
]
assert right["scrubbed"]
assert right["scrubbed"]["UserPasswordObfuscatingComparator::password"] == [
"pbkdf2_sha25...+Qayg="
]
def test_good_user_password_obfuscating_comparator_scrubbed_medium():
cmp = UserPasswordObfuscatingComparator()
left: JSONData = {
"model": "test",
"ordinal": 1,
"pk": 1,
"fields": {
"is_unclaimed": False,
"password": "sha1$abc123$a0aac0d9559f1e7f4b6931f3918e72ad8ec01c04",
},
}
right: JSONData = {
"model": "test",
"ordinal": 1,
"pk": 1,
"fields": {
"is_unclaimed": True,
"password": "sha1$abc123$1e3c01a9c0b08c3579b50eaf19bf144fa4324d4d",
},
}
cmp.scrub(left, right)
assert left["scrubbed"]
assert left["scrubbed"]["UserPasswordObfuscatingComparator::password"] == ["sha1$a...1c04"]
assert right["scrubbed"]
assert right["scrubbed"]["UserPasswordObfuscatingComparator::password"] == ["sha1$a...4d4d"]
def test_good_user_password_obfuscating_comparator_scrubbed_short():
cmp = UserPasswordObfuscatingComparator()
left: JSONData = {
"model": "test",
"ordinal": 1,
"pk": 1,
"fields": {
"is_unclaimed": False,
"password": "md5$abc$d2315d2c3883695e40598e56792847ab",
},
}
right: JSONData = {
"model": "test",
"ordinal": 1,
"pk": 1,
"fields": {
"is_unclaimed": True,
"password": "md5$abc$161b6bc86389b8b1fe6e8390e9618c9d",
},
}
cmp.scrub(left, right)
assert left["scrubbed"]
assert left["scrubbed"]["UserPasswordObfuscatingComparator::password"] == ["..."]
assert right["scrubbed"]
assert right["scrubbed"]["UserPasswordObfuscatingComparator::password"] == ["..."]