mcp-proxy-adapter 6.9.28__py3-none-any.whl → 6.9.29__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.

Potentially problematic release.


This version of mcp-proxy-adapter might be problematic. Click here for more details.

Files changed (212) hide show
  1. mcp_proxy_adapter/__init__.py +10 -0
  2. mcp_proxy_adapter/__main__.py +8 -21
  3. mcp_proxy_adapter/api/app.py +10 -913
  4. mcp_proxy_adapter/api/core/__init__.py +18 -0
  5. mcp_proxy_adapter/api/core/app_factory.py +243 -0
  6. mcp_proxy_adapter/api/core/lifespan_manager.py +55 -0
  7. mcp_proxy_adapter/api/core/registration_manager.py +166 -0
  8. mcp_proxy_adapter/api/core/ssl_context_factory.py +88 -0
  9. mcp_proxy_adapter/api/handlers.py +78 -199
  10. mcp_proxy_adapter/api/middleware/__init__.py +1 -44
  11. mcp_proxy_adapter/api/middleware/base.py +0 -42
  12. mcp_proxy_adapter/api/middleware/command_permission_middleware.py +0 -85
  13. mcp_proxy_adapter/api/middleware/error_handling.py +1 -127
  14. mcp_proxy_adapter/api/middleware/factory.py +0 -94
  15. mcp_proxy_adapter/api/middleware/logging.py +0 -112
  16. mcp_proxy_adapter/api/middleware/performance.py +0 -35
  17. mcp_proxy_adapter/api/middleware/protocol_middleware.py +2 -98
  18. mcp_proxy_adapter/api/middleware/transport_middleware.py +0 -37
  19. mcp_proxy_adapter/api/middleware/unified_security.py +10 -10
  20. mcp_proxy_adapter/api/middleware/user_info_middleware.py +0 -118
  21. mcp_proxy_adapter/api/openapi/__init__.py +21 -0
  22. mcp_proxy_adapter/api/openapi/command_integration.py +105 -0
  23. mcp_proxy_adapter/api/openapi/openapi_generator.py +40 -0
  24. mcp_proxy_adapter/api/openapi/openapi_registry.py +62 -0
  25. mcp_proxy_adapter/api/openapi/schema_loader.py +116 -0
  26. mcp_proxy_adapter/api/schemas.py +0 -61
  27. mcp_proxy_adapter/api/tool_integration.py +0 -117
  28. mcp_proxy_adapter/api/tools.py +0 -46
  29. mcp_proxy_adapter/cli/__init__.py +12 -0
  30. mcp_proxy_adapter/cli/commands/__init__.py +15 -0
  31. mcp_proxy_adapter/cli/commands/client.py +100 -0
  32. mcp_proxy_adapter/cli/commands/config_generate.py +21 -0
  33. mcp_proxy_adapter/cli/commands/config_validate.py +36 -0
  34. mcp_proxy_adapter/cli/commands/generate.py +259 -0
  35. mcp_proxy_adapter/cli/commands/server.py +174 -0
  36. mcp_proxy_adapter/cli/commands/sets.py +128 -0
  37. mcp_proxy_adapter/cli/commands/testconfig.py +177 -0
  38. mcp_proxy_adapter/cli/examples/__init__.py +8 -0
  39. mcp_proxy_adapter/cli/examples/http_basic.py +82 -0
  40. mcp_proxy_adapter/cli/examples/https_token.py +96 -0
  41. mcp_proxy_adapter/cli/examples/mtls_roles.py +103 -0
  42. mcp_proxy_adapter/cli/main.py +63 -0
  43. mcp_proxy_adapter/cli/parser.py +324 -0
  44. mcp_proxy_adapter/cli/validators.py +231 -0
  45. mcp_proxy_adapter/client/jsonrpc_client.py +406 -0
  46. mcp_proxy_adapter/client/proxy.py +45 -0
  47. mcp_proxy_adapter/commands/__init__.py +44 -28
  48. mcp_proxy_adapter/commands/auth_validation_command.py +7 -344
  49. mcp_proxy_adapter/commands/base.py +19 -43
  50. mcp_proxy_adapter/commands/builtin_commands.py +0 -75
  51. mcp_proxy_adapter/commands/catalog/__init__.py +20 -0
  52. mcp_proxy_adapter/commands/catalog/catalog_loader.py +34 -0
  53. mcp_proxy_adapter/commands/catalog/catalog_manager.py +122 -0
  54. mcp_proxy_adapter/commands/catalog/catalog_syncer.py +149 -0
  55. mcp_proxy_adapter/commands/catalog/command_catalog.py +43 -0
  56. mcp_proxy_adapter/commands/catalog/dependency_manager.py +37 -0
  57. mcp_proxy_adapter/commands/catalog_manager.py +58 -928
  58. mcp_proxy_adapter/commands/cert_monitor_command.py +0 -88
  59. mcp_proxy_adapter/commands/certificate_management_command.py +0 -45
  60. mcp_proxy_adapter/commands/command_registry.py +172 -904
  61. mcp_proxy_adapter/commands/config_command.py +0 -28
  62. mcp_proxy_adapter/commands/dependency_container.py +1 -70
  63. mcp_proxy_adapter/commands/dependency_manager.py +0 -128
  64. mcp_proxy_adapter/commands/echo_command.py +0 -34
  65. mcp_proxy_adapter/commands/health_command.py +0 -3
  66. mcp_proxy_adapter/commands/help_command.py +0 -159
  67. mcp_proxy_adapter/commands/hooks.py +0 -137
  68. mcp_proxy_adapter/commands/key_management_command.py +0 -25
  69. mcp_proxy_adapter/commands/load_command.py +7 -78
  70. mcp_proxy_adapter/commands/plugins_command.py +0 -16
  71. mcp_proxy_adapter/commands/protocol_management_command.py +0 -28
  72. mcp_proxy_adapter/commands/proxy_registration_command.py +0 -88
  73. mcp_proxy_adapter/commands/queue_commands.py +750 -0
  74. mcp_proxy_adapter/commands/registration_status_command.py +0 -43
  75. mcp_proxy_adapter/commands/registry/__init__.py +18 -0
  76. mcp_proxy_adapter/commands/registry/command_info.py +103 -0
  77. mcp_proxy_adapter/commands/registry/command_loader.py +207 -0
  78. mcp_proxy_adapter/commands/registry/command_manager.py +119 -0
  79. mcp_proxy_adapter/commands/registry/command_registry.py +217 -0
  80. mcp_proxy_adapter/commands/reload_command.py +0 -80
  81. mcp_proxy_adapter/commands/result.py +25 -77
  82. mcp_proxy_adapter/commands/role_test_command.py +0 -44
  83. mcp_proxy_adapter/commands/roles_management_command.py +0 -199
  84. mcp_proxy_adapter/commands/security_command.py +0 -30
  85. mcp_proxy_adapter/commands/settings_command.py +0 -68
  86. mcp_proxy_adapter/commands/ssl_setup_command.py +0 -42
  87. mcp_proxy_adapter/commands/token_management_command.py +0 -1
  88. mcp_proxy_adapter/commands/transport_management_command.py +0 -20
  89. mcp_proxy_adapter/commands/unload_command.py +0 -71
  90. mcp_proxy_adapter/config.py +15 -626
  91. mcp_proxy_adapter/core/__init__.py +5 -39
  92. mcp_proxy_adapter/core/app_factory.py +14 -36
  93. mcp_proxy_adapter/core/app_runner.py +0 -27
  94. mcp_proxy_adapter/core/auth_validator.py +1 -93
  95. mcp_proxy_adapter/core/certificate/__init__.py +20 -0
  96. mcp_proxy_adapter/core/certificate/certificate_creator.py +371 -0
  97. mcp_proxy_adapter/core/certificate/certificate_extractor.py +183 -0
  98. mcp_proxy_adapter/core/certificate/certificate_utils.py +249 -0
  99. mcp_proxy_adapter/core/certificate/certificate_validator.py +110 -0
  100. mcp_proxy_adapter/core/certificate/ssl_context_manager.py +70 -0
  101. mcp_proxy_adapter/core/certificate_utils.py +64 -903
  102. mcp_proxy_adapter/core/client.py +0 -6
  103. mcp_proxy_adapter/core/client_manager.py +0 -19
  104. mcp_proxy_adapter/core/client_security.py +0 -2
  105. mcp_proxy_adapter/core/config/__init__.py +18 -0
  106. mcp_proxy_adapter/core/config/config.py +195 -0
  107. mcp_proxy_adapter/core/config/config_factory.py +22 -0
  108. mcp_proxy_adapter/core/config/config_loader.py +66 -0
  109. mcp_proxy_adapter/core/config/feature_manager.py +31 -0
  110. mcp_proxy_adapter/core/config/simple_config.py +112 -0
  111. mcp_proxy_adapter/core/config/simple_config_generator.py +50 -0
  112. mcp_proxy_adapter/core/config/simple_config_validator.py +96 -0
  113. mcp_proxy_adapter/core/config_converter.py +0 -186
  114. mcp_proxy_adapter/core/config_validator.py +96 -1238
  115. mcp_proxy_adapter/core/errors.py +7 -42
  116. mcp_proxy_adapter/core/job_manager.py +54 -0
  117. mcp_proxy_adapter/core/logging.py +2 -22
  118. mcp_proxy_adapter/core/mtls_asgi.py +0 -20
  119. mcp_proxy_adapter/core/mtls_asgi_app.py +0 -12
  120. mcp_proxy_adapter/core/mtls_proxy.py +0 -80
  121. mcp_proxy_adapter/core/mtls_server.py +3 -173
  122. mcp_proxy_adapter/core/protocol_manager.py +1 -191
  123. mcp_proxy_adapter/core/proxy/__init__.py +22 -0
  124. mcp_proxy_adapter/core/proxy/auth_manager.py +27 -0
  125. mcp_proxy_adapter/core/proxy/proxy_registration_manager.py +137 -0
  126. mcp_proxy_adapter/core/proxy/registration_client.py +60 -0
  127. mcp_proxy_adapter/core/proxy/ssl_manager.py +101 -0
  128. mcp_proxy_adapter/core/proxy_client.py +0 -1
  129. mcp_proxy_adapter/core/proxy_registration.py +36 -913
  130. mcp_proxy_adapter/core/role_utils.py +0 -308
  131. mcp_proxy_adapter/core/security_adapter.py +1 -36
  132. mcp_proxy_adapter/core/security_factory.py +1 -150
  133. mcp_proxy_adapter/core/security_integration.py +0 -33
  134. mcp_proxy_adapter/core/server_adapter.py +1 -40
  135. mcp_proxy_adapter/core/server_engine.py +2 -173
  136. mcp_proxy_adapter/core/settings.py +0 -127
  137. mcp_proxy_adapter/core/signal_handler.py +0 -65
  138. mcp_proxy_adapter/core/ssl_utils.py +19 -137
  139. mcp_proxy_adapter/core/transport_manager.py +0 -151
  140. mcp_proxy_adapter/core/unified_config_adapter.py +1 -193
  141. mcp_proxy_adapter/core/utils.py +1 -182
  142. mcp_proxy_adapter/core/validation/__init__.py +21 -0
  143. mcp_proxy_adapter/core/validation/config_validator.py +211 -0
  144. mcp_proxy_adapter/core/validation/file_validator.py +73 -0
  145. mcp_proxy_adapter/core/validation/protocol_validator.py +191 -0
  146. mcp_proxy_adapter/core/validation/security_validator.py +58 -0
  147. mcp_proxy_adapter/core/validation/validation_result.py +27 -0
  148. mcp_proxy_adapter/custom_openapi.py +33 -652
  149. mcp_proxy_adapter/examples/bugfix_certificate_config.py +0 -23
  150. mcp_proxy_adapter/examples/check_config.py +0 -2
  151. mcp_proxy_adapter/examples/client_usage_example.py +164 -0
  152. mcp_proxy_adapter/examples/config_builder.py +13 -2
  153. mcp_proxy_adapter/examples/config_cli.py +0 -1
  154. mcp_proxy_adapter/examples/create_test_configs.py +0 -46
  155. mcp_proxy_adapter/examples/debug_request_state.py +0 -1
  156. mcp_proxy_adapter/examples/full_application/commands/custom_echo_command.py +0 -47
  157. mcp_proxy_adapter/examples/full_application/commands/dynamic_calculator_command.py +0 -45
  158. mcp_proxy_adapter/examples/full_application/commands/echo_command.py +0 -12
  159. mcp_proxy_adapter/examples/full_application/commands/help_command.py +0 -12
  160. mcp_proxy_adapter/examples/full_application/commands/list_command.py +0 -7
  161. mcp_proxy_adapter/examples/full_application/hooks/__init__.py +0 -2
  162. mcp_proxy_adapter/examples/full_application/hooks/application_hooks.py +0 -59
  163. mcp_proxy_adapter/examples/full_application/hooks/builtin_command_hooks.py +0 -54
  164. mcp_proxy_adapter/examples/full_application/main.py +186 -150
  165. mcp_proxy_adapter/examples/full_application/proxy_endpoints.py +0 -107
  166. mcp_proxy_adapter/examples/full_application/test_minimal_server.py +0 -24
  167. mcp_proxy_adapter/examples/full_application/test_server.py +0 -58
  168. mcp_proxy_adapter/examples/generate_config.py +65 -11
  169. mcp_proxy_adapter/examples/queue_demo_simple.py +632 -0
  170. mcp_proxy_adapter/examples/queue_integration_example.py +578 -0
  171. mcp_proxy_adapter/examples/queue_server_demo.py +82 -0
  172. mcp_proxy_adapter/examples/queue_server_example.py +85 -0
  173. mcp_proxy_adapter/examples/queue_server_simple.py +173 -0
  174. mcp_proxy_adapter/examples/required_certificates.py +0 -2
  175. mcp_proxy_adapter/examples/run_full_test_suite.py +0 -29
  176. mcp_proxy_adapter/examples/run_proxy_server.py +31 -71
  177. mcp_proxy_adapter/examples/run_security_tests_fixed.py +0 -27
  178. mcp_proxy_adapter/examples/security_test/__init__.py +18 -0
  179. mcp_proxy_adapter/examples/security_test/auth_manager.py +14 -0
  180. mcp_proxy_adapter/examples/security_test/ssl_context_manager.py +28 -0
  181. mcp_proxy_adapter/examples/security_test/test_client.py +159 -0
  182. mcp_proxy_adapter/examples/security_test/test_result.py +22 -0
  183. mcp_proxy_adapter/examples/security_test_client.py +24 -1075
  184. mcp_proxy_adapter/examples/setup/__init__.py +24 -0
  185. mcp_proxy_adapter/examples/setup/certificate_manager.py +215 -0
  186. mcp_proxy_adapter/examples/setup/config_generator.py +12 -0
  187. mcp_proxy_adapter/examples/setup/config_validator.py +118 -0
  188. mcp_proxy_adapter/examples/setup/environment_setup.py +62 -0
  189. mcp_proxy_adapter/examples/setup/test_files_generator.py +10 -0
  190. mcp_proxy_adapter/examples/setup/test_runner.py +89 -0
  191. mcp_proxy_adapter/examples/setup_test_environment.py +133 -1425
  192. mcp_proxy_adapter/examples/test_config.py +0 -3
  193. mcp_proxy_adapter/examples/test_config_builder.py +25 -405
  194. mcp_proxy_adapter/examples/test_examples.py +0 -1
  195. mcp_proxy_adapter/examples/test_framework_complete.py +0 -2
  196. mcp_proxy_adapter/examples/test_mcp_server.py +0 -1
  197. mcp_proxy_adapter/examples/test_protocol_examples.py +0 -1
  198. mcp_proxy_adapter/examples/universal_client.py +0 -6
  199. mcp_proxy_adapter/examples/update_config_certificates.py +0 -1
  200. mcp_proxy_adapter/examples/validate_generator_compatibility.py +0 -1
  201. mcp_proxy_adapter/examples/validate_generator_compatibility_simple.py +0 -187
  202. mcp_proxy_adapter/integrations/__init__.py +25 -0
  203. mcp_proxy_adapter/integrations/queuemgr_integration.py +462 -0
  204. mcp_proxy_adapter/main.py +70 -62
  205. mcp_proxy_adapter/openapi.py +0 -22
  206. mcp_proxy_adapter/version.py +1 -1
  207. {mcp_proxy_adapter-6.9.28.dist-info → mcp_proxy_adapter-6.9.29.dist-info}/METADATA +2 -1
  208. mcp_proxy_adapter-6.9.29.dist-info/RECORD +235 -0
  209. {mcp_proxy_adapter-6.9.28.dist-info → mcp_proxy_adapter-6.9.29.dist-info}/entry_points.txt +1 -1
  210. mcp_proxy_adapter-6.9.28.dist-info/RECORD +0 -149
  211. {mcp_proxy_adapter-6.9.28.dist-info → mcp_proxy_adapter-6.9.29.dist-info}/WHEEL +0 -0
  212. {mcp_proxy_adapter-6.9.28.dist-info → mcp_proxy_adapter-6.9.29.dist-info}/top_level.txt +0 -0
