mirror of
https://code.briarproject.org/briar/briar.git
synced 2026-02-13 11:19:04 +01:00
Add an IntroductionManager and Validator
This Introduction BSP Client uses its own group to communicate with existing contacts. It uses four types of messages to facilitate introductions: the introduction, the response, the ack and the abort. The protocol logic is encapsulated in two protocol engines, one for the introducer and one for the introducee. The introduction client keeps the local state for each engine, hands messages over to the engines and processes the result and state changes they return.
This commit is contained in:
31
briar-api/src/org/briarproject/api/ProtocolEngine.java
Normal file
31
briar-api/src/org/briarproject/api/ProtocolEngine.java
Normal file
@@ -0,0 +1,31 @@
|
||||
package org.briarproject.api;
|
||||
|
||||
import org.briarproject.api.event.Event;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public interface ProtocolEngine<A, S, M> {
|
||||
StateUpdate<S, M> onLocalAction(S localState, A action);
|
||||
|
||||
StateUpdate<S, M> onMessageReceived(S localState, M received);
|
||||
|
||||
StateUpdate<S, M> onMessageDelivered(S localState, M delivered);
|
||||
|
||||
class StateUpdate<S, M> {
|
||||
public final boolean deleteMessages;
|
||||
public final boolean deleteState;
|
||||
public final S localState;
|
||||
public final List<M> toSend;
|
||||
public final List<Event> toBroadcast;
|
||||
|
||||
public StateUpdate(boolean deleteMessages, boolean deleteState,
|
||||
S localState, List<M> toSend, List<Event> toBroadcast) {
|
||||
|
||||
this.deleteMessages = deleteMessages;
|
||||
this.deleteState = deleteState;
|
||||
this.localState = localState;
|
||||
this.toSend = toSend;
|
||||
this.toBroadcast = toBroadcast;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -5,7 +5,6 @@ import org.briarproject.api.db.DbException;
|
||||
import org.briarproject.api.db.Transaction;
|
||||
import org.briarproject.api.identity.Author;
|
||||
import org.briarproject.api.identity.AuthorId;
|
||||
import org.briarproject.api.identity.LocalAuthor;
|
||||
|
||||
import java.util.Collection;
|
||||
|
||||
|
||||
@@ -0,0 +1,26 @@
|
||||
package org.briarproject.api.event;
|
||||
|
||||
import org.briarproject.api.contact.ContactId;
|
||||
import org.briarproject.api.introduction.IntroductionRequest;
|
||||
|
||||
public class IntroductionRequestReceivedEvent extends Event {
|
||||
|
||||
private final ContactId contactId;
|
||||
private final IntroductionRequest introductionRequest;
|
||||
|
||||
public IntroductionRequestReceivedEvent(ContactId contactId,
|
||||
IntroductionRequest introductionRequest) {
|
||||
|
||||
this.contactId = contactId;
|
||||
this.introductionRequest = introductionRequest;
|
||||
}
|
||||
|
||||
public ContactId getContactId() {
|
||||
return contactId;
|
||||
}
|
||||
|
||||
public IntroductionRequest getIntroductionRequest() {
|
||||
return introductionRequest;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
package org.briarproject.api.event;
|
||||
|
||||
import org.briarproject.api.contact.ContactId;
|
||||
import org.briarproject.api.introduction.IntroductionResponse;
|
||||
|
||||
public class IntroductionResponseReceivedEvent extends Event {
|
||||
|
||||
private final ContactId contactId;
|
||||
private final IntroductionResponse introductionResponse;
|
||||
|
||||
public IntroductionResponseReceivedEvent(ContactId contactId,
|
||||
IntroductionResponse introductionResponse) {
|
||||
|
||||
this.contactId = contactId;
|
||||
this.introductionResponse = introductionResponse;
|
||||
}
|
||||
|
||||
public ContactId getContactId() {
|
||||
return contactId;
|
||||
}
|
||||
|
||||
public IntroductionResponse getIntroductionResponse() {
|
||||
return introductionResponse;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
package org.briarproject.api.event;
|
||||
|
||||
import org.briarproject.api.contact.Contact;
|
||||
|
||||
public class IntroductionSucceededEvent extends Event {
|
||||
|
||||
private final Contact contact;
|
||||
|
||||
public IntroductionSucceededEvent(Contact contact) {
|
||||
this.contact = contact;
|
||||
}
|
||||
|
||||
public Contact getContact() {
|
||||
return contact;
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,6 @@
|
||||
package org.briarproject.api.event;
|
||||
|
||||
import org.briarproject.api.db.Metadata;
|
||||
import org.briarproject.api.sync.ClientId;
|
||||
import org.briarproject.api.sync.Message;
|
||||
|
||||
|
||||
@@ -0,0 +1,43 @@
|
||||
package org.briarproject.api.introduction;
|
||||
|
||||
import static org.briarproject.api.introduction.IntroductionConstants.TYPE_ABORT;
|
||||
import static org.briarproject.api.introduction.IntroductionConstants.TYPE_ACK;
|
||||
import static org.briarproject.api.introduction.IntroductionConstants.TYPE_REQUEST;
|
||||
import static org.briarproject.api.introduction.IntroductionConstants.TYPE_RESPONSE;
|
||||
|
||||
public enum IntroduceeAction {
|
||||
|
||||
LOCAL_ACCEPT,
|
||||
LOCAL_DECLINE,
|
||||
LOCAL_ABORT,
|
||||
REMOTE_REQUEST,
|
||||
REMOTE_ACCEPT,
|
||||
REMOTE_DECLINE,
|
||||
REMOTE_ABORT,
|
||||
ACK;
|
||||
|
||||
public static IntroduceeAction getRemote(int type, boolean accept) {
|
||||
if (type == TYPE_REQUEST) return REMOTE_REQUEST;
|
||||
if (type == TYPE_RESPONSE && accept) return REMOTE_ACCEPT;
|
||||
if (type == TYPE_RESPONSE) return REMOTE_DECLINE;
|
||||
if (type == TYPE_ACK) return ACK;
|
||||
if (type == TYPE_ABORT) return REMOTE_ABORT;
|
||||
return null;
|
||||
}
|
||||
|
||||
public static IntroduceeAction getRemote(int type) {
|
||||
return getRemote(type, true);
|
||||
}
|
||||
|
||||
public static IntroduceeAction getLocal(int type, boolean accept) {
|
||||
if (type == TYPE_RESPONSE && accept) return LOCAL_ACCEPT;
|
||||
if (type == TYPE_RESPONSE) return LOCAL_DECLINE;
|
||||
if (type == TYPE_ABORT) return LOCAL_ABORT;
|
||||
return null;
|
||||
}
|
||||
|
||||
public static IntroduceeAction getLocal(int type) {
|
||||
return getLocal(type, true);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,76 @@
|
||||
package org.briarproject.api.introduction;
|
||||
|
||||
import static org.briarproject.api.introduction.IntroduceeAction.ACK;
|
||||
import static org.briarproject.api.introduction.IntroduceeAction.LOCAL_ACCEPT;
|
||||
import static org.briarproject.api.introduction.IntroduceeAction.LOCAL_DECLINE;
|
||||
import static org.briarproject.api.introduction.IntroduceeAction.REMOTE_ACCEPT;
|
||||
import static org.briarproject.api.introduction.IntroduceeAction.REMOTE_DECLINE;
|
||||
import static org.briarproject.api.introduction.IntroduceeAction.REMOTE_REQUEST;
|
||||
|
||||
public enum IntroduceeProtocolState {
|
||||
|
||||
ERROR(0),
|
||||
AWAIT_REQUEST(1) {
|
||||
@Override
|
||||
public IntroduceeProtocolState next(IntroduceeAction a) {
|
||||
if (a == REMOTE_REQUEST) return AWAIT_RESPONSES;
|
||||
return ERROR;
|
||||
}
|
||||
},
|
||||
AWAIT_RESPONSES(2) {
|
||||
@Override
|
||||
public IntroduceeProtocolState next(IntroduceeAction a) {
|
||||
if (a == REMOTE_ACCEPT) return AWAIT_LOCAL_RESPONSE;
|
||||
if (a == REMOTE_DECLINE) return FINISHED;
|
||||
if (a == LOCAL_ACCEPT) return AWAIT_REMOTE_RESPONSE;
|
||||
if (a == LOCAL_DECLINE) return FINISHED;
|
||||
return ERROR;
|
||||
}
|
||||
},
|
||||
AWAIT_REMOTE_RESPONSE(3) {
|
||||
@Override
|
||||
public IntroduceeProtocolState next(IntroduceeAction a) {
|
||||
if (a == REMOTE_ACCEPT) return AWAIT_ACK;
|
||||
if (a == REMOTE_DECLINE) return FINISHED;
|
||||
return ERROR;
|
||||
}
|
||||
},
|
||||
AWAIT_LOCAL_RESPONSE(4) {
|
||||
@Override
|
||||
public IntroduceeProtocolState next(IntroduceeAction a) {
|
||||
if (a == LOCAL_ACCEPT) return AWAIT_ACK;
|
||||
if (a == LOCAL_DECLINE) return FINISHED;
|
||||
return ERROR;
|
||||
}
|
||||
},
|
||||
AWAIT_ACK(5) {
|
||||
@Override
|
||||
public IntroduceeProtocolState next(IntroduceeAction a) {
|
||||
if (a == ACK) return FINISHED;
|
||||
return ERROR;
|
||||
}
|
||||
},
|
||||
FINISHED(6);
|
||||
|
||||
private final int value;
|
||||
|
||||
IntroduceeProtocolState(int value) {
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
public int getValue() {
|
||||
return value;
|
||||
}
|
||||
|
||||
public static IntroduceeProtocolState fromValue(int value) {
|
||||
for (IntroduceeProtocolState s : values()) {
|
||||
if (s.value == value) return s;
|
||||
}
|
||||
throw new IllegalArgumentException();
|
||||
}
|
||||
|
||||
public IntroduceeProtocolState next(IntroduceeAction a) {
|
||||
return this;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,46 @@
|
||||
package org.briarproject.api.introduction;
|
||||
|
||||
import static org.briarproject.api.introduction.IntroductionConstants.TYPE_ABORT;
|
||||
import static org.briarproject.api.introduction.IntroductionConstants.TYPE_ACK;
|
||||
import static org.briarproject.api.introduction.IntroductionConstants.TYPE_REQUEST;
|
||||
import static org.briarproject.api.introduction.IntroductionConstants.TYPE_RESPONSE;
|
||||
|
||||
public enum IntroducerAction {
|
||||
|
||||
LOCAL_REQUEST,
|
||||
LOCAL_ABORT,
|
||||
REMOTE_ACCEPT_1,
|
||||
REMOTE_ACCEPT_2,
|
||||
REMOTE_DECLINE_1,
|
||||
REMOTE_DECLINE_2,
|
||||
REMOTE_ABORT,
|
||||
ACK_1,
|
||||
ACK_2;
|
||||
|
||||
public static IntroducerAction getLocal(int type) {
|
||||
if (type == TYPE_REQUEST) return LOCAL_REQUEST;
|
||||
if (type == TYPE_ABORT) return LOCAL_ABORT;
|
||||
return null;
|
||||
}
|
||||
|
||||
public static IntroducerAction getRemote(int type, boolean one,
|
||||
boolean accept) {
|
||||
|
||||
if (one) {
|
||||
if (type == TYPE_RESPONSE && accept) return REMOTE_ACCEPT_1;
|
||||
if (type == TYPE_RESPONSE) return REMOTE_DECLINE_1;
|
||||
if (type == TYPE_ACK) return ACK_1;
|
||||
} else {
|
||||
if (type == TYPE_RESPONSE && accept) return REMOTE_ACCEPT_2;
|
||||
if (type == TYPE_RESPONSE) return REMOTE_DECLINE_2;
|
||||
if (type == TYPE_ACK) return ACK_2;
|
||||
}
|
||||
if (type == TYPE_ABORT) return REMOTE_ABORT;
|
||||
return null;
|
||||
}
|
||||
|
||||
public static IntroducerAction getRemote(int type, boolean one) {
|
||||
return getRemote(type, one, true);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,94 @@
|
||||
package org.briarproject.api.introduction;
|
||||
|
||||
import static org.briarproject.api.introduction.IntroducerAction.ACK_1;
|
||||
import static org.briarproject.api.introduction.IntroducerAction.ACK_2;
|
||||
import static org.briarproject.api.introduction.IntroducerAction.LOCAL_REQUEST;
|
||||
import static org.briarproject.api.introduction.IntroducerAction.REMOTE_ACCEPT_1;
|
||||
import static org.briarproject.api.introduction.IntroducerAction.REMOTE_ACCEPT_2;
|
||||
import static org.briarproject.api.introduction.IntroducerAction.REMOTE_DECLINE_1;
|
||||
import static org.briarproject.api.introduction.IntroducerAction.REMOTE_DECLINE_2;
|
||||
|
||||
public enum IntroducerProtocolState {
|
||||
|
||||
ERROR(0),
|
||||
PREPARE_REQUESTS(1) {
|
||||
@Override
|
||||
public IntroducerProtocolState next(IntroducerAction a) {
|
||||
if (a == LOCAL_REQUEST) return AWAIT_RESPONSES;
|
||||
return ERROR;
|
||||
}
|
||||
},
|
||||
AWAIT_RESPONSES(2) {
|
||||
@Override
|
||||
public IntroducerProtocolState next(IntroducerAction a) {
|
||||
if (a == REMOTE_ACCEPT_1) return AWAIT_RESPONSE_2;
|
||||
if (a == REMOTE_ACCEPT_2) return AWAIT_RESPONSE_1;
|
||||
if (a == REMOTE_DECLINE_1) return FINISHED;
|
||||
if (a == REMOTE_DECLINE_2) return FINISHED;
|
||||
return ERROR;
|
||||
}
|
||||
},
|
||||
AWAIT_RESPONSE_1(3) {
|
||||
public IntroducerProtocolState next(IntroducerAction a) {
|
||||
if (a == REMOTE_ACCEPT_1) return AWAIT_ACKS;
|
||||
if (a == REMOTE_DECLINE_1) return FINISHED;
|
||||
return ERROR;
|
||||
}
|
||||
},
|
||||
AWAIT_RESPONSE_2(4) {
|
||||
@Override
|
||||
public IntroducerProtocolState next(IntroducerAction a) {
|
||||
if (a == REMOTE_ACCEPT_2) return AWAIT_ACKS;
|
||||
if (a == REMOTE_DECLINE_2) return FINISHED;
|
||||
return ERROR;
|
||||
}
|
||||
},
|
||||
AWAIT_ACKS(5) {
|
||||
@Override
|
||||
public IntroducerProtocolState next(IntroducerAction a) {
|
||||
if (a == ACK_1) return AWAIT_ACK_2;
|
||||
if (a == ACK_2) return AWAIT_ACK_1;
|
||||
return ERROR;
|
||||
}
|
||||
},
|
||||
AWAIT_ACK_1(6) {
|
||||
@Override
|
||||
public IntroducerProtocolState next(IntroducerAction a) {
|
||||
if (a == ACK_1) return FINISHED;
|
||||
return ERROR;
|
||||
}
|
||||
},
|
||||
AWAIT_ACK_2(7) {
|
||||
@Override
|
||||
public IntroducerProtocolState next(IntroducerAction a) {
|
||||
if (a == ACK_2) return FINISHED;
|
||||
return ERROR;
|
||||
}
|
||||
},
|
||||
FINISHED(8);
|
||||
|
||||
private final int value;
|
||||
|
||||
IntroducerProtocolState(int value) {
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
public int getValue() {
|
||||
return value;
|
||||
}
|
||||
|
||||
public static IntroducerProtocolState fromValue(int value) {
|
||||
for (IntroducerProtocolState s : values()) {
|
||||
if (s.value == value) return s;
|
||||
}
|
||||
throw new IllegalArgumentException();
|
||||
}
|
||||
|
||||
public static boolean isOngoing(IntroducerProtocolState state) {
|
||||
return state != FINISHED && state != ERROR;
|
||||
}
|
||||
|
||||
public IntroducerProtocolState next(IntroducerAction a) {
|
||||
return this;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,68 @@
|
||||
package org.briarproject.api.introduction;
|
||||
|
||||
public interface IntroductionConstants {
|
||||
|
||||
/* Protocol roles */
|
||||
int ROLE_INTRODUCER = 0;
|
||||
int ROLE_INTRODUCEE = 1;
|
||||
|
||||
/* Message types */
|
||||
int TYPE_REQUEST = 1;
|
||||
int TYPE_RESPONSE = 2;
|
||||
int TYPE_ACK = 3;
|
||||
int TYPE_ABORT = 4;
|
||||
|
||||
/* Message Constants */
|
||||
String TYPE = "type";
|
||||
String GROUP_ID = "groupId";
|
||||
String SESSION_ID = "sessionId";
|
||||
String CONTACT = "contactId";
|
||||
String NAME = "name";
|
||||
String PUBLIC_KEY = "publicKey";
|
||||
String E_PUBLIC_KEY = "ephemeralPublicKey";
|
||||
String MSG = "msg";
|
||||
String ACCEPT = "accept";
|
||||
String TIME = "time";
|
||||
String DEVICE_ID = "deviceId";
|
||||
String TRANSPORT = "transport";
|
||||
String MESSAGE_ID = "messageId";
|
||||
String MESSAGE_TIME = "timestamp";
|
||||
|
||||
/* Introducer Local State Metadata */
|
||||
String STATE = "state";
|
||||
String ROLE = "role";
|
||||
String GROUP_ID_1 = "groupId1";
|
||||
String GROUP_ID_2 = "groupId2";
|
||||
String CONTACT_1 = "contact1";
|
||||
String CONTACT_2 = "contact2";
|
||||
String AUTHOR_ID_1 = "authorId1";
|
||||
String AUTHOR_ID_2 = "authorId2";
|
||||
String CONTACT_ID_1 = "contactId1";
|
||||
String CONTACT_ID_2 = "contactId2";
|
||||
String RESPONSE_1 = "response1";
|
||||
String RESPONSE_2 = "response2";
|
||||
String READ = "read";
|
||||
|
||||
/* Introduction Request Action */
|
||||
String PUBLIC_KEY1 = "publicKey1";
|
||||
String PUBLIC_KEY2 = "publicKey2";
|
||||
|
||||
/* Introducee Local State Metadata (without those already defined) */
|
||||
String STORAGE_ID = "storageId";
|
||||
String INTRODUCER = "introducer";
|
||||
String LOCAL_AUTHOR_ID = "localAuthorId";
|
||||
String REMOTE_AUTHOR_ID = "remoteAuthorId";
|
||||
String OUR_PUBLIC_KEY = "ourEphemeralPublicKey";
|
||||
String OUR_PRIVATE_KEY = "ourEphemeralPrivateKey";
|
||||
String OUR_TIME = "ourTime";
|
||||
String ADDED_CONTACT_ID = "addedContactId";
|
||||
String NOT_OUR_RESPONSE = "notOurResponse";
|
||||
String EXISTS = "contactExists";
|
||||
String ANSWERED = "answered";
|
||||
|
||||
String TASK = "task";
|
||||
int TASK_ADD_CONTACT = 0;
|
||||
int TASK_ACTIVATE_CONTACT = 1;
|
||||
int TASK_ABORT = 2;
|
||||
|
||||
}
|
||||
@@ -0,0 +1,62 @@
|
||||
package org.briarproject.api.introduction;
|
||||
|
||||
import org.briarproject.api.FormatException;
|
||||
import org.briarproject.api.contact.Contact;
|
||||
import org.briarproject.api.contact.ContactId;
|
||||
import org.briarproject.api.data.BdfDictionary;
|
||||
import org.briarproject.api.db.DbException;
|
||||
import org.briarproject.api.db.Transaction;
|
||||
import org.briarproject.api.sync.ClientId;
|
||||
import org.briarproject.api.sync.Group;
|
||||
import org.briarproject.api.sync.MessageId;
|
||||
|
||||
import java.util.Collection;
|
||||
|
||||
public interface IntroductionManager {
|
||||
|
||||
/** Returns the unique ID of the introduction client. */
|
||||
ClientId getClientId();
|
||||
|
||||
/**
|
||||
* sends two initial introduction messages
|
||||
*/
|
||||
void makeIntroduction(Contact c1, Contact c2, String msg)
|
||||
throws DbException, FormatException;
|
||||
|
||||
/**
|
||||
* Accept an introduction that had been made
|
||||
*/
|
||||
void acceptIntroduction(final SessionId sessionId)
|
||||
throws DbException, FormatException;
|
||||
|
||||
/**
|
||||
* Decline an introduction that had been made
|
||||
*/
|
||||
void declineIntroduction(final SessionId sessionId)
|
||||
throws DbException, FormatException;
|
||||
|
||||
/**
|
||||
* Get all introduction messages for the contact with this contactId
|
||||
*/
|
||||
Collection<IntroductionMessage> getIntroductionMessages(ContactId contactId)
|
||||
throws DbException;
|
||||
|
||||
/** Marks an introduction message as read or unread. */
|
||||
void setReadFlag(MessageId m, boolean read) throws DbException;
|
||||
|
||||
|
||||
/** Get the session state for the given session ID */
|
||||
BdfDictionary getSessionState(Transaction txn, byte[] sessionId)
|
||||
throws DbException, FormatException;
|
||||
|
||||
/** Gets the group used for introductions with Contact c */
|
||||
Group getIntroductionGroup(Contact c);
|
||||
|
||||
/** Get the local group used to store session states */
|
||||
Group getLocalGroup();
|
||||
|
||||
/** Send an introduction message */
|
||||
void sendMessage(Transaction txn, BdfDictionary message)
|
||||
throws DbException, FormatException;
|
||||
|
||||
}
|
||||
@@ -0,0 +1,54 @@
|
||||
package org.briarproject.api.introduction;
|
||||
|
||||
import org.briarproject.api.sync.MessageId;
|
||||
|
||||
abstract public class IntroductionMessage {
|
||||
|
||||
private final SessionId sessionId;
|
||||
private final MessageId messageId;
|
||||
private final long time;
|
||||
private final boolean local, sent, seen, read;
|
||||
|
||||
public IntroductionMessage(SessionId sessionId, MessageId messageId,
|
||||
long time, boolean local, boolean sent, boolean seen,
|
||||
boolean read) {
|
||||
|
||||
this.sessionId = sessionId;
|
||||
this.messageId = messageId;
|
||||
this.time = time;
|
||||
this.local = local;
|
||||
this.sent = sent;
|
||||
this.seen = seen;
|
||||
this.read = read;
|
||||
}
|
||||
|
||||
public SessionId getSessionId() {
|
||||
return sessionId;
|
||||
}
|
||||
|
||||
public long getTime() {
|
||||
return time;
|
||||
}
|
||||
|
||||
public MessageId getMessageId() {
|
||||
return messageId;
|
||||
}
|
||||
|
||||
public boolean isLocal() {
|
||||
return local;
|
||||
}
|
||||
|
||||
public boolean isSent() {
|
||||
return sent;
|
||||
}
|
||||
|
||||
public boolean isSeen() {
|
||||
return seen;
|
||||
}
|
||||
|
||||
public boolean isRead() {
|
||||
return read;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,36 @@
|
||||
package org.briarproject.api.introduction;
|
||||
|
||||
import org.briarproject.api.identity.AuthorId;
|
||||
import org.briarproject.api.sync.MessageId;
|
||||
|
||||
public class IntroductionRequest extends IntroductionResponse {
|
||||
|
||||
private final String message;
|
||||
private final boolean answered, exists;
|
||||
|
||||
public IntroductionRequest(SessionId sessionId, MessageId messageId,
|
||||
long time, boolean local, boolean sent, boolean seen, boolean read,
|
||||
AuthorId authorId, String name, boolean accepted, String message,
|
||||
boolean answered, boolean exists) {
|
||||
|
||||
super(sessionId, messageId, time, local, sent, seen, read, authorId,
|
||||
name, accepted);
|
||||
|
||||
this.message = message;
|
||||
this.answered = answered;
|
||||
this.exists = exists;
|
||||
}
|
||||
|
||||
public String getMessage() {
|
||||
return message;
|
||||
}
|
||||
|
||||
public boolean wasAnswered() {
|
||||
return answered;
|
||||
}
|
||||
|
||||
public boolean doesExist() {
|
||||
return exists;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
package org.briarproject.api.introduction;
|
||||
|
||||
import org.briarproject.api.identity.AuthorId;
|
||||
import org.briarproject.api.sync.MessageId;
|
||||
|
||||
public class IntroductionResponse extends IntroductionMessage {
|
||||
|
||||
private final AuthorId remoteAuthorId;
|
||||
private final String name;
|
||||
private final boolean accepted;
|
||||
|
||||
public IntroductionResponse(SessionId sessionId, MessageId messageId,
|
||||
long time, boolean local, boolean sent, boolean seen, boolean read,
|
||||
AuthorId remoteAuthorId, String name, boolean accepted) {
|
||||
|
||||
super(sessionId, messageId, time, local, sent, seen, read);
|
||||
|
||||
this.remoteAuthorId = remoteAuthorId;
|
||||
this.name = name;
|
||||
this.accepted = accepted;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public boolean wasAccepted() {
|
||||
return accepted;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
package org.briarproject.api.introduction;
|
||||
|
||||
import org.briarproject.api.sync.MessageId;
|
||||
|
||||
/**
|
||||
* Type-safe wrapper for a byte array that uniquely identifies an
|
||||
* introduction session.
|
||||
*/
|
||||
public class SessionId extends MessageId {
|
||||
|
||||
public SessionId(byte[] id) {
|
||||
super(id);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
return o instanceof SessionId && super.equals(o);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user