1
1
import json
2
2
import logging
3
3
4
+ from urllib .parse import quote
5
+
4
6
from mauth_client .authenticator import LocalAuthenticator
5
7
from mauth_client .config import Config
6
8
from mauth_client .consts import (
@@ -22,17 +24,17 @@ def __init__(self, app, exempt=None):
22
24
self .exempt = exempt .copy () if exempt else set ()
23
25
24
26
def __call__ (self , environ , start_response ):
25
- req = environ [ "werkzeug.request" ]
27
+ path = environ . get ( "PATH_INFO" , "" )
26
28
27
- if req . path in self .exempt :
29
+ if path in self .exempt :
28
30
return self .app (environ , start_response )
29
31
30
32
signable = RequestSignable (
31
- method = req . method ,
32
- url = req . url ,
33
+ method = environ [ "REQUEST_METHOD" ] ,
34
+ url = self . _extract_url ( environ ) ,
33
35
body = self ._read_body (environ ),
34
36
)
35
- signed = Signed .from_headers (dict ( req . headers ))
37
+ signed = Signed .from_headers (self . _extract_headers ( environ ))
36
38
authenticator = LocalAuthenticator (signable , signed , logger )
37
39
is_authentic , status , message = authenticator .is_authentic ()
38
40
@@ -60,3 +62,54 @@ def _read_body(self, environ):
60
62
body = input .read ()
61
63
input .seek (0 )
62
64
return body
65
+
66
+ def _extract_headers (self , environ ):
67
+ """
68
+ Adapted from werkzeug package: https://github.com/pallets/werkzeug
69
+ """
70
+ headers = {}
71
+
72
+ # don't care to titleize the header keys since
73
+ # the Signed class is just going to lowercase them
74
+ for k , v in environ .items ():
75
+ if k .startswith ("HTTP_" ) and k not in {
76
+ "HTTP_CONTENT_TYPE" ,
77
+ "HTTP_CONTENT_LENGTH" ,
78
+ }:
79
+ key = k [5 :].replace ("_" , "-" )
80
+ headers [key ] = v
81
+ elif k in {"CONTENT_TYPE" , "CONTENT_LENGTH" }:
82
+ key = k .replace ("_" , "-" )
83
+ headers [key ] = v
84
+
85
+ return headers
86
+
87
+ def _extract_url (self , environ ):
88
+ """
89
+ Adapted from https://peps.python.org/pep-0333/#url-reconstruction
90
+ """
91
+ scheme = environ ["wsgi.url_scheme" ]
92
+ url_parts = [scheme , "://" ]
93
+ http_host = environ .get ("HTTP_HOST" )
94
+
95
+ if http_host :
96
+ url_parts .append (http_host )
97
+ else :
98
+ url_parts .append (environ ["SERVER_NAME" ])
99
+ port = environ ["SERVER_PORT" ]
100
+
101
+ if (
102
+ (scheme == "https" and port != 443 )
103
+ or
104
+ (scheme != "https" and port != 80 )
105
+ ):
106
+ url_parts .append (f":{ port } " )
107
+
108
+ url_parts .append (quote (environ .get ("SCRIPT_NAME" , "" )))
109
+ url_parts .append (quote (environ .get ("PATH_INFO" ), "" ))
110
+
111
+ qs = environ .get ("QUERY_STRING" )
112
+ if qs :
113
+ url_parts .append (f"?{ qs } " )
114
+
115
+ return "" .join (url_parts )
0 commit comments