mirror of
https://github.com/vector-im/element-android.git
synced 2024-11-16 02:05:06 +08:00
Encrypt file WIP
This commit is contained in:
parent
014d03893a
commit
0c2d3f36c3
@ -42,7 +42,7 @@ object MXEncryptedAttachments {
|
||||
*/
|
||||
data class EncryptionResult(
|
||||
var encryptedFileInfo: EncryptedFileInfo,
|
||||
var encryptedStream: InputStream
|
||||
var encryptedByteArray: ByteArray
|
||||
)
|
||||
|
||||
/***
|
||||
@ -112,7 +112,7 @@ object MXEncryptedAttachments {
|
||||
hashes = mapOf("sha256" to base64ToUnpaddedBase64(Base64.encodeToString(messageDigest.digest(), Base64.DEFAULT))!!),
|
||||
v = "v2"
|
||||
),
|
||||
encryptedStream = ByteArrayInputStream(outStream.toByteArray())
|
||||
encryptedByteArray = outStream.toByteArray()
|
||||
)
|
||||
|
||||
outStream.close()
|
||||
|
@ -25,13 +25,17 @@ import im.vector.matrix.android.api.session.events.model.Event
|
||||
import im.vector.matrix.android.api.session.events.model.toContent
|
||||
import im.vector.matrix.android.api.session.events.model.toModel
|
||||
import im.vector.matrix.android.api.session.room.model.message.*
|
||||
import im.vector.matrix.android.internal.crypto.attachments.MXEncryptedAttachments
|
||||
import im.vector.matrix.android.internal.crypto.model.rest.EncryptedFileInfo
|
||||
import im.vector.matrix.android.internal.network.ProgressRequestBody
|
||||
import im.vector.matrix.android.internal.session.room.send.SendEventWorker
|
||||
import im.vector.matrix.android.internal.worker.SessionWorkerParams
|
||||
import im.vector.matrix.android.internal.worker.WorkerParamsFactory
|
||||
import im.vector.matrix.android.internal.worker.getSessionComponent
|
||||
import timber.log.Timber
|
||||
import java.io.ByteArrayInputStream
|
||||
import java.io.File
|
||||
import java.io.FileInputStream
|
||||
import javax.inject.Inject
|
||||
|
||||
|
||||
@ -42,7 +46,8 @@ internal class UploadContentWorker(context: Context, params: WorkerParameters) :
|
||||
override val userId: String,
|
||||
val roomId: String,
|
||||
val event: Event,
|
||||
val attachment: ContentAttachmentData
|
||||
val attachment: ContentAttachmentData,
|
||||
val isRoomEncrypted: Boolean
|
||||
) : SessionWorkerParams
|
||||
|
||||
@Inject lateinit var fileUploader: FileUploader
|
||||
@ -58,17 +63,33 @@ internal class UploadContentWorker(context: Context, params: WorkerParameters) :
|
||||
val eventId = params.event.eventId ?: return Result.success()
|
||||
val attachment = params.attachment
|
||||
|
||||
val isRoomEncrypted = params.isRoomEncrypted
|
||||
|
||||
|
||||
val thumbnailData = ThumbnailExtractor.extractThumbnail(params.attachment)
|
||||
val attachmentFile = createAttachmentFile(attachment) ?: return Result.failure()
|
||||
var uploadedThumbnailUrl: String? = null
|
||||
var uploadedThumbnailEncryptedFileInfo: EncryptedFileInfo? = null
|
||||
|
||||
if (thumbnailData != null) {
|
||||
fileUploader
|
||||
.uploadByteArray(thumbnailData.bytes, "thumb_${attachment.name}", thumbnailData.mimeType)
|
||||
if (isRoomEncrypted) {
|
||||
Timber.v("Encrypt thumbnail")
|
||||
val encryptionResult = MXEncryptedAttachments.encryptAttachment(ByteArrayInputStream(thumbnailData.bytes), thumbnailData.mimeType)
|
||||
?: return Result.failure()
|
||||
|
||||
uploadedThumbnailEncryptedFileInfo = encryptionResult.encryptedFileInfo
|
||||
|
||||
fileUploader
|
||||
.uploadByteArray(encryptionResult.encryptedByteArray, "thumb_${attachment.name}", thumbnailData.mimeType)
|
||||
} else {
|
||||
fileUploader
|
||||
.uploadByteArray(thumbnailData.bytes, "thumb_${attachment.name}", thumbnailData.mimeType)
|
||||
}
|
||||
.fold(
|
||||
{ Timber.e(it) },
|
||||
{ uploadedThumbnailUrl = it.contentUri }
|
||||
)
|
||||
|
||||
}
|
||||
|
||||
val progressListener = object : ProgressRequestBody.Listener {
|
||||
@ -76,12 +97,28 @@ internal class UploadContentWorker(context: Context, params: WorkerParameters) :
|
||||
contentUploadStateTracker.setProgress(eventId, current, total)
|
||||
}
|
||||
}
|
||||
return fileUploader
|
||||
.uploadFile(attachmentFile, attachment.name, attachment.mimeType, progressListener)
|
||||
|
||||
var uploadedFileEncryptedFileInfo: EncryptedFileInfo? = null
|
||||
|
||||
return if (isRoomEncrypted) {
|
||||
Timber.v("Encrypt file")
|
||||
|
||||
val encryptionResult = MXEncryptedAttachments.encryptAttachment(FileInputStream(attachmentFile), attachment.mimeType)
|
||||
?: return Result.failure()
|
||||
|
||||
uploadedFileEncryptedFileInfo = encryptionResult.encryptedFileInfo
|
||||
|
||||
fileUploader
|
||||
.uploadByteArray(encryptionResult.encryptedByteArray, attachment.name, attachment.mimeType, progressListener)
|
||||
} else {
|
||||
fileUploader
|
||||
.uploadFile(attachmentFile, attachment.name, attachment.mimeType, progressListener)
|
||||
}
|
||||
.fold(
|
||||
{ handleFailure(params) },
|
||||
{ handleSuccess(params, it.contentUri, uploadedThumbnailUrl) }
|
||||
{ handleSuccess(params, it.contentUri, uploadedFileEncryptedFileInfo, uploadedThumbnailUrl, uploadedThumbnailEncryptedFileInfo) }
|
||||
)
|
||||
|
||||
}
|
||||
|
||||
private fun createAttachmentFile(attachment: ContentAttachmentData): File? {
|
||||
@ -100,39 +137,67 @@ internal class UploadContentWorker(context: Context, params: WorkerParameters) :
|
||||
|
||||
private fun handleSuccess(params: Params,
|
||||
attachmentUrl: String,
|
||||
thumbnailUrl: String?): Result {
|
||||
encryptedFileInfo: EncryptedFileInfo?,
|
||||
thumbnailUrl: String?,
|
||||
thumbnailEncryptedFileInfo: EncryptedFileInfo?): Result {
|
||||
contentUploadStateTracker.setSuccess(params.event.eventId!!)
|
||||
val event = updateEvent(params.event, attachmentUrl, thumbnailUrl)
|
||||
val event = updateEvent(params.event, attachmentUrl, encryptedFileInfo, thumbnailUrl, thumbnailEncryptedFileInfo)
|
||||
val sendParams = SendEventWorker.Params(params.userId, params.roomId, event)
|
||||
return Result.success(WorkerParamsFactory.toData(sendParams))
|
||||
}
|
||||
|
||||
private fun updateEvent(event: Event, url: String, thumbnailUrl: String? = null): Event {
|
||||
private fun updateEvent(event: Event,
|
||||
url: String,
|
||||
encryptedFileInfo: EncryptedFileInfo?,
|
||||
thumbnailUrl: String? = null,
|
||||
thumbnailEncryptedFileInfo: EncryptedFileInfo?): Event {
|
||||
val messageContent: MessageContent = event.content.toModel() ?: return event
|
||||
val updatedContent = when (messageContent) {
|
||||
is MessageImageContent -> messageContent.update(url)
|
||||
is MessageVideoContent -> messageContent.update(url, thumbnailUrl)
|
||||
is MessageFileContent -> messageContent.update(url)
|
||||
is MessageAudioContent -> messageContent.update(url)
|
||||
is MessageImageContent -> messageContent.update(url, encryptedFileInfo)
|
||||
is MessageVideoContent -> messageContent.update(url, encryptedFileInfo, thumbnailUrl, thumbnailEncryptedFileInfo)
|
||||
is MessageFileContent -> messageContent.update(url, encryptedFileInfo)
|
||||
is MessageAudioContent -> messageContent.update(url, encryptedFileInfo)
|
||||
else -> messageContent
|
||||
}
|
||||
return event.copy(content = updatedContent.toContent())
|
||||
}
|
||||
|
||||
private fun MessageImageContent.update(url: String): MessageImageContent {
|
||||
return copy(url = url)
|
||||
private fun MessageImageContent.update(url: String,
|
||||
encryptedFileInfo: EncryptedFileInfo?): MessageImageContent {
|
||||
return copy(
|
||||
url = url,
|
||||
encryptedFileInfo = encryptedFileInfo
|
||||
)
|
||||
}
|
||||
|
||||
private fun MessageVideoContent.update(url: String, thumbnailUrl: String?): MessageVideoContent {
|
||||
return copy(url = url, videoInfo = videoInfo?.copy(thumbnailUrl = thumbnailUrl))
|
||||
private fun MessageVideoContent.update(url: String,
|
||||
encryptedFileInfo: EncryptedFileInfo?,
|
||||
thumbnailUrl: String?,
|
||||
thumbnailEncryptedFileInfo: EncryptedFileInfo?): MessageVideoContent {
|
||||
return copy(
|
||||
url = url,
|
||||
encryptedFileInfo = encryptedFileInfo,
|
||||
videoInfo = videoInfo?.copy(
|
||||
thumbnailUrl = thumbnailUrl,
|
||||
thumbnailFile = thumbnailEncryptedFileInfo
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
private fun MessageFileContent.update(url: String): MessageFileContent {
|
||||
return copy(url = url)
|
||||
private fun MessageFileContent.update(url: String,
|
||||
encryptedFileInfo: EncryptedFileInfo?): MessageFileContent {
|
||||
return copy(
|
||||
url = url,
|
||||
encryptedFileInfo = encryptedFileInfo
|
||||
)
|
||||
}
|
||||
|
||||
private fun MessageAudioContent.update(url: String): MessageAudioContent {
|
||||
return copy(url = url)
|
||||
private fun MessageAudioContent.update(url: String,
|
||||
encryptedFileInfo: EncryptedFileInfo?): MessageAudioContent {
|
||||
return copy(
|
||||
url = url,
|
||||
encryptedFileInfo = encryptedFileInfo
|
||||
)
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -101,7 +101,7 @@ internal class DefaultSendService @Inject constructor(private val context: Conte
|
||||
val event = localEchoEventFactory.createMediaEvent(roomId, attachment).also {
|
||||
saveLocalEcho(it)
|
||||
}
|
||||
val uploadWork = createUploadMediaWork(event, attachment)
|
||||
val uploadWork = createUploadMediaWork(event, attachment, cryptoService.isRoomEncrypted(roomId))
|
||||
val sendWork = createSendEventWork(event)
|
||||
|
||||
WorkManager.getInstance(context)
|
||||
@ -148,8 +148,8 @@ internal class DefaultSendService @Inject constructor(private val context: Conte
|
||||
return TimelineSendEventWorkCommon.createWork<RedactEventWorker>(redactWorkData)
|
||||
}
|
||||
|
||||
private fun createUploadMediaWork(event: Event, attachment: ContentAttachmentData): OneTimeWorkRequest {
|
||||
val uploadMediaWorkerParams = UploadContentWorker.Params(credentials.userId, roomId, event, attachment)
|
||||
private fun createUploadMediaWork(event: Event, attachment: ContentAttachmentData, isRoomEncrypted: Boolean): OneTimeWorkRequest {
|
||||
val uploadMediaWorkerParams = UploadContentWorker.Params(credentials.userId, roomId, event, attachment, isRoomEncrypted)
|
||||
val uploadWorkData = WorkerParamsFactory.toData(uploadMediaWorkerParams)
|
||||
|
||||
return OneTimeWorkRequestBuilder<UploadContentWorker>()
|
||||
|
Loading…
Reference in New Issue
Block a user