feat: bringing the config sync message types and amendment functions into a companion extension function to build into regular member change handling / invite logic
This commit is contained in:
parent
ecc75dfeed
commit
4b6a7c145e
|
@ -31,6 +31,7 @@ import org.session.libsession.messaging.contacts.Contact
|
|||
import org.session.libsession.messaging.jobs.AttachmentUploadJob
|
||||
import org.session.libsession.messaging.jobs.BackgroundGroupAddJob
|
||||
import org.session.libsession.messaging.jobs.ConfigurationSyncJob
|
||||
import org.session.libsession.messaging.jobs.ConfigurationSyncJob.Companion.messageInformation
|
||||
import org.session.libsession.messaging.jobs.GroupAvatarDownloadJob
|
||||
import org.session.libsession.messaging.jobs.InviteContactsJob
|
||||
import org.session.libsession.messaging.jobs.Job
|
||||
|
@ -1618,9 +1619,12 @@ open class Storage(
|
|||
|
||||
override fun handleMemberLeft(message: GroupUpdated, closedGroupId: SessionId) {
|
||||
val userGroups = configFactory.userGroups ?: return
|
||||
val closedGroupHexString = closedGroupId.hexString()
|
||||
val closedGroup = userGroups.getClosedGroup(closedGroupId.hexString()) ?: return
|
||||
if (closedGroup.hasAdminKey()) {
|
||||
// re-key and do a new config removing the previous member
|
||||
val adminKey = closedGroup.adminKey
|
||||
val signCallback = SnodeAPI.signingKeyCallback(adminKey)
|
||||
val info = configFactory.getGroupInfoConfig(closedGroupId) ?: return
|
||||
val members = configFactory.getGroupMemberConfig(closedGroupId) ?: return
|
||||
val keys = configFactory.getGroupKeysConfig(closedGroupId, info, members, free = false) ?: return
|
||||
|
@ -1628,8 +1632,61 @@ open class Storage(
|
|||
|
||||
keys.rekey(info, members)
|
||||
|
||||
val
|
||||
val toDelete = mutableListOf<String>()
|
||||
|
||||
val keyMessage = keys.messageInformation(closedGroupHexString, adminKey)
|
||||
val infoMessage = info.messageInformation(toDelete, closedGroupHexString, adminKey)
|
||||
val membersMessage = members.messageInformation(toDelete, closedGroupHexString, adminKey)
|
||||
|
||||
val delete = SnodeAPI.buildAuthenticatedDeleteBatchInfo(
|
||||
closedGroupHexString,
|
||||
toDelete,
|
||||
signCallback
|
||||
)
|
||||
|
||||
val stores = listOf(keyMessage, infoMessage, membersMessage).map(ConfigurationSyncJob.ConfigMessageInformation::batch)
|
||||
|
||||
val response = SnodeAPI.getSingleTargetSnode(closedGroupHexString).bind { snode ->
|
||||
SnodeAPI.getRawBatchResponse(
|
||||
snode,
|
||||
closedGroupHexString,
|
||||
stores + delete,
|
||||
sequence = true
|
||||
)
|
||||
}
|
||||
|
||||
try {
|
||||
response.get()
|
||||
// todo: error handling here
|
||||
|
||||
configFactory.saveGroupConfigs(keys, info, members)
|
||||
|
||||
val timestamp = SnodeAPI.nowWithOffset
|
||||
val messageToSign = "MEMBER_CHANGE${GroupUpdateMemberChangeMessage.Type.REMOVED.name}$timestamp"
|
||||
val signature = SodiumUtilities.sign(messageToSign.toByteArray(), adminKey)
|
||||
val updatedMessage = GroupUpdated(
|
||||
DataMessage.GroupUpdateMessage.newBuilder()
|
||||
.setMemberChangeMessage(
|
||||
GroupUpdateMemberChangeMessage.newBuilder()
|
||||
.addAllMemberSessionIds(listOf(message.sender!!))
|
||||
.setType(GroupUpdateMemberChangeMessage.Type.REMOVED)
|
||||
.setAdminSignature(ByteString.copyFrom(signature))
|
||||
)
|
||||
.build()
|
||||
).apply { this.sentTimestamp = timestamp }
|
||||
MessageSender.send(updatedMessage, fromSerialized(closedGroupHexString))
|
||||
insertGroupInfoChange(updatedMessage, closedGroupId)
|
||||
info.free()
|
||||
members.free()
|
||||
keys.free()
|
||||
} catch (e: Exception) {
|
||||
Log.e("ClosedGroup", "Failed to store new key", e)
|
||||
info.free()
|
||||
members.free()
|
||||
keys.free()
|
||||
// toaster toast here
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
insertGroupInfoChange(message, closedGroupId)
|
||||
|
|
|
@ -102,58 +102,6 @@ data class ConfigurationSyncJob(val destination: Destination) : Job {
|
|||
return SyncInformation(configsRequiringPush, toDelete)
|
||||
}
|
||||
|
||||
private fun ConfigBase.messageInformation(toDelete: MutableList<String>,
|
||||
destinationPubKey: String,
|
||||
signingKey: ByteArray? = null,
|
||||
ed25519PubKey: String? = null): ConfigMessageInformation {
|
||||
val sentTimestamp = SnodeAPI.nowWithOffset
|
||||
val (push, seqNo, obsoleteHashes) = push()
|
||||
toDelete.addAll(obsoleteHashes)
|
||||
val message =
|
||||
SnodeMessage(
|
||||
destinationPubKey,
|
||||
Base64.encodeBytes(push),
|
||||
SnodeMessage.CONFIG_TTL,
|
||||
sentTimestamp
|
||||
)
|
||||
|
||||
return ConfigMessageInformation(
|
||||
if (signingKey != null && ed25519PubKey == null) {
|
||||
SnodeAPI.buildAuthenticatedStoreBatchInfo(
|
||||
namespace(),
|
||||
message,
|
||||
signingKey,
|
||||
)
|
||||
} else SnodeAPI.buildAuthenticatedStoreBatchInfo(
|
||||
namespace(),
|
||||
message,
|
||||
)!!,
|
||||
this,
|
||||
seqNo
|
||||
)
|
||||
}
|
||||
|
||||
private fun GroupKeysConfig.messageInformation(destinationPubKey: String, signingKey: ByteArray): ConfigMessageInformation {
|
||||
val sentTimestamp = SnodeAPI.nowWithOffset
|
||||
val message =
|
||||
SnodeMessage(
|
||||
destinationPubKey,
|
||||
Base64.encodeBytes(pendingConfig()!!), // should not be null from checking has pending
|
||||
SnodeMessage.CONFIG_TTL,
|
||||
sentTimestamp
|
||||
)
|
||||
|
||||
return ConfigMessageInformation(
|
||||
SnodeAPI.buildAuthenticatedStoreBatchInfo(
|
||||
namespace(),
|
||||
message,
|
||||
signingKey
|
||||
),
|
||||
this,
|
||||
0
|
||||
)
|
||||
}
|
||||
|
||||
override suspend fun execute(dispatcherName: String) {
|
||||
val storage = MessagingModuleConfiguration.shared.storage
|
||||
|
||||
|
@ -305,6 +253,58 @@ data class ConfigurationSyncJob(val destination: Destination) : Job {
|
|||
// type mappings
|
||||
const val CONTACT_TYPE = 1
|
||||
const val GROUP_TYPE = 2
|
||||
|
||||
fun ConfigBase.messageInformation(toDelete: MutableList<String>,
|
||||
destinationPubKey: String,
|
||||
signingKey: ByteArray? = null,
|
||||
ed25519PubKey: String? = null): ConfigMessageInformation {
|
||||
val sentTimestamp = SnodeAPI.nowWithOffset
|
||||
val (push, seqNo, obsoleteHashes) = push()
|
||||
toDelete.addAll(obsoleteHashes)
|
||||
val message =
|
||||
SnodeMessage(
|
||||
destinationPubKey,
|
||||
Base64.encodeBytes(push),
|
||||
SnodeMessage.CONFIG_TTL,
|
||||
sentTimestamp
|
||||
)
|
||||
|
||||
return ConfigMessageInformation(
|
||||
if (signingKey != null && ed25519PubKey == null) {
|
||||
SnodeAPI.buildAuthenticatedStoreBatchInfo(
|
||||
namespace(),
|
||||
message,
|
||||
signingKey,
|
||||
)
|
||||
} else SnodeAPI.buildAuthenticatedStoreBatchInfo(
|
||||
namespace(),
|
||||
message,
|
||||
)!!,
|
||||
this,
|
||||
seqNo
|
||||
)
|
||||
}
|
||||
|
||||
fun GroupKeysConfig.messageInformation(destinationPubKey: String, signingKey: ByteArray): ConfigMessageInformation {
|
||||
val sentTimestamp = SnodeAPI.nowWithOffset
|
||||
val message =
|
||||
SnodeMessage(
|
||||
destinationPubKey,
|
||||
Base64.encodeBytes(pendingConfig()!!), // should not be null from checking has pending
|
||||
SnodeMessage.CONFIG_TTL,
|
||||
sentTimestamp
|
||||
)
|
||||
|
||||
return ConfigMessageInformation(
|
||||
SnodeAPI.buildAuthenticatedStoreBatchInfo(
|
||||
namespace(),
|
||||
message,
|
||||
signingKey
|
||||
),
|
||||
this,
|
||||
0
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
class Factory : Job.Factory<ConfigurationSyncJob> {
|
||||
|
|
Loading…
Reference in New Issue