@@ -9,8 +9,6 @@ Version: 1.0.0
9
9
  """
10
10
 
11
11
  import logging
12
- from typing import List, Optional, Set
13
- from cryptography import x509
14
12
 
15
13
 
16
14
  class RoleUtils:
@@ -24,130 +22,14 @@ class RoleUtils:
24
22
  ROLE_EXTENSION_OID = "1.3.6.1.4.1.99999.1"
25
23
 
26
24
  @staticmethod
27
- def extract_roles_from_certificate(cert_path: str) -> List[str]:
28
- """
29
- Extract roles from certificate file.
30
-
31
- Args:
32
- cert_path: Path to certificate file
33
-
34
- Returns:
35
- List of roles extracted from certificate
36
- """
37
- try:
38
- with open(cert_path, "rb") as f:
39
- cert_data = f.read()
40
-
41
- cert = x509.load_pem_x509_certificate(cert_data)
42
-
43
- # Extract roles from custom extension
44
- for extension in cert.extensions:
45
- if extension.oid.dotted_string == RoleUtils.ROLE_EXTENSION_OID:
46
- roles_data = extension.value.value.decode("utf-8")
47
- return [
48
- role.strip() for role in roles_data.split(",") if role.strip()
49
- ]
50
-
51
- return []
52
-
53
- except Exception as e:
54
- logging.getLogger(__name__).error(
55
- f"Failed to extract roles from certificate {cert_path}: {e}"
56
- )
57
- return []
58
25
 
59
26
  @staticmethod
60
- def extract_roles_from_certificate_object(cert: x509.Certificate) -> List[str]:
61
- """
62
- Extract roles from certificate object.
63
-
64
- Args:
65
- cert: Certificate object
66
-
67
- Returns:
68
- List of roles extracted from certificate
69
- """
70
- try:
71
- # Extract roles from custom extension
72
- for extension in cert.extensions:
73
- if extension.oid.dotted_string == RoleUtils.ROLE_EXTENSION_OID:
74
- roles_data = extension.value.value.decode("utf-8")
75
- return [
76
- role.strip() for role in roles_data.split(",") if role.strip()
77
- ]
78
-
79
- return []
80
-
81
- except Exception as e:
82
- logging.getLogger(__name__).error(
83
- f"Failed to extract roles from certificate object: {e}"
84
- )
85
- return []
86
27
 
87
28
  @staticmethod
88
- def compare_roles(role1: str, role2: str) -> bool:
89
- """
90
- Compare two roles (case-insensitive).
91
-
92
- Args:
93
- role1: First role to compare
94
- role2: Second role to compare
95
-
96
- Returns:
97
- True if roles are equal (case-insensitive), False otherwise
98
- """
99
- if not role1 or not role2:
100
- return False
101
-
102
- return role1.lower().strip() == role2.lower().strip()
103
29
 
104
30
  @staticmethod
105
- def compare_role_lists(roles1: List[str], roles2: List[str]) -> bool:
106
- """
107
- Compare two lists of roles (case-insensitive).
108
-
109
- Args:
110
- roles1: First list of roles
111
- roles2: Second list of roles
112
-
113
- Returns:
114
- True if role lists are equal (case-insensitive), False otherwise
115
- """
116
- if not roles1 and not roles2:
117
- return True
118
-
119
- if not roles1 or not roles2:
120
- return False
121
-
122
- # Normalize and sort both lists
123
- normalized_roles1 = sorted(
124
- [role.lower().strip() for role in roles1 if role.strip()]
125
- )
126
- normalized_roles2 = sorted(
127
- [role.lower().strip() for role in roles2 if role.strip()]
128
- )
129
-
130
- return normalized_roles1 == normalized_roles2
131
31
 
132
32
  @staticmethod
133
- def validate_roles(roles: List[str]) -> bool:
134
- """
135
- Validate list of roles.
136
-
137
- Args:
138
- roles: List of roles to validate
139
-
140
- Returns:
141
- True if roles are valid, False otherwise
142
- """
143
- if not isinstance(roles, list):
144
- return False
145
-
146
- for role in roles:
147
- if not RoleUtils.validate_single_role(role):
148
- return False
149
-
150
- return True
151
33
 
152
34
  @staticmethod
153
35
  def validate_single_role(role: str) -> bool:
@@ -230,211 +112,21 @@ class RoleUtils:
230
112
  return normalized
231
113
 
232
114
  @staticmethod
233
- def has_role(user_roles: List[str], required_role: str) -> bool:
234
- """
235
- Check if user has required role.
236
-
237
- Args:
238
- user_roles: List of user roles
239
- required_role: Required role to check
240
-
241
- Returns:
242
- True if user has required role, False otherwise
243
- """
244
- if not user_roles or not required_role:
245
- return False
246
-
247
- normalized_required = RoleUtils.normalize_role(required_role)
248
- normalized_user_roles = RoleUtils.normalize_roles(user_roles)
249
-
250
- return normalized_required in normalized_user_roles
251
115
 
252
116
  @staticmethod
253
- def has_any_role(user_roles: List[str], required_roles: List[str]) -> bool:
254
- """
255
- Check if user has any of the required roles.
256
-
257
- Args:
258
- user_roles: List of user roles
259
- required_roles: List of required roles to check
260
-
261
- Returns:
262
- True if user has any required role, False otherwise
263
- """
264
- if not user_roles or not required_roles:
265
- return False
266
-
267
- normalized_user_roles = RoleUtils.normalize_roles(user_roles)
268
- normalized_required_roles = RoleUtils.normalize_roles(required_roles)
269
-
270
- return any(role in normalized_user_roles for role in normalized_required_roles)
271
117
 
272
118
  @staticmethod
273
- def has_all_roles(user_roles: List[str], required_roles: List[str]) -> bool:
274
- """
275
- Check if user has all required roles.
276
-
277
- Args:
278
- user_roles: List of user roles
279
- required_roles: List of required roles to check
280
-
281
- Returns:
282
- True if user has all required roles, False otherwise
283
- """
284
- if not user_roles or not required_roles:
285
- return False
286
-
287
- normalized_user_roles = RoleUtils.normalize_roles(user_roles)
288
- normalized_required_roles = RoleUtils.normalize_roles(required_roles)
289
-
290
- return all(role in normalized_user_roles for role in normalized_required_roles)
291
119
 
292
120
  @staticmethod
293
- def get_common_roles(roles1: List[str], roles2: List[str]) -> List[str]:
294
- """
295
- Get common roles between two role lists.
296
-
297
- Args:
298
- roles1: First list of roles
299
- roles2: Second list of roles
300
-
301
- Returns:
302
- List of common roles
303
- """
304
- if not roles1 or not roles2:
305
- return []
306
-
307
- normalized_roles1 = set(RoleUtils.normalize_roles(roles1))
308
- normalized_roles2 = set(RoleUtils.normalize_roles(roles2))
309
-
310
- return list(normalized_roles1.intersection(normalized_roles2))
311
121
 
312
122
  @staticmethod
313
- def merge_roles(roles1: List[str], roles2: List[str]) -> List[str]:
314
- """
315
- Merge two role lists (remove duplicates).
316
-
317
- Args:
318
- roles1: First list of roles
319
- roles2: Second list of roles
320
-
321
- Returns:
322
- Merged list of roles without duplicates
323
- """
324
- all_roles = (roles1 or []) + (roles2 or [])
325
- return RoleUtils.normalize_roles(all_roles)
326
123
 
327
124
  @staticmethod
328
- def remove_roles(roles: List[str], roles_to_remove: List[str]) -> List[str]:
329
- """
330
- Remove specified roles from role list.
331
-
332
- Args:
333
- roles: List of roles
334
- roles_to_remove: List of roles to remove
335
-
336
- Returns:
337
- List of roles with specified roles removed
338
- """
339
- if not roles:
340
- return []
341
-
342
- if not roles_to_remove:
343
- return roles.copy()
344
-
345
- normalized_roles = RoleUtils.normalize_roles(roles)
346
- normalized_to_remove = set(RoleUtils.normalize_roles(roles_to_remove))
347
-
348
- return [role for role in normalized_roles if role not in normalized_to_remove]
349
125
 
350
126
  @staticmethod
351
- def is_admin_role(role: str) -> bool:
352
- """
353
- Check if role is an admin role.
354
-
355
- Args:
356
- role: Role to check
357
-
358
- Returns:
359
- True if role is admin, False otherwise
360
- """
361
- if not role:
362
- return False
363
-
364
- admin_roles = {"admin", "administrator", "root", "superuser", "super-admin"}
365
- normalized_role = RoleUtils.normalize_role(role)
366
-
367
- return normalized_role in admin_roles
368
127
 
369
128
  @staticmethod
370
- def is_system_role(role: str) -> bool:
371
- """
372
- Check if role is a system role.
373
-
374
- Args:
375
- role: Role to check
376
-
377
- Returns:
378
- True if role is system role, False otherwise
379
- """
380
- if not role:
381
- return False
382
-
383
- system_roles = {"system", "service", "daemon", "internal", "system-user"}
384
- normalized_role = RoleUtils.normalize_role(role)
385
-
386
- return normalized_role in system_roles
387
129
 
388
130
  @staticmethod
389
- def get_role_hierarchy(role: str) -> List[str]:
390
- """
391
- Get role hierarchy (parent roles).
392
-
393
- Args:
394
- role: Role to get hierarchy for
395
-
396
- Returns:
397
- List of parent roles in hierarchy
398
- """
399
- if not role:
400
- return []
401
-
402
- normalized_role = RoleUtils.normalize_role(role)
403
-
404
- # Define role hierarchy
405
- hierarchy = {
406
- "super-admin": ["admin", "user"],
407
- "admin": ["user"],
408
- "moderator": ["user"],
409
- "user": [],
410
- "guest": [],
411
- }
412
-
413
- return hierarchy.get(normalized_role, [])
414
131
 
415
132
  @staticmethod
416
- def get_role_permissions(role: str) -> List[str]:
417
- """
418
- Get permissions for a role.
419
-
420
- Args:
421
- role: Role to get permissions for
422
-
423
- Returns:
424
- List of permissions for the role
425
- """
426
- if not role:
427
- return []
428
-
429
- normalized_role = RoleUtils.normalize_role(role)
430
-
431
- # Define role permissions
432
- permissions = {
433
- "super-admin": ["read", "write", "delete", "admin", "system"],
434
- "admin": ["read", "write", "delete", "admin"],
435
- "moderator": ["read", "write", "moderate"],
436
- "user": ["read", "write"],
437
- "guest": ["read"],
438
- }
439
-
440
- return permissions.get(normalized_role, [])
@@ -7,8 +7,7 @@ handling configuration conversion and request validation.
7
7
 
8
8
  import json
9
9
  import logging
10
- from typing import Dict, Any, List, Optional
11
- from pathlib import Path
10
+ from typing import Dict, Any, Optional
12
11
 
13
12
  # Import mcp_security_framework components
14
13
  try:
@@ -341,38 +340,4 @@ class SecurityAdapter:
341
340
  get_global_logger().info(f"Total API keys loaded: {len(api_keys)}")
342
341
  return api_keys
343
342
 
344
- def create_middleware(self, framework: str = "fastapi"):
345
- """
346
- Create framework-specific middleware.
347
-
348
- Args:
349
- framework: Framework type (fastapi, flask, etc.)
350
-
351
- Returns:
352
- Middleware instance
353
- """
354
- if not self.security_manager:
355
- get_global_logger().warning("Cannot create middleware: security framework not available")
356
- return None
357
343
 
358
- try:
359
- if framework == "fastapi":
360
- from mcp_security_framework.middleware import (
361
- create_fastapi_security_middleware,
362
- )
363
-
364
- return create_fastapi_security_middleware(self.security_manager)
365
- else:
366
- raise ValueError(f"Unsupported framework: {framework}")
367
- except Exception as e:
368
- get_global_logger().error(f"Failed to create middleware: {e}")
369
- return None
370
-
371
- def is_available(self) -> bool:
372
- """
373
- Check if security framework is available.
374
-
375
- Returns:
376
- True if framework is available, False otherwise
377
- """
378
- return SECURITY_FRAMEWORK_AVAILABLE and self.security_manager is not None
@@ -6,7 +6,7 @@ and middleware components with proper configuration and error handling.
6
6
  """
