diff --git a/management/mailconfig.py b/management/mailconfig.py index 1ec17295..1dbc4ae6 100755 --- a/management/mailconfig.py +++ b/management/mailconfig.py @@ -286,6 +286,18 @@ def get_mail_users(env, as_map=False, map_by="maildrop"): return utils.sort_email_addresses(users, env) +def sizeof_fmt(num): + for unit in ['','K','M','G','T']: + if abs(num) < 1024.0: + if abs(num) > 99: + return "%3.0f%s" % (num, unit) + else: + return "%2.1f%s" % (num, unit) + + num /= 1024.0 + + return str(num) + def sizeof_fmt(num): for unit in ['','K','M','G','T']: if abs(num) < 1024.0: @@ -794,6 +806,14 @@ def add_mail_user(email, pw, privs, quota, display_name, env): except ValueError as e: return (str(e), 400) + if quota is None: + quota = '0' + + try: + quota = validate_quota(quota) + except ValueError as e: + return (str(e), 400) + # get the database conn = open_database(env) @@ -867,6 +887,8 @@ def add_mail_user(email, pw, privs, quota, display_name, env): dovecot_quota_recalc(email) + dovecot_quota_recalc(email) + # Update things in case any new domains are added. if domain_added: return kick(env, return_status) @@ -976,6 +998,40 @@ def validate_quota(quota): return quota + +def get_mail_quota(email, env): + user = find_mail_user(env, email, ['mailboxQuota']) + if user is None: + return ("That's not a user (%s)." % email, 400) + if len(user['mailboxQuota'])==0: + return '0' + else: + return user['mailboxQuota'][0] + +def set_mail_quota(email, quota, env): + # validate that password is acceptable + quota = validate_quota(quota) + + # update the database + conn = open_database(env) + user = find_mail_user(env, email, ['mailboxQuota'], conn) + if user is None: + return ("That's not a user (%s)." % email, 400) + + conn.modify_record(user, { 'mailboxQuota': quota }) + dovecot_quota_recalc(email) + return "OK" + +def dovecot_quota_recalc(email): + # dovecot processes running for the user will not recognize the new quota setting + # a reload is necessary to reread the quota setting, but it will also shut down + # running dovecot processes. Email clients generally log back in when they lose + # a connection. + # subprocess.call(['doveadm', 'reload']) + + # force dovecot to recalculate the quota info for the user. + subprocess.call(["doveadm", "quota", "recalc", "-u", email]) + def get_mail_password(email, env): # Gets the hashed passwords for a user. In ldap, userPassword is # multi-valued and each value can have different hash. This diff --git a/setup/mail-users.sh b/setup/mail-users.sh index 026977a4..d7a5fe67 100755 --- a/setup/mail-users.sh +++ b/setup/mail-users.sh @@ -93,8 +93,8 @@ user_filter = (&(objectClass=mailUser)(|(mail=%u)(maildrop=%u))) user_attrs = maildrop=user, \ mailboxQuota=quota_rule=*:bytes=%\$, \ =quota_rule2=Trash:storage=+100M, \ - =quota_rule3=Drafts:ignore, \ - =quota_rule4=Sent:ignore + =quota_rule3=Drafts:storage=+25M, \ + =quota_rule4=Sent:storage=+50M # Account iteration for various dovecot tools (doveadm) iterate_filter = (objectClass=mailUser) diff --git a/tests/lib/installed-state.sh b/tests/lib/installed-state.sh index 174b37e5..47645a60 100644 --- a/tests/lib/installed-state.sh +++ b/tests/lib/installed-state.sh @@ -178,17 +178,16 @@ installed_state_compare() { # s2: re-sort aliases jq -c ".[] | .aliases | sort_by(.address) | .[] | {address:.address, forwards_to:.forwards_to, permitted_senders:.permitted_senders, auto:.auto, description:.description}" "$s2/aliases.json" > "$s2/aliases-cmp.json" - fi - if [ $MIGRATION_ML_VERSION_A -le 2 -a $MIGRATION_ML_VERSION_B -ge 3 ]; then - # miabldap migration level <=2 does not have quota fields, so - # remove them from the comparison - grep -vE '"(quota|box_quota|box_size|percent)":' "$s2/users-cmp.json" > "$s2/users-cmp2.json" || changed="true" - cp "$s2/users-cmp2.json" "$s2/users-cmp.json" && rm -f "$s2/users-cmp2.json" + if [ $MIGRATION_ML_VERSION_A -le 2 -a $MIGRATION_ML_VERSION_B -ge 3 ]; then + # miabldap migration level <=2 does not have quota fields, so + # remove them from the comparison + grep -vE '"(quota|box_quota|box_size|percent)":' "$s2/users-cmp.json" > "$s2/users-cmp2.json" || changed="true" + cp "$s2/users-cmp2.json" "$s2/users-cmp.json" && rm -f "$s2/users-cmp2.json" + fi fi - # # users #