aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMohamed Zenadi <zeapo@users.noreply.github.com>2015-01-04 21:49:56 +0100
committerMohamed Zenadi <zeapo@users.noreply.github.com>2015-01-04 21:49:56 +0100
commitdf8994d84f3923ba64cb36ecdad54aa29e28f2a0 (patch)
tree7eb85fa141183222ca565cb8ee6d5c977cd88729
parent33689cefc7a429e4f51607a013f6adc9c01ede94 (diff)
parent6922652173e05433bb9524b036baafb96c91ca1b (diff)
Merge pull request #57 from zeapo/feature/refactor-git
Refactoring of the git process
-rw-r--r--app/build.gradle1
-rw-r--r--app/src/androidTest/java/com/zeapo/pwdstore/ApplicationTest.java13
-rw-r--r--app/src/androidTest/java/com/zeapo/pwdstore/GitActivityClone.java111
-rw-r--r--app/src/androidTest/java/com/zeapo/pwdstore/GitActivityTest.java74
-rw-r--r--app/src/main/AndroidManifest.xml2
-rw-r--r--app/src/main/java/com/zeapo/pwdstore/PasswordStore.java28
-rw-r--r--app/src/main/java/com/zeapo/pwdstore/UserPreference.java9
-rw-r--r--app/src/main/java/com/zeapo/pwdstore/git/CloneOperation.java67
-rw-r--r--app/src/main/java/com/zeapo/pwdstore/git/GitActivity.java (renamed from app/src/main/java/com/zeapo/pwdstore/git/GitHandler.java)469
-rw-r--r--app/src/main/java/com/zeapo/pwdstore/git/GitOperation.java170
-rw-r--r--app/src/main/java/com/zeapo/pwdstore/git/PullOperation.java41
-rw-r--r--app/src/main/java/com/zeapo/pwdstore/git/PushOperation.java41
-rw-r--r--app/src/main/java/com/zeapo/pwdstore/git/config/GitConfigSessionFactory.java24
-rw-r--r--app/src/main/java/com/zeapo/pwdstore/git/config/SshConfigSessionFactory.java70
-rw-r--r--app/src/main/res/layout/activity_git_clone.xml2
-rw-r--r--app/src/main/res/menu/git_clone.xml2
-rw-r--r--app/src/main/res/values/strings.xml5
17 files changed, 758 insertions, 371 deletions
diff --git a/app/build.gradle b/app/build.gradle
index 6e107b6e..4ec80f82 100644
--- a/app/build.gradle
+++ b/app/build.gradle
@@ -32,6 +32,7 @@ dependencies {
compile project(':libraries:openpgp-api-lib')
compile 'org.eclipse.jgit:org.eclipse.jgit:3.6.0.201411121045-m1'
compile 'org.apache.commons:commons-io:1.3.2'
+ compile 'com.jayway.android.robotium:robotium-solo:5.2.1'
}
tasks.findAll { // make all tasks whose name starts with 'assemble'...
it.name.startsWith 'assemble'
diff --git a/app/src/androidTest/java/com/zeapo/pwdstore/ApplicationTest.java b/app/src/androidTest/java/com/zeapo/pwdstore/ApplicationTest.java
deleted file mode 100644
index e0cf8c74..00000000
--- a/app/src/androidTest/java/com/zeapo/pwdstore/ApplicationTest.java
+++ /dev/null
@@ -1,13 +0,0 @@
-package com.zeapo.pwdstore;
-
-import android.app.Application;
-import android.test.ApplicationTestCase;
-
-/**
- * <a href="http://d.android.com/tools/testing/testing_android.html">Testing Fundamentals</a>
- */
-public class ApplicationTest extends ApplicationTestCase<Application> {
- public ApplicationTest() {
- super(Application.class);
- }
-} \ No newline at end of file
diff --git a/app/src/androidTest/java/com/zeapo/pwdstore/GitActivityClone.java b/app/src/androidTest/java/com/zeapo/pwdstore/GitActivityClone.java
new file mode 100644
index 00000000..10d33472
--- /dev/null
+++ b/app/src/androidTest/java/com/zeapo/pwdstore/GitActivityClone.java
@@ -0,0 +1,111 @@
+package com.zeapo.pwdstore;
+
+import android.app.Activity;
+import android.app.Instrumentation;
+import android.content.Intent;
+import android.content.SharedPreferences;
+import android.preference.PreferenceManager;
+import android.test.ActivityInstrumentationTestCase2;
+import android.util.Log;
+import android.widget.Button;
+import android.widget.EditText;
+import android.widget.Spinner;
+
+import com.robotium.solo.Solo;
+import com.zeapo.pwdstore.git.GitActivity;
+import com.zeapo.pwdstore.utils.PasswordRepository;
+
+import org.apache.commons.io.FileUtils;
+
+import java.io.File;
+
+public class GitActivityClone extends ActivityInstrumentationTestCase2<GitActivity> {
+ private static final String TAG = "GitActTest";
+ private Activity gitActivity;
+ private Instrumentation mInstrumentation;
+ private SharedPreferences settings;
+
+ private Spinner protocolSpinner;
+ private Spinner connectionModeSpinner;
+ private EditText uri;
+ private EditText server_url;
+ private EditText server_port;
+ private EditText server_path;
+ private EditText server_user;
+
+ public GitActivityClone() {
+ super(GitActivity.class);
+ }
+
+ protected void setUp() throws Exception {
+ super.setUp();
+ mInstrumentation = getInstrumentation();
+
+ Intent intent = new Intent();
+ intent.putExtra("Operation", GitActivity.REQUEST_CLONE);
+ setActivityIntent(intent);
+
+ gitActivity = getActivity(); // get a references to the app under test
+ assertNotNull(gitActivity);
+
+ settings = PreferenceManager.getDefaultSharedPreferences(gitActivity.getApplicationContext());
+
+ uri = (EditText) gitActivity.findViewById(R.id.clone_uri);
+ server_url = ((EditText) gitActivity.findViewById(R.id.server_url));
+ server_port = ((EditText) gitActivity.findViewById(R.id.server_port));
+ server_path = ((EditText) gitActivity.findViewById(R.id.server_path));
+ server_user = ((EditText) gitActivity.findViewById(R.id.server_user));
+ protocolSpinner = (Spinner) gitActivity.findViewById(R.id.clone_protocol);
+ connectionModeSpinner = (Spinner) gitActivity.findViewById(R.id.connection_mode);
+
+ assertNotNull(uri);
+ assertNotNull(server_url);
+ assertNotNull(server_port);
+ assertNotNull(server_path);
+ assertNotNull(server_user);
+ assertNotNull(protocolSpinner);
+ assertNotNull(connectionModeSpinner);
+
+ assertEquals(protocolSpinner.getSelectedItem(), settings.getString("git_remote_protocol", "ssh://"));
+ assertEquals(connectionModeSpinner.getSelectedItem(), settings.getString("git_remote_auth", "ssh-key"));
+ }
+
+ public void testCloneSshUser() throws Exception {
+ final Solo solo = new Solo(getInstrumentation(), getActivity());
+ FileUtils.deleteDirectory(new File(gitActivity.getFilesDir() + gitActivity.getResources().getString(R.string.store_git)));
+ // create the repository static variable in PasswordRepository
+ PasswordRepository.getRepository(new File(gitActivity.getFilesDir() + gitActivity.getResources().getString(R.string.store_git)));
+
+ gitActivity.runOnUiThread(new Runnable() {
+ public void run() {
+ protocolSpinner.setSelection(0); // ssh://
+ }
+ });
+
+ mInstrumentation.waitForIdleSync();
+
+ solo.clearEditText(server_user);
+ solo.enterText(server_user, "testpwd");
+ solo.clearEditText(server_path);
+ solo.enterText(server_path, "repo-test");
+ solo.clearEditText(server_url);
+ solo.enterText(server_url, "192.168.1.28");
+
+ mInstrumentation.waitForIdleSync();
+
+ gitActivity.runOnUiThread(new Runnable() {
+ public void run() {
+ connectionModeSpinner.setSelection(1); // user/pwd
+ ((Button) gitActivity.findViewById(R.id.clone_button)).performClick();
+ }
+ });
+
+ mInstrumentation.waitForIdleSync();
+
+ assertTrue("Could not find the dialog!", solo.searchText(gitActivity.getResources().getString(R.string.passphrase_dialog_title)));
+ solo.enterText(solo.getEditText("Password"), "test");
+ solo.clickOnButton(gitActivity.getResources().getString(R.string.dialog_ok));
+
+ mInstrumentation.waitForIdleSync();
+ }
+}
diff --git a/app/src/androidTest/java/com/zeapo/pwdstore/GitActivityTest.java b/app/src/androidTest/java/com/zeapo/pwdstore/GitActivityTest.java
new file mode 100644
index 00000000..83995b51
--- /dev/null
+++ b/app/src/androidTest/java/com/zeapo/pwdstore/GitActivityTest.java
@@ -0,0 +1,74 @@
+package com.zeapo.pwdstore;
+
+import android.app.Activity;
+import android.app.Instrumentation;
+import android.content.Intent;
+import android.content.SharedPreferences;
+import android.preference.PreferenceManager;
+import android.test.ActivityInstrumentationTestCase2;
+import android.test.ActivityTestCase;
+import android.test.InstrumentationTestCase;
+import android.util.Log;
+import android.widget.EditText;
+import android.widget.Spinner;
+
+import com.zeapo.pwdstore.git.GitActivity;
+
+public class GitActivityTest extends ActivityInstrumentationTestCase2<GitActivity> {
+ private Activity gitActivity;
+ private Instrumentation mInstrumentation;
+ private SharedPreferences settings;
+
+ private Spinner protocolSpinner;
+ private Spinner connectionModeSpinner;
+ private EditText uri;
+ private EditText server_url;
+ private EditText server_port;
+ private EditText server_path;
+ private EditText server_user;
+
+ public GitActivityTest() {
+ super(GitActivity.class);
+ }
+
+ protected void setUp() throws Exception {
+ super.setUp();
+ mInstrumentation = getInstrumentation();
+
+ Intent intent = new Intent();
+ intent.putExtra("Operation", GitActivity.EDIT_SERVER);
+ setActivityIntent(intent);
+
+ gitActivity = getActivity(); // get a references to the app under test
+ assertNotNull(gitActivity);
+
+ settings = PreferenceManager.getDefaultSharedPreferences(gitActivity.getApplicationContext());
+
+ uri = (EditText) gitActivity.findViewById(R.id.clone_uri);
+ server_url = ((EditText) gitActivity.findViewById(R.id.server_url));
+ server_port = ((EditText) gitActivity.findViewById(R.id.server_port));
+ server_path = ((EditText) gitActivity.findViewById(R.id.server_path));
+ server_user = ((EditText) gitActivity.findViewById(R.id.server_user));
+ protocolSpinner = (Spinner) gitActivity.findViewById(R.id.clone_protocol);
+ connectionModeSpinner = (Spinner) gitActivity.findViewById(R.id.connection_mode);
+
+ assertEquals(protocolSpinner.getSelectedItem(), settings.getString("git_remote_protocol", "ssh://"));
+ assertEquals(connectionModeSpinner.getSelectedItem(), settings.getString("git_remote_auth", "ssh-key"));
+ }
+
+ /**
+ * If we change from ssh protocol to https we automatically switch to username/password auth
+ * @throws Exception
+ */
+ public void testSpinnerChange() throws Exception{
+ gitActivity.runOnUiThread(new Runnable() {
+ public void run() {
+ protocolSpinner.requestFocus();
+ protocolSpinner.setSelection(1); // 1 < is https://
+ }
+ });
+ mInstrumentation.waitForIdleSync();
+
+ assertEquals(connectionModeSpinner.getSelectedItem(), "username/password"); // 1 < is username/password
+ }
+}
diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index 4a124c94..cc21dc54 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -11,7 +11,7 @@
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
- <activity android:name=".git.GitHandler"
+ <activity android:name=".git.GitActivity"
android:parentActivityName=".PasswordStore">
<meta-data android:name="android.PARENT_ACTIVITY1"
android:value="com.zeapo.pwdstore.PasswordStore" />
diff --git a/app/src/main/java/com/zeapo/pwdstore/PasswordStore.java b/app/src/main/java/com/zeapo/pwdstore/PasswordStore.java
index f7107eff..2af74075 100644
--- a/app/src/main/java/com/zeapo/pwdstore/PasswordStore.java
+++ b/app/src/main/java/com/zeapo/pwdstore/PasswordStore.java
@@ -18,8 +18,8 @@ import android.view.MenuItem;
import android.view.View;
import com.zeapo.pwdstore.crypto.PgpHandler;
+import com.zeapo.pwdstore.git.GitActivity;
import com.zeapo.pwdstore.git.GitAsyncTask;
-import com.zeapo.pwdstore.git.GitHandler;
import com.zeapo.pwdstore.utils.PasswordItem;
import com.zeapo.pwdstore.utils.PasswordRecyclerAdapter;
import com.zeapo.pwdstore.utils.PasswordRepository;
@@ -151,9 +151,9 @@ public class PasswordStore extends ActionBarActivity {
break;
}
- intent = new Intent(this, GitHandler.class);
- intent.putExtra("Operation", GitHandler.REQUEST_PUSH);
- startActivityForResult(intent, GitHandler.REQUEST_PUSH);
+ intent = new Intent(this, GitActivity.class);
+ intent.putExtra("Operation", GitActivity.REQUEST_PUSH);
+ startActivityForResult(intent, GitActivity.REQUEST_PUSH);
this.leftActivity = true;
return true;
@@ -163,9 +163,9 @@ public class PasswordStore extends ActionBarActivity {
break;
}
- intent = new Intent(this, GitHandler.class);
- intent.putExtra("Operation", GitHandler.REQUEST_PULL);
- startActivityForResult(intent, GitHandler.REQUEST_PULL);
+ intent = new Intent(this, GitActivity.class);
+ intent.putExtra("Operation", GitActivity.REQUEST_PULL);
+ startActivityForResult(intent, GitActivity.REQUEST_PULL);
this.leftActivity = true;
return true;
@@ -186,9 +186,9 @@ public class PasswordStore extends ActionBarActivity {
}
public void getClone(View view){
- Intent intent = new Intent(this, GitHandler.class);
- intent.putExtra("Operation", GitHandler.REQUEST_CLONE);
- startActivityForResult(intent, GitHandler.REQUEST_CLONE);
+ Intent intent = new Intent(this, GitActivity.class);
+ intent.putExtra("Operation", GitActivity.REQUEST_CLONE);
+ startActivityForResult(intent, GitActivity.REQUEST_CLONE);
}
private void createRepository() {
@@ -228,7 +228,7 @@ public class PasswordStore extends ActionBarActivity {
@Override
public void onClick(DialogInterface dialogInterface, int i) {
Intent intent = new Intent(activity, UserPreference.class);
- startActivityForResult(intent, GitHandler.REQUEST_INIT);
+ startActivityForResult(intent, GitActivity.REQUEST_INIT);
}
})
.setNegativeButton(this.getResources().getString(R.string.dialog_negative), new DialogInterface.OnClickListener() {
@@ -433,7 +433,7 @@ public class PasswordStore extends ActionBarActivity {
protected void onActivityResult(int requestCode, int resultCode,
Intent data) {
if (resultCode == RESULT_OK) {
- if (requestCode == GitHandler.REQUEST_CLONE)
+ if (requestCode == GitActivity.REQUEST_CLONE)
checkLocalRepository();
switch (requestCode) {
@@ -446,10 +446,10 @@ public class PasswordStore extends ActionBarActivity {
);
refreshListAdapter();
break;
- case GitHandler.REQUEST_INIT:
+ case GitActivity.REQUEST_INIT:
initRepository(getCurrentFocus());
break;
- case GitHandler.REQUEST_PULL:
+ case GitActivity.REQUEST_PULL:
updateListAdapter();
break;
}
diff --git a/app/src/main/java/com/zeapo/pwdstore/UserPreference.java b/app/src/main/java/com/zeapo/pwdstore/UserPreference.java
index 89c1cd36..43198738 100644
--- a/app/src/main/java/com/zeapo/pwdstore/UserPreference.java
+++ b/app/src/main/java/com/zeapo/pwdstore/UserPreference.java
@@ -10,9 +10,10 @@ import android.preference.PreferenceFragment;
import android.support.v7.app.ActionBarActivity;
import android.util.Log;
import android.view.MenuItem;
+import android.widget.Toast;
import com.zeapo.pwdstore.crypto.PgpHandler;
-import com.zeapo.pwdstore.git.GitHandler;
+import com.zeapo.pwdstore.git.GitActivity;
import com.zeapo.pwdstore.utils.PasswordRepository;
import org.apache.commons.io.FileUtils;
@@ -105,8 +106,8 @@ public class UserPreference extends ActionBarActivity implements Preference.OnPr
break;
case "git_server_info":
{
- Intent intent = new Intent(this, GitHandler.class);
- intent.putExtra("Operation", GitHandler.EDIT_SERVER);
+ Intent intent = new Intent(this, GitActivity.class);
+ intent.putExtra("Operation", GitActivity.EDIT_SERVER);
startActivityForResult(intent, EDIT_GIT_INFO);
}
break;
@@ -153,7 +154,7 @@ public class UserPreference extends ActionBarActivity implements Preference.OnPr
{
try {
copySshKey(data.getData());
- Log.i("PREF", "Got key");
+ Toast.makeText(this, this.getResources().getString(R.string.ssh_key_success_dialog_title), Toast.LENGTH_LONG).show();
setResult(RESULT_OK);
finish();
} catch (IOException e)
diff --git a/app/src/main/java/com/zeapo/pwdstore/git/CloneOperation.java b/app/src/main/java/com/zeapo/pwdstore/git/CloneOperation.java
new file mode 100644
index 00000000..dc94ce3b
--- /dev/null
+++ b/app/src/main/java/com/zeapo/pwdstore/git/CloneOperation.java
@@ -0,0 +1,67 @@
+package com.zeapo.pwdstore.git;
+
+import android.app.Activity;
+
+import org.eclipse.jgit.api.CloneCommand;
+import org.eclipse.jgit.api.Git;
+
+import java.io.File;
+
+public class CloneOperation extends GitOperation {
+ private static final String TAG = "CLONEOPT";
+
+ /**
+ * 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() throws Exception {
+ if (this.provider != null) {
+ ((CloneCommand) this.command).setCredentialsProvider(this.provider);
+ }
+ new GitAsyncTask(callingActivity, true, false, CloneCommand.class).execute(this.command);
+ }
+}
diff --git a/app/src/main/java/com/zeapo/pwdstore/git/GitHandler.java b/app/src/main/java/com/zeapo/pwdstore/git/GitActivity.java
index 85872d65..637d2052 100644
--- a/app/src/main/java/com/zeapo/pwdstore/git/GitHandler.java
+++ b/app/src/main/java/com/zeapo/pwdstore/git/GitActivity.java
@@ -10,22 +10,17 @@ import android.os.Bundle;
import android.preference.PreferenceManager;
import android.support.v7.app.ActionBarActivity;
import android.text.Editable;
-import android.text.InputType;
import android.text.TextWatcher;
+import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.EditText;
-import android.widget.LinearLayout;
import android.widget.Spinner;
import android.widget.TextView;
-import com.jcraft.jsch.JSch;
-import com.jcraft.jsch.JSchException;
-import com.jcraft.jsch.Session;
-import com.jcraft.jsch.UserInfo;
import com.zeapo.pwdstore.R;
import com.zeapo.pwdstore.UserPreference;
import com.zeapo.pwdstore.utils.PasswordRepository;
@@ -34,29 +29,17 @@ import org.eclipse.jgit.api.CloneCommand;
import org.eclipse.jgit.api.Git;
import org.apache.commons.io.FileUtils;
-import org.eclipse.jgit.api.GitCommand;
-import org.eclipse.jgit.api.PullCommand;
-import org.eclipse.jgit.api.PushCommand;
-import org.eclipse.jgit.errors.UnsupportedCredentialItem;
-import org.eclipse.jgit.transport.CredentialItem;
-import org.eclipse.jgit.transport.CredentialsProvider;
-import org.eclipse.jgit.transport.CredentialsProviderUserInfo;
-import org.eclipse.jgit.transport.JschConfigSessionFactory;
-import org.eclipse.jgit.transport.OpenSshConfig;
-import org.eclipse.jgit.transport.SshSessionFactory;
-import org.eclipse.jgit.transport.URIish;
import org.eclipse.jgit.transport.UsernamePasswordCredentialsProvider;
-import org.eclipse.jgit.util.FS;
import java.io.File;
import java.io.IOException;
-import java.lang.reflect.Method;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
// TODO move the messages to strings.xml
-public class GitHandler extends ActionBarActivity {
+public class GitActivity extends ActionBarActivity {
+ private static final String TAG = "GitAct";
private Activity activity;
private Context context;
@@ -77,8 +60,6 @@ public class GitHandler extends ActionBarActivity {
public static final int REQUEST_INIT = 104;
public static final int EDIT_SERVER = 105;
- private static final int GET_SSH_KEY_FROM_CLONE = 201;
-
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
@@ -98,11 +79,11 @@ public class GitHandler extends ActionBarActivity {
case REQUEST_CLONE:
case EDIT_SERVER:
setContentView(R.layout.activity_git_clone);
+ setTitle(R.string.title_activity_git_clone);
final Spinner protcol_spinner = (Spinner) findViewById(R.id.clone_protocol);
final Spinner connection_mode_spinner = (Spinner) findViewById(R.id.connection_mode);
-
// init the spinner for connection modes
final ArrayAdapter<CharSequence> connection_mode_adapter = ArrayAdapter.createFromResource(this,
R.array.connection_modes, android.R.layout.simple_spinner_item);
@@ -131,9 +112,9 @@ public class GitHandler extends ActionBarActivity {
new AdapterView.OnItemSelectedListener() {
@Override
public void onItemSelected(AdapterView<?> adapterView, View view, int i, long l) {
- protocol = ((Spinner)findViewById(R.id.clone_protocol)).getSelectedItem().toString();
+ protocol = ((Spinner) findViewById(R.id.clone_protocol)).getSelectedItem().toString();
if (protocol.equals("ssh://")) {
- ((EditText)findViewById(R.id.clone_uri)).setHint("user@hostname:path");
+ ((EditText) findViewById(R.id.clone_uri)).setHint("user@hostname:path");
((EditText) findViewById(R.id.server_port)).setHint(R.string.default_ssh_port);
@@ -141,7 +122,7 @@ public class GitHandler extends ActionBarActivity {
connection_mode_spinner.setSelection(0);
connection_mode_spinner.setEnabled(true);
} else {
- ((EditText)findViewById(R.id.clone_uri)).setHint("hostname/path");
+ ((EditText) findViewById(R.id.clone_uri)).setHint("hostname/path");
((EditText) findViewById(R.id.server_port)).setHint(R.string.default_https_port);
@@ -158,13 +139,24 @@ public class GitHandler extends ActionBarActivity {
}
);
+ if (protocol.equals("ssh://")) {
+ protcol_spinner.setSelection(0);
+ } else {
+ protcol_spinner.setSelection(1);
+ }
+
+ if (connectionMode.equals("ssh-key")) {
+ connection_mode_spinner.setSelection(0);
+ } else {
+ connection_mode_spinner.setSelection(1);
+ }
// init the server information
final EditText server_url = ((EditText) findViewById(R.id.server_url));
final EditText server_port = ((EditText) findViewById(R.id.server_port));
final EditText server_path = ((EditText) findViewById(R.id.server_path));
final EditText server_user = ((EditText) findViewById(R.id.server_user));
- final EditText server_uri = ((EditText)findViewById(R.id.clone_uri));
+ final EditText server_uri = ((EditText) findViewById(R.id.clone_uri));
View.OnFocusChangeListener updateListener = new View.OnFocusChangeListener() {
@Override
@@ -180,7 +172,8 @@ public class GitHandler extends ActionBarActivity {
server_url.addTextChangedListener(new TextWatcher() {
@Override
- public void beforeTextChanged(CharSequence charSequence, int i, int i2, int i3) { }
+ public void beforeTextChanged(CharSequence charSequence, int i, int i2, int i3) {
+ }
@Override
public void onTextChanged(CharSequence charSequence, int i, int i2, int i3) {
@@ -189,11 +182,13 @@ public class GitHandler extends ActionBarActivity {
}
@Override
- public void afterTextChanged(Editable editable) { }
+ public void afterTextChanged(Editable editable) {
+ }
});
server_port.addTextChangedListener(new TextWatcher() {
@Override
- public void beforeTextChanged(CharSequence charSequence, int i, int i2, int i3) { }
+ public void beforeTextChanged(CharSequence charSequence, int i, int i2, int i3) {
+ }
@Override
public void onTextChanged(CharSequence charSequence, int i, int i2, int i3) {
@@ -202,11 +197,13 @@ public class GitHandler extends ActionBarActivity {
}
@Override
- public void afterTextChanged(Editable editable) { }
+ public void afterTextChanged(Editable editable) {
+ }
});
server_user.addTextChangedListener(new TextWatcher() {
@Override
- public void beforeTextChanged(CharSequence charSequence, int i, int i2, int i3) { }
+ public void beforeTextChanged(CharSequence charSequence, int i, int i2, int i3) {
+ }
@Override
public void onTextChanged(CharSequence charSequence, int i, int i2, int i3) {
@@ -215,11 +212,13 @@ public class GitHandler extends ActionBarActivity {
}
@Override
- public void afterTextChanged(Editable editable) { }
+ public void afterTextChanged(Editable editable) {
+ }
});
server_path.addTextChangedListener(new TextWatcher() {
@Override
- public void beforeTextChanged(CharSequence charSequence, int i, int i2, int i3) { }
+ public void beforeTextChanged(CharSequence charSequence, int i, int i2, int i3) {
+ }
@Override
public void onTextChanged(CharSequence charSequence, int i, int i2, int i3) {
@@ -228,7 +227,8 @@ public class GitHandler extends ActionBarActivity {
}
@Override
- public void afterTextChanged(Editable editable) { }
+ public void afterTextChanged(Editable editable) {
+ }
});
server_uri.addTextChangedListener(new TextWatcher() {
@@ -247,8 +247,7 @@ public class GitHandler extends ActionBarActivity {
}
});
- if (operationCode == EDIT_SERVER)
- {
+ if (operationCode == EDIT_SERVER) {
findViewById(R.id.clone_button).setVisibility(View.INVISIBLE);
findViewById(R.id.save_button).setVisibility(View.VISIBLE);
} else {
@@ -256,21 +255,24 @@ public class GitHandler extends ActionBarActivity {
findViewById(R.id.save_button).setVisibility(View.INVISIBLE);
}
+ updateURI();
break;
case REQUEST_PULL:
- authenticateAndRun("pullOperation");
+ pullFromRepository();
break;
case REQUEST_PUSH:
- authenticateAndRun("pushOperation");
+ pushToRepository();
break;
}
}
- /** Fills in the server_uri field with the information coming from other fields */
+ /**
+ * Fills in the server_uri field with the information coming from other fields
+ */
private void updateURI() {
EditText uri = (EditText) findViewById(R.id.clone_uri);
EditText server_url = ((EditText) findViewById(R.id.server_url));
@@ -278,11 +280,9 @@ public class GitHandler extends ActionBarActivity {
EditText server_path = ((EditText) findViewById(R.id.server_path));
EditText server_user = ((EditText) findViewById(R.id.server_user));
- if (uri != null) {
- switch (protocol)
- {
- case "ssh://":
- {
+ if (uri != null) {
+ switch (protocol) {
+ case "ssh://": {
String hostname =
server_user.getText()
+ "@" +
@@ -306,8 +306,7 @@ public class GitHandler extends ActionBarActivity {
if (!hostname.equals("@:")) uri.setText(hostname);
}
break;
- case "https://":
- {
+ case "https://": {
StringBuilder hostname = new StringBuilder();
hostname.append(server_url.getText().toString().trim());
@@ -325,13 +324,15 @@ public class GitHandler extends ActionBarActivity {
}
break;
default:
- break;
+ break;
}
}
}
- /** Splits the information in server_uri into the other fields */
+ /**
+ * Splits the information in server_uri into the other fields
+ */
private void splitURI() {
EditText server_uri = (EditText) findViewById(R.id.clone_uri);
EditText server_url = ((EditText) findViewById(R.id.server_url));
@@ -397,76 +398,35 @@ public class GitHandler extends ActionBarActivity {
return super.onOptionsItemSelected(item);
}
- protected class GitConfigSessionFactory extends JschConfigSessionFactory {
-
- protected void configure(OpenSshConfig.Host hc, Session session) {
- session.setConfig("StrictHostKeyChecking", "no");
- }
+ /**
+ * Saves the configuration found in the form
+ */
+ private void saveConfiguration() {
+ // remember the settings
+ SharedPreferences.Editor editor = settings.edit();
- @Override
- protected JSch
- getJSch(final OpenSshConfig.Host hc, FS fs) throws JSchException {
- JSch jsch = super.getJSch(hc, fs);
- jsch.removeAllIdentity();
- return jsch;
- }
+ editor.putString("git_remote_server", ((EditText) findViewById(R.id.server_url)).getText().toString());
+ editor.putString("git_remote_location", ((EditText) findViewById(R.id.server_path)).getText().toString());
+ editor.putString("git_remote_username", ((EditText) findViewById(R.id.server_user)).getText().toString());
+ editor.putString("git_remote_protocol", protocol);
+ editor.putString("git_remote_auth", connectionMode);
+ editor.putString("git_remote_port", port);
+ editor.commit();
}
- protected class SshConfigSessionFactory extends GitConfigSessionFactory {
- private String sshKey;
- private String passphrase;
-
- public SshConfigSessionFactory(String sshKey, String passphrase) {
- this.sshKey = sshKey;
- this.passphrase = passphrase;
- }
-
- @Override
- protected JSch
- getJSch(final OpenSshConfig.Host hc, FS fs) throws JSchException {
- JSch jsch = super.getJSch(hc, fs);
- jsch.removeAllIdentity();
- jsch.addIdentity(sshKey);
- return jsch;
- }
-
- @Override
- protected void configure(OpenSshConfig.Host hc, Session session) {
- session.setConfig("StrictHostKeyChecking", "no");
-
- CredentialsProvider provider = new CredentialsProvider() {
- @Override
- public boolean isInteractive() {
- return false;
- }
-
- @Override
- public boolean supports(CredentialItem... items) {
- return true;
- }
-
- @Override
- public boolean get(URIish uri, CredentialItem... items) throws UnsupportedCredentialItem {
- for (CredentialItem item : items) {
- if (item instanceof CredentialItem.Username) {
- ((CredentialItem.Username) item).setValue(settings.getString("git_remote_username", "git"));
- continue;
- }
- if (item instanceof CredentialItem.StringType) {
- ((CredentialItem.StringType) item).setValue(passphrase);
- }
- }
- return true;
- }
- };
- UserInfo userInfo = new CredentialsProviderUserInfo(session, provider);
- session.setUserInfo(userInfo);
- }
+ /**
+ * Save the repository information to the shared preferences settings
+ *
+ * @param view
+ */
+ public void saveConfiguration(View view) {
+ saveConfiguration();
+ PasswordRepository.addRemote("origin", ((EditText) findViewById(R.id.clone_uri)).getText().toString(), true);
}
-
/**
* Clones the repository, the directory exists, deletes it
+ *
* @param view
*/
public void cloneRepository(View view) {
@@ -505,8 +465,7 @@ public class GitHandler extends ActionBarActivity {
username = hostname.split("@")[0];
}
-
- if (localDir.exists()) {
+ if (localDir.exists() && localDir.listFiles().length != 0) {
new AlertDialog.Builder(this).
setTitle(R.string.dialog_delete_title).
setMessage(R.string.dialog_delete_msg).
@@ -516,7 +475,15 @@ public class GitHandler extends ActionBarActivity {
public void onClick(DialogInterface dialog, int id) {
try {
FileUtils.deleteDirectory(localDir);
- authenticateAndRun("cloneOperation");
+ try {
+ new CloneOperation(localDir, activity)
+ .setCommand(hostname)
+ .executeAfterAuthentication(connectionMode, settings.getString("git_remote_username", "git"), new File(getFilesDir() + "/.ssh_key"));
+ } catch (Exception e) {
+ //This is what happens when jgit fails :(
+ //TODO Handle the diffent cases of exceptions
+ e.printStackTrace();
+ }
} catch (IOException e) {
//TODO Handle the exception correctly if we are unable to delete the directory...
e.printStackTrace();
@@ -538,8 +505,12 @@ public class GitHandler extends ActionBarActivity {
).
show();
} else {
+ saveConfiguration();
+
try {
- authenticateAndRun("cloneOperation");
+ new CloneOperation(localDir, activity)
+ .setCommand(hostname)
+ .executeAfterAuthentication(connectionMode, settings.getString("git_remote_username", "git"), new File(getFilesDir() + "/.ssh_key"));
} catch (Exception e) {
//This is what happens when jgit fails :(
//TODO Handle the diffent cases of exceptions
@@ -548,53 +519,28 @@ public class GitHandler extends ActionBarActivity {
}
}
-
/**
- * Save the repository information to the shared preferences settings
- * @param view
+ * Pull the latest changes from the remote repository and merges them locally
*/
- public void saveConfiguration(View view) {
- // remember the settings
- SharedPreferences.Editor editor = settings.edit();
-
- editor.putString("git_remote_server", ((EditText) findViewById(R.id.server_url)).getText().toString());
- editor.putString("git_remote_location", ((EditText) findViewById(R.id.server_path)).getText().toString());
- editor.putString("git_remote_username", ((EditText) findViewById(R.id.server_user)).getText().toString());
- editor.putString("git_remote_protocol", protocol);
- editor.putString("git_remote_auth", connectionMode);
- editor.putString("git_remote_port", port);
- editor.commit();
-
- PasswordRepository.addRemote("origin", ((EditText) findViewById(R.id.clone_uri)).getText().toString(), true);
+ public void pullFromRepository() {
+ syncRepository(REQUEST_PULL);
}
- public void cloneOperation(UsernamePasswordCredentialsProvider provider) {
-
- // remember the settings
- SharedPreferences.Editor editor = settings.edit();
-
- editor.putString("git_remote_server", ((EditText) findViewById(R.id.server_url)).getText().toString());
- editor.putString("git_remote_location", ((EditText) findViewById(R.id.server_path)).getText().toString());
- editor.putString("git_remote_username", ((EditText) findViewById(R.id.server_user)).getText().toString());
- editor.putString("git_remote_protocol", protocol);
- editor.putString("git_remote_auth", connectionMode);
- editor.putString("git_remote_port", port);
- editor.commit();
-
- CloneCommand cmd = Git.cloneRepository().
- setCredentialsProvider(provider).
- setCloneAllBranches(true).
- setDirectory(localDir).
- setURI(hostname);
-
- new GitAsyncTask(activity, true, false, CloneCommand.class).execute(cmd);
+ /**
+ * Pushes the latest changes from the local repository to the remote one
+ */
+ public void pushToRepository() {
+ syncRepository(REQUEST_PUSH);
}
- public void pullOperation(UsernamePasswordCredentialsProvider provider) {
-
+ /**
+ * Syncs the local repository with the remote one (either pull or push)
+ * @param operation the operation to execute can be REQUEST_PULL or REQUEST_PUSH
+ */
+ private void syncRepository(int operation) {
if (settings.getString("git_remote_username", "").isEmpty() ||
- settings.getString("git_remote_server", "").isEmpty() ||
- settings.getString("git_remote_location", "").isEmpty() )
+ settings.getString("git_remote_server", "").isEmpty() ||
+ settings.getString("git_remote_location", "").isEmpty())
new AlertDialog.Builder(this)
.setMessage(activity.getResources().getString(R.string.set_information_dialog_text))
.setPositiveButton(activity.getResources().getString(R.string.dialog_positive), new DialogInterface.OnClickListener() {
@@ -616,185 +562,23 @@ public class GitHandler extends ActionBarActivity {
else {
// check that the remote origin is here, else add it
- PasswordRepository.addRemote("origin", settings.getString("git_remote_username", "user")
- + "@" +
- settings.getString("git_remote_server", "server.com").trim()
- + ":" +
- settings.getString("git_remote_location", "path/to/repository"), false);
-
- GitCommand cmd;
- if (provider != null)
- cmd = new Git(PasswordRepository.getRepository(new File("")))
- .pull()
- .setRebase(true)
- .setRemote("origin")
- .setCredentialsProvider(provider);
- else
- cmd = new Git(PasswordRepository.getRepository(new File("")))
- .pull()
- .setRebase(true)
- .setRemote("origin");
-
- new GitAsyncTask(activity, true, false, PullCommand.class).execute(cmd);
- }
- }
-
+ PasswordRepository.addRemote("origin", hostname, false);
+ GitOperation op;
- public void pushOperation(UsernamePasswordCredentialsProvider provider) {
- if (settings.getString("git_remote_username", "user").isEmpty() ||
- settings.getString("git_remote_server", "server.com").trim().isEmpty() ||
- settings.getString("git_remote_location", "path/to/repository").isEmpty() )
- new AlertDialog.Builder(this)
- .setMessage("You have to set the information about the server before synchronizing with the server")
- .setPositiveButton("On my way!", new DialogInterface.OnClickListener() {
- @Override
- public void onClick(DialogInterface dialogInterface, int i) {
- Intent intent = new Intent(activity, UserPreference.class);
- startActivityForResult(intent, REQUEST_PUSH);
- }
- })
- .setNegativeButton("Nah... later", new DialogInterface.OnClickListener() {
- @Override
- public void onClick(DialogInterface dialogInterface, int i) {
- // do nothing :(
- setResult(RESULT_OK);
- finish();
- }
- })
- .show();
-
- else {
- // check that the remote origin is here, else add it
- PasswordRepository.addRemote("origin", settings.getString("git_remote_username", "user")
- + "@" +
- settings.getString("git_remote_server", "server.com").trim()
- + ":" +
- settings.getString("git_remote_location", "path/to/repository"), false);
-
- GitCommand cmd;
- if (provider != null)
- cmd = new Git(PasswordRepository.getRepository(new File("")))
- .push()
- .setPushAll()
- .setRemote("origin")
- .setCredentialsProvider(provider);
- else
- cmd = new Git(PasswordRepository.getRepository(new File("")))
- .push()
- .setPushAll()
- .setRemote("origin");
-
-
- new GitAsyncTask(activity, true, false, PushCommand.class).execute(cmd);
- }
- }
-
- /** Finds the method and provides it with authentication paramters via invokeWithAuthentication */
- private void authenticateAndRun(String operation) {
- try {
- invokeWithAuthentication(this, GitHandler.class.getMethod(operation, UsernamePasswordCredentialsProvider.class));
- } catch (Exception e) {
- e.printStackTrace();
- }
- }
-
- /** Calls a method encapsulating a GitCommand and providing it with authentication parameters
- *
- * @param activity
- * @param method
- */
- private void invokeWithAuthentication(final GitHandler activity, final Method method) {
-
- if (connectionMode.equalsIgnoreCase("ssh-key")) {
- final File sshKey = new File(getFilesDir() + "/.ssh_key");
- if (!sshKey.exists()) {
- new AlertDialog.Builder(this)
- .setMessage(activity.getResources().getString(R.string.ssh_preferences_dialog_text))
- .setTitle(activity.getResources().getString(R.string.ssh_preferences_dialog_title))
- .setPositiveButton(activity.getResources().getString(R.string.dialog_ok), new DialogInterface.OnClickListener() {
- @Override
- public void onClick(DialogInterface dialog, int id) {
- try {
- Intent intent = new Intent(getApplicationContext(), UserPreference.class);
- intent.putExtra("operation", "get_ssh_key");
- startActivityForResult(intent, GET_SSH_KEY_FROM_CLONE);
- } catch (Exception e) {
- System.out.println("Exception caught :(");
- e.printStackTrace();
- }
- }
- }).setNegativeButton(activity.getResources().getString(R.string.dialog_cancel), new DialogInterface.OnClickListener() {
- @Override
- public void onClick(DialogInterface dialog, int id) {
- // Do nothing...
- }
- }).show();
+ if (operation == REQUEST_PULL) {
+ op = new PullOperation(localDir, activity).setCommand();
+ } else if (operation == REQUEST_PUSH) {
+ op = new PushOperation(localDir, activity).setCommand();
} else {
- final EditText passphrase = new EditText(activity);
- passphrase.setHint("Passphrase");
- passphrase.setWidth(LinearLayout.LayoutParams.MATCH_PARENT);
- passphrase.setInputType(InputType.TYPE_CLASS_TEXT | InputType.TYPE_TEXT_VARIATION_PASSWORD);
-
- new AlertDialog.Builder(activity)
- .setTitle(activity.getResources().getString(R.string.passphrase_dialog_title))
- .setMessage(activity.getResources().getString(R.string.passphrase_dialog_text))
- .setView(passphrase)
- .setPositiveButton(activity.getResources().getString(R.string.dialog_ok), new DialogInterface.OnClickListener() {
- public void onClick(DialogInterface dialog, int whichButton) {
-
- SshSessionFactory.setInstance(new GitConfigSessionFactory());
- try {
-
- JschConfigSessionFactory sessionFactory = new SshConfigSessionFactory(sshKey.getAbsolutePath(), passphrase.getText().toString());
- SshSessionFactory.setInstance(sessionFactory);
-
- try {
- method.invoke(activity, (UsernamePasswordCredentialsProvider) null);
- } catch (Exception e){
- e.printStackTrace();
- }
-
- } catch (Exception e){
- e.printStackTrace();
- }
-
- }
- }).setNegativeButton(activity.getResources().getString(R.string.dialog_cancel), new DialogInterface.OnClickListener() {
- public void onClick(DialogInterface dialog, int whichButton) {
- // Do nothing.
- }
- }).show();
+ Log.e(TAG, "Sync operation not recognized : " + operation);
+ return;
}
- } else {
- final EditText password = new EditText(activity);
- password.setHint("Password");
- password.setWidth(LinearLayout.LayoutParams.MATCH_PARENT);
- password.setInputType(InputType.TYPE_CLASS_TEXT | InputType.TYPE_TEXT_VARIATION_PASSWORD);
-
- new AlertDialog.Builder(activity)
- .setTitle(activity.getResources().getString(R.string.passphrase_dialog_title))
- .setMessage(activity.getResources().getString(R.string.password_dialog_text))
- .setView(password)
- .setPositiveButton(activity.getResources().getString(R.string.dialog_ok), new DialogInterface.OnClickListener() {
- public void onClick(DialogInterface dialog, int whichButton) {
-
- SshSessionFactory.setInstance(new GitConfigSessionFactory());
- try {
- method.invoke(activity,
- new UsernamePasswordCredentialsProvider(
- settings.getString("git_remote_username", "git"),
- password.getText().toString())
- );
- } catch (Exception e){
- e.printStackTrace();
- }
- }
- }).setNegativeButton(activity.getResources().getString(R.string.dialog_cancel), new DialogInterface.OnClickListener() {
- public void onClick(DialogInterface dialog, int whichButton) {
- // Do nothing.
- }
- }).show();
+ try {
+ op.executeAfterAuthentication(connectionMode, settings.getString("git_remote_username", "git"), new File(getFilesDir() + "/.ssh_key"));
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
}
}
@@ -807,16 +591,31 @@ public class GitHandler extends ActionBarActivity {
}
if (resultCode == RESULT_OK) {
+ GitOperation op;
switch (requestCode) {
case REQUEST_PULL:
- authenticateAndRun("pullOperation");
+ op = new PullOperation(localDir, activity).setCommand();
break;
+
case REQUEST_PUSH:
- authenticateAndRun("pushOperation");
+ op = new PushOperation(localDir, activity).setCommand();
break;
- case GET_SSH_KEY_FROM_CLONE:
- authenticateAndRun("cloneOperation");
+
+ case GitOperation.GET_SSH_KEY_FROM_CLONE:
+ op = new CloneOperation(localDir, activity).setCommand(hostname);
+ break;
+ default:
+ Log.e(TAG, "Operation not recognized : " + resultCode);
+ setResult(RESULT_CANCELED);
+ finish();
+ return;
+ }
+
+ try {
+ op.executeAfterAuthentication(connectionMode, settings.getString("git_remote_username", "git"), new File(getFilesDir() + "/.ssh_key"));
+ } catch (Exception e) {
+ e.printStackTrace();
}
}
diff --git a/app/src/main/java/com/zeapo/pwdstore/git/GitOperation.java b/app/src/main/java/com/zeapo/pwdstore/git/GitOperation.java
new file mode 100644
index 00000000..60112c90
--- /dev/null
+++ b/app/src/main/java/com/zeapo/pwdstore/git/GitOperation.java
@@ -0,0 +1,170 @@
+package com.zeapo.pwdstore.git;
+
+import android.app.Activity;
+import android.app.AlertDialog;
+import android.content.DialogInterface;
+import android.content.Intent;
+import android.support.annotation.Nullable;
+import android.text.InputType;
+import android.util.Log;
+import android.widget.EditText;
+import android.widget.LinearLayout;
+
+import com.zeapo.pwdstore.R;
+import com.zeapo.pwdstore.UserPreference;
+import com.zeapo.pwdstore.git.config.GitConfigSessionFactory;
+import com.zeapo.pwdstore.git.config.SshConfigSessionFactory;
+import com.zeapo.pwdstore.utils.PasswordRepository;
+
+import org.eclipse.jgit.api.CloneCommand;
+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 {
+ private static final String TAG = "GitOpt";
+ public static final int GET_SSH_KEY_FROM_CLONE = 201;
+
+ protected final Repository repository;
+ protected final Activity callingActivity;
+ protected UsernamePasswordCredentialsProvider provider;
+ protected 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
+ */
+ public 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
+ */
+ public GitOperation setAuthentication(File sshKey, String username, String passphrase) {
+ JschConfigSessionFactory sessionFactory = new SshConfigSessionFactory(sshKey.getAbsolutePath(), username, passphrase);
+ SshSessionFactory.setInstance(sessionFactory);
+ this.provider = null;
+ return this;
+ }
+
+ /**
+ * Executes the GitCommand in an async task
+ *
+ * @throws Exception
+ */
+ public abstract void execute() throws Exception;
+
+ /**
+ * 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
+ * @throws Exception
+ */
+ public void executeAfterAuthentication(String connectionMode, final String username, @Nullable final File sshKey) throws Exception {
+ 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.dialog_ok), new DialogInterface.OnClickListener() {
+ @Override
+ public void onClick(DialogInterface dialog, int 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.dialog_cancel), new DialogInterface.OnClickListener() {
+ @Override
+ public void onClick(DialogInterface dialog, int id) {
+ // Do nothing...
+ }
+ }).show();
+ } else {
+ final EditText passphrase = new EditText(callingActivity);
+ passphrase.setHint("Passphrase");
+ passphrase.setWidth(LinearLayout.LayoutParams.MATCH_PARENT);
+ passphrase.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.passphrase_dialog_text))
+ .setView(passphrase)
+ .setPositiveButton(callingActivity.getResources().getString(R.string.dialog_ok), new DialogInterface.OnClickListener() {
+ public void onClick(DialogInterface dialog, int whichButton) {
+ try {
+ // Authenticate using the ssh-key and then execute the command
+ setAuthentication(sshKey, username, passphrase.getText().toString()).execute();
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+
+ }
+ }).setNegativeButton(callingActivity.getResources().getString(R.string.dialog_cancel), new DialogInterface.OnClickListener() {
+ public void onClick(DialogInterface dialog, int whichButton) {
+ // Do nothing.
+ }
+ }).show();
+ }
+ } 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), new DialogInterface.OnClickListener() {
+ public void onClick(DialogInterface dialog, int whichButton) {
+ // authenticate using the user/pwd and then execute the command
+ try {
+ setAuthentication(username, password.getText().toString()).execute();
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+
+ }
+ }).setNegativeButton(callingActivity.getResources().getString(R.string.dialog_cancel), new DialogInterface.OnClickListener() {
+ public void onClick(DialogInterface dialog, int whichButton) {
+ // Do nothing.
+ }
+ }).show();
+ }
+ }
+}
diff --git a/app/src/main/java/com/zeapo/pwdstore/git/PullOperation.java b/app/src/main/java/com/zeapo/pwdstore/git/PullOperation.java
new file mode 100644
index 00000000..abf4bfe6
--- /dev/null
+++ b/app/src/main/java/com/zeapo/pwdstore/git/PullOperation.java
@@ -0,0 +1,41 @@
+package com.zeapo.pwdstore.git;
+
+import android.app.Activity;
+
+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() throws Exception {
+ if (this.provider != null) {
+ ((PullCommand) this.command).setCredentialsProvider(this.provider);
+ }
+ new GitAsyncTask(callingActivity, true, false, PullCommand.class).execute(this.command);
+ }
+}
diff --git a/app/src/main/java/com/zeapo/pwdstore/git/PushOperation.java b/app/src/main/java/com/zeapo/pwdstore/git/PushOperation.java
new file mode 100644
index 00000000..73ed05ff
--- /dev/null
+++ b/app/src/main/java/com/zeapo/pwdstore/git/PushOperation.java
@@ -0,0 +1,41 @@
+package com.zeapo.pwdstore.git;
+
+import android.app.Activity;
+
+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() throws Exception {
+ if (this.provider != null) {
+ ((PushCommand) this.command).setCredentialsProvider(this.provider);
+ }
+ new GitAsyncTask(callingActivity, true, false, PushCommand.class).execute(this.command);
+ }
+}
diff --git a/app/src/main/java/com/zeapo/pwdstore/git/config/GitConfigSessionFactory.java b/app/src/main/java/com/zeapo/pwdstore/git/config/GitConfigSessionFactory.java
new file mode 100644
index 00000000..ab23361e
--- /dev/null
+++ b/app/src/main/java/com/zeapo/pwdstore/git/config/GitConfigSessionFactory.java
@@ -0,0 +1,24 @@
+package com.zeapo.pwdstore.git.config;
+
+import com.jcraft.jsch.JSch;
+import com.jcraft.jsch.JSchException;
+import com.jcraft.jsch.Session;
+
+import org.eclipse.jgit.transport.JschConfigSessionFactory;
+import org.eclipse.jgit.transport.OpenSshConfig;
+import org.eclipse.jgit.util.FS;
+
+public class GitConfigSessionFactory extends JschConfigSessionFactory {
+
+ protected void configure(OpenSshConfig.Host hc, Session session) {
+ session.setConfig("StrictHostKeyChecking", "no");
+ }
+
+ @Override
+ protected JSch
+ getJSch(final OpenSshConfig.Host hc, FS fs) throws JSchException {
+ JSch jsch = super.getJSch(hc, fs);
+ jsch.removeAllIdentity();
+ return jsch;
+ }
+} \ No newline at end of file
diff --git a/app/src/main/java/com/zeapo/pwdstore/git/config/SshConfigSessionFactory.java b/app/src/main/java/com/zeapo/pwdstore/git/config/SshConfigSessionFactory.java
new file mode 100644
index 00000000..333a6325
--- /dev/null
+++ b/app/src/main/java/com/zeapo/pwdstore/git/config/SshConfigSessionFactory.java
@@ -0,0 +1,70 @@
+package com.zeapo.pwdstore.git.config;
+
+import android.content.SharedPreferences;
+
+import com.jcraft.jsch.JSch;
+import com.jcraft.jsch.JSchException;
+import com.jcraft.jsch.Session;
+import com.jcraft.jsch.UserInfo;
+
+import org.eclipse.jgit.errors.UnsupportedCredentialItem;
+import org.eclipse.jgit.transport.CredentialItem;
+import org.eclipse.jgit.transport.CredentialsProvider;
+import org.eclipse.jgit.transport.CredentialsProviderUserInfo;
+import org.eclipse.jgit.transport.OpenSshConfig;
+import org.eclipse.jgit.transport.URIish;
+import org.eclipse.jgit.util.FS;
+
+public class SshConfigSessionFactory extends GitConfigSessionFactory {
+ private String sshKey;
+ private String passphrase;
+ private String username;
+
+ public SshConfigSessionFactory(String sshKey, String username, String passphrase) {
+ this.sshKey = sshKey;
+ this.passphrase = passphrase;
+ this.username = username;
+ }
+
+ @Override
+ protected JSch
+ getJSch(final OpenSshConfig.Host hc, FS fs) throws JSchException {
+ JSch jsch = super.getJSch(hc, fs);
+ jsch.removeAllIdentity();
+ jsch.addIdentity(sshKey);
+ return jsch;
+ }
+
+ @Override
+ protected void configure(OpenSshConfig.Host hc, Session session) {
+ session.setConfig("StrictHostKeyChecking", "no");
+
+ CredentialsProvider provider = new CredentialsProvider() {
+ @Override
+ public boolean isInteractive() {
+ return false;
+ }
+
+ @Override
+ public boolean supports(CredentialItem... items) {
+ return true;
+ }
+
+ @Override
+ public boolean get(URIish uri, CredentialItem... items) throws UnsupportedCredentialItem {
+ for (CredentialItem item : items) {
+ if (item instanceof CredentialItem.Username) {
+ ((CredentialItem.Username) item).setValue(username);
+ continue;
+ }
+ if (item instanceof CredentialItem.StringType) {
+ ((CredentialItem.StringType) item).setValue(passphrase);
+ }
+ }
+ return true;
+ }
+ };
+ UserInfo userInfo = new CredentialsProviderUserInfo(session, provider);
+ session.setUserInfo(userInfo);
+ }
+} \ No newline at end of file
diff --git a/app/src/main/res/layout/activity_git_clone.xml b/app/src/main/res/layout/activity_git_clone.xml
index 07d57934..d53a2201 100644
--- a/app/src/main/res/layout/activity_git_clone.xml
+++ b/app/src/main/res/layout/activity_git_clone.xml
@@ -6,7 +6,7 @@
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
android:paddingBottom="@dimen/activity_vertical_margin"
- tools:context="com.zeapo.pwdstore.git.GitHandler"
+ tools:context="com.zeapo.pwdstore.git.GitActivity"
android:background="@android:color/white">
<LinearLayout
android:layout_width="match_parent"
diff --git a/app/src/main/res/menu/git_clone.xml b/app/src/main/res/menu/git_clone.xml
index 4a240712..092a8b2b 100644
--- a/app/src/main/res/menu/git_clone.xml
+++ b/app/src/main/res/menu/git_clone.xml
@@ -1,7 +1,7 @@
<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
xmlns:pwstore="http://schemas.android.com/apk/res-auto"
- tools:context="com.zeapo.pwdstore.git.GitHandler" >
+ tools:context="com.zeapo.pwdstore.git.GitActivity" >
<item android:id="@+id/user_pref"
android:title="@string/action_settings"
android:orderInCategory="100"
diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml
index 86885674..8cf8d140 100644
--- a/app/src/main/res/values/strings.xml
+++ b/app/src/main/res/values/strings.xml
@@ -12,7 +12,7 @@
<string name="dialog_delete_msg">Target directory already exist. Current version support only a single store. Do you want to delete the current password store directory?</string>
<string name="dialog_delete">Delete directory</string>
<string name="dialog_do_not_delete">Cancel</string>
- <string name="title_activity_git_clone">Clone repository</string>
+ <string name="title_activity_git_clone">Repository information</string>
<!-- Password Store -->
<string name="creation_dialog_text">Please clone or create a new repository below before trying to add a password or any synchronization operation.</string>
@@ -41,7 +41,7 @@
<!-- Git Async Task -->
<string name="running_dialog_text">Running command...</string>
<string name="jgit_error_dialog_title">Internal exception occurred</string>
- <string name="jgit_error_dialog_text">Message from jgit: /n</string>
+ <string name="jgit_error_dialog_text">Message from jgit: \n</string>
<!-- Git Handler -->
<string name="read_only_dialog_text">You are about to use a read-only repository, you will not be able to push to it</string>
@@ -108,6 +108,7 @@
<string name="pref_password_dialog_title">Set the time you want the password to be in clipboard</string>
<string name="pref_copy_title">Automatically Copy Password</string>
<string name="pref_copy_dialog_title">Automatically copy the password to the clipboard after decryption was successful.</string>
+ <string name="ssh_key_success_dialog_title" translatable="false">SSH-key imported</string>
<string name="ssh_key_error_dialog_title">Error while trying to import the ssh-key</string>
<string name="ssh_key_error_dialog_text">Message : \n</string>
<string name="pref_recursive_filter">Recursive filtering</string>