Repository navigation
refactor: add client parameter handling to prevent sending sensitive config in request body - #7875
Conversation
… search functionality
…config in request body
| raise_exception=False, | ||
| ) | ||
|
|
||
| self.assertFalse(result) |
There was a problem hiding this comment.
Here's my review of the code:
Irregularities / Potential Issues
-
Missing test for actual success path: Neither credential test covers the happy path (valid credentials returning
True). Only failure cases are tested. -
Brittle assertion on exception message verbatim:
test_validation_propagates_provider_error_messageasserts the exact string"Error code: 500 - {...}"is in.message. If the production code re-wraps or reformats the error, this breaks. Consider asserting on a stable substring like"internal_error"instead. -
Unused import:
QianfanVisionModelandQianfanChatModelare both used, but verifyMagicMockusage — it's fine. Howevermax_tokens=1/temperature=0.95are arbitrary; document why if meaningful, else simplify. -
Hard-coded fake API key prefix
sk-test: Fine for mocks, but ensure no network calls actually occur.new_instancecould theoretically trigger validation/network I/O — confirm it doesn't, otherwise tests are not hermetic despiteSimpleTestCase. -
Untested behavior in
test_client_params_are_not_sent_in_request_body: The test verifies params are absent fromextra_bodyand payload, but doesn't verify they land where expected on the underlying client beyond attribute checks. Attributemodel.request_timeoutexisting doesn't guarantee it was passed to the OpenAI client constructor. -
MagicMock
provider.get_modelreturns a mock whose.invokeraises — good, but the model's other attributes (e.g., name) may be accessed byis_validbeforeinvoke; confirm the mock covers those accesses (currently any attribute auto-resolves to aMagicMock, which may mask bugs). -
Duplicated setup across tests:
_mock_provider+QianfanLLMModelCredential()+ argument tuple is repeated. Consider a helper orsetUp. -
subTestloop only covers construction args identical for both models — fine, but add a comment that vision/chat share the same client-config contract intentionally.
Optimization Suggestions
- Add a positive-path test (
invokesucceeds →is_validreturnsTrue). - Parametrize the two credential tests with
subTestoverraise_exceptionTrue/False to reduce duplication. - Assert
AppApiException.messagecontains the original exception text viaassertIn("internal_error", ...)rather than the full raw string. - Verify request params are forwarded to the client (e.g., assert against the constructed OpenAI client) to prove they're "applied," not just absent from the body.
- Consider asserting
payloaddoes not unexpectedly contain other internal keys (snapshot-style) to catch regressions broadly.
Overall the tests are reasonable and focused; main gaps are the missing success case and over-specific error-message assertions.
| response["Content-Disposition"] = 'attachment; filename="data.xlsx"' | ||
| workbook.save(response) | ||
| return response | ||
|
|
There was a problem hiding this comment.
Review of the Diff
1. __contains → __icontains (lines ~245, ~400, ~533)
Good change.
- Better UX: case-insensitive search is usually what users expect.
- Caveat:
icontainson large tables can be slower and may bypass certain DB indexes (e.g., PostgreSQLLIKEindex only helps withtext_pattern_ops/pg_trgm). If these querysets are large or hit hot paths, consider a trigram index or full-text search.
2. Removing redundant f-string (f'attachment; filename="data.xlsx"' → plain string)
Correct. There were no interpolation placeholders, so the f prefix was dead code. No behavior change.
3. is_resource_filter = False added after workspace_manage branch (line ~409)
Potentially behavior-changing — verify intended semantics.
Compare with the sibling method around line ~533:
if is_workspace_manage(auth, workspace_id):
queryset = queryset.filter(workspace_id=workspace_id)
is_resource_filter = False # <-- only here in original
elif is_extends_workspace_manage(auth, workspace_id):
...The patched block now also sets is_resource_filter = False for the workspace-manager path. Two concerns:
- Is this a bug fix or an accidental change? If
is_resource_filtercontrols whether further permission filtering is applied downstream, setting it toFalsemeans workspace managers now skip that extra filtering. That is likely the intent (managers shouldn't be restricted by per-resource permissions), but it should be confirmed against tests. - Consistency: The sibling method at ~533 already does this. So this change makes them consistent — good, but worth double-checking there isn't another branch (e.g.,
is_extends_workspace_manage) missing the same treatment. - Naming clarity:
is_resource_filteris ambiguous. Consider something likeskip_resource_permission_filter.
4. Other observations (not in diff but visible)
-
Content-Type mismatch:
content_type="application/vnd.ms-excel"is the MIME type for.xls, but the file is written asdata.xlsx. For modern Excel use:content_type = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"
Also add UTF-8 filename encoding via
filename*=UTF-8''...if non-ASCII names may be used later. -
Duplication: The
exportmethod is copy-pasted three times. Extract a shared helper like_build_excel_response(rows). -
QuerySet(Application)— assuming this is a custom wrapper; fine, just noting.
5. Minor
- In the removed f-string,
workbook.save(response)is unchanged — fine. - Consider adding a test asserting case-insensitivity for each
get_queryset, sinceicontainsrelies on DB collation and can differ across backends (SQLite vs MySQL vs Postgres).
Summary
| Change | Verdict |
|---|---|
icontains |
✅ Recommended |
Remove useless f prefix |
✅ Correct |
is_resource_filter = False |
|
| Content-Type / duplication | 💡 Optimize separately |
| return False | ||
| return True | ||
|
|
||
| def encryption_dict(self, model_info: Dict[str, object]): |
There was a problem hiding this comment.
Here are the issues and suggestions for the code:
Potential Issues:
-
Inconsistent return behavior: The function now can return
False(whenraise_exception=False) or implicitly returnTrueat the end, but in earlier paths it may raise exceptions. This is fine, but ensure callers handle both cases. -
Exception re-raise logic order:
- If
eisAppApiException, it re-raises as-is. - Otherwise, if
raise_exception=True, it wraps in a newAppApiException. - However, the original exception loses its traceback context. Consider using
raise ... from eto preserve the chain:raise AppApiException(...) from e
- If
-
Swallowing exceptions silently: When
raise_exception=False, the exception is logged (withexc_info=True) but conversion toreturn Falsehides details. If callers rely only on boolean result, this is fine, but no error message reaches them. -
Logging already happens before branching: Since
maxkb_logger.error(...)runs for all cases, wrapped exceptions will be double-logged at the caller level. Acceptable, but note it. -
is_validreturnsTrueunconditionally at the end — this means any exception path withraise_exception=FalsereturnsFalse, while success returnsTrue. Just confirm this matches the intended contract (could there be other validation failures that should also returnFalseinstead of raising?).
Optimization Suggestions:
-
Preserve the exception chain:
raise AppApiException(...) from e
-
Consider validating the type of
raise_exceptionearly (it's assumed boolean). Minor. -
The error message template uses
.format(error=str(e))— fine, but ensuregettextstring has matching{error}placeholder in all translations. -
If
AppApiExceptionis a subclass of a general exception used elsewhere, ensure theisinstancecheck doesn't accidentally catch unrelated subclasses you want to wrap. -
Consider whether
return Falseshould also happen whenraise_exception=Falsefor theAppApiExceptionbranch — currently it always re-raisesAppApiExceptionregardless ofraise_exception. Confirm that's intentional (likely yes, since it's a domain-specific error).
Summary: Main fix is adding from e to preserve traceback; otherwise the logic change looks reasonable assuming intended semantics.
refactor: update string filtering to be case-insensitive for improved search functionality
refactor: add client parameter handling to prevent sending sensitive config in request body