Coverage for /pythoncovmergedfiles/medio/medio/usr/local/lib/python3.8/site-packages/httplib2/auth.py: 52%

40 statements  

« prev     ^ index     » next       coverage.py v7.3.2, created at 2023-12-08 06:51 +0000

1import base64 

2import re 

3 

4import pyparsing as pp 

5 

6from .error import * 

7 

8 

9try: # pyparsing>=3.0.0 

10 downcaseTokens = pp.common.downcaseTokens 

11except AttributeError: 

12 downcaseTokens = pp.downcaseTokens 

13 

14UNQUOTE_PAIRS = re.compile(r"\\(.)") 

15unquote = lambda s, l, t: UNQUOTE_PAIRS.sub(r"\1", t[0][1:-1]) 

16 

17# https://tools.ietf.org/html/rfc7235#section-1.2 

18# https://tools.ietf.org/html/rfc7235#appendix-B 

19tchar = "!#$%&'*+-.^_`|~" + pp.nums + pp.alphas 

20token = pp.Word(tchar).setName("token") 

21token68 = pp.Combine(pp.Word("-._~+/" + pp.nums + pp.alphas) + pp.Optional(pp.Word("=").leaveWhitespace())).setName( 

22 "token68" 

23) 

24 

25quoted_string = pp.dblQuotedString.copy().setName("quoted-string").setParseAction(unquote) 

26auth_param_name = token.copy().setName("auth-param-name").addParseAction(downcaseTokens) 

27auth_param = auth_param_name + pp.Suppress("=") + (quoted_string | token) 

28params = pp.Dict(pp.delimitedList(pp.Group(auth_param))) 

29 

30scheme = token("scheme") 

31challenge = scheme + (params("params") | token68("token")) 

32 

33authentication_info = params.copy() 

34www_authenticate = pp.delimitedList(pp.Group(challenge)) 

35 

36 

37def _parse_authentication_info(headers, headername="authentication-info"): 

38 """https://tools.ietf.org/html/rfc7615 

39 """ 

40 header = headers.get(headername, "").strip() 

41 if not header: 

42 return {} 

43 try: 

44 parsed = authentication_info.parseString(header) 

45 except pp.ParseException as ex: 

46 # print(ex.explain(ex)) 

47 raise MalformedHeader(headername) 

48 

49 return parsed.asDict() 

50 

51 

52def _parse_www_authenticate(headers, headername="www-authenticate"): 

53 """Returns a dictionary of dictionaries, one dict per auth_scheme.""" 

54 header = headers.get(headername, "").strip() 

55 if not header: 

56 return {} 

57 try: 

58 parsed = www_authenticate.parseString(header) 

59 except pp.ParseException as ex: 

60 # print(ex.explain(ex)) 

61 raise MalformedHeader(headername) 

62 

63 retval = { 

64 challenge["scheme"].lower(): challenge["params"].asDict() 

65 if "params" in challenge 

66 else {"token": challenge.get("token")} 

67 for challenge in parsed 

68 } 

69 return retval