Set group context

Android needs this
This commit is contained in:
nielsandriesse 2020-12-08 13:17:02 +11:00
parent 5e3e755c47
commit f504965dfa
9 changed files with 33 additions and 20 deletions

View File

@ -126,7 +126,7 @@ public final class ClosedGroupUpdate : ControlMessage {
return ClosedGroupUpdate(kind: kind) return ClosedGroupUpdate(kind: kind)
} }
public override func toProto() -> SNProtoContent? { public override func toProto(using transaction: YapDatabaseReadWriteTransaction) -> SNProtoContent? {
guard let kind = kind else { guard let kind = kind else {
SNLog("Couldn't construct closed group update proto from: \(self).") SNLog("Couldn't construct closed group update proto from: \(self).")
return nil return nil
@ -156,6 +156,8 @@ public final class ClosedGroupUpdate : ControlMessage {
let contentProto = SNProtoContent.builder() let contentProto = SNProtoContent.builder()
let dataMessageProto = SNProtoDataMessage.builder() let dataMessageProto = SNProtoDataMessage.builder()
dataMessageProto.setClosedGroupUpdate(try closedGroupUpdate.build()) dataMessageProto.setClosedGroupUpdate(try closedGroupUpdate.build())
// Group context
try setGroupContextIfNeeded(on: dataMessageProto, using: transaction)
contentProto.setDataMessage(try dataMessageProto.build()) contentProto.setDataMessage(try dataMessageProto.build())
return try contentProto.build() return try contentProto.build()
} catch { } catch {

View File

@ -38,7 +38,7 @@ public final class ExpirationTimerUpdate : ControlMessage {
return ExpirationTimerUpdate(duration: duration) return ExpirationTimerUpdate(duration: duration)
} }
public override func toProto() -> SNProtoContent? { public override func toProto(using transaction: YapDatabaseReadWriteTransaction) -> SNProtoContent? {
guard let duration = duration else { guard let duration = duration else {
SNLog("Couldn't construct expiration timer update proto from: \(self).") SNLog("Couldn't construct expiration timer update proto from: \(self).")
return nil return nil
@ -46,6 +46,13 @@ public final class ExpirationTimerUpdate : ControlMessage {
let dataMessageProto = SNProtoDataMessage.builder() let dataMessageProto = SNProtoDataMessage.builder()
dataMessageProto.setFlags(UInt32(SNProtoDataMessage.SNProtoDataMessageFlags.expirationTimerUpdate.rawValue)) dataMessageProto.setFlags(UInt32(SNProtoDataMessage.SNProtoDataMessageFlags.expirationTimerUpdate.rawValue))
dataMessageProto.setExpireTimer(duration) dataMessageProto.setExpireTimer(duration)
// Group context
do {
try setGroupContextIfNeeded(on: dataMessageProto, using: transaction)
} catch {
SNLog("Couldn't construct expiration timer update proto from: \(self).")
return nil
}
let contentProto = SNProtoContent.builder() let contentProto = SNProtoContent.builder()
do { do {
contentProto.setDataMessage(try dataMessageProto.build()) contentProto.setDataMessage(try dataMessageProto.build())

View File

@ -38,7 +38,7 @@ public final class ReadReceipt : ControlMessage {
return ReadReceipt(timestamps: timestamps) return ReadReceipt(timestamps: timestamps)
} }
public override func toProto() -> SNProtoContent? { public override func toProto(using transaction: YapDatabaseReadWriteTransaction) -> SNProtoContent? {
guard let timestamps = timestamps else { guard let timestamps = timestamps else {
SNLog("Couldn't construct read receipt proto from: \(self).") SNLog("Couldn't construct read receipt proto from: \(self).")
return nil return nil

View File

@ -64,7 +64,7 @@ public final class TypingIndicator : ControlMessage {
return TypingIndicator(kind: kind) return TypingIndicator(kind: kind)
} }
public override func toProto() -> SNProtoContent? { public override func toProto(using transaction: YapDatabaseReadWriteTransaction) -> SNProtoContent? {
guard let timestamp = sentTimestamp, let kind = kind else { guard let timestamp = sentTimestamp, let kind = kind else {
SNLog("Couldn't construct typing indicator proto from: \(self).") SNLog("Couldn't construct typing indicator proto from: \(self).")
return nil return nil

View File

@ -22,7 +22,7 @@ public final class NullMessage : ControlMessage {
return NullMessage() return NullMessage()
} }
public override func toProto() -> SNProtoContent? { public override func toProto(using transaction: YapDatabaseReadWriteTransaction) -> SNProtoContent? {
let nullMessageProto = SNProtoNullMessage.builder() let nullMessageProto = SNProtoNullMessage.builder()
let paddingSize = UInt.random(in: 0..<512) // random(in:) uses the system's default random generator, which is cryptographically secure let paddingSize = UInt.random(in: 0..<512) // random(in:) uses the system's default random generator, which is cryptographically secure
let padding = Data.getSecureRandomData(ofSize: paddingSize)! let padding = Data.getSecureRandomData(ofSize: paddingSize)!

View File

@ -50,7 +50,7 @@ public final class SessionRequest : ControlMessage {
return SessionRequest(preKeyBundle: preKeyBundle) return SessionRequest(preKeyBundle: preKeyBundle)
} }
public override func toProto() -> SNProtoContent? { public override func toProto(using transaction: YapDatabaseReadWriteTransaction) -> SNProtoContent? {
guard let preKeyBundle = preKeyBundle else { guard let preKeyBundle = preKeyBundle else {
SNLog("Couldn't construct session request proto from: \(self).") SNLog("Couldn't construct session request proto from: \(self).")
return nil return nil

View File

@ -44,8 +44,15 @@ public class Message : NSObject, NSCoding { // NSObject/NSCoding conformance is
preconditionFailure("fromProto(_:) is abstract and must be overridden.") preconditionFailure("fromProto(_:) is abstract and must be overridden.")
} }
public func toProto() -> SNProtoContent? { public func toProto(using transaction: YapDatabaseReadWriteTransaction) -> SNProtoContent? {
preconditionFailure("toProto() is abstract and must be overridden.") preconditionFailure("toProto(using:) is abstract and must be overridden.")
}
public func setGroupContextIfNeeded(on dataMessage: SNProtoDataMessage.SNProtoDataMessageBuilder, using transaction: YapDatabaseReadTransaction) throws {
guard let thread = TSThread.fetch(uniqueId: threadID!, transaction: transaction) as? TSGroupThread, thread.usesSharedSenderKeys else { return }
// Android needs a group context or it'll interpret the message as a one-to-one message
let groupProto = SNProtoGroupContext.builder(id: thread.groupModel.groupId, type: .deliver)
dataMessage.setGroup(try groupProto.build())
} }
// MARK: General // MARK: General

View File

@ -54,11 +54,7 @@ public final class VisibleMessage : Message {
return result return result
} }
public override func toProto() -> SNProtoContent? { public override func toProto(using transaction: YapDatabaseReadWriteTransaction) -> SNProtoContent? {
preconditionFailure("Use toProto(using:) instead.")
}
public func toProto(using transaction: YapDatabaseReadWriteTransaction) -> SNProtoContent? {
let proto = SNProtoContent.builder() let proto = SNProtoContent.builder()
var attachmentIDs = self.attachmentIDs var attachmentIDs = self.attachmentIDs
let dataMessage: SNProtoDataMessage.SNProtoDataMessageBuilder let dataMessage: SNProtoDataMessage.SNProtoDataMessageBuilder
@ -90,6 +86,13 @@ public final class VisibleMessage : Message {
let attachmentProtos = attachments.compactMap { $0.buildProto() } let attachmentProtos = attachments.compactMap { $0.buildProto() }
dataMessage.setAttachments(attachmentProtos) dataMessage.setAttachments(attachmentProtos)
// TODO: Contact // TODO: Contact
// Group context
do {
try setGroupContextIfNeeded(on: dataMessage, using: transaction)
} catch {
SNLog("Couldn't construct visible message proto from: \(self).")
return nil
}
// Build // Build
do { do {
proto.setDataMessage(try dataMessage.build()) proto.setDataMessage(try dataMessage.build())

View File

@ -149,13 +149,7 @@ public final class MessageSender : NSObject {
} }
} }
// Convert it to protobuf // Convert it to protobuf
let protoOrNil: SNProtoContent? guard let proto = message.toProto(using: transaction) else { handleFailure(with: Error.protoConversionFailed, using: transaction); return promise }
if let message = message as? VisibleMessage {
protoOrNil = message.toProto(using: transaction) // Needed because of how TSAttachmentStream works
} else {
protoOrNil = message.toProto()
}
guard let proto = protoOrNil else { handleFailure(with: Error.protoConversionFailed, using: transaction); return promise }
// Serialize the protobuf // Serialize the protobuf
let plaintext: Data let plaintext: Data
do { do {