Changed addVoterToGroup to setVotersGroup.

Voter-Registry
Vladimir Eliezer Tokarev 2016-03-05 03:20:07 -08:00
parent da614c13ab
commit 4d72d6083e
6 changed files with 112 additions and 47 deletions

View File

@ -1,8 +1,13 @@
package meerkat.util; 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.ArrayList;
import java.util.Collection;
import java.util.LinkedList; import java.util.LinkedList;
import java.util.List; 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<DigitalSignature> 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) * Gets list of tags values from given messages (tagName values)
* @param messages list of messages from which we want to retrieve specific tag values * @param messages list of messages from which we want to retrieve specific tag values

View File

@ -3,9 +3,7 @@ package meerkat;
import com.google.protobuf.Timestamp; import com.google.protobuf.Timestamp;
import meerkat.bulletinboard.AsyncBulletinBoardClient; import meerkat.bulletinboard.AsyncBulletinBoardClient;
import meerkat.crypto.DigitalSignature; import meerkat.crypto.DigitalSignature;
import meerkat.protobuf.BulletinBoardAPI.BulletinBoardMessage;
import meerkat.protobuf.BulletinBoardAPI.UnsignedBulletinBoardMessage; import meerkat.protobuf.BulletinBoardAPI.UnsignedBulletinBoardMessage;
import meerkat.protobuf.Crypto;
import meerkat.protobuf.VoterRegistry.GroupID; import meerkat.protobuf.VoterRegistry.GroupID;
import meerkat.protobuf.VoterRegistry.VoterID; import meerkat.protobuf.VoterRegistry.VoterID;
import meerkat.protobuf.VoterRegistry.VoterInfo; import meerkat.protobuf.VoterRegistry.VoterInfo;
@ -22,6 +20,8 @@ import java.util.ArrayList;
import java.util.Collection; import java.util.Collection;
import java.util.List; import java.util.List;
import static meerkat.util.BulletinBoardUtils.signToBulletinBoardMessage;
/** /**
* TODO : add ability to use DB of certificates * TODO : add ability to use DB of certificates
*/ */
@ -34,90 +34,109 @@ public class Registry implements VoterRegistry{
protected Collection<DigitalSignature> signers; protected Collection<DigitalSignature> signers;
protected AsyncBulletinBoardClient bulletinBoardClient ; protected AsyncBulletinBoardClient bulletinBoardClient ;
protected InputStream certificateStream;
public void init(Collection<DigitalSignature> signers, @Override
AsyncBulletinBoardClient communicator, public void init(Collection<DigitalSignature> signers, AsyncBulletinBoardClient communicator) {
InputStream certificateStream) {
this.signers = signers; this.signers = signers;
this.bulletinBoardClient = communicator; this.bulletinBoardClient = communicator;
this.certificateStream = certificateStream;
} }
/** /**
* Creates BulletinBoardMessage with signed basicMessage and * Loads all the verification certificate to all the signers
* UnsignedBulletinBoardMessage that contains the basic message * @param certificateStream the certificate for the validation
* */
* @param basicMessage BasicMessage public void loadCertificateToSigners(InputStream certificateStream)
* @return BulletinBoardMessage {
*/
protected BulletinBoardMessage createBulletinBoardMessage(UnsignedBulletinBoardMessage basicMessage) {
try { try {
BulletinBoardMessage.Builder bulletinBoardMessage = BulletinBoardMessage.newBuilder(); for (DigitalSignature signer: signers)
for (DigitalSignature signer : signers) { {
signer.updateContent(basicMessage);
Crypto.Signature signature = signer.sign();
bulletinBoardMessage.setMsg(basicMessage).addSig(signature);
signer.loadVerificationCertificates(certificateStream); signer.loadVerificationCertificates(certificateStream);
} }
return bulletinBoardMessage.build(); } catch (CertificateException e) {
} catch (SignatureException | CertificateException e) {
e.printStackTrace(); e.printStackTrace();
return null;
} }
} }
@Override
public void addVoter(VoterInfo voterInfo, RegistryCallBack callback) { public void addVoter(VoterInfo voterInfo, RegistryCallBack callback) {
UnsignedBulletinBoardMessage.Builder basicMessage = UnsignedBulletinBoardMessage basicMessage =
UnsignedBulletinBoardMessage.newBuilder(). UnsignedBulletinBoardMessage.newBuilder().
addTag(RegistryTags.ID_TAG + voterInfo.getId().getId()) addTag(RegistryTags.ID_TAG + voterInfo.getId().getId())
.addTag(RegistryTags.VOTER_ENTRY_TAG) .addTag(RegistryTags.VOTER_ENTRY_TAG)
.addTag(RegistryTags.VOTER_DATA_TAG + voterInfo.getInfo()) .addTag(voterInfo.getInfo())
.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);
}
} }
public void addToGroups(VoterRegistryMessage voterGroup, RegistryCallBack callback) { @Override
public void setVoterGroups(VoterRegistryMessage voterGroup, RegistryCallBack callback) {
UnsignedBulletinBoardMessage.Builder basicMessage = UnsignedBulletinBoardMessage.Builder basicMessage =
UnsignedBulletinBoardMessage.newBuilder() UnsignedBulletinBoardMessage.newBuilder()
.addTag(RegistryTags.ID_TAG + voterGroup.getVoterID().getId()) .addTag(RegistryTags.ID_TAG + voterGroup.getVoterID().getId())
.addTag(RegistryTags.ADD_TO_GROUP_TAG) .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()) for (GroupID groupId : voterGroup.getGroupIDList())
{ {
basicMessage.addTag(RegistryTags.GROUP_ID_TAG + groupId.getId()); 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) { public void setVoted(VoterID voterId, RegistryCallBack callback) {
UnsignedBulletinBoardMessage.Builder basicMessage = UnsignedBulletinBoardMessage basicMessage =
UnsignedBulletinBoardMessage.newBuilder() UnsignedBulletinBoardMessage.newBuilder()
.addTag(RegistryTags.ID_TAG + voterId.getId()) .addTag(RegistryTags.ID_TAG + voterId.getId())
.addTag(RegistryTags.VOTE_ACTION_TAG) .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) { public void getGroups(GroupID groupID, RegistryCallBack callback) {
List<String> GroupsActionsTags = new ArrayList<String>(2) {{ List<String> GroupsActionsTags = new ArrayList<String>(2) {{
add(RegistryTags.GROUP_ID_TAG + groupID.getId()); add(RegistryTags.GROUP_ID_TAG + groupID.getId());
}}; }};
bulletinBoardClient.readMessages(MessageCollectionUtils.generateFiltersFromTags(GroupsActionsTags), bulletinBoardClient.readMessages(MessageCollectionUtils.generateFiltersFromTags(GroupsActionsTags),
new LatestMessagesCallBack(callback, signers)); new LatestMessagesCallBack(callback, signers));
} }
@Override
public void getPersonIDDetails(VoterID voterID, RegistryCallBack callback) { public void getPersonIDDetails(VoterID voterID, RegistryCallBack callback) {
List<String> GroupsActionsTags = new ArrayList<String>() {{ List<String> GroupsActionsTags = new ArrayList<String>() {{
add(RegistryTags.ID_TAG + voterID.getId()); add(RegistryTags.ID_TAG + voterID.getId());
add(RegistryTags.VOTER_ENTRY_TAG); add(RegistryTags.VOTER_ENTRY_TAG);
}}; }};
bulletinBoardClient.readMessages(MessageCollectionUtils.generateFiltersFromTags(GroupsActionsTags), bulletinBoardClient.readMessages(MessageCollectionUtils.generateFiltersFromTags(GroupsActionsTags),
new LatestMessagesCallBack(callback, signers)); new LatestMessagesCallBack(callback, signers));
} }
@Override
public boolean hasVoted(VoterID voterId, RegistryCallBack callBack) {
return false;
}
} }

View File

@ -1,7 +1,11 @@
package meerkat; package meerkat;
import meerkat.bulletinboard.AsyncBulletinBoardClient;
import meerkat.crypto.DigitalSignature;
import meerkat.protobuf.VoterRegistry.*; import meerkat.protobuf.VoterRegistry.*;
import java.util.Collection;
/** /**
* Created by Vladimir Eliezer Tokarev on 1/22/2016. * Created by Vladimir Eliezer Tokarev on 1/22/2016.
* provides voters management options * provides voters management options
@ -18,6 +22,13 @@ public interface VoterRegistry {
void handleFailure(Throwable throwable); 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<DigitalSignature> signers, AsyncBulletinBoardClient communicator);
/** /**
* Adds new voter to the bulletin-board * Adds new voter to the bulletin-board
* Passes true to callBack.handleResult if the actions succeeded else false * 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 * @param callBack when the adding voter done callBack.handleResult will be called
* @return true if the adding action succeeded else return false * @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 * Sets that the voter have voted
@ -66,5 +77,13 @@ public interface VoterRegistry {
* @return list of strings (empty list if the lookup failed) * @return list of strings (empty list if the lookup failed)
*/ */
void getPersonIDDetails(VoterID voterID, RegistryCallBack callBack); 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);
} }

