add autoSync on startup

This commit is contained in:
zeapo
2017-06-05 14:30:19 +02:00
parent 3a5a322bfa
commit bbd7f66191
11 changed files with 78 additions and 33 deletions

View File

@@ -23,16 +23,19 @@ import android.support.v7.app.AlertDialog;
import android.support.v7.app.AppCompatActivity; import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.SearchView; import android.support.v7.widget.SearchView;
import android.text.TextUtils; import android.text.TextUtils;
import android.text.format.DateUtils;
import android.util.Log; 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.TextView; import android.widget.TextView;
import android.widget.Toast;
import com.zeapo.pwdstore.crypto.PgpHandler; import com.zeapo.pwdstore.crypto.PgpHandler;
import com.zeapo.pwdstore.git.GitActivity; import com.zeapo.pwdstore.git.GitActivity;
import com.zeapo.pwdstore.git.GitAsyncTask; import com.zeapo.pwdstore.git.GitAsyncTask;
import com.zeapo.pwdstore.git.GitOperation; import com.zeapo.pwdstore.git.GitOperation;
import com.zeapo.pwdstore.git.SyncOperation;
import com.zeapo.pwdstore.pwgen.PRNGFixes; import com.zeapo.pwdstore.pwgen.PRNGFixes;
import com.zeapo.pwdstore.utils.PasswordItem; import com.zeapo.pwdstore.utils.PasswordItem;
import com.zeapo.pwdstore.utils.PasswordRecyclerAdapter; import com.zeapo.pwdstore.utils.PasswordRecyclerAdapter;
@@ -43,8 +46,13 @@ import org.eclipse.jgit.api.Git;
import org.eclipse.jgit.lib.Repository; import org.eclipse.jgit.lib.Repository;
import java.io.File; import java.io.File;
import java.sql.Timestamp;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Calendar;
import java.util.Collections; import java.util.Collections;
import java.util.Date;
import java.util.HashSet; import java.util.HashSet;
import java.util.Iterator; import java.util.Iterator;
import java.util.List; import java.util.List;
@@ -339,6 +347,23 @@ public class PasswordStore extends AppCompatActivity {
startActivityForResult(intent, HOME); startActivityForResult(intent, HOME);
} else { } else {
checkLocalRepository(PasswordRepository.getRepositoryDirectory(getApplicationContext())); checkLocalRepository(PasswordRepository.getRepositoryDirectory(getApplicationContext()));
File localDir = PasswordRepository.getRepositoryDirectory(getApplicationContext());
checkLocalRepository(localDir);
int lastSync = settings.getInt("last_sync", -1);
int currentTime = (int) Calendar.getInstance().getTimeInMillis() / 1000;
if (settings.getBoolean("git_auto_sync", false) && currentTime > lastSync + 10) {
Toast.makeText(getApplicationContext(), "Running git auto sync", Toast.LENGTH_LONG).show();
SyncOperation op = new SyncOperation(localDir.getAbsoluteFile(), activity).setCommands();
try {
String connectionMode = settings.getString("git_remote_auth", "ssh-key");
op.executeAfterAuthentication(connectionMode, settings.getString("git_remote_username", "git"), new File(getFilesDir() + "/.ssh_key"), false);
} catch (Exception e) {
e.printStackTrace();
}
settings.edit().putInt("last_sync", currentTime).apply();
}
} }
} }
@@ -545,7 +570,7 @@ public class PasswordStore extends AppCompatActivity {
private void commitChange(final String message) { private void commitChange(final String message) {
new GitOperation(PasswordRepository.getRepositoryDirectory(activity), activity) { new GitOperation(PasswordRepository.getRepositoryDirectory(activity), activity) {
@Override @Override
public void execute() { public void execute(boolean finishOnEnd) {
Log.d(TAG, "Commiting with message " + message); Log.d(TAG, "Commiting with message " + message);
Git git = new Git(this.repository); Git git = new Git(this.repository);
GitAsyncTask tasks = new GitAsyncTask(activity, false, true, this); GitAsyncTask tasks = new GitAsyncTask(activity, false, true, this);
@@ -554,7 +579,7 @@ public class PasswordStore extends AppCompatActivity {
git.commit().setMessage(message) git.commit().setMessage(message)
); );
} }
}.execute(); }.execute(true);
} }
protected void onActivityResult(int requestCode, int resultCode, protected void onActivityResult(int requestCode, int resultCode,

View File

@@ -66,7 +66,7 @@ public class CloneOperation extends GitOperation {
} }
@Override @Override
public void execute() { public void execute(boolean finishOnEnd) {
if (this.provider != null) { if (this.provider != null) {
((CloneCommand) this.command).setCredentialsProvider(this.provider); ((CloneCommand) this.command).setCredentialsProvider(this.provider);
} }

View File

@@ -536,7 +536,7 @@ public class GitActivity extends AppCompatActivity {
try { try {
new CloneOperation(localDir, activity) new CloneOperation(localDir, activity)
.setCommand(hostname) .setCommand(hostname)
.executeAfterAuthentication(connectionMode, settings.getString("git_remote_username", "git"), new File(getFilesDir() + "/.ssh_key")); .executeAfterAuthentication(connectionMode, settings.getString("git_remote_username", "git"), new File(getFilesDir() + "/.ssh_key"), true);
} 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
@@ -574,7 +574,7 @@ public class GitActivity extends AppCompatActivity {
} }
new CloneOperation(localDir, activity) new CloneOperation(localDir, activity)
.setCommand(hostname) .setCommand(hostname)
.executeAfterAuthentication(connectionMode, settings.getString("git_remote_username", "git"), new File(getFilesDir() + "/.ssh_key")); .executeAfterAuthentication(connectionMode, settings.getString("git_remote_username", "git"), new File(getFilesDir() + "/.ssh_key"), true);
} 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
@@ -632,7 +632,7 @@ public class GitActivity extends AppCompatActivity {
} }
try { try {
op.executeAfterAuthentication(connectionMode, settings.getString("git_remote_username", "git"), new File(getFilesDir() + "/.ssh_key")); op.executeAfterAuthentication(connectionMode, settings.getString("git_remote_username", "git"), new File(getFilesDir() + "/.ssh_key"), true);
} catch (Exception e) { } catch (Exception e) {
e.printStackTrace(); e.printStackTrace();
} }
@@ -674,7 +674,7 @@ public class GitActivity extends AppCompatActivity {
} }
try { try {
op.executeAfterAuthentication(connectionMode, settings.getString("git_remote_username", "git"), new File(getFilesDir() + "/.ssh_key")); op.executeAfterAuthentication(connectionMode, settings.getString("git_remote_username", "git"), new File(getFilesDir() + "/.ssh_key"), true);
} catch (Exception e) { } catch (Exception e) {
e.printStackTrace(); e.printStackTrace();
} }

View File

@@ -3,7 +3,10 @@ package com.zeapo.pwdstore.git;
import android.app.Activity; import android.app.Activity;
import android.app.ProgressDialog; import android.app.ProgressDialog;
import android.os.AsyncTask; import android.os.AsyncTask;
import android.support.design.widget.Snackbar;
import android.text.Html;
import android.util.Log; import android.util.Log;
import android.widget.Toast;
import com.zeapo.pwdstore.PasswordStore; import com.zeapo.pwdstore.PasswordStore;
import com.zeapo.pwdstore.R; import com.zeapo.pwdstore.R;
@@ -13,26 +16,35 @@ import org.eclipse.jgit.api.GitCommand;
import org.eclipse.jgit.api.StatusCommand; import org.eclipse.jgit.api.StatusCommand;
public class GitAsyncTask extends AsyncTask<GitCommand, Integer, String> { public class GitAsyncTask extends AsyncTask<GitCommand, String, String> {
private Activity activity; private Activity activity;
private boolean finishOnEnd; private boolean finishOnEnd;
private boolean refreshListOnEnd; private boolean refreshListOnEnd;
private ProgressDialog dialog; private ProgressDialog dialog;
private GitOperation operation; private GitOperation operation;
private Snackbar snack;
public GitAsyncTask(Activity activity, boolean finishOnEnd, boolean refreshListOnEnd, GitOperation operation) { public GitAsyncTask(Activity activity, boolean finishOnEnd, boolean refreshListOnEnd, GitOperation operation) {
this.activity = activity; this.activity = activity;
this.finishOnEnd = finishOnEnd; this.finishOnEnd = finishOnEnd;
this.refreshListOnEnd = refreshListOnEnd; this.refreshListOnEnd = refreshListOnEnd;
this.operation = operation; this.operation = operation;
dialog = new ProgressDialog(this.activity);
} }
protected void onPreExecute() { protected void onPreExecute() {
this.dialog.setMessage(activity.getResources().getString(R.string.running_dialog_text)); // Toast.makeText(activity.getApplicationContext(), String.format("Running %s", operation.toString()), Toast.LENGTH_LONG).show();
this.dialog.setCancelable(false); snack = Snackbar.make(activity.findViewById(R.id.main_layout),
this.dialog.show(); Html.fromHtml(String.format("<font color=\"#ffffff\">Running the Git operation %s</font>", operation.toString())),
Snackbar.LENGTH_INDEFINITE);
snack.show();
}
protected void onProgressUpdate(String... progress) {
if (this.snack != null) snack.dismiss();
snack = Snackbar.make(activity.findViewById(R.id.main_layout),
Html.fromHtml(String.format("<font color=\"#ffffff\">Running: <strong>%s</strong></font>", progress[0])),
Snackbar.LENGTH_INDEFINITE);
snack.show();
} }
@Override @Override
@@ -51,7 +63,7 @@ public class GitAsyncTask extends AsyncTask<GitCommand, Integer, String> {
} else { } else {
command.call(); command.call();
} }
publishProgress(command.getClass().getName());
} catch (Exception e) { } catch (Exception e) {
e.printStackTrace(); e.printStackTrace();
return e.getMessage() + "\nCaused by:\n" + e.getCause(); return e.getMessage() + "\nCaused by:\n" + e.getCause();
@@ -61,9 +73,9 @@ public class GitAsyncTask extends AsyncTask<GitCommand, Integer, String> {
} }
protected void onPostExecute(String result) { protected void onPostExecute(String result) {
if (this.dialog != null) if (this.snack != null)
try { try {
this.dialog.dismiss(); this.snack.dismiss();
} catch (Exception e) { } catch (Exception e) {
// ignore // ignore
} }

View File

@@ -76,29 +76,30 @@ public abstract class GitOperation {
/** /**
* Executes the GitCommand in an async task * Executes the GitCommand in an async task
* @param finishOnEnd
*/ */
public abstract void execute(); public abstract void execute(boolean finishOnEnd);
/** /**
* Executes the GitCommand in an async task after creating the authentication * Executes the GitCommand in an async task after creating the authentication
*
* @param connectionMode the server-connection mode * @param connectionMode the server-connection mode
* @param username the username * @param username the username
* @param sshKey the ssh-key file * @param sshKey the ssh-key file
* @param finishOnEnd
*/ */
public void executeAfterAuthentication(final String connectionMode, final String username, @Nullable final File sshKey) { public void executeAfterAuthentication(final String connectionMode, final String username, @Nullable final File sshKey, boolean finishOnEnd) {
executeAfterAuthentication(connectionMode, username, sshKey, false); executeAfterAuthentication(connectionMode, username, sshKey, false, finishOnEnd);
} }
/** /**
* Executes the GitCommand in an async task after creating the authentication * Executes the GitCommand in an async task after creating the authentication
*
* @param connectionMode the server-connection mode * @param connectionMode the server-connection mode
* @param username the username * @param username the username
* @param sshKey the ssh-key file * @param sshKey the ssh-key file
* @param showError show the passphrase edit text in red * @param showError show the passphrase edit text in red
* @param finishOnEnd
*/ */
private void executeAfterAuthentication(final String connectionMode, final String username, @Nullable final File sshKey, final boolean showError) { private void executeAfterAuthentication(final String connectionMode, final String username, @Nullable final File sshKey, final boolean showError, final boolean finishOnEnd) {
if (connectionMode.equalsIgnoreCase("ssh-key")) { if (connectionMode.equalsIgnoreCase("ssh-key")) {
if (sshKey == null || !sshKey.exists()) { if (sshKey == null || !sshKey.exists()) {
new AlertDialog.Builder(callingActivity) new AlertDialog.Builder(callingActivity)
@@ -161,10 +162,10 @@ public abstract class GitOperation {
public void onClick(DialogInterface dialog, int whichButton) { public void onClick(DialogInterface dialog, int whichButton) {
if (keyPair.decrypt(passphrase.getText().toString())) { if (keyPair.decrypt(passphrase.getText().toString())) {
// Authenticate using the ssh-key and then execute the command // Authenticate using the ssh-key and then execute the command
setAuthentication(sshKey, username, passphrase.getText().toString()).execute(); setAuthentication(sshKey, username, passphrase.getText().toString()).execute(finishOnEnd);
} else { } else {
// call back the method // call back the method
executeAfterAuthentication(connectionMode, username, sshKey, true); executeAfterAuthentication(connectionMode, username, sshKey, true, finishOnEnd);
} }
} }
}).setNegativeButton(callingActivity.getResources().getString(R.string.dialog_cancel), new DialogInterface.OnClickListener() { }).setNegativeButton(callingActivity.getResources().getString(R.string.dialog_cancel), new DialogInterface.OnClickListener() {
@@ -173,7 +174,7 @@ public abstract class GitOperation {
} }
}).show(); }).show();
} else { } else {
setAuthentication(sshKey, username, "").execute(); setAuthentication(sshKey, username, "").execute(finishOnEnd);
} }
} catch (JSchException e) { } catch (JSchException e) {
new AlertDialog.Builder(callingActivity) new AlertDialog.Builder(callingActivity)
@@ -200,7 +201,7 @@ public abstract class GitOperation {
.setPositiveButton(callingActivity.getResources().getString(R.string.dialog_ok), new DialogInterface.OnClickListener() { .setPositiveButton(callingActivity.getResources().getString(R.string.dialog_ok), new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int whichButton) { public void onClick(DialogInterface dialog, int whichButton) {
// authenticate using the user/pwd and then execute the command // authenticate using the user/pwd and then execute the command
setAuthentication(username, password.getText().toString()).execute(); setAuthentication(username, password.getText().toString()).execute(finishOnEnd);
} }
}).setNegativeButton(callingActivity.getResources().getString(R.string.dialog_cancel), new DialogInterface.OnClickListener() { }).setNegativeButton(callingActivity.getResources().getString(R.string.dialog_cancel), new DialogInterface.OnClickListener() {

View File

@@ -36,7 +36,7 @@ public class PullOperation extends GitOperation {
} }
@Override @Override
public void execute() { public void execute(boolean finishOnEnd) {
if (this.provider != null) { if (this.provider != null) {
((PullCommand) this.command).setCredentialsProvider(this.provider); ((PullCommand) this.command).setCredentialsProvider(this.provider);
} }

View File

@@ -36,7 +36,7 @@ public class PushOperation extends GitOperation {
} }
@Override @Override
public void execute() { public void execute(boolean finishOnEnd) {
if (this.provider != null) { if (this.provider != null) {
((PushCommand) this.command).setCredentialsProvider(this.provider); ((PushCommand) this.command).setCredentialsProvider(this.provider);
} }

View File

@@ -48,12 +48,12 @@ public class SyncOperation extends GitOperation {
} }
@Override @Override
public void execute() { public void execute(boolean finishOnEnd) {
if (this.provider != null) { if (this.provider != null) {
this.pullCommand.setCredentialsProvider(this.provider); this.pullCommand.setCredentialsProvider(this.provider);
this.pushCommand.setCredentialsProvider(this.provider); this.pushCommand.setCredentialsProvider(this.provider);
} }
new GitAsyncTask(callingActivity, true, false, this).execute(this.addCommand, this.statusCommand, this.commitCommand, this.pullCommand, this.pushCommand); new GitAsyncTask(callingActivity, finishOnEnd, false, this).execute(this.addCommand, this.statusCommand, this.commitCommand, this.pullCommand, this.pushCommand);
} }
@Override @Override

View File

@@ -3,7 +3,8 @@
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent"
tools:context=".pwdstore" tools:context=".pwdstore"
android:orientation="vertical"> android:orientation="vertical"
android:id="@+id/main_activity">
<LinearLayout <LinearLayout
android:id="@+id/main_layout" android:id="@+id/main_layout"

View File

@@ -197,4 +197,6 @@
<string name="no_repo_selected2">No external repository selected</string> <string name="no_repo_selected2">No external repository selected</string>
<string name="send_plaintext_password_to">Send password as plaintext using…</string> <string name="send_plaintext_password_to">Send password as plaintext using…</string>
<string name="show_password">Show password</string> <string name="show_password">Show password</string>
<string name="git_auto_sync_title">Auto Sync on start</string>
<string name="git_auto_sync_summary">Synchronize the repository when starting the application or when resuming.</string>
</resources> </resources>

View File

@@ -16,6 +16,10 @@
<Preference <Preference
android:key="ssh_see_key" android:key="ssh_see_key"
android:title="@string/pref_ssh_see_key_title" /> android:title="@string/pref_ssh_see_key_title" />
<CheckBoxPreference
android:key="git_auto_sync"
android:summary="@string/git_auto_sync_summary"
android:title="@string/git_auto_sync_title" />
<Preference <Preference
android:key="git_delete_repo" android:key="git_delete_repo"
android:summary="@string/pref_git_delete_repo_summary" android:summary="@string/pref_git_delete_repo_summary"