mirror of
https://github.com/servalproject/serval-dna.git
synced 2025-02-20 17:33:08 +00:00
Add Keyring Java API (incomplete) with tests
keyringListIdentities() keyringSetDidName()
This commit is contained in:
parent
0e783c6b73
commit
7635e6b71b
@ -25,6 +25,8 @@ import org.servalproject.servaldna.meshms.MeshMSConversationList;
|
||||
import org.servalproject.servaldna.meshms.MeshMSException;
|
||||
import org.servalproject.servaldna.meshms.MeshMSMessageList;
|
||||
|
||||
import java.lang.Iterable;
|
||||
import java.util.Vector;
|
||||
import java.io.InputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.UnsupportedEncodingException;
|
||||
@ -37,6 +39,9 @@ import org.servalproject.servaldna.BundleId;
|
||||
import org.servalproject.servaldna.BundleSecret;
|
||||
import org.servalproject.servaldna.ServalDCommand;
|
||||
import org.servalproject.servaldna.ServalDInterfaceException;
|
||||
import org.servalproject.servaldna.keyring.KeyringCommon;
|
||||
import org.servalproject.servaldna.keyring.KeyringIdentity;
|
||||
import org.servalproject.servaldna.keyring.KeyringIdentityList;
|
||||
import org.servalproject.servaldna.rhizome.RhizomeCommon;
|
||||
import org.servalproject.servaldna.rhizome.RhizomeIncompleteManifest;
|
||||
import org.servalproject.servaldna.rhizome.RhizomeBundleList;
|
||||
@ -74,6 +79,18 @@ public class ServalDClient implements ServalDHttpConnectionFactory
|
||||
this.restfulPassword = restfulPassword;
|
||||
}
|
||||
|
||||
public KeyringIdentityList keyringListIdentities(String pin) throws ServalDInterfaceException, IOException
|
||||
{
|
||||
KeyringIdentityList list = new KeyringIdentityList(this);
|
||||
list.connect(pin);
|
||||
return list;
|
||||
}
|
||||
|
||||
public KeyringIdentity keyringSetDidName(SubscriberId sid, String did, String name, String pin) throws ServalDInterfaceException, IOException
|
||||
{
|
||||
return KeyringCommon.setDidName(this, sid, did, name, pin);
|
||||
}
|
||||
|
||||
public RhizomeBundleList rhizomeListBundles() throws ServalDInterfaceException, IOException
|
||||
{
|
||||
RhizomeBundleList list = new RhizomeBundleList(this);
|
||||
@ -171,7 +188,20 @@ public class ServalDClient implements ServalDHttpConnectionFactory
|
||||
// interface ServalDHttpConnectionFactory
|
||||
public HttpURLConnection newServalDHttpConnection(String path) throws ServalDInterfaceException, IOException
|
||||
{
|
||||
URL url = new URL("http", "localhost", httpPort, path);
|
||||
return newServalDHttpConnection(path, new Vector<QueryParam>());
|
||||
}
|
||||
|
||||
// interface ServalDHttpConnectionFactory
|
||||
public HttpURLConnection newServalDHttpConnection(String path, Iterable<QueryParam> query_params) throws ServalDInterfaceException, IOException
|
||||
{
|
||||
StringBuilder str = new StringBuilder();
|
||||
char sep = '?';
|
||||
for (QueryParam param : query_params) {
|
||||
str.append(sep);
|
||||
param.uri_encode(str);
|
||||
sep = '&';
|
||||
}
|
||||
URL url = new URL("http://localhost:" + httpPort + path + str.toString());
|
||||
URLConnection uconn = url.openConnection();
|
||||
HttpURLConnection conn;
|
||||
try {
|
||||
|
@ -20,11 +20,49 @@
|
||||
|
||||
package org.servalproject.servaldna;
|
||||
|
||||
import java.lang.Iterable;
|
||||
import java.lang.StringBuilder;
|
||||
import java.io.IOException;
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.net.HttpURLConnection;
|
||||
|
||||
public interface ServalDHttpConnectionFactory {
|
||||
|
||||
public static class QueryParam
|
||||
{
|
||||
public final String key;
|
||||
public final String value;
|
||||
public QueryParam(String key, String value) {
|
||||
this.key = key;
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
public void uri_encode(StringBuilder str) throws UnsupportedEncodingException {
|
||||
uri_encode_string(str, this.key);
|
||||
if (this.value != null) {
|
||||
str.append('=');
|
||||
uri_encode_string(str, this.value);
|
||||
}
|
||||
}
|
||||
|
||||
static private void uri_encode_string(StringBuilder str, String text) throws UnsupportedEncodingException {
|
||||
for (byte b : text.getBytes("UTF-8")) {
|
||||
if ( (b >= '0' && b <= '9')
|
||||
|| (b >= 'A' && b <= 'Z')
|
||||
|| (b >= 'a' && b <= 'z')
|
||||
|| b == '_' || b == '.' || b == '-' || b == '~') {
|
||||
str.appendCodePoint(b);
|
||||
} else {
|
||||
str.append('%');
|
||||
str.append(Character.forDigit((b >> 4) % 16, 16));
|
||||
str.append(Character.forDigit(b % 16, 16));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public HttpURLConnection newServalDHttpConnection(String path) throws ServalDInterfaceException, IOException;
|
||||
|
||||
public HttpURLConnection newServalDHttpConnection(String path, Iterable<QueryParam> query_params) throws ServalDInterfaceException, IOException;
|
||||
|
||||
}
|
||||
|
231
java/org/servalproject/servaldna/keyring/KeyringCommon.java
Normal file
231
java/org/servalproject/servaldna/keyring/KeyringCommon.java
Normal file
@ -0,0 +1,231 @@
|
||||
/**
|
||||
* Copyright (C) 2015 Serval Project Inc.
|
||||
*
|
||||
* This file is part of Serval Software (http://www.servalproject.org)
|
||||
*
|
||||
* Serval Software is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This source code is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this source code; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
package org.servalproject.servaldna.keyring;
|
||||
|
||||
import java.lang.StringBuilder;
|
||||
import java.lang.reflect.Constructor;
|
||||
import java.lang.reflect.Method;
|
||||
import java.lang.reflect.Modifier;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.util.Map;
|
||||
import java.util.List;
|
||||
import java.util.Vector;
|
||||
import java.io.IOException;
|
||||
import java.io.PrintStream;
|
||||
import java.io.InputStream;
|
||||
import java.io.InputStreamReader;
|
||||
import java.io.OutputStream;
|
||||
import java.net.URL;
|
||||
import java.net.HttpURLConnection;
|
||||
import org.servalproject.json.JSONTokeniser;
|
||||
import org.servalproject.json.JSONInputException;
|
||||
import org.servalproject.servaldna.SubscriberId;
|
||||
import org.servalproject.servaldna.ServalDHttpConnectionFactory;
|
||||
import org.servalproject.servaldna.ServalDInterfaceException;
|
||||
import org.servalproject.servaldna.ServalDFailureException;
|
||||
import org.servalproject.servaldna.ServalDNotImplementedException;
|
||||
|
||||
public class KeyringCommon
|
||||
{
|
||||
|
||||
public static class Status {
|
||||
InputStream input_stream;
|
||||
JSONTokeniser json;
|
||||
public int http_status_code;
|
||||
public String http_status_message;
|
||||
public KeyringIdentity identity;
|
||||
}
|
||||
|
||||
private static void dumpStatus(Status status, PrintStream out)
|
||||
{
|
||||
out.println("input_stream=" + status.input_stream);
|
||||
out.println("http_status_code=" + status.http_status_code);
|
||||
out.println("http_status_message=" + status.http_status_message);
|
||||
if (status.identity == null) {
|
||||
out.println("identity=null");
|
||||
} else {
|
||||
out.println("identity.sid=" + status.identity.sid);
|
||||
out.println("identity.did=" + status.identity.did);
|
||||
out.println("identity.name=" + status.identity.name);
|
||||
}
|
||||
}
|
||||
|
||||
protected static Status receiveResponse(HttpURLConnection conn, int expected_response_code) throws IOException, ServalDInterfaceException
|
||||
{
|
||||
int[] expected_response_codes = { expected_response_code };
|
||||
return receiveResponse(conn, expected_response_codes);
|
||||
}
|
||||
|
||||
protected static Status receiveResponse(HttpURLConnection conn, int[] expected_response_codes) throws IOException, ServalDInterfaceException
|
||||
{
|
||||
Status status = new Status();
|
||||
status.http_status_code = conn.getResponseCode();
|
||||
status.http_status_message = conn.getResponseMessage();
|
||||
for (int code: expected_response_codes) {
|
||||
if (status.http_status_code == code) {
|
||||
status.input_stream = conn.getInputStream();
|
||||
return status;
|
||||
}
|
||||
}
|
||||
if (!conn.getContentType().equals("application/json"))
|
||||
throw new ServalDInterfaceException("unexpected HTTP Content-Type: " + conn.getContentType());
|
||||
if (status.http_status_code >= 300) {
|
||||
status.json = new JSONTokeniser(new InputStreamReader(conn.getErrorStream(), "UTF-8"));
|
||||
decodeRestfulStatus(status);
|
||||
}
|
||||
if (status.http_status_code == HttpURLConnection.HTTP_FORBIDDEN)
|
||||
return status;
|
||||
if (status.http_status_code == HttpURLConnection.HTTP_NOT_IMPLEMENTED)
|
||||
throw new ServalDNotImplementedException(status.http_status_message);
|
||||
throw new ServalDInterfaceException("unexpected HTTP response: " + status.http_status_code + " " + status.http_status_message);
|
||||
}
|
||||
|
||||
protected static ServalDInterfaceException unexpectedResponse(HttpURLConnection conn, Status status)
|
||||
{
|
||||
return new ServalDInterfaceException(
|
||||
"unexpected Keyring failure, " + quoteString(status.http_status_message)
|
||||
+ " from " + conn.getURL()
|
||||
);
|
||||
}
|
||||
|
||||
protected static Status receiveRestfulResponse(HttpURLConnection conn, int expected_response_code) throws IOException, ServalDInterfaceException
|
||||
{
|
||||
int[] expected_response_codes = { expected_response_code };
|
||||
return receiveRestfulResponse(conn, expected_response_codes);
|
||||
}
|
||||
|
||||
protected static Status receiveRestfulResponse(HttpURLConnection conn, int[] expected_response_codes) throws IOException, ServalDInterfaceException
|
||||
{
|
||||
Status status = receiveResponse(conn, expected_response_codes);
|
||||
if (!conn.getContentType().equals("application/json"))
|
||||
throw new ServalDInterfaceException("unexpected HTTP Content-Type: " + conn.getContentType());
|
||||
status.json = new JSONTokeniser(new InputStreamReader(status.input_stream, "UTF-8"));
|
||||
return status;
|
||||
}
|
||||
|
||||
protected static void decodeRestfulStatus(Status status) throws IOException, ServalDInterfaceException
|
||||
{
|
||||
JSONTokeniser json = status.json;
|
||||
try {
|
||||
json.consume(JSONTokeniser.Token.START_OBJECT);
|
||||
json.consume("http_status_code");
|
||||
json.consume(JSONTokeniser.Token.COLON);
|
||||
int hs = json.consume(Integer.class);
|
||||
json.consume(JSONTokeniser.Token.COMMA);
|
||||
if (status.http_status_code == 0)
|
||||
status.http_status_code = json.consume(Integer.class);
|
||||
else if (hs != status.http_status_code)
|
||||
throw new ServalDInterfaceException("JSON/header conflict"
|
||||
+ ", http_status_code=" + hs
|
||||
+ " but HTTP response code is " + status.http_status_code);
|
||||
json.consume("http_status_message");
|
||||
json.consume(JSONTokeniser.Token.COLON);
|
||||
status.http_status_message = json.consume(String.class);
|
||||
Object tok = json.nextToken();
|
||||
if (tok == JSONTokeniser.Token.COMMA) {
|
||||
json.consume("identity");
|
||||
json.consume(JSONTokeniser.Token.COLON);
|
||||
json.consume(JSONTokeniser.Token.START_OBJECT);
|
||||
json.consume("sid");
|
||||
json.consume(JSONTokeniser.Token.COLON);
|
||||
String sid_hex = json.consume(String.class);
|
||||
SubscriberId sid = new SubscriberId(sid_hex);
|
||||
String did = null;
|
||||
String name = null;
|
||||
tok = json.nextToken();
|
||||
if (tok == JSONTokeniser.Token.COMMA) {
|
||||
json.consume("did");
|
||||
json.consume(JSONTokeniser.Token.COLON);
|
||||
did = json.consume(String.class);
|
||||
tok = json.nextToken();
|
||||
}
|
||||
if (tok == JSONTokeniser.Token.COMMA) {
|
||||
json.consume("name");
|
||||
json.consume(JSONTokeniser.Token.COLON);
|
||||
name = json.consume(String.class);
|
||||
tok = json.nextToken();
|
||||
}
|
||||
json.match(tok, JSONTokeniser.Token.END_OBJECT);
|
||||
tok = json.nextToken();
|
||||
status.identity = new KeyringIdentity(0, sid, did, name);
|
||||
}
|
||||
json.match(tok, JSONTokeniser.Token.END_OBJECT);
|
||||
json.consume(JSONTokeniser.Token.EOF);
|
||||
}
|
||||
catch (SubscriberId.InvalidHexException e) {
|
||||
throw new ServalDInterfaceException("malformed JSON status response", e);
|
||||
}
|
||||
catch (JSONInputException e) {
|
||||
throw new ServalDInterfaceException("malformed JSON status response", e);
|
||||
}
|
||||
}
|
||||
|
||||
private static void dumpHeaders(HttpURLConnection conn, PrintStream out)
|
||||
{
|
||||
for (Map.Entry<String,List<String>> e: conn.getHeaderFields().entrySet())
|
||||
for (String v: e.getValue())
|
||||
out.println("received header " + e.getKey() + ": " + v);
|
||||
}
|
||||
|
||||
private static String quoteString(String unquoted)
|
||||
{
|
||||
if (unquoted == null)
|
||||
return "null";
|
||||
StringBuilder b = new StringBuilder(unquoted.length() + 2);
|
||||
b.append('"');
|
||||
for (int i = 0; i < unquoted.length(); ++i) {
|
||||
char c = unquoted.charAt(i);
|
||||
if (c == '"' || c == '\\')
|
||||
b.append('\\');
|
||||
b.append(c);
|
||||
}
|
||||
b.append('"');
|
||||
return b.toString();
|
||||
}
|
||||
|
||||
public static KeyringIdentity setDidName(ServalDHttpConnectionFactory connector, SubscriberId sid, String did, String name, String pin)
|
||||
throws IOException, ServalDInterfaceException
|
||||
{
|
||||
Vector<ServalDHttpConnectionFactory.QueryParam> query_params = new Vector<ServalDHttpConnectionFactory.QueryParam>();
|
||||
if (did != null)
|
||||
query_params.add(new ServalDHttpConnectionFactory.QueryParam("did", did));
|
||||
if (name != null)
|
||||
query_params.add(new ServalDHttpConnectionFactory.QueryParam("name", name));
|
||||
if (pin != null)
|
||||
query_params.add(new ServalDHttpConnectionFactory.QueryParam("pin", pin));
|
||||
HttpURLConnection conn = connector.newServalDHttpConnection("/restful/keyring/" + sid.toHex() + "/set", query_params);
|
||||
conn.connect();
|
||||
Status status = receiveRestfulResponse(conn, HttpURLConnection.HTTP_OK);
|
||||
try {
|
||||
decodeRestfulStatus(status);
|
||||
dumpStatus(status, System.err);
|
||||
if (status.identity == null)
|
||||
throw new ServalDInterfaceException("invalid JSON response; missing identity");
|
||||
|
||||
return status.identity;
|
||||
}
|
||||
finally {
|
||||
if (status.input_stream != null)
|
||||
status.input_stream.close();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,43 @@
|
||||
/**
|
||||
* Copyright (C) 2015 Serval Project Inc.
|
||||
*
|
||||
* This file is part of Serval Software (http://www.servalproject.org)
|
||||
*
|
||||
* Serval Software is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This source code is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this source code; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
package org.servalproject.servaldna.keyring;
|
||||
|
||||
import org.servalproject.servaldna.SubscriberId;
|
||||
|
||||
public class KeyringIdentity {
|
||||
|
||||
public final int rowNumber;
|
||||
public final SubscriberId sid;
|
||||
public final String did;
|
||||
public final String name;
|
||||
|
||||
protected KeyringIdentity(int rowNumber,
|
||||
SubscriberId sid,
|
||||
String did,
|
||||
String name)
|
||||
{
|
||||
this.rowNumber = rowNumber;
|
||||
this.sid = sid;
|
||||
this.did = did;
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,118 @@
|
||||
/**
|
||||
* Copyright (C) 2015 Serval Project Inc.
|
||||
*
|
||||
* This file is part of Serval Software (http://www.servalproject.org)
|
||||
*
|
||||
* Serval Software is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This source code is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this source code; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
package org.servalproject.servaldna.keyring;
|
||||
|
||||
import org.servalproject.json.JSONInputException;
|
||||
import org.servalproject.json.JSONTableScanner;
|
||||
import org.servalproject.json.JSONTokeniser;
|
||||
import org.servalproject.servaldna.ServalDHttpConnectionFactory;
|
||||
import org.servalproject.servaldna.ServalDInterfaceException;
|
||||
import org.servalproject.servaldna.SubscriberId;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.HttpURLConnection;
|
||||
import java.util.Vector;
|
||||
import java.util.Map;
|
||||
|
||||
public class KeyringIdentityList {
|
||||
|
||||
private ServalDHttpConnectionFactory httpConnector;
|
||||
private HttpURLConnection httpConnection;
|
||||
private JSONTokeniser json;
|
||||
private JSONTableScanner table;
|
||||
int rowCount;
|
||||
|
||||
public KeyringIdentityList(ServalDHttpConnectionFactory connector)
|
||||
{
|
||||
this.httpConnector = connector;
|
||||
this.table = new JSONTableScanner()
|
||||
.addColumn("sid", SubscriberId.class)
|
||||
.addColumn("did", String.class, JSONTokeniser.Narrow.ALLOW_NULL)
|
||||
.addColumn("name", String.class, JSONTokeniser.Narrow.ALLOW_NULL);
|
||||
}
|
||||
|
||||
public boolean isConnected()
|
||||
{
|
||||
return this.json != null;
|
||||
}
|
||||
|
||||
public void connect(String pin) throws IOException, ServalDInterfaceException
|
||||
{
|
||||
try {
|
||||
rowCount = 0;
|
||||
Vector<ServalDHttpConnectionFactory.QueryParam> query_params = new Vector<ServalDHttpConnectionFactory.QueryParam>();
|
||||
if (pin != null) {
|
||||
query_params.add(new ServalDHttpConnectionFactory.QueryParam("pin", pin));
|
||||
}
|
||||
httpConnection = httpConnector.newServalDHttpConnection("/restful/keyring/identities.json", query_params);
|
||||
httpConnection.connect();
|
||||
KeyringCommon.Status status = KeyringCommon.receiveRestfulResponse(httpConnection, HttpURLConnection.HTTP_OK);
|
||||
json = status.json;
|
||||
json.consume(JSONTokeniser.Token.START_OBJECT);
|
||||
json.consume("header");
|
||||
json.consume(JSONTokeniser.Token.COLON);
|
||||
table.consumeHeaderArray(json);
|
||||
json.consume(JSONTokeniser.Token.COMMA);
|
||||
json.consume("rows");
|
||||
json.consume(JSONTokeniser.Token.COLON);
|
||||
json.consume(JSONTokeniser.Token.START_ARRAY);
|
||||
}
|
||||
catch (JSONInputException e) {
|
||||
throw new ServalDInterfaceException(e);
|
||||
}
|
||||
}
|
||||
|
||||
public KeyringIdentity nextIdentity() throws ServalDInterfaceException, IOException
|
||||
{
|
||||
try {
|
||||
Object tok = json.nextToken();
|
||||
if (tok == JSONTokeniser.Token.END_ARRAY) {
|
||||
json.consume(JSONTokeniser.Token.END_OBJECT);
|
||||
json.consume(JSONTokeniser.Token.EOF);
|
||||
return null;
|
||||
}
|
||||
if (rowCount != 0)
|
||||
JSONTokeniser.match(tok, JSONTokeniser.Token.COMMA);
|
||||
else
|
||||
json.pushToken(tok);
|
||||
Map<String,Object> row = table.consumeRowArray(json);
|
||||
return new KeyringIdentity(
|
||||
rowCount++,
|
||||
(SubscriberId)row.get("sid"),
|
||||
(String)row.get("did"),
|
||||
(String)row.get("name")
|
||||
);
|
||||
}
|
||||
catch (JSONInputException e) {
|
||||
throw new ServalDInterfaceException(e);
|
||||
}
|
||||
}
|
||||
|
||||
public void close() throws IOException
|
||||
{
|
||||
httpConnection = null;
|
||||
if (json != null) {
|
||||
json.close();
|
||||
json = null;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
90
java/org/servalproject/test/Keyring.java
Normal file
90
java/org/servalproject/test/Keyring.java
Normal file
@ -0,0 +1,90 @@
|
||||
/**
|
||||
* Copyright (C) 2015 Serval Project Inc.
|
||||
*
|
||||
* This file is part of Serval Software (http://www.servalproject.org)
|
||||
*
|
||||
* Serval Software is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This source code is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this source code; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
package org.servalproject.test;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import org.servalproject.servaldna.ServalDClient;
|
||||
import org.servalproject.servaldna.ServalDInterfaceException;
|
||||
import org.servalproject.servaldna.ServalDNotImplementedException;
|
||||
import org.servalproject.servaldna.ServerControl;
|
||||
import org.servalproject.servaldna.BundleId;
|
||||
import org.servalproject.servaldna.BundleSecret;
|
||||
import org.servalproject.servaldna.SubscriberId;
|
||||
import org.servalproject.servaldna.keyring.KeyringIdentityList;
|
||||
import org.servalproject.servaldna.keyring.KeyringIdentity;
|
||||
|
||||
public class Keyring {
|
||||
|
||||
static void keyring_list(String pin) throws ServalDInterfaceException, IOException, InterruptedException
|
||||
{
|
||||
ServalDClient client = new ServerControl().getRestfulClient();
|
||||
KeyringIdentityList list = null;
|
||||
try {
|
||||
list = client.keyringListIdentities(pin);
|
||||
KeyringIdentity id;
|
||||
while ((id = list.nextIdentity()) != null) {
|
||||
System.out.println("sid=" + id.sid +
|
||||
", did=" + id.did +
|
||||
", name=" + id.name
|
||||
);
|
||||
}
|
||||
}
|
||||
finally {
|
||||
if (list != null)
|
||||
list.close();
|
||||
}
|
||||
System.exit(0);
|
||||
}
|
||||
|
||||
static void set(SubscriberId sid, String did, String name, String pin) throws ServalDInterfaceException, IOException, InterruptedException
|
||||
{
|
||||
ServalDClient client = new ServerControl().getRestfulClient();
|
||||
KeyringIdentity id = client.keyringSetDidName(sid, did, name, pin);
|
||||
System.out.println("sid=" + id.sid +
|
||||
", did=" + id.did +
|
||||
", name=" + id.name
|
||||
);
|
||||
System.exit(0);
|
||||
}
|
||||
|
||||
public static void main(String... args)
|
||||
{
|
||||
if (args.length < 1)
|
||||
return;
|
||||
String methodName = args[0];
|
||||
try {
|
||||
if (methodName.equals("list-identities"))
|
||||
keyring_list(args.length >= 2 ? args[1] : null);
|
||||
else if (methodName.equals("set"))
|
||||
set(new SubscriberId(args[1]), args[2], args[3], args.length >= 5 ? args[4] : null);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
System.exit(1);
|
||||
}
|
||||
System.err.println("No such command: " + methodName);
|
||||
System.exit(1);
|
||||
}
|
||||
}
|
@ -35,11 +35,12 @@ includeTests rhizomeprotocol
|
||||
includeTests meshms
|
||||
includeTests directory_service
|
||||
includeTests vomp
|
||||
includeTests rhizomerestful
|
||||
includeTests keyringrestful
|
||||
includeTests rhizomerestful
|
||||
includeTests meshmsrestful
|
||||
if type -p "$JAVAC" >/dev/null; then
|
||||
includeTests jni
|
||||
includeTests keyringjava
|
||||
includeTests rhizomejava
|
||||
includeTests meshmsjava
|
||||
fi
|
||||
|
128
tests/keyringjava
Executable file
128
tests/keyringjava
Executable file
@ -0,0 +1,128 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Tests for Keyring Java API.
|
||||
#
|
||||
# Copyright 2015 Serval Project Inc.
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU General Public License
|
||||
# as published by the Free Software Foundation; either version 2
|
||||
# of the License, or (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
|
||||
source "${0%/*}/../testframework.sh"
|
||||
source "${0%/*}/../testdefs.sh"
|
||||
source "${0%/*}/../testdefs_java.sh"
|
||||
|
||||
setup() {
|
||||
setup_servald
|
||||
setup_servald_so
|
||||
compile_java_classes
|
||||
set_instance +A
|
||||
set_keyring_config
|
||||
set_extra_config
|
||||
if [ -z "$IDENTITY_COUNT" ]; then
|
||||
create_single_identity
|
||||
else
|
||||
create_identities $IDENTITY_COUNT
|
||||
fi
|
||||
export SERVALD_RHIZOME_DB_RETRY_LIMIT_MS=60000
|
||||
start_servald_server
|
||||
wait_until servald_restful_http_server_started +A
|
||||
get_servald_restful_http_server_port PORTA +A
|
||||
}
|
||||
|
||||
teardown() {
|
||||
stop_all_servald_servers
|
||||
kill_all_servald_processes
|
||||
assert_no_servald_processes
|
||||
report_all_servald_servers
|
||||
}
|
||||
|
||||
set_keyring_config() {
|
||||
executeOk_servald config \
|
||||
set log.console.level debug \
|
||||
set debug.httpd on \
|
||||
set debug.keyring on \
|
||||
set debug.verbose on
|
||||
}
|
||||
|
||||
set_extra_config() {
|
||||
:
|
||||
}
|
||||
|
||||
doc_keyringList="Java API list keyring identities"
|
||||
setup_keyringList() {
|
||||
IDENTITY_COUNT=10
|
||||
DIDA1=123123123
|
||||
NAMEA1='Joe Bloggs'
|
||||
DIDA5=567567567
|
||||
setup
|
||||
}
|
||||
test_keyringList() {
|
||||
executeJavaOk org.servalproject.test.Keyring list-identities
|
||||
tfw_cat --stdout --stderr
|
||||
assertStdoutLineCount == $IDENTITY_COUNT
|
||||
# TODO: these tests only work because the listed order of identities is the
|
||||
# order of creation, which makes locked identities easy to attack. When the
|
||||
# random search TODO in keyring.c:find_free_slot() is done, then these tests
|
||||
# should fail.
|
||||
for ((n = 1; n != IDENTITY_COUNT + 1; ++n)); do
|
||||
line="$(sed -n -e ${n}p "$TFWSTDOUT")"
|
||||
unset_vars_with_prefix XX_
|
||||
unpack_vars XX_ "$line"
|
||||
local sidvar=SIDA$n
|
||||
local didvar=DIDA$n
|
||||
local namevar=NAMEA$n
|
||||
assert [ "$XX_sid" = "${!sidvar}" ]
|
||||
assert [ "$XX_did" = "${!didvar-null}" ]
|
||||
assert [ "$XX_name" = "${!namevar-null}" ]
|
||||
done
|
||||
}
|
||||
|
||||
doc_keyringListPin="Java API list keyring identities, with PIN"
|
||||
setup_keyringListPin() {
|
||||
IDENTITY_COUNT=3
|
||||
PINA1='wif waf'
|
||||
setup
|
||||
}
|
||||
test_keyringListPin() {
|
||||
# First, list without supplying the PIN
|
||||
executeJavaOk org.servalproject.test.Keyring list-identities
|
||||
tfw_cat --stdout --stderr
|
||||
assertStdoutLineCount == $((IDENTITY_COUNT - 1))
|
||||
assertStdoutGrep --matches=0 "sid=$SIDA1"
|
||||
assertStdoutGrep --matches=1 "sid=$SIDA2"
|
||||
assertStdoutGrep --matches=1 "sid=$SIDA3"
|
||||
# Then, list supplying the PIN
|
||||
executeJavaOk org.servalproject.test.Keyring list-identities "$PINA1"
|
||||
tfw_cat --stdout --stderr
|
||||
assertStdoutLineCount == $IDENTITY_COUNT
|
||||
assertStdoutGrep --matches=1 "sid=$SIDA1"
|
||||
assertStdoutGrep --matches=1 "sid=$SIDA2"
|
||||
assertStdoutGrep --matches=1 "sid=$SIDA3"
|
||||
}
|
||||
|
||||
doc_keyringSetDidName="Java API set DID and name"
|
||||
setup_keyringSetDidName() {
|
||||
IDENTITY_COUNT=2
|
||||
setup
|
||||
}
|
||||
test_keyringSetDidName() {
|
||||
executeJavaOk org.servalproject.test.Keyring set "$SIDA1" 987654321 'Joe Bloggs'
|
||||
tfw_cat --stdout --stderr
|
||||
assertStdoutGrep --matches=1 "sid=$SIDA1, did=987654321, name=Joe Bloggs$"
|
||||
executeOk_servald keyring list
|
||||
assert_keyring_list 2
|
||||
assertStdoutGrep --stderr --matches=1 "^$SIDA1:987654321:Joe Bloggs\$"
|
||||
}
|
||||
|
||||
runTests "$@"
|
Loading…
x
Reference in New Issue
Block a user