Merge pull request #571 from michaelschattgen/feature/wipe-entries

Add checkbox dialog to wipe vault before import
This commit is contained in:
Alexander Bakker 2020-08-16 17:58:21 +02:00 committed by GitHub
commit 141f491ca7
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
7 changed files with 92 additions and 3 deletions

View file

@ -233,6 +233,37 @@ public class Dialogs {
showTextInputDialog(context, setPasswordMessageId, messageId, R.string.password, listener, dismissListener, true);
}
public static void showCheckboxDialog(Context context, @StringRes int titleId, @StringRes int messageId, @StringRes int checkboxMessageId, CheckboxInputListener listener) {
View view = LayoutInflater.from(context).inflate(R.layout.dialog_checkbox, null);
CheckBox checkBox = view.findViewById(R.id.checkbox);
checkBox.setText(checkboxMessageId);
AlertDialog.Builder builder = new AlertDialog.Builder(context)
.setTitle(titleId)
.setView(view)
.setNegativeButton(R.string.no, (dialog1, which) ->
listener.onCheckboxInputResult(false))
.setPositiveButton(R.string.yes, (dialog1, which) ->
listener.onCheckboxInputResult(checkBox.isChecked()));
if (messageId != 0) {
builder.setMessage(messageId);
}
AlertDialog dialog = builder.create();
final AtomicReference<Button> buttonOK = new AtomicReference<>();
dialog.setOnShowListener(d -> {
Button button = dialog.getButton(AlertDialog.BUTTON_POSITIVE);
button.setEnabled(false);
buttonOK.set(button);
});
checkBox.setOnCheckedChangeListener((buttonView, isChecked) -> buttonOK.get().setEnabled(isChecked));
showSecureDialog(dialog);
}
public static void showNumberPickerDialog(Activity activity, NumberInputListener listener) {
View view = activity.getLayoutInflater().inflate(R.layout.dialog_number_picker, null);
NumberPicker numberPicker = view.findViewById(R.id.numberPicker);
@ -352,6 +383,10 @@ public class Dialogs {
.create());
}
public interface CheckboxInputListener {
void onCheckboxInputResult(boolean checkbox);
}
public interface NumberInputListener {
void onNumberInputResult(int number);
}

View file

@ -39,6 +39,7 @@ import com.beemdevelopment.aegis.ui.preferences.SwitchPreference;
import com.beemdevelopment.aegis.ui.tasks.PasswordSlotDecryptTask;
import com.beemdevelopment.aegis.ui.tasks.ProgressDialogTask;
import com.beemdevelopment.aegis.util.UUIDMap;
import com.beemdevelopment.aegis.vault.Vault;
import com.beemdevelopment.aegis.vault.VaultBackupManager;
import com.beemdevelopment.aegis.vault.VaultEntry;
import com.beemdevelopment.aegis.vault.VaultFileCredentials;
@ -659,6 +660,7 @@ public class PreferencesFragment extends PreferenceFragmentCompat {
Intent intent = new Intent(getActivity(), SelectEntriesActivity.class);
intent.putExtra("entries", (ArrayList<ImportEntry>) entries);
intent.putExtra("errors", (ArrayList<DatabaseImporterEntryException>) result.getErrors());
intent.putExtra("vaultContainsEntries", _vault.getEntries().size() > 0);
startActivityForResult(intent, CODE_SELECT_ENTRIES);
}
@ -721,6 +723,11 @@ public class PreferencesFragment extends PreferenceFragmentCompat {
return;
}
boolean wipeEntries = data.getBooleanExtra("wipeEntries", false);
if (wipeEntries) {
_vault.wipeEntries();
}
List<ImportEntry> selectedEntries = (ArrayList<ImportEntry>) data.getSerializableExtra("entries");
for (ImportEntry selectedEntry : selectedEntries) {
VaultEntry savedEntry = _importerEntries.getByUUID(selectedEntry.getUUID());

View file

@ -25,10 +25,12 @@ import com.getbase.floatingactionbutton.FloatingActionButton;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.atomic.AtomicBoolean;
public class SelectEntriesActivity extends AegisActivity {
private ImportEntriesAdapter _adapter;
private FabScrollHelper _fabScrollHelper;
private boolean _vaultContainsEntries;
@Override
protected void onCreate(Bundle savedInstanceState) {
@ -57,6 +59,7 @@ public class SelectEntriesActivity extends AegisActivity {
Intent intent = getIntent();
List<ImportEntry> entries = (ArrayList<ImportEntry>) intent.getSerializableExtra("entries");
List<DatabaseImporterEntryException> errors = (ArrayList<DatabaseImporterEntryException>) intent.getSerializableExtra("errors");
_vaultContainsEntries = intent.getBooleanExtra("vaultContainsEntries", false);
for (ImportEntry entry : entries) {
_adapter.addEntry(entry);
@ -67,7 +70,13 @@ public class SelectEntriesActivity extends AegisActivity {
}
FloatingActionButton fabMenu = findViewById(R.id.fab);
fabMenu.setOnClickListener(v -> returnSelectedEntries());
fabMenu.setOnClickListener(v -> {
if (_vaultContainsEntries) {
showWipeEntriesDialog();
} else {
returnSelectedEntries(false);
}
});
_fabScrollHelper = new FabScrollHelper(fabMenu);
}
@ -100,10 +109,19 @@ public class SelectEntriesActivity extends AegisActivity {
.create());
}
private void returnSelectedEntries() {
List<ImportEntry> entries = _adapter.getCheckedEntries();
private void showWipeEntriesDialog() {
Dialogs.showCheckboxDialog(this, R.string.dialog_wipe_entries_title,
R.string.dialog_wipe_entries_message,
R.string.dialog_wipe_entries_checkbox,
this::returnSelectedEntries
);
}
private void returnSelectedEntries(boolean wipeEntries) {
Intent intent = new Intent();
List<ImportEntry> entries = _adapter.getCheckedEntries();
intent.putExtra("entries", (ArrayList<ImportEntry>) entries);
intent.putExtra("wipeEntries", wipeEntries);
setResult(RESULT_OK, intent);
finish();
}

View file

@ -44,6 +44,13 @@ public class UUIDMap <T extends UUIDMap.Value> implements Iterable<T>, Serializa
return oldValue;
}
/**
* Clears the internal map.
*/
public void wipe() {
_map.clear();
}
/**
* Replaces an old value (with the same UUID as the new given value) in the
* internal map with the new given value.

View file

@ -154,6 +154,10 @@ public class VaultManager {
return _vault.getEntries().remove(entry);
}
public void wipeEntries() {
_vault.getEntries().wipe();
}
public VaultEntry replaceEntry(VaultEntry entry) {
return _vault.getEntries().replace(entry);
}

View file

@ -0,0 +1,15 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingStart="20dp"
android:paddingEnd="20dp"
android:paddingTop="20dp">
<CheckBox
android:id="@+id/checkbox"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<requestFocus/>
</CheckBox>
</LinearLayout>

View file

@ -315,4 +315,7 @@
<string name="title_activity_scan_qr">Scan a QR code</string>
<string name="title_activity_manage_slots">Manage key slots</string>
<string name="title_activity_select_entries">Select entries</string>
<string name="dialog_wipe_entries_title">Wipe entries</string>
<string name="dialog_wipe_entries_message">Your vault already contains entries. Do you want to remove these entries before importing this file?\n\n<b>In doing so, you will permanently lose access to the existing entries in the vault.</b></string>
<string name="dialog_wipe_entries_checkbox">Wipe vault contents</string>
</resources>