Clean protobuf

pull/362/head
Niels Andriesse 3 years ago
parent 1ba98c5f99
commit 82690259b2

@ -15,8 +15,6 @@ public final class ClosedGroupControlMessage : ControlMessage {
// MARK: Kind
public enum Kind : CustomStringConvertible {
case new(publicKey: Data, name: String, encryptionKeyPair: ECKeyPair, members: [Data], admins: [Data])
/// - Note: Deprecated in favor of more explicit group updates.
case update(name: String, members: [Data])
/// An encryption key pair encrypted for each member individually.
///
/// - Note: `publicKey` is only set when an encryption key pair is sent in a one-to-one context (i.e. not in a group).
@ -30,7 +28,6 @@ public final class ClosedGroupControlMessage : ControlMessage {
public var description: String {
switch self {
case .new: return "new"
case .update: return "update"
case .encryptionKeyPair: return "encryptionKeyPair"
case .nameChange: return "nameChange"
case .membersAdded: return "membersAdded"
@ -95,8 +92,6 @@ public final class ClosedGroupControlMessage : ControlMessage {
case .new(let publicKey, let name, let encryptionKeyPair, let members, let admins):
return !publicKey.isEmpty && !name.isEmpty && !encryptionKeyPair.publicKey.isEmpty
&& !encryptionKeyPair.privateKey.isEmpty && !members.isEmpty && !admins.isEmpty
case .update(let name, _):
return !name.isEmpty
case .encryptionKeyPair: return true
case .nameChange(let name): return !name.isEmpty
case .membersAdded(let members): return !members.isEmpty
@ -118,10 +113,6 @@ public final class ClosedGroupControlMessage : ControlMessage {
let members = coder.decodeObject(forKey: "members") as? [Data],
let admins = coder.decodeObject(forKey: "admins") as? [Data] else { return nil }
self.kind = .new(publicKey: publicKey, name: name, encryptionKeyPair: encryptionKeyPair, members: members, admins: admins)
case "update":
guard let name = coder.decodeObject(forKey: "name") as? String,
let members = coder.decodeObject(forKey: "members") as? [Data] else { return nil }
self.kind = .update(name: name, members: members)
case "encryptionKeyPair":
let publicKey = coder.decodeObject(forKey: "publicKey") as? Data
guard let wrappers = coder.decodeObject(forKey: "wrappers") as? [KeyPairWrapper] else { return nil }
@ -154,10 +145,6 @@ public final class ClosedGroupControlMessage : ControlMessage {
coder.encode(encryptionKeyPair, forKey: "encryptionKeyPair")
coder.encode(members, forKey: "members")
coder.encode(admins, forKey: "admins")
case .update(let name, let members):
coder.encode("update", forKey: "kind")
coder.encode(name, forKey: "name")
coder.encode(members, forKey: "members")
case .encryptionKeyPair(let publicKey, let wrappers):
coder.encode("encryptionKeyPair", forKey: "kind")
coder.encode(publicKey, forKey: "publicKey")
@ -194,9 +181,6 @@ public final class ClosedGroupControlMessage : ControlMessage {
SNLog("Couldn't parse key pair.")
return nil
}
case .update:
guard let name = closedGroupControlMessageProto.name else { return nil }
kind = .update(name: name, members: closedGroupControlMessageProto.members)
case .encryptionKeyPair:
let publicKey = closedGroupControlMessageProto.publicKey
let wrappers = closedGroupControlMessageProto.wrappers.compactMap { KeyPairWrapper.fromProto($0) }
@ -237,10 +221,6 @@ public final class ClosedGroupControlMessage : ControlMessage {
}
closedGroupControlMessage.setMembers(members)
closedGroupControlMessage.setAdmins(admins)
case .update(let name, let members):
closedGroupControlMessage = SNProtoDataMessageClosedGroupControlMessage.builder(type: .update)
closedGroupControlMessage.setName(name)
closedGroupControlMessage.setMembers(members)
case .encryptionKeyPair(let publicKey, let wrappers):
closedGroupControlMessage = SNProtoDataMessageClosedGroupControlMessage.builder(type: .encryptionKeyPair)
if let publicKey = publicKey {

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

@ -1,10 +1,9 @@
// DO NOT EDIT.
// swift-format-ignore-file
//
// Generated by the Swift generator plugin for the protocol buffer compiler.
// Source: WebSocketResources.proto
//
// For information on using the generated types, please see the documentation:
// For information on using the generated types, please see the documenation:
// https://github.com/apple/swift-protobuf/
//*
@ -21,7 +20,7 @@ import SwiftProtobuf
// If the compiler emits an error on this type, it is because this file
// was generated by a version of the `protoc` Swift plug-in that is
// incompatible with the version of SwiftProtobuf to which you are linking.
// Please ensure that you are building against the same version of the API
// Please ensure that your are building against the same version of the API
// that was used to generate this file.
fileprivate struct _GeneratedWithProtocGenSwiftVersion: SwiftProtobuf.ProtobufAPIVersionCheck {
struct _2: SwiftProtobuf.ProtobufAPIVersion_2 {}
@ -146,31 +145,31 @@ struct WebSocketProtos_WebSocketMessage {
/// @required
var type: WebSocketProtos_WebSocketMessage.TypeEnum {
get {return _type ?? .unknown}
set {_type = newValue}
get {return _storage._type ?? .unknown}
set {_uniqueStorage()._type = newValue}
}
/// Returns true if `type` has been explicitly set.
var hasType: Bool {return self._type != nil}
var hasType: Bool {return _storage._type != nil}
/// Clears the value of `type`. Subsequent reads from it will return its default value.
mutating func clearType() {self._type = nil}
mutating func clearType() {_uniqueStorage()._type = nil}
var request: WebSocketProtos_WebSocketRequestMessage {
get {return _request ?? WebSocketProtos_WebSocketRequestMessage()}
set {_request = newValue}
get {return _storage._request ?? WebSocketProtos_WebSocketRequestMessage()}
set {_uniqueStorage()._request = newValue}
}
/// Returns true if `request` has been explicitly set.
var hasRequest: Bool {return self._request != nil}
var hasRequest: Bool {return _storage._request != nil}
/// Clears the value of `request`. Subsequent reads from it will return its default value.
mutating func clearRequest() {self._request = nil}
mutating func clearRequest() {_uniqueStorage()._request = nil}
var response: WebSocketProtos_WebSocketResponseMessage {
get {return _response ?? WebSocketProtos_WebSocketResponseMessage()}
set {_response = newValue}
get {return _storage._response ?? WebSocketProtos_WebSocketResponseMessage()}
set {_uniqueStorage()._response = newValue}
}
/// Returns true if `response` has been explicitly set.
var hasResponse: Bool {return self._response != nil}
var hasResponse: Bool {return _storage._response != nil}
/// Clears the value of `response`. Subsequent reads from it will return its default value.
mutating func clearResponse() {self._response = nil}
mutating func clearResponse() {_uniqueStorage()._response = nil}
var unknownFields = SwiftProtobuf.UnknownStorage()
@ -205,9 +204,7 @@ struct WebSocketProtos_WebSocketMessage {
init() {}
fileprivate var _type: WebSocketProtos_WebSocketMessage.TypeEnum? = nil
fileprivate var _request: WebSocketProtos_WebSocketRequestMessage? = nil
fileprivate var _response: WebSocketProtos_WebSocketResponseMessage? = nil
fileprivate var _storage = _StorageClass.defaultInstance
}
#if swift(>=4.2)
@ -336,34 +333,70 @@ extension WebSocketProtos_WebSocketMessage: SwiftProtobuf.Message, SwiftProtobuf
3: .same(proto: "response"),
]
fileprivate class _StorageClass {
var _type: WebSocketProtos_WebSocketMessage.TypeEnum? = nil
var _request: WebSocketProtos_WebSocketRequestMessage? = nil
var _response: WebSocketProtos_WebSocketResponseMessage? = nil
static let defaultInstance = _StorageClass()
private init() {}
init(copying source: _StorageClass) {
_type = source._type
_request = source._request
_response = source._response
}
}
fileprivate mutating func _uniqueStorage() -> _StorageClass {
if !isKnownUniquelyReferenced(&_storage) {
_storage = _StorageClass(copying: _storage)
}
return _storage
}
mutating func decodeMessage<D: SwiftProtobuf.Decoder>(decoder: inout D) throws {
while let fieldNumber = try decoder.nextFieldNumber() {
switch fieldNumber {
case 1: try decoder.decodeSingularEnumField(value: &self._type)
case 2: try decoder.decodeSingularMessageField(value: &self._request)
case 3: try decoder.decodeSingularMessageField(value: &self._response)
default: break
_ = _uniqueStorage()
try withExtendedLifetime(_storage) { (_storage: _StorageClass) in
while let fieldNumber = try decoder.nextFieldNumber() {
switch fieldNumber {
case 1: try decoder.decodeSingularEnumField(value: &_storage._type)
case 2: try decoder.decodeSingularMessageField(value: &_storage._request)
case 3: try decoder.decodeSingularMessageField(value: &_storage._response)
default: break
}
}
}
}
func traverse<V: SwiftProtobuf.Visitor>(visitor: inout V) throws {
if let v = self._type {
try visitor.visitSingularEnumField(value: v, fieldNumber: 1)
}
if let v = self._request {
try visitor.visitSingularMessageField(value: v, fieldNumber: 2)
}
if let v = self._response {
try visitor.visitSingularMessageField(value: v, fieldNumber: 3)
try withExtendedLifetime(_storage) { (_storage: _StorageClass) in
if let v = _storage._type {
try visitor.visitSingularEnumField(value: v, fieldNumber: 1)
}
if let v = _storage._request {
try visitor.visitSingularMessageField(value: v, fieldNumber: 2)
}
if let v = _storage._response {
try visitor.visitSingularMessageField(value: v, fieldNumber: 3)
}
}
try unknownFields.traverse(visitor: &visitor)
}
static func ==(lhs: WebSocketProtos_WebSocketMessage, rhs: WebSocketProtos_WebSocketMessage) -> Bool {
if lhs._type != rhs._type {return false}
if lhs._request != rhs._request {return false}
if lhs._response != rhs._response {return false}
if lhs._storage !== rhs._storage {
let storagesAreEqual: Bool = withExtendedLifetime((lhs._storage, rhs._storage)) { (_args: (_StorageClass, _StorageClass)) in
let _storage = _args.0
let rhs_storage = _args.1
if _storage._type != rhs_storage._type {return false}
if _storage._request != rhs_storage._request {return false}
if _storage._response != rhs_storage._response {return false}
return true
}
if !storagesAreEqual {return false}
}
if lhs.unknownFields != rhs.unknownFields {return false}
return true
}

@ -7,8 +7,8 @@ package SessionProtos;
message Envelope {
enum Type {
UNIDENTIFIED_SENDER = 6;
CLOSED_GROUP_CIPHERTEXT = 7;
SESSION_MESSAGE = 6;
CLOSED_GROUP_MESSAGE = 7;
}
// @required
@ -16,7 +16,7 @@ message Envelope {
optional string source = 2;
optional uint32 sourceDevice = 7;
// @required
optional uint64 timestamp = 5;
required uint64 timestamp = 5;
optional bytes content = 8;
optional uint64 serverTimestamp = 10;
}
@ -29,9 +29,9 @@ message TypingMessage {
}
// @required
optional uint64 timestamp = 1;
required uint64 timestamp = 1;
// @required
optional Action action = 2;
required Action action = 2;
}
message Content {
@ -41,13 +41,6 @@ message Content {
optional ConfigurationMessage configurationMessage = 7;
}
message ClosedGroupCiphertextMessageWrapper {
// @required
optional bytes ciphertext = 1;
// @required
optional bytes ephemeralPublicKey = 2;
}
message KeyPair {
// @required
required bytes publicKey = 1;
@ -76,87 +69,16 @@ message DataMessage {
}
// @required
optional uint64 id = 1;
required uint64 id = 1;
// @required
optional string author = 2;
required string author = 2;
optional string text = 3;
repeated QuotedAttachment attachments = 4;
}
message Contact {
message Name {
optional string givenName = 1;
optional string familyName = 2;
optional string prefix = 3;
optional string suffix = 4;
optional string middleName = 5;
optional string displayName = 6;
}
message Phone {
enum Type {
HOME = 1;
MOBILE = 2;
WORK = 3;
CUSTOM = 4;
}
optional string value = 1;
optional Type type = 2;
optional string label = 3;
}
message Email {
enum Type {
HOME = 1;
MOBILE = 2;
WORK = 3;
CUSTOM = 4;
}
optional string value = 1;
optional Type type = 2;
optional string label = 3;
}
message PostalAddress {
enum Type {
HOME = 1;
WORK = 2;
CUSTOM = 3;
}
optional Type type = 1;
optional string label = 2;
optional string street = 3;
optional string pobox = 4;
optional string neighborhood = 5;
optional string city = 6;
optional string region = 7;
optional string postcode = 8;
optional string country = 9;
}
message Avatar {
optional AttachmentPointer avatar = 1;
optional bool isProfile = 2;
}
optional Name name = 1;
repeated Phone number = 3;
repeated Email email = 4;
repeated PostalAddress address = 5;
optional Avatar avatar = 6;
optional string organization = 7;
}
message Preview {
// @required
optional string url = 1;
required string url = 1;
optional string title = 2;
optional AttachmentPointer image = 3;
}
@ -170,7 +92,6 @@ message DataMessage {
enum Type {
NEW = 1; // publicKey, name, encryptionKeyPair, members, admins
UPDATE = 2; // name, members
ENCRYPTION_KEY_PAIR = 3; // publicKey, wrappers
NAME_CHANGE = 4; // name
MEMBERS_ADDED = 5; // members
@ -204,7 +125,6 @@ message DataMessage {
optional bytes profileKey = 6;
optional uint64 timestamp = 7;
optional Quote quote = 8;
repeated Contact contact = 9;
repeated Preview preview = 10;
optional LokiProfile profile = 101;
optional ClosedGroupControlMessage closedGroupControlMessage = 104;
@ -246,7 +166,7 @@ message ReceiptMessage {
}
// @required
optional Type type = 1;
required Type type = 1;
repeated uint64 timestamp = 2;
}
@ -257,7 +177,7 @@ message AttachmentPointer {
}
// @required
optional fixed64 id = 1;
required fixed64 id = 1;
optional string contentType = 2;
optional bytes key = 3;
optional uint32 size = 4;
@ -271,26 +191,6 @@ message AttachmentPointer {
optional string url = 101;
}
message ContactDetails {
message Avatar {
optional string contentType = 1;
optional uint32 length = 2;
}
// @required
optional string number = 1;
optional string name = 2;
optional Avatar avatar = 3;
optional string color = 4;
optional bytes profileKey = 6;
optional bool blocked = 7;
optional uint32 expireTimer = 8;
optional string nickname = 101;
}
// -------- Deprecated --------
message GroupContext {
enum Type {

@ -311,7 +311,6 @@ extension MessageReceiver {
private static func handleClosedGroupControlMessage(_ message: ClosedGroupControlMessage, using transaction: Any) {
switch message.kind! {
case .new: handleNewClosedGroup(message, using: transaction)
case .update: handleClosedGroupUpdated(message, using: transaction) // Deprecated
case .encryptionKeyPair: handleClosedGroupEncryptionKeyPair(message, using: transaction)
case .nameChange: handleClosedGroupNameChanged(message, using: transaction)
case .membersAdded: handleClosedGroupMembersAdded(message, using: transaction)
@ -561,68 +560,4 @@ extension MessageReceiver {
// Perform the update
update(groupID, thread, group)
}
// MARK: - Deprecated
/// - Note: Deprecated.
private static func handleClosedGroupUpdated(_ message: ClosedGroupControlMessage, using transaction: Any) {
// Prepare
guard case let .update(name, membersAsData) = message.kind else { return }
let transaction = transaction as! YapDatabaseReadWriteTransaction
// Unwrap the message
guard let groupPublicKey = message.groupPublicKey else { return }
let members = membersAsData.map { $0.toHexString() }
// Get the group
let groupID = LKGroupUtilities.getEncodedClosedGroupIDAsData(groupPublicKey)
let threadID = TSGroupThread.threadId(fromGroupId: groupID)
guard let thread = TSGroupThread.fetch(uniqueId: threadID, transaction: transaction) else {
return SNLog("Ignoring closed group update message for nonexistent group.")
}
let group = thread.groupModel
let oldMembers = group.groupMemberIds
// Check that the message isn't from before the group was created
guard Double(message.sentTimestamp!) > thread.creationDate.timeIntervalSince1970 * 1000 else {
return SNLog("Ignoring closed group update from before thread was created.")
}
// Check that the sender is a member of the group (before the update)
guard Set(group.groupMemberIds).contains(message.sender!) else {
return SNLog("Ignoring closed group update message from non-member.")
}
// Check that the admin wasn't removed unless the group was destroyed entirely
if !members.contains(group.groupAdminIds.first!) && !members.isEmpty {
return SNLog("Ignoring invalid closed group update message.")
}
// Remove the group from the user's set of public keys to poll for if the current user was removed
let userPublicKey = getUserHexEncodedPublicKey()
let wasCurrentUserRemoved = !members.contains(userPublicKey)
if wasCurrentUserRemoved {
Storage.shared.removeClosedGroupPublicKey(groupPublicKey, using: transaction)
// Remove the key pairs
Storage.shared.removeAllClosedGroupEncryptionKeyPairs(for: groupPublicKey, using: transaction)
// Notify the PN server
let _ = PushNotificationAPI.performOperation(.unsubscribe, for: groupPublicKey, publicKey: userPublicKey)
}
// Generate and distribute a new encryption key pair if needed
let wasAnyUserRemoved = (Set(members).intersection(oldMembers) != Set(oldMembers))
let isCurrentUserAdmin = group.groupAdminIds.contains(getUserHexEncodedPublicKey())
if wasAnyUserRemoved && isCurrentUserAdmin {
do {
try MessageSender.generateAndSendNewEncryptionKeyPair(for: groupPublicKey, to: Set(members), using: transaction)
} catch {
SNLog("Couldn't distribute new encryption key pair.")
}
}
// Update the group
let newGroupModel = TSGroupModel(title: name, memberIds: members, image: nil, groupId: groupID, groupType: .closedGroup, adminIds: group.groupAdminIds)
thread.setGroupModel(newGroupModel, with: transaction)
// Notify the user if needed
if Set(members) != Set(oldMembers) || name != group.groupName {
let infoMessageType: TSInfoMessageType = wasCurrentUserRemoved ? .typeGroupQuit : .typeGroupUpdate
let updateInfo = group.getInfoStringAboutUpdate(to: newGroupModel)
let infoMessage = TSInfoMessage(timestamp: NSDate.ows_millisecondTimeStamp(), in: thread, messageType: infoMessageType, customMessage: updateInfo)
infoMessage.save(with: transaction)
}
}
}

@ -68,10 +68,10 @@ public enum MessageReceiver {
(plaintext, sender) = (envelope.content!, envelope.source!)
} else {
switch envelope.type {
case .unidentifiedSender:
case .sessionMessage:
guard let userX25519KeyPair = SNMessagingKitConfiguration.shared.storage.getUserKeyPair() else { throw Error.noUserX25519KeyPair }
(plaintext, sender) = try decryptWithSessionProtocol(ciphertext: ciphertext, using: userX25519KeyPair)
case .closedGroupCiphertext:
case .closedGroupMessage:
guard let hexEncodedGroupPublicKey = envelope.source, SNMessagingKitConfiguration.shared.storage.isClosedGroup(hexEncodedGroupPublicKey) else { throw Error.invalidGroupPublicKey }
var encryptionKeyPairs = Storage.shared.getClosedGroupEncryptionKeyPairs(for: hexEncodedGroupPublicKey)
guard !encryptionKeyPairs.isEmpty else { throw Error.noGroupKeyPair }

@ -184,10 +184,10 @@ public final class MessageSender : NSObject {
let senderPublicKey: String
switch destination {
case .contact(_):
kind = .unidentifiedSender
kind = .sessionMessage
senderPublicKey = ""
case .closedGroup(let groupPublicKey):
kind = .closedGroupCiphertext
kind = .closedGroupMessage
senderPublicKey = groupPublicKey
case .openGroup(_, _): preconditionFailure()
}

@ -147,7 +147,7 @@ public final class OpenGroupPoller : NSObject {
let content = SNProtoContent.builder()
content.setDataMessage(try! dataMessageProto.build())
// Envelope
let envelope = SNProtoEnvelope.builder(type: .unidentifiedSender, timestamp: message.timestamp)
let envelope = SNProtoEnvelope.builder(type: .sessionMessage, timestamp: message.timestamp)
envelope.setSource(senderPublicKey)
envelope.setSourceDevice(1)
envelope.setContent(try! content.build().serializedData())

Loading…
Cancel
Save