Task 13: wire geo_batch_lookup through dependency injection and mark task completed

This commit is contained in:
2026-04-14 09:51:23 +02:00
parent 88715ab07f
commit 56ade7fb08
6 changed files with 52 additions and 37 deletions

View File

@@ -10,23 +10,19 @@ Manual ban and unban operations and the active-bans overview:
from __future__ import annotations
from typing import TYPE_CHECKING
if TYPE_CHECKING:
import aiohttp
from fastapi import APIRouter, HTTPException, Request, status
from app.dependencies import (
AuthDep,
DbDep,
Fail2BanSocketDep,
GeoBatchLookupDep,
HttpSessionDep,
)
from app.exceptions import JailNotFoundError, JailOperationError
from app.models.ban import ActiveBanListResponse, BanRequest, UnbanAllResponse, UnbanRequest
from app.models.jail import JailCommandResponse
from app.services import geo_service, jail_service
from app.exceptions import JailNotFoundError, JailOperationError
from app.services import jail_service
from app.utils.fail2ban_client import Fail2BanConnectionError
router: APIRouter = APIRouter(prefix="/api/bans", tags=["Bans"])
@@ -58,6 +54,7 @@ async def get_active_bans(
db: DbDep,
socket_path: Fail2BanSocketDep,
http_session: HttpSessionDep,
geo_batch_lookup: GeoBatchLookupDep,
) -> ActiveBanListResponse:
"""Return every IP that is currently banned across all fail2ban jails.
@@ -77,7 +74,7 @@ async def get_active_bans(
try:
return await jail_service.get_active_bans(
socket_path,
geo_batch_lookup=geo_service.lookup_batch,
geo_batch_lookup=geo_batch_lookup,
http_session=http_session,
app_db=db,
)

View File

@@ -31,6 +31,7 @@ from app.dependencies import (
AppDep,
AuthDep,
Fail2BanSocketDep,
GeoBatchLookupDep,
HttpSessionDep,
SchedulerDep,
get_db,
@@ -122,6 +123,7 @@ async def run_import_now(
db: DbDep,
_auth: AuthDep,
socket_path: Fail2BanSocketDep,
geo_batch_lookup: GeoBatchLookupDep,
) -> ImportRunResult:
"""Download and apply all enabled blocklist sources immediately.
@@ -140,7 +142,7 @@ async def run_import_now(
http_session,
socket_path,
geo_is_cached=geo_service.is_cached,
geo_batch_lookup=geo_service.lookup_batch,
geo_batch_lookup=geo_batch_lookup,
ban_ip=jail_service.ban_ip,
)

View File

