Repos / pytaku / e7f5647671
commit e7f5647671f7f667d219531c5b9e5e8e977dba89
Author: Bùi Thành Nhân <hi@imnhan.com>
Date:   Sat Aug 8 01:41:51 2020 +0700

    add mechanism to nuke all sessions in 1 code push

diff --git a/src/pytaku/decorators.py b/src/pytaku/decorators.py
index 8d7b0bc..6863355 100644
--- a/src/pytaku/decorators.py
+++ b/src/pytaku/decorators.py
@@ -5,6 +5,27 @@
 from .persistence import read
 
 
+def ensure_session_version(f, CURRENT_VERSION=1):
+    """
+    Increment CURRENT_VERSION to nuke all current sessions.
+    Useful for when I try to change session structure or something. Maybe.
+    """
+
+    @wraps(f)
+    def decorated_function(*args, **kwargs):
+        if (
+            not session.get("version")
+            or not isinstance(session["version"], int)
+            or session["version"] < CURRENT_VERSION
+        ):
+            session.clear()
+            session["version"] = CURRENT_VERSION
+            return redirect("/")
+        return f(*args, **kwargs)
+
+    return decorated_function
+
+
 def require_login(f):
     @wraps(f)
     def decorated_function(*args, **kwargs):
diff --git a/src/pytaku/main.py b/src/pytaku/main.py
index af04fb9..a1903a8 100644
--- a/src/pytaku/main.py
+++ b/src/pytaku/main.py
@@ -17,7 +17,7 @@
 
 from . import mangadex
 from .conf import config
-from .decorators import require_login, trigger_has_read
+from .decorators import ensure_session_version, require_login, trigger_has_read
 from .persistence import (
     follow,
     get_followed_titles,
@@ -38,6 +38,7 @@
 
 
 @app.route("/")
+@ensure_session_version
 def home_view():
     if session.get("user"):
         return redirect(url_for("follows_view"))
@@ -45,6 +46,7 @@ def home_view():
 
 
 @app.route("/me", methods=["GET"])
+@ensure_session_version
 @require_login
 def follows_view():
     titles = get_followed_titles(session["user"]["id"])
@@ -52,6 +54,7 @@ def follows_view():
 
 
 @app.route("/follow/<site>/<title_id>", methods=["POST"])
+@ensure_session_version
 @require_login
 def follow_view(site, title_id):
     follow(session["user"]["id"], site, title_id)
@@ -59,6 +62,7 @@ def follow_view(site, title_id):
 
 
 @app.route("/unfollow/<site>/<title_id>", methods=["POST"])
+@ensure_session_version
 @require_login
 def unfollow_view(site, title_id):
     unfollow(session["user"]["id"], site, title_id)
@@ -66,12 +70,14 @@ def unfollow_view(site, title_id):
 
 
 @app.route("/logout", methods=["POST"])
+@ensure_session_version
 def logout_view():
     session.pop("user")
     return redirect("/")
 
 
 @app.route("/auth", methods=["GET", "POST"])
+@ensure_session_version
 def auth_view():
     if session.get("user"):
         return redirect(url_for("home_view"))
@@ -155,6 +161,7 @@ def auth_view():
 
 
 @app.route("/title/<site>/<title_id>")
+@ensure_session_version
 @trigger_has_read
 def title_view(site, title_id):
     user = session.get("user", None)
@@ -172,6 +179,7 @@ def title_view(site, title_id):
 
 
 @app.route("/chapter/<site>/<chapter_id>")
+@ensure_session_version
 @trigger_has_read
 def chapter_view(site, chapter_id):
     chapter = load_chapter(site, chapter_id)
@@ -197,6 +205,7 @@ def chapter_view(site, chapter_id):
 
 
 @app.route("/search")
+@ensure_session_version
 def search_view():
     query = request.args.get("q", "").strip()
     titles = []