From 05826264c0eb56a25b6972223e35164c5a320d57 Mon Sep 17 00:00:00 2001 From: cameronvoell Date: Wed, 24 Jul 2024 07:00:49 -0700 Subject: [PATCH] adds newGroupCustomPermissions function --- Package.resolved | 4 +- Package.swift | 2 +- Sources/XMTPiOS/Conversations.swift | 50 +++++++++++-- Sources/XMTPiOS/Group.swift | 2 +- Sources/XMTPiOS/Mls/PermissionPolicySet.swift | 75 +++++++++++-------- Tests/XMTPTests/GroupPermissionsTests.swift | 54 +++++++++++++ XMTP.podspec | 4 +- 7 files changed, 146 insertions(+), 45 deletions(-) diff --git a/Package.resolved b/Package.resolved index a649204d..ea392581 100644 --- a/Package.resolved +++ b/Package.resolved @@ -41,8 +41,8 @@ "kind" : "remoteSourceControl", "location" : "https://github.com/xmtp/libxmtp-swift.git", "state" : { - "revision" : "b19830dc02d03deea89e9fad3b3ed22e102f86f2", - "version" : "0.5.4-beta3" + "revision" : "1b4900330822a7fbb143cdf67fcede557e57dbe8", + "version" : "0.5.6-beta1" } }, { diff --git a/Package.swift b/Package.swift index db4e55d3..c9532f4b 100644 --- a/Package.swift +++ b/Package.swift @@ -25,7 +25,7 @@ let package = Package( .package(url: "https://github.com/1024jp/GzipSwift", from: "5.2.0"), .package(url: "https://github.com/bufbuild/connect-swift", exact: "0.12.0"), .package(url: "https://github.com/apple/swift-docc-plugin.git", from: "1.0.0"), - .package(url: "https://github.com/xmtp/libxmtp-swift.git", exact: "0.5.6-beta0"), + .package(url: "https://github.com/xmtp/libxmtp-swift.git", exact: "0.5.6-beta1"), ], targets: [ // Targets are the basic building blocks of a package. A target can define a module or a test suite. diff --git a/Sources/XMTPiOS/Conversations.swift b/Sources/XMTPiOS/Conversations.swift index 6f181cc9..e1b916ec 100644 --- a/Sources/XMTPiOS/Conversations.swift +++ b/Sources/XMTPiOS/Conversations.swift @@ -141,13 +141,50 @@ public actor Conversations { } } } - - public func newGroup(with addresses: [String], - permissions: GroupPermissionPreconfiguration = .allMembers, + + public func newGroup(with addresses: [String], + permissions: GroupPermissionPreconfiguration = .allMembers, + name: String = "", + imageUrlSquare: String = "", + description: String = "", + pinnedFrameUrl: String = "" + ) async throws -> Group { + return try await newGroupInternal( + with: addresses, + permissions: GroupPermissionPreconfiguration.toFfiGroupPermissionOptions(option: permissions), + name: name, + imageUrlSquare: imageUrlSquare, + description: description, + pinnedFrameUrl: pinnedFrameUrl, + permissionPolicySet: nil + ) + } + + public func newGroupCustomPermissions(with addresses: [String], + permissionPolicySet: PermissionPolicySet, + name: String = "", + imageUrlSquare: String = "", + description: String = "", + pinnedFrameUrl: String = "" + ) async throws -> Group { + return try await newGroupInternal( + with: addresses, + permissions: FfiGroupPermissionsOptions.customPolicy, + name: name, + imageUrlSquare: imageUrlSquare, + description: description, + pinnedFrameUrl: pinnedFrameUrl, + permissionPolicySet: PermissionPolicySet.toFfiPermissionPolicySet(permissionPolicySet) + ) + } + + private func newGroupInternal(with addresses: [String], + permissions: FfiGroupPermissionsOptions = .allMembers, name: String = "", imageUrlSquare: String = "", description: String = "", - pinnedFrameUrl: String = "" + pinnedFrameUrl: String = "", + permissionPolicySet: FfiPermissionPolicySet? = nil ) async throws -> Group { guard let v3Client = client.v3Client else { throw GroupError.alphaMLSNotEnabled @@ -177,11 +214,12 @@ public actor Conversations { throw GroupError.memberNotRegistered(erroredAddresses) } let group = try await v3Client.conversations().createGroup(accountAddresses: addresses, - opts: FfiCreateGroupOptions(permissions: GroupPermissionPreconfiguration.toFfiGroupPermissionOptions(option: permissions), + opts: FfiCreateGroupOptions(permissions: permissions, groupName: name, groupImageUrlSquare: imageUrlSquare, groupDescription: description, - groupPinnedFrameUrl: pinnedFrameUrl + groupPinnedFrameUrl: pinnedFrameUrl, + customPermissionPolicySet: permissionPolicySet )).fromFFI(client: client) try await client.contacts.allowGroups(groupIds: [group.id]) return group diff --git a/Sources/XMTPiOS/Group.swift b/Sources/XMTPiOS/Group.swift index a7e476a0..028f4bc6 100644 --- a/Sources/XMTPiOS/Group.swift +++ b/Sources/XMTPiOS/Group.swift @@ -100,7 +100,7 @@ public struct Group: Identifiable, Equatable, Hashable { } public func permissionPolicySet() throws -> PermissionPolicySet { - return PermissionPolicySet(ffiPermissionPolicySet: try permissions().policySet()) + return PermissionPolicySet.fromFfiPermissionPolicySet(try permissions().policySet()) } public func creatorInboxId() throws -> String { diff --git a/Sources/XMTPiOS/Mls/PermissionPolicySet.swift b/Sources/XMTPiOS/Mls/PermissionPolicySet.swift index 86a78de3..45ff8742 100644 --- a/Sources/XMTPiOS/Mls/PermissionPolicySet.swift +++ b/Sources/XMTPiOS/Mls/PermissionPolicySet.swift @@ -54,41 +54,50 @@ public enum GroupPermissionPreconfiguration { } public class PermissionPolicySet { - let ffiPermissionPolicySet: FfiPermissionPolicySet - - init(ffiPermissionPolicySet: FfiPermissionPolicySet) { - self.ffiPermissionPolicySet = ffiPermissionPolicySet - } - - public var addMemberPolicy: PermissionOption { - return PermissionOption.fromFfiPermissionPolicy(ffiPolicy: ffiPermissionPolicySet.addMemberPolicy) - } - - public var removeMemberPolicy: PermissionOption { - return PermissionOption.fromFfiPermissionPolicy(ffiPolicy: ffiPermissionPolicySet.removeMemberPolicy) - } - - public var addAdminPolicy: PermissionOption { - return PermissionOption.fromFfiPermissionPolicy(ffiPolicy: ffiPermissionPolicySet.addAdminPolicy) - } - - public var removeAdminPolicy: PermissionOption { - return PermissionOption.fromFfiPermissionPolicy(ffiPolicy: ffiPermissionPolicySet.removeAdminPolicy) - } - - public var updateGroupNamePolicy: PermissionOption { - return PermissionOption.fromFfiPermissionPolicy(ffiPolicy: ffiPermissionPolicySet.updateGroupNamePolicy) - } - - public var updateGroupDescriptionPolicy: PermissionOption { - return PermissionOption.fromFfiPermissionPolicy(ffiPolicy: ffiPermissionPolicySet.updateGroupDescriptionPolicy) + var addMemberPolicy: PermissionOption + var removeMemberPolicy: PermissionOption + var addAdminPolicy: PermissionOption + var removeAdminPolicy: PermissionOption + var updateGroupNamePolicy: PermissionOption + var updateGroupDescriptionPolicy: PermissionOption + var updateGroupImagePolicy: PermissionOption + var updateGroupPinnedFrameUrlPolicy: PermissionOption + + init(addMemberPolicy: PermissionOption, removeMemberPolicy: PermissionOption, addAdminPolicy: PermissionOption, removeAdminPolicy: PermissionOption, updateGroupNamePolicy: PermissionOption, updateGroupDescriptionPolicy: PermissionOption, updateGroupImagePolicy: PermissionOption, updateGroupPinnedFrameUrlPolicy: PermissionOption) { + self.addMemberPolicy = addMemberPolicy + self.removeMemberPolicy = removeMemberPolicy + self.addAdminPolicy = addAdminPolicy + self.removeAdminPolicy = removeAdminPolicy + self.updateGroupNamePolicy = updateGroupNamePolicy + self.updateGroupDescriptionPolicy = updateGroupDescriptionPolicy + self.updateGroupImagePolicy = updateGroupImagePolicy + self.updateGroupPinnedFrameUrlPolicy = updateGroupPinnedFrameUrlPolicy } - - public var updateGroupImagePolicy: PermissionOption { - return PermissionOption.fromFfiPermissionPolicy(ffiPolicy: ffiPermissionPolicySet.updateGroupImageUrlSquarePolicy) + + static func toFfiPermissionPolicySet(_ permissionPolicySet: PermissionPolicySet) -> FfiPermissionPolicySet { + return FfiPermissionPolicySet( + addMemberPolicy: PermissionOption.toFfiPermissionPolicy(option: permissionPolicySet.addMemberPolicy), + removeMemberPolicy: PermissionOption.toFfiPermissionPolicy(option: permissionPolicySet.removeMemberPolicy), + addAdminPolicy: PermissionOption.toFfiPermissionPolicy(option: permissionPolicySet.addAdminPolicy), + removeAdminPolicy: PermissionOption.toFfiPermissionPolicy(option: permissionPolicySet.removeAdminPolicy), + updateGroupNamePolicy: PermissionOption.toFfiPermissionPolicy(option: permissionPolicySet.updateGroupNamePolicy), + updateGroupDescriptionPolicy: PermissionOption.toFfiPermissionPolicy(option: permissionPolicySet.updateGroupDescriptionPolicy), + updateGroupImageUrlSquarePolicy: PermissionOption.toFfiPermissionPolicy(option: permissionPolicySet.updateGroupImagePolicy), + updateGroupPinnedFrameUrlPolicy: PermissionOption.toFfiPermissionPolicy(option: permissionPolicySet.updateGroupPinnedFrameUrlPolicy) + ) } - public var updateGroupPinnedFrameUrlPolicy: PermissionOption { - return PermissionOption.fromFfiPermissionPolicy(ffiPolicy: ffiPermissionPolicySet.updateGroupPinnedFrameUrlPolicy) + static func fromFfiPermissionPolicySet(_ ffiPermissionPolicySet: FfiPermissionPolicySet) -> PermissionPolicySet { + return PermissionPolicySet( + addMemberPolicy: PermissionOption.fromFfiPermissionPolicy(ffiPolicy: ffiPermissionPolicySet.addMemberPolicy), + removeMemberPolicy: PermissionOption.fromFfiPermissionPolicy(ffiPolicy: ffiPermissionPolicySet.removeMemberPolicy), + addAdminPolicy: PermissionOption.fromFfiPermissionPolicy(ffiPolicy: ffiPermissionPolicySet.addAdminPolicy), + removeAdminPolicy: PermissionOption.fromFfiPermissionPolicy(ffiPolicy: ffiPermissionPolicySet.removeAdminPolicy), + updateGroupNamePolicy: PermissionOption.fromFfiPermissionPolicy(ffiPolicy: ffiPermissionPolicySet.updateGroupNamePolicy), + updateGroupDescriptionPolicy: PermissionOption.fromFfiPermissionPolicy(ffiPolicy: ffiPermissionPolicySet.updateGroupDescriptionPolicy), + updateGroupImagePolicy: PermissionOption.fromFfiPermissionPolicy(ffiPolicy: ffiPermissionPolicySet.updateGroupImageUrlSquarePolicy), + updateGroupPinnedFrameUrlPolicy: PermissionOption.fromFfiPermissionPolicy(ffiPolicy: ffiPermissionPolicySet.updateGroupPinnedFrameUrlPolicy) + ) } } + diff --git a/Tests/XMTPTests/GroupPermissionsTests.swift b/Tests/XMTPTests/GroupPermissionsTests.swift index 370458a3..0c320b4c 100644 --- a/Tests/XMTPTests/GroupPermissionsTests.swift +++ b/Tests/XMTPTests/GroupPermissionsTests.swift @@ -321,4 +321,58 @@ class GroupPermissionTests: XCTestCase { XCTAssertEqual(try bobGroup.groupPinnedFrameUrl(), "https://foo/barz.com") XCTAssertEqual(try aliceGroup.groupPinnedFrameUrl(), "https://foo/barz.com") } + + func testCanCreateGroupWithCustomPermissions() async throws { + let fixtures = try await localFixtures() + let permissionPolicySet = PermissionPolicySet( + addMemberPolicy: PermissionOption.admin, + removeMemberPolicy: PermissionOption.deny, + addAdminPolicy: PermissionOption.admin, + removeAdminPolicy: PermissionOption.superAdmin, + updateGroupNamePolicy: PermissionOption.admin, + updateGroupDescriptionPolicy: PermissionOption.allow, + updateGroupImagePolicy: PermissionOption.admin, + updateGroupPinnedFrameUrlPolicy: PermissionOption.deny + ) + let bobGroup = try await fixtures.bobClient.conversations.newGroupCustomPermissions( + with: [fixtures.alice.walletAddress, fixtures.caro.walletAddress], + permissionPolicySet: permissionPolicySet, + pinnedFrameUrl: "initial url" + ) + + try await fixtures.aliceClient.conversations.sync() + let aliceGroup = try await fixtures.aliceClient.conversations.groups().first! + + let alicePermissionSet = try aliceGroup.permissionPolicySet() + XCTAssert(alicePermissionSet.addMemberPolicy == PermissionOption.admin) + XCTAssert(alicePermissionSet.removeMemberPolicy == PermissionOption.deny) + XCTAssert(alicePermissionSet.addAdminPolicy == PermissionOption.admin) + XCTAssert(alicePermissionSet.removeAdminPolicy == PermissionOption.superAdmin) + XCTAssert(alicePermissionSet.updateGroupNamePolicy == PermissionOption.admin) + XCTAssert(alicePermissionSet.updateGroupDescriptionPolicy == PermissionOption.allow) + XCTAssert(alicePermissionSet.updateGroupImagePolicy == PermissionOption.admin) + XCTAssert(alicePermissionSet.updateGroupPinnedFrameUrlPolicy == PermissionOption.deny) + } + + func testCreateGroupWithInvalidPermissionsFails() async throws { + let fixtures = try await localFixtures() + // Add / remove admin can not be set to "allow" + let permissionPolicySetInvalid = PermissionPolicySet( + addMemberPolicy: PermissionOption.admin, + removeMemberPolicy: PermissionOption.deny, + addAdminPolicy: PermissionOption.allow, + removeAdminPolicy: PermissionOption.superAdmin, + updateGroupNamePolicy: PermissionOption.admin, + updateGroupDescriptionPolicy: PermissionOption.allow, + updateGroupImagePolicy: PermissionOption.admin, + updateGroupPinnedFrameUrlPolicy: PermissionOption.deny + ) + await assertThrowsAsyncError( + try await fixtures.bobClient.conversations.newGroupCustomPermissions( + with: [fixtures.alice.walletAddress, fixtures.caro.walletAddress], + permissionPolicySet: permissionPolicySetInvalid, + pinnedFrameUrl: "initial url" + ) + ) + } } diff --git a/XMTP.podspec b/XMTP.podspec index c25fb5f0..0a7f56f7 100644 --- a/XMTP.podspec +++ b/XMTP.podspec @@ -16,7 +16,7 @@ Pod::Spec.new do |spec| # spec.name = "XMTP" - spec.version = "0.13.8" + spec.version = "0.13.9" spec.summary = "XMTP SDK Cocoapod" # This description is used to generate tags and improve search results. @@ -44,5 +44,5 @@ Pod::Spec.new do |spec| spec.dependency "web3.swift" spec.dependency "GzipSwift" spec.dependency "Connect-Swift", "= 0.12.0" - spec.dependency 'LibXMTP', '= 0.5.6-beta0' + spec.dependency 'LibXMTP', '= 0.5.6-beta1' end