Complete Phase 1: Foundation - Flask web application infrastructure

Implement complete database schema and Flask application structure for
SneakyScan web interface. This establishes the foundation for web-based
scan management, scheduling, and visualization.

Database & ORM:
- Add 11 SQLAlchemy models for comprehensive scan data storage
  (Scan, ScanSite, ScanIP, ScanPort, ScanService, ScanCertificate,
  ScanTLSVersion, Schedule, Alert, AlertRule, Setting)
- Configure Alembic migrations system with initial schema migration
- Add init_db.py script for database initialization and password setup
- Support both migration-based and direct table creation

Settings System:
- Implement SettingsManager with automatic encryption for sensitive values
- Add Fernet encryption for SMTP passwords and API tokens
- Implement PasswordManager with bcrypt password hashing (work factor 12)
- Initialize default settings for SMTP, authentication, and retention

Flask Application:
- Create Flask app factory pattern with scoped session management
- Add 4 API blueprints: scans, schedules, alerts, settings
- Implement functional Settings API (GET/PUT/DELETE endpoints)
- Add CORS support, error handlers, and request/response logging
- Configure development and production logging to file and console

Docker & Deployment:
- Update Dockerfile to install Flask dependencies
- Add docker-compose-web.yml for web application deployment
- Configure volume mounts for database, output, and logs persistence
- Expose port 5000 for Flask web server

Testing & Validation:
- Add validate_phase1.py script to verify all deliverables
- Validate directory structure, Python syntax, models, and endpoints
- All validation checks passing

Documentation:
- Add PHASE1_COMPLETE.md with comprehensive Phase 1 summary
- Update ROADMAP.md with Phase 1 completion status
- Update .gitignore to exclude database files and documentation

Files changed: 21 files
- New: web/ directory with complete Flask app structure
- New: migrations/ with Alembic configuration
- New: requirements-web.txt with Flask dependencies
- Modified: Dockerfile, ROADMAP.md, .gitignore
This commit is contained in:
2025-11-13 23:59:23 -06:00
parent e29c839d80
commit 986c0d3d17
22 changed files with 3138 additions and 42 deletions

150
web/api/scans.py Normal file
View File

@@ -0,0 +1,150 @@
"""
Scans API blueprint.
Handles endpoints for triggering scans, listing scan history, and retrieving
scan results.
"""
from flask import Blueprint, current_app, jsonify, request
bp = Blueprint('scans', __name__)
@bp.route('', methods=['GET'])
def list_scans():
"""
List all scans with pagination.
Query params:
page: Page number (default: 1)
per_page: Items per page (default: 20, max: 100)
status: Filter by status (running, completed, failed)
Returns:
JSON response with scans list and pagination info
"""
# TODO: Implement in Phase 2
return jsonify({
'scans': [],
'total': 0,
'page': 1,
'per_page': 20,
'message': 'Scans endpoint - to be implemented in Phase 2'
})
@bp.route('/<int:scan_id>', methods=['GET'])
def get_scan(scan_id):
"""
Get details for a specific scan.
Args:
scan_id: Scan ID
Returns:
JSON response with scan details
"""
# TODO: Implement in Phase 2
return jsonify({
'scan_id': scan_id,
'message': 'Scan detail endpoint - to be implemented in Phase 2'
})
@bp.route('', methods=['POST'])
def trigger_scan():
"""
Trigger a new scan.
Request body:
config_file: Path to YAML config file
Returns:
JSON response with scan_id and status
"""
# TODO: Implement in Phase 2
data = request.get_json() or {}
config_file = data.get('config_file')
return jsonify({
'scan_id': None,
'status': 'not_implemented',
'message': 'Scan trigger endpoint - to be implemented in Phase 2',
'config_file': config_file
}), 501 # Not Implemented
@bp.route('/<int:scan_id>', methods=['DELETE'])
def delete_scan(scan_id):
"""
Delete a scan and its associated files.
Args:
scan_id: Scan ID to delete
Returns:
JSON response with deletion status
"""
# TODO: Implement in Phase 2
return jsonify({
'scan_id': scan_id,
'status': 'not_implemented',
'message': 'Scan deletion endpoint - to be implemented in Phase 2'
}), 501
@bp.route('/<int:scan_id>/status', methods=['GET'])
def get_scan_status(scan_id):
"""
Get current status of a running scan.
Args:
scan_id: Scan ID
Returns:
JSON response with scan status and progress
"""
# TODO: Implement in Phase 2
return jsonify({
'scan_id': scan_id,
'status': 'not_implemented',
'progress': '0%',
'message': 'Scan status endpoint - to be implemented in Phase 2'
})
@bp.route('/<int:scan_id1>/compare/<int:scan_id2>', methods=['GET'])
def compare_scans(scan_id1, scan_id2):
"""
Compare two scans and show differences.
Args:
scan_id1: First scan ID
scan_id2: Second scan ID
Returns:
JSON response with comparison results
"""
# TODO: Implement in Phase 4
return jsonify({
'scan_id1': scan_id1,
'scan_id2': scan_id2,
'diff': {},
'message': 'Scan comparison endpoint - to be implemented in Phase 4'
})
# Health check endpoint
@bp.route('/health', methods=['GET'])
def health_check():
"""
Health check endpoint for monitoring.
Returns:
JSON response with API health status
"""
return jsonify({
'status': 'healthy',
'api': 'scans',
'version': '1.0.0-phase1'
})