]> git.ipfire.org Git - ipfire.org.git/commitdiff
dbl: Implement closing reports
authorMichael Tremer <michael.tremer@ipfire.org>
Sun, 8 Feb 2026 18:35:03 +0000 (18:35 +0000)
committerMichael Tremer <michael.tremer@ipfire.org>
Sun, 8 Feb 2026 18:35:03 +0000 (18:35 +0000)
Signed-off-by: Michael Tremer <michael.tremer@ipfire.org>
src/backend/dbl.py
src/templates/dbl/reports/show.html
src/web/__init__.py
src/web/dbl.py

index 5693fad91c282b760b46c119156b48b84f7b12d0..c50301cfd15b828894a64e4cea6f08c4fee09767 100644 (file)
@@ -66,7 +66,8 @@ class DBL(Object):
                        raise e
 
                # Decode the response
-               return json.loads(response.body)
+               if response.body:
+                       return json.loads(response.body)
 
        async def get_lists(self):
                """
@@ -378,6 +379,27 @@ class Report(Model):
 
                return self._list
 
+       # Close!
+
+       async def close(self, closed_by, accept=True):
+               """
+                       Closes the report
+               """
+               # Cannot already be closed
+               if self.is_closed():
+                       raise RuntimeError("Report %s is already closed" % self)
+
+               # Compose the payload
+               body = {
+                       "closed_by" : closed_by.uid,
+                       "accept"    : accept,
+               }
+
+               # Send the request
+               await self._backend.dbl._fetch(
+                       "/reports/%s/close" % self.id, method="POST", body=body,
+               )
+
 
 class History(Model):
        """
index ce1f77f919fb9db561874903c46699561c4a290f..2e586f38461b772d191814501fdad72a9ab719ac 100644 (file)
                                                        {% end %}
                                                </nav>
 
-                                               {% if current_user and current_user.is_dbl_moderator() %}
-                                                       <div class="block">
-                                                               <form method="POST" action="/dbl/reports/{{ report.id }}/approve">
-                                                                       {% raw xsrf_form_html() %}
-
-                                                                       <button class="button is-success is-fullwidth">
-                                                                               {{ _("Approve") }}
-                                                                       </button>
-                                                               </form>
-                                                       </div>
+                                               {# Actions #}
+                                               {% if not report.is_closed() %}
+                                                       {% if current_user and current_user.is_dbl_moderator() %}
+                                                               <div class="block">
+                                                                       <form method="POST" action="/dbl/reports/{{ report.id }}/close">
+                                                                               {% raw xsrf_form_html() %}
 
-                                                       <div class="block">
-                                                               <form method="POST" action="/dbl/reports/{{ report.id }}/reject">
-                                                                       {% raw xsrf_form_html() %}
+                                                                               <input type="hidden" name="accept" value="true" />
 
-                                                                       <button class="button is-link is-outlined is-fullwidth">
-                                                                               {{ _("Reject") }}
-                                                                       </button>
-                                                               </form>
-                                                       </div>
+                                                                               <button class="button is-success is-fullwidth">
+                                                                                       {{ _("Approve") }}
+                                                                               </button>
+                                                                       </form>
+                                                               </div>
+
+                                                               <div class="block">
+                                                                       <form method="POST" action="/dbl/reports/{{ report.id }}/close">
+                                                                               {% raw xsrf_form_html() %}
+
+                                                                               <input type="hidden" name="accept" value="false" />
+
+                                                                               <button class="button is-link is-outlined is-fullwidth">
+                                                                                       {{ _("Reject") }}
+                                                                               </button>
+                                                                       </form>
+                                                               </div>
+                                                       {% end %}
                                                {% end %}
                                        </div>
                                </div>
index 45e13f0bc48ae93a9c8b7777ec62d84853e8bf26..2bb5ff55877d87faf70af7fe49cdd0be8075412f 100644 (file)
@@ -227,6 +227,7 @@ class Application(tornado.web.Application):
                        (r"/dbl/lists/([\w\-]+)/history", dbl.ListHistoryHandler),
                        (r"/dbl/report", dbl.SubmitReportHandler),
                        (r"/dbl/reports/([0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12})", dbl.ReportHandler),
+                       (r"/dbl/reports/([0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12})/close", dbl.ReportCloseHandler),
                        (r"/dbl/search", dbl.SearchHandler),
 
                        # Single-Sign-On for Discourse
index ac16132a68490b307fd1f5e2edbf1378667ddca0..fea1f2840c4b3b9dde141afc02ccfaee094f6a21 100644 (file)
@@ -142,6 +142,29 @@ class ReportHandler(base.AnalyticsMixin, BaseHandler):
                        list=list, reporter=reporter, status=status)
 
 
+class ReportCloseHandler(base.AnalyticsMixin, BaseHandler):
+       def prepare(self):
+               # Require DBL moderators
+               if not self.current_user.is_dbl_moderator():
+                       raise tornado.web.HTTPError(401)
+
+       @tornado.web.authenticated
+       async def post(self, id):
+               # Fetch the report
+               report = await self.backend.dbl.get_report(id)
+               if not report:
+                       raise tornado.web.HTTPError(404, "Could not find report '%s'" % id)
+
+               # Has the report been accepted?
+               accept = self.get_argument_bool("accept")
+
+               # Approve the report
+               await report.close(self.current_user, accept=accept)
+
+               # Send back to the report
+               self.redirect("/dbl/reports/%s" % report.id)
+
+
 class SearchHandler(base.AnalyticsMixin, BaseHandler):
        async def get(self):
                # Fetch the query