Skip to content

Commit c8c2ab1

Browse files
authored
Merge pull request #2 from GodwinShen/1-new-feature-create-internal-request-handler
Created internal_request_handler function to reduce redundant code an…
2 parents bbf657d + 9d0b895 commit c8c2ab1

File tree

1 file changed

+74
-215
lines changed

1 file changed

+74
-215
lines changed

flaskProxyWithAuth.py

Lines changed: 74 additions & 215 deletions
Original file line numberDiff line numberDiff line change
@@ -9,12 +9,48 @@
99

1010
#load_dotenv()
1111

12+
def internal_request_handler(request, target_url="http://localhost:80"):
13+
"""
14+
Internal request handler to forward requests to the docker containers.
15+
"""
16+
# Construct the new request to the target service
17+
resp = requests.request(
18+
method=request.method,
19+
url=target_url,
20+
headers={key: value for (key, value) in request.headers if key != 'Host'},
21+
data=request.get_data(),
22+
cookies=request.cookies,
23+
allow_redirects=True,
24+
params=request.args
25+
)
26+
27+
# Create a Flask response object from the target service's response
28+
excluded_headers = ['content-encoding', 'content-length', 'transfer-encoding', 'connection']
29+
headers = [(name, value) for (name, value) in resp.raw.headers.items() if name.lower() not in excluded_headers]
30+
response = Response(resp.content, resp.status_code, headers)
31+
# Fix for JS files
32+
if request.path.endswith('.js'):
33+
response.headers["Content-Type"] = "application/javascript"
34+
35+
response.headers["Access-Control-Allow-Origin"] = "*"
36+
response.headers["Access-Control-Allow-Methods"] = "GET, POST, PUT, DELETE, OPTIONS"
37+
response.headers["Access-Control-Allow-Headers"] = "Content-Type, Authorization"
38+
39+
print(f"Response from target URL: {target_url}")
40+
print(f"Response status code: {resp.status_code}")
41+
print(f"Response headers: {headers}")
42+
43+
return response
44+
45+
1246
app = Flask(__name__)
1347
app.secret_key = os.getenv("FLASK_SECRET_KEY")
1448
app.wsgi_app = ProxyFix(
1549
app.wsgi_app, x_for=1, x_proto=1, x_host=1, x_prefix=1
1650
)
1751