7
7
 
8
8
  import logging
9
- from typing import Dict, Any, Optional
9
+ from typing import Dict, Any
10
10
 
11
11
  from mcp_proxy_adapter.core.logging import get_global_logger
12
12
  from .security_adapter import SecurityAdapter
@@ -40,22 +40,6 @@ class SecurityFactory:
40
40
  raise
41
41
 
42
42
  @staticmethod
43
- def create_security_manager(config: Dict[str, Any]):
44
- """
45
- Create SecurityManager from configuration.
46
-
47
- Args:
48
- config: mcp_proxy_adapter configuration dictionary
49
-
50
- Returns:
51
- SecurityManager instance or None if not available
52
- """
53
- try:
54
- adapter = SecurityFactory.create_security_adapter(config)
55
- return adapter.security_manager
56
- except Exception as e:
57
- get_global_logger().error(f"Failed to create security manager: {e}")
58
- return None
59
43
 
60
44
  @staticmethod
61
45
  def create_middleware(config: Dict[str, Any], framework: str = "fastapi"):
@@ -85,145 +69,12 @@ class SecurityFactory:
85
69
  return None
86
70
 
87
71
  @staticmethod
88
- def create_fastapi_middleware(config: Dict[str, Any]):
89
- """
90
- Create FastAPI-specific security middleware.
91
-
92
- Args:
93
- config: mcp_proxy_adapter configuration dictionary
94
-
95
- Returns:
96
- FastAPI middleware instance or None if creation failed
97
- """
98
- return SecurityFactory.create_middleware(config, "fastapi")
99
72
 
