mirror of
https://github.com/oxen-io/session-android.git
synced 2024-11-23 18:15:22 +00:00
Update AttachmentUploadJob for the V2 file server
This commit is contained in:
parent
75ce0f056c
commit
0faeb7becf
@ -3,8 +3,10 @@ package org.session.libsession.messaging.jobs
|
|||||||
import com.esotericsoftware.kryo.Kryo
|
import com.esotericsoftware.kryo.Kryo
|
||||||
import com.esotericsoftware.kryo.io.Input
|
import com.esotericsoftware.kryo.io.Input
|
||||||
import com.esotericsoftware.kryo.io.Output
|
import com.esotericsoftware.kryo.io.Output
|
||||||
|
import nl.komponents.kovenant.Promise
|
||||||
import org.session.libsession.messaging.MessagingModuleConfiguration
|
import org.session.libsession.messaging.MessagingModuleConfiguration
|
||||||
import org.session.libsession.messaging.file_server.FileServerAPI
|
import org.session.libsession.messaging.file_server.FileServerAPI
|
||||||
|
import org.session.libsession.messaging.file_server.FileServerAPIV2
|
||||||
import org.session.libsession.messaging.messages.Message
|
import org.session.libsession.messaging.messages.Message
|
||||||
import org.session.libsession.messaging.open_groups.OpenGroupAPIV2
|
import org.session.libsession.messaging.open_groups.OpenGroupAPIV2
|
||||||
import org.session.libsession.messaging.sending_receiving.MessageSender
|
import org.session.libsession.messaging.sending_receiving.MessageSender
|
||||||
@ -15,6 +17,7 @@ import org.session.libsignal.service.api.messages.SignalServiceAttachmentStream
|
|||||||
import org.session.libsignal.service.internal.crypto.PaddingInputStream
|
import org.session.libsignal.service.internal.crypto.PaddingInputStream
|
||||||
import org.session.libsignal.service.internal.push.PushAttachmentData
|
import org.session.libsignal.service.internal.push.PushAttachmentData
|
||||||
import org.session.libsignal.service.internal.push.http.AttachmentCipherOutputStreamFactory
|
import org.session.libsignal.service.internal.push.http.AttachmentCipherOutputStreamFactory
|
||||||
|
import org.session.libsignal.service.internal.push.http.DigestingRequestBody
|
||||||
import org.session.libsignal.service.internal.util.Util
|
import org.session.libsignal.service.internal.util.Util
|
||||||
import org.session.libsignal.service.loki.PlaintextOutputStreamFactory
|
import org.session.libsignal.service.loki.PlaintextOutputStreamFactory
|
||||||
import org.session.libsignal.utilities.logging.Log
|
import org.session.libsignal.utilities.logging.Log
|
||||||
@ -45,27 +48,29 @@ class AttachmentUploadJob(val attachmentID: Long, val threadID: String, val mess
|
|||||||
|
|
||||||
override fun execute() {
|
override fun execute() {
|
||||||
try {
|
try {
|
||||||
val attachment = MessagingModuleConfiguration.shared.messageDataProvider.getScaledSignalAttachmentStream(attachmentID)
|
val storage = MessagingModuleConfiguration.shared.storage
|
||||||
|
val messageDataProvider = MessagingModuleConfiguration.shared.messageDataProvider
|
||||||
|
val attachment = messageDataProvider.getScaledSignalAttachmentStream(attachmentID)
|
||||||
?: return handleFailure(Error.NoAttachment)
|
?: return handleFailure(Error.NoAttachment)
|
||||||
val usePadding = false
|
val v2OpenGroup = storage.getV2OpenGroup(threadID)
|
||||||
val openGroupV2 = MessagingModuleConfiguration.shared.storage.getV2OpenGroup(threadID)
|
val v1OpenGroup = storage.getOpenGroup(threadID)
|
||||||
val openGroup = MessagingModuleConfiguration.shared.storage.getOpenGroup(threadID)
|
if (v2OpenGroup != null) {
|
||||||
val server = openGroupV2?.server ?: openGroup?.server ?: FileServerAPI.shared.server
|
val keyAndResult = upload(attachment, v2OpenGroup.server, false) {
|
||||||
val shouldEncrypt = (openGroup == null && openGroupV2 == null) // Encrypt if this isn't an open group
|
OpenGroupAPIV2.upload(it, v2OpenGroup.room, v2OpenGroup.server)
|
||||||
val attachmentKey = Util.getSecretBytes(64)
|
}
|
||||||
val paddedLength = if (usePadding) PaddingInputStream.getPaddedSize(attachment.length) else attachment.length
|
handleSuccess(attachment, keyAndResult.first, keyAndResult.second)
|
||||||
val dataStream = if (usePadding) PaddingInputStream(attachment.inputStream, attachment.length) else attachment.inputStream
|
} else if (v1OpenGroup == null) {
|
||||||
val ciphertextLength = if (shouldEncrypt) AttachmentCipherOutputStream.getCiphertextLength(paddedLength) else attachment.length
|
val keyAndResult = upload(attachment, FileServerAPIV2.DEFAULT_SERVER, true) {
|
||||||
val outputStreamFactory = if (shouldEncrypt) AttachmentCipherOutputStreamFactory(attachmentKey) else PlaintextOutputStreamFactory()
|
FileServerAPIV2.upload(it)
|
||||||
val attachmentData = PushAttachmentData(attachment.contentType, dataStream, ciphertextLength, outputStreamFactory, attachment.listener)
|
}
|
||||||
val uploadResult = if (openGroupV2 != null) {
|
handleSuccess(attachment, keyAndResult.first, keyAndResult.second)
|
||||||
val dataBytes = attachmentData.data.readBytes()
|
} else { // V1 open group
|
||||||
val result = OpenGroupAPIV2.upload(dataBytes, openGroupV2.room, openGroupV2.server).get()
|
val server = v1OpenGroup.server
|
||||||
DotNetAPI.UploadResult(result, "${openGroupV2.server}/files/$result", byteArrayOf())
|
val pushData = PushAttachmentData(attachment.contentType, attachment.inputStream,
|
||||||
} else {
|
attachment.length, PlaintextOutputStreamFactory(), attachment.listener)
|
||||||
FileServerAPI.shared.uploadAttachment(server, attachmentData)
|
val result = FileServerAPI.shared.uploadAttachment(server, pushData)
|
||||||
|
handleSuccess(attachment, ByteArray(0), result)
|
||||||
}
|
}
|
||||||
handleSuccess(attachment, attachmentKey, uploadResult)
|
|
||||||
} catch (e: java.lang.Exception) {
|
} catch (e: java.lang.Exception) {
|
||||||
if (e == Error.NoAttachment) {
|
if (e == Error.NoAttachment) {
|
||||||
this.handlePermanentFailure(e)
|
this.handlePermanentFailure(e)
|
||||||
@ -77,6 +82,19 @@ class AttachmentUploadJob(val attachmentID: Long, val threadID: String, val mess
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun upload(attachment: SignalServiceAttachmentStream, server: String, encrypt: Boolean, upload: (ByteArray) -> Promise<Long, Exception>): Pair<ByteArray, DotNetAPI.UploadResult> {
|
||||||
|
val key = if (encrypt) Util.getSecretBytes(64) else ByteArray(0)
|
||||||
|
val rawLength = attachment.length
|
||||||
|
val length = if (encrypt) PaddingInputStream.getPaddedSize(rawLength) else rawLength
|
||||||
|
val stream = if (encrypt) PaddingInputStream(attachment.inputStream, rawLength) else attachment.inputStream
|
||||||
|
val ciphertextLength = if (encrypt) AttachmentCipherOutputStream.getCiphertextLength(length) else rawLength
|
||||||
|
val outputStreamFactory = if (encrypt) AttachmentCipherOutputStreamFactory(key) else PlaintextOutputStreamFactory()
|
||||||
|
val pushData = PushAttachmentData(attachment.contentType, stream, ciphertextLength, outputStreamFactory, attachment.listener)
|
||||||
|
val file = DigestingRequestBody(pushData.data, outputStreamFactory, attachment.contentType, pushData.dataSize, attachment.listener)
|
||||||
|
val id = upload(pushData.data.readBytes()).get()
|
||||||
|
return Pair(key, DotNetAPI.UploadResult(id, "${server}/files/$id", file.transmittedDigest))
|
||||||
|
}
|
||||||
|
|
||||||
private fun handleSuccess(attachment: SignalServiceAttachmentStream, attachmentKey: ByteArray, uploadResult: DotNetAPI.UploadResult) {
|
private fun handleSuccess(attachment: SignalServiceAttachmentStream, attachmentKey: ByteArray, uploadResult: DotNetAPI.UploadResult) {
|
||||||
Log.d(TAG, "Attachment uploaded successfully.")
|
Log.d(TAG, "Attachment uploaded successfully.")
|
||||||
delegate?.handleJobSucceeded(this)
|
delegate?.handleJobSucceeded(this)
|
||||||
|
@ -12,16 +12,15 @@ import javax.crypto.spec.SecretKeySpec
|
|||||||
|
|
||||||
@WorkerThread
|
@WorkerThread
|
||||||
internal object AESGCM {
|
internal object AESGCM {
|
||||||
|
|
||||||
internal data class EncryptionResult(
|
|
||||||
internal val ciphertext: ByteArray,
|
|
||||||
internal val symmetricKey: ByteArray,
|
|
||||||
internal val ephemeralPublicKey: ByteArray
|
|
||||||
)
|
|
||||||
|
|
||||||
internal val gcmTagSize = 128
|
internal val gcmTagSize = 128
|
||||||
internal val ivSize = 12
|
internal val ivSize = 12
|
||||||
|
|
||||||
|
internal data class EncryptionResult(
|
||||||
|
internal val ciphertext: ByteArray,
|
||||||
|
internal val symmetricKey: ByteArray,
|
||||||
|
internal val ephemeralPublicKey: ByteArray
|
||||||
|
)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sync. Don't call from the main thread.
|
* Sync. Don't call from the main thread.
|
||||||
*/
|
*/
|
||||||
|
Loading…
Reference in New Issue
Block a user