Reformats project based on editorconfig

This commit is contained in:
ericdecanini 2022-05-05 19:10:35 +02:00
parent 59ab16651b
commit 3fb03e2b2c
291 changed files with 2776 additions and 1688 deletions

View File

@ -37,7 +37,10 @@ class PermalinkParserTest {
Assert.assertTrue("Should be parsed as email invite but was ${parsedLink::class.java}", parsedLink is PermalinkData.RoomEmailInviteLink) Assert.assertTrue("Should be parsed as email invite but was ${parsedLink::class.java}", parsedLink is PermalinkData.RoomEmailInviteLink)
parsedLink as PermalinkData.RoomEmailInviteLink parsedLink as PermalinkData.RoomEmailInviteLink
Assert.assertEquals("!MRBNLPtFnMAazZVPMO:matrix.org", parsedLink.roomId) Assert.assertEquals("!MRBNLPtFnMAazZVPMO:matrix.org", parsedLink.roomId)
Assert.assertEquals("XmOwRZnSFabCRhTywFbJWKXWVNPysOpXIbroMGaUymqkJSvHeVKRsjHajwjCYdBsvGSvHauxbKfJmOxtXldtyLnyBMLKpBQCMzyYggrdapbVIceWZBtmslOQrXLABRoe", parsedLink.token) Assert.assertEquals(
"XmOwRZnSFabCRhTywFbJWKXWVNPysOpXIbroMGaUymqkJSvHeVKRsjHajwjCYdBsvGSvHauxbKfJmOxtXldtyLnyBMLKpBQCMzyYggrdapbVIceWZBtmslOQrXLABRoe",
parsedLink.token
)
Assert.assertEquals("vector.im", parsedLink.identityServer) Assert.assertEquals("vector.im", parsedLink.identityServer)
Assert.assertEquals("Team2", parsedLink.roomName) Assert.assertEquals("Team2", parsedLink.roomName)
Assert.assertEquals("hiphop5", parsedLink.inviterName) Assert.assertEquals("hiphop5", parsedLink.inviterName)
@ -45,7 +48,8 @@ class PermalinkParserTest {
@Test @Test
fun testParseLinkWIthEvent() { fun testParseLinkWIthEvent() {
val rawInvite = "https://matrix.to/#/!OGEhHVWSdvArJzumhm:matrix.org/\$xuvJUVDJnwEeVjPx029rAOZ50difpmU_5gZk_T0jGfc?via=matrix.org&via=libera.chat&via=matrix.example.io" val rawInvite =
"https://matrix.to/#/!OGEhHVWSdvArJzumhm:matrix.org/\$xuvJUVDJnwEeVjPx029rAOZ50difpmU_5gZk_T0jGfc?via=matrix.org&via=libera.chat&via=matrix.example.io"
val parsedLink = PermalinkParser.parse(rawInvite) val parsedLink = PermalinkParser.parse(rawInvite)
Assert.assertTrue("Should be parsed as room link", parsedLink is PermalinkData.RoomLink) Assert.assertTrue("Should be parsed as room link", parsedLink is PermalinkData.RoomLink)

View File

@ -21,5 +21,7 @@ import kotlinx.coroutines.asCoroutineDispatcher
import org.matrix.android.sdk.api.MatrixCoroutineDispatchers import org.matrix.android.sdk.api.MatrixCoroutineDispatchers
import java.util.concurrent.Executors import java.util.concurrent.Executors
internal val testCoroutineDispatchers = MatrixCoroutineDispatchers(Main, Main, Main, Main, internal val testCoroutineDispatchers = MatrixCoroutineDispatchers(
Executors.newSingleThreadExecutor().asCoroutineDispatcher()) Main, Main, Main, Main,
Executors.newSingleThreadExecutor().asCoroutineDispatcher()
)

View File

@ -67,9 +67,11 @@ class DeactivateAccountTest : InstrumentedTest {
val throwable = commonTestHelper.logAccountWithError(session.myUserId, TestConstants.PASSWORD) val throwable = commonTestHelper.logAccountWithError(session.myUserId, TestConstants.PASSWORD)
// Test the error // Test the error
assertTrue(throwable is Failure.ServerError && assertTrue(
throwable.error.code == MatrixError.M_USER_DEACTIVATED && throwable is Failure.ServerError &&
throwable.error.message == "This account has been deactivated") throwable.error.code == MatrixError.M_USER_DEACTIVATED &&
throwable.error.message == "This account has been deactivated"
)
// Try to create an account with the deactivate account user id, it will fail (M_USER_IN_USE) // Try to create an account with the deactivate account user id, it will fail (M_USER_IN_USE)
val hs = commonTestHelper.createHomeServerConfig() val hs = commonTestHelper.createHomeServerConfig()
@ -95,8 +97,10 @@ class DeactivateAccountTest : InstrumentedTest {
// Test the error // Test the error
accountCreationError.let { accountCreationError.let {
assertTrue(it is Failure.ServerError && assertTrue(
it.error.code == MatrixError.M_USER_IN_USE) it is Failure.ServerError &&
it.error.code == MatrixError.M_USER_IN_USE
)
} }
// No need to close the session, it has been deactivated // No need to close the session, it has been deactivated

View File

@ -291,7 +291,8 @@ class CryptoTestHelper(private val testHelper: CommonTestHelper) {
) )
) )
} }
}, it) }, it
)
} }
} }
@ -308,7 +309,8 @@ class CryptoTestHelper(private val testHelper: CommonTestHelper) {
requestID, requestID,
roomId, roomId,
bob.myUserId, bob.myUserId,
bob.sessionParams.credentials.deviceId!!) bob.sessionParams.credentials.deviceId!!
)
// we should reach SHOW SAS on both // we should reach SHOW SAS on both
var alicePovTx: OutgoingSasVerificationTransaction? = null var alicePovTx: OutgoingSasVerificationTransaction? = null

View File

@ -29,15 +29,17 @@ import org.matrix.android.sdk.internal.raw.RawModule
import org.matrix.android.sdk.internal.settings.SettingsModule import org.matrix.android.sdk.internal.settings.SettingsModule
import org.matrix.android.sdk.internal.util.system.SystemModule import org.matrix.android.sdk.internal.util.system.SystemModule
@Component(modules = [ @Component(
TestModule::class, modules = [
MatrixModule::class, TestModule::class,
NetworkModule::class, MatrixModule::class,
AuthModule::class, NetworkModule::class,
RawModule::class, AuthModule::class,
SettingsModule::class, RawModule::class,
SystemModule::class SettingsModule::class,
]) SystemModule::class
]
)
@MatrixScope @MatrixScope
internal interface TestMatrixComponent : MatrixComponent { internal interface TestMatrixComponent : MatrixComponent {

View File

@ -76,9 +76,11 @@ class CryptoStoreTest : InstrumentedTest {
} }
val olmSession1 = OlmSession().apply { val olmSession1 = OlmSession().apply {
initOutboundSession(olmAccount1, initOutboundSession(
olmAccount1,
olmAccount1.identityKeys()[OlmAccount.JSON_KEY_IDENTITY_KEY], olmAccount1.identityKeys()[OlmAccount.JSON_KEY_IDENTITY_KEY],
olmAccount1.oneTimeKeys()[OlmAccount.JSON_KEY_ONE_TIME_KEY]?.values?.first()) olmAccount1.oneTimeKeys()[OlmAccount.JSON_KEY_ONE_TIME_KEY]?.values?.first()
)
} }
val sessionId1 = olmSession1.sessionIdentifier() val sessionId1 = olmSession1.sessionIdentifier()
@ -93,9 +95,11 @@ class CryptoStoreTest : InstrumentedTest {
} }
val olmSession2 = OlmSession().apply { val olmSession2 = OlmSession().apply {
initOutboundSession(olmAccount2, initOutboundSession(
olmAccount2,
olmAccount2.identityKeys()[OlmAccount.JSON_KEY_IDENTITY_KEY], olmAccount2.identityKeys()[OlmAccount.JSON_KEY_IDENTITY_KEY],
olmAccount2.oneTimeKeys()[OlmAccount.JSON_KEY_ONE_TIME_KEY]?.values?.first()) olmAccount2.oneTimeKeys()[OlmAccount.JSON_KEY_ONE_TIME_KEY]?.values?.first()
)
} }
val sessionId2 = olmSession2.sessionIdentifier() val sessionId2 = olmSession2.sessionIdentifier()

View File

@ -299,11 +299,13 @@ class E2eeSanityTests : InstrumentedTest {
} }
val importedResult = testHelper.doSync<ImportRoomKeysResult> { val importedResult = testHelper.doSync<ImportRoomKeysResult> {
keysBackupService.restoreKeyBackupWithPassword(keyVersionResult!!, keysBackupService.restoreKeyBackupWithPassword(
keyVersionResult!!,
keyBackupPassword, keyBackupPassword,
null, null,
null, null,
null, it) null, it
)
} }
assertEquals(3, importedResult.totalNumberOfKeys) assertEquals(3, importedResult.totalNumberOfKeys)

View File

@ -83,7 +83,8 @@ class ExportEncryptionTest {
@Test @Test
fun checkExportDecrypt1() { fun checkExportDecrypt1() {
val password = "password" val password = "password"
val input = "-----BEGIN MEGOLM SESSION DATA-----\nAXNhbHRzYWx0c2FsdHNhbHSIiIiIiIiIiIiIiIiIiIiIAAAACmIRUW2OjZ3L2l6j9h0lHlV3M2dx\n" + "cissyYBxjsfsAndErh065A8=\n-----END MEGOLM SESSION DATA-----" val input =
"-----BEGIN MEGOLM SESSION DATA-----\nAXNhbHRzYWx0c2FsdHNhbHSIiIiIiIiIiIiIiIiIiIiIAAAACmIRUW2OjZ3L2l6j9h0lHlV3M2dx\n" + "cissyYBxjsfsAndErh065A8=\n-----END MEGOLM SESSION DATA-----"
val expectedString = "plain" val expectedString = "plain"
var decodedString: String? = null var decodedString: String? = null
@ -93,15 +94,18 @@ class ExportEncryptionTest {
fail("## checkExportDecrypt1() failed : " + e.message) fail("## checkExportDecrypt1() failed : " + e.message)
} }
assertEquals("## checkExportDecrypt1() : expectedString $expectedString -- decodedString $decodedString", assertEquals(
"## checkExportDecrypt1() : expectedString $expectedString -- decodedString $decodedString",
expectedString, expectedString,
decodedString) decodedString
)
} }
@Test @Test
fun checkExportDecrypt2() { fun checkExportDecrypt2() {
val password = "betterpassword" val password = "betterpassword"
val input = "-----BEGIN MEGOLM SESSION DATA-----\nAW1vcmVzYWx0bW9yZXNhbHT//////////wAAAAAAAAAAAAAD6KyBpe1Niv5M5NPm4ZATsJo5nghk\n" + "KYu63a0YQ5DRhUWEKk7CcMkrKnAUiZny\n-----END MEGOLM SESSION DATA-----" val input =
"-----BEGIN MEGOLM SESSION DATA-----\nAW1vcmVzYWx0bW9yZXNhbHT//////////wAAAAAAAAAAAAAD6KyBpe1Niv5M5NPm4ZATsJo5nghk\n" + "KYu63a0YQ5DRhUWEKk7CcMkrKnAUiZny\n-----END MEGOLM SESSION DATA-----"
val expectedString = "Hello, World" val expectedString = "Hello, World"
var decodedString: String? = null var decodedString: String? = null
@ -111,15 +115,18 @@ class ExportEncryptionTest {
fail("## checkExportDecrypt2() failed : " + e.message) fail("## checkExportDecrypt2() failed : " + e.message)
} }
assertEquals("## checkExportDecrypt2() : expectedString $expectedString -- decodedString $decodedString", assertEquals(
"## checkExportDecrypt2() : expectedString $expectedString -- decodedString $decodedString",
expectedString, expectedString,
decodedString) decodedString
)
} }
@Test @Test
fun checkExportDecrypt3() { fun checkExportDecrypt3() {
val password = "SWORDFISH" val password = "SWORDFISH"
val input = "-----BEGIN MEGOLM SESSION DATA-----\nAXllc3NhbHR5Z29vZG5lc3P//////////wAAAAAAAAAAAAAD6OIW+Je7gwvjd4kYrb+49gKCfExw\n" + "MgJBMD4mrhLkmgAngwR1pHjbWXaoGybtiAYr0moQ93GrBQsCzPbvl82rZhaXO3iH5uHo/RCEpOqp\nPgg29363BGR+/Ripq/VCLKGNbw==\n-----END MEGOLM SESSION DATA-----" val input =
"-----BEGIN MEGOLM SESSION DATA-----\nAXllc3NhbHR5Z29vZG5lc3P//////////wAAAAAAAAAAAAAD6OIW+Je7gwvjd4kYrb+49gKCfExw\n" + "MgJBMD4mrhLkmgAngwR1pHjbWXaoGybtiAYr0moQ93GrBQsCzPbvl82rZhaXO3iH5uHo/RCEpOqp\nPgg29363BGR+/Ripq/VCLKGNbw==\n-----END MEGOLM SESSION DATA-----"
val expectedString = "alphanumericallyalphanumericallyalphanumericallyalphanumerically" val expectedString = "alphanumericallyalphanumericallyalphanumericallyalphanumerically"
var decodedString: String? = null var decodedString: String? = null
@ -129,9 +136,11 @@ class ExportEncryptionTest {
fail("## checkExportDecrypt3() failed : " + e.message) fail("## checkExportDecrypt3() failed : " + e.message)
} }
assertEquals("## checkExportDecrypt3() : expectedString $expectedString -- decodedString $decodedString", assertEquals(
"## checkExportDecrypt3() : expectedString $expectedString -- decodedString $decodedString",
expectedString, expectedString,
decodedString) decodedString
)
} }
@Test @Test
@ -147,9 +156,11 @@ class ExportEncryptionTest {
fail("## checkExportEncrypt1() failed : " + e.message) fail("## checkExportEncrypt1() failed : " + e.message)
} }
assertEquals("## checkExportEncrypt1() : expectedString $expectedString -- decodedString $decodedString", assertEquals(
"## checkExportEncrypt1() : expectedString $expectedString -- decodedString $decodedString",
expectedString, expectedString,
decodedString) decodedString
)
} }
@Test @Test
@ -165,9 +176,11 @@ class ExportEncryptionTest {
fail("## checkExportEncrypt2() failed : " + e.message) fail("## checkExportEncrypt2() failed : " + e.message)
} }
assertEquals("## checkExportEncrypt2() : expectedString $expectedString -- decodedString $decodedString", assertEquals(
"## checkExportEncrypt2() : expectedString $expectedString -- decodedString $decodedString",
expectedString, expectedString,
decodedString) decodedString
)
} }
@Test @Test
@ -183,14 +196,17 @@ class ExportEncryptionTest {
fail("## checkExportEncrypt3() failed : " + e.message) fail("## checkExportEncrypt3() failed : " + e.message)
} }
assertEquals("## checkExportEncrypt3() : expectedString $expectedString -- decodedString $decodedString", assertEquals(
"## checkExportEncrypt3() : expectedString $expectedString -- decodedString $decodedString",
expectedString, expectedString,
decodedString) decodedString
)
} }
@Test @Test
fun checkExportEncrypt4() { fun checkExportEncrypt4() {
val password = "passwordpasswordpasswordpasswordpasswordpasswordpasswordpasswordpasswordpasswordpasswordpasswordpasswordpasswordpasswordpassword" + "passwordpasswordpasswordpasswordpasswordpasswordpasswordpasswordpasswordpasswordpasswordpasswordpasswordpasswordpasswordpassword" val password =
"passwordpasswordpasswordpasswordpasswordpasswordpasswordpasswordpasswordpasswordpasswordpasswordpasswordpasswordpasswordpassword" + "passwordpasswordpasswordpasswordpasswordpasswordpasswordpasswordpasswordpasswordpasswordpasswordpasswordpasswordpasswordpassword"
val expectedString = "alphanumericallyalphanumericallyalphanumericallyalphanumerically" val expectedString = "alphanumericallyalphanumericallyalphanumericallyalphanumerically"
var decodedString: String? = null var decodedString: String? = null
@ -201,8 +217,10 @@ class ExportEncryptionTest {
fail("## checkExportEncrypt4() failed : " + e.message) fail("## checkExportEncrypt4() failed : " + e.message)
} }
assertEquals("## checkExportEncrypt4() : expectedString $expectedString -- decodedString $decodedString", assertEquals(
"## checkExportEncrypt4() : expectedString $expectedString -- decodedString $decodedString",
expectedString, expectedString,
decodedString) decodedString
)
} }
} }

View File

@ -171,7 +171,10 @@ class UnwedgingTest : InstrumentedTest {
// Let us wedge the session now. Set crypto state like after the first message // Let us wedge the session now. Set crypto state like after the first message
Timber.i("## CRYPTO | testUnwedging: wedge the session now. Set crypto state like after the first message") Timber.i("## CRYPTO | testUnwedging: wedge the session now. Set crypto state like after the first message")
aliceCryptoStore.storeSession(OlmSessionWrapper(deserializeFromRealm<OlmSession>(oldSession)!!), bobSession.cryptoService().getMyDevice().identityKey()!!) aliceCryptoStore.storeSession(
OlmSessionWrapper(deserializeFromRealm<OlmSession>(oldSession)!!),
bobSession.cryptoService().getMyDevice().identityKey()!!
)
olmDevice.clearOlmSessionCache() olmDevice.clearOlmSessionCache()
Thread.sleep(6_000) Thread.sleep(6_000)
@ -218,7 +221,8 @@ class UnwedgingTest : InstrumentedTest {
) )
) )
} }
}, it) }, it
)
} }
// Wait until we received back the key // Wait until we received back the key

View File

