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 @@ -101,7 +101,7 @@
EXECUTOR_TYPE = 'thread'
EXECUTOR_MAX_WORKERS = 30
SESSION_TYPE = 'filesystem'
VERSION = "0.261.258"
VERSION = "0.261.259"
IS_DEVELOPMENT = is_development_env_enabled()

# Opt-out for deployments where App Service Easy Auth is active but the platform
Expand Down
5 changes: 5 additions & 0 deletions application/single_app/functions_collaboration.py
Original file line number Diff line number Diff line change
Expand Up @@ -1260,6 +1260,11 @@
if not allowed:
raise PermissionError(reason)

invited_participants = (
_normalize_group_conversation_participants(group_doc, invited_participants)

Check warning on line 1264 in application/single_app/functions_collaboration.py

View workflow job for this annotation

GitHub Actions / malicious-pr-security-review

Important - Changed line contains AI, plugin, agent, or workspace boundary marker. Recommendation%3A Check whether prompts, chat history, uploaded documents, embeddings, citations, settings, or identity can cross a new boundary.
if invited_participants else []
)

collaboration_conversation_doc = None
linked_collaboration_id = str(source_conversation_doc.get('collaboration_conversation_id') or '').strip()
if linked_collaboration_id:
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
# Group Collaboration Invitee Validation Order Fix (v0.261.259)

## Overview

Group conversation conversion now proves that every requested invitee is a current member of the source group before reading the conversation's message history. This keeps authorization checks ahead of dependent data access while preserving the existing conversion and invitation behavior.

Check warning on line 5 in docs/explanation/fixes/GROUP_COLLABORATION_INVITEE_VALIDATION_ORDER_FIX.md

View workflow job for this annotation

GitHub Actions / malicious-pr-security-review

Important - Changed line contains AI, plugin, agent, or workspace boundary marker. Recommendation%3A Check whether prompts, chat history, uploaded documents, embeddings, citations, settings, or identity can cross a new boundary.

Check warning on line 5 in docs/explanation/fixes/GROUP_COLLABORATION_INVITEE_VALIDATION_ORDER_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.

Fixed in version: **0.261.259**

