diff --git a/management/daemon.py b/management/daemon.py index f23c2af1..61e55451 100755 --- a/management/daemon.py +++ b/management/daemon.py @@ -104,12 +104,18 @@ def mail_users(): @app.route('/mail/users/add', methods=['POST']) @authorized_personnel_only def mail_users_add(): - return add_mail_user(request.form.get('email', ''), request.form.get('password', ''), request.form.get('privileges', ''), env) + try: + return add_mail_user(request.form.get('email', ''), request.form.get('password', ''), request.form.get('privileges', ''), env) + except ValueError as e: + return (str(e), 400) @app.route('/mail/users/password', methods=['POST']) @authorized_personnel_only def mail_users_password(): - return set_mail_password(request.form.get('email', ''), request.form.get('password', ''), env) + try: + return set_mail_password(request.form.get('email', ''), request.form.get('password', ''), env) + except ValueError as e: + return (str(e), 400) @app.route('/mail/users/remove', methods=['POST']) @authorized_personnel_only diff --git a/management/mailconfig.py b/management/mailconfig.py index e3128f39..1c05f2bc 100755 --- a/management/mailconfig.py +++ b/management/mailconfig.py @@ -139,13 +139,7 @@ def add_mail_user(email, pw, privs, env): if not validate_email(email, mode='user'): return ("Invalid email address.", 400) - # validate password - if pw.strip() == "": - return ("No password provided.", 400) - if re.search(r"[\s]", pw): - return ("Passwords cannot contain spaces.", 400) - if len(pw) < 4: - return ("Passwords must be at least four characters.", 400) + validate_password(pw) # validate privileges if privs is None or privs.strip() == "": @@ -193,6 +187,8 @@ def add_mail_user(email, pw, privs, env): return kick(env, "mail user added") def set_mail_password(email, pw, env): + validate_password(pw) + # hash the password pw = utils.shell('check_output', ["/usr/bin/doveadm", "pw", "-s", "SHA512-CRYPT", "-p", pw]).strip() @@ -386,6 +382,16 @@ def kick(env, mail_result=None): return "".join(s for s in results if s != "") +def validate_password(pw): + # validate password + if pw.strip() == "": + raise ValueError("No password provided.") + if re.search(r"[\s]", pw): + raise ValueError("Passwords cannot contain spaces.") + if len(pw) < 4: + raise ValueError("Passwords must be at least four characters.") + + if __name__ == "__main__": import sys if len(sys.argv) > 2 and sys.argv[1] == "validate-email": diff --git a/management/templates/index.html b/management/templates/index.html index a37644ce..f6e6ee06 100644 --- a/management/templates/index.html +++ b/management/templates/index.html @@ -182,6 +182,11 @@ var global_modal_state = null; var global_modal_funcs = null; $(function() { + $('#global_modal').on('shown.bs.modal', function (e) { + // set focus to first input in the global modal's body + var input = $('#global_modal .modal-body input'); + if (input.length > 0) $(input[0]).focus(); + }) $('#global_modal .btn-danger').click(function() { // Don't take action now. Wait for the modal to be totally hidden // so that we don't attempt to show another modal while this one diff --git a/management/templates/users.html b/management/templates/users.html index 1e420c52..cc58c6c1 100644 --- a/management/templates/users.html +++ b/management/templates/users.html @@ -52,6 +52,13 @@ + + + set password + + | + + @@ -141,11 +148,35 @@ function do_add_user() { return false; } +function users_set_password(elem) { + var email = $(elem).parents('tr').attr('data-email'); + show_modal_confirm( + "Archive User", + $("

Set a new password for " + email + "?

Passwords must be at least four characters and may not contain spaces.

"), + "Set Password", + function() { + api( + "/mail/users/password", + "POST", + { + email: email, + password: $('#users_set_password_pw').val() + }, + function(r) { + // Responses are multiple lines of pre-formatted text. + show_modal_error("Set Password", $("
").text(r));
+        },
+        function(r) {
+          show_modal_error("Set Password", r);
+        });
+    });
+}
+
 function users_remove(elem) {
   var email = $(elem).parents('tr').attr('data-email');
   show_modal_confirm(
     "Archive User",
-    $("

Are you sure you want to archive " + email + "?

The user's mailboxes will not be deleted (you can do that later), but the user will no longer be able to log into any services on this machine.

"), + $("

Are you sure you want to archive " + email + "?

The user's mailboxes will not be deleted (you can do that later), but the user will no longer be able to log into any services on this machine.

"), "Archive", function() { api( @@ -178,7 +209,7 @@ function mod_priv(elem, add_remove) { var add_remove1 = add_remove.charAt(0).toUpperCase() + add_remove.substring(1); show_modal_confirm( "Modify Privileges", - "Are you sure you want to " + add_remove + " the " + priv + " privilege for " + email + "?", + "Are you sure you want to " + add_remove + " the " + priv + " privilege for " + email + "?", add_remove1, function() { api(