Skip to content

Commit d78628b

Browse files
committed
middleware;denied access log
1 parent 0f13d4e commit d78628b

2 files changed

Lines changed: 55 additions & 69 deletions

File tree

globals.py

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,10 @@
1515
with open("requests.json") as fp:
1616
log = json.load(fp)
1717

18+
# Denied Log
19+
with open("denied.json") as fd:
20+
denied = json.load(fd)
21+
1822

1923
# Initiate Redis connection
2024
redis_client = redis.Redis(
@@ -43,6 +47,22 @@ def append_request_log(request: Request):
4347
json.dump(log, json_file, indent=4, separators=(",", ": "))
4448

4549

50+
def append_denied_log(request: Request):
51+
"""Logs some general info about the denied request recieved in `denied.json`"""
52+
denied.append(
53+
{
54+
"url": str(request.url),
55+
"ip": request.client.host,
56+
"method": request.method,
57+
"cookies": request.cookies,
58+
"headers": dict(request.headers),
59+
"time": str(datetime.now()),
60+
}
61+
)
62+
with open("denied.json", "w") as json_file:
63+
json.dump(denied, json_file, indent=4, separators=(",", ": "))
64+
65+
4666
def set_cache(cache_key: str, data):
4767
"""Cache the data in Redis\n
4868
`Decimal` values are converted to `String`"""

main.py

Lines changed: 35 additions & 69 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@
33
import json, time
44
from fastapi import FastAPI, Request, status, Depends, Response
55
from fastapi.responses import JSONResponse
6+
from starlette.middleware.base import BaseHTTPMiddleware
7+
from starlette.middleware import Middleware
68
from auth import VerifyToken
79
from threading import Thread # Not used yet
810

@@ -17,10 +19,10 @@
1719
redis_client,
1820
WHITELISTED_IPS,
1921
append_request_log,
22+
append_denied_log,
2023
)
2124

2225
from sql import selectQuery, insertQuery
23-
import surftimer.queries # Containing all SurfTimer queries from `queries.sp`
2426

2527
# Import all the endpoints for each table
2628
from surftimer.ck_latestrecords import router as ck_latestrecords_router
@@ -44,11 +46,28 @@ def to_dict(self):
4446
return {"inserted": self.inserted}
4547

4648

47-
# Swagger UI configuration
49+
class IPValidatorMiddleware(BaseHTTPMiddleware):
50+
async def dispatch(self, request: Request, call_next):
51+
# Get client IP
52+
ip = str(request.client.host)
53+
54+
# Check if IP is allowed
55+
if ip not in WHITELISTED_IPS:
56+
append_denied_log(request)
57+
data = {"message": "Not Allowed", "ip": ip}
58+
return JSONResponse(status_code=status.HTTP_400_BAD_REQUEST, content=data)
59+
60+
append_request_log(request)
61+
# Proceed if IP is allowed
62+
return await call_next(request)
63+
64+
65+
# Swagger UI configuration - https://swagger.io/docs/open-source-tools/swagger-ui/usage/configuration/
4866
swagger_config = {
4967
"displayOperationId": False, # Show operationId on the UI
5068
"defaultModelsExpandDepth": 1, # The default expansion depth for models (set to -1 completely hide the models)
5169
"defaultModelExpandDepth": 2,
70+
"defaultModelRendering": "example",
5271
"deepLinking": True, # Enables deep linking for tags and operations
5372
"useUnsafeMarkdown": True,
5473
"displayRequestDuration": True,
@@ -65,22 +84,10 @@ def to_dict(self):
6584
version="0.0.0",
6685
debug=True,
6786
swagger_ui_parameters=swagger_config,
68-
# docs_url=None,
87+
middleware=[Middleware(IPValidatorMiddleware)],
6988
)
7089

7190

72-
@app.get("/docs2", include_in_schema=False)
73-
async def custom_swagger_ui_html_cdn():
74-
return get_swagger_ui_html(
75-
openapi_url=app.openapi_url,
76-
title=f"{app.title} - Swagger UI",
77-
# swagger_ui_dark.css CDN link
78-
swagger_css_url="https://cdn.jsdelivr.net/gh/Itz-fork/Fastapi-Swagger-UI-Dark/assets/swagger_ui_dark.min.css",
79-
# swagger_css_url="https://raw.clarityeu.com/theme-newspaper.css",
80-
swagger_ui_parameters=swagger_config,
81-
)
82-
83-
8491
# Attach the routes
8592
app.include_router(ck_latestrecords_router)
8693
app.include_router(ck_maptier_router)
@@ -91,18 +98,15 @@ async def custom_swagger_ui_html_cdn():
9198
app.include_router(ck_playertemp_router)
9299