@ -126,8 +126,16 @@ class XSigningTest : InstrumentedTest {
assertNull("Alice should not see bob User key", bobKeysFromAlicePOV.userKey()) assertNull("Alice should not see bob User key", bobKeysFromAlicePOV.userKey())
assertNotNull("Alice can see bob SelfSigned key", bobKeysFromAlicePOV.selfSigningKey()) assertNotNull("Alice can see bob SelfSigned key", bobKeysFromAlicePOV.selfSigningKey())
assertEquals("Bob keys from alice pov should match", bobKeysFromAlicePOV.masterKey()?.unpaddedBase64PublicKey, bobSession.cryptoService().crossSigningService().getMyCrossSigningKeys()?.masterKey()?.unpaddedBase64PublicKey) assertEquals(
assertEquals("Bob keys from alice pov should match", bobKeysFromAlicePOV.selfSigningKey()?.unpaddedBase64PublicKey, bobSession.cryptoService().crossSigningService().getMyCrossSigningKeys()?.selfSigningKey()?.unpaddedBase64PublicKey) "Bob keys from alice pov should match",
bobKeysFromAlicePOV.masterKey()?.unpaddedBase64PublicKey,
bobSession.cryptoService().crossSigningService().getMyCrossSigningKeys()?.masterKey()?.unpaddedBase64PublicKey
)
assertEquals(
"Bob keys from alice pov should match",
bobKeysFromAlicePOV.selfSigningKey()?.unpaddedBase64PublicKey,
bobSession.cryptoService().crossSigningService().getMyCrossSigningKeys()?.selfSigningKey()?.unpaddedBase64PublicKey
)
assertFalse("Bob keys from alice pov should not be trusted", bobKeysFromAlicePOV.isTrusted()) assertFalse("Bob keys from alice pov should not be trusted", bobKeysFromAlicePOV.isTrusted())

View File

@ -145,7 +145,10 @@ class KeyShareTests : InstrumentedTest {
Log.v("TEST", "Incoming request Session 1 (looking for $outGoingRequestId)") Log.v("TEST", "Incoming request Session 1 (looking for $outGoingRequestId)")
Log.v("TEST", "=========================") Log.v("TEST", "=========================")
it.forEach { keyRequest -> it.forEach { keyRequest ->
Log.v("TEST", "[ts${keyRequest.localCreationTimestamp}] requestId ${keyRequest.requestId}, for sessionId ${keyRequest.requestBody?.sessionId} is ${keyRequest.state}") Log.v(
"TEST",
"[ts${keyRequest.localCreationTimestamp}] requestId ${keyRequest.requestId}, for sessionId ${keyRequest.requestBody?.sessionId} is ${keyRequest.state}"
)
} }
Log.v("TEST", "=========================") Log.v("TEST", "=========================")
} }
@ -164,8 +167,10 @@ class KeyShareTests : InstrumentedTest {
} }
// Mark the device as trusted // Mark the device as trusted
aliceSession.cryptoService().setDeviceVerification(DeviceTrustLevel(crossSigningVerified = false, locallyVerified = true), aliceSession.myUserId, aliceSession.cryptoService().setDeviceVerification(
aliceSession2.sessionParams.deviceId ?: "") DeviceTrustLevel(crossSigningVerified = false, locallyVerified = true), aliceSession.myUserId,
aliceSession2.sessionParams.deviceId ?: ""
)
// Re request // Re request
aliceSession2.cryptoService().reRequestRoomKeyForEvent(receivedEvent.root) aliceSession2.cryptoService().reRequestRoomKeyForEvent(receivedEvent.root)
@ -223,7 +228,8 @@ class KeyShareTests : InstrumentedTest {
) )
) )
} }
}, it) }, it
)
} }
// Also bootstrap keybackup on first session // Also bootstrap keybackup on first session
@ -282,8 +288,10 @@ class KeyShareTests : InstrumentedTest {
}) })
val txId = "m.testVerif12" val txId = "m.testVerif12"
aliceVerificationService2.beginKeyVerification(VerificationMethod.SAS, aliceSession1.myUserId, aliceSession1.sessionParams.deviceId aliceVerificationService2.beginKeyVerification(
?: "", txId) VerificationMethod.SAS, aliceSession1.myUserId, aliceSession1.sessionParams.deviceId
?: "", txId
)
commonTestHelper.waitWithLatch { latch -> commonTestHelper.waitWithLatch { latch ->
commonTestHelper.retryPeriodicallyWithLatch(latch) { commonTestHelper.retryPeriodicallyWithLatch(latch) {
@ -337,7 +345,8 @@ class KeyShareTests : InstrumentedTest {
) )
) )
} }
}, it) }, it
)
} }
// Create an encrypted room and send a couple of messages // Create an encrypted room and send a couple of messages
@ -371,7 +380,8 @@ class KeyShareTests : InstrumentedTest {
) )
) )
} }
}, it) }, it
)
} }
// Let alice invite bob // Let alice invite bob

View File

@ -147,13 +147,15 @@ class WithHeldTests : InstrumentedTest {
val aliceInterceptor = testHelper.getTestInterceptor(aliceSession) val aliceInterceptor = testHelper.getTestInterceptor(aliceSession)
// Simulate no OTK // Simulate no OTK
aliceInterceptor!!.addRule(MockOkHttpInterceptor.SimpleRule( aliceInterceptor!!.addRule(
"/keys/claim", MockOkHttpInterceptor.SimpleRule(
200, "/keys/claim",
""" 200,
"""
{ "one_time_keys" : {} } { "one_time_keys" : {} }
""" """
)) )
)
Log.d("#TEST", "Recovery :${aliceSession.sessionParams.credentials.accessToken}") Log.d("#TEST", "Recovery :${aliceSession.sessionParams.credentials.accessToken}")
val roomAlicePov = aliceSession.getRoom(testData.roomId)!! val roomAlicePov = aliceSession.getRoom(testData.roomId)!!
@ -184,7 +186,10 @@ class WithHeldTests : InstrumentedTest {
// Ensure that alice has marked the session to be shared with bob // Ensure that alice has marked the session to be shared with bob
val sessionId = eventBobPOV!!.root.content.toModel<EncryptedEventContent>()!!.sessionId!! val sessionId = eventBobPOV!!.root.content.toModel<EncryptedEventContent>()!!.sessionId!!
val chainIndex = aliceSession.cryptoService().getSharedWithInfo(testData.roomId, sessionId).getObject(bobSession.myUserId, bobSession.sessionParams.credentials.deviceId) val chainIndex = aliceSession.cryptoService().getSharedWithInfo(testData.roomId, sessionId).getObject(
bobSession.myUserId,
bobSession.sessionParams.credentials.deviceId
)
Assert.assertEquals("Alice should have marked bob's device for this session", 0, chainIndex) Assert.assertEquals("Alice should have marked bob's device for this session", 0, chainIndex)
// Add a new device for bob // Add a new device for bob
@ -202,7 +207,10 @@ class WithHeldTests : InstrumentedTest {
} }
} }
val chainIndex2 = aliceSession.cryptoService().getSharedWithInfo(testData.roomId, sessionId).getObject(bobSecondSession.myUserId, bobSecondSession.sessionParams.credentials.deviceId) val chainIndex2 = aliceSession.cryptoService().getSharedWithInfo(testData.roomId, sessionId).getObject(
bobSecondSession.myUserId,
bobSecondSession.sessionParams.credentials.deviceId
)
Assert.assertEquals("Alice should have marked bob's device for this session", 1, chainIndex2) Assert.assertEquals("Alice should have marked bob's device for this session", 1, chainIndex2)

View File

