mirror of
https://code.briarproject.org/briar/briar.git
synced 2026-02-16 12:49:55 +01:00
Update introduction validator to support auto-delete timers.
This commit is contained in:
@@ -64,4 +64,9 @@ public class ValidationUtils {
|
|||||||
if (dictionary != null && dictionary.size() != size)
|
if (dictionary != null && dictionary.size() != size)
|
||||||
throw new FormatException();
|
throw new FormatException();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static void checkRange(@Nullable Long l, long min, long max)
|
||||||
|
throws FormatException {
|
||||||
|
if (l != null && (l < min || l > max)) throw new FormatException();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -31,7 +31,7 @@ public interface IntroductionManager extends ConversationClient {
|
|||||||
/**
|
/**
|
||||||
* The current minor version of the introduction client.
|
* The current minor version of the introduction client.
|
||||||
*/
|
*/
|
||||||
int MINOR_VERSION = 0;
|
int MINOR_VERSION = 1;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sends two initial introduction messages.
|
* Sends two initial introduction messages.
|
||||||
|
|||||||
@@ -31,6 +31,7 @@ import java.util.Map;
|
|||||||
import javax.annotation.Nullable;
|
import javax.annotation.Nullable;
|
||||||
import javax.annotation.concurrent.Immutable;
|
import javax.annotation.concurrent.Immutable;
|
||||||
|
|
||||||
|
import static org.briarproject.bramble.api.autodelete.AutoDeleteConstants.NO_AUTO_DELETE_TIMER;
|
||||||
import static org.briarproject.briar.introduction.MessageType.ABORT;
|
import static org.briarproject.briar.introduction.MessageType.ABORT;
|
||||||
import static org.briarproject.briar.introduction.MessageType.ACCEPT;
|
import static org.briarproject.briar.introduction.MessageType.ACCEPT;
|
||||||
import static org.briarproject.briar.introduction.MessageType.ACTIVATE;
|
import static org.briarproject.briar.introduction.MessageType.ACTIVATE;
|
||||||
@@ -40,7 +41,7 @@ import static org.briarproject.briar.introduction.MessageType.REQUEST;
|
|||||||
|
|
||||||
@Immutable
|
@Immutable
|
||||||
@NotNullByDefault
|
@NotNullByDefault
|
||||||
abstract class AbstractProtocolEngine<S extends Session>
|
abstract class AbstractProtocolEngine<S extends Session<?>>
|
||||||
implements ProtocolEngine<S> {
|
implements ProtocolEngine<S> {
|
||||||
|
|
||||||
protected final DatabaseComponent db;
|
protected final DatabaseComponent db;
|
||||||
@@ -140,9 +141,11 @@ abstract class AbstractProtocolEngine<S extends Session>
|
|||||||
private void sendMessage(Transaction txn, MessageType type,
|
private void sendMessage(Transaction txn, MessageType type,
|
||||||
SessionId sessionId, Message m, boolean visibleInConversation)
|
SessionId sessionId, Message m, boolean visibleInConversation)
|
||||||
throws DbException {
|
throws DbException {
|
||||||
|
// TODO: If message is visible in conversation, look up current
|
||||||
|
// auto-delete timer and include it in message
|
||||||
BdfDictionary meta = messageEncoder
|
BdfDictionary meta = messageEncoder
|
||||||
.encodeMetadata(type, sessionId, m.getTimestamp(), true, true,
|
.encodeMetadata(type, sessionId, m.getTimestamp(), true, true,
|
||||||
visibleInConversation);
|
visibleInConversation, NO_AUTO_DELETE_TIMER);
|
||||||
try {
|
try {
|
||||||
clientHelper.addLocalMessage(txn, m, meta, true, false);
|
clientHelper.addLocalMessage(txn, m, meta, true, false);
|
||||||
} catch (FormatException e) {
|
} catch (FormatException e) {
|
||||||
@@ -150,9 +153,10 @@ abstract class AbstractProtocolEngine<S extends Session>
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void broadcastIntroductionResponseReceivedEvent(Transaction txn, Session s,
|
void broadcastIntroductionResponseReceivedEvent(Transaction txn,
|
||||||
AuthorId sender, Author otherAuthor, AbstractIntroductionMessage m,
|
Session<?> s, AuthorId sender, Author otherAuthor,
|
||||||
boolean canSucceed) throws DbException {
|
AbstractIntroductionMessage m, boolean canSucceed)
|
||||||
|
throws DbException {
|
||||||
AuthorId localAuthorId = identityManager.getLocalAuthor(txn).getId();
|
AuthorId localAuthorId = identityManager.getLocalAuthor(txn).getId();
|
||||||
Contact c = contactManager.getContact(txn, sender, localAuthorId);
|
Contact c = contactManager.getContact(txn, sender, localAuthorId);
|
||||||
AuthorInfo otherAuthorInfo =
|
AuthorInfo otherAuthorInfo =
|
||||||
|
|||||||
@@ -12,6 +12,7 @@ interface IntroductionConstants {
|
|||||||
String MSG_KEY_LOCAL = "local";
|
String MSG_KEY_LOCAL = "local";
|
||||||
String MSG_KEY_VISIBLE_IN_UI = "visibleInUi";
|
String MSG_KEY_VISIBLE_IN_UI = "visibleInUi";
|
||||||
String MSG_KEY_AVAILABLE_TO_ANSWER = "availableToAnswer";
|
String MSG_KEY_AVAILABLE_TO_ANSWER = "availableToAnswer";
|
||||||
|
String MSG_KEY_AUTO_DELETE_TIMER = "autoDeleteTimer";
|
||||||
|
|
||||||
// Session Keys
|
// Session Keys
|
||||||
String SESSION_KEY_SESSION_ID = "sessionId";
|
String SESSION_KEY_SESSION_ID = "sessionId";
|
||||||
|
|||||||
@@ -18,10 +18,14 @@ import org.briarproject.briar.api.client.SessionId;
|
|||||||
import javax.annotation.concurrent.Immutable;
|
import javax.annotation.concurrent.Immutable;
|
||||||
|
|
||||||
import static java.util.Collections.singletonList;
|
import static java.util.Collections.singletonList;
|
||||||
|
import static org.briarproject.bramble.api.autodelete.AutoDeleteConstants.MAX_AUTO_DELETE_TIMER_MS;
|
||||||
|
import static org.briarproject.bramble.api.autodelete.AutoDeleteConstants.MIN_AUTO_DELETE_TIMER_MS;
|
||||||
|
import static org.briarproject.bramble.api.autodelete.AutoDeleteConstants.NO_AUTO_DELETE_TIMER;
|
||||||
import static org.briarproject.bramble.api.crypto.CryptoConstants.MAC_BYTES;
|
import static org.briarproject.bramble.api.crypto.CryptoConstants.MAC_BYTES;
|
||||||
import static org.briarproject.bramble.api.crypto.CryptoConstants.MAX_SIGNATURE_BYTES;
|
import static org.briarproject.bramble.api.crypto.CryptoConstants.MAX_SIGNATURE_BYTES;
|
||||||
import static org.briarproject.bramble.api.identity.AuthorConstants.MAX_PUBLIC_KEY_LENGTH;
|
import static org.briarproject.bramble.api.identity.AuthorConstants.MAX_PUBLIC_KEY_LENGTH;
|
||||||
import static org.briarproject.bramble.util.ValidationUtils.checkLength;
|
import static org.briarproject.bramble.util.ValidationUtils.checkLength;
|
||||||
|
import static org.briarproject.bramble.util.ValidationUtils.checkRange;
|
||||||
import static org.briarproject.bramble.util.ValidationUtils.checkSize;
|
import static org.briarproject.bramble.util.ValidationUtils.checkSize;
|
||||||
import static org.briarproject.briar.api.introduction.IntroductionConstants.MAX_INTRODUCTION_TEXT_LENGTH;
|
import static org.briarproject.briar.api.introduction.IntroductionConstants.MAX_INTRODUCTION_TEXT_LENGTH;
|
||||||
import static org.briarproject.briar.introduction.MessageType.ACCEPT;
|
import static org.briarproject.briar.introduction.MessageType.ACCEPT;
|
||||||
@@ -52,13 +56,14 @@ class IntroductionValidator extends BdfMessageValidator {
|
|||||||
return validateRequestMessage(m, body);
|
return validateRequestMessage(m, body);
|
||||||
case ACCEPT:
|
case ACCEPT:
|
||||||
return validateAcceptMessage(m, body);
|
return validateAcceptMessage(m, body);
|
||||||
|
case DECLINE:
|
||||||
|
return validateDeclineMessage(type, m, body);
|
||||||
case AUTH:
|
case AUTH:
|
||||||
return validateAuthMessage(m, body);
|
return validateAuthMessage(m, body);
|
||||||
case ACTIVATE:
|
case ACTIVATE:
|
||||||
return validateActivateMessage(m, body);
|
return validateActivateMessage(m, body);
|
||||||
case DECLINE:
|
|
||||||
case ABORT:
|
case ABORT:
|
||||||
return validateOtherMessage(type, m, body);
|
return validateAbortMessage(type, m, body);
|
||||||
default:
|
default:
|
||||||
throw new FormatException();
|
throw new FormatException();
|
||||||
}
|
}
|
||||||
@@ -66,7 +71,11 @@ class IntroductionValidator extends BdfMessageValidator {
|
|||||||
|
|
||||||
private BdfMessageContext validateRequestMessage(Message m, BdfList body)
|
private BdfMessageContext validateRequestMessage(Message m, BdfList body)
|
||||||
throws FormatException {
|
throws FormatException {
|
||||||
checkSize(body, 4);
|
// Client version 0.0: Message type, optional previous message ID,
|
||||||
|
// author, optional text.
|
||||||
|
// Client version 0.1: Message type, optional previous message ID,
|
||||||
|
// author, optional text, optional auto-delete timer.
|
||||||
|
checkSize(body, 4, 5);
|
||||||
|
|
||||||
byte[] previousMessageId = body.getOptionalRaw(1);
|
byte[] previousMessageId = body.getOptionalRaw(1);
|
||||||
checkLength(previousMessageId, UniqueId.LENGTH);
|
checkLength(previousMessageId, UniqueId.LENGTH);
|
||||||
@@ -77,8 +86,16 @@ class IntroductionValidator extends BdfMessageValidator {
|
|||||||
String text = body.getOptionalString(3);
|
String text = body.getOptionalString(3);
|
||||||
checkLength(text, 1, MAX_INTRODUCTION_TEXT_LENGTH);
|
checkLength(text, 1, MAX_INTRODUCTION_TEXT_LENGTH);
|
||||||
|
|
||||||
|
Long timer = null;
|
||||||
|
if (body.size() == 5) {
|
||||||
|
timer = body.getOptionalLong(4);
|
||||||
|
checkRange(timer, MIN_AUTO_DELETE_TIMER_MS,
|
||||||
|
MAX_AUTO_DELETE_TIMER_MS);
|
||||||
|
}
|
||||||
|
if (timer == null) timer = NO_AUTO_DELETE_TIMER;
|
||||||
|
|
||||||
BdfDictionary meta =
|
BdfDictionary meta =
|
||||||
messageEncoder.encodeRequestMetadata(m.getTimestamp());
|
messageEncoder.encodeRequestMetadata(m.getTimestamp(), timer);
|
||||||
if (previousMessageId == null) {
|
if (previousMessageId == null) {
|
||||||
return new BdfMessageContext(meta);
|
return new BdfMessageContext(meta);
|
||||||
} else {
|
} else {
|
||||||
@@ -89,7 +106,12 @@ class IntroductionValidator extends BdfMessageValidator {
|
|||||||
|
|
||||||
private BdfMessageContext validateAcceptMessage(Message m, BdfList body)
|
private BdfMessageContext validateAcceptMessage(Message m, BdfList body)
|
||||||
throws FormatException {
|
throws FormatException {
|
||||||
checkSize(body, 6);
|
// Client version 0.0: Message type, session ID, optional previous
|
||||||
|
// message ID, ephemeral public key, timestamp, transport properties.
|
||||||
|
// Client version 0.1: Message type, session ID, optional previous
|
||||||
|
// message ID, ephemeral public key, timestamp, transport properties,
|
||||||
|
// optional auto-delete timer.
|
||||||
|
checkSize(body, 6, 7);
|
||||||
|
|
||||||
byte[] sessionIdBytes = body.getRaw(1);
|
byte[] sessionIdBytes = body.getRaw(1);
|
||||||
checkLength(sessionIdBytes, UniqueId.LENGTH);
|
checkLength(sessionIdBytes, UniqueId.LENGTH);
|
||||||
@@ -109,9 +131,50 @@ class IntroductionValidator extends BdfMessageValidator {
|
|||||||
clientHelper
|
clientHelper
|
||||||
.parseAndValidateTransportPropertiesMap(transportProperties);
|
.parseAndValidateTransportPropertiesMap(transportProperties);
|
||||||
|
|
||||||
|
Long timer = null;
|
||||||
|
if (body.size() == 7) {
|
||||||
|
timer = body.getOptionalLong(6);
|
||||||
|
checkRange(timer, MIN_AUTO_DELETE_TIMER_MS,
|
||||||
|
MAX_AUTO_DELETE_TIMER_MS);
|
||||||
|
}
|
||||||
|
if (timer == null) timer = NO_AUTO_DELETE_TIMER;
|
||||||
|
|
||||||
SessionId sessionId = new SessionId(sessionIdBytes);
|
SessionId sessionId = new SessionId(sessionIdBytes);
|
||||||
BdfDictionary meta = messageEncoder.encodeMetadata(ACCEPT, sessionId,
|
BdfDictionary meta = messageEncoder.encodeMetadata(ACCEPT, sessionId,
|
||||||
m.getTimestamp(), false, false, false);
|
m.getTimestamp(), false, false, false, timer);
|
||||||
|
if (previousMessageId == null) {
|
||||||
|
return new BdfMessageContext(meta);
|
||||||
|
} else {
|
||||||
|
MessageId dependency = new MessageId(previousMessageId);
|
||||||
|
return new BdfMessageContext(meta, singletonList(dependency));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private BdfMessageContext validateDeclineMessage(MessageType type,
|
||||||
|
Message m, BdfList body) throws FormatException {
|
||||||
|
// Client version 0.0: Message type, session ID, optional previous
|
||||||
|
// message ID.
|
||||||
|
// Client version 0.1: Message type, session ID, optional previous
|
||||||
|
// message ID, optional auto-delete timer.
|
||||||
|
checkSize(body, 3, 4);
|
||||||
|
|
||||||
|
byte[] sessionIdBytes = body.getRaw(1);
|
||||||
|
checkLength(sessionIdBytes, UniqueId.LENGTH);
|
||||||
|
|
||||||
|
byte[] previousMessageId = body.getOptionalRaw(2);
|
||||||
|
checkLength(previousMessageId, UniqueId.LENGTH);
|
||||||
|
|
||||||
|
Long timer = null;
|
||||||
|
if (body.size() == 4) {
|
||||||
|
timer = body.getOptionalLong(3);
|
||||||
|
checkRange(timer, MIN_AUTO_DELETE_TIMER_MS,
|
||||||
|
MAX_AUTO_DELETE_TIMER_MS);
|
||||||
|
}
|
||||||
|
if (timer == null) timer = NO_AUTO_DELETE_TIMER;
|
||||||
|
|
||||||
|
SessionId sessionId = new SessionId(sessionIdBytes);
|
||||||
|
BdfDictionary meta = messageEncoder.encodeMetadata(type, sessionId,
|
||||||
|
m.getTimestamp(), false, false, false, timer);
|
||||||
if (previousMessageId == null) {
|
if (previousMessageId == null) {
|
||||||
return new BdfMessageContext(meta);
|
return new BdfMessageContext(meta);
|
||||||
} else {
|
} else {
|
||||||
@@ -138,7 +201,7 @@ class IntroductionValidator extends BdfMessageValidator {
|
|||||||
|
|
||||||
SessionId sessionId = new SessionId(sessionIdBytes);
|
SessionId sessionId = new SessionId(sessionIdBytes);
|
||||||
BdfDictionary meta = messageEncoder.encodeMetadata(AUTH, sessionId,
|
BdfDictionary meta = messageEncoder.encodeMetadata(AUTH, sessionId,
|
||||||
m.getTimestamp(), false, false, false);
|
m.getTimestamp(), false, false, false, NO_AUTO_DELETE_TIMER);
|
||||||
MessageId dependency = new MessageId(previousMessageId);
|
MessageId dependency = new MessageId(previousMessageId);
|
||||||
return new BdfMessageContext(meta, singletonList(dependency));
|
return new BdfMessageContext(meta, singletonList(dependency));
|
||||||
}
|
}
|
||||||
@@ -158,7 +221,7 @@ class IntroductionValidator extends BdfMessageValidator {
|
|||||||
|
|
||||||
SessionId sessionId = new SessionId(sessionIdBytes);
|
SessionId sessionId = new SessionId(sessionIdBytes);
|
||||||
BdfDictionary meta = messageEncoder.encodeMetadata(ACTIVATE, sessionId,
|
BdfDictionary meta = messageEncoder.encodeMetadata(ACTIVATE, sessionId,
|
||||||
m.getTimestamp(), false, false, false);
|
m.getTimestamp(), false, false, false, NO_AUTO_DELETE_TIMER);
|
||||||
if (previousMessageId == null) {
|
if (previousMessageId == null) {
|
||||||
return new BdfMessageContext(meta);
|
return new BdfMessageContext(meta);
|
||||||
} else {
|
} else {
|
||||||
@@ -167,7 +230,7 @@ class IntroductionValidator extends BdfMessageValidator {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private BdfMessageContext validateOtherMessage(MessageType type,
|
private BdfMessageContext validateAbortMessage(MessageType type,
|
||||||
Message m, BdfList body) throws FormatException {
|
Message m, BdfList body) throws FormatException {
|
||||||
checkSize(body, 3);
|
checkSize(body, 3);
|
||||||
|
|
||||||
@@ -179,7 +242,7 @@ class IntroductionValidator extends BdfMessageValidator {
|
|||||||
|
|
||||||
SessionId sessionId = new SessionId(sessionIdBytes);
|
SessionId sessionId = new SessionId(sessionIdBytes);
|
||||||
BdfDictionary meta = messageEncoder.encodeMetadata(type, sessionId,
|
BdfDictionary meta = messageEncoder.encodeMetadata(type, sessionId,
|
||||||
m.getTimestamp(), false, false, false);
|
m.getTimestamp(), false, false, false, NO_AUTO_DELETE_TIMER);
|
||||||
if (previousMessageId == null) {
|
if (previousMessageId == null) {
|
||||||
return new BdfMessageContext(meta);
|
return new BdfMessageContext(meta);
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@@ -18,11 +18,12 @@ import javax.annotation.Nullable;
|
|||||||
@NotNullByDefault
|
@NotNullByDefault
|
||||||
interface MessageEncoder {
|
interface MessageEncoder {
|
||||||
|
|
||||||
BdfDictionary encodeRequestMetadata(long timestamp);
|
BdfDictionary encodeRequestMetadata(long timestamp,
|
||||||
|
long autoDeleteTimer);
|
||||||
|
|
||||||
BdfDictionary encodeMetadata(MessageType type,
|
BdfDictionary encodeMetadata(MessageType type,
|
||||||
@Nullable SessionId sessionId, long timestamp, boolean local,
|
@Nullable SessionId sessionId, long timestamp, boolean local,
|
||||||
boolean read, boolean visible);
|
boolean read, boolean visible, long autoDeleteTimer);
|
||||||
|
|
||||||
void addSessionId(BdfDictionary meta, SessionId sessionId);
|
void addSessionId(BdfDictionary meta, SessionId sessionId);
|
||||||
|
|
||||||
|
|||||||
@@ -20,7 +20,9 @@ import java.util.Map;
|
|||||||
import javax.annotation.Nullable;
|
import javax.annotation.Nullable;
|
||||||
import javax.inject.Inject;
|
import javax.inject.Inject;
|
||||||
|
|
||||||
|
import static org.briarproject.bramble.api.autodelete.AutoDeleteConstants.NO_AUTO_DELETE_TIMER;
|
||||||
import static org.briarproject.briar.client.MessageTrackerConstants.MSG_KEY_READ;
|
import static org.briarproject.briar.client.MessageTrackerConstants.MSG_KEY_READ;
|
||||||
|
import static org.briarproject.briar.introduction.IntroductionConstants.MSG_KEY_AUTO_DELETE_TIMER;
|
||||||
import static org.briarproject.briar.introduction.IntroductionConstants.MSG_KEY_AVAILABLE_TO_ANSWER;
|
import static org.briarproject.briar.introduction.IntroductionConstants.MSG_KEY_AVAILABLE_TO_ANSWER;
|
||||||
import static org.briarproject.briar.introduction.IntroductionConstants.MSG_KEY_LOCAL;
|
import static org.briarproject.briar.introduction.IntroductionConstants.MSG_KEY_LOCAL;
|
||||||
import static org.briarproject.briar.introduction.IntroductionConstants.MSG_KEY_MESSAGE_TYPE;
|
import static org.briarproject.briar.introduction.IntroductionConstants.MSG_KEY_MESSAGE_TYPE;
|
||||||
@@ -48,9 +50,10 @@ class MessageEncoderImpl implements MessageEncoder {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public BdfDictionary encodeRequestMetadata(long timestamp) {
|
public BdfDictionary encodeRequestMetadata(long timestamp,
|
||||||
BdfDictionary meta =
|
long autoDeleteTimer) {
|
||||||
encodeMetadata(REQUEST, null, timestamp, false, false, false);
|
BdfDictionary meta = encodeMetadata(REQUEST, null, timestamp,
|
||||||
|
false, false, false, autoDeleteTimer);
|
||||||
meta.put(MSG_KEY_AVAILABLE_TO_ANSWER, false);
|
meta.put(MSG_KEY_AVAILABLE_TO_ANSWER, false);
|
||||||
return meta;
|
return meta;
|
||||||
}
|
}
|
||||||
@@ -58,7 +61,7 @@ class MessageEncoderImpl implements MessageEncoder {
|
|||||||
@Override
|
@Override
|
||||||
public BdfDictionary encodeMetadata(MessageType type,
|
public BdfDictionary encodeMetadata(MessageType type,
|
||||||
@Nullable SessionId sessionId, long timestamp, boolean local,
|
@Nullable SessionId sessionId, long timestamp, boolean local,
|
||||||
boolean read, boolean visible) {
|
boolean read, boolean visible, long autoDeleteTimer) {
|
||||||
BdfDictionary meta = new BdfDictionary();
|
BdfDictionary meta = new BdfDictionary();
|
||||||
meta.put(MSG_KEY_MESSAGE_TYPE, type.getValue());
|
meta.put(MSG_KEY_MESSAGE_TYPE, type.getValue());
|
||||||
if (sessionId != null)
|
if (sessionId != null)
|
||||||
@@ -69,6 +72,9 @@ class MessageEncoderImpl implements MessageEncoder {
|
|||||||
meta.put(MSG_KEY_LOCAL, local);
|
meta.put(MSG_KEY_LOCAL, local);
|
||||||
meta.put(MSG_KEY_READ, read);
|
meta.put(MSG_KEY_READ, read);
|
||||||
meta.put(MSG_KEY_VISIBLE_IN_UI, visible);
|
meta.put(MSG_KEY_VISIBLE_IN_UI, visible);
|
||||||
|
if (autoDeleteTimer != NO_AUTO_DELETE_TIMER) {
|
||||||
|
meta.put(MSG_KEY_AUTO_DELETE_TIMER, autoDeleteTimer);
|
||||||
|
}
|
||||||
return meta;
|
return meta;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -13,12 +13,12 @@ class MessageMetadata {
|
|||||||
private final MessageType type;
|
private final MessageType type;
|
||||||
@Nullable
|
@Nullable
|
||||||
private final SessionId sessionId;
|
private final SessionId sessionId;
|
||||||
private final long timestamp;
|
private final long timestamp, autoDeleteTimer;
|
||||||
private final boolean local, read, visible, available;
|
private final boolean local, read, visible, available;
|
||||||
|
|
||||||
MessageMetadata(MessageType type, @Nullable SessionId sessionId,
|
MessageMetadata(MessageType type, @Nullable SessionId sessionId,
|
||||||
long timestamp, boolean local, boolean read, boolean visible,
|
long timestamp, boolean local, boolean read, boolean visible,
|
||||||
boolean available) {
|
boolean available, long autoDeleteTimer) {
|
||||||
this.type = type;
|
this.type = type;
|
||||||
this.sessionId = sessionId;
|
this.sessionId = sessionId;
|
||||||
this.timestamp = timestamp;
|
this.timestamp = timestamp;
|
||||||
@@ -26,6 +26,7 @@ class MessageMetadata {
|
|||||||
this.read = read;
|
this.read = read;
|
||||||
this.visible = visible;
|
this.visible = visible;
|
||||||
this.available = available;
|
this.available = available;
|
||||||
|
this.autoDeleteTimer = autoDeleteTimer;
|
||||||
}
|
}
|
||||||
|
|
||||||
MessageType getMessageType() {
|
MessageType getMessageType() {
|
||||||
@@ -57,4 +58,7 @@ class MessageMetadata {
|
|||||||
return available;
|
return available;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public long getAutoDeleteTimer() {
|
||||||
|
return autoDeleteTimer;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -19,7 +19,9 @@ import java.util.Map;
|
|||||||
|
|
||||||
import javax.inject.Inject;
|
import javax.inject.Inject;
|
||||||
|
|
||||||
|
import static org.briarproject.bramble.api.autodelete.AutoDeleteConstants.NO_AUTO_DELETE_TIMER;
|
||||||
import static org.briarproject.briar.client.MessageTrackerConstants.MSG_KEY_READ;
|
import static org.briarproject.briar.client.MessageTrackerConstants.MSG_KEY_READ;
|
||||||
|
import static org.briarproject.briar.introduction.IntroductionConstants.MSG_KEY_AUTO_DELETE_TIMER;
|
||||||
import static org.briarproject.briar.introduction.IntroductionConstants.MSG_KEY_AVAILABLE_TO_ANSWER;
|
import static org.briarproject.briar.introduction.IntroductionConstants.MSG_KEY_AVAILABLE_TO_ANSWER;
|
||||||
import static org.briarproject.briar.introduction.IntroductionConstants.MSG_KEY_LOCAL;
|
import static org.briarproject.briar.introduction.IntroductionConstants.MSG_KEY_LOCAL;
|
||||||
import static org.briarproject.briar.introduction.IntroductionConstants.MSG_KEY_MESSAGE_TYPE;
|
import static org.briarproject.briar.introduction.IntroductionConstants.MSG_KEY_MESSAGE_TYPE;
|
||||||
@@ -65,8 +67,9 @@ class MessageParserImpl implements MessageParser {
|
|||||||
boolean read = d.getBoolean(MSG_KEY_READ);
|
boolean read = d.getBoolean(MSG_KEY_READ);
|
||||||
boolean visible = d.getBoolean(MSG_KEY_VISIBLE_IN_UI);
|
boolean visible = d.getBoolean(MSG_KEY_VISIBLE_IN_UI);
|
||||||
boolean available = d.getBoolean(MSG_KEY_AVAILABLE_TO_ANSWER, false);
|
boolean available = d.getBoolean(MSG_KEY_AVAILABLE_TO_ANSWER, false);
|
||||||
|
long timer = d.getLong(MSG_KEY_AUTO_DELETE_TIMER, NO_AUTO_DELETE_TIMER);
|
||||||
return new MessageMetadata(type, sessionId, timestamp, local, read,
|
return new MessageMetadata(type, sessionId, timestamp, local, read,
|
||||||
visible, available);
|
visible, available, timer);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -29,6 +29,7 @@ import static org.briarproject.bramble.api.autodelete.AutoDeleteConstants.MIN_AU
|
|||||||
import static org.briarproject.bramble.api.sync.SyncConstants.MAX_MESSAGE_BODY_LENGTH;
|
import static org.briarproject.bramble.api.sync.SyncConstants.MAX_MESSAGE_BODY_LENGTH;
|
||||||
import static org.briarproject.bramble.api.transport.TransportConstants.MAX_CLOCK_DIFFERENCE;
|
import static org.briarproject.bramble.api.transport.TransportConstants.MAX_CLOCK_DIFFERENCE;
|
||||||
import static org.briarproject.bramble.util.ValidationUtils.checkLength;
|
import static org.briarproject.bramble.util.ValidationUtils.checkLength;
|
||||||
|
import static org.briarproject.bramble.util.ValidationUtils.checkRange;
|
||||||
import static org.briarproject.bramble.util.ValidationUtils.checkSize;
|
import static org.briarproject.bramble.util.ValidationUtils.checkSize;
|
||||||
import static org.briarproject.briar.api.attachment.MediaConstants.MAX_CONTENT_TYPE_BYTES;
|
import static org.briarproject.briar.api.attachment.MediaConstants.MAX_CONTENT_TYPE_BYTES;
|
||||||
import static org.briarproject.briar.api.attachment.MediaConstants.MSG_KEY_CONTENT_TYPE;
|
import static org.briarproject.briar.api.attachment.MediaConstants.MSG_KEY_CONTENT_TYPE;
|
||||||
@@ -137,10 +138,10 @@ class PrivateMessageValidator implements MessageValidator {
|
|||||||
checkLength(contentType, 1, MAX_CONTENT_TYPE_BYTES);
|
checkLength(contentType, 1, MAX_CONTENT_TYPE_BYTES);
|
||||||
}
|
}
|
||||||
Long timer = null;
|
Long timer = null;
|
||||||
if (body.size() == 4) timer = body.getOptionalLong(3);
|
if (body.size() == 4) {
|
||||||
if (timer != null && (timer < MIN_AUTO_DELETE_TIMER_MS ||
|
timer = body.getOptionalLong(3);
|
||||||
timer > MAX_AUTO_DELETE_TIMER_MS)) {
|
checkRange(timer, MIN_AUTO_DELETE_TIMER_MS,
|
||||||
throw new FormatException();
|
MAX_AUTO_DELETE_TIMER_MS);
|
||||||
}
|
}
|
||||||
// Return the metadata
|
// Return the metadata
|
||||||
BdfDictionary meta = new BdfDictionary();
|
BdfDictionary meta = new BdfDictionary();
|
||||||
|
|||||||
@@ -6,20 +6,29 @@ import org.briarproject.bramble.api.crypto.PublicKey;
|
|||||||
import org.briarproject.bramble.api.data.BdfDictionary;
|
import org.briarproject.bramble.api.data.BdfDictionary;
|
||||||
import org.briarproject.bramble.api.data.BdfEntry;
|
import org.briarproject.bramble.api.data.BdfEntry;
|
||||||
import org.briarproject.bramble.api.data.BdfList;
|
import org.briarproject.bramble.api.data.BdfList;
|
||||||
|
import org.briarproject.bramble.api.plugin.TransportId;
|
||||||
|
import org.briarproject.bramble.api.properties.TransportProperties;
|
||||||
import org.briarproject.bramble.api.sync.MessageId;
|
import org.briarproject.bramble.api.sync.MessageId;
|
||||||
import org.briarproject.bramble.test.ValidatorTestCase;
|
import org.briarproject.bramble.test.ValidatorTestCase;
|
||||||
import org.briarproject.briar.api.client.SessionId;
|
import org.briarproject.briar.api.client.SessionId;
|
||||||
import org.jmock.Expectations;
|
import org.jmock.Expectations;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
import javax.annotation.Nullable;
|
import javax.annotation.Nullable;
|
||||||
|
|
||||||
|
import static java.util.Collections.singletonMap;
|
||||||
|
import static org.briarproject.bramble.api.autodelete.AutoDeleteConstants.MAX_AUTO_DELETE_TIMER_MS;
|
||||||
|
import static org.briarproject.bramble.api.autodelete.AutoDeleteConstants.MIN_AUTO_DELETE_TIMER_MS;
|
||||||
|
import static org.briarproject.bramble.api.autodelete.AutoDeleteConstants.NO_AUTO_DELETE_TIMER;
|
||||||
import static org.briarproject.bramble.api.crypto.CryptoConstants.MAC_BYTES;
|
import static org.briarproject.bramble.api.crypto.CryptoConstants.MAC_BYTES;
|
||||||
import static org.briarproject.bramble.api.crypto.CryptoConstants.MAX_AGREEMENT_PUBLIC_KEY_BYTES;
|
import static org.briarproject.bramble.api.crypto.CryptoConstants.MAX_AGREEMENT_PUBLIC_KEY_BYTES;
|
||||||
import static org.briarproject.bramble.api.crypto.CryptoConstants.MAX_SIGNATURE_BYTES;
|
import static org.briarproject.bramble.api.crypto.CryptoConstants.MAX_SIGNATURE_BYTES;
|
||||||
import static org.briarproject.bramble.test.TestUtils.getAgreementPublicKey;
|
import static org.briarproject.bramble.test.TestUtils.getAgreementPublicKey;
|
||||||
import static org.briarproject.bramble.test.TestUtils.getRandomBytes;
|
import static org.briarproject.bramble.test.TestUtils.getRandomBytes;
|
||||||
import static org.briarproject.bramble.test.TestUtils.getRandomId;
|
import static org.briarproject.bramble.test.TestUtils.getRandomId;
|
||||||
|
import static org.briarproject.bramble.test.TestUtils.getTransportId;
|
||||||
import static org.briarproject.bramble.util.StringUtils.getRandomString;
|
import static org.briarproject.bramble.util.StringUtils.getRandomString;
|
||||||
import static org.briarproject.briar.api.introduction.IntroductionConstants.MAX_INTRODUCTION_TEXT_LENGTH;
|
import static org.briarproject.briar.api.introduction.IntroductionConstants.MAX_INTRODUCTION_TEXT_LENGTH;
|
||||||
import static org.briarproject.briar.introduction.MessageType.ABORT;
|
import static org.briarproject.briar.introduction.MessageType.ABORT;
|
||||||
@@ -44,9 +53,12 @@ public class IntroductionValidatorTest extends ValidatorTestCase {
|
|||||||
private final BdfDictionary meta = new BdfDictionary();
|
private final BdfDictionary meta = new BdfDictionary();
|
||||||
private final PublicKey ephemeralPublicKey = getAgreementPublicKey();
|
private final PublicKey ephemeralPublicKey = getAgreementPublicKey();
|
||||||
private final long acceptTimestamp = 42;
|
private final long acceptTimestamp = 42;
|
||||||
|
private final TransportId transportId = getTransportId();
|
||||||
private final BdfDictionary transportProperties = BdfDictionary.of(
|
private final BdfDictionary transportProperties = BdfDictionary.of(
|
||||||
new BdfEntry("transportId", new BdfDictionary())
|
new BdfEntry(transportId.getString(), new BdfDictionary())
|
||||||
);
|
);
|
||||||
|
private final Map<TransportId, TransportProperties> transportPropertiesMap =
|
||||||
|
singletonMap(transportId, new TransportProperties());
|
||||||
private final byte[] mac = getRandomBytes(MAC_BYTES);
|
private final byte[] mac = getRandomBytes(MAC_BYTES);
|
||||||
private final byte[] signature = getRandomBytes(MAX_SIGNATURE_BYTES);
|
private final byte[] signature = getRandomBytes(MAX_SIGNATURE_BYTES);
|
||||||
|
|
||||||
@@ -60,7 +72,7 @@ public class IntroductionValidatorTest extends ValidatorTestCase {
|
|||||||
authorList, text);
|
authorList, text);
|
||||||
|
|
||||||
expectParseAuthor(authorList, author);
|
expectParseAuthor(authorList, author);
|
||||||
expectEncodeRequestMetadata();
|
expectEncodeRequestMetadata(NO_AUTO_DELETE_TIMER);
|
||||||
BdfMessageContext messageContext =
|
BdfMessageContext messageContext =
|
||||||
validator.validateMessage(message, group, body);
|
validator.validateMessage(message, group, body);
|
||||||
|
|
||||||
@@ -72,7 +84,7 @@ public class IntroductionValidatorTest extends ValidatorTestCase {
|
|||||||
BdfList body = BdfList.of(REQUEST.getValue(), null, authorList, text);
|
BdfList body = BdfList.of(REQUEST.getValue(), null, authorList, text);
|
||||||
|
|
||||||
expectParseAuthor(authorList, author);
|
expectParseAuthor(authorList, author);
|
||||||
expectEncodeRequestMetadata();
|
expectEncodeRequestMetadata(NO_AUTO_DELETE_TIMER);
|
||||||
BdfMessageContext messageContext =
|
BdfMessageContext messageContext =
|
||||||
validator.validateMessage(message, group, body);
|
validator.validateMessage(message, group, body);
|
||||||
|
|
||||||
@@ -84,13 +96,42 @@ public class IntroductionValidatorTest extends ValidatorTestCase {
|
|||||||
BdfList body = BdfList.of(REQUEST.getValue(), null, authorList, null);
|
BdfList body = BdfList.of(REQUEST.getValue(), null, authorList, null);
|
||||||
|
|
||||||
expectParseAuthor(authorList, author);
|
expectParseAuthor(authorList, author);
|
||||||
expectEncodeRequestMetadata();
|
expectEncodeRequestMetadata(NO_AUTO_DELETE_TIMER);
|
||||||
BdfMessageContext messageContext =
|
BdfMessageContext messageContext =
|
||||||
validator.validateMessage(message, group, body);
|
validator.validateMessage(message, group, body);
|
||||||
|
|
||||||
assertExpectedContext(messageContext, null);
|
assertExpectedContext(messageContext, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testAcceptsRequestWithNullAutoDeleteTimer() throws Exception {
|
||||||
|
testAcceptsRequestWithAutoDeleteTimer(null);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testAcceptsRequestWithMinAutoDeleteTimer() throws Exception {
|
||||||
|
testAcceptsRequestWithAutoDeleteTimer(MIN_AUTO_DELETE_TIMER_MS);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testAcceptsRequestWithMaxAutoDeleteTimer() throws Exception {
|
||||||
|
testAcceptsRequestWithAutoDeleteTimer(MAX_AUTO_DELETE_TIMER_MS);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void testAcceptsRequestWithAutoDeleteTimer(@Nullable Long timer)
|
||||||
|
throws Exception {
|
||||||
|
BdfList body = BdfList.of(REQUEST.getValue(), previousMsgId.getBytes(),
|
||||||
|
authorList, text, timer);
|
||||||
|
|
||||||
|
expectParseAuthor(authorList, author);
|
||||||
|
long autoDeleteTimer = timer == null ? NO_AUTO_DELETE_TIMER : timer;
|
||||||
|
expectEncodeRequestMetadata(autoDeleteTimer);
|
||||||
|
BdfMessageContext messageContext =
|
||||||
|
validator.validateMessage(message, group, body);
|
||||||
|
|
||||||
|
assertExpectedContext(messageContext, previousMsgId);
|
||||||
|
}
|
||||||
|
|
||||||
@Test(expected = FormatException.class)
|
@Test(expected = FormatException.class)
|
||||||
public void testRejectsTooShortBodyForRequest() throws Exception {
|
public void testRejectsTooShortBodyForRequest() throws Exception {
|
||||||
BdfList body = BdfList.of(REQUEST.getValue(), null, authorList);
|
BdfList body = BdfList.of(REQUEST.getValue(), null, authorList);
|
||||||
@@ -99,8 +140,8 @@ public class IntroductionValidatorTest extends ValidatorTestCase {
|
|||||||
|
|
||||||
@Test(expected = FormatException.class)
|
@Test(expected = FormatException.class)
|
||||||
public void testRejectsTooLongBodyForRequest() throws Exception {
|
public void testRejectsTooLongBodyForRequest() throws Exception {
|
||||||
BdfList body =
|
BdfList body = BdfList.of(REQUEST.getValue(), null, authorList, text,
|
||||||
BdfList.of(REQUEST.getValue(), null, authorList, text, null);
|
null, null);
|
||||||
validator.validateMessage(message, group, body);
|
validator.validateMessage(message, group, body);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -119,6 +160,32 @@ public class IntroductionValidatorTest extends ValidatorTestCase {
|
|||||||
validator.validateMessage(message, group, body);
|
validator.validateMessage(message, group, body);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test(expected = FormatException.class)
|
||||||
|
public void testRejectsRequestWithNonLongAutoDeleteTimer()
|
||||||
|
throws Exception {
|
||||||
|
BdfList body = BdfList.of(REQUEST.getValue(), previousMsgId.getBytes(),
|
||||||
|
authorList, text, "foo");
|
||||||
|
expectParseAuthor(authorList, author);
|
||||||
|
validator.validateMessage(message, group, body);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test(expected = FormatException.class)
|
||||||
|
public void testRejectsRequestWithTooSmallAutoDeleteTimer()
|
||||||
|
throws Exception {
|
||||||
|
BdfList body = BdfList.of(REQUEST.getValue(), previousMsgId.getBytes(),
|
||||||
|
authorList, text, MIN_AUTO_DELETE_TIMER_MS - 1);
|
||||||
|
expectParseAuthor(authorList, author);
|
||||||
|
validator.validateMessage(message, group, body);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test(expected = FormatException.class)
|
||||||
|
public void testRejectsRequestWithTooBigAutoDeleteTimer() throws Exception {
|
||||||
|
BdfList body = BdfList.of(REQUEST.getValue(), previousMsgId.getBytes(),
|
||||||
|
authorList, text, MAX_AUTO_DELETE_TIMER_MS + 1);
|
||||||
|
expectParseAuthor(authorList, author);
|
||||||
|
validator.validateMessage(message, group, body);
|
||||||
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
// Introduction ACCEPT
|
// Introduction ACCEPT
|
||||||
//
|
//
|
||||||
@@ -129,11 +196,38 @@ public class IntroductionValidatorTest extends ValidatorTestCase {
|
|||||||
previousMsgId.getBytes(), ephemeralPublicKey.getEncoded(),
|
previousMsgId.getBytes(), ephemeralPublicKey.getEncoded(),
|
||||||
acceptTimestamp, transportProperties);
|
acceptTimestamp, transportProperties);
|
||||||
expectParsePublicKey();
|
expectParsePublicKey();
|
||||||
context.checking(new Expectations() {{
|
expectParseTransportProperties();
|
||||||
oneOf(clientHelper).parseAndValidateTransportPropertiesMap(
|
expectEncodeMetadata(ACCEPT, NO_AUTO_DELETE_TIMER);
|
||||||
transportProperties);
|
BdfMessageContext messageContext =
|
||||||
}});
|
validator.validateMessage(message, group, body);
|
||||||
expectEncodeMetadata(ACCEPT);
|
|
||||||
|
assertExpectedContext(messageContext, previousMsgId);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testAcceptsAcceptWithNullAutoDeleteTimer() throws Exception {
|
||||||
|
testAcceptsAcceptWithAutoDeleteTimer(null);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testAcceptsAcceptWithMinAutoDeleteTimer() throws Exception {
|
||||||
|
testAcceptsAcceptWithAutoDeleteTimer(MIN_AUTO_DELETE_TIMER_MS);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testAcceptsAcceptWithMaxAutoDeleteTimer() throws Exception {
|
||||||
|
testAcceptsAcceptWithAutoDeleteTimer(MAX_AUTO_DELETE_TIMER_MS);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void testAcceptsAcceptWithAutoDeleteTimer(@Nullable Long timer)
|
||||||
|
throws Exception {
|
||||||
|
BdfList body = BdfList.of(ACCEPT.getValue(), sessionId.getBytes(),
|
||||||
|
previousMsgId.getBytes(), ephemeralPublicKey.getEncoded(),
|
||||||
|
acceptTimestamp, transportProperties, timer);
|
||||||
|
expectParsePublicKey();
|
||||||
|
expectParseTransportProperties();
|
||||||
|
long autoDeleteTimer = timer == null ? NO_AUTO_DELETE_TIMER : timer;
|
||||||
|
expectEncodeMetadata(ACCEPT, autoDeleteTimer);
|
||||||
BdfMessageContext messageContext =
|
BdfMessageContext messageContext =
|
||||||
validator.validateMessage(message, group, body);
|
validator.validateMessage(message, group, body);
|
||||||
|
|
||||||
@@ -152,7 +246,7 @@ public class IntroductionValidatorTest extends ValidatorTestCase {
|
|||||||
public void testRejectsTooLongBodyForAccept() throws Exception {
|
public void testRejectsTooLongBodyForAccept() throws Exception {
|
||||||
BdfList body = BdfList.of(ACCEPT.getValue(), sessionId.getBytes(),
|
BdfList body = BdfList.of(ACCEPT.getValue(), sessionId.getBytes(),
|
||||||
previousMsgId.getBytes(), ephemeralPublicKey.getEncoded(),
|
previousMsgId.getBytes(), ephemeralPublicKey.getEncoded(),
|
||||||
acceptTimestamp, transportProperties, null);
|
acceptTimestamp, transportProperties, null, null);
|
||||||
validator.validateMessage(message, group, body);
|
validator.validateMessage(message, group, body);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -200,6 +294,40 @@ public class IntroductionValidatorTest extends ValidatorTestCase {
|
|||||||
validator.validateMessage(message, group, body);
|
validator.validateMessage(message, group, body);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test(expected = FormatException.class)
|
||||||
|
public void testRejectsAcceptWithNonLongAutoDeleteTimer()
|
||||||
|
throws Exception {
|
||||||
|
BdfList body = BdfList.of(ACCEPT.getValue(), sessionId.getBytes(),
|
||||||
|
previousMsgId.getBytes(), ephemeralPublicKey.getEncoded(),
|
||||||
|
acceptTimestamp, transportProperties, "foo");
|
||||||
|
expectParsePublicKey();
|
||||||
|
expectParseTransportProperties();
|
||||||
|
validator.validateMessage(message, group, body);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test(expected = FormatException.class)
|
||||||
|
public void testRejectsAcceptWithTooSmallAutoDeleteTimer()
|
||||||
|
throws Exception {
|
||||||
|
BdfList body = BdfList.of(ACCEPT.getValue(), sessionId.getBytes(),
|
||||||
|
previousMsgId.getBytes(), ephemeralPublicKey.getEncoded(),
|
||||||
|
acceptTimestamp, transportProperties,
|
||||||
|
MIN_AUTO_DELETE_TIMER_MS - 1);
|
||||||
|
expectParsePublicKey();
|
||||||
|
expectParseTransportProperties();
|
||||||
|
validator.validateMessage(message, group, body);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test(expected = FormatException.class)
|
||||||
|
public void testRejectsAcceptWithTooBigAutoDeleteTimer() throws Exception {
|
||||||
|
BdfList body = BdfList.of(ACCEPT.getValue(), sessionId.getBytes(),
|
||||||
|
previousMsgId.getBytes(), ephemeralPublicKey.getEncoded(),
|
||||||
|
acceptTimestamp, transportProperties,
|
||||||
|
MAX_AUTO_DELETE_TIMER_MS + 1);
|
||||||
|
expectParsePublicKey();
|
||||||
|
expectParseTransportProperties();
|
||||||
|
validator.validateMessage(message, group, body);
|
||||||
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
// Introduction DECLINE
|
// Introduction DECLINE
|
||||||
//
|
//
|
||||||
@@ -209,7 +337,35 @@ public class IntroductionValidatorTest extends ValidatorTestCase {
|
|||||||
BdfList body = BdfList.of(DECLINE.getValue(), sessionId.getBytes(),
|
BdfList body = BdfList.of(DECLINE.getValue(), sessionId.getBytes(),
|
||||||
previousMsgId.getBytes());
|
previousMsgId.getBytes());
|
||||||
|
|
||||||
expectEncodeMetadata(DECLINE);
|
expectEncodeMetadata(DECLINE, NO_AUTO_DELETE_TIMER);
|
||||||
|
BdfMessageContext messageContext =
|
||||||
|
validator.validateMessage(message, group, body);
|
||||||
|
|
||||||
|
assertExpectedContext(messageContext, previousMsgId);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testAcceptsDeclineWithNullAutoDeleteTimer() throws Exception {
|
||||||
|
testAcceptsDeclineWithAutoDeleteTimer(null);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testAcceptsDeclineWithMinAutoDeleteTimer() throws Exception {
|
||||||
|
testAcceptsDeclineWithAutoDeleteTimer(MIN_AUTO_DELETE_TIMER_MS);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testAcceptsDeclineWithMaxAutoDeleteTimer() throws Exception {
|
||||||
|
testAcceptsDeclineWithAutoDeleteTimer(MAX_AUTO_DELETE_TIMER_MS);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void testAcceptsDeclineWithAutoDeleteTimer(@Nullable Long timer)
|
||||||
|
throws Exception {
|
||||||
|
BdfList body = BdfList.of(DECLINE.getValue(), sessionId.getBytes(),
|
||||||
|
previousMsgId.getBytes(), timer);
|
||||||
|
|
||||||
|
long autoDeleteTimer = timer == null ? NO_AUTO_DELETE_TIMER : timer;
|
||||||
|
expectEncodeMetadata(DECLINE, autoDeleteTimer);
|
||||||
BdfMessageContext messageContext =
|
BdfMessageContext messageContext =
|
||||||
validator.validateMessage(message, group, body);
|
validator.validateMessage(message, group, body);
|
||||||
|
|
||||||
@@ -225,7 +381,7 @@ public class IntroductionValidatorTest extends ValidatorTestCase {
|
|||||||
@Test(expected = FormatException.class)
|
@Test(expected = FormatException.class)
|
||||||
public void testRejectsTooLongBodyForDecline() throws Exception {
|
public void testRejectsTooLongBodyForDecline() throws Exception {
|
||||||
BdfList body = BdfList.of(DECLINE.getValue(), sessionId.getBytes(),
|
BdfList body = BdfList.of(DECLINE.getValue(), sessionId.getBytes(),
|
||||||
previousMsgId.getBytes(), null);
|
previousMsgId.getBytes(), null, null);
|
||||||
validator.validateMessage(message, group, body);
|
validator.validateMessage(message, group, body);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -242,6 +398,28 @@ public class IntroductionValidatorTest extends ValidatorTestCase {
|
|||||||
validator.validateMessage(message, group, body);
|
validator.validateMessage(message, group, body);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test(expected = FormatException.class)
|
||||||
|
public void testRejectsNonLongAutoDeleteTimerForDecline() throws Exception {
|
||||||
|
BdfList body = BdfList.of(DECLINE.getValue(), sessionId.getBytes(),
|
||||||
|
previousMsgId.getBytes(), "foo");
|
||||||
|
validator.validateMessage(message, group, body);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test(expected = FormatException.class)
|
||||||
|
public void testRejectsTooSmallAutoDeleteTimerForDecline()
|
||||||
|
throws Exception {
|
||||||
|
BdfList body = BdfList.of(DECLINE.getValue(), sessionId.getBytes(),
|
||||||
|
previousMsgId.getBytes(), MIN_AUTO_DELETE_TIMER_MS - 1);
|
||||||
|
validator.validateMessage(message, group, body);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test(expected = FormatException.class)
|
||||||
|
public void testRejectsTooBigAutoDeleteTimerForDecline() throws Exception {
|
||||||
|
BdfList body = BdfList.of(DECLINE.getValue(), sessionId.getBytes(),
|
||||||
|
previousMsgId.getBytes(), MAX_AUTO_DELETE_TIMER_MS + 1);
|
||||||
|
validator.validateMessage(message, group, body);
|
||||||
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
// Introduction AUTH
|
// Introduction AUTH
|
||||||
//
|
//
|
||||||
@@ -251,7 +429,7 @@ public class IntroductionValidatorTest extends ValidatorTestCase {
|
|||||||
BdfList body = BdfList.of(AUTH.getValue(), sessionId.getBytes(),
|
BdfList body = BdfList.of(AUTH.getValue(), sessionId.getBytes(),
|
||||||
previousMsgId.getBytes(), mac, signature);
|
previousMsgId.getBytes(), mac, signature);
|
||||||
|
|
||||||
expectEncodeMetadata(AUTH);
|
expectEncodeMetadata(AUTH, NO_AUTO_DELETE_TIMER);
|
||||||
BdfMessageContext messageContext =
|
BdfMessageContext messageContext =
|
||||||
validator.validateMessage(message, group, body);
|
validator.validateMessage(message, group, body);
|
||||||
|
|
||||||
@@ -340,7 +518,7 @@ public class IntroductionValidatorTest extends ValidatorTestCase {
|
|||||||
BdfList body = BdfList.of(ACTIVATE.getValue(), sessionId.getBytes(),
|
BdfList body = BdfList.of(ACTIVATE.getValue(), sessionId.getBytes(),
|
||||||
previousMsgId.getBytes(), mac);
|
previousMsgId.getBytes(), mac);
|
||||||
|
|
||||||
expectEncodeMetadata(ACTIVATE);
|
expectEncodeMetadata(ACTIVATE, NO_AUTO_DELETE_TIMER);
|
||||||
BdfMessageContext messageContext =
|
BdfMessageContext messageContext =
|
||||||
validator.validateMessage(message, group, body);
|
validator.validateMessage(message, group, body);
|
||||||
|
|
||||||
@@ -398,7 +576,7 @@ public class IntroductionValidatorTest extends ValidatorTestCase {
|
|||||||
BdfList body = BdfList.of(ABORT.getValue(), sessionId.getBytes(),
|
BdfList body = BdfList.of(ABORT.getValue(), sessionId.getBytes(),
|
||||||
previousMsgId.getBytes());
|
previousMsgId.getBytes());
|
||||||
|
|
||||||
expectEncodeMetadata(ABORT);
|
expectEncodeMetadata(ABORT, NO_AUTO_DELETE_TIMER);
|
||||||
BdfMessageContext messageContext =
|
BdfMessageContext messageContext =
|
||||||
validator.validateMessage(message, group, body);
|
validator.validateMessage(message, group, body);
|
||||||
|
|
||||||
@@ -442,17 +620,28 @@ public class IntroductionValidatorTest extends ValidatorTestCase {
|
|||||||
will(returnValue(ephemeralPublicKey));
|
will(returnValue(ephemeralPublicKey));
|
||||||
}});
|
}});
|
||||||
}
|
}
|
||||||
private void expectEncodeRequestMetadata() {
|
|
||||||
|
private void expectParseTransportProperties() throws Exception {
|
||||||
context.checking(new Expectations() {{
|
context.checking(new Expectations() {{
|
||||||
oneOf(messageEncoder).encodeRequestMetadata(message.getTimestamp());
|
oneOf(clientHelper).parseAndValidateTransportPropertiesMap(
|
||||||
|
transportProperties);
|
||||||
|
will(returnValue(transportPropertiesMap));
|
||||||
|
}});
|
||||||
|
}
|
||||||
|
|
||||||
|
private void expectEncodeRequestMetadata(long autoDeleteTimer) {
|
||||||
|
context.checking(new Expectations() {{
|
||||||
|
oneOf(messageEncoder).encodeRequestMetadata(message.getTimestamp(),
|
||||||
|
autoDeleteTimer);
|
||||||
will(returnValue(meta));
|
will(returnValue(meta));
|
||||||
}});
|
}});
|
||||||
}
|
}
|
||||||
|
|
||||||
private void expectEncodeMetadata(MessageType type) {
|
private void expectEncodeMetadata(MessageType type, long autoDeleteTimer) {
|
||||||
context.checking(new Expectations() {{
|
context.checking(new Expectations() {{
|
||||||
oneOf(messageEncoder).encodeMetadata(type, sessionId,
|
oneOf(messageEncoder).encodeMetadata(type, sessionId,
|
||||||
message.getTimestamp(), false, false, false);
|
message.getTimestamp(), false, false, false,
|
||||||
|
autoDeleteTimer);
|
||||||
will(returnValue(meta));
|
will(returnValue(meta));
|
||||||
}});
|
}});
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -23,6 +23,8 @@ import java.util.Map;
|
|||||||
|
|
||||||
import javax.inject.Inject;
|
import javax.inject.Inject;
|
||||||
|
|
||||||
|
import static org.briarproject.bramble.api.autodelete.AutoDeleteConstants.MAX_AUTO_DELETE_TIMER_MS;
|
||||||
|
import static org.briarproject.bramble.api.autodelete.AutoDeleteConstants.MIN_AUTO_DELETE_TIMER_MS;
|
||||||
import static org.briarproject.bramble.api.crypto.CryptoConstants.MAC_BYTES;
|
import static org.briarproject.bramble.api.crypto.CryptoConstants.MAC_BYTES;
|
||||||
import static org.briarproject.bramble.api.crypto.CryptoConstants.MAX_SIGNATURE_BYTES;
|
import static org.briarproject.bramble.api.crypto.CryptoConstants.MAX_SIGNATURE_BYTES;
|
||||||
import static org.briarproject.bramble.test.TestUtils.getAgreementPublicKey;
|
import static org.briarproject.bramble.test.TestUtils.getAgreementPublicKey;
|
||||||
@@ -88,7 +90,7 @@ public class MessageEncoderParserIntegrationTest extends BrambleTestCase {
|
|||||||
@Test
|
@Test
|
||||||
public void testRequestMessageMetadata() throws FormatException {
|
public void testRequestMessageMetadata() throws FormatException {
|
||||||
BdfDictionary d = messageEncoder
|
BdfDictionary d = messageEncoder
|
||||||
.encodeRequestMetadata(timestamp);
|
.encodeRequestMetadata(timestamp, MIN_AUTO_DELETE_TIMER_MS);
|
||||||
MessageMetadata meta = messageParser.parseMetadata(d);
|
MessageMetadata meta = messageParser.parseMetadata(d);
|
||||||
|
|
||||||
assertEquals(REQUEST, meta.getMessageType());
|
assertEquals(REQUEST, meta.getMessageType());
|
||||||
@@ -98,13 +100,14 @@ public class MessageEncoderParserIntegrationTest extends BrambleTestCase {
|
|||||||
assertFalse(meta.isRead());
|
assertFalse(meta.isRead());
|
||||||
assertFalse(meta.isVisibleInConversation());
|
assertFalse(meta.isVisibleInConversation());
|
||||||
assertFalse(meta.isAvailableToAnswer());
|
assertFalse(meta.isAvailableToAnswer());
|
||||||
|
assertEquals(MIN_AUTO_DELETE_TIMER_MS, meta.getAutoDeleteTimer());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testMessageMetadata() throws FormatException {
|
public void testMessageMetadata() throws FormatException {
|
||||||
BdfDictionary d = messageEncoder
|
BdfDictionary d = messageEncoder
|
||||||
.encodeMetadata(ABORT, sessionId, timestamp, false, true,
|
.encodeMetadata(ABORT, sessionId, timestamp, false, true,
|
||||||
false);
|
false, MAX_AUTO_DELETE_TIMER_MS);
|
||||||
MessageMetadata meta = messageParser.parseMetadata(d);
|
MessageMetadata meta = messageParser.parseMetadata(d);
|
||||||
|
|
||||||
assertEquals(ABORT, meta.getMessageType());
|
assertEquals(ABORT, meta.getMessageType());
|
||||||
@@ -114,6 +117,7 @@ public class MessageEncoderParserIntegrationTest extends BrambleTestCase {
|
|||||||
assertTrue(meta.isRead());
|
assertTrue(meta.isRead());
|
||||||
assertFalse(meta.isVisibleInConversation());
|
assertFalse(meta.isVisibleInConversation());
|
||||||
assertFalse(meta.isAvailableToAnswer());
|
assertFalse(meta.isAvailableToAnswer());
|
||||||
|
assertEquals(MAX_AUTO_DELETE_TIMER_MS, meta.getAutoDeleteTimer());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
|||||||
Reference in New Issue
Block a user