diff --git a/libsession/build.gradle b/libsession/build.gradle index aea50a3003..47fc374def 100644 --- a/libsession/build.gradle +++ b/libsession/build.gradle @@ -38,7 +38,10 @@ dependencies { implementation 'androidx.core:core-ktx:1.3.2' implementation 'androidx.appcompat:appcompat:1.2.0' implementation 'com.google.android.material:material:1.2.1' + implementation "com.google.protobuf:protobuf-java:$protobufVersion" testImplementation 'junit:junit:4.+' androidTestImplementation 'androidx.test.ext:junit:1.1.2' androidTestImplementation 'androidx.test.espresso:espresso-core:3.3.0' + + implementation project(":libsignal") } \ No newline at end of file diff --git a/libsession/src/main/java/org/session/libsession/messaging/messages/Destination.kt b/libsession/src/main/java/org/session/libsession/messaging/messages/Destination.kt index bd39ccbbce..8c255bdce5 100644 --- a/libsession/src/main/java/org/session/libsession/messaging/messages/Destination.kt +++ b/libsession/src/main/java/org/session/libsession/messaging/messages/Destination.kt @@ -1,5 +1,9 @@ -package org.session.messaging.messages +package org.session.libsession.messaging.messages -enum class Destination { +sealed class Destination { + + class Contact(val publicKey: String) + class ClosedGroup(val groupPublicKey: String) + class OpenGroup(val channel: Long, val server: String) } \ No newline at end of file diff --git a/libsession/src/main/java/org/session/libsession/messaging/messages/Message.kt b/libsession/src/main/java/org/session/libsession/messaging/messages/Message.kt index b1ca1ce0ca..6176cee7c8 100644 --- a/libsession/src/main/java/org/session/libsession/messaging/messages/Message.kt +++ b/libsession/src/main/java/org/session/libsession/messaging/messages/Message.kt @@ -1,5 +1,33 @@ -package org.session.messaging.messages +package org.session.libsession.messaging.messages -open class Message { +import org.session.libsignal.service.internal.push.SignalServiceProtos + +abstract class Message { + + var id: String? = null + var threadID: String? = null + var sentTimestamp: Long? = null + var receivedTimestamp: Long? = null + var recipient: String? = null + var sender: String? = null + var groupPublicKey: String? = null + var openGroupServerMessageID: Long? = null + + companion object { + @JvmStatic + val ttl = 2 * 24 * 60 * 60 * 1000 + + //fun fromProto(proto: SignalServiceProtos.Content): Message? {} + } + + open fun isValid(): Boolean { + sentTimestamp = if (sentTimestamp!! > 0) sentTimestamp else return false + receivedTimestamp = if (receivedTimestamp!! > 0) receivedTimestamp else return false + return sender != null && recipient != null + } + + + + abstract fun toProto(): SignalServiceProtos.Content? } \ No newline at end of file diff --git a/libsession/src/main/java/org/session/libsession/messaging/messages/control/ClosedGroupUpdate.kt b/libsession/src/main/java/org/session/libsession/messaging/messages/control/ClosedGroupUpdate.kt index e6c673c7ee..18f424ba8e 100644 --- a/libsession/src/main/java/org/session/libsession/messaging/messages/control/ClosedGroupUpdate.kt +++ b/libsession/src/main/java/org/session/libsession/messaging/messages/control/ClosedGroupUpdate.kt @@ -1,4 +1,154 @@ -package org.session.messaging.messages.control +package org.session.libsession.messaging.messages.control -class ClosedGroupUpdate : ControlMessage() { +import com.google.protobuf.ByteString +import org.session.libsignal.libsignal.logging.Log +import org.session.libsignal.service.internal.push.SignalServiceProtos +import org.session.libsignal.service.loki.protocol.closedgroups.ClosedGroupSenderKey + +class ClosedGroupUpdate() : ControlMessage() { + + companion object { + const val TAG = "ClosedGroupUpdate" + + fun fromProto(proto: SignalServiceProtos.Content): ClosedGroupUpdate? { + val closedGroupUpdateProto = proto.dataMessage?.closedGroupUpdate ?: return null + val groupPublicKey = closedGroupUpdateProto.groupPublicKey + var kind: Kind? = null + when(closedGroupUpdateProto.type) { + SignalServiceProtos.ClosedGroupUpdate.Type.NEW -> { + val name = closedGroupUpdateProto.name ?: return null + val groupPrivateKey = closedGroupUpdateProto.groupPrivateKey ?: return null + val senderKeys = closedGroupUpdateProto.senderKeysList.map { ClosedGroupSenderKey.fromProto(it) } + kind = Kind.New( + groupPublicKey = groupPublicKey.toByteArray(), + name = name, + groupPrivateKey = groupPrivateKey.toByteArray(), + senderKeys = senderKeys, + members = closedGroupUpdateProto.membersList.map { it.toByteArray() }, + admins = closedGroupUpdateProto.adminsList.map { it.toByteArray() } + ) + } + SignalServiceProtos.ClosedGroupUpdate.Type.INFO -> { + val name = closedGroupUpdateProto.name ?: return null + val senderKeys = closedGroupUpdateProto.senderKeysList.map { ClosedGroupSenderKey.fromProto(it) } + kind = Kind.Info( + groupPublicKey = groupPublicKey.toByteArray(), + name = name, + senderKeys = senderKeys, + members = closedGroupUpdateProto.membersList.map { it.toByteArray() }, + admins = closedGroupUpdateProto.adminsList.map { it.toByteArray() } + ) + } + SignalServiceProtos.ClosedGroupUpdate.Type.SENDER_KEY_REQUEST -> { + kind = Kind.SenderKeyRequest(groupPublicKey = groupPublicKey.toByteArray()) + } + SignalServiceProtos.ClosedGroupUpdate.Type.SENDER_KEY -> { + val senderKeyProto = closedGroupUpdateProto.senderKeysList?.first() ?: return null + kind = Kind.SenderKey( + groupPublicKey = groupPublicKey.toByteArray(), + senderKey = ClosedGroupSenderKey.fromProto(senderKeyProto) + ) + } + } + return ClosedGroupUpdate(kind) + } + } + //private val TAG: String = ClosedGroupUpdate::class.java.simpleName + + // Kind enum + sealed class Kind { + class New(val groupPublicKey: ByteArray, val name: String, val groupPrivateKey: ByteArray, val senderKeys: Collection, val members: Collection, val admins: Collection) : Kind() + class Info(val groupPublicKey: ByteArray, val name: String, val senderKeys: Collection, val members: Collection, val admins: Collection) : Kind() + class SenderKeyRequest(val groupPublicKey: ByteArray) : Kind() + class SenderKey(val groupPublicKey: ByteArray, val senderKey: org.session.libsignal.service.loki.protocol.closedgroups.ClosedGroupSenderKey) : Kind() + } + + var kind: Kind? = null + + // constructors + internal constructor(kind: Kind?) : this() { + this.kind = kind + } + + override fun isValid(): Boolean { + if (!super.isValid() || kind == null) return false + val kind = kind ?: return false + when(kind) { + is Kind.New -> { + return !kind.groupPublicKey.isEmpty() && !kind.name.isEmpty() && !kind.groupPrivateKey.isEmpty() && !kind.members.isEmpty() && !kind.admins.isEmpty() + } + is Kind.Info -> { + return !kind.groupPublicKey.isEmpty() && !kind.name.isEmpty() && !kind.members.isEmpty() && !kind.admins.isEmpty() + } + is Kind.SenderKeyRequest -> { + return !kind.groupPublicKey.isEmpty() + } + is Kind.SenderKey -> { + return !kind.groupPublicKey.isEmpty() + } + } + } + + override fun toProto(): SignalServiceProtos.Content? { + val kind = kind + if (kind == null) { + Log.w(TAG, "Couldn't construct closed group update proto from: $this") + return null + } + try { + val closedGroupUpdate: SignalServiceProtos.ClosedGroupUpdate.Builder = SignalServiceProtos.ClosedGroupUpdate.newBuilder() + when (kind) { + is Kind.New -> { + closedGroupUpdate.groupPublicKey = ByteString.copyFrom(kind.groupPublicKey) + closedGroupUpdate.type = SignalServiceProtos.ClosedGroupUpdate.Type.NEW + closedGroupUpdate.name = kind.name + closedGroupUpdate.groupPrivateKey = ByteString.copyFrom(kind.groupPrivateKey) + closedGroupUpdate.addAllSenderKeys(kind.senderKeys.map { it.toProto() }) + closedGroupUpdate.addAllMembers(kind.members.map { ByteString.copyFrom(it) }) + closedGroupUpdate.addAllAdmins(kind.admins.map { ByteString.copyFrom(it) }) + } + is Kind.Info -> { + closedGroupUpdate.groupPublicKey = ByteString.copyFrom(kind.groupPublicKey) + closedGroupUpdate.type = SignalServiceProtos.ClosedGroupUpdate.Type.INFO + closedGroupUpdate.name = kind.name + closedGroupUpdate.addAllSenderKeys(kind.senderKeys.map { it.toProto() }) + closedGroupUpdate.addAllMembers(kind.members.map { ByteString.copyFrom(it) }) + closedGroupUpdate.addAllAdmins(kind.admins.map { ByteString.copyFrom(it) }) + } + is Kind.SenderKeyRequest -> { + closedGroupUpdate.groupPublicKey = ByteString.copyFrom(kind.groupPublicKey) + closedGroupUpdate.type = SignalServiceProtos.ClosedGroupUpdate.Type.SENDER_KEY_REQUEST + } + is Kind.SenderKey -> { + closedGroupUpdate.groupPublicKey = ByteString.copyFrom(kind.groupPublicKey) + closedGroupUpdate.type = SignalServiceProtos.ClosedGroupUpdate.Type.SENDER_KEY + closedGroupUpdate.addAllSenderKeys(listOf( kind.senderKey.toProto() )) + } + } + val contentProto = SignalServiceProtos.Content.newBuilder() + val dataMessageProto = SignalServiceProtos.DataMessage.newBuilder() + dataMessageProto.closedGroupUpdate = closedGroupUpdate.build() + contentProto.dataMessage = dataMessageProto.build() + return contentProto.build() + } catch (e: Exception) { + Log.w(TAG, "Couldn't construct closed group update proto from: $this") + return null + } + return null + } + +} + +// extension functions to class ClosedGroupSenderKey + +private fun ClosedGroupSenderKey.Companion.fromProto(proto: SignalServiceProtos.ClosedGroupUpdate.SenderKey): org.session.libsignal.service.loki.protocol.closedgroups.ClosedGroupSenderKey { + return ClosedGroupSenderKey(chainKey = proto.chainKey.toByteArray(), keyIndex = proto.keyIndex, publicKey = proto.publicKey.toByteArray()) +} + +private fun ClosedGroupSenderKey.toProto(): SignalServiceProtos.ClosedGroupUpdate.SenderKey { + val proto = SignalServiceProtos.ClosedGroupUpdate.SenderKey.newBuilder() + proto.chainKey = ByteString.copyFrom(chainKey) + proto.keyIndex = keyIndex + proto.publicKey = ByteString.copyFrom(publicKey) + return proto.build() } \ No newline at end of file diff --git a/libsession/src/main/java/org/session/libsession/messaging/messages/control/ControlMessage.kt b/libsession/src/main/java/org/session/libsession/messaging/messages/control/ControlMessage.kt index 670553854c..44cd7ee4d8 100644 --- a/libsession/src/main/java/org/session/libsession/messaging/messages/control/ControlMessage.kt +++ b/libsession/src/main/java/org/session/libsession/messaging/messages/control/ControlMessage.kt @@ -1,6 +1,6 @@ -package org.session.messaging.messages.control +package org.session.libsession.messaging.messages.control -import org.session.messaging.messages.Message +import org.session.libsession.messaging.messages.Message -open class ControlMessage : Message() { +abstract class ControlMessage : Message() { } \ No newline at end of file diff --git a/libsession/src/main/java/org/session/libsession/messaging/messages/control/ExpirationTimerUpdate.kt b/libsession/src/main/java/org/session/libsession/messaging/messages/control/ExpirationTimerUpdate.kt index 24d9140792..8ba8b802bd 100644 --- a/libsession/src/main/java/org/session/libsession/messaging/messages/control/ExpirationTimerUpdate.kt +++ b/libsession/src/main/java/org/session/libsession/messaging/messages/control/ExpirationTimerUpdate.kt @@ -1,4 +1,13 @@ -package org.session.messaging.messages.control +package org.session.libsession.messaging.messages.control + +import org.session.libsignal.service.internal.push.SignalServiceProtos class ExpirationTimerUpdate : ControlMessage() { + override fun fromProto(proto: SignalServiceProtos.Content): ExpirationTimerUpdate? { + TODO("Not yet implemented") + } + + override fun toProto(): SignalServiceProtos.Content? { + TODO("Not yet implemented") + } } \ No newline at end of file diff --git a/libsession/src/main/java/org/session/libsession/messaging/messages/control/ReadReceipt.kt b/libsession/src/main/java/org/session/libsession/messaging/messages/control/ReadReceipt.kt index 74f96aec81..2aa507065b 100644 --- a/libsession/src/main/java/org/session/libsession/messaging/messages/control/ReadReceipt.kt +++ b/libsession/src/main/java/org/session/libsession/messaging/messages/control/ReadReceipt.kt @@ -1,4 +1,13 @@ -package org.session.messaging.messages.control +package org.session.libsession.messaging.messages.control + +import org.session.libsignal.service.internal.push.SignalServiceProtos class ReadReceipt : ControlMessage() { + override fun fromProto(proto: SignalServiceProtos.Content): ReadReceipt? { + TODO("Not yet implemented") + } + + override fun toProto(): SignalServiceProtos.Content? { + TODO("Not yet implemented") + } } \ No newline at end of file diff --git a/libsession/src/main/java/org/session/libsession/messaging/messages/control/TypingIndicator.kt b/libsession/src/main/java/org/session/libsession/messaging/messages/control/TypingIndicator.kt index 9610e0b88d..a08d8f3ff0 100644 --- a/libsession/src/main/java/org/session/libsession/messaging/messages/control/TypingIndicator.kt +++ b/libsession/src/main/java/org/session/libsession/messaging/messages/control/TypingIndicator.kt @@ -1,4 +1,13 @@ -package org.session.messaging.messages.control +package org.session.libsession.messaging.messages.control + +import org.session.libsignal.service.internal.push.SignalServiceProtos class TypingIndicator : ControlMessage() { + override fun fromProto(proto: SignalServiceProtos.Content): TypingIndicator?{ + TODO("Not yet implemented") + } + + override fun toProto(): SignalServiceProtos.Content? { + TODO("Not yet implemented") + } } \ No newline at end of file diff --git a/libsession/src/main/java/org/session/libsession/messaging/messages/control/unused/NullMessage.kt b/libsession/src/main/java/org/session/libsession/messaging/messages/control/unused/NullMessage.kt index a791c32ca3..392d56caf5 100644 --- a/libsession/src/main/java/org/session/libsession/messaging/messages/control/unused/NullMessage.kt +++ b/libsession/src/main/java/org/session/libsession/messaging/messages/control/unused/NullMessage.kt @@ -1,6 +1,14 @@ -package org.session.messaging.messages.control.unused +package org.session.libsession.messaging.messages.control.unused -import org.session.messaging.messages.control.ControlMessage +import org.session.libsession.messaging.messages.control.ControlMessage +import org.session.libsignal.service.internal.push.SignalServiceProtos class NullMessage : ControlMessage() { + override fun fromProto(proto: SignalServiceProtos.Content): NullMessage? { + TODO("Not yet implemented") + } + + override fun toProto(): SignalServiceProtos.Content? { + TODO("Not yet implemented") + } } \ No newline at end of file diff --git a/libsession/src/main/java/org/session/libsession/messaging/messages/control/unused/SessionRequest.kt b/libsession/src/main/java/org/session/libsession/messaging/messages/control/unused/SessionRequest.kt index 51f99a7c16..8090d68f68 100644 --- a/libsession/src/main/java/org/session/libsession/messaging/messages/control/unused/SessionRequest.kt +++ b/libsession/src/main/java/org/session/libsession/messaging/messages/control/unused/SessionRequest.kt @@ -1,6 +1,14 @@ -package org.session.messaging.messages.control.unused +package org.session.libsession.messaging.messages.control.unused -import org.session.messaging.messages.control.ControlMessage +import org.session.libsession.messaging.messages.control.ControlMessage +import org.session.libsignal.service.internal.push.SignalServiceProtos class SessionRequest : ControlMessage() { + override fun fromProto(proto: SignalServiceProtos.Content): SessionRequest? { + TODO("Not yet implemented") + } + + override fun toProto(): SignalServiceProtos.Content? { + TODO("Not yet implemented") + } } \ No newline at end of file diff --git a/libsession/src/main/java/org/session/libsession/messaging/messages/visible/Contact.kt b/libsession/src/main/java/org/session/libsession/messaging/messages/visible/Contact.kt index 7efb865119..cd67a4764e 100644 --- a/libsession/src/main/java/org/session/libsession/messaging/messages/visible/Contact.kt +++ b/libsession/src/main/java/org/session/libsession/messaging/messages/visible/Contact.kt @@ -1,4 +1,13 @@ -package org.session.messaging.messages.visible +package org.session.libsession.messaging.messages.visible -internal class Contact { +import org.session.libsignal.service.internal.push.SignalServiceProtos + +internal class Contact : VisibleMessage() { + override fun fromProto(proto: SignalServiceProtos.Content): Contact? { + TODO("Not yet implemented") + } + + override fun toProto(): SignalServiceProtos.Content? { + TODO("Not yet implemented") + } } \ No newline at end of file diff --git a/libsession/src/main/java/org/session/libsession/messaging/messages/visible/LinkPreview.kt b/libsession/src/main/java/org/session/libsession/messaging/messages/visible/LinkPreview.kt index a385545b51..355d8bd0c0 100644 --- a/libsession/src/main/java/org/session/libsession/messaging/messages/visible/LinkPreview.kt +++ b/libsession/src/main/java/org/session/libsession/messaging/messages/visible/LinkPreview.kt @@ -1,4 +1,13 @@ -package org.session.messaging.messages.visible +package org.session.libsession.messaging.messages.visible -internal class LinkPreview { +import org.session.libsignal.service.internal.push.SignalServiceProtos + +internal class LinkPreview : VisibleMessage(){ + override fun fromProto(proto: SignalServiceProtos.Content): LinkPreview? { + TODO("Not yet implemented") + } + + override fun toProto(): SignalServiceProtos.Content? { + TODO("Not yet implemented") + } } \ No newline at end of file diff --git a/libsession/src/main/java/org/session/libsession/messaging/messages/visible/Profile.kt b/libsession/src/main/java/org/session/libsession/messaging/messages/visible/Profile.kt index 22740911ea..0b125bb1f9 100644 --- a/libsession/src/main/java/org/session/libsession/messaging/messages/visible/Profile.kt +++ b/libsession/src/main/java/org/session/libsession/messaging/messages/visible/Profile.kt @@ -1,4 +1,13 @@ -package org.session.messaging.messages.visible +package org.session.libsession.messaging.messages.visible -internal class Profile { +import org.session.libsignal.service.internal.push.SignalServiceProtos + +internal class Profile : VisibleMessage() { + override fun fromProto(proto: SignalServiceProtos.Content): Profile? { + TODO("Not yet implemented") + } + + override fun toProto(): SignalServiceProtos.Content? { + TODO("Not yet implemented") + } } \ No newline at end of file diff --git a/libsession/src/main/java/org/session/libsession/messaging/messages/visible/Quote.kt b/libsession/src/main/java/org/session/libsession/messaging/messages/visible/Quote.kt index 90e2c287c5..7c0179e293 100644 --- a/libsession/src/main/java/org/session/libsession/messaging/messages/visible/Quote.kt +++ b/libsession/src/main/java/org/session/libsession/messaging/messages/visible/Quote.kt @@ -1,4 +1,13 @@ -package org.session.messaging.messages.visible +package org.session.libsession.messaging.messages.visible -internal class Quote { +import org.session.libsignal.service.internal.push.SignalServiceProtos + +internal class Quote : VisibleMessage() { + override fun fromProto(proto: SignalServiceProtos.Content): Quote? { + TODO("Not yet implemented") + } + + override fun toProto(): SignalServiceProtos.Content? { + TODO("Not yet implemented") + } } \ No newline at end of file diff --git a/libsession/src/main/java/org/session/libsession/messaging/messages/visible/VisibleMessage.kt b/libsession/src/main/java/org/session/libsession/messaging/messages/visible/VisibleMessage.kt index 0b332aaaca..5ea2cea79e 100644 --- a/libsession/src/main/java/org/session/libsession/messaging/messages/visible/VisibleMessage.kt +++ b/libsession/src/main/java/org/session/libsession/messaging/messages/visible/VisibleMessage.kt @@ -1,6 +1,6 @@ -package org.session.messaging.messages.visible +package org.session.libsession.messaging.messages.visible -import org.session.messaging.messages.Message +import org.session.libsession.messaging.messages.Message -class VisibleMessage : Message() { +abstract class VisibleMessage : Message() { } \ No newline at end of file diff --git a/libsession/src/main/java/org/session/libsession/messaging/messages/visible/attachments/Attachment.kt b/libsession/src/main/java/org/session/libsession/messaging/messages/visible/attachments/Attachment.kt index fa94a1808e..e0093d9831 100644 --- a/libsession/src/main/java/org/session/libsession/messaging/messages/visible/attachments/Attachment.kt +++ b/libsession/src/main/java/org/session/libsession/messaging/messages/visible/attachments/Attachment.kt @@ -1,4 +1,14 @@ -package org.session.messaging.messages.visible.attachments +package org.session.libsession.messaging.messages.visible.attachments -internal class Attachment { +import org.session.libsession.messaging.messages.visible.VisibleMessage +import org.session.libsignal.service.internal.push.SignalServiceProtos + +internal class Attachment : VisibleMessage() { + override fun fromProto(proto: SignalServiceProtos.Content): Attachment? { + TODO("Not yet implemented") + } + + override fun toProto(): SignalServiceProtos.Content? { + TODO("Not yet implemented") + } } \ No newline at end of file