Convert GitOperation API and implementations to Kotlin
Signed-off-by: Harsh Shandilya <msfjarvis@gmail.com>
This commit is contained in:
parent
daafc01ce2
commit
168c3d42aa
11 changed files with 481 additions and 511 deletions
|
@ -595,7 +595,7 @@ public class PasswordStore extends AppCompatActivity {
|
|||
@Override
|
||||
public void execute() {
|
||||
Log.d(TAG, "Committing with message " + message);
|
||||
Git git = new Git(repository);
|
||||
Git git = new Git(getRepository());
|
||||
GitAsyncTask tasks = new GitAsyncTask(activity, false, true, this);
|
||||
tasks.execute(
|
||||
git.add().addFilepattern("."),
|
||||
|
|
|
@ -1,82 +0,0 @@
|
|||
package com.zeapo.pwdstore.git;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.app.AlertDialog;
|
||||
import com.zeapo.pwdstore.R;
|
||||
import org.eclipse.jgit.api.CloneCommand;
|
||||
import org.eclipse.jgit.api.Git;
|
||||
|
||||
import java.io.File;
|
||||
|
||||
public class CloneOperation extends GitOperation {
|
||||
/**
|
||||
* Creates a new clone operation
|
||||
*
|
||||
* @param fileDir the git working tree directory
|
||||
* @param callingActivity the calling activity
|
||||
*/
|
||||
public CloneOperation(File fileDir, Activity callingActivity) {
|
||||
super(fileDir, callingActivity);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the command using the repository uri
|
||||
*
|
||||
* @param uri the uri of the repository
|
||||
* @return the current object
|
||||
*/
|
||||
public CloneOperation setCommand(String uri) {
|
||||
this.command = Git.cloneRepository().
|
||||
setCloneAllBranches(true).
|
||||
setDirectory(repository.getWorkTree()).
|
||||
setURI(uri);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* sets the authentication for user/pwd scheme
|
||||
*
|
||||
* @param username the username
|
||||
* @param password the password
|
||||
* @return the current object
|
||||
*/
|
||||
@Override
|
||||
public CloneOperation setAuthentication(String username, String password) {
|
||||
super.setAuthentication(username, password);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* sets the authentication for the ssh-key scheme
|
||||
*
|
||||
* @param sshKey the ssh-key file
|
||||
* @param username the username
|
||||
* @param passphrase the passphrase
|
||||
* @return the current object
|
||||
*/
|
||||
@Override
|
||||
public CloneOperation setAuthentication(File sshKey, String username, String passphrase) {
|
||||
super.setAuthentication(sshKey, username, passphrase);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute() {
|
||||
if (this.provider != null) {
|
||||
((CloneCommand) this.command).setCredentialsProvider(this.provider);
|
||||
}
|
||||
new GitAsyncTask(callingActivity, true, false, this).execute(this.command);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onError(String errorMessage) {
|
||||
new AlertDialog.Builder(callingActivity).
|
||||
setTitle(callingActivity.getResources().getString(R.string.jgit_error_dialog_title)).
|
||||
setMessage("Error occured during the clone operation, "
|
||||
+ callingActivity.getResources().getString(R.string.jgit_error_dialog_text)
|
||||
+ errorMessage
|
||||
+ "\nPlease check the FAQ for possible reasons why this error might occur.").
|
||||
setPositiveButton(callingActivity.getResources().getString(R.string.dialog_ok), (dialogInterface, i) -> {
|
||||
}).show();
|
||||
}
|
||||
}
|
72
app/src/main/java/com/zeapo/pwdstore/git/CloneOperation.kt
Normal file
72
app/src/main/java/com/zeapo/pwdstore/git/CloneOperation.kt
Normal file
|
@ -0,0 +1,72 @@
|
|||
package com.zeapo.pwdstore.git
|
||||
|
||||
import android.app.Activity
|
||||
import android.app.AlertDialog
|
||||
import com.zeapo.pwdstore.R
|
||||
import org.eclipse.jgit.api.CloneCommand
|
||||
import org.eclipse.jgit.api.Git
|
||||
|
||||
import java.io.File
|
||||
|
||||
/**
|
||||
* Creates a new clone operation
|
||||
*
|
||||
* @param fileDir the git working tree directory
|
||||
* @param callingActivity the calling activity
|
||||
*/
|
||||
class CloneOperation(fileDir: File, callingActivity: Activity) : GitOperation(fileDir, callingActivity) {
|
||||
|
||||
/**
|
||||
* Sets the command using the repository uri
|
||||
*
|
||||
* @param uri the uri of the repository
|
||||
* @return the current object
|
||||
*/
|
||||
fun setCommand(uri: String): CloneOperation {
|
||||
this.command = Git.cloneRepository().setCloneAllBranches(true).setDirectory(repository.workTree).setURI(uri)
|
||||
return this
|
||||
}
|
||||
|
||||
/**
|
||||
* sets the authentication for user/pwd scheme
|
||||
*
|
||||
* @param username the username
|
||||
* @param password the password
|
||||
* @return the current object
|
||||
*/
|
||||
public override fun setAuthentication(username: String, password: String): CloneOperation {
|
||||
super.setAuthentication(username, password)
|
||||
return this
|
||||
}
|
||||
|
||||
/**
|
||||
* sets the authentication for the ssh-key scheme
|
||||
*
|
||||
* @param sshKey the ssh-key file
|
||||
* @param username the username
|
||||
* @param passphrase the passphrase
|
||||
* @return the current object
|
||||
*/
|
||||
public override fun setAuthentication(sshKey: File, username: String, passphrase: String): CloneOperation {
|
||||
super.setAuthentication(sshKey, username, passphrase)
|
||||
return this
|
||||
}
|
||||
|
||||
override fun execute() {
|
||||
if (this.provider != null) {
|
||||
(this.command as CloneCommand).setCredentialsProvider(this.provider)
|
||||
}
|
||||
GitAsyncTask(callingActivity, true, false, this).execute(this.command)
|
||||
}
|
||||
|
||||
override fun onError(errorMessage: String) {
|
||||
AlertDialog.Builder(callingActivity)
|
||||
.setTitle(callingActivity.resources.getString(R.string.jgit_error_dialog_title))
|
||||
.setMessage("Error occured during the clone operation, "
|
||||
+ callingActivity.resources.getString(R.string.jgit_error_dialog_text)
|
||||
+ errorMessage
|
||||
+ "\nPlease check the FAQ for possible reasons why this error might occur.")
|
||||
.setPositiveButton(callingActivity.resources.getString(R.string.dialog_ok)) { _, _ -> }
|
||||
.show()
|
||||
}
|
||||
}
|
|
@ -1,256 +0,0 @@
|
|||
package com.zeapo.pwdstore.git;
|
||||
|
||||
import android.annotation.SuppressLint;
|
||||
import android.app.Activity;
|
||||
import android.content.Intent;
|
||||
import android.content.SharedPreferences;
|
||||
import android.preference.PreferenceManager;
|
||||
import android.text.InputType;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.widget.CheckBox;
|
||||
import android.widget.EditText;
|
||||
import android.widget.LinearLayout;
|
||||
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.appcompat.app.AlertDialog;
|
||||
|
||||
import com.jcraft.jsch.JSch;
|
||||
import com.jcraft.jsch.JSchException;
|
||||
import com.jcraft.jsch.KeyPair;
|
||||
import com.zeapo.pwdstore.R;
|
||||
import com.zeapo.pwdstore.UserPreference;
|
||||
import com.zeapo.pwdstore.git.config.GitConfigSessionFactory;
|
||||
import com.zeapo.pwdstore.git.config.SshApiSessionFactory;
|
||||
import com.zeapo.pwdstore.git.config.SshConfigSessionFactory;
|
||||
import com.zeapo.pwdstore.utils.PasswordRepository;
|
||||
|
||||
import org.eclipse.jgit.api.GitCommand;
|
||||
import org.eclipse.jgit.lib.Repository;
|
||||
import org.eclipse.jgit.transport.JschConfigSessionFactory;
|
||||
import org.eclipse.jgit.transport.SshSessionFactory;
|
||||
import org.eclipse.jgit.transport.UsernamePasswordCredentialsProvider;
|
||||
|
||||
import java.io.File;
|
||||
|
||||
public abstract class GitOperation {
|
||||
public static final int GET_SSH_KEY_FROM_CLONE = 201;
|
||||
|
||||
protected final Repository repository;
|
||||
final Activity callingActivity;
|
||||
UsernamePasswordCredentialsProvider provider;
|
||||
GitCommand command;
|
||||
|
||||
/**
|
||||
* Creates a new git operation
|
||||
*
|
||||
* @param fileDir the git working tree directory
|
||||
* @param callingActivity the calling activity
|
||||
*/
|
||||
public GitOperation(File fileDir, Activity callingActivity) {
|
||||
this.repository = PasswordRepository.getRepository(fileDir);
|
||||
this.callingActivity = callingActivity;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the authentication using user/pwd scheme
|
||||
*
|
||||
* @param username the username
|
||||
* @param password the password
|
||||
* @return the current object
|
||||
*/
|
||||
GitOperation setAuthentication(String username, String password) {
|
||||
SshSessionFactory.setInstance(new GitConfigSessionFactory());
|
||||
this.provider = new UsernamePasswordCredentialsProvider(username, password);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the authentication using ssh-key scheme
|
||||
*
|
||||
* @param sshKey the ssh-key file
|
||||
* @param username the username
|
||||
* @param passphrase the passphrase
|
||||
* @return the current object
|
||||
*/
|
||||
GitOperation setAuthentication(File sshKey, String username, String passphrase) {
|
||||
JschConfigSessionFactory sessionFactory = new SshConfigSessionFactory(sshKey.getAbsolutePath(), username, passphrase);
|
||||
SshSessionFactory.setInstance(sessionFactory);
|
||||
this.provider = null;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the authentication using OpenKeystore scheme
|
||||
*
|
||||
* @param identity The identiy to use
|
||||
* @return the current object
|
||||
*/
|
||||
GitOperation setAuthentication(String username, SshApiSessionFactory.ApiIdentity identity) {
|
||||
SshSessionFactory.setInstance(new SshApiSessionFactory(username, identity));
|
||||
this.provider = null;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Executes the GitCommand in an async task
|
||||
*/
|
||||
public abstract void execute();
|
||||
|
||||
/**
|
||||
* Executes the GitCommand in an async task after creating the authentication
|
||||
*
|
||||
* @param connectionMode the server-connection mode
|
||||
* @param username the username
|
||||
* @param sshKey the ssh-key file to use in ssh-key connection mode
|
||||
* @param identity the api identity to use for auth in OpenKeychain connection mode
|
||||
*/
|
||||
public void executeAfterAuthentication(final String connectionMode,
|
||||
final String username,
|
||||
@Nullable final File sshKey,
|
||||
SshApiSessionFactory.ApiIdentity identity) {
|
||||
executeAfterAuthentication(connectionMode, username, sshKey, identity, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Executes the GitCommand in an async task after creating the authentication
|
||||
*
|
||||
* @param connectionMode the server-connection mode
|
||||
* @param username the username
|
||||
* @param sshKey the ssh-key file to use in ssh-key connection mode
|
||||
* @param identity the api identity to use for auth in OpenKeychain connection mode
|
||||
* @param showError show the passphrase edit text in red
|
||||
*/
|
||||
private void executeAfterAuthentication(final String connectionMode,
|
||||
final String username,
|
||||
@Nullable final File sshKey,
|
||||
SshApiSessionFactory.ApiIdentity identity,
|
||||
final boolean showError) {
|
||||
if (connectionMode.equalsIgnoreCase("ssh-key")) {
|
||||
if (sshKey == null || !sshKey.exists()) {
|
||||
new AlertDialog.Builder(callingActivity)
|
||||
.setMessage(callingActivity.getResources().getString(R.string.ssh_preferences_dialog_text))
|
||||
.setTitle(callingActivity.getResources().getString(R.string.ssh_preferences_dialog_title))
|
||||
.setPositiveButton(callingActivity.getResources().getString(R.string.ssh_preferences_dialog_import), (dialog, id) -> {
|
||||
try {
|
||||
// Ask the UserPreference to provide us with the ssh-key
|
||||
// onResult has to be handled by the callingActivity
|
||||
Intent intent = new Intent(callingActivity.getApplicationContext(), UserPreference.class);
|
||||
intent.putExtra("operation", "get_ssh_key");
|
||||
callingActivity.startActivityForResult(intent, GET_SSH_KEY_FROM_CLONE);
|
||||
} catch (Exception e) {
|
||||
System.out.println("Exception caught :(");
|
||||
e.printStackTrace();
|
||||
}
|
||||
})
|
||||
.setNegativeButton(callingActivity.getResources().getString(R.string.ssh_preferences_dialog_generate), (dialog, which) -> {
|
||||
try {
|
||||
// Duplicated code
|
||||
Intent intent = new Intent(callingActivity.getApplicationContext(), UserPreference.class);
|
||||
intent.putExtra("operation", "make_ssh_key");
|
||||
callingActivity.startActivityForResult(intent, GET_SSH_KEY_FROM_CLONE);
|
||||
} catch (Exception e) {
|
||||
System.out.println("Exception caught :(");
|
||||
e.printStackTrace();
|
||||
}
|
||||
})
|
||||
.setNeutralButton(callingActivity.getResources().getString(R.string.dialog_cancel), (dialog, id) -> {
|
||||
// Finish the blank GitActivity so user doesn't have to press back
|
||||
callingActivity.finish();
|
||||
}).show();
|
||||
} else {
|
||||
LayoutInflater layoutInflater = LayoutInflater.from(callingActivity.getApplicationContext());
|
||||
@SuppressLint("InflateParams") final View dialogView = layoutInflater.inflate(R.layout.git_passphrase_layout, null);
|
||||
final EditText passphrase = dialogView.findViewById(R.id.sshkey_passphrase);
|
||||
final SharedPreferences settings = PreferenceManager.getDefaultSharedPreferences(callingActivity.getApplicationContext());
|
||||
final String sshKeyPassphrase = settings.getString("ssh_key_passphrase", null);
|
||||
if (showError) {
|
||||
passphrase.setError("Wrong passphrase");
|
||||
}
|
||||
JSch jsch = new JSch();
|
||||
try {
|
||||
final KeyPair keyPair = KeyPair.load(jsch, callingActivity.getFilesDir() + "/.ssh_key");
|
||||
|
||||
if (keyPair.isEncrypted()) {
|
||||
if (sshKeyPassphrase != null && !sshKeyPassphrase.isEmpty()) {
|
||||
if (keyPair.decrypt(sshKeyPassphrase)) {
|
||||
// Authenticate using the ssh-key and then execute the command
|
||||
setAuthentication(sshKey, username, sshKeyPassphrase).execute();
|
||||
} else {
|
||||
// call back the method
|
||||
executeAfterAuthentication(connectionMode, username, sshKey, identity, true);
|
||||
}
|
||||
} else {
|
||||
new AlertDialog.Builder(callingActivity)
|
||||
.setTitle(callingActivity.getResources().getString(R.string.passphrase_dialog_title))
|
||||
.setMessage(callingActivity.getResources().getString(R.string.passphrase_dialog_text))
|
||||
.setView(dialogView)
|
||||
.setPositiveButton(callingActivity.getResources().getString(R.string.dialog_ok), (dialog, whichButton) -> {
|
||||
if (keyPair.decrypt(passphrase.getText().toString())) {
|
||||
boolean rememberPassphrase = ((CheckBox) dialogView.findViewById(R.id.sshkey_remember_passphrase)).isChecked();
|
||||
if (rememberPassphrase) {
|
||||
settings.edit().putString("ssh_key_passphrase", passphrase.getText().toString()).apply();
|
||||
}
|
||||
// Authenticate using the ssh-key and then execute the command
|
||||
setAuthentication(sshKey, username, passphrase.getText().toString()).execute();
|
||||
} else {
|
||||
settings.edit().putString("ssh_key_passphrase", null).apply();
|
||||
// call back the method
|
||||
executeAfterAuthentication(connectionMode, username, sshKey, identity, true);
|
||||
}
|
||||
}).setNegativeButton(callingActivity.getResources().getString(R.string.dialog_cancel), (dialog, whichButton) -> {
|
||||
// Do nothing.
|
||||
}).show();
|
||||
}
|
||||
} else {
|
||||
setAuthentication(sshKey, username, "").execute();
|
||||
}
|
||||
} catch (JSchException e) {
|
||||
new AlertDialog.Builder(callingActivity)
|
||||
.setTitle("Unable to open the ssh-key")
|
||||
.setMessage("Please check that it was imported.")
|
||||
.setPositiveButton("Ok", (dialogInterface, i) -> {
|
||||
|
||||
}).show();
|
||||
}
|
||||
}
|
||||
} else if (connectionMode.equalsIgnoreCase("OpenKeychain")) {
|
||||
setAuthentication(username, identity).execute();
|
||||
} else {
|
||||
final EditText password = new EditText(callingActivity);
|
||||
password.setHint("Password");
|
||||
password.setWidth(LinearLayout.LayoutParams.MATCH_PARENT);
|
||||
password.setInputType(InputType.TYPE_CLASS_TEXT | InputType.TYPE_TEXT_VARIATION_PASSWORD);
|
||||
|
||||
new AlertDialog.Builder(callingActivity)
|
||||
.setTitle(callingActivity.getResources().getString(R.string.passphrase_dialog_title))
|
||||
.setMessage(callingActivity.getResources().getString(R.string.password_dialog_text))
|
||||
.setView(password)
|
||||
.setPositiveButton(callingActivity.getResources().getString(R.string.dialog_ok), (dialog, whichButton) -> {
|
||||
// authenticate using the user/pwd and then execute the command
|
||||
setAuthentication(username, password.getText().toString()).execute();
|
||||
|
||||
})
|
||||
.setNegativeButton(callingActivity.getResources().getString(R.string.dialog_cancel), (dialog, whichButton) -> callingActivity.finish()).show();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Action to execute on error
|
||||
*/
|
||||
public void onError(String errorMessage) {
|
||||
new AlertDialog.Builder(callingActivity).
|
||||
setTitle(callingActivity.getResources().getString(R.string.jgit_error_dialog_title)).
|
||||
setMessage(callingActivity.getResources().getString(R.string.jgit_error_dialog_text) + errorMessage).
|
||||
setPositiveButton(callingActivity.getResources().getString(R.string.dialog_ok), (dialogInterface, i) -> {
|
||||
callingActivity.setResult(Activity.RESULT_CANCELED);
|
||||
callingActivity.finish();
|
||||
}).show();
|
||||
}
|
||||
|
||||
/**
|
||||
* Action to execute on success
|
||||
*/
|
||||
public void onSuccess() {
|
||||
}
|
||||
}
|
252
app/src/main/java/com/zeapo/pwdstore/git/GitOperation.kt
Normal file
252
app/src/main/java/com/zeapo/pwdstore/git/GitOperation.kt
Normal file
|
@ -0,0 +1,252 @@
|
|||
package com.zeapo.pwdstore.git
|
||||
|
||||
import android.annotation.SuppressLint
|
||||
import android.app.Activity
|
||||
import android.content.Intent
|
||||
import android.preference.PreferenceManager
|
||||
import android.text.InputType
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.widget.CheckBox
|
||||
import android.widget.EditText
|
||||
import android.widget.LinearLayout
|
||||
import androidx.appcompat.app.AlertDialog
|
||||
|
||||
import com.jcraft.jsch.JSch
|
||||
import com.jcraft.jsch.JSchException
|
||||
import com.jcraft.jsch.KeyPair
|
||||
import com.zeapo.pwdstore.R
|
||||
import com.zeapo.pwdstore.UserPreference
|
||||
import com.zeapo.pwdstore.git.config.GitConfigSessionFactory
|
||||
import com.zeapo.pwdstore.git.config.SshApiSessionFactory
|
||||
import com.zeapo.pwdstore.git.config.SshConfigSessionFactory
|
||||
import com.zeapo.pwdstore.utils.PasswordRepository
|
||||
|
||||
import org.eclipse.jgit.api.GitCommand
|
||||
import org.eclipse.jgit.lib.Repository
|
||||
import org.eclipse.jgit.transport.SshSessionFactory
|
||||
import org.eclipse.jgit.transport.UsernamePasswordCredentialsProvider
|
||||
|
||||
import java.io.File
|
||||
|
||||
/**
|
||||
* Creates a new git operation
|
||||
*
|
||||
* @param fileDir the git working tree directory
|
||||
* @param callingActivity the calling activity
|
||||
*/
|
||||
abstract class GitOperation(fileDir: File, internal val callingActivity: Activity) {
|
||||
|
||||
protected val repository: Repository = PasswordRepository.getRepository(fileDir)
|
||||
internal var provider: UsernamePasswordCredentialsProvider? = null
|
||||
internal var command: GitCommand<*>? = null
|
||||
|
||||
/**
|
||||
* Sets the authentication using user/pwd scheme
|
||||
*
|
||||
* @param username the username
|
||||
* @param password the password
|
||||
* @return the current object
|
||||
*/
|
||||
internal open fun setAuthentication(username: String, password: String): GitOperation {
|
||||
SshSessionFactory.setInstance(GitConfigSessionFactory())
|
||||
this.provider = UsernamePasswordCredentialsProvider(username, password)
|
||||
return this
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the authentication using ssh-key scheme
|
||||
*
|
||||
* @param sshKey the ssh-key file
|
||||
* @param username the username
|
||||
* @param passphrase the passphrase
|
||||
* @return the current object
|
||||
*/
|
||||
internal open fun setAuthentication(sshKey: File, username: String, passphrase: String): GitOperation {
|
||||
val sessionFactory = SshConfigSessionFactory(sshKey.absolutePath, username, passphrase)
|
||||
SshSessionFactory.setInstance(sessionFactory)
|
||||
this.provider = null
|
||||
return this
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the authentication using OpenKeystore scheme
|
||||
*
|
||||
* @param identity The identiy to use
|
||||
* @return the current object
|
||||
*/
|
||||
private fun setAuthentication(username: String, identity: SshApiSessionFactory.ApiIdentity?): GitOperation {
|
||||
SshSessionFactory.setInstance(SshApiSessionFactory(username, identity))
|
||||
this.provider = null
|
||||
return this
|
||||
}
|
||||
|
||||
/**
|
||||
* Executes the GitCommand in an async task
|
||||
*/
|
||||
abstract fun execute()
|
||||
|
||||
/**
|
||||
* Executes the GitCommand in an async task after creating the authentication
|
||||
*
|
||||
* @param connectionMode the server-connection mode
|
||||
* @param username the username
|
||||
* @param sshKey the ssh-key file to use in ssh-key connection mode
|
||||
* @param identity the api identity to use for auth in OpenKeychain connection mode
|
||||
*/
|
||||
fun executeAfterAuthentication(connectionMode: String,
|
||||
username: String,
|
||||
sshKey: File?,
|
||||
identity: SshApiSessionFactory.ApiIdentity?) {
|
||||
executeAfterAuthentication(connectionMode, username, sshKey, identity, false)
|
||||
}
|
||||
|
||||
/**
|
||||
* Executes the GitCommand in an async task after creating the authentication
|
||||
*
|
||||
* @param connectionMode the server-connection mode
|
||||
* @param username the username
|
||||
* @param sshKey the ssh-key file to use in ssh-key connection mode
|
||||
* @param identity the api identity to use for auth in OpenKeychain connection mode
|
||||
* @param showError show the passphrase edit text in red
|
||||
*/
|
||||
private fun executeAfterAuthentication(connectionMode: String,
|
||||
username: String,
|
||||
sshKey: File?,
|
||||
identity: SshApiSessionFactory.ApiIdentity?,
|
||||
showError: Boolean) {
|
||||
if (connectionMode.equals("ssh-key", ignoreCase = true)) {
|
||||
if (sshKey == null || !sshKey.exists()) {
|
||||
AlertDialog.Builder(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)) { _, _ ->
|
||||
try {
|
||||
// Ask the UserPreference to provide us with the ssh-key
|
||||
// onResult has to be handled by the callingActivity
|
||||
val intent = Intent(callingActivity.applicationContext, UserPreference::class.java)
|
||||
intent.putExtra("operation", "get_ssh_key")
|
||||
callingActivity.startActivityForResult(intent, GET_SSH_KEY_FROM_CLONE)
|
||||
} catch (e: Exception) {
|
||||
println("Exception caught :(")
|
||||
e.printStackTrace()
|
||||
}
|
||||
}
|
||||
.setNegativeButton(callingActivity.resources.getString(R.string.ssh_preferences_dialog_generate)) { _, _ ->
|
||||
try {
|
||||
// Duplicated code
|
||||
val intent = Intent(callingActivity.applicationContext, UserPreference::class.java)
|
||||
intent.putExtra("operation", "make_ssh_key")
|
||||
callingActivity.startActivityForResult(intent, GET_SSH_KEY_FROM_CLONE)
|
||||
} catch (e: Exception) {
|
||||
println("Exception caught :(")
|
||||
e.printStackTrace()
|
||||
}
|
||||
}
|
||||
.setNeutralButton(callingActivity.resources.getString(R.string.dialog_cancel)) { _, _ ->
|
||||
// Finish the blank GitActivity so user doesn't have to press back
|
||||
callingActivity.finish()
|
||||
}.show()
|
||||
} else {
|
||||
val layoutInflater = LayoutInflater.from(callingActivity.applicationContext)
|
||||
@SuppressLint("InflateParams") val dialogView = layoutInflater.inflate(R.layout.git_passphrase_layout, null)
|
||||
val passphrase = dialogView.findViewById<EditText>(R.id.sshkey_passphrase)
|
||||
val settings = PreferenceManager.getDefaultSharedPreferences(callingActivity.applicationContext)
|
||||
val sshKeyPassphrase = settings.getString("ssh_key_passphrase", null)
|
||||
if (showError) {
|
||||
passphrase.error = "Wrong passphrase"
|
||||
}
|
||||
val jsch = JSch()
|
||||
try {
|
||||
val keyPair = KeyPair.load(jsch, callingActivity.filesDir.toString() + "/.ssh_key")
|
||||
|
||||
if (keyPair.isEncrypted) {
|
||||
if (sshKeyPassphrase != null && sshKeyPassphrase.isNotEmpty()) {
|
||||
if (keyPair.decrypt(sshKeyPassphrase)) {
|
||||
// Authenticate using the ssh-key and then execute the command
|
||||
setAuthentication(sshKey, username, sshKeyPassphrase).execute()
|
||||
} else {
|
||||
// call back the method
|
||||
executeAfterAuthentication(connectionMode, username, sshKey, identity, true)
|
||||
}
|
||||
} else {
|
||||
AlertDialog.Builder(callingActivity)
|
||||
.setTitle(callingActivity.resources.getString(R.string.passphrase_dialog_title))
|
||||
.setMessage(callingActivity.resources.getString(R.string.passphrase_dialog_text))
|
||||
.setView(dialogView)
|
||||
.setPositiveButton(callingActivity.resources.getString(R.string.dialog_ok)) { _, _ ->
|
||||
if (keyPair.decrypt(passphrase.text.toString())) {
|
||||
val rememberPassphrase = (dialogView.findViewById<View>(R.id.sshkey_remember_passphrase) as CheckBox).isChecked
|
||||
if (rememberPassphrase) {
|
||||
settings.edit().putString("ssh_key_passphrase", passphrase.text.toString()).apply()
|
||||
}
|
||||
// Authenticate using the ssh-key and then execute the command
|
||||
setAuthentication(sshKey, username, passphrase.text.toString()).execute()
|
||||
} else {
|
||||
settings.edit().putString("ssh_key_passphrase", null).apply()
|
||||
// call back the method
|
||||
executeAfterAuthentication(connectionMode, username, sshKey, identity, true)
|
||||
}
|
||||
}.setNegativeButton(callingActivity.resources.getString(R.string.dialog_cancel)) { _, _ ->
|
||||
// Do nothing.
|
||||
}.show()
|
||||
}
|
||||
} else {
|
||||
setAuthentication(sshKey, username, "").execute()
|
||||
}
|
||||
} catch (e: JSchException) {
|
||||
AlertDialog.Builder(callingActivity)
|
||||
.setTitle("Unable to open the ssh-key")
|
||||
.setMessage("Please check that it was imported.")
|
||||
.setPositiveButton("Ok") { _, _ -> }
|
||||
.show()
|
||||
}
|
||||
|
||||
}
|
||||
} else if (connectionMode.equals("OpenKeychain", ignoreCase = true)) {
|
||||
setAuthentication(username, identity).execute()
|
||||
} else {
|
||||
val password = EditText(callingActivity)
|
||||
password.hint = "Password"
|
||||
password.width = LinearLayout.LayoutParams.MATCH_PARENT
|
||||
password.inputType = InputType.TYPE_CLASS_TEXT or InputType.TYPE_TEXT_VARIATION_PASSWORD
|
||||
|
||||
AlertDialog.Builder(callingActivity)
|
||||
.setTitle(callingActivity.resources.getString(R.string.passphrase_dialog_title))
|
||||
.setMessage(callingActivity.resources.getString(R.string.password_dialog_text))
|
||||
.setView(password)
|
||||
.setPositiveButton(callingActivity.resources.getString(R.string.dialog_ok)) { _, _ ->
|
||||
// authenticate using the user/pwd and then execute the command
|
||||
setAuthentication(username, password.text.toString()).execute()
|
||||
|
||||
}
|
||||
.setNegativeButton(callingActivity.resources.getString(R.string.dialog_cancel)) { _, _ ->
|
||||
callingActivity.finish()
|
||||
}
|
||||
.show()
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Action to execute on error
|
||||
*/
|
||||
open fun onError(errorMessage: String) {
|
||||
AlertDialog.Builder(callingActivity)
|
||||
.setTitle(callingActivity.resources.getString(R.string.jgit_error_dialog_title))
|
||||
.setMessage(callingActivity.resources.getString(R.string.jgit_error_dialog_text) + errorMessage)
|
||||
.setPositiveButton(callingActivity.resources.getString(R.string.dialog_ok)) { _, _ ->
|
||||
callingActivity.setResult(Activity.RESULT_CANCELED)
|
||||
callingActivity.finish()
|
||||
}
|
||||
.show()
|
||||
}
|
||||
|
||||
/**
|
||||
* Action to execute on success
|
||||
*/
|
||||
open fun onSuccess() {}
|
||||
|
||||
companion object {
|
||||
const val GET_SSH_KEY_FROM_CLONE = 201
|
||||
}
|
||||
}
|
|
@ -1,54 +0,0 @@
|
|||
package com.zeapo.pwdstore.git;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.app.AlertDialog;
|
||||
import com.zeapo.pwdstore.R;
|
||||
import org.eclipse.jgit.api.Git;
|
||||
import org.eclipse.jgit.api.PullCommand;
|
||||
|
||||
import java.io.File;
|
||||
|
||||
public class PullOperation extends GitOperation {
|
||||
|
||||
/**
|
||||
* Creates a new git operation
|
||||
*
|
||||
* @param fileDir the git working tree directory
|
||||
* @param callingActivity the calling activity
|
||||
*/
|
||||
public PullOperation(File fileDir, Activity callingActivity) {
|
||||
super(fileDir, callingActivity);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the command
|
||||
*
|
||||
* @return the current object
|
||||
*/
|
||||
public PullOperation setCommand() {
|
||||
this.command = new Git(repository)
|
||||
.pull()
|
||||
.setRebase(true)
|
||||
.setRemote("origin");
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute() {
|
||||
if (this.provider != null) {
|
||||
((PullCommand) this.command).setCredentialsProvider(this.provider);
|
||||
}
|
||||
new GitAsyncTask(callingActivity, true, false, this).execute(this.command);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onError(String errorMessage) {
|
||||
new AlertDialog.Builder(callingActivity).
|
||||
setTitle(callingActivity.getResources().getString(R.string.jgit_error_dialog_title)).
|
||||
setMessage("Error occured during the pull operation, "
|
||||
+ callingActivity.getResources().getString(R.string.jgit_error_dialog_text)
|
||||
+ errorMessage
|
||||
+ "\nPlease check the FAQ for possible reasons why this error might occur.").
|
||||
setPositiveButton(callingActivity.getResources().getString(R.string.dialog_ok), (dialogInterface, i) -> callingActivity.finish()).show();
|
||||
}
|
||||
}
|
49
app/src/main/java/com/zeapo/pwdstore/git/PullOperation.kt
Normal file
49
app/src/main/java/com/zeapo/pwdstore/git/PullOperation.kt
Normal file
|
@ -0,0 +1,49 @@
|
|||
package com.zeapo.pwdstore.git
|
||||
|
||||
import android.app.Activity
|
||||
import android.app.AlertDialog
|
||||
import com.zeapo.pwdstore.R
|
||||
import org.eclipse.jgit.api.Git
|
||||
import org.eclipse.jgit.api.PullCommand
|
||||
|
||||
import java.io.File
|
||||
|
||||
/**
|
||||
* Creates a new git operation
|
||||
*
|
||||
* @param fileDir the git working tree directory
|
||||
* @param callingActivity the calling activity
|
||||
*/
|
||||
class PullOperation(fileDir: File, callingActivity: Activity) : GitOperation(fileDir, callingActivity) {
|
||||
|
||||
/**
|
||||
* Sets the command
|
||||
*
|
||||
* @return the current object
|
||||
*/
|
||||
fun setCommand(): PullOperation {
|
||||
this.command = Git(repository)
|
||||
.pull()
|
||||
.setRebase(true)
|
||||
.setRemote("origin")
|
||||
return this
|
||||
}
|
||||
|
||||
override fun execute() {
|
||||
if (this.provider != null) {
|
||||
(this.command as PullCommand).setCredentialsProvider(this.provider)
|
||||
}
|
||||
GitAsyncTask(callingActivity, true, false, this).execute(this.command)
|
||||
}
|
||||
|
||||
override fun onError(errorMessage: String) {
|
||||
AlertDialog.Builder(callingActivity)
|
||||
.setTitle(callingActivity.resources.getString(R.string.jgit_error_dialog_title))
|
||||
.setMessage("Error occured during the pull operation, "
|
||||
+ callingActivity.resources.getString(R.string.jgit_error_dialog_text)
|
||||
+ errorMessage
|
||||
+ "\nPlease check the FAQ for possible reasons why this error might occur.")
|
||||
.setPositiveButton(callingActivity.resources.getString(R.string.dialog_ok)) { _, _ -> callingActivity.finish() }
|
||||
.show()
|
||||
}
|
||||
}
|
|
@ -1,52 +0,0 @@
|
|||
package com.zeapo.pwdstore.git;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.app.AlertDialog;
|
||||
import com.zeapo.pwdstore.R;
|
||||
import org.eclipse.jgit.api.Git;
|
||||
import org.eclipse.jgit.api.PushCommand;
|
||||
|
||||
import java.io.File;
|
||||
|
||||
public class PushOperation extends GitOperation {
|
||||
|
||||
/**
|
||||
* Creates a new git operation
|
||||
*
|
||||
* @param fileDir the git working tree directory
|
||||
* @param callingActivity the calling activity
|
||||
*/
|
||||
public PushOperation(File fileDir, Activity callingActivity) {
|
||||
super(fileDir, callingActivity);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the command
|
||||
*
|
||||
* @return the current object
|
||||
*/
|
||||
public PushOperation setCommand() {
|
||||
this.command = new Git(repository)
|
||||
.push()
|
||||
.setPushAll()
|
||||
.setRemote("origin");
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute() {
|
||||
if (this.provider != null) {
|
||||
((PushCommand) this.command).setCredentialsProvider(this.provider);
|
||||
}
|
||||
new GitAsyncTask(callingActivity, true, false, this).execute(this.command);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onError(String errorMessage) {
|
||||
// TODO handle the "Nothing to push" case
|
||||
new AlertDialog.Builder(callingActivity).
|
||||
setTitle(callingActivity.getResources().getString(R.string.jgit_error_dialog_title)).
|
||||
setMessage(callingActivity.getString(R.string.jgit_error_push_dialog_text) + errorMessage).
|
||||
setPositiveButton(callingActivity.getResources().getString(R.string.dialog_ok), (dialogInterface, i) -> callingActivity.finish()).show();
|
||||
}
|
||||
}
|
47
app/src/main/java/com/zeapo/pwdstore/git/PushOperation.kt
Normal file
47
app/src/main/java/com/zeapo/pwdstore/git/PushOperation.kt
Normal file
|
@ -0,0 +1,47 @@
|
|||
package com.zeapo.pwdstore.git
|
||||
|
||||
import android.app.Activity
|
||||
import android.app.AlertDialog
|
||||
import com.zeapo.pwdstore.R
|
||||
import org.eclipse.jgit.api.Git
|
||||
import org.eclipse.jgit.api.PushCommand
|
||||
|
||||
import java.io.File
|
||||
|
||||
/**
|
||||
* Creates a new git operation
|
||||
*
|
||||
* @param fileDir the git working tree directory
|
||||
* @param callingActivity the calling activity
|
||||
*/
|
||||
class PushOperation(fileDir: File, callingActivity: Activity) : GitOperation(fileDir, callingActivity) {
|
||||
|
||||
/**
|
||||
* Sets the command
|
||||
*
|
||||
* @return the current object
|
||||
*/
|
||||
fun setCommand(): PushOperation {
|
||||
this.command = Git(repository)
|
||||
.push()
|
||||
.setPushAll()
|
||||
.setRemote("origin")
|
||||
return this
|
||||
}
|
||||
|
||||
override fun execute() {
|
||||
if (this.provider != null) {
|
||||
(this.command as PushCommand).setCredentialsProvider(this.provider)
|
||||
}
|
||||
GitAsyncTask(callingActivity, true, false, this).execute(this.command)
|
||||
}
|
||||
|
||||
override fun onError(errorMessage: String) {
|
||||
// TODO handle the "Nothing to push" case
|
||||
AlertDialog.Builder(callingActivity)
|
||||
.setTitle(callingActivity.resources.getString(R.string.jgit_error_dialog_title))
|
||||
.setMessage(callingActivity.getString(R.string.jgit_error_push_dialog_text) + errorMessage)
|
||||
.setPositiveButton(callingActivity.resources.getString(R.string.dialog_ok)) { _, _ -> callingActivity.finish() }
|
||||
.show()
|
||||
}
|
||||
}
|
|
@ -1,66 +0,0 @@
|
|||
package com.zeapo.pwdstore.git;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.app.AlertDialog;
|
||||
import com.zeapo.pwdstore.R;
|
||||
import org.eclipse.jgit.api.AddCommand;
|
||||
import org.eclipse.jgit.api.CommitCommand;
|
||||
import org.eclipse.jgit.api.Git;
|
||||
import org.eclipse.jgit.api.PullCommand;
|
||||
import org.eclipse.jgit.api.PushCommand;
|
||||
import org.eclipse.jgit.api.StatusCommand;
|
||||
|
||||
import java.io.File;
|
||||
|
||||
public class SyncOperation extends GitOperation {
|
||||
private AddCommand addCommand;
|
||||
private StatusCommand statusCommand;
|
||||
private CommitCommand commitCommand;
|
||||
private PullCommand pullCommand;
|
||||
private PushCommand pushCommand;
|
||||
|
||||
/**
|
||||
* Creates a new git operation
|
||||
*
|
||||
* @param fileDir the git working tree directory
|
||||
* @param callingActivity the calling activity
|
||||
*/
|
||||
public SyncOperation(File fileDir, Activity callingActivity) {
|
||||
super(fileDir, callingActivity);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the command
|
||||
*
|
||||
* @return the current object
|
||||
*/
|
||||
public SyncOperation setCommands() {
|
||||
Git git = new Git(repository);
|
||||
this.addCommand = git.add().addFilepattern(".");
|
||||
this.statusCommand = git.status();
|
||||
this.commitCommand = git.commit().setAll(true).setMessage("[Android Password Store] Sync");
|
||||
this.pullCommand = git.pull().setRebase(true).setRemote("origin");
|
||||
this.pushCommand = git.push().setPushAll().setRemote("origin");
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute() {
|
||||
if (this.provider != null) {
|
||||
this.pullCommand.setCredentialsProvider(this.provider);
|
||||
this.pushCommand.setCredentialsProvider(this.provider);
|
||||
}
|
||||
new GitAsyncTask(callingActivity, true, false, this).execute(this.addCommand, this.statusCommand, this.commitCommand, this.pullCommand, this.pushCommand);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onError(String errorMessage) {
|
||||
new AlertDialog.Builder(callingActivity).
|
||||
setTitle(callingActivity.getResources().getString(R.string.jgit_error_dialog_title)).
|
||||
setMessage("Error occured during the sync operation, "
|
||||
+ "\nPlease check the FAQ for possible reasons why this error might occur."
|
||||
+ callingActivity.getResources().getString(R.string.jgit_error_dialog_text)
|
||||
+ errorMessage).
|
||||
setPositiveButton(callingActivity.getResources().getString(R.string.dialog_ok), (dialogInterface, i) -> callingActivity.finish()).show();
|
||||
}
|
||||
}
|
60
app/src/main/java/com/zeapo/pwdstore/git/SyncOperation.kt
Normal file
60
app/src/main/java/com/zeapo/pwdstore/git/SyncOperation.kt
Normal file
|
@ -0,0 +1,60 @@
|
|||
package com.zeapo.pwdstore.git
|
||||
|
||||
import android.app.Activity
|
||||
import android.app.AlertDialog
|
||||
import com.zeapo.pwdstore.R
|
||||
import org.eclipse.jgit.api.AddCommand
|
||||
import org.eclipse.jgit.api.CommitCommand
|
||||
import org.eclipse.jgit.api.Git
|
||||
import org.eclipse.jgit.api.PullCommand
|
||||
import org.eclipse.jgit.api.PushCommand
|
||||
import org.eclipse.jgit.api.StatusCommand
|
||||
|
||||
import java.io.File
|
||||
|
||||
/**
|
||||
* Creates a new git operation
|
||||
*
|
||||
* @param fileDir the git working tree directory
|
||||
* @param callingActivity the calling activity
|
||||
*/
|
||||
class SyncOperation(fileDir: File, callingActivity: Activity) : GitOperation(fileDir, callingActivity) {
|
||||
private var addCommand: AddCommand? = null
|
||||
private var statusCommand: StatusCommand? = null
|
||||
private var commitCommand: CommitCommand? = null
|
||||
private var pullCommand: PullCommand? = null
|
||||
private var pushCommand: PushCommand? = null
|
||||
|
||||
/**
|
||||
* Sets the command
|
||||
*
|
||||
* @return the current object
|
||||
*/
|
||||
fun setCommands(): SyncOperation {
|
||||
val git = Git(repository)
|
||||
this.addCommand = git.add().addFilepattern(".")
|
||||
this.statusCommand = git.status()
|
||||
this.commitCommand = git.commit().setAll(true).setMessage("[Android Password Store] Sync")
|
||||
this.pullCommand = git.pull().setRebase(true).setRemote("origin")
|
||||
this.pushCommand = git.push().setPushAll().setRemote("origin")
|
||||
return this
|
||||
}
|
||||
|
||||
override fun execute() {
|
||||
if (this.provider != null) {
|
||||
this.pullCommand!!.setCredentialsProvider(this.provider)
|
||||
this.pushCommand!!.setCredentialsProvider(this.provider)
|
||||
}
|
||||
GitAsyncTask(callingActivity, true, false, this).execute(this.addCommand, this.statusCommand, this.commitCommand, this.pullCommand, this.pushCommand)
|
||||
}
|
||||
|
||||
override fun onError(errorMessage: String) {
|
||||
AlertDialog.Builder(callingActivity).setTitle(callingActivity.resources.getString(R.string.jgit_error_dialog_title))
|
||||
.setMessage("Error occured during the sync operation, "
|
||||
+ "\nPlease check the FAQ for possible reasons why this error might occur."
|
||||
+ callingActivity.resources.getString(R.string.jgit_error_dialog_text)
|
||||
+ errorMessage)
|
||||
.setPositiveButton(callingActivity.resources.getString(R.string.dialog_ok)) { _, _ -> callingActivity.finish() }
|
||||
.show()
|
||||
}
|
||||
}
|
Loading…
Reference in a new issue