diff --git a/build.xml b/build.xml
index 4f9735d47..d7f85278c 100644
--- a/build.xml
+++ b/build.xml
@@ -5,7 +5,7 @@
-
+
diff --git a/src/main/java/i5/las2peer/persistency/Envelope.java b/src/main/java/i5/las2peer/persistency/Envelope.java
index beeb55e1b..e687c0705 100644
--- a/src/main/java/i5/las2peer/persistency/Envelope.java
+++ b/src/main/java/i5/las2peer/persistency/Envelope.java
@@ -1,20 +1,5 @@
package i5.las2peer.persistency;
-import java.io.ByteArrayInputStream;
-import java.io.IOException;
-import java.io.ObjectInputStream;
-import java.io.ObjectStreamClass;
-import java.io.Serializable;
-import java.io.UnsupportedEncodingException;
-import java.util.Date;
-import java.util.Enumeration;
-import java.util.Hashtable;
-import java.util.Random;
-
-import javax.crypto.SecretKey;
-
-import org.apache.commons.codec.binary.Base64;
-
import i5.las2peer.execution.L2pThread;
import i5.las2peer.p2p.ArtifactNotFoundException;
import i5.las2peer.p2p.StorageException;
@@ -32,6 +17,21 @@
import i5.simpleXML.Parser;
import i5.simpleXML.XMLSyntaxException;
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.io.ObjectInputStream;
+import java.io.ObjectStreamClass;
+import java.io.Serializable;
+import java.nio.charset.StandardCharsets;
+import java.util.Date;
+import java.util.Enumeration;
+import java.util.Hashtable;
+import java.util.Random;
+
+import javax.crypto.SecretKey;
+
+import org.apache.commons.codec.binary.Base64;
+
/**
* An envelope provides a secure storage for any {@link Serializable} content within the LAS2peer network.
*
@@ -211,12 +211,10 @@ private void initReaders(Agent[] readers) throws EncodingFailedException {
* @param content
* @param reader
*
- * @throws UnsupportedEncodingException
* @throws EncodingFailedException
* @throws DecodingFailedException
*/
- public Envelope(String content, Agent reader)
- throws UnsupportedEncodingException, EncodingFailedException, DecodingFailedException {
+ public Envelope(String content, Agent reader) throws EncodingFailedException, DecodingFailedException {
this(content, new Agent[] { reader });
}
@@ -228,10 +226,9 @@ public Envelope(String content, Agent reader)
* @param content
* @param readers
*
- * @throws UnsupportedEncodingException
* @throws EncodingFailedException
*/
- public Envelope(String content, Agent[] readers) throws UnsupportedEncodingException, EncodingFailedException {
+ public Envelope(String content, Agent[] readers) throws EncodingFailedException {
this(content, readers, new Random().nextLong());
}
@@ -243,11 +240,9 @@ public Envelope(String content, Agent[] readers) throws UnsupportedEncodingExcep
* @param content
* @param readers
* @param id
- * @throws UnsupportedEncodingException
* @throws EncodingFailedException
*/
- private Envelope(String content, Agent[] readers, long id)
- throws UnsupportedEncodingException, EncodingFailedException {
+ private Envelope(String content, Agent[] readers, long id) throws EncodingFailedException {
this.id = id;
initKey();
@@ -270,10 +265,9 @@ private Envelope(String content, Agent[] readers, long id)
* @param content
* @param readers
*
- * @throws UnsupportedEncodingException
* @throws EncodingFailedException
*/
- public Envelope(XmlAble content, Agent[] readers) throws UnsupportedEncodingException, EncodingFailedException {
+ public Envelope(XmlAble content, Agent[] readers) throws EncodingFailedException {
this(content, readers, new Random().nextLong());
}
@@ -288,10 +282,8 @@ public Envelope(XmlAble content, Agent[] readers) throws UnsupportedEncodingExce
* @param readers
* @param id
* @throws EncodingFailedException
- * @throws UnsupportedEncodingException
*/
- private Envelope(XmlAble content, Agent[] readers, long id)
- throws UnsupportedEncodingException, EncodingFailedException {
+ private Envelope(XmlAble content, Agent[] readers, long id) throws EncodingFailedException {
this.id = id;
initKey();
@@ -315,7 +307,7 @@ private Envelope(XmlAble content, Agent[] readers, long id)
*
* @param content
* @param reader
- * @throws EnvelopeException
+ * @throws EnvelopeException
*
* @throws EncodingFailedException
* @throws SerializationException
@@ -353,8 +345,8 @@ public Envelope(Serializable content, Agent[] readers) throws EncodingFailedExce
* @throws EncodingFailedException
* @throws SerializationException
*/
- private Envelope(Serializable content, Agent[] readers, long id)
- throws EncodingFailedException, SerializationException {
+ private Envelope(Serializable content, Agent[] readers, long id) throws EncodingFailedException,
+ SerializationException {
this.id = id;
initKey();
@@ -434,7 +426,7 @@ public void open(Agent agent) throws DecodingFailedException, L2pSecurityExcepti
throw new L2pSecurityException("agent " + agent.getId() + " has no access to this object");
}
- symmetricKey = (SecretKey) agent.returnSecretKey(encoded);
+ symmetricKey = agent.returnSecretKey(encoded);
openedBy = agent;
decryptData();
@@ -561,6 +553,21 @@ public void removeReader(Agent agent) throws L2pSecurityException {
htEncryptedKeys.remove(agent.getId());
}
+ /**
+ * checks if an agent is reader
+ *
+ * Attention: only direct reading access will be checked, no access gained via group memberships
+ *
+ * @param agent agent to check
+ * @return true if and only if the given agent is a reader
+ */
+ public boolean hasReader(Agent agent) {
+ if (agent instanceof GroupAgent)
+ return htEncryptedGroupKeys.containsKey(agent.getId());
+ else
+ return htEncryptedKeys.containsKey(agent.getId());
+ }
+
/**
* add a signature for the content. only agents that signed the Evnelope have writing access. if no signature is
* given, every reader can write to the envelope.
@@ -695,7 +702,7 @@ public byte[] getContentAsBinary() throws DecodingFailedException {
* returns the contents of this envelope as string
*
* @return content as string
- * @throws EnvelopeException
+ * @throws EnvelopeException
*
* @throws DecodingFailedException
*/
@@ -703,9 +710,7 @@ public String getContentAsString() throws EnvelopeException {
byte[] content = null;
try {
content = getContentAsBinary();
- return new String(content, "UTF-8");
- } catch (UnsupportedEncodingException e) {
- return new String(content);
+ return new String(content, StandardCharsets.UTF_8);
} catch (Exception e) {
throw new EnvelopeException("Coding problems with interpreting the content", e);
}
@@ -743,6 +748,15 @@ public XmlAble getContentAsXmlAble() throws EnvelopeException {
}
}
+ /**
+ * get a list with all ids of non-group agents entitled to read this envelope
+ *
+ * @return array with all agent ids
+ */
+ public Long[] getReader() {
+ return htEncryptedKeys.keySet().toArray(new Long[0]);
+ }
+
/**
* get a list with all ids of groups entitled to read this envelope
*
@@ -780,7 +794,8 @@ public Serializable getContentAsSerializable() throws EnvelopeException {
/**
* Get the content as deserialized object. This method uses the same class loader as the calling class.
- * @param
+ *
+ * @param
*
* @param cls
* @return the typed content of this envelope
@@ -799,7 +814,8 @@ public T getContent(Class cls) throws EnvelopeExcept
/**
* Get the content as deserialized object.
- * @param
+ *
+ * @param
*
* @param cls
* @param classLoader
@@ -837,8 +853,9 @@ protected Class> resolveClass(ObjectStreamClass desc) throws IOException, Clas
/**
* @return a XML (string) representation of this envelope
- * @throws SerializationException
+ * @throws SerializationException
*/
+ @Override
public String toXmlString() throws SerializationException {
if (baPlainData != null && baCipherData == null) {
try {
@@ -848,8 +865,8 @@ public String toXmlString() throws SerializationException {
}
}
- String encodedKeys = "\t\n";
+ String encodedKeys = "\t\n";
for (Long id : htEncryptedKeys.keySet()) {
encodedKeys += "\t\t" + Base64.encodeBase64String(htEncryptedKeys.get(id))
+ "\n";
@@ -994,11 +1011,11 @@ public static Envelope createFromXml(Element root) throws MalformedXMLException
if (!keys.getName().equals("keys"))
throw new MalformedXMLException("not an envelope");
if (!keys.getAttribute("encoding").equals("base64"))
- throw new MalformedXMLException(
- "base 64 encoding of the content expected - got: " + keys.getAttribute("encoding"));
+ throw new MalformedXMLException("base 64 encoding of the content expected - got: "
+ + keys.getAttribute("encoding"));
if (!keys.getAttribute("encryption").equals(CryptoTools.getAsymmetricAlgorithm()))
- throw new MalformedXMLException(
- CryptoTools.getAsymmetricAlgorithm() + " encryption of the content expected");
+ throw new MalformedXMLException(CryptoTools.getAsymmetricAlgorithm()
+ + " encryption of the content expected");
for (Enumeration enKeys = keys.getChildren(); enKeys.hasMoreElements();) {
Element key = enKeys.nextElement();
@@ -1019,8 +1036,8 @@ public static Envelope createFromXml(Element root) throws MalformedXMLException
if (!signatures.getName().equals("signatures"))
throw new MalformedXMLException("signatures expected");
if (!signatures.getAttribute("encoding").equals("base64"))
- throw new MalformedXMLException(
- "base 64 encoding of the content expected - got: " + keys.getAttribute("encoding"));
+ throw new MalformedXMLException("base 64 encoding of the content expected - got: "
+ + keys.getAttribute("encoding"));
if (!signatures.getAttribute("method").equals(CryptoTools.getSignatureMethod()))
throw new MalformedXMLException(CryptoTools.getSignatureMethod() + " expected as signature method");
@@ -1045,7 +1062,7 @@ public static Envelope createFromXml(Element root) throws MalformedXMLException
* get a locked copy of this agent
*
* @return a locked clone of this envelope
- * @throws EnvelopeException
+ * @throws EnvelopeException
* @throws EncodingFailedException
*/
public final Envelope cloneLocked() throws EnvelopeException {
@@ -1129,10 +1146,9 @@ public static long getClassEnvelopeId(String cls, String identifier) {
*
* @throws EncodingFailedException
* @throws SerializationException
- * @throws UnsupportedEncodingException
*/
public static Envelope createClassIdEnvelope(Object content, String identifier, Agent[] readers)
- throws EncodingFailedException, SerializationException, UnsupportedEncodingException {
+ throws EncodingFailedException, SerializationException {
if (content instanceof String)
return new Envelope((String) content, readers, getClassEnvelopeId(content.getClass(), identifier));
else if (content instanceof XmlAble)
@@ -1156,10 +1172,9 @@ else if (content instanceof byte[])
*
* @throws SerializationException
* @throws EncodingFailedException
- * @throws UnsupportedEncodingException
*/
public static Envelope createClassIdEnvelope(Object content, String identifier, Agent reader)
- throws UnsupportedEncodingException, EncodingFailedException, SerializationException {
+ throws EncodingFailedException, SerializationException {
return createClassIdEnvelope(content, identifier, new Agent[] { reader });
}
@@ -1188,8 +1203,8 @@ public static Envelope fetch(long id) throws ArtifactNotFoundException, StorageE
* @throws ArtifactNotFoundException
* @throws StorageException
*/
- public static Envelope fetchClassIdEnvelope(Class> cls, String identifier)
- throws ArtifactNotFoundException, StorageException {
+ public static Envelope fetchClassIdEnvelope(Class> cls, String identifier) throws ArtifactNotFoundException,
+ StorageException {
return Context.getCurrent().getStoredObject(cls, identifier);
}
@@ -1239,11 +1254,10 @@ public void updateContent(byte[] content) throws L2pSecurityException {
*
* @param content
*
- * @throws UnsupportedEncodingException
* @throws L2pSecurityException
*/
- public void updateContent(String content) throws UnsupportedEncodingException, L2pSecurityException {
- updateContent(content.getBytes("UTF-8"));
+ public void updateContent(String content) throws L2pSecurityException {
+ updateContent(content.getBytes(StandardCharsets.UTF_8));
contentType = ContentType.String;
}
@@ -1265,10 +1279,9 @@ public void updateContent(Serializable content) throws L2pSecurityException, Ser
*
* @param content
* @throws L2pSecurityException
- * @throws UnsupportedEncodingException
- * @throws SerializationException
+ * @throws SerializationException
*/
- public void updateContent(XmlAble content) throws UnsupportedEncodingException, L2pSecurityException, SerializationException {
+ public void updateContent(XmlAble content) throws L2pSecurityException, SerializationException {
updateContent(content.toXmlString());
contentType = ContentType.XmlAble;
clContentClass = content.getClass();
@@ -1297,8 +1310,8 @@ public void checkOverwrite(Envelope envelope) throws L2pSecurityException {
return;
}
- throw new L2pSecurityException(
- "Check for Overwriting envelope " + getId() + " failed: No needed signature is provided!");
+ throw new L2pSecurityException("Check for Overwriting envelope " + getId()
+ + " failed: No needed signature is provided!");
}
/**
diff --git a/src/main/java/i5/las2peer/security/UserAgentManager.java b/src/main/java/i5/las2peer/security/UserAgentManager.java
index 5a756ee71..5fe38415d 100644
--- a/src/main/java/i5/las2peer/security/UserAgentManager.java
+++ b/src/main/java/i5/las2peer/security/UserAgentManager.java
@@ -1,7 +1,5 @@
package i5.las2peer.security;
-import java.io.UnsupportedEncodingException;
-
import i5.las2peer.logging.NodeObserver.Event;
import i5.las2peer.p2p.AgentNotKnownException;
import i5.las2peer.p2p.ArtifactNotFoundException;
@@ -18,16 +16,16 @@
*
*/
public class UserAgentManager {
-
+
private static final String PREFIX_USER_NAME = "USER_NAME-";
private static final String PREFIX_USER_MAIL = "USER_MAIL-";
-
- private Node node;
-
+
+ private Node node;
+
public UserAgentManager(Node node) {
this.node = node;
}
-
+
/**
* Stores login name and email of an user agent to the network
*
@@ -36,15 +34,17 @@ public UserAgentManager(Node node) {
* @throws DuplicateLoginNameException
* @throws AgentLockedException
*/
- public void registerUserAgent(UserAgent agent) throws DuplicateEmailException, DuplicateLoginNameException, AgentLockedException {
+ public void registerUserAgent(UserAgent agent)
+ throws DuplicateEmailException, DuplicateLoginNameException, AgentLockedException {
if (agent.isLocked())
throw new AgentLockedException("Only unlocked Agents can be registered!");
-
+
Long content = agent.getId();
-
+
if (agent.hasLogin()) {
try {
- Envelope envName = Envelope.createClassIdEnvelope(content, PREFIX_USER_NAME + agent.getLoginName().toLowerCase(), agent);
+ Envelope envName = Envelope.createClassIdEnvelope(content,
+ PREFIX_USER_NAME + agent.getLoginName().toLowerCase(), agent);
envName.open(agent);
envName.setOverWriteBlindly(true);
envName.addReader(node.getAnonymous());
@@ -53,15 +53,15 @@ public void registerUserAgent(UserAgent agent) throws DuplicateEmailException, D
envName.close();
} catch (L2pSecurityException e) {
throw new DuplicateLoginNameException();
- } catch (UnsupportedEncodingException | EncodingFailedException
- | SerializationException | StorageException | DecodingFailedException e) {
+ } catch (EncodingFailedException | SerializationException | StorageException | DecodingFailedException e) {
node.observerNotice(Event.NODE_ERROR, "Envelope error while updating user list: " + e);
}
}
-
+
if (agent.hasEmail()) {
try {
- Envelope envMail = Envelope.createClassIdEnvelope(content, PREFIX_USER_MAIL + agent.getEmail().toLowerCase(), agent);
+ Envelope envMail = Envelope.createClassIdEnvelope(content,
+ PREFIX_USER_MAIL + agent.getEmail().toLowerCase(), agent);
envMail.open(agent);
envMail.setOverWriteBlindly(true);
envMail.addReader(node.getAnonymous());
@@ -70,56 +70,61 @@ public void registerUserAgent(UserAgent agent) throws DuplicateEmailException, D
envMail.close();
} catch (L2pSecurityException e) {
throw new DuplicateEmailException();
- } catch (UnsupportedEncodingException | EncodingFailedException
- | SerializationException | StorageException | DecodingFailedException e) {
+ } catch (EncodingFailedException | SerializationException | StorageException | DecodingFailedException e) {
node.observerNotice(Event.NODE_ERROR, "Envelope error while updating user list: " + e);
}
}
}
-
+
/**
* updates login name and email of an user
+ *
* @param agent
* @throws AgentLockedException
- * @throws DuplicateEmailException
- * @throws DuplicateLoginNameException
+ * @throws DuplicateEmailException
+ * @throws DuplicateLoginNameException
*/
- public void updateUserAgent(UserAgent agent) throws AgentLockedException, DuplicateEmailException, DuplicateLoginNameException {
+ public void updateUserAgent(UserAgent agent)
+ throws AgentLockedException, DuplicateEmailException, DuplicateLoginNameException {
registerUserAgent(agent);
}
-
+
/**
* get an {@link UserAgent}'s id by login name
+ *
* @param name
* @return
* @throws AgentNotKnownException
*/
public long getAgentIdByLogin(String name) throws AgentNotKnownException {
try {
- Envelope env = node.fetchArtifact(Envelope.getClassEnvelopeId(Long.class, PREFIX_USER_NAME + name.toLowerCase()));
+ Envelope env = node
+ .fetchArtifact(Envelope.getClassEnvelopeId(Long.class, PREFIX_USER_NAME + name.toLowerCase()));
env.open(node.getAnonymous());
Long content = env.getContent(Long.class);
env.close();
-
+
return content;
} catch (StorageException | ArtifactNotFoundException | EnvelopeException | L2pSecurityException e) {
throw new AgentNotKnownException("Username not found!", e);
}
}
-
+
/**
* get an {@link UserAgent}'s id by email address
+ *
* @param email
* @return
* @throws AgentNotKnownException
*/
public long getAgentIdByEmail(String email) throws AgentNotKnownException {
try {
- Envelope env = node.fetchArtifact(Envelope.getClassEnvelopeId(Long.class, PREFIX_USER_MAIL + email.toLowerCase()));
+ Envelope env = node
+ .fetchArtifact(Envelope.getClassEnvelopeId(Long.class, PREFIX_USER_MAIL + email.toLowerCase()));
env.open(node.getAnonymous());
Long content = env.getContent(Long.class);
env.close();
-
+
return content;
} catch (StorageException | ArtifactNotFoundException | EnvelopeException | L2pSecurityException e) {
throw new AgentNotKnownException("Email not found!", e);
diff --git a/src/main/java/i5/las2peer/tools/L2pNodeLauncher.java b/src/main/java/i5/las2peer/tools/L2pNodeLauncher.java
index a821e2b03..c03556df1 100644
--- a/src/main/java/i5/las2peer/tools/L2pNodeLauncher.java
+++ b/src/main/java/i5/las2peer/tools/L2pNodeLauncher.java
@@ -51,7 +51,11 @@
import rice.p2p.commonapi.NodeHandle;
/**
- * This class implements the LAS2peer node launcher functionalities.
+ * las2peer node launcher
+ *
+ * It is the main tool for service developers / node maintainers to start their services, upload agents to the network
+ * and to test their service methods directly in the p2p network. The launcher both supports the start of a new network
+ * as well as starting a node that connects to an already existing network via a bootstrap.
*
* All methods to be executed can be stated via additional command line parameters to the {@link #main} method.
*/