From e6cc9b628ebd461ddacdfdaf773278f111ab3319 Mon Sep 17 00:00:00 2001 From: J-Jamet Date: Fri, 1 Dec 2017 20:03:22 +0100 Subject: [PATCH] New keyfile management --- .../keepassdroid/AssignPasswordDialog.java | 55 ++++-- .../com/keepassdroid/GroupBaseActivity.java | 4 +- .../com/keepassdroid/PasswordActivity.java | 121 ++----------- .../fileselect/FileSelectActivity.java | 4 +- .../com/keepassdroid/view/KeyFileHelper.java | 162 ++++++++++++++++++ app/src/main/res/layout/file_selection.xml | 10 ++ .../res/layout/file_selection_filename.xml | 16 +- app/src/main/res/layout/set_password.xml | 5 +- 8 files changed, 243 insertions(+), 134 deletions(-) create mode 100644 app/src/main/java/com/keepassdroid/view/KeyFileHelper.java diff --git a/app/src/main/java/com/keepassdroid/AssignPasswordDialog.java b/app/src/main/java/com/keepassdroid/AssignPasswordDialog.java index 9ee54ca1f..09c8eefc6 100644 --- a/app/src/main/java/com/keepassdroid/AssignPasswordDialog.java +++ b/app/src/main/java/com/keepassdroid/AssignPasswordDialog.java @@ -22,6 +22,7 @@ package com.keepassdroid; import android.app.Dialog; import android.content.Context; import android.content.DialogInterface; +import android.content.Intent; import android.net.Uri; import android.os.Bundle; import android.support.annotation.NonNull; @@ -31,26 +32,31 @@ import android.view.LayoutInflater; import android.view.View; import android.widget.Button; import android.widget.CompoundButton; +import android.widget.EditText; import android.widget.TextView; import android.widget.Toast; import com.keepassdroid.utils.EmptyUtils; import com.keepassdroid.utils.UriUtil; +import com.keepassdroid.view.KeyFileHelper; import com.kunzisoft.keepass.R; public class AssignPasswordDialog extends DialogFragment { - private String masterPassword; private Uri mKeyfile; + private View rootView; + private CompoundButton passwordCheckBox; + private CompoundButton keyfileCheckBox; private AssignPasswordDialogListener mListener; + private KeyFileHelper keyFileHelper; public interface AssignPasswordDialogListener { - void onDialogPositiveClick(String masterPassword, Uri keyFile); - void onDialogNegativeClick(String masterPassword, Uri keyFile); + void onAssignKeyDialogPositiveClick(String masterPassword, Uri keyFile); + void onAssignKeyDialogNegativeClick(String masterPassword, Uri keyFile); } @Override @@ -85,6 +91,20 @@ public class AssignPasswordDialog extends DialogFragment { } }); + + passwordCheckBox = (CompoundButton) rootView.findViewById(R.id.password_checkBox); + keyfileCheckBox = (CompoundButton) rootView.findViewById(R.id.keyfile_checkox); + + keyFileHelper = new KeyFileHelper(this); + rootView.findViewById(R.id.browse_button) + .setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View view) { + keyfileCheckBox.setChecked(true); + keyFileHelper.getOpenFileOnClickViewListener().onClick(view); + } + }); + AlertDialog dialog = builder.create(); dialog.setOnShowListener(new DialogInterface.OnShowListener() { @@ -94,8 +114,7 @@ public class AssignPasswordDialog extends DialogFragment { positiveButton.setOnClickListener(new View.OnClickListener() { @Override public void onClick(final View v) { - CompoundButton passwordCheckBox = (CompoundButton) rootView.findViewById(R.id.password_checkBox); - CompoundButton keyfileCheckBox = (CompoundButton) rootView.findViewById(R.id.keyfile_checkox); + masterPassword = ""; mKeyfile = null; @@ -130,10 +149,11 @@ public class AssignPasswordDialog extends DialogFragment { } if (!error) { - if (masterPassword == null || masterPassword.isEmpty()) { + if (!keyfileCheckBox.isChecked() && + (masterPassword == null || masterPassword.isEmpty())) { showEmptyPasswordConfirmationDialog(); } else { - mListener.onDialogPositiveClick(masterPassword, mKeyfile); + mListener.onAssignKeyDialogPositiveClick(masterPassword, mKeyfile); dismiss(); } } @@ -143,7 +163,7 @@ public class AssignPasswordDialog extends DialogFragment { negativeButton.setOnClickListener(new View.OnClickListener() { @Override public void onClick(final View v) { - mListener.onDialogNegativeClick(masterPassword, mKeyfile); + mListener.onAssignKeyDialogNegativeClick(masterPassword, mKeyfile); dismiss(); } }); @@ -159,16 +179,31 @@ public class AssignPasswordDialog extends DialogFragment { builder.setMessage(R.string.warning_empty_password) .setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialog, int id) { - mListener.onDialogPositiveClick(masterPassword, mKeyfile); + mListener.onAssignKeyDialogPositiveClick(masterPassword, mKeyfile); AssignPasswordDialog.this.dismiss(); } }) .setNegativeButton(R.string.cancel, new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialog, int id) { - mListener.onDialogNegativeClick(masterPassword, mKeyfile); + mListener.onAssignKeyDialogNegativeClick(masterPassword, mKeyfile); } }); builder.create().show(); } + @Override + public void onActivityResult(int requestCode, int resultCode, Intent data) { + super.onActivityResult(requestCode, resultCode, data); + + keyFileHelper.onActivityResultCallback(requestCode, resultCode, data, + new KeyFileHelper.KeyFileCallback() { + @Override + public void onResultCallback(Uri uri) { + if(uri != null) { + EditText keyFileView = (EditText) rootView.findViewById(R.id.pass_keyfile); + keyFileView.setText(uri.toString()); + } + } + }); + } } diff --git a/app/src/main/java/com/keepassdroid/GroupBaseActivity.java b/app/src/main/java/com/keepassdroid/GroupBaseActivity.java index b554bf260..3e3232c89 100644 --- a/app/src/main/java/com/keepassdroid/GroupBaseActivity.java +++ b/app/src/main/java/com/keepassdroid/GroupBaseActivity.java @@ -269,7 +269,7 @@ public abstract class GroupBaseActivity extends LockCloseListActivity } @Override - public void onDialogPositiveClick(String masterPassword, Uri keyFile) { + public void onAssignKeyDialogPositiveClick(String masterPassword, Uri keyFile) { AssignPasswordHelper assignPasswordHelper = new AssignPasswordHelper(this, @@ -278,7 +278,7 @@ public abstract class GroupBaseActivity extends LockCloseListActivity } @Override - public void onDialogNegativeClick(String masterPassword, Uri keyFile) { + public void onAssignKeyDialogNegativeClick(String masterPassword, Uri keyFile) { } diff --git a/app/src/main/java/com/keepassdroid/PasswordActivity.java b/app/src/main/java/com/keepassdroid/PasswordActivity.java index 69cbdc104..5976993d7 100644 --- a/app/src/main/java/com/keepassdroid/PasswordActivity.java +++ b/app/src/main/java/com/keepassdroid/PasswordActivity.java @@ -20,7 +20,6 @@ package com.keepassdroid; import android.app.Activity; -import android.content.ActivityNotFoundException; import android.content.Context; import android.content.DialogInterface; import android.content.DialogInterface.OnClickListener; @@ -50,18 +49,15 @@ import com.keepassdroid.app.App; import com.keepassdroid.compat.BackupManagerCompat; import com.keepassdroid.compat.ClipDataCompat; import com.keepassdroid.compat.EditorCompat; -import com.keepassdroid.compat.StorageAF; import com.keepassdroid.database.edit.LoadDB; import com.keepassdroid.database.edit.OnFinish; import com.keepassdroid.dialog.PasswordEncodingDialogHelper; -import com.keepassdroid.fileselect.BrowserDialog; import com.keepassdroid.fingerprint.FingerPrintHelper; -import com.keepassdroid.intents.Intents; import com.keepassdroid.utils.EmptyUtils; -import com.keepassdroid.utils.Interaction; import com.keepassdroid.utils.MenuUtil; import com.keepassdroid.utils.UriUtil; import com.keepassdroid.utils.Util; +import com.keepassdroid.view.KeyFileHelper; import com.kunzisoft.keepass.KeePass; import com.kunzisoft.keepass.R; @@ -79,10 +75,6 @@ public class PasswordActivity extends LockingActivity implements FingerPrintHelp private static final String KEY_LAUNCH_IMMEDIATELY = "launchImmediately"; private static final String VIEW_INTENT = "android.intent.action.VIEW"; - private static final int FILE_BROWSE = 256; - public static final int GET_CONTENT = 257; - private static final int OPEN_DOC = 258; - private Uri mDbUri = null; private Uri mKeyUri = null; private boolean mRememberKeyfile; @@ -100,6 +92,8 @@ public class PasswordActivity extends LockingActivity implements FingerPrintHelp private EditText passwordView; private Button confirmButton; + private KeyFileHelper keyFileHelper; + public static void Launch( Activity act, String fileName) throws FileNotFoundException { @@ -139,6 +133,17 @@ public class PasswordActivity extends LockingActivity implements FingerPrintHelp Intent data) { super.onActivityResult(requestCode, resultCode, data); + keyFileHelper.onActivityResultCallback(requestCode, resultCode, data, + new KeyFileHelper.KeyFileCallback() { + @Override + public void onResultCallback(Uri uri) { + if(uri != null) { + EditText fn = (EditText) findViewById(R.id.pass_keyfile); + fn.setText(uri.toString()); + } + } + }); + switch (requestCode) { case KeePass.EXIT_NORMAL: setEditText(R.id.password, ""); @@ -151,37 +156,8 @@ public class PasswordActivity extends LockingActivity implements FingerPrintHelp finish(); App.getDB().clear(); break; - case FILE_BROWSE: - if (resultCode == RESULT_OK) { - String filename = data.getDataString(); - if (filename != null) { - EditText fn = (EditText) findViewById(R.id.pass_keyfile); - fn.setText(filename); - mKeyUri = UriUtil.parseDefaultFile(filename); - } - } - break; - case GET_CONTENT: - case OPEN_DOC: - if (resultCode == RESULT_OK) { - if (data != null) { - Uri uri = data.getData(); - if (uri != null) { - if (requestCode == GET_CONTENT) { - uri = UriUtil.translate(this, uri); - } - String path = uri.toString(); - if (path != null) { - EditText fn = (EditText) findViewById(R.id.pass_keyfile); - fn.setText(path); - - } - mKeyUri = uri; - } - } - } - break; } + } @Override @@ -497,14 +473,6 @@ public class PasswordActivity extends LockingActivity implements FingerPrintHelp String pass, Uri keyfile) { - /* - TODO Remove - if (pass.length() == 0 && (keyfile == null || keyfile.toString().length() == 0)) { - errorMessage(R.string.error_nopass); - return; - } - */ - // Clear before we load Database db = App.getDB(); db.clear(); @@ -664,62 +632,9 @@ public class PasswordActivity extends LockingActivity implements FingerPrintHelp CompoundButton defaultCheck = (CompoundButton) findViewById(R.id.default_database); defaultCheck.setOnCheckedChangeListener(new DefaultCheckChange()); - View browse = findViewById(R.id.browse_button); - browse.setOnClickListener(new View.OnClickListener() { - - public void onClick(View v) { - if (StorageAF.useStorageFramework(PasswordActivity.this)) { - Intent i = new Intent(StorageAF.ACTION_OPEN_DOCUMENT); - i.addCategory(Intent.CATEGORY_OPENABLE); - i.setType("*/*"); - startActivityForResult(i, OPEN_DOC); - } else { - Intent i = new Intent(Intent.ACTION_GET_CONTENT); - i.addCategory(Intent.CATEGORY_OPENABLE); - i.setType("*/*"); - - try { - startActivityForResult(i, GET_CONTENT); - } catch (ActivityNotFoundException e) { - lookForOpenIntentsFilePicker(); - } - } - } - - private void lookForOpenIntentsFilePicker() { - if (Interaction.isIntentAvailable(PasswordActivity.this, Intents.OPEN_INTENTS_FILE_BROWSE)) { - Intent i = new Intent(Intents.OPEN_INTENTS_FILE_BROWSE); - - // Get file path parent if possible - try { - if (mDbUri != null && mDbUri.toString().length() > 0) { - if (mDbUri.getScheme().equals("file")) { - File keyfile = new File(mDbUri.getPath()); - File parent = keyfile.getParentFile(); - if (parent != null) { - i.setData(Uri.parse("file://" + parent.getAbsolutePath())); - } - } - } - } catch (Exception e) { - // Ignore - } - - try { - startActivityForResult(i, FILE_BROWSE); - } catch (ActivityNotFoundException e) { - showBrowserDialog(); - } - } else { - showBrowserDialog(); - } - } - - private void showBrowserDialog() { - BrowserDialog browserDialog = new BrowserDialog(PasswordActivity.this); - browserDialog.show(); - } - }); + View browseView = findViewById(R.id.browse_button); + keyFileHelper = new KeyFileHelper(PasswordActivity.this); + browseView.setOnClickListener(keyFileHelper.getOpenFileOnClickViewListener()); retrieveSettings(); diff --git a/app/src/main/java/com/keepassdroid/fileselect/FileSelectActivity.java b/app/src/main/java/com/keepassdroid/fileselect/FileSelectActivity.java index dfa7be00a..9e226d524 100644 --- a/app/src/main/java/com/keepassdroid/fileselect/FileSelectActivity.java +++ b/app/src/main/java/com/keepassdroid/fileselect/FileSelectActivity.java @@ -299,7 +299,7 @@ public class FileSelectActivity extends StylishActivity implements } @Override - public void onDialogPositiveClick(String masterPassword, Uri keyFile) { + public void onAssignKeyDialogPositiveClick(String masterPassword, Uri keyFile) { String filename = Util.getEditText(FileSelectActivity.this, R.id.file_filename); @@ -328,7 +328,7 @@ public class FileSelectActivity extends StylishActivity implements } @Override - public void onDialogNegativeClick(String masterPassword, Uri keyFile) { + public void onAssignKeyDialogNegativeClick(String masterPassword, Uri keyFile) { } diff --git a/app/src/main/java/com/keepassdroid/view/KeyFileHelper.java b/app/src/main/java/com/keepassdroid/view/KeyFileHelper.java new file mode 100644 index 000000000..00bebb761 --- /dev/null +++ b/app/src/main/java/com/keepassdroid/view/KeyFileHelper.java @@ -0,0 +1,162 @@ +package com.keepassdroid.view; + +import android.app.Activity; +import android.content.ActivityNotFoundException; +import android.content.Intent; +import android.net.Uri; +import android.support.v4.app.Fragment; +import android.view.View; + +import com.keepassdroid.compat.StorageAF; +import com.keepassdroid.fileselect.BrowserDialog; +import com.keepassdroid.intents.Intents; +import com.keepassdroid.utils.Interaction; +import com.keepassdroid.utils.UriUtil; + +import java.io.File; + +import static android.app.Activity.RESULT_OK; + +/** + * Created by joker on 01/12/17. + */ + +public class KeyFileHelper { + + public static final int GET_CONTENT = 25745; + private static final int OPEN_DOC = 25845; + private static final int FILE_BROWSE = 25645; + + private Activity activity; + private Fragment fragment; + private Uri mDbUri; + + public KeyFileHelper(Activity context) { + this(context, null); + } + + public KeyFileHelper(Activity context, Uri mDbUri) { + this.activity = context; + this.fragment = null; + this.mDbUri = mDbUri; + } + + public KeyFileHelper(Fragment context) { + this(context, null); + } + + public KeyFileHelper(Fragment context, Uri mDbUri) { + this.activity = context.getActivity(); + this.fragment = context; + this.mDbUri = mDbUri; + } + + public View.OnClickListener getOpenFileOnClickViewListener() { + return new View.OnClickListener() { + + public void onClick(View v) { + if (StorageAF.useStorageFramework(activity)) { + Intent i = new Intent(StorageAF.ACTION_OPEN_DOCUMENT); + i.addCategory(Intent.CATEGORY_OPENABLE); + i.setType("*/*"); + if(fragment != null) + fragment.startActivityForResult(i, OPEN_DOC); + else + activity.startActivityForResult(i, OPEN_DOC); + } else { + Intent i = new Intent(Intent.ACTION_GET_CONTENT); + i.addCategory(Intent.CATEGORY_OPENABLE); + i.setType("*/*"); + + try { + if(fragment != null) + fragment.startActivityForResult(i, GET_CONTENT); + else + activity.startActivityForResult(i, GET_CONTENT); + } catch (ActivityNotFoundException e) { + lookForOpenIntentsFilePicker(); + } + } + } + }; + } + + private void lookForOpenIntentsFilePicker() { + if (Interaction.isIntentAvailable(activity, Intents.OPEN_INTENTS_FILE_BROWSE)) { + Intent i = new Intent(Intents.OPEN_INTENTS_FILE_BROWSE); + + // Get file path parent if possible + try { + if (mDbUri != null && mDbUri.toString().length() > 0) { + if (mDbUri.getScheme().equals("file")) { + File keyfile = new File(mDbUri.getPath()); + File parent = keyfile.getParentFile(); + if (parent != null) { + i.setData(Uri.parse("file://" + parent.getAbsolutePath())); + } + } + } + } catch (Exception e) { + // Ignore + } + + try { + if(fragment != null) + fragment.startActivityForResult(i, FILE_BROWSE); + else + activity.startActivityForResult(i, FILE_BROWSE); + } catch (ActivityNotFoundException e) { + showBrowserDialog(); + } + } else { + showBrowserDialog(); + } + } + + private void showBrowserDialog() { + BrowserDialog browserDialog = new BrowserDialog(activity); + browserDialog.show(); + } + + + public void onActivityResultCallback( + int requestCode, + int resultCode, + Intent data, + KeyFileCallback keyFileCallback) { + + switch (requestCode) { + case FILE_BROWSE: + if (resultCode == RESULT_OK) { + String filename = data.getDataString(); + Uri keyUri = null; + if (filename != null) { + keyUri = UriUtil.parseDefaultFile(filename); + } + if (keyFileCallback != null) + keyFileCallback.onResultCallback(keyUri); + } + break; + case GET_CONTENT: + case OPEN_DOC: + if (resultCode == RESULT_OK) { + if (data != null) { + Uri uri = data.getData(); + if (uri != null) { + if (requestCode == GET_CONTENT) { + uri = UriUtil.translate(activity, uri); + } + if (keyFileCallback != null) + keyFileCallback.onResultCallback(uri); + } + } + } + break; + } + } + + public interface KeyFileCallback { + void onResultCallback(Uri uri); + } + +} diff --git a/app/src/main/res/layout/file_selection.xml b/app/src/main/res/layout/file_selection.xml index 8e44f8da6..df040805e 100644 --- a/app/src/main/res/layout/file_selection.xml +++ b/app/src/main/res/layout/file_selection.xml @@ -50,4 +50,14 @@ + + \ No newline at end of file diff --git a/app/src/main/res/layout/file_selection_filename.xml b/app/src/main/res/layout/file_selection_filename.xml index 12c43fab3..87796e328 100644 --- a/app/src/main/res/layout/file_selection_filename.xml +++ b/app/src/main/res/layout/file_selection_filename.xml @@ -75,25 +75,11 @@ - - - + android:src="@drawable/ic_open_folder_white_24dp" /> diff --git a/app/src/main/res/layout/set_password.xml b/app/src/main/res/layout/set_password.xml index 508009d18..53715f165 100644 --- a/app/src/main/res/layout/set_password.xml +++ b/app/src/main/res/layout/set_password.xml @@ -108,14 +108,15 @@ android:src="@drawable/ic_folder_white_24dp" android:tint="?attr/colorAccentCompat" /> - + android:maxLines="1" + android:singleLine="true"/>