Skip to content

refactor(api): validate OAuth bearer token cache with Pydantic - #43713

Open
Redestiny wants to merge 8 commits into
langgenius:mainfrom
Redestiny:refactor/oauth-bearer-cache-validation
Open

Redestiny wants to merge 8 commits into
langgenius:mainfrom
Redestiny:refactor/oauth-bearer-cache-validation

Conversation

@Redestiny

@Redestiny Redestiny commented Oct 9, 2026 •

Copy link
Copy Markdown
Contributor

Summary

Part of #33092. Validate OAuth bearer-token cache entries with a reusable Pydantic TypeAdapter. Malformed JSON, invalid cache shapes, and invalid identity fields become cache misses so the database row can repair the cache. Preserve serialized values, UUID/datetime conversions, the negative-cache sentinel, and older entries without client_id.

Synchronize with main at b531dcbe. Retain its authenticator refusal and rate-limit ordering tests alongside the cache regressions. Tests use the shared Redis transport fixture and a real OAuth database row.

Validation

  • OAuth bearer unit suite: 39 passed.
  • Changed-file Ruff formatting/lint and scoped production Pyrefly checks: passed.
  • Response-contract lint: no mismatches. git diff --check: passed.
  • Updated-head Main CI Pipeline on da8b870104f2857e7a5b2ce830b3db2a89488bae: passed.

AI-assisted implementation and validation with Codex.

@ghfind-review ghfind-review Bot added the review: medium ghfind author score; see https://ghfind.com label Oct 9, 2026
@github-actions github-actions Bot added the size:L This PR changes 100-499 lines, ignoring generated files. label Oct 9, 2026
@github-actions

github-actions Bot commented Oct 9, 2026

Copy link
Copy Markdown
Contributor

Pyrefly Diff

base → PR
--- /tmp/pyrefly_base.txt	2026-10-09 16:33:56.508417899 +0000
+++ /tmp/pyrefly_pr.txt	2026-10-09 16:33:27.098158684 +0000
@@ -1903,15 +1903,15 @@
 ERROR Object of class `FunctionType` has no attribute `__handler__` [missing-attribute]
   --> tests/unit_tests/controllers/openapi/test_app_run_streaming.py:87:18
 ERROR Object of class `Resource` has no attribute `post` [missing-attribute]
-   --> tests/unit_tests/controllers/openapi/test_app_run_streaming.py:147:20
+   --> tests/unit_tests/controllers/openapi/test_app_run_streaming.py:142:20
 ERROR Object of class `Resource` has no attribute `post` [missing-attribute]
-   --> tests/unit_tests/controllers/openapi/test_app_run_streaming.py:162:13
+   --> tests/unit_tests/controllers/openapi/test_app_run_streaming.py:157:13
 ERROR Object of class `Resource` has no attribute `post` [missing-attribute]
-   --> tests/unit_tests/controllers/openapi/test_app_run_streaming.py:187:9
+   --> tests/unit_tests/controllers/openapi/test_app_run_streaming.py:182:9
 ERROR Object of class `Resource` has no attribute `post` [missing-attribute]
-   --> tests/unit_tests/controllers/openapi/test_app_run_streaming.py:210:20
+   --> tests/unit_tests/controllers/openapi/test_app_run_streaming.py:205:20
 ERROR Object of class `Resource` has no attribute `post` [missing-attribute]
-   --> tests/unit_tests/controllers/openapi/test_app_run_streaming.py:228:20
+   --> tests/unit_tests/controllers/openapi/test_app_run_streaming.py:223:20
 ERROR Object of class `FunctionType` has no attribute `__handler__` [missing-attribute]
   --> tests/unit_tests/controllers/openapi/test_apps_permitted_external_query.py:71:18
 ERROR Object of class `FunctionType` has no attribute `view_class` [missing-attribute]
@@ -2041,21 +2041,15 @@
 ERROR Argument `None` is not assignable to parameter `value` with type `SQLCoreOperations[datetime] | datetime` in function `sqlalchemy.orm.base.Mapped.__set__` [bad-argument-type]
   --> tests/unit_tests/controllers/service_api/dataset/test_rag_pipeline_file_upload_serialization.py:34:30
 ERROR Argument `() -> Session` is not assignable to parameter `session_factory` with type `sessionmaker[@_]` in function `sqlalchemy.orm.scoping.scoped_session.__init__` [bad-argument-type]
-   --> tests/unit_tests/controllers/service_api/test_wraps.py:100:27
+  --> tests/unit_tests/controllers/service_api/test_wraps.py:93:27
 ERROR Missing argument `app_model` in function `protected_view` [missing-argument]
