Skip to content

Commit

Permalink
docs: apply patch locating user_id & session cookie changes scidsg#603
Browse files Browse the repository at this point in the history
  • Loading branch information
rmlibre committed Oct 7, 2024
1 parent 87679fa commit e588c15
Show file tree
Hide file tree
Showing 8 changed files with 47 additions and 0 deletions.
1 change: 1 addition & 0 deletions hushline/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,7 @@ def page_not_found(e: Exception) -> Response:

@app.context_processor
def inject_user() -> dict[str, Any]:
# TODO: #603 upcoming session cookie change
if "user_id" in session:
user = db.session.get(User, session["user_id"])
return {"user": user}
Expand Down
2 changes: 2 additions & 0 deletions hushline/admin.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
def create_blueprint() -> Blueprint:
bp = Blueprint("admin", __file__, url_prefix="/admin")

# TODO: #603 upcoming session cookie change
@bp.route("/toggle_verified/<int:user_id>", methods=["POST"])
@admin_authentication_required
def toggle_verified(user_id: int) -> Response:
Expand All @@ -21,6 +22,7 @@ def toggle_verified(user_id: int) -> Response:
flash("✅ User verification status toggled.", "success")
return redirect(url_for("settings.index"))

# TODO: #603 upcoming session cookie change
@bp.route("/toggle_admin/<int:user_id>", methods=["POST"])
@admin_authentication_required
def toggle_admin(user_id: int) -> Response:
Expand Down
8 changes: 8 additions & 0 deletions hushline/premium.py
Original file line number Diff line number Diff line change
Expand Up @@ -365,6 +365,7 @@ def create_blueprint(app: Flask) -> Blueprint:
@bp.route("/")
@authentication_required
def index() -> Response | str:
# TODO: #603 upcoming session cookie change
user = db.session.get(User, session.get("user_id"))
if not user:
session.clear()
Expand All @@ -390,6 +391,7 @@ def index() -> Response | str:
@bp.route("/select-tier")
@authentication_required
def select_tier() -> Response | str:
# TODO: #603 upcoming session cookie change
user = db.session.get(User, session.get("user_id"))
if not user:
session.clear()
Expand All @@ -402,6 +404,7 @@ def select_tier() -> Response | str:
@bp.route("/select-tier/free", methods=["POST"])
@authentication_required
def select_free() -> Response | str:
# TODO: #603 upcoming session cookie change
user = db.session.get(User, session.get("user_id"))
if not user:
session.clear()
Expand All @@ -422,6 +425,7 @@ def waiting() -> Response | str:
@bp.route("/upgrade", methods=["POST"])
@authentication_required
def upgrade() -> Response | str:
# TODO: #603 upcoming session cookie change
user = db.session.get(User, session.get("user_id"))
if not user:
session.clear()
Expand Down Expand Up @@ -476,6 +480,7 @@ def upgrade() -> Response | str:
@bp.route("/disable-autorenew", methods=["POST"])
@authentication_required
def disable_autorenew() -> Response | str | Tuple[Response | str, int]:
# TODO: #603 upcoming session cookie change
user = db.session.get(User, session.get("user_id"))
if not user:
session.clear()
Expand Down Expand Up @@ -504,6 +509,7 @@ def disable_autorenew() -> Response | str | Tuple[Response | str, int]:
@bp.route("/enable-autorenew", methods=["POST"])
@authentication_required
def enable_autorenew() -> Response | str | Tuple[Response | str, int]:
# TODO: #603 upcoming session cookie change
user = db.session.get(User, session.get("user_id"))
if not user:
session.clear()
Expand Down Expand Up @@ -532,6 +538,7 @@ def enable_autorenew() -> Response | str | Tuple[Response | str, int]:
@bp.route("/cancel", methods=["POST"])
@authentication_required
def cancel() -> Response | str | Tuple[Response | str, int]:
# TODO: #603 upcoming session cookie change
user = db.session.get(User, session.get("user_id"))
if not user:
session.clear()
Expand Down Expand Up @@ -562,6 +569,7 @@ def cancel() -> Response | str | Tuple[Response | str, int]:
@bp.route("/status.json")
@authentication_required
def status() -> Response | str:
# TODO: #603 upcoming session cookie change
user = db.session.get(User, session.get("user_id"))
if not user:
session.clear()
Expand Down
19 changes: 19 additions & 0 deletions hushline/routes.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import json
import logging
import re
import secrets
Expand Down Expand Up @@ -101,12 +102,15 @@ def get_ip_address() -> str:
def init_app(app: Flask) -> None:
@app.route("/")
def index() -> Response:
# TODO: #603 upcoming session cookie change
if "user_id" in session:
# TODO: #603 upcoming session cookie change
user = db.session.get(User, session.get("user_id"))
if user:
return redirect(url_for("inbox"))

flash("🫥 User not found. Please log in again.")
# TODO: #603 upcoming session cookie change
session.pop("user_id", None) # Clear the invalid user_id from session
return redirect(url_for("login"))

Expand All @@ -115,6 +119,7 @@ def index() -> Response:
@app.route("/inbox")
@authentication_required
def inbox() -> Response | str:
# TODO: #603 upcoming session cookie change
user = db.session.get(User, session.get("user_id"))
if not user:
flash("👉 Please log in to access your inbox.")
Expand Down Expand Up @@ -167,6 +172,7 @@ def profile(username: str) -> Response | str:
user=uname.user,
username=uname,
display_name_or_username=uname.display_name or uname.username,
# TODO: #603 upcoming session cookie change
current_user_id=session.get("user_id"),
public_key=uname.user.pgp_key,
is_personal_server=app.config["IS_PERSONAL_SERVER"],
Expand Down Expand Up @@ -274,10 +280,12 @@ def redirect_submit_message(username: str) -> Response:
@app.route("/delete_message/<int:message_id>", methods=["POST"])
@authentication_required
def delete_message(message_id: int) -> Response:
# TODO: #603 upcoming session cookie change
if "user_id" not in session:
flash("🔑 Please log in to continue.")
return redirect(url_for("login"))

# TODO: #603 upcoming session cookie change
user = db.session.get(User, session.get("user_id"))
if not user:
flash("🫥 User not found. Please log in again.")
Expand Down Expand Up @@ -313,6 +321,7 @@ def delete_message(message_id: int) -> Response:
def register() -> Response | str | tuple[Response | str, int]:
if (
session.get("is_authenticated", False)
# TODO: #603 upcoming session cookie change
and (user_id := session.get("user_id", False))
and db.session.get(User, user_id)
):
Expand Down Expand Up @@ -379,6 +388,7 @@ def register() -> Response | str | tuple[Response | str, int]:

@app.route("/login", methods=["GET", "POST"])
def login() -> Response | str:
# TODO: #603 upcoming session cookie change
if "user_id" in session and session.get("is_authenticated", False):
flash("👉 You are already logged in.")
return redirect(url_for("inbox"))
Expand All @@ -390,6 +400,7 @@ def login() -> Response | str:
).one_or_none()
if username and username.user.check_password(form.password.data):
session.permanent = True
# TODO: #603 upcoming session cookie change
session["user_id"] = username.user_id
session["username"] = username.username
session["is_authenticated"] = True
Expand Down Expand Up @@ -421,6 +432,7 @@ def login() -> Response | str:
@app.route("/verify-2fa-login", methods=["GET", "POST"])
def verify_2fa_login() -> Response | str | tuple[Response | str, int]:
# Redirect to login if the login process has not started yet
# TODO: #603 upcoming session cookie change
user = db.session.get(User, session.get("user_id"))
if not user:
session.clear()
Expand Down Expand Up @@ -519,6 +531,7 @@ def get_directory_usernames(admin_first: bool = False) -> Sequence[Username]:

