From ef20cd297b5609e31b17f02a63624b8d080427e7 Mon Sep 17 00:00:00 2001
From: Janne Koschinski <janne@kuschku.de>
Date: Thu, 10 Jan 2019 13:56:09 +0100
Subject: [PATCH] Make the lib more reusable, prepare for desktop UI

---
 .../ssl/QuasselHostnameVerifier.kt            |  1 +
 .../ui/chat/info/core/CoreInfoFragment.kt     |  2 +-
 desktop/build.gradle.kts                      | 39 ++++++++++++
 .../java/de/kuschku/desktop/CliArguments.kt   | 59 +++++++++++++++++++
 .../src/main/java/de/kuschku/desktop/Main.kt  | 27 +++++++++
 .../libquassel/connection/CoreConnection.kt   | 14 +++--
 .../kuschku/libquassel/protocol/ClientData.kt | 15 ++++-
 .../quassel/syncables/BacklogManager.kt       | 14 ++---
 .../quassel/syncables/BufferSyncer.kt         |  2 +-
 .../quassel/syncables/RpcHandler.kt           |  6 +-
 .../libquassel/session/ProtocolHandler.kt     |  8 +--
 .../de/kuschku/libquassel/session/Session.kt  | 33 ++++++-----
 .../libquassel/session/SessionManager.kt      | 12 ++--
 .../ssl/BrowserCompatibleHostnameVerifier.kt  |  4 +-
 .../ssl/TrustAllHostnameVerifier.kt           | 28 +++++++++
 .../kuschku/libquassel/ssl/TrustManagers.kt   | 43 ++++++++++++++
 .../de/kuschku/libquassel}/ssl/X509Helper.kt  |  5 +-
 settings.gradle                               |  4 +-
 18 files changed, 268 insertions(+), 48 deletions(-)
 create mode 100644 desktop/build.gradle.kts
 create mode 100644 desktop/src/main/java/de/kuschku/desktop/CliArguments.kt
 create mode 100644 desktop/src/main/java/de/kuschku/desktop/Main.kt
 rename {app/src/main/java/de/kuschku/quasseldroid => lib/src/main/java/de/kuschku/libquassel}/ssl/BrowserCompatibleHostnameVerifier.kt (96%)
 create mode 100644 lib/src/main/java/de/kuschku/libquassel/ssl/TrustAllHostnameVerifier.kt
 create mode 100644 lib/src/main/java/de/kuschku/libquassel/ssl/TrustManagers.kt
 rename {app/src/main/java/de/kuschku/quasseldroid => lib/src/main/java/de/kuschku/libquassel}/ssl/X509Helper.kt (96%)

diff --git a/app/src/main/java/de/kuschku/quasseldroid/ssl/QuasselHostnameVerifier.kt b/app/src/main/java/de/kuschku/quasseldroid/ssl/QuasselHostnameVerifier.kt
index 4f6ec01b9..9b94a3ca5 100644
--- a/app/src/main/java/de/kuschku/quasseldroid/ssl/QuasselHostnameVerifier.kt
+++ b/app/src/main/java/de/kuschku/quasseldroid/ssl/QuasselHostnameVerifier.kt
@@ -22,6 +22,7 @@ package de.kuschku.quasseldroid.ssl
 import de.kuschku.libquassel.connection.HostnameVerifier
 import de.kuschku.libquassel.connection.QuasselSecurityException
 import de.kuschku.libquassel.connection.SocketAddress
+import de.kuschku.libquassel.ssl.BrowserCompatibleHostnameVerifier
 import de.kuschku.quasseldroid.ssl.custom.QuasselHostnameManager
 import java.security.cert.X509Certificate
 import javax.net.ssl.SSLException
diff --git a/app/src/main/java/de/kuschku/quasseldroid/ui/chat/info/core/CoreInfoFragment.kt b/app/src/main/java/de/kuschku/quasseldroid/ui/chat/info/core/CoreInfoFragment.kt
index 65330355e..86f7f5ff1 100644
--- a/app/src/main/java/de/kuschku/quasseldroid/ui/chat/info/core/CoreInfoFragment.kt
+++ b/app/src/main/java/de/kuschku/quasseldroid/ui/chat/info/core/CoreInfoFragment.kt
@@ -33,9 +33,9 @@ import androidx.recyclerview.widget.RecyclerView
 import butterknife.BindView
 import butterknife.ButterKnife
 import de.kuschku.libquassel.quassel.QuasselFeatures
