Merge pull request #346 from loki-project/push-notifications

Push Notifications 2.0 + Onion Routing
This commit is contained in:
Niels Andriesse 2020-09-18 11:10:26 +10:00 committed by GitHub
commit 26a1738d55
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 39 additions and 86 deletions

View File

@ -1,27 +1,24 @@
package org.thoughtcrime.securesms.loki.api package org.thoughtcrime.securesms.loki.api
import android.content.Context import android.content.Context
import nl.komponents.kovenant.functional.map
import okhttp3.* import okhttp3.*
import org.thoughtcrime.securesms.database.DatabaseFactory import org.thoughtcrime.securesms.database.DatabaseFactory
import org.thoughtcrime.securesms.jobmanager.Data
import org.thoughtcrime.securesms.jobmanager.impl.NetworkConstraint
import org.thoughtcrime.securesms.jobs.BaseJob
import org.thoughtcrime.securesms.loki.protocol.ClosedGroupUpdateMessageSendJob
import org.thoughtcrime.securesms.util.TextSecurePreferences import org.thoughtcrime.securesms.util.TextSecurePreferences
import org.whispersystems.libsignal.logging.Log import org.whispersystems.libsignal.logging.Log
import org.whispersystems.signalservice.internal.util.JsonUtil import org.whispersystems.signalservice.internal.util.JsonUtil
import org.whispersystems.signalservice.loki.api.PushNotificationAcknowledgement import org.whispersystems.signalservice.loki.api.PushNotificationAcknowledgement
import java.io.IOException import org.whispersystems.signalservice.loki.api.onionrequests.OnionRequestAPI
import java.lang.Exception
import java.util.concurrent.TimeUnit
object LokiPushNotificationManager { object LokiPushNotificationManager {
private val connection = OkHttpClient()
private val tokenExpirationInterval = 12 * 60 * 60 * 1000 private val tokenExpirationInterval = 12 * 60 * 60 * 1000
private val server by lazy { private val server by lazy {
PushNotificationAcknowledgement.shared.server PushNotificationAcknowledgement.shared.server
} }
private val pnServerPublicKey by lazy {
PushNotificationAcknowledgement.pnServerPublicKey
}
enum class ClosedGroupOperation { enum class ClosedGroupOperation {
Subscribe, Unsubscribe; Subscribe, Unsubscribe;
@ -38,34 +35,19 @@ object LokiPushNotificationManager {
@JvmStatic @JvmStatic
fun unregister(token: String, context: Context) { fun unregister(token: String, context: Context) {
val parameters = mapOf( "token" to token ) val parameters = mapOf( "token" to token )
val url = "$server/register" val url = "$server/unregister"
val body = RequestBody.create(MediaType.get("application/json"), JsonUtil.toJson(parameters)) val body = RequestBody.create(MediaType.get("application/json"), JsonUtil.toJson(parameters))
val request = Request.Builder().url(url).post(body).build() val request = Request.Builder().url(url).post(body)
connection.newCall(request).enqueue(object : Callback { OnionRequestAPI.sendOnionRequest(request.build(), server, pnServerPublicKey).map { json ->
val code = json["code"] as? Int
override fun onResponse(call: Call, response: Response) {
when (response.code()) {
200 -> {
val bodyAsString = response.body()!!.string()
val json = JsonUtil.fromJson(bodyAsString, Map::class.java)
val code = json?.get("code") as? Int
if (code != null && code != 0) { if (code != null && code != 0) {
TextSecurePreferences.setIsUsingFCM(context, false) TextSecurePreferences.setIsUsingFCM(context, false)
Log.d("Loki", "Successfully unregistered from FCM.")
} else { } else {
Log.d("Loki", "Couldn't disable FCM due to error: ${json?.get("message") as? String ?: "null"}.") Log.d("Loki", "Couldn't disable FCM due to error: ${json["message"] as? String ?: "null"}.")
} }
}.fail { exception ->
Log.d("Loki", "Couldn't disable FCM due to error: ${exception}.")
} }
else -> {
Log.d("Loki", "Couldn't disable FCM.")
}
}
}
override fun onFailure(call: Call, exception: IOException) {
Log.d("Loki", "Couldn't disable FCM due to error: $exception.")
}
})
// Unsubscribe from all closed groups // Unsubscribe from all closed groups
val allClosedGroupPublicKeys = DatabaseFactory.getSSKDatabase(context).getAllClosedGroupPublicKeys() val allClosedGroupPublicKeys = DatabaseFactory.getSSKDatabase(context).getAllClosedGroupPublicKeys()
val userPublicKey = TextSecurePreferences.getLocalNumber(context) val userPublicKey = TextSecurePreferences.getLocalNumber(context)
@ -82,34 +64,19 @@ object LokiPushNotificationManager {
val parameters = mapOf( "token" to token, "pubKey" to publicKey ) val parameters = mapOf( "token" to token, "pubKey" to publicKey )
val url = "$server/register" val url = "$server/register"
val body = RequestBody.create(MediaType.get("application/json"), JsonUtil.toJson(parameters)) val body = RequestBody.create(MediaType.get("application/json"), JsonUtil.toJson(parameters))
val request = Request.Builder().url(url).post(body).build() val request = Request.Builder().url(url).post(body)
connection.newCall(request).enqueue(object : Callback { OnionRequestAPI.sendOnionRequest(request.build(), server, pnServerPublicKey).map { json ->
val code = json["code"] as? Int
override fun onResponse(call: Call, response: Response) {
when (response.code()) {
200 -> {
val bodyAsString = response.body()!!.string()
val json = JsonUtil.fromJson(bodyAsString, Map::class.java)
val code = json?.get("code") as? Int
if (code != null && code != 0) { if (code != null && code != 0) {
TextSecurePreferences.setIsUsingFCM(context, true) TextSecurePreferences.setIsUsingFCM(context, true)
TextSecurePreferences.setFCMToken(context, token) TextSecurePreferences.setFCMToken(context, token)
TextSecurePreferences.setLastFCMUploadTime(context, System.currentTimeMillis()) TextSecurePreferences.setLastFCMUploadTime(context, System.currentTimeMillis())
Log.d("Loki", "Successfully registered for FCM.")
} else { } else {
Log.d("Loki", "Couldn't register for FCM due to error: ${json?.get("message") as? String ?: "null"}.") Log.d("Loki", "Couldn't register for FCM due to error: ${json["message"] as? String ?: "null"}.")
} }
}.fail { exception ->
Log.d("Loki", "Couldn't register for FCM due to error: ${exception}.")
} }
else -> {
Log.d("Loki", "Couldn't register for FCM due.")
}
}
}
override fun onFailure(call: Call, exception: IOException) {
Log.d("Loki", "Couldn't register for FCM due to error: $exception.")
}
})
// Subscribe to all closed groups // Subscribe to all closed groups
val allClosedGroupPublicKeys = DatabaseFactory.getSSKDatabase(context).getAllClosedGroupPublicKeys() val allClosedGroupPublicKeys = DatabaseFactory.getSSKDatabase(context).getAllClosedGroupPublicKeys()
allClosedGroupPublicKeys.forEach { closedGroup -> allClosedGroupPublicKeys.forEach { closedGroup ->
@ -123,28 +90,14 @@ object LokiPushNotificationManager {
val parameters = mapOf( "closedGroupPublicKey" to closedGroupPublicKey, "pubKey" to publicKey ) val parameters = mapOf( "closedGroupPublicKey" to closedGroupPublicKey, "pubKey" to publicKey )
val url = "$server/${operation.rawValue}" val url = "$server/${operation.rawValue}"
val body = RequestBody.create(MediaType.get("application/json"), JsonUtil.toJson(parameters)) val body = RequestBody.create(MediaType.get("application/json"), JsonUtil.toJson(parameters))
val request = Request.Builder().url(url).post(body).build() val request = Request.Builder().url(url).post(body)
connection.newCall(request).enqueue(object : Callback { OnionRequestAPI.sendOnionRequest(request.build(), server, pnServerPublicKey).map { json ->
val code = json["code"] as? Int
override fun onResponse(call: Call, response: Response) {
when (response.code()) {
200 -> {
val bodyAsString = response.body()!!.string()
val json = JsonUtil.fromJson(bodyAsString, Map::class.java)
val code = json?.get("code") as? Int
if (code == null || code == 0) { if (code == null || code == 0) {
Log.d("Loki", "Couldn't subscribe/unsubscribe to/from PNs for closed group with ID: $closedGroupPublicKey due to error: ${json?.get("message") as? String ?: "null"}.") Log.d("Loki", "Couldn't subscribe/unsubscribe closed group: $closedGroupPublicKey due to error: ${json["message"] as? String ?: "null"}.")
} }
}.fail { exception ->
Log.d("Loki", "Couldn't subscribe/unsubscribe closed group: $closedGroupPublicKey due to error: ${exception}.")
} }
else -> {
Log.d("Loki", "Couldn't subscribe/unsubscribe to/from PNs for closed group with ID: $closedGroupPublicKey.")
}
}
}
override fun onFailure(call: Call, exception: IOException) {
Log.d("Loki", "Couldn't subscribe/unsubscribe to/from PNs for closed group with ID: $closedGroupPublicKey due to error: $exception.")
}
})
} }
} }

View File

@ -129,7 +129,7 @@ class ClosedGroupUpdateMessageSendJob private constructor(parameters: Parameters
// isClosedGroup can always be false as it's only used in the context of legacy closed groups // isClosedGroup can always be false as it's only used in the context of legacy closed groups
messageSender.sendMessage(0, address, udAccess.get().targetUnidentifiedAccess, messageSender.sendMessage(0, address, udAccess.get().targetUnidentifiedAccess,
Date().time, serializedContentMessage, false, ttl, false, Date().time, serializedContentMessage, false, ttl, false,
useFallbackEncryption, false, false) useFallbackEncryption, false, false, false)
} catch (e: Exception) { } catch (e: Exception) {
Log.d("Loki", "Failed to send closed group update message to: $destination due to error: $e.") Log.d("Loki", "Failed to send closed group update message to: $destination due to error: $e.")
} }

View File

@ -56,7 +56,7 @@ class NullMessageSendJob private constructor(parameters: Parameters, private val
try { try {
messageSender.sendMessage(0, address, udAccess.get().targetUnidentifiedAccess, messageSender.sendMessage(0, address, udAccess.get().targetUnidentifiedAccess,
Date().time, serializedContentMessage, false, ttl, false, Date().time, serializedContentMessage, false, ttl, false,
false, false, false) false, false, false, false)
} catch (e: Exception) { } catch (e: Exception) {
Log.d("Loki", "Failed to send null message to: $publicKey due to error: $e.") Log.d("Loki", "Failed to send null message to: $publicKey due to error: $e.")
throw e throw e

View File

@ -72,7 +72,7 @@ class SessionRequestMessageSendJob private constructor(parameters: Parameters, p
try { try {
messageSender.sendMessage(0, address, udAccess.get().targetUnidentifiedAccess, messageSender.sendMessage(0, address, udAccess.get().targetUnidentifiedAccess,
Date().time, serializedContentMessage, false, ttl, false, Date().time, serializedContentMessage, false, ttl, false,
true, false, false) true, false, false, false)
} catch (e: Exception) { } catch (e: Exception) {
Log.d("Loki", "Failed to send session request to: $publicKey due to error: $e.") Log.d("Loki", "Failed to send session request to: $publicKey due to error: $e.")
throw e throw e