Add button to export debug info of a user

This commit is contained in:
Jonas Schäfer
2021-01-21 16:15:28 +01:00
parent f5d0bfdec7
commit b6188ed29f
10 changed files with 158 additions and 47 deletions

View File

@@ -1,4 +1,5 @@
import asyncio
import json
import typing
from datetime import datetime
@@ -69,6 +70,22 @@ async def delete_user(localpart: str) -> typing.Union[str, quart.Response]:
)
@bp.route("/user/<localpart>/debug")
@client.require_admin_session()
async def debug_user(localpart: str) -> typing.Union[str, quart.Response]:
target_user_info = await client.get_user_by_localpart(localpart)
debug_info = json.dumps(
await client.get_user_debug_info(localpart),
indent=2,
sort_keys=True,
)
return await render_template(
"admin_debug_user.html",
target_user=target_user_info,
debug_dump=debug_info,
)
class InvitesListForm(flask_wtf.FlaskForm): # type:ignore
action_revoke = wtforms.StringField()

View File

@@ -791,6 +791,19 @@ class ProsodyClient:
self._raise_error_from_response(resp)
return AdminUserInfo.from_api_response(await resp.json())
@autosession
async def get_user_debug_info(
self,
localpart: str,
*,
session: aiohttp.ClientSession,
) -> AdminUserInfo:
async with session.get(
self._admin_v1_endpoint("/users/{}/debug".format(localpart)),
) as resp:
self._raise_error_from_response(resp)
return await resp.json()
@autosession
async def delete_user_by_localpart(
self,

View File

@@ -14,6 +14,11 @@ p, blockquote, ul, ol, table, dl {
color: inherit;
}
pre {
line-height: 1.5;
margin: 1.5em 0;
}
blockquote {
margin-left: $w-l2;
margin-right: $w-l2;

View File

@@ -813,11 +813,9 @@ div.elevated {
div.elevated > *:first-child {
margin-top: 0;
margin-bottom: 0;
}
div.elevated > *:last-child {
margin-top: 0;
margin-bottom: 0;
}
@@ -870,7 +868,7 @@ ul.inline {
margin-right: 0;
}
div.elevated {
div.elevated, main > div.box {
margin-left: 0;
margin-right: 0;
}

View File

@@ -7,6 +7,11 @@ licensed under the terms of the Apache 2.0 License -->
<path d="M0 0h24v24H0V0z" fill="none" />
<path d="M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm0 3c1.66 0 3 1.34 3 3s-1.34 3-3 3-3-1.34-3-3 1.34-3 3-3zm0 14.2c-2.5 0-4.71-1.28-6-3.22.03-1.99 4-3.08 6-3.08 1.99 0 5.97 1.09 6 3.08-1.29 1.94-3.5 3.22-6 3.22z" />
</symbol>
<!-- from: action/bug_report/materialiconsround/24px.svg -->
<symbol id="icon-bug_report" viewBox="0 0 24 24">
<path d="M0 0h24v24H0V0z" fill="none" />
<path d="M19 8h-1.81c-.45-.78-1.07-1.45-1.82-1.96l.93-.93c.39-.39.39-1.02 0-1.41-.39-.39-1.02-.39-1.41 0l-1.47 1.47C12.96 5.06 12.49 5 12 5s-.96.06-1.41.17L9.11 3.7c-.39-.39-1.02-.39-1.41 0-.39.39-.39 1.02 0 1.41l.92.93C7.88 6.55 7.26 7.22 6.81 8H5c-.55 0-1 .45-1 1s.45 1 1 1h1.09c-.05.33-.09.66-.09 1v1H5c-.55 0-1 .45-1 1s.45 1 1 1h1v1c0 .34.04.67.09 1H5c-.55 0-1 .45-1 1s.45 1 1 1h1.81c1.04 1.79 2.97 3 5.19 3s4.15-1.21 5.19-3H19c.55 0 1-.45 1-1s-.45-1-1-1h-1.09c.05-.33.09-.66.09-1v-1h1c.55 0 1-.45 1-1s-.45-1-1-1h-1v-1c0-.34-.04-.67-.09-1H19c.55 0 1-.45 1-1s-.45-1-1-1zm-6 8h-2c-.55 0-1-.45-1-1s.45-1 1-1h2c.55 0 1 .45 1 1s-.45 1-1 1zm0-4h-2c-.55 0-1-.45-1-1s.45-1 1-1h2c.55 0 1 .45 1 1s-.45 1-1 1z" />
</symbol>
<!-- from: action/done/materialiconsround/24px.svg -->
<symbol id="icon-done" viewBox="0 0 24 24">
<path d="M0 0h24v24H0V0z" fill="none" />

Before

Width:  |  Height:  |  Size: 8.1 KiB

After

Width:  |  Height:  |  Size: 8.9 KiB

View File

@@ -0,0 +1,23 @@
{% extends "app.html" %}
{% from "library.j2" import clipboard_button %}
{% block head_lead %}
{{ super() }}
{% include "copy-snippet.html" %}
{% endblock %}
{% block content %}
<h1>{% trans user_name=target_user.localpart %}Debug information for {{ user_name }}{% endtrans %}</h1>
<h2></h2>
<div class="box warning">
<header>{% trans %}Warning{% endtrans %}</header>
<p>{% trans %}The below dump may contain sensitive information.{% endtrans %}</p>
</div>
<div class="elevated box">
<header>{% trans %}Raw debug dump{% endtrans %}</header>
<p>{% call clipboard_button(debug_dump, show_label=True, class="primary") -%}
{% trans %}Copy complete output{% endtrans %}
{%- endcall %}</p>
<pre class="guru-meditation">
{{ debug_dump }}
</pre
</div>
{% endblock %}

View File

@@ -23,6 +23,9 @@
{%- call action_button("remove", url_for(".delete_user", localpart=user.localpart), class="secondary") -%}
{% trans user_name=user.localpart %}Delete user {{ user_name }}{% endtrans %}
{%- endcall -%}
{%- call action_button("bug_report", url_for(".debug_user", localpart=user.localpart), class="secondary") -%}
{% trans user_name=user.localpart %}Show debug information for {{ user_name }}{% endtrans %}
{%- endcall -%}
</td>
</tr>
{% endfor %}

View File

@@ -7,7 +7,7 @@ msgid ""
msgstr ""
"Project-Id-Version: SnikketWeb 0.1.0\n"
"Report-Msgid-Bugs-To: jonas@zombofant.net\n"
"POT-Creation-Date: 2021-01-21 16:55+0100\n"
"POT-Creation-Date: 2021-01-21 16:56+0100\n"
"PO-Revision-Date: 2020-03-07 16:32+0100\n"
"Last-Translator: Jonas Schäfer <jonas@zombofant.net>\n"
"Language: de\n"
@@ -18,71 +18,71 @@ msgstr ""
"Content-Transfer-Encoding: 8bit\n"
"Generated-By: Babel 2.9.0\n"
#: snikket_web/admin.py:51
#: snikket_web/admin.py:52
msgid "Delete user permanently"
msgstr "Benutzer endgültig löschen"
#: snikket_web/admin.py:78
#: snikket_web/admin.py:95
msgid "Invite to circle"
msgstr "In Gemeinschaft einladen"
#: snikket_web/admin.py:84
#: snikket_web/admin.py:101
msgid "At least one circle must be selected"
msgstr "Mindestens eine Gemeinschaft muss ausgewählt sein"
#: snikket_web/admin.py:89
#: snikket_web/admin.py:106
msgid "Valid for"
msgstr "Gültig für"
#: snikket_web/admin.py:91
#: snikket_web/admin.py:108
msgid "One hour"
msgstr "Eine Stunde"
#: snikket_web/admin.py:92
#: snikket_web/admin.py:109
msgid "Twelve hours"
msgstr "Zwölf Stunden"
#: snikket_web/admin.py:93
#: snikket_web/admin.py:110
msgid "One day"
msgstr "Ein Tag"
#: snikket_web/admin.py:94
#: snikket_web/admin.py:111
msgid "One week"
msgstr "Eine Woche"
#: snikket_web/admin.py:95
#: snikket_web/admin.py:112
msgid "Four weeks"
msgstr "Vier Wochen"
#: snikket_web/admin.py:101
#: snikket_web/admin.py:118
msgid "Allow multiple uses"
msgstr "Mehrfach verwendbar"
#: snikket_web/admin.py:105
#: snikket_web/admin.py:122
msgid "New invitation link"
msgstr "Neuer Einladungslink"
#: snikket_web/admin.py:163
#: snikket_web/admin.py:180
msgid "Revoke"
msgstr "Löschen"
#: snikket_web/admin.py:214 snikket_web/admin.py:257
#: snikket_web/admin.py:231 snikket_web/admin.py:274
msgid "Name"
msgstr "Name"
#: snikket_web/admin.py:218 snikket_web/templates/admin_circles.html:42
#: snikket_web/admin.py:235 snikket_web/templates/admin_circles.html:42
msgid "Create circle"
msgstr "Gemeinschaft gründen"
#: snikket_web/admin.py:261 snikket_web/user.py:68
#: snikket_web/admin.py:278 snikket_web/user.py:68
msgid "Apply"
msgstr "Übernehmen"
#: snikket_web/admin.py:265
#: snikket_web/admin.py:282
msgid "Delete circle permanently"
msgstr "Gemeinschaft endgültig löschen"
#: snikket_web/infra.py:41
#: snikket_web/infra.py:40
msgid "Main"
msgstr "Kern"
@@ -213,6 +213,28 @@ msgstr ""
"Erzeuge eine neue Einladung um mehr Benutzer auf deine Snikket-Instanz "
"einzuladen indem du den folgenden Button klickst."
#: snikket_web/templates/admin_debug_user.html:8
#, python-format
msgid "Debug information for %(user_name)s"
msgstr "Debugging-Informationen für %(user_name)s"
#: snikket_web/templates/admin_debug_user.html:11
#: snikket_web/templates/user_passwd.html:36
msgid "Warning"
msgstr "Warnung"
#: snikket_web/templates/admin_debug_user.html:12
msgid "The below dump may contain sensitive information."
msgstr "Die untenstehende Ausgabe könnte persönliche Informationen enthalten."
#: snikket_web/templates/admin_debug_user.html:15
msgid "Raw debug dump"
msgstr "Rohe Debug-Ausgabe"
#: snikket_web/templates/admin_debug_user.html:17
msgid "Copy complete output"
msgstr "Komplette Ausgabe kopieren"
#: snikket_web/templates/admin_delete_user.html:4
#: snikket_web/templates/admin_users.html:24
#, python-format
@@ -434,6 +456,11 @@ msgstr "Derzeit gibt es keine ausstehenden Einladungen."
msgid "Phone number"
msgstr "Telefonnummer"
#: snikket_web/templates/admin_users.html:27
#, python-format
msgid "Show debug information for %(user_name)s"
msgstr "Debugging-Informationen für %(user_name)s anzeigen"
#: snikket_web/templates/app.html:4
msgid "Snikket Web Portal"
msgstr "Snikket Webportal"
@@ -570,10 +597,6 @@ msgstr ""
msgid "Password change failed"
msgstr "Passwortänderung fehlgeschlagen"
#: snikket_web/templates/user_passwd.html:36
msgid "Warning"
msgstr "Warnung"
#: snikket_web/templates/user_passwd.html:37
msgid ""
"After changing your password, you will have to enter the new password on "

View File

@@ -7,7 +7,7 @@ msgid ""
msgstr ""
"Project-Id-Version: PROJECT VERSION\n"
"Report-Msgid-Bugs-To: EMAIL@ADDRESS\n"
"POT-Creation-Date: 2021-01-21 16:55+0100\n"
"POT-Creation-Date: 2021-01-21 16:56+0100\n"
"PO-Revision-Date: 2020-03-07 16:50+0100\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language: en\n"
@@ -18,71 +18,71 @@ msgstr ""
"Content-Transfer-Encoding: 8bit\n"
"Generated-By: Babel 2.9.0\n"
#: snikket_web/admin.py:51
#: snikket_web/admin.py:52
msgid "Delete user permanently"
msgstr ""
#: snikket_web/admin.py:78
#: snikket_web/admin.py:95
msgid "Invite to circle"
msgstr ""
#: snikket_web/admin.py:84
#: snikket_web/admin.py:101
msgid "At least one circle must be selected"
msgstr ""
#: snikket_web/admin.py:89
#: snikket_web/admin.py:106
msgid "Valid for"
msgstr ""
#: snikket_web/admin.py:91
#: snikket_web/admin.py:108
msgid "One hour"
msgstr ""
#: snikket_web/admin.py:92
#: snikket_web/admin.py:109
msgid "Twelve hours"
msgstr ""
#: snikket_web/admin.py:93
#: snikket_web/admin.py:110
msgid "One day"
msgstr ""
#: snikket_web/admin.py:94
#: snikket_web/admin.py:111
msgid "One week"
msgstr ""
#: snikket_web/admin.py:95
#: snikket_web/admin.py:112
msgid "Four weeks"
msgstr ""
#: snikket_web/admin.py:101
#: snikket_web/admin.py:118
msgid "Allow multiple uses"
msgstr ""
#: snikket_web/admin.py:105
#: snikket_web/admin.py:122
msgid "New invitation link"
msgstr ""
#: snikket_web/admin.py:163
#: snikket_web/admin.py:180
msgid "Revoke"
msgstr ""
#: snikket_web/admin.py:214 snikket_web/admin.py:257
#: snikket_web/admin.py:231 snikket_web/admin.py:274
msgid "Name"
msgstr ""
#: snikket_web/admin.py:218 snikket_web/templates/admin_circles.html:42
#: snikket_web/admin.py:235 snikket_web/templates/admin_circles.html:42
msgid "Create circle"
msgstr ""
#: snikket_web/admin.py:261 snikket_web/user.py:68
#: snikket_web/admin.py:278 snikket_web/user.py:68
msgid "Apply"
msgstr ""
#: snikket_web/admin.py:265
#: snikket_web/admin.py:282
msgid "Delete circle permanently"
msgstr ""
#: snikket_web/infra.py:41
#: snikket_web/infra.py:40
msgid "Main"
msgstr ""
@@ -211,6 +211,28 @@ msgid ""
"instance by clicking the button below."
msgstr ""
#: snikket_web/templates/admin_debug_user.html:8
#, fuzzy, python-format
msgid "Debug information for %(user_name)s"
msgstr "Welcome home, %(user_name)s."
#: snikket_web/templates/admin_debug_user.html:11
#: snikket_web/templates/user_passwd.html:36
msgid "Warning"
msgstr "Warning"
#: snikket_web/templates/admin_debug_user.html:12
msgid "The below dump may contain sensitive information."
msgstr ""
#: snikket_web/templates/admin_debug_user.html:15
msgid "Raw debug dump"
msgstr ""
#: snikket_web/templates/admin_debug_user.html:17
msgid "Copy complete output"
msgstr ""
#: snikket_web/templates/admin_delete_user.html:4
#: snikket_web/templates/admin_users.html:24
#, python-format
@@ -421,6 +443,11 @@ msgstr ""
msgid "Phone number"
msgstr ""
#: snikket_web/templates/admin_users.html:27
#, fuzzy, python-format
msgid "Show debug information for %(user_name)s"
msgstr "Welcome home, %(user_name)s."
#: snikket_web/templates/app.html:4
msgid "Snikket Web Portal"
msgstr ""
@@ -546,10 +573,6 @@ msgstr ""
msgid "Password change failed"
msgstr ""
#: snikket_web/templates/user_passwd.html:36
msgid "Warning"
msgstr ""
#: snikket_web/templates/user_passwd.html:37
msgid ""
"After changing your password, you will have to enter the new password on "

View File

@@ -1,4 +1,5 @@
action/account_circle:profile
action/bug_report:bug_report
action/done:done
action/logout:logout
action/login:login