Fix compilation issues

This commit is contained in:
SessionHero01 2024-10-14 14:37:13 +11:00
parent 1f9b00bc0a
commit 222df30a18
No known key found for this signature in database
4 changed files with 118 additions and 88 deletions

View File

@ -35,6 +35,7 @@ import org.session.libsession.utilities.ConfigUpdateNotification
import org.session.libsession.utilities.GroupUtil
import org.session.libsession.utilities.SSKEnvironment.ProfileManagerProtocol.Companion.NAME_PADDED_LENGTH
import org.session.libsession.utilities.TextSecurePreferences
import org.session.libsession.utilities.UserConfigType
import org.session.libsession.utilities.recipients.Recipient
import org.session.libsignal.crypto.ecc.DjbECPrivateKey
import org.session.libsignal.crypto.ecc.DjbECPublicKey
@ -86,7 +87,7 @@ class ConfigToDatabaseSync @Inject constructor(
.collect { config ->
try {
Log.i(TAG, "Start syncing user configs")
syncUserConfigs(config.timestamp)
syncUserConfigs(config.configType, config.timestamp)
Log.i(TAG, "Finished syncing user configs")
} catch (e: Exception) {
Log.e(TAG, "Error syncing user configs", e)
@ -116,23 +117,23 @@ class ConfigToDatabaseSync @Inject constructor(
updateGroup(info)
}
private fun syncUserConfigs(updateTimestamp: Long) {
lateinit var updateUserInfo: UpdateUserInfo
lateinit var updateUserGroupsInfo: UpdateUserGroupsInfo
lateinit var updateContacts: List<Contact>
lateinit var updateConvoVolatile: List<Conversation?>
configFactory.withUserConfigs { configs ->
updateUserInfo = UpdateUserInfo(configs.userProfile)
updateUserGroupsInfo = UpdateUserGroupsInfo(configs.userGroups)
updateContacts = configs.contacts.all()
updateConvoVolatile = configs.convoInfoVolatile.all()
private fun syncUserConfigs(userConfigType: UserConfigType, updateTimestamp: Long) {
val configUpdate = configFactory.withUserConfigs { configs ->
when (userConfigType) {
UserConfigType.USER_PROFILE -> UpdateUserInfo(configs.userProfile)
UserConfigType.USER_GROUPS -> UpdateUserGroupsInfo(configs.userGroups)
UserConfigType.CONTACTS -> UpdateContacts(configs.contacts.all())
UserConfigType.CONVO_INFO_VOLATILE -> UpdateConvoVolatile(configs.convoInfoVolatile.all())
}
}
updateUser(updateUserInfo, updateTimestamp)
updateContacts(updateContacts, updateTimestamp)
updateUserGroups(updateUserGroupsInfo, updateTimestamp)
updateConvoVolatile(updateConvoVolatile)
when (configUpdate) {
is UpdateUserInfo -> updateUser(configUpdate, updateTimestamp)
is UpdateUserGroupsInfo -> updateUserGroups(configUpdate, updateTimestamp)
is UpdateContacts -> updateContacts(configUpdate, updateTimestamp)
is UpdateConvoVolatile -> updateConvoVolatile(configUpdate)
else -> error("Unknown config update type: $configUpdate")
}
}
private data class UpdateUserInfo(
@ -219,8 +220,10 @@ class ConfigToDatabaseSync @Inject constructor(
}
}
private fun updateContacts(contacts: List<Contact>, messageTimestamp: Long) {
storage.addLibSessionContacts(contacts, messageTimestamp)
private data class UpdateContacts(val contacts: List<Contact>)
private fun updateContacts(contacts: UpdateContacts, messageTimestamp: Long) {
storage.addLibSessionContacts(contacts.contacts, messageTimestamp)
}
private data class UpdateUserGroupsInfo(
@ -368,8 +371,10 @@ class ConfigToDatabaseSync @Inject constructor(
}
}
private fun updateConvoVolatile(convos: List<Conversation?>) {
val extracted = convos.filterNotNull()
private data class UpdateConvoVolatile(val convos: List<Conversation?>)
private fun updateConvoVolatile(convos: UpdateConvoVolatile) {
val extracted = convos.convos.filterNotNull()
for (conversation in extracted) {
val threadId = when (conversation) {
is Conversation.OneToOne -> storage.getThreadIdFor(conversation.accountId, null, null, createThread = false)

View File

@ -49,6 +49,7 @@ import org.session.libsignal.utilities.IdPrefix
import org.session.libsignal.utilities.Log
import org.session.libsignal.utilities.toHexString
import org.thoughtcrime.securesms.database.ConfigDatabase
import org.thoughtcrime.securesms.database.ConfigVariant
import org.thoughtcrime.securesms.database.LokiThreadDatabase
import org.thoughtcrime.securesms.database.ThreadDatabase
import org.thoughtcrime.securesms.groups.GroupManager
@ -142,14 +143,18 @@ class ConfigFactory @Inject constructor(
*
* @param cb A function that takes a [UserConfigsImpl] and returns a pair of the result of the operation and a boolean indicating if the configs were changed.
*/
private fun <T> doWithMutableUserConfigs(cb: (UserConfigsImpl) -> Pair<T, ConfigUpdateNotification?>): T {
private fun <T> doWithMutableUserConfigs(cb: (UserConfigsImpl) -> Pair<T, List<ConfigUpdateNotification>>): T {
val (lock, configs) = ensureUserConfigsInitialized()
val (result, changed) = lock.write {
cb(configs)
}
if (changed != null) {
_configUpdateNotifications.tryEmit(changed)
if (changed.isNotEmpty()) {
for (notification in changed) {
if (!_configUpdateNotifications.tryEmit(notification)) {
Log.e("ConfigFactory", "Unable to deliver config update notification")
}
}
}
return result
@ -163,7 +168,7 @@ class ConfigFactory @Inject constructor(
return
}
return doWithMutableUserConfigs { configs ->
val toDump = doWithMutableUserConfigs { configs ->
val config = when (userConfigType) {
UserConfigType.CONTACTS -> configs.contacts
UserConfigType.USER_PROFILE -> configs.userProfile
@ -171,22 +176,42 @@ class ConfigFactory @Inject constructor(
UserConfigType.USER_GROUPS -> configs.userGroups
}
// Merge the list of config messages, we'll be told which messages have been merged
// and we will then find out which message has the max timestamp
val maxTimestamp = config.merge(messages.map { it.hash to it.data }.toTypedArray())
.asSequence()
.mapNotNull { hash -> messages.firstOrNull { it.hash == hash } }
.maxOfOrNull { it.timestamp }
Unit to maxTimestamp?.let(ConfigUpdateNotification::UserConfigsMerged)
maxTimestamp?.let {
(config.dump() to it) to
listOf(ConfigUpdateNotification.UserConfigsMerged(userConfigType, it))
} ?: (null to emptyList())
}
// Dump now regardless so we can save the timestamp to the database
if (toDump != null) {
val (dump, timestamp) = toDump
configDatabase.storeConfig(
variant = userConfigType.configVariant,
publicKey = requiresCurrentUserAccountId().hexString,
data = dump,
timestamp = timestamp
)
}
}
override fun <T> withMutableUserConfigs(cb: (MutableUserConfigs) -> T): T {
return doWithMutableUserConfigs {
val result = cb(it)
val changed = if (it.persistIfDirty(clock)) {
ConfigUpdateNotification.UserConfigsModified
val changed = if (it.userGroups.dirty() ||
it.convoInfoVolatile.dirty() ||
it.userProfile.dirty() ||
it.contacts.dirty()) {
listOf(ConfigUpdateNotification.UserConfigsModified)
} else {
null
emptyList()
}
result to changed
@ -293,15 +318,30 @@ class ConfigFactory @Inject constructor(
return
}
doWithMutableUserConfigs { configs ->
contacts?.let { (push, result) -> configs.contacts.confirmPushed(push.seqNo, result.hash) }
userProfile?.let { (push, result) -> configs.userProfile.confirmPushed(push.seqNo, result.hash) }
convoInfoVolatile?.let { (push, result) -> configs.convoInfoVolatile.confirmPushed(push.seqNo, result.hash) }
userGroups?.let { (push, result) -> configs.userGroups.confirmPushed(push.seqNo, result.hash) }
// Confirm push for the configs and gather the dumped data to be saved into the db.
// For this operation, we will no notify the users as there won't be any real change in terms
// of the displaying data.
val dump = doWithMutableUserConfigs { configs ->
sequenceOf(contacts, userProfile, convoInfoVolatile, userGroups)
.zip(
sequenceOf(
UserConfigType.CONTACTS to configs.contacts,
UserConfigType.USER_PROFILE to configs.userProfile,
UserConfigType.CONVO_INFO_VOLATILE to configs.convoInfoVolatile,
UserConfigType.USER_GROUPS to configs.userGroups
)
)
.filter { (push, _) -> push != null }
.onEach { (push, config) -> config.second.confirmPushed(push!!.first.seqNo, push.second.hash) }
.map { (push, config) ->
Triple(config.first.configVariant, config.second.dump(), push!!.second.timestamp)
}.toList() to emptyList()
}
configs.persistIfDirty(clock)
Unit to null
// We need to persist the data to the database to save timestamp after the push
val userAccountId = requiresCurrentUserAccountId()
for ((variant, data, timestamp) in dump) {
configDatabase.storeConfig(variant, userAccountId.hexString, data, timestamp)
}
}
@ -329,18 +369,6 @@ class ConfigFactory @Inject constructor(
}
}
override fun getConfigTimestamp(forConfigObject: ConfigBase, publicKey: String): Long {
val variant = when (forConfigObject) {
is UserProfile -> SharedConfigMessage.Kind.USER_PROFILE.name
is Contacts -> SharedConfigMessage.Kind.CONTACTS.name
is ConversationVolatileConfig -> SharedConfigMessage.Kind.CONVO_INFO_VOLATILE.name
is UserGroupsConfig -> SharedConfigMessage.Kind.GROUPS.name
else -> throw UnsupportedOperationException("Can't support type of ${forConfigObject::class.simpleName} yet")
}
return configDatabase.retrieveConfigLastUpdateTimestamp(variant, publicKey)
}
override fun conversationInConfig(
publicKey: String?,
groupPublicKey: String?,
@ -391,6 +419,10 @@ class ConfigFactory @Inject constructor(
return (changeTimestampMs >= (lastUpdateTimestampMs - CONFIG_CHANGE_BUFFER_PERIOD))
}
override fun getConfigTimestamp(userConfigType: UserConfigType, publicKey: String): Long {
return configDatabase.retrieveConfigLastUpdateTimestamp(userConfigType.configVariant, publicKey)
}
override fun getGroupAuth(groupId: AccountId): SwarmAuth? {
val (adminKey, authData) = withUserConfigs {
val group = it.userGroups.getClosedGroup(groupId.hexString)
@ -441,6 +473,14 @@ class ConfigFactory @Inject constructor(
}
}
private val UserConfigType.configVariant: ConfigVariant
get() = when (this) {
UserConfigType.CONTACTS -> ConfigDatabase.CONTACTS_VARIANT
UserConfigType.USER_PROFILE -> ConfigDatabase.USER_PROFILE_VARIANT
UserConfigType.CONVO_INFO_VOLATILE -> ConfigDatabase.CONVO_INFO_VARIANT
UserConfigType.USER_GROUPS -> ConfigDatabase.USER_GROUPS_VARIANT
}
/**
* Sync group data from our local database
*/
@ -639,30 +679,6 @@ private class UserConfigsImpl(
convoInfoVolatile.initFrom(storage, threadDb)
}
}
/**
* Persists the config if it is dirty and returns the list of classes that were persisted
*/
fun persistIfDirty(clock: SnodeClock): Boolean {
return sequenceOf(
contacts to ConfigDatabase.CONTACTS_VARIANT,
userGroups to ConfigDatabase.USER_GROUPS_VARIANT,
userProfile to ConfigDatabase.USER_PROFILE_VARIANT,
convoInfoVolatile to ConfigDatabase.CONVO_INFO_VARIANT
).fold(false) { acc, (config, variant) ->
if (config.needsDump()) {
configDatabase.storeConfig(
variant = variant,
publicKey = userAccountId.hexString,
data = config.dump(),
timestamp = clock.currentTimeMills()
)
true
} else {
acc
}
}
}
}
private class GroupConfigsImpl(

View File

@ -35,6 +35,7 @@ import org.session.libsession.messaging.sending_receiving.handleVisibleMessage
import org.session.libsession.messaging.utilities.Data
import org.session.libsession.messaging.utilities.SodiumUtilities
import org.session.libsession.utilities.SSKEnvironment
import org.session.libsession.utilities.UserConfigType
import org.session.libsignal.protos.UtilProtos
import org.session.libsignal.utilities.AccountId
import org.session.libsignal.utilities.IdPrefix
@ -103,24 +104,23 @@ class BatchMessageReceiveJob(
executeAsync(dispatcherName)
}
private fun isHidden(message: Message): Boolean{
private fun isHidden(message: Message): Boolean {
// if the contact is marked as hidden for 1on1 messages
// and the message's sentTimestamp is earlier than the sentTimestamp of the last config
val config = MessagingModuleConfiguration.shared.configFactory
val configFactory = MessagingModuleConfiguration.shared.configFactory
val publicKey = MessagingModuleConfiguration.shared.storage.getUserPublicKey()
if(config.contacts == null || message.sentTimestamp == null || publicKey == null) return false
val contactConfigTimestamp = config.getConfigTimestamp(config.contacts!!, publicKey)
if(message.groupPublicKey == null && // not a group
if (message.sentTimestamp == null || publicKey == null) return false
val contactConfigTimestamp = configFactory.getConfigTimestamp(UserConfigType.CONTACTS, publicKey)
return configFactory.withUserConfigs { configs ->
message.groupPublicKey == null && // not a group
message.openGroupServerMessageID == null && // not a community
// not marked as hidden
config.contacts?.get(message.senderOrSync)?.priority == ConfigBase.PRIORITY_HIDDEN &&
configs.contacts.get(message.senderOrSync)?.priority == ConfigBase.PRIORITY_HIDDEN &&
// the message's sentTimestamp is earlier than the sentTimestamp of the last config
message.sentTimestamp!! < contactConfigTimestamp
) {
return true
}
return false
}
suspend fun executeAsync(dispatcherName: String) {

View File

@ -5,7 +5,6 @@ import kotlinx.coroutines.flow.filter
import kotlinx.coroutines.flow.first
import kotlinx.coroutines.flow.onStart
import kotlinx.coroutines.withTimeoutOrNull
import network.loki.messenger.libsession_util.ConfigBase
import network.loki.messenger.libsession_util.MutableConfig
import network.loki.messenger.libsession_util.MutableContacts
import network.loki.messenger.libsession_util.MutableConversationVolatileConfig
@ -196,8 +195,18 @@ interface MutableGroupConfigs : GroupConfigs {
sealed interface ConfigUpdateNotification {
/**
* The user configs have been modified locally.
*/
data object UserConfigsModified : ConfigUpdateNotification
data class UserConfigsMerged(val timestamp: Long) : ConfigUpdateNotification
/**
* The user configs have been merged from the server.
*/
data class UserConfigsMerged(
val configType: UserConfigType,
val timestamp: Long
) : ConfigUpdateNotification
data class GroupConfigsUpdated(val groupId: AccountId) : ConfigUpdateNotification
}