diff options
author | Marvin W <git@larma.de> | 2018-11-10 08:05:14 -0600 |
---|---|---|
committer | Marvin W <git@larma.de> | 2018-11-10 08:05:14 -0600 |
commit | dfb75e2cda1eb9edbbdd9ea88c131d9cb31742ed (patch) | |
tree | d3c1ae4251844239eb46e57c8eacf03466aed608 /plugins/omemo/src/database.vala | |
parent | 559bbc5ca3ad5d44ea949788005a29fe9d86a232 (diff) | |
parent | 65a12021bc7abbf5ddea068ffe9b4715cfc34f0b (diff) | |
download | dino-dfb75e2cda1eb9edbbdd9ea88c131d9cb31742ed.tar.gz dino-dfb75e2cda1eb9edbbdd9ea88c131d9cb31742ed.zip |
Merge PR #413 "Improvements to the OMEMO plugin"
Diffstat (limited to 'plugins/omemo/src/database.vala')
-rw-r--r-- | plugins/omemo/src/database.vala | 109 |
1 files changed, 96 insertions, 13 deletions
diff --git a/plugins/omemo/src/database.vala b/plugins/omemo/src/database.vala index 5c7309f3..247c00f6 100644 --- a/plugins/omemo/src/database.vala +++ b/plugins/omemo/src/database.vala @@ -6,31 +6,47 @@ using Dino.Entities; namespace Dino.Plugins.Omemo { public class Database : Qlite.Database { - private const int VERSION = 1; + private const int VERSION = 2; public class IdentityMetaTable : Table { + public enum TrustLevel { + VERIFIED, + TRUSTED, + UNTRUSTED, + UNKNOWN; + + public string to_string() { + int val = this; + return val.to_string(); + } + } + + //Default to provide backwards compatability + public Column<int> identity_id = new Column.Integer("identity_id") { not_null = true, min_version = 2, default = "-1" }; public Column<string> address_name = new Column.Text("address_name") { not_null = true }; public Column<int> device_id = new Column.Integer("device_id") { not_null = true }; public Column<string?> identity_key_public_base64 = new Column.Text("identity_key_public_base64"); - public Column<bool> trusted_identity = new Column.BoolInt("trusted_identity") { default = "0" }; + public Column<bool> trusted_identity = new Column.BoolInt("trusted_identity") { default = "0", max_version = 1 }; + public Column<int> trust_level = new Column.Integer("trust_level") { default = TrustLevel.UNKNOWN.to_string(), min_version = 2 }; public Column<bool> now_active = new Column.BoolInt("now_active") { default = "1" }; public Column<long> last_active = new Column.Long("last_active"); internal IdentityMetaTable(Database db) { base(db, "identity_meta"); - init({address_name, device_id, identity_key_public_base64, trusted_identity, now_active, last_active}); - index("identity_meta_idx", {address_name, device_id}, true); - index("identity_meta_list_idx", {address_name}); + init({identity_id, address_name, device_id, identity_key_public_base64, trusted_identity, trust_level, now_active, last_active}); + index("identity_meta_idx", {identity_id, address_name, device_id}, true); + index("identity_meta_list_idx", {identity_id, address_name}); } - public QueryBuilder with_address(string address_name) { - return select().with(this.address_name, "=", address_name); + public QueryBuilder with_address(int identity_id, string address_name) { + return select().with(this.identity_id, "=", identity_id).with(this.address_name, "=", address_name); } - public void insert_device_list(string address_name, ArrayList<int32> devices) { - update().with(this.address_name, "=", address_name).set(now_active, false).perform(); + public void insert_device_list(int32 identity_id, string address_name, ArrayList<int32> devices) { + update().with(this.identity_id, "=", identity_id).with(this.address_name, "=", address_name).set(now_active, false).perform(); foreach (int32 device_id in devices) { upsert() + .value(this.identity_id, identity_id, true) .value(this.address_name, address_name, true) .value(this.device_id, device_id, true) .value(this.now_active, true) @@ -39,13 +55,61 @@ public class Database : Qlite.Database { } } - public int64 insert_device_bundle(string address_name, int device_id, Bundle bundle) { + public int64 insert_device_bundle(int32 identity_id, string address_name, int device_id, Bundle bundle, TrustLevel trust) { if (bundle == null || bundle.identity_key == null) return -1; return upsert() + .value(this.identity_id, identity_id, true) .value(this.address_name, address_name, true) .value(this.device_id, device_id, true) .value(this.identity_key_public_base64, Base64.encode(bundle.identity_key.serialize())) - .perform(); + .value(this.trust_level, trust).perform(); + } + + public QueryBuilder get_trusted_devices(int identity_id, string address_name) { + return this.with_address(identity_id, address_name) + .with(this.trust_level, "!=", TrustLevel.UNTRUSTED) + .with(this.now_active, "=", true); + } + + public QueryBuilder get_known_devices(int identity_id, string address_name) { + return this.with_address(identity_id, address_name) + .with(this.trust_level, "!=", TrustLevel.UNKNOWN) + .without_null(this.identity_key_public_base64); + } + + public QueryBuilder get_unknown_devices(int identity_id, string address_name) { + return this.with_address(identity_id, address_name) + .with_null(this.identity_key_public_base64); + } + + public QueryBuilder get_new_devices(int identity_id, string address_name) { + return this.with_address(identity_id, address_name) + .with(this.trust_level, "=", TrustLevel.UNKNOWN) + .without_null(this.identity_key_public_base64); + } + + public Row? get_device(int identity_id, string address_name, int device_id) { + return this.with_address(identity_id, address_name) + .with(this.device_id, "=", device_id).single().row().inner; + } + } + + + public class TrustTable : Table { + public Column<int> identity_id = new Column.Integer("identity_id") { not_null = true }; + public Column<string> address_name = new Column.Text("address_name"); + public Column<bool> blind_trust = new Column.BoolInt("blind_trust") { default = "1" } ; + + internal TrustTable(Database db) { + base(db, "trust"); + init({identity_id, address_name, blind_trust}); + index("trust_idx", {identity_id, address_name}, true); + } + + public bool get_blind_trust(int32 identity_id, string address_name) { + return this.select().with(this.identity_id, "=", identity_id) + .with(this.address_name, "=", address_name) + .with(this.blind_trust, "=", true).count() > 0; } } @@ -60,6 +124,13 @@ public class Database : Qlite.Database { base(db, "identity"); init({id, account_id, device_id, identity_key_private_base64, identity_key_public_base64}); } + + public int get_id(int account_id) { + int id = -1; + Row? row = this.row_with(this.account_id, account_id).inner; + if (row != null) id = ((!)row)[this.id]; + return id; + } } public class SignedPreKeyTable : Table { @@ -103,6 +174,7 @@ public class Database : Qlite.Database { } public IdentityMetaTable identity_meta { get; private set; } + public TrustTable trust { get; private set; } public IdentityTable identity { get; private set; } public SignedPreKeyTable signed_pre_key { get; private set; } public PreKeyTable pre_key { get; private set; } @@ -111,18 +183,29 @@ public class Database : Qlite.Database { public Database(string fileName) { base(fileName, VERSION); identity_meta = new IdentityMetaTable(this); + trust = new TrustTable(this); identity = new IdentityTable(this); signed_pre_key = new SignedPreKeyTable(this); pre_key = new PreKeyTable(this); session = new SessionTable(this); - init({identity_meta, identity, signed_pre_key, pre_key, session}); + init({identity_meta, trust, identity, signed_pre_key, pre_key, session}); try { exec("PRAGMA synchronous=0"); } catch (Error e) { } } public override void migrate(long oldVersion) { - // new table columns are added, outdated columns are still present + if(oldVersion == 1) { + try { + exec("DROP INDEX identity_meta_idx"); + exec("DROP INDEX identity_meta_list_idx"); + exec("CREATE UNIQUE INDEX identity_meta_idx ON identity_meta (identity_id, address_name, device_id)"); + exec("CREATE INDEX identity_meta_list_idx ON identity_meta (identity_id, address_name)"); + } catch (Error e) { + stderr.printf("Failed to migrate OMEMO database\n"); + Process.exit(-1); + } + } } } |