From e3a080dd5bc802b2a67ff9d1fc7ec052b0349a40 Mon Sep 17 00:00:00 2001 From: Morgan Pretty Date: Wed, 21 Dec 2022 18:29:57 +1100 Subject: [PATCH] Updated to the latest version of the libSession-utl (contacts size) Fixed some broken unit tests (still some broken ones) --- .../SessionUtil+Contacts.swift | 2 +- .../ios-arm64/libsession-util.a | Bin 934024 -> 935072 bytes .../libsession-util.a | Bin 2091280 -> 2093456 bytes .../session/config/contacts.h | 7 +- .../session/config/contacts.hpp | 17 +- .../LibSessionUtil/ConfigContactsSpec.swift | 13 +- .../Open Groups/OpenGroupAPISpec.swift | 48 ++-- .../MessageSenderEncryptionSpec.swift | 217 +++++++++++------- .../Networking/BatchResponseSpec.swift | 6 +- 9 files changed, 184 insertions(+), 126 deletions(-) diff --git a/SessionMessagingKit/LibSessionUtil/Config Handling/SessionUtil+Contacts.swift b/SessionMessagingKit/LibSessionUtil/Config Handling/SessionUtil+Contacts.swift index 26ce1fce0..703d6fe63 100644 --- a/SessionMessagingKit/LibSessionUtil/Config Handling/SessionUtil+Contacts.swift +++ b/SessionMessagingKit/LibSessionUtil/Config Handling/SessionUtil+Contacts.swift @@ -155,7 +155,7 @@ internal extension SessionUtil { .bytes .map { CChar(bitPattern: $0) } var contact: contacts_contact = contacts_contact() - guard contacts_get_or_create(conf, &contact, &sessionId) else { + guard contacts_get_or_construct(conf, &contact, &sessionId) else { SNLog("Unable to upsert contact from Config Message") return } diff --git a/SessionMessagingKit/LibSessionUtil/libsession-util.xcframework/ios-arm64/libsession-util.a b/SessionMessagingKit/LibSessionUtil/libsession-util.xcframework/ios-arm64/libsession-util.a index 3f991bb6aadfa330a62538ad0adf8abfb0b9eb53..16f752d7cad87a57c2693076c1a1ffb407bae5a1 100644 GIT binary patch delta 27623 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 diff --git a/SessionMessagingKit/LibSessionUtil/libsession-util.xcframework/session/config/contacts.h b/SessionMessagingKit/LibSessionUtil/libsession-util.xcframework/session/config/contacts.h index a889c7cb9..ba27f79b9 100644 --- a/SessionMessagingKit/LibSessionUtil/libsession-util.xcframework/session/config/contacts.h +++ b/SessionMessagingKit/LibSessionUtil/libsession-util.xcframework/session/config/contacts.h @@ -67,7 +67,7 @@ bool contacts_get(const config_object* conf, contacts_contact* contact, const ch /// /// This is the method that should usually be used to create or update a contact, followed by /// setting fields in the contact, and then giving it to contacts_set(). -bool contacts_get_or_create( +bool contacts_get_or_construct( const config_object* conf, contacts_contact* contact, const char* session_id) __attribute__((warn_unused_result)); @@ -79,7 +79,7 @@ void contacts_set(config_object* conf, const contacts_contact* contact); // is simple enough; for example to update `approved` and leave everything else unchanged: // // contacts_contact c; -// if (contacts_get_or_create(conf, &c, some_session_id)) { +// if (contacts_get_or_construct(conf, &c, some_session_id)) { // const char* new_nickname = "Joe"; // c.approved = new_nickname; // contacts_set_or_create(conf, &c); @@ -92,6 +92,9 @@ void contacts_set(config_object* conf, const contacts_contact* contact); /// iteration; see details below. bool contacts_erase(config_object* conf, const char* session_id); +/// Returns the number of contacts. +size_t contacts_size(const config_object* conf); + /// Functions for iterating through the entire contact list, in sorted order. Intended use is: /// /// contacts_contact c; diff --git a/SessionMessagingKit/LibSessionUtil/libsession-util.xcframework/session/config/contacts.hpp b/SessionMessagingKit/LibSessionUtil/libsession-util.xcframework/session/config/contacts.hpp index 1601c6146..f97199c53 100644 --- a/SessionMessagingKit/LibSessionUtil/libsession-util.xcframework/session/config/contacts.hpp +++ b/SessionMessagingKit/LibSessionUtil/libsession-util.xcframework/session/config/contacts.hpp @@ -84,16 +84,17 @@ class Contacts : public ConfigBase { /// Similar to get(), but if the session ID does not exist this returns a filled-out /// contact_info containing the session_id (all other fields will be empty/defaulted). This is - /// intended to be combined with `set` to set-or-create a record. Note that this does not add - /// the session id to the contact list when called: that requires also calling `set` with this - /// value. - contact_info get_or_create(std::string_view pubkey_hex) const; + /// intended to be combined with `set` to set-or-create a record. + /// + /// NB: calling this does *not* add the session id to the contact list when called: that + /// requires also calling `set` with this value. + contact_info get_or_construct(std::string_view pubkey_hex) const; /// Sets or updates multiple contact info values at once with the given info. The usual use is /// to access the current info, change anything desired, then pass it back into set_contact, /// e.g.: /// - /// auto c = contacts.get_or_create(pubkey); + /// auto c = contacts.get_or_construct(pubkey); /// c.name = "Session User 42"; /// c.nickname = "BFF"; /// contacts.set(c); @@ -119,6 +120,12 @@ class Contacts : public ConfigBase { /// example. iterator erase(iterator it); + /// Returns the number of contacts. + size_t size() const; + + /// Returns true if the contact list is empty. + bool empty() const { return size() == 0; } + /// Iterators for iterating through all contacts. Typically you access this implicit via a for /// loop over the `Contacts` object: /// diff --git a/SessionMessagingKitTests/LibSessionUtil/ConfigContactsSpec.swift b/SessionMessagingKitTests/LibSessionUtil/ConfigContactsSpec.swift index b2f9c7744..f1426c85b 100644 --- a/SessionMessagingKitTests/LibSessionUtil/ConfigContactsSpec.swift +++ b/SessionMessagingKitTests/LibSessionUtil/ConfigContactsSpec.swift @@ -38,8 +38,10 @@ class ConfigContactsSpec: QuickSpec { let contactPtr: UnsafeMutablePointer? = nil expect(contacts_get(conf, contactPtr, &definitelyRealId)).to(beFalse()) + expect(contacts_size(conf)).to(equal(0)) + var contact2: contacts_contact = contacts_contact() - expect(contacts_get_or_create(conf, &contact2, &definitelyRealId)).to(beTrue()) + expect(contacts_get_or_construct(conf, &contact2, &definitelyRealId)).to(beTrue()) expect(contact2.name).to(beNil()) expect(contact2.nickname).to(beNil()) expect(contact2.approved).to(beFalse()) @@ -155,7 +157,7 @@ class ConfigContactsSpec: QuickSpec { .bytes .map { CChar(bitPattern: $0) } var contact5: contacts_contact = contacts_contact() - expect(contacts_get_or_create(conf2, &contact5, &anotherId)).to(beTrue()) + expect(contacts_get_or_construct(conf2, &contact5, &anotherId)).to(beTrue()) expect(contact5.name).to(beNil()) expect(contact5.nickname).to(beNil()) expect(contact5.approved).to(beFalse()) @@ -193,6 +195,8 @@ class ConfigContactsSpec: QuickSpec { // Iterate through and make sure we got everything we expected var sessionIds: [String] = [] var nicknames: [String] = [] + expect(contacts_size(conf)).to(equal(2)) + var contact6: contacts_contact = contacts_contact() let contactIterator: UnsafeMutablePointer = contacts_iterator_new(conf) while !contacts_iterator_done(contactIterator, &contact6) { @@ -211,6 +215,7 @@ class ConfigContactsSpec: QuickSpec { contacts_iterator_free(contactIterator) // Need to free the iterator expect(sessionIds.count).to(equal(2)) + expect(sessionIds.count).to(equal(contacts_size(conf))) expect(sessionIds.first).to(equal(String(cString: definitelyRealId.nullTerminated()))) expect(sessionIds.last).to(equal(String(cString: anotherId.nullTerminated()))) expect(nicknames.first).to(equal("Joey")) @@ -233,7 +238,7 @@ class ConfigContactsSpec: QuickSpec { .map { CChar(bitPattern: $0) } let profileKey7: [UInt8] = "qwerty".bytes var contact7: contacts_contact = contacts_contact() - expect(contacts_get_or_create(conf2, &contact7, &thirdId)).to(beTrue()) + expect(contacts_get_or_construct(conf2, &contact7, &thirdId)).to(beTrue()) nickname7.withUnsafeBufferPointer { contact7.nickname = $0.baseAddress } contact7.approved = true contact7.approved_me = true @@ -297,6 +302,8 @@ class ConfigContactsSpec: QuickSpec { // Validate the changes var sessionIds2: [String] = [] var nicknames2: [String] = [] + expect(contacts_size(conf)).to(equal(2)) + var contact8: contacts_contact = contacts_contact() let contactIterator2: UnsafeMutablePointer = contacts_iterator_new(conf) while !contacts_iterator_done(contactIterator2, &contact8) { diff --git a/SessionMessagingKitTests/Open Groups/OpenGroupAPISpec.swift b/SessionMessagingKitTests/Open Groups/OpenGroupAPISpec.swift index d0bee4fff..d97f36586 100644 --- a/SessionMessagingKitTests/Open Groups/OpenGroupAPISpec.swift +++ b/SessionMessagingKitTests/Open Groups/OpenGroupAPISpec.swift @@ -27,9 +27,9 @@ class OpenGroupAPISpec: QuickSpec { var dependencies: SMKDependencies! var response: (ResponseInfoType, Codable)? = nil - var pollResponse: [OpenGroupAPI.Endpoint: (ResponseInfoType, Codable?)]? + var pollResponse: (info: ResponseInfoType, data: [OpenGroupAPI.Endpoint: Codable])? var error: Error? - + describe("an OpenGroupAPI") { // MARK: - Configuration @@ -205,14 +205,16 @@ class OpenGroupAPISpec: QuickSpec { expect(error?.localizedDescription).to(beNil()) // Validate the response data - expect(pollResponse?.values).to(haveCount(3)) - expect(pollResponse?.keys).to(contain(.capabilities)) - expect(pollResponse?.keys).to(contain(.roomPollInfo("testRoom", 0))) - expect(pollResponse?.keys).to(contain(.roomMessagesRecent("testRoom"))) - expect(pollResponse?[.capabilities]?.0).to(beAKindOf(TestOnionRequestAPI.ResponseInfo.self)) + + expect(pollResponse?.data.count).to(equal(3)) + expect(pollResponse?.data.keys).to(contain(.capabilities)) + expect(pollResponse?.data.keys).to(contain(.roomPollInfo("testRoom", 0))) + expect(pollResponse?.data.keys).to(contain(.roomMessagesRecent("testRoom"))) + expect(pollResponse?.data[.capabilities]) + .to(beAKindOf(TestOnionRequestAPI.ResponseInfo.self)) // Validate request data - let requestData: TestOnionRequestAPI.RequestData? = (pollResponse?[.capabilities]?.0 as? TestOnionRequestAPI.ResponseInfo)?.requestData + let requestData: TestOnionRequestAPI.RequestData? = (pollResponse?.data[.capabilities] as? TestOnionRequestAPI.ResponseInfo)?.requestData expect(requestData?.urlString).to(equal("testserver/batch")) expect(requestData?.httpMethod).to(equal("POST")) expect(requestData?.publicKey).to(equal("88672ccb97f40bb57238989226cf429b575ba355443f47bc76c5ab144a96c65b")) @@ -241,7 +243,7 @@ class OpenGroupAPISpec: QuickSpec { timeout: .milliseconds(100) ) expect(error?.localizedDescription).to(beNil()) - expect(pollResponse?.keys).to(contain(.roomMessagesRecent("testRoom"))) + expect(pollResponse?.data.keys).to(contain(.roomMessagesRecent("testRoom"))) } it("retrieves recent messages if there was a last message and it has not performed the initial poll and the last message was too long ago") { @@ -272,7 +274,7 @@ class OpenGroupAPISpec: QuickSpec { timeout: .milliseconds(100) ) expect(error?.localizedDescription).to(beNil()) - expect(pollResponse?.keys).to(contain(.roomMessagesRecent("testRoom"))) + expect(pollResponse?.data.keys).to(contain(.roomMessagesRecent("testRoom"))) } it("retrieves recent messages if there was a last message and it has performed an initial poll but it was not too long ago") { @@ -303,7 +305,7 @@ class OpenGroupAPISpec: QuickSpec { timeout: .milliseconds(100) ) expect(error?.localizedDescription).to(beNil()) - expect(pollResponse?.keys).to(contain(.roomMessagesSince("testRoom", seqNo: 123))) + expect(pollResponse?.data.keys).to(contain(.roomMessagesSince("testRoom", seqNo: 123))) } it("retrieves recent messages if there was a last message and there has already been a poll this session") { @@ -334,7 +336,7 @@ class OpenGroupAPISpec: QuickSpec { timeout: .milliseconds(100) ) expect(error?.localizedDescription).to(beNil()) - expect(pollResponse?.keys).to(contain(.roomMessagesSince("testRoom", seqNo: 123))) + expect(pollResponse?.data.keys).to(contain(.roomMessagesSince("testRoom", seqNo: 123))) } context("when unblinded") { @@ -370,8 +372,8 @@ class OpenGroupAPISpec: QuickSpec { expect(error?.localizedDescription).to(beNil()) // Validate the response data - expect(pollResponse?.keys).toNot(contain(.inbox)) - expect(pollResponse?.keys).toNot(contain(.outbox)) + expect(pollResponse?.data.keys).toNot(contain(.inbox)) + expect(pollResponse?.data.keys).toNot(contain(.outbox)) } } @@ -471,8 +473,8 @@ class OpenGroupAPISpec: QuickSpec { expect(error?.localizedDescription).to(beNil()) // Validate the response data - expect(pollResponse?.keys).to(contain(.inbox)) - expect(pollResponse?.keys).to(contain(.outbox)) + expect(pollResponse?.data.keys).to(contain(.inbox)) + expect(pollResponse?.data.keys).to(contain(.outbox)) } it("retrieves recent inbox messages if there was no last message") { @@ -498,7 +500,7 @@ class OpenGroupAPISpec: QuickSpec { timeout: .milliseconds(100) ) expect(error?.localizedDescription).to(beNil()) - expect(pollResponse?.keys).to(contain(.inbox)) + expect(pollResponse?.data.keys).to(contain(.inbox)) } it("retrieves inbox messages since the last message if there was one") { @@ -529,7 +531,7 @@ class OpenGroupAPISpec: QuickSpec { timeout: .milliseconds(100) ) expect(error?.localizedDescription).to(beNil()) - expect(pollResponse?.keys).to(contain(.inboxSince(id: 124))) + expect(pollResponse?.data.keys).to(contain(.inboxSince(id: 124))) } it("retrieves recent outbox messages if there was no last message") { @@ -555,7 +557,7 @@ class OpenGroupAPISpec: QuickSpec { timeout: .milliseconds(100) ) expect(error?.localizedDescription).to(beNil()) - expect(pollResponse?.keys).to(contain(.outbox)) + expect(pollResponse?.data.keys).to(contain(.outbox)) } it("retrieves outbox messages since the last message if there was one") { @@ -586,7 +588,7 @@ class OpenGroupAPISpec: QuickSpec { timeout: .milliseconds(100) ) expect(error?.localizedDescription).to(beNil()) - expect(pollResponse?.keys).to(contain(.outboxSince(id: 125))) + expect(pollResponse?.data.keys).to(contain(.outboxSince(id: 125))) } } } @@ -650,9 +652,9 @@ class OpenGroupAPISpec: QuickSpec { ) expect(error?.localizedDescription).to(beNil()) - let capabilitiesResponse: HTTP.BatchSubResponse? = (pollResponse?[.capabilities]?.1 as? HTTP.BatchSubResponse) - let pollInfoResponse: HTTP.BatchSubResponse? = (pollResponse?[.roomPollInfo("testRoom", 0)]?.1 as? HTTP.BatchSubResponse) - let messagesResponse: HTTP.BatchSubResponse<[Failable]>? = (pollResponse?[.roomMessagesRecent("testRoom")]?.1 as? HTTP.BatchSubResponse<[Failable]>) + let capabilitiesResponse: HTTP.BatchSubResponse? = (pollResponse?.data[.capabilities] as? HTTP.BatchSubResponse) + let pollInfoResponse: HTTP.BatchSubResponse? = (pollResponse?.data[.roomPollInfo("testRoom", 0)] as? HTTP.BatchSubResponse) + let messagesResponse: HTTP.BatchSubResponse<[Failable]>? = (pollResponse?.data[.roomMessagesRecent("testRoom")] as? HTTP.BatchSubResponse<[Failable]>) expect(capabilitiesResponse?.failedToParseBody).to(beFalse()) expect(pollInfoResponse?.failedToParseBody).to(beTrue()) expect(messagesResponse?.failedToParseBody).to(beTrue()) diff --git a/SessionMessagingKitTests/Sending & Receiving/MessageSenderEncryptionSpec.swift b/SessionMessagingKitTests/Sending & Receiving/MessageSenderEncryptionSpec.swift index aa3de4a23..514bb6af9 100644 --- a/SessionMessagingKitTests/Sending & Receiving/MessageSenderEncryptionSpec.swift +++ b/SessionMessagingKitTests/Sending & Receiving/MessageSenderEncryptionSpec.swift @@ -56,11 +56,14 @@ class MessageSenderEncryptionSpec: QuickSpec { } it("can encrypt correctly") { - let result = try? MessageSender.encryptWithSessionProtocol( - "TestMessage".data(using: .utf8)!, - for: "05\(TestConstants.publicKey)", - using: SMKDependencies(storage: mockStorage) - ) + let result = mockStorage.write { db in + try? MessageSender.encryptWithSessionProtocol( + db, + plaintext: "TestMessage".data(using: .utf8)!, + for: "05\(TestConstants.publicKey)", + using: SMKDependencies(storage: mockStorage) + ) + } // Note: A Nonce is used for this so we can't compare the exact value when not mocked expect(result).toNot(beNil()) @@ -68,11 +71,14 @@ class MessageSenderEncryptionSpec: QuickSpec { } it("returns the correct value when mocked") { - let result = try? MessageSender.encryptWithSessionProtocol( - "TestMessage".data(using: .utf8)!, - for: "05\(TestConstants.publicKey)", - using: dependencies - ) + let result = mockStorage.write { db in + try? MessageSender.encryptWithSessionProtocol( + db, + plaintext: "TestMessage".data(using: .utf8)!, + for: "05\(TestConstants.publicKey)", + using: dependencies + ) + } expect(result?.bytes).to(equal([1, 2, 3])) } @@ -83,51 +89,63 @@ class MessageSenderEncryptionSpec: QuickSpec { _ = try Identity.filter(id: .ed25519SecretKey).deleteAll(db) } - expect { - try MessageSender.encryptWithSessionProtocol( - "TestMessage".data(using: .utf8)!, - for: "05\(TestConstants.publicKey)", - using: dependencies - ) + mockStorage.write { db in + expect { + try MessageSender.encryptWithSessionProtocol( + db, + plaintext: "TestMessage".data(using: .utf8)!, + for: "05\(TestConstants.publicKey)", + using: dependencies + ) + } + .to(throwError(MessageSenderError.noUserED25519KeyPair)) } - .to(throwError(MessageSenderError.noUserED25519KeyPair)) } it("throws an error if the signature generation fails") { mockSign.when { $0.signature(message: anyArray(), secretKey: anyArray()) }.thenReturn(nil) - expect { - try MessageSender.encryptWithSessionProtocol( - "TestMessage".data(using: .utf8)!, - for: "05\(TestConstants.publicKey)", - using: dependencies - ) + mockStorage.write { db in + expect { + try MessageSender.encryptWithSessionProtocol( + db, + plaintext: "TestMessage".data(using: .utf8)!, + for: "05\(TestConstants.publicKey)", + using: dependencies + ) + } + .to(throwError(MessageSenderError.signingFailed)) } - .to(throwError(MessageSenderError.signingFailed)) } it("throws an error if the encryption fails") { mockBox.when { $0.seal(message: anyArray(), recipientPublicKey: anyArray()) }.thenReturn(nil) - expect { - try MessageSender.encryptWithSessionProtocol( - "TestMessage".data(using: .utf8)!, - for: "05\(TestConstants.publicKey)", - using: dependencies - ) + mockStorage.write { db in + expect { + try MessageSender.encryptWithSessionProtocol( + db, + plaintext: "TestMessage".data(using: .utf8)!, + for: "05\(TestConstants.publicKey)", + using: dependencies + ) + } + .to(throwError(MessageSenderError.encryptionFailed)) } - .to(throwError(MessageSenderError.encryptionFailed)) } } context("when encrypting with the blinded session protocol") { it("successfully encrypts") { - let result = try? MessageSender.encryptWithSessionBlindingProtocol( - "TestMessage".data(using: .utf8)!, - for: "15\(TestConstants.blindedPublicKey)", - openGroupPublicKey: TestConstants.serverPublicKey, - using: dependencies - ) + let result = mockStorage.write { db in + try? MessageSender.encryptWithSessionBlindingProtocol( + db, + plaintext: "TestMessage".data(using: .utf8)!, + for: "15\(TestConstants.blindedPublicKey)", + openGroupPublicKey: TestConstants.serverPublicKey, + using: dependencies + ) + } expect(result?.toHexString()) .to(equal( @@ -138,23 +156,29 @@ class MessageSenderEncryptionSpec: QuickSpec { } it("includes a version at the start of the encrypted value") { - let result = try? MessageSender.encryptWithSessionBlindingProtocol( - "TestMessage".data(using: .utf8)!, - for: "15\(TestConstants.blindedPublicKey)", - openGroupPublicKey: TestConstants.serverPublicKey, - using: dependencies - ) + let result = mockStorage.write { db in + try? MessageSender.encryptWithSessionBlindingProtocol( + db, + plaintext: "TestMessage".data(using: .utf8)!, + for: "15\(TestConstants.blindedPublicKey)", + openGroupPublicKey: TestConstants.serverPublicKey, + using: dependencies + ) + } expect(result?.toHexString().prefix(2)).to(equal("00")) } it("includes the nonce at the end of the encrypted value") { - let maybeResult = try? MessageSender.encryptWithSessionBlindingProtocol( - "TestMessage".data(using: .utf8)!, - for: "15\(TestConstants.blindedPublicKey)", - openGroupPublicKey: TestConstants.serverPublicKey, - using: dependencies - ) + let maybeResult = mockStorage.write { db in + try? MessageSender.encryptWithSessionBlindingProtocol( + db, + plaintext: "TestMessage".data(using: .utf8)!, + for: "15\(TestConstants.blindedPublicKey)", + openGroupPublicKey: TestConstants.serverPublicKey, + using: dependencies + ) + } let result: [UInt8] = (maybeResult?.bytes ?? []) let nonceBytes: [UInt8] = Array(result[max(0, (result.count - 24))..)?.body) + expect((result?.responses[0] as? HTTP.BatchSubResponse)?.body) .to(equal(testType)) - expect((result?[1].1 as? HTTP.BatchSubResponse)?.body) + expect((result?.responses[1] as? HTTP.BatchSubResponse)?.body) .to(equal(testType2)) }