11import traceback
22from copy import deepcopy
3- from datetime import datetime
3+ from datetime import datetime , timedelta
44from distutils .util import strtobool
5+ from io import BytesIO
56from itertools import chain
6- from typing import Any , Dict , Mapping
7+ from typing import Any , Dict , Mapping , Optional , Tuple
78
89from lxml import etree
910from lxml .builder import ElementMaker
10- from lxml .etree import DocumentInvalid
11+ from lxml .etree import DocumentInvalid , ElementTree
1112from xmlsec .crypto import CertDict
1213
1314from .constants import ATTRS , NF_URI , NS , config
@@ -80,15 +81,15 @@ def find_merge_strategy(strategy_name):
8081
8182
8283def parse_saml_metadata (
83- source ,
84- key = None ,
85- base_url = None ,
86- fail_on_error = False ,
87- filter_invalid = True ,
84+ source : BytesIO ,
85+ key : Optional [ str ] = None ,
86+ base_url : Optional [ str ] = None ,
87+ fail_on_error : bool = False ,
88+ filter_invalid : bool = True ,
8889 cleanup = None ,
89- validate = True ,
90- validation_errors = None ,
91- ):
90+ validate : bool = True ,
91+ validation_errors : Optional [ Dict [ str , Any ]] = None ,
92+ ) -> Tuple [ ElementTree , Optional [ timedelta ], Optional [ Exception ]] :
9293 """Parse a piece of XML and return an EntitiesDescriptor element after validation.
9394
9495 :param source: a file-like object containing SAML metadata
@@ -100,6 +101,7 @@ def parse_saml_metadata(
100101 :param validation_errors: A dict that will be used to return validation errors to the caller
101102 :param cleanup: A list of callables that can be used to pre-process parsed metadata before validation. Use as a clue-bat.
102103
104+ :return: Tuple with t (ElementTree), expire_time_offset, exception
103105 """
104106
105107 if validation_errors is None :
@@ -283,7 +285,7 @@ def _update_entities(_t, **kwargs):
283285add_parser (MDServiceListParser ())
284286
285287
286- def metadata_expiration (t ) :
288+ def metadata_expiration (t : ElementTree ) -> Optional [ timedelta ] :
287289 relt = root (t )
288290 if relt .tag in ('{%s}EntityDescriptor' % NS ['md' ], '{%s}EntitiesDescriptor' % NS ['md' ]):
289291 cache_duration = config .default_cache_duration
@@ -316,7 +318,11 @@ def filter_invalids_from_document(t, base_url, validation_errors):
316318 return t
317319
318320
319- def filter_or_validate (t , filter_invalid = False , base_url = "" , source = None , validation_errors = dict ()):
321+ def filter_or_validate (
322+ t , filter_invalid : bool = False , base_url : str = "" , source = None , validation_errors : Optional [Dict [str , Any ]] = None
323+ ):
324+ if validation_errors is None :
325+ validation_errors = {}
320326 log .debug ("Filtering invalids from {}" .format (base_url ))
321327 if filter_invalid :
322328 t = filter_invalids_from_document (t , base_url = base_url , validation_errors = validation_errors )
0 commit comments