aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHarsh Shandilya <me@msfjarvis.dev>2022-07-18 22:52:45 +0530
committerHarsh Shandilya <me@msfjarvis.dev>2022-07-18 23:04:59 +0530
commit018939f815d939cc5ee3e97bea373d26ce94626c (patch)
treeffc16effbdaf47d535958c0544cdda505aee96ea
parent82923983490fa87303303f37f39585b4785d9275 (diff)
Add key manager UI
-rw-r--r--app/build.gradle.kts9
-rw-r--r--app/src/main/AndroidManifest.xml5
-rw-r--r--app/src/main/java/app/passwordstore/ui/pgp/PGPKeyListActivity.kt44
-rw-r--r--app/src/main/java/app/passwordstore/ui/settings/PGPSettings.kt9
-rw-r--r--app/src/main/java/app/passwordstore/util/extensions/AndroidExtensions.kt3
-rw-r--r--app/src/main/java/app/passwordstore/util/viewmodel/PGPKeyListViewModel.kt46
-rw-r--r--app/src/main/res/values/strings.xml1
7 files changed, 116 insertions, 1 deletions
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 @@
<activity
android:name=".ui.pgp.PGPKeyImportActivity"
android:theme="@style/NoBackgroundThemeM3" />
+ <activity
+ android:name=".ui.pgp.PGPKeyListActivity"
+ android:exported="false"
+ android:label="@string/activity_label_pgp_key_manager"
+ android:parentActivityName=".ui.settings.SettingsActivity" />
</application>
<queries>
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 <T : FragmentActivity> FragmentActivity.launchActivity(clazz: Class<T>) {
+fun <T : ComponentActivity> ComponentActivity.launchActivity(clazz: Class<T>) {
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<GpgIdentifier> 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 @@
<string name="pref_category_pgp_title">PGP settings</string>
<string name="pwgen_some_error_occurred">Some error occurred</string>
<string name="git_run_gc_job">Run garbage collection job</string>
+ <string name="activity_label_pgp_key_manager">PGP Key Manager</string>
</resources>