14
14
import time
15
15
import urllib .parse
16
16
from collections import defaultdict
17
+ from typing import Dict
17
18
18
19
19
20
class OAuthHandler (http .server .BaseHTTPRequestHandler ):
@@ -23,7 +24,7 @@ class OAuthHandler(http.server.BaseHTTPRequestHandler):
23
24
documentation for BaseHTTPRequestHandler.
24
25
"""
25
26
26
- JsonObject = dict [str , object ] # TypeAlias is not available until 3.10
27
+ JsonObject = Dict [str , object ] # TypeAlias is not available until 3.10
27
28
28
29
def _check_issuer (self ):
29
30
"""
@@ -35,14 +36,16 @@ def _check_issuer(self):
35
36
)
36
37
self ._parameterized = self .path .startswith ("/param/" )
37
38
39
+ # Strip off the magic path segment. (The more readable
40
+ # str.removeprefix()/removesuffix() aren't available until Py3.9.)
38
41
if self ._alt_issuer :
39
42
# The /alternate issuer uses IETF-style .well-known URIs.
40
43
if self .path .startswith ("/.well-known/" ):
41
- self .path = self .path . removesuffix ("/alternate" )
44
+ self .path = self .path [: - len ("/alternate" )]
42
45
else :
43
- self .path = self .path . removeprefix ("/alternate" )
46
+ self .path = self .path [ len ("/alternate" ) :]
44
47
elif self ._parameterized :
45
- self .path = self .path . removeprefix ("/param" )
48
+ self .path = self .path [ len ("/param" ) :]
46
49
47
50
def _check_authn (self ):
48
51
"""
@@ -58,8 +61,10 @@ def _check_authn(self):
58
61
if method != "Basic" :
59
62
raise RuntimeError (f"client used { method } auth; expected Basic" )
60
63
61
- username = urllib .parse .quote_plus (self .client_id )
62
- password = urllib .parse .quote_plus (secret )
64
+ # TODO: Remove "~" from the safe list after Py3.6 support is removed.
65
+ # 3.7 does this by default.
66
+ username = urllib .parse .quote_plus (self .client_id , safe = "~" )
67
+ password = urllib .parse .quote_plus (secret , safe = "~" )
63
68
expected_creds = f"{ username } :{ password } "
64
69
65
70
if creds .encode () != base64 .b64encode (expected_creds .encode ()):
@@ -83,7 +88,7 @@ def do_GET(self):
83
88
84
89
self ._send_json (resp )
85
90
86
- def _parse_params (self ) -> dict [str , str ]:
91
+ def _parse_params (self ) -> Dict [str , str ]:
87
92
"""
88
93
Parses apart the form-urlencoded request body and returns the resulting
89
94
dict. For use by do_POST().
@@ -316,11 +321,14 @@ def authorization(self) -> JsonObject:
316
321
return resp
317
322
318
323
def token (self ) -> JsonObject :
319
- if err := self ._get_param ("error_code" , None ):
324
+ err = self ._get_param ("error_code" , None )
325
+ if err :
320
326
self ._response_code = self ._get_param ("error_status" , 400 )
321
327
322
328
resp = {"error" : err }
323
- if desc := self ._get_param ("error_desc" , "" ):
329
+
330
+ desc = self ._get_param ("error_desc" , "" )
331
+ if desc :
324
332
resp ["error_description" ] = desc
325
333
326
334
return resp
0 commit comments