@ -54,9 +54,11 @@ class KeysBackupPasswordTest : InstrumentedTest {
assertEquals(OlmPkDecryption.privateKeyLength(), generatePrivateKeyResult.privateKey.size) assertEquals(OlmPkDecryption.privateKeyLength(), generatePrivateKeyResult.privateKey.size)
// Reverse operation // Reverse operation
val retrievedPrivateKey = retrievePrivateKeyWithPassword(PASSWORD, val retrievedPrivateKey = retrievePrivateKeyWithPassword(
PASSWORD,
generatePrivateKeyResult.salt, generatePrivateKeyResult.salt,
generatePrivateKeyResult.iterations) generatePrivateKeyResult.iterations
)
assertEquals(OlmPkDecryption.privateKeyLength(), retrievedPrivateKey.size) assertEquals(OlmPkDecryption.privateKeyLength(), retrievedPrivateKey.size)
assertArrayEquals(generatePrivateKeyResult.privateKey, retrievedPrivateKey) assertArrayEquals(generatePrivateKeyResult.privateKey, retrievedPrivateKey)
@ -102,9 +104,11 @@ class KeysBackupPasswordTest : InstrumentedTest {
assertEquals(OlmPkDecryption.privateKeyLength(), generatePrivateKeyResult.privateKey.size) assertEquals(OlmPkDecryption.privateKeyLength(), generatePrivateKeyResult.privateKey.size)
// Reverse operation, with bad password // Reverse operation, with bad password
val retrievedPrivateKey = retrievePrivateKeyWithPassword(BAD_PASSWORD, val retrievedPrivateKey = retrievePrivateKeyWithPassword(
BAD_PASSWORD,
generatePrivateKeyResult.salt, generatePrivateKeyResult.salt,
generatePrivateKeyResult.iterations) generatePrivateKeyResult.iterations
)
assertEquals(OlmPkDecryption.privateKeyLength(), retrievedPrivateKey.size) assertEquals(OlmPkDecryption.privateKeyLength(), retrievedPrivateKey.size)
assertByteArrayNotEqual(generatePrivateKeyResult.privateKey, retrievedPrivateKey) assertByteArrayNotEqual(generatePrivateKeyResult.privateKey, retrievedPrivateKey)
@ -122,9 +126,11 @@ class KeysBackupPasswordTest : InstrumentedTest {
assertEquals(OlmPkDecryption.privateKeyLength(), generatePrivateKeyResult.privateKey.size) assertEquals(OlmPkDecryption.privateKeyLength(), generatePrivateKeyResult.privateKey.size)
// Reverse operation, with bad iteration // Reverse operation, with bad iteration
val retrievedPrivateKey = retrievePrivateKeyWithPassword(PASSWORD, val retrievedPrivateKey = retrievePrivateKeyWithPassword(
PASSWORD,
generatePrivateKeyResult.salt, generatePrivateKeyResult.salt,
500_001) 500_001
)
assertEquals(OlmPkDecryption.privateKeyLength(), retrievedPrivateKey.size) assertEquals(OlmPkDecryption.privateKeyLength(), retrievedPrivateKey.size)
assertByteArrayNotEqual(generatePrivateKeyResult.privateKey, retrievedPrivateKey) assertByteArrayNotEqual(generatePrivateKeyResult.privateKey, retrievedPrivateKey)
@ -142,9 +148,11 @@ class KeysBackupPasswordTest : InstrumentedTest {
assertEquals(OlmPkDecryption.privateKeyLength(), generatePrivateKeyResult.privateKey.size) assertEquals(OlmPkDecryption.privateKeyLength(), generatePrivateKeyResult.privateKey.size)
// Reverse operation, with bad iteration // Reverse operation, with bad iteration
val retrievedPrivateKey = retrievePrivateKeyWithPassword(PASSWORD, val retrievedPrivateKey = retrievePrivateKeyWithPassword(
PASSWORD,
BAD_SALT, BAD_SALT,
generatePrivateKeyResult.iterations) generatePrivateKeyResult.iterations
)
assertEquals(OlmPkDecryption.privateKeyLength(), retrievedPrivateKey.size) assertEquals(OlmPkDecryption.privateKeyLength(), retrievedPrivateKey.size)
assertByteArrayNotEqual(generatePrivateKeyResult.privateKey, retrievedPrivateKey) assertByteArrayNotEqual(generatePrivateKeyResult.privateKey, retrievedPrivateKey)
@ -168,7 +176,8 @@ class KeysBackupPasswordTest : InstrumentedTest {
116.toByte(), 224.toByte(), 229.toByte(), 224.toByte(), 9.toByte(), 3.toByte(), 178.toByte(), 162.toByte(), 116.toByte(), 224.toByte(), 229.toByte(), 224.toByte(), 9.toByte(), 3.toByte(), 178.toByte(), 162.toByte(),
120.toByte(), 23.toByte(), 108.toByte(), 218.toByte(), 22.toByte(), 61.toByte(), 241.toByte(), 200.toByte(), 120.toByte(), 23.toByte(), 108.toByte(), 218.toByte(), 22.toByte(), 61.toByte(), 241.toByte(), 200.toByte(),
235.toByte(), 173.toByte(), 236.toByte(), 100.toByte(), 115.toByte(), 247.toByte(), 33.toByte(), 132.toByte(), 235.toByte(), 173.toByte(), 236.toByte(), 100.toByte(), 115.toByte(), 247.toByte(), 33.toByte(), 132.toByte(),
195.toByte(), 154.toByte(), 64.toByte(), 158.toByte(), 184.toByte(), 148.toByte(), 20.toByte(), 85.toByte()) 195.toByte(), 154.toByte(), 64.toByte(), 158.toByte(), 184.toByte(), 148.toByte(), 20.toByte(), 85.toByte()
)
assertArrayEquals(privateKeyBytes, retrievedPrivateKey) assertArrayEquals(privateKeyBytes, retrievedPrivateKey)
} }

View File

@ -272,10 +272,12 @@ class KeysBackupTest : InstrumentedTest {
assertNotNull(decryption) assertNotNull(decryption)
// - Check decryptKeyBackupData() returns stg // - Check decryptKeyBackupData() returns stg
val sessionData = keysBackup val sessionData = keysBackup
.decryptKeyBackupData(keyBackupData, .decryptKeyBackupData(
keyBackupData,
session.olmInboundGroupSession!!.sessionIdentifier(), session.olmInboundGroupSession!!.sessionIdentifier(),
cryptoTestData.roomId, cryptoTestData.roomId,
decryption!!) decryption!!
)
assertNotNull(sessionData) assertNotNull(sessionData)
// - Compare the decrypted megolm key with the original one // - Compare the decrypted megolm key with the original one
keysBackupTestHelper.assertKeysEquals(session.exportKeys(), sessionData) keysBackupTestHelper.assertKeysEquals(session.exportKeys(), sessionData)
@ -297,7 +299,8 @@ class KeysBackupTest : InstrumentedTest {
// - Restore the e2e backup from the homeserver // - Restore the e2e backup from the homeserver
val importRoomKeysResult = testHelper.doSync<ImportRoomKeysResult> { val importRoomKeysResult = testHelper.doSync<ImportRoomKeysResult> {
testData.aliceSession2.cryptoService().keysBackupService().restoreKeysWithRecoveryKey(testData.aliceSession2.cryptoService().keysBackupService().keysBackupVersion!!, testData.aliceSession2.cryptoService().keysBackupService().restoreKeysWithRecoveryKey(
testData.aliceSession2.cryptoService().keysBackupService().keysBackupVersion!!,
testData.prepareKeysBackupDataResult.megolmBackupCreationInfo.recoveryKey, testData.prepareKeysBackupDataResult.megolmBackupCreationInfo.recoveryKey,
null, null,
null, null,
@ -680,7 +683,8 @@ class KeysBackupTest : InstrumentedTest {
val steps = ArrayList<StepProgressListener.Step>() val steps = ArrayList<StepProgressListener.Step>()
val importRoomKeysResult = testHelper.doSync<ImportRoomKeysResult> { val importRoomKeysResult = testHelper.doSync<ImportRoomKeysResult> {
testData.aliceSession2.cryptoService().keysBackupService().restoreKeyBackupWithPassword(testData.aliceSession2.cryptoService().keysBackupService().keysBackupVersion!!, testData.aliceSession2.cryptoService().keysBackupService().restoreKeyBackupWithPassword(
testData.aliceSession2.cryptoService().keysBackupService().keysBackupVersion!!,
password, password,
null, null,
null, null,
@ -771,7 +775,8 @@ class KeysBackupTest : InstrumentedTest {
// - Restore the e2e backup with the recovery key. // - Restore the e2e backup with the recovery key.
val importRoomKeysResult = testHelper.doSync<ImportRoomKeysResult> { val importRoomKeysResult = testHelper.doSync<ImportRoomKeysResult> {
testData.aliceSession2.cryptoService().keysBackupService().restoreKeysWithRecoveryKey(testData.aliceSession2.cryptoService().keysBackupService().keysBackupVersion!!, testData.aliceSession2.cryptoService().keysBackupService().restoreKeysWithRecoveryKey(
testData.aliceSession2.cryptoService().keysBackupService().keysBackupVersion!!,
testData.prepareKeysBackupDataResult.megolmBackupCreationInfo.recoveryKey, testData.prepareKeysBackupDataResult.megolmBackupCreationInfo.recoveryKey,
null, null,
null, null,
@ -1055,7 +1060,11 @@ class KeysBackupTest : InstrumentedTest {
assertFalse(keysBackup2.isEnabled) assertFalse(keysBackup2.isEnabled)
// - Validate the old device from the new one // - Validate the old device from the new one
aliceSession2.cryptoService().setDeviceVerification(DeviceTrustLevel(crossSigningVerified = false, locallyVerified = true), aliceSession2.myUserId, oldDeviceId) aliceSession2.cryptoService().setDeviceVerification(
DeviceTrustLevel(crossSigningVerified = false, locallyVerified = true),
aliceSession2.myUserId,
oldDeviceId
)
// -> Backup should automatically enable on the new device // -> Backup should automatically enable on the new device
val latch4 = CountDownLatch(1) val latch4 = CountDownLatch(1)

View File

@ -88,10 +88,12 @@ internal class KeysBackupTestHelper(
stateObserver.stopAndCheckStates(null) stateObserver.stopAndCheckStates(null)
return KeysBackupScenarioData(cryptoTestData, return KeysBackupScenarioData(
cryptoTestData,
aliceKeys, aliceKeys,
prepareKeysBackupDataResult, prepareKeysBackupDataResult,
aliceSession2) aliceSession2
)
} }
fun prepareAndCreateKeysBackupData(keysBackup: KeysBackupService, fun prepareAndCreateKeysBackupData(keysBackup: KeysBackupService,

View File

@ -207,14 +207,16 @@ class QuadSTests : InstrumentedTest {
// Assert that can decrypt with both keys // Assert that can decrypt with both keys
testHelper.runBlockingTest { testHelper.runBlockingTest {
aliceSession.sharedSecretStorageService().getSecret("my.secret", aliceSession.sharedSecretStorageService().getSecret(
"my.secret",
keyId1, keyId1,
RawBytesKeySpec.fromRecoveryKey(key1Info.recoveryKey)!! RawBytesKeySpec.fromRecoveryKey(key1Info.recoveryKey)!!
) )
} }
testHelper.runBlockingTest { testHelper.runBlockingTest {
aliceSession.sharedSecretStorageService().getSecret("my.secret", aliceSession.sharedSecretStorageService().getSecret(
"my.secret",
keyId2, keyId2,
RawBytesKeySpec.fromRecoveryKey(key2Info.recoveryKey)!! RawBytesKeySpec.fromRecoveryKey(key2Info.recoveryKey)!!
) )
@ -245,13 +247,15 @@ class QuadSTests : InstrumentedTest {
testHelper.runBlockingTest { testHelper.runBlockingTest {
try { try {
aliceSession.sharedSecretStorageService().getSecret("my.secret", aliceSession.sharedSecretStorageService().getSecret(
"my.secret",
keyId1, keyId1,
RawBytesKeySpec.fromPassphrase( RawBytesKeySpec.fromPassphrase(
"A bad passphrase", "A bad passphrase",
key1Info.content?.passphrase?.salt ?: "", key1Info.content?.passphrase?.salt ?: "",
key1Info.content?.passphrase?.iterations ?: 0, key1Info.content?.passphrase?.iterations ?: 0,
null) null
)
) )
} catch (throwable: Throwable) { } catch (throwable: Throwable) {
assert(throwable is SharedSecretStorageError.BadMac) assert(throwable is SharedSecretStorageError.BadMac)
@ -260,13 +264,15 @@ class QuadSTests : InstrumentedTest {
// Now try with correct key // Now try with correct key
testHelper.runBlockingTest { testHelper.runBlockingTest {
aliceSession.sharedSecretStorageService().getSecret("my.secret", aliceSession.sharedSecretStorageService().getSecret(
"my.secret",
keyId1, keyId1,
RawBytesKeySpec.fromPassphrase( RawBytesKeySpec.fromPassphrase(
passphrase, passphrase,
key1Info.content?.passphrase?.salt ?: "", key1Info.content?.passphrase?.salt ?: "",
key1Info.content?.passphrase?.iterations ?: 0, key1Info.content?.passphrase?.iterations ?: 0,
null) null
)
) )
} }
@ -321,7 +327,8 @@ class QuadSTests : InstrumentedTest {
keyId, keyId,
passphrase, passphrase,
emptyKeySigner, emptyKeySigner,
null) null
)
} }
assertAccountData(session, "${DefaultSharedSecretStorageService.KEY_ID_BASE}.$keyId") assertAccountData(session, "${DefaultSharedSecretStorageService.KEY_ID_BASE}.$keyId")

View File

@ -75,10 +75,12 @@ class SASTest : InstrumentedTest {
} }
bobVerificationService.addListener(bobListener) bobVerificationService.addListener(bobListener)
val txID = aliceVerificationService.beginKeyVerification(VerificationMethod.SAS, val txID = aliceVerificationService.beginKeyVerification(
VerificationMethod.SAS,
bobSession.myUserId, bobSession.myUserId,
bobSession.cryptoService().getMyDevice().deviceId, bobSession.cryptoService().getMyDevice().deviceId,
null) null
)
assertNotNull("Alice should have a started transaction", txID) assertNotNull("Alice should have a started transaction", txID)
val aliceKeyTx = aliceVerificationService.getExistingTransaction(bobSession.myUserId, txID!!) val aliceKeyTx = aliceVerificationService.getExistingTransaction(bobSession.myUserId, txID!!)
@ -467,8 +469,10 @@ class SASTest : InstrumentedTest {
val aliceTx = aliceVerificationService.getExistingTransaction(bobUserId, verificationSAS!!) as SASDefaultVerificationTransaction val aliceTx = aliceVerificationService.getExistingTransaction(bobUserId, verificationSAS!!) as SASDefaultVerificationTransaction
val bobTx = bobVerificationService.getExistingTransaction(aliceSession.myUserId, verificationSAS) as SASDefaultVerificationTransaction val bobTx = bobVerificationService.getExistingTransaction(aliceSession.myUserId, verificationSAS) as SASDefaultVerificationTransaction
assertEquals("Should have same SAS", aliceTx.getShortCodeRepresentation(SasMode.DECIMAL), assertEquals(
bobTx.getShortCodeRepresentation(SasMode.DECIMAL)) "Should have same SAS", aliceTx.getShortCodeRepresentation(SasMode.DECIMAL),
bobTx.getShortCodeRepresentation(SasMode.DECIMAL)
)
cryptoTestData.cleanUp(testHelper) cryptoTestData.cleanUp(testHelper)
} }
@ -544,7 +548,8 @@ class SASTest : InstrumentedTest {
// Assert that devices are verified // Assert that devices are verified
val bobDeviceInfoFromAlicePOV: CryptoDeviceInfo? = aliceSession.cryptoService().getDeviceInfo(bobUserId, bobDeviceId) val bobDeviceInfoFromAlicePOV: CryptoDeviceInfo? = aliceSession.cryptoService().getDeviceInfo(bobUserId, bobDeviceId)
val aliceDeviceInfoFromBobPOV: CryptoDeviceInfo? = bobSession.cryptoService().getDeviceInfo(aliceSession.myUserId, aliceSession.cryptoService().getMyDevice().deviceId) val aliceDeviceInfoFromBobPOV: CryptoDeviceInfo? =
bobSession.cryptoService().getDeviceInfo(aliceSession.myUserId, aliceSession.cryptoService().getMyDevice().deviceId)
assertTrue("alice device should be verified from bob point of view", aliceDeviceInfoFromBobPOV!!.isVerified) assertTrue("alice device should be verified from bob point of view", aliceDeviceInfoFromBobPOV!!.isVerified)
assertTrue("bob device should be verified from alice point of view", bobDeviceInfoFromAlicePOV!!.isVerified) assertTrue("bob device should be verified from alice point of view", bobDeviceInfoFromAlicePOV!!.isVerified)
@ -611,14 +616,16 @@ class SASTest : InstrumentedTest {
requestID!!, requestID!!,
cryptoTestData.roomId, cryptoTestData.roomId,
bobSession.myUserId, bobSession.myUserId,
bobSession.sessionParams.deviceId!!) bobSession.sessionParams.deviceId!!
)
bobVerificationService.beginKeyVerificationInDMs( bobVerificationService.beginKeyVerificationInDMs(
VerificationMethod.SAS, VerificationMethod.SAS,
requestID!!, requestID!!,
cryptoTestData.roomId, cryptoTestData.roomId,
aliceSession.myUserId, aliceSession.myUserId,
aliceSession.sessionParams.deviceId!!) aliceSession.sessionParams.deviceId!!
)
// we should reach SHOW SAS on both // we should reach SHOW SAS on both
var alicePovTx: SasVerificationTransaction? var alicePovTx: SasVerificationTransaction?

View File

@ -37,7 +37,8 @@ class QrCodeTest : InstrumentedTest {
sharedSecret = "MTIzNDU2Nzg" sharedSecret = "MTIzNDU2Nzg"
) )
private val value1 = "MATRIX\u0002\u0000\u0000\u000DMaTransaction\u0092Ñ0qCú²íq\u0087á®\u0013à\u0098\u0091\u000DÇéoÃ\"_²lq]hC«¢UMynd¤Ù.ô\u0091XäÏ\u0094ê\u008B«\u009Døl\u000F¿+\u008CË\u0014¤®õÁ\u008BA¥12345678" private val value1 =
"MATRIX\u0002\u0000\u0000\u000DMaTransaction\u0092Ñ0qCú²íq\u0087á®\u0013à\u0098\u0091\u000DÇéoÃ\"_²lq]hC«¢UMynd¤Ù.ô\u0091XäÏ\u0094ê\u008B«\u009Døl\u000F¿+\u008CË\u0014¤®õÁ\u008BA¥12345678"
private val qrCode2 = QrCodeData.SelfVerifyingMasterKeyTrusted( private val qrCode2 = QrCodeData.SelfVerifyingMasterKeyTrusted(
transactionId = "MaTransaction", transactionId = "MaTransaction",
@ -46,7 +47,8 @@ class QrCodeTest : InstrumentedTest {
sharedSecret = "MTIzNDU2Nzg" sharedSecret = "MTIzNDU2Nzg"
) )
private val value2 = "MATRIX\u0002\u0001\u0000\u000DMaTransaction\u0092Ñ0qCú²íq\u0087á®\u0013à\u0098\u0091\u000DÇéoÃ\"_²lq]hC«¢UMynd¤Ù.ô\u0091XäÏ\u0094ê\u008B«\u009Døl\u000F¿+\u008CË\u0014¤®õÁ\u008BA¥12345678" private val value2 =
"MATRIX\u0002\u0001\u0000\u000DMaTransaction\u0092Ñ0qCú²íq\u0087á®\u0013à\u0098\u0091\u000DÇéoÃ\"_²lq]hC«¢UMynd¤Ù.ô\u0091XäÏ\u0094ê\u008B«\u009Døl\u000F¿+\u008CË\u0014¤®õÁ\u008BA¥12345678"
private val qrCode3 = QrCodeData.SelfVerifyingMasterKeyNotTrusted( private val qrCode3 = QrCodeData.SelfVerifyingMasterKeyNotTrusted(
transactionId = "MaTransaction", transactionId = "MaTransaction",
@ -55,7 +57,8 @@ class QrCodeTest : InstrumentedTest {
sharedSecret = "MTIzNDU2Nzg" sharedSecret = "MTIzNDU2Nzg"
) )
private val value3 = "MATRIX\u0002\u0002\u0000\u000DMaTransactionMynd¤Ù.ô\u0091XäÏ\u0094ê\u008B«\u009Døl\u000F¿+\u008CË\u0014¤®õÁ\u008B\u0092Ñ0qCú²íq\u0087á®\u0013à\u0098\u0091\u000DÇéoÃ\"_²lq]hC«¢U12345678" private val value3 =
"MATRIX\u0002\u0002\u0000\u000DMaTransactionMynd¤Ù.ô\u0091XäÏ\u0094ê\u008B«\u009Døl\u000F¿+\u008CË\u0014¤®õÁ\u008B\u0092Ñ0qCú²íq\u0087á®\u0013à\u0098\u0091\u000DÇéoÃ\"_²lq]hC«¢U12345678"
private val sharedSecretByteArray = "12345678".toByteArray(Charsets.ISO_8859_1) private val sharedSecretByteArray = "12345678".toByteArray(Charsets.ISO_8859_1)

View File

@ -175,7 +175,8 @@ class VerificationTest : InstrumentedTest {
) )
) )
} }
}, callback) }, callback
)
} }
testHelper.doSync<Unit> { callback -> testHelper.doSync<Unit> { callback ->
@ -191,7 +192,8 @@ class VerificationTest : InstrumentedTest {
) )
) )
} }
}, callback) }, callback
)
} }
val aliceVerificationService = aliceSession.cryptoService().verificationService() val aliceVerificationService = aliceSession.cryptoService().verificationService()

View File

@ -71,10 +71,12 @@ class MarkdownParserTest : InstrumentedTest {
testIdentity("") testIdentity("")
testIdentity("a") testIdentity("a")
testIdentity("1") testIdentity("1")
testIdentity("Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et " + testIdentity(
"dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea com" + "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et " +
"modo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pari" + "dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea com" +
"atur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.") "modo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pari" +
"atur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum."
)
} }
@Test @Test
@ -294,16 +296,20 @@ class MarkdownParserTest : InstrumentedTest {
"$markdownPattern$name$markdownPattern" "$markdownPattern$name$markdownPattern"
.let { .let {
markdownParser.parse(it) markdownParser.parse(it)
.expect(expectedText = it, .expect(
expectedFormattedText = "<$htmlExpectedTag>$name</$htmlExpectedTag>") expectedText = it,
expectedFormattedText = "<$htmlExpectedTag>$name</$htmlExpectedTag>"
)
} }
// Test twice the same tag // Test twice the same tag
"$markdownPattern$name$markdownPattern and $markdownPattern$name bis$markdownPattern" "$markdownPattern$name$markdownPattern and $markdownPattern$name bis$markdownPattern"
.let { .let {
markdownParser.parse(it) markdownParser.parse(it)
.expect(expectedText = it, .expect(
expectedFormattedText = "<$htmlExpectedTag>$name</$htmlExpectedTag> and <$htmlExpectedTag>$name bis</$htmlExpectedTag>") expectedText = it,
expectedFormattedText = "<$htmlExpectedTag>$name</$htmlExpectedTag> and <$htmlExpectedTag>$name bis</$htmlExpectedTag>"
)
} }
val textBefore = "a" val textBefore = "a"
@ -313,48 +319,60 @@ class MarkdownParserTest : InstrumentedTest {
"$textBefore$markdownPattern$name$markdownPattern" "$textBefore$markdownPattern$name$markdownPattern"
.let { .let {
markdownParser.parse(it) markdownParser.parse(it)
.expect(expectedText = it, .expect(
expectedFormattedText = "$textBefore<$htmlExpectedTag>$name</$htmlExpectedTag>") expectedText = it,
expectedFormattedText = "$textBefore<$htmlExpectedTag>$name</$htmlExpectedTag>"
)
} }
// With text before and space // With text before and space
"$textBefore $markdownPattern$name$markdownPattern" "$textBefore $markdownPattern$name$markdownPattern"
.let { .let {
markdownParser.parse(it) markdownParser.parse(it)
.expect(expectedText = it, .expect(
expectedFormattedText = "$textBefore <$htmlExpectedTag>$name</$htmlExpectedTag>") expectedText = it,
expectedFormattedText = "$textBefore <$htmlExpectedTag>$name</$htmlExpectedTag>"
)
} }
// With sticked text after // With sticked text after
"$markdownPattern$name$markdownPattern$textAfter" "$markdownPattern$name$markdownPattern$textAfter"
.let { .let {
markdownParser.parse(it) markdownParser.parse(it)
.expect(expectedText = it, .expect(
expectedFormattedText = "<$htmlExpectedTag>$name</$htmlExpectedTag>$textAfter") expectedText = it,
expectedFormattedText = "<$htmlExpectedTag>$name</$htmlExpectedTag>$textAfter"
)
} }
// With space and text after // With space and text after
"$markdownPattern$name$markdownPattern $textAfter" "$markdownPattern$name$markdownPattern $textAfter"
.let { .let {
markdownParser.parse(it) markdownParser.parse(it)
.expect(expectedText = it, .expect(
expectedFormattedText = "<$htmlExpectedTag>$name</$htmlExpectedTag> $textAfter") expectedText = it,
expectedFormattedText = "<$htmlExpectedTag>$name</$htmlExpectedTag> $textAfter"
)
} }
// With sticked text before and text after // With sticked text before and text after
"$textBefore$markdownPattern$name$markdownPattern$textAfter" "$textBefore$markdownPattern$name$markdownPattern$textAfter"
.let { .let {
markdownParser.parse(it) markdownParser.parse(it)
.expect(expectedText = it, .expect(
expectedFormattedText = "a<$htmlExpectedTag>$name</$htmlExpectedTag>$textAfter") expectedText = it,
expectedFormattedText = "a<$htmlExpectedTag>$name</$htmlExpectedTag>$textAfter"
)
} }
// With text before and after, with spaces // With text before and after, with spaces
"$textBefore $markdownPattern$name$markdownPattern $textAfter" "$textBefore $markdownPattern$name$markdownPattern $textAfter"
.let { .let {
markdownParser.parse(it) markdownParser.parse(it)
.expect(expectedText = it, .expect(
expectedFormattedText = "$textBefore <$htmlExpectedTag>$name</$htmlExpectedTag> $textAfter") expectedText = it,
expectedFormattedText = "$textBefore <$htmlExpectedTag>$name</$htmlExpectedTag> $textAfter"
)
} }
} }
@ -366,16 +384,20 @@ class MarkdownParserTest : InstrumentedTest {
"$markdownPattern$name\n$name$markdownPattern" "$markdownPattern$name\n$name$markdownPattern"
.let { .let {
markdownParser.parse(it) markdownParser.parse(it)
.expect(expectedText = it, .expect(
expectedFormattedText = "<$htmlExpectedTag>$name$softBreak$name</$htmlExpectedTag>") expectedText = it,
expectedFormattedText = "<$htmlExpectedTag>$name$softBreak$name</$htmlExpectedTag>"
)
} }
// With new line between two blocks // With new line between two blocks
"$markdownPattern$name$markdownPattern\n$markdownPattern$name$markdownPattern" "$markdownPattern$name$markdownPattern\n$markdownPattern$name$markdownPattern"
.let { .let {
markdownParser.parse(it) markdownParser.parse(it)
.expect(expectedText = it, .expect(
expectedFormattedText = "<$htmlExpectedTag>$name</$htmlExpectedTag><br /><$htmlExpectedTag>$name</$htmlExpectedTag>") expectedText = it,
expectedFormattedText = "<$htmlExpectedTag>$name</$htmlExpectedTag><br /><$htmlExpectedTag>$name</$htmlExpectedTag>"
)
} }
} }

View File

@ -39,27 +39,35 @@ internal class JsonCanonicalizerTest : InstrumentedTest {
"""{"a":["c":"b","d":"e"]}""", """{"a":["c":"b","d":"e"]}""",
"""{"a":["d":"b","c":"e"]}""" """{"a":["d":"b","c":"e"]}"""
).forEach { ).forEach {
assertEquals(it, assertEquals(
JsonCanonicalizer.canonicalize(it)) it,
JsonCanonicalizer.canonicalize(it)
)
} }
} }
@Test @Test
fun reorderTest() { fun reorderTest() {
assertEquals("""{"a":true,"b":false}""", assertEquals(
JsonCanonicalizer.canonicalize("""{"b":false,"a":true}""")) """{"a":true,"b":false}""",
JsonCanonicalizer.canonicalize("""{"b":false,"a":true}""")
)
} }
@Test @Test
fun realSampleTest() { fun realSampleTest() {
assertEquals("""{"algorithms":["m.megolm.v1.aes-sha2","m.olm.v1.curve25519-aes-sha2"],"device_id":"VSCUNFSOUI","keys":{"curve25519:VSCUNFSOUI":"utyOjnhiQ73qNhi9HlN0OgWIowe5gthTS8r0r9TcJ3o","ed25519:VSCUNFSOUI":"qNhEt+Yggaajet0hX\/FjTRLfySgs65ldYyomm7PIx6U"},"user_id":"@benoitx:matrix.org"}""", assertEquals(
JsonCanonicalizer.canonicalize("""{"algorithms":["m.megolm.v1.aes-sha2","m.olm.v1.curve25519-aes-sha2"],"device_id":"VSCUNFSOUI","user_id":"@benoitx:matrix.org","keys":{"curve25519:VSCUNFSOUI":"utyOjnhiQ73qNhi9HlN0OgWIowe5gthTS8r0r9TcJ3o","ed25519:VSCUNFSOUI":"qNhEt+Yggaajet0hX/FjTRLfySgs65ldYyomm7PIx6U"}}""")) """{"algorithms":["m.megolm.v1.aes-sha2","m.olm.v1.curve25519-aes-sha2"],"device_id":"VSCUNFSOUI","keys":{"curve25519:VSCUNFSOUI":"utyOjnhiQ73qNhi9HlN0OgWIowe5gthTS8r0r9TcJ3o","ed25519:VSCUNFSOUI":"qNhEt+Yggaajet0hX\/FjTRLfySgs65ldYyomm7PIx6U"},"user_id":"@benoitx:matrix.org"}""",
JsonCanonicalizer.canonicalize("""{"algorithms":["m.megolm.v1.aes-sha2","m.olm.v1.curve25519-aes-sha2"],"device_id":"VSCUNFSOUI","user_id":"@benoitx:matrix.org","keys":{"curve25519:VSCUNFSOUI":"utyOjnhiQ73qNhi9HlN0OgWIowe5gthTS8r0r9TcJ3o","ed25519:VSCUNFSOUI":"qNhEt+Yggaajet0hX/FjTRLfySgs65ldYyomm7PIx6U"}}""")
)
} }
@Test @Test
fun doubleQuoteTest() { fun doubleQuoteTest() {
assertEquals("{\"a\":\"\\\"\"}", assertEquals(
JsonCanonicalizer.canonicalize("{\"a\":\"\\\"\"}")) "{\"a\":\"\\\"\"}",
JsonCanonicalizer.canonicalize("{\"a\":\"\\\"\"}")
)
} }
/* ========================================================================================== /* ==========================================================================================
@ -68,38 +76,52 @@ internal class JsonCanonicalizerTest : InstrumentedTest {
@Test @Test
fun matrixOrg001Test() { fun matrixOrg001Test() {
assertEquals("""{}""", assertEquals(
JsonCanonicalizer.canonicalize("""{}""")) """{}""",
JsonCanonicalizer.canonicalize("""{}""")
)
} }
@Test @Test
fun matrixOrg002Test() { fun matrixOrg002Test() {
assertEquals("""{"one":1,"two":"Two"}""", assertEquals(
JsonCanonicalizer.canonicalize("""{ """{"one":1,"two":"Two"}""",
JsonCanonicalizer.canonicalize(
"""{
"one": 1, "one": 1,
"two": "Two" "two": "Two"
}""")) }"""
)
)
} }
@Test @Test
fun matrixOrg003Test() { fun matrixOrg003Test() {
assertEquals("""{"a":"1","b":"2"}""", assertEquals(
JsonCanonicalizer.canonicalize("""{ """{"a":"1","b":"2"}""",
JsonCanonicalizer.canonicalize(
"""{
"b": "2", "b": "2",
"a": "1" "a": "1"
}""")) }"""
)
)
} }
@Test @Test
fun matrixOrg004Test() { fun matrixOrg004Test() {
assertEquals("""{"a":"1","b":"2"}""", assertEquals(
JsonCanonicalizer.canonicalize("""{"b":"2","a":"1"}""")) """{"a":"1","b":"2"}""",
JsonCanonicalizer.canonicalize("""{"b":"2","a":"1"}""")
)
} }
@Test @Test
fun matrixOrg005Test() { fun matrixOrg005Test() {
assertEquals("""{"auth":{"mxid":"@john.doe:example.com","profile":{"display_name":"John Doe","three_pids":[{"address":"john.doe@example.org","medium":"email"},{"address":"123456789","medium":"msisdn"}]},"success":true}}""", assertEquals(
JsonCanonicalizer.canonicalize("""{ """{"auth":{"mxid":"@john.doe:example.com","profile":{"display_name":"John Doe","three_pids":[{"address":"john.doe@example.org","medium":"email"},{"address":"123456789","medium":"msisdn"}]},"success":true}}""",
JsonCanonicalizer.canonicalize(
"""{
"auth": { "auth": {
"success": true, "success": true,
"mxid": "@john.doe:example.com", "mxid": "@john.doe:example.com",
@ -117,37 +139,53 @@ internal class JsonCanonicalizerTest : InstrumentedTest {
] ]
} }
} }
}""")) }"""
)
)
} }
@Test @Test
fun matrixOrg006Test() { fun matrixOrg006Test() {
assertEquals("""{"a":"日本語"}""", assertEquals(
JsonCanonicalizer.canonicalize("""{ """{"a":"日本語"}""",
JsonCanonicalizer.canonicalize(
"""{
"a": "日本語" "a": "日本語"
}""")) }"""
)
)
} }
@Test @Test
fun matrixOrg007Test() { fun matrixOrg007Test() {
assertEquals("""{"日":1,"本":2}""", assertEquals(
JsonCanonicalizer.canonicalize("""{ """{"日":1,"本":2}""",
JsonCanonicalizer.canonicalize(
"""{
"": 2, "": 2,
"": 1 "": 1
}""")) }"""
)
)
} }
@Test @Test
fun matrixOrg008Test() { fun matrixOrg008Test() {
assertEquals("""{"a":"日"}""", assertEquals(
JsonCanonicalizer.canonicalize("{\"a\": \"\u65E5\"}")) """{"a":"日"}""",
JsonCanonicalizer.canonicalize("{\"a\": \"\u65E5\"}")
)
} }
@Test @Test
fun matrixOrg009Test() { fun matrixOrg009Test() {
assertEquals("""{"a":null}""", assertEquals(
JsonCanonicalizer.canonicalize("""{ """{"a":null}""",
JsonCanonicalizer.canonicalize(
"""{
"a": null "a": null
}""")) }"""
)
)
} }
} }

View File

@ -26,9 +26,18 @@ class StringOrderTest {
@Test @Test
fun testbasing() { fun testbasing() {
assertEquals("a", StringOrderUtils.baseToString(StringOrderUtils.stringToBase("a", StringOrderUtils.DEFAULT_ALPHABET), StringOrderUtils.DEFAULT_ALPHABET)) assertEquals(
assertEquals("element", StringOrderUtils.baseToString(StringOrderUtils.stringToBase("element", StringOrderUtils.DEFAULT_ALPHABET), StringOrderUtils.DEFAULT_ALPHABET)) "a",
assertEquals("matrix", StringOrderUtils.baseToString(StringOrderUtils.stringToBase("matrix", StringOrderUtils.DEFAULT_ALPHABET), StringOrderUtils.DEFAULT_ALPHABET)) StringOrderUtils.baseToString(StringOrderUtils.stringToBase("a", StringOrderUtils.DEFAULT_ALPHABET), StringOrderUtils.DEFAULT_ALPHABET)
)
assertEquals(
"element",
StringOrderUtils.baseToString(StringOrderUtils.stringToBase("element", StringOrderUtils.DEFAULT_ALPHABET), StringOrderUtils.DEFAULT_ALPHABET)
)
assertEquals(
"matrix",
StringOrderUtils.baseToString(StringOrderUtils.stringToBase("matrix", StringOrderUtils.DEFAULT_ALPHABET), StringOrderUtils.DEFAULT_ALPHABET)
)
} }
@Test @Test

View File

@ -59,7 +59,8 @@ class ThreadMessagingTest : InstrumentedTest {
val sentMessages = commonTestHelper.sendTextMessage( val sentMessages = commonTestHelper.sendTextMessage(
room = aliceRoom, room = aliceRoom,
message = textMessage, message = textMessage,
nbOfMessages = 1) nbOfMessages = 1
)
val initMessage = sentMessages.first() val initMessage = sentMessages.first()
@ -73,7 +74,8 @@ class ThreadMessagingTest : InstrumentedTest {
room = aliceRoom, room = aliceRoom,
message = "Reply In the above thread", message = "Reply In the above thread",
numberOfMessages = 1, numberOfMessages = 1,
rootThreadEventId = initMessage.root.eventId.orEmpty()) rootThreadEventId = initMessage.root.eventId.orEmpty()
)
val replyInThread = repliesInThread.first() val replyInThread = repliesInThread.first()
replyInThread.root.isThread().shouldBeTrue() replyInThread.root.isThread().shouldBeTrue()
@ -116,7 +118,8 @@ class ThreadMessagingTest : InstrumentedTest {
val sentMessages = commonTestHelper.sendTextMessage( val sentMessages = commonTestHelper.sendTextMessage(
room = aliceRoom, room = aliceRoom,
message = textMessage, message = textMessage,
nbOfMessages = 1) nbOfMessages = 1
)
val initMessage = sentMessages.first() val initMessage = sentMessages.first()
@ -134,7 +137,8 @@ class ThreadMessagingTest : InstrumentedTest {
room = bobRoom, room = bobRoom,
message = "Reply In the above thread", message = "Reply In the above thread",
numberOfMessages = 1, numberOfMessages = 1,
rootThreadEventId = initMessage.root.eventId.orEmpty()) rootThreadEventId = initMessage.root.eventId.orEmpty()
)
val replyInThread = repliesInThread.first() val replyInThread = repliesInThread.first()
replyInThread.root.isThread().shouldBeTrue() replyInThread.root.isThread().shouldBeTrue()
@ -190,7 +194,8 @@ class ThreadMessagingTest : InstrumentedTest {
val sentMessages = commonTestHelper.sendTextMessage( val sentMessages = commonTestHelper.sendTextMessage(
room = aliceRoom, room = aliceRoom,
message = textMessage, message = textMessage,
nbOfMessages = 5) nbOfMessages = 5
)
sentMessages.forEach { sentMessages.forEach {
it.root.isThread().shouldBeFalse() it.root.isThread().shouldBeFalse()
@ -206,7 +211,8 @@ class ThreadMessagingTest : InstrumentedTest {
room = aliceRoom, room = aliceRoom,
message = "Reply In the above thread", message = "Reply In the above thread",
numberOfMessages = 40, numberOfMessages = 40,
rootThreadEventId = selectedInitMessage.root.eventId.orEmpty()) rootThreadEventId = selectedInitMessage.root.eventId.orEmpty()
)
repliesInThread.forEach { repliesInThread.forEach {
it.root.isThread().shouldBeTrue() it.root.isThread().shouldBeTrue()
@ -253,7 +259,8 @@ class ThreadMessagingTest : InstrumentedTest {
val sentMessages = commonTestHelper.sendTextMessage( val sentMessages = commonTestHelper.sendTextMessage(
room = aliceRoom, room = aliceRoom,
message = textMessage, message = textMessage,
nbOfMessages = 5) nbOfMessages = 5
)
sentMessages.forEach { sentMessages.forEach {
it.root.isThread().shouldBeFalse() it.root.isThread().shouldBeFalse()
@ -270,7 +277,8 @@ class ThreadMessagingTest : InstrumentedTest {
room = aliceRoom, room = aliceRoom,
message = "Alice reply In the above second thread message", message = "Alice reply In the above second thread message",
numberOfMessages = 35, numberOfMessages = 35,
rootThreadEventId = secondMessage.root.eventId.orEmpty()) rootThreadEventId = secondMessage.root.eventId.orEmpty()
)
// Let's reply in timeline to that message from another user // Let's reply in timeline to that message from another user
val bobSession = cryptoTestData.secondSession!! val bobSession = cryptoTestData.secondSession!!
@ -282,14 +290,16 @@ class ThreadMessagingTest : InstrumentedTest {
room = bobRoom, room = bobRoom,
message = "Bob reply In the above first thread message", message = "Bob reply In the above first thread message",
numberOfMessages = 42, numberOfMessages = 42,
rootThreadEventId = firstMessage.root.eventId.orEmpty()) rootThreadEventId = firstMessage.root.eventId.orEmpty()
)
// Bob will also reply in second thread 5 times // Bob will also reply in second thread 5 times
val bobThreadRepliesInSecondMessage = commonTestHelper.replyInThreadMessage( val bobThreadRepliesInSecondMessage = commonTestHelper.replyInThreadMessage(
room = bobRoom, room = bobRoom,
message = "Another Bob reply In the above second thread message", message = "Another Bob reply In the above second thread message",
numberOfMessages = 20, numberOfMessages = 20,
rootThreadEventId = secondMessage.root.eventId.orEmpty()) rootThreadEventId = secondMessage.root.eventId.orEmpty()
)
aliceThreadRepliesInSecondMessage.forEach { aliceThreadRepliesInSecondMessage.forEach {
it.root.isThread().shouldBeTrue() it.root.isThread().shouldBeTrue()

View File

@ -68,7 +68,8 @@ internal class ChunkEntityTest : InstrumentedTest {
roomId = ROOM_ID, roomId = ROOM_ID,
eventEntity = fakeEvent, eventEntity = fakeEvent,
direction = PaginationDirection.FORWARDS, direction = PaginationDirection.FORWARDS,
roomMemberContentsByUser = emptyMap()) roomMemberContentsByUser = emptyMap()
)
chunk.timelineEvents.size shouldBeEqualTo 1 chunk.timelineEvents.size shouldBeEqualTo 1
} }
} }
@ -84,12 +85,14 @@ internal class ChunkEntityTest : InstrumentedTest {
roomId = ROOM_ID, roomId = ROOM_ID,
eventEntity = fakeEvent, eventEntity = fakeEvent,
direction = PaginationDirection.FORWARDS, direction = PaginationDirection.FORWARDS,
roomMemberContentsByUser = emptyMap()) roomMemberContentsByUser = emptyMap()
)
chunk.addTimelineEvent( chunk.addTimelineEvent(
roomId = ROOM_ID, roomId = ROOM_ID,
eventEntity = fakeEvent, eventEntity = fakeEvent,
direction = PaginationDirection.FORWARDS, direction = PaginationDirection.FORWARDS,
roomMemberContentsByUser = emptyMap()) roomMemberContentsByUser = emptyMap()
)
chunk.timelineEvents.size shouldBeEqualTo 1 chunk.timelineEvents.size shouldBeEqualTo 1
} }
} }
@ -162,7 +165,8 @@ internal class ChunkEntityTest : InstrumentedTest {
roomId = roomId, roomId = roomId,
eventEntity = fakeEvent, eventEntity = fakeEvent,
direction = direction, direction = direction,
roomMemberContentsByUser = emptyMap()) roomMemberContentsByUser = emptyMap()
)
} }
} }

View File

@ -71,7 +71,8 @@ class TimelineForwardPaginationTest : InstrumentedTest {
val sentMessages = commonTestHelper.sendTextMessage( val sentMessages = commonTestHelper.sendTextMessage(
roomFromAlicePOV, roomFromAlicePOV,
message, message,
numberOfMessagesToSend) numberOfMessagesToSend
)
// Alice clear the cache and restart the sync // Alice clear the cache and restart the sync
commonTestHelper.clearCacheAndSync(aliceSession) commonTestHelper.clearCacheAndSync(aliceSession)

View File

@ -94,7 +94,8 @@ class TimelinePreviousLastForwardTest : InstrumentedTest {
val firstMessageFromAliceId = commonTestHelper.sendTextMessage( val firstMessageFromAliceId = commonTestHelper.sendTextMessage(
roomFromAlicePOV, roomFromAlicePOV,
firstMessage, firstMessage,
30) 30
)
.last() .last()
.eventId .eventId
@ -130,7 +131,8 @@ class TimelinePreviousLastForwardTest : InstrumentedTest {
commonTestHelper.sendTextMessage( commonTestHelper.sendTextMessage(
roomFromAlicePOV, roomFromAlicePOV,
secondMessage, secondMessage,
30) 30
)
// Bob start to sync // Bob start to sync
bobSession.startSync(true) bobSession.startSync(true)

View File

@ -64,7 +64,8 @@ class TimelineSimpleBackPaginationTest : InstrumentedTest {
commonTestHelper.sendTextMessage( commonTestHelper.sendTextMessage(
roomFromAlicePOV, roomFromAlicePOV,
message, message,
numberOfMessagesToSent) numberOfMessagesToSent
)
val bobTimeline = roomFromBobPOV.timelineService().createTimeline(null, TimelineSettings(30)) val bobTimeline = roomFromBobPOV.timelineService().createTimeline(null, TimelineSettings(30))
bobTimeline.start() bobTimeline.start()

View File

@ -85,7 +85,8 @@ class SearchMessagesTest : InstrumentedTest {
commonTestHelper.sendTextMessage( commonTestHelper.sendTextMessage(
roomFromAlicePOV, roomFromAlicePOV,
MESSAGE, MESSAGE,
2) 2
)
val data = commonTestHelper.runBlockingTest { val data = commonTestHelper.runBlockingTest {
block.invoke(cryptoTestData) block.invoke(cryptoTestData)

View File

@ -177,21 +177,27 @@ class SpaceHierarchyTest : InstrumentedTest {
val commonTestHelper = CommonTestHelper(context()) val commonTestHelper = CommonTestHelper(context())
val session = commonTestHelper.createAccount("John", SessionTestParams(true)) val session = commonTestHelper.createAccount("John", SessionTestParams(true))
val spaceAInfo = createPublicSpace(session, "SpaceA", listOf( val spaceAInfo = createPublicSpace(
session, "SpaceA", listOf(
Triple("A1", true /*auto-join*/, true/*canonical*/), Triple("A1", true /*auto-join*/, true/*canonical*/),
Triple("A2", true, true) Triple("A2", true, true)
)) )
)
/* val spaceBInfo = */ createPublicSpace(session, "SpaceB", listOf( /* val spaceBInfo = */ createPublicSpace(
session, "SpaceB", listOf(
Triple("B1", true /*auto-join*/, true/*canonical*/), Triple("B1", true /*auto-join*/, true/*canonical*/),
Triple("B2", true, true), Triple("B2", true, true),
Triple("B3", true, true) Triple("B3", true, true)
)) )
)
val spaceCInfo = createPublicSpace(session, "SpaceC", listOf( val spaceCInfo = createPublicSpace(
session, "SpaceC", listOf(
Triple("C1", true /*auto-join*/, true/*canonical*/), Triple("C1", true /*auto-join*/, true/*canonical*/),
Triple("C2", true, true) Triple("C2", true, true)
)) )
)
// add C as a subspace of A // add C as a subspace of A
val spaceA = session.spaceService().getSpace(spaceAInfo.spaceId) val spaceA = session.spaceService().getSpace(spaceAInfo.spaceId)
@ -254,15 +260,19 @@ class SpaceHierarchyTest : InstrumentedTest {
val commonTestHelper = CommonTestHelper(context()) val commonTestHelper = CommonTestHelper(context())
val session = commonTestHelper.createAccount("John", SessionTestParams(true)) val session = commonTestHelper.createAccount("John", SessionTestParams(true))
val spaceAInfo = createPublicSpace(session, "SpaceA", listOf( val spaceAInfo = createPublicSpace(
session, "SpaceA", listOf(
Triple("A1", true /*auto-join*/, true/*canonical*/), Triple("A1", true /*auto-join*/, true/*canonical*/),
Triple("A2", true, true) Triple("A2", true, true)
)) )
)
val spaceCInfo = createPublicSpace(session, "SpaceC", listOf( val spaceCInfo = createPublicSpace(
session, "SpaceC", listOf(
Triple("C1", true /*auto-join*/, true/*canonical*/), Triple("C1", true /*auto-join*/, true/*canonical*/),
Triple("C2", true, true) Triple("C2", true, true)
)) )
)
// add C as a subspace of A // add C as a subspace of A
val spaceA = session.spaceService().getSpace(spaceAInfo.spaceId) val spaceA = session.spaceService().getSpace(spaceAInfo.spaceId)
@ -296,16 +306,20 @@ class SpaceHierarchyTest : InstrumentedTest {
val commonTestHelper = CommonTestHelper(context()) val commonTestHelper = CommonTestHelper(context())
val session = commonTestHelper.createAccount("John", SessionTestParams(true)) val session = commonTestHelper.createAccount("John", SessionTestParams(true))
val spaceAInfo = createPublicSpace(session, "SpaceA", listOf( val spaceAInfo = createPublicSpace(
session, "SpaceA", listOf(
Triple("A1", true /*auto-join*/, true/*canonical*/), Triple("A1", true /*auto-join*/, true/*canonical*/),
Triple("A2", true, true) Triple("A2", true, true)
)) )
)
val spaceBInfo = createPublicSpace(session, "SpaceB", listOf( val spaceBInfo = createPublicSpace(
session, "SpaceB", listOf(
Triple("B1", true /*auto-join*/, true/*canonical*/), Triple("B1", true /*auto-join*/, true/*canonical*/),
Triple("B2", true, true), Triple("B2", true, true),
Triple("B3", true, true) Triple("B3", true, true)
)) )
)
// add B as a subspace of A // add B as a subspace of A
val spaceA = session.spaceService().getSpace(spaceAInfo.spaceId) val spaceA = session.spaceService().getSpace(spaceAInfo.spaceId)
@ -315,10 +329,12 @@ class SpaceHierarchyTest : InstrumentedTest {
session.spaceService().setSpaceParent(spaceBInfo.spaceId, spaceAInfo.spaceId, true, viaServers) session.spaceService().setSpaceParent(spaceBInfo.spaceId, spaceAInfo.spaceId, true, viaServers)
} }
val spaceCInfo = createPublicSpace(session, "SpaceC", listOf( val spaceCInfo = createPublicSpace(
session, "SpaceC", listOf(
Triple("C1", true /*auto-join*/, true/*canonical*/), Triple("C1", true /*auto-join*/, true/*canonical*/),
Triple("C2", true, true) Triple("C2", true, true)
)) )
)
commonTestHelper.waitWithLatch { latch -> commonTestHelper.waitWithLatch { latch ->
@ -446,21 +462,27 @@ class SpaceHierarchyTest : InstrumentedTest {
val commonTestHelper = CommonTestHelper(context()) val commonTestHelper = CommonTestHelper(context())
val session = commonTestHelper.createAccount("John", SessionTestParams(true)) val session = commonTestHelper.createAccount("John", SessionTestParams(true))
/* val spaceAInfo = */ createPublicSpace(session, "SpaceA", listOf( /* val spaceAInfo = */ createPublicSpace(
session, "SpaceA", listOf(
Triple("A1", true /*auto-join*/, true/*canonical*/), Triple("A1", true /*auto-join*/, true/*canonical*/),
Triple("A2", true, true) Triple("A2", true, true)
)) )
)
val spaceBInfo = createPublicSpace(session, "SpaceB", listOf( val spaceBInfo = createPublicSpace(
session, "SpaceB", listOf(
Triple("B1", true /*auto-join*/, true/*canonical*/), Triple("B1", true /*auto-join*/, true/*canonical*/),
Triple("B2", true, true), Triple("B2", true, true),
Triple("B3", true, true) Triple("B3", true, true)
)) )
)
val spaceCInfo = createPublicSpace(session, "SpaceC", listOf( val spaceCInfo = createPublicSpace(
session, "SpaceC", listOf(
Triple("C1", true /*auto-join*/, true/*canonical*/), Triple("C1", true /*auto-join*/, true/*canonical*/),
Triple("C2", true, true) Triple("C2", true, true)
)) )
)
val viaServers = listOf(session.sessionParams.homeServerHost ?: "") val viaServers = listOf(session.sessionParams.homeServerHost ?: "")
@ -494,10 +516,12 @@ class SpaceHierarchyTest : InstrumentedTest {
val aliceSession = commonTestHelper.createAccount("Alice", SessionTestParams(true)) val aliceSession = commonTestHelper.createAccount("Alice", SessionTestParams(true))
val bobSession = commonTestHelper.createAccount("Bib", SessionTestParams(true)) val bobSession = commonTestHelper.createAccount("Bib", SessionTestParams(true))
val spaceAInfo = createPrivateSpace(aliceSession, "Private Space A", listOf( val spaceAInfo = createPrivateSpace(
aliceSession, "Private Space A", listOf(
Triple("General", true /*suggested*/, true/*canonical*/), Triple("General", true /*suggested*/, true/*canonical*/),
Triple("Random", true, true) Triple("Random", true, true)
)) )
)
commonTestHelper.runBlockingTest { commonTestHelper.runBlockingTest {
aliceSession.getRoom(spaceAInfo.spaceId)!!.membershipService().invite(bobSession.myUserId, null) aliceSession.getRoom(spaceAInfo.spaceId)!!.membershipService().invite(bobSession.myUserId, null)

View File

@ -28,8 +28,12 @@ internal class MathsHtmlNodeRenderer(private val context: HtmlNodeRendererContex
val display = node.javaClass == DisplayMaths::class.java val display = node.javaClass == DisplayMaths::class.java
val contents = node.firstChild // should be the only child val contents = node.firstChild // should be the only child
val latex = (contents as Text).literal val latex = (contents as Text).literal
val attributes = context.extendAttributes(node, if (display) "div" else "span", Collections.singletonMap("data-mx-maths", val attributes = context.extendAttributes(
latex)) node, if (display) "div" else "span", Collections.singletonMap(
"data-mx-maths",
latex
)
)
html.tag(if (display) "div" else "span", attributes) html.tag(if (display) "div" else "span", attributes)
html.tag("code") html.tag("code")
context.render(contents) context.render(contents)

View File

@ -132,9 +132,11 @@ class Matrix private constructor(context: Context, matrixConfiguration: MatrixCo
val matrixConfiguration = (appContext as MatrixConfiguration.Provider).providesMatrixConfiguration() val matrixConfiguration = (appContext as MatrixConfiguration.Provider).providesMatrixConfiguration()
instance = Matrix(appContext, matrixConfiguration) instance = Matrix(appContext, matrixConfiguration)
} else { } else {
throw IllegalStateException("Matrix is not initialized properly." + throw IllegalStateException(
" If you want to manage your own Matrix instance use Matrix.createInstance" + "Matrix is not initialized properly." +
" otherwise you should call Matrix.initialize or let your application implement MatrixConfiguration.Provider.") " If you want to manage your own Matrix instance use Matrix.createInstance" +
" otherwise you should call Matrix.initialize or let your application implement MatrixConfiguration.Provider."
)
} }
} }
return instance return instance

View File

@ -1,127 +1,129 @@
/* /*
* Copyright 2020 The Matrix.org Foundation C.I.C. * Copyright 2020 The Matrix.org Foundation C.I.C.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
* You may obtain a copy of the License at * You may obtain a copy of the License at
* *
* http://www.apache.org/licenses/LICENSE-2.0 * http://www.apache.org/licenses/LICENSE-2.0
* *
* Unless required by applicable law or agreed to in writing, software * Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, * distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
*/ */
package org.matrix.android.sdk.api.auth package org.matrix.android.sdk.api.auth
import org.matrix.android.sdk.api.auth.data.LocalizedFlowDataLoginTerms import org.matrix.android.sdk.api.auth.data.LocalizedFlowDataLoginTerms
import org.matrix.android.sdk.api.auth.registration.TermPolicies import org.matrix.android.sdk.api.auth.registration.TermPolicies
/** /**
* This method extract the policies from the login terms parameter, regarding the user language. * This method extract the policies from the login terms parameter, regarding the user language.
* For each policy, if user language is not found, the default language is used and if not found, the first url and name are used (not predictable) * For each policy, if user language is not found, the default language is used and if not found, the first url and name are used (not predictable)
* *
* Example of Data: * Example of Data:
* <pre> * <pre>
* "m.login.terms": { * "m.login.terms": {
* "policies": { * "policies": {
* "privacy_policy": { * "privacy_policy": {
* "version": "1.0", * "version": "1.0",
* "en": { * "en": {
* "url": "http:\/\/matrix.org\/_matrix\/consent?v=1.0", * "url": "http:\/\/matrix.org\/_matrix\/consent?v=1.0",
* "name": "Terms and Conditions" * "name": "Terms and Conditions"
* } * }
* } * }
* } * }
* } * }
*</pre> *</pre>
* *
* @param userLanguage the user language * @param userLanguage the user language
* @param defaultLanguage the default language to use if the user language is not found for a policy in registrationFlowResponse * @param defaultLanguage the default language to use if the user language is not found for a policy in registrationFlowResponse
*/ */
fun TermPolicies.toLocalizedLoginTerms(userLanguage: String, fun TermPolicies.toLocalizedLoginTerms(userLanguage: String,
defaultLanguage: String = "en"): List<LocalizedFlowDataLoginTerms> { defaultLanguage: String = "en"): List<LocalizedFlowDataLoginTerms> {
val result = ArrayList<LocalizedFlowDataLoginTerms>() val result = ArrayList<LocalizedFlowDataLoginTerms>()
val policies = get("policies") val policies = get("policies")
if (policies is Map<*, *>) { if (policies is Map<*, *>) {
policies.keys.forEach { policyName -> policies.keys.forEach { policyName ->
val localizedFlowDataLoginTermsPolicyName = policyName as String val localizedFlowDataLoginTermsPolicyName = policyName as String
var localizedFlowDataLoginTermsVersion: String? = null var localizedFlowDataLoginTermsVersion: String? = null
var localizedFlowDataLoginTermsLocalizedUrl: String? = null var localizedFlowDataLoginTermsLocalizedUrl: String? = null
var localizedFlowDataLoginTermsLocalizedName: String? = null var localizedFlowDataLoginTermsLocalizedName: String? = null
val policy = policies[policyName] val policy = policies[policyName]
// Enter this policy // Enter this policy
if (policy is Map<*, *>) { if (policy is Map<*, *>) {
// Version // Version
localizedFlowDataLoginTermsVersion = policy["version"] as String? localizedFlowDataLoginTermsVersion = policy["version"] as String?
var userLanguageUrlAndName: UrlAndName? = null var userLanguageUrlAndName: UrlAndName? = null
var defaultLanguageUrlAndName: UrlAndName? = null var defaultLanguageUrlAndName: UrlAndName? = null
var firstUrlAndName: UrlAndName? = null var firstUrlAndName: UrlAndName? = null
// Search for language // Search for language
policy.keys.forEach { policyKey -> policy.keys.forEach { policyKey ->
when (policyKey) { when (policyKey) {
"version" -> Unit // Ignore "version" -> Unit // Ignore
userLanguage -> { userLanguage -> {
// We found the data for the user language // We found the data for the user language
userLanguageUrlAndName = extractUrlAndName(policy[policyKey]) userLanguageUrlAndName = extractUrlAndName(policy[policyKey])
} }
defaultLanguage -> { defaultLanguage -> {
// We found default language // We found default language
defaultLanguageUrlAndName = extractUrlAndName(policy[policyKey]) defaultLanguageUrlAndName = extractUrlAndName(policy[policyKey])
} }
else -> { else -> {
if (firstUrlAndName == null) { if (firstUrlAndName == null) {
// Get at least some data // Get at least some data
firstUrlAndName = extractUrlAndName(policy[policyKey]) firstUrlAndName = extractUrlAndName(policy[policyKey])
} }
} }
} }
} }
// Copy found language data by priority // Copy found language data by priority
when { when {
userLanguageUrlAndName != null -> { userLanguageUrlAndName != null -> {
localizedFlowDataLoginTermsLocalizedUrl = userLanguageUrlAndName!!.url localizedFlowDataLoginTermsLocalizedUrl = userLanguageUrlAndName!!.url
localizedFlowDataLoginTermsLocalizedName = userLanguageUrlAndName!!.name localizedFlowDataLoginTermsLocalizedName = userLanguageUrlAndName!!.name
} }
defaultLanguageUrlAndName != null -> { defaultLanguageUrlAndName != null -> {
localizedFlowDataLoginTermsLocalizedUrl = defaultLanguageUrlAndName!!.url localizedFlowDataLoginTermsLocalizedUrl = defaultLanguageUrlAndName!!.url
localizedFlowDataLoginTermsLocalizedName = defaultLanguageUrlAndName!!.name localizedFlowDataLoginTermsLocalizedName = defaultLanguageUrlAndName!!.name
} }
firstUrlAndName != null -> { firstUrlAndName != null -> {
localizedFlowDataLoginTermsLocalizedUrl = firstUrlAndName!!.url localizedFlowDataLoginTermsLocalizedUrl = firstUrlAndName!!.url
localizedFlowDataLoginTermsLocalizedName = firstUrlAndName!!.name localizedFlowDataLoginTermsLocalizedName = firstUrlAndName!!.name
} }
} }
} }
result.add(LocalizedFlowDataLoginTerms( result.add(
policyName = localizedFlowDataLoginTermsPolicyName, LocalizedFlowDataLoginTerms(
version = localizedFlowDataLoginTermsVersion, policyName = localizedFlowDataLoginTermsPolicyName,
localizedUrl = localizedFlowDataLoginTermsLocalizedUrl, version = localizedFlowDataLoginTermsVersion,
localizedName = localizedFlowDataLoginTermsLocalizedName localizedUrl = localizedFlowDataLoginTermsLocalizedUrl,
)) localizedName = localizedFlowDataLoginTermsLocalizedName
} )
} )
}
return result }
}
return result
private fun extractUrlAndName(policyData: Any?): UrlAndName? { }
if (policyData is Map<*, *>) {
val url = policyData["url"] as String? private fun extractUrlAndName(policyData: Any?): UrlAndName? {
val name = policyData["name"] as String? if (policyData is Map<*, *>) {
val url = policyData["url"] as String?
if (url != null && name != null) { val name = policyData["name"] as String?
return UrlAndName(url, name)
} if (url != null && name != null) {
} return UrlAndName(url, name)
return null }
} }
return null
}

View File

@ -88,8 +88,10 @@ fun RegistrationFlowResponse.toFlowResult(): FlowResult {
val isMandatory = flows?.all { type in it.stages.orEmpty() } == true val isMandatory = flows?.all { type in it.stages.orEmpty() } == true
val stage = when (type) { val stage = when (type) {
LoginFlowTypes.RECAPTCHA -> Stage.ReCaptcha(isMandatory, ((params?.get(type) as? Map<*, *>)?.get("public_key") as? String) LoginFlowTypes.RECAPTCHA -> Stage.ReCaptcha(
?: "") isMandatory, ((params?.get(type) as? Map<*, *>)?.get("public_key") as? String)
?: ""
)
LoginFlowTypes.DUMMY -> Stage.Dummy(isMandatory) LoginFlowTypes.DUMMY -> Stage.Dummy(isMandatory)
LoginFlowTypes.TERMS -> Stage.Terms(isMandatory, params?.get(type) as? TermPolicies ?: emptyMap<String, String>()) LoginFlowTypes.TERMS -> Stage.Terms(isMandatory, params?.get(type) as? TermPolicies ?: emptyMap<String, String>())
LoginFlowTypes.EMAIL_IDENTITY -> Stage.Email(isMandatory) LoginFlowTypes.EMAIL_IDENTITY -> Stage.Email(isMandatory)

View File

@ -93,7 +93,8 @@ data class CryptoCrossSigningKey(
userId = userId, userId = userId,
usages = listOf(usage.value), usages = listOf(usage.value),
keys = mapOf("ed25519:$b64key" to b64key), keys = mapOf("ed25519:$b64key" to b64key),
signatures = signMap) signatures = signMap
)
} }
} }
} }

View File

@ -68,7 +68,8 @@ interface FileService {
mxcUrl = messageContent.getFileUrl(), mxcUrl = messageContent.getFileUrl(),
fileName = messageContent.getFileName(), fileName = messageContent.getFileName(),
mimeType = messageContent.mimeType, mimeType = messageContent.mimeType,
elementToDecrypt = messageContent.encryptedFileInfo?.toElementToDecrypt()) elementToDecrypt = messageContent.encryptedFileInfo?.toElementToDecrypt()
)
/** /**
* Use this URI and pass it to intent using flag Intent.FLAG_GRANT_READ_URI_PERMISSION * Use this URI and pass it to intent using flag Intent.FLAG_GRANT_READ_URI_PERMISSION

View File

@ -379,9 +379,11 @@ internal class DefaultAuthenticationService @Inject constructor(
throw MatrixIdFailure.InvalidMatrixId throw MatrixIdFailure.InvalidMatrixId
} }
return getWellknownTask.execute(GetWellknownTask.Params( return getWellknownTask.execute(
domain = matrixId.getDomain(), GetWellknownTask.Params(
homeServerConnectionConfig = homeServerConnectionConfig) domain = matrixId.getDomain(),
homeServerConnectionConfig = homeServerConnectionConfig
)
) )
} }
@ -390,13 +392,15 @@ internal class DefaultAuthenticationService @Inject constructor(
password: String, password: String,
initialDeviceName: String, initialDeviceName: String,
deviceId: String?): Session { deviceId: String?): Session {
return directLoginTask.execute(DirectLoginTask.Params( return directLoginTask.execute(
homeServerConnectionConfig = homeServerConnectionConfig, DirectLoginTask.Params(
userId = matrixId, homeServerConnectionConfig = homeServerConnectionConfig,
password = password, userId = matrixId,
deviceName = initialDeviceName, password = password,
deviceId = deviceId deviceName = initialDeviceName,
)) deviceId = deviceId
)
)
} }
private fun buildAuthAPI(homeServerConnectionConfig: HomeServerConnectionConfig): AuthAPI { private fun buildAuthAPI(homeServerConnectionConfig: HomeServerConnectionConfig): AuthAPI {

View File

@ -21,9 +21,11 @@ import io.realm.annotations.RealmModule
/** /**
* Realm module for authentication classes * Realm module for authentication classes
*/ */
@RealmModule(library = true, @RealmModule(
library = true,
classes = [ classes = [
SessionParamsEntity::class, SessionParamsEntity::class,
PendingSessionEntity::class PendingSessionEntity::class
]) ]
)
internal class AuthRealmModule internal class AuthRealmModule

