Add percentage used and update tools/mail.py to set quotas

This commit is contained in:
John Supplee 2019-02-01 15:36:27 +02:00
parent fa66585b6b
commit 7874683618
5 changed files with 94 additions and 17 deletions

View File

@ -56,6 +56,19 @@ Todo
Changes
-------
### v0.40-quota-0.13-alpha
* Add a `default-quota` setting in `settings.yaml`
* Add input for setting quota when entering a new user in control panel
* Modify `tools/mail.py` to allow for setting and getting the default system quota
* Modify `tools/mail.py` to allow for getting a user's quota setting
* Modify the mail users list in control panel to display percentage used
### v0.40-quota-0.12-alpha
* Update README

View File

@ -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, get_default_quota, validate_quota
from mailconfig import get_mail_quota, set_mail_quota, get_default_quota, validate_quota
env = utils.load_environment()
auth_service = auth.KeyAuthService()
@ -153,11 +153,26 @@ def mail_users():
@app.route('/mail/users/add', methods=['POST'])
@authorized_personnel_only
def mail_users_add():
quota = request.form.get('quota', get_default_quota(env))
try:
return add_mail_user(request.form.get('email', ''), request.form.get('password', ''), request.form.get('privileges', ''), request.form.get('quota', ''), env)
return add_mail_user(request.form.get('email', ''), request.form.get('password', ''), request.form.get('privileges', ''), quota, env)
except ValueError as e:
return (str(e), 400)
@app.route('/mail/users/quota', methods=['GET'])
@authorized_personnel_only
def get_mail_users_quota():
email = request.values.get('email', '')
quota = get_mail_quota(email, env)
if request.values.get('text'):
return quota
return json_response({
"email": email,
"quota": quota
})
@app.route('/mail/users/quota', methods=['POST'])
@authorized_personnel_only
def mail_users_quota():
@ -531,16 +546,19 @@ def privacy_status_set():
@app.route('/system/default-quota', methods=["GET"])
@authorized_personnel_only
def default_quota_get():
return json_response({
"default-quota": get_default_quota(env)
})
if request.values.get('text'):
return get_default_quota(env)
else:
return json_response({
"default-quota": get_default_quota(env),
})
@app.route('/system/default-quota', methods=["POST"])
@authorized_personnel_only
def default_quota_set():
config = utils.load_settings(env)
try:
config["default-quota"] = validate_quota(request.form.get('default_quota'))
config["default-quota"] = validate_quota(request.values.get('default_quota'))
utils.write_settings(config, env)
except ValueError as e:

View File

@ -147,18 +147,30 @@ def get_mail_users_ex(env, with_archived=False):
(user, domain) = email.split('@')
box_size = 0
box_count = 0
box_quota = ''
box_quota = 0
percent = ''
try:
dirsize_file = os.path.join(env['STORAGE_ROOT'], 'mail/mailboxes/%s/%s/maildirsize' % (domain, user))
with open(dirsize_file, 'r') as f:
box_quota = f.readline()
box_quota = int(f.readline().split('S')[0])
for line in f.readlines():
(size, count) = line.split(' ')
box_size += int(size)
box_count += int(count)
try:
percent = (box_size / box_quota) * 100
except:
percent = 'Error'
except:
box_size = '?'
box_count = '?'
box_quota = '?'
percent = '?'
if quota == '0':
percent = ''
user = {
"email": email,
@ -166,6 +178,7 @@ def get_mail_users_ex(env, with_archived=False):
"quota": quota,
"box_quota": box_quota,
"box_size": sizeof_fmt(box_size) if box_size != '?' else box_size,
"percent": '%3.0f%%' % percent if type(percent) != str else percent,
"box_count": box_count,
"status": "active",
}
@ -324,6 +337,9 @@ def add_mail_user(email, pw, privs, quota, env):
validation = validate_privilege(p)
if validation: return validation
if quota is None:
quota = get_default_quota()
try:
quota = validate_quota(quota)
except ValueError as e:
@ -338,7 +354,7 @@ def add_mail_user(email, pw, privs, quota, env):
# add the user to the database
try:
c.execute("INSERT INTO users (email, password, privileges, quota) VALUES (?, ?, ?, ?)",
(email, pw, "\n".join(privs)), quota)
(email, pw, "\n".join(privs), quota))
except sqlite3.IntegrityError:
return ("User already exists.", 400)
@ -369,6 +385,15 @@ 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 get_mail_quota(email, env):
conn, c = open_database(env, with_connection=True)
c.execute("SELECT quota FROM users WHERE email=?", (email,))
rows = c.fetchall()
if len(rows) != 1:
return ("That's not a user (%s)." % email, 400)
return rows[0][0]
def set_mail_quota(email, quota, env):
# validate that password is acceptable
quota = validate_quota(quota)

