| """ |
| Services management views for the control panel. |
| """ |
|
|
| import json |
| import logging |
|
|
| from django.shortcuts import render, redirect |
| from django.contrib.auth.decorators import login_required, user_passes_test |
| from django.contrib import messages |
| from django.views.decorators.http import require_POST |
| from django.http import HttpRequest, HttpResponse, JsonResponse |
|
|
| from core.models import GlobalSettings |
| from core.forms import S3SettingsForm |
| from core.services.s3_service import S3Service |
| from core.services.encryption_service import EncryptionService |
|
|
| logger = logging.getLogger(__name__) |
|
|
|
|
| def superuser_required(view_func): |
| """Decorator to require superuser status for S3 configuration.""" |
| return user_passes_test(lambda u: u.is_superuser, login_url="auth:login")(view_func) |
|
|
|
|
| @login_required |
| @superuser_required |
| def services_view(request: HttpRequest) -> HttpResponse: |
| """Display services configuration page.""" |
| settings = GlobalSettings.get_settings() |
| s3_form = S3SettingsForm(instance=settings) |
| s3_status = S3Service.get_status() |
|
|
| return render( |
| request, |
| "cpanel/services/list.html", |
| { |
| "settings": settings, |
| "s3_form": s3_form, |
| "s3_status": s3_status, |
| }, |
| ) |
|
|
|
|
| @login_required |
| @superuser_required |
| @require_POST |
| def s3_settings_view(request: HttpRequest) -> HttpResponse: |
| """Update S3 storage settings.""" |
| settings = GlobalSettings.get_settings() |
| form = S3SettingsForm(request.POST, instance=settings) |
|
|
| if form.is_valid(): |
| form.save(settings) |
| messages.success(request, "S3 storage settings saved successfully.") |
| else: |
| for field, errors in form.errors.items(): |
| for error in errors: |
| messages.error(request, f"{field}: {error}") |
|
|
| return redirect("cpanel:services") |
|
|
|
|
| @login_required |
| @superuser_required |
| @require_POST |
| def s3_test_connection_view(request: HttpRequest) -> JsonResponse: |
| """Test S3 connection and return result. |
| |
| Accepts form data in POST body to test credentials before saving. |
| Falls back to saved settings if no form data provided. |
| """ |
| try: |
| |
| data = {} |
| if request.body: |
| try: |
| data = json.loads(request.body) |
| except json.JSONDecodeError: |
| return JsonResponse( |
| {"success": False, "error": "Invalid JSON in request body"}, |
| status=400, |
| ) |
|
|
| if data: |
| |
| settings = GlobalSettings.get_settings() |
|
|
| |
| access_key = data.get("s3_access_key", "") |
| if not access_key and settings.s3_access_key_encrypted: |
| access_key = EncryptionService.decrypt(settings.s3_access_key_encrypted) |
|
|
| secret_key = data.get("s3_secret_key", "") |
| if not secret_key and settings.s3_secret_key_encrypted: |
| secret_key = EncryptionService.decrypt(settings.s3_secret_key_encrypted) |
|
|
| success, message = S3Service.test_connection_with_credentials( |
| bucket_name=data.get("s3_bucket_name", ""), |
| access_key=access_key, |
| secret_key=secret_key, |
| endpoint_url=data.get("s3_endpoint_url", ""), |
| region=data.get("s3_region", "us-east-1"), |
| use_ssl=data.get("s3_use_ssl", True), |
| path_style=data.get("s3_path_style", False), |
| ) |
| else: |
| |
| success, message = S3Service.test_connection() |
|
|
| return JsonResponse( |
| { |
| "success": success, |
| "message": message if success else None, |
| "error": message if not success else None, |
| } |
| ) |
| except Exception as e: |
| logger.exception("S3 connection test failed") |
| return JsonResponse( |
| { |
| "success": False, |
| "error": str(e), |
| } |
| ) |
|
|