app: refactor GitSettings and ProxyUtils and inject them using hilt
Signed-off-by: Aditya Wasan <adityawasan55@gmail.com>
This commit is contained in:
parent
47099c723b
commit
c3f8de99be
13 changed files with 140 additions and 91 deletions
|
@ -16,18 +16,24 @@ import androidx.appcompat.app.AppCompatDelegate.MODE_NIGHT_YES
|
||||||
import com.github.ajalt.timberkt.Timber.DebugTree
|
import com.github.ajalt.timberkt.Timber.DebugTree
|
||||||
import com.github.ajalt.timberkt.Timber.plant
|
import com.github.ajalt.timberkt.Timber.plant
|
||||||
import dagger.hilt.android.HiltAndroidApp
|
import dagger.hilt.android.HiltAndroidApp
|
||||||
|
import dev.msfjarvis.aps.injection.context.FilesDirPath
|
||||||
|
import dev.msfjarvis.aps.injection.prefs.SettingsPreferences
|
||||||
import dev.msfjarvis.aps.util.extensions.getString
|
import dev.msfjarvis.aps.util.extensions.getString
|
||||||
import dev.msfjarvis.aps.util.extensions.sharedPrefs
|
|
||||||
import dev.msfjarvis.aps.util.git.sshj.setUpBouncyCastleForSshj
|
import dev.msfjarvis.aps.util.git.sshj.setUpBouncyCastleForSshj
|
||||||
import dev.msfjarvis.aps.util.proxy.ProxyUtils
|
import dev.msfjarvis.aps.util.proxy.ProxyUtils
|
||||||
|
import dev.msfjarvis.aps.util.settings.GitSettings
|
||||||
import dev.msfjarvis.aps.util.settings.PreferenceKeys
|
import dev.msfjarvis.aps.util.settings.PreferenceKeys
|
||||||
import dev.msfjarvis.aps.util.settings.runMigrations
|
import dev.msfjarvis.aps.util.settings.runMigrations
|
||||||
|
import javax.inject.Inject
|
||||||
|
|
||||||
@Suppress("Unused")
|
@Suppress("Unused")
|
||||||
@HiltAndroidApp
|
@HiltAndroidApp
|
||||||
class Application : android.app.Application(), SharedPreferences.OnSharedPreferenceChangeListener {
|
class Application : android.app.Application(), SharedPreferences.OnSharedPreferenceChangeListener {
|
||||||
|
|
||||||
private val prefs by lazy { sharedPrefs }
|
@Inject @SettingsPreferences lateinit var prefs: SharedPreferences
|
||||||
|
@Inject @FilesDirPath lateinit var filesDirPath: String
|
||||||
|
@Inject lateinit var proxyUtils: ProxyUtils
|
||||||
|
@Inject lateinit var gitSettings: GitSettings
|
||||||
|
|
||||||
override fun onCreate() {
|
override fun onCreate() {
|
||||||
super.onCreate()
|
super.onCreate()
|
||||||
|
@ -42,8 +48,8 @@ class Application : android.app.Application(), SharedPreferences.OnSharedPrefere
|
||||||
prefs.registerOnSharedPreferenceChangeListener(this)
|
prefs.registerOnSharedPreferenceChangeListener(this)
|
||||||
setNightMode()
|
setNightMode()
|
||||||
setUpBouncyCastleForSshj()
|
setUpBouncyCastleForSshj()
|
||||||
runMigrations(applicationContext)
|
runMigrations(filesDirPath, prefs, gitSettings)
|
||||||
ProxyUtils.setDefaultProxy()
|
proxyUtils.setDefaultProxy()
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onTerminate() {
|
override fun onTerminate() {
|
||||||
|
|
|
@ -12,6 +12,7 @@ import com.github.michaelbull.result.Result
|
||||||
import com.github.michaelbull.result.andThen
|
import com.github.michaelbull.result.andThen
|
||||||
import com.github.michaelbull.result.mapError
|
import com.github.michaelbull.result.mapError
|
||||||
import com.google.android.material.dialog.MaterialAlertDialogBuilder
|
import com.google.android.material.dialog.MaterialAlertDialogBuilder
|
||||||
|
import dagger.hilt.android.AndroidEntryPoint
|
||||||
import dev.msfjarvis.aps.R
|
import dev.msfjarvis.aps.R
|
||||||
import dev.msfjarvis.aps.util.extensions.getEncryptedGitPrefs
|
import dev.msfjarvis.aps.util.extensions.getEncryptedGitPrefs
|
||||||
import dev.msfjarvis.aps.util.extensions.sharedPrefs
|
import dev.msfjarvis.aps.util.extensions.sharedPrefs
|
||||||
|
@ -25,6 +26,7 @@ import dev.msfjarvis.aps.util.git.operation.SyncOperation
|
||||||
import dev.msfjarvis.aps.util.git.sshj.ContinuationContainerActivity
|
import dev.msfjarvis.aps.util.git.sshj.ContinuationContainerActivity
|
||||||
import dev.msfjarvis.aps.util.settings.GitSettings
|
import dev.msfjarvis.aps.util.settings.GitSettings
|
||||||
import dev.msfjarvis.aps.util.settings.PreferenceKeys
|
import dev.msfjarvis.aps.util.settings.PreferenceKeys
|
||||||
|
import javax.inject.Inject
|
||||||
import kotlinx.coroutines.Dispatchers
|
import kotlinx.coroutines.Dispatchers
|
||||||
import kotlinx.coroutines.withContext
|
import kotlinx.coroutines.withContext
|
||||||
import net.schmizz.sshj.common.DisconnectReason
|
import net.schmizz.sshj.common.DisconnectReason
|
||||||
|
@ -36,6 +38,7 @@ import net.schmizz.sshj.userauth.UserAuthException
|
||||||
* Abstract [AppCompatActivity] that holds some information that is commonly shared across
|
* Abstract [AppCompatActivity] that holds some information that is commonly shared across
|
||||||
* git-related tasks and makes sense to be held here.
|
* git-related tasks and makes sense to be held here.
|
||||||
*/
|
*/
|
||||||
|
@AndroidEntryPoint
|
||||||
abstract class BaseGitActivity : ContinuationContainerActivity() {
|
abstract class BaseGitActivity : ContinuationContainerActivity() {
|
||||||
|
|
||||||
/** Enum of possible Git operations than can be run through [launchGitOperation]. */
|
/** Enum of possible Git operations than can be run through [launchGitOperation]. */
|
||||||
|
@ -48,29 +51,31 @@ abstract class BaseGitActivity : ContinuationContainerActivity() {
|
||||||
SYNC,
|
SYNC,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Inject lateinit var gitSettings: GitSettings
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Attempt to launch the requested Git operation.
|
* Attempt to launch the requested Git operation.
|
||||||
* @param operation The type of git operation to launch
|
* @param operation The type of git operation to launch
|
||||||
*/
|
*/
|
||||||
suspend fun launchGitOperation(operation: GitOp): Result<Unit, Throwable> {
|
suspend fun launchGitOperation(operation: GitOp): Result<Unit, Throwable> {
|
||||||
if (GitSettings.url == null) {
|
if (gitSettings.url == null) {
|
||||||
return Err(IllegalStateException("Git url is not set!"))
|
return Err(IllegalStateException("Git url is not set!"))
|
||||||
}
|
}
|
||||||
if (operation == GitOp.SYNC && !GitSettings.useMultiplexing) {
|
if (operation == GitOp.SYNC && !gitSettings.useMultiplexing) {
|
||||||
// If the server does not support multiple SSH channels per connection, we cannot run
|
// If the server does not support multiple SSH channels per connection, we cannot run
|
||||||
// a sync operation without reconnecting and thus break sync into its two parts.
|
// a sync operation without reconnecting and thus break sync into its two parts.
|
||||||
return launchGitOperation(GitOp.PULL).andThen { launchGitOperation(GitOp.PUSH) }
|
return launchGitOperation(GitOp.PULL).andThen { launchGitOperation(GitOp.PUSH) }
|
||||||
}
|
}
|
||||||
val op =
|
val op =
|
||||||
when (operation) {
|
when (operation) {
|
||||||
GitOp.CLONE -> CloneOperation(this, GitSettings.url!!)
|
GitOp.CLONE -> CloneOperation(this, gitSettings.url!!)
|
||||||
GitOp.PULL -> PullOperation(this, GitSettings.rebaseOnPull)
|
GitOp.PULL -> PullOperation(this, gitSettings.rebaseOnPull)
|
||||||
GitOp.PUSH -> PushOperation(this)
|
GitOp.PUSH -> PushOperation(this)
|
||||||
GitOp.SYNC -> SyncOperation(this, GitSettings.rebaseOnPull)
|
GitOp.SYNC -> SyncOperation(this, gitSettings.rebaseOnPull)
|
||||||
GitOp.BREAK_OUT_OF_DETACHED -> BreakOutOfDetached(this)
|
GitOp.BREAK_OUT_OF_DETACHED -> BreakOutOfDetached(this)
|
||||||
GitOp.RESET -> ResetToRemoteOperation(this)
|
GitOp.RESET -> ResetToRemoteOperation(this)
|
||||||
}
|
}
|
||||||
return op.executeAfterAuthentication(GitSettings.authMode).mapError(::transformGitError)
|
return op.executeAfterAuthentication(gitSettings.authMode).mapError(::transformGitError)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun finishOnSuccessHandler(@Suppress("UNUSED_PARAMETER") nothing: Unit) {
|
fun finishOnSuccessHandler(@Suppress("UNUSED_PARAMETER") nothing: Unit) {
|
||||||
|
@ -105,7 +110,7 @@ abstract class BaseGitActivity : ContinuationContainerActivity() {
|
||||||
val err = rootCauseException(throwable)
|
val err = rootCauseException(throwable)
|
||||||
return when {
|
return when {
|
||||||
err.message?.contains("cannot open additional channels") == true -> {
|
err.message?.contains("cannot open additional channels") == true -> {
|
||||||
GitSettings.useMultiplexing = false
|
gitSettings.useMultiplexing = false
|
||||||
SSHException(
|
SSHException(
|
||||||
DisconnectReason.TOO_MANY_CONNECTIONS,
|
DisconnectReason.TOO_MANY_CONNECTIONS,
|
||||||
"The server does not support multiple Git operations per SSH session. Please try again, a slower fallback mode will be used."
|
"The server does not support multiple Git operations per SSH session. Please try again, a slower fallback mode will be used."
|
||||||
|
|
|
@ -25,7 +25,6 @@ import dev.msfjarvis.aps.databinding.ActivityGitConfigBinding
|
||||||
import dev.msfjarvis.aps.ui.git.base.BaseGitActivity
|
import dev.msfjarvis.aps.ui.git.base.BaseGitActivity
|
||||||
import dev.msfjarvis.aps.ui.git.log.GitLogActivity
|
import dev.msfjarvis.aps.ui.git.log.GitLogActivity
|
||||||
import dev.msfjarvis.aps.util.extensions.viewBinding
|
import dev.msfjarvis.aps.util.extensions.viewBinding
|
||||||
import dev.msfjarvis.aps.util.settings.GitSettings
|
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
import org.eclipse.jgit.lib.Constants
|
import org.eclipse.jgit.lib.Constants
|
||||||
import org.eclipse.jgit.lib.Repository
|
import org.eclipse.jgit.lib.Repository
|
||||||
|
@ -40,9 +39,9 @@ class GitConfigActivity : BaseGitActivity() {
|
||||||
setContentView(binding.root)
|
setContentView(binding.root)
|
||||||
supportActionBar?.setDisplayHomeAsUpEnabled(true)
|
supportActionBar?.setDisplayHomeAsUpEnabled(true)
|
||||||
|
|
||||||
if (GitSettings.authorName.isEmpty()) binding.gitUserName.requestFocus()
|
if (gitSettings.authorName.isEmpty()) binding.gitUserName.requestFocus()
|
||||||
else binding.gitUserName.setText(GitSettings.authorName)
|
else binding.gitUserName.setText(gitSettings.authorName)
|
||||||
binding.gitUserEmail.setText(GitSettings.authorEmail)
|
binding.gitUserEmail.setText(gitSettings.authorEmail)
|
||||||
setupTools()
|
setupTools()
|
||||||
binding.saveButton.setOnClickListener {
|
binding.saveButton.setOnClickListener {
|
||||||
val email = binding.gitUserEmail.text.toString().trim()
|
val email = binding.gitUserEmail.text.toString().trim()
|
||||||
|
@ -53,8 +52,8 @@ class GitConfigActivity : BaseGitActivity() {
|
||||||
.setPositiveButton(getString(R.string.dialog_ok), null)
|
.setPositiveButton(getString(R.string.dialog_ok), null)
|
||||||
.show()
|
.show()
|
||||||
} else {
|
} else {
|
||||||
GitSettings.authorEmail = email
|
gitSettings.authorEmail = email
|
||||||
GitSettings.authorName = name
|
gitSettings.authorName = name
|
||||||
Snackbar.make(
|
Snackbar.make(
|
||||||
binding.root,
|
binding.root,
|
||||||
getString(R.string.git_server_config_save_success),
|
getString(R.string.git_server_config_save_success),
|
||||||
|
@ -102,8 +101,8 @@ class GitConfigActivity : BaseGitActivity() {
|
||||||
setMessage(
|
setMessage(
|
||||||
resources.getString(
|
resources.getString(
|
||||||
R.string.git_break_out_of_detached_success,
|
R.string.git_break_out_of_detached_success,
|
||||||
GitSettings.branch,
|
gitSettings.branch,
|
||||||
"conflicting-${GitSettings.branch}-...",
|
"conflicting-${gitSettings.branch}-...",
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
setOnDismissListener { finish() }
|
setOnDismissListener { finish() }
|
||||||
|
|
|
@ -54,7 +54,7 @@ class GitServerConfigActivity : BaseGitActivity() {
|
||||||
setContentView(binding.root)
|
setContentView(binding.root)
|
||||||
supportActionBar?.setDisplayHomeAsUpEnabled(true)
|
supportActionBar?.setDisplayHomeAsUpEnabled(true)
|
||||||
|
|
||||||
newAuthMode = GitSettings.authMode
|
newAuthMode = gitSettings.authMode
|
||||||
|
|
||||||
binding.authModeGroup.apply {
|
binding.authModeGroup.apply {
|
||||||
when (newAuthMode) {
|
when (newAuthMode) {
|
||||||
|
@ -74,21 +74,21 @@ class GitServerConfigActivity : BaseGitActivity() {
|
||||||
}
|
}
|
||||||
|
|
||||||
binding.serverUrl.setText(
|
binding.serverUrl.setText(
|
||||||
GitSettings.url.also {
|
gitSettings.url.also {
|
||||||
if (it.isNullOrEmpty()) return@also
|
if (it.isNullOrEmpty()) return@also
|
||||||
setAuthModes(it.startsWith("http://") || it.startsWith("https://"))
|
setAuthModes(it.startsWith("http://") || it.startsWith("https://"))
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
binding.serverBranch.setText(GitSettings.branch)
|
binding.serverBranch.setText(gitSettings.branch)
|
||||||
|
|
||||||
binding.serverUrl.doOnTextChanged { text, _, _, _ ->
|
binding.serverUrl.doOnTextChanged { text, _, _, _ ->
|
||||||
if (text.isNullOrEmpty()) return@doOnTextChanged
|
if (text.isNullOrEmpty()) return@doOnTextChanged
|
||||||
setAuthModes(text.startsWith("http://") || text.startsWith("https://"))
|
setAuthModes(text.startsWith("http://") || text.startsWith("https://"))
|
||||||
}
|
}
|
||||||
|
|
||||||
binding.clearHostKeyButton.isVisible = GitSettings.hasSavedHostKey()
|
binding.clearHostKeyButton.isVisible = gitSettings.hasSavedHostKey()
|
||||||
binding.clearHostKeyButton.setOnClickListener {
|
binding.clearHostKeyButton.setOnClickListener {
|
||||||
GitSettings.clearSavedHostKey()
|
gitSettings.clearSavedHostKey()
|
||||||
Snackbar.make(
|
Snackbar.make(
|
||||||
binding.root,
|
binding.root,
|
||||||
getString(R.string.clear_saved_host_key_success),
|
getString(R.string.clear_saved_host_key_success),
|
||||||
|
@ -135,7 +135,7 @@ class GitServerConfigActivity : BaseGitActivity() {
|
||||||
return@setOnClickListener
|
return@setOnClickListener
|
||||||
}
|
}
|
||||||
when (val updateResult =
|
when (val updateResult =
|
||||||
GitSettings.updateConnectionSettingsIfValid(
|
gitSettings.updateConnectionSettingsIfValid(
|
||||||
newAuthMode = newAuthMode,
|
newAuthMode = newAuthMode,
|
||||||
newUrl = binding.serverUrl.text.toString().trim(),
|
newUrl = binding.serverUrl.text.toString().trim(),
|
||||||
newBranch = binding.serverBranch.text.toString().trim()
|
newBranch = binding.serverBranch.text.toString().trim()
|
||||||
|
|
|
@ -53,6 +53,7 @@ import me.zhanghai.android.fastscroll.FastScrollerBuilder
|
||||||
@AndroidEntryPoint
|
@AndroidEntryPoint
|
||||||
class PasswordFragment : Fragment(R.layout.password_recycler_view) {
|
class PasswordFragment : Fragment(R.layout.password_recycler_view) {
|
||||||
|
|
||||||
|
@Inject lateinit var gitSettings: GitSettings
|
||||||
@Inject lateinit var shortcutHandler: ShortcutHandler
|
@Inject lateinit var shortcutHandler: ShortcutHandler
|
||||||
private lateinit var recyclerAdapter: PasswordItemRecyclerAdapter
|
private lateinit var recyclerAdapter: PasswordItemRecyclerAdapter
|
||||||
private lateinit var listener: OnFragmentInteractionListener
|
private lateinit var listener: OnFragmentInteractionListener
|
||||||
|
@ -111,7 +112,7 @@ class PasswordFragment : Fragment(R.layout.password_recycler_view) {
|
||||||
// When authentication is set to AuthMode.None then the only git operation we can
|
// When authentication is set to AuthMode.None then the only git operation we can
|
||||||
// run is a pull, so automatically fallback to that.
|
// run is a pull, so automatically fallback to that.
|
||||||
val operationId =
|
val operationId =
|
||||||
when (GitSettings.authMode) {
|
when (gitSettings.authMode) {
|
||||||
AuthMode.None -> BaseGitActivity.GitOp.PULL
|
AuthMode.None -> BaseGitActivity.GitOp.PULL
|
||||||
else -> BaseGitActivity.GitOp.SYNC
|
else -> BaseGitActivity.GitOp.SYNC
|
||||||
}
|
}
|
||||||
|
|
|
@ -243,7 +243,7 @@ class PasswordStore : BaseGitActivity() {
|
||||||
override fun onCreateOptionsMenu(menu: Menu?): Boolean {
|
override fun onCreateOptionsMenu(menu: Menu?): Boolean {
|
||||||
val menuRes =
|
val menuRes =
|
||||||
when {
|
when {
|
||||||
GitSettings.authMode == AuthMode.None -> R.menu.main_menu_no_auth
|
gitSettings.authMode == AuthMode.None -> R.menu.main_menu_no_auth
|
||||||
PasswordRepository.isGitRepo() -> R.menu.main_menu_git
|
PasswordRepository.isGitRepo() -> R.menu.main_menu_git
|
||||||
else -> R.menu.main_menu_non_git
|
else -> R.menu.main_menu_non_git
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,6 +13,7 @@ import androidx.appcompat.app.AppCompatActivity
|
||||||
import androidx.core.content.edit
|
import androidx.core.content.edit
|
||||||
import androidx.core.os.postDelayed
|
import androidx.core.os.postDelayed
|
||||||
import androidx.core.widget.doOnTextChanged
|
import androidx.core.widget.doOnTextChanged
|
||||||
|
import dagger.hilt.android.AndroidEntryPoint
|
||||||
import dev.msfjarvis.aps.R
|
import dev.msfjarvis.aps.R
|
||||||
import dev.msfjarvis.aps.databinding.ActivityProxySelectorBinding
|
import dev.msfjarvis.aps.databinding.ActivityProxySelectorBinding
|
||||||
import dev.msfjarvis.aps.util.extensions.getEncryptedProxyPrefs
|
import dev.msfjarvis.aps.util.extensions.getEncryptedProxyPrefs
|
||||||
|
@ -21,12 +22,17 @@ import dev.msfjarvis.aps.util.extensions.viewBinding
|
||||||
import dev.msfjarvis.aps.util.proxy.ProxyUtils
|
import dev.msfjarvis.aps.util.proxy.ProxyUtils
|
||||||
import dev.msfjarvis.aps.util.settings.GitSettings
|
import dev.msfjarvis.aps.util.settings.GitSettings
|
||||||
import dev.msfjarvis.aps.util.settings.PreferenceKeys
|
import dev.msfjarvis.aps.util.settings.PreferenceKeys
|
||||||
|
import javax.inject.Inject
|
||||||
|
|
||||||
private val IP_ADDRESS_REGEX = Patterns.IP_ADDRESS.toRegex()
|
private val IP_ADDRESS_REGEX = Patterns.IP_ADDRESS.toRegex()
|
||||||
private val WEB_ADDRESS_REGEX = Patterns.WEB_URL.toRegex()
|
private val WEB_ADDRESS_REGEX = Patterns.WEB_URL.toRegex()
|
||||||
|
|
||||||
|
@AndroidEntryPoint
|
||||||
class ProxySelectorActivity : AppCompatActivity() {
|
class ProxySelectorActivity : AppCompatActivity() {
|
||||||
|
|
||||||
|
@Inject lateinit var gitSettings: GitSettings
|
||||||
|
@Inject lateinit var proxyUtils: ProxyUtils
|
||||||
|
|
||||||
private val binding by viewBinding(ActivityProxySelectorBinding::inflate)
|
private val binding by viewBinding(ActivityProxySelectorBinding::inflate)
|
||||||
private val proxyPrefs by lazy(LazyThreadSafetyMode.NONE) {
|
private val proxyPrefs by lazy(LazyThreadSafetyMode.NONE) {
|
||||||
applicationContext.getEncryptedProxyPrefs()
|
applicationContext.getEncryptedProxyPrefs()
|
||||||
|
@ -59,19 +65,19 @@ class ProxySelectorActivity : AppCompatActivity() {
|
||||||
private fun saveSettings() {
|
private fun saveSettings() {
|
||||||
proxyPrefs.edit {
|
proxyPrefs.edit {
|
||||||
binding.proxyHost.text?.toString()?.takeIf { it.isNotEmpty() }.let {
|
binding.proxyHost.text?.toString()?.takeIf { it.isNotEmpty() }.let {
|
||||||
GitSettings.proxyHost = it
|
gitSettings.proxyHost = it
|
||||||
}
|
}
|
||||||
binding.proxyUser.text?.toString()?.takeIf { it.isNotEmpty() }.let {
|
binding.proxyUser.text?.toString()?.takeIf { it.isNotEmpty() }.let {
|
||||||
GitSettings.proxyUsername = it
|
gitSettings.proxyUsername = it
|
||||||
}
|
}
|
||||||
binding.proxyPort.text?.toString()?.takeIf { it.isNotEmpty() }?.let {
|
binding.proxyPort.text?.toString()?.takeIf { it.isNotEmpty() }?.let {
|
||||||
GitSettings.proxyPort = it.toInt()
|
gitSettings.proxyPort = it.toInt()
|
||||||
}
|
}
|
||||||
binding.proxyPassword.text?.toString()?.takeIf { it.isNotEmpty() }.let {
|
binding.proxyPassword.text?.toString()?.takeIf { it.isNotEmpty() }.let {
|
||||||
GitSettings.proxyPassword = it
|
gitSettings.proxyPassword = it
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ProxyUtils.setDefaultProxy()
|
proxyUtils.setDefaultProxy()
|
||||||
Handler(Looper.getMainLooper()).postDelayed(500) { finish() }
|
Handler(Looper.getMainLooper()).postDelayed(500) { finish() }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,6 +6,7 @@
|
||||||
package dev.msfjarvis.aps.ui.settings
|
package dev.msfjarvis.aps.ui.settings
|
||||||
|
|
||||||
import android.content.Intent
|
import android.content.Intent
|
||||||
|
import android.content.SharedPreferences
|
||||||
import android.content.pm.ShortcutManager
|
import android.content.pm.ShortcutManager
|
||||||
import android.os.Build
|
import android.os.Build
|
||||||
import androidx.core.content.edit
|
import androidx.core.content.edit
|
||||||
|
@ -14,6 +15,10 @@ import androidx.fragment.app.FragmentActivity
|
||||||
import com.github.michaelbull.result.onFailure
|
import com.github.michaelbull.result.onFailure
|
||||||
import com.github.michaelbull.result.runCatching
|
import com.github.michaelbull.result.runCatching
|
||||||
import com.google.android.material.dialog.MaterialAlertDialogBuilder
|
import com.google.android.material.dialog.MaterialAlertDialogBuilder
|
||||||
|
import dagger.hilt.EntryPoint
|
||||||
|
import dagger.hilt.InstallIn
|
||||||
|
import dagger.hilt.android.EntryPointAccessors
|
||||||
|
import dagger.hilt.components.SingletonComponent
|
||||||
import de.Maxr1998.modernpreferences.Preference
|
import de.Maxr1998.modernpreferences.Preference
|
||||||
import de.Maxr1998.modernpreferences.PreferenceScreen
|
import de.Maxr1998.modernpreferences.PreferenceScreen
|
||||||
import de.Maxr1998.modernpreferences.helpers.checkBox
|
import de.Maxr1998.modernpreferences.helpers.checkBox
|
||||||
|
@ -22,13 +27,13 @@ import de.Maxr1998.modernpreferences.helpers.onClick
|
||||||
import de.Maxr1998.modernpreferences.helpers.pref
|
import de.Maxr1998.modernpreferences.helpers.pref
|
||||||
import dev.msfjarvis.aps.R
|
import dev.msfjarvis.aps.R
|
||||||
import dev.msfjarvis.aps.data.repo.PasswordRepository
|
import dev.msfjarvis.aps.data.repo.PasswordRepository
|
||||||
|
import dev.msfjarvis.aps.injection.prefs.GitPreferences
|
||||||
import dev.msfjarvis.aps.ui.git.config.GitConfigActivity
|
import dev.msfjarvis.aps.ui.git.config.GitConfigActivity
|
||||||
import dev.msfjarvis.aps.ui.git.config.GitServerConfigActivity
|
import dev.msfjarvis.aps.ui.git.config.GitServerConfigActivity
|
||||||
import dev.msfjarvis.aps.ui.proxy.ProxySelectorActivity
|
import dev.msfjarvis.aps.ui.proxy.ProxySelectorActivity
|
||||||
import dev.msfjarvis.aps.ui.sshkeygen.ShowSshKeyFragment
|
import dev.msfjarvis.aps.ui.sshkeygen.ShowSshKeyFragment
|
||||||
import dev.msfjarvis.aps.ui.sshkeygen.SshKeyGenActivity
|
import dev.msfjarvis.aps.ui.sshkeygen.SshKeyGenActivity
|
||||||
import dev.msfjarvis.aps.ui.sshkeygen.SshKeyImportActivity
|
import dev.msfjarvis.aps.ui.sshkeygen.SshKeyImportActivity
|
||||||
import dev.msfjarvis.aps.util.extensions.getEncryptedGitPrefs
|
|
||||||
import dev.msfjarvis.aps.util.extensions.getString
|
import dev.msfjarvis.aps.util.extensions.getString
|
||||||
import dev.msfjarvis.aps.util.extensions.sharedPrefs
|
import dev.msfjarvis.aps.util.extensions.sharedPrefs
|
||||||
import dev.msfjarvis.aps.util.extensions.snackbar
|
import dev.msfjarvis.aps.util.extensions.snackbar
|
||||||
|
@ -37,9 +42,10 @@ import dev.msfjarvis.aps.util.settings.PreferenceKeys
|
||||||
|
|
||||||
class RepositorySettings(private val activity: FragmentActivity) : SettingsProvider {
|
class RepositorySettings(private val activity: FragmentActivity) : SettingsProvider {
|
||||||
|
|
||||||
private val encryptedPreferences by lazy(LazyThreadSafetyMode.NONE) {
|
private val hiltEntryPoint = EntryPointAccessors.fromApplication(activity.applicationContext, RepositorySettingsEntryPoint::class.java)
|
||||||
activity.getEncryptedGitPrefs()
|
private val encryptedPreferences = hiltEntryPoint.encryptedPreferences()
|
||||||
}
|
private val gitSettings = hiltEntryPoint.gitSettings()
|
||||||
|
|
||||||
|
|
||||||
private fun <T : FragmentActivity> launchActivity(clazz: Class<T>) {
|
private fun <T : FragmentActivity> launchActivity(clazz: Class<T>) {
|
||||||
activity.startActivity(Intent(activity, clazz))
|
activity.startActivity(Intent(activity, clazz))
|
||||||
|
@ -74,7 +80,7 @@ class RepositorySettings(private val activity: FragmentActivity) : SettingsProvi
|
||||||
}
|
}
|
||||||
pref(PreferenceKeys.PROXY_SETTINGS) {
|
pref(PreferenceKeys.PROXY_SETTINGS) {
|
||||||
titleRes = R.string.pref_edit_proxy_settings
|
titleRes = R.string.pref_edit_proxy_settings
|
||||||
visible = GitSettings.url?.startsWith("https") == true && PasswordRepository.isGitRepo()
|
visible = gitSettings.url?.startsWith("https") == true && PasswordRepository.isGitRepo()
|
||||||
onClick {
|
onClick {
|
||||||
launchActivity(ProxySelectorActivity::class.java)
|
launchActivity(ProxySelectorActivity::class.java)
|
||||||
true
|
true
|
||||||
|
@ -206,4 +212,11 @@ class RepositorySettings(private val activity: FragmentActivity) : SettingsProvi
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@EntryPoint
|
||||||
|
@InstallIn(SingletonComponent::class)
|
||||||
|
interface RepositorySettingsEntryPoint {
|
||||||
|
fun gitSettings(): GitSettings
|
||||||
|
@GitPreferences fun encryptedPreferences(): SharedPreferences
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,6 +10,10 @@ import androidx.fragment.app.FragmentActivity
|
||||||
import com.github.michaelbull.result.Result
|
import com.github.michaelbull.result.Result
|
||||||
import com.github.michaelbull.result.runCatching
|
import com.github.michaelbull.result.runCatching
|
||||||
import com.google.android.material.snackbar.Snackbar
|
import com.google.android.material.snackbar.Snackbar
|
||||||
|
import dagger.hilt.EntryPoint
|
||||||
|
import dagger.hilt.InstallIn
|
||||||
|
import dagger.hilt.android.EntryPointAccessors
|
||||||
|
import dagger.hilt.components.SingletonComponent
|
||||||
import dev.msfjarvis.aps.R
|
import dev.msfjarvis.aps.R
|
||||||
import dev.msfjarvis.aps.util.extensions.snackbar
|
import dev.msfjarvis.aps.util.extensions.snackbar
|
||||||
import dev.msfjarvis.aps.util.git.GitException.PullException
|
import dev.msfjarvis.aps.util.git.GitException.PullException
|
||||||
|
@ -30,6 +34,9 @@ class GitCommandExecutor(
|
||||||
private val operation: GitOperation,
|
private val operation: GitOperation,
|
||||||
) {
|
) {
|
||||||
|
|
||||||
|
private val hiltEntryPoint = EntryPointAccessors.fromApplication(activity.applicationContext, GitCommandExecutorEntryPoint::class.java)
|
||||||
|
private val gitSettings = hiltEntryPoint.gitSettings()
|
||||||
|
|
||||||
suspend fun execute(): Result<Unit, Throwable> {
|
suspend fun execute(): Result<Unit, Throwable> {
|
||||||
val snackbar =
|
val snackbar =
|
||||||
activity.snackbar(
|
activity.snackbar(
|
||||||
|
@ -49,8 +56,8 @@ class GitCommandExecutor(
|
||||||
// the previous status will eventually be used to avoid a commit
|
// the previous status will eventually be used to avoid a commit
|
||||||
if (nbChanges > 0) {
|
if (nbChanges > 0) {
|
||||||
withContext(Dispatchers.IO) {
|
withContext(Dispatchers.IO) {
|
||||||
val name = GitSettings.authorName.ifEmpty { "root" }
|
val name = gitSettings.authorName.ifEmpty { "root" }
|
||||||
val email = GitSettings.authorEmail.ifEmpty { "localhost" }
|
val email = gitSettings.authorEmail.ifEmpty { "localhost" }
|
||||||
val identity = PersonIdent(name, email)
|
val identity = PersonIdent(name, email)
|
||||||
command.setAuthor(identity).setCommitter(identity).call()
|
command.setAuthor(identity).setCommitter(identity).call()
|
||||||
}
|
}
|
||||||
|
@ -111,4 +118,10 @@ class GitCommandExecutor(
|
||||||
}
|
}
|
||||||
.also { snackbar.dismiss() }
|
.also { snackbar.dismiss() }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@EntryPoint
|
||||||
|
@InstallIn(SingletonComponent::class)
|
||||||
|
interface GitCommandExecutorEntryPoint {
|
||||||
|
fun gitSettings(): GitSettings
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,6 +14,11 @@ import com.github.michaelbull.result.Result
|
||||||
import com.github.michaelbull.result.onFailure
|
import com.github.michaelbull.result.onFailure
|
||||||
import com.github.michaelbull.result.runCatching
|
import com.github.michaelbull.result.runCatching
|
||||||
import com.google.android.material.dialog.MaterialAlertDialogBuilder
|
import com.google.android.material.dialog.MaterialAlertDialogBuilder
|
||||||
|
import dagger.hilt.EntryPoint
|
||||||
|
import dagger.hilt.InstallIn
|
||||||
|
import dagger.hilt.android.AndroidEntryPoint
|
||||||
|
import dagger.hilt.android.EntryPointAccessors
|
||||||
|
import dagger.hilt.components.SingletonComponent
|
||||||
import dev.msfjarvis.aps.R
|
import dev.msfjarvis.aps.R
|
||||||
import dev.msfjarvis.aps.data.repo.PasswordRepository
|
import dev.msfjarvis.aps.data.repo.PasswordRepository
|
||||||
import dev.msfjarvis.aps.ui.sshkeygen.SshKeyGenActivity
|
import dev.msfjarvis.aps.ui.sshkeygen.SshKeyGenActivity
|
||||||
|
@ -26,6 +31,8 @@ import dev.msfjarvis.aps.util.git.sshj.SshKey
|
||||||
import dev.msfjarvis.aps.util.git.sshj.SshjSessionFactory
|
import dev.msfjarvis.aps.util.git.sshj.SshjSessionFactory
|
||||||
import dev.msfjarvis.aps.util.settings.AuthMode
|
import dev.msfjarvis.aps.util.settings.AuthMode
|
||||||
import dev.msfjarvis.aps.util.settings.GitSettings
|
import dev.msfjarvis.aps.util.settings.GitSettings
|
||||||
|
import javax.inject.Inject
|
||||||
|
import javax.inject.Singleton
|
||||||
import kotlin.coroutines.resume
|
import kotlin.coroutines.resume
|
||||||
import kotlin.coroutines.suspendCoroutine
|
import kotlin.coroutines.suspendCoroutine
|
||||||
import kotlinx.coroutines.Dispatchers
|
import kotlinx.coroutines.Dispatchers
|
||||||
|
@ -53,10 +60,11 @@ abstract class GitOperation(protected val callingActivity: FragmentActivity) {
|
||||||
abstract val commands: Array<GitCommand<out Any>>
|
abstract val commands: Array<GitCommand<out Any>>
|
||||||
private val hostKeyFile = callingActivity.filesDir.resolve(".host_key")
|
private val hostKeyFile = callingActivity.filesDir.resolve(".host_key")
|
||||||
private var sshSessionFactory: SshjSessionFactory? = null
|
private var sshSessionFactory: SshjSessionFactory? = null
|
||||||
|
private val hiltEntryPoint = EntryPointAccessors.fromApplication(callingActivity.applicationContext, GitOperationEntryPoint::class.java)
|
||||||
|
|
||||||
protected val repository = PasswordRepository.getRepository(null)!!
|
protected val repository = PasswordRepository.getRepository(null)!!
|
||||||
protected val git = Git(repository)
|
protected val git = Git(repository)
|
||||||
protected val remoteBranch = GitSettings.branch
|
protected val remoteBranch = hiltEntryPoint.gitSettings().branch
|
||||||
private val authActivity
|
private val authActivity
|
||||||
get() = callingActivity as ContinuationContainerActivity
|
get() = callingActivity as ContinuationContainerActivity
|
||||||
|
|
||||||
|
@ -220,4 +228,11 @@ abstract class GitOperation(protected val callingActivity: FragmentActivity) {
|
||||||
/** Timeout in seconds before [TransportCommand] will abort a stalled IO operation. */
|
/** Timeout in seconds before [TransportCommand] will abort a stalled IO operation. */
|
||||||
private const val CONNECT_TIMEOUT = 10
|
private const val CONNECT_TIMEOUT = 10
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Using @EntryPoint seems to be our best option here, changing this to constructor injection would require a larger refactor.
|
||||||
|
@EntryPoint
|
||||||
|
@InstallIn(SingletonComponent::class)
|
||||||
|
interface GitOperationEntryPoint {
|
||||||
|
fun gitSettings(): GitSettings
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,20 +14,20 @@ import java.net.Proxy
|
||||||
import java.net.ProxySelector
|
import java.net.ProxySelector
|
||||||
import java.net.SocketAddress
|
import java.net.SocketAddress
|
||||||
import java.net.URI
|
import java.net.URI
|
||||||
|
import javax.inject.Inject
|
||||||
|
import javax.inject.Singleton
|
||||||
|
|
||||||
/** Utility class for [Proxy] handling. */
|
/** Utility class for [Proxy] handling. */
|
||||||
object ProxyUtils {
|
@Singleton
|
||||||
|
class ProxyUtils @Inject constructor(private val gitSettings: GitSettings) {
|
||||||
private const val HTTP_PROXY_USER_PROPERTY = "http.proxyUser"
|
|
||||||
private const val HTTP_PROXY_PASSWORD_PROPERTY = "http.proxyPassword"
|
|
||||||
|
|
||||||
/** Set the default [Proxy] and [Authenticator] for the app based on user provided settings. */
|
/** Set the default [Proxy] and [Authenticator] for the app based on user provided settings. */
|
||||||
fun setDefaultProxy() {
|
fun setDefaultProxy() {
|
||||||
ProxySelector.setDefault(
|
ProxySelector.setDefault(
|
||||||
object : ProxySelector() {
|
object : ProxySelector() {
|
||||||
override fun select(uri: URI?): MutableList<Proxy> {
|
override fun select(uri: URI?): MutableList<Proxy> {
|
||||||
val host = GitSettings.proxyHost
|
val host = gitSettings.proxyHost
|
||||||
val port = GitSettings.proxyPort
|
val port = gitSettings.proxyPort
|
||||||
return if (host == null || port == -1) {
|
return if (host == null || port == -1) {
|
||||||
mutableListOf(Proxy.NO_PROXY)
|
mutableListOf(Proxy.NO_PROXY)
|
||||||
} else {
|
} else {
|
||||||
|
@ -42,8 +42,8 @@ object ProxyUtils {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
val user = GitSettings.proxyUsername ?: ""
|
val user = gitSettings.proxyUsername ?: ""
|
||||||
val password = GitSettings.proxyPassword ?: ""
|
val password = gitSettings.proxyPassword ?: ""
|
||||||
if (user.isEmpty() || password.isEmpty()) {
|
if (user.isEmpty() || password.isEmpty()) {
|
||||||
System.clearProperty(HTTP_PROXY_USER_PROPERTY)
|
System.clearProperty(HTTP_PROXY_USER_PROPERTY)
|
||||||
System.clearProperty(HTTP_PROXY_PASSWORD_PROPERTY)
|
System.clearProperty(HTTP_PROXY_PASSWORD_PROPERTY)
|
||||||
|
@ -63,4 +63,9 @@ object ProxyUtils {
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
private const val HTTP_PROXY_USER_PROPERTY = "http.proxyUser"
|
||||||
|
private const val HTTP_PROXY_PASSWORD_PROPERTY = "http.proxyPassword"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,16 +4,19 @@
|
||||||
*/
|
*/
|
||||||
package dev.msfjarvis.aps.util.settings
|
package dev.msfjarvis.aps.util.settings
|
||||||
|
|
||||||
|
import android.content.SharedPreferences
|
||||||
import androidx.core.content.edit
|
import androidx.core.content.edit
|
||||||
import com.github.michaelbull.result.getOrElse
|
import com.github.michaelbull.result.getOrElse
|
||||||
import com.github.michaelbull.result.runCatching
|
import com.github.michaelbull.result.runCatching
|
||||||
import dev.msfjarvis.aps.Application
|
|
||||||
import dev.msfjarvis.aps.data.repo.PasswordRepository
|
import dev.msfjarvis.aps.data.repo.PasswordRepository
|
||||||
import dev.msfjarvis.aps.util.extensions.getEncryptedGitPrefs
|
import dev.msfjarvis.aps.injection.context.FilesDirPath
|
||||||
import dev.msfjarvis.aps.util.extensions.getEncryptedProxyPrefs
|
import dev.msfjarvis.aps.injection.prefs.GitPreferences
|
||||||
|
import dev.msfjarvis.aps.injection.prefs.ProxyPreferences
|
||||||
|
import dev.msfjarvis.aps.injection.prefs.SettingsPreferences
|
||||||
import dev.msfjarvis.aps.util.extensions.getString
|
import dev.msfjarvis.aps.util.extensions.getString
|
||||||
import dev.msfjarvis.aps.util.extensions.sharedPrefs
|
|
||||||
import java.io.File
|
import java.io.File
|
||||||
|
import javax.inject.Inject
|
||||||
|
import javax.inject.Singleton
|
||||||
import org.eclipse.jgit.transport.URIish
|
import org.eclipse.jgit.transport.URIish
|
||||||
|
|
||||||
enum class Protocol(val pref: String) {
|
enum class Protocol(val pref: String) {
|
||||||
|
@ -48,29 +51,22 @@ enum class AuthMode(val pref: String) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
object GitSettings {
|
@Singleton
|
||||||
|
class GitSettings @Inject constructor(
|
||||||
|
@SettingsPreferences private val settings: SharedPreferences,
|
||||||
|
@GitPreferences private val encryptedSettings: SharedPreferences,
|
||||||
|
@ProxyPreferences private val proxySettings: SharedPreferences,
|
||||||
|
@FilesDirPath private val filesDirPath: String,
|
||||||
|
) {
|
||||||
|
|
||||||
private const val DEFAULT_BRANCH = "master"
|
|
||||||
|
|
||||||
private val settings by lazy(LazyThreadSafetyMode.PUBLICATION) {
|
|
||||||
Application.instance.sharedPrefs
|
|
||||||
}
|
|
||||||
private val encryptedSettings by lazy(LazyThreadSafetyMode.PUBLICATION) {
|
|
||||||
Application.instance.getEncryptedGitPrefs()
|
|
||||||
}
|
|
||||||
private val proxySettings by lazy(LazyThreadSafetyMode.PUBLICATION) {
|
|
||||||
Application.instance.getEncryptedProxyPrefs()
|
|
||||||
}
|
|
||||||
private val hostKeyPath by lazy(LazyThreadSafetyMode.NONE) {
|
private val hostKeyPath by lazy(LazyThreadSafetyMode.NONE) {
|
||||||
"${Application.instance.filesDir}/.host_key"
|
"$filesDirPath/.host_key"
|
||||||
}
|
}
|
||||||
|
|
||||||
var authMode
|
var authMode
|
||||||
get() = AuthMode.fromString(settings.getString(PreferenceKeys.GIT_REMOTE_AUTH))
|
get() = AuthMode.fromString(settings.getString(PreferenceKeys.GIT_REMOTE_AUTH))
|
||||||
private set(value) {
|
private set(value) {
|
||||||
settings.edit { putString(PreferenceKeys.GIT_REMOTE_AUTH, value.pref) }
|
settings.edit { putString(PreferenceKeys.GIT_REMOTE_AUTH, value.pref) }
|
||||||
}
|
}
|
||||||
|
|
||||||
var url
|
var url
|
||||||
get() = settings.getString(PreferenceKeys.GIT_REMOTE_URL)
|
get() = settings.getString(PreferenceKeys.GIT_REMOTE_URL)
|
||||||
private set(value) {
|
private set(value) {
|
||||||
|
@ -84,55 +80,46 @@ object GitSettings {
|
||||||
encryptedSettings.edit { remove(PreferenceKeys.HTTPS_PASSWORD) }
|
encryptedSettings.edit { remove(PreferenceKeys.HTTPS_PASSWORD) }
|
||||||
clearSavedHostKey()
|
clearSavedHostKey()
|
||||||
}
|
}
|
||||||
|
|
||||||
var authorName
|
var authorName
|
||||||
get() = settings.getString(PreferenceKeys.GIT_CONFIG_AUTHOR_NAME) ?: ""
|
get() = settings.getString(PreferenceKeys.GIT_CONFIG_AUTHOR_NAME) ?: ""
|
||||||
set(value) {
|
set(value) {
|
||||||
settings.edit { putString(PreferenceKeys.GIT_CONFIG_AUTHOR_NAME, value) }
|
settings.edit { putString(PreferenceKeys.GIT_CONFIG_AUTHOR_NAME, value) }
|
||||||
}
|
}
|
||||||
|
|
||||||
var authorEmail
|
var authorEmail
|
||||||
get() = settings.getString(PreferenceKeys.GIT_CONFIG_AUTHOR_EMAIL) ?: ""
|
get() = settings.getString(PreferenceKeys.GIT_CONFIG_AUTHOR_EMAIL) ?: ""
|
||||||
set(value) {
|
set(value) {
|
||||||
settings.edit { putString(PreferenceKeys.GIT_CONFIG_AUTHOR_EMAIL, value) }
|
settings.edit { putString(PreferenceKeys.GIT_CONFIG_AUTHOR_EMAIL, value) }
|
||||||
}
|
}
|
||||||
|
|
||||||
var branch
|
var branch
|
||||||
get() = settings.getString(PreferenceKeys.GIT_BRANCH_NAME) ?: DEFAULT_BRANCH
|
get() = settings.getString(PreferenceKeys.GIT_BRANCH_NAME) ?: DEFAULT_BRANCH
|
||||||
private set(value) {
|
private set(value) {
|
||||||
settings.edit { putString(PreferenceKeys.GIT_BRANCH_NAME, value) }
|
settings.edit { putString(PreferenceKeys.GIT_BRANCH_NAME, value) }
|
||||||
}
|
}
|
||||||
|
|
||||||
var useMultiplexing
|
var useMultiplexing
|
||||||
get() = settings.getBoolean(PreferenceKeys.GIT_REMOTE_USE_MULTIPLEXING, true)
|
get() = settings.getBoolean(PreferenceKeys.GIT_REMOTE_USE_MULTIPLEXING, true)
|
||||||
set(value) {
|
set(value) {
|
||||||
settings.edit { putBoolean(PreferenceKeys.GIT_REMOTE_USE_MULTIPLEXING, value) }
|
settings.edit { putBoolean(PreferenceKeys.GIT_REMOTE_USE_MULTIPLEXING, value) }
|
||||||
}
|
}
|
||||||
|
|
||||||
var proxyHost
|
var proxyHost
|
||||||
get() = proxySettings.getString(PreferenceKeys.PROXY_HOST)
|
get() = proxySettings.getString(PreferenceKeys.PROXY_HOST)
|
||||||
set(value) {
|
set(value) {
|
||||||
proxySettings.edit { putString(PreferenceKeys.PROXY_HOST, value) }
|
proxySettings.edit { putString(PreferenceKeys.PROXY_HOST, value) }
|
||||||
}
|
}
|
||||||
|
|
||||||
var proxyPort
|
var proxyPort
|
||||||
get() = proxySettings.getInt(PreferenceKeys.PROXY_PORT, -1)
|
get() = proxySettings.getInt(PreferenceKeys.PROXY_PORT, -1)
|
||||||
set(value) {
|
set(value) {
|
||||||
proxySettings.edit { putInt(PreferenceKeys.PROXY_PORT, value) }
|
proxySettings.edit { putInt(PreferenceKeys.PROXY_PORT, value) }
|
||||||
}
|
}
|
||||||
|
|
||||||
var proxyUsername
|
var proxyUsername
|
||||||
get() = settings.getString(PreferenceKeys.PROXY_USERNAME)
|
get() = settings.getString(PreferenceKeys.PROXY_USERNAME)
|
||||||
set(value) {
|
set(value) {
|
||||||
proxySettings.edit { putString(PreferenceKeys.PROXY_USERNAME, value) }
|
proxySettings.edit { putString(PreferenceKeys.PROXY_USERNAME, value) }
|
||||||
}
|
}
|
||||||
|
|
||||||
var proxyPassword
|
var proxyPassword
|
||||||
get() = proxySettings.getString(PreferenceKeys.PROXY_PASSWORD)
|
get() = proxySettings.getString(PreferenceKeys.PROXY_PASSWORD)
|
||||||
set(value) {
|
set(value) {
|
||||||
proxySettings.edit { putString(PreferenceKeys.PROXY_PASSWORD, value) }
|
proxySettings.edit { putString(PreferenceKeys.PROXY_PASSWORD, value) }
|
||||||
}
|
}
|
||||||
|
|
||||||
var rebaseOnPull
|
var rebaseOnPull
|
||||||
get() = settings.getBoolean(PreferenceKeys.REBASE_ON_PULL, true)
|
get() = settings.getBoolean(PreferenceKeys.REBASE_ON_PULL, true)
|
||||||
set(value) {
|
set(value) {
|
||||||
|
@ -141,8 +128,7 @@ object GitSettings {
|
||||||
|
|
||||||
sealed class UpdateConnectionSettingsResult {
|
sealed class UpdateConnectionSettingsResult {
|
||||||
class MissingUsername(val newProtocol: Protocol) : UpdateConnectionSettingsResult()
|
class MissingUsername(val newProtocol: Protocol) : UpdateConnectionSettingsResult()
|
||||||
class AuthModeMismatch(val newProtocol: Protocol, val validModes: List<AuthMode>) :
|
class AuthModeMismatch(val newProtocol: Protocol, val validModes: List<AuthMode>) : UpdateConnectionSettingsResult()
|
||||||
UpdateConnectionSettingsResult()
|
|
||||||
object Valid : UpdateConnectionSettingsResult()
|
object Valid : UpdateConnectionSettingsResult()
|
||||||
object FailedToParseUrl : UpdateConnectionSettingsResult()
|
object FailedToParseUrl : UpdateConnectionSettingsResult()
|
||||||
}
|
}
|
||||||
|
@ -164,7 +150,6 @@ object GitSettings {
|
||||||
}
|
}
|
||||||
if (newAuthMode != AuthMode.None && parsedUrl.user.isNullOrBlank())
|
if (newAuthMode != AuthMode.None && parsedUrl.user.isNullOrBlank())
|
||||||
return UpdateConnectionSettingsResult.MissingUsername(newProtocol)
|
return UpdateConnectionSettingsResult.MissingUsername(newProtocol)
|
||||||
|
|
||||||
val validHttpsAuth = listOf(AuthMode.None, AuthMode.Password)
|
val validHttpsAuth = listOf(AuthMode.None, AuthMode.Password)
|
||||||
val validSshAuth = listOf(AuthMode.OpenKeychain, AuthMode.Password, AuthMode.SshKey)
|
val validSshAuth = listOf(AuthMode.OpenKeychain, AuthMode.Password, AuthMode.SshKey)
|
||||||
when {
|
when {
|
||||||
|
@ -189,4 +174,8 @@ object GitSettings {
|
||||||
|
|
||||||
/** Returns true if a host key was previously saved */
|
/** Returns true if a host key was previously saved */
|
||||||
fun hasSavedHostKey(): Boolean = File(hostKeyPath).exists()
|
fun hasSavedHostKey(): Boolean = File(hostKeyPath).exists()
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
private const val DEFAULT_BRANCH = "master"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,7 +6,6 @@
|
||||||
|
|
||||||
package dev.msfjarvis.aps.util.settings
|
package dev.msfjarvis.aps.util.settings
|
||||||
|
|
||||||
import android.content.Context
|
|
||||||
import android.content.SharedPreferences
|
import android.content.SharedPreferences
|
||||||
import androidx.core.content.edit
|
import androidx.core.content.edit
|
||||||
import com.github.ajalt.timberkt.e
|
import com.github.ajalt.timberkt.e
|
||||||
|
@ -14,20 +13,18 @@ import com.github.ajalt.timberkt.i
|
||||||
import com.github.michaelbull.result.get
|
import com.github.michaelbull.result.get
|
||||||
import com.github.michaelbull.result.runCatching
|
import com.github.michaelbull.result.runCatching
|
||||||
import dev.msfjarvis.aps.util.extensions.getString
|
import dev.msfjarvis.aps.util.extensions.getString
|
||||||
import dev.msfjarvis.aps.util.extensions.sharedPrefs
|
|
||||||
import dev.msfjarvis.aps.util.git.sshj.SshKey
|
import dev.msfjarvis.aps.util.git.sshj.SshKey
|
||||||
import java.io.File
|
import java.io.File
|
||||||
import java.net.URI
|
import java.net.URI
|
||||||
|
|
||||||
fun runMigrations(context: Context) {
|
fun runMigrations(filesDirPath: String, sharedPrefs: SharedPreferences, gitSettings: GitSettings) {
|
||||||
val sharedPrefs = context.sharedPrefs
|
migrateToGitUrlBasedConfig(sharedPrefs, gitSettings)
|
||||||
migrateToGitUrlBasedConfig(sharedPrefs)
|
|
||||||
migrateToHideAll(sharedPrefs)
|
migrateToHideAll(sharedPrefs)
|
||||||
migrateToSshKey(context, sharedPrefs)
|
migrateToSshKey(filesDirPath, sharedPrefs)
|
||||||
migrateToClipboardHistory(sharedPrefs)
|
migrateToClipboardHistory(sharedPrefs)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun migrateToGitUrlBasedConfig(sharedPrefs: SharedPreferences) {
|
private fun migrateToGitUrlBasedConfig(sharedPrefs: SharedPreferences, gitSettings: GitSettings) {
|
||||||
val serverHostname = sharedPrefs.getString(PreferenceKeys.GIT_REMOTE_SERVER) ?: return
|
val serverHostname = sharedPrefs.getString(PreferenceKeys.GIT_REMOTE_SERVER) ?: return
|
||||||
i { "Migrating to URL-based Git config" }
|
i { "Migrating to URL-based Git config" }
|
||||||
val serverPort = sharedPrefs.getString(PreferenceKeys.GIT_REMOTE_PORT) ?: ""
|
val serverPort = sharedPrefs.getString(PreferenceKeys.GIT_REMOTE_PORT) ?: ""
|
||||||
|
@ -76,10 +73,10 @@ private fun migrateToGitUrlBasedConfig(sharedPrefs: SharedPreferences) {
|
||||||
remove(PreferenceKeys.GIT_REMOTE_PROTOCOL)
|
remove(PreferenceKeys.GIT_REMOTE_PROTOCOL)
|
||||||
}
|
}
|
||||||
if (url == null ||
|
if (url == null ||
|
||||||
GitSettings.updateConnectionSettingsIfValid(
|
gitSettings.updateConnectionSettingsIfValid(
|
||||||
newAuthMode = GitSettings.authMode,
|
newAuthMode = gitSettings.authMode,
|
||||||
newUrl = url,
|
newUrl = url,
|
||||||
newBranch = GitSettings.branch
|
newBranch = gitSettings.branch
|
||||||
) != GitSettings.UpdateConnectionSettingsResult.Valid
|
) != 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" }
|
||||||
|
@ -95,8 +92,8 @@ private fun migrateToHideAll(sharedPrefs: SharedPreferences) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun migrateToSshKey(context: Context, sharedPrefs: SharedPreferences) {
|
private fun migrateToSshKey(filesDirPath: String, sharedPrefs: SharedPreferences) {
|
||||||
val privateKeyFile = File(context.filesDir, ".ssh_key")
|
val privateKeyFile = File(filesDirPath, ".ssh_key")
|
||||||
if (sharedPrefs.contains(PreferenceKeys.USE_GENERATED_KEY) &&
|
if (sharedPrefs.contains(PreferenceKeys.USE_GENERATED_KEY) &&
|
||||||
!SshKey.exists &&
|
!SshKey.exists &&
|
||||||
privateKeyFile.exists()
|
privateKeyFile.exists()
|
||||||
|
|
Loading…
Reference in a new issue