From 4d72d6083e434bf09acc70ca11e3e20748c62f21 Mon Sep 17 00:00:00 2001 From: Vladimir Eliezer Tokarev Date: Sat, 5 Mar 2016 03:20:07 -0800 Subject: [PATCH] Changed addVoterToGroup to setVotersGroup. --- .../java/meerkat/util/BulletinBoardUtils.java | 26 +++++- .../src/main/java/meerkat/Registry.java | 85 ++++++++++++------- .../src/main/java/meerkat/VoterRegistry.java | 21 ++++- .../registry/LatestMessagesCallBack.java | 15 ++-- .../java/meerkat/registry/RegistryTags.java | 3 +- .../src/test/java/SimpleRegistryTest.java | 9 +- 6 files changed, 112 insertions(+), 47 deletions(-) diff --git a/meerkat-common/src/main/java/meerkat/util/BulletinBoardUtils.java b/meerkat-common/src/main/java/meerkat/util/BulletinBoardUtils.java index 9bc97ff..a6784ae 100644 --- a/meerkat-common/src/main/java/meerkat/util/BulletinBoardUtils.java +++ b/meerkat-common/src/main/java/meerkat/util/BulletinBoardUtils.java @@ -1,8 +1,13 @@ package meerkat.util; -import meerkat.protobuf.BulletinBoardAPI.*; +import meerkat.crypto.DigitalSignature; +import meerkat.protobuf.BulletinBoardAPI.BulletinBoardMessage; +import meerkat.protobuf.BulletinBoardAPI.UnsignedBulletinBoardMessage; +import meerkat.protobuf.Crypto; +import java.security.SignatureException; import java.util.ArrayList; +import java.util.Collection; import java.util.LinkedList; import java.util.List; @@ -28,6 +33,25 @@ public class BulletinBoardUtils { } + /** + * Creates BulletinBoardMessage with UnsignedBulletinBoardMessage and its signature + * signed by all given DigitalSignatures + * + * @param unsignedMessage BasicMessage + * @param signers collection of DigitalSignature which will sign the + * UnsignedBulletinBoardMessage message + * @return BulletinBoardMessage + */ + public static BulletinBoardMessage signToBulletinBoardMessage(UnsignedBulletinBoardMessage unsignedMessage, Collection signers) throws SignatureException { + BulletinBoardMessage.Builder bulletinBoardMessage = BulletinBoardMessage.newBuilder(); + for (DigitalSignature signer : signers) { + signer.updateContent(unsignedMessage); + Crypto.Signature signature = signer.sign(); + bulletinBoardMessage.setMsg(unsignedMessage).addSig(signature); + } + return bulletinBoardMessage.build(); + } + /** * Gets list of tags values from given messages (tagName values) * @param messages list of messages from which we want to retrieve specific tag values diff --git a/voter-registry/src/main/java/meerkat/Registry.java b/voter-registry/src/main/java/meerkat/Registry.java index d97d2c7..9f363a0 100644 --- a/voter-registry/src/main/java/meerkat/Registry.java +++ b/voter-registry/src/main/java/meerkat/Registry.java @@ -3,9 +3,7 @@ package meerkat; import com.google.protobuf.Timestamp; import meerkat.bulletinboard.AsyncBulletinBoardClient; import meerkat.crypto.DigitalSignature; -import meerkat.protobuf.BulletinBoardAPI.BulletinBoardMessage; import meerkat.protobuf.BulletinBoardAPI.UnsignedBulletinBoardMessage; -import meerkat.protobuf.Crypto; import meerkat.protobuf.VoterRegistry.GroupID; import meerkat.protobuf.VoterRegistry.VoterID; import meerkat.protobuf.VoterRegistry.VoterInfo; @@ -22,6 +20,8 @@ import java.util.ArrayList; import java.util.Collection; import java.util.List; +import static meerkat.util.BulletinBoardUtils.signToBulletinBoardMessage; + /** * TODO : add ability to use DB of certificates */ @@ -34,90 +34,109 @@ public class Registry implements VoterRegistry{ protected Collection signers; protected AsyncBulletinBoardClient bulletinBoardClient ; - protected InputStream certificateStream; - public void init(Collection signers, - AsyncBulletinBoardClient communicator, - InputStream certificateStream) { + @Override + public void init(Collection signers, AsyncBulletinBoardClient communicator) { this.signers = signers; this.bulletinBoardClient = communicator; - this.certificateStream = certificateStream; } /** - * Creates BulletinBoardMessage with signed basicMessage and - * UnsignedBulletinBoardMessage that contains the basic message - * - * @param basicMessage BasicMessage - * @return BulletinBoardMessage - */ - protected BulletinBoardMessage createBulletinBoardMessage(UnsignedBulletinBoardMessage basicMessage) { + * Loads all the verification certificate to all the signers + * @param certificateStream the certificate for the validation + */ + public void loadCertificateToSigners(InputStream certificateStream) + { try { - BulletinBoardMessage.Builder bulletinBoardMessage = BulletinBoardMessage.newBuilder(); - for (DigitalSignature signer : signers) { - signer.updateContent(basicMessage); - Crypto.Signature signature = signer.sign(); - bulletinBoardMessage.setMsg(basicMessage).addSig(signature); - + for (DigitalSignature signer: signers) + { signer.loadVerificationCertificates(certificateStream); } - return bulletinBoardMessage.build(); - } catch (SignatureException | CertificateException e) { + } catch (CertificateException e) { e.printStackTrace(); - return null; } } + @Override public void addVoter(VoterInfo voterInfo, RegistryCallBack callback) { - UnsignedBulletinBoardMessage.Builder basicMessage = + UnsignedBulletinBoardMessage basicMessage = UnsignedBulletinBoardMessage.newBuilder(). addTag(RegistryTags.ID_TAG + voterInfo.getId().getId()) .addTag(RegistryTags.VOTER_ENTRY_TAG) - .addTag(RegistryTags.VOTER_DATA_TAG + voterInfo.getInfo()) - .setTimestamp(Timestamp.newBuilder().setNanos((int) System.nanoTime()).build()); + .addTag(voterInfo.getInfo()) + .setTimestamp(Timestamp.newBuilder().setNanos((int) System.nanoTime()) + .build()).build(); - bulletinBoardClient.postMessage(createBulletinBoardMessage(basicMessage.build()), new MessagesCallBack(callback)); + try { + bulletinBoardClient.postMessage(signToBulletinBoardMessage(basicMessage, signers), + new MessagesCallBack(callback)); + } catch (SignatureException e) { + callback.handleFailure(e); + } } - public void addToGroups(VoterRegistryMessage voterGroup, RegistryCallBack callback) { + @Override + public void setVoterGroups(VoterRegistryMessage voterGroup, RegistryCallBack callback) { UnsignedBulletinBoardMessage.Builder basicMessage = UnsignedBulletinBoardMessage.newBuilder() .addTag(RegistryTags.ID_TAG + voterGroup.getVoterID().getId()) .addTag(RegistryTags.ADD_TO_GROUP_TAG) - .setTimestamp(Timestamp.newBuilder().setNanos((int) System.nanoTime()).build()); + .setTimestamp(Timestamp.newBuilder().setNanos((int) System.nanoTime()) + .build()); for (GroupID groupId : voterGroup.getGroupIDList()) { basicMessage.addTag(RegistryTags.GROUP_ID_TAG + groupId.getId()); } - bulletinBoardClient.postMessage(createBulletinBoardMessage(basicMessage.build()), new MessagesCallBack(callback)); + try { + bulletinBoardClient.postMessage(signToBulletinBoardMessage(basicMessage.build(), signers), + new MessagesCallBack(callback)); + } catch (SignatureException e) { + callback.handleFailure(e); + } } + @Override public void setVoted(VoterID voterId, RegistryCallBack callback) { - UnsignedBulletinBoardMessage.Builder basicMessage = + UnsignedBulletinBoardMessage basicMessage = UnsignedBulletinBoardMessage.newBuilder() .addTag(RegistryTags.ID_TAG + voterId.getId()) .addTag(RegistryTags.VOTE_ACTION_TAG) - .setTimestamp(Timestamp.newBuilder().setNanos((int) System.nanoTime()).build()); + .setTimestamp(Timestamp.newBuilder().setNanos((int) System.nanoTime()) + .build()).build(); - bulletinBoardClient.postMessage(createBulletinBoardMessage(basicMessage.build()), new MessagesCallBack(callback)); + try { + bulletinBoardClient.postMessage(signToBulletinBoardMessage(basicMessage, signers), + new MessagesCallBack(callback)); + } catch (SignatureException e) { + callback.handleFailure(e); + } } + @Override public void getGroups(GroupID groupID, RegistryCallBack callback) { List GroupsActionsTags = new ArrayList(2) {{ add(RegistryTags.GROUP_ID_TAG + groupID.getId()); }}; + bulletinBoardClient.readMessages(MessageCollectionUtils.generateFiltersFromTags(GroupsActionsTags), new LatestMessagesCallBack(callback, signers)); } + @Override public void getPersonIDDetails(VoterID voterID, RegistryCallBack callback) { List GroupsActionsTags = new ArrayList() {{ add(RegistryTags.ID_TAG + voterID.getId()); add(RegistryTags.VOTER_ENTRY_TAG); }}; + bulletinBoardClient.readMessages(MessageCollectionUtils.generateFiltersFromTags(GroupsActionsTags), new LatestMessagesCallBack(callback, signers)); } + + @Override + public boolean hasVoted(VoterID voterId, RegistryCallBack callBack) { + return false; + } } diff --git a/voter-registry/src/main/java/meerkat/VoterRegistry.java b/voter-registry/src/main/java/meerkat/VoterRegistry.java index 25d7822..c0f1f50 100644 --- a/voter-registry/src/main/java/meerkat/VoterRegistry.java +++ b/voter-registry/src/main/java/meerkat/VoterRegistry.java @@ -1,7 +1,11 @@ package meerkat; +import meerkat.bulletinboard.AsyncBulletinBoardClient; +import meerkat.crypto.DigitalSignature; import meerkat.protobuf.VoterRegistry.*; +import java.util.Collection; + /** * Created by Vladimir Eliezer Tokarev on 1/22/2016. * provides voters management options @@ -18,6 +22,13 @@ public interface VoterRegistry { void handleFailure(Throwable throwable); } + /** + * Initialize the voter registry + * @param signers object that will sign the messages before sent them + * @param communicator the object which communicates with the BulletinBoardServer + */ + void init(Collection signers, AsyncBulletinBoardClient communicator); + /** * Adds new voter to the bulletin-board * Passes true to callBack.handleResult if the actions succeeded else false @@ -36,7 +47,7 @@ public interface VoterRegistry { * @param callBack when the adding voter done callBack.handleResult will be called * @return true if the adding action succeeded else return false */ - void addToGroups(VoterRegistryMessage voterGroup, RegistryCallBack callBack); + void setVoterGroups(VoterRegistryMessage voterGroup, RegistryCallBack callBack); /** * Sets that the voter have voted @@ -66,5 +77,13 @@ public interface VoterRegistry { * @return list of strings (empty list if the lookup failed) */ void getPersonIDDetails(VoterID voterID, RegistryCallBack callBack); + + /** + * Checks if the given voter (by his id) have already voted + * @param voterId the id of the the voter + * @param callBack method that will be called with the when the result will be found + * @return true if voter had voted + */ + boolean hasVoted(VoterID voterId, RegistryCallBack callBack); } diff --git a/voter-registry/src/main/java/meerkat/registry/LatestMessagesCallBack.java b/voter-registry/src/main/java/meerkat/registry/LatestMessagesCallBack.java index 0d081b1..597ef1f 100644 --- a/voter-registry/src/main/java/meerkat/registry/LatestMessagesCallBack.java +++ b/voter-registry/src/main/java/meerkat/registry/LatestMessagesCallBack.java @@ -64,15 +64,18 @@ public class LatestMessagesCallBack implements FutureCallback msg) { + BulletinBoardMessage lastAddedMessage = Collections.max(msg, (first, second) -> { + TimestampComparator comparator = new TimestampComparator(); + return comparator.compare(first.getMsg().getTimestamp(), second.getMsg().getTimestamp()); + }); + + List messages = new ArrayList(){{add(lastAddedMessage);}}; + if (isAddToGroupsList(msg)) { - List groupsOfUser = GetListOfTags(msg, RegistryTags.GROUP_ID_TAG); - callback.handleResult(groupsOfUser); + callback.handleResult(GetListOfTags(messages, RegistryTags.GROUP_ID_TAG)); } else { - callback.handleResult(Collections.max(msg, (first, second) -> { - TimestampComparator comparator = new TimestampComparator(); - return comparator.compare(first.getMsg().getTimestamp(), second.getMsg().getTimestamp()); - })); + callback.handleResult(lastAddedMessage); } } diff --git a/voter-registry/src/main/java/meerkat/registry/RegistryTags.java b/voter-registry/src/main/java/meerkat/registry/RegistryTags.java index 375e367..365aded 100644 --- a/voter-registry/src/main/java/meerkat/registry/RegistryTags.java +++ b/voter-registry/src/main/java/meerkat/registry/RegistryTags.java @@ -8,9 +8,8 @@ package meerkat.registry; public interface RegistryTags { String ID_TAG = "ID: "; String VOTER_ENTRY_TAG = "VoterEntry: "; - String VOTER_DATA_TAG = "Data: "; String GROUP_ID_TAG = "GroupID: "; - String ADD_TO_GROUP_TAG = "addToGroups: "; + String ADD_TO_GROUP_TAG = "setVoterGroups: "; String VOTE_ACTION_TAG = "VoteAction: "; } diff --git a/voter-registry/src/test/java/SimpleRegistryTest.java b/voter-registry/src/test/java/SimpleRegistryTest.java index 12a9197..59631e4 100644 --- a/voter-registry/src/test/java/SimpleRegistryTest.java +++ b/voter-registry/src/test/java/SimpleRegistryTest.java @@ -132,7 +132,8 @@ public class SimpleRegistryTest extends TestCase { private Registry GetRegistry() { Registry registry = new Registry(); - registry.init(signers, bulletinBoardClient, certStream); + registry.init(signers, bulletinBoardClient); + registry.loadCertificateToSigners(certStream); return registry; } @@ -246,7 +247,7 @@ public class SimpleRegistryTest extends TestCase { .addGroupID(GroupID.newBuilder().setId(groupId)).build(); Registry registry = GetRegistry(); - registry.addToGroups(voterInfo, handler); + registry.setVoterGroups(voterInfo, handler); jobSemaphore.acquire(); assertEquals(1, handler.counter); @@ -282,7 +283,7 @@ public class SimpleRegistryTest extends TestCase { this.certStream = getClass().getResourceAsStream(CERT1_PEM_EXAMPLE); Registry registry = GetRegistry(); - registry.addToGroups(voterInfo, handler); + registry.setVoterGroups(voterInfo, handler); jobSemaphore.acquire(); assertEquals(1, handler.counter ); @@ -318,7 +319,7 @@ public class SimpleRegistryTest extends TestCase { jobSemaphore.acquire(1); assertEquals(id, findTagWithPrefix(personalHandler.data, RegistryTags.ID_TAG)); - assertTrue(findTagWithPrefix(personalHandler.data, RegistryTags.VOTER_DATA_TAG).contains(data)); + assertTrue(findTagWithPrefix(personalHandler.data, data) != null); } }