Merge pull request #57 from zeapo/feature/refactor-git
Refactoring of the git process
This commit is contained in:
commit
df8994d84f
17 changed files with 759 additions and 372 deletions
|
@ -32,6 +32,7 @@ dependencies {
|
||||||
compile project(':libraries:openpgp-api-lib')
|
compile project(':libraries:openpgp-api-lib')
|
||||||
compile 'org.eclipse.jgit:org.eclipse.jgit:3.6.0.201411121045-m1'
|
compile 'org.eclipse.jgit:org.eclipse.jgit:3.6.0.201411121045-m1'
|
||||||
compile 'org.apache.commons:commons-io:1.3.2'
|
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'...
|
tasks.findAll { // make all tasks whose name starts with 'assemble'...
|
||||||
it.name.startsWith 'assemble'
|
it.name.startsWith 'assemble'
|
||||||
|
|
|
@ -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);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -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();
|
||||||
|
}
|
||||||
|
}
|
|
@ -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
|
||||||
|
}
|
||||||
|
}
|
|
@ -11,7 +11,7 @@
|
||||||
<category android:name="android.intent.category.LAUNCHER" />
|
<category android:name="android.intent.category.LAUNCHER" />
|
||||||
</intent-filter>
|
</intent-filter>
|
||||||
</activity>
|
</activity>
|
||||||
<activity android:name=".git.GitHandler"
|
<activity android:name=".git.GitActivity"
|
||||||
android:parentActivityName=".PasswordStore">
|
android:parentActivityName=".PasswordStore">
|
||||||
<meta-data android:name="android.PARENT_ACTIVITY1"
|
<meta-data android:name="android.PARENT_ACTIVITY1"
|
||||||
android:value="com.zeapo.pwdstore.PasswordStore" />
|
android:value="com.zeapo.pwdstore.PasswordStore" />
|
||||||
|
|
|
@ -18,8 +18,8 @@ import android.view.MenuItem;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
|
|
||||||
import com.zeapo.pwdstore.crypto.PgpHandler;
|
import com.zeapo.pwdstore.crypto.PgpHandler;
|
||||||
|
import com.zeapo.pwdstore.git.GitActivity;
|
||||||
import com.zeapo.pwdstore.git.GitAsyncTask;
|
import com.zeapo.pwdstore.git.GitAsyncTask;
|
||||||
import com.zeapo.pwdstore.git.GitHandler;
|
|
||||||
import com.zeapo.pwdstore.utils.PasswordItem;
|
import com.zeapo.pwdstore.utils.PasswordItem;
|
||||||
import com.zeapo.pwdstore.utils.PasswordRecyclerAdapter;
|
import com.zeapo.pwdstore.utils.PasswordRecyclerAdapter;
|
||||||
import com.zeapo.pwdstore.utils.PasswordRepository;
|
import com.zeapo.pwdstore.utils.PasswordRepository;
|
||||||
|
@ -151,9 +151,9 @@ public class PasswordStore extends ActionBarActivity {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
intent = new Intent(this, GitHandler.class);
|
intent = new Intent(this, GitActivity.class);
|
||||||
intent.putExtra("Operation", GitHandler.REQUEST_PUSH);
|
intent.putExtra("Operation", GitActivity.REQUEST_PUSH);
|
||||||
startActivityForResult(intent, GitHandler.REQUEST_PUSH);
|
startActivityForResult(intent, GitActivity.REQUEST_PUSH);
|
||||||
this.leftActivity = true;
|
this.leftActivity = true;
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
|
@ -163,9 +163,9 @@ public class PasswordStore extends ActionBarActivity {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
intent = new Intent(this, GitHandler.class);
|
intent = new Intent(this, GitActivity.class);
|
||||||
intent.putExtra("Operation", GitHandler.REQUEST_PULL);
|
intent.putExtra("Operation", GitActivity.REQUEST_PULL);
|
||||||
startActivityForResult(intent, GitHandler.REQUEST_PULL);
|
startActivityForResult(intent, GitActivity.REQUEST_PULL);
|
||||||
this.leftActivity = true;
|
this.leftActivity = true;
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
|
@ -186,9 +186,9 @@ public class PasswordStore extends ActionBarActivity {
|
||||||
}
|
}
|
||||||
|
|
||||||
public void getClone(View view){
|
public void getClone(View view){
|
||||||
Intent intent = new Intent(this, GitHandler.class);
|
Intent intent = new Intent(this, GitActivity.class);
|
||||||
intent.putExtra("Operation", GitHandler.REQUEST_CLONE);
|
intent.putExtra("Operation", GitActivity.REQUEST_CLONE);
|
||||||
startActivityForResult(intent, GitHandler.REQUEST_CLONE);
|
startActivityForResult(intent, GitActivity.REQUEST_CLONE);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void createRepository() {
|
private void createRepository() {
|
||||||
|
@ -228,7 +228,7 @@ public class PasswordStore extends ActionBarActivity {
|
||||||
@Override
|
@Override
|
||||||
public void onClick(DialogInterface dialogInterface, int i) {
|
public void onClick(DialogInterface dialogInterface, int i) {
|
||||||
Intent intent = new Intent(activity, UserPreference.class);
|
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() {
|
.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,
|
protected void onActivityResult(int requestCode, int resultCode,
|
||||||
Intent data) {
|
Intent data) {
|
||||||
if (resultCode == RESULT_OK) {
|
if (resultCode == RESULT_OK) {
|
||||||
if (requestCode == GitHandler.REQUEST_CLONE)
|
if (requestCode == GitActivity.REQUEST_CLONE)
|
||||||
checkLocalRepository();
|
checkLocalRepository();
|
||||||
|
|
||||||
switch (requestCode) {
|
switch (requestCode) {
|
||||||
|
@ -446,10 +446,10 @@ public class PasswordStore extends ActionBarActivity {
|
||||||
);
|
);
|
||||||
refreshListAdapter();
|
refreshListAdapter();
|
||||||
break;
|
break;
|
||||||
case GitHandler.REQUEST_INIT:
|
case GitActivity.REQUEST_INIT:
|
||||||
initRepository(getCurrentFocus());
|
initRepository(getCurrentFocus());
|
||||||
break;
|
break;
|
||||||
case GitHandler.REQUEST_PULL:
|
case GitActivity.REQUEST_PULL:
|
||||||
updateListAdapter();
|
updateListAdapter();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,9 +10,10 @@ import android.preference.PreferenceFragment;
|
||||||
import android.support.v7.app.ActionBarActivity;
|
import android.support.v7.app.ActionBarActivity;
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
import android.view.MenuItem;
|
import android.view.MenuItem;
|
||||||
|
import android.widget.Toast;
|
||||||
|
|
||||||
import com.zeapo.pwdstore.crypto.PgpHandler;
|
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 com.zeapo.pwdstore.utils.PasswordRepository;
|
||||||
|
|
||||||
import org.apache.commons.io.FileUtils;
|
import org.apache.commons.io.FileUtils;
|
||||||
|
@ -105,8 +106,8 @@ public class UserPreference extends ActionBarActivity implements Preference.OnPr
|
||||||
break;
|
break;
|
||||||
case "git_server_info":
|
case "git_server_info":
|
||||||
{
|
{
|
||||||
Intent intent = new Intent(this, GitHandler.class);
|
Intent intent = new Intent(this, GitActivity.class);
|
||||||
intent.putExtra("Operation", GitHandler.EDIT_SERVER);
|
intent.putExtra("Operation", GitActivity.EDIT_SERVER);
|
||||||
startActivityForResult(intent, EDIT_GIT_INFO);
|
startActivityForResult(intent, EDIT_GIT_INFO);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
@ -153,7 +154,7 @@ public class UserPreference extends ActionBarActivity implements Preference.OnPr
|
||||||
{
|
{
|
||||||
try {
|
try {
|
||||||
copySshKey(data.getData());
|
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);
|
setResult(RESULT_OK);
|
||||||
finish();
|
finish();
|
||||||
} catch (IOException e)
|
} catch (IOException e)
|
||||||
|
|
67
app/src/main/java/com/zeapo/pwdstore/git/CloneOperation.java
Normal file
67
app/src/main/java/com/zeapo/pwdstore/git/CloneOperation.java
Normal file
|
@ -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);
|
||||||
|
}
|
||||||
|
}
|
|
@ -10,22 +10,17 @@ import android.os.Bundle;
|
||||||
import android.preference.PreferenceManager;
|
import android.preference.PreferenceManager;
|
||||||
import android.support.v7.app.ActionBarActivity;
|
import android.support.v7.app.ActionBarActivity;
|
||||||
import android.text.Editable;
|
import android.text.Editable;
|
||||||
import android.text.InputType;
|
|
||||||
import android.text.TextWatcher;
|
import android.text.TextWatcher;
|
||||||
|
import android.util.Log;
|
||||||
import android.view.Menu;
|
import android.view.Menu;
|
||||||
import android.view.MenuItem;
|
import android.view.MenuItem;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
import android.widget.AdapterView;
|
import android.widget.AdapterView;
|
||||||
import android.widget.ArrayAdapter;
|
import android.widget.ArrayAdapter;
|
||||||
import android.widget.EditText;
|
import android.widget.EditText;
|
||||||
import android.widget.LinearLayout;
|
|
||||||
import android.widget.Spinner;
|
import android.widget.Spinner;
|
||||||
import android.widget.TextView;
|
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.R;
|
||||||
import com.zeapo.pwdstore.UserPreference;
|
import com.zeapo.pwdstore.UserPreference;
|
||||||
import com.zeapo.pwdstore.utils.PasswordRepository;
|
import com.zeapo.pwdstore.utils.PasswordRepository;
|
||||||
|
@ -34,29 +29,17 @@ import org.eclipse.jgit.api.CloneCommand;
|
||||||
import org.eclipse.jgit.api.Git;
|
import org.eclipse.jgit.api.Git;
|
||||||
|
|
||||||
import org.apache.commons.io.FileUtils;
|
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.transport.UsernamePasswordCredentialsProvider;
|
||||||
import org.eclipse.jgit.util.FS;
|
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.lang.reflect.Method;
|
|
||||||
import java.util.regex.Matcher;
|
import java.util.regex.Matcher;
|
||||||
import java.util.regex.Pattern;
|
import java.util.regex.Pattern;
|
||||||
|
|
||||||
// TODO move the messages to strings.xml
|
// 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 Activity activity;
|
||||||
private Context context;
|
private Context context;
|
||||||
|
@ -77,8 +60,6 @@ public class GitHandler extends ActionBarActivity {
|
||||||
public static final int REQUEST_INIT = 104;
|
public static final int REQUEST_INIT = 104;
|
||||||
public static final int EDIT_SERVER = 105;
|
public static final int EDIT_SERVER = 105;
|
||||||
|
|
||||||
private static final int GET_SSH_KEY_FROM_CLONE = 201;
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void onCreate(Bundle savedInstanceState) {
|
protected void onCreate(Bundle savedInstanceState) {
|
||||||
super.onCreate(savedInstanceState);
|
super.onCreate(savedInstanceState);
|
||||||
|
@ -98,11 +79,11 @@ public class GitHandler extends ActionBarActivity {
|
||||||
case REQUEST_CLONE:
|
case REQUEST_CLONE:
|
||||||
case EDIT_SERVER:
|
case EDIT_SERVER:
|
||||||
setContentView(R.layout.activity_git_clone);
|
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 protcol_spinner = (Spinner) findViewById(R.id.clone_protocol);
|
||||||
final Spinner connection_mode_spinner = (Spinner) findViewById(R.id.connection_mode);
|
final Spinner connection_mode_spinner = (Spinner) findViewById(R.id.connection_mode);
|
||||||
|
|
||||||
|
|
||||||
// init the spinner for connection modes
|
// init the spinner for connection modes
|
||||||
final ArrayAdapter<CharSequence> connection_mode_adapter = ArrayAdapter.createFromResource(this,
|
final ArrayAdapter<CharSequence> connection_mode_adapter = ArrayAdapter.createFromResource(this,
|
||||||
R.array.connection_modes, android.R.layout.simple_spinner_item);
|
R.array.connection_modes, android.R.layout.simple_spinner_item);
|
||||||
|
@ -131,9 +112,9 @@ public class GitHandler extends ActionBarActivity {
|
||||||
new AdapterView.OnItemSelectedListener() {
|
new AdapterView.OnItemSelectedListener() {
|
||||||
@Override
|
@Override
|
||||||
public void onItemSelected(AdapterView<?> adapterView, View view, int i, long l) {
|
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://")) {
|
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);
|
((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.setSelection(0);
|
||||||
connection_mode_spinner.setEnabled(true);
|
connection_mode_spinner.setEnabled(true);
|
||||||
} else {
|
} 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);
|
((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
|
// init the server information
|
||||||
final EditText server_url = ((EditText) findViewById(R.id.server_url));
|
final EditText server_url = ((EditText) findViewById(R.id.server_url));
|
||||||
final EditText server_port = ((EditText) findViewById(R.id.server_port));
|
final EditText server_port = ((EditText) findViewById(R.id.server_port));
|
||||||
final EditText server_path = ((EditText) findViewById(R.id.server_path));
|
final EditText server_path = ((EditText) findViewById(R.id.server_path));
|
||||||
final EditText server_user = ((EditText) findViewById(R.id.server_user));
|
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() {
|
View.OnFocusChangeListener updateListener = new View.OnFocusChangeListener() {
|
||||||
@Override
|
@Override
|
||||||
|
@ -180,7 +172,8 @@ public class GitHandler extends ActionBarActivity {
|
||||||
|
|
||||||
server_url.addTextChangedListener(new TextWatcher() {
|
server_url.addTextChangedListener(new TextWatcher() {
|
||||||
@Override
|
@Override
|
||||||
public void beforeTextChanged(CharSequence charSequence, int i, int i2, int i3) { }
|
public void beforeTextChanged(CharSequence charSequence, int i, int i2, int i3) {
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onTextChanged(CharSequence charSequence, int i, int i2, int i3) {
|
public void onTextChanged(CharSequence charSequence, int i, int i2, int i3) {
|
||||||
|
@ -189,11 +182,13 @@ public class GitHandler extends ActionBarActivity {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void afterTextChanged(Editable editable) { }
|
public void afterTextChanged(Editable editable) {
|
||||||
|
}
|
||||||
});
|
});
|
||||||
server_port.addTextChangedListener(new TextWatcher() {
|
server_port.addTextChangedListener(new TextWatcher() {
|
||||||
@Override
|
@Override
|
||||||
public void beforeTextChanged(CharSequence charSequence, int i, int i2, int i3) { }
|
public void beforeTextChanged(CharSequence charSequence, int i, int i2, int i3) {
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onTextChanged(CharSequence charSequence, int i, int i2, int i3) {
|
public void onTextChanged(CharSequence charSequence, int i, int i2, int i3) {
|
||||||
|
@ -202,11 +197,13 @@ public class GitHandler extends ActionBarActivity {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void afterTextChanged(Editable editable) { }
|
public void afterTextChanged(Editable editable) {
|
||||||
|
}
|
||||||
});
|
});
|
||||||
server_user.addTextChangedListener(new TextWatcher() {
|
server_user.addTextChangedListener(new TextWatcher() {
|
||||||
@Override
|
@Override
|
||||||
public void beforeTextChanged(CharSequence charSequence, int i, int i2, int i3) { }
|
public void beforeTextChanged(CharSequence charSequence, int i, int i2, int i3) {
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onTextChanged(CharSequence charSequence, int i, int i2, int i3) {
|
public void onTextChanged(CharSequence charSequence, int i, int i2, int i3) {
|
||||||
|
@ -215,11 +212,13 @@ public class GitHandler extends ActionBarActivity {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void afterTextChanged(Editable editable) { }
|
public void afterTextChanged(Editable editable) {
|
||||||
|
}
|
||||||
});
|
});
|
||||||
server_path.addTextChangedListener(new TextWatcher() {
|
server_path.addTextChangedListener(new TextWatcher() {
|
||||||
@Override
|
@Override
|
||||||
public void beforeTextChanged(CharSequence charSequence, int i, int i2, int i3) { }
|
public void beforeTextChanged(CharSequence charSequence, int i, int i2, int i3) {
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onTextChanged(CharSequence charSequence, int i, int i2, int i3) {
|
public void onTextChanged(CharSequence charSequence, int i, int i2, int i3) {
|
||||||
|
@ -228,7 +227,8 @@ public class GitHandler extends ActionBarActivity {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void afterTextChanged(Editable editable) { }
|
public void afterTextChanged(Editable editable) {
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
server_uri.addTextChangedListener(new TextWatcher() {
|
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.clone_button).setVisibility(View.INVISIBLE);
|
||||||
findViewById(R.id.save_button).setVisibility(View.VISIBLE);
|
findViewById(R.id.save_button).setVisibility(View.VISIBLE);
|
||||||
} else {
|
} else {
|
||||||
|
@ -256,21 +255,24 @@ public class GitHandler extends ActionBarActivity {
|
||||||
findViewById(R.id.save_button).setVisibility(View.INVISIBLE);
|
findViewById(R.id.save_button).setVisibility(View.INVISIBLE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
updateURI();
|
||||||
|
|
||||||
break;
|
break;
|
||||||
case REQUEST_PULL:
|
case REQUEST_PULL:
|
||||||
authenticateAndRun("pullOperation");
|
pullFromRepository();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case REQUEST_PUSH:
|
case REQUEST_PUSH:
|
||||||
authenticateAndRun("pushOperation");
|
pushToRepository();
|
||||||
break;
|
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() {
|
private void updateURI() {
|
||||||
EditText uri = (EditText) findViewById(R.id.clone_uri);
|
EditText uri = (EditText) findViewById(R.id.clone_uri);
|
||||||
EditText server_url = ((EditText) findViewById(R.id.server_url));
|
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_path = ((EditText) findViewById(R.id.server_path));
|
||||||
EditText server_user = ((EditText) findViewById(R.id.server_user));
|
EditText server_user = ((EditText) findViewById(R.id.server_user));
|
||||||
|
|
||||||
if (uri != null) {
|
if (uri != null) {
|
||||||
switch (protocol)
|
switch (protocol) {
|
||||||
{
|
case "ssh://": {
|
||||||
case "ssh://":
|
|
||||||
{
|
|
||||||
String hostname =
|
String hostname =
|
||||||
server_user.getText()
|
server_user.getText()
|
||||||
+ "@" +
|
+ "@" +
|
||||||
|
@ -306,8 +306,7 @@ public class GitHandler extends ActionBarActivity {
|
||||||
if (!hostname.equals("@:")) uri.setText(hostname);
|
if (!hostname.equals("@:")) uri.setText(hostname);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case "https://":
|
case "https://": {
|
||||||
{
|
|
||||||
StringBuilder hostname = new StringBuilder();
|
StringBuilder hostname = new StringBuilder();
|
||||||
hostname.append(server_url.getText().toString().trim());
|
hostname.append(server_url.getText().toString().trim());
|
||||||
|
|
||||||
|
@ -325,13 +324,15 @@ public class GitHandler extends ActionBarActivity {
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
default:
|
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() {
|
private void splitURI() {
|
||||||
EditText server_uri = (EditText) findViewById(R.id.clone_uri);
|
EditText server_uri = (EditText) findViewById(R.id.clone_uri);
|
||||||
EditText server_url = ((EditText) findViewById(R.id.server_url));
|
EditText server_url = ((EditText) findViewById(R.id.server_url));
|
||||||
|
@ -397,76 +398,35 @@ public class GitHandler extends ActionBarActivity {
|
||||||
return super.onOptionsItemSelected(item);
|
return super.onOptionsItemSelected(item);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected class GitConfigSessionFactory extends JschConfigSessionFactory {
|
/**
|
||||||
|
* Saves the configuration found in the form
|
||||||
|
*/
|
||||||
|
private void saveConfiguration() {
|
||||||
|
// remember the settings
|
||||||
|
SharedPreferences.Editor editor = settings.edit();
|
||||||
|
|
||||||
protected void configure(OpenSshConfig.Host hc, Session session) {
|
editor.putString("git_remote_server", ((EditText) findViewById(R.id.server_url)).getText().toString());
|
||||||
session.setConfig("StrictHostKeyChecking", "no");
|
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);
|
||||||
@Override
|
editor.putString("git_remote_auth", connectionMode);
|
||||||
protected JSch
|
editor.putString("git_remote_port", port);
|
||||||
getJSch(final OpenSshConfig.Host hc, FS fs) throws JSchException {
|
editor.commit();
|
||||||
JSch jsch = super.getJSch(hc, fs);
|
|
||||||
jsch.removeAllIdentity();
|
|
||||||
return jsch;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protected class SshConfigSessionFactory extends GitConfigSessionFactory {
|
/**
|
||||||
private String sshKey;
|
* Save the repository information to the shared preferences settings
|
||||||
private String passphrase;
|
*
|
||||||
|
* @param view
|
||||||
public SshConfigSessionFactory(String sshKey, String passphrase) {
|
*/
|
||||||
this.sshKey = sshKey;
|
public void saveConfiguration(View view) {
|
||||||
this.passphrase = passphrase;
|
saveConfiguration();
|
||||||
}
|
PasswordRepository.addRemote("origin", ((EditText) findViewById(R.id.clone_uri)).getText().toString(), true);
|
||||||
|
|
||||||
@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);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Clones the repository, the directory exists, deletes it
|
* Clones the repository, the directory exists, deletes it
|
||||||
|
*
|
||||||
* @param view
|
* @param view
|
||||||
*/
|
*/
|
||||||
public void cloneRepository(View view) {
|
public void cloneRepository(View view) {
|
||||||
|
@ -505,8 +465,7 @@ public class GitHandler extends ActionBarActivity {
|
||||||
username = hostname.split("@")[0];
|
username = hostname.split("@")[0];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (localDir.exists() && localDir.listFiles().length != 0) {
|
||||||
if (localDir.exists()) {
|
|
||||||
new AlertDialog.Builder(this).
|
new AlertDialog.Builder(this).
|
||||||
setTitle(R.string.dialog_delete_title).
|
setTitle(R.string.dialog_delete_title).
|
||||||
setMessage(R.string.dialog_delete_msg).
|
setMessage(R.string.dialog_delete_msg).
|
||||||
|
@ -516,7 +475,15 @@ public class GitHandler extends ActionBarActivity {
|
||||||
public void onClick(DialogInterface dialog, int id) {
|
public void onClick(DialogInterface dialog, int id) {
|
||||||
try {
|
try {
|
||||||
FileUtils.deleteDirectory(localDir);
|
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) {
|
} catch (IOException e) {
|
||||||
//TODO Handle the exception correctly if we are unable to delete the directory...
|
//TODO Handle the exception correctly if we are unable to delete the directory...
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
|
@ -538,8 +505,12 @@ public class GitHandler extends ActionBarActivity {
|
||||||
).
|
).
|
||||||
show();
|
show();
|
||||||
} else {
|
} else {
|
||||||
|
saveConfiguration();
|
||||||
|
|
||||||
try {
|
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) {
|
} catch (Exception e) {
|
||||||
//This is what happens when jgit fails :(
|
//This is what happens when jgit fails :(
|
||||||
//TODO Handle the diffent cases of exceptions
|
//TODO Handle the diffent cases of exceptions
|
||||||
|
@ -548,53 +519,28 @@ public class GitHandler extends ActionBarActivity {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Pull the latest changes from the remote repository and merges them locally
|
||||||
|
*/
|
||||||
|
public void pullFromRepository() {
|
||||||
|
syncRepository(REQUEST_PULL);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Save the repository information to the shared preferences settings
|
* Pushes the latest changes from the local repository to the remote one
|
||||||
* @param view
|
|
||||||
*/
|
*/
|
||||||
public void saveConfiguration(View view) {
|
public void pushToRepository() {
|
||||||
// remember the settings
|
syncRepository(REQUEST_PUSH);
|
||||||
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 cloneOperation(UsernamePasswordCredentialsProvider provider) {
|
/**
|
||||||
|
* Syncs the local repository with the remote one (either pull or push)
|
||||||
// remember the settings
|
* @param operation the operation to execute can be REQUEST_PULL or REQUEST_PUSH
|
||||||
SharedPreferences.Editor editor = settings.edit();
|
*/
|
||||||
|
private void syncRepository(int operation) {
|
||||||
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);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void pullOperation(UsernamePasswordCredentialsProvider provider) {
|
|
||||||
|
|
||||||
if (settings.getString("git_remote_username", "").isEmpty() ||
|
if (settings.getString("git_remote_username", "").isEmpty() ||
|
||||||
settings.getString("git_remote_server", "").isEmpty() ||
|
settings.getString("git_remote_server", "").isEmpty() ||
|
||||||
settings.getString("git_remote_location", "").isEmpty() )
|
settings.getString("git_remote_location", "").isEmpty())
|
||||||
new AlertDialog.Builder(this)
|
new AlertDialog.Builder(this)
|
||||||
.setMessage(activity.getResources().getString(R.string.set_information_dialog_text))
|
.setMessage(activity.getResources().getString(R.string.set_information_dialog_text))
|
||||||
.setPositiveButton(activity.getResources().getString(R.string.dialog_positive), new DialogInterface.OnClickListener() {
|
.setPositiveButton(activity.getResources().getString(R.string.dialog_positive), new DialogInterface.OnClickListener() {
|
||||||
|
@ -616,185 +562,23 @@ public class GitHandler extends ActionBarActivity {
|
||||||
|
|
||||||
else {
|
else {
|
||||||
// check that the remote origin is here, else add it
|
// check that the remote origin is here, else add it
|
||||||
PasswordRepository.addRemote("origin", settings.getString("git_remote_username", "user")
|
PasswordRepository.addRemote("origin", hostname, false);
|
||||||
+ "@" +
|
GitOperation op;
|
||||||
settings.getString("git_remote_server", "server.com").trim()
|
|
||||||
+ ":" +
|
|
||||||
settings.getString("git_remote_location", "path/to/repository"), false);
|
|
||||||
|
|
||||||
GitCommand cmd;
|
if (operation == REQUEST_PULL) {
|
||||||
if (provider != null)
|
op = new PullOperation(localDir, activity).setCommand();
|
||||||
cmd = new Git(PasswordRepository.getRepository(new File("")))
|
} else if (operation == REQUEST_PUSH) {
|
||||||
.pull()
|
op = new PushOperation(localDir, activity).setCommand();
|
||||||
.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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
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();
|
|
||||||
} else {
|
} else {
|
||||||
final EditText passphrase = new EditText(activity);
|
Log.e(TAG, "Sync operation not recognized : " + operation);
|
||||||
passphrase.setHint("Passphrase");
|
return;
|
||||||
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();
|
|
||||||
}
|
}
|
||||||
} 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)
|
try {
|
||||||
.setTitle(activity.getResources().getString(R.string.passphrase_dialog_title))
|
op.executeAfterAuthentication(connectionMode, settings.getString("git_remote_username", "git"), new File(getFilesDir() + "/.ssh_key"));
|
||||||
.setMessage(activity.getResources().getString(R.string.password_dialog_text))
|
} catch (Exception e) {
|
||||||
.setView(password)
|
e.printStackTrace();
|
||||||
.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();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -807,16 +591,31 @@ public class GitHandler extends ActionBarActivity {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (resultCode == RESULT_OK) {
|
if (resultCode == RESULT_OK) {
|
||||||
|
GitOperation op;
|
||||||
|
|
||||||
switch (requestCode) {
|
switch (requestCode) {
|
||||||
case REQUEST_PULL:
|
case REQUEST_PULL:
|
||||||
authenticateAndRun("pullOperation");
|
op = new PullOperation(localDir, activity).setCommand();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case REQUEST_PUSH:
|
case REQUEST_PUSH:
|
||||||
authenticateAndRun("pushOperation");
|
op = new PushOperation(localDir, activity).setCommand();
|
||||||
break;
|
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();
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
170
app/src/main/java/com/zeapo/pwdstore/git/GitOperation.java
Normal file
170
app/src/main/java/com/zeapo/pwdstore/git/GitOperation.java
Normal file
|
@ -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();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
41
app/src/main/java/com/zeapo/pwdstore/git/PullOperation.java
Normal file
41
app/src/main/java/com/zeapo/pwdstore/git/PullOperation.java
Normal file
|
@ -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);
|
||||||
|
}
|
||||||
|
}
|
41
app/src/main/java/com/zeapo/pwdstore/git/PushOperation.java
Normal file
41
app/src/main/java/com/zeapo/pwdstore/git/PushOperation.java
Normal file
|
@ -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);
|
||||||
|
}
|
||||||
|
}
|
|
@ -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;
|
||||||
|
}
|
||||||
|
}
|
|
@ -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);
|
||||||
|
}
|
||||||
|
}
|
|
@ -6,7 +6,7 @@
|
||||||
android:paddingRight="@dimen/activity_horizontal_margin"
|
android:paddingRight="@dimen/activity_horizontal_margin"
|
||||||
android:paddingTop="@dimen/activity_vertical_margin"
|
android:paddingTop="@dimen/activity_vertical_margin"
|
||||||
android:paddingBottom="@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">
|
android:background="@android:color/white">
|
||||||
<LinearLayout
|
<LinearLayout
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
<menu xmlns:android="http://schemas.android.com/apk/res/android"
|
<menu xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
xmlns:tools="http://schemas.android.com/tools"
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
xmlns:pwstore="http://schemas.android.com/apk/res-auto"
|
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"
|
<item android:id="@+id/user_pref"
|
||||||
android:title="@string/action_settings"
|
android:title="@string/action_settings"
|
||||||
android:orderInCategory="100"
|
android:orderInCategory="100"
|
||||||
|
|
|
@ -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_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_delete">Delete directory</string>
|
||||||
<string name="dialog_do_not_delete">Cancel</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 -->
|
<!-- 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>
|
<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 -->
|
<!-- Git Async Task -->
|
||||||
<string name="running_dialog_text">Running command...</string>
|
<string name="running_dialog_text">Running command...</string>
|
||||||
<string name="jgit_error_dialog_title">Internal exception occurred</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 -->
|
<!-- 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>
|
<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_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_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="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_title">Error while trying to import the ssh-key</string>
|
||||||
<string name="ssh_key_error_dialog_text">Message : \n</string>
|
<string name="ssh_key_error_dialog_text">Message : \n</string>
|
||||||
<string name="pref_recursive_filter">Recursive filtering</string>
|
<string name="pref_recursive_filter">Recursive filtering</string>
|
||||||
|
|
Loading…
Reference in a new issue