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 @@ -96,7 +96,7 @@
EXECUTOR_TYPE = 'thread'
EXECUTOR_MAX_WORKERS = 30
SESSION_TYPE = 'filesystem'
VERSION = "0.250.051"
VERSION = "0.250.052"

SESSION_COOKIE_SAMESITE = os.getenv('SESSION_COOKIE_SAMESITE', 'Lax')
SESSION_COOKIE_HTTPONLY = os.getenv('SESSION_COOKIE_HTTPONLY', 'true').lower() != 'false'
Expand Down
2 changes: 1 addition & 1 deletion application/single_app/templates/_sidebar_nav.html
Original file line number Diff line number Diff line change
Expand Up @@ -844,7 +844,7 @@
<!-- Access logic: When require_member_of_control_center_admin is ENABLED, only ControlCenterAdmin role grants access -->
<!-- When DISABLED (default), only regular Admin role grants access (ControlCenterAdmin is ignored) -->
<!-- DashboardReader role grants dashboard-only access when that setting is enabled -->
{% if request.endpoint == 'control_center' and ((app_settings.require_member_of_control_center_admin and session.get('user') and 'ControlCenterAdmin' in session['user']['roles']) or (app_settings.require_member_of_control_center_dashboard_reader and session.get('user') and 'ControlCenterDashboardReader' in session['user']['roles']) or (not app_settings.require_member_of_control_center_admin and 'Admin' in session['user']['roles'])) %}
{% if request.endpoint == 'frontend_control_center.control_center' and ((app_settings.require_member_of_control_center_admin and session.get('user') and 'ControlCenterAdmin' in session['user']['roles']) or (app_settings.require_member_of_control_center_dashboard_reader and session.get('user') and 'ControlCenterDashboardReader' in session['user']['roles']) or (not app_settings.require_member_of_control_center_admin and 'Admin' in session['user']['roles'])) %}

Check warning on line 847 in application/single_app/templates/_sidebar_nav.html

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.
{% set control_center_menu_expanded = sidebar_menu_state.get('controlCenter', true) %}
<div class="overflow-auto">
<div id="control-center-toggle" class="mt-2 mb-1 ps-3 pe-2 text-muted small d-flex align-items-center justify-content-between" style="font-weight: 500; letter-spacing: 0.02em; cursor: pointer; user-select: none;" role="button" tabindex="0" aria-controls="control-center-section" aria-expanded="{{ 'true' if control_center_menu_expanded else 'false' }}" data-sidebar-menu-key="controlCenter" data-sidebar-menu-target="control-center-section" data-sidebar-menu-caret="control-center-caret">
Expand Down
40 changes: 40 additions & 0 deletions docs/explanation/fixes/CONTROL_CENTER_LEFT_NAV_ENDPOINT_FIX.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
# Control Center Left Nav Endpoint Fix

Fixed/Implemented in version: **0.250.052**

## Issue Description

Admins could open Control Center while the left navigation Control Center section stayed hidden, even when the ControlCenterAdmin and ControlCenterDashboardReader app-role settings were disabled.

Check warning on line 7 in docs/explanation/fixes/CONTROL_CENTER_LEFT_NAV_ENDPOINT_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 7 in docs/explanation/fixes/CONTROL_CENTER_LEFT_NAV_ENDPOINT_FIX.md

View workflow job for this annotation

GitHub Actions / malicious-pr-security-review

Moderate - Changed line contains obfuscation, dynamic loading, or hidden payload marker. Recommendation%3A Confirm the changed code is not hiding behavior, decoding payloads, or bypassing normal review.

## Root Cause Analysis

The full sidebar template checked for the unqualified endpoint name `control_center`. The route is registered on the `frontend_control_center` Blueprint, so Flask exposes the endpoint as `frontend_control_center.control_center`. The mismatch prevented the page-local Control Center left-nav section from rendering.

## Technical Details

Files modified:

- `application/single_app/templates/_sidebar_nav.html`
- `application/single_app/config.py`
- `functional_tests/test_control_center_left_nav_endpoint.py`

Code changes summary:

- Updated the Control Center sidebar condition to match the blueprint-qualified endpoint.
- Preserved the existing role fallback where regular `Admin` users get Control Center navigation when ControlCenterAdmin enforcement is disabled.

Check warning on line 24 in docs/explanation/fixes/CONTROL_CENTER_LEFT_NAV_ENDPOINT_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.
- Added a regression test for the endpoint condition and version bump.

## Validation

Validation approach:

- Run `python functional_tests/test_control_center_left_nav_endpoint.py`.
- Run `git -c core.whitespace=blank-at-eol,blank-at-eof,space-before-tab,cr-at-eol diff --check`.

Before: the Control Center page could load but the left nav section was not rendered because the endpoint check did not match.

After: the sidebar condition matches `frontend_control_center.control_center`, allowing authorized admins to see the Control Center left-nav section.

Related issue: Fixes #1009

Version reference: `application/single_app/config.py` version `0.250.052`.
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.052)**

#### Bug Fixes

* **Control Center Left Nav Endpoint Fix**
* Fixed an issue where admins could open Control Center while the left navigation Control Center section stayed hidden when ControlCenterAdmin enforcement was disabled.

Check warning on line 10 in docs/explanation/release_notes.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 10 in docs/explanation/release_notes.md

View workflow job for this annotation

GitHub Actions / malicious-pr-security-review

Moderate - Changed line contains obfuscation, dynamic loading, or hidden payload marker. Recommendation%3A Confirm the changed code is not hiding behavior, decoding payloads, or bypassing normal review.
* Updated the sidebar endpoint check to use the blueprint-qualified `frontend_control_center.control_center` route and added regression coverage for the regular Admin fallback.
* (Ref: microsoft/simplechat#1009, `_sidebar_nav.html`, `test_control_center_left_nav_endpoint.py`)

### **(v0.250.051)**

#### User Interface Enhancements
Expand Down
91 changes: 91 additions & 0 deletions functional_tests/test_control_center_left_nav_endpoint.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
# test_control_center_left_nav_endpoint.py
#!/usr/bin/env python3
"""
Functional test for Control Center left nav endpoint matching.
Version: 0.250.052
Implemented in: 0.250.052

This test ensures the Control Center sidebar section uses the blueprint-qualified
endpoint so admins see the left nav when ControlCenterAdmin enforcement is disabled.

Check warning on line 9 in functional_tests/test_control_center_left_nav_endpoint.py

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.
"""

from pathlib import Path


ROOT = Path(__file__).resolve().parents[1]


def read_text(relative_path: str) -> str:
"""Read a repository file as UTF-8 text."""
return (ROOT / relative_path).read_text(encoding="utf-8")


def test_control_center_sidebar_uses_blueprint_endpoint() -> bool:
"""Validate the Control Center sidebar section matches the registered endpoint."""

Check warning on line 24 in functional_tests/test_control_center_left_nav_endpoint.py

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.
print("Testing Control Center sidebar endpoint match...")
sidebar_template = read_text("application/single_app/templates/_sidebar_nav.html")

expected_endpoint_check = "request.endpoint == 'frontend_control_center.control_center'"
stale_endpoint_check = "request.endpoint == 'control_center'"

if expected_endpoint_check not in sidebar_template:
print("Control Center sidebar does not use the blueprint-qualified endpoint.")
return False

if stale_endpoint_check in sidebar_template:
print("Control Center sidebar still contains the stale unqualified endpoint check.")
return False

print("Control Center sidebar endpoint match found.")
return True


def test_control_center_regular_admin_fallback_preserved() -> bool:
"""Validate regular admins still get Control Center nav when app-role enforcement is disabled."""

Check warning on line 44 in functional_tests/test_control_center_left_nav_endpoint.py

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.
print("Testing Control Center regular Admin fallback...")
sidebar_template = read_text("application/single_app/templates/_sidebar_nav.html")

required_snippets = [
"not app_settings.require_member_of_control_center_admin and 'Admin' in session['user']['roles']",

Check warning on line 49 in functional_tests/test_control_center_left_nav_endpoint.py

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.
"app_settings.require_member_of_control_center_dashboard_reader",
"ControlCenterDashboardReader",
"ControlCenterAdmin",
]

missing_snippets = [snippet for snippet in required_snippets if snippet not in sidebar_template]
if missing_snippets:
print(f"Missing Control Center role fallback snippets: {missing_snippets}")
return False

print("Control Center regular Admin fallback preserved.")
return True


def test_config_version_bumped_for_control_center_left_nav_fix() -> bool:
"""Validate the repository version bump for the Control Center left nav fix."""
print("Testing config version bump for Control Center left nav fix...")
config_content = read_text("application/single_app/config.py")

if 'VERSION = "0.250.052"' not in config_content:
print("Config version was not bumped to 0.250.052")
return False

print("Config version bump found.")
return True


if __name__ == "__main__":
checks = [
test_control_center_sidebar_uses_blueprint_endpoint,
test_control_center_regular_admin_fallback_preserved,
test_config_version_bumped_for_control_center_left_nav_fix,
]

results = []
for check in checks:
print(f"\nRunning {check.__name__}...")
results.append(check())

success = all(results)
print(f"\nResults: {sum(results)}/{len(results)} checks passed")
raise SystemExit(0 if success else 1)
Loading