2929from etptypes .energistics .etp .v12 .protocol .core .close_session import (
3030 CloseSession ,
3131)
32+ from etptypes .energistics .etp .v12 .protocol .core .authorize_response import (
33+ AuthorizeResponse ,
34+ )
35+ from etptypes .energistics .etp .v12 .protocol .core .authorize import Authorize
3236from etptypes .energistics .etp .v12 .protocol .core .open_session import OpenSession
3337from etptypes .energistics .etp .v12 .protocol .core .request_session import (
3438 RequestSession ,
4145 InvalidMessageError ,
4246 UnsupportedProtocolError ,
4347 NotSupportedError ,
48+ InvalidStateError ,
49+ AuthorizationRequired ,
4450)
4551from etpproto .messages import Message
4652from etpproto .utils import ProtocolDict , get_all_etp_protocol_classes
@@ -136,6 +142,8 @@ class ETPConnection:
136142
137143 is_connected : bool = field (default = False )
138144
145+ auth_required : bool = field (default = False )
146+
139147 message_id : int = field (default = 1 )
140148
141149 # ______ __ __ ________ __
@@ -164,6 +172,7 @@ def __post_init__(self):
164172 self .message_id = 1
165173 elif self .connection_type == ConnectionType .CLIENT :
166174 self .message_id = 2
175+ self .auth_required = False # auth is only required on server side
167176
168177 def _handle_answer_and_error (
169178 self ,
@@ -189,158 +198,182 @@ async def _handle_message_generator(
189198 if (
190199 etp_input_msg is not None and etp_input_msg .header is not None
191200 ): # si pas un message none
192- if (
193- isinstance (etp_input_msg .body , RequestSession )
194- or isinstance (etp_input_msg .body , OpenSession )
195- or self .is_connected
201+ if not self .auth_required or (
202+ self .client_info is not None
203+ and (
204+ self .client_info .authenticated
205+ or (
206+ isinstance (etp_input_msg .body , Authorize )
207+ or isinstance (etp_input_msg .body , AuthorizeResponse )
208+ )
209+ )
196210 ):
197- current_msg_id = etp_input_msg .header .message_id
198-
199- # if requires acknowledge :
200- if etp_input_msg .is_asking_acknowledge () and not isinstance (
201- etp_input_msg .body , Acknowledge
211+ if (
212+ # isinstance(etp_input_msg.body, RequestSession)
213+ # or isinstance(etp_input_msg.body, OpenSession)
214+ etp_input_msg .header .protocol
215+ == CommunicationProtocol .CORE .value
216+ or self .is_connected
202217 ):
203- yield Message .get_object_message (
204- Acknowledge (),
205- correlation_id = current_msg_id ,
206- msg_id = self .consume_msg_id (),
207- )
208- # time.sleep(3)
209-
210- # only if the user is connected or request for an OpenSession or if the message is not the full message
218+ current_msg_id = etp_input_msg .header .message_id
211219
212- if self .is_connected and isinstance (
213- etp_input_msg .body , CloseSession
214- ):
215- logging .debug (
216- f"{ self .client_info .ip } : CloseSession recieved"
217- )
218- self .is_connected = False
219- else :
220- # Test if it is an Open/Request session
220+ # if requires acknowledge :
221221 if (
222- isinstance (etp_input_msg .body , RequestSession )
223- and self .connection_type == ConnectionType .SERVER
224- ) or (
225- isinstance (etp_input_msg .body , OpenSession )
226- and self .connection_type == ConnectionType .CLIENT
222+ etp_input_msg .is_asking_acknowledge ()
223+ and not isinstance (etp_input_msg .body , Acknowledge )
227224 ):
228- self .is_connected = True
229- self .client_info .negotiate (etp_input_msg .body )
230-
231- # logging.debug(etp_input_msg, etp_input_msg.is_chunk_msg(), etp_input_msg.is_chunk_msg_referencer())
232- # On test si c'est un message de BLOB qu'il faut mettre en cache :
233- if etp_input_msg .is_multipart_msg () and (
234- etp_input_msg .is_chunk_msg ()
235- or etp_input_msg .is_chunk_msg_referencer ()
225+ yield Message .get_object_message (
226+ Acknowledge (),
227+ correlation_id = current_msg_id ,
228+ msg_id = self .consume_msg_id (),
229+ )
230+ # time.sleep(3)
231+
232+ # only if the user is connected or request for an OpenSession or if the message is not the full message
233+
234+ if self .is_connected and isinstance (
235+ etp_input_msg .body , CloseSession
236236 ):
237- cache_id = (
238- etp_input_msg .header .correlation_id
239- if etp_input_msg .header .correlation_id != 0
240- else etp_input_msg .header .message_id
237+ logging .debug (
238+ f"{ self .client_info .ip } : CloseSession recieved"
241239 )
242- if cache_id not in self .chunk_msg_cache :
243- self .chunk_msg_cache [cache_id ] = []
244- self .chunk_msg_cache [cache_id ].append (etp_input_msg )
245-
246- # si final on rassemble et on handle.
247- if etp_input_msg .is_final_msg ():
248- logging .debug (
249- f"Reassemble chunks :{ self .chunk_msg_cache [cache_id ]} " ,
240+ self .is_connected = False
241+ else :
242+ # Test if it is an Open/Request session
243+ if (
244+ isinstance (etp_input_msg .body , RequestSession )
245+ and self .connection_type == ConnectionType .SERVER
246+ ) or (
247+ isinstance (etp_input_msg .body , OpenSession )
248+ and self .connection_type == ConnectionType .CLIENT
249+ ):
250+ self .is_connected = True
251+ self .client_info .negotiate (etp_input_msg .body )
252+
253+ # logging.debug(etp_input_msg, etp_input_msg.is_chunk_msg(), etp_input_msg.is_chunk_msg_referencer())
254+ # On test si c'est un message de BLOB qu'il faut mettre en cache :
255+ if etp_input_msg .is_multipart_msg () and (
256+ etp_input_msg .is_chunk_msg ()
257+ or etp_input_msg .is_chunk_msg_referencer ()
258+ ):
259+ cache_id = (
260+ etp_input_msg .header .correlation_id
261+ if etp_input_msg .header .correlation_id != 0
262+ else etp_input_msg .header .message_id
263+ )
264+ if cache_id not in self .chunk_msg_cache :
265+ self .chunk_msg_cache [cache_id ] = []
266+ self .chunk_msg_cache [cache_id ].append (
267+ etp_input_msg
250268 )
269+
270+ # si final on rassemble et on handle.
271+ if etp_input_msg .is_final_msg ():
272+ logging .debug (
273+ f"Reassemble chunks :{ self .chunk_msg_cache [cache_id ]} " ,
274+ )
275+ try :
276+ async for msg in self ._handle_message_generator (
277+ Message .reassemble_chunk (
278+ self .chunk_msg_cache [cache_id ]
279+ )
280+ ):
281+ if msg is not None :
282+ yield msg
283+ else :
284+ if (
285+ cache_id
286+ not in self .error_msg_cache
287+ ):
288+ self .error_msg_cache [
289+ cache_id
290+ ] = []
291+ self .error_msg_cache [
292+ cache_id
293+ ].append (
294+ InvalidMessageError ().to_etp_message (
295+ msg_id = self .consume_msg_id ()
296+ )
297+ )
298+
299+ except Exception as e :
300+ logging .error (
301+ f"{ self .client_info .ip } : _SERVER_ not handled exception" ,
302+ )
303+ raise e
304+
305+ if cache_id in self .error_msg_cache :
306+ for err_msg in self .error_msg_cache [
307+ cache_id
308+ ]:
309+ if err_msg is not None :
310+ yield err_msg
311+ self .error_msg_cache .pop (cache_id )
312+
313+ if cache_id in self .chunk_msg_cache :
314+ self .chunk_msg_cache .pop (cache_id )
315+
316+ else : # ce n'est pas un message envoye en chunks
317+ # now try to have an answer
251318 try :
252- async for msg in self ._handle_message_generator (
253- Message .reassemble_chunk (
254- self .chunk_msg_cache [cache_id ]
319+ # Test si le protocol est supporte par le serveur
320+ if (
321+ CommunicationProtocol (
322+ etp_input_msg .header .protocol
255323 )
324+ in self .transition_table
256325 ):
257- if msg is not None :
258- yield msg
259- else :
260- if (
261- cache_id
262- not in self .error_msg_cache
326+ # demande la reponse au protocols du serveur
327+ try :
328+ async for handled in self .transition_table [
329+ CommunicationProtocol (
330+ etp_input_msg .header .protocol
331+ )
332+ ].handle_message (
333+ etp_object = etp_input_msg .body ,
334+ msg_header = etp_input_msg .header ,
335+ client_info = self .client_info ,
263336 ):
264- self .error_msg_cache [ cache_id ] = []
265- self . error_msg_cache [ cache_id ]. append (
266- InvalidMessageError (). to_etp_message (
267- msg_id = self . consume_msg_id ()
337+ yield self ._handle_answer_and_error (
338+ msg = handled ,
339+ req_msg = etp_input_msg ,
340+ request_msg_id = current_msg_id ,
268341 )
342+ except ETPError as exp_invalid_msg_type :
343+ yield exp_invalid_msg_type .to_etp_message (
344+ msg_id = self .consume_msg_id (),
345+ correlation_id = current_msg_id ,
269346 )
270-
271- except Exception as e :
347+ else :
348+ logging .debug (
349+ f"{ self .client_info .ip } : #handle_msg : unkown protocol id : { str (etp_input_msg .header .protocol )} "
350+ )
351+ raise UnsupportedProtocolError (
352+ etp_input_msg .header .protocol
353+ )
354+ except ETPError as etp_err :
272355 logging .error (
273- f"{ self .client_info .ip } : _SERVER_ not handled exception" ,
356+ f"{ self .client_info .ip } : _SERVER_ internal error : { etp_err } "
274357 )
275- raise e
276-
277- if cache_id in self .error_msg_cache :
278- for err_msg in self .error_msg_cache [cache_id ]:
279- if err_msg is not None :
280- yield err_msg
281- self .error_msg_cache .pop (cache_id )
282-
283- if cache_id in self .chunk_msg_cache :
284- self .chunk_msg_cache .pop (cache_id )
285-
286- else : # ce n'est pas un message envoye en chunks
287- # now try to have an answer
288- try :
289- # Test si le protocol est supporte par le serveur
290- if (
291- CommunicationProtocol (
292- etp_input_msg .header .protocol
293- )
294- in self .transition_table
295- ):
296- # demande la reponse au protocols du serveur
297- try :
298- async for handled in self .transition_table [
299- CommunicationProtocol (
300- etp_input_msg .header .protocol
301- )
302- ].handle_message (
303- etp_object = etp_input_msg .body ,
304- msg_header = etp_input_msg .header ,
305- client_info = self .client_info ,
306- ):
307- yield self ._handle_answer_and_error (
308- msg = handled ,
309- req_msg = etp_input_msg ,
310- request_msg_id = current_msg_id ,
311- )
312- except ETPError as exp_invalid_msg_type :
313- yield exp_invalid_msg_type .to_etp_message (
358+ yield self ._handle_answer_and_error (
359+ msg = etp_err .to_etp_message (
314360 msg_id = self .consume_msg_id (),
315361 correlation_id = current_msg_id ,
316- )
317-
318- else :
319- logging .debug (
320- f"{ self .client_info .ip } : #handle_msg : unkown protocol id : { str (etp_input_msg .header .protocol )} "
362+ ),
363+ req_msg = etp_input_msg ,
364+ request_msg_id = current_msg_id ,
321365 )
322- raise UnsupportedProtocolError (
323- etp_input_msg .header .protocol
366+ except Exception as e :
367+ logging .error (
368+ f"{ self .client_info .ip } : _SERVER_ not handled exception" ,
324369 )
325- except ETPError as etp_err :
326- logging .error (
327- f"{ self .client_info .ip } : _SERVER_ internal error : { etp_err } "
328- )
329- yield self ._handle_answer_and_error (
330- msg = etp_err .to_etp_message (
331- msg_id = self .consume_msg_id (),
332- correlation_id = current_msg_id ,
333- ),
334- req_msg = etp_input_msg ,
335- request_msg_id = current_msg_id ,
336- )
337- except Exception as e :
338- logging .error (
339- f"{ self .client_info .ip } : _SERVER_ not handled exception" ,
340- )
341- raise e
342- else : # not connected
343- yield InvalidMessageError ().to_etp_message (
370+ raise e
371+ else : # not connected
372+ yield InvalidStateError ().to_etp_message (
373+ msg_id = self .consume_msg_id ()
374+ )
375+ else : # not authenticated
376+ yield AuthorizationRequired ().to_etp_message (
344377 msg_id = self .consume_msg_id ()
345378 )
346379 else : # null message
@@ -445,7 +478,7 @@ def get_supported_protocol_list(
445478 ) -> List [SupportedProtocol ]:
446479 supported_protocols : List [SupportedProtocol ] = []
447480 for protocol in cls .transition_table :
448- if protocol .value != protocol .CORE :
481+ if protocol .value != CommunicationProtocol .CORE :
449482 supported_protocols .append (
450483 SupportedProtocol (
451484 protocol = protocol .value ,
0 commit comments