From ccad47937e509d065fbe4bc9173f5ce4a391a0ab Mon Sep 17 00:00:00 2001 From: John Supplee Date: Mon, 28 Jan 2019 23:27:03 +0200 Subject: [PATCH] Add components to user interface for setting quotas --- management/daemon.py | 10 ++++++++- management/mailconfig.py | 27 ++++++++++++++++++++++- management/templates/users.html | 39 +++++++++++++++++++++++++++++++-- 3 files changed, 72 insertions(+), 4 deletions(-) diff --git a/management/daemon.py b/management/daemon.py index 572b6b4a..5b3bd326 100755 --- a/management/daemon.py +++ b/management/daemon.py @@ -9,7 +9,7 @@ import auth, utils, multiprocessing.pool from mailconfig import get_mail_users, get_mail_users_ex, get_admins, add_mail_user, set_mail_password, remove_mail_user from mailconfig import get_mail_user_privileges, add_remove_mail_user_privilege from mailconfig import get_mail_aliases, get_mail_aliases_ex, get_mail_domains, add_mail_alias, remove_mail_alias - +from mailconfig import set_mail_quota env = utils.load_environment() auth_service = auth.KeyAuthService() @@ -158,6 +158,14 @@ def mail_users_add(): except ValueError as e: return (str(e), 400) +@app.route('/mail/users/quota', methods=['POST']) +@authorized_personnel_only +def mail_users_quota(): + try: + return set_mail_quota(request.form.get('email', ''), request.form.get('quota'), env) + except ValueError as e: + return (str(e), 400) + @app.route('/mail/users/password', methods=['POST']) @authorized_personnel_only def mail_users_password(): diff --git a/management/mailconfig.py b/management/mailconfig.py index 783461ec..62ca1d39 100755 --- a/management/mailconfig.py +++ b/management/mailconfig.py @@ -135,7 +135,7 @@ def get_mail_users_ex(env, with_archived=False): user = { "email": email, "privileges": parse_privs(privileges), - "quota": 'unlimited' if quota == '0' else quota, + "quota": quota, "status": "active", } users.append(user) @@ -333,6 +333,31 @@ def hash_password(pw): # http://wiki2.dovecot.org/Authentication/PasswordSchemes return utils.shell('check_output', ["/usr/bin/doveadm", "pw", "-s", "SHA512-CRYPT", "-p", pw]).strip() +def set_mail_quota(email, quota, env): + # validate that password is acceptable + quota = validate_quota(quota) + + # update the database + conn, c = open_database(env, with_connection=True) + c.execute("UPDATE users SET quota=? WHERE email=?", (quota, email)) + if c.rowcount != 1: + return ("That's not a user (%s)." % email, 400) + conn.commit() + return "OK" + +def validate_quota(quota): + # validate quota + quota = quota.strip().upper() + + if quota == "": + raise ValueError("No quota provided.") + if re.search(r"[\s,.]", quota): + raise ValueError("Quotas cannot contain spaces or commas.") + if not re.match(r'^\d+[GM]?$', quota): + raise ValueError("Invalid quota.") + + return quota + def get_mail_password(email, env): # Gets the hashed password for a user. Passwords are stored in Dovecot's # password format, with a prefixed scheme. diff --git a/management/templates/users.html b/management/templates/users.html index 09a66bc6..40f3be08 100644 --- a/management/templates/users.html +++ b/management/templates/users.html @@ -41,7 +41,7 @@ - + @@ -61,6 +61,10 @@ + + set quota + + | set password @@ -155,8 +159,9 @@ function show_users() { n2.addClass("account_" + user.status); n.attr('data-email', user.email); + n.attr('data-quota', user.quota); n.find('.address').text(user.email); - n.find('.quota').text(user.quota); + n.find('.quota').text((user.quota == '0') ? 'unlimited' : user.quota); n2.find('.restore_info tt').text(user.mailbox); if (user.status == 'inactive') continue; @@ -233,6 +238,36 @@ function users_set_password(elem) { }); } +function users_set_quota(elem) { + var email = $(elem).parents('tr').attr('data-email'); + var quota = $(elem).parents('tr').attr('data-quota'); + + show_modal_confirm( + "Set Quota", + $("

Set quota for " + email + "?

" + + "

" + + "" + + "

" + + "

Quotas may not contain any numbers or commas. Suffixes of G (gigabytes) and M (megabytes) are allowed.

" + + "

For unlimited storage enter 0 (zero)

"), + "Set Quota", + function() { + api( + "/mail/users/quota", + "POST", + { + email: email, + quota: $('#users_set_quota').val() + }, + function(r) { + show_users(); + }, + function(r) { + show_modal_error("Set Quota", r); + }); + }); +} + function users_remove(elem) { var email = $(elem).parents('tr').attr('data-email');
Email AddressEmail Address Quota Actions