Show alias for introduction notices in private conversation

parent cdbe2a00
...@@ -10,7 +10,11 @@ import javax.annotation.concurrent.Immutable; ...@@ -10,7 +10,11 @@ import javax.annotation.concurrent.Immutable;
public class AuthorInfo { public class AuthorInfo {
public enum Status { public enum Status {
NONE, ANONYMOUS, UNKNOWN, UNVERIFIED, VERIFIED, OURSELVES NONE, ANONYMOUS, UNKNOWN, UNVERIFIED, VERIFIED, OURSELVES;
public boolean isContact() {
return this == UNVERIFIED || this == VERIFIED;
}
} }
private final Status status; private final Status status;
......
...@@ -24,6 +24,7 @@ import static org.briarproject.briar.android.contact.ConversationRequestItem.Req ...@@ -24,6 +24,7 @@ import static org.briarproject.briar.android.contact.ConversationRequestItem.Req
import static org.briarproject.briar.android.contact.ConversationRequestItem.RequestType.FORUM; import static org.briarproject.briar.android.contact.ConversationRequestItem.RequestType.FORUM;
import static org.briarproject.briar.android.contact.ConversationRequestItem.RequestType.GROUP; import static org.briarproject.briar.android.contact.ConversationRequestItem.RequestType.GROUP;
import static org.briarproject.briar.android.contact.ConversationRequestItem.RequestType.INTRODUCTION; import static org.briarproject.briar.android.contact.ConversationRequestItem.RequestType.INTRODUCTION;
import static org.briarproject.briar.android.util.UiUtils.getContactDisplayName;
@UiThread @UiThread
@NotNullByDefault @NotNullByDefault
...@@ -188,33 +189,36 @@ class ConversationVisitor implements PrivateMessageVisitor<ConversationItem> { ...@@ -188,33 +189,36 @@ class ConversationVisitor implements PrivateMessageVisitor<ConversationItem> {
@Override @Override
public ConversationItem visitIntroductionRequest(IntroductionRequest r) { public ConversationItem visitIntroductionRequest(IntroductionRequest r) {
String name = getContactDisplayName(r.getNameable(), r.getAlias());
if (r.isLocal()) { if (r.isLocal()) {
String text = ctx.getString(R.string.introduction_request_sent, String text = ctx.getString(R.string.introduction_request_sent,
contactName.getValue(), r.getName()); contactName.getValue(), name);
return new ConversationNoticeOutItem(text, r); return new ConversationNoticeOutItem(text, r);
} else { } else {
String text = ctx.getString(R.string.introduction_request_received, String text = ctx.getString(R.string.introduction_request_received,
contactName.getValue(), r.getName()); contactName.getValue(), name);
return new ConversationRequestItem(text, INTRODUCTION, r); return new ConversationRequestItem(text, INTRODUCTION, r);
} }
} }
@Override @Override
public ConversationItem visitIntroductionResponse(IntroductionResponse r) { public ConversationItem visitIntroductionResponse(IntroductionResponse r) {
String introducedAuthor =
getContactDisplayName(r.getIntroducedAuthor(),
r.getIntroducedAuthorInfo().getAlias());
if (r.isLocal()) { if (r.isLocal()) {
String text; String text;
if (r.wasAccepted()) { if (r.wasAccepted()) {
String introducee = r.getIntroducedAuthor().getName();
text = ctx.getString( text = ctx.getString(
R.string.introduction_response_accepted_sent, R.string.introduction_response_accepted_sent,
introducee) introducedAuthor)
+ "\n\n" + ctx.getString( + "\n\n" + ctx.getString(
R.string.introduction_response_accepted_sent_info, R.string.introduction_response_accepted_sent_info,
introducee); introducedAuthor);
} else { } else {
text = ctx.getString( text = ctx.getString(
R.string.introduction_response_declined_sent, R.string.introduction_response_declined_sent,
r.getIntroducedAuthor().getName()); introducedAuthor);
} }
return new ConversationNoticeOutItem(text, r); return new ConversationNoticeOutItem(text, r);
} else { } else {
...@@ -223,17 +227,17 @@ class ConversationVisitor implements PrivateMessageVisitor<ConversationItem> { ...@@ -223,17 +227,17 @@ class ConversationVisitor implements PrivateMessageVisitor<ConversationItem> {
text = ctx.getString( text = ctx.getString(
R.string.introduction_response_accepted_received, R.string.introduction_response_accepted_received,
contactName.getValue(), contactName.getValue(),
r.getIntroducedAuthor().getName()); introducedAuthor);
} else if (r.isIntroducer()) { } else if (r.isIntroducer()) {
text = ctx.getString( text = ctx.getString(
R.string.introduction_response_declined_received, R.string.introduction_response_declined_received,
contactName.getValue(), contactName.getValue(),
r.getIntroducedAuthor().getName()); introducedAuthor);
} else { } else {
text = ctx.getString( text = ctx.getString(
R.string.introduction_response_declined_received_by_introducee, R.string.introduction_response_declined_received_by_introducee,
contactName.getValue(), contactName.getValue(),
r.getIntroducedAuthor().getName()); introducedAuthor);
} }
return new ConversationNoticeInItem(text, r); return new ConversationNoticeInItem(text, r);
} }
......
package org.briarproject.briar.api.introduction; package org.briarproject.briar.api.introduction;
import org.briarproject.bramble.api.identity.Author; import org.briarproject.bramble.api.identity.Author;
import org.briarproject.bramble.api.identity.AuthorInfo;
import org.briarproject.bramble.api.nullsafety.NotNullByDefault; import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
import org.briarproject.bramble.api.sync.GroupId; import org.briarproject.bramble.api.sync.GroupId;
import org.briarproject.bramble.api.sync.MessageId; import org.briarproject.bramble.api.sync.MessageId;
...@@ -15,19 +16,24 @@ import javax.annotation.concurrent.Immutable; ...@@ -15,19 +16,24 @@ import javax.annotation.concurrent.Immutable;
@NotNullByDefault @NotNullByDefault
public class IntroductionRequest extends PrivateRequest<Author> { public class IntroductionRequest extends PrivateRequest<Author> {
private final boolean contact; private final AuthorInfo authorInfo;
public IntroductionRequest(MessageId messageId, GroupId groupId, public IntroductionRequest(MessageId messageId, GroupId groupId,
long time, boolean local, boolean sent, boolean seen, boolean read, long time, boolean local, boolean sent, boolean seen, boolean read,
SessionId sessionId, Author author, @Nullable String text, SessionId sessionId, Author author, @Nullable String text,
boolean answered, boolean contact) { boolean answered, AuthorInfo authorInfo) {
super(messageId, groupId, time, local, sent, seen, read, sessionId, super(messageId, groupId, time, local, sent, seen, read, sessionId,
author, text, answered); author, text, answered);
this.contact = contact; this.authorInfo = authorInfo;
}
@Nullable
public String getAlias() {
return authorInfo.getAlias();
} }
public boolean isContact() { public boolean isContact() {
return contact; return authorInfo.getStatus().isContact();
} }
@Override @Override
......
package org.briarproject.briar.api.introduction; package org.briarproject.briar.api.introduction;
import org.briarproject.bramble.api.identity.Author; import org.briarproject.bramble.api.identity.Author;
import org.briarproject.bramble.api.identity.AuthorInfo;
import org.briarproject.bramble.api.nullsafety.NotNullByDefault; import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
import org.briarproject.bramble.api.sync.GroupId; import org.briarproject.bramble.api.sync.GroupId;
import org.briarproject.bramble.api.sync.MessageId; import org.briarproject.bramble.api.sync.MessageId;
...@@ -17,14 +18,17 @@ import static org.briarproject.briar.api.introduction.Role.INTRODUCER; ...@@ -17,14 +18,17 @@ import static org.briarproject.briar.api.introduction.Role.INTRODUCER;
public class IntroductionResponse extends PrivateResponse { public class IntroductionResponse extends PrivateResponse {
private final Author introducedAuthor; private final Author introducedAuthor;
private final AuthorInfo introducedAuthorInfo;
private final Role ourRole; private final Role ourRole;
public IntroductionResponse(MessageId messageId, GroupId groupId, long time, public IntroductionResponse(MessageId messageId, GroupId groupId, long time,
boolean local, boolean sent, boolean seen, boolean read, boolean local, boolean sent, boolean seen, boolean read,
SessionId sessionId, boolean accepted, Author author, Role role) { SessionId sessionId, boolean accepted, Author author,
AuthorInfo introducedAuthorInfo, Role role) {
super(messageId, groupId, time, local, sent, seen, read, sessionId, super(messageId, groupId, time, local, sent, seen, read, sessionId,
accepted); accepted);
this.introducedAuthor = author; this.introducedAuthor = author;
this.introducedAuthorInfo = introducedAuthorInfo;
this.ourRole = role; this.ourRole = role;
} }
...@@ -32,6 +36,10 @@ public class IntroductionResponse extends PrivateResponse { ...@@ -32,6 +36,10 @@ public class IntroductionResponse extends PrivateResponse {
return introducedAuthor; return introducedAuthor;
} }
public AuthorInfo getIntroducedAuthorInfo() {
return introducedAuthorInfo;
}
public boolean isIntroducer() { public boolean isIntroducer() {
return ourRole == INTRODUCER; return ourRole == INTRODUCER;
} }
......
...@@ -11,6 +11,7 @@ import org.briarproject.bramble.api.db.DbException; ...@@ -11,6 +11,7 @@ import org.briarproject.bramble.api.db.DbException;
import org.briarproject.bramble.api.db.Transaction; import org.briarproject.bramble.api.db.Transaction;
import org.briarproject.bramble.api.identity.Author; import org.briarproject.bramble.api.identity.Author;
import org.briarproject.bramble.api.identity.AuthorId; import org.briarproject.bramble.api.identity.AuthorId;
import org.briarproject.bramble.api.identity.AuthorInfo;
import org.briarproject.bramble.api.identity.IdentityManager; import org.briarproject.bramble.api.identity.IdentityManager;
import org.briarproject.bramble.api.nullsafety.NotNullByDefault; import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
import org.briarproject.bramble.api.plugin.TransportId; import org.briarproject.bramble.api.plugin.TransportId;
...@@ -149,11 +150,13 @@ abstract class AbstractProtocolEngine<S extends Session> ...@@ -149,11 +150,13 @@ abstract class AbstractProtocolEngine<S extends Session>
throws DbException { 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 =
contactManager.getAuthorInfo(txn, otherAuthor.getId());
IntroductionResponse response = IntroductionResponse response =
new IntroductionResponse(m.getMessageId(), m.getGroupId(), new IntroductionResponse(m.getMessageId(), m.getGroupId(),
m.getTimestamp(), false, false, false, false, m.getTimestamp(), false, false, false, false,
s.getSessionId(), m instanceof AcceptMessage, s.getSessionId(), m instanceof AcceptMessage,
otherAuthor, s.getRole()); otherAuthor, otherAuthorInfo, s.getRole());
IntroductionResponseReceivedEvent e = IntroductionResponseReceivedEvent e =
new IntroductionResponseReceivedEvent(response, c.getId()); new IntroductionResponseReceivedEvent(response, c.getId());
txn.attach(e); txn.attach(e);
......
...@@ -12,6 +12,7 @@ import org.briarproject.bramble.api.db.ContactExistsException; ...@@ -12,6 +12,7 @@ import org.briarproject.bramble.api.db.ContactExistsException;
import org.briarproject.bramble.api.db.DatabaseComponent; import org.briarproject.bramble.api.db.DatabaseComponent;
import org.briarproject.bramble.api.db.DbException; import org.briarproject.bramble.api.db.DbException;
import org.briarproject.bramble.api.db.Transaction; import org.briarproject.bramble.api.db.Transaction;
import org.briarproject.bramble.api.identity.AuthorInfo;
import org.briarproject.bramble.api.identity.IdentityManager; import org.briarproject.bramble.api.identity.IdentityManager;
import org.briarproject.bramble.api.identity.LocalAuthor; import org.briarproject.bramble.api.identity.LocalAuthor;
import org.briarproject.bramble.api.nullsafety.NotNullByDefault; import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
...@@ -251,12 +252,12 @@ class IntroduceeProtocolEngine ...@@ -251,12 +252,12 @@ class IntroduceeProtocolEngine
LocalAuthor localAuthor = identityManager.getLocalAuthor(txn); LocalAuthor localAuthor = identityManager.getLocalAuthor(txn);
Contact c = contactManager.getContact(txn, s.getIntroducer().getId(), Contact c = contactManager.getContact(txn, s.getIntroducer().getId(),
localAuthor.getId()); localAuthor.getId());
boolean contactExists = contactManager AuthorInfo authorInfo =
.contactExists(txn, m.getAuthor().getId(), localAuthor.getId()); contactManager.getAuthorInfo(txn, m.getAuthor().getId());
IntroductionRequest request = new IntroductionRequest(m.getMessageId(), IntroductionRequest request = new IntroductionRequest(m.getMessageId(),
m.getGroupId(), m.getTimestamp(), false, false, false, false, m.getGroupId(), m.getTimestamp(), false, false, false, false,
s.getSessionId(), m.getAuthor(), m.getText(), false, s.getSessionId(), m.getAuthor(), m.getText(), false,
contactExists); authorInfo);
IntroductionRequestReceivedEvent e = IntroductionRequestReceivedEvent e =
new IntroductionRequestReceivedEvent(request, c.getId()); new IntroductionRequestReceivedEvent(request, c.getId());
txn.attach(e); txn.attach(e);
......
...@@ -15,6 +15,8 @@ import org.briarproject.bramble.api.db.DbException; ...@@ -15,6 +15,8 @@ import org.briarproject.bramble.api.db.DbException;
import org.briarproject.bramble.api.db.Metadata; import org.briarproject.bramble.api.db.Metadata;
import org.briarproject.bramble.api.db.Transaction; import org.briarproject.bramble.api.db.Transaction;
import org.briarproject.bramble.api.identity.Author; import org.briarproject.bramble.api.identity.Author;
import org.briarproject.bramble.api.identity.AuthorId;
import org.briarproject.bramble.api.identity.AuthorInfo;
import org.briarproject.bramble.api.identity.IdentityManager; import org.briarproject.bramble.api.identity.IdentityManager;
import org.briarproject.bramble.api.identity.LocalAuthor; import org.briarproject.bramble.api.identity.LocalAuthor;
import org.briarproject.bramble.api.nullsafety.NotNullByDefault; import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
...@@ -39,6 +41,7 @@ import org.briarproject.briar.introduction.IntroducerSession.Introducee; ...@@ -39,6 +41,7 @@ import org.briarproject.briar.introduction.IntroducerSession.Introducee;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collection; import java.util.Collection;
import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Map.Entry; import java.util.Map.Entry;
...@@ -408,6 +411,7 @@ class IntroductionManagerImpl extends ConversationClientImpl ...@@ -408,6 +411,7 @@ class IntroductionManagerImpl extends ConversationClientImpl
.getMessageMetadataAsDictionary(txn, contactGroupId, query); .getMessageMetadataAsDictionary(txn, contactGroupId, query);
List<PrivateMessageHeader> messages = List<PrivateMessageHeader> messages =
new ArrayList<>(results.size()); new ArrayList<>(results.size());
Map<AuthorId, AuthorInfo> authorInfos = new HashMap<>();
for (Entry<MessageId, BdfDictionary> e : results.entrySet()) { for (Entry<MessageId, BdfDictionary> e : results.entrySet()) {
MessageId m = e.getKey(); MessageId m = e.getKey();
MessageMetadata meta = MessageMetadata meta =
...@@ -419,15 +423,17 @@ class IntroductionManagerImpl extends ConversationClientImpl ...@@ -419,15 +423,17 @@ class IntroductionManagerImpl extends ConversationClientImpl
if (type == REQUEST) { if (type == REQUEST) {
messages.add( messages.add(
parseInvitationRequest(txn, contactGroupId, m, parseInvitationRequest(txn, contactGroupId, m,
meta, status, ss.bdfSession)); meta, status, ss.bdfSession, authorInfos));
} else if (type == ACCEPT) { } else if (type == ACCEPT) {
messages.add( messages.add(
parseInvitationResponse(contactGroupId, m, meta, parseInvitationResponse(txn, contactGroupId, m,
status, ss.bdfSession, true)); meta, status, ss.bdfSession, authorInfos,
true));
} else if (type == DECLINE) { } else if (type == DECLINE) {
messages.add( messages.add(
parseInvitationResponse(contactGroupId, m, meta, parseInvitationResponse(txn, contactGroupId, m,
status, ss.bdfSession, false)); meta, status, ss.bdfSession, authorInfos,
false));
} }
} }
return messages; return messages;
...@@ -438,43 +444,41 @@ class IntroductionManagerImpl extends ConversationClientImpl ...@@ -438,43 +444,41 @@ class IntroductionManagerImpl extends ConversationClientImpl
private IntroductionRequest parseInvitationRequest(Transaction txn, private IntroductionRequest parseInvitationRequest(Transaction txn,
GroupId contactGroupId, MessageId m, MessageMetadata meta, GroupId contactGroupId, MessageId m, MessageMetadata meta,
MessageStatus status, BdfDictionary bdfSession) MessageStatus status, BdfDictionary bdfSession,
Map<AuthorId, AuthorInfo> authorInfos)
throws DbException, FormatException { throws DbException, FormatException {
Role role = sessionParser.getRole(bdfSession); Role role = sessionParser.getRole(bdfSession);
SessionId sessionId; SessionId sessionId;
Author author;
if (role == INTRODUCER) { if (role == INTRODUCER) {
IntroducerSession session = IntroducerSession session =
sessionParser.parseIntroducerSession(bdfSession); sessionParser.parseIntroducerSession(bdfSession);
sessionId = session.getSessionId(); sessionId = session.getSessionId();
if (contactGroupId.equals(session.getIntroduceeA().groupId)) {
author = session.getIntroduceeB().author;
} else {
author = session.getIntroduceeA().author;
}
} else if (role == INTRODUCEE) { } else if (role == INTRODUCEE) {
IntroduceeSession session = sessionParser IntroduceeSession session = sessionParser
.parseIntroduceeSession(contactGroupId, bdfSession); .parseIntroduceeSession(contactGroupId, bdfSession);
sessionId = session.getSessionId(); sessionId = session.getSessionId();
author = session.getRemote().author;
} else throw new AssertionError(); } else throw new AssertionError();
Message msg = clientHelper.getMessage(txn, m); Message msg = clientHelper.getMessage(txn, m);
BdfList body = clientHelper.toList(msg); BdfList body = clientHelper.toList(msg);
RequestMessage rm = messageParser.parseRequestMessage(msg, body); RequestMessage rm = messageParser.parseRequestMessage(msg, body);
String text = rm.getText(); String text = rm.getText();
LocalAuthor localAuthor = identityManager.getLocalAuthor(txn); Author author = rm.getAuthor();
boolean contactExists = contactManager AuthorInfo authorInfo = authorInfos.get(author.getId());
.contactExists(txn, rm.getAuthor().getId(), if (authorInfo == null) {
localAuthor.getId()); authorInfo = contactManager.getAuthorInfo(txn, author.getId());
authorInfos.put(author.getId(), authorInfo);
}
return new IntroductionRequest(m, contactGroupId, meta.getTimestamp(), return new IntroductionRequest(m, contactGroupId, meta.getTimestamp(),
meta.isLocal(), status.isSent(), status.isSeen(), meta.isRead(), meta.isLocal(), status.isSent(), status.isSeen(), meta.isRead(),
sessionId, author, text, !meta.isAvailableToAnswer(), sessionId, author, text, !meta.isAvailableToAnswer(),
contactExists); authorInfo);
} }
private IntroductionResponse parseInvitationResponse(GroupId contactGroupId, private IntroductionResponse parseInvitationResponse(Transaction txn,
MessageId m, MessageMetadata meta, MessageStatus status, GroupId contactGroupId, MessageId m, MessageMetadata meta,
BdfDictionary bdfSession, boolean accept) throws FormatException { MessageStatus status, BdfDictionary bdfSession,
Map<AuthorId, AuthorInfo> authorInfos, boolean accept)
throws FormatException, DbException {
Role role = sessionParser.getRole(bdfSession); Role role = sessionParser.getRole(bdfSession);
SessionId sessionId; SessionId sessionId;
Author author; Author author;
...@@ -493,9 +497,14 @@ class IntroductionManagerImpl extends ConversationClientImpl ...@@ -493,9 +497,14 @@ class IntroductionManagerImpl extends ConversationClientImpl
sessionId = session.getSessionId(); sessionId = session.getSessionId();
author = session.getRemote().author; author = session.getRemote().author;
} else throw new AssertionError(); } else throw new AssertionError();
AuthorInfo authorInfo = authorInfos.get(author.getId());
if (authorInfo == null) {
authorInfo = contactManager.getAuthorInfo(txn, author.getId());
authorInfos.put(author.getId(), authorInfo);
}
return new IntroductionResponse(m, contactGroupId, meta.getTimestamp(), return new IntroductionResponse(m, contactGroupId, meta.getTimestamp(),
meta.isLocal(), status.isSent(), status.isSeen(), meta.isRead(), meta.isLocal(), status.isSent(), status.isSeen(), meta.isRead(),
sessionId, accept, author, role); sessionId, accept, author, authorInfo, role);
} }
private void removeSessionWithIntroducer(Transaction txn, private void removeSessionWithIntroducer(Transaction txn,
......
...@@ -7,6 +7,9 @@ import io.javalin.json.JavalinJson.toJson ...@@ -7,6 +7,9 @@ import io.javalin.json.JavalinJson.toJson
import io.mockk.* import io.mockk.*
import org.briarproject.bramble.api.contact.ContactId import org.briarproject.bramble.api.contact.ContactId
import org.briarproject.bramble.api.db.NoSuchContactException import org.briarproject.bramble.api.db.NoSuchContactException
import org.briarproject.bramble.api.identity.AuthorInfo
import org.briarproject.bramble.api.identity.AuthorInfo.Status.UNVERIFIED
import org.briarproject.bramble.api.identity.AuthorInfo.Status.VERIFIED
import org.briarproject.bramble.test.ImmediateExecutor import org.briarproject.bramble.test.ImmediateExecutor
import org.briarproject.bramble.test.TestUtils.getRandomId import org.briarproject.bramble.test.TestUtils.getRandomId
import org.briarproject.bramble.util.StringUtils.getRandomString import org.briarproject.bramble.util.StringUtils.getRandomString
...@@ -61,7 +64,7 @@ internal class MessagingControllerImplTest : ControllerTest() { ...@@ -61,7 +64,7 @@ internal class MessagingControllerImplTest : ControllerTest() {
fun listIntroductionRequest() { fun listIntroductionRequest() {
val request = IntroductionRequest( val request = IntroductionRequest(
message.id, group.id, timestamp, true, true, false, true, sessionId, author, text, message.id, group.id, timestamp, true, true, false, true, sessionId, author, text,
false, false false, AuthorInfo(UNVERIFIED)
) )
expectGetContact() expectGetContact()
...@@ -200,7 +203,7 @@ internal class MessagingControllerImplTest : ControllerTest() { ...@@ -200,7 +203,7 @@ internal class MessagingControllerImplTest : ControllerTest() {
fun testIntroductionRequestWithNullText() { fun testIntroductionRequestWithNullText() {
val request = IntroductionRequest( val request = IntroductionRequest(
message.id, group.id, timestamp, true, true, false, true, sessionId, author, null, message.id, group.id, timestamp, true, true, false, true, sessionId, author, null,
false, false false, AuthorInfo(VERIFIED)
) )
val json = """ val json = """
{ {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment