forked from purplebored/purplebored.pl
98 lines
2.6 KiB
Python
98 lines
2.6 KiB
Python
#!/usr/bin/env python3
|
|
# -*- coding: utf-8 -*-
|
|
"""Home routes"""
|
|
|
|
import typing as t
|
|
|
|
import flask
|
|
from werkzeug.wrappers import Response
|
|
|
|
import pbpl.forms.prow as form_pow
|
|
import pbpl.forms.text as text_form
|
|
from pbpl.db import db
|
|
from pbpl.models import TextModel
|
|
|
|
from .bp import Bp
|
|
|
|
home: Bp = Bp("home", __name__)
|
|
|
|
__all__: t.Tuple[str] = ("home",)
|
|
|
|
|
|
@home.get("/", ishtml=True)
|
|
@home.csp("img-src $self; script-src $internal $wasm; style-src $internal; form-action $self; connect-src $self; manifest-src $self")
|
|
def index() -> str:
|
|
"""Home page"""
|
|
|
|
nonce: str = form_pow.proof_of_work_protect_session("home.index/text")
|
|
|
|
return flask.render_template(
|
|
"home/index.j2",
|
|
form=text_form.TextForm(),
|
|
texts=TextModel.query.all(),
|
|
pow_nonce=nonce,
|
|
)
|
|
|
|
|
|
@home.post("/")
|
|
@home.csp("img-src $self; script-src $internal; style-src $internal")
|
|
def text() -> Response:
|
|
"""Post some text"""
|
|
|
|
form: text_form.FlaskForm = text_form.TextForm()
|
|
|
|
if not form.validate_on_submit(): # type: ignore
|
|
flask.flash("Invalid form data/form", "error")
|
|
flask.abort(400)
|
|
|
|
if form.text.data is None:
|
|
flask.flash("Invalid form text", "error")
|
|
flask.abort(400)
|
|
|
|
if form.pow_solution.data is None or not form_pow.proof_of_work_verify_session(
|
|
"home.index/text",
|
|
form.pow_solution.data,
|
|
):
|
|
flask.flash("Invalid Proof-of-Work solution", "error")
|
|
flask.abort(403)
|
|
|
|
db.session.add(TextModel(text=form.text.data))
|
|
db.session.commit()
|
|
|
|
flask.flash("Your text has been saved")
|
|
return flask.redirect(flask.url_for("home.index"))
|
|
|
|
|
|
@home.get("/manifest.json")
|
|
@home.csp("manifest-src $self; img-src $self")
|
|
@home.cache("30d")
|
|
def manifest() -> t.Any:
|
|
"""Manifest file"""
|
|
return flask.jsonify( # type: ignore
|
|
{
|
|
"$schema": "https://json.schemastore.org/web-manifest-combined.json",
|
|
"short_name": "Example page",
|
|
"name": "Example page",
|
|
"description": "This is an example description",
|
|
"icons": [
|
|
{
|
|
"src": "/favicon.ico",
|
|
"sizes": "256x256",
|
|
"type": "image/vnd.microsoft.icon",
|
|
}
|
|
],
|
|
"start_url": ".",
|
|
"display": "standalone",
|
|
"theme_color": "#fbfbfb",
|
|
"background_color": "#121212",
|
|
}
|
|
)
|
|
|
|
|
|
@home.get("/favicon.ico")
|
|
@home.csp("img-src $self")
|
|
@home.cache("30d")
|
|
def favicon() -> Response:
|
|
"""Website icon"""
|
|
return flask.send_from_directory("static", "favicon.ico")
|