Related issue: [#1651](https://github.com/microsoft/simplechat/issues/1651)

Check warning on line 9 in docs/explanation/fixes/GROUP_COLLABORATION_INVITEE_VALIDATION_ORDER_FIX.md

View workflow job for this annotation

GitHub Actions / malicious-pr-security-review

Important - Changed line contains external connection or remote asset marker. Recommendation%3A Review whether changed code can send prompts, files, credentials, cookies, settings, logs, or user data to a new sink.

Dependencies: group membership normalization, group role authorization, and Microsoft 365 history publication.

Check warning on line 11 in docs/explanation/fixes/GROUP_COLLABORATION_INVITEE_VALIDATION_ORDER_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 11 in docs/explanation/fixes/GROUP_COLLABORATION_INVITEE_VALIDATION_ORDER_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.

The application version was updated in `application/single_app/config.py` from `0.261.258` to `0.261.259`.

## Issue Description

An owner converting an eligible legacy group conversation could include an identity that was not a current member of the source group. The request was rejected and no records were changed, but Microsoft 365 publication preparation queried the source message history before participant normalization raised the rejection.

Check warning on line 17 in docs/explanation/fixes/GROUP_COLLABORATION_INVITEE_VALIDATION_ORDER_FIX.md

View workflow job for this annotation

GitHub Actions / malicious-pr-security-review

Important - Changed line contains AI, plugin, agent, or workspace boundary marker. Recommendation%3A Check whether prompts, chat history, uploaded documents, embeddings, citations, settings, or identity can cross a new boundary.

The group document collaboration suite also replaced the workflow-alert safety module with a test stub that no longer matched the production module's exported constants. That mismatch stopped the suite during fixture setup and hid its sharing assertions.

## Root Cause

`ensure_group_collaboration_for_legacy_conversation` passed the raw invitee list into history publication before `create_group_collaboration_conversation_record` normalized those invitees against the current group document. The correct validation existed, but it ran after a dependent transcript read.

Check warning on line 23 in docs/explanation/fixes/GROUP_COLLABORATION_INVITEE_VALIDATION_ORDER_FIX.md

View workflow job for this annotation

GitHub Actions / malicious-pr-security-review

Important - Changed line contains AI, plugin, agent, or workspace boundary marker. Recommendation%3A Check whether prompts, chat history, uploaded documents, embeddings, citations, settings, or identity can cross a new boundary.

Check warning on line 23 in docs/explanation/fixes/GROUP_COLLABORATION_INVITEE_VALIDATION_ORDER_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.

Separately, `functions_notifications` gained an import path through `functions_workflow_alerts`, whose safety contract requires three public diagnostic constants. The isolated test stub exported only the sanitizer function.

## Technical Details

### Files Modified

- `application/single_app/functions_collaboration.py`
- `application/single_app/config.py`
- `functional_tests/test_group_collaboration_source_storage_fix.py`

Check warning on line 33 in docs/explanation/fixes/GROUP_COLLABORATION_INVITEE_VALIDATION_ORDER_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.
- `functional_tests/test_group_document_collaboration.py`
- `docs/explanation/release_notes.md`

### Code Changes

The conversion path now normalizes requested invitees immediately after it verifies the owner, source conversation, group, current owner role, and active group status. Only the validated participant summaries can reach an existing collaborative conversation, Microsoft 365 publication preparation, conversation record creation, or transcript copying.

The document collaboration fixture now provides the exact workflow-alert diagnostic constants exported by production while retaining its assertion that document sharing must not enter workflow-alert rendering.

No route, response status, or request payload contract changed.

## Testing And Validation

The focused regression command exercises both invalid-invitee storage modes, the V1 route contract, and the document-sharing fixture import path. It completed with 3 tests and 38 subtests passing.

The complete group source-storage suite completed with 20 tests and 106 subtests passing. The targeted document-sharing fixture case passed, editor diagnostics reported no errors, and the broken-access-control guardrail passed for the changed production module. Documentation validation completed with 7 of 7 application-surface checks and 6 of 6 site-quality checks passing.

## Impact Analysis

### Before

- An out-of-group invitee was rejected without mutation, but only after the source transcript was queried.
- The document collaboration suite stopped during fixture setup because its safety stub was incomplete.

### After

- Every invitee is authorized against current group membership before transcript or publication evidence access.
- Rejected conversion requests do not read either possible source message container.
- The document collaboration suite reaches its route, policy, Search, notification, and storage assertions.

## Known Limitations

The fix does not change who may convert a conversation, which groups may be used, or which participant roles are assigned. It only moves the existing invitee normalization to the earliest point after the source group and caller have been authorized.
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](https://github.com/microsoft/simplechat/tree/main/docs/explanation/features) and [Fixes by Version](https://github.com/microsoft/simplechat/tree/main/docs/explanation/fixes).

### **(v0.261.259)**

#### Bug Fixes

* **Rejected Group Conversation Invites Stop Before History Reads**
* Converting an existing group conversation now verifies every invited participant against the group's current membership before preparing Microsoft 365 publication evidence or reading the conversation transcript. An identity outside the group is still rejected without changing any records, but the rejection now happens before message history is queried.
* The document collaboration regression fixture now exposes the current workflow-alert safety contract, so its sharing and repair checks reach their assertions instead of stopping during module import.
* (Ref: #1651, `ensure_group_collaboration_for_legacy_conversation`, `test_group_collaboration_source_storage_fix.py`, `test_group_document_collaboration.py`, [Group Collaboration Invitee Validation Order Fix](fixes/GROUP_COLLABORATION_INVITEE_VALIDATION_ORDER_FIX.md))

### **(v0.261.258)**

#### User Interface Enhancements
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,12 @@
#!/usr/bin/env python3
"""
Functional regression for group conversation source storage.
Version: 0.261.257
Version: 0.261.259
Implemented in: 0.261.024
Ported to the React branch in: 0.261.106
Soft-delete helper seeded in the harness in: 0.261.257
Related issue: microsoft/simplechat#1472
Invitee validation ordering fixed in: 0.261.259
Related issues: microsoft/simplechat#1472, microsoft/simplechat#1651

Exercise production conversion and route helpers against isolated Cosmos stores.
Group context must not imply group-container storage or weaken authorization.
Expand Down
12 changes: 10 additions & 2 deletions functional_tests/test_group_document_collaboration.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
# test_group_document_collaboration.py
"""
Functional tests for immutable group document sharing and repair.
Version: 0.261.131
Version: 0.261.259
Implemented in: 0.261.131
Workflow alert safety fixture updated in: 0.261.259

Real Flask routes, policy, conditional source writes, Search write guards, access
index projections and notification persistence run against local service seams.
Expand Down Expand Up @@ -179,7 +180,14 @@ def directory_query(query, parameters=None, **kwargs):
get_user_public_workspaces=Mock(),
))
patch.setitem(sys.modules, "functions_workflow_alert_safety", module_stub(
"functions_workflow_alert_safety", sanitize_workflow_alert_record=Mock(
"functions_workflow_alert_safety",
WORKFLOW_ALERT_EVALUATION_ERROR_CODE="workflow_alert_evaluation_failed",
WORKFLOW_ALERT_EVALUATION_ERROR_MESSAGE=(
"Alert conditions could not be evaluated. "
"Review the workflow model configuration or contact an administrator."
),
WORKFLOW_ALERT_EVALUATOR_UNAVAILABLE_MESSAGE="No model evaluator was available for this run.",
sanitize_workflow_alert_record=Mock(
side_effect=AssertionError("Sharing must not enter workflow alert rendering."),
),
))
Expand Down
Loading