diff --git a/app/dashboard/__init__.py b/app/dashboard/__init__.py index 4fa49b9a..4cc25e80 100644 --- a/app/dashboard/__init__.py +++ b/app/dashboard/__init__.py @@ -13,4 +13,5 @@ from .views import ( mfa_cancel, domain_detail, lifetime_licence, + directory, ) diff --git a/app/dashboard/templates/dashboard/directory.html b/app/dashboard/templates/dashboard/directory.html new file mode 100644 index 00000000..71a44257 --- /dev/null +++ b/app/dashboard/templates/dashboard/directory.html @@ -0,0 +1,94 @@ +{% extends 'default.html' %} +{% set active_page = "directory" %} + +{% block title %} + Directory +{% endblock %} + +{% block default_content %} +
+
+

Directories

+ + + + {% for dir in dirs %} +
+
+
+ {{ dir.name }} +
+
+ Created {{ dir.created_at | dt }}
+ {{ dir.nb_alias() }} aliases. +
+
+ + + +
+ {% endfor %} + + {% if dirs|length > 0 %} +
+ {% endif %} + +
+ {{ new_dir_form.csrf_token }} + + +
Directory Name
+
+ Directory name must be at least 3 characters. + Only letter, number, dash (-), underscore (_) can be used. +
+ + {{ new_dir_form.name(class="form-control", placeholder="my-directory", pattern="[0-9A-Za-z-_]{3,}", + title="Only letter, number, dash (-), underscore (_) can be used. Directory name must be at least 3 characters.", + autofocus="1") }} + {{ render_field_errors(new_dir_form.name) }} + +
+ +
+ +
+{% endblock %} + +{% block script %} + +{% endblock %} \ No newline at end of file diff --git a/app/dashboard/views/directory.py b/app/dashboard/views/directory.py new file mode 100644 index 00000000..f0b8f912 --- /dev/null +++ b/app/dashboard/views/directory.py @@ -0,0 +1,76 @@ +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.config import EMAIL_DOMAIN +from app.dashboard.base import dashboard_bp +from app.extensions import db +from app.models import Directory + + +class NewDirForm(FlaskForm): + name = StringField( + "name", validators=[validators.DataRequired(), validators.Length(min=3)] + ) + + +@dashboard_bp.route("/directory", methods=["GET", "POST"]) +@login_required +def directory(): + # only premium user can add directory + if not current_user.is_premium(): + flash("Only premium user can add directories", "warning") + return redirect(url_for("dashboard.index")) + + dirs = Directory.query.filter_by(user_id=current_user.id).all() + + new_dir_form = NewDirForm() + + if request.method == "POST": + if request.form.get("form-name") == "delete": + dir_id = request.form.get("dir-id") + dir = Directory.get(dir_id) + + if not dir: + flash("Unknown error. Refresh the page", "warning") + return redirect(url_for("dashboard.directory")) + elif dir.user_id != current_user.id: + flash("You cannot delete this directory", "warning") + return redirect(url_for("dashboard.directory")) + + name = dir.name + Directory.delete(dir_id) + db.session.commit() + flash(f"Directory {name} has been deleted", "success") + + return redirect(url_for("dashboard.directory")) + + elif request.form.get("form-name") == "create": + if new_dir_form.validate(): + new_dir_name = new_dir_form.name.data + + if Directory.get_by(name=new_dir_name): + flash(f"{new_dir_name} already added", "warning") + # ra+ and reply+ are reserved for reply-email and reverse-alias + elif new_dir_name in ("ra", "reply"): + flash( + f"{new_dir_name} cannot be *ra* and *reply*, please use another name!", + "warning", + ) + else: + new_dir = Directory.create( + name=new_dir_name, user_id=current_user.id + ) + db.session.commit() + + flash(f"Directory {new_dir.name} is created", "success") + + return redirect(url_for("dashboard.directory",)) + + return render_template( + "dashboard/directory.html", + dirs=dirs, + new_dir_form=new_dir_form, + EMAIL_DOMAIN=EMAIL_DOMAIN, + ) diff --git a/templates/menu.html b/templates/menu.html index d89abeca..e93e73e4 100644 --- a/templates/menu.html +++ b/templates/menu.html @@ -30,6 +30,14 @@ + +