Класс шифрования готов
This commit is contained in:
@@ -3,9 +3,9 @@ package com.github.nullptroma.wallenc.data.vaults.local
|
|||||||
import com.fasterxml.jackson.core.JacksonException
|
import com.fasterxml.jackson.core.JacksonException
|
||||||
import com.fasterxml.jackson.module.kotlin.jacksonObjectMapper
|
import com.fasterxml.jackson.module.kotlin.jacksonObjectMapper
|
||||||
import com.fasterxml.jackson.module.kotlin.readValue
|
import com.fasterxml.jackson.module.kotlin.readValue
|
||||||
import com.github.nullptroma.wallenc.data.vaults.local.entity.LocalDirectory
|
import com.github.nullptroma.wallenc.domain.common.impl.CommonDirectory
|
||||||
import com.github.nullptroma.wallenc.data.vaults.local.entity.LocalFile
|
import com.github.nullptroma.wallenc.domain.common.impl.CommonFile
|
||||||
import com.github.nullptroma.wallenc.data.vaults.local.entity.LocalMetaInfo
|
import com.github.nullptroma.wallenc.domain.common.impl.CommonMetaInfo
|
||||||
import com.github.nullptroma.wallenc.domain.datatypes.DataPackage
|
import com.github.nullptroma.wallenc.domain.datatypes.DataPackage
|
||||||
import com.github.nullptroma.wallenc.domain.datatypes.DataPage
|
import com.github.nullptroma.wallenc.domain.datatypes.DataPage
|
||||||
import com.github.nullptroma.wallenc.domain.interfaces.IDirectory
|
import com.github.nullptroma.wallenc.domain.interfaces.IDirectory
|
||||||
@@ -114,7 +114,7 @@ class LocalStorageAccessor(
|
|||||||
private class LocalStorageFilePair private constructor(
|
private class LocalStorageFilePair private constructor(
|
||||||
val file: File,
|
val file: File,
|
||||||
val metaFile: File,
|
val metaFile: File,
|
||||||
val meta: LocalMetaInfo
|
val meta: CommonMetaInfo
|
||||||
) {
|
) {
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
@@ -135,23 +135,23 @@ class LocalStorageAccessor(
|
|||||||
}
|
}
|
||||||
)
|
)
|
||||||
val metaFile = metaFilePath.toFile()
|
val metaFile = metaFilePath.toFile()
|
||||||
val metaInfo: LocalMetaInfo
|
val metaInfo: CommonMetaInfo
|
||||||
val storageFilePath = "/" + filePath.relativeTo(filesystemBasePath)
|
val storageFilePath = "/" + filePath.relativeTo(filesystemBasePath)
|
||||||
|
|
||||||
if (!metaFile.exists()) {
|
if (!metaFile.exists()) {
|
||||||
metaInfo = LocalMetaInfo(
|
metaInfo = CommonMetaInfo(
|
||||||
size = filePath.fileSize(),
|
size = filePath.fileSize(),
|
||||||
path = storageFilePath
|
path = storageFilePath
|
||||||
)
|
)
|
||||||
_jackson.writeValue(metaFile, metaInfo)
|
_jackson.writeValue(metaFile, metaInfo)
|
||||||
} else {
|
} else {
|
||||||
var readMeta: LocalMetaInfo
|
var readMeta: CommonMetaInfo
|
||||||
try {
|
try {
|
||||||
val reader = metaFile.bufferedReader()
|
val reader = metaFile.bufferedReader()
|
||||||
readMeta = _jackson.readValue(reader)
|
readMeta = _jackson.readValue(reader)
|
||||||
} catch (e: JacksonException) {
|
} catch (e: JacksonException) {
|
||||||
// если файл повреждён - пересоздать
|
// если файл повреждён - пересоздать
|
||||||
readMeta = LocalMetaInfo(
|
readMeta = CommonMetaInfo(
|
||||||
size = filePath.fileSize(),
|
size = filePath.fileSize(),
|
||||||
path = storageFilePath
|
path = storageFilePath
|
||||||
)
|
)
|
||||||
@@ -174,7 +174,7 @@ class LocalStorageAccessor(
|
|||||||
var pair: LocalStorageFilePair? = null
|
var pair: LocalStorageFilePair? = null
|
||||||
try {
|
try {
|
||||||
val reader = metaFile.bufferedReader()
|
val reader = metaFile.bufferedReader()
|
||||||
val metaInfo: LocalMetaInfo = _jackson.readValue(reader)
|
val metaInfo: CommonMetaInfo = _jackson.readValue(reader)
|
||||||
val pathString = Path(filesystemBasePath.pathString, metaInfo.path).pathString
|
val pathString = Path(filesystemBasePath.pathString, metaInfo.path).pathString
|
||||||
val file = File(pathString)
|
val file = File(pathString)
|
||||||
if (!file.exists()) {
|
if (!file.exists()) {
|
||||||
@@ -213,8 +213,8 @@ class LocalStorageAccessor(
|
|||||||
private suspend fun scanStorage(
|
private suspend fun scanStorage(
|
||||||
baseStoragePath: String,
|
baseStoragePath: String,
|
||||||
maxDepth: Int,
|
maxDepth: Int,
|
||||||
fileCallback: (suspend (File, LocalFile) -> Unit)? = null,
|
fileCallback: (suspend (File, CommonFile) -> Unit)? = null,
|
||||||
dirCallback: (suspend (File, LocalDirectory) -> Unit)? = null
|
dirCallback: (suspend (File, CommonDirectory) -> Unit)? = null
|
||||||
) {
|
) {
|
||||||
if (!checkAvailable())
|
if (!checkAvailable())
|
||||||
throw Exception("Not available")
|
throw Exception("Not available")
|
||||||
@@ -234,9 +234,9 @@ class LocalStorageAccessor(
|
|||||||
workedMetaFiles.add(pair.metaFile.absolutePath)
|
workedMetaFiles.add(pair.metaFile.absolutePath)
|
||||||
|
|
||||||
if (pair.file.isFile) {
|
if (pair.file.isFile) {
|
||||||
fileCallback?.invoke(pair.file, LocalFile(pair.meta))
|
fileCallback?.invoke(pair.file, CommonFile(pair.meta))
|
||||||
} else {
|
} else {
|
||||||
dirCallback?.invoke(pair.file, LocalDirectory(pair.meta, null))
|
dirCallback?.invoke(pair.file, CommonDirectory(pair.meta, null))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
@@ -257,8 +257,8 @@ class LocalStorageAccessor(
|
|||||||
var size = 0L
|
var size = 0L
|
||||||
var numOfFiles = 0
|
var numOfFiles = 0
|
||||||
|
|
||||||
scanStorage(baseStoragePath = "/", maxDepth = -1, fileCallback = { _, localFile ->
|
scanStorage(baseStoragePath = "/", maxDepth = -1, fileCallback = { _, CommonFile ->
|
||||||
size += localFile.metaInfo.size
|
size += CommonFile.metaInfo.size
|
||||||
numOfFiles++
|
numOfFiles++
|
||||||
|
|
||||||
if(numOfFiles % DATA_PAGE_LENGTH == 0) {
|
if(numOfFiles % DATA_PAGE_LENGTH == 0) {
|
||||||
@@ -276,8 +276,8 @@ class LocalStorageAccessor(
|
|||||||
return@withContext listOf()
|
return@withContext listOf()
|
||||||
|
|
||||||
val list = mutableListOf<IFile>()
|
val list = mutableListOf<IFile>()
|
||||||
scanStorage(baseStoragePath = "/", maxDepth = -1, fileCallback = { _, localFile ->
|
scanStorage(baseStoragePath = "/", maxDepth = -1, fileCallback = { _, CommonFile ->
|
||||||
list.add(localFile)
|
list.add(CommonFile)
|
||||||
})
|
})
|
||||||
return@withContext list
|
return@withContext list
|
||||||
}
|
}
|
||||||
@@ -287,8 +287,8 @@ class LocalStorageAccessor(
|
|||||||
return@withContext listOf()
|
return@withContext listOf()
|
||||||
|
|
||||||
val list = mutableListOf<IFile>()
|
val list = mutableListOf<IFile>()
|
||||||
scanStorage(baseStoragePath = path, maxDepth = 0, fileCallback = { _, localFile ->
|
scanStorage(baseStoragePath = path, maxDepth = 0, fileCallback = { _, CommonFile ->
|
||||||
list.add(localFile)
|
list.add(CommonFile)
|
||||||
})
|
})
|
||||||
return@withContext list
|
return@withContext list
|
||||||
}
|
}
|
||||||
@@ -299,7 +299,7 @@ class LocalStorageAccessor(
|
|||||||
|
|
||||||
val buf = mutableListOf<IFile>()
|
val buf = mutableListOf<IFile>()
|
||||||
var pageNumber = 0
|
var pageNumber = 0
|
||||||
scanStorage(baseStoragePath = path, maxDepth = 0, fileCallback = { _, localFile ->
|
scanStorage(baseStoragePath = path, maxDepth = 0, fileCallback = { _, CommonFile ->
|
||||||
if (buf.size == DATA_PAGE_LENGTH) {
|
if (buf.size == DATA_PAGE_LENGTH) {
|
||||||
val page = DataPage(
|
val page = DataPage(
|
||||||
list = buf.toList(),
|
list = buf.toList(),
|
||||||
@@ -312,7 +312,7 @@ class LocalStorageAccessor(
|
|||||||
emit(page)
|
emit(page)
|
||||||
buf.clear()
|
buf.clear()
|
||||||
}
|
}
|
||||||
buf.add(localFile)
|
buf.add(CommonFile)
|
||||||
})
|
})
|
||||||
// отправка последней страницы
|
// отправка последней страницы
|
||||||
val page = DataPage(
|
val page = DataPage(
|
||||||
@@ -381,11 +381,11 @@ class LocalStorageAccessor(
|
|||||||
emit(page)
|
emit(page)
|
||||||
}.flowOn(ioDispatcher)
|
}.flowOn(ioDispatcher)
|
||||||
|
|
||||||
private fun writeMeta(metaFile: File, meta: LocalMetaInfo) {
|
private fun writeMeta(metaFile: File, meta: CommonMetaInfo) {
|
||||||
_jackson.writeValue(metaFile, meta)
|
_jackson.writeValue(metaFile, meta)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun createFile(storagePath: String): LocalFile {
|
private fun createFile(storagePath: String): CommonFile {
|
||||||
val path = Path(_filesystemBasePath.pathString, storagePath)
|
val path = Path(_filesystemBasePath.pathString, storagePath)
|
||||||
val file = path.toFile()
|
val file = path.toFile()
|
||||||
if(file.exists() && file.isDirectory) {
|
if(file.exists() && file.isDirectory) {
|
||||||
@@ -398,10 +398,10 @@ class LocalStorageAccessor(
|
|||||||
val pair = LocalStorageFilePair.from(_filesystemBasePath, file) ?: throw Exception("Что то пошло не так") // TODO
|
val pair = LocalStorageFilePair.from(_filesystemBasePath, file) ?: throw Exception("Что то пошло не так") // TODO
|
||||||
val newMeta = pair.meta.copy(lastModified = java.time.Clock.systemUTC().instant())
|
val newMeta = pair.meta.copy(lastModified = java.time.Clock.systemUTC().instant())
|
||||||
writeMeta(pair.metaFile, newMeta)
|
writeMeta(pair.metaFile, newMeta)
|
||||||
return LocalFile(newMeta)
|
return CommonFile(newMeta)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun createDir(storagePath: String): LocalDirectory {
|
private fun createDir(storagePath: String): CommonDirectory {
|
||||||
val path = Path(_filesystemBasePath.pathString, storagePath)
|
val path = Path(_filesystemBasePath.pathString, storagePath)
|
||||||
val file = path.toFile()
|
val file = path.toFile()
|
||||||
if(file.exists() && !file.isDirectory) {
|
if(file.exists() && !file.isDirectory) {
|
||||||
@@ -414,7 +414,7 @@ class LocalStorageAccessor(
|
|||||||
val pair = LocalStorageFilePair.from(_filesystemBasePath, file) ?: throw Exception("Что то пошло не так") // TODO
|
val pair = LocalStorageFilePair.from(_filesystemBasePath, file) ?: throw Exception("Что то пошло не так") // TODO
|
||||||
val newMeta = pair.meta.copy(lastModified = java.time.Clock.systemUTC().instant())
|
val newMeta = pair.meta.copy(lastModified = java.time.Clock.systemUTC().instant())
|
||||||
writeMeta(pair.metaFile, newMeta)
|
writeMeta(pair.metaFile, newMeta)
|
||||||
return LocalDirectory(newMeta, 0)
|
return CommonDirectory(newMeta, 0)
|
||||||
}
|
}
|
||||||
|
|
||||||
override suspend fun touchFile(path: String): Unit = withContext(ioDispatcher) {
|
override suspend fun touchFile(path: String): Unit = withContext(ioDispatcher) {
|
||||||
|
|||||||
@@ -1,8 +0,0 @@
|
|||||||
package com.github.nullptroma.wallenc.data.vaults.local.entity
|
|
||||||
|
|
||||||
import com.github.nullptroma.wallenc.domain.interfaces.IDirectory
|
|
||||||
|
|
||||||
data class LocalDirectory(
|
|
||||||
override val metaInfo: LocalMetaInfo,
|
|
||||||
override val elementsCount: Int?
|
|
||||||
) : IDirectory
|
|
||||||
@@ -1,5 +0,0 @@
|
|||||||
package com.github.nullptroma.wallenc.data.vaults.local.entity
|
|
||||||
|
|
||||||
import com.github.nullptroma.wallenc.domain.interfaces.IFile
|
|
||||||
|
|
||||||
data class LocalFile(override val metaInfo: LocalMetaInfo) : IFile
|
|
||||||
@@ -1,13 +0,0 @@
|
|||||||
package com.github.nullptroma.wallenc.data.vaults.local.entity
|
|
||||||
|
|
||||||
import com.github.nullptroma.wallenc.domain.interfaces.IMetaInfo
|
|
||||||
import java.time.Instant
|
|
||||||
|
|
||||||
|
|
||||||
data class LocalMetaInfo(
|
|
||||||
override val size: Long,
|
|
||||||
override val isDeleted: Boolean = false,
|
|
||||||
override val isHidden: Boolean = false,
|
|
||||||
override val lastModified: Instant = java.time.Clock.systemUTC().instant(),
|
|
||||||
override val path: String
|
|
||||||
) : IMetaInfo
|
|
||||||
@@ -0,0 +1,8 @@
|
|||||||
|
package com.github.nullptroma.wallenc.domain.common.impl
|
||||||
|
|
||||||
|
import com.github.nullptroma.wallenc.domain.interfaces.IDirectory
|
||||||
|
|
||||||
|
data class CommonDirectory(
|
||||||
|
override val metaInfo: CommonMetaInfo,
|
||||||
|
override val elementsCount: Int?
|
||||||
|
) : IDirectory
|
||||||
@@ -0,0 +1,5 @@
|
|||||||
|
package com.github.nullptroma.wallenc.domain.common.impl
|
||||||
|
|
||||||
|
import com.github.nullptroma.wallenc.domain.interfaces.IFile
|
||||||
|
|
||||||
|
data class CommonFile(override val metaInfo: CommonMetaInfo) : IFile
|
||||||
@@ -1,13 +1,14 @@
|
|||||||
package com.github.nullptroma.wallenc.domain.encrypt.entity
|
package com.github.nullptroma.wallenc.domain.common.impl
|
||||||
|
|
||||||
import com.github.nullptroma.wallenc.domain.interfaces.IMetaInfo
|
import com.github.nullptroma.wallenc.domain.interfaces.IMetaInfo
|
||||||
|
import java.time.Clock
|
||||||
import java.time.Instant
|
import java.time.Instant
|
||||||
|
|
||||||
|
|
||||||
data class EncryptedMetaInfo(
|
data class CommonMetaInfo(
|
||||||
override val size: Long,
|
override val size: Long,
|
||||||
override val isDeleted: Boolean = false,
|
override val isDeleted: Boolean = false,
|
||||||
override val isHidden: Boolean = false,
|
override val isHidden: Boolean = false,
|
||||||
override val lastModified: Instant = java.time.Clock.systemUTC().instant(),
|
override val lastModified: Instant = Clock.systemUTC().instant(),
|
||||||
override val path: String
|
override val path: String
|
||||||
) : IMetaInfo
|
) : IMetaInfo
|
||||||
@@ -1,13 +1,14 @@
|
|||||||
package com.github.nullptroma.wallenc.domain.encrypt
|
package com.github.nullptroma.wallenc.domain.encrypt
|
||||||
|
|
||||||
|
import com.github.nullptroma.wallenc.domain.common.impl.CommonDirectory
|
||||||
|
import com.github.nullptroma.wallenc.domain.common.impl.CommonFile
|
||||||
|
import com.github.nullptroma.wallenc.domain.common.impl.CommonMetaInfo
|
||||||
import com.github.nullptroma.wallenc.domain.datatypes.DataPackage
|
import com.github.nullptroma.wallenc.domain.datatypes.DataPackage
|
||||||
import com.github.nullptroma.wallenc.domain.datatypes.EncryptKey
|
import com.github.nullptroma.wallenc.domain.datatypes.EncryptKey
|
||||||
import com.github.nullptroma.wallenc.domain.encrypt.entity.EncryptedDirectory
|
|
||||||
import com.github.nullptroma.wallenc.domain.encrypt.entity.EncryptedFile
|
|
||||||
import com.github.nullptroma.wallenc.domain.encrypt.entity.EncryptedMetaInfo
|
|
||||||
import com.github.nullptroma.wallenc.domain.interfaces.IDirectory
|
import com.github.nullptroma.wallenc.domain.interfaces.IDirectory
|
||||||
import com.github.nullptroma.wallenc.domain.interfaces.IFile
|
import com.github.nullptroma.wallenc.domain.interfaces.IFile
|
||||||
import com.github.nullptroma.wallenc.domain.interfaces.ILogger
|
import com.github.nullptroma.wallenc.domain.interfaces.ILogger
|
||||||
|
import com.github.nullptroma.wallenc.domain.interfaces.IMetaInfo
|
||||||
import com.github.nullptroma.wallenc.domain.interfaces.IStorageAccessor
|
import com.github.nullptroma.wallenc.domain.interfaces.IStorageAccessor
|
||||||
import kotlinx.coroutines.CoroutineDispatcher
|
import kotlinx.coroutines.CoroutineDispatcher
|
||||||
import kotlinx.coroutines.CoroutineScope
|
import kotlinx.coroutines.CoroutineScope
|
||||||
@@ -15,10 +16,13 @@ import kotlinx.coroutines.flow.Flow
|
|||||||
import kotlinx.coroutines.flow.MutableSharedFlow
|
import kotlinx.coroutines.flow.MutableSharedFlow
|
||||||
import kotlinx.coroutines.flow.SharedFlow
|
import kotlinx.coroutines.flow.SharedFlow
|
||||||
import kotlinx.coroutines.flow.StateFlow
|
import kotlinx.coroutines.flow.StateFlow
|
||||||
|
import kotlinx.coroutines.flow.map
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
import java.io.InputStream
|
import java.io.InputStream
|
||||||
import java.io.OutputStream
|
import java.io.OutputStream
|
||||||
import javax.crypto.Cipher
|
import javax.crypto.Cipher
|
||||||
|
import javax.crypto.CipherInputStream
|
||||||
|
import javax.crypto.CipherOutputStream
|
||||||
import javax.crypto.spec.IvParameterSpec
|
import javax.crypto.spec.IvParameterSpec
|
||||||
import javax.crypto.spec.SecretKeySpec
|
import javax.crypto.spec.SecretKeySpec
|
||||||
import kotlin.io.encoding.Base64
|
import kotlin.io.encoding.Base64
|
||||||
@@ -46,8 +50,6 @@ class EncryptedStorageAccessor(
|
|||||||
private val _secretKey = SecretKeySpec(key.to32Bytes(), "AES")
|
private val _secretKey = SecretKeySpec(key.to32Bytes(), "AES")
|
||||||
|
|
||||||
init {
|
init {
|
||||||
val enc = encryptPath("/hello/world/test.txt")
|
|
||||||
val dec = decryptPath(enc)
|
|
||||||
collectSourceState(CoroutineScope(ioDispatcher))
|
collectSourceState(CoroutineScope(ioDispatcher))
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -55,16 +57,7 @@ class EncryptedStorageAccessor(
|
|||||||
coroutineScope.launch {
|
coroutineScope.launch {
|
||||||
launch {
|
launch {
|
||||||
source.filesUpdates.collect {
|
source.filesUpdates.collect {
|
||||||
val files = it.data.map {
|
val files = it.data.map(::decryptEntity)
|
||||||
val meta = it.metaInfo
|
|
||||||
EncryptedFile(EncryptedMetaInfo(
|
|
||||||
size = meta.size,
|
|
||||||
isDeleted = meta.isDeleted,
|
|
||||||
isHidden = meta.isHidden,
|
|
||||||
lastModified = meta.lastModified,
|
|
||||||
path = decryptPath(meta.path)
|
|
||||||
))
|
|
||||||
}
|
|
||||||
_filesUpdates.emit(DataPackage(
|
_filesUpdates.emit(DataPackage(
|
||||||
data = files,
|
data = files,
|
||||||
isLoading = it.isLoading,
|
isLoading = it.isLoading,
|
||||||
@@ -75,16 +68,7 @@ class EncryptedStorageAccessor(
|
|||||||
|
|
||||||
launch {
|
launch {
|
||||||
source.dirsUpdates.collect {
|
source.dirsUpdates.collect {
|
||||||
val dirs = it.data.map {
|
val dirs = it.data.map(::decryptEntity)
|
||||||
val meta = it.metaInfo
|
|
||||||
EncryptedDirectory(EncryptedMetaInfo(
|
|
||||||
size = meta.size,
|
|
||||||
isDeleted = meta.isDeleted,
|
|
||||||
isHidden = meta.isHidden,
|
|
||||||
lastModified = meta.lastModified,
|
|
||||||
path = decryptPath(meta.path)
|
|
||||||
), it.elementsCount)
|
|
||||||
}
|
|
||||||
_dirsUpdates.emit(DataPackage(
|
_dirsUpdates.emit(DataPackage(
|
||||||
data = dirs,
|
data = dirs,
|
||||||
isLoading = it.isLoading,
|
isLoading = it.isLoading,
|
||||||
@@ -95,6 +79,42 @@ class EncryptedStorageAccessor(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun encryptEntity(file: IFile): IFile {
|
||||||
|
return CommonFile(encryptMeta(file.metaInfo))
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun decryptEntity(file: IFile): IFile {
|
||||||
|
return CommonFile(decryptMeta(file.metaInfo))
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun encryptEntity(dir: IDirectory): IDirectory {
|
||||||
|
return CommonDirectory(encryptMeta(dir.metaInfo), dir.elementsCount)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun decryptEntity(dir: IDirectory): IDirectory {
|
||||||
|
return CommonDirectory(decryptMeta(dir.metaInfo), dir.elementsCount)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun encryptMeta(meta: IMetaInfo): CommonMetaInfo {
|
||||||
|
return CommonMetaInfo(
|
||||||
|
size = meta.size,
|
||||||
|
isDeleted = meta.isDeleted,
|
||||||
|
isHidden = meta.isHidden,
|
||||||
|
lastModified = meta.lastModified,
|
||||||
|
path = encryptPath(meta.path)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun decryptMeta(meta: IMetaInfo): CommonMetaInfo {
|
||||||
|
return CommonMetaInfo(
|
||||||
|
size = meta.size,
|
||||||
|
isDeleted = meta.isDeleted,
|
||||||
|
isHidden = meta.isHidden,
|
||||||
|
lastModified = meta.lastModified,
|
||||||
|
path = decryptPath(meta.path)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
@OptIn(ExperimentalEncodingApi::class)
|
@OptIn(ExperimentalEncodingApi::class)
|
||||||
private fun encryptString(str: String): String {
|
private fun encryptString(str: String): String {
|
||||||
val cipher = Cipher.getInstance(AES_FOR_STRINGS)
|
val cipher = Cipher.getInstance(AES_FOR_STRINGS)
|
||||||
@@ -121,7 +141,6 @@ class EncryptedStorageAccessor(
|
|||||||
for (segment in path)
|
for (segment in path)
|
||||||
segments.add(encryptString(segment.pathString))
|
segments.add(encryptString(segment.pathString))
|
||||||
val res = Path("/",*(segments.toTypedArray()))
|
val res = Path("/",*(segments.toTypedArray()))
|
||||||
logger.debug("encryptPath", "$pathStr to $res")
|
|
||||||
return res.pathString
|
return res.pathString
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -131,56 +150,83 @@ class EncryptedStorageAccessor(
|
|||||||
for (segment in path)
|
for (segment in path)
|
||||||
segments.add(decryptString(segment.pathString))
|
segments.add(decryptString(segment.pathString))
|
||||||
val res = Path("/",*(segments.toTypedArray()))
|
val res = Path("/",*(segments.toTypedArray()))
|
||||||
logger.debug("decryptPath", "$pathStr to $res")
|
|
||||||
return res.pathString
|
return res.pathString
|
||||||
}
|
}
|
||||||
|
|
||||||
override suspend fun getAllFiles(): List<IFile> {
|
override suspend fun getAllFiles(): List<IFile> {
|
||||||
TODO("Not yet implemented")
|
return source.getAllFiles().map(::decryptEntity)
|
||||||
}
|
}
|
||||||
|
|
||||||
override suspend fun getFiles(path: String): List<IFile> {
|
override suspend fun getFiles(path: String): List<IFile> {
|
||||||
TODO("Not yet implemented")
|
return source.getFiles(encryptPath(path)).map(::decryptEntity)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun getFilesFlow(path: String): Flow<DataPackage<List<IFile>>> {
|
override fun getFilesFlow(path: String): Flow<DataPackage<List<IFile>>> {
|
||||||
TODO("Not yet implemented")
|
val flow = source.getFilesFlow(encryptPath(path)).map {
|
||||||
|
DataPackage(
|
||||||
|
data = it.data.map(::decryptEntity),
|
||||||
|
isLoading = it.isLoading,
|
||||||
|
isError = it.isError
|
||||||
|
)
|
||||||
|
}
|
||||||
|
return flow
|
||||||
}
|
}
|
||||||
|
|
||||||
override suspend fun getAllDirs(): List<IDirectory> {
|
override suspend fun getAllDirs(): List<IDirectory> {
|
||||||
TODO("Not yet implemented")
|
return source.getAllDirs().map(::decryptEntity)
|
||||||
}
|
}
|
||||||
|
|
||||||
override suspend fun getDirs(path: String): List<IDirectory> {
|
override suspend fun getDirs(path: String): List<IDirectory> {
|
||||||
TODO("Not yet implemented")
|
return source.getDirs(encryptPath(path)).map(::decryptEntity)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun getDirsFlow(path: String): Flow<DataPackage<List<IDirectory>>> {
|
override fun getDirsFlow(path: String): Flow<DataPackage<List<IDirectory>>> {
|
||||||
TODO("Not yet implemented")
|
val flow = source.getDirsFlow(encryptPath(path)).map {
|
||||||
|
DataPackage(
|
||||||
|
data = it.data.map(::decryptEntity),
|
||||||
|
isLoading = it.isLoading,
|
||||||
|
isError = it.isError
|
||||||
|
)
|
||||||
|
}
|
||||||
|
return flow
|
||||||
}
|
}
|
||||||
|
|
||||||
override suspend fun touchFile(path: String) {
|
override suspend fun touchFile(path: String) {
|
||||||
TODO("Not yet implemented")
|
source.touchFile(encryptPath(path))
|
||||||
}
|
}
|
||||||
|
|
||||||
override suspend fun touchDir(path: String) {
|
override suspend fun touchDir(path: String) {
|
||||||
TODO("Not yet implemented")
|
source.touchDir(encryptPath(path))
|
||||||
}
|
}
|
||||||
|
|
||||||
override suspend fun delete(path: String) {
|
override suspend fun delete(path: String) {
|
||||||
TODO("Not yet implemented")
|
source.delete(encryptPath(path))
|
||||||
}
|
}
|
||||||
|
|
||||||
override suspend fun openWrite(path: String): OutputStream {
|
override suspend fun openWrite(path: String): OutputStream {
|
||||||
TODO("Not yet implemented")
|
val stream = source.openWrite(encryptPath(path))
|
||||||
|
val iv = IvParameterSpec(Random.nextBytes(IV_LEN))
|
||||||
|
stream.write(iv.iv) // Запись инициализационного вектора сырой файл
|
||||||
|
val cipher = Cipher.getInstance(AES_FOR_STRINGS)
|
||||||
|
cipher.init(Cipher.ENCRYPT_MODE, _secretKey, iv) // инициализация шифратора
|
||||||
|
return CipherOutputStream(stream, cipher)
|
||||||
}
|
}
|
||||||
|
|
||||||
override suspend fun openRead(path: String): InputStream {
|
override suspend fun openRead(path: String): InputStream {
|
||||||
TODO("Not yet implemented")
|
val stream = source.openRead(encryptPath(path))
|
||||||
|
val ivBytes = ByteArray(IV_LEN) // Буфер для 16 байт IV
|
||||||
|
val bytesRead = stream.read(ivBytes) // Чтение IV вектора
|
||||||
|
if(bytesRead != IV_LEN)
|
||||||
|
throw Exception("TODO iv не прочитан")
|
||||||
|
val iv = IvParameterSpec(ivBytes)
|
||||||
|
|
||||||
|
val cipher = Cipher.getInstance(AES_FOR_STRINGS)
|
||||||
|
cipher.init(Cipher.DECRYPT_MODE, _secretKey, iv)
|
||||||
|
return CipherInputStream(stream, cipher)
|
||||||
}
|
}
|
||||||
|
|
||||||
override suspend fun moveToTrash(path: String) {
|
override suspend fun moveToTrash(path: String) {
|
||||||
TODO("Not yet implemented")
|
source.moveToTrash(encryptPath(path))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -1,8 +0,0 @@
|
|||||||
package com.github.nullptroma.wallenc.domain.encrypt.entity
|
|
||||||
|
|
||||||
import com.github.nullptroma.wallenc.domain.interfaces.IDirectory
|
|
||||||
|
|
||||||
data class EncryptedDirectory(
|
|
||||||
override val metaInfo: EncryptedMetaInfo,
|
|
||||||
override val elementsCount: Int?
|
|
||||||
) : IDirectory
|
|
||||||
@@ -1,5 +0,0 @@
|
|||||||
package com.github.nullptroma.wallenc.domain.encrypt.entity
|
|
||||||
|
|
||||||
import com.github.nullptroma.wallenc.domain.interfaces.IFile
|
|
||||||
|
|
||||||
data class EncryptedFile(override val metaInfo: EncryptedMetaInfo) : IFile
|
|
||||||
Reference in New Issue
Block a user