mirror of
https://github.com/Kunzisoft/KeePassDX.git
synced 2025-12-04 15:49:33 +01:00
Change clones (To redefine)
This commit is contained in:
@@ -19,10 +19,7 @@
|
|||||||
*/
|
*/
|
||||||
package com.keepassdroid.tests;
|
package com.keepassdroid.tests;
|
||||||
|
|
||||||
import java.util.UUID;
|
import com.keepassdroid.database.AutoType;
|
||||||
|
|
||||||
import junit.framework.TestCase;
|
|
||||||
|
|
||||||
import com.keepassdroid.database.PwEntryV4;
|
import com.keepassdroid.database.PwEntryV4;
|
||||||
import com.keepassdroid.database.PwGroupV4;
|
import com.keepassdroid.database.PwGroupV4;
|
||||||
import com.keepassdroid.database.PwIconCustom;
|
import com.keepassdroid.database.PwIconCustom;
|
||||||
@@ -30,13 +27,17 @@ import com.keepassdroid.database.PwIconStandard;
|
|||||||
import com.keepassdroid.database.security.ProtectedBinary;
|
import com.keepassdroid.database.security.ProtectedBinary;
|
||||||
import com.keepassdroid.database.security.ProtectedString;
|
import com.keepassdroid.database.security.ProtectedString;
|
||||||
|
|
||||||
|
import junit.framework.TestCase;
|
||||||
|
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
public class PwEntryTestV4 extends TestCase {
|
public class PwEntryTestV4 extends TestCase {
|
||||||
public void testAssign() {
|
public void testAssign() {
|
||||||
PwEntryV4 entry = new PwEntryV4();
|
PwEntryV4 entry = new PwEntryV4();
|
||||||
|
|
||||||
entry.setAdditional("test223");
|
entry.setAdditional("test223");
|
||||||
|
|
||||||
entry.setAutoType(entry.new AutoType());
|
entry.setAutoType(new AutoType());
|
||||||
entry.getAutoType().defaultSequence = "1324";
|
entry.getAutoType().defaultSequence = "1324";
|
||||||
entry.getAutoType().enabled = true;
|
entry.getAutoType().enabled = true;
|
||||||
entry.getAutoType().obfuscationOptions = 123412432109L;
|
entry.getAutoType().obfuscationOptions = 123412432109L;
|
||||||
|
|||||||
@@ -25,7 +25,6 @@ import android.content.SharedPreferences;
|
|||||||
import android.preference.PreferenceManager;
|
import android.preference.PreferenceManager;
|
||||||
import android.test.AndroidTestCase;
|
import android.test.AndroidTestCase;
|
||||||
|
|
||||||
import com.kunzisoft.keepass.R;
|
|
||||||
import com.keepassdroid.database.Database;
|
import com.keepassdroid.database.Database;
|
||||||
import com.keepassdroid.database.PwGroup;
|
import com.keepassdroid.database.PwGroup;
|
||||||
import com.keepassdroid.tests.database.TestData;
|
import com.keepassdroid.tests.database.TestData;
|
||||||
@@ -66,7 +65,7 @@ public class SearchTest extends AndroidTestCase {
|
|||||||
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(ctx);
|
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(ctx);
|
||||||
SharedPreferences.Editor editor = prefs.edit();
|
SharedPreferences.Editor editor = prefs.edit();
|
||||||
|
|
||||||
editor.putBoolean(ctx.getString(R.string.settings_omitbackup_key), setting);
|
editor.putBoolean("settings_omitbackup_key", setting);
|
||||||
editor.commit();
|
editor.commit();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -38,10 +38,8 @@ import android.widget.Toast;
|
|||||||
import com.keepassdroid.app.App;
|
import com.keepassdroid.app.App;
|
||||||
import com.keepassdroid.database.Database;
|
import com.keepassdroid.database.Database;
|
||||||
import com.keepassdroid.database.PwDatabase;
|
import com.keepassdroid.database.PwDatabase;
|
||||||
import com.keepassdroid.database.PwDatabaseV4;
|
|
||||||
import com.keepassdroid.database.PwDate;
|
import com.keepassdroid.database.PwDate;
|
||||||
import com.keepassdroid.database.PwEntry;
|
import com.keepassdroid.database.PwEntry;
|
||||||
import com.keepassdroid.database.PwEntryV4;
|
|
||||||
import com.keepassdroid.database.PwGroup;
|
import com.keepassdroid.database.PwGroup;
|
||||||
import com.keepassdroid.database.PwGroupId;
|
import com.keepassdroid.database.PwGroupId;
|
||||||
import com.keepassdroid.database.PwIconStandard;
|
import com.keepassdroid.database.PwIconStandard;
|
||||||
@@ -61,9 +59,6 @@ import com.keepassdroid.utils.Util;
|
|||||||
import com.keepassdroid.view.EntryEditNewField;
|
import com.keepassdroid.view.EntryEditNewField;
|
||||||
import com.kunzisoft.keepass.R;
|
import com.kunzisoft.keepass.R;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.Calendar;
|
|
||||||
import java.util.Date;
|
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
|
|
||||||
@@ -246,22 +241,17 @@ public class EntryEditActivity extends LockingHideActivity
|
|||||||
}
|
}
|
||||||
|
|
||||||
protected PwEntry populateNewEntry() {
|
protected PwEntry populateNewEntry() {
|
||||||
if (mEntry instanceof PwEntryV4) {
|
PwDatabase db = App.getDB().pm;
|
||||||
// TODO backup
|
|
||||||
PwEntryV4 newEntry = (PwEntryV4) mEntry.clone(true);
|
|
||||||
newEntry.setHistory((ArrayList<PwEntryV4>) newEntry.getHistory().clone());
|
|
||||||
newEntry.createBackup((PwDatabaseV4) App.getDB().pm);
|
|
||||||
}
|
|
||||||
|
|
||||||
PwEntry newEntry = mEntry.clone(true);
|
PwEntry newEntry = mEntry.clone();
|
||||||
|
|
||||||
|
newEntry.startToDecodeReference(db);
|
||||||
|
|
||||||
|
newEntry.createBackup(db);
|
||||||
|
|
||||||
newEntry.setLastAccessTime(new PwDate());
|
newEntry.setLastAccessTime(new PwDate());
|
||||||
newEntry.setLastModificationTime(new PwDate());
|
newEntry.setLastModificationTime(new PwDate());
|
||||||
|
|
||||||
PwDatabase db = App.getDB().pm;
|
|
||||||
|
|
||||||
newEntry.startToDecodeReference(db);
|
|
||||||
|
|
||||||
newEntry.setTitle(entryTitleView.getText().toString());
|
newEntry.setTitle(entryTitleView.getText().toString());
|
||||||
if(mSelectedIconID != -1)
|
if(mSelectedIconID != -1)
|
||||||
// or TODO icon factory newEntry.setIcon(App.getDB().pm.iconFactory.getIcon(mSelectedIconID));
|
// or TODO icon factory newEntry.setIcon(App.getDB().pm.iconFactory.getIcon(mSelectedIconID));
|
||||||
|
|||||||
37
app/src/main/java/com/keepassdroid/database/AutoType.java
Normal file
37
app/src/main/java/com/keepassdroid/database/AutoType.java
Normal file
@@ -0,0 +1,37 @@
|
|||||||
|
package com.keepassdroid.database;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
public class AutoType implements Cloneable, Serializable {
|
||||||
|
private static final long OBF_OPT_NONE = 0;
|
||||||
|
|
||||||
|
public boolean enabled = true;
|
||||||
|
public long obfuscationOptions = OBF_OPT_NONE;
|
||||||
|
public String defaultSequence = "";
|
||||||
|
|
||||||
|
private HashMap<String, String> windowSeqPairs = new HashMap<>();
|
||||||
|
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
public AutoType clone() {
|
||||||
|
AutoType auto;
|
||||||
|
try {
|
||||||
|
auto = (AutoType) super.clone();
|
||||||
|
} catch (CloneNotSupportedException e) {
|
||||||
|
throw new RuntimeException(e);
|
||||||
|
}
|
||||||
|
auto.windowSeqPairs = (HashMap<String, String>) windowSeqPairs.clone();
|
||||||
|
return auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void put(String key, String value) {
|
||||||
|
windowSeqPairs.put(key, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Set<Map.Entry<String, String>> entrySet() {
|
||||||
|
return windowSeqPairs.entrySet();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -19,14 +19,14 @@
|
|||||||
*/
|
*/
|
||||||
package com.keepassdroid.database;
|
package com.keepassdroid.database;
|
||||||
|
|
||||||
|
import com.keepassdroid.app.App;
|
||||||
|
import com.keepassdroid.utils.Types;
|
||||||
|
|
||||||
import java.io.Serializable;
|
import java.io.Serializable;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.Calendar;
|
import java.util.Calendar;
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
|
|
||||||
import com.keepassdroid.app.App;
|
|
||||||
import com.keepassdroid.utils.Types;
|
|
||||||
|
|
||||||
/** Converting from the C Date format to the Java data format is
|
/** Converting from the C Date format to the Java data format is
|
||||||
* expensive when done for every record at once. I use this class to
|
* expensive when done for every record at once. I use this class to
|
||||||
* allow lazy conversions between the formats.
|
* allow lazy conversions between the formats.
|
||||||
@@ -115,7 +115,7 @@ public class PwDate implements Cloneable, Serializable {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Object clone() {
|
public PwDate clone() {
|
||||||
PwDate copy = new PwDate();
|
PwDate copy = new PwDate();
|
||||||
|
|
||||||
if ( cDateBuilt ) {
|
if ( cDateBuilt ) {
|
||||||
|
|||||||
@@ -44,22 +44,23 @@ public abstract class PwEntry extends PwNode implements Cloneable {
|
|||||||
throw new RuntimeException("Unknown PwGroup instance.");
|
throw new RuntimeException("Unknown PwGroup instance.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Object clone() {
|
public PwEntry clone() {
|
||||||
PwEntry newEntry;
|
PwEntry newEntry;
|
||||||
try {
|
try {
|
||||||
newEntry = (PwEntry) super.clone();
|
newEntry = (PwEntry) super.clone();
|
||||||
} catch (CloneNotSupportedException e) {
|
} catch (CloneNotSupportedException e) {
|
||||||
throw new RuntimeException("Clone should be supported");
|
throw new RuntimeException("Clone should be supported");
|
||||||
}
|
}
|
||||||
|
|
||||||
return newEntry;
|
return newEntry;
|
||||||
}
|
}
|
||||||
|
|
||||||
public PwEntry clone(boolean deepStrings) {
|
@Override
|
||||||
return (PwEntry) clone();
|
protected void addCloneAttributesToNewEntry(PwEntry newEntry) {
|
||||||
}
|
super.addCloneAttributesToNewEntry(newEntry);
|
||||||
|
newEntry.icon = new PwIconStandard(this.icon);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Type getType() {
|
public Type getType() {
|
||||||
@@ -171,6 +172,11 @@ public abstract class PwEntry extends PwNode implements Cloneable {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a backup of entry
|
||||||
|
*/
|
||||||
|
public void createBackup(PwDatabase db) {}
|
||||||
|
|
||||||
public EntrySearchStringIterator stringIterator() {
|
public EntrySearchStringIterator stringIterator() {
|
||||||
return EntrySearchStringIterator.getInstance(this);
|
return EntrySearchStringIterator.getInstance(this);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -42,10 +42,7 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
|||||||
|
|
||||||
package com.keepassdroid.database;
|
package com.keepassdroid.database;
|
||||||
|
|
||||||
import com.keepassdroid.utils.Types;
|
|
||||||
|
|
||||||
import java.io.UnsupportedEncodingException;
|
import java.io.UnsupportedEncodingException;
|
||||||
import java.util.Random;
|
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
|
|
||||||
|
|
||||||
@@ -68,6 +65,7 @@ import java.util.UUID;
|
|||||||
* @author Naomaru Itoi <nao@phoneid.org>
|
* @author Naomaru Itoi <nao@phoneid.org>
|
||||||
* @author Bill Zwicky <wrzwicky@pobox.com>
|
* @author Bill Zwicky <wrzwicky@pobox.com>
|
||||||
* @author Dominik Reichl <dominik.reichl@t-online.de>
|
* @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 {
|
||||||
|
|
||||||
@@ -81,10 +79,10 @@ public class PwEntryV3 extends PwEntry {
|
|||||||
private PwGroupV3 parent = null;
|
private PwGroupV3 parent = null;
|
||||||
private int groupId;
|
private int groupId;
|
||||||
|
|
||||||
private byte[] uuid;
|
private UUID uuid;
|
||||||
|
private String title;
|
||||||
private String username;
|
private String username;
|
||||||
private byte[] password;
|
private byte[] password;
|
||||||
private String title;
|
|
||||||
private String url;
|
private String url;
|
||||||
private String additional;
|
private String additional;
|
||||||
|
|
||||||
@@ -98,15 +96,74 @@ public class PwEntryV3 extends PwEntry {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public PwEntryV3(PwGroupV3 p) {
|
public PwEntryV3(PwGroupV3 p) {
|
||||||
|
|
||||||
parent = p;
|
parent = p;
|
||||||
groupId = ((PwGroupIdV3)parent.getId()).getId();
|
groupId = ((PwGroupIdV3)parent.getId()).getId(); // TODO remove
|
||||||
|
uuid = UUID.randomUUID();
|
||||||
Random random = new Random();
|
|
||||||
uuid = new byte[16];
|
|
||||||
random.nextBytes(uuid);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void assign(PwEntry source) {
|
||||||
|
if ( ! (source instanceof PwEntryV3) ) {
|
||||||
|
throw new RuntimeException("DB version mix");
|
||||||
|
}
|
||||||
|
super.assign(source);
|
||||||
|
PwEntryV3 src = (PwEntryV3) source;
|
||||||
|
assign(src);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void assign(PwEntryV3 source) {
|
||||||
|
|
||||||
|
parent = source.parent;
|
||||||
|
groupId = source.groupId;
|
||||||
|
|
||||||
|
uuid = source.uuid;
|
||||||
|
title = source.title;
|
||||||
|
username = source.username;
|
||||||
|
int passLen = source.password.length;
|
||||||
|
password = new byte[passLen];
|
||||||
|
System.arraycopy(source.password, 0, password, 0, passLen);
|
||||||
|
url = source.url;
|
||||||
|
additional = source.additional;
|
||||||
|
|
||||||
|
binaryDesc = source.binaryDesc;
|
||||||
|
if ( source.binaryData != null ) {
|
||||||
|
int descLen = source.binaryData.length;
|
||||||
|
binaryData = new byte[descLen];
|
||||||
|
System.arraycopy(source.binaryData, 0, binaryData, 0, descLen);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public PwEntryV3 clone() {
|
||||||
|
PwEntryV3 newEntry = (PwEntryV3) super.clone();
|
||||||
|
|
||||||
|
// Attributes in parent
|
||||||
|
addCloneAttributesToNewEntry(newEntry);
|
||||||
|
|
||||||
|
// Attributes here
|
||||||
|
// newEntry.parent stay the same in copy
|
||||||
|
// newEntry.groupId stay the same in copy
|
||||||
|
// newEntry.uuid stay the same in copy
|
||||||
|
// newEntry.title stay the same in copy
|
||||||
|
// newEntry.username stay the same in copy
|
||||||
|
if (password != null) {
|
||||||
|
int passLen = password.length;
|
||||||
|
password = new byte[passLen];
|
||||||
|
System.arraycopy(password, 0, newEntry.password, 0, passLen);
|
||||||
|
}
|
||||||
|
// newEntry.url stay the same in copy
|
||||||
|
// newEntry.additional stay the same in copy
|
||||||
|
|
||||||
|
// newEntry.binaryDesc stay the same in copy
|
||||||
|
if ( binaryData != null ) {
|
||||||
|
int descLen = binaryData.length;
|
||||||
|
newEntry.binaryData = new byte[descLen];
|
||||||
|
System.arraycopy(binaryData, 0, newEntry.binaryData, 0, descLen);
|
||||||
|
}
|
||||||
|
|
||||||
|
return newEntry;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public PwGroupV3 getParent() {
|
public PwGroupV3 getParent() {
|
||||||
return parent;
|
return parent;
|
||||||
@@ -127,12 +184,12 @@ public class PwEntryV3 extends PwEntry {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public UUID getUUID() {
|
public UUID getUUID() {
|
||||||
return Types.bytestoUUID(uuid);
|
return uuid;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void setUUID(UUID u) {
|
public void setUUID(UUID uuid) {
|
||||||
uuid = Types.UUIDtoBytes(u);
|
this.uuid = uuid;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -192,7 +249,7 @@ public class PwEntryV3 extends PwEntry {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (uuid == null) {
|
if (uuid == null) {
|
||||||
uuid = Types.UUIDtoBytes(UUID.randomUUID());
|
uuid = UUID.randomUUID();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (title == null) {
|
if (title == null) {
|
||||||
@@ -305,74 +362,4 @@ public class PwEntryV3 extends PwEntry {
|
|||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public void assign(PwEntry source) {
|
|
||||||
|
|
||||||
if ( ! (source instanceof PwEntryV3) ) {
|
|
||||||
throw new RuntimeException("DB version mix");
|
|
||||||
}
|
|
||||||
|
|
||||||
super.assign(source);
|
|
||||||
|
|
||||||
PwEntryV3 src = (PwEntryV3) source;
|
|
||||||
assign(src);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void assign(PwEntryV3 source) {
|
|
||||||
title = source.title;
|
|
||||||
url = source.url;
|
|
||||||
groupId = source.groupId;
|
|
||||||
username = source.username;
|
|
||||||
additional = source.additional;
|
|
||||||
uuid = source.uuid;
|
|
||||||
|
|
||||||
int passLen = source.password.length;
|
|
||||||
password = new byte[passLen];
|
|
||||||
System.arraycopy(source.password, 0, password, 0, passLen);
|
|
||||||
|
|
||||||
setCreationTime( (PwDate) source.getCreationTime().clone() );
|
|
||||||
setLastModificationTime( (PwDate) source.getLastModificationTime().clone() );
|
|
||||||
setLastAccessTime( (PwDate) source.getLastAccessTime().clone() );
|
|
||||||
setExpiryTime( (PwDate) source.getExpiryTime().clone() );
|
|
||||||
|
|
||||||
binaryDesc = source.binaryDesc;
|
|
||||||
|
|
||||||
if ( source.binaryData != null ) {
|
|
||||||
int descLen = source.binaryData.length;
|
|
||||||
binaryData = new byte[descLen];
|
|
||||||
System.arraycopy(source.binaryData, 0, binaryData, 0, descLen);
|
|
||||||
}
|
|
||||||
|
|
||||||
parent = source.parent;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Object clone() {
|
|
||||||
PwEntryV3 newEntry = (PwEntryV3) super.clone();
|
|
||||||
|
|
||||||
if (password != null) {
|
|
||||||
int passLen = password.length;
|
|
||||||
password = new byte[passLen];
|
|
||||||
System.arraycopy(password, 0, newEntry.password, 0, passLen);
|
|
||||||
}
|
|
||||||
|
|
||||||
newEntry.setCreationTime( (PwDate) getCreationTime().clone() );
|
|
||||||
newEntry.setLastModificationTime( (PwDate) getLastModificationTime().clone() );
|
|
||||||
newEntry.setLastAccessTime( (PwDate) getLastAccessTime().clone() );
|
|
||||||
newEntry.setExpiryTime( (PwDate) getExpiryTime().clone() );
|
|
||||||
|
|
||||||
newEntry.binaryDesc = binaryDesc;
|
|
||||||
|
|
||||||
if ( binaryData != null ) {
|
|
||||||
int descLen = binaryData.length;
|
|
||||||
newEntry.binaryData = new byte[descLen];
|
|
||||||
System.arraycopy(binaryData, 0, newEntry.binaryData, 0, descLen);
|
|
||||||
}
|
|
||||||
|
|
||||||
newEntry.parent = parent;
|
|
||||||
|
|
||||||
return newEntry;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -23,17 +23,16 @@ import com.keepassdroid.database.security.ProtectedBinary;
|
|||||||
import com.keepassdroid.database.security.ProtectedString;
|
import com.keepassdroid.database.security.ProtectedString;
|
||||||
import com.keepassdroid.utils.SprEngineV4;
|
import com.keepassdroid.utils.SprEngineV4;
|
||||||
|
|
||||||
import java.io.Serializable;
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Map.Entry;
|
import java.util.Map.Entry;
|
||||||
import java.util.Set;
|
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
|
|
||||||
public class PwEntryV4 extends PwEntry implements ITimeLogger {
|
public class PwEntryV4 extends PwEntry implements ITimeLogger {
|
||||||
|
|
||||||
public static final String STR_TITLE = "Title";
|
public static final String STR_TITLE = "Title";
|
||||||
public static final String STR_USERNAME = "UserName";
|
public static final String STR_USERNAME = "UserName";
|
||||||
public static final String STR_PASSWORD = "Password";
|
public static final String STR_PASSWORD = "Password";
|
||||||
@@ -45,7 +44,7 @@ public class PwEntryV4 extends PwEntry implements ITimeLogger {
|
|||||||
private transient boolean mDecodeRef = false;
|
private transient boolean mDecodeRef = false;
|
||||||
|
|
||||||
private PwGroupV4 parent;
|
private PwGroupV4 parent;
|
||||||
private UUID uuid = PwDatabaseV4.UUID_ZERO;
|
private UUID uuid = PwDatabaseV4.UUID_ZERO; // TODO move to parent
|
||||||
private PwIconCustom customIcon = PwIconCustom.ZERO;
|
private PwIconCustom customIcon = PwIconCustom.ZERO;
|
||||||
private long usageCount = 0;
|
private long usageCount = 0;
|
||||||
private PwDate parentGroupLastMod = new PwDate();
|
private PwDate parentGroupLastMod = new PwDate();
|
||||||
@@ -63,41 +62,6 @@ public class PwEntryV4 extends PwEntry implements ITimeLogger {
|
|||||||
private String additional = "";
|
private String additional = "";
|
||||||
private String tags = "";
|
private String tags = "";
|
||||||
|
|
||||||
public class AutoType implements Cloneable, Serializable {
|
|
||||||
private static final long OBF_OPT_NONE = 0;
|
|
||||||
|
|
||||||
public boolean enabled = true;
|
|
||||||
public long obfuscationOptions = OBF_OPT_NONE;
|
|
||||||
public String defaultSequence = "";
|
|
||||||
|
|
||||||
private HashMap<String, String> windowSeqPairs = new HashMap<>();
|
|
||||||
|
|
||||||
@SuppressWarnings("unchecked")
|
|
||||||
public Object clone() {
|
|
||||||
AutoType auto;
|
|
||||||
try {
|
|
||||||
auto = (AutoType) super.clone();
|
|
||||||
}
|
|
||||||
catch (CloneNotSupportedException e) {
|
|
||||||
throw new RuntimeException(e);
|
|
||||||
}
|
|
||||||
|
|
||||||
auto.windowSeqPairs = (HashMap<String, String>) windowSeqPairs.clone();
|
|
||||||
|
|
||||||
return auto;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
public void put(String key, String value) {
|
|
||||||
windowSeqPairs.put(key, value);
|
|
||||||
}
|
|
||||||
|
|
||||||
public Set<Entry<String, String>> entrySet() {
|
|
||||||
return windowSeqPairs.entrySet();
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
public PwEntryV4() {
|
public PwEntryV4() {
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -106,55 +70,63 @@ public class PwEntryV4 extends PwEntry implements ITimeLogger {
|
|||||||
uuid = UUID.randomUUID();
|
uuid = UUID.randomUUID();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void assign(PwEntry source) {
|
||||||
|
if ( ! (source instanceof PwEntryV4) ) {
|
||||||
|
throw new RuntimeException("DB version mix.");
|
||||||
|
}
|
||||||
|
super.assign(source);
|
||||||
|
PwEntryV4 src = (PwEntryV4) source;
|
||||||
|
parent = src.parent;
|
||||||
|
uuid = src.uuid;
|
||||||
|
customIcon = src.customIcon;
|
||||||
|
usageCount = src.usageCount;
|
||||||
|
parentGroupLastMod = src.parentGroupLastMod;
|
||||||
|
// TODO customData
|
||||||
|
|
||||||
@SuppressWarnings("unchecked")
|
fields = src.fields;
|
||||||
@Override
|
binaries = src.binaries;
|
||||||
public PwEntry clone(boolean deepStrings) {
|
foregroundColor = src.foregroundColor;
|
||||||
PwEntryV4 entry = (PwEntryV4) super.clone(deepStrings);
|
backgroupColor = src.backgroupColor;
|
||||||
|
overrideURL = src.overrideURL;
|
||||||
if (deepStrings) {
|
autoType = src.autoType;
|
||||||
entry.fields = (HashMap<String, ProtectedString>) fields.clone();
|
history = src.history;
|
||||||
}
|
|
||||||
|
|
||||||
return entry;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
url = src.url;
|
||||||
public Object clone() {
|
additional = src.additional;
|
||||||
PwEntryV4 newEntry = (PwEntryV4) super.clone();
|
tags = src.tags;
|
||||||
return newEntry;
|
}
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@SuppressWarnings("unchecked")
|
||||||
public void assign(PwEntry source) {
|
@Override
|
||||||
|
public PwEntryV4 clone() {
|
||||||
if ( ! (source instanceof PwEntryV4) ) {
|
PwEntryV4 newEntry = (PwEntryV4) super.clone();
|
||||||
throw new RuntimeException("DB version mix.");
|
|
||||||
}
|
|
||||||
|
|
||||||
super.assign(source);
|
|
||||||
|
|
||||||
PwEntryV4 src = (PwEntryV4) source;
|
|
||||||
assign(src);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void assign(PwEntryV4 source) {
|
// Attributes in parent
|
||||||
super.assign(source);
|
addCloneAttributesToNewEntry(newEntry);
|
||||||
parent = source.parent;
|
|
||||||
uuid = source.uuid;
|
// Attributes here
|
||||||
fields = source.fields;
|
// newEntry.parent stay the same in copy
|
||||||
binaries = source.binaries;
|
// newEntry.uuid stay the same in copy
|
||||||
customIcon = source.customIcon;
|
newEntry.customIcon = new PwIconCustom(this.customIcon);
|
||||||
foregroundColor = source.foregroundColor;
|
// newEntry.usageCount stay the same in copy
|
||||||
backgroupColor = source.backgroupColor;
|
newEntry.parentGroupLastMod = this.parentGroupLastMod.clone();
|
||||||
overrideURL = source.overrideURL;
|
// TODO customData make copy from hashmap
|
||||||
autoType = source.autoType;
|
|
||||||
history = source.history;
|
newEntry.fields = (HashMap<String, ProtectedString>) this.fields.clone();
|
||||||
parentGroupLastMod = source.parentGroupLastMod;
|
newEntry.binaries = (HashMap<String, ProtectedBinary>) this.binaries.clone();
|
||||||
usageCount = source.usageCount;
|
// newEntry.foregroundColor stay the same in copy
|
||||||
url = source.url;
|
// newEntry.backgroupColor stay the same in copy
|
||||||
additional = source.additional;
|
// newEntry.overrideURL stay the same in copy
|
||||||
}
|
newEntry.autoType = autoType.clone();
|
||||||
|
newEntry.history = (ArrayList<PwEntryV4>) this.history.clone();
|
||||||
|
|
||||||
|
// newEntry.url stay the same in copy
|
||||||
|
// newEntry.additional stay the same in copy
|
||||||
|
// newEntry.tags stay the same in copy
|
||||||
|
|
||||||
|
return newEntry;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void startToDecodeReference(PwDatabase db) {
|
public void startToDecodeReference(PwDatabase db) {
|
||||||
@@ -312,74 +284,6 @@ public class PwEntryV4 extends PwEntry implements ITimeLogger {
|
|||||||
return customIcon;
|
return customIcon;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void createBackup(PwDatabaseV4 db) {
|
|
||||||
PwEntryV4 copy = cloneDeep();
|
|
||||||
copy.history = new ArrayList<>();
|
|
||||||
history.add(copy);
|
|
||||||
|
|
||||||
if (db != null) maintainBackups(db);
|
|
||||||
}
|
|
||||||
|
|
||||||
@SuppressWarnings("unchecked")
|
|
||||||
public PwEntryV4 cloneDeep() {
|
|
||||||
PwEntryV4 entry = (PwEntryV4) clone(true);
|
|
||||||
|
|
||||||
entry.binaries = (HashMap<String, ProtectedBinary>) binaries.clone();
|
|
||||||
entry.history = (ArrayList<PwEntryV4>) history.clone();
|
|
||||||
entry.autoType = (AutoType) autoType.clone();
|
|
||||||
|
|
||||||
return entry;
|
|
||||||
}
|
|
||||||
|
|
||||||
private boolean maintainBackups(PwDatabaseV4 db) {
|
|
||||||
boolean deleted = false;
|
|
||||||
|
|
||||||
int maxItems = db.historyMaxItems;
|
|
||||||
if (maxItems >= 0) {
|
|
||||||
while (history.size() > maxItems) {
|
|
||||||
removeOldestBackup();
|
|
||||||
deleted = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
long maxSize = db.historyMaxSize;
|
|
||||||
if (maxSize >= 0) {
|
|
||||||
while(true) {
|
|
||||||
long histSize = 0;
|
|
||||||
for (PwEntryV4 entry : history) {
|
|
||||||
histSize += entry.getSize();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (histSize > maxSize) {
|
|
||||||
removeOldestBackup();
|
|
||||||
deleted = true;
|
|
||||||
} else {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return deleted;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void removeOldestBackup() {
|
|
||||||
Date min = null;
|
|
||||||
int index = -1;
|
|
||||||
|
|
||||||
for (int i = 0; i < history.size(); i++) {
|
|
||||||
PwEntry entry = history.get(i);
|
|
||||||
Date lastMod = entry.getLastModificationTime().getDate();
|
|
||||||
if ((min == null) || lastMod.before(min)) {
|
|
||||||
index = i;
|
|
||||||
min = lastMod;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (index != -1) {
|
|
||||||
history.remove(index);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean allowExtraFields() {
|
public boolean allowExtraFields() {
|
||||||
@@ -396,7 +300,7 @@ public class PwEntryV4 extends PwEntry implements ITimeLogger {
|
|||||||
if (fields.size() > 0) {
|
if (fields.size() > 0) {
|
||||||
for (Map.Entry<String, ProtectedString> pair : fields.entrySet()) {
|
for (Map.Entry<String, ProtectedString> pair : fields.entrySet()) {
|
||||||
String key = pair.getKey();
|
String key = pair.getKey();
|
||||||
if (!PwEntryV4.IsStandardField(key)) {
|
if (!PwEntryV4.isStandardField(key)) {
|
||||||
protectedFields.put(key, pair.getValue());
|
protectedFields.put(key, pair.getValue());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -413,7 +317,7 @@ public class PwEntryV4 extends PwEntry implements ITimeLogger {
|
|||||||
for (Map.Entry<String, ProtectedString> pair : fields.entrySet()) {
|
for (Map.Entry<String, ProtectedString> pair : fields.entrySet()) {
|
||||||
String key = pair.getKey();
|
String key = pair.getKey();
|
||||||
// TODO Add hidden style for protection field
|
// TODO Add hidden style for protection field
|
||||||
if (!PwEntryV4.IsStandardField(key)) {
|
if (!PwEntryV4.isStandardField(key)) {
|
||||||
extraFields.put(key, spr.compile(pair.getValue().toString(), this, mDatabase));
|
extraFields.put(key, spr.compile(pair.getValue().toString(), this, mDatabase));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -421,7 +325,7 @@ public class PwEntryV4 extends PwEntry implements ITimeLogger {
|
|||||||
return extraFields;
|
return extraFields;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static boolean IsStandardField(String key) {
|
private static boolean isStandardField(String key) {
|
||||||
return key.equals(STR_TITLE) || key.equals(STR_USERNAME)
|
return key.equals(STR_TITLE) || key.equals(STR_USERNAME)
|
||||||
|| key.equals(STR_PASSWORD) || key.equals(STR_URL)
|
|| key.equals(STR_PASSWORD) || key.equals(STR_URL)
|
||||||
|| key.equals(STR_NOTES);
|
|| key.equals(STR_NOTES);
|
||||||
@@ -436,7 +340,7 @@ public class PwEntryV4 extends PwEntry implements ITimeLogger {
|
|||||||
Iterator<Entry<String, ProtectedString>> iter = fields.entrySet().iterator();
|
Iterator<Entry<String, ProtectedString>> iter = fields.entrySet().iterator();
|
||||||
while (iter.hasNext()) {
|
while (iter.hasNext()) {
|
||||||
Map.Entry<String, ProtectedString> pair = iter.next();
|
Map.Entry<String, ProtectedString> pair = iter.next();
|
||||||
if (!PwEntryV4.IsStandardField(pair.getKey())) {
|
if (!PwEntryV4.isStandardField(pair.getKey())) {
|
||||||
iter.remove();
|
iter.remove();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -498,10 +402,6 @@ public class PwEntryV4 extends PwEntry implements ITimeLogger {
|
|||||||
return history.size();
|
return history.size();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static String getStrTitle() {
|
|
||||||
return STR_TITLE;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getAdditional() {
|
public String getAdditional() {
|
||||||
return additional;
|
return additional;
|
||||||
}
|
}
|
||||||
@@ -556,6 +456,68 @@ public class PwEntryV4 extends PwEntry implements ITimeLogger {
|
|||||||
return size;
|
return size;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void createBackup(PwDatabase db) {
|
||||||
|
super.createBackup(db);
|
||||||
|
|
||||||
|
PwEntryV4 copy = clone();
|
||||||
|
copy.history = new ArrayList<>();
|
||||||
|
history.add(copy);
|
||||||
|
|
||||||
|
if (db != null)
|
||||||
|
if (db instanceof PwDatabaseV4)
|
||||||
|
maintainBackups((PwDatabaseV4) db);
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean maintainBackups(PwDatabaseV4 db) {
|
||||||
|
boolean deleted = false;
|
||||||
|
|
||||||
|
int maxItems = db.historyMaxItems;
|
||||||
|
if (maxItems >= 0) {
|
||||||
|
while (history.size() > maxItems) {
|
||||||
|
removeOldestBackup();
|
||||||
|
deleted = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
long maxSize = db.historyMaxSize;
|
||||||
|
if (maxSize >= 0) {
|
||||||
|
while(true) {
|
||||||
|
long histSize = 0;
|
||||||
|
for (PwEntryV4 entry : history) {
|
||||||
|
histSize += entry.getSize();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (histSize > maxSize) {
|
||||||
|
removeOldestBackup();
|
||||||
|
deleted = true;
|
||||||
|
} else {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return deleted;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void removeOldestBackup() {
|
||||||
|
Date min = null;
|
||||||
|
int index = -1;
|
||||||
|
|
||||||
|
for (int i = 0; i < history.size(); i++) {
|
||||||
|
PwEntry entry = history.get(i);
|
||||||
|
Date lastMod = entry.getLastModificationTime().getDate();
|
||||||
|
if ((min == null) || lastMod.before(min)) {
|
||||||
|
index = i;
|
||||||
|
min = lastMod;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (index != -1) {
|
||||||
|
history.remove(index);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void touch(boolean modified, boolean touchParents) {
|
public void touch(boolean modified, boolean touchParents) {
|
||||||
super.touch(modified, touchParents);
|
super.touch(modified, touchParents);
|
||||||
@@ -572,7 +534,6 @@ public class PwEntryV4 extends PwEntry implements ITimeLogger {
|
|||||||
if (parent != null) {
|
if (parent != null) {
|
||||||
return parent.isSearchEnabled();
|
return parent.isSearchEnabled();
|
||||||
}
|
}
|
||||||
|
|
||||||
return PwGroupV4.DEFAULT_SEARCHING_ENABLED;
|
return PwGroupV4.DEFAULT_SEARCHING_ENABLED;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -35,7 +35,6 @@ public abstract class PwGroup extends PwNode {
|
|||||||
|
|
||||||
protected List<PwGroup> childGroups = new ArrayList<>();
|
protected List<PwGroup> childGroups = new ArrayList<>();
|
||||||
protected List<PwEntry> childEntries = new ArrayList<>();
|
protected List<PwEntry> childEntries = new ArrayList<>();
|
||||||
private transient List<PwNode> children = new ArrayList<>();
|
|
||||||
|
|
||||||
public void initNewGroup(String nm, PwGroupId newId) {
|
public void initNewGroup(String nm, PwGroupId newId) {
|
||||||
setId(newId);
|
setId(newId);
|
||||||
@@ -101,7 +100,7 @@ public abstract class PwGroup extends PwNode {
|
|||||||
* @return List of direct children (one level below) as PwNode
|
* @return List of direct children (one level below) as PwNode
|
||||||
*/
|
*/
|
||||||
public List<PwNode> getDirectChildren() {
|
public List<PwNode> getDirectChildren() {
|
||||||
children.clear();
|
List<PwNode> children = new ArrayList<>();
|
||||||
children.addAll(childGroups);
|
children.addAll(childGroups);
|
||||||
for(PwEntry child : childEntries) {
|
for(PwEntry child : childEntries) {
|
||||||
if (!child.isMetaStream())
|
if (!child.isMetaStream())
|
||||||
@@ -110,14 +109,6 @@ public abstract class PwGroup extends PwNode {
|
|||||||
return children;
|
return children;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Number of direct elements in Node (one level below)
|
|
||||||
* @return Size of child elements, default is 0
|
|
||||||
*/
|
|
||||||
public int numberOfDirectChildren() {
|
|
||||||
return childGroups.size() + childEntries.size();
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean isContainedIn(PwGroup container) {
|
public boolean isContainedIn(PwGroup container) {
|
||||||
PwGroup cur = this;
|
PwGroup cur = this;
|
||||||
while (cur != null) {
|
while (cur != null) {
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ package com.keepassdroid.database;
|
|||||||
import java.io.Serializable;
|
import java.io.Serializable;
|
||||||
|
|
||||||
public abstract class PwIcon implements Serializable {
|
public abstract class PwIcon implements Serializable {
|
||||||
|
|
||||||
public boolean isMetaStreamIcon() {
|
public boolean isMetaStreamIcon() {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -32,6 +32,11 @@ public class PwIconCustom extends PwIcon {
|
|||||||
imageData = data;
|
imageData = data;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public PwIconCustom(PwIconCustom icon) {
|
||||||
|
uuid = icon.uuid;
|
||||||
|
imageData = icon.imageData;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int hashCode() {
|
public int hashCode() {
|
||||||
final int prime = 31;
|
final int prime = 31;
|
||||||
|
|||||||
@@ -32,6 +32,10 @@ public class PwIconStandard extends PwIcon {
|
|||||||
this.iconId = iconId;
|
this.iconId = iconId;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public PwIconStandard(PwIconStandard icon) {
|
||||||
|
this.iconId = icon.iconId;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isMetaStreamIcon() {
|
public boolean isMetaStreamIcon() {
|
||||||
return iconId == 0;
|
return iconId == 0;
|
||||||
|
|||||||
@@ -30,10 +30,17 @@ import static com.keepassdroid.database.PwDate.PW_NEVER_EXPIRE;
|
|||||||
*/
|
*/
|
||||||
public abstract class PwNode implements ISmallTimeLogger, Serializable {
|
public abstract class PwNode implements ISmallTimeLogger, Serializable {
|
||||||
|
|
||||||
private PwDate creation = new PwDate();
|
protected PwDate creation = new PwDate();
|
||||||
private PwDate lastMod = new PwDate();
|
protected PwDate lastMod = new PwDate();
|
||||||
private PwDate lastAccess = new PwDate();
|
protected PwDate lastAccess = new PwDate();
|
||||||
private PwDate expireDate = new PwDate(NEVER_EXPIRE);
|
protected PwDate expireDate = new PwDate(NEVER_EXPIRE);
|
||||||
|
|
||||||
|
protected void addCloneAttributesToNewEntry(PwEntry newEntry) {
|
||||||
|
newEntry.creation = creation.clone();
|
||||||
|
newEntry.lastMod = lastMod.clone();
|
||||||
|
newEntry.lastAccess = lastAccess.clone();
|
||||||
|
newEntry.expireDate = expireDate.clone();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Type of available Nodes
|
* Type of available Nodes
|
||||||
|
|||||||
@@ -40,7 +40,7 @@ public class UpdateEntry extends RunnableOnFinish {
|
|||||||
|
|
||||||
// Keep backup of original values in case save fails
|
// Keep backup of original values in case save fails
|
||||||
PwEntry backup;
|
PwEntry backup;
|
||||||
backup = (PwEntry) mOldE.clone();
|
backup = mOldE.clone();
|
||||||
|
|
||||||
mFinish = new AfterUpdate(backup, finish);
|
mFinish = new AfterUpdate(backup, finish);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -40,7 +40,7 @@ import com.keepassdroid.database.PwDefsV4;
|
|||||||
import com.keepassdroid.database.PwDeletedObject;
|
import com.keepassdroid.database.PwDeletedObject;
|
||||||
import com.keepassdroid.database.PwEntry;
|
import com.keepassdroid.database.PwEntry;
|
||||||
import com.keepassdroid.database.PwEntryV4;
|
import com.keepassdroid.database.PwEntryV4;
|
||||||
import com.keepassdroid.database.PwEntryV4.AutoType;
|
import com.keepassdroid.database.AutoType;
|
||||||
import com.keepassdroid.database.PwGroup;
|
import com.keepassdroid.database.PwGroup;
|
||||||
import com.keepassdroid.database.PwGroupV4;
|
import com.keepassdroid.database.PwGroupV4;
|
||||||
import com.keepassdroid.database.PwIconCustom;
|
import com.keepassdroid.database.PwIconCustom;
|
||||||
|
|||||||
Reference in New Issue
Block a user