Validate edge device ID headers#4825
Conversation
Greptile SummaryThis PR hardens the FEG header-parsing logic by treating
Confidence Score: 5/5Safe to merge — the change is a narrow defensive guard with no effect on the happy path and full branch coverage in the new tests. The two modified lines (mismatch check + re-assignment) are logically correct: DeviceInfo is a dict subclass, so device_info.get('device_id') after from_query_string reliably returns the overwritten value only when the query string actually contained that key. The canonical re-assignment on line 72 is now unconditional, closing the previously addressed gap. All four branches are exercised by the new test suite. No files require special attention. Important Files Changed
Flowchart%%{init: {'theme': 'neutral'}}%%
flowchart TD
A[Request arrives] --> B{X-Flare-Device-ID\npresent?}
B -- No --> C[400 INVALID_REQUEST\nDevice ID missing]
B -- Yes --> D[DeviceInfo device_id\n= canonical ID]
D --> E{X-Flare-Device-Info\npresent?}
E -- No --> H
E -- Yes --> F[from_query_string\nparses metadata]
F --> G{device_id in\nDEVICE_INFO AND\n!= canonical?}
G -- Yes --> J[400 INVALID_REQUEST\nDevice ID mismatch]
G -- No --> H[device_info.device_id\n= canonical ID]
H --> I[Continue to\nroute handler]
%%{init: {'theme': 'base', 'themeVariables': {"darkMode": true, "background": "#0d1117", "primaryColor": "#21262d", "primaryTextColor": "#e6edf3", "primaryBorderColor": "#8b949e", "lineColor": "#8b949e", "textColor": "#e6edf3", "edgeLabelBackground": "#161b22", "actorBkg": "#21262d", "actorBorder": "#8b949e", "actorTextColor": "#e6edf3", "actorLineColor": "#8b949e", "signalColor": "#8b949e", "signalTextColor": "#e6edf3", "noteBkgColor": "#373320", "noteBorderColor": "#d4a72c", "noteTextColor": "#f0e6c0", "labelBoxBkgColor": "#21262d", "labelBoxBorderColor": "#8b949e", "labelTextColor": "#e6edf3", "loopTextColor": "#e6edf3", "activationBkgColor": "#30363d", "activationBorderColor": "#8b949e"}}}%%
flowchart TD
A[Request arrives] --> B{X-Flare-Device-ID\npresent?}
B -- No --> C[400 INVALID_REQUEST\nDevice ID missing]
B -- Yes --> D[DeviceInfo device_id\n= canonical ID]
D --> E{X-Flare-Device-Info\npresent?}
E -- No --> H
E -- Yes --> F[from_query_string\nparses metadata]
F --> G{device_id in\nDEVICE_INFO AND\n!= canonical?}
G -- Yes --> J[400 INVALID_REQUEST\nDevice ID mismatch]
G -- No --> H[device_info.device_id\n= canonical ID]
H --> I[Continue to\nroute handler]
Reviews (4): Last reviewed commit: "Merge branch 'main' into fix-edge-device..." | Re-trigger Greptile |
f275c5d to
8b5f5cc
Compare
|
@fallintoplace |
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## main #4825 +/- ##
==========================================
+ Coverage 56.39% 56.60% +0.21%
==========================================
Files 968 968
Lines 92166 92170 +4
==========================================
+ Hits 51976 52172 +196
+ Misses 40190 39998 -192
Flags with carried forward coverage won't be shown. Click here to find out more. ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
|
@YuanTingHsieh I have updated both branch. Thank you for your attention. |
Summary
X-Flare-Device-IDas the canonical device identity for FEG requests.X-Flare-Device-Infocontains a conflictingdevice_id.Why
The FEG parser creates
DeviceInfofromX-Flare-Device-ID, but then blindly applies fields parsed fromX-Flare-Device-Info. Adevice_idembedded in the metadata header could override the canonical ID used for routing, selection, device tracking, and result attribution. The simulation client already removesdevice_idfrom the metadata header, so treating the standalone ID header as canonical matches the existing client behavior.Testing
.venv/bin/python -m pytest tests/unit_test/edge/web/views/feg_views_test.py -q.venv/bin/python -m black --check nvflare/edge/web/views/feg_views.py tests/unit_test/edge/web/views/feg_views_test.py.venv/bin/python -m isort --check-only nvflare/edge/web/views/feg_views.py tests/unit_test/edge/web/views/feg_views_test.py.venv/bin/python -m flake8 nvflare/edge/web/views/feg_views.py tests/unit_test/edge/web/views/feg_views_test.pysource .venv/bin/activate && ./runtest.sh -s