mirror of
https://github.com/oxen-io/session-android.git
synced 2024-11-27 12:05:22 +00:00
handle expiration timer with NEW group update type
This commit is contained in:
parent
534e0e8e69
commit
3b03aef80f
@ -428,6 +428,11 @@ class Storage(context: Context, helper: SQLCipherOpenHelper) : Database(context,
|
|||||||
DatabaseFactory.getLokiAPIDatabase(context).removeAllClosedGroupEncryptionKeyPairs(groupPublicKey)
|
DatabaseFactory.getLokiAPIDatabase(context).removeAllClosedGroupEncryptionKeyPairs(groupPublicKey)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun setExpirationTimer(groupID: String, duration: Int) {
|
||||||
|
val recipient = Recipient.from(context, fromSerialized(groupID), false)
|
||||||
|
DatabaseFactory.getRecipientDatabase(context).setExpireMessages(recipient, duration);
|
||||||
|
}
|
||||||
|
|
||||||
override fun getAllV2OpenGroups(): Map<Long, OpenGroupV2> {
|
override fun getAllV2OpenGroups(): Map<Long, OpenGroupV2> {
|
||||||
return DatabaseFactory.getLokiThreadDatabase(context).getAllV2OpenGroups()
|
return DatabaseFactory.getLokiThreadDatabase(context).getAllV2OpenGroups()
|
||||||
}
|
}
|
||||||
|
@ -115,6 +115,7 @@ interface StorageProtocol {
|
|||||||
fun isClosedGroup(publicKey: String): Boolean
|
fun isClosedGroup(publicKey: String): Boolean
|
||||||
fun getClosedGroupEncryptionKeyPairs(groupPublicKey: String): MutableList<ECKeyPair>
|
fun getClosedGroupEncryptionKeyPairs(groupPublicKey: String): MutableList<ECKeyPair>
|
||||||
fun getLatestClosedGroupEncryptionKeyPair(groupPublicKey: String): ECKeyPair?
|
fun getLatestClosedGroupEncryptionKeyPair(groupPublicKey: String): ECKeyPair?
|
||||||
|
fun setExpirationTimer(groupID: String, duration: Int)
|
||||||
|
|
||||||
// Groups
|
// Groups
|
||||||
fun getAllGroups(): List<GroupRecord>
|
fun getAllGroups(): List<GroupRecord>
|
||||||
|
@ -34,6 +34,7 @@ class ClosedGroupControlMessage() : ControlMessage() {
|
|||||||
is Kind.New -> {
|
is Kind.New -> {
|
||||||
!kind.publicKey.isEmpty && kind.name.isNotEmpty() && kind.encryptionKeyPair?.publicKey != null
|
!kind.publicKey.isEmpty && kind.name.isNotEmpty() && kind.encryptionKeyPair?.publicKey != null
|
||||||
&& kind.encryptionKeyPair?.privateKey != null && kind.members.isNotEmpty() && kind.admins.isNotEmpty()
|
&& kind.encryptionKeyPair?.privateKey != null && kind.members.isNotEmpty() && kind.admins.isNotEmpty()
|
||||||
|
&& kind.expireTimer >= 0
|
||||||
}
|
}
|
||||||
is Kind.EncryptionKeyPair -> true
|
is Kind.EncryptionKeyPair -> true
|
||||||
is Kind.NameChange -> kind.name.isNotEmpty()
|
is Kind.NameChange -> kind.name.isNotEmpty()
|
||||||
@ -44,8 +45,8 @@ class ClosedGroupControlMessage() : ControlMessage() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
sealed class Kind {
|
sealed class Kind {
|
||||||
class New(var publicKey: ByteString, var name: String, var encryptionKeyPair: ECKeyPair?, var members: List<ByteString>, var admins: List<ByteString>) : Kind() {
|
class New(var publicKey: ByteString, var name: String, var encryptionKeyPair: ECKeyPair?, var members: List<ByteString>, var admins: List<ByteString>, var expireTimer: Int) : Kind() {
|
||||||
internal constructor() : this(ByteString.EMPTY, "", null, listOf(), listOf())
|
internal constructor() : this(ByteString.EMPTY, "", null, listOf(), listOf(), 0)
|
||||||
}
|
}
|
||||||
/** An encryption key pair encrypted for each member individually.
|
/** An encryption key pair encrypted for each member individually.
|
||||||
*
|
*
|
||||||
@ -88,10 +89,11 @@ class ClosedGroupControlMessage() : ControlMessage() {
|
|||||||
val publicKey = closedGroupControlMessageProto.publicKey ?: return null
|
val publicKey = closedGroupControlMessageProto.publicKey ?: return null
|
||||||
val name = closedGroupControlMessageProto.name ?: return null
|
val name = closedGroupControlMessageProto.name ?: return null
|
||||||
val encryptionKeyPairAsProto = closedGroupControlMessageProto.encryptionKeyPair ?: return null
|
val encryptionKeyPairAsProto = closedGroupControlMessageProto.encryptionKeyPair ?: return null
|
||||||
|
val expireTimer = closedGroupControlMessageProto.expireTimer
|
||||||
try {
|
try {
|
||||||
val encryptionKeyPair = ECKeyPair(DjbECPublicKey(encryptionKeyPairAsProto.publicKey.toByteArray()),
|
val encryptionKeyPair = ECKeyPair(DjbECPublicKey(encryptionKeyPairAsProto.publicKey.toByteArray()),
|
||||||
DjbECPrivateKey(encryptionKeyPairAsProto.privateKey.toByteArray()))
|
DjbECPrivateKey(encryptionKeyPairAsProto.privateKey.toByteArray()))
|
||||||
kind = Kind.New(publicKey, name, encryptionKeyPair, closedGroupControlMessageProto.membersList, closedGroupControlMessageProto.adminsList)
|
kind = Kind.New(publicKey, name, encryptionKeyPair, closedGroupControlMessageProto.membersList, closedGroupControlMessageProto.adminsList, expireTimer)
|
||||||
} catch (e: Exception) {
|
} catch (e: Exception) {
|
||||||
Log.w(TAG, "Couldn't parse key pair from proto: $encryptionKeyPairAsProto.")
|
Log.w(TAG, "Couldn't parse key pair from proto: $encryptionKeyPairAsProto.")
|
||||||
return null
|
return null
|
||||||
@ -140,9 +142,10 @@ class ClosedGroupControlMessage() : ControlMessage() {
|
|||||||
val encryptionKeyPair = SignalServiceProtos.KeyPair.newBuilder()
|
val encryptionKeyPair = SignalServiceProtos.KeyPair.newBuilder()
|
||||||
encryptionKeyPair.publicKey = ByteString.copyFrom(kind.encryptionKeyPair!!.publicKey.serialize().removing05PrefixIfNeeded())
|
encryptionKeyPair.publicKey = ByteString.copyFrom(kind.encryptionKeyPair!!.publicKey.serialize().removing05PrefixIfNeeded())
|
||||||
encryptionKeyPair.privateKey = ByteString.copyFrom(kind.encryptionKeyPair!!.privateKey.serialize())
|
encryptionKeyPair.privateKey = ByteString.copyFrom(kind.encryptionKeyPair!!.privateKey.serialize())
|
||||||
closedGroupControlMessage.encryptionKeyPair = encryptionKeyPair.build()
|
closedGroupControlMessage.encryptionKeyPair = encryptionKeyPair.build()
|
||||||
closedGroupControlMessage.addAllMembers(kind.members)
|
closedGroupControlMessage.addAllMembers(kind.members)
|
||||||
closedGroupControlMessage.addAllAdmins(kind.admins)
|
closedGroupControlMessage.addAllAdmins(kind.admins)
|
||||||
|
closedGroupControlMessage.expireTimer = kind.expireTimer
|
||||||
}
|
}
|
||||||
is Kind.EncryptionKeyPair -> {
|
is Kind.EncryptionKeyPair -> {
|
||||||
closedGroupControlMessage.type = DataMessage.ClosedGroupControlMessage.Type.ENCRYPTION_KEY_PAIR
|
closedGroupControlMessage.type = DataMessage.ClosedGroupControlMessage.Type.ENCRYPTION_KEY_PAIR
|
||||||
|
@ -11,8 +11,10 @@ import org.session.libsession.messaging.sending_receiving.MessageSender.Error
|
|||||||
import org.session.libsession.messaging.sending_receiving.notifications.PushNotificationAPI
|
import org.session.libsession.messaging.sending_receiving.notifications.PushNotificationAPI
|
||||||
import org.session.libsession.messaging.sending_receiving.pollers.ClosedGroupPollerV2
|
import org.session.libsession.messaging.sending_receiving.pollers.ClosedGroupPollerV2
|
||||||
import org.session.libsession.utilities.Address
|
import org.session.libsession.utilities.Address
|
||||||
|
import org.session.libsession.utilities.Address.Companion.fromSerialized
|
||||||
import org.session.libsession.utilities.GroupUtil
|
import org.session.libsession.utilities.GroupUtil
|
||||||
import org.session.libsession.utilities.TextSecurePreferences
|
import org.session.libsession.utilities.TextSecurePreferences
|
||||||
|
import org.session.libsession.utilities.recipients.Recipient
|
||||||
import org.session.libsignal.crypto.ecc.Curve
|
import org.session.libsignal.crypto.ecc.Curve
|
||||||
import org.session.libsignal.crypto.ecc.ECKeyPair
|
import org.session.libsignal.crypto.ecc.ECKeyPair
|
||||||
import org.session.libsignal.utilities.guava.Optional
|
import org.session.libsignal.utilities.guava.Optional
|
||||||
@ -50,7 +52,7 @@ fun MessageSender.create(name: String, members: Collection<String>): Promise<Str
|
|||||||
null, null, LinkedList(admins.map { Address.fromSerialized(it) }), System.currentTimeMillis())
|
null, null, LinkedList(admins.map { Address.fromSerialized(it) }), System.currentTimeMillis())
|
||||||
storage.setProfileSharing(Address.fromSerialized(groupID), true)
|
storage.setProfileSharing(Address.fromSerialized(groupID), true)
|
||||||
// Send a closed group update message to all members individually
|
// Send a closed group update message to all members individually
|
||||||
val closedGroupUpdateKind = ClosedGroupControlMessage.Kind.New(ByteString.copyFrom(Hex.fromStringCondensed(groupPublicKey)), name, encryptionKeyPair, membersAsData, adminsAsData)
|
val closedGroupUpdateKind = ClosedGroupControlMessage.Kind.New(ByteString.copyFrom(Hex.fromStringCondensed(groupPublicKey)), name, encryptionKeyPair, membersAsData, adminsAsData, 0)
|
||||||
val sentTime = System.currentTimeMillis()
|
val sentTime = System.currentTimeMillis()
|
||||||
for (member in members) {
|
for (member in members) {
|
||||||
val closedGroupControlMessage = ClosedGroupControlMessage(closedGroupUpdateKind)
|
val closedGroupControlMessage = ClosedGroupControlMessage(closedGroupUpdateKind)
|
||||||
@ -131,6 +133,9 @@ fun MessageSender.addMembers(groupPublicKey: String, membersToAdd: List<String>)
|
|||||||
Log.d("Loki", "Can't add members to nonexistent closed group.")
|
Log.d("Loki", "Can't add members to nonexistent closed group.")
|
||||||
throw Error.NoThread
|
throw Error.NoThread
|
||||||
}
|
}
|
||||||
|
// Get expiration timer value for the group
|
||||||
|
val recipient = Recipient.from(context, fromSerialized(groupID), false)
|
||||||
|
val expireTimer = recipient.expireMessages
|
||||||
if (membersToAdd.isEmpty()) {
|
if (membersToAdd.isEmpty()) {
|
||||||
Log.d("Loki", "Invalid closed group update.")
|
Log.d("Loki", "Invalid closed group update.")
|
||||||
throw Error.InvalidClosedGroupUpdate
|
throw Error.InvalidClosedGroupUpdate
|
||||||
@ -155,7 +160,7 @@ fun MessageSender.addMembers(groupPublicKey: String, membersToAdd: List<String>)
|
|||||||
send(closedGroupControlMessage, Address.fromSerialized(groupID))
|
send(closedGroupControlMessage, Address.fromSerialized(groupID))
|
||||||
// Send closed group update messages to any new members individually
|
// Send closed group update messages to any new members individually
|
||||||
for (member in membersToAdd) {
|
for (member in membersToAdd) {
|
||||||
val closedGroupNewKind = ClosedGroupControlMessage.Kind.New(ByteString.copyFrom(Hex.fromStringCondensed(groupPublicKey)), name, encryptionKeyPair, membersAsData, adminsAsData)
|
val closedGroupNewKind = ClosedGroupControlMessage.Kind.New(ByteString.copyFrom(Hex.fromStringCondensed(groupPublicKey)), name, encryptionKeyPair, membersAsData, adminsAsData, expireTimer)
|
||||||
val closedGroupControlMessage = ClosedGroupControlMessage(closedGroupNewKind)
|
val closedGroupControlMessage = ClosedGroupControlMessage(closedGroupNewKind)
|
||||||
closedGroupControlMessage.sentTimestamp = sentTime
|
closedGroupControlMessage.sentTimestamp = sentTime
|
||||||
send(closedGroupControlMessage, Address.fromSerialized(member))
|
send(closedGroupControlMessage, Address.fromSerialized(member))
|
||||||
|
@ -121,7 +121,7 @@ private fun handleConfigurationMessage(message: ConfigurationMessage) {
|
|||||||
for (closedGroup in message.closedGroups) {
|
for (closedGroup in message.closedGroups) {
|
||||||
if (allClosedGroupPublicKeys.contains(closedGroup.publicKey)) continue
|
if (allClosedGroupPublicKeys.contains(closedGroup.publicKey)) continue
|
||||||
handleNewClosedGroup(message.sender!!, message.sentTimestamp!!, closedGroup.publicKey, closedGroup.name,
|
handleNewClosedGroup(message.sender!!, message.sentTimestamp!!, closedGroup.publicKey, closedGroup.name,
|
||||||
closedGroup.encryptionKeyPair!!, closedGroup.members, closedGroup.admins, message.sentTimestamp!!)
|
closedGroup.encryptionKeyPair!!, closedGroup.members, closedGroup.admins, message.sentTimestamp!!, 0)
|
||||||
}
|
}
|
||||||
val allV2OpenGroups = storage.getAllV2OpenGroups().map { it.value.joinURL }
|
val allV2OpenGroups = storage.getAllV2OpenGroups().map { it.value.joinURL }
|
||||||
for (openGroup in message.openGroups) {
|
for (openGroup in message.openGroups) {
|
||||||
@ -256,10 +256,11 @@ private fun MessageReceiver.handleNewClosedGroup(message: ClosedGroupControlMess
|
|||||||
val groupPublicKey = kind.publicKey.toByteArray().toHexString()
|
val groupPublicKey = kind.publicKey.toByteArray().toHexString()
|
||||||
val members = kind.members.map { it.toByteArray().toHexString() }
|
val members = kind.members.map { it.toByteArray().toHexString() }
|
||||||
val admins = kind.admins.map { it.toByteArray().toHexString() }
|
val admins = kind.admins.map { it.toByteArray().toHexString() }
|
||||||
handleNewClosedGroup(message.sender!!, message.sentTimestamp!!, groupPublicKey, kind.name, kind.encryptionKeyPair!!, members, admins, message.sentTimestamp!!)
|
val expireTimer = kind.expireTimer
|
||||||
|
handleNewClosedGroup(message.sender!!, message.sentTimestamp!!, groupPublicKey, kind.name, kind.encryptionKeyPair!!, members, admins, message.sentTimestamp!!, expireTimer)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun handleNewClosedGroup(sender: String, sentTimestamp: Long, groupPublicKey: String, name: String, encryptionKeyPair: ECKeyPair, members: List<String>, admins: List<String>, formationTimestamp: Long) {
|
private fun handleNewClosedGroup(sender: String, sentTimestamp: Long, groupPublicKey: String, name: String, encryptionKeyPair: ECKeyPair, members: List<String>, admins: List<String>, formationTimestamp: Long, expireTimer: Int) {
|
||||||
val context = MessagingModuleConfiguration.shared.context
|
val context = MessagingModuleConfiguration.shared.context
|
||||||
val storage = MessagingModuleConfiguration.shared.storage
|
val storage = MessagingModuleConfiguration.shared.storage
|
||||||
// Create the group
|
// Create the group
|
||||||
@ -289,6 +290,8 @@ private fun handleNewClosedGroup(sender: String, sentTimestamp: Long, groupPubli
|
|||||||
storage.addClosedGroupPublicKey(groupPublicKey)
|
storage.addClosedGroupPublicKey(groupPublicKey)
|
||||||
// Store the encryption key pair
|
// Store the encryption key pair
|
||||||
storage.addClosedGroupEncryptionKeyPair(encryptionKeyPair, groupPublicKey)
|
storage.addClosedGroupEncryptionKeyPair(encryptionKeyPair, groupPublicKey)
|
||||||
|
// Set expiration timer
|
||||||
|
storage.setExpirationTimer(groupID, expireTimer)
|
||||||
// Notify the PN server
|
// Notify the PN server
|
||||||
PushNotificationAPI.performOperation(PushNotificationAPI.ClosedGroupOperation.Subscribe, groupPublicKey, storage.getUserPublicKey()!!)
|
PushNotificationAPI.performOperation(PushNotificationAPI.ClosedGroupOperation.Subscribe, groupPublicKey, storage.getUserPublicKey()!!)
|
||||||
// Start polling
|
// Start polling
|
||||||
|
Loading…
Reference in New Issue
Block a user