Validate several ids in constructors (#336)
* Validate ids in constructors. * Remove redundant `.value` usage in string interpolation. * Make a distinction between `SessionId` and `UserId` in `TestData`.
This commit is contained in:
parent
f98fe8e52c
commit
e704870e3f
36 changed files with 193 additions and 199 deletions
|
|
@ -18,9 +18,9 @@ package io.element.android.libraries.deeplink
|
|||
|
||||
import android.content.Intent
|
||||
import android.net.Uri
|
||||
import io.element.android.libraries.matrix.api.core.asRoomId
|
||||
import io.element.android.libraries.matrix.api.core.asSessionId
|
||||
import io.element.android.libraries.matrix.api.core.asThreadId
|
||||
import io.element.android.libraries.matrix.api.core.RoomId
|
||||
import io.element.android.libraries.matrix.api.core.SessionId
|
||||
import io.element.android.libraries.matrix.api.core.ThreadId
|
||||
import javax.inject.Inject
|
||||
|
||||
class DeeplinkParser @Inject constructor() {
|
||||
|
|
@ -35,9 +35,9 @@ class DeeplinkParser @Inject constructor() {
|
|||
if (scheme != SCHEME) return null
|
||||
if (host != HOST) return null
|
||||
val pathBits = path.orEmpty().split("/").drop(1)
|
||||
val sessionId = pathBits.elementAtOrNull(0)?.asSessionId() ?: return null
|
||||
val roomId = pathBits.elementAtOrNull(1)?.asRoomId()
|
||||
val threadId = pathBits.elementAtOrNull(2)?.asThreadId()
|
||||
val sessionId = pathBits.elementAtOrNull(0)?.let(::SessionId) ?: return null
|
||||
val roomId = pathBits.elementAtOrNull(1)?.let(::RoomId)
|
||||
val threadId = pathBits.elementAtOrNull(2)?.let(::ThreadId)
|
||||
return DeeplinkData(
|
||||
sessionId = sessionId,
|
||||
roomId = roomId,
|
||||
|
|
|
|||
|
|
@ -22,7 +22,7 @@ import com.google.common.truth.Truth.assertThat
|
|||
import io.element.android.libraries.matrix.test.A_ROOM_ID
|
||||
import io.element.android.libraries.matrix.test.A_SESSION_ID
|
||||
import io.element.android.libraries.matrix.test.A_THREAD_ID
|
||||
import io.element.android.tests.testutils.assertNullOrThrow
|
||||
import io.element.android.tests.testutils.assertThrowsInDebug
|
||||
import org.junit.Test
|
||||
import org.junit.runner.RunWith
|
||||
import org.robolectric.RobolectricTestRunner
|
||||
|
|
@ -59,12 +59,13 @@ class DeeplinkParserTest {
|
|||
assertThat(sut.getFromIntent(createIntent("elementx://close/@alice:server.org"))).isNull()
|
||||
// No session Id
|
||||
assertThat(sut.getFromIntent(createIntent("elementx://open"))).isNull()
|
||||
// Invalid sessionId
|
||||
assertNullOrThrow {
|
||||
|
||||
assertThrowsInDebug {
|
||||
// Invalid sessionId
|
||||
sut.getFromIntent(createIntent("elementx://open/alice:server.org"))
|
||||
}
|
||||
// Empty sessionId
|
||||
assertNullOrThrow {
|
||||
assertThrowsInDebug {
|
||||
// Empty sessionId
|
||||
sut.getFromIntent(createIntent("elementx://open//"))
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -20,10 +20,12 @@ import io.element.android.libraries.matrix.api.BuildConfig
|
|||
import java.io.Serializable
|
||||
|
||||
@JvmInline
|
||||
value class EventId(val value: String) : Serializable
|
||||
value class EventId(val value: String) : Serializable {
|
||||
init {
|
||||
if (BuildConfig.DEBUG && !MatrixPatterns.isEventId(value)) {
|
||||
error("`$value` is not a valid event id.\nExample event id: `\$Rqnc-F-dvnEYJTyHq_iKxU2bZ1CI92-kuZq3a5lr5Zg`.")
|
||||
}
|
||||
}
|
||||
|
||||
fun String.asEventId() = if (BuildConfig.DEBUG && !MatrixPatterns.isEventId(this)) {
|
||||
error("`$this` is not a valid event Id")
|
||||
} else {
|
||||
EventId(this)
|
||||
override fun toString(): String = value
|
||||
}
|
||||
|
|
|
|||
|
|
@ -21,13 +21,12 @@ import java.io.Serializable
|
|||
|
||||
@JvmInline
|
||||
value class RoomId(val value: String) : Serializable {
|
||||
override fun toString(): String {
|
||||
return value
|
||||
}
|
||||
}
|
||||
|
||||
fun String.asRoomId() = if (BuildConfig.DEBUG && !MatrixPatterns.isRoomId(this)) {
|
||||
error("`$this` is not a valid room Id")
|
||||
} else {
|
||||
RoomId(this)
|
||||
init {
|
||||
if (BuildConfig.DEBUG && !MatrixPatterns.isRoomId(value)) {
|
||||
error("`$value` is not a valid room id.\n Example room id: `!room_id:domain`.")
|
||||
}
|
||||
}
|
||||
|
||||
override fun toString(): String = value
|
||||
}
|
||||
|
|
|
|||
|
|
@ -16,12 +16,4 @@
|
|||
|
||||
package io.element.android.libraries.matrix.api.core
|
||||
|
||||
import io.element.android.libraries.matrix.api.BuildConfig
|
||||
|
||||
typealias SessionId = UserId
|
||||
|
||||
fun String.asSessionId() = if (BuildConfig.DEBUG && !MatrixPatterns.isSessionId(this)) {
|
||||
error("`$this` is not a valid session Id")
|
||||
} else {
|
||||
SessionId(this)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -20,15 +20,21 @@ import io.element.android.libraries.matrix.api.BuildConfig
|
|||
import java.io.Serializable
|
||||
|
||||
@JvmInline
|
||||
value class SpaceId(val value: String) : Serializable
|
||||
value class SpaceId(val value: String) : Serializable {
|
||||
init {
|
||||
if (BuildConfig.DEBUG && !MatrixPatterns.isSpaceId(value)) {
|
||||
error(
|
||||
"`$value` is not a valid space id.\n" +
|
||||
"Space ids are the same as room ids.\n" +
|
||||
"Example space id: `!space_id:domain`."
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
override fun toString(): String = value
|
||||
}
|
||||
|
||||
/**
|
||||
* Value to use when no space is selected by the user.
|
||||
*/
|
||||
val MAIN_SPACE = SpaceId("!mainSpace")
|
||||
|
||||
fun String.asSpaceId() = if (BuildConfig.DEBUG && !MatrixPatterns.isSpaceId(this)) {
|
||||
error("`$this` is not a valid space Id")
|
||||
} else {
|
||||
SpaceId(this)
|
||||
}
|
||||
val MAIN_SPACE = SpaceId("!mainSpace:local")
|
||||
|
|
|
|||
|
|
@ -20,10 +20,16 @@ import io.element.android.libraries.matrix.api.BuildConfig
|
|||
import java.io.Serializable
|
||||
|
||||
@JvmInline
|
||||
value class ThreadId(val value: String) : Serializable
|
||||
value class ThreadId(val value: String) : Serializable {
|
||||
init {
|
||||
if (BuildConfig.DEBUG && !MatrixPatterns.isThreadId(value)) {
|
||||
error(
|
||||
"`$value` is not a valid thread id.\n" +
|
||||
"Thread ids are the same as event ids.\n" +
|
||||
"Example thread id: `\$Rqnc-F-dvnEYJTyHq_iKxU2bZ1CI92-kuZq3a5lr5Zg`."
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
fun String.asThreadId() = if (BuildConfig.DEBUG && !MatrixPatterns.isThreadId(this)) {
|
||||
error("`$this` is not a valid thread Id")
|
||||
} else {
|
||||
ThreadId(this)
|
||||
override fun toString(): String = value
|
||||
}
|
||||
|
|
|
|||
|
|
@ -21,13 +21,12 @@ import java.io.Serializable
|
|||
|
||||
@JvmInline
|
||||
value class UserId(val value: String) : Serializable {
|
||||
override fun toString(): String {
|
||||
return value
|
||||
}
|
||||
}
|
||||
|
||||
fun String.asUserId() = if (BuildConfig.DEBUG && !MatrixPatterns.isUserId(this)) {
|
||||
error("`$this` is not a valid user Id")
|
||||
} else {
|
||||
UserId(this)
|
||||
init {
|
||||
if (BuildConfig.DEBUG && !MatrixPatterns.isUserId(value)) {
|
||||
error("`$value` is not a valid user id.\nExample user id: `@name:domain`.")
|
||||
}
|
||||
}
|
||||
|
||||
override fun toString(): String = value
|
||||
}
|
||||
|
|
|
|||
|
|
@ -20,7 +20,6 @@ import io.element.android.libraries.core.coroutine.CoroutineDispatchers
|
|||
import io.element.android.libraries.matrix.api.MatrixClient
|
||||
import io.element.android.libraries.matrix.api.core.RoomId
|
||||
import io.element.android.libraries.matrix.api.core.UserId
|
||||
import io.element.android.libraries.matrix.api.core.asRoomId
|
||||
import io.element.android.libraries.matrix.api.createroom.CreateRoomParameters
|
||||
import io.element.android.libraries.matrix.api.createroom.RoomPreset
|
||||
import io.element.android.libraries.matrix.api.createroom.RoomVisibility
|
||||
|
|
@ -201,7 +200,7 @@ class RustMatrixClient constructor(
|
|||
invite = createRoomParams.invite?.map { it.value },
|
||||
avatar = createRoomParams.avatar,
|
||||
)
|
||||
val roomId = client.createRoom(rustParams).asRoomId()
|
||||
val roomId = RoomId(client.createRoom(rustParams))
|
||||
|
||||
// Wait to receive the room back from the sync
|
||||
withTimeout(30_000L) {
|
||||
|
|
|
|||
|
|
@ -17,7 +17,6 @@
|
|||
package io.element.android.libraries.matrix.impl.timeline.item.event
|
||||
|
||||
import io.element.android.libraries.matrix.api.core.EventId
|
||||
import io.element.android.libraries.matrix.api.core.asEventId
|
||||
import io.element.android.libraries.matrix.api.timeline.item.event.AudioMessageType
|
||||
import io.element.android.libraries.matrix.api.timeline.item.event.EmoteMessageType
|
||||
import io.element.android.libraries.matrix.api.timeline.item.event.FileMessageType
|
||||
|
|
@ -70,7 +69,7 @@ class EventMessageMapper {
|
|||
}
|
||||
MessageContent(
|
||||
body = message.body(),
|
||||
inReplyTo = message.inReplyTo()?.eventId?.asEventId(),
|
||||
inReplyTo = message.inReplyTo()?.eventId?.let(::EventId),
|
||||
isEdited = message.isEdited(),
|
||||
type = type
|
||||
)
|
||||
|
|
|
|||
|
|
@ -29,8 +29,8 @@ const val A_PASSWORD = "password"
|
|||
|
||||
val A_USER_ID = UserId("@alice:server.org")
|
||||
val A_USER_ID_2 = UserId("@bob:server.org")
|
||||
val A_SESSION_ID = SessionId(A_USER_ID.value)
|
||||
val A_SESSION_ID_2 = SessionId(A_USER_ID_2.value)
|
||||
val A_SESSION_ID: SessionId = A_USER_ID
|
||||
val A_SESSION_ID_2: SessionId = A_USER_ID_2
|
||||
val A_SPACE_ID = SpaceId("!aSpaceId:domain")
|
||||
val A_ROOM_ID = RoomId("!aRoomId:domain")
|
||||
val A_ROOM_ID_2 = RoomId("!aRoomId2:domain")
|
||||
|
|
|
|||
|
|
@ -24,9 +24,7 @@ import io.element.android.libraries.architecture.bindings
|
|||
import io.element.android.libraries.core.log.logger.LoggerTag
|
||||
import io.element.android.libraries.matrix.api.core.RoomId
|
||||
import io.element.android.libraries.matrix.api.core.SessionId
|
||||
import io.element.android.libraries.matrix.api.core.asRoomId
|
||||
import io.element.android.libraries.matrix.api.core.asSessionId
|
||||
import io.element.android.libraries.matrix.api.core.asThreadId
|
||||
import io.element.android.libraries.matrix.api.core.ThreadId
|
||||
import io.element.android.libraries.push.impl.log.notificationLoggerTag
|
||||
import io.element.android.services.analytics.api.AnalyticsTracker
|
||||
import io.element.android.services.toolbox.api.systemclock.SystemClock
|
||||
|
|
@ -51,32 +49,27 @@ class NotificationBroadcastReceiver : BroadcastReceiver() {
|
|||
if (intent == null || context == null) return
|
||||
context.bindings<NotificationBroadcastReceiverBindings>().inject(this)
|
||||
Timber.tag(loggerTag.value).v("NotificationBroadcastReceiver received : $intent")
|
||||
val sessionId = intent.extras?.getString(KEY_SESSION_ID)?.asSessionId() ?: return
|
||||
val sessionId = intent.extras?.getString(KEY_SESSION_ID)?.let(::SessionId) ?: return
|
||||
val roomId = intent.getStringExtra(KEY_ROOM_ID)?.let(::RoomId)
|
||||
when (intent.action) {
|
||||
actionIds.smartReply ->
|
||||
handleSmartReply(intent, context)
|
||||
actionIds.dismissRoom ->
|
||||
intent.getStringExtra(KEY_ROOM_ID)?.asRoomId()?.let { roomId ->
|
||||
notificationDrawerManager.clearMessagesForRoom(sessionId, roomId)
|
||||
}
|
||||
actionIds.dismissRoom -> if (roomId != null) {
|
||||
notificationDrawerManager.clearMessagesForRoom(sessionId, roomId)
|
||||
}
|
||||
actionIds.dismissSummary ->
|
||||
notificationDrawerManager.clearAllEvents(sessionId)
|
||||
actionIds.markRoomRead ->
|
||||
intent.getStringExtra(KEY_ROOM_ID)?.asRoomId()?.let { roomId ->
|
||||
notificationDrawerManager.clearMessagesForRoom(sessionId, roomId)
|
||||
handleMarkAsRead(sessionId, roomId)
|
||||
}
|
||||
actionIds.join -> {
|
||||
intent.getStringExtra(KEY_ROOM_ID)?.asRoomId()?.let { roomId ->
|
||||
notificationDrawerManager.clearMemberShipNotificationForRoom(sessionId, roomId)
|
||||
handleJoinRoom(sessionId, roomId)
|
||||
}
|
||||
actionIds.markRoomRead -> if (roomId != null) {
|
||||
notificationDrawerManager.clearMessagesForRoom(sessionId, roomId)
|
||||
handleMarkAsRead(sessionId, roomId)
|
||||
}
|
||||
actionIds.reject -> {
|
||||
intent.getStringExtra(KEY_ROOM_ID)?.asRoomId()?.let { roomId ->
|
||||
notificationDrawerManager.clearMemberShipNotificationForRoom(sessionId, roomId)
|
||||
handleRejectRoom(sessionId, roomId)
|
||||
}
|
||||
actionIds.join -> if (roomId != null) {
|
||||
notificationDrawerManager.clearMemberShipNotificationForRoom(sessionId, roomId)
|
||||
handleJoinRoom(sessionId, roomId)
|
||||
}
|
||||
actionIds.reject -> if (roomId != null) {
|
||||
notificationDrawerManager.clearMemberShipNotificationForRoom(sessionId, roomId)
|
||||
handleRejectRoom(sessionId, roomId)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -125,9 +118,9 @@ class NotificationBroadcastReceiver : BroadcastReceiver() {
|
|||
|
||||
private fun handleSmartReply(intent: Intent, context: Context) {
|
||||
val message = getReplyMessage(intent)
|
||||
val sessionId = intent.getStringExtra(KEY_SESSION_ID)?.asSessionId()
|
||||
val roomId = intent.getStringExtra(KEY_ROOM_ID)?.asRoomId()
|
||||
val threadId = intent.getStringExtra(KEY_THREAD_ID)?.asThreadId()
|
||||
val sessionId = intent.getStringExtra(KEY_SESSION_ID)?.let(::SessionId)
|
||||
val roomId = intent.getStringExtra(KEY_ROOM_ID)?.let(::RoomId)
|
||||
val threadId = intent.getStringExtra(KEY_THREAD_ID)?.let(::ThreadId)
|
||||
|
||||
if (message.isNullOrBlank() || roomId == null) {
|
||||
// ignore this event
|
||||
|
|
|
|||
|
|
@ -63,7 +63,7 @@ class PendingIntentFactory @Inject constructor(
|
|||
fun createDismissSummaryPendingIntent(sessionId: SessionId): PendingIntent {
|
||||
val intent = Intent(context, NotificationBroadcastReceiver::class.java)
|
||||
intent.action = actionIds.dismissSummary
|
||||
intent.data = createIgnoredUri("deleteSummary/${sessionId.value}")
|
||||
intent.data = createIgnoredUri("deleteSummary/$sessionId")
|
||||
intent.putExtra(NotificationBroadcastReceiver.KEY_SESSION_ID, sessionId.value)
|
||||
return PendingIntent.getBroadcast(
|
||||
context,
|
||||
|
|
@ -76,7 +76,7 @@ class PendingIntentFactory @Inject constructor(
|
|||
fun createDismissRoomPendingIntent(sessionId: SessionId, roomId: RoomId): PendingIntent {
|
||||
val intent = Intent(context, NotificationBroadcastReceiver::class.java)
|
||||
intent.action = actionIds.dismissRoom
|
||||
intent.data = createIgnoredUri("deleteRoom/${sessionId.value}/${roomId.value}")
|
||||
intent.data = createIgnoredUri("deleteRoom/$sessionId/$roomId")
|
||||
intent.putExtra(NotificationBroadcastReceiver.KEY_SESSION_ID, sessionId.value)
|
||||
intent.putExtra(NotificationBroadcastReceiver.KEY_ROOM_ID, roomId.value)
|
||||
return PendingIntent.getBroadcast(
|
||||
|
|
|
|||
|
|
@ -78,7 +78,7 @@ class QuickReplyActionFactory @Inject constructor(
|
|||
return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
|
||||
val intent = Intent(context, NotificationBroadcastReceiver::class.java)
|
||||
intent.action = actionIds.smartReply
|
||||
intent.data = createIgnoredUri("quickReply/${sessionId.value}/${roomId.value}" + threadId?.let { "/${it.value}" }.orEmpty())
|
||||
intent.data = createIgnoredUri("quickReply/$sessionId/$roomId" + threadId?.let { "/$it" }.orEmpty())
|
||||
intent.putExtra(NotificationBroadcastReceiver.KEY_SESSION_ID, sessionId.value)
|
||||
intent.putExtra(NotificationBroadcastReceiver.KEY_ROOM_ID, roomId.value)
|
||||
threadId?.let {
|
||||
|
|
|
|||
|
|
@ -35,21 +35,21 @@ class NotificationEventQueueTest {
|
|||
fun `given events when redacting some then marks matching event ids as redacted`() {
|
||||
val queue = givenQueue(
|
||||
listOf(
|
||||
aSimpleNotifiableEvent(eventId = EventId("redacted-id-1")),
|
||||
aNotifiableMessageEvent(eventId = EventId("redacted-id-2")),
|
||||
anInviteNotifiableEvent(eventId = EventId("redacted-id-3")),
|
||||
aSimpleNotifiableEvent(eventId = EventId("kept-id")),
|
||||
aSimpleNotifiableEvent(eventId = EventId("\$redacted-id-1")),
|
||||
aNotifiableMessageEvent(eventId = EventId("\$redacted-id-2")),
|
||||
anInviteNotifiableEvent(eventId = EventId("\$redacted-id-3")),
|
||||
aSimpleNotifiableEvent(eventId = EventId("\$kept-id")),
|
||||
)
|
||||
)
|
||||
|
||||
queue.markRedacted(listOf(EventId("redacted-id-1"), EventId("redacted-id-2"), EventId("redacted-id-3")))
|
||||
queue.markRedacted(listOf(EventId("\$redacted-id-1"), EventId("\$redacted-id-2"), EventId("\$redacted-id-3")))
|
||||
|
||||
assertThat(queue.rawEvents()).isEqualTo(
|
||||
listOf(
|
||||
aSimpleNotifiableEvent(eventId = EventId("redacted-id-1"), isRedacted = true),
|
||||
aNotifiableMessageEvent(eventId = EventId("redacted-id-2"), isRedacted = true),
|
||||
anInviteNotifiableEvent(eventId = EventId("redacted-id-3"), isRedacted = true),
|
||||
aSimpleNotifiableEvent(eventId = EventId("kept-id"), isRedacted = false),
|
||||
aSimpleNotifiableEvent(eventId = EventId("\$redacted-id-1"), isRedacted = true),
|
||||
aNotifiableMessageEvent(eventId = EventId("\$redacted-id-2"), isRedacted = true),
|
||||
anInviteNotifiableEvent(eventId = EventId("\$redacted-id-3"), isRedacted = true),
|
||||
aSimpleNotifiableEvent(eventId = EventId("\$kept-id"), isRedacted = false),
|
||||
)
|
||||
)
|
||||
}
|
||||
|
|
@ -179,8 +179,8 @@ class NotificationEventQueueTest {
|
|||
|
||||
@Test
|
||||
fun `given event when adding new event with edited event id matching the existing event id then updates existing event`() {
|
||||
val editedEvent = aSimpleNotifiableEvent(eventId = EventId("id-to-edit"))
|
||||
val updatedEvent = editedEvent.copy(eventId = EventId("1"), editedEventId = EventId("id-to-edit"), title = "updated title", isUpdated = true)
|
||||
val editedEvent = aSimpleNotifiableEvent(eventId = EventId("\$id-to-edit"))
|
||||
val updatedEvent = editedEvent.copy(eventId = EventId("\$1"), editedEventId = EventId("\$id-to-edit"), title = "updated title", isUpdated = true)
|
||||
val queue = givenQueue(listOf(editedEvent))
|
||||
|
||||
queue.add(updatedEvent)
|
||||
|
|
@ -190,8 +190,8 @@ class NotificationEventQueueTest {
|
|||
|
||||
@Test
|
||||
fun `given event when adding new event with edited event id matching the existing event edited id then updates existing event`() {
|
||||
val editedEvent = aSimpleNotifiableEvent(eventId = EventId("0"), editedEventId = EventId("id-to-edit"))
|
||||
val updatedEvent = editedEvent.copy(eventId = EventId("1"), editedEventId = EventId("id-to-edit"), title = "updated title", isUpdated = true)
|
||||
val editedEvent = aSimpleNotifiableEvent(eventId = EventId("\$0"), editedEventId = EventId("\$id-to-edit"))
|
||||
val updatedEvent = editedEvent.copy(eventId = EventId("\$1"), editedEventId = EventId("\$id-to-edit"), title = "updated title", isUpdated = true)
|
||||
val queue = givenQueue(listOf(editedEvent))
|
||||
|
||||
queue.add(updatedEvent)
|
||||
|
|
|
|||
|
|
@ -171,10 +171,10 @@ class NotificationFactoryTest {
|
|||
val roomWithRedactedMessage = mapOf(
|
||||
A_ROOM_ID to listOf(
|
||||
ProcessedEvent(ProcessedEvent.Type.KEEP, A_MESSAGE_EVENT.copy(isRedacted = true)),
|
||||
ProcessedEvent(ProcessedEvent.Type.KEEP, A_MESSAGE_EVENT.copy(eventId = EventId("not-redacted")))
|
||||
ProcessedEvent(ProcessedEvent.Type.KEEP, A_MESSAGE_EVENT.copy(eventId = EventId("\$not-redacted")))
|
||||
)
|
||||
)
|
||||
val withRedactedRemoved = listOf(A_MESSAGE_EVENT.copy(eventId = EventId("not-redacted")))
|
||||
val withRedactedRemoved = listOf(A_MESSAGE_EVENT.copy(eventId = EventId("\$not-redacted")))
|
||||
val expectedNotification = roomGroupMessageCreator.givenCreatesRoomMessageFor(
|
||||
A_SESSION_ID,
|
||||
withRedactedRemoved,
|
||||
|
|
|
|||
|
|
@ -18,7 +18,7 @@ package io.element.android.libraries.push.providers.firebase
|
|||
|
||||
import io.element.android.libraries.core.log.logger.LoggerTag
|
||||
import io.element.android.libraries.matrix.api.auth.MatrixAuthenticationService
|
||||
import io.element.android.libraries.matrix.api.core.asSessionId
|
||||
import io.element.android.libraries.matrix.api.core.SessionId
|
||||
import io.element.android.libraries.push.providers.api.PusherSubscriber
|
||||
import io.element.android.libraries.pushstore.api.UserPushStoreFactory
|
||||
import io.element.android.libraries.sessionstorage.api.SessionStore
|
||||
|
|
@ -42,7 +42,7 @@ class FirebaseNewTokenHandler @Inject constructor(
|
|||
firebaseStore.storeFcmToken(firebaseToken)
|
||||
// Register the pusher for all the sessions
|
||||
sessionStore.getAllSessions().toUserList()
|
||||
.mapNotNull { it.asSessionId() }
|
||||
.map { SessionId(it) }
|
||||
.forEach { userId ->
|
||||
val userDataStore = userPushStoreFactory.create(userId)
|
||||
if (userDataStore.getPushProviderName() == FirebaseConfig.name) {
|
||||
|
|
|
|||
|
|
@ -16,8 +16,8 @@
|
|||
|
||||
package io.element.android.libraries.push.providers.firebase
|
||||
|
||||
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.EventId
|
||||
import io.element.android.libraries.matrix.api.core.RoomId
|
||||
import io.element.android.libraries.push.providers.api.PushData
|
||||
|
||||
/**
|
||||
|
|
@ -41,8 +41,8 @@ data class PushDataFirebase(
|
|||
)
|
||||
|
||||
fun PushDataFirebase.toPushData(): PushData? {
|
||||
val safeEventId = eventId?.asEventId() ?: return null
|
||||
val safeRoomId = roomId?.asRoomId() ?: return null
|
||||
val safeEventId = eventId?.let(::EventId) ?: return null
|
||||
val safeRoomId = roomId?.let(::RoomId) ?: return null
|
||||
return PushData(
|
||||
eventId = safeEventId,
|
||||
roomId = safeRoomId,
|
||||
|
|
|
|||
|
|
@ -20,7 +20,7 @@ import com.google.common.truth.Truth.assertThat
|
|||
import io.element.android.libraries.matrix.test.AN_EVENT_ID
|
||||
import io.element.android.libraries.matrix.test.A_ROOM_ID
|
||||
import io.element.android.libraries.push.providers.api.PushData
|
||||
import io.element.android.tests.testutils.assertNullOrThrow
|
||||
import io.element.android.tests.testutils.assertThrowsInDebug
|
||||
import org.junit.Test
|
||||
|
||||
class FirebasePushParserTest {
|
||||
|
|
@ -52,26 +52,26 @@ class FirebasePushParserTest {
|
|||
fun `test empty roomId`() {
|
||||
val pushParser = FirebasePushParser()
|
||||
assertThat(pushParser.parse(FIREBASE_PUSH_DATA.mutate("room_id", null))).isNull()
|
||||
assertNullOrThrow { pushParser.parse(FIREBASE_PUSH_DATA.mutate("room_id", "")) }
|
||||
assertThrowsInDebug { pushParser.parse(FIREBASE_PUSH_DATA.mutate("room_id", "")) }
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `test invalid roomId`() {
|
||||
val pushParser = FirebasePushParser()
|
||||
assertNullOrThrow { pushParser.parse(FIREBASE_PUSH_DATA.mutate("room_id", "aRoomId:domain")) }
|
||||
assertThrowsInDebug { pushParser.parse(FIREBASE_PUSH_DATA.mutate("room_id", "aRoomId:domain")) }
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `test empty eventId`() {
|
||||
val pushParser = FirebasePushParser()
|
||||
assertThat(pushParser.parse(FIREBASE_PUSH_DATA.mutate("event_id", null))).isNull()
|
||||
assertNullOrThrow { pushParser.parse(FIREBASE_PUSH_DATA.mutate("event_id", "")) }
|
||||
assertThrowsInDebug { pushParser.parse(FIREBASE_PUSH_DATA.mutate("event_id", "")) }
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `test invalid eventId`() {
|
||||
val pushParser = FirebasePushParser()
|
||||
assertNullOrThrow { pushParser.parse(FIREBASE_PUSH_DATA.mutate("event_id", "anEventId")) }
|
||||
assertThrowsInDebug { pushParser.parse(FIREBASE_PUSH_DATA.mutate("event_id", "anEventId")) }
|
||||
}
|
||||
|
||||
companion object {
|
||||
|
|
|
|||
|
|
@ -16,8 +16,8 @@
|
|||
|
||||
package io.element.android.libraries.push.providers.unifiedpush
|
||||
|
||||
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.EventId
|
||||
import io.element.android.libraries.matrix.api.core.RoomId
|
||||
import io.element.android.libraries.push.providers.api.PushData
|
||||
import kotlinx.serialization.SerialName
|
||||
import kotlinx.serialization.Serializable
|
||||
|
|
@ -56,8 +56,8 @@ data class PushDataUnifiedPushCounts(
|
|||
)
|
||||
|
||||
fun PushDataUnifiedPush.toPushData(clientSecret: String): PushData? {
|
||||
val safeEventId = notification?.eventId?.asEventId() ?: return null
|
||||
val safeRoomId = notification.roomId?.asRoomId() ?: return null
|
||||
val safeEventId = notification?.eventId?.let(::EventId) ?: return null
|
||||
val safeRoomId = notification.roomId?.let(::RoomId) ?: return null
|
||||
return PushData(
|
||||
eventId = safeEventId,
|
||||
roomId = safeRoomId,
|
||||
|
|
|
|||
|
|
@ -20,7 +20,7 @@ import com.google.common.truth.Truth.assertThat
|
|||
import io.element.android.libraries.matrix.test.AN_EVENT_ID
|
||||
import io.element.android.libraries.matrix.test.A_ROOM_ID
|
||||
import io.element.android.libraries.push.providers.api.PushData
|
||||
import io.element.android.tests.testutils.assertNullOrThrow
|
||||
import io.element.android.tests.testutils.assertThrowsInDebug
|
||||
import org.junit.Test
|
||||
|
||||
class UnifiedPushParserTest {
|
||||
|
|
@ -52,7 +52,7 @@ class UnifiedPushParserTest {
|
|||
@Test
|
||||
fun `test empty roomId`() {
|
||||
val pushParser = UnifiedPushParser()
|
||||
assertNullOrThrow {
|
||||
assertThrowsInDebug {
|
||||
pushParser.parse(UNIFIED_PUSH_DATA.replace(A_ROOM_ID.value, "").toByteArray(), aClientSecret)
|
||||
}
|
||||
}
|
||||
|
|
@ -60,7 +60,7 @@ class UnifiedPushParserTest {
|
|||
@Test
|
||||
fun `test invalid roomId`() {
|
||||
val pushParser = UnifiedPushParser()
|
||||
assertNullOrThrow {
|
||||
assertThrowsInDebug {
|
||||
pushParser.parse(UNIFIED_PUSH_DATA.mutate(A_ROOM_ID.value, "aRoomId:domain"), aClientSecret)
|
||||
}
|
||||
}
|
||||
|
|
@ -68,7 +68,7 @@ class UnifiedPushParserTest {
|
|||
@Test
|
||||
fun `test empty eventId`() {
|
||||
val pushParser = UnifiedPushParser()
|
||||
assertNullOrThrow {
|
||||
assertThrowsInDebug {
|
||||
pushParser.parse(UNIFIED_PUSH_DATA.mutate(AN_EVENT_ID.value, ""), aClientSecret)
|
||||
}
|
||||
}
|
||||
|
|
@ -76,14 +76,14 @@ class UnifiedPushParserTest {
|
|||
@Test
|
||||
fun `test invalid eventId`() {
|
||||
val pushParser = UnifiedPushParser()
|
||||
assertNullOrThrow {
|
||||
assertThrowsInDebug {
|
||||
pushParser.parse(UNIFIED_PUSH_DATA.mutate(AN_EVENT_ID.value, "anEventId"), aClientSecret)
|
||||
}
|
||||
}
|
||||
|
||||
companion object {
|
||||
private val UNIFIED_PUSH_DATA =
|
||||
"{\"notification\":{\"event_id\":\"${AN_EVENT_ID.value}\",\"room_id\":\"${A_ROOM_ID.value}\",\"counts\":{\"unread\":1},\"prio\":\"high\"}}"
|
||||
"{\"notification\":{\"event_id\":\"$AN_EVENT_ID\",\"room_id\":\"$A_ROOM_ID\",\"counts\":{\"unread\":1},\"prio\":\"high\"}}"
|
||||
// TODO Check client secret format?
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -22,7 +22,6 @@ import io.element.android.libraries.di.AppScope
|
|||
import io.element.android.libraries.di.ApplicationContext
|
||||
import io.element.android.libraries.di.SingleIn
|
||||
import io.element.android.libraries.matrix.api.core.SessionId
|
||||
import io.element.android.libraries.matrix.api.core.asSessionId
|
||||
import io.element.android.libraries.pushstore.api.UserPushStore
|
||||
import io.element.android.libraries.pushstore.api.UserPushStoreFactory
|
||||
import io.element.android.libraries.sessionstorage.api.observer.SessionListener
|
||||
|
|
@ -60,6 +59,6 @@ class DefaultUserPushStoreFactory @Inject constructor(
|
|||
|
||||
override suspend fun onSessionDeleted(userId: String) {
|
||||
// Delete the store
|
||||
userId.asSessionId()?.let { create(it).reset() }
|
||||
create(SessionId(userId)).reset()
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -26,7 +26,6 @@ import com.squareup.anvil.annotations.ContributesBinding
|
|||
import io.element.android.libraries.di.AppScope
|
||||
import io.element.android.libraries.di.ApplicationContext
|
||||
import io.element.android.libraries.matrix.api.core.SessionId
|
||||
import io.element.android.libraries.matrix.api.core.asSessionId
|
||||
import io.element.android.libraries.pushstore.api.clientsecret.PushClientSecretStore
|
||||
import kotlinx.coroutines.flow.first
|
||||
import javax.inject.Inject
|
||||
|
|
@ -58,7 +57,7 @@ class PushClientSecretStoreDataStore @Inject constructor(
|
|||
val matchingKey = keyValues.keys.find {
|
||||
keyValues[it] == clientSecret
|
||||
}
|
||||
return matchingKey?.name?.asSessionId()
|
||||
return matchingKey?.name?.let(::SessionId)
|
||||
}
|
||||
|
||||
private fun getPreferenceKeyForUser(userId: SessionId) = stringPreferencesKey(userId.value)
|
||||
|
|
|
|||
|
|
@ -24,8 +24,8 @@ import kotlinx.coroutines.ExperimentalCoroutinesApi
|
|||
import kotlinx.coroutines.test.runTest
|
||||
import org.junit.Test
|
||||
|
||||
private val A_USER_ID_0 = SessionId("A_USER_ID_0")
|
||||
private val A_USER_ID_1 = SessionId("A_USER_ID_1")
|
||||
private val A_USER_ID_0 = SessionId("@A_USER_ID_0:domain")
|
||||
private val A_USER_ID_1 = SessionId("@A_USER_ID_1:domain")
|
||||
|
||||
private const val A_UNKNOWN_SECRET = "A_UNKNOWN_SECRET"
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue