refactor: refactor the configs to implement a parent with common functionality across config base and config sig

This commit is contained in:
0x330a
2023-09-17 23:00:40 +10:00
parent 915fa5bc2b
commit b5b248a6ec
6 changed files with 130 additions and 34 deletions

View File

@@ -109,12 +109,6 @@ Java_network_loki_messenger_libsession_1util_ConfigBase_merge__Lkotlin_Pair_2(JN
#pragma clang diagnostic pop #pragma clang diagnostic pop
} }
extern "C" extern "C"
JNIEXPORT jint JNICALL
Java_network_loki_messenger_libsession_1util_ConfigBase_configNamespace(JNIEnv *env, jobject thiz) {
auto conf = ptrToConfigBase(env, thiz);
return (std::int16_t) conf->storage_namespace();
}
extern "C"
JNIEXPORT jclass JNICALL JNIEXPORT jclass JNICALL
Java_network_loki_messenger_libsession_1util_ConfigBase_00024Companion_kindFor(JNIEnv *env, Java_network_loki_messenger_libsession_1util_ConfigBase_00024Companion_kindFor(JNIEnv *env,
jobject thiz, jobject thiz,

View File

@@ -25,4 +25,10 @@ inline std::pair<std::string, session::ustring> extractHashAndData(JNIEnv *env,
return ret_pair; return ret_pair;
} }
inline session::config::ConfigSig* ptrToConfigSig(JNIEnv* env, jobject obj) {
jclass baseClass = env->FindClass("network/loki/messenger/libsession_util/ConfigSig");
jfieldID pointerField = env->GetFieldID(baseClass, "pointer", "J");
return (session::config::ConfigSig*) env->GetLongField(obj, pointerField);
}
#endif #endif

View File

@@ -284,4 +284,70 @@ Java_network_loki_messenger_libsession_1util_util_BaseCommunityInfo_fullUrl(JNIE
auto deserialized = util::deserialize_base_community(env, thiz); auto deserialized = util::deserialize_base_community(env, thiz);
auto full_url = deserialized.full_url(); auto full_url = deserialized.full_url();
return env->NewStringUTF(full_url.data()); return env->NewStringUTF(full_url.data());
}
extern "C"
JNIEXPORT jint JNICALL
Java_org_session_libsignal_utilities_Namespace_DEFAULT(JNIEnv *env, jobject thiz) {
return 0;
}
extern "C"
JNIEXPORT jint JNICALL
Java_org_session_libsignal_utilities_Namespace_USER_1PROFILE(JNIEnv *env, jobject thiz) {
return (int) session::config::Namespace::UserProfile;
}
extern "C"
JNIEXPORT jint JNICALL
Java_org_session_libsignal_utilities_Namespace_CONTACTS(JNIEnv *env, jobject thiz) {
return (int) session::config::Namespace::Contacts;
}
extern "C"
JNIEXPORT jint JNICALL
Java_org_session_libsignal_utilities_Namespace_CONVO_1INFO_1VOLATILE(JNIEnv *env, jobject thiz) {
return (int) session::config::Namespace::ConvoInfoVolatile;
}
extern "C"
JNIEXPORT jint JNICALL
Java_org_session_libsignal_utilities_Namespace_GROUPS(JNIEnv *env, jobject thiz) {
return (int) session::config::Namespace::UserGroups;
}
extern "C"
JNIEXPORT jint JNICALL
Java_org_session_libsignal_utilities_Namespace_CLOSED_1GROUP_1INFO(JNIEnv *env, jobject thiz) {
return (int) session::config::Namespace::GroupInfo;
}
extern "C"
JNIEXPORT jint JNICALL
Java_org_session_libsignal_utilities_Namespace_CLOSED_1GROUP_1MEMBERS(JNIEnv *env, jobject thiz) {
return (int) session::config::Namespace::GroupMembers;
}
extern "C"
JNIEXPORT jint JNICALL
Java_org_session_libsignal_utilities_Namespace_ENCRYPTION_1KEYS(JNIEnv *env, jobject thiz) {
return (int) session::config::Namespace::GroupKeys;
}
extern "C"
JNIEXPORT void JNICALL
Java_network_loki_messenger_libsession_1util_Config_free(JNIEnv *env, jobject thiz) {
jclass baseClass = env->FindClass("network/loki/messenger/libsession_util/Config");
jfieldID pointerField = env->GetFieldID(baseClass, "pointer", "J");
jclass sig = env->FindClass("network/loki/messenger/libsession_util/ConfigSig");
jclass base = env->FindClass("network/loki/messenger/libsession_util/ConfigBase");
jclass ours = env->GetObjectClass(thiz);
if (env->IsSameObject(sig, ours)) {
// config sig object
auto config = (session::config::ConfigSig*) env->GetLongField(thiz, pointerField);
delete config;
} else if (env->IsSameObject(base, ours)) {
auto config = (session::config::ConfigBase*) env->GetLongField(thiz, pointerField);
delete config;
}
} }