100
73
  @staticmethod
101
- def validate_config(config: Dict[str, Any]) -> bool:
102
- """
103
- Validate security configuration.
104
-
105
- Args:
106
- config: Configuration dictionary to validate
107
-
108
- Returns:
109
- True if configuration is valid, False otherwise
110
- """
111
- try:
112
- # Check if security section exists
113
- security_config = config.get("security", {})
114
-
115
- # Validate required fields
116
- if not isinstance(security_config, dict):
117
- get_global_logger().error("Security configuration must be a dictionary")
118
- return False
119
-
120
- # Validate auth configuration
121
- auth_config = security_config.get("auth", {})
122
- if not isinstance(auth_config, dict):
123
- get_global_logger().error("Auth configuration must be a dictionary")
124
- return False
125
-
126
- # Validate SSL configuration
127
- ssl_config = security_config.get("ssl", {})
128
- if not isinstance(ssl_config, dict):
129
- get_global_logger().error("SSL configuration must be a dictionary")
130
- return False
131
-
132
- # Validate permissions configuration
133
- permissions_config = security_config.get("permissions", {})
134
- if not isinstance(permissions_config, dict):
135
- get_global_logger().error("Permissions configuration must be a dictionary")
136
- return False
137
-
138
- # Validate rate limit configuration
139
- rate_limit_config = security_config.get("rate_limit", {})
140
- if not isinstance(rate_limit_config, dict):
141
- get_global_logger().error("Rate limit configuration must be a dictionary")
142
- return False
143
-
144
- get_global_logger().info("Security configuration validation passed")
145
- return True
146
-
147
- except Exception as e:
148
- get_global_logger().error(f"Configuration validation failed: {e}")
149
- return False
150
74
 
151
75
  @staticmethod
152
- def get_default_config() -> Dict[str, Any]:
153
- """
154
- Get default security configuration.
155
-
156
- Returns:
157
- Default security configuration dictionary
158
- """
159
- return {
160
- "security": {
161
- "framework": "mcp_security_framework",
162
- "enabled": True,
163
- "auth": {
164
- "enabled": True,
165
- "methods": ["api_key"],
166
- "api_keys": {},
167
- "jwt_secret": "",
168
- "jwt_algorithm": "HS256",
169
- },
170
- "ssl": {
171
- "enabled": False,
172
- "cert_file": None,
173
- "key_file": None,
174
- "ca_cert": None,
175
- "min_tls_version": "TLSv1.2",
176
- "verify_client": False,
177
- "client_cert_required": False,
178
- },
179
- "permissions": {
180
- "enabled": True,
181
- "roles_file": "roles.json",
182
- "default_role": "user",
183
- "deny_by_default": True,
184
- },
185
- "rate_limit": {
186
- "enabled": True,
187
- "requests_per_minute": 60,
188
- "requests_per_hour": 1000,
189
- "burst_limit": 10,
190
- "by_ip": True,
191
- "by_user": True,
192
- },
193
- }
194
- }
195
76
 
196
77
  @staticmethod