View File

@ -64,15 +64,18 @@ public class LatestMessagesCallBack implements FutureCallback<List<BulletinBoard
*/ */
@Override @Override
public void onSuccess(List<BulletinBoardMessage> msg) { public void onSuccess(List<BulletinBoardMessage> msg) {
BulletinBoardMessage lastAddedMessage = Collections.max(msg, (first, second) -> {
TimestampComparator comparator = new TimestampComparator();
return comparator.compare(first.getMsg().getTimestamp(), second.getMsg().getTimestamp());
});
List<BulletinBoardMessage> messages = new ArrayList<BulletinBoardMessage>(){{add(lastAddedMessage);}};
if (isAddToGroupsList(msg)) { if (isAddToGroupsList(msg)) {
List<String> groupsOfUser = GetListOfTags(msg, RegistryTags.GROUP_ID_TAG); callback.handleResult(GetListOfTags(messages, RegistryTags.GROUP_ID_TAG));
callback.handleResult(groupsOfUser);
} }
else { else {
callback.handleResult(Collections.max(msg, (first, second) -> { callback.handleResult(lastAddedMessage);
TimestampComparator comparator = new TimestampComparator();
return comparator.compare(first.getMsg().getTimestamp(), second.getMsg().getTimestamp());
}));
} }
} }

