comparison sat/plugins/plugin_xep_0447.py @ 4023:78b5f356900c

component AP gateway: handle attachments
author Goffi <goffi@goffi.org>
date Thu, 23 Mar 2023 15:42:21 +0100
parents 0ff265725489
children 524856bd7b19
comparison
equal deleted inserted replaced
4022:cdb7de398c85 4023:78b5f356900c
265 265
266 @param file_sharing_elt: <file-sharing/> element 266 @param file_sharing_elt: <file-sharing/> element
267 @return: file-sharing data. It a dict whose keys correspond to 267 @return: file-sharing data. It a dict whose keys correspond to
268 [get_file_sharing_elt] parameters 268 [get_file_sharing_elt] parameters
269 """ 269 """
270 if file_sharing_elt.name != "file-sharing": 270 if file_sharing_elt.name != "file-sharing" or file_sharing_elt.uri != NS_SFS:
271 try: 271 try:
272 file_sharing_elt = next( 272 file_sharing_elt = next(
273 file_sharing_elt.elements(NS_SFS, "file-sharing") 273 file_sharing_elt.elements(NS_SFS, "file-sharing")
274 ) 274 )
275 except StopIteration: 275 except StopIteration:
293 client: SatXMPPEntity, 293 client: SatXMPPEntity,
294 message_elt: domish.Element, 294 message_elt: domish.Element,
295 data: Dict[str, Any] 295 data: Dict[str, Any]
296 ) -> Dict[str, Any]: 296 ) -> Dict[str, Any]:
297 """Check <message> for a shared file, and add it as an attachment""" 297 """Check <message> for a shared file, and add it as an attachment"""
298 # XXX: XEP-0447 doesn't support several attachments in a single message, thus only 298 # XXX: XEP-0447 doesn't support several attachments in a single message, for now
299 # one attachment can be added 299 # however that should be fixed in future version, and so we accept several
300 try: 300 # <file-sharing> element in a message.
301 for file_sharing_elt in message_elt.elements(NS_SFS, "file-sharing"):
301 attachment = self.parse_file_sharing_elt(message_elt) 302 attachment = self.parse_file_sharing_elt(message_elt)
302 except exceptions.NotFound: 303
303 return data 304 if any(
304 305 s.get(C.MESS_KEY_ENCRYPTED, False)
305 if any( 306 for s in attachment["sources"]
306 s.get(C.MESS_KEY_ENCRYPTED, False) 307 ) and client.encryption.isEncrypted(data):
307 for s in attachment["sources"] 308 # we don't add the encrypted flag if the message itself is not encrypted,
308 ) and client.encryption.isEncrypted(data): 309 # because the decryption key is part of the link, so sending it over
309 # we don't add the encrypted flag if the message itself is not encrypted, 310 # unencrypted channel is like having no encryption at all.
310 # because the decryption key is part of the link, so sending it over 311 attachment[C.MESS_KEY_ENCRYPTED] = True
311 # unencrypted channel is like having no encryption at all. 312
312 attachment[C.MESS_KEY_ENCRYPTED] = True 313 attachments = data['extra'].setdefault(C.KEY_ATTACHMENTS, [])
313 314 attachments.append(attachment)
314 attachments = data['extra'].setdefault(C.MESS_KEY_ATTACHMENTS, [])
315 attachments.append(attachment)
316 315
317 return data 316 return data
318 317
319 async def attach(self, client, data): 318 async def attach(self, client, data):
320 # XXX: for now, XEP-0447 only allow to send one file per <message/>, thus we need 319 # XXX: for now, XEP-0447 only allow to send one file per <message/>, thus we need
321 # to send each file in a separate message 320 # to send each file in a separate message
322 attachments = data["extra"][C.MESS_KEY_ATTACHMENTS] 321 attachments = data["extra"][C.KEY_ATTACHMENTS]
323 if not data['message'] or data['message'] == {'': ''}: 322 if not data['message'] or data['message'] == {'': ''}:
324 extra_attachments = attachments[1:] 323 extra_attachments = attachments[1:]
325 del attachments[1:] 324 del attachments[1:]
326 else: 325 else:
327 # we have a message, we must send first attachment separately 326 # we have a message, we must send first attachment separately
328 extra_attachments = attachments[:] 327 extra_attachments = attachments[:]
329 attachments.clear() 328 attachments.clear()
330 del data["extra"][C.MESS_KEY_ATTACHMENTS] 329 del data["extra"][C.KEY_ATTACHMENTS]
331 330
332 if attachments: 331 if attachments:
333 if len(attachments) > 1: 332 if len(attachments) > 1:
334 raise exceptions.InternalError( 333 raise exceptions.InternalError(
335 "There should not be more that one attachment at this point" 334 "There should not be more that one attachment at this point"
341 file_hash = (attachment["hash_algo"], attachment["hash"]) 340 file_hash = (attachment["hash_algo"], attachment["hash"])
342 except KeyError: 341 except KeyError:
343 file_hash = None 342 file_hash = None
344 file_sharing_elt = self.get_file_sharing_elt( 343 file_sharing_elt = self.get_file_sharing_elt(
345 [{"url": attachment["url"]}], 344 [{"url": attachment["url"]}],
346 name=attachment["name"], 345 name=attachment.get("name"),
347 size=attachment["size"], 346 size=attachment.get("size"),
347 desc=attachment.get("desc"),
348 media_type=attachment.get("media_type"),
348 file_hash=file_hash 349 file_hash=file_hash
349 ) 350 )
350 data["xml"].addChild(file_sharing_elt) 351 data["xml"].addChild(file_sharing_elt)
351 352
352 for attachment in extra_attachments: 353 for attachment in extra_attachments:
354 await client.sendMessage( 355 await client.sendMessage(
355 to_jid=data['to'], 356 to_jid=data['to'],
356 message={'': ''}, 357 message={'': ''},
357 subject=data['subject'], 358 subject=data['subject'],
358 mess_type=data['type'], 359 mess_type=data['type'],
359 extra={C.MESS_KEY_ATTACHMENTS: [attachment]}, 360 extra={C.KEY_ATTACHMENTS: [attachment]},
360 ) 361 )
361 362
362 if ((not data['extra'] 363 if ((not data['extra']
363 and (not data['message'] or data['message'] == {'': ''}) 364 and (not data['message'] or data['message'] == {'': ''})
364 and not data['subject'])): 365 and not data['subject'])):