Improve Git server config activity (#1051)
This commit is contained in:
parent
cbe780f31c
commit
d0b15cec49
6 changed files with 94 additions and 44 deletions
|
@ -9,9 +9,14 @@ All notable changes to this project will be documented in this file.
|
||||||
- Allow sorting by recently used
|
- Allow sorting by recently used
|
||||||
- Add [Bromite](https://www.bromite.org/) and [Ungoogled Chromium](https://git.droidware.info/wchen342/ungoogled-chromium-android) to supported browsers list for Autofill
|
- Add [Bromite](https://www.bromite.org/) and [Ungoogled Chromium](https://git.droidware.info/wchen342/ungoogled-chromium-android) to supported browsers list for Autofill
|
||||||
|
|
||||||
|
### Changed
|
||||||
|
|
||||||
|
- A descriptive error message is shown if no username is specified in the Git server settings
|
||||||
|
|
||||||
### Fixed
|
### Fixed
|
||||||
|
|
||||||
- Password creation UI will scroll if it does not fit on the screen
|
- Password creation UI will scroll if it does not fit on the screen
|
||||||
|
- Git server protocol and authentication mode are only updated when explicitly saved
|
||||||
|
|
||||||
## [1.11.2] - 2020-08-24
|
## [1.11.2] - 2020-08-24
|
||||||
|
|
||||||
|
|
|
@ -8,6 +8,8 @@ package com.zeapo.pwdstore
|
||||||
|
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
import androidx.core.content.edit
|
import androidx.core.content.edit
|
||||||
|
import com.zeapo.pwdstore.git.config.ConnectionMode
|
||||||
|
import com.zeapo.pwdstore.git.config.Protocol
|
||||||
import com.zeapo.pwdstore.utils.PreferenceKeys
|
import com.zeapo.pwdstore.utils.PreferenceKeys
|
||||||
import com.zeapo.pwdstore.utils.getString
|
import com.zeapo.pwdstore.utils.getString
|
||||||
import com.zeapo.pwdstore.utils.sharedPrefs
|
import com.zeapo.pwdstore.utils.sharedPrefs
|
||||||
|
@ -33,7 +35,8 @@ class MigrationsTest {
|
||||||
putString(PreferenceKeys.GIT_REMOTE_USERNAME, "msfjarvis")
|
putString(PreferenceKeys.GIT_REMOTE_USERNAME, "msfjarvis")
|
||||||
putString(PreferenceKeys.GIT_REMOTE_LOCATION, "/mnt/disk3/pass-repo")
|
putString(PreferenceKeys.GIT_REMOTE_LOCATION, "/mnt/disk3/pass-repo")
|
||||||
putString(PreferenceKeys.GIT_REMOTE_SERVER, "192.168.0.102")
|
putString(PreferenceKeys.GIT_REMOTE_SERVER, "192.168.0.102")
|
||||||
putString(PreferenceKeys.GIT_REMOTE_PROTOCOL, "ssh://")
|
putString(PreferenceKeys.GIT_REMOTE_PROTOCOL, Protocol.Ssh.pref)
|
||||||
|
putString(PreferenceKeys.GIT_REMOTE_AUTH, ConnectionMode.Password.pref)
|
||||||
}
|
}
|
||||||
runMigrations(context)
|
runMigrations(context)
|
||||||
checkOldKeysAreRemoved(context)
|
checkOldKeysAreRemoved(context)
|
||||||
|
@ -51,7 +54,8 @@ class MigrationsTest {
|
||||||
putString(PreferenceKeys.GIT_REMOTE_USERNAME, "msfjarvis")
|
putString(PreferenceKeys.GIT_REMOTE_USERNAME, "msfjarvis")
|
||||||
putString(PreferenceKeys.GIT_REMOTE_LOCATION, "/mnt/disk3/pass-repo")
|
putString(PreferenceKeys.GIT_REMOTE_LOCATION, "/mnt/disk3/pass-repo")
|
||||||
putString(PreferenceKeys.GIT_REMOTE_SERVER, "192.168.0.102")
|
putString(PreferenceKeys.GIT_REMOTE_SERVER, "192.168.0.102")
|
||||||
putString(PreferenceKeys.GIT_REMOTE_PROTOCOL, "ssh://")
|
putString(PreferenceKeys.GIT_REMOTE_PROTOCOL, Protocol.Ssh.pref)
|
||||||
|
putString(PreferenceKeys.GIT_REMOTE_AUTH, ConnectionMode.SshKey.pref)
|
||||||
}
|
}
|
||||||
runMigrations(context)
|
runMigrations(context)
|
||||||
checkOldKeysAreRemoved(context)
|
checkOldKeysAreRemoved(context)
|
||||||
|
@ -69,7 +73,8 @@ class MigrationsTest {
|
||||||
putString(PreferenceKeys.GIT_REMOTE_USERNAME, "msfjarvis")
|
putString(PreferenceKeys.GIT_REMOTE_USERNAME, "msfjarvis")
|
||||||
putString(PreferenceKeys.GIT_REMOTE_LOCATION, "Android-Password-Store/pass-test")
|
putString(PreferenceKeys.GIT_REMOTE_LOCATION, "Android-Password-Store/pass-test")
|
||||||
putString(PreferenceKeys.GIT_REMOTE_SERVER, "github.com")
|
putString(PreferenceKeys.GIT_REMOTE_SERVER, "github.com")
|
||||||
putString(PreferenceKeys.GIT_REMOTE_PROTOCOL, "https://")
|
putString(PreferenceKeys.GIT_REMOTE_PROTOCOL, Protocol.Https.pref)
|
||||||
|
putString(PreferenceKeys.GIT_REMOTE_AUTH, ConnectionMode.None.pref)
|
||||||
}
|
}
|
||||||
runMigrations(context)
|
runMigrations(context)
|
||||||
checkOldKeysAreRemoved(context)
|
checkOldKeysAreRemoved(context)
|
||||||
|
|
|
@ -76,7 +76,11 @@ private fun migrateToGitUrlBasedConfig(context: Context) {
|
||||||
remove(PreferenceKeys.GIT_REMOTE_SERVER)
|
remove(PreferenceKeys.GIT_REMOTE_SERVER)
|
||||||
remove(PreferenceKeys.GIT_REMOTE_USERNAME)
|
remove(PreferenceKeys.GIT_REMOTE_USERNAME)
|
||||||
}
|
}
|
||||||
if (url == null || !GitSettings.updateUrlIfValid(url)) {
|
if (url == null || GitSettings.updateConnectionSettingsIfValid(
|
||||||
|
newProtocol = protocol,
|
||||||
|
newConnectionMode = GitSettings.connectionMode,
|
||||||
|
newUrl = url,
|
||||||
|
newBranch = GitSettings.branch) != GitSettings.UpdateConnectionSettingsResult.Valid) {
|
||||||
e { "Failed to migrate to URL-based Git config, generated URL is invalid" }
|
e { "Failed to migrate to URL-based Git config, generated URL is invalid" }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -32,6 +32,9 @@ class GitServerConfigActivity : BaseGitActivity() {
|
||||||
|
|
||||||
private val binding by viewBinding(ActivityGitCloneBinding::inflate)
|
private val binding by viewBinding(ActivityGitCloneBinding::inflate)
|
||||||
|
|
||||||
|
private lateinit var newProtocol: Protocol
|
||||||
|
private lateinit var newConnectionMode: ConnectionMode
|
||||||
|
|
||||||
override fun onCreate(savedInstanceState: Bundle?) {
|
override fun onCreate(savedInstanceState: Bundle?) {
|
||||||
super.onCreate(savedInstanceState)
|
super.onCreate(savedInstanceState)
|
||||||
val isClone = intent?.extras?.getInt(REQUEST_ARG_OP) ?: -1 == REQUEST_CLONE
|
val isClone = intent?.extras?.getInt(REQUEST_ARG_OP) ?: -1 == REQUEST_CLONE
|
||||||
|
@ -41,22 +44,26 @@ class GitServerConfigActivity : BaseGitActivity() {
|
||||||
setContentView(binding.root)
|
setContentView(binding.root)
|
||||||
supportActionBar?.setDisplayHomeAsUpEnabled(true)
|
supportActionBar?.setDisplayHomeAsUpEnabled(true)
|
||||||
|
|
||||||
binding.cloneProtocolGroup.check(when (GitSettings.protocol) {
|
newProtocol = GitSettings.protocol
|
||||||
Protocol.Ssh -> R.id.clone_protocol_ssh
|
binding.cloneProtocolGroup.apply {
|
||||||
Protocol.Https -> R.id.clone_protocol_https
|
when (newProtocol) {
|
||||||
})
|
Protocol.Ssh -> check(R.id.clone_protocol_ssh)
|
||||||
binding.cloneProtocolGroup.addOnButtonCheckedListener { _, checkedId, checked ->
|
Protocol.Https -> check(R.id.clone_protocol_https)
|
||||||
if (checked) {
|
}
|
||||||
when (checkedId) {
|
addOnButtonCheckedListener { _, checkedId, checked ->
|
||||||
R.id.clone_protocol_https -> GitSettings.protocol = Protocol.Https
|
if (checked) {
|
||||||
R.id.clone_protocol_ssh -> GitSettings.protocol = Protocol.Ssh
|
when (checkedId) {
|
||||||
|
R.id.clone_protocol_https -> newProtocol = Protocol.Https
|
||||||
|
R.id.clone_protocol_ssh -> newProtocol = Protocol.Ssh
|
||||||
|
}
|
||||||
|
updateConnectionModeToggleGroup()
|
||||||
}
|
}
|
||||||
updateConnectionModeToggleGroup()
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
newConnectionMode = GitSettings.connectionMode
|
||||||
binding.connectionModeGroup.apply {
|
binding.connectionModeGroup.apply {
|
||||||
when (GitSettings.connectionMode) {
|
when (newConnectionMode) {
|
||||||
ConnectionMode.SshKey -> check(R.id.connection_mode_ssh_key)
|
ConnectionMode.SshKey -> check(R.id.connection_mode_ssh_key)
|
||||||
ConnectionMode.Password -> check(R.id.connection_mode_password)
|
ConnectionMode.Password -> check(R.id.connection_mode_password)
|
||||||
ConnectionMode.OpenKeychain -> check(R.id.connection_mode_open_keychain)
|
ConnectionMode.OpenKeychain -> check(R.id.connection_mode_open_keychain)
|
||||||
|
@ -64,10 +71,10 @@ class GitServerConfigActivity : BaseGitActivity() {
|
||||||
}
|
}
|
||||||
addOnButtonCheckedListener { _, _, _ ->
|
addOnButtonCheckedListener { _, _, _ ->
|
||||||
when (checkedButtonId) {
|
when (checkedButtonId) {
|
||||||
R.id.connection_mode_ssh_key -> GitSettings.connectionMode = ConnectionMode.SshKey
|
R.id.connection_mode_ssh_key -> newConnectionMode = ConnectionMode.SshKey
|
||||||
R.id.connection_mode_open_keychain -> GitSettings.connectionMode = ConnectionMode.OpenKeychain
|
R.id.connection_mode_open_keychain -> newConnectionMode = ConnectionMode.OpenKeychain
|
||||||
R.id.connection_mode_password -> GitSettings.connectionMode = ConnectionMode.Password
|
R.id.connection_mode_password -> newConnectionMode = ConnectionMode.Password
|
||||||
View.NO_ID -> GitSettings.connectionMode = ConnectionMode.None
|
View.NO_ID -> newConnectionMode = ConnectionMode.None
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -77,36 +84,50 @@ class GitServerConfigActivity : BaseGitActivity() {
|
||||||
binding.serverBranch.setText(GitSettings.branch)
|
binding.serverBranch.setText(GitSettings.branch)
|
||||||
|
|
||||||
binding.saveButton.setOnClickListener {
|
binding.saveButton.setOnClickListener {
|
||||||
if (isClone && PasswordRepository.getRepository(null) == null)
|
when (GitSettings.updateConnectionSettingsIfValid(
|
||||||
PasswordRepository.initialize()
|
newProtocol = newProtocol,
|
||||||
GitSettings.branch = binding.serverBranch.text.toString().trim()
|
newConnectionMode = newConnectionMode,
|
||||||
if (GitSettings.updateUrlIfValid(binding.serverUrl.text.toString().trim())) {
|
newUrl = binding.serverUrl.text.toString().trim(),
|
||||||
if (!isClone) {
|
newBranch = binding.serverBranch.text.toString().trim())) {
|
||||||
Snackbar.make(binding.root, getString(R.string.git_server_config_save_success), Snackbar.LENGTH_SHORT).show()
|
GitSettings.UpdateConnectionSettingsResult.FailedToParseUrl -> {
|
||||||
Handler().postDelayed(500) { finish() }
|
Snackbar.make(binding.root, getString(R.string.git_server_config_save_error), Snackbar.LENGTH_LONG).show()
|
||||||
} else {
|
}
|
||||||
cloneRepository()
|
GitSettings.UpdateConnectionSettingsResult.MissingUsername -> {
|
||||||
|
when (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 -> {
|
||||||
|
if (isClone && PasswordRepository.getRepository(null) == null)
|
||||||
|
PasswordRepository.initialize()
|
||||||
|
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), Snackbar.LENGTH_LONG).show()
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun updateConnectionModeToggleGroup() {
|
private fun updateConnectionModeToggleGroup() {
|
||||||
if (GitSettings.protocol == Protocol.Ssh) {
|
if (newProtocol == 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)
|
|
||||||
binding.connectionModeSshKey.isEnabled = true
|
binding.connectionModeSshKey.isEnabled = true
|
||||||
binding.connectionModeOpenKeychain.isEnabled = true
|
binding.connectionModeOpenKeychain.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.connectionModeGroup.checkedButtonIds.isEmpty())
|
||||||
|
binding.connectionModeGroup.check(R.id.connection_mode_ssh_key)
|
||||||
binding.connectionModeGroup.isSelectionRequired = true
|
binding.connectionModeGroup.isSelectionRequired = true
|
||||||
} else {
|
} else {
|
||||||
binding.connectionModeGroup.isSelectionRequired = false
|
binding.connectionModeGroup.isSelectionRequired = false
|
||||||
// Reset connection mode to password if the current value is not valid for HTTPS
|
// 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
|
// Important note: This has to happen before disabling the other toggle buttons or they
|
||||||
// won't uncheck.
|
// won't uncheck.
|
||||||
if (GitSettings.connectionMode !in listOf(ConnectionMode.None, ConnectionMode.Password))
|
if (newConnectionMode !in listOf(ConnectionMode.None, ConnectionMode.Password))
|
||||||
binding.connectionModeGroup.check(R.id.connection_mode_password)
|
binding.connectionModeGroup.check(R.id.connection_mode_password)
|
||||||
binding.connectionModeSshKey.isEnabled = false
|
binding.connectionModeSshKey.isEnabled = false
|
||||||
binding.connectionModeOpenKeychain.isEnabled = false
|
binding.connectionModeOpenKeychain.isEnabled = false
|
||||||
|
|
|
@ -55,14 +55,14 @@ object GitSettings {
|
||||||
|
|
||||||
var protocol
|
var protocol
|
||||||
get() = Protocol.fromString(settings.getString(PreferenceKeys.GIT_REMOTE_PROTOCOL))
|
get() = Protocol.fromString(settings.getString(PreferenceKeys.GIT_REMOTE_PROTOCOL))
|
||||||
set(value) {
|
private set(value) {
|
||||||
settings.edit {
|
settings.edit {
|
||||||
putString(PreferenceKeys.GIT_REMOTE_PROTOCOL, value.pref)
|
putString(PreferenceKeys.GIT_REMOTE_PROTOCOL, value.pref)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
var connectionMode
|
var connectionMode
|
||||||
get() = ConnectionMode.fromString(settings.getString(PreferenceKeys.GIT_REMOTE_AUTH))
|
get() = ConnectionMode.fromString(settings.getString(PreferenceKeys.GIT_REMOTE_AUTH))
|
||||||
set(value) {
|
private set(value) {
|
||||||
settings.edit {
|
settings.edit {
|
||||||
putString(PreferenceKeys.GIT_REMOTE_AUTH, value.pref)
|
putString(PreferenceKeys.GIT_REMOTE_AUTH, value.pref)
|
||||||
}
|
}
|
||||||
|
@ -71,6 +71,8 @@ object GitSettings {
|
||||||
get() = settings.getString(PreferenceKeys.GIT_REMOTE_URL)
|
get() = settings.getString(PreferenceKeys.GIT_REMOTE_URL)
|
||||||
private set(value) {
|
private set(value) {
|
||||||
require(value != null)
|
require(value != null)
|
||||||
|
if (value == url)
|
||||||
|
return
|
||||||
settings.edit {
|
settings.edit {
|
||||||
putString(PreferenceKeys.GIT_REMOTE_URL, value)
|
putString(PreferenceKeys.GIT_REMOTE_URL, value)
|
||||||
}
|
}
|
||||||
|
@ -96,20 +98,31 @@ object GitSettings {
|
||||||
}
|
}
|
||||||
var branch
|
var branch
|
||||||
get() = settings.getString(PreferenceKeys.GIT_BRANCH_NAME) ?: DEFAULT_BRANCH
|
get() = settings.getString(PreferenceKeys.GIT_BRANCH_NAME) ?: DEFAULT_BRANCH
|
||||||
set(value) {
|
private set(value) {
|
||||||
settings.edit {
|
settings.edit {
|
||||||
putString(PreferenceKeys.GIT_BRANCH_NAME, value)
|
putString(PreferenceKeys.GIT_BRANCH_NAME, value)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun updateUrlIfValid(newUrl: String): Boolean {
|
enum class UpdateConnectionSettingsResult {
|
||||||
try {
|
Valid,
|
||||||
|
FailedToParseUrl,
|
||||||
|
MissingUsername,
|
||||||
|
}
|
||||||
|
|
||||||
|
fun updateConnectionSettingsIfValid(newProtocol: Protocol, newConnectionMode: ConnectionMode, newUrl: String, newBranch: String): UpdateConnectionSettingsResult {
|
||||||
|
val parsedUrl = try {
|
||||||
URIish(newUrl)
|
URIish(newUrl)
|
||||||
} catch (_: Exception) {
|
} catch (_: Exception) {
|
||||||
return false
|
return UpdateConnectionSettingsResult.FailedToParseUrl
|
||||||
}
|
}
|
||||||
if (newUrl != url)
|
if (newConnectionMode != ConnectionMode.None && parsedUrl.user.isNullOrBlank())
|
||||||
url = newUrl
|
return UpdateConnectionSettingsResult.MissingUsername
|
||||||
return true
|
|
||||||
|
url = newUrl
|
||||||
|
protocol = newProtocol
|
||||||
|
connectionMode = newConnectionMode
|
||||||
|
branch = newBranch
|
||||||
|
return UpdateConnectionSettingsResult.Valid
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -328,6 +328,8 @@
|
||||||
<string name="connection_mode_openkeychain" translatable="false">OpenKeychain</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_success">Successfully saved configuration</string>
|
||||||
<string name="git_server_config_save_error">The provided repository URL is not valid</string>
|
<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_config_error_hostname_empty">empty hostname</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_generic">please verify your settings and try again</string>
|
||||||
<string name="git_config_error_nonnumeric_port">port must be numeric</string>
|
<string name="git_config_error_nonnumeric_port">port must be numeric</string>
|
||||||
|
|
Loading…
Reference in a new issue