]> git.ipfire.org Git - dbl.git/commitdiff
dnsbl: Add a command to add a source to a list
authorMichael Tremer <michael.tremer@ipfire.org>
Fri, 5 Dec 2025 15:59:02 +0000 (15:59 +0000)
committerMichael Tremer <michael.tremer@ipfire.org>
Fri, 5 Dec 2025 15:59:02 +0000 (15:59 +0000)
Signed-off-by: Michael Tremer <michael.tremer@ipfire.org>
Makefile.am
src/dnsbl/__init__.py
src/dnsbl/lists.py
src/dnsbl/sources.py [new file with mode: 0644]
src/scripts/dnsbl.in

index ddbfcb24c703777d7c78bdb487567ad7297c6f3b..14a72ad75d3bdb956ef38e72c12c22c2daa3021d 100644 (file)
@@ -54,6 +54,7 @@ dist_pkgpython_PYTHON = \
        src/dnsbl/i18n.py \
        src/dnsbl/lists.py \
        src/dnsbl/logger.py \
+       src/dnsbl/sources.py \
        src/dnsbl/util.py
 
 # ------------------------------------------------------------------------------
index 4b108be4167fae66f7b34b840438aa1bb744eeea..e4240b0b42880b2565e8a5a000d2f24264ad68e8 100644 (file)
@@ -31,6 +31,7 @@ log = logging.getLogger(__name__)
 
 # Import sub-modules
 from . import lists
+from . import sources
 
 class Backend(object):
        def __init__(self, config=None, debug=False):
@@ -84,6 +85,10 @@ class Backend(object):
        def lists(self):
                return lists.Lists(self)
 
+       @functools.cached_property
+       def sources(self):
+               return sources.Sources(self)
+
        def update_sources(self):
                """
                        Updates all sources
index 3f683d4b1025e85fc9772147d5813c94adabccf3..4bd882013e37e64312d1cc020b6a607830d5b043 100644 (file)
@@ -20,7 +20,9 @@
 
 import datetime
 import sqlmodel
+import typing
 
+from . import sources
 from . import util
 
 class Lists(object):
@@ -105,3 +107,6 @@ class List(sqlmodel.SQLModel, table=True):
 
        # License
        license : str
+
+       # Sources
+       sources : typing.List["Source"] = sqlmodel.Relationship(back_populates="list")
diff --git a/src/dnsbl/sources.py b/src/dnsbl/sources.py
new file mode 100644 (file)
index 0000000..ed30291
--- /dev/null
@@ -0,0 +1,96 @@
+###############################################################################
+#                                                                             #
+# dnsbl - A DNS Blacklist Compositor For IPFire                               #
+# Copyright (C) 2025 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 datetime
+import sqlmodel
+
+class Sources(object):
+       def __init__(self, backend):
+               self.backend = backend
+
+       def get_by_id(self, id):
+               stmt = (
+                       sqlmodel
+                       .select(
+                               Source,
+                       )
+                       .where(
+                               Source.id == id,
+                       )
+               )
+
+               with self.backend.session() as session:
+                       result = session.execute(stmt)
+
+                       return result.scalar_one_or_none()
+
+       def create(self, list, name, url, created_by, license):
+               """
+                       Creates a new source
+               """
+               # Create a new source
+               with self.backend.session() as session:
+                       source = Source(
+                               list       = list,
+                               name       = name,
+                               url        = url,
+                               created_by = created_by,
+                               license    = license,
+                       )
+                       session.add(source)
+                       session.commit()
+
+               return source
+
+
+class Source(sqlmodel.SQLModel, table=True):
+       __tablename__ = "sources"
+
+       # ID
+       id : int = sqlmodel.Field(primary_key=True)
+
+       # Name
+       name : str
+
+       # URL
+       url : str
+
+       # Created At
+       created_at : datetime.datetime = sqlmodel.Field(
+               sa_column_kwargs = {"server_default" : sqlmodel.text("CURRENT_TIMESTAMP")}
+       )
+
+       # Created By
+       created_by : str
+
+       # Deleted At
+       deleted_at : datetime.datetime | None
+
+       # Deleted By
+       deleted_by : str | None
+
+       # License
+       license : str
+
+       # List ID
+       list_id : int = sqlmodel.Field(foreign_key="lists.id")
+
+       # List
+       list : "List" = sqlmodel.Relationship(back_populates="sources")
index ef4556d5aab6b9a25239e655cd6c3c74e680a428..7b6a2144d063982db64fd321934ff651c7728f6b 100644 (file)
@@ -56,6 +56,21 @@ class CLI(object):
                                help=_("The license of the list"))
                create_list.set_defaults(func=self.__create_list)
 
+               # list-add-source
+               list_add_source = subparsers.add_parser("list-add-source",
+                               help=_("Creates a new source to a list"))
+               list_add_source.add_argument("list",
+                               help=_("The name of the list"))
+               list_add_source.add_argument("--name", required=True,
+                               help=_("The name of the source"))
+               list_add_source.add_argument("--url", required=True,
+                               help=_("The URL of the source"))
+               list_add_source.add_argument("--license", required=True,
+                               help=_("The license of the source"))
+               list_add_source.add_argument("--created-by", required=True,
+                               default=os.environ.get("USER"), help=_("The creator of the source"))
+               list_add_source.set_defaults(func=self.__list_add_source)
+
                # update
                update = subparsers.add_parser("update", help=_("Update sources"))
                update.set_defaults(func=self.__update)
@@ -104,6 +119,22 @@ class CLI(object):
                        license    = args.license,
                )
 
+       def __list_add_source(self, backend, args):
+               """
+                       Adds a new source to a list
+               """
+               # Fetch the list
+               list = backend.lists.get_by_slug(args.list)
+
+               # Create the source
+               backend.sources.create(
+                       list       = list,
+                       name       = args.name,
+                       url        = args.url,
+                       created_by = args.created_by,
+                       license    = args.license,
+               )
+
        def __update(self, backend, args):
                """
                        Updates all sources