Source code for mud_server.admin_gradio.api.settings

"""
Settings API client for MUD Server.

This module handles user settings and server management operations:
- Password changes
- Server control (stop server)

All functions follow a consistent pattern:
    - Validate session state and permissions
    - Validate input
    - Make API request using BaseAPIClient
    - Return standardized response dictionaries

Response Format:
    All functions return dictionaries with:
    {
        "success": bool,         # Whether operation succeeded
        "message": str,          # User-facing message
        "data": None,
        "error": str | None,     # Error details if failed
    }
"""

from mud_server.admin_gradio.api.base import BaseAPIClient
from mud_server.admin_gradio.ui.validators import (
    validate_admin_role,
    validate_password,
    validate_password_confirmation,
    validate_password_different,
    validate_required_field,
    validate_session_state,
)


[docs] class SettingsAPIClient(BaseAPIClient): """ API client for settings and server management operations. This client handles password changes and server control operations. Example: >>> client = SettingsAPIClient() >>> result = client.change_password( ... session_id="abc123", ... old_password="old123", ... new_password="new456", ... confirm_password="new456" ... ) >>> if result["success"]: ... print("Password changed successfully") """
[docs] def change_password( self, session_id: str | None, old_password: str, new_password: str, confirm_password: str, ) -> dict: """ Change the current user's password. Validates passwords, sends change request to backend, and returns confirmation or error message. Args: session_id: User's session ID from login old_password: Current password (for verification) new_password: Desired new password confirm_password: New password confirmation Returns: Dictionary with structure: { "success": bool, "message": str, "data": None, "error": str | None, } Examples: >>> client = SettingsAPIClient() >>> result = client.change_password( ... session_id="abc123", ... old_password="old123", ... new_password="new456789", ... confirm_password="new456789" ... ) >>> result["success"] True """ # Validate session session_state = {"logged_in": bool(session_id)} is_valid, error = validate_session_state(session_state) if not is_valid: return { "success": False, "message": error, "data": None, "error": error, } # Validate old password is provided is_valid, error = validate_required_field(old_password, "current password") if not is_valid: return { "success": False, "message": error, "data": None, "error": error, } # Validate new password meets requirements is_valid, error = validate_password(new_password) if not is_valid: return { "success": False, "message": "New password must be at least 8 characters.", "data": None, "error": error, } # Validate new passwords match is_valid, error = validate_password_confirmation(new_password, confirm_password) if not is_valid: return { "success": False, "message": "New passwords do not match.", "data": None, "error": error, } # Validate new password is different from old is_valid, error = validate_password_different(old_password, new_password) if not is_valid: return { "success": False, "message": error, "data": None, "error": error, } # Make API request response = self.post( "/change-password", json={ "session_id": session_id, "old_password": old_password, "new_password": new_password, }, ) if response["success"]: data = response["data"] return { "success": True, "message": f"✅ {data['message']}", "data": None, "error": None, } else: return { "success": False, "message": f"❌ {response['error']}", "data": None, "error": response["error"], }
[docs] def stop_server( self, session_id: str | None, role: str, ) -> dict: """ Stop the backend server (Admin/Superuser only). This operation requires admin or superuser permissions. The server will shut down gracefully after responding to this request. Args: session_id: User's session ID from login role: User's role (for permission checking) Returns: Dictionary with structure: { "success": bool, "message": str, "data": None, "error": str | None, } Examples: >>> client = SettingsAPIClient() >>> result = client.stop_server(session_id="abc123", role="admin") >>> if result["success"]: ... print("Server shutting down") """ # Validate session session_state = {"logged_in": bool(session_id), "role": role} is_valid, error = validate_session_state(session_state) if not is_valid: return { "success": False, "message": error, "data": None, "error": error, } # Validate admin role is_valid, error = validate_admin_role(session_state) if not is_valid: return { "success": False, "message": error, "data": None, "error": error, } # Make API request response = self.post( "/admin/server/stop", json={"session_id": session_id}, ) if response["success"]: data = response["data"] return { "success": True, "message": f"✅ {data['message']}", "data": None, "error": None, } elif response["status_code"] == 403: return { "success": False, "message": "Access Denied: Insufficient permissions.", "data": None, "error": "Insufficient permissions", } else: # Server might be stopped or unreachable after this call error_msg = response["error"] if "Cannot connect to server" in error_msg or response["status_code"] == 0: return { "success": True, # Consider this success - server stopped "message": f"Server stopped or cannot connect to {self.server_url}", "data": None, "error": None, } return { "success": False, "message": f"❌ {error_msg}", "data": None, "error": error_msg, }