mirror of
https://github.com/Kunzisoft/KeePassDX.git
synced 2025-12-04 15:49:33 +01:00
Add type parameter to PwObject
This commit is contained in:
@@ -39,6 +39,7 @@ 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;
|
||||
import com.keepassdroid.notifications.NotificationCopyingService;
|
||||
import com.keepassdroid.notifications.NotificationField;
|
||||
import com.keepassdroid.settings.PreferencesUtil;
|
||||
@@ -179,6 +180,7 @@ public class EntryActivity extends LockingHideActivity {
|
||||
if (mEntry.allowExtraFields()) {
|
||||
try {
|
||||
int anonymousFieldNumber = 0;
|
||||
Map<String, String> map = mEntry.getExtraFields();
|
||||
for (Map.Entry<String, String> entry : mEntry.getExtraFields().entrySet()) {
|
||||
notificationFields.add(
|
||||
new NotificationField(
|
||||
|
||||
@@ -76,7 +76,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 mEntry;
|
||||
protected PwEntry<PwGroup> mEntry;
|
||||
protected PwEntry mCallbackNewEntry;
|
||||
protected boolean mIsNew;
|
||||
protected int mSelectedIconID = -1;
|
||||
|
||||
@@ -51,6 +51,7 @@ import java.io.SyncFailedException;
|
||||
* @author bpellin
|
||||
*/
|
||||
public class Database {
|
||||
|
||||
public PwDatabase pm;
|
||||
public Uri mUri;
|
||||
public SearchDbHelper searchHelper;
|
||||
@@ -152,22 +153,27 @@ public class Database {
|
||||
if ( pm != null ) {
|
||||
PwGroup root = pm.getRootGroup();
|
||||
pm.populateGlobals(root);
|
||||
LoadData(ctx, pm, password, kfIs, status);
|
||||
loadData(ctx, pm, password);
|
||||
}
|
||||
loaded = true;
|
||||
}
|
||||
|
||||
public void LoadData(Context ctx, PwDatabase pm, String password, InputStream keyInputStream, UpdateStatus status) {
|
||||
if ( pm != null ) {
|
||||
passwordEncodingError = !pm.validatePasswordEncoding(password);
|
||||
public void loadData(Context ctx, PwDatabase pm, String password) {
|
||||
passwordEncodingError = !pm.validatePasswordEncoding(password);
|
||||
switch (pm.getVersion()) {
|
||||
case V3:
|
||||
searchHelper = new SearchDbHelper.SearchDbHelperV3(ctx);
|
||||
break;
|
||||
case V4:
|
||||
searchHelper = new SearchDbHelper.SearchDbHelperV4(ctx);
|
||||
break;
|
||||
}
|
||||
searchHelper = new SearchDbHelper(ctx);
|
||||
loaded = true;
|
||||
}
|
||||
|
||||
public PwGroup Search(String str) {
|
||||
if (searchHelper == null) { return null; }
|
||||
return searchHelper.search(this, str);
|
||||
return searchHelper.search(this.pm, str);
|
||||
}
|
||||
|
||||
public void SaveData(Context ctx) throws IOException, PwDbOutputException {
|
||||
|
||||
@@ -24,77 +24,23 @@ import com.keepassdroid.database.iterator.EntrySearchStringIterator;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
|
||||
public abstract class EntrySearchHandler extends EntryHandler<PwEntry> {
|
||||
private List<PwEntry> listStorage;
|
||||
private SearchParameters sp;
|
||||
private Date now;
|
||||
|
||||
public static EntrySearchHandler getInstance(PwGroup group, SearchParameters sp, List<PwEntry> listStorage) {
|
||||
if (group instanceof PwGroupV3) { // TODO WTF ?
|
||||
return new EntrySearchHandlerV4(sp, listStorage);
|
||||
} else if (group instanceof PwGroupV4) {
|
||||
return new EntrySearchHandlerV4(sp, listStorage);
|
||||
} else {
|
||||
throw new RuntimeException("Not implemented.");
|
||||
}
|
||||
}
|
||||
public abstract class EntrySearchHandler<T extends PwEntry> extends EntryHandler<T> {
|
||||
|
||||
protected EntrySearchHandler(SearchParameters sp, List<PwEntry> listStorage) {
|
||||
protected List<T> listStorage;
|
||||
protected SearchParameters sp;
|
||||
protected Date now;
|
||||
|
||||
protected EntrySearchHandler(SearchParameters sp, List<T> listStorage) {
|
||||
this.listStorage = listStorage;
|
||||
this.sp = sp;
|
||||
this.listStorage = listStorage;
|
||||
now = new Date();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean operate(PwEntry entry) {
|
||||
if (sp.respectEntrySearchingDisabled && !entry.isSearchingEnabled()) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (sp.excludeExpired && entry.expires() && now.after(entry.getExpiryTime().getDate())) {
|
||||
return true;
|
||||
}
|
||||
|
||||
String term = sp.searchString;
|
||||
if (sp.ignoreCase) {
|
||||
term = term.toLowerCase();
|
||||
}
|
||||
|
||||
if (searchStrings(entry, term)) {
|
||||
listStorage.add(entry);
|
||||
return true;
|
||||
}
|
||||
|
||||
if (sp.searchInGroupNames) {
|
||||
PwGroup parent = entry.getParent();
|
||||
if (parent != null) {
|
||||
String groupName = parent.getName();
|
||||
if (groupName != null) {
|
||||
if (sp.ignoreCase) {
|
||||
groupName = groupName.toLowerCase();
|
||||
}
|
||||
|
||||
if (groupName.contains(term)) {
|
||||
listStorage.add(entry);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (searchID(entry)) {
|
||||
listStorage.add(entry);
|
||||
return true;
|
||||
}
|
||||
|
||||
return true;
|
||||
this.now = new Date();
|
||||
}
|
||||
|
||||
protected boolean searchID(PwEntry entry) {
|
||||
return false;
|
||||
}
|
||||
|
||||
private boolean searchStrings(PwEntry entry, String term) {
|
||||
protected boolean searchStrings(PwEntry entry, String term) {
|
||||
EntrySearchStringIterator iter = EntrySearchStringIterator.getInstance(entry, sp);
|
||||
while (iter.hasNext()) {
|
||||
String str = iter.next();
|
||||
|
||||
@@ -22,19 +22,20 @@ package com.keepassdroid.database;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
|
||||
public class EntrySearchHandlerAll extends EntryHandler<PwEntry> {
|
||||
private List<PwEntry> listStorage;
|
||||
public class EntrySearchHandlerAll<T extends PwEntry> extends EntryHandler<T> {
|
||||
|
||||
private List<T> listStorage;
|
||||
private SearchParameters sp;
|
||||
private Date now;
|
||||
|
||||
public EntrySearchHandlerAll(SearchParameters sp, List<PwEntry> listStorage) {
|
||||
public EntrySearchHandlerAll(SearchParameters sp, List<T> listStorage) {
|
||||
this.sp = sp;
|
||||
this.listStorage = listStorage;
|
||||
now = new Date();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean operate(PwEntry entry) {
|
||||
public boolean operate(T entry) {
|
||||
if (sp.respectEntrySearchingDisabled && !entry.isSearchingEnabled()) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -25,14 +25,60 @@ import com.keepassdroid.utils.UuidUtil;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
|
||||
public class EntrySearchHandlerV4 extends EntrySearchHandler {
|
||||
public class EntrySearchHandlerV4 extends EntrySearchHandler<PwEntryV4> {
|
||||
|
||||
private SearchParametersV4 sp;
|
||||
|
||||
protected EntrySearchHandlerV4(SearchParameters sp, List<PwEntry> listStorage) {
|
||||
protected EntrySearchHandlerV4(SearchParameters sp, List<PwEntryV4> listStorage) {
|
||||
super(sp, listStorage);
|
||||
this.sp = (SearchParametersV4) sp;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean operate(PwEntryV4 entry) {
|
||||
if (sp.respectEntrySearchingDisabled && !entry.isSearchingEnabled()) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (sp.excludeExpired && entry.expires() && now.after(entry.getExpiryTime().getDate())) {
|
||||
return true;
|
||||
}
|
||||
|
||||
String term = sp.searchString;
|
||||
if (sp.ignoreCase) {
|
||||
term = term.toLowerCase();
|
||||
}
|
||||
|
||||
if (searchStrings(entry, term)) {
|
||||
listStorage.add(entry);
|
||||
return true;
|
||||
}
|
||||
|
||||
if (sp.searchInGroupNames) {
|
||||
PwGroup parent = entry.getParent();
|
||||
if (parent != null) {
|
||||
String groupName = parent.getName();
|
||||
if (groupName != null) {
|
||||
if (sp.ignoreCase) {
|
||||
groupName = groupName.toLowerCase();
|
||||
}
|
||||
|
||||
if (groupName.contains(term)) {
|
||||
listStorage.add(entry);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (searchID(entry)) {
|
||||
listStorage.add(entry);
|
||||
return true;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean searchID(PwEntry e) {
|
||||
PwEntryV4 entry = (PwEntryV4) e;
|
||||
|
||||
@@ -15,7 +15,7 @@ public class EntrySearchV4 {
|
||||
this.root = root;
|
||||
}
|
||||
|
||||
public void searchEntries(SearchParameters sp, List<PwEntry> listStorage) {
|
||||
public void searchEntries(SearchParameters sp, List<PwEntryV4> listStorage) {
|
||||
if (sp == null) { return; }
|
||||
if (listStorage == null) { return; }
|
||||
|
||||
@@ -30,9 +30,9 @@ public class EntrySearchV4 {
|
||||
Collections.sort(terms, stringLengthComparator);
|
||||
|
||||
String fullSearch = sp.searchString;
|
||||
List<PwEntry> pg = root.getChildEntries();
|
||||
List<PwEntryV4> pg = root.getChildEntries();
|
||||
for (int i = 0; i < terms.size(); i ++) {
|
||||
List<PwEntry> pgNew = new ArrayList<>();
|
||||
List<PwEntryV4> pgNew = new ArrayList<>();
|
||||
|
||||
sp.searchString = terms.get(i);
|
||||
|
||||
@@ -47,9 +47,9 @@ public class EntrySearchV4 {
|
||||
break;
|
||||
}
|
||||
|
||||
List<PwEntry> complement = new ArrayList<>();
|
||||
List<PwEntryV4> complement = new ArrayList<>();
|
||||
if (negate) {
|
||||
for (PwEntry entry: pg) {
|
||||
for (PwEntryV4 entry: pg) {
|
||||
if (!pgNew.contains(entry)) {
|
||||
complement.add(entry);
|
||||
}
|
||||
@@ -68,13 +68,13 @@ public class EntrySearchV4 {
|
||||
|
||||
}
|
||||
|
||||
private boolean searchEntriesSingle(SearchParameters spIn, List<PwEntry> listStorage) {
|
||||
private boolean searchEntriesSingle(SearchParameters spIn, List<PwEntryV4> listStorage) {
|
||||
SearchParameters sp = (SearchParameters) spIn.clone();
|
||||
EntryHandler<PwEntry> eh;
|
||||
EntryHandler<PwEntryV4> eh;
|
||||
if (sp.searchString.length() <= 0) {
|
||||
eh = new EntrySearchHandlerAll(sp, listStorage);
|
||||
eh = new EntrySearchHandlerAll<>(sp, listStorage);
|
||||
} else {
|
||||
eh = EntrySearchHandler.getInstance(root, sp, listStorage);
|
||||
eh = new EntrySearchHandlerV4(sp, listStorage);
|
||||
}
|
||||
return root.preOrderTraverseTree(null, eh);
|
||||
}
|
||||
|
||||
@@ -19,6 +19,13 @@
|
||||
*/
|
||||
package com.keepassdroid.database;
|
||||
|
||||
import com.keepassdroid.crypto.finalkey.FinalKey;
|
||||
import com.keepassdroid.crypto.finalkey.FinalKeyFactory;
|
||||
import com.keepassdroid.database.exception.InvalidKeyFileException;
|
||||
import com.keepassdroid.database.exception.KeyFileEmptyException;
|
||||
import com.keepassdroid.stream.NullOutputStream;
|
||||
import com.keepassdroid.utils.Util;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
@@ -32,14 +39,8 @@ import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.UUID;
|
||||
|
||||
import com.keepassdroid.crypto.finalkey.FinalKey;
|
||||
import com.keepassdroid.crypto.finalkey.FinalKeyFactory;
|
||||
import com.keepassdroid.database.exception.InvalidKeyFileException;
|
||||
import com.keepassdroid.database.exception.KeyFileEmptyException;
|
||||
import com.keepassdroid.stream.NullOutputStream;
|
||||
import com.keepassdroid.utils.Util;
|
||||
|
||||
public abstract class PwDatabase {
|
||||
public abstract class PwDatabase<PwGroupDB extends PwGroup<PwGroupDB, PwGroupDB, PwEntryDB>,
|
||||
PwEntryDB extends PwEntry<PwGroupDB>> {
|
||||
|
||||
public static final UUID UUID_ZERO = new UUID(0,0);
|
||||
|
||||
@@ -47,11 +48,11 @@ public abstract class PwDatabase {
|
||||
protected byte[] finalKey;
|
||||
|
||||
protected String name = "KeePass database";
|
||||
protected PwGroup rootGroup;
|
||||
protected PwGroupDB rootGroup;
|
||||
protected PwIconFactory iconFactory = new PwIconFactory();
|
||||
|
||||
protected Map<PwGroupId, PwGroup> groups = new HashMap<>();
|
||||
protected Map<UUID, PwEntry> entries = new HashMap<>();
|
||||
protected Map<PwGroupId, PwGroupDB> groups = new HashMap<>();
|
||||
protected Map<UUID, PwEntryDB> entries = new HashMap<>();
|
||||
|
||||
private static boolean isKDBExtension(String filename) {
|
||||
if (filename == null) { return false; }
|
||||
@@ -70,6 +71,8 @@ public abstract class PwDatabase {
|
||||
}
|
||||
}
|
||||
|
||||
public abstract PwVersion getVersion();
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
@@ -78,11 +81,11 @@ public abstract class PwDatabase {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public PwGroup getRootGroup() {
|
||||
public PwGroupDB getRootGroup() {
|
||||
return rootGroup;
|
||||
}
|
||||
|
||||
public void setRootGroup(PwGroup rootGroup) {
|
||||
public void setRootGroup(PwGroupDB rootGroup) {
|
||||
this.rootGroup = rootGroup;
|
||||
}
|
||||
|
||||
@@ -277,11 +280,11 @@ public abstract class PwDatabase {
|
||||
|
||||
public abstract PwEncryptionAlgorithm getEncryptionAlgorithm();
|
||||
|
||||
public abstract List<PwGroup> getGrpRoots();
|
||||
public abstract List<PwGroupDB> getGrpRoots();
|
||||
|
||||
public abstract List<PwGroup> getGroups();
|
||||
public abstract List<PwGroupDB> getGroups();
|
||||
|
||||
public void addGroupTo(PwGroup newGroup, PwGroup parent) {
|
||||
public void addGroupTo(PwGroupDB newGroup, PwGroupDB parent) {
|
||||
// Add tree to parent tree
|
||||
if ( parent == null ) {
|
||||
parent = rootGroup;
|
||||
@@ -294,7 +297,7 @@ public abstract class PwDatabase {
|
||||
parent.touch(true, true);
|
||||
}
|
||||
|
||||
public void removeGroupFrom(PwGroup remove, PwGroup parent) {
|
||||
public void removeGroupFrom(PwGroupDB remove, PwGroupDB parent) {
|
||||
// Remove tree from parent tree
|
||||
if (parent != null) {
|
||||
parent.removeChildGroup(remove);
|
||||
@@ -304,7 +307,7 @@ public abstract class PwDatabase {
|
||||
|
||||
public abstract PwGroupId newGroupId();
|
||||
|
||||
public PwGroup getGroupByGroupId(PwGroupId id) {
|
||||
public PwGroupDB getGroupByGroupId(PwGroupId id) {
|
||||
return this.groups.get(id);
|
||||
}
|
||||
|
||||
@@ -316,10 +319,10 @@ public abstract class PwDatabase {
|
||||
* @return True if the ID is used, false otherwise
|
||||
*/
|
||||
protected boolean isGroupIdUsed(PwGroupId id) {
|
||||
List<PwGroup> groups = getGroups();
|
||||
List<PwGroupDB> groups = getGroups();
|
||||
|
||||
for (int i = 0; i < groups.size(); i++) {
|
||||
PwGroup group =groups.get(i);
|
||||
PwGroupDB group =groups.get(i);
|
||||
if (group.getId().equals(id)) {
|
||||
return true;
|
||||
}
|
||||
@@ -328,15 +331,15 @@ public abstract class PwDatabase {
|
||||
return false;
|
||||
}
|
||||
|
||||
public abstract PwGroup createGroup();
|
||||
public abstract PwGroupDB createGroup();
|
||||
|
||||
public abstract List<PwEntry> getEntries();
|
||||
public abstract List<PwEntryDB> getEntries();
|
||||
|
||||
public PwEntry getEntryByUUIDId(UUID id) {
|
||||
public PwEntryDB getEntryByUUIDId(UUID id) {
|
||||
return this.entries.get(id);
|
||||
}
|
||||
|
||||
public void addEntryTo(PwEntry newEntry, PwGroup parent) {
|
||||
public void addEntryTo(PwEntryDB newEntry, PwGroupDB parent) {
|
||||
// Add entry to parent
|
||||
if (parent != null) {
|
||||
parent.addChildEntry(newEntry);
|
||||
@@ -346,7 +349,7 @@ public abstract class PwDatabase {
|
||||
entries.put(newEntry.getUUID(), newEntry);
|
||||
}
|
||||
|
||||
public void removeEntryFrom(PwEntry remove, PwGroup parent) {
|
||||
public void removeEntryFrom(PwEntryDB remove, PwGroupDB parent) {
|
||||
// Remove entry for parent
|
||||
if (parent != null) {
|
||||
parent.removeChildEntry(remove);
|
||||
@@ -354,20 +357,20 @@ public abstract class PwDatabase {
|
||||
entries.remove(remove.getUUID());
|
||||
}
|
||||
|
||||
public abstract boolean isBackup(PwGroup group);
|
||||
public abstract boolean isBackup(PwGroupDB group);
|
||||
|
||||
public void populateGlobals(PwGroup currentGroup) {
|
||||
public void populateGlobals(PwGroupDB currentGroup) {
|
||||
|
||||
List<PwGroup> childGroups = currentGroup.getChildGroups();
|
||||
List<PwEntry> childEntries = currentGroup.getChildEntries();
|
||||
List<PwGroupDB> childGroups = currentGroup.getChildGroups();
|
||||
List<PwEntryDB> childEntries = currentGroup.getChildEntries();
|
||||
|
||||
for (int i = 0; i < childEntries.size(); i++ ) {
|
||||
PwEntry cur = childEntries.get(i);
|
||||
PwEntryDB cur = childEntries.get(i);
|
||||
entries.put(cur.getUUID(), cur);
|
||||
}
|
||||
|
||||
for (int i = 0; i < childGroups.size(); i++ ) {
|
||||
PwGroup cur = childGroups.get(i);
|
||||
PwGroupDB cur = childGroups.get(i);
|
||||
groups.put(cur.getId(), cur);
|
||||
populateGlobals(cur);
|
||||
}
|
||||
@@ -394,7 +397,7 @@ public abstract class PwDatabase {
|
||||
* @param group Group to remove
|
||||
* @return true if group can be recycle, false elsewhere
|
||||
*/
|
||||
public boolean canRecycle(PwGroup group) {
|
||||
public boolean canRecycle(PwGroupDB group) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -403,54 +406,54 @@ public abstract class PwDatabase {
|
||||
* @param entry Entry to remove
|
||||
* @return true if entry can be recycle, false elsewhere
|
||||
*/
|
||||
public boolean canRecycle(PwEntry entry) {
|
||||
public boolean canRecycle(PwEntryDB entry) {
|
||||
return false;
|
||||
}
|
||||
|
||||
public void recycle(PwGroup group) {
|
||||
public 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(PwEntry entry) {
|
||||
public 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(PwGroup group, PwGroup origParent) {
|
||||
public void undoRecycle(PwGroupDB group, PwGroupDB origParent) {
|
||||
throw new RuntimeException("Call not valid for .kdb databases.");
|
||||
}
|
||||
|
||||
public void undoRecycle(PwEntry entry, PwGroup origParent) {
|
||||
public void undoRecycle(PwEntryDB entry, PwGroupDB origParent) {
|
||||
throw new RuntimeException("Call not valid for .kdb databases.");
|
||||
}
|
||||
|
||||
public void deleteGroup(PwGroup group) {
|
||||
PwGroup parent = group.getParent();
|
||||
public void deleteGroup(PwGroupDB group) {
|
||||
PwGroupDB parent = (PwGroupDB) group.getParent(); // TODO inference
|
||||
removeGroupFrom(group, parent);
|
||||
parent.touch(false, true);
|
||||
}
|
||||
|
||||
public void deleteEntry(PwEntry entry) {
|
||||
PwGroup parent = entry.getParent();
|
||||
public void deleteEntry(PwEntryDB entry) {
|
||||
PwGroupDB parent = (PwGroupDB) entry.getParent(); // TODO inference
|
||||
removeEntryFrom(entry, parent);
|
||||
parent.touch(false, true);
|
||||
}
|
||||
|
||||
// TODO Delete group
|
||||
public void undoDeleteGroup(PwGroup group, PwGroup origParent) {
|
||||
public void undoDeleteGroup(PwGroupDB group, PwGroupDB origParent) {
|
||||
addGroupTo(group, origParent);
|
||||
}
|
||||
|
||||
public void undoDeleteEntry(PwEntry entry, PwGroup origParent) {
|
||||
public void undoDeleteEntry(PwEntryDB entry, PwGroupDB origParent) {
|
||||
addEntryTo(entry, origParent);
|
||||
}
|
||||
|
||||
public PwGroup getRecycleBin() {
|
||||
public PwGroupDB getRecycleBin() {
|
||||
return null;
|
||||
}
|
||||
|
||||
public boolean isGroupSearchable(PwGroup group, boolean omitBackup) {
|
||||
public boolean isGroupSearchable(PwGroupDB group, boolean omitBackup) {
|
||||
return group != null;
|
||||
}
|
||||
|
||||
|
||||
@@ -46,33 +46,33 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
package com.keepassdroid.database;
|
||||
|
||||
// Java
|
||||
import com.keepassdroid.database.exception.InvalidKeyFileException;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Random;
|
||||
|
||||
import com.keepassdroid.database.exception.InvalidKeyFileException;
|
||||
|
||||
/**
|
||||
* @author Naomaru Itoi <nao@phoneid.org>
|
||||
* @author Bill Zwicky <wrzwicky@pobox.com>
|
||||
* @author Dominik Reichl <dominik.reichl@t-online.de>
|
||||
*/
|
||||
public class PwDatabaseV3 extends PwDatabase {
|
||||
public class PwDatabaseV3 extends PwDatabase<PwGroupV3, PwEntryV3> {
|
||||
|
||||
private static final int DEFAULT_ENCRYPTION_ROUNDS = 300;
|
||||
|
||||
// all entries
|
||||
private List<PwEntry> entries = new ArrayList<>();
|
||||
private List<PwEntryV3> entries = new ArrayList<>();
|
||||
// all groups
|
||||
private List<PwGroup> groups = new ArrayList<>();
|
||||
private List<PwGroupV3> groups = new ArrayList<>();
|
||||
// Algorithm used to encrypt the database
|
||||
private PwEncryptionAlgorithm algorithm;
|
||||
private int numKeyEncRounds;
|
||||
|
||||
private void initAndAddGroup(String name, int iconId, PwGroup parent) {
|
||||
PwGroup group = createGroup();
|
||||
private void initAndAddGroup(String name, int iconId, PwGroupV3 parent) {
|
||||
PwGroupV3 group = createGroup();
|
||||
group.initNewGroup(name, newGroupId());
|
||||
group.setIcon(iconFactory.getIcon(iconId));
|
||||
addGroupTo(group, parent);
|
||||
@@ -91,6 +91,11 @@ public class PwDatabaseV3 extends PwDatabase {
|
||||
initAndAddGroup("eMail", 19, rootGroup);
|
||||
}
|
||||
|
||||
@Override
|
||||
public PwVersion getVersion() {
|
||||
return PwVersion.V3;
|
||||
}
|
||||
|
||||
@Override
|
||||
public PwEncryptionAlgorithm getEncryptionAlgorithm() {
|
||||
return algorithm;
|
||||
@@ -109,15 +114,15 @@ public class PwDatabaseV3 extends PwDatabase {
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<PwGroup> getGroups() {
|
||||
public List<PwGroupV3> getGroups() {
|
||||
return groups;
|
||||
}
|
||||
|
||||
public void setGroups(List<PwGroup> grp) {
|
||||
public void setGroups(List<PwGroupV3> grp) {
|
||||
groups = grp;
|
||||
}
|
||||
|
||||
public void addGroup(PwGroup group) {
|
||||
public void addGroup(PwGroupV3 group) {
|
||||
this.groups.add(group);
|
||||
}
|
||||
|
||||
@@ -126,7 +131,7 @@ public class PwDatabaseV3 extends PwDatabase {
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<PwEntry> getEntries() {
|
||||
public List<PwEntryV3> getEntries() {
|
||||
return entries;
|
||||
}
|
||||
|
||||
@@ -134,7 +139,7 @@ public class PwDatabaseV3 extends PwDatabase {
|
||||
return entries.get(position);
|
||||
}
|
||||
|
||||
public void addEntry(PwEntry entry) {
|
||||
public void addEntry(PwEntryV3 entry) {
|
||||
this.entries.add(entry);
|
||||
}
|
||||
|
||||
@@ -143,23 +148,23 @@ public class PwDatabaseV3 extends PwDatabase {
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<PwGroup> getGrpRoots() {
|
||||
public List<PwGroupV3> getGrpRoots() {
|
||||
int target = 0;
|
||||
List<PwGroup> kids = new ArrayList<PwGroup>();
|
||||
List<PwGroupV3> kids = new ArrayList<>();
|
||||
for (int i = 0; i < groups.size(); i++) {
|
||||
PwGroupV3 grp = (PwGroupV3) groups.get(i);
|
||||
PwGroupV3 grp = groups.get(i);
|
||||
if (grp.getLevel() == target)
|
||||
kids.add(grp);
|
||||
}
|
||||
return kids;
|
||||
}
|
||||
|
||||
public List<PwGroup> getGrpChildren(PwGroupV3 parent) {
|
||||
public List<PwGroupV3> getGrpChildren(PwGroupV3 parent) {
|
||||
int idx = groups.indexOf(parent);
|
||||
int target = parent.getLevel() + 1;
|
||||
List<PwGroup> kids = new ArrayList<PwGroup>();
|
||||
List<PwGroupV3> kids = new ArrayList<>();
|
||||
while (++idx < groups.size()) {
|
||||
PwGroupV3 grp = (PwGroupV3) groups.get(idx);
|
||||
PwGroupV3 grp = groups.get(idx);
|
||||
if (grp.getLevel() < target)
|
||||
break;
|
||||
else if (grp.getLevel() == target)
|
||||
@@ -168,15 +173,15 @@ public class PwDatabaseV3 extends PwDatabase {
|
||||
return kids;
|
||||
}
|
||||
|
||||
public List<PwEntry> getEntries(PwGroupV3 parent) {
|
||||
List<PwEntry> kids = new ArrayList<PwEntry>();
|
||||
public List<PwEntryV3> getEntries(PwGroupV3 parent) {
|
||||
List<PwEntryV3> kids = new ArrayList<>();
|
||||
/*
|
||||
* for( Iterator i = entries.iterator(); i.hasNext(); ) { PwEntryV3 ent
|
||||
* = (PwEntryV3)i.next(); if( ent.groupId == parent.groupId ) kids.add(
|
||||
* ent ); }
|
||||
*/
|
||||
for (int i = 0; i < entries.size(); i++) {
|
||||
PwEntryV3 ent = (PwEntryV3) entries.get(i);
|
||||
PwEntryV3 ent = entries.get(i);
|
||||
if (ent.getGroupId() == parent.getGroupId())
|
||||
kids.add(ent);
|
||||
}
|
||||
@@ -193,12 +198,12 @@ public class PwDatabaseV3 extends PwDatabase {
|
||||
PwGroupV3 root = new PwGroupV3();
|
||||
rootGroup = root;
|
||||
|
||||
List<PwGroup> rootChildGroups = getGrpRoots();
|
||||
List<PwGroupV3> rootChildGroups = getGrpRoots();
|
||||
root.setGroups(rootChildGroups);
|
||||
root.setEntries(new ArrayList<>());
|
||||
root.setLevel(-1);
|
||||
for (int i = 0; i < rootChildGroups.size(); i++) {
|
||||
PwGroupV3 grp = (PwGroupV3) rootChildGroups.get(i);
|
||||
PwGroupV3 grp = rootChildGroups.get(i);
|
||||
grp.setParent(root);
|
||||
constructTree(grp);
|
||||
}
|
||||
@@ -212,14 +217,14 @@ public class PwDatabaseV3 extends PwDatabase {
|
||||
|
||||
// set parent in child entries
|
||||
for (int i = 0; i < currentGroup.numbersOfChildEntries(); i++) {
|
||||
PwEntryV3 entry = (PwEntryV3) currentGroup.getChildEntryAt(i);
|
||||
PwEntryV3 entry = currentGroup.getChildEntryAt(i);
|
||||
entry.setParent(currentGroup);
|
||||
}
|
||||
// recursively construct child groups
|
||||
for (int i = 0; i < currentGroup.numbersOfChildGroups(); i++) {
|
||||
PwGroupV3 grp = (PwGroupV3) currentGroup.getChildGroupAt(i);
|
||||
PwGroupV3 grp = currentGroup.getChildGroupAt(i);
|
||||
grp.setParent(currentGroup);
|
||||
constructTree((PwGroupV3) currentGroup.getChildGroupAt(i));
|
||||
constructTree(currentGroup.getChildGroupAt(i));
|
||||
}
|
||||
return;
|
||||
}
|
||||
@@ -292,7 +297,7 @@ public class PwDatabaseV3 extends PwDatabase {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addEntryTo(PwEntry newEntry, PwGroup parent) {
|
||||
public void addEntryTo(PwEntryV3 newEntry, PwGroupV3 parent) {
|
||||
super.addEntryTo(newEntry, parent);
|
||||
|
||||
// Add entry to root entries
|
||||
@@ -300,7 +305,7 @@ public class PwDatabaseV3 extends PwDatabase {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addGroupTo(PwGroup newGroup, PwGroup parent) {
|
||||
public void addGroupTo(PwGroupV3 newGroup, PwGroupV3 parent) {
|
||||
super.addGroupTo(newGroup, parent);
|
||||
|
||||
// Add tree to root groups
|
||||
@@ -309,7 +314,7 @@ public class PwDatabaseV3 extends PwDatabase {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeEntryFrom(PwEntry remove, PwGroup parent) {
|
||||
public void removeEntryFrom(PwEntryV3 remove, PwGroupV3 parent) {
|
||||
super.removeEntryFrom(remove, parent);
|
||||
|
||||
// Remove entry from root entry
|
||||
@@ -317,7 +322,7 @@ public class PwDatabaseV3 extends PwDatabase {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeGroupFrom(PwGroup remove, PwGroup parent) {
|
||||
public void removeGroupFrom(PwGroupV3 remove, PwGroupV3 parent) {
|
||||
super.removeGroupFrom(remove, parent);
|
||||
|
||||
// Remove tree from root entry
|
||||
@@ -325,7 +330,7 @@ public class PwDatabaseV3 extends PwDatabase {
|
||||
}
|
||||
|
||||
@Override
|
||||
public PwGroup createGroup() {
|
||||
public PwGroupV3 createGroup() {
|
||||
return new PwGroupV3();
|
||||
}
|
||||
|
||||
@@ -339,21 +344,19 @@ public class PwDatabaseV3 extends PwDatabase {
|
||||
// No-op
|
||||
}
|
||||
@Override
|
||||
public boolean isBackup(PwGroup group) {
|
||||
PwGroupV3 g = (PwGroupV3) group;
|
||||
while (g != null) {
|
||||
if (g.getLevel() == 0 && g.getName().equalsIgnoreCase("Backup")) {
|
||||
public boolean isBackup(PwGroupV3 group) {
|
||||
while (group != null) {
|
||||
if (group.getLevel() == 0 && group.getName().equalsIgnoreCase("Backup")) {
|
||||
return true;
|
||||
}
|
||||
|
||||
g = (PwGroupV3) g.getParent();
|
||||
group = group.getParent();
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isGroupSearchable(PwGroup group, boolean omitBackup) {
|
||||
public boolean isGroupSearchable(PwGroupV3 group, boolean omitBackup) {
|
||||
if (!super.isGroupSearchable(group, omitBackup)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -104,6 +104,11 @@ public class PwDatabaseV4 extends PwDatabase {
|
||||
|
||||
public String localizedAppName = "KeePassDX"; // TODO resource
|
||||
|
||||
@Override
|
||||
public PwVersion getVersion() {
|
||||
return PwVersion.V4;
|
||||
}
|
||||
|
||||
public byte[] getHmacKey() {
|
||||
return hmacKey;
|
||||
}
|
||||
@@ -520,7 +525,7 @@ public class PwDatabaseV4 extends PwDatabase {
|
||||
}
|
||||
|
||||
@Override
|
||||
public PwGroup createGroup() {
|
||||
public PwGroupV4 createGroup() {
|
||||
return new PwGroupV4();
|
||||
}
|
||||
|
||||
|
||||
@@ -26,15 +26,15 @@ import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.UUID;
|
||||
|
||||
public abstract class PwEntry extends PwNode implements Cloneable {
|
||||
public abstract class PwEntry<Parent extends PwGroup> extends PwNode<Parent> implements Cloneable {
|
||||
|
||||
private static final String PMS_TAN_ENTRY = "<TAN>";
|
||||
|
||||
protected UUID uuid = PwDatabase.UUID_ZERO;
|
||||
|
||||
@Override
|
||||
protected void construct() {
|
||||
super.construct();
|
||||
protected void construct(Parent parent) {
|
||||
super.construct(parent);
|
||||
uuid = UUID.randomUUID();
|
||||
}
|
||||
|
||||
@@ -72,7 +72,7 @@ public abstract class PwEntry extends PwNode implements Cloneable {
|
||||
return Type.ENTRY;
|
||||
}
|
||||
|
||||
public void assign(PwEntry source) {
|
||||
protected void assign(PwEntry<Parent> source) {
|
||||
super.assign(source);
|
||||
uuid = source.uuid;
|
||||
}
|
||||
@@ -179,21 +179,6 @@ public abstract class PwEntry extends PwNode implements Cloneable {
|
||||
return EntrySearchStringIterator.getInstance(this);
|
||||
}
|
||||
|
||||
public void touch(boolean modified, boolean touchParents) {
|
||||
PwDate now = new PwDate();
|
||||
|
||||
setLastAccessTime(now);
|
||||
|
||||
if (modified) {
|
||||
setLastModificationTime(now);
|
||||
}
|
||||
|
||||
PwGroup parent = getParent();
|
||||
if (touchParents && parent != null) {
|
||||
parent.touch(modified, true);
|
||||
}
|
||||
}
|
||||
|
||||
public void touchLocation() { }
|
||||
|
||||
public boolean isSearchingEnabled() {
|
||||
|
||||
@@ -67,7 +67,7 @@ import java.util.UUID;
|
||||
* @author Dominik Reichl <dominik.reichl@t-online.de>
|
||||
* @author Jeremy Jamet <jeremy.jamet@kunzisoft.com>
|
||||
*/
|
||||
public class PwEntryV3 extends PwEntry {
|
||||
public class PwEntryV3 extends PwEntry<PwGroupV3> {
|
||||
|
||||
/** Size of byte buffer needed to hold this struct. */
|
||||
private static final String PMS_ID_BINDESC = "bin-stream";
|
||||
@@ -75,8 +75,7 @@ public class PwEntryV3 extends PwEntry {
|
||||
private static final String PMS_ID_USER = "SYSTEM";
|
||||
private static final String PMS_ID_URL = "$";
|
||||
|
||||
// for tree traversing
|
||||
private PwGroupV3 parent = null;
|
||||
// TODO Parent ID to remove
|
||||
private int groupId;
|
||||
|
||||
private String title;
|
||||
@@ -94,34 +93,26 @@ public class PwEntryV3 extends PwEntry {
|
||||
}
|
||||
|
||||
public PwEntryV3(PwGroupV3 p) {
|
||||
construct();
|
||||
parent = p;
|
||||
groupId = ((PwGroupIdV3)parent.getId()).getId(); // TODO remove
|
||||
construct(p);
|
||||
groupId = ((PwGroupIdV3) this.parent.getId()).getId(); // TODO remove
|
||||
}
|
||||
|
||||
@Override
|
||||
public void assign(PwEntry source) {
|
||||
if ( ! (source instanceof PwEntryV3) ) {
|
||||
throw new RuntimeException("DB version mix");
|
||||
}
|
||||
super.assign(source);
|
||||
PwEntryV3 src = (PwEntryV3) source;
|
||||
parent = src.parent;
|
||||
groupId = src.groupId;
|
||||
protected void assignData(PwEntryV3 source) {
|
||||
groupId = source.groupId;
|
||||
|
||||
title = src.title;
|
||||
username = src.username;
|
||||
int passLen = src.password.length;
|
||||
title = source.title;
|
||||
username = source.username;
|
||||
int passLen = source.password.length;
|
||||
password = new byte[passLen];
|
||||
System.arraycopy(src.password, 0, password, 0, passLen);
|
||||
url = src.url;
|
||||
additional = src.additional;
|
||||
System.arraycopy(source.password, 0, password, 0, passLen);
|
||||
url = source.url;
|
||||
additional = source.additional;
|
||||
|
||||
binaryDesc = src.binaryDesc;
|
||||
if ( src.binaryData != null ) {
|
||||
int descLen = src.binaryData.length;
|
||||
binaryDesc = source.binaryDesc;
|
||||
if ( source.binaryData != null ) {
|
||||
int descLen = source.binaryData.length;
|
||||
binaryData = new byte[descLen];
|
||||
System.arraycopy(src.binaryData, 0, binaryData, 0, descLen);
|
||||
System.arraycopy(source.binaryData, 0, binaryData, 0, descLen);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -155,16 +146,6 @@ public class PwEntryV3 extends PwEntry {
|
||||
return newEntry;
|
||||
}
|
||||
|
||||
@Override
|
||||
public PwGroupV3 getParent() {
|
||||
return parent;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setParent(PwGroup parent) {
|
||||
this.parent = (PwGroupV3) parent;
|
||||
}
|
||||
|
||||
public int getGroupId() {
|
||||
return groupId;
|
||||
}
|
||||
|
||||
@@ -30,7 +30,7 @@ import java.util.Iterator;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
|
||||
public class PwEntryV4 extends PwEntry implements ITimeLogger {
|
||||
public class PwEntryV4 extends PwEntry<PwGroupV4> implements ITimeLogger {
|
||||
|
||||
public static final String STR_TITLE = "Title";
|
||||
public static final String STR_USERNAME = "UserName";
|
||||
@@ -41,8 +41,7 @@ public class PwEntryV4 extends PwEntry implements ITimeLogger {
|
||||
// To decode each field not serializable
|
||||
private transient PwDatabase mDatabase = null;
|
||||
private transient boolean mDecodeRef = false;
|
||||
|
||||
private PwGroupV4 parent;
|
||||
|
||||
private PwIconCustom customIcon = PwIconCustom.ZERO;
|
||||
private long usageCount = 0;
|
||||
private PwDate parentGroupLastMod = new PwDate();
|
||||
@@ -65,34 +64,27 @@ public class PwEntryV4 extends PwEntry implements ITimeLogger {
|
||||
}
|
||||
|
||||
public PwEntryV4(PwGroupV4 p) {
|
||||
construct();
|
||||
parent = p;
|
||||
construct(p);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void assign(PwEntry source) {
|
||||
if ( ! (source instanceof PwEntryV4) ) {
|
||||
throw new RuntimeException("DB version mix.");
|
||||
}
|
||||
public void assign(PwEntryV4 source) {
|
||||
super.assign(source);
|
||||
PwEntryV4 src = (PwEntryV4) source;
|
||||
parent = src.parent;
|
||||
customIcon = src.customIcon;
|
||||
usageCount = src.usageCount;
|
||||
parentGroupLastMod = src.parentGroupLastMod;
|
||||
customIcon = source.customIcon;
|
||||
usageCount = source.usageCount;
|
||||
parentGroupLastMod = source.parentGroupLastMod;
|
||||
// TODO customData
|
||||
|
||||
fields = src.fields;
|
||||
binaries = src.binaries;
|
||||
foregroundColor = src.foregroundColor;
|
||||
backgroupColor = src.backgroupColor;
|
||||
overrideURL = src.overrideURL;
|
||||
autoType = src.autoType;
|
||||
history = src.history;
|
||||
fields = source.fields;
|
||||
binaries = source.binaries;
|
||||
foregroundColor = source.foregroundColor;
|
||||
backgroupColor = source.backgroupColor;
|
||||
overrideURL = source.overrideURL;
|
||||
autoType = source.autoType;
|
||||
history = source.history;
|
||||
|
||||
url = src.url;
|
||||
additional = src.additional;
|
||||
tags = src.tags;
|
||||
url = source.url;
|
||||
additional = source.additional;
|
||||
tags = source.tags;
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@@ -104,7 +96,6 @@ public class PwEntryV4 extends PwEntry implements ITimeLogger {
|
||||
addCloneAttributesToNewEntry(newEntry);
|
||||
|
||||
// Attributes here
|
||||
// newEntry.parent stay the same in copy
|
||||
newEntry.customIcon = new PwIconCustom(this.customIcon);
|
||||
// newEntry.usageCount stay the same in copy
|
||||
newEntry.parentGroupLastMod = this.parentGroupLastMod.clone();
|
||||
@@ -206,16 +197,6 @@ public class PwEntryV4 extends PwEntry implements ITimeLogger {
|
||||
setString(STR_NOTES, notes, protect);
|
||||
}
|
||||
|
||||
@Override
|
||||
public PwGroupV4 getParent() {
|
||||
return parent;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setParent(PwGroup parent) {
|
||||
this.parent = (PwGroupV4) parent;
|
||||
}
|
||||
|
||||
public String getString(String key) {
|
||||
ProtectedString value = fields.get(key);
|
||||
|
||||
|
||||
@@ -22,56 +22,56 @@ package com.keepassdroid.database;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public abstract class PwGroup extends PwNode {
|
||||
public abstract class PwGroup<Parent extends PwGroup, ChildGroup extends PwGroup, ChildEntry extends PwEntry>
|
||||
extends PwNode<Parent> {
|
||||
|
||||
protected String name = "";
|
||||
|
||||
protected List<PwGroup> childGroups = new ArrayList<>();
|
||||
protected List<PwEntry> childEntries = new ArrayList<>();
|
||||
protected List<ChildGroup> childGroups = new ArrayList<>();
|
||||
protected List<ChildEntry> childEntries = new ArrayList<>();
|
||||
|
||||
public void initNewGroup(String nm, PwGroupId newId) {
|
||||
setId(newId);
|
||||
name = nm;
|
||||
}
|
||||
|
||||
public List<PwGroup> getChildGroups() {
|
||||
public List<ChildGroup> getChildGroups() {
|
||||
return childGroups;
|
||||
}
|
||||
|
||||
public List<PwEntry> getChildEntries() {
|
||||
public List<ChildEntry> getChildEntries() {
|
||||
return childEntries;
|
||||
}
|
||||
|
||||
public void setGroups(List<PwGroup> groups) {
|
||||
public void setGroups(List<ChildGroup> groups) {
|
||||
childGroups = groups;
|
||||
}
|
||||
|
||||
public void setEntries(List<PwEntry> entries) {
|
||||
public void setEntries(List<ChildEntry> entries) {
|
||||
childEntries = entries;
|
||||
}
|
||||
|
||||
public void addChildGroup(PwGroup group) {
|
||||
public void addChildGroup(ChildGroup group) {
|
||||
this.childGroups.add(group);
|
||||
}
|
||||
|
||||
public void addChildEntry(PwEntry entry) {
|
||||
public void addChildEntry(ChildEntry entry) {
|
||||
this.childEntries.add(entry);
|
||||
}
|
||||
|
||||
// Todo parameter type
|
||||
public PwGroup getChildGroupAt(int number) {
|
||||
public ChildGroup getChildGroupAt(int number) {
|
||||
return this.childGroups.get(number);
|
||||
}
|
||||
|
||||
public PwEntry getChildEntryAt(int number) {
|
||||
public ChildEntry getChildEntryAt(int number) {
|
||||
return this.childEntries.get(number);
|
||||
}
|
||||
|
||||
public void removeChildGroup(PwGroup group) {
|
||||
public void removeChildGroup(ChildGroup group) {
|
||||
this.childGroups.remove(group);
|
||||
}
|
||||
|
||||
public void removeChildEntry(PwEntry entry) {
|
||||
public void removeChildEntry(ChildEntry entry) {
|
||||
this.childEntries.remove(entry);
|
||||
}
|
||||
|
||||
@@ -95,24 +95,13 @@ public abstract class PwGroup extends PwNode {
|
||||
public List<PwNode> getDirectChildren() {
|
||||
List<PwNode> children = new ArrayList<>();
|
||||
children.addAll(childGroups);
|
||||
for(PwEntry child : childEntries) {
|
||||
for(ChildEntry child : childEntries) {
|
||||
if (!child.isMetaStream())
|
||||
children.add(child);
|
||||
}
|
||||
return children;
|
||||
}
|
||||
|
||||
public boolean isContainedIn(PwGroup container) {
|
||||
PwGroup cur = this;
|
||||
while (cur != null) {
|
||||
if (cur == container) {
|
||||
return true;
|
||||
}
|
||||
cur = cur.getParent();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public abstract PwGroupId getId();
|
||||
public abstract void setId(PwGroupId id);
|
||||
|
||||
@@ -133,28 +122,15 @@ public abstract class PwGroup extends PwNode {
|
||||
return false;
|
||||
}
|
||||
|
||||
public void touch(boolean modified, boolean touchParents) {
|
||||
PwDate now = new PwDate();
|
||||
setLastAccessTime(now);
|
||||
|
||||
if (modified) {
|
||||
setLastModificationTime(now);
|
||||
}
|
||||
|
||||
PwGroup parent = getParent();
|
||||
if (touchParents && parent != null) {
|
||||
parent.touch(modified, true);
|
||||
}
|
||||
}
|
||||
|
||||
public boolean preOrderTraverseTree(GroupHandler<PwGroup> groupHandler, EntryHandler<PwEntry> entryHandler) {
|
||||
public boolean preOrderTraverseTree(GroupHandler<ChildGroup> groupHandler,
|
||||
EntryHandler<ChildEntry> entryHandler) {
|
||||
if (entryHandler != null) {
|
||||
for (PwEntry entry : childEntries) {
|
||||
for (ChildEntry entry : childEntries) {
|
||||
if (!entryHandler.operate(entry)) return false;
|
||||
}
|
||||
}
|
||||
|
||||
for (PwGroup group : childGroups) {
|
||||
for (ChildGroup group : childGroups) {
|
||||
if ((groupHandler != null) && !groupHandler.operate(group)) return false;
|
||||
group.preOrderTraverseTree(groupHandler, entryHandler);
|
||||
}
|
||||
|
||||
@@ -26,10 +26,9 @@ package com.keepassdroid.database;
|
||||
* @author Bill Zwicky <wrzwicky@pobox.com>
|
||||
* @author Dominik Reichl <dominik.reichl@t-online.de>
|
||||
*/
|
||||
public class PwGroupV3 extends PwGroup {
|
||||
public class PwGroupV3 extends PwGroup<PwGroupV3, PwGroupV3, PwEntryV3> {
|
||||
|
||||
// for tree traversing
|
||||
private PwGroupV3 parent = null;
|
||||
private int groupId;
|
||||
|
||||
private int level = 0; // short
|
||||
@@ -41,15 +40,10 @@ public class PwGroupV3 extends PwGroup {
|
||||
super();
|
||||
}
|
||||
|
||||
@Override
|
||||
public PwGroup getParent() {
|
||||
return parent;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setParent(PwGroup prt) {
|
||||
parent = (PwGroupV3) prt;
|
||||
level = parent.getLevel() + 1;
|
||||
public void setParent(PwGroupV3 parent) {
|
||||
super.setParent(parent);
|
||||
level = this.parent.getLevel() + 1;
|
||||
}
|
||||
|
||||
public int getGroupId() {
|
||||
|
||||
@@ -23,11 +23,10 @@ import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.UUID;
|
||||
|
||||
public class PwGroupV4 extends PwGroup implements ITimeLogger {
|
||||
public class PwGroupV4 extends PwGroup<PwGroupV4, PwGroupV4, PwEntryV4> implements ITimeLogger {
|
||||
|
||||
public static final boolean DEFAULT_SEARCHING_ENABLED = true;
|
||||
|
||||
private PwGroupV4 parent = null;
|
||||
private UUID uuid = PwDatabase.UUID_ZERO;
|
||||
private PwIconCustom customIcon = PwIconCustom.ZERO;
|
||||
private long usageCount = 0;
|
||||
@@ -48,7 +47,6 @@ public class PwGroupV4 extends PwGroup implements ITimeLogger {
|
||||
}
|
||||
|
||||
public PwGroupV4(String name, PwIconStandard icon) {
|
||||
super.construct();
|
||||
this.uuid = UUID.randomUUID();
|
||||
this.name = name;
|
||||
this.icon = icon;
|
||||
@@ -60,27 +58,17 @@ public class PwGroupV4 extends PwGroup implements ITimeLogger {
|
||||
parentGroupLastMod = new PwDate();
|
||||
}
|
||||
|
||||
public void AddGroup(PwGroupV4 subGroup) {
|
||||
public void addGroup(PwGroupV4 subGroup) {
|
||||
if ( subGroup == null ) throw new RuntimeException("subGroup");
|
||||
childGroups.add(subGroup);
|
||||
subGroup.parent = this;
|
||||
}
|
||||
|
||||
public void AddEntry(PwEntryV4 pe) {
|
||||
public void addEntry(PwEntryV4 pe) {
|
||||
assert(pe != null);
|
||||
addChildEntry(pe);
|
||||
pe.setParent(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public PwGroup getParent() {
|
||||
return parent;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setParent(PwGroup prt) {
|
||||
parent = (PwGroupV4) prt;
|
||||
}
|
||||
|
||||
public UUID getUUID() {
|
||||
return uuid;
|
||||
|
||||
@@ -28,7 +28,9 @@ import static com.keepassdroid.database.PwDate.PW_NEVER_EXPIRE;
|
||||
/**
|
||||
* Abstract class who manage Groups and Entries
|
||||
*/
|
||||
public abstract class PwNode implements ISmallTimeLogger, Serializable {
|
||||
public abstract class PwNode<Parent extends PwGroup> implements ISmallTimeLogger, Serializable {
|
||||
|
||||
protected Parent parent = null;
|
||||
|
||||
protected PwIconStandard icon = PwIconStandard.FIRST;
|
||||
|
||||
@@ -37,10 +39,13 @@ public abstract class PwNode implements ISmallTimeLogger, Serializable {
|
||||
protected PwDate lastAccess = new PwDate();
|
||||
protected PwDate expireDate = new PwDate(NEVER_EXPIRE);
|
||||
|
||||
protected void construct() {
|
||||
protected void construct(Parent parent) {
|
||||
this.parent = parent;
|
||||
}
|
||||
|
||||
public void assign(PwNode source) {
|
||||
protected void assign(PwNode<Parent> source) {
|
||||
this.parent = source.parent;
|
||||
|
||||
this.icon = source.icon;
|
||||
|
||||
this.creation = source.creation;
|
||||
@@ -50,6 +55,8 @@ public abstract class PwNode implements ISmallTimeLogger, Serializable {
|
||||
}
|
||||
|
||||
protected void addCloneAttributesToNewEntry(PwEntry newEntry) {
|
||||
// newEntry.parent stay the same in copy
|
||||
|
||||
newEntry.icon = new PwIconStandard(this.icon);
|
||||
|
||||
newEntry.creation = creation.clone();
|
||||
@@ -94,12 +101,16 @@ public abstract class PwNode implements ISmallTimeLogger, Serializable {
|
||||
* Retrieve the parent node
|
||||
* @return PwGroup parent as group
|
||||
*/
|
||||
public abstract PwGroup getParent();
|
||||
public Parent getParent() {
|
||||
return parent;
|
||||
}
|
||||
|
||||
/**
|
||||
* Assign a parent to this node
|
||||
*/
|
||||
public abstract void setParent(PwGroup parent);
|
||||
public void setParent(Parent prt) {
|
||||
parent = prt;
|
||||
}
|
||||
|
||||
public PwDate getCreationTime() {
|
||||
return creation;
|
||||
@@ -162,4 +173,29 @@ public abstract class PwNode implements ISmallTimeLogger, Serializable {
|
||||
boolean isSameType(PwNode otherNode) {
|
||||
return getType() != null ? getType().equals(otherNode.getType()) : otherNode.getType() == null;
|
||||
}
|
||||
|
||||
public boolean isContainedIn(PwGroup container) {
|
||||
PwGroup cur = this.getParent();
|
||||
while (cur != null) {
|
||||
if (cur.equals(container)) {
|
||||
return true;
|
||||
}
|
||||
cur = cur.getParent();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public void touch(boolean modified, boolean touchParents) {
|
||||
PwDate now = new PwDate();
|
||||
setLastAccessTime(now);
|
||||
|
||||
if (modified) {
|
||||
setLastModificationTime(now);
|
||||
}
|
||||
|
||||
Parent parent = getParent();
|
||||
if (touchParents && parent != null) {
|
||||
parent.touch(modified, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -48,7 +48,7 @@ public class UpdateEntry extends RunnableOnFinish {
|
||||
@Override
|
||||
public void run() {
|
||||
// Update entry with new values
|
||||
mOldE.assign(mNewE);
|
||||
mOldE = mNewE; // TODO Verify
|
||||
mOldE.touch(true, true);
|
||||
|
||||
|
||||
@@ -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.assign(mBackup);
|
||||
mOldE = mBackup; // TODO Verify
|
||||
}
|
||||
// TODO Callback for update entry
|
||||
super.run();
|
||||
|
||||
@@ -19,7 +19,39 @@
|
||||
*/
|
||||
package com.keepassdroid.database.load;
|
||||
|
||||
import static com.keepassdroid.database.PwDatabaseV4XML.*;
|
||||
import com.keepassdroid.crypto.CipherFactory;
|
||||
import com.keepassdroid.crypto.PwStreamCipherFactory;
|
||||
import com.keepassdroid.crypto.engine.CipherEngine;
|
||||
import com.keepassdroid.database.ITimeLogger;
|
||||
import com.keepassdroid.database.PwCompressionAlgorithm;
|
||||
import com.keepassdroid.database.PwDatabase;
|
||||
import com.keepassdroid.database.PwDatabaseV4;
|
||||
import com.keepassdroid.database.PwDatabaseV4XML;
|
||||
import com.keepassdroid.database.PwDate;
|
||||
import com.keepassdroid.database.PwDbHeaderV4;
|
||||
import com.keepassdroid.database.PwDeletedObject;
|
||||
import com.keepassdroid.database.PwEntryV4;
|
||||
import com.keepassdroid.database.PwGroupV4;
|
||||
import com.keepassdroid.database.PwIconCustom;
|
||||
import com.keepassdroid.database.exception.ArcFourException;
|
||||
import com.keepassdroid.database.exception.InvalidDBException;
|
||||
import com.keepassdroid.database.exception.InvalidPasswordException;
|
||||
import com.keepassdroid.database.security.ProtectedBinary;
|
||||
import com.keepassdroid.database.security.ProtectedString;
|
||||
import com.keepassdroid.stream.BetterCipherInputStream;
|
||||
import com.keepassdroid.stream.HashedBlockInputStream;
|
||||
import com.keepassdroid.stream.HmacBlockInputStream;
|
||||
import com.keepassdroid.stream.LEDataInputStream;
|
||||
import com.keepassdroid.tasks.UpdateStatus;
|
||||
import com.keepassdroid.utils.DateUtil;
|
||||
import com.keepassdroid.utils.EmptyUtils;
|
||||
import com.keepassdroid.utils.MemUtil;
|
||||
import com.keepassdroid.utils.Types;
|
||||
|
||||
import org.spongycastle.crypto.StreamCipher;
|
||||
import org.xmlpull.v1.XmlPullParser;
|
||||
import org.xmlpull.v1.XmlPullParserException;
|
||||
import org.xmlpull.v1.XmlPullParserFactory;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
@@ -39,41 +71,93 @@ import java.util.zip.GZIPInputStream;
|
||||
import javax.crypto.Cipher;
|
||||
import javax.crypto.NoSuchPaddingException;
|
||||
|
||||
import org.spongycastle.crypto.StreamCipher;
|
||||
import org.xmlpull.v1.XmlPullParser;
|
||||
import org.xmlpull.v1.XmlPullParserException;
|
||||
import org.xmlpull.v1.XmlPullParserFactory;
|
||||
|
||||
import biz.source_code.base64Coder.Base64Coder;
|
||||
|
||||
import com.keepassdroid.database.PwDatabase;
|
||||
import com.keepassdroid.database.PwDate;
|
||||
import com.keepassdroid.tasks.UpdateStatus;
|
||||
import com.keepassdroid.crypto.CipherFactory;
|
||||
import com.keepassdroid.crypto.PwStreamCipherFactory;
|
||||
import com.keepassdroid.crypto.engine.CipherEngine;
|
||||
import com.keepassdroid.database.ITimeLogger;
|
||||
import com.keepassdroid.database.PwCompressionAlgorithm;
|
||||
import com.keepassdroid.database.PwDatabaseV4;
|
||||
import com.keepassdroid.database.PwDatabaseV4XML;
|
||||
import com.keepassdroid.database.PwDbHeaderV4;
|
||||
import com.keepassdroid.database.PwDeletedObject;
|
||||
import com.keepassdroid.database.PwEntryV4;
|
||||
import com.keepassdroid.database.PwGroupV4;
|
||||
import com.keepassdroid.database.PwIconCustom;
|
||||
import com.keepassdroid.database.exception.ArcFourException;
|
||||
import com.keepassdroid.database.exception.InvalidDBException;
|
||||
import com.keepassdroid.database.exception.InvalidPasswordException;
|
||||
import com.keepassdroid.database.security.ProtectedBinary;
|
||||
import com.keepassdroid.database.security.ProtectedString;
|
||||
import com.keepassdroid.stream.BetterCipherInputStream;
|
||||
import com.keepassdroid.stream.HashedBlockInputStream;
|
||||
import com.keepassdroid.stream.HmacBlockInputStream;
|
||||
import com.keepassdroid.stream.LEDataInputStream;
|
||||
import com.keepassdroid.utils.DateUtil;
|
||||
import com.keepassdroid.utils.EmptyUtils;
|
||||
import com.keepassdroid.utils.MemUtil;
|
||||
import com.keepassdroid.utils.Types;
|
||||
import static com.keepassdroid.database.PwDatabaseV4XML.AttrCompressed;
|
||||
import static com.keepassdroid.database.PwDatabaseV4XML.AttrId;
|
||||
import static com.keepassdroid.database.PwDatabaseV4XML.AttrProtected;
|
||||
import static com.keepassdroid.database.PwDatabaseV4XML.AttrRef;
|
||||
import static com.keepassdroid.database.PwDatabaseV4XML.ElemAutoType;
|
||||
import static com.keepassdroid.database.PwDatabaseV4XML.ElemAutoTypeDefaultSeq;
|
||||
import static com.keepassdroid.database.PwDatabaseV4XML.ElemAutoTypeEnabled;
|
||||
import static com.keepassdroid.database.PwDatabaseV4XML.ElemAutoTypeItem;
|
||||
import static com.keepassdroid.database.PwDatabaseV4XML.ElemAutoTypeObfuscation;
|
||||
import static com.keepassdroid.database.PwDatabaseV4XML.ElemBgColor;
|
||||
import static com.keepassdroid.database.PwDatabaseV4XML.ElemBinaries;
|
||||
import static com.keepassdroid.database.PwDatabaseV4XML.ElemBinary;
|
||||
import static com.keepassdroid.database.PwDatabaseV4XML.ElemCreationTime;
|
||||
import static com.keepassdroid.database.PwDatabaseV4XML.ElemCustomData;
|
||||
import static com.keepassdroid.database.PwDatabaseV4XML.ElemCustomIconID;
|
||||
import static com.keepassdroid.database.PwDatabaseV4XML.ElemCustomIconItem;
|
||||
import static com.keepassdroid.database.PwDatabaseV4XML.ElemCustomIconItemData;
|
||||
import static com.keepassdroid.database.PwDatabaseV4XML.ElemCustomIconItemID;
|
||||
import static com.keepassdroid.database.PwDatabaseV4XML.ElemCustomIcons;
|
||||
import static com.keepassdroid.database.PwDatabaseV4XML.ElemDbColor;
|
||||
import static com.keepassdroid.database.PwDatabaseV4XML.ElemDbDefaultUser;
|
||||
import static com.keepassdroid.database.PwDatabaseV4XML.ElemDbDefaultUserChanged;
|
||||
import static com.keepassdroid.database.PwDatabaseV4XML.ElemDbDesc;
|
||||
import static com.keepassdroid.database.PwDatabaseV4XML.ElemDbDescChanged;
|
||||
import static com.keepassdroid.database.PwDatabaseV4XML.ElemDbKeyChangeForce;
|
||||
import static com.keepassdroid.database.PwDatabaseV4XML.ElemDbKeyChangeForceOnce;
|
||||
import static com.keepassdroid.database.PwDatabaseV4XML.ElemDbKeyChangeRec;
|
||||
import static com.keepassdroid.database.PwDatabaseV4XML.ElemDbKeyChanged;
|
||||
import static com.keepassdroid.database.PwDatabaseV4XML.ElemDbMntncHistoryDays;
|
||||
import static com.keepassdroid.database.PwDatabaseV4XML.ElemDbName;
|
||||
import static com.keepassdroid.database.PwDatabaseV4XML.ElemDbNameChanged;
|
||||
import static com.keepassdroid.database.PwDatabaseV4XML.ElemDeletedObject;
|
||||
import static com.keepassdroid.database.PwDatabaseV4XML.ElemDeletedObjects;
|
||||
import static com.keepassdroid.database.PwDatabaseV4XML.ElemDeletionTime;
|
||||
import static com.keepassdroid.database.PwDatabaseV4XML.ElemDocNode;
|
||||
import static com.keepassdroid.database.PwDatabaseV4XML.ElemEnableAutoType;
|
||||
import static com.keepassdroid.database.PwDatabaseV4XML.ElemEnableSearching;
|
||||
import static com.keepassdroid.database.PwDatabaseV4XML.ElemEntry;
|
||||
import static com.keepassdroid.database.PwDatabaseV4XML.ElemEntryTemplatesGroup;
|
||||
import static com.keepassdroid.database.PwDatabaseV4XML.ElemEntryTemplatesGroupChanged;
|
||||
import static com.keepassdroid.database.PwDatabaseV4XML.ElemExpires;
|
||||
import static com.keepassdroid.database.PwDatabaseV4XML.ElemExpiryTime;
|
||||
import static com.keepassdroid.database.PwDatabaseV4XML.ElemFgColor;
|
||||
import static com.keepassdroid.database.PwDatabaseV4XML.ElemGenerator;
|
||||
import static com.keepassdroid.database.PwDatabaseV4XML.ElemGroup;
|
||||
import static com.keepassdroid.database.PwDatabaseV4XML.ElemGroupDefaultAutoTypeSeq;
|
||||
import static com.keepassdroid.database.PwDatabaseV4XML.ElemHeaderHash;
|
||||
import static com.keepassdroid.database.PwDatabaseV4XML.ElemHistory;
|
||||
import static com.keepassdroid.database.PwDatabaseV4XML.ElemHistoryMaxItems;
|
||||
import static com.keepassdroid.database.PwDatabaseV4XML.ElemHistoryMaxSize;
|
||||
import static com.keepassdroid.database.PwDatabaseV4XML.ElemIcon;
|
||||
import static com.keepassdroid.database.PwDatabaseV4XML.ElemIsExpanded;
|
||||
import static com.keepassdroid.database.PwDatabaseV4XML.ElemKey;
|
||||
import static com.keepassdroid.database.PwDatabaseV4XML.ElemKeystrokeSequence;
|
||||
import static com.keepassdroid.database.PwDatabaseV4XML.ElemLastAccessTime;
|
||||
import static com.keepassdroid.database.PwDatabaseV4XML.ElemLastModTime;
|
||||
import static com.keepassdroid.database.PwDatabaseV4XML.ElemLastSelectedGroup;
|
||||
import static com.keepassdroid.database.PwDatabaseV4XML.ElemLastTopVisibleEntry;
|
||||
import static com.keepassdroid.database.PwDatabaseV4XML.ElemLastTopVisibleGroup;
|
||||
import static com.keepassdroid.database.PwDatabaseV4XML.ElemLocationChanged;
|
||||
import static com.keepassdroid.database.PwDatabaseV4XML.ElemMemoryProt;
|
||||
import static com.keepassdroid.database.PwDatabaseV4XML.ElemMeta;
|
||||
import static com.keepassdroid.database.PwDatabaseV4XML.ElemName;
|
||||
import static com.keepassdroid.database.PwDatabaseV4XML.ElemNotes;
|
||||
import static com.keepassdroid.database.PwDatabaseV4XML.ElemOverrideUrl;
|
||||
import static com.keepassdroid.database.PwDatabaseV4XML.ElemProtAutoHide;
|
||||
import static com.keepassdroid.database.PwDatabaseV4XML.ElemProtNotes;
|
||||
import static com.keepassdroid.database.PwDatabaseV4XML.ElemProtPassword;
|
||||
import static com.keepassdroid.database.PwDatabaseV4XML.ElemProtTitle;
|
||||
import static com.keepassdroid.database.PwDatabaseV4XML.ElemProtURL;
|
||||
import static com.keepassdroid.database.PwDatabaseV4XML.ElemProtUserName;
|
||||
import static com.keepassdroid.database.PwDatabaseV4XML.ElemRecycleBinChanged;
|
||||
import static com.keepassdroid.database.PwDatabaseV4XML.ElemRecycleBinEnabled;
|
||||
import static com.keepassdroid.database.PwDatabaseV4XML.ElemRecycleBinUuid;
|
||||
import static com.keepassdroid.database.PwDatabaseV4XML.ElemRoot;
|
||||
import static com.keepassdroid.database.PwDatabaseV4XML.ElemSettingsChanged;
|
||||
import static com.keepassdroid.database.PwDatabaseV4XML.ElemString;
|
||||
import static com.keepassdroid.database.PwDatabaseV4XML.ElemStringDictExItem;
|
||||
import static com.keepassdroid.database.PwDatabaseV4XML.ElemTags;
|
||||
import static com.keepassdroid.database.PwDatabaseV4XML.ElemTimes;
|
||||
import static com.keepassdroid.database.PwDatabaseV4XML.ElemUsageCount;
|
||||
import static com.keepassdroid.database.PwDatabaseV4XML.ElemUuid;
|
||||
import static com.keepassdroid.database.PwDatabaseV4XML.ElemValue;
|
||||
import static com.keepassdroid.database.PwDatabaseV4XML.ElemWindow;
|
||||
import static com.keepassdroid.database.PwDatabaseV4XML.ValTrue;
|
||||
|
||||
public class ImporterV4 extends Importer {
|
||||
|
||||
@@ -582,13 +666,13 @@ public class ImporterV4 extends Importer {
|
||||
return SwitchContext(ctx, KdbContext.GroupCustomData, xpp);
|
||||
} else if ( name.equalsIgnoreCase(ElemGroup) ) {
|
||||
ctxGroup = new PwGroupV4();
|
||||
ctxGroups.peek().AddGroup(ctxGroup);
|
||||
ctxGroups.peek().addGroup(ctxGroup);
|
||||
ctxGroups.push(ctxGroup);
|
||||
|
||||
return SwitchContext(ctx, KdbContext.Group, xpp);
|
||||
} else if ( name.equalsIgnoreCase(ElemEntry) ) {
|
||||
ctxEntry = new PwEntryV4();
|
||||
ctxGroup.AddEntry(ctxEntry);
|
||||
ctxGroup.addEntry(ctxEntry);
|
||||
|
||||
entryInHistory = false;
|
||||
return SwitchContext(ctx, KdbContext.Entry, xpp);
|
||||
|
||||
@@ -19,6 +19,17 @@
|
||||
*/
|
||||
package com.keepassdroid.database.save;
|
||||
|
||||
import com.keepassdroid.crypto.CipherFactory;
|
||||
import com.keepassdroid.database.PwDatabaseV3;
|
||||
import com.keepassdroid.database.PwDbHeader;
|
||||
import com.keepassdroid.database.PwDbHeaderV3;
|
||||
import com.keepassdroid.database.PwEncryptionAlgorithm;
|
||||
import com.keepassdroid.database.PwEntryV3;
|
||||
import com.keepassdroid.database.PwGroupV3;
|
||||
import com.keepassdroid.database.exception.PwDbOutputException;
|
||||
import com.keepassdroid.stream.LEDataOutputStream;
|
||||
import com.keepassdroid.stream.NullOutputStream;
|
||||
|
||||
import java.io.BufferedOutputStream;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
@@ -37,18 +48,6 @@ import javax.crypto.CipherOutputStream;
|
||||
import javax.crypto.spec.IvParameterSpec;
|
||||
import javax.crypto.spec.SecretKeySpec;
|
||||
|
||||
import com.keepassdroid.crypto.CipherFactory;
|
||||
import com.keepassdroid.database.PwDatabaseV3;
|
||||
import com.keepassdroid.database.PwDbHeader;
|
||||
import com.keepassdroid.database.PwDbHeaderV3;
|
||||
import com.keepassdroid.database.PwEncryptionAlgorithm;
|
||||
import com.keepassdroid.database.PwEntryV3;
|
||||
import com.keepassdroid.database.PwGroup;
|
||||
import com.keepassdroid.database.PwGroupV3;
|
||||
import com.keepassdroid.database.exception.PwDbOutputException;
|
||||
import com.keepassdroid.stream.LEDataOutputStream;
|
||||
import com.keepassdroid.stream.NullOutputStream;
|
||||
|
||||
public class PwDbV3Output extends PwDbOutput {
|
||||
private PwDatabaseV3 mPM;
|
||||
private byte[] headerHashBlock;
|
||||
@@ -218,9 +217,9 @@ public class PwDbV3Output extends PwDbOutput {
|
||||
}
|
||||
|
||||
// Groups
|
||||
List<PwGroup> groups = mPM.getGroups();
|
||||
List<PwGroupV3> groups = mPM.getGroups();
|
||||
for ( int i = 0; i < groups.size(); i++ ) {
|
||||
PwGroupV3 pg = (PwGroupV3) groups.get(i);
|
||||
PwGroupV3 pg = groups.get(i);
|
||||
PwGroupOutputV3 pgo = new PwGroupOutputV3(pg, os);
|
||||
try {
|
||||
pgo.output();
|
||||
@@ -242,24 +241,24 @@ public class PwDbV3Output extends PwDbOutput {
|
||||
}
|
||||
|
||||
private void sortGroupsForOutput() {
|
||||
List<PwGroup> groupList = new ArrayList<PwGroup>();
|
||||
List<PwGroupV3> groupList = new ArrayList<>();
|
||||
|
||||
// Rebuild list according to coalation sorting order removing any orphaned groups
|
||||
List<PwGroup> roots = mPM.getGrpRoots();
|
||||
List<PwGroupV3> roots = mPM.getGrpRoots();
|
||||
for ( int i = 0; i < roots.size(); i++ ) {
|
||||
sortGroup((PwGroupV3) roots.get(i), groupList);
|
||||
sortGroup(roots.get(i), groupList);
|
||||
}
|
||||
|
||||
mPM.setGroups(groupList);
|
||||
}
|
||||
|
||||
private void sortGroup(PwGroupV3 group, List<PwGroup> groupList) {
|
||||
private void sortGroup(PwGroupV3 group, List<PwGroupV3> groupList) {
|
||||
// Add current tree
|
||||
groupList.add(group);
|
||||
|
||||
// Recurse over children
|
||||
for ( int i = 0; i < group.numbersOfChildGroups(); i++ ) {
|
||||
sortGroup((PwGroupV3) group.getChildGroupAt(i), groupList);
|
||||
sortGroup(group.getChildGroupAt(i), groupList);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -26,22 +26,20 @@ import com.keepassdroid.crypto.PwStreamCipherFactory;
|
||||
import com.keepassdroid.crypto.engine.CipherEngine;
|
||||
import com.keepassdroid.crypto.keyDerivation.KdfEngine;
|
||||
import com.keepassdroid.crypto.keyDerivation.KdfFactory;
|
||||
import com.keepassdroid.database.AutoType;
|
||||
import com.keepassdroid.database.CrsAlgorithm;
|
||||
import com.keepassdroid.database.EntryHandler;
|
||||
import com.keepassdroid.database.GroupHandler;
|
||||
import com.keepassdroid.database.ITimeLogger;
|
||||
import com.keepassdroid.database.MemoryProtectionConfig;
|
||||
import com.keepassdroid.database.PwCompressionAlgorithm;
|
||||
import com.keepassdroid.database.PwDatabaseV4;
|
||||
import com.keepassdroid.database.MemoryProtectionConfig;
|
||||
import com.keepassdroid.database.PwDatabaseV4XML;
|
||||
import com.keepassdroid.database.PwDbHeader;
|
||||
import com.keepassdroid.database.PwDbHeaderV4;
|
||||
import com.keepassdroid.database.PwDefsV4;
|
||||
import com.keepassdroid.database.PwDeletedObject;
|
||||
import com.keepassdroid.database.PwEntry;
|
||||
import com.keepassdroid.database.PwEntryV4;
|
||||
import com.keepassdroid.database.AutoType;
|
||||
import com.keepassdroid.database.PwGroup;
|
||||
import com.keepassdroid.database.PwGroupV4;
|
||||
import com.keepassdroid.database.PwIconCustom;
|
||||
import com.keepassdroid.database.exception.PwDbOutputException;
|
||||
@@ -228,7 +226,7 @@ public class PwDbV4Output extends PwDbOutput {
|
||||
}
|
||||
}
|
||||
|
||||
private class GroupWriter extends GroupHandler<PwGroup> {
|
||||
private class GroupWriter extends GroupHandler<PwGroupV4> {
|
||||
private Stack<PwGroupV4> groupStack;
|
||||
|
||||
public GroupWriter(Stack<PwGroupV4> gs) {
|
||||
@@ -236,8 +234,7 @@ public class PwDbV4Output extends PwDbOutput {
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean operate(PwGroup g) {
|
||||
PwGroupV4 group = (PwGroupV4) g;
|
||||
public boolean operate(PwGroupV4 group) {
|
||||
assert(group != null);
|
||||
|
||||
while(true) {
|
||||
@@ -260,11 +257,10 @@ public class PwDbV4Output extends PwDbOutput {
|
||||
}
|
||||
}
|
||||
|
||||
private class EntryWriter extends EntryHandler<PwEntry> {
|
||||
private class EntryWriter extends EntryHandler<PwEntryV4> {
|
||||
|
||||
@Override
|
||||
public boolean operate(PwEntry e) {
|
||||
PwEntryV4 entry = (PwEntryV4) e;
|
||||
public boolean operate(PwEntryV4 entry) {
|
||||
assert(entry != null);
|
||||
|
||||
try {
|
||||
|
||||
@@ -22,17 +22,17 @@ package com.keepassdroid.search;
|
||||
import android.content.Context;
|
||||
import android.content.SharedPreferences;
|
||||
import android.preference.PreferenceManager;
|
||||
import android.util.Log;
|
||||
|
||||
import com.kunzisoft.keepass.R;
|
||||
import com.keepassdroid.database.Database;
|
||||
import com.keepassdroid.database.PwDatabase;
|
||||
import com.keepassdroid.database.PwDatabaseV3;
|
||||
import com.keepassdroid.database.PwDatabaseV4;
|
||||
import com.keepassdroid.database.PwEntry;
|
||||
import com.keepassdroid.database.PwEntryV3;
|
||||
import com.keepassdroid.database.PwEntryV4;
|
||||
import com.keepassdroid.database.PwGroup;
|
||||
import com.keepassdroid.database.PwGroupV3;
|
||||
import com.keepassdroid.database.PwGroupV4;
|
||||
import com.kunzisoft.keepass.R;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Iterator;
|
||||
@@ -41,11 +41,14 @@ import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.Queue;
|
||||
|
||||
public class SearchDbHelper {
|
||||
public class SearchDbHelper<PwDatabaseVersion extends PwDatabase,
|
||||
PwGroupSearch extends PwGroup<PwGroupSearch, PwGroupSearch, PwEntrySearch>,
|
||||
PwEntrySearch extends PwEntry<PwGroupSearch>> {
|
||||
|
||||
private final Context mCtx;
|
||||
|
||||
public SearchDbHelper(Context ctx) {
|
||||
mCtx = ctx;
|
||||
private SearchDbHelper(Context ctx) {
|
||||
this.mCtx = ctx;
|
||||
}
|
||||
|
||||
private boolean omitBackup() {
|
||||
@@ -54,18 +57,9 @@ public class SearchDbHelper {
|
||||
|
||||
}
|
||||
|
||||
public PwGroup search(Database db, String qStr) {
|
||||
PwDatabase pm = db.pm;
|
||||
public PwGroupSearch search(PwDatabaseVersion pm, String qStr) {
|
||||
|
||||
PwGroup group;
|
||||
if ( pm instanceof PwDatabaseV3 ) {
|
||||
group = new PwGroupV3();
|
||||
} else if ( pm instanceof PwDatabaseV4 ) {
|
||||
group = new PwGroupV4();
|
||||
} else {
|
||||
Log.d("SearchDbHelper", "Tried to search with unknown db");
|
||||
return null;
|
||||
}
|
||||
PwGroupSearch group = (PwGroupSearch) pm.createGroup();
|
||||
group.setName(mCtx.getString(R.string.search_results));
|
||||
group.setEntries(new ArrayList<>());
|
||||
|
||||
@@ -74,20 +68,20 @@ public class SearchDbHelper {
|
||||
qStr = qStr.toLowerCase(loc);
|
||||
boolean isOmitBackup = omitBackup();
|
||||
|
||||
Queue<PwGroup> worklist = new LinkedList<>();
|
||||
Queue<PwGroupSearch> worklist = new LinkedList<>();
|
||||
if (pm.getRootGroup() != null) {
|
||||
worklist.add(pm.getRootGroup());
|
||||
worklist.add((PwGroupSearch) pm.getRootGroup());
|
||||
}
|
||||
|
||||
while (worklist.size() != 0) {
|
||||
PwGroup top = worklist.remove();
|
||||
PwGroupSearch top = worklist.remove();
|
||||
|
||||
if (pm.isGroupSearchable(top, isOmitBackup)) {
|
||||
for (PwEntry entry : top.getChildEntries()) {
|
||||
for (PwEntrySearch entry : top.getChildEntries()) {
|
||||
processEntries(entry, group.getChildEntries(), qStr, loc);
|
||||
}
|
||||
|
||||
for (PwGroup childGroup : top.getChildGroups()) {
|
||||
for (PwGroupSearch childGroup : top.getChildGroups()) {
|
||||
if (childGroup != null) {
|
||||
worklist.add(childGroup);
|
||||
}
|
||||
@@ -98,7 +92,7 @@ public class SearchDbHelper {
|
||||
return group;
|
||||
}
|
||||
|
||||
public void processEntries(PwEntry entry, List<PwEntry> results, String qStr, Locale loc) {
|
||||
public void processEntries(PwEntrySearch entry, List<PwEntrySearch> results, String qStr, Locale loc) {
|
||||
// Search all strings in the entry
|
||||
Iterator<String> iter = entry.stringIterator();
|
||||
while (iter.hasNext()) {
|
||||
@@ -112,5 +106,19 @@ public class SearchDbHelper {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static class SearchDbHelperV3 extends SearchDbHelper<PwDatabaseV3, PwGroupV3, PwEntryV3>{
|
||||
|
||||
public SearchDbHelperV3(Context ctx) {
|
||||
super(ctx);
|
||||
}
|
||||
}
|
||||
|
||||
public static class SearchDbHelperV4 extends SearchDbHelper<PwDatabaseV4, PwGroupV4, PwEntryV4>{
|
||||
|
||||
public SearchDbHelperV4(Context ctx) {
|
||||
super(ctx);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -156,13 +156,13 @@ public class SprEngineV4 {
|
||||
else if (scan == 'O') { sp.searchInOther = true; }
|
||||
else { return null; }
|
||||
|
||||
List<PwEntry> list = new ArrayList<>();
|
||||
List<PwEntryV4> list = new ArrayList<>();
|
||||
// TODO type parameter
|
||||
EntrySearchV4 entrySearchV4 = new EntrySearchV4((PwGroupV4) ctx.db.getRootGroup());
|
||||
entrySearchV4.searchEntries(sp, list);
|
||||
|
||||
if (list.size() > 0) {
|
||||
return new TargetResult((PwEntryV4)list.get(0), wanted);
|
||||
return new TargetResult(list.get(0), wanted);
|
||||
}
|
||||
|
||||
return null;
|
||||
|
||||
Reference in New Issue
Block a user