]> git.ipfire.org Git - ipfire.org.git/commitdiff
dnsbl: Add a simple search function
authorMichael Tremer <michael.tremer@ipfire.org>
Tue, 30 Dec 2025 15:23:15 +0000 (15:23 +0000)
committerMichael Tremer <michael.tremer@ipfire.org>
Tue, 30 Dec 2025 15:23:15 +0000 (15:23 +0000)
Signed-off-by: Michael Tremer <michael.tremer@ipfire.org>
Makefile.am
src/backend/dnsbl.py
src/templates/base.html
src/templates/dnsbl/search.html [new file with mode: 0644]
src/web/__init__.py
src/web/dnsbl.py

index 68db2c29243dde2469b7eb510834d9aa55e92003..8118bdc88da9e14c6eccebfe510016b68a900fcc 100644 (file)
@@ -184,7 +184,8 @@ templates_blog_modules_DATA = \
 templates_blog_modulesdir = $(templates_blogdir)/modules
 
 templates_dnsbl_DATA = \
-       src/templates/dnsbl/index.html
+       src/templates/dnsbl/index.html \
+       src/templates/dnsbl/search.html
 
 templates_dnsbldir = $(templatesdir)/dnsbl
 
index 7999a7bb6f6a9b5c558eda79da56f95b97cf7cbd..beec69c0ed7aa3df6d56bbfddb1414d79680b379 100644 (file)
@@ -1,5 +1,6 @@
 #!/usr/bin/python3
 
+import asyncio
 import datetime
 import json
 import logging
@@ -99,6 +100,29 @@ class DNSBL(Object):
                # Return the report
                return Report(self.backend, **response)
 
+       # Search!
+
+       async def search(self, q):
+               """
+                       Searches for a domain
+               """
+               tasks = {}
+
+               # Perform the search
+               result = await self._fetch("/search", args={ "q" : q })
+
+               # Fetch all lists
+               async with asyncio.TaskGroup() as tg:
+                       for slug in result:
+                               task = tg.create_task(
+                                       self.get_list(slug),
+                               )
+
+                               tasks[task] = result[slug]
+
+               # Return a mapping with the list and domains
+               return { task.result() : tasks[task] for task in tasks }
+
 
 class Model(pydantic.BaseModel):
        """
@@ -120,6 +144,9 @@ class List(Model):
        def __str__(self):
                return self.name
 
+       def __hash__(self):
+               return hash(self.slug)
+
        # Name
        name : str
 
index 8163484210f5fe3b0c80e50955aa130ea6fc7512..80fa86cadcdb9f7d47b9611fe153799e95385479 100644 (file)
                                                                                {{ _("Report") }}
                                                                        </a>
 
+                                                                       <div class="navbar-item">
+                                                                               <form action="/dnsbl/search" method="GET">
+                                                                                       <div class="field">
+                                                                                               <div class="control has-icons-left">
+                                                                                                       <input class="input" type="text"
+                                                                                                               name="q" {% if q %}value="{{ q }}"{% end %}
+                                                                                                               placeholder="{{ _("Search DNSBL...") }}">
+                                                                                                       <span class="icon is-small is-left">
+                                                                                                               <i class="fas fa-search"></i>
+                                                                                                       </span>
+                                                                                               </div>
+                                                                                       </div>
+                                                                               </form>
+                                                                       </div>
+
                                                                {# Location #}
                                                                {% elif request.path.startswith("/location") %}
                                                                        <a class="navbar-item is-tab
diff --git a/src/templates/dnsbl/search.html b/src/templates/dnsbl/search.html
new file mode 100644 (file)
index 0000000..fbb8ce5
--- /dev/null
@@ -0,0 +1,58 @@
+{% extends "../base.html" %}
+
+{% block head %}
+       {% module OpenGraph(
+               title=_("IPFire DNSBL - Search Results For: %s") % q,
+       ) %}
+{% end block %}
+
+{% block title %}{{ _("Search Results For: %s") % q }}{% end block %}
+
+{% block container %}
+       <section class="hero is-dark">
+               <div class="hero-body">
+                       <div class="container">
+                               <h1 class="title">
+                                       {{ _("Search Results For: %s") % q }}
+                               </h1>
+                       </div>
+               </div>
+       </section>
+
+       <section class="section">
+               <div class="container">
+                       {# Show any results #}
+                       {% if results %}
+                               {% for list, domains in sorted(results.items()) %}
+                                       <div class="block">
+                                               <h5 class="title is-5">
+                                                       <a href="/dnsbl/lists/{{ list.slug }}">
+                                                               {{ list }}
+                                                       </a>
+                                               </h5>
+
+                                               <div class="content">
+                                                       {{ _("There is one matching domain on this list:",
+                                                                       "There are %(num)s matching domains on this list:", len(domains)) % \
+                                                               { "num" : len(domains) } }}
+
+                                                       <ul>
+                                                               {% for domain in domains %}
+                                                                       <li>
+                                                                               {{ domain }}
+                                                                       </li>
+                                                               {% end %}
+                                                       </ul>
+                                               </div>
+                                       </div>
+                               {% end %}
+
+                       {# Show a note if there has been no results #}
+                       {% else %}
+                               <div class="notification has-text-centered">
+                                       {{ _("There are no matches for '%s'") % q }}
+                               </div>
+                       {% end %}
+               </div>
+       </section>
+{% end block %}
index 0305ea1ba1c1dac1a524860e6f9bdca290ad425f..8778e5214eb096ac40cbe83e4c2e15351144ef6f 100644 (file)
@@ -220,6 +220,7 @@ class Application(tornado.web.Application):
                        (r"/dnsbl/lists/(\w+)/reports", dnsbl.ListReportsHandler),
                        (r"/dnsbl/report", dnsbl.SubmitReportHandler),
                        (r"/dnsbl/reports/([0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12})", dnsbl.ReportHandler),
+                       (r"/dnsbl/search", dnsbl.SearchHandler),
 
                        # Single-Sign-On for Discourse
                        (r"/sso/discourse", auth.SSODiscourse),
index a9821df21c8ac9a656bfdb94304507a329b97065..3abee1c8e57c533b220df9a45d60688330361dfe 100644 (file)
@@ -91,6 +91,22 @@ class ReportHandler(base.AnalyticsMixin, BaseHandler):
                self.render("dnsbl/reports/show.html", report=report, list=list)
 
 
+class SearchHandler(base.AnalyticsMixin, BaseHandler):
+       async def get(self):
+               # Fetch the query
+               q = self.get_argument("q", None)
+
+               # Fail if there is nothing to search for
+               if not q:
+                       raise tornado.web.HTTPError(400, "Empty search query")
+
+               # Search for the query
+               results = await self.backend.dnsbl.search(q)
+
+               # Render the page
+               self.render("dnsbl/search.html", q=q, results=results)
+
+
 class ListsModule(ui_modules.UIModule):
        def render(self, lists):
                return self.render_string("dnsbl/modules/lists.html", lists=lists)