PushData must have valid Event and Room ids.
This commit is contained in:
parent
5bb504861c
commit
1134f50090
8 changed files with 48 additions and 60 deletions
|
|
@ -20,7 +20,7 @@ import io.element.android.libraries.push.impl.push.PushData
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
|
|
||||||
class FirebasePushParser @Inject constructor() {
|
class FirebasePushParser @Inject constructor() {
|
||||||
fun parse(message: Map<String, String?>): PushData {
|
fun parse(message: Map<String, String?>): PushData? {
|
||||||
val pushDataFirebase = PushDataFirebase(
|
val pushDataFirebase = PushDataFirebase(
|
||||||
eventId = message["event_id"],
|
eventId = message["event_id"],
|
||||||
roomId = message["room_id"],
|
roomId = message["room_id"],
|
||||||
|
|
|
||||||
|
|
@ -16,7 +16,6 @@
|
||||||
|
|
||||||
package io.element.android.libraries.push.impl.firebase
|
package io.element.android.libraries.push.impl.firebase
|
||||||
|
|
||||||
import io.element.android.libraries.matrix.api.core.MatrixPatterns
|
|
||||||
import io.element.android.libraries.matrix.api.core.asEventId
|
import io.element.android.libraries.matrix.api.core.asEventId
|
||||||
import io.element.android.libraries.matrix.api.core.asRoomId
|
import io.element.android.libraries.matrix.api.core.asRoomId
|
||||||
import io.element.android.libraries.push.impl.push.PushData
|
import io.element.android.libraries.push.impl.push.PushData
|
||||||
|
|
@ -41,9 +40,13 @@ data class PushDataFirebase(
|
||||||
val clientSecret: String?
|
val clientSecret: String?
|
||||||
)
|
)
|
||||||
|
|
||||||
fun PushDataFirebase.toPushData() = PushData(
|
fun PushDataFirebase.toPushData(): PushData? {
|
||||||
eventId = eventId?.takeIf { MatrixPatterns.isEventId(it) }?.asEventId(),
|
val safeEventId = eventId?.asEventId() ?: return null
|
||||||
roomId = roomId?.takeIf { MatrixPatterns.isRoomId(it) }?.asRoomId(),
|
val safeRoomId = roomId?.asRoomId() ?: return null
|
||||||
unread = unread,
|
return PushData(
|
||||||
clientSecret = clientSecret,
|
eventId = safeEventId,
|
||||||
)
|
roomId = safeRoomId,
|
||||||
|
unread = unread,
|
||||||
|
clientSecret = clientSecret,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -53,8 +53,11 @@ class VectorFirebaseMessagingService : FirebaseMessagingService() {
|
||||||
override fun onMessageReceived(message: RemoteMessage) {
|
override fun onMessageReceived(message: RemoteMessage) {
|
||||||
Timber.tag(loggerTag.value).d("New Firebase message")
|
Timber.tag(loggerTag.value).d("New Firebase message")
|
||||||
coroutineScope.launch {
|
coroutineScope.launch {
|
||||||
pushParser.parse(message.data).let {
|
val pushData = pushParser.parse(message.data)
|
||||||
pushHandler.handle(it)
|
if (pushData == null) {
|
||||||
|
Timber.tag(loggerTag.value).w("Invalid data received from Firebase")
|
||||||
|
} else {
|
||||||
|
pushHandler.handle(pushData)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -22,14 +22,14 @@ import io.element.android.libraries.matrix.api.core.RoomId
|
||||||
/**
|
/**
|
||||||
* Represent parsed data that the app has received from a Push content.
|
* Represent parsed data that the app has received from a Push content.
|
||||||
*
|
*
|
||||||
* @property eventId The Event ID. If not null, it will not be empty, and will have a valid format.
|
* @property eventId The Event Id.
|
||||||
* @property roomId The Room ID. If not null, it will not be empty, and will have a valid format.
|
* @property roomId The Room Id.
|
||||||
* @property unread Number of unread message.
|
* @property unread Number of unread message.
|
||||||
* @property clientSecret A client secret, used to determine which user should receive the notification.
|
* @property clientSecret data used when the pusher was configured, to be able to determine the session.
|
||||||
*/
|
*/
|
||||||
data class PushData(
|
data class PushData(
|
||||||
val eventId: EventId?,
|
val eventId: EventId,
|
||||||
val roomId: RoomId?,
|
val roomId: RoomId,
|
||||||
val unread: Int?,
|
val unread: Int?,
|
||||||
val clientSecret: String?,
|
val clientSecret: String?,
|
||||||
)
|
)
|
||||||
|
|
|
||||||
|
|
@ -16,7 +16,6 @@
|
||||||
|
|
||||||
package io.element.android.libraries.push.impl.unifiedpush
|
package io.element.android.libraries.push.impl.unifiedpush
|
||||||
|
|
||||||
import io.element.android.libraries.matrix.api.core.MatrixPatterns
|
|
||||||
import io.element.android.libraries.matrix.api.core.asEventId
|
import io.element.android.libraries.matrix.api.core.asEventId
|
||||||
import io.element.android.libraries.matrix.api.core.asRoomId
|
import io.element.android.libraries.matrix.api.core.asRoomId
|
||||||
import io.element.android.libraries.push.impl.push.PushData
|
import io.element.android.libraries.push.impl.push.PushData
|
||||||
|
|
@ -56,9 +55,13 @@ data class PushDataUnifiedPushCounts(
|
||||||
@SerialName("unread") val unread: Int? = null
|
@SerialName("unread") val unread: Int? = null
|
||||||
)
|
)
|
||||||
|
|
||||||
fun PushDataUnifiedPush.toPushData() = PushData(
|
fun PushDataUnifiedPush.toPushData(): PushData? {
|
||||||
eventId = notification?.eventId?.takeIf { MatrixPatterns.isEventId(it) }?.asEventId(),
|
val safeEventId = notification?.eventId?.asEventId() ?: return null
|
||||||
roomId = notification?.roomId?.takeIf { MatrixPatterns.isRoomId(it) }?.asRoomId(),
|
val safeRoomId = notification.roomId?.asRoomId() ?: return null
|
||||||
unread = notification?.counts?.unread,
|
return PushData(
|
||||||
clientSecret = null // TODO EAx check how client secret will be sent through UnifiedPush
|
eventId = safeEventId,
|
||||||
)
|
roomId = safeRoomId,
|
||||||
|
unread = notification.counts?.unread,
|
||||||
|
clientSecret = null // TODO EAx check how client secret will be sent through UnifiedPush
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -67,10 +67,11 @@ class VectorUnifiedPushMessagingReceiver : MessagingReceiver() {
|
||||||
override fun onMessage(context: Context, message: ByteArray, instance: String) {
|
override fun onMessage(context: Context, message: ByteArray, instance: String) {
|
||||||
Timber.tag(loggerTag.value).d("New message")
|
Timber.tag(loggerTag.value).d("New message")
|
||||||
coroutineScope.launch {
|
coroutineScope.launch {
|
||||||
pushParser.parse(message)?.let {
|
val pushData = pushParser.parse(message)
|
||||||
pushHandler.handle(it)
|
if (pushData == null) {
|
||||||
} ?: run {
|
Timber.tag(loggerTag.value).w("Invalid data received from UnifiedPush")
|
||||||
Timber.tag(loggerTag.value).w("Invalid received data Json format")
|
} else {
|
||||||
|
pushHandler.handle(pushData)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -30,18 +30,11 @@ class FirebasePushParserTest {
|
||||||
clientSecret = "a-secret"
|
clientSecret = "a-secret"
|
||||||
)
|
)
|
||||||
|
|
||||||
private val emptyData = PushData(
|
|
||||||
eventId = null,
|
|
||||||
roomId = null,
|
|
||||||
unread = null,
|
|
||||||
clientSecret = null
|
|
||||||
)
|
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun `test edge cases Firebase`() {
|
fun `test edge cases Firebase`() {
|
||||||
val pushParser = FirebasePushParser()
|
val pushParser = FirebasePushParser()
|
||||||
// Empty Json
|
// Empty Json
|
||||||
assertThat(pushParser.parse(emptyMap())).isEqualTo(emptyData)
|
assertThat(pushParser.parse(emptyMap())).isNull()
|
||||||
// Bad Json
|
// Bad Json
|
||||||
assertThat(pushParser.parse(FIREBASE_PUSH_DATA.mutate("unread", "str"))).isEqualTo(validData.copy(unread = null))
|
assertThat(pushParser.parse(FIREBASE_PUSH_DATA.mutate("unread", "str"))).isEqualTo(validData.copy(unread = null))
|
||||||
// Extra data
|
// Extra data
|
||||||
|
|
@ -57,31 +50,27 @@ class FirebasePushParserTest {
|
||||||
@Test
|
@Test
|
||||||
fun `test empty roomId`() {
|
fun `test empty roomId`() {
|
||||||
val pushParser = FirebasePushParser()
|
val pushParser = FirebasePushParser()
|
||||||
val expected = validData.copy(roomId = null)
|
assertThat(pushParser.parse(FIREBASE_PUSH_DATA.mutate("room_id", null))).isNull()
|
||||||
assertThat(pushParser.parse(FIREBASE_PUSH_DATA.mutate("room_id", null))).isEqualTo(expected)
|
assertThat(pushParser.parse(FIREBASE_PUSH_DATA.mutate("room_id", ""))).isNull()
|
||||||
assertThat(pushParser.parse(FIREBASE_PUSH_DATA.mutate("room_id", ""))).isEqualTo(expected)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun `test invalid roomId`() {
|
fun `test invalid roomId`() {
|
||||||
val pushParser = FirebasePushParser()
|
val pushParser = FirebasePushParser()
|
||||||
val expected = validData.copy(roomId = null)
|
assertThat(pushParser.parse(FIREBASE_PUSH_DATA.mutate("room_id", "aRoomId:domain"))).isNull()
|
||||||
assertThat(pushParser.parse(FIREBASE_PUSH_DATA.mutate("room_id", "aRoomId:domain"))).isEqualTo(expected)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun `test empty eventId`() {
|
fun `test empty eventId`() {
|
||||||
val pushParser = FirebasePushParser()
|
val pushParser = FirebasePushParser()
|
||||||
val expected = validData.copy(eventId = null)
|
assertThat(pushParser.parse(FIREBASE_PUSH_DATA.mutate("event_id", null))).isNull()
|
||||||
assertThat(pushParser.parse(FIREBASE_PUSH_DATA.mutate("event_id", null))).isEqualTo(expected)
|
assertThat(pushParser.parse(FIREBASE_PUSH_DATA.mutate("event_id", ""))).isNull()
|
||||||
assertThat(pushParser.parse(FIREBASE_PUSH_DATA.mutate("event_id", ""))).isEqualTo(expected)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun `test invalid eventId`() {
|
fun `test invalid eventId`() {
|
||||||
val pushParser = FirebasePushParser()
|
val pushParser = FirebasePushParser()
|
||||||
val expected = validData.copy(eventId = null)
|
assertThat(pushParser.parse(FIREBASE_PUSH_DATA.mutate("event_id", "anEventId"))).isNull()
|
||||||
assertThat(pushParser.parse(FIREBASE_PUSH_DATA.mutate("event_id", "anEventId"))).isEqualTo(expected)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
|
|
|
||||||
|
|
@ -31,20 +31,13 @@ class UnifiedPushParserTest {
|
||||||
clientSecret = null
|
clientSecret = null
|
||||||
)
|
)
|
||||||
|
|
||||||
private val emptyData = PushData(
|
|
||||||
eventId = null,
|
|
||||||
roomId = null,
|
|
||||||
unread = null,
|
|
||||||
clientSecret = null
|
|
||||||
)
|
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun `test edge cases UnifiedPush`() {
|
fun `test edge cases UnifiedPush`() {
|
||||||
val pushParser = UnifiedPushParser()
|
val pushParser = UnifiedPushParser()
|
||||||
// Empty string
|
// Empty string
|
||||||
assertThat(pushParser.parse("".toByteArray())).isNull()
|
assertThat(pushParser.parse("".toByteArray())).isNull()
|
||||||
// Empty Json
|
// Empty Json
|
||||||
assertThat(pushParser.parse("{}".toByteArray())).isEqualTo(emptyData)
|
assertThat(pushParser.parse("{}".toByteArray())).isNull()
|
||||||
// Bad Json
|
// Bad Json
|
||||||
assertThat(pushParser.parse("ABC".toByteArray())).isNull()
|
assertThat(pushParser.parse("ABC".toByteArray())).isNull()
|
||||||
}
|
}
|
||||||
|
|
@ -58,29 +51,25 @@ class UnifiedPushParserTest {
|
||||||
@Test
|
@Test
|
||||||
fun `test empty roomId`() {
|
fun `test empty roomId`() {
|
||||||
val pushParser = UnifiedPushParser()
|
val pushParser = UnifiedPushParser()
|
||||||
val expected = validData.copy(roomId = null)
|
assertThat(pushParser.parse(UNIFIED_PUSH_DATA.replace(A_ROOM_ID.value, "").toByteArray())).isNull()
|
||||||
assertThat(pushParser.parse(UNIFIED_PUSH_DATA.replace(A_ROOM_ID.value, "").toByteArray())).isEqualTo(expected)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun `test invalid roomId`() {
|
fun `test invalid roomId`() {
|
||||||
val pushParser = UnifiedPushParser()
|
val pushParser = UnifiedPushParser()
|
||||||
val expected = validData.copy(roomId = null)
|
assertThat(pushParser.parse(UNIFIED_PUSH_DATA.mutate(A_ROOM_ID.value, "aRoomId:domain"))).isNull()
|
||||||
assertThat(pushParser.parse(UNIFIED_PUSH_DATA.mutate(A_ROOM_ID.value, "aRoomId:domain"))).isEqualTo(expected)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun `test empty eventId`() {
|
fun `test empty eventId`() {
|
||||||
val pushParser = UnifiedPushParser()
|
val pushParser = UnifiedPushParser()
|
||||||
val expected = validData.copy(eventId = null)
|
assertThat(pushParser.parse(UNIFIED_PUSH_DATA.mutate(AN_EVENT_ID.value, ""))).isNull()
|
||||||
assertThat(pushParser.parse(UNIFIED_PUSH_DATA.mutate(AN_EVENT_ID.value, ""))).isEqualTo(expected)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun `test invalid eventId`() {
|
fun `test invalid eventId`() {
|
||||||
val pushParser = UnifiedPushParser()
|
val pushParser = UnifiedPushParser()
|
||||||
val expected = validData.copy(eventId = null)
|
assertThat(pushParser.parse(UNIFIED_PUSH_DATA.mutate(AN_EVENT_ID.value, "anEventId"))).isNull()
|
||||||
assertThat(pushParser.parse(UNIFIED_PUSH_DATA.mutate(AN_EVENT_ID.value, "anEventId"))).isEqualTo(expected)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue