Skip to content

Commit

Permalink
Merge branch 'develop' into feat/user-folders
Browse files Browse the repository at this point in the history
  • Loading branch information
Garzas authored Dec 9, 2024
2 parents 7fa79d5 + 46ab0bc commit e2b73ad
Show file tree
Hide file tree
Showing 32 changed files with 257 additions and 224 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,10 @@ package com.wire.kalium.cryptography
import com.wire.crypto.ClientId
import com.wire.crypto.CoreCrypto
import com.wire.crypto.CoreCryptoCallbacks
import com.wire.crypto.CoreCryptoLogLevel
import com.wire.crypto.CoreCryptoLogger
import com.wire.crypto.coreCryptoDeferredInit
import com.wire.crypto.setLogger
import com.wire.kalium.cryptography.MLSClientImpl.Companion.toCrlRegistration
import com.wire.kalium.cryptography.exceptions.CryptographyException
import java.io.File
Expand All @@ -36,12 +39,28 @@ actual suspend fun coreCryptoCentral(
key = databaseKey
)
coreCrypto.setCallbacks(Callbacks())
setLogger(CoreCryptoLoggerImpl(), CoreCryptoLogLevel.INFO)
return CoreCryptoCentralImpl(
cc = coreCrypto,
rootDir = rootDir
)
}

private class CoreCryptoLoggerImpl : CoreCryptoLogger {
override fun log(level: CoreCryptoLogLevel, message: String, context: String?) {
when (level) {
CoreCryptoLogLevel.TRACE -> kaliumLogger.v("$message. $context")
CoreCryptoLogLevel.DEBUG -> kaliumLogger.d("$message. $context")
CoreCryptoLogLevel.INFO -> kaliumLogger.i("$message. $context")
CoreCryptoLogLevel.WARN -> kaliumLogger.w("$message. $context")
CoreCryptoLogLevel.ERROR -> kaliumLogger.e("$message. $context")
CoreCryptoLogLevel.OFF -> {
// nop
}
}
}
}

