mcp-security-framework 0.1.0__py3-none-any.whl → 1.1.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- mcp_security_framework/core/auth_manager.py +12 -2
- mcp_security_framework/core/cert_manager.py +247 -16
- mcp_security_framework/core/permission_manager.py +4 -0
- mcp_security_framework/core/rate_limiter.py +10 -0
- mcp_security_framework/core/security_manager.py +2 -0
- mcp_security_framework/examples/comprehensive_example.py +884 -0
- mcp_security_framework/examples/django_example.py +45 -12
- mcp_security_framework/examples/fastapi_example.py +826 -354
- mcp_security_framework/examples/flask_example.py +51 -11
- mcp_security_framework/examples/gateway_example.py +109 -17
- mcp_security_framework/examples/microservice_example.py +112 -16
- mcp_security_framework/examples/standalone_example.py +646 -430
- mcp_security_framework/examples/test_all_examples.py +556 -0
- mcp_security_framework/middleware/auth_middleware.py +1 -1
- mcp_security_framework/middleware/fastapi_auth_middleware.py +82 -14
- mcp_security_framework/middleware/flask_auth_middleware.py +154 -7
- mcp_security_framework/schemas/models.py +1 -0
- mcp_security_framework/utils/cert_utils.py +5 -5
- {mcp_security_framework-0.1.0.dist-info → mcp_security_framework-1.1.0.dist-info}/METADATA +1 -1
- {mcp_security_framework-0.1.0.dist-info → mcp_security_framework-1.1.0.dist-info}/RECORD +38 -32
- tests/conftest.py +306 -0
- tests/test_cli/test_cert_cli.py +13 -31
- tests/test_core/test_cert_manager.py +12 -12
- tests/test_examples/test_comprehensive_example.py +560 -0
- tests/test_examples/test_fastapi_example.py +214 -116
- tests/test_examples/test_flask_example.py +250 -131
- tests/test_examples/test_standalone_example.py +44 -99
- tests/test_integration/test_auth_flow.py +4 -4
- tests/test_integration/test_certificate_flow.py +1 -1
- tests/test_integration/test_fastapi_integration.py +39 -45
- tests/test_integration/test_flask_integration.py +4 -2
- tests/test_integration/test_standalone_integration.py +48 -48
- tests/test_middleware/test_fastapi_auth_middleware.py +724 -0
- tests/test_middleware/test_flask_auth_middleware.py +638 -0
- tests/test_middleware/test_security_middleware.py +9 -3
- {mcp_security_framework-0.1.0.dist-info → mcp_security_framework-1.1.0.dist-info}/WHEEL +0 -0
- {mcp_security_framework-0.1.0.dist-info → mcp_security_framework-1.1.0.dist-info}/entry_points.txt +0 -0
- {mcp_security_framework-0.1.0.dist-info → mcp_security_framework-1.1.0.dist-info}/top_level.txt +0 -0
@@ -28,7 +28,7 @@ Last Modified: 2024-01-20
|
|
28
28
|
|
29
29
|
import json
|
30
30
|
import logging
|
31
|
-
from typing import Any, Dict, Optional
|
31
|
+
from typing import Any, Dict, Optional, List
|
32
32
|
|
33
33
|
from fastapi import Request, Response, status
|
34
34
|
from fastapi.responses import JSONResponse
|
@@ -67,15 +67,14 @@ class FastAPIAuthMiddleware(AuthMiddleware):
|
|
67
67
|
AuthMiddlewareError: When authentication processing fails
|
68
68
|
"""
|
69
69
|
|
70
|
-
def __init__(self,
|
70
|
+
def __init__(self, security_manager: Any):
|
71
71
|
"""
|
72
72
|
Initialize FastAPI Authentication Middleware.
|
73
73
|
|
74
74
|
Args:
|
75
|
-
config (SecurityConfig): Security configuration settings
|
76
75
|
security_manager: Security manager instance
|
77
76
|
"""
|
78
|
-
super().__init__(
|
77
|
+
super().__init__(security_manager)
|
79
78
|
self.logger = logging.getLogger(__name__)
|
80
79
|
|
81
80
|
async def __call__(self, request: Request, call_next: Any) -> Response:
|
@@ -102,7 +101,7 @@ class FastAPIAuthMiddleware(AuthMiddleware):
|
|
102
101
|
return await call_next(request)
|
103
102
|
|
104
103
|
# Perform authentication
|
105
|
-
auth_result =
|
104
|
+
auth_result = self._authenticate_only(request)
|
106
105
|
|
107
106
|
if not auth_result.is_valid:
|
108
107
|
return self._auth_error_response(auth_result)
|
@@ -209,7 +208,7 @@ class FastAPIAuthMiddleware(AuthMiddleware):
|
|
209
208
|
user_agent = request.headers.get("User-Agent", "")
|
210
209
|
return f"auth:{ip}:{hash(user_agent)}"
|
211
210
|
|
212
|
-
|
211
|
+
def _try_auth_method(self, request: Request, method: str) -> AuthResult:
|
213
212
|
"""
|
214
213
|
Try authentication using specific method with FastAPI request.
|
215
214
|
|
@@ -222,13 +221,13 @@ class FastAPIAuthMiddleware(AuthMiddleware):
|
|
222
221
|
"""
|
223
222
|
try:
|
224
223
|
if method == "api_key":
|
225
|
-
return
|
224
|
+
return self._try_api_key_auth(request)
|
226
225
|
elif method == "jwt":
|
227
|
-
return
|
226
|
+
return self._try_jwt_auth(request)
|
228
227
|
elif method == "certificate":
|
229
|
-
return
|
228
|
+
return self._try_certificate_auth(request)
|
230
229
|
elif method == "basic":
|
231
|
-
return
|
230
|
+
return self._try_basic_auth(request)
|
232
231
|
else:
|
233
232
|
return AuthResult(
|
234
233
|
is_valid=False,
|
@@ -255,7 +254,7 @@ class FastAPIAuthMiddleware(AuthMiddleware):
|
|
255
254
|
error_message=f"Authentication method {method} failed: {str(e)}"
|
256
255
|
)
|
257
256
|
|
258
|
-
|
257
|
+
def _try_api_key_auth(self, request: Request) -> AuthResult:
|
259
258
|
"""
|
260
259
|
Try API key authentication with FastAPI request.
|
261
260
|
|
@@ -287,7 +286,7 @@ class FastAPIAuthMiddleware(AuthMiddleware):
|
|
287
286
|
# Authenticate using security manager
|
288
287
|
return self.security_manager.auth_manager.authenticate_api_key(api_key)
|
289
288
|
|
290
|
-
|
289
|
+
def _try_jwt_auth(self, request: Request) -> AuthResult:
|
291
290
|
"""
|
292
291
|
Try JWT authentication with FastAPI request.
|
293
292
|
|
@@ -315,7 +314,7 @@ class FastAPIAuthMiddleware(AuthMiddleware):
|
|
315
314
|
# Authenticate using security manager
|
316
315
|
return self.security_manager.auth_manager.authenticate_jwt_token(token)
|
317
316
|
|
318
|
-
|
317
|
+
def _try_certificate_auth(self, request: Request) -> AuthResult:
|
319
318
|
"""
|
320
319
|
Try certificate authentication with FastAPI request.
|
321
320
|
|
@@ -338,7 +337,7 @@ class FastAPIAuthMiddleware(AuthMiddleware):
|
|
338
337
|
error_message="Certificate authentication not implemented"
|
339
338
|
)
|
340
339
|
|
341
|
-
|
340
|
+
def _try_basic_auth(self, request: Request) -> AuthResult:
|
342
341
|
"""
|
343
342
|
Try basic authentication with FastAPI request.
|
344
343
|
|
@@ -428,6 +427,75 @@ class FastAPIAuthMiddleware(AuthMiddleware):
|
|
428
427
|
extra={"error": str(e)},
|
429
428
|
exc_info=True
|
430
429
|
)
|
430
|
+
|
431
|
+
# Abstract method implementations
|
432
|
+
|
433
|
+
def _get_rate_limit_identifier(self, request: Request) -> str:
|
434
|
+
"""
|
435
|
+
Get rate limit identifier from FastAPI request.
|
436
|
+
|
437
|
+
Args:
|
438
|
+
request (Request): FastAPI request object
|
439
|
+
|
440
|
+
Returns:
|
441
|
+
str: Rate limit identifier (IP address)
|
442
|
+
"""
|
443
|
+
return self._get_client_ip(request)
|
444
|
+
|
445
|
+
def _get_request_path(self, request: Request) -> str:
|
446
|
+
"""
|
447
|
+
Get request path from FastAPI request.
|
448
|
+
|
449
|
+
Args:
|
450
|
+
request (Request): FastAPI request object
|
451
|
+
|
452
|
+
Returns:
|
453
|
+
str: Request path
|
454
|
+
"""
|
455
|
+
return str(request.url.path)
|
456
|
+
|
457
|
+
def _get_required_permissions(self, request: Request) -> List[str]:
|
458
|
+
"""
|
459
|
+
Get required permissions for FastAPI request.
|
460
|
+
|
461
|
+
Args:
|
462
|
+
request (Request): FastAPI request object
|
463
|
+
|
464
|
+
Returns:
|
465
|
+
List[str]: List of required permissions
|
466
|
+
"""
|
467
|
+
# For authentication-only middleware, no permissions are required
|
468
|
+
return []
|
469
|
+
|
470
|
+
def _apply_security_headers(self, response: Response, headers: Dict[str, str]) -> None:
|
471
|
+
"""
|
472
|
+
Apply security headers to FastAPI response.
|
473
|
+
|
474
|
+
Args:
|
475
|
+
response (Response): FastAPI response object
|
476
|
+
headers (Dict[str, str]): Headers to apply
|
477
|
+
"""
|
478
|
+
for header, value in headers.items():
|
479
|
+
response.headers[header] = value
|
480
|
+
|
481
|
+
def _create_error_response(self, status_code: int, message: str) -> JSONResponse:
|
482
|
+
"""
|
483
|
+
Create error response for FastAPI.
|
484
|
+
|
485
|
+
Args:
|
486
|
+
status_code (int): HTTP status code
|
487
|
+
message (str): Error message
|
488
|
+
|
489
|
+
Returns:
|
490
|
+
JSONResponse: FastAPI error response object
|
491
|
+
"""
|
492
|
+
return JSONResponse(
|
493
|
+
status_code=status_code,
|
494
|
+
content={
|
495
|
+
"error": message,
|
496
|
+
"error_code": -32000
|
497
|
+
}
|
498
|
+
)
|
431
499
|
|
432
500
|
|
433
501
|
class AuthMiddlewareError(Exception):
|
@@ -27,7 +27,7 @@ Last Modified: 2024-01-20
|
|
27
27
|
|
28
28
|
import json
|
29
29
|
import logging
|
30
|
-
from typing import Any, Dict, Optional
|
30
|
+
from typing import Any, Dict, Optional, List
|
31
31
|
|
32
32
|
from flask import Request, Response, jsonify, current_app
|
33
33
|
from werkzeug.exceptions import Unauthorized
|
@@ -65,15 +65,15 @@ class FlaskAuthMiddleware(AuthMiddleware):
|
|
65
65
|
AuthMiddlewareError: When authentication processing fails
|
66
66
|
"""
|
67
67
|
|
68
|
-
def __init__(self,
|
68
|
+
def __init__(self, security_manager: Any):
|
69
69
|
"""
|
70
70
|
Initialize Flask Authentication Middleware.
|
71
71
|
|
72
72
|
Args:
|
73
|
-
|
74
|
-
|
73
|
+
security_manager: Security manager instance containing
|
74
|
+
all security components and configuration.
|
75
75
|
"""
|
76
|
-
super().__init__(
|
76
|
+
super().__init__(security_manager)
|
77
77
|
self.logger = logging.getLogger(__name__)
|
78
78
|
|
79
79
|
def __call__(self, environ: Dict[str, Any], start_response: Any) -> Any:
|
@@ -446,8 +446,155 @@ class FlaskAuthMiddleware(AuthMiddleware):
|
|
446
446
|
extra={"error": str(e)},
|
447
447
|
exc_info=True
|
448
448
|
)
|
449
|
-
|
450
|
-
|
449
|
+
|
450
|
+
def _apply_security_headers(self, response: Any) -> Any:
|
451
|
+
"""
|
452
|
+
Apply security headers to response.
|
453
|
+
|
454
|
+
Args:
|
455
|
+
response: WSGI response
|
456
|
+
|
457
|
+
Returns:
|
458
|
+
Any: Response with security headers
|
459
|
+
"""
|
460
|
+
# This would be implemented for actual Flask responses
|
461
|
+
# For now, return the response as-is
|
462
|
+
return response
|
463
|
+
|
464
|
+
def _create_error_response(self, error_message: str, error_code: int, start_response: Any) -> Any:
|
465
|
+
"""
|
466
|
+
Create error response for Flask.
|
467
|
+
|
468
|
+
Args:
|
469
|
+
error_message (str): Error message
|
470
|
+
error_code (int): Error code
|
471
|
+
start_response: WSGI start_response function
|
472
|
+
|
473
|
+
Returns:
|
474
|
+
Any: WSGI error response
|
475
|
+
"""
|
476
|
+
error_data = {
|
477
|
+
"error": "Security error",
|
478
|
+
"error_code": error_code,
|
479
|
+
"error_message": error_message
|
480
|
+
}
|
481
|
+
|
482
|
+
status = '400 Bad Request'
|
483
|
+
headers = [('Content-Type', 'application/json')]
|
484
|
+
|
485
|
+
start_response(status, headers)
|
486
|
+
return [json.dumps(error_data).encode()]
|
487
|
+
|
488
|
+
def _get_rate_limit_identifier(self, request: Request) -> str:
|
489
|
+
"""
|
490
|
+
Get rate limit identifier from request.
|
491
|
+
|
492
|
+
Args:
|
493
|
+
request (Request): Flask request object
|
494
|
+
|
495
|
+
Returns:
|
496
|
+
str: Rate limit identifier (IP address)
|
497
|
+
"""
|
498
|
+
return self._get_client_ip(request)
|
499
|
+
|
500
|
+
def _get_request_path(self, request: Request) -> str:
|
501
|
+
"""
|
502
|
+
Get request path from request.
|
503
|
+
|
504
|
+
Args:
|
505
|
+
request (Request): Flask request object
|
506
|
+
|
507
|
+
Returns:
|
508
|
+
str: Request path
|
509
|
+
"""
|
510
|
+
return request.path
|
511
|
+
|
512
|
+
def _get_required_permissions(self, request: Request) -> List[str]:
|
513
|
+
"""
|
514
|
+
Get required permissions for request.
|
515
|
+
|
516
|
+
Args:
|
517
|
+
request (Request): Flask request object
|
518
|
+
|
519
|
+
Returns:
|
520
|
+
List[str]: Required permissions
|
521
|
+
"""
|
522
|
+
# This would be implemented based on your application's authorization logic
|
523
|
+
# For now, return an empty list
|
524
|
+
return []
|
525
|
+
|
526
|
+
def _validation_error_response(self, error_message: str, error_code: int = -32000, start_response: Any = None) -> Any:
|
527
|
+
"""
|
528
|
+
Create validation error response for Flask.
|
529
|
+
|
530
|
+
Args:
|
531
|
+
error_message (str): Error message
|
532
|
+
error_code (int): Error code
|
533
|
+
start_response: WSGI start_response function
|
534
|
+
|
535
|
+
Returns:
|
536
|
+
Any: WSGI error response
|
537
|
+
"""
|
538
|
+
if start_response is None:
|
539
|
+
start_response = Mock()
|
540
|
+
return self._create_error_response(error_message, error_code, start_response)
|
541
|
+
|
542
|
+
def _rate_limit_error_response(self, error_message: str, error_code: int = -32000, start_response: Any = None) -> Any:
|
543
|
+
"""
|
544
|
+
Create rate limit error response for Flask.
|
545
|
+
|
546
|
+
Args:
|
547
|
+
error_message (str): Error message
|
548
|
+
error_code (int): Error code
|
549
|
+
start_response: WSGI start_response function
|
550
|
+
|
551
|
+
Returns:
|
552
|
+
Any: WSGI error response
|
553
|
+
"""
|
554
|
+
if start_response is None:
|
555
|
+
start_response = Mock()
|
556
|
+
return self._create_error_response(error_message, error_code, start_response)
|
557
|
+
|
558
|
+
def _security_header_response(self, error_message: str, error_code: int = -32000, start_response: Any = None) -> Any:
|
559
|
+
"""
|
560
|
+
Create security header error response for Flask.
|
561
|
+
|
562
|
+
Args:
|
563
|
+
error_message (str): Error message
|
564
|
+
error_code (int): Error code
|
565
|
+
start_response: WSGI start_response function
|
566
|
+
|
567
|
+
Returns:
|
568
|
+
Any: WSGI error response
|
569
|
+
"""
|
570
|
+
if start_response is None:
|
571
|
+
start_response = Mock()
|
572
|
+
return self._create_error_response(error_message, error_code, start_response)
|
573
|
+
|
574
|
+
def _authz_error_response(self, auth_result: AuthResult, start_response: Any) -> Any:
|
575
|
+
"""
|
576
|
+
Create authorization error response for Flask.
|
577
|
+
|
578
|
+
Args:
|
579
|
+
auth_result (AuthResult): Authentication result
|
580
|
+
start_response: WSGI start_response function
|
581
|
+
|
582
|
+
Returns:
|
583
|
+
Any: WSGI error response
|
584
|
+
"""
|
585
|
+
error_data = {
|
586
|
+
"error": "Authorization failed",
|
587
|
+
"error_code": auth_result.error_code,
|
588
|
+
"error_message": auth_result.error_message
|
589
|
+
}
|
590
|
+
|
591
|
+
status = '403 Forbidden'
|
592
|
+
headers = [('Content-Type', 'application/json')]
|
593
|
+
|
594
|
+
start_response(status, headers)
|
595
|
+
return [json.dumps(error_data).encode()]
|
596
|
+
|
597
|
+
|
451
598
|
class AuthMiddlewareError(Exception):
|
452
599
|
"""
|
453
600
|
Authentication Middleware Error
|
@@ -125,8 +125,8 @@ def extract_certificate_info(cert_data: Union[str, bytes, Path]) -> Dict:
|
|
125
125
|
"issuer": str(cert.issuer),
|
126
126
|
"serial_number": str(cert.serial_number),
|
127
127
|
"version": cert.version.name,
|
128
|
-
"not_before": cert.
|
129
|
-
"not_after": cert.
|
128
|
+
"not_before": cert.not_valid_before_utc,
|
129
|
+
"not_after": cert.not_valid_after_utc,
|
130
130
|
"signature_algorithm": cert.signature_algorithm_oid._name,
|
131
131
|
"public_key_algorithm": cert.public_key_algorithm_oid._name,
|
132
132
|
"key_size": _get_key_size(cert.public_key()),
|
@@ -319,7 +319,7 @@ def get_certificate_expiry(cert_data: Union[str, bytes, Path]) -> Dict:
|
|
319
319
|
now = datetime.now(timezone.utc)
|
320
320
|
|
321
321
|
# Calculate time until expiry
|
322
|
-
time_until_expiry = cert.
|
322
|
+
time_until_expiry = cert.not_valid_after_utc.replace(tzinfo=timezone.utc) - now
|
323
323
|
days_until_expiry = time_until_expiry.days
|
324
324
|
|
325
325
|
# Determine expiry status
|
@@ -331,8 +331,8 @@ def get_certificate_expiry(cert_data: Union[str, bytes, Path]) -> Dict:
|
|
331
331
|
status = "valid"
|
332
332
|
|
333
333
|
return {
|
334
|
-
"not_after": cert.
|
335
|
-
"not_before": cert.
|
334
|
+
"not_after": cert.not_valid_after_utc,
|
335
|
+
"not_before": cert.not_valid_before_utc,
|
336
336
|
"days_until_expiry": days_until_expiry,
|
337
337
|
"is_expired": time_until_expiry.total_seconds() < 0,
|
338
338
|
"expires_soon": days_until_expiry <= 30,
|
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.4
|
2
2
|
Name: mcp-security-framework
|
3
|
-
Version:
|
3
|
+
Version: 1.1.0
|
4
4
|
Summary: Universal security framework for microservices with SSL/TLS, authentication, authorization, and rate limiting
|
5
5
|
Author-email: Vasiliy Zdanovskiy <vasilyvz@gmail.com>
|
6
6
|
Maintainer-email: Vasiliy Zdanovskiy <vasilyvz@gmail.com>
|
@@ -4,62 +4,68 @@ mcp_security_framework/cli/__init__.py,sha256=cPLJ5iZYxSomXFjA4-IPWE3hmMx6ryiWae
|
|
4
4
|
mcp_security_framework/cli/cert_cli.py,sha256=QW2YciGE5jKdfzYMwXCn-znNm22VhAaSHk4qH4tcp2w,19129
|
5
5
|
mcp_security_framework/cli/security_cli.py,sha256=fmYVT03NbR7PrO6qUa9L1FQhTTPd1ZMFIB6H6nWLqOU,27993
|
6
6
|
mcp_security_framework/core/__init__.py,sha256=LiX8_M5qWiTXccJFjSLxup9emhklp-poq57SvznsKEg,1729
|
7
|
-
mcp_security_framework/core/auth_manager.py,sha256=
|
8
|
-
mcp_security_framework/core/cert_manager.py,sha256=
|
9
|
-
mcp_security_framework/core/permission_manager.py,sha256=
|
10
|
-
mcp_security_framework/core/rate_limiter.py,sha256=
|
11
|
-
mcp_security_framework/core/security_manager.py,sha256=
|
7
|
+
mcp_security_framework/core/auth_manager.py,sha256=yRLKp9YXQxpdRUqzlJ9xcCW4PnXpBBpSpMeeysrYWPU,38620
|
8
|
+
mcp_security_framework/core/cert_manager.py,sha256=mPO5LNo6MdYgiY8akEQ-cn58AsQOCvnurOWYYFmC3WY,78659
|
9
|
+
mcp_security_framework/core/permission_manager.py,sha256=Ts_O_A0AMl_vAcMxRG9LpYbBl3cR6Anv0LAS0rwpKr4,26489
|
10
|
+
mcp_security_framework/core/rate_limiter.py,sha256=QMdlRRqf-GU7eUgM5vttjvhkYmFs2INX9f0qMgxO8BY,20694
|
11
|
+
mcp_security_framework/core/security_manager.py,sha256=mwDSFHswp91Wc90PQ9JyIukqq15dO4lK56yjmoY5PDA,38176
|
12
12
|
mcp_security_framework/core/ssl_manager.py,sha256=nCDrukaELONQs_uAfb30g69HDxRp2u4k0Bpq8eJH6Zo,27718
|
13
13
|
mcp_security_framework/examples/__init__.py,sha256=RW-qTe-Fu3Hbl1Kyd58pWqYan92cmW-y0g2wEVCK850,1909
|
14
|
-
mcp_security_framework/examples/
|
15
|
-
mcp_security_framework/examples/
|
16
|
-
mcp_security_framework/examples/
|
17
|
-
mcp_security_framework/examples/
|
18
|
-
mcp_security_framework/examples/
|
19
|
-
mcp_security_framework/examples/
|
14
|
+
mcp_security_framework/examples/comprehensive_example.py,sha256=ZEz1lOJM-a2hy8ccMeRdVZzdunGyOPhuYaf59xMWe4E,35738
|
15
|
+
mcp_security_framework/examples/django_example.py,sha256=RFmZlXj9_fWpIjQrm3z798IQEq4iLZu8NbHg7NNAIbY,24433
|
16
|
+
mcp_security_framework/examples/fastapi_example.py,sha256=BFJjDCq3kmHowxREvb9Cb2rqzRAJPOo5HzBx1ccGovc,36346
|
17
|
+
mcp_security_framework/examples/flask_example.py,sha256=6BhplNC9yA-7cBs03J1Amo0sR7V0vP4NFj8LP3Sd9JA,20619
|
18
|
+
mcp_security_framework/examples/gateway_example.py,sha256=BOEmykUJ56eGilZJT5V1j1swaW62MvlXLrE1aL0l2pw,33279
|
19
|
+
mcp_security_framework/examples/microservice_example.py,sha256=MUKAqV-0-xLga6VVddgVNfAsapgOgh7RDroWrDhEkvE,29951
|
20
|
+
mcp_security_framework/examples/standalone_example.py,sha256=IckipYe2I4wzbdmOV2EN1_ycucY-W4fU57ocKEgOtzQ,30633
|
21
|
+
mcp_security_framework/examples/test_all_examples.py,sha256=BkxHUUL_2hWc2f3b15lnlja3Zwp6frcic9GQVfhaXEY,20074
|
20
22
|
mcp_security_framework/middleware/__init__.py,sha256=wSBfpfdrz4ErqhwCOJI1uxbQ5Q22_2HdjrxmwwWuj0o,8027
|
21
|
-
mcp_security_framework/middleware/auth_middleware.py,sha256=
|
22
|
-
mcp_security_framework/middleware/fastapi_auth_middleware.py,sha256=
|
23
|
+
mcp_security_framework/middleware/auth_middleware.py,sha256=kk0koMxrESjJ_nZ_6h5WvuupGA0exK1Q19n0Spuw1k8,10242
|
24
|
+
mcp_security_framework/middleware/fastapi_auth_middleware.py,sha256=LsCBlU4XRja66VCDkYEHk7fmD27-SrAGyPOijtxmRHQ,17502
|
23
25
|
mcp_security_framework/middleware/fastapi_middleware.py,sha256=J8olLT3SICbM-NJ2m11cPkOfhREtlJHYk5ENfggbuU4,27260
|
24
|
-
mcp_security_framework/middleware/flask_auth_middleware.py,sha256=
|
26
|
+
mcp_security_framework/middleware/flask_auth_middleware.py,sha256=e94Y8SqfPikg0V-tap3iK9TffHqSCKXvclKdBCatLWg,20891
|
25
27
|
mcp_security_framework/middleware/flask_middleware.py,sha256=wtHafpEgOvA8ZEIzJQzt-LqbIrcFWd1sz8QJXNpgkEU,21083
|
26
28
|
mcp_security_framework/middleware/mtls_middleware.py,sha256=TsI9BwFkX98KqG9E1bpFFOrcA8vsaumRc0GH6dOEHRs,14694
|
27
29
|
mcp_security_framework/middleware/rate_limit_middleware.py,sha256=EgjF7mzhkdgfL4nT4eLtKchWmmwaa50WCuIVwYwl_ac,13661
|
28
30
|
mcp_security_framework/middleware/security_middleware.py,sha256=aQDt9ktMzs0KzNq_aW_23dfOSTmIrWHNj_ps0O7MK40,17804
|
29
31
|
mcp_security_framework/schemas/__init__.py,sha256=lefkbRlbj2ICfasSj51MQ04o3z1YycnbnknSJCFfXbU,2590
|
30
32
|
mcp_security_framework/schemas/config.py,sha256=dMlMum-pCWMwYoqBm14dUD725pOW63dYPfIqXv_0maQ,25816
|
31
|
-
mcp_security_framework/schemas/models.py,sha256=
|
33
|
+
mcp_security_framework/schemas/models.py,sha256=5L-GdtHmuH8HfYkAueeN2Amm6l9i0jIv72jJbDejLlI,26813
|
32
34
|
mcp_security_framework/schemas/responses.py,sha256=nVXaqF5GTSprXTa_wiUEu38nvSw9WAXtKViAJNbO-Xg,23206
|
33
35
|
mcp_security_framework/tests/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
34
36
|
mcp_security_framework/utils/__init__.py,sha256=wwwdmQYHTSz0Puvs9FD6aIKmWp3NFARe3JPWNH-b_wk,3098
|
35
|
-
mcp_security_framework/utils/cert_utils.py,sha256=
|
37
|
+
mcp_security_framework/utils/cert_utils.py,sha256=TzErmDK_dAtDCNDnUPh_Oa13HkUDev-G_pHGSXS3cB4,17160
|
36
38
|
mcp_security_framework/utils/crypto_utils.py,sha256=OH2V7_C3FjStxFTIXMUPfNXZuWG2-QjgoBrIH4Lv4p0,12392
|
37
39
|
mcp_security_framework/utils/validation_utils.py,sha256=e9BX3kw9gdXSmFsc7lmG-qnzSlK0-Ynn7Xs4uKHquF4,16279
|
38
40
|
tests/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
41
|
+
tests/conftest.py,sha256=Ws5h-n_hAry_QKquFA0h1TW-v8sHGi2_t06S0s5YOw8,9024
|
39
42
|
tests/test_cli/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
40
|
-
tests/test_cli/test_cert_cli.py,sha256=
|
43
|
+
tests/test_cli/test_cert_cli.py,sha256=3hL_4y9-908sjgLrFQVNrm0Pr8yacNCAzKf9avisfDY,14327
|
41
44
|
tests/test_cli/test_security_cli.py,sha256=oMEUEzt-B-UR-acAzUa-BR1YDOGEwdmKiSy-MIuflGE,25926
|
42
45
|
tests/test_core/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
43
46
|
tests/test_core/test_auth_manager.py,sha256=tyJUe3yBP95SFwbhSr_IloKhEQw0BuEdvjAC1Hnwu4s,22540
|
44
|
-
tests/test_core/test_cert_manager.py,sha256=
|
47
|
+
tests/test_core/test_cert_manager.py,sha256=MPbrf0qUvRP0Yj67xowuw7gI20HQWgBobGsvFz30iKM,36083
|
45
48
|
tests/test_core/test_permission_manager.py,sha256=0XeghWXZqVpKyyRuhuDu1dkLUSwuZaFWkRQxQhkkFVI,14966
|
46
49
|
tests/test_core/test_rate_limiter.py,sha256=YzzlhlxZm-A7YGMiIV8LXDA0zmb_6uRF9GRx9s21Q0U,22544
|
47
50
|
tests/test_core/test_security_manager.py,sha256=y8klHTMeBoh16wI-10-7gd92T7ZpmuPaSmDtfWM88Ns,35007
|
48
51
|
tests/test_core/test_ssl_manager.py,sha256=Vm_Nw4SoVro_iwPPc_uD9CwzXpVBkGyVH7EqDtHawvU,20362
|
49
52
|
tests/test_examples/__init__.py,sha256=VC0N1wB9d01Acnqfos-9x68o23xxHkRhAh4-1qJKUTc,157
|
50
|
-
tests/test_examples/
|
51
|
-
tests/test_examples/
|
52
|
-
tests/test_examples/
|
53
|
+
tests/test_examples/test_comprehensive_example.py,sha256=JqCa7QKlk0wY0jHm9G22_AkWcuQCTIOOvCoCnWr3ZIA,26142
|
54
|
+
tests/test_examples/test_fastapi_example.py,sha256=BsWlWdRue7VwluWaj3psaeIlQl7Ra_kBBJqOzsMRMws,13260
|
55
|
+
tests/test_examples/test_flask_example.py,sha256=nh7As80LDz2vZXhLOo9IaJDNZiYBRdMbItDS_PhihwE,12822
|
56
|
+
tests/test_examples/test_standalone_example.py,sha256=rw8Djqw9dhgtz2P50y9rBXUWYij30uK-cjdWzJHyamI,8520
|
53
57
|
tests/test_integration/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
54
|
-
tests/test_integration/test_auth_flow.py,sha256
|
55
|
-
tests/test_integration/test_certificate_flow.py,sha256=
|
56
|
-
tests/test_integration/test_fastapi_integration.py,sha256=
|
57
|
-
tests/test_integration/test_flask_integration.py,sha256=
|
58
|
-
tests/test_integration/test_standalone_integration.py,sha256=
|
58
|
+
tests/test_integration/test_auth_flow.py,sha256=-qtPdfy_uGbcW8wh4K31VlSlFkHiLKYRszg8lC5_o0E,19212
|
59
|
+
tests/test_integration/test_certificate_flow.py,sha256=ILX7b01Oum5DBYb4UusSzwniqgUkc5bbhLzcPEihjJo,19969
|
60
|
+
tests/test_integration/test_fastapi_integration.py,sha256=5BhqPSWC07WCgoq4moEx9PX0XLJxOLljGrd25ZwccUs,13401
|
61
|
+
tests/test_integration/test_flask_integration.py,sha256=hZ3yerzG8n1hrTLKMR0-LuERTYEide_-t_8xyvUSvjY,15767
|
62
|
+
tests/test_integration/test_standalone_integration.py,sha256=K8n7hkSYEqwCMSxfNC0Iwedr9SA7YJSFXIeoq0kRqLc,19076
|
59
63
|
tests/test_middleware/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
64
|
+
tests/test_middleware/test_fastapi_auth_middleware.py,sha256=pORcQ1DssYBcO1yEQO402mUFgXRn9QRfkaQKshlm06o,30139
|
60
65
|
tests/test_middleware/test_fastapi_middleware.py,sha256=43U1PGHDa9a8AnvJpbuyUE1psDuvj2-g64dWkEuqTBM,21150
|
66
|
+
tests/test_middleware/test_flask_auth_middleware.py,sha256=KP-JvrtZbf67i-g8rkXJmBnay_CppXqTGuDh-ZQu1gM,25356
|
61
67
|
tests/test_middleware/test_flask_middleware.py,sha256=OfucOhChC3rr8UdSYz2EWQzCtA0oalMqzDxdiT1tNOQ,23364
|
62
|
-
tests/test_middleware/test_security_middleware.py,sha256=
|
68
|
+
tests/test_middleware/test_security_middleware.py,sha256=X7Ui-jPkZ2czobEZRf6NwXovH8sGiwYYUdIR7ADQLXA,19653
|
63
69
|
tests/test_schemas/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
64
70
|
tests/test_schemas/test_config.py,sha256=Bp_yZ_HBIl7jcR7Wb1S9iCB0tCu_Ov26YKHTulDs1RU,29430
|
65
71
|
tests/test_schemas/test_models.py,sha256=bBeZOPqveuVJuEi_BTVWdVsdj08JXJTEFwvBM4eFRVU,34311
|
@@ -69,8 +75,8 @@ tests/test_utils/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,
|
|
69
75
|
tests/test_utils/test_cert_utils.py,sha256=2k1kUCJy0T2HPBwOcU5USGfEBQZ_rGzumAGkDdywLak,21232
|
70
76
|
tests/test_utils/test_crypto_utils.py,sha256=yEb4hzG6-irj2DPoXY0DUboJfbeR87ussgTuBpxLGz4,20737
|
71
77
|
tests/test_utils/test_validation_utils.py,sha256=lus_wHJ2WyVnBGQ28S7dSv78uWcCIuLhn5uflJw-uGw,18569
|
72
|
-
mcp_security_framework-
|
73
|
-
mcp_security_framework-
|
74
|
-
mcp_security_framework-
|
75
|
-
mcp_security_framework-
|
76
|
-
mcp_security_framework-
|
78
|
+
mcp_security_framework-1.1.0.dist-info/METADATA,sha256=QZQBtZE8weA0gcd3G0g2Yx2GErDQ-TLqge2_CCmlIf4,11680
|
79
|
+
mcp_security_framework-1.1.0.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
80
|
+
mcp_security_framework-1.1.0.dist-info/entry_points.txt,sha256=qBh92fVDmd1m2f3xeW0hTu3Ksg8QfGJyV8UEkdA2itg,142
|
81
|
+
mcp_security_framework-1.1.0.dist-info/top_level.txt,sha256=ifUiGrTDcD574MXSOoAN2rp2wpUvWlb4jD9LTUgDWCA,29
|
82
|
+
mcp_security_framework-1.1.0.dist-info/RECORD,,
|