Merge pull request #149 from zeapo/fix/external
Add warnings to the user about storing the passwords on the sdcard
This commit is contained in:
commit
5b3cc540e4
6 changed files with 129 additions and 58 deletions
|
@ -58,20 +58,18 @@ android {
|
||||||
}
|
}
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
compile 'com.android.support:appcompat-v7:23.0.1'
|
compile 'com.android.support:appcompat-v7:23.1.1'
|
||||||
compile 'com.android.support:recyclerview-v7:23.0.1'
|
compile 'com.android.support:recyclerview-v7:23.1.1'
|
||||||
compile 'com.android.support:cardview-v7:23.0.1'
|
compile 'com.android.support:cardview-v7:23.1.1'
|
||||||
compile 'com.android.support:design:23.0.1'
|
compile 'com.android.support:design:23.1.1'
|
||||||
compile 'org.sufficientlysecure:openpgp-api:9.0'
|
compile 'org.sufficientlysecure:openpgp-api:9.0'
|
||||||
|
compile 'com.nononsenseapps:filepicker:2.4.2'
|
||||||
compile ('org.eclipse.jgit:org.eclipse.jgit:3.7.1.201504261725-r') {
|
compile ('org.eclipse.jgit:org.eclipse.jgit:3.7.1.201504261725-r') {
|
||||||
exclude group: 'org.apache.httpcomponents', module: 'httpclient'
|
exclude group: 'org.apache.httpcomponents', module: 'httpclient'
|
||||||
}
|
}
|
||||||
compile 'com.jcraft:jsch:0.1.53'
|
compile 'com.jcraft:jsch:0.1.53'
|
||||||
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.3.1'
|
compile 'com.jayway.android.robotium:robotium-solo:5.3.1'
|
||||||
compile ('net.rdrei.android.dirchooser:library:3.0@aar') {
|
|
||||||
transitive = true;
|
|
||||||
}
|
|
||||||
compile group: 'com.google.guava', name: 'guava', version: '18.0'
|
compile group: 'com.google.guava', name: 'guava', version: '18.0'
|
||||||
}
|
}
|
||||||
tasks.findAll { // make all tasks whose name starts with 'assemble'...
|
tasks.findAll { // make all tasks whose name starts with 'assemble'...
|
||||||
|
|
|
@ -72,7 +72,15 @@
|
||||||
android:value="com.zeapo.pwdstore.PasswordStore" />
|
android:value="com.zeapo.pwdstore.PasswordStore" />
|
||||||
</activity>
|
</activity>
|
||||||
|
|
||||||
<activity android:name="net.rdrei.android.dirchooser.DirectoryChooserActivity" />
|
<activity
|
||||||
|
android:name="com.nononsenseapps.filepicker.FilePickerActivity"
|
||||||
|
android:label="@string/app_name"
|
||||||
|
android:theme="@style/FilePickerTheme">
|
||||||
|
<intent-filter>
|
||||||
|
<action android:name="android.intent.action.GET_CONTENT" />
|
||||||
|
<category android:name="android.intent.category.DEFAULT" />
|
||||||
|
</intent-filter>
|
||||||
|
</activity>
|
||||||
</application>
|
</application>
|
||||||
|
|
||||||
</manifest>
|
</manifest>
|
||||||
|
|
|
@ -497,31 +497,7 @@ public class PasswordStore extends AppCompatActivity {
|
||||||
new AlertDialog.Builder(this)
|
new AlertDialog.Builder(this)
|
||||||
.setTitle("Repository location")
|
.setTitle("Repository location")
|
||||||
.setMessage("Select where to create or clone your password repository.")
|
.setMessage("Select where to create or clone your password repository.")
|
||||||
.setPositiveButton("External", new DialogInterface.OnClickListener() {
|
.setPositiveButton("Hidden (preferred)", new DialogInterface.OnClickListener() {
|
||||||
public void onClick(DialogInterface dialog, int whichButton) {
|
|
||||||
settings.edit().putBoolean("git_external", true).apply();
|
|
||||||
|
|
||||||
if (settings.getString("git_external_repo", null) == null) {
|
|
||||||
Intent intent = new Intent(activity, UserPreference.class);
|
|
||||||
intent.putExtra("operation", "git_external");
|
|
||||||
startActivityForResult(intent, operation);
|
|
||||||
} else {
|
|
||||||
switch (operation) {
|
|
||||||
case NEW_REPO_BUTTON:
|
|
||||||
initializeRepositoryInfo();
|
|
||||||
break;
|
|
||||||
case CLONE_REPO_BUTTON:
|
|
||||||
PasswordRepository.initialize(PasswordStore.this);
|
|
||||||
|
|
||||||
Intent intent = new Intent(activity, GitActivity.class);
|
|
||||||
intent.putExtra("Operation", GitActivity.REQUEST_CLONE);
|
|
||||||
startActivityForResult(intent, GitActivity.REQUEST_CLONE);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.setNegativeButton("Internal", new DialogInterface.OnClickListener() {
|
|
||||||
public void onClick(DialogInterface dialog, int whichButton) {
|
public void onClick(DialogInterface dialog, int whichButton) {
|
||||||
settings.edit().putBoolean("git_external", false).apply();
|
settings.edit().putBoolean("git_external", false).apply();
|
||||||
|
|
||||||
|
@ -539,6 +515,46 @@ public class PasswordStore extends AppCompatActivity {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
.setNegativeButton("SD-Card", new DialogInterface.OnClickListener() {
|
||||||
|
public void onClick(DialogInterface dialog, int whichButton) {
|
||||||
|
settings.edit().putBoolean("git_external", true).apply();
|
||||||
|
|
||||||
|
if (settings.getString("git_external_repo", null) == null) {
|
||||||
|
Intent intent = new Intent(activity, UserPreference.class);
|
||||||
|
intent.putExtra("operation", "git_external");
|
||||||
|
startActivityForResult(intent, operation);
|
||||||
|
} else {
|
||||||
|
new AlertDialog.Builder(activity).
|
||||||
|
setTitle("Directory already selected").
|
||||||
|
setMessage("Do you want to use \"" + settings.getString("git_external_repo", null) + "\"?").
|
||||||
|
setPositiveButton("Use", new DialogInterface.OnClickListener() {
|
||||||
|
@Override
|
||||||
|
public void onClick(DialogInterface dialog, int which) {
|
||||||
|
switch (operation) {
|
||||||
|
case NEW_REPO_BUTTON:
|
||||||
|
initializeRepositoryInfo();
|
||||||
|
break;
|
||||||
|
case CLONE_REPO_BUTTON:
|
||||||
|
PasswordRepository.initialize(PasswordStore.this);
|
||||||
|
|
||||||
|
Intent intent = new Intent(activity, GitActivity.class);
|
||||||
|
intent.putExtra("Operation", GitActivity.REQUEST_CLONE);
|
||||||
|
startActivityForResult(intent, GitActivity.REQUEST_CLONE);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}).
|
||||||
|
setNegativeButton("Change", new DialogInterface.OnClickListener() {
|
||||||
|
@Override
|
||||||
|
public void onClick(DialogInterface dialog, int which) {
|
||||||
|
Intent intent = new Intent(activity, UserPreference.class);
|
||||||
|
intent.putExtra("operation", "git_external");
|
||||||
|
startActivityForResult(intent, operation);
|
||||||
|
}
|
||||||
|
}).show();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
.show();
|
.show();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
package com.zeapo.pwdstore;
|
package com.zeapo.pwdstore;
|
||||||
|
|
||||||
import android.accessibilityservice.AccessibilityServiceInfo;
|
import android.accessibilityservice.AccessibilityServiceInfo;
|
||||||
|
import android.app.Activity;
|
||||||
import android.app.DialogFragment;
|
import android.app.DialogFragment;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.content.DialogInterface;
|
import android.content.DialogInterface;
|
||||||
|
@ -23,14 +24,12 @@ import android.widget.Toast;
|
||||||
import com.google.common.base.Function;
|
import com.google.common.base.Function;
|
||||||
import com.google.common.base.Joiner;
|
import com.google.common.base.Joiner;
|
||||||
import com.google.common.collect.Iterables;
|
import com.google.common.collect.Iterables;
|
||||||
|
import com.nononsenseapps.filepicker.FilePickerActivity;
|
||||||
import com.zeapo.pwdstore.autofill.AutofillPreferenceActivity;
|
import com.zeapo.pwdstore.autofill.AutofillPreferenceActivity;
|
||||||
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.utils.PasswordRepository;
|
import com.zeapo.pwdstore.utils.PasswordRepository;
|
||||||
|
|
||||||
import net.rdrei.android.dirchooser.DirectoryChooserActivity;
|
|
||||||
import net.rdrei.android.dirchooser.DirectoryChooserConfig;
|
|
||||||
|
|
||||||
import org.apache.commons.io.FileUtils;
|
import org.apache.commons.io.FileUtils;
|
||||||
import org.apache.commons.io.IOUtils;
|
import org.apache.commons.io.IOUtils;
|
||||||
import org.openintents.openpgp.util.OpenPgpKeyPreference;
|
import org.openintents.openpgp.util.OpenPgpKeyPreference;
|
||||||
|
@ -126,7 +125,7 @@ public class UserPreference extends AppCompatActivity {
|
||||||
new AlertDialog.Builder(callingActivity).
|
new AlertDialog.Builder(callingActivity).
|
||||||
setTitle(R.string.pref_dialog_delete_title).
|
setTitle(R.string.pref_dialog_delete_title).
|
||||||
setMessage(getResources().getString(R.string.dialog_delete_msg)
|
setMessage(getResources().getString(R.string.dialog_delete_msg)
|
||||||
+ " " + PasswordRepository.getWorkTree().toString()).
|
+ " \n" + PasswordRepository.getWorkTree().toString()).
|
||||||
setCancelable(false).
|
setCancelable(false).
|
||||||
setPositiveButton(R.string.dialog_delete, new DialogInterface.OnClickListener() {
|
setPositiveButton(R.string.dialog_delete, new DialogInterface.OnClickListener() {
|
||||||
@Override
|
@Override
|
||||||
|
@ -266,19 +265,32 @@ public class UserPreference extends AppCompatActivity {
|
||||||
}
|
}
|
||||||
|
|
||||||
public void selectExternalGitRepository() {
|
public void selectExternalGitRepository() {
|
||||||
Intent intent = new Intent(this, DirectoryChooserActivity.class);
|
final Activity activity = this;
|
||||||
File dir = new File(Environment.getExternalStorageDirectory() + "/PasswordStore");
|
new AlertDialog.Builder(this).
|
||||||
if (!dir.exists()) {
|
setTitle("Choose where to store the passwords").
|
||||||
dir.mkdir();
|
setMessage("You must select a directory where to store your passwords. If you want " +
|
||||||
}
|
"to store your passwords within the hidden storage of the application, " +
|
||||||
DirectoryChooserConfig config = DirectoryChooserConfig.builder()
|
"cancel this dialog and disable the \"External Repository\" option.").
|
||||||
.newDirectoryName("PasswordStore")
|
setPositiveButton(R.string.dialog_ok, new DialogInterface.OnClickListener() {
|
||||||
.allowNewDirectoryNameModification(true)
|
@Override
|
||||||
.initialDirectory(Environment.getExternalStorageDirectory() + "/PasswordStore")
|
public void onClick(DialogInterface dialog, int which) {
|
||||||
.build();
|
// This always works
|
||||||
intent.putExtra(DirectoryChooserActivity.EXTRA_CONFIG, config);
|
Intent i = new Intent(activity.getApplicationContext(), FilePickerActivity.class);
|
||||||
|
// This works if you defined the intent filter
|
||||||
|
// Intent i = new Intent(Intent.ACTION_GET_CONTENT);
|
||||||
|
|
||||||
|
// Set these depending on your use case. These are the defaults.
|
||||||
|
i.putExtra(FilePickerActivity.EXTRA_ALLOW_MULTIPLE, false);
|
||||||
|
i.putExtra(FilePickerActivity.EXTRA_ALLOW_CREATE_DIR, true);
|
||||||
|
i.putExtra(FilePickerActivity.EXTRA_MODE, FilePickerActivity.MODE_DIR);
|
||||||
|
|
||||||
|
i.putExtra(FilePickerActivity.EXTRA_START_PATH, Environment.getExternalStorageDirectory().getPath());
|
||||||
|
|
||||||
|
startActivityForResult(i, SELECT_GIT_DIRECTORY);
|
||||||
|
}
|
||||||
|
}).
|
||||||
|
setNegativeButton(R.string.dialog_cancel, null).show();
|
||||||
|
|
||||||
startActivityForResult(intent, SELECT_GIT_DIRECTORY);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -381,17 +393,37 @@ public class UserPreference extends AppCompatActivity {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
case SELECT_GIT_DIRECTORY: {
|
||||||
|
final Uri uri = data.getData();
|
||||||
|
|
||||||
|
if (uri.getPath().equals(Environment.getExternalStorageDirectory().getPath())) {
|
||||||
|
// the user wants to use the root of the sdcard as a store...
|
||||||
|
new AlertDialog.Builder(this).
|
||||||
|
setTitle("SD-Card root selected").
|
||||||
|
setMessage("You have selected the root of your sdcard for the store. " +
|
||||||
|
"This is extremly dangerous and you will lose your data " +
|
||||||
|
"as its content will be deleted").
|
||||||
|
setPositiveButton("Remove everything", new DialogInterface.OnClickListener() {
|
||||||
|
@Override
|
||||||
|
public void onClick(DialogInterface dialog, int which) {
|
||||||
|
PreferenceManager.getDefaultSharedPreferences(getApplicationContext())
|
||||||
|
.edit()
|
||||||
|
.putString("git_external_repo", uri.getPath())
|
||||||
|
.apply();
|
||||||
|
}
|
||||||
|
}).
|
||||||
|
setNegativeButton(R.string.dialog_cancel, null).show();
|
||||||
|
} else {
|
||||||
|
PreferenceManager.getDefaultSharedPreferences(getApplicationContext())
|
||||||
|
.edit()
|
||||||
|
.putString("git_external_repo", uri.getPath())
|
||||||
|
.apply();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// why do they have to use a different resultCode than OK :/
|
|
||||||
if (requestCode == SELECT_GIT_DIRECTORY && resultCode == DirectoryChooserActivity.RESULT_CODE_DIR_SELECTED) {
|
|
||||||
PreferenceManager.getDefaultSharedPreferences(getApplicationContext())
|
|
||||||
.edit()
|
|
||||||
.putString("git_external_repo", data.getStringExtra(DirectoryChooserActivity.RESULT_SELECTED_DIR))
|
|
||||||
.apply();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,7 +9,7 @@
|
||||||
<string name="action_settings">Settings</string>
|
<string name="action_settings">Settings</string>
|
||||||
<string name="hello_world">Hello world!</string>
|
<string name="hello_world">Hello world!</string>
|
||||||
<string name="dialog_delete_title">Directory already exist</string>
|
<string name="dialog_delete_title">Directory already exist</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_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">Repository information</string>
|
<string name="title_activity_git_clone">Repository information</string>
|
||||||
|
|
|
@ -13,4 +13,21 @@
|
||||||
<style name="ActionMode" parent="@style/Widget.AppCompat.ActionMode">
|
<style name="ActionMode" parent="@style/Widget.AppCompat.ActionMode">
|
||||||
<item name="background">@color/blue_grey_700</item>
|
<item name="background">@color/blue_grey_700</item>
|
||||||
</style>
|
</style>
|
||||||
|
|
||||||
|
<!-- You can also inherit from NNF_BaseTheme.Light -->
|
||||||
|
<style name="FilePickerTheme" parent="NNF_BaseTheme">
|
||||||
|
<!-- Set these to match your theme -->
|
||||||
|
<item name="colorPrimary">@color/blue_grey_500</item>
|
||||||
|
<item name="colorPrimaryDark">@color/blue_grey_700</item>
|
||||||
|
<item name="colorAccent">@color/teal_A700</item>
|
||||||
|
|
||||||
|
<!-- Need to set this also to style create folder dialog -->
|
||||||
|
<item name="alertDialogTheme">@style/FilePickerAlertDialogTheme</item>
|
||||||
|
</style>
|
||||||
|
|
||||||
|
<style name="FilePickerAlertDialogTheme" parent="Theme.AppCompat.Dialog.Alert">
|
||||||
|
<item name="colorPrimary">@color/blue_grey_500</item>
|
||||||
|
<item name="colorPrimaryDark">@color/blue_grey_700</item>
|
||||||
|
<item name="colorAccent">@color/teal_A700</item>
|
||||||
|
</style>
|
||||||
</resources>
|
</resources>
|
||||||
|
|
Loading…
Reference in a new issue