[O] Optimize logging, add blacklist

This commit is contained in:
Hykilpikonna
2022-08-15 18:19:20 -04:00
parent 3c66d4b0c3
commit e827fabd0f
+17 -12
View File
@@ -7,6 +7,7 @@ from pathlib import Path
import uvicorn import uvicorn
from fastapi import FastAPI, Body from fastapi import FastAPI, Body
from pysafebrowsing import SafeBrowsing from pysafebrowsing import SafeBrowsing
from starlette.requests import Request
from starlette.responses import RedirectResponse, HTMLResponse, FileResponse, PlainTextResponse from starlette.responses import RedirectResponse, HTMLResponse, FileResponse, PlainTextResponse
app = FastAPI() app = FastAPI()
@@ -27,6 +28,8 @@ base = len(chars)
re_url = re.compile(r"""^https?://(?:\S+(?::\S*)?@)?(?:(?!(?:10|127)(?:\.\d{1,3}){3})(?!(?:169\.254|192\.168)(?:\.\d{1,3}){2})(?!172\.(?:1[6-9]|2\d|3[0-1])(?:\.\d{1,3}){2})(?:[1-9]\d?|1\d\d|2[01]\d|22[0-3])(?:\.(?:1?\d{1,2}|2[0-4]\d|25[0-5])){2}(?:\.(?:[1-9]\d?|1\d\d|2[0-4]\d|25[0-4]))|(?:(?:[a-z\u00a1-\uffff0-9]-*)*[a-z\u00a1-\uffff0-9]+)(?:\.(?:[a-z\u00a1-\uffff0-9]-*)*[a-z\u00a1-\uffff0-9]+)*(?:\.(?:[a-z\u00a1-\uffff]{2,}))\.?)(?::\d{2,5})?(?:[/?#]\S*)?$""") re_url = re.compile(r"""^https?://(?:\S+(?::\S*)?@)?(?:(?!(?:10|127)(?:\.\d{1,3}){3})(?!(?:169\.254|192\.168)(?:\.\d{1,3}){2})(?!172\.(?:1[6-9]|2\d|3[0-1])(?:\.\d{1,3}){2})(?:[1-9]\d?|1\d\d|2[01]\d|22[0-3])(?:\.(?:1?\d{1,2}|2[0-4]\d|25[0-5])){2}(?:\.(?:[1-9]\d?|1\d\d|2[0-4]\d|25[0-4]))|(?:(?:[a-z\u00a1-\uffff0-9]-*)*[a-z\u00a1-\uffff0-9]+)(?:\.(?:[a-z\u00a1-\uffff0-9]-*)*[a-z\u00a1-\uffff0-9]+)*(?:\.(?:[a-z\u00a1-\uffff]{2,}))\.?)(?::\d{2,5})?(?:[/?#]\S*)?$""")
safe_browsing = SafeBrowsing(os.environ['GOOGLE_API_KEY']) safe_browsing = SafeBrowsing(os.environ['GOOGLE_API_KEY'])
blacklist = {'docs', 'favicon'}
def store(): def store():
data_path.mkdir(parents=True, exist_ok=True) data_path.mkdir(parents=True, exist_ok=True)
@@ -61,8 +64,8 @@ def decode(s: str) -> int:
@app.get('/{short}') @app.get('/{short}')
def expand(short: str): def expand(short: str):
print(short) if short == 'favicon.ico':
print(links) return FileResponse('favicon.ico')
if short in links: if short in links:
return RedirectResponse(links[short]) return RedirectResponse(links[short])
else: else:
@@ -74,39 +77,41 @@ def index():
return FileResponse('index.html') return FileResponse('index.html')
@app.get('/favicon.ico')
def favicon():
return FileResponse('favicon.ico')
@app.put('/') @app.put('/')
def put(name: str | None = None, body: str = Body()): def put(request: Request, name: str | None = None, body: str = Body()):
try: try:
global last_id global last_id
ip = request.headers.get('X-Real-IP') or request.client.host
print(f'New PUT request from {ip}')
print(f'> URL: {body.replace("https://", "").replace("http://", "")}')
# Check valid html # Check valid html
assert re_url.match(body) assert re_url.match(body), 'Invalid HTML'
sb = safe_browsing.lookup_url(body) sb = safe_browsing.lookup_url(body)
print(sb) print(f'> SafeBrowsing Result: {sb}')
assert not sb['malicious'], f'Link is malicious ({",".join(sb["threats"]).lower()})' assert not sb['malicious'], f'Link is malicious ({",".join(sb["threats"]).lower()})'
# Generate name # Generate name
while not name: while not name:
last_id += 1 last_id += 1
name = encode(last_id) name = encode(last_id)
if name in links: if name in links or name in blacklist:
name = None name = None
# Put name # Put name
links[name] = body links[name] = body
print(f'> Added link: {name}')
store() store()
return PlainTextResponse(f'/{name}') return PlainTextResponse(f'/{name}')
except AssertionError as e: except AssertionError as e:
print(f'> Rejected. {e}')
return PlainTextResponse(f'Error: {e}', status_code=400) return PlainTextResponse(f'Error: {e}', status_code=400)
if __name__ == '__main__': if __name__ == '__main__':
load() load()
uvicorn.run(app) uvicorn.run(app, host='0.0.0.0', port=8000)