@@ -21,6 +21,7 @@ from app.dependencies import (
AuthDep,
DbDep,
Fail2BanSocketDep,
GeoBatchLookupDep,
HttpSessionDep,
ServerStatusDep,
)
@@ -83,6 +84,7 @@ async def get_dashboard_bans(
db: DbDep,
socket_path: Fail2BanSocketDep,
http_session: HttpSessionDep,
geo_batch_lookup: GeoBatchLookupDep,
range: TimeRange = Query(default=_DEFAULT_RANGE, description="Time-range preset."),
source: Literal["fail2ban", "archive"] = Query(
default="fail2ban",
@@ -123,7 +125,7 @@ async def get_dashboard_bans(
page_size=page_size,
http_session=http_session,
app_db=db,
geo_batch_lookup=geo_service.lookup_batch,
geo_batch_lookup=geo_batch_lookup,
origin=origin,
)
@@ -138,6 +140,7 @@ async def get_bans_by_country(
db: DbDep,
socket_path: Fail2BanSocketDep,
http_session: HttpSessionDep,
geo_batch_lookup: GeoBatchLookupDep,
range: TimeRange = Query(default=_DEFAULT_RANGE, description="Time-range preset."),
source: Literal["fail2ban", "archive"] = Query(
default="fail2ban",
@@ -175,7 +178,7 @@ async def get_bans_by_country(
source=source,
http_session=http_session,
geo_cache_lookup=geo_service.lookup_cached_only,
geo_batch_lookup=geo_service.lookup_batch,
geo_batch_lookup=geo_batch_lookup,
app_db=db,
origin=origin,
country_code=country_code,

View File

@@ -27,6 +27,7 @@ from app.dependencies import (
AuthDep,
DbDep,
Fail2BanSocketDep,
GeoBatchLookupDep,
HttpSessionDep,
JailServiceDep,
)
@@ -38,7 +39,7 @@ from app.models.jail import (
JailDetailResponse,
JailListResponse,
)
from app.services import geo_service, jail_service
from app.services import jail_service
from app.utils.fail2ban_client import Fail2BanConnectionError
router: APIRouter = APIRouter(prefix="/api/jails", tags=["Jails"])
@@ -108,7 +109,7 @@ def _conflict(message: str) -> HTTPException:
async def get_jails(
_auth: AuthDep,
socket_path: Fail2BanSocketDep,
jail_service: JailServiceDep,
jail_service_dep: JailServiceDep,
) -> JailListResponse:
"""Return a summary of every active fail2ban jail.
@@ -123,7 +124,7 @@ async def get_jails(
:class:`~app.models.jail.JailListResponse` with all active jails.
"""
try:
return await jail_service.list_jails(socket_path)
return await jail_service_dep.list_jails(socket_path)
except Fail2BanConnectionError as exc:
raise _bad_gateway(exc) from exc
@@ -137,7 +138,7 @@ async def get_jail(
_auth: AuthDep,
name: _NamePath,
socket_path: Fail2BanSocketDep,
jail_service: JailServiceDep,
jail_service_dep: JailServiceDep,
) -> JailDetailResponse:
"""Return the complete configuration and runtime state for one jail.
@@ -157,7 +158,7 @@ async def get_jail(
HTTPException: 502 when fail2ban is unreachable.
"""
try:
return await jail_service.get_jail(socket_path, name)
return await jail_service_dep.get_jail(socket_path, name)
except JailNotFoundError:
raise _not_found(name) from None
except Fail2BanConnectionError as exc:
@@ -177,7 +178,7 @@ async def get_jail(
async def reload_all_jails(
_auth: AuthDep,
socket_path: Fail2BanSocketDep,
jail_service: JailServiceDep,
jail_service_dep: JailServiceDep,
) -> JailCommandResponse:
"""Reload every fail2ban jail to apply configuration changes.
@@ -195,7 +196,7 @@ async def reload_all_jails(
HTTPException: 409 when fail2ban reports the operation failed.
"""
try:
await jail_service.reload_all(socket_path)
await jail_service_dep.reload_all(socket_path)
return JailCommandResponse(message="All jails reloaded successfully.", jail="*")
except JailOperationError as exc:
raise _conflict(str(exc)) from exc
@@ -212,7 +213,7 @@ async def start_jail(
_auth: AuthDep,
name: _NamePath,
socket_path: Fail2BanSocketDep,
jail_service: JailServiceDep,
jail_service_dep: JailServiceDep,
) -> JailCommandResponse:
"""Start a fail2ban jail that is currently stopped.
@@ -229,7 +230,7 @@ async def start_jail(
HTTPException: 502 when fail2ban is unreachable.
"""
try:
await jail_service.start_jail(socket_path, name)
await jail_service_dep.start_jail(socket_path, name)
return JailCommandResponse(message=f"Jail {name!r} started.", jail=name)
except JailNotFoundError:
raise _not_found(name) from None
@@ -248,7 +249,7 @@ async def stop_jail(
_auth: AuthDep,
name: _NamePath,
socket_path: Fail2BanSocketDep,
jail_service: JailServiceDep,
jail_service_dep: JailServiceDep,
) -> JailCommandResponse:
"""Stop a running fail2ban jail.
@@ -268,7 +269,7 @@ async def stop_jail(
HTTPException: 502 when fail2ban is unreachable.
"""
try:
await jail_service.stop_jail(socket_path, name)
await jail_service_dep.stop_jail(socket_path, name)
return JailCommandResponse(message=f"Jail {name!r} stopped.", jail=name)
except JailOperationError as exc:
raise _conflict(str(exc)) from exc
@@ -285,7 +286,7 @@ async def toggle_idle(
_auth: AuthDep,
name: _NamePath,
socket_path: Fail2BanSocketDep,
jail_service: JailServiceDep,
jail_service_dep: JailServiceDep,
on: bool = Body(..., description="``true`` to enable idle, ``false`` to disable."),
) -> JailCommandResponse:
"""Enable or disable idle mode for a fail2ban jail.
@@ -308,7 +309,7 @@ async def toggle_idle(
"""
state_str = "on" if on else "off"
try:
await jail_service.set_idle(socket_path, name, on=on)
await jail_service_dep.set_idle(socket_path, name, on=on)
return JailCommandResponse(
message=f"Jail {name!r} idle mode turned {state_str}.",
jail=name,
@@ -330,7 +331,7 @@ async def reload_jail(
_auth: AuthDep,
name: _NamePath,
socket_path: Fail2BanSocketDep,
jail_service: JailServiceDep,
jail_service_dep: JailServiceDep,
) -> JailCommandResponse:
"""Reload a single fail2ban jail to pick up configuration changes.
@@ -347,7 +348,7 @@ async def reload_jail(
HTTPException: 502 when fail2ban is unreachable.
"""
try:
await jail_service.reload_jail(socket_path, name)
await jail_service_dep.reload_jail(socket_path, name)
return JailCommandResponse(message=f"Jail {name!r} reloaded.", jail=name)
except JailNotFoundError:
raise _not_found(name) from None
@@ -379,7 +380,7 @@ async def get_ignore_list(
_auth: AuthDep,
name: _NamePath,
socket_path: Fail2BanSocketDep,
jail_service: JailServiceDep,
jail_service_dep: JailServiceDep,
) -> list[str]:
"""Return the current ignore list (IP whitelist) for a fail2ban jail.
@@ -395,7 +396,7 @@ async def get_ignore_list(
HTTPException: 502 when fail2ban is unreachable.
"""
try:
return await jail_service.get_ignore_list(socket_path, name)
return await jail_service_dep.get_ignore_list(socket_path, name)
except JailNotFoundError:
raise _not_found(name) from None
except Fail2BanConnectionError as exc:
@@ -413,7 +414,7 @@ async def add_ignore_ip(
name: _NamePath,
body: IgnoreIpRequest,
socket_path: Fail2BanSocketDep,
jail_service: JailServiceDep,
jail_service_dep: JailServiceDep,
) -> JailCommandResponse:
"""Add an IP address or CIDR network to a jail's ignore list.
@@ -435,7 +436,7 @@ async def add_ignore_ip(
HTTPException: 502 when fail2ban is unreachable.
"""
try:
await jail_service.add_ignore_ip(socket_path, name, body.ip)
await jail_service_dep.add_ignore_ip(socket_path, name, body.ip)
return JailCommandResponse(
message=f"IP {body.ip!r} added to ignore list of jail {name!r}.",
jail=name,
@@ -463,7 +464,7 @@ async def del_ignore_ip(
name: _NamePath,
body: IgnoreIpRequest,
socket_path: Fail2BanSocketDep,
jail_service: JailServiceDep,
jail_service_dep: JailServiceDep,
) -> JailCommandResponse:
"""Remove an IP address or CIDR network from a jail's ignore list.
@@ -481,7 +482,7 @@ async def del_ignore_ip(
HTTPException: 502 when fail2ban is unreachable.
"""
try:
await jail_service.del_ignore_ip(socket_path, name, body.ip)
await jail_service_dep.del_ignore_ip(socket_path, name, body.ip)
return JailCommandResponse(
message=f"IP {body.ip!r} removed from ignore list of jail {name!r}.",
jail=name,
@@ -503,7 +504,7 @@ async def toggle_ignore_self(
_auth: AuthDep,
name: _NamePath,
socket_path: Fail2BanSocketDep,
jail_service: JailServiceDep,
jail_service_dep: JailServiceDep,
on: bool = Body(..., description="``true`` to enable ignoreself, ``false`` to disable."),
) -> JailCommandResponse:
"""Toggle the ``ignoreself`` flag for a fail2ban jail.
@@ -526,7 +527,7 @@ async def toggle_ignore_self(
"""
state_str = "enabled" if on else "disabled"
try:
await jail_service.set_ignore_self(socket_path, name, on=on)
await jail_service_dep.set_ignore_self(socket_path, name, on=on)
return JailCommandResponse(
message=f"ignoreself {state_str} for jail {name!r}.",
jail=name,
@@ -555,7 +556,8 @@ async def get_jail_banned_ips(
name: _NamePath,
socket_path: Fail2BanSocketDep,
http_session: HttpSessionDep,
jail_service: JailServiceDep,
jail_service_dep: JailServiceDep,
geo_batch_lookup: GeoBatchLookupDep,
page: int = 1,
page_size: int = 25,
search: str | None = None,
@@ -593,13 +595,13 @@ async def get_jail_banned_ips(
)
try:
return await jail_service.get_jail_banned_ips(
return await jail_service_dep.get_jail_banned_ips(
socket_path=socket_path,
jail_name=name,
page=page,
page_size=page_size,
search=search,
geo_batch_lookup=geo_service.lookup_batch,
geo_batch_lookup=geo_batch_lookup,
http_session=http_session,
app_db=db,
)