Convert SignalService, Database, Group, Payment, and other remaining protos to wire.

This commit is contained in:
Cody Henthorne
2023-09-18 15:32:43 -04:00
committed by Alex Hart
parent a6b7d0bcc5
commit efbd5cab85
267 changed files with 7100 additions and 7214 deletions

View File

@@ -293,22 +293,22 @@ class GroupTableTest {
private fun insertPushGroup(
members: List<DecryptedMember> = listOf(
DecryptedMember.newBuilder()
.setAciBytes(harness.self.requireAci().toByteString())
.setJoinedAtRevision(0)
.setRole(Member.Role.DEFAULT)
DecryptedMember.Builder()
.aciBytes(harness.self.requireAci().toByteString())
.joinedAtRevision(0)
.role(Member.Role.DEFAULT)
.build(),
DecryptedMember.newBuilder()
.setAciBytes(Recipient.resolved(harness.others[0]).requireAci().toByteString())
.setJoinedAtRevision(0)
.setRole(Member.Role.DEFAULT)
DecryptedMember.Builder()
.aciBytes(Recipient.resolved(harness.others[0]).requireAci().toByteString())
.joinedAtRevision(0)
.role(Member.Role.DEFAULT)
.build()
)
): GroupId {
val groupMasterKey = GroupMasterKey(Random.nextBytes(GroupMasterKey.SIZE))
val decryptedGroupState = DecryptedGroup.newBuilder()
.addAllMembers(members)
.setRevision(0)
val decryptedGroupState = DecryptedGroup.Builder()
.members(members)
.revision(0)
.build()
return groupTable.create(groupMasterKey, decryptedGroupState)!!
@@ -317,23 +317,23 @@ class GroupTableTest {
private fun insertPushGroupWithSelfAndOthers(others: List<RecipientId>): GroupId {
val groupMasterKey = GroupMasterKey(Random.nextBytes(GroupMasterKey.SIZE))
val selfMember: DecryptedMember = DecryptedMember.newBuilder()
.setAciBytes(harness.self.requireAci().toByteString())
.setJoinedAtRevision(0)
.setRole(Member.Role.DEFAULT)
val selfMember: DecryptedMember = DecryptedMember.Builder()
.aciBytes(harness.self.requireAci().toByteString())
.joinedAtRevision(0)
.role(Member.Role.DEFAULT)
.build()
val otherMembers: List<DecryptedMember> = others.map { id ->
DecryptedMember.newBuilder()
.setAciBytes(Recipient.resolved(id).requireAci().toByteString())
.setJoinedAtRevision(0)
.setRole(Member.Role.DEFAULT)
DecryptedMember.Builder()
.aciBytes(Recipient.resolved(id).requireAci().toByteString())
.joinedAtRevision(0)
.role(Member.Role.DEFAULT)
.build()
}
val decryptedGroupState = DecryptedGroup.newBuilder()
.addAllMembers(listOf(selfMember) + otherMembers)
.setRevision(0)
val decryptedGroupState = DecryptedGroup.Builder()
.members(listOf(selfMember) + otherMembers)
.revision(0)
.build()
return groupTable.create(groupMasterKey, decryptedGroupState)!!

View File

@@ -48,7 +48,7 @@ class MessageTableTest_gifts {
val messageId = MmsHelper.insert(
recipient = Recipient.resolved(recipients[0]),
sentTimeMillis = 1,
giftBadge = GiftBadge.getDefaultInstance()
giftBadge = GiftBadge()
)
val result = mms.setOutgoingGiftsRevealed(listOf(messageId))
@@ -62,7 +62,7 @@ class MessageTableTest_gifts {
val messageId = MmsHelper.insert(
recipient = Recipient.resolved(recipients[0]),
sentTimeMillis = 1,
giftBadge = GiftBadge.getDefaultInstance()
giftBadge = GiftBadge()
)
mms.setOutgoingGiftsRevealed(listOf(messageId))
@@ -76,13 +76,13 @@ class MessageTableTest_gifts {
val messageId = MmsHelper.insert(
recipient = Recipient.resolved(recipients[0]),
sentTimeMillis = 1,
giftBadge = GiftBadge.getDefaultInstance()
giftBadge = GiftBadge()
)
MmsHelper.insert(
recipient = Recipient.resolved(recipients[0]),
sentTimeMillis = 2,
giftBadge = GiftBadge.getDefaultInstance()
giftBadge = GiftBadge()
)
val result = mms.setOutgoingGiftsRevealed(listOf(messageId))
@@ -96,13 +96,13 @@ class MessageTableTest_gifts {
val messageId = MmsHelper.insert(
recipient = Recipient.resolved(recipients[0]),
sentTimeMillis = 1,
giftBadge = GiftBadge.getDefaultInstance()
giftBadge = GiftBadge()
)
val messageId2 = MmsHelper.insert(
recipient = Recipient.resolved(recipients[0]),
sentTimeMillis = 2,
giftBadge = GiftBadge.getDefaultInstance()
giftBadge = GiftBadge()
)
val result = mms.setOutgoingGiftsRevealed(listOf(messageId, messageId2))
@@ -115,13 +115,13 @@ class MessageTableTest_gifts {
val messageId = MmsHelper.insert(
recipient = Recipient.resolved(recipients[0]),
sentTimeMillis = 1,
giftBadge = GiftBadge.getDefaultInstance()
giftBadge = GiftBadge()
)
val messageId2 = MmsHelper.insert(
recipient = Recipient.resolved(recipients[0]),
sentTimeMillis = 2,
giftBadge = GiftBadge.getDefaultInstance()
giftBadge = GiftBadge()
)
MmsHelper.insert(
@@ -140,13 +140,13 @@ class MessageTableTest_gifts {
val messageId = MmsHelper.insert(
recipient = Recipient.resolved(recipients[0]),
sentTimeMillis = 1,
giftBadge = GiftBadge.getDefaultInstance()
giftBadge = GiftBadge()
)
val messageId2 = MmsHelper.insert(
recipient = Recipient.resolved(recipients[0]),
sentTimeMillis = 2,
giftBadge = GiftBadge.getDefaultInstance()
giftBadge = GiftBadge()
)
val messageId3 = MmsHelper.insert(
@@ -165,13 +165,13 @@ class MessageTableTest_gifts {
MmsHelper.insert(
recipient = Recipient.resolved(recipients[0]),
sentTimeMillis = 1,
giftBadge = GiftBadge.getDefaultInstance()
giftBadge = GiftBadge()
)
MmsHelper.insert(
recipient = Recipient.resolved(recipients[0]),
sentTimeMillis = 2,
giftBadge = GiftBadge.getDefaultInstance()
giftBadge = GiftBadge()
)
val messageId3 = MmsHelper.insert(

View File

@@ -1228,7 +1228,7 @@ class RecipientTableTest_getAndPossiblyMerge {
.use { cursor: Cursor ->
if (cursor.moveToFirst()) {
val bytes = Base64.decode(cursor.requireNonNullString(MessageTable.BODY))
ThreadMergeEvent.parseFrom(bytes)
ThreadMergeEvent.ADAPTER.decode(bytes)
} else {
null
}
@@ -1246,7 +1246,7 @@ class RecipientTableTest_getAndPossiblyMerge {
.use { cursor: Cursor ->
if (cursor.moveToFirst()) {
val bytes = Base64.decode(cursor.requireNonNullString(MessageTable.BODY))
SessionSwitchoverEvent.parseFrom(bytes)
SessionSwitchoverEvent.ADAPTER.decode(bytes)
} else {
null
}

View File

@@ -22,8 +22,9 @@ import org.thoughtcrime.securesms.testing.MessageContentFuzzer
import org.thoughtcrime.securesms.testing.SignalActivityRule
import org.thoughtcrime.securesms.testing.assertIs
import org.thoughtcrime.securesms.util.MessageTableTestUtils
import org.whispersystems.signalservice.internal.push.SignalServiceProtos
import org.whispersystems.signalservice.internal.push.SignalServiceProtos.EditMessage
import org.whispersystems.signalservice.internal.push.Content
import org.whispersystems.signalservice.internal.push.EditMessage
import org.whispersystems.signalservice.internal.push.SyncMessage
import kotlin.time.Duration.Companion.seconds
@RunWith(AndroidJUnit4::class)
@@ -67,16 +68,17 @@ class EditMessageSyncProcessorTest {
val content = MessageContentFuzzer.fuzzTextMessage()
val metadata = MessageContentFuzzer.envelopeMetadata(harness.self.id, toRecipient.id)
val syncContent = SignalServiceProtos.Content.newBuilder().setSyncMessage(
SignalServiceProtos.SyncMessage.newBuilder().setSent(
SignalServiceProtos.SyncMessage.Sent.newBuilder()
.setDestinationServiceId(metadata.destinationServiceId.toString())
.setTimestamp(originalTimestamp)
.setExpirationStartTimestamp(originalTimestamp)
.setMessage(content.dataMessage)
)
val syncContent = Content.Builder().syncMessage(
SyncMessage.Builder().sent(
SyncMessage.Sent.Builder()
.destinationServiceId(metadata.destinationServiceId.toString())
.timestamp(originalTimestamp)
.expirationStartTimestamp(originalTimestamp)
.message(content.dataMessage)
.build()
).build()
).build()
SignalDatabase.recipients.setExpireMessages(toRecipient.id, content.dataMessage.expireTimer)
SignalDatabase.recipients.setExpireMessages(toRecipient.id, content.dataMessage?.expireTimer ?: 0)
val syncTextMessage = TestMessage(
envelope = MessageContentFuzzer.envelope(originalTimestamp),
content = syncContent,
@@ -86,18 +88,20 @@ class EditMessageSyncProcessorTest {
val editTimestamp = originalTimestamp + 200
val editedContent = MessageContentFuzzer.fuzzTextMessage()
val editSyncContent = SignalServiceProtos.Content.newBuilder().setSyncMessage(
SignalServiceProtos.SyncMessage.newBuilder().setSent(
SignalServiceProtos.SyncMessage.Sent.newBuilder()
.setDestinationServiceId(metadata.destinationServiceId.toString())
.setTimestamp(editTimestamp)
.setExpirationStartTimestamp(editTimestamp)
.setEditMessage(
EditMessage.newBuilder()
.setDataMessage(editedContent.dataMessage)
.setTargetSentTimestamp(originalTimestamp)
val editSyncContent = Content.Builder().syncMessage(
SyncMessage.Builder().sent(
SyncMessage.Sent.Builder()
.destinationServiceId(metadata.destinationServiceId.toString())
.timestamp(editTimestamp)
.expirationStartTimestamp(editTimestamp)
.editMessage(
EditMessage.Builder()
.dataMessage(editedContent.dataMessage)
.targetSentTimestamp(originalTimestamp)
.build()
)
)
.build()
).build()
).build()
val syncEditMessage = TestMessage(
@@ -109,38 +113,38 @@ class EditMessageSyncProcessorTest {
testResult.runSync(listOf(syncTextMessage, syncEditMessage))
SignalDatabase.recipients.setExpireMessages(toRecipient.id, content.dataMessage.expireTimer / 1000)
SignalDatabase.recipients.setExpireMessages(toRecipient.id, (content.dataMessage?.expireTimer ?: 0) / 1000)
val originalTextMessage = OutgoingMessage(
threadRecipient = toRecipient,
sentTimeMillis = originalTimestamp,
body = content.dataMessage.body,
expiresIn = content.dataMessage.expireTimer.seconds.inWholeMilliseconds,
body = content.dataMessage?.body ?: "",
expiresIn = content.dataMessage?.expireTimer?.seconds?.inWholeMilliseconds ?: 0,
isUrgent = true,
isSecure = true,
bodyRanges = content.dataMessage.bodyRangesList.toBodyRangeList()
bodyRanges = content.dataMessage?.bodyRanges.toBodyRangeList()
)
val threadId = SignalDatabase.threads.getOrCreateThreadIdFor(toRecipient)
val originalMessageId = SignalDatabase.messages.insertMessageOutbox(originalTextMessage, threadId, false, null)
SignalDatabase.messages.markAsSent(originalMessageId, true)
if (content.dataMessage.expireTimer > 0) {
if ((content.dataMessage?.expireTimer ?: 0) > 0) {
SignalDatabase.messages.markExpireStarted(originalMessageId, originalTimestamp)
}
val editMessage = OutgoingMessage(
threadRecipient = toRecipient,
sentTimeMillis = editTimestamp,
body = editedContent.dataMessage.body,
expiresIn = content.dataMessage.expireTimer.seconds.inWholeMilliseconds,
body = editedContent.dataMessage?.body ?: "",
expiresIn = content.dataMessage?.expireTimer?.seconds?.inWholeMilliseconds ?: 0,
isUrgent = true,
isSecure = true,
bodyRanges = editedContent.dataMessage.bodyRangesList.toBodyRangeList(),
bodyRanges = editedContent.dataMessage?.bodyRanges.toBodyRangeList(),
messageToEdit = originalMessageId
)
val editMessageId = SignalDatabase.messages.insertMessageOutbox(editMessage, threadId, false, null)
SignalDatabase.messages.markAsSent(editMessageId, true)
if (content.dataMessage.expireTimer > 0) {
if ((content.dataMessage?.expireTimer ?: 0) > 0) {
SignalDatabase.messages.markExpireStarted(editMessageId, originalTimestamp)
}
testResult.collectLocal()
@@ -167,7 +171,7 @@ class EditMessageSyncProcessorTest {
fun runSync(messages: List<TestMessage>) {
messages.forEach { (envelope, content, metadata, serverDeliveredTimestamp) ->
if (content.hasSyncMessage()) {
if (content.syncMessage != null) {
processorV2.process(
envelope,
content,

View File

@@ -1,13 +1,13 @@
package org.thoughtcrime.securesms.messages
import androidx.test.ext.junit.runners.AndroidJUnit4
import okio.ByteString.Companion.toByteString
import org.junit.Before
import org.junit.Rule
import org.junit.Test
import org.junit.runner.RunWith
import org.thoughtcrime.securesms.database.GroupReceiptTable
import org.thoughtcrime.securesms.database.SignalDatabase
import org.thoughtcrime.securesms.database.model.toProtoByteString
import org.thoughtcrime.securesms.messages.SignalServiceProtoUtil.buildWith
import org.thoughtcrime.securesms.testing.GroupTestingUtils
import org.thoughtcrime.securesms.testing.GroupTestingUtils.asMember
@@ -15,8 +15,8 @@ import org.thoughtcrime.securesms.testing.MessageContentFuzzer
import org.thoughtcrime.securesms.testing.SignalActivityRule
import org.thoughtcrime.securesms.testing.assertIs
import org.thoughtcrime.securesms.util.MessageTableTestUtils
import org.whispersystems.signalservice.internal.push.SignalServiceProtos.DataMessage
import org.whispersystems.signalservice.internal.push.SignalServiceProtos.GroupContextV2
import org.whispersystems.signalservice.internal.push.DataMessage
import org.whispersystems.signalservice.internal.push.GroupContextV2
@Suppress("ClassName")
@RunWith(AndroidJUnit4::class)
@@ -41,9 +41,9 @@ class MessageContentProcessor__recipientStatusTest {
@Test
fun syncGroupSentTextMessageWithRecipientUpdateFollowup() {
val (groupId, masterKey, groupRecipientId) = GroupTestingUtils.insertGroup(revision = 0, harness.self.asMember(), harness.others[0].asMember(), harness.others[1].asMember())
val groupContextV2 = GroupContextV2.newBuilder().setRevision(0).setMasterKey(masterKey.serialize().toProtoByteString()).build()
val groupContextV2 = GroupContextV2.Builder().revision(0).masterKey(masterKey.serialize().toByteString()).build()
val initialTextMessage = DataMessage.newBuilder().buildWith {
val initialTextMessage = DataMessage.Builder().buildWith {
body = MessageContentFuzzer.string()
groupV2 = groupContextV2
timestamp = envelopeTimestamp

View File

@@ -6,7 +6,6 @@ import io.mockk.mockkObject
import io.mockk.mockkStatic
import io.mockk.unmockkStatic
import okio.ByteString
import okio.ByteString.Companion.toByteString
import org.junit.After
import org.junit.Before
import org.junit.Ignore
@@ -26,7 +25,7 @@ import org.thoughtcrime.securesms.testing.Entry
import org.thoughtcrime.securesms.testing.FakeClientHelpers
import org.thoughtcrime.securesms.testing.SignalActivityRule
import org.thoughtcrime.securesms.testing.awaitFor
import org.whispersystems.signalservice.internal.push.SignalServiceProtos.Envelope
import org.whispersystems.signalservice.internal.push.Envelope
import org.whispersystems.signalservice.internal.websocket.WebSocketMessage
import org.whispersystems.signalservice.internal.websocket.WebSocketRequestMessage
import java.util.regex.Pattern
@@ -93,7 +92,7 @@ class MessageProcessingPerformanceTest {
val messageCount = 100
val envelopes = generateInboundEnvelopes(bobClient, messageCount)
val firstTimestamp = envelopes.first().timestamp
val lastTimestamp = envelopes.last().timestamp
val lastTimestamp = envelopes.last().timestamp ?: 0
// Inject the envelopes into the websocket
Thread {
@@ -190,7 +189,7 @@ class MessageProcessingPerformanceTest {
path = "/api/v1/message",
id = Random(System.currentTimeMillis()).nextLong(),
headers = listOf("X-Signal-Timestamp: ${this.timestamp}"),
body = this.toByteArray().toByteString()
body = this.encodeByteString()
)
).encodeByteString()
}

View File

@@ -1,11 +1,12 @@
package org.thoughtcrime.securesms.messages
import org.whispersystems.signalservice.api.crypto.EnvelopeMetadata
import org.whispersystems.signalservice.internal.push.SignalServiceProtos
import org.whispersystems.signalservice.internal.push.Content
import org.whispersystems.signalservice.internal.push.Envelope
data class TestMessage(
val envelope: SignalServiceProtos.Envelope,
val content: SignalServiceProtos.Content,
val envelope: Envelope,
val content: Content,
val metadata: EnvelopeMetadata,
val serverDeliveredTimestamp: Long
)

View File

@@ -5,7 +5,8 @@ import org.signal.core.util.logging.Log
import org.thoughtcrime.securesms.testing.LogPredicate
import org.thoughtcrime.securesms.util.SignalLocalMetrics
import org.whispersystems.signalservice.api.crypto.EnvelopeMetadata
import org.whispersystems.signalservice.internal.push.SignalServiceProtos
import org.whispersystems.signalservice.internal.push.Content
import org.whispersystems.signalservice.internal.push.Envelope
class TimingMessageContentProcessor(context: Context) : MessageContentProcessor(context) {
companion object {
@@ -19,9 +20,9 @@ class TimingMessageContentProcessor(context: Context) : MessageContentProcessor(
fun endTag(timestamp: Long) = "$timestamp end"
}
override fun process(envelope: SignalServiceProtos.Envelope, content: SignalServiceProtos.Content, metadata: EnvelopeMetadata, serverDeliveredTimestamp: Long, processingEarlyContent: Boolean, localMetric: SignalLocalMetrics.MessageReceive?) {
Log.d(TAG, startTag(envelope.timestamp))
override fun process(envelope: Envelope, content: Content, metadata: EnvelopeMetadata, serverDeliveredTimestamp: Long, processingEarlyContent: Boolean, localMetric: SignalLocalMetrics.MessageReceive?) {
Log.d(TAG, startTag(envelope.timestamp!!))
super.process(envelope, content, metadata, serverDeliveredTimestamp, processingEarlyContent, localMetric)
Log.d(TAG, endTag(envelope.timestamp))
Log.d(TAG, endTag(envelope.timestamp!!))
}
}

View File

@@ -11,7 +11,7 @@ import org.thoughtcrime.securesms.recipients.Recipient
import org.thoughtcrime.securesms.testing.FakeClientHelpers.toEnvelope
import org.whispersystems.signalservice.api.push.ServiceId
import org.whispersystems.signalservice.api.push.SignalServiceAddress
import org.whispersystems.signalservice.internal.push.SignalServiceProtos.Envelope
import org.whispersystems.signalservice.internal.push.Envelope
/**
* Welcome to Alice's Client.

View File

@@ -31,11 +31,10 @@ import org.whispersystems.signalservice.api.crypto.UnidentifiedAccess
import org.whispersystems.signalservice.api.push.DistributionId
import org.whispersystems.signalservice.api.push.ServiceId
import org.whispersystems.signalservice.api.push.SignalServiceAddress
import org.whispersystems.signalservice.internal.push.SignalServiceProtos
import org.whispersystems.signalservice.internal.push.Envelope
import java.util.Optional
import java.util.UUID
import java.util.concurrent.locks.ReentrantLock
import kotlin.UnsupportedOperationException
/**
* Welcome to Bob's Client.
@@ -61,7 +60,7 @@ class BobClient(val serviceId: ServiceId, val e164: String, val identityKeyPair:
}
/** Inspired by SignalServiceMessageSender#getEncryptedMessage */
fun encrypt(now: Long): SignalServiceProtos.Envelope {
fun encrypt(now: Long): Envelope {
val envelopeContent = FakeClientHelpers.encryptedTextMessage(now)
val cipher = SignalServiceCipher(serviceAddress, 1, aciStore, sessionLock, null)
@@ -72,10 +71,10 @@ class BobClient(val serviceId: ServiceId, val e164: String, val identityKeyPair:
}
return cipher.encrypt(getAliceProtocolAddress(), getAliceUnidentifiedAccess(), envelopeContent)
.toEnvelope(envelopeContent.content.get().dataMessage.timestamp, getAliceServiceId())
.toEnvelope(envelopeContent.content.get().dataMessage!!.timestamp!!, getAliceServiceId())
}
fun decrypt(envelope: SignalServiceProtos.Envelope, serverDeliveredTimestamp: Long) {
fun decrypt(envelope: Envelope, serverDeliveredTimestamp: Long) {
val cipher = SignalServiceCipher(serviceAddress, 1, aciStore, sessionLock, UnidentifiedAccessUtil.getCertificateValidator())
cipher.decrypt(envelope, serverDeliveredTimestamp)
}

View File

@@ -1,5 +1,6 @@
package org.thoughtcrime.securesms.testing
import okio.ByteString.Companion.toByteString
import org.signal.libsignal.internal.Native
import org.signal.libsignal.internal.NativeHandleGuard
import org.signal.libsignal.metadata.certificate.CertificateValidator
@@ -9,15 +10,16 @@ import org.signal.libsignal.protocol.ecc.Curve
import org.signal.libsignal.protocol.ecc.ECKeyPair
import org.signal.libsignal.protocol.ecc.ECPublicKey
import org.signal.libsignal.zkgroup.profiles.ProfileKey
import org.thoughtcrime.securesms.database.model.toProtoByteString
import org.thoughtcrime.securesms.messages.SignalServiceProtoUtil.buildWith
import org.whispersystems.signalservice.api.crypto.ContentHint
import org.whispersystems.signalservice.api.crypto.EnvelopeContent
import org.whispersystems.signalservice.api.crypto.UnidentifiedAccess
import org.whispersystems.signalservice.api.crypto.UnidentifiedAccessPair
import org.whispersystems.signalservice.api.push.ServiceId
import org.whispersystems.signalservice.internal.push.Content
import org.whispersystems.signalservice.internal.push.DataMessage
import org.whispersystems.signalservice.internal.push.Envelope
import org.whispersystems.signalservice.internal.push.OutgoingPushMessage
import org.whispersystems.signalservice.internal.push.SignalServiceProtos
import org.whispersystems.signalservice.internal.push.SignalServiceProtos.Envelope
import org.whispersystems.util.Base64
import java.util.Optional
import java.util.UUID
@@ -52,9 +54,9 @@ object FakeClientHelpers {
}
fun encryptedTextMessage(now: Long, message: String = "Test body message"): EnvelopeContent {
val content = SignalServiceProtos.Content.newBuilder().apply {
setDataMessage(
SignalServiceProtos.DataMessage.newBuilder().apply {
val content = Content.Builder().apply {
dataMessage(
DataMessage.Builder().buildWith {
body = message
timestamp = now
}
@@ -64,16 +66,16 @@ object FakeClientHelpers {
}
fun OutgoingPushMessage.toEnvelope(timestamp: Long, destination: ServiceId): Envelope {
return Envelope.newBuilder()
.setType(Envelope.Type.valueOf(this.type))
.setSourceDevice(1)
.setTimestamp(timestamp)
.setServerTimestamp(timestamp + 1)
.setDestinationServiceId(destination.toString())
.setServerGuid(UUID.randomUUID().toString())
.setContent(Base64.decode(this.content).toProtoByteString())
.setUrgent(true)
.setStory(false)
return Envelope.Builder()
.type(Envelope.Type.fromValue(this.type))
.sourceDevice(1)
.timestamp(timestamp)
.serverTimestamp(timestamp + 1)
.destinationServiceId(destination.toString())
.serverGuid(UUID.randomUUID().toString())
.content(Base64.decode(this.content).toByteString())
.urgent(true)
.story(false)
.build()
}
}

View File

@@ -16,19 +16,19 @@ import kotlin.random.Random
*/
object GroupTestingUtils {
fun member(aci: ACI, revision: Int = 0, role: Member.Role = Member.Role.ADMINISTRATOR): DecryptedMember {
return DecryptedMember.newBuilder()
.setAciBytes(aci.toByteString())
.setJoinedAtRevision(revision)
.setRole(role)
return DecryptedMember.Builder()
.aciBytes(aci.toByteString())
.joinedAtRevision(revision)
.role(role)
.build()
}
fun insertGroup(revision: Int = 0, vararg members: DecryptedMember): TestGroupInfo {
val groupMasterKey = GroupMasterKey(Random.nextBytes(GroupMasterKey.SIZE))
val decryptedGroupState = DecryptedGroup.newBuilder()
.addAllMembers(members.toList())
.setRevision(revision)
.setTitle(MessageContentFuzzer.string())
val decryptedGroupState = DecryptedGroup.Builder()
.members(members.toList())
.revision(revision)
.title(MessageContentFuzzer.string())
.build()
val groupId = SignalDatabase.groups.create(groupMasterKey, decryptedGroupState)!!

View File

@@ -1,21 +1,20 @@
package org.thoughtcrime.securesms.testing
import com.google.protobuf.ByteString
import org.thoughtcrime.securesms.database.model.toProtoByteString
import okio.ByteString
import okio.ByteString.Companion.toByteString
import org.thoughtcrime.securesms.groups.GroupId
import org.thoughtcrime.securesms.messages.SignalServiceProtoUtil.buildWith
import org.thoughtcrime.securesms.messages.TestMessage
import org.thoughtcrime.securesms.recipients.Recipient
import org.thoughtcrime.securesms.recipients.RecipientId
import org.whispersystems.signalservice.api.crypto.EnvelopeMetadata
import org.whispersystems.signalservice.api.util.UuidUtil
import org.whispersystems.signalservice.internal.push.SignalServiceProtos
import org.whispersystems.signalservice.internal.push.SignalServiceProtos.AttachmentPointer
import org.whispersystems.signalservice.internal.push.SignalServiceProtos.Content
import org.whispersystems.signalservice.internal.push.SignalServiceProtos.DataMessage
import org.whispersystems.signalservice.internal.push.SignalServiceProtos.Envelope
import org.whispersystems.signalservice.internal.push.SignalServiceProtos.GroupContextV2
import org.whispersystems.signalservice.internal.push.SignalServiceProtos.SyncMessage
import org.whispersystems.signalservice.internal.push.AttachmentPointer
import org.whispersystems.signalservice.internal.push.BodyRange
import org.whispersystems.signalservice.internal.push.Content
import org.whispersystems.signalservice.internal.push.DataMessage
import org.whispersystems.signalservice.internal.push.Envelope
import org.whispersystems.signalservice.internal.push.GroupContextV2
import org.whispersystems.signalservice.internal.push.SyncMessage
import java.util.UUID
import kotlin.random.Random
import kotlin.random.nextInt
@@ -35,10 +34,10 @@ object MessageContentFuzzer {
* Create an [Envelope].
*/
fun envelope(timestamp: Long): Envelope {
return Envelope.newBuilder()
.setTimestamp(timestamp)
.setServerTimestamp(timestamp + 5)
.setServerGuidBytes(UuidUtil.toByteString(UUID.randomUUID()))
return Envelope.Builder()
.timestamp(timestamp)
.serverTimestamp(timestamp + 5)
.serverGuid(UUID.randomUUID().toString())
.build()
}
@@ -62,20 +61,22 @@ object MessageContentFuzzer {
* - Bold style body ranges
*/
fun fuzzTextMessage(groupContextV2: GroupContextV2? = null): Content {
return Content.newBuilder()
.setDataMessage(
DataMessage.newBuilder().buildWith {
return Content.Builder()
.dataMessage(
DataMessage.Builder().buildWith {
body = string()
if (random.nextBoolean()) {
expireTimer = random.nextInt(0..28.days.inWholeSeconds.toInt())
}
if (random.nextBoolean()) {
addBodyRanges(
SignalServiceProtos.BodyRange.newBuilder().buildWith {
start = 0
length = 1
style = SignalServiceProtos.BodyRange.Style.BOLD
}
bodyRanges(
listOf(
BodyRange.Builder().buildWith {
start = 0
length = 1
style = BodyRange.Style.BOLD
}
)
)
}
if (groupContextV2 != null) {
@@ -95,16 +96,16 @@ object MessageContentFuzzer {
recipientUpdate: Boolean = false
): Content {
return Content
.newBuilder()
.setSyncMessage(
SyncMessage.newBuilder().buildWith {
sent = SyncMessage.Sent.newBuilder().buildWith {
.Builder()
.syncMessage(
SyncMessage.Builder().buildWith {
sent = SyncMessage.Sent.Builder().buildWith {
timestamp = textMessage.timestamp
message = textMessage
isRecipientUpdate = recipientUpdate
addAllUnidentifiedStatus(
unidentifiedStatus(
deliveredTo.map {
SyncMessage.Sent.UnidentifiedDeliveryStatus.newBuilder().buildWith {
SyncMessage.Sent.UnidentifiedDeliveryStatus.Builder().buildWith {
destinationServiceId = Recipient.resolved(it).requireServiceId().toString()
unidentified = true
}
@@ -123,9 +124,9 @@ object MessageContentFuzzer {
* - A message with 0-2 attachment pointers and may contain a text body
*/
fun fuzzMediaMessageWithBody(quoteAble: List<TestMessage> = emptyList()): Content {
return Content.newBuilder()
.setDataMessage(
DataMessage.newBuilder().buildWith {
return Content.Builder()
.dataMessage(
DataMessage.Builder().buildWith {
if (random.nextBoolean()) {
body = string()
}
@@ -133,28 +134,28 @@ object MessageContentFuzzer {
if (random.nextBoolean() && quoteAble.isNotEmpty()) {
body = string()
val quoted = quoteAble.random(random)
quote = DataMessage.Quote.newBuilder().buildWith {
quote = DataMessage.Quote.Builder().buildWith {
id = quoted.envelope.timestamp
authorAci = quoted.metadata.sourceServiceId.toString()
text = quoted.content.dataMessage.body
addAllAttachments(quoted.content.dataMessage.attachmentsList)
addAllBodyRanges(quoted.content.dataMessage.bodyRangesList)
text = quoted.content.dataMessage?.body
attachments(quoted.content.dataMessage?.attachments ?: emptyList())
bodyRanges(quoted.content.dataMessage?.bodyRanges ?: emptyList())
type = DataMessage.Quote.Type.NORMAL
}
}
if (random.nextFloat() < 0.1 && quoteAble.isNotEmpty()) {
val quoted = quoteAble.random(random)
quote = DataMessage.Quote.newBuilder().buildWith {
id = random.nextLong(quoted.envelope.timestamp - 1000000, quoted.envelope.timestamp)
quote = DataMessage.Quote.Builder().buildWith {
id = random.nextLong(quoted.envelope.timestamp!! - 1000000, quoted.envelope.timestamp!!)
authorAci = quoted.metadata.sourceServiceId.toString()
text = quoted.content.dataMessage.body
text = quoted.content.dataMessage?.body
}
}
if (random.nextFloat() < 0.25) {
val total = random.nextInt(1, 2)
(0..total).forEach { _ -> addAttachments(attachmentPointer()) }
attachments((0..total).map { attachmentPointer() })
}
}
)
@@ -166,12 +167,12 @@ object MessageContentFuzzer {
* - A reaction to a prior message
*/
fun fuzzMediaMessageNoContent(previousMessages: List<TestMessage> = emptyList()): Content {
return Content.newBuilder()
.setDataMessage(
DataMessage.newBuilder().buildWith {
return Content.Builder()
.dataMessage(
DataMessage.Builder().buildWith {
if (random.nextFloat() < 0.25) {
val reactTo = previousMessages.random(random)
reaction = DataMessage.Reaction.newBuilder().buildWith {
reaction = DataMessage.Reaction.Builder().buildWith {
emoji = emojis.random(random)
remove = false
targetAuthorAci = reactTo.metadata.sourceServiceId.toString()
@@ -187,15 +188,15 @@ object MessageContentFuzzer {
* - A sticker
*/
fun fuzzMediaMessageNoText(previousMessages: List<TestMessage> = emptyList()): Content {
return Content.newBuilder()
.setDataMessage(
DataMessage.newBuilder().buildWith {
return Content.Builder()
.dataMessage(
DataMessage.Builder().buildWith {
if (random.nextFloat() < 0.9) {
sticker = DataMessage.Sticker.newBuilder().buildWith {
sticker = DataMessage.Sticker.Builder().buildWith {
packId = byteString(length = 24)
packKey = byteString(length = 128)
stickerId = random.nextInt()
data = attachmentPointer()
data_ = attachmentPointer()
emoji = emojis.random(random)
}
}
@@ -223,14 +224,14 @@ object MessageContentFuzzer {
* Generate a random [ByteString].
*/
fun byteString(length: Int = 512): ByteString {
return random.nextBytes(length).toProtoByteString()
return random.nextBytes(length).toByteString()
}
/**
* Generate a random [AttachmentPointer].
*/
fun attachmentPointer(): AttachmentPointer {
return AttachmentPointer.newBuilder().run {
return AttachmentPointer.Builder().run {
cdnKey = string()
contentType = mediaTypes.random(random)
key = byteString()

View File

@@ -1,70 +0,0 @@
package org.thoughtcrime.securesms.testing
import com.google.protobuf.ByteString
import org.signal.libsignal.zkgroup.groups.GroupMasterKey
import org.whispersystems.signalservice.api.push.ServiceId.ACI
import org.whispersystems.signalservice.internal.push.SignalServiceProtos
import org.whispersystems.signalservice.internal.push.SignalServiceProtos.DataMessage
import org.whispersystems.signalservice.internal.push.SignalServiceProtos.GroupContextV2
import org.whispersystems.signalservice.internal.serialize.protos.AddressProto
import org.whispersystems.signalservice.internal.serialize.protos.MetadataProto
import org.whispersystems.signalservice.internal.serialize.protos.SignalServiceContentProto
import java.util.UUID
import kotlin.random.Random
class TestProtos private constructor() {
fun address(
uuid: UUID = UUID.randomUUID()
): AddressProto.Builder {
return AddressProto.newBuilder()
.setUuid(ACI.from(uuid).toByteString())
}
fun metadata(
address: AddressProto = address().build()
): MetadataProto.Builder {
return MetadataProto.newBuilder()
.setAddress(address)
}
fun groupContextV2(
revision: Int = 0,
masterKeyBytes: ByteArray = Random.Default.nextBytes(GroupMasterKey.SIZE)
): GroupContextV2.Builder {
return GroupContextV2.newBuilder()
.setRevision(revision)
.setMasterKey(ByteString.copyFrom(masterKeyBytes))
}
fun storyContext(
sentTimestamp: Long = Random.nextLong(),
authorUuid: String = UUID.randomUUID().toString()
): DataMessage.StoryContext.Builder {
return DataMessage.StoryContext.newBuilder()
.setAuthorAci(authorUuid)
.setSentTimestamp(sentTimestamp)
}
fun dataMessage(): DataMessage.Builder {
return DataMessage.newBuilder()
}
fun content(): SignalServiceProtos.Content.Builder {
return SignalServiceProtos.Content.newBuilder()
}
fun serviceContent(
localAddress: AddressProto = address().build(),
metadata: MetadataProto = metadata().build()
): SignalServiceContentProto.Builder {
return SignalServiceContentProto.newBuilder()
.setLocalAddress(localAddress)
.setMetadata(metadata)
}
companion object {
fun <T> build(buildFn: TestProtos.() -> T): T {
return TestProtos().buildFn()
}
}
}