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):