from typing import Optional from flask import Blueprint, Response, flash, redirect, render_template, url_for from flask.typing import ResponseReturnValue from app.extensions import db from app.models.bridges import Bridge from app.portal.util import LifecycleForm bp = Blueprint("bridge", __name__) _SECTION_TEMPLATE_VARS = { "section": "bridge", "help_url": "https://bypass.censorship.guide/user/bridges.html", } @bp.route("/list") def bridge_list() -> ResponseReturnValue: bridges = Bridge.query.filter(Bridge.destroyed.is_(None)).all() return render_template( "list.html.j2", title="Tor Bridges", item="bridge", items=bridges, **_SECTION_TEMPLATE_VARS, ) @bp.route("/block/", methods=["GET", "POST"]) def bridge_blocked(bridge_id: int) -> ResponseReturnValue: bridge: Optional[Bridge] = Bridge.query.filter( Bridge.id == bridge_id, Bridge.destroyed.is_(None) ).first() if bridge is None: return Response( render_template( "error.html.j2", header="404 Proxy Not Found", message="The requested bridge could not be found.", **_SECTION_TEMPLATE_VARS, ) ) form = LifecycleForm() if form.validate_on_submit(): bridge.deprecate(reason="manual") db.session.commit() flash("Bridge will be shortly replaced.", "success") return redirect( url_for("portal.bridgeconf.bridgeconf_edit", bridgeconf_id=bridge.conf_id) ) return render_template( "lifecycle.html.j2", header=f"Mark bridge {bridge.hashed_fingerprint} as blocked?", message=bridge.hashed_fingerprint, form=form, **_SECTION_TEMPLATE_VARS, ) @bp.route("/expire/", methods=["GET", "POST"]) def bridge_expire(bridge_id: int) -> ResponseReturnValue: bridge: Optional[Bridge] = Bridge.query.filter( Bridge.id == bridge_id, Bridge.destroyed.is_(None) ).first() if bridge is None: return Response( render_template( "error.html.j2", header="404 Proxy Not Found", message="The requested bridge could not be found.", **_SECTION_TEMPLATE_VARS, ) ) form = LifecycleForm() if form.validate_on_submit(): bridge.destroy() db.session.commit() flash("Bridge will be shortly destroyed.", "success") return redirect( url_for("portal.bridgeconf.bridgeconf_edit", bridgeconf_id=bridge.conf_id) ) return render_template( "lifecycle.html.j2", header=f"Destroy bridge {bridge.hashed_fingerprint}?", message=bridge.hashed_fingerprint, form=form, **_SECTION_TEMPLATE_VARS, )