diff --git a/duniter4j-core-client/src/main/java/org/duniter/core/client/model/bma/NetworkPeering.java b/duniter4j-core-client/src/main/java/org/duniter/core/client/model/bma/NetworkPeering.java index a8a6c8b2360913fea540b656ea44cce915c7b5ee..48c24b51e0187ffe56e8f0de4ddb7a3accc036d9 100644 --- a/duniter4j-core-client/src/main/java/org/duniter/core/client/model/bma/NetworkPeering.java +++ b/duniter4j-core-client/src/main/java/org/duniter/core/client/model/bma/NetworkPeering.java @@ -94,6 +94,10 @@ public class NetworkPeering implements Serializable { this.status = status; } + /** + * Unsigned raw + * @return + */ public String getRaw() { return raw; } @@ -111,7 +115,21 @@ public class NetworkPeering implements Serializable { } public String toString() { - if (StringUtils.isNotBlank(raw)) return raw; + // Use raw, if exists + String raw = this.raw != null ? this.raw : toUnsignedRaw(); + + // Append signature (if any) + if (StringUtils.isBlank(signature)) { + return raw; + } + + return new StringBuilder() + .append(raw) + .append(signature).append("\n") + .toString(); + } + + public String toUnsignedRaw() { StringBuilder sb = new StringBuilder(); // Version @@ -131,9 +149,6 @@ public class NetworkPeering implements Serializable { .filter(Objects::nonNull) // can be null .forEach(ep -> sb.append(ep.toString()).append("\n")); } - if (StringUtils.isNotBlank(signature)) { - sb.append(signature).append("\n"); - } return sb.toString(); } diff --git a/duniter4j-core-client/src/main/java/org/duniter/core/client/model/bma/NetworkPeerings.java b/duniter4j-core-client/src/main/java/org/duniter/core/client/model/bma/NetworkPeerings.java index d2850757a747133afa80b30948cd8e9c0746db43..a0e9c6a3f85b542f798462c8dc377c0b9b5083d9 100644 --- a/duniter4j-core-client/src/main/java/org/duniter/core/client/model/bma/NetworkPeerings.java +++ b/duniter4j-core-client/src/main/java/org/duniter/core/client/model/bma/NetworkPeerings.java @@ -22,12 +22,15 @@ package org.duniter.core.client.model.bma; * #L% */ +import com.google.common.base.Joiner; import com.google.common.collect.Lists; +import org.duniter.core.util.ArrayUtils; import org.duniter.core.util.Preconditions; import org.duniter.core.util.StringUtils; import org.duniter.core.util.http.InetAddressUtils; import java.io.IOException; +import java.util.Arrays; import java.util.List; import java.util.regex.Matcher; @@ -92,7 +95,10 @@ public class NetworkPeerings { result.setStatus("UP"); - result.setRaw(document); + // Remove signature (will be an end line) + lines[lines.length - 1] = ""; + String unsignedRaw = Joiner.on('\n').join(lines); + result.setRaw(unsignedRaw); return result; } diff --git a/duniter4j-core-client/src/main/java/org/duniter/core/client/service/local/NetworkServiceImpl.java b/duniter4j-core-client/src/main/java/org/duniter/core/client/service/local/NetworkServiceImpl.java index e18681ed004e3166f5ca91fcf41124826ace1da9..31d2b51abf0a240dbafe7ba20fbeb2a4bc7cb5be 100644 --- a/duniter4j-core-client/src/main/java/org/duniter/core/client/service/local/NetworkServiceImpl.java +++ b/duniter4j-core-client/src/main/java/org/duniter/core/client/service/local/NetworkServiceImpl.java @@ -139,7 +139,7 @@ public class NetworkServiceImpl extends BaseRemoteServiceImpl implements Network .filter(peerFilter(filter)) .sorted(peerComparator(sort)) .collect(Collectors.toList())) - .thenApplyAsync(this::logPeers) + //.thenApplyAsync(this::logPeers) .get(); } catch (InterruptedException | ExecutionException e) { throw new TechnicalException("Error while loading peers: " + e.getMessage(), e); diff --git a/duniter4j-core-client/src/test/java/org/duniter/core/client/model/bma/NetworkPeeringsTest.java b/duniter4j-core-client/src/test/java/org/duniter/core/client/model/bma/NetworkPeeringsTest.java index f2db982a76888372d3a5f1c9ace7e50abe125adc..a4422c5f981e5d59b5e1f5dedccd114bbc6c71a0 100644 --- a/duniter4j-core-client/src/test/java/org/duniter/core/client/model/bma/NetworkPeeringsTest.java +++ b/duniter4j-core-client/src/test/java/org/duniter/core/client/model/bma/NetworkPeeringsTest.java @@ -1,16 +1,32 @@ package org.duniter.core.client.model.bma; +import org.duniter.core.client.TestResource; +import org.duniter.core.client.service.ServiceLocator; +import org.duniter.core.service.CryptoService; import org.junit.Assert; +import org.junit.Before; +import org.junit.ClassRule; import org.junit.Test; public class NetworkPeeringsTest { + @ClassRule + public static final TestResource resource = TestResource.create(); + + private CryptoService cryptoService; + + @Before + public void setUp() { + cryptoService = ServiceLocator.instance().getCryptoService(); + } + @Test public void parse() throws Exception { - String doc = "Version: 10\nType: Peer\nCurrency: g1\nPublicKey: 38MEAZN68Pz1DTvT3tqgxx4yQP6snJCQhPqEFxbDk4aE\nBlock: 162694-0000067CAF81B13E4BD7AE72A06F9981D80EB957E4D46C23A67B4DF734E258ED\nEndpoints:\nBMAS g1.duniter.fr 443\nES_CORE_API g1.data.duniter.fr 443\nES_USER_API g1.data.duniter.fr 443\nES_SUBSCRIPTION_API g1.data.duniter.fr 443\nBASIC_MERKLED_API g1.duniter.fr 80\nWS2P fb17fcd4 g1.duniter.fr 443 /ws2p\nU+obPZqDQ3WDDclyCrOhT80Dq/8sPZp0ng+hj4THPAaxKNQwc9cijNnfvwzSsQ/hZBJpZ6+Gzrzso+zprhNICQ==\n"; + String unsignedRaw = "Version: 10\nType: Peer\nCurrency: g1\nPublicKey: 38MEAZN68Pz1DTvT3tqgxx4yQP6snJCQhPqEFxbDk4aE\nBlock: 162694-0000067CAF81B13E4BD7AE72A06F9981D80EB957E4D46C23A67B4DF734E258ED\nEndpoints:\nBMAS g1.duniter.fr 443\nES_CORE_API g1.data.duniter.fr 443\nES_USER_API g1.data.duniter.fr 443\nES_SUBSCRIPTION_API g1.data.duniter.fr 443\nBASIC_MERKLED_API g1.duniter.fr 80\nWS2P fb17fcd4 g1.duniter.fr 443 /ws2p\n"; + String signedRaw = unsignedRaw + "U+obPZqDQ3WDDclyCrOhT80Dq/8sPZp0ng+hj4THPAaxKNQwc9cijNnfvwzSsQ/hZBJpZ6+Gzrzso+zprhNICQ==\n"; - NetworkPeering peering = NetworkPeerings.parse(doc); + NetworkPeering peering = NetworkPeerings.parse(signedRaw); Assert.assertNotNull(peering); Assert.assertEquals("g1", peering.getCurrency()); @@ -19,6 +35,25 @@ public class NetworkPeeringsTest { Assert.assertEquals("162694-0000067CAF81B13E4BD7AE72A06F9981D80EB957E4D46C23A67B4DF734E258ED", peering.getBlock()); Assert.assertEquals("U+obPZqDQ3WDDclyCrOhT80Dq/8sPZp0ng+hj4THPAaxKNQwc9cijNnfvwzSsQ/hZBJpZ6+Gzrzso+zprhNICQ==", peering.getSignature()); Assert.assertEquals(6, peering.getEndpoints().length); + Assert.assertEquals(unsignedRaw, peering.getRaw()); + Assert.assertEquals(signedRaw, peering.toString()); } + @Test + public void parseAndVerify() throws Exception { + + String unsignedRaw = "Version: 10\nType: Peer\nCurrency: g1\nPublicKey: B9BJkrZsXeoWxeUcu8rwz8PtCT67bN2xJ9xJdZNzxTxd\nBlock: 348676-00000032B293BD0B9709239D333D2D904839AD20ADE8840236BDC1732299589F\nEndpoints:\nWS2P 471cffa5 77.152.31.154 20900\n"; + String signature = "Q+/SIISPcOu+i2MqvdbrGdyp2pFAkIShgpAp0sziNZbiETd4WMANwtCb75dn04E4cMmVhpr0aBfa9Pcm/Y++AQ=="; + String signedRaw = unsignedRaw + signature + "\n"; + + NetworkPeering peering = NetworkPeerings.parse(signedRaw); + Assert.assertNotNull(peering); + + Assert.assertEquals("g1", peering.getCurrency()); + Assert.assertEquals(1, peering.getEndpoints().length); + Assert.assertEquals(unsignedRaw, peering.getRaw()); + Assert.assertEquals(signedRaw, peering.toString()); + + Assert.assertEquals(true, cryptoService.verify(unsignedRaw, signature, peering.getPubkey())); + } } diff --git a/duniter4j-core-shared/src/main/java/org/duniter/core/util/ArrayUtils.java b/duniter4j-core-shared/src/main/java/org/duniter/core/util/ArrayUtils.java index 5134a648ef09f3310d741844fcff6b5dffbc3242..6cba46bf39ccf13be17abfce4523a5bf99e444f1 100644 --- a/duniter4j-core-shared/src/main/java/org/duniter/core/util/ArrayUtils.java +++ b/duniter4j-core-shared/src/main/java/org/duniter/core/util/ArrayUtils.java @@ -22,12 +22,6 @@ package org.duniter.core.util; * #L% */ -import com.google.common.collect.Lists; - -import java.util.ArrayList; -import java.util.Collection; -import java.util.Iterator; - /** * Created by eis on 23/12/14. */