+import de.kuschku.libquassel.ssl.X509Helper
 import de.kuschku.libquassel.util.helpers.value
 import de.kuschku.quasseldroid.R
-import de.kuschku.quasseldroid.ssl.X509Helper
 import de.kuschku.quasseldroid.util.helper.*
 import de.kuschku.quasseldroid.util.missingfeatures.MissingFeature
 import de.kuschku.quasseldroid.util.missingfeatures.MissingFeaturesDialog
diff --git a/desktop/build.gradle.kts b/desktop/build.gradle.kts
new file mode 100644
index 000000000..88efe8d89
--- /dev/null
+++ b/desktop/build.gradle.kts
@@ -0,0 +1,39 @@
+/*
+ * Quasseldroid - Quassel client for Android
+ *
+ * Copyright (c) 2019 Janne Koschinski
+ * Copyright (c) 2019 The Quassel Project
+ *
+ * This program is free software: you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 3 as published
+ * by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+plugins {
+  application
+  kotlin("jvm")
+  kotlin("kapt")
+}
+
+application {
+  mainClassName = "de.kuschku.cli.MainKt"
+}
+
+dependencies {
+  implementation(kotlin("stdlib", "1.3.11"))
+
+  implementation("io.reactivex.rxjava2", "rxjava", "2.1.9")
+  implementation("info.picocli", "picocli", "3.9.0")
+
+  implementation(project(":lib"))
+
+  testImplementation("junit", "junit", "4.12")
+}
diff --git a/desktop/src/main/java/de/kuschku/desktop/CliArguments.kt b/desktop/src/main/java/de/kuschku/desktop/CliArguments.kt
new file mode 100644
index 000000000..c1b577e84
--- /dev/null
+++ b/desktop/src/main/java/de/kuschku/desktop/CliArguments.kt
@@ -0,0 +1,59 @@
+/*
+ * Quasseldroid - Quassel client for Android
+ *
+ * Copyright (c) 2019 Janne Koschinski
+ * Copyright (c) 2019 The Quassel Project
+ *
+ * This program is free software: you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 3 as published
+ * by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+package de.kuschku.desktop
+
+import picocli.CommandLine
+
+class CliArguments {
+  @CommandLine.Option(names = ["--user"])
+  var user: String = ""
+  @CommandLine.Option(names = ["--pass"])
+  var pass: String = ""
+  @CommandLine.Option(names = ["--host"])
+  var host: String = ""
+  @CommandLine.Option(names = ["--port"])
+  var port: Int = 4242
+
+  override fun toString(): String {
+    return "CliArguments(user='$user', pass='$pass', host='$host', port='$port')"
+  }
+
+  override fun equals(other: Any?): Boolean {
+    if (this === other) return true
+    if (javaClass != other?.javaClass) return false
+
+    other as CliArguments
+
+    if (user != other.user) return false
+    if (pass != other.pass) return false
+    if (host != other.host) return false
+    if (port != other.port) return false
+
+    return true
+  }
+
+  override fun hashCode(): Int {
+    var result = user.hashCode()
+    result = 31 * result + pass.hashCode()
+    result = 31 * result + host.hashCode()
+    result = 31 * result + port.hashCode()
+    return result
+  }
+}
diff --git a/desktop/src/main/java/de/kuschku/desktop/Main.kt b/desktop/src/main/java/de/kuschku/desktop/Main.kt
new file mode 100644
index 000000000..d521760f1
--- /dev/null
+++ b/desktop/src/main/java/de/kuschku/desktop/Main.kt
@@ -0,0 +1,27 @@
+/*
+ * Quasseldroid - Quassel client for Android
+ *
+ * Copyright (c) 2019 Janne Koschinski
+ * Copyright (c) 2019 The Quassel Project
+ *
+ * This program is free software: you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 3 as published
+ * by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+package de.kuschku.desktop
+
+import picocli.CommandLine
+
+fun main(vararg args: String) {
+  val cliArguments = CliArguments()
+  CommandLine(cliArguments).parse(*args)
+}
diff --git a/lib/src/main/java/de/kuschku/libquassel/connection/CoreConnection.kt b/lib/src/main/java/de/kuschku/libquassel/connection/CoreConnection.kt
index 6b2f08735..fd50ab783 100644
--- a/lib/src/main/java/de/kuschku/libquassel/connection/CoreConnection.kt
+++ b/lib/src/main/java/de/kuschku/libquassel/connection/CoreConnection.kt
@@ -27,13 +27,17 @@ import de.kuschku.libquassel.protocol.primitive.serializer.IntSerializer
 import de.kuschku.libquassel.protocol.primitive.serializer.ProtocolInfoSerializer
 import de.kuschku.libquassel.protocol.primitive.serializer.VariantListSerializer
 import de.kuschku.libquassel.quassel.ProtocolFeature
+import de.kuschku.libquassel.quassel.QuasselFeatures
 import de.kuschku.libquassel.session.ProtocolHandler
+import de.kuschku.libquassel.ssl.BrowserCompatibleHostnameVerifier
+import de.kuschku.libquassel.ssl.TrustManagers
 import de.kuschku.libquassel.util.Optional
 import de.kuschku.libquassel.util.compatibility.CompatibilityUtils
 import de.kuschku.libquassel.util.compatibility.HandlerService
 import de.kuschku.libquassel.util.compatibility.LoggingHandler.Companion.log
 import de.kuschku.libquassel.util.compatibility.LoggingHandler.LogLevel.DEBUG
 import de.kuschku.libquassel.util.compatibility.LoggingHandler.LogLevel.WARN
+import de.kuschku.libquassel.util.compatibility.reference.JavaHandlerService
 import de.kuschku.libquassel.util.flag.hasFlag
 import de.kuschku.libquassel.util.helpers.hexDump
 import de.kuschku.libquassel.util.helpers.write
@@ -49,12 +53,12 @@ import javax.net.ssl.SSLSession
 import javax.net.ssl.X509TrustManager
 
 class CoreConnection(
-  private val clientData: ClientData,
-  private val features: Features,
-  private val trustManager: X509TrustManager,
-  private val hostnameVerifier: HostnameVerifier,
   private val address: SocketAddress,
-  private val handlerService: HandlerService
+  private val clientData: ClientData = ClientData.DEFAULT,
+  private val features: Features = Features(clientData.clientFeatures, QuasselFeatures.empty()),
+  private val handlerService: HandlerService = JavaHandlerService(),
+  private val trustManager: X509TrustManager = TrustManagers.default(),
+  private val hostnameVerifier: HostnameVerifier = BrowserCompatibleHostnameVerifier()
 ) : Thread(), Closeable {
   companion object {
     private const val TAG = "CoreConnection"
diff --git a/lib/src/main/java/de/kuschku/libquassel/protocol/ClientData.kt b/lib/src/main/java/de/kuschku/libquassel/protocol/ClientData.kt
index 1a39495f9..5b48da237 100644
--- a/lib/src/main/java/de/kuschku/libquassel/protocol/ClientData.kt
+++ b/lib/src/main/java/de/kuschku/libquassel/protocol/ClientData.kt
@@ -28,4 +28,17 @@ data class ClientData(
   val clientFeatures: QuasselFeatures,
   val protocolFeatures: Protocol_Features,
   val supportedProtocols: List<Protocol>
-)
+) {
+  companion object {
+    val DEFAULT = ClientData(
+      identifier = "libquassel-java",
+      buildDate = Instant.EPOCH,
+      clientFeatures = QuasselFeatures.all(),
+      protocolFeatures = Protocol_Features.of(
+        Protocol_Feature.Compression,
+        Protocol_Feature.TLS
+      ),
+      supportedProtocols = listOf(Protocol.Datastream)
+    )
+  }
+}
diff --git a/lib/src/main/java/de/kuschku/libquassel/quassel/syncables/BacklogManager.kt b/lib/src/main/java/de/kuschku/libquassel/quassel/syncables/BacklogManager.kt
index 0f50ef1e8..369d28711 100644
--- a/lib/src/main/java/de/kuschku/libquassel/quassel/syncables/BacklogManager.kt
+++ b/lib/src/main/java/de/kuschku/libquassel/quassel/syncables/BacklogManager.kt
@@ -28,7 +28,7 @@ import de.kuschku.libquassel.util.compatibility.LoggingHandler.LogLevel.DEBUG
 
 class BacklogManager(
   var session: ISession,
-  private val backlogStorage: BacklogStorage
+  private val backlogStorage: BacklogStorage? = null
 ) : SyncableObject(session.proxy, "BacklogManager"), IBacklogManager {
   private val loading = mutableMapOf<BufferId, (List<Message>) -> Boolean>()
   private val loadingFiltered = mutableMapOf<BufferId, (List<Message>) -> Boolean>()
@@ -42,7 +42,7 @@ class BacklogManager(
     initialized = true
   }
 
-  fun updateIgnoreRules() = backlogStorage.updateIgnoreRules(session)
+  fun updateIgnoreRules() = backlogStorage?.updateIgnoreRules(session)
 
   fun requestBacklog(bufferId: BufferId, first: MsgId = -1, last: MsgId = -1, limit: Int = -1,
                      additional: Int = 0, callback: (List<Message>) -> Boolean) {
@@ -79,7 +79,7 @@ class BacklogManager(
     val list = messages.mapNotNull<QVariant_, Message>(QVariant_::value)
     if (loading.remove(bufferId)?.invoke(list) != false) {
       log(DEBUG, "BacklogManager", "storeMessages(${list.size})")
-      backlogStorage.storeMessages(session, list)
+      backlogStorage?.storeMessages(session, list)
     }
   }
 
@@ -88,7 +88,7 @@ class BacklogManager(
     val list = messages.mapNotNull<QVariant_, Message>(QVariant_::value)
     if (loading.remove(-1)?.invoke(list) != false) {
       log(DEBUG, "BacklogManager", "storeMessages(${list.size})")
-      backlogStorage.storeMessages(session, list)
+      backlogStorage?.storeMessages(session, list)
     }
   }
 
@@ -98,7 +98,7 @@ class BacklogManager(
     val list = messages.mapNotNull<QVariant_, Message>(QVariant_::value)
     if (loadingFiltered.remove(bufferId)?.invoke(list) != false) {
       log(DEBUG, "BacklogManager", "storeMessages(${list.size})")
-      backlogStorage.storeMessages(session, list)
+      backlogStorage?.storeMessages(session, list)
     }
   }
 
@@ -107,11 +107,11 @@ class BacklogManager(
     val list = messages.mapNotNull<QVariant_, Message>(QVariant_::value)
     if (loadingFiltered.remove(-1)?.invoke(list) != false) {
       log(DEBUG, "BacklogManager", "storeMessages(${list.size})")
-      backlogStorage.storeMessages(session, list)
+      backlogStorage?.storeMessages(session, list)
     }
   }
 
   fun removeBuffer(buffer: BufferId) {
-    backlogStorage.clearMessages(buffer)
+    backlogStorage?.clearMessages(buffer)
   }
 }
diff --git a/lib/src/main/java/de/kuschku/libquassel/quassel/syncables/BufferSyncer.kt b/lib/src/main/java/de/kuschku/libquassel/quassel/syncables/BufferSyncer.kt
index 9d431723a..1b63fd425 100644
--- a/lib/src/main/java/de/kuschku/libquassel/quassel/syncables/BufferSyncer.kt
+++ b/lib/src/main/java/de/kuschku/libquassel/quassel/syncables/BufferSyncer.kt
@@ -32,7 +32,7 @@ import io.reactivex.subjects.BehaviorSubject
 
 class BufferSyncer constructor(
   var session: ISession,
-  private val notificationManager: NotificationManager?
+  private val notificationManager: NotificationManager? = null
 ) : SyncableObject(session.proxy, "BufferSyncer"), IBufferSyncer {
   override fun deinit() {
     super.deinit()
diff --git a/lib/src/main/java/de/kuschku/libquassel/quassel/syncables/RpcHandler.kt b/lib/src/main/java/de/kuschku/libquassel/quassel/syncables/RpcHandler.kt
index b106c9b09..8fb675f6c 100644
--- a/lib/src/main/java/de/kuschku/libquassel/quassel/syncables/RpcHandler.kt
+++ b/lib/src/main/java/de/kuschku/libquassel/quassel/syncables/RpcHandler.kt
@@ -32,8 +32,8 @@ import java.nio.ByteBuffer
 
 class RpcHandler(
   override val session: Session,
-  private val backlogStorage: BacklogStorage,
-  private val notificationManager: NotificationManager?
+  private val backlogStorage: BacklogStorage? = null,
+  private val notificationManager: NotificationManager? = null
 ) : IRpcHandler {
   override fun displayStatusMsg(net: String, msg: String) {
   }
@@ -61,7 +61,7 @@ class RpcHandler(
 
   override fun displayMsg(message: Message) {
     session.bufferSyncer.bufferInfoUpdated(message.bufferInfo)
-    backlogStorage.storeMessages(session, message)
+    backlogStorage?.storeMessages(session, message)
     notificationManager?.processMessages(session, true, message)
   }
 
diff --git a/lib/src/main/java/de/kuschku/libquassel/session/ProtocolHandler.kt b/lib/src/main/java/de/kuschku/libquassel/session/ProtocolHandler.kt
index 6fd36247f..ac5799918 100644
--- a/lib/src/main/java/de/kuschku/libquassel/session/ProtocolHandler.kt
+++ b/lib/src/main/java/de/kuschku/libquassel/session/ProtocolHandler.kt
@@ -32,7 +32,7 @@ import de.kuschku.libquassel.util.compatibility.LoggingHandler.LogLevel.DEBUG
 import java.io.Closeable
 
 abstract class ProtocolHandler(
-  private val exceptionHandler: (Throwable) -> Unit
+  private val exceptionHandler: ((Throwable) -> Unit)? = null
 ) : SignalProxy, AuthHandler, Closeable {
   protected var closed = false
   protected abstract val objectStorage: ObjectStorage
@@ -61,7 +61,7 @@ abstract class ProtocolHandler(
     } catch (e: ObjectNotFoundException) {
       log(DEBUG, "ProtocolHandler", "An error has occured while processing $f", e)
     } catch (e: Throwable) {
-      exceptionHandler.invoke(MessageHandlingException.SignalProxy(f, e))
+      exceptionHandler?.invoke(MessageHandlingException.SignalProxy(f, e))
     }
     return true
   }
@@ -76,7 +76,7 @@ abstract class ProtocolHandler(
     } catch (e: ObjectNotFoundException) {
       log(DEBUG, "ProtocolHandler", "An error has occured while processing $f", e)
     } catch (e: Throwable) {
-      exceptionHandler.invoke(MessageHandlingException.Handshake(f, e))
+      exceptionHandler?.invoke(MessageHandlingException.Handshake(f, e))
     }
     return true
   }
@@ -103,7 +103,7 @@ abstract class ProtocolHandler(
         try {
           this.handle(it)
         } catch (e: Throwable) {
-          exceptionHandler.invoke(e)
+          exceptionHandler?.invoke(e)
         }
       }
     }
diff --git a/lib/src/main/java/de/kuschku/libquassel/session/Session.kt b/lib/src/main/java/de/kuschku/libquassel/session/Session.kt
index ea53f85f3..fbafa47d4 100644
--- a/lib/src/main/java/de/kuschku/libquassel/session/Session.kt
+++ b/lib/src/main/java/de/kuschku/libquassel/session/Session.kt
@@ -26,9 +26,12 @@ import de.kuschku.libquassel.protocol.message.SignalProxyMessage
 import de.kuschku.libquassel.quassel.ExtendedFeature
 import de.kuschku.libquassel.quassel.QuasselFeatures
 import de.kuschku.libquassel.quassel.syncables.*
+import de.kuschku.libquassel.ssl.BrowserCompatibleHostnameVerifier
+import de.kuschku.libquassel.ssl.TrustManagers
 import de.kuschku.libquassel.util.compatibility.HandlerService
 import de.kuschku.libquassel.util.compatibility.LoggingHandler.Companion.log
 import de.kuschku.libquassel.util.compatibility.LoggingHandler.LogLevel.INFO
+import de.kuschku.libquassel.util.compatibility.reference.JavaHandlerService
 import de.kuschku.libquassel.util.rxjava.ReusableUnicastSubject
 import io.reactivex.Observable
 import io.reactivex.subjects.BehaviorSubject
@@ -37,19 +40,19 @@ import org.threeten.bp.Instant
 import javax.net.ssl.X509TrustManager
 
 class Session(
-  clientData: ClientData,
-  trustManager: X509TrustManager,
-  hostnameVerifier: HostnameVerifier,
   address: SocketAddress,
-  private val handlerService: HandlerService,
-  backlogStorage: BacklogStorage,
-  private val notificationManager: NotificationManager?,
   private var userData: Pair<String, String>,
-  heartBeatFactory: () -> HeartBeatRunner,
-  val disconnectFromCore: (() -> Unit)?,
-  private val initCallback: ((Session) -> Unit)?,
-  exceptionHandler: (Throwable) -> Unit,
-  private val hasErroredCallback: (Error) -> Unit
+  trustManager: X509TrustManager = TrustManagers.default(),
+  hostnameVerifier: HostnameVerifier = BrowserCompatibleHostnameVerifier(),
+  clientData: ClientData = ClientData.DEFAULT,
+  private val handlerService: HandlerService = JavaHandlerService(),
+  heartBeatFactory: () -> HeartBeatRunner = ::JavaHeartBeatRunner,
+  val disconnectFromCore: (() -> Unit)? = null,
+  private val initCallback: ((Session) -> Unit)? = null,
+  exceptionHandler: ((Throwable) -> Unit)? = null,
+  private val hasErroredCallback: ((Error) -> Unit)? = null,
+  private val notificationManager: NotificationManager? = null,
+  backlogStorage: BacklogStorage? = null
 ) : ProtocolHandler(exceptionHandler), ISession {
   override val objectStorage: ObjectStorage = ObjectStorage(this)
   override val proxy: SignalProxy = this
@@ -59,12 +62,12 @@ class Session(
     get() = coreConnection.sslSession
 
   private val coreConnection = CoreConnection(
+    address,
     clientData,
     features,
+    handlerService,
     trustManager,
-    hostnameVerifier,
-    address,
-    handlerService
+    hostnameVerifier
   )
   override val state = coreConnection.state
 
@@ -112,7 +115,7 @@ class Session(
   }
 
   private fun handleError(error: Error) {
-    hasErroredCallback.invoke(error)
+    hasErroredCallback?.invoke(error)
     this.error.onNext(error)
   }
 
diff --git a/lib/src/main/java/de/kuschku/libquassel/session/SessionManager.kt b/lib/src/main/java/de/kuschku/libquassel/session/SessionManager.kt
index 5ed8b2298..b240aa158 100644
--- a/lib/src/main/java/de/kuschku/libquassel/session/SessionManager.kt
+++ b/lib/src/main/java/de/kuschku/libquassel/session/SessionManager.kt
@@ -124,19 +124,19 @@ class SessionManager(
     hasErrored = false
     inProgressSession.onNext(
       Session(
-        clientData,
+        address,
+        userData,
         trustManager,
         hostnameVerifier,
-        address,
+        clientData,
         handlerService,
-        backlogStorage,
-        notificationManager,
-        userData,
         heartBeatFactory,
         disconnectFromCore,
         initCallback,
         exceptionHandler,
-        ::hasErroredCallback
+        ::hasErroredCallback,
+        notificationManager,
+        backlogStorage
       )
     )
   }
diff --git a/app/src/main/java/de/kuschku/quasseldroid/ssl/BrowserCompatibleHostnameVerifier.kt b/lib/src/main/java/de/kuschku/libquassel/ssl/BrowserCompatibleHostnameVerifier.kt
similarity index 96%
rename from app/src/main/java/de/kuschku/quasseldroid/ssl/BrowserCompatibleHostnameVerifier.kt
rename to lib/src/main/java/de/kuschku/libquassel/ssl/BrowserCompatibleHostnameVerifier.kt
index 72c6e8033..4b5ddaefd 100644
--- a/app/src/main/java/de/kuschku/quasseldroid/ssl/BrowserCompatibleHostnameVerifier.kt
+++ b/lib/src/main/java/de/kuschku/libquassel/ssl/BrowserCompatibleHostnameVerifier.kt
@@ -17,11 +17,11 @@
  * with this program. If not, see <http://www.gnu.org/licenses/>.
  */
 
