Skip to content

Commit

Permalink
Add url validation when updating recipients. If existing key and url (#…
Browse files Browse the repository at this point in the history
…717)

has changed then fail validation.
  • Loading branch information
melowe authored Apr 26, 2019
1 parent 565ecb7 commit f4ace61
Show file tree
Hide file tree
Showing 4 changed files with 142 additions and 2 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@

package com.quorum.tessera.node;

import com.quorum.tessera.encryption.PublicKey;
import com.quorum.tessera.node.model.PartyInfo;
import java.util.Map;
import java.util.Objects;
import java.util.stream.Collectors;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class PartyInfoRecipientUpdateCheck {

private static final Logger LOGGER = LoggerFactory.getLogger(PartyInfoRecipientUpdateCheck.class);

private final PartyInfo existingPartyInfo;

private final PartyInfo newPartyInfo;

public PartyInfoRecipientUpdateCheck(PartyInfo existingPartyInfo, PartyInfo newPartyInfo) {
this.existingPartyInfo = Objects.requireNonNull(existingPartyInfo);
this.newPartyInfo = Objects.requireNonNull(newPartyInfo);
}

public boolean validateKeysToUrls() {

final Map<PublicKey, String> existingRecipientKeyUrlMap = existingPartyInfo.getRecipients()
.stream()
.collect(Collectors.toMap(r -> r.getKey(), r -> r.getUrl()));

final Map<PublicKey, String> newRecipientKeyUrlMap = newPartyInfo.getRecipients()
.stream()
.collect(Collectors.toMap(r -> r.getKey(), r -> r.getUrl()));

for(Map.Entry<PublicKey,String> e : newRecipientKeyUrlMap.entrySet()) {
PublicKey key = e.getKey();
if(existingRecipientKeyUrlMap.containsKey(key)) {

String existingUrl = existingRecipientKeyUrlMap.get(key);
String newUrl = newRecipientKeyUrlMap.get(key);
if(!existingUrl.equalsIgnoreCase(newUrl)) {
return false;
}
}
}
return true;
}


}
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,16 @@
import java.util.Set;

import static java.util.Collections.unmodifiableSet;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
* Stores a list of all discovered nodes and public keys
*/
public class PartyInfoStore {

private static final Logger LOGGER = LoggerFactory.getLogger(PartyInfoStore.class);

private final String advertisedUrl;

private final Set<Recipient> recipients;
Expand All @@ -33,11 +37,21 @@ public PartyInfoStore(final ConfigService configService) {
}

/**
* Merge an incoming {@link PartyInfo} into the current one, adding any
* new keys or parties to the current store
* Merge an incoming {@link PartyInfo} into the current one, adding any new
* keys or parties to the current store
*
* @param newInfo the incoming information that may contain new nodes/keys
*/
public synchronized void store(final PartyInfo newInfo) {

PartyInfo existingPartyInfo = getPartyInfo();

PartyInfoRecipientUpdateCheck partyInfoRecipientUpdateCheck = new PartyInfoRecipientUpdateCheck(existingPartyInfo,newInfo);
if(!partyInfoRecipientUpdateCheck.validateKeysToUrls()) {
LOGGER.warn("Attempt is being made to update existing key with new url. Terminating party info update.");
return;
}

recipients.addAll(newInfo.getRecipients());
parties.addAll(newInfo.getParties());

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@

package com.quorum.tessera.node;

import com.quorum.tessera.encryption.PublicKey;
import com.quorum.tessera.node.model.PartyInfo;
import com.quorum.tessera.node.model.Recipient;
import java.util.Collections;
import java.util.HashSet;
import java.util.Set;
import static org.assertj.core.api.Assertions.assertThat;
import org.junit.Test;


public class PartyInfoRecipientUpdateCheckTest {


@Test
public void validateEmpty() {

String url = "http://somedomain.com";

Set<Recipient> existingRecipients = new HashSet<>();
Set<Recipient> newRecipients = new HashSet<>();
PartyInfo existingPartyInfo = new PartyInfo(url, existingRecipients, Collections.EMPTY_SET);
PartyInfo newPartyInfo = new PartyInfo(url, newRecipients, Collections.EMPTY_SET);
PartyInfoRecipientUpdateCheck check = new PartyInfoRecipientUpdateCheck(existingPartyInfo,newPartyInfo);

assertThat(check.validateKeysToUrls()).isTrue();

}

@Test
public void attemptToChangeUrl() {

String url = "http://somedomain.com";

PublicKey key = PublicKey.from("ONE".getBytes());

Recipient existingRecipient = new Recipient(key,"http://one.com");
Set<Recipient> existingRecipients = Collections.singleton(existingRecipient);

Recipient newRecipient = new Recipient(key,"http://two.com");
Set<Recipient> newRecipients = Collections.singleton(newRecipient);


PartyInfo existingPartyInfo = new PartyInfo(url, existingRecipients, Collections.EMPTY_SET);
PartyInfo newPartyInfo = new PartyInfo(url, newRecipients, Collections.EMPTY_SET);

PartyInfoRecipientUpdateCheck check = new PartyInfoRecipientUpdateCheck(existingPartyInfo,newPartyInfo);
assertThat(check.validateKeysToUrls()).isFalse();

}
}
Original file line number Diff line number Diff line change
Expand Up @@ -136,5 +136,28 @@ public void receivingMessageUpdatesSenderTimestamp() {
assertThat(firstContact).isBeforeOrEqualTo(secondContact);

}

@Test
public void attemptToUpdateReciepentWithExistingKeyWithNewUrlIsIgnored() {

final PublicKey testKey = PublicKey.from("some-key".getBytes());

final Set<Recipient> ourKeys = singleton(new Recipient(testKey, uri));

final PartyInfo initial = new PartyInfo(uri, ourKeys, emptySet());

partyInfoStore.store(initial);


final Set<Recipient> newRecipients = singleton(new Recipient(testKey, "http://other.com"));
final PartyInfo updated = new PartyInfo(uri, newRecipients, emptySet());

partyInfoStore.store(updated);

final Set<Recipient> retrievedRecipients = partyInfoStore.getPartyInfo().getRecipients();

assertThat(retrievedRecipients).hasSize(1)
.containsExactly(new Recipient(testKey, uri));
}

}

0 comments on commit f4ace61

Please sign in to comment.