|
@@ -2,11 +2,11 @@
|
|
|
Admin service for handling administrative operations.
|
|
Admin service for handling administrative operations.
|
|
|
"""
|
|
"""
|
|
|
import logging
|
|
import logging
|
|
|
-from typing import Optional, List
|
|
|
|
|
|
|
+from typing import List
|
|
|
|
|
|
|
|
-from fastapi import Request
|
|
|
|
|
|
|
+from fastapi import Depends, Request
|
|
|
|
|
+from web.core.config import get_settings, Settings
|
|
|
|
|
|
|
|
-from core.config import get_settings
|
|
|
|
|
|
|
|
|
|
logger = logging.getLogger(__name__)
|
|
logger = logging.getLogger(__name__)
|
|
|
|
|
|
|
@@ -14,66 +14,31 @@ logger = logging.getLogger(__name__)
|
|
|
class AdminService:
|
|
class AdminService:
|
|
|
"""Service for managing administrative operations."""
|
|
"""Service for managing administrative operations."""
|
|
|
|
|
|
|
|
- def __init__(self, versions_fetcher=None):
|
|
|
|
|
|
|
+ def __init__(self, remote_reload_token: str, versions_fetcher=None):
|
|
|
"""
|
|
"""
|
|
|
Initialize the admin service.
|
|
Initialize the admin service.
|
|
|
|
|
|
|
|
Args:
|
|
Args:
|
|
|
|
|
+ remote_reload_token: Remote reload authentication token
|
|
|
versions_fetcher: VersionsFetcher instance for managing remotes
|
|
versions_fetcher: VersionsFetcher instance for managing remotes
|
|
|
"""
|
|
"""
|
|
|
|
|
+ self.remote_reload_token = remote_reload_token
|
|
|
self.versions_fetcher = versions_fetcher
|
|
self.versions_fetcher = versions_fetcher
|
|
|
- self.settings = get_settings()
|
|
|
|
|
|
|
|
|
|
- def get_auth_token(self) -> Optional[str]:
|
|
|
|
|
|
|
+ async def verify_remote_reload_token(self, token: str) -> bool:
|
|
|
"""
|
|
"""
|
|
|
- Retrieve the authorization token from file or environment.
|
|
|
|
|
-
|
|
|
|
|
- Returns:
|
|
|
|
|
- The authorization token if found, None otherwise
|
|
|
|
|
- """
|
|
|
|
|
- try:
|
|
|
|
|
- # Try to read the secret token from the file
|
|
|
|
|
- token_file_path = self.settings.admin_token_file_path
|
|
|
|
|
- with open(token_file_path, 'r') as file:
|
|
|
|
|
- token = file.read().strip()
|
|
|
|
|
- return token
|
|
|
|
|
- except (FileNotFoundError, PermissionError) as e:
|
|
|
|
|
- logger.error(
|
|
|
|
|
- f"Couldn't open token file at "
|
|
|
|
|
- f"{self.settings.admin_token_file_path}: {e}. "
|
|
|
|
|
- "Checking environment for token."
|
|
|
|
|
- )
|
|
|
|
|
- # If the file does not exist or no permission, check environment
|
|
|
|
|
- return self.settings.admin_token_env
|
|
|
|
|
- except Exception as e:
|
|
|
|
|
- logger.error(
|
|
|
|
|
- f"Unexpected error reading token file at "
|
|
|
|
|
- f"{self.settings.admin_token_file_path}: {e}. "
|
|
|
|
|
- "Checking environment for token."
|
|
|
|
|
- )
|
|
|
|
|
- # For any other error, fall back to environment variable
|
|
|
|
|
- return self.settings.admin_token_env
|
|
|
|
|
-
|
|
|
|
|
- async def verify_token(self, token: str) -> bool:
|
|
|
|
|
- """
|
|
|
|
|
- Verify that the provided token matches the expected admin token.
|
|
|
|
|
|
|
+ Verify that the provided token matches the expected remote reload token.
|
|
|
|
|
|
|
|
Args:
|
|
Args:
|
|
|
token: The token to verify
|
|
token: The token to verify
|
|
|
|
|
|
|
|
Returns:
|
|
Returns:
|
|
|
True if token is valid, False otherwise
|
|
True if token is valid, False otherwise
|
|
|
-
|
|
|
|
|
- Raises:
|
|
|
|
|
- RuntimeError: If admin token is not configured on server
|
|
|
|
|
"""
|
|
"""
|
|
|
- expected_token = self.get_auth_token()
|
|
|
|
|
-
|
|
|
|
|
- if expected_token is None:
|
|
|
|
|
- logger.error("No admin token configured")
|
|
|
|
|
- raise RuntimeError("Admin token not configured on server")
|
|
|
|
|
|
|
+ if not token:
|
|
|
|
|
+ return False
|
|
|
|
|
|
|
|
- return token == expected_token
|
|
|
|
|
|
|
+ return token == self.remote_reload_token
|
|
|
|
|
|
|
|
async def refresh_remotes(self) -> List[str]:
|
|
async def refresh_remotes(self) -> List[str]:
|
|
|
"""
|
|
"""
|
|
@@ -102,14 +67,29 @@ class AdminService:
|
|
|
return remotes_refreshed
|
|
return remotes_refreshed
|
|
|
|
|
|
|
|
|
|
|
|
|
-def get_admin_service(request: Request) -> AdminService:
|
|
|
|
|
|
|
+def get_admin_service(
|
|
|
|
|
+ request: Request,
|
|
|
|
|
+ settings: Settings = Depends(get_settings)
|
|
|
|
|
+) -> AdminService:
|
|
|
"""
|
|
"""
|
|
|
Get AdminService instance with dependencies from app state.
|
|
Get AdminService instance with dependencies from app state.
|
|
|
|
|
|
|
|
Args:
|
|
Args:
|
|
|
request: FastAPI Request object
|
|
request: FastAPI Request object
|
|
|
|
|
+ settings: Application settings
|
|
|
|
|
|
|
|
Returns:
|
|
Returns:
|
|
|
AdminService instance initialized with app state dependencies
|
|
AdminService instance initialized with app state dependencies
|
|
|
|
|
+
|
|
|
|
|
+ Raises:
|
|
|
|
|
+ RuntimeError: If remote reload token is not configured
|
|
|
"""
|
|
"""
|
|
|
- return AdminService(versions_fetcher=request.app.state.versions_fetcher)
|
|
|
|
|
|
|
+ remote_reload_token = settings.remote_reload_token
|
|
|
|
|
+
|
|
|
|
|
+ if remote_reload_token is None:
|
|
|
|
|
+ raise RuntimeError("Remote reload token not configured on server")
|
|
|
|
|
+
|
|
|
|
|
+ return AdminService(
|
|
|
|
|
+ remote_reload_token=remote_reload_token,
|
|
|
|
|
+ versions_fetcher=request.app.state.versions_fetcher
|
|
|
|
|
+ )
|