Sanitize URLs
All checks were successful
Build Formula10 Docker Image / build-docker (push) Successful in 14s

This commit is contained in:
2024-02-20 01:30:13 +01:00
parent 218ec19bf9
commit 9b0379a889
4 changed files with 24 additions and 14 deletions

View File

@ -1,3 +1,5 @@
from urllib.parse import unquote
from flask import Flask, render_template, request, redirect from flask import Flask, render_template, request, redirect
from model import * from model import *
from database_utils import reload_static_data, reload_dynamic_data, export_dynamic_data from database_utils import reload_static_data, reload_dynamic_data, export_dynamic_data
@ -65,6 +67,7 @@ def race_root():
@app.route("/race/<user_name>") @app.route("/race/<user_name>")
def race_active_user(user_name: str): def race_active_user(user_name: str):
user_name = unquote(user_name)
model = TemplateModel() model = TemplateModel()
return render_template("race.jinja", return render_template("race.jinja",
active_user=model.user_by(user_name=user_name, ignore=["Everyone"]), active_user=model.user_by(user_name=user_name, ignore=["Everyone"]),
@ -73,15 +76,18 @@ def race_active_user(user_name: str):
@app.route("/race-guess/<race_name>/<user_name>", methods=["POST"]) @app.route("/race-guess/<race_name>/<user_name>", methods=["POST"])
def race_guess_post(race_name: str, user_name: str): def race_guess_post(race_name: str, user_name: str):
race_name = unquote(race_name)
user_name = unquote(user_name)
pxx: str | None = request.form.get("pxxselect") pxx: str | None = request.form.get("pxxselect")
dnf: str | None = request.form.get("dnfselect") dnf: str | None = request.form.get("dnfselect")
if pxx is None or dnf is None: if pxx is None or dnf is None:
return race_active_user(user_name) return redirect(f"/race/{quote(user_name)}")
if RaceResult.query.filter_by(race_name=race_name).first() is not None: if RaceResult.query.filter_by(race_name=race_name).first() is not None:
print("Error: Can't guess race result if the race result is already known!") print("Error: Can't guess race result if the race result is already known!")
return redirect(f"/race/{user_name}") return redirect(f"/race/{quote(user_name)}")
raceguess: RaceGuess | None = RaceGuess.query.filter_by(user_name=user_name, race_name=race_name).first() raceguess: RaceGuess | None = RaceGuess.query.filter_by(user_name=user_name, race_name=race_name).first()
@ -105,6 +111,7 @@ def season_root():
@app.route("/season/<user_name>") @app.route("/season/<user_name>")
def season_active_user(user_name: str): def season_active_user(user_name: str):
user_name = unquote(user_name)
model = TemplateModel() model = TemplateModel()
return render_template("season.jinja", return render_template("season.jinja",
active_user=model.user_by(user_name=user_name, ignore=["Everyone"]), active_user=model.user_by(user_name=user_name, ignore=["Everyone"]),
@ -113,6 +120,7 @@ def season_active_user(user_name: str):
@app.route("/season-guess/<user_name>", methods=["POST"]) @app.route("/season-guess/<user_name>", methods=["POST"])
def season_guess_post(user_name: str): def season_guess_post(user_name: str):
user_name = unquote(user_name)
guesses: List[str | None] = [ guesses: List[str | None] = [
request.form.get("hottakeselect"), request.form.get("hottakeselect"),
request.form.get("p2select"), request.form.get("p2select"),
@ -128,7 +136,7 @@ def season_guess_post(user_name: str):
if any(guess is None for guess in guesses + teamwinnerguesses): if any(guess is None for guess in guesses + teamwinnerguesses):
print("Error: /guessseason could not obtain request data!") print("Error: /guessseason could not obtain request data!")
return redirect(f"/season/{user_name}") return redirect(f"/season/{quote(user_name)}")
seasonguess: SeasonGuess | None = SeasonGuess.query.filter_by(user_name=user_name).first() seasonguess: SeasonGuess | None = SeasonGuess.query.filter_by(user_name=user_name).first()
teamwinners: TeamWinners | None = seasonguess.team_winners if seasonguess is not None else None teamwinners: TeamWinners | None = seasonguess.team_winners if seasonguess is not None else None
@ -165,7 +173,7 @@ def season_guess_post(user_name: str):
seasonguess.podium_drivers_id = user_name seasonguess.podium_drivers_id = user_name
db.session.commit() db.session.commit()
return redirect(f"/season/{user_name}") return redirect(f"/season/{quote(user_name)}")
@app.route("/result") @app.route("/result")
@ -175,6 +183,7 @@ def result_root():
@app.route("/result/<race_name>") @app.route("/result/<race_name>")
def result_active_race(race_name: str): def result_active_race(race_name: str):
race_name = unquote(race_name)
model = TemplateModel() model = TemplateModel()
return render_template("enter.jinja", return render_template("enter.jinja",
active_result=model.race_result_by(race_name=race_name), active_result=model.race_result_by(race_name=race_name),
@ -183,6 +192,7 @@ def result_active_race(race_name: str):
@app.route("/result-enter/<result_race_name>", methods=["POST"]) @app.route("/result-enter/<result_race_name>", methods=["POST"])
def result_enter_post(result_race_name: str): def result_enter_post(result_race_name: str):
result_race_name = unquote(result_race_name)
pxxs: List[str] = request.form.getlist("pxxdrivers") pxxs: List[str] = request.form.getlist("pxxdrivers")
dnfs: List[str] = request.form.getlist("dnf-drivers") dnfs: List[str] = request.form.getlist("dnf-drivers")
excludes: List[str] = request.form.getlist("exclude-drivers") excludes: List[str] = request.form.getlist("exclude-drivers")
@ -208,7 +218,7 @@ def result_enter_post(result_race_name: str):
print("Error: Can't redirect to /enter/<GrandPrix> because race couldn't be found") print("Error: Can't redirect to /enter/<GrandPrix> because race couldn't be found")
return redirect(f"/result/Current") return redirect(f"/result/Current")
return redirect(f"/result/{race.name}") return redirect(f"/result/{quote(race.name)}")
@app.route("/user") @app.route("/user")

View File

@ -29,7 +29,7 @@ class Race(db.Model):
return self return self
@property @property
def name_sanitized(self): def name_sanitized(self) -> str:
return quote(self.name) return quote(self.name)
name: Mapped[str] = mapped_column(String(64), primary_key=True) name: Mapped[str] = mapped_column(String(64), primary_key=True)
@ -96,7 +96,7 @@ class User(db.Model):
] ]
@property @property
def name_sanitized(self): def name_sanitized(self) -> str:
return quote(self.name) return quote(self.name)
name: Mapped[str] = mapped_column(String(32), primary_key=True) name: Mapped[str] = mapped_column(String(32), primary_key=True)

View File

@ -160,8 +160,8 @@ P{{ result.race.pxx + 3 }}: {{ result.pxx(3).abbr }}
<div class="collapse navbar-collapse" id="navbarCollapse"> <div class="collapse navbar-collapse" id="navbarCollapse">
<div class="navbar-nav me-2"> <div class="navbar-nav me-2">
{{ nav_selector("/race/" ~ (active_user.name if active_user is not none else "Everyone"), "Race Picks") }} {{ nav_selector("/race/" ~ (active_user.name_sanitized if active_user is not none else "Everyone"), "Race Picks") }}
{{ nav_selector("/season/" ~ (active_user.name if active_user is not none else "Everyone"), "Season Picks") }} {{ nav_selector("/season/" ~ (active_user.name_sanitized if active_user is not none else "Everyone"), "Season Picks") }}
{{ nav_selector("/graphs", "Statistics") }} {{ nav_selector("/graphs", "Statistics") }}
{{ nav_selector("/rules", "Rules") }} {{ nav_selector("/rules", "Rules") }}
</div> </div>

View File

@ -2,7 +2,7 @@
{% block title %}Formula 10 - Race{% endblock title %} {% block title %}Formula 10 - Race{% endblock title %}
{% set active_page = "/race/" ~ (active_user.name if active_user is not none else "Everyone") %} {% set active_page = "/race/" ~ (active_user.name_sanitized if active_user is not none else "Everyone") %}
{% block head_extra %} {% block head_extra %}
<script defer> <script defer>
@ -30,7 +30,7 @@
</li> </li>
{% for user in model.all_users() %} {% for user in model.all_users() %}
<li><a class="dropdown-item" href="/race/{{ user.name }}">{{ user.name }}</a></li> <li><a class="dropdown-item" href="/race/{{ user.name_sanitized }}">{{ user.name }}</a></li>
{% endfor %} {% endfor %}
</ul> </ul>
</div> </div>
@ -61,7 +61,7 @@
{% if active_user is none %} {% if active_user is none %}
{% for user in model.all_users() %} {% for user in model.all_users() %}
<td class="text-center text-nowrap" style="min-width: 100px;"> <td class="text-center text-nowrap" style="min-width: 100px;">
<a href="/race/{{ user.name }}" class="link-dark">{{ user.name }}</a> <a href="/race/{{ user.name_sanitized }}" class="link-dark">{{ user.name }}</a>
</td> </td>
{% endfor %} {% endfor %}
{% else %} {% else %}
@ -115,7 +115,7 @@
</td> </td>
<td> <td>
<form action="/race-guess/{{ current_race.name }}/{{ active_user.name }}" method="post"> <form action="/race-guess/{{ current_race.name_sanitized }}/{{ active_user.name_sanitized }}" method="post">
{% set user_guess = model.race_guesses_by(user_name=active_user.name, race_name=current_race.name) %} {% set user_guess = model.race_guesses_by(user_name=active_user.name, race_name=current_race.name) %}
{# Driver PXX Select #} {# Driver PXX Select #}
@ -139,7 +139,7 @@
<tr> <tr>
<td class="text-nowrap"> <td class="text-nowrap">
<span class="fw-bold">{{ past_result.race.number }}:</span> <a <span class="fw-bold">{{ past_result.race.number }}:</span> <a
href="/result/{{ past_result.race.name }}" class="link-dark">{{ past_result.race.name }}</a><br> href="/result/{{ past_result.race.name_sanitized }}" class="link-dark">{{ past_result.race.name }}</a><br>
<small><span class="fw-bold">Guessed:</span> P{{ past_result.race.pxx }}</small> <small><span class="fw-bold">Guessed:</span> P{{ past_result.race.pxx }}</small>
</td> </td>