mirror of
https://github.com/oxen-io/session-android.git
synced 2024-12-24 16:57:50 +00:00
Merge pull request #359 from loki-project/closed-group-editing
Fix Adding & Removing Members Simultaneously
This commit is contained in:
commit
828acc1620
@ -112,6 +112,7 @@ object ClosedGroupsProtocol {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
val oldMembers = group.members.map { it.serialize() }.toSet()
|
val oldMembers = group.members.map { it.serialize() }.toSet()
|
||||||
|
val newMembers = members.minus(oldMembers)
|
||||||
val membersAsData = members.map { Hex.fromStringCondensed(it) }
|
val membersAsData = members.map { Hex.fromStringCondensed(it) }
|
||||||
val admins = group.admins.map { it.serialize() }
|
val admins = group.admins.map { it.serialize() }
|
||||||
val adminsAsData = admins.map { Hex.fromStringCondensed(it) }
|
val adminsAsData = admins.map { Hex.fromStringCondensed(it) }
|
||||||
@ -123,6 +124,7 @@ object ClosedGroupsProtocol {
|
|||||||
val wasAnyUserRemoved = members.toSet().intersect(oldMembers) != oldMembers.toSet()
|
val wasAnyUserRemoved = members.toSet().intersect(oldMembers) != oldMembers.toSet()
|
||||||
val removedMembers = oldMembers.minus(members)
|
val removedMembers = oldMembers.minus(members)
|
||||||
val isUserLeaving = removedMembers.contains(userPublicKey)
|
val isUserLeaving = removedMembers.contains(userPublicKey)
|
||||||
|
var newSenderKeys = listOf<ClosedGroupSenderKey>()
|
||||||
if (wasAnyUserRemoved) {
|
if (wasAnyUserRemoved) {
|
||||||
if (isUserLeaving && removedMembers.count() != 1) {
|
if (isUserLeaving && removedMembers.count() != 1) {
|
||||||
Log.d("Loki", "Can't remove self and others simultaneously.")
|
Log.d("Loki", "Can't remove self and others simultaneously.")
|
||||||
@ -161,8 +163,7 @@ object ClosedGroupsProtocol {
|
|||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// Generate ratchets for any new members
|
// Generate ratchets for any new members
|
||||||
val newMembers = members.minus(oldMembers)
|
newSenderKeys = newMembers.map { publicKey ->
|
||||||
val newSenderKeys: List<ClosedGroupSenderKey> = newMembers.map { publicKey ->
|
|
||||||
val ratchet = SharedSenderKeysImplementation.shared.generateRatchet(groupPublicKey, publicKey)
|
val ratchet = SharedSenderKeysImplementation.shared.generateRatchet(groupPublicKey, publicKey)
|
||||||
ClosedGroupSenderKey(Hex.fromStringCondensed(ratchet.chainKey), ratchet.keyIndex, Hex.fromStringCondensed(publicKey))
|
ClosedGroupSenderKey(Hex.fromStringCondensed(ratchet.chainKey), ratchet.keyIndex, Hex.fromStringCondensed(publicKey))
|
||||||
}
|
}
|
||||||
@ -171,18 +172,18 @@ object ClosedGroupsProtocol {
|
|||||||
newSenderKeys, membersAsData, adminsAsData)
|
newSenderKeys, membersAsData, adminsAsData)
|
||||||
val job = ClosedGroupUpdateMessageSendJob(groupPublicKey, closedGroupUpdateKind)
|
val job = ClosedGroupUpdateMessageSendJob(groupPublicKey, closedGroupUpdateKind)
|
||||||
ApplicationContext.getInstance(context).jobManager.add(job)
|
ApplicationContext.getInstance(context).jobManager.add(job)
|
||||||
// Establish sessions if needed
|
}
|
||||||
establishSessionsWithMembersIfNeeded(context, newMembers)
|
// Establish sessions if needed
|
||||||
// Send closed group update messages to the new members using established channels
|
establishSessionsWithMembersIfNeeded(context, newMembers)
|
||||||
val allSenderKeys = sskDatabase.getAllClosedGroupSenderKeys(groupPublicKey) + newSenderKeys
|
// Send closed group update messages to the new members using established channels
|
||||||
for (member in newMembers) {
|
val allSenderKeys = sskDatabase.getAllClosedGroupSenderKeys(groupPublicKey) + newSenderKeys
|
||||||
@Suppress("NAME_SHADOWING")
|
for (member in newMembers) {
|
||||||
val closedGroupUpdateKind = ClosedGroupUpdateMessageSendJob.Kind.New(Hex.fromStringCondensed(groupPublicKey), name,
|
@Suppress("NAME_SHADOWING")
|
||||||
Hex.fromStringCondensed(groupPrivateKey), allSenderKeys, membersAsData, adminsAsData)
|
val closedGroupUpdateKind = ClosedGroupUpdateMessageSendJob.Kind.New(Hex.fromStringCondensed(groupPublicKey), name,
|
||||||
@Suppress("NAME_SHADOWING")
|
Hex.fromStringCondensed(groupPrivateKey), allSenderKeys, membersAsData, adminsAsData)
|
||||||
val job = ClosedGroupUpdateMessageSendJob(member, closedGroupUpdateKind)
|
@Suppress("NAME_SHADOWING")
|
||||||
ApplicationContext.getInstance(context).jobManager.add(job)
|
val job = ClosedGroupUpdateMessageSendJob(member, closedGroupUpdateKind)
|
||||||
}
|
ApplicationContext.getInstance(context).jobManager.add(job)
|
||||||
}
|
}
|
||||||
// Update the group
|
// Update the group
|
||||||
groupDB.updateTitle(groupID, name)
|
groupDB.updateTitle(groupID, name)
|
||||||
@ -225,7 +226,7 @@ object ClosedGroupsProtocol {
|
|||||||
when (closedGroupUpdate.type) {
|
when (closedGroupUpdate.type) {
|
||||||
SignalServiceProtos.ClosedGroupUpdate.Type.NEW -> {
|
SignalServiceProtos.ClosedGroupUpdate.Type.NEW -> {
|
||||||
return !closedGroupUpdate.name.isNullOrEmpty() && !(closedGroupUpdate.groupPrivateKey ?: ByteString.copyFrom(ByteArray(0))).isEmpty
|
return !closedGroupUpdate.name.isNullOrEmpty() && !(closedGroupUpdate.groupPrivateKey ?: ByteString.copyFrom(ByteArray(0))).isEmpty
|
||||||
&& closedGroupUpdate.senderKeysCount > 0 && closedGroupUpdate.membersCount > 0 && closedGroupUpdate.adminsCount > 0
|
&& closedGroupUpdate.membersCount > 0 && closedGroupUpdate.adminsCount > 0 // senderKeys may be empty
|
||||||
}
|
}
|
||||||
SignalServiceProtos.ClosedGroupUpdate.Type.INFO -> {
|
SignalServiceProtos.ClosedGroupUpdate.Type.INFO -> {
|
||||||
return !closedGroupUpdate.name.isNullOrEmpty() && closedGroupUpdate.membersCount > 0 && closedGroupUpdate.adminsCount > 0 // senderKeys may be empty
|
return !closedGroupUpdate.name.isNullOrEmpty() && closedGroupUpdate.membersCount > 0 && closedGroupUpdate.adminsCount > 0 // senderKeys may be empty
|
||||||
@ -255,6 +256,24 @@ object ClosedGroupsProtocol {
|
|||||||
val ratchet = ClosedGroupRatchet(senderKey.chainKey.toHexString(), senderKey.keyIndex, listOf())
|
val ratchet = ClosedGroupRatchet(senderKey.chainKey.toHexString(), senderKey.keyIndex, listOf())
|
||||||
sskDatabase.setClosedGroupRatchet(groupPublicKey, senderKey.publicKey.toHexString(), ratchet)
|
sskDatabase.setClosedGroupRatchet(groupPublicKey, senderKey.publicKey.toHexString(), ratchet)
|
||||||
}
|
}
|
||||||
|
// Sort out any discrepancies between the provided sender keys and what's required
|
||||||
|
val missingSenderKeys = members.toSet().subtract(senderKeys.map { Hex.toStringCondensed(it.publicKey) })
|
||||||
|
if (missingSenderKeys.contains(userPublicKey)) {
|
||||||
|
establishSessionsWithMembersIfNeeded(context, missingSenderKeys)
|
||||||
|
val userRatchet = SharedSenderKeysImplementation.shared.generateRatchet(groupPublicKey, userPublicKey)
|
||||||
|
val userSenderKey = ClosedGroupSenderKey(Hex.fromStringCondensed(userRatchet.chainKey), userRatchet.keyIndex, Hex.fromStringCondensed(userPublicKey))
|
||||||
|
for (member in members) {
|
||||||
|
if (member == userPublicKey) { continue }
|
||||||
|
@Suppress("NAME_SHADOWING")
|
||||||
|
val closedGroupUpdateKind = ClosedGroupUpdateMessageSendJob.Kind.SenderKey(Hex.fromStringCondensed(groupPublicKey), userSenderKey)
|
||||||
|
@Suppress("NAME_SHADOWING")
|
||||||
|
val job = ClosedGroupUpdateMessageSendJob(member, closedGroupUpdateKind)
|
||||||
|
ApplicationContext.getInstance(context).jobManager.add(job)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (publicKey in missingSenderKeys.minus(userPublicKey)) {
|
||||||
|
requestSenderKey(context, groupPublicKey, publicKey)
|
||||||
|
}
|
||||||
// Create the group
|
// Create the group
|
||||||
val groupID = doubleEncodeGroupID(groupPublicKey)
|
val groupID = doubleEncodeGroupID(groupPublicKey)
|
||||||
DatabaseFactory.getGroupDatabase(context).create(groupID, name, LinkedList<Address>(members.map { Address.fromSerialized(it) }),
|
DatabaseFactory.getGroupDatabase(context).create(groupID, name, LinkedList<Address>(members.map { Address.fromSerialized(it) }),
|
||||||
|
Loading…
x
Reference in New Issue
Block a user