Compare commits

...

4 Commits

Author SHA1 Message Date
Jonas Schäfer
d9b73055a8 Add confirmation step to circle deletion
Deleting a circle is highly destructive. It removes the group chat
alongside history, as well as the user list. It should definitely be
protected by a confirmation dialogue, I have no clue why it wasn't.

Fixes #153.
2023-04-01 10:08:52 +02:00
Matthew Wild
f37270594e Merge pull request #152 from snikket-im/fix/role-config
Follow new role scheme in Prosody
2023-03-29 20:16:36 +01:00
Jonas Schäfer
fcfcdbeb23 Follow new role scheme in Prosody
Prosody changed its role scheme to only support a single primary role
for each user. In addition, the names of the built-in roles have been
changed. We thus follow those changes to be compatible with the most
recent trunk.

One open question is whether we should switch admin -> operator here,
too (operator being a server-wide admin), but so far there's no need
to.
2023-03-29 18:42:53 +02:00
Jonas Schäfer
fd566b7f30 Merge pull request #151 from snikket-im/fix/user-listing-roles
Make AdminUserInfo compatible with new API
2023-03-28 22:23:06 +02:00
6 changed files with 126 additions and 54 deletions

View File

@@ -77,7 +77,7 @@ class EditUserForm(BaseForm):
_l("Access Level"),
choices=[
("prosody:restricted", _("Limited")),
("prosody:normal", _l("Normal user")),
("prosody:user", _l("Normal user")),
("prosody:admin", _l("Administrator")),
],
)
@@ -116,7 +116,7 @@ async def edit_user(localpart: str) -> typing.Union[werkzeug.Response, str]:
await client.update_user(
localpart,
display_name=form.display_name.data,
roles=[form.role.data],
role=form.role.data,
)
await flash(
@@ -131,7 +131,7 @@ async def edit_user(localpart: str) -> typing.Union[werkzeug.Response, str]:
if target_user_info.roles:
form.role.data = target_user_info.roles[0]
else:
form.role.data = "prosody:normal"
form.role.data = "prosody:user"
return await render_template(
"admin_edit_user.html",
@@ -452,10 +452,6 @@ class EditCircleForm(BaseForm):
_l("Update circle")
)
action_delete = wtforms.SubmitField(
_l("Delete circle permanently")
)
action_remove_user = wtforms.StringField()
action_add_user = wtforms.SubmitField(
@@ -515,13 +511,6 @@ async def edit_circle(id_: str) -> typing.Union[str, werkzeug.Response]:
_("Circle data updated"),
"success",
)
elif form.action_delete.data:
await client.delete_group(id_)
await flash(
_("Circle deleted"),
"success",
)
return redirect(url_for(".circles"))
elif form.action_add_user.data:
if form.user_to_add.data in valid_users:
await client.add_group_member(
@@ -553,6 +542,47 @@ async def edit_circle(id_: str) -> typing.Union[str, werkzeug.Response]:
)
class DeleteCircleForm(BaseForm):
action_delete = wtforms.SubmitField(
_l("Delete circle permanently")
)
@bp.route("/circle/<id_>/delete", methods=["GET", "POST"])
@client.require_admin_session()
async def delete_circle(id_: str) -> typing.Union[str, werkzeug.Response]:
async with client.authenticated_session() as session:
try:
circle = await client.get_group_by_id(
id_,
session=session,
)
except aiohttp.ClientResponseError as exc:
if exc.status == 404:
await flash(
_("No such circle exists"),
"alert",
)
return redirect(url_for(".circles"))
raise
form = DeleteCircleForm()
if form.validate_on_submit():
if form.action_delete.data:
await client.delete_group(id_)
await flash(
_("Circle deleted"),
"success",
)
return redirect(url_for(".circles"))
return await render_template(
"admin_delete_circle.html",
target_circle=circle,
form=form,
)
_CPU_EPOCH = time.process_time()
_MONOTONIC_EPOCH = time.monotonic()

View File

@@ -885,7 +885,7 @@ class ProsodyClient:
localpart: str,
*,
display_name: typing.Optional[str],
roles: typing.Optional[typing.Collection[str]],
role: typing.Optional[str],
session: aiohttp.ClientSession,
) -> None:
payload: typing.Dict[str, typing.Any] = {
@@ -893,8 +893,8 @@ class ProsodyClient:
}
if display_name is not None:
payload["display_name"] = display_name
if roles is not None:
payload["roles"] = list(roles)
if role is not None:
payload["role"] = role
async with session.put(
self._admin_v1_endpoint("/users/{}".format(localpart)),

View File

@@ -0,0 +1,21 @@
{% extends "admin_app.html" %}
{% from "library.j2" import box, form_button, standard_button %}
{% block content %}
<h1>{% trans circle_name=target_circle.name %}Delete circle {{ circle_name }}{% endtrans %}</h1>
<div class="form layout-expanded"><form method="POST">
<h2 class="form-title">{% trans %}Delete circle{% endtrans %}</h2>
{{ form.csrf_token }}
<p class="form-descr">{% trans %}Are you sure you want to delete the following circle?{% endtrans %}</p>
<dl>
<dt>{% trans %}Name{% endtrans %}</dt>
<dd>{{ target_circle.name }}</dd>
</dl>
{% call box("alert", _("Danger")) %}
<p>{% trans %}The circle and the corresponding chat will be deleted, permanently and immediately upon pushing the below button. <strong>There is no way back!</strong>{% endtrans %}</p>
{% endcall %}
<div class="f-bbox">
{%- call standard_button("back", url_for(".edit_circle", id_=target_circle.id_), class="tertiary") %}{% trans %}Back{% endtrans %}{% endcall -%}
{%- call form_button("delete", form.action_delete, class="primary danger") %}{% endcall -%}
</div>
</form></div>
{% endblock %}

View File

@@ -48,7 +48,7 @@
<h3 class="form-title">{% trans %}Delete circle{% endtrans %}</h3>
<p class="form-desc">{% trans %}Deleting a circle does not delete any users in the circle.{% endtrans %}</p>
<div class="f-bbox">
{%- call form_button("delete", form.action_delete, class="secondary danger") %}{% endcall -%}
{%- call standard_button("delete", url_for(".delete_circle", id_=target_circle.id_), class="secondary danger") %}{% trans %}Delete circle{% endtrans %}{% endcall -%}
</div>
</div>
{%- endif -%}

View File

@@ -3,7 +3,7 @@
{% macro access_level_description(role, caller=None) %}
{%- if role == "prosody:restricted" -%}
{% trans %}Limited users can interact with users on the same Snikket service and be members of circles.{% endtrans %}
{%- elif role == "prosody:normal" -%}
{%- elif role == "prosody:user" -%}
{% trans %}Like limited users and can also interact with users on other Snikket services.{% endtrans %}
{%- elif role == "prosody:admin" -%}
{% trans %}Like normal users and can access the admin panel in the web portal.{% endtrans %}

View File

@@ -8,7 +8,7 @@ msgid ""
msgstr ""
"Project-Id-Version: PROJECT VERSION\n"
"Report-Msgid-Bugs-To: EMAIL@ADDRESS\n"
"POT-Creation-Date: 2023-03-28 19:16+0200\n"
"POT-Creation-Date: 2023-04-01 10:07+0200\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
@@ -142,6 +142,7 @@ msgid "Invitation revoked"
msgstr ""
#: snikket_web/admin.py:394 snikket_web/admin.py:442
#: snikket_web/templates/admin_delete_circle.html:10
msgid "Name"
msgstr ""
@@ -161,51 +162,51 @@ msgstr ""
msgid "Update circle"
msgstr ""
#: snikket_web/admin.py:456
msgid "Delete circle permanently"
msgstr ""
#: snikket_web/admin.py:462
#: snikket_web/admin.py:458
msgid "Add user"
msgstr ""
#: snikket_web/admin.py:478
#: snikket_web/admin.py:474 snikket_web/admin.py:563
msgid "No such circle exists"
msgstr ""
#: snikket_web/admin.py:515
#: snikket_web/admin.py:511
msgid "Circle data updated"
msgstr ""
#: snikket_web/admin.py:521
msgid "Circle deleted"
msgstr ""
#: snikket_web/admin.py:532
msgid "User added to circle"
msgstr ""
#: snikket_web/admin.py:541
#: snikket_web/admin.py:530
msgid "User removed from circle"
msgstr ""
#: snikket_web/admin.py:610
#: snikket_web/admin.py:547
msgid "Delete circle permanently"
msgstr ""
#: snikket_web/admin.py:574
msgid "Circle deleted"
msgstr ""
#: snikket_web/admin.py:640
msgid "Message contents"
msgstr ""
#: snikket_web/admin.py:616
#: snikket_web/admin.py:646
msgid "Only send to online users"
msgstr ""
#: snikket_web/admin.py:620
#: snikket_web/admin.py:650
msgid "Post to all users"
msgstr ""
#: snikket_web/admin.py:624
#: snikket_web/admin.py:654
msgid "Send preview to yourself"
msgstr ""
#: snikket_web/admin.py:646
#: snikket_web/admin.py:676
msgid "Announcement sent!"
msgstr ""
@@ -552,6 +553,43 @@ msgstr ""
msgid "Copy complete output"
msgstr ""
#: snikket_web/templates/admin_delete_circle.html:4
#, python-format
msgid "Delete circle %(circle_name)s"
msgstr ""
#: snikket_web/templates/admin_delete_circle.html:6
#: snikket_web/templates/admin_edit_circle.html:48
#: snikket_web/templates/admin_edit_circle.html:51
msgid "Delete circle"
msgstr ""
#: snikket_web/templates/admin_delete_circle.html:8
msgid "Are you sure you want to delete the following circle?"
msgstr ""
#: snikket_web/templates/admin_delete_circle.html:13
#: snikket_web/templates/admin_delete_user.html:15
msgid "Danger"
msgstr ""
#: snikket_web/templates/admin_delete_circle.html:14
msgid ""
"The circle and the corresponding chat will be deleted, permanently and "
"immediately upon pushing the below button. <strong>There is no way "
"back!</strong>"
msgstr ""
#: snikket_web/templates/admin_delete_circle.html:17
#: snikket_web/templates/admin_delete_user.html:19
#: snikket_web/templates/admin_reset_user_password.html:25
#: snikket_web/templates/user_logout.html:10
#: snikket_web/templates/user_manage_data.html:14
#: snikket_web/templates/user_passwd.html:27
#: snikket_web/templates/user_profile.html:32
msgid "Back"
msgstr ""
#: snikket_web/templates/admin_delete_user.html:4
#, python-format
msgid "Delete user %(user_name)s"
@@ -566,10 +604,6 @@ msgstr ""
msgid "Are you sure you want to delete the following user?"
msgstr ""
#: snikket_web/templates/admin_delete_user.html:15
msgid "Danger"
msgstr ""
#: snikket_web/templates/admin_delete_user.html:16
msgid ""
"The user and their data will be deleted irrevocably, permanently and "
@@ -577,15 +611,6 @@ msgid ""
"back!</strong>"
msgstr ""
#: snikket_web/templates/admin_delete_user.html:19
#: snikket_web/templates/admin_reset_user_password.html:25
#: snikket_web/templates/user_logout.html:10
#: snikket_web/templates/user_manage_data.html:14
#: snikket_web/templates/user_passwd.html:27
#: snikket_web/templates/user_profile.html:32
msgid "Back"
msgstr ""
#: snikket_web/templates/admin_edit_circle.html:14
msgid "This is your main circle"
msgstr ""
@@ -618,10 +643,6 @@ msgstr ""
msgid "Return to circle list"
msgstr ""
#: snikket_web/templates/admin_edit_circle.html:48
msgid "Delete circle"
msgstr ""
#: snikket_web/templates/admin_edit_circle.html:49
msgid "Deleting a circle does not delete any users in the circle."
msgstr ""