-
-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
- Loading branch information
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
package edu.stanford.spezi.modules.storage.local | ||
Check warning on line 1 in modules/storage/src/androidTest/kotlin/edu/stanford/spezi/modules/storage/local/LocalStorageTests.kt GitHub Actions / detekt[detekt] modules/storage/src/androidTest/kotlin/edu/stanford/spezi/modules/storage/local/LocalStorageTests.kt#L1 <detekt.FinalNewline>
Raw output
|
||
|
||
import org.junit.Test | ||
import kotlin.random.Random | ||
|
||
class LocalStorageTests { | ||
data class Letter(val greeting: String) | ||
|
||
@Test | ||
fun localStorage() { | ||
val localStorage = LocalStorage() | ||
|
||
var greeting = "Hello Paul 👋" | ||
for (index in 0..Random.nextInt(10)) { | ||
greeting += "🚀" | ||
} | ||
val letter = Letter(greeting = greeting) | ||
localStorage.store(letter, settings = LocalStorageSetting.Unencrypted) | ||
val storedLetter: Letter = localStorage.read(settings = LocalStorageSetting.Unencrypted) | ||
|
||
assert(letter.greeting == storedLetter.greeting) | ||
|
||
localStorage.delete(Letter::class) | ||
localStorage.delete(storageKey = "Letter") | ||
} | ||
} | ||
Check warning on line 26 in modules/storage/src/androidTest/kotlin/edu/stanford/spezi/modules/storage/local/LocalStorageTests.kt GitHub Actions / detekt[detekt] modules/storage/src/androidTest/kotlin/edu/stanford/spezi/modules/storage/local/LocalStorageTests.kt#L26 <detekt.NewLineAtEndOfFile>
Raw output
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,126 @@ | ||
package edu.stanford.spezi.modules.storage.local | ||
Check warning on line 1 in modules/storage/src/main/kotlin/edu/stanford/spezi/modules/storage/local/LocalStorage.kt GitHub Actions / detekt[detekt] modules/storage/src/main/kotlin/edu/stanford/spezi/modules/storage/local/LocalStorage.kt#L1 <detekt.FinalNewline>
Raw output
|
||
|
||
import android.content.Context | ||
import androidx.security.crypto.EncryptedFile | ||
Check warning on line 4 in modules/storage/src/main/kotlin/edu/stanford/spezi/modules/storage/local/LocalStorage.kt GitHub Actions / detekt[detekt] modules/storage/src/main/kotlin/edu/stanford/spezi/modules/storage/local/LocalStorage.kt#L4 <detekt.NoUnusedImports>
Raw output
Check warning on line 4 in modules/storage/src/main/kotlin/edu/stanford/spezi/modules/storage/local/LocalStorage.kt GitHub Actions / detekt[detekt] modules/storage/src/main/kotlin/edu/stanford/spezi/modules/storage/local/LocalStorage.kt#L4 <detekt.UnusedImports>
Raw output
|
||
import androidx.security.crypto.MasterKey | ||
import dagger.hilt.android.qualifiers.ApplicationContext | ||
import edu.stanford.spezi.core.coroutines.di.Dispatching | ||
import edu.stanford.spezi.modules.storage.secure.SecureStorage | ||
import kotlinx.coroutines.CoroutineDispatcher | ||
import java.io.File | ||
import javax.inject.Inject | ||
import kotlin.reflect.KClass | ||
|
||
class LocalStorage @Inject constructor( | ||
@ApplicationContext val context: Context, | ||
@Dispatching.IO private val ioDispatcher: CoroutineDispatcher, | ||
) { | ||
Check warning on line 17 in modules/storage/src/main/kotlin/edu/stanford/spezi/modules/storage/local/LocalStorage.kt GitHub Actions / detekt[detekt] modules/storage/src/main/kotlin/edu/stanford/spezi/modules/storage/local/LocalStorage.kt#L17 <detekt.Indentation>
Raw output
|
||
private val masterKey = MasterKey.Builder(context) | ||
.setKeyScheme(MasterKey.KeyScheme.AES256_GCM) | ||
.build() | ||
private val secureStorage = SecureStorage() | ||
|
||
private inline fun <reified C: Any> store( | ||
Check warning on line 23 in modules/storage/src/main/kotlin/edu/stanford/spezi/modules/storage/local/LocalStorage.kt GitHub Actions / detekt[detekt] modules/storage/src/main/kotlin/edu/stanford/spezi/modules/storage/local/LocalStorage.kt#L23 <detekt.SpacingAroundColon>
Raw output
Check warning on line 23 in modules/storage/src/main/kotlin/edu/stanford/spezi/modules/storage/local/LocalStorage.kt GitHub Actions / detekt[detekt] modules/storage/src/main/kotlin/edu/stanford/spezi/modules/storage/local/LocalStorage.kt#L23 <detekt.UnusedPrivateMember>
Raw output
|
||
// TODO: iOS has this only as a private helper function | ||
element: C, | ||
storageKey: String?, | ||
settings: LocalStorageSetting, | ||
encode: (C) -> ByteArray | ||
Check warning on line 28 in modules/storage/src/main/kotlin/edu/stanford/spezi/modules/storage/local/LocalStorage.kt GitHub Actions / detekt[detekt] modules/storage/src/main/kotlin/edu/stanford/spezi/modules/storage/local/LocalStorage.kt#L28 <detekt.TrailingCommaOnDeclarationSite>
Raw output
|
||
): Unit { | ||
Check warning on line 29 in modules/storage/src/main/kotlin/edu/stanford/spezi/modules/storage/local/LocalStorage.kt GitHub Actions / detekt[detekt] modules/storage/src/main/kotlin/edu/stanford/spezi/modules/storage/local/LocalStorage.kt#L29 <detekt.NoUnitReturn>
Raw output
|
||
val file = file(storageKey, C::class) | ||
|
||
val alreadyExistedBefore = file.exists() | ||
|
||
// Called at the end of each execution path | ||
// We can not use defer as the function can potentially throw an error. | ||
|
||
|
||
Check warning on line 37 in modules/storage/src/main/kotlin/edu/stanford/spezi/modules/storage/local/LocalStorage.kt GitHub Actions / detekt[detekt] modules/storage/src/main/kotlin/edu/stanford/spezi/modules/storage/local/LocalStorage.kt#L37 <detekt.NoConsecutiveBlankLines>
Raw output
|
||
val data = encode(element) | ||
|
||
val keys = settings.keys(secureStorage) | ||
Check warning on line 40 in modules/storage/src/main/kotlin/edu/stanford/spezi/modules/storage/local/LocalStorage.kt GitHub Actions / detekt[detekt] modules/storage/src/main/kotlin/edu/stanford/spezi/modules/storage/local/LocalStorage.kt#L40 <detekt.Indentation>
Raw output
|
||
|
||
// Determine if the data should be encrypted or not: | ||
if (keys == null) { | ||
file.writeBytes(data) | ||
setResourceValues(alreadyExistedBefore, settings, file) | ||
return | ||
} | ||
|
||
// TODO: Check if encryption is supported | ||
// | ||
// iOS: | ||
// // Encryption enabled: | ||
// guard SecKeyIsAlgorithmSupported (keys.publicKey, .encrypt, encryptionAlgorithm) else { | ||
// throw LocalStorageError.encryptionNotPossible | ||
// } | ||
// | ||
// var encryptError: Unmanaged<CFError>? | ||
// guard let encryptedData = SecKeyCreateEncryptedData( | ||
// keys.publicKey, | ||
// encryptionAlgorithm, | ||
// data as CFData, & encryptError) as Data? else { | ||
// throw LocalStorageError.encryptionNotPossible | ||
// } | ||
|
||
val encryptedData = data | ||
file.writeBytes(encryptedData) | ||
setResourceValues(alreadyExistedBefore, settings, file) | ||
} | ||
|
||
private inline fun <reified C: Any> read( // TODO: iOS only has this as a private helper | ||
Check warning on line 70 in modules/storage/src/main/kotlin/edu/stanford/spezi/modules/storage/local/LocalStorage.kt GitHub Actions / detekt[detekt] modules/storage/src/main/kotlin/edu/stanford/spezi/modules/storage/local/LocalStorage.kt#L70 <detekt.SpacingAroundColon>
Raw output
Check warning on line 70 in modules/storage/src/main/kotlin/edu/stanford/spezi/modules/storage/local/LocalStorage.kt GitHub Actions / detekt[detekt] modules/storage/src/main/kotlin/edu/stanford/spezi/modules/storage/local/LocalStorage.kt#L70 <detekt.UnusedPrivateMember>
Raw output
|
||
storageKey: String?, | ||
settings: LocalStorageSetting, | ||
decode: (ByteArray) -> C | ||
Check warning on line 73 in modules/storage/src/main/kotlin/edu/stanford/spezi/modules/storage/local/LocalStorage.kt GitHub Actions / detekt[detekt] modules/storage/src/main/kotlin/edu/stanford/spezi/modules/storage/local/LocalStorage.kt#L73 <detekt.TrailingCommaOnDeclarationSite>
Raw output
|
||
): C { | ||
val file = file(storageKey, C::class) | ||
val keys = settings.keys(secureStorage = secureStorage) | ||
?: return decode(file.readBytes()) | ||
|
||
val privateKey = keys.first | ||
val publicKey = keys.second | ||
|
||
// TODO: iOS decryption: | ||
// guard SecKeyIsAlgorithmSupported(keys.privateKey, .decrypt, encryptionAlgorithm) else { | ||
// throw LocalStorageError.decryptionNotPossible | ||
// } | ||
|
||
// var decryptError: Unmanaged<CFError>? | ||
// guard let decryptedData = SecKeyCreateDecryptedData(keys.privateKey, encryptionAlgorithm, data as CFData, &decryptError) as Data? else { | ||
Check warning on line 88 in modules/storage/src/main/kotlin/edu/stanford/spezi/modules/storage/local/LocalStorage.kt GitHub Actions / detekt[detekt] modules/storage/src/main/kotlin/edu/stanford/spezi/modules/storage/local/LocalStorage.kt#L88 <detekt.MaxLineLength>
Raw output
|
||
// throw LocalStorageError.decryptionNotPossible | ||
// } | ||
|
||
return decode(file.readBytes()) | ||
} | ||
|
||
private fun setResourceValues( | ||
alreadyExistedBefore: Boolean, | ||
settings: LocalStorageSetting, | ||
file: File | ||
Check warning on line 98 in modules/storage/src/main/kotlin/edu/stanford/spezi/modules/storage/local/LocalStorage.kt GitHub Actions / detekt[detekt] modules/storage/src/main/kotlin/edu/stanford/spezi/modules/storage/local/LocalStorage.kt#L98 <detekt.TrailingCommaOnDeclarationSite>
Raw output
|
||
) { | ||
try { | ||
if (settings.excludedFromBackupValue) { | ||
// TODO: Check how to exclude files from backup - may need more flexibility here though | ||
} | ||
} catch (error: Throwable) { | ||
Check warning on line 104 in modules/storage/src/main/kotlin/edu/stanford/spezi/modules/storage/local/LocalStorage.kt GitHub Actions / detekt[detekt] modules/storage/src/main/kotlin/edu/stanford/spezi/modules/storage/local/LocalStorage.kt#L104 <detekt.TooGenericExceptionCaught>
Raw output
Check warning on line 104 in modules/storage/src/main/kotlin/edu/stanford/spezi/modules/storage/local/LocalStorage.kt GitHub Actions / detekt[detekt] modules/storage/src/main/kotlin/edu/stanford/spezi/modules/storage/local/LocalStorage.kt#L104 <detekt.SwallowedException>
Raw output
|
||
// Revert a written file if it did not exist before. | ||
if (!alreadyExistedBefore) { | ||
file.delete() | ||
} | ||
throw LocalStorageError.CouldNotExcludedFromBackup | ||
} | ||
} | ||
|
||
private inline fun <reified C : Any> file(storageKey: String? = null, type: KClass<C> = C::class): File { | ||
val fileName = storageKey ?: type.qualifiedName ?: throw Error() // TODO: This should never happen, right? | ||
Check warning on line 114 in modules/storage/src/main/kotlin/edu/stanford/spezi/modules/storage/local/LocalStorage.kt GitHub Actions / detekt[detekt] modules/storage/src/main/kotlin/edu/stanford/spezi/modules/storage/local/LocalStorage.kt#L114 <detekt.TooGenericExceptionThrown>
Raw output
|
||
val directory = File(context.filesDir, "edu.stanford.spezi/LocalStorage") | ||
|
||
try { | ||
if (!directory.exists()) | ||
directory.mkdirs() | ||
Check warning on line 119 in modules/storage/src/main/kotlin/edu/stanford/spezi/modules/storage/local/LocalStorage.kt GitHub Actions / detekt[detekt] modules/storage/src/main/kotlin/edu/stanford/spezi/modules/storage/local/LocalStorage.kt#L119 <detekt.MultiLineIfElse>
Raw output
|
||
} catch (error: Throwable) { | ||
Check warning on line 120 in modules/storage/src/main/kotlin/edu/stanford/spezi/modules/storage/local/LocalStorage.kt GitHub Actions / detekt[detekt] modules/storage/src/main/kotlin/edu/stanford/spezi/modules/storage/local/LocalStorage.kt#L120 <detekt.TooGenericExceptionCaught>
Raw output
|
||
println("Failed to create directories: $error") | ||
} | ||
|
||
return File(context.filesDir, "edu.stanford.spezi/LocalStorage/$fileName.localstorage") | ||
} | ||
} | ||
Check warning on line 126 in modules/storage/src/main/kotlin/edu/stanford/spezi/modules/storage/local/LocalStorage.kt GitHub Actions / detekt[detekt] modules/storage/src/main/kotlin/edu/stanford/spezi/modules/storage/local/LocalStorage.kt#L126 <detekt.NewLineAtEndOfFile>
Raw output
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
package edu.stanford.spezi.modules.storage.local | ||
Check warning on line 1 in modules/storage/src/main/kotlin/edu/stanford/spezi/modules/storage/local/LocalStorageError.kt GitHub Actions / detekt[detekt] modules/storage/src/main/kotlin/edu/stanford/spezi/modules/storage/local/LocalStorageError.kt#L1 <detekt.FinalNewline>
Raw output
|
||
|
||
sealed class LocalStorageError: Error() { | ||
Check warning on line 3 in modules/storage/src/main/kotlin/edu/stanford/spezi/modules/storage/local/LocalStorageError.kt GitHub Actions / detekt[detekt] modules/storage/src/main/kotlin/edu/stanford/spezi/modules/storage/local/LocalStorageError.kt#L3 <detekt.SpacingAroundColon>
Raw output
|
||
data object EncryptionNotPossible: LocalStorageError() { | ||
Check warning on line 4 in modules/storage/src/main/kotlin/edu/stanford/spezi/modules/storage/local/LocalStorageError.kt GitHub Actions / detekt[detekt] modules/storage/src/main/kotlin/edu/stanford/spezi/modules/storage/local/LocalStorageError.kt#L4 <detekt.SpacingAroundColon>
Raw output
|
||
private fun readResolve(): Any = EncryptionNotPossible | ||
Check warning on line 5 in modules/storage/src/main/kotlin/edu/stanford/spezi/modules/storage/local/LocalStorageError.kt GitHub Actions / detekt[detekt] modules/storage/src/main/kotlin/edu/stanford/spezi/modules/storage/local/LocalStorageError.kt#L5 <detekt.UnusedPrivateMember>
Raw output
|
||
} | ||
data object CouldNotExcludedFromBackup: LocalStorageError() { | ||
Check warning on line 7 in modules/storage/src/main/kotlin/edu/stanford/spezi/modules/storage/local/LocalStorageError.kt GitHub Actions / detekt[detekt] modules/storage/src/main/kotlin/edu/stanford/spezi/modules/storage/local/LocalStorageError.kt#L7 <detekt.SpacingAroundColon>
Raw output
|
||
private fun readResolve(): Any = CouldNotExcludedFromBackup // TODO: Weird naming | ||
Check warning on line 8 in modules/storage/src/main/kotlin/edu/stanford/spezi/modules/storage/local/LocalStorageError.kt GitHub Actions / detekt[detekt] modules/storage/src/main/kotlin/edu/stanford/spezi/modules/storage/local/LocalStorageError.kt#L8 <detekt.UnusedPrivateMember>
Raw output
|
||
} | ||
data object DecryptionNotPossible: LocalStorageError() { | ||
Check warning on line 10 in modules/storage/src/main/kotlin/edu/stanford/spezi/modules/storage/local/LocalStorageError.kt GitHub Actions / detekt[detekt] modules/storage/src/main/kotlin/edu/stanford/spezi/modules/storage/local/LocalStorageError.kt#L10 <detekt.SpacingAroundColon>
Raw output
|
||
private fun readResolve(): Any = DecryptionNotPossible | ||
Check warning on line 11 in modules/storage/src/main/kotlin/edu/stanford/spezi/modules/storage/local/LocalStorageError.kt GitHub Actions / detekt[detekt] modules/storage/src/main/kotlin/edu/stanford/spezi/modules/storage/local/LocalStorageError.kt#L11 <detekt.UnusedPrivateMember>
Raw output
|
||
} | ||
} | ||
Check warning on line 13 in modules/storage/src/main/kotlin/edu/stanford/spezi/modules/storage/local/LocalStorageError.kt GitHub Actions / detekt[detekt] modules/storage/src/main/kotlin/edu/stanford/spezi/modules/storage/local/LocalStorageError.kt#L13 <detekt.NewLineAtEndOfFile>
Raw output
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,58 @@ | ||
package edu.stanford.spezi.modules.storage.local | ||
Check warning on line 1 in modules/storage/src/main/kotlin/edu/stanford/spezi/modules/storage/local/LocalStorageSetting.kt GitHub Actions / detekt[detekt] modules/storage/src/main/kotlin/edu/stanford/spezi/modules/storage/local/LocalStorageSetting.kt#L1 <detekt.FinalNewline>
Raw output
|
||
|
||
import edu.stanford.spezi.modules.storage.secure.SecureStorage | ||
import edu.stanford.spezi.modules.storage.secure.SecureStorageScope | ||
import javax.crypto.SecretKey | ||
|
||
sealed class LocalStorageSetting { // TODO: Adopt android-specific names instead, as SecureEnclave and AccessGroup are iOS-specific | ||
data class Unencrypted( | ||
val excludedFromBackup: Boolean = true | ||
Check warning on line 9 in modules/storage/src/main/kotlin/edu/stanford/spezi/modules/storage/local/LocalStorageSetting.kt GitHub Actions / detekt[detekt] modules/storage/src/main/kotlin/edu/stanford/spezi/modules/storage/local/LocalStorageSetting.kt#L9 <detekt.TrailingCommaOnDeclarationSite>
Raw output
|
||
): LocalStorageSetting() | ||
Check warning on line 10 in modules/storage/src/main/kotlin/edu/stanford/spezi/modules/storage/local/LocalStorageSetting.kt GitHub Actions / detekt[detekt] modules/storage/src/main/kotlin/edu/stanford/spezi/modules/storage/local/LocalStorageSetting.kt#L10 <detekt.SpacingAroundColon>
Raw output
|
||
|
||
data class Encrypted( | ||
val privateKey: SecretKey, | ||
val publicKey: SecretKey, | ||
val excludedFromBackup: Boolean | ||
Check warning on line 15 in modules/storage/src/main/kotlin/edu/stanford/spezi/modules/storage/local/LocalStorageSetting.kt GitHub Actions / detekt[detekt] modules/storage/src/main/kotlin/edu/stanford/spezi/modules/storage/local/LocalStorageSetting.kt#L15 <detekt.TrailingCommaOnDeclarationSite>
Raw output
|
||
): LocalStorageSetting() | ||
Check warning on line 16 in modules/storage/src/main/kotlin/edu/stanford/spezi/modules/storage/local/LocalStorageSetting.kt GitHub Actions / detekt[detekt] modules/storage/src/main/kotlin/edu/stanford/spezi/modules/storage/local/LocalStorageSetting.kt#L16 <detekt.SpacingAroundColon>
Raw output
|
||
|
||
data class EncyptedUsingSecureEnclave( | ||
val userPresence: Boolean = false | ||
Check warning on line 19 in modules/storage/src/main/kotlin/edu/stanford/spezi/modules/storage/local/LocalStorageSetting.kt GitHub Actions / detekt[detekt] modules/storage/src/main/kotlin/edu/stanford/spezi/modules/storage/local/LocalStorageSetting.kt#L19 <detekt.TrailingCommaOnDeclarationSite>
Raw output
|
||
): LocalStorageSetting() | ||
Check warning on line 20 in modules/storage/src/main/kotlin/edu/stanford/spezi/modules/storage/local/LocalStorageSetting.kt GitHub Actions / detekt[detekt] modules/storage/src/main/kotlin/edu/stanford/spezi/modules/storage/local/LocalStorageSetting.kt#L20 <detekt.SpacingAroundColon>
Raw output
|
||
|
||
data class EncryptedUsingKeychain( | ||
val userPresence: Boolean, | ||
val excludedFromBackup: Boolean = true | ||
Check warning on line 24 in modules/storage/src/main/kotlin/edu/stanford/spezi/modules/storage/local/LocalStorageSetting.kt GitHub Actions / detekt[detekt] modules/storage/src/main/kotlin/edu/stanford/spezi/modules/storage/local/LocalStorageSetting.kt#L24 <detekt.TrailingCommaOnDeclarationSite>
Raw output
|
||
): LocalStorageSetting() | ||
Check warning on line 25 in modules/storage/src/main/kotlin/edu/stanford/spezi/modules/storage/local/LocalStorageSetting.kt GitHub Actions / detekt[detekt] modules/storage/src/main/kotlin/edu/stanford/spezi/modules/storage/local/LocalStorageSetting.kt#L25 <detekt.SpacingAroundColon>
Raw output
|
||
|
||
val excludedFromBackupValue: Boolean get() = | ||
when (this) { | ||
is Unencrypted -> excludedFromBackup | ||
is Encrypted -> excludedFromBackup | ||
is EncryptedUsingKeychain -> excludedFromBackup | ||
is EncyptedUsingSecureEnclave -> true | ||
} | ||
|
||
fun keys(secureStorage: SecureStorage): Pair<SecretKey, SecretKey>? { | ||
Check warning on line 35 in modules/storage/src/main/kotlin/edu/stanford/spezi/modules/storage/local/LocalStorageSetting.kt GitHub Actions / detekt[detekt] modules/storage/src/main/kotlin/edu/stanford/spezi/modules/storage/local/LocalStorageSetting.kt#L35 <detekt.ReturnCount>
Raw output
|
||
val secureStorageScope = when (this) { | ||
is Unencrypted -> return null | ||
is Encrypted -> return Pair(privateKey, publicKey) | ||
is EncyptedUsingSecureEnclave -> | ||
SecureStorageScope.SecureEnclave(userPresence) | ||
is EncryptedUsingKeychain -> | ||
SecureStorageScope.Keychain(userPresence) | ||
} | ||
|
||
val tag = "LocalStorage.${secureStorageScope.identifier}" | ||
try { | ||
val privateKey = secureStorage.retrievePrivateKey(tag) | ||
val publicKey = secureStorage.retrievePublicKey(tag) | ||
if (privateKey != null && publicKey !== null) | ||
return Pair(privateKey, publicKey) | ||
Check warning on line 50 in modules/storage/src/main/kotlin/edu/stanford/spezi/modules/storage/local/LocalStorageSetting.kt GitHub Actions / detekt[detekt] modules/storage/src/main/kotlin/edu/stanford/spezi/modules/storage/local/LocalStorageSetting.kt#L50 <detekt.MultiLineIfElse>
Raw output
|
||
} catch (_: Throwable) {} | ||
|
||
val privateKey = secureStorage.createKey(tag) | ||
val publicKey = secureStorage.retrievePublicKey(tag) | ||
?: throw LocalStorageError.EncryptionNotPossible | ||
return Pair(privateKey, publicKey) | ||
} | ||
} | ||
Check warning on line 58 in modules/storage/src/main/kotlin/edu/stanford/spezi/modules/storage/local/LocalStorageSetting.kt GitHub Actions / detekt[detekt] modules/storage/src/main/kotlin/edu/stanford/spezi/modules/storage/local/LocalStorageSetting.kt#L58 <detekt.NewLineAtEndOfFile>
Raw output
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
package edu.stanford.spezi.modules.storage.secure | ||
Check warning on line 1 in modules/storage/src/main/kotlin/edu/stanford/spezi/modules/storage/secure/Credentials.kt GitHub Actions / detekt[detekt] modules/storage/src/main/kotlin/edu/stanford/spezi/modules/storage/secure/Credentials.kt#L1 <detekt.FinalNewline>
Raw output
|
||
|
||
data class Credentials( | ||
val username: String, | ||
val password: String | ||
Check warning on line 5 in modules/storage/src/main/kotlin/edu/stanford/spezi/modules/storage/secure/Credentials.kt GitHub Actions / detekt[detekt] modules/storage/src/main/kotlin/edu/stanford/spezi/modules/storage/secure/Credentials.kt#L5 <detekt.TrailingCommaOnDeclarationSite>
Raw output
|
||
) | ||
Check warning on line 6 in modules/storage/src/main/kotlin/edu/stanford/spezi/modules/storage/secure/Credentials.kt GitHub Actions / detekt[detekt] modules/storage/src/main/kotlin/edu/stanford/spezi/modules/storage/secure/Credentials.kt#L6 <detekt.NewLineAtEndOfFile>
Raw output
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,88 @@ | ||
package edu.stanford.spezi.modules.storage.secure | ||
Check warning on line 1 in modules/storage/src/main/kotlin/edu/stanford/spezi/modules/storage/secure/SecureStorage.kt GitHub Actions / detekt[detekt] modules/storage/src/main/kotlin/edu/stanford/spezi/modules/storage/secure/SecureStorage.kt#L1 <detekt.FinalNewline>
Raw output
|
||
|
||
import java.security.KeyStore | ||
import javax.crypto.SecretKey | ||
|
||
class SecureStorage { | ||
private val keyStore: KeyStore = KeyStore.getInstance("AndroidKeyStore").apply { load(null) } | ||
|
||
fun createKey( | ||
tag: String, | ||
size: Int = 256, | ||
storageScope: SecureStorageScope = SecureStorageScope.secureEnclave | ||
Check warning on line 12 in modules/storage/src/main/kotlin/edu/stanford/spezi/modules/storage/secure/SecureStorage.kt GitHub Actions / detekt[detekt] modules/storage/src/main/kotlin/edu/stanford/spezi/modules/storage/secure/SecureStorage.kt#L12 <detekt.TrailingCommaOnDeclarationSite>
Raw output
|
||
): SecretKey { | ||
// TODO: Implement | ||
throw NotImplementedError() | ||
} | ||
|
||
fun retrievePrivateKey(tag: String): SecretKey? { | ||
// TODO: Implement | ||
throw NotImplementedError() | ||
} | ||
|
||
fun retrievePublicKey(tag: String): SecretKey? { | ||
// TODO: Implement | ||
throw NotImplementedError() | ||
} | ||
|
||
fun deleteKeys(tag: String) { | ||
// TODO: Implement | ||
throw NotImplementedError() | ||
} | ||
|
||
fun store( | ||
credentials: Credentials, | ||
server: String? = null, | ||
removeDuplicate: Boolean = true, | ||
storageScope: SecureStorageScope | ||
Check warning on line 37 in modules/storage/src/main/kotlin/edu/stanford/spezi/modules/storage/secure/SecureStorage.kt GitHub Actions / detekt[detekt] modules/storage/src/main/kotlin/edu/stanford/spezi/modules/storage/secure/SecureStorage.kt#L37 <detekt.TrailingCommaOnDeclarationSite>
Raw output
|
||
) { | ||
// TODO: Implement | ||
throw NotImplementedError() | ||
} | ||
|
||
fun deleteCredentials( | ||
username: String, | ||
server: String? = null, | ||
accessGroup: String? = null | ||
Check warning on line 46 in modules/storage/src/main/kotlin/edu/stanford/spezi/modules/storage/secure/SecureStorage.kt GitHub Actions / detekt[detekt] modules/storage/src/main/kotlin/edu/stanford/spezi/modules/storage/secure/SecureStorage.kt#L46 <detekt.TrailingCommaOnDeclarationSite>
Raw output
|
||
) { | ||
// TODO: Implement | ||
throw NotImplementedError() | ||
} | ||
|
||
fun deleteAllCredentials( | ||
itemTypes: SecureStorageItemTypes = SecureStorageItemTypes.all, | ||
accessGroup: String? = null | ||
Check warning on line 54 in modules/storage/src/main/kotlin/edu/stanford/spezi/modules/storage/secure/SecureStorage.kt GitHub Actions / detekt[detekt] modules/storage/src/main/kotlin/edu/stanford/spezi/modules/storage/secure/SecureStorage.kt#L54 <detekt.TrailingCommaOnDeclarationSite>
Raw output
|
||
) { | ||
// TODO: Implement | ||
throw NotImplementedError() | ||
} | ||
|
||
fun updateCredentials( | ||
username: String, | ||
server: String? = null, | ||
newCredentials: Credentials, | ||
newServer: String? = null, | ||
removeDuplicate: Boolean = true, | ||
storageScope: SecureStorageScope = SecureStorageScope.keychain | ||
Check warning on line 66 in modules/storage/src/main/kotlin/edu/stanford/spezi/modules/storage/secure/SecureStorage.kt GitHub Actions / detekt[detekt] modules/storage/src/main/kotlin/edu/stanford/spezi/modules/storage/secure/SecureStorage.kt#L66 <detekt.TrailingCommaOnDeclarationSite>
Raw output
|
||
) { | ||
// TODO: Implement | ||
throw NotImplementedError() | ||
} | ||
|
||
fun retrieveCredentials( | ||
username: String, | ||
server: String? = null, | ||
accessGroup: String? = null | ||
Check warning on line 75 in modules/storage/src/main/kotlin/edu/stanford/spezi/modules/storage/secure/SecureStorage.kt GitHub Actions / detekt[detekt] modules/storage/src/main/kotlin/edu/stanford/spezi/modules/storage/secure/SecureStorage.kt#L75 <detekt.TrailingCommaOnDeclarationSite>
Raw output
|
||
): Credentials? { | ||
// TODO: Implement | ||
throw NotImplementedError() | ||
} | ||
|
||
fun retrieveAllCredentials( | ||
server: String? = null, | ||
accessGroup: String? = null | ||
Check warning on line 83 in modules/storage/src/main/kotlin/edu/stanford/spezi/modules/storage/secure/SecureStorage.kt GitHub Actions / detekt[detekt] modules/storage/src/main/kotlin/edu/stanford/spezi/modules/storage/secure/SecureStorage.kt#L83 <detekt.TrailingCommaOnDeclarationSite>
Raw output
|
||
): List<Credentials> { | ||
// TODO: Implement | ||
throw NotImplementedError() | ||
} | ||
} | ||
Check warning on line 88 in modules/storage/src/main/kotlin/edu/stanford/spezi/modules/storage/secure/SecureStorage.kt GitHub Actions / detekt[detekt] modules/storage/src/main/kotlin/edu/stanford/spezi/modules/storage/secure/SecureStorage.kt#L88 <detekt.NewLineAtEndOfFile>
Raw output
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
package edu.stanford.spezi.modules.storage.secure | ||
Check warning on line 1 in modules/storage/src/main/kotlin/edu/stanford/spezi/modules/storage/secure/SecureStorageError.kt GitHub Actions / detekt[detekt] modules/storage/src/main/kotlin/edu/stanford/spezi/modules/storage/secure/SecureStorageError.kt#L1 <detekt.FinalNewline>
Raw output
|
||
|
||
sealed class SecureStorageError: Error() { | ||
Check warning on line 3 in modules/storage/src/main/kotlin/edu/stanford/spezi/modules/storage/secure/SecureStorageError.kt GitHub Actions / detekt[detekt] modules/storage/src/main/kotlin/edu/stanford/spezi/modules/storage/secure/SecureStorageError.kt#L3 <detekt.SpacingAroundColon>
Raw output
|
||
data object NotFound: SecureStorageError() { | ||
Check warning on line 4 in modules/storage/src/main/kotlin/edu/stanford/spezi/modules/storage/secure/SecureStorageError.kt GitHub Actions / detekt[detekt] modules/storage/src/main/kotlin/edu/stanford/spezi/modules/storage/secure/SecureStorageError.kt#L4 <detekt.SpacingAroundColon>
Raw output
|
||
private fun readResolve(): Any = NotFound | ||
Check warning on line 5 in modules/storage/src/main/kotlin/edu/stanford/spezi/modules/storage/secure/SecureStorageError.kt GitHub Actions / detekt[detekt] modules/storage/src/main/kotlin/edu/stanford/spezi/modules/storage/secure/SecureStorageError.kt#L5 <detekt.UnusedPrivateMember>
Raw output
|
||
} | ||
|
||
data class CreateFailed(val error: Error? = null): SecureStorageError() | ||
Check warning on line 8 in modules/storage/src/main/kotlin/edu/stanford/spezi/modules/storage/secure/SecureStorageError.kt GitHub Actions / detekt[detekt] modules/storage/src/main/kotlin/edu/stanford/spezi/modules/storage/secure/SecureStorageError.kt#L8 <detekt.SpacingAroundColon>
Raw output
|
||
data object MissingEntitlement: SecureStorageError() { | ||
Check warning on line 9 in modules/storage/src/main/kotlin/edu/stanford/spezi/modules/storage/secure/SecureStorageError.kt GitHub Actions / detekt[detekt] modules/storage/src/main/kotlin/edu/stanford/spezi/modules/storage/secure/SecureStorageError.kt#L9 <detekt.SpacingAroundColon>
Raw output
|
||
private fun readResolve(): Any = MissingEntitlement | ||
Check warning on line 10 in modules/storage/src/main/kotlin/edu/stanford/spezi/modules/storage/secure/SecureStorageError.kt GitHub Actions / detekt[detekt] modules/storage/src/main/kotlin/edu/stanford/spezi/modules/storage/secure/SecureStorageError.kt#L10 <detekt.UnusedPrivateMember>
Raw output
|
||
} | ||
// TODO: Missing cases for keychainError(status: OSStatus) | ||
} | ||
Check warning on line 13 in modules/storage/src/main/kotlin/edu/stanford/spezi/modules/storage/secure/SecureStorageError.kt GitHub Actions / detekt[detekt] modules/storage/src/main/kotlin/edu/stanford/spezi/modules/storage/secure/SecureStorageError.kt#L13 <detekt.NewLineAtEndOfFile>
Raw output
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,36 @@ | ||
package edu.stanford.spezi.modules.storage.secure | ||
Check warning on line 1 in modules/storage/src/main/kotlin/edu/stanford/spezi/modules/storage/secure/SecureStorageItemTypes.kt GitHub Actions / detekt[detekt] modules/storage/src/main/kotlin/edu/stanford/spezi/modules/storage/secure/SecureStorageItemTypes.kt#L1 <detekt.FinalNewline>
Raw output
|
||
|
||
enum class SecureStorageItemType { | ||
KEYS, | ||
SERVER_CREDENTIALS, | ||
NON_SERVER_CREDENTIALS | ||
Check warning on line 6 in modules/storage/src/main/kotlin/edu/stanford/spezi/modules/storage/secure/SecureStorageItemTypes.kt GitHub Actions / detekt[detekt] modules/storage/src/main/kotlin/edu/stanford/spezi/modules/storage/secure/SecureStorageItemTypes.kt#L6 <detekt.TrailingCommaOnDeclarationSite>
Raw output
|
||
} | ||
|
||
data class SecureStorageItemTypes(val types: Set<SecureStorageItemType>) { | ||
companion object { | ||
val keys = SecureStorageItemTypes( | ||
setOf( | ||
SecureStorageItemType.KEYS | ||
) | ||
) | ||
val serverCredentials = SecureStorageItemTypes( | ||
setOf( | ||
SecureStorageItemType.SERVER_CREDENTIALS | ||
) | ||
) | ||
val nonServerCredentials = SecureStorageItemTypes( | ||
setOf( | ||
SecureStorageItemType.NON_SERVER_CREDENTIALS | ||
) | ||
) | ||
val credentials = SecureStorageItemTypes( | ||
setOf( | ||
SecureStorageItemType.SERVER_CREDENTIALS, | ||
SecureStorageItemType.NON_SERVER_CREDENTIALS | ||
) | ||
) | ||
val all = SecureStorageItemTypes( | ||
SecureStorageItemType.entries.toSet() | ||
) | ||
} | ||
} | ||
Check warning on line 36 in modules/storage/src/main/kotlin/edu/stanford/spezi/modules/storage/secure/SecureStorageItemTypes.kt GitHub Actions / detekt[detekt] modules/storage/src/main/kotlin/edu/stanford/spezi/modules/storage/secure/SecureStorageItemTypes.kt#L36 <detekt.NewLineAtEndOfFile>
Raw output
|