feat: adding user groups to the list of user configs, refactorign some of the config factory to fetch the user configs easier. Add handling for polling user group namespace

This commit is contained in:
0x330a 2023-03-06 17:16:42 +11:00
parent 66c997dfb2
commit 8d8325f16e
No known key found for this signature in database
GPG Key ID: 267811D6E6A2698C
4 changed files with 31 additions and 6 deletions

View File

@ -4,6 +4,7 @@ import android.content.Context
import network.loki.messenger.libsession_util.ConfigBase import network.loki.messenger.libsession_util.ConfigBase
import network.loki.messenger.libsession_util.Contacts import network.loki.messenger.libsession_util.Contacts
import network.loki.messenger.libsession_util.ConversationVolatileConfig import network.loki.messenger.libsession_util.ConversationVolatileConfig
import network.loki.messenger.libsession_util.UserGroupsConfig
import network.loki.messenger.libsession_util.UserProfile import network.loki.messenger.libsession_util.UserProfile
import org.session.libsession.utilities.ConfigFactoryProtocol import org.session.libsession.utilities.ConfigFactoryProtocol
import org.session.libsession.utilities.ConfigFactoryUpdateListener import org.session.libsession.utilities.ConfigFactoryUpdateListener
@ -34,7 +35,8 @@ class ConfigFactory(private val context: Context,
private val contactsHashes = ConcurrentSkipListSet<String>() private val contactsHashes = ConcurrentSkipListSet<String>()
private val convoVolatileLock = Object() private val convoVolatileLock = Object()
private var _convoVolatileConfig: ConversationVolatileConfig? = null private var _convoVolatileConfig: ConversationVolatileConfig? = null
private val convoHashes = ConcurrentSkipListSet<String>() private val userGroupsLock = Object()
private var _userGroups: UserGroupsConfig? = null
private val listeners: MutableList<ConfigFactoryUpdateListener> = mutableListOf() private val listeners: MutableList<ConfigFactoryUpdateListener> = mutableListOf()
fun registerListener(listener: ConfigFactoryUpdateListener) { listeners += listener } fun registerListener(listener: ConfigFactoryUpdateListener) { listeners += listener }
@ -77,7 +79,6 @@ class ConfigFactory(private val context: Context,
_convoVolatileConfig = if (convoDump != null) { _convoVolatileConfig = if (convoDump != null) {
ConversationVolatileConfig.newInstance(secretKey, convoDump) ConversationVolatileConfig.newInstance(secretKey, convoDump)
} else { } else {
// TODO: generate convo volatile config here
ConfigurationMessageUtilities.generateConversationVolatileDump(context)?.let { dump -> ConfigurationMessageUtilities.generateConversationVolatileDump(context)?.let { dump ->
ConversationVolatileConfig.newInstance(secretKey, dump) ConversationVolatileConfig.newInstance(secretKey, dump)
} ?: ConversationVolatileConfig.newInstance(secretKey) } ?: ConversationVolatileConfig.newInstance(secretKey)
@ -86,6 +87,21 @@ class ConfigFactory(private val context: Context,
_convoVolatileConfig _convoVolatileConfig
} }
override val userGroups: UserGroupsConfig? get() = synchronized(userGroupsLock) {
if (_userGroups == null) {
val (secretKey, publicKey) = maybeGetUserInfo() ?: return@synchronized null
val userGroupsDump = configDatabase.retrieveConfigAndHashes(SharedConfigMessage.Kind.GROUPS.name, publicKey)
_userGroups = if (userGroupsDump != null) {
UserGroupsConfig.Companion.newInstance(secretKey, userGroupsDump)
} else {
ConfigurationMessageUtilities.generateUserGroupDump(context)?.let { dump ->
UserGroupsConfig.Companion.newInstance(secretKey, dump)
} ?: UserGroupsConfig.newInstance(secretKey)
}
}
_userGroups
}
private fun persistUserConfigDump() = synchronized(userLock) { private fun persistUserConfigDump() = synchronized(userLock) {
val dumped = user?.dump() ?: return val dumped = user?.dump() ?: return
@ -105,6 +121,12 @@ class ConfigFactory(private val context: Context,
configDatabase.storeConfig(SharedConfigMessage.Kind.CONVO_INFO_VOLATILE.name, publicKey, dumped) configDatabase.storeConfig(SharedConfigMessage.Kind.CONVO_INFO_VOLATILE.name, publicKey, dumped)
} }
private fun persistUserGroupsConfigDump() = synchronized(userGroupsLock) {
val dumped = userGroups?.dump() ?: return
val (_, publicKey) = maybeGetUserInfo() ?: return
configDatabase.storeConfig(SharedConfigMessage.Kind.GROUPS.name, publicKey, dumped)
}
override fun persist(forConfigObject: ConfigBase) { override fun persist(forConfigObject: ConfigBase) {
listeners.forEach { listener -> listeners.forEach { listener ->
listener.notifyUpdates(forConfigObject) listener.notifyUpdates(forConfigObject)
@ -113,6 +135,7 @@ class ConfigFactory(private val context: Context,
is UserProfile -> persistUserConfigDump() is UserProfile -> persistUserConfigDump()
is Contacts -> persistContactsConfigDump() is Contacts -> persistContactsConfigDump()
is ConversationVolatileConfig -> persistConvoVolatileConfigDump() is ConversationVolatileConfig -> persistConvoVolatileConfigDump()
is UserGroupsConfig -> persistUserGroupsConfigDump()
else -> throw UnsupportedOperationException("Can't support type of ${forConfigObject::class.simpleName} yet") else -> throw UnsupportedOperationException("Can't support type of ${forConfigObject::class.simpleName} yet")
} }
} }

View File

@ -194,7 +194,6 @@ object ConfigurationMessageUtilities {
} }
recipient.isContactRecipient -> { recipient.isContactRecipient -> {
val sessionId = SessionId(recipient.address.serialize()) val sessionId = SessionId(recipient.address.serialize())
if (recipient.isLocalNumber) null // this is handled by the user profile NTS data if (recipient.isLocalNumber) null // this is handled by the user profile NTS data
else convoConfig.getOrConstructOneToOne(recipient.address.serialize()) else convoConfig.getOrConstructOneToOne(recipient.address.serialize())
} }
@ -237,7 +236,6 @@ object ConfigurationMessageUtilities {
val sessionId = GroupUtil.doubleEncodeGroupID(group.getId()) val sessionId = GroupUtil.doubleEncodeGroupID(group.getId())
val admins = group.admins.map { it.serialize() to true }.toMap() val admins = group.admins.map { it.serialize() to true }.toMap()
val members = group.members.filterNot { it.serialize() !in admins.keys }.map { it.serialize() to false }.toMap() val members = group.members.filterNot { it.serialize() !in admins.keys }.map { it.serialize() to false }.toMap()
val encPub = storage.getClosedGroupEncryptionKeyPairs(group.)
GroupInfo.LegacyGroupInfo( GroupInfo.LegacyGroupInfo(
sessionId = sessionId, sessionId = sessionId,
name = group.title, name = group.title,
@ -248,7 +246,6 @@ object ConfigurationMessageUtilities {
encSecKey = encryptionKeyPair.privateKey.serialize() encSecKey = encryptionKeyPair.privateKey.serialize()
) )
} }
(allOpenGroups + allLgc).forEach { groupInfo -> (allOpenGroups + allLgc).forEach { groupInfo ->
groupConfig.set(groupInfo) groupConfig.set(groupInfo)
} }

View File

@ -9,6 +9,7 @@ import kotlinx.coroutines.runBlocking
import network.loki.messenger.libsession_util.ConfigBase import network.loki.messenger.libsession_util.ConfigBase
import network.loki.messenger.libsession_util.Contacts import network.loki.messenger.libsession_util.Contacts
import network.loki.messenger.libsession_util.ConversationVolatileConfig import network.loki.messenger.libsession_util.ConversationVolatileConfig
import network.loki.messenger.libsession_util.UserGroupsConfig
import network.loki.messenger.libsession_util.UserProfile import network.loki.messenger.libsession_util.UserProfile
import nl.komponents.kovenant.Deferred import nl.komponents.kovenant.Deferred
import nl.komponents.kovenant.Promise import nl.komponents.kovenant.Promise
@ -175,7 +176,7 @@ class Poller(private val configFactory: ConfigFactoryProtocol, debounceTimer: Ti
requestSparseArray[personalMessages.namespace!!] = personalMessages requestSparseArray[personalMessages.namespace!!] = personalMessages
} }
// get the latest convo info volatile // get the latest convo info volatile
listOfNotNull(configFactory.user, configFactory.contacts, configFactory.convoVolatile).mapNotNull { config -> configFactory.getUserConfigs().mapNotNull { config ->
SnodeAPI.buildAuthenticatedRetrieveBatchRequest( SnodeAPI.buildAuthenticatedRetrieveBatchRequest(
snode, userPublicKey, snode, userPublicKey,
config.configNamespace() config.configNamespace()
@ -236,6 +237,7 @@ class Poller(private val configFactory: ConfigFactoryProtocol, debounceTimer: Ti
UserProfile::class.java -> processConfig(snode, body, key, configFactory.user) UserProfile::class.java -> processConfig(snode, body, key, configFactory.user)
Contacts::class.java -> processConfig(snode, body, key, configFactory.contacts) Contacts::class.java -> processConfig(snode, body, key, configFactory.contacts)
ConversationVolatileConfig::class.java -> processConfig(snode, body, key, configFactory.convoVolatile) ConversationVolatileConfig::class.java -> processConfig(snode, body, key, configFactory.convoVolatile)
UserGroupsConfig::class.java -> processConfig(snode, body, key, configFactory.userGroups)
} }
} }
} }

View File

@ -3,12 +3,15 @@ package org.session.libsession.utilities
import network.loki.messenger.libsession_util.ConfigBase import network.loki.messenger.libsession_util.ConfigBase
import network.loki.messenger.libsession_util.Contacts import network.loki.messenger.libsession_util.Contacts
import network.loki.messenger.libsession_util.ConversationVolatileConfig import network.loki.messenger.libsession_util.ConversationVolatileConfig
import network.loki.messenger.libsession_util.UserGroupsConfig
import network.loki.messenger.libsession_util.UserProfile import network.loki.messenger.libsession_util.UserProfile
interface ConfigFactoryProtocol { interface ConfigFactoryProtocol {
val user: UserProfile? val user: UserProfile?
val contacts: Contacts? val contacts: Contacts?
val convoVolatile: ConversationVolatileConfig? val convoVolatile: ConversationVolatileConfig?
val userGroups: UserGroupsConfig?
fun getUserConfigs(): List<ConfigBase>
fun persist(forConfigObject: ConfigBase) fun persist(forConfigObject: ConfigBase)
} }