Filter for username constraint events where confirmed=true
Some checks failed
CI / test (push) Has been cancelled
Some checks failed
CI / test (push) Has been cancelled
This commit is contained in:
parent
79d41786a6
commit
40b329a88c
@ -88,20 +88,22 @@ public abstract class AbstractUpdatesHandler<T> implements
|
||||
private KinesisRecord<T> dbUpdateFor(final StreamRecord dbRecord) {
|
||||
Map<String, AttributeValue> oldImage = dbRecord.getOldImage();
|
||||
Map<String, AttributeValue> newImage = dbRecord.getNewImage();
|
||||
if (oldImage == null || oldImage.isEmpty()) {
|
||||
return toKinesisRecord(null, fromDynamoDbImage(newImage));
|
||||
} else if (newImage == null || newImage.isEmpty()) {
|
||||
return toKinesisRecord(fromDynamoDbImage(oldImage), null);
|
||||
}
|
||||
T oldConstraint = fromDynamoDbImage(oldImage);
|
||||
T newConstraint = fromDynamoDbImage(newImage);
|
||||
if (oldConstraint.equals(newConstraint)) {
|
||||
|
||||
final T prev = oldImage == null || oldImage.isEmpty() ? null : fromDynamoDbImage(oldImage);
|
||||
final T next = newImage == null || newImage.isEmpty() ? null : fromDynamoDbImage(newImage);
|
||||
|
||||
if (prev == null && next == null) {
|
||||
return null;
|
||||
} else {
|
||||
return toKinesisRecord(oldConstraint, newConstraint);
|
||||
}
|
||||
|
||||
if (prev != null && prev.equals(next)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return toKinesisRecord(prev, next);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
abstract T fromDynamoDbImage(Map<String, AttributeValue> image);
|
||||
abstract KinesisRecord<T> toKinesisRecord(@Nullable T prev, @Nullable T next);
|
||||
}
|
||||
|
||||
@ -26,8 +26,15 @@ public class FilterUsernameUpdatesHandler extends AbstractUpdatesHandler<Usernam
|
||||
super(kinesisClient, kinesisOutputStream);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
UsernameConstraint fromDynamoDbImage(final Map<String, AttributeValue> image) {
|
||||
return UsernameConstraint.fromItem(image);
|
||||
final UsernameConstraint constraint = UsernameConstraint.fromItem(image);
|
||||
// We only care about confirmed username constraint entries since those indicate a change on the account
|
||||
// that must be propagated to the transparency log.
|
||||
if (!constraint.confirmed()) {
|
||||
return null;
|
||||
}
|
||||
return constraint;
|
||||
}
|
||||
|
||||
KinesisRecord<UsernameConstraint> toKinesisRecord(final @Nullable UsernameConstraint prev, final @Nullable UsernameConstraint next) {
|
||||
|
||||
@ -16,12 +16,15 @@ import java.util.Map;
|
||||
|
||||
record UsernameConstraint(
|
||||
byte[] usernameHash,
|
||||
byte[] aci) {
|
||||
byte[] aci,
|
||||
boolean confirmed) {
|
||||
|
||||
@VisibleForTesting
|
||||
static final String KEY_USERNAME_HASH = "N";
|
||||
@VisibleForTesting
|
||||
static final String ATTR_ACCOUNT_UUID = "U";
|
||||
@VisibleForTesting
|
||||
static final String ATTR_CONFIRMED = "F";
|
||||
|
||||
@Override
|
||||
public boolean equals(final Object o) {
|
||||
@ -31,7 +34,8 @@ record UsernameConstraint(
|
||||
return false;
|
||||
UsernameConstraint usernameConstraint = (UsernameConstraint) o;
|
||||
return Arrays.equals(usernameHash, usernameConstraint.usernameHash) &&
|
||||
Arrays.equals(aci, usernameConstraint.aci);
|
||||
Arrays.equals(aci, usernameConstraint.aci) &&
|
||||
confirmed == usernameConstraint.confirmed;
|
||||
}
|
||||
|
||||
public record Pair(@Nullable UsernameConstraint prev, @Nullable UsernameConstraint next) implements KinesisRecord<UsernameConstraint> {
|
||||
@ -51,6 +55,7 @@ record UsernameConstraint(
|
||||
static UsernameConstraint fromItem(Map<String, AttributeValue> item) {
|
||||
Preconditions.checkNotNull(item.get(KEY_USERNAME_HASH));
|
||||
Preconditions.checkNotNull(item.get(ATTR_ACCOUNT_UUID));
|
||||
Preconditions.checkNotNull(item.get(ATTR_CONFIRMED));
|
||||
|
||||
final byte[] usernameHash = new byte[32];
|
||||
|
||||
@ -60,6 +65,8 @@ record UsernameConstraint(
|
||||
final byte[] uuid = new byte[16];
|
||||
item.get(ATTR_ACCOUNT_UUID).getB().get(uuid);
|
||||
|
||||
return new UsernameConstraint(usernameHash, uuid);
|
||||
final boolean confirmed = item.get(ATTR_CONFIRMED).getBOOL();
|
||||
|
||||
return new UsernameConstraint(usernameHash, uuid, confirmed);
|
||||
}
|
||||
}
|
||||
|
||||
@ -57,22 +57,44 @@ class FilterUsernameUpdatesHandlerTest {
|
||||
private static Stream<Arguments> handleRequest() {
|
||||
return Stream.of(
|
||||
Arguments.of(
|
||||
"username/testevent_creation.json",
|
||||
new UsernameConstraint.Pair(
|
||||
null,
|
||||
new UsernameConstraint(USERNAME_HASH, PREV_ACI))),
|
||||
Arguments.of(
|
||||
"username/testevent_deletion.json",
|
||||
new UsernameConstraint.Pair(
|
||||
new UsernameConstraint(USERNAME_HASH, PREV_ACI),
|
||||
"username/testevent_account_deletion.json", new UsernameConstraint.Pair(
|
||||
new UsernameConstraint(USERNAME_HASH, PREV_ACI, true),
|
||||
null)),
|
||||
Arguments.of(
|
||||
"username/testevent_nochange.json", null),
|
||||
"username/testevent_create_confirm.json", new UsernameConstraint.Pair(
|
||||
null,
|
||||
new UsernameConstraint(USERNAME_HASH, NEXT_ACI, true))),
|
||||
Arguments.of(
|
||||
"username/testevent_modify.json",
|
||||
"username/testevent_create_reserve.json", null),
|
||||
Arguments.of(
|
||||
"username/testevent_deletion_hold_expiring.json", null),
|
||||
Arguments.of(
|
||||
"username/testevent_modify_confirm.json",
|
||||
new UsernameConstraint.Pair(
|
||||
new UsernameConstraint(USERNAME_HASH, PREV_ACI),
|
||||
new UsernameConstraint(USERNAME_HASH, NEXT_ACI))));
|
||||
null,
|
||||
new UsernameConstraint(USERNAME_HASH, NEXT_ACI, true))),
|
||||
Arguments.of(
|
||||
"username/testevent_modify_unconfirm.json",
|
||||
new UsernameConstraint.Pair(
|
||||
new UsernameConstraint(USERNAME_HASH, PREV_ACI, true),
|
||||
null)),
|
||||
Arguments.of(
|
||||
"username/testevent_modify_aci_changed_old_confirmed_new_confirmed.json",
|
||||
new UsernameConstraint.Pair(
|
||||
new UsernameConstraint(USERNAME_HASH, PREV_ACI, true),
|
||||
new UsernameConstraint(USERNAME_HASH, NEXT_ACI, true))),
|
||||
Arguments.of(
|
||||
"username/testevent_modify_aci_changed_old_unconfirmed_new_confirmed.json",
|
||||
new UsernameConstraint.Pair(
|
||||
null,
|
||||
new UsernameConstraint(USERNAME_HASH, NEXT_ACI, true))),
|
||||
Arguments.of(
|
||||
"username/testevent_modify_aci_changed_old_confirmed_new_unconfirmed.json",
|
||||
new UsernameConstraint.Pair(
|
||||
new UsernameConstraint(USERNAME_HASH, PREV_ACI, true),
|
||||
null)),
|
||||
Arguments.of(
|
||||
"username/testevent_nochange.json", null));
|
||||
}
|
||||
|
||||
UsernameConstraint.Pair mapWithoutException(SdkBytes in) {
|
||||
|
||||
@ -14,6 +14,9 @@
|
||||
}
|
||||
},
|
||||
"OldImage": {
|
||||
"F": {
|
||||
"BOOL": true
|
||||
},
|
||||
"N": {
|
||||
"B": "EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE="
|
||||
},
|
||||
@ -25,5 +28,5 @@
|
||||
"StreamViewType": "NEW_AND_OLD_IMAGES"
|
||||
}
|
||||
}
|
||||
]
|
||||
]
|
||||
}
|
||||
@ -14,11 +14,14 @@
|
||||
}
|
||||
},
|
||||
"NewImage": {
|
||||
"F": {
|
||||
"BOOL": true
|
||||
},
|
||||
"N": {
|
||||
"B": "EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE="
|
||||
},
|
||||
"U": {
|
||||
"B": "IiIiIiIiIiIiIiIiIiIiIg=="
|
||||
"B": "BbBbBbBbBbBbBbBbBbBbBg=="
|
||||
}
|
||||
},
|
||||
"SizeBytes": 148,
|
||||
@ -0,0 +1,35 @@
|
||||
{
|
||||
"Records": [
|
||||
{
|
||||
"eventID": "88888888-85b6-4a4b-a74e-bf4688888888",
|
||||
"eventName": "MODIFY",
|
||||
"eventVersion": "1.1",
|
||||
"eventSource": "aws:dynamodb",
|
||||
"awsRegion": "us-east-1",
|
||||
"dynamodb": {
|
||||
"ApproximateCreationDateTime": "2026-02-17T12:55:17-05:00",
|
||||
"Keys": {
|
||||
"N": {
|
||||
"B": "EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE="
|
||||
}
|
||||
},
|
||||
"NewImage": {
|
||||
"F": {
|
||||
"BOOL": false
|
||||
},
|
||||
"N": {
|
||||
"B": "EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE="
|
||||
},
|
||||
"U": {
|
||||
"B": "IiIiIiIiIiIiIiIiIiIiIg=="
|
||||
},
|
||||
"TTL": {
|
||||
"N": "123456789"
|
||||
}
|
||||
},
|
||||
"SizeBytes": 148,
|
||||
"StreamViewType": "NEW_AND_OLD_IMAGES"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
@ -0,0 +1,35 @@
|
||||
{
|
||||
"Records": [
|
||||
{
|
||||
"eventID": "88888888-85b6-4a4b-a74e-bf4688888888",
|
||||
"eventName": "REMOVE",
|
||||
"eventVersion": "1.1",
|
||||
"eventSource": "aws:dynamodb",
|
||||
"awsRegion": "us-east-1",
|
||||
"dynamodb": {
|
||||
"ApproximateCreationDateTime": "2026-02-17T12:55:15-05:00",
|
||||
"Keys": {
|
||||
"N": {
|
||||
"B": "EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE="
|
||||
}
|
||||
},
|
||||
"OldImage": {
|
||||
"F": {
|
||||
"BOOL": false
|
||||
},
|
||||
"N": {
|
||||
"B": "EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE="
|
||||
},
|
||||
"U": {
|
||||
"B": "IiIiIiIiIiIiIiIiIiIiIg=="
|
||||
},
|
||||
"TTL": {
|
||||
"N": "123456789"
|
||||
}
|
||||
},
|
||||
"SizeBytes": 96,
|
||||
"StreamViewType": "NEW_AND_OLD_IMAGES"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
@ -14,6 +14,9 @@
|
||||
}
|
||||
},
|
||||
"NewImage": {
|
||||
"F": {
|
||||
"BOOL": true
|
||||
},
|
||||
"N": {
|
||||
"B": "EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE="
|
||||
},
|
||||
@ -22,6 +25,9 @@
|
||||
}
|
||||
},
|
||||
"OldImage": {
|
||||
"F": {
|
||||
"BOOL": true
|
||||
},
|
||||
"N": {
|
||||
"B": "EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE="
|
||||
},
|
||||
@ -0,0 +1,46 @@
|
||||
{
|
||||
"Records": [
|
||||
{
|
||||
"eventID": "88888888-85b6-4a4b-a74e-bf4688888888",
|
||||
"eventName": "MODIFY",
|
||||
"eventVersion": "1.1",
|
||||
"eventSource": "aws:dynamodb",
|
||||
"awsRegion": "us-east-1",
|
||||
"dynamodb": {
|
||||
"ApproximateCreationDateTime": "2026-02-17T12:55:17-05:00",
|
||||
"Keys": {
|
||||
"N": {
|
||||
"B": "EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE="
|
||||
}
|
||||
},
|
||||
"NewImage": {
|
||||
"F": {
|
||||
"BOOL": false
|
||||
},
|
||||
"N": {
|
||||
"B": "EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE="
|
||||
},
|
||||
"U": {
|
||||
"B": "BbBbBbBbBbBbBbBbBbBbBg=="
|
||||
},
|
||||
"TTL": {
|
||||
"N": "123456789"
|
||||
}
|
||||
},
|
||||
"OldImage": {
|
||||
"F": {
|
||||
"BOOL": true
|
||||
},
|
||||
"N": {
|
||||
"B": "EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE="
|
||||
},
|
||||
"U": {
|
||||
"B": "IiIiIiIiIiIiIiIiIiIiIg=="
|
||||
}
|
||||
},
|
||||
"SizeBytes": 148,
|
||||
"StreamViewType": "NEW_AND_OLD_IMAGES"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
@ -0,0 +1,46 @@
|
||||
{
|
||||
"Records": [
|
||||
{
|
||||
"eventID": "88888888-85b6-4a4b-a74e-bf4688888888",
|
||||
"eventName": "MODIFY",
|
||||
"eventVersion": "1.1",
|
||||
"eventSource": "aws:dynamodb",
|
||||
"awsRegion": "us-east-1",
|
||||
"dynamodb": {
|
||||
"ApproximateCreationDateTime": "2026-02-17T12:55:17-05:00",
|
||||
"Keys": {
|
||||
"N": {
|
||||
"B": "EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE="
|
||||
}
|
||||
},
|
||||
"NewImage": {
|
||||
"F": {
|
||||
"BOOL": true
|
||||
},
|
||||
"N": {
|
||||
"B": "EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE="
|
||||
},
|
||||
"U": {
|
||||
"B": "BbBbBbBbBbBbBbBbBbBbBg=="
|
||||
}
|
||||
},
|
||||
"OldImage": {
|
||||
"F": {
|
||||
"BOOL": false
|
||||
},
|
||||
"N": {
|
||||
"B": "EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE="
|
||||
},
|
||||
"U": {
|
||||
"B": "IiIiIiIiIiIiIiIiIiIiIg=="
|
||||
},
|
||||
"TTL": {
|
||||
"N": "123456789"
|
||||
}
|
||||
},
|
||||
"SizeBytes": 148,
|
||||
"StreamViewType": "NEW_AND_OLD_IMAGES"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
@ -0,0 +1,46 @@
|
||||
{
|
||||
"Records": [
|
||||
{
|
||||
"eventID": "88888888-85b6-4a4b-a74e-bf4688888888",
|
||||
"eventName": "MODIFY",
|
||||
"eventVersion": "1.1",
|
||||
"eventSource": "aws:dynamodb",
|
||||
"awsRegion": "us-east-1",
|
||||
"dynamodb": {
|
||||
"ApproximateCreationDateTime": "2026-02-17T12:55:17-05:00",
|
||||
"Keys": {
|
||||
"N": {
|
||||
"B": "EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE="
|
||||
}
|
||||
},
|
||||
"NewImage": {
|
||||
"F": {
|
||||
"BOOL": true
|
||||
},
|
||||
"N": {
|
||||
"B": "EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE="
|
||||
},
|
||||
"U": {
|
||||
"B": "BbBbBbBbBbBbBbBbBbBbBg=="
|
||||
}
|
||||
},
|
||||
"OldImage": {
|
||||
"F": {
|
||||
"BOOL": false
|
||||
},
|
||||
"N": {
|
||||
"B": "EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE="
|
||||
},
|
||||
"U": {
|
||||
"B": "BbBbBbBbBbBbBbBbBbBbBg=="
|
||||
},
|
||||
"TTL": {
|
||||
"N": "123456789"
|
||||
}
|
||||
},
|
||||
"SizeBytes": 148,
|
||||
"StreamViewType": "NEW_AND_OLD_IMAGES"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
@ -0,0 +1,46 @@
|
||||
{
|
||||
"Records": [
|
||||
{
|
||||
"eventID": "88888888-85b6-4a4b-a74e-bf4688888888",
|
||||
"eventName": "MODIFY",
|
||||
"eventVersion": "1.1",
|
||||
"eventSource": "aws:dynamodb",
|
||||
"awsRegion": "us-east-1",
|
||||
"dynamodb": {
|
||||
"ApproximateCreationDateTime": "2026-02-17T12:55:17-05:00",
|
||||
"Keys": {
|
||||
"N": {
|
||||
"B": "EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE="
|
||||
}
|
||||
},
|
||||
"NewImage": {
|
||||
"F": {
|
||||
"BOOL": false
|
||||
},
|
||||
"N": {
|
||||
"B": "EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE="
|
||||
},
|
||||
"U": {
|
||||
"B": "BbBbBbBbBbBbBbBbBbBbBg=="
|
||||
},
|
||||
"TTL": {
|
||||
"N": "123456789"
|
||||
}
|
||||
},
|
||||
"OldImage": {
|
||||
"F": {
|
||||
"BOOL": true
|
||||
},
|
||||
"N": {
|
||||
"B": "EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE="
|
||||
},
|
||||
"U": {
|
||||
"B": "IiIiIiIiIiIiIiIiIiIiIg=="
|
||||
}
|
||||
},
|
||||
"SizeBytes": 148,
|
||||
"StreamViewType": "NEW_AND_OLD_IMAGES"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
@ -14,6 +14,9 @@
|
||||
}
|
||||
},
|
||||
"NewImage": {
|
||||
"F": {
|
||||
"BOOL": false
|
||||
},
|
||||
"N": {
|
||||
"B": "EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE="
|
||||
},
|
||||
@ -22,6 +25,9 @@
|
||||
}
|
||||
},
|
||||
"OldImage": {
|
||||
"F": {
|
||||
"BOOL": false
|
||||
},
|
||||
"N": {
|
||||
"B": "EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE="
|
||||
},
|
||||
|
||||
Loading…
Reference in New Issue
Block a user