Mercurial > libervia-backend
comparison sat/plugins/plugin_xep_0166/__init__.py @ 4053:dd39e60ca2aa
plugin XEP-0166: set `jingle_elt`, `desc_elt` and `transport_elt`:
those values are set to corresponding domish.Element in session for session
init/confirmation/accept workflow.
author | Goffi <goffi@goffi.org> |
---|---|
date | Mon, 29 May 2023 13:32:28 +0200 |
parents | 3900626bc100 |
children |
comparison
equal
deleted
inserted
replaced
4052:2ced30f6d5de | 4053:dd39e60ca2aa |
---|---|
249 @param fail(failure.Failure): the exceptions raised | 249 @param fail(failure.Failure): the exceptions raised |
250 @param session(dict): data of the session | 250 @param session(dict): data of the session |
251 @param request(domsih.Element): jingle request | 251 @param request(domsih.Element): jingle request |
252 @param client: %(doc_client)s | 252 @param client: %(doc_client)s |
253 """ | 253 """ |
254 del session["jingle_elt"] | |
254 log.warning(f"Error while processing jingle request [{client.profile}]") | 255 log.warning(f"Error while processing jingle request [{client.profile}]") |
255 if isinstance(failure_.value, defer.FirstError): | 256 if isinstance(failure_.value, defer.FirstError): |
256 failure_ = failure_.value.subFailure.value | 257 failure_ = failure_.value.subFailure.value |
257 if isinstance(failure_, exceptions.DataError): | 258 if isinstance(failure_, exceptions.DataError): |
258 return self.sendError(client, "bad-request", session["id"], request) | 259 return self.sendError(client, "bad-request", session["id"], request) |
508 | 509 |
509 iq_elt, jingle_elt = self._build_jingle_elt( | 510 iq_elt, jingle_elt = self._build_jingle_elt( |
510 client, session, XEP_0166.A_SESSION_INITIATE | 511 client, session, XEP_0166.A_SESSION_INITIATE |
511 ) | 512 ) |
512 jingle_elt["initiator"] = initiator.full() | 513 jingle_elt["initiator"] = initiator.full() |
514 session["jingle_elt"] = jingle_elt | |
513 | 515 |
514 session_contents = session["contents"] | 516 session_contents = session["contents"] |
515 | 517 |
516 for content in contents: | 518 for content in contents: |
517 # we get the application plugin | 519 # we get the application plugin |
525 raise exceptions.InternalError( | 527 raise exceptions.InternalError( |
526 "No transport registered for {}".format(transport_type) | 528 "No transport registered for {}".format(transport_type) |
527 ) | 529 ) |
528 | 530 |
529 # we build the session data for this content | 531 # we build the session data for this content |
532 application_data = {} | |
533 transport_data = content_data.transport_data | |
530 session_content = { | 534 session_content = { |
531 "application": content_data.application, | 535 "application": content_data.application, |
532 "application_data": {}, | 536 "application_data": application_data, |
533 "transport": transport, | 537 "transport": transport, |
534 "transport_data": content_data.transport_data, | 538 "transport_data": transport_data, |
535 "creator": XEP_0166.ROLE_INITIATOR, | 539 "creator": XEP_0166.ROLE_INITIATOR, |
536 "senders": content.get("senders", "both"), | 540 "senders": content.get("senders", "both"), |
537 } | 541 } |
538 if content_data.content_name in session_contents: | 542 if content_data.content_name in session_contents: |
539 raise exceptions.InternalError( | 543 raise exceptions.InternalError( |
549 content_elt["senders"] = content["senders"] | 553 content_elt["senders"] = content["senders"] |
550 except KeyError: | 554 except KeyError: |
551 pass | 555 pass |
552 | 556 |
553 # then the description element | 557 # then the description element |
554 desc_elt = await utils.as_deferred( | 558 application_data["desc_elt"] = desc_elt = await utils.as_deferred( |
555 content_data.application.handler.jingle_session_init, | 559 content_data.application.handler.jingle_session_init, |
556 client, session, content_data.content_name, | 560 client, session, content_data.content_name, |
557 *content_data.app_args, **content_data.app_kwargs | 561 *content_data.app_args, **content_data.app_kwargs |
558 ) | 562 ) |
559 content_elt.addChild(desc_elt) | 563 content_elt.addChild(desc_elt) |
560 | 564 |
561 # and the transport one | 565 # and the transport one |
562 transport_elt = await utils.as_deferred( | 566 transport_data["transport_elt"] = transport_elt = await utils.as_deferred( |
563 transport.handler.jingle_session_init, | 567 transport.handler.jingle_session_init, |
564 client, session, content_data.content_name, | 568 client, session, content_data.content_name, |
565 ) | 569 ) |
566 content_elt.addChild(transport_elt) | 570 content_elt.addChild(transport_elt) |
567 | 571 |
568 if not await self.host.trigger.async_point( | 572 if not await self.host.trigger.async_point( |
569 "XEP-0166_initiate_elt_built", | 573 "XEP-0166_initiate_elt_built", |
570 client, session, iq_elt, jingle_elt | 574 client, session, iq_elt, jingle_elt |
571 ): | 575 ): |
572 return sid | 576 return sid |
577 | |
578 # processing is done, we can remove elements | |
579 for content_data in session_contents.values(): | |
580 del content_data["application_data"]["desc_elt"] | |
581 del content_data["transport_data"]["transport_elt"] | |
582 del session["jingle_elt"] | |
583 | |
573 if encrypted: | 584 if encrypted: |
574 for content in session["contents"].values(): | 585 for content in session["contents"].values(): |
575 if "encryption" not in content: | 586 if "encryption" not in content: |
576 raise exceptions.EncryptionError( | 587 raise exceptions.EncryptionError( |
577 "Encryption is requested, but no encryption has been set" | 588 "Encryption is requested, but no encryption has been set" |
740 with_transport: bool = True, | 751 with_transport: bool = True, |
741 store_in_session: bool = True, | 752 store_in_session: bool = True, |
742 ) -> Dict[str, dict]: | 753 ) -> Dict[str, dict]: |
743 """Parse contents elements and fill contents_dict accordingly | 754 """Parse contents elements and fill contents_dict accordingly |
744 | 755 |
745 after the parsing, contents_dict will containt handlers, "desc_elt" and "transport_elt" | 756 after the parsing, contents_dict will containt handlers, "desc_elt" and |
757 "transport_elt" | |
746 @param jingle_elt: parent <jingle> element, containing one or more <content> | 758 @param jingle_elt: parent <jingle> element, containing one or more <content> |
747 @param session: session data | 759 @param session: session data |
748 @param request: the whole request | 760 @param request: the whole request |
749 @param client: %(doc_client)s | 761 @param client: %(doc_client)s |
750 @param new: True if the content is new and must be created, | 762 @param new: True if the content is new and must be created, |
977 | 989 |
978 # at this point we can send the <iq/> result to confirm reception of the request | 990 # at this point we can send the <iq/> result to confirm reception of the request |
979 client.send(xmlstream.toResponse(request, "result")) | 991 client.send(xmlstream.toResponse(request, "result")) |
980 | 992 |
981 | 993 |
994 assert "jingle_elt" not in session | |
995 session["jingle_elt"] = jingle_elt | |
982 if not await self.host.trigger.async_point( | 996 if not await self.host.trigger.async_point( |
983 "XEP-0166_on_session_initiate", | 997 "XEP-0166_on_session_initiate", |
984 client, session, request, jingle_elt | 998 client, session, request, jingle_elt |
985 ): | 999 ): |
986 return | 1000 return |
1015 @param confirm_results(list[bool]): all True if session is accepted | 1029 @param confirm_results(list[bool]): all True if session is accepted |
1016 @param session(dict): session data | 1030 @param session(dict): session data |
1017 @param jingle_elt(domish.Element): jingle data of this session | 1031 @param jingle_elt(domish.Element): jingle data of this session |
1018 @param client: %(doc_client)s | 1032 @param client: %(doc_client)s |
1019 """ | 1033 """ |
1034 del session["jingle_elt"] | |
1020 confirmed = all(confirm_results) | 1035 confirmed = all(confirm_results) |
1021 if not confirmed: | 1036 if not confirmed: |
1022 return self.terminate(client, XEP_0166.REASON_DECLINE, session) | 1037 return self.terminate(client, XEP_0166.REASON_DECLINE, session) |
1023 | 1038 |
1024 iq_elt, jingle_elt = self._build_jingle_elt( | 1039 iq_elt, jingle_elt = self._build_jingle_elt( |
1025 client, session, XEP_0166.A_SESSION_ACCEPT | 1040 client, session, XEP_0166.A_SESSION_ACCEPT |
1026 ) | 1041 ) |
1027 jingle_elt["responder"] = session['local_jid'].full() | 1042 jingle_elt["responder"] = session['local_jid'].full() |
1043 session["jingle_elt"] = jingle_elt | |
1028 | 1044 |
1029 # contents | 1045 # contents |
1030 | 1046 |
1031 def addElement(domish_elt, content_elt): | 1047 def addElement(domish_elt, content_elt): |
1032 content_elt.addChild(domish_elt) | 1048 content_elt.addChild(domish_elt) |
1074 session, | 1090 session, |
1075 app_method_name=None, | 1091 app_method_name=None, |
1076 elements=False, | 1092 elements=False, |
1077 ) | 1093 ) |
1078 ) | 1094 ) |
1095 d_list.addCallback(lambda __: session.pop("jingle_elt")) | |
1079 d_list.addCallback(lambda __: iq_elt.send()) | 1096 d_list.addCallback(lambda __: iq_elt.send()) |
1080 | 1097 |
1081 def change_state(__, session): | 1098 def change_state(__, session): |
1082 session["state"] = STATE_ACTIVE | 1099 session["state"] = STATE_ACTIVE |
1083 | 1100 |
1090 d_list.addErrback(self._iq_error, session["id"], client) | 1107 d_list.addErrback(self._iq_error, session["id"], client) |
1091 return d_list | 1108 return d_list |
1092 | 1109 |
1093 def on_session_terminate(self, client, request, jingle_elt, session): | 1110 def on_session_terminate(self, client, request, jingle_elt, session): |
1094 # TODO: check reason, display a message to user if needed | 1111 # TODO: check reason, display a message to user if needed |
1095 log.debug("Jingle Session {} terminated".format(session["id"])) | 1112 log.debug(f"Jingle Session {session['id']} terminated") |
1096 try: | 1113 try: |
1097 reason_elt = next(jingle_elt.elements(NS_JINGLE, "reason")) | 1114 reason_elt = next(jingle_elt.elements(NS_JINGLE, "reason")) |
1098 except StopIteration: | 1115 except StopIteration: |
1099 log.warning("No reason given for session termination") | 1116 log.warning("No reason given for session termination") |
1100 reason_elt = jingle_elt.addElement("reason") | 1117 reason_elt = jingle_elt.addElement("reason") |
1133 | 1150 |
1134 # at this point we can send the <iq/> result to confirm reception of the request | 1151 # at this point we can send the <iq/> result to confirm reception of the request |
1135 client.send(xmlstream.toResponse(request, "result")) | 1152 client.send(xmlstream.toResponse(request, "result")) |
1136 # and change the state | 1153 # and change the state |
1137 session["state"] = STATE_ACTIVE | 1154 session["state"] = STATE_ACTIVE |
1155 session["jingle_elt"] = jingle_elt | |
1138 | 1156 |
1139 await defer.DeferredList(self._call_plugins( | 1157 await defer.DeferredList(self._call_plugins( |
1140 client, | 1158 client, |
1141 XEP_0166.A_PREPARE_INITIATOR, | 1159 XEP_0166.A_PREPARE_INITIATOR, |
1142 session, | 1160 session, |
1152 negociate_dlist.addCallback( | 1170 negociate_dlist.addCallback( |
1153 lambda __: self._call_plugins( | 1171 lambda __: self._call_plugins( |
1154 client, XEP_0166.A_START, session, app_method_name=None, elements=False | 1172 client, XEP_0166.A_START, session, app_method_name=None, elements=False |
1155 ) | 1173 ) |
1156 ) | 1174 ) |
1175 negociate_dlist.addCallback(lambda __: session.pop("jingle_elt")) | |
1157 | 1176 |
1158 def _on_session_cb(self, result, client, request, jingle_elt, session): | 1177 def _on_session_cb(self, result, client, request, jingle_elt, session): |
1159 client.send(xmlstream.toResponse(request, "result")) | 1178 client.send(xmlstream.toResponse(request, "result")) |
1160 | 1179 |
1161 def _on_session_eb(self, failure_, client, request, jingle_elt, session): | 1180 def _on_session_eb(self, failure_, client, request, jingle_elt, session): |