Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion application/single_app/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,7 @@
EXECUTOR_TYPE = 'thread'
EXECUTOR_MAX_WORKERS = 30
SESSION_TYPE = 'filesystem'
VERSION = "0.250.110"
VERSION = "0.250.111"
IS_DEVELOPMENT = is_development_env_enabled()

SESSION_COOKIE_SAMESITE = os.getenv('SESSION_COOKIE_SAMESITE', 'Lax')
Expand Down
19 changes: 0 additions & 19 deletions application/single_app/route_backend_data_management.py
Original file line number Diff line number Diff line change
Expand Up @@ -769,25 +769,6 @@ def get_admin_data_management_migration_catalog(target_type):
return jsonify({"success": False, "error": str(exc)}), 400
return jsonify({"success": True, **catalog}), 200

@bp.route("/api/admin/data-management/restore/review", methods=["POST"])
@swagger_route(security=get_auth_security())
@login_required
@admin_required
def review_admin_data_management_restore():
payload = request.get_json(silent=True) or {}
restore_plan = payload.get("restore_plan") if isinstance(payload.get("restore_plan"), dict) else {}
try:
review = review_data_management_restore(restore_plan)
except Exception as exc:
log_event(
"[DataManagement] Restore review failed.",
{"error": str(exc)},
level=logging.ERROR,
exceptionTraceback=True,
)
return jsonify({"success": False, "error": "Restore review could not be completed."}), 400
return jsonify({"success": True, "review": review}), 200

@bp.route("/api/admin/data-management/migration/summary", methods=["POST"])
@swagger_route(security=get_auth_security())
@login_required
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
# Data Management Restore Route Endpoint Collision Fix

Fixed/Implemented in version: **0.250.111**

## Issue Description

Application startup failed while registering the Data Management Blueprint because two restore review routes used the same URL and endpoint function name.

## Root Cause Analysis

An earlier restore review handler remained in `route_backend_data_management.py` after the authorization-aware restore review workflow was added. Flask therefore attempted to register `backend_data_management.review_admin_data_management_restore` twice and raised an `AssertionError`.

Check warning on line 11 in docs/explanation/fixes/DATA_MANAGEMENT_RESTORE_ROUTE_ENDPOINT_COLLISION_FIX.md

View workflow job for this annotation

GitHub Actions / malicious-pr-security-review

Important - Changed line contains secret or sensitive data source marker. Recommendation%3A Pair this source with any nearby network, logging, serialization, or process execution sink before approving.

## Technical Details

Files modified:

- `application/single_app/route_backend_data_management.py`
- `application/single_app/config.py`
- `functional_tests/test_data_management_security_patterns.py`

Code changes summary:

- Removed the obsolete duplicate restore review route.
- Retained the complete handler that validates settings and restore plans and issues restore review authorization tokens.

Check warning on line 24 in docs/explanation/fixes/DATA_MANAGEMENT_RESTORE_ROUTE_ENDPOINT_COLLISION_FIX.md

View workflow job for this annotation

GitHub Actions / malicious-pr-security-review

Important - Changed line contains security control, sanitization, or audit marker. Recommendation%3A Confirm the change does not weaken auth, CSRF, CSP, XSS defenses, settings sanitization, redaction, audit logging, or tests.

Check warning on line 24 in docs/explanation/fixes/DATA_MANAGEMENT_RESTORE_ROUTE_ENDPOINT_COLLISION_FIX.md

View workflow job for this annotation

GitHub Actions / malicious-pr-security-review

Important - Changed line contains secret or sensitive data source marker. Recommendation%3A Pair this source with any nearby network, logging, serialization, or process execution sink before approving.
- Added a regression assertion requiring unique route endpoint names in the Data Management Blueprint.
- Updated the application version to `0.250.111`.

Impact analysis:

- The Data Management Blueprint can register during application startup.
- The restore review API path and authorization-aware behavior remain unchanged.

Check warning on line 31 in docs/explanation/fixes/DATA_MANAGEMENT_RESTORE_ROUTE_ENDPOINT_COLLISION_FIX.md

View workflow job for this annotation

GitHub Actions / malicious-pr-security-review

Important - Changed line contains secret or sensitive data source marker. Recommendation%3A Pair this source with any nearby network, logging, serialization, or process execution sink before approving.

## Validation

Test results:

- The endpoint uniqueness regression test passes with 28 unique Data Management routes.

Check warning on line 37 in docs/explanation/fixes/DATA_MANAGEMENT_RESTORE_ROUTE_ENDPOINT_COLLISION_FIX.md

View workflow job for this annotation

GitHub Actions / malicious-pr-security-review

Important - Changed line contains security control, sanitization, or audit marker. Recommendation%3A Confirm the change does not weaken auth, CSRF, CSP, XSS defenses, settings sanitization, redaction, audit logging, or tests.
- Data Management route security and route policy tests validate authentication and Blueprint registration contracts.

Check warning on line 38 in docs/explanation/fixes/DATA_MANAGEMENT_RESTORE_ROUTE_ENDPOINT_COLLISION_FIX.md

View workflow job for this annotation

GitHub Actions / malicious-pr-security-review

Important - Changed line contains security control, sanitization, or audit marker. Recommendation%3A Confirm the change does not weaken auth, CSRF, CSP, XSS defenses, settings sanitization, redaction, audit logging, or tests.

Before: Flask stopped startup because the restore review endpoint was registered twice.

After: Flask registers one restore review endpoint backed by the guarded restore workflow.

Version reference: `application/single_app/config.py` version `0.250.111`.
1 change: 1 addition & 0 deletions docs/explanation/fixes/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ order: 120
category: Version History
---

- [Data Management Restore Route Endpoint Collision Fix](DATA_MANAGEMENT_RESTORE_ROUTE_ENDPOINT_COLLISION_FIX.md)
- [Font Size and 200 Percent Zoom Fix](FONT_SIZE_AND_200_PERCENT_ZOOM_FIX.md)
- [Public Workspace Prompt Migration Fix](PUBLIC_WORKSPACE_PROMPT_MIGRATION_FIX.md)
- [Azure OpenAI Model Discovery Identity Fix](v0.250.001/AZURE_OPENAI_MODEL_DISCOVERY_IDENTITY_FIX.md)
Expand Down
9 changes: 9 additions & 0 deletions docs/explanation/release_notes.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,15 @@

For feature-focused and fix-focused drill-downs by version, see [Features by Version](/explanation/features/) and [Fixes by Version](/explanation/fixes/).

### **(v0.250.111)**

#### Bug Fixes

* **Data Management Restore Route Registration**
* Fixed application startup failure caused by duplicate Data Management restore review route and endpoint registrations.
* Preserved the authorization-aware restore review workflow and added regression coverage requiring unique Blueprint endpoint names.

Check warning on line 11 in docs/explanation/release_notes.md

View workflow job for this annotation

GitHub Actions / malicious-pr-security-review

Important - Changed line contains secret or sensitive data source marker. Recommendation%3A Pair this source with any nearby network, logging, serialization, or process execution sink before approving.
* (Ref: `route_backend_data_management.py`, `test_data_management_security_patterns.py`, `DATA_MANAGEMENT_RESTORE_ROUTE_ENDPOINT_COLLISION_FIX.md`)

### **(v0.250.110)**

#### New Features
Expand Down
13 changes: 10 additions & 3 deletions functional_tests/test_data_management_security_patterns.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,15 @@
# test_data_management_security_patterns.py
"""
Functional test for Data Management security patterns.
Version: 0.250.108
Version: 0.250.111
Implemented in: 0.241.211
Updated in: 0.250.102
Updated in: 0.250.103
Updated in: 0.250.104
Updated in: 0.250.105
Updated in: 0.250.106
Updated in: 0.250.108
Updated in: 0.250.111

This test ensures Data Management admin routes require authenticated admin
access, secrets stay redacted in frontend responses, and the admin browser
Expand All @@ -26,6 +27,7 @@
admin cancellation/retry controls, and latest-only sidecar state sanitization.
Version 0.250.103 verifies paginated migration catalogs and sanitized
server-owned review results.
Version 0.250.111 verifies Data Management Blueprint endpoint names are unique.
"""

import ast
Expand Down Expand Up @@ -76,7 +78,7 @@ def test_version_and_container_registration():
"""Validate the Data Management version and Cosmos job container registrations."""
config_source = read_text(CONFIG_FILE)

assert 'VERSION = "0.250.108"' in config_source
assert 'VERSION = "0.250.111"' in config_source
assert 'cosmos_data_management_jobs_container_name = "data_management_jobs"' in config_source
assert 'partition_key=PartitionKey(path="/id")' in config_source
assert 'cosmos_data_management_job_items_container_name = "data_management_job_items"' in config_source
Expand All @@ -96,7 +98,12 @@ def test_version_and_container_registration():
def test_admin_routes_require_login_admin_and_swagger_security():
"""Validate every Data Management route has the required admin security stack."""
routes = route_functions_with_decorators()
assert len(routes) == 29
assert len(routes) == 28

route_function_names = [function_name for function_name, _decorators in routes]
assert len(route_function_names) == len(set(route_function_names)), (
"Data Management route endpoint names must be unique"
)

for function_name, decorators in routes:
assert "swagger_route" in decorators, f"{function_name} missing swagger_route"
Expand Down
Loading