-package de.kuschku.quasseldroid.ssl
+package de.kuschku.libquassel.ssl
 
 import de.kuschku.libquassel.connection.HostnameVerifier
 import de.kuschku.libquassel.connection.SocketAddress
-import de.kuschku.quasseldroid.ssl.X509Helper.hostnames
+import de.kuschku.libquassel.ssl.X509Helper.hostnames
 import java.net.IDN
 import java.security.cert.X509Certificate
 import javax.net.ssl.SSLException
diff --git a/lib/src/main/java/de/kuschku/libquassel/ssl/TrustAllHostnameVerifier.kt b/lib/src/main/java/de/kuschku/libquassel/ssl/TrustAllHostnameVerifier.kt
new file mode 100644
index 000000000..88d1e4268
--- /dev/null
+++ b/lib/src/main/java/de/kuschku/libquassel/ssl/TrustAllHostnameVerifier.kt
@@ -0,0 +1,28 @@
+/*
+ * Quasseldroid - Quassel client for Android
+ *
+ * Copyright (c) 2019 Janne Koschinski
+ * Copyright (c) 2019 The Quassel Project
+ *
+ * This program is free software: you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 3 as published
+ * by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+package de.kuschku.libquassel.ssl
+
+import de.kuschku.libquassel.connection.HostnameVerifier
+import de.kuschku.libquassel.connection.SocketAddress
+import java.security.cert.X509Certificate
+
+class TrustAllHostnameVerifier : HostnameVerifier {
+  override fun checkValid(address: SocketAddress, chain: Array<out X509Certificate>) = Unit
+}
diff --git a/lib/src/main/java/de/kuschku/libquassel/ssl/TrustManagers.kt b/lib/src/main/java/de/kuschku/libquassel/ssl/TrustManagers.kt
new file mode 100644
index 000000000..3bd19a4f8
--- /dev/null
+++ b/lib/src/main/java/de/kuschku/libquassel/ssl/TrustManagers.kt
@@ -0,0 +1,43 @@
+/*
+ * Quasseldroid - Quassel client for Android
+ *
+ * Copyright (c) 2019 Janne Koschinski
+ * Copyright (c) 2019 The Quassel Project
+ *
+ * This program is free software: you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 3 as published
+ * by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+package de.kuschku.libquassel.ssl
+
+import java.security.GeneralSecurityException
+import java.security.KeyStore
+import java.security.cert.X509Certificate
+import javax.net.ssl.KeyManagerFactory
+import javax.net.ssl.TrustManagerFactory
+import javax.net.ssl.X509TrustManager
+
+object TrustManagers {
+  fun default() = TrustManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm()).apply {
+    init(null as KeyStore?)
+  }.trustManagers.mapNotNull {
+    it as? X509TrustManager
+  }.firstOrNull() ?: throw GeneralSecurityException("No TrustManager available")
+
+  fun trustAll() = TrustAllX509TrustManager()
+
+  class TrustAllX509TrustManager : X509TrustManager {
+    override fun checkClientTrusted(p0: Array<out X509Certificate>?, p1: String?) = Unit
+    override fun checkServerTrusted(p0: Array<out X509Certificate>?, p1: String?) = Unit
+    override fun getAcceptedIssuers(): Array<X509Certificate> = emptyArray()
+  }
+}
diff --git a/app/src/main/java/de/kuschku/quasseldroid/ssl/X509Helper.kt b/lib/src/main/java/de/kuschku/libquassel/ssl/X509Helper.kt
similarity index 96%
rename from app/src/main/java/de/kuschku/quasseldroid/ssl/X509Helper.kt
rename to lib/src/main/java/de/kuschku/libquassel/ssl/X509Helper.kt
index 0270a1ea2..a2562c2a2 100644
--- a/app/src/main/java/de/kuschku/quasseldroid/ssl/X509Helper.kt
+++ b/lib/src/main/java/de/kuschku/libquassel/ssl/X509Helper.kt
@@ -17,14 +17,15 @@
  * with this program. If not, see <http://www.gnu.org/licenses/>.
  */
 
-package de.kuschku.quasseldroid.ssl
+package de.kuschku.libquassel.ssl
 
 import java.security.cert.X509Certificate
 
 // FIXME: re-read RFC and check it's actually secure
 object X509Helper {
   fun hostnames(certificate: X509Certificate): Sequence<String> =
-    (sequenceOf(commonName(certificate)) + subjectAlternativeNames(certificate))
+    (sequenceOf(commonName(certificate)) + subjectAlternativeNames(
+      certificate))
       .filterNotNull()
       .distinct()
 
diff --git a/settings.gradle b/settings.gradle
index 919e4870e..ee35cd847 100644
--- a/settings.gradle
+++ b/settings.gradle
@@ -17,9 +17,11 @@
  * with this program. If not, see <http://www.gnu.org/licenses/>.
  */
 
-include ':invokerannotations', ':lifecycle-ktx',
+include ':invokerannotations',
         ':invokergenerator',
         ':lib',
+        ':lifecycle-ktx',
+        ':desktop',
         ":viewmodel",
         ":persistence",
         ':malheur',
-- 
GitLab