From 98cf6b5bba9c6aa550304277f9be0ed642f6c48a Mon Sep 17 00:00:00 2001
From: akwizgran <akwizgran@users.sourceforge.net>
Date: Fri, 11 Nov 2016 11:29:55 +0000
Subject: [PATCH] Mark relationship visible when syncing group with peer.

---
 .../privategroup/PrivateGroupManagerImpl.java | 19 ++++++++++-------
 .../invitation/PeerProtocolEngine.java        | 21 +++++++++++++++++++
 2 files changed, 33 insertions(+), 7 deletions(-)

diff --git a/briar-core/src/org/briarproject/privategroup/PrivateGroupManagerImpl.java b/briar-core/src/org/briarproject/privategroup/PrivateGroupManagerImpl.java
index c2bdf6cf49..5ff1193f93 100644
--- a/briar-core/src/org/briarproject/privategroup/PrivateGroupManagerImpl.java
+++ b/briar-core/src/org/briarproject/privategroup/PrivateGroupManagerImpl.java
@@ -443,21 +443,26 @@ public class PrivateGroupManagerImpl extends BdfIncomingMessageHook implements
 		BdfDictionary meta = clientHelper.getGroupMetadataAsDictionary(txn, g);
 		BdfList members = meta.getList(GROUP_KEY_MEMBERS);
 		Visibility v = INVISIBLE;
-		boolean foundMember = false;
+		boolean foundMember = false, changed = false;
 		for (int i = 0 ; i < members.size(); i++) {
 			BdfDictionary d = members.getDictionary(i);
 			AuthorId memberId = new AuthorId(d.getRaw(KEY_MEMBER_ID));
 			if (a.equals(memberId)) {
 				foundMember = true;
-				Visibility vOld = getVisibility(d);
-				if (vOld != INVISIBLE) throw new ProtocolStateException();
-				v = byContact ? REVEALED_BY_CONTACT : REVEALED_BY_US;
-				d.put(GROUP_KEY_VISIBILITY, v.getInt());
+				// Don't update the visibility if the contact is already visible
+				if (getVisibility(d) == INVISIBLE) {
+					changed = true;
+					v = byContact ? REVEALED_BY_CONTACT : REVEALED_BY_US;
+					d.put(GROUP_KEY_VISIBILITY, v.getInt());
+				}
+				break;
 			}
 		}
 		if (!foundMember) throw new ProtocolStateException();
-		clientHelper.mergeGroupMetadata(txn, g, meta);
-		txn.attach(new ContactRelationshipRevealedEvent(g, v));
+		if (changed) {
+			clientHelper.mergeGroupMetadata(txn, g, meta);
+			txn.attach(new ContactRelationshipRevealedEvent(g, v));
+		}
 	}
 
 	@Override
diff --git a/briar-core/src/org/briarproject/privategroup/invitation/PeerProtocolEngine.java b/briar-core/src/org/briarproject/privategroup/invitation/PeerProtocolEngine.java
index 6d3c721f38..84aa82ced3 100644
--- a/briar-core/src/org/briarproject/privategroup/invitation/PeerProtocolEngine.java
+++ b/briar-core/src/org/briarproject/privategroup/invitation/PeerProtocolEngine.java
@@ -3,6 +3,8 @@ package org.briarproject.privategroup.invitation;
 import org.briarproject.api.FormatException;
 import org.briarproject.api.clients.ClientHelper;
 import org.briarproject.api.clients.ProtocolStateException;
+import org.briarproject.api.contact.Contact;
+import org.briarproject.api.contact.ContactId;
 import org.briarproject.api.db.DatabaseComponent;
 import org.briarproject.api.db.DbException;
 import org.briarproject.api.db.Transaction;
@@ -179,6 +181,7 @@ class PeerProtocolEngine extends AbstractProtocolEngine<PeerSession> {
 		} catch (FormatException e) {
 			throw new DbException(e); // Invalid group metadata
 		}
+		// The relationship is already marked visible to the group
 		// Move to the BOTH_JOINED state
 		return new PeerSession(s.getContactGroupId(), s.getPrivateGroupId(),
 				sent.getId(), s.getLastRemoteMessageId(), sent.getTimestamp(),
@@ -228,6 +231,12 @@ class PeerProtocolEngine extends AbstractProtocolEngine<PeerSession> {
 		} catch (FormatException e) {
 			throw new DbException(e); // Invalid group metadata
 		}
+		try {
+			// Mark the relationship visible to the group, revealed by contact
+			relationshipRevealed(txn, s, true);
+		} catch (FormatException e) {
+			throw new DbException(e); // Invalid group metadata
+		}
 		// Move to the BOTH_JOINED state
 		return new PeerSession(s.getContactGroupId(), s.getPrivateGroupId(),
 				sent.getId(), s.getLastRemoteMessageId(), sent.getTimestamp(),
@@ -254,6 +263,8 @@ class PeerProtocolEngine extends AbstractProtocolEngine<PeerSession> {
 		Message sent = sendJoinMessage(txn, s, false);
 		// Start syncing the private group with the contact
 		syncPrivateGroupWithContact(txn, s, true);
+		// Mark the relationship visible to the group, revealed by contact
+		relationshipRevealed(txn, s, true);
 		// Move to the BOTH_JOINED state
 		return new PeerSession(s.getContactGroupId(), s.getPrivateGroupId(),
 				sent.getId(), m.getId(), sent.getTimestamp(), BOTH_JOINED);
@@ -266,6 +277,8 @@ class PeerProtocolEngine extends AbstractProtocolEngine<PeerSession> {
 			return abort(txn, s);
 		// Start syncing the private group with the contact
 		syncPrivateGroupWithContact(txn, s, true);
+		// Mark the relationship visible to the group, revealed by us
+		relationshipRevealed(txn, s, false);
 		// Move to the BOTH_JOINED state
 		return new PeerSession(s.getContactGroupId(), s.getPrivateGroupId(),
 				s.getLastLocalMessageId(), m.getId(), s.getLocalTimestamp(),
@@ -321,4 +334,12 @@ class PeerProtocolEngine extends AbstractProtocolEngine<PeerSession> {
 				sent.getId(), s.getLastRemoteMessageId(), sent.getTimestamp(),
 				ERROR);
 	}
+
+	private void relationshipRevealed(Transaction txn, PeerSession s,
+			boolean byContact) throws DbException, FormatException {
+		ContactId contactId = getContactId(txn, s.getContactGroupId());
+		Contact contact = db.getContact(txn, contactId);
+		privateGroupManager.relationshipRevealed(txn, s.getPrivateGroupId(),
+				contact.getAuthor().getId(), byContact);
+	}
 }
-- 
GitLab