From 018939f815d939cc5ee3e97bea373d26ce94626c Mon Sep 17 00:00:00 2001 From: Harsh Shandilya Date: Mon, 18 Jul 2022 22:52:45 +0530 Subject: Add key manager UI --- app/build.gradle.kts | 9 +++++ app/src/main/AndroidManifest.xml | 5 +++ .../app/passwordstore/ui/pgp/PGPKeyListActivity.kt | 44 +++++++++++++++++++++ .../app/passwordstore/ui/settings/PGPSettings.kt | 9 +++++ .../util/extensions/AndroidExtensions.kt | 3 +- .../util/viewmodel/PGPKeyListViewModel.kt | 46 ++++++++++++++++++++++ app/src/main/res/values/strings.xml | 1 + 7 files changed, 116 insertions(+), 1 deletion(-) create mode 100644 app/src/main/java/app/passwordstore/ui/pgp/PGPKeyListActivity.kt create mode 100644 app/src/main/java/app/passwordstore/util/viewmodel/PGPKeyListViewModel.kt (limited to 'app') diff --git a/app/build.gradle.kts b/app/build.gradle.kts index cc8e7037..a8032620 100644 --- a/app/build.gradle.kts +++ b/app/build.gradle.kts @@ -27,6 +27,14 @@ android { testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner" } + buildFeatures { + compose = true + composeOptions { + useLiveLiterals = false + kotlinCompilerExtensionVersion = libs.compose.compiler.get().versionConstraint.requiredVersion + } + } + namespace = "app.passwordstore" lint { @@ -52,6 +60,7 @@ dependencies { implementation(projects.passgen.random) implementation(projects.uiCompose) implementation(libs.androidx.activity.ktx) + implementation(libs.androidx.activity.compose) implementation(libs.androidx.appcompat) implementation(libs.androidx.autofill) implementation(libs.androidx.biometricKtx) diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index c08c284e..e187240d 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -163,6 +163,11 @@ + diff --git a/app/src/main/java/app/passwordstore/ui/pgp/PGPKeyListActivity.kt b/app/src/main/java/app/passwordstore/ui/pgp/PGPKeyListActivity.kt new file mode 100644 index 00000000..3cce4060 --- /dev/null +++ b/app/src/main/java/app/passwordstore/ui/pgp/PGPKeyListActivity.kt @@ -0,0 +1,44 @@ +package app.passwordstore.ui.pgp + +import android.os.Bundle +import androidx.activity.ComponentActivity +import androidx.activity.compose.setContent +import androidx.activity.viewModels +import androidx.compose.foundation.layout.padding +import androidx.compose.material3.ExperimentalMaterial3Api +import androidx.compose.material3.Scaffold +import androidx.compose.runtime.Composable +import androidx.compose.ui.Modifier +import app.passwordstore.ui.compose.theme.APSTheme +import app.passwordstore.util.viewmodel.PGPKeyListViewModel +import dagger.hilt.android.AndroidEntryPoint + +@AndroidEntryPoint +@OptIn(ExperimentalMaterial3Api::class) +class PGPKeyListActivity : ComponentActivity() { + + private val viewModel: PGPKeyListViewModel by viewModels() + + override fun onCreate(savedInstanceState: Bundle?) { + super.onCreate(savedInstanceState) + setContent { + APSTheme { + Scaffold { paddingValues -> + PGPKeyList(viewModel = viewModel, modifier = Modifier.padding(paddingValues)) + } + } + } + } +} + +@Composable +fun PGPKeyList( + viewModel: PGPKeyListViewModel, + modifier: Modifier = Modifier, +) { + KeyList( + identifiers = viewModel.keys, + onItemClick = viewModel::deleteKey, + modifier = modifier, + ) +} diff --git a/app/src/main/java/app/passwordstore/ui/settings/PGPSettings.kt b/app/src/main/java/app/passwordstore/ui/settings/PGPSettings.kt index 85e8667b..d44fd365 100644 --- a/app/src/main/java/app/passwordstore/ui/settings/PGPSettings.kt +++ b/app/src/main/java/app/passwordstore/ui/settings/PGPSettings.kt @@ -7,6 +7,7 @@ package app.passwordstore.ui.settings import androidx.fragment.app.FragmentActivity import app.passwordstore.ui.pgp.PGPKeyImportActivity +import app.passwordstore.ui.pgp.PGPKeyListActivity import app.passwordstore.util.extensions.launchActivity import de.Maxr1998.modernpreferences.PreferenceScreen import de.Maxr1998.modernpreferences.helpers.onClick @@ -24,6 +25,14 @@ class PGPSettings(private val activity: FragmentActivity) : SettingsProvider { false } } + pref("__") { + title = "Key manager" + persistent = false + onClick { + activity.launchActivity(PGPKeyListActivity::class.java) + false + } + } } } } diff --git a/app/src/main/java/app/passwordstore/util/extensions/AndroidExtensions.kt b/app/src/main/java/app/passwordstore/util/extensions/AndroidExtensions.kt index 69811e05..ebb24a78 100644 --- a/app/src/main/java/app/passwordstore/util/extensions/AndroidExtensions.kt +++ b/app/src/main/java/app/passwordstore/util/extensions/AndroidExtensions.kt @@ -15,6 +15,7 @@ import android.util.Base64 import android.util.TypedValue import android.view.View import android.view.autofill.AutofillManager +import androidx.activity.ComponentActivity import androidx.annotation.RequiresApi import androidx.core.content.ContextCompat import androidx.core.content.getSystemService @@ -120,7 +121,7 @@ fun FragmentActivity.snackbar( } /** Launch an activity denoted by [clazz]. */ -fun FragmentActivity.launchActivity(clazz: Class) { +fun ComponentActivity.launchActivity(clazz: Class) { startActivity(Intent(this, clazz)) } diff --git a/app/src/main/java/app/passwordstore/util/viewmodel/PGPKeyListViewModel.kt b/app/src/main/java/app/passwordstore/util/viewmodel/PGPKeyListViewModel.kt new file mode 100644 index 00000000..93e450b4 --- /dev/null +++ b/app/src/main/java/app/passwordstore/util/viewmodel/PGPKeyListViewModel.kt @@ -0,0 +1,46 @@ +package app.passwordstore.util.viewmodel + +import androidx.compose.runtime.getValue +import androidx.compose.runtime.mutableStateOf +import androidx.compose.runtime.setValue +import androidx.lifecycle.ViewModel +import androidx.lifecycle.viewModelScope +import app.passwordstore.crypto.GpgIdentifier +import app.passwordstore.crypto.KeyUtils +import app.passwordstore.crypto.PGPKeyManager +import com.github.michaelbull.result.Err +import com.github.michaelbull.result.Ok +import com.github.michaelbull.result.map +import dagger.hilt.android.lifecycle.HiltViewModel +import javax.inject.Inject +import kotlinx.coroutines.launch + +@HiltViewModel +class PGPKeyListViewModel @Inject constructor(private val keyManager: PGPKeyManager) : ViewModel() { + var keys: List by mutableStateOf(emptyList()) + + init { + getKeys() + } + + private fun getKeys() { + viewModelScope.launch { + when ( + val result = + keyManager.getAllKeys().map { keys -> + keys.mapNotNull { key -> KeyUtils.tryGetEmail(key) } + } + ) { + is Ok -> keys = result.value + is Err -> TODO() + } + } + } + + fun deleteKey(identifier: GpgIdentifier) { + viewModelScope.launch { + keyManager.removeKey(identifier) + getKeys() + } + } +} diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index b9b90294..67b429f9 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -378,5 +378,6 @@ PGP settings Some error occurred Run garbage collection job + PGP Key Manager -- cgit v1.2.3