You've already forked snikket-web-portal
@@ -17,10 +17,11 @@ from quart import (
|
|||||||
url_for,
|
url_for,
|
||||||
request,
|
request,
|
||||||
abort,
|
abort,
|
||||||
|
flash,
|
||||||
)
|
)
|
||||||
import flask_wtf
|
import flask_wtf
|
||||||
|
|
||||||
from flask_babel import lazy_gettext as _l
|
from flask_babel import lazy_gettext as _l, _
|
||||||
|
|
||||||
from . import prosodyclient
|
from . import prosodyclient
|
||||||
from .infra import client, circle_name
|
from .infra import client, circle_name
|
||||||
@@ -68,6 +69,10 @@ async def delete_user(localpart: str) -> typing.Union[str, quart.Response]:
|
|||||||
if form.validate_on_submit():
|
if form.validate_on_submit():
|
||||||
if form.action_delete.data:
|
if form.action_delete.data:
|
||||||
await client.delete_user_by_localpart(localpart)
|
await client.delete_user_by_localpart(localpart)
|
||||||
|
await flash(
|
||||||
|
_("User deleted"),
|
||||||
|
"success",
|
||||||
|
)
|
||||||
return redirect(url_for(".users"))
|
return redirect(url_for(".users"))
|
||||||
|
|
||||||
return await render_template(
|
return await render_template(
|
||||||
@@ -107,8 +112,16 @@ async def create_password_reset_link() -> typing.Union[str, quart.Response]:
|
|||||||
localpart=localpart,
|
localpart=localpart,
|
||||||
ttl=86400,
|
ttl=86400,
|
||||||
)
|
)
|
||||||
|
await flash(
|
||||||
|
_("Password reset link created"),
|
||||||
|
"success",
|
||||||
|
)
|
||||||
elif form.action_revoke.data:
|
elif form.action_revoke.data:
|
||||||
await client.delete_invite(form.action_revoke.data)
|
await client.delete_invite(form.action_revoke.data)
|
||||||
|
await flash(
|
||||||
|
_("Password reset link deleted"),
|
||||||
|
"success",
|
||||||
|
)
|
||||||
return redirect(url_for(".users"))
|
return redirect(url_for(".users"))
|
||||||
|
|
||||||
return await render_template(
|
return await render_template(
|
||||||
@@ -242,6 +255,10 @@ async def create_invite() -> typing.Union[str, quart.Response]:
|
|||||||
group_ids=form.circles.data,
|
group_ids=form.circles.data,
|
||||||
ttl=form.lifetime.data,
|
ttl=form.lifetime.data,
|
||||||
)
|
)
|
||||||
|
await flash(
|
||||||
|
_("Invitation created"),
|
||||||
|
"success",
|
||||||
|
)
|
||||||
return redirect(url_for(".edit_invite", id_=invite.id_))
|
return redirect(url_for(".edit_invite", id_=invite.id_))
|
||||||
return await render_template("admin_create_invite.html",
|
return await render_template("admin_create_invite.html",
|
||||||
invite_form=form)
|
invite_form=form)
|
||||||
@@ -254,7 +271,11 @@ async def edit_invite(id_: str) -> typing.Union[str, quart.Response]:
|
|||||||
invite_info = await client.get_invite_by_id(id_)
|
invite_info = await client.get_invite_by_id(id_)
|
||||||
except aiohttp.ClientResponseError as exc:
|
except aiohttp.ClientResponseError as exc:
|
||||||
if exc.status == 404:
|
if exc.status == 404:
|
||||||
abort(404)
|
await flash(
|
||||||
|
_("No such invitation exists"),
|
||||||
|
"alert",
|
||||||
|
)
|
||||||
|
return redirect(url_for(".invitations"))
|
||||||
circles = await client.list_groups()
|
circles = await client.list_groups()
|
||||||
circle_map = {
|
circle_map = {
|
||||||
circle.id_: circle
|
circle.id_: circle
|
||||||
@@ -265,6 +286,10 @@ async def edit_invite(id_: str) -> typing.Union[str, quart.Response]:
|
|||||||
if form.validate_on_submit():
|
if form.validate_on_submit():
|
||||||
if form.action_revoke.data:
|
if form.action_revoke.data:
|
||||||
await client.delete_invite(id_)
|
await client.delete_invite(id_)
|
||||||
|
await flash(
|
||||||
|
_("Invitation revoked"),
|
||||||
|
"success",
|
||||||
|
)
|
||||||
return redirect(url_for(".invitations"))
|
return redirect(url_for(".invitations"))
|
||||||
return redirect(url_for(".edit_invite", id_=id_))
|
return redirect(url_for(".edit_invite", id_=id_))
|
||||||
|
|
||||||
@@ -313,6 +338,10 @@ async def create_circle() -> typing.Union[str, quart.Response]:
|
|||||||
circle = await client.create_group(
|
circle = await client.create_group(
|
||||||
name=create_form.name.data,
|
name=create_form.name.data,
|
||||||
)
|
)
|
||||||
|
await flash(
|
||||||
|
_("Circle created"),
|
||||||
|
"success",
|
||||||
|
)
|
||||||
return redirect(url_for(".edit_circle", id_=circle.id_))
|
return redirect(url_for(".edit_circle", id_=circle.id_))
|
||||||
|
|
||||||
return await render_template(
|
return await render_template(
|
||||||
@@ -358,6 +387,10 @@ async def edit_circle(id_: str) -> typing.Union[str, quart.Response]:
|
|||||||
)
|
)
|
||||||
except aiohttp.ClientResponseError as exc:
|
except aiohttp.ClientResponseError as exc:
|
||||||
if exc.status == 404:
|
if exc.status == 404:
|
||||||
|
await flash(
|
||||||
|
_("No such circle exists"),
|
||||||
|
"alert",
|
||||||
|
)
|
||||||
return redirect(url_for(".circles"))
|
return redirect(url_for(".circles"))
|
||||||
raise
|
raise
|
||||||
|
|
||||||
@@ -391,21 +424,36 @@ async def edit_circle(id_: str) -> typing.Union[str, quart.Response]:
|
|||||||
id_,
|
id_,
|
||||||
new_name=form.name.data,
|
new_name=form.name.data,
|
||||||
)
|
)
|
||||||
|
await flash(
|
||||||
|
_("Circle data updated"),
|
||||||
|
"success",
|
||||||
|
)
|
||||||
elif form.action_delete.data:
|
elif form.action_delete.data:
|
||||||
await client.delete_group(id_)
|
await client.delete_group(id_)
|
||||||
|
await flash(
|
||||||
|
_("Circle deleted"),
|
||||||
|
"success",
|
||||||
|
)
|
||||||
return redirect(url_for(".circles"))
|
return redirect(url_for(".circles"))
|
||||||
elif form.action_add_user.data:
|
elif form.action_add_user.data:
|
||||||
if form.user_to_add.data in valid_users:
|
if form.user_to_add.data in valid_users:
|
||||||
print("is valid")
|
|
||||||
await client.add_group_member(
|
await client.add_group_member(
|
||||||
id_,
|
id_,
|
||||||
form.user_to_add.data,
|
form.user_to_add.data,
|
||||||
)
|
)
|
||||||
|
await flash(
|
||||||
|
_("User added to circle"),
|
||||||
|
"success",
|
||||||
|
)
|
||||||
elif form.action_remove_user.data:
|
elif form.action_remove_user.data:
|
||||||
await client.remove_group_member(
|
await client.remove_group_member(
|
||||||
id_,
|
id_,
|
||||||
form.action_remove_user.data,
|
form.action_remove_user.data,
|
||||||
)
|
)
|
||||||
|
await flash(
|
||||||
|
_("User removed from circle"),
|
||||||
|
"success",
|
||||||
|
)
|
||||||
|
|
||||||
return redirect(url_for(".edit_circle", id_=id_))
|
return redirect(url_for(".edit_circle", id_=id_))
|
||||||
else:
|
else:
|
||||||
|
|||||||
@@ -15,6 +15,7 @@ from quart import (
|
|||||||
render_template,
|
render_template,
|
||||||
request,
|
request,
|
||||||
Response,
|
Response,
|
||||||
|
flash,
|
||||||
)
|
)
|
||||||
|
|
||||||
import babel
|
import babel
|
||||||
@@ -22,7 +23,7 @@ import wtforms
|
|||||||
|
|
||||||
import flask_wtf
|
import flask_wtf
|
||||||
|
|
||||||
from flask_babel import lazy_gettext as _l
|
from flask_babel import lazy_gettext as _l, _
|
||||||
|
|
||||||
from . import xmpputil, _version
|
from . import xmpputil, _version
|
||||||
from .infra import client
|
from .infra import client
|
||||||
@@ -79,6 +80,10 @@ async def login() -> typing.Union[str, quart.Response]:
|
|||||||
except quart.exceptions.Unauthorized:
|
except quart.exceptions.Unauthorized:
|
||||||
form.password.errors.append(ERR_CREDENTIALS_INVALID)
|
form.password.errors.append(ERR_CREDENTIALS_INVALID)
|
||||||
else:
|
else:
|
||||||
|
await flash(
|
||||||
|
_("Login successful!"),
|
||||||
|
"success"
|
||||||
|
)
|
||||||
return redirect(url_for('user.index'))
|
return redirect(url_for('user.index'))
|
||||||
|
|
||||||
return await render_template("login.html", form=form)
|
return await render_template("login.html", form=form)
|
||||||
|
|||||||
@@ -2,7 +2,14 @@ import asyncio
|
|||||||
import typing
|
import typing
|
||||||
|
|
||||||
import quart.flask_patch
|
import quart.flask_patch
|
||||||
from quart import Blueprint, render_template, request, redirect, url_for
|
from quart import (
|
||||||
|
Blueprint,
|
||||||
|
render_template,
|
||||||
|
request,
|
||||||
|
redirect,
|
||||||
|
url_for,
|
||||||
|
flash,
|
||||||
|
)
|
||||||
import quart.exceptions
|
import quart.exceptions
|
||||||
|
|
||||||
import wtforms
|
import wtforms
|
||||||
@@ -93,6 +100,10 @@ async def change_pw() -> typing.Union[str, quart.Response]:
|
|||||||
_("Incorrect password"),
|
_("Incorrect password"),
|
||||||
)
|
)
|
||||||
else:
|
else:
|
||||||
|
await flash(
|
||||||
|
_("Password changed"),
|
||||||
|
"success",
|
||||||
|
)
|
||||||
return redirect(url_for("user.change_pw"))
|
return redirect(url_for("user.change_pw"))
|
||||||
|
|
||||||
return await render_template("user_passwd.html", form=form)
|
return await render_template("user_passwd.html", form=form)
|
||||||
@@ -131,6 +142,10 @@ async def profile() -> typing.Union[str, quart.Response]:
|
|||||||
client.set_nickname_access_model(access_model),
|
client.set_nickname_access_model(access_model),
|
||||||
)
|
)
|
||||||
|
|
||||||
|
await flash(
|
||||||
|
_("Profile updated"),
|
||||||
|
"success",
|
||||||
|
)
|
||||||
return redirect(url_for(".profile"))
|
return redirect(url_for(".profile"))
|
||||||
|
|
||||||
return await render_template("user_profile.html", form=form)
|
return await render_template("user_profile.html", form=form)
|
||||||
@@ -142,6 +157,12 @@ async def logout() -> typing.Union[quart.Response, str]:
|
|||||||
form = LogoutForm()
|
form = LogoutForm()
|
||||||
if form.validate_on_submit():
|
if form.validate_on_submit():
|
||||||
await client.logout()
|
await client.logout()
|
||||||
|
# No flashing here because we don’t collect flashes in the login page
|
||||||
|
# and it’d be weird.
|
||||||
|
# await flash(
|
||||||
|
# _("Logged out"),
|
||||||
|
# "success",
|
||||||
|
# )
|
||||||
return redirect(url_for("main.index"))
|
return redirect(url_for("main.index"))
|
||||||
|
|
||||||
return await render_template("user_logout.html", form=form)
|
return await render_template("user_logout.html", form=form)
|
||||||
|
|||||||
Reference in New Issue
Block a user