implementation of the zombie members handling logic

This commit is contained in:
Brice-W
2021-04-23 14:07:10 +10:00
parent 3e4a6a9df4
commit b064f8f5d7
9 changed files with 169 additions and 60 deletions

View File

@@ -28,7 +28,6 @@ import org.session.libsignal.service.api.messages.SignalServiceAttachmentPointer
import org.session.libsignal.service.loki.database.LokiOpenGroupDatabaseProtocol;
import java.io.Closeable;
import java.io.IOException;
import java.security.SecureRandom;
import java.util.Collections;
import java.util.LinkedList;
@@ -44,6 +43,7 @@ public class GroupDatabase extends Database implements LokiOpenGroupDatabaseProt
static final String GROUP_ID = "group_id";
private static final String TITLE = "title";
private static final String MEMBERS = "members";
private static final String ZOMBIE_MEMBERS = "zombie_members";
private static final String AVATAR = "avatar";
private static final String AVATAR_ID = "avatar_id";
private static final String AVATAR_KEY = "avatar_key";
@@ -64,6 +64,7 @@ public class GroupDatabase extends Database implements LokiOpenGroupDatabaseProt
GROUP_ID + " TEXT, " +
TITLE + " TEXT, " +
MEMBERS + " TEXT, " +
ZOMBIE_MEMBERS + " TEXT, " +
AVATAR + " BLOB, " +
AVATAR_ID + " INTEGER, " +
AVATAR_KEY + " BLOB, " +
@@ -81,7 +82,7 @@ public class GroupDatabase extends Database implements LokiOpenGroupDatabaseProt
};
private static final String[] GROUP_PROJECTION = {
GROUP_ID, TITLE, MEMBERS, AVATAR, AVATAR_ID, AVATAR_KEY, AVATAR_CONTENT_TYPE, AVATAR_RELAY, AVATAR_DIGEST,
GROUP_ID, TITLE, MEMBERS, ZOMBIE_MEMBERS, AVATAR, AVATAR_ID, AVATAR_KEY, AVATAR_CONTENT_TYPE, AVATAR_RELAY, AVATAR_DIGEST,
TIMESTAMP, ACTIVE, MMS, AVATAR_URL, ADMINS
};
@@ -162,7 +163,7 @@ public class GroupDatabase extends Database implements LokiOpenGroupDatabaseProt
}
public @NonNull List<Recipient> getGroupMembers(String groupId, boolean includeSelf) {
List<Address> members = getCurrentMembers(groupId);
List<Address> members = getCurrentMembers(groupId, false);
List<Recipient> recipients = new LinkedList<>();
for (Address member : members) {
@@ -177,6 +178,19 @@ public class GroupDatabase extends Database implements LokiOpenGroupDatabaseProt
return recipients;
}
public @NonNull List<Recipient> getGroupZombieMembers(String groupId) {
List<Address> members = getCurrentZombieMembers(groupId);
List<Recipient> recipients = new LinkedList<>();
for (Address member : members) {
if (member.isContact()) {
recipients.add(Recipient.from(context, member, false));
}
}
return recipients;
}
public long create(@NonNull String groupId, @Nullable String title, @NonNull List<Address> members,
@Nullable SignalServiceAttachmentPointer avatar, @Nullable String relay, @Nullable List<Address> admins, @NonNull Long formationTimestamp)
{
@@ -300,6 +314,16 @@ public class GroupDatabase extends Database implements LokiOpenGroupDatabaseProt
});
}
public void updateZombieMembers(String groupId, List<Address> members) {
Collections.sort(members);
ContentValues contents = new ContentValues();
contents.put(ZOMBIE_MEMBERS, Address.toSerializedList(members, ','));
contents.put(ACTIVE, 1);
databaseHelper.getWritableDatabase().update(TABLE_NAME, contents, GROUP_ID + " = ?",
new String[] {groupId});
}
public void updateAdmins(String groupId, List<Address> admins) {
Collections.sort(admins);
@@ -311,7 +335,7 @@ public class GroupDatabase extends Database implements LokiOpenGroupDatabaseProt
}
public void removeMember(String groupId, Address source) {
List<Address> currentMembers = getCurrentMembers(groupId);
List<Address> currentMembers = getCurrentMembers(groupId, false);
currentMembers.remove(source);
ContentValues contents = new ContentValues();
@@ -329,18 +353,22 @@ public class GroupDatabase extends Database implements LokiOpenGroupDatabaseProt
});
}
private List<Address> getCurrentMembers(String groupId) {
private List<Address> getCurrentMembers(String groupId, boolean zombieMembers) {
Cursor cursor = null;
String membersColumn = MEMBERS;
if (zombieMembers) membersColumn = ZOMBIE_MEMBERS;
try {
cursor = databaseHelper.getReadableDatabase().query(TABLE_NAME, new String[] {MEMBERS},
cursor = databaseHelper.getReadableDatabase().query(TABLE_NAME, new String[] {membersColumn},
GROUP_ID + " = ?",
new String[] {groupId},
null, null, null);
if (cursor != null && cursor.moveToFirst()) {
String serializedMembers = cursor.getString(cursor.getColumnIndexOrThrow(MEMBERS));
return Address.fromSerializedList(serializedMembers, ',');
String serializedMembers = cursor.getString(cursor.getColumnIndexOrThrow(membersColumn));
if (serializedMembers != null && !serializedMembers.isEmpty())
return Address.fromSerializedList(serializedMembers, ',');
}
return new LinkedList<>();
@@ -350,6 +378,10 @@ public class GroupDatabase extends Database implements LokiOpenGroupDatabaseProt
}
}
private List<Address> getCurrentZombieMembers(String groupId) {
return getCurrentMembers(groupId, true);
}
public boolean isActive(String groupId) {
Optional<GroupRecord> record = getGroup(groupId);
return record.isPresent() && record.get().isActive();

View File

@@ -395,6 +395,10 @@ class Storage(context: Context, helper: SQLCipherOpenHelper) : Database(context,
DatabaseFactory.getGroupDatabase(context).setActive(groupID, value)
}
override fun getZombieMember(groupID: String): Set<String> {
return DatabaseFactory.getGroupDatabase(context).getGroupZombieMembers(groupID).map { it.address.serialize() }.toHashSet()
}
override fun removeMember(groupID: String, member: Address) {
DatabaseFactory.getGroupDatabase(context).removeMember(groupID, member)
}
@@ -403,6 +407,10 @@ class Storage(context: Context, helper: SQLCipherOpenHelper) : Database(context,
DatabaseFactory.getGroupDatabase(context).updateMembers(groupID, members)
}
override fun updateZombieMembers(groupID: String, members: List<Address>) {
DatabaseFactory.getGroupDatabase(context).updateZombieMembers(groupID, members)
}
override fun insertIncomingInfoMessage(context: Context, senderPublicKey: String, groupID: String, type: SignalServiceGroup.Type, name: String, members: Collection<String>, admins: Collection<String>, sentTimestamp: Long) {
val group = SignalServiceGroup(type, GroupUtil.getDecodedGroupIDAsData(groupID), SignalServiceGroup.GroupType.SIGNAL, name, members.toList(), null, admins.toList())
val m = IncomingTextMessage(Address.fromSerialized(senderPublicKey), 1, sentTimestamp, "", Optional.of(group), 0, true)

View File

@@ -54,9 +54,10 @@ public class SQLCipherOpenHelper extends SQLiteOpenHelper {
private static final int lokiV20 = 41;
private static final int lokiV21 = 42;
private static final int lokiV22 = 43;
private static final int lokiV23 = 44;
// Loki - onUpgrade(...) must be updated to use Loki version numbers if Signal makes any database changes
private static final int DATABASE_VERSION = lokiV22;
private static final int DATABASE_VERSION = lokiV23;
private static final String DATABASE_NAME = "signal.db";
private final Context context;
@@ -272,6 +273,10 @@ public class SQLCipherOpenHelper extends SQLiteOpenHelper {
"SendDeliveryReceiptJob");
}
if (oldVersion < lokiV23) {
db.execSQL("ALTER TABLE groups ADD COLUMN zombie_members TEXT");
}
db.setTransactionSuccessful();
} finally {
db.endTransaction();