feat(sync): перевёл группы синхронизации на Room и добавил контроль совместимости
This commit is contained in:
@@ -30,6 +30,15 @@ class UnlockManager(
|
||||
get() = _openedStorages
|
||||
private val mutex = Mutex()
|
||||
|
||||
override fun getOpenedStorageKey(uuid: UUID): EncryptKey? {
|
||||
val opened = _openedStorages.value
|
||||
val direct = opened[uuid]
|
||||
if (direct != null) {
|
||||
return direct.getKey()
|
||||
}
|
||||
return null
|
||||
}
|
||||
|
||||
init {
|
||||
CoroutineScope(ioDispatcher).launch {
|
||||
vaultsManager.allStorages.collect {
|
||||
|
||||
@@ -53,6 +53,8 @@ class EncryptedStorage private constructor(
|
||||
throw Exception("Incorrect key") // TODO
|
||||
}
|
||||
|
||||
fun getKey(): EncryptKey = EncryptKey(key.bytes)
|
||||
|
||||
override fun dispose() {
|
||||
_accessor.dispose()
|
||||
job.cancel()
|
||||
|
||||
@@ -263,14 +263,7 @@ class EncryptedStorageAccessor(
|
||||
appendSyncEntry(path = path, operation = StorageSyncOperation.DELETE)
|
||||
}
|
||||
|
||||
override suspend fun openWrite(path: String): OutputStream {
|
||||
val stream = source.openWrite(encryptPath(path))
|
||||
return dataEncryptor.encryptStream(stream).onClosed {
|
||||
scope.launch {
|
||||
appendSyncEntry(path = path, operation = StorageSyncOperation.UPSERT)
|
||||
}
|
||||
}
|
||||
}
|
||||
override suspend fun openWrite(path: String): OutputStream = openWriteInternal(path, recordJournal = true)
|
||||
|
||||
override suspend fun openRead(path: String): InputStream {
|
||||
val stream = source.openRead(encryptPath(path))
|
||||
@@ -290,7 +283,7 @@ class EncryptedStorageAccessor(
|
||||
val path = Path(systemHiddenDirName, name).pathString
|
||||
return@run try {
|
||||
openRead(path)
|
||||
} catch (_: FileNotFoundException) {
|
||||
} catch (_: Exception) {
|
||||
// Как у Yandex/Local: системного файла ещё нет — создаём пустой и читаем снова.
|
||||
openWriteSystemFile(name).use { }
|
||||
openRead(path)
|
||||
@@ -300,7 +293,7 @@ class EncryptedStorageAccessor(
|
||||
override suspend fun openWriteSystemFile(name: String): OutputStream = scope.run {
|
||||
val path = Path(systemHiddenDirName, name).pathString
|
||||
systemHiddenFilesIsActual = false
|
||||
return@run openWrite(path).onClosing {
|
||||
return@run openWriteInternal(path, recordJournal = false).onClosing {
|
||||
systemHiddenFilesIsActual = false
|
||||
}
|
||||
}
|
||||
@@ -393,6 +386,9 @@ class EncryptedStorageAccessor(
|
||||
|
||||
private suspend fun appendSyncEntry(path: String, operation: StorageSyncOperation) {
|
||||
val cleanedPath = if (path.startsWith("/")) path else "/$path"
|
||||
if (cleanedPath.startsWith("/$systemHiddenDirName/")) {
|
||||
return
|
||||
}
|
||||
val entries = readSyncJournal()
|
||||
val nextSequence = (entries.maxOfOrNull { it.revision.sequence } ?: 0L) + 1L
|
||||
appendSyncJournal(
|
||||
@@ -410,6 +406,19 @@ class EncryptedStorageAccessor(
|
||||
)
|
||||
}
|
||||
|
||||
private suspend fun openWriteInternal(path: String, recordJournal: Boolean): OutputStream {
|
||||
val stream = source.openWrite(encryptPath(path))
|
||||
val encrypted = dataEncryptor.encryptStream(stream)
|
||||
if (!recordJournal) {
|
||||
return encrypted
|
||||
}
|
||||
return encrypted.onClosed {
|
||||
scope.launch {
|
||||
appendSyncEntry(path = path, operation = StorageSyncOperation.UPSERT)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun Iterable<IFile>.filterSystemHiddenFiles(): List<IFile> {
|
||||
return this.filter { file ->
|
||||
!file.metaInfo.path.contains(
|
||||
|
||||
Reference in New Issue
Block a user