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.setIcon(new PwIconStandard(5));
entry.setOverrideURL("override"); entry.setOverrideURL("override");
entry.setParent(new PwGroupV4()); entry.setParent(new PwGroupV4());
entry.addField("key2", new ProtectedString(false, "value2")); entry.addExtraField("key2", new ProtectedString(false, "value2"));
entry.setUrl("http://localhost"); entry.setUrl("http://localhost");
entry.setUUID(UUID.randomUUID()); entry.setUUID(UUID.randomUUID());
PwEntryV4 target = new PwEntryV4(); 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 /* This test is not so useful now that I am not implementing value equality for Entries
assertTrue("Entries do not match.", entry.equals(target)); assertTrue("Entries do not match.", entry.equals(target));

View File

@@ -32,7 +32,7 @@ public class EntryV4 extends TestCase {
db.setHistoryMaxItems(2); db.setHistoryMaxItems(2);
PwEntryV4 entry = new PwEntryV4(); PwEntryV4 entry = new PwEntryV4();
entry.startToDecodeReference(db); entry.startToManageFieldReferences(db);
entry.setTitle("Title1"); entry.setTitle("Title1");
entry.setUsername("User1"); entry.setUsername("User1");
entry.createBackup(db); entry.createBackup(db);
@@ -46,7 +46,7 @@ public class EntryV4 extends TestCase {
entry.createBackup(db); entry.createBackup(db);
PwEntryV4 backup = entry.getHistory().get(0); PwEntryV4 backup = entry.getHistory().get(0);
entry.endToDecodeReference(db); entry.endToManageFieldReferences();
assertEquals("Title2", backup.getTitle()); assertEquals("Title2", backup.getTitle());
assertEquals("User2", backup.getUsername()); assertEquals("User2", backup.getUsername());
} }

View File

@@ -37,9 +37,10 @@ import android.widget.Toast;
import com.keepassdroid.app.App; import com.keepassdroid.app.App;
import com.keepassdroid.database.Database; import com.keepassdroid.database.Database;
import com.keepassdroid.database.ExtraFields;
import com.keepassdroid.database.PwDatabase; import com.keepassdroid.database.PwDatabase;
import com.keepassdroid.database.PwEntry; 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.NotificationCopyingService;
import com.keepassdroid.notifications.NotificationField; import com.keepassdroid.notifications.NotificationField;
import com.keepassdroid.settings.PreferencesUtil; import com.keepassdroid.settings.PreferencesUtil;
@@ -53,7 +54,6 @@ import com.kunzisoft.keepass.R;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Date; import java.util.Date;
import java.util.Map;
import java.util.UUID; import java.util.UUID;
import static com.keepassdroid.settings.PreferencesUtil.isClipboardNotificationsEnable; import static com.keepassdroid.settings.PreferencesUtil.isClipboardNotificationsEnable;
@@ -108,7 +108,7 @@ public class EntryActivity extends LockingHideActivity {
// Get Entry from UUID // Get Entry from UUID
Intent i = getIntent(); Intent i = getIntent();
UUID uuid = Types.bytestoUUID(i.getByteArrayExtra(KEY_ENTRY)); UUID uuid = Types.bytestoUUID(i.getByteArrayExtra(KEY_ENTRY));
mEntry = db.pm.getEntryByUUIDId(uuid); mEntry = db.getPm().getEntryByUUIDId(uuid);
if (mEntry == null) { if (mEntry == null) {
Toast.makeText(this, R.string.entry_not_found, Toast.LENGTH_LONG).show(); Toast.makeText(this, R.string.entry_not_found, Toast.LENGTH_LONG).show();
finish(); finish();
@@ -147,14 +147,14 @@ public class EntryActivity extends LockingHideActivity {
fillData(); fillData();
invalidateOptionsMenu(); invalidateOptionsMenu();
// TODO Start decode mEntry.startToManageFieldReferences(App.getDB().getPm());
// If notifications enabled in settings // If notifications enabled in settings
// Don't if application timeout // Don't if application timeout
if (firstLaunchOfActivity && !App.isShutdown() && isClipboardNotificationsEnable(getApplicationContext())) { if (firstLaunchOfActivity && !App.isShutdown() && isClipboardNotificationsEnable(getApplicationContext())) {
if (mEntry.getUsername().length() > 0 if (mEntry.getUsername().length() > 0
|| (mEntry.getPassword().length() > 0 && PreferencesUtil.allowCopyPassword(this)) || (mEntry.getPassword().length() > 0 && PreferencesUtil.allowCopyPassword(this))
|| mEntry.containsExtraFields()) { || mEntry.containsCustomFields()) {
// username already copied, waiting for user's action before copy password. // username already copied, waiting for user's action before copy password.
Intent intent = new Intent(this, NotificationCopyingService.class); Intent intent = new Intent(this, NotificationCopyingService.class);
intent.setAction(NotificationCopyingService.ACTION_NEW_NOTIFICATION); intent.setAction(NotificationCopyingService.ACTION_NEW_NOTIFICATION);
@@ -181,17 +181,19 @@ public class EntryActivity extends LockingHideActivity {
// Add extra fields // Add extra fields
if (mEntry.allowExtraFields()) { if (mEntry.allowExtraFields()) {
try { try {
int anonymousFieldNumber = 0; mEntry.getFields().doActionToAllCustomProtectedField(new ExtraFields.ActionProtected() {
Map<String, String> map = mEntry.getExtraFields(); private int anonymousFieldNumber = 0;
for (Map.Entry<String, String> entry : mEntry.getExtraFields().entrySet()) { @Override
notificationFields.add( public void doAction(String key, ProtectedString value) {
new NotificationField( notificationFields.add(
NotificationField.NotificationFieldId.getAnonymousFieldId()[anonymousFieldNumber], new NotificationField(
entry.getValue(), NotificationField.NotificationFieldId.getAnonymousFieldId()[anonymousFieldNumber],
entry.getKey(), value.toString(),
getResources())); key,
anonymousFieldNumber++; getResources()));
} anonymousFieldNumber++;
}
});
} catch (ArrayIndexOutOfBoundsException e) { } catch (ArrayIndexOutOfBoundsException e) {
Log.w(TAG, "Only " + NotificationField.NotificationFieldId.getAnonymousFieldId().length + Log.w(TAG, "Only " + NotificationField.NotificationFieldId.getAnonymousFieldId().length +
" anonymous notifications are available"); " anonymous notifications are available");
@@ -202,7 +204,7 @@ public class EntryActivity extends LockingHideActivity {
startService(intent); startService(intent);
} }
// TODO end decode mEntry.endToManageFieldReferences();
} }
firstLaunchOfActivity = false; firstLaunchOfActivity = false;
} }
@@ -214,9 +216,9 @@ public class EntryActivity extends LockingHideActivity {
protected void fillData() { protected void fillData() {
Database db = App.getDB(); Database db = App.getDB();
PwDatabase pm = db.pm; PwDatabase pm = db.getPm();
mEntry.startToDecodeReference(pm); mEntry.startToManageFieldReferences(pm);
// Assign title // Assign title
populateTitle(db.drawFactory.getIconDrawable(getResources(), mEntry.getIcon()), populateTitle(db.drawFactory.getIconDrawable(getResources(), mEntry.getIcon()),
@@ -245,12 +247,15 @@ public class EntryActivity extends LockingHideActivity {
// Assign custom fields // Assign custom fields
if (mEntry.allowExtraFields()) { if (mEntry.allowExtraFields()) {
entryContentsView.clearExtraFields(); entryContentsView.clearExtraFields();
for (Map.Entry<String, String> field : mEntry.getExtraFields().entrySet()) {
final String label = field.getKey(); mEntry.getFields().doActionToAllCustomProtectedField((label, value) ->
final String value = field.getValue();
entryContentsView.addExtraField(label, value, view -> entryContentsView.addExtraField(label, value.toString(), view ->
clipboardHelper.timeoutCopyToClipboard(value, getString(R.string.copy_field, label))); clipboardHelper.timeoutCopyToClipboard(
} value.toString(),
getString(R.string.copy_field, label)
)
));
} }
// Assign dates // Assign dates
@@ -264,7 +269,7 @@ public class EntryActivity extends LockingHideActivity {
entryContentsView.assignExpiresDate(getString(R.string.never)); entryContentsView.assignExpiresDate(getString(R.string.never));
} }
mEntry.endToDecodeReference(pm); mEntry.endToManageFieldReferences();
} }
@Override @Override

View File

@@ -60,7 +60,6 @@ import com.keepassdroid.utils.Util;
import com.keepassdroid.view.EntryEditNewField; import com.keepassdroid.view.EntryEditNewField;
import com.kunzisoft.keepass.R; import com.kunzisoft.keepass.R;
import java.util.Map;
import java.util.UUID; import java.util.UUID;
public class EntryEditActivity extends LockingHideActivity 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 int ADD_OR_UPDATE_ENTRY_REQUEST_CODE = 7129;
public static final String ADD_OR_UPDATE_ENTRY_KEY = "ADD_OR_UPDATE_ENTRY_KEY"; 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 PwEntry mCallbackNewEntry;
protected boolean mIsNew; protected boolean mIsNew;
protected int mSelectedIconID = -1; protected int mSelectedIconID = -1;
@@ -153,7 +152,7 @@ public class EntryEditActivity extends LockingHideActivity
Intent intent = getIntent(); Intent intent = getIntent();
byte[] uuidBytes = intent.getByteArrayExtra(KEY_ENTRY); byte[] uuidBytes = intent.getByteArrayExtra(KEY_ENTRY);
PwDatabase pm = db.pm; PwDatabase pm = db.getPm();
if ( uuidBytes == null ) { if ( uuidBytes == null ) {
PwGroupId parentId = (PwGroupId) intent.getSerializableExtra(KEY_PARENT); PwGroupId parentId = (PwGroupId) intent.getSerializableExtra(KEY_PARENT);
PwGroup parent = pm.getGroupByGroupId(parentId); PwGroup parent = pm.getGroupByGroupId(parentId);
@@ -244,11 +243,11 @@ public class EntryEditActivity extends LockingHideActivity
} }
protected PwEntry populateNewEntry() { protected PwEntry populateNewEntry() {
PwDatabase db = App.getDB().pm; PwDatabase db = App.getDB().getPm();
PwEntry newEntry = mEntry.clone(); PwEntry newEntry = mEntry.clone();
newEntry.startToDecodeReference(db); newEntry.startToManageFieldReferences(db);
newEntry.createBackup(db); newEntry.createBackup(db);
@@ -261,7 +260,7 @@ public class EntryEditActivity extends LockingHideActivity
newEntry.setIcon(new PwIconStandard(mSelectedIconID)); newEntry.setIcon(new PwIconStandard(mSelectedIconID));
else { else {
if (mIsNew) { if (mIsNew) {
newEntry.setIcon(App.getDB().pm.getIconFactory().getFirstIcon()); newEntry.setIcon(App.getDB().getPm().getIconFactory().getFirstIcon());
} }
else { else {
// Keep previous icon, if no new one was selected // Keep previous icon, if no new one was selected
@@ -274,19 +273,19 @@ public class EntryEditActivity extends LockingHideActivity
newEntry.setPassword(entryPasswordView.getText().toString()); newEntry.setPassword(entryPasswordView.getText().toString());
if (newEntry.allowExtraFields()) { if (newEntry.allowExtraFields()) {
// Delete all new standard strings // Delete all extra strings
newEntry.removeExtraFields(); newEntry.removeAllCustomFields();
// Add extra fields from views // Add extra fields from views
for (int i = 0; i < entryExtraFieldsContainer.getChildCount(); i++) { for (int i = 0; i < entryExtraFieldsContainer.getChildCount(); i++) {
EntryEditNewField view = (EntryEditNewField) entryExtraFieldsContainer.getChildAt(i); EntryEditNewField view = (EntryEditNewField) entryExtraFieldsContainer.getChildAt(i);
String key = view.getLabel(); String key = view.getLabel();
String value = view.getValue(); String value = view.getValue();
boolean protect = view.isProtected(); 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; return newEntry;
} }
@@ -318,6 +317,8 @@ public class EntryEditActivity extends LockingHideActivity
ImageButton currIconButton = findViewById(R.id.icon_button); ImageButton currIconButton = findViewById(R.id.icon_button);
App.getDB().drawFactory.assignDrawableTo(currIconButton, getResources(), mEntry.getIcon()); App.getDB().drawFactory.assignDrawableTo(currIconButton, getResources(), mEntry.getIcon());
mEntry.startToManageFieldReferences(App.getDB().getPm());
entryTitleView.setText(mEntry.getTitle()); entryTitleView.setText(mEntry.getTitle());
entryUserNameView.setText(mEntry.getUsername()); entryUserNameView.setText(mEntry.getUsername());
entryUrlView.setText(mEntry.getUrl()); entryUrlView.setText(mEntry.getUrl());
@@ -336,13 +337,15 @@ public class EntryEditActivity extends LockingHideActivity
if (mEntry.allowExtraFields()) { if (mEntry.allowExtraFields()) {
LinearLayout container = findViewById(R.id.advanced_container); 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 entryEditNewField = new EntryEditNewField(EntryEditActivity.this);
entryEditNewField.setData(pair.getKey(), pair.getValue()); entryEditNewField.setData(key, value);
entryEditNewField.setFontVisibility(visibilityFontActivated); entryEditNewField.setFontVisibility(visibilityFontActivated);
container.addView(entryEditNewField); container.addView(entryEditNewField);
} });
} }
mEntry.endToManageFieldReferences();
} }
@Override @Override

View File

@@ -179,14 +179,14 @@ public class GroupActivity extends ListNodesActivity
PwGroup currentGroup; PwGroup currentGroup;
Database db = App.getDB(); Database db = App.getDB();
readOnly = db.readOnly; readOnly = db.readOnly;
PwGroup root = db.pm.getRootGroup(); PwGroup root = db.getPm().getRootGroup();
Log.w(TAG, "Creating tree view"); Log.w(TAG, "Creating tree view");
PwGroupId pwGroupId = (PwGroupId) getIntent().getSerializableExtra(GROUP_ID_KEY); PwGroupId pwGroupId = (PwGroupId) getIntent().getSerializableExtra(GROUP_ID_KEY);
if ( pwGroupId == null ) { if ( pwGroupId == null ) {
currentGroup = root; currentGroup = root;
} else { } else {
currentGroup = db.pm.getGroupByGroupId(pwGroupId); currentGroup = db.getPm().getGroupByGroupId(pwGroupId);
} }
if (currentGroup != null) { if (currentGroup != null) {

View File

@@ -39,6 +39,7 @@ import android.widget.TextView;
import com.keepassdroid.adapters.NodeAdapter; import com.keepassdroid.adapters.NodeAdapter;
import com.keepassdroid.app.App; import com.keepassdroid.app.App;
import com.keepassdroid.compat.EditorCompat; import com.keepassdroid.compat.EditorCompat;
import com.keepassdroid.database.Database;
import com.keepassdroid.database.PwDatabase; import com.keepassdroid.database.PwDatabase;
import com.keepassdroid.database.PwEntry; import com.keepassdroid.database.PwEntry;
import com.keepassdroid.database.PwGroup; import com.keepassdroid.database.PwGroup;
@@ -177,7 +178,7 @@ public abstract class ListNodesActivity extends LockingActivity
case R.id.menu_sort: case R.id.menu_sort:
SortDialogFragment sortDialogFragment; SortDialogFragment sortDialogFragment;
PwDatabase database = App.getDB().pm; PwDatabase database = App.getDB().getPm();
/* /*
// TODO Recycle bin bottom // TODO Recycle bin bottom
if (database.isRecycleBinAvailable() && database.isRecycleBinEnabled()) { if (database.isRecycleBinAvailable() && database.isRecycleBinEnabled()) {
@@ -294,8 +295,9 @@ public abstract class ListNodesActivity extends LockingActivity
if ( mSuccess) { if ( mSuccess) {
mAdapter.removeNode(pwNode); mAdapter.removeNode(pwNode);
PwGroup parent = pwNode.getParent(); PwGroup parent = pwNode.getParent();
PwDatabase database = App.getDB().pm; Database db = App.getDB();
if (database.isRecycleBinAvailable() && database.isRecycleBinEnabled()) { PwDatabase database = db.getPm();
if (db.isRecycleBinAvailabledAndEnabled()) {
PwGroup recycleBin = database.getRecycleBin(); PwGroup recycleBin = database.getRecycleBin();
// Add trash if it doesn't exists // Add trash if it doesn't exists
if (parent.equals(recycleBin) 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) { public void onCreateContextMenu(ContextMenu contextMenu, View view, ContextMenu.ContextMenuInfo contextMenuInfo) {
MenuItem clearMenu = contextMenu.add(Menu.NONE, MENU_OPEN, Menu.NONE, R.string.menu_open); MenuItem clearMenu = contextMenu.add(Menu.NONE, MENU_OPEN, Menu.NONE, R.string.menu_open);
clearMenu.setOnMenuItemClickListener(mOnMyActionClickListener); 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 // TODO make edit for group
// clearMenu = contextMenu.add(Menu.NONE, MENU_EDIT, Menu.NONE, R.string.menu_edit); // clearMenu = contextMenu.add(Menu.NONE, MENU_EDIT, Menu.NONE, R.string.menu_edit);
// clearMenu.setOnMenuItemClickListener(mOnMyActionClickListener); // clearMenu.setOnMenuItemClickListener(mOnMyActionClickListener);

View File

@@ -52,7 +52,9 @@ import java.io.SyncFailedException;
*/ */
public class Database { public class Database {
public PwDatabase pm; private static final String TAG = Database.class.getName();
private PwDatabase pm;
public Uri mUri; public Uri mUri;
public SearchDbHelper searchHelper; public SearchDbHelper searchHelper;
public boolean readOnly = false; public boolean readOnly = false;
@@ -62,6 +64,14 @@ public class Database {
private boolean loaded = false; private boolean loaded = false;
public PwDatabase getPm() {
return pm;
}
public void setPm(PwDatabase pm) {
this.pm = pm;
}
public boolean Loaded() { public boolean Loaded() {
return 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) { private long getFixRounds(Context ctx) {
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(ctx); SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(ctx);
return prefs.getLong(ctx.getString(R.string.roundsFix_key), ctx.getResources().getInteger(R.integer.roundsFix_default)); 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) { public static PwDatabase getNewDBInstance(String filename) {
// TODO other condition to create a database
if (isKDBExtension(filename)) { if (isKDBExtension(filename)) {
return new PwDatabaseV3(); return new PwDatabaseV3();
} else { } else {
@@ -284,7 +285,7 @@ public abstract class PwDatabase<PwGroupDB extends PwGroup<PwGroupDB, PwGroupDB,
public abstract List<PwGroupDB> getGroups(); public abstract List<PwGroupDB> getGroups();
public void addGroupTo(PwGroupDB newGroup, PwGroupDB parent) { protected void addGroupTo(PwGroupDB newGroup, PwGroupDB parent) {
// Add tree to parent tree // Add tree to parent tree
if ( parent == null ) { if ( parent == null ) {
parent = rootGroup; parent = rootGroup;
@@ -297,7 +298,7 @@ public abstract class PwDatabase<PwGroupDB extends PwGroup<PwGroupDB, PwGroupDB,
parent.touch(true, true); parent.touch(true, true);
} }
public void removeGroupFrom(PwGroupDB remove, PwGroupDB parent) { protected void removeGroupFrom(PwGroupDB remove, PwGroupDB parent) {
// Remove tree from parent tree // Remove tree from parent tree
if (parent != null) { if (parent != null) {
parent.removeChildGroup(remove); parent.removeChildGroup(remove);
@@ -339,7 +340,7 @@ public abstract class PwDatabase<PwGroupDB extends PwGroup<PwGroupDB, PwGroupDB,
return this.entries.get(id); return this.entries.get(id);
} }
public void addEntryTo(PwEntryDB newEntry, PwGroupDB parent) { protected void addEntryTo(PwEntryDB newEntry, PwGroupDB parent) {
// Add entry to parent // Add entry to parent
if (parent != null) { if (parent != null) {
parent.addChildEntry(newEntry); parent.addChildEntry(newEntry);
@@ -349,7 +350,7 @@ public abstract class PwDatabase<PwGroupDB extends PwGroup<PwGroupDB, PwGroupDB,
entries.put(newEntry.getUUID(), newEntry); entries.put(newEntry.getUUID(), newEntry);
} }
public void removeEntryFrom(PwEntryDB remove, PwGroupDB parent) { protected void removeEntryFrom(PwEntryDB remove, PwGroupDB parent) {
// Remove entry for parent // Remove entry for parent
if (parent != null) { if (parent != null) {
parent.removeChildEntry(remove); parent.removeChildEntry(remove);
@@ -359,7 +360,7 @@ public abstract class PwDatabase<PwGroupDB extends PwGroup<PwGroupDB, PwGroupDB,
public abstract boolean isBackup(PwGroupDB group); public abstract boolean isBackup(PwGroupDB group);
public void populateGlobals(PwGroupDB currentGroup) { protected void populateGlobals(PwGroupDB currentGroup) {
List<PwGroupDB> childGroups = currentGroup.getChildGroups(); List<PwGroupDB> childGroups = currentGroup.getChildGroups();
List<PwEntryDB> childEntries = currentGroup.getChildEntries(); 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 * Determine if RecycleBin is available or not for this version of database
* @return true if RecycleBin enable * @return true if RecycleBin enable
*/ */
public boolean isRecycleBinAvailable() { protected boolean isRecycleBinAvailable() {
return false; return false;
} }
@@ -388,7 +389,7 @@ public abstract class PwDatabase<PwGroupDB extends PwGroup<PwGroupDB, PwGroupDB,
* Determine if RecycleBin is enable or not * Determine if RecycleBin is enable or not
* @return true if RecycleBin enable, false if is not available or not enable * @return true if RecycleBin enable, false if is not available or not enable
*/ */
public boolean isRecycleBinEnabled() { protected boolean isRecycleBinEnabled() {
return false; return false;
} }
@@ -397,7 +398,7 @@ public abstract class PwDatabase<PwGroupDB extends PwGroup<PwGroupDB, PwGroupDB,
* @param group Group to remove * @param group Group to remove
* @return true if group can be recycle, false elsewhere * @return true if group can be recycle, false elsewhere
*/ */
public boolean canRecycle(PwGroupDB group) { protected boolean canRecycle(PwGroupDB group) {
return false; return false;
} }
@@ -406,36 +407,36 @@ public abstract class PwDatabase<PwGroupDB extends PwGroup<PwGroupDB, PwGroupDB,
* @param entry Entry to remove * @param entry Entry to remove
* @return true if entry can be recycle, false elsewhere * @return true if entry can be recycle, false elsewhere
*/ */
public boolean canRecycle(PwEntryDB entry) { protected boolean canRecycle(PwEntryDB entry) {
return false; return false;
} }
public void recycle(PwGroupDB group) { protected void recycle(PwGroupDB group) {
// Assume calls to this are protected by calling inRecyleBin // Assume calls to this are protected by calling inRecyleBin
throw new RuntimeException("Call not valid for .kdb databases."); 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 // Assume calls to this are protected by calling inRecyleBin
throw new RuntimeException("Call not valid for .kdb databases."); 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."); 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."); throw new RuntimeException("Call not valid for .kdb databases.");
} }
public void deleteGroup(PwGroupDB group) { protected void deleteGroup(PwGroupDB group) {
PwGroupDB parent = (PwGroupDB) group.getParent(); // TODO inference PwGroupDB parent = group.getParent(); // TODO inference
removeGroupFrom(group, parent); removeGroupFrom(group, parent);
parent.touch(false, true); parent.touch(false, true);
} }
public void deleteEntry(PwEntryDB entry) { protected void deleteEntry(PwEntryDB entry) {
PwGroupDB parent = (PwGroupDB) entry.getParent(); // TODO inference PwGroupDB parent = entry.getParent(); // TODO inference
removeEntryFrom(entry, parent); removeEntryFrom(entry, parent);
parent.touch(false, true); parent.touch(false, true);
} }

View File

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

View File

@@ -56,7 +56,7 @@ import javax.xml.parsers.DocumentBuilderFactory;
import biz.source_code.base64Coder.Base64Coder; 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; public static final int DEFAULT_ROUNDS = 6000;
private static final int DEFAULT_HISTORY_MAX_ITEMS = 10; // -1 unlimited private static final int DEFAULT_HISTORY_MAX_ITEMS = 10; // -1 unlimited
@@ -451,41 +451,41 @@ public class PwDatabaseV4 extends PwDatabase {
} }
@Override @Override
public List<PwGroup> getGroups() { public List<PwGroupV4> getGroups() {
List<PwGroup> list = new ArrayList<>(); List<PwGroupV4> list = new ArrayList<>();
PwGroupV4 root = (PwGroupV4) rootGroup; PwGroupV4 root = rootGroup;
buildChildGroupsRecursive(root, list); buildChildGroupsRecursive(root, list);
return list; return list;
} }
private static void buildChildGroupsRecursive(PwGroupV4 root, List<PwGroup> list) { private static void buildChildGroupsRecursive(PwGroupV4 root, List<PwGroupV4> list) {
list.add(root); list.add(root);
for ( int i = 0; i < root.numbersOfChildGroups(); i++) { for ( int i = 0; i < root.numbersOfChildGroups(); i++) {
PwGroupV4 child = (PwGroupV4) root.getChildGroupAt(i); PwGroupV4 child = root.getChildGroupAt(i);
buildChildGroupsRecursive(child, list); buildChildGroupsRecursive(child, list);
} }
} }
@Override @Override
public List<PwGroup> getGrpRoots() { public List<PwGroupV4> getGrpRoots() {
return rootGroup.getChildGroups(); return rootGroup.getChildGroups();
} }
@Override @Override
public List<PwEntry> getEntries() { public List<PwEntryV4> getEntries() {
List<PwEntry> list = new ArrayList<>(); List<PwEntryV4> list = new ArrayList<>();
PwGroupV4 root = (PwGroupV4) rootGroup; PwGroupV4 root = rootGroup;
buildChildEntriesRecursive(root, list); buildChildEntriesRecursive(root, list);
return 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++ ) { for ( int i = 0; i < root.numbersOfChildEntries(); i++ ) {
list.add(root.getChildEntryAt(i)); list.add(root.getChildEntryAt(i));
} }
for ( int i = 0; i < root.numbersOfChildGroups(); i++ ) { for ( int i = 0; i < root.numbersOfChildGroups(); i++ ) {
PwGroupV4 child = (PwGroupV4) root.getChildGroupAt(i); PwGroupV4 child = root.getChildGroupAt(i);
buildChildEntriesRecursive(child, list); buildChildEntriesRecursive(child, list);
} }
} }
@@ -513,7 +513,7 @@ public class PwDatabaseV4 extends PwDatabase {
@Override @Override
public PwGroupIdV4 newGroupId() { public PwGroupIdV4 newGroupId() {
PwGroupIdV4 id = new PwGroupIdV4(UUID_ZERO); PwGroupIdV4 id;
while (true) { while (true) {
id = new PwGroupIdV4(UUID.randomUUID()); id = new PwGroupIdV4(UUID.randomUUID());
@@ -530,7 +530,7 @@ public class PwDatabaseV4 extends PwDatabase {
} }
@Override @Override
public boolean isBackup(PwGroup group) { public boolean isBackup(PwGroupV4 group) {
if (!recycleBinEnabled) { if (!recycleBinEnabled) {
return false; return false;
} }
@@ -539,7 +539,7 @@ public class PwDatabaseV4 extends PwDatabase {
} }
@Override @Override
public void populateGlobals(PwGroup currentGroup) { public void populateGlobals(PwGroupV4 currentGroup) {
groups.put(rootGroup.getId(), rootGroup); groups.put(rootGroup.getId(), rootGroup);
super.populateGlobals(currentGroup); super.populateGlobals(currentGroup);
@@ -594,7 +594,7 @@ public class PwDatabaseV4 extends PwDatabase {
} }
@Override @Override
public boolean canRecycle(PwGroup group) { public boolean canRecycle(PwGroupV4 group) {
if (!recycleBinEnabled) { if (!recycleBinEnabled) {
return false; return false;
} }
@@ -603,23 +603,23 @@ public class PwDatabaseV4 extends PwDatabase {
} }
@Override @Override
public boolean canRecycle(PwEntry entry) { public boolean canRecycle(PwEntryV4 entry) {
if (!recycleBinEnabled) { if (!recycleBinEnabled) {
return false; return false;
} }
PwGroup parent = entry.getParent(); PwGroupV4 parent = entry.getParent();
return (parent != null) && canRecycle(parent); return (parent != null) && canRecycle(parent);
} }
@Override @Override
public void recycle(PwGroup group) { public void recycle(PwGroupV4 group) {
ensureRecycleBin(); ensureRecycleBin();
PwGroup parent = group.getParent(); PwGroupV4 parent = group.getParent();
removeGroupFrom(group, parent); removeGroupFrom(group, parent);
parent.touch(false, true); parent.touch(false, true);
PwGroup recycleBin = getRecycleBin(); PwGroupV4 recycleBin = getRecycleBin();
addGroupTo(group, recycleBin); addGroupTo(group, recycleBin);
group.touch(false, true); group.touch(false, true);
@@ -627,14 +627,14 @@ public class PwDatabaseV4 extends PwDatabase {
} }
@Override @Override
public void recycle(PwEntry entry) { public void recycle(PwEntryV4 entry) {
ensureRecycleBin(); ensureRecycleBin();
PwGroup parent = entry.getParent(); PwGroupV4 parent = entry.getParent();
removeEntryFrom(entry, parent); removeEntryFrom(entry, parent);
parent.touch(false, true); parent.touch(false, true);
PwGroup recycleBin = getRecycleBin(); PwGroupV4 recycleBin = getRecycleBin();
addEntryTo(entry, recycleBin); addEntryTo(entry, recycleBin);
entry.touch(false, true); entry.touch(false, true);
@@ -642,18 +642,18 @@ public class PwDatabaseV4 extends PwDatabase {
} }
@Override @Override
public void undoRecycle(PwGroup group, PwGroup origParent) { public void undoRecycle(PwGroupV4 group, PwGroupV4 origParent) {
PwGroup recycleBin = getRecycleBin(); PwGroupV4 recycleBin = getRecycleBin();
removeGroupFrom(group, recycleBin); removeGroupFrom(group, recycleBin);
addGroupTo(group, origParent); addGroupTo(group, origParent);
} }
@Override @Override
public void undoRecycle(PwEntry entry, PwGroup origParent) { public void undoRecycle(PwEntryV4 entry, PwGroupV4 origParent) {
PwGroup recycleBin = getRecycleBin(); PwGroupV4 recycleBin = getRecycleBin();
removeEntryFrom(entry, recycleBin); removeEntryFrom(entry, recycleBin);
addEntryTo(entry, origParent); addEntryTo(entry, origParent);
@@ -668,13 +668,13 @@ public class PwDatabaseV4 extends PwDatabase {
} }
@Override @Override
public void deleteEntry(PwEntry entry) { public void deleteEntry(PwEntryV4 entry) {
super.deleteEntry(entry); super.deleteEntry(entry);
deletedObjects.add(new PwDeletedObject(entry.getUUID())); deletedObjects.add(new PwDeletedObject(entry.getUUID()));
} }
@Override @Override
public void undoDeleteEntry(PwEntry entry, PwGroup origParent) { public void undoDeleteEntry(PwEntryV4 entry, PwGroupV4 origParent) {
super.undoDeleteEntry(entry, origParent); super.undoDeleteEntry(entry, origParent);
// TODO undo delete entry // TODO undo delete entry
deletedObjects.remove(entry); deletedObjects.remove(entry);
@@ -687,7 +687,7 @@ public class PwDatabaseV4 extends PwDatabase {
} }
PwGroupId recycleId = new PwGroupIdV4(recycleBinUUID); PwGroupId recycleId = new PwGroupIdV4(recycleBinUUID);
return (PwGroupV4) groups.get(recycleId); return groups.get(recycleId);
} }
public KdfParameters getKdfParameters() { public KdfParameters getKdfParameters() {
@@ -719,14 +719,12 @@ public class PwDatabaseV4 extends PwDatabase {
} }
@Override @Override
public boolean isGroupSearchable(PwGroup group, boolean omitBackup) { public boolean isGroupSearchable(PwGroupV4 group, boolean omitBackup) {
if (!super.isGroupSearchable(group, omitBackup)) { if (!super.isGroupSearchable(group, omitBackup)) {
return false; return false;
} }
PwGroupV4 g = (PwGroupV4) group; return group.isSearchingEnabled();
return g.isSearchingEnabled();
} }
@Override @Override
@@ -756,17 +754,16 @@ public class PwDatabaseV4 extends PwDatabase {
return filename.substring(0, lastExtDot); return filename.substring(0, lastExtDot);
} }
private class GroupHasCustomData extends GroupHandler<PwGroup> { private class GroupHasCustomData extends GroupHandler<PwGroupV4> {
public boolean hasCustomData = false; public boolean hasCustomData = false;
@Override @Override
public boolean operate(PwGroup group) { public boolean operate(PwGroupV4 group) {
if (group == null) { if (group == null) {
return true; return true;
} }
PwGroupV4 g4 = (PwGroupV4) group; if (group.containsCustomData()) {
if (g4.containsCustomData()) {
hasCustomData = true; hasCustomData = true;
return false; 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; public boolean hasCustomData = false;
@Override @Override
public boolean operate(PwEntry entry) { public boolean operate(PwEntryV4 entry) {
if (entry == null) { if (entry == null) {
return true; return true;
} }
PwEntryV4 e4 = (PwEntryV4)entry; if (entry.containsCustomData()) {
if (e4.containsCustomData()) {
hasCustomData = true; hasCustomData = true;
return false; return false;
} }

View File

@@ -22,8 +22,6 @@ package com.keepassdroid.database;
import com.keepassdroid.database.iterator.EntrySearchStringIterator; import com.keepassdroid.database.iterator.EntrySearchStringIterator;
import com.keepassdroid.database.security.ProtectedString; import com.keepassdroid.database.security.ProtectedString;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID; import java.util.UUID;
public abstract class PwEntry<Parent extends PwGroup> extends PwNode<Parent> implements Cloneable { 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; this.uuid = uuid;
} }
public void startToDecodeReference(PwDatabase db) {} public void startToManageFieldReferences(PwDatabase db) {}
public void endToDecodeReference(PwDatabase db) {} public void endToManageFieldReferences() {}
public abstract String getTitle(); public abstract String getTitle();
public abstract void setTitle(String title); 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 * Retrieve extra fields to show, key is the label, value is the value of field
* @return Map of label/value * @return Map of label/value
*/ */
public Map<String, String> getExtraFields() { public ExtraFields getFields() {
return new HashMap<>(); return new ExtraFields();
} }
/**
* 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<>();
}
/** /**
* If entry contains extra fields * If entry contains extra fields
* @return true if there is extra fields * @return true if there is extra fields
*/ */
public boolean containsExtraFields() { public boolean containsCustomFields() {
return !getExtraProtectedFields().keySet().isEmpty(); 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 label Label of field, must be unique
* @param value Value of field * @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 * 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 groupId = ((PwGroupIdV3) this.parent.getId()).getId(); // TODO remove
} }
protected void assignData(PwEntryV3 source) { protected void updateWith(PwEntryV3 source) {
groupId = source.groupId; groupId = source.groupId;
title = source.title; title = source.title;
@@ -254,11 +254,9 @@ public class PwEntryV3 extends PwEntry<PwGroupV3> {
/** /**
* fill byte array * 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++) for (int i=0; i<array.length; i++)
array[i] = value; array[i] = value;
return;
} }
/** Securely erase old password before copying new. */ /** 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.ArrayList;
import java.util.Date; import java.util.Date;
import java.util.HashMap; import java.util.HashMap;
import java.util.Iterator;
import java.util.Map; import java.util.Map;
import java.util.Map.Entry; import java.util.Map.Entry;
@@ -39,7 +38,7 @@ public class PwEntryV4 extends PwEntry<PwGroupV4> implements ITimeLogger {
public static final String STR_NOTES = "Notes"; public static final String STR_NOTES = "Notes";
// To decode each field not serializable // To decode each field not serializable
private transient PwDatabase mDatabase = null; private transient PwDatabaseV4 mDatabase = null;
private transient boolean mDecodeRef = false; private transient boolean mDecodeRef = false;
private PwIconCustom customIcon = PwIconCustom.ZERO; private PwIconCustom customIcon = PwIconCustom.ZERO;
@@ -47,7 +46,7 @@ public class PwEntryV4 extends PwEntry<PwGroupV4> implements ITimeLogger {
private PwDate parentGroupLastMod = new PwDate(); private PwDate parentGroupLastMod = new PwDate();
private Map<String, String> customData = new HashMap<>(); 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 HashMap<String, ProtectedBinary> binaries = new HashMap<>();
private String foregroundColor = ""; private String foregroundColor = "";
private String backgroupColor = ""; private String backgroupColor = "";
@@ -67,7 +66,7 @@ public class PwEntryV4 extends PwEntry<PwGroupV4> implements ITimeLogger {
construct(p); construct(p);
} }
public void assign(PwEntryV4 source) { public void updateWith(PwEntryV4 source) {
super.assign(source); super.assign(source);
customIcon = source.customIcon; customIcon = source.customIcon;
usageCount = source.usageCount; usageCount = source.usageCount;
@@ -99,9 +98,9 @@ public class PwEntryV4 extends PwEntry<PwGroupV4> implements ITimeLogger {
newEntry.customIcon = new PwIconCustom(this.customIcon); newEntry.customIcon = new PwIconCustom(this.customIcon);
// newEntry.usageCount stay the same in copy // newEntry.usageCount stay the same in copy
newEntry.parentGroupLastMod = this.parentGroupLastMod.clone(); 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.binaries = (HashMap<String, ProtectedBinary>) this.binaries.clone();
// newEntry.foregroundColor stay the same in copy // newEntry.foregroundColor stay the same in copy
// newEntry.backgroupColor 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 @Override
public void startToDecodeReference(PwDatabase db) { public void startToManageFieldReferences(PwDatabase db) {
this.mDatabase = db; this.mDatabase = (PwDatabaseV4) db;
this.mDecodeRef = true; this.mDecodeRef = true;
} }
@Override @Override
public void endToDecodeReference(PwDatabase db) { public void endToManageFieldReferences() {
this.mDatabase = null; this.mDatabase = null;
this.mDecodeRef = false; this.mDecodeRef = false;
} }
private String decodeRefKey(boolean decodeRef, String key) { private String decodeRefKey(boolean decodeRef, String key) {
String text = getString(key); String text = getProtectedStringValue(key);
if (decodeRef) { if (decodeRef) {
text = decodeRef(text, mDatabase); text = decodeRef(text, mDatabase);
} }
@@ -159,55 +158,50 @@ public class PwEntryV4 extends PwEntry<PwGroupV4> implements ITimeLogger {
@Override @Override
public void setTitle(String title) { public void setTitle(String title) {
PwDatabaseV4 db = (PwDatabaseV4) mDatabase; PwDatabaseV4 db = mDatabase;
boolean protect = db.getMemoryProtection().protectTitle; boolean protect = db.getMemoryProtection().protectTitle;
setString(STR_TITLE, title, protect); setProtectedString(STR_TITLE, title, protect);
} }
@Override @Override
public void setUsername(String user) { public void setUsername(String user) {
PwDatabaseV4 db = (PwDatabaseV4) mDatabase; PwDatabaseV4 db = mDatabase;
boolean protect = db.getMemoryProtection().protectUserName; boolean protect = db.getMemoryProtection().protectUserName;
setString(STR_USERNAME, user, protect); setProtectedString(STR_USERNAME, user, protect);
} }
@Override @Override
public void setPassword(String pass) { public void setPassword(String pass) {
PwDatabaseV4 db = (PwDatabaseV4) mDatabase; PwDatabaseV4 db = mDatabase;
boolean protect = db.getMemoryProtection().protectPassword; boolean protect = db.getMemoryProtection().protectPassword;
setString(STR_PASSWORD, pass, protect); setProtectedString(STR_PASSWORD, pass, protect);
} }
@Override @Override
public void setUrl(String url) { public void setUrl(String url) {
PwDatabaseV4 db = (PwDatabaseV4) mDatabase; PwDatabaseV4 db = mDatabase;
boolean protect = db.getMemoryProtection().protectUrl; boolean protect = db.getMemoryProtection().protectUrl;
setString(STR_URL, url, protect); setProtectedString(STR_URL, url, protect);
} }
@Override @Override
public void setNotes(String notes) { public void setNotes(String notes) {
PwDatabaseV4 db = (PwDatabaseV4) mDatabase; PwDatabaseV4 db = mDatabase;
boolean protect = db.getMemoryProtection().protectNotes; boolean protect = db.getMemoryProtection().protectNotes;
setString(STR_NOTES, notes, protect); setProtectedString(STR_NOTES, notes, protect);
} }
public String getString(String key) { public String getProtectedStringValue(String key) {
ProtectedString value = fields.get(key); return fields.getProtectedStringValue(key);
if ( value == null ) return "";
return value.toString();
} }
public void setString(String key, String value, boolean protect) { public void setProtectedString(String key, String value, boolean protect) {
ProtectedString ps = new ProtectedString(protect, value); fields.putProtectedString(key, value, protect);
fields.put(key, ps);
} }
public PwIconCustom getCustomIcon() { public PwIconCustom getCustomIcon() {
@@ -258,60 +252,17 @@ public class PwEntryV4 extends PwEntry<PwGroupV4> implements ITimeLogger {
return true; return true;
} }
public Map<String, ProtectedString> getFields() { public ExtraFields getFields() {
return fields; return fields;
} }
@Override public void addExtraField(String label, ProtectedString value) {
public Map<String, ProtectedString> getExtraProtectedFields() { fields.putProtectedString(label, value);
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;
} }
@Override @Override
public Map<String, String> getExtraFields() { public void removeAllCustomFields() {
Map<String, String> extraFields = super.getExtraFields(); fields.removeAllCustomFields();
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 HashMap<String, ProtectedBinary> getBinaries() { public HashMap<String, ProtectedBinary> getBinaries() {
@@ -397,8 +348,8 @@ public class PwEntryV4 extends PwEntry<PwGroupV4> implements ITimeLogger {
private static final long FIXED_LENGTH_SIZE = 128; // Approximate fixed length size private static final long FIXED_LENGTH_SIZE = 128; // Approximate fixed length size
public long getSize() { public long getSize() {
long size = FIXED_LENGTH_SIZE; 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.getKey().length();
size += pair.getValue().length(); size += pair.getValue().length();
} }

View File

@@ -22,10 +22,10 @@ package com.keepassdroid.database.edit;
import android.content.Context; import android.content.Context;
import com.keepassdroid.database.Database; import com.keepassdroid.database.Database;
import com.keepassdroid.database.PwDatabase;
import com.keepassdroid.database.PwEntry; import com.keepassdroid.database.PwEntry;
public class AddEntry extends RunnableOnFinish { public class AddEntry extends RunnableOnFinish {
protected Database mDb; protected Database mDb;
private PwEntry mEntry; private PwEntry mEntry;
private Context ctx; private Context ctx;
@@ -33,16 +33,16 @@ public class AddEntry extends RunnableOnFinish {
public AddEntry(Context ctx, Database db, PwEntry entry, OnFinish finish) { public AddEntry(Context ctx, Database db, PwEntry entry, OnFinish finish) {
super(finish); super(finish);
mDb = db; this.mDb = db;
mEntry = entry; this.mEntry = entry;
this.ctx = ctx; this.ctx = ctx;
mFinish = new AfterAdd(mFinish); this.mFinish = new AfterAdd(mFinish);
} }
@Override @Override
public void run() { public void run() {
mDb.pm.addEntryTo(mEntry, mEntry.getParent()); mDb.addEntryTo(mEntry, mEntry.getParent());
// Commit to disk // Commit to disk
SaveDB save = new SaveDB(ctx, mDb, mFinish); SaveDB save = new SaveDB(ctx, mDb, mFinish);
@@ -57,9 +57,8 @@ public class AddEntry extends RunnableOnFinish {
@Override @Override
public void run() { public void run() {
PwDatabase pm = mDb.pm;
if ( !mSuccess ) { if ( !mSuccess ) {
pm.removeEntryFrom(mEntry, mEntry.getParent()); mDb.removeEntryFrom(mEntry, mEntry.getParent());
} }
// TODO if add entry callback // TODO if add entry callback
super.run(); super.run();

View File

@@ -26,6 +26,7 @@ import com.keepassdroid.database.PwDatabase;
import com.keepassdroid.database.PwGroup; import com.keepassdroid.database.PwGroup;
public class AddGroup extends RunnableOnFinish { public class AddGroup extends RunnableOnFinish {
protected Database mDb; protected Database mDb;
private String mName; private String mName;
private int mIconID; private int mIconID;
@@ -39,25 +40,25 @@ public class AddGroup extends RunnableOnFinish {
boolean dontSave) { boolean dontSave) {
super(afterAddNode); super(afterAddNode);
mDb = db; this.mDb = db;
mName = name; this.mName = name;
mIconID = iconid; this.mIconID = iconid;
mParent = parent; this.mParent = parent;
mDontSave = dontSave; this.mDontSave = dontSave;
this.ctx = ctx; this.ctx = ctx;
mFinish = new AfterAdd(mFinish); this.mFinish = new AfterAdd(mFinish);
} }
@Override @Override
public void run() { public void run() {
PwDatabase pm = mDb.pm; PwDatabase pm = mDb.getPm();
// Generate new group // Generate new group
mGroup = pm.createGroup(); mGroup = pm.createGroup();
mGroup.initNewGroup(mName, pm.newGroupId()); mGroup.initNewGroup(mName, pm.newGroupId());
mGroup.setIcon(mDb.pm.getIconFactory().getIcon(mIconID)); mGroup.setIcon(pm.getIconFactory().getIcon(mIconID));
pm.addGroupTo(mGroup, mParent); mDb.addGroupTo(mGroup, mParent);
// Commit to disk // Commit to disk
SaveDB save = new SaveDB(ctx, mDb, mFinish, mDontSave); SaveDB save = new SaveDB(ctx, mDb, mFinish, mDontSave);
@@ -72,9 +73,8 @@ public class AddGroup extends RunnableOnFinish {
@Override @Override
public void run() { public void run() {
PwDatabase pm = mDb.pm;
if ( !mSuccess ) { if ( !mSuccess ) {
pm.removeGroupFrom(mGroup, mParent); mDb.removeGroupFrom(mGroup, mParent);
} }
// TODO Better callback // TODO Better callback

View File

@@ -50,7 +50,7 @@ public class CreateDB extends RunnableOnFinish {
pm.initNew(mFilename); pm.initNew(mFilename);
// Set Database state // Set Database state
db.pm = pm; db.setPm(pm);
db.mUri = UriUtil.parseDefaultFile(mFilename); db.mUri = UriUtil.parseDefaultFile(mFilename);
db.setLoaded(); db.setLoaded();
App.clearShutdown(); App.clearShutdown();

View File

@@ -22,7 +22,6 @@ package com.keepassdroid.database.edit;
import android.content.Context; import android.content.Context;
import com.keepassdroid.database.Database; import com.keepassdroid.database.Database;
import com.keepassdroid.database.PwDatabase;
import com.keepassdroid.database.PwEntry; import com.keepassdroid.database.PwEntry;
import com.keepassdroid.database.PwGroup; 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) { public DeleteEntry(Context ctx, Database db, PwEntry entry, OnFinish finish, boolean dontSave) {
super(finish); super(finish);
mDb = db; this.mDb = db;
mEntry = entry; this.mEntry = entry;
mDontSave = dontSave; this.mDontSave = dontSave;
this.ctx = ctx; this.ctx = ctx;
} }
@Override @Override
public void run() { public void run() {
PwDatabase pm = mDb.pm;
PwGroup parent = mEntry.getParent(); PwGroup parent = mEntry.getParent();
// Remove Entry from parent // Remove Entry from parent
boolean recycle = pm.canRecycle(mEntry); boolean recycle = mDb.canRecycle(mEntry);
if (recycle) { if (recycle) {
pm.recycle(mEntry); mDb.recycle(mEntry);
} }
else { else {
pm.deleteEntry(mEntry); mDb.deleteEntry(mEntry);
} }
// Save // Save
@@ -89,13 +87,12 @@ public class DeleteEntry extends RunnableOnFinish {
@Override @Override
public void run() { public void run() {
PwDatabase pm = mDb.pm;
if ( !mSuccess ) { if ( !mSuccess ) {
if (recycled) { if (recycled) {
pm.undoRecycle(mEntry, mParent); mDb.undoRecycle(mEntry, mParent);
} }
else { else {
pm.undoDeleteEntry(mEntry, mParent); mDb.undoDeleteEntry(mEntry, mParent);
} }
} }
// TODO Callback after delete entry // TODO Callback after delete entry

View File

@@ -23,7 +23,6 @@ import android.content.Context;
import com.keepassdroid.app.App; import com.keepassdroid.app.App;
import com.keepassdroid.database.Database; import com.keepassdroid.database.Database;
import com.keepassdroid.database.PwDatabase;
import com.keepassdroid.database.PwEntry; import com.keepassdroid.database.PwEntry;
import com.keepassdroid.database.PwGroup; import com.keepassdroid.database.PwGroup;
@@ -34,25 +33,25 @@ public class DeleteGroup extends RunnableOnFinish {
private Context mContext; private Context mContext;
private Database mDb; private Database mDb;
private PwGroup mGroup; private PwGroup<PwGroup, PwGroup, PwEntry> mGroup;
private boolean mDontSave; 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); super(finish);
setMembers(ctx, db, group, false); 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); super(finish);
setMembers(ctx, db, group, dontSave); 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); super(finish);
setMembers(null, db, group, dontSave); 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; mDb = db;
mGroup = group; mGroup = group;
mContext = ctx; mContext = ctx;
@@ -61,18 +60,17 @@ public class DeleteGroup extends RunnableOnFinish {
@Override @Override
public void run() { public void run() {
PwDatabase pm = mDb.pm;
PwGroup parent = mGroup.getParent(); PwGroup parent = mGroup.getParent();
// Remove Group from parent // Remove Group from parent
boolean recycle = pm.canRecycle(mGroup); boolean recycle = mDb.canRecycle(mGroup);
if (recycle) { if (recycle) {
pm.recycle(mGroup); mDb.recycle(mGroup);
} }
else { else {
// TODO tests // TODO tests
// Remove child entries // 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++ ) { for ( int i = 0; i < childEnt.size(); i++ ) {
DeleteEntry task = new DeleteEntry(mContext, mDb, childEnt.get(i), null, true); DeleteEntry task = new DeleteEntry(mContext, mDb, childEnt.get(i), null, true);
task.run(); task.run();
@@ -84,11 +82,11 @@ public class DeleteGroup extends RunnableOnFinish {
DeleteGroup task = new DeleteGroup(mContext, mDb, childGrp.get(i), null, true); DeleteGroup task = new DeleteGroup(mContext, mDb, childGrp.get(i), null, true);
task.run(); task.run();
} }
pm.deleteGroup(mGroup); mDb.deleteGroup(mGroup);
// Remove from PwDatabaseV3 // Remove from PwDatabaseV3
// TODO ENcapsulate // TODO ENcapsulate
mDb.pm.getGroups().remove(mGroup); mDb.getPm().getGroups().remove(mGroup);
} }
// Save // Save
@@ -114,10 +112,9 @@ public class DeleteGroup extends RunnableOnFinish {
} }
public void run() { public void run() {
PwDatabase pm = mDb.pm;
if ( !mSuccess ) { if ( !mSuccess ) {
if (recycled) { if (recycled) {
pm.undoRecycle(mGroup, mParent); mDb.undoRecycle(mGroup, mParent);
} }
else { else {
// Let's not bother recovering from a failure to save a deleted tree. It is too much work. // 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) { public boolean validatePassword(Context ctx, DialogInterface.OnClickListener onclick) {
if (!mDb.pm.validatePasswordEncoding(mPassword)) { if (!mDb.getPm().validatePasswordEncoding(mPassword)) {
PasswordEncodingDialogHelper dialog = new PasswordEncodingDialogHelper(); PasswordEncodingDialogHelper dialog = new PasswordEncodingDialogHelper();
dialog.show(ctx, onclick, true); dialog.show(ctx, onclick, true);
return false; return false;
@@ -67,7 +67,7 @@ public class SetPassword extends RunnableOnFinish {
@Override @Override
public void run() { public void run() {
PwDatabase pm = mDb.pm; PwDatabase pm = mDb.getPm();
byte[] backupKey = new byte[pm.getMasterKey().length]; byte[] backupKey = new byte[pm.getMasterKey().length];
System.arraycopy(pm.getMasterKey(), 0, backupKey, 0, backupKey.length); System.arraycopy(pm.getMasterKey(), 0, backupKey, 0, backupKey.length);
@@ -105,8 +105,8 @@ public class SetPassword extends RunnableOnFinish {
public void run() { public void run() {
if ( ! mSuccess ) { if ( ! mSuccess ) {
// Erase the current master key // Erase the current master key
erase(mDb.pm.getMasterKey()); erase(mDb.getPm().getMasterKey());
mDb.pm.setMasterKey(mBackup); mDb.getPm().setMasterKey(mBackup);
} }
super.run(); super.run();

View File

@@ -25,6 +25,7 @@ import com.keepassdroid.database.Database;
import com.keepassdroid.database.PwEntry; import com.keepassdroid.database.PwEntry;
public class UpdateEntry extends RunnableOnFinish { public class UpdateEntry extends RunnableOnFinish {
private Database mDb; private Database mDb;
private PwEntry mOldE; private PwEntry mOldE;
private PwEntry mNewE; private PwEntry mNewE;
@@ -48,10 +49,9 @@ public class UpdateEntry extends RunnableOnFinish {
@Override @Override
public void run() { public void run() {
// Update entry with new values // Update entry with new values
mOldE = mNewE; // TODO Verify mDb.updateEntry(mOldE, mNewE);
mOldE.touch(true, true); mOldE.touch(true, true);
// Commit to disk // Commit to disk
SaveDB save = new SaveDB(ctx, mDb, mFinish); SaveDB save = new SaveDB(ctx, mDb, mFinish);
save.run(); save.run();
@@ -69,7 +69,7 @@ public class UpdateEntry extends RunnableOnFinish {
public void run() { public void run() {
if ( !mSuccess ) { if ( !mSuccess ) {
// If we fail to save, back out changes to global structure // If we fail to save, back out changes to global structure
mOldE = mBackup; // TODO Verify mDb.updateEntry(mOldE, mBackup);
} }
// TODO Callback for update entry // TODO Callback for update entry
super.run(); super.run();

View File

@@ -35,14 +35,13 @@ public class EntrySearchStringIteratorV4 extends EntrySearchStringIterator {
public EntrySearchStringIteratorV4(PwEntryV4 entry) { public EntrySearchStringIteratorV4(PwEntryV4 entry) {
this.sp = SearchParametersV4.DEFAULT; this.sp = SearchParametersV4.DEFAULT;
setIterator = entry.getFields().entrySet().iterator(); setIterator = entry.getFields().getListOfAllFields().entrySet().iterator();
advance(); advance();
} }
public EntrySearchStringIteratorV4(PwEntryV4 entry, SearchParametersV4 sp) { public EntrySearchStringIteratorV4(PwEntryV4 entry, SearchParametersV4 sp) {
this.sp = sp; this.sp = sp;
setIterator = entry.getFields().entrySet().iterator(); setIterator = entry.getFields().getListOfAllFields().entrySet().iterator();
advance(); advance();
} }

View File

@@ -628,7 +628,7 @@ public class ImporterV4 extends Importer {
if ( ctxGroups.size() != 0 ) throw new IOException("Group list should be empty."); if ( ctxGroups.size() != 0 ) throw new IOException("Group list should be empty.");
db.setRootGroup(new PwGroupV4()); db.setRootGroup(new PwGroupV4());
ctxGroups.push((PwGroupV4)db.getRootGroup()); ctxGroups.push(db.getRootGroup());
ctxGroup = ctxGroups.peek(); ctxGroup = ctxGroups.peek();
return SwitchContext(ctx, KdbContext.Group, xpp); return SwitchContext(ctx, KdbContext.Group, xpp);
@@ -946,7 +946,7 @@ public class ImporterV4 extends Importer {
} else if ( ctx == KdbContext.EntryTimes && name.equalsIgnoreCase(ElemTimes) ) { } else if ( ctx == KdbContext.EntryTimes && name.equalsIgnoreCase(ElemTimes) ) {
return KdbContext.Entry; return KdbContext.Entry;
} else if ( ctx == KdbContext.EntryString && name.equalsIgnoreCase(ElemString) ) { } else if ( ctx == KdbContext.EntryString && name.equalsIgnoreCase(ElemString) ) {
ctxEntry.addField(ctxStringName, ctxStringValue); ctxEntry.addExtraField(ctxStringName, ctxStringValue);
ctxStringName = null; ctxStringName = null;
ctxStringValue = null; ctxStringValue = null;

View File

@@ -468,7 +468,7 @@ public class PwDbV4Output extends PwDbOutput {
writeList(ElemTimes, entry); writeList(ElemTimes, entry);
writeList(entry.getFields(), true); writeList(entry.getFields().getListOfAllFields(), true);
writeList(entry.getBinaries()); writeList(entry.getBinaries());
writeList(ElemAutoType, entry.getAutoType()); writeList(ElemAutoType, entry.getAutoType());

View File

@@ -41,13 +41,19 @@ public class ProtectedString implements Serializable {
public ProtectedString() { public ProtectedString() {
this(false, ""); this(false, "");
} }
public ProtectedString(ProtectedString toCopy) {
this.string = toCopy.string;
this.protect = toCopy.protect;
}
public ProtectedString(boolean enableProtection, String string) { public ProtectedString(boolean enableProtection, String string) {
protect = enableProtection; protect = enableProtection;
this.string = string; this.string = string;
} }
@Override
public String toString() { public String toString() {
return string; return string;
} }

View File

@@ -253,7 +253,7 @@ public class NestedSettingsFragment extends PreferenceFragmentCompat
Database db = App.getDB(); Database db = App.getDB();
if (db.Loaded()) { if (db.Loaded()) {
if (db.pm.algorithmSettingsEnabled()) { if (db.getPm().algorithmSettingsEnabled()) {
Preference roundPref = findPreference(getString(R.string.rounds_key)); Preference roundPref = findPreference(getString(R.string.rounds_key));
roundPref.setEnabled(true); roundPref.setEnabled(true);
@@ -271,11 +271,11 @@ public class NestedSettingsFragment extends PreferenceFragmentCompat
setAlgorithm(db, algorithmPref); setAlgorithm(db, algorithmPref);
} }
if (db.pm.isRecycleBinAvailable()) { if (db.isRecycleBinAvailabledAndEnabled()) {
SwitchPreference recycleBinPref = (SwitchPreference) findPreference(getString(R.string.recycle_bin_key)); SwitchPreference recycleBinPref = (SwitchPreference) findPreference(getString(R.string.recycle_bin_key));
// TODO Recycle // TODO Recycle
//recycleBinPref.setEnabled(true); //recycleBinPref.setEnabled(true);
recycleBinPref.setChecked(db.pm.isRecycleBinEnabled()); recycleBinPref.setChecked(db.isRecycleBinAvailabledAndEnabled());
} }
} else { } else {
@@ -304,12 +304,12 @@ public class NestedSettingsFragment extends PreferenceFragmentCompat
} }
private void setRounds(Database db, Preference rounds) { 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) { private void setAlgorithm(Database db, Preference algorithm) {
int resId; int resId;
if ( db.pm.getEncryptionAlgorithm() == PwEncryptionAlgorithm.Rjindal ) { if ( db.getPm().getEncryptionAlgorithm() == PwEncryptionAlgorithm.Rjindal ) {
resId = R.string.rijndael; resId = R.string.rijndael;
} else { } else {
resId = R.string.twofish; resId = R.string.twofish;

View File

@@ -70,11 +70,11 @@ public class RoundsPreferenceDialogFragmentCompat extends PreferenceDialogFragme
protected void onBindDialogView(View view) { protected void onBindDialogView(View view) {
super.onBindDialogView(view); super.onBindDialogView(view);
mRoundsView = (TextView) view.findViewById(R.id.rounds); mRoundsView = view.findViewById(R.id.rounds);
// Get the time from the related Preference // Get the time from the related Preference
Database db = App.getDB(); Database db = App.getDB();
mPM = db.pm; mPM = db.getPm();
long numRounds = mPM.getNumRounds(); long numRounds = mPM.getNumRounds();
DialogPreference preference = getPreference(); DialogPreference preference = getPreference();
@@ -98,9 +98,7 @@ public class RoundsPreferenceDialogFragmentCompat extends PreferenceDialogFragme
@Override @Override
public void run() { public void run() {
if ( mSuccess ) { if (!mSuccess) {
} else {
displayMessage(mCtx); displayMessage(mCtx);
mPM.setNumRounds(mOldRounds); mPM.setNumRounds(mOldRounds);
} }

View File

@@ -26,6 +26,7 @@ import java.util.HashMap;
import java.util.Map; import java.util.Map;
public class SprContextV4 implements Cloneable { public class SprContextV4 implements Cloneable {
public PwDatabaseV4 db; public PwDatabaseV4 db;
public PwEntryV4 entry; public PwEntryV4 entry;
public Map<String, String> refsCache = new HashMap<>(); public Map<String, String> refsCache = new HashMap<>();