Skip to content

Commit

Permalink
add swift code for newGroupCustomPermissions
Browse files Browse the repository at this point in the history
  • Loading branch information
cameronvoell committed Jul 24, 2024
1 parent 44e224c commit f17acb7
Show file tree
Hide file tree
Showing 6 changed files with 118 additions and 81 deletions.
8 changes: 4 additions & 4 deletions example/ios/Podfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -449,7 +449,7 @@ PODS:
- GenericJSON (~> 2.0)
- Logging (~> 1.0.0)
- secp256k1.swift (~> 0.1)
- XMTP (0.13.9):
- XMTP (0.13.10):
- Connect-Swift (= 0.12.0)
- GzipSwift
- LibXMTP (= 0.5.6-beta1)
Expand All @@ -458,7 +458,7 @@ PODS:
- ExpoModulesCore
- MessagePacker
- secp256k1.swift
- XMTP (= 0.13.9)
- XMTP (= 0.13.10)
- Yoga (1.14.0)

DEPENDENCIES:
Expand Down Expand Up @@ -763,8 +763,8 @@ SPEC CHECKSUMS:
secp256k1.swift: a7e7a214f6db6ce5db32cc6b2b45e5c4dd633634
SwiftProtobuf: 407a385e97fd206c4fbe880cc84123989167e0d1
web3.swift: 2263d1e12e121b2c42ffb63a5a7beb1acaf33959
XMTP: 518a21ff9d2b7235dbf8d79fdc388a576c94f1e2
XMTPReactNative: e3803ae32fa0dd849c2265b8d9109f682840ee24
XMTP: 19f9c073262c44fbe98489208cda7a44d079064d
XMTPReactNative: 296aaa356ea5c67c98779665bcb5e1cad140d135
Yoga: e71803b4c1fff832ccf9b92541e00f9b873119b9