93100

94-
@app.middleware("http")
95-
async def validate_ip(request: Request, call_next):
96-
# Get client IP
97-
ip = str(request.client.host)
98-
99-
# Check if IP is allowed
100-
if ip not in WHITELISTED_IPS:
101-
data = {"message": f"IP {ip} is not allowed to access this resource."}
102-
return JSONResponse(status_code=status.HTTP_400_BAD_REQUEST, content=data)
103-
104-
# Proceed if IP is allowed
105-
return await call_next(request)
101+
@app.get("/docs2", include_in_schema=False)
102+
async def custom_swagger_ui_html_cdn():
103+
return get_swagger_ui_html(
104+
openapi_url=app.openapi_url,
105+
title=f"{app.title} - Swagger UI",
106+
# swagger_ui_dark.css CDN link
107+
swagger_css_url="https://cdn.jsdelivr.net/gh/Itz-fork/Fastapi-Swagger-UI-Dark/assets/swagger_ui_dark.min.css",
108+
swagger_ui_parameters=swagger_config,
109+
)
106110

107111

108112
@app.get("/")
@@ -140,20 +144,15 @@ async def mapchooser(
140144
```"""
141145
tic = time.perf_counter()
142146

143-
append_request_log(request)
144-
145147
json_data = []
146148

147149
# Check if data is cached in Redis
148-
cached_data = redis_client.get(
149-
f"mapchooser_{type}_{tier_min}_{tier_max}_{tier}_{steamid}_{style}"
150-
)
150+
cache_key = f"mapchooser:{type}_{tier_min}_{tier_max}_{tier}_{steamid}_{style}"
151+
cached_data = redis_client.get(cache_key)
151152
if cached_data:
152153
# Return cached data
153154
# print(json.loads(cached_data))
154-
print(
155-
f"[Redis] Loaded 'mapchooser_{type}_{tier_min}_{tier_max}_{tier}_{steamid}_{style}' ({time.perf_counter() - tic:0.4f}s)"
156-
)
155+
print(f"[Redis] Loaded '{cache_key}' ({time.perf_counter() - tic:0.4f}s)")
157156
return JSONResponse(
158157
status_code=status.HTTP_200_OK, content=json.loads(cached_data)
159158
)
@@ -255,47 +254,14 @@ async def mapchooser(
255254

256255
# Cache the data in Redis
257256
redis_client.set(
258-
f"mapchooser_{type}_{tier_min}_{tier_max}_{tier}_{steamid}_{style}",
257+
cache_key,
259258
json.dumps(json_data),
260259
ex=config["REDIS"]["EXPIRY"],
261260
)
262261

263262
return json_data
264263

265264

266-
# request: Request,
267-
# response: Response,
268-
# steamid32: str,
269-
# name: str,
270-
# runtime: float,
271-
# mapname: str,
272-
# ):
273-
# """Inserts a new record to the table\n
274-
# ```char sql_insertLatestRecords[] = ....```"""
275-
# tic = time.perf_counter()
276-
# append_request_log(request)
277-
278-
# sql = surftimer.queries.sql_insertLatestRecords.format(
279-
# steamid32, name, runtime, mapname
280-
# )
281-
# # xquery = insertQuery(sql)
282-
# xquery = 0
283-
# # time.sleep(3)
284-
285-
# if xquery < 1:
286-
# JSONResponse(
287-
# status_code=status.HTTP_204_NO_CONTENT,
288-
# content={"inserted": xquery, "xtime": time.perf_counter() - tic},
289-
# )
290-
291-
# # Prepare the response
292-
# toc = time.perf_counter()
293-
# print(f"Execution time {toc - tic:0.4f}")
294-
# # output = ResponseInsertQuery(xquery)
295-
296-
# return {"inserted": xquery, "xtime": time.perf_counter() - tic}
297-
298-
299265
# new code 👇
300266
@app.get(
301267
"/api/private",

0 commit comments

Comments
 (0)