refactor: message sender + closed group

pull/439/head
Ryan ZHAO 4 years ago
parent c32c58eee7
commit 4cfa5e9f3b

@ -24,52 +24,47 @@ import org.session.libsignal.service.loki.protocol.closedgroups.SharedSenderKeys
import org.session.libsignal.service.loki.utilities.hexEncodedPrivateKey import org.session.libsignal.service.loki.utilities.hexEncodedPrivateKey
import org.session.libsignal.service.loki.utilities.hexEncodedPublicKey import org.session.libsignal.service.loki.utilities.hexEncodedPublicKey
import org.session.libsignal.service.loki.utilities.removing05PrefixIfNeeded import org.session.libsignal.service.loki.utilities.removing05PrefixIfNeeded
import org.session.libsignal.utilities.ThreadUtils
import java.util.* import java.util.*
fun MessageSender.createClosedGroup(name: String, members: Collection<String>): Promise<String, Exception> { fun MessageSender.createClosedGroup(name: String, members: Collection<String>): Promise<String, Exception> {
val deferred = deferred<String, Exception>() val deferred = deferred<String, Exception>()
// Prepare ThreadUtils.queue {
val context = MessagingConfiguration.shared.context // Prepare
val storage = MessagingConfiguration.shared.storage val context = MessagingConfiguration.shared.context
val members = members val storage = MessagingConfiguration.shared.storage
val userPublicKey = storage.getUserPublicKey()!! val userPublicKey = storage.getUserPublicKey()!!
// Generate a key pair for the group val membersAsData = members.map { ByteString.copyFrom(Hex.fromStringCondensed(it)) }
val groupKeyPair = Curve.generateKeyPair() // Generate the group's public key
val groupPublicKey = groupKeyPair.hexEncodedPublicKey // Includes the "05" prefix val groupPublicKey = Curve.generateKeyPair().hexEncodedPublicKey // Includes the "05" prefix
members.plus(userPublicKey) // Generate the key pair that'll be used for encryption and decryption
val membersAsData = members.map { Hex.fromStringCondensed(it) } val encryptionKeyPair = Curve.generateKeyPair()
// Create ratchets for all members // Create the group
val senderKeys: List<ClosedGroupSenderKey> = members.map { publicKey -> val groupID = GroupUtil.doubleEncodeGroupID(groupPublicKey)
val ratchet = SharedSenderKeysImplementation.shared.generateRatchet(groupPublicKey, publicKey) val admins = setOf( userPublicKey )
ClosedGroupSenderKey(Hex.fromStringCondensed(ratchet.chainKey), ratchet.keyIndex, Hex.fromStringCondensed(publicKey)) val adminsAsData = admins.map { ByteString.copyFrom(Hex.fromStringCondensed(it)) }
} storage.createGroup(groupID, name, LinkedList(members.map { Address.fromSerialized(it) }),
// Create the group null, null, LinkedList(admins.map { Address.fromSerialized(it) }))
val admins = setOf( userPublicKey ) storage.setProfileSharing(Address.fromSerialized(groupID), true)
val adminsAsData = admins.map { Hex.fromStringCondensed(it) } // Send a closed group update message to all members individually
val groupID = GroupUtil.getEncodedClosedGroupID(GroupUtil.getEncodedClosedGroupID(Hex.fromStringCondensed(groupPublicKey)).toByteArray()) //double encoded val closedGroupUpdateKind = ClosedGroupControlMessage.Kind.New(ByteString.copyFrom(Hex.fromStringCondensed(groupPublicKey)), name, encryptionKeyPair, membersAsData, adminsAsData)
storage.createGroup(groupID, name, LinkedList(members.map { Address.fromSerialized(it) }), null, null, LinkedList(admins.map { Address.fromSerialized(it) })) for (member in members) {
storage.setProfileSharing(Address.fromSerialized(groupID), true) if (member == userPublicKey) { continue }
// Send a closed group update message to all members using established channels val closedGroupControlMessage = ClosedGroupControlMessage(closedGroupUpdateKind)
val promises = mutableListOf<Promise<Unit, Exception>>() sendNonDurably(closedGroupControlMessage, Address.fromSerialized(groupID)).get()
for (member in members) { }
if (member == userPublicKey) { continue } // Add the group to the user's set of public keys to poll for
val closedGroupUpdateKind = ClosedGroupUpdate.Kind.New(Hex.fromStringCondensed(groupPublicKey), name, groupKeyPair.privateKey.serialize(), storage.addClosedGroupPublicKey(groupPublicKey)
senderKeys, membersAsData, adminsAsData) // Store the encryption key pair
val closedGroupUpdate = ClosedGroupUpdate() storage.addClosedGroupEncryptionKeyPair(encryptionKeyPair, groupPublicKey)
closedGroupUpdate.kind = closedGroupUpdateKind // Notify the user
val address = Address.fromSerialized(member) val threadID = storage.getOrCreateThreadIdFor(Address.fromSerialized(groupID))
val promise = MessageSender.sendNonDurably(closedGroupUpdate, address) storage.insertOutgoingInfoMessage(context, groupID, SignalServiceProtos.GroupContext.Type.UPDATE, name, members, admins, threadID)
promises.add(promise) // Notify the PN server
PushNotificationAPI.performOperation(PushNotificationAPI.ClosedGroupOperation.Subscribe, groupPublicKey, userPublicKey)
// Fulfill the promise
deferred.resolve(groupID)
} }
// Add the group to the user's set of public keys to poll for
MessagingConfiguration.shared.sskDatabase.setClosedGroupPrivateKey(groupPublicKey, groupKeyPair.hexEncodedPrivateKey)
// Notify the PN server
PushNotificationAPI.performOperation(PushNotificationAPI.ClosedGroupOperation.Subscribe, groupPublicKey, userPublicKey)
// Notify the user
val threadID =storage.getOrCreateThreadIdFor(Address.fromSerialized(groupID))
storage.insertOutgoingInfoMessage(context, groupID, SignalServiceProtos.GroupContext.Type.UPDATE, name, members, admins, threadID)
// Fulfill the promise
deferred.resolve(groupPublicKey)
// Return // Return
return deferred.promise return deferred.promise
} }

Loading…
Cancel
Save