feat: trust dialog and processing attachments for users after trusting them

This commit is contained in:
jubb
2021-07-09 15:13:43 +10:00
parent bc4f660fb0
commit 9dfd051e63
18 changed files with 230 additions and 59 deletions

View File

@@ -3,6 +3,7 @@ package org.session.libsession.database
import org.session.libsession.messaging.sending_receiving.attachments.*
import org.session.libsession.utilities.Address
import org.session.libsession.utilities.UploadResult
import org.session.libsession.utilities.recipients.Recipient
import org.session.libsignal.messages.SignalServiceAttachmentPointer
import org.session.libsignal.messages.SignalServiceAttachmentStream
import java.io.InputStream
@@ -29,4 +30,5 @@ interface MessageDataProvider {
fun getMessageBodyFor(timestamp: Long, author: String): String
fun getAttachmentIDsFor(messageID: Long): List<Long>
fun getLinkPreviewAttachmentIDFor(messageID: Long): Long?
fun getIndividualRecipientForMms(mmsId: Long): Recipient?
}

View File

@@ -139,6 +139,7 @@ interface StorageProtocol {
fun getContactWithSessionID(sessionID: String): Contact?
fun getAllContacts(): Set<Contact>
fun setContact(contact: Contact)
fun getRecipientForThread(threadId: Long): Recipient?
fun getRecipientSettings(address: Address): RecipientSettings?
fun addContacts(contacts: List<ConfigurationMessage.Contact>)

View File

@@ -17,6 +17,7 @@ import org.session.libsignal.utilities.Log
import java.io.File
import java.io.FileInputStream
import java.io.InputStream
import java.lang.NullPointerException
class AttachmentDownloadJob(val attachmentID: Long, val databaseMessageID: Long) : Job {
override var delegate: JobDelegate? = null
@@ -26,6 +27,8 @@ class AttachmentDownloadJob(val attachmentID: Long, val databaseMessageID: Long)
// Error
internal sealed class Error(val description: String) : Exception(description) {
object NoAttachment : Error("No such attachment.")
object NoThread: Error("Thread no longer exists")
object NoSender: Error("Thread recipient or sender does not exist")
}
// Settings
@@ -42,8 +45,12 @@ class AttachmentDownloadJob(val attachmentID: Long, val databaseMessageID: Long)
override fun execute() {
val storage = MessagingModuleConfiguration.shared.storage
val messageDataProvider = MessagingModuleConfiguration.shared.messageDataProvider
val threadID = storage.getThreadIdForMms(databaseMessageID)
val handleFailure: (java.lang.Exception, attachmentId: AttachmentId?) -> Unit = { exception, attachment ->
if (exception == Error.NoAttachment
|| exception == Error.NoThread
|| exception == Error.NoSender
|| (exception is OnionRequestAPI.HTTPRequestFailedAtDestinationException && exception.statusCode == 400)) {
attachment?.let { id ->
messageDataProvider.setAttachmentState(AttachmentState.FAILED, id, databaseMessageID)
@@ -55,13 +62,34 @@ class AttachmentDownloadJob(val attachmentID: Long, val databaseMessageID: Long)
this.handleFailure(exception)
}
}
if (threadID < 0) {
Log.e("Loki", "Thread doesn't exist for database message ID $databaseMessageID")
handleFailure(Error.NoThread, null)
return
}
val threadRecipient = storage.getRecipientForThread(threadID)
val sender = messageDataProvider.getIndividualRecipientForMms(databaseMessageID)
val contact = sender?.address?.let { storage.getContactWithSessionID(it.serialize()) }
if (threadRecipient == null || sender == null || contact == null) {
handleFailure(Error.NoSender, null)
return
}
if (!threadRecipient.isGroupRecipient && (!contact.isTrusted || storage.getUserPublicKey() != sender.address.serialize())) {
Log.e("Loki", "Thread isn't a group recipient, or contact isn't trusted or self-send")
return
}
var tempFile: File? = null
try {
val attachment = messageDataProvider.getDatabaseAttachment(attachmentID)
?: return handleFailure(Error.NoAttachment, null)
if (attachment.hasData()) {
Log.d("Loki", "The attachment $attachmentID already has data")
}
messageDataProvider.setAttachmentState(AttachmentState.STARTED, attachment.attachmentId, this.databaseMessageID)
tempFile = createTempFile()
val threadID = storage.getThreadIdForMms(databaseMessageID)
val openGroupV2 = storage.getV2OpenGroup(threadID)
if (openGroupV2 == null) {
DownloadUtilities.downloadFile(tempFile, attachment.url)
@@ -94,7 +122,7 @@ class AttachmentDownloadJob(val attachmentID: Long, val databaseMessageID: Long)
handleSuccess()
} catch (e: Exception) {
tempFile?.delete()
return handleFailure(e)
return handleFailure(e,null)
}
}

View File

@@ -100,6 +100,23 @@ class JobQueue : JobDelegate {
Log.d("Loki", "resumed pending send message $id")
}
fun resumePendingJobs(typeKey: String) {
val allPendingJobs = MessagingModuleConfiguration.shared.storage.getAllPendingJobs(typeKey)
val pendingJobs = mutableListOf<Job>()
for ((id, job) in allPendingJobs) {
if (job == null) {
// Job failed to deserialize, remove it from the DB
handleJobFailedPermanently(id)
} else {
pendingJobs.add(job)
}
}
pendingJobs.sortedBy { it.id }.forEach { job ->
Log.i("Loki", "Resuming pending job of type: ${job::class.simpleName}.")
queue.offer(job) // Offer always called on unlimited capacity
}
}
fun resumePendingJobs() {
if (hasResumedPendingJobs) {
Log.d("Loki", "resumePendingJobs() should only be called once.")
@@ -114,20 +131,7 @@ class JobQueue : JobDelegate {
NotifyPNServerJob.KEY
)
allJobTypes.forEach { type ->
val allPendingJobs = MessagingModuleConfiguration.shared.storage.getAllPendingJobs(type)
val pendingJobs = mutableListOf<Job>()
for ((id, job) in allPendingJobs) {
if (job == null) {
// Job failed to deserialize, remove it from the DB
handleJobFailedPermanently(id)
} else {
pendingJobs.add(job)
}
}
pendingJobs.sortedBy { it.id }.forEach { job ->
Log.i("Loki", "Resuming pending job of type: ${job::class.simpleName}.")
queue.offer(job) // Offer always called on unlimited capacity
}
resumePendingJobs(type)
}
}

View File

@@ -221,17 +221,10 @@ fun MessageReceiver.handleVisibleMessage(message: VisibleMessage, proto: SignalS
val messageID = storage.persist(message, quoteModel, linkPreviews, message.groupPublicKey, openGroupID, attachments) ?: throw MessageReceiver.Error.DuplicateMessage
// Parse & persist attachments
// Start attachment downloads if needed
val contact = message.sender?.let { address -> storage.getContactWithSessionID(address) }
storage.getAttachmentsForMessage(messageID).forEach { attachment ->
attachment.attachmentId?.let { id ->
// if open group or self-send, then always download attachment
val immediatelyDownload = !openGroupID.isNullOrEmpty() // open group
|| userPublicKey == message.sender // self-send
|| contact?.isTrusted == true // trusted contact
if (immediatelyDownload) {
val downloadJob = AttachmentDownloadJob(id.rowId, messageID)
JobQueue.shared.add(downloadJob)
}
val downloadJob = AttachmentDownloadJob(id.rowId, messageID)
JobQueue.shared.add(downloadJob)
}
}
val openGroupServerID = message.openGroupServerMessageID