aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--CHANGELOG.md1
-rw-r--r--app/src/androidTest/java/com/zeapo/pwdstore/MigrationsTest.kt1
-rw-r--r--app/src/main/java/com/zeapo/pwdstore/Migrations.kt3
-rw-r--r--app/src/main/java/com/zeapo/pwdstore/git/GitServerConfigActivity.kt59
-rw-r--r--app/src/main/java/com/zeapo/pwdstore/git/config/GitSettings.kt37
-rw-r--r--app/src/main/java/com/zeapo/pwdstore/utils/PreferenceKeys.kt1
-rw-r--r--app/src/main/res/layout/activity_git_clone.xml54
-rw-r--r--app/src/main/res/values/strings.xml1
8 files changed, 50 insertions, 107 deletions
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 52236278..c375b7ff 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -12,6 +12,7 @@ All notable changes to this project will be documented in this file.
### Changed
- A descriptive error message is shown if no username is specified in the Git server settings
+- Remove explicit protocol choice from Git server settings, it is now inferred from your URL
### Fixed
diff --git a/app/src/androidTest/java/com/zeapo/pwdstore/MigrationsTest.kt b/app/src/androidTest/java/com/zeapo/pwdstore/MigrationsTest.kt
index 531ceebf..c66bb215 100644
--- a/app/src/androidTest/java/com/zeapo/pwdstore/MigrationsTest.kt
+++ b/app/src/androidTest/java/com/zeapo/pwdstore/MigrationsTest.kt
@@ -24,6 +24,7 @@ class MigrationsTest {
assertNull(getString(PreferenceKeys.GIT_REMOTE_USERNAME))
assertNull(getString(PreferenceKeys.GIT_REMOTE_SERVER))
assertNull(getString(PreferenceKeys.GIT_REMOTE_LOCATION))
+ assertNull(getString(PreferenceKeys.GIT_REMOTE_PROTOCOL))
}
@Test
diff --git a/app/src/main/java/com/zeapo/pwdstore/Migrations.kt b/app/src/main/java/com/zeapo/pwdstore/Migrations.kt
index cdf56bb3..7148ad7e 100644
--- a/app/src/main/java/com/zeapo/pwdstore/Migrations.kt
+++ b/app/src/main/java/com/zeapo/pwdstore/Migrations.kt
@@ -75,13 +75,12 @@ private fun migrateToGitUrlBasedConfig(context: Context) {
remove(PreferenceKeys.GIT_REMOTE_PORT)
remove(PreferenceKeys.GIT_REMOTE_SERVER)
remove(PreferenceKeys.GIT_REMOTE_USERNAME)
+ remove(PreferenceKeys.GIT_REMOTE_PROTOCOL)
}
if (url == null || GitSettings.updateConnectionSettingsIfValid(
- newProtocol = protocol,
newAuthMode = GitSettings.authMode,
newUrl = url,
newBranch = GitSettings.branch) != GitSettings.UpdateConnectionSettingsResult.Valid) {
e { "Failed to migrate to URL-based Git config, generated URL is invalid" }
}
}
-
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 cd6747f7..5aa34201 100644
--- a/app/src/main/java/com/zeapo/pwdstore/git/GitServerConfigActivity.kt
+++ b/app/src/main/java/com/zeapo/pwdstore/git/GitServerConfigActivity.kt
@@ -32,7 +32,6 @@ class GitServerConfigActivity : BaseGitActivity() {
private val binding by viewBinding(ActivityGitCloneBinding::inflate)
- private lateinit var newProtocol: Protocol
private lateinit var newAuthMode: AuthMode
override fun onCreate(savedInstanceState: Bundle?) {
@@ -44,24 +43,8 @@ class GitServerConfigActivity : BaseGitActivity() {
setContentView(binding.root)
supportActionBar?.setDisplayHomeAsUpEnabled(true)
- newProtocol = GitSettings.protocol
- binding.protocolGroup.apply {
- when (newProtocol) {
- Protocol.Ssh -> check(R.id.protocol_ssh)
- Protocol.Https -> check(R.id.protocol_https)
- }
- addOnButtonCheckedListener { _, checkedId, checked ->
- if (checked) {
- when (checkedId) {
- R.id.protocol_https -> newProtocol = Protocol.Https
- R.id.protocol_ssh -> newProtocol = Protocol.Ssh
- }
- updateAuthModeToggleGroup()
- }
- }
- }
-
newAuthMode = GitSettings.authMode
+
binding.authModeGroup.apply {
when (newAuthMode) {
AuthMode.SshKey -> check(R.id.auth_mode_ssh_key)
@@ -78,27 +61,25 @@ class GitServerConfigActivity : BaseGitActivity() {
}
}
}
- updateAuthModeToggleGroup()
binding.serverUrl.setText(GitSettings.url)
binding.serverBranch.setText(GitSettings.branch)
binding.saveButton.setOnClickListener {
- when (GitSettings.updateConnectionSettingsIfValid(
- newProtocol = newProtocol,
+ when (val updateResult = GitSettings.updateConnectionSettingsIfValid(
newAuthMode = newAuthMode,
newUrl = binding.serverUrl.text.toString().trim(),
newBranch = binding.serverBranch.text.toString().trim())) {
GitSettings.UpdateConnectionSettingsResult.FailedToParseUrl -> {
Snackbar.make(binding.root, getString(R.string.git_server_config_save_error), Snackbar.LENGTH_LONG).show()
}
- GitSettings.UpdateConnectionSettingsResult.MissingUsername -> {
- when (newProtocol) {
+ is GitSettings.UpdateConnectionSettingsResult.MissingUsername -> {
+ when (updateResult.newProtocol) {
Protocol.Https -> Snackbar.make(binding.root, getString(R.string.git_server_config_save_missing_username_https), Snackbar.LENGTH_LONG).show()
Protocol.Ssh -> Snackbar.make(binding.root, getString(R.string.git_server_config_save_missing_username_ssh), Snackbar.LENGTH_LONG).show()
}
}
- else -> {
+ GitSettings.UpdateConnectionSettingsResult.Valid -> {
if (isClone && PasswordRepository.getRepository(null) == null)
PasswordRepository.initialize()
if (!isClone) {
@@ -108,32 +89,18 @@ class GitServerConfigActivity : BaseGitActivity() {
cloneRepository()
}
}
+ is GitSettings.UpdateConnectionSettingsResult.AuthModeMismatch -> {
+ val message = getString(
+ R.string.git_server_config_save_auth_mode_mismatch,
+ updateResult.newProtocol,
+ updateResult.validModes.joinToString(", "),
+ )
+ Snackbar.make(binding.root, message, Snackbar.LENGTH_LONG).show()
+ }
}
}
}
- private fun updateAuthModeToggleGroup() {
- if (newProtocol == Protocol.Ssh) {
- binding.authModeSshKey.isEnabled = true
- binding.authModeOpenKeychain.isEnabled = true
- // Reset connection mode to SSH key if the current value (none) is not valid for SSH.
- // Important note: This has to happen after enabling the other toggle buttons or they
- // won't check.
- if (binding.authModeGroup.checkedButtonIds.isEmpty())
- binding.authModeGroup.check(R.id.auth_mode_ssh_key)
- binding.authModeGroup.isSelectionRequired = true
- } else {
- binding.authModeGroup.isSelectionRequired = false
- // 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 (newAuthMode !in listOf(AuthMode.None, AuthMode.Password))
- binding.authModeGroup.check(R.id.auth_mode_password)
- binding.authModeSshKey.isEnabled = false
- binding.authModeOpenKeychain.isEnabled = false
- }
- }
-
/**
* Clones the repository, the directory exists, deletes it
*/
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
index b9c572fc..b0d931e0 100644
--- a/app/src/main/java/com/zeapo/pwdstore/git/config/GitSettings.kt
+++ b/app/src/main/java/com/zeapo/pwdstore/git/config/GitSettings.kt
@@ -53,13 +53,6 @@ object GitSettings {
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))
- private set(value) {
- settings.edit {
- putString(PreferenceKeys.GIT_REMOTE_PROTOCOL, value.pref)
- }
- }
var authMode
get() = AuthMode.fromString(settings.getString(PreferenceKeys.GIT_REMOTE_AUTH))
private set(value) {
@@ -104,23 +97,39 @@ object GitSettings {
}
}
- enum class UpdateConnectionSettingsResult {
- Valid,
- FailedToParseUrl,
- MissingUsername,
+ sealed class UpdateConnectionSettingsResult {
+ class MissingUsername(val newProtocol: Protocol) : UpdateConnectionSettingsResult()
+ class AuthModeMismatch(val newProtocol: Protocol, val validModes: List<AuthMode>) : UpdateConnectionSettingsResult()
+ object Valid : UpdateConnectionSettingsResult()
+ object FailedToParseUrl : UpdateConnectionSettingsResult()
}
- fun updateConnectionSettingsIfValid(newProtocol: Protocol, newAuthMode: AuthMode, newUrl: String, newBranch: String): UpdateConnectionSettingsResult {
+ fun updateConnectionSettingsIfValid(newAuthMode: AuthMode, newUrl: String, newBranch: String): UpdateConnectionSettingsResult {
val parsedUrl = try {
URIish(newUrl)
} catch (_: Exception) {
return UpdateConnectionSettingsResult.FailedToParseUrl
}
+ val newProtocol = when (parsedUrl.scheme) {
+ in listOf("http", "https") -> Protocol.Https
+ in listOf("ssh", null) -> Protocol.Ssh
+ else -> return UpdateConnectionSettingsResult.FailedToParseUrl
+ }
if (newAuthMode != AuthMode.None && parsedUrl.user.isNullOrBlank())
- return UpdateConnectionSettingsResult.MissingUsername
+ return UpdateConnectionSettingsResult.MissingUsername(newProtocol)
+
+ val validHttpsAuth = listOf(AuthMode.None, AuthMode.Password)
+ val validSshAuth = listOf(AuthMode.OpenKeychain, AuthMode.Password, AuthMode.SshKey)
+ when {
+ newProtocol == Protocol.Https && newAuthMode !in validHttpsAuth -> {
+ return UpdateConnectionSettingsResult.AuthModeMismatch(newProtocol, validHttpsAuth)
+ }
+ newProtocol == Protocol.Ssh && newAuthMode !in validSshAuth -> {
+ return UpdateConnectionSettingsResult.AuthModeMismatch(newProtocol, validSshAuth)
+ }
+ }
url = newUrl
- protocol = newProtocol
authMode = newAuthMode
branch = newBranch
return UpdateConnectionSettingsResult.Valid
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 05fb9326..2bb48201 100644
--- a/app/src/main/java/com/zeapo/pwdstore/utils/PreferenceKeys.kt
+++ b/app/src/main/java/com/zeapo/pwdstore/utils/PreferenceKeys.kt
@@ -32,6 +32,7 @@ object PreferenceKeys {
const val GIT_REMOTE_LOCATION = "git_remote_location"
@Deprecated("Use GIT_REMOTE_URL instead")
const val GIT_REMOTE_PORT = "git_remote_port"
+ @Deprecated("Use GIT_REMOTE_URL instead")
const val GIT_REMOTE_PROTOCOL = "git_remote_protocol"
const val GIT_DELETE_REPO = "git_delete_repo"
@Deprecated("Use GIT_REMOTE_URL instead")
diff --git a/app/src/main/res/layout/activity_git_clone.xml b/app/src/main/res/layout/activity_git_clone.xml
index f16bda94..b7ec6fc1 100644
--- a/app/src/main/res/layout/activity_git_clone.xml
+++ b/app/src/main/res/layout/activity_git_clone.xml
@@ -29,42 +29,6 @@
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
- <androidx.appcompat.widget.AppCompatTextView
- android:id="@+id/label_server_protocol"
- style="@style/TextAppearance.MaterialComponents.Headline6"
- android:layout_width="0dp"
- android:layout_height="wrap_content"
- android:layout_margin="8dp"
- android:text="@string/server_protocol"
- app:layout_constraintStart_toStartOf="parent"
- app:layout_constraintTop_toBottomOf="@id/server_label" />
-
- <com.google.android.material.button.MaterialButtonToggleGroup
- android:id="@+id/protocol_group"
- style="@style/TextAppearance.MaterialComponents.Headline1"
- android:layout_width="0dp"
- android:layout_height="wrap_content"
- android:layout_margin="8dp"
- app:layout_constraintStart_toStartOf="parent"
- app:layout_constraintTop_toBottomOf="@id/label_server_protocol"
- app:selectionRequired="true"
- app:singleSelection="true">
-
- <com.google.android.material.button.MaterialButton
- android:id="@+id/protocol_ssh"
- style="?attr/materialButtonOutlinedStyle"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:text="@string/clone_protocol_ssh" />
-
- <com.google.android.material.button.MaterialButton
- android:id="@+id/protocol_https"
- style="?attr/materialButtonOutlinedStyle"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:text="@string/clone_protocol_https" />
- </com.google.android.material.button.MaterialButtonToggleGroup>
-
<com.google.android.material.textfield.TextInputLayout
android:id="@+id/label_server_url"
android:layout_width="0dp"
@@ -73,15 +37,15 @@
android:hint="@string/server_url"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
- app:layout_constraintTop_toBottomOf="@id/protocol_group">
+ app:layout_constraintTop_toBottomOf="@id/server_label">
<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:nextFocusForward="@id/server_branch"
- android:inputType="textWebEmailAddress" />
+ android:inputType="textWebEmailAddress"
+ android:nextFocusForward="@id/server_branch" />
</com.google.android.material.textfield.TextInputLayout>
@@ -91,21 +55,21 @@
android:layout_height="wrap_content"
android:layout_margin="8dp"
android:hint="@string/server_branch"
- app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
+ app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/label_server_url">
<com.google.android.material.textfield.TextInputEditText
android:id="@+id/server_branch"
- android:imeOptions="actionDone"
android:layout_width="match_parent"
- android:inputType="textNoSuggestions"
- android:layout_height="wrap_content" />
+ android:layout_height="wrap_content"
+ android:imeOptions="actionDone"
+ android:inputType="textNoSuggestions" />
</com.google.android.material.textfield.TextInputLayout>
<androidx.appcompat.widget.AppCompatTextView
- android:id="@+id/label_connection_mode"
+ android:id="@+id/label_auth_mode"
style="@style/TextAppearance.MaterialComponents.Headline6"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
@@ -123,7 +87,7 @@
android:layout_height="wrap_content"
android:layout_margin="8dp"
app:layout_constraintStart_toStartOf="parent"
- app:layout_constraintTop_toBottomOf="@id/label_connection_mode"
+ app:layout_constraintTop_toBottomOf="@id/label_auth_mode"
app:singleSelection="true">
<com.google.android.material.button.MaterialButton
diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml
index 86e1c722..f27224ff 100644
--- a/app/src/main/res/values/strings.xml
+++ b/app/src/main/res/values/strings.xml
@@ -330,6 +330,7 @@
<string name="git_server_config_save_error">The provided repository URL is not valid</string>
<string name="git_server_config_save_missing_username_https">Please specify the HTTPS username in the form https://username@example.com/…</string>
<string name="git_server_config_save_missing_username_ssh">Please specify the SSH username in the form username@example.com:…</string>
+ <string name="git_server_config_save_auth_mode_mismatch">Valid authentication modes for %1$s: %2$s</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>