From fa731a46235e7d6b46450f339539247d3671514b Mon Sep 17 00:00:00 2001 From: fiaxh Date: Fri, 16 Nov 2018 16:27:31 +0100 Subject: Split login jid/password into two steps with checks --- libdino/src/application.vala | 5 +- libdino/src/entity/account.vala | 2 + libdino/src/service/connection_manager.vala | 4 +- libdino/src/service/registration.vala | 86 ++++++++++++++++++++++++++++- libdino/src/service/stream_interactor.vala | 8 +-- 5 files changed, 96 insertions(+), 9 deletions(-) (limited to 'libdino') diff --git a/libdino/src/application.vala b/libdino/src/application.vala index d307c746..7b19a9e9 100644 --- a/libdino/src/application.vala +++ b/libdino/src/application.vala @@ -40,6 +40,7 @@ public interface Dino.Application : GLib.Application { ContentItemStore.start(stream_interactor, db); NotificationEvents.start(stream_interactor); SearchProcessor.start(stream_interactor, db); + Register.start(stream_interactor, db); create_actions(); @@ -110,11 +111,11 @@ public interface Dino.Application : GLib.Application { } protected void add_connection(Account account) { - stream_interactor.connect(account); + stream_interactor.connect_account(account); } protected void remove_connection(Account account) { - stream_interactor.disconnect(account); + stream_interactor.disconnect_account(account); } private void restore() { diff --git a/libdino/src/entity/account.vala b/libdino/src/entity/account.vala index 111fbf08..f7257b5a 100644 --- a/libdino/src/entity/account.vala +++ b/libdino/src/entity/account.vala @@ -44,6 +44,8 @@ public class Account : Object { } public void persist(Database db) { + if (id > 0) return; + this.db = db; id = (int) db.account.insert() .value(db.account.bare_jid, bare_jid.to_string()) diff --git a/libdino/src/service/connection_manager.vala b/libdino/src/service/connection_manager.vala index 2abbc9cb..6a7964a0 100644 --- a/libdino/src/service/connection_manager.vala +++ b/libdino/src/service/connection_manager.vala @@ -5,7 +5,7 @@ using Dino.Entities; namespace Dino { -public class ConnectionManager { +public class ConnectionManager : Object { public signal void stream_opened(Account account, XmppStream stream); public signal void connection_state_changed(Account account, ConnectionState state); @@ -133,7 +133,7 @@ public class ConnectionManager { connections[account].stream.get_module(Presence.Module.IDENTITY).send_presence(connections[account].stream, presence); } - public void disconnect(Account account) { + public void disconnect_account(Account account) { if (connections.has_key(account)) { make_offline(account); try { diff --git a/libdino/src/service/registration.vala b/libdino/src/service/registration.vala index 32d8b04b..8cac355e 100644 --- a/libdino/src/service/registration.vala +++ b/libdino/src/service/registration.vala @@ -5,12 +5,96 @@ using Dino.Entities; namespace Dino { -public class Register { +public class Register : StreamInteractionModule, Object{ + public static ModuleIdentity IDENTITY = new ModuleIdentity("registration"); + public string id { get { return IDENTITY.id; } } + + private StreamInteractor stream_interactor; + private Database db; + + public static void start(StreamInteractor stream_interactor, Database db) { + Register m = new Register(stream_interactor, db); + stream_interactor.add_module(m); + } + + private Register(StreamInteractor stream_interactor, Database db) { + this.stream_interactor = stream_interactor; + this.db = db; + } + + public async ConnectionManager.ConnectionError.Source? add_check_account(Account account) { + SourceFunc callback = add_check_account.callback; + ConnectionManager.ConnectionError.Source? ret = null; + + ulong handler_id_connected = stream_interactor.stream_negotiated.connect((connected_account, stream) => { + if (connected_account.equals(account)) { + account.persist(db); + account.enabled = true; + Idle.add((owned)callback); + } + }); + ulong handler_id_error = stream_interactor.connection_manager.connection_error.connect((connected_account, error) => { + if (connected_account.equals(account)) { + ret = error.source; + } + stream_interactor.disconnect_account(account); + Idle.add((owned)callback); + }); + + stream_interactor.connect_account(account); + yield; + stream_interactor.disconnect(handler_id_connected); + stream_interactor.connection_manager.disconnect(handler_id_error); + + return ret; + } + + public class ServerAvailabilityReturn { + public bool available { get; set; } + public TlsCertificateFlags? error_flags { get; set; } + } + + public static async ServerAvailabilityReturn check_server_availability(Jid jid) { + XmppStream stream = new XmppStream(); + stream.add_module(new Tls.Module()); + stream.add_module(new Iq.Module()); + stream.add_module(new Xep.SrvRecordsTls.Module()); + + ServerAvailabilityReturn ret = new ServerAvailabilityReturn() { available=false }; + SourceFunc callback = check_server_availability.callback; + stream.stream_negotiated.connect(() => { + if (callback != null) { + ret.available = true; + Idle.add((owned)callback); + } + }); + stream.get_module(Tls.Module.IDENTITY).invalid_certificate.connect((peer_cert, errors) => { + if (callback != null) { + + ret.error_flags = errors; + Idle.add((owned)callback); + } + }); + Timeout.add_seconds(5, () => { + if (callback != null) { + Idle.add((owned)callback); + } + return false; + }); + + stream.connect.begin(jid.domainpart); + yield; + try { + stream.disconnect(); + } catch (Error e) {} + return ret; + } public static async Xep.InBandRegistration.Form get_registration_form(Jid jid) { XmppStream stream = new XmppStream(); stream.add_module(new Tls.Module()); stream.add_module(new Iq.Module()); + stream.add_module(new Xep.SrvRecordsTls.Module()); stream.add_module(new Xep.InBandRegistration.Module()); stream.connect.begin(jid.bare_jid.to_string()); diff --git a/libdino/src/service/stream_interactor.vala b/libdino/src/service/stream_interactor.vala index d9f3f0ec..55ab8984 100644 --- a/libdino/src/service/stream_interactor.vala +++ b/libdino/src/service/stream_interactor.vala @@ -5,7 +5,7 @@ using Dino.Entities; namespace Dino { -public class StreamInteractor { +public class StreamInteractor : Object { public signal void account_added(Account account); public signal void account_removed(Account account); @@ -23,14 +23,14 @@ public class StreamInteractor { connection_manager.stream_opened.connect(on_stream_opened); } - public void connect(Account account) { + public void connect_account(Account account) { module_manager.initialize(account); account_added(account); connection_manager.connect(account); } - public void disconnect(Account account) { - connection_manager.disconnect(account); + public void disconnect_account(Account account) { + connection_manager.disconnect_account(account); account_removed(account); } -- cgit v1.2.3-70-g09d2