resolve mobile login
This commit is contained in:
5 files changed
+47
-6
No files matched your search
+18
-1
@@ -3,9 +3,11 @@ from __future__ import annotations
|
|||||||
|
|
||||||
import click
|
import click
|
||||||
import os
|
import os
|
||||||
|
from urllib.parse import urlsplit
|
||||||
from uuid import uuid4
|
from uuid import uuid4
|
||||||
|
|
||||||
from flask import Flask, render_template, request
|
from flask import Flask, flash, redirect, render_template, request, url_for
|
||||||
|
from flask_wtf.csrf import CSRFError
|
||||||
from werkzeug.exceptions import HTTPException
|
from werkzeug.exceptions import HTTPException
|
||||||
|
|
||||||
from boker.auth import current_user_id, is_logged_in, is_site_admin, normalize_email
|
from boker.auth import current_user_id, is_logged_in, is_site_admin, normalize_email
|
||||||
@@ -82,6 +84,21 @@ def create_app(config_overrides: dict | None = None) -> Flask:
|
|||||||
def forbidden(e):
|
def forbidden(e):
|
||||||
return render_template("403.html"), 403
|
return render_template("403.html"), 403
|
||||||
|
|
||||||
|
@app.errorhandler(CSRFError)
|
||||||
|
def csrf_error(error):
|
||||||
|
flash("Your form expired. Please try again.", "error")
|
||||||
|
|
||||||
|
referrer = request.referrer or ""
|
||||||
|
parsed = urlsplit(referrer)
|
||||||
|
if parsed.netloc == request.host and parsed.path:
|
||||||
|
return redirect(parsed.path)
|
||||||
|
|
||||||
|
if request.path.startswith("/account/login"):
|
||||||
|
return redirect(url_for("account.login"))
|
||||||
|
if request.path.startswith("/account/register"):
|
||||||
|
return redirect(url_for("account.register"))
|
||||||
|
return redirect(url_for("public.home"))
|
||||||
|
|
||||||
@app.errorhandler(Exception)
|
@app.errorhandler(Exception)
|
||||||
def unexpected_error(error):
|
def unexpected_error(error):
|
||||||
if isinstance(error, HTTPException):
|
if isinstance(error, HTTPException):
|
||||||
|
|||||||
+2
-2
@@ -8,7 +8,7 @@ BASE_DIR = Path(__file__).resolve().parent.parent
|
|||||||
DEFAULT_DATABASE_URL = f"sqlite:///{BASE_DIR / 'data' / 'boker-dev.sqlite3'}"
|
DEFAULT_DATABASE_URL = f"sqlite:///{BASE_DIR / 'data' / 'boker-dev.sqlite3'}"
|
||||||
DEFAULT_SECRET_KEY = "change-this-before-deploying"
|
DEFAULT_SECRET_KEY = "change-this-before-deploying"
|
||||||
|
|
||||||
APP_VERSION = "2.5.32"
|
APP_VERSION = "2.5.33"
|
||||||
|
|
||||||
|
|
||||||
def load_local_env(env_path: Path) -> None:
|
def load_local_env(env_path: Path) -> None:
|
||||||
@@ -59,5 +59,5 @@ class Config:
|
|||||||
|
|
||||||
class ProductionConfig(Config):
|
class ProductionConfig(Config):
|
||||||
SESSION_COOKIE_SECURE: bool = True
|
SESSION_COOKIE_SECURE: bool = True
|
||||||
SESSION_COOKIE_SAMESITE: str = "Strict"
|
SESSION_COOKIE_SAMESITE: str = "Lax"
|
||||||
PREFERRED_URL_SCHEME: str = "https"
|
PREFERRED_URL_SCHEME: str = "https"
|
||||||
@@ -35,7 +35,7 @@ class ProductionConfigTests(unittest.TestCase):
|
|||||||
)
|
)
|
||||||
|
|
||||||
self.assertTrue(app.config["SESSION_COOKIE_SECURE"])
|
self.assertTrue(app.config["SESSION_COOKIE_SECURE"])
|
||||||
self.assertEqual(app.config["SESSION_COOKIE_SAMESITE"], "Strict")
|
self.assertEqual(app.config["SESSION_COOKIE_SAMESITE"], "Lax")
|
||||||
self.assertTrue(app.config["SQLALCHEMY_DATABASE_URI"].startswith("postgresql+psycopg://"))
|
self.assertTrue(app.config["SQLALCHEMY_DATABASE_URI"].startswith("postgresql+psycopg://"))
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -42,6 +42,28 @@ class ErrorPageTests(unittest.TestCase):
|
|||||||
self.assertNotIn(b"RuntimeError", response.data)
|
self.assertNotIn(b"RuntimeError", response.data)
|
||||||
self.assertRegex(response.get_data(as_text=True), re.compile(r"Incident [a-f0-9]{12}"))
|
self.assertRegex(response.get_data(as_text=True), re.compile(r"Incident [a-f0-9]{12}"))
|
||||||
|
|
||||||
|
def test_csrf_errors_redirect_to_form_with_flash(self):
|
||||||
|
csrf_app = create_app(
|
||||||
|
{
|
||||||
|
"TESTING": True,
|
||||||
|
"PROPAGATE_EXCEPTIONS": False,
|
||||||
|
"SQLALCHEMY_DATABASE_URI": self.app.config["SQLALCHEMY_DATABASE_URI"],
|
||||||
|
"WTF_CSRF_ENABLED": True,
|
||||||
|
}
|
||||||
|
)
|
||||||
|
client = csrf_app.test_client()
|
||||||
|
|
||||||
|
response = client.post(
|
||||||
|
"/account/login",
|
||||||
|
data={"csrf_token": "stale-token", "email": "owner@example.com", "password": "password123"},
|
||||||
|
)
|
||||||
|
|
||||||
|
self.assertEqual(response.status_code, 302)
|
||||||
|
self.assertEqual(response.headers["Location"], "/account/login")
|
||||||
|
with client.session_transaction() as flask_session:
|
||||||
|
flashes = flask_session.get("_flashes", [])
|
||||||
|
self.assertIn(("error", "Your form expired. Please try again."), flashes)
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
unittest.main()
|
unittest.main()
|
||||||
+4
-2
@@ -34,9 +34,11 @@ class SeoTests(unittest.TestCase):
|
|||||||
html = response.get_data(as_text=True)
|
html = response.get_data(as_text=True)
|
||||||
|
|
||||||
self.assertEqual(response.status_code, 200)
|
self.assertEqual(response.status_code, 200)
|
||||||
self.assertIn("Free Home Poker Tracker, Ledger & League Leaderboards", html)
|
self.assertIn("Free Poker Tracker, Ledger, Stats & Profit/Loss App", html)
|
||||||
self.assertIn('name="description"', html)
|
self.assertIn('name="description"', html)
|
||||||
self.assertIn("Track home poker sessions, buy-ins, cashouts, settlements", html)
|
self.assertIn("free poker tracker and poker ledger for home games", html)
|
||||||
|
self.assertIn("My Boker", html)
|
||||||
|
self.assertIn("poker profit or loss", html)
|
||||||
self.assertIn('rel="canonical" href="https://myboker.org/"', html)
|
self.assertIn('rel="canonical" href="https://myboker.org/"', html)
|
||||||
self.assertIn('application/ld+json', html)
|
self.assertIn('application/ld+json', html)
|
||||||
|
|
||||||
|
|||||||
Reference in new issue
Block a user