View File

@ -44,7 +44,8 @@ internal class PendingSessionMapper @Inject constructor(moshi: Moshi) {
resetPasswordData = resetPasswordData, resetPasswordData = resetPasswordData,
currentSession = entity.currentSession, currentSession = entity.currentSession,
isRegistrationStarted = entity.isRegistrationStarted, isRegistrationStarted = entity.isRegistrationStarted,
currentThreePidData = threePidData) currentThreePidData = threePidData
)
} }
fun map(sessionData: PendingSessionData?): PendingSessionEntity? { fun map(sessionData: PendingSessionData?): PendingSessionEntity? {

View File

@ -54,6 +54,7 @@ internal class SessionParamsMapper @Inject constructor(moshi: Moshi) {
sessionParams.userId, sessionParams.userId,
credentialsJson, credentialsJson,
homeServerConnectionConfigJson, homeServerConnectionConfigJson,
sessionParams.isTokenValid) sessionParams.isTokenValid
)
} }
} }

View File

@ -120,21 +120,25 @@ internal class DefaultRegistrationWizard(
RegisterAddThreePidTask.Params( RegisterAddThreePidTask.Params(
threePid, threePid,
pendingSessionData.clientSecret, pendingSessionData.clientSecret,
pendingSessionData.sendAttempt)) pendingSessionData.sendAttempt
)
)
pendingSessionData = pendingSessionData.copy(sendAttempt = pendingSessionData.sendAttempt + 1) pendingSessionData = pendingSessionData.copy(sendAttempt = pendingSessionData.sendAttempt + 1)
.also { pendingSessionStore.savePendingSessionData(it) } .also { pendingSessionStore.savePendingSessionData(it) }
val params = RegistrationParams( val params = RegistrationParams(
auth = if (threePid is RegisterThreePid.Email) { auth = if (threePid is RegisterThreePid.Email) {
AuthParams.createForEmailIdentity(safeSession, AuthParams.createForEmailIdentity(
safeSession,
ThreePidCredentials( ThreePidCredentials(
clientSecret = pendingSessionData.clientSecret, clientSecret = pendingSessionData.clientSecret,
sid = response.sid sid = response.sid
) )
) )
} else { } else {
AuthParams.createForMsisdnIdentity(safeSession, AuthParams.createForMsisdnIdentity(
safeSession,
ThreePidCredentials( ThreePidCredentials(
clientSecret = pendingSessionData.clientSecret, clientSecret = pendingSessionData.clientSecret,
sid = response.sid sid = response.sid

View File

@ -712,8 +712,10 @@ internal class DefaultCryptoService @Inject constructor(
}.foldToCallback(callback) }.foldToCallback(callback)
} else { } else {
val algorithm = getEncryptionAlgorithm(roomId) val algorithm = getEncryptionAlgorithm(roomId)
val reason = String.format(MXCryptoError.UNABLE_TO_ENCRYPT_REASON, val reason = String.format(
algorithm ?: MXCryptoError.NO_MORE_ALGORITHM_REASON) MXCryptoError.UNABLE_TO_ENCRYPT_REASON,
algorithm ?: MXCryptoError.NO_MORE_ALGORITHM_REASON
)
Timber.tag(loggerTag.value).e("encryptEventContent() : failed $reason") Timber.tag(loggerTag.value).e("encryptEventContent() : failed $reason")
callback.onFailure(Failure.CryptoError(MXCryptoError.Base(MXCryptoError.ErrorType.UNABLE_TO_ENCRYPT, reason))) callback.onFailure(Failure.CryptoError(MXCryptoError.Base(MXCryptoError.ErrorType.UNABLE_TO_ENCRYPT, reason)))
} }

View File

@ -73,7 +73,7 @@ internal class SendGossipRequestWorker(context: Context, params: WorkerParameter
val eventType: String val eventType: String
val requestId: String val requestId: String
when { when {
params.keyShareRequest != null -> { params.keyShareRequest != null -> {
eventType = EventType.ROOM_KEY_REQUEST eventType = EventType.ROOM_KEY_REQUEST
requestId = params.keyShareRequest.requestId requestId = params.keyShareRequest.requestId
val toDeviceContent = RoomKeyShareRequest( val toDeviceContent = RoomKeyShareRequest(
@ -120,7 +120,7 @@ internal class SendGossipRequestWorker(context: Context, params: WorkerParameter
} }
} }
} }
else -> { else -> {
return buildErrorResult(params, "Unknown empty gossiping request").also { return buildErrorResult(params, "Unknown empty gossiping request").also {
Timber.e("Unknown empty gossiping request: $params") Timber.e("Unknown empty gossiping request: $params")
} }

View File

@ -137,10 +137,14 @@ internal class EnsureOlmSessionsForDevicesAction @Inject constructor(
olmDevice.verifySignature(fingerprint, oneTimeKey.signalableJSONDictionary(), signature) olmDevice.verifySignature(fingerprint, oneTimeKey.signalableJSONDictionary(), signature)
isVerified = true isVerified = true
} catch (e: Exception) { } catch (e: Exception) {
Timber.tag(loggerTag.value).d(e, "verifyKeyAndStartSession() : Verify error for otk: ${oneTimeKey.signalableJSONDictionary()}," + Timber.tag(loggerTag.value).d(
" signature:$signature fingerprint:$fingerprint") e, "verifyKeyAndStartSession() : Verify error for otk: ${oneTimeKey.signalableJSONDictionary()}," +
Timber.tag(loggerTag.value).e("verifyKeyAndStartSession() : Verify error for ${deviceInfo.userId}|${deviceInfo.deviceId} " + " signature:$signature fingerprint:$fingerprint"
" - signable json ${oneTimeKey.signalableJSONDictionary()}") )
Timber.tag(loggerTag.value).e(
"verifyKeyAndStartSession() : Verify error for ${deviceInfo.userId}|${deviceInfo.deviceId} " +
" - signable json ${oneTimeKey.signalableJSONDictionary()}"
)
errorMessage = e.message errorMessage = e.message
} }

View File

@ -96,11 +96,13 @@ internal class MXMegolmDecryption(private val userId: String,
} }
return runCatching { return runCatching {
olmDevice.decryptGroupMessage(encryptedEventContent.ciphertext, olmDevice.decryptGroupMessage(
encryptedEventContent.ciphertext,
event.roomId, event.roomId,
timeline, timeline,
encryptedEventContent.sessionId, encryptedEventContent.sessionId,
encryptedEventContent.senderKey) encryptedEventContent.senderKey
)
} }
.fold( .fold(
{ olmDecryptionResult -> { olmDecryptionResult ->
@ -132,9 +134,11 @@ internal class MXMegolmDecryption(private val userId: String,
requestKeysForEvent(event, true) requestKeysForEvent(event, true)
} }
// Encapsulate as withHeld exception // Encapsulate as withHeld exception
throw MXCryptoError.Base(MXCryptoError.ErrorType.KEYS_WITHHELD, throw MXCryptoError.Base(
MXCryptoError.ErrorType.KEYS_WITHHELD,
withHeldInfo.code?.value ?: "", withHeldInfo.code?.value ?: "",
withHeldInfo.reason) withHeldInfo.reason
)
} }
if (requestKeysOnFail) { if (requestKeysOnFail) {
@ -144,7 +148,8 @@ internal class MXMegolmDecryption(private val userId: String,
throw MXCryptoError.Base( throw MXCryptoError.Base(
MXCryptoError.ErrorType.UNKNOWN_MESSAGE_INDEX, MXCryptoError.ErrorType.UNKNOWN_MESSAGE_INDEX,
"UNKNOWN_MESSAGE_INDEX", "UNKNOWN_MESSAGE_INDEX",
null) null
)
} }
val reason = String.format(MXCryptoError.OLM_REASON, throwable.olmException.message) val reason = String.format(MXCryptoError.OLM_REASON, throwable.olmException.message)
@ -153,7 +158,8 @@ internal class MXMegolmDecryption(private val userId: String,
throw MXCryptoError.Base( throw MXCryptoError.Base(
MXCryptoError.ErrorType.OLM, MXCryptoError.ErrorType.OLM,
reason, reason,
detailedReason) detailedReason
)
} }
if (throwable is MXCryptoError.Base) { if (throwable is MXCryptoError.Base) {
if ( if (
@ -166,9 +172,11 @@ internal class MXMegolmDecryption(private val userId: String,
requestKeysForEvent(event, true) requestKeysForEvent(event, true)
} }
// Encapsulate as withHeld exception // Encapsulate as withHeld exception
throw MXCryptoError.Base(MXCryptoError.ErrorType.KEYS_WITHHELD, throw MXCryptoError.Base(
MXCryptoError.ErrorType.KEYS_WITHHELD,
withHeldInfo.code?.value ?: "", withHeldInfo.code?.value ?: "",
withHeldInfo.reason) withHeldInfo.reason
)
} else { } else {
// This is un-used in Matrix Android SDK2, not sure if needed // This is un-used in Matrix Android SDK2, not sure if needed
// addEventToPendingList(event, timeline) // addEventToPendingList(event, timeline)
@ -298,13 +306,15 @@ internal class MXMegolmDecryption(private val userId: String,
} }
Timber.tag(loggerTag.value).i("onRoomKeyEvent addInboundGroupSession ${roomKeyContent.sessionId}") Timber.tag(loggerTag.value).i("onRoomKeyEvent addInboundGroupSession ${roomKeyContent.sessionId}")
val added = olmDevice.addInboundGroupSession(roomKeyContent.sessionId, val added = olmDevice.addInboundGroupSession(
roomKeyContent.sessionId,
roomKeyContent.sessionKey, roomKeyContent.sessionKey,
roomKeyContent.roomId, roomKeyContent.roomId,
senderKey, senderKey,
forwardingCurve25519KeyChain, forwardingCurve25519KeyChain,
keysClaimed, keysClaimed,
exportFormat) exportFormat
)
if (added) { if (added) {
defaultKeysBackupService.maybeBackupKeys() defaultKeysBackupService.maybeBackupKeys()

View File

@ -56,6 +56,7 @@ internal class MXMegolmDecryptionFactory @Inject constructor(
sendToDeviceTask, sendToDeviceTask,
coroutineDispatchers, coroutineDispatchers,
cryptoCoroutineScope, cryptoCoroutineScope,
eventsManager) eventsManager
)
} }
} }

View File

@ -337,8 +337,9 @@ internal class MXMegolmEncryption(
sessionId: String, sessionId: String,
senderKey: String?, senderKey: String?,
code: WithHeldCode) { code: WithHeldCode) {
Timber.tag(loggerTag.value).d("notifyKeyWithHeld() :sending withheld for session:$sessionId and code $code to" + Timber.tag(loggerTag.value).d(
" ${targets.joinToString { "${it.userId}|${it.deviceId}" }}" "notifyKeyWithHeld() :sending withheld for session:$sessionId and code $code to" +
" ${targets.joinToString { "${it.userId}|${it.deviceId}" }}"
) )
val withHeldContent = RoomKeyWithHeldContent( val withHeldContent = RoomKeyWithHeldContent(
roomId = roomId, roomId = roomId,

View File

@ -36,6 +36,7 @@ internal class SharedWithHelper(
userId = deviceInfo.userId, userId = deviceInfo.userId,
deviceId = deviceInfo.deviceId, deviceId = deviceInfo.deviceId,
deviceIdentityKey = deviceInfo.identityKey() ?: "", deviceIdentityKey = deviceInfo.identityKey() ?: "",
chainIndex = chainIndex) chainIndex = chainIndex
)
} }
} }

View File

@ -45,20 +45,26 @@ internal class MXOlmDecryption(
override suspend fun decryptEvent(event: Event, timeline: String): MXEventDecryptionResult { override suspend fun decryptEvent(event: Event, timeline: String): MXEventDecryptionResult {
val olmEventContent = event.content.toModel<OlmEventContent>() ?: run { val olmEventContent = event.content.toModel<OlmEventContent>() ?: run {
Timber.tag(loggerTag.value).e("## decryptEvent() : bad event format") Timber.tag(loggerTag.value).e("## decryptEvent() : bad event format")
throw MXCryptoError.Base(MXCryptoError.ErrorType.BAD_EVENT_FORMAT, throw MXCryptoError.Base(
MXCryptoError.BAD_EVENT_FORMAT_TEXT_REASON) MXCryptoError.ErrorType.BAD_EVENT_FORMAT,
MXCryptoError.BAD_EVENT_FORMAT_TEXT_REASON
)
} }
val cipherText = olmEventContent.ciphertext ?: run { val cipherText = olmEventContent.ciphertext ?: run {
Timber.tag(loggerTag.value).e("## decryptEvent() : missing cipher text") Timber.tag(loggerTag.value).e("## decryptEvent() : missing cipher text")
throw MXCryptoError.Base(MXCryptoError.ErrorType.MISSING_CIPHER_TEXT, throw MXCryptoError.Base(
MXCryptoError.MISSING_CIPHER_TEXT_REASON) MXCryptoError.ErrorType.MISSING_CIPHER_TEXT,
MXCryptoError.MISSING_CIPHER_TEXT_REASON
)
} }
val senderKey = olmEventContent.senderKey ?: run { val senderKey = olmEventContent.senderKey ?: run {
Timber.tag(loggerTag.value).e("## decryptEvent() : missing sender key") Timber.tag(loggerTag.value).e("## decryptEvent() : missing sender key")
throw MXCryptoError.Base(MXCryptoError.ErrorType.MISSING_SENDER_KEY, throw MXCryptoError.Base(
MXCryptoError.MISSING_SENDER_KEY_TEXT_REASON) MXCryptoError.ErrorType.MISSING_SENDER_KEY,
MXCryptoError.MISSING_SENDER_KEY_TEXT_REASON
)
} }
val messageAny = cipherText[olmDevice.deviceCurve25519Key] ?: run { val messageAny = cipherText[olmDevice.deviceCurve25519Key] ?: run {
@ -98,52 +104,70 @@ internal class MXOlmDecryption(
} }
if (olmPayloadContent.recipient != userId) { if (olmPayloadContent.recipient != userId) {
Timber.tag(loggerTag.value).e("## decryptEvent() : Event ${event.eventId}:" + Timber.tag(loggerTag.value).e(
" Intended recipient ${olmPayloadContent.recipient} does not match our id $userId") "## decryptEvent() : Event ${event.eventId}:" +
throw MXCryptoError.Base(MXCryptoError.ErrorType.BAD_RECIPIENT, " Intended recipient ${olmPayloadContent.recipient} does not match our id $userId"
String.format(MXCryptoError.BAD_RECIPIENT_REASON, olmPayloadContent.recipient)) )
throw MXCryptoError.Base(
MXCryptoError.ErrorType.BAD_RECIPIENT,
String.format(MXCryptoError.BAD_RECIPIENT_REASON, olmPayloadContent.recipient)
)
} }
val recipientKeys = olmPayloadContent.recipientKeys ?: run { val recipientKeys = olmPayloadContent.recipientKeys ?: run {
Timber.tag(loggerTag.value).e("## decryptEvent() : Olm event (id=${event.eventId}) contains no 'recipient_keys'" + Timber.tag(loggerTag.value).e(
" property; cannot prevent unknown-key attack") "## decryptEvent() : Olm event (id=${event.eventId}) contains no 'recipient_keys'" +
throw MXCryptoError.Base(MXCryptoError.ErrorType.MISSING_PROPERTY, " property; cannot prevent unknown-key attack"
String.format(MXCryptoError.ERROR_MISSING_PROPERTY_REASON, "recipient_keys")) )
throw MXCryptoError.Base(
MXCryptoError.ErrorType.MISSING_PROPERTY,
String.format(MXCryptoError.ERROR_MISSING_PROPERTY_REASON, "recipient_keys")
)
} }
val ed25519 = recipientKeys["ed25519"] val ed25519 = recipientKeys["ed25519"]
if (ed25519 != olmDevice.deviceEd25519Key) { if (ed25519 != olmDevice.deviceEd25519Key) {
Timber.tag(loggerTag.value).e("## decryptEvent() : Event ${event.eventId}: Intended recipient ed25519 key $ed25519 did not match ours") Timber.tag(loggerTag.value).e("## decryptEvent() : Event ${event.eventId}: Intended recipient ed25519 key $ed25519 did not match ours")
throw MXCryptoError.Base(MXCryptoError.ErrorType.BAD_RECIPIENT_KEY, throw MXCryptoError.Base(
MXCryptoError.BAD_RECIPIENT_KEY_REASON) MXCryptoError.ErrorType.BAD_RECIPIENT_KEY,
MXCryptoError.BAD_RECIPIENT_KEY_REASON
)
} }
if (olmPayloadContent.sender.isNullOrBlank()) { if (olmPayloadContent.sender.isNullOrBlank()) {
Timber.tag(loggerTag.value) Timber.tag(loggerTag.value)
.e("## decryptEvent() : Olm event (id=${event.eventId}) contains no 'sender' property; cannot prevent unknown-key attack") .e("## decryptEvent() : Olm event (id=${event.eventId}) contains no 'sender' property; cannot prevent unknown-key attack")
throw MXCryptoError.Base(MXCryptoError.ErrorType.MISSING_PROPERTY, throw MXCryptoError.Base(
String.format(MXCryptoError.ERROR_MISSING_PROPERTY_REASON, "sender")) MXCryptoError.ErrorType.MISSING_PROPERTY,
String.format(MXCryptoError.ERROR_MISSING_PROPERTY_REASON, "sender")
)
} }
if (olmPayloadContent.sender != event.senderId) { if (olmPayloadContent.sender != event.senderId) {
Timber.tag(loggerTag.value) Timber.tag(loggerTag.value)
.e("Event ${event.eventId}: sender ${olmPayloadContent.sender} does not match reported sender ${event.senderId}") .e("Event ${event.eventId}: sender ${olmPayloadContent.sender} does not match reported sender ${event.senderId}")
throw MXCryptoError.Base(MXCryptoError.ErrorType.FORWARDED_MESSAGE, throw MXCryptoError.Base(
String.format(MXCryptoError.FORWARDED_MESSAGE_REASON, olmPayloadContent.sender)) MXCryptoError.ErrorType.FORWARDED_MESSAGE,
String.format(MXCryptoError.FORWARDED_MESSAGE_REASON, olmPayloadContent.sender)
)
} }
if (olmPayloadContent.roomId != event.roomId) { if (olmPayloadContent.roomId != event.roomId) {
Timber.tag(loggerTag.value) Timber.tag(loggerTag.value)
.e("## decryptEvent() : Event ${event.eventId}: room ${olmPayloadContent.roomId} does not match reported room ${event.roomId}") .e("## decryptEvent() : Event ${event.eventId}: room ${olmPayloadContent.roomId} does not match reported room ${event.roomId}")
throw MXCryptoError.Base(MXCryptoError.ErrorType.BAD_ROOM, throw MXCryptoError.Base(
String.format(MXCryptoError.BAD_ROOM_REASON, olmPayloadContent.roomId)) MXCryptoError.ErrorType.BAD_ROOM,
String.format(MXCryptoError.BAD_ROOM_REASON, olmPayloadContent.roomId)
)
} }
val keys = olmPayloadContent.keys ?: run { val keys = olmPayloadContent.keys ?: run {
Timber.tag(loggerTag.value).e("## decryptEvent failed : null keys") Timber.tag(loggerTag.value).e("## decryptEvent failed : null keys")
throw MXCryptoError.Base(MXCryptoError.ErrorType.UNABLE_TO_DECRYPT, throw MXCryptoError.Base(
MXCryptoError.MISSING_CIPHER_TEXT_REASON) MXCryptoError.ErrorType.UNABLE_TO_DECRYPT,
MXCryptoError.MISSING_CIPHER_TEXT_REASON
)
} }
return MXEventDecryptionResult( return MXEventDecryptionResult(

View File

@ -26,6 +26,7 @@ internal class MXOlmDecryptionFactory @Inject constructor(private val olmDevice:
fun create(): MXOlmDecryption { fun create(): MXOlmDecryption {
return MXOlmDecryption( return MXOlmDecryption(
olmDevice, olmDevice,
userId) userId
)
} }
} }

View File

@ -38,6 +38,7 @@ internal class MXOlmEncryptionFactory @Inject constructor(private val olmDevice:
cryptoStore, cryptoStore,
messageEncrypter, messageEncrypter,
deviceListManager, deviceListManager,
ensureOlmSessionsForUsersAction) ensureOlmSessionsForUsersAction
)
} }
} }

View File

@ -566,8 +566,10 @@ internal class DefaultCrossSigningService @Inject constructor(
} }
// Sign the other MasterKey with our UserSigning key // Sign the other MasterKey with our UserSigning key
val newSignature = JsonCanonicalizer.getCanonicalJson(Map::class.java, val newSignature = JsonCanonicalizer.getCanonicalJson(
otherMasterKeys.signalableJSONDictionary()).let { userPkSigning?.sign(it) } Map::class.java,
otherMasterKeys.signalableJSONDictionary()
).let { userPkSigning?.sign(it) }
if (newSignature == null) { if (newSignature == null) {
// race?? // race??
@ -684,7 +686,8 @@ internal class DefaultCrossSigningService @Inject constructor(
val otherSSKSignature = otherDevice.signatures?.get(otherUserId)?.get("ed25519:${otherKeys.selfSigningKey()?.unpaddedBase64PublicKey}") val otherSSKSignature = otherDevice.signatures?.get(otherUserId)?.get("ed25519:${otherKeys.selfSigningKey()?.unpaddedBase64PublicKey}")
?: return legacyFallbackTrust( ?: return legacyFallbackTrust(
locallyTrusted, locallyTrusted,
DeviceTrustResult.MissingDeviceSignature(otherDeviceId, otherKeys.selfSigningKey() DeviceTrustResult.MissingDeviceSignature(
otherDeviceId, otherKeys.selfSigningKey()
?.unpaddedBase64PublicKey ?.unpaddedBase64PublicKey
?: "" ?: ""
) )
@ -733,7 +736,8 @@ internal class DefaultCrossSigningService @Inject constructor(
val otherSSKSignature = otherDevice.signatures?.get(otherKeys.userId)?.get("ed25519:${otherKeys.selfSigningKey()?.unpaddedBase64PublicKey}") val otherSSKSignature = otherDevice.signatures?.get(otherKeys.userId)?.get("ed25519:${otherKeys.selfSigningKey()?.unpaddedBase64PublicKey}")
?: return legacyFallbackTrust( ?: return legacyFallbackTrust(
locallyTrusted, locallyTrusted,
DeviceTrustResult.MissingDeviceSignature(otherDevice.deviceId, otherKeys.selfSigningKey() DeviceTrustResult.MissingDeviceSignature(
otherDevice.deviceId, otherKeys.selfSigningKey()
?.unpaddedBase64PublicKey ?.unpaddedBase64PublicKey
?: "" ?: ""
) )

View File

@ -516,7 +516,8 @@ internal class DefaultKeysBackupService @Inject constructor(
UpdateKeysBackupVersionBody( UpdateKeysBackupVersionBody(
algorithm = keysBackupVersion.algorithm, algorithm = keysBackupVersion.algorithm,
authData = newMegolmBackupAuthDataWithNewSignature.toJsonDict(), authData = newMegolmBackupAuthDataWithNewSignature.toJsonDict(),
version = keysBackupVersion.version) version = keysBackupVersion.version
)
} }
// And send it to the homeserver // And send it to the homeserver
@ -719,14 +720,18 @@ internal class DefaultKeysBackupService @Inject constructor(
} }
} }
} }
Timber.v("restoreKeysWithRecoveryKey: Decrypted ${sessionsData.size} keys out" + Timber.v(
" of $sessionsFromHsCount from the backup store on the homeserver") "restoreKeysWithRecoveryKey: Decrypted ${sessionsData.size} keys out" +
" of $sessionsFromHsCount from the backup store on the homeserver"
)
// Do not trigger a backup for them if they come from the backup version we are using // Do not trigger a backup for them if they come from the backup version we are using
val backUp = keysVersionResult.version != keysBackupVersion?.version val backUp = keysVersionResult.version != keysBackupVersion?.version
if (backUp) { if (backUp) {
Timber.v("restoreKeysWithRecoveryKey: Those keys will be backed up" + Timber.v(
" to backup version: ${keysBackupVersion?.version}") "restoreKeysWithRecoveryKey: Those keys will be backed up" +
" to backup version: ${keysBackupVersion?.version}"
)
} }
// Import them into the crypto store // Import them into the crypto store
@ -801,11 +806,15 @@ internal class DefaultKeysBackupService @Inject constructor(
// Get key for the room and for the session // Get key for the room and for the session
val data = getRoomSessionDataTask.execute(GetRoomSessionDataTask.Params(roomId, sessionId, version)) val data = getRoomSessionDataTask.execute(GetRoomSessionDataTask.Params(roomId, sessionId, version))
// Convert to KeysBackupData // Convert to KeysBackupData
KeysBackupData(mutableMapOf( KeysBackupData(
roomId to RoomKeysBackupData(mutableMapOf( mutableMapOf(
sessionId to data roomId to RoomKeysBackupData(
)) mutableMapOf(
)) sessionId to data
)
)
)
)
} else if (roomId != null) { } else if (roomId != null) {
// Get all keys for the room // Get all keys for the room
val data = getRoomSessionsDataTask.execute(GetRoomSessionsDataTask.Params(roomId, version)) val data = getRoomSessionsDataTask.execute(GetRoomSessionsDataTask.Params(roomId, version))
@ -1326,7 +1335,8 @@ internal class DefaultKeysBackupService @Inject constructor(
"sender_key" to sessionData.senderKey, "sender_key" to sessionData.senderKey,
"sender_claimed_keys" to sessionData.senderClaimedKeys, "sender_claimed_keys" to sessionData.senderClaimedKeys,
"forwarding_curve25519_key_chain" to (sessionData.forwardingCurve25519KeyChain.orEmpty()), "forwarding_curve25519_key_chain" to (sessionData.forwardingCurve25519KeyChain.orEmpty()),
"session_key" to sessionData.sessionKey) "session_key" to sessionData.sessionKey
)
val json = MoshiProvider.providesMoshi() val json = MoshiProvider.providesMoshi()
.adapter(Map::class.java) .adapter(Map::class.java)
@ -1354,7 +1364,8 @@ internal class DefaultKeysBackupService @Inject constructor(
sessionData = mapOf( sessionData = mapOf(
"ciphertext" to encryptedSessionBackupData.mCipherText, "ciphertext" to encryptedSessionBackupData.mCipherText,
"mac" to encryptedSessionBackupData.mMac, "mac" to encryptedSessionBackupData.mMac,
"ephemeral" to encryptedSessionBackupData.mEphemeralKey) "ephemeral" to encryptedSessionBackupData.mEphemeralKey
)
) )
} }

View File

@ -40,7 +40,8 @@ internal class DefaultDeleteRoomSessionDataTask @Inject constructor(
roomKeysApi.deleteRoomSessionData( roomKeysApi.deleteRoomSessionData(
params.roomId, params.roomId,
params.sessionId, params.sessionId,
params.version) params.version
)
} }
} }
} }