-   --> tests/unit_tests/controllers/service_api/test_wraps.py:262:36
+   --> tests/unit_tests/controllers/service_api/test_wraps.py:255:36
 ERROR Missing argument `app_model` in function `protected_view` [missing-argument]
-   --> tests/unit_tests/controllers/service_api/test_wraps.py:337:61
+   --> tests/unit_tests/controllers/service_api/test_wraps.py:330:61
 ERROR Missing argument `end_user` in function `protected_view` [missing-argument]
-   --> tests/unit_tests/controllers/service_api/test_wraps.py:337:61
-ERROR Missing argument `app_model` in function `protected_view` [missing-argument]
-   --> tests/unit_tests/controllers/service_api/test_wraps.py:398:36
-ERROR Object of class `NoneType` has no attribute `last_used_at` [missing-attribute]
-   --> tests/unit_tests/controllers/service_api/test_wraps.py:402:16
+   --> tests/unit_tests/controllers/service_api/test_wraps.py:330:61
 ERROR Argument `Literal['abnormal']` is not assignable to parameter `value` with type `AppStatus | SQLCoreOperations[AppStatus]` in function `sqlalchemy.orm.base.Mapped.__set__` [bad-argument-type]
-   --> tests/unit_tests/controllers/service_api/test_wraps.py:437:28
-ERROR Object of class `NoneType` has no attribute `last_used_at` [missing-attribute]
-   --> tests/unit_tests/controllers/service_api/test_wraps.py:936:16
+   --> tests/unit_tests/controllers/service_api/test_wraps.py:371:28
 ERROR Cannot index into `object` [bad-index]
    --> tests/unit_tests/controllers/test_swagger.py:151:20
 ERROR Cannot index into `object` [bad-index]
@@ -5975,15 +5969,15 @@
 ERROR Object of class `Subscription` has no attribute `_start_if_needed` [missing-attribute]
    --> tests/unit_tests/libs/broadcast_channel/redis/test_channel_unit_tests.py:216:13
 ERROR Argument `FakeRedisClient` is not assignable to parameter `client` with type `Redis[Unknown] | RedisCluster[Unknown]` in function `libs.broadcast_channel.redis._subscription.RedisSubscriptionBase.__init__` [bad-argument-type]
-   --> tests/unit_tests/libs/broadcast_channel/redis/test_channel_unit_tests.py:693:20
+   --> tests/unit_tests/libs/broadcast_channel/redis/test_channel_unit_tests.py:695:20
 ERROR Argument `FakeRedisClient` is not assignable to parameter `client` with type `Redis[Unknown] | RedisCluster[Unknown]` in function `libs.broadcast_channel.redis._subscription.RedisSubscriptionBase.__init__` [bad-argument-type]
-   --> tests/unit_tests/libs/broadcast_channel/redis/test_channel_unit_tests.py:713:20
+   --> tests/unit_tests/libs/broadcast_channel/redis/test_channel_unit_tests.py:715:20
 ERROR Argument `TestRedisShardedSubscription.test_get_message_uses_target_node_for_cluster_client.DummyRedisCluster` is not assignable to parameter `client` with type `Redis[Unknown] | RedisCluster[Unknown]` in function `libs.broadcast_channel.redis._subscription.RedisSubscriptionBase.__init__` [bad-argument-type]
-   --> tests/unit_tests/libs/broadcast_channel/redis/test_channel_unit_tests.py:898:20
+   --> tests/unit_tests/libs/broadcast_channel/redis/test_channel_unit_tests.py:900:20
 ERROR Argument `FakeRedisClient` is not assignable to parameter `client` with type `Redis[Unknown] | RedisCluster[Unknown]` in function `libs.broadcast_channel.redis._subscription.RedisSubscriptionBase.__init__` [bad-argument-type]
-    --> tests/unit_tests/libs/broadcast_channel/redis/test_channel_unit_tests.py:1028:20
+    --> tests/unit_tests/libs/broadcast_channel/redis/test_channel_unit_tests.py:1030:20
 ERROR Argument `FakeRedisClient` is not assignable to parameter `client` with type `Redis[Unknown] | RedisCluster[Unknown]` in function `libs.broadcast_channel.redis._subscription.RedisSubscriptionBase.__init__` [bad-argument-type]
-    --> tests/unit_tests/libs/broadcast_channel/redis/test_channel_unit_tests.py:1125:24
+    --> tests/unit_tests/libs/broadcast_channel/redis/test_channel_unit_tests.py:1127:24
 ERROR Class member `FailExpireRedis.expire` overrides a member in a parent class but is missing an `@override` decorator [missing-override-decorator]
   --> tests/unit_tests/libs/broadcast_channel/redis/test_streams_channel_unit_tests.py:87:9
 ERROR Class member `FailXrevrangeRedis.xrevrange` overrides a member in a parent class but is missing an `@override` decorator [missing-override-decorator]
