We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
Prevent admin journalists from deleting themselves
To prevent lockouts and other forms of usability degradation, I propose one of two things:
1) a full ban on any admin from deleting themselves
2) an admin may not delete themselves if they are the last remaining admin

--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `securedrop/journalist_app/admin.py`
Content:
```
1 # -*- coding: utf-8 -*-
2 
3 import os
4 
5 from flask import (Blueprint, render_template, request, url_for, redirect, g,
6                    current_app, flash, abort)
7 from flask_babel import gettext
8 from sqlalchemy.exc import IntegrityError
9 from sqlalchemy.orm.exc import NoResultFound
10 
11 from db import (db_session, Journalist, InvalidUsernameException,
12                 PasswordError)
13 from journalist_app.decorators import admin_required
14 from journalist_app.utils import (make_password, commit_account_changes,
15                                   set_diceware_password)
16 from journalist_app.forms import LogoForm, NewUserForm
17 
18 
19 def make_blueprint(config):
20     view = Blueprint('admin', __name__)
21 
22     @view.route('/', methods=('GET', 'POST'))
23     @admin_required
24     def index():
25         users = Journalist.query.all()
26         return render_template("admin.html", users=users)
27 
28     @view.route('/config', methods=('GET', 'POST'))
29     @admin_required
30     def manage_config():
31         form = LogoForm()
32         if form.validate_on_submit():
33             f = form.logo.data
34             static_filepath = os.path.join(config.SECUREDROP_ROOT,
35                                            "static/i/logo.png")
36             f.save(static_filepath)
37             flash(gettext("Image updated."), "notification")
38             return redirect(url_for("admin.manage_config"))
39         else:
40             return render_template("config.html", form=form)
41 
42     @view.route('/add', methods=('GET', 'POST'))
43     @admin_required
44     def add_user():
45         form = NewUserForm()
46         if form.validate_on_submit():
47             form_valid = True
48             username = request.form['username']
49             password = request.form['password']
50             is_admin = bool(request.form.get('is_admin'))
51 
52             try:
53                 otp_secret = None
54                 if request.form.get('is_hotp', False):
55                     otp_secret = request.form.get('otp_secret', '')
56                 new_user = Journalist(username=username,
57                                       password=password,
58                                       is_admin=is_admin,
59                                       otp_secret=otp_secret)
60                 db_session.add(new_user)
61                 db_session.commit()
62             except PasswordError:
63                 flash(gettext(
64                       'There was an error with the autogenerated password. '
65                       'User not created. Please try again.'), 'error')
66                 form_valid = False
67             except InvalidUsernameException as e:
68                 form_valid = False
69                 flash('Invalid username: ' + str(e), "error")
70             except IntegrityError as e:
71                 db_session.rollback()
72                 form_valid = False
73                 if "UNIQUE constraint failed: journalists.username" in str(e):
74                     flash(gettext("That username is already in use"),
75                           "error")
76                 else:
77                     flash(gettext("An error occurred saving this user"
78                                   " to the database."
79                                   " Please inform your administrator."),
80                           "error")
81                     current_app.logger.error("Adding user "
82                                              "'{}' failed: {}".format(
83                                                  username, e))
84 
85             if form_valid:
86                 return redirect(url_for('admin.new_user_two_factor',
87                                         uid=new_user.id))
88 
89         return render_template("admin_add_user.html",
90                                password=make_password(config),
91                                form=form)
92 
93     @view.route('/2fa', methods=('GET', 'POST'))
94     @admin_required
95     def new_user_two_factor():
96         user = Journalist.query.get(request.args['uid'])
97 
98         if request.method == 'POST':
99             token = request.form['token']
100             if user.verify_token(token):
101                 flash(gettext(
102                     "Token in two-factor authentication "
103                     "accepted for user {user}.").format(
104                         user=user.username),
105                     "notification")
106                 return redirect(url_for("admin.index"))
107             else:
108                 flash(gettext(
109                     "Could not verify token in two-factor authentication."),
110                       "error")
111 
112         return render_template("admin_new_user_two_factor.html", user=user)
113 
114     @view.route('/reset-2fa-totp', methods=['POST'])
115     @admin_required
116     def reset_two_factor_totp():
117         uid = request.form['uid']
118         user = Journalist.query.get(uid)
119         user.is_totp = True
120         user.regenerate_totp_shared_secret()
121         db_session.commit()
122         return redirect(url_for('admin.new_user_two_factor', uid=uid))
123 
124     @view.route('/reset-2fa-hotp', methods=['POST'])
125     @admin_required
126     def reset_two_factor_hotp():
127         uid = request.form['uid']
128         otp_secret = request.form.get('otp_secret', None)
129         if otp_secret:
130             user = Journalist.query.get(uid)
131             try:
132                 user.set_hotp_secret(otp_secret)
133             except TypeError as e:
134                 if "Non-hexadecimal digit found" in str(e):
135                     flash(gettext(
136                         "Invalid secret format: "
137                         "please only submit letters A-F and numbers 0-9."),
138                           "error")
139                 elif "Odd-length string" in str(e):
140                     flash(gettext(
141                         "Invalid secret format: "
142                         "odd-length secret. Did you mistype the secret?"),
143                           "error")
144                 else:
145                     flash(gettext(
146                         "An unexpected error occurred! "
147                         "Please inform your administrator."), "error")
148                     current_app.logger.error(
149                         "set_hotp_secret '{}' (id {}) failed: {}".format(
150                             otp_secret, uid, e))
151                 return render_template('admin_edit_hotp_secret.html', uid=uid)
152             else:
153                 db_session.commit()
154                 return redirect(url_for('admin.new_user_two_factor', uid=uid))
155         else:
156             return render_template('admin_edit_hotp_secret.html', uid=uid)
157 
158     @view.route('/edit/<int:user_id>', methods=('GET', 'POST'))
159     @admin_required
160     def edit_user(user_id):
161         user = Journalist.query.get(user_id)
162 
163         if request.method == 'POST':
164             if request.form.get('username', None):
165                 new_username = request.form['username']
166 
167                 try:
168                     Journalist.check_username_acceptable(new_username)
169                 except InvalidUsernameException as e:
170                     flash('Invalid username: ' + str(e), 'error')
171                     return redirect(url_for("admin.edit_user",
172                                             user_id=user_id))
173 
174                 if new_username == user.username:
175                     pass
176                 elif Journalist.query.filter_by(
177                         username=new_username).one_or_none():
178                     flash(gettext(
179                         'Username "{user}" already taken.').format(
180                             user=new_username),
181                         "error")
182                     return redirect(url_for("admin.edit_user",
183                                             user_id=user_id))
184                 else:
185                     user.username = new_username
186 
187             user.is_admin = bool(request.form.get('is_admin'))
188 
189             commit_account_changes(user)
190 
191         password = make_password(config)
192         return render_template("edit_account.html", user=user,
193                                password=password)
194 
195     @view.route('/edit/<int:user_id>/new-password', methods=('POST',))
196     @admin_required
197     def set_password(user_id):
198         try:
199             user = Journalist.query.get(user_id)
200         except NoResultFound:
201             abort(404)
202 
203         password = request.form.get('password')
204         set_diceware_password(user, password)
205         return redirect(url_for('admin.edit_user', user_id=user_id))
206 
207     @view.route('/delete/<int:user_id>', methods=('POST',))
208     @admin_required
209     def delete_user(user_id):
210         user = Journalist.query.get(user_id)
211         if user:
212             db_session.delete(user)
213             db_session.commit()
214             flash(gettext("Deleted user '{user}'").format(
215                 user=user.username), "notification")
216         else:
217             current_app.logger.error(
218                 "Admin {} tried to delete nonexistent user with pk={}".format(
219                     g.user.username, user_id))
220             abort(404)
221 
222         return redirect(url_for('admin.index'))
223 
224     @view.route('/edit/<int:user_id>/new-password', methods=('POST',))
225     @admin_required
226     def new_password(user_id):
227         try:
228             user = Journalist.query.get(user_id)
229         except NoResultFound:
230             abort(404)
231 
232         password = request.form.get('password')
233         set_diceware_password(user, password)
234         return redirect(url_for('admin.edit_user', user_id=user_id))
235 
236     @view.route('/ossec-test')
237     @admin_required
238     def ossec_test():
239         current_app.logger.error('This is a test OSSEC alert')
240         flash('Test alert sent. Check your email.', 'notification')
241         return redirect(url_for('admin.manage_config'))
242 
243     return view
244
```
--- END FILES ---

Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.

