api-foundry-query-engine 0.8.31__tar.gz → 0.8.32__tar.gz

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.
Files changed (33) hide show
  1. {api_foundry_query_engine-0.8.31 → api_foundry_query_engine-0.8.32}/PKG-INFO +1 -1
  2. {api_foundry_query_engine-0.8.31 → api_foundry_query_engine-0.8.32}/api_foundry_query_engine/dao/sql_delete_query_handler.py +20 -4
  3. {api_foundry_query_engine-0.8.31 → api_foundry_query_engine-0.8.32}/api_foundry_query_engine/dao/sql_query_handler.py +59 -16
  4. {api_foundry_query_engine-0.8.31 → api_foundry_query_engine-0.8.32}/pyproject.toml +2 -2
  5. {api_foundry_query_engine-0.8.31 → api_foundry_query_engine-0.8.32}/.gitignore +0 -0
  6. {api_foundry_query_engine-0.8.31 → api_foundry_query_engine-0.8.32}/LICENSE +0 -0
  7. {api_foundry_query_engine-0.8.31 → api_foundry_query_engine-0.8.32}/api_foundry_query_engine/.pre-commit-config.yaml +0 -0
  8. {api_foundry_query_engine-0.8.31 → api_foundry_query_engine-0.8.32}/api_foundry_query_engine/__init__.py +0 -0
  9. {api_foundry_query_engine-0.8.31 → api_foundry_query_engine-0.8.32}/api_foundry_query_engine/adapters/adapter.py +0 -0
  10. {api_foundry_query_engine-0.8.31 → api_foundry_query_engine-0.8.32}/api_foundry_query_engine/adapters/case_change_adapter.py +0 -0
  11. {api_foundry_query_engine-0.8.31 → api_foundry_query_engine-0.8.32}/api_foundry_query_engine/adapters/gateway_adapter.py +0 -0
  12. {api_foundry_query_engine-0.8.31 → api_foundry_query_engine-0.8.32}/api_foundry_query_engine/adapters/security_adapter.py +0 -0
  13. {api_foundry_query_engine-0.8.31 → api_foundry_query_engine-0.8.32}/api_foundry_query_engine/connectors/connection.py +0 -0
  14. {api_foundry_query_engine-0.8.31 → api_foundry_query_engine-0.8.32}/api_foundry_query_engine/connectors/connection_factory.py +0 -0
  15. {api_foundry_query_engine-0.8.31 → api_foundry_query_engine-0.8.32}/api_foundry_query_engine/connectors/oracle_connector.py +0 -0
  16. {api_foundry_query_engine-0.8.31 → api_foundry_query_engine-0.8.32}/api_foundry_query_engine/connectors/postgres_connection.py +0 -0
  17. {api_foundry_query_engine-0.8.31 → api_foundry_query_engine-0.8.32}/api_foundry_query_engine/dao/dao.py +0 -0
  18. {api_foundry_query_engine-0.8.31 → api_foundry_query_engine-0.8.32}/api_foundry_query_engine/dao/operation_dao.py +0 -0
  19. {api_foundry_query_engine-0.8.31 → api_foundry_query_engine-0.8.32}/api_foundry_query_engine/dao/sql_custom_query_handler.py +0 -0
  20. {api_foundry_query_engine-0.8.31 → api_foundry_query_engine-0.8.32}/api_foundry_query_engine/dao/sql_insert_query_handler.py +0 -0
  21. {api_foundry_query_engine-0.8.31 → api_foundry_query_engine-0.8.32}/api_foundry_query_engine/dao/sql_select_query_handler.py +0 -0
  22. {api_foundry_query_engine-0.8.31 → api_foundry_query_engine-0.8.32}/api_foundry_query_engine/dao/sql_subselect_query_handler.py +0 -0
  23. {api_foundry_query_engine-0.8.31 → api_foundry_query_engine-0.8.32}/api_foundry_query_engine/dao/sql_update_query_handler.py +0 -0
  24. {api_foundry_query_engine-0.8.31 → api_foundry_query_engine-0.8.32}/api_foundry_query_engine/lambda_handler.py +0 -0
  25. {api_foundry_query_engine-0.8.31 → api_foundry_query_engine-0.8.32}/api_foundry_query_engine/operation.py +0 -0
  26. {api_foundry_query_engine-0.8.31 → api_foundry_query_engine-0.8.32}/api_foundry_query_engine/services/service.py +0 -0
  27. {api_foundry_query_engine-0.8.31 → api_foundry_query_engine-0.8.32}/api_foundry_query_engine/services/transactional_service.py +0 -0
  28. {api_foundry_query_engine-0.8.31 → api_foundry_query_engine-0.8.32}/api_foundry_query_engine/utils/api_model.py +0 -0
  29. {api_foundry_query_engine-0.8.31 → api_foundry_query_engine-0.8.32}/api_foundry_query_engine/utils/app_exception.py +0 -0
  30. {api_foundry_query_engine-0.8.31 → api_foundry_query_engine-0.8.32}/api_foundry_query_engine/utils/claims_check.py +0 -0
  31. {api_foundry_query_engine-0.8.31 → api_foundry_query_engine-0.8.32}/api_foundry_query_engine/utils/gateway_operation.py +0 -0
  32. {api_foundry_query_engine-0.8.31 → api_foundry_query_engine-0.8.32}/api_foundry_query_engine/utils/logger.py +0 -0
  33. {api_foundry_query_engine-0.8.31 → api_foundry_query_engine-0.8.32}/api_foundry_query_engine/utils/token_decoder.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: api-foundry-query-engine