View File

@ -8,9 +8,8 @@ package meerkat.registry;
public interface RegistryTags { public interface RegistryTags {
String ID_TAG = "ID: "; String ID_TAG = "ID: ";
String VOTER_ENTRY_TAG = "VoterEntry: "; String VOTER_ENTRY_TAG = "VoterEntry: ";
String VOTER_DATA_TAG = "Data: ";
String GROUP_ID_TAG = "GroupID: "; String GROUP_ID_TAG = "GroupID: ";
String ADD_TO_GROUP_TAG = "addToGroups: "; String ADD_TO_GROUP_TAG = "setVoterGroups: ";
String VOTE_ACTION_TAG = "VoteAction: "; String VOTE_ACTION_TAG = "VoteAction: ";
} }

View File

@ -132,7 +132,8 @@ public class SimpleRegistryTest extends TestCase {
private Registry GetRegistry() private Registry GetRegistry()
{ {
Registry registry = new Registry(); Registry registry = new Registry();
registry.init(signers, bulletinBoardClient, certStream); registry.init(signers, bulletinBoardClient);
registry.loadCertificateToSigners(certStream);
return registry; return registry;
} }
@ -246,7 +247,7 @@ public class SimpleRegistryTest extends TestCase {
.addGroupID(GroupID.newBuilder().setId(groupId)).build(); .addGroupID(GroupID.newBuilder().setId(groupId)).build();
Registry registry = GetRegistry(); Registry registry = GetRegistry();
registry.addToGroups(voterInfo, handler); registry.setVoterGroups(voterInfo, handler);
jobSemaphore.acquire(); jobSemaphore.acquire();
assertEquals(1, handler.counter); assertEquals(1, handler.counter);
@ -282,7 +283,7 @@ public class SimpleRegistryTest extends TestCase {
this.certStream = getClass().getResourceAsStream(CERT1_PEM_EXAMPLE); this.certStream = getClass().getResourceAsStream(CERT1_PEM_EXAMPLE);
Registry registry = GetRegistry(); Registry registry = GetRegistry();
registry.addToGroups(voterInfo, handler); registry.setVoterGroups(voterInfo, handler);
jobSemaphore.acquire(); jobSemaphore.acquire();
assertEquals(1, handler.counter ); assertEquals(1, handler.counter );
@ -318,7 +319,7 @@ public class SimpleRegistryTest extends TestCase {
jobSemaphore.acquire(1); jobSemaphore.acquire(1);
assertEquals(id, findTagWithPrefix(personalHandler.data, RegistryTags.ID_TAG)); assertEquals(id, findTagWithPrefix(personalHandler.data, RegistryTags.ID_TAG));
assertTrue(findTagWithPrefix(personalHandler.data, RegistryTags.VOTER_DATA_TAG).contains(data)); assertTrue(findTagWithPrefix(personalHandler.data, data) != null);
} }
} }