Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add profile data to message request responses #994

Merged
merged 5 commits into from
Jan 24, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
42 changes: 32 additions & 10 deletions app/src/main/java/org/thoughtcrime/securesms/database/Storage.kt
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package org.thoughtcrime.securesms.database

import android.content.Context
import android.net.Uri
import org.session.libsession.avatars.AvatarHelper
import org.session.libsession.database.StorageProtocol
import org.session.libsession.messaging.BlindedIdMapping
import org.session.libsession.messaging.calls.CallMessageType
Expand All @@ -12,6 +13,7 @@ import org.session.libsession.messaging.messages.control.ConfigurationMessage
import org.session.libsession.messaging.messages.control.MessageRequestResponse
import org.session.libsession.messaging.messages.signal.*
import org.session.libsession.messaging.messages.visible.Attachment
import org.session.libsession.messaging.messages.visible.Profile
import org.session.libsession.messaging.messages.visible.Reaction
import org.session.libsession.messaging.messages.visible.VisibleMessage
import org.session.libsession.messaging.open_groups.GroupMember
Expand All @@ -28,6 +30,11 @@ import org.session.libsession.messaging.utilities.UpdateMessageData
import org.session.libsession.snode.OnionRequestAPI
import org.session.libsession.utilities.*
import org.session.libsession.utilities.Address.Companion.fromSerialized
import org.session.libsession.utilities.GroupRecord
import org.session.libsession.utilities.GroupUtil
import org.session.libsession.utilities.ProfileKeyUtil
import org.session.libsession.utilities.SSKEnvironment
import org.session.libsession.utilities.TextSecurePreferences
import org.session.libsession.utilities.recipients.Recipient
import org.session.libsignal.crypto.ecc.ECKeyPair
import org.session.libsignal.messages.SignalServiceAttachmentPointer
Expand All @@ -44,6 +51,7 @@ import org.thoughtcrime.securesms.groups.OpenGroupManager
import org.thoughtcrime.securesms.jobs.RetrieveProfileAvatarJob
import org.thoughtcrime.securesms.mms.PartAuthority
import org.thoughtcrime.securesms.util.SessionMetaProtocol
import java.security.MessageDigest