3
- Version: 0.8.31
3
+ Version: 0.8.32
4
4
  Summary: The AWS lambda service handler use by the `api_foundry` project is a powerful tool designed to automate the deployment of REST APIs on AWS using Lambda services to access and interact with relational databases (RDBMS). This project leverages the OpenAPI specification to define and manage the APIs
5
5
  Project-URL: Documentation, https://github.com/DanRepik/api-foundry
6
6
  Project-URL: Source, https://github.com/DanRepik/api-foundry
@@ -29,12 +29,28 @@ class SQLDeleteSchemaQueryHandler(SQLSchemaQueryHandler):
29
29
  if not self.schema_object.permissions:
30
30
  return True
31
31
 
32
+ # Use the proper provider-action-role structure
33
+ provider_permissions = self.schema_object.permissions.get("default", {})
34
+ delete_permissions = provider_permissions.get("delete", {})
35
+
32
36
  for role in self.operation.roles:
33
- role_permissions = self.schema_object.permissions.get(role, {})
37
+ role_permissions = delete_permissions.get(role)
34
38
  log.info("role: %s, role_permissions: %s", role, role_permissions)
35
- if len(role_permissions) == 0:
36
- continue
37
- allowed = role_permissions.get("delete", False)
39
+
40
+ # If no permissions found for role, check wildcard "*"
41
+ if role_permissions is None:
42
+ role_permissions = delete_permissions.get("*")
43
+ log.info("Fallback to wildcard role '*': %s", role_permissions)
44
+ if role_permissions is None:
45
+ continue
46
+
47
+ # Handle both boolean and object permission formats
48
+ if isinstance(role_permissions, bool):
49
+ allowed = role_permissions
50
+ else:
51
+ # For complex permission objects, existence means allowed
52
+ allowed = True
53
+
38
54
  if allowed:
39
55
  return True
40
56
 
@@ -193,28 +193,71 @@ class SQLQueryHandler:
193
193
  )
194
194
  log.info("Operation roles: %s", self.operation.roles)
195
195
 
