dist_pkgpython_api_PYTHON = \
src/dnsbl/api/__init__.py \
+ src/dnsbl/api/domains.py \
src/dnsbl/api/lists.py \
src/dnsbl/api/reports.py
def auth(self):
return auth.Auth(self)
+ @functools.cached_property
+ def domains(self):
+ return domains.Domains(self)
+
@functools.cached_property
def lists(self):
return lists.Lists(self)
raise fastapi.HTTPException(401, "Invalid API key")
# Import any endpoints
+from . import domains
from . import lists
from . import reports
--- /dev/null
+###############################################################################
+# #
+# dnsbl - A DNS Blocklist Compositor For IPFire #
+# Copyright (C) 2026 IPFire Development Team #
+# #
+# This program is free software: you can redistribute it and/or modify #
+# it under the terms of the GNU General Public License as published by #
+# the Free Software Foundation, either version 3 of the License, or #
+# (at your option) any later version. #
+# #
+# This program is distributed in the hope that it will be useful, #
+# but WITHOUT ANY WARRANTY; without even the implied warranty of #
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the #
+# GNU General Public License for more details. #
+# #
+# You should have received a copy of the GNU General Public License #
+# along with this program. If not, see <http://www.gnu.org/licenses/>. #
+# #
+###############################################################################
+
+import fastapi
+import typing
+import uuid
+
+from .. import domains
+
+# Import the main app
+from . import app
+from . import backend
+
+# Create a router
+router = fastapi.APIRouter(
+ prefix="/domains",
+ tags=["Domains"],
+)
+
+@router.get("/{name}")
+def get_domain(name: str):
+ # Fetch all domains that match the name
+ domains = backend.domains.get_by_name(name)
+
+ # Show where the domain is currently listed
+ return { domain.list.slug : { "added_at" : domain.added_at } for domain in domains }
+
+# Include our endpoints
+app.include_router(router)
# Setup logging
log = logging.getLogger(__name__)
+class Domains(object):
+ def __init__(self, backend):
+ self.backend = backend
+
+ def get_by_name(self, name):
+ """
+ Fetch all domain objects that match the name
+ """
+ stmt = (
+ sqlmodel
+ .select(
+ Domain,
+ )
+ .where(
+ # Name must match
+ Domain.name == name,
+
+ # Ignore domains that have been removed
+ Domain.removed_at == None,
+ )
+ )
+
+ return self.backend.db.fetch_as_set(stmt)
+
+
class Domain(sqlmodel.SQLModel, database.BackendMixin, table=True):
__tablename__ = "domains"
def __str__(self):
return self.name
+ def __hash__(self):
+ return hash(self.id)
+
# ID
id: int = sqlmodel.Field(primary_key=True)
priority = priority,
)
+ def get_listing_domain(self, name):
+ """
+ Returns all lists that currently contain the given domain.
+ """
+ stmt = (
+ sqlmodel
+ .select(
+ List,
+ )
+ .select_from(
+ domains.Domain,
+ domains.Domain.list_id == List.id,
+ )
+ .where(
+ # Fetch the matching domain
+ domains.Domain.name == name,
+
+ # Ignore any domains that have been removed
+ domains.Domain.removed_at == None,
+
+ # Ignore deleted lists
+ List.deleted_at == None,
+ )
+ .order_by(
+ List.name,
+ List.slug,
+ )
+ )
+
+ return self.backend.db.fetch_as_list(stmt)
+
class List(sqlmodel.SQLModel, database.BackendMixin, table=True):
__tablename__ = "lists"