diff --git a/.gitignore b/.gitignore index 25803df..6339218 100644 --- a/.gitignore +++ b/.gitignore @@ -13,3 +13,4 @@ out *.prefs *.project *.classpath +bulletin-board-server/local-instances/meerkat.db diff --git a/build.gradle-template b/build.gradle-template index 14cb9dd..60ec7c9 100644 --- a/build.gradle-template +++ b/build.gradle-template @@ -57,6 +57,21 @@ dependencies { /*==== You probably don't have to edit below this line =======*/ +// Setup test configuration that can appear as a dependency in +// other subprojects +configurations { + testOutput.extendsFrom (testCompile) +} + +task testJar(type: Jar, dependsOn: testClasses) { + classifier = 'tests' + from sourceSets.test.output +} + +artifacts { + testOutput testJar +} + // The run task added by the application plugin // is also of type JavaExec. tasks.withType(JavaExec) { diff --git a/bulletin-board-server/.gitignore b/bulletin-board-server/.gitignore new file mode 100644 index 0000000..ae3c172 --- /dev/null +++ b/bulletin-board-server/.gitignore @@ -0,0 +1 @@ +/bin/ diff --git a/bulletin-board-server/build.gradle b/bulletin-board-server/build.gradle index 031ce36..790f0d3 100644 --- a/bulletin-board-server/build.gradle +++ b/bulletin-board-server/build.gradle @@ -9,8 +9,10 @@ apply plugin: 'java' apply plugin: 'eclipse' apply plugin: 'idea' +//apply plugin: 'application' + //apply plugin: 'jetty' -//mainClassName = 'Demo' +//mainClassName = 'SQLiteIntegrationTest' apply plugin: 'maven-publish' @@ -42,6 +44,8 @@ dependencies { // Jersey for RESTful API compile 'org.glassfish.jersey.containers:jersey-container-servlet:2.22.+' + compile 'org.xerial:sqlite-jdbc:3.7.+' + // Logging compile 'org.slf4j:slf4j-api:1.7.7' @@ -51,6 +55,9 @@ dependencies { // Google protobufs compile 'com.google.protobuf:protobuf-java:3.+' + // Depend on test resources from meerkat-common + testCompile project(path: ':meerkat-common', configuration: 'testOutput') + testCompile 'junit:junit:4.+' runtime 'org.codehaus.groovy:groovy:2.4.+' @@ -61,6 +68,10 @@ test { exclude '**/*IntegrationTest*' } +task debugIntegrationTest(type: Test){ + include '**/*IntegrationTest*' + debug = true +} task integrationTest(type: Test) { include '**/*IntegrationTest*' @@ -68,7 +79,9 @@ task integrationTest(type: Test) { gretty { httpPort = 8081 + contextPath = '/' integrationTestTask = 'integrationTest' + loggingLevel = 'TRACE' } diff --git a/bulletin-board-server/src/main/java/meerkat/bulletinboard/httpserver/BulletinBoardHttpServer.java b/bulletin-board-server/src/main/java/meerkat/bulletinboard/httpserver/BulletinBoardHttpServer.java index 10683cb..6d344fe 100644 --- a/bulletin-board-server/src/main/java/meerkat/bulletinboard/httpserver/BulletinBoardHttpServer.java +++ b/bulletin-board-server/src/main/java/meerkat/bulletinboard/httpserver/BulletinBoardHttpServer.java @@ -11,7 +11,7 @@ import javax.servlet.http.HttpServletResponse; import meerkat.bulletinboard.BulletinBoardServer; import meerkat.bulletinboard.sqlserver.SQLiteBulletinBoardServer; import meerkat.comm.CommunicationException; -import meerkat.protobuf.Voting.BulletinBoardMessage; +import meerkat.protobuf.BulletinBoardAPI.*; public class BulletinBoardHttpServer extends HttpServlet { diff --git a/bulletin-board-server/src/main/java/meerkat/bulletinboard/service/HelloProtoBuf.java b/bulletin-board-server/src/main/java/meerkat/bulletinboard/service/HelloProtoBuf.java index f848a47..baa1d98 100644 --- a/bulletin-board-server/src/main/java/meerkat/bulletinboard/service/HelloProtoBuf.java +++ b/bulletin-board-server/src/main/java/meerkat/bulletinboard/service/HelloProtoBuf.java @@ -3,8 +3,7 @@ package meerkat.bulletinboard.service; import com.google.protobuf.ByteString; import com.google.protobuf.Message; import meerkat.protobuf.Crypto; -import meerkat.protobuf.Voting; -import meerkat.protobuf.Voting.BulletinBoardMessage; +import meerkat.protobuf.BulletinBoardAPI.*; import java.util.Arrays; import java.util.List; @@ -16,7 +15,7 @@ public class HelloProtoBuf { public Message sayHello() { BulletinBoardMessage.Builder msg = BulletinBoardMessage.newBuilder(); - Voting.UnsignedBulletinBoardMessage.Builder unsigned = Voting.UnsignedBulletinBoardMessage.newBuilder(); + UnsignedBulletinBoardMessage.Builder unsigned = UnsignedBulletinBoardMessage.newBuilder(); unsigned.setData(ByteString.copyFromUtf8("Hello World!")); List tags = Arrays.asList("Greetings", "FirstPrograms"); unsigned.addAllTags(tags); @@ -24,7 +23,7 @@ public class HelloProtoBuf { Crypto.Signature.Builder sig = Crypto.Signature.newBuilder(); sig.setData(ByteString.copyFromUtf8("deadbeef")); - msg.setSig(sig); + msg.addSig(sig); return msg.build(); } diff --git a/bulletin-board-server/src/main/java/meerkat/bulletinboard/sqlserver/BulletinBoardSQLServer.java b/bulletin-board-server/src/main/java/meerkat/bulletinboard/sqlserver/BulletinBoardSQLServer.java index 0ed06c9..9978cf5 100644 --- a/bulletin-board-server/src/main/java/meerkat/bulletinboard/sqlserver/BulletinBoardSQLServer.java +++ b/bulletin-board-server/src/main/java/meerkat/bulletinboard/sqlserver/BulletinBoardSQLServer.java @@ -1,5 +1,6 @@ package meerkat.bulletinboard.sqlserver; +import java.util.Arrays; import java.util.List; import com.google.protobuf.ProtocolStringList; @@ -11,13 +12,12 @@ import java.sql.SQLException; import java.sql.Statement; import meerkat.bulletinboard.BulletinBoardServer; -import meerkat.bulletinboard.MessageFilter; import meerkat.comm.CommunicationException; +import meerkat.protobuf.BulletinBoardAPI.*; +import meerkat.protobuf.Crypto.Signature; import meerkat.protobuf.Crypto.SignatureVerificationKey; -import meerkat.protobuf.Voting.BulletinBoardMessage; import meerkat.crypto.Digest; import meerkat.crypto.concrete.SHA256Digest; -import meerkat.protobuf.Voting.MessageID; public abstract class BulletinBoardSQLServer implements BulletinBoardServer{ @@ -53,53 +53,109 @@ public abstract class BulletinBoardSQLServer implements BulletinBoardServer{ * @return TRUE if the message is authenticated and FALSE otherwise. */ private boolean verifyMessage(BulletinBoardMessage msg) { + //TODO: Replace with actual verification. return true; } /** - * This procedure makes sure that all tags in the given list have an entry in the tags list. - * @param tagIterator + * This procedure makes sure that all tags in the given list have an entry in the tags table. + * @param tags */ - protected abstract void insertNewTags(String[] tags) throws CommunicationException; + protected abstract void insertNewTags(String[] tags) throws SQLException; + + /** + * This procedure is used to convert a boolean to a BoolMsg. + * @param b is the boolean to convert. + * @return a ProtoBuf message with boolean payload. + */ + private BoolMsg boolToBoolMsg(boolean b){ + return BoolMsg.newBuilder() + .setValue(b) + .build(); + } @Override - public boolean postMessage(BulletinBoardMessage msg) throws CommunicationException { + public BoolMsg postMessage(BulletinBoardMessage msg) throws CommunicationException { + if (!verifyMessage(msg)) { - return false; + return boolToBoolMsg(false); } PreparedStatement pstmt; + ResultSet rs; String sql; byte[] msgID; + long entryNum; ProtocolStringList tagList; String[] tags; + List signatureList; + Signature[] signatures; + + // Calculate message ID (depending only on the the unsigned message) + digest.reset(); - digest.update(msg); + digest.update(msg.getMsg()); msgID = digest.digest(); + // Add message to table if needed and store entry number of message. + try { - sql = "INSERT INTO MsgTable (Id, Data, Signature) VALUES(?,?,?)"; - pstmt = connection.prepareStatement(sql); - pstmt.setBytes(1, msgID); - pstmt.setBytes(2,msg.getMsg().getData().toByteArray()); - pstmt.setBytes(3,msg.getSig().toByteArray()); - pstmt.executeUpdate(); + sql = "SELECT EntryNum From MsgTable WHERE MsgId = ?"; + pstmt = connection.prepareStatement(sql); + pstmt.setBytes(1, msgID); + rs = pstmt.executeQuery(); + + if (rs.next()){ + + entryNum = rs.getLong(1); + + } else{ + + sql = "INSERT INTO MsgTable (MsgId, Msg) VALUES(?,?)"; + pstmt = connection.prepareStatement(sql); + pstmt.setBytes(1, msgID); + pstmt.setBytes(2, msg.toByteArray()); + pstmt.executeUpdate(); + + rs = pstmt.getGeneratedKeys(); + rs.next(); + entryNum = rs.getLong(1); + + } + pstmt.close(); + } catch (SQLException e) { + throw new CommunicationException("Error inserting into MsgTable: " + e.getMessage()); + } + + // Retrieve tags and store new ones in tag table. + + try { + tagList = msg.getMsg().getTagsList(); tags = new String[tagList.size()]; + tags = tagList.toArray(tags); insertNewTags(tags); - sql = "INSERT INTO MsgTagTable (MsgId, TagId) SELECT (?, TagId) FROM TagTable WHERE tag=?"; + } catch (SQLException e) { + throw new CommunicationException(e.getMessage()); + } + + // Connect message to tags. + + try{ + sql = "INSERT OR IGNORE INTO MsgTagTable (TagId, EntryNum) SELECT TagTable.TagId, ? AS EntryNum FROM TagTable WHERE Tag = ?"; pstmt = connection.prepareStatement(sql); + pstmt.setLong(1, entryNum); + for (String tag : tags){ - pstmt.setBytes(1, msgID); pstmt.setString(2, tag); pstmt.addBatch(); } @@ -108,19 +164,43 @@ public abstract class BulletinBoardSQLServer implements BulletinBoardServer{ pstmt.close(); } catch (SQLException e) { - throw new CommunicationException("Error accessing DB: " + e.getMessage()); + throw new CommunicationException("Error Linking tags: " + e.getMessage()); + } + + // Retrieve signatures. + + signatureList = msg.getSigList(); + signatures = new Signature[signatureList.size()]; + signatures = signatureList.toArray(signatures); + + // Connect message to signatures. + + try{ + sql = "INSERT OR IGNORE INTO SignatureTable (EntryNum, SignerId, Signature) VALUES (?,?,?)"; + pstmt = connection.prepareStatement(sql); + + pstmt.setLong(1, entryNum); + + for (Signature sig : signatures){ + + pstmt.setBytes(2, sig.getSignerId().toByteArray()); + pstmt.setBytes(3, sig.toByteArray()); + pstmt.addBatch(); + } + + pstmt.executeBatch(); + pstmt.close(); + + } catch (SQLException e) { + throw new CommunicationException("Error Linking tags: " + e.getMessage()); } - return true; - } - - @Override - public List readMessages(MessageFilter filter, int max) { - // TODO Auto-generated method stub - return null; + return boolToBoolMsg(true); } - public void testPrint(){ + public String testPrint(){ + + String s = ""; try { @@ -128,20 +208,30 @@ public abstract class BulletinBoardSQLServer implements BulletinBoardServer{ ResultSet rs = statement.executeQuery("select * from MsgTable"); while (rs.next()) { // read the result set - System.out.println("data = " + rs.getString("Data")); - System.out.println("id = " + rs.getInt("Id")); + s += "entry = " + rs.getInt("EntryNum") + " \n"; + s += "id = " + Arrays.toString(rs.getBytes("MsgId")) + " \n"; + s += "msg = " + Arrays.toString(rs.getBytes("Msg")) + " \n"; + s += "signer ID = " + Arrays.toString(rs.getBytes("SignerId")) + "\t\n
"; + } + + rs = statement.executeQuery("select * from TagTable"); + while (rs.next()) { + // read the result set + s += "Tag = " + rs.getString("Tag") + " \n"; + s += "TagId = " + rs.getInt("TagId") + "\t\n
"; } rs = statement.executeQuery("select * from MsgTagTable"); while (rs.next()) { // read the result set - System.out.println("MsgId = " + rs.getInt("MsgId")); - System.out.println("TagId = " + rs.getString("TagId")); + s += "MsgId = " + Arrays.toString(rs.getBytes("MsgId")) + " \n"; + s += "TagId = " + rs.getInt("TagId") + "\t\n
"; } } catch(SQLException e){ - System.out.println("Error reading from DB"); + s += "Error reading from DB"; } + return s; } } diff --git a/bulletin-board-server/src/main/java/meerkat/bulletinboard/sqlserver/SQLiteBulletinBoardServer.java b/bulletin-board-server/src/main/java/meerkat/bulletinboard/sqlserver/SQLiteBulletinBoardServer.java index 6c9cf40..abc87a2 100644 --- a/bulletin-board-server/src/main/java/meerkat/bulletinboard/sqlserver/SQLiteBulletinBoardServer.java +++ b/bulletin-board-server/src/main/java/meerkat/bulletinboard/sqlserver/SQLiteBulletinBoardServer.java @@ -2,15 +2,17 @@ package meerkat.bulletinboard.sqlserver; import java.sql.DriverManager; import java.sql.PreparedStatement; +import java.sql.ResultSet; import java.sql.SQLException; import java.sql.Statement; import java.util.List; -import meerkat.bulletinboard.MessageFilter; +import com.google.protobuf.InvalidProtocolBufferException; + +import meerkat.protobuf.BulletinBoardAPI.*; +import meerkat.protobuf.Crypto.Signature; import meerkat.bulletinboard.sqlserver.BulletinBoardSQLServer; import meerkat.comm.CommunicationException; -import meerkat.protobuf.Voting.BulletinBoardMessage; - public class SQLiteBulletinBoardServer extends BulletinBoardSQLServer { @@ -20,20 +22,24 @@ public class SQLiteBulletinBoardServer extends BulletinBoardSQLServer { * This procedure initializes: * 1. The database connection * 2. The database tables (if they do not yet exist). - * 3. */ + @Override public void init() throws CommunicationException { try{ - connection = DriverManager.getConnection("jdbc:sqlite:./local-instances/meerkat.db"); + connection = DriverManager.getConnection("jdbc:sqlite:local-instances/meerkat.db"); Statement statement = connection.createStatement(); statement.setQueryTimeout(TIMEOUT); - - statement.executeUpdate("CREATE TABLE IF NOT EXISTS MsgTable (EntryNum INTEGER, Id varbinary(1000) UNIQUE, Data varbinary(1000), Signature varbinary(1000), PRIMARY KEY (EntryNum ASC))"); - statement.executeUpdate("CREATE TABLE IF NOT EXISTS TagTable (Id int, Tag v archar(50) UNIQUE, PRIMARY KEY (Id ASC))"); - statement.executeUpdate("CREATE TABLE IF NOT EXISTS MsgTagTable (MsgId varbinary(1000), TagId int, FOREIGN KEY (MsgId) REFERENCES MsgTable(Id), FOREIGN KEY (TagId) REFERENCES TagTable(Id))"); + + statement.executeUpdate("CREATE TABLE IF NOT EXISTS MsgTable (EntryNum INTEGER PRIMARY KEY, MsgId BLOB UNIQUE, Msg BLOB)"); + + statement.executeUpdate("CREATE TABLE IF NOT EXISTS TagTable (TagId INTEGER PRIMARY KEY, Tag varchar(50) UNIQUE)"); + statement.executeUpdate("CREATE TABLE IF NOT EXISTS MsgTagTable (EntryNum BLOB, TagId INTEGER, FOREIGN KEY (EntryNum) REFERENCES MsgTable(EntryNum), FOREIGN KEY (TagId) REFERENCES TagTable(TagId), UNIQUE (EntryNum, TagID))"); + + statement.executeUpdate("CREATE TABLE IF NOT EXISTS SignatureTable (EntryNum BLOB, SignerId BLOB, Signature BLOB UNIQUE, FOREIGN KEY (EntryNum) REFERENCES MsgTable(EntryNum))"); + statement.executeUpdate("CREATE INDEX IF NOT EXISTS SignerIndex ON SignatureTable(SignerId)"); statement.close(); @@ -41,18 +47,11 @@ public class SQLiteBulletinBoardServer extends BulletinBoardSQLServer { } catch (SQLException e) { - throw new CommunicationException("Couldn't form a connection with the database"); + throw new CommunicationException("Couldn't form a connection with the database" + e.getMessage()); } } - - - @Override - public List readMessages(MessageFilter filter, int max) { - // TODO Auto-generated method stub - return null; - } public void close() throws CommunicationException{ @@ -66,9 +65,8 @@ public class SQLiteBulletinBoardServer extends BulletinBoardSQLServer { } - @Override - protected void insertNewTags(String[] tags) throws CommunicationException { + protected void insertNewTags(String[] tags) throws SQLException { PreparedStatement pstmt; String sql; @@ -87,9 +85,178 @@ public class SQLiteBulletinBoardServer extends BulletinBoardSQLServer { pstmt.close(); } catch (SQLException e){ - throw new CommunicationException("Error adding new tags to table"); + throw new SQLException("Error adding new tags to table: " + e.getMessage()); } } + @Override + public BoolMsg postMessage(BulletinBoardMessage msg) throws CommunicationException { + return super.postMessage(msg); + } + + @Override + public BulletinBoardMessageList readMessages(MessageFilterList filterList) throws CommunicationException{ + + PreparedStatement pstmt; + ResultSet messages, signatures; + + long entryNum; + BulletinBoardMessageList.Builder resultListBuilder = BulletinBoardMessageList.newBuilder(); + BulletinBoardMessage.Builder messageBuilder; + + String sql; + String sqlSuffix = ""; + + List filters = filterList.getFilterList(); + int i; + + boolean tagsRequired = false; + boolean signaturesRequired = false; + + boolean isFirstFilter = true; + + // Check if Tag/Signature tables are required for filtering purposes. + + for (MessageFilter filter : filters){ + if (filter.getType() == FilterType.TAG){ + tagsRequired = true; + } else if (filter.getType() == FilterType.SIGNER_ID){ + signaturesRequired = true; + } + } + + sql = "SELECT MsgTable.EntryNum, MsgTable.Msg FROM MsgTable"; + + if (tagsRequired){ + sql += " INNER JOIN MsgTagTable ON MsgTable.EntryNum = MsgTagTable.EntryNum"; + sql += " INNER JOIN TagTable ON TagTable.TagId = MsgTagTable.TagId"; + } + + if (signaturesRequired){ + sql += " INNER JOIN SignatureTable ON SignatureTable.EntryNum = MsgTable.EntryNum"; + } + + // Add conditions. + + if (!filters.isEmpty()){ + sql += " WHERE"; + + for (MessageFilter filter : filters){ + + if (filter.getType().getNumber() != FilterType.MAX_MESSAGES_VALUE){ + if (isFirstFilter){ + isFirstFilter = false; + } else{ + sql += " AND"; + } + } + + switch (filter.getType().getNumber()){ + case FilterType.EXACT_ENTRY_VALUE: + sql += " MsgTable.EntryNum = ?"; + break; + case FilterType.MAX_ENTRY_VALUE: + sql += " MsgTable.EntryNum <= ?"; + break; + case FilterType.MAX_MESSAGES_VALUE: + sqlSuffix += " LIMIT = ?"; + break; + case FilterType.MSG_ID_VALUE: + sql += " MsgTableMsgId = ?"; + break; + case FilterType.SIGNER_ID_VALUE: + sql += " SignatureTable.SignerId = ?"; + break; + case FilterType.TAG_VALUE: + sql += " TagTable.Tag = ?"; + break; + } + } + + sql += sqlSuffix; + } + + // Make query. + + try { + pstmt = connection.prepareStatement(sql); + + // Specify values for filters. + + i = 1; + for (MessageFilter filter : filters){ + + switch (filter.getType().getNumber()){ + + case FilterType.EXACT_ENTRY_VALUE: // Go through. + case FilterType.MAX_ENTRY_VALUE: + pstmt.setLong(i, filter.getEntry()); + i++; + break; + + case FilterType.MSG_ID_VALUE: // Go through. + case FilterType.SIGNER_ID_VALUE: + pstmt.setBytes(i, filter.getId().toByteArray()); + i++; + break; + + case FilterType.TAG_VALUE: + pstmt.setString(i, filter.getTag()); + break; + + // The max-messages condition is applied as a suffix. Therefore, it is treated differently. + case FilterType.MAX_MESSAGES_VALUE: + pstmt.setLong(filters.size(), filter.getMaxMessages()); + break; + + } + } + + // Run query. + + messages = pstmt.executeQuery(); + + // Compile list of messages. + + sql = "SELECT Signature FROM SignatureTable WHERE EntryNum = ?"; + pstmt = connection.prepareStatement(sql); + + while (messages.next()){ + + // Get entry number and retrieve signatures. + + entryNum = messages.getLong(1); + pstmt.setLong(1, entryNum); + signatures = pstmt.executeQuery(); + + // Create message and append signatures. + + messageBuilder = BulletinBoardMessage.newBuilder() + .setEntryNum(entryNum) + .setMsg(UnsignedBulletinBoardMessage.parseFrom(messages.getBytes(2))); + + while (signatures.next()){ + messageBuilder.addSig(Signature.parseFrom(signatures.getBytes(1))); + } + + // Finalize message and add to message list. + + resultListBuilder.addMessage(messageBuilder.build()); + + } + + pstmt.close(); + + } catch (SQLException e){ + throw new CommunicationException("Error reading messages from DB: " + e.getMessage()); + } catch (InvalidProtocolBufferException e) { + throw new CommunicationException("Invalid data from DB: " + e.getMessage()); + } + + //Combine results and return. + + return resultListBuilder.build(); + } + } diff --git a/bulletin-board-server/src/main/java/meerkat/bulletinboard/webapp/BulletinBoardWebApp.java b/bulletin-board-server/src/main/java/meerkat/bulletinboard/webapp/BulletinBoardWebApp.java new file mode 100644 index 0000000..ed162e1 --- /dev/null +++ b/bulletin-board-server/src/main/java/meerkat/bulletinboard/webapp/BulletinBoardWebApp.java @@ -0,0 +1,63 @@ +package meerkat.bulletinboard.webapp; + +import javax.annotation.PostConstruct; +import javax.annotation.PreDestroy; +import javax.ws.rs.Consumes; +import javax.ws.rs.GET; +import javax.ws.rs.POST; +import javax.ws.rs.Path; +import javax.ws.rs.Produces; +import javax.ws.rs.core.MediaType; + +import meerkat.bulletinboard.BulletinBoardServer; +import meerkat.bulletinboard.sqlserver.SQLiteBulletinBoardServer; +import meerkat.comm.CommunicationException; +import meerkat.protobuf.BulletinBoardAPI.BoolMsg; +import meerkat.protobuf.BulletinBoardAPI.BulletinBoardMessage; +import meerkat.protobuf.BulletinBoardAPI.BulletinBoardMessageList; +import meerkat.protobuf.BulletinBoardAPI.MessageFilterList; +import meerkat.rest.Constants; + +@Path("/sqlserver") +public class BulletinBoardWebApp implements BulletinBoardServer{ + + BulletinBoardServer bulletinBoard; + + @PostConstruct + @Override + public void init() throws CommunicationException { + bulletinBoard = new SQLiteBulletinBoardServer(); + bulletinBoard.init(); + } + + @Path("postmessage") + @POST + @Consumes(Constants.MEDIATYPE_PROTOBUF) + @Produces(Constants.MEDIATYPE_PROTOBUF) + @Override + public BoolMsg postMessage(BulletinBoardMessage msg) throws CommunicationException { + return bulletinBoard.postMessage(msg); + } + + @Path("readmessages") + @POST + @Consumes(Constants.MEDIATYPE_PROTOBUF) + @Produces(Constants.MEDIATYPE_PROTOBUF) + @Override + public BulletinBoardMessageList readMessages(MessageFilterList filterList) throws CommunicationException { + return bulletinBoard.readMessages(filterList); + } + + @Override + @PreDestroy + public void close() throws CommunicationException { + bulletinBoard.close(); + } + + @GET + @Produces(MediaType.TEXT_PLAIN) + public String test() { + return "This BulletinBoard is up and running!\n Please consult the API documents to perform queries."; + } + +} diff --git a/bulletin-board-server/src/main/java/meerkat/bulletinboard/webapp/HelloProtoWebApp.java b/bulletin-board-server/src/main/java/meerkat/bulletinboard/webapp/HelloProtoWebApp.java index cbe2ae5..c0791c3 100644 --- a/bulletin-board-server/src/main/java/meerkat/bulletinboard/webapp/HelloProtoWebApp.java +++ b/bulletin-board-server/src/main/java/meerkat/bulletinboard/webapp/HelloProtoWebApp.java @@ -1,22 +1,50 @@ package meerkat.bulletinboard.webapp; - +import com.google.protobuf.ByteString; import com.google.protobuf.Message; import meerkat.bulletinboard.service.HelloProtoBuf; +import meerkat.protobuf.Crypto.*; +import meerkat.protobuf.BulletinBoardAPI.*; import meerkat.rest.Constants; -import service.HelloWorldService; +import javax.annotation.PostConstruct; import javax.ws.rs.GET; import javax.ws.rs.Path; import javax.ws.rs.Produces; @Path("/proto") public class HelloProtoWebApp { - private static HelloProtoBuf helloProtoBuf = new HelloProtoBuf(); + private HelloProtoBuf helloProtoBuf; - @GET - @Produces(Constants.MEDIATYPE_PROTOBUF) - public Message hello() { - return helloProtoBuf.sayHello(); - } + @PostConstruct + public void init() { + helloProtoBuf = new HelloProtoBuf(); + } + + @GET + @Produces(Constants.MEDIATYPE_PROTOBUF) + public Message hello() { + byte[] b1 = { (byte) 1, (byte) 2, (byte) 3, (byte) 4 }; + byte[] b2 = { (byte) 11, (byte) 12, (byte) 13, (byte) 14 }; + byte[] b3 = {(byte) 21, (byte)22, (byte) 23, (byte) 24}; + + Message msg; + + if (helloProtoBuf != null) { + msg = helloProtoBuf.sayHello(); + } else { + msg = BulletinBoardMessage.newBuilder() + .setMsg(UnsignedBulletinBoardMessage.newBuilder() + .addTags("Signature") + .addTags("Trustee") + .setData(ByteString.copyFrom(b1)).build()) + .addSig(Signature.newBuilder() + .setType(SignatureType.DSA) + .setData(ByteString.copyFrom(b2)) + .setSignerId(ByteString.copyFrom(b3)).build()) + .build(); + } + + return msg; + } } diff --git a/bulletin-board-server/src/main/java/service/HelloWorldService.java b/bulletin-board-server/src/main/java/service/HelloWorldService.java deleted file mode 100644 index dbdf159..0000000 --- a/bulletin-board-server/src/main/java/service/HelloWorldService.java +++ /dev/null @@ -1,9 +0,0 @@ -package service; - - - -public class HelloWorldService { - public String sayHello() { - return "Hello, World!"; - } -} diff --git a/bulletin-board-server/src/main/java/webapp/HelloWebApp.java b/bulletin-board-server/src/main/java/webapp/HelloWebApp.java deleted file mode 100644 index 0a518f7..0000000 --- a/bulletin-board-server/src/main/java/webapp/HelloWebApp.java +++ /dev/null @@ -1,16 +0,0 @@ -package webapp; - -import javax.ws.rs.GET; -import javax.ws.rs.Path; - -import service.HelloWorldService; - -@Path("/hello") -public class HelloWebApp { - private static HelloWorldService helloWorldService = new HelloWorldService(); - - @GET - public String hello() { - return helloWorldService.sayHello(); - } -} diff --git a/bulletin-board-server/src/main/proto/meerkat/bulletin_board_server.proto b/bulletin-board-server/src/main/proto/meerkat/bulletin_board_server.proto new file mode 100644 index 0000000..e31485b --- /dev/null +++ b/bulletin-board-server/src/main/proto/meerkat/bulletin_board_server.proto @@ -0,0 +1,9 @@ +syntax = "proto3"; + +package meerkat; + +option java_package = "meerkat.protobuf"; + +message Boolean { + bool value = 1; +} \ No newline at end of file diff --git a/bulletin-board-server/src/main/webapp/META-INF/jetty-env.xml b/bulletin-board-server/src/main/webapp/META-INF/jetty-env.xml new file mode 100644 index 0000000..c4d368f --- /dev/null +++ b/bulletin-board-server/src/main/webapp/META-INF/jetty-env.xml @@ -0,0 +1,12 @@ + + + + + org.eclipse.jetty.server.webapp.ContainerIncludeJarPattern + none + + + org.eclipse.jetty.server.webapp.WebInfIncludeJarPattern + none + + \ No newline at end of file diff --git a/bulletin-board-server/src/main/webapp/WEB-INF/web.xml b/bulletin-board-server/src/main/webapp/WEB-INF/web.xml index ba674d2..cc90843 100644 --- a/bulletin-board-server/src/main/webapp/WEB-INF/web.xml +++ b/bulletin-board-server/src/main/webapp/WEB-INF/web.xml @@ -6,7 +6,7 @@ jersey.config.server.provider.packages - webapp, meerkat + meerkat 1 diff --git a/bulletin-board-server/src/test/java/HelloIntegrationTest.java b/bulletin-board-server/src/test/java/HelloIntegrationTest.java deleted file mode 100644 index 9de027e..0000000 --- a/bulletin-board-server/src/test/java/HelloIntegrationTest.java +++ /dev/null @@ -1,22 +0,0 @@ -import javax.ws.rs.client.Client; -import javax.ws.rs.client.ClientBuilder; -import javax.ws.rs.client.WebTarget; -import static org.hamcrest.CoreMatchers.is; -import static org.hamcrest.MatcherAssert.assertThat; -import org.junit.Test; - -public class HelloIntegrationTest { - - private static String PROP_GETTY_URL = "gretty.httpBaseURI"; - private static String BASE_URL = System.getProperty(PROP_GETTY_URL); - private static String HELLO_URL = BASE_URL + "/hello"; - - @Test - public void testHello() throws Exception { - Client client = ClientBuilder.newClient(); - WebTarget webTarget = client.target(HELLO_URL); - String response = webTarget.request().get(String.class); - System.out.println(response); - assertThat(response, is("Hello, World!")); - } -} diff --git a/bulletin-board-server/src/test/java/meerkat/bulletinboard/HelloProtoIntegrationTest.java b/bulletin-board-server/src/test/java/meerkat/bulletinboard/HelloProtoIntegrationTest.java index 4a6cbb3..a34de1d 100644 --- a/bulletin-board-server/src/test/java/meerkat/bulletinboard/HelloProtoIntegrationTest.java +++ b/bulletin-board-server/src/test/java/meerkat/bulletinboard/HelloProtoIntegrationTest.java @@ -1,6 +1,6 @@ package meerkat.bulletinboard; -import meerkat.protobuf.Voting; +import meerkat.protobuf.BulletinBoardAPI.*; import meerkat.rest.Constants; import meerkat.rest.ProtobufMessageBodyReader; import meerkat.rest.ProtobufMessageBodyWriter; @@ -17,10 +17,10 @@ import static org.hamcrest.MatcherAssert.assertThat; * Created by talm on 10/11/15. */ public class HelloProtoIntegrationTest { - private static String PROP_GETTY_URL = "gretty.httpBaseURI"; - private static String BASE_URL = System.getProperty(PROP_GETTY_URL); - private static String HELLO_URL = BASE_URL + "/proto"; + private static String DEFAULT_BASE_URL = "http://localhost:8081/"; + private static String BASE_URL = System.getProperty(PROP_GETTY_URL, DEFAULT_BASE_URL); + private static String HELLO_URL = "proto"; @Test public void testHello() throws Exception { @@ -28,8 +28,9 @@ public class HelloProtoIntegrationTest { client.register(ProtobufMessageBodyReader.class); client.register(ProtobufMessageBodyWriter.class); - WebTarget webTarget = client.target(HELLO_URL); - Voting.BulletinBoardMessage response = webTarget.request(Constants.MEDIATYPE_PROTOBUF).get(Voting.BulletinBoardMessage.class); + WebTarget webTarget = client.target(BASE_URL).path(HELLO_URL); + BulletinBoardMessage response = webTarget.request(Constants.MEDIATYPE_PROTOBUF) + .get(BulletinBoardMessage.class); System.out.println(response.getMsg().getData()); diff --git a/bulletin-board-server/src/test/java/meerkat/bulletinboard/SQLiteIntegrationTest.java b/bulletin-board-server/src/test/java/meerkat/bulletinboard/SQLiteIntegrationTest.java deleted file mode 100644 index 0ebb8e0..0000000 --- a/bulletin-board-server/src/test/java/meerkat/bulletinboard/SQLiteIntegrationTest.java +++ /dev/null @@ -1,41 +0,0 @@ -package meerkat.bulletinboard; - - -import com.google.protobuf.ByteString; - -import meerkat.bulletinboard.sqlserver.SQLiteBulletinBoardServer; -import meerkat.comm.CommunicationException; -import meerkat.protobuf.Crypto.*; -import meerkat.protobuf.Voting.*; - -public class SQLiteIntegrationTest { - public static void main(){ - byte[] b1 = {(byte) 1, (byte)2, (byte) 3, (byte) 4}; - byte[] b2 = {(byte) 11, (byte)12, (byte) 13, (byte) 14}; - - BulletinBoardMessage msg = BulletinBoardMessage.newBuilder() - .setMsg(UnsignedBulletinBoardMessage.newBuilder() - .setTags(0, "signature") - .setTags(1, "Trustee") - .setData(ByteString.copyFrom(b1)) - .build()) - .setSig(Signature.newBuilder() - .setType(SignatureType.DSA) - .setData(ByteString.copyFrom(b2)) - .build()) - .build(); - - SQLiteBulletinBoardServer bbs = new SQLiteBulletinBoardServer(); - - try{ - bbs.init(); - - bbs.postMessage(msg); - bbs.testPrint(); - - bbs.close(); - } catch(CommunicationException e){ - System.out.println(e.getMessage()); - } - } -} diff --git a/bulletin-board-server/src/test/java/meerkat/bulletinboard/SQLiteServerIntegrationTest.java b/bulletin-board-server/src/test/java/meerkat/bulletinboard/SQLiteServerIntegrationTest.java new file mode 100644 index 0000000..558d52d --- /dev/null +++ b/bulletin-board-server/src/test/java/meerkat/bulletinboard/SQLiteServerIntegrationTest.java @@ -0,0 +1,173 @@ +package meerkat.bulletinboard; + + +import com.google.protobuf.ByteString; +import com.google.protobuf.TextFormat; + +import meerkat.protobuf.Crypto.*; +import meerkat.protobuf.BulletinBoardAPI.*; +import meerkat.rest.Constants; +import meerkat.rest.ProtobufMessageBodyReader; +import meerkat.rest.ProtobufMessageBodyWriter; + +import org.junit.Before; +import org.junit.Test; + +import javax.ws.rs.client.Client; +import javax.ws.rs.client.ClientBuilder; +import javax.ws.rs.client.Entity; +import javax.ws.rs.client.WebTarget; +import javax.ws.rs.core.Response; + +public class SQLiteServerIntegrationTest { + + private static String PROP_GETTY_URL = "gretty.httpBaseURI"; + private static String DEFAULT_BASE_URL = "localhost:8081"; + private static String BASE_URL = System.getProperty(PROP_GETTY_URL, DEFAULT_BASE_URL); + private static String SQL_SERVER_POST = "sqlserver/postmessage"; + private static String SQL_SERVER_GET = "sqlserver/readmessages"; + + Client client; +// Connection connection; + + @Before + public void setup() throws Exception { + client = ClientBuilder.newClient(); + client.register(ProtobufMessageBodyReader.class); + client.register(ProtobufMessageBodyWriter.class); + + } + + @Test + public void testPost() throws Exception { + byte[] b1 = {(byte) 1, (byte) 2, (byte) 3, (byte) 4}; + byte[] b2 = {(byte) 11, (byte) 12, (byte) 13, (byte) 14}; + byte[] b3 = {(byte) 21, (byte) 22, (byte) 23, (byte) 24}; + byte[] b4 = {(byte) 4, (byte) 5, (byte) 100, (byte) -50, (byte) 0}; + + WebTarget webTarget; + Response response; + BoolMsg bool; + + BulletinBoardMessage msg; + + MessageFilterList filterList; + BulletinBoardMessageList msgList; + +// try{ +// connection = DriverManager.getConnection("jdbc:sqlite:d:/arbel/projects/meerkat-java/bulletin-board-server/local-instances/meerkat.db"); +// } catch (SQLException e) { +// System.err.println(e.getMessage()); +// assert false; +// } + + // Test writing mechanism + + System.err.println("******** Testing: " + SQL_SERVER_POST); + webTarget = client.target(BASE_URL).path(SQL_SERVER_POST); + + msg = BulletinBoardMessage.newBuilder() + .setMsg(UnsignedBulletinBoardMessage.newBuilder() + .addTags("Signature") + .addTags("Trustee") + .setData(ByteString.copyFrom(b1)) + .build()) + .addSig(Signature.newBuilder() + .setType(SignatureType.DSA) + .setData(ByteString.copyFrom(b2)) + .setSignerId(ByteString.copyFrom(b3)) + .build()) + .addSig(Signature.newBuilder() + .setType(SignatureType.ECDSA) + .setData(ByteString.copyFrom(b3)) + .setSignerId(ByteString.copyFrom(b2)) + .build()) + .build(); + + response = webTarget.request(Constants.MEDIATYPE_PROTOBUF).post(Entity.entity(msg, Constants.MEDIATYPE_PROTOBUF)); + System.err.println(response); + bool = response.readEntity(BoolMsg.class); + assert bool.getValue(); + + msg = BulletinBoardMessage.newBuilder() + .setMsg(UnsignedBulletinBoardMessage.newBuilder() + .addTags("Vote") + .addTags("Trustee") + .setData(ByteString.copyFrom(b4)) + .build()) + .addSig(Signature.newBuilder() + .setType(SignatureType.ECDSA) + .setData(ByteString.copyFrom(b4)) + .setSignerId(ByteString.copyFrom(b2)) + .build()) + .build(); + + response = webTarget.request(Constants.MEDIATYPE_PROTOBUF).post(Entity.entity(msg, Constants.MEDIATYPE_PROTOBUF)); + System.err.println(response); + bool = response.readEntity(BoolMsg.class); + assert bool.getValue(); + + // Test reading mechanism + + System.err.println("******** Testing: " + SQL_SERVER_GET); + webTarget = client.target(BASE_URL).path(SQL_SERVER_GET); + + filterList = MessageFilterList.newBuilder() + .addFilter( + MessageFilter.newBuilder() + .setType(FilterType.TAG) + .setTag("Vote") + .build() + ) + .build(); + +// String sql = "SELECT MsgTable.EntryNum, MsgTable.Msg FROM MsgTable INNER JOIN SignatureTable ON SignatureTable.EntryNum = MsgTable.EntryNum WHERE SignatureTable.SignerId = ?"; +// PreparedStatement pstmt = connection.prepareStatement(sql); +// int i=1; +// for (MessageFilter filter : filterList.getFilterList()){ +// +// switch (filter.getType().getNumber()){ +// +// case FilterType.EXACT_ENTRY_VALUE: // Go through. +// case FilterType.MAX_ENTRY_VALUE: +// pstmt.setLong(i, filter.getEntry()); +// i++; +// break; +// +// case FilterType.MSG_ID_VALUE: // Go through. +// case FilterType.SIGNER_ID_VALUE: +// pstmt.setBytes(i, filter.getId().toByteArray()); +// i++; +// break; +// +// case FilterType.TAG_VALUE: +// pstmt.setString(i, filter.getTag()); +// break; +// +// // The max-messages condition is applied as a suffix. Therefore, it is treated differently. +// case FilterType.MAX_MESSAGES_VALUE: +// pstmt.setLong(filterList.getFilterList().size(), filter.getMaxMessages()); +// break; +// +// } +// } +// ResultSet rs = pstmt.executeQuery(); +// +// i = 0; +// while (rs.next()){ +// i++; +// assert rs.getBytes(2) +// } +// System.err.println("Local DB size = " + i); +// pstmt.close(); + + response = webTarget.request(Constants.MEDIATYPE_PROTOBUF).post(Entity.entity(filterList, Constants.MEDIATYPE_PROTOBUF)); + System.err.println(response); + msgList = response.readEntity(BulletinBoardMessageList.class); + System.err.println("List size: " + msgList.getMessageCount()); + System.err.println("This is the list:"); + System.err.println(TextFormat.printToString(msgList)); + assert msgList.getMessageCount() == 1; + } + +} diff --git a/meerkat-common/.gitignore b/meerkat-common/.gitignore new file mode 100644 index 0000000..ae3c172 --- /dev/null +++ b/meerkat-common/.gitignore @@ -0,0 +1 @@ +/bin/ diff --git a/meerkat-common/build.gradle b/meerkat-common/build.gradle index d445fff..eb2c6a2 100644 --- a/meerkat-common/build.gradle +++ b/meerkat-common/build.gradle @@ -59,6 +59,23 @@ dependencies { /*==== You probably don't have to edit below this line =======*/ +// Setup test configuration that can appear as a dependency in +// other subprojects +configurations { + testOutput.extendsFrom (testCompile) +} + +task testJar(type: Jar, dependsOn: testClasses) { + classifier = 'tests' + from sourceSets.test.output +} + +artifacts { + testOutput testJar +} + + + // The run task added by the application plugin // is also of type JavaExec. tasks.withType(JavaExec) { diff --git a/meerkat-common/src/main/java/Demo.java b/meerkat-common/src/main/java/Demo.java index 3b8e857..be79642 100644 --- a/meerkat-common/src/main/java/Demo.java +++ b/meerkat-common/src/main/java/Demo.java @@ -1,5 +1,5 @@ import com.google.protobuf.ByteString; -import static meerkat.protobuf.Voting.*; +import static meerkat.protobuf.BulletinBoardAPI.*; import java.io.IOException; /** diff --git a/meerkat-common/src/main/java/meerkat/bulletinboard/BulletinBoard.java b/meerkat-common/src/main/java/meerkat/bulletinboard/BulletinBoard.java index eb31c6d..0efd6a7 100644 --- a/meerkat-common/src/main/java/meerkat/bulletinboard/BulletinBoard.java +++ b/meerkat-common/src/main/java/meerkat/bulletinboard/BulletinBoard.java @@ -1,7 +1,7 @@ package meerkat.bulletinboard; import meerkat.comm.*; -import static meerkat.protobuf.Voting.*; +import static meerkat.protobuf.BulletinBoardAPI.*; import java.util.List; diff --git a/meerkat-common/src/main/java/meerkat/bulletinboard/BulletinBoardServer.java b/meerkat-common/src/main/java/meerkat/bulletinboard/BulletinBoardServer.java index fdd0b3c..fe19d6e 100644 --- a/meerkat-common/src/main/java/meerkat/bulletinboard/BulletinBoardServer.java +++ b/meerkat-common/src/main/java/meerkat/bulletinboard/BulletinBoardServer.java @@ -1,9 +1,7 @@ package meerkat.bulletinboard; -import java.util.List; - import meerkat.comm.CommunicationException; -import meerkat.protobuf.Voting.BulletinBoardMessage; +import meerkat.protobuf.BulletinBoardAPI.*; /** * Created by Arbel on 07/11/15. @@ -24,18 +22,17 @@ public interface BulletinBoardServer{ /** * Post a message to bulletin board. * @param msg is the actual (signed) message - * @return TRUE if the message has been authenticated and FALSE otherwise. + * @return TRUE if the message has been authenticated and FALSE otherwise (in ProtoBuf form). * @throws CommunicationException on DB connection error. */ - public boolean postMessage(BulletinBoardMessage msg) throws CommunicationException; + public BoolMsg postMessage(BulletinBoardMessage msg) throws CommunicationException; /** * Read all messages posted matching the given filter. - * @param filter return only messages that match the filter (null means no filtering). - * @param max maximum number of messages to return (0=no limit) + * @param filter return only messages that match the filter (empty list means no filtering). * @return */ - List readMessages(MessageFilter filter, int max); + BulletinBoardMessageList readMessages(MessageFilterList filterList) throws CommunicationException; /** * This method closes the connection to the DB. diff --git a/meerkat-common/src/main/java/meerkat/bulletinboard/MessageFilter.java b/meerkat-common/src/main/java/meerkat/bulletinboard/MessageFilter.java deleted file mode 100644 index 08dcb52..0000000 --- a/meerkat-common/src/main/java/meerkat/bulletinboard/MessageFilter.java +++ /dev/null @@ -1,27 +0,0 @@ -package meerkat.bulletinboard; - -/** - * Created by talm on 25/10/15. - * - * A filter for messages (run on the BB server side). - * - * TODO: define a limited filter language (e.g., by tag, by signer, by time, etc.) that can - * be efficiently run on the BB database. - * - */ -public abstract class MessageFilter { - public enum FilterType{ - ENTRY_NUM, - ID, - TAG, - SIGNER, - TIME - } - - FilterType filterType; - - public MessageFilter(FilterType filterType){ - - } - -} diff --git a/meerkat-common/src/main/java/meerkat/crypto/DigitalSignature.java b/meerkat-common/src/main/java/meerkat/crypto/DigitalSignature.java index 1abad8f..e0a9294 100644 --- a/meerkat-common/src/main/java/meerkat/crypto/DigitalSignature.java +++ b/meerkat-common/src/main/java/meerkat/crypto/DigitalSignature.java @@ -17,7 +17,7 @@ import static meerkat.protobuf.Crypto.*; /** * Created by talm on 25/10/15. * - * Sign and verifyarrays of messages + * Sign and verify arrays of messages */ public interface DigitalSignature { final public static String CERTIFICATE_ENCODING_X509 = "X.509"; diff --git a/meerkat-common/src/main/proto/meerkat/BulletinBoardAPI.proto b/meerkat-common/src/main/proto/meerkat/BulletinBoardAPI.proto new file mode 100644 index 0000000..986fcb8 --- /dev/null +++ b/meerkat-common/src/main/proto/meerkat/BulletinBoardAPI.proto @@ -0,0 +1,73 @@ +syntax = "proto3"; + +package meerkat; + +option java_package = "meerkat.protobuf"; + +import 'meerkat/crypto.proto'; + +message BoolMsg { + bool value = 1; +} + + +message MessageID { + // The ID of a message for unique retrieval. + // Note that it is assumed that this ID is a function of the message itself. + bytes ID = 1; +} + +message UnsignedBulletinBoardMessage { + // Optional tags describing message + repeated string tags = 1; + + // The actual content of the message + bytes data = 2; +} + +message BulletinBoardMessage { + + // Serial entry number of message in database + int64 entryNum = 1; + + // Unsigned raw data of message + UnsignedBulletinBoardMessage msg = 2; + + // Signature of message (and tags), excluding the entry number. + repeated meerkat.Signature sig = 3; +} + +message BulletinBoardMessageList { + + repeated BulletinBoardMessage message = 1; + +} + +enum FilterType { + MSG_ID = 0; // Match exact message ID + EXACT_ENTRY = 1; // Match exact entry number in database (chronological) + MAX_ENTRY = 2; // Find all entries in database up to specified entry number (chronological) + SIGNER_ID = 3; // Find all entries in database that correspond to specific signature (signer) + TAG = 4; // Find all entries in database that have a specific tag + MAX_MESSAGES = 5; // Return at most some specified number of messages +} + +message MessageFilter { + + FilterType type = 1; + + oneof filter{ + bytes id = 2; + int64 entry = 3; + string tag = 4; + int64 maxMessages = 5; + } +} + +message MessageFilterList { + + // Combination of filters. + // To be implemented using intersection ("AND") operations. + repeated MessageFilter filter = 1; + +} \ No newline at end of file diff --git a/meerkat-common/src/main/proto/meerkat/voting.proto b/meerkat-common/src/main/proto/meerkat/voting.proto index f7195e2..beb4e0c 100644 --- a/meerkat-common/src/main/proto/meerkat/voting.proto +++ b/meerkat-common/src/main/proto/meerkat/voting.proto @@ -6,28 +6,6 @@ import 'meerkat/crypto.proto'; option java_package = "meerkat.protobuf"; -message MessageID { - // The ID of a message for unique retrieval. - // Note that it is assumed that this ID is a function of the message itself. - bytes ID = 1; -} - -message UnsignedBulletinBoardMessage { - // Optional tags describing message - repeated string tags = 1; - - // The actual content of the message - bytes data = 2; -} - -message BulletinBoardMessage { - - UnsignedBulletinBoardMessage msg = 1; - - // Signature of message (and tags) - meerkat.Signature sig = 2; -} - // A ballot question. This is an opaque // data type that is parsed by the UI to display // the question. diff --git a/meerkat-common/src/test/java/meerkat/crypto/concrete/TestECDSASignature.java b/meerkat-common/src/test/java/meerkat/crypto/concrete/TestECDSASignature.java index 4fbb35c..8d9a880 100644 --- a/meerkat-common/src/test/java/meerkat/crypto/concrete/TestECDSASignature.java +++ b/meerkat-common/src/test/java/meerkat/crypto/concrete/TestECDSASignature.java @@ -2,7 +2,7 @@ package meerkat.crypto.concrete; import com.google.protobuf.ByteString; import meerkat.protobuf.Crypto; -import meerkat.protobuf.Voting; +import meerkat.protobuf.BulletinBoardAPI.*; import org.junit.Test; import java.io.ByteArrayInputStream; @@ -149,13 +149,13 @@ public class TestECDSASignature { signer.loadSigningCertificate(keyStore); - Voting.UnsignedBulletinBoardMessage.Builder unsignedMsgBuilder = Voting.UnsignedBulletinBoardMessage.newBuilder(); + UnsignedBulletinBoardMessage.Builder unsignedMsgBuilder = UnsignedBulletinBoardMessage.newBuilder(); unsignedMsgBuilder.setData(ByteString.copyFromUtf8(HELLO_WORLD)); unsignedMsgBuilder.addTags("Tag1"); unsignedMsgBuilder.addTags("Tag2"); unsignedMsgBuilder.addTags("Tag3"); - Voting.UnsignedBulletinBoardMessage usMsg = unsignedMsgBuilder.build(); + UnsignedBulletinBoardMessage usMsg = unsignedMsgBuilder.build(); signer.updateContent(usMsg); Crypto.Signature sig = signer.sign(); diff --git a/meerkat-common/src/test/resources/certs/signed-messages/random1.bin b/meerkat-common/src/test/resources/certs/signed-messages/random1.bin new file mode 100644 index 0000000..e4e56df Binary files /dev/null and b/meerkat-common/src/test/resources/certs/signed-messages/random1.bin differ diff --git a/meerkat-common/src/test/resources/certs/signed-messages/random1.bin.user1.sha256sig b/meerkat-common/src/test/resources/certs/signed-messages/random1.bin.user1.sha256sig new file mode 100644 index 0000000..33ba6a8 Binary files /dev/null and b/meerkat-common/src/test/resources/certs/signed-messages/random1.bin.user1.sha256sig differ diff --git a/meerkat-common/src/test/resources/certs/signed-messages/random1.bin.user2.sha256sig b/meerkat-common/src/test/resources/certs/signed-messages/random1.bin.user2.sha256sig new file mode 100644 index 0000000..ca8ebf7 Binary files /dev/null and b/meerkat-common/src/test/resources/certs/signed-messages/random1.bin.user2.sha256sig differ diff --git a/meerkat-common/src/test/resources/certs/signed-messages/random2.bin b/meerkat-common/src/test/resources/certs/signed-messages/random2.bin new file mode 100644 index 0000000..91aae82 Binary files /dev/null and b/meerkat-common/src/test/resources/certs/signed-messages/random2.bin differ diff --git a/meerkat-common/src/test/resources/certs/signed-messages/random2.bin.user1.sha256sig b/meerkat-common/src/test/resources/certs/signed-messages/random2.bin.user1.sha256sig new file mode 100644 index 0000000..e1eac6e Binary files /dev/null and b/meerkat-common/src/test/resources/certs/signed-messages/random2.bin.user1.sha256sig differ diff --git a/meerkat-common/src/test/resources/certs/signed-messages/random2.bin.user2.sha256sig b/meerkat-common/src/test/resources/certs/signed-messages/random2.bin.user2.sha256sig new file mode 100644 index 0000000..973b3b0 Binary files /dev/null and b/meerkat-common/src/test/resources/certs/signed-messages/random2.bin.user2.sha256sig differ diff --git a/meerkat-common/src/test/resources/certs/signed-messages/random3.bin b/meerkat-common/src/test/resources/certs/signed-messages/random3.bin new file mode 100644 index 0000000..a0afb95 Binary files /dev/null and b/meerkat-common/src/test/resources/certs/signed-messages/random3.bin differ diff --git a/meerkat-common/src/test/resources/certs/signed-messages/random3.bin.user1.sha256sig b/meerkat-common/src/test/resources/certs/signed-messages/random3.bin.user1.sha256sig new file mode 100644 index 0000000..7c87d33 Binary files /dev/null and b/meerkat-common/src/test/resources/certs/signed-messages/random3.bin.user1.sha256sig differ diff --git a/meerkat-common/src/test/resources/certs/signed-messages/random3.bin.user2.sha256sig b/meerkat-common/src/test/resources/certs/signed-messages/random3.bin.user2.sha256sig new file mode 100644 index 0000000..d6d3656 --- /dev/null +++ b/meerkat-common/src/test/resources/certs/signed-messages/random3.bin.user2.sha256sig @@ -0,0 +1 @@ +0D r=¥|n“Ò2ɪ‰!S»®[gCŸ$ä°Ž/ Ê”(Âò½ ^esüHLŸ½o,oV®”§ce²p0(èXÆ]&@ \ No newline at end of file diff --git a/restful-api-common/.gitignore b/restful-api-common/.gitignore new file mode 100644 index 0000000..ae3c172 --- /dev/null +++ b/restful-api-common/.gitignore @@ -0,0 +1 @@ +/bin/