Encrypted files: store decrypted file in a dedicated folder
This commit is contained in:
parent
237cb63fc2
commit
62791e4b36
|
@ -60,10 +60,15 @@ interface FileService {
|
|||
fun fileState(mxcUrl: String, mimeType: String?): FileState
|
||||
|
||||
/**
|
||||
* Clears all the files downloaded by the service
|
||||
* Clears all the files downloaded by the service, including decrypted files
|
||||
*/
|
||||
fun clearCache()
|
||||
|
||||
/**
|
||||
* Clears all the decrypted files by the service
|
||||
*/
|
||||
fun clearDecryptedCache()
|
||||
|
||||
/**
|
||||
* Get size of cached files
|
||||
*/
|
||||
|
|
|
@ -63,7 +63,15 @@ internal class DefaultFileService @Inject constructor(
|
|||
|
||||
private fun String.safeFileName() = URLEncoder.encode(this, Charsets.US_ASCII.displayName())
|
||||
|
||||
private val downloadFolder = File(sessionCacheDirectory, "MF")
|
||||
// Folder to store downloaded file (not decrypted)
|
||||
private val legacyFolder = File(sessionCacheDirectory, "MF")
|
||||
private val downloadFolder = File(sessionCacheDirectory, "F")
|
||||
private val decryptedFolder = File(downloadFolder, "D")
|
||||
|
||||
init {
|
||||
// Clear the legacy downloaded files
|
||||
legacyFolder.deleteRecursively()
|
||||
}
|
||||
|
||||
/**
|
||||
* Retain ongoing downloads to avoid re-downloading and already downloading file
|
||||
|
@ -103,8 +111,8 @@ internal class DefaultFileService @Inject constructor(
|
|||
return taskExecutor.executorScope.launch(coroutineDispatchers.main) {
|
||||
withContext(coroutineDispatchers.io) {
|
||||
Try {
|
||||
if (!downloadFolder.exists()) {
|
||||
downloadFolder.mkdirs()
|
||||
if (!decryptedFolder.exists()) {
|
||||
decryptedFolder.mkdirs()
|
||||
}
|
||||
// ensure we use unique file name by using URL (mapped to suitable file name)
|
||||
// Also we need to add extension for the FileProvider, if not it lot's of app that it's
|
||||
|
@ -134,29 +142,42 @@ internal class DefaultFileService @Inject constructor(
|
|||
|
||||
Timber.v("Response size ${response.body?.contentLength()} - Stream available: ${!source.exhausted()}")
|
||||
|
||||
if (elementToDecrypt != null) {
|
||||
Timber.v("## FileService: decrypt file")
|
||||
val decryptSuccess = destFile.outputStream().buffered().use {
|
||||
MXEncryptedAttachments.decryptAttachment(
|
||||
source.inputStream(),
|
||||
elementToDecrypt,
|
||||
it
|
||||
)
|
||||
}
|
||||
response.close()
|
||||
if (!decryptSuccess) {
|
||||
return@flatMap Try.Failure(IllegalStateException("Decryption error"))
|
||||
}
|
||||
} else {
|
||||
writeToFile(source.inputStream(), destFile)
|
||||
response.close()
|
||||
}
|
||||
// Write the file to cache (encrypted version if the file is encrypted)
|
||||
writeToFile(source.inputStream(), destFile)
|
||||
response.close()
|
||||
} else {
|
||||
Timber.v("## FileService: cache hit for $url")
|
||||
}
|
||||
|
||||
Try.just(destFile)
|
||||
}
|
||||
}.flatMap { downloadedFile ->
|
||||
// Decrypt if necessary
|
||||
if (elementToDecrypt != null) {
|
||||
val decryptedFile = File(decryptedFolder, fileForUrl(unwrappedUrl, mimeType))
|
||||
|
||||
if (!decryptedFile.exists()) {
|
||||
Timber.v("## FileService: decrypt file")
|
||||
val decryptSuccess = decryptedFile.outputStream().buffered().use { outputStream ->
|
||||
downloadedFile.inputStream().use { inputStream ->
|
||||
MXEncryptedAttachments.decryptAttachment(
|
||||
inputStream,
|
||||
elementToDecrypt,
|
||||
outputStream
|
||||
)
|
||||
}
|
||||
}
|
||||
if (!decryptSuccess) {
|
||||
return@flatMap Try.Failure(IllegalStateException("Decryption error"))
|
||||
}
|
||||
} else {
|
||||
Timber.v("## FileService: cache hit for decrypted file")
|
||||
}
|
||||
Try.just(decryptedFile)
|
||||
} else {
|
||||
// Clear file
|
||||
Try.just(downloadedFile)
|
||||
}
|
||||
}.fold(
|
||||
{ throwable ->
|
||||
callback.onFailure(throwable)
|
||||
|
@ -240,4 +261,8 @@ internal class DefaultFileService @Inject constructor(
|
|||
override fun clearCache() {
|
||||
downloadFolder.deleteRecursively()
|
||||
}
|
||||
|
||||
override fun clearDecryptedCache() {
|
||||
decryptedFolder.deleteRecursively()
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue