Update configuration message for contacts

This commit is contained in:
nielsandriesse 2021-02-24 13:49:16 +11:00
parent 268971af9a
commit f488453140
5 changed files with 126 additions and 35 deletions

View file

@ -7,6 +7,7 @@ public final class ConfigurationMessage : ControlMessage {
public var displayName: String?
public var profilePictureURL: String?
public var profileKey: Data?
public var contacts: Set<Contact> = []
public override var ttl: UInt64 { 4 * 24 * 60 * 60 * 1000 }
@ -15,13 +16,14 @@ public final class ConfigurationMessage : ControlMessage {
// MARK: Initialization
public override init() { super.init() }
public init(displayName: String?, profilePictureURL: String?, profileKey: Data?, closedGroups: Set<ClosedGroup>, openGroups: Set<String>) {
public init(displayName: String?, profilePictureURL: String?, profileKey: Data?, closedGroups: Set<ClosedGroup>, openGroups: Set<String>, contacts: Set<Contact>) {
super.init()
self.displayName = displayName
self.profilePictureURL = profilePictureURL
self.profileKey = profileKey
self.closedGroups = closedGroups
self.openGroups = openGroups
self.contacts = contacts
}
// MARK: Coding
@ -32,6 +34,7 @@ public final class ConfigurationMessage : ControlMessage {
if let displayName = coder.decodeObject(forKey: "displayName") as! String? { self.displayName = displayName }
if let profilePictureURL = coder.decodeObject(forKey: "profilePictureURL") as! String? { self.profilePictureURL = profilePictureURL }
if let profileKey = coder.decodeObject(forKey: "profileKey") as! Data? { self.profileKey = profileKey }
if let contacts = coder.decodeObject(forKey: "contacts") as! Set<Contact>? { self.contacts = contacts }
}
public override func encode(with coder: NSCoder) {
@ -41,6 +44,7 @@ public final class ConfigurationMessage : ControlMessage {
coder.encode(displayName, forKey: "displayName")
coder.encode(profilePictureURL, forKey: "profilePictureURL")
coder.encode(profileKey, forKey: "profileKey")
coder.encode(contacts, forKey: "contacts")
}
// MARK: Proto Conversion
@ -51,7 +55,9 @@ public final class ConfigurationMessage : ControlMessage {
let profileKey = configurationProto.profileKey
let closedGroups = Set(configurationProto.closedGroups.compactMap { ClosedGroup.fromProto($0) })
let openGroups = Set(configurationProto.openGroups)
return ConfigurationMessage(displayName: displayName, profilePictureURL: profilePictureURL, profileKey: profileKey, closedGroups: closedGroups, openGroups: openGroups)
let contacts = Set(configurationProto.contacts.compactMap { Contact.fromProto($0) })
return ConfigurationMessage(displayName: displayName, profilePictureURL: profilePictureURL, profileKey: profileKey,
closedGroups: closedGroups, openGroups: openGroups, contacts: contacts)
}
public override func toProto(using transaction: YapDatabaseReadWriteTransaction) -> SNProtoContent? {
@ -61,6 +67,7 @@ public final class ConfigurationMessage : ControlMessage {
if let profileKey = profileKey { configurationProto.setProfileKey(profileKey) }
configurationProto.setClosedGroups(closedGroups.compactMap { $0.toProto() })
configurationProto.setOpenGroups([String](openGroups))
configurationProto.setContacts(contacts.compactMap { $0.toProto() })
let contentProto = SNProtoContent.builder()
do {
contentProto.setConfigurationMessage(try configurationProto.build())
@ -77,6 +84,10 @@ public final class ConfigurationMessage : ControlMessage {
ConfigurationMessage(
closedGroups: \([ClosedGroup](closedGroups).prettifiedDescription)
openGroups: \([String](openGroups).prettifiedDescription)
displayName: \(displayName ?? "null")
profilePictureURL: \(profilePictureURL ?? "null")
profileKey: \(profileKey?.toHexString() ?? "null")
contacts: \([Contact](contacts).prettifiedDescription)
)
"""
}
@ -137,10 +148,13 @@ extension ConfigurationMessage {
}
let members = Set(proto.members.map { $0.toHexString() })
let admins = Set(proto.admins.map { $0.toHexString() })
return ClosedGroup(publicKey: publicKey, name: name, encryptionKeyPair: encryptionKeyPair, members: members, admins: admins)
let result = ClosedGroup(publicKey: publicKey, name: name, encryptionKeyPair: encryptionKeyPair, members: members, admins: admins)
guard result.isValid else { return nil }
return result
}
public func toProto() -> SNProtoConfigurationMessageClosedGroup? {
guard isValid else { return nil }
let result = SNProtoConfigurationMessageClosedGroup.builder()
result.setPublicKey(Data(hex: publicKey))
result.setName(name)
@ -164,3 +178,66 @@ extension ConfigurationMessage {
public override var description: String { name }
}
}
// MARK: Contact
extension ConfigurationMessage {
@objc(SNConfigurationMessageContact)
public final class Contact : NSObject, NSCoding { // NSObject/NSCoding conformance is needed for YapDatabase compatibility
public var publicKey: String?
public var displayName: String?
public var profilePictureURL: String?
public var profileKey: Data?
public var isValid: Bool { publicKey != nil && displayName != nil }
public init(publicKey: String, displayName: String, profilePictureURL: String?, profileKey: Data?) {
self.publicKey = publicKey
self.displayName = displayName
self.profilePictureURL = profilePictureURL
self.profileKey = profileKey
}
public required init?(coder: NSCoder) {
guard let publicKey = coder.decodeObject(forKey: "publicKey") as! String?,
let displayName = coder.decodeObject(forKey: "displayName") as! String? else { return nil }
self.publicKey = publicKey
self.displayName = displayName
self.profilePictureURL = coder.decodeObject(forKey: "profilePictureURL") as! String?
self.profileKey = coder.decodeObject(forKey: "profileKey") as! Data?
}
public func encode(with coder: NSCoder) {
coder.encode(publicKey, forKey: "publicKey")
coder.encode(displayName, forKey: "displayName")
coder.encode(profilePictureURL, forKey: "profilePictureURL")
coder.encode(profileKey, forKey: "profileKey")
}
public static func fromProto(_ proto: SNProtoConfigurationMessageContact) -> Contact? {
let publicKey = proto.publicKey.toHexString()
let displayName = proto.name
let profilePictureURL = proto.profilePicture
let profileKey = proto.profileKey
let result = Contact(publicKey: publicKey, displayName: displayName, profilePictureURL: profilePictureURL, profileKey: profileKey)
guard result.isValid else { return nil }
return result
}
public func toProto() -> SNProtoConfigurationMessageContact? {
guard isValid else { return nil }
guard let publicKey = publicKey, let displayName = displayName else { return nil }
let result = SNProtoConfigurationMessageContact.builder(publicKey: Data(hex: publicKey), name: displayName)
if let profilePictureURL = profilePictureURL { result.setProfilePicture(profilePictureURL) }
if let profileKey = profileKey { result.setProfileKey(profileKey) }
do {
return try result.build()
} catch {
SNLog("Couldn't construct contact proto from: \(self).")
return nil
}
}
public override var description: String { displayName! }
}
}

View file

@ -3109,19 +3109,13 @@ extension SNProtoConfigurationMessageClosedGroup.SNProtoConfigurationMessageClos
// MARK: - SNProtoConfigurationMessageContactBuilder
@objc public class func builder() -> SNProtoConfigurationMessageContactBuilder {
return SNProtoConfigurationMessageContactBuilder()
@objc public class func builder(publicKey: Data, name: String) -> SNProtoConfigurationMessageContactBuilder {
return SNProtoConfigurationMessageContactBuilder(publicKey: publicKey, name: name)
}
// asBuilder() constructs a builder that reflects the proto's contents.
@objc public func asBuilder() -> SNProtoConfigurationMessageContactBuilder {
let builder = SNProtoConfigurationMessageContactBuilder()
if let _value = publicKey {
builder.setPublicKey(_value)
}
if let _value = name {
builder.setName(_value)
}
let builder = SNProtoConfigurationMessageContactBuilder(publicKey: publicKey, name: name)
if let _value = profilePicture {
builder.setProfilePicture(_value)
}
@ -3137,6 +3131,13 @@ extension SNProtoConfigurationMessageClosedGroup.SNProtoConfigurationMessageClos
@objc fileprivate override init() {}
@objc fileprivate init(publicKey: Data, name: String) {
super.init()
setPublicKey(publicKey)
setName(name)
}
@objc public func setPublicKey(_ valueParam: Data) {
proto.publicKey = valueParam
}
@ -3164,25 +3165,9 @@ extension SNProtoConfigurationMessageClosedGroup.SNProtoConfigurationMessageClos
fileprivate let proto: SessionProtos_ConfigurationMessage.Contact
@objc public var publicKey: Data? {
guard proto.hasPublicKey else {
return nil
}
return proto.publicKey
}
@objc public var hasPublicKey: Bool {
return proto.hasPublicKey
}
@objc public let publicKey: Data
@objc public var name: String? {
guard proto.hasName else {
return nil
}
return proto.name
}
@objc public var hasName: Bool {
return proto.hasName
}
@objc public let name: String
@objc public var profilePicture: String? {
guard proto.hasProfilePicture else {
@ -3204,8 +3189,12 @@ extension SNProtoConfigurationMessageClosedGroup.SNProtoConfigurationMessageClos
return proto.hasProfileKey
}
private init(proto: SessionProtos_ConfigurationMessage.Contact) {
private init(proto: SessionProtos_ConfigurationMessage.Contact,
publicKey: Data,
name: String) {
self.proto = proto
self.publicKey = publicKey
self.name = name
}
@objc
@ -3219,11 +3208,23 @@ extension SNProtoConfigurationMessageClosedGroup.SNProtoConfigurationMessageClos
}
fileprivate class func parseProto(_ proto: SessionProtos_ConfigurationMessage.Contact) throws -> SNProtoConfigurationMessageContact {
guard proto.hasPublicKey else {
throw SNProtoError.invalidProtobuf(description: "\(logTag) missing required field: publicKey")
}
let publicKey = proto.publicKey
guard proto.hasName else {
throw SNProtoError.invalidProtobuf(description: "\(logTag) missing required field: name")
}
let name = proto.name
// MARK: - Begin Validation Logic for SNProtoConfigurationMessageContact -
// MARK: - End Validation Logic for SNProtoConfigurationMessageContact -
let result = SNProtoConfigurationMessageContact(proto: proto)
let result = SNProtoConfigurationMessageContact(proto: proto,
publicKey: publicKey,
name: name)
return result
}

View file

@ -1335,6 +1335,7 @@ struct SessionProtos_ConfigurationMessage {
// `Message` and `Message+*Additions` files in the SwiftProtobuf library for
// methods supported on all messages.
/// @required
var publicKey: Data {
get {return _publicKey ?? SwiftProtobuf.Internal.emptyData}
set {_publicKey = newValue}
@ -1344,6 +1345,7 @@ struct SessionProtos_ConfigurationMessage {
/// Clears the value of `publicKey`. Subsequent reads from it will return its default value.
mutating func clearPublicKey() {self._publicKey = nil}
/// @required
var name: String {
get {return _name ?? String()}
set {_name = newValue}
@ -2843,6 +2845,7 @@ extension SessionProtos_ConfigurationMessage: SwiftProtobuf.Message, SwiftProtob
public var isInitialized: Bool {
if !SwiftProtobuf.Internal.areAllInitialized(self.closedGroups) {return false}
if !SwiftProtobuf.Internal.areAllInitialized(self.contacts) {return false}
return true
}
@ -2961,6 +2964,12 @@ extension SessionProtos_ConfigurationMessage.Contact: SwiftProtobuf.Message, Swi
4: .same(proto: "profileKey"),
]
public var isInitialized: Bool {
if self._publicKey == nil {return false}
if self._name == nil {return false}
return true
}
mutating func decodeMessage<D: SwiftProtobuf.Decoder>(decoder: inout D) throws {
while let fieldNumber = try decoder.nextFieldNumber() {
switch fieldNumber {

View file

@ -222,8 +222,10 @@ message ConfigurationMessage {
}
message Contact {
optional bytes publicKey = 1;
optional string name = 2;
// @required
required bytes publicKey = 1;
// @required
required string name = 2;
optional string profilePicture = 3;
optional bytes profileKey = 4;
}

View file

@ -8,6 +8,7 @@ extension ConfigurationMessage {
let profileKey = storage.getUserProfileKey()
var closedGroups: Set<ClosedGroup> = []
var openGroups: Set<String> = []
var contacts: Set<Contact> = []
Storage.read { transaction in
TSGroupThread.enumerateCollectionObjects(with: transaction) { object, _ in
guard let thread = object as? TSGroupThread else { return }
@ -28,6 +29,7 @@ extension ConfigurationMessage {
}
}
}
return ConfigurationMessage(displayName: displayName, profilePictureURL: profilePictureURL, profileKey: profileKey, closedGroups: closedGroups, openGroups: openGroups)
return ConfigurationMessage(displayName: displayName, profilePictureURL: profilePictureURL, profileKey: profileKey,
closedGroups: closedGroups, openGroups: openGroups, contacts: contacts)
}
}