Resolve an API key file preference against the path allowlist. - User preference set and path allowed: read and return the key. - User preference set but path rejected: log a warning and return None WITHOUT falling back to the admin default. Silent substitution would make t
(pref_name, config_default)
| 326 | |
| 327 | |
| 328 | def _resolve_pref_key_file(pref_name, config_default): |
| 329 | """ |
| 330 | Resolve an API key file preference against the path allowlist. |
| 331 | |
| 332 | - User preference set and path allowed: read and return the key. |
| 333 | - User preference set but path rejected: log a warning and return |
| 334 | None WITHOUT falling back to the admin default. Silent |
| 335 | substitution would make the user's request go through using |
| 336 | a different key than they expected (the symptom in jbro90's |
| 337 | comment on issue #9936). |
| 338 | - No user preference: read from the admin's trusted config path. |
| 339 | |
| 340 | Returns the key string, or None. |
| 341 | """ |
| 342 | pref_file = _get_preference_value(pref_name) |
| 343 | if pref_file: |
| 344 | safe_path = validate_api_key_path(pref_file) |
| 345 | if safe_path is None: |
| 346 | try: |
| 347 | from flask import current_app |
| 348 | current_app.logger.warning( |
| 349 | "LLM API key file preference '%s'=%r is not " |
| 350 | "within the allowed user storage directory; " |
| 351 | "ignoring. Place the key file in your private " |
| 352 | "user storage to use it.", |
| 353 | pref_name, pref_file |
| 354 | ) |
| 355 | except Exception: |
| 356 | pass |
| 357 | return None |
| 358 | return _read_api_key_from_file(safe_path) |
| 359 | return _read_api_key_from_file(config_default, _trusted=True) |
| 360 | |
| 361 | |
| 362 | def is_pref_api_key_path_rejected(pref_name): |
no test coverage detected