mirror of
https://github.com/beemdevelopment/Aegis.git
synced 2025-06-10 00:27:49 +00:00
Merge pull request #389 from alexbakker/edit-entry-fix
Write entries to the vault directly in EditEntryActivity
This commit is contained in:
commit
0bbc413423
6 changed files with 116 additions and 84 deletions
|
@ -8,13 +8,14 @@ import android.provider.Settings;
|
|||
import android.view.WindowManager;
|
||||
import android.widget.Toast;
|
||||
|
||||
import androidx.annotation.CallSuper;
|
||||
import androidx.appcompat.app.AppCompatActivity;
|
||||
|
||||
import com.beemdevelopment.aegis.AegisApplication;
|
||||
import com.beemdevelopment.aegis.Preferences;
|
||||
import com.beemdevelopment.aegis.R;
|
||||
import com.beemdevelopment.aegis.Theme;
|
||||
|
||||
import androidx.annotation.CallSuper;
|
||||
import androidx.appcompat.app.AppCompatActivity;
|
||||
import com.beemdevelopment.aegis.vault.VaultManagerException;
|
||||
|
||||
import java.util.Locale;
|
||||
|
||||
|
@ -126,6 +127,16 @@ public abstract class AegisActivity extends AppCompatActivity implements AegisAp
|
|||
this.getResources().updateConfiguration(config, this.getResources().getDisplayMetrics());
|
||||
}
|
||||
|
||||
protected boolean saveVault() {
|
||||
try {
|
||||
getApp().getVaultManager().save();
|
||||
return true;
|
||||
} catch (VaultManagerException e) {
|
||||
Toast.makeText(this, getString(R.string.saving_error), Toast.LENGTH_LONG).show();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Reports whether this Activity has been resumed. (i.e. onResume was called)
|
||||
*/
|
||||
|
|
|
@ -31,7 +31,6 @@ import androidx.appcompat.app.AlertDialog;
|
|||
import com.amulyakhare.textdrawable.TextDrawable;
|
||||
import com.avito.android.krop.KropView;
|
||||
import com.beemdevelopment.aegis.R;
|
||||
import com.beemdevelopment.aegis.vault.VaultEntry;
|
||||
import com.beemdevelopment.aegis.encoding.Base32;
|
||||
import com.beemdevelopment.aegis.encoding.EncodingException;
|
||||
import com.beemdevelopment.aegis.helpers.EditTextHelper;
|
||||
|
@ -43,16 +42,18 @@ import com.beemdevelopment.aegis.otp.OtpInfoException;
|
|||
import com.beemdevelopment.aegis.otp.SteamInfo;
|
||||
import com.beemdevelopment.aegis.otp.TotpInfo;
|
||||
import com.beemdevelopment.aegis.util.Cloner;
|
||||
import com.beemdevelopment.aegis.vault.VaultEntry;
|
||||
import com.beemdevelopment.aegis.vault.VaultManager;
|
||||
import com.bumptech.glide.Glide;
|
||||
import com.bumptech.glide.load.engine.DiskCacheStrategy;
|
||||
import com.bumptech.glide.request.target.CustomTarget;
|
||||
import com.bumptech.glide.request.transition.Transition;
|
||||
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.text.Collator;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.TreeSet;
|
||||
import java.util.UUID;
|
||||
import java.util.concurrent.atomic.AtomicReference;
|
||||
|
||||
import de.hdodenhof.circleimageview.CircleImageView;
|
||||
|
@ -89,22 +90,28 @@ public class EditEntryActivity extends AegisActivity {
|
|||
private RelativeLayout _advancedSettingsHeader;
|
||||
private RelativeLayout _advancedSettings;
|
||||
|
||||
private VaultManager _vault;
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
setContentView(R.layout.activity_edit_entry);
|
||||
|
||||
_vault = getApp().getVaultManager();
|
||||
_groups = _vault.getGroups();
|
||||
|
||||
ActionBar bar = getSupportActionBar();
|
||||
bar.setHomeAsUpIndicator(R.drawable.ic_close);
|
||||
bar.setDisplayHomeAsUpEnabled(true);
|
||||
|
||||
// retrieve info from the calling activity
|
||||
Intent intent = getIntent();
|
||||
_origEntry = (VaultEntry) intent.getSerializableExtra("entry");
|
||||
_isNew = intent.getBooleanExtra("isNew", false);
|
||||
_groups = new TreeSet<>(Collator.getInstance());
|
||||
_groups.addAll(intent.getStringArrayListExtra("groups"));
|
||||
if (_isNew) {
|
||||
UUID entryUUID = (UUID) intent.getSerializableExtra("entryUUID");
|
||||
if (entryUUID != null) {
|
||||
_origEntry = _vault.getEntryByUUID(entryUUID);
|
||||
} else {
|
||||
_origEntry = (VaultEntry) intent.getSerializableExtra("newEntry");
|
||||
_isNew = true;
|
||||
setTitle(R.string.add_new_entry);
|
||||
}
|
||||
|
||||
|
@ -185,9 +192,8 @@ public class EditEntryActivity extends AegisActivity {
|
|||
_spinnerType.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
|
||||
@Override
|
||||
public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
|
||||
String type = _spinnerType.getSelectedItem().toString();
|
||||
|
||||
switch (type.toLowerCase()) {
|
||||
String type = _spinnerType.getSelectedItem().toString().toLowerCase();
|
||||
switch (type) {
|
||||
case TotpInfo.ID:
|
||||
case SteamInfo.ID:
|
||||
_rowCounter.setVisibility(View.GONE);
|
||||
|
@ -251,7 +257,6 @@ public class EditEntryActivity extends AegisActivity {
|
|||
// automatically open advanced settings since 'Secret' is required.
|
||||
if (_isNew) {
|
||||
openAdvancedSettings();
|
||||
|
||||
setGroup(selectedGroup);
|
||||
}
|
||||
}
|
||||
|
@ -264,6 +269,7 @@ public class EditEntryActivity extends AegisActivity {
|
|||
int pos = _groups.contains(groupName) ? _groups.headSet(groupName).size() : -1;
|
||||
_spinnerGroup.setSelection(pos + 1, false);
|
||||
}
|
||||
|
||||
private void openAdvancedSettings() {
|
||||
Animation fadeOut = new AlphaAnimation(1, 0);
|
||||
fadeOut.setInterpolator(new AccelerateInterpolator());
|
||||
|
@ -344,7 +350,7 @@ public class EditEntryActivity extends AegisActivity {
|
|||
return;
|
||||
}
|
||||
|
||||
finish(entry.get(), false);
|
||||
addAndFinish(entry.get());
|
||||
},
|
||||
(dialog, which) -> super.onBackPressed()
|
||||
);
|
||||
|
@ -361,7 +367,7 @@ public class EditEntryActivity extends AegisActivity {
|
|||
break;
|
||||
case R.id.action_delete:
|
||||
Dialogs.showDeleteEntryDialog(this, (dialog, which) -> {
|
||||
finish(_origEntry, true);
|
||||
deleteAndFinish(_origEntry);
|
||||
});
|
||||
break;
|
||||
case R.id.action_default_icon:
|
||||
|
@ -389,12 +395,30 @@ public class EditEntryActivity extends AegisActivity {
|
|||
return true;
|
||||
}
|
||||
|
||||
private void finish(VaultEntry entry, boolean delete) {
|
||||
private void addAndFinish(VaultEntry entry) {
|
||||
if (_isNew) {
|
||||
_vault.addEntry(entry);
|
||||
} else {
|
||||
_vault.replaceEntry(entry);
|
||||
}
|
||||
|
||||
saveAndFinish(entry, false);
|
||||
}
|
||||
|
||||
private void deleteAndFinish(VaultEntry entry) {
|
||||
_vault.removeEntry(entry);
|
||||
saveAndFinish(entry, true);
|
||||
}
|
||||
|
||||
private void saveAndFinish(VaultEntry entry, boolean delete) {
|
||||
Intent intent = new Intent();
|
||||
intent.putExtra("entry", entry);
|
||||
intent.putExtra("entryUUID", entry.getUUID());
|
||||
intent.putExtra("delete", delete);
|
||||
setResult(RESULT_OK, intent);
|
||||
finish();
|
||||
|
||||
if (saveVault()) {
|
||||
setResult(RESULT_OK, intent);
|
||||
finish();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -540,7 +564,7 @@ public class EditEntryActivity extends AegisActivity {
|
|||
return false;
|
||||
}
|
||||
|
||||
finish(entry, false);
|
||||
addAndFinish(entry);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
@ -51,17 +51,17 @@ import java.io.InputStream;
|
|||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.TreeSet;
|
||||
import java.util.UUID;
|
||||
|
||||
public class MainActivity extends AegisActivity implements EntryListView.Listener {
|
||||
// activity request codes
|
||||
private static final int CODE_SCAN = 0;
|
||||
private static final int CODE_ADD_ENTRY = 1;
|
||||
private static final int CODE_EDIT_ENTRY = 2;
|
||||
private static final int CODE_ENTER_ENTRY = 3;
|
||||
private static final int CODE_DO_INTRO = 4;
|
||||
private static final int CODE_DECRYPT = 5;
|
||||
private static final int CODE_PREFERENCES = 6;
|
||||
private static final int CODE_SCAN_IMAGE = 7;
|
||||
private static final int CODE_DO_INTRO = 3;
|
||||
private static final int CODE_DECRYPT = 4;
|
||||
private static final int CODE_PREFERENCES = 5;
|
||||
private static final int CODE_SCAN_IMAGE = 6;
|
||||
|
||||
// permission request codes
|
||||
private static final int CODE_PERM_CAMERA = 0;
|
||||
|
@ -112,7 +112,7 @@ public class MainActivity extends AegisActivity implements EntryListView.Listene
|
|||
_fabMenu = findViewById(R.id.fab);
|
||||
findViewById(R.id.fab_enter).setOnClickListener(view -> {
|
||||
_fabMenu.collapse();
|
||||
startEditProfileActivity(CODE_ENTER_ENTRY, null, true);
|
||||
startEditEntryActivity(CODE_ADD_ENTRY, null, true);
|
||||
});
|
||||
findViewById(R.id.fab_scan_image).setOnClickListener(view -> {
|
||||
_fabMenu.collapse();
|
||||
|
@ -179,9 +179,6 @@ public class MainActivity extends AegisActivity implements EntryListView.Listene
|
|||
case CODE_EDIT_ENTRY:
|
||||
onEditEntryResult(resultCode, data);
|
||||
break;
|
||||
case CODE_ENTER_ENTRY:
|
||||
onEnterEntryResult(resultCode, data);
|
||||
break;
|
||||
case CODE_DO_INTRO:
|
||||
onDoIntroResult(resultCode, data);
|
||||
break;
|
||||
|
@ -238,50 +235,42 @@ public class MainActivity extends AegisActivity implements EntryListView.Listene
|
|||
}
|
||||
}
|
||||
|
||||
private void startEditProfileActivity(int requestCode, VaultEntry entry, boolean isNew) {
|
||||
private void startEditEntryActivity(int requestCode, VaultEntry entry, boolean isNew) {
|
||||
Intent intent = new Intent(this, EditEntryActivity.class);
|
||||
intent.putExtra("entry", entry != null ? entry : VaultEntry.getDefault());
|
||||
intent.putExtra("isNew", isNew);
|
||||
if (isNew) {
|
||||
intent.putExtra("newEntry", entry != null ? entry : VaultEntry.getDefault());
|
||||
} else {
|
||||
intent.putExtra("entryUUID", entry.getUUID());
|
||||
}
|
||||
intent.putExtra("selectedGroup", _selectedGroup);
|
||||
intent.putExtra("groups", new ArrayList<>(_vault.getGroups()));
|
||||
startActivityForResult(intent, requestCode);
|
||||
}
|
||||
|
||||
private void onScanResult(int resultCode, Intent data) {
|
||||
if (resultCode == RESULT_OK) {
|
||||
VaultEntry entry = (VaultEntry) data.getSerializableExtra("entry");
|
||||
startEditProfileActivity(CODE_ADD_ENTRY, entry, true);
|
||||
startEditEntryActivity(CODE_ADD_ENTRY, entry, true);
|
||||
}
|
||||
}
|
||||
|
||||
private void onAddEntryResult(int resultCode, Intent data) {
|
||||
if (resultCode == RESULT_OK) {
|
||||
VaultEntry entry = (VaultEntry) data.getSerializableExtra("entry");
|
||||
addEntry(entry);
|
||||
saveVault();
|
||||
UUID entryUUID = (UUID) data.getSerializableExtra("entryUUID");
|
||||
VaultEntry entry = _vault.getEntryByUUID(entryUUID);
|
||||
_entryListView.addEntry(entry);
|
||||
}
|
||||
}
|
||||
|
||||
private void onEditEntryResult(int resultCode, Intent data) {
|
||||
if (resultCode == RESULT_OK) {
|
||||
VaultEntry entry = (VaultEntry) data.getSerializableExtra("entry");
|
||||
if (data.getBooleanExtra("delete", false)) {
|
||||
deleteEntry(entry);
|
||||
} else {
|
||||
// this profile has been serialized/deserialized and is no longer the same instance it once was
|
||||
// to deal with this, the replaceEntry functions are used
|
||||
VaultEntry oldEntry = _vault.replaceEntry(entry);
|
||||
_entryListView.replaceEntry(oldEntry, entry);
|
||||
saveVault();
|
||||
}
|
||||
}
|
||||
}
|
||||
UUID entryUUID = (UUID) data.getSerializableExtra("entryUUID");
|
||||
|
||||
private void onEnterEntryResult(int resultCode, Intent data) {
|
||||
if (resultCode == RESULT_OK) {
|
||||
VaultEntry entry = (VaultEntry) data.getSerializableExtra("entry");
|
||||
addEntry(entry);
|
||||
saveVault();
|
||||
if (data.getBooleanExtra("delete", false)) {
|
||||
_entryListView.removeEntry(entryUUID);
|
||||
} else {
|
||||
VaultEntry entry = _vault.getEntryByUUID(entryUUID);
|
||||
_entryListView.replaceEntry(entryUUID, entry);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -309,7 +298,7 @@ public class MainActivity extends AegisActivity implements EntryListView.Listene
|
|||
GoogleAuthInfo info = GoogleAuthInfo.parseUri(result.getText());
|
||||
VaultEntry entry = new VaultEntry(info);
|
||||
|
||||
startEditProfileActivity(CODE_ADD_ENTRY, entry, true);
|
||||
startEditEntryActivity(CODE_ADD_ENTRY, entry, true);
|
||||
} catch (NotFoundException | IOException | ChecksumException | FormatException | GoogleAuthInfoException e) {
|
||||
Toast.makeText(this, getString(R.string.unable_to_read_qrcode), Toast.LENGTH_SHORT).show();
|
||||
e.printStackTrace();
|
||||
|
@ -359,11 +348,6 @@ public class MainActivity extends AegisActivity implements EntryListView.Listene
|
|||
_entryListView.setGroupFilter(group, true);
|
||||
}
|
||||
|
||||
private void addEntry(VaultEntry entry) {
|
||||
_vault.addEntry(entry);
|
||||
_entryListView.addEntry(entry);
|
||||
}
|
||||
|
||||
private void onDoIntroResult(int resultCode, Intent data) {
|
||||
if (resultCode == IntroActivity.RESULT_EXCEPTION) {
|
||||
// TODO: user feedback
|
||||
|
@ -442,10 +426,9 @@ public class MainActivity extends AegisActivity implements EntryListView.Listene
|
|||
|
||||
if (info != null) {
|
||||
VaultEntry entry = new VaultEntry(info);
|
||||
startEditProfileActivity(CODE_ADD_ENTRY, entry, true);
|
||||
startEditEntryActivity(CODE_ADD_ENTRY, entry, true);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -511,13 +494,6 @@ public class MainActivity extends AegisActivity implements EntryListView.Listene
|
|||
saveVault();
|
||||
}
|
||||
|
||||
private void deleteEntry(VaultEntry entry) {
|
||||
VaultEntry oldEntry = _vault.removeEntry(entry);
|
||||
saveVault();
|
||||
|
||||
_entryListView.removeEntry(oldEntry);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onCreateOptionsMenu(Menu menu) {
|
||||
_menu = menu;
|
||||
|
@ -662,14 +638,6 @@ public class MainActivity extends AegisActivity implements EntryListView.Listene
|
|||
startActivityForResult(intent, CODE_DECRYPT);
|
||||
}
|
||||
|
||||
private void saveVault() {
|
||||
try {
|
||||
_vault.save();
|
||||
} catch (VaultManagerException e) {
|
||||
Toast.makeText(this, getString(R.string.saving_error), Toast.LENGTH_LONG).show();
|
||||
}
|
||||
}
|
||||
|
||||
private void updateLockIcon() {
|
||||
// hide the lock icon if the vault is not unlocked
|
||||
if (_menu != null && !_vault.isLocked()) {
|
||||
|
@ -784,7 +752,7 @@ public class MainActivity extends AegisActivity implements EntryListView.Listene
|
|||
return true;
|
||||
|
||||
case R.id.action_edit:
|
||||
startEditProfileActivity(CODE_EDIT_ENTRY, _selectedEntries.get(0), false);
|
||||
startEditEntryActivity(CODE_EDIT_ENTRY, _selectedEntries.get(0), false);
|
||||
mode.finish();
|
||||
return true;
|
||||
|
||||
|
|
|
@ -10,12 +10,12 @@ import androidx.recyclerview.widget.RecyclerView;
|
|||
import com.beemdevelopment.aegis.R;
|
||||
import com.beemdevelopment.aegis.SortCategory;
|
||||
import com.beemdevelopment.aegis.ViewMode;
|
||||
import com.beemdevelopment.aegis.vault.VaultEntry;
|
||||
import com.beemdevelopment.aegis.helpers.ItemTouchHelperAdapter;
|
||||
import com.beemdevelopment.aegis.otp.HotpInfo;
|
||||
import com.beemdevelopment.aegis.otp.OtpInfo;
|
||||
import com.beemdevelopment.aegis.otp.OtpInfoException;
|
||||
import com.beemdevelopment.aegis.otp.TotpInfo;
|
||||
import com.beemdevelopment.aegis.vault.VaultEntry;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
|
@ -23,6 +23,7 @@ import java.util.Comparator;
|
|||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.UUID;
|
||||
|
||||
public class EntryAdapter extends RecyclerView.Adapter<EntryHolder> implements ItemTouchHelperAdapter {
|
||||
private EntryListView _view;
|
||||
|
@ -144,6 +145,11 @@ public class EntryAdapter extends RecyclerView.Adapter<EntryHolder> implements I
|
|||
checkPeriodUniformity();
|
||||
}
|
||||
|
||||
public void removeEntry(UUID uuid) {
|
||||
VaultEntry entry = getEntryByUUID(uuid);
|
||||
removeEntry(entry);
|
||||
}
|
||||
|
||||
public void clearEntries() {
|
||||
_entries.clear();
|
||||
_shownEntries.clear();
|
||||
|
@ -151,7 +157,8 @@ public class EntryAdapter extends RecyclerView.Adapter<EntryHolder> implements I
|
|||
checkPeriodUniformity();
|
||||
}
|
||||
|
||||
public void replaceEntry(VaultEntry oldEntry, VaultEntry newEntry) {
|
||||
public void replaceEntry(UUID uuid, VaultEntry newEntry) {
|
||||
VaultEntry oldEntry = getEntryByUUID(uuid);
|
||||
_entries.set(_entries.indexOf(oldEntry), newEntry);
|
||||
|
||||
if (_shownEntries.contains(oldEntry)) {
|
||||
|
@ -174,6 +181,16 @@ public class EntryAdapter extends RecyclerView.Adapter<EntryHolder> implements I
|
|||
checkPeriodUniformity();
|
||||
}
|
||||
|
||||
private VaultEntry getEntryByUUID(UUID uuid) {
|
||||
for (VaultEntry entry : _entries) {
|
||||
if (entry.getUUID().equals(uuid)) {
|
||||
return entry;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
private boolean isEntryFiltered(VaultEntry entry) {
|
||||
String group = entry.getGroup();
|
||||
String issuer = entry.getIssuer().toLowerCase();
|
||||
|
|
|
@ -22,10 +22,10 @@ import androidx.recyclerview.widget.RecyclerView;
|
|||
import com.beemdevelopment.aegis.R;
|
||||
import com.beemdevelopment.aegis.SortCategory;
|
||||
import com.beemdevelopment.aegis.ViewMode;
|
||||
import com.beemdevelopment.aegis.vault.VaultEntry;
|
||||
import com.beemdevelopment.aegis.helpers.SimpleItemTouchHelperCallback;
|
||||
import com.beemdevelopment.aegis.helpers.UiRefresher;
|
||||
import com.beemdevelopment.aegis.otp.TotpInfo;
|
||||
import com.beemdevelopment.aegis.vault.VaultEntry;
|
||||
import com.bumptech.glide.Glide;
|
||||
import com.bumptech.glide.ListPreloader;
|
||||
import com.bumptech.glide.RequestBuilder;
|
||||
|
@ -35,6 +35,7 @@ import com.bumptech.glide.util.ViewPreloadSizeProvider;
|
|||
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
|
||||
public class EntryListView extends Fragment implements EntryAdapter.Listener {
|
||||
private EntryAdapter _adapter;
|
||||
|
@ -262,12 +263,17 @@ public class EntryListView extends Fragment implements EntryAdapter.Listener {
|
|||
updateEmptyState();
|
||||
}
|
||||
|
||||
public void removeEntry(UUID uuid) {
|
||||
_adapter.removeEntry(uuid);
|
||||
updateEmptyState();
|
||||
}
|
||||
|
||||
public void clearEntries() {
|
||||
_adapter.clearEntries();
|
||||
}
|
||||
|
||||
public void replaceEntry(VaultEntry oldEntry, VaultEntry newEntry) {
|
||||
_adapter.replaceEntry(oldEntry, newEntry);
|
||||
public void replaceEntry(UUID uuid, VaultEntry newEntry) {
|
||||
_adapter.replaceEntry(uuid, newEntry);
|
||||
}
|
||||
|
||||
public void runEntriesAnimation() {
|
||||
|
|
|
@ -17,6 +17,7 @@ import java.io.OutputStream;
|
|||
import java.text.Collator;
|
||||
import java.util.Collection;
|
||||
import java.util.TreeSet;
|
||||
import java.util.UUID;
|
||||
|
||||
public class VaultManager {
|
||||
public static final String FILENAME = "aegis.json";
|
||||
|
@ -144,6 +145,11 @@ public class VaultManager {
|
|||
_vault.getEntries().add(entry);
|
||||
}
|
||||
|
||||
public VaultEntry getEntryByUUID(UUID uuid) {
|
||||
assertState(false, true);
|
||||
return _vault.getEntries().getByUUID(uuid);
|
||||
}
|
||||
|
||||
public VaultEntry removeEntry(VaultEntry entry) {
|
||||
assertState(false, true);
|
||||
return _vault.getEntries().remove(entry);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue