From 04a55fa30d3f195b97bd906132501efa62347b12 Mon Sep 17 00:00:00 2001 From: Christopher Kobusch Date: Mon, 8 May 2023 00:00:50 +0200 Subject: [PATCH 1/3] Swift package compatibility --- MatrixSDK.xcodeproj/project.pbxproj | 2 +- .../Realm/MXBeaconInfoSummaryRealmStore.swift | 9 ++-- .../Store/Realm/MXRealmBeacon.swift | 2 +- .../Store/Realm/MXRealmBeaconInfo.swift | 2 +- .../Realm/MXRealmBeaconInfoSummary.swift | 2 +- .../Crypto/MXBackgroundCryptoV2.swift | 2 +- .../RoomEvent/MXRoomEventDecryption.swift | 2 +- .../RoomEvent/MXRoomEventEncryption.swift | 2 +- .../Data/MXCryptoUserIdentityWrapper.swift | 2 +- .../EventEncryptionAlgorithm+String.swift | 2 +- .../MXDeviceVerification+LocalTrust.swift | 2 +- ...EventDecryptionResult+DecryptedEvent.swift | 2 +- ...mHistoryVisibility+HistoryVisibility.swift | 2 +- .../CryptoMachine/MXCryptoMachine.swift | 2 +- .../CryptoMachine/MXCryptoProtocols.swift | 2 +- .../CryptoMachine/MXCryptoRequests.swift | 2 +- .../CryptoMachine/MXCryptoSDKLogger.swift | 2 +- .../Devices/Data/MXCryptoDeviceWrapper.swift | 2 +- .../Engine/MXCryptoKeyBackupEngine.swift | 2 +- MatrixSDK/Crypto/MXCryptoV2.swift | 2 +- .../Data/MXCryptoMigrationStore.swift | 4 +- .../Migration/MXCryptoMigrationV2.swift | 4 +- .../MXKeyVerificationManagerV2.swift | 2 +- .../Requests/MXKeyVerificationRequestV2.swift | 2 +- .../QRCode/MXQRCodeTransactionV2.swift | 2 +- .../Transactions/SAS/MXSASTransactionV2.swift | 2 +- .../Utils/Logs/MXAnalyticsDestination.swift | 4 ++ MatrixSDK/Utils/Logs/MXLog.swift | 4 ++ MatrixSDK/Utils/Realm/RLMSupport.swift | 43 ++++++++++--------- MatrixSDK/Utils/Realm/Realm+MatrixSDK.swift | 2 +- .../Megolm/MXMegolmDecryptionUnitTests.swift | 2 +- .../MXRoomEventDecryptionUnitTests.swift | 2 +- .../MXRoomEventEncryptionUnitTests.swift | 2 +- .../Data/MXCrossSigningInfoUnitTests.swift | 2 +- .../MXCrossSigningInfoSourceUnitTests.swift | 2 +- .../MXCrossSigningV2UnitTests.swift | 2 +- .../CryptoMachine/DecryptedEvent+Stub.swift | 2 +- .../Crypto/CryptoMachine/Device+Stub.swift | 2 +- .../EventEncryptionAlgorithmUnitTests.swift | 2 +- .../MXCryptoMachineUnitTests.swift | 2 +- .../CryptoMachine/MXCryptoProtocolStubs.swift | 2 +- .../MXCryptoRequestsUnitTests.swift | 2 +- .../Data/Store/MXMemoryCryptoStore.swift | 2 +- .../Devices/Data/MXDeviceInfoUnitTests.swift | 2 +- .../Devices/MXDeviceInfoSourceUnitTests.swift | 2 +- .../MXCryptoKeyBackupEngineUnitTests.swift | 2 +- .../MXCryptoMigrationStoreUnitTests.swift | 2 +- .../Trust/MXTrustLevelSourceUnitTests.swift | 2 +- .../MXKeyVerificationRequestV2UnitTests.swift | 2 +- .../Requests/VerificationRequestStub.swift | 2 +- .../MXQRCodeTransactionV2UnitTests.swift | 2 +- .../Transactions/QRCode/QrCodeStub.swift | 2 +- .../SAS/MXSASTransactionV2UnitTests.swift | 2 +- .../Transactions/SAS/SasStub.swift | 2 +- changelog.d/sdk-1497.build | 1 + 55 files changed, 88 insertions(+), 77 deletions(-) create mode 100644 changelog.d/sdk-1497.build diff --git a/MatrixSDK.xcodeproj/project.pbxproj b/MatrixSDK.xcodeproj/project.pbxproj index 643661e11e..33185391d3 100644 --- a/MatrixSDK.xcodeproj/project.pbxproj +++ b/MatrixSDK.xcodeproj/project.pbxproj @@ -8346,7 +8346,7 @@ MACOSX_DEPLOYMENT_TARGET = 10.15; MTL_ENABLE_DEBUG_INFO = YES; ONLY_ACTIVE_ARCH = YES; - OTHER_SWIFT_FLAGS = "-D DEBUG"; + OTHER_SWIFT_FLAGS = "-D DEBUG -D IS_TEST_RUN"; SDKROOT = ""; SWIFT_SWIFT3_OBJC_INFERENCE = On; SWIFT_VERSION = 5.0; diff --git a/MatrixSDK/Aggregations/LocationSharing/Store/Realm/MXBeaconInfoSummaryRealmStore.swift b/MatrixSDK/Aggregations/LocationSharing/Store/Realm/MXBeaconInfoSummaryRealmStore.swift index a67ca8d1d5..5545ad8478 100644 --- a/MatrixSDK/Aggregations/LocationSharing/Store/Realm/MXBeaconInfoSummaryRealmStore.swift +++ b/MatrixSDK/Aggregations/LocationSharing/Store/Realm/MXBeaconInfoSummaryRealmStore.swift @@ -15,7 +15,7 @@ // import Foundation -import Realm +@_implementationOnly import Realm @objcMembers public class MXBeaconInfoSummaryRealmStore: NSObject { @@ -155,10 +155,11 @@ public class MXBeaconInfoSummaryRealmStore: NSObject { private func beaconInfoSummaries(from realmBeaconInfoSummaryResults: RLMResults) -> [MXBeaconInfoSummary] { var summaries: [MXBeaconInfoSummary] = [] - - for realmSummary in realmBeaconInfoSummaryResults { + + var iterator = NSFastEnumerationIterator(realmBeaconInfoSummaryResults) + while let realmSummary = iterator.next() as? MXRealmBeaconInfoSummary { - if let realmBeaconInfoSummary = realmSummary as? MXRealmBeaconInfoSummary, let summary = self.mapper.beaconInfoSummary(from: realmBeaconInfoSummary) { + if let summary = self.mapper.beaconInfoSummary(from: realmSummary) { summaries.append(summary) } } diff --git a/MatrixSDK/Aggregations/LocationSharing/Store/Realm/MXRealmBeacon.swift b/MatrixSDK/Aggregations/LocationSharing/Store/Realm/MXRealmBeacon.swift index df77263b9b..e31e3efd66 100644 --- a/MatrixSDK/Aggregations/LocationSharing/Store/Realm/MXRealmBeacon.swift +++ b/MatrixSDK/Aggregations/LocationSharing/Store/Realm/MXRealmBeacon.swift @@ -15,7 +15,7 @@ // import Foundation -import Realm +@_implementationOnly import Realm class MXRealmBeacon: RLMObject { diff --git a/MatrixSDK/Aggregations/LocationSharing/Store/Realm/MXRealmBeaconInfo.swift b/MatrixSDK/Aggregations/LocationSharing/Store/Realm/MXRealmBeaconInfo.swift index 5774fa584b..0ffc19fcb8 100644 --- a/MatrixSDK/Aggregations/LocationSharing/Store/Realm/MXRealmBeaconInfo.swift +++ b/MatrixSDK/Aggregations/LocationSharing/Store/Realm/MXRealmBeaconInfo.swift @@ -15,7 +15,7 @@ // import Foundation -import Realm +@_implementationOnly import Realm class MXRealmBeaconInfo: RLMObject { diff --git a/MatrixSDK/Aggregations/LocationSharing/Store/Realm/MXRealmBeaconInfoSummary.swift b/MatrixSDK/Aggregations/LocationSharing/Store/Realm/MXRealmBeaconInfoSummary.swift index 74a23a7974..f57a9ede9e 100644 --- a/MatrixSDK/Aggregations/LocationSharing/Store/Realm/MXRealmBeaconInfoSummary.swift +++ b/MatrixSDK/Aggregations/LocationSharing/Store/Realm/MXRealmBeaconInfoSummary.swift @@ -15,7 +15,7 @@ // import Foundation -import Realm +@_implementationOnly import Realm class MXRealmBeaconInfoSummary: RLMObject { diff --git a/MatrixSDK/Background/Crypto/MXBackgroundCryptoV2.swift b/MatrixSDK/Background/Crypto/MXBackgroundCryptoV2.swift index d2db3ede3f..b340bad3f5 100644 --- a/MatrixSDK/Background/Crypto/MXBackgroundCryptoV2.swift +++ b/MatrixSDK/Background/Crypto/MXBackgroundCryptoV2.swift @@ -16,7 +16,7 @@ import Foundation -import MatrixSDKCrypto +@_implementationOnly import MatrixSDKCrypto /// An implementation of `MXBackgroundCrypto` which uses [matrix-rust-sdk](https://github.com/matrix-org/matrix-rust-sdk/tree/main/crates/matrix-sdk-crypto) /// under the hood. diff --git a/MatrixSDK/Crypto/Algorithms/RoomEvent/MXRoomEventDecryption.swift b/MatrixSDK/Crypto/Algorithms/RoomEvent/MXRoomEventDecryption.swift index 39545956db..7ba577845b 100644 --- a/MatrixSDK/Crypto/Algorithms/RoomEvent/MXRoomEventDecryption.swift +++ b/MatrixSDK/Crypto/Algorithms/RoomEvent/MXRoomEventDecryption.swift @@ -15,7 +15,7 @@ // import Foundation -import MatrixSDKCrypto +@_implementationOnly import MatrixSDKCrypto /// Object responsible for decrypting room events and dealing with undecryptable events protocol MXRoomEventDecrypting: Actor { diff --git a/MatrixSDK/Crypto/Algorithms/RoomEvent/MXRoomEventEncryption.swift b/MatrixSDK/Crypto/Algorithms/RoomEvent/MXRoomEventEncryption.swift index fe9fa93268..cd6f91d9e5 100644 --- a/MatrixSDK/Crypto/Algorithms/RoomEvent/MXRoomEventEncryption.swift +++ b/MatrixSDK/Crypto/Algorithms/RoomEvent/MXRoomEventEncryption.swift @@ -15,7 +15,7 @@ // import Foundation -import MatrixSDKCrypto +@_implementationOnly import MatrixSDKCrypto /// Object responsible for encrypting room events and ensuring that room keys are distributed to room members protocol MXRoomEventEncrypting { diff --git a/MatrixSDK/Crypto/CrossSigning/Data/MXCryptoUserIdentityWrapper.swift b/MatrixSDK/Crypto/CrossSigning/Data/MXCryptoUserIdentityWrapper.swift index f444ca2eb2..b325a4ca45 100644 --- a/MatrixSDK/Crypto/CrossSigning/Data/MXCryptoUserIdentityWrapper.swift +++ b/MatrixSDK/Crypto/CrossSigning/Data/MXCryptoUserIdentityWrapper.swift @@ -15,7 +15,7 @@ // import Foundation -import MatrixSDKCrypto +@_implementationOnly import MatrixSDKCrypto /// Convenience wrapper around `MatrixSDKCrypto`'s `UserIdentity` /// which can be used to create `MatrixSDK`s `MXCrossSigningInfo` diff --git a/MatrixSDK/Crypto/CryptoMachine/Extensions/EventEncryptionAlgorithm+String.swift b/MatrixSDK/Crypto/CryptoMachine/Extensions/EventEncryptionAlgorithm+String.swift index 21f5919733..f022605b4c 100644 --- a/MatrixSDK/Crypto/CryptoMachine/Extensions/EventEncryptionAlgorithm+String.swift +++ b/MatrixSDK/Crypto/CryptoMachine/Extensions/EventEncryptionAlgorithm+String.swift @@ -15,7 +15,7 @@ // import Foundation -import MatrixSDKCrypto +@_implementationOnly import MatrixSDKCrypto extension EventEncryptionAlgorithm { enum Error: Swift.Error { diff --git a/MatrixSDK/Crypto/CryptoMachine/Extensions/MXDeviceVerification+LocalTrust.swift b/MatrixSDK/Crypto/CryptoMachine/Extensions/MXDeviceVerification+LocalTrust.swift index e5287ce91d..ffae8e5323 100644 --- a/MatrixSDK/Crypto/CryptoMachine/Extensions/MXDeviceVerification+LocalTrust.swift +++ b/MatrixSDK/Crypto/CryptoMachine/Extensions/MXDeviceVerification+LocalTrust.swift @@ -15,7 +15,7 @@ // import Foundation -import MatrixSDKCrypto +@_implementationOnly import MatrixSDKCrypto extension MXDeviceVerification { var localTrust: LocalTrust { diff --git a/MatrixSDK/Crypto/CryptoMachine/Extensions/MXEventDecryptionResult+DecryptedEvent.swift b/MatrixSDK/Crypto/CryptoMachine/Extensions/MXEventDecryptionResult+DecryptedEvent.swift index b7d0249262..8f715e6bb6 100644 --- a/MatrixSDK/Crypto/CryptoMachine/Extensions/MXEventDecryptionResult+DecryptedEvent.swift +++ b/MatrixSDK/Crypto/CryptoMachine/Extensions/MXEventDecryptionResult+DecryptedEvent.swift @@ -15,7 +15,7 @@ // import Foundation -import MatrixSDKCrypto +@_implementationOnly import MatrixSDKCrypto extension MXEventDecryptionResult { enum Error: Swift.Error { diff --git a/MatrixSDK/Crypto/CryptoMachine/Extensions/MXRoomHistoryVisibility+HistoryVisibility.swift b/MatrixSDK/Crypto/CryptoMachine/Extensions/MXRoomHistoryVisibility+HistoryVisibility.swift index a073deddb6..4a92183a32 100644 --- a/MatrixSDK/Crypto/CryptoMachine/Extensions/MXRoomHistoryVisibility+HistoryVisibility.swift +++ b/MatrixSDK/Crypto/CryptoMachine/Extensions/MXRoomHistoryVisibility+HistoryVisibility.swift @@ -15,7 +15,7 @@ // import Foundation -import MatrixSDKCrypto +@_implementationOnly import MatrixSDKCrypto extension MXRoomHistoryVisibility { var visibility: HistoryVisibility { diff --git a/MatrixSDK/Crypto/CryptoMachine/MXCryptoMachine.swift b/MatrixSDK/Crypto/CryptoMachine/MXCryptoMachine.swift index b92cd55f8a..3999f6cdc8 100644 --- a/MatrixSDK/Crypto/CryptoMachine/MXCryptoMachine.swift +++ b/MatrixSDK/Crypto/CryptoMachine/MXCryptoMachine.swift @@ -15,7 +15,7 @@ // import Foundation -import MatrixSDKCrypto +@_implementationOnly import MatrixSDKCrypto typealias GetRoomAction = (String) -> MXRoom? diff --git a/MatrixSDK/Crypto/CryptoMachine/MXCryptoProtocols.swift b/MatrixSDK/Crypto/CryptoMachine/MXCryptoProtocols.swift index 65dee0f900..2a7e586627 100644 --- a/MatrixSDK/Crypto/CryptoMachine/MXCryptoProtocols.swift +++ b/MatrixSDK/Crypto/CryptoMachine/MXCryptoProtocols.swift @@ -15,7 +15,7 @@ // import Foundation -import MatrixSDKCrypto +@_implementationOnly import MatrixSDKCrypto /// A set of protocols defining the functionality in `MatrixSDKCrypto` and separating them into logical units diff --git a/MatrixSDK/Crypto/CryptoMachine/MXCryptoRequests.swift b/MatrixSDK/Crypto/CryptoMachine/MXCryptoRequests.swift index 5703725543..e4d111aba3 100644 --- a/MatrixSDK/Crypto/CryptoMachine/MXCryptoRequests.swift +++ b/MatrixSDK/Crypto/CryptoMachine/MXCryptoRequests.swift @@ -15,7 +15,7 @@ // import Foundation -import MatrixSDKCrypto +@_implementationOnly import MatrixSDKCrypto /// Convenience class to delegate network requests originating in Rust crypto module /// to the native REST API client diff --git a/MatrixSDK/Crypto/CryptoMachine/MXCryptoSDKLogger.swift b/MatrixSDK/Crypto/CryptoMachine/MXCryptoSDKLogger.swift index 9c84ce7d78..57fff5b941 100644 --- a/MatrixSDK/Crypto/CryptoMachine/MXCryptoSDKLogger.swift +++ b/MatrixSDK/Crypto/CryptoMachine/MXCryptoSDKLogger.swift @@ -15,7 +15,7 @@ // import Foundation -import MatrixSDKCrypto +@_implementationOnly import MatrixSDKCrypto /// Redirects logs originating in `MatrixSDKCrypto` into `MXLog` class MXCryptoSDKLogger: Logger { diff --git a/MatrixSDK/Crypto/Devices/Data/MXCryptoDeviceWrapper.swift b/MatrixSDK/Crypto/Devices/Data/MXCryptoDeviceWrapper.swift index d85be87c63..28c432f35f 100644 --- a/MatrixSDK/Crypto/Devices/Data/MXCryptoDeviceWrapper.swift +++ b/MatrixSDK/Crypto/Devices/Data/MXCryptoDeviceWrapper.swift @@ -15,7 +15,7 @@ // import Foundation -import MatrixSDKCrypto +@_implementationOnly import MatrixSDKCrypto /// Convenience wrapper around `MatrixSDKCrypto`'s `Device` /// which can be used to create `MatrixSDK`s `MXDeviceInfo` diff --git a/MatrixSDK/Crypto/KeyBackup/Engine/MXCryptoKeyBackupEngine.swift b/MatrixSDK/Crypto/KeyBackup/Engine/MXCryptoKeyBackupEngine.swift index c7338e8bdc..8d62a63630 100644 --- a/MatrixSDK/Crypto/KeyBackup/Engine/MXCryptoKeyBackupEngine.swift +++ b/MatrixSDK/Crypto/KeyBackup/Engine/MXCryptoKeyBackupEngine.swift @@ -15,7 +15,7 @@ // import Foundation -import MatrixSDKCrypto +@_implementationOnly import MatrixSDKCrypto class MXCryptoKeyBackupEngine: NSObject, MXKeyBackupEngine { // Batch size chosen arbitrarily, will be moved to CryptoSDK diff --git a/MatrixSDK/Crypto/MXCryptoV2.swift b/MatrixSDK/Crypto/MXCryptoV2.swift index f700e7fd6d..1cf2aee9f9 100644 --- a/MatrixSDK/Crypto/MXCryptoV2.swift +++ b/MatrixSDK/Crypto/MXCryptoV2.swift @@ -15,7 +15,7 @@ // import Foundation -import MatrixSDKCrypto +@_implementationOnly import MatrixSDKCrypto /// An implementation of `MXCrypto` which uses [matrix-rust-sdk](https://github.com/matrix-org/matrix-rust-sdk/tree/main/crates/matrix-sdk-crypto) /// under the hood. diff --git a/MatrixSDK/Crypto/Migration/Data/MXCryptoMigrationStore.swift b/MatrixSDK/Crypto/Migration/Data/MXCryptoMigrationStore.swift index 6465ee00d9..6683ca0a7c 100644 --- a/MatrixSDK/Crypto/Migration/Data/MXCryptoMigrationStore.swift +++ b/MatrixSDK/Crypto/Migration/Data/MXCryptoMigrationStore.swift @@ -15,8 +15,8 @@ // import Foundation -import OLMKit -import MatrixSDKCrypto +@_implementationOnly import OLMKit +@_implementationOnly import MatrixSDKCrypto struct MXCryptoMigrationStore { struct GlobalSettings { diff --git a/MatrixSDK/Crypto/Migration/MXCryptoMigrationV2.swift b/MatrixSDK/Crypto/Migration/MXCryptoMigrationV2.swift index 4368ad68ea..32d96c36a4 100644 --- a/MatrixSDK/Crypto/Migration/MXCryptoMigrationV2.swift +++ b/MatrixSDK/Crypto/Migration/MXCryptoMigrationV2.swift @@ -15,8 +15,8 @@ // import Foundation -import OLMKit -import MatrixSDKCrypto +@_implementationOnly import OLMKit +@_implementationOnly import MatrixSDKCrypto class MXCryptoMigrationV2: NSObject { enum Error: Swift.Error { diff --git a/MatrixSDK/Crypto/Verification/MXKeyVerificationManagerV2.swift b/MatrixSDK/Crypto/Verification/MXKeyVerificationManagerV2.swift index 42291c59a5..e68978e205 100644 --- a/MatrixSDK/Crypto/Verification/MXKeyVerificationManagerV2.swift +++ b/MatrixSDK/Crypto/Verification/MXKeyVerificationManagerV2.swift @@ -6,7 +6,7 @@ // import Foundation -import MatrixSDKCrypto +@_implementationOnly import MatrixSDKCrypto class MXKeyVerificationManagerV2: NSObject, MXKeyVerificationManager { enum Error: Swift.Error { diff --git a/MatrixSDK/Crypto/Verification/Requests/MXKeyVerificationRequestV2.swift b/MatrixSDK/Crypto/Verification/Requests/MXKeyVerificationRequestV2.swift index 24c701fc8d..9f54c3d5a9 100644 --- a/MatrixSDK/Crypto/Verification/Requests/MXKeyVerificationRequestV2.swift +++ b/MatrixSDK/Crypto/Verification/Requests/MXKeyVerificationRequestV2.swift @@ -15,7 +15,7 @@ // import Foundation -import MatrixSDKCrypto +@_implementationOnly import MatrixSDKCrypto /// Verification request originating from `MatrixSDKCrypto` class MXKeyVerificationRequestV2: NSObject, MXKeyVerificationRequest { diff --git a/MatrixSDK/Crypto/Verification/Transactions/QRCode/MXQRCodeTransactionV2.swift b/MatrixSDK/Crypto/Verification/Transactions/QRCode/MXQRCodeTransactionV2.swift index 5974c44354..0ecda52b60 100644 --- a/MatrixSDK/Crypto/Verification/Transactions/QRCode/MXQRCodeTransactionV2.swift +++ b/MatrixSDK/Crypto/Verification/Transactions/QRCode/MXQRCodeTransactionV2.swift @@ -15,7 +15,7 @@ // import Foundation -import MatrixSDKCrypto +@_implementationOnly import MatrixSDKCrypto /// QR transaction originating from `MatrixSDKCrypto` class MXQRCodeTransactionV2: NSObject, MXQRCodeTransaction { diff --git a/MatrixSDK/Crypto/Verification/Transactions/SAS/MXSASTransactionV2.swift b/MatrixSDK/Crypto/Verification/Transactions/SAS/MXSASTransactionV2.swift index f1d42a68d9..4468ae8f19 100644 --- a/MatrixSDK/Crypto/Verification/Transactions/SAS/MXSASTransactionV2.swift +++ b/MatrixSDK/Crypto/Verification/Transactions/SAS/MXSASTransactionV2.swift @@ -15,7 +15,7 @@ // import Foundation -import MatrixSDKCrypto +@_implementationOnly import MatrixSDKCrypto /// SAS transaction originating from `MatrixSDKCrypto` class MXSASTransactionV2: NSObject, MXSASTransaction { diff --git a/MatrixSDK/Utils/Logs/MXAnalyticsDestination.swift b/MatrixSDK/Utils/Logs/MXAnalyticsDestination.swift index e3615dc3ce..601ad5b00e 100644 --- a/MatrixSDK/Utils/Logs/MXAnalyticsDestination.swift +++ b/MatrixSDK/Utils/Logs/MXAnalyticsDestination.swift @@ -6,7 +6,11 @@ // import Foundation +#if IS_TEST_RUN import SwiftyBeaver +#else +@_implementationOnly import SwiftyBeaver +#endif /// SwiftyBeaver log destination that sends errors to analytics tracker class MXAnalyticsDestination: BaseDestination { diff --git a/MatrixSDK/Utils/Logs/MXLog.swift b/MatrixSDK/Utils/Logs/MXLog.swift index c36bbc446d..acfa33bd96 100644 --- a/MatrixSDK/Utils/Logs/MXLog.swift +++ b/MatrixSDK/Utils/Logs/MXLog.swift @@ -15,7 +15,11 @@ // import Foundation +#if IS_TEST_RUN import SwiftyBeaver +#else +@_implementationOnly import SwiftyBeaver +#endif /// Various MXLog configuration options. Used in conjunction with `MXLog.configure()` @objc public class MXLogConfiguration: NSObject { diff --git a/MatrixSDK/Utils/Realm/RLMSupport.swift b/MatrixSDK/Utils/Realm/RLMSupport.swift index ab3c840ab9..e855317795 100644 --- a/MatrixSDK/Utils/Realm/RLMSupport.swift +++ b/MatrixSDK/Utils/Realm/RLMSupport.swift @@ -16,7 +16,7 @@ // //////////////////////////////////////////////////////////////////////////// -import Realm +@_implementationOnly import Realm extension RLMRealm { /** @@ -24,7 +24,7 @@ extension RLMRealm { - see: `+ [RLMRealm schemaVersionAtURL:encryptionKey:error:]` */ - @nonobjc public class func schemaVersion(at url: URL, usingEncryptionKey key: Data? = nil) throws -> UInt64 { + @nonobjc class func schemaVersion(at url: URL, usingEncryptionKey key: Data? = nil) throws -> UInt64 { var error: NSError? let version = __schemaVersion(at: url, encryptionKey: key, error: &error) guard version != RLMNotVersioned else { throw error! } @@ -38,7 +38,7 @@ extension RLMRealm { - see `- [RLMRealm resolveThreadSafeReference:]` */ - @nonobjc public func resolve(reference: RLMThreadSafeReference) -> Confined? { + @nonobjc func resolve(reference: RLMThreadSafeReference) -> Confined? { return __resolve(reference as! RLMThreadSafeReference) as! Confined? } } @@ -49,7 +49,7 @@ extension RLMObject { - see `+ [RLMObject objectsWithPredicate:]` */ - public class func objects(where predicateFormat: String, _ args: CVarArg...) -> RLMResults { + class func objects(where predicateFormat: String, _ args: CVarArg...) -> RLMResults { return objects(with: NSPredicate(format: predicateFormat, arguments: getVaList(args))) as! RLMResults } @@ -58,7 +58,7 @@ extension RLMObject { - see `+ [RLMObject objectsInRealm:withPredicate:]` */ - public class func objects(in realm: RLMRealm, + class func objects(in realm: RLMRealm, where predicateFormat: String, _ args: CVarArg...) -> RLMResults { return objects(in: realm, with: NSPredicate(format: predicateFormat, arguments: getVaList(args))) as! RLMResults @@ -66,7 +66,7 @@ extension RLMObject { } /// A protocol defining iterator support for RLMArray, RLMSet & RLMResults. -public protocol _RLMCollectionIterator { +protocol _RLMCollectionIterator { /** Returns a `RLMCollectionIterator` that yields successive elements in the collection. This enables support for sequence-style enumeration of `RLMObject` subclasses in Swift. @@ -76,43 +76,44 @@ public protocol _RLMCollectionIterator { extension _RLMCollectionIterator where Self: RLMCollection { /// :nodoc: - public func makeIterator() -> RLMCollectionIterator { + func makeIterator() -> RLMCollectionIterator { return RLMCollectionIterator(self) } } /// :nodoc: -public typealias RLMDictionarySingleEntry = (key: String, value: RLMObject) +typealias RLMDictionarySingleEntry = (key: String, value: RLMObject) /// A protocol defining iterator support for RLMDictionary -public protocol _RLMDictionaryIterator { +protocol _RLMDictionaryIterator { /// :nodoc: func makeIterator() -> RLMDictionaryIterator } extension _RLMDictionaryIterator where Self: RLMCollection { /// :nodoc: - public func makeIterator() -> RLMDictionaryIterator { + func makeIterator() -> RLMDictionaryIterator { return RLMDictionaryIterator(self) } } // Sequence conformance for RLMArray, RLMDictionary, RLMSet and RLMResults is provided by RLMCollection's // `makeIterator()` implementation. -extension RLMArray: Sequence, _RLMCollectionIterator { } -extension RLMDictionary: Sequence, _RLMDictionaryIterator {} -extension RLMSet: Sequence, _RLMCollectionIterator {} -extension RLMResults: Sequence, _RLMCollectionIterator {} +// Disabled since `@_implementationOnly`-importing Realm prevents these extensions. Note that this makes this whole file basically useless. +//extension RLMArray: Sequence, _RLMCollectionIterator { } +//extension RLMDictionary: Sequence, _RLMDictionaryIterator {} +//extension RLMSet: Sequence, _RLMCollectionIterator {} +//extension RLMResults: Sequence, _RLMCollectionIterator {} /** This struct enables sequence-style enumeration for RLMObjects in Swift via `RLMCollection.makeIterator` */ -public struct RLMCollectionIterator: IteratorProtocol { +struct RLMCollectionIterator: IteratorProtocol { private var iteratorBase: NSFastEnumerationIterator internal init(_ collection: RLMCollection) { iteratorBase = NSFastEnumerationIterator(collection) } - public mutating func next() -> RLMObject? { + mutating func next() -> RLMObject? { return iteratorBase.next() as! RLMObject? } } @@ -120,7 +121,7 @@ public struct RLMCollectionIterator: IteratorProtocol { /** This struct enables sequence-style enumeration for RLMDictionary in Swift via `RLMDictionary.makeIterator` */ -public struct RLMDictionaryIterator: IteratorProtocol { +struct RLMDictionaryIterator: IteratorProtocol { private var iteratorBase: NSFastEnumerationIterator private let dictionary: RLMDictionary @@ -129,7 +130,7 @@ public struct RLMDictionaryIterator: IteratorProtocol { iteratorBase = NSFastEnumerationIterator(collection) } - public mutating func next() -> RLMDictionarySingleEntry? { + mutating func next() -> RLMDictionarySingleEntry? { let key = iteratorBase.next() if let key = key { return (key: key as Any, value: dictionary[key as AnyObject]) as? RLMDictionarySingleEntry @@ -146,7 +147,7 @@ extension RLMCollection { /** Returns the index of the first object in the collection matching the predicate. */ - public func indexOfObject(where predicateFormat: String, _ args: CVarArg...) -> UInt { + func indexOfObject(where predicateFormat: String, _ args: CVarArg...) -> UInt { guard let index = indexOfObject?(with: NSPredicate(format: predicateFormat, arguments: getVaList(args))) else { fatalError("This RLMCollection does not support indexOfObject(where:)") } @@ -156,14 +157,14 @@ extension RLMCollection { /** Returns all objects matching the given predicate in the collection. */ - public func objects(where predicateFormat: String, _ args: CVarArg...) -> RLMResults { + func objects(where predicateFormat: String, _ args: CVarArg...) -> RLMResults { return objects(with: NSPredicate(format: predicateFormat, arguments: getVaList(args))) as! RLMResults } } extension RLMCollection { /// Allows for subscript support with RLMDictionary. - public subscript(_ key: String) -> AnyObject? { + subscript(_ key: String) -> AnyObject? { get { (self as! RLMDictionary).object(forKey: key as NSString) } diff --git a/MatrixSDK/Utils/Realm/Realm+MatrixSDK.swift b/MatrixSDK/Utils/Realm/Realm+MatrixSDK.swift index 434aa6782d..45e1f18678 100644 --- a/MatrixSDK/Utils/Realm/Realm+MatrixSDK.swift +++ b/MatrixSDK/Utils/Realm/Realm+MatrixSDK.swift @@ -14,7 +14,7 @@ // limitations under the License. // -import Realm +@_implementationOnly import Realm extension RLMRealm { diff --git a/MatrixSDKTests/Crypto/Algorithms/Megolm/MXMegolmDecryptionUnitTests.swift b/MatrixSDKTests/Crypto/Algorithms/Megolm/MXMegolmDecryptionUnitTests.swift index 344f49e0d2..ccd66c9715 100644 --- a/MatrixSDKTests/Crypto/Algorithms/Megolm/MXMegolmDecryptionUnitTests.swift +++ b/MatrixSDKTests/Crypto/Algorithms/Megolm/MXMegolmDecryptionUnitTests.swift @@ -15,7 +15,7 @@ // import Foundation -import MatrixSDKCrypto +@_implementationOnly import MatrixSDKCrypto @testable import MatrixSDK class MXMegolmDecryptionUnitTests: XCTestCase { diff --git a/MatrixSDKTests/Crypto/Algorithms/RoomEvents/MXRoomEventDecryptionUnitTests.swift b/MatrixSDKTests/Crypto/Algorithms/RoomEvents/MXRoomEventDecryptionUnitTests.swift index f2eb25723b..d28626cef2 100644 --- a/MatrixSDKTests/Crypto/Algorithms/RoomEvents/MXRoomEventDecryptionUnitTests.swift +++ b/MatrixSDKTests/Crypto/Algorithms/RoomEvents/MXRoomEventDecryptionUnitTests.swift @@ -17,7 +17,7 @@ import Foundation @testable import MatrixSDK -import MatrixSDKCrypto +@_implementationOnly import MatrixSDKCrypto class MXRoomEventDecryptionUnitTests: XCTestCase { class DecryptorStub: CryptoIdentityStub, MXCryptoRoomEventDecrypting { diff --git a/MatrixSDKTests/Crypto/Algorithms/RoomEvents/MXRoomEventEncryptionUnitTests.swift b/MatrixSDKTests/Crypto/Algorithms/RoomEvents/MXRoomEventEncryptionUnitTests.swift index 8dc292a901..5812aa554b 100644 --- a/MatrixSDKTests/Crypto/Algorithms/RoomEvents/MXRoomEventEncryptionUnitTests.swift +++ b/MatrixSDKTests/Crypto/Algorithms/RoomEvents/MXRoomEventEncryptionUnitTests.swift @@ -16,7 +16,7 @@ import Foundation @testable import MatrixSDK -import MatrixSDKCrypto +@_implementationOnly import MatrixSDKCrypto class MXRoomEventEncryptionUnitTests: XCTestCase { class StateStub: MXRoomState { diff --git a/MatrixSDKTests/Crypto/CrossSigning/Data/MXCrossSigningInfoUnitTests.swift b/MatrixSDKTests/Crypto/CrossSigning/Data/MXCrossSigningInfoUnitTests.swift index 7f01767846..1e630e6a1e 100644 --- a/MatrixSDKTests/Crypto/CrossSigning/Data/MXCrossSigningInfoUnitTests.swift +++ b/MatrixSDKTests/Crypto/CrossSigning/Data/MXCrossSigningInfoUnitTests.swift @@ -17,7 +17,7 @@ import Foundation import XCTest @testable import MatrixSDK -import MatrixSDKCrypto +@_implementationOnly import MatrixSDKCrypto class MXCrossSigningInfoUnitTests: XCTestCase { func makeKey(type: String, user: String) -> MXCrossSigningKey { diff --git a/MatrixSDKTests/Crypto/CrossSigning/MXCrossSigningInfoSourceUnitTests.swift b/MatrixSDKTests/Crypto/CrossSigning/MXCrossSigningInfoSourceUnitTests.swift index 4ed6168f50..1a7261f384 100644 --- a/MatrixSDKTests/Crypto/CrossSigning/MXCrossSigningInfoSourceUnitTests.swift +++ b/MatrixSDKTests/Crypto/CrossSigning/MXCrossSigningInfoSourceUnitTests.swift @@ -17,7 +17,7 @@ import Foundation import XCTest @testable import MatrixSDK -import MatrixSDKCrypto +@_implementationOnly import MatrixSDKCrypto class MXCrossSigningInfoSourceUnitTests: XCTestCase { var cryptoSource: UserIdentitySourceStub! diff --git a/MatrixSDKTests/Crypto/CrossSigning/MXCrossSigningV2UnitTests.swift b/MatrixSDKTests/Crypto/CrossSigning/MXCrossSigningV2UnitTests.swift index fd5fcc2fee..b053232708 100644 --- a/MatrixSDKTests/Crypto/CrossSigning/MXCrossSigningV2UnitTests.swift +++ b/MatrixSDKTests/Crypto/CrossSigning/MXCrossSigningV2UnitTests.swift @@ -17,7 +17,7 @@ import Foundation import XCTest @testable import MatrixSDK -import MatrixSDKCrypto +@_implementationOnly import MatrixSDKCrypto class MXCrossSigningV2UnitTests: XCTestCase { diff --git a/MatrixSDKTests/Crypto/CryptoMachine/DecryptedEvent+Stub.swift b/MatrixSDKTests/Crypto/CryptoMachine/DecryptedEvent+Stub.swift index 5c77c80896..52edc33f3f 100644 --- a/MatrixSDKTests/Crypto/CryptoMachine/DecryptedEvent+Stub.swift +++ b/MatrixSDKTests/Crypto/CryptoMachine/DecryptedEvent+Stub.swift @@ -15,7 +15,7 @@ // import Foundation -import MatrixSDKCrypto +@_implementationOnly import MatrixSDKCrypto extension DecryptedEvent { static func stub( diff --git a/MatrixSDKTests/Crypto/CryptoMachine/Device+Stub.swift b/MatrixSDKTests/Crypto/CryptoMachine/Device+Stub.swift index 2b5cb493ff..edd4ec326a 100644 --- a/MatrixSDKTests/Crypto/CryptoMachine/Device+Stub.swift +++ b/MatrixSDKTests/Crypto/CryptoMachine/Device+Stub.swift @@ -15,7 +15,7 @@ // import Foundation -import MatrixSDKCrypto +@_implementationOnly import MatrixSDKCrypto extension Device { static func stub( diff --git a/MatrixSDKTests/Crypto/CryptoMachine/Extensions/EventEncryptionAlgorithmUnitTests.swift b/MatrixSDKTests/Crypto/CryptoMachine/Extensions/EventEncryptionAlgorithmUnitTests.swift index 8bcae0ddf4..f26a068c15 100644 --- a/MatrixSDKTests/Crypto/CryptoMachine/Extensions/EventEncryptionAlgorithmUnitTests.swift +++ b/MatrixSDKTests/Crypto/CryptoMachine/Extensions/EventEncryptionAlgorithmUnitTests.swift @@ -16,7 +16,7 @@ import Foundation import XCTest -import MatrixSDKCrypto +@_implementationOnly import MatrixSDKCrypto @testable import MatrixSDK class EventEncryptionAlgorithmUnitTests: XCTestCase { diff --git a/MatrixSDKTests/Crypto/CryptoMachine/MXCryptoMachineUnitTests.swift b/MatrixSDKTests/Crypto/CryptoMachine/MXCryptoMachineUnitTests.swift index 0ef92ebcf3..48308b2dce 100644 --- a/MatrixSDKTests/Crypto/CryptoMachine/MXCryptoMachineUnitTests.swift +++ b/MatrixSDKTests/Crypto/CryptoMachine/MXCryptoMachineUnitTests.swift @@ -15,7 +15,7 @@ // import Foundation -import MatrixSDKCrypto +@_implementationOnly import MatrixSDKCrypto @testable import MatrixSDK class MXCryptoMachineUnitTests: XCTestCase { diff --git a/MatrixSDKTests/Crypto/CryptoMachine/MXCryptoProtocolStubs.swift b/MatrixSDKTests/Crypto/CryptoMachine/MXCryptoProtocolStubs.swift index 570e35d392..073559d956 100644 --- a/MatrixSDKTests/Crypto/CryptoMachine/MXCryptoProtocolStubs.swift +++ b/MatrixSDKTests/Crypto/CryptoMachine/MXCryptoProtocolStubs.swift @@ -16,7 +16,7 @@ import Foundation @testable import MatrixSDK -@testable import MatrixSDKCrypto +@_implementationOnly @testable import MatrixSDKCrypto class CryptoIdentityStub: MXCryptoIdentity { var userId: String = "Alice" diff --git a/MatrixSDKTests/Crypto/CryptoMachine/MXCryptoRequestsUnitTests.swift b/MatrixSDKTests/Crypto/CryptoMachine/MXCryptoRequestsUnitTests.swift index 16d697fe4a..384d9346d8 100644 --- a/MatrixSDKTests/Crypto/CryptoMachine/MXCryptoRequestsUnitTests.swift +++ b/MatrixSDKTests/Crypto/CryptoMachine/MXCryptoRequestsUnitTests.swift @@ -16,7 +16,7 @@ import Foundation @testable import MatrixSDK -import MatrixSDKCrypto +@_implementationOnly import MatrixSDKCrypto class MXCryptoRequestsUnitTests: XCTestCase { func test_canCreateToDeviceRequest() { diff --git a/MatrixSDKTests/Crypto/Data/Store/MXMemoryCryptoStore.swift b/MatrixSDKTests/Crypto/Data/Store/MXMemoryCryptoStore.swift index 2b1c240c56..97c53ba0e0 100644 --- a/MatrixSDKTests/Crypto/Data/Store/MXMemoryCryptoStore.swift +++ b/MatrixSDKTests/Crypto/Data/Store/MXMemoryCryptoStore.swift @@ -15,7 +15,7 @@ // import Foundation -import OLMKit +@_implementationOnly import OLMKit public class MXMemoryCryptoStore: NSObject, MXCryptoStore { diff --git a/MatrixSDKTests/Crypto/Devices/Data/MXDeviceInfoUnitTests.swift b/MatrixSDKTests/Crypto/Devices/Data/MXDeviceInfoUnitTests.swift index abdf3ba911..44e0c1a5cd 100644 --- a/MatrixSDKTests/Crypto/Devices/Data/MXDeviceInfoUnitTests.swift +++ b/MatrixSDKTests/Crypto/Devices/Data/MXDeviceInfoUnitTests.swift @@ -17,7 +17,7 @@ import Foundation import XCTest @testable import MatrixSDK -import MatrixSDKCrypto +@_implementationOnly import MatrixSDKCrypto class MXDeviceInfoUnitTests: XCTestCase { func test_canCreateInfo_withDevice() { diff --git a/MatrixSDKTests/Crypto/Devices/MXDeviceInfoSourceUnitTests.swift b/MatrixSDKTests/Crypto/Devices/MXDeviceInfoSourceUnitTests.swift index 163ce55228..1a65e652d2 100644 --- a/MatrixSDKTests/Crypto/Devices/MXDeviceInfoSourceUnitTests.swift +++ b/MatrixSDKTests/Crypto/Devices/MXDeviceInfoSourceUnitTests.swift @@ -17,7 +17,7 @@ import Foundation import XCTest @testable import MatrixSDK -import MatrixSDKCrypto +@_implementationOnly import MatrixSDKCrypto class MXDeviceInfoSourceUnitTests: XCTestCase { var cryptoSource: DevicesSourceStub! diff --git a/MatrixSDKTests/Crypto/KeyBackup/Engine/MXCryptoKeyBackupEngineUnitTests.swift b/MatrixSDKTests/Crypto/KeyBackup/Engine/MXCryptoKeyBackupEngineUnitTests.swift index ba9271fe0b..196c8ac7d1 100644 --- a/MatrixSDKTests/Crypto/KeyBackup/Engine/MXCryptoKeyBackupEngineUnitTests.swift +++ b/MatrixSDKTests/Crypto/KeyBackup/Engine/MXCryptoKeyBackupEngineUnitTests.swift @@ -16,7 +16,7 @@ import Foundation @testable import MatrixSDK -import MatrixSDKCrypto +@_implementationOnly import MatrixSDKCrypto class MXCryptoKeyBackupEngineUnitTests: XCTestCase { actor DecryptorSpy: MXRoomEventDecrypting { diff --git a/MatrixSDKTests/Crypto/Migration/Data/MXCryptoMigrationStoreUnitTests.swift b/MatrixSDKTests/Crypto/Migration/Data/MXCryptoMigrationStoreUnitTests.swift index 1197fc26ff..09998e6cdb 100644 --- a/MatrixSDKTests/Crypto/Migration/Data/MXCryptoMigrationStoreUnitTests.swift +++ b/MatrixSDKTests/Crypto/Migration/Data/MXCryptoMigrationStoreUnitTests.swift @@ -16,7 +16,7 @@ import Foundation import XCTest -import MatrixSDKCrypto +@_implementationOnly import MatrixSDKCrypto @testable import MatrixSDK class MXCryptoMigrationStoreUnitTests: XCTestCase { diff --git a/MatrixSDKTests/Crypto/Trust/MXTrustLevelSourceUnitTests.swift b/MatrixSDKTests/Crypto/Trust/MXTrustLevelSourceUnitTests.swift index dc53091a9f..04e704c52c 100644 --- a/MatrixSDKTests/Crypto/Trust/MXTrustLevelSourceUnitTests.swift +++ b/MatrixSDKTests/Crypto/Trust/MXTrustLevelSourceUnitTests.swift @@ -17,7 +17,7 @@ import Foundation import XCTest @testable import MatrixSDK -import MatrixSDKCrypto +@_implementationOnly import MatrixSDKCrypto class MXTrustLevelSourceUnitTests: XCTestCase { var userIdentitySource: UserIdentitySourceStub! diff --git a/MatrixSDKTests/Crypto/Verification/Requests/MXKeyVerificationRequestV2UnitTests.swift b/MatrixSDKTests/Crypto/Verification/Requests/MXKeyVerificationRequestV2UnitTests.swift index 4854950d36..9fef0c06b2 100644 --- a/MatrixSDKTests/Crypto/Verification/Requests/MXKeyVerificationRequestV2UnitTests.swift +++ b/MatrixSDKTests/Crypto/Verification/Requests/MXKeyVerificationRequestV2UnitTests.swift @@ -16,7 +16,7 @@ import Foundation import XCTest -import MatrixSDKCrypto +@_implementationOnly import MatrixSDKCrypto @testable import MatrixSDK class MXKeyVerificationRequestV2UnitTests: XCTestCase { diff --git a/MatrixSDKTests/Crypto/Verification/Requests/VerificationRequestStub.swift b/MatrixSDKTests/Crypto/Verification/Requests/VerificationRequestStub.swift index 730eaeb6d9..5a48049af1 100644 --- a/MatrixSDKTests/Crypto/Verification/Requests/VerificationRequestStub.swift +++ b/MatrixSDKTests/Crypto/Verification/Requests/VerificationRequestStub.swift @@ -16,7 +16,7 @@ import Foundation -import MatrixSDKCrypto +@_implementationOnly import MatrixSDKCrypto class VerificationRequestStub: VerificationRequestProtocol { diff --git a/MatrixSDKTests/Crypto/Verification/Transactions/QRCode/MXQRCodeTransactionV2UnitTests.swift b/MatrixSDKTests/Crypto/Verification/Transactions/QRCode/MXQRCodeTransactionV2UnitTests.swift index 61bf513aeb..c3fc00dde1 100644 --- a/MatrixSDKTests/Crypto/Verification/Transactions/QRCode/MXQRCodeTransactionV2UnitTests.swift +++ b/MatrixSDKTests/Crypto/Verification/Transactions/QRCode/MXQRCodeTransactionV2UnitTests.swift @@ -16,7 +16,7 @@ import Foundation import XCTest -import MatrixSDKCrypto +@_implementationOnly import MatrixSDKCrypto @testable import MatrixSDK class MXQRCodeTransactionV2UnitTests: XCTestCase { diff --git a/MatrixSDKTests/Crypto/Verification/Transactions/QRCode/QrCodeStub.swift b/MatrixSDKTests/Crypto/Verification/Transactions/QRCode/QrCodeStub.swift index 15fe3df825..29c1c88b3b 100644 --- a/MatrixSDKTests/Crypto/Verification/Transactions/QRCode/QrCodeStub.swift +++ b/MatrixSDKTests/Crypto/Verification/Transactions/QRCode/QrCodeStub.swift @@ -16,7 +16,7 @@ import Foundation -import MatrixSDKCrypto +@_implementationOnly import MatrixSDKCrypto struct QrCodeStub: QrCodeProtocol { private let _otherUserId: String diff --git a/MatrixSDKTests/Crypto/Verification/Transactions/SAS/MXSASTransactionV2UnitTests.swift b/MatrixSDKTests/Crypto/Verification/Transactions/SAS/MXSASTransactionV2UnitTests.swift index fa45ff94a2..6aa81859ba 100644 --- a/MatrixSDKTests/Crypto/Verification/Transactions/SAS/MXSASTransactionV2UnitTests.swift +++ b/MatrixSDKTests/Crypto/Verification/Transactions/SAS/MXSASTransactionV2UnitTests.swift @@ -16,7 +16,7 @@ import Foundation import XCTest -import MatrixSDKCrypto +@_implementationOnly import MatrixSDKCrypto @testable import MatrixSDK class MXSASTransactionV2UnitTests: XCTestCase { diff --git a/MatrixSDKTests/Crypto/Verification/Transactions/SAS/SasStub.swift b/MatrixSDKTests/Crypto/Verification/Transactions/SAS/SasStub.swift index ed81168ef1..1a738ecc44 100644 --- a/MatrixSDKTests/Crypto/Verification/Transactions/SAS/SasStub.swift +++ b/MatrixSDKTests/Crypto/Verification/Transactions/SAS/SasStub.swift @@ -16,7 +16,7 @@ import Foundation -import MatrixSDKCrypto +@_implementationOnly import MatrixSDKCrypto struct SasStub: SasProtocol { diff --git a/changelog.d/sdk-1497.build b/changelog.d/sdk-1497.build new file mode 100644 index 0000000000..2f7fc863ad --- /dev/null +++ b/changelog.d/sdk-1497.build @@ -0,0 +1 @@ +Build: Makes distributing the SDK as a binary Swift package possible again. Contributed by Christopher Kobusch (@Topheee). From 09abbfa9d42be704a6539d05e9086fa8716012e6 Mon Sep 17 00:00:00 2001 From: Christopher Kobusch Date: Sat, 23 Sep 2023 22:54:07 +0200 Subject: [PATCH 2/3] add @_implementationOnly to new files --- MatrixSDK/Crypto/Dehydration/DehydrationService.swift | 2 +- .../Crypto/Migration/LegacyRealmStore/LegacyRealmStore.swift | 2 +- .../Crypto/Migration/MXCryptoMigrationV2UnitTests.swift | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/MatrixSDK/Crypto/Dehydration/DehydrationService.swift b/MatrixSDK/Crypto/Dehydration/DehydrationService.swift index 6f4ccb9c77..0c2902a28d 100644 --- a/MatrixSDK/Crypto/Dehydration/DehydrationService.swift +++ b/MatrixSDK/Crypto/Dehydration/DehydrationService.swift @@ -15,7 +15,7 @@ // import Foundation -import MatrixSDKCrypto +@_implementationOnly import MatrixSDKCrypto enum DehydrationServiceError: Error { case failedDehydration(Error) diff --git a/MatrixSDKTests/Crypto/Migration/LegacyRealmStore/LegacyRealmStore.swift b/MatrixSDKTests/Crypto/Migration/LegacyRealmStore/LegacyRealmStore.swift index 4510c3a782..4c337d57ff 100644 --- a/MatrixSDKTests/Crypto/Migration/LegacyRealmStore/LegacyRealmStore.swift +++ b/MatrixSDKTests/Crypto/Migration/LegacyRealmStore/LegacyRealmStore.swift @@ -15,7 +15,7 @@ // import Foundation -import Realm +@_implementationOnly import Realm /// Class simulating legacy crypto store associated with the now-deprecated native crypto module /// diff --git a/MatrixSDKTests/Crypto/Migration/MXCryptoMigrationV2UnitTests.swift b/MatrixSDKTests/Crypto/Migration/MXCryptoMigrationV2UnitTests.swift index 88b5cfc676..ddea7c1834 100644 --- a/MatrixSDKTests/Crypto/Migration/MXCryptoMigrationV2UnitTests.swift +++ b/MatrixSDKTests/Crypto/Migration/MXCryptoMigrationV2UnitTests.swift @@ -15,7 +15,7 @@ // import Foundation -import MatrixSDKCrypto +@_implementationOnly import MatrixSDKCrypto @testable import MatrixSDK class MXCryptoMigrationV2UnitTests: XCTestCase { From 4c39591283a6779598cb5d2af3bac6184bac53ed Mon Sep 17 00:00:00 2001 From: Christopher Kobusch Date: Mon, 25 May 2026 14:23:28 +0200 Subject: [PATCH 3/3] fix AFNetworking inet6 in Podfile --- MatrixSDK/ContentScan/PKMessageWrapper.swift | 2 +- .../Data/MXCryptoMigrationStore.swift | 234 -------- .../Migration/MXCryptoMigrationV2.swift | 222 ------- .../SecretStorage/MXCryptoSecretStoreV2.swift | 2 +- .../Megolm/MXMegolmDecryptionUnitTests.swift | 328 ----------- .../Data/Store/MXMemoryCryptoStore.swift | 547 ------------------ .../MXCryptoMigrationStoreUnitTests.swift | 284 --------- .../LegacyRealmStore/LegacyRealmStore.swift | 162 ------ .../MXCryptoMigrationV2UnitTests.swift | 167 ------ Podfile | 23 + Podfile.lock | 2 +- 11 files changed, 26 insertions(+), 1947 deletions(-) delete mode 100644 MatrixSDK/Crypto/Migration/Data/MXCryptoMigrationStore.swift delete mode 100644 MatrixSDK/Crypto/Migration/MXCryptoMigrationV2.swift delete mode 100644 MatrixSDKTests/Crypto/Algorithms/Megolm/MXMegolmDecryptionUnitTests.swift delete mode 100644 MatrixSDKTests/Crypto/Data/Store/MXMemoryCryptoStore.swift delete mode 100644 MatrixSDKTests/Crypto/Migration/Data/MXCryptoMigrationStoreUnitTests.swift delete mode 100644 MatrixSDKTests/Crypto/Migration/LegacyRealmStore/LegacyRealmStore.swift delete mode 100644 MatrixSDKTests/Crypto/Migration/MXCryptoMigrationV2UnitTests.swift diff --git a/MatrixSDK/ContentScan/PKMessageWrapper.swift b/MatrixSDK/ContentScan/PKMessageWrapper.swift index 05aa716b0f..7c31613bd6 100644 --- a/MatrixSDK/ContentScan/PKMessageWrapper.swift +++ b/MatrixSDK/ContentScan/PKMessageWrapper.swift @@ -15,7 +15,7 @@ // import Foundation -import MatrixSDKCrypto +@_implementationOnly import MatrixSDKCrypto @objc public class PKMessageWrapper: NSObject { private let pkMessage: PkMessage diff --git a/MatrixSDK/Crypto/Migration/Data/MXCryptoMigrationStore.swift b/MatrixSDK/Crypto/Migration/Data/MXCryptoMigrationStore.swift deleted file mode 100644 index 0db0770235..0000000000 --- a/MatrixSDK/Crypto/Migration/Data/MXCryptoMigrationStore.swift +++ /dev/null @@ -1,234 +0,0 @@ -// -// Copyright 2023 The Matrix.org Foundation C.I.C -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// - -import Foundation -@_implementationOnly import OLMKit -@_implementationOnly import MatrixSDKCrypto - -struct MXCryptoMigrationStore { - struct GlobalSettings { - let onlyAllowTrustedDevices: Bool - } - - enum Error: Swift.Error { - case missingAccount - } - - let legacyStore: MXCryptoStore - - var userId: String? { - legacyStore.userId() - } - - var deviceId: String? { - legacyStore.deviceId() - } - - var olmSessionCount: UInt { - legacyStore.sessionsCount() - } - - var megolmSessionCount: UInt { - legacyStore.inboundGroupSessionsCount(false) - } - - var globalSettings: GlobalSettings { - .init(onlyAllowTrustedDevices: legacyStore.globalBlacklistUnverifiedDevices) - } - - func extractData(with pickleKey: Data) throws -> MigrationData { - return .init( - account: try pickledAccount(pickleKey: pickleKey), - sessions: [], // Sessions are extracted in batches separately - inboundGroupSessions: [], // Group sessions are extracted in batches separately - pickleKey: [UInt8](pickleKey), - backupVersion: legacyStore.backupVersion, - backupRecoveryKey: backupRecoveryKey(), - crossSigning: crossSigning(), - trackedUsers: trackedUsers(), - roomSettings: extractRoomSettings() - ) - } - - func extractSessions( - with pickleKey: Data, - batchSize: Int, - callback: @escaping ([PickledSession], Double) -> Void - ) { - legacyStore.enumerateSessions(by: batchSize) { sessions, progress in - let pickled: [PickledSession] = sessions?.compactMap { - do { - return try PickledSession(session: $0, pickleKey: pickleKey) - } catch { - MXLog.error("[MXCryptoMigrationStore] cannot extract olm session", context: error) - return nil - } - } ?? [] - callback(pickled, progress) - } - } - - func extractGroupSessions( - with pickleKey: Data, - batchSize: Int, - callback: @escaping ([PickledInboundGroupSession], Double) -> Void - ) { - legacyStore.enumerateInboundGroupSessions(by: batchSize) { sessions, backedUp, progress in - let pickled: [PickledInboundGroupSession] = sessions?.compactMap { - do { - return try PickledInboundGroupSession( - session: $0, - pickleKey: pickleKey, - backedUp: backedUp?.contains($0.session.sessionIdentifier()) == true - ) - } catch { - MXLog.error("[MXCryptoMigrationStore] cannot extract megolm session", context: error) - return nil - } - } ?? [] - callback(pickled, progress) - } - } - - func extractRoomSettings() -> [String: RoomSettings] { - return legacyStore - .roomSettings() - .reduce(into: [String: RoomSettings]()) { dict, item in - do { - let algorithm = try EventEncryptionAlgorithm(string: item.algorithm) - dict[item.roomId] = RoomSettings( - algorithm: algorithm, - onlyAllowTrustedDevices: item.blacklistUnverifiedDevices - ) - } catch { - MXLog.error("[MXCryptoMigrationStore] cannot extract room settings", context: error) - } - } - } - - // MARK: - Private - - private func pickledAccount(pickleKey: Data) throws -> PickledAccount { - guard - let userId = legacyStore.userId(), - let deviceId = legacyStore.deviceId(), - let account = legacyStore.account() - else { - throw Error.missingAccount - } - return try PickledAccount( - userId: userId, - deviceId: deviceId, - account: account, - pickleKey: pickleKey - ) - } - - private func backupRecoveryKey() -> String? { - guard let privateKey = secret(for: MXSecretId.keyBackup) else { - return nil - } - - let data = MXBase64Tools.data(fromBase64: privateKey) - return MXRecoveryKey.encode(data) - } - - private func crossSigning() -> CrossSigningKeyExport { - let master = secret(for: MXSecretId.crossSigningMaster) - let selfSigning = secret(for: MXSecretId.crossSigningSelfSigning) - let userSigning = secret(for: MXSecretId.crossSigningUserSigning) - - return .init( - masterKey: master, - selfSigningKey: selfSigning, - userSigningKey: userSigning - ) - } - - private func trackedUsers() -> [String] { - var users = [String]() - for (user, status) in legacyStore.deviceTrackingStatus() ?? [:] { - if status != 0 { - users.append(user) - } - } - return users - } - - private func secret(for secretId: Unmanaged) -> String? { - return legacyStore.secret(withSecretId: secretId.takeUnretainedValue() as String) - } -} - -private extension PickledAccount { - init( - userId: String, - deviceId: String, - account: OLMAccount, - pickleKey: Data - ) throws { - let pickle = try account.serializeData(withKey: pickleKey) - self.init( - userId: userId, - deviceId: deviceId, - pickle: pickle, - shared: true, // Not yet implemented - uploadedSignedKeyCount: 50 // Not yet implemented - ) - } -} - -private extension PickledSession { - init(session: MXOlmSession, pickleKey: Data) throws { - let pickle = try session.session.serializeData(withKey: pickleKey) - let time = "\(Int(session.lastReceivedMessageTs))" - - self.init( - pickle: pickle, - senderKey: session.deviceKey, - createdUsingFallbackKey: false, // Not yet implemented - creationTime: time, // Not yet implemented - lastUseTime: time - ) - } -} - -private extension PickledInboundGroupSession { - enum Error: Swift.Error { - case invalidSession - } - - init(session: MXOlmInboundGroupSession, pickleKey: Data, backedUp: Bool) throws { - guard - let senderKey = session.senderKey, - let roomId = session.roomId - else { - throw Error.invalidSession - } - - let pickle = try session.session.serializeData(withKey: pickleKey) - - self.init( - pickle: pickle, - senderKey: senderKey, - signingKey: session.keysClaimed ?? [:], - roomId: roomId, - forwardingChains: session.forwardingCurve25519KeyChain ?? [], - imported: session.isUntrusted, - backedUp: backedUp - ) - } -} diff --git a/MatrixSDK/Crypto/Migration/MXCryptoMigrationV2.swift b/MatrixSDK/Crypto/Migration/MXCryptoMigrationV2.swift deleted file mode 100644 index 32d96c36a4..0000000000 --- a/MatrixSDK/Crypto/Migration/MXCryptoMigrationV2.swift +++ /dev/null @@ -1,222 +0,0 @@ -// -// Copyright 2022 The Matrix.org Foundation C.I.C -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// - -import Foundation -@_implementationOnly import OLMKit -@_implementationOnly import MatrixSDKCrypto - -class MXCryptoMigrationV2: NSObject { - enum Error: Swift.Error { - case missingCredentials - case unknownPickleKey - } - - private static let SessionBatchSize = 1000 - - private let legacyDevice: MXOlmDevice - private let store: MXCryptoMigrationStore - private let log = MXNamedLog(name: "MXCryptoMachineMigration") - - init(legacyStore: MXCryptoStore) { - MXCryptoSDKLogger.shared.log(logLine: "Starting logs") - - // We need to create legacy OlmDevice which sets itself internally as pickle key delegate - // Once established we can get the pickleKey from OLMKit which is used to decrypt and migrate - // the legacy store data - legacyDevice = MXOlmDevice(store: legacyStore) - store = .init(legacyStore: legacyStore) - } - - func migrateAllData(updateProgress: @escaping (Double) -> Void) throws { - log.debug("Starting migration") - - let startDate = Date() - updateProgress(0) - - let pickleKey = try legacyPickleKey() - let data = try store.extractData(with: pickleKey) - - let url = try MXCryptoMachineStore.storeURL(for: data.account.userId) - let passphrase = try MXCryptoMachineStore.storePassphrase() - - if FileManager.default.fileExists(atPath: url.path) { - try FileManager.default.removeItem(at: url) - } - - let details = """ - Migration summary - - user id : \(data.account.userId) - - device id : \(data.account.deviceId) - - olm_sessions : \(store.olmSessionCount) - - megolm_sessions : \(store.megolmSessionCount) - - backup_key : \(data.backupRecoveryKey != nil ? "true" : "false") - - master_key : \(data.crossSigning.masterKey != nil ? "true" : "false") - - user_signing_key : \(data.crossSigning.userSigningKey != nil ? "true" : "false") - - self_signing_key : \(data.crossSigning.selfSigningKey != nil ? "true" : "false") - - tracked_users : \(data.trackedUsers.count) - - room_settings : \(data.roomSettings.count) - - global_settings : \(store.globalSettings) - """ - log.debug(details) - - try migrate( - data: data, - path: url.path, - passphrase: passphrase, - progressListener: self - ) - - log.debug("Migrating olm sessions in batches") - - // How much does migration of olm vs megolm sessions contribute to the overall progress - let totalSessions = store.olmSessionCount + store.megolmSessionCount - let olmToMegolmRatio = totalSessions > 0 ? Double(store.olmSessionCount)/Double(totalSessions) : 0 - - store.extractSessions(with: pickleKey, batchSize: Self.SessionBatchSize) { [weak self] batch, progress in - updateProgress(progress * olmToMegolmRatio) - - do { - try self?.migrateSessionsBatch( - data: data, - sessions: batch, - url: url, - passphrase: passphrase - ) - } catch { - self?.log.error("Error migrating some sessions", context: error) - } - } - - log.debug("Migrating megolm sessions in batches") - - store.extractGroupSessions(with: pickleKey, batchSize: Self.SessionBatchSize) { [weak self] batch, progress in - updateProgress(olmToMegolmRatio + progress * (1 - olmToMegolmRatio)) - - do { - try self?.migrateSessionsBatch( - data: data, - inboundGroupSessions: batch, - url: url, - passphrase: passphrase - ) - } catch { - self?.log.error("Error migrating some sessions", context: error) - } - } - - log.debug("Migrating global settings") - try migrateGlobalSettings( - userId: data.account.userId, - deviceId: data.account.deviceId, - url: url, - passphrase: passphrase - ) - - let duration = Date().timeIntervalSince(startDate) * 1000 - log.debug("Migration completed in \(duration) ms") - updateProgress(1) - } - - func migrateRoomAndGlobalSettingsOnly(updateProgress: @escaping (Double) -> Void) throws { - guard let userId = store.userId, let deviceId = store.deviceId else { - throw Error.missingCredentials - } - - let url = try MXCryptoMachineStore.storeURL(for: userId) - let passphrase = try MXCryptoMachineStore.storePassphrase() - let settings = store.extractRoomSettings() - - let details = """ - Settings migration summary - - user id : \(userId) - - device id : \(deviceId) - - room_settings : \(settings.count) - - global_settings : \(store.globalSettings) - """ - log.debug(details) - updateProgress(0) - - try migrateRoomSettings( - roomSettings: settings, - path: url.path, - passphrase: passphrase - ) - - log.debug("Migrating global settings") - try migrateGlobalSettings( - userId: userId, - deviceId: deviceId, - url: url, - passphrase: passphrase - ) - - log.debug("Migration completed") - updateProgress(1) - } - - private func legacyPickleKey() throws -> Data { - guard let key = OLMKit.sharedInstance().pickleKeyDelegate?.pickleKey() else { - throw Error.unknownPickleKey - } - return key - } - - private func migrateSessionsBatch( - data: MigrationData, - sessions: [PickledSession] = [], - inboundGroupSessions: [PickledInboundGroupSession] = [], - url: URL, - passphrase: String - ) throws { - try migrateSessions( - data: .init( - userId: data.account.userId, - deviceId: data.account.deviceId, - curve25519Key: legacyDevice.deviceCurve25519Key, - ed25519Key: legacyDevice.deviceEd25519Key, - sessions: sessions, - inboundGroupSessions: inboundGroupSessions, - pickleKey: data.pickleKey - ), - path: url.path, - passphrase: passphrase, - progressListener: self - ) - } - - private func migrateGlobalSettings( - userId: String, - deviceId: String, - url: URL, - passphrase: String - ) throws { - let machine = try OlmMachine( - userId: userId, - deviceId: deviceId, - path: url.path, - passphrase: passphrase - ) - - let onlyTrusted = store.globalSettings.onlyAllowTrustedDevices - try machine.setOnlyAllowTrustedDevices(onlyAllowTrustedDevices: onlyTrusted) - } -} - -extension MXCryptoMigrationV2: ProgressListener { - func onProgress(progress: Int32, total: Int32) { - // Progress loggged manually - } -} diff --git a/MatrixSDK/Crypto/SecretStorage/MXCryptoSecretStoreV2.swift b/MatrixSDK/Crypto/SecretStorage/MXCryptoSecretStoreV2.swift index 7e2e9774b4..3fcb7899e7 100644 --- a/MatrixSDK/Crypto/SecretStorage/MXCryptoSecretStoreV2.swift +++ b/MatrixSDK/Crypto/SecretStorage/MXCryptoSecretStoreV2.swift @@ -15,7 +15,7 @@ // import Foundation -import MatrixSDKCrypto +@_implementationOnly import MatrixSDKCrypto enum MXCryptoError: Error { case secretDoesNotMatch diff --git a/MatrixSDKTests/Crypto/Algorithms/Megolm/MXMegolmDecryptionUnitTests.swift b/MatrixSDKTests/Crypto/Algorithms/Megolm/MXMegolmDecryptionUnitTests.swift deleted file mode 100644 index ccd66c9715..0000000000 --- a/MatrixSDKTests/Crypto/Algorithms/Megolm/MXMegolmDecryptionUnitTests.swift +++ /dev/null @@ -1,328 +0,0 @@ -// -// Copyright 2022 The Matrix.org Foundation C.I.C -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// - -import Foundation -@_implementationOnly import MatrixSDKCrypto -@testable import MatrixSDK - -class MXMegolmDecryptionUnitTests: XCTestCase { - /// Spy session used to assert on the results of the test - struct SpySession: Equatable { - let sharedHistory: Bool - } - - /// Spy olm device used to collect spy sessions for the purpose of test assertions - class DeviceStub: MXOlmDevice { - var sessions: [SpySession] = [] - - override func addInboundGroupSession( - _ sessionId: String!, - sessionKey: String!, - roomId: String!, - senderKey: String!, - forwardingCurve25519KeyChain: [String]!, - keysClaimed: [String : String]!, - exportFormat: Bool, - sharedHistory: Bool, - untrusted: Bool - ) -> Bool { - sessions.append( - .init(sharedHistory: sharedHistory) - ) - return true - } - - var stubbedResult: MXDecryptionResult? - - override func decryptGroupMessage( - _ body: String!, - isEditEvent: Bool, - roomId: String!, - inTimeline timeline: String!, - sessionId: String!, - senderKey: String! - ) throws -> MXDecryptionResult { - stubbedResult ?? MXDecryptionResult() - } - } - - /// Stub of the session which returns a preconfigured summary of rooms - class SessionStub: MXSession { - var historyVisibility: String = kMXRoomHistoryVisibilityWorldReadable - - override func room(withRoomId roomId: String!) -> MXRoom! { - return MXRoom(roomId: roomId, andMatrixSession: self) - } - - override func roomSummary(withRoomId roomId: String!) -> MXRoomSummary! { - let summary = MXRoomSummary() - summary.historyVisibility = historyVisibility - return summary - } - } - - class CryptoStoreStub: MXRealmCryptoStore { - var sessions: [String: MXOlmInboundGroupSession] = [:] - - override func inboundGroupSession( - withId sessionId: String!, - andSenderKey senderKey: String! - ) -> MXOlmInboundGroupSession! { - return sessions["\(sessionId!)-\(senderKey!)"] - } - } - - /// Stub of crypto which connects various other stubbed objects (device, session) - class CryptoStub: MXLegacyCrypto { - private let device: MXOlmDevice - private let cryptoStore: MXCryptoStore - private let session: MXSession - private let devices: MXDeviceList - - init(device: MXOlmDevice, store: MXCryptoStore, session: MXSession, devices: MXDeviceList) { - self.device = device - self.cryptoStore = store - self.session = session - self.devices = devices - } - - override var olmDevice: MXOlmDevice! { - return device - } - - override var cryptoQueue: DispatchQueue! { - return DispatchQueue.main - } - - override var store: MXCryptoStore! { - return cryptoStore - } - - override var mxSession: MXSession! { - return session - } - - override var deviceList: MXDeviceList! { - return devices - } - - override func trustLevel(forUser userId: String) -> MXUserTrustLevel { - return MXUserTrustLevel(crossSigningVerified: true, locallyVerified: true) - } - } - - class DeviceListStub: MXDeviceList { - var stubbedDevices = [String: Device]() - override func device(withIdentityKey senderKey: String!, andAlgorithm algorithm: String!) -> MXDeviceInfo! { - guard algorithm != nil, let senderKey = senderKey, let device = stubbedDevices[senderKey] else { - return nil - } - - return .init(device: .init(device: device)) - } - } - - let roomId1 = "ABC" - let roomId2 = "XYZ" - let sessionId1 = "123" - let sessionId2 = "999" - let senderKey = "456" - - var device: DeviceStub! - var store: CryptoStoreStub! - var session: SessionStub! - var crypto: CryptoStub! - var devicesList: DeviceListStub! - var decryption: MXMegolmDecryption! - - override func setUp() { - super.setUp() - - device = DeviceStub() - store = CryptoStoreStub() - session = SessionStub() - devicesList = DeviceListStub() - crypto = CryptoStub(device: device, store: store, session: session, devices: devicesList) - decryption = MXMegolmDecryption(crypto: crypto) - } - - // Ensure that `sharedHistory` is added to an inbound session only - // if explicitly set by the room key event - func test_onRoomKeyEvent_addsSessionSharedHistoryFromEvent() { - MXSDKOptions.sharedInstance().enableRoomSharedHistoryOnInvite = true - - // Configure a set of event values and outcome values where `sharedHistory` - // on the final session is set to whatever value the event has, defaulting - // to false if not specified. This is even if the room's history is currently - // set to shared or world readable - let eventToExpectation: [(Bool?, Bool)] = [ - (nil, false), - (false, false), - (true, true) - ] - session.historyVisibility = kMXRoomHistoryVisibilityWorldReadable - - for (eventValue, expectedValue) in eventToExpectation { - let event = MXEvent.roomKeyFixture( - sharedHistory: eventValue - ) - device.sessions = [] - - decryption.onRoomKeyEvent(event) - - XCTAssertEqual(device.sessions.count, 1) - XCTAssertEqual(device.sessions.first, SpySession(sharedHistory: expectedValue)) - } - } - - // Ensure that checking for the presence of shared history, only session - // with matching roomId is queried - func test_hasSharedHistory_queriesSessionWithMatchingRoomId() { - // Parametrize the test via a configuration and a set of cases - // with expected outcome - struct Configuration { - let sharedHistory: Bool - let sessionId: String - let roomId: String - } - let allCases = [ - - // Mismatched session id -> does not have keys - ( - Configuration( - sharedHistory: true, - sessionId: sessionId2, - roomId: roomId1 - ), - false - ), - - // Mismatched room id -> does not have keys - ( - Configuration( - sharedHistory: true, - sessionId: sessionId1, - roomId: roomId2 - ), - false - ), - - // Matching session and room id but not sharing history -> does not have keys - ( - Configuration( - sharedHistory: false, - sessionId: sessionId1, - roomId: roomId1 - ), - false - ), - - // Matching session and room id and sharing history -> has keys - ( - Configuration( - sharedHistory: true, - sessionId: sessionId1, - roomId: roomId1 - ), - true - ) - ] - - for (config, expectedValue) in allCases { - let session = MXOlmInboundGroupSession() - session.sharedHistory = config.sharedHistory - session.roomId = config.roomId - - store.sessions = [ - "\(config.sessionId)-\(senderKey)": session - ] - - let hasSharedHistory = decryption.hasSharedHistory(forRoomId: roomId1, sessionId: sessionId1, senderKey: senderKey) - XCTAssertEqual(hasSharedHistory, expectedValue) - } - } - - func test_decryptEvent_untrustedResult() { - let event = MXEvent.encryptedFixture() - device.stubbedResult = MXDecryptionResult() - device.stubbedResult?.senderKey = "ABCD" - - devicesList.stubbedDevices = [ - "ABCD": Device.stub( - locallyTrusted: false, - crossSigningTrusted: true - ) - ] - - device.stubbedResult?.isUntrusted = true - let result1 = decryption.decryptEvent(event, inTimeline: nil) - XCTAssertEqual(result1?.decoration.color, .grey) - - device.stubbedResult?.isUntrusted = false - let result2 = decryption.decryptEvent(event, inTimeline: nil) - XCTAssertEqual(result2?.decoration.color, MXEventDecryptionDecorationColor.none) - } - - func test_decryptEvent_untrustedDevice() { - let event = MXEvent.encryptedFixture() - device.stubbedResult = MXDecryptionResult() - device.stubbedResult?.senderKey = "XYZ" - - devicesList.stubbedDevices = [ - "XYZ": Device.stub( - locallyTrusted: false, - crossSigningTrusted: false - ) - ] - let result1 = decryption.decryptEvent(event, inTimeline: nil) - XCTAssertEqual(result1?.decoration.color, .red) - - devicesList.stubbedDevices = [ - "XYZ": Device.stub( - locallyTrusted: false, - crossSigningTrusted: true - ) - ] - let result2 = decryption.decryptEvent(event, inTimeline: nil) - XCTAssertEqual(result2?.decoration.color, MXEventDecryptionDecorationColor.none) - } - - func test_decryptEvent_unknownDevice() { - let invalidKey = "123" - let validKey = "456" - - let event = MXEvent.encryptedFixture() - device.stubbedResult = MXDecryptionResult() - device.stubbedResult?.senderKey = validKey - - let stub = Device.stub( - locallyTrusted: true, - crossSigningTrusted: true - ) - - devicesList.stubbedDevices = [ - invalidKey: stub - ] - let result1 = decryption.decryptEvent(event, inTimeline: nil) - XCTAssertEqual(result1?.decoration.color, .red) - - devicesList.stubbedDevices = [ - validKey: stub - ] - let result2 = decryption.decryptEvent(event, inTimeline: nil) - XCTAssertEqual(result2?.decoration.color, MXEventDecryptionDecorationColor.none) - } -} diff --git a/MatrixSDKTests/Crypto/Data/Store/MXMemoryCryptoStore.swift b/MatrixSDKTests/Crypto/Data/Store/MXMemoryCryptoStore.swift deleted file mode 100644 index 97c53ba0e0..0000000000 --- a/MatrixSDKTests/Crypto/Data/Store/MXMemoryCryptoStore.swift +++ /dev/null @@ -1,547 +0,0 @@ -// -// Copyright 2022 The Matrix.org Foundation C.I.C -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// - -import Foundation -@_implementationOnly import OLMKit - -public class MXMemoryCryptoStore: NSObject, MXCryptoStore { - - private static var stores: [MXCredentials: MXMemoryCryptoStore] = [:] - - private let credentials: MXCredentials - private var storeAccount: Account? - private var devices: [String: [MXDeviceInfo]] = [:] - private var algorithms: [String: RoomAlgorithm] = [:] - private var inboundSessions: [InboundSession] = [] - private var outboundSessions: [String: MXOlmOutboundGroupSession] = [:] - private var secrets: [String: String] = [:] - private var incomingRoomKeyRequestsMap: [String: MXIncomingRoomKeyRequest] = [:] - private var outgoingRoomKeyRequests: [String: MXOutgoingRoomKeyRequest] = [:] - private var olmSessions: [OlmSessionMapKey: MXOlmSession] = [:] - private var crossSigningKeysMap: [String: MXCrossSigningInfo] = [:] - private var sharedOutboundSessions: [SharedOutboundSession] = [] - - // MARK: - MXCryptoStore - - public required init!(credentials: MXCredentials!) { - self.credentials = credentials - storeAccount = Account() - storeAccount?.userId = credentials.userId - storeAccount?.deviceId = credentials.deviceId - storeAccount?.cryptoVersion = MXCryptoVersion(rawValue: MXCryptoVersion.versionCount.rawValue - 1) ?? .versionUndefined - super.init() - } - - public static func hasData(for credentials: MXCredentials!) -> Bool { - stores[credentials] != nil - } - - public static func createStore(with credentials: MXCredentials!) -> Self! { - if let existingStore = stores[credentials] as? Self { - return existingStore - } - if let newStore = Self(credentials: credentials) { - stores[credentials] = newStore - return newStore - } - return nil - } - - public static func delete(with credentials: MXCredentials!) { - stores.removeValue(forKey: credentials) - } - - public static func deleteAllStores() { - stores.removeAll() - } - - public static func deleteReadonlyStore(with credentials: MXCredentials!) { - // no-op - } - - // MARK: - User ID - - public func userId() -> String! { - storeAccount?.userId - } - - // MARK: - Device ID - - public func storeDeviceId(_ deviceId: String!) { - storeAccount?.deviceId = deviceId - } - - public func deviceId() -> String! { - storeAccount?.deviceId - } - - // MARK: - Account - - public func setAccount(_ account: OLMAccount!) { - storeAccount?.olmAccount = account - } - - public func account() -> OLMAccount! { - storeAccount?.olmAccount - } - - public func performAccountOperation(_ block: ((OLMAccount?) -> Void)!) { - block?(storeAccount?.olmAccount) - } - - // MARK: - Device Sync Token - - public func storeDeviceSyncToken(_ deviceSyncToken: String!) { - storeAccount?.deviceSyncToken = deviceSyncToken - } - - public func deviceSyncToken() -> String! { - storeAccount?.deviceSyncToken - } - - // MARK: - Devices - - public func storeDevice(forUser userId: String!, device: MXDeviceInfo!) { - if devices[userId] == nil { - devices[userId] = [] - } - devices[userId]?.append(device) - } - - public func device(withDeviceId deviceId: String!, forUser userId: String!) -> MXDeviceInfo! { - devices[userId]?.first { $0.deviceId == deviceId } - } - - public func device(withIdentityKey identityKey: String!) -> MXDeviceInfo! { - Array(devices.values).flatMap { $0 }.first { $0.identityKey == identityKey } - } - - public func storeDevices(forUser userId: String!, devices: [String : MXDeviceInfo]!) { - if self.devices[userId] != nil { - // Reset all previously stored devices for this user - self.devices.removeValue(forKey: userId) - } - - self.devices[userId] = Array(devices.values) - } - - public func devices(forUser userId: String!) -> [String : MXDeviceInfo]! { - let devices = devices[userId] ?? [] - - var result: [String: MXDeviceInfo] = [:] - - for device in devices { - result[device.deviceId] = device - } - - return result - } - - // MARK: - Device Tracking Status - - public func deviceTrackingStatus() -> [String : NSNumber]! { - storeAccount?.deviceTrackingStatus - } - - public func storeDeviceTrackingStatus(_ statusMap: [String : NSNumber]!) { - storeAccount?.deviceTrackingStatus = statusMap - } - - // MARK: - Cross Signing Keys - - public func storeCrossSigningKeys(_ crossSigningInfo: MXCrossSigningInfo!) { - crossSigningKeysMap[crossSigningInfo.userId] = crossSigningInfo - } - - public func crossSigningKeys(forUser userId: String!) -> MXCrossSigningInfo! { - crossSigningKeysMap[userId] - } - - public func crossSigningKeys() -> [MXCrossSigningInfo]! { - Array(crossSigningKeysMap.values) - } - - // MARK: - Room Algorithm - - public func storeAlgorithm(forRoom roomId: String!, algorithm: String!) { - algorithms[roomId] = RoomAlgorithm(algorithm: algorithm) - } - - public func algorithm(forRoom roomId: String!) -> String! { - algorithms[roomId]?.algorithm - } - - // MARK: - Room Settings - - public func roomSettings() -> [MXRoomSettings]! { - return algorithms.compactMap { roomId, item in - do { - return try MXRoomSettings( - roomId: roomId, - algorithm: item.algorithm, - blacklistUnverifiedDevices: item.blacklistUnverifiedDevices - ) - } catch { - MXLog.debug("[MXMemoryCryptoStore] roomSettings: Failed creating algorithm", context: error) - return nil - } - } - } - - // MARK: - OLM Session - - public func store(_ session: MXOlmSession!) { - let key = OlmSessionMapKey(sessionId: session.session.sessionIdentifier(), deviceKey: session.deviceKey) - olmSessions[key] = session - } - - public func session(withDevice deviceKey: String!, andSessionId sessionId: String!) -> MXOlmSession! { - let key = OlmSessionMapKey(sessionId: sessionId, deviceKey: deviceKey) - return olmSessions[key] - } - - public func performSessionOperation(withDevice deviceKey: String!, andSessionId sessionId: String!, block: ((MXOlmSession?) -> Void)!) { - let session = session(withDevice: deviceKey, andSessionId: sessionId) - block?(session) - } - - public func sessions(withDevice deviceKey: String!) -> [MXOlmSession]! { - Array(olmSessions.filter { $0.key.deviceKey == deviceKey }.values) - } - - public func enumerateSessions(by batchSize: Int, block: (([MXOlmSession]?, Double) -> Void)!) { - block(Array(olmSessions.values), 1) - } - - public func sessionsCount() -> UInt { - UInt(olmSessions.count) - } - - // MARK: - Inbound Group Sessions - - public func store(_ sessions: [MXOlmInboundGroupSession]!) { - inboundSessions.append(contentsOf: sessions.map { InboundSession(session: $0) } ) - } - - public func inboundGroupSession(withId sessionId: String!, andSenderKey senderKey: String!) -> MXOlmInboundGroupSession! { - inboundSessions.first { $0.sessionId == sessionId && $0.session.senderKey == senderKey }?.session - } - - public func performSessionOperationWithGroupSession(withId sessionId: String!, senderKey: String!, block: ((MXOlmInboundGroupSession?) -> Void)!) { - let session = inboundGroupSession(withId: sessionId, andSenderKey: senderKey) - block?(session) - } - - public func inboundGroupSessions() -> [MXOlmInboundGroupSession]! { - inboundSessions.map { $0.session } - } - - public func enumerateInboundGroupSessions(by batchSize: Int, block: (([MXOlmInboundGroupSession]?, Set?, Double) -> Void)!) { - let backedUp = inboundSessions.filter { $0.backedUp }.map(\.sessionId) - block(inboundGroupSessions(), Set(backedUp), 1) - } - - public func inboundGroupSessions(withSessionId sessionId: String!) -> [MXOlmInboundGroupSession]! { - inboundSessions.filter { $0.sessionId == sessionId }.map { $0.session } - } - - public func removeInboundGroupSession(withId sessionId: String!, andSenderKey senderKey: String!) { - inboundSessions.removeAll { $0.sessionId == sessionId && $0.session.senderKey == senderKey } - } - - // MARK: - Outbound Group Sessions - - public func store(_ session: OLMOutboundGroupSession!, withRoomId roomId: String!) -> MXOlmOutboundGroupSession! { - let creationTime: TimeInterval - - if let existingSession = outboundSessions[roomId], - existingSession.sessionId == session.sessionIdentifier() { - // Update the existing one - creationTime = existingSession.creationTime - } else { - creationTime = Date().timeIntervalSince1970 - } - - if let newSession = MXOlmOutboundGroupSession(session: session, roomId: roomId, creationTime: creationTime) { - outboundSessions[roomId] = newSession - return newSession - } - - return nil - } - - public func outboundGroupSession(withRoomId roomId: String!) -> MXOlmOutboundGroupSession! { - outboundSessions[roomId] - } - - public func outboundGroupSessions() -> [MXOlmOutboundGroupSession]! { - Array(outboundSessions.values) - } - - public func removeOutboundGroupSession(withRoomId roomId: String!) { - outboundSessions.removeValue(forKey: roomId) - } - - // MARK: - Shared Devices - - public func storeSharedDevices(_ devices: MXUsersDevicesMap!, messageIndex: UInt, forOutboundGroupSessionInRoomWithId roomId: String!, sessionId: String!) { - for userId in devices.userIds() { - for deviceId in devices.deviceIds(forUser: userId) { - guard let device = device(withDeviceId: deviceId, forUser: userId) else { - continue - } - - let session = SharedOutboundSession(roomId: roomId, sessionId: sessionId, device: device, messageIndex: messageIndex) - sharedOutboundSessions.append(session) - } - } - } - - public func sharedDevicesForOutboundGroupSessionInRoom(withId roomId: String!, sessionId: String!) -> MXUsersDevicesMap! { - let result = MXUsersDevicesMap() - - let sessions = sharedOutboundSessions.filter { $0.roomId == roomId && $0.sessionId == sessionId } - - for session in sessions { - result.setObject(NSNumber(value: session.messageIndex), - forUser: session.device.userId, - andDevice: session.device.deviceId) - } - - return result - } - - public func messageIndexForSharedDeviceInRoom(withId roomId: String!, sessionId: String!, userId: String!, deviceId: String!) -> NSNumber! { - guard let index = sharedOutboundSessions.first(where: { $0.roomId == roomId - && $0.sessionId == sessionId - && $0.device.deviceId == deviceId })?.messageIndex else { - return nil - } - return NSNumber(value: index) - } - - // MARK: - Backup Markers - - public var backupVersion: String! { - get { - storeAccount?.backupVersion - } set { - storeAccount?.backupVersion = newValue - } - } - - public func resetBackupMarkers() { - inboundSessions.forEach { $0.backedUp = false } - } - - public func markBackupDone(for sessions: [MXOlmInboundGroupSession]!) { - for session in sessions { - inboundSessions.filter({ $0.sessionId == session.session.sessionIdentifier() }).forEach { $0.backedUp = true } - } - } - - public func inboundGroupSessions(toBackup limit: UInt) -> [MXOlmInboundGroupSession]! { - let toBackup = inboundSessions.filter { !$0.backedUp } - if toBackup.isEmpty { - return [] - } - let toDrop = toBackup.count > limit ? toBackup.count - Int(limit) : 0 - return toBackup.dropLast(toDrop).map { $0.session } - } - - public func inboundGroupSessionsCount(_ onlyBackedUp: Bool) -> UInt { - UInt(onlyBackedUp ? inboundSessions.filter { $0.backedUp }.count : inboundSessions.count) - } - - // MARK: - Outgoing Room Key Requests - - public func outgoingRoomKeyRequest(withRequestBody requestBody: [AnyHashable : Any]!) -> MXOutgoingRoomKeyRequest! { - outgoingRoomKeyRequests.first(where: { NSDictionary(dictionary: $1.requestBody).isEqual(to: requestBody) })?.value - } - - public func outgoingRoomKeyRequest(with state: MXRoomKeyRequestState) -> MXOutgoingRoomKeyRequest! { - outgoingRoomKeyRequests.first(where: { $0.value.state == state })?.value - } - - public func allOutgoingRoomKeyRequests(with state: MXRoomKeyRequestState) -> [MXOutgoingRoomKeyRequest]! { - Array(outgoingRoomKeyRequests.filter { $1.state == state }.values) - } - - public func allOutgoingRoomKeyRequests(withRoomId roomId: String!, sessionId: String!, algorithm: String!, senderKey: String!) -> [MXOutgoingRoomKeyRequest]! { - Array(outgoingRoomKeyRequests.filter { - $1.roomId == roomId - && $1.sessionId == sessionId - && $1.algorithm == algorithm - && $1.senderKey == senderKey - }.values) - } - - public func store(_ request: MXOutgoingRoomKeyRequest!) { - outgoingRoomKeyRequests[request.requestId] = request - } - - public func update(_ request: MXOutgoingRoomKeyRequest!) { - outgoingRoomKeyRequests[request.requestId] = request - } - - public func deleteOutgoingRoomKeyRequest(withRequestId requestId: String!) { - outgoingRoomKeyRequests.removeValue(forKey: requestId) - } - - // MARK: - Incoming Room Key Requests - - public func store(_ request: MXIncomingRoomKeyRequest!) { - incomingRoomKeyRequestsMap[request.requestId] = request - } - - public func deleteIncomingRoomKeyRequest(_ requestId: String!, fromUser userId: String!, andDevice deviceId: String!) { - let toBeRemoved = incomingRoomKeyRequestsMap.filter { $1.requestId == requestId && $1.userId == userId && $1.deviceId == deviceId } - for identifier in toBeRemoved { - incomingRoomKeyRequestsMap.removeValue(forKey: identifier.key) - } - } - - public func incomingRoomKeyRequest(withRequestId requestId: String!, fromUser userId: String!, andDevice deviceId: String!) -> MXIncomingRoomKeyRequest! { - incomingRoomKeyRequestsMap.first(where: { $1.requestId == requestId && $1.userId == userId && $1.deviceId == deviceId })?.value - } - - public func incomingRoomKeyRequests() -> MXUsersDevicesMap! { - let result = MXUsersDevicesMap() - - for request in incomingRoomKeyRequestsMap { - if let requests = result.object(forDevice: request.value.deviceId, forUser: request.value.userId) { - requests.add(request.value) - } else { - let requests = NSMutableArray(object: request.value) - result.setObject(requests, forUser: request.value.userId, andDevice: request.value.deviceId) - } - } - - return result as? MXUsersDevicesMap - } - - // MARK: - Secrets - - public func storeSecret(_ secret: String, withSecretId secretId: String) { - secrets[secretId] = secret - } - - public func hasSecret(withSecretId secretId: String) -> Bool { - return secrets[secretId] != nil - } - - public func secret(withSecretId secretId: String) -> String? { - secrets[secretId] - } - - public func deleteSecret(withSecretId secretId: String) { - secrets.removeValue(forKey: secretId) - } - - // MARK: - Blacklist Unverified Devices - - public var globalBlacklistUnverifiedDevices: Bool { - get { - storeAccount?.globalBlacklistUnverifiedDevices ?? false - } set { - storeAccount?.globalBlacklistUnverifiedDevices = newValue - } - } - - public func blacklistUnverifiedDevices(inRoom roomId: String!) -> Bool { - algorithms[roomId]?.blacklistUnverifiedDevices ?? false - } - - public func storeBlacklistUnverifiedDevices(inRoom roomId: String!, blacklist: Bool) { - if let algorithm = algorithms[roomId] { - algorithm.blacklistUnverifiedDevices = blacklist - } else { - algorithms[roomId] = RoomAlgorithm(algorithm: nil, blacklistUnverifiedDevices: blacklist) - } - } - - // MARK: - Crypto Version - - public var cryptoVersion: MXCryptoVersion { - get { - storeAccount?.cryptoVersion ?? .versionUndefined - } set { - storeAccount?.cryptoVersion = newValue - } - } - -} - -// MARK: - Models - -// MARK: InboundSession - -private class InboundSession { - let session: MXOlmInboundGroupSession - var backedUp: Bool - - var sessionId: String { - session.session.sessionIdentifier() - } - - init(session: MXOlmInboundGroupSession, - backedUp: Bool = false) { - self.session = session - self.backedUp = backedUp - } -} - -// MARK: OlmSessionMapKey - -private struct OlmSessionMapKey: Hashable { - let sessionId: String - let deviceKey: String -} - -// MARK: Account - -private struct Account { - var userId: String? - var deviceId: String? - var cryptoVersion: MXCryptoVersion = .versionUndefined - var deviceSyncToken: String? - var olmAccount: OLMAccount? - var backupVersion: String? - var globalBlacklistUnverifiedDevices: Bool = false - var deviceTrackingStatus: [String : NSNumber]? -} - -// MARK: SharedOutboundSession - -private struct SharedOutboundSession { - let roomId: String - let sessionId: String - let device: MXDeviceInfo - let messageIndex: UInt -} - -// MARK: RoomAlgorithm - -private class RoomAlgorithm { - let algorithm: String? - var blacklistUnverifiedDevices: Bool - - init(algorithm: String?, - blacklistUnverifiedDevices: Bool = false) { - self.algorithm = algorithm - self.blacklistUnverifiedDevices = blacklistUnverifiedDevices - } -} diff --git a/MatrixSDKTests/Crypto/Migration/Data/MXCryptoMigrationStoreUnitTests.swift b/MatrixSDKTests/Crypto/Migration/Data/MXCryptoMigrationStoreUnitTests.swift deleted file mode 100644 index 09998e6cdb..0000000000 --- a/MatrixSDKTests/Crypto/Migration/Data/MXCryptoMigrationStoreUnitTests.swift +++ /dev/null @@ -1,284 +0,0 @@ -// -// Copyright 2023 The Matrix.org Foundation C.I.C -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// - -import Foundation -import XCTest -@_implementationOnly import MatrixSDKCrypto -@testable import MatrixSDK - -class MXCryptoMigrationStoreUnitTests: XCTestCase { - - var pickleKey: Data! - var legacyStore: MXMemoryCryptoStore! - var store: MXCryptoMigrationStore! - - override func setUp() { - pickleKey = "1234".data(using: .ascii)! - - let credentials = MXCredentials() - credentials.userId = "Alice" - credentials.deviceId = "ABC" - - legacyStore = MXMemoryCryptoStore(credentials: credentials) - legacyStore.setAccount(OLMAccount(newAccount: ())) - - store = .init(legacyStore: legacyStore) - } - - // MARK: - Helpers - - func extractData(pickleKey: Data? = nil) throws -> MigrationData { - try store.extractData(with: pickleKey ?? self.pickleKey) - } - - func extractSessions(pickleKey: Data? = nil) throws -> [PickledSession] { - var sessions = [PickledSession]() - store.extractSessions(with: pickleKey ?? self.pickleKey, batchSize: .max) { batch, progress in - sessions += batch - } - return sessions - } - - func extractGroupSessions(pickleKey: Data? = nil) throws -> [PickledInboundGroupSession] { - var sessions = [PickledInboundGroupSession]() - store.extractGroupSessions(with: pickleKey ?? self.pickleKey, batchSize: .max) { batch, progress in - sessions += batch - } - return sessions - } - - @discardableResult - func storeGroupSession( - roomId: String = "ABC", - senderKey: String? = "Bob", - isUntrusted: Bool = false, - backedUp: Bool = false - ) -> MXOlmInboundGroupSession { - let device = MXOlmDevice(store: legacyStore)! - let outbound = device.createOutboundGroupSessionForRoom(withRoomId: roomId) - - let session = MXOlmInboundGroupSession(sessionKey: outbound!.sessionKey)! - session.senderKey = senderKey - session.roomId = roomId - session.keysClaimed = ["A": "1"] - session.isUntrusted = isUntrusted - legacyStore.store([session]) - - if backedUp { - legacyStore.markBackupDone(for: [session]) - } - return session - } - - func storeSecret(_ secret: String, secretId: Unmanaged) { - legacyStore.storeSecret(secret, withSecretId: secretId.takeUnretainedValue() as String) - } - - // MARK: - Tests - - func test_credentials() { - XCTAssertEqual(store.userId, "Alice") - XCTAssertEqual(store.deviceId, "ABC") - } - - func test_trustedSettings() { - legacyStore.globalBlacklistUnverifiedDevices = false - XCTAssertFalse(store.globalSettings.onlyAllowTrustedDevices) - - legacyStore.globalBlacklistUnverifiedDevices = true - XCTAssertTrue(store.globalSettings.onlyAllowTrustedDevices) - } - - func test_missingAccountFailsExtraction() { - legacyStore.setAccount(nil) - do { - _ = try extractData() - XCTFail("Should not succeed") - } catch MXCryptoMigrationStore.Error.missingAccount { - XCTAssert(true) - } catch { - XCTFail("Unknown error") - } - } - - func test_extractsAccount() throws { - let legacyPickle = try legacyStore.account().serializeData(withKey: pickleKey) - - let account = try extractData().account - - XCTAssertEqual(account.userId, "Alice") - XCTAssertEqual(account.deviceId, "ABC") - XCTAssertEqual(account.pickle, legacyPickle) - XCTAssertTrue(account.shared) - XCTAssertEqual(account.uploadedSignedKeyCount, 50) - } - - func test_extractsSession() throws { - let session = MXOlmSession(olmSession: OLMSession(), deviceKey: "XYZ") - session.lastReceivedMessageTs = 123 - legacyStore.store(session) - let pickle = try session.session.serializeData(withKey: pickleKey) - - // There are no sessions in the general migration data - XCTAssertTrue(try extractData().sessions.isEmpty) - - // But they can be accumulated by batching - let sessions = try extractSessions() - XCTAssertEqual(sessions.count, 1) - XCTAssertEqual(sessions[0].pickle, pickle) - XCTAssertEqual(sessions[0].senderKey, "XYZ") - XCTAssertFalse(sessions[0].createdUsingFallbackKey) - XCTAssertEqual(sessions[0].creationTime, "123") - XCTAssertEqual(sessions[0].lastUseTime, "123") - } - - func test_extractsMultipleSessionsInBatches() throws { - for i in 0 ..< 12 { - legacyStore.store(MXOlmSession(olmSession: OLMSession(), deviceKey: "\(i)")) - } - - // There are no sessions in the general migration data - XCTAssertTrue(try extractData().sessions.isEmpty) - // But they can be accumulated by batching - let sessions = try extractSessions() - XCTAssertEqual(sessions.count, 12) - } - - func test_extractsGroupSession() throws { - let session = storeGroupSession(roomId: "abcd") - let pickle = try session.session.serializeData(withKey: pickleKey) - - // There are no sessions in the general migration data - XCTAssertTrue(try extractData().inboundGroupSessions.isEmpty) - - // But they can be accumulated by batching - let sessions = try extractGroupSessions() - XCTAssertEqual(sessions.count, 1) - XCTAssertEqual(sessions[0].pickle, pickle) - XCTAssertEqual(sessions[0].senderKey, "Bob") - XCTAssertEqual(sessions[0].signingKey, ["A": "1"]) - XCTAssertEqual(sessions[0].roomId, "abcd") - XCTAssertEqual(sessions[0].forwardingChains, []) - } - - func test_extractsOnlyValidGroupSessions() throws { - for i in 0 ..< 4 { - let isValid = i % 2 == 0 - storeGroupSession(senderKey: isValid ? "Bob" : nil) - } - - // There are no sessions in the general migration data - XCTAssertTrue(try extractData().inboundGroupSessions.isEmpty) - - // But they can be accumulated by batching - let sessions = try extractGroupSessions() - XCTAssertEqual(sessions.count, 2) - } - - func test_extractsImportedGroupSessionStatus() throws { - storeGroupSession(isUntrusted: true) - storeGroupSession(isUntrusted: false) - storeGroupSession(isUntrusted: false) - - let sessions = try extractGroupSessions() - - XCTAssertEqual(sessions.count, 3) - XCTAssertTrue(sessions[0].imported) - XCTAssertFalse(sessions[1].imported) - XCTAssertFalse(sessions[1].imported) - } - - func test_extractsBackedUpGroupSessionStatus() throws { - storeGroupSession(backedUp: false) - storeGroupSession(backedUp: true) - storeGroupSession(backedUp: false) - - let sessions = try extractGroupSessions() - - XCTAssertEqual(sessions.count, 3) - XCTAssertFalse(sessions[0].backedUp) - XCTAssertTrue(sessions[1].backedUp) - XCTAssertFalse(sessions[2].backedUp) - } - - func test_extractsBackupVersion() throws { - legacyStore.backupVersion = "5" - let version = try extractData().backupVersion - XCTAssertEqual(version, "5") - } - - func test_extractsBackupRecoveryKey() throws { - let privateKey = "ABCD" - storeSecret(privateKey, secretId: MXSecretId.keyBackup) - - let key = try extractData().backupRecoveryKey - - let recovery = MXRecoveryKey.encode(MXBase64Tools.data(fromBase64: privateKey)) - XCTAssertNotNil(key) - XCTAssertNotNil(recovery) - XCTAssertEqual(key, recovery) - } - - func test_extractsPickeKey() throws { - let pickleKey = "some key".data(using: .ascii)! - let key = try extractData(pickleKey: pickleKey).pickleKey - XCTAssertEqual(key, [UInt8](pickleKey)) - } - - func test_extractsCrossSigning() throws { - storeSecret("MASTER", secretId: MXSecretId.crossSigningMaster) - storeSecret("USER", secretId: MXSecretId.crossSigningUserSigning) - storeSecret("SELF", secretId: MXSecretId.crossSigningSelfSigning) - - let crossSigning = try extractData().crossSigning - - XCTAssertEqual(crossSigning.masterKey, "MASTER") - XCTAssertEqual(crossSigning.userSigningKey, "USER") - XCTAssertEqual(crossSigning.selfSigningKey, "SELF") - } - - func test_extractsOnlyTrackedUsers() throws { - let users = [ - "Alice": MXDeviceTrackingStatusNotTracked, - "Bob": MXDeviceTrackingStatusPendingDownload, - "Carol": MXDeviceTrackingStatusDownloadInProgress, - "Dave": MXDeviceTrackingStatusUpToDate, - ].mapValues { NSNumber(value: $0.rawValue) } - legacyStore.storeDeviceTrackingStatus(users) - - let trackedUsers = try extractData().trackedUsers - - XCTAssertEqual(Set(trackedUsers), ["Bob", "Carol", "Dave"]) - } - - func test_extractsRoomSettings() throws { - legacyStore.storeAlgorithm(forRoom: "room1", algorithm: kMXCryptoOlmAlgorithm) - legacyStore.storeBlacklistUnverifiedDevices(inRoom: "room1", blacklist: true) - - legacyStore.storeAlgorithm(forRoom: "room2", algorithm: kMXCryptoMegolmAlgorithm) - legacyStore.storeBlacklistUnverifiedDevices(inRoom: "room2", blacklist: false) - - legacyStore.storeAlgorithm(forRoom: "room3", algorithm: "something invalid") - legacyStore.storeBlacklistUnverifiedDevices(inRoom: "room3", blacklist: true) - - let settings = try extractData().roomSettings - - XCTAssertEqual(settings, [ - "room1": RoomSettings(algorithm: .olmV1Curve25519AesSha2, onlyAllowTrustedDevices: true), - "room2": RoomSettings(algorithm: .megolmV1AesSha2, onlyAllowTrustedDevices: false), - ]) - } -} diff --git a/MatrixSDKTests/Crypto/Migration/LegacyRealmStore/LegacyRealmStore.swift b/MatrixSDKTests/Crypto/Migration/LegacyRealmStore/LegacyRealmStore.swift deleted file mode 100644 index 4c337d57ff..0000000000 --- a/MatrixSDKTests/Crypto/Migration/LegacyRealmStore/LegacyRealmStore.swift +++ /dev/null @@ -1,162 +0,0 @@ -// -// Copyright 2023 The Matrix.org Foundation C.I.C -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// - -import Foundation -@_implementationOnly import Realm - -/// Class simulating legacy crypto store associated with the now-deprecated native crypto module -/// -/// It has access to several pre-made realm files with legacy accounts that can be loaded -/// and migrated to current crypto module -class LegacyRealmStore { - enum Error: Swift.Error { - case missingDependencies - } - - /// A few pre-created accounts with hardcoded details - enum Account { - - /// Realm store with crypto version `version2`, used for migration testing - case version2 - - /// Realm store with crypto version `deprecated1`, used for migration testing - case deprecated1 - - /// Realm store with crypto version `deprecated3`, used for migration testing - case deprecated3 - - /// Realm store with a verified accounts used to test cross-signing migration - case verified - - /// Realm store with an unverified accounts used to test cross-signing migration - case unverified - - /// File name for the associated account file - var fileName: String { - switch self { - case .version2: - return "legacy_version2_account" - case .deprecated1: - return "legacy_deprecated1_account" - case .deprecated3: - return "legacy_deprecated3_account" - case .verified: - return "legacy_verified_account" - case .unverified: - return "legacy_unverified_account" - } - } - - /// Hardcoded room id matching a given account - var roomId: String? { - switch self { - case .version2: - return nil - case .deprecated1: - return nil - case .deprecated3: - return nil - case .verified: - return "!QUWVMCIhJqIqTMLxof:x.y.z" - case .unverified: - return nil - } - } - - /// Hardcoded account credentials matching a given account - var credentials: MXCredentials { - let cred = MXCredentials() - switch self { - case .version2: - cred.userId = "@mxalice-54aeab93-b4b2-4edf-85e1-bc0dbbb710ee:x.y.z" - cred.deviceId = "NAHEYWCBBM" - case .deprecated1: - cred.userId = "@mxalice-d9eed33b-e269-4171-9352-8ee8b84b37a1:x.y.z" - cred.deviceId = "KLWNEPIHMX" - case .deprecated3: - cred.userId = "@mxalice-4c5a01ea-9fac-4568-bda6-09e2d14f0e5d:x.y.z" - cred.deviceId = "DCGBYVZFQI" - case .verified: - cred.userId = "@mxalice-107ca1c5-4d03-4ff4-affc-369f4ce6de6f:x.y.z" - cred.deviceId = "AXDAYKSETI" - case .unverified: - cred.userId = "@mxalice-f5314669-7d43-4662-8262-771728e1921f:x.y.z" - cred.deviceId = "ELSGFERWHH" - } - return cred - } - } - - static func load(account: Account) throws -> MXRealmCryptoStore { - guard - let sourceUrl = Bundle(for: Self.self).url(forResource: account.fileName, withExtension: "realm"), - let folder = realmFolder() - else { - throw Error.missingDependencies - } - - if !FileManager.default.fileExists(atPath: folder.path) { - try FileManager.default.createDirectory(at: folder, withIntermediateDirectories: true) - } - - let credentials = account.credentials - let file = "\(credentials.userId!)-\(credentials.deviceId!).realm" - - let targetUrl = folder.appendingPathComponent(file) - if FileManager.default.fileExists(atPath: targetUrl.path) { - try FileManager.default.removeItem(at: targetUrl) - } - - try FileManager.default.copyItem(at: sourceUrl, to: targetUrl) - return MXRealmCryptoStore(credentials: credentials) - } - - static func hasData(for account: Account) -> Bool { - let credentials = account.credentials - let file = "\(credentials.userId!)-\(credentials.deviceId!).realm" - - return MXRealmCryptoStore.hasData(for: credentials) - } - - static func deleteAllStores() throws { - guard let folder = realmFolder() else { - throw Error.missingDependencies - } - - if FileManager.default.fileExists(atPath: folder.path) { - try FileManager.default.removeItem(at: folder) - } - } - - private static func realmFolder() -> URL? { - platformDirectoryURL()? - .appendingPathComponent("MXRealmCryptoStore") - } - - private static func platformDirectoryURL() -> URL? { - #if os(OSX) - guard - let applicationSupport = FileManager.default.urls(for: .applicationSupportDirectory, in: .userDomainMask).first, - let identifier = Bundle.main.bundleIdentifier - else { - return nil - } - return applicationSupport.appendingPathComponent(identifier) - #else - return FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first - #endif - } -} diff --git a/MatrixSDKTests/Crypto/Migration/MXCryptoMigrationV2UnitTests.swift b/MatrixSDKTests/Crypto/Migration/MXCryptoMigrationV2UnitTests.swift deleted file mode 100644 index ddea7c1834..0000000000 --- a/MatrixSDKTests/Crypto/Migration/MXCryptoMigrationV2UnitTests.swift +++ /dev/null @@ -1,167 +0,0 @@ -// -// Copyright 2023 The Matrix.org Foundation C.I.C -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// - -import Foundation -@_implementationOnly import MatrixSDKCrypto -@testable import MatrixSDK - -class MXCryptoMigrationV2UnitTests: XCTestCase { - enum Error: Swift.Error { - case missingEvent - } - - override func tearDown() async throws { - try LegacyRealmStore.deleteAllStores() - } - - // MARK: - Helpers - - private func fullyMigratedOlmMachine(legacyStore: MXCryptoStore) throws -> MXCryptoMachine { - MXKeyProvider.sharedInstance().delegate = MXKeyProviderStub() - let migration = MXCryptoMigrationV2(legacyStore: legacyStore) - try migration.migrateAllData { _ in } - let machine = try MXCryptoMachine( - userId: legacyStore.userId(), - deviceId: legacyStore.deviceId(), - restClient: MXRestClientStub(), - getRoomAction: { _ in - return nil - }) - MXKeyProvider.sharedInstance().delegate = nil - return machine - } - - private func partiallyMigratedOlmMachine(legacyStore: MXCryptoStore) throws -> MXCryptoMachine { - MXKeyProvider.sharedInstance().delegate = MXKeyProviderStub() - let migration = MXCryptoMigrationV2(legacyStore: legacyStore) - try migration.migrateRoomAndGlobalSettingsOnly { _ in } - let machine = try MXCryptoMachine( - userId: legacyStore.userId(), - deviceId: legacyStore.deviceId(), - restClient: MXRestClientStub(), - getRoomAction: { _ in - return nil - }) - MXKeyProvider.sharedInstance().delegate = nil - return machine - } - - private func loadEncryptedEvent() throws -> MXEvent { - guard let url = Bundle(for: Self.self).url(forResource: "archived_encrypted_event", withExtension: nil) else { - throw Error.missingEvent - } - - let data = try Data(contentsOf: url) - guard let event = NSKeyedUnarchiver.unarchiveObject(with: data) as? MXEvent else { - throw Error.missingEvent - } - return event - } - - // MARK: - Tests - - func test_migratesAccountDetails() throws { - let store = try LegacyRealmStore.load(account: .verified) - let machine = try fullyMigratedOlmMachine(legacyStore: store) - - XCTAssertEqual(machine.userId, store.userId()) - XCTAssertEqual(machine.deviceId, store.deviceId()) - XCTAssertNotNil(machine.deviceCurve25519Key) - XCTAssertEqual(machine.deviceCurve25519Key, store.account().identityKeys()[kMXKeyCurve25519Type] as? String) - XCTAssertNotNil(machine.deviceEd25519Key) - XCTAssertEqual(machine.deviceEd25519Key, store.account().identityKeys()[kMXKeyEd25519Type] as? String) - } - - func test_canDecryptMegolmMessageAfterMigration() throws { - // Load a previously archived and encrypted event - let event = try loadEncryptedEvent() - XCTAssertTrue(event.isEncrypted) - XCTAssertEqual(event.content["algorithm"] as? String, kMXCryptoMegolmAlgorithm) - XCTAssertNotNil(event.content["ciphertext"]) - - // Migrate data to crypto v2 - let store = try LegacyRealmStore.load(account: .verified) - let machine = try fullyMigratedOlmMachine(legacyStore: store) - - // Decrypt the event using crypto v2 - let decrypted = try machine.decryptRoomEvent(event) - let result = try MXEventDecryptionResult(event: decrypted) - let content = result.clearEvent["content"] as? [String: Any] - - // At this point we should be able to read back the original message after - // having decrypted the event with room keys migrated earlier - XCTAssertEqual(content?["body"] as? String, "Hi bob") - } - - func test_notCrossSignedAfterMigration() throws { - let store = try LegacyRealmStore.load(account: .unverified) - let machine = try fullyMigratedOlmMachine(legacyStore: store) - - let crossSigningV2 = MXCrossSigningV2(crossSigning: machine, restClient: MXRestClientStub()) - XCTAssertFalse(crossSigningV2.canCrossSign) - XCTAssertFalse(crossSigningV2.hasAllPrivateKeys) - } - - func test_migratesCrossSigningStatus() throws { - let store = try LegacyRealmStore.load(account: .verified) - let machine = try fullyMigratedOlmMachine(legacyStore: store) - - let crossSigningV2 = MXCrossSigningV2(crossSigning: machine, restClient: MXRestClientStub()) - XCTAssertTrue(crossSigningV2.hasAllPrivateKeys) - } - - func test_migratesRoomSettings() throws { - let store = try LegacyRealmStore.load(account: .verified) - let machine = try fullyMigratedOlmMachine(legacyStore: store) - - let settings = machine.roomSettings(roomId: LegacyRealmStore.Account.verified.roomId!) - XCTAssertEqual(settings, .init(algorithm: .megolmV1AesSha2, onlyAllowTrustedDevices: true)) - } - - func test_migratesRoomSettingsInPartialMigration() throws { - let store = try LegacyRealmStore.load(account: .verified) - let machine = try partiallyMigratedOlmMachine(legacyStore: store) - - let settings = machine.roomSettings(roomId: LegacyRealmStore.Account.verified.roomId!) - XCTAssertEqual(settings, .init(algorithm: .megolmV1AesSha2, onlyAllowTrustedDevices: true)) - } - - func test_migratesGlobalSettings() throws { - let store1 = try LegacyRealmStore.load(account: .unverified) - let machine1 = try fullyMigratedOlmMachine(legacyStore: store1) - XCTAssertTrue(machine1.onlyAllowTrustedDevices) - - let store2 = try LegacyRealmStore.load(account: .verified) - let machine2 = try fullyMigratedOlmMachine(legacyStore: store2) - XCTAssertFalse(machine2.onlyAllowTrustedDevices) - } - - func test_migratesGlobalSettingsInPartialMigration() throws { - let store1 = try LegacyRealmStore.load(account: .unverified) - let machine1 = try partiallyMigratedOlmMachine(legacyStore: store1) - XCTAssertTrue(machine1.onlyAllowTrustedDevices) - - let store2 = try LegacyRealmStore.load(account: .verified) - let machine2 = try partiallyMigratedOlmMachine(legacyStore: store2) - XCTAssertFalse(machine2.onlyAllowTrustedDevices) - } -} - -extension MXCryptoMigrationV2UnitTests: Logger { - func log(logLine: String) { - MXLog.debug("[MXCryptoMigrationV2Tests]: \(logLine)") - } -} diff --git a/Podfile b/Podfile index 77ddd65582..4cdb653390 100644 --- a/Podfile +++ b/Podfile @@ -36,7 +36,30 @@ abstract_target 'MatrixSDK' do end end +# from here: https://juejin.cn/post/7621018086649430025 +def patch_afnetworking_private_header(installer) + # 扫描并移除 AFNetworking 对私有 IPv6 头文件的直接引用,兼容新版 Xcode 的模块校验。 + afnetworking_dir = File.join(installer.sandbox.pod_dir('AFNetworking'), 'AFNetworking') + return unless Dir.exist?(afnetworking_dir) + + private_header_import = '#import ' + Dir.glob(File.join(afnetworking_dir, '**', '*.{h,m}')).each do |file_path| + #next unless mcs_file_exists(file_path) + + file_content = File.read(file_path) + next unless file_content.include?(private_header_import) + + original_mode = File.stat(file_path).mode + File.chmod(original_mode | 0o200, file_path) + File.write(file_path, file_content.gsub(private_header_import, '')) + File.chmod(original_mode, file_path) + puts "patched AFNetworking private header import: #{File.basename(file_path)}" + end +end + post_install do |installer| + patch_afnetworking_private_header(installer) + installer.pods_project.targets.each do |target| target.build_configurations.each do |config| config.build_settings['IPHONEOS_DEPLOYMENT_TARGET'] = '13.0' diff --git a/Podfile.lock b/Podfile.lock index 48f3238e97..840b2616c2 100644 --- a/Podfile.lock +++ b/Podfile.lock @@ -63,6 +63,6 @@ SPEC CHECKSUMS: Realm: 9ca328bd7e700cc19703799785e37f77d1a130f2 SwiftyBeaver: 84069991dd5dca07d7069100985badaca7f0ce82 -PODFILE CHECKSUM: 43b5fd9b5489fc93ff6f9121742d30463242345f +PODFILE CHECKSUM: 6ae14a373709e4d335bf93c3aaaff569bed7fce0 COCOAPODS: 1.16.2