mirror of
https://github.com/apidoorman/doorman.git
synced 2026-02-09 02:29:42 -06:00
additional tests and fix
This commit is contained in:
@@ -1,8 +1,12 @@
|
||||
import os
|
||||
import sys
|
||||
import time
|
||||
import pytest
|
||||
import requests
|
||||
|
||||
# Ensure backend packages are importable when running from live-tests dir
|
||||
sys.path.insert(0, os.path.abspath(os.path.join(os.path.dirname(__file__), '..')))
|
||||
|
||||
from config import BASE_URL, ADMIN_EMAIL, ADMIN_PASSWORD, require_env, STRICT_HEALTH
|
||||
from client import LiveClient
|
||||
|
||||
|
||||
@@ -173,16 +173,36 @@ async def gateway(request: Request, path: str):
|
||||
parts = [p for p in (path or '').split('/') if p]
|
||||
api_public = False
|
||||
api_auth_required = True
|
||||
resolved_api = None
|
||||
if len(parts) >= 2 and parts[1].startswith('v') and parts[1][1:].isdigit():
|
||||
api_key = doorman_cache.get_cache('api_id_cache', f'/{parts[0]}/{parts[1]}')
|
||||
api = await api_util.get_api(api_key, f'/{parts[0]}/{parts[1]}')
|
||||
api_public = bool(api.get('api_public')) if api else False
|
||||
api_auth_required = bool(api.get('api_auth_required')) if api and api.get('api_auth_required') is not None else True
|
||||
if api:
|
||||
resolved_api = await api_util.get_api(api_key, f'/{parts[0]}/{parts[1]}')
|
||||
# Early endpoint existence check to return 404 before auth when missing
|
||||
if resolved_api:
|
||||
try:
|
||||
enforce_api_ip_policy(request, api)
|
||||
# Enforce per-API IP policy first
|
||||
enforce_api_ip_policy(request, resolved_api)
|
||||
except HTTPException as e:
|
||||
return process_response(ResponseModel(status_code=e.status_code, error_code=e.detail, error_message='IP restricted').dict(), 'rest')
|
||||
# Build endpoint URI and verify it exists for this API/method
|
||||
endpoint_uri = '/' + '/'.join(parts[2:]) if len(parts) > 2 else '/'
|
||||
try:
|
||||
endpoints = await api_util.get_api_endpoints(resolved_api.get('api_id'))
|
||||
import re as _re
|
||||
regex_pattern = _re.compile(r'\{[^/]+\}')
|
||||
composite = request.method + endpoint_uri
|
||||
if not any(_re.fullmatch(regex_pattern.sub(r'([^/]+)', ep), composite) for ep in (endpoints or [])):
|
||||
return process_response(ResponseModel(
|
||||
status_code=404,
|
||||
response_headers={'request_id': request_id},
|
||||
error_code='GTW003',
|
||||
error_message='Endpoint does not exist for the requested API'
|
||||
).dict(), 'rest')
|
||||
except Exception:
|
||||
# If endpoint introspection fails, fall through to service handler
|
||||
pass
|
||||
api_public = bool(resolved_api.get('api_public')) if resolved_api else False
|
||||
api_auth_required = bool(resolved_api.get('api_auth_required')) if resolved_api and resolved_api.get('api_auth_required') is not None else True
|
||||
username = None
|
||||
if not api_public:
|
||||
if api_auth_required:
|
||||
|
||||
@@ -77,11 +77,12 @@ async def memory_dump(request: Request, body: Optional[DumpRequest] = None):
|
||||
if body and body.path:
|
||||
path = body.path
|
||||
dump_path = dump_memory_to_file(path)
|
||||
# Wrap under 'response' key so clients/tests see a consistent envelope
|
||||
return process_response(ResponseModel(
|
||||
status_code=200,
|
||||
response_headers={'request_id': request_id},
|
||||
message='Memory dump created successfully',
|
||||
response={'path': dump_path}
|
||||
response={'response': {'path': dump_path}}
|
||||
).dict(), 'rest')
|
||||
except Exception as e:
|
||||
logger.critical(f'{request_id} | Unexpected error: {str(e)}', exc_info=True)
|
||||
@@ -150,11 +151,12 @@ async def memory_restore(request: Request, body: Optional[RestoreRequest] = None
|
||||
if body and body.path:
|
||||
path = body.path
|
||||
info = restore_memory_from_file(path)
|
||||
# Wrap under 'response' key for consistency with dump
|
||||
return process_response(ResponseModel(
|
||||
status_code=200,
|
||||
response_headers={'request_id': request_id},
|
||||
message='Memory restore completed',
|
||||
response=info
|
||||
response={'response': info}
|
||||
).dict(), 'rest')
|
||||
except FileNotFoundError as e:
|
||||
return process_response(ResponseModel(
|
||||
|
||||
@@ -188,6 +188,12 @@ class EndpointService:
|
||||
error_message='Unable to delete endpoint'
|
||||
).dict()
|
||||
doorman_cache.delete_cache('endpoint_cache', cache_key)
|
||||
try:
|
||||
api_id = endpoint.get('api_id') if isinstance(endpoint, dict) else None
|
||||
if api_id:
|
||||
doorman_cache.delete_cache('api_endpoint_cache', api_id)
|
||||
except Exception:
|
||||
pass
|
||||
logger.info(request_id + ' | Endpoint deletion successful')
|
||||
return ResponseModel(
|
||||
status_code=200,
|
||||
|
||||
Reference in New Issue
Block a user