Merge pull request #431 from Brice-W/exp-timer-config-message

Add Closed Group Expiration Timer Setting to Configuration Message
This commit is contained in:
Niels Andriesse 2021-07-07 15:07:40 +10:00 committed by GitHub
commit 4a0a66533d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 42 additions and 13 deletions

View File

@ -250,14 +250,6 @@ public final class ClosedGroupControlMessage : ControlMessage {
dataMessageProto.setClosedGroupControlMessage(try closedGroupControlMessage.build())
// Group context
try setGroupContextIfNeeded(on: dataMessageProto, using: transaction)
// Expiration timer
// TODO: We * want * expiration timer updates to be explicit. But currently Android will disable the expiration timer for a conversation
// if it receives a message without the current expiration timer value attached to it...
var expiration: UInt32 = 0
if let disappearingMessagesConfiguration = OWSDisappearingMessagesConfiguration.fetch(uniqueId: threadID!, transaction: transaction) {
expiration = disappearingMessagesConfiguration.isEnabled ? disappearingMessagesConfiguration.durationSeconds : 0
}
dataMessageProto.setExpireTimer(expiration)
contentProto.setDataMessage(try dataMessageProto.build())
return try contentProto.build()
} catch {

View File

@ -101,15 +101,17 @@ extension ConfigurationMessage {
public let encryptionKeyPair: ECKeyPair
public let members: Set<String>
public let admins: Set<String>
public let expirationTimer: UInt32
public var isValid: Bool { !members.isEmpty && !admins.isEmpty }
public init(publicKey: String, name: String, encryptionKeyPair: ECKeyPair, members: Set<String>, admins: Set<String>) {
public init(publicKey: String, name: String, encryptionKeyPair: ECKeyPair, members: Set<String>, admins: Set<String>, expirationTimer: UInt32) {
self.publicKey = publicKey
self.name = name
self.encryptionKeyPair = encryptionKeyPair
self.members = members
self.admins = admins
self.expirationTimer = expirationTimer
}
public required init?(coder: NSCoder) {
@ -118,11 +120,13 @@ extension ConfigurationMessage {
let encryptionKeyPair = coder.decodeObject(forKey: "encryptionKeyPair") as! ECKeyPair?,
let members = coder.decodeObject(forKey: "members") as! Set<String>?,
let admins = coder.decodeObject(forKey: "admins") as! Set<String>? else { return nil }
let expirationTimer = coder.decodeObject(forKey: "expirationTimer") as? UInt32 ?? 0
self.publicKey = publicKey
self.name = name
self.encryptionKeyPair = encryptionKeyPair
self.members = members
self.admins = admins
self.expirationTimer = expirationTimer
}
public func encode(with coder: NSCoder) {
@ -131,6 +135,7 @@ extension ConfigurationMessage {
coder.encode(encryptionKeyPair, forKey: "encryptionKeyPair")
coder.encode(members, forKey: "members")
coder.encode(admins, forKey: "admins")
coder.encode(expirationTimer, forKey: "expirationTimer")
}
public static func fromProto(_ proto: SNProtoConfigurationMessageClosedGroup) -> ClosedGroup? {
@ -146,7 +151,8 @@ extension ConfigurationMessage {
}
let members = Set(proto.members.map { $0.toHexString() })
let admins = Set(proto.admins.map { $0.toHexString() })
let result = ClosedGroup(publicKey: publicKey, name: name, encryptionKeyPair: encryptionKeyPair, members: members, admins: admins)
let expirationTimer = proto.expirationTimer
let result = ClosedGroup(publicKey: publicKey, name: name, encryptionKeyPair: encryptionKeyPair, members: members, admins: admins, expirationTimer: expirationTimer)
guard result.isValid else { return nil }
return result
}
@ -165,6 +171,7 @@ extension ConfigurationMessage {
}
result.setMembers(members.map { Data(hex: $0) })
result.setAdmins(admins.map { Data(hex: $0) })
result.setExpirationTimer(expirationTimer)
do {
return try result.build()
} catch {

View File

@ -2100,6 +2100,9 @@ extension SNProtoDataMessage.SNProtoDataMessageBuilder {
}
builder.setMembers(members)
builder.setAdmins(admins)
if hasExpirationTimer {
builder.setExpirationTimer(expirationTimer)
}
return builder
}
@ -2141,6 +2144,10 @@ extension SNProtoDataMessage.SNProtoDataMessageBuilder {
proto.admins = wrappedItems
}
@objc public func setExpirationTimer(_ valueParam: UInt32) {
proto.expirationTimer = valueParam
}
@objc public func build() throws -> SNProtoConfigurationMessageClosedGroup {
return try SNProtoConfigurationMessageClosedGroup.parseProto(proto)
}
@ -2182,6 +2189,13 @@ extension SNProtoDataMessage.SNProtoDataMessageBuilder {
return proto.admins
}
@objc public var expirationTimer: UInt32 {
return proto.expirationTimer
}
@objc public var hasExpirationTimer: Bool {
return proto.hasExpirationTimer
}
private init(proto: SessionProtos_ConfigurationMessage.ClosedGroup,
encryptionKeyPair: SNProtoKeyPair?) {
self.proto = proto

View File

@ -971,6 +971,15 @@ struct SessionProtos_ConfigurationMessage {
var admins: [Data] = []
var expirationTimer: UInt32 {
get {return _expirationTimer ?? 0}
set {_expirationTimer = newValue}
}
/// Returns true if `expirationTimer` has been explicitly set.
var hasExpirationTimer: Bool {return self._expirationTimer != nil}
/// Clears the value of `expirationTimer`. Subsequent reads from it will return its default value.
mutating func clearExpirationTimer() {self._expirationTimer = nil}
var unknownFields = SwiftProtobuf.UnknownStorage()
init() {}
@ -978,6 +987,7 @@ struct SessionProtos_ConfigurationMessage {
fileprivate var _publicKey: Data? = nil
fileprivate var _name: String? = nil
fileprivate var _encryptionKeyPair: SessionProtos_KeyPair? = nil
fileprivate var _expirationTimer: UInt32? = nil
}
struct Contact {
@ -2294,6 +2304,7 @@ extension SessionProtos_ConfigurationMessage.ClosedGroup: SwiftProtobuf.Message,
3: .same(proto: "encryptionKeyPair"),
4: .same(proto: "members"),
5: .same(proto: "admins"),
6: .same(proto: "expirationTimer"),
]
public var isInitialized: Bool {
@ -2312,6 +2323,7 @@ extension SessionProtos_ConfigurationMessage.ClosedGroup: SwiftProtobuf.Message,
case 3: try { try decoder.decodeSingularMessageField(value: &self._encryptionKeyPair) }()
case 4: try { try decoder.decodeRepeatedBytesField(value: &self.members) }()
case 5: try { try decoder.decodeRepeatedBytesField(value: &self.admins) }()
case 6: try { try decoder.decodeSingularUInt32Field(value: &self._expirationTimer) }()
default: break
}
}
@ -2333,6 +2345,9 @@ extension SessionProtos_ConfigurationMessage.ClosedGroup: SwiftProtobuf.Message,
if !self.admins.isEmpty {
try visitor.visitRepeatedBytesField(value: self.admins, fieldNumber: 5)
}
if let v = self._expirationTimer {
try visitor.visitSingularUInt32Field(value: v, fieldNumber: 6)
}
try unknownFields.traverse(visitor: &visitor)
}
@ -2342,6 +2357,7 @@ extension SessionProtos_ConfigurationMessage.ClosedGroup: SwiftProtobuf.Message,
if lhs._encryptionKeyPair != rhs._encryptionKeyPair {return false}
if lhs.members != rhs.members {return false}
if lhs.admins != rhs.admins {return false}
if lhs._expirationTimer != rhs._expirationTimer {return false}
if lhs.unknownFields != rhs.unknownFields {return false}
return true
}

View File

@ -161,6 +161,7 @@ message ConfigurationMessage {
optional KeyPair encryptionKeyPair = 3;
repeated bytes members = 4;
repeated bytes admins = 5;
optional uint32 expirationTimer = 6;
}
message Contact {

View File

@ -207,8 +207,7 @@ extension MessageReceiver {
let allClosedGroupPublicKeys = storage.getUserClosedGroupPublicKeys()
for closedGroup in message.closedGroups {
guard !allClosedGroupPublicKeys.contains(closedGroup.publicKey) else { continue }
handleNewClosedGroup(groupPublicKey: closedGroup.publicKey, name: closedGroup.name, encryptionKeyPair: closedGroup.encryptionKeyPair,
members: [String](closedGroup.members), admins: [String](closedGroup.admins), expirationTimer: 0, messageSentTimestamp: message.sentTimestamp!, using: transaction)
handleNewClosedGroup(groupPublicKey: closedGroup.publicKey, name: closedGroup.name, encryptionKeyPair: closedGroup.encryptionKeyPair, members: [String](closedGroup.members), admins: [String](closedGroup.admins), expirationTimer: closedGroup.expirationTimer, messageSentTimestamp: message.sentTimestamp!, using: transaction)
}
// Open groups
for openGroupURL in message.openGroups {

View File

@ -22,7 +22,7 @@ extension ConfigurationMessage {
guard storage.isClosedGroup(groupPublicKey),
let encryptionKeyPair = storage.getLatestClosedGroupEncryptionKeyPair(for: groupPublicKey) else { return }
let closedGroup = ClosedGroup(publicKey: groupPublicKey, name: thread.groupModel.groupName!, encryptionKeyPair: encryptionKeyPair,
members: Set(thread.groupModel.groupMemberIds), admins: Set(thread.groupModel.groupAdminIds))
members: Set(thread.groupModel.groupMemberIds), admins: Set(thread.groupModel.groupAdminIds), expirationTimer: thread.disappearingMessagesDuration(with: transaction))
closedGroups.insert(closedGroup)
case .openGroup:
if let v2OpenGroup = storage.getV2OpenGroup(for: thread.uniqueId!) {