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 @@