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:
Mohamed Zenadi 2015-11-22 14:19:48 +01:00
commit 5b3cc540e4
6 changed files with 129 additions and 58 deletions

View file

@ -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'...

View file

@ -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>

View file

@ -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();
} }

View file

@ -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();
}
} }
} }

View file

@ -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>

View file

@ -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>