197
- def merge_config(
198
- base_config: Dict[str, Any], security_config: Dict[str, Any]
199
- ) -> Dict[str, Any]:
200
- """
201
- Merge security configuration into base configuration.
202
-
203
- Args:
204
- base_config: Base configuration dictionary
205
- security_config: Security configuration to merge
206
-
207
- Returns:
208
- Merged configuration dictionary
209
- """
210
- try:
211
- # Create a copy of base config
212
- merged_config = base_config.copy()
213
-
214
- # Merge security configuration
215
- if "security" not in merged_config:
216
- merged_config["security"] = {}
217
-
218
- # Deep merge security configuration
219
- SecurityFactory._deep_merge(merged_config["security"], security_config)
220
-
221
- get_global_logger().info("Security configuration merged successfully")
222
- return merged_config
223
-
224
- except Exception as e:
225
- get_global_logger().error(f"Failed to merge security configuration: {e}")
226
- return base_config
227
78
 
228
79
  @staticmethod
229
80
  def _deep_merge(base_dict: Dict[str, Any], update_dict: Dict[str, Any]) -> None:
@@ -333,43 +333,10 @@ class SecurityIntegration:
333
333
  return await self.rate_limiter.get_rate_limit_info(identifier)
334
334
 
335
335
  # Middleware creation - direct use of framework middleware
336
- def create_fastapi_middleware(self, app) -> FastAPISecurityMiddleware:
337
- """Create FastAPI security middleware."""
338
- return FastAPISecurityMiddleware(app, self.security_config)
339
336
 
340
337
  # Utility methods
341
- def is_security_enabled(self) -> bool:
342
- """Check if security is enabled."""
343
- return self.security_config.auth.enabled or self.security_config.ssl.enabled
344
338
 
345
- def get_public_paths(self) -> List[str]:
346
- """Get public paths that bypass authentication."""
347
- return self.security_config.auth.public_paths
348
339
 
349
- def get_security_config(self) -> SecurityConfig:
350
- """Get security configuration."""
351
- return self.security_config
352
340
 
353
341
 
354
342
  # Factory function for easy integration
355
- def create_security_integration(config: Dict[str, Any]) -> SecurityIntegration:
356
- """
357
- Create security integration instance.
358
-
359
- Args:
360
- config: Configuration dictionary
361
-
362
- Returns:
363
- SecurityIntegration instance
364
-
365
- Raises:
366
- RuntimeError: If security integration cannot be created
367
- """
368
- try:
369
- return SecurityIntegration(config)
370
- except ImportError as e:
371
- get_global_logger().error(f"mcp_security_framework not available: {e}")
372
- raise RuntimeError("Security framework is required but not available") from e
373
- except Exception as e:
374
- get_global_logger().error(f"Failed to create security integration: {e}")
375
- raise RuntimeError(f"Security integration failed: {e}") from e
@@ -10,9 +10,9 @@ email: vasilyvz@gmail.com
10
10
 