View File

@ -7,6 +7,7 @@
#user_table .account_inactive .if_active { display: none; }
#user_table .account_active .if_inactive { display: none; }
#user_table .account_active.if_inactive { display: none; }
.row-center { text-align: center; }
</style>
<h3>Add a mail user</h3>
@ -47,9 +48,10 @@
<thead>
<tr>
<th width="35%">Email Address</th>
<th>Messages</th>
<th>Size</th>
<th>Quota</th>
<th class="row-center">Messages</th>
<th class="row-center">Size</th>
<th class="row-center">Used</th>
<th class="row-center">Quota</th>
<th>Actions</th>
</tr>
</thead>
@ -62,9 +64,10 @@
<tr id="user-template">
<td class='address'>
</td>
<td class="box-count"></td>
<td class="box-size"></td>
<td class="quota">
<td class="box-count row-center"></td>
<td class="box-size row-center"></td>
<td class="percent row-center"></td>
<td class="quota row-center">
</td>
<td class='actions'>
<span class='privs'>
@ -159,7 +162,7 @@ function show_users() {
function(r) {
$('#user_table tbody').html("");
for (var i = 0; i < r.length; i++) {
var hdr = $("<tr><td colspan='3'><h4/></td></tr>");
var hdr = $("<tr><td colspan='6'><h4/></td></tr>");
hdr.find('h4').text(r[i].domain);
$('#user_table tbody').append(hdr);
@ -180,7 +183,14 @@ function show_users() {
n.attr('data-quota', user.quota);
n.find('.address').text(user.email);
n.find('.box-count').text(user.box_count);
if (user.box_count == '?') {
n.find('.box-count').attr('title', 'Message count is unkown')
}
n.find('.box-size').text(user.box_size);
if (user.box_size == '?') {
n.find('.box-size').attr('title', 'Mailbox size is unkown')
}
n.find('.percent').text(user.percent)
n.find('.quota').text((user.quota == '0') ? 'unlimited' : user.quota);
n2.find('.restore_info tt').text(user.mailbox);

View File

@ -57,10 +57,11 @@ def setup_key_auth(mgmt_uri):
if len(sys.argv) < 2:
print("Usage: ")
print(" tools/mail.py system default-quota [new default]")
print(" tools/mail.py user (lists users with quotas)")
print(" tools/mail.py user add user@domain.com [password]")
print(" tools/mail.py user password user@domain.com [password]")
print(" tools/mail.py user quota user@domain new-quota")
print(" tools/mail.py user quota user@domain [new-quota]")
print(" tools/mail.py user remove user@domain.com")
print(" tools/mail.py user make-admin user@domain.com")
print(" tools/mail.py user remove-admin user@domain.com")
@ -121,6 +122,10 @@ elif sys.argv[1] == "user" and sys.argv[2] == "admins":
if "admin" in user['privileges']:
print(user['email'])
elif sys.argv[1] == "user" and sys.argv[2] == "quota" and len(sys.argv) == 4:
# Set a user's quota
print(mgmt("/mail/users/quota?text=1&email=%s" % sys.argv[3]))
elif sys.argv[1] == "user" and sys.argv[2] == "quota" and len(sys.argv) == 5:
# Set a user's quota
users = mgmt("/mail/users/quota", { "email": sys.argv[3], "quota": sys.argv[4] })
@ -134,6 +139,12 @@ elif sys.argv[1] == "alias" and sys.argv[2] == "add" and len(sys.argv) == 5:
elif sys.argv[1] == "alias" and sys.argv[2] == "remove" and len(sys.argv) == 4:
print(mgmt("/mail/aliases/remove", { "address": sys.argv[3] }))
elif sys.argv[1] == "system" and sys.argv[2] == "default-quota" and len(sys.argv) == 3:
print(mgmt("/system/default-quota?text=1"))
elif sys.argv[1] == "system" and sys.argv[2] == "default-quota" and len(sys.argv) == 4:
print(mgmt("/system/default-quota", { "default_quota": sys.argv[3]}))
else:
print("Invalid command-line arguments.")
sys.exit(1)