@app.route("/directory")
def directory() -> Response | str:
# TODO: #603 upcoming session cookie change
logged_in = "user_id" in session
is_personal_server = app.config["IS_PERSONAL_SERVER"]
return render_template(
Expand All @@ -530,6 +543,7 @@ def directory() -> Response | str:

@app.route("/directory/get-session-user.json")
def session_user() -> dict[str, bool]:
# TODO: #603 upcoming session cookie change
logged_in = "user_id" in session
return {"logged_in": logged_in}

Expand Down Expand Up @@ -564,3 +578,8 @@ def personal_server_info() -> Response:
@app.route("/health.json")
def health() -> dict[str, str]:
return {"status": "ok"}

@app.route('/session_info')
def session_info() -> str:
expiration = app.session_interface.get_expiration_time(app, session)
return json.dumps(dict(session, expiration=str(expiration)), indent=4)
11 changes: 11 additions & 0 deletions hushline/settings/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -201,6 +201,7 @@ def create_blueprint() -> Blueprint:
@authentication_required
@bp.route("/", methods=["GET", "POST"])
async def index() -> str | Response:
# TODO: #603 upcoming session cookie change
user_id = session.get("user_id")
if not user_id:
return redirect(url_for("login"))
Expand Down Expand Up @@ -342,6 +343,7 @@ async def index() -> str | Response:
@bp.route("/toggle-2fa", methods=["POST"])
@authentication_required
def toggle_2fa() -> Response:
# TODO: #603 upcoming session cookie change
user_id = session.get("user_id")
if not user_id:
return redirect(url_for("login"))
Expand All @@ -355,6 +357,7 @@ def toggle_2fa() -> Response:
@bp.route("/change-password", methods=["POST"])
@authentication_required
def change_password() -> str | Response:
# TODO: #603 upcoming session cookie change
user_id = session.get("user_id")
if not user_id:
flash("Session expired, please log in again.", "info")
Expand Down Expand Up @@ -391,6 +394,7 @@ def change_password() -> str | Response:
@bp.route("/enable-2fa", methods=["GET", "POST"])
@authentication_required
def enable_2fa() -> Response | str:
# TODO: #603 upcoming session cookie change
user = db.session.get(User, session.get("user_id"))
form = TwoFactorForm()

Expand Down Expand Up @@ -436,6 +440,7 @@ def enable_2fa() -> Response | str:
@bp.route("/disable-2fa", methods=["POST"])
@authentication_required
def disable_2fa() -> Response | str:
# TODO: #603 upcoming session cookie change
user_id = session.get("user_id")
if not user_id:
return redirect(url_for("login"))
Expand All @@ -455,6 +460,7 @@ def confirm_disable_2fa() -> Response | str:
@bp.route("/verify-2fa-setup", methods=["POST"])
@authentication_required
def verify_2fa_setup() -> Response | str:
# TODO: #603 upcoming session cookie change
user = db.session.get(User, session["user_id"])
if not user:
return redirect(url_for("login"))
Expand All @@ -476,6 +482,7 @@ def verify_2fa_setup() -> Response | str:
@bp.route("/update_pgp_key_proton", methods=["POST"])
@authentication_required
def update_pgp_key_proton() -> Response | str:
# TODO: #603 upcoming session cookie change
user_id = session.get("user_id")
if not user_id:
flash("⛔️ User not authenticated.")
Expand Down Expand Up @@ -521,6 +528,7 @@ def update_pgp_key_proton() -> Response | str:
@bp.route("/update-pgp-key", methods=["POST"])
@authentication_required
def update_pgp_key() -> Response | str:
# TODO: #603 upcoming session cookie change
user_id = session.get("user_id")
if not user_id:
flash("⛔️ User not authenticated.")
Expand Down Expand Up @@ -556,6 +564,7 @@ def update_pgp_key() -> Response | str:
@bp.route("/update-smtp-settings", methods=["POST"])
@authentication_required
def update_smtp_settings() -> Response | str:
# TODO: #603 upcoming session cookie change
user_id = session.get("user_id")
if not user_id:
return redirect(url_for("login"))
Expand Down Expand Up @@ -664,6 +673,7 @@ def update_brand_app_name() -> Response | str:
@bp.route("/delete-account", methods=["POST"])
@authentication_required
def delete_account() -> Response | str:
# TODO: #603 upcoming session cookie change
user_id = session.get("user_id")
if not user_id:
flash("Please log in to continue.")
Expand Down Expand Up @@ -692,6 +702,7 @@ def delete_account() -> Response | str:
async def alias(username_id: int) -> Response | str:
alias = db.session.scalars(
db.select(Username).filter_by(
# TODO: #603 upcoming session cookie change
id=username_id, user_id=session["user_id"], is_primary=False
)
).one_or_none()
Expand Down
2 changes: 2 additions & 0 deletions hushline/templates/base.html
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,7 @@ <h1>{{ host_org.brand_app_name }}</h1>
<div class="navGroup">
<a class="mobileNav btnIcon" aria-label="Navigation menu">Menu</a>
<ul>
<!-- TODO: #603 upcoming session cookie change -->
{% if 'user_id' in session and (session.get('is_authenticated', False)) %}
{% if is_premium_enabled and user.is_free_tier %}
<li>
Expand All @@ -121,6 +122,7 @@ <h1>{{ host_org.brand_app_name }}</h1>
{% if not is_personal_server %}
<li><a href="{{ url_for('vision') }}">Vision</a></li>
{% endif %}
<!-- TODO: #603 upcoming session cookie change -->
{% if 'user_id' in session and (session.get('is_authenticated', False)) %}
<li>
<a href="{{ url_for('inbox', username=session.username) }}"
Expand Down
2 changes: 2 additions & 0 deletions hushline/templates/settings/admin.html
Original file line number Diff line number Diff line change
Expand Up @@ -37,13 +37,15 @@ <h4>{{ user.primary_username.username }}</h4>
Admin: {{ "✅ Yes" if user.is_admin else "👎 No" }}
</p>
<div class="tableActions">
<!-- TODO: #603 upcoming session cookie change -->
<form
action="{{ url_for('admin.toggle_verified', user_id=user.id) }}"
method="POST"
class="formBody"
>
<button type="submit">Toggle Verified</button>
</form>
<!-- TODO: #603 upcoming session cookie change -->
<form
action="{{ url_for('admin.toggle_admin', user_id=user.id) }}"
method="POST"
Expand Down
2 changes: 2 additions & 0 deletions hushline/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
def authentication_required(f: Callable[..., Any]) -> Callable[..., Any]:
@wraps(f)
def decorated_function(*args: Any, **kwargs: Any) -> Any:
# TODO: #603 upcoming session cookie change
if "user_id" not in session:
flash("👉 Please complete authentication.")
return redirect(url_for("login"))
Expand All @@ -32,6 +33,7 @@ def admin_authentication_required(f: Callable[..., Any]) -> Callable[..., Any]:
@wraps(f)
@authentication_required
def decorated_function(*args: Any, **kwargs: Any) -> Any:
# TODO: #603 upcoming session cookie change
user = db.session.get(User, session["user_id"])
if not user or not user.is_admin:
abort(403)
Expand Down

0 comments on commit e588c15

Please sign in to comment.