class Storage(context: Context, helper: SQLCipherOpenHelper) : Database(context, helper), StorageProtocol {

Expand All @@ -55,16 +63,11 @@ class Storage(context: Context, helper: SQLCipherOpenHelper) : Database(context,
return DatabaseComponent.get(context).lokiAPIDatabase().getUserX25519KeyPair()
}

override fun getUserDisplayName(): String? {
return TextSecurePreferences.getProfileName(context)
}

override fun getUserProfileKey(): ByteArray? {
return ProfileKeyUtil.getProfileKey(context)
}

override fun getUserProfilePictureURL(): String? {
return TextSecurePreferences.getProfilePictureURL(context)
override fun getUserProfile(): Profile {
val displayName = TextSecurePreferences.getProfileName(context)!!
val profileKey = ProfileKeyUtil.getProfileKey(context)
val profilePictureUrl = TextSecurePreferences.getProfilePictureURL(context)
return Profile(displayName, profileKey, profilePictureUrl)
}

override fun setUserProfilePictureURL(newValue: String) {
Expand Down Expand Up @@ -754,6 +757,25 @@ class Storage(context: Context, helper: SQLCipherOpenHelper) : Database(context,
val smsDb = DatabaseComponent.get(context).smsDatabase()
val sender = Recipient.from(context, fromSerialized(senderPublicKey), false)
val threadId = threadDB.getOrCreateThreadIdFor(sender)
val profile = response.profile
if (profile != null) {
val profileManager = SSKEnvironment.shared.profileManager
val name = profile.displayName!!
if (name.isNotEmpty()) {
profileManager.setName(context, sender, name)
}
val newProfileKey = profile.profileKey

val needsProfilePicture = !AvatarHelper.avatarFileExists(context, sender.address)
val profileKeyValid = newProfileKey?.isNotEmpty() == true && (newProfileKey.size == 16 || newProfileKey.size == 32) && profile.profilePictureURL?.isNotEmpty() == true
val profileKeyChanged = (sender.profileKey == null || !MessageDigest.isEqual(sender.profileKey, newProfileKey))

if ((profileKeyValid && profileKeyChanged) || (profileKeyValid && needsProfilePicture)) {
profileManager.setProfileKey(context, sender, newProfileKey!!)
profileManager.setUnidentifiedAccessMode(context, sender, Recipient.UnidentifiedAccessMode.UNKNOWN)
profileManager.setProfilePictureURL(context, sender, profile.profilePictureURL!!)
}
}
threadDB.setHasSent(threadId, true)
val mappingDb = DatabaseComponent.get(context).blindedIdMappingDatabase()
val mappings = mutableMapOf<String, BlindedIdMapping>()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import org.session.libsession.messaging.messages.Message
import org.session.libsession.messaging.messages.control.ConfigurationMessage
import org.session.libsession.messaging.messages.control.MessageRequestResponse
import org.session.libsession.messaging.messages.visible.Attachment
import org.session.libsession.messaging.messages.visible.Profile
import org.session.libsession.messaging.messages.visible.Reaction
import org.session.libsession.messaging.messages.visible.VisibleMessage
import org.session.libsession.messaging.open_groups.GroupMember
Expand All @@ -35,9 +36,7 @@ interface StorageProtocol {
// General
fun getUserPublicKey(): String?
fun getUserX25519KeyPair(): ECKeyPair
fun getUserDisplayName(): String?
fun getUserProfileKey(): ByteArray?
fun getUserProfilePictureURL(): String?
fun getUserProfile(): Profile
fun setUserProfilePictureURL(newProfilePicture: String)
// Signal
fun getOrGenerateRegistrationID(): Int
Expand Down
Original file line number Diff line number Diff line change
@@ -1,15 +1,22 @@
package org.session.libsession.messaging.messages.control

import com.google.protobuf.ByteString
import org.session.libsession.messaging.messages.visible.Profile
import org.session.libsignal.protos.SignalServiceProtos
import org.session.libsignal.utilities.Log

class MessageRequestResponse(val isApproved: Boolean) : ControlMessage() {
class MessageRequestResponse(val isApproved: Boolean, var profile: Profile? = null) : ControlMessage() {

override val isSelfSendValid: Boolean = true

override fun toProto(): SignalServiceProtos.Content? {
val profileProto = SignalServiceProtos.DataMessage.LokiProfile.newBuilder()
profile?.displayName?.let { profileProto.displayName = it }
profile?.profilePictureURL?.let { profileProto.profilePicture = it }
val messageRequestResponseProto = SignalServiceProtos.MessageRequestResponse.newBuilder()
.setIsApproved(isApproved)
.setProfile(profileProto.build())
profile?.profileKey?.let { messageRequestResponseProto.profileKey = ByteString.copyFrom(it) }
return try {
SignalServiceProtos.Content.newBuilder()
.setMessageRequestResponse(messageRequestResponseProto.build())
Expand All @@ -26,7 +33,13 @@ class MessageRequestResponse(val isApproved: Boolean) : ControlMessage() {
fun fromProto(proto: SignalServiceProtos.Content): MessageRequestResponse? {
val messageRequestResponseProto = if (proto.hasMessageRequestResponse()) proto.messageRequestResponse else return null
val isApproved = messageRequestResponseProto.isApproved
return MessageRequestResponse(isApproved)
val profileProto = messageRequestResponseProto.profile
val profile = Profile().apply {
displayName = profileProto.displayName
profileKey = if (messageRequestResponseProto.hasProfileKey()) messageRequestResponseProto.profileKey.toByteArray() else null
profilePictureURL = profileProto.profilePicture
}
return MessageRequestResponse(isApproved, profile)
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ class Profile() {
}
}

internal constructor(displayName: String, profileKey: ByteArray? = null, profilePictureURL: String? = null) : this() {
constructor(displayName: String, profileKey: ByteArray? = null, profilePictureURL: String? = null) : this() {
this.displayName = displayName
this.profileKey = profileKey
this.profilePictureURL = profilePictureURL
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,13 @@ import org.session.libsession.messaging.jobs.MessageSendJob
import org.session.libsession.messaging.jobs.NotifyPNServerJob
import org.session.libsession.messaging.messages.Destination
import org.session.libsession.messaging.messages.Message
import org.session.libsession.messaging.messages.control.*
import org.session.libsession.messaging.messages.control.CallMessage
import org.session.libsession.messaging.messages.control.ClosedGroupControlMessage
import org.session.libsession.messaging.messages.control.ConfigurationMessage
import org.session.libsession.messaging.messages.control.ExpirationTimerUpdate
import org.session.libsession.messaging.messages.control.MessageRequestResponse
import org.session.libsession.messaging.messages.control.UnsendRequest
import org.session.libsession.messaging.messages.visible.LinkPreview
import org.session.libsession.messaging.messages.visible.Profile
import org.session.libsession.messaging.messages.visible.Quote
import org.session.libsession.messaging.messages.visible.VisibleMessage
import org.session.libsession.messaging.open_groups.OpenGroupApi
Expand Down Expand Up @@ -109,14 +113,10 @@ object MessageSender {
}
// Attach the user's profile if needed
if (message is VisibleMessage) {
val displayName = storage.getUserDisplayName()!!
val profileKey = storage.getUserProfileKey()
val profilePictureUrl = storage.getUserProfilePictureURL()
if (profileKey != null && profilePictureUrl != null) {
message.profile = Profile(displayName, profileKey, profilePictureUrl)
} else {
message.profile = Profile(displayName)
}
message.profile = storage.getUserProfile()
}
if (message is MessageRequestResponse) {
message.profile = storage.getUserProfile()
}
// Convert it to protobuf
val proto = message.toProto() ?: throw Error.ProtoConversionFailed
Expand Down Expand Up @@ -248,14 +248,7 @@ object MessageSender {
try {
// Attach the user's profile if needed
if (message is VisibleMessage) {
val displayName = storage.getUserDisplayName()!!
val profileKey = storage.getUserProfileKey()
val profilePictureUrl = storage.getUserProfilePictureURL()
if (profileKey != null && profilePictureUrl != null) {
message.profile = Profile(displayName, profileKey, profilePictureUrl)
} else {
message.profile = Profile(displayName)
}
message.profile = storage.getUserProfile()
}
when (destination) {
is Destination.OpenGroup -> {
Expand Down
4 changes: 3 additions & 1 deletion libsignal/protobuf/SignalService.proto
Original file line number Diff line number Diff line change
Expand Up @@ -233,7 +233,9 @@ message ConfigurationMessage {

message MessageRequestResponse {
// @required
required bool isApproved = 1; // Whether the request was approved
required bool isApproved = 1;
optional bytes profileKey = 2;
optional DataMessage.LokiProfile profile = 3;
}

message ReceiptMessage {
Expand Down
Loading