Add type parameter to PwObject

This commit is contained in:
J-Jamet
2018-03-28 14:33:00 +02:00
parent a8d07c3e82
commit 9ece794f9a
23 changed files with 464 additions and 424 deletions

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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