WebHost: Use B64encoded UUIDs for links.

Warning: This will break old links
This commit is contained in:
Fabian Dill 2020-07-27 05:04:49 +02:00
parent 63cbdb9449
commit 8696ee4c9e
6 changed files with 50 additions and 31 deletions

View File

@ -2,6 +2,8 @@
So unless you're Berserker you need to include license information.""" So unless you're Berserker you need to include license information."""
import os import os
import uuid
import base64
from pony.flask import Pony from pony.flask import Pony
from flask import Flask, request, redirect, url_for, render_template, Response, session, abort from flask import Flask, request, redirect, url_for, render_template, Response, session, abort
@ -46,7 +48,21 @@ av = Autoversion(app)
cache = Cache(app) cache = Cache(app)
Compress(app) Compress(app)
# this local cache is risky business if app hosting is done with subprocesses as it will not sync. Waitress is fine though from werkzeug.routing import BaseConverter
class B64UUIDConverter(BaseConverter):
def to_python(self, value):
return uuid.UUID(bytes=base64.urlsafe_b64decode(value + '=='))
def to_url(self, value):
return base64.urlsafe_b64encode(value.bytes).rstrip(b'=').decode('ascii')
# short UUID
app.url_map.converters["suuid"] = B64UUIDConverter
app.jinja_env.filters['suuid'] = lambda value: base64.urlsafe_b64encode(value.bytes).rstrip(b'=').decode('ascii')
@app.before_request @app.before_request
@ -56,7 +72,7 @@ def register_session():
session["_id"] = uuid4() # uniquely identify each session without needing a login session["_id"] = uuid4() # uniquely identify each session without needing a login
@app.route('/seed/<uuid:seed>') @app.route('/seed/<suuid:seed>')
def view_seed(seed: UUID): def view_seed(seed: UUID):
seed = Seed.get(id=seed) seed = Seed.get(id=seed)
if not seed: if not seed:
@ -65,7 +81,7 @@ def view_seed(seed: UUID):
rooms=[room for room in seed.rooms if room.owner == session["_id"]]) rooms=[room for room in seed.rooms if room.owner == session["_id"]])
@app.route('/new_room/<uuid:seed>') @app.route('/new_room/<suuid:seed>')
def new_room(seed: UUID): def new_room(seed: UUID):
seed = Seed.get(id=seed) seed = Seed.get(id=seed)
if not seed: if not seed:
@ -84,14 +100,13 @@ def _read_log(path: str):
f"Likely a crash during spinup of multiworld instance or it is still spinning up." f"Likely a crash during spinup of multiworld instance or it is still spinning up."
@app.route('/log/<uuid:room>') @app.route('/log/<suuid:room>')
def display_log(room: UUID): def display_log(room: UUID):
# noinspection PyTypeChecker # noinspection PyTypeChecker
return Response(_read_log(os.path.join("logs", str(room) + ".txt")), mimetype="text/plain;charset=UTF-8") return Response(_read_log(os.path.join("logs", str(room) + ".txt")), mimetype="text/plain;charset=UTF-8")
@app.route('/hosted/<suuid:room>', methods=['GET', 'POST'])
@app.route('/hosted/<uuid:room>', methods=['GET', 'POST'])
def host_room(room: UUID): def host_room(room: UUID):
room = Room.get(id=room) room = Room.get(id=room)
if room is None: if room is None:

View File

@ -1,19 +1,22 @@
{% extends 'layout.html' %} {% extends 'layout.html' %}
{% block head %} {% block head %}
<title>Multiworld {{ room.id }}</title> <title>Multiworld {{ room.id|suuid }}</title>
<link rel="stylesheet" type="text/css" href="{{ static_autoversion("host_room.css") }}" /> <link rel="stylesheet" type="text/css" href="{{ static_autoversion("host_room.css") }}"/>
{% endblock %} {% endblock %}
{% block body %} {% block body %}
<div id="host-room"> <div id="host-room">
{% if room.owner == session["_id"] %} {% if room.owner == session["_id"] %}
Room created from <a href="{{ url_for("view_seed", seed=room.seed.id) }}">Seed #{{ room.seed.id }}</a><br> Room created from <a href="{{ url_for("view_seed", seed=room.seed.id) }}">Seed #{{ room.seed.id|suuid }}</a>
<br>
{% endif %} {% endif %}
{% if room.tracker %} {% if room.tracker %}
This room has a <a href="{{ url_for("get_tracker", tracker=room.tracker) }}">Multiworld Tracker</a> enabled.<br> This room has a <a href="{{ url_for("get_tracker", tracker=room.tracker) }}">Multiworld Tracker</a> enabled.
<br>
{% endif %} {% endif %}
This room will be closed after {{ room.timeout//60//60 }} hours of inactivity. Should you wish to continue later, This room will be closed after {{ room.timeout//60//60 }} hours of inactivity. Should you wish to continue
later,
you can simply refresh this page and the server will be started again.<br> you can simply refresh this page and the server will be started again.<br>
{% if room.owner == session["_id"] %} {% if room.owner == session["_id"] %}
<form method=post> <form method=post>

View File

@ -1,7 +1,7 @@
{% macro list_rooms(rooms) -%} {% macro list_rooms(rooms) -%}
<ul> <ul>
{% for room in rooms %} {% for room in rooms %}
<li><a href="{{ url_for("host_room", room=room.id) }}">Room #{{ room.id }}</a></li> <li><a href="{{ url_for("host_room", room=room.id) }}">Room #{{ room.id|suuid }}</a></li>
{% endfor %} {% endfor %}
{{ caller() }} {{ caller() }}
</ul> </ul>

View File

@ -36,8 +36,9 @@
<tbody> <tbody>
{% for room in rooms %} {% for room in rooms %}
<tr> <tr>
<td><a href="{{ url_for("view_seed", seed=room.seed.id) }}">{{ room.seed.id }}</a></td> <td><a href="{{ url_for("view_seed", seed=room.seed.id) }}">{{ room.seed.id|suuid }}</a>
<td><a href="{{ url_for("host_room", room=room.id) }}">{{ room.id }}</a></td> </td>
<td><a href="{{ url_for("host_room", room=room.id) }}">{{ room.id|suuid }}</a></td>
<td>{{ room.seed.multidata.names[0]|length }} Total: <td>{{ room.seed.multidata.names[0]|length }} Total:
{{ room.seed.multidata.names[0]|join(", ")|truncate(256, False, " ...") }}</td> {{ room.seed.multidata.names[0]|join(", ")|truncate(256, False, " ...") }}</td>
<td>{{ room.creation_time.strftime("%Y-%m-%d %H:%M") }}</td> <td>{{ room.creation_time.strftime("%Y-%m-%d %H:%M") }}</td>

View File

@ -2,9 +2,9 @@
{% import "macros.html" as macros %} {% import "macros.html" as macros %}
{% block head %} {% block head %}
<title>Multiworld Seed {{ seed.id }}</title> <title>Multiworld Seed {{ seed.id|suuid }}</title>
<link rel="stylesheet" type="text/css" href="{{ static_autoversion("view_seed.css") }}" /> <link rel="stylesheet" type="text/css" href="{{ static_autoversion("view_seed.css") }}"/>
<script type="application/ecmascript" src="{{ static_autoversion("view_seed.js") }}" ></script> <script type="application/ecmascript" src="{{ static_autoversion("view_seed.js") }}"></script>
{% endblock %} {% endblock %}
{% block body %} {% block body %}
@ -13,19 +13,19 @@
<h3>Seed Info</h3> <h3>Seed Info</h3>
<table> <table>
<tbody> <tbody>
<tr> <tr>
<td>Seed:&nbsp;</td> <td>Seed:&nbsp;</td>
<td>{{ seed.id }}</td> <td>{{ seed.id|suuid }}</td>
</tr> </tr>
<tr> <tr>
<td>Created:&nbsp;</td> <td>Created:&nbsp;</td>
<td id="creation-time" data-creation-time="{{ seed.creation_time }}"></td> <td id="creation-time" data-creation-time="{{ seed.creation_time }}"></td>
</tr> </tr>
<tr> <tr>
<td>Players:&nbsp;</td> <td>Players:&nbsp;</td>
<td> <td>
<ul> <ul>
{% for team in seed.multidata["names"] %} {% for team in seed.multidata["names"] %}
<li>Team #{{ loop.index }} - {{ team | length }} <li>Team #{{ loop.index }} - {{ team | length }}
<ul> <ul>
{% for player in team %} {% for player in team %}

View File

@ -248,7 +248,7 @@ def get_static_room_data(room: Room):
return result return result
@app.route('/tracker/<uuid:tracker>') @app.route('/tracker/<suuid:tracker>')
@cache.memoize(timeout=30) # update every 30 seconds @cache.memoize(timeout=30) # update every 30 seconds
def get_tracker(tracker: UUID): def get_tracker(tracker: UUID):
room = Room.get(tracker=tracker) room = Room.get(tracker=tracker)