View File

@ -38,7 +38,8 @@ internal class DefaultDeleteRoomSessionsDataTask @Inject constructor(
return executeRequest(globalErrorReceiver) { return executeRequest(globalErrorReceiver) {
roomKeysApi.deleteRoomSessionsData( roomKeysApi.deleteRoomSessionsData(
params.roomId, params.roomId,
params.version) params.version
)
} }
} }
} }

View File

@ -41,7 +41,8 @@ internal class DefaultGetRoomSessionDataTask @Inject constructor(
roomKeysApi.getRoomSessionData( roomKeysApi.getRoomSessionData(
params.roomId, params.roomId,
params.sessionId, params.sessionId,
params.version) params.version
)
} }
} }
} }

View File

@ -39,7 +39,8 @@ internal class DefaultGetRoomSessionsDataTask @Inject constructor(
return executeRequest(globalErrorReceiver) { return executeRequest(globalErrorReceiver) {
roomKeysApi.getRoomSessionsData( roomKeysApi.getRoomSessionsData(
params.roomId, params.roomId,
params.version) params.version
)
} }
} }
} }

View File

@ -44,7 +44,8 @@ internal class DefaultStoreRoomSessionDataTask @Inject constructor(
params.roomId, params.roomId,
params.sessionId, params.sessionId,
params.version, params.version,
params.keyBackupData) params.keyBackupData
)
} }
} }
} }