@@ -6055,7 +6049,7 @@
 ERROR Argument `None` is not assignable to parameter `pattern` with type `str` in function `libs.helper.escape_like_pattern` [bad-argument-type]
    --> tests/unit_tests/libs/test_helper.py:114:38
 ERROR Object of class `TooManyRequests` has no attribute `headers` [missing-attribute]
-  --> tests/unit_tests/libs/test_rate_limit_bearer.py:99:17
+  --> tests/unit_tests/libs/test_rate_limit_bearer.py:74:17
 ERROR Argument `_FakeRedis` is not assignable to parameter `redis_client` with type `_RateLimiterRedisClient` in function `libs.helper.RateLimiter.__init__` [bad-argument-type]
   --> tests/unit_tests/libs/test_rate_limiter.py:44:22
 ERROR Class member `TestEnhancedCronSyntax.setUp` overrides a member in a parent class but is missing an `@override` decorator [missing-override-decorator]
@@ -6409,13 +6403,13 @@
 ERROR Argument `_FakeRedisClient` is not assignable to parameter `redis_client` with type `Redis[Unknown] | RedisCluster[Unknown]` in function `libs.broadcast_channel.redis.pubsub_channel.BroadcastChannel.__init__` [bad-argument-type]
    --> tests/unit_tests/services/test_app_generate_service_streaming_integration.py:127:34
 ERROR Argument `str | None` is not assignable to parameter `tenant_id` with type `str` in function `services.app_service.AppService.create_app` [bad-argument-type]
-   --> tests/unit_tests/services/test_app_service.py:257:17
+   --> tests/unit_tests/services/test_app_service.py:247:17
 ERROR Argument `str | None` is not assignable to parameter `tenant_id` with type `str` in function `services.app_service.AppService.create_app` [bad-argument-type]
-   --> tests/unit_tests/services/test_app_service.py:322:17
+   --> tests/unit_tests/services/test_app_service.py:312:17
 ERROR Argument `str | None` is not assignable to parameter `tenant_id` with type `str` in function `services.app_service.AppService.create_app` [bad-argument-type]
-   --> tests/unit_tests/services/test_app_service.py:355:17
+   --> tests/unit_tests/services/test_app_service.py:345:17
 ERROR Argument `Literal['advanced-chat', 'agent', 'agent-chat', 'channel', 'chat', 'completion', 'rag-pipeline', 'workflow']` is not assignable to parameter `mode` with type `Literal['advanced-chat', 'agent', 'agent-chat', 'chat', 'completion', 'workflow']` in function `services.entities.app_entities.CreateAppParams.__init__` [bad-argument-type]
-   --> tests/unit_tests/services/test_app_service.py:356:65
+   --> tests/unit_tests/services/test_app_service.py:346:65
 ERROR `in` is not supported between `Literal['Quota limit reached']` and `None` [not-iterable]
    --> tests/unit_tests/services/test_async_workflow_service.py:344:16
 ERROR Argument `BillingInfo` is not assignable to parameter `result` with type `dict[Unknown, Unknown]` in function `TestBillingServiceSubscriptionInfoDataType._assert_billing_info_types` [bad-argument-type]

@github-actions

github-actions Bot commented Oct 9, 2026 •

Copy link
Copy Markdown
Contributor

Pyrefly Type Coverage

Metric Base PR Delta
Type coverage 83.00% 83.01% +0.00%
Strict coverage 82.66% 82.66% +0.00%
Typed symbols 85,596 85,616 +20
Untyped symbols 17,603 17,602 -1
Modules 4373 4373 0

@codecov

codecov Bot commented Oct 9, 2026 •

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 89.68%. Comparing base (ac0f594) to head (da8b870).
⚠️ Report is 5 commits behind head on main.

Additional details and impacted files
@@             Coverage Diff             @@
##             main   #43713       +/-   ##
===========================================
+ Coverage   68.81%   89.68%   +20.86%     
===========================================
  Files        6103     6149       +46     
  Lines      368940   385961    +17021     
  Branches    77825    77222      -603     
===========================================
+ Hits       253897   346156    +92259     
+ Misses     112233    33707    -78526     
- Partials     2810     6098     +3288     
Flag Coverage Δ
api 89.64% <100.00%> (+37.30%) ⬆️

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

Copy link
Copy Markdown
Contributor Author

Updated against main in da8b8701, preserving the current authenticator and rate-limit tests alongside the cache validation regressions. All 39 OAuth bearer tests, scoped lint/type checks, and updated-head Main CI passed. The change remains limited to the cache implementation and its unit test. Ready for maintainer review.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

review: medium ghfind author score; see https://ghfind.com size:L This PR changes 100-499 lines, ignoring generated files.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants