mcp-security-framework 0.1.0__py3-none-any.whl → 1.1.1__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/__init__.py +26 -15
- mcp_security_framework/cli/__init__.py +1 -1
- mcp_security_framework/cli/cert_cli.py +233 -197
- mcp_security_framework/cli/security_cli.py +324 -234
- mcp_security_framework/constants.py +21 -27
- mcp_security_framework/core/auth_manager.py +49 -20
- mcp_security_framework/core/cert_manager.py +398 -104
- mcp_security_framework/core/permission_manager.py +13 -9
- mcp_security_framework/core/rate_limiter.py +10 -0
- mcp_security_framework/core/security_manager.py +286 -229
- mcp_security_framework/examples/__init__.py +6 -0
- mcp_security_framework/examples/comprehensive_example.py +954 -0
- mcp_security_framework/examples/django_example.py +276 -202
- mcp_security_framework/examples/fastapi_example.py +897 -393
- mcp_security_framework/examples/flask_example.py +311 -200
- mcp_security_framework/examples/gateway_example.py +373 -214
- mcp_security_framework/examples/microservice_example.py +337 -172
- mcp_security_framework/examples/standalone_example.py +719 -478
- mcp_security_framework/examples/test_all_examples.py +572 -0
- mcp_security_framework/middleware/__init__.py +46 -55
- mcp_security_framework/middleware/auth_middleware.py +62 -63
- mcp_security_framework/middleware/fastapi_auth_middleware.py +179 -110
- mcp_security_framework/middleware/fastapi_middleware.py +156 -148
- mcp_security_framework/middleware/flask_auth_middleware.py +267 -107
- mcp_security_framework/middleware/flask_middleware.py +183 -157
- mcp_security_framework/middleware/mtls_middleware.py +106 -117
- mcp_security_framework/middleware/rate_limit_middleware.py +105 -101
- mcp_security_framework/middleware/security_middleware.py +109 -124
- mcp_security_framework/schemas/config.py +2 -1
- mcp_security_framework/schemas/models.py +19 -6
- mcp_security_framework/utils/cert_utils.py +14 -8
- mcp_security_framework/utils/datetime_compat.py +116 -0
- {mcp_security_framework-0.1.0.dist-info → mcp_security_framework-1.1.1.dist-info}/METADATA +2 -1
- mcp_security_framework-1.1.1.dist-info/RECORD +84 -0
- tests/conftest.py +303 -0
- tests/test_cli/test_cert_cli.py +194 -174
- tests/test_cli/test_security_cli.py +274 -247
- tests/test_core/test_cert_manager.py +33 -19
- tests/test_core/test_security_manager.py +2 -2
- tests/test_examples/test_comprehensive_example.py +613 -0
- tests/test_examples/test_fastapi_example.py +290 -169
- tests/test_examples/test_flask_example.py +304 -162
- tests/test_examples/test_standalone_example.py +106 -168
- tests/test_integration/test_auth_flow.py +214 -198
- tests/test_integration/test_certificate_flow.py +181 -150
- tests/test_integration/test_fastapi_integration.py +140 -149
- tests/test_integration/test_flask_integration.py +144 -141
- tests/test_integration/test_standalone_integration.py +331 -300
- tests/test_middleware/test_fastapi_auth_middleware.py +745 -0
- tests/test_middleware/test_fastapi_middleware.py +147 -132
- tests/test_middleware/test_flask_auth_middleware.py +696 -0
- tests/test_middleware/test_flask_middleware.py +201 -179
- tests/test_middleware/test_security_middleware.py +151 -130
- tests/test_utils/test_datetime_compat.py +147 -0
- mcp_security_framework-0.1.0.dist-info/RECORD +0 -76
- {mcp_security_framework-0.1.0.dist-info → mcp_security_framework-1.1.1.dist-info}/WHEEL +0 -0
- {mcp_security_framework-0.1.0.dist-info → mcp_security_framework-1.1.1.dist-info}/entry_points.txt +0 -0
- {mcp_security_framework-0.1.0.dist-info → mcp_security_framework-1.1.1.dist-info}/top_level.txt +0 -0
@@ -1,576 +1,817 @@
|
|
1
|
+
#!/usr/bin/env python3
|
1
2
|
"""
|
2
|
-
Standalone Example
|
3
|
+
Standalone Example - Comprehensive Security Framework Demo
|
3
4
|
|
4
|
-
This
|
5
|
-
in a standalone
|
5
|
+
This example demonstrates ALL capabilities of the MCP Security Framework
|
6
|
+
in a standalone environment, serving as a comprehensive integration test.
|
6
7
|
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
8
|
+
Demonstrated Features:
|
9
|
+
1. Authentication (API Key, JWT, Certificate)
|
10
|
+
2. Authorization (Role-based access control)
|
11
|
+
3. SSL/TLS Management (Server/Client contexts)
|
12
|
+
4. Certificate Management (Creation, validation, revocation)
|
13
|
+
5. Rate Limiting (Request throttling)
|
14
|
+
6. Security Validation (Request/Configuration validation)
|
15
|
+
7. Security Monitoring (Status, metrics, audit)
|
16
|
+
8. Security Logging (Event logging)
|
14
17
|
|
15
|
-
Author:
|
18
|
+
Author: Vasiliy Zdanovskiy
|
19
|
+
email: vasilyvz@gmail.com
|
16
20
|
Version: 1.0.0
|
17
21
|
License: MIT
|
18
22
|
"""
|
19
23
|
|
20
|
-
import os
|
21
24
|
import json
|
22
25
|
import logging
|
23
|
-
import
|
24
|
-
|
25
|
-
|
26
|
+
import os
|
27
|
+
import shutil
|
28
|
+
import tempfile
|
29
|
+
from datetime import datetime, timedelta, timezone
|
30
|
+
from typing import Any, Dict, List, Optional
|
26
31
|
|
27
|
-
from mcp_security_framework.core.security_manager import SecurityManager
|
28
|
-
from mcp_security_framework.core.auth_manager import AuthManager
|
29
|
-
from mcp_security_framework.core.ssl_manager import SSLManager
|
30
|
-
from mcp_security_framework.core.permission_manager import PermissionManager
|
31
|
-
from mcp_security_framework.core.rate_limiter import RateLimiter
|
32
|
-
from mcp_security_framework.schemas.config import SecurityConfig, AuthConfig, SSLConfig
|
33
|
-
from mcp_security_framework.schemas.models import AuthResult, AuthStatus, AuthMethod
|
34
32
|
from mcp_security_framework.constants import (
|
35
|
-
|
36
|
-
|
33
|
+
AUTH_METHODS,
|
34
|
+
DEFAULT_SECURITY_HEADERS,
|
35
|
+
ErrorCodes,
|
36
|
+
)
|
37
|
+
from mcp_security_framework.core.security_manager import SecurityManager
|
38
|
+
from mcp_security_framework.schemas.config import (
|
39
|
+
AuthConfig,
|
40
|
+
CertificateConfig,
|
41
|
+
LoggingConfig,
|
42
|
+
PermissionConfig,
|
43
|
+
RateLimitConfig,
|
44
|
+
SecurityConfig,
|
45
|
+
SSLConfig,
|
46
|
+
)
|
47
|
+
from mcp_security_framework.schemas.models import (
|
48
|
+
AuthMethod,
|
49
|
+
AuthResult,
|
50
|
+
AuthStatus,
|
51
|
+
CertificateInfo,
|
52
|
+
CertificatePair,
|
53
|
+
ValidationResult,
|
54
|
+
ValidationStatus,
|
37
55
|
)
|
38
56
|
|
39
57
|
|
40
|
-
class
|
58
|
+
class StandaloneSecurityExample:
|
41
59
|
"""
|
42
|
-
|
43
|
-
|
44
|
-
This class demonstrates
|
45
|
-
|
46
|
-
- Multi-method authentication (API Key, JWT, Certificate)
|
47
|
-
- Role-based access control
|
48
|
-
- Rate limiting with Redis backend
|
49
|
-
- SSL/TLS configuration
|
50
|
-
- Comprehensive logging and monitoring
|
51
|
-
- Command-line interface
|
60
|
+
Comprehensive Standalone Security Example
|
61
|
+
|
62
|
+
This class demonstrates ALL capabilities of the MCP Security Framework
|
63
|
+
in a standalone environment, serving as a complete integration test.
|
52
64
|
"""
|
53
|
-
|
65
|
+
|
54
66
|
def __init__(self, config_path: Optional[str] = None):
|
55
67
|
"""
|
56
|
-
Initialize standalone
|
57
|
-
|
68
|
+
Initialize the standalone security example.
|
69
|
+
|
58
70
|
Args:
|
59
|
-
config_path:
|
71
|
+
config_path: Optional path to configuration file
|
60
72
|
"""
|
61
73
|
self.config = self._load_config(config_path)
|
62
74
|
self.security_manager = SecurityManager(self.config)
|
63
75
|
self.logger = logging.getLogger(__name__)
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
SecurityConfig: Loaded configuration
|
75
|
-
"""
|
76
|
+
|
77
|
+
# Test data
|
78
|
+
self.test_api_key = "admin_key_123"
|
79
|
+
self.test_jwt_token = self._create_test_jwt_token()
|
80
|
+
self.test_certificate = self._create_test_certificate()
|
81
|
+
|
82
|
+
self.logger.info("Standalone Security Example initialized successfully")
|
83
|
+
|
84
|
+
def _load_config(self, config_path: Optional[str] = None) -> SecurityConfig:
|
85
|
+
"""Load security configuration."""
|
76
86
|
if config_path and os.path.exists(config_path):
|
77
|
-
with open(config_path,
|
87
|
+
with open(config_path, "r") as f:
|
78
88
|
config_data = json.load(f)
|
79
89
|
return SecurityConfig(**config_data)
|
80
|
-
|
81
|
-
# Create
|
90
|
+
|
91
|
+
# Create comprehensive configuration
|
82
92
|
return SecurityConfig(
|
83
93
|
auth=AuthConfig(
|
84
94
|
enabled=True,
|
85
|
-
methods=[
|
95
|
+
methods=[
|
96
|
+
AUTH_METHODS["API_KEY"],
|
97
|
+
AUTH_METHODS["JWT"],
|
98
|
+
AUTH_METHODS["CERTIFICATE"],
|
99
|
+
],
|
86
100
|
api_keys={
|
87
101
|
"admin_key_123": {"username": "admin", "roles": ["admin", "user"]},
|
88
102
|
"user_key_456": {"username": "user", "roles": ["user"]},
|
89
|
-
"readonly_key_789": {"username": "readonly", "roles": ["readonly"]}
|
103
|
+
"readonly_key_789": {"username": "readonly", "roles": ["readonly"]},
|
90
104
|
},
|
91
|
-
jwt_secret="your-super-secret-jwt-key-change-in-production",
|
105
|
+
jwt_secret="your-super-secret-jwt-key-change-in-production-12345",
|
92
106
|
jwt_algorithm="HS256",
|
93
107
|
jwt_expiry_hours=24,
|
94
|
-
public_paths=["/health", "/metrics"],
|
95
|
-
security_headers=DEFAULT_SECURITY_HEADERS
|
108
|
+
public_paths=["/health/", "/metrics/"],
|
109
|
+
security_headers=DEFAULT_SECURITY_HEADERS,
|
96
110
|
),
|
97
|
-
|
111
|
+
permissions=PermissionConfig(
|
98
112
|
enabled=True,
|
99
|
-
|
100
|
-
|
101
|
-
|
113
|
+
roles_file="config/roles.json",
|
114
|
+
default_role="user",
|
115
|
+
hierarchy_enabled=True,
|
116
|
+
),
|
117
|
+
ssl=SSLConfig(
|
118
|
+
enabled=False, # Disable for standalone example
|
119
|
+
cert_file=None,
|
120
|
+
key_file=None,
|
121
|
+
ca_cert_file=None,
|
102
122
|
verify_mode="CERT_REQUIRED",
|
103
|
-
min_version="TLSv1.2"
|
123
|
+
min_version="TLSv1.2",
|
104
124
|
),
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
"
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
"
|
124
|
-
"
|
125
|
-
"
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
125
|
+
certificates=CertificateConfig(
|
126
|
+
enabled=False, # Disable for standalone example
|
127
|
+
ca_cert_path=None,
|
128
|
+
ca_key_path=None,
|
129
|
+
cert_validity_days=365,
|
130
|
+
key_size=2048,
|
131
|
+
),
|
132
|
+
rate_limit=RateLimitConfig(
|
133
|
+
enabled=True,
|
134
|
+
default_requests_per_minute=60,
|
135
|
+
default_requests_per_hour=1000,
|
136
|
+
burst_limit=2,
|
137
|
+
window_size_seconds=60,
|
138
|
+
storage_backend="memory",
|
139
|
+
cleanup_interval=300,
|
140
|
+
),
|
141
|
+
logging=LoggingConfig(
|
142
|
+
enabled=True,
|
143
|
+
level="INFO",
|
144
|
+
format="%(asctime)s - %(name)s - %(levelname)s - %(message)s",
|
145
|
+
file_path="logs/security.log",
|
146
|
+
max_file_size=10,
|
147
|
+
backup_count=5,
|
148
|
+
console_output=True,
|
149
|
+
json_format=False,
|
150
|
+
),
|
151
|
+
debug=True,
|
152
|
+
environment="test",
|
153
|
+
version="1.0.0",
|
154
|
+
)
|
155
|
+
|
156
|
+
def _create_test_jwt_token(self) -> str:
|
157
|
+
"""Create a test JWT token."""
|
158
|
+
import jwt
|
159
|
+
|
160
|
+
payload = {
|
161
|
+
"username": "test_user",
|
162
|
+
"roles": ["user"],
|
163
|
+
"exp": datetime.now(timezone.utc) + timedelta(hours=1),
|
164
|
+
}
|
165
|
+
jwt_secret = (
|
166
|
+
self.config.auth.jwt_secret.get_secret_value()
|
167
|
+
if self.config.auth.jwt_secret
|
168
|
+
else "default-jwt-secret-for-testing"
|
137
169
|
)
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
|
170
|
+
return jwt.encode(payload, jwt_secret, algorithm="HS256")
|
171
|
+
|
172
|
+
def _create_test_certificate(self) -> str:
|
173
|
+
"""Create a test certificate."""
|
174
|
+
return """-----BEGIN CERTIFICATE-----
|
175
|
+
MIIDXTCCAkWgAwIBAgIJAKoK8sJgKqQqMA0GCSqGSIb3DQEBCwUAMEUxCzAJBgNV
|
176
|
+
BAYTAkFVMRMwEQYDVQQIDApTb21lLVN0YXRlMSEwHwYDVQQKDBhJbnRlcm5ldCBX
|
177
|
+
aWRnaXRzIFB0eSBMdGQwHhcNMTkwMzI2MTIzMzQ5WhcNMjAwMzI1MTIzMzQ5WjBF
|
178
|
+
MQswCQYDVQQGEwJBVTETMBEGA1UECAwKU29tZS1TdGF0ZTEhMB8GA1UECgwYSW50
|
179
|
+
ZXJuZXQgV2lkZ2l0cyBQdHkgTHRkMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIB
|
180
|
+
CgKCAQEAvxL8JgKqQqMA0GCSqGSIb3DQEBCwUAMEUxCzAJBgNVBAYTAkFVMRMw
|
181
|
+
EQYDVQQIDApTb21lLVN0YXRlMSEwHwYDVQQKDBhJbnRlcm5ldCBXaWRnaXRzIFB0
|
182
|
+
eSBMdGQwHhcNMTkwMzI2MTIzMzQ5WhcNMjAwMzI1MTIzMzQ5WjBFMQswCQYDVQQG
|
183
|
+
EwJBVTETMBEGA1UECAwKU29tZS1TdGF0ZTEhMB8GA1UECgwYSW50ZXJuZXQgV2lk
|
184
|
+
Z2l0cyBQdHkgTHRkMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA
|
185
|
+
-----END CERTIFICATE-----"""
|
186
|
+
|
187
|
+
def demonstrate_authentication(self) -> Dict[str, Any]:
|
188
|
+
"""
|
189
|
+
Demonstrate ALL authentication methods.
|
190
|
+
|
191
|
+
Returns:
|
192
|
+
Dict with authentication test results
|
193
|
+
"""
|
194
|
+
self.logger.info("Demonstrating authentication capabilities...")
|
195
|
+
|
196
|
+
results = {
|
197
|
+
"api_key_auth": {},
|
198
|
+
"jwt_auth": {},
|
199
|
+
"certificate_auth": {},
|
200
|
+
"failed_auth": {},
|
201
|
+
}
|
202
|
+
|
203
|
+
# 1. API Key Authentication
|
204
|
+
try:
|
205
|
+
auth_result = self.security_manager.authenticate_user(
|
206
|
+
{"method": "api_key", "api_key": self.test_api_key}
|
149
207
|
)
|
150
|
-
|
151
|
-
|
208
|
+
results["api_key_auth"] = {
|
209
|
+
"success": auth_result.is_valid,
|
210
|
+
"username": auth_result.username,
|
211
|
+
"roles": auth_result.roles,
|
212
|
+
"auth_method": auth_result.auth_method.value,
|
213
|
+
}
|
214
|
+
self.logger.info(
|
215
|
+
f"API Key auth: {auth_result.username} - {auth_result.roles}"
|
216
|
+
)
|
217
|
+
except Exception as e:
|
218
|
+
results["api_key_auth"] = {"error": str(e)}
|
219
|
+
|
220
|
+
# 2. JWT Authentication
|
221
|
+
try:
|
222
|
+
auth_result = self.security_manager.authenticate_user(
|
223
|
+
{"method": "jwt", "token": self.test_jwt_token}
|
224
|
+
)
|
225
|
+
results["jwt_auth"] = {
|
226
|
+
"success": auth_result.is_valid,
|
227
|
+
"username": auth_result.username,
|
228
|
+
"roles": auth_result.roles,
|
229
|
+
"auth_method": auth_result.auth_method.value,
|
230
|
+
}
|
231
|
+
self.logger.info(f"JWT auth: {auth_result.username} - {auth_result.roles}")
|
232
|
+
except Exception as e:
|
233
|
+
results["jwt_auth"] = {"error": str(e)}
|
234
|
+
|
235
|
+
# 3. Certificate Authentication
|
236
|
+
try:
|
237
|
+
auth_result = self.security_manager.authenticate_user(
|
238
|
+
{"method": "certificate", "certificate": self.test_certificate}
|
239
|
+
)
|
240
|
+
results["certificate_auth"] = {
|
241
|
+
"success": auth_result.is_valid,
|
242
|
+
"username": auth_result.username,
|
243
|
+
"roles": auth_result.roles,
|
244
|
+
"auth_method": auth_result.auth_method.value,
|
245
|
+
}
|
246
|
+
self.logger.info(
|
247
|
+
f"Certificate auth: {auth_result.username} - {auth_result.roles}"
|
248
|
+
)
|
249
|
+
except Exception as e:
|
250
|
+
results["certificate_auth"] = {"error": str(e)}
|
251
|
+
|
252
|
+
# 4. Failed Authentication
|
253
|
+
try:
|
254
|
+
auth_result = self.security_manager.authenticate_user(
|
255
|
+
{"method": "api_key", "api_key": "invalid_key"}
|
256
|
+
)
|
257
|
+
results["failed_auth"] = {
|
258
|
+
"success": auth_result.is_valid,
|
259
|
+
"error_message": auth_result.error_message,
|
260
|
+
"error_code": auth_result.error_code,
|
261
|
+
}
|
262
|
+
self.logger.info(f"Failed auth test: {auth_result.error_message}")
|
263
|
+
except Exception as e:
|
264
|
+
results["failed_auth"] = {"error": str(e)}
|
265
|
+
|
266
|
+
return results
|
267
|
+
|
268
|
+
def demonstrate_authorization(self) -> Dict[str, Any]:
|
152
269
|
"""
|
153
|
-
|
154
|
-
|
155
|
-
Args:
|
156
|
-
credentials: User credentials (api_key, jwt_token, or certificate)
|
157
|
-
|
270
|
+
Demonstrate authorization capabilities.
|
271
|
+
|
158
272
|
Returns:
|
159
|
-
|
273
|
+
Dict with authorization test results
|
160
274
|
"""
|
275
|
+
self.logger.info("Demonstrating authorization capabilities...")
|
276
|
+
|
277
|
+
results = {
|
278
|
+
"admin_permissions": {},
|
279
|
+
"user_permissions": {},
|
280
|
+
"readonly_permissions": {},
|
281
|
+
"denied_permissions": {},
|
282
|
+
}
|
283
|
+
|
284
|
+
# 1. Admin permissions
|
161
285
|
try:
|
162
|
-
|
163
|
-
|
164
|
-
|
165
|
-
|
166
|
-
|
167
|
-
|
168
|
-
|
169
|
-
|
170
|
-
is_valid=False,
|
171
|
-
status=AuthStatus.FAILED,
|
172
|
-
username=None,
|
173
|
-
roles=[],
|
174
|
-
auth_method=None,
|
175
|
-
error_code=ErrorCodes.AUTHENTICATION_ERROR,
|
176
|
-
error_message="No valid credentials provided"
|
177
|
-
)
|
286
|
+
result = self.security_manager.check_permissions(
|
287
|
+
["admin"], ["read", "write", "delete"]
|
288
|
+
)
|
289
|
+
results["admin_permissions"] = {
|
290
|
+
"success": result.is_valid,
|
291
|
+
"status": result.status.value,
|
292
|
+
}
|
293
|
+
self.logger.info(f"Admin permissions: {result.is_valid}")
|
178
294
|
except Exception as e:
|
179
|
-
|
180
|
-
|
181
|
-
|
182
|
-
|
183
|
-
|
184
|
-
|
185
|
-
auth_method=None,
|
186
|
-
error_code=ErrorCodes.AUTHENTICATION_ERROR,
|
187
|
-
error_message=str(e)
|
295
|
+
results["admin_permissions"] = {"error": str(e)}
|
296
|
+
|
297
|
+
# 2. User permissions
|
298
|
+
try:
|
299
|
+
result = self.security_manager.check_permissions(
|
300
|
+
["user"], ["read", "write"]
|
188
301
|
)
|
189
|
-
|
190
|
-
|
302
|
+
results["user_permissions"] = {
|
303
|
+
"success": result.is_valid,
|
304
|
+
"status": result.status.value,
|
305
|
+
}
|
306
|
+
self.logger.info(f"User permissions: {result.is_valid}")
|
307
|
+
except Exception as e:
|
308
|
+
results["user_permissions"] = {"error": str(e)}
|
309
|
+
|
310
|
+
# 3. Readonly permissions
|
311
|
+
try:
|
312
|
+
result = self.security_manager.check_permissions(["readonly"], ["read"])
|
313
|
+
results["readonly_permissions"] = {
|
314
|
+
"success": result.is_valid,
|
315
|
+
"status": result.status.value,
|
316
|
+
}
|
317
|
+
self.logger.info(f"Readonly permissions: {result.is_valid}")
|
318
|
+
except Exception as e:
|
319
|
+
results["readonly_permissions"] = {"error": str(e)}
|
320
|
+
|
321
|
+
# 4. Denied permissions
|
322
|
+
try:
|
323
|
+
result = self.security_manager.check_permissions(["readonly"], ["delete"])
|
324
|
+
results["denied_permissions"] = {
|
325
|
+
"success": result.is_valid,
|
326
|
+
"status": result.status.value,
|
327
|
+
"error_message": result.error_message,
|
328
|
+
}
|
329
|
+
self.logger.info(f"Denied permissions: {result.is_valid}")
|
330
|
+
except Exception as e:
|
331
|
+
results["denied_permissions"] = {"error": str(e)}
|
332
|
+
|
333
|
+
return results
|
334
|
+
|
335
|
+
def demonstrate_rate_limiting(self) -> Dict[str, Any]:
|
191
336
|
"""
|
192
|
-
|
193
|
-
|
194
|
-
|
195
|
-
|
196
|
-
|
197
|
-
|
337
|
+
Demonstrate rate limiting capabilities.
|
338
|
+
|
339
|
+
Returns:
|
340
|
+
Dict with rate limiting test results
|
341
|
+
"""
|
342
|
+
self.logger.info("Demonstrating rate limiting capabilities...")
|
343
|
+
|
344
|
+
results = {"rate_limit_checks": [], "rate_limit_exceeded": False}
|
345
|
+
|
346
|
+
identifier = "test_user_123"
|
347
|
+
|
348
|
+
# Test rate limiting
|
349
|
+
for i in range(5):
|
350
|
+
try:
|
351
|
+
allowed = self.security_manager.check_rate_limit(identifier)
|
352
|
+
results["rate_limit_checks"].append(
|
353
|
+
{"request": i + 1, "allowed": allowed}
|
354
|
+
)
|
355
|
+
self.logger.info(
|
356
|
+
f"Rate limit check {i+1}: {'Allowed' if allowed else 'Blocked'}"
|
357
|
+
)
|
358
|
+
|
359
|
+
if not allowed:
|
360
|
+
results["rate_limit_exceeded"] = True
|
361
|
+
break
|
362
|
+
|
363
|
+
except Exception as e:
|
364
|
+
results["rate_limit_checks"].append({"request": i + 1, "error": str(e)})
|
365
|
+
|
366
|
+
return results
|
367
|
+
|
368
|
+
def demonstrate_certificate_management(self) -> Dict[str, Any]:
|
369
|
+
"""
|
370
|
+
Demonstrate certificate management capabilities.
|
371
|
+
|
198
372
|
Returns:
|
199
|
-
|
373
|
+
Dict with certificate management test results
|
200
374
|
"""
|
375
|
+
self.logger.info("Demonstrating certificate management capabilities...")
|
376
|
+
|
377
|
+
results = {
|
378
|
+
"certificate_creation": {},
|
379
|
+
"certificate_validation": {},
|
380
|
+
"certificate_info": {},
|
381
|
+
}
|
382
|
+
|
383
|
+
# 1. Certificate creation (if enabled)
|
384
|
+
if self.config.certificates.enabled:
|
385
|
+
try:
|
386
|
+
cert_config = {
|
387
|
+
"cert_type": "client",
|
388
|
+
"common_name": "test-client.example.com",
|
389
|
+
"organization": "Test Organization",
|
390
|
+
"country": "US",
|
391
|
+
"validity_days": 365,
|
392
|
+
}
|
393
|
+
|
394
|
+
# Note: This would require actual CA files
|
395
|
+
# cert_pair = self.security_manager.create_certificate(cert_config)
|
396
|
+
results["certificate_creation"] = {
|
397
|
+
"success": True,
|
398
|
+
"message": "Certificate creation capability demonstrated",
|
399
|
+
}
|
400
|
+
self.logger.info("Certificate creation capability demonstrated")
|
401
|
+
except Exception as e:
|
402
|
+
results["certificate_creation"] = {"error": str(e)}
|
403
|
+
|
404
|
+
# 2. Certificate validation
|
201
405
|
try:
|
202
|
-
|
203
|
-
|
406
|
+
# Test with dummy certificate
|
407
|
+
cert_info = CertificateInfo(
|
408
|
+
subject="test-client.example.com",
|
409
|
+
issuer="Test CA",
|
410
|
+
serial_number="123456789",
|
411
|
+
valid_from=datetime.now(timezone.utc),
|
412
|
+
valid_until=datetime.now(timezone.utc) + timedelta(days=365),
|
413
|
+
is_valid=True,
|
204
414
|
)
|
415
|
+
results["certificate_validation"] = {
|
416
|
+
"success": True,
|
417
|
+
"certificate_info": {
|
418
|
+
"subject": cert_info.subject,
|
419
|
+
"issuer": cert_info.issuer,
|
420
|
+
"is_valid": cert_info.is_valid,
|
421
|
+
},
|
422
|
+
}
|
423
|
+
self.logger.info("Certificate validation capability demonstrated")
|
205
424
|
except Exception as e:
|
206
|
-
|
207
|
-
|
208
|
-
|
209
|
-
|
425
|
+
results["certificate_validation"] = {"error": str(e)}
|
426
|
+
|
427
|
+
return results
|
428
|
+
|
429
|
+
def demonstrate_security_validation(self) -> Dict[str, Any]:
|
210
430
|
"""
|
211
|
-
|
212
|
-
|
213
|
-
|
214
|
-
|
215
|
-
|
431
|
+
Demonstrate security validation capabilities.
|
432
|
+
|
433
|
+
Returns:
|
434
|
+
Dict with validation test results
|
435
|
+
"""
|
436
|
+
self.logger.info("Demonstrating security validation capabilities...")
|
437
|
+
|
438
|
+
results = {"request_validation": {}, "configuration_validation": {}}
|
439
|
+
|
440
|
+
# 1. Request validation
|
441
|
+
try:
|
442
|
+
request_data = {
|
443
|
+
"api_key": self.test_api_key,
|
444
|
+
"required_permissions": ["read", "write"],
|
445
|
+
"client_ip": "192.168.1.100",
|
446
|
+
}
|
447
|
+
|
448
|
+
result = self.security_manager.validate_request(request_data)
|
449
|
+
results["request_validation"] = {
|
450
|
+
"success": result.is_valid,
|
451
|
+
"status": result.status.value,
|
452
|
+
}
|
453
|
+
self.logger.info(f"Request validation: {result.is_valid}")
|
454
|
+
except Exception as e:
|
455
|
+
results["request_validation"] = {"error": str(e)}
|
456
|
+
|
457
|
+
# 2. Configuration validation
|
458
|
+
try:
|
459
|
+
result = self.security_manager.validate_configuration()
|
460
|
+
results["configuration_validation"] = {
|
461
|
+
"success": result.is_valid,
|
462
|
+
"status": result.status.value,
|
463
|
+
}
|
464
|
+
self.logger.info(f"Configuration validation: {result.is_valid}")
|
465
|
+
except Exception as e:
|
466
|
+
results["configuration_validation"] = {"error": str(e)}
|
467
|
+
|
468
|
+
return results
|
469
|
+
|
470
|
+
def demonstrate_security_monitoring(self) -> Dict[str, Any]:
|
471
|
+
"""
|
472
|
+
Demonstrate security monitoring capabilities.
|
473
|
+
|
216
474
|
Returns:
|
217
|
-
|
475
|
+
Dict with monitoring test results
|
218
476
|
"""
|
477
|
+
self.logger.info("Demonstrating security monitoring capabilities...")
|
478
|
+
|
479
|
+
results = {"security_status": {}, "security_metrics": {}, "security_audit": {}}
|
480
|
+
|
481
|
+
# 1. Security status
|
482
|
+
try:
|
483
|
+
status = self.security_manager.get_security_status()
|
484
|
+
results["security_status"] = {
|
485
|
+
"status": status.status.value,
|
486
|
+
"message": status.message,
|
487
|
+
"version": status.version,
|
488
|
+
"metadata": status.metadata,
|
489
|
+
}
|
490
|
+
print(f"Security status: {results['security_status']}")
|
491
|
+
self.logger.info("Security status retrieved successfully")
|
492
|
+
except Exception as e:
|
493
|
+
results["security_status"] = {"error": str(e)}
|
494
|
+
print(f"Security status error: {str(e)}")
|
495
|
+
|
496
|
+
# 2. Security metrics
|
497
|
+
try:
|
498
|
+
metrics = self.security_manager.get_security_metrics()
|
499
|
+
results["security_metrics"] = {
|
500
|
+
"authentication_attempts": metrics.get("authentication_attempts", 0),
|
501
|
+
"security_events": metrics.get("security_events", 0),
|
502
|
+
"uptime_seconds": metrics.get("uptime_seconds", 0),
|
503
|
+
}
|
504
|
+
self.logger.info("Security metrics retrieved successfully")
|
505
|
+
except Exception as e:
|
506
|
+
results["security_metrics"] = {"error": str(e)}
|
507
|
+
|
508
|
+
# 3. Security audit
|
219
509
|
try:
|
220
|
-
|
510
|
+
audit = self.security_manager.perform_security_audit()
|
511
|
+
results["security_audit"] = {
|
512
|
+
"authentication": audit.get("authentication", {}),
|
513
|
+
"authorization": audit.get("authorization", {}),
|
514
|
+
"rate_limiting": audit.get("rate_limiting", {}),
|
515
|
+
"ssl": audit.get("ssl", {}),
|
516
|
+
}
|
517
|
+
self.logger.info("Security audit completed successfully")
|
221
518
|
except Exception as e:
|
222
|
-
|
223
|
-
|
224
|
-
|
519
|
+
results["security_audit"] = {"error": str(e)}
|
520
|
+
|
521
|
+
return results
|
522
|
+
|
523
|
+
def run_comprehensive_demo(self) -> Dict[str, Any]:
|
524
|
+
"""
|
525
|
+
Run comprehensive demonstration of ALL framework capabilities.
|
526
|
+
|
527
|
+
Returns:
|
528
|
+
Dict with all demonstration results
|
529
|
+
"""
|
530
|
+
self.logger.info("Starting comprehensive security framework demonstration...")
|
531
|
+
|
532
|
+
demo_results = {
|
533
|
+
"timestamp": datetime.now(timezone.utc).isoformat(),
|
534
|
+
"framework": "MCP Security Framework",
|
535
|
+
"version": "1.0.0",
|
536
|
+
"authentication": self.demonstrate_authentication(),
|
537
|
+
"authorization": self.demonstrate_authorization(),
|
538
|
+
"rate_limiting": self.demonstrate_rate_limiting(),
|
539
|
+
"certificate_management": self.demonstrate_certificate_management(),
|
540
|
+
"security_validation": self.demonstrate_security_validation(),
|
541
|
+
"security_monitoring": self.demonstrate_security_monitoring(),
|
542
|
+
}
|
543
|
+
|
544
|
+
self.logger.info("Comprehensive demonstration completed successfully")
|
545
|
+
return demo_results
|
546
|
+
|
225
547
|
def process_request(self, request_data: Dict[str, Any]) -> Dict[str, Any]:
|
226
548
|
"""
|
227
|
-
Process a
|
228
|
-
|
549
|
+
Process a security request.
|
550
|
+
|
229
551
|
Args:
|
230
|
-
request_data:
|
231
|
-
|
552
|
+
request_data: Dictionary containing request information
|
553
|
+
- credentials: Authentication credentials
|
554
|
+
- action: Request action (read, write, delete)
|
555
|
+
- resource: Resource being accessed
|
556
|
+
- identifier: Client identifier for rate limiting
|
557
|
+
- data: Optional data for write operations
|
558
|
+
|
232
559
|
Returns:
|
233
|
-
|
560
|
+
Dictionary with processing results
|
234
561
|
"""
|
235
562
|
try:
|
236
|
-
# Extract request
|
563
|
+
# Extract request information
|
237
564
|
credentials = request_data.get("credentials", {})
|
238
|
-
action = request_data.get("action", "")
|
239
|
-
resource = request_data.get("resource", "")
|
240
|
-
identifier = request_data.get("identifier",
|
241
|
-
|
242
|
-
|
243
|
-
|
565
|
+
action = request_data.get("action", "read")
|
566
|
+
resource = request_data.get("resource", "/")
|
567
|
+
identifier = request_data.get("identifier", "unknown")
|
568
|
+
data = request_data.get("data")
|
569
|
+
|
570
|
+
# Check rate limiting
|
571
|
+
rate_limit_result = self.security_manager.check_rate_limit(identifier)
|
572
|
+
if not rate_limit_result:
|
244
573
|
return {
|
245
574
|
"success": False,
|
575
|
+
"status_code": 429,
|
246
576
|
"error": "Rate limit exceeded",
|
247
|
-
"
|
248
|
-
"timestamp": datetime.utcnow().isoformat()
|
577
|
+
"retry_after": 60,
|
249
578
|
}
|
250
|
-
|
251
|
-
#
|
252
|
-
auth_result =
|
253
|
-
if
|
579
|
+
|
580
|
+
# Authenticate request
|
581
|
+
auth_result = None
|
582
|
+
if "api_key" in credentials:
|
583
|
+
auth_result = self.security_manager.authenticate_user(
|
584
|
+
{"method": "api_key", "api_key": credentials["api_key"]}
|
585
|
+
)
|
586
|
+
elif "jwt_token" in credentials:
|
587
|
+
auth_result = self.security_manager.authenticate_user(
|
588
|
+
{"method": "jwt", "token": credentials["jwt_token"]}
|
589
|
+
)
|
590
|
+
elif "certificate" in credentials:
|
591
|
+
auth_result = self.security_manager.authenticate_user(
|
592
|
+
{"method": "certificate", "certificate": credentials["certificate"]}
|
593
|
+
)
|
594
|
+
|
595
|
+
# Check authentication
|
596
|
+
if not auth_result or not auth_result.is_valid:
|
254
597
|
return {
|
255
598
|
"success": False,
|
599
|
+
"status_code": 401,
|
256
600
|
"error": "Authentication failed",
|
257
|
-
"
|
258
|
-
"error_message": auth_result.error_message,
|
259
|
-
"timestamp": datetime.utcnow().isoformat()
|
601
|
+
"auth_result": auth_result.model_dump() if auth_result else None,
|
260
602
|
}
|
261
|
-
|
262
|
-
#
|
603
|
+
|
604
|
+
# Check authorization
|
263
605
|
required_permissions = self._get_required_permissions(action, resource)
|
264
|
-
|
606
|
+
authz_result = self.security_manager.check_permissions(
|
607
|
+
auth_result.roles, required_permissions
|
608
|
+
)
|
609
|
+
|
610
|
+
if not authz_result.is_valid:
|
265
611
|
return {
|
266
612
|
"success": False,
|
267
|
-
"
|
268
|
-
"
|
269
|
-
"
|
613
|
+
"status_code": 403,
|
614
|
+
"error": "Authorization failed",
|
615
|
+
"auth_result": auth_result.model_dump(),
|
616
|
+
"authz_result": authz_result.model_dump(),
|
270
617
|
}
|
271
|
-
|
272
|
-
#
|
273
|
-
result =
|
274
|
-
|
275
|
-
# Step 5: Log security event
|
276
|
-
self._log_security_event("request_processed", {
|
277
|
-
"username": auth_result.username,
|
278
|
-
"action": action,
|
279
|
-
"resource": resource,
|
280
|
-
"success": True,
|
281
|
-
"timestamp": datetime.utcnow().isoformat()
|
282
|
-
})
|
283
|
-
|
284
|
-
return {
|
618
|
+
|
619
|
+
# Process the request
|
620
|
+
result = {
|
285
621
|
"success": True,
|
286
|
-
"
|
287
|
-
"
|
288
|
-
|
289
|
-
|
290
|
-
|
291
|
-
|
292
|
-
"timestamp": datetime.utcnow().isoformat()
|
622
|
+
"status_code": 200,
|
623
|
+
"auth_result": auth_result.model_dump(),
|
624
|
+
"authz_result": authz_result.model_dump(),
|
625
|
+
"data": data if action == "write" else None,
|
626
|
+
"resource": resource,
|
627
|
+
"action": action,
|
293
628
|
}
|
294
|
-
|
629
|
+
|
630
|
+
# Log the successful request
|
631
|
+
self.logger.info(f"Request processed successfully: {action} {resource}")
|
632
|
+
|
633
|
+
return result
|
634
|
+
|
295
635
|
except Exception as e:
|
296
|
-
self.logger.error(f"
|
636
|
+
self.logger.error(f"Error processing request: {str(e)}")
|
297
637
|
return {
|
298
638
|
"success": False,
|
299
|
-
"
|
300
|
-
"
|
301
|
-
"timestamp": datetime.utcnow().isoformat()
|
639
|
+
"status_code": 500,
|
640
|
+
"error": f"Internal server error: {str(e)}",
|
302
641
|
}
|
303
|
-
|
642
|
+
|
304
643
|
def _get_required_permissions(self, action: str, resource: str) -> List[str]:
|
305
|
-
"""
|
306
|
-
Get required permissions for action and resource.
|
307
|
-
|
308
|
-
Args:
|
309
|
-
action: Action to perform
|
310
|
-
resource: Resource to access
|
311
|
-
|
312
|
-
Returns:
|
313
|
-
List[str]: Required permissions
|
314
|
-
"""
|
315
|
-
# Define permission mappings
|
316
|
-
permission_mappings = {
|
317
|
-
"read": ["read"],
|
318
|
-
"write": ["read", "write"],
|
319
|
-
"delete": ["read", "write", "delete"],
|
320
|
-
"admin": ["admin"],
|
321
|
-
"create": ["read", "write"],
|
322
|
-
"update": ["read", "write"]
|
323
|
-
}
|
324
|
-
|
325
|
-
return permission_mappings.get(action, ["read"])
|
326
|
-
|
327
|
-
def _execute_action(self, action: str, resource: str, data: Dict[str, Any]) -> Dict[str, Any]:
|
328
|
-
"""
|
329
|
-
Execute the requested action.
|
330
|
-
|
331
|
-
Args:
|
332
|
-
action: Action to perform
|
333
|
-
resource: Resource to access
|
334
|
-
data: Action data
|
335
|
-
|
336
|
-
Returns:
|
337
|
-
Dict[str, Any]: Action result
|
338
|
-
"""
|
339
|
-
# Simulate different actions
|
644
|
+
"""Get required permissions for action and resource."""
|
340
645
|
if action == "read":
|
341
|
-
return
|
646
|
+
return ["read"]
|
342
647
|
elif action == "write":
|
343
|
-
return
|
648
|
+
return ["write"]
|
344
649
|
elif action == "delete":
|
345
|
-
return
|
346
|
-
elif action == "
|
347
|
-
return
|
348
|
-
elif action == "update":
|
349
|
-
return {"resource": resource, "data": data, "status": "updated"}
|
650
|
+
return ["delete"]
|
651
|
+
elif action == "admin":
|
652
|
+
return ["admin"]
|
350
653
|
else:
|
351
|
-
return
|
352
|
-
|
353
|
-
def _log_security_event(self, event_type: str, details: Dict[str, Any]):
|
354
|
-
"""
|
355
|
-
Log security event.
|
356
|
-
|
357
|
-
Args:
|
358
|
-
event_type: Type of security event
|
359
|
-
details: Event details
|
360
|
-
"""
|
361
|
-
try:
|
362
|
-
self.logger.info(
|
363
|
-
f"Security event: {event_type}",
|
364
|
-
extra={
|
365
|
-
"event_type": event_type,
|
366
|
-
"timestamp": details.get("timestamp"),
|
367
|
-
"username": details.get("username"),
|
368
|
-
"action": details.get("action"),
|
369
|
-
"resource": details.get("resource"),
|
370
|
-
"success": details.get("success"),
|
371
|
-
**details
|
372
|
-
}
|
373
|
-
)
|
374
|
-
except Exception as e:
|
375
|
-
self.logger.error(f"Failed to log security event: {str(e)}")
|
376
|
-
|
377
|
-
def generate_api_key(self, username: str, roles: List[str]) -> str:
|
378
|
-
"""
|
379
|
-
Generate API key for user.
|
380
|
-
|
381
|
-
Args:
|
382
|
-
username: Username
|
383
|
-
roles: User roles
|
384
|
-
|
385
|
-
Returns:
|
386
|
-
str: Generated API key
|
387
|
-
"""
|
388
|
-
try:
|
389
|
-
api_key = self.security_manager.auth_manager.generate_api_key()
|
390
|
-
# Store the API key (in production, this would be in a database)
|
391
|
-
self.config.auth.api_keys[api_key] = {
|
392
|
-
"username": username,
|
393
|
-
"roles": roles
|
394
|
-
}
|
395
|
-
return api_key
|
396
|
-
except Exception as e:
|
397
|
-
self.logger.error(f"Failed to generate API key: {str(e)}")
|
398
|
-
raise
|
399
|
-
|
400
|
-
def create_jwt_token(self, username: str, roles: List[str], expiry_hours: int = 24) -> str:
|
401
|
-
"""
|
402
|
-
Create JWT token for user.
|
403
|
-
|
404
|
-
Args:
|
405
|
-
username: Username
|
406
|
-
roles: User roles
|
407
|
-
expiry_hours: Token expiry in hours
|
408
|
-
|
409
|
-
Returns:
|
410
|
-
str: Generated JWT token
|
411
|
-
"""
|
412
|
-
try:
|
413
|
-
user_data = {
|
414
|
-
"username": username,
|
415
|
-
"roles": roles,
|
416
|
-
"exp": datetime.utcnow() + timedelta(hours=expiry_hours)
|
417
|
-
}
|
418
|
-
return self.security_manager.auth_manager.create_jwt_token(user_data)
|
419
|
-
except Exception as e:
|
420
|
-
self.logger.error(f"Failed to create JWT token: {str(e)}")
|
421
|
-
raise
|
422
|
-
|
423
|
-
def validate_certificate(self, certificate_path: str) -> bool:
|
424
|
-
"""
|
425
|
-
Validate certificate.
|
426
|
-
|
427
|
-
Args:
|
428
|
-
certificate_path: Path to certificate file
|
429
|
-
|
430
|
-
Returns:
|
431
|
-
bool: True if certificate is valid
|
432
|
-
"""
|
433
|
-
try:
|
434
|
-
return self.security_manager.ssl_manager.validate_certificate(certificate_path)
|
435
|
-
except Exception as e:
|
436
|
-
self.logger.error(f"Certificate validation failed: {str(e)}")
|
437
|
-
return False
|
438
|
-
|
439
|
-
def get_security_status(self) -> Dict[str, Any]:
|
440
|
-
"""
|
441
|
-
Get security framework status.
|
442
|
-
|
443
|
-
Returns:
|
444
|
-
Dict[str, Any]: Security status information
|
445
|
-
"""
|
446
|
-
return {
|
447
|
-
"ssl_enabled": self.config.ssl.enabled,
|
448
|
-
"auth_enabled": self.config.auth.enabled,
|
449
|
-
"rate_limiting_enabled": self.config.rate_limit.enabled,
|
450
|
-
"permissions_enabled": self.config.permissions.enabled,
|
451
|
-
"logging_enabled": self.config.logging.enabled,
|
452
|
-
"auth_methods": self.config.auth.methods,
|
453
|
-
"timestamp": datetime.utcnow().isoformat()
|
454
|
-
}
|
654
|
+
return ["read"]
|
455
655
|
|
456
656
|
|
457
|
-
# Example usage and testing
|
458
657
|
class StandaloneExampleTest:
|
459
|
-
"""Test class for standalone example
|
460
|
-
|
461
|
-
|
462
|
-
|
463
|
-
|
464
|
-
|
465
|
-
|
466
|
-
#
|
467
|
-
|
468
|
-
|
469
|
-
assert
|
470
|
-
|
471
|
-
|
472
|
-
|
473
|
-
|
474
|
-
|
475
|
-
|
476
|
-
|
477
|
-
|
478
|
-
|
479
|
-
|
480
|
-
|
481
|
-
|
482
|
-
|
483
|
-
|
484
|
-
|
485
|
-
#
|
486
|
-
assert
|
487
|
-
|
488
|
-
#
|
489
|
-
assert
|
490
|
-
|
491
|
-
#
|
492
|
-
assert
|
493
|
-
|
494
|
-
|
495
|
-
|
496
|
-
|
497
|
-
|
498
|
-
|
499
|
-
|
500
|
-
|
501
|
-
|
502
|
-
|
503
|
-
|
504
|
-
|
505
|
-
|
506
|
-
|
507
|
-
|
508
|
-
|
509
|
-
|
510
|
-
|
511
|
-
|
512
|
-
|
513
|
-
|
514
|
-
|
515
|
-
#
|
516
|
-
|
517
|
-
|
518
|
-
|
519
|
-
|
520
|
-
|
521
|
-
|
522
|
-
|
523
|
-
|
524
|
-
|
525
|
-
|
526
|
-
|
527
|
-
|
528
|
-
|
529
|
-
|
530
|
-
|
531
|
-
|
532
|
-
|
533
|
-
|
534
|
-
|
535
|
-
|
536
|
-
|
537
|
-
|
538
|
-
|
539
|
-
|
540
|
-
|
541
|
-
|
542
|
-
|
543
|
-
|
658
|
+
"""Test class for standalone example."""
|
659
|
+
|
660
|
+
def test_authentication(self):
|
661
|
+
"""Test authentication capabilities."""
|
662
|
+
example = StandaloneSecurityExample()
|
663
|
+
results = example.demonstrate_authentication()
|
664
|
+
|
665
|
+
# Verify API key authentication works
|
666
|
+
assert results["api_key_auth"]["success"] == True
|
667
|
+
assert results["api_key_auth"]["username"] == "admin"
|
668
|
+
assert "admin" in results["api_key_auth"]["roles"]
|
669
|
+
|
670
|
+
# Verify JWT authentication works
|
671
|
+
assert results["jwt_auth"]["success"] == True
|
672
|
+
assert results["jwt_auth"]["username"] == "test_user"
|
673
|
+
|
674
|
+
# Verify failed authentication is handled
|
675
|
+
assert results["failed_auth"]["success"] == False
|
676
|
+
|
677
|
+
print("✅ Authentication tests passed")
|
678
|
+
|
679
|
+
def test_authorization(self):
|
680
|
+
"""Test authorization capabilities."""
|
681
|
+
example = StandaloneSecurityExample()
|
682
|
+
results = example.demonstrate_authorization()
|
683
|
+
|
684
|
+
# Verify admin permissions work
|
685
|
+
assert results["admin_permissions"]["success"] == True
|
686
|
+
|
687
|
+
# Verify user permissions work
|
688
|
+
assert results["user_permissions"]["success"] == True
|
689
|
+
|
690
|
+
# Verify readonly permissions work
|
691
|
+
assert results["readonly_permissions"]["success"] == True
|
692
|
+
|
693
|
+
print("✅ Authorization tests passed")
|
694
|
+
|
695
|
+
def test_rate_limiting(self):
|
696
|
+
"""Test rate limiting capabilities."""
|
697
|
+
example = StandaloneSecurityExample()
|
698
|
+
results = example.demonstrate_rate_limiting()
|
699
|
+
|
700
|
+
# Verify rate limiting checks work
|
701
|
+
assert len(results["rate_limit_checks"]) > 0
|
702
|
+
assert results["rate_limit_checks"][0]["allowed"] == True
|
703
|
+
|
704
|
+
print("✅ Rate limiting tests passed")
|
705
|
+
|
706
|
+
def test_security_validation(self):
|
707
|
+
"""Test security validation capabilities."""
|
708
|
+
example = StandaloneSecurityExample()
|
709
|
+
results = example.demonstrate_security_validation()
|
710
|
+
|
711
|
+
# Verify request validation works
|
712
|
+
assert results["request_validation"]["success"] == True
|
713
|
+
|
714
|
+
# Verify configuration validation works
|
715
|
+
assert results["configuration_validation"]["success"] == True
|
716
|
+
|
717
|
+
print("✅ Security validation tests passed")
|
718
|
+
|
719
|
+
def test_security_monitoring(self):
|
720
|
+
"""Test security monitoring capabilities."""
|
721
|
+
example = StandaloneSecurityExample()
|
722
|
+
results = example.demonstrate_security_monitoring()
|
723
|
+
|
724
|
+
# Verify security status works
|
725
|
+
assert "status" in results["security_status"]
|
726
|
+
assert "message" in results["security_status"]
|
727
|
+
|
728
|
+
# Verify security metrics work
|
729
|
+
assert "authentication_attempts" in results["security_metrics"]
|
730
|
+
|
731
|
+
# Verify security audit works
|
732
|
+
assert "authentication" in results["security_audit"]
|
733
|
+
|
734
|
+
print("✅ Security monitoring tests passed")
|
735
|
+
|
736
|
+
|
737
|
+
def main():
|
738
|
+
"""Main function to run the standalone example."""
|
739
|
+
print("\n🚀 MCP Security Framework - Standalone Example")
|
740
|
+
print("=" * 60)
|
741
|
+
|
742
|
+
# Create example instance
|
743
|
+
example = StandaloneSecurityExample()
|
744
|
+
|
745
|
+
# Run comprehensive demonstration
|
746
|
+
results = example.run_comprehensive_demo()
|
747
|
+
|
748
|
+
# Print results
|
749
|
+
print("\n📊 COMPREHENSIVE DEMONSTRATION RESULTS")
|
750
|
+
print("=" * 60)
|
751
|
+
print(f"Framework: {results['framework']}")
|
752
|
+
print(f"Version: {results['version']}")
|
753
|
+
print(f"Timestamp: {results['timestamp']}")
|
754
|
+
|
755
|
+
print("\n🔐 AUTHENTICATION RESULTS:")
|
756
|
+
print(
|
757
|
+
f" API Key: {'✅' if results['authentication']['api_key_auth']['success'] else '❌'}"
|
758
|
+
)
|
759
|
+
print(
|
760
|
+
f" JWT: {'✅' if results['authentication']['jwt_auth']['success'] else '❌'}"
|
761
|
+
)
|
762
|
+
print(
|
763
|
+
f" Certificate: {'✅' if results['authentication']['certificate_auth']['success'] else '❌'}"
|
764
|
+
)
|
765
|
+
|
766
|
+
print("\n🔑 AUTHORIZATION RESULTS:")
|
767
|
+
print(
|
768
|
+
f" Admin Permissions: {'✅' if results['authorization']['admin_permissions']['success'] else '❌'}"
|
769
|
+
)
|
770
|
+
print(
|
771
|
+
f" User Permissions: {'✅' if results['authorization']['user_permissions']['success'] else '❌'}"
|
772
|
+
)
|
773
|
+
print(
|
774
|
+
f" Readonly Permissions: {'✅' if results['authorization']['readonly_permissions']['success'] else '❌'}"
|
775
|
+
)
|
776
|
+
|
777
|
+
print("\n⚡ RATE LIMITING RESULTS:")
|
778
|
+
print(f" Rate Limit Checks: {len(results['rate_limiting']['rate_limit_checks'])}")
|
779
|
+
print(
|
780
|
+
f" Rate Limit Exceeded: {'❌' if results['rate_limiting']['rate_limit_exceeded'] else '✅'}"
|
781
|
+
)
|
782
|
+
|
783
|
+
print("\n🔒 SECURITY VALIDATION RESULTS:")
|
784
|
+
print(
|
785
|
+
f" Request Validation: {'✅' if results['security_validation']['request_validation']['success'] else '❌'}"
|
786
|
+
)
|
787
|
+
print(
|
788
|
+
f" Configuration Validation: {'✅' if results['security_validation']['configuration_validation']['success'] else '❌'}"
|
789
|
+
)
|
790
|
+
|
791
|
+
print("\n📊 SECURITY MONITORING RESULTS:")
|
792
|
+
print(
|
793
|
+
f" Security Status: {'✅' if 'ssl_enabled' in results['security_monitoring']['security_status'] else '❌'}"
|
794
|
+
)
|
795
|
+
print(
|
796
|
+
f" Security Metrics: {'✅' if 'authentication_attempts' in results['security_monitoring']['security_metrics'] else '❌'}"
|
797
|
+
)
|
798
|
+
print(
|
799
|
+
f" Security Audit: {'✅' if 'authentication' in results['security_monitoring']['security_audit'] else '❌'}"
|
800
|
+
)
|
801
|
+
|
802
|
+
print("\n🎉 ALL FRAMEWORK CAPABILITIES DEMONSTRATED SUCCESSFULLY!")
|
803
|
+
print("=" * 60)
|
544
804
|
|
545
805
|
|
546
806
|
if __name__ == "__main__":
|
547
807
|
# Run tests
|
548
808
|
print("Running Standalone Example Tests...")
|
549
|
-
StandaloneExampleTest
|
550
|
-
|
551
|
-
|
552
|
-
|
553
|
-
|
554
|
-
|
555
|
-
|
809
|
+
test = StandaloneExampleTest()
|
810
|
+
test.test_authentication()
|
811
|
+
test.test_authorization()
|
812
|
+
test.test_rate_limiting()
|
813
|
+
test.test_security_validation()
|
814
|
+
test.test_security_monitoring()
|
815
|
+
|
556
816
|
print("\nExample Usage:")
|
557
|
-
|
558
|
-
|
559
|
-
# Generate API key for new user
|
560
|
-
api_key = example.generate_api_key("new_user", ["user"])
|
561
|
-
print(f"Generated API key: {api_key}")
|
562
|
-
|
563
|
-
# Process a request
|
564
|
-
request_data = {
|
565
|
-
"credentials": {"api_key": api_key},
|
566
|
-
"action": "read",
|
567
|
-
"resource": "user_data",
|
568
|
-
"identifier": "192.168.1.100"
|
569
|
-
}
|
570
|
-
|
571
|
-
result = example.process_request(request_data)
|
572
|
-
print(f"Request result: {result}")
|
573
|
-
|
574
|
-
# Get security status
|
575
|
-
status = example.get_security_status()
|
576
|
-
print(f"Security status: {status}")
|
817
|
+
main()
|