View File

@ -42,7 +42,8 @@ internal class DefaultStoreRoomSessionsDataTask @Inject constructor(
roomKeysApi.storeRoomSessionsData( roomKeysApi.storeRoomSessionsData(
params.roomId, params.roomId,
params.version, params.version,
params.roomKeysBackupData) params.roomKeysBackupData
)
} }
} }
} }

View File

@ -40,7 +40,8 @@ internal class DefaultStoreSessionsDataTask @Inject constructor(
return executeRequest(globalErrorReceiver) { return executeRequest(globalErrorReceiver) {
roomKeysApi.storeSessionsData( roomKeysApi.storeSessionsData(
params.version, params.version,
params.keysBackupData) params.keysBackupData
)
} }
} }
} }

View File

@ -213,7 +213,8 @@ internal class DefaultSharedSecretStorageService @Inject constructor(
secretKey.privateKey, secretKey.privateKey,
ByteArray(32) { 0.toByte() }, ByteArray(32) { 0.toByte() },
secretName.toByteArray(), secretName.toByteArray(),
64) 64
)
// The first 32 bytes are used as the AES key, and the next 32 bytes are used as the MAC key // The first 32 bytes are used as the AES key, and the next 32 bytes are used as the MAC key
val aesKey = pseudoRandomKey.copyOfRange(0, 32) val aesKey = pseudoRandomKey.copyOfRange(0, 32)
@ -255,7 +256,8 @@ internal class DefaultSharedSecretStorageService @Inject constructor(
secretKey.privateKey, secretKey.privateKey,
ByteArray(32) { 0.toByte() }, ByteArray(32) { 0.toByte() },
secretName.toByteArray(), secretName.toByteArray(),
64) 64
)
// The first 32 bytes are used as the AES key, and the next 32 bytes are used as the MAC key // The first 32 bytes are used as the AES key, and the next 32 bytes are used as the MAC key
val aesKey = pseudoRandomKey.copyOfRange(0, 32) val aesKey = pseudoRandomKey.copyOfRange(0, 32)

