]> git.ipfire.org Git - ipfire.org.git/commitdiff
users: Add controls to delete a user
authorMichael Tremer <michael.tremer@ipfire.org>
Wed, 28 Jun 2023 10:43:54 +0000 (10:43 +0000)
committerMichael Tremer <michael.tremer@ipfire.org>
Wed, 28 Jun 2023 10:43:54 +0000 (10:43 +0000)
Signed-off-by: Michael Tremer <michael.tremer@ipfire.org>
Makefile.am
src/backend/accounts.py
src/templates/users/delete.html [new file with mode: 0644]
src/templates/users/deleted.html [new file with mode: 0644]
src/templates/users/show.html
src/web/__init__.py
src/web/users.py

index 85762aefdbffd4b8722ad3b80088b7d170fcc9f5..fbf9d3bd011da846ab0d53b7d9180aebe2bbae25 100644 (file)
@@ -307,6 +307,8 @@ templates_static_DATA = \
 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 \
index d6e2d749ba5ef3fdacca6f01a63d2cf042b16ffd..a8269764039888ff10470d5dd91e7cb65fa994a9 100644 (file)
@@ -869,7 +869,7 @@ class Account(LDAPObject):
                        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:
@@ -884,7 +884,7 @@ class Account(LDAPObject):
 
                # 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
                """
diff --git a/src/templates/users/delete.html b/src/templates/users/delete.html
new file mode 100644 (file)
index 0000000..9b0367a
--- /dev/null
@@ -0,0 +1,44 @@
+{% 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 %}
diff --git a/src/templates/users/deleted.html b/src/templates/users/deleted.html
new file mode 100644 (file)
index 0000000..d277928
--- /dev/null
@@ -0,0 +1,19 @@
+{% 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 %}
index 644a95bfd9ab462b6e51c8da11ff5e860ef3bcea..842f11ede93d310947dfc0d09528cdbc1c426a7c 100644 (file)
                                                </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>
index 024f84c64c4f660218309e74dcf5c42b4c0b3a09..72e22ab288c18c196f220b6965514f1459930da7 100644 (file)
@@ -168,6 +168,7 @@ class Application(tornado.web.Application):
                        (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),
 
index a1572d836b5023af2b0fdefcdf1d926c0d43efc7..6dee34b9585074a06373bf9799862d1800d5ada4 100644 (file)
@@ -203,6 +203,36 @@ class EditHandler(base.BaseHandler):
                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):