from typing import Optional from flask import render_template, request, redirect, url_for, flash from flask_login import login_required, current_user from flask_wtf import FlaskForm from wtforms import StringField, validators from app.alias_audit_log_utils import emit_alias_audit_log, AliasAuditLogAction from app.dashboard.base import dashboard_bp from app.db import Session from app.models import Contact from app.pgp_utils import PGPException, load_public_key_and_check class PGPContactForm(FlaskForm): action = StringField( "action", validators=[validators.DataRequired(), validators.AnyOf(("save", "remove"))], ) pgp = StringField("pgp", validators=[validators.Optional()]) @dashboard_bp.route("/contact//", methods=["GET", "POST"]) @login_required def contact_detail_route(contact_id): contact: Optional[Contact] = Contact.get(contact_id) if not contact or contact.user_id != current_user.id: flash("You cannot see this page", "warning") return redirect(url_for("dashboard.index")) alias = contact.alias pgp_form = PGPContactForm() if request.method == "POST": if request.form.get("form-name") == "pgp": if not pgp_form.validate(): flash("Invalid request", "warning") return redirect(request.url) if pgp_form.action.data == "save": if not current_user.is_premium(): flash("Only premium plan can add PGP Key", "warning") return redirect( url_for("dashboard.contact_detail_route", contact_id=contact_id) ) if not pgp_form.pgp.data: flash("Invalid pgp key") else: contact.pgp_public_key = pgp_form.pgp.data try: contact.pgp_finger_print = load_public_key_and_check( contact.pgp_public_key ) except PGPException: flash("Cannot add the public key, please verify it", "error") else: emit_alias_audit_log( alias=alias, action=AliasAuditLogAction.UpdateContact, message=f"Added PGP key {contact.pgp_public_key} for contact {contact_id} ({contact.email})", ) Session.commit() flash( f"PGP public key for {contact.email} is saved successfully", "success", ) return redirect( url_for( "dashboard.contact_detail_route", contact_id=contact_id ) ) elif pgp_form.action.data == "remove": # Free user can decide to remove contact PGP key emit_alias_audit_log( alias=alias, action=AliasAuditLogAction.UpdateContact, message=f"Removed PGP key {contact.pgp_public_key} for contact {contact_id} ({contact.email})", ) contact.pgp_public_key = None contact.pgp_finger_print = None Session.commit() flash(f"PGP public key for {contact.email} is removed", "success") return redirect( url_for("dashboard.contact_detail_route", contact_id=contact_id) ) return render_template( "dashboard/contact_detail.html", contact=contact, alias=alias, pgp_form=pgp_form )