View File

@@ -10,12 +10,20 @@ import network.loki.messenger.libsession_util.util.UserPic
import org.session.libsignal.protos.SignalServiceProtos.SharedConfigMessage.Kind import org.session.libsignal.protos.SignalServiceProtos.SharedConfigMessage.Kind
import org.session.libsignal.utilities.IdPrefix import org.session.libsignal.utilities.IdPrefix
import org.session.libsignal.utilities.Log import org.session.libsignal.utilities.Log
import org.session.libsignal.utilities.Namespace
import org.session.libsignal.utilities.SessionId import org.session.libsignal.utilities.SessionId
import java.io.Closeable import java.io.Closeable
import java.util.Stack import java.util.Stack
sealed class Config(protected val pointer: Long): Closeable {
abstract fun namespace(): Int
external fun free()
override fun close() {
free()
}
}
sealed class ConfigBase(protected val /* yucky */ pointer: Long) { sealed class ConfigBase(pointer: Long): Config(pointer) {
companion object { companion object {
init { init {
System.loadLibrary("session_util") System.loadLibrary("session_util")
@@ -53,13 +61,9 @@ sealed class ConfigBase(protected val /* yucky */ pointer: Long) {
external fun merge(toMerge: Array<Pair<String,ByteArray>>): Int external fun merge(toMerge: Array<Pair<String,ByteArray>>): Int
external fun currentHashes(): List<String> external fun currentHashes(): List<String>
external fun configNamespace(): Int
// Singular merge // Singular merge
external fun merge(toMerge: Pair<String,ByteArray>): Int external fun merge(toMerge: Pair<String,ByteArray>): Int
external fun free()
} }
class Contacts(pointer: Long) : ConfigBase(pointer) { class Contacts(pointer: Long) : ConfigBase(pointer) {
@@ -71,6 +75,8 @@ class Contacts(pointer: Long) : ConfigBase(pointer) {
external fun newInstance(ed25519SecretKey: ByteArray, initialDump: ByteArray): Contacts external fun newInstance(ed25519SecretKey: ByteArray, initialDump: ByteArray): Contacts
} }
override fun namespace() = Namespace.CONTACTS()
external fun get(sessionId: String): Contact? external fun get(sessionId: String): Contact?
external fun getOrConstruct(sessionId: String): Contact external fun getOrConstruct(sessionId: String): Contact
external fun all(): List<Contact> external fun all(): List<Contact>
@@ -126,6 +132,8 @@ class UserProfile(pointer: Long) : ConfigBase(pointer) {
external fun newInstance(ed25519SecretKey: ByteArray, initialDump: ByteArray): UserProfile external fun newInstance(ed25519SecretKey: ByteArray, initialDump: ByteArray): UserProfile
} }
override fun namespace() = Namespace.USER_PROFILE()
external fun setName(newName: String) external fun setName(newName: String)
external fun getName(): String? external fun getName(): String?
external fun getPic(): UserPic external fun getPic(): UserPic
@@ -146,6 +154,8 @@ class ConversationVolatileConfig(pointer: Long): ConfigBase(pointer) {
external fun newInstance(ed25519SecretKey: ByteArray, initialDump: ByteArray): ConversationVolatileConfig external fun newInstance(ed25519SecretKey: ByteArray, initialDump: ByteArray): ConversationVolatileConfig
} }
override fun namespace() = Namespace.CONVO_INFO_VOLATILE()
external fun getOneToOne(pubKeyHex: String): Conversation.OneToOne? external fun getOneToOne(pubKeyHex: String): Conversation.OneToOne?
external fun getOrConstructOneToOne(pubKeyHex: String): Conversation.OneToOne external fun getOrConstructOneToOne(pubKeyHex: String): Conversation.OneToOne
external fun eraseOneToOne(pubKeyHex: String): Boolean external fun eraseOneToOne(pubKeyHex: String): Boolean
@@ -195,6 +205,8 @@ class UserGroupsConfig(pointer: Long): ConfigBase(pointer) {
external fun newInstance(ed25519SecretKey: ByteArray, initialDump: ByteArray): UserGroupsConfig external fun newInstance(ed25519SecretKey: ByteArray, initialDump: ByteArray): UserGroupsConfig
} }
override fun namespace() = Namespace.GROUPS()
external fun getCommunityInfo(baseUrl: String, room: String): GroupInfo.CommunityGroupInfo? external fun getCommunityInfo(baseUrl: String, room: String): GroupInfo.CommunityGroupInfo?
external fun getLegacyGroupInfo(sessionId: String): GroupInfo.LegacyGroupInfo? external fun getLegacyGroupInfo(sessionId: String): GroupInfo.LegacyGroupInfo?
external fun getClosedGroup(sessionId: String): GroupInfo.ClosedGroupInfo? external fun getClosedGroup(sessionId: String): GroupInfo.ClosedGroupInfo?
@@ -230,6 +242,9 @@ class GroupInfoConfig(pointer: Long): ConfigBase(pointer), Closeable {
initialDump: ByteArray = byteArrayOf() initialDump: ByteArray = byteArrayOf()
): GroupInfoConfig ): GroupInfoConfig
} }
override fun namespace() = Namespace.CLOSED_GROUP_INFO()
external fun id(): SessionId external fun id(): SessionId
external fun destroyGroup() external fun destroyGroup()
external fun getCreated(): Long? external fun getCreated(): Long?
@@ -264,6 +279,9 @@ class GroupMembersConfig(pointer: Long): ConfigBase(pointer), Closeable {
initialDump: ByteArray = byteArrayOf() initialDump: ByteArray = byteArrayOf()
): GroupMembersConfig ): GroupMembersConfig
} }
override fun namespace() = Namespace.CLOSED_GROUP_MEMBERS()
external fun all(): Stack<GroupMember> external fun all(): Stack<GroupMember>
external fun erase(groupMember: GroupMember): Boolean external fun erase(groupMember: GroupMember): Boolean
external fun get(pubKeyHex: String): GroupMember? external fun get(pubKeyHex: String): GroupMember?
@@ -274,7 +292,9 @@ class GroupMembersConfig(pointer: Long): ConfigBase(pointer), Closeable {
} }
} }
class GroupKeysConfig(private val pointer: Long): Closeable { sealed class ConfigSig(pointer: Long) : Config(pointer)
class GroupKeysConfig(pointer: Long): ConfigSig(pointer) {
companion object { companion object {
init { init {
System.loadLibrary("session_util") System.loadLibrary("session_util")
@@ -287,8 +307,10 @@ class GroupKeysConfig(private val pointer: Long): Closeable {
info: GroupInfoConfig, info: GroupInfoConfig,
members: GroupMembersConfig members: GroupMembersConfig
): GroupKeysConfig ): GroupKeysConfig
external fun storageNamespace(): Int
} }
override fun namespace() = Namespace.ENCRYPTION_KEYS()
external fun groupKeys(): Stack<ByteArray> external fun groupKeys(): Stack<ByteArray>
external fun keyDump(): ByteArray external fun keyDump(): ByteArray
external fun loadKey(message: ByteArray, external fun loadKey(message: ByteArray,
@@ -300,7 +322,6 @@ class GroupKeysConfig(private val pointer: Long): Closeable {
external fun pendingKey(): ByteArray? external fun pendingKey(): ByteArray?
external fun pendingConfig(): ByteArray? external fun pendingConfig(): ByteArray?
external fun rekey(info: GroupInfoConfig, members: GroupMembersConfig): ByteArray external fun rekey(info: GroupInfoConfig, members: GroupMembersConfig): ByteArray
external fun free()
override fun close() { override fun close() {
free() free()
} }

View File

@@ -10,9 +10,11 @@ import org.session.libsession.messaging.sending_receiving.MessageSender
import org.session.libsession.messaging.utilities.Data import org.session.libsession.messaging.utilities.Data
import org.session.libsession.snode.RawResponse import org.session.libsession.snode.RawResponse
import org.session.libsession.snode.SnodeAPI import org.session.libsession.snode.SnodeAPI
import org.session.libsession.snode.SnodeAPI.SnodeBatchRequestInfo
import org.session.libsession.utilities.TextSecurePreferences import org.session.libsession.utilities.TextSecurePreferences
import org.session.libsignal.utilities.Log import org.session.libsignal.utilities.Log
import java.util.concurrent.atomic.AtomicBoolean import java.util.concurrent.atomic.AtomicBoolean
typealias ConfigPair<T> = List<Pair<T, ConfigBase>>
// only contact (self) and closed group destinations will be supported // only contact (self) and closed group destinations will be supported
data class ConfigurationSyncJob(val destination: Destination): Job { data class ConfigurationSyncJob(val destination: Destination): Job {
@@ -24,27 +26,19 @@ data class ConfigurationSyncJob(val destination: Destination): Job {
val shouldRunAgain = AtomicBoolean(false) val shouldRunAgain = AtomicBoolean(false)
data class SyncInformation(val configs: ConfigPair<SnodeBatchRequestInfo>, val toDelete: List<String>)
override suspend fun execute(dispatcherName: String) { override suspend fun execute(dispatcherName: String) {
val storage = MessagingModuleConfiguration.shared.storage val storage = MessagingModuleConfiguration.shared.storage
val forcedConfig = TextSecurePreferences.hasForcedNewConfig(MessagingModuleConfiguration.shared.context) val forcedConfig = TextSecurePreferences.hasForcedNewConfig(MessagingModuleConfiguration.shared.context)
val currentTime = SnodeAPI.nowWithOffset val currentTime = SnodeAPI.nowWithOffset
val userEdKeyPair = MessagingModuleConfiguration.shared.getUserED25519KeyPair()
val userPublicKey = storage.getUserPublicKey() val userPublicKey = storage.getUserPublicKey()
val delegate = delegate val delegate = delegate ?: return Log.e("ConfigurationSyncJob", "No Delegate")
if (destination is Destination.ClosedGroup // TODO: closed group configs will be handled in closed group feature if ((destination is Destination.Contact && destination.publicKey != userPublicKey)) {
// if we haven't enabled the new configs don't run
|| !ConfigBase.isNewConfigEnabled(forcedConfig, currentTime)
// if we don't have a user ed key pair for signing updates
|| userEdKeyPair == null
// this will be useful to not handle null delegate cases
|| delegate == null
// check our local identity key exists
|| userPublicKey.isNullOrEmpty()
// don't allow pushing configs for non-local user
|| (destination is Destination.Contact && destination.publicKey != userPublicKey)
) {
Log.w(TAG, "No need to run config sync job, TODO") Log.w(TAG, "No need to run config sync job, TODO")
return delegate?.handleJobSucceeded(this, dispatcherName) ?: Unit return delegate.handleJobSucceeded(this, dispatcherName)
} }
// configFactory singleton instance will come in handy for modifying hashes and fetching configs for namespace etc // configFactory singleton instance will come in handy for modifying hashes and fetching configs for namespace etc
@@ -61,7 +55,7 @@ data class ConfigurationSyncJob(val destination: Destination): Job {
// allow null results here so the list index matches configsRequiringPush // allow null results here so the list index matches configsRequiringPush
val sentTimestamp: Long = SnodeAPI.nowWithOffset val sentTimestamp: Long = SnodeAPI.nowWithOffset
val batchObjects: List<Pair<SharedConfigurationMessage, SnodeAPI.SnodeBatchRequestInfo>?> = configsRequiringPush.map { config -> val batchObjects: List<Pair<SharedConfigurationMessage, SnodeBatchRequestInfo>?> = configsRequiringPush.map { config ->
val (data, seqNo, obsoleteHashes) = config.push() val (data, seqNo, obsoleteHashes) = config.push()
toDeleteHashes += obsoleteHashes toDeleteHashes += obsoleteHashes
SharedConfigurationMessage(config.protoKindFor(), data, seqNo) to config SharedConfigurationMessage(config.protoKindFor(), data, seqNo) to config
@@ -85,7 +79,7 @@ data class ConfigurationSyncJob(val destination: Destination): Job {
return delegate.handleJobFailedPermanently(this, dispatcherName, NullPointerException("One or more requests had a null batch request info")) return delegate.handleJobFailedPermanently(this, dispatcherName, NullPointerException("One or more requests had a null batch request info"))
} }
val allRequests = mutableListOf<SnodeAPI.SnodeBatchRequestInfo>() val allRequests = mutableListOf<SnodeBatchRequestInfo>()
allRequests += batchObjects.requireNoNulls().map { (_, request) -> request } allRequests += batchObjects.requireNoNulls().map { (_, request) -> request }
// add in the deletion if we have any hashes // add in the deletion if we have any hashes
if (toDeleteRequest != null) { if (toDeleteRequest != null) {
@@ -154,6 +148,14 @@ data class ConfigurationSyncJob(val destination: Destination): Job {
} }
} }
private fun getUserSyncInformation(delegate: JobDelegate) {
val userEdKeyPair = MessagingModuleConfiguration.shared.getUserED25519KeyPair()
}
private fun syncGroupConfigs(delegate: JobDelegate) {
}
fun Destination.destinationPublicKey(): String = when (this) { fun Destination.destinationPublicKey(): String = when (this) {
is Destination.Contact -> publicKey is Destination.Contact -> publicKey
is Destination.ClosedGroup -> publicKey is Destination.ClosedGroup -> publicKey

View File

@@ -1,7 +1,14 @@
package org.session.libsignal.utilities package org.session.libsignal.utilities
object Namespace { object Namespace {
const val ALL = "all" fun ALL() = "all"
const val DEFAULT = 0 fun UNAUTHENTICATED_CLOSED_GROUP() = -10
const val UNAUTHENTICATED_CLOSED_GROUP = -10 external fun DEFAULT(): Int
external fun USER_PROFILE(): Int
external fun CONTACTS(): Int
external fun CONVO_INFO_VOLATILE(): Int
external fun GROUPS(): Int
external fun CLOSED_GROUP_INFO(): Int
external fun CLOSED_GROUP_MEMBERS(): Int
external fun ENCRYPTION_KEYS(): Int
} }