Skip to content

Commit 0e2b4b8

Browse files
authored
Merge pull request #577 from TS0713/admin_add_server_exception_update_fix
admin_add_server_exception_update_fix
2 parents 9a74f4f + e1ce4e9 commit 0e2b4b8

File tree

4 files changed

+38
-15
lines changed

4 files changed

+38
-15
lines changed

mcpgateway/admin.py

Lines changed: 4 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -435,12 +435,6 @@ async def admin_add_server(request: Request, db: Session = Depends(get_db), user
435435
except CoreValidationError as ex:
436436
return JSONResponse(content={"message": str(ex), "success": False}, status_code=422)
437437

438-
except ValidationError as ex:
439-
return JSONResponse(content={"message": str(ex), "success": False}, status_code=422)
440-
441-
except IntegrityError as ex:
442-
logger.error(f"Database error: {ex}")
443-
return JSONResponse(content={"message": f"Server already exists with name: {server.name}", "success": False}, status_code=409)
444438
except Exception as ex:
445439
if isinstance(ex, ServerError):
446440
# Custom server logic error — 500 Internal Server Error makes sense
@@ -456,11 +450,11 @@ async def admin_add_server(request: Request, db: Session = Depends(get_db), user
456450

457451
if isinstance(ex, ValidationError):
458452
# Pydantic or input validation failure — 422 Unprocessable Entity is correct
459-
return JSONResponse(content={"message": ErrorFormatter.format_validation_error(ex), "success": False}, status_code=422)
453+
return JSONResponse(content=ErrorFormatter.format_validation_error(ex), status_code=422)
460454

461455
if isinstance(ex, IntegrityError):
462456
# DB constraint violation — 409 Conflict is appropriate
463-
return JSONResponse(content={"message": ErrorFormatter.format_database_error(ex), "success": False}, status_code=409)
457+
return JSONResponse(content=ErrorFormatter.format_database_error(ex), status_code=409)
464458

465459
# For any other unhandled error, default to 500
466460
return JSONResponse(content={"message": str(ex), "success": False}, status_code=500)
@@ -2299,12 +2293,9 @@ async def admin_add_gateway(request: Request, db: Session = Depends(get_db), use
22992293
# Convert KeyError to ValidationError-like response
23002294
return JSONResponse(content={"message": f"Missing required field: {e}", "success": False}, status_code=422)
23012295

2302-
except ValueError as ex:
2296+
except ValidationError as ex:
23032297
# --- Getting only the custom message from the ValueError ---
2304-
error_ctx = []
2305-
logger.info(f" ALL -> {ex.errors()}")
2306-
for err in ex.errors():
2307-
error_ctx.append(str(err["ctx"]["error"]))
2298+
error_ctx = [str(err["ctx"]["error"]) for err in ex.errors()]
23082299
return JSONResponse(content={"success": False, "message": "; ".join(error_ctx)}, status_code=422)
23092300

23102301
try:

mcpgateway/config.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -490,7 +490,9 @@ def validate_database(self) -> None:
490490
db_dir.mkdir(parents=True)
491491

492492
# Validation patterns for safe display (configurable)
493-
validation_dangerous_html_pattern: str = r"<(script|iframe|object|embed|link|meta|base|form|img|svg|video|audio|source|track|area|map|canvas|applet|frame|frameset|html|head|body|style)\b|</*(script|iframe|object|embed|link|meta|base|form|img|svg|video|audio|source|track|area|map|canvas|applet|frame|frameset|html|head|body|style)>"
493+
validation_dangerous_html_pattern: str = (
494+
r"<(script|iframe|object|embed|link|meta|base|form|img|svg|video|audio|source|track|area|map|canvas|applet|frame|frameset|html|head|body|style)\b|</*(script|iframe|object|embed|link|meta|base|form|img|svg|video|audio|source|track|area|map|canvas|applet|frame|frameset|html|head|body|style)>"
495+
)
494496

495497
validation_dangerous_js_pattern: str = r"javascript:|vbscript:|on\w+\s*=|data:.*script"
496498
validation_allowed_url_schemes: List[str] = ["http://", "https://", "ws://", "wss://"]

mcpgateway/schemas.py

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1572,6 +1572,16 @@ class PromptInvocation(BaseModelWithConfigDict):
15721572

15731573
# --- Transport Type ---
15741574
class TransportType(str, Enum):
1575+
"""
1576+
Enumeration of supported transport mechanisms for communication between components.
1577+
1578+
Attributes:
1579+
SSE (str): Server-Sent Events transport.
1580+
HTTP (str): Standard HTTP-based transport.
1581+
STDIO (str): Standard input/output transport.
1582+
STREAMABLEHTTP (str): HTTP transport with streaming.
1583+
"""
1584+
15751585
SSE = "SSE"
15761586
HTTP = "HTTP"
15771587
STDIO = "STDIO"
@@ -1690,6 +1700,24 @@ def create_auth_value(cls, v, info):
16901700
@field_validator("transport")
16911701
@classmethod
16921702
def validate_transport(cls, v: str) -> str:
1703+
"""
1704+
Validates that the given transport value is one of the supported TransportType values.
1705+
1706+
Args:
1707+
v (str): The transport value to validate.
1708+
1709+
Returns:
1710+
str: The validated transport value if it is valid.
1711+
1712+
Raises:
1713+
ValueError: If the provided value is not a valid transport type.
1714+
1715+
Valid transport types are defined in the TransportType enum:
1716+
- SSE
1717+
- HTTP
1718+
- STDIO
1719+
- STREAMABLEHTTP
1720+
"""
16931721
if v not in [t.value for t in TransportType]:
16941722
raise ValueError(f"Invalid transport type: {v}. Must be one of: {', '.join([t.value for t in TransportType])}")
16951723
return v

mcpgateway/validators.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,9 @@ class SecurityValidator:
5252
"""Configurable validation with MCP-compliant limits"""
5353

5454
# Configurable patterns (from settings)
55-
DANGEROUS_HTML_PATTERN = settings.validation_dangerous_html_pattern # Default: '<(script|iframe|object|embed|link|meta|base|form|img|svg|video|audio|source|track|area|map|canvas|applet|frame|frameset|html|head|body|style)\b|</*(script|iframe|object|embed|link|meta|base|form|img|svg|video|audio|source|track|area|map|canvas|applet|frame|frameset|html|head|body|style)>'
55+
DANGEROUS_HTML_PATTERN = (
56+
settings.validation_dangerous_html_pattern
57+
) # Default: '<(script|iframe|object|embed|link|meta|base|form|img|svg|video|audio|source|track|area|map|canvas|applet|frame|frameset|html|head|body|style)\b|</*(script|iframe|object|embed|link|meta|base|form|img|svg|video|audio|source|track|area|map|canvas|applet|frame|frameset|html|head|body|style)>'
5658
DANGEROUS_JS_PATTERN = settings.validation_dangerous_js_pattern # Default: javascript:|vbscript:|on\w+\s*=|data:.*script
5759
ALLOWED_URL_SCHEMES = settings.validation_allowed_url_schemes # Default: ["http://", "https://", "ws://", "wss://"]
5860

0 commit comments

Comments
 (0)