View File

@ -38,7 +38,8 @@ import org.matrix.android.sdk.internal.crypto.store.db.model.WithHeldSessionEnti
/** /**
* Realm module for Crypto store classes * Realm module for Crypto store classes
*/ */
@RealmModule(library = true, @RealmModule(
library = true,
classes = [ classes = [
CryptoMetadataEntity::class, CryptoMetadataEntity::class,
CryptoRoomEntity::class, CryptoRoomEntity::class,
@ -57,5 +58,6 @@ import org.matrix.android.sdk.internal.crypto.store.db.model.WithHeldSessionEnti
WithHeldSessionEntity::class, WithHeldSessionEntity::class,
SharedSessionEntity::class, SharedSessionEntity::class,
OutboundGroupSessionInfoEntity::class OutboundGroupSessionInfoEntity::class
]) ]
)
internal class RealmCryptoStoreModule internal class RealmCryptoStoreModule

View File

@ -27,11 +27,13 @@ import javax.inject.Inject
internal class CrossSigningKeysMapper @Inject constructor(moshi: Moshi) { internal class CrossSigningKeysMapper @Inject constructor(moshi: Moshi) {
private val signaturesAdapter = moshi.adapter<Map<String, Map<String, String>>>(Types.newParameterizedType( private val signaturesAdapter = moshi.adapter<Map<String, Map<String, String>>>(
Map::class.java, Types.newParameterizedType(
String::class.java, Map::class.java,
Any::class.java String::class.java,
)) Any::class.java
)
)
fun update(keyInfo: KeyInfoEntity, cryptoCrossSigningKey: CryptoCrossSigningKey) { fun update(keyInfo: KeyInfoEntity, cryptoCrossSigningKey: CryptoCrossSigningKey) {
// update signatures? // update signatures?

View File

@ -72,16 +72,20 @@ internal class MigrateCryptoTo004(realm: DynamicRealm) : RealmMigrator(realm, 4)
?.addField(CryptoMetadataEntityFields.X_SIGN_SELF_SIGNED_PRIVATE_KEY, String::class.java) ?.addField(CryptoMetadataEntityFields.X_SIGN_SELF_SIGNED_PRIVATE_KEY, String::class.java)
val moshi = Moshi.Builder().add(SerializeNulls.JSON_ADAPTER_FACTORY).build() val moshi = Moshi.Builder().add(SerializeNulls.JSON_ADAPTER_FACTORY).build()
val listMigrationAdapter = moshi.adapter<List<String>>(Types.newParameterizedType( val listMigrationAdapter = moshi.adapter<List<String>>(
List::class.java, Types.newParameterizedType(
String::class.java, List::class.java,
Any::class.java String::class.java,
)) Any::class.java
val mapMigrationAdapter = moshi.adapter<JsonDict>(Types.newParameterizedType( )
Map::class.java, )
String::class.java, val mapMigrationAdapter = moshi.adapter<JsonDict>(
Any::class.java Types.newParameterizedType(
)) Map::class.java,
String::class.java,
Any::class.java
)
)
realm.schema.get("DeviceInfoEntity") realm.schema.get("DeviceInfoEntity")
?.addField(DeviceInfoEntityFields.USER_ID, String::class.java) ?.addField(DeviceInfoEntityFields.USER_ID, String::class.java)

View File

@ -27,21 +27,27 @@ import timber.log.Timber
internal object CryptoMapper { internal object CryptoMapper {
private val moshi = Moshi.Builder().add(SerializeNulls.JSON_ADAPTER_FACTORY).build() private val moshi = Moshi.Builder().add(SerializeNulls.JSON_ADAPTER_FACTORY).build()
private val listMigrationAdapter = moshi.adapter<List<String>>(Types.newParameterizedType( private val listMigrationAdapter = moshi.adapter<List<String>>(
List::class.java, Types.newParameterizedType(
String::class.java, List::class.java,
Any::class.java String::class.java,
)) Any::class.java
private val mapMigrationAdapter = moshi.adapter<JsonDict>(Types.newParameterizedType( )
Map::class.java, )
String::class.java, private val mapMigrationAdapter = moshi.adapter<JsonDict>(
Any::class.java Types.newParameterizedType(
)) Map::class.java,
private val mapOfStringMigrationAdapter = moshi.adapter<Map<String, Map<String, String>>>(Types.newParameterizedType( String::class.java,
Map::class.java, Any::class.java
String::class.java, )
Any::class.java )
)) private val mapOfStringMigrationAdapter = moshi.adapter<Map<String, Map<String, String>>>(
Types.newParameterizedType(
Map::class.java,
String::class.java,
Any::class.java
)
)
internal fun mapToEntity(deviceInfo: CryptoDeviceInfo): DeviceInfoEntity { internal fun mapToEntity(deviceInfo: CryptoDeviceInfo): DeviceInfoEntity {
return DeviceInfoEntity(primaryKey = DeviceInfoEntity.createPrimaryKey(deviceInfo.userId, deviceInfo.deviceId)) return DeviceInfoEntity(primaryKey = DeviceInfoEntity.createPrimaryKey(deviceInfo.userId, deviceInfo.deviceId))
@ -91,11 +97,13 @@ internal object CryptoMapper {
}, },
keys = deviceInfoEntity.keysMapJson?.let { keys = deviceInfoEntity.keysMapJson?.let {
try { try {
moshi.adapter<Map<String, String>>(Types.newParameterizedType( moshi.adapter<Map<String, String>>(
Map::class.java, Types.newParameterizedType(
String::class.java, Map::class.java,
Any::class.java String::class.java,
)).fromJson(it) Any::class.java
)
).fromJson(it)
} catch (failure: Throwable) { } catch (failure: Throwable) {
Timber.e(failure) Timber.e(failure)
null null

View File

@ -73,11 +73,13 @@ internal class DefaultSendEventTask @Inject constructor(
@Throws @Throws
private suspend fun handleEncryption(params: SendEventTask.Params): Event { private suspend fun handleEncryption(params: SendEventTask.Params): Event {
if (params.encrypt && !params.event.isEncrypted()) { if (params.encrypt && !params.event.isEncrypted()) {
return encryptEventTask.execute(EncryptEventTask.Params( return encryptEventTask.execute(
params.event.roomId ?: "", EncryptEventTask.Params(
params.event, params.event.roomId ?: "",
listOf("m.relates_to") params.event,
)) listOf("m.relates_to")
)
)
} }
return params.event return params.event
} }

View File

@ -64,11 +64,13 @@ internal class DefaultSendVerificationMessageTask @Inject constructor(
private suspend fun handleEncryption(params: SendVerificationMessageTask.Params): Event { private suspend fun handleEncryption(params: SendVerificationMessageTask.Params): Event {
if (cryptoSessionInfoProvider.isRoomEncrypted(params.event.roomId ?: "")) { if (cryptoSessionInfoProvider.isRoomEncrypted(params.event.roomId ?: "")) {
try { try {
return encryptEventTask.execute(EncryptEventTask.Params( return encryptEventTask.execute(
params.event.roomId ?: "", EncryptEventTask.Params(
params.event, params.event.roomId ?: "",
listOf("m.relates_to") params.event,
)) listOf("m.relates_to")
)
)
} catch (throwable: Throwable) { } catch (throwable: Throwable) {
// We said it's ok to send verification request in clear // We said it's ok to send verification request in clear
} }

View File

@ -53,7 +53,8 @@ internal class DefaultIncomingSASDefaultVerificationTransaction(
transactionId, transactionId,
otherUserID, otherUserID,
null, null,
isIncoming = true), isIncoming = true
),
IncomingSasVerificationTransaction { IncomingSasVerificationTransaction {
override val uxState: IncomingSasVerificationTransaction.UxState override val uxState: IncomingSasVerificationTransaction.UxState

View File

@ -50,7 +50,8 @@ internal class DefaultOutgoingSASDefaultVerificationTransaction(
transactionId, transactionId,
otherUserId, otherUserId,
otherDeviceId, otherDeviceId,
isIncoming = false), isIncoming = false
),
OutgoingSasVerificationTransaction { OutgoingSasVerificationTransaction {
override val uxState: OutgoingSasVerificationTransaction.UxState override val uxState: OutgoingSasVerificationTransaction.UxState

View File

@ -105,8 +105,10 @@ internal abstract class DefaultVerificationTransaction(
private fun setDeviceVerified(userId: String, deviceId: String) { private fun setDeviceVerified(userId: String, deviceId: String) {
// TODO should not override cross sign status // TODO should not override cross sign status
setDeviceVerificationAction.handle(DeviceTrustLevel(crossSigningVerified = false, locallyVerified = true), setDeviceVerificationAction.handle(
DeviceTrustLevel(crossSigningVerified = false, locallyVerified = true),
userId, userId,
deviceId) deviceId
)
} }
} }

View File

@ -58,7 +58,8 @@ internal abstract class SASDefaultVerificationTransaction(
transactionId, transactionId,
otherUserId, otherUserId,
otherDeviceId, otherDeviceId,
isIncoming), isIncoming
),
SasVerificationTransaction { SasVerificationTransaction {
companion object { companion object {
@ -297,9 +298,11 @@ internal abstract class SASDefaultVerificationTransaction(
return return
} }
trust(otherMasterKeyIsVerified, trust(
otherMasterKeyIsVerified,
verifiedDevices, verifiedDevices,
eventuallyMarkMyMasterKeyAsTrusted = otherMasterKey?.trustLevel?.isVerified() == false) eventuallyMarkMyMasterKeyAsTrusted = otherMasterKey?.trustLevel?.isVerified() == false
)
} }
override fun cancel() { override fun cancel() {

View File

@ -54,7 +54,8 @@ internal class DefaultQrCodeVerificationTransaction(
transactionId, transactionId,
otherUserId, otherUserId,
otherDeviceId, otherDeviceId,
isIncoming), isIncoming
),
QrCodeVerificationTransaction { QrCodeVerificationTransaction {
override val qrCodeText: String? override val qrCodeText: String?

View File

@ -56,7 +56,8 @@ internal sealed class QrCodeData(
transactionId, transactionId,
userMasterCrossSigningPublicKey, userMasterCrossSigningPublicKey,
otherUserMasterCrossSigningPublicKey, otherUserMasterCrossSigningPublicKey,
sharedSecret) sharedSecret
)
/** /**
* self-verifying in which the current device does trust the master key * self-verifying in which the current device does trust the master key
@ -77,7 +78,8 @@ internal sealed class QrCodeData(
transactionId, transactionId,
userMasterCrossSigningPublicKey, userMasterCrossSigningPublicKey,
otherDeviceKey, otherDeviceKey,
sharedSecret) sharedSecret
)
/** /**
* self-verifying in which the current device does not yet trust the master key * self-verifying in which the current device does not yet trust the master key
@ -98,5 +100,6 @@ internal sealed class QrCodeData(
transactionId, transactionId,
deviceKey, deviceKey,
userMasterCrossSigningPublicKey, userMasterCrossSigningPublicKey,
sharedSecret) sharedSecret
)
} }

View File

@ -207,8 +207,10 @@ internal fun List<TimelineEvent>.mapEventsWithEdition(realm: Realm, roomId: Stri
?.eventId ?.eventId
?.let { editedEventId -> ?.let { editedEventId ->
TimelineEventEntity.where(realm, roomId, eventId = editedEventId).findFirst()?.let { editedEvent -> TimelineEventEntity.where(realm, roomId, eventId = editedEventId).findFirst()?.let { editedEvent ->
it.root.threadDetails = it.root.threadDetails?.copy(lastRootThreadEdition = editedEvent.root?.asDomain()?.getDecryptedTextSummary() it.root.threadDetails = it.root.threadDetails?.copy(
?: "(edited)") lastRootThreadEdition = editedEvent.root?.asDomain()?.getDecryptedTextSummary()
?: "(edited)"
)
it it
} ?: it } ?: it
} ?: it } ?: it
@ -341,7 +343,8 @@ internal fun updateNotificationsNew(roomId: String, realm: Realm, currentUserId:
realm = realm, realm = realm,
roomId = roomId, roomId = roomId,
rootThreadEventId = eventId, rootThreadEventId = eventId,
senderId = currentUserId) senderId = currentUserId
)
val rootThreadEventEntity = EventEntity.where(realm, eventId).findFirst() val rootThreadEventEntity = EventEntity.where(realm, eventId).findFirst()
if (isUserParticipating) { if (isUserParticipating) {

View File

@ -24,7 +24,8 @@ import org.matrix.android.sdk.internal.database.model.threads.ThreadSummaryEntit
/** /**
* Realm module for Session * Realm module for Session
*/ */
@RealmModule(library = true, @RealmModule(
library = true,
classes = [ classes = [
ChunkEntity::class, ChunkEntity::class,
EventEntity::class, EventEntity::class,
@ -71,5 +72,6 @@ import org.matrix.android.sdk.internal.database.model.threads.ThreadSummaryEntit
SpaceParentSummaryEntity::class, SpaceParentSummaryEntity::class,
UserPresenceEntity::class, UserPresenceEntity::class,
ThreadSummaryEntity::class ThreadSummaryEntity::class
]) ]
)
internal class SessionRealmModule internal class SessionRealmModule

View File

@ -43,15 +43,17 @@ import org.matrix.android.sdk.internal.worker.MatrixWorkerFactory
import org.matrix.olm.OlmManager import org.matrix.olm.OlmManager
import java.io.File import java.io.File
@Component(modules = [ @Component(
MatrixModule::class, modules = [
NetworkModule::class, MatrixModule::class,
AuthModule::class, NetworkModule::class,
RawModule::class, AuthModule::class,
SettingsModule::class, RawModule::class,
SystemModule::class, SettingsModule::class,
NoOpTestModule::class SystemModule::class,
]) NoOpTestModule::class
]
)
@MatrixScope @MatrixScope
internal interface MatrixComponent { internal interface MatrixComponent {

View File

@ -36,7 +36,8 @@ internal object MatrixModule {
@Provides @Provides
@MatrixScope @MatrixScope
fun providesMatrixCoroutineDispatchers(): MatrixCoroutineDispatchers { fun providesMatrixCoroutineDispatchers(): MatrixCoroutineDispatchers {
return MatrixCoroutineDispatchers(io = Dispatchers.IO, return MatrixCoroutineDispatchers(
io = Dispatchers.IO,
computation = Dispatchers.Default, computation = Dispatchers.Default,
main = Dispatchers.Main, main = Dispatchers.Main,
crypto = createBackgroundHandler("Crypto_Thread").asCoroutineDispatcher(), crypto = createBackgroundHandler("Crypto_Thread").asCoroutineDispatcher(),

View File

@ -46,17 +46,18 @@ internal object MoshiProvider {
.add(TlsVersionMoshiAdapter()) .add(TlsVersionMoshiAdapter())
// Use addLast here so we can inject a SplitLazyRoomSyncJsonAdapter later to override the default parsing. // Use addLast here so we can inject a SplitLazyRoomSyncJsonAdapter later to override the default parsing.
.addLast(DefaultLazyRoomSyncEphemeralJsonAdapter()) .addLast(DefaultLazyRoomSyncEphemeralJsonAdapter())
.add(RuntimeJsonAdapterFactory.of(MessageContent::class.java, "msgtype", MessageDefaultContent::class.java) .add(
.registerSubtype(MessageTextContent::class.java, MessageType.MSGTYPE_TEXT) RuntimeJsonAdapterFactory.of(MessageContent::class.java, "msgtype", MessageDefaultContent::class.java)
.registerSubtype(MessageNoticeContent::class.java, MessageType.MSGTYPE_NOTICE) .registerSubtype(MessageTextContent::class.java, MessageType.MSGTYPE_TEXT)
.registerSubtype(MessageEmoteContent::class.java, MessageType.MSGTYPE_EMOTE) .registerSubtype(MessageNoticeContent::class.java, MessageType.MSGTYPE_NOTICE)
.registerSubtype(MessageAudioContent::class.java, MessageType.MSGTYPE_AUDIO) .registerSubtype(MessageEmoteContent::class.java, MessageType.MSGTYPE_EMOTE)
.registerSubtype(MessageImageContent::class.java, MessageType.MSGTYPE_IMAGE) .registerSubtype(MessageAudioContent::class.java, MessageType.MSGTYPE_AUDIO)
.registerSubtype(MessageVideoContent::class.java, MessageType.MSGTYPE_VIDEO) .registerSubtype(MessageImageContent::class.java, MessageType.MSGTYPE_IMAGE)
.registerSubtype(MessageLocationContent::class.java, MessageType.MSGTYPE_LOCATION) .registerSubtype(MessageVideoContent::class.java, MessageType.MSGTYPE_VIDEO)
.registerSubtype(MessageFileContent::class.java, MessageType.MSGTYPE_FILE) .registerSubtype(MessageLocationContent::class.java, MessageType.MSGTYPE_LOCATION)
.registerSubtype(MessageVerificationRequestContent::class.java, MessageType.MSGTYPE_VERIFICATION_REQUEST) .registerSubtype(MessageFileContent::class.java, MessageType.MSGTYPE_FILE)
.registerSubtype(MessagePollResponseContent::class.java, MessageType.MSGTYPE_POLL_RESPONSE) .registerSubtype(MessageVerificationRequestContent::class.java, MessageType.MSGTYPE_VERIFICATION_REQUEST)
.registerSubtype(MessagePollResponseContent::class.java, MessageType.MSGTYPE_POLL_RESPONSE)
) )
.add(SerializeNulls.JSON_ADAPTER_FACTORY) .add(SerializeNulls.JSON_ADAPTER_FACTORY)
.build() .build()

View File

@ -84,9 +84,11 @@ internal class WorkManagerProvider @Inject constructor(
if (workInfo?.state?.isFinished == true) { if (workInfo?.state?.isFinished == true) {
checkWorkerLiveState.removeObserver(this) checkWorkerLiveState.removeObserver(this)
if (workInfo.state == WorkInfo.State.FAILED) { if (workInfo.state == WorkInfo.State.FAILED) {
throw RuntimeException("MatrixWorkerFactory is not being set on your worker configuration.\n" + throw RuntimeException(
"Makes sure to add it to a DelegatingWorkerFactory if you have your own factory or use it directly.\n" + "MatrixWorkerFactory is not being set on your worker configuration.\n" +
"You can grab the instance through the Matrix class.") "Makes sure to add it to a DelegatingWorkerFactory if you have your own factory or use it directly.\n" +
"You can grab the instance through the Matrix class."
)
} }
} }
} }

View File

@ -132,7 +132,7 @@ internal class DefaultLegacySessionImporter @Inject constructor(
bytes = it.bytes, bytes = it.bytes,
hashType = when (it.type) { hashType = when (it.type) {
LegacyFingerprint.HashType.SHA1, LegacyFingerprint.HashType.SHA1,
null -> Fingerprint.HashType.SHA1 null -> Fingerprint.HashType.SHA1
LegacyFingerprint.HashType.SHA256 -> Fingerprint.HashType.SHA256 LegacyFingerprint.HashType.SHA256 -> Fingerprint.HashType.SHA256
} }
) )

View File

@ -76,10 +76,12 @@ class WellKnown {
if (apiUrl != null && if (apiUrl != null &&
apiUrl.startsWith("https://") && apiUrl.startsWith("https://") &&
uiUrl!!.startsWith("https://")) { uiUrl!!.startsWith("https://")) {
managers.add(WellKnownManagerConfig( managers.add(
apiUrl = apiUrl, WellKnownManagerConfig(
uiUrl = uiUrl apiUrl = apiUrl,
)) uiUrl = uiUrl
)
)
} }
} }
} }

View File

@ -63,8 +63,10 @@ internal class RuntimeJsonAdapterFactory<T>(
} }
val fallbackAdapter = moshi.adapter<Any>(fallbackType) val fallbackAdapter = moshi.adapter<Any>(fallbackType)
val objectJsonAdapter = moshi.adapter(Any::class.java) val objectJsonAdapter = moshi.adapter(Any::class.java)
return RuntimeJsonAdapter(labelKey, labelToAdapter, typeToLabel, return RuntimeJsonAdapter(
objectJsonAdapter, fallbackAdapter).nullSafe() labelKey, labelToAdapter, typeToLabel,
objectJsonAdapter, fallbackAdapter
).nullSafe()
} }
@Suppress("UNCHECKED_CAST") @Suppress("UNCHECKED_CAST")
@ -77,8 +79,10 @@ internal class RuntimeJsonAdapterFactory<T>(
override fun fromJson(reader: JsonReader): Any? { override fun fromJson(reader: JsonReader): Any? {
val peekedToken = reader.peek() val peekedToken = reader.peek()
if (peekedToken != JsonReader.Token.BEGIN_OBJECT) { if (peekedToken != JsonReader.Token.BEGIN_OBJECT) {
throw JsonDataException("Expected BEGIN_OBJECT but was " + peekedToken + throw JsonDataException(
" at path " + reader.path) "Expected BEGIN_OBJECT but was " + peekedToken +
" at path " + reader.path
)
} }
val jsonValue = reader.readJsonValue() val jsonValue = reader.readJsonValue()
val jsonObject = jsonValue as Map<String, Any>? val jsonObject = jsonValue as Map<String, Any>?
@ -91,13 +95,15 @@ internal class RuntimeJsonAdapterFactory<T>(
override fun toJson(writer: JsonWriter, value: Any?) { override fun toJson(writer: JsonWriter, value: Any?) {
val type: Class<*> = value!!.javaClass val type: Class<*> = value!!.javaClass
val label = typeToLabel[type] val label = typeToLabel[type]
?: throw IllegalArgumentException("Expected one of " + ?: throw IllegalArgumentException(
typeToLabel.keys + "Expected one of " +
" but found " + typeToLabel.keys +
value + " but found " +
", a " + value +
value.javaClass + ", a " +
". Register this subtype.") value.javaClass +
". Register this subtype."
)
val adapter = labelToAdapter[label]!! val adapter = labelToAdapter[label]!!
val jsonValue = adapter.toJsonValue(value) as Map<String, Any>? val jsonValue = adapter.toJsonValue(value) as Map<String, Any>?
val valueWithLabel: MutableMap<String, Any> = LinkedHashMap(1 + jsonValue!!.size) val valueWithLabel: MutableMap<String, Any> = LinkedHashMap(1 + jsonValue!!.size)

View File

@ -35,8 +35,10 @@ internal fun RealmQuery<RoomSummaryEntity>.process(sortOrder: RoomSortOrder): Re
arrayOf( arrayOf(
RoomSummaryEntityFields.IS_FAVOURITE, RoomSummaryEntityFields.IS_FAVOURITE,
RoomSummaryEntityFields.IS_LOW_PRIORITY, RoomSummaryEntityFields.IS_LOW_PRIORITY,
RoomSummaryEntityFields.LAST_ACTIVITY_TIME), RoomSummaryEntityFields.LAST_ACTIVITY_TIME
arrayOf(Sort.DESCENDING, Sort.ASCENDING, Sort.DESCENDING)) ),
arrayOf(Sort.DESCENDING, Sort.ASCENDING, Sort.DESCENDING)
)
} }
RoomSortOrder.NONE -> { RoomSortOrder.NONE -> {
} }

View File

@ -23,9 +23,11 @@ import org.matrix.android.sdk.internal.database.model.RawCacheEntity
/** /**
* Realm module for global classes * Realm module for global classes
*/ */
@RealmModule(library = true, @RealmModule(
library = true,
classes = [ classes = [
RawCacheEntity::class, RawCacheEntity::class,
KnownServerUrlEntity::class KnownServerUrlEntity::class
]) ]
)
internal class GlobalRealmModule internal class GlobalRealmModule

View File

@ -68,7 +68,8 @@ import org.matrix.android.sdk.internal.session.widgets.WidgetModule
import org.matrix.android.sdk.internal.task.TaskExecutor import org.matrix.android.sdk.internal.task.TaskExecutor
import org.matrix.android.sdk.internal.util.system.SystemModule import org.matrix.android.sdk.internal.util.system.SystemModule
@Component(dependencies = [MatrixComponent::class], @Component(
dependencies = [MatrixComponent::class],
modules = [ modules = [
SessionModule::class, SessionModule::class,
RoomModule::class, RoomModule::class,

View File

@ -60,10 +60,10 @@ internal class DefaultDeactivateAccountTask @Inject constructor(
execute(params.copy(userAuthParam = authUpdate)) execute(params.copy(userAuthParam = authUpdate))
} }
)) { )) {
UiaResult.SUCCESS -> { UiaResult.SUCCESS -> {
false false
} }
UiaResult.FAILURE -> { UiaResult.FAILURE -> {
Timber.d("## UIA: propagate failure") Timber.d("## UIA: propagate failure")
throw throwable throw throwable
} }

View File

@ -289,12 +289,14 @@ internal class UploadContentWorker(val context: Context, params: WorkerParameter
val uploadThumbnailResult = dealWithThumbnail(params) val uploadThumbnailResult = dealWithThumbnail(params)
handleSuccess(params, handleSuccess(
params,
contentUploadResponse.contentUri, contentUploadResponse.contentUri,
uploadedFileEncryptedFileInfo, uploadedFileEncryptedFileInfo,
uploadThumbnailResult?.uploadedThumbnailUrl, uploadThumbnailResult?.uploadedThumbnailUrl,
uploadThumbnailResult?.uploadedThumbnailEncryptedFileInfo, uploadThumbnailResult?.uploadedThumbnailEncryptedFileInfo,
newAttachmentAttributes) newAttachmentAttributes
)
} catch (t: Throwable) { } catch (t: Throwable) {
Timber.e(t, "## ERROR ${t.localizedMessage}") Timber.e(t, "## ERROR ${t.localizedMessage}")
handleFailure(params, t) handleFailure(params, t)

View File

@ -21,9 +21,11 @@ import io.realm.annotations.RealmModule
/** /**
* Realm module for content scanner classes * Realm module for content scanner classes
*/ */
@RealmModule(library = true, @RealmModule(
library = true,
classes = [ classes = [
ContentScannerInfoEntity::class, ContentScannerInfoEntity::class,
ContentScanResultEntity::class ContentScanResultEntity::class
]) ]
)
internal class ContentScannerRealmModule internal class ContentScannerRealmModule

View File

@ -94,10 +94,12 @@ internal class DefaultGetHomeServerCapabilitiesTask @Inject constructor(
}.getOrNull() }.getOrNull()
val wellknownResult = runCatching { val wellknownResult = runCatching {
getWellknownTask.execute(GetWellknownTask.Params( getWellknownTask.execute(
domain = userId.getDomain(), GetWellknownTask.Params(
homeServerConnectionConfig = homeServerConnectionConfig domain = userId.getDomain(),
)) homeServerConnectionConfig = homeServerConnectionConfig
)
)
}.getOrNull() }.getOrNull()
insertInDb(capabilities, mediaConfig, versions, wellknownResult) insertInDb(capabilities, mediaConfig, versions, wellknownResult)

View File

@ -218,9 +218,11 @@ internal class DefaultIdentityService @Inject constructor(
listeners.toList().forEach { tryOrNull { it.onIdentityServerChange() } } listeners.toList().forEach { tryOrNull { it.onIdentityServerChange() } }
} }
updateUserAccountDataTask.execute(UpdateUserAccountDataTask.IdentityParams( updateUserAccountDataTask.execute(
identityContent = IdentityServerContent(baseUrl = url) UpdateUserAccountDataTask.IdentityParams(
)) identityContent = IdentityServerContent(baseUrl = url)
)
)
} }
override fun getUserConsent(): Boolean { override fun getUserConsent(): Boolean {
@ -297,11 +299,13 @@ internal class DefaultIdentityService @Inject constructor(
} }
override suspend fun sign3pidInvitation(identiyServer: String, token: String, secret: String): SignInvitationResult { override suspend fun sign3pidInvitation(identiyServer: String, token: String, secret: String): SignInvitationResult {
return sign3pidInvitationTask.execute(Sign3pidInvitationTask.Params( return sign3pidInvitationTask.execute(
url = identiyServer, Sign3pidInvitationTask.Params(
token = token, url = identiyServer,
privateKey = secret token = token,
)) privateKey = secret
)
)
} }
override fun addListener(listener: IdentityServiceListener) { override fun addListener(listener: IdentityServiceListener) {

View File

@ -83,11 +83,13 @@ internal class DefaultIdentityBulkLookupTask @Inject constructor(
return try { return try {
LookUpData(hashedAddresses, LookUpData(hashedAddresses,
executeRequest(null) { executeRequest(null) {
identityAPI.lookup(IdentityLookUpParams( identityAPI.lookup(
hashedAddresses, IdentityLookUpParams(
IdentityHashDetailResponse.ALGORITHM_SHA256, hashedAddresses,
hashDetailResponse.pepper IdentityHashDetailResponse.ALGORITHM_SHA256,
)) hashDetailResponse.pepper
)
)
}) })
} catch (failure: Throwable) { } catch (failure: Throwable) {
// Catch invalid hash pepper and retry // Catch invalid hash pepper and retry
@ -117,8 +119,10 @@ internal class DefaultIdentityBulkLookupTask @Inject constructor(
return withOlmUtility { olmUtility -> return withOlmUtility { olmUtility ->
threePids.map { threePid -> threePids.map { threePid ->
base64ToBase64Url( base64ToBase64Url(
olmUtility.sha256(threePid.value.lowercase(Locale.ROOT) + olmUtility.sha256(
" " + threePid.toMedium() + " " + pepper) threePid.value.lowercase(Locale.ROOT) +
" " + threePid.toMedium() + " " + pepper
)
) )
} }
} }

View File

@ -57,18 +57,22 @@ internal class DefaultIdentityRequestTokenForBindingTask @Inject constructor(
val tokenResponse = executeRequest(null) { val tokenResponse = executeRequest(null) {
when (params.threePid) { when (params.threePid) {
is ThreePid.Email -> identityAPI.requestTokenToBindEmail(IdentityRequestTokenForEmailBody( is ThreePid.Email -> identityAPI.requestTokenToBindEmail(
clientSecret = clientSecret, IdentityRequestTokenForEmailBody(
sendAttempt = sendAttempt, clientSecret = clientSecret,
email = params.threePid.email sendAttempt = sendAttempt,
)) email = params.threePid.email
)
)
is ThreePid.Msisdn -> { is ThreePid.Msisdn -> {
identityAPI.requestTokenToBindMsisdn(IdentityRequestTokenForMsisdnBody( identityAPI.requestTokenToBindMsisdn(
clientSecret = clientSecret, IdentityRequestTokenForMsisdnBody(
sendAttempt = sendAttempt, clientSecret = clientSecret,
phoneNumber = params.threePid.msisdn, sendAttempt = sendAttempt,
countryCode = params.threePid.getCountryCode() phoneNumber = params.threePid.msisdn,
)) countryCode = params.threePid.getCountryCode()
)
)
} }
} }
} }

View File

@ -50,7 +50,8 @@ internal class DefaultIdentitySubmitTokenForBindingTask @Inject constructor(
clientSecret = identityPendingBinding.clientSecret, clientSecret = identityPendingBinding.clientSecret,
sid = identityPendingBinding.sid, sid = identityPendingBinding.sid,
token = params.token token = params.token
)) )
)
} }
if (!tokenResponse.isSuccess()) { if (!tokenResponse.isSuccess()) {

View File

@ -21,9 +21,11 @@ import io.realm.annotations.RealmModule
/** /**
* Realm module for identity server classes * Realm module for identity server classes
*/ */
@RealmModule(library = true, @RealmModule(
library = true,
classes = [ classes = [
IdentityDataEntity::class, IdentityDataEntity::class,
IdentityPendingBindingEntity::class IdentityPendingBindingEntity::class
]) ]
)
internal class IdentityRealmModule internal class IdentityRealmModule

View File

@ -50,7 +50,8 @@ internal class DefaultBindThreePidsTask @Inject constructor(private val profileA
identityServerUrlWithoutProtocol = identityServerUrlWithoutProtocol, identityServerUrlWithoutProtocol = identityServerUrlWithoutProtocol,
identityServerAccessToken = identityServerAccessToken, identityServerAccessToken = identityServerAccessToken,
sid = identityPendingBinding.sid sid = identityPendingBinding.sid
)) )
)
} }
// Binding is over, cleanup the store // Binding is over, cleanup the store

View File

@ -135,21 +135,25 @@ internal class DefaultProfileService @Inject constructor(private val taskExecuto
override suspend fun finalizeAddingThreePid(threePid: ThreePid, override suspend fun finalizeAddingThreePid(threePid: ThreePid,
userInteractiveAuthInterceptor: UserInteractiveAuthInterceptor) { userInteractiveAuthInterceptor: UserInteractiveAuthInterceptor) {
finalizeAddingThreePidTask finalizeAddingThreePidTask
.execute(FinalizeAddingThreePidTask.Params( .execute(
threePid = threePid, FinalizeAddingThreePidTask.Params(
userInteractiveAuthInterceptor = userInteractiveAuthInterceptor, threePid = threePid,
userWantsToCancel = false userInteractiveAuthInterceptor = userInteractiveAuthInterceptor,
)) userWantsToCancel = false
)
)
refreshThreePids() refreshThreePids()
} }
override suspend fun cancelAddingThreePid(threePid: ThreePid) { override suspend fun cancelAddingThreePid(threePid: ThreePid) {
finalizeAddingThreePidTask finalizeAddingThreePidTask
.execute(FinalizeAddingThreePidTask.Params( .execute(
threePid = threePid, FinalizeAddingThreePidTask.Params(
userInteractiveAuthInterceptor = null, threePid = threePid,
userWantsToCancel = true userInteractiveAuthInterceptor = null,
)) userWantsToCancel = true
)
)
refreshThreePids() refreshThreePids()
} }
@ -161,8 +165,8 @@ internal class DefaultProfileService @Inject constructor(private val taskExecuto
private fun UserThreePidEntity.asDomain(): ThreePid { private fun UserThreePidEntity.asDomain(): ThreePid {
return when (medium) { return when (medium) {
ThirdPartyIdentifier.MEDIUM_EMAIL -> ThreePid.Email(address) ThirdPartyIdentifier.MEDIUM_EMAIL -> ThreePid.Email(address)
ThirdPartyIdentifier.MEDIUM_MSISDN -> ThreePid.Msisdn(address) ThirdPartyIdentifier.MEDIUM_MSISDN -> ThreePid.Msisdn(address)
else -> error("Invalid medium type") else -> error("Invalid medium type")
} }
} }

View File

@ -45,7 +45,8 @@ internal class DefaultUnbindThreePidsTask @Inject constructor(private val profil
identityServerUrlWithoutProtocol, identityServerUrlWithoutProtocol,
params.threePid.toMedium(), params.threePid.toMedium(),
params.threePid.value params.threePid.value
)) )
)
}.isSuccess() }.isSuccess()
} }
} }

View File

@ -85,17 +85,19 @@ internal class DefaultPushersService @Inject constructor(
deviceDisplayName: String, deviceDisplayName: String,
append: Boolean) { append: Boolean) {
addPusherTask.execute( addPusherTask.execute(
AddPusherTask.Params(JsonPusher( AddPusherTask.Params(
pushKey = email, JsonPusher(
kind = Pusher.KIND_EMAIL, pushKey = email,
appId = Pusher.APP_ID_EMAIL, kind = Pusher.KIND_EMAIL,
profileTag = "", appId = Pusher.APP_ID_EMAIL,
lang = lang, profileTag = "",
appDisplayName = appDisplayName, lang = lang,
deviceDisplayName = deviceDisplayName, appDisplayName = appDisplayName,
data = JsonPusherData(brand = emailBranding), deviceDisplayName = deviceDisplayName,
append = append data = JsonPusherData(brand = emailBranding),
)) append = append
)
)
) )
} }

View File

@ -67,8 +67,10 @@ internal class DefaultProcessEventForPushTask @Inject constructor(
}.filter { }.filter {
it.senderId != userId it.senderId != userId
} }
Timber.v("[PushRules] Found ${allEvents.size} out of ${(newJoinEvents + inviteEvents).size}" + Timber.v(
" to check for push rules with ${params.rules.size} rules") "[PushRules] Found ${allEvents.size} out of ${(newJoinEvents + inviteEvents).size}" +
" to check for push rules with ${params.rules.size} rules"
)
val matchedEvents = allEvents.mapNotNull { event -> val matchedEvents = allEvents.mapNotNull { event ->
pushRuleFinder.fulfilledBingRule(event, params.rules)?.let { pushRuleFinder.fulfilledBingRule(event, params.rules)?.let {
Timber.v("[PushRules] Rule $it match for event ${event.eventId}") Timber.v("[PushRules] Rule $it match for event ${event.eventId}")

View File

@ -116,7 +116,8 @@ internal class CreateRoomBodyBuilder @Inject constructor(
fileUploader.uploadFromUri( fileUploader.uploadFromUri(
uri = avatarUri, uri = avatarUri,
filename = UUID.randomUUID().toString(), filename = UUID.randomUUID().toString(),
mimeType = MimeTypes.Jpeg) mimeType = MimeTypes.Jpeg
)
} }
}?.let { response -> }?.let { response ->
Event( Event(

View File

@ -83,7 +83,8 @@ internal class RoomMemberEventHandler @Inject constructor(
roomMember, roomMember,
// When an update is happening, insertOrUpdate replace existing values with null if they are not provided, // When an update is happening, insertOrUpdate replace existing values with null if they are not provided,
// but we want to preserve presence record value and not replace it with null // but we want to preserve presence record value and not replace it with null
getExistingPresenceState(realm, roomId, userId)) getExistingPresenceState(realm, roomId, userId)
)
realm.insertOrUpdate(roomMemberEntity) realm.insertOrUpdate(roomMemberEntity)
} }

Some files were not shown because too many files have changed in this diff Show More