Mercurial > libervia-backend
comparison sat/plugins/plugin_sec_oxps.py @ 4037:524856bd7b19
massive refactoring to switch from camelCase to snake_case:
historically, Libervia (SàT before) was using camelCase as allowed by PEP8 when using a
pre-PEP8 code, to use the same coding style as in Twisted.
However, snake_case is more readable and it's better to follow PEP8 best practices, so it
has been decided to move on full snake_case. Because Libervia has a huge codebase, this
ended with a ugly mix of camelCase and snake_case.
To fix that, this patch does a big refactoring by renaming every function and method
(including bridge) that are not coming from Twisted or Wokkel, to use fully snake_case.
This is a massive change, and may result in some bugs.
author | Goffi <goffi@goffi.org> |
---|---|
date | Sat, 08 Apr 2023 13:54:42 +0200 |
parents | 9badc46c5481 |
children | c23cad65ae99 |
comparison
equal
deleted
inserted
replaced
4036:c4464d7ae97b | 4037:524856bd7b19 |
---|---|
81 class PubsubEncryption: | 81 class PubsubEncryption: |
82 namespace = NS_OXPS | 82 namespace = NS_OXPS |
83 | 83 |
84 def __init__(self, host): | 84 def __init__(self, host): |
85 log.info(_("OpenPGP for XMPP Pubsub plugin initialization")) | 85 log.info(_("OpenPGP for XMPP Pubsub plugin initialization")) |
86 host.registerNamespace("oxps", NS_OXPS) | 86 host.register_namespace("oxps", NS_OXPS) |
87 self.host = host | 87 self.host = host |
88 self._p = host.plugins["XEP-0060"] | 88 self._p = host.plugins["XEP-0060"] |
89 self._h = host.plugins["XEP-0334"] | 89 self._h = host.plugins["XEP-0334"] |
90 self._ox = host.plugins["XEP-0373"] | 90 self._ox = host.plugins["XEP-0373"] |
91 host.trigger.add("XEP-0060_publish", self._publish_trigger) | 91 host.trigger.add("XEP-0060_publish", self._publish_trigger) |
92 host.trigger.add("XEP-0060_items", self._items_trigger) | 92 host.trigger.add("XEP-0060_items", self._items_trigger) |
93 host.trigger.add( | 93 host.trigger.add( |
94 "messageReceived", | 94 "messageReceived", |
95 self._message_received_trigger, | 95 self._message_received_trigger, |
96 ) | 96 ) |
97 host.bridge.addMethod( | 97 host.bridge.add_method( |
98 "psSecretShare", | 98 "ps_secret_share", |
99 ".plugin", | 99 ".plugin", |
100 in_sign="sssass", | 100 in_sign="sssass", |
101 out_sign="", | 101 out_sign="", |
102 method=self._ps_secret_share, | 102 method=self._ps_secret_share, |
103 async_=True, | 103 async_=True, |
104 ) | 104 ) |
105 host.bridge.addMethod( | 105 host.bridge.add_method( |
106 "psSecretRevoke", | 106 "ps_secret_revoke", |
107 ".plugin", | 107 ".plugin", |
108 in_sign="sssass", | 108 in_sign="sssass", |
109 out_sign="", | 109 out_sign="", |
110 method=self._ps_secret_revoke, | 110 method=self._ps_secret_revoke, |
111 async_=True, | 111 async_=True, |
112 ) | 112 ) |
113 host.bridge.addMethod( | 113 host.bridge.add_method( |
114 "psSecretRotate", | 114 "ps_secret_rotate", |
115 ".plugin", | 115 ".plugin", |
116 in_sign="ssass", | 116 in_sign="ssass", |
117 out_sign="", | 117 out_sign="", |
118 method=self._ps_secret_rotate, | 118 method=self._ps_secret_rotate, |
119 async_=True, | 119 async_=True, |
120 ) | 120 ) |
121 host.bridge.addMethod( | 121 host.bridge.add_method( |
122 "psSecretsList", | 122 "ps_secrets_list", |
123 ".plugin", | 123 ".plugin", |
124 in_sign="sss", | 124 in_sign="sss", |
125 out_sign="s", | 125 out_sign="s", |
126 method=self._ps_secrets_list, | 126 method=self._ps_secrets_list, |
127 async_=True, | 127 async_=True, |
128 ) | 128 ) |
129 | 129 |
130 def getHandler(self, client): | 130 def get_handler(self, client): |
131 return PubsubEncryption_Handler() | 131 return PubsubEncryption_Handler() |
132 | 132 |
133 async def profileConnecting(self, client): | 133 async def profile_connecting(self, client): |
134 client.__storage = persistent.LazyPersistentBinaryDict( | 134 client.__storage = persistent.LazyPersistentBinaryDict( |
135 IMPORT_NAME, client.profile | 135 IMPORT_NAME, client.profile |
136 ) | 136 ) |
137 # cache to avoid useless DB access, and to avoid race condition by ensuring that | 137 # cache to avoid useless DB access, and to avoid race condition by ensuring that |
138 # the same shared_secrets instance is always used for a given node. | 138 # the same shared_secrets instance is always used for a given node. |
237 recipients: List[str], | 237 recipients: List[str], |
238 profile_key: str | 238 profile_key: str |
239 ) -> defer.Deferred: | 239 ) -> defer.Deferred: |
240 return defer.ensureDeferred( | 240 return defer.ensureDeferred( |
241 self.revoke( | 241 self.revoke( |
242 self.host.getClient(profile_key), | 242 self.host.get_client(profile_key), |
243 jid.JID(service) if service else None, | 243 jid.JID(service) if service else None, |
244 node, | 244 node, |
245 secret_id, | 245 secret_id, |
246 [jid.JID(r) for r in recipients] or None, | 246 [jid.JID(r) for r in recipients] or None, |
247 ) | 247 ) |
265 entities known to have the shared secret will be notified. | 265 entities known to have the shared secret will be notified. |
266 Use empty list if you don't want to notify anybody (not recommended) | 266 Use empty list if you don't want to notify anybody (not recommended) |
267 """ | 267 """ |
268 if service is None: | 268 if service is None: |
269 service = client.jid.userhostJID() | 269 service = client.jid.userhostJID() |
270 node_uri = uri.buildXMPPUri("pubsub", path=service.full(), node=node) | 270 node_uri = uri.build_xmpp_uri("pubsub", path=service.full(), node=node) |
271 shared_secrets = await self.load_secrets(client, node_uri) | 271 shared_secrets = await self.load_secrets(client, node_uri) |
272 if not shared_secrets: | 272 if not shared_secrets: |
273 raise exceptions.NotFound(f"No shared secret is known for {node_uri}") | 273 raise exceptions.NotFound(f"No shared secret is known for {node_uri}") |
274 try: | 274 try: |
275 shared_secret = shared_secrets[secret_id] | 275 shared_secret = shared_secrets[secret_id] |
325 ) | 325 ) |
326 message_elt = domish.Element((None, "message")) | 326 message_elt = domish.Element((None, "message")) |
327 message_elt["from"] = client.jid.full() | 327 message_elt["from"] = client.jid.full() |
328 message_elt["to"] = recipient.full() | 328 message_elt["to"] = recipient.full() |
329 message_elt.addChild((openpgp_elt)) | 329 message_elt.addChild((openpgp_elt)) |
330 self._h.addHintElements(message_elt, [self._h.HINT_STORE]) | 330 self._h.add_hint_elements(message_elt, [self._h.HINT_STORE]) |
331 client.send(message_elt) | 331 client.send(message_elt) |
332 | 332 |
333 def _ps_secret_share( | 333 def _ps_secret_share( |
334 self, | 334 self, |
335 recipient: str, | 335 recipient: str, |
338 secret_ids: List[str], | 338 secret_ids: List[str], |
339 profile_key: str | 339 profile_key: str |
340 ) -> defer.Deferred: | 340 ) -> defer.Deferred: |
341 return defer.ensureDeferred( | 341 return defer.ensureDeferred( |
342 self.share_secrets( | 342 self.share_secrets( |
343 self.host.getClient(profile_key), | 343 self.host.get_client(profile_key), |
344 jid.JID(recipient), | 344 jid.JID(recipient), |
345 jid.JID(service) if service else None, | 345 jid.JID(service) if service else None, |
346 node, | 346 node, |
347 secret_ids or None, | 347 secret_ids or None, |
348 ) | 348 ) |
375 ) | 375 ) |
376 message_elt = domish.Element((None, "message")) | 376 message_elt = domish.Element((None, "message")) |
377 message_elt["from"] = client.jid.full() | 377 message_elt["from"] = client.jid.full() |
378 message_elt["to"] = recipient.full() | 378 message_elt["to"] = recipient.full() |
379 message_elt.addChild((openpgp_elt)) | 379 message_elt.addChild((openpgp_elt)) |
380 self._h.addHintElements(message_elt, [self._h.HINT_STORE]) | 380 self._h.add_hint_elements(message_elt, [self._h.HINT_STORE]) |
381 client.send(message_elt) | 381 client.send(message_elt) |
382 shared_secret.shared_with.add(recipient) | 382 shared_secret.shared_with.add(recipient) |
383 | 383 |
384 async def share_secrets( | 384 async def share_secrets( |
385 self, | 385 self, |
397 @param secret_ids: IDs of the secrets to share, or None to share all known secrets | 397 @param secret_ids: IDs of the secrets to share, or None to share all known secrets |
398 (disabled or not) | 398 (disabled or not) |
399 """ | 399 """ |
400 if service is None: | 400 if service is None: |
401 service = client.jid.userhostJID() | 401 service = client.jid.userhostJID() |
402 node_uri = uri.buildXMPPUri("pubsub", path=service.full(), node=node) | 402 node_uri = uri.build_xmpp_uri("pubsub", path=service.full(), node=node) |
403 shared_secrets = await self.load_secrets(client, node_uri) | 403 shared_secrets = await self.load_secrets(client, node_uri) |
404 if shared_secrets is None: | 404 if shared_secrets is None: |
405 # no secret shared yet, let's generate one | 405 # no secret shared yet, let's generate one |
406 shared_secret = self.generate_secret(client) | 406 shared_secret = self.generate_secret(client) |
407 shared_secrets = {shared_secret.id: shared_secret} | 407 shared_secrets = {shared_secret.id: shared_secret} |
427 recipients: List[str], | 427 recipients: List[str], |
428 profile_key: str, | 428 profile_key: str, |
429 ) -> defer.Deferred: | 429 ) -> defer.Deferred: |
430 return defer.ensureDeferred( | 430 return defer.ensureDeferred( |
431 self.rotate_secret( | 431 self.rotate_secret( |
432 self.host.getClient(profile_key), | 432 self.host.get_client(profile_key), |
433 jid.JID(service) if service else None, | 433 jid.JID(service) if service else None, |
434 node, | 434 node, |
435 [jid.JID(r) for r in recipients] or None | 435 [jid.JID(r) for r in recipients] or None |
436 ) | 436 ) |
437 ) | 437 ) |
451 if None, all recipients known to have last active shared secret will get the | 451 if None, all recipients known to have last active shared secret will get the |
452 new secret | 452 new secret |
453 """ | 453 """ |
454 if service is None: | 454 if service is None: |
455 service = client.jid.userhostJID() | 455 service = client.jid.userhostJID() |
456 node_uri = uri.buildXMPPUri("pubsub", path=service.full(), node=node) | 456 node_uri = uri.build_xmpp_uri("pubsub", path=service.full(), node=node) |
457 shared_secrets = await self.load_secrets(client, node_uri) | 457 shared_secrets = await self.load_secrets(client, node_uri) |
458 if shared_secrets is None: | 458 if shared_secrets is None: |
459 shared_secrets = {} | 459 shared_secrets = {} |
460 for shared_secret in shared_secrets.values(): | 460 for shared_secret in shared_secrets.values(): |
461 if not shared_secret.revoked: | 461 if not shared_secret.revoked: |
487 node: str, | 487 node: str, |
488 profile_key: str | 488 profile_key: str |
489 ) -> defer.Deferred: | 489 ) -> defer.Deferred: |
490 d = defer.ensureDeferred( | 490 d = defer.ensureDeferred( |
491 self.list_shared_secrets( | 491 self.list_shared_secrets( |
492 self.host.getClient(profile_key), | 492 self.host.get_client(profile_key), |
493 jid.JID(service) if service else None, | 493 jid.JID(service) if service else None, |
494 node, | 494 node, |
495 ) | 495 ) |
496 ) | 496 ) |
497 d.addCallback(lambda ret: data_format.serialise(ret)) | 497 d.addCallback(lambda ret: data_format.serialise(ret)) |
510 @return: shared secrets data | 510 @return: shared secrets data |
511 @raise exceptions.NotFound: no shared secret found for this node | 511 @raise exceptions.NotFound: no shared secret found for this node |
512 """ | 512 """ |
513 if service is None: | 513 if service is None: |
514 service = client.jid.userhostJID() | 514 service = client.jid.userhostJID() |
515 node_uri = uri.buildXMPPUri("pubsub", path=service.full(), node=node) | 515 node_uri = uri.build_xmpp_uri("pubsub", path=service.full(), node=node) |
516 shared_secrets = await self.load_secrets(client, node_uri) | 516 shared_secrets = await self.load_secrets(client, node_uri) |
517 if shared_secrets is None: | 517 if shared_secrets is None: |
518 raise exceptions.NotFound(f"No shared secrets found for {node_uri}") | 518 raise exceptions.NotFound(f"No shared secrets found for {node_uri}") |
519 return [ | 519 return [ |
520 dataclasses.asdict(s, dict_factory=self.__secrect_dict_factory) | 520 dataclasses.asdict(s, dict_factory=self.__secrect_dict_factory) |
539 except (KeyError, RuntimeError) as e: | 539 except (KeyError, RuntimeError) as e: |
540 log.warning( | 540 log.warning( |
541 f"ignoring invalid <revoke> element: {e}\n{revoke_elt.toXml()}" | 541 f"ignoring invalid <revoke> element: {e}\n{revoke_elt.toXml()}" |
542 ) | 542 ) |
543 return | 543 return |
544 node_uri = uri.buildXMPPUri("pubsub", path=service.full(), node=node) | 544 node_uri = uri.build_xmpp_uri("pubsub", path=service.full(), node=node) |
545 shared_secrets = await self.load_secrets(client, node_uri) | 545 shared_secrets = await self.load_secrets(client, node_uri) |
546 if shared_secrets is None: | 546 if shared_secrets is None: |
547 log.warning( | 547 log.warning( |
548 f"Can't revoke shared secret {secret_id}: no known shared secrets for " | 548 f"Can't revoke shared secret {secret_id}: no known shared secrets for " |
549 f"{node_uri}" | 549 f"{node_uri}" |
602 ) | 602 ) |
603 return | 603 return |
604 shared_secret = SharedSecret( | 604 shared_secret = SharedSecret( |
605 id=secret_id, key=key, timestamp=timestamp, origin=sender, revoked=revoked | 605 id=secret_id, key=key, timestamp=timestamp, origin=sender, revoked=revoked |
606 ) | 606 ) |
607 node_uri = uri.buildXMPPUri("pubsub", path=service.full(), node=node) | 607 node_uri = uri.build_xmpp_uri("pubsub", path=service.full(), node=node) |
608 shared_secrets = await self.load_secrets(client, node_uri) | 608 shared_secrets = await self.load_secrets(client, node_uri) |
609 if shared_secrets is None: | 609 if shared_secrets is None: |
610 shared_secrets = {} | 610 shared_secrets = {} |
611 # no known shared secret yet for this node, we have to trust first user who | 611 # no known shared secret yet for this node, we have to trust first user who |
612 # send it | 612 # send it |
634 sender: jid.JID, | 634 sender: jid.JID, |
635 extra: Dict[str, Any] | 635 extra: Dict[str, Any] |
636 ) -> bool: | 636 ) -> bool: |
637 if not items or not extra.get("encrypted"): | 637 if not items or not extra.get("encrypted"): |
638 return True | 638 return True |
639 node_uri = uri.buildXMPPUri("pubsub", path=service.full(), node=node) | 639 node_uri = uri.build_xmpp_uri("pubsub", path=service.full(), node=node) |
640 shared_secrets = await self.load_secrets(client, node_uri) | 640 shared_secrets = await self.load_secrets(client, node_uri) |
641 if shared_secrets is None: | 641 if shared_secrets is None: |
642 shared_secrets = {} | 642 shared_secrets = {} |
643 shared_secret = None | 643 shared_secret = None |
644 else: | 644 else: |
711 log.warning( | 711 log.warning( |
712 f'"key" attribute is missing from encrypted item: {item.toXml()}' | 712 f'"key" attribute is missing from encrypted item: {item.toXml()}' |
713 ) | 713 ) |
714 continue | 714 continue |
715 if shared_secrets is None: | 715 if shared_secrets is None: |
716 node_uri = uri.buildXMPPUri("pubsub", path=service.full(), node=node) | 716 node_uri = uri.build_xmpp_uri("pubsub", path=service.full(), node=node) |
717 shared_secrets = await self.load_secrets(client, node_uri) | 717 shared_secrets = await self.load_secrets(client, node_uri) |
718 if shared_secrets is None: | 718 if shared_secrets is None: |
719 log.warning( | 719 log.warning( |
720 f"No known shared secret for {node_uri}, can't decrypt" | 720 f"No known shared secret for {node_uri}, can't decrypt" |
721 ) | 721 ) |