mirror of
https://github.com/beemdevelopment/Aegis.git
synced 2025-05-15 06:22:49 +00:00
Merge pull request #571 from michaelschattgen/feature/wipe-entries
Add checkbox dialog to wipe vault before import
This commit is contained in:
commit
141f491ca7
7 changed files with 92 additions and 3 deletions
|
@ -233,6 +233,37 @@ public class Dialogs {
|
||||||
showTextInputDialog(context, setPasswordMessageId, messageId, R.string.password, listener, dismissListener, true);
|
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) {
|
public static void showNumberPickerDialog(Activity activity, NumberInputListener listener) {
|
||||||
View view = activity.getLayoutInflater().inflate(R.layout.dialog_number_picker, null);
|
View view = activity.getLayoutInflater().inflate(R.layout.dialog_number_picker, null);
|
||||||
NumberPicker numberPicker = view.findViewById(R.id.numberPicker);
|
NumberPicker numberPicker = view.findViewById(R.id.numberPicker);
|
||||||
|
@ -352,6 +383,10 @@ public class Dialogs {
|
||||||
.create());
|
.create());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public interface CheckboxInputListener {
|
||||||
|
void onCheckboxInputResult(boolean checkbox);
|
||||||
|
}
|
||||||
|
|
||||||
public interface NumberInputListener {
|
public interface NumberInputListener {
|
||||||
void onNumberInputResult(int number);
|
void onNumberInputResult(int number);
|
||||||
}
|
}
|
||||||
|
|
|
@ -39,6 +39,7 @@ import com.beemdevelopment.aegis.ui.preferences.SwitchPreference;
|
||||||
import com.beemdevelopment.aegis.ui.tasks.PasswordSlotDecryptTask;
|
import com.beemdevelopment.aegis.ui.tasks.PasswordSlotDecryptTask;
|
||||||
import com.beemdevelopment.aegis.ui.tasks.ProgressDialogTask;
|
import com.beemdevelopment.aegis.ui.tasks.ProgressDialogTask;
|
||||||
import com.beemdevelopment.aegis.util.UUIDMap;
|
import com.beemdevelopment.aegis.util.UUIDMap;
|
||||||
|
import com.beemdevelopment.aegis.vault.Vault;
|
||||||
import com.beemdevelopment.aegis.vault.VaultBackupManager;
|
import com.beemdevelopment.aegis.vault.VaultBackupManager;
|
||||||
import com.beemdevelopment.aegis.vault.VaultEntry;
|
import com.beemdevelopment.aegis.vault.VaultEntry;
|
||||||
import com.beemdevelopment.aegis.vault.VaultFileCredentials;
|
import com.beemdevelopment.aegis.vault.VaultFileCredentials;
|
||||||
|
@ -659,6 +660,7 @@ public class PreferencesFragment extends PreferenceFragmentCompat {
|
||||||
Intent intent = new Intent(getActivity(), SelectEntriesActivity.class);
|
Intent intent = new Intent(getActivity(), SelectEntriesActivity.class);
|
||||||
intent.putExtra("entries", (ArrayList<ImportEntry>) entries);
|
intent.putExtra("entries", (ArrayList<ImportEntry>) entries);
|
||||||
intent.putExtra("errors", (ArrayList<DatabaseImporterEntryException>) result.getErrors());
|
intent.putExtra("errors", (ArrayList<DatabaseImporterEntryException>) result.getErrors());
|
||||||
|
intent.putExtra("vaultContainsEntries", _vault.getEntries().size() > 0);
|
||||||
startActivityForResult(intent, CODE_SELECT_ENTRIES);
|
startActivityForResult(intent, CODE_SELECT_ENTRIES);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -721,6 +723,11 @@ public class PreferencesFragment extends PreferenceFragmentCompat {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
boolean wipeEntries = data.getBooleanExtra("wipeEntries", false);
|
||||||
|
if (wipeEntries) {
|
||||||
|
_vault.wipeEntries();
|
||||||
|
}
|
||||||
|
|
||||||
List<ImportEntry> selectedEntries = (ArrayList<ImportEntry>) data.getSerializableExtra("entries");
|
List<ImportEntry> selectedEntries = (ArrayList<ImportEntry>) data.getSerializableExtra("entries");
|
||||||
for (ImportEntry selectedEntry : selectedEntries) {
|
for (ImportEntry selectedEntry : selectedEntries) {
|
||||||
VaultEntry savedEntry = _importerEntries.getByUUID(selectedEntry.getUUID());
|
VaultEntry savedEntry = _importerEntries.getByUUID(selectedEntry.getUUID());
|
||||||
|
|
|
@ -25,10 +25,12 @@ import com.getbase.floatingactionbutton.FloatingActionButton;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.concurrent.atomic.AtomicBoolean;
|
||||||
|
|
||||||
public class SelectEntriesActivity extends AegisActivity {
|
public class SelectEntriesActivity extends AegisActivity {
|
||||||
private ImportEntriesAdapter _adapter;
|
private ImportEntriesAdapter _adapter;
|
||||||
private FabScrollHelper _fabScrollHelper;
|
private FabScrollHelper _fabScrollHelper;
|
||||||
|
private boolean _vaultContainsEntries;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void onCreate(Bundle savedInstanceState) {
|
protected void onCreate(Bundle savedInstanceState) {
|
||||||
|
@ -57,6 +59,7 @@ public class SelectEntriesActivity extends AegisActivity {
|
||||||
Intent intent = getIntent();
|
Intent intent = getIntent();
|
||||||
List<ImportEntry> entries = (ArrayList<ImportEntry>) intent.getSerializableExtra("entries");
|
List<ImportEntry> entries = (ArrayList<ImportEntry>) intent.getSerializableExtra("entries");
|
||||||
List<DatabaseImporterEntryException> errors = (ArrayList<DatabaseImporterEntryException>) intent.getSerializableExtra("errors");
|
List<DatabaseImporterEntryException> errors = (ArrayList<DatabaseImporterEntryException>) intent.getSerializableExtra("errors");
|
||||||
|
_vaultContainsEntries = intent.getBooleanExtra("vaultContainsEntries", false);
|
||||||
|
|
||||||
for (ImportEntry entry : entries) {
|
for (ImportEntry entry : entries) {
|
||||||
_adapter.addEntry(entry);
|
_adapter.addEntry(entry);
|
||||||
|
@ -67,7 +70,13 @@ public class SelectEntriesActivity extends AegisActivity {
|
||||||
}
|
}
|
||||||
|
|
||||||
FloatingActionButton fabMenu = findViewById(R.id.fab);
|
FloatingActionButton fabMenu = findViewById(R.id.fab);
|
||||||
fabMenu.setOnClickListener(v -> returnSelectedEntries());
|
fabMenu.setOnClickListener(v -> {
|
||||||
|
if (_vaultContainsEntries) {
|
||||||
|
showWipeEntriesDialog();
|
||||||
|
} else {
|
||||||
|
returnSelectedEntries(false);
|
||||||
|
}
|
||||||
|
});
|
||||||
_fabScrollHelper = new FabScrollHelper(fabMenu);
|
_fabScrollHelper = new FabScrollHelper(fabMenu);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -100,10 +109,19 @@ public class SelectEntriesActivity extends AegisActivity {
|
||||||
.create());
|
.create());
|
||||||
}
|
}
|
||||||
|
|
||||||
private void returnSelectedEntries() {
|
private void showWipeEntriesDialog() {
|
||||||
List<ImportEntry> entries = _adapter.getCheckedEntries();
|
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();
|
Intent intent = new Intent();
|
||||||
|
List<ImportEntry> entries = _adapter.getCheckedEntries();
|
||||||
intent.putExtra("entries", (ArrayList<ImportEntry>) entries);
|
intent.putExtra("entries", (ArrayList<ImportEntry>) entries);
|
||||||
|
intent.putExtra("wipeEntries", wipeEntries);
|
||||||
setResult(RESULT_OK, intent);
|
setResult(RESULT_OK, intent);
|
||||||
finish();
|
finish();
|
||||||
}
|
}
|
||||||
|
|
|
@ -44,6 +44,13 @@ public class UUIDMap <T extends UUIDMap.Value> implements Iterable<T>, Serializa
|
||||||
return oldValue;
|
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
|
* Replaces an old value (with the same UUID as the new given value) in the
|
||||||
* internal map with the new given value.
|
* internal map with the new given value.
|
||||||
|
|
|
@ -154,6 +154,10 @@ public class VaultManager {
|
||||||
return _vault.getEntries().remove(entry);
|
return _vault.getEntries().remove(entry);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void wipeEntries() {
|
||||||
|
_vault.getEntries().wipe();
|
||||||
|
}
|
||||||
|
|
||||||
public VaultEntry replaceEntry(VaultEntry entry) {
|
public VaultEntry replaceEntry(VaultEntry entry) {
|
||||||
return _vault.getEntries().replace(entry);
|
return _vault.getEntries().replace(entry);
|
||||||
}
|
}
|
||||||
|
|
15
app/src/main/res/layout/dialog_checkbox.xml
Normal file
15
app/src/main/res/layout/dialog_checkbox.xml
Normal 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>
|
|
@ -315,4 +315,7 @@
|
||||||
<string name="title_activity_scan_qr">Scan a QR code</string>
|
<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_manage_slots">Manage key slots</string>
|
||||||
<string name="title_activity_select_entries">Select entries</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>
|
</resources>
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue