summaryrefslogtreecommitdiffstats
path: root/app/src/main/java/dev/msfjarvis/aps/util
diff options
context:
space:
mode:
authorHarsh Shandilya <me@msfjarvis.dev>2021-05-15 12:56:49 +0530
committerHarsh Shandilya <me@msfjarvis.dev>2021-05-15 15:40:20 +0530
commit7e2eb2425e7b9b6ccb37b7b89f19de3fa7a20c44 (patch)
tree6b8a9557ac51b5fab5d2ad7611084cf0de6c57cf /app/src/main/java/dev/msfjarvis/aps/util
parent2fcb285e276594842798be6990b92ba09e733f49 (diff)
downloadHardenedPass-7e2eb2425e7b9b6ccb37b7b89f19de3fa7a20c44.tar.gz
HardenedPass-7e2eb2425e7b9b6ccb37b7b89f19de3fa7a20c44.zip
all: reformat with Spotless again
Signed-off-by: Harsh Shandilya <me@msfjarvis.dev>
Diffstat (limited to 'app/src/main/java/dev/msfjarvis/aps/util')
-rw-r--r--app/src/main/java/dev/msfjarvis/aps/util/auth/BiometricAuthenticator.kt18
-rw-r--r--app/src/main/java/dev/msfjarvis/aps/util/autofill/Api30AutofillResponseBuilder.kt32
-rw-r--r--app/src/main/java/dev/msfjarvis/aps/util/autofill/AutofillMatcher.kt35
-rw-r--r--app/src/main/java/dev/msfjarvis/aps/util/autofill/AutofillPreferences.kt6
-rw-r--r--app/src/main/java/dev/msfjarvis/aps/util/autofill/AutofillResponseBuilder.kt5
-rw-r--r--app/src/main/java/dev/msfjarvis/aps/util/autofill/AutofillViewUtils.kt22
-rw-r--r--app/src/main/java/dev/msfjarvis/aps/util/crypto/GpgIdentifier.kt6
-rw-r--r--app/src/main/java/dev/msfjarvis/aps/util/extensions/AndroidExtensions.kt9
-rw-r--r--app/src/main/java/dev/msfjarvis/aps/util/extensions/FragmentViewBindingDelegate.kt15
-rw-r--r--app/src/main/java/dev/msfjarvis/aps/util/git/ErrorMessages.kt3
-rw-r--r--app/src/main/java/dev/msfjarvis/aps/util/git/GitCommandExecutor.kt6
-rw-r--r--app/src/main/java/dev/msfjarvis/aps/util/git/GitCommit.kt7
-rw-r--r--app/src/main/java/dev/msfjarvis/aps/util/git/GitLogModel.kt4
-rw-r--r--app/src/main/java/dev/msfjarvis/aps/util/git/operation/BreakOutOfDetached.kt16
-rw-r--r--app/src/main/java/dev/msfjarvis/aps/util/git/operation/CloneOperation.kt3
-rw-r--r--app/src/main/java/dev/msfjarvis/aps/util/git/operation/CredentialFinder.kt15
-rw-r--r--app/src/main/java/dev/msfjarvis/aps/util/git/operation/GitOperation.kt33
-rw-r--r--app/src/main/java/dev/msfjarvis/aps/util/git/operation/PushOperation.kt3
-rw-r--r--app/src/main/java/dev/msfjarvis/aps/util/git/operation/ResetToRemoteOperation.kt3
-rw-r--r--app/src/main/java/dev/msfjarvis/aps/util/git/sshj/OpenKeychainKeyProvider.kt36
-rw-r--r--app/src/main/java/dev/msfjarvis/aps/util/git/sshj/OpenKeychainWrappedKeyAlgorithmFactory.kt12
-rw-r--r--app/src/main/java/dev/msfjarvis/aps/util/git/sshj/SshKey.kt45
-rw-r--r--app/src/main/java/dev/msfjarvis/aps/util/git/sshj/SshjConfig.kt36
-rw-r--r--app/src/main/java/dev/msfjarvis/aps/util/git/sshj/SshjSessionFactory.kt29
-rw-r--r--app/src/main/java/dev/msfjarvis/aps/util/pwgen/PasswordGenerator.kt17
-rw-r--r--app/src/main/java/dev/msfjarvis/aps/util/pwgen/RandomPasswordGenerator.kt4
-rw-r--r--app/src/main/java/dev/msfjarvis/aps/util/pwgen/RandomPhonemesGenerator.kt25
-rw-r--r--app/src/main/java/dev/msfjarvis/aps/util/pwgenxkpwd/PasswordBuilder.kt4
-rw-r--r--app/src/main/java/dev/msfjarvis/aps/util/pwgenxkpwd/XkpwdDictionary.kt5
-rw-r--r--app/src/main/java/dev/msfjarvis/aps/util/services/ClipboardService.kt11
-rw-r--r--app/src/main/java/dev/msfjarvis/aps/util/services/OreoAutofillService.kt19
-rw-r--r--app/src/main/java/dev/msfjarvis/aps/util/services/PasswordExportService.kt6
-rw-r--r--app/src/main/java/dev/msfjarvis/aps/util/settings/GitSettings.kt18
-rw-r--r--app/src/main/java/dev/msfjarvis/aps/util/settings/Migrations.kt8
-rw-r--r--app/src/main/java/dev/msfjarvis/aps/util/settings/PasswordSortOrder.kt9
-rw-r--r--app/src/main/java/dev/msfjarvis/aps/util/totp/UriTotpFinder.kt3
-rw-r--r--app/src/main/java/dev/msfjarvis/aps/util/viewmodel/SearchableRepositoryViewModel.kt44
37 files changed, 418 insertions, 154 deletions
diff --git a/app/src/main/java/dev/msfjarvis/aps/util/auth/BiometricAuthenticator.kt b/app/src/main/java/dev/msfjarvis/aps/util/auth/BiometricAuthenticator.kt
index c3655298..7236ac7c 100644
--- a/app/src/main/java/dev/msfjarvis/aps/util/auth/BiometricAuthenticator.kt
+++ b/app/src/main/java/dev/msfjarvis/aps/util/auth/BiometricAuthenticator.kt
@@ -19,7 +19,8 @@ import dev.msfjarvis.aps.R
object BiometricAuthenticator {
private const val TAG = "BiometricAuthenticator"
- private const val validAuthenticators = Authenticators.DEVICE_CREDENTIAL or Authenticators.BIOMETRIC_WEAK
+ private const val validAuthenticators =
+ Authenticators.DEVICE_CREDENTIAL or Authenticators.BIOMETRIC_WEAK
sealed class Result {
data class Success(val cryptoObject: BiometricPrompt.CryptoObject?) : Result()
@@ -29,7 +30,8 @@ object BiometricAuthenticator {
}
fun canAuthenticate(activity: FragmentActivity): Boolean {
- return BiometricManager.from(activity).canAuthenticate(validAuthenticators) == BiometricManager.BIOMETRIC_SUCCESS
+ return BiometricManager.from(activity).canAuthenticate(validAuthenticators) ==
+ BiometricManager.BIOMETRIC_SUCCESS
}
fun authenticate(
@@ -55,7 +57,11 @@ object BiometricAuthenticator {
BiometricPrompt.ERROR_NO_DEVICE_CREDENTIAL -> {
Result.HardwareUnavailableOrDisabled
}
- else -> Result.Failure(errorCode, activity.getString(R.string.biometric_auth_error_reason, errString))
+ else ->
+ Result.Failure(
+ errorCode,
+ activity.getString(R.string.biometric_auth_error_reason, errString)
+ )
}
)
}
@@ -77,7 +83,11 @@ object BiometricAuthenticator {
.setTitle(activity.getString(dialogTitleRes))
.setAllowedAuthenticators(validAuthenticators)
.build()
- BiometricPrompt(activity, ContextCompat.getMainExecutor(activity.applicationContext), authCallback)
+ BiometricPrompt(
+ activity,
+ ContextCompat.getMainExecutor(activity.applicationContext),
+ authCallback
+ )
.authenticate(promptInfo)
} else {
callback(Result.HardwareUnavailableOrDisabled)
diff --git a/app/src/main/java/dev/msfjarvis/aps/util/autofill/Api30AutofillResponseBuilder.kt b/app/src/main/java/dev/msfjarvis/aps/util/autofill/Api30AutofillResponseBuilder.kt
index a39db31d..ea03bb23 100644
--- a/app/src/main/java/dev/msfjarvis/aps/util/autofill/Api30AutofillResponseBuilder.kt
+++ b/app/src/main/java/dev/msfjarvis/aps/util/autofill/Api30AutofillResponseBuilder.kt
@@ -61,7 +61,11 @@ class Api30AutofillResponseBuilder(form: FillableForm) {
}
}
- private fun makeMatchDataset(context: Context, file: File, imeSpec: InlinePresentationSpec?): Dataset? {
+ private fun makeMatchDataset(
+ context: Context,
+ file: File,
+ imeSpec: InlinePresentationSpec?
+ ): Dataset? {
if (!scenario.hasFieldsToFillOn(AutofillAction.Match)) return null
val metadata = makeFillMatchMetadata(context, file)
val intentSender = AutofillDecryptActivity.makeDecryptFileIntentSender(file, context)
@@ -82,12 +86,21 @@ class Api30AutofillResponseBuilder(form: FillableForm) {
return makeIntentDataset(context, AutofillAction.Generate, intentSender, metadata, imeSpec)
}
- private fun makeFillOtpFromSmsDataset(context: Context, imeSpec: InlinePresentationSpec?): Dataset? {
+ private fun makeFillOtpFromSmsDataset(
+ context: Context,
+ imeSpec: InlinePresentationSpec?
+ ): Dataset? {
if (!scenario.hasFieldsToFillOn(AutofillAction.FillOtpFromSms)) return null
if (!AutofillSmsActivity.shouldOfferFillFromSms(context)) return null
val metadata = makeFillOtpFromSmsMetadata(context)
val intentSender = AutofillSmsActivity.makeFillOtpFromSmsIntentSender(context)
- return makeIntentDataset(context, AutofillAction.FillOtpFromSms, intentSender, metadata, imeSpec)
+ return makeIntentDataset(
+ context,
+ AutofillAction.FillOtpFromSms,
+ intentSender,
+ metadata,
+ imeSpec
+ )
}
private fun makePublisherChangedDataset(
@@ -150,7 +163,12 @@ class Api30AutofillResponseBuilder(form: FillableForm) {
addDataset(it)
}
if (datasetCount == 0) return null
- setHeader(makeRemoteView(context, makeHeaderMetadata(formOrigin.getPrettyIdentifier(context, untrusted = true))))
+ setHeader(
+ makeRemoteView(
+ context,
+ makeHeaderMetadata(formOrigin.getPrettyIdentifier(context, untrusted = true))
+ )
+ )
makeSaveInfo()?.let { setSaveInfo(it) }
setClientState(clientState)
setIgnoredIds(*ignoredIds.toTypedArray())
@@ -177,7 +195,11 @@ class Api30AutofillResponseBuilder(form: FillableForm) {
}
/** Creates and returns a suitable [FillResponse] to the Autofill framework. */
- fun fillCredentials(context: Context, inlineSuggestionsRequest: InlineSuggestionsRequest?, callback: FillCallback) {
+ fun fillCredentials(
+ context: Context,
+ inlineSuggestionsRequest: InlineSuggestionsRequest?,
+ callback: FillCallback
+ ) {
AutofillMatcher.getMatchesFor(context, formOrigin)
.fold(
success = { matchedFiles ->
diff --git a/app/src/main/java/dev/msfjarvis/aps/util/autofill/AutofillMatcher.kt b/app/src/main/java/dev/msfjarvis/aps/util/autofill/AutofillMatcher.kt
index 418843f6..ea10c1ac 100644
--- a/app/src/main/java/dev/msfjarvis/aps/util/autofill/AutofillMatcher.kt
+++ b/app/src/main/java/dev/msfjarvis/aps/util/autofill/AutofillMatcher.kt
@@ -35,7 +35,9 @@ private fun Context.matchPreferences(formOrigin: FormOrigin): SharedPreferences
}
class AutofillPublisherChangedException(val formOrigin: FormOrigin) :
- Exception("The publisher of '${formOrigin.identifier}' changed since an entry was first matched with this app") {
+ Exception(
+ "The publisher of '${formOrigin.identifier}' changed since an entry was first matched with this app"
+ ) {
init {
require(formOrigin is FormOrigin.App)
@@ -50,10 +52,12 @@ class AutofillMatcher {
private const val MAX_NUM_MATCHES = 10
private const val PREFERENCE_PREFIX_TOKEN = "token;"
- private fun tokenKey(formOrigin: FormOrigin.App) = "$PREFERENCE_PREFIX_TOKEN${formOrigin.identifier}"
+ private fun tokenKey(formOrigin: FormOrigin.App) =
+ "$PREFERENCE_PREFIX_TOKEN${formOrigin.identifier}"
private const val PREFERENCE_PREFIX_MATCHES = "matches;"
- private fun matchesKey(formOrigin: FormOrigin) = "$PREFERENCE_PREFIX_MATCHES${formOrigin.identifier}"
+ private fun matchesKey(formOrigin: FormOrigin) =
+ "$PREFERENCE_PREFIX_MATCHES${formOrigin.identifier}"
private fun hasFormOriginHashChanged(context: Context, formOrigin: FormOrigin): Boolean {
return when (formOrigin) {
@@ -61,7 +65,8 @@ class AutofillMatcher {
is FormOrigin.App -> {
val packageName = formOrigin.identifier
val certificatesHash = computeCertificatesHash(context, packageName)
- val storedCertificatesHash = context.autofillAppMatches.getString(tokenKey(formOrigin), null) ?: return false
+ val storedCertificatesHash =
+ context.autofillAppMatches.getString(tokenKey(formOrigin), null) ?: return false
val hashHasChanged = certificatesHash != storedCertificatesHash
if (hashHasChanged) {
e { "$packageName: stored=$storedCertificatesHash, new=$certificatesHash" }
@@ -91,15 +96,21 @@ class AutofillMatcher {
* time the user associated an entry with it, an [AutofillPublisherChangedException] will be
* thrown.
*/
- fun getMatchesFor(context: Context, formOrigin: FormOrigin): Result<List<File>, AutofillPublisherChangedException> {
+ fun getMatchesFor(
+ context: Context,
+ formOrigin: FormOrigin
+ ): Result<List<File>, AutofillPublisherChangedException> {
if (hasFormOriginHashChanged(context, formOrigin)) {
return Err(AutofillPublisherChangedException(formOrigin))
}
val matchPreferences = context.matchPreferences(formOrigin)
- val matchedFiles = matchPreferences.getStringSet(matchesKey(formOrigin), emptySet())!!.map { File(it) }
+ val matchedFiles =
+ matchPreferences.getStringSet(matchesKey(formOrigin), emptySet())!!.map { File(it) }
return Ok(
matchedFiles.filter { it.exists() }.also { validFiles ->
- matchPreferences.edit { putStringSet(matchesKey(formOrigin), validFiles.map { it.absolutePath }.toSet()) }
+ matchPreferences.edit {
+ putStringSet(matchesKey(formOrigin), validFiles.map { it.absolutePath }.toSet())
+ }
}
)
}
@@ -127,7 +138,8 @@ class AutofillMatcher {
throw AutofillPublisherChangedException(formOrigin)
}
val matchPreferences = context.matchPreferences(formOrigin)
- val matchedFiles = matchPreferences.getStringSet(matchesKey(formOrigin), emptySet())!!.map { File(it) }
+ val matchedFiles =
+ matchPreferences.getStringSet(matchesKey(formOrigin), emptySet())!!.map { File(it) }
val newFiles = setOf(file.absoluteFile).union(matchedFiles)
if (newFiles.size > MAX_NUM_MATCHES) {
Toast.makeText(
@@ -138,7 +150,9 @@ class AutofillMatcher {
.show()
return
}
- matchPreferences.edit { putStringSet(matchesKey(formOrigin), newFiles.map { it.absolutePath }.toSet()) }
+ matchPreferences.edit {
+ putStringSet(matchesKey(formOrigin), newFiles.map { it.absolutePath }.toSet())
+ }
storeFormOriginHash(context, formOrigin)
d { "Stored match for $formOrigin" }
}
@@ -153,7 +167,8 @@ class AutofillMatcher {
delete: Collection<File> = emptyList()
) {
val deletePathList = delete.map { it.absolutePath }
- val oldNewPathMap = moveFromTo.mapValues { it.value.absolutePath }.mapKeys { it.key.absolutePath }
+ val oldNewPathMap =
+ moveFromTo.mapValues { it.value.absolutePath }.mapKeys { it.key.absolutePath }
for (prefs in listOf(context.autofillAppMatches, context.autofillWebMatches)) {
for ((key, value) in prefs.all) {
if (!key.startsWith(PREFERENCE_PREFIX_MATCHES)) continue
diff --git a/app/src/main/java/dev/msfjarvis/aps/util/autofill/AutofillPreferences.kt b/app/src/main/java/dev/msfjarvis/aps/util/autofill/AutofillPreferences.kt
index c6cdffed..fdbd15af 100644
--- a/app/src/main/java/dev/msfjarvis/aps/util/autofill/AutofillPreferences.kt
+++ b/app/src/main/java/dev/msfjarvis/aps/util/autofill/AutofillPreferences.kt
@@ -96,7 +96,8 @@ enum class DirectoryStructure(val value: String) {
when (this) {
EncryptedUsername -> null
FileBased -> file.nameWithoutExtension.takeIf { file.parentFile != null }
- DirectoryBased -> file.parentFile?.let { parentFile -> "${parentFile.name}/${file.nameWithoutExtension}" }
+ DirectoryBased ->
+ file.parentFile?.let { parentFile -> "${parentFile.name}/${file.nameWithoutExtension}" }
?: file.nameWithoutExtension
}
@@ -138,7 +139,8 @@ object AutofillPreferences {
directoryStructure: DirectoryStructure
): Credentials {
// Always give priority to a username stored in the encrypted extras
- val username = entry.username ?: directoryStructure.getUsernameFor(file) ?: context.getDefaultUsername()
+ val username =
+ entry.username ?: directoryStructure.getUsernameFor(file) ?: context.getDefaultUsername()
return Credentials(username, entry.password, entry.totp.value)
}
}
diff --git a/app/src/main/java/dev/msfjarvis/aps/util/autofill/AutofillResponseBuilder.kt b/app/src/main/java/dev/msfjarvis/aps/util/autofill/AutofillResponseBuilder.kt
index d8126438..9dabf914 100644
--- a/app/src/main/java/dev/msfjarvis/aps/util/autofill/AutofillResponseBuilder.kt
+++ b/app/src/main/java/dev/msfjarvis/aps/util/autofill/AutofillResponseBuilder.kt
@@ -154,7 +154,10 @@ class AutofillResponseBuilder(form: FillableForm) {
if (datasetCount == 0) return null
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
setHeader(
- makeRemoteView(context, makeHeaderMetadata(formOrigin.getPrettyIdentifier(context, untrusted = true)))
+ makeRemoteView(
+ context,
+ makeHeaderMetadata(formOrigin.getPrettyIdentifier(context, untrusted = true))
+ )
)
}
makeSaveInfo()?.let { setSaveInfo(it) }
diff --git a/app/src/main/java/dev/msfjarvis/aps/util/autofill/AutofillViewUtils.kt b/app/src/main/java/dev/msfjarvis/aps/util/autofill/AutofillViewUtils.kt
index 46f7d821..1d09d001 100644
--- a/app/src/main/java/dev/msfjarvis/aps/util/autofill/AutofillViewUtils.kt
+++ b/app/src/main/java/dev/msfjarvis/aps/util/autofill/AutofillViewUtils.kt
@@ -51,13 +51,15 @@ fun makeInlinePresentation(
if (UiVersions.INLINE_UI_VERSION_1 !in UiVersions.getVersions(imeSpec.style)) return null
- val launchIntent = PendingIntent.getActivity(context, 0, Intent(context, PasswordStore::class.java), 0)
+ val launchIntent =
+ PendingIntent.getActivity(context, 0, Intent(context, PasswordStore::class.java), 0)
val slice =
InlineSuggestionUi.newContentBuilder(launchIntent).run {
setTitle(metadata.title)
if (metadata.subtitle != null) setSubtitle(metadata.subtitle)
setContentDescription(
- if (metadata.subtitle != null) "${metadata.title} - ${metadata.subtitle}" else metadata.title
+ if (metadata.subtitle != null) "${metadata.title} - ${metadata.subtitle}"
+ else metadata.title
)
setStartIcon(Icon.createWithResource(context, metadata.iconRes))
build().slice
@@ -69,13 +71,19 @@ fun makeInlinePresentation(
fun makeFillMatchMetadata(context: Context, file: File): DatasetMetadata {
val directoryStructure = AutofillPreferences.directoryStructure(context)
val relativeFile = file.relativeTo(PasswordRepository.getRepositoryDirectory())
- val title = directoryStructure.getIdentifierFor(relativeFile) ?: directoryStructure.getAccountPartFor(relativeFile)!!
+ val title =
+ directoryStructure.getIdentifierFor(relativeFile)
+ ?: directoryStructure.getAccountPartFor(relativeFile)!!
val subtitle = directoryStructure.getAccountPartFor(relativeFile)
return DatasetMetadata(title, subtitle, R.drawable.ic_person_black_24dp)
}
fun makeSearchAndFillMetadata(context: Context) =
- DatasetMetadata(context.getString(R.string.oreo_autofill_search_in_store), null, R.drawable.ic_search_black_24dp)
+ DatasetMetadata(
+ context.getString(R.string.oreo_autofill_search_in_store),
+ null,
+ R.drawable.ic_search_black_24dp
+ )
fun makeGenerateAndFillMetadata(context: Context) =
DatasetMetadata(
@@ -85,7 +93,11 @@ fun makeGenerateAndFillMetadata(context: Context) =
)
fun makeFillOtpFromSmsMetadata(context: Context) =
- DatasetMetadata(context.getString(R.string.oreo_autofill_fill_otp_from_sms), null, R.drawable.ic_autofill_sms)
+ DatasetMetadata(
+ context.getString(R.string.oreo_autofill_fill_otp_from_sms),
+ null,
+ R.drawable.ic_autofill_sms
+ )
fun makeEmptyMetadata() = DatasetMetadata("PLACEHOLDER", "PLACEHOLDER", R.mipmap.ic_launcher)
diff --git a/app/src/main/java/dev/msfjarvis/aps/util/crypto/GpgIdentifier.kt b/app/src/main/java/dev/msfjarvis/aps/util/crypto/GpgIdentifier.kt
index cc759e9a..f99b623c 100644
--- a/app/src/main/java/dev/msfjarvis/aps/util/crypto/GpgIdentifier.kt
+++ b/app/src/main/java/dev/msfjarvis/aps/util/crypto/GpgIdentifier.kt
@@ -17,7 +17,8 @@ sealed class GpgIdentifier {
if (identifier.isEmpty()) return null
// Match long key IDs:
// FF22334455667788 or 0xFF22334455667788
- val maybeLongKeyId = identifier.removePrefix("0x").takeIf { it.matches("[a-fA-F0-9]{16}".toRegex()) }
+ val maybeLongKeyId =
+ identifier.removePrefix("0x").takeIf { it.matches("[a-fA-F0-9]{16}".toRegex()) }
if (maybeLongKeyId != null) {
val keyId = maybeLongKeyId.toULong(16)
return KeyId(keyId.toLong())
@@ -25,7 +26,8 @@ sealed class GpgIdentifier {
// Match fingerprints:
// FF223344556677889900112233445566778899 or 0xFF223344556677889900112233445566778899
- val maybeFingerprint = identifier.removePrefix("0x").takeIf { it.matches("[a-fA-F0-9]{40}".toRegex()) }
+ val maybeFingerprint =
+ identifier.removePrefix("0x").takeIf { it.matches("[a-fA-F0-9]{40}".toRegex()) }
if (maybeFingerprint != null) {
// Truncating to the long key ID is not a security issue since OpenKeychain only
// accepts
diff --git a/app/src/main/java/dev/msfjarvis/aps/util/extensions/AndroidExtensions.kt b/app/src/main/java/dev/msfjarvis/aps/util/extensions/AndroidExtensions.kt
index 94103118..21cc30bc 100644
--- a/app/src/main/java/dev/msfjarvis/aps/util/extensions/AndroidExtensions.kt
+++ b/app/src/main/java/dev/msfjarvis/aps/util/extensions/AndroidExtensions.kt
@@ -41,7 +41,11 @@ fun <T : View> AlertDialog.requestInputFocusOnView(@IdRes id: Int) {
setOnShowListener {
findViewById<T>(id)?.apply {
setOnFocusChangeListener { v, _ ->
- v.post { context.getSystemService<InputMethodManager>()?.showSoftInput(v, InputMethodManager.SHOW_IMPLICIT) }
+ v.post {
+ context
+ .getSystemService<InputMethodManager>()
+ ?.showSoftInput(v, InputMethodManager.SHOW_IMPLICIT)
+ }
}
requestFocus()
}
@@ -64,7 +68,8 @@ fun Context.getEncryptedProxyPrefs() = getEncryptedPrefs("http_proxy")
/** Get an instance of [EncryptedSharedPreferences] with the given [fileName] */
private fun Context.getEncryptedPrefs(fileName: String): SharedPreferences {
- val masterKeyAlias = MasterKey.Builder(applicationContext).setKeyScheme(MasterKey.KeyScheme.AES256_GCM).build()
+ val masterKeyAlias =
+ MasterKey.Builder(applicationContext).setKeyScheme(MasterKey.KeyScheme.AES256_GCM).build()
return EncryptedSharedPreferences.create(
applicationContext,
fileName,
diff --git a/app/src/main/java/dev/msfjarvis/aps/util/extensions/FragmentViewBindingDelegate.kt b/app/src/main/java/dev/msfjarvis/aps/util/extensions/FragmentViewBindingDelegate.kt
index 5a1b554f..de21a359 100644
--- a/app/src/main/java/dev/msfjarvis/aps/util/extensions/FragmentViewBindingDelegate.kt
+++ b/app/src/main/java/dev/msfjarvis/aps/util/extensions/FragmentViewBindingDelegate.kt
@@ -20,8 +20,10 @@ import kotlin.reflect.KProperty
* Imported from
* https://medium.com/@Zhuinden/simple-one-liner-viewbinding-in-fragments-and-activities-with-kotlin-961430c6c07c
*/
-class FragmentViewBindingDelegate<T : ViewBinding>(val fragment: Fragment, val viewBindingFactory: (View) -> T) :
- ReadOnlyProperty<Fragment, T> {
+class FragmentViewBindingDelegate<T : ViewBinding>(
+ val fragment: Fragment,
+ val viewBindingFactory: (View) -> T
+) : ReadOnlyProperty<Fragment, T> {
private var binding: T? = null
@@ -51,7 +53,9 @@ class FragmentViewBindingDelegate<T : ViewBinding>(val fragment: Fragment, val v
val lifecycle = fragment.viewLifecycleOwner.lifecycle
if (!lifecycle.currentState.isAtLeast(Lifecycle.State.INITIALIZED)) {
- throw IllegalStateException("Should not attempt to get bindings when Fragment views are destroyed.")
+ throw IllegalStateException(
+ "Should not attempt to get bindings when Fragment views are destroyed."
+ )
}
return viewBindingFactory(thisRef.requireView()).also { this.binding = it }
@@ -61,5 +65,6 @@ class FragmentViewBindingDelegate<T : ViewBinding>(val fragment: Fragment, val v
fun <T : ViewBinding> Fragment.viewBinding(viewBindingFactory: (View) -> T) =
FragmentViewBindingDelegate(this, viewBindingFactory)
-inline fun <T : ViewBinding> AppCompatActivity.viewBinding(crossinline bindingInflater: (LayoutInflater) -> T) =
- lazy(LazyThreadSafetyMode.NONE) { bindingInflater.invoke(layoutInflater) }
+inline fun <T : ViewBinding> AppCompatActivity.viewBinding(
+ crossinline bindingInflater: (LayoutInflater) -> T
+) = lazy(LazyThreadSafetyMode.NONE) { bindingInflater.invoke(layoutInflater) }
diff --git a/app/src/main/java/dev/msfjarvis/aps/util/git/ErrorMessages.kt b/app/src/main/java/dev/msfjarvis/aps/util/git/ErrorMessages.kt
index 04809fdd..36dc445f 100644
--- a/app/src/main/java/dev/msfjarvis/aps/util/git/ErrorMessages.kt
+++ b/app/src/main/java/dev/msfjarvis/aps/util/git/ErrorMessages.kt
@@ -14,7 +14,8 @@ import java.net.UnknownHostException
/**
* Supertype for all Git-related [Exception] s that can be thrown by [GitCommandExecutor.execute].
*/
-sealed class GitException(@StringRes res: Int, vararg fmt: String) : Exception(buildMessage(res, *fmt)) {
+sealed class GitException(@StringRes res: Int, vararg fmt: String) :
+ Exception(buildMessage(res, *fmt)) {
override val message = super.message!!
diff --git a/app/src/main/java/dev/msfjarvis/aps/util/git/GitCommandExecutor.kt b/app/src/main/java/dev/msfjarvis/aps/util/git/GitCommandExecutor.kt
index 4546aee1..7be06385 100644
--- a/app/src/main/java/dev/msfjarvis/aps/util/git/GitCommandExecutor.kt
+++ b/app/src/main/java/dev/msfjarvis/aps/util/git/GitCommandExecutor.kt
@@ -74,11 +74,13 @@ class GitCommandExecutor(
// Code imported (modified) from Gerrit PushOp, license Apache v2
for (rru in result.remoteUpdates) {
when (rru.status) {
- RemoteRefUpdate.Status.REJECTED_NONFASTFORWARD -> throw PushException.NonFastForward
+ RemoteRefUpdate.Status.REJECTED_NONFASTFORWARD ->
+ throw PushException.NonFastForward
RemoteRefUpdate.Status.REJECTED_NODELETE,
RemoteRefUpdate.Status.REJECTED_REMOTE_CHANGED,
RemoteRefUpdate.Status.NON_EXISTING,
- RemoteRefUpdate.Status.NOT_ATTEMPTED, -> throw PushException.Generic(rru.status.name)
+ RemoteRefUpdate.Status.NOT_ATTEMPTED, ->
+ throw PushException.Generic(rru.status.name)
RemoteRefUpdate.Status.REJECTED_OTHER_REASON -> {
throw if ("non-fast-forward" == rru.message) {
PushException.RemoteRejected
diff --git a/app/src/main/java/dev/msfjarvis/aps/util/git/GitCommit.kt b/app/src/main/java/dev/msfjarvis/aps/util/git/GitCommit.kt
index 68b1c167..490f5e2c 100644
--- a/app/src/main/java/dev/msfjarvis/aps/util/git/GitCommit.kt
+++ b/app/src/main/java/dev/msfjarvis/aps/util/git/GitCommit.kt
@@ -15,4 +15,9 @@ import java.util.Date
* @property authorName name of the commit's author without email address.
* @property time time when the commit was created.
*/
-data class GitCommit(val hash: String, val shortMessage: String, val authorName: String, val time: Date)
+data class GitCommit(
+ val hash: String,
+ val shortMessage: String,
+ val authorName: String,
+ val time: Date
+)
diff --git a/app/src/main/java/dev/msfjarvis/aps/util/git/GitLogModel.kt b/app/src/main/java/dev/msfjarvis/aps/util/git/GitLogModel.kt
index 1ba65086..bfef2571 100644
--- a/app/src/main/java/dev/msfjarvis/aps/util/git/GitLogModel.kt
+++ b/app/src/main/java/dev/msfjarvis/aps/util/git/GitLogModel.kt
@@ -40,7 +40,9 @@ class GitLogModel {
// Additionally, tests with 1000 commits in the log have not produced a significant delay in the
// user experience.
private val cache: MutableList<GitCommit> by lazy(LazyThreadSafetyMode.NONE) {
- commits().map { GitCommit(it.hash, it.shortMessage, it.authorIdent.name, it.time) }.toMutableList()
+ commits()
+ .map { GitCommit(it.hash, it.shortMessage, it.authorIdent.name, it.time) }
+ .toMutableList()
}
val size = cache.size
diff --git a/app/src/main/java/dev/msfjarvis/aps/util/git/operation/BreakOutOfDetached.kt b/app/src/main/java/dev/msfjarvis/aps/util/git/operation/BreakOutOfDetached.kt
index 196d6d48..fd0aedf7 100644
--- a/app/src/main/java/dev/msfjarvis/aps/util/git/operation/BreakOutOfDetached.kt
+++ b/app/src/main/java/dev/msfjarvis/aps/util/git/operation/BreakOutOfDetached.kt
@@ -11,13 +11,17 @@ import org.eclipse.jgit.api.RebaseCommand
import org.eclipse.jgit.api.ResetCommand
import org.eclipse.jgit.lib.RepositoryState
-class BreakOutOfDetached(callingActivity: ContinuationContainerActivity) : GitOperation(callingActivity) {
+class BreakOutOfDetached(callingActivity: ContinuationContainerActivity) :
+ GitOperation(callingActivity) {
private val merging = repository.repositoryState == RepositoryState.MERGING
private val resetCommands =
arrayOf(
// git checkout -b conflict-branch
- git.checkout().setCreateBranch(true).setName("conflicting-$remoteBranch-${System.currentTimeMillis()}"),
+ git
+ .checkout()
+ .setCreateBranch(true)
+ .setName("conflicting-$remoteBranch-${System.currentTimeMillis()}"),
// push the changes
git.push().setRemote("origin"),
// switch back to ${gitBranch}
@@ -47,8 +51,12 @@ class BreakOutOfDetached(callingActivity: ContinuationContainerActivity) : GitOp
if (!git.repository.repositoryState.isRebasing && !merging) {
MaterialAlertDialogBuilder(callingActivity)
.setTitle(callingActivity.resources.getString(R.string.git_abort_and_push_title))
- .setMessage(callingActivity.resources.getString(R.string.git_break_out_of_detached_unneeded))
- .setPositiveButton(callingActivity.resources.getString(R.string.dialog_ok)) { _, _ -> callingActivity.finish() }
+ .setMessage(
+ callingActivity.resources.getString(R.string.git_break_out_of_detached_unneeded)
+ )
+ .setPositiveButton(callingActivity.resources.getString(R.string.dialog_ok)) { _, _ ->
+ callingActivity.finish()
+ }
.show()
false
} else {
diff --git a/app/src/main/java/dev/msfjarvis/aps/util/git/operation/CloneOperation.kt b/app/src/main/java/dev/msfjarvis/aps/util/git/operation/CloneOperation.kt
index a5a4f5d0..75db2ea5 100644
--- a/app/src/main/java/dev/msfjarvis/aps/util/git/operation/CloneOperation.kt
+++ b/app/src/main/java/dev/msfjarvis/aps/util/git/operation/CloneOperation.kt
@@ -14,7 +14,8 @@ import org.eclipse.jgit.api.GitCommand
* @param uri URL to clone the repository from
* @param callingActivity the calling activity
*/
-class CloneOperation(callingActivity: ContinuationContainerActivity, uri: String) : GitOperation(callingActivity) {
+class CloneOperation(callingActivity: ContinuationContainerActivity, uri: String) :
+ GitOperation(callingActivity) {
override val commands: Array<GitCommand<out Any>> =
arrayOf(
diff --git a/app/src/main/java/dev/msfjarvis/aps/util/git/operation/CredentialFinder.kt b/app/src/main/java/dev/msfjarvis/aps/util/git/operation/CredentialFinder.kt
index 40869cf2..e06cc996 100644
--- a/app/src/main/java/dev/msfjarvis/aps/util/git/operation/CredentialFinder.kt
+++ b/app/src/main/java/dev/msfjarvis/aps/util/git/operation/CredentialFinder.kt
@@ -24,7 +24,8 @@ import dev.msfjarvis.aps.util.settings.PreferenceKeys
import kotlin.coroutines.Continuation
import kotlin.coroutines.resume
-class CredentialFinder(val callingActivity: FragmentActivity, val authMode: AuthMode) : InteractivePasswordFinder() {
+class CredentialFinder(val callingActivity: FragmentActivity, val authMode: AuthMode) :
+ InteractivePasswordFinder() {
override fun askForPassword(cont: Continuation<String?>, isRetry: Boolean) {
val gitOperationPrefs = callingActivity.getEncryptedGitPrefs()
@@ -49,18 +50,22 @@ class CredentialFinder(val callingActivity: FragmentActivity, val authMode: Auth
rememberRes = R.string.git_operation_remember_password
errorRes = R.string.git_operation_wrong_password
}
- else -> throw IllegalStateException("Only SshKey and Password connection mode ask for passwords")
+ else ->
+ throw IllegalStateException("Only SshKey and Password connection mode ask for passwords")
}
if (isRetry) gitOperationPrefs.edit { remove(credentialPref) }
val storedCredential = gitOperationPrefs.getString(credentialPref, null)
if (storedCredential == null) {
val layoutInflater = LayoutInflater.from(callingActivity)
- @SuppressLint("InflateParams") val dialogView = layoutInflater.inflate(R.layout.git_credential_layout, null)
- val credentialLayout = dialogView.findViewById<TextInputLayout>(R.id.git_auth_passphrase_layout)
+ @SuppressLint("InflateParams")
+ val dialogView = layoutInflater.inflate(R.layout.git_credential_layout, null)
+ val credentialLayout =
+ dialogView.findViewById<TextInputLayout>(R.id.git_auth_passphrase_layout)
val editCredential = dialogView.findViewById<TextInputEditText>(R.id.git_auth_credential)
editCredential.setHint(hintRes)
- val rememberCredential = dialogView.findViewById<MaterialCheckBox>(R.id.git_auth_remember_credential)
+ val rememberCredential =
+ dialogView.findViewById<MaterialCheckBox>(R.id.git_auth_remember_credential)
rememberCredential.setText(rememberRes)
if (isRetry) {
credentialLayout.error = callingActivity.resources.getString(errorRes)
diff --git a/app/src/main/java/dev/msfjarvis/aps/util/git/operation/GitOperation.kt b/app/src/main/java/dev/msfjarvis/aps/util/git/operation/GitOperation.kt
index 0d0dac9c..dbea37e8 100644
--- a/app/src/main/java/dev/msfjarvis/aps/util/git/operation/GitOperation.kt
+++ b/app/src/main/java/dev/msfjarvis/aps/util/git/operation/GitOperation.kt
@@ -60,7 +60,8 @@ abstract class GitOperation(protected val callingActivity: FragmentActivity) {
private val authActivity
get() = callingActivity as ContinuationContainerActivity
- private class HttpsCredentialsProvider(private val passwordFinder: PasswordFinder) : CredentialsProvider() {
+ private class HttpsCredentialsProvider(private val passwordFinder: PasswordFinder) :
+ CredentialsProvider() {
private var cachedPassword: CharArray? = null
@@ -72,7 +73,8 @@ abstract class GitOperation(protected val callingActivity: FragmentActivity) {
is CredentialItem.Username -> item.value = uri?.user
is CredentialItem.Password -> {
item.value =
- cachedPassword?.clone() ?: passwordFinder.reqPassword(null).also { cachedPassword = it.clone() }
+ cachedPassword?.clone()
+ ?: passwordFinder.reqPassword(null).also { cachedPassword = it.clone() }
}
else -> UnsupportedCredentialItem(uri, item.javaClass.name)
}
@@ -102,7 +104,10 @@ abstract class GitOperation(protected val callingActivity: FragmentActivity) {
.onFailure { e -> e(e) }
}
- private fun registerAuthProviders(authMethod: SshAuthMethod, credentialsProvider: CredentialsProvider? = null) {
+ private fun registerAuthProviders(
+ authMethod: SshAuthMethod,
+ credentialsProvider: CredentialsProvider? = null
+ ) {
sshSessionFactory = SshjSessionFactory(authMethod, hostKeyFile)
commands.filterIsInstance<TransportCommand<*, *>>().forEach { command ->
command.setTransportConfigCallback { transport: Transport ->
@@ -132,12 +137,12 @@ abstract class GitOperation(protected val callingActivity: FragmentActivity) {
MaterialAlertDialogBuilder(callingActivity)
.setMessage(callingActivity.resources.getString(R.string.ssh_preferences_dialog_text))
.setTitle(callingActivity.resources.getString(R.string.ssh_preferences_dialog_title))
- .setPositiveButton(callingActivity.resources.getString(R.string.ssh_preferences_dialog_import)) { _, _ ->
- getSshKey(false)
- }
- .setNegativeButton(callingActivity.resources.getString(R.string.ssh_preferences_dialog_generate)) { _, _ ->
- getSshKey(true)
- }
+ .setPositiveButton(
+ callingActivity.resources.getString(R.string.ssh_preferences_dialog_import)
+ ) { _, _ -> getSshKey(false) }
+ .setNegativeButton(
+ callingActivity.resources.getString(R.string.ssh_preferences_dialog_generate)
+ ) { _, _ -> getSshKey(true) }
.setNeutralButton(callingActivity.resources.getString(R.string.dialog_cancel)) { _, _ ->
// Finish the blank GitActivity so user doesn't have to press back
callingActivity.finish()
@@ -153,9 +158,10 @@ abstract class GitOperation(protected val callingActivity: FragmentActivity) {
val result =
withContext(Dispatchers.Main) {
suspendCoroutine<BiometricAuthenticator.Result> { cont ->
- BiometricAuthenticator.authenticate(callingActivity, R.string.biometric_prompt_title_ssh_auth) {
- if (it !is BiometricAuthenticator.Result.Failure) cont.resume(it)
- }
+ BiometricAuthenticator.authenticate(
+ callingActivity,
+ R.string.biometric_prompt_title_ssh_auth
+ ) { if (it !is BiometricAuthenticator.Result.Failure) cont.resume(it) }
}
}
when (result) {
@@ -193,7 +199,8 @@ abstract class GitOperation(protected val callingActivity: FragmentActivity) {
}
AuthMode.OpenKeychain -> registerAuthProviders(SshAuthMethod.OpenKeychain(authActivity))
AuthMode.Password -> {
- val httpsCredentialProvider = HttpsCredentialsProvider(CredentialFinder(callingActivity, AuthMode.Password))
+ val httpsCredentialProvider =
+ HttpsCredentialsProvider(CredentialFinder(callingActivity, AuthMode.Password))
registerAuthProviders(SshAuthMethod.Password(authActivity), httpsCredentialProvider)
}
AuthMode.None -> {}
diff --git a/app/src/main/java/dev/msfjarvis/aps/util/git/operation/PushOperation.kt b/app/src/main/java/dev/msfjarvis/aps/util/git/operation/PushOperation.kt
index a9f168ad..14f16164 100644
--- a/app/src/main/java/dev/msfjarvis/aps/util/git/operation/PushOperation.kt
+++ b/app/src/main/java/dev/msfjarvis/aps/util/git/operation/PushOperation.kt
@@ -7,7 +7,8 @@ package dev.msfjarvis.aps.util.git.operation
import dev.msfjarvis.aps.util.git.sshj.ContinuationContainerActivity
import org.eclipse.jgit.api.GitCommand
-class PushOperation(callingActivity: ContinuationContainerActivity) : GitOperation(callingActivity) {
+class PushOperation(callingActivity: ContinuationContainerActivity) :
+ GitOperation(callingActivity) {
override val commands: Array<GitCommand<out Any>> =
arrayOf(
diff --git a/app/src/main/java/dev/msfjarvis/aps/util/git/operation/ResetToRemoteOperation.kt b/app/src/main/java/dev/msfjarvis/aps/util/git/operation/ResetToRemoteOperation.kt
index dccd69b0..16114f65 100644
--- a/app/src/main/java/dev/msfjarvis/aps/util/git/operation/ResetToRemoteOperation.kt
+++ b/app/src/main/java/dev/msfjarvis/aps/util/git/operation/ResetToRemoteOperation.kt
@@ -7,7 +7,8 @@ package dev.msfjarvis.aps.util.git.operation
import dev.msfjarvis.aps.util.git.sshj.ContinuationContainerActivity
import org.eclipse.jgit.api.ResetCommand
-class ResetToRemoteOperation(callingActivity: ContinuationContainerActivity) : GitOperation(callingActivity) {
+class ResetToRemoteOperation(callingActivity: ContinuationContainerActivity) :
+ GitOperation(callingActivity) {
override val commands =
arrayOf(
diff --git a/app/src/main/java/dev/msfjarvis/aps/util/git/sshj/OpenKeychainKeyProvider.kt b/app/src/main/java/dev/msfjarvis/aps/util/git/sshj/OpenKeychainKeyProvider.kt
index acb7d8d7..d726c353 100644
--- a/app/src/main/java/dev/msfjarvis/aps/util/git/sshj/OpenKeychainKeyProvider.kt
+++ b/app/src/main/java/dev/msfjarvis/aps/util/git/sshj/OpenKeychainKeyProvider.kt
@@ -106,7 +106,8 @@ class OpenKeychainKeyProvider private constructor(val activity: ContinuationCont
val response = sshPublicKeyResponse.response as SshPublicKeyResponse
val sshPublicKey = response.sshPublicKey!!
publicKey =
- parseSshPublicKey(sshPublicKey) ?: throw IllegalStateException("OpenKeychain API returned invalid SSH key")
+ parseSshPublicKey(sshPublicKey)
+ ?: throw IllegalStateException("OpenKeychain API returned invalid SSH key")
}
is ApiResponse.NoSuchKey ->
if (isRetry) {
@@ -122,13 +123,17 @@ class OpenKeychainKeyProvider private constructor(val activity: ContinuationCont
private suspend fun selectKey() {
when (val keySelectionResponse = executeApiRequest(KeySelectionRequest())) {
- is ApiResponse.Success -> keyId = (keySelectionResponse.response as KeySelectionResponse).keyId
+ is ApiResponse.Success ->
+ keyId = (keySelectionResponse.response as KeySelectionResponse).keyId
is ApiResponse.GeneralError -> throw keySelectionResponse.exception
is ApiResponse.NoSuchKey -> throw keySelectionResponse.exception
}
}
- private suspend fun executeApiRequest(request: Request, resultOfUserInteraction: Intent? = null): ApiResponse {
+ private suspend fun executeApiRequest(
+ request: Request,
+ resultOfUserInteraction: Intent? = null
+ ): ApiResponse {
d { "executeRequest($request) called" }
val result =
withContext(Dispatchers.Main) {
@@ -141,7 +146,11 @@ class OpenKeychainKeyProvider private constructor(val activity: ContinuationCont
}
private suspend fun parseResult(request: Request, result: Intent): ApiResponse {
- return when (result.getIntExtra(SshAuthenticationApi.EXTRA_RESULT_CODE, SshAuthenticationApi.RESULT_CODE_ERROR)) {
+ return when (result.getIntExtra(
+ SshAuthenticationApi.EXTRA_RESULT_CODE,
+ SshAuthenticationApi.RESULT_CODE_ERROR
+ )
+ ) {
SshAuthenticationApi.RESULT_CODE_SUCCESS -> {
ApiResponse.Success(
when (request) {
@@ -153,20 +162,27 @@ class OpenKeychainKeyProvider private constructor(val activity: ContinuationCont
)
}
SshAuthenticationApi.RESULT_CODE_USER_INTERACTION_REQUIRED -> {
- val pendingIntent: PendingIntent = result.getParcelableExtra(SshAuthenticationApi.EXTRA_PENDING_INTENT)!!
+ val pendingIntent: PendingIntent =
+ result.getParcelableExtra(SshAuthenticationApi.EXTRA_PENDING_INTENT)!!
val resultOfUserInteraction: Intent =
withContext(Dispatchers.Main) {
suspendCoroutine { cont ->
activity.stashedCont = cont
- activity.continueAfterUserInteraction.launch(IntentSenderRequest.Builder(pendingIntent).build())
+ activity.continueAfterUserInteraction.launch(
+ IntentSenderRequest.Builder(pendingIntent).build()
+ )
}
}
executeApiRequest(request, resultOfUserInteraction)
}
else -> {
- val error = result.getParcelableExtra<SshAuthenticationApiError>(SshAuthenticationApi.EXTRA_ERROR)
+ val error =
+ result.getParcelableExtra<SshAuthenticationApiError>(SshAuthenticationApi.EXTRA_ERROR)
val exception =
- UserAuthException(DisconnectReason.UNKNOWN, "Request ${request::class.simpleName} failed: ${error?.message}")
+ UserAuthException(
+ DisconnectReason.UNKNOWN,
+ "Request ${request::class.simpleName} failed: ${error?.message}"
+ )
when (error?.error) {
SshAuthenticationApiError.NO_AUTH_KEY, SshAuthenticationApiError.NO_SUCH_KEY ->
ApiResponse.NoSuchKey(exception)
@@ -181,7 +197,9 @@ class OpenKeychainKeyProvider private constructor(val activity: ContinuationCont
privateKey =
object : OpenKeychainPrivateKey {
override suspend fun sign(challenge: ByteArray, hashAlgorithm: Int) =
- when (val signingResponse = executeApiRequest(SigningRequest(challenge, keyId, hashAlgorithm))) {
+ when (val signingResponse =
+ executeApiRequest(SigningRequest(challenge, keyId, hashAlgorithm))
+ ) {
is ApiResponse.Success -> (signingResponse.response as SigningResponse).signature
is ApiResponse.GeneralError -> throw signingResponse.exception
is ApiResponse.NoSuchKey -> throw signingResponse.exception
diff --git a/app/src/main/java/dev/msfjarvis/aps/util/git/sshj/OpenKeychainWrappedKeyAlgorithmFactory.kt b/app/src/main/java/dev/msfjarvis/aps/util/git/sshj/OpenKeychainWrappedKeyAlgorithmFactory.kt
index 0ab01ba5..56831b1d 100644
--- a/app/src/main/java/dev/msfjarvis/aps/util/git/sshj/OpenKeychainWrappedKeyAlgorithmFactory.kt
+++ b/app/src/main/java/dev/msfjarvis/aps/util/git/sshj/OpenKeychainWrappedKeyAlgorithmFactory.kt
@@ -28,7 +28,8 @@ class OpenKeychainWrappedKeyAlgorithmFactory(private val factory: Factory.Named<
override fun create() = OpenKeychainWrappedKeyAlgorithm(factory.create())
}
-class OpenKeychainWrappedKeyAlgorithm(private val keyAlgorithm: KeyAlgorithm) : KeyAlgorithm by keyAlgorithm {
+class OpenKeychainWrappedKeyAlgorithm(private val keyAlgorithm: KeyAlgorithm) :
+ KeyAlgorithm by keyAlgorithm {
private val hashAlgorithm =
when (keyAlgorithm.keyAlgorithm) {
@@ -39,11 +40,14 @@ class OpenKeychainWrappedKeyAlgorithm(private val keyAlgorithm: KeyAlgorithm) :
else -> SshAuthenticationApi.SHA512
}
- override fun newSignature() = OpenKeychainWrappedSignature(keyAlgorithm.newSignature(), hashAlgorithm)
+ override fun newSignature() =
+ OpenKeychainWrappedSignature(keyAlgorithm.newSignature(), hashAlgorithm)
}
-class OpenKeychainWrappedSignature(private val wrappedSignature: Signature, private val hashAlgorithm: Int) :
- Signature by wrappedSignature {
+class OpenKeychainWrappedSignature(
+ private val wrappedSignature: Signature,
+ private val hashAlgorithm: Int
+) : Signature by wrappedSignature {
private val data = ByteArrayOutputStream()
diff --git a/app/src/main/java/dev/msfjarvis/aps/util/git/sshj/SshKey.kt b/app/src/main/java/dev/msfjarvis/aps/util/git/sshj/SshKey.kt
index 37414707..3d23658e 100644
--- a/app/src/main/java/dev/msfjarvis/aps/util/git/sshj/SshKey.kt
+++ b/app/src/main/java/dev/msfjarvis/aps/util/git/sshj/SshKey.kt
@@ -115,7 +115,8 @@ object SshKey {
private var type: Type?
get() = Type.fromValue(context.sharedPrefs.getString(PreferenceKeys.GIT_REMOTE_KEY_TYPE))
- set(value) = context.sharedPrefs.edit { putString(PreferenceKeys.GIT_REMOTE_KEY_TYPE, value?.value) }
+ set(value) =
+ context.sharedPrefs.edit { putString(PreferenceKeys.GIT_REMOTE_KEY_TYPE, value?.value) }
private val isStrongBoxSupported by lazy(LazyThreadSafetyMode.NONE) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P)
@@ -138,13 +139,20 @@ object SshKey {
}
}
- enum class Algorithm(val algorithm: String, val applyToSpec: KeyGenParameterSpec.Builder.() -> Unit) {
+ enum class Algorithm(
+ val algorithm: String,
+ val applyToSpec: KeyGenParameterSpec.Builder.() -> Unit
+ ) {
Rsa(
KeyProperties.KEY_ALGORITHM_RSA,
{
setKeySize(3072)
setSignaturePaddings(KeyProperties.SIGNATURE_PADDING_RSA_PKCS1)
- setDigests(KeyProperties.DIGEST_SHA1, KeyProperties.DIGEST_SHA256, KeyProperties.DIGEST_SHA512)
+ setDigests(
+ KeyProperties.DIGEST_SHA1,
+ KeyProperties.DIGEST_SHA256,
+ KeyProperties.DIGEST_SHA512
+ )
}
),
Ecdsa(
@@ -163,7 +171,9 @@ object SshKey {
private fun delete() {
androidKeystore.deleteEntry(KEYSTORE_ALIAS)
// Remove Tink key set used by AndroidX's EncryptedFile.
- context.getSharedPreferences(ANDROIDX_SECURITY_KEYSET_PREF_NAME, Context.MODE_PRIVATE).edit { clear() }
+ context.getSharedPreferences(ANDROIDX_SECURITY_KEYSET_PREF_NAME, Context.MODE_PRIVATE).edit {
+ clear()
+ }
if (privateKeyFile.isFile) {
privateKeyFile.delete()
}
@@ -177,7 +187,8 @@ object SshKey {
fun import(uri: Uri) {
// First check whether the content at uri is likely an SSH private key.
val fileSize =
- context.contentResolver.query(uri, arrayOf(OpenableColumns.SIZE), null, null, null)?.use { cursor ->
+ context.contentResolver.query(uri, arrayOf(OpenableColumns.SIZE), null, null, null)?.use {
+ cursor ->
// Cursor returns only a single row.
cursor.moveToFirst()
cursor.getInt(0)
@@ -186,7 +197,9 @@ object SshKey {
// We assume that an SSH key's ideal size is > 0 bytes && < 100 kilobytes.
if (fileSize > 100_000 || fileSize == 0)
- throw IllegalArgumentException(context.getString(R.string.ssh_key_import_error_not_an_ssh_key_message))
+ throw IllegalArgumentException(
+ context.getString(R.string.ssh_key_import_error_not_an_ssh_key_message)
+ )
val sshKeyInputStream =
context.contentResolver.openInputStream(uri)
@@ -199,7 +212,9 @@ object SshKey {
!Regex("BEGIN .* PRIVATE KEY").containsMatchIn(lines.first()) ||
!Regex("END .* PRIVATE KEY").containsMatchIn(lines.last())
)
- throw IllegalArgumentException(context.getString(R.string.ssh_key_import_error_not_an_ssh_key_message))
+ throw IllegalArgumentException(
+ context.getString(R.string.ssh_key_import_error_not_an_ssh_key_message)
+ )
// At this point, we are reasonably confident that we have actually been provided a private
// key and delete the old key.
@@ -249,7 +264,9 @@ object SshKey {
val encryptedPrivateKeyFile = getOrCreateWrappedPrivateKeyFile(requireAuthentication)
// Generate the ed25519 key pair and encrypt the private key.
val keyPair = net.i2p.crypto.eddsa.KeyPairGenerator().generateKeyPair()
- encryptedPrivateKeyFile.openFileOutput().use { os -> os.write((keyPair.private as EdDSAPrivateKey).seed) }
+ encryptedPrivateKeyFile.openFileOutput().use { os ->
+ os.write((keyPair.private as EdDSAPrivateKey).seed)
+ }
// Write public key in SSH format to .ssh_key.pub.
publicKeyFile.writeText(toSshPublicKey(keyPair.public))
@@ -288,7 +305,8 @@ object SshKey {
fun provide(client: SSHClient, passphraseFinder: InteractivePasswordFinder): KeyProvider? =
when (type) {
- Type.LegacyGenerated, Type.Imported -> client.loadKeys(privateKeyFile.absolutePath, passphraseFinder)
+ Type.LegacyGenerated, Type.Imported ->
+ client.loadKeys(privateKeyFile.absolutePath, passphraseFinder)
Type.KeystoreNative -> KeystoreNativeKeyProvider
Type.KeystoreWrappedEd25519 -> KeystoreWrappedEd25519KeyProvider
null -> null
@@ -305,7 +323,10 @@ object SshKey {
override fun getPrivate(): PrivateKey =
runCatching { androidKeystore.sshPrivateKey!! }.getOrElse { error ->
e(error)
- throw IOException("Failed to access private key '$KEYSTORE_ALIAS' from Android Keystore", error)
+ throw IOException(
+ "Failed to access private key '$KEYSTORE_ALIAS' from Android Keystore",
+ error
+ )
}
override fun getType(): KeyType = KeyType.fromKey(public)
@@ -326,7 +347,9 @@ object SshKey {
// for `requireAuthentication` is not used as the key already exists at this point.
val encryptedPrivateKeyFile = runBlocking { getOrCreateWrappedPrivateKeyFile(false) }
val rawPrivateKey = encryptedPrivateKeyFile.openFileInput().use { it.readBytes() }
- EdDSAPrivateKey(EdDSAPrivateKeySpec(rawPrivateKey, EdDSANamedCurveTable.ED_25519_CURVE_SPEC))
+ EdDSAPrivateKey(
+ EdDSAPrivateKeySpec(rawPrivateKey, EdDSANamedCurveTable.ED_25519_CURVE_SPEC)
+ )
}
.getOrElse { error ->
e(error)
diff --git a/app/src/main/java/dev/msfjarvis/aps/util/git/sshj/SshjConfig.kt b/app/src/main/java/dev/msfjarvis/aps/util/git/sshj/SshjConfig.kt
index e93787f4..f8053ef3 100644
--- a/app/src/main/java/dev/msfjarvis/aps/util/git/sshj/SshjConfig.kt
+++ b/app/src/main/java/dev/msfjarvis/aps/util/git/sshj/SshjConfig.kt
@@ -37,7 +37,8 @@ fun setUpBouncyCastleForSshj() {
// Replace the Android BC provider with the Java BouncyCastle provider since the former does
// not include all the required algorithms.
// Note: This may affect crypto operations in other parts of the application.
- val bcIndex = Security.getProviders().indexOfFirst { it.name == BouncyCastleProvider.PROVIDER_NAME }
+ val bcIndex =
+ Security.getProviders().indexOfFirst { it.name == BouncyCastleProvider.PROVIDER_NAME }
if (bcIndex == -1) {
// No Android BC found, install Java BC at lowest priority.
Security.addProvider(BouncyCastleProvider())
@@ -77,9 +78,11 @@ private abstract class AbstractLogger(private val name: String) : Logger {
override fun trace(msg: String, t: Throwable?) = t(msg, t)
override fun trace(marker: Marker, msg: String) = trace(msg)
override fun trace(marker: Marker?, format: String, arg: Any?) = trace(format, arg)
- override fun trace(marker: Marker?, format: String, arg1: Any?, arg2: Any?) = trace(format, arg1, arg2)
+ override fun trace(marker: Marker?, format: String, arg1: Any?, arg2: Any?) =
+ trace(format, arg1, arg2)
- override fun trace(marker: Marker?, format: String, vararg arguments: Any?) = trace(format, *arguments)
+ override fun trace(marker: Marker?, format: String, vararg arguments: Any?) =
+ trace(format, *arguments)
override fun trace(marker: Marker?, msg: String, t: Throwable?) = trace(msg, t)
@@ -90,9 +93,11 @@ private abstract class AbstractLogger(private val name: String) : Logger {
override fun debug(msg: String, t: Throwable?) = d(msg, t)
override fun debug(marker: Marker, msg: String) = debug(msg)
override fun debug(marker: Marker?, format: String, arg: Any?) = debug(format, arg)
- override fun debug(marker: Marker?, format: String, arg1: Any?, arg2: Any?) = debug(format, arg1, arg2)
+ override fun debug(marker: Marker?, format: String, arg1: Any?, arg2: Any?) =
+ debug(format, arg1, arg2)
- override fun debug(marker: Marker?, format: String, vararg arguments: Any?) = debug(format, *arguments)
+ override fun debug(marker: Marker?, format: String, vararg arguments: Any?) =
+ debug(format, *arguments)
override fun debug(marker: Marker?, msg: String, t: Throwable?) = debug(msg, t)
@@ -103,9 +108,11 @@ private abstract class AbstractLogger(private val name: String) : Logger {
override fun info(msg: String, t: Throwable?) = i(msg, t)
override fun info(marker: Marker, msg: String) = info(msg)
override fun info(marker: Marker?, format: String, arg: Any?) = info(format, arg)
- override fun info(marker: Marker?, format: String, arg1: Any?, arg2: Any?) = info(format, arg1, arg2)
+ override fun info(marker: Marker?, format: String, arg1: Any?, arg2: Any?) =
+ info(format, arg1, arg2)
- override fun info(marker: Marker?, format: String, vararg arguments: Any?) = info(format, *arguments)
+ override fun info(marker: Marker?, format: String, vararg arguments: Any?) =
+ info(format, *arguments)
override fun info(marker: Marker?, msg: String, t: Throwable?) = info(msg, t)
@@ -116,9 +123,11 @@ private abstract class AbstractLogger(private val name: String) : Logger {
override fun warn(msg: String, t: Throwable?) = w(msg, t)
override fun warn(marker: Marker, msg: String) = warn(msg)
override fun warn(marker: Marker?, format: String, arg: Any?) = warn(format, arg)
- override fun warn(marker: Marker?, format: String, arg1: Any?, arg2: Any?) = warn(format, arg1, arg2)
+ override fun warn(marker: Marker?, format: String, arg1: Any?, arg2: Any?) =
+ warn(format, arg1, arg2)
- override fun warn(marker: Marker?, format: String, vararg arguments: Any?) = warn(format, *arguments)
+ override fun warn(marker: Marker?, format: String, vararg arguments: Any?) =
+ warn(format, *arguments)
override fun warn(marker: Marker?, msg: String, t: Throwable?) = warn(msg, t)
@@ -129,9 +138,11 @@ private abstract class AbstractLogger(private val name: String) : Logger {
override fun error(msg: String, t: Throwable?) = e(msg, t)
override fun error(marker: Marker, msg: String) = error(msg)
override fun error(marker: Marker?, format: String, arg: Any?) = error(format, arg)
- override fun error(marker: Marker?, format: String, arg1: Any?, arg2: Any?) = error(format, arg1, arg2)
+ override fun error(marker: Marker?, format: String, arg1: Any?, arg2: Any?) =
+ error(format, arg1, arg2)
- override fun error(marker: Marker?, format: String, vararg arguments: Any?) = error(format, *arguments)
+ override fun error(marker: Marker?, format: String, vararg arguments: Any?) =
+ error(format, *arguments)
override fun error(marker: Marker?, msg: String, t: Throwable?) = error(msg, t)
}
@@ -148,7 +159,8 @@ object TimberLoggerFactory : LoggerFactory {
// Replace slf4j's "{}" format string style with standard Java's "%s".
// The supposedly redundant escape on the } is not redundant.
- @Suppress("RegExpRedundantEscape") private fun String.fix() = replace("""(?!<\\)\{\}""".toRegex(), "%s")
+ @Suppress("RegExpRedundantEscape")
+ private fun String.fix() = replace("""(?!<\\)\{\}""".toRegex(), "%s")
override fun t(message: String, t: Throwable?, vararg args: Any?) {
Timber.tag(name).v(t, message.fix(), *args)
diff --git a/app/src/main/java/dev/msfjarvis/aps/util/git/sshj/SshjSessionFactory.kt b/app/src/main/java/dev/msfjarvis/aps/util/git/sshj/SshjSessionFactory.kt
index 95676d7f..bc068f52 100644
--- a/app/src/main/java/dev/msfjarvis/aps/util/git/sshj/SshjSessionFactory.kt
+++ b/app/src/main/java/dev/msfjarvis/aps/util/git/sshj/SshjSessionFactory.kt
@@ -52,7 +52,10 @@ abstract class InteractivePasswordFinder : PasswordFinder {
abstract fun askForPassword(cont: Continuation<String?>, isRetry: Boolean)
final override fun reqPassword(resource: Resource<*>?): CharArray {
- val password = runBlocking(Dispatchers.Main) { suspendCoroutine<String?> { cont -> askForPassword(cont, isRetry) } }
+ val password =
+ runBlocking(Dispatchers.Main) {
+ suspendCoroutine<String?> { cont -> askForPassword(cont, isRetry) }
+ }
isRetry = true
return password?.toCharArray() ?: throw SSHException(DisconnectReason.AUTH_CANCELLED_BY_USER)
}
@@ -60,11 +63,17 @@ abstract class InteractivePasswordFinder : PasswordFinder {
final override fun shouldRetry(resource: Resource<*>?) = true
}
-class SshjSessionFactory(private val authMethod: SshAuthMethod, private val hostKeyFile: File) : SshSessionFactory() {
+class SshjSessionFactory(private val authMethod: SshAuthMethod, private val hostKeyFile: File) :
+ SshSessionFactory() {
private var currentSession: SshjSession? = null
- override fun getSession(uri: URIish, credentialsProvider: CredentialsProvider?, fs: FS?, tms: Int): RemoteSession {
+ override fun getSession(
+ uri: URIish,
+ credentialsProvider: CredentialsProvider?,
+ fs: FS?,
+ tms: Int
+ ): RemoteSession {
return currentSession
?: SshjSession(uri, uri.user, authMethod, hostKeyFile).connect().also {
d { "New SSH connection created" }
@@ -81,7 +90,9 @@ private fun makeTofuHostKeyVerifier(hostKeyFile: File): HostKeyVerifier {
if (!hostKeyFile.exists()) {
return HostKeyVerifier { _, _, key ->
val digest =
- runCatching { SecurityUtils.getMessageDigest("SHA-256") }.getOrElse { e -> throw SSHRuntimeException(e) }
+ runCatching { SecurityUtils.getMessageDigest("SHA-256") }.getOrElse { e ->
+ throw SSHRuntimeException(e)
+ }
digest.update(PlainBuffer().putPublicKey(key).compactData)
val digestData = digest.digest()
val hostKeyEntry = "SHA256:${Base64.encodeToString(digestData, Base64.NO_WRAP)}"
@@ -115,7 +126,9 @@ private class SshjSession(
val userPlusHost = "${uri.user}@${uri.host}"
val realUser = userPlusHost.substringBeforeLast('@')
val realHost = userPlusHost.substringAfterLast('@')
- uri.setUser(realUser).setHost(realHost).also { d { "After fixup: user=${it.user}, host=${it.host}" } }
+ uri.setUser(realUser).setHost(realHost).also {
+ d { "After fixup: user=${it.user}, host=${it.host}" }
+ }
} else {
uri
}
@@ -131,7 +144,8 @@ private class SshjSession(
ssh.auth(username, passwordAuth)
}
is SshAuthMethod.SshKey -> {
- val pubkeyAuth = AuthPublickey(SshKey.provide(ssh, CredentialFinder(authMethod.activity, AuthMode.SshKey)))
+ val pubkeyAuth =
+ AuthPublickey(SshKey.provide(ssh, CredentialFinder(authMethod.activity, AuthMode.SshKey)))
ssh.auth(username, pubkeyAuth, passwordAuth)
}
is SshAuthMethod.OpenKeychain -> {
@@ -174,7 +188,8 @@ private class SshjSession(
}
}
-private class SshjProcess(private val command: Session.Command, private val timeout: Long) : Process() {
+private class SshjProcess(private val command: Session.Command, private val timeout: Long) :
+ Process() {
override fun waitFor(): Int {
command.join(timeout, TimeUnit.SECONDS)
diff --git a/app/src/main/java/dev/msfjarvis/aps/util/pwgen/PasswordGenerator.kt b/app/src/main/java/dev/msfjarvis/aps/util/pwgen/PasswordGenerator.kt
index 8199ebfc..bd21ea0a 100644
--- a/app/src/main/java/dev/msfjarvis/aps/util/pwgen/PasswordGenerator.kt
+++ b/app/src/main/java/dev/msfjarvis/aps/util/pwgen/PasswordGenerator.kt
@@ -42,7 +42,10 @@ object PasswordGenerator {
*/
fun setPrefs(ctx: Context, options: List<PasswordOption>, targetLength: Int): Boolean {
ctx.getSharedPreferences("PasswordGenerator", Context.MODE_PRIVATE).edit {
- for (possibleOption in PasswordOption.values()) putBoolean(possibleOption.key, possibleOption in options)
+ for (possibleOption in PasswordOption.values()) putBoolean(
+ possibleOption.key,
+ possibleOption in options
+ )
putInt("length", targetLength)
}
return true
@@ -82,7 +85,9 @@ object PasswordGenerator {
} else {
// The No* options are false, so the respective character category will be included.
when (option) {
- PasswordOption.NoDigits, PasswordOption.NoUppercaseLetters, PasswordOption.NoLowercaseLetters -> {
+ PasswordOption.NoDigits,
+ PasswordOption.NoUppercaseLetters,
+ PasswordOption.NoLowercaseLetters -> {
numCharacterCategories++
}
PasswordOption.NoAmbiguousCharacters,
@@ -98,7 +103,9 @@ object PasswordGenerator {
throw PasswordGeneratorException(ctx.resources.getString(R.string.pwgen_no_chars_error))
}
if (length < numCharacterCategories) {
- throw PasswordGeneratorException(ctx.resources.getString(R.string.pwgen_length_too_short_error))
+ throw PasswordGeneratorException(
+ ctx.resources.getString(R.string.pwgen_length_too_short_error)
+ )
}
if (!(pwgenFlags hasFlag UPPERS) && !(pwgenFlags hasFlag LOWERS)) {
phonemes = false
@@ -114,7 +121,9 @@ object PasswordGenerator {
var iterations = 0
do {
if (iterations++ > 1000)
- throw PasswordGeneratorException(ctx.resources.getString(R.string.pwgen_max_iterations_exceeded))
+ throw PasswordGeneratorException(
+ ctx.resources.getString(R.string.pwgen_max_iterations_exceeded)
+ )
password =
if (phonemes) {
RandomPhonemesGenerator.generate(length, pwgenFlags)
diff --git a/app/src/main/java/dev/msfjarvis/aps/util/pwgen/RandomPasswordGenerator.kt b/app/src/main/java/dev/msfjarvis/aps/util/pwgen/RandomPasswordGenerator.kt
index e92a753b..c1a8aeb1 100644
--- a/app/src/main/java/dev/msfjarvis/aps/util/pwgen/RandomPasswordGenerator.kt
+++ b/app/src/main/java/dev/msfjarvis/aps/util/pwgen/RandomPasswordGenerator.kt
@@ -36,7 +36,9 @@ object RandomPasswordGenerator {
var password = ""
while (password.length < targetLength) {
val candidate = bank.secureRandomCharacter()
- if (pwFlags hasFlag PasswordGenerator.NO_AMBIGUOUS && candidate in PasswordGenerator.AMBIGUOUS_STR) {
+ if (pwFlags hasFlag PasswordGenerator.NO_AMBIGUOUS &&
+ candidate in PasswordGenerator.AMBIGUOUS_STR
+ ) {
continue
}
password += candidate
diff --git a/app/src/main/java/dev/msfjarvis/aps/util/pwgen/RandomPhonemesGenerator.kt b/app/src/main/java/dev/msfjarvis/aps/util/pwgen/RandomPhonemesGenerator.kt
index 0b8ca872..5a5f5f21 100644
--- a/app/src/main/java/dev/msfjarvis/aps/util/pwgen/RandomPhonemesGenerator.kt
+++ b/app/src/main/java/dev/msfjarvis/aps/util/pwgen/RandomPhonemesGenerator.kt
@@ -100,7 +100,9 @@ object RandomPhonemesGenerator {
if (!candidate.flags.hasFlag(nextBasicType) ||
(isStartOfPart && candidate.flags hasFlag NOT_FIRST) ||
// Don't let a diphthong that starts with a vowel follow a vowel.
- (previousFlags hasFlag VOWEL && candidate.flags hasFlag VOWEL && candidate.flags hasFlag DIPHTHONG) ||
+ (previousFlags hasFlag VOWEL &&
+ candidate.flags hasFlag VOWEL &&
+ candidate.flags hasFlag DIPHTHONG) ||
// Don't add multi-character candidates if we would go over the targetLength.
(password.length + candidate.length > targetLength) ||
(pwFlags hasFlag PasswordGenerator.NO_AMBIGUOUS && candidate.isAmbiguous)
@@ -129,11 +131,15 @@ object RandomPhonemesGenerator {
// Second part: Add digits and symbols with a certain probability (if requested) if
// they would not directly follow the first character in a pronounceable part.
- if (!isStartOfPart && pwFlags hasFlag PasswordGenerator.DIGITS && secureRandomBiasedBoolean(30)) {
+ if (!isStartOfPart &&
+ pwFlags hasFlag PasswordGenerator.DIGITS &&
+ secureRandomBiasedBoolean(30)
+ ) {
var randomDigit: Char
do {
randomDigit = secureRandomNumber(10).toString(10).first()
- } while (pwFlags hasFlag PasswordGenerator.NO_AMBIGUOUS && randomDigit in PasswordGenerator.AMBIGUOUS_STR)
+ } while (pwFlags hasFlag PasswordGenerator.NO_AMBIGUOUS &&
+ randomDigit in PasswordGenerator.AMBIGUOUS_STR)
password += randomDigit
// Begin a new pronounceable part after every digit.
@@ -143,11 +149,15 @@ object RandomPhonemesGenerator {
continue
}
- if (!isStartOfPart && pwFlags hasFlag PasswordGenerator.SYMBOLS && secureRandomBiasedBoolean(20)) {
+ if (!isStartOfPart &&
+ pwFlags hasFlag PasswordGenerator.SYMBOLS &&
+ secureRandomBiasedBoolean(20)
+ ) {
var randomSymbol: Char
do {
randomSymbol = PasswordGenerator.SYMBOLS_STR.secureRandomCharacter()
- } while (pwFlags hasFlag PasswordGenerator.NO_AMBIGUOUS && randomSymbol in PasswordGenerator.AMBIGUOUS_STR)
+ } while (pwFlags hasFlag PasswordGenerator.NO_AMBIGUOUS &&
+ randomSymbol in PasswordGenerator.AMBIGUOUS_STR)
password += randomSymbol
// Continue the password generation as if nothing was added.
}
@@ -157,8 +167,9 @@ object RandomPhonemesGenerator {
nextBasicType =
when {
candidate.flags.hasFlag(CONSONANT) -> VOWEL
- previousFlags.hasFlag(VOWEL) || candidate.flags.hasFlag(DIPHTHONG) || secureRandomBiasedBoolean(60) ->
- CONSONANT
+ previousFlags.hasFlag(VOWEL) ||
+ candidate.flags.hasFlag(DIPHTHONG) ||
+ secureRandomBiasedBoolean(60) -> CONSONANT
else -> VOWEL
}
previousFlags = candidate.flags
diff --git a/app/src/main/java/dev/msfjarvis/aps/util/pwgenxkpwd/PasswordBuilder.kt b/app/src/main/java/dev/msfjarvis/aps/util/pwgenxkpwd/PasswordBuilder.kt
index 3eb2cce7..af8ac5c2 100644
--- a/app/src/main/java/dev/msfjarvis/aps/util/pwgenxkpwd/PasswordBuilder.kt
+++ b/app/src/main/java/dev/msfjarvis/aps/util/pwgenxkpwd/PasswordBuilder.kt
@@ -109,7 +109,9 @@ class PasswordBuilder(ctx: Context) {
}
else candidate
CapsType.TitleCase ->
- candidate.replaceFirstChar { if (it.isLowerCase()) it.titlecase(Locale.getDefault()) else it.toString() }
+ candidate.replaceFirstChar {
+ if (it.isLowerCase()) it.titlecase(Locale.getDefault()) else it.toString()
+ }
CapsType.lowercase -> candidate.lowercase(Locale.getDefault())
CapsType.As_iS -> candidate
}
diff --git a/app/src/main/java/dev/msfjarvis/aps/util/pwgenxkpwd/XkpwdDictionary.kt b/app/src/main/java/dev/msfjarvis/aps/util/pwgenxkpwd/XkpwdDictionary.kt
index ab31892f..25162378 100644
--- a/app/src/main/java/dev/msfjarvis/aps/util/pwgenxkpwd/XkpwdDictionary.kt
+++ b/app/src/main/java/dev/msfjarvis/aps/util/pwgenxkpwd/XkpwdDictionary.kt
@@ -30,7 +30,10 @@ class XkpwdDictionary(context: Context) {
context.resources.openRawResource(R.raw.xkpwdict).bufferedReader().readLines()
}
- words = lines.asSequence().map { it.trim() }.filter { it.isNotEmpty() && !it.contains(' ') }.groupBy { it.length }
+ words =
+ lines.asSequence().map { it.trim() }.filter { it.isNotEmpty() && !it.contains(' ') }.groupBy {
+ it.length
+ }
}
companion object {
diff --git a/app/src/main/java/dev/msfjarvis/aps/util/services/ClipboardService.kt b/app/src/main/java/dev/msfjarvis/aps/util/services/ClipboardService.kt
index d25a110e..de7d727c 100644
--- a/app/src/main/java/dev/msfjarvis/aps/util/services/ClipboardService.kt
+++ b/app/src/main/java/dev/msfjarvis/aps/util/services/ClipboardService.kt
@@ -140,7 +140,10 @@ class ClipboardService : Service() {
}
@RequiresApi(Build.VERSION_CODES.N)
- private fun createNotificationApi24(pendingIntent: PendingIntent, clearTimeMs: Long): Notification {
+ private fun createNotificationApi24(
+ pendingIntent: PendingIntent,
+ clearTimeMs: Long
+ ): Notification {
return NotificationCompat.Builder(this, CHANNEL_ID)
.setContentTitle(getString(R.string.app_name))
.setContentText(getString(R.string.tap_clear_clipboard))
@@ -157,7 +160,11 @@ class ClipboardService : Service() {
private fun createNotificationChannel() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
val serviceChannel =
- NotificationChannel(CHANNEL_ID, getString(R.string.app_name), NotificationManager.IMPORTANCE_LOW)
+ NotificationChannel(
+ CHANNEL_ID,
+ getString(R.string.app_name),
+ NotificationManager.IMPORTANCE_LOW
+ )
val manager = getSystemService<NotificationManager>()
if (manager != null) {
manager.createNotificationChannel(serviceChannel)
diff --git a/app/src/main/java/dev/msfjarvis/aps/util/services/OreoAutofillService.kt b/app/src/main/java/dev/msfjarvis/aps/util/services/OreoAutofillService.kt
index ce55fe7b..4c75a619 100644
--- a/app/src/main/java/dev/msfjarvis/aps/util/services/OreoAutofillService.kt
+++ b/app/src/main/java/dev/msfjarvis/aps/util/services/OreoAutofillService.kt
@@ -60,7 +60,11 @@ class OreoAutofillService : AutofillService() {
cachePublicSuffixList(applicationContext)
}
- override fun onFillRequest(request: FillRequest, cancellationSignal: CancellationSignal, callback: FillCallback) {
+ override fun onFillRequest(
+ request: FillRequest,
+ cancellationSignal: CancellationSignal,
+ callback: FillCallback
+ ) {
val structure =
request.fillContexts.lastOrNull()?.structure
?: run {
@@ -93,7 +97,8 @@ class OreoAutofillService : AutofillService() {
return
}
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
- Api30AutofillResponseBuilder(formToFill).fillCredentials(this, request.inlineSuggestionsRequest, callback)
+ Api30AutofillResponseBuilder(formToFill)
+ .fillCredentials(this, request.inlineSuggestionsRequest, callback)
} else {
AutofillResponseBuilder(formToFill).fillCredentials(this, callback)
}
@@ -148,11 +153,13 @@ class OreoAutofillService : AutofillService() {
}
}
-fun Context.getDefaultUsername() = sharedPrefs.getString(PreferenceKeys.OREO_AUTOFILL_DEFAULT_USERNAME)
+fun Context.getDefaultUsername() =
+ sharedPrefs.getString(PreferenceKeys.OREO_AUTOFILL_DEFAULT_USERNAME)
fun Context.getCustomSuffixes(): Sequence<String> {
- return sharedPrefs.getString(PreferenceKeys.OREO_AUTOFILL_CUSTOM_PUBLIC_SUFFIXES)?.splitToSequence('\n')?.filter {
- it.isNotBlank() && it.first() != '.' && it.last() != '.'
- }
+ return sharedPrefs
+ .getString(PreferenceKeys.OREO_AUTOFILL_CUSTOM_PUBLIC_SUFFIXES)
+ ?.splitToSequence('\n')
+ ?.filter { it.isNotBlank() && it.first() != '.' && it.last() != '.' }
?: emptySequence()
}
diff --git a/app/src/main/java/dev/msfjarvis/aps/util/services/PasswordExportService.kt b/app/src/main/java/dev/msfjarvis/aps/util/services/PasswordExportService.kt
index 2ecd2287..72f14144 100644
--- a/app/src/main/java/dev/msfjarvis/aps/util/services/PasswordExportService.kt
+++ b/app/src/main/java/dev/msfjarvis/aps/util/services/PasswordExportService.kt
@@ -137,7 +137,11 @@ class PasswordExportService : Service() {
private fun createNotificationChannel() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
val serviceChannel =
- NotificationChannel(CHANNEL_ID, getString(R.string.app_name), NotificationManager.IMPORTANCE_LOW)
+ NotificationChannel(
+ CHANNEL_ID,
+ getString(R.string.app_name),
+ NotificationManager.IMPORTANCE_LOW
+ )
val manager = getSystemService<NotificationManager>()
if (manager != null) {
manager.createNotificationChannel(serviceChannel)
diff --git a/app/src/main/java/dev/msfjarvis/aps/util/settings/GitSettings.kt b/app/src/main/java/dev/msfjarvis/aps/util/settings/GitSettings.kt
index 3a508e45..d3c85fa7 100644
--- a/app/src/main/java/dev/msfjarvis/aps/util/settings/GitSettings.kt
+++ b/app/src/main/java/dev/msfjarvis/aps/util/settings/GitSettings.kt
@@ -25,7 +25,8 @@ enum class Protocol(val pref: String) {
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")
+ return map[type ?: return Ssh]
+ ?: throw IllegalArgumentException("$type is not a valid Protocol")
}
}
}
@@ -41,7 +42,8 @@ enum class AuthMode(val pref: String) {
private val map = values().associateBy(AuthMode::pref)
fun fromString(type: String?): AuthMode {
- return map[type ?: return SshKey] ?: throw IllegalArgumentException("$type is not a valid AuthMode")
+ return map[type ?: return SshKey]
+ ?: throw IllegalArgumentException("$type is not a valid AuthMode")
}
}
}
@@ -50,12 +52,18 @@ object GitSettings {
private const val DEFAULT_BRANCH = "master"
- private val settings by lazy(LazyThreadSafetyMode.PUBLICATION) { Application.instance.sharedPrefs }
+ 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) { "${Application.instance.filesDir}/.host_key" }
+ private val proxySettings by lazy(LazyThreadSafetyMode.PUBLICATION) {
+ Application.instance.getEncryptedProxyPrefs()
+ }
+ private val hostKeyPath by lazy(LazyThreadSafetyMode.NONE) {
+ "${Application.instance.filesDir}/.host_key"
+ }
var authMode
get() = AuthMode.fromString(settings.getString(PreferenceKeys.GIT_REMOTE_AUTH))
diff --git a/app/src/main/java/dev/msfjarvis/aps/util/settings/Migrations.kt b/app/src/main/java/dev/msfjarvis/aps/util/settings/Migrations.kt
index a5612603..b9333617 100644
--- a/app/src/main/java/dev/msfjarvis/aps/util/settings/Migrations.kt
+++ b/app/src/main/java/dev/msfjarvis/aps/util/settings/Migrations.kt
@@ -60,7 +60,8 @@ private fun migrateToGitUrlBasedConfig(sharedPrefs: SharedPreferences) {
val url =
when {
urlWithFreeEntryScheme.startsWith("https://") -> urlWithFreeEntryScheme
- urlWithFreeEntryScheme.startsWith("http://") -> urlWithFreeEntryScheme.replaceFirst("http", "https")
+ urlWithFreeEntryScheme.startsWith("http://") ->
+ urlWithFreeEntryScheme.replaceFirst("http", "https")
else -> "https://$urlWithFreeEntryScheme"
}
runCatching { if (URI(url).rawAuthority != null) url else null }.get()
@@ -96,7 +97,10 @@ private fun migrateToHideAll(sharedPrefs: SharedPreferences) {
private fun migrateToSshKey(context: Context, sharedPrefs: SharedPreferences) {
val privateKeyFile = File(context.filesDir, ".ssh_key")
- if (sharedPrefs.contains(PreferenceKeys.USE_GENERATED_KEY) && !SshKey.exists && privateKeyFile.exists()) {
+ if (sharedPrefs.contains(PreferenceKeys.USE_GENERATED_KEY) &&
+ !SshKey.exists &&
+ privateKeyFile.exists()
+ ) {
// Currently uses a private key imported or generated with an old version of Password Store.
// Generated keys come with a public key which the user should still be able to view after
// the migration (not possible for regular imported keys), hence the special case.
diff --git a/app/src/main/java/dev/msfjarvis/aps/util/settings/PasswordSortOrder.kt b/app/src/main/java/dev/msfjarvis/aps/util/settings/PasswordSortOrder.kt
index ee678de2..6b48b6a9 100644
--- a/app/src/main/java/dev/msfjarvis/aps/util/settings/PasswordSortOrder.kt
+++ b/app/src/main/java/dev/msfjarvis/aps/util/settings/PasswordSortOrder.kt
@@ -18,10 +18,15 @@ enum class PasswordSortOrder(val comparator: java.util.Comparator<PasswordItem>)
(p1.type + p1.name).compareTo(p2.type + p2.name, ignoreCase = true)
}
),
- INDEPENDENT(Comparator { p1: PasswordItem, p2: PasswordItem -> p1.name.compareTo(p2.name, ignoreCase = true) }),
+ INDEPENDENT(
+ Comparator { p1: PasswordItem, p2: PasswordItem ->
+ p1.name.compareTo(p2.name, ignoreCase = true)
+ }
+ ),
RECENTLY_USED(
Comparator { p1: PasswordItem, p2: PasswordItem ->
- val recentHistory = Application.instance.getSharedPreferences("recent_password_history", Context.MODE_PRIVATE)
+ val recentHistory =
+ Application.instance.getSharedPreferences("recent_password_history", Context.MODE_PRIVATE)
val timeP1 = recentHistory.getString(p1.file.absolutePath.base64())
val timeP2 = recentHistory.getString(p2.file.absolutePath.base64())
when {
diff --git a/app/src/main/java/dev/msfjarvis/aps/util/totp/UriTotpFinder.kt b/app/src/main/java/dev/msfjarvis/aps/util/totp/UriTotpFinder.kt
index 2e954804..fa8481a9 100644
--- a/app/src/main/java/dev/msfjarvis/aps/util/totp/UriTotpFinder.kt
+++ b/app/src/main/java/dev/msfjarvis/aps/util/totp/UriTotpFinder.kt
@@ -44,7 +44,8 @@ class UriTotpFinder @Inject constructor() : TotpFinder {
override fun findAlgorithm(content: String): String {
content.split("\n".toRegex()).forEach { line ->
- if (line.startsWith(TOTP_FIELDS[0]) && Uri.parse(line).getQueryParameter("algorithm") != null) {
+ if (line.startsWith(TOTP_FIELDS[0]) && Uri.parse(line).getQueryParameter("algorithm") != null
+ ) {
return Uri.parse(line).getQueryParameter("algorithm")!!
}
}
diff --git a/app/src/main/java/dev/msfjarvis/aps/util/viewmodel/SearchableRepositoryViewModel.kt b/app/src/main/java/dev/msfjarvis/aps/util/viewmodel/SearchableRepositoryViewModel.kt
index f0488537..7106dbe3 100644
--- a/app/src/main/java/dev/msfjarvis/aps/util/viewmodel/SearchableRepositoryViewModel.kt
+++ b/app/src/main/java/dev/msfjarvis/aps/util/viewmodel/SearchableRepositoryViewModel.kt
@@ -75,8 +75,14 @@ private fun PasswordItem.Companion.makeComparator(
PasswordSortOrder.FILE_FIRST -> compareByDescending { it.type }
PasswordSortOrder.RECENTLY_USED -> PasswordSortOrder.RECENTLY_USED.comparator
}
- .then(compareBy(nullsLast(CaseInsensitiveComparator)) { directoryStructure.getIdentifierFor(it.file) })
- .then(compareBy(nullsLast(CaseInsensitiveComparator)) { directoryStructure.getUsernameFor(it.file) })
+ .then(
+ compareBy(nullsLast(CaseInsensitiveComparator)) {
+ directoryStructure.getIdentifierFor(it.file)
+ }
+ )
+ .then(
+ compareBy(nullsLast(CaseInsensitiveComparator)) { directoryStructure.getUsernameFor(it.file) }
+ )
}
val PasswordItem.stableId: String
@@ -179,7 +185,8 @@ class SearchableRepositoryViewModel(application: Application) : AndroidViewModel
.mapLatest { searchAction ->
val listResultFlow =
when (searchAction.searchMode) {
- SearchMode.RecursivelyInSubdirectories -> listFilesRecursively(searchAction.baseDirectory)
+ SearchMode.RecursivelyInSubdirectories ->
+ listFilesRecursively(searchAction.baseDirectory)
SearchMode.InCurrentDirectoryOnly -> listFiles(searchAction.baseDirectory)
}
val prefilteredResultFlow =
@@ -188,9 +195,8 @@ class SearchableRepositoryViewModel(application: Application) : AndroidViewModel
ListMode.DirectoriesOnly -> listResultFlow.filter { it.isDirectory }
ListMode.AllEntries -> listResultFlow
}
- val filterModeToUse = if (searchAction.filter == "") FilterMode.NoFilter else searchAction.filterMode
val passwordList =
- when (filterModeToUse) {
+ when (if (searchAction.filter == "") FilterMode.NoFilter else searchAction.filterMode) {
FilterMode.NoFilter -> {
prefilteredResultFlow.map { it.toPasswordItem() }.toList().sortedWith(itemComparator)
}
@@ -201,7 +207,9 @@ class SearchableRepositoryViewModel(application: Application) : AndroidViewModel
val regex = generateStrictDomainRegex(searchAction.filter)
if (regex != null) {
prefilteredResultFlow
- .filter { absoluteFile -> regex.containsMatchIn(absoluteFile.relativeTo(root).path) }
+ .filter { absoluteFile ->
+ regex.containsMatchIn(absoluteFile.relativeTo(root).path)
+ }
.map { it.toPasswordItem() }
.toList()
.sortedWith(itemComparator)
@@ -218,7 +226,9 @@ class SearchableRepositoryViewModel(application: Application) : AndroidViewModel
.filter { it.first > 0 }
.toList()
.sortedWith(
- compareByDescending<Pair<Int, PasswordItem>> { it.first }.thenBy(itemComparator) { it.second }
+ compareByDescending<Pair<Int, PasswordItem>> { it.first }.thenBy(itemComparator) {
+ it.second
+ }
)
.map { it.second }
}
@@ -387,7 +397,9 @@ open class SearchableRepositoryAdapter<T : RecyclerView.ViewHolder>(
addObserver(
object : SelectionTracker.SelectionObserver<String>() {
override fun onSelectionChanged() {
- this@SearchableRepositoryAdapter.onSelectionChangedListener?.invoke(requireSelectionTracker().selection)
+ this@SearchableRepositoryAdapter.onSelectionChangedListener?.invoke(
+ requireSelectionTracker().selection
+ )
}
}
)
@@ -395,15 +407,23 @@ open class SearchableRepositoryAdapter<T : RecyclerView.ViewHolder>(
}
private var onItemClickedListener: ((holder: T, item: PasswordItem) -> Unit)? = null
- open fun onItemClicked(listener: (holder: T, item: PasswordItem) -> Unit): SearchableRepositoryAdapter<T> {
- check(onItemClickedListener == null) { "Only a single listener can be registered for onItemClicked" }
+ open fun onItemClicked(
+ listener: (holder: T, item: PasswordItem) -> Unit
+ ): SearchableRepositoryAdapter<T> {
+ check(onItemClickedListener == null) {
+ "Only a single listener can be registered for onItemClicked"
+ }
onItemClickedListener = listener
return this
}
private var onSelectionChangedListener: ((selection: Selection<String>) -> Unit)? = null
- open fun onSelectionChanged(listener: (selection: Selection<String>) -> Unit): SearchableRepositoryAdapter<T> {
- check(onSelectionChangedListener == null) { "Only a single listener can be registered for onSelectionChanged" }
+ open fun onSelectionChanged(
+ listener: (selection: Selection<String>) -> Unit
+ ): SearchableRepositoryAdapter<T> {
+ check(onSelectionChangedListener == null) {
+ "Only a single listener can be registered for onSelectionChanged"
+ }
onSelectionChangedListener = listener
return this
}