Files
ServerKit/backend/app/api/ssl.py
T
Juan Denis 06d63cbc52 Add standalone WordPress and SSL management UI
Implements backend endpoints and service logic for managing standalone WordPress via Docker, including install, uninstall, start, stop, and restart. Adds Nginx integration for WordPress at /wordpress. Introduces a new frontend page for SSL certificate management with Certbot install, obtain, renew, and revoke actions. Updates the WordPress frontend page to support one-click install, status, and lifecycle management. Updates documentation and install instructions for improved clarity.
2026-01-25 22:48:12 -05:00

146 lines
4.2 KiB
Python

from flask import Blueprint, request, jsonify
from flask_jwt_extended import jwt_required, get_jwt_identity
from app.models import User
from app.services.ssl_service import SSLService
ssl_bp = Blueprint('ssl', __name__)
def admin_required(fn):
"""Decorator to require admin role."""
from functools import wraps
@wraps(fn)
def wrapper(*args, **kwargs):
current_user_id = get_jwt_identity()
user = User.query.get(current_user_id)
if not user or user.role != 'admin':
return jsonify({'error': 'Admin access required'}), 403
return fn(*args, **kwargs)
return wrapper
@ssl_bp.route('/certificates', methods=['GET'])
@jwt_required()
@admin_required
def list_certificates():
"""List all SSL certificates."""
certificates = SSLService.list_certificates()
return jsonify({'certificates': certificates}), 200
@ssl_bp.route('/certificates/<domain>', methods=['GET'])
@jwt_required()
@admin_required
def get_certificate(domain):
"""Get details for a specific certificate."""
info = SSLService.get_certificate_info(domain)
if info:
return jsonify({'certificate': info}), 200
return jsonify({'error': 'Certificate not found'}), 404
@ssl_bp.route('/certificates', methods=['POST'])
@jwt_required()
@admin_required
def obtain_certificate():
"""Obtain a new SSL certificate from Let's Encrypt."""
data = request.get_json()
if not data:
return jsonify({'error': 'No data provided'}), 400
domains = data.get('domains')
email = data.get('email')
if not domains or not email:
return jsonify({'error': 'domains and email are required'}), 400
result = SSLService.obtain_certificate(
domains=domains,
email=email,
webroot_path=data.get('webroot_path'),
use_nginx=data.get('use_nginx', True)
)
return jsonify(result), 201 if result['success'] else 400
@ssl_bp.route('/certificates/<domain>/renew', methods=['POST'])
@jwt_required()
@admin_required
def renew_certificate(domain):
"""Renew a specific certificate."""
result = SSLService.renew_certificate(domain)
return jsonify(result), 200 if result['success'] else 400
@ssl_bp.route('/certificates/renew-all', methods=['POST'])
@jwt_required()
@admin_required
def renew_all_certificates():
"""Renew all certificates that need renewal."""
result = SSLService.renew_certificate()
return jsonify(result), 200 if result['success'] else 400
@ssl_bp.route('/certificates/<domain>', methods=['DELETE'])
@jwt_required()
@admin_required
def revoke_certificate(domain):
"""Revoke and delete a certificate."""
result = SSLService.revoke_certificate(domain)
return jsonify(result), 200 if result['success'] else 400
@ssl_bp.route('/certificates/<domain>/check', methods=['GET'])
@jwt_required()
@admin_required
def check_certificate_expiry(domain):
"""Check if a certificate is expiring soon."""
result = SSLService.check_expiry(domain)
return jsonify(result), 200
@ssl_bp.route('/auto-renewal', methods=['POST'])
@jwt_required()
@admin_required
def setup_auto_renewal():
"""Set up automatic certificate renewal."""
result = SSLService.setup_auto_renewal()
return jsonify(result), 200 if result['success'] else 400
@ssl_bp.route('/install-certbot', methods=['POST'])
@jwt_required()
@admin_required
def install_certbot():
"""Install certbot if not already installed."""
if SSLService.is_certbot_installed():
return jsonify({'success': True, 'message': 'Certbot is already installed'}), 200
result = SSLService.install_certbot()
return jsonify(result), 200 if result['success'] else 400
@ssl_bp.route('/status', methods=['GET'])
@jwt_required()
@admin_required
def get_ssl_status():
"""Get overall SSL status."""
is_installed = SSLService.is_certbot_installed()
certificates = SSLService.list_certificates()
expiring_soon = []
for cert in certificates:
check = SSLService.check_expiry(cert['name'])
if check.get('expiring_soon'):
expiring_soon.append(cert['name'])
return jsonify({
'certbot_installed': is_installed,
'total_certificates': len(certificates),
'expiring_soon': expiring_soon,
'certificates': certificates
}), 200