summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFabian Henneke <FabianHenneke@users.noreply.github.com>2020-08-11 18:11:39 +0200
committerGitHub <noreply@github.com>2020-08-11 18:11:39 +0200
commit15aa92980239d6d61c3b0febc0407b7f63e152b3 (patch)
tree92b25ea3bca41e37fe4727bab82665b04ee8206e
parent8f957ca99454efe1711e2424620d2632bed6cb63 (diff)
Switch to URL-based Git config and refactor Git settings (#1008)
* Make Git config URL-based and refactor * Use Kotlin style null handling for string prefs * Also show an error if generated URL can't be parsed * Add some testcases for migration strategy Signed-off-by: Harsh Shandilya <me@msfjarvis.dev> Co-authored-by: Harsh Shandilya <me@msfjarvis.dev>
-rw-r--r--CHANGELOG.md1
-rw-r--r--app/src/androidTest/java/com/zeapo/pwdstore/MigrationsTest.kt81
-rw-r--r--app/src/androidTest/java/com/zeapo/pwdstore/git/GitServerConfigActivityTest.kt126
-rw-r--r--app/src/main/java/com/zeapo/pwdstore/Application.kt5
-rw-r--r--app/src/main/java/com/zeapo/pwdstore/ClipboardService.kt4
-rw-r--r--app/src/main/java/com/zeapo/pwdstore/LaunchActivity.kt1
-rw-r--r--app/src/main/java/com/zeapo/pwdstore/Migrations.kt83
-rw-r--r--app/src/main/java/com/zeapo/pwdstore/PasswordFragment.kt5
-rw-r--r--app/src/main/java/com/zeapo/pwdstore/PasswordStore.kt15
-rw-r--r--app/src/main/java/com/zeapo/pwdstore/SearchableRepositoryViewModel.kt1
-rw-r--r--app/src/main/java/com/zeapo/pwdstore/UserPreference.kt20
-rw-r--r--app/src/main/java/com/zeapo/pwdstore/autofill/oreo/AutofillHelper.kt8
-rw-r--r--app/src/main/java/com/zeapo/pwdstore/autofill/oreo/AutofillPreferences.kt2
-rw-r--r--app/src/main/java/com/zeapo/pwdstore/autofill/oreo/PublicSuffixListCache.kt9
-rw-r--r--app/src/main/java/com/zeapo/pwdstore/crypto/BasePgpActivity.kt4
-rw-r--r--app/src/main/java/com/zeapo/pwdstore/crypto/PasswordCreationActivity.kt3
-rw-r--r--app/src/main/java/com/zeapo/pwdstore/git/BaseGitActivity.kt122
-rw-r--r--app/src/main/java/com/zeapo/pwdstore/git/GitConfigActivity.kt21
-rw-r--r--app/src/main/java/com/zeapo/pwdstore/git/GitOperationActivity.kt5
-rw-r--r--app/src/main/java/com/zeapo/pwdstore/git/GitServerConfigActivity.kt91
-rw-r--r--app/src/main/java/com/zeapo/pwdstore/git/config/ConnectionMode.kt22
-rw-r--r--app/src/main/java/com/zeapo/pwdstore/git/config/GitSettings.kt115
-rw-r--r--app/src/main/java/com/zeapo/pwdstore/git/config/Protocol.kt20
-rw-r--r--app/src/main/java/com/zeapo/pwdstore/git/config/SshApiSessionFactory.java36
-rw-r--r--app/src/main/java/com/zeapo/pwdstore/git/config/SshjSessionFactory.kt4
-rw-r--r--app/src/main/java/com/zeapo/pwdstore/git/operation/GitOperation.kt33
-rw-r--r--app/src/main/java/com/zeapo/pwdstore/pwgenxkpwd/XkpwdDictionary.kt4
-rw-r--r--app/src/main/java/com/zeapo/pwdstore/sshkeygen/SshKeyGenActivity.kt1
-rw-r--r--app/src/main/java/com/zeapo/pwdstore/ui/adapters/PasswordItemRecyclerAdapter.kt1
-rw-r--r--app/src/main/java/com/zeapo/pwdstore/utils/Extensions.kt2
-rw-r--r--app/src/main/java/com/zeapo/pwdstore/utils/PasswordRepository.kt9
-rw-r--r--app/src/main/java/com/zeapo/pwdstore/utils/PreferenceKeys.kt9
-rw-r--r--app/src/main/res/layout/activity_git_clone.xml68
-rw-r--r--app/src/main/res/values-ar/strings.xml4
-rw-r--r--app/src/main/res/values-cs/strings.xml4
-rw-r--r--app/src/main/res/values-de/strings.xml4
-rw-r--r--app/src/main/res/values-es/strings.xml4
-rw-r--r--app/src/main/res/values-fr/strings.xml4
-rw-r--r--app/src/main/res/values-ja/strings.xml4
-rw-r--r--app/src/main/res/values-pt-rBR/strings.xml5
-rw-r--r--app/src/main/res/values-ru/strings.xml4
-rw-r--r--app/src/main/res/values-zh-rCN/strings.xml4
-rw-r--r--app/src/main/res/values-zh-rTW/strings.xml4
-rw-r--r--app/src/main/res/values/strings.xml8
44 files changed, 395 insertions, 585 deletions
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 418ad027..2b2249a0 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -10,6 +10,7 @@ All notable changes to this project will be documented in this file.
### Changed
+- The Git repository URL can now be specified directly
- Slightly reduce APK size
- Always show the parent path in entries
- Passwords will no longer be copied to the clipboard by default
diff --git a/app/src/androidTest/java/com/zeapo/pwdstore/MigrationsTest.kt b/app/src/androidTest/java/com/zeapo/pwdstore/MigrationsTest.kt
new file mode 100644
index 00000000..d1b04fc3
--- /dev/null
+++ b/app/src/androidTest/java/com/zeapo/pwdstore/MigrationsTest.kt
@@ -0,0 +1,81 @@
+/*
+ * Copyright © 2014-2020 The Android Password Store Authors. All Rights Reserved.
+ * SPDX-License-Identifier: GPL-3.0-only
+ */
+
+@file:Suppress("DEPRECATION")
+package com.zeapo.pwdstore
+
+import android.content.Context
+import androidx.core.content.edit
+import com.zeapo.pwdstore.utils.PreferenceKeys
+import com.zeapo.pwdstore.utils.getString
+import com.zeapo.pwdstore.utils.sharedPrefs
+import org.junit.Test
+
+import org.junit.Assert.*
+
+class MigrationsTest {
+
+ private fun checkOldKeysAreRemoved(context: Context) = with(context.sharedPrefs) {
+ assertNull(getString(PreferenceKeys.GIT_REMOTE_PORT))
+ assertNull(getString(PreferenceKeys.GIT_REMOTE_USERNAME))
+ assertNull(getString(PreferenceKeys.GIT_REMOTE_SERVER))
+ assertNull(getString(PreferenceKeys.GIT_REMOTE_LOCATION))
+ }
+
+ @Test
+ fun verifySshWithCustomPortMigration() {
+ val context = Application.instance.applicationContext
+ context.sharedPrefs.edit {
+ clear()
+ putString(PreferenceKeys.GIT_REMOTE_PORT, "2200")
+ putString(PreferenceKeys.GIT_REMOTE_USERNAME, "msfjarvis")
+ putString(PreferenceKeys.GIT_REMOTE_LOCATION, "/mnt/disk3/pass-repo")
+ putString(PreferenceKeys.GIT_REMOTE_SERVER, "192.168.0.102")
+ putString(PreferenceKeys.GIT_REMOTE_PROTOCOL, "ssh://")
+ }
+ runMigrations(context)
+ checkOldKeysAreRemoved(context)
+ assertEquals(
+ context.sharedPrefs.getString(PreferenceKeys.GIT_REMOTE_URL),
+ "ssh://msfjarvis@192.168.0.102:2200/mnt/disk3/pass-repo"
+ )
+ }
+
+ @Test
+ fun verifySshWithDefaultPortMigration() {
+ val context = Application.instance.applicationContext
+ context.sharedPrefs.edit {
+ clear()
+ putString(PreferenceKeys.GIT_REMOTE_USERNAME, "msfjarvis")
+ putString(PreferenceKeys.GIT_REMOTE_LOCATION, "/mnt/disk3/pass-repo")
+ putString(PreferenceKeys.GIT_REMOTE_SERVER, "192.168.0.102")
+ putString(PreferenceKeys.GIT_REMOTE_PROTOCOL, "ssh://")
+ }
+ runMigrations(context)
+ checkOldKeysAreRemoved(context)
+ assertEquals(
+ context.sharedPrefs.getString(PreferenceKeys.GIT_REMOTE_URL),
+ "msfjarvis@192.168.0.102:/mnt/disk3/pass-repo"
+ )
+ }
+
+ @Test
+ fun verifyHttpsWithGitHubMigration() {
+ val context = Application.instance.applicationContext
+ context.sharedPrefs.edit {
+ clear()
+ putString(PreferenceKeys.GIT_REMOTE_USERNAME, "msfjarvis")
+ putString(PreferenceKeys.GIT_REMOTE_LOCATION, "Android-Password-Store/pass-test")
+ putString(PreferenceKeys.GIT_REMOTE_SERVER, "github.com")
+ putString(PreferenceKeys.GIT_REMOTE_PROTOCOL, "https://")
+ }
+ runMigrations(context)
+ checkOldKeysAreRemoved(context)
+ assertEquals(
+ context.sharedPrefs.getString(PreferenceKeys.GIT_REMOTE_URL),
+ "https://github.com/Android-Password-Store/pass-test"
+ )
+ }
+}
diff --git a/app/src/androidTest/java/com/zeapo/pwdstore/git/GitServerConfigActivityTest.kt b/app/src/androidTest/java/com/zeapo/pwdstore/git/GitServerConfigActivityTest.kt
deleted file mode 100644
index 2c2691b1..00000000
--- a/app/src/androidTest/java/com/zeapo/pwdstore/git/GitServerConfigActivityTest.kt
+++ /dev/null
@@ -1,126 +0,0 @@
-/*
- * Copyright © 2014-2020 The Android Password Store Authors. All Rights Reserved.
- * SPDX-License-Identifier: GPL-3.0-only
- */
-
-package com.zeapo.pwdstore.git
-
-import android.view.View
-import androidx.test.espresso.Espresso.onView
-import androidx.test.espresso.UiController
-import androidx.test.espresso.ViewAction
-import androidx.test.espresso.action.ViewActions.replaceText
-import androidx.test.espresso.matcher.ViewMatchers.isEnabled
-import androidx.test.espresso.matcher.ViewMatchers.withId
-import androidx.test.ext.junit.runners.AndroidJUnit4
-import androidx.test.rule.ActivityTestRule
-import com.google.android.material.button.MaterialButtonToggleGroup
-import com.zeapo.pwdstore.R
-import com.zeapo.pwdstore.git.BaseGitActivity.GitUpdateUrlResult
-import kotlin.test.assertEquals
-import org.hamcrest.Matcher
-import org.junit.Rule
-import org.junit.Test
-import org.junit.runner.RunWith
-
-@RunWith(AndroidJUnit4::class)
-class GitServerConfigActivityTest {
-
- @Rule
- @JvmField
- val activityRule = ActivityTestRule(GitServerConfigActivity::class.java, true)
-
- private val activity get() = activityRule.activity
-
- @Test
- fun invalidValuesFailPredictably() {
- setDefaultSshValues()
- onView(withId(R.id.server_port)).perform(replaceText("69420"))
- assertEquals(activity.updateUrl(), GitUpdateUrlResult.CustomPortRequiresAbsoluteUrlError)
-
- setDefaultSshValues()
- onView(withId(R.id.server_url)).perform(replaceText(""))
- assertEquals(activity.updateUrl(), GitUpdateUrlResult.EmptyHostnameError)
-
- setDefaultSshValues()
- onView(withId(R.id.server_port)).perform(replaceText("xyz_is_not_a_port"))
- assertEquals(activity.updateUrl(), GitUpdateUrlResult.NonNumericPortError)
-
- setDefaultHttpsValues()
- onView(withId(R.id.server_port)).perform(replaceText("xyz_is_not_a_port"))
- assertEquals(activity.updateUrl(), GitUpdateUrlResult.NonNumericPortError)
-
- setDefaultHttpsValues()
- onView(withId(R.id.server_url)).perform(replaceText(""))
- assertEquals(activity.updateUrl(), GitUpdateUrlResult.EmptyHostnameError)
- }
-
- @Test
- fun urlIsConstructedCorrectly() {
- setDefaultSshValues()
- activity.updateUrl()
- assertEquals("john_doe@github.com:john_doe/my_secret_repository", activity.url)
-
- setDefaultSshValues()
- onView(withId(R.id.server_port)).perform(replaceText("69420"))
- onView(withId(R.id.server_url)).perform(replaceText("192.168.0.102"))
- onView(withId(R.id.server_path)).perform(replaceText("/home/john_doe/my_secret_repository"))
- activity.updateUrl()
- assertEquals("ssh://john_doe@192.168.0.102:69420/home/john_doe/my_secret_repository", activity.url)
-
- setDefaultHttpsValues()
- activity.updateUrl()
- assertEquals("https://github.com/john_doe/my_secret_repository", activity.url)
-
- setDefaultHttpsValues()
- onView(withId(R.id.server_port)).perform(replaceText("69420"))
- onView(withId(R.id.server_url)).perform(replaceText("192.168.0.102"))
- onView(withId(R.id.server_path)).perform(replaceText("/home/john_doe/my_secret_repository"))
- activity.updateUrl()
- assertEquals("https://192.168.0.102:69420/home/john_doe/my_secret_repository", activity.url)
- }
-
- private fun <T> callMethod(message: String = "", viewMethod: (view: T) -> Unit): ViewAction {
- return object : ViewAction {
- override fun getDescription(): String {
- return if (message.isBlank()) viewMethod.toString() else message
- }
-
- override fun getConstraints(): Matcher<View> {
- return isEnabled()
- }
-
- @Suppress("UNCHECKED_CAST")
- override fun perform(uiController: UiController?, view: View?) {
- viewMethod(view!! as T)
- }
-
- }
- }
-
- private fun setDefaultHttpsValues() {
- onView(withId(R.id.clone_protocol_group)).perform(callMethod<MaterialButtonToggleGroup> {
- it.check(R.id.clone_protocol_https)
- })
- onView(withId(R.id.connection_mode_group)).perform(callMethod<MaterialButtonToggleGroup> {
- it.check(R.id.connection_mode_password)
- })
- onView(withId(R.id.server_path)).perform(replaceText("john_doe/my_secret_repository"))
- onView(withId(R.id.server_port)).perform(replaceText(""))
- onView(withId(R.id.server_url)).perform(replaceText("github.com"))
- onView(withId(R.id.server_user)).perform(replaceText("john_doe"))
- }
-
- private fun setDefaultSshValues() {
- onView(withId(R.id.clone_protocol_group)).perform(callMethod<MaterialButtonToggleGroup> {
- it.check(R.id.clone_protocol_ssh)
- })
- onView(withId(R.id.connection_mode_group)).perform(callMethod<MaterialButtonToggleGroup> {
- it.check(R.id.connection_mode_ssh_key)
- })
- onView(withId(R.id.server_path)).perform(replaceText("john_doe/my_secret_repository"))
- onView(withId(R.id.server_port)).perform(replaceText(""))
- onView(withId(R.id.server_url)).perform(replaceText("github.com"))
- onView(withId(R.id.server_user)).perform(replaceText("john_doe"))
- }
-}
diff --git a/app/src/main/java/com/zeapo/pwdstore/Application.kt b/app/src/main/java/com/zeapo/pwdstore/Application.kt
index c3b9a90d..544eb047 100644
--- a/app/src/main/java/com/zeapo/pwdstore/Application.kt
+++ b/app/src/main/java/com/zeapo/pwdstore/Application.kt
@@ -10,12 +10,12 @@ import androidx.appcompat.app.AppCompatDelegate.MODE_NIGHT_AUTO_BATTERY
import androidx.appcompat.app.AppCompatDelegate.MODE_NIGHT_FOLLOW_SYSTEM
import androidx.appcompat.app.AppCompatDelegate.MODE_NIGHT_NO
import androidx.appcompat.app.AppCompatDelegate.MODE_NIGHT_YES
-import androidx.preference.PreferenceManager
import com.github.ajalt.timberkt.Timber.DebugTree
import com.github.ajalt.timberkt.Timber.plant
import com.zeapo.pwdstore.git.config.setUpBouncyCastleForSshj
import com.zeapo.pwdstore.utils.PreferenceKeys
import com.zeapo.pwdstore.utils.sharedPrefs
+import com.zeapo.pwdstore.utils.getString
@Suppress("Unused")
class Application : android.app.Application(), SharedPreferences.OnSharedPreferenceChangeListener {
@@ -30,6 +30,7 @@ class Application : android.app.Application(), SharedPreferences.OnSharedPrefere
sharedPrefs.registerOnSharedPreferenceChangeListener(this)
setNightMode()
setUpBouncyCastleForSshj()
+ runMigrations(applicationContext)
}
override fun onTerminate() {
@@ -44,7 +45,7 @@ class Application : android.app.Application(), SharedPreferences.OnSharedPrefere
}
private fun setNightMode() {
- AppCompatDelegate.setDefaultNightMode(when (sharedPrefs.getString(PreferenceKeys.APP_THEME, getString(R.string.app_theme_def))) {
+ AppCompatDelegate.setDefaultNightMode(when (sharedPrefs.getString(PreferenceKeys.APP_THEME) ?: getString(R.string.app_theme_def)) {
"light" -> MODE_NIGHT_NO
"dark" -> MODE_NIGHT_YES
"follow_system" -> MODE_NIGHT_FOLLOW_SYSTEM
diff --git a/app/src/main/java/com/zeapo/pwdstore/ClipboardService.kt b/app/src/main/java/com/zeapo/pwdstore/ClipboardService.kt
index 20a36539..d02a333a 100644
--- a/app/src/main/java/com/zeapo/pwdstore/ClipboardService.kt
+++ b/app/src/main/java/com/zeapo/pwdstore/ClipboardService.kt
@@ -15,10 +15,10 @@ import android.os.Build
import android.os.IBinder
import androidx.core.app.NotificationCompat
import androidx.core.content.getSystemService
-import androidx.preference.PreferenceManager
import com.github.ajalt.timberkt.d
import com.zeapo.pwdstore.utils.PreferenceKeys
import com.zeapo.pwdstore.utils.clipboard
+import com.zeapo.pwdstore.utils.getString
import com.zeapo.pwdstore.utils.sharedPrefs
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
@@ -46,7 +46,7 @@ class ClipboardService : Service() {
ACTION_START -> {
val time = try {
- Integer.parseInt(settings.getString(PreferenceKeys.GENERAL_SHOW_TIME, "45") as String)
+ Integer.parseInt(settings.getString(PreferenceKeys.GENERAL_SHOW_TIME) ?: "45")
} catch (e: NumberFormatException) {
45
}
diff --git a/app/src/main/java/com/zeapo/pwdstore/LaunchActivity.kt b/app/src/main/java/com/zeapo/pwdstore/LaunchActivity.kt
index 71f59851..430f683a 100644
--- a/app/src/main/java/com/zeapo/pwdstore/LaunchActivity.kt
+++ b/app/src/main/java/com/zeapo/pwdstore/LaunchActivity.kt
@@ -9,7 +9,6 @@ import android.os.Bundle
import android.os.Handler
import androidx.appcompat.app.AppCompatActivity
import androidx.core.content.edit
-import androidx.preference.PreferenceManager
import com.zeapo.pwdstore.crypto.DecryptActivity
import com.zeapo.pwdstore.utils.BiometricAuthenticator
import com.zeapo.pwdstore.utils.PreferenceKeys
diff --git a/app/src/main/java/com/zeapo/pwdstore/Migrations.kt b/app/src/main/java/com/zeapo/pwdstore/Migrations.kt
new file mode 100644
index 00000000..1e1943d8
--- /dev/null
+++ b/app/src/main/java/com/zeapo/pwdstore/Migrations.kt
@@ -0,0 +1,83 @@
+/*
+ * Copyright © 2014-2020 The Android Password Store Authors. All Rights Reserved.
+ * SPDX-License-Identifier: GPL-3.0-only
+ */
+@file:Suppress("DEPRECATION")
+
+package com.zeapo.pwdstore
+
+import android.content.Context
+import androidx.core.content.edit
+import com.github.ajalt.timberkt.e
+import com.github.ajalt.timberkt.i
+import com.zeapo.pwdstore.git.config.GitSettings
+import com.zeapo.pwdstore.git.config.Protocol
+import com.zeapo.pwdstore.utils.PreferenceKeys
+import com.zeapo.pwdstore.utils.getString
+import com.zeapo.pwdstore.utils.sharedPrefs
+import java.net.URI
+
+fun runMigrations(context: Context) {
+ migrateToGitUrlBasedConfig(context)
+}
+
+private fun migrateToGitUrlBasedConfig(context: Context) {
+ val serverHostname = context.sharedPrefs.getString(PreferenceKeys.GIT_REMOTE_SERVER)
+ ?: return
+ i { "Migrating to URL-based Git config" }
+ val serverPort = context.sharedPrefs.getString(PreferenceKeys.GIT_REMOTE_PORT) ?: ""
+ val serverUser = context.sharedPrefs.getString(PreferenceKeys.GIT_REMOTE_USERNAME) ?: ""
+ val serverPath = context.sharedPrefs.getString(PreferenceKeys.GIT_REMOTE_LOCATION) ?: ""
+ val protocol = Protocol.fromString(context.sharedPrefs.getString(PreferenceKeys.GIT_REMOTE_PROTOCOL))
+
+ // Whether we need the leading ssh:// depends on the use of a custom port.
+ val hostnamePart = serverHostname.removePrefix("ssh://")
+ val url = when (protocol) {
+ Protocol.Ssh -> {
+ val userPart = if (serverUser.isEmpty()) "" else "${serverUser.trimEnd('@')}@"
+ val portPart =
+ if (serverPort == "22" || serverPort.isEmpty()) "" else ":$serverPort"
+ if (portPart.isEmpty()) {
+ "$userPart$hostnamePart:$serverPath"
+ } else {
+ // Only absolute paths are supported with custom ports.
+ if (!serverPath.startsWith('/'))
+ null
+ else
+ // We have to specify the ssh scheme as this is the only way to pass a custom
+ // port.
+ "ssh://$userPart$hostnamePart$portPart$serverPath"
+ }
+ }
+ Protocol.Https -> {
+ val portPart =
+ if (serverPort == "443" || serverPort.isEmpty()) "" else ":$serverPort"
+ val pathPart = serverPath.trimStart('/', ':')
+ val urlWithFreeEntryScheme = "$hostnamePart$portPart/$pathPart"
+ val url = when {
+ urlWithFreeEntryScheme.startsWith("https://") -> urlWithFreeEntryScheme
+ urlWithFreeEntryScheme.startsWith("http://") -> urlWithFreeEntryScheme.replaceFirst("http", "https")
+ else -> "https://$urlWithFreeEntryScheme"
+ }
+ try {
+ if (URI(url).rawAuthority != null)
+ url
+ else
+ null
+ } catch (_: Exception) {
+ null
+ }
+ }
+ }
+
+ context.sharedPrefs.edit {
+ remove(PreferenceKeys.GIT_REMOTE_LOCATION)
+ remove(PreferenceKeys.GIT_REMOTE_PORT)
+ remove(PreferenceKeys.GIT_REMOTE_SERVER)
+ remove(PreferenceKeys.GIT_REMOTE_USERNAME)
+ }
+ if (url == null || !GitSettings.updateUrlIfValid(url)) {
+ e { "Failed to migrate to URL-based Git config, generated URL is invalid" }
+ }
+}
+
diff --git a/app/src/main/java/com/zeapo/pwdstore/PasswordFragment.kt b/app/src/main/java/com/zeapo/pwdstore/PasswordFragment.kt
index c9d00353..6657afaf 100644
--- a/app/src/main/java/com/zeapo/pwdstore/PasswordFragment.kt
+++ b/app/src/main/java/com/zeapo/pwdstore/PasswordFragment.kt
@@ -26,12 +26,12 @@ import com.zeapo.pwdstore.git.BaseGitActivity
import com.zeapo.pwdstore.git.GitOperationActivity
import com.zeapo.pwdstore.git.GitServerConfigActivity
import com.zeapo.pwdstore.git.config.ConnectionMode
+import com.zeapo.pwdstore.git.config.GitSettings
import com.zeapo.pwdstore.ui.OnOffItemAnimator
import com.zeapo.pwdstore.ui.adapters.PasswordItemRecyclerAdapter
import com.zeapo.pwdstore.ui.dialogs.ItemCreationBottomSheet
import com.zeapo.pwdstore.utils.PasswordItem
import com.zeapo.pwdstore.utils.PasswordRepository
-import com.zeapo.pwdstore.utils.PreferenceKeys
import com.zeapo.pwdstore.utils.sharedPrefs
import com.zeapo.pwdstore.utils.viewBinding
import java.io.File
@@ -91,8 +91,7 @@ class PasswordFragment : Fragment(R.layout.password_recycler_view) {
} else {
// When authentication is set to ConnectionMode.None then the only git operation we
// can run is a pull, so automatically fallback to that.
- val operationId = when (ConnectionMode.fromString(settings.getString
- (PreferenceKeys.GIT_REMOTE_AUTH, null))) {
+ val operationId = when (GitSettings.connectionMode) {
ConnectionMode.None -> BaseGitActivity.REQUEST_PULL
else -> BaseGitActivity.REQUEST_SYNC
}
diff --git a/app/src/main/java/com/zeapo/pwdstore/PasswordStore.kt b/app/src/main/java/com/zeapo/pwdstore/PasswordStore.kt
index 3f31a2c5..8223b127 100644
--- a/app/src/main/java/com/zeapo/pwdstore/PasswordStore.kt
+++ b/app/src/main/java/com/zeapo/pwdstore/PasswordStore.kt
@@ -7,7 +7,6 @@ package com.zeapo.pwdstore
import android.Manifest
import android.annotation.SuppressLint
import android.content.Intent
-import android.content.SharedPreferences
import android.content.pm.PackageManager
import android.content.pm.ShortcutInfo.Builder
import android.content.pm.ShortcutManager
@@ -34,7 +33,6 @@ import androidx.fragment.app.FragmentManager
import androidx.fragment.app.commit
import androidx.lifecycle.ViewModelProvider
import androidx.lifecycle.lifecycleScope
-import androidx.preference.PreferenceManager
import com.github.ajalt.timberkt.d
import com.github.ajalt.timberkt.e
import com.github.ajalt.timberkt.i
@@ -52,6 +50,7 @@ import com.zeapo.pwdstore.git.BaseGitActivity
import com.zeapo.pwdstore.git.GitOperationActivity
import com.zeapo.pwdstore.git.GitServerConfigActivity
import com.zeapo.pwdstore.git.config.ConnectionMode
+import com.zeapo.pwdstore.git.config.GitSettings
import com.zeapo.pwdstore.ui.dialogs.FolderCreationDialogFragment
import com.zeapo.pwdstore.utils.PasswordItem
import com.zeapo.pwdstore.utils.PasswordRepository
@@ -66,6 +65,7 @@ import com.zeapo.pwdstore.utils.PasswordRepository.PasswordSortOrder.Companion.g
import com.zeapo.pwdstore.utils.PreferenceKeys
import com.zeapo.pwdstore.utils.commitChange
import com.zeapo.pwdstore.utils.contains
+import com.zeapo.pwdstore.utils.getString
import com.zeapo.pwdstore.utils.isInsideRepository
import com.zeapo.pwdstore.utils.listFilesRecursively
import com.zeapo.pwdstore.utils.requestInputFocusOnView
@@ -114,8 +114,8 @@ class PasswordStore : AppCompatActivity(R.layout.activity_pwdstore) {
private val directoryChangeAction = registerForActivityResult(StartActivityForResult()) { result ->
if (result.resultCode == RESULT_OK) {
if (settings.getBoolean(PreferenceKeys.GIT_EXTERNAL, false) &&
- settings.getString(PreferenceKeys.GIT_EXTERNAL_REPO, null) != null) {
- val externalRepoPath = settings.getString(PreferenceKeys.GIT_EXTERNAL_REPO, null)
+ settings.getString(PreferenceKeys.GIT_EXTERNAL_REPO) != null) {
+ val externalRepoPath = settings.getString(PreferenceKeys.GIT_EXTERNAL_REPO)
val dir = externalRepoPath?.let { File(it) }
if (dir != null &&
dir.exists() &&
@@ -252,8 +252,7 @@ class PasswordStore : AppCompatActivity(R.layout.activity_pwdstore) {
override fun onCreateOptionsMenu(menu: Menu?): Boolean {
val menuRes = when {
- ConnectionMode.fromString(settings.getString(PreferenceKeys.GIT_REMOTE_AUTH, null))
- == ConnectionMode.None -> R.menu.main_menu_no_auth
+ GitSettings.connectionMode == ConnectionMode.None -> R.menu.main_menu_no_auth
PasswordRepository.isGitRepo() -> R.menu.main_menu_git
else -> R.menu.main_menu_non_git
}
@@ -403,7 +402,7 @@ class PasswordStore : AppCompatActivity(R.layout.activity_pwdstore) {
private fun initializeRepositoryInfo() {
val externalRepo = settings.getBoolean(PreferenceKeys.GIT_EXTERNAL, false)
- val externalRepoPath = settings.getString(PreferenceKeys.GIT_EXTERNAL_REPO, null)
+ val externalRepoPath = settings.getString(PreferenceKeys.GIT_EXTERNAL_REPO)
if (externalRepo && !hasRequiredStoragePermissions()) {
return
}
@@ -849,7 +848,7 @@ class PasswordStore : AppCompatActivity(R.layout.activity_pwdstore) {
}
.setNegativeButton(resources.getString(R.string.location_sdcard)) { _, _ ->
settings.edit { putBoolean(PreferenceKeys.GIT_EXTERNAL, true) }
- val externalRepo = settings.getString(PreferenceKeys.GIT_EXTERNAL_REPO, null)
+ val externalRepo = settings.getString(PreferenceKeys.GIT_EXTERNAL_REPO)
if (externalRepo == null) {
val intent = Intent(activity, UserPreference::class.java)
intent.putExtra("operation", "git_external")
diff --git a/app/src/main/java/com/zeapo/pwdstore/SearchableRepositoryViewModel.kt b/app/src/main/java/com/zeapo/pwdstore/SearchableRepositoryViewModel.kt
index f1728d6d..7ffa71a3 100644
--- a/app/src/main/java/com/zeapo/pwdstore/SearchableRepositoryViewModel.kt
+++ b/app/src/main/java/com/zeapo/pwdstore/SearchableRepositoryViewModel.kt
@@ -15,7 +15,6 @@ import androidx.lifecycle.LiveData
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.asFlow
import androidx.lifecycle.asLiveData
-import androidx.preference.PreferenceManager
import androidx.recyclerview.selection.ItemDetailsLookup
import androidx.recyclerview.selection.ItemKeyProvider
import androidx.recyclerview.selection.Selection
diff --git a/app/src/main/java/com/zeapo/pwdstore/UserPreference.kt b/app/src/main/java/com/zeapo/pwdstore/UserPreference.kt
index 43cab0a0..7f01e063 100644
--- a/app/src/main/java/com/zeapo/pwdstore/UserPreference.kt
+++ b/app/src/main/java/com/zeapo/pwdstore/UserPreference.kt
@@ -34,7 +34,6 @@ import androidx.preference.EditTextPreference
import androidx.preference.ListPreference
import androidx.preference.Preference
import androidx.preference.PreferenceFragmentCompat
-import androidx.preference.PreferenceManager
import androidx.preference.SwitchPreferenceCompat
import com.github.ajalt.timberkt.Timber.tag
import com.github.ajalt.timberkt.d
@@ -54,6 +53,7 @@ import com.zeapo.pwdstore.utils.PasswordRepository
import com.zeapo.pwdstore.utils.PreferenceKeys
import com.zeapo.pwdstore.utils.autofillManager
import com.zeapo.pwdstore.utils.getEncryptedPrefs
+import com.zeapo.pwdstore.utils.getString
import com.zeapo.pwdstore.utils.sharedPrefs
import java.io.File
import java.io.IOException
@@ -141,11 +141,11 @@ class UserPreference : AppCompatActivity() {
// Misc preferences
val appVersionPreference = findPreference<Preference>(PreferenceKeys.APP_VERSION)
- selectExternalGitRepositoryPreference?.summary = sharedPreferences.getString(PreferenceKeys.GIT_EXTERNAL_REPO, getString(R.string.no_repo_selected))
+ selectExternalGitRepositoryPreference?.summary = sharedPreferences.getString(PreferenceKeys.GIT_EXTERNAL_REPO) ?: getString(R.string.no_repo_selected)
viewSshKeyPreference?.isVisible = sharedPreferences.getBoolean(PreferenceKeys.USE_GENERATED_KEY, false)
deleteRepoPreference?.isVisible = !sharedPreferences.getBoolean(PreferenceKeys.GIT_EXTERNAL, false)
- clearClipboard20xPreference?.isVisible = sharedPreferences.getString(PreferenceKeys.GENERAL_SHOW_TIME, "45")?.toInt() != 0
- openkeystoreIdPreference?.isVisible = sharedPreferences.getString(PreferenceKeys.SSH_OPENKEYSTORE_KEYID, null)?.isNotEmpty()
+ clearClipboard20xPreference?.isVisible = sharedPreferences.getString(PreferenceKeys.GENERAL_SHOW_TIME)?.toInt() != 0
+ openkeystoreIdPreference?.isVisible = sharedPreferences.getString(PreferenceKeys.SSH_OPENKEYSTORE_KEYID)?.isNotEmpty()
?: false
updateAutofillSettings()
@@ -171,9 +171,9 @@ class UserPreference : AppCompatActivity() {
clearSavedPassPreference?.onPreferenceClickListener = ClickListener {
encryptedPreferences.edit {
- if (encryptedPreferences.getString(PreferenceKeys.HTTPS_PASSWORD, null) != null)
+ if (encryptedPreferences.getString(PreferenceKeys.HTTPS_PASSWORD) != null)
remove(PreferenceKeys.HTTPS_PASSWORD)
- else if (encryptedPreferences.getString(PreferenceKeys.SSH_KEY_LOCAL_PASSPHRASE, null) != null)
+ else if (encryptedPreferences.getString(PreferenceKeys.SSH_KEY_LOCAL_PASSPHRASE) != null)
remove(PreferenceKeys.SSH_KEY_LOCAL_PASSPHRASE)
}
updateClearSavedPassphrasePrefs()
@@ -226,7 +226,7 @@ class UserPreference : AppCompatActivity() {
}
selectExternalGitRepositoryPreference?.summary =
- sharedPreferences.getString(PreferenceKeys.GIT_EXTERNAL_REPO, context.getString(R.string.no_repo_selected))
+ sharedPreferences.getString(PreferenceKeys.GIT_EXTERNAL_REPO) ?: context.getString(R.string.no_repo_selected)
selectExternalGitRepositoryPreference?.onPreferenceClickListener = ClickListener {
prefsActivity.selectExternalGitRepository()
true
@@ -321,7 +321,7 @@ class UserPreference : AppCompatActivity() {
prefsActivity.storeCustomDictionaryPath()
true
}
- val dictUri = sharedPreferences.getString(PreferenceKeys.PREF_KEY_CUSTOM_DICT, "")
+ val dictUri = sharedPreferences.getString(PreferenceKeys.PREF_KEY_CUSTOM_DICT) ?: ""
if (!TextUtils.isEmpty(dictUri)) {
setCustomDictSummary(prefCustomXkpwdDictionary, Uri.parse(dictUri))
@@ -377,8 +377,8 @@ class UserPreference : AppCompatActivity() {
private fun updateClearSavedPassphrasePrefs() {
clearSavedPassPreference?.apply {
- val sshPass = encryptedPreferences.getString(PreferenceKeys.SSH_KEY_LOCAL_PASSPHRASE, null)
- val httpsPass = encryptedPreferences.getString(PreferenceKeys.HTTPS_PASSWORD, null)
+ val sshPass = encryptedPreferences.getString(PreferenceKeys.SSH_KEY_LOCAL_PASSPHRASE)
+ val httpsPass = encryptedPreferences.getString(PreferenceKeys.HTTPS_PASSWORD)
if (sshPass == null && httpsPass == null) {
isVisible = false
return@apply
diff --git a/app/src/main/java/com/zeapo/pwdstore/autofill/oreo/AutofillHelper.kt b/app/src/main/java/com/zeapo/pwdstore/autofill/oreo/AutofillHelper.kt
index d5c7af75..14bcb501 100644
--- a/app/src/main/java/com/zeapo/pwdstore/autofill/oreo/AutofillHelper.kt
+++ b/app/src/main/java/com/zeapo/pwdstore/autofill/oreo/AutofillHelper.kt
@@ -23,6 +23,8 @@ import com.zeapo.pwdstore.R
import com.zeapo.pwdstore.model.PasswordEntry
import com.zeapo.pwdstore.utils.PasswordRepository
import com.zeapo.pwdstore.utils.PreferenceKeys
+import com.zeapo.pwdstore.utils.getString
+import com.zeapo.pwdstore.utils.sharedPrefs
import java.io.File
import java.security.MessageDigest
@@ -37,11 +39,7 @@ private fun ByteArray.base64(): String {
return Base64.encodeToString(this, Base64.NO_WRAP)
}
-private fun Context.getDefaultUsername(): String? {
- return PreferenceManager
- .getDefaultSharedPreferences(this)
- .getString(PreferenceKeys.OREO_AUTOFILL_DEFAULT_USERNAME, null)
-}
+private fun Context.getDefaultUsername() = sharedPrefs.getString(PreferenceKeys.OREO_AUTOFILL_DEFAULT_USERNAME)
private fun stableHash(array: Collection<ByteArray>): String {
val hashes = array.map { it.sha256().base64() }
diff --git a/app/src/main/java/com/zeapo/pwdstore/autofill/oreo/AutofillPreferences.kt b/app/src/main/java/com/zeapo/pwdstore/autofill/oreo/AutofillPreferences.kt
index 3e10933a..9c84e1ad 100644
--- a/app/src/main/java/com/zeapo/pwdstore/autofill/oreo/AutofillPreferences.kt
+++ b/app/src/main/java/com/zeapo/pwdstore/autofill/oreo/AutofillPreferences.kt
@@ -5,10 +5,8 @@
package com.zeapo.pwdstore.autofill.oreo
import android.content.Context
-import android.content.SharedPreferences
import android.os.Build
import androidx.annotation.RequiresApi
-import androidx.preference.PreferenceManager
import com.zeapo.pwdstore.utils.sharedPrefs
import java.io.File
import java.nio.file.Paths
diff --git a/app/src/main/java/com/zeapo/pwdstore/autofill/oreo/PublicSuffixListCache.kt b/app/src/main/java/com/zeapo/pwdstore/autofill/oreo/PublicSuffixListCache.kt
index 536357f5..8107248e 100644
--- a/app/src/main/java/com/zeapo/pwdstore/autofill/oreo/PublicSuffixListCache.kt
+++ b/app/src/main/java/com/zeapo/pwdstore/autofill/oreo/PublicSuffixListCache.kt
@@ -6,8 +6,8 @@ package com.zeapo.pwdstore.autofill.oreo
import android.content.Context
import android.util.Patterns
-import androidx.preference.PreferenceManager
import com.zeapo.pwdstore.utils.PreferenceKeys
+import com.zeapo.pwdstore.utils.getString
import com.zeapo.pwdstore.utils.sharedPrefs
import kotlinx.coroutines.runBlocking
import mozilla.components.lib.publicsuffixlist.PublicSuffixList
@@ -69,9 +69,10 @@ fun getSuffixPlusUpToOne(domain: String, suffix: String): String? {
}
fun getCustomSuffixes(context: Context): Sequence<String> {
- return context.sharedPrefs.getString(PreferenceKeys.OREO_AUTOFILL_CUSTOM_PUBLIC_SUFFIXES, "")!!
- .splitToSequence('\n')
- .filter { it.isNotBlank() && it.first() != '.' && it.last() != '.' }
+ return context.sharedPrefs.getString(PreferenceKeys.OREO_AUTOFILL_CUSTOM_PUBLIC_SUFFIXES)
+ ?.splitToSequence('\n')
+ ?.filter { it.isNotBlank() && it.first() != '.' && it.last() != '.' }
+ ?: emptySequence()
}
suspend fun getCanonicalSuffix(context: Context, domain: String): String {
diff --git a/app/src/main/java/com/zeapo/pwdstore/crypto/BasePgpActivity.kt b/app/src/main/java/com/zeapo/pwdstore/crypto/BasePgpActivity.kt
index fd7a8794..06f03ed9 100644
--- a/app/src/main/java/com/zeapo/pwdstore/crypto/BasePgpActivity.kt
+++ b/app/src/main/java/com/zeapo/pwdstore/crypto/BasePgpActivity.kt
@@ -30,6 +30,7 @@ import com.zeapo.pwdstore.R
import com.zeapo.pwdstore.utils.OPENPGP_PROVIDER
import com.zeapo.pwdstore.utils.PreferenceKeys
import com.zeapo.pwdstore.utils.clipboard
+import com.zeapo.pwdstore.utils.getString
import com.zeapo.pwdstore.utils.sharedPrefs
import com.zeapo.pwdstore.utils.snackbar
import java.io.File
@@ -254,8 +255,7 @@ open class BasePgpActivity : AppCompatActivity(), OpenPgpServiceConnection.OnBou
var clearAfter = 45
try {
- clearAfter = (settings.getString(PreferenceKeys.GENERAL_SHOW_TIME, "45")
- ?: "45").toInt()
+ clearAfter = (settings.getString(PreferenceKeys.GENERAL_SHOW_TIME) ?: "45").toInt()
} catch (_: NumberFormatException) {
}
diff --git a/app/src/main/java/com/zeapo/pwdstore/crypto/PasswordCreationActivity.kt b/app/src/main/java/com/zeapo/pwdstore/crypto/PasswordCreationActivity.kt
index 177e1499..e42bfef3 100644
--- a/app/src/main/java/com/zeapo/pwdstore/crypto/PasswordCreationActivity.kt
+++ b/app/src/main/java/com/zeapo/pwdstore/crypto/PasswordCreationActivity.kt
@@ -31,6 +31,7 @@ import com.zeapo.pwdstore.ui.dialogs.XkPasswordGeneratorDialogFragment
import com.zeapo.pwdstore.utils.PasswordRepository
import com.zeapo.pwdstore.utils.PreferenceKeys
import com.zeapo.pwdstore.utils.commitChange
+import com.zeapo.pwdstore.utils.getString
import com.zeapo.pwdstore.utils.isInsideRepository
import com.zeapo.pwdstore.utils.snackbar
import com.zeapo.pwdstore.utils.viewBinding
@@ -220,7 +221,7 @@ class PasswordCreationActivity : BasePgpActivity(), OpenPgpServiceConnection.OnB
}
private fun generatePassword() {
- when (settings.getString(PreferenceKeys.PREF_KEY_PWGEN_TYPE, KEY_PWGEN_TYPE_CLASSIC)) {
+ when (settings.getString(PreferenceKeys.PREF_KEY_PWGEN_TYPE) ?: KEY_PWGEN_TYPE_CLASSIC) {
KEY_PWGEN_TYPE_CLASSIC -> PasswordGeneratorDialogFragment()
.show(supportFragmentManager, "generator")
KEY_PWGEN_TYPE_XKPASSWD -> XkPasswordGeneratorDialogFragment()
diff --git a/app/src/main/java/com/zeapo/pwdstore/git/BaseGitActivity.kt b/app/src/main/java/com/zeapo/pwdstore/git/BaseGitActivity.kt
index 06f85d1b..fb0831d6 100644
--- a/app/src/main/java/com/zeapo/pwdstore/git/BaseGitActivity.kt
+++ b/app/src/main/java/com/zeapo/pwdstore/git/BaseGitActivity.kt
@@ -5,20 +5,15 @@
package com.zeapo.pwdstore.git
import android.content.Intent
-import android.content.SharedPreferences
-import android.os.Bundle
import android.view.MenuItem
import androidx.annotation.CallSuper
import androidx.appcompat.app.AppCompatActivity
-import androidx.core.content.edit
-import androidx.core.text.isDigitsOnly
import androidx.lifecycle.lifecycleScope
import com.github.ajalt.timberkt.Timber.tag
import com.github.ajalt.timberkt.e
import com.google.android.material.dialog.MaterialAlertDialogBuilder
-import com.zeapo.pwdstore.R
import com.zeapo.pwdstore.git.config.ConnectionMode
-import com.zeapo.pwdstore.git.config.Protocol
+import com.zeapo.pwdstore.git.config.GitSettings
import com.zeapo.pwdstore.git.config.SshApiSessionFactory
import com.zeapo.pwdstore.git.operation.BreakOutOfDetached
import com.zeapo.pwdstore.git.operation.CloneOperation
@@ -28,11 +23,6 @@ import com.zeapo.pwdstore.git.operation.PushOperation
import com.zeapo.pwdstore.git.operation.ResetToRemoteOperation
import com.zeapo.pwdstore.git.operation.SyncOperation
import com.zeapo.pwdstore.utils.PasswordRepository
-import com.zeapo.pwdstore.utils.PreferenceKeys
-import com.zeapo.pwdstore.utils.getEncryptedPrefs
-import com.zeapo.pwdstore.utils.sharedPrefs
-import java.io.File
-import java.net.URI
import kotlinx.coroutines.launch
/**
@@ -41,39 +31,8 @@ import kotlinx.coroutines.launch
*/
abstract class BaseGitActivity : AppCompatActivity() {
- lateinit var protocol: Protocol
- lateinit var connectionMode: ConnectionMode
- var url: String? = null
- lateinit var serverHostname: String
- lateinit var serverPort: String
- lateinit var serverUser: String
- lateinit var serverPath: String
- lateinit var username: String
- lateinit var email: String
- lateinit var branch: String
private var identityBuilder: SshApiSessionFactory.IdentityBuilder? = null
private var identity: SshApiSessionFactory.ApiIdentity? = null
- lateinit var settings: SharedPreferences
- private set
- private lateinit var encryptedSettings: SharedPreferences
-
- @CallSuper
- override fun onCreate(savedInstanceState: Bundle?) {
- super.onCreate(savedInstanceState)
-
- settings = sharedPrefs
- encryptedSettings = getEncryptedPrefs("git_operation")
- protocol = Protocol.fromString(settings.getString(PreferenceKeys.GIT_REMOTE_PROTOCOL, null))
- connectionMode = ConnectionMode.fromString(settings.getString(PreferenceKeys.GIT_REMOTE_AUTH, null))
- serverHostname = settings.getString(PreferenceKeys.GIT_REMOTE_SERVER, null) ?: ""
- serverPort = settings.getString(PreferenceKeys.GIT_REMOTE_PORT, null) ?: ""
- serverUser = settings.getString(PreferenceKeys.GIT_REMOTE_USERNAME, null) ?: ""
- serverPath = settings.getString(PreferenceKeys.GIT_REMOTE_LOCATION, null) ?: ""
- username = settings.getString(PreferenceKeys.GIT_CONFIG_USER_NAME, null) ?: ""
- email = settings.getString(PreferenceKeys.GIT_CONFIG_USER_EMAIL, null) ?: ""
- branch = settings.getString(PreferenceKeys.GIT_BRANCH_NAME, null) ?: "master"
- updateUrl()
- }
override fun onOptionsItemSelected(item: MenuItem): Boolean {
return when (item.itemId) {
@@ -95,77 +54,6 @@ abstract class BaseGitActivity : AppCompatActivity() {
super.onDestroy()
}
- enum class GitUpdateUrlResult(val textRes: Int) {
- Ok(0),
- CustomPortRequiresAbsoluteUrlError(R.string.git_config_error_custom_port_absolute),
- EmptyHostnameError(R.string.git_config_error_hostname_empty),
- GenericError(R.string.git_config_error_generic),
- NonNumericPortError(R.string.git_config_error_nonnumeric_port)
- }
-
- /**
- * Update the [url] field with the values that build it up. This function returns a
- * [GitUpdateUrlResult] indicating whether the values could be used to build a URL and only adds
- * the `origin` remote when they were. This check is not perfect, it is mostly meant to catch
- * syntax-related typos.
- */
- fun updateUrl(): GitUpdateUrlResult {
- if (serverHostname.isEmpty())
- return GitUpdateUrlResult.EmptyHostnameError
- if (!serverPort.isDigitsOnly())
- return GitUpdateUrlResult.NonNumericPortError
-
- val previousUrl = url ?: ""
- // Whether we need the leading ssh:// depends on the use of a custom port.
- val hostnamePart = serverHostname.removePrefix("ssh://")
- val newUrl = when (protocol) {
- Protocol.Ssh -> {
- val userPart = if (serverUser.isEmpty()) "" else "${serverUser.trimEnd('@')}@"
- val portPart =
- if (serverPort == "22" || serverPort.isEmpty()) "" else ":$serverPort"
- if (portPart.isEmpty()) {
- "$userPart$hostnamePart:$serverPath"
- } else {
- // Only absolute paths are supported with custom ports.
- if (!serverPath.startsWith('/'))
- return GitUpdateUrlResult.CustomPortRequiresAbsoluteUrlError
- val pathPart = serverPath
- // We have to specify the ssh scheme as this is the only way to pass a custom
- // port.
- "ssh://$userPart$hostnamePart$portPart$pathPart"
- }
- }
- Protocol.Https -> {
- val portPart =
- if (serverPort == "443" || serverPort.isEmpty()) "" else ":$serverPort"
- val pathPart = serverPath.trimStart('/', ':')
- val urlWithFreeEntryScheme = "$hostnamePart$portPart/$pathPart"
- val url = when {
- urlWithFreeEntryScheme.startsWith("https://") -> urlWithFreeEntryScheme
- urlWithFreeEntryScheme.startsWith("http://") -> urlWithFreeEntryScheme.replaceFirst("http", "https")
- else -> "https://$urlWithFreeEntryScheme"
- }
- try {
- if (URI(url).rawAuthority != null)
- url
- else
- return GitUpdateUrlResult.GenericError
- } catch (_: Exception) {
- return GitUpdateUrlResult.GenericError
- }
- }
- }
- if (PasswordRepository.isInitialized)
- PasswordRepository.addRemote("origin", newUrl, true)
- // When the server changes, remote password and host key file should be deleted.
- if (previousUrl.isNotEmpty() && newUrl != previousUrl) {
- encryptedSettings.edit { remove(PreferenceKeys.HTTPS_PASSWORD) }
- File("$filesDir/.host_key").delete()
- }
- url = newUrl
- return GitUpdateUrlResult.Ok
- }
-
/**
* Attempt to launch the requested Git operation. Depending on the configured auth, it may not
* be possible to launch the operation immediately. In that case, this function may launch an
@@ -176,7 +64,7 @@ abstract class BaseGitActivity : AppCompatActivity() {
* @param operation The type of git operation to launch
*/
suspend fun launchGitOperation(operation: Int) {
- if (url == null) {
+ if (GitSettings.url == null) {
setResult(RESULT_CANCELED)
finish()
return
@@ -185,7 +73,7 @@ abstract class BaseGitActivity : AppCompatActivity() {
// Before launching the operation with OpenKeychain auth, we need to issue several requests
// to the OpenKeychain API. IdentityBuild will take care of launching the relevant intents,
// we just need to keep calling it until it returns a completed ApiIdentity.
- if (connectionMode == ConnectionMode.OpenKeychain && identity == null) {
+ if (GitSettings.connectionMode == ConnectionMode.OpenKeychain && identity == null) {
// Lazy initialization of the IdentityBuilder
if (identityBuilder == null) {
identityBuilder = SshApiSessionFactory.IdentityBuilder(this)
@@ -199,7 +87,7 @@ abstract class BaseGitActivity : AppCompatActivity() {
val localDir = requireNotNull(PasswordRepository.getRepositoryDirectory())
val op = when (operation) {
- REQUEST_CLONE, GitOperation.GET_SSH_KEY_FROM_CLONE -> CloneOperation(localDir, url!!, this)
+ REQUEST_CLONE, GitOperation.GET_SSH_KEY_FROM_CLONE -> CloneOperation(localDir, GitSettings.url!!, this)
REQUEST_PULL -> PullOperation(localDir, this)
REQUEST_PUSH -> PushOperation(localDir, this)
REQUEST_SYNC -> SyncOperation(localDir, this)
@@ -213,7 +101,7 @@ abstract class BaseGitActivity : AppCompatActivity() {
return
}
}
- op.executeAfterAuthentication(connectionMode, serverUser, identity)
+ op.executeAfterAuthentication(GitSettings.connectionMode, identity)
} catch (e: Exception) {
e.printStackTrace()
MaterialAlertDialogBuilder(this).setMessage(e.message).show()
diff --git a/app/src/main/java/com/zeapo/pwdstore/git/GitConfigActivity.kt b/app/src/main/java/com/zeapo/pwdstore/git/GitConfigActivity.kt
index e84c87e1..5138b50b 100644
--- a/app/src/main/java/com/zeapo/pwdstore/git/GitConfigActivity.kt
+++ b/app/src/main/java/com/zeapo/pwdstore/git/GitConfigActivity.kt
@@ -7,15 +7,14 @@ package com.zeapo.pwdstore.git
import android.os.Bundle
import android.os.Handler
import android.util.Patterns
-import androidx.core.content.edit
import androidx.core.os.postDelayed
import androidx.lifecycle.lifecycleScope
import com.google.android.material.dialog.MaterialAlertDialogBuilder
import com.google.android.material.snackbar.Snackbar
import com.zeapo.pwdstore.R
import com.zeapo.pwdstore.databinding.ActivityGitConfigBinding
+import com.zeapo.pwdstore.git.config.GitSettings
import com.zeapo.pwdstore.utils.PasswordRepository
-import com.zeapo.pwdstore.utils.PreferenceKeys
import com.zeapo.pwdstore.utils.viewBinding
import kotlinx.coroutines.launch
import org.eclipse.jgit.lib.Constants
@@ -29,16 +28,16 @@ class GitConfigActivity : BaseGitActivity() {
setContentView(binding.root)
supportActionBar?.setDisplayHomeAsUpEnabled(true)
- if (username.isEmpty())
+ if (GitSettings.authorName.isEmpty())
binding.gitUserName.requestFocus()
else
- binding.gitUserName.setText(username)
- binding.gitUserEmail.setText(email)
+ binding.gitUserName.setText(GitSettings.authorName)
+ binding.gitUserEmail.setText(GitSettings.authorEmail)
val repo = PasswordRepository.getRepository(PasswordRepository.getRepositoryDirectory())
if (repo != null) {
try {
val objectId = repo.resolve(Constants.HEAD)
- val ref = repo.getRef("refs/heads/$branch")
+ val ref = repo.getRef("refs/heads/${GitSettings.branch}")
val head = if (ref.objectId.equals(objectId)) ref.name else "DETACHED"
binding.gitCommitHash.text = String.format("%s (%s)", objectId.abbreviate(8).name(), head)
@@ -60,12 +59,10 @@ class GitConfigActivity : BaseGitActivity() {
.setPositiveButton(getString(R.string.dialog_ok), null)
.show()
} else {
- settings.edit {
- putString(PreferenceKeys.GIT_CONFIG_USER_EMAIL, email)
- putString(PreferenceKeys.GIT_CONFIG_USER_NAME, name)
- }
- PasswordRepository.setUserName(name)
- PasswordRepository.setUserEmail(email)
+ GitSettings.authorEmail = email
+ GitSettings.authorName = name
+ PasswordRepository.setGitAuthorEmail(email)
+ PasswordRepository.setGitAuthorName(name)
Snackbar.make(binding.root, getString(R.string.git_server_config_save_success), Snackbar.LENGTH_SHORT).show()
Handler().postDelayed(500) { finish() }
}
diff --git a/app/src/main/java/com/zeapo/pwdstore/git/GitOperationActivity.kt b/app/src/main/java/com/zeapo/pwdstore/git/GitOperationActivity.kt
index 121a3402..eda2a8fe 100644
--- a/app/src/main/java/com/zeapo/pwdstore/git/GitOperationActivity.kt
+++ b/app/src/main/java/com/zeapo/pwdstore/git/GitOperationActivity.kt
@@ -12,6 +12,7 @@ import androidx.lifecycle.lifecycleScope
import com.google.android.material.dialog.MaterialAlertDialogBuilder
import com.zeapo.pwdstore.R
import com.zeapo.pwdstore.UserPreference
+import com.zeapo.pwdstore.git.config.GitSettings
import com.zeapo.pwdstore.utils.PasswordRepository
import kotlinx.coroutines.launch
@@ -57,7 +58,7 @@ open class GitOperationActivity : BaseGitActivity() {
* @param operation the operation to execute can be REQUEST_PULL or REQUEST_PUSH
*/
private suspend fun syncRepository(operation: Int) {
- if (serverUser.isEmpty() || serverHostname.isEmpty() || url.isNullOrEmpty())
+ if (GitSettings.url.isNullOrEmpty())
MaterialAlertDialogBuilder(this)
.setMessage(getString(R.string.set_information_dialog_text))
.setPositiveButton(getString(R.string.dialog_positive)) { _, _ ->
@@ -72,7 +73,7 @@ open class GitOperationActivity : BaseGitActivity() {
.show()
else {
// check that the remote origin is here, else add it
- PasswordRepository.addRemote("origin", url!!, true)
+ PasswordRepository.addRemote("origin", GitSettings.url!!, true)
launchGitOperation(operation)
}
}
diff --git a/app/src/main/java/com/zeapo/pwdstore/git/GitServerConfigActivity.kt b/app/src/main/java/com/zeapo/pwdstore/git/GitServerConfigActivity.kt
index 3fe0314a..4d744821 100644
--- a/app/src/main/java/com/zeapo/pwdstore/git/GitServerConfigActivity.kt
+++ b/app/src/main/java/com/zeapo/pwdstore/git/GitServerConfigActivity.kt
@@ -7,18 +7,16 @@ package com.zeapo.pwdstore.git
import android.os.Bundle
import android.os.Handler
import android.view.View
-import androidx.core.content.edit
import androidx.core.os.postDelayed
-import androidx.core.widget.doOnTextChanged
import androidx.lifecycle.lifecycleScope
import com.google.android.material.dialog.MaterialAlertDialogBuilder
import com.google.android.material.snackbar.Snackbar
import com.zeapo.pwdstore.R
import com.zeapo.pwdstore.databinding.ActivityGitCloneBinding
import com.zeapo.pwdstore.git.config.ConnectionMode
+import com.zeapo.pwdstore.git.config.GitSettings
import com.zeapo.pwdstore.git.config.Protocol
import com.zeapo.pwdstore.utils.PasswordRepository
-import com.zeapo.pwdstore.utils.PreferenceKeys
import com.zeapo.pwdstore.utils.viewBinding
import java.io.IOException
import kotlinx.coroutines.launch
@@ -40,22 +38,22 @@ class GitServerConfigActivity : BaseGitActivity() {
setContentView(binding.root)
supportActionBar?.setDisplayHomeAsUpEnabled(true)
- binding.cloneProtocolGroup.check(when (protocol) {
+ binding.cloneProtocolGroup.check(when (GitSettings.protocol) {
Protocol.Ssh -> R.id.clone_protocol_ssh
Protocol.Https -> R.id.clone_protocol_https
})
binding.cloneProtocolGroup.addOnButtonCheckedListener { _, checkedId, checked ->
if (checked) {
when (checkedId) {
- R.id.clone_protocol_https -> protocol = Protocol.Https
- R.id.clone_protocol_ssh -> protocol = Protocol.Ssh
+ R.id.clone_protocol_https -> GitSettings.protocol = Protocol.Https
+ R.id.clone_protocol_ssh -> GitSettings.protocol = Protocol.Ssh
}
updateConnectionModeToggleGroup()
}
}
binding.connectionModeGroup.apply {
- when (connectionMode) {
+ when (GitSettings.connectionMode) {
ConnectionMode.SshKey -> check(R.id.connection_mode_ssh_key)
ConnectionMode.Password -> check(R.id.connection_mode_password)
ConnectionMode.OpenKeychain -> check(R.id.connection_mode_open_keychain)
@@ -63,82 +61,37 @@ class GitServerConfigActivity : BaseGitActivity() {
}
addOnButtonCheckedListener { _, _, _ ->
when (checkedButtonId) {
- R.id.connection_mode_ssh_key -> connectionMode = ConnectionMode.SshKey
- R.id.connection_mode_open_keychain -> connectionMode = ConnectionMode.OpenKeychain
- R.id.connection_mode_password -> connectionMode = ConnectionMode.Password
- View.NO_ID -> connectionMode = ConnectionMode.None
+ R.id.connection_mode_ssh_key -> GitSettings.connectionMode = ConnectionMode.SshKey
+ R.id.connection_mode_open_keychain -> GitSettings.connectionMode = ConnectionMode.OpenKeychain
+ R.id.connection_mode_password -> GitSettings.connectionMode = ConnectionMode.Password
+ View.NO_ID -> GitSettings.connectionMode = ConnectionMode.None
}
}
}
updateConnectionModeToggleGroup()
- binding.serverUrl.apply {
- setText(serverHostname)
- doOnTextChanged { text, _, _, _ ->
- serverHostname = text.toString().trim()
- }
- }
-
- binding.serverPort.apply {
- setText(serverPort)
- doOnTextChanged { text, _, _, _ ->
- serverPort = text.toString().trim()
- }
- }
-
- binding.serverUser.apply {
- if (serverUser.isEmpty()) {
- requestFocus()
- } else {
- setText(serverUser)
- }
- doOnTextChanged { text, _, _, _ ->
- serverUser = text.toString().trim()
- }
- }
-
- binding.serverPath.apply {
- setText(serverPath)
- doOnTextChanged { text, _, _, _ ->
- serverPath = text.toString().trim()
- }
- }
-
- binding.serverBranch.apply {
- setText(branch)
- doOnTextChanged { text, _, _, _ ->
- branch = text.toString().trim()
- }
- }
+ binding.serverUrl.setText(GitSettings.url)
+ binding.serverBranch.setText(GitSettings.branch)
binding.saveButton.setOnClickListener {
if (isClone && PasswordRepository.getRepository(null) == null)
PasswordRepository.initialize()
- when (val result = updateUrl()) {
- GitUpdateUrlResult.Ok -> {
- settings.edit {
- putString(PreferenceKeys.GIT_REMOTE_PROTOCOL, protocol.pref)
- putString(PreferenceKeys.GIT_REMOTE_AUTH, connectionMode.pref)
- putString(PreferenceKeys.GIT_REMOTE_SERVER, serverHostname)
- putString(PreferenceKeys.GIT_REMOTE_PORT, serverPort)
- putString(PreferenceKeys.GIT_REMOTE_USERNAME, serverUser)
- putString(PreferenceKeys.GIT_REMOTE_LOCATION, serverPath)
- putString(PreferenceKeys.GIT_BRANCH_NAME, branch)
- }
- if (!isClone) {
- Snackbar.make(binding.root, getString(R.string.git_server_config_save_success), Snackbar.LENGTH_SHORT).show()
- Handler().postDelayed(500) { finish() }
- } else {
- cloneRepository()
- }
+ GitSettings.branch = binding.serverBranch.text.toString().trim()
+ if (GitSettings.updateUrlIfValid(binding.serverUrl.text.toString().trim())) {
+ if (!isClone) {
+ Snackbar.make(binding.root, getString(R.string.git_server_config_save_success), Snackbar.LENGTH_SHORT).show()
+ Handler().postDelayed(500) { finish() }
+ } else {
+ cloneRepository()
}
- else -> Snackbar.make(binding.root, getString(R.string.git_server_config_save_error_prefix, getString(result.textRes)), Snackbar.LENGTH_LONG).show()
+ } else {
+ Snackbar.make(binding.root, getString(R.string.git_server_config_save_error), Snackbar.LENGTH_LONG).show()
}
}
}
private fun updateConnectionModeToggleGroup() {
- if (protocol == Protocol.Ssh) {
+ if (GitSettings.protocol == Protocol.Ssh) {
// Reset connection mode to SSH key if the current value (none) is not valid for SSH
if (binding.connectionModeGroup.checkedButtonIds.isEmpty())
binding.connectionModeGroup.check(R.id.connection_mode_ssh_key)
@@ -150,7 +103,7 @@ class GitServerConfigActivity : BaseGitActivity() {
// Reset connection mode to password if the current value is not valid for HTTPS
// Important note: This has to happen before disabling the other toggle buttons or they
// won't uncheck.
- if (connectionMode !in listOf(ConnectionMode.None, ConnectionMode.Password))
+ if (GitSettings.connectionMode !in listOf(ConnectionMode.None, ConnectionMode.Password))
binding.connectionModeGroup.check(R.id.connection_mode_password)
binding.connectionModeSshKey.isEnabled = false
binding.connectionModeOpenKeychain.isEnabled = false
diff --git a/app/src/main/java/com/zeapo/pwdstore/git/config/ConnectionMode.kt b/app/src/main/java/com/zeapo/pwdstore/git/config/ConnectionMode.kt
deleted file mode 100644
index 6c4524c9..00000000
--- a/app/src/main/java/com/zeapo/pwdstore/git/config/ConnectionMode.kt
+++ /dev/null
@@ -1,22 +0,0 @@
-/*
- * Copyright © 2014-2020 The Android Password Store Authors. All Rights Reserved.
- * SPDX-License-Identifier: GPL-3.0-only
- */
-package com.zeapo.pwdstore.git.config
-
-enum class ConnectionMode(val pref: String) {
- SshKey("ssh-key"),
- Password("username/password"),
- OpenKeychain("OpenKeychain"),
- None("None"),
- ;
-
- companion object {
-
- private val map = values().associateBy(ConnectionMode::pref)
- fun fromString(type: String?): ConnectionMode {
- return map[type ?: return SshKey]
- ?: throw IllegalArgumentException("$type is not a valid ConnectionMode")
- }
- }
-}
diff --git a/app/src/main/java/com/zeapo/pwdstore/git/config/GitSettings.kt b/app/src/main/java/com/zeapo/pwdstore/git/config/GitSettings.kt
new file mode 100644
index 00000000..b81a8f8f
--- /dev/null
+++ b/app/src/main/java/com/zeapo/pwdstore/git/config/GitSettings.kt
@@ -0,0 +1,115 @@
+/*
+ * Copyright © 2014-2020 The Android Password Store Authors. All Rights Reserved.
+ * SPDX-License-Identifier: GPL-3.0-only
+ */
+package com.zeapo.pwdstore.git.config
+
+import androidx.core.content.edit
+import com.zeapo.pwdstore.Application
+import com.zeapo.pwdstore.utils.PasswordRepository
+import com.zeapo.pwdstore.utils.PreferenceKeys
+import com.zeapo.pwdstore.utils.getEncryptedPrefs
+import com.zeapo.pwdstore.utils.getString
+import com.zeapo.pwdstore.utils.sharedPrefs
+import java.io.File
+import org.eclipse.jgit.transport.URIish
+
+enum class Protocol(val pref: String) {
+ Ssh("ssh://"),
+ Https("https://"),
+ ;
+
+ companion object {
+
+ private val map = values().associateBy(Protocol::pref)
+ fun fromString(type: String?): Protocol {
+ return map[type ?: return Ssh]
+ ?: throw IllegalArgumentException("$type is not a valid Protocol")
+ }
+ }
+}
+
+enum class ConnectionMode(val pref: String) {
+ SshKey("ssh-key"),
+ Password("username/password"),
+ OpenKeychain("OpenKeychain"),
+ None("None"),
+ ;
+
+ companion object {
+
+ private val map = values().associateBy(ConnectionMode::pref)
+ fun fromString(type: String?): ConnectionMode {
+ return map[type ?: return SshKey]
+ ?: throw IllegalArgumentException("$type is not a valid ConnectionMode")
+ }
+ }
+}
+
+object GitSettings {
+
+ private const val DEFAULT_BRANCH = "master"
+
+ private val settings by lazy { Application.instance.sharedPrefs }
+ private val encryptedSettings by lazy { Application.instance.getEncryptedPrefs("git_operation") }
+
+ var protocol
+ get() = Protocol.fromString(settings.getString(PreferenceKeys.GIT_REMOTE_PROTOCOL))
+ set(value) {
+ settings.edit {
+ putString(PreferenceKeys.GIT_REMOTE_PROTOCOL, value.pref)
+ }
+ }
+ var connectionMode
+ get() = ConnectionMode.fromString(settings.getString(PreferenceKeys.GIT_REMOTE_AUTH))
+ set(value) {
+ settings.edit {
+ putString(PreferenceKeys.GIT_REMOTE_AUTH, value.pref)
+ }
+ }
+ var url
+ get() = settings.getString(PreferenceKeys.GIT_REMOTE_URL)
+ private set(value) {
+ require(value != null)
+ settings.edit {
+ putString(PreferenceKeys.GIT_REMOTE_URL, value)
+ }
+ if (PasswordRepository.isInitialized)
+ PasswordRepository.addRemote("origin", value, true)
+ // When the server changes, remote password and host key file should be deleted.
+ encryptedSettings.edit { remove(PreferenceKeys.HTTPS_PASSWORD) }
+ File("${Application.instance.filesDir}/.host_key").delete()
+ }
+ var authorName
+ get() = settings.getString(PreferenceKeys.GIT_CONFIG_AUTHOR_NAME) ?: ""
+ set(value) {
+ settings.edit {
+ putString(PreferenceKeys.GIT_CONFIG_AUTHOR_NAME, value)
+ }
+ }
+ var authorEmail
+ get() = settings.getString(PreferenceKeys.GIT_CONFIG_AUTHOR_EMAIL) ?: ""
+ set(value) {
+ settings.edit {
+ putString(PreferenceKeys.GIT_CONFIG_AUTHOR_EMAIL, value)
+ }
+ }
+ var branch
+ get() = settings.getString(PreferenceKeys.GIT_BRANCH_NAME) ?: DEFAULT_BRANCH
+ set(value) {
+ settings.edit {
+ putString(PreferenceKeys.GIT_BRANCH_NAME, value)
+ }
+ }
+
+ fun updateUrlIfValid(newUrl: String): Boolean {
+ try {
+ URIish(newUrl)
+ } catch (_: Exception) {
+ return false
+ }
+ if (newUrl != url)
+ url = newUrl
+ return true
+ }
+}
diff --git a/app/src/main/java/com/zeapo/pwdstore/git/config/Protocol.kt b/app/src/main/java/com/zeapo/pwdstore/git/config/Protocol.kt
deleted file mode 100644
index 5e172c76..00000000
--- a/app/src/main/java/com/zeapo/pwdstore/git/config/Protocol.kt
+++ /dev/null
@@ -1,20 +0,0 @@
-/*
- * Copyright © 2014-2020 The Android Password Store Authors. All Rights Reserved.
- * SPDX-License-Identifier: GPL-3.0-only
- */
-package com.zeapo.pwdstore.git.config
-
-enum class Protocol(val pref: String) {
- Ssh("ssh://"),
- Https("https://"),
- ;
-
- companion object {
-
- private val map = values().associateBy(Protocol::pref)
- fun fromString(type: String?): Protocol {
- return map[type ?: return Ssh]
- ?: throw IllegalArgumentException("$type is not a valid Protocol")
- }
- }
-}
diff --git a/app/src/main/java/com/zeapo/pwdstore/git/config/SshApiSessionFactory.java b/app/src/main/java/com/zeapo/pwdstore/git/config/SshApiSessionFactory.java
index aa62fdae..03760741 100644
--- a/app/src/main/java/com/zeapo/pwdstore/git/config/SshApiSessionFactory.java
+++ b/app/src/main/java/com/zeapo/pwdstore/git/config/SshApiSessionFactory.java
@@ -18,18 +18,12 @@ import com.jcraft.jsch.Identity;
import com.jcraft.jsch.JSch;
import com.jcraft.jsch.JSchException;
import com.jcraft.jsch.Session;
-import com.jcraft.jsch.UserInfo;
import com.zeapo.pwdstore.R;
import com.zeapo.pwdstore.git.BaseGitActivity;
import com.zeapo.pwdstore.utils.PreferenceKeys;
-import org.eclipse.jgit.errors.UnsupportedCredentialItem;
-import org.eclipse.jgit.transport.CredentialItem;
-import org.eclipse.jgit.transport.CredentialsProvider;
-import org.eclipse.jgit.transport.CredentialsProviderUserInfo;
import org.eclipse.jgit.transport.JschConfigSessionFactory;
import org.eclipse.jgit.transport.OpenSshConfig;
-import org.eclipse.jgit.transport.URIish;
import org.eclipse.jgit.util.Base64;
import org.eclipse.jgit.util.FS;
import org.openintents.ssh.authentication.ISshAuthenticationService;
@@ -52,11 +46,9 @@ public class SshApiSessionFactory extends JschConfigSessionFactory {
*/
public static final int POST_SIGNATURE = 301;
- private final String username;
private final Identity identity;
- public SshApiSessionFactory(String username, Identity identity) {
- this.username = username;
+ public SshApiSessionFactory(Identity identity) {
this.identity = identity;
}
@@ -74,32 +66,6 @@ public class SshApiSessionFactory extends JschConfigSessionFactory {
protected void configure(@NonNull OpenSshConfig.Host hc, Session session) {
session.setConfig("StrictHostKeyChecking", "no");
session.setConfig("PreferredAuthentications", "publickey");
-
- CredentialsProvider provider =
- new CredentialsProvider() {
- @Override
- public boolean isInteractive() {
- return false;
- }
-
- @Override
- public boolean supports(CredentialItem... items) {
- return true;
- }
-
- @Override
- public boolean get(URIish uri, CredentialItem... items)
- throws UnsupportedCredentialItem {
- for (CredentialItem item : items) {
- if (item instanceof CredentialItem.Username) {
- ((CredentialItem.Username) item).setValue(username);
- }
- }
- return true;
- }
- };
- UserInfo userInfo = new CredentialsProviderUserInfo(session, provider);
- session.setUserInfo(userInfo);
}
/**
diff --git a/app/src/main/java/com/zeapo/pwdstore/git/config/SshjSessionFactory.kt b/app/src/main/java/com/zeapo/pwdstore/git/config/SshjSessionFactory.kt
index c35e4a79..066f8ac6 100644
--- a/app/src/main/java/com/zeapo/pwdstore/git/config/SshjSessionFactory.kt
+++ b/app/src/main/java/com/zeapo/pwdstore/git/config/SshjSessionFactory.kt
@@ -95,10 +95,10 @@ abstract class InteractivePasswordFinder : PasswordFinder {
final override fun shouldRetry(resource: Resource<*>?) = true
}
-class SshjSessionFactory(private val username: String, private val authData: SshAuthData, private val hostKeyFile: File) : SshSessionFactory() {
+class SshjSessionFactory(private val authData: SshAuthData, private val hostKeyFile: File) : SshSessionFactory() {
override fun getSession(uri: URIish, credentialsProvider: CredentialsProvider?, fs: FS?, tms: Int): RemoteSession {
- return SshjSession(uri, username, authData, hostKeyFile).connect()
+ return SshjSession(uri, uri.user, authData, hostKeyFile).connect()
}
fun clearCredentials() {
diff --git a/app/src/main/java/com/zeapo/pwdstore/git/operation/GitOperation.kt b/app/src/main/java/com/zeapo/pwdstore/git/operation/GitOperation.kt
index 591c121f..ad8d318a 100644
--- a/app/src/main/java/com/zeapo/pwdstore/git/operation/GitOperation.kt
+++ b/app/src/main/java/com/zeapo/pwdstore/git/operation/GitOperation.kt
@@ -15,6 +15,7 @@ import com.zeapo.pwdstore.R
import com.zeapo.pwdstore.UserPreference
import com.zeapo.pwdstore.git.ErrorMessages
import com.zeapo.pwdstore.git.config.ConnectionMode
+import com.zeapo.pwdstore.git.config.GitSettings
import com.zeapo.pwdstore.git.config.InteractivePasswordFinder
import com.zeapo.pwdstore.git.config.SshApiSessionFactory
import com.zeapo.pwdstore.git.config.SshAuthData
@@ -47,18 +48,15 @@ abstract class GitOperation(gitDir: File, internal val callingActivity: Fragment
private val hostKeyFile = callingActivity.filesDir.resolve(".host_key")
protected val repository = PasswordRepository.getRepository(gitDir)
protected val git = Git(repository)
- protected val remoteBranch = PreferenceManager
- .getDefaultSharedPreferences(callingActivity.applicationContext)
- .getString(PreferenceKeys.GIT_BRANCH_NAME, "master")
+ protected val remoteBranch = GitSettings.branch
- private class PasswordFinderCredentialsProvider(private val username: String, private val passwordFinder: PasswordFinder) : CredentialsProvider() {
+ private class PasswordFinderCredentialsProvider(private val passwordFinder: PasswordFinder) : CredentialsProvider() {
override fun isInteractive() = true
override fun get(uri: URIish?, vararg items: CredentialItem): Boolean {
for (item in items) {
when (item) {
- is CredentialItem.Username -> item.value = username
is CredentialItem.Password -> item.value = passwordFinder.reqPassword(null)
else -> UnsupportedCredentialItem(uri, item.javaClass.name)
}
@@ -67,26 +65,26 @@ abstract class GitOperation(gitDir: File, internal val callingActivity: Fragment
}
override fun supports(vararg items: CredentialItem) = items.all {
- it is CredentialItem.Username || it is CredentialItem.Password
+ it is CredentialItem.Password
}
}
- private fun withPasswordAuthentication(username: String, passwordFinder: InteractivePasswordFinder): GitOperation {
- val sessionFactory = SshjSessionFactory(username, SshAuthData.Password(passwordFinder), hostKeyFile)
+ private fun withPasswordAuthentication(passwordFinder: InteractivePasswordFinder): GitOperation {
+ val sessionFactory = SshjSessionFactory(SshAuthData.Password(passwordFinder), hostKeyFile)
SshSessionFactory.setInstance(sessionFactory)
- this.provider = PasswordFinderCredentialsProvider(username, passwordFinder)
+ this.provider = PasswordFinderCredentialsProvider(passwordFinder)
return this
}
- private fun withPublicKeyAuthentication(username: String, passphraseFinder: InteractivePasswordFinder): GitOperation {
- val sessionFactory = SshjSessionFactory(username, SshAuthData.PublicKeyFile(sshKeyFile, passphraseFinder), hostKeyFile)
+ private fun withPublicKeyAuthentication(passphraseFinder: InteractivePasswordFinder): GitOperation {
+ val sessionFactory = SshjSessionFactory(SshAuthData.PublicKeyFile(sshKeyFile, passphraseFinder), hostKeyFile)
SshSessionFactory.setInstance(sessionFactory)
this.provider = null
return this
}
- private fun withOpenKeychainAuthentication(username: String, identity: SshApiSessionFactory.ApiIdentity?): GitOperation {
- SshSessionFactory.setInstance(SshApiSessionFactory(username, identity))
+ private fun withOpenKeychainAuthentication(identity: SshApiSessionFactory.ApiIdentity?): GitOperation {
+ SshSessionFactory.setInstance(SshApiSessionFactory(identity))
this.provider = null
return this
}
@@ -117,7 +115,6 @@ abstract class GitOperation(gitDir: File, internal val callingActivity: Fragment
suspend fun executeAfterAuthentication(
connectionMode: ConnectionMode,
- username: String,
identity: SshApiSessionFactory.ApiIdentity?
) {
when (connectionMode) {
@@ -136,12 +133,12 @@ abstract class GitOperation(gitDir: File, internal val callingActivity: Fragment
callingActivity.finish()
}.show()
} else {
- withPublicKeyAuthentication(username, CredentialFinder(callingActivity,
- connectionMode)).execute()
+ withPublicKeyAuthentication(
+ CredentialFinder(callingActivity, connectionMode)).execute()
}
- ConnectionMode.OpenKeychain -> withOpenKeychainAuthentication(username, identity).execute()
+ ConnectionMode.OpenKeychain -> withOpenKeychainAuthentication(identity).execute()
ConnectionMode.Password -> withPasswordAuthentication(
- username, CredentialFinder(callingActivity, connectionMode)).execute()
+ CredentialFinder(callingActivity, connectionMode)).execute()
ConnectionMode.None -> execute()
}
}
diff --git a/app/src/main/java/com/zeapo/pwdstore/pwgenxkpwd/XkpwdDictionary.kt b/app/src/main/java/com/zeapo/pwdstore/pwgenxkpwd/XkpwdDictionary.kt
index 3edaa5da..2d0fbee9 100644
--- a/app/src/main/java/com/zeapo/pwdstore/pwgenxkpwd/XkpwdDictionary.kt
+++ b/app/src/main/java/com/zeapo/pwdstore/pwgenxkpwd/XkpwdDictionary.kt
@@ -5,9 +5,9 @@
package com.zeapo.pwdstore.pwgenxkpwd
import android.content.Context
-import androidx.preference.PreferenceManager
import com.zeapo.pwdstore.R
import com.zeapo.pwdstore.utils.PreferenceKeys
+import com.zeapo.pwdstore.utils.getString
import com.zeapo.pwdstore.utils.sharedPrefs
import java.io.File
@@ -17,7 +17,7 @@ class XkpwdDictionary(context: Context) {
init {
val prefs = context.sharedPrefs
- val uri = prefs.getString(PreferenceKeys.PREF_KEY_CUSTOM_DICT, "")!!
+ val uri = prefs.getString(PreferenceKeys.PREF_KEY_CUSTOM_DICT) ?: ""
val customDictFile = File(context.filesDir, XKPWD_CUSTOM_DICT_FILE)
val lines = if (prefs.getBoolean(PreferenceKeys.PREF_KEY_IS_CUSTOM_DICT, false) &&
diff --git a/app/src/main/java/com/zeapo/pwdstore/sshkeygen/SshKeyGenActivity.kt b/app/src/main/java/com/zeapo/pwdstore/sshkeygen/SshKeyGenActivity.kt
index d4d76738..98bda9d7 100644
--- a/app/src/main/java/com/zeapo/pwdstore/sshkeygen/SshKeyGenActivity.kt
+++ b/app/src/main/java/com/zeapo/pwdstore/sshkeygen/SshKeyGenActivity.kt
@@ -12,7 +12,6 @@ import androidx.appcompat.app.AppCompatActivity
import androidx.core.content.edit
import androidx.core.content.getSystemService
import androidx.lifecycle.lifecycleScope
-import androidx.preference.PreferenceManager
import com.google.android.material.dialog.MaterialAlertDialogBuilder
import com.jcraft.jsch.JSch
import com.jcraft.jsch.KeyPair
diff --git a/app/src/main/java/com/zeapo/pwdstore/ui/adapters/PasswordItemRecyclerAdapter.kt b/app/src/main/java/com/zeapo/pwdstore/ui/adapters/PasswordItemRecyclerAdapter.kt
index 9d5487ab..dc9d0ebd 100644
--- a/app/src/main/java/com/zeapo/pwdstore/ui/adapters/PasswordItemRecyclerAdapter.kt
+++ b/app/src/main/java/com/zeapo/pwdstore/ui/adapters/PasswordItemRecyclerAdapter.kt
@@ -10,7 +10,6 @@ import android.view.MotionEvent
import android.view.View
import androidx.appcompat.widget.AppCompatImageView
import androidx.appcompat.widget.AppCompatTextView
-import androidx.preference.PreferenceManager
import androidx.recyclerview.selection.ItemDetailsLookup
import androidx.recyclerview.selection.Selection
import androidx.recyclerview.widget.RecyclerView
diff --git a/app/src/main/java/com/zeapo/pwdstore/utils/Extensions.kt b/app/src/main/java/com/zeapo/pwdstore/utils/Extensions.kt
index a3ddc170..e088097b 100644
--- a/app/src/main/java/com/zeapo/pwdstore/utils/Extensions.kt
+++ b/app/src/main/java/com/zeapo/pwdstore/utils/Extensions.kt
@@ -101,6 +101,8 @@ fun Context.getEncryptedPrefs(fileName: String): SharedPreferences {
val Context.sharedPrefs: SharedPreferences
get() = PreferenceManager.getDefaultSharedPreferences(applicationContext)
+fun SharedPreferences.getString(key: String): String? = getString(key, null)
+
suspend fun FragmentActivity.commitChange(
message: String,
finishWithResultOnEnd: Intent? = null,
diff --git a/app/src/main/java/com/zeapo/pwdstore/utils/PasswordRepository.kt b/app/src/main/java/com/zeapo/pwdstore/utils/PasswordRepository.kt
index e07f30f2..0a918d0c 100644
--- a/app/src/main/java/com/zeapo/pwdstore/utils/PasswordRepository.kt
+++ b/app/src/main/java/com/zeapo/pwdstore/utils/PasswordRepository.kt
@@ -39,8 +39,7 @@ open class PasswordRepository protected constructor() {
@JvmStatic
fun getSortOrder(settings: SharedPreferences): PasswordSortOrder {
- return valueOf(settings.getString(PreferenceKeys.SORT_ORDER, null)
- ?: FOLDER_FIRST.name)
+ return valueOf(settings.getString(PreferenceKeys.SORT_ORDER) ?: FOLDER_FIRST.name)
}
}
}
@@ -155,7 +154,7 @@ open class PasswordRepository protected constructor() {
@JvmStatic
fun getRepositoryDirectory(): File {
return if (settings.getBoolean(PreferenceKeys.GIT_EXTERNAL, false)) {
- val externalRepo = settings.getString(PreferenceKeys.GIT_EXTERNAL_REPO, null)
+ val externalRepo = settings.getString(PreferenceKeys.GIT_EXTERNAL_REPO)
if (externalRepo != null)
File(externalRepo)
else
@@ -239,7 +238,7 @@ open class PasswordRepository protected constructor() {
* @param username username
*/
@JvmStatic
- fun setUserName(username: String) {
+ fun setGitAuthorName(username: String) {
setStringConfig("user", null, "name", username)
}
@@ -249,7 +248,7 @@ open class PasswordRepository protected constructor() {
* @param email email
*/
@JvmStatic
- fun setUserEmail(email: String) {
+ fun setGitAuthorEmail(email: String) {
setStringConfig("user", null, "email", email)
}
diff --git a/app/src/main/java/com/zeapo/pwdstore/utils/PreferenceKeys.kt b/app/src/main/java/com/zeapo/pwdstore/utils/PreferenceKeys.kt
index 24bf2096..05fb9326 100644
--- a/app/src/main/java/com/zeapo/pwdstore/utils/PreferenceKeys.kt
+++ b/app/src/main/java/com/zeapo/pwdstore/utils/PreferenceKeys.kt
@@ -23,16 +23,21 @@ object PreferenceKeys {
const val FILTER_RECURSIVELY = "filter_recursively"
const val GENERAL_SHOW_TIME = "general_show_time"
const val GIT_CONFIG = "git_config"
- const val GIT_CONFIG_USER_EMAIL = "git_config_user_email"
- const val GIT_CONFIG_USER_NAME = "git_config_user_name"
+ const val GIT_CONFIG_AUTHOR_EMAIL = "git_config_user_email"
+ const val GIT_CONFIG_AUTHOR_NAME = "git_config_user_name"
const val GIT_EXTERNAL = "git_external"
const val GIT_EXTERNAL_REPO = "git_external_repo"
const val GIT_REMOTE_AUTH = "git_remote_auth"
+ @Deprecated("Use GIT_REMOTE_URL instead")
const val GIT_REMOTE_LOCATION = "git_remote_location"
+ @Deprecated("Use GIT_REMOTE_URL instead")
const val GIT_REMOTE_PORT = "git_remote_port"
const val GIT_REMOTE_PROTOCOL = "git_remote_protocol"
const val GIT_DELETE_REPO = "git_delete_repo"
+ @Deprecated("Use GIT_REMOTE_URL instead")
const val GIT_REMOTE_SERVER = "git_remote_server"
+ const val GIT_REMOTE_URL = "git_remote_url"
+ @Deprecated("Use GIT_REMOTE_URL instead")
const val GIT_REMOTE_USERNAME = "git_remote_username"
const val GIT_SERVER_INFO = "git_server_info"
const val GIT_BRANCH_NAME = "git_branch"
diff --git a/app/src/main/res/layout/activity_git_clone.xml b/app/src/main/res/layout/activity_git_clone.xml
index f9bec00a..7c59572c 100644
--- a/app/src/main/res/layout/activity_git_clone.xml
+++ b/app/src/main/res/layout/activity_git_clone.xml
@@ -66,77 +66,17 @@
</com.google.android.material.button.MaterialButtonToggleGroup>
<com.google.android.material.textfield.TextInputLayout
- android:id="@+id/server_user_layout"
- android:layout_width="0dp"
- android:layout_height="wrap_content"
- android:layout_margin="8dp"
- android:hint="@string/server_user"
- app:layout_constraintEnd_toEndOf="parent"
- app:layout_constraintStart_toStartOf="parent"
- app:layout_constraintTop_toBottomOf="@id/clone_protocol_group">
-
- <com.google.android.material.textfield.TextInputEditText
- android:id="@+id/server_user"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:imeOptions="actionNext"
- android:inputType="textWebEmailAddress"
- android:nextFocusForward="@id/server_url" />
- </com.google.android.material.textfield.TextInputLayout>
-
- <com.google.android.material.textfield.TextInputLayout
android:id="@+id/label_server_url"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_margin="8dp"
android:hint="@string/server_url"
- app:layout_constraintEnd_toStartOf="@id/label_server_port"
- app:layout_constraintStart_toStartOf="parent"
- app:layout_constraintTop_toBottomOf="@id/server_user_layout">
-
- <com.google.android.material.textfield.TextInputEditText
- android:id="@+id/server_url"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:imeOptions="actionNext"
- android:inputType="textWebEmailAddress"
- android:nextFocusForward="@id/server_port" />
-
- </com.google.android.material.textfield.TextInputLayout>
-
- <com.google.android.material.textfield.TextInputLayout
- android:id="@+id/label_server_port"
- android:layout_width="0dp"
- android:layout_height="wrap_content"
- android:layout_margin="8dp"
- android:hint="@string/server_port_hint"
- app:layout_constraintDimensionRatio="1:0.8"
- app:layout_constraintEnd_toEndOf="parent"
- app:layout_constraintStart_toEndOf="@id/label_server_url"
- app:layout_constraintTop_toBottomOf="@id/server_user_layout">
-
- <com.google.android.material.textfield.TextInputEditText
- android:id="@+id/server_port"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:imeOptions="actionNext"
- android:inputType="number"
- android:nextFocusForward="@id/server_path" />
-
- </com.google.android.material.textfield.TextInputLayout>
-
- <com.google.android.material.textfield.TextInputLayout
- android:id="@+id/label_server_path"
- android:layout_width="0dp"
- android:layout_height="wrap_content"
- android:layout_margin="8dp"
- android:hint="@string/server_path"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
- app:layout_constraintTop_toBottomOf="@id/label_server_url">
+ app:layout_constraintTop_toBottomOf="@id/clone_protocol_group">
<com.google.android.material.textfield.TextInputEditText
- android:id="@+id/server_path"
+ android:id="@+id/server_url"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:imeOptions="actionNext"
@@ -150,10 +90,10 @@
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_margin="8dp"
- android:hint="Branch"
+ android:hint="@string/server_branch"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
- app:layout_constraintTop_toBottomOf="@id/label_server_path">
+ app:layout_constraintTop_toBottomOf="@id/label_server_url">
<com.google.android.material.textfield.TextInputEditText
android:id="@+id/server_branch"
diff --git a/app/src/main/res/values-ar/strings.xml b/app/src/main/res/values-ar/strings.xml
index 643c1641..695a7499 100644
--- a/app/src/main/res/values-ar/strings.xml
+++ b/app/src/main/res/values-ar/strings.xml
@@ -29,10 +29,6 @@
<string name="initialize">إستخدام مجلد محلي</string>
<string name="server_name">الخادوم</string>
<string name="server_protocol">البروتوكول</string>
- <string name="server_url">عنوان الخادوم</string>
- <string name="server_port_hint">22</string>
- <string name="server_path">مسار المستودع</string>
- <string name="server_user">إسم المستخدم</string>
<string name="connection_mode">نوع المصادقة</string>
diff --git a/app/src/main/res/values-cs/strings.xml b/app/src/main/res/values-cs/strings.xml
index 0ed0bcea..3c4df560 100644
--- a/app/src/main/res/values-cs/strings.xml
+++ b/app/src/main/res/values-cs/strings.xml
@@ -57,10 +57,6 @@
<string name="external_repository_dialog_title">Vyberte kam ukládat hesla</string>
<string name="server_name">Server</string>
<string name="server_protocol">Protokol</string>
- <string name="server_url">URL serveru</string>
- <string name="server_port_hint">22</string>
- <string name="server_path">Cesta k repozitáři</string>
- <string name="server_user">Jméno</string>
<string name="connection_mode">Mód ověření</string>
diff --git a/app/src/main/res/values-de/strings.xml b/app/src/main/res/values-de/strings.xml
index cdfb7dba..fd94c8a9 100644
--- a/app/src/main/res/values-de/strings.xml
+++ b/app/src/main/res/values-de/strings.xml
@@ -40,10 +40,6 @@
<string name="initialize">Nutze lokalen Ordner</string>
<string name="server_name">Server</string>
<string name="server_protocol">Protokoll</string>
- <string name="server_url">Server URL</string>
- <string name="server_port_hint">22</string>
- <string name="server_path">Repo-Pfad</string>
- <string name="server_user">Nutzername</string>
<string name="connection_mode">Authentifizierungsmethode</string>
diff --git a/app/src/main/res/values-es/strings.xml b/app/src/main/res/values-es/strings.xml
index 780e83ca..ff04cf3e 100644
--- a/app/src/main/res/values-es/strings.xml
+++ b/app/src/main/res/values-es/strings.xml
@@ -54,10 +54,6 @@
<string name="server_name">Servidor</string>
<string name="server_protocol">Protocolo</string>
- <string name="server_url">URL de servidor</string>
- <string name="server_port_hint">22</string>
- <string name="server_path">Ruta del repositorio</string>
- <string name="server_user">Nombre de usuario</string>
<string name="connection_mode">Modo de autenticación</string>
diff --git a/app/src/main/res/values-fr/strings.xml b/app/src/main/res/values-fr/strings.xml
index 19fbdb33..9f9e1768 100644
--- a/app/src/main/res/values-fr/strings.xml
+++ b/app/src/main/res/values-fr/strings.xml
@@ -60,10 +60,6 @@
<string name="server_name">Serveur</string>
<string name="server_protocol">Protocole</string>
- <string name="server_url">URL du serveur</string>
- <string name="server_port_hint">22</string>
- <string name="server_path">Chemin du dépôt</string>
- <string name="server_user">Nom d\'utilisateur</string>
<string name="connection_mode">Méthode d\'authentification</string>
diff --git a/app/src/main/res/values-ja/strings.xml b/app/src/main/res/values-ja/strings.xml
index e0e84cda..132ecad4 100644
--- a/app/src/main/res/values-ja/strings.xml
+++ b/app/src/main/res/values-ja/strings.xml
@@ -41,10 +41,6 @@
<string name="initialize">ローカルディレクトリーを使用する</string>
<string name="server_name">サーバー</string>
<string name="server_protocol">プロトコル</string>
- <string name="server_url">サーバー URL</string>
- <string name="server_port_hint">22</string>
- <string name="server_path">リポジトリのパス</string>
- <string name="server_user">ユーザー名</string>
<string name="connection_mode">認証モード</string>
diff --git a/app/src/main/res/values-pt-rBR/strings.xml b/app/src/main/res/values-pt-rBR/strings.xml
index 8ed71353..79edf2d9 100644
--- a/app/src/main/res/values-pt-rBR/strings.xml
+++ b/app/src/main/res/values-pt-rBR/strings.xml
@@ -68,10 +68,6 @@
<string name="external_repository_dialog_text">Você deve selecionar um diretório onde armazenar suas senhas. Se você deseja armazenar suas senhas dentro do armazenamento oculto do aplicativo, cancele esta caixa de diálogo e desative a opção \"Repositório Externo\".</string>
<string name="server_name">Servidor</string>
<string name="server_protocol">Protocolo</string>
- <string name="server_url">URL do servidor</string>
- <string name="server_port_hint">Porta</string>
- <string name="server_path">Caminho do repositório</string>
- <string name="server_user">Usuário</string>
<string name="connection_mode">Modo de autenticação</string>
<!-- Git Config fragment -->
<string name="git_user_name_hint">Usuário</string>
@@ -295,7 +291,6 @@
<string name="connection_mode_ssh_key">Chave SSH</string>
<string name="connection_mode_basic_authentication">Senha</string>
<string name="git_server_config_save_success">Configuração salva com sucesso</string>
- <string name="git_server_config_save_error_prefix">Erro de configuração: %s</string>
<string name="git_config_error_hostname_empty">hostname vazio</string>
<string name="git_config_error_generic">por favor, verifique suas configurações e tente novamente</string>
<string name="git_config_error_nonnumeric_port">porta deve ser numérica</string>
diff --git a/app/src/main/res/values-ru/strings.xml b/app/src/main/res/values-ru/strings.xml
index 7a46da75..596e1c14 100644
--- a/app/src/main/res/values-ru/strings.xml
+++ b/app/src/main/res/values-ru/strings.xml
@@ -62,10 +62,6 @@
<string name="server_name">Сервер</string>
<string name="server_protocol">Протокол</string>
- <string name="server_url">URL сервера</string>
- <string name="server_port_hint">22</string>
- <string name="server_path">Путь к репозиторию</string>
- <string name="server_user">Имя пользователя</string>
<string name="connection_mode">Тип авторизации</string>
diff --git a/app/src/main/res/values-zh-rCN/strings.xml b/app/src/main/res/values-zh-rCN/strings.xml
index 343d5855..e7899c76 100644
--- a/app/src/main/res/values-zh-rCN/strings.xml
+++ b/app/src/main/res/values-zh-rCN/strings.xml
@@ -41,10 +41,6 @@
<string name="initialize">使用本地目录</string>
<string name="server_name">服务器</string>
<string name="server_protocol">接口</string>
- <string name="server_url">服务器 URL</string>
- <string name="server_port_hint">22</string>
- <string name="server_path">Repo 路径</string>
- <string name="server_user">用户名</string>
<string name="connection_mode">认证模式</string>
diff --git a/app/src/main/res/values-zh-rTW/strings.xml b/app/src/main/res/values-zh-rTW/strings.xml
index bbc9672a..572d67da 100644
--- a/app/src/main/res/values-zh-rTW/strings.xml
+++ b/app/src/main/res/values-zh-rTW/strings.xml
@@ -38,10 +38,6 @@
<string name="initialize">使用本機目錄</string>
<string name="server_name">伺服器</string>
<string name="server_protocol">port</string>
- <string name="server_url">伺服器 URL</string>
- <string name="server_port_hint">22</string>
- <string name="server_path">Repo 路徑</string>
- <string name="server_user">使用者名稱</string>
<string name="connection_mode">認證模式</string>
diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml
index 9251d91e..46dfa401 100644
--- a/app/src/main/res/values/strings.xml
+++ b/app/src/main/res/values/strings.xml
@@ -83,10 +83,8 @@
<string name="server_name">Server</string>
<string name="server_protocol">Protocol</string>
- <string name="server_url">Server URL</string>
- <string name="server_port_hint">Port</string>
- <string name="server_path">Repo path</string>
- <string name="server_user">Username</string>
+ <string name="server_url">Repository URL</string>
+ <string name="server_branch">Branch</string>
<string name="connection_mode">Authentication Mode</string>
@@ -326,7 +324,7 @@
<string name="connection_mode_basic_authentication">Password</string>
<string name="connection_mode_openkeychain" translatable="false">OpenKeychain</string>
<string name="git_server_config_save_success">Successfully saved configuration</string>
- <string name="git_server_config_save_error_prefix">Configuration error: %s</string>
+ <string name="git_server_config_save_error">The provided repository URL is not valid</string>
<string name="git_config_error_hostname_empty">empty hostname</string>
<string name="git_config_error_generic">please verify your settings and try again</string>
<string name="git_config_error_nonnumeric_port">port must be numeric</string>