From ab9d8eb52b76b7fd77b1fc3f03ab9ae36c4b4fc4 Mon Sep 17 00:00:00 2001 From: Jonas Platte Date: Tue, 12 Apr 2022 16:36:31 +0200 Subject: [PATCH 01/51] feat: Initial apple platforms support Co-authored-by: Stefan Ceriu Co-authored-by: Benjamin Kampmann --- .gitignore | 4 + .../MatrixRustSDK.xcodeproj/project.pbxproj | 632 ++++++++++++++++++ .../contents.xcworkspacedata | 7 + .../xcshareddata/IDEWorkspaceChecks.plist | 8 + .../xcschemes/MatrixRustSDK.xcscheme | 98 +++ .../AccentColor.colorset/Contents.json | 11 + .../AppIcon.appiconset/Contents.json | 98 +++ .../Assets.xcassets/Contents.json | 6 + .../MatrixRustSDK/ClientError+Error.swift | 11 + .../MatrixRustSDK/ContentView.swift | 21 + apple/MatrixRustSDK/MatrixRustSDK/Info.plist | 5 + .../MatrixRustSDK-Bridging-Header.h | 5 + .../MatrixRustSDK/MatrixRustSDK.entitlements | 10 + .../MatrixRustSDK/MatrixRustSDKApp.swift | 17 + .../MatrixRustSDKTests.swift | 21 + .../MatrixRustSDKUITests.swift | 42 ++ apple/MatrixRustSDK/README.md | 39 ++ apple/MatrixRustSDK/build_xcframework.sh | 94 +++ .../MatrixRustSDK/debug_build_xcframework.sh | 58 ++ crates/matrix-sdk-ffi/Cargo.toml | 38 ++ crates/matrix-sdk-ffi/README.md | 13 + crates/matrix-sdk-ffi/build.rs | 3 + crates/matrix-sdk-ffi/src/api.udl | 137 ++++ crates/matrix-sdk-ffi/src/backward_stream.rs | 42 ++ crates/matrix-sdk-ffi/src/client.rs | 163 +++++ crates/matrix-sdk-ffi/src/lib.rs | 110 +++ crates/matrix-sdk-ffi/src/messages.rs | 242 +++++++ crates/matrix-sdk-ffi/src/room.rs | 143 ++++ 28 files changed, 2078 insertions(+) create mode 100644 apple/MatrixRustSDK/MatrixRustSDK.xcodeproj/project.pbxproj create mode 100644 apple/MatrixRustSDK/MatrixRustSDK.xcodeproj/project.xcworkspace/contents.xcworkspacedata create mode 100644 apple/MatrixRustSDK/MatrixRustSDK.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist create mode 100644 apple/MatrixRustSDK/MatrixRustSDK.xcodeproj/xcshareddata/xcschemes/MatrixRustSDK.xcscheme create mode 100644 apple/MatrixRustSDK/MatrixRustSDK/Assets.xcassets/AccentColor.colorset/Contents.json create mode 100644 apple/MatrixRustSDK/MatrixRustSDK/Assets.xcassets/AppIcon.appiconset/Contents.json create mode 100644 apple/MatrixRustSDK/MatrixRustSDK/Assets.xcassets/Contents.json create mode 100644 apple/MatrixRustSDK/MatrixRustSDK/ClientError+Error.swift create mode 100644 apple/MatrixRustSDK/MatrixRustSDK/ContentView.swift create mode 100644 apple/MatrixRustSDK/MatrixRustSDK/Info.plist create mode 100644 apple/MatrixRustSDK/MatrixRustSDK/MatrixRustSDK-Bridging-Header.h create mode 100644 apple/MatrixRustSDK/MatrixRustSDK/MatrixRustSDK.entitlements create mode 100644 apple/MatrixRustSDK/MatrixRustSDK/MatrixRustSDKApp.swift create mode 100644 apple/MatrixRustSDK/MatrixRustSDKTests/MatrixRustSDKTests.swift create mode 100644 apple/MatrixRustSDK/MatrixRustSDKUITests/MatrixRustSDKUITests.swift create mode 100644 apple/MatrixRustSDK/README.md create mode 100755 apple/MatrixRustSDK/build_xcframework.sh create mode 100755 apple/MatrixRustSDK/debug_build_xcframework.sh create mode 100644 crates/matrix-sdk-ffi/Cargo.toml create mode 100644 crates/matrix-sdk-ffi/README.md create mode 100644 crates/matrix-sdk-ffi/build.rs create mode 100644 crates/matrix-sdk-ffi/src/api.udl create mode 100644 crates/matrix-sdk-ffi/src/backward_stream.rs create mode 100644 crates/matrix-sdk-ffi/src/client.rs create mode 100644 crates/matrix-sdk-ffi/src/lib.rs create mode 100644 crates/matrix-sdk-ffi/src/messages.rs create mode 100644 crates/matrix-sdk-ffi/src/room.rs diff --git a/.gitignore b/.gitignore index f12193193..a6abb2fb4 100644 --- a/.gitignore +++ b/.gitignore @@ -1,6 +1,10 @@ Cargo.lock target +generated master.zip emsdk-* .idea/ + +## User settings +xcuserdata/ .vscode/ diff --git a/apple/MatrixRustSDK/MatrixRustSDK.xcodeproj/project.pbxproj b/apple/MatrixRustSDK/MatrixRustSDK.xcodeproj/project.pbxproj new file mode 100644 index 000000000..04b66cc16 --- /dev/null +++ b/apple/MatrixRustSDK/MatrixRustSDK.xcodeproj/project.pbxproj @@ -0,0 +1,632 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 55; + objects = { + +/* Begin PBXBuildFile section */ + 181AA19B27B52AB40005F102 /* MatrixSDKFFI.xcframework in Frameworks */ = {isa = PBXBuildFile; fileRef = 181AA19A27B52AB40005F102 /* MatrixSDKFFI.xcframework */; }; + 181AA19C27B52AB40005F102 /* MatrixSDKFFI.xcframework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 181AA19A27B52AB40005F102 /* MatrixSDKFFI.xcframework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; + 189A89BA27B40BBF0048B0A5 /* sdk.swift in Sources */ = {isa = PBXBuildFile; fileRef = 189A89B927B40BBF0048B0A5 /* sdk.swift */; }; + 189A89C827B4201C0048B0A5 /* ClientError+Error.swift in Sources */ = {isa = PBXBuildFile; fileRef = 189A89C727B4201C0048B0A5 /* ClientError+Error.swift */; }; + 18CE89D827B2939900CA89E1 /* MatrixRustSDKApp.swift in Sources */ = {isa = PBXBuildFile; fileRef = 18CE89D727B2939900CA89E1 /* MatrixRustSDKApp.swift */; }; + 18CE89DA27B2939900CA89E1 /* ContentView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 18CE89D927B2939900CA89E1 /* ContentView.swift */; }; + 18CE89DC27B2939A00CA89E1 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 18CE89DB27B2939A00CA89E1 /* Assets.xcassets */; }; + 18CE89E927B2939A00CA89E1 /* MatrixRustSDKTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 18CE89E827B2939A00CA89E1 /* MatrixRustSDKTests.swift */; }; + 18CE89F327B2939A00CA89E1 /* MatrixRustSDKUITests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 18CE89F227B2939A00CA89E1 /* MatrixRustSDKUITests.swift */; }; +/* End PBXBuildFile section */ + +/* Begin PBXContainerItemProxy section */ + 18CE89E527B2939A00CA89E1 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 18CE89CC27B2939900CA89E1 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 18CE89D327B2939900CA89E1; + remoteInfo = MatrixRustSDK; + }; + 18CE89EF27B2939A00CA89E1 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 18CE89CC27B2939900CA89E1 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 18CE89D327B2939900CA89E1; + remoteInfo = MatrixRustSDK; + }; +/* End PBXContainerItemProxy section */ + +/* Begin PBXCopyFilesBuildPhase section */ + 18CE8A1F27B2941600CA89E1 /* Embed Frameworks */ = { + isa = PBXCopyFilesBuildPhase; + buildActionMask = 2147483647; + dstPath = ""; + dstSubfolderSpec = 10; + files = ( + 181AA19C27B52AB40005F102 /* MatrixSDKFFI.xcframework in Embed Frameworks */, + ); + name = "Embed Frameworks"; + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXCopyFilesBuildPhase section */ + +/* Begin PBXFileReference section */ + 181AA19927B52AA60005F102 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist; path = Info.plist; sourceTree = ""; }; + 181AA19A27B52AB40005F102 /* MatrixSDKFFI.xcframework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcframework; name = MatrixSDKFFI.xcframework; path = ../../generated/MatrixSDKFFI.xcframework; sourceTree = ""; }; + 189A899E27B2BADA0048B0A5 /* build_xcframework.sh */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.sh; path = build_xcframework.sh; sourceTree = SOURCE_ROOT; }; + 189A89B927B40BBF0048B0A5 /* sdk.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = sdk.swift; path = ../../../generated/swift/sdk.swift; sourceTree = ""; }; + 189A89C327B417CA0048B0A5 /* MatrixRustSDK-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "MatrixRustSDK-Bridging-Header.h"; sourceTree = ""; }; + 189A89C727B4201C0048B0A5 /* ClientError+Error.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "ClientError+Error.swift"; sourceTree = ""; }; + 18CE89D427B2939900CA89E1 /* MatrixRustSDK.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = MatrixRustSDK.app; sourceTree = BUILT_PRODUCTS_DIR; }; + 18CE89D727B2939900CA89E1 /* MatrixRustSDKApp.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MatrixRustSDKApp.swift; sourceTree = ""; }; + 18CE89D927B2939900CA89E1 /* ContentView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ContentView.swift; sourceTree = ""; }; + 18CE89DB27B2939A00CA89E1 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; + 18CE89E427B2939A00CA89E1 /* MatrixRustSDKTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = MatrixRustSDKTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; + 18CE89E827B2939A00CA89E1 /* MatrixRustSDKTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MatrixRustSDKTests.swift; sourceTree = ""; }; + 18CE89EE27B2939A00CA89E1 /* MatrixRustSDKUITests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = MatrixRustSDKUITests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; + 18CE89F227B2939A00CA89E1 /* MatrixRustSDKUITests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MatrixRustSDKUITests.swift; sourceTree = ""; }; + 18CE8A0127B293A900CA89E1 /* MatrixRustSDK.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = MatrixRustSDK.entitlements; sourceTree = ""; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + 18CE89D127B2939900CA89E1 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 181AA19B27B52AB40005F102 /* MatrixSDKFFI.xcframework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 18CE89E127B2939A00CA89E1 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 18CE89EB27B2939A00CA89E1 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + 189A89AB27B2E16B0048B0A5 /* Frameworks */ = { + isa = PBXGroup; + children = ( + 181AA19A27B52AB40005F102 /* MatrixSDKFFI.xcframework */, + ); + name = Frameworks; + sourceTree = ""; + }; + 189A89B827B40BB10048B0A5 /* Generated */ = { + isa = PBXGroup; + children = ( + 189A89B927B40BBF0048B0A5 /* sdk.swift */, + ); + name = Generated; + sourceTree = ""; + }; + 18CE89CB27B2939900CA89E1 = { + isa = PBXGroup; + children = ( + 18CE89D627B2939900CA89E1 /* MatrixRustSDK */, + 18CE89E727B2939A00CA89E1 /* MatrixRustSDKTests */, + 18CE89F127B2939A00CA89E1 /* MatrixRustSDKUITests */, + 18CE89D527B2939900CA89E1 /* Products */, + 189A89AB27B2E16B0048B0A5 /* Frameworks */, + ); + sourceTree = ""; + }; + 18CE89D527B2939900CA89E1 /* Products */ = { + isa = PBXGroup; + children = ( + 18CE89D427B2939900CA89E1 /* MatrixRustSDK.app */, + 18CE89E427B2939A00CA89E1 /* MatrixRustSDKTests.xctest */, + 18CE89EE27B2939A00CA89E1 /* MatrixRustSDKUITests.xctest */, + ); + name = Products; + sourceTree = ""; + }; + 18CE89D627B2939900CA89E1 /* MatrixRustSDK */ = { + isa = PBXGroup; + children = ( + 181AA19927B52AA60005F102 /* Info.plist */, + 189A899E27B2BADA0048B0A5 /* build_xcframework.sh */, + 189A89B827B40BB10048B0A5 /* Generated */, + 18CE89D727B2939900CA89E1 /* MatrixRustSDKApp.swift */, + 18CE89D927B2939900CA89E1 /* ContentView.swift */, + 189A89C727B4201C0048B0A5 /* ClientError+Error.swift */, + 18CE8A0127B293A900CA89E1 /* MatrixRustSDK.entitlements */, + 18CE89DB27B2939A00CA89E1 /* Assets.xcassets */, + 189A89C327B417CA0048B0A5 /* MatrixRustSDK-Bridging-Header.h */, + ); + path = MatrixRustSDK; + sourceTree = ""; + }; + 18CE89E727B2939A00CA89E1 /* MatrixRustSDKTests */ = { + isa = PBXGroup; + children = ( + 18CE89E827B2939A00CA89E1 /* MatrixRustSDKTests.swift */, + ); + path = MatrixRustSDKTests; + sourceTree = ""; + }; + 18CE89F127B2939A00CA89E1 /* MatrixRustSDKUITests */ = { + isa = PBXGroup; + children = ( + 18CE89F227B2939A00CA89E1 /* MatrixRustSDKUITests.swift */, + ); + path = MatrixRustSDKUITests; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXNativeTarget section */ + 18CE89D327B2939900CA89E1 /* MatrixRustSDK */ = { + isa = PBXNativeTarget; + buildConfigurationList = 18CE89F827B2939A00CA89E1 /* Build configuration list for PBXNativeTarget "MatrixRustSDK" */; + buildPhases = ( + 18CE89D027B2939900CA89E1 /* Sources */, + 18CE89D127B2939900CA89E1 /* Frameworks */, + 18CE89D227B2939900CA89E1 /* Resources */, + 18CE8A1F27B2941600CA89E1 /* Embed Frameworks */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = MatrixRustSDK; + productName = MatrixRustSDK; + productReference = 18CE89D427B2939900CA89E1 /* MatrixRustSDK.app */; + productType = "com.apple.product-type.application"; + }; + 18CE89E327B2939A00CA89E1 /* MatrixRustSDKTests */ = { + isa = PBXNativeTarget; + buildConfigurationList = 18CE89FB27B2939A00CA89E1 /* Build configuration list for PBXNativeTarget "MatrixRustSDKTests" */; + buildPhases = ( + 18CE89E027B2939A00CA89E1 /* Sources */, + 18CE89E127B2939A00CA89E1 /* Frameworks */, + 18CE89E227B2939A00CA89E1 /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + 18CE89E627B2939A00CA89E1 /* PBXTargetDependency */, + ); + name = MatrixRustSDKTests; + productName = MatrixRustSDKTests; + productReference = 18CE89E427B2939A00CA89E1 /* MatrixRustSDKTests.xctest */; + productType = "com.apple.product-type.bundle.unit-test"; + }; + 18CE89ED27B2939A00CA89E1 /* MatrixRustSDKUITests */ = { + isa = PBXNativeTarget; + buildConfigurationList = 18CE89FE27B2939A00CA89E1 /* Build configuration list for PBXNativeTarget "MatrixRustSDKUITests" */; + buildPhases = ( + 18CE89EA27B2939A00CA89E1 /* Sources */, + 18CE89EB27B2939A00CA89E1 /* Frameworks */, + 18CE89EC27B2939A00CA89E1 /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + 18CE89F027B2939A00CA89E1 /* PBXTargetDependency */, + ); + name = MatrixRustSDKUITests; + productName = MatrixRustSDKUITests; + productReference = 18CE89EE27B2939A00CA89E1 /* MatrixRustSDKUITests.xctest */; + productType = "com.apple.product-type.bundle.ui-testing"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + 18CE89CC27B2939900CA89E1 /* Project object */ = { + isa = PBXProject; + attributes = { + BuildIndependentTargetsInParallel = 1; + LastSwiftUpdateCheck = 1320; + LastUpgradeCheck = 1320; + TargetAttributes = { + 18CE89D327B2939900CA89E1 = { + CreatedOnToolsVersion = 13.2.1; + LastSwiftMigration = 1320; + }; + 18CE89E327B2939A00CA89E1 = { + CreatedOnToolsVersion = 13.2.1; + TestTargetID = 18CE89D327B2939900CA89E1; + }; + 18CE89ED27B2939A00CA89E1 = { + CreatedOnToolsVersion = 13.2.1; + TestTargetID = 18CE89D327B2939900CA89E1; + }; + }; + }; + buildConfigurationList = 18CE89CF27B2939900CA89E1 /* Build configuration list for PBXProject "MatrixRustSDK" */; + compatibilityVersion = "Xcode 13.0"; + developmentRegion = en; + hasScannedForEncodings = 0; + knownRegions = ( + en, + Base, + ); + mainGroup = 18CE89CB27B2939900CA89E1; + productRefGroup = 18CE89D527B2939900CA89E1 /* Products */; + projectDirPath = ""; + projectRoot = ""; + targets = ( + 18CE89D327B2939900CA89E1 /* MatrixRustSDK */, + 18CE89E327B2939A00CA89E1 /* MatrixRustSDKTests */, + 18CE89ED27B2939A00CA89E1 /* MatrixRustSDKUITests */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXResourcesBuildPhase section */ + 18CE89D227B2939900CA89E1 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 18CE89DC27B2939A00CA89E1 /* Assets.xcassets in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 18CE89E227B2939A00CA89E1 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 18CE89EC27B2939A00CA89E1 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXResourcesBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ + 18CE89D027B2939900CA89E1 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 189A89C827B4201C0048B0A5 /* ClientError+Error.swift in Sources */, + 18CE89DA27B2939900CA89E1 /* ContentView.swift in Sources */, + 189A89BA27B40BBF0048B0A5 /* sdk.swift in Sources */, + 18CE89D827B2939900CA89E1 /* MatrixRustSDKApp.swift in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 18CE89E027B2939A00CA89E1 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 18CE89E927B2939A00CA89E1 /* MatrixRustSDKTests.swift in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 18CE89EA27B2939A00CA89E1 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 18CE89F327B2939A00CA89E1 /* MatrixRustSDKUITests.swift in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin PBXTargetDependency section */ + 18CE89E627B2939A00CA89E1 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = 18CE89D327B2939900CA89E1 /* MatrixRustSDK */; + targetProxy = 18CE89E527B2939A00CA89E1 /* PBXContainerItemProxy */; + }; + 18CE89F027B2939A00CA89E1 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = 18CE89D327B2939900CA89E1 /* MatrixRustSDK */; + targetProxy = 18CE89EF27B2939A00CA89E1 /* PBXContainerItemProxy */; + }; +/* End PBXTargetDependency section */ + +/* Begin XCBuildConfiguration section */ + 18CE89F627B2939A00CA89E1 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++17"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_ENABLE_OBJC_WEAK = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = dwarf; + ENABLE_STRICT_OBJC_MSGSEND = YES; + ENABLE_TESTABILITY = YES; + GCC_C_LANGUAGE_STANDARD = gnu11; + GCC_DYNAMIC_NO_PIC = NO; + GCC_NO_COMMON_BLOCKS = YES; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PREPROCESSOR_DEFINITIONS = ( + "DEBUG=1", + "$(inherited)", + ); + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 15.2; + MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; + MTL_FAST_MATH = YES; + ONLY_ACTIVE_ARCH = YES; + SDKROOT = iphoneos; + SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; + SWIFT_OPTIMIZATION_LEVEL = "-Onone"; + }; + name = Debug; + }; + 18CE89F727B2939A00CA89E1 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++17"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_ENABLE_OBJC_WEAK = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + ENABLE_NS_ASSERTIONS = NO; + ENABLE_STRICT_OBJC_MSGSEND = YES; + GCC_C_LANGUAGE_STANDARD = gnu11; + GCC_NO_COMMON_BLOCKS = YES; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 15.2; + MTL_ENABLE_DEBUG_INFO = NO; + MTL_FAST_MATH = YES; + SDKROOT = iphoneos; + SWIFT_COMPILATION_MODE = wholemodule; + SWIFT_OPTIMIZATION_LEVEL = "-O"; + VALIDATE_PRODUCT = YES; + }; + name = Release; + }; + 18CE89F927B2939A00CA89E1 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; + CLANG_ENABLE_MODULES = YES; + CODE_SIGN_ENTITLEMENTS = MatrixRustSDK/MatrixRustSDK.entitlements; + "CODE_SIGN_IDENTITY[sdk=macosx*]" = "-"; + CODE_SIGN_STYLE = Automatic; + CURRENT_PROJECT_VERSION = 1; + ENABLE_PREVIEWS = YES; + GENERATE_INFOPLIST_FILE = YES; + INFOPLIST_FILE = MatrixRustSDK/Info.plist; + INFOPLIST_KEY_UIApplicationSceneManifest_Generation = YES; + INFOPLIST_KEY_UIApplicationSupportsIndirectInputEvents = YES; + INFOPLIST_KEY_UILaunchScreen_Generation = YES; + INFOPLIST_KEY_UISupportedInterfaceOrientations_iPad = "UIInterfaceOrientationPortrait UIInterfaceOrientationPortraitUpsideDown UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight"; + INFOPLIST_KEY_UISupportedInterfaceOrientations_iPhone = "UIInterfaceOrientationPortrait UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight"; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + ); + MARKETING_VERSION = 1.0; + PRODUCT_BUNDLE_IDENTIFIER = org.matrix.MatrixRustSDK; + PRODUCT_NAME = "$(TARGET_NAME)"; + SUPPORTS_MACCATALYST = YES; + SWIFT_EMIT_LOC_STRINGS = YES; + SWIFT_OBJC_BRIDGING_HEADER = "MatrixRustSDK/MatrixRustSDK-Bridging-Header.h"; + SWIFT_OPTIMIZATION_LEVEL = "-Onone"; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Debug; + }; + 18CE89FA27B2939A00CA89E1 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; + CLANG_ENABLE_MODULES = YES; + CODE_SIGN_ENTITLEMENTS = MatrixRustSDK/MatrixRustSDK.entitlements; + "CODE_SIGN_IDENTITY[sdk=macosx*]" = "-"; + CODE_SIGN_STYLE = Automatic; + CURRENT_PROJECT_VERSION = 1; + ENABLE_PREVIEWS = YES; + GENERATE_INFOPLIST_FILE = YES; + INFOPLIST_FILE = MatrixRustSDK/Info.plist; + INFOPLIST_KEY_UIApplicationSceneManifest_Generation = YES; + INFOPLIST_KEY_UIApplicationSupportsIndirectInputEvents = YES; + INFOPLIST_KEY_UILaunchScreen_Generation = YES; + INFOPLIST_KEY_UISupportedInterfaceOrientations_iPad = "UIInterfaceOrientationPortrait UIInterfaceOrientationPortraitUpsideDown UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight"; + INFOPLIST_KEY_UISupportedInterfaceOrientations_iPhone = "UIInterfaceOrientationPortrait UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight"; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + ); + MARKETING_VERSION = 1.0; + PRODUCT_BUNDLE_IDENTIFIER = org.matrix.MatrixRustSDK; + PRODUCT_NAME = "$(TARGET_NAME)"; + SUPPORTS_MACCATALYST = YES; + SWIFT_EMIT_LOC_STRINGS = YES; + SWIFT_OBJC_BRIDGING_HEADER = "MatrixRustSDK/MatrixRustSDK-Bridging-Header.h"; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Release; + }; + 18CE89FC27B2939A00CA89E1 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; + BUNDLE_LOADER = "$(TEST_HOST)"; + CODE_SIGN_STYLE = Automatic; + CURRENT_PROJECT_VERSION = 1; + GENERATE_INFOPLIST_FILE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 15.2; + MARKETING_VERSION = 1.0; + PRODUCT_BUNDLE_IDENTIFIER = org.matrix.MatrixRustSDKTests; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_EMIT_LOC_STRINGS = NO; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + TEST_HOST = "$(BUILT_PRODUCTS_DIR)/MatrixRustSDK.app/MatrixRustSDK"; + }; + name = Debug; + }; + 18CE89FD27B2939A00CA89E1 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; + BUNDLE_LOADER = "$(TEST_HOST)"; + CODE_SIGN_STYLE = Automatic; + CURRENT_PROJECT_VERSION = 1; + GENERATE_INFOPLIST_FILE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 15.2; + MARKETING_VERSION = 1.0; + PRODUCT_BUNDLE_IDENTIFIER = org.matrix.MatrixRustSDKTests; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_EMIT_LOC_STRINGS = NO; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + TEST_HOST = "$(BUILT_PRODUCTS_DIR)/MatrixRustSDK.app/MatrixRustSDK"; + }; + name = Release; + }; + 18CE89FF27B2939A00CA89E1 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; + CODE_SIGN_STYLE = Automatic; + CURRENT_PROJECT_VERSION = 1; + GENERATE_INFOPLIST_FILE = YES; + MARKETING_VERSION = 1.0; + PRODUCT_BUNDLE_IDENTIFIER = org.matrix.MatrixRustSDKUITests; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_EMIT_LOC_STRINGS = NO; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + TEST_TARGET_NAME = MatrixRustSDK; + }; + name = Debug; + }; + 18CE8A0027B2939A00CA89E1 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; + CODE_SIGN_STYLE = Automatic; + CURRENT_PROJECT_VERSION = 1; + GENERATE_INFOPLIST_FILE = YES; + MARKETING_VERSION = 1.0; + PRODUCT_BUNDLE_IDENTIFIER = org.matrix.MatrixRustSDKUITests; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_EMIT_LOC_STRINGS = NO; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + TEST_TARGET_NAME = MatrixRustSDK; + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + 18CE89CF27B2939900CA89E1 /* Build configuration list for PBXProject "MatrixRustSDK" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 18CE89F627B2939A00CA89E1 /* Debug */, + 18CE89F727B2939A00CA89E1 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 18CE89F827B2939A00CA89E1 /* Build configuration list for PBXNativeTarget "MatrixRustSDK" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 18CE89F927B2939A00CA89E1 /* Debug */, + 18CE89FA27B2939A00CA89E1 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 18CE89FB27B2939A00CA89E1 /* Build configuration list for PBXNativeTarget "MatrixRustSDKTests" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 18CE89FC27B2939A00CA89E1 /* Debug */, + 18CE89FD27B2939A00CA89E1 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 18CE89FE27B2939A00CA89E1 /* Build configuration list for PBXNativeTarget "MatrixRustSDKUITests" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 18CE89FF27B2939A00CA89E1 /* Debug */, + 18CE8A0027B2939A00CA89E1 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; +/* End XCConfigurationList section */ + }; + rootObject = 18CE89CC27B2939900CA89E1 /* Project object */; +} diff --git a/apple/MatrixRustSDK/MatrixRustSDK.xcodeproj/project.xcworkspace/contents.xcworkspacedata b/apple/MatrixRustSDK/MatrixRustSDK.xcodeproj/project.xcworkspace/contents.xcworkspacedata new file mode 100644 index 000000000..919434a62 --- /dev/null +++ b/apple/MatrixRustSDK/MatrixRustSDK.xcodeproj/project.xcworkspace/contents.xcworkspacedata @@ -0,0 +1,7 @@ + + + + + diff --git a/apple/MatrixRustSDK/MatrixRustSDK.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist b/apple/MatrixRustSDK/MatrixRustSDK.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist new file mode 100644 index 000000000..18d981003 --- /dev/null +++ b/apple/MatrixRustSDK/MatrixRustSDK.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist @@ -0,0 +1,8 @@ + + + + + IDEDidComputeMac32BitWarning + + + diff --git a/apple/MatrixRustSDK/MatrixRustSDK.xcodeproj/xcshareddata/xcschemes/MatrixRustSDK.xcscheme b/apple/MatrixRustSDK/MatrixRustSDK.xcodeproj/xcshareddata/xcschemes/MatrixRustSDK.xcscheme new file mode 100644 index 000000000..6644a0efe --- /dev/null +++ b/apple/MatrixRustSDK/MatrixRustSDK.xcodeproj/xcshareddata/xcschemes/MatrixRustSDK.xcscheme @@ -0,0 +1,98 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/apple/MatrixRustSDK/MatrixRustSDK/Assets.xcassets/AccentColor.colorset/Contents.json b/apple/MatrixRustSDK/MatrixRustSDK/Assets.xcassets/AccentColor.colorset/Contents.json new file mode 100644 index 000000000..eb8789700 --- /dev/null +++ b/apple/MatrixRustSDK/MatrixRustSDK/Assets.xcassets/AccentColor.colorset/Contents.json @@ -0,0 +1,11 @@ +{ + "colors" : [ + { + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/apple/MatrixRustSDK/MatrixRustSDK/Assets.xcassets/AppIcon.appiconset/Contents.json b/apple/MatrixRustSDK/MatrixRustSDK/Assets.xcassets/AppIcon.appiconset/Contents.json new file mode 100644 index 000000000..9221b9bb1 --- /dev/null +++ b/apple/MatrixRustSDK/MatrixRustSDK/Assets.xcassets/AppIcon.appiconset/Contents.json @@ -0,0 +1,98 @@ +{ + "images" : [ + { + "idiom" : "iphone", + "scale" : "2x", + "size" : "20x20" + }, + { + "idiom" : "iphone", + "scale" : "3x", + "size" : "20x20" + }, + { + "idiom" : "iphone", + "scale" : "2x", + "size" : "29x29" + }, + { + "idiom" : "iphone", + "scale" : "3x", + "size" : "29x29" + }, + { + "idiom" : "iphone", + "scale" : "2x", + "size" : "40x40" + }, + { + "idiom" : "iphone", + "scale" : "3x", + "size" : "40x40" + }, + { + "idiom" : "iphone", + "scale" : "2x", + "size" : "60x60" + }, + { + "idiom" : "iphone", + "scale" : "3x", + "size" : "60x60" + }, + { + "idiom" : "ipad", + "scale" : "1x", + "size" : "20x20" + }, + { + "idiom" : "ipad", + "scale" : "2x", + "size" : "20x20" + }, + { + "idiom" : "ipad", + "scale" : "1x", + "size" : "29x29" + }, + { + "idiom" : "ipad", + "scale" : "2x", + "size" : "29x29" + }, + { + "idiom" : "ipad", + "scale" : "1x", + "size" : "40x40" + }, + { + "idiom" : "ipad", + "scale" : "2x", + "size" : "40x40" + }, + { + "idiom" : "ipad", + "scale" : "1x", + "size" : "76x76" + }, + { + "idiom" : "ipad", + "scale" : "2x", + "size" : "76x76" + }, + { + "idiom" : "ipad", + "scale" : "2x", + "size" : "83.5x83.5" + }, + { + "idiom" : "ios-marketing", + "scale" : "1x", + "size" : "1024x1024" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/apple/MatrixRustSDK/MatrixRustSDK/Assets.xcassets/Contents.json b/apple/MatrixRustSDK/MatrixRustSDK/Assets.xcassets/Contents.json new file mode 100644 index 000000000..73c00596a --- /dev/null +++ b/apple/MatrixRustSDK/MatrixRustSDK/Assets.xcassets/Contents.json @@ -0,0 +1,6 @@ +{ + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/apple/MatrixRustSDK/MatrixRustSDK/ClientError+Error.swift b/apple/MatrixRustSDK/MatrixRustSDK/ClientError+Error.swift new file mode 100644 index 000000000..354eccef3 --- /dev/null +++ b/apple/MatrixRustSDK/MatrixRustSDK/ClientError+Error.swift @@ -0,0 +1,11 @@ +// +// ClientError+Error.swift +// MatrixRustSDK +// +// Created by Stefan Ceriu on 09.02.2022. +// + +import Foundation + +// Fixes code generation problem from uniffi +extension ClientError: Error { } diff --git a/apple/MatrixRustSDK/MatrixRustSDK/ContentView.swift b/apple/MatrixRustSDK/MatrixRustSDK/ContentView.swift new file mode 100644 index 000000000..67f95eb10 --- /dev/null +++ b/apple/MatrixRustSDK/MatrixRustSDK/ContentView.swift @@ -0,0 +1,21 @@ +// +// ContentView.swift +// MatrixRustSDK +// +// Created by Stefan Ceriu on 08.02.2022. +// + +import SwiftUI + +struct ContentView: View { + var body: some View { + Text("Hello, Rust!") + .padding() + } +} + +struct ContentView_Previews: PreviewProvider { + static var previews: some View { + ContentView() + } +} diff --git a/apple/MatrixRustSDK/MatrixRustSDK/Info.plist b/apple/MatrixRustSDK/MatrixRustSDK/Info.plist new file mode 100644 index 000000000..0c67376eb --- /dev/null +++ b/apple/MatrixRustSDK/MatrixRustSDK/Info.plist @@ -0,0 +1,5 @@ + + + + + diff --git a/apple/MatrixRustSDK/MatrixRustSDK/MatrixRustSDK-Bridging-Header.h b/apple/MatrixRustSDK/MatrixRustSDK/MatrixRustSDK-Bridging-Header.h new file mode 100644 index 000000000..7cd6f6ea3 --- /dev/null +++ b/apple/MatrixRustSDK/MatrixRustSDK/MatrixRustSDK-Bridging-Header.h @@ -0,0 +1,5 @@ +// +// Use this file to import your target's public headers that you would like to expose to Swift. +// + +#import "sdkFFI.h" diff --git a/apple/MatrixRustSDK/MatrixRustSDK/MatrixRustSDK.entitlements b/apple/MatrixRustSDK/MatrixRustSDK/MatrixRustSDK.entitlements new file mode 100644 index 000000000..ee95ab7e5 --- /dev/null +++ b/apple/MatrixRustSDK/MatrixRustSDK/MatrixRustSDK.entitlements @@ -0,0 +1,10 @@ + + + + + com.apple.security.app-sandbox + + com.apple.security.network.client + + + diff --git a/apple/MatrixRustSDK/MatrixRustSDK/MatrixRustSDKApp.swift b/apple/MatrixRustSDK/MatrixRustSDK/MatrixRustSDKApp.swift new file mode 100644 index 000000000..69d888555 --- /dev/null +++ b/apple/MatrixRustSDK/MatrixRustSDK/MatrixRustSDKApp.swift @@ -0,0 +1,17 @@ +// +// MatrixRustSDKApp.swift +// MatrixRustSDK +// +// Created by Stefan Ceriu on 08.02.2022. +// + +import SwiftUI + +@main +struct MatrixRustSDKApp: App { + var body: some Scene { + WindowGroup { + ContentView() + } + } +} diff --git a/apple/MatrixRustSDK/MatrixRustSDKTests/MatrixRustSDKTests.swift b/apple/MatrixRustSDK/MatrixRustSDKTests/MatrixRustSDKTests.swift new file mode 100644 index 000000000..32ca8b63a --- /dev/null +++ b/apple/MatrixRustSDK/MatrixRustSDKTests/MatrixRustSDKTests.swift @@ -0,0 +1,21 @@ +// +// MatrixRustSDKTests.swift +// MatrixRustSDKTests +// +// Created by Stefan Ceriu on 08.02.2022. +// + +import XCTest +@testable import MatrixRustSDK + +class MatrixRustSDKTests: XCTestCase { + func testExample() throws { + do { + let _ = try loginNewClient(basePath: "", username: "test", password: "test") + } catch ClientError.generic(let message) { + XCTAssertNotNil(message.range(of: "Read-only file system")) + } catch { + XCTFail("Not expecting any other kind of exception") + } + } +} diff --git a/apple/MatrixRustSDK/MatrixRustSDKUITests/MatrixRustSDKUITests.swift b/apple/MatrixRustSDK/MatrixRustSDKUITests/MatrixRustSDKUITests.swift new file mode 100644 index 000000000..4e6558448 --- /dev/null +++ b/apple/MatrixRustSDK/MatrixRustSDKUITests/MatrixRustSDKUITests.swift @@ -0,0 +1,42 @@ +// +// MatrixRustSDKUITests.swift +// MatrixRustSDKUITests +// +// Created by Stefan Ceriu on 08.02.2022. +// + +import XCTest + +class MatrixRustSDKUITests: XCTestCase { + + override func setUpWithError() throws { + // Put setup code here. This method is called before the invocation of each test method in the class. + + // In UI tests it is usually best to stop immediately when a failure occurs. + continueAfterFailure = false + + // In UI tests it’s important to set the initial state - such as interface orientation - required for your tests before they run. The setUp method is a good place to do this. + } + + override func tearDownWithError() throws { + // Put teardown code here. This method is called after the invocation of each test method in the class. + } + + func testExample() throws { + // UI tests must launch the application that they test. + let app = XCUIApplication() + app.launch() + + // Use recording to get started writing UI tests. + // Use XCTAssert and related functions to verify your tests produce the correct results. + } + + func testLaunchPerformance() throws { + if #available(macOS 10.15, iOS 13.0, tvOS 13.0, watchOS 7.0, *) { + // This measures how long it takes to launch your application. + measure(metrics: [XCTApplicationLaunchMetric()]) { + XCUIApplication().launch() + } + } + } +} diff --git a/apple/MatrixRustSDK/README.md b/apple/MatrixRustSDK/README.md new file mode 100644 index 000000000..bb49cae34 --- /dev/null +++ b/apple/MatrixRustSDK/README.md @@ -0,0 +1,39 @@ +# Apple platforms support + +This project and build script demonstrate how to create an XCFramework that can be imported into an Xcode project and run on Apple platforms. + +## Building the universal framework + +``` +sh build_xcframework.sh +``` + +**Prerequisites** + +* the Rust toolchain +* UniFFI - `cargo install uniffi_bindge` +* Apple targets (e.g. `rustup target add aarch64-apple-ios`) +* `xcodebuild` command line tool from [Apple](https://developer.apple.com/library/archive/technotes/tn2339/_index.html) +* `lipo` for creating the fat static libs + + +The `build_xcframework.sh` script will go through all the steps required to generate a fully usable `.xcframework`: + +1. compile `matrix-sdk-ffi` libraries for iOS, the iOS simulator, MacOS, and Mac Catalyst under `/target`. Some targets are not part of the standard library and they will be built using the nightly toolchain. +* `lipo` together the libraries for the same platform under `/generated` +* run `uniffi` and generate the C header, module map and swift files +* `xcodebuild` an `xcframework` from the fat static libs and the original iOS one, and add the header and module map to it under `generated/MatrixSDKFFI.xcframework` +* cleanup and delete the generated files except the .xcframework and the swift sources (that aren't part of the framework) + +## Running the Xcode project + +The Xcode project is meant to provide a simple example on how to integrate everything together but also a place to run unit and integration tests from. + +It's pre-configured to link to the generated .xcframework and .swift files so succesfully running the script first is necessary for it to compile. + +It makes the compiled code available to swift by importing the C header through its bridging header. + +Once all the generated components are available running it should be as easy as chosing a platform and clicking run. + +## Distribution +The generated framework and Swift code can be distributed and integrated directly but in order to make things simpler we bundle them together as a Swift package available [TBD](here) \ No newline at end of file diff --git a/apple/MatrixRustSDK/build_xcframework.sh b/apple/MatrixRustSDK/build_xcframework.sh new file mode 100755 index 000000000..9a2474918 --- /dev/null +++ b/apple/MatrixRustSDK/build_xcframework.sh @@ -0,0 +1,94 @@ +#!/usr/bin/env bash +set -eEu + +cd "$(dirname "$0")" + +# Path to the repo root +SRC_ROOT=../.. + +TARGET_DIR="${SRC_ROOT}/target" + +GENERATED_DIR="${SRC_ROOT}/generated" +mkdir -p ${GENERATED_DIR} + +REL_FLAG="--release" +REL_TYPE_DIR="release" + +# Build static libs for all the different architectures + +# iOS +cargo build --locked -p matrix-sdk-ffi ${REL_FLAG} --target "aarch64-apple-ios" + +# MacOS +cargo build --locked -p matrix-sdk-ffi ${REL_FLAG} --target "aarch64-apple-darwin" +cargo build --locked -p matrix-sdk-ffi ${REL_FLAG} --target "x86_64-apple-darwin" + +# iOS Simulator +cargo +nightly build --locked -p matrix-sdk-ffi ${REL_FLAG} --target "aarch64-apple-ios-sim" +cargo build --locked -p matrix-sdk-ffi ${REL_FLAG} --target "x86_64-apple-ios" + +# Mac Catalyst +cargo +nightly build --locked -Z build-std -p matrix-sdk-ffi ${REL_FLAG} --target "aarch64-apple-ios-macabi" +cargo +nightly build --locked -Z build-std -p matrix-sdk-ffi ${REL_FLAG} --target "x86_64-apple-ios-macabi" + +# Lipo together the libraries for the same platform + +# MacOS +lipo -create \ + "${TARGET_DIR}/x86_64-apple-darwin/${REL_TYPE_DIR}/libmatrix_sdk_ffi.a" \ + "${TARGET_DIR}/aarch64-apple-darwin/${REL_TYPE_DIR}/libmatrix_sdk_ffi.a" \ + -output "${GENERATED_DIR}/libmatrix_sdk_ffi_macos.a" + +# iOS Simulator +lipo -create \ + "${TARGET_DIR}/x86_64-apple-ios/${REL_TYPE_DIR}/libmatrix_sdk_ffi.a" \ + "${TARGET_DIR}/aarch64-apple-ios-sim/${REL_TYPE_DIR}/libmatrix_sdk_ffi.a" \ + -output "${GENERATED_DIR}/libmatrix_sdk_ffi_iossimulator.a" + +# Mac Catalyst +lipo -create \ + "${TARGET_DIR}/x86_64-apple-ios-macabi/${REL_TYPE_DIR}/libmatrix_sdk_ffi.a" \ + "${TARGET_DIR}/aarch64-apple-ios-macabi/${REL_TYPE_DIR}/libmatrix_sdk_ffi.a" \ + -output "${GENERATED_DIR}/libmatrix_sdk_ffi_maccatalyst.a" + + +# Generate uniffi files +uniffi-bindgen generate "${SRC_ROOT}/crates/matrix-sdk-ffi/src/api.udl" --language swift --out-dir ${GENERATED_DIR} + +# Move them to the right place +HEADERS_DIR=${GENERATED_DIR}/headers +mkdir -p ${HEADERS_DIR} + +mv ${GENERATED_DIR}/*.h ${GENERATED_DIR}/*.modulemap ${HEADERS_DIR} + +SWIFT_DIR="${GENERATED_DIR}/swift" +mkdir -p ${SWIFT_DIR} + +mv ${GENERATED_DIR}/*.swift ${SWIFT_DIR} + +# Build the xcframework + +if [ -d "${GENERATED_DIR}/MatrixSDKFFI.xcframework" ]; then rm -rf "${GENERATED_DIR}/MatrixSDKFFI.xcframework"; fi + +xcodebuild -create-xcframework \ + -library "${GENERATED_DIR}/libmatrix_sdk_ffi_macos.a" \ + -headers ${HEADERS_DIR} \ + -library "${GENERATED_DIR}/libmatrix_sdk_ffi_iossimulator.a" \ + -headers ${HEADERS_DIR} \ + -library "${GENERATED_DIR}/libmatrix_sdk_ffi_maccatalyst.a" \ + -headers ${HEADERS_DIR} \ + -library "${TARGET_DIR}/aarch64-apple-ios/${REL_TYPE_DIR}/libmatrix_sdk_ffi.a" \ + -headers ${HEADERS_DIR} \ + -output "${GENERATED_DIR}/MatrixSDKFFI.xcframework" + +# Cleanup + +if [ -f "${GENERATED_DIR}/libmatrix_sdk_ffi_macos.a" ]; then rm -rf "${GENERATED_DIR}/libmatrix_sdk_ffi_macos.a"; fi +if [ -f "${GENERATED_DIR}/libmatrix_sdk_ffi_iossimulator.a" ]; then rm -rf "${GENERATED_DIR}/libmatrix_sdk_ffi_iossimulator.a"; fi +if [ -f "${GENERATED_DIR}/libmatrix_sdk_ffi_maccatalyst.a" ]; then rm -rf "${GENERATED_DIR}/libmatrix_sdk_ffi_maccatalyst.a"; fi +if [ -d ${HEADERS_DIR} ]; then rm -rf ${HEADERS_DIR}; fi + +# Debug -> Copy generated files over to ../../../matrix-rust-components-swift +# rsync -a --delete "${GENERATED_DIR}/MatrixSDKFFI.xcframework" "../../../matrix-rust-components-swift/" +# rsync -a --delete "${GENERATED_DIR}/swift/" "../../../matrix-rust-components-swift/Sources/MatrixRustSDK" + diff --git a/apple/MatrixRustSDK/debug_build_xcframework.sh b/apple/MatrixRustSDK/debug_build_xcframework.sh new file mode 100755 index 000000000..0f579c98c --- /dev/null +++ b/apple/MatrixRustSDK/debug_build_xcframework.sh @@ -0,0 +1,58 @@ +#!/usr/bin/env bash +set -eEu + +cd "$(dirname "$0")" + +# Path to the repo root +SRC_ROOT=../.. + +TARGET_DIR="${SRC_ROOT}/target" + +GENERATED_DIR="${SRC_ROOT}/generated" +mkdir -p ${GENERATED_DIR} + +# Release for now. Debug builds cause crashes deep inside the Tokio runtime. +REL_FLAG="--release" +REL_TYPE_DIR="release" + +# Build static the lib for aarch64 simulator + +cargo +nightly build --locked -p matrix-sdk-ffi ${REL_FLAG} --target "aarch64-apple-ios-sim" + +lipo -create \ + "${TARGET_DIR}/aarch64-apple-ios-sim/${REL_TYPE_DIR}/libmatrix_sdk_ffi.a" \ + -output "${GENERATED_DIR}/libmatrix_sdk_ffi_iossimulator.a" + +# Generate uniffi files +uniffi-bindgen generate "${SRC_ROOT}/crates/matrix-sdk-ffi/src/api.udl" --language swift --out-dir ${GENERATED_DIR} + +# Move them to the right place +HEADERS_DIR=${GENERATED_DIR}/headers +mkdir -p ${HEADERS_DIR} + +mv ${GENERATED_DIR}/*.h ${GENERATED_DIR}/*.modulemap ${HEADERS_DIR} + +SWIFT_DIR="${GENERATED_DIR}/swift" +mkdir -p ${SWIFT_DIR} + +mv ${GENERATED_DIR}/*.swift ${SWIFT_DIR} + +# Build the xcframework + +if [ -d "${GENERATED_DIR}/MatrixSDKFFI.xcframework" ]; then rm -rf "${GENERATED_DIR}/MatrixSDKFFI.xcframework"; fi + +xcodebuild -create-xcframework \ + -library "${GENERATED_DIR}/libmatrix_sdk_ffi_iossimulator.a" \ + -headers ${HEADERS_DIR} \ + -output "${GENERATED_DIR}/MatrixSDKFFI.xcframework" + +# Cleanup + +if [ -f "${GENERATED_DIR}/libmatrix_sdk_ffi_iossimulator.a" ]; then rm -rf "${GENERATED_DIR}/libmatrix_sdk_ffi_iossimulator.a"; fi +if [ -d ${HEADERS_DIR} ]; then rm -rf ${HEADERS_DIR}; fi + +# Debug -> Copy generated files over to ../../../matrix-rust-components-swift +echo "$(echo "import MatrixSDKFFIWrapper\n"; cat "${SWIFT_DIR}/sdk.swift")" > "${SWIFT_DIR}/sdk.swift" + +rsync -a --delete "${GENERATED_DIR}/MatrixSDKFFI.xcframework" "../../../matrix-rust-components-swift/" +rsync -a --delete "${GENERATED_DIR}/swift/" "../../../matrix-rust-components-swift/Sources/MatrixRustSDK" diff --git a/crates/matrix-sdk-ffi/Cargo.toml b/crates/matrix-sdk-ffi/Cargo.toml new file mode 100644 index 000000000..e773e95c6 --- /dev/null +++ b/crates/matrix-sdk-ffi/Cargo.toml @@ -0,0 +1,38 @@ +[package] +name = "matrix-sdk-ffi" +version = "0.1.0" +edition = "2021" +homepage = "https://github.com/matrix-org/matrix-rust-sdk" +keywords = ["matrix", "chat", "messaging", "ffi"] +license = "Apache-2.0" +readme = "README.md" +rust-version = "1.56" +repository = "https://github.com/matrix-org/matrix-rust-sdk" + +[lib] +crate-type = ["cdylib", "staticlib"] + +[features] +default = ["with-runtime"] +with-runtime = ["tokio"] + +[build-dependencies] +uniffi_build = { version = "0.17.0", features = ["builtin-bindgen"] } + +[dependencies] +anyhow = "1.0.51" +extension-trait = "1.0.1" +futures-core = "0.3.17" +futures-util = { version = "0.3.17", default-features = false } +matrix-sdk = { path = "../matrix-sdk" } +once_cell = "1.10.0" +parking_lot = "0.12.0" +sanitize-filename-reader-friendly = "2.2.1" +serde = { version = "1", features = ["derive"] } +serde_json = { version = "1" } +thiserror = "1.0.30" +tokio = { version = "1", optional = true, features = ["rt-multi-thread", "macros"] } +tokio-stream = "0.1.8" +tracing = "0.1.32" +uniffi = "0.17.0" +uniffi_macros = "0.17.0" diff --git a/crates/matrix-sdk-ffi/README.md b/crates/matrix-sdk-ffi/README.md new file mode 100644 index 000000000..ac2311058 --- /dev/null +++ b/crates/matrix-sdk-ffi/README.md @@ -0,0 +1,13 @@ +# FFI bindings for the rust matrix SDK + +This uses [´uniffi´](https://mozilla.github.io/uniffi-rs/Overview.html) to build the matrix bindings for native support and wasm-bindgen for web-browser assembly support. Please refer to the specific section to figure out how to build and use the bindings for your platform. + +## Platforms + +### Swift/iOS sync + + + +### Swift/iOS async + +TBD \ No newline at end of file diff --git a/crates/matrix-sdk-ffi/build.rs b/crates/matrix-sdk-ffi/build.rs new file mode 100644 index 000000000..40ec554ca --- /dev/null +++ b/crates/matrix-sdk-ffi/build.rs @@ -0,0 +1,3 @@ +fn main() { + uniffi_build::generate_scaffolding("./src/api.udl").expect("Building the UDL file failed"); +} diff --git a/crates/matrix-sdk-ffi/src/api.udl b/crates/matrix-sdk-ffi/src/api.udl new file mode 100644 index 000000000..bd34a4872 --- /dev/null +++ b/crates/matrix-sdk-ffi/src/api.udl @@ -0,0 +1,137 @@ +namespace sdk { + [Throws=ClientError] + Client login_new_client(string base_path, string username, string password); + + [Throws=ClientError] + Client guest_client(string base_path, string homeserver); + + [Throws=ClientError] + Client login_with_token(string base_path, string restore_token); + + MediaSource media_source_from_url(string url); +}; + +[Error] +interface ClientError { + Generic(string msg); +}; + +callback interface ClientDelegate { + void did_receive_sync_update(); +}; + +interface Client { + void set_delegate(ClientDelegate? delegate); + + void start_sync(); + + [Throws=ClientError] + string restore_token(); + + boolean is_guest(); + + boolean has_first_synced(); + + boolean is_syncing(); + + [Throws=ClientError] + string user_id(); + + [Throws=ClientError] + string display_name(); + + [Throws=ClientError] + string avatar_url(); + + [Throws=ClientError] + string device_id(); + + sequence rooms(); + + [Throws=ClientError] + sequence load_image(MediaSource source); +}; + +callback interface RoomDelegate { + void did_receive_message(AnyMessage message); +}; + +interface Room { + void set_delegate(RoomDelegate? delegate); + + string id(); + + [Throws=ClientError] + string display_name(); + + string? avatar_url(); + + [Throws=ClientError] + string? member_avatar_url(string user_id); + + [Throws=ClientError] + string? member_display_name(string user_id); + + boolean is_direct(); + + boolean is_public(); + + boolean is_space(); + + boolean is_encrypted(); + + boolean is_tombstoned(); + + string? name(); + + string? topic(); + + BackwardsStream? start_live_event_listener(); + + void stop_live_event_listener(); +}; + +interface BackwardsStream { + sequence paginate_backwards(u64 count); +}; + +interface AnyMessage { + TextMessage? text_message(); + ImageMessage? image_message(); + NoticeMessage? notice_message(); + EmoteMessage? emote_message(); +}; + +interface BaseMessage { + string id(); + string body(); + string sender(); + u64 origin_server_ts(); +}; + +interface TextMessage { + BaseMessage base_message(); + string? html_body(); +}; + +interface ImageMessage { + BaseMessage base_message(); + MediaSource source(); + u64? width(); + u64? height(); + string? blurhash(); +}; + +interface NoticeMessage { + BaseMessage base_message(); + string? html_body(); +}; + +interface EmoteMessage { + BaseMessage base_message(); + string? html_body(); +}; + +interface MediaSource { + string url(); +}; diff --git a/crates/matrix-sdk-ffi/src/backward_stream.rs b/crates/matrix-sdk-ffi/src/backward_stream.rs new file mode 100644 index 000000000..087c1ad0e --- /dev/null +++ b/crates/matrix-sdk-ffi/src/backward_stream.rs @@ -0,0 +1,42 @@ +use core::pin::Pin; +use std::sync::Arc; + +use futures_core::Stream; +use matrix_sdk::{deserialized_responses::SyncRoomEvent, locks::Mutex}; +use tokio_stream::StreamExt; +use tracing::error; + +use super::{ + messages::{sync_event_to_message, AnyMessage}, + RUNTIME, +}; + +type MsgStream = Pin> + Send>>; + +pub struct BackwardsStream { + stream: Arc>, +} + +impl BackwardsStream { + pub fn new(stream: MsgStream) -> Self { + BackwardsStream { stream: Arc::new(Mutex::new(Box::pin(stream))) } + } + + pub fn paginate_backwards(&self, count: u64) -> Vec> { + let stream = self.stream.clone(); + RUNTIME.block_on(async move { + let mut stream = stream.lock().await; + (&mut *stream) + .take(count as usize) + .filter_map(|r| match r { + Ok(ev) => sync_event_to_message(ev), + Err(e) => { + error!("Pagniation error: {e}"); + None + } + }) + .collect() + .await + }) + } +} diff --git a/crates/matrix-sdk-ffi/src/client.rs b/crates/matrix-sdk-ffi/src/client.rs new file mode 100644 index 000000000..387ae2e10 --- /dev/null +++ b/crates/matrix-sdk-ffi/src/client.rs @@ -0,0 +1,163 @@ +use std::sync::Arc; + +use matrix_sdk::{ + config::SyncSettings, + media::{MediaFormat, MediaRequest}, + ruma::{ + api::client::{ + filter::{FilterDefinition, LazyLoadOptions, RoomEventFilter, RoomFilter}, + sync::sync_events::v3::Filter, + }, + events::room::MediaSource, + }, + Client as MatrixClient, LoopCtrl, +}; +use parking_lot::RwLock; + +use super::{room::Room, ClientState, RestoreToken, RUNTIME}; + +impl std::ops::Deref for Client { + type Target = MatrixClient; + fn deref(&self) -> &MatrixClient { + &self.client + } +} + +pub trait ClientDelegate: Sync + Send { + fn did_receive_sync_update(&self); +} + +#[derive(Clone)] +pub struct Client { + client: MatrixClient, + state: Arc>, + delegate: Arc>>>, +} + +impl Client { + pub fn new(client: MatrixClient, state: ClientState) -> Self { + Client { + client, + state: Arc::new(RwLock::new(state)), + delegate: Arc::new(RwLock::new(None)), + } + } + + pub fn set_delegate(&self, delegate: Option>) { + *self.delegate.write() = delegate; + } + + pub fn start_sync(&self) { + let client = self.client.clone(); + let state = self.state.clone(); + let delegate = self.delegate.clone(); + RUNTIME.spawn(async move { + let mut filter = FilterDefinition::default(); + let mut room_filter = RoomFilter::default(); + let mut event_filter = RoomEventFilter::default(); + + event_filter.lazy_load_options = + LazyLoadOptions::Enabled { include_redundant_members: false }; + room_filter.state = event_filter; + filter.room = room_filter; + + let filter_id = client.get_or_upload_filter("sync", filter).await.unwrap(); + + let sync_settings = SyncSettings::new().filter(Filter::FilterId(&filter_id)); + + client + .sync_with_callback(sync_settings, |_| async { + if !state.read().has_first_synced { + state.write().has_first_synced = true + } + + if state.read().should_stop_syncing { + state.write().is_syncing = false; + return LoopCtrl::Break; + } else if !state.read().is_syncing { + state.write().is_syncing = true; + } + + if let Some(ref delegate) = *delegate.read() { + delegate.did_receive_sync_update() + } + LoopCtrl::Continue + }) + .await; + }); + } + + /// Indication whether we've received a first sync response since + /// establishing the client (in memory) + pub fn has_first_synced(&self) -> bool { + self.state.read().has_first_synced + } + + /// Indication whether we are currently syncing + pub fn is_syncing(&self) -> bool { + self.state.read().has_first_synced + } + + /// Is this a guest account? + pub fn is_guest(&self) -> bool { + self.state.read().is_guest + } + + pub fn restore_token(&self) -> anyhow::Result { + RUNTIME.block_on(async move { + let session = self.client.session().await.expect("Missing session"); + let homeurl = self.client.homeserver().await.into(); + Ok(serde_json::to_string(&RestoreToken { + session, + homeurl, + is_guest: self.state.read().is_guest, + })?) + }) + } + + pub fn rooms(&self) -> Vec> { + self.client.rooms().into_iter().map(|room| Arc::new(Room::new(room))).collect() + } + + pub fn user_id(&self) -> anyhow::Result { + let l = self.client.clone(); + RUNTIME.block_on(async move { + let user_id = l.user_id().await.expect("No User ID found"); + Ok(user_id.to_string()) + }) + } + + pub fn display_name(&self) -> anyhow::Result { + let l = self.client.clone(); + RUNTIME.block_on(async move { + let display_name = l.account().get_display_name().await?.expect("No User ID found"); + Ok(display_name) + }) + } + + pub fn avatar_url(&self) -> anyhow::Result { + let l = self.client.clone(); + RUNTIME.block_on(async move { + let avatar_url = l.account().get_avatar_url().await?.expect("No User ID found"); + Ok(avatar_url.to_string()) + }) + } + + pub fn device_id(&self) -> anyhow::Result { + let l = self.client.clone(); + RUNTIME.block_on(async move { + let device_id = l.device_id().await.expect("No Device ID found"); + Ok(device_id.to_string()) + }) + } + + pub fn load_image(&self, media_source: Arc) -> anyhow::Result> { + let l = self.client.clone(); + let source = (*media_source).clone(); + + RUNTIME.block_on(async move { + Ok(l.get_media_content(&MediaRequest { source, format: MediaFormat::File }, true) + .await?) + }) + } +} diff --git a/crates/matrix-sdk-ffi/src/lib.rs b/crates/matrix-sdk-ffi/src/lib.rs new file mode 100644 index 000000000..6407aca7f --- /dev/null +++ b/crates/matrix-sdk-ffi/src/lib.rs @@ -0,0 +1,110 @@ +// TODO: target-os conditional would be good. + +#![allow(unused_qualifications)] + +pub mod backward_stream; +pub mod client; +pub mod messages; +pub mod room; + +use std::{fs, path, sync::Arc}; + +use client::Client; +use matrix_sdk::{store::make_store_config, Client as MatrixClient, ClientBuilder, Session}; +use once_cell::sync::Lazy; +use sanitize_filename_reader_friendly::sanitize; +use serde::{Deserialize, Serialize}; +use tokio::runtime::Runtime; + +pub static RUNTIME: Lazy = + Lazy::new(|| Runtime::new().expect("Can't start Tokio runtime")); + +pub use matrix_sdk::ruma::{api::client::account::register, UserId}; + +pub use self::{backward_stream::*, client::*, messages::*, room::*}; + +pub fn guest_client(base_path: String, homeurl: String) -> anyhow::Result> { + let builder = new_client_builder(base_path, homeurl.clone())?.homeserver_url(&homeurl); + let mut guest_registration = register::v3::Request::new(); + guest_registration.kind = register::RegistrationKind::Guest; + RUNTIME.block_on(async move { + let client = builder.build().await?; + let register = client.register(guest_registration).await?; + let session = Session { + access_token: register.access_token.expect("no access token given"), + user_id: register.user_id, + device_id: register.device_id.clone().expect("device id is given by server"), + }; + client.restore_login(session).await?; + let c = Client::new(client, ClientState { is_guest: true, ..ClientState::default() }); + Ok(Arc::new(c)) + }) +} + +pub fn login_with_token(base_path: String, restore_token: String) -> anyhow::Result> { + let RestoreToken { session, homeurl, is_guest } = serde_json::from_str(&restore_token)?; + let builder = new_client_builder(base_path, session.user_id.to_string())? + .homeserver_url(&homeurl) + .user_id(&session.user_id); + // First we need to log in. + RUNTIME.block_on(async move { + let client = builder.build().await?; + client.restore_login(session).await?; + let c = Client::new(client, ClientState { is_guest, ..ClientState::default() }); + Ok(Arc::new(c)) + }) +} + +pub fn login_new_client( + base_path: String, + username: String, + password: String, +) -> anyhow::Result> { + let builder = new_client_builder(base_path, username.clone())?; + let user = Box::::try_from(username)?; + // First we need to log in. + RUNTIME.block_on(async move { + let client = builder.user_id(&user).build().await?; + client.login(user, &password, None, None).await?; + let c = Client::new(client, ClientState { is_guest: false, ..ClientState::default() }); + Ok(Arc::new(c)) + }) +} + +fn new_client_builder(base_path: String, home: String) -> anyhow::Result { + let data_path = path::PathBuf::from(base_path).join(sanitize(&home)); + + fs::create_dir_all(&data_path)?; + let store_config = make_store_config(&data_path, None)?; + + Ok(MatrixClient::builder().user_agent("rust-sdk-ios").store_config(store_config)) +} + +#[derive(Default, Debug)] +pub struct ClientState { + is_guest: bool, + has_first_synced: bool, + is_syncing: bool, + should_stop_syncing: bool, +} + +#[derive(Serialize, Deserialize)] +struct RestoreToken { + is_guest: bool, + homeurl: String, + session: Session, +} + +#[derive(thiserror::Error, Debug)] +pub enum ClientError { + #[error("client error: {msg}")] + Generic { msg: String }, +} + +impl From for ClientError { + fn from(e: anyhow::Error) -> ClientError { + ClientError::Generic { msg: e.to_string() } + } +} + +uniffi_macros::include_scaffolding!("api"); diff --git a/crates/matrix-sdk-ffi/src/messages.rs b/crates/matrix-sdk-ffi/src/messages.rs new file mode 100644 index 000000000..533b43d02 --- /dev/null +++ b/crates/matrix-sdk-ffi/src/messages.rs @@ -0,0 +1,242 @@ +use std::sync::Arc; + +use extension_trait::extension_trait; +pub use matrix_sdk::ruma::events::room::MediaSource; +use matrix_sdk::{ + deserialized_responses::SyncRoomEvent, + ruma::events::{ + room::{ + message::{ImageMessageEventContent, MessageFormat, MessageType}, + ImageInfo, + }, + AnySyncMessageLikeEvent, AnySyncRoomEvent, SyncMessageLikeEvent, + }, +}; + +#[derive(Clone)] +pub struct BaseMessage { + id: String, + body: String, + sender: String, + origin_server_ts: u64, +} + +impl BaseMessage { + pub fn id(&self) -> String { + self.id.clone() + } + + pub fn body(&self) -> String { + self.body.clone() + } + + pub fn sender(&self) -> String { + self.sender.clone() + } + + pub fn origin_server_ts(&self) -> u64 { + self.origin_server_ts + } +} + +pub struct TextMessage { + base_message: Arc, + html_body: Option, +} + +impl TextMessage { + pub fn base_message(&self) -> Arc { + self.base_message.clone() + } + + pub fn html_body(&self) -> Option { + self.html_body.clone() + } +} + +pub struct ImageMessage { + base_message: Arc, + source: Arc, + info: Option>, +} + +impl ImageMessage { + pub fn base_message(&self) -> Arc { + self.base_message.clone() + } + + pub fn source(&self) -> Arc { + self.source.clone() + } + + pub fn width(&self) -> Option { + self.info.clone()?.width?.try_into().ok() + } + + pub fn height(&self) -> Option { + self.info.clone()?.height?.try_into().ok() + } + + pub fn blurhash(&self) -> Option { + self.info.clone()?.blurhash + } +} + +pub struct NoticeMessage { + base_message: Arc, + html_body: Option, +} + +impl NoticeMessage { + pub fn base_message(&self) -> Arc { + self.base_message.clone() + } + + pub fn html_body(&self) -> Option { + self.html_body.clone() + } +} + +pub struct EmoteMessage { + base_message: Arc, + html_body: Option, +} + +impl EmoteMessage { + pub fn base_message(&self) -> Arc { + self.base_message.clone() + } + + pub fn html_body(&self) -> Option { + self.html_body.clone() + } +} + +pub struct AnyMessage { + text: Option>, + image: Option>, + notice: Option>, + emote: Option>, +} + +impl AnyMessage { + pub fn text_message(&self) -> Option> { + self.text.clone() + } + + pub fn image_message(&self) -> Option> { + self.image.clone() + } + + pub fn notice_message(&self) -> Option> { + self.notice.clone() + } + + pub fn emote_message(&self) -> Option> { + self.emote.clone() + } +} + +pub fn sync_event_to_message(sync_event: SyncRoomEvent) -> Option> { + match sync_event.event.deserialize() { + Ok(AnySyncRoomEvent::MessageLike(AnySyncMessageLikeEvent::RoomMessage( + SyncMessageLikeEvent::Original(m), + ))) => { + let base_message = Arc::new(BaseMessage { + id: m.event_id.to_string(), + body: m.content.body().to_owned(), + sender: m.sender.to_string(), + origin_server_ts: m.origin_server_ts.as_secs().into(), + }); + + match m.content.msgtype { + MessageType::Image(ImageMessageEventContent { source, info, .. }) => { + let any_message = AnyMessage { + text: None, + image: Some(Arc::new(ImageMessage { + base_message, + source: Arc::new(source), + info, + })), + notice: None, + emote: None, + }; + + Some(Arc::new(any_message)) + } + MessageType::Text(content) => { + let mut html_body: Option = None; + if let Some(formatted_body) = content.formatted { + if formatted_body.format == MessageFormat::Html { + html_body = Some(formatted_body.body); + } + } + + let any_message = AnyMessage { + text: Some(Arc::new(TextMessage { base_message, html_body })), + image: None, + notice: None, + emote: None, + }; + Some(Arc::new(any_message)) + } + MessageType::Notice(content) => { + let mut html_body: Option = None; + if let Some(formatted_body) = content.formatted { + if formatted_body.format == MessageFormat::Html { + html_body = Some(formatted_body.body); + } + } + + let any_message = AnyMessage { + text: None, + image: None, + notice: Some(Arc::new(NoticeMessage { base_message, html_body })), + emote: None, + }; + Some(Arc::new(any_message)) + } + MessageType::Emote(content) => { + let mut html_body: Option = None; + if let Some(formatted_body) = content.formatted { + if formatted_body.format == MessageFormat::Html { + html_body = Some(formatted_body.body); + } + } + + let any_message = AnyMessage { + text: None, + image: None, + notice: None, + emote: Some(Arc::new(EmoteMessage { base_message, html_body })), + }; + Some(Arc::new(any_message)) + } + _ => { + let any_message = AnyMessage { + text: Some(Arc::new(TextMessage { base_message, html_body: None })), + image: None, + notice: None, + emote: None, + }; + Some(Arc::new(any_message)) + } + } + } + _ => None, + } +} + +pub fn media_source_from_url(url: String) -> Arc { + Arc::new(MediaSource::Plain(url.into())) +} + +#[extension_trait] +pub impl MediaSourceExt for MediaSource { + fn url(&self) -> String { + match self { + MediaSource::Plain(url) => url.to_string(), + MediaSource::Encrypted(file) => file.url.to_string(), + } + } +} diff --git a/crates/matrix-sdk-ffi/src/room.rs b/crates/matrix-sdk-ffi/src/room.rs new file mode 100644 index 000000000..b0817878b --- /dev/null +++ b/crates/matrix-sdk-ffi/src/room.rs @@ -0,0 +1,143 @@ +use std::sync::Arc; + +use anyhow::Result; +use futures_util::{pin_mut, StreamExt}; +use matrix_sdk::{room::Room as MatrixRoom, ruma::UserId}; +use parking_lot::RwLock; + +use super::{ + backward_stream::BackwardsStream, + messages::{sync_event_to_message, AnyMessage}, + RUNTIME, +}; + +pub trait RoomDelegate: Sync + Send { + fn did_receive_message(&self, messages: Arc); +} + +pub struct Room { + room: MatrixRoom, + delegate: Arc>>>, + is_listening_to_live_events: Arc>, +} + +impl Room { + pub fn new(room: MatrixRoom) -> Self { + Room { + room, + delegate: Arc::new(RwLock::new(None)), + is_listening_to_live_events: Arc::new(RwLock::new(false)), + } + } + + pub fn set_delegate(&self, delegate: Option>) { + *self.delegate.write() = delegate; + } + + pub fn id(&self) -> String { + self.room.room_id().to_string() + } + + pub fn name(&self) -> Option { + self.room.name() + } + + pub fn display_name(&self) -> Result { + let r = self.room.clone(); + RUNTIME.block_on(async move { Ok(r.display_name().await?) }) + } + + pub fn topic(&self) -> Option { + self.room.topic() + } + + pub fn avatar_url(&self) -> Option { + self.room.avatar_url().map(|m| m.to_string()) + } + + pub fn member_avatar_url(&self, user_id: String) -> Result> { + let room = self.room.clone(); + let user_id = user_id; + RUNTIME.block_on(async move { + let user_id = <&UserId>::try_from(&*user_id).expect("Invalid user id."); + let member = room.get_member(user_id).await?.expect("No user found"); + let avatar_url_string = member.avatar_url().map(|m| m.to_string()); + Ok(avatar_url_string) + }) + } + + pub fn member_display_name(&self, user_id: String) -> Result> { + let room = self.room.clone(); + let user_id = user_id; + RUNTIME.block_on(async move { + let user_id = <&UserId>::try_from(&*user_id).expect("Invalid user id."); + let member = room.get_member(user_id).await?.expect("No user found"); + let avatar_url_string = member.display_name().map(|m| m.to_owned()); + Ok(avatar_url_string) + }) + } + + pub fn is_direct(&self) -> bool { + self.room.is_direct() + } + + pub fn is_public(&self) -> bool { + self.room.is_public() + } + + pub fn is_encrypted(&self) -> bool { + self.room.is_encrypted() + } + + pub fn is_space(&self) -> bool { + self.room.is_space() + } + + pub fn is_tombstoned(&self) -> bool { + self.room.is_tombstoned() + } + + pub fn start_live_event_listener(&self) -> Option> { + if *self.is_listening_to_live_events.read() { + return None; + } + + *self.is_listening_to_live_events.write() = true; + + let room = self.room.clone(); + let delegate = self.delegate.clone(); + let is_listening_to_live_events = self.is_listening_to_live_events.clone(); + + let (forward_stream, backwards) = RUNTIME.block_on(async move { + room.timeline().await.expect("Failed acquiring timeline streams") + }); + + RUNTIME.spawn(async move { + pin_mut!(forward_stream); + + while let Some(sync_event) = forward_stream.next().await { + if !(*is_listening_to_live_events.read()) { + return; + } + + if let Some(delegate) = &*delegate.read() { + if let Some(message) = sync_event_to_message(sync_event) { + delegate.did_receive_message(message) + } + } + } + }); + Some(Arc::new(BackwardsStream::new(Box::pin(backwards)))) + } + + pub fn stop_live_event_listener(&self) { + *self.is_listening_to_live_events.write() = false; + } +} + +impl std::ops::Deref for Room { + type Target = MatrixRoom; + fn deref(&self) -> &MatrixRoom { + &self.room + } +} From 56cfe8f231ad0abd1541995813255ccd17e27c9f Mon Sep 17 00:00:00 2001 From: Jonas Platte Date: Wed, 13 Apr 2022 11:54:42 +0200 Subject: [PATCH 02/51] squash! feat: Initial apple platforms support Some FFI API cleanup --- crates/matrix-sdk-ffi/src/api.udl | 27 ++++++++++----------------- crates/matrix-sdk-ffi/src/client.rs | 2 +- 2 files changed, 11 insertions(+), 18 deletions(-) diff --git a/crates/matrix-sdk-ffi/src/api.udl b/crates/matrix-sdk-ffi/src/api.udl index bd34a4872..194d4f10c 100644 --- a/crates/matrix-sdk-ffi/src/api.udl +++ b/crates/matrix-sdk-ffi/src/api.udl @@ -49,7 +49,7 @@ interface Client { sequence rooms(); [Throws=ClientError] - sequence load_image(MediaSource source); + sequence get_media_content(MediaSource source); }; callback interface RoomDelegate { @@ -60,32 +60,25 @@ interface Room { void set_delegate(RoomDelegate? delegate); string id(); + string? name(); + string? topic(); + string? avatar_url(); + + boolean is_direct(); + boolean is_public(); + boolean is_space(); + boolean is_encrypted(); + boolean is_tombstoned(); [Throws=ClientError] string display_name(); - string? avatar_url(); - [Throws=ClientError] string? member_avatar_url(string user_id); [Throws=ClientError] string? member_display_name(string user_id); - boolean is_direct(); - - boolean is_public(); - - boolean is_space(); - - boolean is_encrypted(); - - boolean is_tombstoned(); - - string? name(); - - string? topic(); - BackwardsStream? start_live_event_listener(); void stop_live_event_listener(); diff --git a/crates/matrix-sdk-ffi/src/client.rs b/crates/matrix-sdk-ffi/src/client.rs index 387ae2e10..06eb563e8 100644 --- a/crates/matrix-sdk-ffi/src/client.rs +++ b/crates/matrix-sdk-ffi/src/client.rs @@ -151,7 +151,7 @@ impl Client { }) } - pub fn load_image(&self, media_source: Arc) -> anyhow::Result> { + pub fn get_media_content(&self, media_source: Arc) -> anyhow::Result> { let l = self.client.clone(); let source = (*media_source).clone(); From 9909cb597a656e4d70f22167cb5ae0e7c6976f28 Mon Sep 17 00:00:00 2001 From: Jonas Platte Date: Wed, 13 Apr 2022 12:07:55 +0200 Subject: [PATCH 03/51] squash! feat: Initial apple platforms support Enable sending of messages --- crates/matrix-sdk-ffi/Cargo.toml | 2 +- crates/matrix-sdk-ffi/src/api.udl | 8 +++++++- crates/matrix-sdk-ffi/src/client.rs | 5 +++++ crates/matrix-sdk-ffi/src/messages.rs | 6 +++++- crates/matrix-sdk-ffi/src/room.rs | 20 ++++++++++++++++++-- 5 files changed, 36 insertions(+), 5 deletions(-) diff --git a/crates/matrix-sdk-ffi/Cargo.toml b/crates/matrix-sdk-ffi/Cargo.toml index e773e95c6..0682f5a54 100644 --- a/crates/matrix-sdk-ffi/Cargo.toml +++ b/crates/matrix-sdk-ffi/Cargo.toml @@ -24,7 +24,7 @@ anyhow = "1.0.51" extension-trait = "1.0.1" futures-core = "0.3.17" futures-util = { version = "0.3.17", default-features = false } -matrix-sdk = { path = "../matrix-sdk" } +matrix-sdk = { path = "../matrix-sdk", features = ["markdown"] } once_cell = "1.10.0" parking_lot = "0.12.0" sanitize-filename-reader-friendly = "2.2.1" diff --git a/crates/matrix-sdk-ffi/src/api.udl b/crates/matrix-sdk-ffi/src/api.udl index 194d4f10c..e98723cef 100644 --- a/crates/matrix-sdk-ffi/src/api.udl +++ b/crates/matrix-sdk-ffi/src/api.udl @@ -9,6 +9,8 @@ namespace sdk { Client login_with_token(string base_path, string restore_token); MediaSource media_source_from_url(string url); + MessageEventContent message_event_content_from_markdown(string md); + string gen_txn_id(); }; [Error] @@ -80,14 +82,18 @@ interface Room { string? member_display_name(string user_id); BackwardsStream? start_live_event_listener(); - void stop_live_event_listener(); + + [Throws=ClientError] + void send(MessageEventContent msg, string? txn_id); }; interface BackwardsStream { sequence paginate_backwards(u64 count); }; +interface MessageEventContent {}; + interface AnyMessage { TextMessage? text_message(); ImageMessage? image_message(); diff --git a/crates/matrix-sdk-ffi/src/client.rs b/crates/matrix-sdk-ffi/src/client.rs index 06eb563e8..a1ad7547f 100644 --- a/crates/matrix-sdk-ffi/src/client.rs +++ b/crates/matrix-sdk-ffi/src/client.rs @@ -9,6 +9,7 @@ use matrix_sdk::{ sync::sync_events::v3::Filter, }, events::room::MediaSource, + TransactionId, }, Client as MatrixClient, LoopCtrl, }; @@ -161,3 +162,7 @@ impl Client { }) } } + +pub fn gen_txn_id() -> String { + TransactionId::new().into() +} diff --git a/crates/matrix-sdk-ffi/src/messages.rs b/crates/matrix-sdk-ffi/src/messages.rs index 533b43d02..4ad317cd2 100644 --- a/crates/matrix-sdk-ffi/src/messages.rs +++ b/crates/matrix-sdk-ffi/src/messages.rs @@ -1,7 +1,7 @@ use std::sync::Arc; use extension_trait::extension_trait; -pub use matrix_sdk::ruma::events::room::MediaSource; +pub use matrix_sdk::ruma::events::room::{message::RoomMessageEventContent, MediaSource}; use matrix_sdk::{ deserialized_responses::SyncRoomEvent, ruma::events::{ @@ -231,6 +231,10 @@ pub fn media_source_from_url(url: String) -> Arc { Arc::new(MediaSource::Plain(url.into())) } +pub fn message_event_content_from_markdown(md: String) -> Arc { + Arc::new(RoomMessageEventContent::text_markdown(md)) +} + #[extension_trait] pub impl MediaSourceExt for MediaSource { fn url(&self) -> String { diff --git a/crates/matrix-sdk-ffi/src/room.rs b/crates/matrix-sdk-ffi/src/room.rs index b0817878b..da31916b9 100644 --- a/crates/matrix-sdk-ffi/src/room.rs +++ b/crates/matrix-sdk-ffi/src/room.rs @@ -1,8 +1,11 @@ use std::sync::Arc; -use anyhow::Result; +use anyhow::{bail, Result}; use futures_util::{pin_mut, StreamExt}; -use matrix_sdk::{room::Room as MatrixRoom, ruma::UserId}; +use matrix_sdk::{ + room::Room as MatrixRoom, + ruma::{events::room::message::RoomMessageEventContent, UserId}, +}; use parking_lot::RwLock; use super::{ @@ -133,6 +136,19 @@ impl Room { pub fn stop_live_event_listener(&self) { *self.is_listening_to_live_events.write() = false; } + + pub fn send(&self, msg: Arc, txn_id: Option) -> Result<()> { + let room = match &self.room { + MatrixRoom::Joined(j) => j.clone(), + _ => bail!("Can't send to a room that isn't in joined state"), + }; + + RUNTIME.block_on(async move { + room.send((*msg).to_owned(), txn_id.as_deref().map(Into::into)).await + })?; + + Ok(()) + } } impl std::ops::Deref for Room { From 40dcc988d69bf86a9f9114933b8503b1b52d2480 Mon Sep 17 00:00:00 2001 From: Jonas Platte Date: Wed, 13 Apr 2022 13:36:41 +0200 Subject: [PATCH 04/51] fixup! feat: Initial apple platforms support --- crates/matrix-sdk-ffi/src/api.udl | 3 ++- crates/matrix-sdk-ffi/src/client.rs | 2 +- crates/matrix-sdk-ffi/src/messages.rs | 14 +++++++++++--- 3 files changed, 14 insertions(+), 5 deletions(-) diff --git a/crates/matrix-sdk-ffi/src/api.udl b/crates/matrix-sdk-ffi/src/api.udl index e98723cef..a2af0c032 100644 --- a/crates/matrix-sdk-ffi/src/api.udl +++ b/crates/matrix-sdk-ffi/src/api.udl @@ -10,7 +10,7 @@ namespace sdk { MediaSource media_source_from_url(string url); MessageEventContent message_event_content_from_markdown(string md); - string gen_txn_id(); + string gen_transaction_id(); }; [Error] @@ -106,6 +106,7 @@ interface BaseMessage { string body(); string sender(); u64 origin_server_ts(); + string? transaction_id(); }; interface TextMessage { diff --git a/crates/matrix-sdk-ffi/src/client.rs b/crates/matrix-sdk-ffi/src/client.rs index a1ad7547f..3d90ebf55 100644 --- a/crates/matrix-sdk-ffi/src/client.rs +++ b/crates/matrix-sdk-ffi/src/client.rs @@ -163,6 +163,6 @@ impl Client { } } -pub fn gen_txn_id() -> String { +pub fn gen_transaction_id() -> String { TransactionId::new().into() } diff --git a/crates/matrix-sdk-ffi/src/messages.rs b/crates/matrix-sdk-ffi/src/messages.rs index 4ad317cd2..96eb7489a 100644 --- a/crates/matrix-sdk-ffi/src/messages.rs +++ b/crates/matrix-sdk-ffi/src/messages.rs @@ -1,7 +1,9 @@ use std::sync::Arc; use extension_trait::extension_trait; -pub use matrix_sdk::ruma::events::room::{message::RoomMessageEventContent, MediaSource}; +pub use matrix_sdk::ruma::events::room::{ + message::RoomMessageEventContent as MessageEventContent, MediaSource, +}; use matrix_sdk::{ deserialized_responses::SyncRoomEvent, ruma::events::{ @@ -19,6 +21,7 @@ pub struct BaseMessage { body: String, sender: String, origin_server_ts: u64, + transaction_id: Option, } impl BaseMessage { @@ -37,6 +40,10 @@ impl BaseMessage { pub fn origin_server_ts(&self) -> u64 { self.origin_server_ts } + + pub fn transaction_id(&self) -> Option { + self.transaction_id.clone() + } } pub struct TextMessage { @@ -147,6 +154,7 @@ pub fn sync_event_to_message(sync_event: SyncRoomEvent) -> Option Arc { Arc::new(MediaSource::Plain(url.into())) } -pub fn message_event_content_from_markdown(md: String) -> Arc { - Arc::new(RoomMessageEventContent::text_markdown(md)) +pub fn message_event_content_from_markdown(md: String) -> Arc { + Arc::new(MessageEventContent::text_markdown(md)) } #[extension_trait] From 1fdd1ab23ab40daef04f0b1b651e5e98155b2be0 Mon Sep 17 00:00:00 2001 From: Jonas Platte Date: Wed, 11 May 2022 11:57:27 +0200 Subject: [PATCH 05/51] Cleanup after rebase --- crates/matrix-sdk-ffi/Cargo.toml | 2 +- crates/matrix-sdk-ffi/src/client.rs | 2 +- crates/matrix-sdk-ffi/src/messages.rs | 2 +- crates/matrix-sdk-ffi/src/room.rs | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/crates/matrix-sdk-ffi/Cargo.toml b/crates/matrix-sdk-ffi/Cargo.toml index 0682f5a54..015d8d860 100644 --- a/crates/matrix-sdk-ffi/Cargo.toml +++ b/crates/matrix-sdk-ffi/Cargo.toml @@ -24,7 +24,7 @@ anyhow = "1.0.51" extension-trait = "1.0.1" futures-core = "0.3.17" futures-util = { version = "0.3.17", default-features = false } -matrix-sdk = { path = "../matrix-sdk", features = ["markdown"] } +matrix-sdk = { path = "../matrix-sdk", features = ["experimental-timeline", "markdown"] } once_cell = "1.10.0" parking_lot = "0.12.0" sanitize-filename-reader-friendly = "2.2.1" diff --git a/crates/matrix-sdk-ffi/src/client.rs b/crates/matrix-sdk-ffi/src/client.rs index 3d90ebf55..ef7cf5e0d 100644 --- a/crates/matrix-sdk-ffi/src/client.rs +++ b/crates/matrix-sdk-ffi/src/client.rs @@ -164,5 +164,5 @@ impl Client { } pub fn gen_transaction_id() -> String { - TransactionId::new().into() + TransactionId::new().to_string() } diff --git a/crates/matrix-sdk-ffi/src/messages.rs b/crates/matrix-sdk-ffi/src/messages.rs index 96eb7489a..5730ff98d 100644 --- a/crates/matrix-sdk-ffi/src/messages.rs +++ b/crates/matrix-sdk-ffi/src/messages.rs @@ -154,7 +154,7 @@ pub fn sync_event_to_message(sync_event: SyncRoomEvent) -> Option Result { let r = self.room.clone(); - RUNTIME.block_on(async move { Ok(r.display_name().await?) }) + RUNTIME.block_on(async move { Ok(r.display_name().await?.to_string()) }) } pub fn topic(&self) -> Option { From bd4763235aebd4df11eb7cdc70a86613a1147260 Mon Sep 17 00:00:00 2001 From: Stefan Ceriu Date: Thu, 12 May 2022 16:49:49 +0300 Subject: [PATCH 06/51] chore(matrix-sdk-ffi) Use stable toolchain for targeting aarch64-apple-ios-sim --- apple/MatrixRustSDK/build_xcframework.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apple/MatrixRustSDK/build_xcframework.sh b/apple/MatrixRustSDK/build_xcframework.sh index 9a2474918..dbf73e72e 100755 --- a/apple/MatrixRustSDK/build_xcframework.sh +++ b/apple/MatrixRustSDK/build_xcframework.sh @@ -24,7 +24,7 @@ cargo build --locked -p matrix-sdk-ffi ${REL_FLAG} --target "aarch64-apple-darwi cargo build --locked -p matrix-sdk-ffi ${REL_FLAG} --target "x86_64-apple-darwin" # iOS Simulator -cargo +nightly build --locked -p matrix-sdk-ffi ${REL_FLAG} --target "aarch64-apple-ios-sim" +cargo build --locked -p matrix-sdk-ffi ${REL_FLAG} --target "aarch64-apple-ios-sim" cargo build --locked -p matrix-sdk-ffi ${REL_FLAG} --target "x86_64-apple-ios" # Mac Catalyst From 248fff370ab3778042aee63bc63a7acdcd0cb9bf Mon Sep 17 00:00:00 2001 From: Amanda Graven Date: Mon, 16 May 2022 10:04:10 +0200 Subject: [PATCH 07/51] test(base): Remove invalid sync event from json The test json used for mocking a sync response contained an ill-formed event with a room_id key present in the event. Since the deserialization ignores the room_id key, this resulted in the client's membership state evaluating to left going by the contents of the state events, despite the room being in the "joined" section of the sync response. This is a violation of the spec. --- crates/matrix-sdk-test/src/test_json/sync.rs | 24 -------------------- crates/matrix-sdk/src/client/mod.rs | 2 +- 2 files changed, 1 insertion(+), 25 deletions(-) diff --git a/crates/matrix-sdk-test/src/test_json/sync.rs b/crates/matrix-sdk-test/src/test_json/sync.rs index 842f6ac01..265534359 100644 --- a/crates/matrix-sdk-test/src/test_json/sync.rs +++ b/crates/matrix-sdk-test/src/test_json/sync.rs @@ -210,30 +210,6 @@ pub static SYNC: Lazy = Lazy::new(|| { "replaces_state": "$152034819067QWJxM:localhost" } }, - { - "content": { - "membership": "leave", - "reason": "offline", - "avatar_url": "mxc://avatar.com/d0dV9jLpe", - "displayname": "example" - }, - "event_id": "$1585345508297748AIUBh:matrix.org", - "origin_server_ts": 158534550, - "sender": "@example:localhost", - "state_key": "@example:localhost", - "type": "m.room.member", - "unsigned": { - "replaces_state": "$1585345354296486IGZfp:localhost", - "prev_content": { - "avatar_url": "mxc://avatar.com/d0dV9jLpe", - "displayname": "example", - "membership": "join" - }, - "prev_sender": "@example2:localhost", - "age": 6992 - }, - "room_id": "!roomid:room.com" - } ] }, "timeline": { diff --git a/crates/matrix-sdk/src/client/mod.rs b/crates/matrix-sdk/src/client/mod.rs index 06125ad5d..4fd1a8fe9 100644 --- a/crates/matrix-sdk/src/client/mod.rs +++ b/crates/matrix-sdk/src/client/mod.rs @@ -3362,7 +3362,7 @@ pub(crate) mod tests { let room = client.get_joined_room(room_id!("!SVkFJHzfwvuaIEawgC:localhost")).unwrap(); let members: Vec = room.active_members().await.unwrap(); - assert_eq!(1, members.len()); + assert_eq!(2, members.len()); // assert!(room.power_levels.is_some()) } From 2862934b874eeda7467a536f7d6dfa835f4e03a3 Mon Sep 17 00:00:00 2001 From: Benjamin Kampmann Date: Tue, 17 May 2022 12:51:47 +0200 Subject: [PATCH 08/51] style: fix clippy lints for ffi --- apple/MatrixRustSDK/README.md | 4 ++-- crates/matrix-sdk-ffi/Cargo.toml | 5 +---- crates/matrix-sdk-ffi/src/lib.rs | 4 ++-- crates/matrix-sdk-ffi/src/uniffi_api.rs | 5 +++++ 4 files changed, 10 insertions(+), 8 deletions(-) create mode 100644 crates/matrix-sdk-ffi/src/uniffi_api.rs diff --git a/apple/MatrixRustSDK/README.md b/apple/MatrixRustSDK/README.md index bb49cae34..56f749356 100644 --- a/apple/MatrixRustSDK/README.md +++ b/apple/MatrixRustSDK/README.md @@ -29,11 +29,11 @@ The `build_xcframework.sh` script will go through all the steps required to gene The Xcode project is meant to provide a simple example on how to integrate everything together but also a place to run unit and integration tests from. -It's pre-configured to link to the generated .xcframework and .swift files so succesfully running the script first is necessary for it to compile. +It's pre-configured to link to the generated .xcframework and .swift files so successfully running the script first is necessary for it to compile. It makes the compiled code available to swift by importing the C header through its bridging header. -Once all the generated components are available running it should be as easy as chosing a platform and clicking run. +Once all the generated components are available running it should be as easy as choosing a platform and clicking run. ## Distribution The generated framework and Swift code can be distributed and integrated directly but in order to make things simpler we bundle them together as a Swift package available [TBD](here) \ No newline at end of file diff --git a/crates/matrix-sdk-ffi/Cargo.toml b/crates/matrix-sdk-ffi/Cargo.toml index 015d8d860..cf66c99e9 100644 --- a/crates/matrix-sdk-ffi/Cargo.toml +++ b/crates/matrix-sdk-ffi/Cargo.toml @@ -12,9 +12,6 @@ repository = "https://github.com/matrix-org/matrix-rust-sdk" [lib] crate-type = ["cdylib", "staticlib"] -[features] -default = ["with-runtime"] -with-runtime = ["tokio"] [build-dependencies] uniffi_build = { version = "0.17.0", features = ["builtin-bindgen"] } @@ -31,7 +28,7 @@ sanitize-filename-reader-friendly = "2.2.1" serde = { version = "1", features = ["derive"] } serde_json = { version = "1" } thiserror = "1.0.30" -tokio = { version = "1", optional = true, features = ["rt-multi-thread", "macros"] } +tokio = { version = "1", features = ["rt-multi-thread", "macros"] } tokio-stream = "0.1.8" tracing = "0.1.32" uniffi = "0.17.0" diff --git a/crates/matrix-sdk-ffi/src/lib.rs b/crates/matrix-sdk-ffi/src/lib.rs index 6407aca7f..95238e3ee 100644 --- a/crates/matrix-sdk-ffi/src/lib.rs +++ b/crates/matrix-sdk-ffi/src/lib.rs @@ -6,6 +6,7 @@ pub mod backward_stream; pub mod client; pub mod messages; pub mod room; +mod uniffi_api; use std::{fs, path, sync::Arc}; @@ -15,6 +16,7 @@ use once_cell::sync::Lazy; use sanitize_filename_reader_friendly::sanitize; use serde::{Deserialize, Serialize}; use tokio::runtime::Runtime; +pub use uniffi_api::*; pub static RUNTIME: Lazy = Lazy::new(|| Runtime::new().expect("Can't start Tokio runtime")); @@ -106,5 +108,3 @@ impl From for ClientError { ClientError::Generic { msg: e.to_string() } } } - -uniffi_macros::include_scaffolding!("api"); diff --git a/crates/matrix-sdk-ffi/src/uniffi_api.rs b/crates/matrix-sdk-ffi/src/uniffi_api.rs new file mode 100644 index 000000000..119d1d4e5 --- /dev/null +++ b/crates/matrix-sdk-ffi/src/uniffi_api.rs @@ -0,0 +1,5 @@ +#![allow(clippy::all)] + +use crate::*; + +uniffi_macros::include_scaffolding!("api"); From a19999b24062eac3cb5c11c3ad968fa0bc6030e6 Mon Sep 17 00:00:00 2001 From: Benjamin Kampmann Date: Tue, 17 May 2022 13:38:07 +0200 Subject: [PATCH 09/51] docs: fixing broken inner link --- crates/matrix-sdk-crypto/src/machine.rs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/crates/matrix-sdk-crypto/src/machine.rs b/crates/matrix-sdk-crypto/src/machine.rs index 9540cf1c0..69d121657 100644 --- a/crates/matrix-sdk-crypto/src/machine.rs +++ b/crates/matrix-sdk-crypto/src/machine.rs @@ -649,6 +649,8 @@ impl OlmMachine { /// # Panics /// /// Panics if a group session for the given room wasn't shared beforehand. + /// + /// [`share_group_session`]: #method.share_group_session pub async fn encrypt( &self, room_id: &RoomId, From 39f1b9d464664af8d4458f5ce94c7cbd793679c7 Mon Sep 17 00:00:00 2001 From: Benjamin Kampmann Date: Tue, 17 May 2022 13:54:37 +0200 Subject: [PATCH 10/51] docs: fix link Co-authored-by: Jonas Platte --- crates/matrix-sdk-crypto/src/machine.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crates/matrix-sdk-crypto/src/machine.rs b/crates/matrix-sdk-crypto/src/machine.rs index 69d121657..1d79ef5a7 100644 --- a/crates/matrix-sdk-crypto/src/machine.rs +++ b/crates/matrix-sdk-crypto/src/machine.rs @@ -650,7 +650,7 @@ impl OlmMachine { /// /// Panics if a group session for the given room wasn't shared beforehand. /// - /// [`share_group_session`]: #method.share_group_session + /// [`share_group_session`]: Self::share_group_session pub async fn encrypt( &self, room_id: &RoomId, From 5bd7d17234e1ea1df0598e03d8a9be00767c4b19 Mon Sep 17 00:00:00 2001 From: Julian Sparber Date: Tue, 17 May 2022 17:03:28 +0200 Subject: [PATCH 11/51] fix(matrix-sdk): room::Common:event() don't return decryption error --- crates/matrix-sdk/src/room/common.rs | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/crates/matrix-sdk/src/room/common.rs b/crates/matrix-sdk/src/room/common.rs index f2f2393c8..5f6cbd2a5 100644 --- a/crates/matrix-sdk/src/room/common.rs +++ b/crates/matrix-sdk/src/room/common.rs @@ -478,12 +478,15 @@ impl Common { let event = self.client.send(request, None).await?.event; #[cfg(feature = "e2e-encryption")] - if let AnySyncRoomEvent::MessageLike(AnySyncMessageLikeEvent::RoomEncrypted( - SyncMessageLikeEvent::Original(encrypted_event), - )) = event.deserialize_as::()? { - Ok(self.decrypt_event(&encrypted_event).await?) - } else { + if let Ok(AnySyncRoomEvent::MessageLike(AnySyncMessageLikeEvent::RoomEncrypted( + SyncMessageLikeEvent::Original(encrypted_event), + ))) = event.deserialize_as::() + { + if let Ok(event) = self.decrypt_event(&encrypted_event).await { + return Ok(event); + } + } Ok(RoomEvent { event, encryption_info: None }) } From 9c07ff1166a42de928dc47bcf488db71ae05a24d Mon Sep 17 00:00:00 2001 From: Julian Sparber Date: Tue, 17 May 2022 17:22:20 +0200 Subject: [PATCH 12/51] matrix-sdk: room::Common:messages() don't return decryption error If decryption fails we want that the user still has access to the events. This was broken in a previous commit. --- crates/matrix-sdk/src/room/common.rs | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/crates/matrix-sdk/src/room/common.rs b/crates/matrix-sdk/src/room/common.rs index 5f6cbd2a5..6a71dbed2 100644 --- a/crates/matrix-sdk/src/room/common.rs +++ b/crates/matrix-sdk/src/room/common.rs @@ -205,16 +205,17 @@ impl Common { #[cfg(feature = "e2e-encryption")] if let Some(machine) = self.client.olm_machine().await { for event in http_response.chunk { - let decrypted_event = - if let AnySyncRoomEvent::MessageLike(AnySyncMessageLikeEvent::RoomEncrypted( - SyncMessageLikeEvent::Original(encrypted_event), - )) = event.deserialize_as::()? - { - machine.decrypt_room_event(&encrypted_event, room_id).await? - } else { - RoomEvent { event, encryption_info: None } - }; + if let Ok(AnySyncRoomEvent::MessageLike(AnySyncMessageLikeEvent::RoomEncrypted( + SyncMessageLikeEvent::Original(encrypted_event), + ))) = event.deserialize_as::() + { + if let Ok(event) = machine.decrypt_room_event(&encrypted_event, room_id).await { + response.chunk.push(event); + continue; + } + } + let decrypted_event = RoomEvent { event, encryption_info: None }; response.chunk.push(decrypted_event); } } else { From d6f9e5f6b684b129f14dc952c764b75fa634d5b0 Mon Sep 17 00:00:00 2001 From: Julian Sparber Date: Tue, 17 May 2022 17:52:12 +0200 Subject: [PATCH 13/51] Remove extra controll flow --- crates/matrix-sdk/src/room/common.rs | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/crates/matrix-sdk/src/room/common.rs b/crates/matrix-sdk/src/room/common.rs index 6a71dbed2..7730d6c21 100644 --- a/crates/matrix-sdk/src/room/common.rs +++ b/crates/matrix-sdk/src/room/common.rs @@ -205,17 +205,21 @@ impl Common { #[cfg(feature = "e2e-encryption")] if let Some(machine) = self.client.olm_machine().await { for event in http_response.chunk { - if let Ok(AnySyncRoomEvent::MessageLike(AnySyncMessageLikeEvent::RoomEncrypted( - SyncMessageLikeEvent::Original(encrypted_event), - ))) = event.deserialize_as::() + let decrypted_event = if let Ok(AnySyncRoomEvent::MessageLike( + AnySyncMessageLikeEvent::RoomEncrypted(SyncMessageLikeEvent::Original( + encrypted_event, + )), + )) = event.deserialize_as::() { if let Ok(event) = machine.decrypt_room_event(&encrypted_event, room_id).await { - response.chunk.push(event); - continue; + event + } else { + RoomEvent { event, encryption_info: None } } - } + } else { + RoomEvent { event, encryption_info: None } + }; - let decrypted_event = RoomEvent { event, encryption_info: None }; response.chunk.push(decrypted_event); } } else { From ba2cef62b0fc484dbcc3f17f3be59aaa464a029c Mon Sep 17 00:00:00 2001 From: Stefan Ceriu Date: Tue, 17 May 2022 12:22:59 +0300 Subject: [PATCH 14/51] Move apple scripts; tweak the debug one to allow for CI builds --- .../{MatrixRustSDK => }/build_xcframework.sh | 7 +----- .../debug_build_xcframework.sh | 23 ++++++++++++++----- 2 files changed, 18 insertions(+), 12 deletions(-) rename apple/{MatrixRustSDK => }/build_xcframework.sh (91%) rename apple/{MatrixRustSDK => }/debug_build_xcframework.sh (70%) diff --git a/apple/MatrixRustSDK/build_xcframework.sh b/apple/build_xcframework.sh similarity index 91% rename from apple/MatrixRustSDK/build_xcframework.sh rename to apple/build_xcframework.sh index dbf73e72e..c031934d2 100755 --- a/apple/MatrixRustSDK/build_xcframework.sh +++ b/apple/build_xcframework.sh @@ -4,7 +4,7 @@ set -eEu cd "$(dirname "$0")" # Path to the repo root -SRC_ROOT=../.. +SRC_ROOT=.. TARGET_DIR="${SRC_ROOT}/target" @@ -87,8 +87,3 @@ if [ -f "${GENERATED_DIR}/libmatrix_sdk_ffi_macos.a" ]; then rm -rf "${GENERATED if [ -f "${GENERATED_DIR}/libmatrix_sdk_ffi_iossimulator.a" ]; then rm -rf "${GENERATED_DIR}/libmatrix_sdk_ffi_iossimulator.a"; fi if [ -f "${GENERATED_DIR}/libmatrix_sdk_ffi_maccatalyst.a" ]; then rm -rf "${GENERATED_DIR}/libmatrix_sdk_ffi_maccatalyst.a"; fi if [ -d ${HEADERS_DIR} ]; then rm -rf ${HEADERS_DIR}; fi - -# Debug -> Copy generated files over to ../../../matrix-rust-components-swift -# rsync -a --delete "${GENERATED_DIR}/MatrixSDKFFI.xcframework" "../../../matrix-rust-components-swift/" -# rsync -a --delete "${GENERATED_DIR}/swift/" "../../../matrix-rust-components-swift/Sources/MatrixRustSDK" - diff --git a/apple/MatrixRustSDK/debug_build_xcframework.sh b/apple/debug_build_xcframework.sh similarity index 70% rename from apple/MatrixRustSDK/debug_build_xcframework.sh rename to apple/debug_build_xcframework.sh index 0f579c98c..86bc31aec 100755 --- a/apple/MatrixRustSDK/debug_build_xcframework.sh +++ b/apple/debug_build_xcframework.sh @@ -1,10 +1,17 @@ #!/usr/bin/env bash set -eEu -cd "$(dirname "$0")" +IS_CI=false + +if [ $# -eq 1 ]; then + IS_CI=true + echo "Running CI build" +else + echo "Running debug build" +fi # Path to the repo root -SRC_ROOT=../.. +SRC_ROOT=.. TARGET_DIR="${SRC_ROOT}/target" @@ -51,8 +58,12 @@ xcodebuild -create-xcframework \ if [ -f "${GENERATED_DIR}/libmatrix_sdk_ffi_iossimulator.a" ]; then rm -rf "${GENERATED_DIR}/libmatrix_sdk_ffi_iossimulator.a"; fi if [ -d ${HEADERS_DIR} ]; then rm -rf ${HEADERS_DIR}; fi -# Debug -> Copy generated files over to ../../../matrix-rust-components-swift -echo "$(echo "import MatrixSDKFFIWrapper\n"; cat "${SWIFT_DIR}/sdk.swift")" > "${SWIFT_DIR}/sdk.swift" +if [ "$IS_CI" = false ] ; then + echo "Preparing matrix-rust-components-swift" -rsync -a --delete "${GENERATED_DIR}/MatrixSDKFFI.xcframework" "../../../matrix-rust-components-swift/" -rsync -a --delete "${GENERATED_DIR}/swift/" "../../../matrix-rust-components-swift/Sources/MatrixRustSDK" + # Debug -> Copy generated files over to ../../../matrix-rust-components-swift + echo "$(echo "import MatrixSDKFFIWrapper\n"; cat "${SWIFT_DIR}/sdk.swift")" > "${SWIFT_DIR}/sdk.swift" + + rsync -a --delete "${GENERATED_DIR}/MatrixSDKFFI.xcframework" "${SRC_ROOT}/../matrix-rust-components-swift/" + rsync -a --delete "${GENERATED_DIR}/swift/" "${SRC_ROOT}/../matrix-rust-components-swift/Sources/MatrixRustSDK" +fi From 45cb162e5a89e8bbdd80704eded9d2ecf1704ba3 Mon Sep 17 00:00:00 2001 From: Stefan Ceriu Date: Tue, 17 May 2022 12:23:23 +0300 Subject: [PATCH 15/51] Fix sample project, cleanup tests and add github action --- .github/workflows/ffi.yml | 57 +++++++++ .../MatrixRustSDK.xcodeproj/project.pbxproj | 119 ------------------ .../MatrixRustSDK/ClientError+Error.swift | 11 -- .../MatrixRustSDKTests.swift | 31 ++++- .../MatrixRustSDKUITests.swift | 42 ------- apple/build_xcframework.sh | 14 +-- apple/debug_build_xcframework.sh | 13 +- 7 files changed, 101 insertions(+), 186 deletions(-) create mode 100644 .github/workflows/ffi.yml delete mode 100644 apple/MatrixRustSDK/MatrixRustSDK/ClientError+Error.swift delete mode 100644 apple/MatrixRustSDK/MatrixRustSDKUITests/MatrixRustSDKUITests.swift diff --git a/.github/workflows/ffi.yml b/.github/workflows/ffi.yml new file mode 100644 index 000000000..dc62437a9 --- /dev/null +++ b/.github/workflows/ffi.yml @@ -0,0 +1,57 @@ +name: FFI + +on: + workflow_dispatch: + push: + branches: [main] + pull_request: +# branches: [main] +# types: +# - opened +# - reopened +# - synchronize +# - ready_for_review + +env: + CARGO_TERM_COLOR: always + +jobs: + test: + name: Run Apple platform tests + runs-on: macos-12 + + steps: + - name: Checkout + uses: actions/checkout@v1 + + - name: Install Rust + uses: actions-rs/toolchain@v1 + with: + toolchain: stable + profile: minimal + override: true + + - name: Install targets + run: | + rustup target add aarch64-apple-ios-sim + rustup target add x86_64-apple-ios + + - name: Install Uniffi + uses: actions-rs/cargo@v1 + with: + command: install + args: uniffi_bindgen + + - name: Load cache + uses: Swatinem/rust-cache@v1 + + - name: Generate .xcframework + run: sh apple/debug_build_xcframework.sh ci + + - name: Run XCTests + run: | + xcodebuild test \ + -project apple/MatrixRustSDK/MatrixRustSDK.xcodeproj \ + -scheme MatrixRustSDK \ + -sdk iphonesimulator \ + -destination 'platform=iOS Simulator,name=iPhone 13,OS=15.4' \ No newline at end of file diff --git a/apple/MatrixRustSDK/MatrixRustSDK.xcodeproj/project.pbxproj b/apple/MatrixRustSDK/MatrixRustSDK.xcodeproj/project.pbxproj index 04b66cc16..38cc51514 100644 --- a/apple/MatrixRustSDK/MatrixRustSDK.xcodeproj/project.pbxproj +++ b/apple/MatrixRustSDK/MatrixRustSDK.xcodeproj/project.pbxproj @@ -10,12 +10,10 @@ 181AA19B27B52AB40005F102 /* MatrixSDKFFI.xcframework in Frameworks */ = {isa = PBXBuildFile; fileRef = 181AA19A27B52AB40005F102 /* MatrixSDKFFI.xcframework */; }; 181AA19C27B52AB40005F102 /* MatrixSDKFFI.xcframework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 181AA19A27B52AB40005F102 /* MatrixSDKFFI.xcframework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; 189A89BA27B40BBF0048B0A5 /* sdk.swift in Sources */ = {isa = PBXBuildFile; fileRef = 189A89B927B40BBF0048B0A5 /* sdk.swift */; }; - 189A89C827B4201C0048B0A5 /* ClientError+Error.swift in Sources */ = {isa = PBXBuildFile; fileRef = 189A89C727B4201C0048B0A5 /* ClientError+Error.swift */; }; 18CE89D827B2939900CA89E1 /* MatrixRustSDKApp.swift in Sources */ = {isa = PBXBuildFile; fileRef = 18CE89D727B2939900CA89E1 /* MatrixRustSDKApp.swift */; }; 18CE89DA27B2939900CA89E1 /* ContentView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 18CE89D927B2939900CA89E1 /* ContentView.swift */; }; 18CE89DC27B2939A00CA89E1 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 18CE89DB27B2939A00CA89E1 /* Assets.xcassets */; }; 18CE89E927B2939A00CA89E1 /* MatrixRustSDKTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 18CE89E827B2939A00CA89E1 /* MatrixRustSDKTests.swift */; }; - 18CE89F327B2939A00CA89E1 /* MatrixRustSDKUITests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 18CE89F227B2939A00CA89E1 /* MatrixRustSDKUITests.swift */; }; /* End PBXBuildFile section */ /* Begin PBXContainerItemProxy section */ @@ -26,13 +24,6 @@ remoteGlobalIDString = 18CE89D327B2939900CA89E1; remoteInfo = MatrixRustSDK; }; - 18CE89EF27B2939A00CA89E1 /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 18CE89CC27B2939900CA89E1 /* Project object */; - proxyType = 1; - remoteGlobalIDString = 18CE89D327B2939900CA89E1; - remoteInfo = MatrixRustSDK; - }; /* End PBXContainerItemProxy section */ /* Begin PBXCopyFilesBuildPhase section */ @@ -52,18 +43,14 @@ /* Begin PBXFileReference section */ 181AA19927B52AA60005F102 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist; path = Info.plist; sourceTree = ""; }; 181AA19A27B52AB40005F102 /* MatrixSDKFFI.xcframework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcframework; name = MatrixSDKFFI.xcframework; path = ../../generated/MatrixSDKFFI.xcframework; sourceTree = ""; }; - 189A899E27B2BADA0048B0A5 /* build_xcframework.sh */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.sh; path = build_xcframework.sh; sourceTree = SOURCE_ROOT; }; 189A89B927B40BBF0048B0A5 /* sdk.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = sdk.swift; path = ../../../generated/swift/sdk.swift; sourceTree = ""; }; 189A89C327B417CA0048B0A5 /* MatrixRustSDK-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "MatrixRustSDK-Bridging-Header.h"; sourceTree = ""; }; - 189A89C727B4201C0048B0A5 /* ClientError+Error.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "ClientError+Error.swift"; sourceTree = ""; }; 18CE89D427B2939900CA89E1 /* MatrixRustSDK.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = MatrixRustSDK.app; sourceTree = BUILT_PRODUCTS_DIR; }; 18CE89D727B2939900CA89E1 /* MatrixRustSDKApp.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MatrixRustSDKApp.swift; sourceTree = ""; }; 18CE89D927B2939900CA89E1 /* ContentView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ContentView.swift; sourceTree = ""; }; 18CE89DB27B2939A00CA89E1 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; 18CE89E427B2939A00CA89E1 /* MatrixRustSDKTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = MatrixRustSDKTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; 18CE89E827B2939A00CA89E1 /* MatrixRustSDKTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MatrixRustSDKTests.swift; sourceTree = ""; }; - 18CE89EE27B2939A00CA89E1 /* MatrixRustSDKUITests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = MatrixRustSDKUITests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; - 18CE89F227B2939A00CA89E1 /* MatrixRustSDKUITests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MatrixRustSDKUITests.swift; sourceTree = ""; }; 18CE8A0127B293A900CA89E1 /* MatrixRustSDK.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = MatrixRustSDK.entitlements; sourceTree = ""; }; /* End PBXFileReference section */ @@ -83,13 +70,6 @@ ); runOnlyForDeploymentPostprocessing = 0; }; - 18CE89EB27B2939A00CA89E1 /* Frameworks */ = { - isa = PBXFrameworksBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - runOnlyForDeploymentPostprocessing = 0; - }; /* End PBXFrameworksBuildPhase section */ /* Begin PBXGroup section */ @@ -114,7 +94,6 @@ children = ( 18CE89D627B2939900CA89E1 /* MatrixRustSDK */, 18CE89E727B2939A00CA89E1 /* MatrixRustSDKTests */, - 18CE89F127B2939A00CA89E1 /* MatrixRustSDKUITests */, 18CE89D527B2939900CA89E1 /* Products */, 189A89AB27B2E16B0048B0A5 /* Frameworks */, ); @@ -125,7 +104,6 @@ children = ( 18CE89D427B2939900CA89E1 /* MatrixRustSDK.app */, 18CE89E427B2939A00CA89E1 /* MatrixRustSDKTests.xctest */, - 18CE89EE27B2939A00CA89E1 /* MatrixRustSDKUITests.xctest */, ); name = Products; sourceTree = ""; @@ -134,11 +112,9 @@ isa = PBXGroup; children = ( 181AA19927B52AA60005F102 /* Info.plist */, - 189A899E27B2BADA0048B0A5 /* build_xcframework.sh */, 189A89B827B40BB10048B0A5 /* Generated */, 18CE89D727B2939900CA89E1 /* MatrixRustSDKApp.swift */, 18CE89D927B2939900CA89E1 /* ContentView.swift */, - 189A89C727B4201C0048B0A5 /* ClientError+Error.swift */, 18CE8A0127B293A900CA89E1 /* MatrixRustSDK.entitlements */, 18CE89DB27B2939A00CA89E1 /* Assets.xcassets */, 189A89C327B417CA0048B0A5 /* MatrixRustSDK-Bridging-Header.h */, @@ -154,14 +130,6 @@ path = MatrixRustSDKTests; sourceTree = ""; }; - 18CE89F127B2939A00CA89E1 /* MatrixRustSDKUITests */ = { - isa = PBXGroup; - children = ( - 18CE89F227B2939A00CA89E1 /* MatrixRustSDKUITests.swift */, - ); - path = MatrixRustSDKUITests; - sourceTree = ""; - }; /* End PBXGroup section */ /* Begin PBXNativeTarget section */ @@ -201,24 +169,6 @@ productReference = 18CE89E427B2939A00CA89E1 /* MatrixRustSDKTests.xctest */; productType = "com.apple.product-type.bundle.unit-test"; }; - 18CE89ED27B2939A00CA89E1 /* MatrixRustSDKUITests */ = { - isa = PBXNativeTarget; - buildConfigurationList = 18CE89FE27B2939A00CA89E1 /* Build configuration list for PBXNativeTarget "MatrixRustSDKUITests" */; - buildPhases = ( - 18CE89EA27B2939A00CA89E1 /* Sources */, - 18CE89EB27B2939A00CA89E1 /* Frameworks */, - 18CE89EC27B2939A00CA89E1 /* Resources */, - ); - buildRules = ( - ); - dependencies = ( - 18CE89F027B2939A00CA89E1 /* PBXTargetDependency */, - ); - name = MatrixRustSDKUITests; - productName = MatrixRustSDKUITests; - productReference = 18CE89EE27B2939A00CA89E1 /* MatrixRustSDKUITests.xctest */; - productType = "com.apple.product-type.bundle.ui-testing"; - }; /* End PBXNativeTarget section */ /* Begin PBXProject section */ @@ -237,10 +187,6 @@ CreatedOnToolsVersion = 13.2.1; TestTargetID = 18CE89D327B2939900CA89E1; }; - 18CE89ED27B2939A00CA89E1 = { - CreatedOnToolsVersion = 13.2.1; - TestTargetID = 18CE89D327B2939900CA89E1; - }; }; }; buildConfigurationList = 18CE89CF27B2939900CA89E1 /* Build configuration list for PBXProject "MatrixRustSDK" */; @@ -258,7 +204,6 @@ targets = ( 18CE89D327B2939900CA89E1 /* MatrixRustSDK */, 18CE89E327B2939A00CA89E1 /* MatrixRustSDKTests */, - 18CE89ED27B2939A00CA89E1 /* MatrixRustSDKUITests */, ); }; /* End PBXProject section */ @@ -279,13 +224,6 @@ ); runOnlyForDeploymentPostprocessing = 0; }; - 18CE89EC27B2939A00CA89E1 /* Resources */ = { - isa = PBXResourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - runOnlyForDeploymentPostprocessing = 0; - }; /* End PBXResourcesBuildPhase section */ /* Begin PBXSourcesBuildPhase section */ @@ -293,7 +231,6 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( - 189A89C827B4201C0048B0A5 /* ClientError+Error.swift in Sources */, 18CE89DA27B2939900CA89E1 /* ContentView.swift in Sources */, 189A89BA27B40BBF0048B0A5 /* sdk.swift in Sources */, 18CE89D827B2939900CA89E1 /* MatrixRustSDKApp.swift in Sources */, @@ -308,14 +245,6 @@ ); runOnlyForDeploymentPostprocessing = 0; }; - 18CE89EA27B2939A00CA89E1 /* Sources */ = { - isa = PBXSourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - 18CE89F327B2939A00CA89E1 /* MatrixRustSDKUITests.swift in Sources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; /* End PBXSourcesBuildPhase section */ /* Begin PBXTargetDependency section */ @@ -324,11 +253,6 @@ target = 18CE89D327B2939900CA89E1 /* MatrixRustSDK */; targetProxy = 18CE89E527B2939A00CA89E1 /* PBXContainerItemProxy */; }; - 18CE89F027B2939A00CA89E1 /* PBXTargetDependency */ = { - isa = PBXTargetDependency; - target = 18CE89D327B2939900CA89E1 /* MatrixRustSDK */; - targetProxy = 18CE89EF27B2939A00CA89E1 /* PBXContainerItemProxy */; - }; /* End PBXTargetDependency section */ /* Begin XCBuildConfiguration section */ @@ -553,40 +477,6 @@ }; name = Release; }; - 18CE89FF27B2939A00CA89E1 /* Debug */ = { - isa = XCBuildConfiguration; - buildSettings = { - ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; - CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 1; - GENERATE_INFOPLIST_FILE = YES; - MARKETING_VERSION = 1.0; - PRODUCT_BUNDLE_IDENTIFIER = org.matrix.MatrixRustSDKUITests; - PRODUCT_NAME = "$(TARGET_NAME)"; - SWIFT_EMIT_LOC_STRINGS = NO; - SWIFT_VERSION = 5.0; - TARGETED_DEVICE_FAMILY = "1,2"; - TEST_TARGET_NAME = MatrixRustSDK; - }; - name = Debug; - }; - 18CE8A0027B2939A00CA89E1 /* Release */ = { - isa = XCBuildConfiguration; - buildSettings = { - ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; - CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 1; - GENERATE_INFOPLIST_FILE = YES; - MARKETING_VERSION = 1.0; - PRODUCT_BUNDLE_IDENTIFIER = org.matrix.MatrixRustSDKUITests; - PRODUCT_NAME = "$(TARGET_NAME)"; - SWIFT_EMIT_LOC_STRINGS = NO; - SWIFT_VERSION = 5.0; - TARGETED_DEVICE_FAMILY = "1,2"; - TEST_TARGET_NAME = MatrixRustSDK; - }; - name = Release; - }; /* End XCBuildConfiguration section */ /* Begin XCConfigurationList section */ @@ -617,15 +507,6 @@ defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; - 18CE89FE27B2939A00CA89E1 /* Build configuration list for PBXNativeTarget "MatrixRustSDKUITests" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - 18CE89FF27B2939A00CA89E1 /* Debug */, - 18CE8A0027B2939A00CA89E1 /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; /* End XCConfigurationList section */ }; rootObject = 18CE89CC27B2939900CA89E1 /* Project object */; diff --git a/apple/MatrixRustSDK/MatrixRustSDK/ClientError+Error.swift b/apple/MatrixRustSDK/MatrixRustSDK/ClientError+Error.swift deleted file mode 100644 index 354eccef3..000000000 --- a/apple/MatrixRustSDK/MatrixRustSDK/ClientError+Error.swift +++ /dev/null @@ -1,11 +0,0 @@ -// -// ClientError+Error.swift -// MatrixRustSDK -// -// Created by Stefan Ceriu on 09.02.2022. -// - -import Foundation - -// Fixes code generation problem from uniffi -extension ClientError: Error { } diff --git a/apple/MatrixRustSDK/MatrixRustSDKTests/MatrixRustSDKTests.swift b/apple/MatrixRustSDK/MatrixRustSDKTests/MatrixRustSDKTests.swift index 32ca8b63a..17e7edd68 100644 --- a/apple/MatrixRustSDK/MatrixRustSDKTests/MatrixRustSDKTests.swift +++ b/apple/MatrixRustSDK/MatrixRustSDKTests/MatrixRustSDKTests.swift @@ -9,13 +9,40 @@ import XCTest @testable import MatrixRustSDK class MatrixRustSDKTests: XCTestCase { - func testExample() throws { + + static var client: Client! + + override class func setUp() { + client = try! guestClient(basePath: basePath, homeserver: "https://matrix.org") + } + + func testClientProperties() { + XCTAssertTrue(Self.client.isGuest()) + + XCTAssertNotNil(try? Self.client.restoreToken()) + XCTAssertNotNil(try? Self.client.deviceId()) + XCTAssertNotNil(try? Self.client.displayName()) + } + + func testReadOnlyFileSystemError() { do { let _ = try loginNewClient(basePath: "", username: "test", password: "test") - } catch ClientError.generic(let message) { + } catch ClientError.Generic(let message) { XCTAssertNotNil(message.range(of: "Read-only file system")) } catch { XCTFail("Not expecting any other kind of exception") } } + + // MARK: - Private + + static private var basePath: String { + guard let url = FileManager.default.urls(for: .cachesDirectory, in: .userDomainMask).first else { + fatalError("Should always be able to retrieve the caches directory") + } + + try? FileManager.default.createDirectory(at: url, withIntermediateDirectories: false, attributes: nil) + + return url.path + } } diff --git a/apple/MatrixRustSDK/MatrixRustSDKUITests/MatrixRustSDKUITests.swift b/apple/MatrixRustSDK/MatrixRustSDKUITests/MatrixRustSDKUITests.swift deleted file mode 100644 index 4e6558448..000000000 --- a/apple/MatrixRustSDK/MatrixRustSDKUITests/MatrixRustSDKUITests.swift +++ /dev/null @@ -1,42 +0,0 @@ -// -// MatrixRustSDKUITests.swift -// MatrixRustSDKUITests -// -// Created by Stefan Ceriu on 08.02.2022. -// - -import XCTest - -class MatrixRustSDKUITests: XCTestCase { - - override func setUpWithError() throws { - // Put setup code here. This method is called before the invocation of each test method in the class. - - // In UI tests it is usually best to stop immediately when a failure occurs. - continueAfterFailure = false - - // In UI tests it’s important to set the initial state - such as interface orientation - required for your tests before they run. The setUp method is a good place to do this. - } - - override func tearDownWithError() throws { - // Put teardown code here. This method is called after the invocation of each test method in the class. - } - - func testExample() throws { - // UI tests must launch the application that they test. - let app = XCUIApplication() - app.launch() - - // Use recording to get started writing UI tests. - // Use XCTAssert and related functions to verify your tests produce the correct results. - } - - func testLaunchPerformance() throws { - if #available(macOS 10.15, iOS 13.0, tvOS 13.0, watchOS 7.0, *) { - // This measures how long it takes to launch your application. - measure(metrics: [XCTApplicationLaunchMetric()]) { - XCUIApplication().launch() - } - } - } -} diff --git a/apple/build_xcframework.sh b/apple/build_xcframework.sh index c031934d2..847664052 100755 --- a/apple/build_xcframework.sh +++ b/apple/build_xcframework.sh @@ -17,19 +17,19 @@ REL_TYPE_DIR="release" # Build static libs for all the different architectures # iOS -cargo build --locked -p matrix-sdk-ffi ${REL_FLAG} --target "aarch64-apple-ios" +cargo build -p matrix-sdk-ffi ${REL_FLAG} --target "aarch64-apple-ios" # MacOS -cargo build --locked -p matrix-sdk-ffi ${REL_FLAG} --target "aarch64-apple-darwin" -cargo build --locked -p matrix-sdk-ffi ${REL_FLAG} --target "x86_64-apple-darwin" +cargo build -p matrix-sdk-ffi ${REL_FLAG} --target "aarch64-apple-darwin" +cargo build -p matrix-sdk-ffi ${REL_FLAG} --target "x86_64-apple-darwin" # iOS Simulator -cargo build --locked -p matrix-sdk-ffi ${REL_FLAG} --target "aarch64-apple-ios-sim" -cargo build --locked -p matrix-sdk-ffi ${REL_FLAG} --target "x86_64-apple-ios" +cargo build -p matrix-sdk-ffi ${REL_FLAG} --target "aarch64-apple-ios-sim" +cargo build -p matrix-sdk-ffi ${REL_FLAG} --target "x86_64-apple-ios" # Mac Catalyst -cargo +nightly build --locked -Z build-std -p matrix-sdk-ffi ${REL_FLAG} --target "aarch64-apple-ios-macabi" -cargo +nightly build --locked -Z build-std -p matrix-sdk-ffi ${REL_FLAG} --target "x86_64-apple-ios-macabi" +cargo +nightly build -Z build-std -p matrix-sdk-ffi ${REL_FLAG} --target "aarch64-apple-ios-macabi" +cargo +nightly build -Z build-std -p matrix-sdk-ffi ${REL_FLAG} --target "x86_64-apple-ios-macabi" # Lipo together the libraries for the same platform diff --git a/apple/debug_build_xcframework.sh b/apple/debug_build_xcframework.sh index 86bc31aec..ba12b63bd 100755 --- a/apple/debug_build_xcframework.sh +++ b/apple/debug_build_xcframework.sh @@ -1,6 +1,8 @@ #!/usr/bin/env bash set -eEu +cd "$(dirname "$0")" + IS_CI=false if [ $# -eq 1 ]; then @@ -22,11 +24,12 @@ mkdir -p ${GENERATED_DIR} REL_FLAG="--release" REL_TYPE_DIR="release" -# Build static the lib for aarch64 simulator - -cargo +nightly build --locked -p matrix-sdk-ffi ${REL_FLAG} --target "aarch64-apple-ios-sim" +# iOS Simulator +cargo build -p matrix-sdk-ffi ${REL_FLAG} --target "aarch64-apple-ios-sim" +cargo build -p matrix-sdk-ffi ${REL_FLAG} --target "x86_64-apple-ios" lipo -create \ + "${TARGET_DIR}/x86_64-apple-ios/${REL_TYPE_DIR}/libmatrix_sdk_ffi.a" \ "${TARGET_DIR}/aarch64-apple-ios-sim/${REL_TYPE_DIR}/libmatrix_sdk_ffi.a" \ -output "${GENERATED_DIR}/libmatrix_sdk_ffi_iossimulator.a" @@ -55,8 +58,8 @@ xcodebuild -create-xcframework \ # Cleanup -if [ -f "${GENERATED_DIR}/libmatrix_sdk_ffi_iossimulator.a" ]; then rm -rf "${GENERATED_DIR}/libmatrix_sdk_ffi_iossimulator.a"; fi -if [ -d ${HEADERS_DIR} ]; then rm -rf ${HEADERS_DIR}; fi +# if [ -f "${GENERATED_DIR}/libmatrix_sdk_ffi_iossimulator.a" ]; then rm -rf "${GENERATED_DIR}/libmatrix_sdk_ffi_iossimulator.a"; fi +# if [ -d ${HEADERS_DIR} ]; then rm -rf ${HEADERS_DIR}; fi if [ "$IS_CI" = false ] ; then echo "Preparing matrix-rust-components-swift" From d863b4eb7511bd813ee0cdba0bfccb2e768f3bf3 Mon Sep 17 00:00:00 2001 From: Stefan Ceriu Date: Wed, 18 May 2022 11:13:15 +0300 Subject: [PATCH 16/51] Bump uniffi to version 0.18.0 --- crates/matrix-sdk-ffi/Cargo.toml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/crates/matrix-sdk-ffi/Cargo.toml b/crates/matrix-sdk-ffi/Cargo.toml index cf66c99e9..3dfd6897c 100644 --- a/crates/matrix-sdk-ffi/Cargo.toml +++ b/crates/matrix-sdk-ffi/Cargo.toml @@ -14,7 +14,7 @@ crate-type = ["cdylib", "staticlib"] [build-dependencies] -uniffi_build = { version = "0.17.0", features = ["builtin-bindgen"] } +uniffi_build = { version = "0.18.0", features = ["builtin-bindgen"] } [dependencies] anyhow = "1.0.51" @@ -31,5 +31,5 @@ thiserror = "1.0.30" tokio = { version = "1", features = ["rt-multi-thread", "macros"] } tokio-stream = "0.1.8" tracing = "0.1.32" -uniffi = "0.17.0" -uniffi_macros = "0.17.0" +uniffi = "0.18.0" +uniffi_macros = "0.18.0" From bc207f1e5c7b3089d79b78b54ab9ff977b9ea78e Mon Sep 17 00:00:00 2001 From: Jonas Platte Date: Wed, 18 May 2022 10:31:52 +0200 Subject: [PATCH 17/51] chore(sdk): Upgrade async-once-cell to 0.3.1 --- crates/matrix-sdk/Cargo.toml | 2 +- crates/matrix-sdk/src/client/builder.rs | 18 +++++------------- 2 files changed, 6 insertions(+), 14 deletions(-) diff --git a/crates/matrix-sdk/Cargo.toml b/crates/matrix-sdk/Cargo.toml index fcf516b42..56e55d69b 100644 --- a/crates/matrix-sdk/Cargo.toml +++ b/crates/matrix-sdk/Cargo.toml @@ -123,7 +123,7 @@ default-features = false optional = true [target.'cfg(target_arch = "wasm32")'.dependencies] -async-once-cell = "0.3.0" +async-once-cell = "0.3.1" wasm-timer = "0.2.5" [target.'cfg(not(target_arch = "wasm32"))'.dependencies] diff --git a/crates/matrix-sdk/src/client/builder.rs b/crates/matrix-sdk/src/client/builder.rs index bfa6440bd..c90e1c603 100644 --- a/crates/matrix-sdk/src/client/builder.rs +++ b/crates/matrix-sdk/src/client/builder.rs @@ -1,11 +1,15 @@ use std::sync::Arc; +#[cfg(target_arch = "wasm32")] +use async_once_cell::OnceCell; use matrix_sdk_base::{locks::RwLock, store::StoreConfig, BaseClient, StateStore}; use ruma::{ api::{client::discovery::discover_homeserver, error::FromHttpResponseError, MatrixVersion}, OwnedServerName, ServerName, UserId, }; use thiserror::Error; +#[cfg(not(target_arch = "wasm32"))] +use tokio::sync::OnceCell; use url::Url; use super::{Client, ClientInner}; @@ -323,23 +327,11 @@ impl ClientBuilder { let homeserver = Arc::new(RwLock::new(Url::parse(&homeserver)?)); let http_client = mk_http_client(homeserver.clone()); - #[cfg(target_arch = "wasm32")] - let server_versions = { - let cell = async_once_cell::OnceCell::new(); - if let Some(server_versions) = self.server_versions { - cell.get_or_init(async move { server_versions }).await; - } - cell - }; - - #[cfg(not(target_arch = "wasm32"))] - let server_versions = tokio::sync::OnceCell::new_with(self.server_versions); - let inner = Arc::new(ClientInner { homeserver, http_client, base_client, - server_versions, + server_versions: OnceCell::new_with(self.server_versions), #[cfg(feature = "e2e-encryption")] group_session_locks: Default::default(), #[cfg(feature = "e2e-encryption")] From 4b8b9db075ac761b1d926bd5eb6f368c9827c3bf Mon Sep 17 00:00:00 2001 From: Stefan Ceriu Date: Wed, 18 May 2022 11:49:29 +0300 Subject: [PATCH 18/51] Have FII action only run on PRs targetting main, similar to the CI one. --- .github/workflows/ffi.yml | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/.github/workflows/ffi.yml b/.github/workflows/ffi.yml index dc62437a9..14dbeebc4 100644 --- a/.github/workflows/ffi.yml +++ b/.github/workflows/ffi.yml @@ -5,12 +5,12 @@ on: push: branches: [main] pull_request: -# branches: [main] -# types: -# - opened -# - reopened -# - synchronize -# - ready_for_review + branches: [main] + types: + - opened + - reopened + - synchronize + - ready_for_review env: CARGO_TERM_COLOR: always From 886809b579e774d1040277b75dada3a4414ce7be Mon Sep 17 00:00:00 2001 From: Benjamin Kampmann Date: Wed, 18 May 2022 11:24:30 +0200 Subject: [PATCH 19/51] chore(Apple): Move apple into subfolder --- .github/workflows/ffi.yml | 4 ++-- .../MatrixRustSDK/MatrixRustSDK.xcodeproj/project.pbxproj | 0 .../project.xcworkspace/contents.xcworkspacedata | 0 .../project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist | 0 .../xcshareddata/xcschemes/MatrixRustSDK.xcscheme | 0 .../Assets.xcassets/AccentColor.colorset/Contents.json | 0 .../Assets.xcassets/AppIcon.appiconset/Contents.json | 0 .../MatrixRustSDK/MatrixRustSDK/Assets.xcassets/Contents.json | 0 .../apple}/MatrixRustSDK/MatrixRustSDK/ContentView.swift | 0 .../apple}/MatrixRustSDK/MatrixRustSDK/Info.plist | 0 .../MatrixRustSDK/MatrixRustSDK-Bridging-Header.h | 0 .../MatrixRustSDK/MatrixRustSDK/MatrixRustSDK.entitlements | 0 .../apple}/MatrixRustSDK/MatrixRustSDK/MatrixRustSDKApp.swift | 0 .../MatrixRustSDK/MatrixRustSDKTests/MatrixRustSDKTests.swift | 0 {apple => bindings/apple}/MatrixRustSDK/README.md | 0 {apple => bindings/apple}/build_xcframework.sh | 2 +- {apple => bindings/apple}/debug_build_xcframework.sh | 0 17 files changed, 3 insertions(+), 3 deletions(-) rename {apple => bindings/apple}/MatrixRustSDK/MatrixRustSDK.xcodeproj/project.pbxproj (100%) rename {apple => bindings/apple}/MatrixRustSDK/MatrixRustSDK.xcodeproj/project.xcworkspace/contents.xcworkspacedata (100%) rename {apple => bindings/apple}/MatrixRustSDK/MatrixRustSDK.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist (100%) rename {apple => bindings/apple}/MatrixRustSDK/MatrixRustSDK.xcodeproj/xcshareddata/xcschemes/MatrixRustSDK.xcscheme (100%) rename {apple => bindings/apple}/MatrixRustSDK/MatrixRustSDK/Assets.xcassets/AccentColor.colorset/Contents.json (100%) rename {apple => bindings/apple}/MatrixRustSDK/MatrixRustSDK/Assets.xcassets/AppIcon.appiconset/Contents.json (100%) rename {apple => bindings/apple}/MatrixRustSDK/MatrixRustSDK/Assets.xcassets/Contents.json (100%) rename {apple => bindings/apple}/MatrixRustSDK/MatrixRustSDK/ContentView.swift (100%) rename {apple => bindings/apple}/MatrixRustSDK/MatrixRustSDK/Info.plist (100%) rename {apple => bindings/apple}/MatrixRustSDK/MatrixRustSDK/MatrixRustSDK-Bridging-Header.h (100%) rename {apple => bindings/apple}/MatrixRustSDK/MatrixRustSDK/MatrixRustSDK.entitlements (100%) rename {apple => bindings/apple}/MatrixRustSDK/MatrixRustSDK/MatrixRustSDKApp.swift (100%) rename {apple => bindings/apple}/MatrixRustSDK/MatrixRustSDKTests/MatrixRustSDKTests.swift (100%) rename {apple => bindings/apple}/MatrixRustSDK/README.md (100%) rename {apple => bindings/apple}/build_xcframework.sh (99%) rename {apple => bindings/apple}/debug_build_xcframework.sh (100%) diff --git a/.github/workflows/ffi.yml b/.github/workflows/ffi.yml index 14dbeebc4..2b0fad4e3 100644 --- a/.github/workflows/ffi.yml +++ b/.github/workflows/ffi.yml @@ -46,12 +46,12 @@ jobs: uses: Swatinem/rust-cache@v1 - name: Generate .xcframework - run: sh apple/debug_build_xcframework.sh ci + run: sh bindings/apple/debug_build_xcframework.sh ci - name: Run XCTests run: | xcodebuild test \ - -project apple/MatrixRustSDK/MatrixRustSDK.xcodeproj \ + -project bindings/apple/MatrixRustSDK/MatrixRustSDK.xcodeproj \ -scheme MatrixRustSDK \ -sdk iphonesimulator \ -destination 'platform=iOS Simulator,name=iPhone 13,OS=15.4' \ No newline at end of file diff --git a/apple/MatrixRustSDK/MatrixRustSDK.xcodeproj/project.pbxproj b/bindings/apple/MatrixRustSDK/MatrixRustSDK.xcodeproj/project.pbxproj similarity index 100% rename from apple/MatrixRustSDK/MatrixRustSDK.xcodeproj/project.pbxproj rename to bindings/apple/MatrixRustSDK/MatrixRustSDK.xcodeproj/project.pbxproj diff --git a/apple/MatrixRustSDK/MatrixRustSDK.xcodeproj/project.xcworkspace/contents.xcworkspacedata b/bindings/apple/MatrixRustSDK/MatrixRustSDK.xcodeproj/project.xcworkspace/contents.xcworkspacedata similarity index 100% rename from apple/MatrixRustSDK/MatrixRustSDK.xcodeproj/project.xcworkspace/contents.xcworkspacedata rename to bindings/apple/MatrixRustSDK/MatrixRustSDK.xcodeproj/project.xcworkspace/contents.xcworkspacedata diff --git a/apple/MatrixRustSDK/MatrixRustSDK.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist b/bindings/apple/MatrixRustSDK/MatrixRustSDK.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist similarity index 100% rename from apple/MatrixRustSDK/MatrixRustSDK.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist rename to bindings/apple/MatrixRustSDK/MatrixRustSDK.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist diff --git a/apple/MatrixRustSDK/MatrixRustSDK.xcodeproj/xcshareddata/xcschemes/MatrixRustSDK.xcscheme b/bindings/apple/MatrixRustSDK/MatrixRustSDK.xcodeproj/xcshareddata/xcschemes/MatrixRustSDK.xcscheme similarity index 100% rename from apple/MatrixRustSDK/MatrixRustSDK.xcodeproj/xcshareddata/xcschemes/MatrixRustSDK.xcscheme rename to bindings/apple/MatrixRustSDK/MatrixRustSDK.xcodeproj/xcshareddata/xcschemes/MatrixRustSDK.xcscheme diff --git a/apple/MatrixRustSDK/MatrixRustSDK/Assets.xcassets/AccentColor.colorset/Contents.json b/bindings/apple/MatrixRustSDK/MatrixRustSDK/Assets.xcassets/AccentColor.colorset/Contents.json similarity index 100% rename from apple/MatrixRustSDK/MatrixRustSDK/Assets.xcassets/AccentColor.colorset/Contents.json rename to bindings/apple/MatrixRustSDK/MatrixRustSDK/Assets.xcassets/AccentColor.colorset/Contents.json diff --git a/apple/MatrixRustSDK/MatrixRustSDK/Assets.xcassets/AppIcon.appiconset/Contents.json b/bindings/apple/MatrixRustSDK/MatrixRustSDK/Assets.xcassets/AppIcon.appiconset/Contents.json similarity index 100% rename from apple/MatrixRustSDK/MatrixRustSDK/Assets.xcassets/AppIcon.appiconset/Contents.json rename to bindings/apple/MatrixRustSDK/MatrixRustSDK/Assets.xcassets/AppIcon.appiconset/Contents.json diff --git a/apple/MatrixRustSDK/MatrixRustSDK/Assets.xcassets/Contents.json b/bindings/apple/MatrixRustSDK/MatrixRustSDK/Assets.xcassets/Contents.json similarity index 100% rename from apple/MatrixRustSDK/MatrixRustSDK/Assets.xcassets/Contents.json rename to bindings/apple/MatrixRustSDK/MatrixRustSDK/Assets.xcassets/Contents.json diff --git a/apple/MatrixRustSDK/MatrixRustSDK/ContentView.swift b/bindings/apple/MatrixRustSDK/MatrixRustSDK/ContentView.swift similarity index 100% rename from apple/MatrixRustSDK/MatrixRustSDK/ContentView.swift rename to bindings/apple/MatrixRustSDK/MatrixRustSDK/ContentView.swift diff --git a/apple/MatrixRustSDK/MatrixRustSDK/Info.plist b/bindings/apple/MatrixRustSDK/MatrixRustSDK/Info.plist similarity index 100% rename from apple/MatrixRustSDK/MatrixRustSDK/Info.plist rename to bindings/apple/MatrixRustSDK/MatrixRustSDK/Info.plist diff --git a/apple/MatrixRustSDK/MatrixRustSDK/MatrixRustSDK-Bridging-Header.h b/bindings/apple/MatrixRustSDK/MatrixRustSDK/MatrixRustSDK-Bridging-Header.h similarity index 100% rename from apple/MatrixRustSDK/MatrixRustSDK/MatrixRustSDK-Bridging-Header.h rename to bindings/apple/MatrixRustSDK/MatrixRustSDK/MatrixRustSDK-Bridging-Header.h diff --git a/apple/MatrixRustSDK/MatrixRustSDK/MatrixRustSDK.entitlements b/bindings/apple/MatrixRustSDK/MatrixRustSDK/MatrixRustSDK.entitlements similarity index 100% rename from apple/MatrixRustSDK/MatrixRustSDK/MatrixRustSDK.entitlements rename to bindings/apple/MatrixRustSDK/MatrixRustSDK/MatrixRustSDK.entitlements diff --git a/apple/MatrixRustSDK/MatrixRustSDK/MatrixRustSDKApp.swift b/bindings/apple/MatrixRustSDK/MatrixRustSDK/MatrixRustSDKApp.swift similarity index 100% rename from apple/MatrixRustSDK/MatrixRustSDK/MatrixRustSDKApp.swift rename to bindings/apple/MatrixRustSDK/MatrixRustSDK/MatrixRustSDKApp.swift diff --git a/apple/MatrixRustSDK/MatrixRustSDKTests/MatrixRustSDKTests.swift b/bindings/apple/MatrixRustSDK/MatrixRustSDKTests/MatrixRustSDKTests.swift similarity index 100% rename from apple/MatrixRustSDK/MatrixRustSDKTests/MatrixRustSDKTests.swift rename to bindings/apple/MatrixRustSDK/MatrixRustSDKTests/MatrixRustSDKTests.swift diff --git a/apple/MatrixRustSDK/README.md b/bindings/apple/MatrixRustSDK/README.md similarity index 100% rename from apple/MatrixRustSDK/README.md rename to bindings/apple/MatrixRustSDK/README.md diff --git a/apple/build_xcframework.sh b/bindings/apple/build_xcframework.sh similarity index 99% rename from apple/build_xcframework.sh rename to bindings/apple/build_xcframework.sh index 847664052..220f76a05 100755 --- a/apple/build_xcframework.sh +++ b/bindings/apple/build_xcframework.sh @@ -4,7 +4,7 @@ set -eEu cd "$(dirname "$0")" # Path to the repo root -SRC_ROOT=.. +SRC_ROOT=../.. TARGET_DIR="${SRC_ROOT}/target" diff --git a/apple/debug_build_xcframework.sh b/bindings/apple/debug_build_xcframework.sh similarity index 100% rename from apple/debug_build_xcframework.sh rename to bindings/apple/debug_build_xcframework.sh From 4522b4e8f54991065965f78e51addba8548387ca Mon Sep 17 00:00:00 2001 From: Benjamin Kampmann Date: Wed, 18 May 2022 11:32:03 +0200 Subject: [PATCH 20/51] ci: move rust cache to include uniffi bindgen install --- .github/workflows/ffi.yml | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/.github/workflows/ffi.yml b/.github/workflows/ffi.yml index 2b0fad4e3..7a3aa63fc 100644 --- a/.github/workflows/ffi.yml +++ b/.github/workflows/ffi.yml @@ -36,14 +36,15 @@ jobs: rustup target add aarch64-apple-ios-sim rustup target add x86_64-apple-ios + - name: Load cache + uses: Swatinem/rust-cache@v1 + - name: Install Uniffi uses: actions-rs/cargo@v1 with: command: install args: uniffi_bindgen - - name: Load cache - uses: Swatinem/rust-cache@v1 - name: Generate .xcframework run: sh bindings/apple/debug_build_xcframework.sh ci From e3503fe102c8ab561ab46a78e4fa4aac3e65641e Mon Sep 17 00:00:00 2001 From: Benjamin Kampmann Date: Wed, 18 May 2022 11:56:38 +0200 Subject: [PATCH 21/51] ci: one more move --- .github/workflows/ffi.yml | 2 +- .../{MatrixRustSDK => }/MatrixRustSDK.xcodeproj/project.pbxproj | 0 .../project.xcworkspace/contents.xcworkspacedata | 0 .../project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist | 0 .../xcshareddata/xcschemes/MatrixRustSDK.xcscheme | 0 .../Assets.xcassets/AccentColor.colorset/Contents.json | 0 .../Assets.xcassets/AppIcon.appiconset/Contents.json | 0 .../{MatrixRustSDK => }/Assets.xcassets/Contents.json | 0 .../apple/MatrixRustSDK/{MatrixRustSDK => }/ContentView.swift | 0 bindings/apple/MatrixRustSDK/{MatrixRustSDK => }/Info.plist | 0 .../{MatrixRustSDK => }/MatrixRustSDK-Bridging-Header.h | 0 .../{MatrixRustSDK => }/MatrixRustSDK.entitlements | 0 .../MatrixRustSDK/{MatrixRustSDK => }/MatrixRustSDKApp.swift | 0 .../MatrixRustSDKTests/MatrixRustSDKTests.swift | 0 bindings/apple/{MatrixRustSDK => }/README.md | 0 15 files changed, 1 insertion(+), 1 deletion(-) rename bindings/apple/{MatrixRustSDK => }/MatrixRustSDK.xcodeproj/project.pbxproj (100%) rename bindings/apple/{MatrixRustSDK => }/MatrixRustSDK.xcodeproj/project.xcworkspace/contents.xcworkspacedata (100%) rename bindings/apple/{MatrixRustSDK => }/MatrixRustSDK.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist (100%) rename bindings/apple/{MatrixRustSDK => }/MatrixRustSDK.xcodeproj/xcshareddata/xcschemes/MatrixRustSDK.xcscheme (100%) rename bindings/apple/MatrixRustSDK/{MatrixRustSDK => }/Assets.xcassets/AccentColor.colorset/Contents.json (100%) rename bindings/apple/MatrixRustSDK/{MatrixRustSDK => }/Assets.xcassets/AppIcon.appiconset/Contents.json (100%) rename bindings/apple/MatrixRustSDK/{MatrixRustSDK => }/Assets.xcassets/Contents.json (100%) rename bindings/apple/MatrixRustSDK/{MatrixRustSDK => }/ContentView.swift (100%) rename bindings/apple/MatrixRustSDK/{MatrixRustSDK => }/Info.plist (100%) rename bindings/apple/MatrixRustSDK/{MatrixRustSDK => }/MatrixRustSDK-Bridging-Header.h (100%) rename bindings/apple/MatrixRustSDK/{MatrixRustSDK => }/MatrixRustSDK.entitlements (100%) rename bindings/apple/MatrixRustSDK/{MatrixRustSDK => }/MatrixRustSDKApp.swift (100%) rename bindings/apple/{MatrixRustSDK => }/MatrixRustSDKTests/MatrixRustSDKTests.swift (100%) rename bindings/apple/{MatrixRustSDK => }/README.md (100%) diff --git a/.github/workflows/ffi.yml b/.github/workflows/ffi.yml index 7a3aa63fc..5ca5e46a3 100644 --- a/.github/workflows/ffi.yml +++ b/.github/workflows/ffi.yml @@ -52,7 +52,7 @@ jobs: - name: Run XCTests run: | xcodebuild test \ - -project bindings/apple/MatrixRustSDK/MatrixRustSDK.xcodeproj \ + -project bindings/apple/MatrixRustSDK.xcodeproj \ -scheme MatrixRustSDK \ -sdk iphonesimulator \ -destination 'platform=iOS Simulator,name=iPhone 13,OS=15.4' \ No newline at end of file diff --git a/bindings/apple/MatrixRustSDK/MatrixRustSDK.xcodeproj/project.pbxproj b/bindings/apple/MatrixRustSDK.xcodeproj/project.pbxproj similarity index 100% rename from bindings/apple/MatrixRustSDK/MatrixRustSDK.xcodeproj/project.pbxproj rename to bindings/apple/MatrixRustSDK.xcodeproj/project.pbxproj diff --git a/bindings/apple/MatrixRustSDK/MatrixRustSDK.xcodeproj/project.xcworkspace/contents.xcworkspacedata b/bindings/apple/MatrixRustSDK.xcodeproj/project.xcworkspace/contents.xcworkspacedata similarity index 100% rename from bindings/apple/MatrixRustSDK/MatrixRustSDK.xcodeproj/project.xcworkspace/contents.xcworkspacedata rename to bindings/apple/MatrixRustSDK.xcodeproj/project.xcworkspace/contents.xcworkspacedata diff --git a/bindings/apple/MatrixRustSDK/MatrixRustSDK.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist b/bindings/apple/MatrixRustSDK.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist similarity index 100% rename from bindings/apple/MatrixRustSDK/MatrixRustSDK.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist rename to bindings/apple/MatrixRustSDK.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist diff --git a/bindings/apple/MatrixRustSDK/MatrixRustSDK.xcodeproj/xcshareddata/xcschemes/MatrixRustSDK.xcscheme b/bindings/apple/MatrixRustSDK.xcodeproj/xcshareddata/xcschemes/MatrixRustSDK.xcscheme similarity index 100% rename from bindings/apple/MatrixRustSDK/MatrixRustSDK.xcodeproj/xcshareddata/xcschemes/MatrixRustSDK.xcscheme rename to bindings/apple/MatrixRustSDK.xcodeproj/xcshareddata/xcschemes/MatrixRustSDK.xcscheme diff --git a/bindings/apple/MatrixRustSDK/MatrixRustSDK/Assets.xcassets/AccentColor.colorset/Contents.json b/bindings/apple/MatrixRustSDK/Assets.xcassets/AccentColor.colorset/Contents.json similarity index 100% rename from bindings/apple/MatrixRustSDK/MatrixRustSDK/Assets.xcassets/AccentColor.colorset/Contents.json rename to bindings/apple/MatrixRustSDK/Assets.xcassets/AccentColor.colorset/Contents.json diff --git a/bindings/apple/MatrixRustSDK/MatrixRustSDK/Assets.xcassets/AppIcon.appiconset/Contents.json b/bindings/apple/MatrixRustSDK/Assets.xcassets/AppIcon.appiconset/Contents.json similarity index 100% rename from bindings/apple/MatrixRustSDK/MatrixRustSDK/Assets.xcassets/AppIcon.appiconset/Contents.json rename to bindings/apple/MatrixRustSDK/Assets.xcassets/AppIcon.appiconset/Contents.json diff --git a/bindings/apple/MatrixRustSDK/MatrixRustSDK/Assets.xcassets/Contents.json b/bindings/apple/MatrixRustSDK/Assets.xcassets/Contents.json similarity index 100% rename from bindings/apple/MatrixRustSDK/MatrixRustSDK/Assets.xcassets/Contents.json rename to bindings/apple/MatrixRustSDK/Assets.xcassets/Contents.json diff --git a/bindings/apple/MatrixRustSDK/MatrixRustSDK/ContentView.swift b/bindings/apple/MatrixRustSDK/ContentView.swift similarity index 100% rename from bindings/apple/MatrixRustSDK/MatrixRustSDK/ContentView.swift rename to bindings/apple/MatrixRustSDK/ContentView.swift diff --git a/bindings/apple/MatrixRustSDK/MatrixRustSDK/Info.plist b/bindings/apple/MatrixRustSDK/Info.plist similarity index 100% rename from bindings/apple/MatrixRustSDK/MatrixRustSDK/Info.plist rename to bindings/apple/MatrixRustSDK/Info.plist diff --git a/bindings/apple/MatrixRustSDK/MatrixRustSDK/MatrixRustSDK-Bridging-Header.h b/bindings/apple/MatrixRustSDK/MatrixRustSDK-Bridging-Header.h similarity index 100% rename from bindings/apple/MatrixRustSDK/MatrixRustSDK/MatrixRustSDK-Bridging-Header.h rename to bindings/apple/MatrixRustSDK/MatrixRustSDK-Bridging-Header.h diff --git a/bindings/apple/MatrixRustSDK/MatrixRustSDK/MatrixRustSDK.entitlements b/bindings/apple/MatrixRustSDK/MatrixRustSDK.entitlements similarity index 100% rename from bindings/apple/MatrixRustSDK/MatrixRustSDK/MatrixRustSDK.entitlements rename to bindings/apple/MatrixRustSDK/MatrixRustSDK.entitlements diff --git a/bindings/apple/MatrixRustSDK/MatrixRustSDK/MatrixRustSDKApp.swift b/bindings/apple/MatrixRustSDK/MatrixRustSDKApp.swift similarity index 100% rename from bindings/apple/MatrixRustSDK/MatrixRustSDK/MatrixRustSDKApp.swift rename to bindings/apple/MatrixRustSDK/MatrixRustSDKApp.swift diff --git a/bindings/apple/MatrixRustSDK/MatrixRustSDKTests/MatrixRustSDKTests.swift b/bindings/apple/MatrixRustSDKTests/MatrixRustSDKTests.swift similarity index 100% rename from bindings/apple/MatrixRustSDK/MatrixRustSDKTests/MatrixRustSDKTests.swift rename to bindings/apple/MatrixRustSDKTests/MatrixRustSDKTests.swift diff --git a/bindings/apple/MatrixRustSDK/README.md b/bindings/apple/README.md similarity index 100% rename from bindings/apple/MatrixRustSDK/README.md rename to bindings/apple/README.md From 6a1b85c560bd2a0c3dcf2077f3795c2793cf9311 Mon Sep 17 00:00:00 2001 From: Stefan Ceriu Date: Wed, 18 May 2022 13:43:29 +0300 Subject: [PATCH 22/51] Fix xcframework debug build script --- bindings/apple/debug_build_xcframework.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bindings/apple/debug_build_xcframework.sh b/bindings/apple/debug_build_xcframework.sh index ba12b63bd..f9054e520 100755 --- a/bindings/apple/debug_build_xcframework.sh +++ b/bindings/apple/debug_build_xcframework.sh @@ -13,7 +13,7 @@ else fi # Path to the repo root -SRC_ROOT=.. +SRC_ROOT=../.. TARGET_DIR="${SRC_ROOT}/target" From 0f910b6229233ea1bb32d0570efc4493d4f960cc Mon Sep 17 00:00:00 2001 From: Jonas Platte Date: Wed, 18 May 2022 13:28:15 +0200 Subject: [PATCH 23/51] fix(base): Make max_power_level reflect the current maximum only MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit … instead of taking into account an older maximum as well. --- crates/matrix-sdk-base/src/rooms/mod.rs | 14 +++----------- 1 file changed, 3 insertions(+), 11 deletions(-) diff --git a/crates/matrix-sdk-base/src/rooms/mod.rs b/crates/matrix-sdk-base/src/rooms/mod.rs index 75c3d21e6..049854a09 100644 --- a/crates/matrix-sdk-base/src/rooms/mod.rs +++ b/crates/matrix-sdk-base/src/rooms/mod.rs @@ -1,7 +1,7 @@ mod members; mod normal; -use std::{cmp::max, collections::HashSet, fmt}; +use std::{collections::HashSet, fmt}; pub use members::RoomMember; pub use normal::{Room, RoomInfo, RoomType}; @@ -143,11 +143,7 @@ impl BaseRoomInfo { self.tombstone = Some(t.into()); } AnySyncStateEvent::RoomPowerLevels(p) => { - self.max_power_level = p - .power_levels() - .users - .values() - .fold(self.max_power_level, |acc, &p| max(acc, p.into())); + self.max_power_level = p.power_levels().max().into(); } _ => return false, } @@ -192,11 +188,7 @@ impl BaseRoomInfo { self.tombstone = Some(t.into()); } AnyStrippedStateEvent::RoomPowerLevels(p) => { - self.max_power_level = p - .content - .users - .values() - .fold(self.max_power_level, |acc, &p| max(acc, p.into())); + self.max_power_level = p.power_levels().max().into(); } _ => return false, } From a364018c0e7296e2ec7de7caa4b20e6a038a390a Mon Sep 17 00:00:00 2001 From: Jonas Platte Date: Wed, 18 May 2022 17:36:42 +0200 Subject: [PATCH 24/51] chore: Use serde::de::DeserializeOwned convenience trait --- crates/matrix-sdk-indexeddb/src/cryptostore.rs | 4 ++-- crates/matrix-sdk-indexeddb/src/state_store.rs | 4 ++-- crates/matrix-sdk-sled/src/cryptostore.rs | 7 ++----- crates/matrix-sdk-sled/src/state_store.rs | 7 ++----- crates/matrix-sdk-store-encryption/src/lib.rs | 6 +++--- 5 files changed, 11 insertions(+), 17 deletions(-) diff --git a/crates/matrix-sdk-indexeddb/src/cryptostore.rs b/crates/matrix-sdk-indexeddb/src/cryptostore.rs index 55a7be518..3b96da8a0 100644 --- a/crates/matrix-sdk-indexeddb/src/cryptostore.rs +++ b/crates/matrix-sdk-indexeddb/src/cryptostore.rs @@ -33,7 +33,7 @@ use matrix_sdk_crypto::{ }; use matrix_sdk_store_encryption::StoreCipher; use ruma::{DeviceId, OwnedDeviceId, OwnedUserId, RoomId, TransactionId, UserId}; -use serde::{Deserialize, Serialize}; +use serde::{de::DeserializeOwned, Serialize}; use wasm_bindgen::JsValue; use web_sys::IdbKeyRange; @@ -284,7 +284,7 @@ impl IndexeddbStore { } } - fn deserialize_value Deserialize<'b>>( + fn deserialize_value( &self, value: JsValue, ) -> Result { diff --git a/crates/matrix-sdk-indexeddb/src/state_store.rs b/crates/matrix-sdk-indexeddb/src/state_store.rs index b505478d6..b992a67d0 100644 --- a/crates/matrix-sdk-indexeddb/src/state_store.rs +++ b/crates/matrix-sdk-indexeddb/src/state_store.rs @@ -46,7 +46,7 @@ use ruma::{ signatures::{redact_in_place, CanonicalJsonObject}, RoomVersionId, }; -use serde::{Deserialize, Serialize}; +use serde::{de::DeserializeOwned, Deserialize, Serialize}; use wasm_bindgen::JsValue; use web_sys::IdbKeyRange; @@ -275,7 +275,7 @@ impl IndexeddbStore { }) } - fn deserialize_event Deserialize<'b>>( + fn deserialize_event( &self, event: JsValue, ) -> std::result::Result { diff --git a/crates/matrix-sdk-sled/src/cryptostore.rs b/crates/matrix-sdk-sled/src/cryptostore.rs index 550536374..646a5dc57 100644 --- a/crates/matrix-sdk-sled/src/cryptostore.rs +++ b/crates/matrix-sdk-sled/src/cryptostore.rs @@ -38,7 +38,7 @@ use ruma::{ events::room_key_request::RequestedKeyInfo, DeviceId, OwnedDeviceId, OwnedUserId, RoomId, TransactionId, UserId, }; -use serde::{Deserialize, Serialize}; +use serde::{de::DeserializeOwned, Deserialize, Serialize}; pub use sled::Error; use sled::{ transaction::{ConflictableTransactionError, TransactionError}, @@ -245,10 +245,7 @@ impl SledStore { } } - fn deserialize_value Deserialize<'b>>( - &self, - event: &[u8], - ) -> Result { + fn deserialize_value(&self, event: &[u8]) -> Result { if let Some(key) = &self.store_cipher { key.decrypt_value(event).map_err(CryptoStoreError::backend) } else { diff --git a/crates/matrix-sdk-sled/src/state_store.rs b/crates/matrix-sdk-sled/src/state_store.rs index e7f575f2b..07f7a4c91 100644 --- a/crates/matrix-sdk-sled/src/state_store.rs +++ b/crates/matrix-sdk-sled/src/state_store.rs @@ -51,7 +51,7 @@ use ruma::{ signatures::{redact_in_place, CanonicalJsonObject}, RoomVersionId, }; -use serde::{Deserialize, Serialize}; +use serde::{de::DeserializeOwned, Deserialize, Serialize}; use sled::{ transaction::{ConflictableTransactionError, TransactionError}, Config, Db, Transactional, Tree, @@ -368,10 +368,7 @@ impl SledStore { } } - fn deserialize_event Deserialize<'b>>( - &self, - event: &[u8], - ) -> Result { + fn deserialize_event(&self, event: &[u8]) -> Result { if let Some(key) = &self.store_cipher { Ok(key.decrypt_value(event)?) } else { diff --git a/crates/matrix-sdk-store-encryption/src/lib.rs b/crates/matrix-sdk-store-encryption/src/lib.rs index 0e0ad8d17..c6b169cd1 100644 --- a/crates/matrix-sdk-store-encryption/src/lib.rs +++ b/crates/matrix-sdk-store-encryption/src/lib.rs @@ -25,7 +25,7 @@ use displaydoc::Display; use hmac::Hmac; use pbkdf2::pbkdf2; use rand::{thread_rng, Error as RandomError, Fill}; -use serde::{Deserialize, Serialize}; +use serde::{de::DeserializeOwned, Deserialize, Serialize}; use sha2::Sha256; use zeroize::Zeroize; @@ -393,7 +393,7 @@ impl StoreCipher { /// assert_eq!(value, decrypted); /// # Result::<_, anyhow::Error>::Ok(()) }; /// ``` - pub fn decrypt_value Deserialize<'b>>(&self, value: &[u8]) -> Result { + pub fn decrypt_value(&self, value: &[u8]) -> Result { let value: EncryptedValue = serde_json::from_slice(value)?; self.decrypt_value_typed(value) } @@ -429,7 +429,7 @@ impl StoreCipher { /// assert_eq!(value, decrypted); /// # Result::<_, anyhow::Error>::Ok(()) }; /// ``` - pub fn decrypt_value_typed Deserialize<'b>>( + pub fn decrypt_value_typed( &self, value: EncryptedValue, ) -> Result { From b955e7aad977b7b283c4622a3c410d8b796d7c79 Mon Sep 17 00:00:00 2001 From: Jonas Platte Date: Wed, 18 May 2022 17:38:17 +0200 Subject: [PATCH 25/51] Use anyhow::Ok instead of turbofish on Result --- crates/matrix-sdk-store-encryption/src/lib.rs | 18 +++++++++--------- crates/matrix-sdk/src/client/mod.rs | 2 +- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/crates/matrix-sdk-store-encryption/src/lib.rs b/crates/matrix-sdk-store-encryption/src/lib.rs index c6b169cd1..2b2735647 100644 --- a/crates/matrix-sdk-store-encryption/src/lib.rs +++ b/crates/matrix-sdk-store-encryption/src/lib.rs @@ -76,7 +76,7 @@ pub enum Error { /// let decrypted: Value = store_cipher.decrypt_value(&encrypted)?; /// /// assert_eq!(value, decrypted); -/// # Result::<_, anyhow::Error>::Ok(()) }; +/// # anyhow::Ok(()) }; /// ``` #[allow(missing_debug_implementations)] pub struct StoreCipher { @@ -115,7 +115,7 @@ impl StoreCipher { /// let export = store_cipher.export("secret-passphrase"); /// /// // Save the export in your key/value store. - /// # Result::<_, anyhow::Error>::Ok(()) }; + /// # anyhow::Ok(()) }; /// ``` pub fn export(&self, passphrase: &str) -> Result, Error> { let mut rng = thread_rng(); @@ -171,7 +171,7 @@ impl StoreCipher { /// let imported = StoreCipher::import("secret-passphrase", &export)?; /// /// // Save the export in your key/value store. - /// # Result::<_, anyhow::Error>::Ok(()) }; + /// # anyhow::Ok(()) }; /// ``` pub fn import(passphrase: &str, encrypted: &[u8]) -> Result { let encrypted: EncryptedStoreCipher = serde_json::from_slice(encrypted)?; @@ -245,7 +245,7 @@ impl StoreCipher { /// let hashed_key = store_cipher.hash_key("list-of-pokemon", key.as_ref()); /// /// // It's now safe to insert the key into our key/value store. - /// # Result::<_, anyhow::Error>::Ok(()) }; + /// # anyhow::Ok(()) }; /// ``` pub fn hash_key(&self, table_name: &str, key: &[u8]) -> [u8; 32] { let mac_key = self.inner.get_mac_key_for_table(table_name); @@ -281,7 +281,7 @@ impl StoreCipher { /// let decrypted: Value = store_cipher.decrypt_value(&encrypted)?; /// /// assert_eq!(value, decrypted); - /// # Result::<_, anyhow::Error>::Ok(()) }; + /// # anyhow::Ok(()) }; /// ``` pub fn encrypt_value(&self, value: &impl Serialize) -> Result, Error> { Ok(serde_json::to_vec(&self.encrypt_value_typed(value)?)?) @@ -351,7 +351,7 @@ impl StoreCipher { /// let decrypted = store_cipher.decrypt_value_data(encrypted)?; /// /// assert_eq!(value, decrypted); - /// # Result::<_, anyhow::Error>::Ok(()) }; + /// # anyhow::Ok(()) }; /// ``` pub fn encrypt_value_data(&self, mut data: Vec) -> Result { let nonce = Keys::get_nonce()?; @@ -391,7 +391,7 @@ impl StoreCipher { /// let decrypted: Value = store_cipher.decrypt_value(&encrypted)?; /// /// assert_eq!(value, decrypted); - /// # Result::<_, anyhow::Error>::Ok(()) }; + /// # anyhow::Ok(()) }; /// ``` pub fn decrypt_value(&self, value: &[u8]) -> Result { let value: EncryptedValue = serde_json::from_slice(value)?; @@ -427,7 +427,7 @@ impl StoreCipher { /// let decrypted: Value = store_cipher.decrypt_value_typed(encrypted)?; /// /// assert_eq!(value, decrypted); - /// # Result::<_, anyhow::Error>::Ok(()) }; + /// # anyhow::Ok(()) }; /// ``` pub fn decrypt_value_typed( &self, @@ -467,7 +467,7 @@ impl StoreCipher { /// let decrypted = store_cipher.decrypt_value_data(encrypted)?; /// /// assert_eq!(value, decrypted); - /// # Result::<_, anyhow::Error>::Ok(()) }; + /// # anyhow::Ok(()) }; /// ``` pub fn decrypt_value_data(&self, value: EncryptedValue) -> Result, Error> { if value.version != VERSION { diff --git a/crates/matrix-sdk/src/client/mod.rs b/crates/matrix-sdk/src/client/mod.rs index 4fd1a8fe9..6f112e909 100644 --- a/crates/matrix-sdk/src/client/mod.rs +++ b/crates/matrix-sdk/src/client/mod.rs @@ -238,7 +238,7 @@ impl Client { /// // Change password /// } /// - /// # Result::<_, anyhow::Error>::Ok(()) }); + /// # anyhow::Ok(()) }); /// ``` pub async fn get_capabilities(&self) -> HttpResult { let res = self.send(get_capabilities::v3::Request::new(), None).await?; From d1410fcded2766688d1be432d3dec899e84a718a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Damir=20Jeli=C4=87?= Date: Wed, 18 May 2022 21:11:35 +0200 Subject: [PATCH 26/51] ci: Run cargo audit every day --- .github/workflows/audit.yml | 13 +++++++++++++ 1 file changed, 13 insertions(+) create mode 100644 .github/workflows/audit.yml diff --git a/.github/workflows/audit.yml b/.github/workflows/audit.yml new file mode 100644 index 000000000..1c9672410 --- /dev/null +++ b/.github/workflows/audit.yml @@ -0,0 +1,13 @@ +name: Security audit +on: + workflow_dispatch: + schedule: + - cron: '0 0 * * *' +jobs: + audit: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v1 + - uses: actions-rs/audit-check@v1 + with: + token: ${{ secrets.GITHUB_TOKEN }} From 9e6e76e5ed506e2880c7ed57950104e3fa7b7a47 Mon Sep 17 00:00:00 2001 From: Denis Kasak Date: Thu, 19 May 2022 13:38:13 +0000 Subject: [PATCH 27/51] docs: Fix reference to ClientConfig in doc comment --- crates/matrix-sdk/src/client/builder.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crates/matrix-sdk/src/client/builder.rs b/crates/matrix-sdk/src/client/builder.rs index c90e1c603..c317b8b08 100644 --- a/crates/matrix-sdk/src/client/builder.rs +++ b/crates/matrix-sdk/src/client/builder.rs @@ -113,7 +113,7 @@ impl ClientBuilder { self } - /// Create a new `ClientConfig` with the given [`StoreConfig`]. + /// Create a new `ClientBuilder` with the given [`StoreConfig`]. /// /// The easiest way to get a [`StoreConfig`] is to use the /// [`make_store_config`] method from the [`store`] module or directly from From 126e8f1bd95daa6157a26243bfc2aa6dac34a186 Mon Sep 17 00:00:00 2001 From: Denis Kasak Date: Thu, 19 May 2022 16:05:08 +0200 Subject: [PATCH 28/51] docs: Unify references to "cryptostore" as "crypto store" --- crates/matrix-sdk-crypto-ffi/src/machine.rs | 2 +- crates/matrix-sdk-crypto/src/backups/mod.rs | 2 +- crates/matrix-sdk-crypto/src/identities/device.rs | 4 ++-- crates/matrix-sdk-sled/src/cryptostore.rs | 4 ++-- crates/matrix-sdk/src/error.rs | 6 +++--- 5 files changed, 9 insertions(+), 9 deletions(-) diff --git a/crates/matrix-sdk-crypto-ffi/src/machine.rs b/crates/matrix-sdk-crypto-ffi/src/machine.rs index 65bf6f51e..b895bb9c6 100644 --- a/crates/matrix-sdk-crypto-ffi/src/machine.rs +++ b/crates/matrix-sdk-crypto-ffi/src/machine.rs @@ -1330,7 +1330,7 @@ impl OlmMachine { Ok(self.runtime.block_on(self.inner.backup_machine().room_key_counts())?.into()) } - /// Store the recovery key in the cryptostore. + /// Store the recovery key in the crypto store. /// /// This is useful if the client wants to support gossiping of the backup /// key. diff --git a/crates/matrix-sdk-crypto/src/backups/mod.rs b/crates/matrix-sdk-crypto/src/backups/mod.rs index 15494822a..10ebca631 100644 --- a/crates/matrix-sdk-crypto/src/backups/mod.rs +++ b/crates/matrix-sdk-crypto/src/backups/mod.rs @@ -220,7 +220,7 @@ impl BackupMachine { Ok(()) } - /// Store the recovery key in the cryptostore. + /// Store the recovery key in the crypto store. /// /// This is useful if the client wants to support gossiping of the backup /// key. diff --git a/crates/matrix-sdk-crypto/src/identities/device.rs b/crates/matrix-sdk-crypto/src/identities/device.rs index 58d15be65..96fa116f7 100644 --- a/crates/matrix-sdk-crypto/src/identities/device.rs +++ b/crates/matrix-sdk-crypto/src/identities/device.rs @@ -456,8 +456,8 @@ impl ReadOnlyDevice { /// Set the trust state of the device to the given state. /// - /// Note: This should only done in the cryptostore where the trust state can - /// be stored. + /// Note: This should only done in the crypto store where the trust state + /// can be stored. pub(crate) fn set_trust_state(&self, state: LocalTrust) { self.trust_state.store(state, Ordering::Relaxed) } diff --git a/crates/matrix-sdk-sled/src/cryptostore.rs b/crates/matrix-sdk-sled/src/cryptostore.rs index 646a5dc57..b9119240c 100644 --- a/crates/matrix-sdk-sled/src/cryptostore.rs +++ b/crates/matrix-sdk-sled/src/cryptostore.rs @@ -205,7 +205,7 @@ impl std::fmt::Debug for SledStore { } impl SledStore { - /// Open the sled based cryptostore at the given path using the given + /// Open the sled-based crypto store at the given path using the given /// passphrase to encrypt private data. pub fn open_with_passphrase( path: impl AsRef, @@ -224,7 +224,7 @@ impl SledStore { SledStore::open_helper(db, Some(path), store_cipher) } - /// Create a sled based cryptostore using the given sled database. + /// Create a sled-based crypto store using the given sled database. /// The given passphrase will be used to encrypt private data. pub fn open_with_database( db: Db, diff --git a/crates/matrix-sdk/src/error.rs b/crates/matrix-sdk/src/error.rs index 5e1b678b9..4ddf286df 100644 --- a/crates/matrix-sdk/src/error.rs +++ b/crates/matrix-sdk/src/error.rs @@ -198,9 +198,9 @@ pub enum RoomKeyImportError { #[error(transparent)] SerdeJson(#[from] JsonError), - /// The cryptostore isn't yet open, logging in is required to open the - /// cryptostore. - #[error("The cryptostore hasn't been yet opened, can't import yet.")] + /// The crypto store isn't yet open. Logging in is required to open the + /// crypto store. + #[error("The crypto store hasn't been yet opened, can't import yet.")] StoreClosed, /// An IO error happened. From c00c9d7b81f7a0c75e1b4a890b39ce700e6c4fc6 Mon Sep 17 00:00:00 2001 From: Denis Kasak Date: Thu, 19 May 2022 16:05:48 +0200 Subject: [PATCH 29/51] docs: Reword feature table so the wording is more uniform --- crates/matrix-sdk/README.md | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/crates/matrix-sdk/README.md b/crates/matrix-sdk/README.md index fa7af4118..c0376c32c 100644 --- a/crates/matrix-sdk/README.md +++ b/crates/matrix-sdk/README.md @@ -59,19 +59,19 @@ More examples can be found in the [examples] directory. The following crate feature flags are available: -| Feature | Default | Description | -| ------------------- | :-----: | --------------------------------------------------------------------- | -| `anyhow` | No | Better logging for event handlers that return `anyhow::Result` | -| `e2e-encryption` | Yes | Enable End-to-end encryption support | -| `eyre` | No | Better logging for event handlers that return `eyre::Result` | -| `image-proc` | No | Enables image processing to generate thumbnails | -| `image-rayon` | No | Enables faster image processing | -| `markdown` | No | Support to send Markdown-formatted messages | -| `qrcode` | Yes | QR code verification support | -| `sled` | Yes | Persistent storage of state and E2EE-Data using sled (if `e2e-encryption` is activated) -| `indexeddb` | No | Persistent storage of state and E2EE-Data for browsers using indexeddb (if `e2e-encryption` is activated) -| `socks` | No | Enables SOCKS support in the default HTTP client, [`reqwest`] | -| `sso-login` | No | Enables SSO login with a local HTTP server | +| Feature | Default | Description | +| ------------------- | :-----: | -------------------------------------------------------------------------------------------------------------------------- | +| `anyhow` | No | Better logging for event handlers that return `anyhow::Result` | +| `e2e-encryption` | Yes | End-to-end encryption (E2EE) support | +| `eyre` | No | Better logging for event handlers that return `eyre::Result` | +| `image-proc` | No | Image processing for generating thumbnails | +| `image-rayon` | No | Enables faster image processing | +| `markdown` | No | Support for sending Markdown-formatted messages | +| `qrcode` | Yes | QR code verification support | +| `sled` | Yes | Persistent storage of state and E2EE data (optionally, if feature `e2e-encryption` is enabled), via Sled | +| `indexeddb` | No | Persistent storage of state and E2EE data (optionally, if feature `e2e-encryption` is enabled) for browsers, via IndexedDB | +| `socks` | No | SOCKS support in the default HTTP client, [`reqwest`] | +| `sso-login` | No | Support for SSO login with a local HTTP server | [`reqwest`]: https://docs.rs/reqwest/0.11.5/reqwest/index.html From 3b70d7f9ba2fb93138ddf820c57d875dd1598b86 Mon Sep 17 00:00:00 2001 From: Denis Kasak Date: Thu, 19 May 2022 16:06:23 +0200 Subject: [PATCH 30/51] docs: Improve wording of store module-level comment Includes a fix to refer to the `e2e-encryption` feature instead of `encryption` (which doesn't exist). --- crates/matrix-sdk/src/store.rs | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/crates/matrix-sdk/src/store.rs b/crates/matrix-sdk/src/store.rs index c99665341..0fcba9f1f 100644 --- a/crates/matrix-sdk/src/store.rs +++ b/crates/matrix-sdk/src/store.rs @@ -16,12 +16,12 @@ //! The re-exports present here depend on the store-related features that are //! enabled: //! -//! 1. `sled` provides a `StateStore`, and a `CryptoStore` for encryption data -//! if `e2e-encryption` is enabled. This is the default persistent store -//! implementation for non-WebAssembly targets. -//! 2. `indexeddb`, too, provides a `StateStore` and a `CryptoStore` if -//! `encryption` is also enabled. This is the default persistent store -//! implementation for WebAssembly targets. +//! 1. The `sled` feature provides a `StateStore` for storing state and +//! a `CryptoStore` for E2EE data (if `e2e-encryption` is enabled). This is +//! the default persistent store implementation for non-WebAssembly targets. +//! 2. The `indexeddb` feature also provides a `StateStore` for storing state +//! and a `CryptoStore` (if `e2e-encryption` is enabled). This is the default +//! persistent store implementation for WebAssembly targets. //! //! Both options provide a `make_store_config` convenience method to create a //! [`StoreConfig`] for [`ClientBuilder::store_config()`]. From c3f2003eb7c2ffb69e955c14a64b66c8c862d42d Mon Sep 17 00:00:00 2001 From: Denis Kasak Date: Thu, 19 May 2022 16:19:23 +0200 Subject: [PATCH 31/51] docs: Slightly reword CryptoStore doc for consistency. --- crates/matrix-sdk-crypto/src/store/mod.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/crates/matrix-sdk-crypto/src/store/mod.rs b/crates/matrix-sdk-crypto/src/store/mod.rs index 890202f70..c82fe9345 100644 --- a/crates/matrix-sdk-crypto/src/store/mod.rs +++ b/crates/matrix-sdk-crypto/src/store/mod.rs @@ -639,8 +639,8 @@ impl CryptoStoreError { } } -/// Trait abstracting a store that the `OlmMachine` uses to store cryptographic -/// keys. +/// Represents a store that the `OlmMachine` uses to store E2EE data (such as +/// cryptographic keys). #[cfg_attr(target_arch = "wasm32", async_trait(?Send))] #[cfg_attr(not(target_arch = "wasm32"), async_trait)] pub trait CryptoStore: AsyncTraitDeps { From 813f38881233944ad6a314d3a558636603d238cf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Damir=20Jeli=C4=87?= Date: Fri, 20 May 2022 07:47:47 +0200 Subject: [PATCH 32/51] refactor(crypto): Make it clear that the encrypt method is for room events --- crates/matrix-sdk-base/src/client.rs | 2 +- crates/matrix-sdk-crypto-ffi/src/machine.rs | 2 +- crates/matrix-sdk-crypto/src/machine.rs | 9 ++++----- crates/matrix-sdk/src/room/joined.rs | 2 +- 4 files changed, 7 insertions(+), 8 deletions(-) diff --git a/crates/matrix-sdk-base/src/client.rs b/crates/matrix-sdk-base/src/client.rs index ff086f96c..df920c5a0 100644 --- a/crates/matrix-sdk-base/src/client.rs +++ b/crates/matrix-sdk-base/src/client.rs @@ -1071,7 +1071,7 @@ impl BaseClient { content: impl MessageLikeEventContent, ) -> Result { match self.olm_machine().await { - Some(o) => Ok(o.encrypt(room_id, content).await?), + Some(o) => Ok(o.encrypt_room_event(room_id, content).await?), None => panic!("Olm machine wasn't started"), } } diff --git a/crates/matrix-sdk-crypto-ffi/src/machine.rs b/crates/matrix-sdk-crypto-ffi/src/machine.rs index b895bb9c6..fbd01ee4f 100644 --- a/crates/matrix-sdk-crypto-ffi/src/machine.rs +++ b/crates/matrix-sdk-crypto-ffi/src/machine.rs @@ -523,7 +523,7 @@ impl OlmMachine { let content = AnyMessageLikeEventContent::from_parts(event_type, &content)?; let encrypted_content = self .runtime - .block_on(self.inner.encrypt(&room_id, content)) + .block_on(self.inner.encrypt_room_event(&room_id, content)) .expect("Encrypting an event produced an error"); Ok(serde_json::to_string(&encrypted_content)?) diff --git a/crates/matrix-sdk-crypto/src/machine.rs b/crates/matrix-sdk-crypto/src/machine.rs index 1d79ef5a7..7ce3e1eb6 100644 --- a/crates/matrix-sdk-crypto/src/machine.rs +++ b/crates/matrix-sdk-crypto/src/machine.rs @@ -651,15 +651,14 @@ impl OlmMachine { /// Panics if a group session for the given room wasn't shared beforehand. /// /// [`share_group_session`]: Self::share_group_session - pub async fn encrypt( + pub async fn encrypt_room_event( &self, room_id: &RoomId, content: impl MessageLikeEventContent, ) -> MegolmResult { let event_type = content.event_type().to_string(); let content = serde_json::to_value(&content)?; - - self.group_session_manager.encrypt(room_id, content, &event_type).await + self.encrypt_room_event_raw(room_id, content, &event_type).await } /// Encrypt a json [`Value`] content for the given room. @@ -682,7 +681,7 @@ impl OlmMachine { /// Panics if a group session for the given room wasn't shared beforehand. /// /// [`encrypt()`]: #method.encrypt - pub async fn encrypt_raw( + pub async fn encrypt_room_event_raw( &self, room_id: &RoomId, content: Value, @@ -1957,7 +1956,7 @@ pub(crate) mod tests { let content = RoomMessageEventContent::text_plain(plaintext); let encrypted_content = alice - .encrypt(room_id, AnyMessageLikeEventContent::RoomMessage(content.clone())) + .encrypt_room_event(room_id, AnyMessageLikeEventContent::RoomMessage(content.clone())) .await .unwrap(); diff --git a/crates/matrix-sdk/src/room/joined.rs b/crates/matrix-sdk/src/room/joined.rs index c7bcb9007..ef773eb91 100644 --- a/crates/matrix-sdk/src/room/joined.rs +++ b/crates/matrix-sdk/src/room/joined.rs @@ -575,7 +575,7 @@ impl Joined { let olm = self.client.olm_machine().await.expect("Olm machine wasn't started"); let encrypted_content = - olm.encrypt_raw(self.inner.room_id(), content, event_type).await?; + olm.encrypt_room_event_raw(self.inner.room_id(), content, event_type).await?; let raw_content = Raw::new(&encrypted_content) .expect("Failed to serialize encrypted event") .cast(); From 1b569a8fd42f203b3bea8d30fd33fd6f6d4bd709 Mon Sep 17 00:00:00 2001 From: Jonas Platte Date: Thu, 19 May 2022 17:57:11 +0200 Subject: [PATCH 33/51] chore: Consistently use anyhow::Result for example main fn's When an `Err` is propagated out of `main`, it will be printed using `Debug`, which is much easier to read in anyhow::Error's case. See also https://docs.rs/anyhow/latest/anyhow/struct.Error.html#display-representations --- crates/matrix-sdk/examples/cross_signing_bootstrap.rs | 6 ++++-- crates/matrix-sdk/examples/emoji_verification.rs | 6 ++++-- crates/matrix-sdk/examples/get_profiles.rs | 2 +- crates/matrix-sdk/examples/image_bot.rs | 2 +- crates/matrix-sdk/examples/login.rs | 6 ++++-- crates/matrix-sdk/examples/timeline.rs | 2 +- 6 files changed, 15 insertions(+), 9 deletions(-) diff --git a/crates/matrix-sdk/examples/cross_signing_bootstrap.rs b/crates/matrix-sdk/examples/cross_signing_bootstrap.rs index 3dd788ef2..eb4d1975c 100644 --- a/crates/matrix-sdk/examples/cross_signing_bootstrap.rs +++ b/crates/matrix-sdk/examples/cross_signing_bootstrap.rs @@ -72,7 +72,7 @@ async fn login( } #[tokio::main] -async fn main() -> Result<(), matrix_sdk::Error> { +async fn main() -> anyhow::Result<()> { tracing_subscriber::fmt::init(); let (homeserver_url, username, password) = @@ -87,5 +87,7 @@ async fn main() -> Result<(), matrix_sdk::Error> { } }; - login(homeserver_url, &username, &password).await + login(homeserver_url, &username, &password).await?; + + Ok(()) } diff --git a/crates/matrix-sdk/examples/emoji_verification.rs b/crates/matrix-sdk/examples/emoji_verification.rs index 4e9112157..b4572227a 100644 --- a/crates/matrix-sdk/examples/emoji_verification.rs +++ b/crates/matrix-sdk/examples/emoji_verification.rs @@ -201,7 +201,7 @@ async fn login( } #[tokio::main] -async fn main() -> Result<(), matrix_sdk::Error> { +async fn main() -> anyhow::Result<()> { tracing_subscriber::fmt::init(); let (homeserver_url, username, password) = @@ -216,5 +216,7 @@ async fn main() -> Result<(), matrix_sdk::Error> { } }; - login(homeserver_url, &username, &password).await + login(homeserver_url, &username, &password).await?; + + Ok(()) } diff --git a/crates/matrix-sdk/examples/get_profiles.rs b/crates/matrix-sdk/examples/get_profiles.rs index 677db3fe0..3c8edc6ea 100644 --- a/crates/matrix-sdk/examples/get_profiles.rs +++ b/crates/matrix-sdk/examples/get_profiles.rs @@ -45,7 +45,7 @@ async fn login( } #[tokio::main] -async fn main() -> Result<(), matrix_sdk::Error> { +async fn main() -> anyhow::Result<()> { tracing_subscriber::fmt::init(); let (homeserver_url, username, password) = diff --git a/crates/matrix-sdk/examples/image_bot.rs b/crates/matrix-sdk/examples/image_bot.rs index 6f6724f1b..208ad7c5a 100644 --- a/crates/matrix-sdk/examples/image_bot.rs +++ b/crates/matrix-sdk/examples/image_bot.rs @@ -74,7 +74,7 @@ async fn login_and_sync( } #[tokio::main] -async fn main() -> Result<(), matrix_sdk::Error> { +async fn main() -> anyhow::Result<()> { tracing_subscriber::fmt::init(); let (homeserver_url, username, password, image_path) = match (env::args().nth(1), env::args().nth(2), env::args().nth(3), env::args().nth(4)) { diff --git a/crates/matrix-sdk/examples/login.rs b/crates/matrix-sdk/examples/login.rs index 1d68f5e64..259359773 100644 --- a/crates/matrix-sdk/examples/login.rs +++ b/crates/matrix-sdk/examples/login.rs @@ -47,7 +47,7 @@ async fn login( } #[tokio::main] -async fn main() -> Result<(), matrix_sdk::Error> { +async fn main() -> anyhow::Result<()> { tracing_subscriber::fmt::init(); let (homeserver_url, username, password) = @@ -62,5 +62,7 @@ async fn main() -> Result<(), matrix_sdk::Error> { } }; - login(homeserver_url, &username, &password).await + login(homeserver_url, &username, &password).await?; + + Ok(()) } diff --git a/crates/matrix-sdk/examples/timeline.rs b/crates/matrix-sdk/examples/timeline.rs index d8d32802b..339a7ee93 100644 --- a/crates/matrix-sdk/examples/timeline.rs +++ b/crates/matrix-sdk/examples/timeline.rs @@ -56,7 +56,7 @@ async fn print_timeline(room: Room) { } #[tokio::main] -async fn main() -> Result<(), matrix_sdk::Error> { +async fn main() -> anyhow::Result<()> { tracing_subscriber::fmt::init(); let (homeserver_url, username, password, room_id) = From cbcc5feef25dc3b90eb09e50c40087a5497454e7 Mon Sep 17 00:00:00 2001 From: Jonas Platte Date: Thu, 19 May 2022 18:09:39 +0200 Subject: [PATCH 34/51] fix(sled): Fix unused import when experimental-timeline isn't enabled --- crates/matrix-sdk-sled/src/state_store.rs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/crates/matrix-sdk-sled/src/state_store.rs b/crates/matrix-sdk-sled/src/state_store.rs index 07f7a4c91..d5e4c70a0 100644 --- a/crates/matrix-sdk-sled/src/state_store.rs +++ b/crates/matrix-sdk-sled/src/state_store.rs @@ -51,7 +51,9 @@ use ruma::{ signatures::{redact_in_place, CanonicalJsonObject}, RoomVersionId, }; -use serde::{de::DeserializeOwned, Deserialize, Serialize}; +#[cfg(feature = "experimental-timeline")] +use serde::Deserialize; +use serde::{de::DeserializeOwned, Serialize}; use sled::{ transaction::{ConflictableTransactionError, TransactionError}, Config, Db, Transactional, Tree, From 85949081cef83a5ed30933c74042e28bc78fcf56 Mon Sep 17 00:00:00 2001 From: Jonas Platte Date: Thu, 19 May 2022 18:24:44 +0200 Subject: [PATCH 35/51] chore: Consistently use anyhow for Result-returning doctests Cuts down on syntactic noise. --- crates/matrix-sdk/src/account.rs | 24 ++++++++++++------------ crates/matrix-sdk/src/attachment.rs | 2 +- crates/matrix-sdk/src/client/builder.rs | 2 +- crates/matrix-sdk/src/client/mod.rs | 16 ++++++++-------- crates/matrix-sdk/src/room/common.rs | 8 ++++---- crates/matrix-sdk/src/room/joined.rs | 14 +++++++------- 6 files changed, 33 insertions(+), 33 deletions(-) diff --git a/crates/matrix-sdk/src/account.rs b/crates/matrix-sdk/src/account.rs index 995095e5c..b195a1f0c 100644 --- a/crates/matrix-sdk/src/account.rs +++ b/crates/matrix-sdk/src/account.rs @@ -67,7 +67,7 @@ impl Account { /// if let Some(name) = client.account().get_display_name().await? { /// println!("Logged in as user '{}' with display name '{}'", user, name); /// } - /// # Result::<_, matrix_sdk::Error>::Ok(()) }); + /// # anyhow::Ok(()) }); /// ``` pub async fn get_display_name(&self) -> Result> { let user_id = self.client.user_id().await.ok_or(Error::AuthenticationRequired)?; @@ -90,7 +90,7 @@ impl Account { /// client.login(user, "password", None, None).await?; /// /// client.account().set_display_name(Some("Alice")).await?; - /// # Result::<_, matrix_sdk::Error>::Ok(()) }); + /// # anyhow::Ok(()) }); /// ``` pub async fn set_display_name(&self, name: Option<&str>) -> Result<()> { let user_id = self.client.user_id().await.ok_or(Error::AuthenticationRequired)?; @@ -115,7 +115,7 @@ impl Account { /// if let Some(url) = client.account().get_avatar_url().await? { /// println!("Your avatar's mxc url is {}", url); /// } - /// # Result::<_, matrix_sdk::Error>::Ok(()) }); + /// # anyhow::Ok(()) }); /// ``` pub async fn get_avatar_url(&self) -> Result> { let user_id = self.client.user_id().await.ok_or(Error::AuthenticationRequired)?; @@ -164,7 +164,7 @@ impl Account { /// if let Some(avatar) = client.account().get_avatar(MediaFormat::File).await? { /// std::fs::write("avatar.png", avatar); /// } - /// # Result::<_, matrix_sdk::Error>::Ok(()) }); + /// # anyhow::Ok(()) }); /// ``` pub async fn get_avatar(&self, format: MediaFormat) -> Result>> { if let Some(url) = self.get_avatar_url().await? { @@ -199,7 +199,7 @@ impl Account { /// let mut image = File::open(&path)?; /// /// client.account().upload_avatar(&mime::IMAGE_JPEG, &mut image).await?; - /// # Result::<_, matrix_sdk::Error>::Ok(()) }); + /// # anyhow::Ok(()) }); /// ``` pub async fn upload_avatar( &self, @@ -230,7 +230,7 @@ impl Account { /// profile.avatar_url /// ); /// } - /// # Result::<_, matrix_sdk::Error>::Ok(()) }); + /// # anyhow::Ok(()) }); /// ``` pub async fn get_profile(&self) -> Result { let user_id = self.client.user_id().await.ok_or(Error::AuthenticationRequired)?; @@ -276,7 +276,7 @@ impl Account { /// "myverysecretpassword", /// Some(AuthData::Dummy(Dummy::new())), /// ).await?; - /// # Result::<_, matrix_sdk::Error>::Ok(()) }); + /// # anyhow::Ok(()) }); /// ``` /// [uiaa]: https://spec.matrix.org/v1.2/client-server-api/#user-interactive-authentication-api /// [`UiaaResponse`]: ruma::api::client::uiaa::UiaaResponse @@ -326,7 +326,7 @@ impl Account { /// /// // Proceed with UIAA. /// - /// # Result::<_, matrix_sdk::Error>::Ok(()) }); + /// # anyhow::Ok(()) }); /// ``` /// [3pid]: https://spec.matrix.org/v1.2/appendices/#3pid-types /// [uiaa]: https://spec.matrix.org/v1.2/client-server-api/#user-interactive-authentication-api @@ -362,7 +362,7 @@ impl Account { /// for threepid in threepids { /// println!("Found 3PID '{}' of type '{}'", threepid.address, threepid.medium); /// } - /// # Result::<_, matrix_sdk::Error>::Ok(()) }); + /// # anyhow::Ok(()) }); /// ``` /// [3pid]: https://spec.matrix.org/v1.2/appendices/#3pid-types pub async fn get_3pids(&self) -> Result { @@ -429,7 +429,7 @@ impl Account { /// /// // Proceed with UIAA. /// - /// # Result::<_, matrix_sdk::Error>::Ok(()) }); + /// # anyhow::Ok(()) }); /// ``` /// [3pid]: https://spec.matrix.org/v1.2/appendices/#3pid-types /// [`ErrorKind::ThreepidInUse`]: ruma::api::client::error::ErrorKind::ThreepidInUse @@ -511,7 +511,7 @@ impl Account { /// /// // Proceed with UIAA. /// - /// # Result::<_, matrix_sdk::Error>::Ok(()) }); + /// # anyhow::Ok(()) }); /// ``` /// [3pid]: https://spec.matrix.org/v1.2/appendices/#3pid-types /// [`ErrorKind::ThreepidInUse`]: ruma::api::client::error::ErrorKind::ThreepidInUse @@ -617,7 +617,7 @@ impl Account { /// _ => println!("Could not unbind 3PID from the Identity Server"), /// } /// - /// # Result::<_, matrix_sdk::Error>::Ok(()) }); + /// # anyhow::Ok(()) }); /// ``` /// [3pid]: https://spec.matrix.org/v1.2/appendices/#3pid-types /// [`ThirdPartyIdRemovalStatus::Success`]: ruma::api::client::account::ThirdPartyIdRemovalStatus::Success diff --git a/crates/matrix-sdk/src/attachment.rs b/crates/matrix-sdk/src/attachment.rs index 5c9fa78ba..2a83134b4 100644 --- a/crates/matrix-sdk/src/attachment.rs +++ b/crates/matrix-sdk/src/attachment.rs @@ -336,7 +336,7 @@ impl<'a, R: Read> AttachmentConfig<'a, R> { /// config, /// ).await?; /// } -/// # Result::<_, matrix_sdk::Error>::Ok(()) }); +/// # anyhow::Ok(()) }); /// ``` #[cfg(feature = "image-proc")] pub fn generate_image_thumbnail( diff --git a/crates/matrix-sdk/src/client/builder.rs b/crates/matrix-sdk/src/client/builder.rs index c317b8b08..479c344ac 100644 --- a/crates/matrix-sdk/src/client/builder.rs +++ b/crates/matrix-sdk/src/client/builder.rs @@ -190,7 +190,7 @@ impl ClientBuilder { /// let client_config = Client::builder() /// .proxy("http://localhost:8080"); /// - /// # Result::<_, matrix_sdk::Error>::Ok(()) + /// # anyhow::Ok(()) /// # }); /// ``` #[cfg(not(target_arch = "wasm32"))] diff --git a/crates/matrix-sdk/src/client/mod.rs b/crates/matrix-sdk/src/client/mod.rs index 6f112e909..1691ae2b4 100644 --- a/crates/matrix-sdk/src/client/mod.rs +++ b/crates/matrix-sdk/src/client/mod.rs @@ -703,7 +703,7 @@ impl Client { /// "Logged in as {}, got device_id {} and access_token {}", /// user, response.device_id, response.access_token /// ); - /// # Result::<_, matrix_sdk::Error>::Ok(()) }); + /// # anyhow::Ok(()) }); /// ``` /// /// [`restore_login`]: #method.restore_login @@ -1372,7 +1372,7 @@ impl Client { /// for room in response.chunk { /// println!("Found room {:?}", room); /// } - /// # Result::<_, matrix_sdk::Error>::Ok(()) }); + /// # anyhow::Ok(()) }); /// ``` pub async fn public_rooms_filtered( &self, @@ -1476,7 +1476,7 @@ impl Client { /// /// // Check the corresponding Response struct to find out what types are /// // returned - /// # Result::<_, matrix_sdk::Error>::Ok(()) }); + /// # anyhow::Ok(()) }); /// ``` pub async fn send( &self, @@ -1544,7 +1544,7 @@ impl Client { /// device.display_name.as_deref().unwrap_or("") /// ); /// } - /// # Result::<_, matrix_sdk::Error>::Ok(()) }); + /// # anyhow::Ok(()) }); /// ``` pub async fn devices(&self) -> HttpResult { let request = get_devices::v3::Request::new(); @@ -1601,7 +1601,7 @@ impl Client { /// .await?; /// } /// } - /// # Result::<_, matrix_sdk::Error>::Ok(()) }); + /// # anyhow::Ok(()) }); pub async fn delete_devices( &self, devices: &[OwnedDeviceId], @@ -1690,7 +1690,7 @@ impl Client { /// // Now keep on syncing forever. `sync()` will use the stored sync token /// // from our `sync_once()` call automatically. /// client.sync(SyncSettings::default()).await; - /// # Result::<_, matrix_sdk::Error>::Ok(()) }); + /// # anyhow::Ok(()) }); /// ``` /// /// [`sync`]: #method.sync @@ -1792,7 +1792,7 @@ impl Client { /// // Now keep on syncing forever. `sync()` will use the latest sync token /// // automatically. /// client.sync(SyncSettings::default()).await; - /// # Result::<_, matrix_sdk::Error>::Ok(()) }); + /// # anyhow::Ok(()) }); /// ``` /// /// [argument docs]: #method.sync_once @@ -1921,7 +1921,7 @@ impl Client { /// } /// } /// - /// # Result::<_, matrix_sdk::Error>::Ok(()) }); + /// # anyhow::Ok(()) }); /// ``` #[instrument(skip(self))] pub async fn sync_stream<'a>( diff --git a/crates/matrix-sdk/src/room/common.rs b/crates/matrix-sdk/src/room/common.rs index 7730d6c21..a78a0f7b2 100644 --- a/crates/matrix-sdk/src/room/common.rs +++ b/crates/matrix-sdk/src/room/common.rs @@ -297,7 +297,7 @@ impl Common { /// } /// } /// - /// # Result::<_, matrix_sdk::Error>::Ok(()) + /// # anyhow::Ok(()) /// # }); /// ``` #[cfg(feature = "experimental-timeline")] @@ -366,7 +366,7 @@ impl Common { /// } /// } /// - /// # Result::<_, matrix_sdk::Error>::Ok(()) + /// # anyhow::Ok(()) /// # }); /// ``` #[cfg(feature = "experimental-timeline")] @@ -430,7 +430,7 @@ impl Common { /// }); /// } /// - /// # Result::<_, matrix_sdk::Error>::Ok(()) + /// # anyhow::Ok(()) /// # }); /// ``` #[cfg(feature = "experimental-timeline")] @@ -845,7 +845,7 @@ impl Common { /// /// room.set_tag(TagName::User(user_tag), tag_info ).await?; /// } - /// # Result::<_, matrix_sdk::Error>::Ok(()) }); + /// # anyhow::Ok(()) }); /// ``` pub async fn set_tag( &self, diff --git a/crates/matrix-sdk/src/room/joined.rs b/crates/matrix-sdk/src/room/joined.rs index c7bcb9007..d9592f6e1 100644 --- a/crates/matrix-sdk/src/room/joined.rs +++ b/crates/matrix-sdk/src/room/joined.rs @@ -177,7 +177,7 @@ impl Joined { /// if let Some(room) = client.get_joined_room(&room_id) { /// room.typing_notice(true).await? /// } - /// # Result::<_, matrix_sdk::Error>::Ok(()) }); + /// # anyhow::Ok(()) }); /// ``` pub async fn typing_notice(&self, typing: bool) -> Result<()> { // Only send a request to the homeserver if the old timeout has elapsed @@ -288,7 +288,7 @@ impl Joined { /// if let Some(room) = client.get_joined_room(&room_id) { /// room.enable_encryption().await? /// } - /// # Result::<_, matrix_sdk::Error>::Ok(()) }); + /// # anyhow::Ok(()) }); /// ``` pub async fn enable_encryption(&self) -> Result<()> { use ruma::{ @@ -458,7 +458,7 @@ impl Joined { /// if let Some(room) = client.get_joined_room(&room_id) { /// room.send(content, Some(&txn_id)).await?; /// } - /// # Result::<_, matrix_sdk::Error>::Ok(()) }); + /// # anyhow::Ok(()) }); /// ``` /// /// [`SyncMessageLikeEvent`]: ruma::events::SyncMessageLikeEvent @@ -526,7 +526,7 @@ impl Joined { /// if let Some(room) = client.get_joined_room(&room_id) { /// room.send_raw(content, "m.room.message", None).await?; /// } - /// # Result::<_, matrix_sdk::Error>::Ok(()) }); + /// # anyhow::Ok(()) }); /// ``` /// /// [`SyncMessageLikeEvent`]: ruma::events::SyncMessageLikeEvent @@ -648,7 +648,7 @@ impl Joined { /// AttachmentConfig::new(), /// ).await?; /// } - /// # Result::<_, matrix_sdk::Error>::Ok(()) }); + /// # anyhow::Ok(()) }); /// ``` pub async fn send_attachment( &self, @@ -813,7 +813,7 @@ impl Joined { /// if let Some(room) = client.get_joined_room(&room_id) { /// room.send_state_event(content, "").await?; /// } - /// # Result::<_, matrix_sdk::Error>::Ok(()) }); + /// # anyhow::Ok(()) }); /// ``` pub async fn send_state_event( &self, @@ -907,7 +907,7 @@ impl Joined { /// let reason = Some("Indecent material"); /// room.redact(&event_id, reason, None).await?; /// } - /// # Result::<_, matrix_sdk::Error>::Ok(()) }); + /// # anyhow::Ok(()) }); /// ``` pub async fn redact( &self, From d6c6211c00ebbabb8045120b7715c9722be45bda Mon Sep 17 00:00:00 2001 From: Jonas Platte Date: Thu, 19 May 2022 18:25:10 +0200 Subject: [PATCH 36/51] chore: Use matrix_sdk::Result alias more --- crates/matrix-sdk-ffi/src/backward_stream.rs | 4 ++-- crates/matrix-sdk/examples/cross_signing_bootstrap.rs | 6 +----- crates/matrix-sdk/examples/emoji_verification.rs | 6 +----- crates/matrix-sdk/examples/get_profiles.rs | 2 +- crates/matrix-sdk/examples/image_bot.rs | 2 +- crates/matrix-sdk/examples/login.rs | 6 +----- 6 files changed, 7 insertions(+), 19 deletions(-) diff --git a/crates/matrix-sdk-ffi/src/backward_stream.rs b/crates/matrix-sdk-ffi/src/backward_stream.rs index 087c1ad0e..b3c281ef5 100644 --- a/crates/matrix-sdk-ffi/src/backward_stream.rs +++ b/crates/matrix-sdk-ffi/src/backward_stream.rs @@ -2,7 +2,7 @@ use core::pin::Pin; use std::sync::Arc; use futures_core::Stream; -use matrix_sdk::{deserialized_responses::SyncRoomEvent, locks::Mutex}; +use matrix_sdk::{deserialized_responses::SyncRoomEvent, locks::Mutex, Result}; use tokio_stream::StreamExt; use tracing::error; @@ -11,7 +11,7 @@ use super::{ RUNTIME, }; -type MsgStream = Pin> + Send>>; +type MsgStream = Pin> + Send>>; pub struct BackwardsStream { stream: Arc>, diff --git a/crates/matrix-sdk/examples/cross_signing_bootstrap.rs b/crates/matrix-sdk/examples/cross_signing_bootstrap.rs index eb4d1975c..35ea66654 100644 --- a/crates/matrix-sdk/examples/cross_signing_bootstrap.rs +++ b/crates/matrix-sdk/examples/cross_signing_bootstrap.rs @@ -37,11 +37,7 @@ async fn bootstrap(client: Client, user_id: OwnedUserId, password: String) { } } -async fn login( - homeserver_url: String, - username: &str, - password: &str, -) -> Result<(), matrix_sdk::Error> { +async fn login(homeserver_url: String, username: &str, password: &str) -> matrix_sdk::Result<()> { let homeserver_url = Url::parse(&homeserver_url).expect("Couldn't parse the homeserver URL"); let client = Client::new(homeserver_url).await.unwrap(); diff --git a/crates/matrix-sdk/examples/emoji_verification.rs b/crates/matrix-sdk/examples/emoji_verification.rs index b4572227a..5bd5b9b06 100644 --- a/crates/matrix-sdk/examples/emoji_verification.rs +++ b/crates/matrix-sdk/examples/emoji_verification.rs @@ -65,11 +65,7 @@ async fn print_devices(user_id: &UserId, client: &Client) { } } -async fn login( - homeserver_url: String, - username: &str, - password: &str, -) -> Result<(), matrix_sdk::Error> { +async fn login(homeserver_url: String, username: &str, password: &str) -> matrix_sdk::Result<()> { let homeserver_url = Url::parse(&homeserver_url).expect("Couldn't parse the homeserver URL"); let client = Client::new(homeserver_url).await.unwrap(); diff --git a/crates/matrix-sdk/examples/get_profiles.rs b/crates/matrix-sdk/examples/get_profiles.rs index 3c8edc6ea..62314b24a 100644 --- a/crates/matrix-sdk/examples/get_profiles.rs +++ b/crates/matrix-sdk/examples/get_profiles.rs @@ -35,7 +35,7 @@ async fn login( homeserver_url: String, username: &str, password: &str, -) -> Result { +) -> matrix_sdk::Result { let homeserver_url = Url::parse(&homeserver_url).expect("Couldn't parse the homeserver URL"); let client = Client::new(homeserver_url).await.unwrap(); diff --git a/crates/matrix-sdk/examples/image_bot.rs b/crates/matrix-sdk/examples/image_bot.rs index 208ad7c5a..4dda9554c 100644 --- a/crates/matrix-sdk/examples/image_bot.rs +++ b/crates/matrix-sdk/examples/image_bot.rs @@ -56,7 +56,7 @@ async fn login_and_sync( username: String, password: String, image: File, -) -> Result<(), matrix_sdk::Error> { +) -> matrix_sdk::Result<()> { let homeserver_url = Url::parse(&homeserver_url).expect("Couldn't parse the homeserver URL"); let client = Client::new(homeserver_url).await.unwrap(); diff --git a/crates/matrix-sdk/examples/login.rs b/crates/matrix-sdk/examples/login.rs index 259359773..d9967530f 100644 --- a/crates/matrix-sdk/examples/login.rs +++ b/crates/matrix-sdk/examples/login.rs @@ -30,11 +30,7 @@ async fn on_room_message(event: OriginalSyncRoomMessageEvent, room: Room) { } } -async fn login( - homeserver_url: String, - username: &str, - password: &str, -) -> Result<(), matrix_sdk::Error> { +async fn login(homeserver_url: String, username: &str, password: &str) -> matrix_sdk::Result<()> { let homeserver_url = Url::parse(&homeserver_url).expect("Couldn't parse the homeserver URL"); let client = Client::new(homeserver_url).await.unwrap(); From f3045dbf995f309b44fffa3bb67af30804e7ccab Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Damir=20Jeli=C4=87?= Date: Fri, 20 May 2022 08:32:50 +0200 Subject: [PATCH 37/51] fixup! refactor(crypto): Make it clear that the encrypt method is for room events --- crates/matrix-sdk-crypto/src/machine.rs | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/crates/matrix-sdk-crypto/src/machine.rs b/crates/matrix-sdk-crypto/src/machine.rs index 7ce3e1eb6..ee2880d03 100644 --- a/crates/matrix-sdk-crypto/src/machine.rs +++ b/crates/matrix-sdk-crypto/src/machine.rs @@ -663,8 +663,9 @@ impl OlmMachine { /// Encrypt a json [`Value`] content for the given room. /// - /// This method is equivalent to the [`encrypt()`] method but operates on an - /// arbitrary JSON value instead of strongly-typed event content struct. + /// This method is equivalent to the [`OlmMachine::encrypt_room_event()`] + /// method but operates on an arbitrary JSON value instead of strongly-typed + /// event content struct. /// /// # Arguments /// @@ -679,8 +680,6 @@ impl OlmMachine { /// # Panics /// /// Panics if a group session for the given room wasn't shared beforehand. - /// - /// [`encrypt()`]: #method.encrypt pub async fn encrypt_room_event_raw( &self, room_id: &RoomId, From e927834108464451de410804e6f255cda93224ca Mon Sep 17 00:00:00 2001 From: Benjamin Kampmann Date: Fri, 20 May 2022 08:33:34 +0200 Subject: [PATCH 38/51] ci(CodeCoverage): split code coverage reporting in mandatory and optional areas --- codecov.yaml | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/codecov.yaml b/codecov.yaml index 33f6aec9f..1ae6e252a 100644 --- a/codecov.yaml +++ b/codecov.yaml @@ -2,10 +2,24 @@ coverage: status: project: default: - # Commits pushed to master should not make the overall - # project coverage decrease by more than 1%: + # by default, we only care about test coverage of the main + # rust crates target: auto threshold: 1% + paths: + - "crates" + bindings: + # Coverage of binding tests is recorded but for informational + # purposes only + informational: true + paths: + - "bindings" + labs: + # Coverage of lab tests is recorded but for informational + # purposes only + informational: true + paths: + - "labs" patch: default: # Be tolerant on slight code coverage diff on PRs to limit From 81db9ef4ca4b3cf610bd4d46e2d10435a5500ca5 Mon Sep 17 00:00:00 2001 From: Benjamin Kampmann Date: Fri, 20 May 2022 08:34:56 +0200 Subject: [PATCH 39/51] ci(CodeCoverage): Remove patch-level coverage reporting --- codecov.yaml | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) diff --git a/codecov.yaml b/codecov.yaml index 1ae6e252a..dff46c0a3 100644 --- a/codecov.yaml +++ b/codecov.yaml @@ -20,11 +20,4 @@ coverage: informational: true paths: - "labs" - patch: - default: - # Be tolerant on slight code coverage diff on PRs to limit - # noisy red coverage status on github PRs. - # Note: The coverage stats are still uploaded - # to codecov so that PR reviewers can see uncovered lines - target: auto - threshold: 1% + patch: off From dd1f81770139596781caaf98c253e4dd79dfa859 Mon Sep 17 00:00:00 2001 From: Benjamin Kampmann Date: Fri, 20 May 2022 10:26:31 +0200 Subject: [PATCH 40/51] ci(CodeCoverage): exclude ffi & wasm from default project --- codecov.yaml | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/codecov.yaml b/codecov.yaml index dff46c0a3..cf8225819 100644 --- a/codecov.yaml +++ b/codecov.yaml @@ -7,17 +7,29 @@ coverage: target: auto threshold: 1% paths: - - "crates" + - "crates/matrix-sdk/" + - "crates/matrix-sdk-appservice/" + - "crates/matrix-sdk-base/" + - "crates/matrix-sdk-common/" + - "crates/matrix-sdk-crypto/" + - "crates/matrix-sdk-qrcode/" + - "crates/matrix-sdk-sled/" + - "crates/matrix-sdk-store-encryption/" + # Coverage of wasm tests isn't supported at the moment, + # see rustwasm/wasm-bindgen#2276 + # - "crates/matrix-sdk-indexeddb" bindings: # Coverage of binding tests is recorded but for informational # purposes only informational: true paths: - - "bindings" + - "bindings/" + - "crates/matrix-sdk-crypto-ffi/" + - "crates/matrix-sdk-ffi/" labs: # Coverage of lab tests is recorded but for informational # purposes only informational: true paths: - - "labs" + - "labs/" patch: off From a992a4e831759f248bbb8198e6d6bdad1e643a16 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Damir=20Jeli=C4=87?= Date: Mon, 23 May 2022 11:07:12 +0200 Subject: [PATCH 41/51] feat(store-encryption): Derive Eq for some structs --- crates/matrix-sdk-store-encryption/src/lib.rs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/crates/matrix-sdk-store-encryption/src/lib.rs b/crates/matrix-sdk-store-encryption/src/lib.rs index 2b2735647..f582a9470 100644 --- a/crates/matrix-sdk-store-encryption/src/lib.rs +++ b/crates/matrix-sdk-store-encryption/src/lib.rs @@ -500,7 +500,7 @@ impl MacKey { /// Encrypted value, ready for storage, as created by the /// [`StoreCipher::encrypt_value_data()`] -#[derive(Debug, Serialize, Deserialize, PartialEq)] +#[derive(Debug, Serialize, Deserialize, PartialEq, Eq)] pub struct EncryptedValue { version: u8, ciphertext: Vec, @@ -557,7 +557,7 @@ impl Keys { } /// Version specific info for the key derivation method that is used. -#[derive(Debug, Serialize, Deserialize, PartialEq)] +#[derive(Debug, Serialize, Deserialize, PartialEq, Eq)] enum KdfInfo { /// The PBKDF2 to Chacha key derivation variant. Pbkdf2ToChaCha20Poly1305 { @@ -572,7 +572,7 @@ enum KdfInfo { /// Version specific info for encryption method that is used to encrypt our /// store cipher. -#[derive(Debug, Serialize, Deserialize, PartialEq)] +#[derive(Debug, Serialize, Deserialize, PartialEq, Eq)] enum CipherTextInfo { /// A store cipher encrypted using the ChaCha20Poly1305 AEAD. ChaCha20Poly1305 { @@ -585,7 +585,7 @@ enum CipherTextInfo { /// An encrypted version of our store cipher, this can be safely stored in a /// database. -#[derive(Debug, Serialize, Deserialize, PartialEq)] +#[derive(Debug, Serialize, Deserialize, PartialEq, Eq)] struct EncryptedStoreCipher { /// Info about the key derivation method that was used to expand the /// passphrase into an encryption key. From 1f722f224f05e15167dbf16bfe4927f6b4d69889 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Damir=20Jeli=C4=87?= Date: Mon, 23 May 2022 11:35:07 +0200 Subject: [PATCH 42/51] feat(crypto): Add a bunch of Eq implementations --- crates/matrix-sdk-crypto/src/gossiping/mod.rs | 2 +- crates/matrix-sdk-crypto/src/identities/device.rs | 2 +- crates/matrix-sdk-crypto/src/lib.rs | 2 +- crates/matrix-sdk-crypto/src/types/one_time_keys.rs | 4 ++-- crates/matrix-sdk-crypto/src/verification/mod.rs | 2 +- 5 files changed, 6 insertions(+), 6 deletions(-) diff --git a/crates/matrix-sdk-crypto/src/gossiping/mod.rs b/crates/matrix-sdk-crypto/src/gossiping/mod.rs index 8a5427e57..d998081a1 100644 --- a/crates/matrix-sdk-crypto/src/gossiping/mod.rs +++ b/crates/matrix-sdk-crypto/src/gossiping/mod.rs @@ -43,7 +43,7 @@ use crate::{ }; /// An error describing why a key share request won't be honored. -#[derive(Debug, Clone, Error, PartialEq)] +#[derive(Debug, Clone, Error, PartialEq, Eq)] pub enum KeyForwardDecision { /// The key request is from a device that we don't own, we're only sharing /// sessions that we know the requesting device already was supposed to get. diff --git a/crates/matrix-sdk-crypto/src/identities/device.rs b/crates/matrix-sdk-crypto/src/identities/device.rs index 96fa116f7..d843bc1be 100644 --- a/crates/matrix-sdk-crypto/src/identities/device.rs +++ b/crates/matrix-sdk-crypto/src/identities/device.rs @@ -348,7 +348,7 @@ impl UserDevices { } } -#[derive(Debug, Clone, Copy, PartialEq, Serialize, Deserialize)] +#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)] /// The local trust state of a device. pub enum LocalTrust { /// The device has been verified and is trusted. diff --git a/crates/matrix-sdk-crypto/src/lib.rs b/crates/matrix-sdk-crypto/src/lib.rs index 3709691ea..3d57bcc6c 100644 --- a/crates/matrix-sdk-crypto/src/lib.rs +++ b/crates/matrix-sdk-crypto/src/lib.rs @@ -45,7 +45,7 @@ use std::collections::{BTreeMap, BTreeSet}; use ruma::OwnedRoomId; /// Return type for the room key importing. -#[derive(Debug, Clone, PartialEq)] +#[derive(Debug, Clone, PartialEq, Eq)] pub struct RoomKeyImportResult { /// The number of room keys that were imported. pub imported_count: usize, diff --git a/crates/matrix-sdk-crypto/src/types/one_time_keys.rs b/crates/matrix-sdk-crypto/src/types/one_time_keys.rs index e28379504..f3c609535 100644 --- a/crates/matrix-sdk-crypto/src/types/one_time_keys.rs +++ b/crates/matrix-sdk-crypto/src/types/one_time_keys.rs @@ -29,7 +29,7 @@ use vodozemac::{Curve25519PublicKey, Ed25519Signature}; pub type SignedKeySignatures = BTreeMap>; /// A key for the SignedCurve25519 algorithm -#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)] +#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)] pub struct SignedKey { // /// The Curve25519 key that can be used to establish Olm sessions. #[serde(deserialize_with = "deserialize_curve_key", serialize_with = "serialize_curve_key")] @@ -151,7 +151,7 @@ impl SignedKey { } /// A one-time public key for "pre-key" messages. -#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)] +#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)] #[serde(untagged)] pub enum OneTimeKey { /// A signed Curve25519 one-time key. diff --git a/crates/matrix-sdk-crypto/src/verification/mod.rs b/crates/matrix-sdk-crypto/src/verification/mod.rs index eb24d0178..496ca7188 100644 --- a/crates/matrix-sdk-crypto/src/verification/mod.rs +++ b/crates/matrix-sdk-crypto/src/verification/mod.rs @@ -376,7 +376,7 @@ impl Cancelled { } } -#[derive(Clone, Debug, Hash, PartialEq, PartialOrd)] +#[derive(Clone, Debug, Hash, PartialEq, Eq, PartialOrd)] pub enum FlowId { ToDevice(OwnedTransactionId), InRoom(OwnedRoomId, OwnedEventId), From f838b5fae8c8ef741a24b3d1aa86c709763da411 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Damir=20Jeli=C4=87?= Date: Mon, 23 May 2022 11:35:23 +0200 Subject: [PATCH 43/51] fix(base): Fix a clippy warning about temporary variables --- crates/matrix-sdk-base/src/rooms/normal.rs | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/crates/matrix-sdk-base/src/rooms/normal.rs b/crates/matrix-sdk-base/src/rooms/normal.rs index f54cbdfc6..512cce85c 100644 --- a/crates/matrix-sdk-base/src/rooms/normal.rs +++ b/crates/matrix-sdk-base/src/rooms/normal.rs @@ -177,7 +177,13 @@ impl Room { /// Get the avatar url of this room. pub fn avatar_url(&self) -> Option { - self.inner.read().unwrap().base_info.avatar.as_ref()?.as_original()?.content.url.clone() + self.inner + .read() + .unwrap() + .base_info + .avatar + .as_ref() + .and_then(|e| e.as_original().and_then(|e| e.content.url.clone())) } /// Get the canonical alias of this room. @@ -194,7 +200,13 @@ impl Room { /// It can also be redacted in current room versions, leaving only the /// `creator` field. pub fn create_content(&self) -> Option { - Some(self.inner.read().unwrap().base_info.create.as_ref()?.as_original()?.content.clone()) + self.inner + .read() + .unwrap() + .base_info + .create + .as_ref() + .and_then(|e| e.as_original().map(|e| e.content.clone())) } /// Is this room considered a direct message. From 453cae641bd9288552fde424d6025467ffaaeefe Mon Sep 17 00:00:00 2001 From: Jonas Platte Date: Mon, 23 May 2022 12:40:31 +0200 Subject: [PATCH 44/51] fix(docs): Remove history gh-pages branch This should drastically reduce the repository size. --- .github/workflows/docs.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/docs.yml b/.github/workflows/docs.yml index 546c760ed..1f0a6da2a 100644 --- a/.github/workflows/docs.yml +++ b/.github/workflows/docs.yml @@ -40,3 +40,4 @@ jobs: with: github_token: ${{ secrets.GITHUB_TOKEN }} publish_dir: ./target/doc/ + force_orphan: true From 24b71bf869d717d438e7ed43bb978aa9def1c2ba Mon Sep 17 00:00:00 2001 From: Johannes Becker Date: Mon, 23 May 2022 10:52:27 +0200 Subject: [PATCH 45/51] feat(appservice): Improve autojoin example --- .../examples/appservice_autojoin.rs | 21 ++++++++++++++++++- 1 file changed, 20 insertions(+), 1 deletion(-) diff --git a/crates/matrix-sdk-appservice/examples/appservice_autojoin.rs b/crates/matrix-sdk-appservice/examples/appservice_autojoin.rs index 1f7b1b71a..c654adfe4 100644 --- a/crates/matrix-sdk-appservice/examples/appservice_autojoin.rs +++ b/crates/matrix-sdk-appservice/examples/appservice_autojoin.rs @@ -8,9 +8,14 @@ use matrix_sdk_appservice::{ events::room::member::{MembershipState, OriginalSyncRoomMemberEvent}, UserId, }, + HttpError, }, AppService, AppServiceRegistration, Result, }; +use ruma::api::{ + client::{error::ErrorKind, uiaa::UiaaResponse}, + error::{FromHttpResponseError, ServerError}, +}; use tracing::trace; pub async fn handle_room_member( @@ -22,7 +27,9 @@ pub async fn handle_room_member( trace!("not an appservice user: {}", event.state_key); } else if let MembershipState::Invite = event.content.membership { let user_id = UserId::parse(event.state_key.as_str())?; - appservice.register_virtual_user(user_id.localpart()).await?; + if let Err(error) = appservice.register_virtual_user(user_id.localpart()).await { + error_if_user_not_in_use(error)?; + } let client = appservice.virtual_user_client(user_id.localpart()).await?; client.join_room_by_id(room.room_id()).await?; @@ -31,6 +38,17 @@ pub async fn handle_room_member( Ok(()) } +pub fn error_if_user_not_in_use(error: matrix_sdk_appservice::Error) -> Result<()> { + match error { + // If user is already in use that's OK. + matrix_sdk_appservice::Error::Matrix(matrix_sdk::Error::Http(HttpError::UiaaError( + FromHttpResponseError::Server(ServerError::Known(UiaaResponse::MatrixError(error))), + ))) if matches!(error.kind, ErrorKind::UserInUse) => Ok(()), + // In all other cases return with an error. + error => Err(error), + } +} + #[tokio::main] pub async fn main() -> Result<(), Box> { env::set_var("RUST_LOG", "matrix_sdk=debug,matrix_sdk_appservice=debug"); @@ -41,6 +59,7 @@ pub async fn main() -> Result<(), Box> { let registration = AppServiceRegistration::try_from_yaml_file("./tests/registration.yaml")?; let appservice = AppService::new(homeserver_url, server_name, registration).await?; + appservice.register_user_query(Box::new(|_, _| Box::pin(async { true }))).await; appservice .register_event_handler_context(appservice.clone())? .register_event_handler( From fa9c91fb0ea2ae823a4c05fc9f6759bdebeead4a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Damir=20Jeli=C4=87?= Date: Mon, 23 May 2022 16:25:39 +0200 Subject: [PATCH 46/51] fix(crypto-ffi): Add support to encrypt custom events --- crates/matrix-sdk-crypto-ffi/src/machine.rs | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/crates/matrix-sdk-crypto-ffi/src/machine.rs b/crates/matrix-sdk-crypto-ffi/src/machine.rs index fbd01ee4f..e87a971ba 100644 --- a/crates/matrix-sdk-crypto-ffi/src/machine.rs +++ b/crates/matrix-sdk-crypto-ffi/src/machine.rs @@ -32,7 +32,7 @@ use ruma::{ }, events::{ key::verification::VerificationMethod, room::encrypted::OriginalSyncRoomEncryptedEvent, - AnyMessageLikeEventContent, AnySyncMessageLikeEvent, EventContent, + AnySyncMessageLikeEvent, }, DeviceKeyAlgorithm, EventId, OwnedTransactionId, OwnedUserId, RoomId, UserId, }; @@ -518,12 +518,11 @@ impl OlmMachine { content: &str, ) -> Result { let room_id = RoomId::parse(room_id)?; - let content: Box = serde_json::from_str(content)?; + let content: Value = serde_json::from_str(content)?; - let content = AnyMessageLikeEventContent::from_parts(event_type, &content)?; let encrypted_content = self .runtime - .block_on(self.inner.encrypt_room_event(&room_id, content)) + .block_on(self.inner.encrypt_room_event_raw(&room_id, content, event_type)) .expect("Encrypting an event produced an error"); Ok(serde_json::to_string(&encrypted_content)?) From ec9ec2567f1d6e8784c60e9e43eee3ebd32e3615 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E4=BE=9D=E4=BA=91?= Date: Tue, 24 May 2022 14:43:02 +0800 Subject: [PATCH 47/51] feat: Add .resolve_room_alias() method to the Client --- crates/matrix-sdk-test/src/test_json/mod.rs | 11 +++++++ crates/matrix-sdk/src/client/mod.rs | 32 +++++++++++++++++++-- 2 files changed, 41 insertions(+), 2 deletions(-) diff --git a/crates/matrix-sdk-test/src/test_json/mod.rs b/crates/matrix-sdk-test/src/test_json/mod.rs index 78f440b2e..2f6c9cc5c 100644 --- a/crates/matrix-sdk-test/src/test_json/mod.rs +++ b/crates/matrix-sdk-test/src/test_json/mod.rs @@ -46,6 +46,17 @@ pub static DEVICES: Lazy = Lazy::new(|| { }) }); +pub static GET_ALIAS: Lazy = Lazy::new(|| { + json!({ + "room_id": "!lUbmUPdxdXxEQurqOs:example.net", + "servers": [ + "example.org", + "example.net", + "matrix.org", + ] + }) +}); + pub static WELL_KNOWN: Lazy = Lazy::new(|| { json!({ "m.homeserver": { diff --git a/crates/matrix-sdk/src/client/mod.rs b/crates/matrix-sdk/src/client/mod.rs index 1691ae2b4..d4ac15e7f 100644 --- a/crates/matrix-sdk/src/client/mod.rs +++ b/crates/matrix-sdk/src/client/mod.rs @@ -43,6 +43,7 @@ use ruma::{ api::{ client::{ account::{register, whoami}, + alias::get_alias, device::{delete_devices, get_devices}, directory::{get_public_rooms, get_public_rooms_filtered}, discovery::{ @@ -64,8 +65,8 @@ use ruma::{ assign, events::room::MediaSource, presence::PresenceState, - MxcUri, OwnedDeviceId, OwnedRoomId, OwnedServerName, OwnedUserId, RoomId, RoomOrAliasId, - ServerName, UInt, + MxcUri, OwnedDeviceId, OwnedRoomId, OwnedServerName, OwnedUserId, RoomAliasId, RoomId, + RoomOrAliasId, ServerName, UInt, }; use serde::de::DeserializeOwned; #[cfg(not(target_arch = "wasm32"))] @@ -608,6 +609,20 @@ impl Client { self.store().get_room(room_id).and_then(|room| room::Left::new(self.clone(), room)) } + /// Resolve a room alias to a room id and a list of servers which know + /// about it. + /// + /// # Arguments + /// + /// `room_alias` - The room alias to be resolved. + pub async fn resolve_room_alias( + &self, + room_alias: &RoomAliasId, + ) -> HttpResult { + let request = get_alias::v3::Request::new(room_alias); + self.send(request, None).await + } + /// Gets the homeserver’s supported login types. /// /// This should be the first step when trying to login so you can call the @@ -2533,6 +2548,19 @@ pub(crate) mod tests { assert!(client.devices().await.is_ok()); } + #[async_test] + async fn resolve_room_alias() { + let client = no_retry_test_client().await; + + let _m = mock("GET", "/_matrix/client/r0/directory/room/%23alias%3Aexample%2Eorg") + .with_status(200) + .with_body(test_json::GET_ALIAS.to_string()) + .create(); + + let alias = ruma::room_alias_id!("#alias:example.org"); + assert!(client.resolve_room_alias(alias).await.is_ok()); + } + #[async_test] async fn test_join_leave_room() { let room_id = room_id!("!SVkFJHzfwvuaIEawgC:localhost"); From 39e12a86ca73df9a50c1b8d0b9d52453078db781 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Damir=20Jeli=C4=87?= Date: Wed, 25 May 2022 12:08:20 +0200 Subject: [PATCH 48/51] chore(crypto): Bump vodozemac --- crates/matrix-sdk-crypto-ffi/Cargo.toml | 3 ++- crates/matrix-sdk-crypto-ffi/src/lib.rs | 6 ++++-- crates/matrix-sdk-crypto-ffi/src/olm.udl | 2 +- crates/matrix-sdk-crypto/Cargo.toml | 6 ++++-- crates/matrix-sdk-crypto/src/olm/account.rs | 3 +-- crates/matrix-sdk-qrcode/Cargo.toml | 3 ++- 6 files changed, 14 insertions(+), 9 deletions(-) diff --git a/crates/matrix-sdk-crypto-ffi/Cargo.toml b/crates/matrix-sdk-crypto-ffi/Cargo.toml index 6e7952137..70c23f35c 100644 --- a/crates/matrix-sdk-crypto-ffi/Cargo.toml +++ b/crates/matrix-sdk-crypto-ffi/Cargo.toml @@ -55,7 +55,8 @@ default_features = false features = ["rt-multi-thread"] [dependencies.vodozemac] -version = "0.2.0" +git = "https://github.com/matrix-org/vodozemac/" +rev = "d0e744287a14319c2a9148fef3747548c740fc36" [build-dependencies] uniffi_build = { version = "0.17.0", features = ["builtin-bindgen"] } diff --git a/crates/matrix-sdk-crypto-ffi/src/lib.rs b/crates/matrix-sdk-crypto-ffi/src/lib.rs index 7b3d166a4..6ca3080a6 100644 --- a/crates/matrix-sdk-crypto-ffi/src/lib.rs +++ b/crates/matrix-sdk-crypto-ffi/src/lib.rs @@ -48,7 +48,7 @@ pub struct MigrationData { /// The list of Megolm inbound group sessions. inbound_group_sessions: Vec, /// The Olm pickle key that was used to pickle all the Olm objects. - pickle_key: String, + pickle_key: Vec, /// The backup version that is currently active. backup_version: Option, // The backup recovery key, as a base58 encoded string. @@ -521,7 +521,9 @@ mod test { "backed_up":true } ], - "pickle_key":"\u{0011}$xJ_N8$>{\u{0005}iJoF03eBVt\u{000e}rUU\\,GYc7J", + "pickle_key": [17, 36, 120, 74, 95, 78, 56, 36, 62, 123, 5, 105, 74, + 111, 70, 48, 51, 101, 66, 86, 116, 14, 114, 85, 85, + 92, 44, 71, 89, 99, 55, 74], "backup_version":"3", "backup_recovery_key":"EsTHScmRV5oT1WBhe2mj2Gn3odeYantZ4NEk7L51p6L8hrmB", "cross_signing":{ diff --git a/crates/matrix-sdk-crypto-ffi/src/olm.udl b/crates/matrix-sdk-crypto-ffi/src/olm.udl index b7a1ba5f3..d9421f03e 100644 --- a/crates/matrix-sdk-crypto-ffi/src/olm.udl +++ b/crates/matrix-sdk-crypto-ffi/src/olm.udl @@ -451,7 +451,7 @@ dictionary MigrationData { sequence inbound_group_sessions; string? backup_version; string? backup_recovery_key; - string pickle_key; + sequence pickle_key; CrossSigningKeyExport cross_signing; sequence tracked_users; }; diff --git a/crates/matrix-sdk-crypto/Cargo.toml b/crates/matrix-sdk-crypto/Cargo.toml index 76c6fbf1a..66debbaed 100644 --- a/crates/matrix-sdk-crypto/Cargo.toml +++ b/crates/matrix-sdk-crypto/Cargo.toml @@ -53,7 +53,8 @@ version = "0.6.1" features = ["client-api-c", "js", "rand", "unstable-msc2676", "unstable-msc2677"] [target.'cfg(target_arch = "wasm32")'.dependencies.vodozemac] -version = "0.2.0" +git = "https://github.com/matrix-org/vodozemac/" +rev = "d0e744287a14319c2a9148fef3747548c740fc36" features = ["js"] [target.'cfg(not(target_arch = "wasm32"))'.dependencies.ruma] @@ -61,7 +62,8 @@ version = "0.6.1" features = ["client-api-c", "rand", "unstable-msc2676", "unstable-msc2677"] [target.'cfg(not(target_arch = "wasm32"))'.dependencies.vodozemac] -version = "0.2.0" +git = "https://github.com/matrix-org/vodozemac/" +rev = "d0e744287a14319c2a9148fef3747548c740fc36" [dev-dependencies] futures = { version = "0.3.21", default-features = false, features = ["executor"] } diff --git a/crates/matrix-sdk-crypto/src/olm/account.rs b/crates/matrix-sdk-crypto/src/olm/account.rs index 115d97bb6..3341f5020 100644 --- a/crates/matrix-sdk-crypto/src/olm/account.rs +++ b/crates/matrix-sdk-crypto/src/olm/account.rs @@ -1012,8 +1012,7 @@ impl ReadOnlyAccount { message: &PreKeyMessage, ) -> Result { let their_identity_key = Curve25519PublicKey::from_base64(their_identity_key)?; - let result = - self.inner.lock().await.create_inbound_session(&their_identity_key, message)?; + let result = self.inner.lock().await.create_inbound_session(their_identity_key, message)?; let now = SecondsSinceUnixEpoch::now(); let session_id = result.session.session_id(); diff --git a/crates/matrix-sdk-qrcode/Cargo.toml b/crates/matrix-sdk-qrcode/Cargo.toml index 417afaade..5cb5f1de7 100644 --- a/crates/matrix-sdk-qrcode/Cargo.toml +++ b/crates/matrix-sdk-qrcode/Cargo.toml @@ -29,4 +29,5 @@ ruma-common = "0.9.0" thiserror = "1.0.30" [dependencies.vodozemac] -version = "0.2.0" +git = "https://github.com/matrix-org/vodozemac/" +rev = "d0e744287a14319c2a9148fef3747548c740fc36" From 15ebc95cd0b6ee7e141323f50fa073f1fbfafa34 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Damir=20Jeli=C4=87?= Date: Wed, 25 May 2022 13:52:22 +0200 Subject: [PATCH 49/51] chore(qrcode): Add more missing Eq implementations --- crates/matrix-sdk-crypto/src/types/cross_signing_key.rs | 2 +- crates/matrix-sdk-crypto/src/types/device_keys.rs | 2 +- crates/matrix-sdk-qrcode/src/types.rs | 8 ++++---- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/crates/matrix-sdk-crypto/src/types/cross_signing_key.rs b/crates/matrix-sdk-crypto/src/types/cross_signing_key.rs index 753b09ff2..d1f74820c 100644 --- a/crates/matrix-sdk-crypto/src/types/cross_signing_key.rs +++ b/crates/matrix-sdk-crypto/src/types/cross_signing_key.rs @@ -77,7 +77,7 @@ impl CrossSigningKey { /// Currently cross signing keys support an ed25519 keypair. The keys transport /// format is a base64 encoded string, any unknown key type will be left as such /// a string. -#[derive(Clone, Debug, PartialEq)] +#[derive(Clone, Debug, PartialEq, Eq)] pub enum SigningKey { /// The ed25519 cross-signing key. Ed25519(Ed25519PublicKey), diff --git a/crates/matrix-sdk-crypto/src/types/device_keys.rs b/crates/matrix-sdk-crypto/src/types/device_keys.rs index aa558f153..6a60be23c 100644 --- a/crates/matrix-sdk-crypto/src/types/device_keys.rs +++ b/crates/matrix-sdk-crypto/src/types/device_keys.rs @@ -115,7 +115,7 @@ impl UnsignedDeviceInfo { /// Currently devices have a curve25519 and ed25519 keypair. The keys transport /// format is a base64 encoded string, any unknown key type will be left as such /// a string. -#[derive(Clone, Debug, PartialEq)] +#[derive(Clone, Debug, PartialEq, Eq)] pub enum DeviceKey { /// The curve25519 device key. Curve25519(Curve25519PublicKey), diff --git a/crates/matrix-sdk-qrcode/src/types.rs b/crates/matrix-sdk-qrcode/src/types.rs index a94e7f5d8..26dc4ef25 100644 --- a/crates/matrix-sdk-qrcode/src/types.rs +++ b/crates/matrix-sdk-qrcode/src/types.rs @@ -32,7 +32,7 @@ use crate::{ }; /// An enum representing the different modes a QR verification can be in. -#[derive(Clone, Debug, PartialEq)] +#[derive(Clone, Debug, PartialEq, Eq)] pub enum QrVerificationData { /// The QR verification is verifying another user Verification(VerificationData), @@ -375,7 +375,7 @@ impl QrVerificationData { /// /// This mode is used for verification between two users using their master /// cross signing keys. -#[derive(Clone, Debug, PartialEq)] +#[derive(Clone, Debug, PartialEq, Eq)] pub struct VerificationData { event_id: OwnedEventId, first_master_key: Ed25519PublicKey, @@ -474,7 +474,7 @@ impl From for QrVerificationData { /// This mode is used for verification between two devices of the same user /// where this device, that is creating this QR code, is trusting or owning /// the cross signing master key. -#[derive(Clone, Debug, PartialEq)] +#[derive(Clone, Debug, PartialEq, Eq)] pub struct SelfVerificationData { transaction_id: String, master_key: Ed25519PublicKey, @@ -577,7 +577,7 @@ impl From for QrVerificationData { /// This mode is used for verification between two devices of the same user /// where this device, that is creating this QR code, is not trusting the /// cross signing master key. -#[derive(Clone, Debug, PartialEq)] +#[derive(Clone, Debug, PartialEq, Eq)] pub struct SelfVerificationNoMasterKey { transaction_id: String, device_key: Ed25519PublicKey, From 28cd0c19e92dbf5a1c8ec0f13cf5aaca4b7473b9 Mon Sep 17 00:00:00 2001 From: Brandon Lau Date: Thu, 26 May 2022 12:01:45 -0700 Subject: [PATCH 50/51] fix(crypto-ffi): make crypto-ffi generate a static library for iOS clients --- crates/matrix-sdk-crypto-ffi/Cargo.toml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/crates/matrix-sdk-crypto-ffi/Cargo.toml b/crates/matrix-sdk-crypto-ffi/Cargo.toml index 70c23f35c..b18573963 100644 --- a/crates/matrix-sdk-crypto-ffi/Cargo.toml +++ b/crates/matrix-sdk-crypto-ffi/Cargo.toml @@ -10,8 +10,8 @@ license = "Apache-2.0" publish = false [lib] -crate-type = ["cdylib", "lib"] -name = "matrix_crypto" +crate-type = ["cdylib", "staticlib"] +name = "matrix_crypto_ffi" [dependencies] anyhow = "1.0.57" From e5390e18dedeacadeaadc88520169bcf3aa81e32 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Damir=20Jeli=C4=87?= Date: Thu, 26 May 2022 11:53:45 +0200 Subject: [PATCH 51/51] refactor(crypto): Introduce a SignJson trait This patch collects our json signing logic into a single place. --- crates/matrix-sdk-crypto/src/olm/account.rs | 35 ++++++------- .../matrix-sdk-crypto/src/olm/signing/mod.rs | 27 ++++++++-- .../src/olm/signing/pk_signing.rs | 51 ++++++++----------- crates/matrix-sdk-crypto/src/olm/utility.rs | 30 +++++++++++ 4 files changed, 89 insertions(+), 54 deletions(-) diff --git a/crates/matrix-sdk-crypto/src/olm/account.rs b/crates/matrix-sdk-crypto/src/olm/account.rs index 3341f5020..bea1c9a85 100644 --- a/crates/matrix-sdk-crypto/src/olm/account.rs +++ b/crates/matrix-sdk-crypto/src/olm/account.rs @@ -35,7 +35,7 @@ use ruma::{ }, AnyToDeviceEvent, OlmV1Keys, }, - serde::{CanonicalJsonValue, Raw}, + serde::Raw, DeviceId, DeviceKeyAlgorithm, DeviceKeyId, EventEncryptionAlgorithm, OwnedDeviceId, OwnedDeviceKeyId, OwnedUserId, RoomId, SecondsSinceUnixEpoch, UInt, UserId, }; @@ -49,8 +49,8 @@ use vodozemac::{ }; use super::{ - EncryptionSettings, InboundGroupSession, OutboundGroupSession, PrivateCrossSigningIdentity, - Session, + utility::SignJson, EncryptionSettings, InboundGroupSession, OutboundGroupSession, + PrivateCrossSigningIdentity, Session, }; use crate::{ error::{EventError, OlmResult, SessionCreationError}, @@ -752,10 +752,14 @@ impl ReadOnlyAccount { // get signed. let json_device_keys = serde_json::to_value(&device_keys).expect("device key is always safe to serialize"); + let signature = self + .sign_json(json_device_keys) + .await + .expect("Newly created device keys can always be signed"); device_keys.signatures.entry(self.user_id().to_owned()).or_default().insert( DeviceKeyId::from_parts(DeviceKeyAlgorithm::Ed25519, &self.device_id), - self.sign_json(json_device_keys).await.to_base64(), + signature.to_base64(), ); device_keys @@ -773,7 +777,7 @@ impl ReadOnlyAccount { &self, cross_signing_key: &mut CrossSigningKey, ) -> Result<(), SignatureError> { - let signature = self.sign_json(serde_json::to_value(&cross_signing_key)?).await; + let signature = self.sign_json(serde_json::to_value(&cross_signing_key)?).await?; cross_signing_key.signatures.entry(self.user_id().to_owned()).or_default().insert( DeviceKeyId::from_parts(DeviceKeyAlgorithm::Ed25519, self.device_id()), @@ -809,19 +813,8 @@ impl ReadOnlyAccount { /// /// * `json` - The value that should be converted into a canonical JSON /// string. - /// - /// # Panic - /// - /// Panics if the json value can't be serialized. - pub async fn sign_json(&self, mut json: Value) -> Ed25519Signature { - let object = json.as_object_mut().expect("Canonical json value isn't an object"); - object.remove("unsigned"); - object.remove("signatures"); - - let canonical_json: CanonicalJsonValue = - json.try_into().expect("Can't canonicalize the json value"); - - self.sign(&canonical_json.to_string()).await + pub async fn sign_json(&self, json: Value) -> Result { + self.inner.lock().await.sign_json(json) } /// Generate, sign and prepare one-time keys to be uploaded. @@ -885,8 +878,10 @@ impl ReadOnlyAccount { SignedKey::new(key.to_owned()) }; - let signature = - self.sign_json(serde_json::to_value(&key).expect("Can't serialize a signed key")).await; + let signature = self + .sign_json(serde_json::to_value(&key).expect("Can't serialize a signed key")) + .await + .expect("Newly created one-time keys can always be signed"); let signatures = BTreeMap::from([( self.user_id().to_owned(), diff --git a/crates/matrix-sdk-crypto/src/olm/signing/mod.rs b/crates/matrix-sdk-crypto/src/olm/signing/mod.rs index 9a538653b..501b5f134 100644 --- a/crates/matrix-sdk-crypto/src/olm/signing/mod.rs +++ b/crates/matrix-sdk-crypto/src/olm/signing/mod.rs @@ -651,13 +651,16 @@ impl PrivateCrossSigningIdentity { #[cfg(test)] mod tests { + use std::collections::BTreeMap; + use matrix_sdk_test::async_test; - use ruma::{device_id, user_id, UserId}; + use ruma::{device_id, user_id, DeviceKeyAlgorithm, DeviceKeyId, UserId}; + use serde_json::json; use super::{PrivateCrossSigningIdentity, Signing}; use crate::{ identities::{ReadOnlyDevice, ReadOnlyUserIdentity}, - olm::ReadOnlyAccount, + olm::{utility::SignJson, ReadOnlyAccount}, }; fn user_id() -> &'static UserId { @@ -667,11 +670,25 @@ mod tests { #[test] fn signature_verification() { let signing = Signing::new(); + let user_id = user_id(); + let key_id = DeviceKeyId::from_parts(DeviceKeyAlgorithm::Ed25519, "DEVICEID".into()); - let message = "Hello world"; + let json = json!({ + "hello": "world" + }); - let signature = signing.sign(message); - assert!(signing.verify(message, &signature).is_ok()); + let signature = + signing.sign_json(json).expect("We should be able to sign a simple json object"); + let signatures = + BTreeMap::from([(user_id, BTreeMap::from([(key_id.clone(), signature.to_base64())]))]); + + let mut json = json!({ + "hello": "world", + "signatures": signatures, + + }); + + assert!(signing.verify_json(user_id, &key_id, &mut json).is_ok()); } #[test] diff --git a/crates/matrix-sdk-crypto/src/olm/signing/pk_signing.rs b/crates/matrix-sdk-crypto/src/olm/signing/pk_signing.rs index 1f7b137ba..5e02da1be 100644 --- a/crates/matrix-sdk-crypto/src/olm/signing/pk_signing.rs +++ b/crates/matrix-sdk-crypto/src/olm/signing/pk_signing.rs @@ -12,11 +12,9 @@ // See the License for the specific language governing permissions and // limitations under the License. -use std::{collections::BTreeMap, convert::TryInto}; +use std::collections::BTreeMap; -use ruma::{ - encryption::KeyUsage, serde::CanonicalJsonValue, DeviceKeyAlgorithm, DeviceKeyId, OwnedUserId, -}; +use ruma::{encryption::KeyUsage, DeviceKeyAlgorithm, DeviceKeyId, OwnedUserId}; use serde::{Deserialize, Serialize}; use serde_json::{Error as JsonError, Value}; use thiserror::Error; @@ -25,6 +23,7 @@ use vodozemac::{Ed25519PublicKey, Ed25519SecretKey, Ed25519Signature, KeyError}; use crate::{ error::SignatureError, identities::{MasterPubkey, SelfSigningPubkey, UserSigningPubkey}, + olm::utility::SignJson, types::{CrossSigningKey, CrossSigningKeySignatures, DeviceKeys}, utilities::{encode, DecodeError}, ReadOnlyUserIdentity, @@ -64,6 +63,12 @@ impl PartialEq for Signing { } } +impl SignJson for Signing { + fn sign_json(&self, value: Value) -> Result { + self.inner.sign_json(value) + } +} + #[derive(PartialEq, Debug)] pub struct MasterSigning { pub inner: Signing, @@ -215,12 +220,9 @@ impl SelfSigning { Ok(Self { inner, public_key }) } - pub fn sign_device_helper(&self, value: Value) -> Result { - self.inner.sign_json(value) - } - pub fn sign_device(&self, device_keys: &mut DeviceKeys) -> Result<(), SignatureError> { - let signature = self.sign_device_helper(serde_json::to_value(&device_keys)?)?; + let serialized = serde_json::to_value(&device_keys)?; + let signature = self.inner.sign_json(serialized)?; device_keys.signatures.entry(self.public_key.user_id().to_owned()).or_default().insert( DeviceKeyId::from_parts( @@ -311,27 +313,18 @@ impl Signing { CrossSigningKey::new(user_id, vec![usage], keys, BTreeMap::new()) } - #[cfg(test)] - pub fn verify( - &self, - message: &str, - signature: &Ed25519Signature, - ) -> Result<(), SignatureError> { - Ok(self.public_key.verify(message.as_bytes(), signature)?) - } - - pub fn sign_json(&self, mut json: Value) -> Result { - let json_object = json.as_object_mut().ok_or(SignatureError::NotAnObject)?; - let _ = json_object.remove("signatures"); - let _ = json_object.remove("unsigned"); - - let canonical_json: CanonicalJsonValue = - json.try_into().expect("Can't canonicalize the json value"); - - Ok(self.sign(&canonical_json.to_string())) - } - pub fn sign(&self, message: &str) -> Ed25519Signature { self.inner.sign(message.as_bytes()) } + + #[cfg(test)] + pub fn verify_json( + &self, + user_id: &ruma::UserId, + key_id: &DeviceKeyId, + message: &mut Value, + ) -> Result<(), SignatureError> { + use crate::olm::VerifyJson; + self.public_key.verify_json(user_id, key_id, message) + } } diff --git a/crates/matrix-sdk-crypto/src/olm/utility.rs b/crates/matrix-sdk-crypto/src/olm/utility.rs index a95ec607f..76c5ad6b6 100644 --- a/crates/matrix-sdk-crypto/src/olm/utility.rs +++ b/crates/matrix-sdk-crypto/src/olm/utility.rs @@ -16,9 +16,39 @@ use std::convert::TryInto; use ruma::{serde::CanonicalJsonValue, DeviceKeyAlgorithm, DeviceKeyId, UserId}; use serde_json::Value; +use vodozemac::{olm::Account, Ed25519SecretKey, Ed25519Signature}; use crate::error::SignatureError; +pub trait SignJson { + fn sign_json(&self, value: Value) -> Result; + + fn to_signable_json(mut value: Value) -> Result { + let json_object = value.as_object_mut().ok_or(SignatureError::NotAnObject)?; + let _ = json_object.remove("signatures"); + let _ = json_object.remove("unsigned"); + + let canonical_json: CanonicalJsonValue = value.try_into().unwrap(); + Ok(canonical_json.to_string()) + } +} + +impl SignJson for Account { + fn sign_json(&self, value: Value) -> Result { + let serialized = Self::to_signable_json(value)?; + + Ok(self.sign(serialized.as_ref())) + } +} + +impl SignJson for Ed25519SecretKey { + fn sign_json(&self, value: Value) -> Result { + let serialized = Self::to_signable_json(value)?; + + Ok(self.sign(serialized.as_ref())) + } +} + pub trait VerifyJson { /// Verify a signed JSON object. ///