PODFILE CHECKSUM: 95d6ace79946933ecf80684613842ee553dd76a2
Expand Down
30 changes: 17 additions & 13 deletions example/src/tests/groupPermissionsTests.ts
Original file line number Diff line number Diff line change
Expand Up @@ -59,9 +59,7 @@ test('super admin can add a new admin', async () => {
const boGroup = (await bo.conversations.listGroups())[0]
try {
await boGroup.addAdmin(caro.inboxId)
throw new Error(
'Expected exception when non-super admin attempts to add an admin.'
)
return false
// eslint-disable-next-line @typescript-eslint/no-unused-vars
} catch (error) {
// expected
Expand Down Expand Up @@ -141,6 +139,7 @@ test('in admin only group, members can update group name once they are an admin'
const boGroup = (await bo.conversations.listGroups())[0]
try {
await boGroup.updateGroupName("bo's group")
return false
// eslint-disable-next-line @typescript-eslint/no-unused-vars
} catch (error) {
// expected
Expand Down Expand Up @@ -216,6 +215,7 @@ test('in admin only group, members can not update group name after admin status
// Bo can no longer update the group name
try {
await boGroup.updateGroupName('new name 2')
return false
// eslint-disable-next-line @typescript-eslint/no-unused-vars
} catch (error) {
// expected error
Expand Down Expand Up @@ -258,6 +258,7 @@ test('can not remove a super admin from a group', async () => {
// Bo should not be able to remove alix from the group
try {
await boGroup.removeMembersByInboxId([alix.inboxId])
return false
// eslint-disable-next-line @typescript-eslint/no-unused-vars
} catch (error) {
// expected
Expand All @@ -284,6 +285,7 @@ test('can not remove a super admin from a group', async () => {
// Verify bo can not remove alix bc alix is a super admin
try {
await boGroup.removeMembersByInboxId([alix.inboxId])
return false
// eslint-disable-next-line @typescript-eslint/no-unused-vars
} catch (error) {
// expected
Expand Down Expand Up @@ -335,6 +337,7 @@ test('can commit after invalid permissions commit', async () => {
)
try {
await alixGroup.addAdmin(alix.inboxId)
return false
// eslint-disable-next-line @typescript-eslint/no-unused-vars
} catch (error) {
// expected
Expand Down Expand Up @@ -376,7 +379,7 @@ test('group with All Members policy has remove function that is admin only', asy
// Verify that Alix cannot remove a member
try {
await alixGroup.removeMembers([caro.address])
assert(false, 'Alix should not be able to remove a member')
return false
// eslint-disable-next-line @typescript-eslint/no-unused-vars
} catch (error) {
// expected
Expand Down Expand Up @@ -429,8 +432,8 @@ test('can update group permissions', async () => {
await alix.conversations.syncGroups()
const alixGroup = (await alix.conversations.listGroups())[0]
try {
await alixGroup.updateGroupDescription('new description')
assert(false, 'Alix should not be able to update the group description')
await alixGroup.updateGroupDescription('new description 2')
return false
// eslint-disable-next-line @typescript-eslint/no-unused-vars
} catch (error) {
// expected
Expand All @@ -439,7 +442,7 @@ test('can update group permissions', async () => {
// Verify that alix can not update permissions
try {
await alixGroup.updateGroupDescriptionPermission('allow')
assert(false, 'Alix should not be able to update the group name permission')
return false
// eslint-disable-next-line @typescript-eslint/no-unused-vars
} catch (error) {
// expected
Expand Down Expand Up @@ -480,7 +483,7 @@ test('can update group pinned frame', async () => {
const alixGroup = (await alix.conversations.listGroups())[0]
try {
await alixGroup.updateGroupPinnedFrameUrl('new pinned frame')
assert(false, 'Alix should not be able to update the group pinned frame')
return false
// eslint-disable-next-line @typescript-eslint/no-unused-vars
} catch (error) {
// expected
Expand Down Expand Up @@ -582,7 +585,7 @@ test('can create a group with custom permissions', async () => {
// Verify that bo can not update the pinned frame even though they are a super admin
try {
await boGroup.updateGroupPinnedFrameUrl('new pinned frame')
assert(false, 'Bo should not be able to update the group pinned frame')
return false
// eslint-disable-next-line @typescript-eslint/no-unused-vars
} catch (error) {
// expected
Expand All @@ -599,7 +602,7 @@ test('can create a group with custom permissions', async () => {
// Verify that alix can not update the group name
try {
await alixGroup.updateGroupName('new name')
assert(false, 'Alix should not be able to update the group name')
return false
// eslint-disable-next-line @typescript-eslint/no-unused-vars
} catch (error) {
// expected
Expand All @@ -612,7 +615,7 @@ test('creating a group with invalid permissions should fail', async () => {
// Create clients
const [alix, bo, caro] = await createClients(3)

// Add/Remove admin must be admin or super admin
// Add/Remove admin can not be set to allow
const customPermissionsPolicySet: PermissionPolicySet = {
addMemberPolicy: 'allow',
removeMemberPolicy: 'deny',
Expand All @@ -630,10 +633,11 @@ test('creating a group with invalid permissions should fail', async () => {
[alix.address, caro.address],
customPermissionsPolicySet
)
assert(false, 'Group creation should fail')
return false
// eslint-disable-next-line @typescript-eslint/no-unused-vars
} catch (error) {
// expected
console.log('error', error)
return true
}
return true
})
110 changes: 74 additions & 36 deletions ios/Wrappers/PermissionPolicySetWrapper.swift
Original file line number Diff line number Diff line change
Expand Up @@ -9,41 +9,79 @@ import Foundation
import XMTP

class PermissionPolicySetWrapper {
static func fromPermissionOption(_ permissionOption: XMTP.PermissionOption) -> String {
switch permissionOption {
case .allow:
return "allow"
case .deny:
return "deny"
case .admin:
return "admin"
case .superAdmin:
return "superAdmin"
case .unknown:
return "unknown"
}
}

static func encodeToObj(_ policySet: XMTP.PermissionPolicySet) -> [String: Any] {
static func fromPermissionOption(_ permissionOption: XMTP.PermissionOption) -> String {
switch permissionOption {
case .allow:
return "allow"
case .deny:
return "deny"
case .admin:
return "admin"
case .superAdmin:
return "superAdmin"
case .unknown:
return "unknown"
}
}

static func createPermissionOption(from string: String) -> PermissionOption {
switch string {
case "allow":
return .allow
case "deny":
return .deny
case "admin":
return .admin
case "superAdmin":
return .superAdmin
default:
return .unknown
}
}


static func encodeToObj(_ policySet: XMTP.PermissionPolicySet) -> [String: Any] {

return [
"addMemberPolicy": fromPermissionOption(policySet.addMemberPolicy),
"removeMemberPolicy": fromPermissionOption(policySet.removeMemberPolicy),
"addAdminPolicy": fromPermissionOption(policySet.addAdminPolicy),
"removeAdminPolicy": fromPermissionOption(policySet.removeAdminPolicy),
"updateGroupNamePolicy": fromPermissionOption(policySet.updateGroupNamePolicy),
"updateGroupDescriptionPolicy": fromPermissionOption(policySet.updateGroupDescriptionPolicy),
"updateGroupImagePolicy": fromPermissionOption(policySet.updateGroupImagePolicy),
"updateGroupPinnedFrameUrlPolicy": fromPermissionOption(policySet.updateGroupPinnedFrameUrlPolicy)
]
}

static func encodeToJsonString(_ policySet: XMTP.PermissionPolicySet) throws -> String {
let obj = encodeToObj(policySet)
let data = try JSONSerialization.data(withJSONObject: obj)
guard let result = String(data: data, encoding: .utf8) else {
throw WrapperError.encodeError("could not encode permission policy")
}
return result
}
return [
"addMemberPolicy": fromPermissionOption(policySet.addMemberPolicy),
"removeMemberPolicy": fromPermissionOption(policySet.removeMemberPolicy),
"addAdminPolicy": fromPermissionOption(policySet.addAdminPolicy),
"removeAdminPolicy": fromPermissionOption(policySet.removeAdminPolicy),
"updateGroupNamePolicy": fromPermissionOption(policySet.updateGroupNamePolicy),
"updateGroupDescriptionPolicy": fromPermissionOption(policySet.updateGroupDescriptionPolicy),
"updateGroupImagePolicy": fromPermissionOption(policySet.updateGroupImagePolicy),
"updateGroupPinnedFrameUrlPolicy": fromPermissionOption(policySet.updateGroupPinnedFrameUrlPolicy)
]
}
public static func createPermissionPolicySet(from json: String) throws -> PermissionPolicySet {
guard let data = json.data(using: .utf8) else {
throw WrapperError.decodeError("Failed to convert PermissionPolicySet JSON string to data")
}

guard let jsonObject = try? JSONSerialization.jsonObject(with: data, options: []),
let jsonDict = jsonObject as? [String: Any] else {
throw WrapperError.decodeError("Failed to parse PermissionPolicySet JSON data")
}

return PermissionPolicySet(
addMemberPolicy: createPermissionOption(from: jsonDict["addMemberPolicy"] as? String ?? ""),
removeMemberPolicy: createPermissionOption(from: jsonDict["removeMemberPolicy"] as? String ?? ""),
addAdminPolicy: createPermissionOption(from: jsonDict["addAdminPolicy"] as? String ?? ""),
removeAdminPolicy: createPermissionOption(from: jsonDict["removeAdminPolicy"] as? String ?? ""),
updateGroupNamePolicy: createPermissionOption(from: jsonDict["updateGroupNamePolicy"] as? String ?? ""),
updateGroupDescriptionPolicy: createPermissionOption(from: jsonDict["updateGroupDescriptionPolicy"] as? String ?? ""),
updateGroupImagePolicy: createPermissionOption(from: jsonDict["updateGroupImagePolicy"] as? String ?? ""),
updateGroupPinnedFrameUrlPolicy: createPermissionOption(from: jsonDict["updateGroupPinnedFrameUrlPolicy"] as? String ?? "")
)
}

static func encodeToJsonString(_ policySet: XMTP.PermissionPolicySet) throws -> String {
let obj = encodeToObj(policySet)
let data = try JSONSerialization.data(withJSONObject: obj)
guard let result = String(data: data, encoding: .utf8) else {
throw WrapperError.encodeError("could not encode permission policy")
}
return result
}

}
1 change: 1 addition & 0 deletions ios/Wrappers/Wrapper.swift
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import Foundation

enum WrapperError: Swift.Error {
case encodeError(String)
case decodeError(String)
}

protocol Wrapper: Codable {
Expand Down
48 changes: 21 additions & 27 deletions ios/XMTPModule.swift
Original file line number Diff line number Diff line change
Expand Up @@ -745,26 +745,27 @@ public class XMTPModule: Module {
}
}

// AsyncFunction("createGroupCustomPermissions") { (inboxId: String, peerAddresses: [String], permissionJson: String, groupOptionsJson: String) -> String in
// guard let client = await clientsManager.getClient(key: inboxId) else {
// throw Error.noClient
// }
// do {
// let createGroupParams = CreateGroupParamsWrapper.createGroupParamsFromJson(groupOptionsJson)
// let group = try await client.conversations.newGroupCustomP(
// with: peerAddresses,
// permissions: permissionLevel,
// name: createGroupParams.groupName,
// imageUrlSquare: createGroupParams.groupImageUrlSquare,
// description: createGroupParams.groupDescription,
// pinnedFrameUrl: createGroupParams.groupPinnedFrameUrl
// )
// return try GroupWrapper.encode(group, client: client)
// } catch {
// print("ERRRO!: \(error.localizedDescription)")
// throw error
// }
// }
AsyncFunction("createGroupCustomPermissions") { (inboxId: String, peerAddresses: [String], permissionPolicySetJson: String, groupOptionsJson: String) -> String in
guard let client = await clientsManager.getClient(key: inboxId) else {
throw Error.noClient
}
do {
let createGroupParams = CreateGroupParamsWrapper.createGroupParamsFromJson(groupOptionsJson)
let permissionPolicySet = try PermissionPolicySetWrapper.createPermissionPolicySet(from: permissionPolicySetJson)
let group = try await client.conversations.newGroupCustomPermissions(
with: peerAddresses,
permissionPolicySet: permissionPolicySet,
name: createGroupParams.groupName,
imageUrlSquare: createGroupParams.groupImageUrlSquare,
description: createGroupParams.groupDescription,
pinnedFrameUrl: createGroupParams.groupPinnedFrameUrl
)
return try GroupWrapper.encode(group, client: client)
} catch {
print("ERRRO!: \(error.localizedDescription)")
throw error
}
}

AsyncFunction("listMemberInboxIds") { (inboxId: String, groupId: String) -> [String] in
guard let client = await clientsManager.getClient(key: inboxId) else {
Expand Down Expand Up @@ -1452,13 +1453,6 @@ public class XMTPModule: Module {
throw Error.invalidPermissionOption
}
}

// func createPermissionPolicySetFromJSON(permissionPolicySetJson: String) -> PermissionPolicySet {
// let data = permissionPolicySetJson.data(using: .utf8) ?? Data()
// let jsonObj = (try? JSONSerialization.jsonObject(with: data, options: [])) as? [String: Any] ?? [:]
//
// return PermissionPolicySet
// }

func createClientConfig(env: String, appVersion: String?, preEnableIdentityCallback: PreEventCallback? = nil, preCreateIdentityCallback: PreEventCallback? = nil, enableV3: Bool = false, dbEncryptionKey: Data? = nil, dbDirectory: String? = nil, historySyncUrl: String? = nil) -> XMTP.ClientOptions {
// Ensure that all codecs have been registered.
Expand Down
2 changes: 1 addition & 1 deletion src/lib/types/PermissionPolicySet.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ export type PermissionOption =
| 'superAdmin' // Only the super admin of the group can perform this action
| 'unknown'

// Add Admin and Remove admin must be set to either 'admin' or 'superAdmin' to be valid
// Add Admin and Remove admin must be set to either 'admin', 'superAdmin' or 'deny' to be valid
export type PermissionPolicySet = {
addMemberPolicy: PermissionOption
removeMemberPolicy: PermissionOption
Expand Down

0 comments on commit f17acb7

Please sign in to comment.