mirror of
https://github.com/Kunzisoft/KeePassDX.git
synced 2025-12-04 15:49:33 +01:00
Refactor Database, Add Type parameters, Refactor ExtraFields
This commit is contained in:
@@ -51,12 +51,12 @@ public class PwEntryTestV4 extends TestCase {
|
||||
entry.setIcon(new PwIconStandard(5));
|
||||
entry.setOverrideURL("override");
|
||||
entry.setParent(new PwGroupV4());
|
||||
entry.addField("key2", new ProtectedString(false, "value2"));
|
||||
entry.addExtraField("key2", new ProtectedString(false, "value2"));
|
||||
entry.setUrl("http://localhost");
|
||||
entry.setUUID(UUID.randomUUID());
|
||||
|
||||
PwEntryV4 target = new PwEntryV4();
|
||||
target.assign(entry);
|
||||
target.updateWith(entry);
|
||||
|
||||
/* This test is not so useful now that I am not implementing value equality for Entries
|
||||
assertTrue("Entries do not match.", entry.equals(target));
|
||||
|
||||
@@ -32,7 +32,7 @@ public class EntryV4 extends TestCase {
|
||||
db.setHistoryMaxItems(2);
|
||||
|
||||
PwEntryV4 entry = new PwEntryV4();
|
||||
entry.startToDecodeReference(db);
|
||||
entry.startToManageFieldReferences(db);
|
||||
entry.setTitle("Title1");
|
||||
entry.setUsername("User1");
|
||||
entry.createBackup(db);
|
||||
@@ -46,7 +46,7 @@ public class EntryV4 extends TestCase {
|
||||
entry.createBackup(db);
|
||||
|
||||
PwEntryV4 backup = entry.getHistory().get(0);
|
||||
entry.endToDecodeReference(db);
|
||||
entry.endToManageFieldReferences();
|
||||
assertEquals("Title2", backup.getTitle());
|
||||
assertEquals("User2", backup.getUsername());
|
||||
}
|
||||
|
||||
@@ -37,9 +37,10 @@ import android.widget.Toast;
|
||||
|
||||
import com.keepassdroid.app.App;
|
||||
import com.keepassdroid.database.Database;
|
||||
import com.keepassdroid.database.ExtraFields;
|
||||
import com.keepassdroid.database.PwDatabase;
|
||||
import com.keepassdroid.database.PwEntry;
|
||||
import com.keepassdroid.database.PwGroup;
|
||||
import com.keepassdroid.database.security.ProtectedString;
|
||||
import com.keepassdroid.notifications.NotificationCopyingService;
|
||||
import com.keepassdroid.notifications.NotificationField;
|
||||
import com.keepassdroid.settings.PreferencesUtil;
|
||||
@@ -53,7 +54,6 @@ import com.kunzisoft.keepass.R;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Date;
|
||||
import java.util.Map;
|
||||
import java.util.UUID;
|
||||
|
||||
import static com.keepassdroid.settings.PreferencesUtil.isClipboardNotificationsEnable;
|
||||
@@ -108,7 +108,7 @@ public class EntryActivity extends LockingHideActivity {
|
||||
// Get Entry from UUID
|
||||
Intent i = getIntent();
|
||||
UUID uuid = Types.bytestoUUID(i.getByteArrayExtra(KEY_ENTRY));
|
||||
mEntry = db.pm.getEntryByUUIDId(uuid);
|
||||
mEntry = db.getPm().getEntryByUUIDId(uuid);
|
||||
if (mEntry == null) {
|
||||
Toast.makeText(this, R.string.entry_not_found, Toast.LENGTH_LONG).show();
|
||||
finish();
|
||||
@@ -147,14 +147,14 @@ public class EntryActivity extends LockingHideActivity {
|
||||
fillData();
|
||||
invalidateOptionsMenu();
|
||||
|
||||
// TODO Start decode
|
||||
mEntry.startToManageFieldReferences(App.getDB().getPm());
|
||||
|
||||
// If notifications enabled in settings
|
||||
// Don't if application timeout
|
||||
if (firstLaunchOfActivity && !App.isShutdown() && isClipboardNotificationsEnable(getApplicationContext())) {
|
||||
if (mEntry.getUsername().length() > 0
|
||||
|| (mEntry.getPassword().length() > 0 && PreferencesUtil.allowCopyPassword(this))
|
||||
|| mEntry.containsExtraFields()) {
|
||||
|| mEntry.containsCustomFields()) {
|
||||
// username already copied, waiting for user's action before copy password.
|
||||
Intent intent = new Intent(this, NotificationCopyingService.class);
|
||||
intent.setAction(NotificationCopyingService.ACTION_NEW_NOTIFICATION);
|
||||
@@ -181,17 +181,19 @@ public class EntryActivity extends LockingHideActivity {
|
||||
// Add extra fields
|
||||
if (mEntry.allowExtraFields()) {
|
||||
try {
|
||||
int anonymousFieldNumber = 0;
|
||||
Map<String, String> map = mEntry.getExtraFields();
|
||||
for (Map.Entry<String, String> entry : mEntry.getExtraFields().entrySet()) {
|
||||
mEntry.getFields().doActionToAllCustomProtectedField(new ExtraFields.ActionProtected() {
|
||||
private int anonymousFieldNumber = 0;
|
||||
@Override
|
||||
public void doAction(String key, ProtectedString value) {
|
||||
notificationFields.add(
|
||||
new NotificationField(
|
||||
NotificationField.NotificationFieldId.getAnonymousFieldId()[anonymousFieldNumber],
|
||||
entry.getValue(),
|
||||
entry.getKey(),
|
||||
value.toString(),
|
||||
key,
|
||||
getResources()));
|
||||
anonymousFieldNumber++;
|
||||
}
|
||||
});
|
||||
} catch (ArrayIndexOutOfBoundsException e) {
|
||||
Log.w(TAG, "Only " + NotificationField.NotificationFieldId.getAnonymousFieldId().length +
|
||||
" anonymous notifications are available");
|
||||
@@ -202,7 +204,7 @@ public class EntryActivity extends LockingHideActivity {
|
||||
|
||||
startService(intent);
|
||||
}
|
||||
// TODO end decode
|
||||
mEntry.endToManageFieldReferences();
|
||||
}
|
||||
firstLaunchOfActivity = false;
|
||||
}
|
||||
@@ -214,9 +216,9 @@ public class EntryActivity extends LockingHideActivity {
|
||||
|
||||
protected void fillData() {
|
||||
Database db = App.getDB();
|
||||
PwDatabase pm = db.pm;
|
||||
PwDatabase pm = db.getPm();
|
||||
|
||||
mEntry.startToDecodeReference(pm);
|
||||
mEntry.startToManageFieldReferences(pm);
|
||||
|
||||
// Assign title
|
||||
populateTitle(db.drawFactory.getIconDrawable(getResources(), mEntry.getIcon()),
|
||||
@@ -245,12 +247,15 @@ public class EntryActivity extends LockingHideActivity {
|
||||
// Assign custom fields
|
||||
if (mEntry.allowExtraFields()) {
|
||||
entryContentsView.clearExtraFields();
|
||||
for (Map.Entry<String, String> field : mEntry.getExtraFields().entrySet()) {
|
||||
final String label = field.getKey();
|
||||
final String value = field.getValue();
|
||||
entryContentsView.addExtraField(label, value, view ->
|
||||
clipboardHelper.timeoutCopyToClipboard(value, getString(R.string.copy_field, label)));
|
||||
}
|
||||
|
||||
mEntry.getFields().doActionToAllCustomProtectedField((label, value) ->
|
||||
|
||||
entryContentsView.addExtraField(label, value.toString(), view ->
|
||||
clipboardHelper.timeoutCopyToClipboard(
|
||||
value.toString(),
|
||||
getString(R.string.copy_field, label)
|
||||
)
|
||||
));
|
||||
}
|
||||
|
||||
// Assign dates
|
||||
@@ -264,7 +269,7 @@ public class EntryActivity extends LockingHideActivity {
|
||||
entryContentsView.assignExpiresDate(getString(R.string.never));
|
||||
}
|
||||
|
||||
mEntry.endToDecodeReference(pm);
|
||||
mEntry.endToManageFieldReferences();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -60,7 +60,6 @@ import com.keepassdroid.utils.Util;
|
||||
import com.keepassdroid.view.EntryEditNewField;
|
||||
import com.kunzisoft.keepass.R;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.UUID;
|
||||
|
||||
public class EntryEditActivity extends LockingHideActivity
|
||||
@@ -79,7 +78,7 @@ public class EntryEditActivity extends LockingHideActivity
|
||||
public static final int ADD_OR_UPDATE_ENTRY_REQUEST_CODE = 7129;
|
||||
public static final String ADD_OR_UPDATE_ENTRY_KEY = "ADD_OR_UPDATE_ENTRY_KEY";
|
||||
|
||||
protected PwEntry<PwGroup> mEntry;
|
||||
protected PwEntry mEntry;
|
||||
protected PwEntry mCallbackNewEntry;
|
||||
protected boolean mIsNew;
|
||||
protected int mSelectedIconID = -1;
|
||||
@@ -153,7 +152,7 @@ public class EntryEditActivity extends LockingHideActivity
|
||||
Intent intent = getIntent();
|
||||
byte[] uuidBytes = intent.getByteArrayExtra(KEY_ENTRY);
|
||||
|
||||
PwDatabase pm = db.pm;
|
||||
PwDatabase pm = db.getPm();
|
||||
if ( uuidBytes == null ) {
|
||||
PwGroupId parentId = (PwGroupId) intent.getSerializableExtra(KEY_PARENT);
|
||||
PwGroup parent = pm.getGroupByGroupId(parentId);
|
||||
@@ -244,11 +243,11 @@ public class EntryEditActivity extends LockingHideActivity
|
||||
}
|
||||
|
||||
protected PwEntry populateNewEntry() {
|
||||
PwDatabase db = App.getDB().pm;
|
||||
PwDatabase db = App.getDB().getPm();
|
||||
|
||||
PwEntry newEntry = mEntry.clone();
|
||||
|
||||
newEntry.startToDecodeReference(db);
|
||||
newEntry.startToManageFieldReferences(db);
|
||||
|
||||
newEntry.createBackup(db);
|
||||
|
||||
@@ -261,7 +260,7 @@ public class EntryEditActivity extends LockingHideActivity
|
||||
newEntry.setIcon(new PwIconStandard(mSelectedIconID));
|
||||
else {
|
||||
if (mIsNew) {
|
||||
newEntry.setIcon(App.getDB().pm.getIconFactory().getFirstIcon());
|
||||
newEntry.setIcon(App.getDB().getPm().getIconFactory().getFirstIcon());
|
||||
}
|
||||
else {
|
||||
// Keep previous icon, if no new one was selected
|
||||
@@ -274,19 +273,19 @@ public class EntryEditActivity extends LockingHideActivity
|
||||
newEntry.setPassword(entryPasswordView.getText().toString());
|
||||
|
||||
if (newEntry.allowExtraFields()) {
|
||||
// Delete all new standard strings
|
||||
newEntry.removeExtraFields();
|
||||
// Delete all extra strings
|
||||
newEntry.removeAllCustomFields();
|
||||
// Add extra fields from views
|
||||
for (int i = 0; i < entryExtraFieldsContainer.getChildCount(); i++) {
|
||||
EntryEditNewField view = (EntryEditNewField) entryExtraFieldsContainer.getChildAt(i);
|
||||
String key = view.getLabel();
|
||||
String value = view.getValue();
|
||||
boolean protect = view.isProtected();
|
||||
newEntry.addField(key, new ProtectedString(protect, value));
|
||||
newEntry.addExtraField(key, new ProtectedString(protect, value));
|
||||
}
|
||||
}
|
||||
|
||||
newEntry.endToDecodeReference(db);
|
||||
newEntry.endToManageFieldReferences();
|
||||
|
||||
return newEntry;
|
||||
}
|
||||
@@ -318,6 +317,8 @@ public class EntryEditActivity extends LockingHideActivity
|
||||
ImageButton currIconButton = findViewById(R.id.icon_button);
|
||||
App.getDB().drawFactory.assignDrawableTo(currIconButton, getResources(), mEntry.getIcon());
|
||||
|
||||
mEntry.startToManageFieldReferences(App.getDB().getPm());
|
||||
|
||||
entryTitleView.setText(mEntry.getTitle());
|
||||
entryUserNameView.setText(mEntry.getUsername());
|
||||
entryUrlView.setText(mEntry.getUrl());
|
||||
@@ -336,13 +337,15 @@ public class EntryEditActivity extends LockingHideActivity
|
||||
|
||||
if (mEntry.allowExtraFields()) {
|
||||
LinearLayout container = findViewById(R.id.advanced_container);
|
||||
for (Map.Entry<String, ProtectedString> pair : mEntry.getExtraProtectedFields().entrySet()) {
|
||||
mEntry.getFields().doActionToAllCustomProtectedField((key, value) -> {
|
||||
EntryEditNewField entryEditNewField = new EntryEditNewField(EntryEditActivity.this);
|
||||
entryEditNewField.setData(pair.getKey(), pair.getValue());
|
||||
entryEditNewField.setData(key, value);
|
||||
entryEditNewField.setFontVisibility(visibilityFontActivated);
|
||||
container.addView(entryEditNewField);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
mEntry.endToManageFieldReferences();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -179,14 +179,14 @@ public class GroupActivity extends ListNodesActivity
|
||||
PwGroup currentGroup;
|
||||
Database db = App.getDB();
|
||||
readOnly = db.readOnly;
|
||||
PwGroup root = db.pm.getRootGroup();
|
||||
PwGroup root = db.getPm().getRootGroup();
|
||||
|
||||
Log.w(TAG, "Creating tree view");
|
||||
PwGroupId pwGroupId = (PwGroupId) getIntent().getSerializableExtra(GROUP_ID_KEY);
|
||||
if ( pwGroupId == null ) {
|
||||
currentGroup = root;
|
||||
} else {
|
||||
currentGroup = db.pm.getGroupByGroupId(pwGroupId);
|
||||
currentGroup = db.getPm().getGroupByGroupId(pwGroupId);
|
||||
}
|
||||
|
||||
if (currentGroup != null) {
|
||||
|
||||
@@ -39,6 +39,7 @@ import android.widget.TextView;
|
||||
import com.keepassdroid.adapters.NodeAdapter;
|
||||
import com.keepassdroid.app.App;
|
||||
import com.keepassdroid.compat.EditorCompat;
|
||||
import com.keepassdroid.database.Database;
|
||||
import com.keepassdroid.database.PwDatabase;
|
||||
import com.keepassdroid.database.PwEntry;
|
||||
import com.keepassdroid.database.PwGroup;
|
||||
@@ -177,7 +178,7 @@ public abstract class ListNodesActivity extends LockingActivity
|
||||
case R.id.menu_sort:
|
||||
SortDialogFragment sortDialogFragment;
|
||||
|
||||
PwDatabase database = App.getDB().pm;
|
||||
PwDatabase database = App.getDB().getPm();
|
||||
/*
|
||||
// TODO Recycle bin bottom
|
||||
if (database.isRecycleBinAvailable() && database.isRecycleBinEnabled()) {
|
||||
@@ -294,8 +295,9 @@ public abstract class ListNodesActivity extends LockingActivity
|
||||
if ( mSuccess) {
|
||||
mAdapter.removeNode(pwNode);
|
||||
PwGroup parent = pwNode.getParent();
|
||||
PwDatabase database = App.getDB().pm;
|
||||
if (database.isRecycleBinAvailable() && database.isRecycleBinEnabled()) {
|
||||
Database db = App.getDB();
|
||||
PwDatabase database = db.getPm();
|
||||
if (db.isRecycleBinAvailabledAndEnabled()) {
|
||||
PwGroup recycleBin = database.getRecycleBin();
|
||||
// Add trash if it doesn't exists
|
||||
if (parent.equals(recycleBin)
|
||||
|
||||
@@ -265,7 +265,7 @@ public class NodeAdapter extends RecyclerView.Adapter<BasicViewHolder> {
|
||||
public void onCreateContextMenu(ContextMenu contextMenu, View view, ContextMenu.ContextMenuInfo contextMenuInfo) {
|
||||
MenuItem clearMenu = contextMenu.add(Menu.NONE, MENU_OPEN, Menu.NONE, R.string.menu_open);
|
||||
clearMenu.setOnMenuItemClickListener(mOnMyActionClickListener);
|
||||
if (!App.getDB().readOnly && !node.equals(App.getDB().pm.getRecycleBin())) {
|
||||
if (!App.getDB().readOnly && !node.equals(App.getDB().getPm().getRecycleBin())) {
|
||||
// TODO make edit for group
|
||||
// clearMenu = contextMenu.add(Menu.NONE, MENU_EDIT, Menu.NONE, R.string.menu_edit);
|
||||
// clearMenu.setOnMenuItemClickListener(mOnMyActionClickListener);
|
||||
|
||||
@@ -52,7 +52,9 @@ import java.io.SyncFailedException;
|
||||
*/
|
||||
public class Database {
|
||||
|
||||
public PwDatabase pm;
|
||||
private static final String TAG = Database.class.getName();
|
||||
|
||||
private PwDatabase pm;
|
||||
public Uri mUri;
|
||||
public SearchDbHelper searchHelper;
|
||||
public boolean readOnly = false;
|
||||
@@ -62,6 +64,14 @@ public class Database {
|
||||
|
||||
private boolean loaded = false;
|
||||
|
||||
public PwDatabase getPm() {
|
||||
return pm;
|
||||
}
|
||||
|
||||
public void setPm(PwDatabase pm) {
|
||||
this.pm = pm;
|
||||
}
|
||||
|
||||
public boolean Loaded() {
|
||||
return loaded;
|
||||
}
|
||||
@@ -103,6 +113,245 @@ public class Database {
|
||||
}
|
||||
}
|
||||
|
||||
public void addEntryTo(PwEntry entry, PwGroup parent) {
|
||||
try {
|
||||
switch (getPm().getVersion()) {
|
||||
case V3:
|
||||
((PwDatabaseV3) getPm()).addEntryTo((PwEntryV3) entry, (PwGroupV3) parent);
|
||||
break;
|
||||
case V4:
|
||||
((PwDatabaseV4) getPm()).addEntryTo((PwEntryV4) entry, (PwGroupV4) parent);
|
||||
break;
|
||||
}
|
||||
} catch (Exception e) {
|
||||
Log.e(TAG, "This version of PwEntry can't be added in this version of PwGroup", e);
|
||||
}
|
||||
}
|
||||
|
||||
public void removeEntryFrom(PwEntry entry, PwGroup parent) {
|
||||
try {
|
||||
switch (getPm().getVersion()) {
|
||||
case V3:
|
||||
((PwDatabaseV3) getPm()).removeEntryFrom((PwEntryV3) entry, (PwGroupV3) parent);
|
||||
break;
|
||||
case V4:
|
||||
((PwDatabaseV4) getPm()).removeEntryFrom((PwEntryV4) entry, (PwGroupV4) parent);
|
||||
break;
|
||||
}
|
||||
} catch (Exception e) {
|
||||
Log.e(TAG, "This version of PwEntry can't be removed from this version of PwGroup", e);
|
||||
}
|
||||
}
|
||||
|
||||
public void addGroupTo(PwGroup group, PwGroup parent) {
|
||||
try {
|
||||
switch (getPm().getVersion()) {
|
||||
case V3:
|
||||
((PwDatabaseV3) getPm()).addGroupTo((PwGroupV3) group, (PwGroupV3) parent);
|
||||
break;
|
||||
case V4:
|
||||
((PwDatabaseV4) getPm()).addGroupTo((PwGroupV4) group, (PwGroupV4) parent);
|
||||
break;
|
||||
}
|
||||
} catch (Exception e) {
|
||||
Log.e(TAG, "This version of PwGroup can't be added in this version of PwGroup", e);
|
||||
}
|
||||
}
|
||||
|
||||
public void removeGroupFrom(PwGroup group, PwGroup parent) {
|
||||
try {
|
||||
switch (getPm().getVersion()) {
|
||||
case V3:
|
||||
((PwDatabaseV3) getPm()).removeGroupFrom((PwGroupV3) group, (PwGroupV3) parent);
|
||||
break;
|
||||
case V4:
|
||||
((PwDatabaseV4) getPm()).removeGroupFrom((PwGroupV4) group, (PwGroupV4) parent);
|
||||
break;
|
||||
}
|
||||
} catch (Exception e) {
|
||||
Log.e(TAG, "This version of PwGroup can't be removed from this version of PwGroup", e);
|
||||
}
|
||||
}
|
||||
|
||||
public boolean canRecycle(PwEntry entry) {
|
||||
try {
|
||||
switch (getPm().getVersion()) {
|
||||
case V3:
|
||||
return ((PwDatabaseV3) getPm()).canRecycle((PwEntryV3) entry);
|
||||
case V4:
|
||||
return ((PwDatabaseV4) getPm()).canRecycle((PwEntryV4) entry);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
Log.e(TAG, "This version of PwEntry can't be recycled", e);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean canRecycle(PwGroup group) {
|
||||
try {
|
||||
switch (getPm().getVersion()) {
|
||||
case V3:
|
||||
return ((PwDatabaseV3) getPm()).canRecycle((PwGroupV3) group);
|
||||
case V4:
|
||||
return ((PwDatabaseV4) getPm()).canRecycle((PwGroupV4) group);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
Log.e(TAG, "This version of PwGroup can't be recycled", e);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public void recycle(PwEntry entry) {
|
||||
try {
|
||||
switch (getPm().getVersion()) {
|
||||
case V3:
|
||||
((PwDatabaseV3) getPm()).recycle((PwEntryV3) entry);
|
||||
break;
|
||||
case V4:
|
||||
((PwDatabaseV4) getPm()).recycle((PwEntryV4) entry);
|
||||
break;
|
||||
}
|
||||
} catch (Exception e) {
|
||||
Log.e(TAG, "This version of PwEntry can't be recycled", e);
|
||||
}
|
||||
}
|
||||
|
||||
public void recycle(PwGroup group) {
|
||||
try {
|
||||
switch (getPm().getVersion()) {
|
||||
case V3:
|
||||
((PwDatabaseV3) getPm()).recycle((PwGroupV3) group);
|
||||
break;
|
||||
case V4:
|
||||
((PwDatabaseV4) getPm()).recycle((PwGroupV4) group);
|
||||
break;
|
||||
}
|
||||
} catch (Exception e) {
|
||||
Log.e(TAG, "This version of PwGroup can't be recycled", e);
|
||||
}
|
||||
}
|
||||
|
||||
public void updateEntry(PwEntry oldEntry, PwEntry newEntry) {
|
||||
try {
|
||||
switch (getPm().getVersion()) {
|
||||
case V3:
|
||||
((PwEntryV3) oldEntry).updateWith((PwEntryV3) newEntry);
|
||||
break;
|
||||
case V4:
|
||||
((PwEntryV4) oldEntry).updateWith((PwEntryV4) newEntry);
|
||||
break;
|
||||
}
|
||||
} catch (Exception e) {
|
||||
Log.e(TAG, "This version of PwEntry can't be updated", e);
|
||||
}
|
||||
}
|
||||
|
||||
public void deleteEntry(PwEntry entry) {
|
||||
try {
|
||||
switch (getPm().getVersion()) {
|
||||
case V3:
|
||||
((PwDatabaseV3) getPm()).deleteEntry((PwEntryV3) entry);
|
||||
break;
|
||||
case V4:
|
||||
((PwDatabaseV4) getPm()).deleteEntry((PwEntryV4) entry);
|
||||
break;
|
||||
}
|
||||
} catch (Exception e) {
|
||||
Log.e(TAG, "This version of PwEntry can't be deleted", e);
|
||||
}
|
||||
}
|
||||
|
||||
public void deleteGroup(PwGroup group) {
|
||||
try {
|
||||
switch (getPm().getVersion()) {
|
||||
case V3:
|
||||
((PwDatabaseV3) getPm()).deleteGroup((PwGroupV3) group);
|
||||
break;
|
||||
case V4:
|
||||
((PwDatabaseV4) getPm()).deleteGroup((PwGroupV4) group);
|
||||
break;
|
||||
}
|
||||
} catch (Exception e) {
|
||||
Log.e(TAG, "This version of PwGroup can't be deleted", e);
|
||||
}
|
||||
}
|
||||
|
||||
public boolean isRecycleBinAvailabledAndEnabled() {
|
||||
try {
|
||||
switch (getPm().getVersion()) {
|
||||
case V3:
|
||||
return ((PwDatabaseV3) getPm()).isRecycleBinAvailable() &&
|
||||
((PwDatabaseV3) getPm()).isRecycleBinEnabled();
|
||||
case V4:
|
||||
return ((PwDatabaseV4) getPm()).isRecycleBinAvailable() &&
|
||||
((PwDatabaseV4) getPm()).isRecycleBinEnabled();
|
||||
}
|
||||
} catch (Exception e) {
|
||||
Log.e(TAG, "This version of database don't know if the Recyclebin is available", e);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public void undoRecycle(PwEntry entry, PwGroup parent) {
|
||||
try {
|
||||
switch (getPm().getVersion()) {
|
||||
case V3:
|
||||
((PwDatabaseV3) getPm()).undoRecycle((PwEntryV3) entry, (PwGroupV3) parent);
|
||||
break;
|
||||
case V4:
|
||||
((PwDatabaseV4) getPm()).undoRecycle((PwEntryV4) entry, (PwGroupV4) parent);
|
||||
break;
|
||||
}
|
||||
} catch (Exception e) {
|
||||
Log.e(TAG, "This version of database can't undo Recycle of this version of PwEntry", e);
|
||||
}
|
||||
}
|
||||
|
||||
public void undoRecycle(PwGroup group, PwGroup parent) {
|
||||
try {
|
||||
switch (getPm().getVersion()) {
|
||||
case V3:
|
||||
((PwDatabaseV3) getPm()).undoRecycle((PwGroupV3) group, (PwGroupV3) parent);
|
||||
break;
|
||||
case V4:
|
||||
((PwDatabaseV4) getPm()).undoRecycle((PwGroupV4) group, (PwGroupV4) parent);
|
||||
break;
|
||||
}
|
||||
} catch (Exception e) {
|
||||
Log.e(TAG, "This version of database can't undo Recycle of this version of PwGroup", e);
|
||||
}
|
||||
}
|
||||
|
||||
public void undoDeleteEntry(PwEntry entry, PwGroup parent) {
|
||||
try {
|
||||
switch (getPm().getVersion()) {
|
||||
case V3:
|
||||
((PwDatabaseV3) getPm()).undoDeleteEntry((PwEntryV3) entry, (PwGroupV3) parent);
|
||||
break;
|
||||
case V4:
|
||||
((PwDatabaseV4) getPm()).undoDeleteEntry((PwEntryV4) entry, (PwGroupV4) parent);
|
||||
break;
|
||||
}
|
||||
} catch (Exception e) {
|
||||
Log.e(TAG, "This version of database can't undo the deletion of this version of PwEntry", e);
|
||||
}
|
||||
}
|
||||
|
||||
public void undoDeleteGroup(PwGroup group, PwGroup parent) {
|
||||
try {
|
||||
switch (getPm().getVersion()) {
|
||||
case V3:
|
||||
((PwDatabaseV3) getPm()).undoDeleteGroup((PwGroupV3) group, (PwGroupV3) parent);
|
||||
break;
|
||||
case V4:
|
||||
((PwDatabaseV4) getPm()).undoDeleteGroup((PwGroupV4) group, (PwGroupV4) parent);
|
||||
break;
|
||||
}
|
||||
} catch (Exception e) {
|
||||
Log.e(TAG, "This version of database can't undo the deletion of this version of PwGroup", e);
|
||||
}
|
||||
}
|
||||
|
||||
private long getFixRounds(Context ctx) {
|
||||
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(ctx);
|
||||
return prefs.getLong(ctx.getString(R.string.roundsFix_key), ctx.getResources().getInteger(R.integer.roundsFix_default));
|
||||
|
||||
110
app/src/main/java/com/keepassdroid/database/ExtraFields.java
Normal file
110
app/src/main/java/com/keepassdroid/database/ExtraFields.java
Normal file
@@ -0,0 +1,110 @@
|
||||
package com.keepassdroid.database;
|
||||
|
||||
import com.keepassdroid.database.security.ProtectedString;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
import java.util.Map;
|
||||
|
||||
import static com.keepassdroid.database.PwEntryV4.STR_NOTES;
|
||||
import static com.keepassdroid.database.PwEntryV4.STR_PASSWORD;
|
||||
import static com.keepassdroid.database.PwEntryV4.STR_TITLE;
|
||||
import static com.keepassdroid.database.PwEntryV4.STR_URL;
|
||||
import static com.keepassdroid.database.PwEntryV4.STR_USERNAME;
|
||||
|
||||
public class ExtraFields implements Serializable, Cloneable {
|
||||
|
||||
private Map<String, ProtectedString> fields;
|
||||
|
||||
public ExtraFields() {
|
||||
fields = new HashMap<>();
|
||||
}
|
||||
|
||||
public boolean containsCustomFields() {
|
||||
return !getCustomProtectedFields().keySet().isEmpty();
|
||||
}
|
||||
|
||||
public String getProtectedStringValue(String key) {
|
||||
ProtectedString value = fields.get(key);
|
||||
if ( value == null ) return "";
|
||||
return value.toString();
|
||||
}
|
||||
|
||||
public void putProtectedString(String key, ProtectedString protectedString) {
|
||||
fields.put(key, protectedString);
|
||||
}
|
||||
|
||||
public void putProtectedString(String key, String value, boolean protect) {
|
||||
ProtectedString ps = new ProtectedString(protect, value);
|
||||
fields.put(key, ps);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return list of standard and customized fields
|
||||
*/
|
||||
public Map<String, ProtectedString> getListOfAllFields() {
|
||||
return fields;
|
||||
}
|
||||
|
||||
public void doActionToAllCustomProtectedField(ActionProtected actionProtected) {
|
||||
for (Map.Entry<String, ProtectedString> field : getCustomProtectedFields().entrySet()) {
|
||||
actionProtected.doAction(field.getKey(), field.getValue());
|
||||
}
|
||||
}
|
||||
|
||||
public interface ActionProtected {
|
||||
void doAction(String key, ProtectedString value);
|
||||
}
|
||||
|
||||
private Map<String, ProtectedString> getCustomProtectedFields() {
|
||||
Map<String, ProtectedString> protectedFields = new HashMap<>();
|
||||
if (fields.size() > 0) {
|
||||
for (Map.Entry<String, ProtectedString> pair : fields.entrySet()) {
|
||||
String key = pair.getKey();
|
||||
if (isNotStandardField(key)) {
|
||||
protectedFields.put(key, pair.getValue());
|
||||
// TODO Add hidden style for protection field
|
||||
}
|
||||
}
|
||||
}
|
||||
return protectedFields;
|
||||
}
|
||||
|
||||
public void removeAllCustomFields() {
|
||||
Iterator<Map.Entry<String, ProtectedString>> iter = fields.entrySet().iterator();
|
||||
while (iter.hasNext()) {
|
||||
Map.Entry<String, ProtectedString> pair = iter.next();
|
||||
if (isNotStandardField(pair.getKey())) {
|
||||
iter.remove();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static boolean isNotStandardField(String key) {
|
||||
return !key.equals(STR_TITLE) && !key.equals(STR_USERNAME)
|
||||
&& !key.equals(STR_PASSWORD) && !key.equals(STR_URL)
|
||||
&& !key.equals(STR_NOTES);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ExtraFields clone() {
|
||||
try {
|
||||
ExtraFields clone = (ExtraFields) super.clone();
|
||||
clone.fields = copyMap(this.fields);
|
||||
return clone;
|
||||
} catch (CloneNotSupportedException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private Map<String, ProtectedString> copyMap(
|
||||
Map<String, ProtectedString> original) {
|
||||
HashMap<String, ProtectedString> copy = new HashMap<>();
|
||||
for (Map.Entry<String, ProtectedString> entry : original.entrySet()) {
|
||||
copy.put(entry.getKey(), new ProtectedString(entry.getValue()));
|
||||
}
|
||||
return copy;
|
||||
}
|
||||
}
|
||||
@@ -64,6 +64,7 @@ public abstract class PwDatabase<PwGroupDB extends PwGroup<PwGroupDB, PwGroupDB,
|
||||
}
|
||||
|
||||
public static PwDatabase getNewDBInstance(String filename) {
|
||||
// TODO other condition to create a database
|
||||
if (isKDBExtension(filename)) {
|
||||
return new PwDatabaseV3();
|
||||
} else {
|
||||
@@ -284,7 +285,7 @@ public abstract class PwDatabase<PwGroupDB extends PwGroup<PwGroupDB, PwGroupDB,
|
||||
|
||||
public abstract List<PwGroupDB> getGroups();
|
||||
|
||||
public void addGroupTo(PwGroupDB newGroup, PwGroupDB parent) {
|
||||
protected void addGroupTo(PwGroupDB newGroup, PwGroupDB parent) {
|
||||
// Add tree to parent tree
|
||||
if ( parent == null ) {
|
||||
parent = rootGroup;
|
||||
@@ -297,7 +298,7 @@ public abstract class PwDatabase<PwGroupDB extends PwGroup<PwGroupDB, PwGroupDB,
|
||||
parent.touch(true, true);
|
||||
}
|
||||
|
||||
public void removeGroupFrom(PwGroupDB remove, PwGroupDB parent) {
|
||||
protected void removeGroupFrom(PwGroupDB remove, PwGroupDB parent) {
|
||||
// Remove tree from parent tree
|
||||
if (parent != null) {
|
||||
parent.removeChildGroup(remove);
|
||||
@@ -339,7 +340,7 @@ public abstract class PwDatabase<PwGroupDB extends PwGroup<PwGroupDB, PwGroupDB,
|
||||
return this.entries.get(id);
|
||||
}
|
||||
|
||||
public void addEntryTo(PwEntryDB newEntry, PwGroupDB parent) {
|
||||
protected void addEntryTo(PwEntryDB newEntry, PwGroupDB parent) {
|
||||
// Add entry to parent
|
||||
if (parent != null) {
|
||||
parent.addChildEntry(newEntry);
|
||||
@@ -349,7 +350,7 @@ public abstract class PwDatabase<PwGroupDB extends PwGroup<PwGroupDB, PwGroupDB,
|
||||
entries.put(newEntry.getUUID(), newEntry);
|
||||
}
|
||||
|
||||
public void removeEntryFrom(PwEntryDB remove, PwGroupDB parent) {
|
||||
protected void removeEntryFrom(PwEntryDB remove, PwGroupDB parent) {
|
||||
// Remove entry for parent
|
||||
if (parent != null) {
|
||||
parent.removeChildEntry(remove);
|
||||
@@ -359,7 +360,7 @@ public abstract class PwDatabase<PwGroupDB extends PwGroup<PwGroupDB, PwGroupDB,
|
||||
|
||||
public abstract boolean isBackup(PwGroupDB group);
|
||||
|
||||
public void populateGlobals(PwGroupDB currentGroup) {
|
||||
protected void populateGlobals(PwGroupDB currentGroup) {
|
||||
|
||||
List<PwGroupDB> childGroups = currentGroup.getChildGroups();
|
||||
List<PwEntryDB> childEntries = currentGroup.getChildEntries();
|
||||
@@ -380,7 +381,7 @@ public abstract class PwDatabase<PwGroupDB extends PwGroup<PwGroupDB, PwGroupDB,
|
||||
* Determine if RecycleBin is available or not for this version of database
|
||||
* @return true if RecycleBin enable
|
||||
*/
|
||||
public boolean isRecycleBinAvailable() {
|
||||
protected boolean isRecycleBinAvailable() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -388,7 +389,7 @@ public abstract class PwDatabase<PwGroupDB extends PwGroup<PwGroupDB, PwGroupDB,
|
||||
* Determine if RecycleBin is enable or not
|
||||
* @return true if RecycleBin enable, false if is not available or not enable
|
||||
*/
|
||||
public boolean isRecycleBinEnabled() {
|
||||
protected boolean isRecycleBinEnabled() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -397,7 +398,7 @@ public abstract class PwDatabase<PwGroupDB extends PwGroup<PwGroupDB, PwGroupDB,
|
||||
* @param group Group to remove
|
||||
* @return true if group can be recycle, false elsewhere
|
||||
*/
|
||||
public boolean canRecycle(PwGroupDB group) {
|
||||
protected boolean canRecycle(PwGroupDB group) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -406,36 +407,36 @@ public abstract class PwDatabase<PwGroupDB extends PwGroup<PwGroupDB, PwGroupDB,
|
||||
* @param entry Entry to remove
|
||||
* @return true if entry can be recycle, false elsewhere
|
||||
*/
|
||||
public boolean canRecycle(PwEntryDB entry) {
|
||||
protected boolean canRecycle(PwEntryDB entry) {
|
||||
return false;
|
||||
}
|
||||
|
||||
public void recycle(PwGroupDB group) {
|
||||
protected void recycle(PwGroupDB group) {
|
||||
// Assume calls to this are protected by calling inRecyleBin
|
||||
throw new RuntimeException("Call not valid for .kdb databases.");
|
||||
}
|
||||
|
||||
public void recycle(PwEntryDB entry) {
|
||||
protected void recycle(PwEntryDB entry) {
|
||||
// Assume calls to this are protected by calling inRecyleBin
|
||||
throw new RuntimeException("Call not valid for .kdb databases.");
|
||||
}
|
||||
|
||||
public void undoRecycle(PwGroupDB group, PwGroupDB origParent) {
|
||||
protected void undoRecycle(PwGroupDB group, PwGroupDB origParent) {
|
||||
throw new RuntimeException("Call not valid for .kdb databases.");
|
||||
}
|
||||
|
||||
public void undoRecycle(PwEntryDB entry, PwGroupDB origParent) {
|
||||
protected void undoRecycle(PwEntryDB entry, PwGroupDB origParent) {
|
||||
throw new RuntimeException("Call not valid for .kdb databases.");
|
||||
}
|
||||
|
||||
public void deleteGroup(PwGroupDB group) {
|
||||
PwGroupDB parent = (PwGroupDB) group.getParent(); // TODO inference
|
||||
protected void deleteGroup(PwGroupDB group) {
|
||||
PwGroupDB parent = group.getParent(); // TODO inference
|
||||
removeGroupFrom(group, parent);
|
||||
parent.touch(false, true);
|
||||
}
|
||||
|
||||
public void deleteEntry(PwEntryDB entry) {
|
||||
PwGroupDB parent = (PwGroupDB) entry.getParent(); // TODO inference
|
||||
protected void deleteEntry(PwEntryDB entry) {
|
||||
PwGroupDB parent = entry.getParent(); // TODO inference
|
||||
removeEntryFrom(entry, parent);
|
||||
parent.touch(false, true);
|
||||
}
|
||||
|
||||
@@ -226,7 +226,6 @@ public class PwDatabaseV3 extends PwDatabase<PwGroupV3, PwEntryV3> {
|
||||
grp.setParent(currentGroup);
|
||||
constructTree(currentGroup.getChildGroupAt(i));
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
@@ -56,7 +56,7 @@ import javax.xml.parsers.DocumentBuilderFactory;
|
||||
import biz.source_code.base64Coder.Base64Coder;
|
||||
|
||||
|
||||
public class PwDatabaseV4 extends PwDatabase {
|
||||
public class PwDatabaseV4 extends PwDatabase<PwGroupV4, PwEntryV4> {
|
||||
|
||||
public static final int DEFAULT_ROUNDS = 6000;
|
||||
private static final int DEFAULT_HISTORY_MAX_ITEMS = 10; // -1 unlimited
|
||||
@@ -451,41 +451,41 @@ public class PwDatabaseV4 extends PwDatabase {
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<PwGroup> getGroups() {
|
||||
List<PwGroup> list = new ArrayList<>();
|
||||
PwGroupV4 root = (PwGroupV4) rootGroup;
|
||||
public List<PwGroupV4> getGroups() {
|
||||
List<PwGroupV4> list = new ArrayList<>();
|
||||
PwGroupV4 root = rootGroup;
|
||||
buildChildGroupsRecursive(root, list);
|
||||
|
||||
return list;
|
||||
}
|
||||
|
||||
private static void buildChildGroupsRecursive(PwGroupV4 root, List<PwGroup> list) {
|
||||
private static void buildChildGroupsRecursive(PwGroupV4 root, List<PwGroupV4> list) {
|
||||
list.add(root);
|
||||
for ( int i = 0; i < root.numbersOfChildGroups(); i++) {
|
||||
PwGroupV4 child = (PwGroupV4) root.getChildGroupAt(i);
|
||||
PwGroupV4 child = root.getChildGroupAt(i);
|
||||
buildChildGroupsRecursive(child, list);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<PwGroup> getGrpRoots() {
|
||||
public List<PwGroupV4> getGrpRoots() {
|
||||
return rootGroup.getChildGroups();
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<PwEntry> getEntries() {
|
||||
List<PwEntry> list = new ArrayList<>();
|
||||
PwGroupV4 root = (PwGroupV4) rootGroup;
|
||||
public List<PwEntryV4> getEntries() {
|
||||
List<PwEntryV4> list = new ArrayList<>();
|
||||
PwGroupV4 root = rootGroup;
|
||||
buildChildEntriesRecursive(root, list);
|
||||
return list;
|
||||
}
|
||||
|
||||
private static void buildChildEntriesRecursive(PwGroupV4 root, List<PwEntry> list) {
|
||||
private static void buildChildEntriesRecursive(PwGroupV4 root, List<PwEntryV4> list) {
|
||||
for ( int i = 0; i < root.numbersOfChildEntries(); i++ ) {
|
||||
list.add(root.getChildEntryAt(i));
|
||||
}
|
||||
for ( int i = 0; i < root.numbersOfChildGroups(); i++ ) {
|
||||
PwGroupV4 child = (PwGroupV4) root.getChildGroupAt(i);
|
||||
PwGroupV4 child = root.getChildGroupAt(i);
|
||||
buildChildEntriesRecursive(child, list);
|
||||
}
|
||||
}
|
||||
@@ -513,7 +513,7 @@ public class PwDatabaseV4 extends PwDatabase {
|
||||
|
||||
@Override
|
||||
public PwGroupIdV4 newGroupId() {
|
||||
PwGroupIdV4 id = new PwGroupIdV4(UUID_ZERO);
|
||||
PwGroupIdV4 id;
|
||||
|
||||
while (true) {
|
||||
id = new PwGroupIdV4(UUID.randomUUID());
|
||||
@@ -530,7 +530,7 @@ public class PwDatabaseV4 extends PwDatabase {
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isBackup(PwGroup group) {
|
||||
public boolean isBackup(PwGroupV4 group) {
|
||||
if (!recycleBinEnabled) {
|
||||
return false;
|
||||
}
|
||||
@@ -539,7 +539,7 @@ public class PwDatabaseV4 extends PwDatabase {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void populateGlobals(PwGroup currentGroup) {
|
||||
public void populateGlobals(PwGroupV4 currentGroup) {
|
||||
groups.put(rootGroup.getId(), rootGroup);
|
||||
|
||||
super.populateGlobals(currentGroup);
|
||||
@@ -594,7 +594,7 @@ public class PwDatabaseV4 extends PwDatabase {
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canRecycle(PwGroup group) {
|
||||
public boolean canRecycle(PwGroupV4 group) {
|
||||
if (!recycleBinEnabled) {
|
||||
return false;
|
||||
}
|
||||
@@ -603,23 +603,23 @@ public class PwDatabaseV4 extends PwDatabase {
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canRecycle(PwEntry entry) {
|
||||
public boolean canRecycle(PwEntryV4 entry) {
|
||||
if (!recycleBinEnabled) {
|
||||
return false;
|
||||
}
|
||||
PwGroup parent = entry.getParent();
|
||||
PwGroupV4 parent = entry.getParent();
|
||||
return (parent != null) && canRecycle(parent);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void recycle(PwGroup group) {
|
||||
public void recycle(PwGroupV4 group) {
|
||||
ensureRecycleBin();
|
||||
|
||||
PwGroup parent = group.getParent();
|
||||
PwGroupV4 parent = group.getParent();
|
||||
removeGroupFrom(group, parent);
|
||||
parent.touch(false, true);
|
||||
|
||||
PwGroup recycleBin = getRecycleBin();
|
||||
PwGroupV4 recycleBin = getRecycleBin();
|
||||
addGroupTo(group, recycleBin);
|
||||
|
||||
group.touch(false, true);
|
||||
@@ -627,14 +627,14 @@ public class PwDatabaseV4 extends PwDatabase {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void recycle(PwEntry entry) {
|
||||
public void recycle(PwEntryV4 entry) {
|
||||
ensureRecycleBin();
|
||||
|
||||
PwGroup parent = entry.getParent();
|
||||
PwGroupV4 parent = entry.getParent();
|
||||
removeEntryFrom(entry, parent);
|
||||
parent.touch(false, true);
|
||||
|
||||
PwGroup recycleBin = getRecycleBin();
|
||||
PwGroupV4 recycleBin = getRecycleBin();
|
||||
addEntryTo(entry, recycleBin);
|
||||
|
||||
entry.touch(false, true);
|
||||
@@ -642,18 +642,18 @@ public class PwDatabaseV4 extends PwDatabase {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void undoRecycle(PwGroup group, PwGroup origParent) {
|
||||
public void undoRecycle(PwGroupV4 group, PwGroupV4 origParent) {
|
||||
|
||||
PwGroup recycleBin = getRecycleBin();
|
||||
PwGroupV4 recycleBin = getRecycleBin();
|
||||
removeGroupFrom(group, recycleBin);
|
||||
|
||||
addGroupTo(group, origParent);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void undoRecycle(PwEntry entry, PwGroup origParent) {
|
||||
public void undoRecycle(PwEntryV4 entry, PwGroupV4 origParent) {
|
||||
|
||||
PwGroup recycleBin = getRecycleBin();
|
||||
PwGroupV4 recycleBin = getRecycleBin();
|
||||
removeEntryFrom(entry, recycleBin);
|
||||
|
||||
addEntryTo(entry, origParent);
|
||||
@@ -668,13 +668,13 @@ public class PwDatabaseV4 extends PwDatabase {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void deleteEntry(PwEntry entry) {
|
||||
public void deleteEntry(PwEntryV4 entry) {
|
||||
super.deleteEntry(entry);
|
||||
deletedObjects.add(new PwDeletedObject(entry.getUUID()));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void undoDeleteEntry(PwEntry entry, PwGroup origParent) {
|
||||
public void undoDeleteEntry(PwEntryV4 entry, PwGroupV4 origParent) {
|
||||
super.undoDeleteEntry(entry, origParent);
|
||||
// TODO undo delete entry
|
||||
deletedObjects.remove(entry);
|
||||
@@ -687,7 +687,7 @@ public class PwDatabaseV4 extends PwDatabase {
|
||||
}
|
||||
|
||||
PwGroupId recycleId = new PwGroupIdV4(recycleBinUUID);
|
||||
return (PwGroupV4) groups.get(recycleId);
|
||||
return groups.get(recycleId);
|
||||
}
|
||||
|
||||
public KdfParameters getKdfParameters() {
|
||||
@@ -719,14 +719,12 @@ public class PwDatabaseV4 extends PwDatabase {
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isGroupSearchable(PwGroup group, boolean omitBackup) {
|
||||
public boolean isGroupSearchable(PwGroupV4 group, boolean omitBackup) {
|
||||
if (!super.isGroupSearchable(group, omitBackup)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
PwGroupV4 g = (PwGroupV4) group;
|
||||
|
||||
return g.isSearchingEnabled();
|
||||
return group.isSearchingEnabled();
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -756,17 +754,16 @@ public class PwDatabaseV4 extends PwDatabase {
|
||||
return filename.substring(0, lastExtDot);
|
||||
}
|
||||
|
||||
private class GroupHasCustomData extends GroupHandler<PwGroup> {
|
||||
private class GroupHasCustomData extends GroupHandler<PwGroupV4> {
|
||||
|
||||
public boolean hasCustomData = false;
|
||||
|
||||
@Override
|
||||
public boolean operate(PwGroup group) {
|
||||
public boolean operate(PwGroupV4 group) {
|
||||
if (group == null) {
|
||||
return true;
|
||||
}
|
||||
PwGroupV4 g4 = (PwGroupV4) group;
|
||||
if (g4.containsCustomData()) {
|
||||
if (group.containsCustomData()) {
|
||||
hasCustomData = true;
|
||||
return false;
|
||||
}
|
||||
@@ -775,18 +772,17 @@ public class PwDatabaseV4 extends PwDatabase {
|
||||
}
|
||||
}
|
||||
|
||||
private class EntryHasCustomData extends EntryHandler<PwEntry> {
|
||||
private class EntryHasCustomData extends EntryHandler<PwEntryV4> {
|
||||
|
||||
public boolean hasCustomData = false;
|
||||
|
||||
@Override
|
||||
public boolean operate(PwEntry entry) {
|
||||
public boolean operate(PwEntryV4 entry) {
|
||||
if (entry == null) {
|
||||
return true;
|
||||
}
|
||||
|
||||
PwEntryV4 e4 = (PwEntryV4)entry;
|
||||
if (e4.containsCustomData()) {
|
||||
if (entry.containsCustomData()) {
|
||||
hasCustomData = true;
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -22,8 +22,6 @@ package com.keepassdroid.database;
|
||||
import com.keepassdroid.database.iterator.EntrySearchStringIterator;
|
||||
import com.keepassdroid.database.security.ProtectedString;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.UUID;
|
||||
|
||||
public abstract class PwEntry<Parent extends PwGroup> extends PwNode<Parent> implements Cloneable {
|
||||
@@ -85,8 +83,8 @@ public abstract class PwEntry<Parent extends PwGroup> extends PwNode<Parent> imp
|
||||
this.uuid = uuid;
|
||||
}
|
||||
|
||||
public void startToDecodeReference(PwDatabase db) {}
|
||||
public void endToDecodeReference(PwDatabase db) {}
|
||||
public void startToManageFieldReferences(PwDatabase db) {}
|
||||
public void endToManageFieldReferences() {}
|
||||
|
||||
public abstract String getTitle();
|
||||
public abstract void setTitle(String title);
|
||||
@@ -130,37 +128,29 @@ public abstract class PwEntry<Parent extends PwGroup> extends PwNode<Parent> imp
|
||||
* Retrieve extra fields to show, key is the label, value is the value of field
|
||||
* @return Map of label/value
|
||||
*/
|
||||
public Map<String, String> getExtraFields() {
|
||||
return new HashMap<>();
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve extra protected fields to show, key is the label, value is the value protected of field
|
||||
* @return Map of label/value
|
||||
*/
|
||||
public Map<String, ProtectedString> getExtraProtectedFields() {
|
||||
return new HashMap<>();
|
||||
public ExtraFields getFields() {
|
||||
return new ExtraFields();
|
||||
}
|
||||
|
||||
/**
|
||||
* If entry contains extra fields
|
||||
* @return true if there is extra fields
|
||||
*/
|
||||
public boolean containsExtraFields() {
|
||||
return !getExtraProtectedFields().keySet().isEmpty();
|
||||
public boolean containsCustomFields() {
|
||||
return getFields().containsCustomFields();
|
||||
}
|
||||
|
||||
/**
|
||||
* Add an extra field to the list
|
||||
* Add an extra field to the list (standard or custom)
|
||||
* @param label Label of field, must be unique
|
||||
* @param value Value of field
|
||||
*/
|
||||
public void addField(String label, ProtectedString value) {}
|
||||
public void addExtraField(String label, ProtectedString value) {}
|
||||
|
||||
/**
|
||||
* Delete all extra fields
|
||||
* Delete all custom fields
|
||||
*/
|
||||
public void removeExtraFields() {}
|
||||
public void removeAllCustomFields() {}
|
||||
|
||||
/**
|
||||
* If it's a node with only meta information like Meta-info SYSTEM Database Color
|
||||
|
||||
@@ -97,7 +97,7 @@ public class PwEntryV3 extends PwEntry<PwGroupV3> {
|
||||
groupId = ((PwGroupIdV3) this.parent.getId()).getId(); // TODO remove
|
||||
}
|
||||
|
||||
protected void assignData(PwEntryV3 source) {
|
||||
protected void updateWith(PwEntryV3 source) {
|
||||
groupId = source.groupId;
|
||||
|
||||
title = source.title;
|
||||
@@ -254,11 +254,9 @@ public class PwEntryV3 extends PwEntry<PwGroupV3> {
|
||||
/**
|
||||
* fill byte array
|
||||
*/
|
||||
private static void fill(byte[] array, byte value)
|
||||
{
|
||||
private static void fill(byte[] array, byte value) {
|
||||
for (int i=0; i<array.length; i++)
|
||||
array[i] = value;
|
||||
return;
|
||||
}
|
||||
|
||||
/** Securely erase old password before copying new. */
|
||||
|
||||
@@ -26,7 +26,6 @@ import com.keepassdroid.utils.SprEngineV4;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Date;
|
||||
import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
|
||||
@@ -39,7 +38,7 @@ public class PwEntryV4 extends PwEntry<PwGroupV4> implements ITimeLogger {
|
||||
public static final String STR_NOTES = "Notes";
|
||||
|
||||
// To decode each field not serializable
|
||||
private transient PwDatabase mDatabase = null;
|
||||
private transient PwDatabaseV4 mDatabase = null;
|
||||
private transient boolean mDecodeRef = false;
|
||||
|
||||
private PwIconCustom customIcon = PwIconCustom.ZERO;
|
||||
@@ -47,7 +46,7 @@ public class PwEntryV4 extends PwEntry<PwGroupV4> implements ITimeLogger {
|
||||
private PwDate parentGroupLastMod = new PwDate();
|
||||
private Map<String, String> customData = new HashMap<>();
|
||||
|
||||
private HashMap<String, ProtectedString> fields = new HashMap<>();
|
||||
private ExtraFields fields = new ExtraFields();
|
||||
private HashMap<String, ProtectedBinary> binaries = new HashMap<>();
|
||||
private String foregroundColor = "";
|
||||
private String backgroupColor = "";
|
||||
@@ -67,7 +66,7 @@ public class PwEntryV4 extends PwEntry<PwGroupV4> implements ITimeLogger {
|
||||
construct(p);
|
||||
}
|
||||
|
||||
public void assign(PwEntryV4 source) {
|
||||
public void updateWith(PwEntryV4 source) {
|
||||
super.assign(source);
|
||||
customIcon = source.customIcon;
|
||||
usageCount = source.usageCount;
|
||||
@@ -99,9 +98,9 @@ public class PwEntryV4 extends PwEntry<PwGroupV4> implements ITimeLogger {
|
||||
newEntry.customIcon = new PwIconCustom(this.customIcon);
|
||||
// newEntry.usageCount stay the same in copy
|
||||
newEntry.parentGroupLastMod = this.parentGroupLastMod.clone();
|
||||
// TODO customData make copy from hashmap
|
||||
|
||||
newEntry.fields = (HashMap<String, ProtectedString>) this.fields.clone();
|
||||
newEntry.fields = this.fields.clone();
|
||||
// TODO customData make copy from hashmap
|
||||
newEntry.binaries = (HashMap<String, ProtectedBinary>) this.binaries.clone();
|
||||
// newEntry.foregroundColor stay the same in copy
|
||||
// newEntry.backgroupColor stay the same in copy
|
||||
@@ -117,19 +116,19 @@ public class PwEntryV4 extends PwEntry<PwGroupV4> implements ITimeLogger {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void startToDecodeReference(PwDatabase db) {
|
||||
this.mDatabase = db;
|
||||
public void startToManageFieldReferences(PwDatabase db) {
|
||||
this.mDatabase = (PwDatabaseV4) db;
|
||||
this.mDecodeRef = true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void endToDecodeReference(PwDatabase db) {
|
||||
public void endToManageFieldReferences() {
|
||||
this.mDatabase = null;
|
||||
this.mDecodeRef = false;
|
||||
}
|
||||
|
||||
private String decodeRefKey(boolean decodeRef, String key) {
|
||||
String text = getString(key);
|
||||
String text = getProtectedStringValue(key);
|
||||
if (decodeRef) {
|
||||
text = decodeRef(text, mDatabase);
|
||||
}
|
||||
@@ -159,55 +158,50 @@ public class PwEntryV4 extends PwEntry<PwGroupV4> implements ITimeLogger {
|
||||
|
||||
@Override
|
||||
public void setTitle(String title) {
|
||||
PwDatabaseV4 db = (PwDatabaseV4) mDatabase;
|
||||
PwDatabaseV4 db = mDatabase;
|
||||
boolean protect = db.getMemoryProtection().protectTitle;
|
||||
|
||||
setString(STR_TITLE, title, protect);
|
||||
setProtectedString(STR_TITLE, title, protect);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setUsername(String user) {
|
||||
PwDatabaseV4 db = (PwDatabaseV4) mDatabase;
|
||||
PwDatabaseV4 db = mDatabase;
|
||||
boolean protect = db.getMemoryProtection().protectUserName;
|
||||
|
||||
setString(STR_USERNAME, user, protect);
|
||||
setProtectedString(STR_USERNAME, user, protect);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setPassword(String pass) {
|
||||
PwDatabaseV4 db = (PwDatabaseV4) mDatabase;
|
||||
PwDatabaseV4 db = mDatabase;
|
||||
boolean protect = db.getMemoryProtection().protectPassword;
|
||||
|
||||
setString(STR_PASSWORD, pass, protect);
|
||||
setProtectedString(STR_PASSWORD, pass, protect);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setUrl(String url) {
|
||||
PwDatabaseV4 db = (PwDatabaseV4) mDatabase;
|
||||
PwDatabaseV4 db = mDatabase;
|
||||
boolean protect = db.getMemoryProtection().protectUrl;
|
||||
|
||||
setString(STR_URL, url, protect);
|
||||
setProtectedString(STR_URL, url, protect);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setNotes(String notes) {
|
||||
PwDatabaseV4 db = (PwDatabaseV4) mDatabase;
|
||||
PwDatabaseV4 db = mDatabase;
|
||||
boolean protect = db.getMemoryProtection().protectNotes;
|
||||
|
||||
setString(STR_NOTES, notes, protect);
|
||||
setProtectedString(STR_NOTES, notes, protect);
|
||||
}
|
||||
|
||||
public String getString(String key) {
|
||||
ProtectedString value = fields.get(key);
|
||||
|
||||
if ( value == null ) return "";
|
||||
|
||||
return value.toString();
|
||||
public String getProtectedStringValue(String key) {
|
||||
return fields.getProtectedStringValue(key);
|
||||
}
|
||||
|
||||
public void setString(String key, String value, boolean protect) {
|
||||
ProtectedString ps = new ProtectedString(protect, value);
|
||||
fields.put(key, ps);
|
||||
public void setProtectedString(String key, String value, boolean protect) {
|
||||
fields.putProtectedString(key, value, protect);
|
||||
}
|
||||
|
||||
public PwIconCustom getCustomIcon() {
|
||||
@@ -258,60 +252,17 @@ public class PwEntryV4 extends PwEntry<PwGroupV4> implements ITimeLogger {
|
||||
return true;
|
||||
}
|
||||
|
||||
public Map<String, ProtectedString> getFields() {
|
||||
public ExtraFields getFields() {
|
||||
return fields;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, ProtectedString> getExtraProtectedFields() {
|
||||
Map<String, ProtectedString> protectedFields = super.getExtraProtectedFields();
|
||||
if (fields.size() > 0) {
|
||||
for (Map.Entry<String, ProtectedString> pair : fields.entrySet()) {
|
||||
String key = pair.getKey();
|
||||
if (!PwEntryV4.isStandardField(key)) {
|
||||
protectedFields.put(key, pair.getValue());
|
||||
}
|
||||
}
|
||||
}
|
||||
return protectedFields;
|
||||
public void addExtraField(String label, ProtectedString value) {
|
||||
fields.putProtectedString(label, value);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, String> getExtraFields() {
|
||||
Map<String, String> extraFields = super.getExtraFields();
|
||||
SprEngineV4 spr = new SprEngineV4();
|
||||
// Display custom fields
|
||||
if (fields.size() > 0) {
|
||||
for (Map.Entry<String, ProtectedString> pair : fields.entrySet()) {
|
||||
String key = pair.getKey();
|
||||
// TODO Add hidden style for protection field
|
||||
if (!PwEntryV4.isStandardField(key)) {
|
||||
extraFields.put(key, spr.compile(pair.getValue().toString(), this, mDatabase));
|
||||
}
|
||||
}
|
||||
}
|
||||
return extraFields;
|
||||
}
|
||||
|
||||
private static boolean isStandardField(String key) {
|
||||
return key.equals(STR_TITLE) || key.equals(STR_USERNAME)
|
||||
|| key.equals(STR_PASSWORD) || key.equals(STR_URL)
|
||||
|| key.equals(STR_NOTES);
|
||||
}
|
||||
|
||||
public void addField(String label, ProtectedString value) {
|
||||
fields.put(label, value);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeExtraFields() {
|
||||
Iterator<Entry<String, ProtectedString>> iter = fields.entrySet().iterator();
|
||||
while (iter.hasNext()) {
|
||||
Map.Entry<String, ProtectedString> pair = iter.next();
|
||||
if (!PwEntryV4.isStandardField(pair.getKey())) {
|
||||
iter.remove();
|
||||
}
|
||||
}
|
||||
public void removeAllCustomFields() {
|
||||
fields.removeAllCustomFields();
|
||||
}
|
||||
|
||||
public HashMap<String, ProtectedBinary> getBinaries() {
|
||||
@@ -398,7 +349,7 @@ public class PwEntryV4 extends PwEntry<PwGroupV4> implements ITimeLogger {
|
||||
public long getSize() {
|
||||
long size = FIXED_LENGTH_SIZE;
|
||||
|
||||
for (Entry<String, ProtectedString> pair : fields.entrySet()) {
|
||||
for (Entry<String, ProtectedString> pair : fields.getListOfAllFields().entrySet()) {
|
||||
size += pair.getKey().length();
|
||||
size += pair.getValue().length();
|
||||
}
|
||||
|
||||
@@ -22,10 +22,10 @@ package com.keepassdroid.database.edit;
|
||||
import android.content.Context;
|
||||
|
||||
import com.keepassdroid.database.Database;
|
||||
import com.keepassdroid.database.PwDatabase;
|
||||
import com.keepassdroid.database.PwEntry;
|
||||
|
||||
public class AddEntry extends RunnableOnFinish {
|
||||
|
||||
protected Database mDb;
|
||||
private PwEntry mEntry;
|
||||
private Context ctx;
|
||||
@@ -33,16 +33,16 @@ public class AddEntry extends RunnableOnFinish {
|
||||
public AddEntry(Context ctx, Database db, PwEntry entry, OnFinish finish) {
|
||||
super(finish);
|
||||
|
||||
mDb = db;
|
||||
mEntry = entry;
|
||||
this.mDb = db;
|
||||
this.mEntry = entry;
|
||||
this.ctx = ctx;
|
||||
|
||||
mFinish = new AfterAdd(mFinish);
|
||||
this.mFinish = new AfterAdd(mFinish);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
mDb.pm.addEntryTo(mEntry, mEntry.getParent());
|
||||
mDb.addEntryTo(mEntry, mEntry.getParent());
|
||||
|
||||
// Commit to disk
|
||||
SaveDB save = new SaveDB(ctx, mDb, mFinish);
|
||||
@@ -57,9 +57,8 @@ public class AddEntry extends RunnableOnFinish {
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
PwDatabase pm = mDb.pm;
|
||||
if ( !mSuccess ) {
|
||||
pm.removeEntryFrom(mEntry, mEntry.getParent());
|
||||
mDb.removeEntryFrom(mEntry, mEntry.getParent());
|
||||
}
|
||||
// TODO if add entry callback
|
||||
super.run();
|
||||
|
||||
@@ -26,6 +26,7 @@ import com.keepassdroid.database.PwDatabase;
|
||||
import com.keepassdroid.database.PwGroup;
|
||||
|
||||
public class AddGroup extends RunnableOnFinish {
|
||||
|
||||
protected Database mDb;
|
||||
private String mName;
|
||||
private int mIconID;
|
||||
@@ -39,25 +40,25 @@ public class AddGroup extends RunnableOnFinish {
|
||||
boolean dontSave) {
|
||||
super(afterAddNode);
|
||||
|
||||
mDb = db;
|
||||
mName = name;
|
||||
mIconID = iconid;
|
||||
mParent = parent;
|
||||
mDontSave = dontSave;
|
||||
this.mDb = db;
|
||||
this.mName = name;
|
||||
this.mIconID = iconid;
|
||||
this.mParent = parent;
|
||||
this.mDontSave = dontSave;
|
||||
this.ctx = ctx;
|
||||
|
||||
mFinish = new AfterAdd(mFinish);
|
||||
this.mFinish = new AfterAdd(mFinish);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
PwDatabase pm = mDb.pm;
|
||||
PwDatabase pm = mDb.getPm();
|
||||
|
||||
// Generate new group
|
||||
mGroup = pm.createGroup();
|
||||
mGroup.initNewGroup(mName, pm.newGroupId());
|
||||
mGroup.setIcon(mDb.pm.getIconFactory().getIcon(mIconID));
|
||||
pm.addGroupTo(mGroup, mParent);
|
||||
mGroup.setIcon(pm.getIconFactory().getIcon(mIconID));
|
||||
mDb.addGroupTo(mGroup, mParent);
|
||||
|
||||
// Commit to disk
|
||||
SaveDB save = new SaveDB(ctx, mDb, mFinish, mDontSave);
|
||||
@@ -72,9 +73,8 @@ public class AddGroup extends RunnableOnFinish {
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
PwDatabase pm = mDb.pm;
|
||||
if ( !mSuccess ) {
|
||||
pm.removeGroupFrom(mGroup, mParent);
|
||||
mDb.removeGroupFrom(mGroup, mParent);
|
||||
}
|
||||
|
||||
// TODO Better callback
|
||||
|
||||
@@ -50,7 +50,7 @@ public class CreateDB extends RunnableOnFinish {
|
||||
pm.initNew(mFilename);
|
||||
|
||||
// Set Database state
|
||||
db.pm = pm;
|
||||
db.setPm(pm);
|
||||
db.mUri = UriUtil.parseDefaultFile(mFilename);
|
||||
db.setLoaded();
|
||||
App.clearShutdown();
|
||||
|
||||
@@ -22,7 +22,6 @@ package com.keepassdroid.database.edit;
|
||||
import android.content.Context;
|
||||
|
||||
import com.keepassdroid.database.Database;
|
||||
import com.keepassdroid.database.PwDatabase;
|
||||
import com.keepassdroid.database.PwEntry;
|
||||
import com.keepassdroid.database.PwGroup;
|
||||
|
||||
@@ -44,25 +43,24 @@ public class DeleteEntry extends RunnableOnFinish {
|
||||
public DeleteEntry(Context ctx, Database db, PwEntry entry, OnFinish finish, boolean dontSave) {
|
||||
super(finish);
|
||||
|
||||
mDb = db;
|
||||
mEntry = entry;
|
||||
mDontSave = dontSave;
|
||||
this.mDb = db;
|
||||
this.mEntry = entry;
|
||||
this.mDontSave = dontSave;
|
||||
this.ctx = ctx;
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
PwDatabase pm = mDb.pm;
|
||||
PwGroup parent = mEntry.getParent();
|
||||
|
||||
// Remove Entry from parent
|
||||
boolean recycle = pm.canRecycle(mEntry);
|
||||
boolean recycle = mDb.canRecycle(mEntry);
|
||||
if (recycle) {
|
||||
pm.recycle(mEntry);
|
||||
mDb.recycle(mEntry);
|
||||
}
|
||||
else {
|
||||
pm.deleteEntry(mEntry);
|
||||
mDb.deleteEntry(mEntry);
|
||||
}
|
||||
|
||||
// Save
|
||||
@@ -89,13 +87,12 @@ public class DeleteEntry extends RunnableOnFinish {
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
PwDatabase pm = mDb.pm;
|
||||
if ( !mSuccess ) {
|
||||
if (recycled) {
|
||||
pm.undoRecycle(mEntry, mParent);
|
||||
mDb.undoRecycle(mEntry, mParent);
|
||||
}
|
||||
else {
|
||||
pm.undoDeleteEntry(mEntry, mParent);
|
||||
mDb.undoDeleteEntry(mEntry, mParent);
|
||||
}
|
||||
}
|
||||
// TODO Callback after delete entry
|
||||
|
||||
@@ -23,7 +23,6 @@ import android.content.Context;
|
||||
|
||||
import com.keepassdroid.app.App;
|
||||
import com.keepassdroid.database.Database;
|
||||
import com.keepassdroid.database.PwDatabase;
|
||||
import com.keepassdroid.database.PwEntry;
|
||||
import com.keepassdroid.database.PwGroup;
|
||||
|
||||
@@ -34,25 +33,25 @@ public class DeleteGroup extends RunnableOnFinish {
|
||||
|
||||
private Context mContext;
|
||||
private Database mDb;
|
||||
private PwGroup mGroup;
|
||||
private PwGroup<PwGroup, PwGroup, PwEntry> mGroup;
|
||||
private boolean mDontSave;
|
||||
|
||||
public DeleteGroup(Context ctx, Database db, PwGroup group, OnFinish finish) {
|
||||
public DeleteGroup(Context ctx, Database db, PwGroup<PwGroup, PwGroup, PwEntry> group, OnFinish finish) {
|
||||
super(finish);
|
||||
setMembers(ctx, db, group, false);
|
||||
}
|
||||
|
||||
public DeleteGroup(Context ctx, Database db, PwGroup group, OnFinish finish, boolean dontSave) {
|
||||
public DeleteGroup(Context ctx, Database db, PwGroup<PwGroup, PwGroup, PwEntry> group, OnFinish finish, boolean dontSave) {
|
||||
super(finish);
|
||||
setMembers(ctx, db, group, dontSave);
|
||||
}
|
||||
|
||||
public DeleteGroup(Database db, PwGroup group, OnFinish finish, boolean dontSave) {
|
||||
public DeleteGroup(Database db, PwGroup<PwGroup, PwGroup, PwEntry> group, OnFinish finish, boolean dontSave) {
|
||||
super(finish);
|
||||
setMembers(null, db, group, dontSave);
|
||||
}
|
||||
|
||||
private void setMembers(Context ctx, Database db, PwGroup group, boolean dontSave) {
|
||||
private void setMembers(Context ctx, Database db, PwGroup<PwGroup, PwGroup, PwEntry> group, boolean dontSave) {
|
||||
mDb = db;
|
||||
mGroup = group;
|
||||
mContext = ctx;
|
||||
@@ -61,18 +60,17 @@ public class DeleteGroup extends RunnableOnFinish {
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
PwDatabase pm = mDb.pm;
|
||||
PwGroup parent = mGroup.getParent();
|
||||
|
||||
// Remove Group from parent
|
||||
boolean recycle = pm.canRecycle(mGroup);
|
||||
boolean recycle = mDb.canRecycle(mGroup);
|
||||
if (recycle) {
|
||||
pm.recycle(mGroup);
|
||||
mDb.recycle(mGroup);
|
||||
}
|
||||
else {
|
||||
// TODO tests
|
||||
// Remove child entries
|
||||
List<PwEntry> childEnt = new ArrayList<>(mGroup.getChildEntries());
|
||||
List<PwEntry> childEnt = new ArrayList<>(mGroup.getChildEntries()); // TODO new Methods
|
||||
for ( int i = 0; i < childEnt.size(); i++ ) {
|
||||
DeleteEntry task = new DeleteEntry(mContext, mDb, childEnt.get(i), null, true);
|
||||
task.run();
|
||||
@@ -84,11 +82,11 @@ public class DeleteGroup extends RunnableOnFinish {
|
||||
DeleteGroup task = new DeleteGroup(mContext, mDb, childGrp.get(i), null, true);
|
||||
task.run();
|
||||
}
|
||||
pm.deleteGroup(mGroup);
|
||||
mDb.deleteGroup(mGroup);
|
||||
|
||||
// Remove from PwDatabaseV3
|
||||
// TODO ENcapsulate
|
||||
mDb.pm.getGroups().remove(mGroup);
|
||||
mDb.getPm().getGroups().remove(mGroup);
|
||||
}
|
||||
|
||||
// Save
|
||||
@@ -114,10 +112,9 @@ public class DeleteGroup extends RunnableOnFinish {
|
||||
}
|
||||
|
||||
public void run() {
|
||||
PwDatabase pm = mDb.pm;
|
||||
if ( !mSuccess ) {
|
||||
if (recycled) {
|
||||
pm.undoRecycle(mGroup, mParent);
|
||||
mDb.undoRecycle(mGroup, mParent);
|
||||
}
|
||||
else {
|
||||
// Let's not bother recovering from a failure to save a deleted tree. It is too much work.
|
||||
|
||||
@@ -56,7 +56,7 @@ public class SetPassword extends RunnableOnFinish {
|
||||
}
|
||||
|
||||
public boolean validatePassword(Context ctx, DialogInterface.OnClickListener onclick) {
|
||||
if (!mDb.pm.validatePasswordEncoding(mPassword)) {
|
||||
if (!mDb.getPm().validatePasswordEncoding(mPassword)) {
|
||||
PasswordEncodingDialogHelper dialog = new PasswordEncodingDialogHelper();
|
||||
dialog.show(ctx, onclick, true);
|
||||
return false;
|
||||
@@ -67,7 +67,7 @@ public class SetPassword extends RunnableOnFinish {
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
PwDatabase pm = mDb.pm;
|
||||
PwDatabase pm = mDb.getPm();
|
||||
|
||||
byte[] backupKey = new byte[pm.getMasterKey().length];
|
||||
System.arraycopy(pm.getMasterKey(), 0, backupKey, 0, backupKey.length);
|
||||
@@ -105,8 +105,8 @@ public class SetPassword extends RunnableOnFinish {
|
||||
public void run() {
|
||||
if ( ! mSuccess ) {
|
||||
// Erase the current master key
|
||||
erase(mDb.pm.getMasterKey());
|
||||
mDb.pm.setMasterKey(mBackup);
|
||||
erase(mDb.getPm().getMasterKey());
|
||||
mDb.getPm().setMasterKey(mBackup);
|
||||
}
|
||||
|
||||
super.run();
|
||||
|
||||
@@ -25,6 +25,7 @@ import com.keepassdroid.database.Database;
|
||||
import com.keepassdroid.database.PwEntry;
|
||||
|
||||
public class UpdateEntry extends RunnableOnFinish {
|
||||
|
||||
private Database mDb;
|
||||
private PwEntry mOldE;
|
||||
private PwEntry mNewE;
|
||||
@@ -48,10 +49,9 @@ public class UpdateEntry extends RunnableOnFinish {
|
||||
@Override
|
||||
public void run() {
|
||||
// Update entry with new values
|
||||
mOldE = mNewE; // TODO Verify
|
||||
mDb.updateEntry(mOldE, mNewE);
|
||||
mOldE.touch(true, true);
|
||||
|
||||
|
||||
// Commit to disk
|
||||
SaveDB save = new SaveDB(ctx, mDb, mFinish);
|
||||
save.run();
|
||||
@@ -69,7 +69,7 @@ public class UpdateEntry extends RunnableOnFinish {
|
||||
public void run() {
|
||||
if ( !mSuccess ) {
|
||||
// If we fail to save, back out changes to global structure
|
||||
mOldE = mBackup; // TODO Verify
|
||||
mDb.updateEntry(mOldE, mBackup);
|
||||
}
|
||||
// TODO Callback for update entry
|
||||
super.run();
|
||||
|
||||
@@ -35,14 +35,13 @@ public class EntrySearchStringIteratorV4 extends EntrySearchStringIterator {
|
||||
|
||||
public EntrySearchStringIteratorV4(PwEntryV4 entry) {
|
||||
this.sp = SearchParametersV4.DEFAULT;
|
||||
setIterator = entry.getFields().entrySet().iterator();
|
||||
setIterator = entry.getFields().getListOfAllFields().entrySet().iterator();
|
||||
advance();
|
||||
|
||||
}
|
||||
|
||||
public EntrySearchStringIteratorV4(PwEntryV4 entry, SearchParametersV4 sp) {
|
||||
this.sp = sp;
|
||||
setIterator = entry.getFields().entrySet().iterator();
|
||||
setIterator = entry.getFields().getListOfAllFields().entrySet().iterator();
|
||||
advance();
|
||||
}
|
||||
|
||||
|
||||
@@ -628,7 +628,7 @@ public class ImporterV4 extends Importer {
|
||||
if ( ctxGroups.size() != 0 ) throw new IOException("Group list should be empty.");
|
||||
|
||||
db.setRootGroup(new PwGroupV4());
|
||||
ctxGroups.push((PwGroupV4)db.getRootGroup());
|
||||
ctxGroups.push(db.getRootGroup());
|
||||
ctxGroup = ctxGroups.peek();
|
||||
|
||||
return SwitchContext(ctx, KdbContext.Group, xpp);
|
||||
@@ -946,7 +946,7 @@ public class ImporterV4 extends Importer {
|
||||
} else if ( ctx == KdbContext.EntryTimes && name.equalsIgnoreCase(ElemTimes) ) {
|
||||
return KdbContext.Entry;
|
||||
} else if ( ctx == KdbContext.EntryString && name.equalsIgnoreCase(ElemString) ) {
|
||||
ctxEntry.addField(ctxStringName, ctxStringValue);
|
||||
ctxEntry.addExtraField(ctxStringName, ctxStringValue);
|
||||
ctxStringName = null;
|
||||
ctxStringValue = null;
|
||||
|
||||
|
||||
@@ -468,7 +468,7 @@ public class PwDbV4Output extends PwDbOutput {
|
||||
|
||||
writeList(ElemTimes, entry);
|
||||
|
||||
writeList(entry.getFields(), true);
|
||||
writeList(entry.getFields().getListOfAllFields(), true);
|
||||
writeList(entry.getBinaries());
|
||||
writeList(ElemAutoType, entry.getAutoType());
|
||||
|
||||
|
||||
@@ -42,12 +42,18 @@ public class ProtectedString implements Serializable {
|
||||
this(false, "");
|
||||
}
|
||||
|
||||
public ProtectedString(ProtectedString toCopy) {
|
||||
this.string = toCopy.string;
|
||||
this.protect = toCopy.protect;
|
||||
}
|
||||
|
||||
public ProtectedString(boolean enableProtection, String string) {
|
||||
protect = enableProtection;
|
||||
this.string = string;
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return string;
|
||||
}
|
||||
|
||||
@@ -253,7 +253,7 @@ public class NestedSettingsFragment extends PreferenceFragmentCompat
|
||||
|
||||
Database db = App.getDB();
|
||||
if (db.Loaded()) {
|
||||
if (db.pm.algorithmSettingsEnabled()) {
|
||||
if (db.getPm().algorithmSettingsEnabled()) {
|
||||
|
||||
Preference roundPref = findPreference(getString(R.string.rounds_key));
|
||||
roundPref.setEnabled(true);
|
||||
@@ -271,11 +271,11 @@ public class NestedSettingsFragment extends PreferenceFragmentCompat
|
||||
setAlgorithm(db, algorithmPref);
|
||||
}
|
||||
|
||||
if (db.pm.isRecycleBinAvailable()) {
|
||||
if (db.isRecycleBinAvailabledAndEnabled()) {
|
||||
SwitchPreference recycleBinPref = (SwitchPreference) findPreference(getString(R.string.recycle_bin_key));
|
||||
// TODO Recycle
|
||||
//recycleBinPref.setEnabled(true);
|
||||
recycleBinPref.setChecked(db.pm.isRecycleBinEnabled());
|
||||
recycleBinPref.setChecked(db.isRecycleBinAvailabledAndEnabled());
|
||||
}
|
||||
|
||||
} else {
|
||||
@@ -304,12 +304,12 @@ public class NestedSettingsFragment extends PreferenceFragmentCompat
|
||||
}
|
||||
|
||||
private void setRounds(Database db, Preference rounds) {
|
||||
rounds.setSummary(Long.toString(db.pm.getNumRounds()));
|
||||
rounds.setSummary(Long.toString(db.getPm().getNumRounds()));
|
||||
}
|
||||
|
||||
private void setAlgorithm(Database db, Preference algorithm) {
|
||||
int resId;
|
||||
if ( db.pm.getEncryptionAlgorithm() == PwEncryptionAlgorithm.Rjindal ) {
|
||||
if ( db.getPm().getEncryptionAlgorithm() == PwEncryptionAlgorithm.Rjindal ) {
|
||||
resId = R.string.rijndael;
|
||||
} else {
|
||||
resId = R.string.twofish;
|
||||
|
||||
@@ -70,11 +70,11 @@ public class RoundsPreferenceDialogFragmentCompat extends PreferenceDialogFragme
|
||||
protected void onBindDialogView(View view) {
|
||||
super.onBindDialogView(view);
|
||||
|
||||
mRoundsView = (TextView) view.findViewById(R.id.rounds);
|
||||
mRoundsView = view.findViewById(R.id.rounds);
|
||||
|
||||
// Get the time from the related Preference
|
||||
Database db = App.getDB();
|
||||
mPM = db.pm;
|
||||
mPM = db.getPm();
|
||||
long numRounds = mPM.getNumRounds();
|
||||
|
||||
DialogPreference preference = getPreference();
|
||||
@@ -98,9 +98,7 @@ public class RoundsPreferenceDialogFragmentCompat extends PreferenceDialogFragme
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
if ( mSuccess ) {
|
||||
|
||||
} else {
|
||||
if (!mSuccess) {
|
||||
displayMessage(mCtx);
|
||||
mPM.setNumRounds(mOldRounds);
|
||||
}
|
||||
|
||||
@@ -26,6 +26,7 @@ import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
public class SprContextV4 implements Cloneable {
|
||||
|
||||
public PwDatabaseV4 db;
|
||||
public PwEntryV4 entry;
|
||||
public Map<String, String> refsCache = new HashMap<>();
|
||||
|
||||
Reference in New Issue
Block a user