aboutsummaryrefslogtreecommitdiffstats
path: root/app/src/main/java/dev/msfjarvis/aps/util/git
diff options
context:
space:
mode:
Diffstat (limited to 'app/src/main/java/dev/msfjarvis/aps/util/git')
-rw-r--r--app/src/main/java/dev/msfjarvis/aps/util/git/GitCommandExecutor.kt114
-rw-r--r--app/src/main/java/dev/msfjarvis/aps/util/git/GitLogModel.kt9
-rw-r--r--app/src/main/java/dev/msfjarvis/aps/util/git/operation/GitOperation.kt16
-rw-r--r--app/src/main/java/dev/msfjarvis/aps/util/git/sshj/SshKey.kt76
-rw-r--r--app/src/main/java/dev/msfjarvis/aps/util/git/sshj/SshjSessionFactory.kt5
5 files changed, 113 insertions, 107 deletions
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 115c2f9f..e6eb77f5 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
@@ -51,76 +51,76 @@ class GitCommandExecutor(
// Count the number of uncommitted files
var nbChanges = 0
return runCatching {
- for (command in operation.commands) {
- when (command) {
- is StatusCommand -> {
- val res = withContext(Dispatchers.IO) { command.call() }
- nbChanges = res.uncommittedChanges.size
- }
- is CommitCommand -> {
- // the previous status will eventually be used to avoid a commit
- if (nbChanges > 0) {
- withContext(Dispatchers.IO) {
- val name = gitSettings.authorName.ifEmpty { "root" }
- val email = gitSettings.authorEmail.ifEmpty { "localhost" }
- val identity = PersonIdent(name, email)
- command.setAuthor(identity).setCommitter(identity).call()
- }
+ for (command in operation.commands) {
+ when (command) {
+ is StatusCommand -> {
+ val res = withContext(Dispatchers.IO) { command.call() }
+ nbChanges = res.uncommittedChanges.size
}
- }
- is PullCommand -> {
- val result = withContext(Dispatchers.IO) { command.call() }
- if (result.rebaseResult != null) {
- if (!result.rebaseResult.status.isSuccessful) {
- throw PullException.PullRebaseFailed
+ is CommitCommand -> {
+ // the previous status will eventually be used to avoid a commit
+ if (nbChanges > 0) {
+ withContext(Dispatchers.IO) {
+ val name = gitSettings.authorName.ifEmpty { "root" }
+ val email = gitSettings.authorEmail.ifEmpty { "localhost" }
+ val identity = PersonIdent(name, email)
+ command.setAuthor(identity).setCommitter(identity).call()
+ }
}
- } else if (result.mergeResult != null) {
- if (!result.mergeResult.mergeStatus.isSuccessful) {
- throw PullException.PullMergeFailed
+ }
+ is PullCommand -> {
+ val result = withContext(Dispatchers.IO) { command.call() }
+ if (result.rebaseResult != null) {
+ if (!result.rebaseResult.status.isSuccessful) {
+ throw PullException.PullRebaseFailed
+ }
+ } else if (result.mergeResult != null) {
+ if (!result.mergeResult.mergeStatus.isSuccessful) {
+ throw PullException.PullMergeFailed
+ }
}
}
- }
- is PushCommand -> {
- val results = withContext(Dispatchers.IO) { command.call() }
- for (result in results) {
- // 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_NODELETE,
- RemoteRefUpdate.Status.REJECTED_REMOTE_CHANGED,
- RemoteRefUpdate.Status.NON_EXISTING,
- RemoteRefUpdate.Status.NOT_ATTEMPTED, ->
- throw PushException.Generic(rru.status.name)
- RemoteRefUpdate.Status.REJECTED_OTHER_REASON -> {
- throw if ("non-fast-forward" == rru.message) {
- PushException.RemoteRejected
- } else {
- PushException.Generic(rru.message)
+ is PushCommand -> {
+ val results = withContext(Dispatchers.IO) { command.call() }
+ for (result in results) {
+ // 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_NODELETE,
+ RemoteRefUpdate.Status.REJECTED_REMOTE_CHANGED,
+ RemoteRefUpdate.Status.NON_EXISTING,
+ RemoteRefUpdate.Status.NOT_ATTEMPTED, ->
+ throw PushException.Generic(rru.status.name)
+ RemoteRefUpdate.Status.REJECTED_OTHER_REASON -> {
+ throw if ("non-fast-forward" == rru.message) {
+ PushException.RemoteRejected
+ } else {
+ PushException.Generic(rru.message)
+ }
}
- }
- RemoteRefUpdate.Status.UP_TO_DATE -> {
- withContext(Dispatchers.Main) {
- Toast.makeText(
- activity.applicationContext,
- activity.applicationContext.getString(R.string.git_push_up_to_date),
- Toast.LENGTH_SHORT
- )
- .show()
+ RemoteRefUpdate.Status.UP_TO_DATE -> {
+ withContext(Dispatchers.Main) {
+ Toast.makeText(
+ activity.applicationContext,
+ activity.applicationContext.getString(R.string.git_push_up_to_date),
+ Toast.LENGTH_SHORT
+ )
+ .show()
+ }
}
+ else -> {}
}
- else -> {}
}
}
}
- }
- else -> {
- withContext(Dispatchers.IO) { command.call() }
+ else -> {
+ withContext(Dispatchers.IO) { command.call() }
+ }
}
}
}
- }
.also { snackbar.dismiss() }
}
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 444a9fee..ed210a65 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
@@ -25,10 +25,11 @@ private fun commits(): Iterable<RevCommit> {
logcat(TAG, ERROR) { "Could not access git repository" }
return listOf()
}
- return runCatching { Git(repo).log().call() }.getOrElse { e ->
- logcat(TAG, ERROR) { e.asLog("Failed to obtain git commits") }
- listOf()
- }
+ return runCatching { Git(repo).log().call() }
+ .getOrElse { e ->
+ logcat(TAG, ERROR) { e.asLog("Failed to obtain git commits") }
+ listOf()
+ }
}
/**
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 f487b195..576a802d 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
@@ -109,14 +109,14 @@ abstract class GitOperation(protected val callingActivity: FragmentActivity) {
private fun getSshKey(make: Boolean) {
runCatching {
- val intent =
- if (make) {
- Intent(callingActivity.applicationContext, SshKeyGenActivity::class.java)
- } else {
- Intent(callingActivity.applicationContext, SshKeyImportActivity::class.java)
- }
- callingActivity.startActivity(intent)
- }
+ val intent =
+ if (make) {
+ Intent(callingActivity.applicationContext, SshKeyGenActivity::class.java)
+ } else {
+ Intent(callingActivity.applicationContext, SshKeyImportActivity::class.java)
+ }
+ callingActivity.startActivity(intent)
+ }
.onFailure { e -> logcat(ERROR) { e.asLog() } }
}
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 f2db6067..d5aaff33 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
@@ -84,19 +84,19 @@ object SshKey {
val mustAuthenticate: Boolean
get() {
return runCatching {
- if (type !in listOf(Type.KeystoreNative, Type.KeystoreWrappedEd25519)) return false
- when (val key = androidKeystore.getKey(KEYSTORE_ALIAS, null)) {
- is PrivateKey -> {
- val factory = KeyFactory.getInstance(key.algorithm, PROVIDER_ANDROID_KEY_STORE)
- return factory.getKeySpec(key, KeyInfo::class.java).isUserAuthenticationRequired
+ if (type !in listOf(Type.KeystoreNative, Type.KeystoreWrappedEd25519)) return false
+ when (val key = androidKeystore.getKey(KEYSTORE_ALIAS, null)) {
+ is PrivateKey -> {
+ val factory = KeyFactory.getInstance(key.algorithm, PROVIDER_ANDROID_KEY_STORE)
+ return factory.getKeySpec(key, KeyInfo::class.java).isUserAuthenticationRequired
+ }
+ is SecretKey -> {
+ val factory = SecretKeyFactory.getInstance(key.algorithm, PROVIDER_ANDROID_KEY_STORE)
+ (factory.getKeySpec(key, KeyInfo::class.java) as KeyInfo).isUserAuthenticationRequired
+ }
+ else -> throw IllegalStateException("SSH key does not exist in Keystore")
}
- is SecretKey -> {
- val factory = SecretKeyFactory.getInstance(key.algorithm, PROVIDER_ANDROID_KEY_STORE)
- (factory.getKeySpec(key, KeyInfo::class.java) as KeyInfo).isUserAuthenticationRequired
- }
- else -> throw IllegalStateException("SSH key does not exist in Keystore")
}
- }
.getOrElse { error ->
// It is fine to swallow the exception here since it will reappear when the key
// is
@@ -316,19 +316,24 @@ object SshKey {
private object KeystoreNativeKeyProvider : KeyProvider {
override fun getPublic(): PublicKey =
- runCatching { androidKeystore.sshPublicKey!! }.getOrElse { error ->
- logcat { error.asLog() }
- throw IOException("Failed to get public key '$KEYSTORE_ALIAS' from Android Keystore", error)
- }
+ runCatching { androidKeystore.sshPublicKey!! }
+ .getOrElse { error ->
+ logcat { error.asLog() }
+ throw IOException(
+ "Failed to get public key '$KEYSTORE_ALIAS' from Android Keystore",
+ error
+ )
+ }
override fun getPrivate(): PrivateKey =
- runCatching { androidKeystore.sshPrivateKey!! }.getOrElse { error ->
- logcat { error.asLog() }
- throw IOException(
- "Failed to access private key '$KEYSTORE_ALIAS' from Android Keystore",
- error
- )
- }
+ runCatching { androidKeystore.sshPrivateKey!! }
+ .getOrElse { error ->
+ logcat { error.asLog() }
+ throw IOException(
+ "Failed to access private key '$KEYSTORE_ALIAS' from Android Keystore",
+ error
+ )
+ }
override fun getType(): KeyType = KeyType.fromKey(public)
}
@@ -336,22 +341,23 @@ object SshKey {
private object KeystoreWrappedEd25519KeyProvider : KeyProvider {
override fun getPublic(): PublicKey =
- runCatching { parseSshPublicKey(sshPublicKey!!)!! }.getOrElse { error ->
- logcat { error.asLog() }
- throw IOException("Failed to get the public key for wrapped ed25519 key", error)
- }
+ runCatching { parseSshPublicKey(sshPublicKey!!)!! }
+ .getOrElse { error ->
+ logcat { error.asLog() }
+ throw IOException("Failed to get the public key for wrapped ed25519 key", error)
+ }
override fun getPrivate(): PrivateKey =
runCatching {
- // The current MasterKey API does not allow getting a reference to an existing one
- // without specifying the KeySpec for a new one. However, the value for passed here
- // 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)
- )
- }
+ // The current MasterKey API does not allow getting a reference to an existing one
+ // without specifying the KeySpec for a new one. However, the value for passed here
+ // 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)
+ )
+ }
.getOrElse { error ->
logcat { error.asLog() }
throw IOException("Failed to unwrap wrapped ed25519 key", error)
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 50c146cc..a9f84fa9 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
@@ -93,9 +93,8 @@ private fun makeTofuHostKeyVerifier(hostKeyFile: File): HostKeyVerifier {
return object : HostKeyVerifier {
override fun verify(hostname: String?, port: Int, key: PublicKey?): Boolean {
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)}"