Apply conversation config on messages being converted to protobuf

This commit is contained in:
charles 2022-12-22 19:33:33 +11:00
parent cdbf76c0f1
commit b1f69539a9
11 changed files with 38 additions and 34 deletions

View File

@ -39,16 +39,16 @@ abstract class Message {
dataMessage.group = groupProto.build()
}
fun setExpirationConfigurationIfNeeded(builder: SignalServiceProtos.Content.Builder) {
val config = threadID?.let { MessagingModuleConfiguration.shared.storage.getExpirationConfiguration(it) }
fun SignalServiceProtos.Content.Builder.setExpirationConfigurationIfNeeded(threadId: Long?) {
val config = threadId?.let { MessagingModuleConfiguration.shared.storage.getExpirationConfiguration(it) }
?: run {
builder.expirationTimer = 0
expirationTimer = 0
return
}
builder.expirationTimer = config.durationSeconds
builder.lastDisappearingMessageChangeTimestamp = config.updatedTimestampMs
expirationTimer = config.durationSeconds
lastDisappearingMessageChangeTimestamp = config.updatedTimestampMs
if (config.isEnabled) {
builder.expirationType = config.expirationType
expirationType = config.expirationType
}
}
}

View File

@ -82,7 +82,7 @@ class CallMessage(): ControlMessage() {
.setUuid(callId!!.toString())
val content = SignalServiceProtos.Content.newBuilder()
setExpirationConfigurationIfNeeded(content)
content.setExpirationConfigurationIfNeeded(threadID)
return content
.setCallMessage(callMessage)

View File

@ -1,18 +1,21 @@
package org.session.libsession.messaging.messages.control
import com.google.protobuf.ByteString
import org.session.libsession.messaging.MessagingModuleConfiguration
import org.session.libsession.utilities.Address
import org.session.libsignal.crypto.ecc.DjbECPrivateKey
import org.session.libsignal.crypto.ecc.DjbECPublicKey
import org.session.libsignal.crypto.ecc.ECKeyPair
import org.session.libsignal.protos.SignalServiceProtos
import org.session.libsignal.protos.SignalServiceProtos.DataMessage
import org.session.libsignal.utilities.removingIdPrefixIfNeeded
import org.session.libsignal.utilities.toHexString
import org.session.libsignal.utilities.Hex
import org.session.libsignal.utilities.Log
import org.session.libsignal.utilities.removingIdPrefixIfNeeded
import org.session.libsignal.utilities.toHexString
class ClosedGroupControlMessage() : ControlMessage() {
var kind: Kind? = null
var groupID: String? = null
override val defaultTtl: Long get() {
return when (kind) {
@ -118,8 +121,9 @@ class ClosedGroupControlMessage() : ControlMessage() {
}
}
internal constructor(kind: Kind?) : this() {
internal constructor(kind: Kind?, groupID: String? = null) : this() {
this.kind = kind
this.groupID = groupID
}
override fun toProto(): SignalServiceProtos.Content? {
@ -167,11 +171,12 @@ class ClosedGroupControlMessage() : ControlMessage() {
val contentProto = SignalServiceProtos.Content.newBuilder()
val dataMessageProto = DataMessage.newBuilder()
dataMessageProto.closedGroupControlMessage = closedGroupControlMessage.build()
// Expiration timer
setExpirationConfigurationIfNeeded(contentProto)
// Group context
setGroupContext(dataMessageProto)
contentProto.dataMessage = dataMessageProto.build()
// Expiration timer
val threadId = groupID?.let { MessagingModuleConfiguration.shared.storage.getOrCreateThreadIdFor(Address.fromSerialized(it)) }
contentProto.setExpirationConfigurationIfNeeded(threadId)
return contentProto.build()
} catch (e: Exception) {
Log.w(TAG, "Couldn't construct closed group control message proto from: $this.")

View File

@ -64,7 +64,7 @@ class DataExtractionNotification() : ControlMessage() {
}
val contentProto = SignalServiceProtos.Content.newBuilder()
contentProto.dataExtractionNotification = dataExtractionNotification.build()
setExpirationConfigurationIfNeeded(contentProto)
contentProto.setExpirationConfigurationIfNeeded(threadID)
return contentProto.build()
} catch (e: Exception) {
Log.w(TAG, "Couldn't construct data extraction notification proto from: $this")

View File

@ -64,7 +64,7 @@ class ExpirationTimerUpdate() : ControlMessage() {
val contentProto = SignalServiceProtos.Content.newBuilder()
return try {
contentProto.dataMessage = dataMessageProto.build()
setExpirationConfigurationIfNeeded(contentProto)
contentProto.setExpirationConfigurationIfNeeded(threadID)
contentProto.build()
} catch (e: Exception) {
Log.w(TAG, "Couldn't construct expiration timer update proto from: $this")

View File

@ -13,7 +13,7 @@ class MessageRequestResponse(val isApproved: Boolean) : ControlMessage() {
val contentProto = SignalServiceProtos.Content.newBuilder()
return try {
contentProto.messageRequestResponse = messageRequestResponseProto.build()
setExpirationConfigurationIfNeeded(contentProto)
contentProto.setExpirationConfigurationIfNeeded(threadID)
contentProto.build()
} catch (e: Exception) {
Log.w(TAG, "Couldn't construct message request response proto from: $this")

View File

@ -41,7 +41,7 @@ class ReadReceipt() : ControlMessage() {
val contentProto = SignalServiceProtos.Content.newBuilder()
return try {
contentProto.receiptMessage = receiptProto.build()
setExpirationConfigurationIfNeeded(contentProto)
contentProto.setExpirationConfigurationIfNeeded(threadID)
contentProto.build()
} catch (e: Exception) {
Log.w(TAG, "Couldn't construct read receipt proto from: $this")

View File

@ -60,7 +60,7 @@ class TypingIndicator() : ControlMessage() {
val contentProto = SignalServiceProtos.Content.newBuilder()
return try {
contentProto.typingMessage = typingIndicatorProto.build()
setExpirationConfigurationIfNeeded(contentProto)
contentProto.setExpirationConfigurationIfNeeded(threadID)
contentProto.build()
} catch (e: Exception) {
Log.w(TAG, "Couldn't construct typing indicator proto from: $this")

View File

@ -45,7 +45,7 @@ class UnsendRequest(): ControlMessage() {
val contentProto = SignalServiceProtos.Content.newBuilder()
return try {
contentProto.unsendRequest = unsendRequestProto.build()
setExpirationConfigurationIfNeeded(contentProto)
contentProto.setExpirationConfigurationIfNeeded(threadID)
contentProto.build()
} catch (e: Exception) {
Log.w(TAG, "Couldn't construct unsend request proto from: $this")

View File

@ -116,7 +116,7 @@ class VisibleMessage : Message() {
dataMessage.addAllAttachments(pointers)
// TODO: Contact
// Expiration timer
setExpirationConfigurationIfNeeded(proto)
proto.setExpirationConfigurationIfNeeded(threadID)
// Group context
val storage = MessagingModuleConfiguration.shared.storage
if (storage.isClosedGroup(recipient!!)) {

View File

@ -15,18 +15,17 @@ 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.TextSecurePreferences
import org.session.libsession.utilities.recipients.Recipient
import org.session.libsignal.crypto.ecc.Curve
import org.session.libsignal.crypto.ecc.ECKeyPair
import org.session.libsignal.utilities.guava.Optional
import org.session.libsignal.messages.SignalServiceGroup
import org.session.libsignal.protos.SignalServiceProtos
import org.session.libsignal.utilities.Hex
import org.session.libsignal.utilities.Log
import org.session.libsignal.utilities.ThreadUtils
import org.session.libsignal.utilities.guava.Optional
import org.session.libsignal.utilities.hexEncodedPublicKey
import org.session.libsignal.utilities.removingIdPrefixIfNeeded
import org.session.libsignal.utilities.Hex
import org.session.libsignal.utilities.ThreadUtils
import org.session.libsignal.utilities.Log
import java.util.*
import java.util.LinkedList
import java.util.concurrent.ConcurrentHashMap
const val groupSizeLimit = 100
@ -49,14 +48,14 @@ fun MessageSender.create(name: String, members: Collection<String>): Promise<Str
val groupID = GroupUtil.doubleEncodeGroupID(groupPublicKey)
val admins = setOf( userPublicKey )
val adminsAsData = admins.map { ByteString.copyFrom(Hex.fromStringCondensed(it)) }
storage.createGroup(groupID, name, LinkedList(members.map { Address.fromSerialized(it) }),
storage.createGroup(groupID, name, LinkedList(members.map { fromSerialized(it) }),
null, null, LinkedList(admins.map { Address.fromSerialized(it) }), System.currentTimeMillis())
storage.setProfileSharing(Address.fromSerialized(groupID), true)
// Send a closed group update message to all members individually
val closedGroupUpdateKind = ClosedGroupControlMessage.Kind.New(ByteString.copyFrom(Hex.fromStringCondensed(groupPublicKey)), name, encryptionKeyPair, membersAsData, adminsAsData, 0)
val sentTime = System.currentTimeMillis() + SnodeAPI.clockOffset
for (member in members) {
val closedGroupControlMessage = ClosedGroupControlMessage(closedGroupUpdateKind)
val closedGroupControlMessage = ClosedGroupControlMessage(closedGroupUpdateKind, groupID)
closedGroupControlMessage.sentTimestamp = sentTime
try {
sendNonDurably(closedGroupControlMessage, Address.fromSerialized(member)).get()
@ -115,7 +114,7 @@ fun MessageSender.setName(groupPublicKey: String, newName: String) {
// Send the update to the group
val kind = ClosedGroupControlMessage.Kind.NameChange(newName)
val sentTime = System.currentTimeMillis() + SnodeAPI.clockOffset
val closedGroupControlMessage = ClosedGroupControlMessage(kind)
val closedGroupControlMessage = ClosedGroupControlMessage(kind, groupID)
closedGroupControlMessage.sentTimestamp = sentTime
send(closedGroupControlMessage, Address.fromSerialized(groupID))
// Update the group
@ -155,13 +154,13 @@ fun MessageSender.addMembers(groupPublicKey: String, membersToAdd: List<String>)
// Send the update to the group
val memberUpdateKind = ClosedGroupControlMessage.Kind.MembersAdded(newMembersAsData)
val sentTime = System.currentTimeMillis() + SnodeAPI.clockOffset
val closedGroupControlMessage = ClosedGroupControlMessage(memberUpdateKind)
val closedGroupControlMessage = ClosedGroupControlMessage(memberUpdateKind, groupID)
closedGroupControlMessage.sentTimestamp = sentTime
send(closedGroupControlMessage, Address.fromSerialized(groupID))
// Send closed group update messages to any new members individually
for (member in membersToAdd) {
val closedGroupNewKind = ClosedGroupControlMessage.Kind.New(ByteString.copyFrom(Hex.fromStringCondensed(groupPublicKey)), name, encryptionKeyPair, membersAsData, adminsAsData, expireTimer)
val closedGroupControlMessage = ClosedGroupControlMessage(closedGroupNewKind)
val closedGroupControlMessage = ClosedGroupControlMessage(closedGroupNewKind, groupID)
// It's important that the sent timestamp of this message is greater than the sent timestamp
// of the `MembersAdded` message above. The reason is that upon receiving this `New` message,
// the recipient will update the closed group formation timestamp and ignore any closed group
@ -210,7 +209,7 @@ fun MessageSender.removeMembers(groupPublicKey: String, membersToRemove: List<St
// Send the update to the group
val memberUpdateKind = ClosedGroupControlMessage.Kind.MembersRemoved(removeMembersAsData)
val sentTime = System.currentTimeMillis() + SnodeAPI.clockOffset
val closedGroupControlMessage = ClosedGroupControlMessage(memberUpdateKind)
val closedGroupControlMessage = ClosedGroupControlMessage(memberUpdateKind, groupID)
closedGroupControlMessage.sentTimestamp = sentTime
send(closedGroupControlMessage, Address.fromSerialized(groupID))
// Send the new encryption key pair to the remaining group members.
@ -239,7 +238,7 @@ fun MessageSender.leave(groupPublicKey: String, notifyUser: Boolean = true): Pro
val admins = group.admins.map { it.serialize() }
val name = group.title
// Send the update to the group
val closedGroupControlMessage = ClosedGroupControlMessage(ClosedGroupControlMessage.Kind.MemberLeft())
val closedGroupControlMessage = ClosedGroupControlMessage(ClosedGroupControlMessage.Kind.MemberLeft(), groupID)
val sentTime = System.currentTimeMillis() + SnodeAPI.clockOffset
closedGroupControlMessage.sentTimestamp = sentTime
storage.setActive(groupID, false)
@ -300,7 +299,7 @@ fun MessageSender.sendEncryptionKeyPair(groupPublicKey: String, newKeyPair: ECKe
}
val kind = ClosedGroupControlMessage.Kind.EncryptionKeyPair(ByteString.copyFrom(Hex.fromStringCondensed(groupPublicKey)), wrappers)
val sentTime = System.currentTimeMillis() + SnodeAPI.clockOffset
val closedGroupControlMessage = ClosedGroupControlMessage(kind)
val closedGroupControlMessage = ClosedGroupControlMessage(kind, null)
closedGroupControlMessage.sentTimestamp = sentTime
return if (force) {
MessageSender.sendNonDurably(closedGroupControlMessage, Address.fromSerialized(destination))
@ -334,6 +333,6 @@ fun MessageSender.sendLatestEncryptionKeyPair(publicKey: String, groupPublicKey:
Log.d("Loki", "Sending latest encryption key pair to: $publicKey.")
val wrapper = ClosedGroupControlMessage.KeyPairWrapper(publicKey, ByteString.copyFrom(ciphertext))
val kind = ClosedGroupControlMessage.Kind.EncryptionKeyPair(ByteString.copyFrom(Hex.fromStringCondensed(groupPublicKey)), listOf(wrapper))
val closedGroupControlMessage = ClosedGroupControlMessage(kind)
val closedGroupControlMessage = ClosedGroupControlMessage(kind, groupID)
MessageSender.send(closedGroupControlMessage, Address.fromSerialized(publicKey))
}