templates_staticdir = $(templatesdir)/static
templates_users_DATA = \
+ src/templates/users/delete.html \
+ src/templates/users/deleted.html \
src/templates/users/edit.html \
src/templates/users/index.html \
src/templates/users/passwd.html \
Deletes this user
"""
# Check if this user can be deleted
- if not self.can_be_deleted(user):
+ if not self.can_be_deleted_by(user):
raise RuntimeError("Cannot delete user %s" % self)
async with asyncio.TaskGroup() as tasks:
# XXX Delete on LDAP
- def can_be_deleted(self, user):
+ def can_be_deleted_by(self, user):
"""
Return True if the user can be deleted by user
"""
--- /dev/null
+{% extends "../base.html" %}
+
+{% block title %}{{ _("Delete %s") % account }}{% end block %}
+
+{% block container %}
+ <section class="section">
+ <div class="container">
+ <div class="columns is-centered">
+ <div class="column is-one-third">
+ <h1 class="title is-1">
+ {{ _("Delete User") }}
+ </h1>
+ <h4 class="subtitle is-4">{{ account }}</h4>
+
+ <div class="block has-text-danger">
+ <form action="" method="POST">
+ {% raw xsrf_form_html() %}
+
+ {% if next %}<input type="hidden" name="next" value="{{ next }}">{% end %}
+
+ <div class="field">
+ <p>
+ {{ _("Are you sure you want to delete %s?") % account }}
+ </p>
+
+ <p>
+ {{ _("This cannot be undone.") }}
+ </p>
+ </div>
+
+ <div class="field">
+ <div class="control">
+ <button class="button is-danger is-fullwidth">
+ {{ _("Delete %s") % account }}
+ </button>
+ </div>
+ </div>
+ </form>
+ </div>
+ </div>
+ </div>
+ </div>
+ </section>
+{% end block %}
--- /dev/null
+{% extends "../base.html" %}
+
+{% block title %}{{ _("%s Deleted") % account }}{% end block %}
+
+{% block container %}
+ <section class="section">
+ <div class="container">
+ <div class="columns is-centered">
+ <div class="column is-half">
+ <div class="notification is-danger has-text-centered">
+ <p class="is-size-5">
+ {{ _("%s has been successfully deleted") % account }}
+ </p>
+ </div>
+ </div>
+ </div>
+ </div>
+ </section>
+{% end block %}
</a>
{% end %}
+ <a class="button is-light" href="/users/{{ account.uid }}/passwd">
+ {{ _("Change Password") }}
+ </a>
+
<a class="button is-warning" href="/users/{{ account.uid }}/edit">
{{ _("Edit") }}
</a>
- <a class="button is-light" href="/users/{{ account.uid }}/passwd">
- {{ _("Change Password") }}
+ <a class="button is-danger" href="/users/{{ account.uid }}/delete"
+ {% if not account.can_be_deleted_by(current_user) %}disabled{% end %}>
+ {{ _("Delete") }}
</a>
{% end %}
</div>
(r"/users", users.IndexHandler),
(r"/users/([a-z_][a-z0-9_-]{0,31})", users.ShowHandler),
(r"/users/([a-z_][a-z0-9_-]{0,31})\.jpg", users.AvatarHandler),
+ (r"/users/([a-z_][a-z0-9_-]{0,31})/delete", users.DeleteHandler),
(r"/users/([a-z_][a-z0-9_-]{0,31})/edit", users.EditHandler),
(r"/users/([a-z_][a-z0-9_-]{0,31})/passwd", users.PasswdHandler),
self.redirect("/users/%s" % account.uid)
+class DeleteHandler(base.BaseHandler):
+ @tornado.web.authenticated
+ def get(self, uid):
+ account = self.backend.accounts.get_by_uid(uid)
+ if not account:
+ raise tornado.web.HTTPError(404, "Could not find account %s" % uid)
+
+ # Check for permissions
+ if not account.can_be_deleted_by(self.current_user):
+ raise tornado.web.HTTPError(403, "%s cannot delete %s" % (self.current_user, account))
+
+ self.render("users/delete.html", account=account)
+
+ @tornado.web.authenticated
+ async def post(self, uid):
+ account = self.backend.accounts.get_by_uid(uid)
+ if not account:
+ raise tornado.web.HTTPError(404, "Could not find account %s" % uid)
+
+ # Check for permissions
+ if not account.can_be_deleted_by(self.current_user):
+ raise tornado.web.HTTPError(403, "%s cannot delete %s" % (self.current_user, account))
+
+ # Delete!
+ with self.db.transaction():
+ await account.delete(self.current_user)
+
+ self.render("users/deleted.html", account=account)
+
+
class PasswdHandler(base.BaseHandler):
@tornado.web.authenticated
def get(self, uid):