11
11
  import logging
12
12
  from typing import Dict, Any, Optional
13
- from pathlib import Path
14
13
 
15
14
  from .server_engine import ServerEngineFactory, ServerEngine
15
+ from .logging import get_global_logger
16
16
 
17
17
  logger = logging.getLogger(__name__)
18
18
 
@@ -75,20 +75,6 @@ class ServerConfigAdapter:
75
75
  return hypercorn_ssl
76
76
 
77
77
  @staticmethod
78
- def get_optimal_engine_for_config(config: Dict[str, Any]) -> Optional[str]:
79
- """
80
- Determine the optimal server engine for a given configuration.
81
-
82
- Currently only hypercorn is supported.
83
-
84
- Args:
85
- config: Server configuration
86
-
87
- Returns:
88
- Optimal engine name (currently always "hypercorn")
89
- """
90
- # Currently only hypercorn is supported
91
- return "hypercorn"
92
78
 
93
79
  @staticmethod
94
80
  def validate_engine_compatibility(config: Dict[str, Any], engine_name: str) -> bool:
@@ -262,29 +248,4 @@ class UnifiedServerRunner:
262
248
 
263
249
  return engine_config
264
250
 
265
- def get_engine_info(self, engine_name: str) -> Dict[str, Any]:
266
- """
267
- Get information about a specific engine.
268
-
269
- Args:
270
- engine_name: Name of the engine
271
-
272
- Returns:
273
- Engine information dictionary
274
- """
275
- return ServerConfigAdapter.get_engine_capabilities(engine_name)
276
251
 
277
- def list_available_engines(self) -> Dict[str, Dict[str, Any]]:
278
- """
279
- List all available engines with their capabilities.
280
-
281
- Returns:
282
- Dictionary mapping engine names to their capabilities
283
- """
284
- engines_info = {}
285
- for name, engine in self.available_engines.items():
286
- engines_info[name] = {
287
- "features": engine.get_supported_features(),
288
- "config_schema": engine.get_config_schema(),
289
- }
290
- return engines_info