login

<     >

2023-08-12 18:44:24 (UTC-03:00)

Marcel Rodrigues <marcelgmr@gmail.com>

implement user deletion

diff --git a/data.lua b/data.lua
index bd5385d..792bf7e 100644
--- a/data.lua
+++ b/data.lua
@@ -97,8 +97,16 @@ function Model:get_user_count()
     return self.db:execute("SELECT COUNT(*) as count FROM User;")[1].count
 end
 
-function Model:get_user(nick)
-    return self.db:execute("SELECT * FROM User WHERE nick = ?;", nick)[1]
+function Model:get_user(nick, full)
+    local user = self.db:execute("SELECT * FROM User WHERE nick = ?;", nick)[1]
+    if full and user ~= nil and user.invited_by ~= nil then
+        local inviter = self.db:execute(
+            "SELECT nick, name FROM User WHERE id = ?;", user.invited_by
+        )[1]
+        user.inviter_nick = inviter.nick
+        user.inviter_name = inviter.name
+    end
+    return user
 end
 
 function Model:get_indexed_users()
@@ -110,6 +118,23 @@ function Model:get_indexed_users()
     return users
 end
 
+function Model:can_manage(user, other)
+    local parent_id = other.invited_by
+    while parent_id ~= nil do
+        if parent_id == user.id then
+            return true
+        end
+        other = self.db:execute("SELECT invited_by FROM User WHERE id = ?;", parent_id)[1]
+        parent_id = other.invited_by
+    end
+    return false
+end
+
+function Model:del_user(user_id)
+    self.db:execute("DELETE FROM Membership WHERE user_id = ?;", user_id)
+    self.db:execute("DELETE FROM User WHERE id = ?;", user_id)
+end
+
 function Model:create_invite(user_id)
     local uuid = auth.hex(auth.uuid4())
     local expire = "strftime('%s', 'now', '+2 days')"

diff --git a/skopos.lua b/skopos.lua
index c7e83ce..0550424 100644
--- a/skopos.lua
+++ b/skopos.lua
@@ -129,12 +129,27 @@ function App:routes()
     function (req, nick)
         local user = self:get_user(req)
         if user == nil then return "/login?after="..req.path, 303 end
-        local other = self.model:get_user(nick)
+        local other = self.model:get_user(nick, true)
         if other == nil then return "not found", 404 end
+        local manage = self.model:can_manage(user, other)
         local projs = self.model:get_user_projects(other.id)
-        local env = {title=self.title, user=user, other=other, projs=projs}
+        local env = {
+            title=self.title, user=user, other=other, manage=manage, projs=projs
+        }
         return lud.template.render_file("view/user.html", env)
     end},
+    {"POST", "/u/([-_%w]+)/del",
+    function (req, nick)
+        local user = self:get_user(req)
+        if user == nil then return "/login", 303 end
+        local other = self.model:get_user(nick)
+        if other == nil then return "not found", 404 end
+        if self.model:can_manage(user, other) then
+            self.model:del_user(other.id)
+            self:log(LOG_INFO, "user "..user.nick.." deleted user "..other.nick)
+        end
+        return "/", 303
+    end},
     -- invites
     {"GET", "/i",
     function (req)

diff --git a/view/user.html b/view/user.html
index 0e6341a..cebb4cd 100644
--- a/view/user.html
+++ b/view/user.html
@@ -21,7 +21,14 @@
   <h1 class="centered">user</h1>
   <p><strong>nick:</strong> {{$other.nick}}</p>
   <p><strong>name:</strong> {{$other.name}}</p>
-  <p><strong>invited by:</strong> {{$other.invited_by or "(root)"}}</p>
+  <p>
+    <strong>invited by:</strong>
+    % if $other.invited_by ~= nil then
+    <a href="/u/{{$other.inviter_nick}}">{{$other.inviter_name}}</a>
+    % else
+    (root)
+    % end
+  </p>
   <p><strong>projects:</strong>
     <ul class="proj-list">
       % for proj in $projs do
@@ -33,5 +40,10 @@
       % end
     </ul>
   </p>
+  % if $manage then
+  <form action="/u/{{$other.nick}}/del" method="post">
+    <button type="submit">delete</button>
+  </form>
+  % end
 </body>
 </html>