Here is an example:

```diff
diff --git a/examples/server_async.py b/examples/server_async.py
--- a/examples/server_async.py
+++ b/examples/server_async.py
@@ -313,4 +313,4 @@
 
 
 if __name__ == "__main__":
-    asyncio.run(run_async_server("."), debug=True)
+    asyncio.run(run_async_server(), debug=True)
diff --git a/examples/server_sync.py b/examples/server_sync.py
--- a/examples/server_sync.py
+++ b/examples/server_sync.py
@@ -313,5 +313,5 @@
 
 
 if __name__ == "__main__":
-    server = run_sync_server(".")
+    server = run_sync_server()
     server.shutdown()

```

diff --git a/securedrop/journalist_app/admin.py b/securedrop/journalist_app/admin.py
--- a/securedrop/journalist_app/admin.py
+++ b/securedrop/journalist_app/admin.py
@@ -208,7 +208,13 @@
     @admin_required
     def delete_user(user_id):
         user = Journalist.query.get(user_id)
-        if user:
+        if user_id == g.user.id:
+            # Do not flash because the interface already has safe guards.
+            # It can only happen by manually crafting a POST request
+            current_app.logger.error(
+                "Admin {} tried to delete itself".format(g.user.username))
+            abort(403)
+        elif user:
             db_session.delete(user)
             db_session.commit()
             flash(gettext("Deleted user '{user}'").format(

{"golden_diff": "diff --git a/securedrop/journalist_app/admin.py b/securedrop/journalist_app/admin.py\n--- a/securedrop/journalist_app/admin.py\n+++ b/securedrop/journalist_app/admin.py\n@@ -208,7 +208,13 @@\n     @admin_required\n     def delete_user(user_id):\n         user = Journalist.query.get(user_id)\n-        if user:\n+        if user_id == g.user.id:\n+            # Do not flash because the interface already has safe guards.\n+            # It can only happen by manually crafting a POST request\n+            current_app.logger.error(\n+                \"Admin {} tried to delete itself\".format(g.user.username))\n+            abort(403)\n+        elif user:\n             db_session.delete(user)\n             db_session.commit()\n             flash(gettext(\"Deleted user '{user}'\").format(\n", "issue": "Prevent admin journalists from deleting themselves\nTo prevent lockouts and other forms of usability degradation, I propose one of two things:\r\n1) a full ban on any admin from deleting themselves\r\n2) an admin may not delete themselves if they are the last remaining admin\n", "before_files": [{"content": "# -*- coding: utf-8 -*-\n\nimport os\n\nfrom flask import (Blueprint, render_template, request, url_for, redirect, g,\n                   current_app, flash, abort)\nfrom flask_babel import gettext\nfrom sqlalchemy.exc import IntegrityError\nfrom sqlalchemy.orm.exc import NoResultFound\n\nfrom db import (db_session, Journalist, InvalidUsernameException,\n                PasswordError)\nfrom journalist_app.decorators import admin_required\nfrom journalist_app.utils import (make_password, commit_account_changes,\n                                  set_diceware_password)\nfrom journalist_app.forms import LogoForm, NewUserForm\n\n\ndef make_blueprint(config):\n    view = Blueprint('admin', __name__)\n\n    @view.route('/', methods=('GET', 'POST'))\n    @admin_required\n    def index():\n        users = Journalist.query.all()\n        return render_template(\"admin.html\", users=users)\n\n    @view.route('/config', methods=('GET', 'POST'))\n    @admin_required\n    def manage_config():\n        form = LogoForm()\n        if form.validate_on_submit():\n            f = form.logo.data\n            static_filepath = os.path.join(config.SECUREDROP_ROOT,\n                                           \"static/i/logo.png\")\n            f.save(static_filepath)\n            flash(gettext(\"Image updated.\"), \"notification\")\n            return redirect(url_for(\"admin.manage_config\"))\n        else:\n            return render_template(\"config.html\", form=form)\n\n    @view.route('/add', methods=('GET', 'POST'))\n    @admin_required\n    def add_user():\n        form = NewUserForm()\n        if form.validate_on_submit():\n            form_valid = True\n            username = request.form['username']\n            password = request.form['password']\n            is_admin = bool(request.form.get('is_admin'))\n\n            try:\n                otp_secret = None\n                if request.form.get('is_hotp', False):\n                    otp_secret = request.form.get('otp_secret', '')\n                new_user = Journalist(username=username,\n                                      password=password,\n                                      is_admin=is_admin,\n                                      otp_secret=otp_secret)\n                db_session.add(new_user)\n                db_session.commit()\n            except PasswordError:\n                flash(gettext(\n                      'There was an error with the autogenerated password. '\n                      'User not created. Please try again.'), 'error')\n                form_valid = False\n            except InvalidUsernameException as e:\n                form_valid = False\n                flash('Invalid username: ' + str(e), \"error\")\n            except IntegrityError as e:\n                db_session.rollback()\n                form_valid = False\n                if \"UNIQUE constraint failed: journalists.username\" in str(e):\n                    flash(gettext(\"That username is already in use\"),\n                          \"error\")\n                else:\n                    flash(gettext(\"An error occurred saving this user\"\n                                  \" to the database.\"\n                                  \" Please inform your administrator.\"),\n                          \"error\")\n                    current_app.logger.error(\"Adding user \"\n                                             \"'{}' failed: {}\".format(\n                                                 username, e))\n\n            if form_valid:\n                return redirect(url_for('admin.new_user_two_factor',\n                                        uid=new_user.id))\n\n        return render_template(\"admin_add_user.html\",\n                               password=make_password(config),\n                               form=form)\n\n    @view.route('/2fa', methods=('GET', 'POST'))\n    @admin_required\n    def new_user_two_factor():\n        user = Journalist.query.get(request.args['uid'])\n\n        if request.method == 'POST':\n            token = request.form['token']\n            if user.verify_token(token):\n                flash(gettext(\n                    \"Token in two-factor authentication \"\n                    \"accepted for user {user}.\").format(\n                        user=user.username),\n                    \"notification\")\n                return redirect(url_for(\"admin.index\"))\n            else:\n                flash(gettext(\n                    \"Could not verify token in two-factor authentication.\"),\n                      \"error\")\n\n        return render_template(\"admin_new_user_two_factor.html\", user=user)\n\n    @view.route('/reset-2fa-totp', methods=['POST'])\n    @admin_required\n    def reset_two_factor_totp():\n        uid = request.form['uid']\n        user = Journalist.query.get(uid)\n        user.is_totp = True\n        user.regenerate_totp_shared_secret()\n        db_session.commit()\n        return redirect(url_for('admin.new_user_two_factor', uid=uid))\n\n    @view.route('/reset-2fa-hotp', methods=['POST'])\n    @admin_required\n    def reset_two_factor_hotp():\n        uid = request.form['uid']\n        otp_secret = request.form.get('otp_secret', None)\n        if otp_secret:\n            user = Journalist.query.get(uid)\n            try:\n                user.set_hotp_secret(otp_secret)\n            except TypeError as e:\n                if \"Non-hexadecimal digit found\" in str(e):\n                    flash(gettext(\n                        \"Invalid secret format: \"\n                        \"please only submit letters A-F and numbers 0-9.\"),\n                          \"error\")\n                elif \"Odd-length string\" in str(e):\n                    flash(gettext(\n                        \"Invalid secret format: \"\n                        \"odd-length secret. Did you mistype the secret?\"),\n                          \"error\")\n                else:\n                    flash(gettext(\n                        \"An unexpected error occurred! \"\n                        \"Please inform your administrator.\"), \"error\")\n                    current_app.logger.error(\n                        \"set_hotp_secret '{}' (id {}) failed: {}\".format(\n                            otp_secret, uid, e))\n                return render_template('admin_edit_hotp_secret.html', uid=uid)\n            else:\n                db_session.commit()\n                return redirect(url_for('admin.new_user_two_factor', uid=uid))\n        else:\n            return render_template('admin_edit_hotp_secret.html', uid=uid)\n\n    @view.route('/edit/<int:user_id>', methods=('GET', 'POST'))\n    @admin_required\n    def edit_user(user_id):\n        user = Journalist.query.get(user_id)\n\n        if request.method == 'POST':\n            if request.form.get('username', None):\n                new_username = request.form['username']\n\n                try:\n                    Journalist.check_username_acceptable(new_username)\n                except InvalidUsernameException as e:\n                    flash('Invalid username: ' + str(e), 'error')\n                    return redirect(url_for(\"admin.edit_user\",\n                                            user_id=user_id))\n\n                if new_username == user.username:\n                    pass\n                elif Journalist.query.filter_by(\n                        username=new_username).one_or_none():\n                    flash(gettext(\n                        'Username \"{user}\" already taken.').format(\n                            user=new_username),\n                        \"error\")\n                    return redirect(url_for(\"admin.edit_user\",\n                                            user_id=user_id))\n                else:\n                    user.username = new_username\n\n            user.is_admin = bool(request.form.get('is_admin'))\n\n            commit_account_changes(user)\n\n        password = make_password(config)\n        return render_template(\"edit_account.html\", user=user,\n                               password=password)\n\n    @view.route('/edit/<int:user_id>/new-password', methods=('POST',))\n    @admin_required\n    def set_password(user_id):\n        try:\n            user = Journalist.query.get(user_id)\n        except NoResultFound:\n            abort(404)\n\n        password = request.form.get('password')\n        set_diceware_password(user, password)\n        return redirect(url_for('admin.edit_user', user_id=user_id))\n\n    @view.route('/delete/<int:user_id>', methods=('POST',))\n    @admin_required\n    def delete_user(user_id):\n        user = Journalist.query.get(user_id)\n        if user:\n            db_session.delete(user)\n            db_session.commit()\n            flash(gettext(\"Deleted user '{user}'\").format(\n                user=user.username), \"notification\")\n        else:\n            current_app.logger.error(\n                \"Admin {} tried to delete nonexistent user with pk={}\".format(\n                    g.user.username, user_id))\n            abort(404)\n\n        return redirect(url_for('admin.index'))\n\n    @view.route('/edit/<int:user_id>/new-password', methods=('POST',))\n    @admin_required\n    def new_password(user_id):\n        try:\n            user = Journalist.query.get(user_id)\n        except NoResultFound:\n            abort(404)\n\n        password = request.form.get('password')\n        set_diceware_password(user, password)\n        return redirect(url_for('admin.edit_user', user_id=user_id))\n\n    @view.route('/ossec-test')\n    @admin_required\n    def ossec_test():\n        current_app.logger.error('This is a test OSSEC alert')\n        flash('Test alert sent. Check your email.', 'notification')\n        return redirect(url_for('admin.manage_config'))\n\n    return view\n", "path": "securedrop/journalist_app/admin.py"}], "after_files": [{"content": "# -*- coding: utf-8 -*-\n\nimport os\n\nfrom flask import (Blueprint, render_template, request, url_for, redirect, g,\n                   current_app, flash, abort)\nfrom flask_babel import gettext\nfrom sqlalchemy.exc import IntegrityError\nfrom sqlalchemy.orm.exc import NoResultFound\n\nfrom db import (db_session, Journalist, InvalidUsernameException,\n                PasswordError)\nfrom journalist_app.decorators import admin_required\nfrom journalist_app.utils import (make_password, commit_account_changes,\n                                  set_diceware_password)\nfrom journalist_app.forms import LogoForm, NewUserForm\n\n\ndef make_blueprint(config):\n    view = Blueprint('admin', __name__)\n\n    @view.route('/', methods=('GET', 'POST'))\n    @admin_required\n    def index():\n        users = Journalist.query.all()\n        return render_template(\"admin.html\", users=users)\n\n    @view.route('/config', methods=('GET', 'POST'))\n    @admin_required\n    def manage_config():\n        form = LogoForm()\n        if form.validate_on_submit():\n            f = form.logo.data\n            static_filepath = os.path.join(config.SECUREDROP_ROOT,\n                                           \"static/i/logo.png\")\n            f.save(static_filepath)\n            flash(gettext(\"Image updated.\"), \"notification\")\n            return redirect(url_for(\"admin.manage_config\"))\n        else:\n            return render_template(\"config.html\", form=form)\n\n    @view.route('/add', methods=('GET', 'POST'))\n    @admin_required\n    def add_user():\n        form = NewUserForm()\n        if form.validate_on_submit():\n            form_valid = True\n            username = request.form['username']\n            password = request.form['password']\n            is_admin = bool(request.form.get('is_admin'))\n\n            try:\n                otp_secret = None\n                if request.form.get('is_hotp', False):\n                    otp_secret = request.form.get('otp_secret', '')\n                new_user = Journalist(username=username,\n                                      password=password,\n                                      is_admin=is_admin,\n                                      otp_secret=otp_secret)\n                db_session.add(new_user)\n                db_session.commit()\n            except PasswordError:\n                flash(gettext(\n                      'There was an error with the autogenerated password. '\n                      'User not created. Please try again.'), 'error')\n                form_valid = False\n            except InvalidUsernameException as e:\n                form_valid = False\n                flash('Invalid username: ' + str(e), \"error\")\n            except IntegrityError as e:\n                db_session.rollback()\n                form_valid = False\n                if \"UNIQUE constraint failed: journalists.username\" in str(e):\n                    flash(gettext(\"That username is already in use\"),\n                          \"error\")\n                else:\n                    flash(gettext(\"An error occurred saving this user\"\n                                  \" to the database.\"\n                                  \" Please inform your administrator.\"),\n                          \"error\")\n                    current_app.logger.error(\"Adding user \"\n                                             \"'{}' failed: {}\".format(\n                                                 username, e))\n\n            if form_valid:\n                return redirect(url_for('admin.new_user_two_factor',\n                                        uid=new_user.id))\n\n        return render_template(\"admin_add_user.html\",\n                               password=make_password(config),\n                               form=form)\n\n    @view.route('/2fa', methods=('GET', 'POST'))\n    @admin_required\n    def new_user_two_factor():\n        user = Journalist.query.get(request.args['uid'])\n\n        if request.method == 'POST':\n            token = request.form['token']\n            if user.verify_token(token):\n                flash(gettext(\n                    \"Token in two-factor authentication \"\n                    \"accepted for user {user}.\").format(\n                        user=user.username),\n                    \"notification\")\n                return redirect(url_for(\"admin.index\"))\n            else:\n                flash(gettext(\n                    \"Could not verify token in two-factor authentication.\"),\n                      \"error\")\n\n        return render_template(\"admin_new_user_two_factor.html\", user=user)\n\n    @view.route('/reset-2fa-totp', methods=['POST'])\n    @admin_required\n    def reset_two_factor_totp():\n        uid = request.form['uid']\n        user = Journalist.query.get(uid)\n        user.is_totp = True\n        user.regenerate_totp_shared_secret()\n        db_session.commit()\n        return redirect(url_for('admin.new_user_two_factor', uid=uid))\n\n    @view.route('/reset-2fa-hotp', methods=['POST'])\n    @admin_required\n    def reset_two_factor_hotp():\n        uid = request.form['uid']\n        otp_secret = request.form.get('otp_secret', None)\n        if otp_secret:\n            user = Journalist.query.get(uid)\n            try:\n                user.set_hotp_secret(otp_secret)\n            except TypeError as e:\n                if \"Non-hexadecimal digit found\" in str(e):\n                    flash(gettext(\n                        \"Invalid secret format: \"\n                        \"please only submit letters A-F and numbers 0-9.\"),\n                          \"error\")\n                elif \"Odd-length string\" in str(e):\n                    flash(gettext(\n                        \"Invalid secret format: \"\n                        \"odd-length secret. Did you mistype the secret?\"),\n                          \"error\")\n                else:\n                    flash(gettext(\n                        \"An unexpected error occurred! \"\n                        \"Please inform your administrator.\"), \"error\")\n                    current_app.logger.error(\n                        \"set_hotp_secret '{}' (id {}) failed: {}\".format(\n                            otp_secret, uid, e))\n                return render_template('admin_edit_hotp_secret.html', uid=uid)\n            else:\n                db_session.commit()\n                return redirect(url_for('admin.new_user_two_factor', uid=uid))\n        else:\n            return render_template('admin_edit_hotp_secret.html', uid=uid)\n\n    @view.route('/edit/<int:user_id>', methods=('GET', 'POST'))\n    @admin_required\n    def edit_user(user_id):\n        user = Journalist.query.get(user_id)\n\n        if request.method == 'POST':\n            if request.form.get('username', None):\n                new_username = request.form['username']\n\n                try:\n                    Journalist.check_username_acceptable(new_username)\n                except InvalidUsernameException as e:\n                    flash('Invalid username: ' + str(e), 'error')\n                    return redirect(url_for(\"admin.edit_user\",\n                                            user_id=user_id))\n\n                if new_username == user.username:\n                    pass\n                elif Journalist.query.filter_by(\n                        username=new_username).one_or_none():\n                    flash(gettext(\n                        'Username \"{user}\" already taken.').format(\n                            user=new_username),\n                        \"error\")\n                    return redirect(url_for(\"admin.edit_user\",\n                                            user_id=user_id))\n                else:\n                    user.username = new_username\n\n            user.is_admin = bool(request.form.get('is_admin'))\n\n            commit_account_changes(user)\n\n        password = make_password(config)\n        return render_template(\"edit_account.html\", user=user,\n                               password=password)\n\n    @view.route('/edit/<int:user_id>/new-password', methods=('POST',))\n    @admin_required\n    def set_password(user_id):\n        try:\n            user = Journalist.query.get(user_id)\n        except NoResultFound:\n            abort(404)\n\n        password = request.form.get('password')\n        set_diceware_password(user, password)\n        return redirect(url_for('admin.edit_user', user_id=user_id))\n\n    @view.route('/delete/<int:user_id>', methods=('POST',))\n    @admin_required\n    def delete_user(user_id):\n        user = Journalist.query.get(user_id)\n        if user_id == g.user.id:\n            # Do not flash because the interface already has safe guards.\n            # It can only happen by manually crafting a POST request\n            current_app.logger.error(\n                \"Admin {} tried to delete itself\".format(g.user.username))\n            abort(403)\n        elif user:\n            db_session.delete(user)\n            db_session.commit()\n            flash(gettext(\"Deleted user '{user}'\").format(\n                user=user.username), \"notification\")\n        else:\n            current_app.logger.error(\n                \"Admin {} tried to delete nonexistent user with pk={}\".format(\n                    g.user.username, user_id))\n            abort(404)\n\n        return redirect(url_for('admin.index'))\n\n    @view.route('/edit/<int:user_id>/new-password', methods=('POST',))\n    @admin_required\n    def new_password(user_id):\n        try:\n            user = Journalist.query.get(user_id)\n        except NoResultFound:\n            abort(404)\n\n        password = request.form.get('password')\n        set_diceware_password(user, password)\n        return redirect(url_for('admin.edit_user', user_id=user_id))\n\n    @view.route('/ossec-test')\n    @admin_required\n    def ossec_test():\n        current_app.logger.error('This is a test OSSEC alert')\n        flash('Test alert sent. Check your email.', 'notification')\n        return redirect(url_for('admin.manage_config'))\n\n    return view\n", "path": "securedrop/journalist_app/admin.py"}]}