private class Callbacks : CoreCryptoCallbacks {
override suspend fun authorize(conversationId: ByteArray, clientId: ClientId): Boolean {
// We always return true because our BE is currently enforcing that this constraint is always true
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ import io.ktor.util.encodeBase64
import kotlinx.coroutines.sync.Mutex
import kotlinx.coroutines.sync.withLock
import java.io.File
import com.wire.crypto.ProteusException as ProteusExceptionNative

@Suppress("TooManyFunctions")
class ProteusClientCoreCryptoImpl private constructor(
Expand Down Expand Up @@ -145,13 +146,12 @@ class ProteusClientCoreCryptoImpl private constructor(
private inline fun <T> wrapException(b: () -> T): T {
try {
return b()
} catch (e: CoreCryptoException) {
val proteusLastErrorCode = coreCrypto.proteusLastErrorCode()
} catch (e: CoreCryptoException.Proteus) {
throw ProteusException(
e.message,
ProteusException.fromProteusCode(proteusLastErrorCode.toInt()),
proteusLastErrorCode.toInt(),
e
message = e.message,
code = mapProteusExceptionToErrorCode(e.v1),
intCode = mapProteusExceptionToRawIntErrorCode(e.v1),
cause = e
)
} catch (e: Exception) {
throw ProteusException(e.message, ProteusException.Code.UNKNOWN_ERROR, null, e)
Expand Down Expand Up @@ -187,11 +187,11 @@ class ProteusClientCoreCryptoImpl private constructor(
return ProteusClientCoreCryptoImpl(coreCrypto)
} catch (exception: ProteusStorageMigrationException) {
throw exception
} catch (e: CoreCryptoException) {
} catch (e: CoreCryptoException.Proteus) {
throw ProteusException(
message = e.message,
code = ProteusException.fromProteusCode(coreCrypto.proteusLastErrorCode().toInt()),
intCode = coreCrypto.proteusLastErrorCode().toInt(),
code = mapProteusExceptionToErrorCode(e.v1),
intCode = mapProteusExceptionToRawIntErrorCode(e.v1),
cause = e.cause
)
} catch (e: Exception) {
Expand All @@ -218,5 +218,24 @@ class ProteusClientCoreCryptoImpl private constructor(
throw ProteusStorageMigrationException("Failed to migrate from crypto box at $rootDir", exception)
}
}

private fun mapProteusExceptionToErrorCode(proteusException: ProteusExceptionNative): ProteusException.Code {
return when (proteusException) {
is ProteusExceptionNative.SessionNotFound -> ProteusException.Code.SESSION_NOT_FOUND
is ProteusExceptionNative.DuplicateMessage -> ProteusException.Code.DUPLICATE_MESSAGE
is ProteusExceptionNative.RemoteIdentityChanged -> ProteusException.Code.REMOTE_IDENTITY_CHANGED
is ProteusExceptionNative.Other -> ProteusException.fromProteusCode(proteusException.v1.toInt())
}
}

@Suppress("MagicNumber")
private fun mapProteusExceptionToRawIntErrorCode(proteusException: ProteusExceptionNative): Int {
return when (proteusException) {
is ProteusExceptionNative.SessionNotFound -> 102
is ProteusExceptionNative.DuplicateMessage -> 209
is ProteusExceptionNative.RemoteIdentityChanged -> 204
is ProteusExceptionNative.Other -> proteusException.v1.toInt()
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -176,19 +176,25 @@ open class ProteusException(message: String?, val code: Code, val intCode: Int?,
}
}

// Mapping source:
// https://github.com/wireapp/proteus/blob/2.x/crates/proteus-traits/src/lib.rs
// https://github.com/wireapp/wire-web-core/blob/7383e108f5e9d15d0b82c41ed504964667463cfc/packages/proteus/README.md
/**
* Those error codes are mapped directly from [com.wire.crypto.ProteusException]:
* - [Code.SESSION_NOT_FOUND]
* - [Code.REMOTE_IDENTITY_CHANGED]
* - [Code.DUPLICATE_MESSAGE]
*
* See the mapping: [com.wire.kalium.cryptography.ProteusClientCoreCryptoImpl.Companion.mapProteusExceptionToErrorCode]
*
* [Mapping sources](https://github.com/wireapp/proteus/blob/2.x/crates/proteus-traits/src/lib.rs)
*
* [Mapping source README](https://github.com/wireapp/wire-web-core/blob/7383e108f5e9d15d0b82c41ed504964667463cfc/packages/proteus/README.md)
*/
fun fromProteusCode(code: Int): Code {
@Suppress("MagicNumber")
return when (code) {
501 -> Code.STORAGE_ERROR
102 -> Code.SESSION_NOT_FOUND
3, 301, 302, 303 -> Code.DECODE_ERROR
204 -> Code.REMOTE_IDENTITY_CHANGED
206, 207, 210 -> Code.INVALID_SIGNATURE
200, 201, 202, 205, 213 -> Code.INVALID_MESSAGE
209 -> Code.DUPLICATE_MESSAGE
211, 212 -> Code.TOO_DISTANT_FUTURE
208 -> Code.OUTDATED_MESSAGE
300 -> Code.IDENTITY_ERROR
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,55 +18,21 @@

package com.wire.kalium.logic.data.call

import com.wire.kalium.util.serialization.LenientJsonSerializer
import kotlinx.serialization.ExperimentalSerializationApi
import kotlinx.serialization.KSerializer
import kotlinx.serialization.SerialName
import kotlinx.serialization.Serializable
import kotlinx.serialization.descriptors.PrimitiveKind
import kotlinx.serialization.descriptors.PrimitiveSerialDescriptor
import kotlinx.serialization.descriptors.SerialDescriptor
import kotlinx.serialization.descriptors.nullable
import kotlinx.serialization.encoding.Decoder
import kotlinx.serialization.encoding.Encoder
import kotlinx.serialization.json.Json

@Serializable
data class CallClient(
@SerialName("userid") val userId: String,
@SerialName("clientid") val clientId: String,
@SerialName("in_subconv") val isMemberOfSubconversation: Boolean = false,
@SerialName("quality")
@Serializable(with = CallQuality.CallQualityAsIntSerializer::class)
val quality: CallQuality = CallQuality.LOW
@SerialName("in_subconv") val isMemberOfSubconversation: Boolean = false
)

@Serializable
data class CallClientList(
@SerialName("clients") val clients: List<CallClient>
) {
fun toJsonString(): String = LenientJsonSerializer.json.encodeToString(serializer(), this)
}

enum class CallQuality {
ANY,
LOW,
HIGH;

data object CallQualityAsIntSerializer : KSerializer<CallQuality> {
override val descriptor: SerialDescriptor = PrimitiveSerialDescriptor("quality", PrimitiveKind.INT).nullable

override fun serialize(encoder: Encoder, value: CallQuality) {
encoder.encodeInt(value.ordinal)
}

@OptIn(ExperimentalSerializationApi::class)
override fun deserialize(decoder: Decoder): CallQuality {
val value = if (decoder.decodeNotNullMark()) decoder.decodeInt() else 0
return when (value) {
1 -> LOW
2 -> HIGH
else -> ANY
}
}
}
// TODO(optimization): Use a shared Json instance instead of creating one every time.
fun toJsonString(): String = Json { isLenient = true }.encodeToString(serializer(), this)
}
20 changes: 10 additions & 10 deletions gradle/libs.versions.toml
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ activity-compose = "1.9.0"
app-compat = "1.6.1"
android-paging3 = "3.2.1"
cli-kt = "3.5.0"
coroutines = "1.8.1"
coroutines = "1.8.0"
compose-compiler = "1.5.13"
compose-ui = "1.6.6"
compose-material = "1.6.6"
Expand All @@ -17,12 +17,12 @@ okio = "3.9.0"
ok-http = "4.12.0"
mockative = "2.2.0"
android-work = "2.9.0"
android-test-runner = "1.6.2"
android-test-core-ktx = "1.6.1"
android-test-rules = "1.6.1"
android-test-core = "1.6.1"
android-test-runner = "1.5.2"
android-test-core-ktx = "1.5.0"
android-test-rules = "1.5.0"
android-test-core = "1.5.0"
androidx-arch = "2.2.0"
androidx-test-orchestrator = "1.5.1"
androidx-test-orchestrator = "1.4.2"
androidx-sqlite = "2.4.0"
benasher-uuid = "0.8.0"
ktx-datetime = { strictly = "0.5.0" }
Expand All @@ -37,20 +37,20 @@ sqldelight = "2.0.1"
sqlcipher-android = "4.5.6"
pbandk = "0.14.2"
turbine = "1.1.0"
avs = "10.0.1"
avs = "9.10.16"
jna = "5.14.0"
core-crypto = "1.0.2"
core-crypto = "2.0.0"
core-crypto-multiplatform = "0.6.0-rc.3-multiplatform-pre1"
completeKotlin = "1.1.0"
desugar-jdk = "2.1.3"
desugar-jdk = "2.0.4"
kermit = "2.0.3"
detekt = "1.23.6"
agp = "8.5.2"
dokka = "1.8.20"
carthage = "0.0.1"
libsodiumBindings = "0.8.7"
protobufCodegen = "0.9.4"
annotation = "1.9.1"
annotation = "1.7.1"
mordant = "2.0.0-beta13"
apache-tika = "2.9.2"
mockk = "1.13.10"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,21 +18,20 @@
package com.wire.kalium.logic

import com.wire.crypto.CoreCryptoException
import uniffi.core_crypto.CryptoError
import com.wire.crypto.MlsException

actual fun mapMLSException(exception: Exception): MLSFailure =
if (exception is CoreCryptoException.CryptoException) {
when (exception.error) {
is CryptoError.WrongEpoch -> MLSFailure.WrongEpoch
is CryptoError.DuplicateMessage -> MLSFailure.DuplicateMessage
is CryptoError.BufferedFutureMessage -> MLSFailure.BufferedFutureMessage
is CryptoError.SelfCommitIgnored -> MLSFailure.SelfCommitIgnored
is CryptoError.UnmergedPendingGroup -> MLSFailure.UnmergedPendingGroup
is CryptoError.StaleProposal -> MLSFailure.StaleProposal
is CryptoError.StaleCommit -> MLSFailure.StaleCommit
is CryptoError.ConversationAlreadyExists -> MLSFailure.ConversationAlreadyExists
is CryptoError.MessageEpochTooOld -> MLSFailure.MessageEpochTooOld
is CryptoError.MlsException -> MLSFailure.InternalErrors
if (exception is CoreCryptoException.Mls) {
when (exception.v1) {
is MlsException.WrongEpoch -> MLSFailure.WrongEpoch
is MlsException.DuplicateMessage -> MLSFailure.DuplicateMessage
is MlsException.BufferedFutureMessage -> MLSFailure.BufferedFutureMessage
is MlsException.SelfCommitIgnored -> MLSFailure.SelfCommitIgnored
is MlsException.UnmergedPendingGroup -> MLSFailure.UnmergedPendingGroup
is MlsException.StaleProposal -> MLSFailure.StaleProposal
is MlsException.StaleCommit -> MLSFailure.StaleCommit
is MlsException.ConversationAlreadyExists -> MLSFailure.ConversationAlreadyExists
is MlsException.MessageEpochTooOld -> MLSFailure.MessageEpochTooOld
else -> MLSFailure.Generic(exception)
}
} else {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -463,19 +463,14 @@ class CallManagerImpl internal constructor(
callClients: CallClientList
) {
withCalling {
// Mapping Needed to support calls between federated and non federated environments (domain separation)
// Needed to support calls between federated and non federated environments
val clients = callClients.clients.map { callClient ->
CallClient(
userId = federatedIdMapper.parseToFederatedId(callClient.userId),
clientId = callClient.clientId,
isMemberOfSubconversation = callClient.isMemberOfSubconversation,
quality = callClient.quality
federatedIdMapper.parseToFederatedId(callClient.userId),
callClient.clientId
)
}
val clientsJson = CallClientList(clients).toJsonString()
callingLogger.d(
"$TAG - wcall_request_video_streams() called -> Requesting video streams for conversation = ${conversationId.toLogString()}"
)
val conversationIdString = federatedIdMapper.parseToFederatedId(conversationId)
calling.wcall_request_video_streams(
inst = it,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,11 @@ internal class CustomServerConfigDataSource internal constructor(
val storedConfigId = serverConfigurationDAO.configByLinks(serverConfigMapper.toEntity(links))?.id
if (storedConfigId != null) {
// if already exists then just update it
serverConfigurationDAO.updateApiVersion(storedConfigId, metadata.commonApiVersion.version)
serverConfigurationDAO.updateServerMetaData(
id = storedConfigId,
federation = metadata.federation,
commonApiVersion = metadata.commonApiVersion.version
)
if (metadata.federation) serverConfigurationDAO.setFederationToTrue(storedConfigId)
storedConfigId
} else {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -57,9 +57,9 @@ interface ServerConfigRepository {
suspend fun fetchApiVersionAndStore(links: ServerConfig.Links): Either<CoreFailure, ServerConfig>

/**
* update the api version of a locally stored config
* update the api version and federation status of a locally stored config
*/
suspend fun updateConfigApiVersion(serverConfig: ServerConfig): Either<CoreFailure, Unit>
suspend fun updateConfigMetaData(serverConfig: ServerConfig): Either<CoreFailure, Unit>

/**
* Return the server links and metadata for the given userId
Expand Down Expand Up @@ -92,7 +92,11 @@ internal class ServerConfigDataSource(
val storedConfigId = dao.configByLinks(serverConfigMapper.toEntity(links))?.id
if (storedConfigId != null) {
// if already exists then just update it
dao.updateApiVersion(storedConfigId, metadata.commonApiVersion.version)
dao.updateServerMetaData(
id = storedConfigId,
federation = metadata.federation,
commonApiVersion = metadata.commonApiVersion.version
)
if (metadata.federation) dao.setFederationToTrue(storedConfigId)
storedConfigId
} else {
Expand Down Expand Up @@ -132,9 +136,17 @@ internal class ServerConfigDataSource(
storeConfig(links, metaData)
}

override suspend fun updateConfigApiVersion(serverConfig: ServerConfig): Either<CoreFailure, Unit> =
override suspend fun updateConfigMetaData(serverConfig: ServerConfig): Either<CoreFailure, Unit> =
fetchMetadata(serverConfig.links)
.flatMap { wrapStorageRequest { dao.updateApiVersion(serverConfig.id, it.commonApiVersion.version) } }
.flatMap { newMetaData ->
wrapStorageRequest {
dao.updateServerMetaData(
id = serverConfig.id,
federation = newMetaData.federation,
commonApiVersion = newMetaData.commonApiVersion.version
)
}
}

override suspend fun configForUser(userId: UserId): Either<StorageFailure, ServerConfig> =
wrapStorageRequest { dao.configForUser(userId.toDao()) }
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,5 @@ enum class SlowSyncStep {
CONTACTS,
JOINING_MLS_CONVERSATIONS,
RESOLVE_ONE_ON_ONE_PROTOCOLS,
LEGAL_HOLD,
CONVERSATION_FOLDERS,
LEGAL_HOLD
}
Loading

0 comments on commit e2b73ad

Please sign in to comment.