Fixes to outbound channel name & topic setting

- Use the correct API for open channels
- Allow changing the name (title) of normal channels
This commit is contained in:
Andrew Ferrazzutti 2022-05-16 01:53:21 -04:00
parent bccd0ed4e0
commit 1541732d0b
3 changed files with 91 additions and 35 deletions

View File

@ -25,8 +25,8 @@
* [ ] Ban<sup>[4]</sup>
* [ ] Unban<sup>[4]</sup>
* [ ] Room metadata changes
* [x] Name<sup>[1]</sup>
* [x] Topic<sup>[1]</sup>
* [x] Name
* [x] Topic
* [ ] Avatar
* [ ] Per-room user nick
* KakaoTalk → Matrix

View File

@ -1219,9 +1219,6 @@ class Portal(DBPortal, BasePortal):
# Misses should be guarded by supports_state_event, but handle this just in case
self.log.error(f"Skipping Matrix state event {evt.event_id} of unsupported type {evt.type}")
return
if not self.is_open:
self.log.info(f"Not bridging f{handler.action_name} change of portal for non-open channel")
return
try:
effective_sender, _ = await self.get_relay_sender(sender, f"{handler.action_name} {evt.event_id}")
if effective_sender:
@ -1338,6 +1335,9 @@ class Portal(DBPortal, BasePortal):
) -> None:
if content.topic == prev_content.topic:
return
if not self.is_open:
self.log.info(f"Not bridging topic change of portal for non-open channel")
return
if not (sender and sender.is_connected):
raise Exception(
"Only users connected to KakaoTalk can set the description of a KakaoTalk channel"

View File

@ -366,20 +366,39 @@ class UserClient {
* @param {ChannelProps} channelProps
*/
async getChannel(channelProps) {
let channel = this.#talkClient.channelList.get(channelProps.id)
if (channel) {
return channel
} else {
const talkChannel = this.#talkClient.channelList.get(channelProps.id)
if (talkChannel) {
return talkChannel
}
const channelList = getChannelListForType(
this.#talkClient.channelList,
channelProps.type
)
const res = await channelList.addChannel({ channelId: channelProps.id })
if (!res.success) {
throw new Error(`Unable to add ${channelProps.type} channel ${channelProps.id}`)
this.error(`Unable to add ${channelProps.type} channel ${channelProps.id}`)
throw res
}
return res.result
}
/**
* @param {Long} channelId
*/
async getNormalChannel(channelId) {
const channelList = this.#talkClient.channelList.normal
const talkChannel = channelList.get(channelId)
if (talkChannel) {
return talkChannel
}
const res = await channelList.addChannel({ channelId: channelId })
if (!res.success) {
this.error(`Unable to add normal channel ${channelProps.id}`)
throw res
}
return res.result
}
/**
@ -600,12 +619,30 @@ export default class PeerClient {
const userClient = this.#getUser(mxid)
const talkChannel = await userClient.getChannel(channelProps)
if (permNeeded) {
const permActual = talkChannel.getUserInfo({ userId: userClient.userId }).perm
await this.#requireChannelPerm(talkChannel, permNeeded, action)
}
return talkChannel
}
/**
* @param {TalkOpenChannel} talkChannel
* @param {OpenChannelUserPerm[]} permNeeded Throw if the user's permission level matches none of the values in this list.
* @param {string} action The action requiring permission
* @throws {PermError} if the user does not have the specified permission level.
*/
async #requireChannelPerm(talkChannel, permNeeded, action) {
const permActual = talkChannel.getUserInfo({ userId: talkChannel.clientUser.userId }).perm
if (permNeeded.indexOf(permActual) == -1) {
throw new PermError(permNeeded, permActual, action)
}
}
return talkChannel
/**
* @param {string} mxid
* @param {Long} channelId
*/
async #getUserNormalChannel(mxid, channelId) {
return await this.#getUser(mxid).getNormalChannel(channelId)
}
/**
@ -1104,13 +1141,12 @@ export default class PeerClient {
* @param {string} req.name
*/
setChannelName = async (req) => {
const talkChannel = await this.#getUserChannel(
req.mxid,
req.channel_props,
[OpenChannelUserPerm.OWNER],
"change channel name"
)
if (!isChannelTypeOpen(req.channel_props.type)) {
const talkChannel = await this.#getUserNormalChannel(req.mxid, req.channel_props.id)
return await talkChannel.setTitleMeta(req.name)
} else {
return await this.#setOpenChannelProperty(req.mxid, req.channel_props, "linkName", req.name)
}
}
/**
@ -1120,13 +1156,33 @@ export default class PeerClient {
* @param {string} req.description
*/
setChannelDescription = async (req) => {
const talkChannel = await this.#getUserChannel(
req.mxid,
req.channel_props,
[OpenChannelUserPerm.OWNER],
"change channel description"
return await this.#setOpenChannelProperty(req.mxid, req.channel_props, "description", req.description)
}
/**
* @param {string} mxid
* @param {ChannelProps} channelProps
* @param {string} propertyName
* @param {any} propertyValue
*/
async #setOpenChannelProperty(mxid, channelProps, propertyName, propertyValue) {
if (isChannelTypeOpen(channelProps)) {
throw ProtocolError(`Cannot set ${propertyName} of non-open channel ${channelProps.id} (type = ${channelProps.type})`)
}
const userClient = this.#getUser(mxid)
/** @type {TalkOpenChannel} */
const talkChannel = await userClient.getChannel(channelProps)
this.#requireChannelPerm(talkChannel, [OpenChannelUserPerm.OWNER], `change channel ${propertyName}`)
const linkRes = await talkChannel.getLatestOpenLink()
if (!linkRes.success) throw linkRes
const link = linkRes.result
link[propertyName] = propertyValue
return await userClient.talkClient.channelList.open.updateOpenLink(
{ linkId: link.linkId }, link
)
return await talkChannel.setNoticeMeta(req.description)
}
/*