Skip to content
This repository was archived by the owner on Oct 15, 2024. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion app/src/main/java/com/zeapo/pwdstore/Application.kt
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ import androidx.appcompat.app.AppCompatDelegate.MODE_NIGHT_NO
import androidx.appcompat.app.AppCompatDelegate.MODE_NIGHT_YES
import com.github.ajalt.timberkt.Timber.DebugTree
import com.github.ajalt.timberkt.Timber.plant
import com.zeapo.pwdstore.git.config.setUpBouncyCastleForSshj
import com.zeapo.pwdstore.git.sshj.setUpBouncyCastleForSshj
import com.zeapo.pwdstore.utils.PreferenceKeys
import com.zeapo.pwdstore.utils.sharedPrefs
import com.zeapo.pwdstore.utils.getString
Expand Down
77 changes: 2 additions & 75 deletions app/src/main/java/com/zeapo/pwdstore/git/BaseGitActivity.kt
Original file line number Diff line number Diff line change
Expand Up @@ -4,17 +4,12 @@
*/
package com.zeapo.pwdstore.git

import android.content.Intent
import android.view.MenuItem
import androidx.annotation.CallSuper
import androidx.appcompat.app.AppCompatActivity
import androidx.lifecycle.lifecycleScope
import com.github.ajalt.timberkt.Timber.tag
import com.github.ajalt.timberkt.e
import com.google.android.material.dialog.MaterialAlertDialogBuilder
import com.zeapo.pwdstore.git.config.ConnectionMode
import com.zeapo.pwdstore.git.config.GitSettings
import com.zeapo.pwdstore.git.config.SshApiSessionFactory
import com.zeapo.pwdstore.git.operation.BreakOutOfDetached
import com.zeapo.pwdstore.git.operation.CloneOperation
import com.zeapo.pwdstore.git.operation.GitOperation
Expand All @@ -23,17 +18,13 @@ import com.zeapo.pwdstore.git.operation.PushOperation
import com.zeapo.pwdstore.git.operation.ResetToRemoteOperation
import com.zeapo.pwdstore.git.operation.SyncOperation
import com.zeapo.pwdstore.utils.PasswordRepository
import kotlinx.coroutines.launch

/**
* Abstract AppCompatActivity that holds some information that is commonly shared across git-related
* tasks and makes sense to be held here.
*/
abstract class BaseGitActivity : AppCompatActivity() {

private var identityBuilder: SshApiSessionFactory.IdentityBuilder? = null
private var identity: SshApiSessionFactory.ApiIdentity? = null

override fun onOptionsItemSelected(item: MenuItem): Boolean {
return when (item.itemId) {
android.R.id.home -> {
Expand All @@ -44,23 +35,8 @@ abstract class BaseGitActivity : AppCompatActivity() {
}
}

@CallSuper
override fun onDestroy() {
// Do not leak the service connection
if (identityBuilder != null) {
identityBuilder!!.close()
identityBuilder = null
}
super.onDestroy()
}

/**
* Attempt to launch the requested Git operation. Depending on the configured auth, it may not
* be possible to launch the operation immediately. In that case, this function may launch an
* intermediate activity instead, which will gather necessary information and post it back via
* onActivityResult, which will then re-call this function. This may happen multiple times,
* until either an error is encountered or the operation is successfully launched.
*
* Attempt to launch the requested Git operation.
* @param operation The type of git operation to launch
*/
suspend fun launchGitOperation(operation: Int) {
Expand All @@ -70,21 +46,6 @@ abstract class BaseGitActivity : AppCompatActivity() {
return
}
try {
// Before launching the operation with OpenKeychain auth, we need to issue several requests
// to the OpenKeychain API. IdentityBuild will take care of launching the relevant intents,
// we just need to keep calling it until it returns a completed ApiIdentity.
if (GitSettings.connectionMode == ConnectionMode.OpenKeychain && identity == null) {
// Lazy initialization of the IdentityBuilder
if (identityBuilder == null) {
identityBuilder = SshApiSessionFactory.IdentityBuilder(this)
}
// Try to get an ApiIdentity and bail if one is not ready yet. The builder will ensure
// that onActivityResult is called with operation again, which will re-invoke us here
identity = identityBuilder!!.tryBuild(operation)
if (identity == null)
return
}

val localDir = requireNotNull(PasswordRepository.getRepositoryDirectory())
val op = when (operation) {
REQUEST_CLONE, GitOperation.GET_SSH_KEY_FROM_CLONE -> CloneOperation(localDir, GitSettings.url!!, this)
Expand All @@ -93,54 +54,20 @@ abstract class BaseGitActivity : AppCompatActivity() {
REQUEST_SYNC -> SyncOperation(localDir, this)
BREAK_OUT_OF_DETACHED -> BreakOutOfDetached(localDir, this)
REQUEST_RESET -> ResetToRemoteOperation(localDir, this)
SshApiSessionFactory.POST_SIGNATURE -> return
else -> {
tag(TAG).e { "Operation not recognized : $operation" }
setResult(RESULT_CANCELED)
finish()
return
}
}
op.executeAfterAuthentication(GitSettings.connectionMode, identity)
op.executeAfterAuthentication(GitSettings.connectionMode)
} catch (e: Exception) {
e.printStackTrace()
MaterialAlertDialogBuilder(this).setMessage(e.message).show()
}
}

public override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
// In addition to the pre-operation-launch series of intents for OpenKeychain auth
// that will pass through here and back to launchGitOperation, there is one
// synchronous operation that happens /after/ the operation has been launched in the
// background thread - the actual signing of the SSH challenge. We pass through the
// completed signature to the ApiIdentity, which will be blocked in the other thread
// waiting for it.
if (requestCode == SshApiSessionFactory.POST_SIGNATURE && identity != null) {
identity!!.postSignature(data)

// If the signature failed (usually because it was cancelled), reset state
if (data == null) {
identity = null
identityBuilder = null
}
return
}

if (resultCode == RESULT_CANCELED) {
setResult(RESULT_CANCELED)
finish()
} else if (resultCode == RESULT_OK) {
// If an operation has been re-queued via this mechanism, let the
// IdentityBuilder attempt to extract some updated state from the intent before
// trying to re-launch the operation.
if (identityBuilder != null) {
identityBuilder!!.consume(data)
}
lifecycleScope.launch { launchGitOperation(requestCode) }
}
super.onActivityResult(requestCode, resultCode, data)
}

companion object {

const val REQUEST_ARG_OP = "OPERATION"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ import com.google.android.material.snackbar.Snackbar
import com.zeapo.pwdstore.R
import com.zeapo.pwdstore.git.GitException.PullException
import com.zeapo.pwdstore.git.GitException.PushException
import com.zeapo.pwdstore.git.config.SshjSessionFactory
import com.zeapo.pwdstore.git.sshj.SshjSessionFactory
import com.zeapo.pwdstore.git.operation.GitOperation
import com.zeapo.pwdstore.utils.Result
import com.zeapo.pwdstore.utils.snackbar
Expand Down
Loading