52+
internal_app_port = os.getenv("INTERNAL_APPLICATION_PORT", 80)
53+
1854
oauth = OAuth(app)
1955
oauth.register(
2056
name="keycloak",
@@ -29,38 +65,18 @@ def index():
2965
user = session.get("user")
3066
if user:
3167
#return jsonify({"message": "You are authenticated!", "user": user}), 200
32-
target_url = "http://localhost:80/"
33-
# Construct the new request to the target service
34-
resp = requests.request(
35-
method=request.method,
36-
url=target_url,
37-
headers={key: value for (key, value) in request.headers if key != 'Host'},
38-
data=request.get_data(),
39-
cookies=request.cookies,
40-
allow_redirects=True,
41-
params=request.args
42-
)
43-
44-
# Create a Flask response object from the target service's response
45-
excluded_headers = ['content-encoding', 'content-length', 'transfer-encoding', 'connection']
46-
headers = [(name, value) for (name, value) in resp.raw.headers.items() if name.lower() not in excluded_headers]
47-
response = Response(resp.content, resp.status_code, headers)
48-
# Fix for JS files
49-
if request.path.endswith('.js'):
50-
response.headers["Content-Type"] = "application/javascript"
51-
52-
response.headers["Access-Control-Allow-Origin"] = "*"
53-
response.headers["Access-Control-Allow-Methods"] = "GET, POST, PUT, DELETE, OPTIONS"
54-
response.headers["Access-Control-Allow-Headers"] = "Content-Type, Authorization"
55-
56-
return response
68+
target_url = f"http://localhost:{internal_app_port}/"
69+
70+
return internal_request_handler(request, target_url)
5771
else:
58-
return render_template_string('''
59-
<h1>Hello, you are not logged in.</h1>
60-
<form action="{{ url_for('login_flask') }}" method="post">
61-
<button type="submit">Login</button>
62-
</form>
63-
''')
72+
redirect_uri = url_for("oauth2", _external=True)
73+
return oauth.keycloak.authorize_redirect(redirect_uri)
74+
# return render_template_string('''
75+
# <h1>Hello, you are not logged in.</h1>
76+
# <form action="{{ url_for('login_flask') }}" method="post">
77+
# <button type="submit">Login</button>
78+
# </form>
79+
# ''')
6480

6581
@app.route("/<string:path0>/<string:path1>/<string:path2>/<string:filename>", methods=["GET", "POST", "PUT", "DELETE"])
6682
def _app(path0, path1, path2, filename):
@@ -74,59 +90,19 @@ def _app(path0, path1, path2, filename):
7490
#return jsonify({"message": "You are authenticated!", "user": user}), 200
7591
#if path1=='..':
7692
# path1 = 'immutable' # this is such a kludge, we'll see if it works
77-
target_url = f'http://localhost:80/{path0}/{path1}/{path2}/{filename}'
78-
# Construct the new request to the target service
79-
resp = requests.request(
80-
method=request.method,
81-
url=target_url,
82-
headers={key: value for (key, value) in request.headers if key != 'Host'},
83-
data=request.get_data(),
84-
cookies=request.cookies,
85-
allow_redirects=True,
86-
params=request.args
87-
)
88-
89-
# Create a Flask response object from the target service's response
90-
excluded_headers = ['content-encoding', 'content-length', 'transfer-encoding', 'connection']
91-
headers = [(name, value) for (name, value) in resp.raw.headers.items() if name.lower() not in excluded_headers]
92-
response = Response(resp.content, resp.status_code, headers)
93-
94-
response.headers["Access-Control-Allow-Origin"] = "*"
95-
response.headers["Access-Control-Allow-Methods"] = "GET, POST, PUT, DELETE, OPTIONS"
96-
response.headers["Access-Control-Allow-Headers"] = "Content-Type, Authorization"
97-
98-
return response
93+
target_url = f'http://localhost:{internal_app_port}/{path0}/{path1}/{path2}/{filename}'
94+
95+
return internal_request_handler(request, target_url)
9996
else:
10097
return jsonify({"message": "You are not logged in."}), 401
10198

10299
@app.route("/<string:path1>/<string:path2>", methods=["GET", "POST", "PUT", "DELETE"])
103100
def _app2(path1, path2):
104101
user = session.get("user")
105102
if user:
106-
target_url = f'http://localhost:80/{path1}/{path2}'
107-
# Construct the new request to the target service
108-
resp = requests.request(
109-
method=request.method,
110-
url=target_url,
111-
headers={key: value for (key, value) in request.headers if key != 'Host'},
112-
data=request.get_data(),
113-
cookies=request.cookies,
114-
allow_redirects=True,
115-
params=request.args
116-
)
117-
118-
# Create a Flask response object from the target service's response
119-
excluded_headers = ['content-encoding', 'content-length', 'transfer-encoding', 'connection']
120-
headers = [(name, value) for (name, value) in resp.raw.headers.items() if name.lower() not in excluded_headers]
121-
response = Response(resp.content, resp.status_code, headers)
122-
if path2.endswith('.js'):
123-
response.headers["Content-Type"] = "application/javascript"
124-
125-
response.headers["Access-Control-Allow-Origin"] = "*"
126-
response.headers["Access-Control-Allow-Methods"] = "GET, POST, PUT, DELETE, OPTIONS"
127-
response.headers["Access-Control-Allow-Headers"] = "Content-Type, Authorization"
128-
129-
return response
103+
target_url = f'http://localhost:{internal_app_port}/{path1}/{path2}'
104+
105+
return internal_request_handler(request, target_url)
130106
else:
131107
return jsonify({"message": "You are not logged in."}), 401
132108

@@ -138,69 +114,19 @@ def _app3(data):
138114
allowed_paths = ['plans', 'models', 'scheduling', 'sequencing', 'constraints', 'tags', 'external_sources', 'dictionaries', 'expansion', 'parcels', 'documentation', 'gateway', 'about']
139115
if user:
140116
#if user and (('__data.json' in data) or ('favicon.svg' in data) or (data in allowed_paths) ):
141-
target_url = f'http://localhost:80/{data}'
142-
# Construct the new request to the target service
143-
resp = requests.request(
144-
method=request.method,
145-
url=target_url,
146-
headers={key: value for (key, value) in request.headers if key != 'Host'},
147-
data=request.get_data(),
148-
cookies=request.cookies,
149-
allow_redirects=True,
150-
params=request.args
151-
)
152-
153-
# Create a Flask response object from the target service's response
154-
excluded_headers = ['content-encoding', 'content-length', 'transfer-encoding', 'connection']
155-
headers = [(name, value) for (name, value) in resp.raw.headers.items() if name.lower() not in excluded_headers]
156-
response = Response(resp.content, resp.status_code, headers)
157-
if data.endswith('.js'):
158-
response.headers["Content-Type"] = "application/javascript"
159-
160-
response.headers["Access-Control-Allow-Origin"] = "*"
161-
response.headers["Access-Control-Allow-Methods"] = "GET, POST, PUT, DELETE, OPTIONS"
162-
response.headers["Access-Control-Allow-Headers"] = "Content-Type, Authorization"
163-
164-
print(f"Response from target URL: {target_url}")
165-
print(f"Response status code: {resp.status_code}")
166-
print(f"Response headers: {headers}")
167-
168-
return response
117+
target_url = f'http://localhost:{internal_app_port}/{data}'
118+
119+
return internal_request_handler(request, target_url)
169120
else:
170121
return jsonify({"message": "You are not logged in."}), 401
171122

172123
@app.route("/login", methods=["GET", "POST", "PUT", "DELETE"])
173124
def _app4():
174125
user = session.get("user")
175126
if user:
176-
target_url = f'http://localhost:80/login'
177-
# Construct the new request to the target service
178-
resp = requests.request(
179-
method=request.method,
180-
url=target_url,
181-
headers={key: value for (key, value) in request.headers if key != 'Host'},
182-
data=request.get_data(),
183-
cookies=request.cookies,
184-
allow_redirects=True,
185-
params=request.args
186-
)
187-
188-
# Create a Flask response object from the target service's response
189-
excluded_headers = ['content-encoding', 'content-length', 'transfer-encoding', 'connection']
190-
headers = [(name, value) for (name, value) in resp.raw.headers.items() if name.lower() not in excluded_headers]
191-
response = Response(resp.content, resp.status_code, headers)
192-
if request.path.endswith('.js'):
193-
response.headers["Content-Type"] = "application/javascript"
194-
195-
response.headers["Access-Control-Allow-Origin"] = "*"
196-
response.headers["Access-Control-Allow-Methods"] = "GET, POST, PUT, DELETE, OPTIONS"
197-
response.headers["Access-Control-Allow-Headers"] = "Content-Type, Authorization"
198-
199-
print(f"Response from target URL: {target_url}")
200-
print(f"Response status code: {resp.status_code}")
201-
print(f"Response headers: {headers}")
202-
203-
return response
127+
target_url = f'http://localhost:{internal_app_port}/login'
128+
129+
return internal_request_handler(request, target_url)
204130
else:
205131
return jsonify({"message": "You are not logged in."}), 401
206132

@@ -211,36 +137,9 @@ def _app5(filename):
211137
print(f"request method: {request.method}")
212138
if user:
213139
#if user and (('version.json' in filename) ):
214-
target_url = f'http://localhost:80/_app/{filename}'
215-
# Construct the new request to the target service
216-
resp = requests.request(
217-
method=request.method,
218-
url=target_url,
219-
headers={key: value for (key, value) in request.headers if key != 'Host'},
220-
data=request.get_data(),
221-
cookies=request.cookies,
222-
allow_redirects=True,
223-
params=request.args
224-
)
225-
226-
# Create a Flask response object from the target service's response
227-
excluded_headers = ['content-encoding', 'content-length', 'transfer-encoding', 'connection']
228-
headers = [(name, value) for (name, value) in resp.raw.headers.items() if name.lower() not in excluded_headers]
229-
response = Response(resp.content, resp.status_code, headers)
230-
231-
# Explicitly set Content-Type for JS files
232-
if filename.endswith('.js'):
233-
response.headers["Content-Type"] = "application/javascript"
234-
235-
response.headers["Access-Control-Allow-Origin"] = "*"
236-
response.headers["Access-Control-Allow-Methods"] = "GET, POST, PUT, DELETE, OPTIONS"
237-
response.headers["Access-Control-Allow-Headers"] = "Content-Type, Authorization"
238-
239-
print(f"Response from target URL: {target_url}")
240-
print(f"Response status code: {resp.status_code}")
241-
print(f"Response headers: {headers}")
242-
243-
return response
140+
target_url = f'http://localhost:{internal_app_port}/_app/{filename}'
141+
142+
return internal_request_handler(request, target_url)
244143
else:
245144
return jsonify({"message": "You are not logged in."}), 401
246145

@@ -251,68 +150,28 @@ def _app6(path0, path1, path2):
251150
#return jsonify({"message": "You are authenticated!", "user": user}), 200
252151
#if path1=='..':
253152
# path1 = 'immutable' # this is such a kludge, we'll see if it works
254-
target_url = f'http://localhost:80/{path0}/{path1}/{path2}'
255-
# Construct the new request to the target service
256-
resp = requests.request(
257-
method=request.method,
258-
url=target_url,
259-
headers={key: value for (key, value) in request.headers if key != 'Host'},
260-
data=request.get_data(),
261-
cookies=request.cookies,
262-
allow_redirects=True,
263-
params=request.args
264-
)
265-
266-
# Create a Flask response object from the target service's response
267-
excluded_headers = ['content-encoding', 'content-length', 'transfer-encoding', 'connection']
268-
headers = [(name, value) for (name, value) in resp.raw.headers.items() if name.lower() not in excluded_headers]
269-
response = Response(resp.content, resp.status_code, headers)
270-
if path2.endswith('.js'):
271-
response.headers["Content-Type"] = "application/javascript"
272-
273-
response.headers["Access-Control-Allow-Origin"] = "*"
274-
response.headers["Access-Control-Allow-Methods"] = "GET, POST, PUT, DELETE, OPTIONS"
275-
response.headers["Access-Control-Allow-Headers"] = "Content-Type, Authorization"
276-
277-
return response
153+
target_url = f'http://localhost:{internal_app_port}/{path0}/{path1}/{path2}'
154+
155+
return internal_request_handler(request, target_url)
278156
else:
279157
return jsonify({"message": "You are not logged in."}), 401
280158

281159
@app.route("/<string:path0>/<string:path1>/<string:path2>/<string:path3>/<string:filename>", methods=["GET", "POST", "PUT", "DELETE"])
282160
def _app7(path0, path1, path2, path3, filename):
283161
user = session.get("user")
284-
print(f"path0: {path0}")
285-
print(f"path1: {path1}")
286-
print(f"path2: {path2}")
287-
print(f"path3: {path3}")
288-
print(f"filename: {filename}")
289-
print(f"request method: {request.method}")
162+
# print(f"path0: {path0}")
163+
# print(f"path1: {path1}")
164+
# print(f"path2: {path2}")
165+
# print(f"path3: {path3}")
166+
# print(f"filename: {filename}")
167+
# print(f"request method: {request.method}")
290168
if user:
291169
#return jsonify({"message": "You are authenticated!", "user": user}), 200
292170
#if path1=='..':
293171
# path1 = 'immutable' # this is such a kludge, we'll see if it works
294-
target_url = f'http://localhost:80/{path0}/{path1}/{path2}/{path3}/{filename}'
295-
# Construct the new request to the target service
296-
resp = requests.request(
297-
method=request.method,
298-
url=target_url,
299-
headers={key: value for (key, value) in request.headers if key != 'Host'},
300-
data=request.get_data(),
301-
cookies=request.cookies,
302-
allow_redirects=True,
303-
params=request.args
304-
)
305-
306-
# Create a Flask response object from the target service's response
307-
excluded_headers = ['content-encoding', 'content-length', 'transfer-encoding', 'connection']
308-
headers = [(name, value) for (name, value) in resp.raw.headers.items() if name.lower() not in excluded_headers]
309-
response = Response(resp.content, resp.status_code, headers)
310-
311-
response.headers["Access-Control-Allow-Origin"] = "*"
312-
response.headers["Access-Control-Allow-Methods"] = "GET, POST, PUT, DELETE, OPTIONS"
313-
response.headers["Access-Control-Allow-Headers"] = "Content-Type, Authorization"
314-
315-
return response
172+
target_url = f'http://localhost:{internal_app_port}/{path0}/{path1}/{path2}/{path3}/{filename}'
173+
174+
return internal_request_handler(request, target_url)
316175
else:
317176
return jsonify({"message": "You are not logged in."}), 401
318177

0 commit comments

Comments
 (0)