196
+ # Permissions structure: {provider: {action: {role: rule}}}
197
+ # Use 'default' as the standard provider
198
+ provider_permissions = permissions.get("default", {})
199
+ action_permissions = provider_permissions.get(permission_type, {})
200
+
201
+ log.info(
202
+ "Extracted action permissions for %s: %s",
203
+ permission_type,
204
+ action_permissions,
205
+ )
206
+
196
207
  for role in self.operation.roles:
197
- role_permissions = permissions.get(role, {})
208
+ role_permissions = action_permissions.get(role, {})
198
209
  log.info("role: %s, role_permissions: %s", role, role_permissions)
199
- if len(role_permissions) == 0:
200
- continue
201
-
202
- # Extract permission patterns for this role
203
- read_perm = role_permissions.get("read", "")
204
- write_perm = role_permissions.get("write", "")
205
- read_pattern = self._extract_permission_pattern(read_perm)
206
- write_pattern = self._extract_permission_pattern(write_perm)
207
-
208
- for prop_name, property in properties.items():
209
- log.info("prop_name: %s, property: %s", prop_name, property)
210
- if permission_type == "read" and re.match(read_pattern, prop_name):
211
- allowed_properties[prop_name] = property
212
- if permission_type == "write" and re.match(write_pattern, prop_name):
213
- allowed_properties[prop_name] = property
210
+
211
+ # If no permissions found for specific role, check wildcard "*"
212
+ if not role_permissions:
213
+ role_permissions = action_permissions.get("*", {})
214
+ log.info("Fallback to wildcard role '*': %s", role_permissions)
215
+ if not role_permissions:
216
+ continue
217
+
218
+ # Extract permission pattern from the rule
219
+ regex_pattern = self._extract_permission_pattern(role_permissions)
220
+
221
+ if regex_pattern:
222
+ # Use efficient regex dictionary filtering
223
+ role_allowed = self._filter_properties_by_regex(
224
+ properties, regex_pattern
225
+ )
226
+ log.info(
227
+ "role: %s, pattern: %s, matched: %s",
228
+ role,
229
+ regex_pattern,
230
+ list(role_allowed.keys()),
231
+ )
232
+
233
+ # Merge with existing allowed properties
234
+ allowed_properties.update(role_allowed)
214
235
 
215
236
  log.info("allowed_properties: %s", allowed_properties)
216
237
  return allowed_properties
217
238
 
239
+ def _filter_properties_by_regex(
240
+ self, properties: Dict[str, SchemaObjectProperty], regex_pattern: str
241
+ ) -> Dict[str, SchemaObjectProperty]:
242
+ """Filter dictionary properties using a regex pattern.
243
+
244
+ Args:
245
+ properties: Dictionary of property name -> SchemaObjectProperty
246
+ regex_pattern: Regex pattern to match property names
247
+
248
+ Returns:
249
+ Dict[str, SchemaObjectProperty]: Filtered properties dict
250
+ """
251
+ if not regex_pattern:
252
+ return {}
253
+
254
+ try:
255
+ compiled_regex = re.compile(regex_pattern)
256
+ return {k: v for k, v in properties.items() if compiled_regex.match(k)}
257
+ except re.error as e:
258
+ log.warning("Invalid regex pattern '%s': %s", regex_pattern, e)
259
+ return {}
260
+
218
261
  def _extract_permission_pattern(self, permission_rule) -> str:
219
262
  """Extract the regex pattern from a permission rule.
220
263
 
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
4
4
 
5
5
  [project]
6
6
  name = "api-foundry-query-engine"
7
- version = "0.8.31"
7
+ version = "0.8.32"
8
8
  authors = [
9
9
  { name="Daniel Repik", email="danrepik@icloud.com" },
10
10
  ]
@@ -89,4 +89,4 @@ build = "mkdocs build --clean --strict"
89
89
  serve = "mkdocs serve --dev-addr localhost:8000"
90
90
 
91
91
  [tool.hatch.publish.index]
92
- disable = ["test"] # Disable test index by default for safety
92
+ disable = true # Disable publishing by default for safety