Migrate from file-based configs to database with per-IP site configuration
Major architectural changes: - Replace YAML config files with database-stored ScanConfig model - Remove CIDR block support in favor of individual IP addresses per site - Each IP now has its own expected_ping, expected_tcp_ports, expected_udp_ports - AlertRule now uses config_id FK instead of config_file string API changes: - POST /api/scans now requires config_id instead of config_file - Alert rules API uses config_id with validation - All config dropdowns fetch from /api/configs dynamically Template updates: - scans.html, dashboard.html, alert_rules.html load configs via API - Display format: Config Title (X sites) in dropdowns - Removed Jinja2 config_files loops Migrations: - 008: Expand CIDRs to individual IPs with per-IP port configs - 009: Remove CIDR-related columns - 010: Add config_id to alert_rules, remove config_file
This commit is contained in:
@@ -4,7 +4,7 @@ Pagination utilities for SneakyScanner web application.
|
||||
Provides helper functions for paginating SQLAlchemy queries.
|
||||
"""
|
||||
|
||||
from typing import Any, Dict, List
|
||||
from typing import Any, Callable, Dict, List, Optional
|
||||
from sqlalchemy.orm import Query
|
||||
|
||||
|
||||
@@ -114,6 +114,7 @@ class PaginatedResult:
|
||||
|
||||
|
||||
def paginate(query: Query, page: int = 1, per_page: int = 20,
|
||||
transform: Optional[Callable[[Any], Dict[str, Any]]] = None,
|
||||
max_per_page: int = 100) -> PaginatedResult:
|
||||
"""
|
||||
Paginate a SQLAlchemy query.
|
||||
@@ -122,6 +123,7 @@ def paginate(query: Query, page: int = 1, per_page: int = 20,
|
||||
query: SQLAlchemy query to paginate
|
||||
page: Page number (1-indexed, default: 1)
|
||||
per_page: Items per page (default: 20)
|
||||
transform: Optional function to transform each item (default: None)
|
||||
max_per_page: Maximum items per page (default: 100)
|
||||
|
||||
Returns:
|
||||
@@ -133,6 +135,11 @@ def paginate(query: Query, page: int = 1, per_page: int = 20,
|
||||
>>> result = paginate(query, page=1, per_page=20)
|
||||
>>> scans = result.items
|
||||
>>> total_pages = result.pages
|
||||
|
||||
>>> # With transform function
|
||||
>>> def scan_to_dict(scan):
|
||||
... return {'id': scan.id, 'name': scan.name}
|
||||
>>> result = paginate(query, page=1, per_page=20, transform=scan_to_dict)
|
||||
"""
|
||||
# Validate and sanitize parameters
|
||||
page = max(1, page) # Page must be at least 1
|
||||
@@ -147,6 +154,10 @@ def paginate(query: Query, page: int = 1, per_page: int = 20,
|
||||
# Execute query with limit and offset
|
||||
items = query.limit(per_page).offset(offset).all()
|
||||
|
||||
# Apply transform if provided
|
||||
if transform is not None:
|
||||
items = [transform(item) for item in items]
|
||||
|
||||
return PaginatedResult(
|
||||
items=items,
|
||||
total=total,
|
||||
|
||||
Reference in New Issue
Block a user