Refactor Database, Add Type parameters, Refactor ExtraFields

This commit is contained in:
J-Jamet
2018-03-29 00:35:25 +02:00
parent 304a5e946d
commit 94ed03ce35
29 changed files with 585 additions and 284 deletions

View File

@@ -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));

View File

@@ -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());
}

View File

@@ -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

View File

@@ -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

View File

@@ -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) {

View File

@@ -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)

View File

@@ -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);

View File

@@ -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));

View 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;
}
}

View File

@@ -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);
}

View File

@@ -226,7 +226,6 @@ public class PwDatabaseV3 extends PwDatabase<PwGroupV3, PwEntryV3> {
grp.setParent(currentGroup);
constructTree(currentGroup.getChildGroupAt(i));
}
return;
}
/*

View File

@@ -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;
}

View File

@@ -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

View File

@@ -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. */

View File

@@ -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();
}

View File

@@ -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();

View File

@@ -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

View File

@@ -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();

View File

@@ -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

View File

@@ -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.

View File

@@ -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();

View File

@@ -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();

View File

@@ -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();
}

View File

@@ -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;

View File

@@ -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());

View File

@@ -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;
}

View File

@@ -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;

View File

@@ -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);
}

View File

@@ -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<>();