diff sat/plugins/plugin_sec_aesgcm.py @ 3922:0ff265725489

plugin XEP-0447: handle attachment and download: - plugin XEP-0447 can now be used in message attachments and to retrieve an attachment - plugin attach: `attachment` being processed is added to `extra` so the handler can inspect it - plugin attach: `size` is added to attachment - plugin download: a whole attachment dict is now used in `download` and `file_download`/`file_download_complete`. `download_uri` can be used as a shortcut when just a URI is used. In addition to URI scheme handler, whole attachment handlers can now be registered with `register_download_handler` - plugin XEP-0363: `file_http_upload` `XEP-0363_upload_size` triggers have been renamed to `XEP-0363_upload_pre_slot` and is now using a dict with arguments, allowing for the size but also the filename to be modified, which is necessary for encryption (filename may be hidden from URL this way). - plugin XEP-0446: fix wrong element name - plugin XEP-0447: source handler can now be registered (`url-data` is registered by default) - plugin XEP-0447: source parsing has been put in a separated `parse_sources_elt` method, as it may be useful to do it independently (notably with XEP-0448) - plugin XEP-0447: parse received message and complete attachments when suitable - plugin XEP-0447: can now be used with message attachments - plugin XEP-0447: can now be used with attachments download - renamed `options` arguments to `extra` for consistency - some style change (progressive move from legacy camelCase to PEP8 snake_case) - some typing rel 379
author Goffi <goffi@goffi.org>
date Thu, 06 Oct 2022 16:02:05 +0200
parents 3ef988734869
children 78b5f356900c
line wrap: on
line diff
--- a/sat/plugins/plugin_sec_aesgcm.py	Thu Oct 06 16:02:05 2022 +0200
+++ b/sat/plugins/plugin_sec_aesgcm.py	Thu Oct 06 16:02:05 2022 +0200
@@ -63,13 +63,13 @@
         log.info(_("AESGCM plugin initialization"))
         self._http_upload = host.plugins['XEP-0363']
         self._attach = host.plugins["ATTACH"]
-        host.plugins["DOWNLOAD"].registerScheme(
+        host.plugins["DOWNLOAD"].register_scheme(
             "aesgcm", self.download
         )
         self._attach.register(
             self.canHandleAttachment, self.attach, encrypted=True)
-        host.trigger.add("XEP-0363_upload_size", self._uploadSizeTrigger)
-        host.trigger.add("XEP-0363_upload", self._uploadTrigger)
+        host.trigger.add("XEP-0363_upload_pre_slot", self._upload_pre_slot)
+        host.trigger.add("XEP-0363_upload", self._upload_trigger)
         host.trigger.add("messageReceived", self._messageReceivedTrigger)
 
     async def download(self, client, uri_parsed, dest_path, options):
@@ -129,7 +129,7 @@
                 decryptor=decryptor))
         else:
             d = defer.Deferred()
-            self.host.plugins["DOWNLOAD"].errbackDownload(file_obj, d, resp)
+            self.host.plugins["DOWNLOAD"].errback_download(file_obj, d, resp)
         return progress_id, d
 
     async def canHandleAttachment(self, client, data):
@@ -140,13 +140,13 @@
         else:
             return True
 
-    async def _uploadCb(self, client, filepath, filename, options):
-        options['encryption'] = C.ENC_AES_GCM
-        return await self._http_upload.fileHTTPUpload(
+    async def _upload_cb(self, client, filepath, filename, extra):
+        extra['encryption'] = C.ENC_AES_GCM
+        return await self._http_upload.file_http_upload(
             client=client,
             filepath=filepath,
             filename=filename,
-            options=options
+            extra=extra
         )
 
     async def attach(self, client, data):
@@ -160,14 +160,16 @@
         if not data['message'] or data['message'] == {'': ''}:
             extra_attachments = attachments[1:]
             del attachments[1:]
-            await self._attach.uploadFiles(client, data, upload_cb=self._uploadCb)
+            await self._attach.upload_files(client, data, upload_cb=self._upload_cb)
         else:
             # we have a message, we must send first attachment separately
             extra_attachments = attachments[:]
             attachments.clear()
             del data["extra"][C.MESS_KEY_ATTACHMENTS]
 
-        body_elt = next(data["xml"].elements(C.NS_CLIENT, "body"))
+        body_elt = data["xml"].body
+        if body_elt is None:
+            body_elt = data["xml"].addElement("body")
 
         for attachment in attachments:
             body_elt.addContent(attachment["url"])
@@ -219,11 +221,11 @@
             decrypted = decryptor.update(data)
             file_obj.write(decrypted)
 
-    def _uploadSizeTrigger(self, client, options, file_path, size, size_adjust):
-        if options.get('encryption') != C.ENC_AES_GCM:
+    def _upload_pre_slot(self, client, extra, file_metadata):
+        if extra.get('encryption') != C.ENC_AES_GCM:
             return True
         # the tag is appended to the file
-        size_adjust.append(16)
+        file_metadata["size"] += 16
         return True
 
     def _encrypt(self, data, encryptor):
@@ -239,8 +241,8 @@
                 # as we have already finalized, we can now send EOF
                 return b''
 
-    def _uploadTrigger(self, client, options, sat_file, file_producer, slot):
-        if options.get('encryption') != C.ENC_AES_GCM:
+    def _upload_trigger(self, client, extra, sat_file, file_producer, slot):
+        if extra.get('encryption') != C.ENC_AES_GCM:
             return True
         log.debug("encrypting file with AES-GCM")
         iv = secrets.token_bytes(12)
@@ -255,7 +257,7 @@
         # so we need to check with final data length to avoid a warning on close()
         sat_file.check_size_with_read = True
 
-        # file_producer get length directly from file, and this cause trouble has
+        # file_producer get length directly from file, and this cause trouble as
         # we have to change the size because of encryption. So we adapt it here,
         # else the producer would stop reading prematurely
         file_producer.length = sat_file.size